├── languages ├── readme ├── bp-xprofile-custom-field-types.mo ├── bp-xprofile-custom-field-types-de_DE.mo ├── bp-xprofile-custom-field-types-fr_FR.mo └── bp-xprofile-custom-field-types-de_DE_formal.mo ├── assets ├── vendors │ ├── jscolor │ │ ├── hs.png │ │ ├── hv.png │ │ ├── arrow.gif │ │ └── cross.gif │ ├── select2 │ │ └── i18n │ │ │ ├── zh-TW.js │ │ │ ├── zh-CN.js │ │ │ ├── ja.js │ │ │ ├── az.js │ │ │ ├── ko.js │ │ │ ├── vi.js │ │ │ ├── tk.js │ │ │ ├── tr.js │ │ │ ├── id.js │ │ │ ├── th.js │ │ │ ├── ar.js │ │ │ ├── km.js │ │ │ ├── nb.js │ │ │ ├── sv.js │ │ │ ├── is.js │ │ │ ├── fi.js │ │ │ ├── et.js │ │ │ ├── ms.js │ │ │ ├── hu.js │ │ │ ├── ka.js │ │ │ ├── bg.js │ │ │ ├── da.js │ │ │ ├── hy.js │ │ │ ├── fa.js │ │ │ ├── en.js │ │ │ ├── he.js │ │ │ ├── hi.js │ │ │ ├── hr.js │ │ │ ├── af.js │ │ │ ├── de.js │ │ │ ├── eu.js │ │ │ ├── pt-BR.js │ │ │ ├── mk.js │ │ │ ├── pt.js │ │ │ ├── lv.js │ │ │ ├── bn.js │ │ │ ├── sq.js │ │ │ ├── ca.js │ │ │ ├── it.js │ │ │ ├── ps.js │ │ │ ├── nl.js │ │ │ ├── fr.js │ │ │ ├── ne.js │ │ │ ├── sl.js │ │ │ ├── es.js │ │ │ ├── gl.js │ │ │ ├── ro.js │ │ │ ├── lt.js │ │ │ ├── pl.js │ │ │ ├── el.js │ │ │ ├── bs.js │ │ │ ├── sr.js │ │ │ ├── uk.js │ │ │ ├── sr-Cyrl.js │ │ │ ├── ru.js │ │ │ ├── dsb.js │ │ │ ├── hsb.js │ │ │ ├── cs.js │ │ │ └── sk.js │ └── modernizr.js ├── css │ └── bp-xprofile-custom-field-types.css └── js │ ├── bp-xprofile-custom-field-types.js │ └── bp-xprofile-custom-field-types-admin.js ├── src ├── contracts │ ├── interface-field-type-selectable.php │ ├── interface-field-type-multi-valued.php │ └── inteface-field-type-multi-selectable.php ├── field-types │ ├── class-field-type-oembed.php │ ├── class-field-type-color.php │ ├── class-field-type-web.php │ ├── class-field-type-email.php │ ├── class-field-type-datepicker.php │ ├── class-field-type-token.php │ ├── class-field-type-number-min-max.php │ ├── class-field-type-slider.php │ ├── class-field-type-decimal-number.php │ ├── class-field-type-image.php │ ├── class-field-type-file.php │ ├── class-field-type-checkbox-acceptance.php │ ├── class-field-type-tags.php │ ├── class-field-type-select-post-type.php │ ├── class-field-type-select-taxonomy.php │ └── class-field-type-multi-select-post-type.php ├── core │ ├── class-data-store.php │ └── bp-xprofile-custom-field-types-functions.php ├── admin │ └── class-admin.php ├── filters │ ├── class-xprofile-kses-filter.php │ └── class-bp-profile-search-helper.php ├── handlers │ ├── class-label-filter.php │ ├── class-taxonomy-terms-creator.php │ ├── class-birthdate-field-validator.php │ ├── class-field-settings-handler.php │ ├── class-from-to-helper.php │ ├── class-tags-creator.php │ └── class-signup-validator.php └── bootstrap │ ├── class-bootstrapper.php │ ├── class-autoloader.php │ └── class-assets-loader.php └── bp-xprofile-custom-field-types.php /languages/readme: -------------------------------------------------------------------------------- 1 | Credits: 2 | German Translation:- Thorsten Wollenhöfer 3 | -------------------------------------------------------------------------------- /assets/vendors/jscolor/hs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buddydev/bp-xprofile-custom-field-types/HEAD/assets/vendors/jscolor/hs.png -------------------------------------------------------------------------------- /assets/vendors/jscolor/hv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buddydev/bp-xprofile-custom-field-types/HEAD/assets/vendors/jscolor/hv.png -------------------------------------------------------------------------------- /assets/vendors/jscolor/arrow.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buddydev/bp-xprofile-custom-field-types/HEAD/assets/vendors/jscolor/arrow.gif -------------------------------------------------------------------------------- /assets/vendors/jscolor/cross.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buddydev/bp-xprofile-custom-field-types/HEAD/assets/vendors/jscolor/cross.gif -------------------------------------------------------------------------------- /languages/bp-xprofile-custom-field-types.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buddydev/bp-xprofile-custom-field-types/HEAD/languages/bp-xprofile-custom-field-types.mo -------------------------------------------------------------------------------- /languages/bp-xprofile-custom-field-types-de_DE.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buddydev/bp-xprofile-custom-field-types/HEAD/languages/bp-xprofile-custom-field-types-de_DE.mo -------------------------------------------------------------------------------- /languages/bp-xprofile-custom-field-types-fr_FR.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buddydev/bp-xprofile-custom-field-types/HEAD/languages/bp-xprofile-custom-field-types-fr_FR.mo -------------------------------------------------------------------------------- /languages/bp-xprofile-custom-field-types-de_DE_formal.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buddydev/bp-xprofile-custom-field-types/HEAD/languages/bp-xprofile-custom-field-types-de_DE_formal.mo -------------------------------------------------------------------------------- /assets/css/bp-xprofile-custom-field-types.css: -------------------------------------------------------------------------------- 1 | .standard-form input[type="color"] { 2 | width: auto !important; /*override the 100% specified by BuddyPress*/ 3 | } 4 | 5 | .field_type_image .bpxcftr-image { 6 | max-width: 100%; 7 | } 8 | 9 | /** 10 | * From to value field 11 | **/ 12 | .bpxcftr-from-to-edit-field input[type="text"] { 13 | width: 10em !important; 14 | display: inline; 15 | } 16 | 17 | .bpxcftr-from-to-edit-field-integer input[type="text"], 18 | .bpxcftr-from-to-edit-field-numeric input[type="text"] { 19 | width: 4em !important; 20 | } 21 | -------------------------------------------------------------------------------- /src/contracts/interface-field-type-selectable.php: -------------------------------------------------------------------------------- 1 | 1&&(e+="i"),e+=" í viðbót"},loadingMore:function(){return"Sæki fleiri niðurstöður…"},maximumSelected:function(n){return"Þú getur aðeins valið "+n.maximum+" atriði"},noResults:function(){return"Ekkert fannst"},searching:function(){return"Leita…"},removeAllItems:function(){return"Fjarlægðu öll atriði"}}}),n.define,n.require}(); -------------------------------------------------------------------------------- /assets/vendors/select2/i18n/fi.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.12 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/fi",[],function(){return{errorLoading:function(){return"Tuloksia ei saatu ladattua."},inputTooLong:function(n){return"Ole hyvä ja anna "+(n.input.length-n.maximum)+" merkkiä vähemmän"},inputTooShort:function(n){return"Ole hyvä ja anna "+(n.minimum-n.input.length)+" merkkiä lisää"},loadingMore:function(){return"Ladataan lisää tuloksia…"},maximumSelected:function(n){return"Voit valita ainoastaan "+n.maximum+" kpl"},noResults:function(){return"Ei tuloksia"},searching:function(){return"Haetaan…"},removeAllItems:function(){return"Poista kaikki kohteet"}}}),n.define,n.require}(); -------------------------------------------------------------------------------- /assets/vendors/select2/i18n/et.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.12 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/et",[],function(){return{inputTooLong:function(e){var n=e.input.length-e.maximum,t="Sisesta "+n+" täht";return 1!=n&&(t+="e"),t+=" vähem"},inputTooShort:function(e){var n=e.minimum-e.input.length,t="Sisesta "+n+" täht";return 1!=n&&(t+="e"),t+=" rohkem"},loadingMore:function(){return"Laen tulemusi…"},maximumSelected:function(e){var n="Saad vaid "+e.maximum+" tulemus";return 1==e.maximum?n+="e":n+="t",n+=" valida"},noResults:function(){return"Tulemused puuduvad"},searching:function(){return"Otsin…"},removeAllItems:function(){return"Eemalda kõik esemed"}}}),e.define,e.require}(); -------------------------------------------------------------------------------- /assets/vendors/select2/i18n/ms.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.12 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ms",[],function(){return{errorLoading:function(){return"Keputusan tidak berjaya dimuatkan."},inputTooLong:function(n){return"Sila hapuskan "+(n.input.length-n.maximum)+" aksara"},inputTooShort:function(n){return"Sila masukkan "+(n.minimum-n.input.length)+" atau lebih aksara"},loadingMore:function(){return"Sedang memuatkan keputusan…"},maximumSelected:function(n){return"Anda hanya boleh memilih "+n.maximum+" pilihan"},noResults:function(){return"Tiada padanan yang ditemui"},searching:function(){return"Mencari…"},removeAllItems:function(){return"Keluarkan semua item"}}}),n.define,n.require}(); -------------------------------------------------------------------------------- /assets/vendors/select2/i18n/hu.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.12 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/hu",[],function(){return{errorLoading:function(){return"Az eredmények betöltése nem sikerült."},inputTooLong:function(e){return"Túl hosszú. "+(e.input.length-e.maximum)+" karakterrel több, mint kellene."},inputTooShort:function(e){return"Túl rövid. Még "+(e.minimum-e.input.length)+" karakter hiányzik."},loadingMore:function(){return"Töltés…"},maximumSelected:function(e){return"Csak "+e.maximum+" elemet lehet kiválasztani."},noResults:function(){return"Nincs találat."},searching:function(){return"Keresés…"},removeAllItems:function(){return"Távolítson el minden elemet"}}}),e.define,e.require}(); -------------------------------------------------------------------------------- /assets/vendors/select2/i18n/ka.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.12 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ka",[],function(){return{errorLoading:function(){return"მონაცემების ჩატვირთვა შეუძლებელია."},inputTooLong:function(n){return"გთხოვთ აკრიფეთ "+(n.input.length-n.maximum)+" სიმბოლოთი ნაკლები"},inputTooShort:function(n){return"გთხოვთ აკრიფეთ "+(n.minimum-n.input.length)+" სიმბოლო ან მეტი"},loadingMore:function(){return"მონაცემების ჩატვირთვა…"},maximumSelected:function(n){return"თქვენ შეგიძლიათ აირჩიოთ არაუმეტეს "+n.maximum+" ელემენტი"},noResults:function(){return"რეზულტატი არ მოიძებნა"},searching:function(){return"ძიება…"},removeAllItems:function(){return"ამოიღე ყველა ელემენტი"}}}),n.define,n.require}(); -------------------------------------------------------------------------------- /assets/vendors/select2/i18n/bg.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.12 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/bg",[],function(){return{inputTooLong:function(n){var e=n.input.length-n.maximum,u="Моля въведете с "+e+" по-малко символ";return e>1&&(u+="a"),u},inputTooShort:function(n){var e=n.minimum-n.input.length,u="Моля въведете още "+e+" символ";return e>1&&(u+="a"),u},loadingMore:function(){return"Зареждат се още…"},maximumSelected:function(n){var e="Можете да направите до "+n.maximum+" ";return n.maximum>1?e+="избора":e+="избор",e},noResults:function(){return"Няма намерени съвпадения"},searching:function(){return"Търсене…"},removeAllItems:function(){return"Премахнете всички елементи"}}}),n.define,n.require}(); -------------------------------------------------------------------------------- /assets/vendors/select2/i18n/da.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.12 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/da",[],function(){return{errorLoading:function(){return"Resultaterne kunne ikke indlæses."},inputTooLong:function(e){return"Angiv venligst "+(e.input.length-e.maximum)+" tegn mindre"},inputTooShort:function(e){return"Angiv venligst "+(e.minimum-e.input.length)+" tegn mere"},loadingMore:function(){return"Indlæser flere resultater…"},maximumSelected:function(e){var n="Du kan kun vælge "+e.maximum+" emne";return 1!=e.maximum&&(n+="r"),n},noResults:function(){return"Ingen resultater fundet"},searching:function(){return"Søger…"},removeAllItems:function(){return"Fjern alle elementer"}}}),e.define,e.require}(); -------------------------------------------------------------------------------- /assets/vendors/select2/i18n/hy.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.12 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/hy",[],function(){return{errorLoading:function(){return"Արդյունքները հնարավոր չէ բեռնել։"},inputTooLong:function(n){return"Խնդրում ենք հեռացնել "+(n.input.length-n.maximum)+" նշան"},inputTooShort:function(n){return"Խնդրում ենք մուտքագրել "+(n.minimum-n.input.length)+" կամ ավել նշաններ"},loadingMore:function(){return"Բեռնվում են նոր արդյունքներ․․․"},maximumSelected:function(n){return"Դուք կարող եք ընտրել առավելագույնը "+n.maximum+" կետ"},noResults:function(){return"Արդյունքներ չեն գտնվել"},searching:function(){return"Որոնում․․․"},removeAllItems:function(){return"Հեռացնել բոլոր տարրերը"}}}),n.define,n.require}(); -------------------------------------------------------------------------------- /assets/vendors/select2/i18n/fa.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.12 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/fa",[],function(){return{errorLoading:function(){return"امکان بارگذاری نتایج وجود ندارد."},inputTooLong:function(n){return"لطفاً "+(n.input.length-n.maximum)+" کاراکتر را حذف نمایید"},inputTooShort:function(n){return"لطفاً تعداد "+(n.minimum-n.input.length)+" کاراکتر یا بیشتر وارد نمایید"},loadingMore:function(){return"در حال بارگذاری نتایج بیشتر..."},maximumSelected:function(n){return"شما تنها می‌توانید "+n.maximum+" آیتم را انتخاب نمایید"},noResults:function(){return"هیچ نتیجه‌ای یافت نشد"},searching:function(){return"در حال جستجو..."},removeAllItems:function(){return"همه موارد را حذف کنید"}}}),n.define,n.require}(); -------------------------------------------------------------------------------- /assets/vendors/select2/i18n/en.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.12 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/en",[],function(){return{errorLoading:function(){return"The results could not be loaded."},inputTooLong:function(e){var n=e.input.length-e.maximum,r="Please delete "+n+" character";return 1!=n&&(r+="s"),r},inputTooShort:function(e){return"Please enter "+(e.minimum-e.input.length)+" or more characters"},loadingMore:function(){return"Loading more results…"},maximumSelected:function(e){var n="You can only select "+e.maximum+" item";return 1!=e.maximum&&(n+="s"),n},noResults:function(){return"No results found"},searching:function(){return"Searching…"},removeAllItems:function(){return"Remove all items"}}}),e.define,e.require}(); -------------------------------------------------------------------------------- /assets/vendors/select2/i18n/he.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.12 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/he",[],function(){return{errorLoading:function(){return"שגיאה בטעינת התוצאות"},inputTooLong:function(n){var e=n.input.length-n.maximum,r="נא למחוק ";return r+=1===e?"תו אחד":e+" תווים"},inputTooShort:function(n){var e=n.minimum-n.input.length,r="נא להכניס ";return r+=1===e?"תו אחד":e+" תווים",r+=" או יותר"},loadingMore:function(){return"טוען תוצאות נוספות…"},maximumSelected:function(n){var e="באפשרותך לבחור עד ";return 1===n.maximum?e+="פריט אחד":e+=n.maximum+" פריטים",e},noResults:function(){return"לא נמצאו תוצאות"},searching:function(){return"מחפש…"},removeAllItems:function(){return"הסר את כל הפריטים"}}}),n.define,n.require}(); -------------------------------------------------------------------------------- /assets/vendors/select2/i18n/hi.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.12 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/hi",[],function(){return{errorLoading:function(){return"परिणामों को लोड नहीं किया जा सका।"},inputTooLong:function(n){var e=n.input.length-n.maximum,r=e+" अक्षर को हटा दें";return e>1&&(r=e+" अक्षरों को हटा दें "),r},inputTooShort:function(n){return"कृपया "+(n.minimum-n.input.length)+" या अधिक अक्षर दर्ज करें"},loadingMore:function(){return"अधिक परिणाम लोड हो रहे है..."},maximumSelected:function(n){return"आप केवल "+n.maximum+" आइटम का चयन कर सकते हैं"},noResults:function(){return"कोई परिणाम नहीं मिला"},searching:function(){return"खोज रहा है..."},removeAllItems:function(){return"सभी वस्तुओं को हटा दें"}}}),n.define,n.require}(); -------------------------------------------------------------------------------- /assets/vendors/select2/i18n/hr.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.12 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/hr",[],function(){function n(n){var e=" "+n+" znak";return n%10<5&&n%10>0&&(n%100<5||n%100>19)?n%10>1&&(e+="a"):e+="ova",e}return{errorLoading:function(){return"Preuzimanje nije uspjelo."},inputTooLong:function(e){return"Unesite "+n(e.input.length-e.maximum)},inputTooShort:function(e){return"Unesite još "+n(e.minimum-e.input.length)},loadingMore:function(){return"Učitavanje rezultata…"},maximumSelected:function(n){return"Maksimalan broj odabranih stavki je "+n.maximum},noResults:function(){return"Nema rezultata"},searching:function(){return"Pretraga…"},removeAllItems:function(){return"Ukloni sve stavke"}}}),n.define,n.require}(); -------------------------------------------------------------------------------- /assets/vendors/select2/i18n/af.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.12 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/af",[],function(){return{errorLoading:function(){return"Die resultate kon nie gelaai word nie."},inputTooLong:function(e){var n=e.input.length-e.maximum,r="Verwyders asseblief "+n+" character";return 1!=n&&(r+="s"),r},inputTooShort:function(e){return"Voer asseblief "+(e.minimum-e.input.length)+" of meer karakters"},loadingMore:function(){return"Meer resultate word gelaai…"},maximumSelected:function(e){var n="Kies asseblief net "+e.maximum+" item";return 1!=e.maximum&&(n+="s"),n},noResults:function(){return"Geen resultate gevind"},searching:function(){return"Besig…"},removeAllItems:function(){return"Verwyder alle items"}}}),e.define,e.require}(); -------------------------------------------------------------------------------- /assets/vendors/select2/i18n/de.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.12 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/de",[],function(){return{errorLoading:function(){return"Die Ergebnisse konnten nicht geladen werden."},inputTooLong:function(e){return"Bitte "+(e.input.length-e.maximum)+" Zeichen weniger eingeben"},inputTooShort:function(e){return"Bitte "+(e.minimum-e.input.length)+" Zeichen mehr eingeben"},loadingMore:function(){return"Lade mehr Ergebnisse…"},maximumSelected:function(e){var n="Sie können nur "+e.maximum+" Element";return 1!=e.maximum&&(n+="e"),n+=" auswählen"},noResults:function(){return"Keine Übereinstimmungen gefunden"},searching:function(){return"Suche…"},removeAllItems:function(){return"Entferne alle Elemente"}}}),e.define,e.require}(); -------------------------------------------------------------------------------- /assets/vendors/select2/i18n/eu.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.12 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/eu",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n="Idatzi ";return n+=1==t?"karaktere bat":t+" karaktere",n+=" gutxiago"},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Idatzi ";return n+=1==t?"karaktere bat":t+" karaktere",n+=" gehiago"},loadingMore:function(){return"Emaitza gehiago kargatzen…"},maximumSelected:function(e){return 1===e.maximum?"Elementu bakarra hauta dezakezu":e.maximum+" elementu hauta ditzakezu soilik"},noResults:function(){return"Ez da bat datorrenik aurkitu"},searching:function(){return"Bilatzen…"},removeAllItems:function(){return"Kendu elementu guztiak"}}}),e.define,e.require}(); -------------------------------------------------------------------------------- /assets/vendors/select2/i18n/pt-BR.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.12 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/pt-BR",[],function(){return{errorLoading:function(){return"Os resultados não puderam ser carregados."},inputTooLong:function(e){var n=e.input.length-e.maximum,r="Apague "+n+" caracter";return 1!=n&&(r+="es"),r},inputTooShort:function(e){return"Digite "+(e.minimum-e.input.length)+" ou mais caracteres"},loadingMore:function(){return"Carregando mais resultados…"},maximumSelected:function(e){var n="Você só pode selecionar "+e.maximum+" ite";return 1==e.maximum?n+="m":n+="ns",n},noResults:function(){return"Nenhum resultado encontrado"},searching:function(){return"Buscando…"},removeAllItems:function(){return"Remover todos os itens"}}}),e.define,e.require}(); -------------------------------------------------------------------------------- /assets/vendors/select2/i18n/mk.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.12 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/mk",[],function(){return{inputTooLong:function(n){var e=(n.input.length,n.maximum,"Ве молиме внесете "+n.maximum+" помалку карактер");return 1!==n.maximum&&(e+="и"),e},inputTooShort:function(n){var e=(n.minimum,n.input.length,"Ве молиме внесете уште "+n.maximum+" карактер");return 1!==n.maximum&&(e+="и"),e},loadingMore:function(){return"Вчитување резултати…"},maximumSelected:function(n){var e="Можете да изберете само "+n.maximum+" ставк";return 1===n.maximum?e+="а":e+="и",e},noResults:function(){return"Нема пронајдено совпаѓања"},searching:function(){return"Пребарување…"},removeAllItems:function(){return"Отстрани ги сите предмети"}}}),n.define,n.require}(); -------------------------------------------------------------------------------- /assets/vendors/select2/i18n/pt.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.12 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/pt",[],function(){return{errorLoading:function(){return"Os resultados não puderam ser carregados."},inputTooLong:function(e){var r=e.input.length-e.maximum,n="Por favor apague "+r+" ";return n+=1!=r?"caracteres":"caractere"},inputTooShort:function(e){return"Introduza "+(e.minimum-e.input.length)+" ou mais caracteres"},loadingMore:function(){return"A carregar mais resultados…"},maximumSelected:function(e){var r="Apenas pode seleccionar "+e.maximum+" ";return r+=1!=e.maximum?"itens":"item"},noResults:function(){return"Sem resultados"},searching:function(){return"A procurar…"},removeAllItems:function(){return"Remover todos os itens"}}}),e.define,e.require}(); -------------------------------------------------------------------------------- /assets/vendors/select2/i18n/lv.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.12 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/lv",[],function(){function e(e,n,u,i){return 11===e?n:e%10==1?u:i}return{inputTooLong:function(n){var u=n.input.length-n.maximum,i="Lūdzu ievadiet par "+u;return(i+=" simbol"+e(u,"iem","u","iem"))+" mazāk"},inputTooShort:function(n){var u=n.minimum-n.input.length,i="Lūdzu ievadiet vēl "+u;return i+=" simbol"+e(u,"us","u","us")},loadingMore:function(){return"Datu ielāde…"},maximumSelected:function(n){var u="Jūs varat izvēlēties ne vairāk kā "+n.maximum;return u+=" element"+e(n.maximum,"us","u","us")},noResults:function(){return"Sakritību nav"},searching:function(){return"Meklēšana…"},removeAllItems:function(){return"Noņemt visus vienumus"}}}),e.define,e.require}(); -------------------------------------------------------------------------------- /assets/vendors/select2/i18n/bn.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.12 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/bn",[],function(){return{errorLoading:function(){return"ফলাফলগুলি লোড করা যায়নি।"},inputTooLong:function(n){var e=n.input.length-n.maximum,u="অনুগ্রহ করে "+e+" টি অক্ষর মুছে দিন।";return 1!=e&&(u="অনুগ্রহ করে "+e+" টি অক্ষর মুছে দিন।"),u},inputTooShort:function(n){return n.minimum-n.input.length+" টি অক্ষর অথবা অধিক অক্ষর লিখুন।"},loadingMore:function(){return"আরো ফলাফল লোড হচ্ছে ..."},maximumSelected:function(n){var e=n.maximum+" টি আইটেম নির্বাচন করতে পারবেন।";return 1!=n.maximum&&(e=n.maximum+" টি আইটেম নির্বাচন করতে পারবেন।"),e},noResults:function(){return"কোন ফলাফল পাওয়া যায়নি।"},searching:function(){return"অনুসন্ধান করা হচ্ছে ..."}}}),n.define,n.require}(); -------------------------------------------------------------------------------- /assets/vendors/select2/i18n/sq.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.12 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/sq",[],function(){return{errorLoading:function(){return"Rezultatet nuk mund të ngarkoheshin."},inputTooLong:function(e){var n=e.input.length-e.maximum,t="Të lutem fshi "+n+" karakter";return 1!=n&&(t+="e"),t},inputTooShort:function(e){return"Të lutem shkruaj "+(e.minimum-e.input.length)+" ose më shumë karaktere"},loadingMore:function(){return"Duke ngarkuar më shumë rezultate…"},maximumSelected:function(e){var n="Mund të zgjedhësh vetëm "+e.maximum+" element";return 1!=e.maximum&&(n+="e"),n},noResults:function(){return"Nuk u gjet asnjë rezultat"},searching:function(){return"Duke kërkuar…"},removeAllItems:function(){return"Hiq të gjitha sendet"}}}),e.define,e.require}(); -------------------------------------------------------------------------------- /assets/vendors/select2/i18n/ca.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.12 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/ca",[],function(){return{errorLoading:function(){return"La càrrega ha fallat"},inputTooLong:function(e){var n=e.input.length-e.maximum,r="Si us plau, elimina "+n+" car";return r+=1==n?"àcter":"àcters"},inputTooShort:function(e){var n=e.minimum-e.input.length,r="Si us plau, introdueix "+n+" car";return r+=1==n?"àcter":"àcters"},loadingMore:function(){return"Carregant més resultats…"},maximumSelected:function(e){var n="Només es pot seleccionar "+e.maximum+" element";return 1!=e.maximum&&(n+="s"),n},noResults:function(){return"No s'han trobat resultats"},searching:function(){return"Cercant…"},removeAllItems:function(){return"Treu tots els elements"}}}),e.define,e.require}(); -------------------------------------------------------------------------------- /assets/vendors/select2/i18n/it.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.12 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/it",[],function(){return{errorLoading:function(){return"I risultati non possono essere caricati."},inputTooLong:function(e){var n=e.input.length-e.maximum,t="Per favore cancella "+n+" caratter";return t+=1!==n?"i":"e"},inputTooShort:function(e){return"Per favore inserisci "+(e.minimum-e.input.length)+" o più caratteri"},loadingMore:function(){return"Caricando più risultati…"},maximumSelected:function(e){var n="Puoi selezionare solo "+e.maximum+" element";return 1!==e.maximum?n+="i":n+="o",n},noResults:function(){return"Nessun risultato trovato"},searching:function(){return"Sto cercando…"},removeAllItems:function(){return"Rimuovi tutti gli oggetti"}}}),e.define,e.require}(); -------------------------------------------------------------------------------- /assets/vendors/select2/i18n/ps.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.12 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ps",[],function(){return{errorLoading:function(){return"پايلي نه سي ترلاسه کېدای"},inputTooLong:function(n){var e=n.input.length-n.maximum,r="د مهربانۍ لمخي "+e+" توری ړنګ کړئ";return 1!=e&&(r=r.replace("توری","توري")),r},inputTooShort:function(n){return"لږ تر لږه "+(n.minimum-n.input.length)+" يا ډېر توري وليکئ"},loadingMore:function(){return"نوري پايلي ترلاسه کيږي..."},maximumSelected:function(n){var e="تاسو يوازي "+n.maximum+" قلم په نښه کولای سی";return 1!=n.maximum&&(e=e.replace("قلم","قلمونه")),e},noResults:function(){return"پايلي و نه موندل سوې"},searching:function(){return"لټول کيږي..."},removeAllItems:function(){return"ټول توکي لرې کړئ"}}}),n.define,n.require}(); -------------------------------------------------------------------------------- /assets/vendors/select2/i18n/nl.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.12 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/nl",[],function(){return{errorLoading:function(){return"De resultaten konden niet worden geladen."},inputTooLong:function(e){return"Gelieve "+(e.input.length-e.maximum)+" karakters te verwijderen"},inputTooShort:function(e){return"Gelieve "+(e.minimum-e.input.length)+" of meer karakters in te voeren"},loadingMore:function(){return"Meer resultaten laden…"},maximumSelected:function(e){var n=1==e.maximum?"kan":"kunnen",r="Er "+n+" maar "+e.maximum+" item";return 1!=e.maximum&&(r+="s"),r+=" worden geselecteerd"},noResults:function(){return"Geen resultaten gevonden…"},searching:function(){return"Zoeken…"},removeAllItems:function(){return"Verwijder alle items"}}}),e.define,e.require}(); -------------------------------------------------------------------------------- /assets/vendors/select2/i18n/fr.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.12 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/fr",[],function(){return{errorLoading:function(){return"Les résultats ne peuvent pas être chargés."},inputTooLong:function(e){var n=e.input.length-e.maximum;return"Supprimez "+n+" caractère"+(n>1?"s":"")},inputTooShort:function(e){var n=e.minimum-e.input.length;return"Saisissez au moins "+n+" caractère"+(n>1?"s":"")},loadingMore:function(){return"Chargement de résultats supplémentaires…"},maximumSelected:function(e){return"Vous pouvez seulement sélectionner "+e.maximum+" élément"+(e.maximum>1?"s":"")},noResults:function(){return"Aucun résultat trouvé"},searching:function(){return"Recherche en cours…"},removeAllItems:function(){return"Supprimer tous les éléments"}}}),e.define,e.require}(); -------------------------------------------------------------------------------- /assets/vendors/select2/i18n/ne.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.12 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ne",[],function(){return{errorLoading:function(){return"नतिजाहरु देखाउन सकिएन।"},inputTooLong:function(n){var e=n.input.length-n.maximum,u="कृपया "+e+" अक्षर मेटाउनुहोस्।";return 1!=e&&(u+="कृपया "+e+" अक्षरहरु मेटाउनुहोस्।"),u},inputTooShort:function(n){return"कृपया बाँकी रहेका "+(n.minimum-n.input.length)+" वा अरु धेरै अक्षरहरु भर्नुहोस्।"},loadingMore:function(){return"अरु नतिजाहरु भरिँदैछन् …"},maximumSelected:function(n){var e="तँपाई "+n.maximum+" वस्तु मात्र छान्न पाउँनुहुन्छ।";return 1!=n.maximum&&(e="तँपाई "+n.maximum+" वस्तुहरु मात्र छान्न पाउँनुहुन्छ।"),e},noResults:function(){return"कुनै पनि नतिजा भेटिएन।"},searching:function(){return"खोजि हुँदैछ…"}}}),n.define,n.require}(); -------------------------------------------------------------------------------- /assets/vendors/select2/i18n/sl.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.12 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/sl",[],function(){return{errorLoading:function(){return"Zadetkov iskanja ni bilo mogoče naložiti."},inputTooLong:function(e){var n=e.input.length-e.maximum,t="Prosim zbrišite "+n+" znak";return 2==n?t+="a":1!=n&&(t+="e"),t},inputTooShort:function(e){var n=e.minimum-e.input.length,t="Prosim vpišite še "+n+" znak";return 2==n?t+="a":1!=n&&(t+="e"),t},loadingMore:function(){return"Nalagam več zadetkov…"},maximumSelected:function(e){var n="Označite lahko največ "+e.maximum+" predmet";return 2==e.maximum?n+="a":1!=e.maximum&&(n+="e"),n},noResults:function(){return"Ni zadetkov."},searching:function(){return"Iščem…"},removeAllItems:function(){return"Odstranite vse elemente"}}}),e.define,e.require}(); -------------------------------------------------------------------------------- /assets/vendors/select2/i18n/es.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.12 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/es",[],function(){return{errorLoading:function(){return"No se pudieron cargar los resultados"},inputTooLong:function(e){var n=e.input.length-e.maximum,r="Por favor, elimine "+n+" car";return r+=1==n?"ácter":"acteres"},inputTooShort:function(e){var n=e.minimum-e.input.length,r="Por favor, introduzca "+n+" car";return r+=1==n?"ácter":"acteres"},loadingMore:function(){return"Cargando más resultados…"},maximumSelected:function(e){var n="Sólo puede seleccionar "+e.maximum+" elemento";return 1!=e.maximum&&(n+="s"),n},noResults:function(){return"No se encontraron resultados"},searching:function(){return"Buscando…"},removeAllItems:function(){return"Eliminar todos los elementos"}}}),e.define,e.require}(); -------------------------------------------------------------------------------- /assets/vendors/select2/i18n/gl.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.12 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/gl",[],function(){return{errorLoading:function(){return"Non foi posíbel cargar os resultados."},inputTooLong:function(e){var n=e.input.length-e.maximum;return 1===n?"Elimine un carácter":"Elimine "+n+" caracteres"},inputTooShort:function(e){var n=e.minimum-e.input.length;return 1===n?"Engada un carácter":"Engada "+n+" caracteres"},loadingMore:function(){return"Cargando máis resultados…"},maximumSelected:function(e){return 1===e.maximum?"Só pode seleccionar un elemento":"Só pode seleccionar "+e.maximum+" elementos"},noResults:function(){return"Non se atoparon resultados"},searching:function(){return"Buscando…"},removeAllItems:function(){return"Elimina todos os elementos"}}}),e.define,e.require}(); -------------------------------------------------------------------------------- /assets/vendors/select2/i18n/ro.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.12 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/ro",[],function(){return{errorLoading:function(){return"Rezultatele nu au putut fi incărcate."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Vă rugăm să ștergeți"+t+" caracter";return 1!==t&&(n+="e"),n},inputTooShort:function(e){return"Vă rugăm să introduceți "+(e.minimum-e.input.length)+" sau mai multe caractere"},loadingMore:function(){return"Se încarcă mai multe rezultate…"},maximumSelected:function(e){var t="Aveți voie să selectați cel mult "+e.maximum;return t+=" element",1!==e.maximum&&(t+="e"),t},noResults:function(){return"Nu au fost găsite rezultate"},searching:function(){return"Căutare…"},removeAllItems:function(){return"Eliminați toate elementele"}}}),e.define,e.require}(); -------------------------------------------------------------------------------- /assets/vendors/select2/i18n/lt.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.12 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/lt",[],function(){function n(n,e,i,t){return n%10==1&&(n%100<11||n%100>19)?e:n%10>=2&&n%10<=9&&(n%100<11||n%100>19)?i:t}return{inputTooLong:function(e){var i=e.input.length-e.maximum,t="Pašalinkite "+i+" simbol";return t+=n(i,"į","ius","ių")},inputTooShort:function(e){var i=e.minimum-e.input.length,t="Įrašykite dar "+i+" simbol";return t+=n(i,"į","ius","ių")},loadingMore:function(){return"Kraunama daugiau rezultatų…"},maximumSelected:function(e){var i="Jūs galite pasirinkti tik "+e.maximum+" element";return i+=n(e.maximum,"ą","us","ų")},noResults:function(){return"Atitikmenų nerasta"},searching:function(){return"Ieškoma…"},removeAllItems:function(){return"Pašalinti visus elementus"}}}),n.define,n.require}(); -------------------------------------------------------------------------------- /assets/vendors/select2/i18n/pl.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.12 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/pl",[],function(){var n=["znak","znaki","znaków"],e=["element","elementy","elementów"],r=function(n,e){return 1===n?e[0]:n>1&&n<=4?e[1]:n>=5?e[2]:void 0};return{errorLoading:function(){return"Nie można załadować wyników."},inputTooLong:function(e){var t=e.input.length-e.maximum;return"Usuń "+t+" "+r(t,n)},inputTooShort:function(e){var t=e.minimum-e.input.length;return"Podaj przynajmniej "+t+" "+r(t,n)},loadingMore:function(){return"Trwa ładowanie…"},maximumSelected:function(n){return"Możesz zaznaczyć tylko "+n.maximum+" "+r(n.maximum,e)},noResults:function(){return"Brak wyników"},searching:function(){return"Trwa wyszukiwanie…"},removeAllItems:function(){return"Usuń wszystkie przedmioty"}}}),n.define,n.require}(); -------------------------------------------------------------------------------- /assets/vendors/select2/i18n/el.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.12 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/el",[],function(){return{errorLoading:function(){return"Τα αποτελέσματα δεν μπόρεσαν να φορτώσουν."},inputTooLong:function(n){var e=n.input.length-n.maximum,u="Παρακαλώ διαγράψτε "+e+" χαρακτήρ";return 1==e&&(u+="α"),1!=e&&(u+="ες"),u},inputTooShort:function(n){return"Παρακαλώ συμπληρώστε "+(n.minimum-n.input.length)+" ή περισσότερους χαρακτήρες"},loadingMore:function(){return"Φόρτωση περισσότερων αποτελεσμάτων…"},maximumSelected:function(n){var e="Μπορείτε να επιλέξετε μόνο "+n.maximum+" επιλογ";return 1==n.maximum&&(e+="ή"),1!=n.maximum&&(e+="ές"),e},noResults:function(){return"Δεν βρέθηκαν αποτελέσματα"},searching:function(){return"Αναζήτηση…"},removeAllItems:function(){return"Καταργήστε όλα τα στοιχεία"}}}),n.define,n.require}(); -------------------------------------------------------------------------------- /assets/vendors/select2/i18n/bs.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.12 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/bs",[],function(){function e(e,n,r,t){return e%10==1&&e%100!=11?n:e%10>=2&&e%10<=4&&(e%100<12||e%100>14)?r:t}return{errorLoading:function(){return"Preuzimanje nije uspijelo."},inputTooLong:function(n){var r=n.input.length-n.maximum,t="Obrišite "+r+" simbol";return t+=e(r,"","a","a")},inputTooShort:function(n){var r=n.minimum-n.input.length,t="Ukucajte bar još "+r+" simbol";return t+=e(r,"","a","a")},loadingMore:function(){return"Preuzimanje još rezultata…"},maximumSelected:function(n){var r="Možete izabrati samo "+n.maximum+" stavk";return r+=e(n.maximum,"u","e","i")},noResults:function(){return"Ništa nije pronađeno"},searching:function(){return"Pretraga…"},removeAllItems:function(){return"Uklonite sve stavke"}}}),e.define,e.require}(); -------------------------------------------------------------------------------- /assets/vendors/select2/i18n/sr.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.12 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/sr",[],function(){function n(n,e,r,t){return n%10==1&&n%100!=11?e:n%10>=2&&n%10<=4&&(n%100<12||n%100>14)?r:t}return{errorLoading:function(){return"Preuzimanje nije uspelo."},inputTooLong:function(e){var r=e.input.length-e.maximum,t="Obrišite "+r+" simbol";return t+=n(r,"","a","a")},inputTooShort:function(e){var r=e.minimum-e.input.length,t="Ukucajte bar još "+r+" simbol";return t+=n(r,"","a","a")},loadingMore:function(){return"Preuzimanje još rezultata…"},maximumSelected:function(e){var r="Možete izabrati samo "+e.maximum+" stavk";return r+=n(e.maximum,"u","e","i")},noResults:function(){return"Ništa nije pronađeno"},searching:function(){return"Pretraga…"},removeAllItems:function(){return"Уклоните све ставке"}}}),n.define,n.require}(); -------------------------------------------------------------------------------- /assets/vendors/select2/i18n/uk.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.12 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/uk",[],function(){function n(n,e,u,r){return n%100>10&&n%100<15?r:n%10==1?e:n%10>1&&n%10<5?u:r}return{errorLoading:function(){return"Неможливо завантажити результати"},inputTooLong:function(e){return"Будь ласка, видаліть "+(e.input.length-e.maximum)+" "+n(e.maximum,"літеру","літери","літер")},inputTooShort:function(n){return"Будь ласка, введіть "+(n.minimum-n.input.length)+" або більше літер"},loadingMore:function(){return"Завантаження інших результатів…"},maximumSelected:function(e){return"Ви можете вибрати лише "+e.maximum+" "+n(e.maximum,"пункт","пункти","пунктів")},noResults:function(){return"Нічого не знайдено"},searching:function(){return"Пошук…"},removeAllItems:function(){return"Видалити всі елементи"}}}),n.define,n.require}(); -------------------------------------------------------------------------------- /assets/vendors/select2/i18n/sr-Cyrl.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.12 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/sr-Cyrl",[],function(){function n(n,e,r,u){return n%10==1&&n%100!=11?e:n%10>=2&&n%10<=4&&(n%100<12||n%100>14)?r:u}return{errorLoading:function(){return"Преузимање није успело."},inputTooLong:function(e){var r=e.input.length-e.maximum,u="Обришите "+r+" симбол";return u+=n(r,"","а","а")},inputTooShort:function(e){var r=e.minimum-e.input.length,u="Укуцајте бар још "+r+" симбол";return u+=n(r,"","а","а")},loadingMore:function(){return"Преузимање још резултата…"},maximumSelected:function(e){var r="Можете изабрати само "+e.maximum+" ставк";return r+=n(e.maximum,"у","е","и")},noResults:function(){return"Ништа није пронађено"},searching:function(){return"Претрага…"},removeAllItems:function(){return"Уклоните све ставке"}}}),n.define,n.require}(); -------------------------------------------------------------------------------- /assets/vendors/select2/i18n/ru.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.12 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ru",[],function(){function n(n,e,r,u){return n%10<5&&n%10>0&&n%100<5||n%100>20?n%10>1?r:e:u}return{errorLoading:function(){return"Невозможно загрузить результаты"},inputTooLong:function(e){var r=e.input.length-e.maximum,u="Пожалуйста, введите на "+r+" символ";return u+=n(r,"","a","ов"),u+=" меньше"},inputTooShort:function(e){var r=e.minimum-e.input.length,u="Пожалуйста, введите ещё хотя бы "+r+" символ";return u+=n(r,"","a","ов")},loadingMore:function(){return"Загрузка данных…"},maximumSelected:function(e){var r="Вы можете выбрать не более "+e.maximum+" элемент";return r+=n(e.maximum,"","a","ов")},noResults:function(){return"Совпадений не найдено"},searching:function(){return"Поиск…"},removeAllItems:function(){return"Удалить все элементы"}}}),n.define,n.require}(); -------------------------------------------------------------------------------- /assets/vendors/select2/i18n/dsb.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.12 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/dsb",[],function(){var n=["znamuško","znamušce","znamuška","znamuškow"],e=["zapisk","zapiska","zapiski","zapiskow"],u=function(n,e){return 1===n?e[0]:2===n?e[1]:n>2&&n<=4?e[2]:n>=5?e[3]:void 0};return{errorLoading:function(){return"Wuslědki njejsu se dali zacytaś."},inputTooLong:function(e){var a=e.input.length-e.maximum;return"Pšosym lašuj "+a+" "+u(a,n)},inputTooShort:function(e){var a=e.minimum-e.input.length;return"Pšosym zapódaj nanejmjenjej "+a+" "+u(a,n)},loadingMore:function(){return"Dalšne wuslědki se zacytaju…"},maximumSelected:function(n){return"Móžoš jano "+n.maximum+" "+u(n.maximum,e)+"wubraś."},noResults:function(){return"Žedne wuslědki namakane"},searching:function(){return"Pyta se…"},removeAllItems:function(){return"Remove all items"}}}),n.define,n.require}(); -------------------------------------------------------------------------------- /assets/vendors/select2/i18n/hsb.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.12 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/hsb",[],function(){var n=["znamješko","znamješce","znamješka","znamješkow"],e=["zapisk","zapiskaj","zapiski","zapiskow"],u=function(n,e){return 1===n?e[0]:2===n?e[1]:n>2&&n<=4?e[2]:n>=5?e[3]:void 0};return{errorLoading:function(){return"Wuslědki njedachu so začitać."},inputTooLong:function(e){var a=e.input.length-e.maximum;return"Prošu zhašej "+a+" "+u(a,n)},inputTooShort:function(e){var a=e.minimum-e.input.length;return"Prošu zapodaj znajmjeńša "+a+" "+u(a,n)},loadingMore:function(){return"Dalše wuslědki so začitaja…"},maximumSelected:function(n){return"Móžeš jenož "+n.maximum+" "+u(n.maximum,e)+"wubrać"},noResults:function(){return"Žane wuslědki namakane"},searching:function(){return"Pyta so…"},removeAllItems:function(){return"Remove all items"}}}),n.define,n.require}(); -------------------------------------------------------------------------------- /assets/js/bp-xprofile-custom-field-types.js: -------------------------------------------------------------------------------- 1 | (function ($) { 2 | 'use strict'; 3 | // colors 4 | if (!Modernizr.inputtypes.color) { 5 | // No html5 field colorpicker => Calling jscolor. 6 | $('.bpxcftr-color').addClass('color'); 7 | } 8 | 9 | $('#profile-edit-form').attr('enctype', 'multipart/form-data'); 10 | $('#signup-form').attr('enctype', 'multipart/form-data'); 11 | $('#your-profile').attr('enctype', 'multipart/form-data'); 12 | 13 | // Slider. 14 | $('input.bpxcftr-slider').on('input', function () { 15 | $('#output-' + $(this).attr('id')).html($(this).val()); 16 | }); 17 | 18 | $('.bpxcftr-remove-tag').on('click', function () { 19 | 20 | var $this = $(this); 21 | 22 | $.post( 23 | ajaxurl, 24 | { 25 | action: 'bpxcftr_remove_user_tag', 26 | nonce: $this.data('nonce'), 27 | field_id: $this.data('fieldId'), 28 | tag: $this.data('tag') 29 | }, 30 | function (resp) { 31 | if (resp.success) { 32 | $this.remove(); 33 | } 34 | } 35 | ); 36 | 37 | }); 38 | 39 | })(jQuery); -------------------------------------------------------------------------------- /assets/vendors/select2/i18n/cs.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.12 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/cs",[],function(){function e(e,n){switch(e){case 2:return n?"dva":"dvě";case 3:return"tři";case 4:return"čtyři"}return""}return{errorLoading:function(){return"Výsledky nemohly být načteny."},inputTooLong:function(n){var t=n.input.length-n.maximum;return 1==t?"Prosím, zadejte o jeden znak méně.":t<=4?"Prosím, zadejte o "+e(t,!0)+" znaky méně.":"Prosím, zadejte o "+t+" znaků méně."},inputTooShort:function(n){var t=n.minimum-n.input.length;return 1==t?"Prosím, zadejte ještě jeden znak.":t<=4?"Prosím, zadejte ještě další "+e(t,!0)+" znaky.":"Prosím, zadejte ještě dalších "+t+" znaků."},loadingMore:function(){return"Načítají se další výsledky…"},maximumSelected:function(n){var t=n.maximum;return 1==t?"Můžete zvolit jen jednu položku.":t<=4?"Můžete zvolit maximálně "+e(t,!1)+" položky.":"Můžete zvolit maximálně "+t+" položek."},noResults:function(){return"Nenalezeny žádné položky."},searching:function(){return"Vyhledávání…"},removeAllItems:function(){return"Odstraňte všechny položky"}}}),e.define,e.require}(); -------------------------------------------------------------------------------- /assets/vendors/select2/i18n/sk.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.12 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/sk",[],function(){var e={2:function(e){return e?"dva":"dve"},3:function(){return"tri"},4:function(){return"štyri"}};return{errorLoading:function(){return"Výsledky sa nepodarilo načítať."},inputTooLong:function(n){var t=n.input.length-n.maximum;return 1==t?"Prosím, zadajte o jeden znak menej":t>=2&&t<=4?"Prosím, zadajte o "+e[t](!0)+" znaky menej":"Prosím, zadajte o "+t+" znakov menej"},inputTooShort:function(n){var t=n.minimum-n.input.length;return 1==t?"Prosím, zadajte ešte jeden znak":t<=4?"Prosím, zadajte ešte ďalšie "+e[t](!0)+" znaky":"Prosím, zadajte ešte ďalších "+t+" znakov"},loadingMore:function(){return"Načítanie ďalších výsledkov…"},maximumSelected:function(n){return 1==n.maximum?"Môžete zvoliť len jednu položku":n.maximum>=2&&n.maximum<=4?"Môžete zvoliť najviac "+e[n.maximum](!1)+" položky":"Môžete zvoliť najviac "+n.maximum+" položiek"},noResults:function(){return"Nenašli sa žiadne položky"},searching:function(){return"Vyhľadávanie…"},removeAllItems:function(){return"Odstráňte všetky položky"}}}),e.define,e.require}(); -------------------------------------------------------------------------------- /src/field-types/class-field-type-oembed.php: -------------------------------------------------------------------------------- 1 | name = _x( 'oEmbed URL', 'xprofile field type', 'bp-xprofile-custom-field-types' ); 27 | $this->category = _x( 'Custom Fields', 'xprofile field type category', 'bp-xprofile-custom-field-types' ); 28 | } 29 | 30 | /** 31 | * Formats URL values for display. 32 | * 33 | * @param string $field_value The URL value, as saved in the database. 34 | * @param string|int $field_id Optional. ID of the field. 35 | * 36 | * @return string URL converted to oembed content. 37 | */ 38 | public static function display_filter( $field_value, $field_id = '' ) { 39 | // Can not cache oEmbed response currently. We will need either data id or user id to allow us caching. 40 | if ( ! empty( $field_value ) ) { 41 | return wp_oembed_get( $field_value ); 42 | } 43 | 44 | return $field_value; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/core/class-data-store.php: -------------------------------------------------------------------------------- 1 | data[ $name ] ) ? $this->data[ $name ] : null; 39 | } 40 | 41 | /** 42 | * Checks if a property is set. 43 | * 44 | * @param string $name property name. 45 | * 46 | * @return bool 47 | */ 48 | public function __isset( $name ) { 49 | return isset( $this->data[ $name ] ); 50 | } 51 | 52 | /** 53 | * Sets a property. 54 | * 55 | * @param string $name property name. 56 | * @param mixed $value value. 57 | */ 58 | public function __set( $name, $value ) { 59 | $this->data[ $name ] = $value; 60 | } 61 | 62 | /** 63 | * Unsets a property. 64 | * 65 | * @param string $name property name. 66 | */ 67 | public function __unset( $name ) { 68 | unset( $this->data[ $name ] ); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/admin/class-admin.php: -------------------------------------------------------------------------------- 1 | setup(); 29 | } 30 | 31 | /** 32 | * Binds hooks 33 | */ 34 | private function setup() { 35 | // called after pp_loaded. 36 | add_action( 'admin_init', array( $this, 'init' ) ); 37 | add_action( 'admin_notices', array( $this, 'notices' ) ); 38 | } 39 | 40 | /** 41 | * Initializes. 42 | */ 43 | public function init() { 44 | 45 | if ( ! bp_is_active( 'xprofile' ) ) { 46 | $notices = (array) get_option( 'bpxcftr_notices', array() ); 47 | 48 | $notices[] = __( 'BuddyPress Xprofile Custom Field Types plugin needs Buddypress Xprofile Component. Please enable Xprofile first.', 'buddypress-xprofile-custom-fields-types' ); 49 | update_option( 'bpxcftr_notices', $notices ); 50 | } 51 | } 52 | 53 | /** 54 | * Shows notices. 55 | */ 56 | public function notices() { 57 | $notices = get_option( 'bpxcftr_notices' ); 58 | 59 | if ( $notices ) { 60 | foreach ( $notices as $notice ) { 61 | $notice = wp_kses_data( $notice ); 62 | $notice = wpautop( $notice ); 63 | 64 | echo "
{$notice}
"; 65 | } 66 | delete_option( 'bpxcftr_notices' ); 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/filters/class-xprofile-kses-filter.php: -------------------------------------------------------------------------------- 1 | setup(); 31 | } 32 | 33 | /** 34 | * Sets up hooks. 35 | */ 36 | public function setup() { 37 | add_filter( 'xprofile_allowed_tags', array( $this, 'filter' ), 10, 3 ); 38 | } 39 | 40 | /** 41 | * Filters xrofile allowed tags and extends for target attribute if needed. 42 | * 43 | * @param array $xprofile_allowedtags Array of allowed tags for profile field values. 44 | * @param \BP_XProfile_ProfileData|null $data_obj The BP_XProfile_ProfileData object. 45 | * @param int|null $field_id The ID of the profile field. 46 | * 47 | * @return array 48 | */ 49 | public function filter( $xprofile_allowedtags, $data_obj, $field_id ) { 50 | 51 | if ( ! $field_id ) { 52 | return $xprofile_allowedtags; 53 | } 54 | 55 | $field = new \BP_XProfile_Field( $field_id ); 56 | if ( 'web' === $field->type && Field_Type_Web::get_link_target( $field_id ) === '_blank' && isset( $xprofile_allowedtags['a'] ) ) { 57 | $xprofile_allowedtags['a']['target'] = array(); 58 | } 59 | 60 | return $xprofile_allowedtags; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/handlers/class-label-filter.php: -------------------------------------------------------------------------------- 1 | setup(); 38 | } 39 | 40 | /** 41 | * Binds hooks 42 | */ 43 | private function setup() { 44 | add_filter( 'bp_get_the_profile_field_name', array( $this, 'filter_label' ) ); 45 | } 46 | 47 | /** 48 | * Filters field label. 49 | * 50 | * @param string $label label. 51 | * 52 | * @return string 53 | */ 54 | public function filter_label( $label ) { 55 | global $field; 56 | if ( ! $field || 'birthdate' !== $field->type ) { 57 | return $label; 58 | } 59 | 60 | $age_label = Field_Type_Birthdate::get_age_label( $field->id ); 61 | if ( ! $age_label ) { 62 | return $label; 63 | } 64 | 65 | // if we are here, should should change it in display context only. For edit context, the normal label should work. 66 | $is_edit = is_admin() || bp_is_register_page() || bp_is_user_profile_edit(); 67 | if ( apply_filters( 'bpxcftr_is_edit_profile_context', $is_edit ) ) { 68 | return $label; 69 | } 70 | 71 | return $age_label; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/filters/class-bp-profile-search-helper.php: -------------------------------------------------------------------------------- 1 | setup(); 31 | } 32 | 33 | /** 34 | * Sets up hooks. 35 | */ 36 | public function setup() { 37 | add_action( 'bps_custom_field', array( $this, 'register_field_types' ) ); 38 | add_action( 'bp_ps_custom_field', array( $this, 'register_field_types' ) ); 39 | } 40 | 41 | /** 42 | * Registers field types to Bp profile Search. 43 | * 44 | * @param \stdClass $field object. 45 | */ 46 | public function register_field_types( $field ) { 47 | 48 | $field_types = bpxcftr_get_field_types(); 49 | 50 | if ( ! isset( $field_types[ $field->type ] ) ) { 51 | return; 52 | } 53 | 54 | switch ( $field->type ) { 55 | 56 | case 'birthdate': 57 | case 'datepicker': 58 | $field->format = 'date'; 59 | break; 60 | 61 | case 'color': 62 | case 'email': 63 | case 'web': 64 | $field->format = 'text'; 65 | break; 66 | 67 | case 'number_minmax': 68 | case 'slider': 69 | $field->format = 'integer'; 70 | break; 71 | 72 | case 'decimal_number': 73 | $field->format = 'decimal'; 74 | break; 75 | 76 | case 'country': 77 | $field->format = 'text'; 78 | $field->options = Field_Type_Country::get_countries(); 79 | break; 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/handlers/class-taxonomy-terms-creator.php: -------------------------------------------------------------------------------- 1 | setup(); 31 | } 32 | 33 | /** 34 | * Binds hooks 35 | */ 36 | private function setup() { 37 | // Pre validate multiselect custom taxonomy. 38 | add_filter( 39 | 'bp_xprofile_set_field_data_pre_validate', 40 | array( $this, 'sanitize' ), 41 | 10, 42 | 3 43 | ); 44 | } 45 | 46 | /** 47 | * Sanitizes Value. 48 | * 49 | * @param mixed $value value. 50 | * @param \BP_XProfile_Field $field field object. 51 | * @param \BP_XProfile_Field_Type $field_type_obj field type object. 52 | * 53 | * @return array|string 54 | */ 55 | public function sanitize( $value, $field, $field_type_obj ) { 56 | // store Field's reference to allow us fetch it when validating. 57 | bpxcftr_set_current_field( $field ); 58 | 59 | if ( 'multiselect_custom_taxonomy' !== $field->type ) { 60 | return $value; 61 | } 62 | 63 | $allow_new_tags = Field_Type_Multi_Select_Taxonomy::allow_new_terms( $field->id ); 64 | $taxonomy_selected = Field_Type_Multi_Select_Taxonomy::get_selected_taxonomy( $field->id ); 65 | 66 | if ( empty( $taxonomy_selected ) || empty( $value ) ) { 67 | return ''; 68 | } 69 | 70 | // Add new tags if needed. 71 | $sanitized = array(); 72 | 73 | foreach ( $value as $tag ) { 74 | 75 | if ( ! term_exists( (int) $tag, $taxonomy_selected ) && ! term_exists( $tag, $taxonomy_selected ) ) { 76 | 77 | if ( ! $allow_new_tags ) { 78 | continue; 79 | } 80 | 81 | $res = wp_insert_term( $tag, $taxonomy_selected ); 82 | 83 | if ( ! is_wp_error( $res ) && is_array( $res ) ) { 84 | $sanitized[] = "{$res['term_id']}"; 85 | } 86 | } else { 87 | $sanitized[] = $tag; 88 | } 89 | } 90 | 91 | return $sanitized; 92 | } 93 | 94 | } 95 | -------------------------------------------------------------------------------- /src/handlers/class-birthdate-field-validator.php: -------------------------------------------------------------------------------- 1 | setup(); 31 | } 32 | 33 | /** 34 | * Binds hooks 35 | */ 36 | private function setup() { 37 | add_action( 'xprofile_data_before_save', array( $this, 'on_field_data_save' ) ); 38 | } 39 | 40 | /** 41 | * Validates on field save. 42 | * 43 | * @param \BP_XProfile_ProfileData $data data object. 44 | * 45 | * @return mixed 46 | */ 47 | public function on_field_data_save( $data ) { 48 | 49 | if ( ! is_user_logged_in() ) { 50 | return $data; 51 | } 52 | 53 | $field_id = $data->field_id; 54 | $field = new \BP_XProfile_Field( $field_id ); 55 | $min_age = Field_Type_Birthdate::get_min_age( $field_id ); 56 | 57 | if ( 'birthdate' !== $field->type || $min_age <= 0 ) { 58 | return $data; 59 | } 60 | 61 | $redirect_url = trailingslashit( bp_displayed_user_domain() . bp_get_profile_slug() . '/edit/group/' . bp_action_variable( 1 ) ); 62 | 63 | // Check birthdate. 64 | $now = new \DateTime(); 65 | $year = $_POST[ 'field_' . $field_id . '_year' ]; 66 | $month = $_POST[ 'field_' . $field_id . '_month' ]; 67 | $day = $_POST[ 'field_' . $field_id . '_day' ]; 68 | 69 | if ( ! is_numeric( $year ) || empty( $month ) || ! is_numeric( $day ) ) { 70 | bp_core_add_message( sprintf( __( 'Incorrect birthdate selection.', 'bp-xprofile-custom-field-types' ), $min_age ), 'error' ); 71 | bp_core_redirect( $redirect_url ); 72 | } 73 | 74 | $birthdate = new \DateTime( sprintf( '%s-%s-%s', str_pad( $day, 2, '0', STR_PAD_LEFT ), $month, $year ) ); 75 | 76 | if ( $now <= $birthdate ) { 77 | bp_core_add_message( sprintf( __( 'Incorrect birthdate selection.', 'bp-xprofile-custom-field-types' ), $min_age ), 'error' ); 78 | bp_core_redirect( $redirect_url ); 79 | } 80 | 81 | $age = $now->diff( $birthdate ); 82 | 83 | if ( $age->y < $min_age ) { 84 | bp_core_add_message( sprintf( __( 'You have to be at least %s years old.', 'bp-xprofile-custom-field-types' ), $min_age ), 'error' ); 85 | bp_core_redirect( $redirect_url ); 86 | } 87 | 88 | return $data; 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /assets/js/bp-xprofile-custom-field-types-admin.js: -------------------------------------------------------------------------------- 1 | jQuery( document).ready(function($) { 2 | 3 | var fieldWithOptions = ['checkbox_acceptance', 'select_custom_post_type', 'multiselect_custom_post_type', 4 | 'select_custom_taxonomy', 'multiselect_custom_taxonomy', 5 | 'decimal_number', 'number_minmax', 'slider','token', 'fromto', 'country', 'web', 'tags']; 6 | 7 | var $selectBox = $('#select2-box'); 8 | 9 | //on initial run for edit field page 10 | var fieldType = $('#fieldtype').val(); 11 | var lastFieldType = fieldType; 12 | toggleSelectSettingsBox(fieldType); 13 | 14 | if ($.inArray(fieldType, fieldWithOptions) !== -1) { 15 | $('#' + fieldType).show(); 16 | } 17 | 18 | // on field type selection change. 19 | $(document).on('change', '#fieldtype', function () { 20 | 21 | var fieldType = $(this).val(); 22 | if ($.inArray(lastFieldType, fieldWithOptions) !== -1) { 23 | $('#' + lastFieldType).hide(); 24 | } 25 | 26 | lastFieldType = fieldType; 27 | 28 | toggleSelectSettingsBox(fieldType); 29 | 30 | if ($.inArray(fieldType, fieldWithOptions) === -1) { 31 | return; 32 | } 33 | 34 | $('.bp-options-box').hide(); 35 | $('#' + fieldType).show(); 36 | 37 | }); 38 | 39 | // Clicking into the custom date format field should select the Custom radio button. 40 | var $birthdate_format_custom_value = jQuery( '#bpxcftr-birthdate-date-format-custom-value' ); 41 | var $birthdate_format_custom = jQuery( '#bpxcftr-birthdate-date-format-custom' ); 42 | var $birthdate_format_sample = jQuery( '#bpxcftr-birthdate-date-format-custom-sample' ); 43 | $birthdate_format_custom_value.on( 'focus', function() { 44 | $birthdate_format_custom.prop( 'checked', 'checked' ); 45 | } ); 46 | 47 | // Validate custom date field. 48 | var $birthdate_format_spinner = jQuery( '#bpxcftr-birthdate-date-format-custom-spinner' ); 49 | $birthdate_format_custom_value.on( 'change', function( e ) { 50 | $birthdate_format_spinner.addClass( 'is-active' ); 51 | jQuery.post( ajaxurl, { 52 | action: 'date_format', 53 | date: e.target.value 54 | }, 55 | function( response ) { 56 | $birthdate_format_spinner.removeClass( 'is-active' ); 57 | $birthdate_format_sample.html( response ); 58 | } ); 59 | } ); 60 | 61 | /** 62 | * Toggle Select2 box based on preference. 63 | * @param selectedType 64 | */ 65 | function toggleSelectSettingsBox( selectedType ) { 66 | 67 | if ( $.inArray( selectedType, BPXprofileCFTRAdmin.selectableTypes ) !== -1 ) { 68 | $selectBox.show(); 69 | } else { 70 | $selectBox.hide(); 71 | } 72 | 73 | } 74 | }); 75 | -------------------------------------------------------------------------------- /src/handlers/class-field-settings-handler.php: -------------------------------------------------------------------------------- 1 | setup(); 31 | } 32 | 33 | /** 34 | * Bind hooks 35 | */ 36 | private function setup() { 37 | add_action( 'bp_custom_profile_edit_fields_pre_visibility', array( $this, 'enable_select2' ) ); 38 | } 39 | 40 | /** 41 | * Enable_select2. 42 | */ 43 | public function enable_select2() { 44 | global $field; 45 | 46 | if ( ! $this->is_select2_enabled( $field ) ) { 47 | return; 48 | } 49 | 50 | $field_name_id = bp_get_the_profile_field_input_name(); 51 | // for multi valued field. 52 | if ( bpxcftr_is_multi_valued_field( $field ) ) { 53 | $field_name_id .= '[]'; 54 | } 55 | 56 | $allow_new_tags = false; 57 | 58 | if ( Field_Type_Multi_Select_Taxonomy::allow_new_terms( $field->id ) || Field_Type_Tags::allow_new_tags( $field->id ) ) { 59 | $allow_new_tags = true; 60 | } 61 | 62 | 63 | if ( $allow_new_tags ) { 64 | ?> 65 | 73 | 76 | 81 | id, 'field', 'do_select2' ); 105 | 106 | return 'on' === $do_select2; 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/field-types/class-field-type-color.php: -------------------------------------------------------------------------------- 1 | name = _x( 'Color (HTML5 field)', 'xprofile field type', 'bp-xprofile-custom-field-types' ); 29 | $this->category = _x( 'Custom Fields', 'xprofile field type category', 'bp-xprofile-custom-field-types' ); 30 | 31 | $this->set_format( '/^.+$/', 'replace' ); 32 | do_action( 'bp_xprofile_field_type_color', $this ); 33 | } 34 | 35 | /** 36 | * Edit profile field/register page. 37 | * 38 | * @param array $raw_properties props. 39 | */ 40 | public function edit_field_html( array $raw_properties = array() ) { 41 | 42 | // reset user_id. 43 | if ( isset( $raw_properties['user_id'] ) ) { 44 | unset( $raw_properties['user_id'] ); 45 | } 46 | 47 | $html = $this->get_edit_field_html_elements( 48 | array_merge( 49 | array( 50 | 'type' => 'color', 51 | 'value' => bp_get_the_profile_field_edit_value(), 52 | 'class' => 'bpxcftr-color', 53 | ), 54 | $raw_properties 55 | ) 56 | ); 57 | ?> 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | > 67 | 68 | 69 |

70 | 71 | 72 | get_edit_field_html_elements( 83 | array_merge( 84 | array( 'type' => 'color' ), 85 | $raw_properties 86 | ) 87 | ); 88 | ?> 89 | 90 | > 91 | Users->Profile Fields->New|Edit entry. 96 | * 97 | * @param \BP_XProfile_Field $current_field object. 98 | * @param string $control_type type. 99 | */ 100 | public function admin_new_field_html( \BP_XProfile_Field $current_field, $control_type = '' ) { 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/handlers/class-from-to-helper.php: -------------------------------------------------------------------------------- 1 | setup(); 36 | } 37 | 38 | /** 39 | * Binds hooks 40 | */ 41 | private function setup() { 42 | add_filter( 'bp_xprofile_set_field_data_pre_validate', array( $this, 'pre_save_validate' ), 10, 3 ); 43 | add_filter( 'xprofile_data_field_id_before_save', array( $this, 'detach' ), 1, 2 ); 44 | add_filter( 'xprofile_data_after_save', array( $this, 'attach' ) ); 45 | } 46 | 47 | /** 48 | * Updates Value on pre-validate to enforce deletion. 49 | * 50 | * @param mixed $value value. 51 | * @param \BP_XProfile_Field $field field object. 52 | * @param \BP_XProfile_Field_Type $field_type_obj field type object. 53 | * 54 | * @return array|string 55 | */ 56 | public function pre_save_validate( $value, $field, $field_type_obj ) { 57 | 58 | if ( 'fromto' !== $field->type ) { 59 | return $value; 60 | } 61 | 62 | if ( ! is_array( $value ) ) { 63 | return $value; 64 | } 65 | 66 | if ( isset( $value['from'] ) && isset( $value['to'] ) && '' === $value['from'] && '' === $value['to'] ) { 67 | return null; 68 | } 69 | 70 | return $value; 71 | } 72 | 73 | /** 74 | * Detaches the validation filter as it will remove our array keys. 75 | * 76 | * @param int $field_id field id. 77 | * @param int $data_field_id data field id. 78 | * 79 | * @return mixed 80 | */ 81 | public function detach( $field_id, $data_field_id ) { 82 | 83 | if ( empty( $field_id ) ) { 84 | return $field_id; 85 | } 86 | 87 | $field = new \BP_XProfile_Field( $field_id ); 88 | 89 | if ( 'fromto' !== $field->type ) { 90 | return $field_id; 91 | } 92 | 93 | if ( has_filter( 'xprofile_data_value_before_save', 'xprofile_sanitize_data_value_before_save' ) ) { 94 | $this->removed = true; 95 | remove_filter( 'xprofile_data_value_before_save', 'xprofile_sanitize_data_value_before_save', 1 ); 96 | } 97 | 98 | return $field_id; 99 | } 100 | 101 | /** 102 | * Re attaches the filter. 103 | */ 104 | public function attach() { 105 | if ( $this->removed ) { 106 | add_filter( 'xprofile_data_value_before_save', 'xprofile_sanitize_data_value_before_save', 1, 4 ); 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /src/field-types/class-field-type-web.php: -------------------------------------------------------------------------------- 1 | name = _x( 'Website (HTML5 field)', 'xprofile field type', 'bp-xprofile-custom-field-types' ); 27 | $this->category = _x( 'Custom Fields', 'xprofile field type category', 'bp-xprofile-custom-field-types' ); 28 | } 29 | 30 | /** 31 | * This method usually outputs HTML for this field type's children options 32 | * on the wp-admin Profile Fields "Add Field" and "Edit Field" screens, but 33 | * for this field type, we don't want it, so it's stubbed out. 34 | * 35 | * @param BP_XProfile_Field $current_field The current profile field on the add/edit screen. 36 | * @param string $control_type Optional. HTML input type used to render the current 37 | * field's child options. 38 | */ 39 | public function admin_new_field_html( \BP_XProfile_Field $current_field, $control_type = '' ) { 40 | 41 | $type = array_search( get_class( $this ), bp_xprofile_get_field_types() ); 42 | 43 | if ( false === $type ) { 44 | return; 45 | } 46 | 47 | $class = $current_field->type != $type ? 'display: none;' : ''; 48 | 49 | $is_checked = self::get_link_target( $current_field->id ) === '_blank'; 50 | ?> 51 | 52 | 53 |
54 | 55 |

56 |
57 |

58 | 61 | 64 |

65 |
66 |
67 | %2$s', esc_url( $field_value ), esc_html( $link ), $target ); 82 | } 83 | 84 | /** 85 | * Returns the link target 86 | * 87 | * @param int $field_id field id. 88 | * 89 | * @return string 90 | */ 91 | public static function get_link_target( $field_id ) { 92 | 93 | if ( ! $field_id ) { 94 | return ''; 95 | } 96 | 97 | return bp_xprofile_get_meta( $field_id, 'field', 'link_target', true ); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/field-types/class-field-type-email.php: -------------------------------------------------------------------------------- 1 | name = _x( 'Email (HTML5 field)', 'xprofile field type', 'bp-xprofile-custom-field-types' ); 30 | $this->category = _x( 'Custom Fields', 'xprofile field type category', 'bp-xprofile-custom-field-types' ); 31 | 32 | do_action( 'bp_xprofile_field_type_email', $this ); 33 | } 34 | 35 | /** 36 | * Edit field html. 37 | * 38 | * @param array $raw_properties properties. 39 | */ 40 | public function edit_field_html( array $raw_properties = array() ) { 41 | 42 | if ( isset( $raw_properties['user_id'] ) ) { 43 | unset( $raw_properties['user_id'] ); 44 | } 45 | 46 | $html = $this->get_edit_field_html_elements( 47 | array_merge( 48 | array( 49 | 'type' => 'email', 50 | 'value' => bp_get_the_profile_field_edit_value(), 51 | ), 52 | $raw_properties 53 | ) 54 | ); 55 | ?> 56 | 57 | 58 | 59 | 60 | 61 | 62 | 67 | 68 | /> 69 | 70 | 71 |

72 | 73 | 74 | get_edit_field_html_elements( 85 | array_merge( 86 | array( 'type' => 'email' ), 87 | $raw_properties 88 | ) 89 | ); 90 | ?> 91 | 92 | /> 93 | 94 | Users->Profile Fields->New|Edit entry. 99 | * 100 | * @param \BP_XProfile_Field $current_field object. 101 | * @param string $control_type type. 102 | */ 103 | public function admin_new_field_html( \BP_XProfile_Field $current_field, $control_type = '' ) { 104 | } 105 | 106 | /** 107 | * Checks if it is a valid email. 108 | * 109 | * @param string $values value. 110 | * 111 | * @return bool 112 | */ 113 | public function is_valid( $values ) { 114 | return empty( $values ) || is_email( $values ); 115 | } 116 | 117 | /** 118 | * Formats value for display. 119 | * 120 | * @param string $field_value Original value of field. 121 | * @param int $field_id Id of field. 122 | * 123 | * @return string Value formatted 124 | */ 125 | public static function display_filter( $field_value, $field_id = 0 ) { 126 | return empty( $field_value ) ? '' : sprintf( '%1$s', $field_value ); 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /src/bootstrap/class-bootstrapper.php: -------------------------------------------------------------------------------- 1 | setup(); 42 | } 43 | 44 | /** 45 | * Binds hooks 46 | */ 47 | private function setup() { 48 | 49 | add_action( 'bp_loaded', array( $this, 'load' ) ); 50 | add_action( 'bp_init', array( $this, 'load_translations' ) ); 51 | 52 | // register. 53 | add_filter( 'bp_xprofile_get_field_types', array( $this, 'register_field_types' ), 10, 1 ); 54 | } 55 | 56 | /** 57 | * Loads core functions/template tags. 58 | * These are non auto loadable constructs. 59 | */ 60 | public function load() { 61 | $this->load_common(); 62 | $this->load_admin(); 63 | } 64 | 65 | /** 66 | * Loads translations. 67 | */ 68 | public function load_translations() { 69 | load_plugin_textdomain( 'bp-xprofile-custom-field-types', false, basename( dirname( bp_xprofile_cftr()->path ) ) . '/languages' ); 70 | } 71 | 72 | /** 73 | * Registers the field types. 74 | * 75 | * @param array $fields field types. 76 | * 77 | * @return array 78 | */ 79 | public function register_field_types( $fields ) { 80 | $fields = array_merge( $fields, bpxcftr_get_field_types() ); 81 | return $fields; 82 | } 83 | 84 | /** 85 | * Loads files common to each request type. 86 | */ 87 | private function load_common() { 88 | $path = bp_xprofile_cftr()->path; 89 | 90 | $files = array( 91 | 'src/core/bp-xprofile-custom-field-types-functions.php', 92 | ); 93 | 94 | if ( is_admin() ) { 95 | } 96 | 97 | foreach ( $files as $file ) { 98 | require_once $path . $file; 99 | } 100 | 101 | // Boot the app. 102 | Assets_Loader::boot(); 103 | Field_Upload_Helper::boot(); 104 | Taxonomy_Terms_Creator::boot(); 105 | Birthdate_Field_Validator::boot(); 106 | Field_Settings_Handler::boot(); 107 | Signup_Validator::boot(); 108 | From_To_Helper::boot(); 109 | Xprofile_Kses_Filter::boot(); 110 | // BP profile Search. 111 | BP_Profile_Search_Helper::boot(); 112 | Label_Filter::boot(); 113 | Tags_Creator::boot(); 114 | } 115 | 116 | /** 117 | * Loads admin. 118 | */ 119 | private function load_admin() { 120 | 121 | if ( ! is_admin() ) { 122 | return; 123 | } 124 | 125 | if ( ! defined( 'DOING_AJAX' ) ) { 126 | Admin::boot(); 127 | } 128 | 129 | Admin_Field_Settings_Helper::boot(); 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /src/field-types/class-field-type-datepicker.php: -------------------------------------------------------------------------------- 1 | name = _x( 'Datepicker (HTML5 field)', 'xprofile field type', 'bp-xprofile-custom-field-types' ); 29 | $this->category = _x( 'Custom Fields', 'xprofile field type category', 'bp-xprofile-custom-field-types' ); 30 | 31 | $this->set_format( '/^\d{4}-\d{1,2}-\d{1,2}$/', 'replace' ); // "Y-m-d 00:00:00" 32 | do_action( 'bp_xprofile_field_type_datepicker', $this ); 33 | } 34 | 35 | /** 36 | * Outputs html for the Profile->Edit and Register screen. 37 | * 38 | * @param array $raw_properties array of attributes. 39 | */ 40 | public function edit_field_html( array $raw_properties = array() ) { 41 | 42 | if ( isset( $raw_properties['user_id'] ) ) { 43 | unset( $raw_properties['user_id'] ); 44 | } 45 | 46 | $html = $this->get_edit_field_html_elements( 47 | array_merge( 48 | array( 49 | 'type' => 'date', 50 | 'value' => bp_get_the_profile_field_edit_value(), 51 | ), 52 | $raw_properties 53 | ) 54 | ); 55 | ?> 56 | 57 | 58 | 59 | 60 | 61 | 62 | 66 | 67 | /> 68 | 69 | 70 |

71 | 72 | 73 | get_edit_field_html_elements( 84 | array_merge( 85 | array( 'type' => 'date' ), 86 | $raw_properties 87 | ) 88 | ); 89 | ?> 90 | 91 | /> 92 | name = _x( 'Token', 'xprofile field type', 'bp-xprofile-custom-field-types' ); 31 | $this->category = _x( 'Custom Fields', 'xprofile field type category', 'bp-xprofile-custom-field-types' ); 32 | 33 | $this->supports_multiple_defaults = false; 34 | $this->accepts_null_value = false; 35 | $this->supports_options = false; 36 | 37 | $this->set_format( '/^.+$/', 'replace' ); 38 | do_action( 'bp_xprofile_field_type_token', $this ); 39 | } 40 | 41 | /** 42 | * Admin new field screen. 43 | * 44 | * @param \BP_XProfile_Field $current_field profile field object. 45 | * @param string $control_type type. 46 | */ 47 | public function admin_new_field_html( \BP_XProfile_Field $current_field, $control_type = '' ) { 48 | 49 | $type = array_search( get_class( $this ), bp_xprofile_get_field_types(), false ); 50 | 51 | if ( false === $type ) { 52 | return; 53 | } 54 | 55 | $class = $current_field->type != $type ? 'display: none;' : ''; 56 | $text = join( ',', self::get_tokens( $current_field->id ) ); 57 | 58 | ?> 59 |
61 |

62 |
63 |

64 | 65 |

66 |

67 | id ) );?>> 68 | 69 |

70 |
71 |
72 | id ); 91 | 92 | if ( self::is_case_ignored( $field->id ) ) { 93 | $tokens = array_map( 'strtoupper', $tokens ); 94 | $values = strtoupper( $values ); 95 | } 96 | 97 | if ( empty( $values ) || ! in_array( $values, $tokens ) ) { 98 | return false; 99 | } 100 | 101 | return true; 102 | } 103 | 104 | /** 105 | * Returns the tokens. 106 | * 107 | * @param int $field_id field id. 108 | * 109 | * @return array 110 | */ 111 | private static function get_tokens( $field_id = 0 ) { 112 | 113 | if ( ! $field_id && ! is_null( $field_id ) ) { 114 | $field_id = bp_get_the_profile_field_id(); 115 | } 116 | 117 | if ( ! $field_id ) { 118 | return array(); 119 | } 120 | 121 | return array_map( 'trim', explode( ',', bp_xprofile_get_meta( $field_id, 'field', 'token_tokens', true ) ) ); 122 | } 123 | 124 | /** 125 | * Checks if the case should be ignored. 126 | * 127 | * @param int $field_id field id. 128 | * 129 | * @return bool 130 | */ 131 | private static function is_case_ignored( $field_id = 0 ) { 132 | 133 | if ( ! $field_id && ! is_null( $field_id ) ) { 134 | $field_id = bp_get_the_profile_field_id(); 135 | } 136 | 137 | if ( ! $field_id ) { 138 | return false; 139 | } 140 | 141 | return (bool) bp_xprofile_get_meta( $field_id, 'field', 'token_ignore_case', true ); 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /src/bootstrap/class-autoloader.php: -------------------------------------------------------------------------------- 1 | root_namespace = $root_namespace; 53 | $this->root_path = $root_path; 54 | } 55 | 56 | /** 57 | * Class Loader. 58 | * 59 | * After registering this autoload function with SPL, the following line 60 | * would cause the function to attempt to load the \BPXProfileCFTR\Bar\Baz\Qux class 61 | * from /path/to/project/buddypress-xprofile-custom-fields-types/src/bar/baz/class-qux.php: 62 | * 63 | * new \BPXProfileCFTR\Baz\Qux; 64 | * maps to /path/to/buddypress-xprofile-custom-fields-types/src/baz/class-qux.php 65 | * The path/directory name should be all lowercase and the the class file is named as 'class-$classname.php' 66 | * Since we wills tick to wp standards, we will be using interface-$classname.php for loading iterface(and similar for traits) 67 | * It sacrifices a bit of speed for readability( if we do not prefix with class-, interface-,trait-, it wil be better). 68 | * 69 | * @param string $class The fully-qualified class name. 70 | * 71 | * @return void 72 | */ 73 | public function __invoke( $class ) { 74 | // Project-specific namespace prefix. 75 | $prefix = $this->root_namespace; 76 | 77 | // Base directory for the namespace prefix. 78 | $base_dir = $this->root_path; 79 | 80 | // does the class use the namespace prefix? 81 | $len = strlen( $prefix ); 82 | 83 | if ( strncmp( $prefix, $class, $len ) !== 0 ) { 84 | // no, move to the next registered auto loader. 85 | return; 86 | } 87 | 88 | // get the relative class name. 89 | // also make it lower case as we will use it as file name with wp standards. 90 | $relative_class = strtolower( substr( $class, $len ) ); 91 | 92 | // replace the namespace prefix with the base directory, replace namespace 93 | // separators with directory separators in the relative class name, append 94 | // with .php. Also, replace the underscore(_) with hyphen(-). 95 | $file = $base_dir . str_replace( array( '_', '\\' ), array( '-', '/' ), $relative_class ); 96 | 97 | $file = explode( '/', $file ); 98 | $file_name = array_pop( $file ); 99 | $base_dir = join( '/', $file ); 100 | 101 | // Since we have a naming convention for file like 'class-', 'interface-', 'trait-', 102 | // we need to test for each of them. 103 | $class_file = $base_dir . "/class-{$file_name}.php"; 104 | $interface_file = $base_dir . "/interface-{$file_name}.php"; 105 | $trait_file = $base_dir . "/trait-{$file_name}.php"; 106 | 107 | // Replace the last component 108 | // If the file exists, require it. 109 | if ( file_exists( $class_file ) ) { 110 | require_once $class_file; 111 | } elseif ( file_exists( $interface_file ) ) { 112 | require_once $interface_file; 113 | } elseif ( file_exists( $trait_file ) ) { 114 | require_once $trait_file; 115 | } 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /bp-xprofile-custom-field-types.php: -------------------------------------------------------------------------------- 1 | bootstrap(); 98 | $this->setup(); 99 | } 100 | 101 | /** 102 | * Get class instance 103 | * 104 | * @return static 105 | */ 106 | public static function get_instance() { 107 | 108 | if ( is_null( self::$instance ) ) { 109 | self::$instance = new self(); 110 | } 111 | 112 | return self::$instance; 113 | } 114 | 115 | /** 116 | * Bootstrap the core. 117 | */ 118 | private function bootstrap() { 119 | // Setup general properties. 120 | $this->path = plugin_dir_path( __FILE__ ); 121 | $this->url = plugin_dir_url( __FILE__ ); 122 | $this->basename = plugin_basename( __FILE__ ); 123 | // Load autoloader. 124 | require_once $this->path . 'src/bootstrap/class-autoloader.php'; 125 | 126 | // Register autoloader. 127 | spl_autoload_register( new Autoloader( 'BPXProfileCFTR\\', __DIR__ . '/src/' ) ); 128 | register_activation_hook( __FILE__, array( $this, 'on_activation' ) ); 129 | register_deactivation_hook( __FILE__, array( $this, 'on_deactivation' ) ); 130 | } 131 | 132 | /** 133 | * Load plugin core files and assets. 134 | */ 135 | private function setup() { 136 | $this->data = new Data_Store(); 137 | 138 | Bootstrapper::boot(); 139 | } 140 | 141 | /** 142 | * On activation create table 143 | */ 144 | public function on_activation() { 145 | update_option( 'bpxcftr_notices', array() ); 146 | } 147 | 148 | /** 149 | * On deactivation create table 150 | */ 151 | public function on_deactivation() { 152 | delete_option( 'bpxcftr_notices' ); 153 | } 154 | 155 | /** 156 | * Magic method for accessing property as readonly(It's a lie, references can be updated). 157 | * 158 | * @param string $name property name. 159 | * 160 | * @return mixed|null 161 | */ 162 | public function __get( $name ) { 163 | 164 | if ( ! in_array( $name, self::$protected, true ) && property_exists( $this, $name ) ) { 165 | return $this->{$name}; 166 | } 167 | 168 | return null; 169 | } 170 | } 171 | 172 | /** 173 | * Returns singleton instance of BP_Xprofile_CFTR 174 | * 175 | * @return BP_Xprofile_CFTR 176 | */ 177 | function bp_xprofile_cftr() { 178 | return BP_Xprofile_CFTR::get_instance(); 179 | } 180 | 181 | bp_xprofile_cftr(); 182 | -------------------------------------------------------------------------------- /src/handlers/class-tags-creator.php: -------------------------------------------------------------------------------- 1 | setup(); 31 | } 32 | 33 | /** 34 | * Binds hooks 35 | */ 36 | private function setup() { 37 | // Pre validate tags. 38 | //add_filter( 'bp_xprofile_set_field_data_pre_validate', array( $this, 'sanitize' ), 10, 2 ); 39 | 40 | add_filter( 'bp_get_the_profile_field_value', array( $this, 'filter_value' ), 10, 3 ); 41 | 42 | add_filter( 'bpxcftr_load_front_assets', array( $this, 'should_load_assets' ) ); 43 | 44 | add_action( 'wp_ajax_bpxcftr_remove_user_tag', array( $this, 'remove_user_tag' ) ); 45 | } 46 | 47 | /** 48 | * Sanitizes Value. 49 | * 50 | * @param mixed $value value. 51 | * @param \BP_XProfile_Field $field field object. 52 | * 53 | * @return array|string 54 | */ 55 | public function sanitize( $value, $field ) { 56 | // store Field's reference to allow us fetch it when validating. 57 | bpxcftr_set_current_field( $field ); 58 | 59 | if ( 'tags' !== $field->type || empty( $value ) ) { 60 | return $value; 61 | } 62 | 63 | $allow_new_tags = Field_Type_Tags::allow_new_tags( $field->id ); 64 | 65 | // Add new tags if needed. 66 | $sanitized = array(); 67 | 68 | $user_id = bp_displayed_user_id(); 69 | 70 | $default_tags = Field_Type_Tags::get_default_tags( $field->id ); 71 | $user_tags = xprofile_get_field_data( $field->id, $user_id ); 72 | $user_tags = $user_tags ? $user_tags : array(); 73 | 74 | foreach ( $value as $tag ) { 75 | 76 | if ( in_array( $tag, $default_tags ) ) { 77 | $sanitized[] = $tag; 78 | } elseif ( $allow_new_tags ) { 79 | $field_data = array_merge( $user_tags, array( $tag ) ); 80 | xprofile_set_field_data( $field->id, $user_id, $field_data ); 81 | 82 | $sanitized[] = $tag; 83 | } 84 | } 85 | 86 | return $sanitized; 87 | } 88 | 89 | /** 90 | * Filters profile field value 91 | * 92 | * @param string $value Value for the profile field. 93 | * @param string $field_type Type for the profile field. 94 | * @param int $field_id ID for the profile field. 95 | * 96 | * @return string 97 | */ 98 | public function filter_value( $value, $field_type, $field_id ) { 99 | if ( 'tags' !== $field_type || ! bp_is_my_profile() ) { 100 | return $value; 101 | } 102 | 103 | if ( ! apply_filters( 'bpxcftr_enable_tag_removal_on_view_profile', true ) ) { 104 | return $value; 105 | } 106 | 107 | $tags = array_filter( explode( ',', $value ) ); 108 | $user_id = get_current_user_id(); 109 | 110 | $appended_tags = array_map( 111 | function ( $tag ) use ( $user_id, $field_id ) { 112 | $tag = wp_strip_all_tags( $tag ); 113 | $nonce = wp_create_nonce( 'bpxcftr-remove-user-' . $user_id . '-tag-' . $tag ); 114 | 115 | return '' . $tag . '[x]'; 116 | }, 117 | $tags 118 | ); 119 | 120 | return join( ', ', $appended_tags ); 121 | } 122 | 123 | /** 124 | * Should load assets. 125 | * 126 | * @return bool 127 | */ 128 | public function should_load_assets() { 129 | 130 | if ( ! bp_is_profile_component() ) { 131 | return false; 132 | } 133 | 134 | return is_super_admin() || bp_is_my_profile(); 135 | } 136 | 137 | /** 138 | * Removes user tag 139 | */ 140 | public function remove_user_tag() { 141 | $posted_data = wp_unslash( $_POST ); 142 | 143 | $tag = isset( $posted_data['tag'] ) ? sanitize_text_field( wp_unslash( $posted_data['tag'] ) ) : ''; 144 | $field_id = isset( $posted_data['field_id'] ) ? wp_unslash( $posted_data['field_id'] ) : ''; 145 | $user_id = get_current_user_id(); 146 | 147 | if ( ! $tag || ! $field_id || ! $user_id || ! bp_is_my_profile() ) { 148 | wp_send_json_error( __( 'Invalid Request.', 'bp-xpofile-custom-field-types' ) ); 149 | } 150 | 151 | check_ajax_referer( 'bpxcftr-remove-user-' . $user_id . '-tag-' . $tag, 'nonce' ); 152 | 153 | $field_data = xprofile_get_field_data( $field_id, $user_id ); 154 | 155 | $position = array_search( $tag, $field_data, true ); 156 | 157 | if ( false === $position ) { 158 | wp_send_json_error( __( 'Tag not found.', 'bp-xpofile-custom-field-types' ) ); 159 | } 160 | 161 | unset( $field_data[ $position ] ); 162 | 163 | xprofile_set_field_data( $field_id, $user_id, $field_data ); 164 | 165 | wp_send_json_success( __( 'Tag removed.', 'bp-xpofile-custom-field-types' ) ); 166 | } 167 | } 168 | -------------------------------------------------------------------------------- /src/core/bp-xprofile-custom-field-types-functions.php: -------------------------------------------------------------------------------- 1 | class name). 22 | */ 23 | function bpxcftr_get_field_types() { 24 | $fields = array( 25 | // I haven't changed the field type name to make it drop-in replacement for BuddyPress Xprofile Custom Fields Type plugin. 26 | 'birthdate' => 'BPXProfileCFTR\Field_Types\Field_Type_Birthdate', 27 | 'email' => 'BPXProfileCFTR\Field_Types\Field_Type_Email', 28 | 'web' => 'BPXProfileCFTR\Field_Types\Field_Type_Web', 29 | 'datepicker' => 'BPXProfileCFTR\Field_Types\Field_Type_Datepicker', 30 | 'select_custom_post_type' => 'BPXProfileCFTR\Field_Types\Field_Type_Select_Post_Type', 31 | 'country' => 'BPXProfileCFTR\Field_Types\Field_Type_Country', 32 | 'multiselect_custom_post_type' => 'BPXProfileCFTR\Field_Types\Field_Type_Multi_Select_Post_Type', 33 | 'select_custom_taxonomy' => 'BPXProfileCFTR\Field_Types\Field_Type_Select_Taxonomy', 34 | 'multiselect_custom_taxonomy' => 'BPXProfileCFTR\Field_Types\Field_Type_Multi_Select_Taxonomy', 35 | 'checkbox_acceptance' => 'BPXProfileCFTR\Field_Types\Field_Type_Checkbox_Acceptance', 36 | 'image' => 'BPXProfileCFTR\Field_Types\Field_Type_Image', 37 | 'file' => 'BPXProfileCFTR\Field_Types\Field_Type_File', 38 | 'color' => 'BPXProfileCFTR\Field_Types\Field_Type_Color', 39 | 'decimal_number' => 'BPXProfileCFTR\Field_Types\Field_Type_Decimal_Number', 40 | 'number_minmax' => 'BPXProfileCFTR\Field_Types\Field_Type_Number_Min_Max', 41 | 'slider' => 'BPXProfileCFTR\Field_Types\Field_Type_Slider', 42 | 'fromto' => 'BPXProfileCFTR\Field_Types\Field_Type_From_To', 43 | 'oembed' => 'BPXProfileCFTR\Field_Types\Field_Type_Oembed', 44 | 'token' => 'BPXProfileCFTR\Field_Types\Field_Type_Token', 45 | 'tags' => 'BPXProfileCFTR\Field_Types\Field_Type_Tags', 46 | ); 47 | 48 | return $fields; 49 | } 50 | 51 | /** 52 | * Returns field types which support the select2 js. 53 | * 54 | * @return array 55 | */ 56 | function bpxcftr_get_selectable_field_types() { 57 | $types = array( 58 | 'selectbox', 59 | 'multiselectbox', 60 | 'select_custom_post_type', 61 | 'multiselect_custom_post_type', 62 | 'select_custom_taxonomy', 63 | 'multiselect_custom_taxonomy', 64 | 'tags', 65 | ); 66 | 67 | return apply_filters( 'bpxcftr_selectable_types', $types ); 68 | } 69 | /** 70 | * Returns an array of allowed file extensions. 71 | * 72 | * @param string $type possible values 'image', 'file'. 73 | * 74 | * @return array 75 | */ 76 | function bpxcftr_get_allowed_file_extensions( $type ) { 77 | 78 | $extensions = array( 79 | 'file' => array( 80 | 'doc', 81 | 'docx', 82 | 'pdf', 83 | ), 84 | 'image' => array( 85 | 'jpg', 86 | 'jpeg', 87 | 'gif', 88 | 'png', 89 | ), 90 | ); 91 | 92 | $extensions = apply_filters( 'bpxcftr_allowed_extensions', $extensions ); 93 | 94 | return isset( $extensions[ $type ] ) ? $extensions[ $type ] : array(); 95 | } 96 | 97 | /** 98 | * Returns maximum allowed file size. 99 | * 100 | * @param string $type field type. 101 | * 102 | * @return int|mixed 103 | */ 104 | function bpxcftr_get_allowed_file_size( $type ) { 105 | 106 | $sizes = array( 107 | 'file' => 8, 108 | 'image' => 8, 109 | ); 110 | 111 | $sizes = apply_filters( 'bpxcftr_allowed_sizes', $sizes ); 112 | return isset( $sizes[ $type ] ) ? $sizes[ $type ] : 0; 113 | } 114 | 115 | /** 116 | * Is field type selectable? 117 | * 118 | * Used for deciding when to apply select2 119 | * 120 | * @param BP_XProfile_Field $field field object. 121 | * 122 | * @return bool 123 | */ 124 | function bpxcftr_is_selectable_field( $field ) { 125 | $selectable_types = bpxcftr_get_selectable_field_types(); 126 | return in_array( $field->type, $selectable_types ) || $field->type_obj instanceof Field_Type_Selectable ; 127 | } 128 | 129 | /** 130 | * Is field type multi valued? 131 | * 132 | * Used for deciding when to apply select2 133 | * 134 | * @param BP_XProfile_Field $field field object. 135 | * 136 | * @return bool 137 | */ 138 | function bpxcftr_is_multi_valued_field( $field ) { 139 | $selectable_types = apply_filters( 'bpxcftr_multi_valued_types', array( 'multiselectbox', 'tags' ) ); 140 | 141 | return in_array( $field->type, $selectable_types, true ) || $field->type_obj instanceof Field_Type_Multi_Valued; 142 | } 143 | 144 | /** 145 | * It is a workaround to get the field at the time is_valid() is called on field types. 146 | * BuddyPress does not pass the id at the moment. 147 | * 148 | * @return BP_XProfile_Field|null 149 | */ 150 | function bpxcftr_get_current_field() { 151 | return bp_xprofile_cftr()->data->current_field; 152 | } 153 | 154 | /** 155 | * Saves the current field value. 156 | * 157 | * @param BP_XProfile_Field|null $field field object or null. 158 | */ 159 | function bpxcftr_set_current_field( $field ) { 160 | bp_xprofile_cftr()->data->current_field = $field; 161 | } 162 | -------------------------------------------------------------------------------- /src/field-types/class-field-type-number-min-max.php: -------------------------------------------------------------------------------- 1 | name = __( 'Number within min/max values (HTML5 field)', 'bp-xprofile-custom-field-types' ); 29 | $this->category = _x( 'Custom Fields', 'xprofile field type category', 'bp-xprofile-custom-field-types' ); 30 | 31 | $this->accepts_null_value = true; 32 | $this->supports_options = false; 33 | 34 | do_action( 'bp_xprofile_field_type_number_minmax', $this ); 35 | } 36 | 37 | /** 38 | * Edit field html. 39 | * 40 | * @param array $raw_properties properties. 41 | */ 42 | public function edit_field_html( array $raw_properties = array() ) { 43 | global $field; 44 | 45 | if ( isset( $raw_properties['user_id'] ) ) { 46 | unset( $raw_properties['user_id'] ); 47 | } 48 | 49 | $args = array( 50 | 'type' => 'number', 51 | 'value' => bp_get_the_profile_field_edit_value(), 52 | 'min' => self::get_min_val( $field->id ), 53 | 'max' => self::get_max_val( $field->id ), 54 | ); 55 | 56 | $html = $this->get_edit_field_html_elements( array_merge( $args, $raw_properties ) ); 57 | 58 | ?> 59 | 60 | 61 | 62 | 63 | 64 | 65 | 70 | /> 71 | 72 | 73 |

74 | 75 | 76 | Users->Profile Fields entry. 81 | * 82 | * @param array $raw_properties properties. 83 | */ 84 | public function admin_field_html( array $raw_properties = array() ) { 85 | global $field; 86 | 87 | $args = array( 88 | 'type' => 'number', 89 | 'min' => self::get_min_val( $field->id ), 90 | 'max' => self::get_max_val( $field->id ), 91 | ); 92 | 93 | $html = $this->get_edit_field_html_elements( array_merge( $args, $raw_properties ) ); 94 | ?> 95 | 96 | /> 97 | 98 | Users->Profile Fields->New|Edit entry. 103 | * 104 | * @param \BP_XProfile_Field $current_field object. 105 | * @param string $control_type type. 106 | */ 107 | public function admin_new_field_html( \BP_XProfile_Field $current_field, $control_type = '' ) { 108 | 109 | $type = array_search( get_class( $this ), bp_xprofile_get_field_types() ); 110 | 111 | if ( false === $type ) { 112 | return; 113 | } 114 | 115 | $class = $current_field->type != $type ? 'display: none;' : ''; 116 | 117 | $min = self::get_min_val( $current_field->id ); 118 | $max = self::get_max_val( $current_field->id ); 119 | 120 | ?> 121 |
122 | 123 |

124 |
125 |

126 | 127 | 130 | 131 | 132 | 133 | 136 | 137 |

138 |
139 |
140 | 141 | id ); 164 | $max = self::get_max_val( $field->id ); 165 | 166 | // unset the current field from our saved field id. 167 | bpxcftr_set_current_field( null ); 168 | 169 | return ( $values >= $min ) && ( $values <= $max ); 170 | } 171 | 172 | /** 173 | * Returns the minimum allowed value for the field id. 174 | * 175 | * @param int $field_id field id. 176 | * 177 | * @return float 178 | */ 179 | public static function get_min_val( $field_id ) { 180 | return bp_xprofile_get_meta( $field_id, 'field', 'min_val', true ); 181 | } 182 | 183 | /** 184 | * Returns the max allowed value for the field id. 185 | * 186 | * @param int $field_id field id. 187 | * 188 | * @return float 189 | */ 190 | public static function get_max_val( $field_id ) { 191 | return bp_xprofile_get_meta( $field_id, 'field', 'max_val', true ); 192 | } 193 | } 194 | -------------------------------------------------------------------------------- /src/field-types/class-field-type-slider.php: -------------------------------------------------------------------------------- 1 | name = __( 'Range input (HTML5 field)', 'bp-xprofile-custom-field-types' ); 28 | $this->category = _x( 'Custom Fields', 'xprofile field type category', 'bp-xprofile-custom-field-types' ); 29 | 30 | $this->accepts_null_value = true; 31 | $this->supports_options = false; 32 | 33 | do_action( 'bp_xprofile_field_type_slider', $this ); 34 | } 35 | 36 | /** 37 | * Edit field html. 38 | * 39 | * @param array $raw_properties properties. 40 | */ 41 | public function edit_field_html( array $raw_properties = array() ) { 42 | global $field; 43 | 44 | if ( isset( $raw_properties['user_id'] ) ) { 45 | unset( $raw_properties['user_id'] ); 46 | } 47 | 48 | $args = array( 49 | 'type' => 'range', 50 | 'class' => 'bpxcftr-slider', 51 | 'value' => bp_get_the_profile_field_edit_value(), 52 | 'min' => self::get_min_val( $field->id ), 53 | 'max' => self::get_max_val( $field->id ), 54 | ); 55 | ?> 56 | 57 | 58 | 59 | 60 | 61 | 62 | 67 | get_edit_field_html_elements( array_merge( $args, $raw_properties ) ); ?> /> 68 | 69 | 70 | 71 |

72 | 73 | 74 | User->Profile Fields screen. 79 | * 80 | * @param array $raw_properties properties. 81 | */ 82 | public function admin_field_html( array $raw_properties = array() ) { 83 | global $field; 84 | 85 | $args = array( 86 | 'type' => 'range', 87 | 'class' => 'bpxcftr-slider', 88 | 'min' => self::get_min_val( $field->id ), 89 | 'max' => self::get_max_val( $field->id ), 90 | ); 91 | ?> 92 | 93 | get_edit_field_html_elements( array_merge( $args, $raw_properties ) ); ?> /> 94 | 95 | User->Profile Fields->New|Edit screen. 101 | * 102 | * @param \BP_XProfile_Field $current_field field. 103 | * @param string $control_type type. 104 | */ 105 | public function admin_new_field_html( \BP_XProfile_Field $current_field, $control_type = '' ) { 106 | 107 | $type = array_search( get_class( $this ), bp_xprofile_get_field_types() ); 108 | 109 | if ( false === $type ) { 110 | return; 111 | } 112 | 113 | $class = $current_field->type != $type ? 'display: none;' : ''; 114 | 115 | $min = self::get_min_val( $current_field->id ); 116 | $max = self::get_max_val( $current_field->id ); 117 | 118 | ?> 119 |
120 | 121 |

122 |
123 |

124 | 127 | 128 | 131 | 132 |

133 |
134 |
135 | 136 | id ); 159 | $max = self::get_max_val( $field->id ); 160 | 161 | // unset the current field from our saved field id. 162 | bpxcftr_set_current_field( null ); 163 | 164 | return ( $values >= $min ) && ( $values <= $max ); 165 | } 166 | 167 | 168 | /** 169 | * Formats value for display. 170 | * 171 | * @param string $field_value Original value of the field. 172 | * @param int $field_id Id of the field. 173 | * 174 | * @return string Value formatted 175 | */ 176 | public static function display_filter( $field_value, $field_id = 0 ) { 177 | return $field_value; 178 | } 179 | 180 | /** 181 | * Returns the minimum allowed value for the field id. 182 | * 183 | * @param int $field_id field id. 184 | * 185 | * @return float 186 | */ 187 | public static function get_min_val( $field_id ) { 188 | return bp_xprofile_get_meta( $field_id, 'field', 'min_val', true ); 189 | } 190 | 191 | /** 192 | * Returns the max allowed value for the field id. 193 | * 194 | * @param int $field_id field id. 195 | * 196 | * @return float 197 | */ 198 | public static function get_max_val( $field_id ) { 199 | return bp_xprofile_get_meta( $field_id, 'field', 'max_val', true ); 200 | } 201 | } 202 | -------------------------------------------------------------------------------- /src/field-types/class-field-type-decimal-number.php: -------------------------------------------------------------------------------- 1 | name = __( 'Decimal number (HTML5 field)', 'bp-xprofile-custom-field-types' ); 30 | $this->category = _x( 'Custom Fields', 'xprofile field type category', 'bp-xprofile-custom-field-types' ); 31 | 32 | $this->accepts_null_value = true; 33 | $this->supports_options = false; 34 | 35 | $this->set_format( '/^\d+\.?\d*$/', 'replace' ); 36 | 37 | do_action( 'bp_xprofile_field_type_decimal_number', $this ); 38 | } 39 | 40 | /** 41 | * Edit field html. 42 | * 43 | * @param array $raw_properties properties. 44 | */ 45 | public function edit_field_html( array $raw_properties = array() ) { 46 | global $field; 47 | 48 | if ( isset( $raw_properties['user_id'] ) ) { 49 | unset( $raw_properties['user_id'] ); 50 | } 51 | 52 | $html = $this->get_edit_field_html_elements( 53 | array_merge( 54 | array( 55 | 'type' => 'number', 56 | 'step' => floatval( self::get_step( $field->id ) ), 57 | 'value' => bp_get_the_profile_field_edit_value(), 58 | ), 59 | $raw_properties 60 | ) 61 | ); 62 | ?> 63 | 64 | 65 | 66 | 67 | 68 | 69 | 75 | /> 76 | 77 | 78 |

79 | 80 | 81 | get_edit_field_html_elements( 93 | array_merge( 94 | array( 95 | 'type' => 'number', 96 | 'step' => self::get_step( $field->id ), 97 | ), 98 | $raw_properties 99 | ) 100 | ); 101 | ?> 102 | /> 103 | Users->Profile Fields->New|Edit entry. 108 | * 109 | * @param \BP_XProfile_Field $current_field object. 110 | * @param string $control_type type. 111 | */ 112 | public function admin_new_field_html( \BP_XProfile_Field $current_field, $control_type = '' ) { 113 | 114 | $type = array_search( get_class( $this ), bp_xprofile_get_field_types() ); 115 | 116 | if ( false === $type ) { 117 | return; 118 | } 119 | 120 | $class = $current_field->type != $type ? 'display: none;' : ''; 121 | $current_precision = self::get_precision( $current_field->id ); 122 | $current_step = self::get_step( $current_field->id ); 123 | if ( ! $current_step ) { 124 | $current_step = 1; 125 | } 126 | ?> 127 |
128 |

129 |
130 |

131 | 132 | 137 |

138 | 139 |

140 | 141 | 142 |

143 |

144 |
145 |
146 | id ); 170 | bpxcftr_set_current_field( null ); 171 | $pos = strpos( $values, '.' ); 172 | 173 | if ( false === $pos ) { 174 | return is_numeric( $values ); 175 | } 176 | 177 | $decimal = substr( $values, $pos + 1 ); 178 | 179 | return is_numeric( $values ) && ( $precision >= strlen( $decimal ) ); 180 | } 181 | 182 | /** 183 | * Returns the step size. 184 | * 185 | * @param int $field_id field id. 186 | * 187 | * @return float|int 188 | */ 189 | private static function get_step( $field_id ) { 190 | return bp_xprofile_get_meta( $field_id, 'field', 'step_size', true ); 191 | } 192 | 193 | /** 194 | * Returns the step size. 195 | * 196 | * @param int $field_id field id. 197 | * 198 | * @return int 199 | */ 200 | private static function get_precision( $field_id ) { 201 | return bp_xprofile_get_meta( $field_id, 'field', 'precision', true ); 202 | } 203 | } 204 | -------------------------------------------------------------------------------- /src/field-types/class-field-type-image.php: -------------------------------------------------------------------------------- 1 | name = _x( 'Image', 'xprofile field type', 'bp-xprofile-custom-field-types' ); 30 | $this->category = _x( 'Custom Fields', 'xprofile field type category', 'bp-xprofile-custom-field-types' ); 31 | 32 | $this->set_format( '/^.+$/', 'replace' ); 33 | do_action( 'bp_xprofile_field_type_image', $this ); 34 | } 35 | 36 | /** 37 | * Edit field html. 38 | * 39 | * @param array $raw_properties properties. 40 | */ 41 | public function edit_field_html( array $raw_properties = array() ) { 42 | global $field; 43 | 44 | if ( isset( $raw_properties['user_id'] ) ) { 45 | unset( $raw_properties['user_id'] ); 46 | } 47 | 48 | $name = bp_get_the_profile_field_input_name(); 49 | 50 | $value = is_user_logged_in() ? bp_get_the_profile_field_value() : ''; 51 | // we user '-' to trigger the save action. 52 | $edit_value = isset( $field->data ) && ! empty( $field->data->value ) ? $field->data->value : '-'; 53 | 54 | $has_file = false; 55 | 56 | // for backward compatibility, check against '-'. 57 | if ( $value && '-' !== $value ) { 58 | $has_file = true; 59 | } 60 | 61 | if ( ( empty( $value ) || '-' === $value ) && xprofile_check_is_required_field( $field->id ) ) { 62 | $raw_properties['required'] = true; 63 | } 64 | 65 | $html = $this->get_edit_field_html_elements( 66 | array_merge( 67 | array( 'type' => 'file' ), 68 | $raw_properties 69 | ) 70 | ); 71 | ?> 72 | 73 | 74 | 75 | 76 | 77 | 78 | /> 79 | 80 | 81 |

82 | 83 |

84 | 85 | 88 | 89 | 90 | 91 | 92 | 93 | 94 |

95 | 96 | Users->Profile Fields 101 | * 102 | * @param array $raw_properties atts. 103 | */ 104 | public function admin_field_html( array $raw_properties = array() ) { 105 | 106 | $html = $this->get_edit_field_html_elements( 107 | array_merge( 108 | array( 'type' => 'file' ), 109 | $raw_properties 110 | ) 111 | ); 112 | ?> 113 | /> 114 | Users->Profile Fields->New|Edit entry. 119 | * 120 | * @param \BP_XProfile_Field $current_field object. 121 | * @param string $control_type type. 122 | */ 123 | public function admin_new_field_html( \BP_XProfile_Field $current_field, $control_type = '' ) { 124 | } 125 | 126 | /** 127 | * Formats value for display. 128 | * 129 | * @param string $field_value Original value of field. 130 | * @param int $field_id Id of field. 131 | * 132 | * @return string Value formatted 133 | */ 134 | public static function display_filter( $field_value, $field_id = 0 ) { 135 | 136 | if ( empty( $field_value ) ) { 137 | return ''; 138 | } 139 | 140 | $field_value = trim( $field_value, '/\\' );// no absolute path or dir please. 141 | // the BP Xprofile Custom Fields type stored /path which was a bad decision 142 | // we are using the above line for back compatibility with them. 143 | $uploads = wp_upload_dir(); 144 | 145 | $new_field_value = trailingslashit( $uploads['baseurl'] ) . $field_value; 146 | 147 | $new_field_value = sprintf( '', esc_url( $new_field_value ) ); 148 | 149 | return apply_filters( 'bpxcftr_image_display_data', $new_field_value, $field_id ); 150 | } 151 | 152 | /** 153 | * Overrides parent's implementation to avoid required attribute on input elements. 154 | * 155 | * @see \BP_XProfile_Field_Type::get_edit_field_html_elements() 156 | * 157 | * Get a sanitised and escaped string of the edit field's HTML elements and attributes. 158 | * 159 | * Must be used inside the {@link bp_profile_fields()} template loop. 160 | * This method was intended to be static but couldn't be because php.net/lsb/ requires PHP >= 5.3. 161 | * 162 | * @param array $properties Optional key/value array of attributes for this edit field. 163 | * @return string 164 | */ 165 | protected function get_edit_field_html_elements( array $properties = array() ) { 166 | 167 | $required = isset( $properties['required'] ) ? true : false; 168 | unset( $properties['required'] ); 169 | $r = bp_parse_args( 170 | $properties, 171 | array( 172 | 'id' => bp_get_the_profile_field_input_name(), 173 | 'name' => bp_get_the_profile_field_input_name(), 174 | ) 175 | ); 176 | 177 | if ( $required ) { 178 | $r['aria-required'] = 'true'; 179 | 180 | // Moderators can bypass field requirements. 181 | if ( ! bp_current_user_can( 'bp_moderate' ) ) { 182 | $r[] = 'required'; 183 | } 184 | } 185 | 186 | /** 187 | * Filters the edit html elements and attributes. 188 | * 189 | * @param array $r Array of parsed arguments. 190 | * @param string $value Class name for the current class instance. 191 | */ 192 | $r = (array) apply_filters( 'bp_xprofile_field_edit_html_elements', $r, get_class( $this ) ); 193 | 194 | return bp_get_form_field_attributes( sanitize_key( bp_get_the_profile_field_name() ), $r ); 195 | } 196 | } 197 | -------------------------------------------------------------------------------- /src/handlers/class-signup-validator.php: -------------------------------------------------------------------------------- 1 | setup(); 31 | } 32 | 33 | /** 34 | * Sets up validation. 35 | */ 36 | public function setup() { 37 | add_action( 'bp_signup_validate', array( $this, 'validate' ) ); 38 | } 39 | 40 | /** 41 | * Validates fields. 42 | */ 43 | public function validate() { 44 | if ( ! bp_is_active( 'xprofile' ) ) { 45 | return; 46 | } 47 | 48 | $profile_field_ids = isset( $_POST['signup_profile_field_ids'] ) ? explode( ',', wp_unslash( $_POST['signup_profile_field_ids'] ) ) : array(); 49 | 50 | foreach ( $profile_field_ids as $field_id ) { 51 | $this->validate_field( $field_id ); 52 | } 53 | } 54 | 55 | /** 56 | * Validates a field. 57 | * 58 | * @param int $field_id field id. 59 | */ 60 | private function validate_field( $field_id ) { 61 | $bp = buddypress(); 62 | $field = new \BP_XProfile_Field( $field_id ); 63 | 64 | switch ( $field->type ) { 65 | case 'image': 66 | case 'file': 67 | if ( empty( $_FILES[ 'field_' . $field_id ] ) || empty( $_FILES[ 'field_' . $field_id ]['name'] ) ) { 68 | if ( $field->is_required ) { 69 | $bp->signup->errors[ 'field_' . $field_id ] = __( 'This is a required field.', 'bp-xprofile-custom-field-types' ); 70 | } 71 | break; 72 | } 73 | // remove error? 74 | unset( $bp->signup->errors[ 'field_' . $field_id ] ); 75 | $this->validate_file( $field ); 76 | 77 | break; 78 | 79 | case 'checkbox_acceptance': 80 | if ( $field->is_required && ( empty( $_POST[ 'field_' . $field_id ] ) || 1 != $_POST[ 'field_' . $field_id ] ) ) { 81 | $bp->signup->errors[ 'field_' . $field_id ] = __( 'This is a required field', 'bp-xprofile-custom-field-types' ); 82 | } 83 | 84 | break; 85 | 86 | case 'fromto': 87 | if ( $field->is_required && ( empty( $_POST[ 'field_' . $field_id ]['from'] ) || empty( $_POST[ 'field_' . $field_id ]['to'] ) ) ) { 88 | $bp->signup->errors[ 'field_' . $field_id ] = __( 'This is a required field', 'bp-xprofile-custom-field-types' ); 89 | } 90 | 91 | break; 92 | 93 | case 'birthdate': 94 | $this->validate_birthdate( $field ); 95 | break; 96 | 97 | case 'token': 98 | $this->validate_token( $field, isset( $_POST[ 'field_' . $field_id ] ) ? trim( $_POST[ 'field_' . $field_id ] ) : '' ); 99 | break; 100 | } 101 | } 102 | 103 | /** 104 | * Validates the file type fields. 105 | * 106 | * @param \BP_XProfile_Field $field field object. 107 | */ 108 | private function validate_file( $field ) { 109 | $bp = buddypress(); 110 | $field_id = $field->id; 111 | 112 | $filesize = round( $_FILES[ 'field_' . $field_id ]['size'] / ( 1024 * 1024 ), 2 ); 113 | 114 | if ( $field->is_required && $filesize <= 0 ) { 115 | $bp->signup->errors[ 'field_' . $field_id ] = __( 'This is a required field.', 'bp-xprofile-custom-field-types' ); 116 | 117 | return; 118 | } 119 | 120 | // Check extensions. 121 | $ext = strtolower( substr( $_FILES[ 'field_' . $field_id ]['name'], strrpos( $_FILES[ 'field_' . $field_id ]['name'], '.' ) + 1 ) ); 122 | 123 | $allowed_extension = bpxcftr_get_allowed_file_extensions( $field->type ); 124 | $allowed_size = bpxcftr_get_allowed_file_size( $field->type ); 125 | 126 | if ( $allowed_size < $filesize ) { 127 | $bp->signup->errors[ 'field_' . $field_id ] = sprintf( __( 'File exceed the upload limit. Max upload size %d.', 'bp-xprofile-custom-field-types' ), $allowed_size ); 128 | } 129 | 130 | if ( ! in_array( $ext, $allowed_extension ) ) { 131 | $bp->signup->errors[ 'field_' . $field_id ] = sprintf( __( 'File type not allowed: (%s).', 'bp-xprofile-custom-field-types' ), implode( ',', $allowed_extension ) ); 132 | } 133 | } 134 | 135 | 136 | /** 137 | * Validates the Birthdate. 138 | * 139 | * @param \BP_XProfile_Field $field field object. 140 | */ 141 | private function validate_birthdate( $field ) { 142 | $bp = buddypress(); 143 | $field_id = $field->id; 144 | $min_age = Field_Type_Birthdate::get_min_age( $field_id ); 145 | 146 | if ( $min_age <= 0 ) { 147 | return; 148 | } 149 | 150 | if ( empty( $_POST[ 'field_' . $field_id ] ) ) { 151 | $bp->signup->errors[ 'field_' . $field_id ] = sprintf( __( 'You have to be at least %s years old.', 'bp-xprofile-custom-field-types' ), $min_age ); 152 | 153 | return; 154 | } 155 | 156 | $year = wp_unslash( $_POST[ 'field_' . $field_id . '_year' ] ); 157 | $month = wp_unslash( $_POST[ 'field_' . $field_id . '_month' ] ); 158 | $day = wp_unslash( $_POST[ 'field_' . $field_id . '_day' ] ); 159 | 160 | if ( ! is_numeric( $year ) || empty( $month ) || ! is_numeric( $day ) ) { 161 | $bp->signup->errors[ 'field_' . $field_id ] = sprintf( __( 'Invalid date.', 'bp-xprofile-custom-field-types' ) ); 162 | return; 163 | } 164 | 165 | // Check birthdate. 166 | $now = new \DateTime(); 167 | $birthdate = new \DateTime( sprintf( '%s-%s-%s', str_pad( $day, 2, '0', STR_PAD_LEFT ), $month, $year ) ); 168 | $age = $now->diff( $birthdate ); 169 | 170 | if ( $age->y < $min_age ) { 171 | $bp->signup->errors[ 'field_' . $field_id ] = sprintf( __( 'You have to be at least %s years old.', 'bp-xprofile-custom-field-types' ), $min_age ); 172 | } 173 | } 174 | 175 | /** 176 | * Validates signup token. 177 | * 178 | * @param \BP_XProfile_Field_Type $field filed type token. 179 | * @param string $token token to validate. 180 | */ 181 | private function validate_token( $field, $token ) { 182 | 183 | if ( ! $field->is_required && empty( $token ) ) { 184 | return; 185 | } 186 | 187 | $field_type_obj = bp_xprofile_create_field_type( 'token' ); 188 | bpxcftr_set_current_field( $field ); 189 | if ( ! $field_type_obj->is_valid( $token ) ) { 190 | buddypress()->signup->errors[ 'field_' . $field->id ] = __( 'Please provide a valid token.', 'bp-xprofile-custom-field-types' ); 191 | } 192 | } 193 | } 194 | -------------------------------------------------------------------------------- /src/field-types/class-field-type-file.php: -------------------------------------------------------------------------------- 1 | name = _x( 'File', 'xprofile field type', 'bp-xprofile-custom-field-types' ); 30 | $this->category = _x( 'Custom Fields', 'xprofile field type category', 'bp-xprofile-custom-field-types' ); 31 | 32 | $this->set_format( '/^.+$/', 'replace' ); 33 | do_action( 'bp_xprofile_field_type_file', $this ); 34 | } 35 | 36 | /** 37 | * Edit field html. 38 | * 39 | * @param array $raw_properties properties. 40 | */ 41 | public function edit_field_html( array $raw_properties = array() ) { 42 | global $field; 43 | 44 | if ( isset( $raw_properties['user_id'] ) ) { 45 | unset( $raw_properties['user_id'] ); 46 | } 47 | 48 | $value = is_user_logged_in() ? bp_get_the_profile_field_value() : ''; 49 | $name = bp_get_the_profile_field_input_name(); 50 | 51 | $has_file = false; 52 | // for backward compatibility, check against '-'. 53 | if ( $value && '-' !== $value ) { 54 | $has_file = true; 55 | } 56 | 57 | $edit_value = isset( $field->data ) && ! empty( $field->data->value ) ? $field->data->value : '-'; 58 | 59 | if ( ( empty( $value ) || '-' === $value ) && xprofile_check_is_required_field( $field->id ) ) { 60 | $raw_properties['required'] = true; 61 | } 62 | 63 | $html = $this->get_edit_field_html_elements( 64 | array_merge( 65 | array( 'type' => 'file' ), 66 | $raw_properties 67 | ) 68 | ); 69 | ?> 70 | 71 | 72 | 73 | 74 | 75 | 76 | 79 | 80 | /> 81 | 82 | 83 |

84 | 85 |

86 | 87 | 90 | 91 | 92 | 93 | 94 | 95 |

96 | 97 | 98 | get_edit_field_html_elements( 109 | array_merge( 110 | array( 'type' => 'file' ), 111 | $raw_properties 112 | ) 113 | ); 114 | ?> 115 | 116 | /> 117 | 118 | Users->Profile Fields->New|Edit entry. 123 | * 124 | * @param \BP_XProfile_Field $current_field object. 125 | * @param string $control_type type. 126 | */ 127 | public function admin_new_field_html( \BP_XProfile_Field $current_field, $control_type = '' ) { 128 | } 129 | 130 | /** 131 | * Formats value for display. 132 | * 133 | * @param string $field_value Original value of field. 134 | * @param int $field_id field id. 135 | * 136 | * @return string Value formatted 137 | */ 138 | public static function display_filter( $field_value, $field_id = 0 ) { 139 | 140 | if ( empty( $field_value ) ) { 141 | return ''; 142 | } 143 | 144 | $field_value = trim( $field_value, '/\\' );// no absolute path or dir please. 145 | // the BP Xprofile Custom Fields type stored '/path' which was a bad decision 146 | // we are using the above line for back compatibility with them. 147 | $uploads = wp_upload_dir(); 148 | 149 | $new_field_value = trailingslashit( $uploads['baseurl'] ) . $field_value; 150 | $new_field_value = apply_filters( 'bpxcftr_file_type_field_data', $new_field_value, $field_id ); 151 | 152 | $new_field_value = sprintf( '%s', esc_url( $new_field_value ), __( 'Download file', 'bp-xprofile-custom-field-types' ) ); 153 | 154 | return apply_filters( 'bpxcftr_file_display_data', $new_field_value, $field_id ); 155 | } 156 | 157 | /** 158 | * Overrides parent's implementation to avoid required attribute on input elements. 159 | * 160 | * @see \BP_XProfile_Field_Type::get_edit_field_html_elements() 161 | * 162 | * Get a sanitised and escaped string of the edit field's HTML elements and attributes. 163 | * 164 | * Must be used inside the {@link bp_profile_fields()} template loop. 165 | * This method was intended to be static but couldn't be because php.net/lsb/ requires PHP >= 5.3. 166 | * 167 | * @param array $properties Optional key/value array of attributes for this edit field. 168 | * @return string 169 | */ 170 | protected function get_edit_field_html_elements( array $properties = array() ) { 171 | 172 | $required = isset( $properties['required'] ) ? true : false; 173 | unset( $properties['required'] ); 174 | $r = bp_parse_args( 175 | $properties, 176 | array( 177 | 'id' => bp_get_the_profile_field_input_name(), 178 | 'name' => bp_get_the_profile_field_input_name(), 179 | ) 180 | ); 181 | 182 | if ( $required ) { 183 | $r['aria-required'] = 'true'; 184 | 185 | // Moderators can bypass field requirements. 186 | if ( ! bp_current_user_can( 'bp_moderate' ) ) { 187 | $r[] = 'required'; 188 | } 189 | } 190 | 191 | /** 192 | * Filters the edit html elements and attributes. 193 | * 194 | * @param array $r Array of parsed arguments. 195 | * @param string $value Class name for the current class instance. 196 | */ 197 | $r = (array) apply_filters( 'bp_xprofile_field_edit_html_elements', $r, get_class( $this ) ); 198 | 199 | return bp_get_form_field_attributes( sanitize_key( bp_get_the_profile_field_name() ), $r ); 200 | } 201 | } 202 | -------------------------------------------------------------------------------- /src/bootstrap/class-assets-loader.php: -------------------------------------------------------------------------------- 1 | setup(); 36 | } 37 | 38 | /** 39 | * Sets up 40 | */ 41 | public function setup() { 42 | add_action( 'bp_enqueue_scripts', array( $this, 'register_front_assets' ) ); 43 | add_action( 'bp_admin_enqueue_scripts', array( $this, 'register_admin_assets' ) ); 44 | 45 | add_action( 'bp_enqueue_scripts', array( $this, 'load_assets' ) ); 46 | add_action( 'bp_admin_enqueue_scripts', array( $this, 'load_admin_assets' ) ); 47 | add_action( 'bp_admin_enqueue_scripts', array( $this, 'load_user_admin_assets' ) ); 48 | } 49 | 50 | /** 51 | * Registers front assets. 52 | */ 53 | public function register_front_assets() { 54 | 55 | if ( ! $this->should_load_front_assets() ) { 56 | return; 57 | } 58 | 59 | $this->register(); 60 | } 61 | 62 | /** 63 | * Loads plugin assets 64 | */ 65 | public function load_assets() { 66 | // css should always be loaded. 67 | wp_enqueue_style( 'bp-xprofile-custom-field-types' ); 68 | 69 | if ( ! $this->should_load_front_assets() ) { 70 | return; 71 | } 72 | $this->enqueue_vendors(); 73 | $this->enqueue_front(); 74 | } 75 | 76 | /** 77 | * Registers admin assets. 78 | */ 79 | public function register_admin_assets() { 80 | 81 | if ( ! $this->should_load_admin_assets() ) { 82 | return; 83 | } 84 | 85 | $this->register(); 86 | } 87 | 88 | /** 89 | * Loads plugin assets 90 | */ 91 | public function load_admin_assets() { 92 | 93 | if ( ! $this->should_load_admin_assets() ) { 94 | return; 95 | } 96 | 97 | $this->enqueue_vendors(); 98 | $this->enqueue_admin(); 99 | } 100 | 101 | /** 102 | * Loads plugin assets 103 | */ 104 | public function load_user_admin_assets() { 105 | 106 | $load = isset( $_GET['page'] ) && 'bp-profile-edit' === $_GET['page']; 107 | $load = apply_filters( 'bpxcftr_load_user_admin_assets', $load ); 108 | 109 | if ( ! $load ) { 110 | return; 111 | } 112 | 113 | $this->enqueue_vendors(); 114 | $this->enqueue_user_admin(); 115 | } 116 | 117 | /** 118 | * Registers assets. 119 | */ 120 | private function register() { 121 | $this->register_vendors(); 122 | $this->register_core(); 123 | $this->register_admin(); 124 | } 125 | 126 | /** 127 | * Enqueues front end assets. 128 | */ 129 | public function enqueue_front() { 130 | wp_enqueue_script( 'bp-xprofile-custom-field-types' ); 131 | 132 | wp_localize_script( 'bp-xprofile-custom-field-types', 'BPXprofileCFTR', $this->data ); 133 | } 134 | 135 | /** 136 | * Loads vendor assets. 137 | */ 138 | public function enqueue_vendors() { 139 | wp_enqueue_style( 'select2' ); 140 | wp_enqueue_script( 'modernizr' ); 141 | wp_enqueue_script( 'jscolor' ); 142 | wp_enqueue_script( 'select2' ); 143 | wp_enqueue_script( 'select2-i18n' ); 144 | } 145 | 146 | /** 147 | * Enqueues admin assets for add/edit field screen. 148 | */ 149 | public function enqueue_admin() { 150 | wp_enqueue_script( 'bp-xprofile-custom-field-types-admin' ); 151 | 152 | wp_localize_script( 'bp-xprofile-custom-field-types', 'BPXprofileCFTR', $this->data ); 153 | 154 | wp_localize_script( 'bp-xprofile-custom-field-types-admin', 'BPXprofileCFTRAdmin', $this->data ); 155 | } 156 | 157 | /** 158 | * Enqueues admin assets needed for user profile edit page. 159 | */ 160 | public function enqueue_user_admin() { 161 | wp_enqueue_script( 'bp-xprofile-custom-field-types' ); 162 | wp_localize_script( 'bp-xprofile-custom-field-types', 'BPXprofileCFTR', $this->data ); 163 | } 164 | 165 | /** 166 | * Registers vendor scripts. 167 | */ 168 | private function register_vendors() { 169 | 170 | $url = bp_xprofile_cftr()->url; 171 | $path = bp_xprofile_cftr()->path; 172 | 173 | $version = bp_xprofile_cftr()->version; 174 | 175 | wp_register_script( 'modernizr', $url . 'assets/vendors/modernizr.js', array(), $version, false ); 176 | wp_register_script( 'jscolor', $url . 'assets/vendors/jscolor/jscolor.js', array(), '1.4.1', true ); 177 | 178 | wp_register_script( 'select2', $url . 'assets/vendors/select2/select2.full.min.js', array( 'jquery' ), '4.0.12', true ); 179 | 180 | $locale = apply_filters( 'bpxcftr_select2_js_locale', get_locale() ); 181 | // Select 2, locale. 182 | $locale_js = is_readable( $path . "assets/vendors/select2/i18n/{$locale}.js" ) ? "{$locale}.js" : 'en.js'; 183 | 184 | wp_register_script( 'select2-i18n', $url . "assets/vendors/select2/i18n/{$locale_js}", array( 'select2' ), '4.0.12', true ); 185 | 186 | wp_register_style( 'select2', $url . 'assets/vendors/select2/select2.min.css', array(), '4.0.2' ); 187 | 188 | } 189 | 190 | /** 191 | * Registers core assets. 192 | */ 193 | private function register_core() { 194 | $url = bp_xprofile_cftr()->url; 195 | $version = bp_xprofile_cftr()->version; 196 | 197 | wp_register_style( 'bp-xprofile-custom-field-types', $url . 'assets/css/bp-xprofile-custom-field-types.css', false, $version ); 198 | 199 | wp_register_script( 'bp-xprofile-custom-field-types', $url . 'assets/js/bp-xprofile-custom-field-types.js', array( 'jquery' ), $version, true ); 200 | 201 | $this->data = array(); 202 | } 203 | 204 | /** 205 | * Registers core assets. 206 | */ 207 | private function register_admin() { 208 | $url = bp_xprofile_cftr()->url; 209 | $version = bp_xprofile_cftr()->version; 210 | 211 | wp_register_script( 'bp-xprofile-custom-field-types-admin', $url . 'assets/js/bp-xprofile-custom-field-types-admin.js', array( 'jquery' ), $version, true ); 212 | 213 | $this->data = array( 214 | 'selectableTypes' => bpxcftr_get_selectable_field_types(), 215 | ); 216 | } 217 | 218 | /** 219 | * Should we load admin assets? 220 | * 221 | * @return bool 222 | */ 223 | private function should_load_admin_assets() { 224 | $load = isset( $_GET['page'] ) && ( 'bp-profile-setup' === $_GET['page'] || 'bp-profile-edit' == $_GET['page'] ); 225 | 226 | return apply_filters( 'bpxcftr_load_admin_assets', $load ); 227 | } 228 | 229 | /** 230 | * Should we load front assets. 231 | * 232 | * @return bool 233 | */ 234 | private function should_load_front_assets() { 235 | $load = bp_is_user_profile_edit() || bp_is_register_page(); 236 | 237 | return apply_filters( 'bpxcftr_load_front_assets', $load ); 238 | } 239 | } 240 | -------------------------------------------------------------------------------- /src/field-types/class-field-type-checkbox-acceptance.php: -------------------------------------------------------------------------------- 1 | name = _x( 'Checkbox Acceptance', 'xprofile field type', 'bp-xprofile-custom-field-types' ); 31 | $this->category = _x( 'Custom Fields', 'xprofile field type category', 'bp-xprofile-custom-field-types' ); 32 | 33 | $this->supports_multiple_defaults = false; 34 | $this->accepts_null_value = false; 35 | $this->supports_options = false; 36 | 37 | $this->set_format( '/^.+$/', 'replace' ); 38 | do_action( 'bp_xprofile_field_type_checkbox_acceptance', $this ); 39 | } 40 | 41 | /** 42 | * Edit field html. 43 | * 44 | * @param array $raw_properties properties. 45 | */ 46 | public function edit_field_html( array $raw_properties = array() ) { 47 | 48 | $user_id = bp_displayed_user_id(); 49 | 50 | if ( isset( $raw_properties['user_id'] ) ) { 51 | $user_id = (int) $raw_properties['user_id']; 52 | unset( $raw_properties['user_id'] ); 53 | } 54 | 55 | // HTML5 required attribute. 56 | if ( bp_get_the_profile_field_is_required() ) { 57 | $raw_properties['required'] = 'required'; 58 | $required = true; 59 | } else { 60 | $required = false; 61 | } 62 | ?> 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 |

75 | 76 | 77 | User->Profile Fields screen. 82 | * 83 | * @param array $raw_properties properties. 84 | */ 85 | public function admin_field_html( array $raw_properties = array() ) { 86 | global $field; 87 | 88 | $text = wp_kses_data( self::get_content( $field ) ); 89 | 90 | $html = $this->get_edit_field_html_elements( array_merge( 91 | array( 'type' => 'checkbox' ), 92 | $raw_properties 93 | ) ); 94 | ?> 95 | 99 | type != $type ? 'display: none;' : ''; 117 | $text = self::get_content( $current_field ); 118 | 119 | ?> 120 |
122 |

123 |
124 |

125 | 126 |

127 |
128 |
129 | field_obj->id, $args['user_id'] ) ); 141 | 142 | if ( ! empty( $_POST[ 'field_' . $this->field_obj->id ] ) ) { 143 | $new_checkbox_acceptance = $_POST[ 'field_' . $this->field_obj->id ]; 144 | $checkbox_acceptance = ( $checkbox_acceptance != $new_checkbox_acceptance ) ? $new_checkbox_acceptance : $checkbox_acceptance; 145 | } 146 | 147 | $checkbox_acceptance = absint( $checkbox_acceptance ); 148 | 149 | $atts = array( 150 | 'type' => 'checkbox', 151 | 'name' => bp_get_the_profile_field_input_name(), 152 | 'id' => bp_get_the_profile_field_input_name(), 153 | 'value' => 1, 154 | 'class' => 'bpxcftr-tos-checkbox', 155 | ); 156 | 157 | if ( $checkbox_acceptance == 1 ) { 158 | $atts['checked'] = "checked"; 159 | } 160 | 161 | $html = 'get_edit_field_html_elements( $atts ) . ' />'; 162 | // we should most probably avoid kses on output. 163 | $html .= wp_kses_post( self::get_content( $field ) ); 164 | echo apply_filters( 'bp_get_the_profile_field_checkbox_acceptance', $html, $args['type'], $this->field_obj->id, $checkbox_acceptance ); 165 | ?> 166 | id; 210 | } 211 | 212 | if ( ! $field_id ) { 213 | return ''; 214 | } 215 | 216 | return bp_xprofile_get_meta( $field_id, 'field', 'tos_content', true ); 217 | } 218 | } 219 | -------------------------------------------------------------------------------- /src/field-types/class-field-type-tags.php: -------------------------------------------------------------------------------- 1 | category = _x( 'Custom Fields', 'xprofile field type category', 'bp-xprofile-custom-field-types' ); 32 | $this->name = _x( 'Tags', 'xprofile field type', 'bp-xprofile-custom-field-types' ); 33 | 34 | $this->supports_multiple_defaults = false; 35 | $this->accepts_null_value = true; 36 | $this->supports_options = false; 37 | 38 | $this->set_format( '/^.+$/', 'replace' ); 39 | 40 | /** 41 | * Fires inside __construct() method for Field_Type_Tags class. 42 | * 43 | * @param Field_Type_Tags $this Current instance of the field type tags. 44 | */ 45 | do_action( 'bp_xprofile_field_type_tags', $this ); 46 | } 47 | 48 | /** 49 | * Outputs HTML for this field type on the wp-admin Profile Fields screen. 50 | * 51 | * Must be used inside the {@link bp_profile_fields()} template loop. 52 | * 53 | * @param BP_XProfile_Field $current_field Current field object. 54 | * @param string $control_type Current field object. 55 | */ 56 | public function admin_new_field_html( \BP_XProfile_Field $current_field, $control_type = '' ) { 57 | $type = array_search( get_class( $this ), bp_xprofile_get_field_types(), false ); 58 | 59 | if ( false === $type ) { 60 | return; 61 | } 62 | 63 | $class = $current_field->type != $type ? 'display: none;' : ''; 64 | $text = join( ',', self::get_default_tags( $current_field->id ) ); 65 | 66 | // phpcs:disable 67 | ?> 68 |
70 |

71 |
72 |

73 | 74 |

75 |

76 | 80 |

81 |
82 |
83 | 'multiple', 108 | 'id' => bp_get_the_profile_field_input_name() . '[]', 109 | 'name' => bp_get_the_profile_field_input_name() . '[]', 110 | ) 111 | ); 112 | 113 | $field_id = bp_get_the_profile_field_id(); 114 | 115 | $default_tags = self::get_default_tags( bp_get_the_profile_field_id() ); 116 | $user_tags = xprofile_get_field_data( $field_id, $user_id ); 117 | $user_tags = $user_tags ? $user_tags : array(); 118 | 119 | $tags = array_unique( array_map( 'trim', array_merge( $default_tags, $user_tags ) ) ); 120 | 121 | $options = array(); 122 | 123 | if ( ! $default_tags && ! $user_tags ) { 124 | //$options[''] = __( '', 'bp-xprofile-custom-field-types' ); 125 | } 126 | 127 | $options = array_merge( $options, array_combine( $tags, $tags ) ); 128 | 129 | ?> 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 143 | 144 | 145 |

146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | name = _x( 'Custom Post Type Selector', 'xprofile field type', 'bp-xprofile-custom-field-types' ); 30 | $this->category = _x( 'Custom Fields', 'xprofile field type category', 'bp-xprofile-custom-field-types' ); 31 | 32 | $this->supports_options = false; 33 | 34 | do_action( 'bp_xprofile_field_type_select_custom_post_type', $this ); 35 | } 36 | 37 | /** 38 | * Edit field html. 39 | * 40 | * @param array $raw_properties properties. 41 | */ 42 | public function edit_field_html( array $raw_properties = array() ) { 43 | $user_id = bp_displayed_user_id(); 44 | 45 | if ( isset( $raw_properties['user_id'] ) ) { 46 | $user_id = (int) $raw_properties['user_id']; 47 | unset( $raw_properties['user_id'] ); 48 | } 49 | 50 | $html = $this->get_edit_field_html_elements( $raw_properties ); 51 | ?> 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 64 | 65 | 66 |

67 | 68 | 69 | id ); 80 | $post_selected = \BP_XProfile_ProfileData::get_value_byid( $this->field_obj->id, $args['user_id'] ); 81 | 82 | $html = ''; 83 | 84 | 85 | if ( ! empty( $_POST[ 'field_' . $this->field_obj->id ] ) ) { 86 | $new_post_selected = (int) $_POST[ 'field_' . $this->field_obj->id ]; 87 | $post_selected = ( $post_selected != $new_post_selected ) ? $new_post_selected : $post_selected; 88 | } 89 | // Get posts of custom post type selected. 90 | $posts = new \WP_Query( 91 | array( 92 | 'posts_per_page' => - 1, 93 | 'post_type' => $post_type_selected, 94 | 'orderby' => 'title', 95 | 'order' => 'ASC', 96 | ) 97 | ); 98 | 99 | if ( $posts ) { 100 | foreach ( $posts->posts as $post ) { 101 | $html .= sprintf( 102 | '', 103 | $post->ID, 104 | ( $post_selected == $post->ID ) ? ' selected="selected"' : '', 105 | $post->post_title 106 | ); 107 | } 108 | } 109 | 110 | echo apply_filters( 'bp_get_the_profile_field_select_custom_post_type', $html, $args['type'], $post_type_selected, $this->field_obj->id ); 111 | } 112 | 113 | /** 114 | * Dashboard->Users->Profile Fields entry. 115 | * 116 | * @param array $raw_properties properties. 117 | */ 118 | public function admin_field_html( array $raw_properties = array() ) { 119 | $html = $this->get_edit_field_html_elements( $raw_properties ); 120 | ?> 121 | 124 | Users->Profile Fields->New|Edit entry. 129 | * 130 | * @param \BP_XProfile_Field $current_field object. 131 | * @param string $control_type type. 132 | */ 133 | public function admin_new_field_html( \BP_XProfile_Field $current_field, $control_type = '' ) { 134 | 135 | $type = array_search( get_class( $this ), bp_xprofile_get_field_types() ); 136 | 137 | if ( false === $type ) { 138 | return; 139 | } 140 | 141 | $class = $current_field->type != $type ? 'display: none;' : ''; 142 | 143 | $post_types = get_post_types( array( 'public' => true ) ); 144 | 145 | $selected_post_type = self::get_selected_post_type( $current_field->id ); 146 | 147 | ?> 148 |
150 | 151 |

152 | 153 |

154 |
155 |

156 | 157 | 163 |

164 |
165 | 166 |
167 | %2$s', esc_url( get_permalink( $post_id ) ), get_the_title( $post_id ) ); 198 | } 199 | 200 | /** 201 | * Returns the selected post type. 202 | * 203 | * @param int $field_id field id. 204 | * 205 | * @return string 206 | */ 207 | private static function get_selected_post_type( $field_id ) { 208 | 209 | if ( ! $field_id ) { 210 | return ''; 211 | } 212 | 213 | return bp_xprofile_get_meta( $field_id, 'field', 'selected_post_type', true ); 214 | } 215 | } 216 | -------------------------------------------------------------------------------- /src/field-types/class-field-type-select-taxonomy.php: -------------------------------------------------------------------------------- 1 | name = _x( 'Custom Taxonomy Selector', 'xprofile field type', 'bp-xprofile-custom-field-types' ); 31 | $this->category = _x( 'Custom Fields', 'xprofile field type category', 'bp-xprofile-custom-field-types' ); 32 | 33 | $this->supports_options = false; 34 | 35 | do_action( 'bp_xprofile_field_type_select_custom_taxonomy', $this ); 36 | } 37 | 38 | /** 39 | * Field edit screen. 40 | * 41 | * @param array $raw_properties properties. 42 | */ 43 | public function edit_field_html( array $raw_properties = array() ) { 44 | 45 | $user_id = bp_displayed_user_id(); 46 | 47 | if ( isset( $raw_properties['user_id'] ) ) { 48 | $user_id = (int) $raw_properties['user_id']; 49 | unset( $raw_properties['user_id'] ); 50 | } 51 | 52 | $html = $this->get_edit_field_html_elements( $raw_properties ); 53 | ?> 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 65 | 66 | 67 |

68 | 69 | 70 | id ); 82 | 83 | $term_selected = \BP_XProfile_ProfileData::get_value_byid( $this->field_obj->id, $args['user_id'] ); 84 | 85 | $html = ''; 86 | 87 | if ( ! empty( $_POST[ 'field_' . $this->field_obj->id ] ) ) { 88 | $new_term_selected = (int) $_POST[ 'field_' . $this->field_obj->id ]; 89 | $term_selected = ( $term_selected != $new_term_selected ) ? $new_term_selected : $term_selected; 90 | } 91 | 92 | // Get terms of custom taxonomy selected. 93 | $terms = get_terms( $taxonomy_selected, array( 'hide_empty' => false ) ); 94 | 95 | if ( $terms && ! is_wp_error( $terms ) ) { 96 | 97 | foreach ( $terms as $term ) { 98 | $html .= sprintf( 99 | '', 100 | $term->term_id, 101 | ( $term_selected == $term->term_id ) ? ' selected="selected"' : '', 102 | $term->name 103 | ); 104 | } 105 | } 106 | 107 | echo apply_filters( 'bp_get_the_profile_field_select_custom_taxonomy', $html, $args['type'], $term_selected, $this->field_obj->id ); 108 | } 109 | 110 | /** 111 | * Dashboard->Users->Profile Fields entry. 112 | * 113 | * @param array $raw_properties properties. 114 | */ 115 | public function admin_field_html( array $raw_properties = array() ) { 116 | $html = $this->get_edit_field_html_elements( $raw_properties ); 117 | ?> 118 | 119 | 122 | 123 | Users->Profile Fields->New|Edit entry. 128 | * 129 | * @param \BP_XProfile_Field $current_field object. 130 | * @param string $control_type type. 131 | */ 132 | public function admin_new_field_html( \BP_XProfile_Field $current_field, $control_type = '' ) { 133 | 134 | $type = array_search( get_class( $this ), bp_xprofile_get_field_types() ); 135 | 136 | if ( false === $type ) { 137 | return; 138 | } 139 | 140 | $class = $current_field->type != $type ? 'display: none;' : ''; 141 | 142 | $taxonomies = get_taxonomies( array( 'public' => true ) ); 143 | 144 | $selected_tax = self::get_selected_taxonomy( $current_field->id ); 145 | ?> 146 |
147 | 150 |

151 | 152 |

153 |
154 |

155 | 156 | 162 |

163 |
164 | 165 |
166 | %2$s', esc_url( get_term_link( $term, $tax ) ), esc_html( $term->name ) ); 214 | } 215 | 216 | /** 217 | * Returns selected taxonomy. 218 | * 219 | * @param int $field_id field id. 220 | * 221 | * @return string 222 | */ 223 | public static function get_selected_taxonomy( $field_id ) { 224 | 225 | if ( ! $field_id ) { 226 | return ''; 227 | } 228 | 229 | return bp_xprofile_get_meta( $field_id, 'field', 'selected_taxonomy', true ); 230 | } 231 | } 232 | -------------------------------------------------------------------------------- /assets/vendors/modernizr.js: -------------------------------------------------------------------------------- 1 | /* Modernizr 2.6.2 (Custom Build) | MIT & BSD 2 | * Build: http://modernizr.com/download/#-inputtypes-shiv-cssclasses-load 3 | */ 4 | ;window.Modernizr=function(a,b,c){function v(a){j.cssText=a}function w(a,b){return v(prefixes.join(a+";")+(b||""))}function x(a,b){return typeof a===b}function y(a,b){return!!~(""+a).indexOf(b)}function z(a,b,d){for(var e in a){var f=b[a[e]];if(f!==c)return d===!1?a[e]:x(f,"function")?f.bind(d||b):f}return!1}function A(){e.inputtypes=function(a){for(var d=0,e,f,h,i=a.length;d",d.insertBefore(c.lastChild,d.firstChild)}function l(){var a=r.elements;return typeof a=="string"?a.split(" "):a}function m(a){var b=i[a[g]];return b||(b={},h++,a[g]=h,i[h]=b),b}function n(a,c,f){c||(c=b);if(j)return c.createElement(a);f||(f=m(c));var g;return f.cache[a]?g=f.cache[a].cloneNode():e.test(a)?g=(f.cache[a]=f.createElem(a)).cloneNode():g=f.createElem(a),g.canHaveChildren&&!d.test(a)?f.frag.appendChild(g):g}function o(a,c){a||(a=b);if(j)return a.createDocumentFragment();c=c||m(a);var d=c.frag.cloneNode(),e=0,f=l(),g=f.length;for(;e",f="hidden"in a,j=a.childNodes.length==1||function(){b.createElement("a");var a=b.createDocumentFragment();return typeof a.cloneNode=="undefined"||typeof a.createDocumentFragment=="undefined"||typeof a.createElement=="undefined"}()}catch(c){f=!0,j=!0}})();var r={elements:c.elements||"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video",shivCSS:c.shivCSS!==!1,supportsUnknownElements:j,shivMethods:c.shivMethods!==!1,type:"default",shivDocument:q,createElement:n,createDocumentFragment:o};a.html5=r,q(b)}(this,b),e._version=d,g.className=g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(f?" js "+q.join(" "):""),e}(this,this.document),function(a,b,c){function d(a){return"[object Function]"==o.call(a)}function e(a){return"string"==typeof a}function f(){}function g(a){return!a||"loaded"==a||"complete"==a||"uninitialized"==a}function h(){var a=p.shift();q=1,a?a.t?m(function(){("c"==a.t?B.injectCss:B.injectJs)(a.s,0,a.a,a.x,a.e,1)},0):(a(),h()):q=0}function i(a,c,d,e,f,i,j){function k(b){if(!o&&g(l.readyState)&&(u.r=o=1,!q&&h(),l.onload=l.onreadystatechange=null,b)){"img"!=a&&m(function(){t.removeChild(l)},50);for(var d in y[c])y[c].hasOwnProperty(d)&&y[c][d].onload()}}var j=j||B.errorTimeout,l=b.createElement(a),o=0,r=0,u={t:d,s:c,e:f,a:i,x:j};1===y[c]&&(r=1,y[c]=[]),"object"==a?l.data=c:(l.src=c,l.type=a),l.width=l.height="0",l.onerror=l.onload=l.onreadystatechange=function(){k.call(this,r)},p.splice(e,0,u),"img"!=a&&(r||2===y[c]?(t.insertBefore(l,s?null:n),m(k,j)):y[c].push(l))}function j(a,b,c,d,f){return q=0,b=b||"j",e(a)?i("c"==b?v:u,a,b,this.i++,c,d,f):(p.splice(this.i++,0,a),1==p.length&&h()),this}function k(){var a=B;return a.loader={load:j,i:0},a}var l=b.documentElement,m=a.setTimeout,n=b.getElementsByTagName("script")[0],o={}.toString,p=[],q=0,r="MozAppearance"in l.style,s=r&&!!b.createRange().compareNode,t=s?l:n.parentNode,l=a.opera&&"[object Opera]"==o.call(a.opera),l=!!b.attachEvent&&!l,u=r?"object":l?"script":"img",v=l?"script":u,w=Array.isArray||function(a){return"[object Array]"==o.call(a)},x=[],y={},z={timeout:function(a,b){return b.length&&(a.timeout=b[0]),a}},A,B;B=function(a){function b(a){var a=a.split("!"),b=x.length,c=a.pop(),d=a.length,c={url:c,origUrl:c,prefixes:a},e,f,g;for(f=0;fname = _x( 'Custom Post Type Multiselector', 'xprofile field type', 'bp-xprofile-custom-field-types' ); 32 | $this->category = _x( 'Custom Fields', 'xprofile field type category', 'bp-xprofile-custom-field-types' ); 33 | 34 | $this->supports_multiple_defaults = true; 35 | $this->supports_options = false; 36 | do_action( 'bp_xprofile_field_type_multiselect_custom_post_type', $this ); 37 | } 38 | 39 | /** 40 | * Edit field html. 41 | * 42 | * @param array $raw_properties properties. 43 | */ 44 | public function edit_field_html( array $raw_properties = array() ) { 45 | $user_id = bp_displayed_user_id(); 46 | 47 | if ( isset( $raw_properties['user_id'] ) ) { 48 | $user_id = (int) $raw_properties['user_id']; 49 | unset( $raw_properties['user_id'] ); 50 | } 51 | 52 | $html = $this->get_edit_field_html_elements( 53 | array_merge( 54 | array( 55 | 'multiple' => 'multiple', 56 | 'id' => bp_get_the_profile_field_input_name() . '[]', 57 | 'name' => bp_get_the_profile_field_input_name() . '[]', 58 | ), 59 | $raw_properties 60 | ) 61 | ); 62 | ?> 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 74 | 75 | 76 |

77 | 78 | 79 | id ); 91 | $posts_selected = maybe_unserialize( \BP_XProfile_ProfileData::get_value_byid( $this->field_obj->id, $args['user_id'] ) ); 92 | 93 | $html = ''; 94 | 95 | if ( ! empty( $_POST[ 'field_' . $this->field_obj->id ] ) ) { 96 | $new_posts_selected = $_POST[ 'field_' . $this->field_obj->id ]; 97 | $posts_selected = ( $posts_selected != $new_posts_selected ) ? $new_posts_selected : $posts_selected; 98 | } 99 | // Get posts of custom post type selected. 100 | $posts = new \WP_Query( 101 | array( 102 | 'posts_per_page' => - 1, 103 | 'post_type' => $post_type_selected, 104 | 'orderby' => 'title', 105 | 'order' => 'ASC', 106 | ) 107 | ); 108 | 109 | if ( $posts ) { 110 | foreach ( $posts->posts as $post ) { 111 | $html .= sprintf( 112 | '', 113 | $post->ID, 114 | ( ! empty( $posts_selected ) && ( in_array( $post->ID, $posts_selected ) ) ) ? 'selected="selected"' : '', 115 | $post->post_title 116 | ); 117 | } 118 | } 119 | 120 | echo apply_filters( 'bp_get_the_profile_field_multiselect_custom_post_type', $html, $args['type'], $post_type_selected, $this->field_obj->id ); 121 | } 122 | 123 | /** 124 | * Dashboard->Users->Profile Fields 125 | * 126 | * @param array $raw_properties atts. 127 | */ 128 | public function admin_field_html( array $raw_properties = array() ) { 129 | 130 | $html = $this->get_edit_field_html_elements( 131 | array_merge( 132 | array( 133 | 'multiple' => 'multiple', 134 | 'id' => bp_get_the_profile_field_input_name() . '[]', 135 | 'name' => bp_get_the_profile_field_input_name() . '[]', 136 | ), 137 | $raw_properties 138 | ) 139 | ); 140 | ?> 141 | 142 | 145 | 146 | Users->Profile Fields->New|Edit entry. 151 | * 152 | * @param \BP_XProfile_Field $current_field object. 153 | * @param string $control_type type. 154 | */ 155 | public function admin_new_field_html( \BP_XProfile_Field $current_field, $control_type = '' ) { 156 | 157 | $type = array_search( get_class( $this ), bp_xprofile_get_field_types() ); 158 | 159 | if ( false === $type ) { 160 | return; 161 | } 162 | 163 | $class = $current_field->type != $type ? 'display: none;' : ''; 164 | 165 | $post_types = get_post_types( array( 'public' => true ) ); 166 | 167 | $selected_post_type = self::get_selected_post_type( $current_field->id ); 168 | ?> 169 |
170 | 171 |

172 | 173 |

174 |
175 |

176 | 177 | 183 |

184 |
185 | 186 |
187 | %2$s', esc_url( get_permalink( $post_id ) ), get_the_title( $post_id ) ); 250 | } 251 | 252 | if ( $list ) { 253 | return "
    {$list}
"; 254 | } 255 | 256 | return ''; 257 | } 258 | 259 | /** 260 | * Returns selected post type. 261 | * 262 | * @param int $field_id field id. 263 | * 264 | * @return string 265 | */ 266 | private static function get_selected_post_type( $field_id ) { 267 | 268 | if ( ! $field_id ) { 269 | return ''; 270 | } 271 | 272 | return bp_xprofile_get_meta( $field_id, 'field', 'selected_post_type', true ); 273 | } 274 | } 275 | --------------------------------------------------------------------------------