Version Description
Download this release
Release Info
| Developer | borkweb |
| Plugin | |
| Version | 4.10.7.3 |
| Comparing to | |
| See all releases | |
Code changes from version 4.12.1.1 to 4.10.7.3
- common/lang/readme.txt +0 -3
- common/lang/tribe-common-af.mo +0 -0
- common/lang/tribe-common-ar.mo +0 -0
- common/lang/tribe-common-bg_BG.mo +0 -0
- common/lang/tribe-common-ca.mo +0 -0
- common/lang/tribe-common-cs_CZ.mo +0 -0
- common/lang/tribe-common-da_DK.mo +0 -0
- common/lang/tribe-common-de_DE.mo +0 -0
- common/lang/tribe-common-el.mo +0 -0
- common/lang/tribe-common-en_GB.mo +0 -0
- common/lang/tribe-common-es_ES.mo +0 -0
- common/lang/tribe-common-et.mo +0 -0
- common/lang/tribe-common-fi.mo +0 -0
- common/lang/tribe-common-fr_CA.mo +0 -0
- common/lang/tribe-common-fr_FR.mo +0 -0
- common/lang/tribe-common-hu_HU.mo +0 -0
- common/lang/tribe-common-id_ID.mo +0 -0
- common/lang/tribe-common-is_IS.mo +0 -0
- common/lang/tribe-common-it_IT.mo +0 -0
- common/lang/tribe-common-ja.mo +0 -0
- common/lang/tribe-common-lt_LT.mo +0 -0
- common/lang/tribe-common-lv.mo +0 -0
- common/lang/tribe-common-nb_NO.mo +0 -0
- common/lang/tribe-common-nl_NL.mo +0 -0
- common/lang/tribe-common-pl_PL.mo +0 -0
- common/lang/tribe-common-pt_BR.mo +0 -0
- common/lang/tribe-common-pt_PT.mo +0 -0
- common/lang/tribe-common-ro_RO.mo +0 -0
- common/lang/tribe-common-ru_RU.mo +0 -0
- common/lang/tribe-common-sk_SK.mo +0 -0
- common/lang/tribe-common-sl_SI.mo +0 -0
- common/lang/tribe-common-sr_RS.mo +0 -0
- common/lang/tribe-common-sv_SE.mo +0 -0
- common/lang/tribe-common-tr_TR.mo +0 -0
- common/lang/tribe-common-zh_CN.mo +0 -0
- common/lang/tribe-common-zh_TW.mo +0 -0
- common/lang/tribe-common.pot +153 -214
- common/src/Tribe/Abstract_Plugin_Register.php +8 -30
- common/src/Tribe/Admin/Notice/Plugin_Download.php +7 -25
- common/src/Tribe/Admin/Notices.php +11 -91
- common/src/Tribe/Assets.php +77 -127
- common/src/Tribe/Autoloader.php +1 -18
- common/src/Tribe/Cache.php +75 -298
- common/src/Tribe/Cache_Listener.php +7 -42
- common/src/Tribe/Container.php +0 -46
- common/src/Tribe/Context.php +4 -175
- common/src/Tribe/Context/locations.php +1 -70
- common/src/Tribe/Customizer.php +137 -23
- common/src/Tribe/Data.php +9 -9
- common/src/Tribe/Date_Utils.php +24 -380
- common/src/Tribe/Debug_Bar/Panels/Context.php +2 -2
- common/src/Tribe/Debug_Bar/Panels/Json_Ld.php +0 -84
- common/src/Tribe/Dependency.php +54 -36
- common/src/Tribe/Dialog/View.php +0 -526
- common/src/Tribe/Editor.php +4 -47
- common/src/Tribe/Editor/Blocks/Abstract.php +3 -37
- common/src/Tribe/Editor/Configuration.php +0 -1
- common/src/Tribe/Extension.php +9 -57
- common/src/Tribe/Feature_Detection.php +0 -106
- common/src/Tribe/Field.php +0 -5
- common/src/Tribe/Freemius.php +2 -3
- common/src/Tribe/Image/Uploader.php +69 -160
- common/src/Tribe/Languages/Locations.php +3 -3
- common/src/Tribe/Log.php +0 -3
- common/src/Tribe/Log/Action_Logger.php +0 -125
- common/src/Tribe/Log/Canonical_Formatter.php +0 -101
- common/src/Tribe/Log/File_Logger.php +1 -1
- common/src/Tribe/Log/Monolog_Logger.php +0 -54
- common/src/Tribe/Log/README.md +0 -154
- common/src/Tribe/Log/Service_Provider.php +0 -148
- common/src/Tribe/Main.php +95 -181
- common/src/Tribe/Models/Post_Types/Base.php +0 -206
- common/src/Tribe/Models/Post_Types/Nothing.php +0 -44
- common/src/Tribe/PUE/Checker.php +83 -93
- common/src/Tribe/PUE/Update_Prevention.php +1 -1
- common/src/Tribe/Plugins.php +36 -68
- common/src/Tribe/Post_Transient.php +10 -11
- common/src/Tribe/Process/Handler.php +0 -40
- common/src/Tribe/Process/Post_Thumbnail_Setter.php +14 -58
- common/src/Tribe/Promoter/Auth.php +10 -0
- common/src/Tribe/Promoter/Connector.php +39 -87
- common/src/Tribe/Repository.php +16 -135
- common/src/Tribe/Repository/Core_Read_Interface.php +0 -402
- common/src/Tribe/Repository/Filter_Validation.php +0 -61
- common/src/Tribe/Repository/Interface.php +7 -0
- common/src/Tribe/Repository/Query_Filters.php +14 -68
- common/src/Tribe/Repository/Read_Interface.php +378 -4
- common/src/Tribe/Repository/Usage_Error.php +0 -41
- common/src/Tribe/Rewrite.php +24 -139
- common/src/Tribe/Service_Providers/Debug_Bar.php +0 -2
- common/src/Tribe/Service_Providers/Dialog.php +0 -110
- common/src/Tribe/Service_Providers/{Promoter.php → Promoter_Connector.php} +4 -6
- common/src/Tribe/Service_Providers/Shortcodes.php +0 -80
- common/src/Tribe/Service_Providers/Tooltip.php +8 -13
- common/src/Tribe/Settings.php +38 -44
- common/src/Tribe/Settings_Manager.php +13 -48
- common/src/Tribe/Shortcode/Manager.php +0 -107
- common/src/Tribe/Shortcode/Shortcode_Abstract.php +0 -247
- common/src/Tribe/Shortcode/Shortcode_Interface.php +0 -125
- common/src/Tribe/Support.php +4 -17
- common/src/Tribe/Template.php +100 -660
- common/src/Tribe/Timezones.php +2 -11
- common/src/Tribe/Tooltip/View.php +8 -39
- common/src/Tribe/Traits/Cache_User.php +0 -17
- common/src/Tribe/Utils/Array.php +0 -79
- common/src/Tribe/Utils/Collection_Interface.php +1 -1
- common/src/Tribe/Utils/Collection_Trait.php +2 -38
- common/src/Tribe/Utils/Date_I18n.php +0 -48
- common/src/Tribe/Utils/Date_I18n_Immutable.php +0 -48
- common/src/Tribe/Utils/Lazy_Collection.php +0 -9
- common/src/Tribe/Utils/Lazy_Events.php +0 -172
- common/src/Tribe/Utils/Lazy_String.php +0 -141
- common/src/Tribe/Utils/Post_Thumbnail.php +35 -115
- common/src/Tribe/Utils/Query.php +0 -72
- common/src/Tribe/Utils/Strings.php +0 -65
- common/src/Tribe/Validate.php +59 -10
- common/src/Tribe/Validator/Base.php +1 -3
- common/src/Tribe/View_Helpers.php +5 -13
- common/src/admin-views/tribe-options-display.php +9 -9
- common/src/admin-views/tribe-options-general.php +30 -33
- common/src/functions/multibyte.php +0 -31
- common/src/functions/template-tags/date.php +18 -38
- common/src/functions/template-tags/general.php +23 -50
- common/src/functions/template-tags/html.php +0 -68
- common/src/functions/template-tags/post.php +0 -97
- common/src/functions/utils.php +53 -469
- common/src/modules/components/form/index.js +1 -0
- common/src/modules/components/form/select/component.js +116 -0
- common/src/modules/components/form/select/index.js +1 -0
- common/src/modules/components/form/select/style.pcss +56 -0
- common/src/modules/components/index.js +5 -0
- common/src/modules/components/plugin-block-hooks/__tests__/__snapshots__/plugin-block-hooks.spec.js.snap +131 -0
- common/src/modules/components/plugin-block-hooks/__tests__/plugin-block-hooks.spec.js +92 -0
- common/src/modules/components/plugin-block-hooks/component.js +138 -0
- common/src/modules/components/plugin-block-hooks/container.js +21 -0
- common/src/modules/components/plugin-block-hooks/index.js +1 -0
- common/src/modules/components/plugin-block-hooks/style.pcss +37 -0
- common/src/modules/components/prevent-block-close/__tests__/component.spec.js +15 -0
- common/src/modules/components/prevent-block-close/component.js +38 -0
- common/src/modules/components/prevent-block-close/index.js +1 -0
- common/src/modules/data/__tests__/utils.test.js +10 -0
- common/src/modules/data/editor/post-types.js +3 -0
- common/src/modules/data/forms/__tests__/__snapshots__/actions.test.js.snap +147 -0
- common/src/modules/data/forms/__tests__/actions.test.js +96 -0
- common/src/modules/data/forms/__tests__/reducer.test.js +88 -0
- common/src/modules/data/forms/__tests__/selectors.test.js +89 -0
- common/src/modules/data/forms/__tests__/types.js +19 -0
- common/src/modules/data/forms/actions.js +153 -0
- common/src/modules/data/forms/index.js +12 -0
- common/src/modules/data/forms/reducer.js +33 -0
- common/src/modules/data/forms/reducers/__tests__/__snapshots__/form.test.js.snap +84 -0
- common/src/modules/data/forms/reducers/__tests__/form.test.js +49 -0
- common/src/modules/data/forms/reducers/__tests__/volatile.test.js +23 -0
- common/src/modules/data/forms/reducers/form.js +58 -0
- common/src/modules/data/forms/reducers/index.js +2 -0
- common/src/modules/data/forms/reducers/volatile.js +15 -0
- common/src/modules/data/forms/selectors.js +39 -0
- common/src/modules/data/forms/types.js +15 -0
- common/src/modules/data/index.js +9 -0
- common/src/modules/data/plugins/__tests__/__snapshots__/actions.test.js.snap +19 -0
- common/src/modules/data/plugins/__tests__/actions.test.js +14 -0
- common/src/modules/data/plugins/__tests__/reducer.test.js +25 -0
- common/src/modules/data/plugins/__tests__/selectors.test.js +23 -0
- common/src/modules/data/plugins/__tests__/types.test.js +12 -0
- common/src/modules/data/plugins/actions.js +18 -0
- common/src/modules/data/plugins/constants.js +4 -0
- common/src/modules/data/plugins/index.js +12 -0
- common/src/modules/data/plugins/proptypes.js +15 -0
- common/src/modules/data/plugins/reducer.js +20 -0
- common/src/modules/data/plugins/selectors.js +9 -0
- common/src/modules/data/plugins/types.js +7 -0
- common/src/modules/data/reducers.js +15 -0
- common/src/modules/data/utils.js +1 -0
- common/src/modules/elements/accordion/__tests__/__snapshots__/element.test.js.snap +71 -0
- common/src/modules/elements/accordion/__tests__/element.test.js +45 -0
- common/src/modules/elements/accordion/element.js +58 -0
- common/src/modules/elements/accordion/row/__tests__/__snapshots__/template.test.js.snap +31 -0
- common/src/modules/elements/accordion/row/__tests__/template.test.js +56 -0
- common/src/modules/elements/accordion/row/template.js +129 -0
- common/src/modules/elements/accordion/style.pcss +8 -0
- common/src/modules/elements/block-icon/index.js +16 -0
- common/src/modules/elements/block-icon/style.pcss +24 -0
- common/src/modules/elements/button/__tests__/__snapshots__/element.test.js.snap +62 -0
- common/src/modules/elements/button/__tests__/element.test.js +60 -0
- common/src/modules/elements/button/element.js +56 -0
- common/src/modules/elements/button/style.pcss +58 -0
- common/src/modules/elements/checkbox-input/__tests__/__snapshots__/element.test.js.snap +47 -0
- common/src/modules/elements/checkbox-input/__tests__/element.test.js +39 -0
- common/src/modules/elements/checkbox-input/element.js +35 -0
- common/src/modules/elements/checkbox-input/style.pcss +25 -0
- common/src/modules/elements/checkbox/__tests__/__snapshots__/element.test.js.snap +168 -0
- common/src/modules/elements/checkbox/__tests__/element.test.js +70 -0
- common/src/modules/elements/checkbox/element.js +61 -0
- common/src/modules/elements/counter/__tests__/__snapshots__/element.test.js.snap +57 -0
- common/src/modules/elements/counter/__tests__/element.test.js +32 -0
- common/src/modules/elements/counter/element.js +37 -0
- common/src/modules/elements/counter/style.pcss +22 -0
- common/src/modules/elements/creatable-select/__tests__/__snapshots__/element.test.js.snap +241 -0
- common/src/modules/elements/creatable-select/__tests__/element.test.js +31 -0
- common/src/modules/elements/creatable-select/element.js +50 -0
- common/src/modules/elements/creatable-select/style.pcss +75 -0
- common/src/modules/elements/day-picker-input/element.js +34 -0
- common/src/modules/elements/day-picker-input/style.pcss +109 -0
- common/src/modules/elements/heading/__tests__/__snapshots__/element.test.js.snap +49 -0
- common/src/modules/elements/heading/__tests__/element.test.js +47 -0
- common/src/modules/elements/heading/element.js +32 -0
- common/src/modules/elements/heading/style.pcss +16 -0
- common/src/modules/elements/image-upload/__tests__/__snapshots__/element.test.js.snap +191 -0
- common/src/modules/elements/image-upload/__tests__/element.test.js +168 -0
- common/src/modules/elements/image-upload/element.js +114 -0
- common/src/modules/elements/image-upload/style.pcss +109 -0
- common/src/modules/elements/image/__tests__/__snapshots__/element.test.js.snap +27 -0
- common/src/modules/elements/image/__tests__/element.test.js +38 -0
- common/src/modules/elements/image/element.js +28 -0
- common/src/modules/elements/index.js +36 -0
- common/src/modules/elements/input/__tests__/__snapshots__/element.test.js.snap +23 -0
- common/src/modules/elements/input/__tests__/element.test.js +28 -0
- common/src/modules/elements/input/element.js +30 -0
- common/src/modules/elements/input/style.pcss +25 -0
- common/src/modules/elements/label-with-link/__tests__/__snapshots__/element.test.js.snap +51 -0
- common/src/modules/elements/label-with-link/__tests__/element.test.js +32 -0
- common/src/modules/elements/label-with-link/element.js +66 -0
- common/src/modules/elements/label-with-link/style.pcss +54 -0
- common/src/modules/elements/label-with-modal/__tests__/__snapshots__/element.test.js.snap +60 -0
- common/src/modules/elements/label-with-modal/__tests__/element.test.js +26 -0
- common/src/modules/elements/label-with-modal/element.js +71 -0
- common/src/modules/elements/label-with-modal/style.pcss +53 -0
- common/src/modules/elements/labeled-item/__tests__/__snapshots__/element.test.js.snap +50 -0
- common/src/modules/elements/labeled-item/__tests__/element.test.js +39 -0
- common/src/modules/elements/labeled-item/element.js +52 -0
- common/src/modules/elements/link/__tests__/__snapshots__/element.test.js.snap +40 -0
- common/src/modules/elements/link/__tests__/element.test.js +39 -0
- common/src/modules/elements/link/element.js +44 -0
- common/src/modules/elements/modal-button/__tests__/__snapshots__/element.test.js.snap +51 -0
- common/src/modules/elements/modal-button/__tests__/element.test.js +46 -0
- common/src/modules/elements/modal-button/element.js +103 -0
- common/src/modules/elements/number-input/__tests__/__snapshots__/element.test.js.snap +55 -0
- common/src/modules/elements/number-input/__tests__/element.test.js +47 -0
- common/src/modules/elements/number-input/element.js +40 -0
- common/src/modules/elements/paragraph/__tests__/__snapshots__/element.test.js.snap +17 -0
- common/src/modules/elements/paragraph/__tests__/element.test.js +19 -0
- common/src/modules/elements/paragraph/element.js +41 -0
- common/src/modules/elements/paragraph/style.pcss +24 -0
- common/src/modules/elements/placeholder/__tests__/__snapshots__/element.test.js.snap +17 -0
- common/src/modules/elements/placeholder/__tests__/element.test.js +18 -0
- common/src/modules/elements/placeholder/element.js +23 -0
- common/src/modules/elements/placeholder/style.pcss +12 -0
- common/src/modules/elements/radio-input/element.js +29 -0
- common/src/modules/elements/radio/element.js +50 -0
- common/src/modules/elements/select/__tests__/__snapshots__/element.test.js.snap +241 -0
- common/src/modules/elements/select/__tests__/element.test.js +31 -0
- common/src/modules/elements/select/element.js +41 -0
- common/src/modules/elements/select/style.pcss +78 -0
- common/src/modules/elements/style.pcss +3 -0
- common/src/modules/elements/textarea/element.js +20 -0
- common/src/modules/elements/time-picker/element.js +204 -0
- common/src/modules/elements/time-picker/style.pcss +86 -0
- common/src/modules/elements/tooltip/__tests__/__snapshots__/element.test.js.snap +22 -0
- common/src/modules/elements/tooltip/__tests__/element.test.js +33 -0
- common/src/modules/elements/tooltip/element.js +56 -0
- common/src/modules/elements/tooltip/style.pcss +14 -0
- common/src/modules/elements/url-input/element.js +27 -0
- common/src/modules/hoc/__tests__/__snapshots__/with-form.test.js.snap +19 -0
- common/src/modules/hoc/__tests__/__snapshots__/with-save-data.test.js.snap +62 -0
- common/src/modules/hoc/__tests__/__snapshots__/with-store.test.js.snap +18 -0
- common/src/modules/hoc/__tests__/with-form.test.js +89 -0
- common/src/modules/hoc/__tests__/with-save-data.test.js +191 -0
- common/src/modules/hoc/__tests__/with-selected.test.js +97 -0
- common/src/modules/hoc/__tests__/with-store.test.js +28 -0
- common/src/modules/hoc/index.js +5 -0
- common/src/modules/hoc/with-block-closer.js +129 -0
- common/src/modules/hoc/with-form.js +71 -0
- {src/modules/blocks → common/src/modules}/hoc/with-save-data.js +1 -6
- common/src/modules/hoc/with-selected.js +64 -0
- common/src/modules/hoc/with-store.js +26 -0
- common/src/modules/package.json +17 -0
- common/src/modules/store/configure-store.js +37 -0
- common/src/modules/store/index.js +13 -0
- common/src/modules/store/middlewares/index.js +3 -0
- common/src/modules/store/middlewares/request/__tests__/__snapshots__/actions.test.js.snap +11 -0
- common/src/modules/store/middlewares/request/__tests__/actions.test.js +14 -0
- common/src/modules/store/middlewares/request/__tests__/types.test.js +11 -0
- common/src/modules/store/middlewares/request/__tests__/utils.test.js +61 -0
- common/src/modules/store/middlewares/request/__tests__/wp-request.test.js +169 -0
- common/src/modules/store/middlewares/request/actions.js +9 -0
- common/src/modules/store/middlewares/request/index.js +9 -0
- common/src/modules/store/middlewares/request/types.js +6 -0
- common/src/modules/store/middlewares/request/utils.js +32 -0
- common/src/modules/store/middlewares/request/wp-request.js +76 -0
- common/src/modules/utils/__tests__/__snapshots__/globals.test.js.snap +93 -0
- common/src/modules/utils/__tests__/__snapshots__/time.test.js.snap +33 -0
- common/src/modules/utils/__tests__/date.test.js +189 -0
- common/src/modules/utils/__tests__/dom.test.js +73 -0
- common/src/modules/utils/__tests__/globals.test.js +84 -0
- common/src/modules/utils/__tests__/input.test.js +20 -0
- common/src/modules/utils/__tests__/moment.test.js +332 -0
- common/src/modules/utils/__tests__/number.test.js +36 -0
- common/src/modules/utils/__tests__/proptypes.test.js +145 -0
- common/src/modules/utils/__tests__/range.test.js +65 -0
- common/src/modules/utils/__tests__/slide.test.js +12 -0
- common/src/modules/utils/__tests__/string.test.js +135 -0
- common/src/modules/utils/__tests__/time.test.js +222 -0
- common/src/modules/utils/api.js +57 -0
- common/src/modules/utils/date.js +151 -0
- common/src/modules/utils/dom.js +50 -0
- common/src/modules/utils/get-hidden-height.js +28 -0
- common/src/modules/utils/globals.js +37 -0
- common/src/modules/utils/index.js +27 -0
- common/src/modules/utils/input.js +12 -0
- common/src/modules/utils/moment.js +332 -0
- common/src/modules/utils/number.js +22 -0
- common/src/modules/utils/proptypes.js +73 -0
- common/src/modules/utils/range.js +89 -0
- common/src/modules/utils/slide.js +119 -0
- common/src/modules/utils/string.js +109 -0
- common/src/modules/utils/time.js +207 -0
- common/src/modules/utils/timezone.js +72 -0
- common/src/resources/css/accessibility.css +34 -0
- common/src/resources/css/app-shop.css +102 -0
- common/src/resources/css/app/components.css +2 -0
- common/src/resources/css/app/components.min.css +2 -2
- common/src/resources/css/app/elements.css +20 -0
- common/src/resources/css/app/elements.min.css +10 -10
- common/src/resources/css/bumpdown.css +69 -0
- common/src/resources/css/buttonset.css +39 -0
- common/src/resources/css/common-full.min.css +0 -1
- common/src/resources/css/common-skeleton.min.css +0 -1
- common/src/resources/css/common.css +2264 -0
- common/src/resources/css/common.min.css +1 -0
common/lang/readme.txt
DELETED
|
@@ -1,3 +0,0 @@
|
|
| 1 |
-
If you are interested in contributing to translations, you can get started at https://translations.theeventscalendar.com/projects/tribe-common/
|
| 2 |
-
|
| 3 |
-
On that site you can also find the .po translation files for doing local translations. We do not include these in the plugin itself to save space.
|
|
|
|
|
|
|
|
|
common/lang/tribe-common-af.mo
CHANGED
|
Binary file
|
common/lang/tribe-common-ar.mo
CHANGED
|
Binary file
|
common/lang/tribe-common-bg_BG.mo
CHANGED
|
Binary file
|
common/lang/tribe-common-ca.mo
CHANGED
|
Binary file
|
common/lang/tribe-common-cs_CZ.mo
CHANGED
|
Binary file
|
common/lang/tribe-common-da_DK.mo
CHANGED
|
Binary file
|
common/lang/tribe-common-de_DE.mo
CHANGED
|
Binary file
|
common/lang/tribe-common-el.mo
CHANGED
|
Binary file
|
common/lang/tribe-common-en_GB.mo
CHANGED
|
Binary file
|
common/lang/tribe-common-es_ES.mo
CHANGED
|
Binary file
|
common/lang/tribe-common-et.mo
CHANGED
|
Binary file
|
common/lang/tribe-common-fi.mo
CHANGED
|
Binary file
|
common/lang/tribe-common-fr_CA.mo
CHANGED
|
Binary file
|
common/lang/tribe-common-fr_FR.mo
CHANGED
|
Binary file
|
common/lang/tribe-common-hu_HU.mo
CHANGED
|
Binary file
|
common/lang/tribe-common-id_ID.mo
CHANGED
|
Binary file
|
common/lang/tribe-common-is_IS.mo
CHANGED
|
Binary file
|
common/lang/tribe-common-it_IT.mo
CHANGED
|
Binary file
|
common/lang/tribe-common-ja.mo
CHANGED
|
Binary file
|
common/lang/tribe-common-lt_LT.mo
CHANGED
|
Binary file
|
common/lang/tribe-common-lv.mo
CHANGED
|
Binary file
|
common/lang/tribe-common-nb_NO.mo
CHANGED
|
Binary file
|
common/lang/tribe-common-nl_NL.mo
CHANGED
|
Binary file
|
common/lang/tribe-common-pl_PL.mo
ADDED
|
Binary file
|
common/lang/tribe-common-pt_BR.mo
CHANGED
|
Binary file
|
common/lang/tribe-common-pt_PT.mo
CHANGED
|
Binary file
|
common/lang/tribe-common-ro_RO.mo
CHANGED
|
Binary file
|
common/lang/tribe-common-ru_RU.mo
CHANGED
|
Binary file
|
common/lang/tribe-common-sk_SK.mo
CHANGED
|
Binary file
|
common/lang/tribe-common-sl_SI.mo
CHANGED
|
Binary file
|
common/lang/tribe-common-sr_RS.mo
CHANGED
|
Binary file
|
common/lang/tribe-common-sv_SE.mo
CHANGED
|
Binary file
|
common/lang/tribe-common-tr_TR.mo
CHANGED
|
Binary file
|
common/lang/tribe-common-zh_CN.mo
CHANGED
|
Binary file
|
common/lang/tribe-common-zh_TW.mo
CHANGED
|
Binary file
|
common/lang/tribe-common.pot
CHANGED
|
@@ -1,14 +1,14 @@
|
|
| 1 |
-
# Copyright (C)
|
| 2 |
# This file is distributed under the same license as the Tribe Common package.
|
| 3 |
msgid ""
|
| 4 |
msgstr ""
|
| 5 |
-
"Project-Id-Version: Tribe Common 4.
|
| 6 |
"Report-Msgid-Bugs-To: http://m.tri.be/191x\n"
|
| 7 |
-
"POT-Creation-Date:
|
| 8 |
"MIME-Version: 1.0\n"
|
| 9 |
"Content-Type: text/plain; charset=UTF-8\n"
|
| 10 |
"Content-Transfer-Encoding: 8bit\n"
|
| 11 |
-
"PO-Revision-Date:
|
| 12 |
"Last-Translator: \n"
|
| 13 |
"Language-Team: \n"
|
| 14 |
|
|
@@ -40,7 +40,7 @@ msgstr ""
|
|
| 40 |
msgid "Press \"Cmd + C\" to copy"
|
| 41 |
msgstr ""
|
| 42 |
|
| 43 |
-
#: src/Tribe/Admin/Help_Page.php:79 src/Tribe/Customizer.php:
|
| 44 |
#: src/Tribe/Plugins_API.php:25
|
| 45 |
msgid "The Events Calendar"
|
| 46 |
msgstr ""
|
|
@@ -173,13 +173,13 @@ msgid "Visit the Add-on Page"
|
|
| 173 |
msgstr ""
|
| 174 |
|
| 175 |
#: src/Tribe/Admin/Notice/Php_Version.php:59
|
| 176 |
-
#: src/Tribe/Admin/Notice/Plugin_Download.php:
|
| 177 |
msgctxt "separator used in a list of items"
|
| 178 |
msgid ", "
|
| 179 |
msgstr ""
|
| 180 |
|
| 181 |
#: src/Tribe/Admin/Notice/Php_Version.php:60
|
| 182 |
-
#: src/Tribe/Admin/Notice/Plugin_Download.php:
|
| 183 |
msgctxt "the final separator in a list of two or more items"
|
| 184 |
msgid " and "
|
| 185 |
msgstr ""
|
|
@@ -198,16 +198,16 @@ msgid ""
|
|
| 198 |
"recommend using PHP 5.6 or above."
|
| 199 |
msgstr ""
|
| 200 |
|
| 201 |
-
#: src/Tribe/Admin/Notice/Plugin_Download.php:
|
| 202 |
-
msgid "
|
|
|
|
| 203 |
msgstr ""
|
| 204 |
|
| 205 |
-
#: src/Tribe/Admin/Notice/Plugin_Download.php:
|
| 206 |
-
|
| 207 |
-
msgid "Read more"
|
| 208 |
msgstr ""
|
| 209 |
|
| 210 |
-
#: src/Tribe/Admin/Notice/Plugin_Download.php:
|
| 211 |
msgid ""
|
| 212 |
"There’s a new version of %1$s available, but your license is expired. You’ll "
|
| 213 |
"need to renew your license to get access to the latest version. If you plan "
|
|
@@ -252,7 +252,7 @@ msgstr ""
|
|
| 252 |
msgid "Rate %1$sEvent Tickets%2$s %3$s"
|
| 253 |
msgstr ""
|
| 254 |
|
| 255 |
-
#: src/Tribe/Customizer.php:
|
| 256 |
msgid ""
|
| 257 |
"Use the following panel of your customizer to change the styling of your "
|
| 258 |
"Calendar and Event pages."
|
|
@@ -291,39 +291,6 @@ msgstr ""
|
|
| 291 |
msgid "State"
|
| 292 |
msgstr ""
|
| 293 |
|
| 294 |
-
#: src/Tribe/Debug_Bar/Panels/Json_Ld.php:21
|
| 295 |
-
#: src/Tribe/Debug_Bar/Panels/Json_Ld.php:40
|
| 296 |
-
msgid "Modern Tribe JSON-LD Data"
|
| 297 |
-
msgstr ""
|
| 298 |
-
|
| 299 |
-
#: src/Tribe/Dialog/View.php:153
|
| 300 |
-
msgid "Open the modal window"
|
| 301 |
-
msgstr ""
|
| 302 |
-
|
| 303 |
-
#: src/Tribe/Dialog/View.php:154
|
| 304 |
-
msgid "Close this modal window"
|
| 305 |
-
msgstr ""
|
| 306 |
-
|
| 307 |
-
#: src/Tribe/Dialog/View.php:222
|
| 308 |
-
msgid "Cancel"
|
| 309 |
-
msgstr ""
|
| 310 |
-
|
| 311 |
-
#: src/Tribe/Dialog/View.php:223
|
| 312 |
-
msgid "Confirm"
|
| 313 |
-
msgstr ""
|
| 314 |
-
|
| 315 |
-
#: src/Tribe/Dialog/View.php:288
|
| 316 |
-
msgid "OK"
|
| 317 |
-
msgstr ""
|
| 318 |
-
|
| 319 |
-
#: src/Tribe/Dialog/View.php:355
|
| 320 |
-
msgid "Open the dialog window"
|
| 321 |
-
msgstr ""
|
| 322 |
-
|
| 323 |
-
#: src/Tribe/Dialog/View.php:369
|
| 324 |
-
msgid "Close this dialog window"
|
| 325 |
-
msgstr ""
|
| 326 |
-
|
| 327 |
#: src/Tribe/Documentation/Swagger/Cost_Details_Definition_Provider.php:24
|
| 328 |
msgid "The cost currency symbol"
|
| 329 |
msgstr ""
|
|
@@ -441,24 +408,24 @@ msgid "Problem loading the block, please remove this block to restart."
|
|
| 441 |
msgstr ""
|
| 442 |
|
| 443 |
#. translators: %s: duration
|
| 444 |
-
#: src/Tribe/Editor/Configuration.php:
|
| 445 |
msgid "%s from now"
|
| 446 |
msgstr ""
|
| 447 |
|
| 448 |
#. translators: %s: duration
|
| 449 |
-
#: src/Tribe/Editor/Configuration.php:
|
| 450 |
msgid "%s ago"
|
| 451 |
msgstr ""
|
| 452 |
|
| 453 |
-
#: src/Tribe/Editor/Configuration.php:
|
| 454 |
msgid "g:i a"
|
| 455 |
msgstr ""
|
| 456 |
|
| 457 |
-
#: src/Tribe/Editor/Configuration.php:
|
| 458 |
msgid "F j, Y"
|
| 459 |
msgstr ""
|
| 460 |
|
| 461 |
-
#: src/Tribe/Editor/Configuration.php:
|
| 462 |
msgid "F j"
|
| 463 |
msgstr ""
|
| 464 |
|
|
@@ -478,7 +445,7 @@ msgstr ""
|
|
| 478 |
msgid "Tutorial"
|
| 479 |
msgstr ""
|
| 480 |
|
| 481 |
-
#: src/Tribe/Extension.php:
|
| 482 |
msgid ""
|
| 483 |
"Unable to run Tribe Extensions. Your website host is running PHP 5.2 or "
|
| 484 |
"older, and has likely disabled or misconfigured debug_backtrace(). You, or "
|
|
@@ -486,28 +453,19 @@ msgid ""
|
|
| 486 |
"debug_backtrace() for Tribe Extensions to work."
|
| 487 |
msgstr ""
|
| 488 |
|
| 489 |
-
#: src/Tribe/
|
| 490 |
-
msgctxt "extension disallowed"
|
| 491 |
-
msgid ""
|
| 492 |
-
"This extension has been programmatically disallowed. The most common reason "
|
| 493 |
-
"is due to another Modern Tribe plugin having absorbed or replaced this "
|
| 494 |
-
"extension's functionality. This extension plugin has been deactivated, and "
|
| 495 |
-
"you should likely delete it."
|
| 496 |
-
msgstr ""
|
| 497 |
-
|
| 498 |
-
#: src/Tribe/Field.php:233
|
| 499 |
msgid "Invalid field type specified"
|
| 500 |
msgstr ""
|
| 501 |
|
| 502 |
-
#: src/Tribe/Field.php:
|
| 503 |
msgid "No radio options specified"
|
| 504 |
msgstr ""
|
| 505 |
|
| 506 |
-
#: src/Tribe/Field.php:
|
| 507 |
msgid "No checkbox options specified"
|
| 508 |
msgstr ""
|
| 509 |
|
| 510 |
-
#: src/Tribe/Field.php:
|
| 511 |
msgid "No select options specified"
|
| 512 |
msgstr ""
|
| 513 |
|
|
@@ -843,8 +801,7 @@ msgstr ""
|
|
| 843 |
msgid "Gambia"
|
| 844 |
msgstr ""
|
| 845 |
|
| 846 |
-
#: src/Tribe/Languages/Locations.php:138
|
| 847 |
-
msgctxt "The country"
|
| 848 |
msgid "Georgia"
|
| 849 |
msgstr ""
|
| 850 |
|
|
@@ -1033,135 +990,135 @@ msgid "Macau"
|
|
| 1033 |
msgstr ""
|
| 1034 |
|
| 1035 |
#: src/Tribe/Languages/Locations.php:185
|
| 1036 |
-
msgid "
|
| 1037 |
msgstr ""
|
| 1038 |
|
| 1039 |
#: src/Tribe/Languages/Locations.php:186
|
| 1040 |
-
msgid "
|
| 1041 |
msgstr ""
|
| 1042 |
|
| 1043 |
#: src/Tribe/Languages/Locations.php:187
|
| 1044 |
-
msgid "
|
| 1045 |
msgstr ""
|
| 1046 |
|
| 1047 |
#: src/Tribe/Languages/Locations.php:188
|
| 1048 |
-
msgid "
|
| 1049 |
msgstr ""
|
| 1050 |
|
| 1051 |
#: src/Tribe/Languages/Locations.php:189
|
| 1052 |
-
msgid "
|
| 1053 |
msgstr ""
|
| 1054 |
|
| 1055 |
#: src/Tribe/Languages/Locations.php:190
|
| 1056 |
-
msgid "
|
| 1057 |
msgstr ""
|
| 1058 |
|
| 1059 |
#: src/Tribe/Languages/Locations.php:191
|
| 1060 |
-
msgid "
|
| 1061 |
msgstr ""
|
| 1062 |
|
| 1063 |
#: src/Tribe/Languages/Locations.php:192
|
| 1064 |
-
msgid "
|
| 1065 |
msgstr ""
|
| 1066 |
|
| 1067 |
#: src/Tribe/Languages/Locations.php:193
|
| 1068 |
-
msgid "
|
| 1069 |
msgstr ""
|
| 1070 |
|
| 1071 |
#: src/Tribe/Languages/Locations.php:194
|
| 1072 |
-
msgid "
|
| 1073 |
msgstr ""
|
| 1074 |
|
| 1075 |
#: src/Tribe/Languages/Locations.php:195
|
| 1076 |
-
msgid "
|
| 1077 |
msgstr ""
|
| 1078 |
|
| 1079 |
#: src/Tribe/Languages/Locations.php:196
|
| 1080 |
-
msgid "
|
| 1081 |
msgstr ""
|
| 1082 |
|
| 1083 |
#: src/Tribe/Languages/Locations.php:197
|
| 1084 |
-
msgid "
|
| 1085 |
msgstr ""
|
| 1086 |
|
| 1087 |
#: src/Tribe/Languages/Locations.php:198
|
| 1088 |
-
msgid "
|
| 1089 |
msgstr ""
|
| 1090 |
|
| 1091 |
#: src/Tribe/Languages/Locations.php:199
|
| 1092 |
-
msgid "
|
| 1093 |
msgstr ""
|
| 1094 |
|
| 1095 |
#: src/Tribe/Languages/Locations.php:200
|
| 1096 |
-
msgid "
|
| 1097 |
msgstr ""
|
| 1098 |
|
| 1099 |
#: src/Tribe/Languages/Locations.php:201
|
| 1100 |
-
msgid "
|
| 1101 |
msgstr ""
|
| 1102 |
|
| 1103 |
#: src/Tribe/Languages/Locations.php:202
|
| 1104 |
-
msgid "
|
| 1105 |
msgstr ""
|
| 1106 |
|
| 1107 |
#: src/Tribe/Languages/Locations.php:203
|
| 1108 |
-
msgid "
|
| 1109 |
msgstr ""
|
| 1110 |
|
| 1111 |
#: src/Tribe/Languages/Locations.php:204
|
| 1112 |
-
msgid "
|
| 1113 |
msgstr ""
|
| 1114 |
|
| 1115 |
#: src/Tribe/Languages/Locations.php:205
|
| 1116 |
-
msgid "
|
| 1117 |
msgstr ""
|
| 1118 |
|
| 1119 |
#: src/Tribe/Languages/Locations.php:206
|
| 1120 |
-
msgid "
|
| 1121 |
msgstr ""
|
| 1122 |
|
| 1123 |
#: src/Tribe/Languages/Locations.php:207
|
| 1124 |
-
msgid "
|
| 1125 |
msgstr ""
|
| 1126 |
|
| 1127 |
#: src/Tribe/Languages/Locations.php:208
|
| 1128 |
-
msgid "
|
| 1129 |
msgstr ""
|
| 1130 |
|
| 1131 |
#: src/Tribe/Languages/Locations.php:209
|
| 1132 |
-
msgid "
|
| 1133 |
msgstr ""
|
| 1134 |
|
| 1135 |
#: src/Tribe/Languages/Locations.php:210
|
| 1136 |
-
msgid "
|
| 1137 |
msgstr ""
|
| 1138 |
|
| 1139 |
#: src/Tribe/Languages/Locations.php:211
|
| 1140 |
-
msgid "New
|
| 1141 |
msgstr ""
|
| 1142 |
|
| 1143 |
#: src/Tribe/Languages/Locations.php:212
|
| 1144 |
-
msgid "
|
| 1145 |
msgstr ""
|
| 1146 |
|
| 1147 |
#: src/Tribe/Languages/Locations.php:213
|
| 1148 |
-
msgid "
|
| 1149 |
msgstr ""
|
| 1150 |
|
| 1151 |
#: src/Tribe/Languages/Locations.php:214
|
| 1152 |
-
msgid "
|
| 1153 |
msgstr ""
|
| 1154 |
|
| 1155 |
#: src/Tribe/Languages/Locations.php:215
|
| 1156 |
-
msgid "
|
| 1157 |
msgstr ""
|
| 1158 |
|
| 1159 |
#: src/Tribe/Languages/Locations.php:216
|
| 1160 |
-
msgid "
|
| 1161 |
msgstr ""
|
| 1162 |
|
| 1163 |
#: src/Tribe/Languages/Locations.php:217
|
| 1164 |
-
msgid "
|
| 1165 |
msgstr ""
|
| 1166 |
|
| 1167 |
#: src/Tribe/Languages/Locations.php:218
|
|
@@ -1524,11 +1481,6 @@ msgstr ""
|
|
| 1524 |
msgid "Florida"
|
| 1525 |
msgstr ""
|
| 1526 |
|
| 1527 |
-
#: src/Tribe/Languages/Locations.php:334
|
| 1528 |
-
msgctxt "The US state Georgia"
|
| 1529 |
-
msgid "Georgia"
|
| 1530 |
-
msgstr ""
|
| 1531 |
-
|
| 1532 |
#: src/Tribe/Languages/Locations.php:335
|
| 1533 |
msgid "Hawaii"
|
| 1534 |
msgstr ""
|
|
@@ -1689,10 +1641,6 @@ msgstr ""
|
|
| 1689 |
msgid "Wyoming"
|
| 1690 |
msgstr ""
|
| 1691 |
|
| 1692 |
-
#: src/Tribe/Log/Action_Logger.php:39
|
| 1693 |
-
msgid "Action-based Logger"
|
| 1694 |
-
msgstr ""
|
| 1695 |
-
|
| 1696 |
#: src/Tribe/Log/Admin.php:133
|
| 1697 |
msgctxt "log selector"
|
| 1698 |
msgid "None currently available"
|
|
@@ -1711,107 +1659,107 @@ msgstr ""
|
|
| 1711 |
msgid "Null logger (will log nothing)"
|
| 1712 |
msgstr ""
|
| 1713 |
|
| 1714 |
-
#: src/Tribe/Log.php:
|
| 1715 |
msgid "Cannot set %s as the current logging engine"
|
| 1716 |
msgstr ""
|
| 1717 |
|
| 1718 |
-
#: src/Tribe/Log.php:
|
| 1719 |
msgid "Disabled"
|
| 1720 |
msgstr ""
|
| 1721 |
|
| 1722 |
-
#: src/Tribe/Log.php:
|
| 1723 |
msgid "Only errors"
|
| 1724 |
msgstr ""
|
| 1725 |
|
| 1726 |
-
#: src/Tribe/Log.php:
|
| 1727 |
msgid "Warnings and errors"
|
| 1728 |
msgstr ""
|
| 1729 |
|
| 1730 |
-
#: src/Tribe/Log.php:
|
| 1731 |
msgid "Full debug (all events)"
|
| 1732 |
msgstr ""
|
| 1733 |
|
| 1734 |
-
#: src/Tribe/Main.php:
|
| 1735 |
msgid ": activate to sort column ascending"
|
| 1736 |
msgstr ""
|
| 1737 |
|
| 1738 |
-
#: src/Tribe/Main.php:
|
| 1739 |
msgid ": activate to sort column descending"
|
| 1740 |
msgstr ""
|
| 1741 |
|
| 1742 |
-
#: src/Tribe/Main.php:
|
| 1743 |
msgid "Show _MENU_ entries"
|
| 1744 |
msgstr ""
|
| 1745 |
|
| 1746 |
-
#: src/Tribe/Main.php:
|
| 1747 |
msgid "No data available in table"
|
| 1748 |
msgstr ""
|
| 1749 |
|
| 1750 |
-
#: src/Tribe/Main.php:
|
| 1751 |
msgid "Showing _START_ to _END_ of _TOTAL_ entries"
|
| 1752 |
msgstr ""
|
| 1753 |
|
| 1754 |
-
#: src/Tribe/Main.php:
|
| 1755 |
msgid "Showing 0 to 0 of 0 entries"
|
| 1756 |
msgstr ""
|
| 1757 |
|
| 1758 |
-
#: src/Tribe/Main.php:
|
| 1759 |
msgid "(filtered from _MAX_ total entries)"
|
| 1760 |
msgstr ""
|
| 1761 |
|
| 1762 |
-
#: src/Tribe/Main.php:
|
| 1763 |
msgid "No matching records found"
|
| 1764 |
msgstr ""
|
| 1765 |
|
| 1766 |
-
#: src/Tribe/Main.php:
|
| 1767 |
msgid "Search:"
|
| 1768 |
msgstr ""
|
| 1769 |
|
| 1770 |
-
#: src/Tribe/Main.php:
|
| 1771 |
msgid "All items on this page were selected. "
|
| 1772 |
msgstr ""
|
| 1773 |
|
| 1774 |
-
#: src/Tribe/Main.php:
|
| 1775 |
msgid "Select all pages"
|
| 1776 |
msgstr ""
|
| 1777 |
|
| 1778 |
-
#: src/Tribe/Main.php:
|
| 1779 |
msgid "Clear Selection."
|
| 1780 |
msgstr ""
|
| 1781 |
|
| 1782 |
-
#: src/Tribe/Main.php:
|
| 1783 |
msgid "All"
|
| 1784 |
msgstr ""
|
| 1785 |
|
| 1786 |
-
#: src/Tribe/Main.php:
|
| 1787 |
msgid "Next"
|
| 1788 |
msgstr ""
|
| 1789 |
|
| 1790 |
-
#: src/Tribe/Main.php:
|
| 1791 |
msgid "Previous"
|
| 1792 |
msgstr ""
|
| 1793 |
|
| 1794 |
-
#: src/Tribe/Main.php:
|
| 1795 |
msgid ": Selected %d rows"
|
| 1796 |
msgstr ""
|
| 1797 |
|
| 1798 |
-
#: src/Tribe/Main.php:
|
| 1799 |
msgid ": Selected 1 row"
|
| 1800 |
msgstr ""
|
| 1801 |
|
| 1802 |
-
#: src/Tribe/Main.php:
|
| 1803 |
msgid "Prev"
|
| 1804 |
msgstr ""
|
| 1805 |
|
| 1806 |
-
#: src/Tribe/Main.php:
|
| 1807 |
msgid "Today"
|
| 1808 |
msgstr ""
|
| 1809 |
|
| 1810 |
-
#: src/Tribe/Main.php:
|
| 1811 |
msgid "Done"
|
| 1812 |
msgstr ""
|
| 1813 |
|
| 1814 |
-
#: src/Tribe/Main.php:
|
| 1815 |
msgid "Clear"
|
| 1816 |
msgstr ""
|
| 1817 |
|
|
@@ -1850,68 +1798,68 @@ msgstr ""
|
|
| 1850 |
msgid "License key(s) updated."
|
| 1851 |
msgstr ""
|
| 1852 |
|
| 1853 |
-
#: src/Tribe/PUE/Checker.php:
|
| 1854 |
msgid ""
|
| 1855 |
"Hmmm... something's wrong with this validator. Please contact %ssupport%s."
|
| 1856 |
msgstr ""
|
| 1857 |
|
| 1858 |
-
#: src/Tribe/PUE/Checker.php:
|
| 1859 |
msgid "unknown date"
|
| 1860 |
msgstr ""
|
| 1861 |
|
| 1862 |
-
#: src/Tribe/PUE/Checker.php:
|
| 1863 |
msgid "Sorry, key validation server is not available."
|
| 1864 |
msgstr ""
|
| 1865 |
|
| 1866 |
-
#: src/Tribe/PUE/Checker.php:
|
| 1867 |
msgid "Valid Key! Expires on %s"
|
| 1868 |
msgstr ""
|
| 1869 |
|
| 1870 |
-
#: src/Tribe/PUE/Checker.php:
|
| 1871 |
msgid "Thanks for setting up a valid key. It will expire on %s"
|
| 1872 |
msgstr ""
|
| 1873 |
|
| 1874 |
-
#: src/Tribe/PUE/Checker.php:
|
| 1875 |
msgid "Renew Your License Now"
|
| 1876 |
msgstr ""
|
| 1877 |
|
| 1878 |
-
#: src/Tribe/PUE/Checker.php:
|
| 1879 |
msgid " (opens in a new window)"
|
| 1880 |
msgstr ""
|
| 1881 |
|
| 1882 |
-
#: src/Tribe/PUE/Checker.php:
|
| 1883 |
msgid "Please refresh the page and try your request again."
|
| 1884 |
msgstr ""
|
| 1885 |
|
| 1886 |
-
#: src/Tribe/PUE/Checker.php:
|
| 1887 |
msgid ""
|
| 1888 |
"There is an update for %s. You'll need to %scheck your license%s to have "
|
| 1889 |
"access to updates, downloads, and support."
|
| 1890 |
msgstr ""
|
| 1891 |
|
| 1892 |
-
#: src/Tribe/PUE/Checker.php:
|
| 1893 |
msgid ""
|
| 1894 |
"There is an update for %s. %sRenew your license%s to get access to bug "
|
| 1895 |
"fixes, security updates, and new features."
|
| 1896 |
msgstr ""
|
| 1897 |
|
| 1898 |
-
#: src/Tribe/PUE/Checker.php:
|
| 1899 |
msgid "Update now to version %s."
|
| 1900 |
msgstr ""
|
| 1901 |
|
| 1902 |
-
#: src/Tribe/PUE/Checker.php:
|
| 1903 |
msgid "There is a new version of %1$s available. %2$s"
|
| 1904 |
msgstr ""
|
| 1905 |
|
| 1906 |
-
#: src/Tribe/PUE/Checker.php:
|
| 1907 |
msgid "A valid license has been entered by your network administrator."
|
| 1908 |
msgstr ""
|
| 1909 |
|
| 1910 |
-
#: src/Tribe/PUE/Checker.php:
|
| 1911 |
msgid "No license entered. Consult your network administrator."
|
| 1912 |
msgstr ""
|
| 1913 |
|
| 1914 |
-
#: src/Tribe/PUE/Checker.php:
|
| 1915 |
msgid "Expired license. Consult your network administrator."
|
| 1916 |
msgstr ""
|
| 1917 |
|
|
@@ -1958,6 +1906,10 @@ msgctxt "formatted plugin list"
|
|
| 1958 |
msgid "%1$s and %2$s"
|
| 1959 |
msgstr ""
|
| 1960 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1961 |
#: src/Tribe/PUE/Update_Prevention.php:184
|
| 1962 |
msgid ""
|
| 1963 |
"Your update failed due to an incompatibility between the version (%1$s) of "
|
|
@@ -1965,12 +1917,6 @@ msgid ""
|
|
| 1965 |
"%4$s"
|
| 1966 |
msgstr ""
|
| 1967 |
|
| 1968 |
-
#: src/Tribe/Plugins.php:147
|
| 1969 |
-
msgid ""
|
| 1970 |
-
"Using this function before \"plugins_loaded\" action has fired can return "
|
| 1971 |
-
"unreliable results."
|
| 1972 |
-
msgstr ""
|
| 1973 |
-
|
| 1974 |
#: src/Tribe/Plugins_API.php:28
|
| 1975 |
msgid ""
|
| 1976 |
"Create an events calendar and manage it with ease. The Events Calendar "
|
|
@@ -2102,39 +2048,39 @@ msgstr ""
|
|
| 2102 |
msgid "Events Help"
|
| 2103 |
msgstr ""
|
| 2104 |
|
| 2105 |
-
#: src/Tribe/Settings.php:
|
| 2106 |
msgid "%s Settings"
|
| 2107 |
msgstr ""
|
| 2108 |
|
| 2109 |
-
#: src/Tribe/Settings.php:
|
| 2110 |
msgid "You've requested a non-existent tab."
|
| 2111 |
msgstr ""
|
| 2112 |
|
| 2113 |
-
#: src/Tribe/Settings.php:
|
| 2114 |
msgid "Save Changes"
|
| 2115 |
msgstr ""
|
| 2116 |
|
| 2117 |
-
#: src/Tribe/Settings.php:
|
| 2118 |
msgid "You don't have permission to do that."
|
| 2119 |
msgstr ""
|
| 2120 |
|
| 2121 |
-
#: src/Tribe/Settings.php:
|
| 2122 |
msgid "The request was sent insecurely."
|
| 2123 |
msgstr ""
|
| 2124 |
|
| 2125 |
-
#: src/Tribe/Settings.php:
|
| 2126 |
msgid "The request wasn't sent from this tab."
|
| 2127 |
msgstr ""
|
| 2128 |
|
| 2129 |
-
#: src/Tribe/Settings.php:
|
| 2130 |
msgid "Your form had the following errors:"
|
| 2131 |
msgstr ""
|
| 2132 |
|
| 2133 |
-
#: src/Tribe/Settings.php:
|
| 2134 |
msgid "None of your settings were saved. Please try again."
|
| 2135 |
msgstr ""
|
| 2136 |
|
| 2137 |
-
#: src/Tribe/Settings.php:
|
| 2138 |
msgid ""
|
| 2139 |
"The above setting was not saved. Other settings were successfully saved."
|
| 2140 |
msgid_plural ""
|
|
@@ -2142,28 +2088,28 @@ msgid_plural ""
|
|
| 2142 |
msgstr[0] ""
|
| 2143 |
msgstr[1] ""
|
| 2144 |
|
| 2145 |
-
#: src/Tribe/Settings.php:
|
| 2146 |
msgid "Settings saved."
|
| 2147 |
msgstr ""
|
| 2148 |
|
| 2149 |
-
#: src/Tribe/Settings_Manager.php:
|
| 2150 |
msgid "General"
|
| 2151 |
msgstr ""
|
| 2152 |
|
| 2153 |
-
#: src/Tribe/Settings_Manager.php:
|
| 2154 |
msgid "Display"
|
| 2155 |
msgstr ""
|
| 2156 |
|
| 2157 |
-
#: src/Tribe/Settings_Manager.php:
|
| 2158 |
msgid "Network"
|
| 2159 |
msgstr ""
|
| 2160 |
|
| 2161 |
-
#: src/Tribe/Settings_Manager.php:
|
| 2162 |
#: src/admin-views/tribe-options-licenses.php:57
|
| 2163 |
msgid "Licenses"
|
| 2164 |
msgstr ""
|
| 2165 |
|
| 2166 |
-
#: src/Tribe/Settings_Manager.php:
|
| 2167 |
msgid "Help"
|
| 2168 |
msgstr ""
|
| 2169 |
|
|
@@ -2201,42 +2147,42 @@ msgid ""
|
|
| 2201 |
"overrides is provided below."
|
| 2202 |
msgstr ""
|
| 2203 |
|
| 2204 |
-
#: src/Tribe/Support.php:
|
| 2205 |
msgid "English"
|
| 2206 |
msgstr ""
|
| 2207 |
|
| 2208 |
-
#: src/Tribe/Support.php:
|
| 2209 |
msgid "Unknown or not set"
|
| 2210 |
msgstr ""
|
| 2211 |
|
| 2212 |
-
#: src/Tribe/Support.php:
|
| 2213 |
msgid ""
|
| 2214 |
"Rewrite rules were purged on load of this help page. Chances are there is a "
|
| 2215 |
"rewrite rule flush occurring in a plugin or theme!"
|
| 2216 |
msgstr ""
|
| 2217 |
|
| 2218 |
-
#: src/Tribe/Support.php:
|
| 2219 |
msgid ""
|
| 2220 |
"Yes, automatically share my system information with the Modern Tribe support "
|
| 2221 |
"team"
|
| 2222 |
msgstr ""
|
| 2223 |
|
| 2224 |
-
#: src/Tribe/Support.php:
|
| 2225 |
msgid ""
|
| 2226 |
"Your system information will only be used by the Modern Tribe support team. "
|
| 2227 |
"All information is stored securely. We do not share this information with "
|
| 2228 |
"any third parties."
|
| 2229 |
msgstr ""
|
| 2230 |
|
| 2231 |
-
#: src/Tribe/Support.php:
|
| 2232 |
msgid "Invalid Key"
|
| 2233 |
msgstr ""
|
| 2234 |
|
| 2235 |
-
#: src/Tribe/Support.php:
|
| 2236 |
msgid "Permission Error"
|
| 2237 |
msgstr ""
|
| 2238 |
|
| 2239 |
-
#: src/Tribe/Support.php:
|
| 2240 |
msgid "Unique System Info Key Generated"
|
| 2241 |
msgstr ""
|
| 2242 |
|
|
@@ -2258,97 +2204,97 @@ msgctxt "non-existant function name passed for field validation"
|
|
| 2258 |
msgid "with function name:"
|
| 2259 |
msgstr ""
|
| 2260 |
|
| 2261 |
-
#: src/Tribe/Validate.php:
|
| 2262 |
msgid "%s must contain numbers and letters only"
|
| 2263 |
msgstr ""
|
| 2264 |
|
| 2265 |
-
#: src/Tribe/Validate.php:
|
| 2266 |
msgid "%s must contain numbers, letters and dots only"
|
| 2267 |
msgstr ""
|
| 2268 |
|
| 2269 |
-
#: src/Tribe/Validate.php:
|
| 2270 |
msgid "%s must contain numbers, letters, dashes and undescores only"
|
| 2271 |
msgstr ""
|
| 2272 |
|
| 2273 |
-
#: src/Tribe/Validate.php:
|
| 2274 |
msgid "%s must not be empty"
|
| 2275 |
msgstr ""
|
| 2276 |
|
| 2277 |
-
#: src/Tribe/Validate.php:
|
| 2278 |
msgid "%s must be a positive number."
|
| 2279 |
msgstr ""
|
| 2280 |
|
| 2281 |
-
#: src/Tribe/Validate.php:
|
| 2282 |
msgid "%s must be a positive number or percent."
|
| 2283 |
msgstr ""
|
| 2284 |
|
| 2285 |
-
#: src/Tribe/Validate.php:
|
| 2286 |
msgid "%s must be a whole number."
|
| 2287 |
msgstr ""
|
| 2288 |
|
| 2289 |
-
#: src/Tribe/Validate.php:
|
| 2290 |
msgid "%s must be a valid slug (numbers, letters, dashes, and underscores)."
|
| 2291 |
msgstr ""
|
| 2292 |
|
| 2293 |
-
#: src/Tribe/Validate.php:
|
| 2294 |
-
msgid "%s must be a valid URL."
|
| 2295 |
msgstr ""
|
| 2296 |
|
| 2297 |
-
#: src/Tribe/Validate.php:
|
| 2298 |
-
#: src/Tribe/Validate.php:
|
| 2299 |
msgid "%s must have a value that's part of its options."
|
| 2300 |
msgstr ""
|
| 2301 |
|
| 2302 |
-
#: src/Tribe/Validate.php:
|
| 2303 |
msgid ""
|
| 2304 |
"Comparison validation failed because no comparison value was provided, for "
|
| 2305 |
"field %s"
|
| 2306 |
msgstr ""
|
| 2307 |
|
| 2308 |
-
#: src/Tribe/Validate.php:
|
| 2309 |
msgid "%s cannot be the same as %s."
|
| 2310 |
msgstr ""
|
| 2311 |
|
| 2312 |
-
#: src/Tribe/Validate.php:
|
| 2313 |
msgid "%s cannot be a duplicate"
|
| 2314 |
msgstr ""
|
| 2315 |
|
| 2316 |
-
#: src/Tribe/Validate.php:
|
| 2317 |
msgid "%s must be a number or percentage."
|
| 2318 |
msgstr ""
|
| 2319 |
|
| 2320 |
-
#: src/Tribe/Validate.php:
|
| 2321 |
msgid "%s must be a number between 0 and 21."
|
| 2322 |
msgstr ""
|
| 2323 |
|
| 2324 |
-
#: src/Tribe/Validate.php:
|
| 2325 |
msgid ""
|
| 2326 |
"%s must consist of letters, numbers, dashes, apostrophes, and spaces only."
|
| 2327 |
msgstr ""
|
| 2328 |
|
| 2329 |
-
#: src/Tribe/Validate.php:
|
| 2330 |
msgid "%s must consist of letters, spaces, apostrophes, and dashes."
|
| 2331 |
msgstr ""
|
| 2332 |
|
| 2333 |
-
#: src/Tribe/Validate.php:
|
| 2334 |
msgid "%s must consist of 5 numbers."
|
| 2335 |
msgstr ""
|
| 2336 |
|
| 2337 |
-
#: src/Tribe/Validate.php:
|
| 2338 |
msgid "%s must be a phone number."
|
| 2339 |
msgstr ""
|
| 2340 |
|
| 2341 |
-
#: src/Tribe/Validate.php:
|
| 2342 |
msgid ""
|
| 2343 |
"Country List must be formatted as one country per line in the following "
|
| 2344 |
"format: <br>US, United States <br> UK, United Kingdom."
|
| 2345 |
msgstr ""
|
| 2346 |
|
| 2347 |
-
#: src/Tribe/Validate.php:
|
| 2348 |
msgid "%s must be an email address."
|
| 2349 |
msgstr ""
|
| 2350 |
|
| 2351 |
-
#: src/Tribe/View_Helpers.php:
|
| 2352 |
msgid "Select a Country:"
|
| 2353 |
msgstr ""
|
| 2354 |
|
|
@@ -2404,13 +2350,11 @@ msgid ""
|
|
| 2404 |
msgstr ""
|
| 2405 |
|
| 2406 |
#: src/admin-views/tribe-options-display.php:36
|
| 2407 |
-
msgid "
|
| 2408 |
msgstr ""
|
| 2409 |
|
| 2410 |
#: src/admin-views/tribe-options-display.php:37
|
| 2411 |
-
msgid ""
|
| 2412 |
-
"Select the date format used for elements with minimal space, such as in "
|
| 2413 |
-
"datepickers."
|
| 2414 |
msgstr ""
|
| 2415 |
|
| 2416 |
#: src/admin-views/tribe-options-general.php:10
|
|
@@ -2462,7 +2406,7 @@ msgstr ""
|
|
| 2462 |
msgid "Debug mode"
|
| 2463 |
msgstr ""
|
| 2464 |
|
| 2465 |
-
#: src/admin-views/tribe-options-general.php:
|
| 2466 |
msgid ""
|
| 2467 |
"Enable this option to log debug information. By default this will log to "
|
| 2468 |
"your server PHP error log. If you'd like to see the log messages in your "
|
|
@@ -2651,11 +2595,6 @@ msgstr ""
|
|
| 2651 |
msgid "Hide the following settings tabs on every site:"
|
| 2652 |
msgstr ""
|
| 2653 |
|
| 2654 |
-
#: src/functions/template-tags/html.php:70
|
| 2655 |
-
msgctxt "The associated field is required."
|
| 2656 |
-
msgid "(required)"
|
| 2657 |
-
msgstr ""
|
| 2658 |
-
|
| 2659 |
#: src/views/promoter/auth.php:35
|
| 2660 |
msgid "Promoter would like to sync with your site"
|
| 2661 |
msgstr ""
|
| 1 |
+
# Copyright (C) 2019 Modern Tribe
|
| 2 |
# This file is distributed under the same license as the Tribe Common package.
|
| 3 |
msgid ""
|
| 4 |
msgstr ""
|
| 5 |
+
"Project-Id-Version: Tribe Common 4.9.15\n"
|
| 6 |
"Report-Msgid-Bugs-To: http://m.tri.be/191x\n"
|
| 7 |
+
"POT-Creation-Date: 2019-08-20 03:22:07+00:00\n"
|
| 8 |
"MIME-Version: 1.0\n"
|
| 9 |
"Content-Type: text/plain; charset=UTF-8\n"
|
| 10 |
"Content-Transfer-Encoding: 8bit\n"
|
| 11 |
+
"PO-Revision-Date: 2019-08-20 03:22\n"
|
| 12 |
"Last-Translator: \n"
|
| 13 |
"Language-Team: \n"
|
| 14 |
|
| 40 |
msgid "Press \"Cmd + C\" to copy"
|
| 41 |
msgstr ""
|
| 42 |
|
| 43 |
+
#: src/Tribe/Admin/Help_Page.php:79 src/Tribe/Customizer.php:642
|
| 44 |
#: src/Tribe/Plugins_API.php:25
|
| 45 |
msgid "The Events Calendar"
|
| 46 |
msgstr ""
|
| 173 |
msgstr ""
|
| 174 |
|
| 175 |
#: src/Tribe/Admin/Notice/Php_Version.php:59
|
| 176 |
+
#: src/Tribe/Admin/Notice/Plugin_Download.php:137
|
| 177 |
msgctxt "separator used in a list of items"
|
| 178 |
msgid ", "
|
| 179 |
msgstr ""
|
| 180 |
|
| 181 |
#: src/Tribe/Admin/Notice/Php_Version.php:60
|
| 182 |
+
#: src/Tribe/Admin/Notice/Plugin_Download.php:138
|
| 183 |
msgctxt "the final separator in a list of two or more items"
|
| 184 |
msgid " and "
|
| 185 |
msgstr ""
|
| 198 |
"recommend using PHP 5.6 or above."
|
| 199 |
msgstr ""
|
| 200 |
|
| 201 |
+
#: src/Tribe/Admin/Notice/Plugin_Download.php:112
|
| 202 |
+
msgid ""
|
| 203 |
+
"To begin using %2$s, please install and activate the latest version of %3$s."
|
| 204 |
msgstr ""
|
| 205 |
|
| 206 |
+
#: src/Tribe/Admin/Notice/Plugin_Download.php:114
|
| 207 |
+
msgid "Read more."
|
|
|
|
| 208 |
msgstr ""
|
| 209 |
|
| 210 |
+
#: src/Tribe/Admin/Notice/Plugin_Download.php:115
|
| 211 |
msgid ""
|
| 212 |
"There’s a new version of %1$s available, but your license is expired. You’ll "
|
| 213 |
"need to renew your license to get access to the latest version. If you plan "
|
| 252 |
msgid "Rate %1$sEvent Tickets%2$s %3$s"
|
| 253 |
msgstr ""
|
| 254 |
|
| 255 |
+
#: src/Tribe/Customizer.php:643
|
| 256 |
msgid ""
|
| 257 |
"Use the following panel of your customizer to change the styling of your "
|
| 258 |
"Calendar and Event pages."
|
| 291 |
msgid "State"
|
| 292 |
msgstr ""
|
| 293 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 294 |
#: src/Tribe/Documentation/Swagger/Cost_Details_Definition_Provider.php:24
|
| 295 |
msgid "The cost currency symbol"
|
| 296 |
msgstr ""
|
| 408 |
msgstr ""
|
| 409 |
|
| 410 |
#. translators: %s: duration
|
| 411 |
+
#: src/Tribe/Editor/Configuration.php:88
|
| 412 |
msgid "%s from now"
|
| 413 |
msgstr ""
|
| 414 |
|
| 415 |
#. translators: %s: duration
|
| 416 |
+
#: src/Tribe/Editor/Configuration.php:90
|
| 417 |
msgid "%s ago"
|
| 418 |
msgstr ""
|
| 419 |
|
| 420 |
+
#: src/Tribe/Editor/Configuration.php:94 src/Tribe/Editor/Configuration.php:97
|
| 421 |
msgid "g:i a"
|
| 422 |
msgstr ""
|
| 423 |
|
| 424 |
+
#: src/Tribe/Editor/Configuration.php:95 src/Tribe/Editor/Configuration.php:97
|
| 425 |
msgid "F j, Y"
|
| 426 |
msgstr ""
|
| 427 |
|
| 428 |
+
#: src/Tribe/Editor/Configuration.php:96
|
| 429 |
msgid "F j"
|
| 430 |
msgstr ""
|
| 431 |
|
| 445 |
msgid "Tutorial"
|
| 446 |
msgstr ""
|
| 447 |
|
| 448 |
+
#: src/Tribe/Extension.php:377
|
| 449 |
msgid ""
|
| 450 |
"Unable to run Tribe Extensions. Your website host is running PHP 5.2 or "
|
| 451 |
"older, and has likely disabled or misconfigured debug_backtrace(). You, or "
|
| 453 |
"debug_backtrace() for Tribe Extensions to work."
|
| 454 |
msgstr ""
|
| 455 |
|
| 456 |
+
#: src/Tribe/Field.php:231
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 457 |
msgid "Invalid field type specified"
|
| 458 |
msgstr ""
|
| 459 |
|
| 460 |
+
#: src/Tribe/Field.php:539
|
| 461 |
msgid "No radio options specified"
|
| 462 |
msgstr ""
|
| 463 |
|
| 464 |
+
#: src/Tribe/Field.php:575
|
| 465 |
msgid "No checkbox options specified"
|
| 466 |
msgstr ""
|
| 467 |
|
| 468 |
+
#: src/Tribe/Field.php:633
|
| 469 |
msgid "No select options specified"
|
| 470 |
msgstr ""
|
| 471 |
|
| 801 |
msgid "Gambia"
|
| 802 |
msgstr ""
|
| 803 |
|
| 804 |
+
#: src/Tribe/Languages/Locations.php:138 src/Tribe/Languages/Locations.php:334
|
|
|
|
| 805 |
msgid "Georgia"
|
| 806 |
msgstr ""
|
| 807 |
|
| 990 |
msgstr ""
|
| 991 |
|
| 992 |
#: src/Tribe/Languages/Locations.php:185
|
| 993 |
+
msgid "Macedonia"
|
| 994 |
msgstr ""
|
| 995 |
|
| 996 |
#: src/Tribe/Languages/Locations.php:186
|
| 997 |
+
msgid "Madagascar"
|
| 998 |
msgstr ""
|
| 999 |
|
| 1000 |
#: src/Tribe/Languages/Locations.php:187
|
| 1001 |
+
msgid "Malawi"
|
| 1002 |
msgstr ""
|
| 1003 |
|
| 1004 |
#: src/Tribe/Languages/Locations.php:188
|
| 1005 |
+
msgid "Malaysia"
|
| 1006 |
msgstr ""
|
| 1007 |
|
| 1008 |
#: src/Tribe/Languages/Locations.php:189
|
| 1009 |
+
msgid "Maldives"
|
| 1010 |
msgstr ""
|
| 1011 |
|
| 1012 |
#: src/Tribe/Languages/Locations.php:190
|
| 1013 |
+
msgid "Mali"
|
| 1014 |
msgstr ""
|
| 1015 |
|
| 1016 |
#: src/Tribe/Languages/Locations.php:191
|
| 1017 |
+
msgid "Malta"
|
| 1018 |
msgstr ""
|
| 1019 |
|
| 1020 |
#: src/Tribe/Languages/Locations.php:192
|
| 1021 |
+
msgid "Marshall Islands"
|
| 1022 |
msgstr ""
|
| 1023 |
|
| 1024 |
#: src/Tribe/Languages/Locations.php:193
|
| 1025 |
+
msgid "Martinique"
|
| 1026 |
msgstr ""
|
| 1027 |
|
| 1028 |
#: src/Tribe/Languages/Locations.php:194
|
| 1029 |
+
msgid "Mauritania"
|
| 1030 |
msgstr ""
|
| 1031 |
|
| 1032 |
#: src/Tribe/Languages/Locations.php:195
|
| 1033 |
+
msgid "Mauritius"
|
| 1034 |
msgstr ""
|
| 1035 |
|
| 1036 |
#: src/Tribe/Languages/Locations.php:196
|
| 1037 |
+
msgid "Mayotte"
|
| 1038 |
msgstr ""
|
| 1039 |
|
| 1040 |
#: src/Tribe/Languages/Locations.php:197
|
| 1041 |
+
msgid "Mexico"
|
| 1042 |
msgstr ""
|
| 1043 |
|
| 1044 |
#: src/Tribe/Languages/Locations.php:198
|
| 1045 |
+
msgid "Micronesia, Federated States of"
|
| 1046 |
msgstr ""
|
| 1047 |
|
| 1048 |
#: src/Tribe/Languages/Locations.php:199
|
| 1049 |
+
msgid "Moldova, Republic of"
|
| 1050 |
msgstr ""
|
| 1051 |
|
| 1052 |
#: src/Tribe/Languages/Locations.php:200
|
| 1053 |
+
msgid "Monaco"
|
| 1054 |
msgstr ""
|
| 1055 |
|
| 1056 |
#: src/Tribe/Languages/Locations.php:201
|
| 1057 |
+
msgid "Mongolia"
|
| 1058 |
msgstr ""
|
| 1059 |
|
| 1060 |
#: src/Tribe/Languages/Locations.php:202
|
| 1061 |
+
msgid "Montenegro"
|
| 1062 |
msgstr ""
|
| 1063 |
|
| 1064 |
#: src/Tribe/Languages/Locations.php:203
|
| 1065 |
+
msgid "Montserrat"
|
| 1066 |
msgstr ""
|
| 1067 |
|
| 1068 |
#: src/Tribe/Languages/Locations.php:204
|
| 1069 |
+
msgid "Morocco"
|
| 1070 |
msgstr ""
|
| 1071 |
|
| 1072 |
#: src/Tribe/Languages/Locations.php:205
|
| 1073 |
+
msgid "Mozambique"
|
| 1074 |
msgstr ""
|
| 1075 |
|
| 1076 |
#: src/Tribe/Languages/Locations.php:206
|
| 1077 |
+
msgid "Myanmar"
|
| 1078 |
msgstr ""
|
| 1079 |
|
| 1080 |
#: src/Tribe/Languages/Locations.php:207
|
| 1081 |
+
msgid "Namibia"
|
| 1082 |
msgstr ""
|
| 1083 |
|
| 1084 |
#: src/Tribe/Languages/Locations.php:208
|
| 1085 |
+
msgid "Nauru"
|
| 1086 |
msgstr ""
|
| 1087 |
|
| 1088 |
#: src/Tribe/Languages/Locations.php:209
|
| 1089 |
+
msgid "Nepal"
|
| 1090 |
msgstr ""
|
| 1091 |
|
| 1092 |
#: src/Tribe/Languages/Locations.php:210
|
| 1093 |
+
msgid "Netherlands"
|
| 1094 |
msgstr ""
|
| 1095 |
|
| 1096 |
#: src/Tribe/Languages/Locations.php:211
|
| 1097 |
+
msgid "New Caledonia"
|
| 1098 |
msgstr ""
|
| 1099 |
|
| 1100 |
#: src/Tribe/Languages/Locations.php:212
|
| 1101 |
+
msgid "New Zealand"
|
| 1102 |
msgstr ""
|
| 1103 |
|
| 1104 |
#: src/Tribe/Languages/Locations.php:213
|
| 1105 |
+
msgid "Nicaragua"
|
| 1106 |
msgstr ""
|
| 1107 |
|
| 1108 |
#: src/Tribe/Languages/Locations.php:214
|
| 1109 |
+
msgid "Niger"
|
| 1110 |
msgstr ""
|
| 1111 |
|
| 1112 |
#: src/Tribe/Languages/Locations.php:215
|
| 1113 |
+
msgid "Nigeria"
|
| 1114 |
msgstr ""
|
| 1115 |
|
| 1116 |
#: src/Tribe/Languages/Locations.php:216
|
| 1117 |
+
msgid "Niue"
|
| 1118 |
msgstr ""
|
| 1119 |
|
| 1120 |
#: src/Tribe/Languages/Locations.php:217
|
| 1121 |
+
msgid "Norfolk Island"
|
| 1122 |
msgstr ""
|
| 1123 |
|
| 1124 |
#: src/Tribe/Languages/Locations.php:218
|
| 1481 |
msgid "Florida"
|
| 1482 |
msgstr ""
|
| 1483 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1484 |
#: src/Tribe/Languages/Locations.php:335
|
| 1485 |
msgid "Hawaii"
|
| 1486 |
msgstr ""
|
| 1641 |
msgid "Wyoming"
|
| 1642 |
msgstr ""
|
| 1643 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1644 |
#: src/Tribe/Log/Admin.php:133
|
| 1645 |
msgctxt "log selector"
|
| 1646 |
msgid "None currently available"
|
| 1659 |
msgid "Null logger (will log nothing)"
|
| 1660 |
msgstr ""
|
| 1661 |
|
| 1662 |
+
#: src/Tribe/Log.php:286
|
| 1663 |
msgid "Cannot set %s as the current logging engine"
|
| 1664 |
msgstr ""
|
| 1665 |
|
| 1666 |
+
#: src/Tribe/Log.php:385
|
| 1667 |
msgid "Disabled"
|
| 1668 |
msgstr ""
|
| 1669 |
|
| 1670 |
+
#: src/Tribe/Log.php:386
|
| 1671 |
msgid "Only errors"
|
| 1672 |
msgstr ""
|
| 1673 |
|
| 1674 |
+
#: src/Tribe/Log.php:387
|
| 1675 |
msgid "Warnings and errors"
|
| 1676 |
msgstr ""
|
| 1677 |
|
| 1678 |
+
#: src/Tribe/Log.php:388
|
| 1679 |
msgid "Full debug (all events)"
|
| 1680 |
msgstr ""
|
| 1681 |
|
| 1682 |
+
#: src/Tribe/Main.php:281
|
| 1683 |
msgid ": activate to sort column ascending"
|
| 1684 |
msgstr ""
|
| 1685 |
|
| 1686 |
+
#: src/Tribe/Main.php:282
|
| 1687 |
msgid ": activate to sort column descending"
|
| 1688 |
msgstr ""
|
| 1689 |
|
| 1690 |
+
#: src/Tribe/Main.php:284
|
| 1691 |
msgid "Show _MENU_ entries"
|
| 1692 |
msgstr ""
|
| 1693 |
|
| 1694 |
+
#: src/Tribe/Main.php:285
|
| 1695 |
msgid "No data available in table"
|
| 1696 |
msgstr ""
|
| 1697 |
|
| 1698 |
+
#: src/Tribe/Main.php:286
|
| 1699 |
msgid "Showing _START_ to _END_ of _TOTAL_ entries"
|
| 1700 |
msgstr ""
|
| 1701 |
|
| 1702 |
+
#: src/Tribe/Main.php:287
|
| 1703 |
msgid "Showing 0 to 0 of 0 entries"
|
| 1704 |
msgstr ""
|
| 1705 |
|
| 1706 |
+
#: src/Tribe/Main.php:288
|
| 1707 |
msgid "(filtered from _MAX_ total entries)"
|
| 1708 |
msgstr ""
|
| 1709 |
|
| 1710 |
+
#: src/Tribe/Main.php:289
|
| 1711 |
msgid "No matching records found"
|
| 1712 |
msgstr ""
|
| 1713 |
|
| 1714 |
+
#: src/Tribe/Main.php:290
|
| 1715 |
msgid "Search:"
|
| 1716 |
msgstr ""
|
| 1717 |
|
| 1718 |
+
#: src/Tribe/Main.php:291
|
| 1719 |
msgid "All items on this page were selected. "
|
| 1720 |
msgstr ""
|
| 1721 |
|
| 1722 |
+
#: src/Tribe/Main.php:292
|
| 1723 |
msgid "Select all pages"
|
| 1724 |
msgstr ""
|
| 1725 |
|
| 1726 |
+
#: src/Tribe/Main.php:293
|
| 1727 |
msgid "Clear Selection."
|
| 1728 |
msgstr ""
|
| 1729 |
|
| 1730 |
+
#: src/Tribe/Main.php:295
|
| 1731 |
msgid "All"
|
| 1732 |
msgstr ""
|
| 1733 |
|
| 1734 |
+
#: src/Tribe/Main.php:296 src/Tribe/Main.php:313
|
| 1735 |
msgid "Next"
|
| 1736 |
msgstr ""
|
| 1737 |
|
| 1738 |
+
#: src/Tribe/Main.php:297
|
| 1739 |
msgid "Previous"
|
| 1740 |
msgstr ""
|
| 1741 |
|
| 1742 |
+
#: src/Tribe/Main.php:302
|
| 1743 |
msgid ": Selected %d rows"
|
| 1744 |
msgstr ""
|
| 1745 |
|
| 1746 |
+
#: src/Tribe/Main.php:303
|
| 1747 |
msgid ": Selected 1 row"
|
| 1748 |
msgstr ""
|
| 1749 |
|
| 1750 |
+
#: src/Tribe/Main.php:314
|
| 1751 |
msgid "Prev"
|
| 1752 |
msgstr ""
|
| 1753 |
|
| 1754 |
+
#: src/Tribe/Main.php:315 src/Tribe/Main.php:317
|
| 1755 |
msgid "Today"
|
| 1756 |
msgstr ""
|
| 1757 |
|
| 1758 |
+
#: src/Tribe/Main.php:316
|
| 1759 |
msgid "Done"
|
| 1760 |
msgstr ""
|
| 1761 |
|
| 1762 |
+
#: src/Tribe/Main.php:318
|
| 1763 |
msgid "Clear"
|
| 1764 |
msgstr ""
|
| 1765 |
|
| 1798 |
msgid "License key(s) updated."
|
| 1799 |
msgstr ""
|
| 1800 |
|
| 1801 |
+
#: src/Tribe/PUE/Checker.php:899
|
| 1802 |
msgid ""
|
| 1803 |
"Hmmm... something's wrong with this validator. Please contact %ssupport%s."
|
| 1804 |
msgstr ""
|
| 1805 |
|
| 1806 |
+
#: src/Tribe/PUE/Checker.php:912
|
| 1807 |
msgid "unknown date"
|
| 1808 |
msgstr ""
|
| 1809 |
|
| 1810 |
+
#: src/Tribe/PUE/Checker.php:918
|
| 1811 |
msgid "Sorry, key validation server is not available."
|
| 1812 |
msgstr ""
|
| 1813 |
|
| 1814 |
+
#: src/Tribe/PUE/Checker.php:938
|
| 1815 |
msgid "Valid Key! Expires on %s"
|
| 1816 |
msgstr ""
|
| 1817 |
|
| 1818 |
+
#: src/Tribe/PUE/Checker.php:943
|
| 1819 |
msgid "Thanks for setting up a valid key. It will expire on %s"
|
| 1820 |
msgstr ""
|
| 1821 |
|
| 1822 |
+
#: src/Tribe/PUE/Checker.php:970 src/Tribe/PUE/Notices.php:342
|
| 1823 |
msgid "Renew Your License Now"
|
| 1824 |
msgstr ""
|
| 1825 |
|
| 1826 |
+
#: src/Tribe/PUE/Checker.php:972 src/Tribe/PUE/Notices.php:344
|
| 1827 |
msgid " (opens in a new window)"
|
| 1828 |
msgstr ""
|
| 1829 |
|
| 1830 |
+
#: src/Tribe/PUE/Checker.php:987
|
| 1831 |
msgid "Please refresh the page and try your request again."
|
| 1832 |
msgstr ""
|
| 1833 |
|
| 1834 |
+
#: src/Tribe/PUE/Checker.php:1008
|
| 1835 |
msgid ""
|
| 1836 |
"There is an update for %s. You'll need to %scheck your license%s to have "
|
| 1837 |
"access to updates, downloads, and support."
|
| 1838 |
msgstr ""
|
| 1839 |
|
| 1840 |
+
#: src/Tribe/PUE/Checker.php:1065
|
| 1841 |
msgid ""
|
| 1842 |
"There is an update for %s. %sRenew your license%s to get access to bug "
|
| 1843 |
"fixes, security updates, and new features."
|
| 1844 |
msgstr ""
|
| 1845 |
|
| 1846 |
+
#: src/Tribe/PUE/Checker.php:1095
|
| 1847 |
msgid "Update now to version %s."
|
| 1848 |
msgstr ""
|
| 1849 |
|
| 1850 |
+
#: src/Tribe/PUE/Checker.php:1106
|
| 1851 |
msgid "There is a new version of %1$s available. %2$s"
|
| 1852 |
msgstr ""
|
| 1853 |
|
| 1854 |
+
#: src/Tribe/PUE/Checker.php:1686
|
| 1855 |
msgid "A valid license has been entered by your network administrator."
|
| 1856 |
msgstr ""
|
| 1857 |
|
| 1858 |
+
#: src/Tribe/PUE/Checker.php:1687
|
| 1859 |
msgid "No license entered. Consult your network administrator."
|
| 1860 |
msgstr ""
|
| 1861 |
|
| 1862 |
+
#: src/Tribe/PUE/Checker.php:1688
|
| 1863 |
msgid "Expired license. Consult your network administrator."
|
| 1864 |
msgstr ""
|
| 1865 |
|
| 1906 |
msgid "%1$s and %2$s"
|
| 1907 |
msgstr ""
|
| 1908 |
|
| 1909 |
+
#: src/Tribe/PUE/Update_Prevention.php:181
|
| 1910 |
+
msgid "Read More."
|
| 1911 |
+
msgstr ""
|
| 1912 |
+
|
| 1913 |
#: src/Tribe/PUE/Update_Prevention.php:184
|
| 1914 |
msgid ""
|
| 1915 |
"Your update failed due to an incompatibility between the version (%1$s) of "
|
| 1917 |
"%4$s"
|
| 1918 |
msgstr ""
|
| 1919 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1920 |
#: src/Tribe/Plugins_API.php:28
|
| 1921 |
msgid ""
|
| 1922 |
"Create an events calendar and manage it with ease. The Events Calendar "
|
| 2048 |
msgid "Events Help"
|
| 2049 |
msgstr ""
|
| 2050 |
|
| 2051 |
+
#: src/Tribe/Settings.php:349
|
| 2052 |
msgid "%s Settings"
|
| 2053 |
msgstr ""
|
| 2054 |
|
| 2055 |
+
#: src/Tribe/Settings.php:363
|
| 2056 |
msgid "You've requested a non-existent tab."
|
| 2057 |
msgstr ""
|
| 2058 |
|
| 2059 |
+
#: src/Tribe/Settings.php:371
|
| 2060 |
msgid "Save Changes"
|
| 2061 |
msgstr ""
|
| 2062 |
|
| 2063 |
+
#: src/Tribe/Settings.php:419
|
| 2064 |
msgid "You don't have permission to do that."
|
| 2065 |
msgstr ""
|
| 2066 |
|
| 2067 |
+
#: src/Tribe/Settings.php:425
|
| 2068 |
msgid "The request was sent insecurely."
|
| 2069 |
msgstr ""
|
| 2070 |
|
| 2071 |
+
#: src/Tribe/Settings.php:431
|
| 2072 |
msgid "The request wasn't sent from this tab."
|
| 2073 |
msgstr ""
|
| 2074 |
|
| 2075 |
+
#: src/Tribe/Settings.php:608
|
| 2076 |
msgid "Your form had the following errors:"
|
| 2077 |
msgstr ""
|
| 2078 |
|
| 2079 |
+
#: src/Tribe/Settings.php:618
|
| 2080 |
msgid "None of your settings were saved. Please try again."
|
| 2081 |
msgstr ""
|
| 2082 |
|
| 2083 |
+
#: src/Tribe/Settings.php:619
|
| 2084 |
msgid ""
|
| 2085 |
"The above setting was not saved. Other settings were successfully saved."
|
| 2086 |
msgid_plural ""
|
| 2088 |
msgstr[0] ""
|
| 2089 |
msgstr[1] ""
|
| 2090 |
|
| 2091 |
+
#: src/Tribe/Settings.php:641
|
| 2092 |
msgid "Settings saved."
|
| 2093 |
msgstr ""
|
| 2094 |
|
| 2095 |
+
#: src/Tribe/Settings_Manager.php:54
|
| 2096 |
msgid "General"
|
| 2097 |
msgstr ""
|
| 2098 |
|
| 2099 |
+
#: src/Tribe/Settings_Manager.php:55
|
| 2100 |
msgid "Display"
|
| 2101 |
msgstr ""
|
| 2102 |
|
| 2103 |
+
#: src/Tribe/Settings_Manager.php:219
|
| 2104 |
msgid "Network"
|
| 2105 |
msgstr ""
|
| 2106 |
|
| 2107 |
+
#: src/Tribe/Settings_Manager.php:253
|
| 2108 |
#: src/admin-views/tribe-options-licenses.php:57
|
| 2109 |
msgid "Licenses"
|
| 2110 |
msgstr ""
|
| 2111 |
|
| 2112 |
+
#: src/Tribe/Settings_Manager.php:283
|
| 2113 |
msgid "Help"
|
| 2114 |
msgstr ""
|
| 2115 |
|
| 2147 |
"overrides is provided below."
|
| 2148 |
msgstr ""
|
| 2149 |
|
| 2150 |
+
#: src/Tribe/Support.php:171
|
| 2151 |
msgid "English"
|
| 2152 |
msgstr ""
|
| 2153 |
|
| 2154 |
+
#: src/Tribe/Support.php:188 src/Tribe/Support.php:189
|
| 2155 |
msgid "Unknown or not set"
|
| 2156 |
msgstr ""
|
| 2157 |
|
| 2158 |
+
#: src/Tribe/Support.php:199
|
| 2159 |
msgid ""
|
| 2160 |
"Rewrite rules were purged on load of this help page. Chances are there is a "
|
| 2161 |
"rewrite rule flush occurring in a plugin or theme!"
|
| 2162 |
msgstr ""
|
| 2163 |
|
| 2164 |
+
#: src/Tribe/Support.php:305
|
| 2165 |
msgid ""
|
| 2166 |
"Yes, automatically share my system information with the Modern Tribe support "
|
| 2167 |
"team"
|
| 2168 |
msgstr ""
|
| 2169 |
|
| 2170 |
+
#: src/Tribe/Support.php:306
|
| 2171 |
msgid ""
|
| 2172 |
"Your system information will only be used by the Modern Tribe support team. "
|
| 2173 |
"All information is stored securely. We do not share this information with "
|
| 2174 |
"any third parties."
|
| 2175 |
msgstr ""
|
| 2176 |
|
| 2177 |
+
#: src/Tribe/Support.php:325 src/Tribe/Support.php:330
|
| 2178 |
msgid "Invalid Key"
|
| 2179 |
msgstr ""
|
| 2180 |
|
| 2181 |
+
#: src/Tribe/Support.php:358 src/Tribe/Support.php:384
|
| 2182 |
msgid "Permission Error"
|
| 2183 |
msgstr ""
|
| 2184 |
|
| 2185 |
+
#: src/Tribe/Support.php:372
|
| 2186 |
msgid "Unique System Info Key Generated"
|
| 2187 |
msgstr ""
|
| 2188 |
|
| 2204 |
msgid "with function name:"
|
| 2205 |
msgstr ""
|
| 2206 |
|
| 2207 |
+
#: src/Tribe/Validate.php:120 src/Tribe/Validate.php:136
|
| 2208 |
msgid "%s must contain numbers and letters only"
|
| 2209 |
msgstr ""
|
| 2210 |
|
| 2211 |
+
#: src/Tribe/Validate.php:152
|
| 2212 |
msgid "%s must contain numbers, letters and dots only"
|
| 2213 |
msgstr ""
|
| 2214 |
|
| 2215 |
+
#: src/Tribe/Validate.php:168
|
| 2216 |
msgid "%s must contain numbers, letters, dashes and undescores only"
|
| 2217 |
msgstr ""
|
| 2218 |
|
| 2219 |
+
#: src/Tribe/Validate.php:184
|
| 2220 |
msgid "%s must not be empty"
|
| 2221 |
msgstr ""
|
| 2222 |
|
| 2223 |
+
#: src/Tribe/Validate.php:200 src/Tribe/Validate.php:228
|
| 2224 |
msgid "%s must be a positive number."
|
| 2225 |
msgstr ""
|
| 2226 |
|
| 2227 |
+
#: src/Tribe/Validate.php:214
|
| 2228 |
msgid "%s must be a positive number or percent."
|
| 2229 |
msgstr ""
|
| 2230 |
|
| 2231 |
+
#: src/Tribe/Validate.php:248
|
| 2232 |
msgid "%s must be a whole number."
|
| 2233 |
msgstr ""
|
| 2234 |
|
| 2235 |
+
#: src/Tribe/Validate.php:267
|
| 2236 |
msgid "%s must be a valid slug (numbers, letters, dashes, and underscores)."
|
| 2237 |
msgstr ""
|
| 2238 |
|
| 2239 |
+
#: src/Tribe/Validate.php:282
|
| 2240 |
+
msgid "%s must be a valid absolute URL."
|
| 2241 |
msgstr ""
|
| 2242 |
|
| 2243 |
+
#: src/Tribe/Validate.php:298 src/Tribe/Validate.php:310
|
| 2244 |
+
#: src/Tribe/Validate.php:323 src/Tribe/Validate.php:345
|
| 2245 |
msgid "%s must have a value that's part of its options."
|
| 2246 |
msgstr ""
|
| 2247 |
|
| 2248 |
+
#: src/Tribe/Validate.php:359
|
| 2249 |
msgid ""
|
| 2250 |
"Comparison validation failed because no comparison value was provided, for "
|
| 2251 |
"field %s"
|
| 2252 |
msgstr ""
|
| 2253 |
|
| 2254 |
+
#: src/Tribe/Validate.php:366
|
| 2255 |
msgid "%s cannot be the same as %s."
|
| 2256 |
msgstr ""
|
| 2257 |
|
| 2258 |
+
#: src/Tribe/Validate.php:368
|
| 2259 |
msgid "%s cannot be a duplicate"
|
| 2260 |
msgstr ""
|
| 2261 |
|
| 2262 |
+
#: src/Tribe/Validate.php:384
|
| 2263 |
msgid "%s must be a number or percentage."
|
| 2264 |
msgstr ""
|
| 2265 |
|
| 2266 |
+
#: src/Tribe/Validate.php:438
|
| 2267 |
msgid "%s must be a number between 0 and 21."
|
| 2268 |
msgstr ""
|
| 2269 |
|
| 2270 |
+
#: src/Tribe/Validate.php:454
|
| 2271 |
msgid ""
|
| 2272 |
"%s must consist of letters, numbers, dashes, apostrophes, and spaces only."
|
| 2273 |
msgstr ""
|
| 2274 |
|
| 2275 |
+
#: src/Tribe/Validate.php:470
|
| 2276 |
msgid "%s must consist of letters, spaces, apostrophes, and dashes."
|
| 2277 |
msgstr ""
|
| 2278 |
|
| 2279 |
+
#: src/Tribe/Validate.php:484
|
| 2280 |
msgid "%s must consist of 5 numbers."
|
| 2281 |
msgstr ""
|
| 2282 |
|
| 2283 |
+
#: src/Tribe/Validate.php:498
|
| 2284 |
msgid "%s must be a phone number."
|
| 2285 |
msgstr ""
|
| 2286 |
|
| 2287 |
+
#: src/Tribe/Validate.php:514
|
| 2288 |
msgid ""
|
| 2289 |
"Country List must be formatted as one country per line in the following "
|
| 2290 |
"format: <br>US, United States <br> UK, United Kingdom."
|
| 2291 |
msgstr ""
|
| 2292 |
|
| 2293 |
+
#: src/Tribe/Validate.php:545
|
| 2294 |
msgid "%s must be an email address."
|
| 2295 |
msgstr ""
|
| 2296 |
|
| 2297 |
+
#: src/Tribe/View_Helpers.php:51
|
| 2298 |
msgid "Select a Country:"
|
| 2299 |
msgstr ""
|
| 2300 |
|
| 2350 |
msgstr ""
|
| 2351 |
|
| 2352 |
#: src/admin-views/tribe-options-display.php:36
|
| 2353 |
+
msgid "Datepicker Date Format"
|
| 2354 |
msgstr ""
|
| 2355 |
|
| 2356 |
#: src/admin-views/tribe-options-display.php:37
|
| 2357 |
+
msgid "Select the date format to use in datepickers"
|
|
|
|
|
|
|
| 2358 |
msgstr ""
|
| 2359 |
|
| 2360 |
#: src/admin-views/tribe-options-general.php:10
|
| 2406 |
msgid "Debug mode"
|
| 2407 |
msgstr ""
|
| 2408 |
|
| 2409 |
+
#: src/admin-views/tribe-options-general.php:59
|
| 2410 |
msgid ""
|
| 2411 |
"Enable this option to log debug information. By default this will log to "
|
| 2412 |
"your server PHP error log. If you'd like to see the log messages in your "
|
| 2595 |
msgid "Hide the following settings tabs on every site:"
|
| 2596 |
msgstr ""
|
| 2597 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2598 |
#: src/views/promoter/auth.php:35
|
| 2599 |
msgid "Promoter would like to sync with your site"
|
| 2600 |
msgstr ""
|
common/src/Tribe/Abstract_Plugin_Register.php
CHANGED
|
@@ -17,42 +17,23 @@ abstract class Tribe__Abstract_Plugin_Register {
|
|
| 17 |
* @var string
|
| 18 |
*/
|
| 19 |
protected $base_dir;
|
| 20 |
-
|
| 21 |
-
/**
|
| 22 |
-
* @var string
|
| 23 |
-
*/
|
| 24 |
protected $main_class;
|
| 25 |
-
|
| 26 |
-
/**
|
| 27 |
-
* @var string
|
| 28 |
-
*/
|
| 29 |
protected $version;
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
*/
|
| 36 |
-
protected $classes_req = [];
|
| 37 |
-
|
| 38 |
-
/**
|
| 39 |
-
* @var array
|
| 40 |
-
*/
|
| 41 |
-
protected $dependencies = [
|
| 42 |
-
'parent-dependencies' => [],
|
| 43 |
-
'co-dependencies' => [],
|
| 44 |
-
'addon-dependencies' => [],
|
| 45 |
-
];
|
| 46 |
|
| 47 |
/**
|
| 48 |
* Registers a plugin with dependencies
|
| 49 |
*/
|
| 50 |
public function register_plugin() {
|
| 51 |
-
tribe_register_plugin(
|
| 52 |
$this->base_dir,
|
| 53 |
$this->main_class,
|
| 54 |
$this->version,
|
| 55 |
-
|
| 56 |
$this->dependencies
|
| 57 |
);
|
| 58 |
}
|
|
@@ -62,11 +43,8 @@ abstract class Tribe__Abstract_Plugin_Register {
|
|
| 62 |
*
|
| 63 |
* This is basically an aliased function - register_plugins, upon
|
| 64 |
* second calling, returns whether or not a plugin should load.
|
| 65 |
-
*
|
| 66 |
-
* @deprecated since 4.9.17 It is unused by any Tribe plugins and returned void.
|
| 67 |
-
* @todo remove in 4.11
|
| 68 |
*/
|
| 69 |
public function has_valid_dependencies() {
|
| 70 |
-
|
| 71 |
}
|
| 72 |
}
|
| 17 |
* @var string
|
| 18 |
*/
|
| 19 |
protected $base_dir;
|
|
|
|
|
|
|
|
|
|
|
|
|
| 20 |
protected $main_class;
|
|
|
|
|
|
|
|
|
|
|
|
|
| 21 |
protected $version;
|
| 22 |
+
protected $dependencies = array(
|
| 23 |
+
'parent-dependencies' => array(),
|
| 24 |
+
'co-dependencies' => array(),
|
| 25 |
+
'addon-dependencies' => array(),
|
| 26 |
+
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 27 |
|
| 28 |
/**
|
| 29 |
* Registers a plugin with dependencies
|
| 30 |
*/
|
| 31 |
public function register_plugin() {
|
| 32 |
+
return tribe_register_plugin(
|
| 33 |
$this->base_dir,
|
| 34 |
$this->main_class,
|
| 35 |
$this->version,
|
| 36 |
+
array(),
|
| 37 |
$this->dependencies
|
| 38 |
);
|
| 39 |
}
|
| 43 |
*
|
| 44 |
* This is basically an aliased function - register_plugins, upon
|
| 45 |
* second calling, returns whether or not a plugin should load.
|
|
|
|
|
|
|
|
|
|
| 46 |
*/
|
| 47 |
public function has_valid_dependencies() {
|
| 48 |
+
return $this->register_plugin();
|
| 49 |
}
|
| 50 |
}
|
common/src/Tribe/Admin/Notice/Plugin_Download.php
CHANGED
|
@@ -27,7 +27,6 @@ class Tribe__Admin__Notice__Plugin_Download {
|
|
| 27 |
* @since 4.8.3 Method introduced.
|
| 28 |
* @since 4.9 Added $version and $addon parameters.
|
| 29 |
* @since 4.9.12 Add $has_pue_notice param
|
| 30 |
-
* @since 4.9.17 Appended "+" to all version numbers to indicate "or any later version".
|
| 31 |
*
|
| 32 |
* @param string $name Name of the required plugin
|
| 33 |
* @param null $thickbox_url Download or purchase URL for plugin from within /wp-admin/ thickbox
|
|
@@ -37,22 +36,18 @@ class Tribe__Admin__Notice__Plugin_Download {
|
|
| 37 |
* @param bool $has_pue_notice Indicates that we need to change the messaging due to expired key.
|
| 38 |
*/
|
| 39 |
public function add_required_plugin( $name, $thickbox_url = null, $is_active = null, $version = null, $addon = false, $has_pue_notice = false ) {
|
| 40 |
-
$this->plugins_required[ $name ] =
|
| 41 |
'name' => $name,
|
| 42 |
'thickbox_url' => $thickbox_url,
|
| 43 |
'is_active' => $is_active,
|
| 44 |
-
'version' => $version
|
| 45 |
'addon' => $addon,
|
| 46 |
'has_pue_notice' => $has_pue_notice,
|
| 47 |
-
|
| 48 |
}
|
| 49 |
|
| 50 |
/**
|
| 51 |
* Echoes the admin notice, attach to admin_notices
|
| 52 |
-
*
|
| 53 |
-
* @see \Tribe__Admin__Notice__Plugin_Download::add_required_plugin()
|
| 54 |
-
*
|
| 55 |
-
* @since 4.9.17 Altered the notice to remove "latest version" verbiage since "+" is now added to the version numbers.
|
| 56 |
*/
|
| 57 |
public function show_inactive_plugins_alert() {
|
| 58 |
if ( ! current_user_can( 'activate_plugins' ) ) {
|
|
@@ -66,11 +61,6 @@ class Tribe__Admin__Notice__Plugin_Download {
|
|
| 66 |
return;
|
| 67 |
}
|
| 68 |
|
| 69 |
-
// Make sure Thickbox is available and consistent appearance regardless of which admin page we're on
|
| 70 |
-
wp_enqueue_style( 'plugin-install' );
|
| 71 |
-
wp_enqueue_script( 'plugin-install' );
|
| 72 |
-
add_thickbox();
|
| 73 |
-
|
| 74 |
$has_pue_notices = false;
|
| 75 |
|
| 76 |
foreach ( $this->plugins_required as $req_plugin ) {
|
|
@@ -119,9 +109,9 @@ class Tribe__Admin__Notice__Plugin_Download {
|
|
| 119 |
$plugin_names_clean_text = wp_kses( $this->implode_with_grammar( $plugin_name ), $allowed_html );
|
| 120 |
$req_plugin_names_clean_text = wp_kses( $this->implode_with_grammar( $req_plugins ), $allowed_html );
|
| 121 |
|
| 122 |
-
$notice_html_content = '<p>' . esc_html__( 'To begin using %2$s, please install and activate %3$s.', 'tribe-common' ) . '</p>';
|
| 123 |
|
| 124 |
-
$read_more_link = '<a href="http://m.tri.be/1aev" target="_blank">' . esc_html__( 'Read more', 'tribe-common' ) . '
|
| 125 |
$pue_notice_text = esc_html__( 'There’s a new version of %1$s available, but your license is expired. You’ll need to renew your license to get access to the latest version. If you plan to continue using your current version of the plugin(s), be sure to use a compatible version of The Events Calendar. %2$s', 'tribe-common' );
|
| 126 |
$pue_notice_html = '<p>' . sprintf( $pue_notice_text, $plugin_names_clean_text, $read_more_link ) . '</p>';
|
| 127 |
|
|
@@ -137,9 +127,7 @@ class Tribe__Admin__Notice__Plugin_Download {
|
|
| 137 |
}
|
| 138 |
|
| 139 |
/**
|
| 140 |
-
* Implodes a list
|
| 141 |
-
*
|
| 142 |
-
* If only 1 item, no grammar. If 2 items, just conjunction. If 3+ items, commas with conjunction.
|
| 143 |
*
|
| 144 |
* @param array $items List of items to implode
|
| 145 |
*
|
|
@@ -151,13 +139,7 @@ class Tribe__Admin__Notice__Plugin_Download {
|
|
| 151 |
$output = $last_item = array_pop( $items );
|
| 152 |
|
| 153 |
if ( $items ) {
|
| 154 |
-
$output = implode( $separator, $items );
|
| 155 |
-
|
| 156 |
-
if ( 1 < count( $items ) ) {
|
| 157 |
-
$output .= $separator;
|
| 158 |
-
}
|
| 159 |
-
|
| 160 |
-
$output .= $conjunction . $last_item;
|
| 161 |
}
|
| 162 |
|
| 163 |
return $output;
|
| 27 |
* @since 4.8.3 Method introduced.
|
| 28 |
* @since 4.9 Added $version and $addon parameters.
|
| 29 |
* @since 4.9.12 Add $has_pue_notice param
|
|
|
|
| 30 |
*
|
| 31 |
* @param string $name Name of the required plugin
|
| 32 |
* @param null $thickbox_url Download or purchase URL for plugin from within /wp-admin/ thickbox
|
| 36 |
* @param bool $has_pue_notice Indicates that we need to change the messaging due to expired key.
|
| 37 |
*/
|
| 38 |
public function add_required_plugin( $name, $thickbox_url = null, $is_active = null, $version = null, $addon = false, $has_pue_notice = false ) {
|
| 39 |
+
$this->plugins_required[ $name ] = array(
|
| 40 |
'name' => $name,
|
| 41 |
'thickbox_url' => $thickbox_url,
|
| 42 |
'is_active' => $is_active,
|
| 43 |
+
'version' => $version,
|
| 44 |
'addon' => $addon,
|
| 45 |
'has_pue_notice' => $has_pue_notice,
|
| 46 |
+
);
|
| 47 |
}
|
| 48 |
|
| 49 |
/**
|
| 50 |
* Echoes the admin notice, attach to admin_notices
|
|
|
|
|
|
|
|
|
|
|
|
|
| 51 |
*/
|
| 52 |
public function show_inactive_plugins_alert() {
|
| 53 |
if ( ! current_user_can( 'activate_plugins' ) ) {
|
| 61 |
return;
|
| 62 |
}
|
| 63 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 64 |
$has_pue_notices = false;
|
| 65 |
|
| 66 |
foreach ( $this->plugins_required as $req_plugin ) {
|
| 109 |
$plugin_names_clean_text = wp_kses( $this->implode_with_grammar( $plugin_name ), $allowed_html );
|
| 110 |
$req_plugin_names_clean_text = wp_kses( $this->implode_with_grammar( $req_plugins ), $allowed_html );
|
| 111 |
|
| 112 |
+
$notice_html_content = '<p>' . esc_html__( 'To begin using %2$s, please install and activate the latest version of %3$s.', 'tribe-common' ) . '</p>';
|
| 113 |
|
| 114 |
+
$read_more_link = '<a href="http://m.tri.be/1aev" target="_blank">' . esc_html__( 'Read more.', 'tribe-common' ) . '</a>';
|
| 115 |
$pue_notice_text = esc_html__( 'There’s a new version of %1$s available, but your license is expired. You’ll need to renew your license to get access to the latest version. If you plan to continue using your current version of the plugin(s), be sure to use a compatible version of The Events Calendar. %2$s', 'tribe-common' );
|
| 116 |
$pue_notice_html = '<p>' . sprintf( $pue_notice_text, $plugin_names_clean_text, $read_more_link ) . '</p>';
|
| 117 |
|
| 127 |
}
|
| 128 |
|
| 129 |
/**
|
| 130 |
+
* Implodes a list items using 'and' as the final separator and a comma everywhere else
|
|
|
|
|
|
|
| 131 |
*
|
| 132 |
* @param array $items List of items to implode
|
| 133 |
*
|
| 139 |
$output = $last_item = array_pop( $items );
|
| 140 |
|
| 141 |
if ( $items ) {
|
| 142 |
+
$output = implode( $separator, $items ) . $conjunction . $last_item;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 143 |
}
|
| 144 |
|
| 145 |
return $output;
|
common/src/Tribe/Admin/Notices.php
CHANGED
|
@@ -111,15 +111,23 @@ class Tribe__Admin__Notices {
|
|
| 111 |
$transients = $this->get_transients();
|
| 112 |
|
| 113 |
foreach ( $transients as $slug => $transient ) {
|
| 114 |
-
|
|
|
|
| 115 |
continue;
|
| 116 |
}
|
| 117 |
-
list( $html, $args, $expire ) = $transients[ $slug ];
|
| 118 |
$this->register( $slug, $html, $args );
|
| 119 |
}
|
| 120 |
|
| 121 |
foreach ( $this->notices as $notice ) {
|
| 122 |
-
if (
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 123 |
continue;
|
| 124 |
}
|
| 125 |
|
|
@@ -549,12 +557,6 @@ class Tribe__Admin__Notices {
|
|
| 549 |
* @return array An associative array in the shape [ <slug> => [ <html>, <args>, <expire timestamp> ] ]
|
| 550 |
*/
|
| 551 |
protected function get_transients() {
|
| 552 |
-
$cached = tribe( 'cache' )['transient_admin_notices'];
|
| 553 |
-
|
| 554 |
-
if ( false !== $cached ) {
|
| 555 |
-
return $cached;
|
| 556 |
-
}
|
| 557 |
-
|
| 558 |
$transient = self::$transient_notices_name;
|
| 559 |
$notices = get_transient( $transient );
|
| 560 |
$notices = is_array( $notices ) ? $notices : array();
|
|
@@ -570,8 +572,6 @@ class Tribe__Admin__Notices {
|
|
| 570 |
}
|
| 571 |
}
|
| 572 |
|
| 573 |
-
tribe( 'cache' )['transient_admin_notices'] = $notices;
|
| 574 |
-
|
| 575 |
return $notices;
|
| 576 |
}
|
| 577 |
|
|
@@ -586,84 +586,4 @@ class Tribe__Admin__Notices {
|
|
| 586 |
$transient = self::$transient_notices_name;
|
| 587 |
set_transient( $transient, $notices, MONTH_IN_SECONDS );
|
| 588 |
}
|
| 589 |
-
|
| 590 |
-
/**
|
| 591 |
-
* Checks whether a specific transient admin notices is being shown or not, depending on its expiration and
|
| 592 |
-
* dismissible status.
|
| 593 |
-
*
|
| 594 |
-
*
|
| 595 |
-
* @since 4.11.1
|
| 596 |
-
*
|
| 597 |
-
* @param string|array $slug The slug, or slugs, of the transient notices to check. This is the same slug used
|
| 598 |
-
* to register the transient notice in the `tribe_transient_notice` function or the
|
| 599 |
-
* `Tribe__Admin__Notices::register_transient()` method.
|
| 600 |
-
*
|
| 601 |
-
* @return bool Whether the transient notice is showing or not.
|
| 602 |
-
*/
|
| 603 |
-
public function showing_transient_notice( $slug ) {
|
| 604 |
-
$transient_notices = (array) $this->get_transients();
|
| 605 |
-
|
| 606 |
-
return isset( $transient_notices[ $slug ] )
|
| 607 |
-
&& ! $this->has_user_dimissed( $slug )
|
| 608 |
-
&& ! $this->transient_notice_expired( $slug );
|
| 609 |
-
}
|
| 610 |
-
|
| 611 |
-
/**
|
| 612 |
-
* Checks whether a transient notice expired or not.
|
| 613 |
-
*
|
| 614 |
-
* @since 4.11.1
|
| 615 |
-
*
|
| 616 |
-
* @param string|array $slug The slug, or slugs, of the transient notices to check. This is the same slug used
|
| 617 |
-
* to register the transient notice in the `tribe_transient_notice` function or the
|
| 618 |
-
* `Tribe__Admin__Notices::register_transient()` method.
|
| 619 |
-
*
|
| 620 |
-
* @return bool Whether the transient notice is expired or not.
|
| 621 |
-
*/
|
| 622 |
-
protected function transient_notice_expired( $slug ) {
|
| 623 |
-
$transients = (array) $this->get_transients();
|
| 624 |
-
|
| 625 |
-
if ( ! isset( $transients[ $slug ] ) ) {
|
| 626 |
-
return true;
|
| 627 |
-
}
|
| 628 |
-
|
| 629 |
-
list( $html, $args, $expire ) = $transients[ $slug ];
|
| 630 |
-
if ( $expire < time() ) {
|
| 631 |
-
return true;
|
| 632 |
-
}
|
| 633 |
-
|
| 634 |
-
return false;
|
| 635 |
-
}
|
| 636 |
-
|
| 637 |
-
/**
|
| 638 |
-
* Checks whether a notice is being shown or not; the result takes the notice callback and dismissible status into
|
| 639 |
-
* account.
|
| 640 |
-
*
|
| 641 |
-
* @since 4.11.1
|
| 642 |
-
*
|
| 643 |
-
* @param string|array $slug The slug, or slugs, of the transient notices to check. This is the same slug used
|
| 644 |
-
* to register the transient notice in the `tribe_transient_notice` function or the
|
| 645 |
-
* `Tribe__Admin__Notices::register_transient()` method.
|
| 646 |
-
*
|
| 647 |
-
* @return bool Whether the notice is showing or not.
|
| 648 |
-
*/
|
| 649 |
-
public function showing_notice( $slug ) {
|
| 650 |
-
if ( ! isset( $this->notices[ $slug ] ) ) {
|
| 651 |
-
return false;
|
| 652 |
-
}
|
| 653 |
-
|
| 654 |
-
$notice = $this->notices[ $slug ];
|
| 655 |
-
if ( $notice->dismiss && $this->has_user_dimissed( $notice->slug ) ) {
|
| 656 |
-
return false;
|
| 657 |
-
}
|
| 658 |
-
|
| 659 |
-
if (
|
| 660 |
-
! empty( $notice->active_callback )
|
| 661 |
-
&& is_callable( $notice->active_callback )
|
| 662 |
-
&& false == call_user_func( $notice->active_callback )
|
| 663 |
-
) {
|
| 664 |
-
return false;
|
| 665 |
-
}
|
| 666 |
-
|
| 667 |
-
return true;
|
| 668 |
-
}
|
| 669 |
}
|
| 111 |
$transients = $this->get_transients();
|
| 112 |
|
| 113 |
foreach ( $transients as $slug => $transient ) {
|
| 114 |
+
list( $html, $args, $expire ) = $transient;
|
| 115 |
+
if ( $expire < time() ) {
|
| 116 |
continue;
|
| 117 |
}
|
|
|
|
| 118 |
$this->register( $slug, $html, $args );
|
| 119 |
}
|
| 120 |
|
| 121 |
foreach ( $this->notices as $notice ) {
|
| 122 |
+
if ( $notice->dismiss && $this->has_user_dimissed( $notice->slug ) ) {
|
| 123 |
+
continue;
|
| 124 |
+
}
|
| 125 |
+
|
| 126 |
+
if (
|
| 127 |
+
! empty( $notice->active_callback )
|
| 128 |
+
&& is_callable( $notice->active_callback )
|
| 129 |
+
&& false == call_user_func( $notice->active_callback )
|
| 130 |
+
) {
|
| 131 |
continue;
|
| 132 |
}
|
| 133 |
|
| 557 |
* @return array An associative array in the shape [ <slug> => [ <html>, <args>, <expire timestamp> ] ]
|
| 558 |
*/
|
| 559 |
protected function get_transients() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 560 |
$transient = self::$transient_notices_name;
|
| 561 |
$notices = get_transient( $transient );
|
| 562 |
$notices = is_array( $notices ) ? $notices : array();
|
| 572 |
}
|
| 573 |
}
|
| 574 |
|
|
|
|
|
|
|
| 575 |
return $notices;
|
| 576 |
}
|
| 577 |
|
| 586 |
$transient = self::$transient_notices_name;
|
| 587 |
set_transient( $transient, $notices, MONTH_IN_SECONDS );
|
| 588 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 589 |
}
|
common/src/Tribe/Assets.php
CHANGED
|
@@ -49,13 +49,15 @@ class Tribe__Assets {
|
|
| 49 |
*/
|
| 50 |
public function register_in_wp( $assets = null ) {
|
| 51 |
if ( is_null( $assets ) ) {
|
| 52 |
-
$assets = $this->
|
| 53 |
}
|
| 54 |
|
| 55 |
if ( ! is_array( $assets ) ) {
|
| 56 |
$assets = [ $assets ];
|
| 57 |
}
|
| 58 |
|
|
|
|
|
|
|
| 59 |
foreach ( $assets as $asset ) {
|
| 60 |
// Asset is already registered.
|
| 61 |
if ( $asset->is_registered ) {
|
|
@@ -95,7 +97,7 @@ class Tribe__Assets {
|
|
| 95 |
if ( did_action( $action ) > 0 ) {
|
| 96 |
$this->enqueue();
|
| 97 |
} else {
|
| 98 |
-
add_action( $action, [ $this, 'enqueue' ], $asset->priority
|
| 99 |
}
|
| 100 |
}
|
| 101 |
}
|
|
@@ -104,14 +106,16 @@ class Tribe__Assets {
|
|
| 104 |
/**
|
| 105 |
* Enqueues registered assets based on their groups.
|
| 106 |
*
|
| 107 |
-
* @since
|
|
|
|
|
|
|
| 108 |
*
|
| 109 |
-
* @
|
| 110 |
*
|
| 111 |
-
* @
|
| 112 |
*/
|
| 113 |
public function enqueue_group( $groups ) {
|
| 114 |
-
$assets
|
| 115 |
$enqueue = [];
|
| 116 |
|
| 117 |
foreach ( $assets as $asset ) {
|
|
@@ -119,11 +123,12 @@ class Tribe__Assets {
|
|
| 119 |
continue;
|
| 120 |
}
|
| 121 |
|
| 122 |
-
$
|
| 123 |
|
| 124 |
-
if ( empty( $
|
| 125 |
continue;
|
| 126 |
}
|
|
|
|
| 127 |
$enqueue[] = $asset->slug;
|
| 128 |
}
|
| 129 |
|
|
@@ -145,11 +150,7 @@ class Tribe__Assets {
|
|
| 145 |
*/
|
| 146 |
public function enqueue( $forcibly_enqueue = null ) {
|
| 147 |
$forcibly_enqueue = array_filter( (array) $forcibly_enqueue );
|
| 148 |
-
|
| 149 |
-
$assets = (array) $this->get( $forcibly_enqueue );
|
| 150 |
-
} else {
|
| 151 |
-
$assets = $this->get();
|
| 152 |
-
}
|
| 153 |
|
| 154 |
foreach ( $assets as $asset ) {
|
| 155 |
// Should this asset be enqueued regardless of the current filter/any conditional requirements?
|
|
@@ -176,7 +177,7 @@ class Tribe__Assets {
|
|
| 176 |
$enqueue = empty( $asset->conditionals );
|
| 177 |
|
| 178 |
if ( ! $enqueue ) {
|
| 179 |
-
// Reset
|
| 180 |
$enqueue = [];
|
| 181 |
|
| 182 |
// Which is the operator?
|
|
@@ -275,81 +276,53 @@ class Tribe__Assets {
|
|
| 275 |
* @return string|false The url to the minified version or false, if file not found.
|
| 276 |
*/
|
| 277 |
public static function maybe_get_min_file( $url ) {
|
| 278 |
-
|
| 279 |
-
|
| 280 |
-
|
| 281 |
-
|
| 282 |
-
|
| 283 |
-
|
| 284 |
-
$urls = [];
|
| 285 |
-
if ( ! isset( $wpmu_plugin_url ) ) {
|
| 286 |
-
$wpmu_plugin_url = set_url_scheme( WPMU_PLUGIN_URL );
|
| 287 |
-
}
|
| 288 |
-
|
| 289 |
-
if ( ! isset( $wp_plugin_url ) ) {
|
| 290 |
-
$wp_plugin_url = set_url_scheme( WP_PLUGIN_URL );
|
| 291 |
-
}
|
| 292 |
-
|
| 293 |
-
if ( ! isset( $wp_content_url ) ) {
|
| 294 |
-
$wp_content_url = set_url_scheme( WP_CONTENT_URL );
|
| 295 |
-
}
|
| 296 |
-
|
| 297 |
-
if ( ! isset( $plugins_url ) ) {
|
| 298 |
-
$plugins_url = plugins_url();
|
| 299 |
-
}
|
| 300 |
-
|
| 301 |
-
if ( ! isset( $base_dirs ) ) {
|
| 302 |
-
$base_dirs[ WPMU_PLUGIN_DIR ] = wp_normalize_path( WPMU_PLUGIN_DIR );
|
| 303 |
-
$base_dirs[ WP_PLUGIN_DIR ] = wp_normalize_path( WP_PLUGIN_DIR );
|
| 304 |
-
$base_dirs[ WP_CONTENT_DIR ] = wp_normalize_path( WP_CONTENT_DIR );
|
| 305 |
-
}
|
| 306 |
|
| 307 |
if ( 0 === strpos( $url, $wpmu_plugin_url ) ) {
|
| 308 |
// URL inside WPMU plugin dir.
|
| 309 |
-
$base_dir =
|
| 310 |
$base_url = $wpmu_plugin_url;
|
| 311 |
} elseif ( 0 === strpos( $url, $wp_plugin_url ) ) {
|
| 312 |
// URL inside WP plugin dir.
|
| 313 |
-
$base_dir =
|
| 314 |
$base_url = $wp_plugin_url;
|
| 315 |
} elseif ( 0 === strpos( $url, $wp_content_url ) ) {
|
| 316 |
// URL inside WP content dir.
|
| 317 |
-
$base_dir =
|
| 318 |
$base_url = $wp_content_url;
|
| 319 |
} elseif ( 0 === strpos( $url, $plugins_url ) ) {
|
| 320 |
-
$base_dir =
|
| 321 |
$base_url = $plugins_url;
|
| 322 |
} else {
|
| 323 |
// Resource needs to be inside wp-content or a plugins dir.
|
| 324 |
return false;
|
| 325 |
}
|
| 326 |
|
| 327 |
-
$script_debug = defined( 'SCRIPT_DEBUG' ) && tribe_is_truthy( SCRIPT_DEBUG );
|
| 328 |
-
|
| 329 |
// Strip the plugin URL and make this relative.
|
| 330 |
$relative_location = str_replace( $base_url, '', $url );
|
| 331 |
|
| 332 |
-
if ( $script_debug ) {
|
| 333 |
-
// Add the actual url after having the min file added.
|
| 334 |
-
$urls[] = $relative_location;
|
| 335 |
-
}
|
| 336 |
-
|
| 337 |
// If needed add the Min Files.
|
| 338 |
-
if (
|
| 339 |
-
|
| 340 |
-
|
| 341 |
-
|
| 342 |
-
}
|
| 343 |
|
| 344 |
-
|
| 345 |
-
|
| 346 |
-
|
| 347 |
}
|
| 348 |
|
|
|
|
|
|
|
|
|
|
| 349 |
// Check for all Urls added to the array.
|
| 350 |
foreach ( $urls as $partial_path ) {
|
| 351 |
$file_path = wp_normalize_path( $base_dir . $partial_path );
|
| 352 |
-
$file_url = $
|
| 353 |
|
| 354 |
if ( file_exists( $file_path ) ) {
|
| 355 |
return $file_url;
|
|
@@ -365,33 +338,30 @@ class Tribe__Assets {
|
|
| 365 |
*
|
| 366 |
* @since 4.3
|
| 367 |
*
|
| 368 |
-
* @param
|
| 369 |
-
* @param
|
| 370 |
-
* @param
|
| 371 |
-
* @param
|
| 372 |
-
* @param
|
| 373 |
-
*
|
| 374 |
-
* @param string|array $arguments {
|
| 375 |
* Optional. Array or string of parameters for this asset.
|
| 376 |
*
|
| 377 |
-
* @type
|
| 378 |
-
* @type int
|
| 379 |
-
* @type string
|
| 380 |
-
* @type string
|
| 381 |
-
* @type array
|
| 382 |
-
* @type string
|
| 383 |
-
* @type string
|
| 384 |
-
* @type bool
|
| 385 |
-
* @type array|object
|
| 386 |
-
*
|
| 387 |
-
*
|
| 388 |
-
* @type string $name Name of the JS variable.
|
| 389 |
-
* @type string|array $data Contents of the JS variable.
|
| 390 |
* }
|
| 391 |
* @type callable[] $conditionals An callable method or an array of them, that will determine if the asset is loaded or not.
|
| 392 |
* }
|
| 393 |
*
|
| 394 |
-
* @return
|
| 395 |
*/
|
| 396 |
public function register( $origin, $slug, $file, $deps = [], $action = null, $arguments = [] ) {
|
| 397 |
// Prevent weird stuff here.
|
|
@@ -473,7 +443,7 @@ class Tribe__Assets {
|
|
| 473 |
}
|
| 474 |
|
| 475 |
// If asset type is wrong don't register.
|
| 476 |
-
if ( ! in_array( $asset->type, [ 'js', 'css' ]
|
| 477 |
return false;
|
| 478 |
}
|
| 479 |
|
|
@@ -543,6 +513,9 @@ class Tribe__Assets {
|
|
| 543 |
// Set the Asset on the array of notices.
|
| 544 |
$this->assets[ $slug ] = $asset;
|
| 545 |
|
|
|
|
|
|
|
|
|
|
| 546 |
// Return the Slug because it might be modified.
|
| 547 |
return $asset;
|
| 548 |
}
|
|
@@ -604,55 +577,18 @@ class Tribe__Assets {
|
|
| 604 |
* Get the Asset Object configuration.
|
| 605 |
*
|
| 606 |
* @since 4.3
|
| 607 |
-
* @since 4.11.0 Added $sort param.
|
| 608 |
*
|
| 609 |
-
* @param
|
| 610 |
-
* @param boolean $sort If we should do any sorting before returning.
|
| 611 |
*
|
| 612 |
-
* @return
|
| 613 |
-
* it was not in the array of objects.
|
| 614 |
*/
|
| 615 |
-
public function get( $slug = null
|
|
|
|
|
|
|
| 616 |
if ( is_null( $slug ) ) {
|
| 617 |
-
if ( $sort ) {
|
| 618 |
-
$cache_key_count = __METHOD__ . ':count';
|
| 619 |
-
// Sorts by priority.
|
| 620 |
-
$cache_count = tribe_get_var( $cache_key_count, 0 );
|
| 621 |
-
$count = count( $this->assets );
|
| 622 |
-
|
| 623 |
-
if ( $count !== $cache_count ) {
|
| 624 |
-
uasort( $this->assets, 'tribe_sort_by_priority' );
|
| 625 |
-
tribe_set_var( $cache_key_count, $count );
|
| 626 |
-
}
|
| 627 |
-
}
|
| 628 |
return $this->assets;
|
| 629 |
}
|
| 630 |
|
| 631 |
-
// If slug is an array we return all of those.
|
| 632 |
-
if ( is_array( $slug ) ) {
|
| 633 |
-
$assets = [];
|
| 634 |
-
foreach ( $slug as $asset_slug ) {
|
| 635 |
-
$asset_slug = sanitize_title_with_dashes( $asset_slug );
|
| 636 |
-
// Skip empty assets.
|
| 637 |
-
if ( empty( $this->assets[ $asset_slug ] ) ) {
|
| 638 |
-
continue;
|
| 639 |
-
}
|
| 640 |
-
|
| 641 |
-
$assets[ $asset_slug ] = $this->assets[ $asset_slug ];
|
| 642 |
-
}
|
| 643 |
-
|
| 644 |
-
if ( empty( $assets ) ) {
|
| 645 |
-
return null;
|
| 646 |
-
}
|
| 647 |
-
|
| 648 |
-
if ( $sort ) {
|
| 649 |
-
// Sorts by priority.
|
| 650 |
-
uasort( $assets, 'tribe_sort_by_priority' );
|
| 651 |
-
}
|
| 652 |
-
|
| 653 |
-
return $assets;
|
| 654 |
-
}
|
| 655 |
-
|
| 656 |
// Prevent weird stuff here.
|
| 657 |
$slug = sanitize_title_with_dashes( $slug );
|
| 658 |
|
|
@@ -663,10 +599,24 @@ class Tribe__Assets {
|
|
| 663 |
return null;
|
| 664 |
}
|
| 665 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 666 |
/**
|
| 667 |
* Checks if an Asset exists.
|
| 668 |
*
|
| 669 |
-
* @param string
|
| 670 |
*
|
| 671 |
* @return bool
|
| 672 |
*/
|
| 49 |
*/
|
| 50 |
public function register_in_wp( $assets = null ) {
|
| 51 |
if ( is_null( $assets ) ) {
|
| 52 |
+
$assets = $this->assets;
|
| 53 |
}
|
| 54 |
|
| 55 |
if ( ! is_array( $assets ) ) {
|
| 56 |
$assets = [ $assets ];
|
| 57 |
}
|
| 58 |
|
| 59 |
+
uasort( $assets, [ $this, 'order_by_priority' ] );
|
| 60 |
+
|
| 61 |
foreach ( $assets as $asset ) {
|
| 62 |
// Asset is already registered.
|
| 63 |
if ( $asset->is_registered ) {
|
| 97 |
if ( did_action( $action ) > 0 ) {
|
| 98 |
$this->enqueue();
|
| 99 |
} else {
|
| 100 |
+
add_action( $action, [ $this, 'enqueue' ], $asset->priority );
|
| 101 |
}
|
| 102 |
}
|
| 103 |
}
|
| 106 |
/**
|
| 107 |
* Enqueues registered assets based on their groups.
|
| 108 |
*
|
| 109 |
+
* @since 4.7
|
| 110 |
+
*
|
| 111 |
+
* @uses self::enqueue
|
| 112 |
*
|
| 113 |
+
* @param string|array $groups Which groups will be enqueued.
|
| 114 |
*
|
| 115 |
+
* @return void
|
| 116 |
*/
|
| 117 |
public function enqueue_group( $groups ) {
|
| 118 |
+
$assets = $this->get();
|
| 119 |
$enqueue = [];
|
| 120 |
|
| 121 |
foreach ( $assets as $asset ) {
|
| 123 |
continue;
|
| 124 |
}
|
| 125 |
|
| 126 |
+
$instersect = array_intersect( (array) $groups, $asset->groups );
|
| 127 |
|
| 128 |
+
if ( empty( $instersect ) ) {
|
| 129 |
continue;
|
| 130 |
}
|
| 131 |
+
|
| 132 |
$enqueue[] = $asset->slug;
|
| 133 |
}
|
| 134 |
|
| 150 |
*/
|
| 151 |
public function enqueue( $forcibly_enqueue = null ) {
|
| 152 |
$forcibly_enqueue = array_filter( (array) $forcibly_enqueue );
|
| 153 |
+
$assets = $this->get();
|
|
|
|
|
|
|
|
|
|
|
|
|
| 154 |
|
| 155 |
foreach ( $assets as $asset ) {
|
| 156 |
// Should this asset be enqueued regardless of the current filter/any conditional requirements?
|
| 177 |
$enqueue = empty( $asset->conditionals );
|
| 178 |
|
| 179 |
if ( ! $enqueue ) {
|
| 180 |
+
// Reset Enqeue
|
| 181 |
$enqueue = [];
|
| 182 |
|
| 183 |
// Which is the operator?
|
| 276 |
* @return string|false The url to the minified version or false, if file not found.
|
| 277 |
*/
|
| 278 |
public static function maybe_get_min_file( $url ) {
|
| 279 |
+
$urls = [];
|
| 280 |
+
$wpmu_plugin_url = set_url_scheme( WPMU_PLUGIN_URL );
|
| 281 |
+
$wp_plugin_url = set_url_scheme( WP_PLUGIN_URL );
|
| 282 |
+
$wp_content_url = set_url_scheme( WP_CONTENT_URL );
|
| 283 |
+
$plugins_url = plugins_url();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 284 |
|
| 285 |
if ( 0 === strpos( $url, $wpmu_plugin_url ) ) {
|
| 286 |
// URL inside WPMU plugin dir.
|
| 287 |
+
$base_dir = wp_normalize_path( WPMU_PLUGIN_DIR );
|
| 288 |
$base_url = $wpmu_plugin_url;
|
| 289 |
} elseif ( 0 === strpos( $url, $wp_plugin_url ) ) {
|
| 290 |
// URL inside WP plugin dir.
|
| 291 |
+
$base_dir = wp_normalize_path( WP_PLUGIN_DIR );
|
| 292 |
$base_url = $wp_plugin_url;
|
| 293 |
} elseif ( 0 === strpos( $url, $wp_content_url ) ) {
|
| 294 |
// URL inside WP content dir.
|
| 295 |
+
$base_dir = wp_normalize_path( WP_CONTENT_DIR );
|
| 296 |
$base_url = $wp_content_url;
|
| 297 |
} elseif ( 0 === strpos( $url, $plugins_url ) ) {
|
| 298 |
+
$base_dir = wp_normalize_path( WP_PLUGIN_DIR );
|
| 299 |
$base_url = $plugins_url;
|
| 300 |
} else {
|
| 301 |
// Resource needs to be inside wp-content or a plugins dir.
|
| 302 |
return false;
|
| 303 |
}
|
| 304 |
|
|
|
|
|
|
|
| 305 |
// Strip the plugin URL and make this relative.
|
| 306 |
$relative_location = str_replace( $base_url, '', $url );
|
| 307 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 308 |
// If needed add the Min Files.
|
| 309 |
+
if ( ! defined( 'SCRIPT_DEBUG' ) || SCRIPT_DEBUG === false ) {
|
| 310 |
+
if ( substr( $relative_location, - 3, 3 ) === '.js' ) {
|
| 311 |
+
$urls[] = substr_replace( $relative_location, '.min', - 3, 0 );
|
| 312 |
+
}
|
|
|
|
| 313 |
|
| 314 |
+
if ( substr( $relative_location, - 4, 4 ) === '.css' ) {
|
| 315 |
+
$urls[] = substr_replace( $relative_location, '.min', - 4, 0 );
|
| 316 |
+
}
|
| 317 |
}
|
| 318 |
|
| 319 |
+
// Add the actual url after having the min file added.
|
| 320 |
+
$urls[] = $relative_location;
|
| 321 |
+
|
| 322 |
// Check for all Urls added to the array.
|
| 323 |
foreach ( $urls as $partial_path ) {
|
| 324 |
$file_path = wp_normalize_path( $base_dir . $partial_path );
|
| 325 |
+
$file_url = plugins_url( basename( $file_path ), $file_path );
|
| 326 |
|
| 327 |
if ( file_exists( $file_path ) ) {
|
| 328 |
return $file_url;
|
| 338 |
*
|
| 339 |
* @since 4.3
|
| 340 |
*
|
| 341 |
+
* @param object $origin The main Object for the plugin you are enqueueing the script/style for.
|
| 342 |
+
* @param string $slug Slug to save the asset.
|
| 343 |
+
* @param string $file Which file will be loaded, either CSS or JS.
|
| 344 |
+
* @param array $deps Dependencies.
|
| 345 |
+
* @param string|null $action (Optional) A WordPress Action, if set needs to happen after: `wp_enqueue_scripts`, `admin_enqueue_scripts`, or `login_enqueue_scripts`.
|
| 346 |
+
* @param string|array $arguments {
|
|
|
|
| 347 |
* Optional. Array or string of parameters for this asset.
|
| 348 |
*
|
| 349 |
+
* @type string|null $action Which WordPress action this asset will be loaded on.
|
| 350 |
+
* @type int $priority Priority in which this asset will be loaded on the WordPress action.
|
| 351 |
+
* @type string $file The relative path to the File that will be enqueued, uses the $origin to get the full path.
|
| 352 |
+
* @type string $type Asset Type, `js` or `css`.
|
| 353 |
+
* @type array $deps An array of other asset as dependencies.
|
| 354 |
+
* @type string $version Version number, used for cache expiring.
|
| 355 |
+
* @type string $media Used only for CSS, when to load the file.
|
| 356 |
+
* @type bool $in_footer A boolean determining if the javascript should be loaded on the footer.
|
| 357 |
+
* @type array|object $localize Variables needed on the JavaScript side {
|
| 358 |
+
* @type string $name Name of the JS variable.
|
| 359 |
+
* @type string|array $data Contents of the JS variable.
|
|
|
|
|
|
|
| 360 |
* }
|
| 361 |
* @type callable[] $conditionals An callable method or an array of them, that will determine if the asset is loaded or not.
|
| 362 |
* }
|
| 363 |
*
|
| 364 |
+
* @return string
|
| 365 |
*/
|
| 366 |
public function register( $origin, $slug, $file, $deps = [], $action = null, $arguments = [] ) {
|
| 367 |
// Prevent weird stuff here.
|
| 443 |
}
|
| 444 |
|
| 445 |
// If asset type is wrong don't register.
|
| 446 |
+
if ( ! in_array( $asset->type, [ 'js', 'css' ] ) ) {
|
| 447 |
return false;
|
| 448 |
}
|
| 449 |
|
| 513 |
// Set the Asset on the array of notices.
|
| 514 |
$this->assets[ $slug ] = $asset;
|
| 515 |
|
| 516 |
+
// Sorts by priority.
|
| 517 |
+
uasort( $this->assets, [ $this, 'order_by_priority' ] );
|
| 518 |
+
|
| 519 |
// Return the Slug because it might be modified.
|
| 520 |
return $asset;
|
| 521 |
}
|
| 577 |
* Get the Asset Object configuration.
|
| 578 |
*
|
| 579 |
* @since 4.3
|
|
|
|
| 580 |
*
|
| 581 |
+
* @param string $slug Slug of the Asset.
|
|
|
|
| 582 |
*
|
| 583 |
+
* @return bool
|
|
|
|
| 584 |
*/
|
| 585 |
+
public function get( $slug = null ) {
|
| 586 |
+
uasort( $this->assets, [ $this, 'order_by_priority' ] );
|
| 587 |
+
|
| 588 |
if ( is_null( $slug ) ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 589 |
return $this->assets;
|
| 590 |
}
|
| 591 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 592 |
// Prevent weird stuff here.
|
| 593 |
$slug = sanitize_title_with_dashes( $slug );
|
| 594 |
|
| 599 |
return null;
|
| 600 |
}
|
| 601 |
|
| 602 |
+
/**
|
| 603 |
+
* Add the Priority ordering, which was causing an issue of not respecting which order stuff was registered.
|
| 604 |
+
*
|
| 605 |
+
* @since 4.7
|
| 606 |
+
*
|
| 607 |
+
* @param object $a First Subject to compare.
|
| 608 |
+
* @param object $b Second subject to compare.
|
| 609 |
+
*
|
| 610 |
+
* @return boolean
|
| 611 |
+
*/
|
| 612 |
+
public function order_by_priority( $a, $b ) {
|
| 613 |
+
return (int) $a->priority === (int) $b->priority ? 0 : (int) $a->priority > (int) $b->priority;
|
| 614 |
+
}
|
| 615 |
+
|
| 616 |
/**
|
| 617 |
* Checks if an Asset exists.
|
| 618 |
*
|
| 619 |
+
* @param string $slug Slug of the Asset.
|
| 620 |
*
|
| 621 |
* @return bool
|
| 622 |
*/
|
common/src/Tribe/Autoloader.php
CHANGED
|
@@ -121,14 +121,6 @@
|
|
| 121 |
public function register_prefix( $prefix, $root_dir, $slug = '' ) {
|
| 122 |
$root_dir = $this->normalize_root_dir( $root_dir );
|
| 123 |
|
| 124 |
-
// Determine if we need to normalize the $prefix.
|
| 125 |
-
$is_namespaced = false !== strpos( $prefix, '\\' );
|
| 126 |
-
|
| 127 |
-
if ( $is_namespaced ) {
|
| 128 |
-
// If the prefix is a namespace, then normalize it.
|
| 129 |
-
$prefix = trim( $prefix, '\\' ) . '\\';
|
| 130 |
-
}
|
| 131 |
-
|
| 132 |
if ( ! isset( $this->prefixes[ $prefix ] ) ) {
|
| 133 |
$this->prefixes[ $prefix ] = array();
|
| 134 |
}
|
|
@@ -171,20 +163,11 @@
|
|
| 171 |
|
| 172 |
protected function get_prefixed_path( $class ) {
|
| 173 |
foreach ( $this->prefixes as $prefix => $dirs ) {
|
| 174 |
-
$is_namespaced = false !== strpos( $prefix, '\\' );
|
| 175 |
-
|
| 176 |
if ( strpos( $class, $prefix ) !== 0 ) {
|
| 177 |
continue;
|
| 178 |
}
|
| 179 |
-
|
| 180 |
$class_name = str_replace( $prefix, '', $class );
|
| 181 |
-
|
| 182 |
-
if ( ! $is_namespaced ) {
|
| 183 |
-
$class_path_frag = implode( '/', explode( $this->dir_separator, $class_name ) ) . '.php';
|
| 184 |
-
} else {
|
| 185 |
-
$class_path_frag = implode( '/', explode( '\\', $class_name ) ) . '.php';
|
| 186 |
-
}
|
| 187 |
-
|
| 188 |
foreach ( $dirs as $dir ) {
|
| 189 |
$path = $dir . '/' . $class_path_frag;
|
| 190 |
if ( ! file_exists( $path ) ) {
|
| 121 |
public function register_prefix( $prefix, $root_dir, $slug = '' ) {
|
| 122 |
$root_dir = $this->normalize_root_dir( $root_dir );
|
| 123 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 124 |
if ( ! isset( $this->prefixes[ $prefix ] ) ) {
|
| 125 |
$this->prefixes[ $prefix ] = array();
|
| 126 |
}
|
| 163 |
|
| 164 |
protected function get_prefixed_path( $class ) {
|
| 165 |
foreach ( $this->prefixes as $prefix => $dirs ) {
|
|
|
|
|
|
|
| 166 |
if ( strpos( $class, $prefix ) !== 0 ) {
|
| 167 |
continue;
|
| 168 |
}
|
|
|
|
| 169 |
$class_name = str_replace( $prefix, '', $class );
|
| 170 |
+
$class_path_frag = implode( '/', explode( $this->dir_separator, $class_name ) ) . '.php';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 171 |
foreach ( $dirs as $dir ) {
|
| 172 |
$path = $dir . '/' . $class_path_frag;
|
| 173 |
if ( ! file_exists( $path ) ) {
|
common/src/Tribe/Cache.php
CHANGED
|
@@ -10,41 +10,23 @@
|
|
| 10 |
* When used in its ArrayAccess API the cache will provide non persistent storage.
|
| 11 |
*/
|
| 12 |
class Tribe__Cache implements ArrayAccess {
|
| 13 |
-
const
|
| 14 |
-
|
| 15 |
-
const NO_EXPIRATION = 0;
|
| 16 |
-
|
| 17 |
-
const NON_PERSISTENT = -1;
|
| 18 |
|
| 19 |
/**
|
| 20 |
* @var array
|
| 21 |
*/
|
| 22 |
-
protected $non_persistent_keys =
|
| 23 |
-
|
| 24 |
-
/**
|
| 25 |
-
* Bootstrap hook
|
| 26 |
-
*
|
| 27 |
-
* @since 4.11.0
|
| 28 |
-
*/
|
| 29 |
-
public function hook() {
|
| 30 |
-
if ( ! wp_next_scheduled( self::SCHEDULED_EVENT_DELETE_TRANSIENT ) ) {
|
| 31 |
-
wp_schedule_event( time(), 'twicedaily', self::SCHEDULED_EVENT_DELETE_TRANSIENT );
|
| 32 |
-
}
|
| 33 |
-
|
| 34 |
-
add_action( self::SCHEDULED_EVENT_DELETE_TRANSIENT, [ $this, 'delete_expired_transients' ] );
|
| 35 |
-
|
| 36 |
-
add_action( 'shutdown', [ $this, 'maybe_delete_expired_transients' ] );
|
| 37 |
-
}
|
| 38 |
|
| 39 |
public static function setup() {
|
| 40 |
-
wp_cache_add_non_persistent_groups(
|
| 41 |
}
|
| 42 |
|
| 43 |
/**
|
| 44 |
-
* @param string
|
| 45 |
-
* @param mixed
|
| 46 |
-
* @param int
|
| 47 |
-
* @param string
|
| 48 |
*
|
| 49 |
* @return bool
|
| 50 |
*/
|
|
@@ -55,13 +37,13 @@ class Tribe__Cache implements ArrayAccess {
|
|
| 55 |
* Filters the expiration for cache objects to provide the ability
|
| 56 |
* to make non-persistent objects be treated as persistent.
|
| 57 |
*
|
| 58 |
-
* @
|
|
|
|
|
|
|
|
|
|
|
|
|
| 59 |
*
|
| 60 |
-
* @
|
| 61 |
-
* @param string $id Cache ID.
|
| 62 |
-
* @param mixed $value Cache value.
|
| 63 |
-
* @param string|array $expiration_trigger Action that triggers automatic expiration.
|
| 64 |
-
* @param string $key Unique cache key based on Cache ID and expiration trigger last run time.
|
| 65 |
*/
|
| 66 |
$expiration = apply_filters( 'tribe_cache_expiration', $expiration, $id, $value, $expiration_trigger, $key );
|
| 67 |
|
|
@@ -79,10 +61,10 @@ class Tribe__Cache implements ArrayAccess {
|
|
| 79 |
}
|
| 80 |
|
| 81 |
/**
|
| 82 |
-
* @param
|
| 83 |
-
* @param
|
| 84 |
-
* @param int
|
| 85 |
-
* @param string
|
| 86 |
*
|
| 87 |
* @return bool
|
| 88 |
*/
|
|
@@ -95,18 +77,17 @@ class Tribe__Cache implements ArrayAccess {
|
|
| 95 |
*
|
| 96 |
* Note: When a default value or callback is specified, this value gets set in the cache.
|
| 97 |
*
|
| 98 |
-
* @param string
|
| 99 |
-
* @param string
|
| 100 |
-
* @param mixed
|
| 101 |
-
* @param int
|
| 102 |
-
* @param mixed
|
| 103 |
*
|
| 104 |
* @return mixed
|
| 105 |
*/
|
| 106 |
-
public function get( $id, $expiration_trigger = '', $default = false, $expiration = 0, $args =
|
| 107 |
-
$
|
| 108 |
-
$
|
| 109 |
-
$value = wp_cache_get( $this->get_id( $id, $expiration_trigger ), $group );
|
| 110 |
|
| 111 |
// Value found.
|
| 112 |
if ( false !== $value ) {
|
|
@@ -130,8 +111,8 @@ class Tribe__Cache implements ArrayAccess {
|
|
| 130 |
}
|
| 131 |
|
| 132 |
/**
|
| 133 |
-
* @param string
|
| 134 |
-
* @param string
|
| 135 |
*
|
| 136 |
* @return mixed
|
| 137 |
*/
|
|
@@ -140,8 +121,8 @@ class Tribe__Cache implements ArrayAccess {
|
|
| 140 |
}
|
| 141 |
|
| 142 |
/**
|
| 143 |
-
* @param string
|
| 144 |
-
* @param string
|
| 145 |
*
|
| 146 |
* @return bool
|
| 147 |
*/
|
|
@@ -150,8 +131,8 @@ class Tribe__Cache implements ArrayAccess {
|
|
| 150 |
}
|
| 151 |
|
| 152 |
/**
|
| 153 |
-
* @param string
|
| 154 |
-
* @param string
|
| 155 |
*
|
| 156 |
* @return bool
|
| 157 |
*/
|
|
@@ -160,116 +141,16 @@ class Tribe__Cache implements ArrayAccess {
|
|
| 160 |
}
|
| 161 |
|
| 162 |
/**
|
| 163 |
-
*
|
| 164 |
-
*
|
| 165 |
-
* This uses a modification of the the query from https://core.trac.wordpress.org/ticket/20316
|
| 166 |
-
*
|
| 167 |
-
* @since 4.11.0
|
| 168 |
-
*
|
| 169 |
-
* @return void Just execute the database SQL no return required.
|
| 170 |
-
*/
|
| 171 |
-
public function delete_expired_transients() {
|
| 172 |
-
if ( tribe_get_var( 'has_deleted_expired_transients', false ) ) {
|
| 173 |
-
return;
|
| 174 |
-
}
|
| 175 |
-
|
| 176 |
-
global $wpdb;
|
| 177 |
-
|
| 178 |
-
$time = time();
|
| 179 |
-
|
| 180 |
-
$sql = "
|
| 181 |
-
DELETE
|
| 182 |
-
a,
|
| 183 |
-
b
|
| 184 |
-
FROM
|
| 185 |
-
{$wpdb->options} a
|
| 186 |
-
INNER JOIN {$wpdb->options} b
|
| 187 |
-
ON b.option_name = CONCAT( '_transient_timeout_', SUBSTRING( a.option_name, 12 ) )
|
| 188 |
-
AND b.option_value < {$time}
|
| 189 |
-
WHERE
|
| 190 |
-
a.option_name LIKE '\_transient\_tribe\_%'
|
| 191 |
-
AND a.option_name NOT LIKE '\_transient\_timeout\_tribe\_%'
|
| 192 |
-
";
|
| 193 |
-
|
| 194 |
-
/**
|
| 195 |
-
* Allow third party filtering of the SQL used for deleting expired transients.
|
| 196 |
-
*
|
| 197 |
-
* @since 4.11.5
|
| 198 |
-
*
|
| 199 |
-
* @param string $sql The SQL we execute to delete all the expired transients.
|
| 200 |
-
* @param int $time Time we are using to determine what is expired.
|
| 201 |
-
*/
|
| 202 |
-
$sql = apply_filters( 'tribe_cache_delete_expired_transients_sql', $sql, $time );
|
| 203 |
-
|
| 204 |
-
if ( empty( $sql ) ) {
|
| 205 |
-
return;
|
| 206 |
-
}
|
| 207 |
-
|
| 208 |
-
$wpdb->query( $sql );
|
| 209 |
-
|
| 210 |
-
// Set the variable to prevent this call from running twice.
|
| 211 |
-
tribe_set_var( 'has_deleted_expired_transients', true );
|
| 212 |
-
}
|
| 213 |
-
|
| 214 |
-
/**
|
| 215 |
-
* Flag if we should delete
|
| 216 |
-
*
|
| 217 |
-
* @since 4.11.5
|
| 218 |
-
*
|
| 219 |
-
* @param boolean $value If we should delete transients or not on shutdown.
|
| 220 |
-
*
|
| 221 |
-
* @return void No return for setting the flag.
|
| 222 |
-
*/
|
| 223 |
-
public function flag_required_delete_transients( $value = true ) {
|
| 224 |
-
tribe_set_var( 'should_delete_expired_transients', $value );
|
| 225 |
-
}
|
| 226 |
-
|
| 227 |
-
/**
|
| 228 |
-
* Runs on hook `shutdown` and will delete transients on the end of the request.
|
| 229 |
-
*
|
| 230 |
-
* @since 4.11.5
|
| 231 |
-
*
|
| 232 |
-
* @return void No return for action hook method.
|
| 233 |
-
*/
|
| 234 |
-
public function maybe_delete_expired_transients() {
|
| 235 |
-
if ( ! tribe_get_var( 'should_delete_expired_transients', false ) ) {
|
| 236 |
-
return;
|
| 237 |
-
}
|
| 238 |
-
|
| 239 |
-
$this->delete_expired_transients();
|
| 240 |
-
}
|
| 241 |
-
|
| 242 |
-
/**
|
| 243 |
-
* @param string $key
|
| 244 |
-
* @param string|array $expiration_trigger
|
| 245 |
*
|
| 246 |
* @return string
|
| 247 |
*/
|
| 248 |
public function get_id( $key, $expiration_trigger = '' ) {
|
| 249 |
-
|
| 250 |
-
$triggers = $expiration_trigger;
|
| 251 |
-
} else {
|
| 252 |
-
$triggers = array_filter( explode( '|', $expiration_trigger ) );
|
| 253 |
-
}
|
| 254 |
-
|
| 255 |
-
$last = 0;
|
| 256 |
-
foreach ( $triggers as $trigger ) {
|
| 257 |
-
// Bail on empty trigger otherwise it creates a `tribe_last_` opt on the DB.
|
| 258 |
-
if ( empty( $trigger ) ) {
|
| 259 |
-
continue;
|
| 260 |
-
}
|
| 261 |
-
|
| 262 |
-
$occurrence = $this->get_last_occurrence( $trigger );
|
| 263 |
-
|
| 264 |
-
if ( $occurrence > $last ) {
|
| 265 |
-
$last = $occurrence;
|
| 266 |
-
}
|
| 267 |
-
}
|
| 268 |
-
|
| 269 |
-
$last = empty( $last ) ? '' : $last;
|
| 270 |
$id = $key . $last;
|
| 271 |
-
if ( strlen( $id ) >
|
| 272 |
-
$id =
|
| 273 |
}
|
| 274 |
|
| 275 |
return $id;
|
|
@@ -278,33 +159,14 @@ class Tribe__Cache implements ArrayAccess {
|
|
| 278 |
/**
|
| 279 |
* Returns the time of an action last occurrence.
|
| 280 |
*
|
| 281 |
-
* @since 4.9.14 Changed the return value type from `int` to `float`.
|
| 282 |
-
*
|
| 283 |
* @param string $action The action to return the time for.
|
| 284 |
*
|
|
|
|
|
|
|
| 285 |
* @return float The time (microtime) an action last occurred, or the current microtime if it never occurred.
|
| 286 |
*/
|
| 287 |
public function get_last_occurrence( $action ) {
|
| 288 |
-
|
| 289 |
-
|
| 290 |
-
$cache_last_actions = tribe_get_var( $cache_var_name, [] );
|
| 291 |
-
|
| 292 |
-
if ( isset( $cache_last_actions[ $action ] ) ) {
|
| 293 |
-
return $cache_last_actions[ $action ];
|
| 294 |
-
}
|
| 295 |
-
|
| 296 |
-
$last_action = (float) get_option( 'tribe_last_' . $action, null );
|
| 297 |
-
|
| 298 |
-
if ( ! $last_action ) {
|
| 299 |
-
$last_action = microtime( true );
|
| 300 |
-
$this->set_last_occurrence( $action, $last_action );
|
| 301 |
-
}
|
| 302 |
-
|
| 303 |
-
$cache_last_actions[ $action ] = (float) $last_action;
|
| 304 |
-
|
| 305 |
-
tribe_set_var( $cache_var_name, $cache_last_actions );
|
| 306 |
-
|
| 307 |
-
return $cache_last_actions[ $action ];
|
| 308 |
}
|
| 309 |
|
| 310 |
/**
|
|
@@ -312,23 +174,14 @@ class Tribe__Cache implements ArrayAccess {
|
|
| 312 |
*
|
| 313 |
* @since 4.9.14 Changed the type of the time stored from an `int` to a `float`.
|
| 314 |
*
|
| 315 |
-
* @param string
|
| 316 |
-
* @param int
|
| 317 |
-
*
|
| 318 |
-
* @return boolean IF we were able to set the last occurrence or not.
|
| 319 |
*/
|
| 320 |
public function set_last_occurrence( $action, $timestamp = 0 ) {
|
| 321 |
if ( empty( $timestamp ) ) {
|
| 322 |
$timestamp = microtime( true );
|
| 323 |
}
|
| 324 |
-
|
| 325 |
-
|
| 326 |
-
// For performance reasons we will only expire cache once per request, when needed.
|
| 327 |
-
if ( $updated ) {
|
| 328 |
-
$this->flag_required_delete_transients( true );
|
| 329 |
-
}
|
| 330 |
-
|
| 331 |
-
return $updated;
|
| 332 |
}
|
| 333 |
|
| 334 |
/**
|
|
@@ -336,14 +189,13 @@ class Tribe__Cache implements ArrayAccess {
|
|
| 336 |
*
|
| 337 |
* @param mixed $components Either a single component of the key or an array of key components.
|
| 338 |
* @param string $prefix
|
| 339 |
-
* @param bool $sort
|
| 340 |
-
* `true`.
|
| 341 |
*
|
| 342 |
* @return string The resulting key.
|
| 343 |
*/
|
| 344 |
public function make_key( $components, $prefix = '', $sort = true ) {
|
| 345 |
-
$key
|
| 346 |
-
$components = is_array( $components ) ? $components :
|
| 347 |
foreach ( $components as $component ) {
|
| 348 |
if ( $sort && is_array( $component ) ) {
|
| 349 |
$is_associative = count( array_filter( array_keys( $component ), 'is_numeric' ) ) < count( array_keys( $component ) );
|
|
@@ -360,140 +212,65 @@ class Tribe__Cache implements ArrayAccess {
|
|
| 360 |
}
|
| 361 |
|
| 362 |
/**
|
| 363 |
-
* Whether a offset exists
|
| 364 |
-
*
|
| 365 |
-
* @since 4.11.0
|
| 366 |
*
|
| 367 |
* @link http://php.net/manual/en/arrayaccess.offsetexists.php
|
| 368 |
-
*
|
| 369 |
-
*
|
| 370 |
-
*
|
| 371 |
-
* @return boolean
|
|
|
|
|
|
|
|
|
|
|
|
|
| 372 |
*/
|
| 373 |
public function offsetExists( $offset ) {
|
| 374 |
-
|
| 375 |
-
|
| 376 |
-
return isset( $flipped[ $offset ] );
|
| 377 |
}
|
| 378 |
|
| 379 |
/**
|
| 380 |
-
* Offset to retrieve
|
| 381 |
*
|
| 382 |
* @link http://php.net/manual/en/arrayaccess.offsetget.php
|
| 383 |
-
*
|
| 384 |
-
*
|
| 385 |
-
*
|
| 386 |
-
* @param mixed $offset The offset to retrieve.
|
| 387 |
-
*
|
| 388 |
* @return mixed Can return all value types.
|
|
|
|
| 389 |
*/
|
| 390 |
public function offsetGet( $offset ) {
|
| 391 |
return $this->get( $offset );
|
| 392 |
}
|
| 393 |
|
| 394 |
/**
|
| 395 |
-
* Offset to set
|
| 396 |
-
*
|
| 397 |
-
* @since 4.11.0
|
| 398 |
*
|
| 399 |
* @link http://php.net/manual/en/arrayaccess.offsetset.php
|
| 400 |
-
*
|
| 401 |
-
*
|
| 402 |
-
*
|
| 403 |
-
*
|
|
|
|
|
|
|
| 404 |
* @return void
|
|
|
|
| 405 |
*/
|
| 406 |
public function offsetSet( $offset, $value ) {
|
| 407 |
$this->set( $offset, $value, self::NON_PERSISTENT );
|
| 408 |
}
|
| 409 |
|
| 410 |
/**
|
| 411 |
-
* Offset to unset
|
| 412 |
-
*
|
| 413 |
-
* @since 4.11.0
|
| 414 |
*
|
| 415 |
* @link http://php.net/manual/en/arrayaccess.offsetunset.php
|
| 416 |
-
*
|
| 417 |
-
*
|
| 418 |
-
*
|
| 419 |
* @return void
|
|
|
|
| 420 |
*/
|
| 421 |
public function offsetUnset( $offset ) {
|
| 422 |
$this->delete( $offset );
|
| 423 |
}
|
|
|
|
| 424 |
|
| 425 |
-
/**
|
| 426 |
-
* Warms up the caches for a collection of posts.
|
| 427 |
-
*
|
| 428 |
-
* @since 4.10.2
|
| 429 |
-
*
|
| 430 |
-
* @param array|int $post_ids A post ID, or a collection of post IDs.
|
| 431 |
-
* @param bool $update_post_meta_cache Whether to warm-up the post meta cache for the posts or not.
|
| 432 |
-
*/
|
| 433 |
-
public function warmup_post_caches( $post_ids, $update_post_meta_cache = false ) {
|
| 434 |
-
if ( empty( $post_ids ) ) {
|
| 435 |
-
return;
|
| 436 |
-
}
|
| 437 |
-
|
| 438 |
-
$post_ids = (array) $post_ids;
|
| 439 |
-
|
| 440 |
-
global $wpdb;
|
| 441 |
-
|
| 442 |
-
$already_cached_ids = [];
|
| 443 |
-
foreach ( $post_ids as $post_id ) {
|
| 444 |
-
if ( wp_cache_get( $post_id, 'posts' ) instanceof \WP_Post ) {
|
| 445 |
-
$already_cached_ids[] = $post_id;
|
| 446 |
-
}
|
| 447 |
-
}
|
| 448 |
-
|
| 449 |
-
$required = array_diff( $post_ids, $already_cached_ids );
|
| 450 |
-
|
| 451 |
-
if ( empty( $required ) ) {
|
| 452 |
-
return;
|
| 453 |
-
}
|
| 454 |
-
|
| 455 |
-
/** @var Tribe__Feature_Detection $feature_detection */
|
| 456 |
-
$feature_detection = tribe( 'feature-detection' );
|
| 457 |
-
$limit = $feature_detection->mysql_limit_for_example( 'post_result' );
|
| 458 |
-
|
| 459 |
-
/**
|
| 460 |
-
* Filters the LIMIT that should be used to warm-up post caches and postmeta caches (if the
|
| 461 |
-
* `$update_post_meta_cache` parameter is `true`).
|
| 462 |
-
*
|
| 463 |
-
* Lower this value on less powerful hosts. Return `0` to disable the warm-up completely, and `-1` to remove the
|
| 464 |
-
* limit (not recommended).
|
| 465 |
-
*
|
| 466 |
-
* @since 4.10.2
|
| 467 |
-
*
|
| 468 |
-
* @param int $limit The number of posts whose caches will be warmed up, per query.
|
| 469 |
-
*/
|
| 470 |
-
$limit = (int) apply_filters( 'tribe_cache_warmup_post_cache_limit', min( $limit, count( $post_ids ) ) );
|
| 471 |
-
|
| 472 |
-
if ( 0 === $limit ) {
|
| 473 |
-
// Warmup disabled.
|
| 474 |
-
return;
|
| 475 |
-
}
|
| 476 |
-
|
| 477 |
-
$buffer = $post_ids;
|
| 478 |
-
$page = 0;
|
| 479 |
-
|
| 480 |
-
do {
|
| 481 |
-
$limit_clause = $limit < 0 ? sprintf( 'LIMIT %d,%d', $limit * $page, $limit ) : '';
|
| 482 |
-
$page++;
|
| 483 |
-
$these_ids = array_splice( $buffer, 0, $limit );
|
| 484 |
-
$interval = implode( ',', array_map( 'absint', $these_ids ) );
|
| 485 |
-
$posts_query = "SELECT * FROM {$wpdb->posts} WHERE ID IN ({$interval}) {$limit_clause}";
|
| 486 |
-
$post_objects = $wpdb->get_results( $posts_query );
|
| 487 |
-
if ( is_array( $post_objects ) && ! empty( $post_objects ) ) {
|
| 488 |
-
foreach ( $post_objects as $post_object ) {
|
| 489 |
-
$post = new \WP_Post( $post_object );
|
| 490 |
-
wp_cache_set( $post_object->ID, $post, 'posts' );
|
| 491 |
-
}
|
| 492 |
-
|
| 493 |
-
if ( $update_post_meta_cache ) {
|
| 494 |
-
update_meta_cache( 'post', $these_ids );
|
| 495 |
-
}
|
| 496 |
-
}
|
| 497 |
-
} while ( ! empty( $post_objects ) && is_array( $post_objects ) && count( $post_objects ) < count( $post_ids ) );
|
| 498 |
-
}
|
| 499 |
-
}
|
| 10 |
* When used in its ArrayAccess API the cache will provide non persistent storage.
|
| 11 |
*/
|
| 12 |
class Tribe__Cache implements ArrayAccess {
|
| 13 |
+
const NO_EXPIRATION = 0;
|
| 14 |
+
const NON_PERSISTENT = - 1;
|
|
|
|
|
|
|
|
|
|
| 15 |
|
| 16 |
/**
|
| 17 |
* @var array
|
| 18 |
*/
|
| 19 |
+
protected $non_persistent_keys = array();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 20 |
|
| 21 |
public static function setup() {
|
| 22 |
+
wp_cache_add_non_persistent_groups( array( 'tribe-events-non-persistent' ) );
|
| 23 |
}
|
| 24 |
|
| 25 |
/**
|
| 26 |
+
* @param string $id
|
| 27 |
+
* @param mixed $value
|
| 28 |
+
* @param int $expiration
|
| 29 |
+
* @param string $expiration_trigger
|
| 30 |
*
|
| 31 |
* @return bool
|
| 32 |
*/
|
| 37 |
* Filters the expiration for cache objects to provide the ability
|
| 38 |
* to make non-persistent objects be treated as persistent.
|
| 39 |
*
|
| 40 |
+
* @param int $expiration Cache expiration time.
|
| 41 |
+
* @param string $id Cache ID.
|
| 42 |
+
* @param mixed $value Cache value.
|
| 43 |
+
* @param string $expiration_trigger Action that triggers automatic expiration.
|
| 44 |
+
* @param string $key Unique cache key based on Cache ID and expiration trigger last run time.
|
| 45 |
*
|
| 46 |
+
* @since 4.8
|
|
|
|
|
|
|
|
|
|
|
|
|
| 47 |
*/
|
| 48 |
$expiration = apply_filters( 'tribe_cache_expiration', $expiration, $id, $value, $expiration_trigger, $key );
|
| 49 |
|
| 61 |
}
|
| 62 |
|
| 63 |
/**
|
| 64 |
+
* @param $id
|
| 65 |
+
* @param $value
|
| 66 |
+
* @param int $expiration
|
| 67 |
+
* @param string $expiration_trigger
|
| 68 |
*
|
| 69 |
* @return bool
|
| 70 |
*/
|
| 77 |
*
|
| 78 |
* Note: When a default value or callback is specified, this value gets set in the cache.
|
| 79 |
*
|
| 80 |
+
* @param string $id The key for the cached value.
|
| 81 |
+
* @param string $expiration_trigger Optional. Hook to trigger cache invalidation.
|
| 82 |
+
* @param mixed $default Optional. A default value or callback that returns a default value.
|
| 83 |
+
* @param int $expiration Optional. When the default value expires, if it gets set.
|
| 84 |
+
* @param mixed $args Optional. Args passed to callback.
|
| 85 |
*
|
| 86 |
* @return mixed
|
| 87 |
*/
|
| 88 |
+
public function get( $id, $expiration_trigger = '', $default = false, $expiration = 0, $args = array() ) {
|
| 89 |
+
$group = in_array( $id, $this->non_persistent_keys ) ? 'tribe-events-non-persistent' : 'tribe-events';
|
| 90 |
+
$value = wp_cache_get( $this->get_id( $id, $expiration_trigger ), $group );
|
|
|
|
| 91 |
|
| 92 |
// Value found.
|
| 93 |
if ( false !== $value ) {
|
| 111 |
}
|
| 112 |
|
| 113 |
/**
|
| 114 |
+
* @param string $id
|
| 115 |
+
* @param string $expiration_trigger
|
| 116 |
*
|
| 117 |
* @return mixed
|
| 118 |
*/
|
| 121 |
}
|
| 122 |
|
| 123 |
/**
|
| 124 |
+
* @param string $id
|
| 125 |
+
* @param string $expiration_trigger
|
| 126 |
*
|
| 127 |
* @return bool
|
| 128 |
*/
|
| 131 |
}
|
| 132 |
|
| 133 |
/**
|
| 134 |
+
* @param string $id
|
| 135 |
+
* @param string $expiration_trigger
|
| 136 |
*
|
| 137 |
* @return bool
|
| 138 |
*/
|
| 141 |
}
|
| 142 |
|
| 143 |
/**
|
| 144 |
+
* @param string $key
|
| 145 |
+
* @param string $expiration_trigger
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 146 |
*
|
| 147 |
* @return string
|
| 148 |
*/
|
| 149 |
public function get_id( $key, $expiration_trigger = '' ) {
|
| 150 |
+
$last = empty( $expiration_trigger ) ? '' : $this->get_last_occurrence( $expiration_trigger );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 151 |
$id = $key . $last;
|
| 152 |
+
if ( strlen( $id ) > 40 ) {
|
| 153 |
+
$id = md5( $id );
|
| 154 |
}
|
| 155 |
|
| 156 |
return $id;
|
| 159 |
/**
|
| 160 |
* Returns the time of an action last occurrence.
|
| 161 |
*
|
|
|
|
|
|
|
| 162 |
* @param string $action The action to return the time for.
|
| 163 |
*
|
| 164 |
+
* @since 4.9.14 Changed the return value type from `int` to `float`.
|
| 165 |
+
*
|
| 166 |
* @return float The time (microtime) an action last occurred, or the current microtime if it never occurred.
|
| 167 |
*/
|
| 168 |
public function get_last_occurrence( $action ) {
|
| 169 |
+
return (float) get_option( 'tribe_last_' . $action, microtime( true ) );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 170 |
}
|
| 171 |
|
| 172 |
/**
|
| 174 |
*
|
| 175 |
* @since 4.9.14 Changed the type of the time stored from an `int` to a `float`.
|
| 176 |
*
|
| 177 |
+
* @param string $action The action to record the last occurrence of.
|
| 178 |
+
* @param int $timestamp The timestamp to assign to the action last occurrence or the current time (microtime).
|
|
|
|
|
|
|
| 179 |
*/
|
| 180 |
public function set_last_occurrence( $action, $timestamp = 0 ) {
|
| 181 |
if ( empty( $timestamp ) ) {
|
| 182 |
$timestamp = microtime( true );
|
| 183 |
}
|
| 184 |
+
update_option( 'tribe_last_' . $action, (float) $timestamp );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 185 |
}
|
| 186 |
|
| 187 |
/**
|
| 189 |
*
|
| 190 |
* @param mixed $components Either a single component of the key or an array of key components.
|
| 191 |
* @param string $prefix
|
| 192 |
+
* @param bool $sort Whether component arrays should be sorted or not to generate the key; defaults to `true`.
|
|
|
|
| 193 |
*
|
| 194 |
* @return string The resulting key.
|
| 195 |
*/
|
| 196 |
public function make_key( $components, $prefix = '', $sort = true ) {
|
| 197 |
+
$key = '';
|
| 198 |
+
$components = is_array( $components ) ? $components : array( $components );
|
| 199 |
foreach ( $components as $component ) {
|
| 200 |
if ( $sort && is_array( $component ) ) {
|
| 201 |
$is_associative = count( array_filter( array_keys( $component ), 'is_numeric' ) ) < count( array_keys( $component ) );
|
| 212 |
}
|
| 213 |
|
| 214 |
/**
|
| 215 |
+
* Whether a offset exists
|
|
|
|
|
|
|
| 216 |
*
|
| 217 |
* @link http://php.net/manual/en/arrayaccess.offsetexists.php
|
| 218 |
+
* @param mixed $offset <p>
|
| 219 |
+
* An offset to check for.
|
| 220 |
+
* </p>
|
| 221 |
+
* @return boolean true on success or false on failure.
|
| 222 |
+
* </p>
|
| 223 |
+
* <p>
|
| 224 |
+
* The return value will be casted to boolean if non-boolean was returned.
|
| 225 |
+
* @since 5.0.0
|
| 226 |
*/
|
| 227 |
public function offsetExists( $offset ) {
|
| 228 |
+
return in_array( $offset, $this->non_persistent_keys );
|
|
|
|
|
|
|
| 229 |
}
|
| 230 |
|
| 231 |
/**
|
| 232 |
+
* Offset to retrieve
|
| 233 |
*
|
| 234 |
* @link http://php.net/manual/en/arrayaccess.offsetget.php
|
| 235 |
+
* @param mixed $offset <p>
|
| 236 |
+
* The offset to retrieve.
|
| 237 |
+
* </p>
|
|
|
|
|
|
|
| 238 |
* @return mixed Can return all value types.
|
| 239 |
+
* @since 5.0.0
|
| 240 |
*/
|
| 241 |
public function offsetGet( $offset ) {
|
| 242 |
return $this->get( $offset );
|
| 243 |
}
|
| 244 |
|
| 245 |
/**
|
| 246 |
+
* Offset to set
|
|
|
|
|
|
|
| 247 |
*
|
| 248 |
* @link http://php.net/manual/en/arrayaccess.offsetset.php
|
| 249 |
+
* @param mixed $offset <p>
|
| 250 |
+
* The offset to assign the value to.
|
| 251 |
+
* </p>
|
| 252 |
+
* @param mixed $value <p>
|
| 253 |
+
* The value to set.
|
| 254 |
+
* </p>
|
| 255 |
* @return void
|
| 256 |
+
* @since 5.0.0
|
| 257 |
*/
|
| 258 |
public function offsetSet( $offset, $value ) {
|
| 259 |
$this->set( $offset, $value, self::NON_PERSISTENT );
|
| 260 |
}
|
| 261 |
|
| 262 |
/**
|
| 263 |
+
* Offset to unset
|
|
|
|
|
|
|
| 264 |
*
|
| 265 |
* @link http://php.net/manual/en/arrayaccess.offsetunset.php
|
| 266 |
+
* @param mixed $offset <p>
|
| 267 |
+
* The offset to unset.
|
| 268 |
+
* </p>
|
| 269 |
* @return void
|
| 270 |
+
* @since 5.0.0
|
| 271 |
*/
|
| 272 |
public function offsetUnset( $offset ) {
|
| 273 |
$this->delete( $offset );
|
| 274 |
}
|
| 275 |
+
}
|
| 276 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
common/src/Tribe/Cache_Listener.php
CHANGED
|
@@ -14,11 +14,6 @@
|
|
| 14 |
*/
|
| 15 |
const TRIGGER_SAVE_POST = 'save_post';
|
| 16 |
|
| 17 |
-
/**
|
| 18 |
-
* The name of the trigger that will be fired when an option is updated
|
| 19 |
-
*/
|
| 20 |
-
const TRIGGER_UPDATED_OPTION = 'updated_option';
|
| 21 |
-
|
| 22 |
/**
|
| 23 |
* The singleton instance of the class.
|
| 24 |
*
|
|
@@ -58,7 +53,6 @@
|
|
| 58 |
*/
|
| 59 |
private function add_hooks() {
|
| 60 |
add_action( 'save_post', [ $this, 'save_post' ], 0, 2 );
|
| 61 |
-
add_action( 'updated_option', [ $this, 'update_last_updated_option' ], 10, 3 );
|
| 62 |
add_action( 'updated_option', [ $this, 'update_last_save_post' ], 10, 3 );
|
| 63 |
add_action( 'generate_rewrite_rules', [ $this, 'generate_rewrite_rules' ] );
|
| 64 |
}
|
|
@@ -85,46 +79,17 @@
|
|
| 85 |
* @param mixed $value The new option value.
|
| 86 |
*/
|
| 87 |
public function update_last_save_post( $option_name, $old_value, $value ) {
|
| 88 |
-
$triggers =
|
| 89 |
-
'tribe_events_calendar_options'
|
| 90 |
-
'permalink_structure'
|
| 91 |
-
'rewrite_rules'
|
| 92 |
-
'start_of_week'
|
| 93 |
-
|
| 94 |
-
if (
|
| 95 |
$this->cache->set_last_occurrence( self::TRIGGER_SAVE_POST );
|
| 96 |
}
|
| 97 |
}
|
| 98 |
|
| 99 |
-
/**
|
| 100 |
-
* Run the caching functionality that is executed on saving tribe calendar options.
|
| 101 |
-
*
|
| 102 |
-
* @see 'updated_option'
|
| 103 |
-
*
|
| 104 |
-
* @since 4.11.0
|
| 105 |
-
*
|
| 106 |
-
* @param string $option_name Name of the updated option.
|
| 107 |
-
* @param mixed $old_value The old option value.
|
| 108 |
-
* @param mixed $value The new option value.
|
| 109 |
-
*/
|
| 110 |
-
public function update_last_updated_option( $option_name, $old_value, $value ) {
|
| 111 |
-
$triggers = [
|
| 112 |
-
'active_plugins' => true,
|
| 113 |
-
'tribe_events_calendar_options' => true,
|
| 114 |
-
'permalink_structure' => true,
|
| 115 |
-
'rewrite_rules' => true,
|
| 116 |
-
'start_of_week' => true,
|
| 117 |
-
'sidebars_widgets' => true,
|
| 118 |
-
'stylesheet' => true,
|
| 119 |
-
'template' => true,
|
| 120 |
-
'WPLANG' => true,
|
| 121 |
-
];
|
| 122 |
-
|
| 123 |
-
if ( ! empty( $triggers[ $option_name ] ) ) {
|
| 124 |
-
$this->cache->set_last_occurrence( self::TRIGGER_UPDATED_OPTION );
|
| 125 |
-
}
|
| 126 |
-
}
|
| 127 |
-
|
| 128 |
/**
|
| 129 |
* For any hook that doesn't need any additional filtering
|
| 130 |
*
|
| 14 |
*/
|
| 15 |
const TRIGGER_SAVE_POST = 'save_post';
|
| 16 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 17 |
/**
|
| 18 |
* The singleton instance of the class.
|
| 19 |
*
|
| 53 |
*/
|
| 54 |
private function add_hooks() {
|
| 55 |
add_action( 'save_post', [ $this, 'save_post' ], 0, 2 );
|
|
|
|
| 56 |
add_action( 'updated_option', [ $this, 'update_last_save_post' ], 10, 3 );
|
| 57 |
add_action( 'generate_rewrite_rules', [ $this, 'generate_rewrite_rules' ] );
|
| 58 |
}
|
| 79 |
* @param mixed $value The new option value.
|
| 80 |
*/
|
| 81 |
public function update_last_save_post( $option_name, $old_value, $value ) {
|
| 82 |
+
$triggers = array(
|
| 83 |
+
'tribe_events_calendar_options',
|
| 84 |
+
'permalink_structure',
|
| 85 |
+
'rewrite_rules',
|
| 86 |
+
'start_of_week',
|
| 87 |
+
);
|
| 88 |
+
if ( in_array( $option_name, $triggers, true ) ) {
|
| 89 |
$this->cache->set_last_occurrence( self::TRIGGER_SAVE_POST );
|
| 90 |
}
|
| 91 |
}
|
| 92 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 93 |
/**
|
| 94 |
* For any hook that doesn't need any additional filtering
|
| 95 |
*
|
common/src/Tribe/Container.php
CHANGED
|
@@ -224,52 +224,6 @@ if ( ! function_exists( 'tribe_get_var' ) ) {
|
|
| 224 |
}
|
| 225 |
}
|
| 226 |
|
| 227 |
-
if ( ! function_exists( 'tribe_unset_var' ) ) {
|
| 228 |
-
/**
|
| 229 |
-
* Returns the value of a registered variable.
|
| 230 |
-
*
|
| 231 |
-
* Example use:
|
| 232 |
-
*
|
| 233 |
-
* tribe_set_var( 'tec.url', 'http://example.com' );
|
| 234 |
-
*
|
| 235 |
-
* tribe_unset_var( 'tec.url' );
|
| 236 |
-
*
|
| 237 |
-
* @since 4.11.0
|
| 238 |
-
*
|
| 239 |
-
* @param string $slug The slug of the variable registered using `tribe_unset_var`.
|
| 240 |
-
*
|
| 241 |
-
* @return void
|
| 242 |
-
*/
|
| 243 |
-
function tribe_unset_var( $slug ) {
|
| 244 |
-
$container = Tribe__Container::init();
|
| 245 |
-
try {
|
| 246 |
-
$container->offsetUnset( $slug );
|
| 247 |
-
} catch ( Exception $e ) {}
|
| 248 |
-
}
|
| 249 |
-
}
|
| 250 |
-
|
| 251 |
-
if ( ! function_exists( 'tribe_isset_var' ) ) {
|
| 252 |
-
/**
|
| 253 |
-
* Returns the value of a registered variable.
|
| 254 |
-
*
|
| 255 |
-
* Example use:
|
| 256 |
-
*
|
| 257 |
-
* tribe_set_var( 'tec.url', 'http://example.com' );
|
| 258 |
-
*
|
| 259 |
-
* tribe_isset_var( 'tec.url' );
|
| 260 |
-
*
|
| 261 |
-
* @since 4.11.0
|
| 262 |
-
*
|
| 263 |
-
* @param string $slug The slug of the variable checked using `tribe_isset_var`.
|
| 264 |
-
*
|
| 265 |
-
* @return boolean Either a the given slug exists.
|
| 266 |
-
*/
|
| 267 |
-
function tribe_isset_var( $slug ) {
|
| 268 |
-
$container = Tribe__Container::init();
|
| 269 |
-
return $container->offsetExists( $slug );
|
| 270 |
-
}
|
| 271 |
-
}
|
| 272 |
-
|
| 273 |
if ( ! function_exists( 'tribe_register_provider' ) ) {
|
| 274 |
/**
|
| 275 |
* Registers a service provider in the container.
|
| 224 |
}
|
| 225 |
}
|
| 226 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 227 |
if ( ! function_exists( 'tribe_register_provider' ) ) {
|
| 228 |
/**
|
| 229 |
* Registers a service provider in the container.
|
common/src/Tribe/Context.php
CHANGED
|
@@ -59,13 +59,6 @@ class Tribe__Context {
|
|
| 59 |
*/
|
| 60 |
const QUERY_PROP = 'query_prop';
|
| 61 |
|
| 62 |
-
/**
|
| 63 |
-
* The key to locate a context value as the value of the main query (global `$wp_query`) method return value.
|
| 64 |
-
*
|
| 65 |
-
* @since 4.9.20
|
| 66 |
-
*/
|
| 67 |
-
const QUERY_METHOD = 'query_method';
|
| 68 |
-
|
| 69 |
/**
|
| 70 |
* The key to locate a context value as the value of a constant.
|
| 71 |
*
|
|
@@ -136,13 +129,6 @@ class Tribe__Context {
|
|
| 136 |
*/
|
| 137 |
const WP_MATCHED_QUERY = 'wp_matched_query';
|
| 138 |
|
| 139 |
-
/**
|
| 140 |
-
* The key to indicate a location should be read by applying a callback to the value of another context location.
|
| 141 |
-
*
|
| 142 |
-
* @since 4.9.18
|
| 143 |
-
*/
|
| 144 |
-
const LOCATION_FUNC = 'location_func';
|
| 145 |
-
|
| 146 |
/*
|
| 147 |
*
|
| 148 |
* An array defining the properties the context will be able to read and (dangerously) write.
|
|
@@ -169,7 +155,6 @@ class Tribe__Context {
|
|
| 169 |
* method - get the value calling a method on a tribe() container binding.
|
| 170 |
* func - get the value from a function or a closure.
|
| 171 |
* filter - get the value by applying a filter.
|
| 172 |
-
* location_func - get the value by applying a callback to the value of a location.
|
| 173 |
*
|
| 174 |
* For each location additional arguments can be specified:
|
| 175 |
* orm_arg - if `false` then the location will never produce an ORM argument, if provided the ORM arg produced bye the
|
|
@@ -280,7 +265,7 @@ class Tribe__Context {
|
|
| 280 |
return false;
|
| 281 |
}
|
| 282 |
|
| 283 |
-
if (
|
| 284 |
$lookup = array( $_GET, $_POST, $_REQUEST );
|
| 285 |
|
| 286 |
$current_post = Tribe__Utils__Array::get_in_any( $lookup, 'post', get_post() );
|
|
@@ -294,7 +279,7 @@ class Tribe__Context {
|
|
| 294 |
|
| 295 |
$post_types = is_array( $post_or_type ) ? $post_or_type : array( $post_or_type );
|
| 296 |
|
| 297 |
-
$post = $is_post ?
|
| 298 |
|
| 299 |
if ( count( array_filter( $post_types, 'is_numeric' ) ) === count( $post_types ) ) {
|
| 300 |
return ! empty( $post ) && in_array( $post->ID, $post_types );
|
|
@@ -376,7 +361,6 @@ class Tribe__Context {
|
|
| 376 |
|
| 377 |
$value = $default;
|
| 378 |
$locations = $this->get_locations();
|
| 379 |
-
$found = false;
|
| 380 |
|
| 381 |
if ( ! $force && isset( $this->request_cache[ $key ] ) ) {
|
| 382 |
$value = $this->request_cache[ $key ];
|
|
@@ -384,8 +368,7 @@ class Tribe__Context {
|
|
| 384 |
foreach ( $locations[ $key ]['read'] as $location => $keys ) {
|
| 385 |
$the_value = $this->$location( (array) $keys, $default );
|
| 386 |
|
| 387 |
-
if ( $default !== $the_value
|
| 388 |
-
$found = true;
|
| 389 |
$value = $the_value;
|
| 390 |
break;
|
| 391 |
}
|
|
@@ -403,11 +386,6 @@ class Tribe__Context {
|
|
| 403 |
*/
|
| 404 |
$value = apply_filters( "tribe_context_{$key}", $value );
|
| 405 |
|
| 406 |
-
// Only cache if the value was found.
|
| 407 |
-
if ( $found ) {
|
| 408 |
-
$this->request_cache[ $key ] = $value;
|
| 409 |
-
}
|
| 410 |
-
|
| 411 |
return $value;
|
| 412 |
}
|
| 413 |
|
|
@@ -461,22 +439,9 @@ class Tribe__Context {
|
|
| 461 |
public function get_locations() {
|
| 462 |
$this->populate_locations();
|
| 463 |
|
| 464 |
-
|
| 465 |
? array_merge( self::$locations, $this->override_locations )
|
| 466 |
: $this->override_locations;
|
| 467 |
-
|
| 468 |
-
if ( $this->use_default_locations ) {
|
| 469 |
-
/**
|
| 470 |
-
* Filters the locations registered in the Context.
|
| 471 |
-
*
|
| 472 |
-
* @since 4.10.2
|
| 473 |
-
*
|
| 474 |
-
* @param array $locations An array of locations registered on the Context object.
|
| 475 |
-
*/
|
| 476 |
-
$locations = apply_filters( 'tribe_context_locations', $locations, $this );
|
| 477 |
-
}
|
| 478 |
-
|
| 479 |
-
return $locations;
|
| 480 |
}
|
| 481 |
|
| 482 |
/**
|
|
@@ -517,11 +482,6 @@ class Tribe__Context {
|
|
| 517 |
$value = $default;
|
| 518 |
|
| 519 |
global $wp_query;
|
| 520 |
-
|
| 521 |
-
if ( ! $wp_query instanceof \WP_Query ) {
|
| 522 |
-
return $value;
|
| 523 |
-
}
|
| 524 |
-
|
| 525 |
foreach ( $query_vars as $query_var ) {
|
| 526 |
$the_value = $wp_query->get( $query_var, self::NOT_FOUND );
|
| 527 |
if ( $the_value !== self::NOT_FOUND ) {
|
|
@@ -1490,135 +1450,4 @@ class Tribe__Context {
|
|
| 1490 |
|
| 1491 |
return $filled;
|
| 1492 |
}
|
| 1493 |
-
|
| 1494 |
-
/**
|
| 1495 |
-
* Convenience method to get and check if a location has a truthy value or not.
|
| 1496 |
-
*
|
| 1497 |
-
* @since 4.9.18
|
| 1498 |
-
*
|
| 1499 |
-
* @param string $flag_key The location to check.
|
| 1500 |
-
* @param bool $default The default value to return if the location is not set.
|
| 1501 |
-
*
|
| 1502 |
-
* @return bool Whether the location has a truthy value or not.
|
| 1503 |
-
*/
|
| 1504 |
-
public function is( $flag_key, $default = false ) {
|
| 1505 |
-
$val = $this->get( $flag_key, $default );
|
| 1506 |
-
|
| 1507 |
-
return ! empty( $val ) || tribe_is_truthy( $val );
|
| 1508 |
-
}
|
| 1509 |
-
|
| 1510 |
-
/**
|
| 1511 |
-
* Reads the value from one callback, passing it the value of another Context location.
|
| 1512 |
-
*
|
| 1513 |
-
* @since 4.9.18
|
| 1514 |
-
*
|
| 1515 |
-
* @param array $location_and_callback An array of two elements: the location key and the callback to call on the
|
| 1516 |
-
* location value. The callback will receive the location value as argument.
|
| 1517 |
-
*
|
| 1518 |
-
* @return mixed The return value of the callback, called on the location value.
|
| 1519 |
-
*/
|
| 1520 |
-
public function location_func( array $location_and_callback ) {
|
| 1521 |
-
list( $location, $callback ) = $location_and_callback;
|
| 1522 |
-
|
| 1523 |
-
return $callback( $this->get( $location ) );
|
| 1524 |
-
}
|
| 1525 |
-
|
| 1526 |
-
/**
|
| 1527 |
-
* Checks whether the current request is a REST API one or not.
|
| 1528 |
-
*
|
| 1529 |
-
* @since 4.9.20
|
| 1530 |
-
*
|
| 1531 |
-
* @return bool Whether the current request is a REST API one or not.
|
| 1532 |
-
*/
|
| 1533 |
-
public function doing_rest() {
|
| 1534 |
-
return defined( 'REST_REQUEST' ) && REST_REQUEST;
|
| 1535 |
-
}
|
| 1536 |
-
|
| 1537 |
-
/**
|
| 1538 |
-
* Reads the value from one or more global WP_Query object methods.
|
| 1539 |
-
*
|
| 1540 |
-
* @since 4.9.20
|
| 1541 |
-
*
|
| 1542 |
-
* @param array $query_vars The list of query methods to call, in order.
|
| 1543 |
-
* @param mixed $default The default value to return if no method was defined on the global `WP_Query` object.
|
| 1544 |
-
*
|
| 1545 |
-
* @return mixed The first valid value found or the default value.
|
| 1546 |
-
*/
|
| 1547 |
-
public function query_method( $methods, $default ) {
|
| 1548 |
-
global $wp_query;
|
| 1549 |
-
$found = $default;
|
| 1550 |
-
|
| 1551 |
-
foreach ( $methods as $method ) {
|
| 1552 |
-
$this_value = $wp_query instanceof WP_Query && method_exists( $wp_query, $method )
|
| 1553 |
-
? call_user_func( [ $wp_query, $method ] )
|
| 1554 |
-
: static::NOT_FOUND;
|
| 1555 |
-
|
| 1556 |
-
if ( static::NOT_FOUND !== $this_value ) {
|
| 1557 |
-
return $this_value;
|
| 1558 |
-
}
|
| 1559 |
-
}
|
| 1560 |
-
|
| 1561 |
-
return $found;
|
| 1562 |
-
}
|
| 1563 |
-
|
| 1564 |
-
/**
|
| 1565 |
-
* Whether the current request is for a PHP-rendered initial state or not.
|
| 1566 |
-
*
|
| 1567 |
-
* This method is a shortcut to make sure we're not doing an AJAX, REST or Cron request.
|
| 1568 |
-
*
|
| 1569 |
-
* @since 4.9.20
|
| 1570 |
-
*
|
| 1571 |
-
* @return bool Whether the current request is for a PHP-rendered initial state or not.
|
| 1572 |
-
*/
|
| 1573 |
-
public function doing_php_initial_state() {
|
| 1574 |
-
return ! $this->doing_rest() && ! $this->doing_ajax() && ! $this->doing_cron();
|
| 1575 |
-
}
|
| 1576 |
-
|
| 1577 |
-
/**
|
| 1578 |
-
* Returns the first key, if there are many, that will be used to read a location.
|
| 1579 |
-
*
|
| 1580 |
-
* The type ar
|
| 1581 |
-
*
|
| 1582 |
-
* @since 4.9.20
|
| 1583 |
-
*
|
| 1584 |
-
* @param string $location The location to get the read key for.
|
| 1585 |
-
* @param string|null $type The type of read location to return the key for; default to `static::REQUEST_VAR`.
|
| 1586 |
-
*
|
| 1587 |
-
* @return string Either the first key for the type of read location, or the input location if not found.
|
| 1588 |
-
*/
|
| 1589 |
-
public function get_read_key_for( $location, $type = null ) {
|
| 1590 |
-
$type = $type ?: static::REQUEST_VAR;
|
| 1591 |
-
$locations = $this->get_locations();
|
| 1592 |
-
if ( isset( $locations[ $location ]['read'][ $type ] ) ) {
|
| 1593 |
-
$keys = (array) $locations[ $location ]['read'][ $type ];
|
| 1594 |
-
return reset( $keys );
|
| 1595 |
-
}
|
| 1596 |
-
|
| 1597 |
-
return $location;
|
| 1598 |
-
}
|
| 1599 |
-
|
| 1600 |
-
/**
|
| 1601 |
-
* Safely set the value of a group of locations.
|
| 1602 |
-
*
|
| 1603 |
-
* This method can only augment the context, without altering it; it can only add new values.
|
| 1604 |
-
*
|
| 1605 |
-
* @since 4.10.2
|
| 1606 |
-
*
|
| 1607 |
-
* @param array|string $values The values to set, if not already set or the key of the value to set, requires
|
| 1608 |
-
* the `$value` to be passed.
|
| 1609 |
-
* @param mixed|null $value The value to set for the key, this parameter will be ignored if the `$values_or_key`
|
| 1610 |
-
* parameter is not a string.
|
| 1611 |
-
*/
|
| 1612 |
-
public function safe_set( $values_or_key, $value = null ) {
|
| 1613 |
-
$values = func_num_args() === 2
|
| 1614 |
-
? [ $values_or_key => $value ]
|
| 1615 |
-
: $values_or_key;
|
| 1616 |
-
|
| 1617 |
-
foreach ( $values as $key => $val ) {
|
| 1618 |
-
if ( static::NOT_FOUND !== $this->get( $key, static::NOT_FOUND ) ) {
|
| 1619 |
-
continue;
|
| 1620 |
-
}
|
| 1621 |
-
$this->request_cache[ $key ] = $val;
|
| 1622 |
-
}
|
| 1623 |
-
}
|
| 1624 |
}
|
| 59 |
*/
|
| 60 |
const QUERY_PROP = 'query_prop';
|
| 61 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 62 |
/**
|
| 63 |
* The key to locate a context value as the value of a constant.
|
| 64 |
*
|
| 129 |
*/
|
| 130 |
const WP_MATCHED_QUERY = 'wp_matched_query';
|
| 131 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 132 |
/*
|
| 133 |
*
|
| 134 |
* An array defining the properties the context will be able to read and (dangerously) write.
|
| 155 |
* method - get the value calling a method on a tribe() container binding.
|
| 156 |
* func - get the value from a function or a closure.
|
| 157 |
* filter - get the value by applying a filter.
|
|
|
|
| 158 |
*
|
| 159 |
* For each location additional arguments can be specified:
|
| 160 |
* orm_arg - if `false` then the location will never produce an ORM argument, if provided the ORM arg produced bye the
|
| 265 |
return false;
|
| 266 |
}
|
| 267 |
|
| 268 |
+
if ( null !== $post_or_type ) {
|
| 269 |
$lookup = array( $_GET, $_POST, $_REQUEST );
|
| 270 |
|
| 271 |
$current_post = Tribe__Utils__Array::get_in_any( $lookup, 'post', get_post() );
|
| 279 |
|
| 280 |
$post_types = is_array( $post_or_type ) ? $post_or_type : array( $post_or_type );
|
| 281 |
|
| 282 |
+
$post = $is_post ? $current_post : null;
|
| 283 |
|
| 284 |
if ( count( array_filter( $post_types, 'is_numeric' ) ) === count( $post_types ) ) {
|
| 285 |
return ! empty( $post ) && in_array( $post->ID, $post_types );
|
| 361 |
|
| 362 |
$value = $default;
|
| 363 |
$locations = $this->get_locations();
|
|
|
|
| 364 |
|
| 365 |
if ( ! $force && isset( $this->request_cache[ $key ] ) ) {
|
| 366 |
$value = $this->request_cache[ $key ];
|
| 368 |
foreach ( $locations[ $key ]['read'] as $location => $keys ) {
|
| 369 |
$the_value = $this->$location( (array) $keys, $default );
|
| 370 |
|
| 371 |
+
if ( $default !== $the_value ) {
|
|
|
|
| 372 |
$value = $the_value;
|
| 373 |
break;
|
| 374 |
}
|
| 386 |
*/
|
| 387 |
$value = apply_filters( "tribe_context_{$key}", $value );
|
| 388 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 389 |
return $value;
|
| 390 |
}
|
| 391 |
|
| 439 |
public function get_locations() {
|
| 440 |
$this->populate_locations();
|
| 441 |
|
| 442 |
+
return $this->use_default_locations
|
| 443 |
? array_merge( self::$locations, $this->override_locations )
|
| 444 |
: $this->override_locations;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 445 |
}
|
| 446 |
|
| 447 |
/**
|
| 482 |
$value = $default;
|
| 483 |
|
| 484 |
global $wp_query;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 485 |
foreach ( $query_vars as $query_var ) {
|
| 486 |
$the_value = $wp_query->get( $query_var, self::NOT_FOUND );
|
| 487 |
if ( $the_value !== self::NOT_FOUND ) {
|
| 1450 |
|
| 1451 |
return $filled;
|
| 1452 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1453 |
}
|
common/src/Tribe/Context/locations.php
CHANGED
|
@@ -9,29 +9,8 @@
|
|
| 9 |
*
|
| 10 |
* @since 4.9.11
|
| 11 |
*/
|
|
|
|
| 12 |
return [
|
| 13 |
-
'post_id' => [
|
| 14 |
-
'read' => [
|
| 15 |
-
Tribe__Context::FUNC => static function () {
|
| 16 |
-
return get_the_ID();
|
| 17 |
-
}
|
| 18 |
-
],
|
| 19 |
-
],
|
| 20 |
-
'permalink_structure' => [
|
| 21 |
-
'read' => [
|
| 22 |
-
Tribe__Context::OPTION => [ 'permalink_structure' ],
|
| 23 |
-
],
|
| 24 |
-
],
|
| 25 |
-
'plain_permalink' => [
|
| 26 |
-
'read' => [
|
| 27 |
-
Tribe__Context::LOCATION_FUNC => [
|
| 28 |
-
'permalink_structure',
|
| 29 |
-
static function( $struct ){
|
| 30 |
-
return empty( $struct );
|
| 31 |
-
},
|
| 32 |
-
],
|
| 33 |
-
],
|
| 34 |
-
],
|
| 35 |
'posts_per_page' => [
|
| 36 |
'read' => [
|
| 37 |
Tribe__Context::REQUEST_VAR => 'posts_per_page',
|
|
@@ -88,52 +67,4 @@ return [
|
|
| 88 |
Tribe__Context::QUERY_VAR => [ 'name', 'post_name' ],
|
| 89 |
],
|
| 90 |
],
|
| 91 |
-
'post_type' => [
|
| 92 |
-
'read' => [
|
| 93 |
-
Tribe__Context::FUNC => static function() {
|
| 94 |
-
$post_type_objs = get_post_types(
|
| 95 |
-
[
|
| 96 |
-
'public' => true,
|
| 97 |
-
'_builtin' => false,
|
| 98 |
-
],
|
| 99 |
-
'objects'
|
| 100 |
-
);
|
| 101 |
-
|
| 102 |
-
foreach( $post_type_objs as $post_type ) {
|
| 103 |
-
if ( empty( $post_type->query_var ) ) {
|
| 104 |
-
continue;
|
| 105 |
-
}
|
| 106 |
-
|
| 107 |
-
$url_value = tribe_get_request_var( $post_type->query_var, false );
|
| 108 |
-
if ( empty( $url_value ) ) {
|
| 109 |
-
continue;
|
| 110 |
-
}
|
| 111 |
-
|
| 112 |
-
return $post_type->name;
|
| 113 |
-
}
|
| 114 |
-
|
| 115 |
-
return Tribe__Context::NOT_FOUND;
|
| 116 |
-
},
|
| 117 |
-
Tribe__Context::QUERY_PROP => 'post_type',
|
| 118 |
-
Tribe__Context::QUERY_VAR => 'post_type',
|
| 119 |
-
Tribe__Context::REQUEST_VAR => 'post_type',
|
| 120 |
-
],
|
| 121 |
-
],
|
| 122 |
-
'single' => [
|
| 123 |
-
'read' => [ Tribe__Context::QUERY_METHOD => 'is_single' ]
|
| 124 |
-
],
|
| 125 |
-
'taxonomy' => [
|
| 126 |
-
'read' => [
|
| 127 |
-
Tribe__Context::QUERY_PROP => [ 'taxonomy' ],
|
| 128 |
-
Tribe__Context::QUERY_VAR => [ 'taxonomy' ],
|
| 129 |
-
Tribe__Context::REQUEST_VAR => [ 'taxonomy' ],
|
| 130 |
-
],
|
| 131 |
-
],
|
| 132 |
-
'post_tag' => [
|
| 133 |
-
'read' => [
|
| 134 |
-
Tribe__Context::QUERY_PROP => [ 'post_tag', 'tag' ],
|
| 135 |
-
Tribe__Context::QUERY_VAR => [ 'post_tag', 'tag' ],
|
| 136 |
-
Tribe__Context::REQUEST_VAR => [ 'post_tag', 'tag' ],
|
| 137 |
-
],
|
| 138 |
-
],
|
| 139 |
];
|
| 9 |
*
|
| 10 |
* @since 4.9.11
|
| 11 |
*/
|
| 12 |
+
|
| 13 |
return [
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 14 |
'posts_per_page' => [
|
| 15 |
'read' => [
|
| 16 |
Tribe__Context::REQUEST_VAR => 'posts_per_page',
|
| 67 |
Tribe__Context::QUERY_VAR => [ 'name', 'post_name' ],
|
| 68 |
],
|
| 69 |
],
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 70 |
];
|
common/src/Tribe/Customizer.php
CHANGED
|
@@ -104,6 +104,17 @@ final class Tribe__Customizer {
|
|
| 104 |
return;
|
| 105 |
}
|
| 106 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 107 |
/**
|
| 108 |
* Filters the Panel ID, which is also the `wp_option` name for the Customizer settings
|
| 109 |
*
|
|
@@ -316,6 +327,18 @@ final class Tribe__Customizer {
|
|
| 316 |
$option = $sections;
|
| 317 |
}
|
| 318 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 319 |
/**
|
| 320 |
* Apply Filters After finding the variable
|
| 321 |
*
|
|
@@ -370,6 +393,18 @@ final class Tribe__Customizer {
|
|
| 370 |
return false;
|
| 371 |
}
|
| 372 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 373 |
/**
|
| 374 |
* Use this filter to add more CSS, using Underscore Template style
|
| 375 |
*
|
|
@@ -379,7 +414,7 @@ final class Tribe__Customizer {
|
|
| 379 |
*
|
| 380 |
* @param string $template
|
| 381 |
*/
|
| 382 |
-
$css_template = trim( apply_filters( 'tribe_customizer_css_template',
|
| 383 |
|
| 384 |
// If we don't have anything on the customizer don't print empty styles
|
| 385 |
// On Customize Page, we don't care we need this
|
|
@@ -404,7 +439,8 @@ final class Tribe__Customizer {
|
|
| 404 |
* @return void
|
| 405 |
*/
|
| 406 |
public function inline_style() {
|
| 407 |
-
|
|
|
|
| 408 |
if ( is_customize_preview() || is_admin() || $this->inline_style ) {
|
| 409 |
return false;
|
| 410 |
}
|
|
@@ -425,30 +461,29 @@ final class Tribe__Customizer {
|
|
| 425 |
return false;
|
| 426 |
}
|
| 427 |
|
| 428 |
-
|
|
|
|
| 429 |
|
| 430 |
-
|
| 431 |
-
|
| 432 |
-
*
|
| 433 |
-
* @since 4.12.1
|
| 434 |
-
*
|
| 435 |
-
* @param array<string> $sheets An array of sheets to search for.
|
| 436 |
-
* @param string $css_template String containing the inline css to add.
|
| 437 |
-
*/
|
| 438 |
-
$sheets = apply_filters( 'tribe_customizer_inline_stylesheets', $sheets, $css_template );
|
| 439 |
|
| 440 |
-
|
| 441 |
-
return false;
|
| 442 |
}
|
| 443 |
|
| 444 |
-
|
| 445 |
-
foreach ( $sheets as $sheet ) {
|
| 446 |
-
if ( wp_style_is( $sheet ) ) {
|
| 447 |
-
wp_add_inline_style( $sheet, wp_strip_all_tags( $this->parse_css_template( $css_template ) ) );
|
| 448 |
-
$this->inline_style = true;
|
| 449 |
|
| 450 |
-
|
| 451 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 452 |
}
|
| 453 |
}
|
| 454 |
|
|
@@ -496,6 +531,17 @@ final class Tribe__Customizer {
|
|
| 496 |
// Set the Cutomizer on a class variable
|
| 497 |
$this->manager = $customizer;
|
| 498 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 499 |
/**
|
| 500 |
* Allow users to filter the Panel
|
| 501 |
*
|
|
@@ -504,7 +550,18 @@ final class Tribe__Customizer {
|
|
| 504 |
* @param WP_Customize_Panel $panel
|
| 505 |
* @param Tribe__Customizer $customizer
|
| 506 |
*/
|
| 507 |
-
$this->panel = apply_filters( 'tribe_customizer_panel', $this->
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 508 |
|
| 509 |
/**
|
| 510 |
* Filter the Sections within our Panel before they are added to the Cutomize Manager
|
|
@@ -519,6 +576,17 @@ final class Tribe__Customizer {
|
|
| 519 |
foreach ( $this->sections as $id => $section ) {
|
| 520 |
$this->sections[ $id ] = $this->register_section( $id, $section );
|
| 521 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 522 |
/**
|
| 523 |
* Allows people to Register and de-register the method to register more Fields
|
| 524 |
*
|
|
@@ -530,6 +598,17 @@ final class Tribe__Customizer {
|
|
| 530 |
do_action( "tribe_customizer_register_{$id}_settings", $this->sections[ $id ], $this->manager );
|
| 531 |
}
|
| 532 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 533 |
/**
|
| 534 |
* Filter the Sections within our Panel, now using the actual WP_Customize_Section
|
| 535 |
*
|
|
@@ -567,6 +646,18 @@ final class Tribe__Customizer {
|
|
| 567 |
'priority' => 125,
|
| 568 |
);
|
| 569 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 570 |
/**
|
| 571 |
* Filter the Panel Arguments for WP Customize
|
| 572 |
*
|
|
@@ -598,6 +689,17 @@ final class Tribe__Customizer {
|
|
| 598 |
* @return WP_Customize_Section
|
| 599 |
*/
|
| 600 |
public function register_section( $id, $args ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 601 |
/**
|
| 602 |
* Filter the Section ID
|
| 603 |
*
|
|
@@ -606,7 +708,7 @@ final class Tribe__Customizer {
|
|
| 606 |
* @param string $section_id
|
| 607 |
* @param Tribe__Customizer $customizer
|
| 608 |
*/
|
| 609 |
-
$section_id = apply_filters( 'tribe_customizer_section_id', $
|
| 610 |
|
| 611 |
// Tries to fetch the section
|
| 612 |
$section = $this->manager->get_section( $section_id );
|
|
@@ -616,6 +718,18 @@ final class Tribe__Customizer {
|
|
| 616 |
return $section;
|
| 617 |
}
|
| 618 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 619 |
/**
|
| 620 |
* Filter the Section arguments, so that developers can filter arguments based on $section_id
|
| 621 |
*
|
| 104 |
return;
|
| 105 |
}
|
| 106 |
|
| 107 |
+
/**
|
| 108 |
+
* Filters the Panel ID, which is also the `wp_option` name for the Customizer settings
|
| 109 |
+
*
|
| 110 |
+
* @deprecated
|
| 111 |
+
* @since 4.0
|
| 112 |
+
*
|
| 113 |
+
* @param string $ID
|
| 114 |
+
* @param self $customizer
|
| 115 |
+
*/
|
| 116 |
+
$this->ID = apply_filters( 'tribe_events_pro_customizer_panel_id', 'tribe_customizer', $this );
|
| 117 |
+
|
| 118 |
/**
|
| 119 |
* Filters the Panel ID, which is also the `wp_option` name for the Customizer settings
|
| 120 |
*
|
| 327 |
$option = $sections;
|
| 328 |
}
|
| 329 |
|
| 330 |
+
/**
|
| 331 |
+
* Apply Filters After finding the variable
|
| 332 |
+
*
|
| 333 |
+
* @deprecated
|
| 334 |
+
* @since 4.0
|
| 335 |
+
*
|
| 336 |
+
* @param mixed $option
|
| 337 |
+
* @param array $search
|
| 338 |
+
* @param array $sections
|
| 339 |
+
*/
|
| 340 |
+
$option = apply_filters( 'tribe_events_pro_customizer_get_option', $option, $search, $sections );
|
| 341 |
+
|
| 342 |
/**
|
| 343 |
* Apply Filters After finding the variable
|
| 344 |
*
|
| 393 |
return false;
|
| 394 |
}
|
| 395 |
|
| 396 |
+
/**
|
| 397 |
+
* Use this filter to add more CSS, using Underscore Template style
|
| 398 |
+
*
|
| 399 |
+
* @deprecated
|
| 400 |
+
* @since 4.0
|
| 401 |
+
*
|
| 402 |
+
* @link http://underscorejs.org/#template
|
| 403 |
+
*
|
| 404 |
+
* @param string $template
|
| 405 |
+
*/
|
| 406 |
+
$css_template = trim( apply_filters( 'tribe_events_pro_customizer_css_template', '' ) );
|
| 407 |
+
|
| 408 |
/**
|
| 409 |
* Use this filter to add more CSS, using Underscore Template style
|
| 410 |
*
|
| 414 |
*
|
| 415 |
* @param string $template
|
| 416 |
*/
|
| 417 |
+
$css_template = trim( apply_filters( 'tribe_customizer_css_template', $css_template ) );
|
| 418 |
|
| 419 |
// If we don't have anything on the customizer don't print empty styles
|
| 420 |
// On Customize Page, we don't care we need this
|
| 439 |
* @return void
|
| 440 |
*/
|
| 441 |
public function inline_style() {
|
| 442 |
+
|
| 443 |
+
//Only load on front end
|
| 444 |
if ( is_customize_preview() || is_admin() || $this->inline_style ) {
|
| 445 |
return false;
|
| 446 |
}
|
| 461 |
return false;
|
| 462 |
}
|
| 463 |
|
| 464 |
+
// add customizer styles inline with either main stylesheet is enqueued or widgets
|
| 465 |
+
if ( wp_style_is( 'tribe-events-calendar-style' ) ) {
|
| 466 |
|
| 467 |
+
wp_add_inline_style( 'tribe-events-calendar-style', wp_strip_all_tags( $this->parse_css_template( $css_template ) ) );
|
| 468 |
+
$this->inline_style = true;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 469 |
|
| 470 |
+
return;
|
|
|
|
| 471 |
}
|
| 472 |
|
| 473 |
+
if ( wp_style_is( 'tribe-events-calendar-pro-style' ) ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
| 474 |
|
| 475 |
+
wp_add_inline_style( 'tribe-events-calendar-pro-style', wp_strip_all_tags( $this->parse_css_template( $css_template ) ) );
|
| 476 |
+
$this->inline_style = true;
|
| 477 |
+
|
| 478 |
+
return;
|
| 479 |
+
}
|
| 480 |
+
|
| 481 |
+
if ( wp_style_is( 'widget-calendar-pro-style' ) ) {
|
| 482 |
+
|
| 483 |
+
wp_add_inline_style( 'widget-calendar-pro-style', wp_strip_all_tags( $this->parse_css_template( $css_template ) ) );
|
| 484 |
+
$this->inline_style = true;
|
| 485 |
+
|
| 486 |
+
return;
|
| 487 |
}
|
| 488 |
}
|
| 489 |
|
| 531 |
// Set the Cutomizer on a class variable
|
| 532 |
$this->manager = $customizer;
|
| 533 |
|
| 534 |
+
/**
|
| 535 |
+
* Allow users to filter the Panel
|
| 536 |
+
*
|
| 537 |
+
* @deprecated
|
| 538 |
+
* @since 4.0
|
| 539 |
+
*
|
| 540 |
+
* @param WP_Customize_Panel $panel
|
| 541 |
+
* @param Tribe__Customizer $customizer
|
| 542 |
+
*/
|
| 543 |
+
$this->panel = apply_filters( 'tribe_events_pro_customizer_panel', $this->register_panel(), $this );
|
| 544 |
+
|
| 545 |
/**
|
| 546 |
* Allow users to filter the Panel
|
| 547 |
*
|
| 550 |
* @param WP_Customize_Panel $panel
|
| 551 |
* @param Tribe__Customizer $customizer
|
| 552 |
*/
|
| 553 |
+
$this->panel = apply_filters( 'tribe_customizer_panel', $this->panel, $this );
|
| 554 |
+
|
| 555 |
+
/**
|
| 556 |
+
* Filter the Sections within our Panel before they are added to the Cutomize Manager
|
| 557 |
+
*
|
| 558 |
+
* @deprecated
|
| 559 |
+
* @since 4.0
|
| 560 |
+
*
|
| 561 |
+
* @param array $sections
|
| 562 |
+
* @param Tribe__Customizer $customizer
|
| 563 |
+
*/
|
| 564 |
+
$this->sections = apply_filters( 'tribe_events_pro_customizer_pre_sections', $this->sections, $this );
|
| 565 |
|
| 566 |
/**
|
| 567 |
* Filter the Sections within our Panel before they are added to the Cutomize Manager
|
| 576 |
foreach ( $this->sections as $id => $section ) {
|
| 577 |
$this->sections[ $id ] = $this->register_section( $id, $section );
|
| 578 |
|
| 579 |
+
/**
|
| 580 |
+
* Allows people to Register and de-register the method to register more Fields
|
| 581 |
+
*
|
| 582 |
+
* @deprecated
|
| 583 |
+
* @since 4.0
|
| 584 |
+
*
|
| 585 |
+
* @param array $section
|
| 586 |
+
* @param WP_Customize_Manager $manager
|
| 587 |
+
*/
|
| 588 |
+
do_action( "tribe_events_pro_customizer_register_{$id}_settings", $this->sections[ $id ], $this->manager );
|
| 589 |
+
|
| 590 |
/**
|
| 591 |
* Allows people to Register and de-register the method to register more Fields
|
| 592 |
*
|
| 598 |
do_action( "tribe_customizer_register_{$id}_settings", $this->sections[ $id ], $this->manager );
|
| 599 |
}
|
| 600 |
|
| 601 |
+
/**
|
| 602 |
+
* Filter the Sections within our Panel, now using the actual WP_Customize_Section
|
| 603 |
+
*
|
| 604 |
+
* @deprecated
|
| 605 |
+
* @since 4.0
|
| 606 |
+
*
|
| 607 |
+
* @param array $sections
|
| 608 |
+
* @param Tribe__Customizer $customizer
|
| 609 |
+
*/
|
| 610 |
+
$this->sections = apply_filters( 'tribe_events_pro_customizer_sections', $this->sections, $this );
|
| 611 |
+
|
| 612 |
/**
|
| 613 |
* Filter the Sections within our Panel, now using the actual WP_Customize_Section
|
| 614 |
*
|
| 646 |
'priority' => 125,
|
| 647 |
);
|
| 648 |
|
| 649 |
+
/**
|
| 650 |
+
* Filter the Panel Arguments for WP Customize
|
| 651 |
+
*
|
| 652 |
+
* @deprecated
|
| 653 |
+
* @since 4.0
|
| 654 |
+
*
|
| 655 |
+
* @param array $args
|
| 656 |
+
* @param string $ID
|
| 657 |
+
* @param Tribe__Customizer $customizer
|
| 658 |
+
*/
|
| 659 |
+
$panel_args = apply_filters( 'tribe_events_pro_customizer_panel_args', $panel_args, $this->ID, $this );
|
| 660 |
+
|
| 661 |
/**
|
| 662 |
* Filter the Panel Arguments for WP Customize
|
| 663 |
*
|
| 689 |
* @return WP_Customize_Section
|
| 690 |
*/
|
| 691 |
public function register_section( $id, $args ) {
|
| 692 |
+
/**
|
| 693 |
+
* Filter the Section ID
|
| 694 |
+
*
|
| 695 |
+
* @deprecated
|
| 696 |
+
* @since 4.0
|
| 697 |
+
*
|
| 698 |
+
* @param string $section_id
|
| 699 |
+
* @param Tribe__Customizer $customizer
|
| 700 |
+
*/
|
| 701 |
+
$section_id = apply_filters( 'tribe_events_pro_customizer_section_id', $id, $this );
|
| 702 |
+
|
| 703 |
/**
|
| 704 |
* Filter the Section ID
|
| 705 |
*
|
| 708 |
* @param string $section_id
|
| 709 |
* @param Tribe__Customizer $customizer
|
| 710 |
*/
|
| 711 |
+
$section_id = apply_filters( 'tribe_customizer_section_id', $section_id, $this );
|
| 712 |
|
| 713 |
// Tries to fetch the section
|
| 714 |
$section = $this->manager->get_section( $section_id );
|
| 718 |
return $section;
|
| 719 |
}
|
| 720 |
|
| 721 |
+
/**
|
| 722 |
+
* Filter the Section arguments, so that developers can filter arguments based on $section_id
|
| 723 |
+
*
|
| 724 |
+
* @deprecated
|
| 725 |
+
* @since 4.0
|
| 726 |
+
*
|
| 727 |
+
* @param array $args
|
| 728 |
+
* @param string $section_id
|
| 729 |
+
* @param Tribe__Customizer $customizer
|
| 730 |
+
*/
|
| 731 |
+
$section_args = apply_filters( 'tribe_events_pro_customizer_section_args', $args, $section_id, $this );
|
| 732 |
+
|
| 733 |
/**
|
| 734 |
* Filter the Section arguments, so that developers can filter arguments based on $section_id
|
| 735 |
*
|
common/src/Tribe/Data.php
CHANGED
|
@@ -65,7 +65,7 @@ class Tribe__Data implements ArrayAccess, Iterator {
|
|
| 65 |
* </p>
|
| 66 |
* <p>
|
| 67 |
* The return value will be casted to boolean if non-boolean was returned.
|
| 68 |
-
* @since
|
| 69 |
*/
|
| 70 |
public function offsetExists( $offset ) {
|
| 71 |
return isset( $this->data[ $offset ] );
|
|
@@ -79,7 +79,7 @@ class Tribe__Data implements ArrayAccess, Iterator {
|
|
| 79 |
* The offset to retrieve.
|
| 80 |
* </p>
|
| 81 |
* @return mixed Can return all value types.
|
| 82 |
-
* @since
|
| 83 |
*/
|
| 84 |
public function offsetGet( $offset ) {
|
| 85 |
return isset( $this->data[ $offset ] )
|
|
@@ -98,7 +98,7 @@ class Tribe__Data implements ArrayAccess, Iterator {
|
|
| 98 |
* The value to set.
|
| 99 |
* </p>
|
| 100 |
* @return void
|
| 101 |
-
* @since
|
| 102 |
*/
|
| 103 |
public function offsetSet( $offset, $value ) {
|
| 104 |
$this->data[ $offset ] = $value;
|
|
@@ -112,7 +112,7 @@ class Tribe__Data implements ArrayAccess, Iterator {
|
|
| 112 |
* The offset to unset.
|
| 113 |
* </p>
|
| 114 |
* @return void
|
| 115 |
-
* @since
|
| 116 |
*/
|
| 117 |
public function offsetUnset( $offset ) {
|
| 118 |
unset( $this->data[ $offset ] );
|
|
@@ -159,7 +159,7 @@ class Tribe__Data implements ArrayAccess, Iterator {
|
|
| 159 |
*
|
| 160 |
* @link http://php.net/manual/en/iterator.current.php
|
| 161 |
* @return mixed Can return any type.
|
| 162 |
-
* @since
|
| 163 |
*/
|
| 164 |
public function current() {
|
| 165 |
$keys = array_keys( $this->data );
|
|
@@ -172,7 +172,7 @@ class Tribe__Data implements ArrayAccess, Iterator {
|
|
| 172 |
*
|
| 173 |
* @link http://php.net/manual/en/iterator.next.php
|
| 174 |
* @return void Any returned value is ignored.
|
| 175 |
-
* @since
|
| 176 |
*/
|
| 177 |
public function next() {
|
| 178 |
$keys = array_keys( $this->data );
|
|
@@ -189,7 +189,7 @@ class Tribe__Data implements ArrayAccess, Iterator {
|
|
| 189 |
*
|
| 190 |
* @link http://php.net/manual/en/iterator.key.php
|
| 191 |
* @return mixed scalar on success, or null on failure.
|
| 192 |
-
* @since
|
| 193 |
*/
|
| 194 |
public function key() {
|
| 195 |
$keys = array_keys( $this->data );
|
|
@@ -203,7 +203,7 @@ class Tribe__Data implements ArrayAccess, Iterator {
|
|
| 203 |
* @link http://php.net/manual/en/iterator.valid.php
|
| 204 |
* @return boolean The return value will be casted to boolean and then evaluated.
|
| 205 |
* Returns true on success or false on failure.
|
| 206 |
-
* @since
|
| 207 |
*/
|
| 208 |
public function valid() {
|
| 209 |
$keys = array_keys( $this->data );
|
|
@@ -216,7 +216,7 @@ class Tribe__Data implements ArrayAccess, Iterator {
|
|
| 216 |
*
|
| 217 |
* @link http://php.net/manual/en/iterator.rewind.php
|
| 218 |
* @return void Any returned value is ignored.
|
| 219 |
-
* @since
|
| 220 |
*/
|
| 221 |
public function rewind() {
|
| 222 |
$this->index = 0;
|
| 65 |
* </p>
|
| 66 |
* <p>
|
| 67 |
* The return value will be casted to boolean if non-boolean was returned.
|
| 68 |
+
* @since 5.0.0
|
| 69 |
*/
|
| 70 |
public function offsetExists( $offset ) {
|
| 71 |
return isset( $this->data[ $offset ] );
|
| 79 |
* The offset to retrieve.
|
| 80 |
* </p>
|
| 81 |
* @return mixed Can return all value types.
|
| 82 |
+
* @since 5.0.0
|
| 83 |
*/
|
| 84 |
public function offsetGet( $offset ) {
|
| 85 |
return isset( $this->data[ $offset ] )
|
| 98 |
* The value to set.
|
| 99 |
* </p>
|
| 100 |
* @return void
|
| 101 |
+
* @since 5.0.0
|
| 102 |
*/
|
| 103 |
public function offsetSet( $offset, $value ) {
|
| 104 |
$this->data[ $offset ] = $value;
|
| 112 |
* The offset to unset.
|
| 113 |
* </p>
|
| 114 |
* @return void
|
| 115 |
+
* @since 5.0.0
|
| 116 |
*/
|
| 117 |
public function offsetUnset( $offset ) {
|
| 118 |
unset( $this->data[ $offset ] );
|
| 159 |
*
|
| 160 |
* @link http://php.net/manual/en/iterator.current.php
|
| 161 |
* @return mixed Can return any type.
|
| 162 |
+
* @since 5.0.0
|
| 163 |
*/
|
| 164 |
public function current() {
|
| 165 |
$keys = array_keys( $this->data );
|
| 172 |
*
|
| 173 |
* @link http://php.net/manual/en/iterator.next.php
|
| 174 |
* @return void Any returned value is ignored.
|
| 175 |
+
* @since 5.0.0
|
| 176 |
*/
|
| 177 |
public function next() {
|
| 178 |
$keys = array_keys( $this->data );
|
| 189 |
*
|
| 190 |
* @link http://php.net/manual/en/iterator.key.php
|
| 191 |
* @return mixed scalar on success, or null on failure.
|
| 192 |
+
* @since 5.0.0
|
| 193 |
*/
|
| 194 |
public function key() {
|
| 195 |
$keys = array_keys( $this->data );
|
| 203 |
* @link http://php.net/manual/en/iterator.valid.php
|
| 204 |
* @return boolean The return value will be casted to boolean and then evaluated.
|
| 205 |
* Returns true on success or false on failure.
|
| 206 |
+
* @since 5.0.0
|
| 207 |
*/
|
| 208 |
public function valid() {
|
| 209 |
$keys = array_keys( $this->data );
|
| 216 |
*
|
| 217 |
* @link http://php.net/manual/en/iterator.rewind.php
|
| 218 |
* @return void Any returned value is ignored.
|
| 219 |
+
* @since 5.0.0
|
| 220 |
*/
|
| 221 |
public function rewind() {
|
| 222 |
$this->index = 0;
|
common/src/Tribe/Date_Utils.php
CHANGED
|
@@ -3,9 +3,6 @@
|
|
| 3 |
* Date utility functions used throughout TEC + Addons
|
| 4 |
*/
|
| 5 |
|
| 6 |
-
use Tribe\Utils\Date_I18n;
|
| 7 |
-
use Tribe\Utils\Date_I18n_Immutable;
|
| 8 |
-
|
| 9 |
// Don't load directly
|
| 10 |
|
| 11 |
if ( ! defined( 'ABSPATH' ) ) {
|
|
@@ -26,38 +23,11 @@ if ( ! class_exists( 'Tribe__Date_Utils' ) ) {
|
|
| 26 |
const DBTIMEFORMAT = 'H:i:s';
|
| 27 |
const DBYEARMONTHTIMEFORMAT = 'Y-m';
|
| 28 |
|
| 29 |
-
/**
|
| 30 |
-
* Default datepicker format index.
|
| 31 |
-
*
|
| 32 |
-
* @since 4.11.0.1
|
| 33 |
-
*
|
| 34 |
-
* @var int
|
| 35 |
-
*/
|
| 36 |
-
private static $default_datepicker_format_index = 1;
|
| 37 |
-
|
| 38 |
private static $localized_months_full = array();
|
| 39 |
private static $localized_months_short = array();
|
| 40 |
private static $localized_weekdays = array();
|
| 41 |
private static $localized_months = array();
|
| 42 |
|
| 43 |
-
/**
|
| 44 |
-
* Get the datepickerFormat index.
|
| 45 |
-
*
|
| 46 |
-
* @since 4.11.0.1
|
| 47 |
-
*
|
| 48 |
-
* @return int
|
| 49 |
-
*/
|
| 50 |
-
public static function get_datepicker_format_index() {
|
| 51 |
-
/**
|
| 52 |
-
* Filter the datepickerFormat index.
|
| 53 |
-
*
|
| 54 |
-
* @since 4.11.0.1
|
| 55 |
-
*
|
| 56 |
-
* @param int $format_index Index of datepickerFormat.
|
| 57 |
-
*/
|
| 58 |
-
return apply_filters( 'tribe_datepicker_format_index', tribe_get_option( 'datepickerFormat', static::$default_datepicker_format_index ) );
|
| 59 |
-
}
|
| 60 |
-
|
| 61 |
/**
|
| 62 |
* Try to format a Date to the Default Datepicker format
|
| 63 |
*
|
|
@@ -69,14 +39,14 @@ if ( ! class_exists( 'Tribe__Date_Utils' ) ) {
|
|
| 69 |
*/
|
| 70 |
public static function maybe_format_from_datepicker( $date, $datepicker = null ) {
|
| 71 |
if ( ! is_numeric( $datepicker ) ) {
|
| 72 |
-
$datepicker =
|
| 73 |
}
|
| 74 |
|
| 75 |
if ( is_numeric( $datepicker ) ) {
|
| 76 |
$datepicker = self::datepicker_formats( $datepicker );
|
| 77 |
}
|
| 78 |
|
| 79 |
-
$default_datepicker = self::datepicker_formats(
|
| 80 |
|
| 81 |
// If the current datepicker is the default we don't care
|
| 82 |
if ( $datepicker === $default_datepicker ) {
|
|
@@ -96,37 +66,25 @@ if ( ! class_exists( 'Tribe__Date_Utils' ) ) {
|
|
| 96 |
|
| 97 |
// The datepicker has issues when a period separator and no leading zero is used. Those formats are purposefully omitted.
|
| 98 |
$formats = array(
|
| 99 |
-
|
| 100 |
-
|
| 101 |
-
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
'm0' => 'Y-m',
|
| 112 |
-
'm1' => 'n/Y',
|
| 113 |
-
'm2' => 'm/Y',
|
| 114 |
-
'm3' => 'n/Y',
|
| 115 |
-
'm4' => 'm/Y',
|
| 116 |
-
'm5' => 'n-Y',
|
| 117 |
-
'm6' => 'm-Y',
|
| 118 |
-
'm7' => 'n-Y',
|
| 119 |
-
'm8' => 'm-Y',
|
| 120 |
-
'm9' => 'Y.m',
|
| 121 |
-
'm10' => 'm.Y',
|
| 122 |
-
'm11' => 'm.Y',
|
| 123 |
);
|
| 124 |
|
| 125 |
if ( is_null( $translate ) ) {
|
| 126 |
return $formats;
|
| 127 |
}
|
| 128 |
|
| 129 |
-
return isset( $formats[ $translate ] ) ? $formats[ $translate ] : $formats[
|
| 130 |
}
|
| 131 |
|
| 132 |
/**
|
|
@@ -262,22 +220,6 @@ if ( ! class_exists( 'Tribe__Date_Utils' ) ) {
|
|
| 262 |
return date( $format, $date );
|
| 263 |
}
|
| 264 |
|
| 265 |
-
/**
|
| 266 |
-
* Returns as string the nearest half a hour for a given valid string datetime.
|
| 267 |
-
*
|
| 268 |
-
* @since 4.10.2
|
| 269 |
-
*
|
| 270 |
-
* @param string $date Valid DateTime string.
|
| 271 |
-
*
|
| 272 |
-
* @return string Rounded datetime string
|
| 273 |
-
*/
|
| 274 |
-
public static function round_nearest_half_hour( $date ) {
|
| 275 |
-
$date_object = static::build_date_object( $date );
|
| 276 |
-
$rounded_minutes = floor( $date_object->format( 'i' ) / 30 ) * 30;
|
| 277 |
-
|
| 278 |
-
return $date_object->format( 'Y-m-d H:' ) . $rounded_minutes . ':00';
|
| 279 |
-
}
|
| 280 |
-
|
| 281 |
/**
|
| 282 |
* Returns the time only.
|
| 283 |
*
|
|
@@ -1249,38 +1191,34 @@ if ( ! class_exists( 'Tribe__Date_Utils' ) ) {
|
|
| 1249 |
return clone $datetime;
|
| 1250 |
}
|
| 1251 |
|
| 1252 |
-
if ( class_exists(
|
| 1253 |
// Return the mutable version of the date.
|
| 1254 |
-
return
|
| 1255 |
}
|
| 1256 |
|
| 1257 |
$timezone_object = null;
|
| 1258 |
-
$datetime = empty( $datetime ) ? 'now' : $datetime;
|
| 1259 |
|
| 1260 |
try {
|
| 1261 |
// PHP 5.2 will not throw an exception but will generate an error.
|
| 1262 |
$utc = new DateTimeZone( 'UTC' );
|
| 1263 |
-
$timezone_object = Tribe__Timezones::build_timezone_object( $timezone );
|
| 1264 |
|
| 1265 |
if ( self::is_timestamp( $datetime ) ) {
|
| 1266 |
-
|
| 1267 |
-
|
| 1268 |
-
return new Date_I18n( '@' . $datetime, $timestamp_timezone );
|
| 1269 |
}
|
| 1270 |
|
|
|
|
|
|
|
| 1271 |
set_error_handler( 'tribe_catch_and_throw' );
|
| 1272 |
-
$date = new
|
| 1273 |
restore_error_handler();
|
| 1274 |
} catch ( Exception $e ) {
|
| 1275 |
-
// If we encounter an error, we need to restore after catching.
|
| 1276 |
-
restore_error_handler();
|
| 1277 |
-
|
| 1278 |
if ( $timezone_object === null ) {
|
| 1279 |
$timezone_object = Tribe__Timezones::build_timezone_object( $timezone );
|
| 1280 |
}
|
| 1281 |
|
| 1282 |
return $with_fallback
|
| 1283 |
-
? new
|
| 1284 |
: false;
|
| 1285 |
}
|
| 1286 |
|
|
@@ -1298,301 +1236,7 @@ if ( ! class_exists( 'Tribe__Date_Utils' ) ) {
|
|
| 1298 |
* like `strtotime`, or not.
|
| 1299 |
*/
|
| 1300 |
public static function is_valid_date( $date ) {
|
| 1301 |
-
|
| 1302 |
-
|
| 1303 |
-
$cache_date_check = tribe_get_var( $cache_var_name, [] );
|
| 1304 |
-
|
| 1305 |
-
if ( isset( $cache_date_check[ $date ] ) ) {
|
| 1306 |
-
return $cache_date_check[ $date ];
|
| 1307 |
-
}
|
| 1308 |
-
|
| 1309 |
-
$cache_date_check[ $date ] = self::build_date_object( $date, null, false ) instanceof DateTimeInterface;
|
| 1310 |
-
|
| 1311 |
-
tribe_set_var( $cache_var_name, $cache_date_check );
|
| 1312 |
-
|
| 1313 |
-
return $cache_date_check[ $date ];
|
| 1314 |
-
}
|
| 1315 |
-
|
| 1316 |
-
/**
|
| 1317 |
-
* Returns the DateTime object representing the start of the week for a date.
|
| 1318 |
-
*
|
| 1319 |
-
* @since 4.9.21
|
| 1320 |
-
*
|
| 1321 |
-
* @throws Exception
|
| 1322 |
-
*
|
| 1323 |
-
* @param string|int|\DateTime $date The date string, timestamp or object.
|
| 1324 |
-
* @param int|null $start_of_week The number representing the start of week day as handled by
|
| 1325 |
-
* WordPress: `0` (for Sunday) through `6` (for Saturday).
|
| 1326 |
-
*
|
| 1327 |
-
* @return array An array of objects representing the week start and end days, or `false` if the
|
| 1328 |
-
* supplied date is invalid. The timezone of the returned object is set to the site one.
|
| 1329 |
-
* The week start has its time set to `00:00:00`, the week end will have its time set
|
| 1330 |
-
* `23:59:59`.
|
| 1331 |
-
*/
|
| 1332 |
-
public static function get_week_start_end( $date, $start_of_week = null ) {
|
| 1333 |
-
static $cache_var_name = __FUNCTION__;
|
| 1334 |
-
|
| 1335 |
-
$cache_week_start_end = tribe_get_var( $cache_var_name, [] );
|
| 1336 |
-
|
| 1337 |
-
$date_obj = static::build_date_object( $date );
|
| 1338 |
-
$date_obj->setTime( 0, 0, 0 );
|
| 1339 |
-
|
| 1340 |
-
$date_string = $date_obj->format( static::DBDATEFORMAT );
|
| 1341 |
-
|
| 1342 |
-
// `0` (for Sunday) through `6` (for Saturday), the way WP handles the `start_of_week` option.
|
| 1343 |
-
$week_start_day = null !== $start_of_week
|
| 1344 |
-
? (int) $start_of_week
|
| 1345 |
-
: (int) get_option( 'start_of_week', 0 );
|
| 1346 |
-
|
| 1347 |
-
$memory_cache_key = "{$date_string}:{$week_start_day}";
|
| 1348 |
-
|
| 1349 |
-
if ( isset( $cache_week_start_end[ $memory_cache_key ] ) ) {
|
| 1350 |
-
return $cache_week_start_end[ $memory_cache_key ];
|
| 1351 |
-
}
|
| 1352 |
-
|
| 1353 |
-
$cache_key = md5(
|
| 1354 |
-
__METHOD__ . serialize( [ $date_obj->format( static::DBDATEFORMAT ), $week_start_day ] )
|
| 1355 |
-
);
|
| 1356 |
-
$cache = tribe( 'cache' );
|
| 1357 |
-
|
| 1358 |
-
if ( false !== $cached = $cache[ $cache_key ] ) {
|
| 1359 |
-
return $cached;
|
| 1360 |
-
}
|
| 1361 |
-
|
| 1362 |
-
// `0` (for Sunday) through `6` (for Saturday), the way WP handles the `start_of_week` option.
|
| 1363 |
-
$date_day = (int) $date_obj->format( 'w' );
|
| 1364 |
-
|
| 1365 |
-
$week_offset = 0;
|
| 1366 |
-
if ( 0 === $date_day && 0 !== $week_start_day ) {
|
| 1367 |
-
$week_offset = 0;
|
| 1368 |
-
} elseif ( $date_day < $week_start_day ) {
|
| 1369 |
-
// If the current date of the week is before the start of the week, move back a week.
|
| 1370 |
-
$week_offset = -1;
|
| 1371 |
-
} elseif ( 0 === $date_day ) {
|
| 1372 |
-
// When start of the week is on a sunday we add a week.
|
| 1373 |
-
$week_offset = 1;
|
| 1374 |
-
}
|
| 1375 |
-
|
| 1376 |
-
$week_start = clone $date_obj;
|
| 1377 |
-
|
| 1378 |
-
/*
|
| 1379 |
-
* From the PHP docs, the `W` format stands for:
|
| 1380 |
-
* - ISO-8601 week number of year, weeks starting on Monday
|
| 1381 |
-
*/
|
| 1382 |
-
$week_start->setISODate(
|
| 1383 |
-
(int) $week_start->format( 'o' ),
|
| 1384 |
-
(int) $week_start->format( 'W' ) + $week_offset,
|
| 1385 |
-
$week_start_day
|
| 1386 |
-
);
|
| 1387 |
-
|
| 1388 |
-
$week_end = clone $week_start;
|
| 1389 |
-
// Add 6 days, then move at the end of the day.
|
| 1390 |
-
$week_end->add( new DateInterval( 'P6D' ) );
|
| 1391 |
-
$week_end->setTime( 23, 59, 59 );
|
| 1392 |
-
|
| 1393 |
-
$week_start = static::immutable( $week_start );
|
| 1394 |
-
$week_end = static::immutable( $week_end );
|
| 1395 |
-
|
| 1396 |
-
$cache[ $cache_key ] = [ $week_start, $week_end ];
|
| 1397 |
-
$cache_week_start_end[ $memory_cache_key ] = [ $week_start, $week_end ];
|
| 1398 |
-
|
| 1399 |
-
tribe_set_var( $cache_var_name, $cache_week_start_end );
|
| 1400 |
-
|
| 1401 |
-
return [ $week_start, $week_end ];
|
| 1402 |
-
}
|
| 1403 |
-
|
| 1404 |
-
/**
|
| 1405 |
-
* Given a specific DateTime we determine the end of that day based on our Internal End of Day Cut-off.
|
| 1406 |
-
*
|
| 1407 |
-
* @since 4.11.2
|
| 1408 |
-
*
|
| 1409 |
-
* @param string|DateTimeInterface $date Date that we are getting the end of day from.
|
| 1410 |
-
* @param null|string $cutoff Which cutoff to use.
|
| 1411 |
-
*
|
| 1412 |
-
* @return DateTimeInterface|false Returns a DateTimeInterface when a valid date is given or false.
|
| 1413 |
-
*/
|
| 1414 |
-
public static function get_shifted_end_of_day( $date, $cutoff = null ) {
|
| 1415 |
-
$date_obj = static::build_date_object( $date );
|
| 1416 |
-
|
| 1417 |
-
if ( ! $date_obj ) {
|
| 1418 |
-
return false;
|
| 1419 |
-
}
|
| 1420 |
-
|
| 1421 |
-
$start_of_day = clone $date_obj;
|
| 1422 |
-
$end_of_day = clone $date_obj;
|
| 1423 |
-
|
| 1424 |
-
if ( empty( $cutoff ) || ! is_string( $cutoff ) || false === strpos( $cutoff, ':' ) ) {
|
| 1425 |
-
$cutoff = tribe_get_option( 'multiDayCutoff', '00:00' );
|
| 1426 |
-
}
|
| 1427 |
-
|
| 1428 |
-
list( $hours_to_add, $minutes_to_add ) = array_map( 'absint', explode( ':', $cutoff ) );
|
| 1429 |
-
|
| 1430 |
-
$seconds_to_add = ( $hours_to_add * HOUR_IN_SECONDS ) + ( $minutes_to_add * MINUTE_IN_SECONDS );
|
| 1431 |
-
if ( 0 !== $seconds_to_add ) {
|
| 1432 |
-
$interval = static::interval( "PT{$seconds_to_add}S" );
|
| 1433 |
-
}
|
| 1434 |
-
|
| 1435 |
-
$start_of_day->setTime( '0', '0', '0' );
|
| 1436 |
-
$end_of_day->setTime( '23', '59', '59' );
|
| 1437 |
-
|
| 1438 |
-
if ( 0 !== $seconds_to_add ) {
|
| 1439 |
-
$start_of_day->add( $interval );
|
| 1440 |
-
$end_of_day->add( $interval );
|
| 1441 |
-
}
|
| 1442 |
-
|
| 1443 |
-
if ( $end_of_day >= $date_obj && $date_obj >= $start_of_day ) {
|
| 1444 |
-
return $end_of_day;
|
| 1445 |
-
}
|
| 1446 |
-
|
| 1447 |
-
$start_of_day->sub( static::interval( 'P1D' ) );
|
| 1448 |
-
|
| 1449 |
-
if ( $start_of_day < $date_obj ) {
|
| 1450 |
-
$end_of_day->sub( static::interval( 'P1D' ) );
|
| 1451 |
-
}
|
| 1452 |
-
|
| 1453 |
-
return $end_of_day;
|
| 1454 |
-
}
|
| 1455 |
-
|
| 1456 |
-
/**
|
| 1457 |
-
* Given a specific DateTime we determine the start of that day based on our Internal End of Day Cut-off.
|
| 1458 |
-
*
|
| 1459 |
-
* @since 4.11.2
|
| 1460 |
-
*
|
| 1461 |
-
* @param string|DateTimeInterface $date Date that we are getting the start of day from.
|
| 1462 |
-
* @param null|string $cutoff Which cutoff to use.
|
| 1463 |
-
*
|
| 1464 |
-
* @return DateTimeInterface|false Returns a DateTimeInterface when a valid date is given or false.
|
| 1465 |
-
*/
|
| 1466 |
-
public static function get_shifted_start_of_day( $date, $cutoff = null ) {
|
| 1467 |
-
$date_obj = static::build_date_object( $date );
|
| 1468 |
-
|
| 1469 |
-
if ( ! $date_obj ) {
|
| 1470 |
-
return false;
|
| 1471 |
-
}
|
| 1472 |
-
|
| 1473 |
-
$start_of_day = clone $date_obj;
|
| 1474 |
-
$end_of_day = clone $date_obj;
|
| 1475 |
-
|
| 1476 |
-
if ( empty( $cutoff ) || ! is_string( $cutoff ) || false === strpos( $cutoff, ':' ) ) {
|
| 1477 |
-
$cutoff = tribe_get_option( 'multiDayCutoff', '00:00' );
|
| 1478 |
-
}
|
| 1479 |
-
|
| 1480 |
-
list( $hours_to_add, $minutes_to_add ) = array_map( 'absint', explode( ':', $cutoff ) );
|
| 1481 |
-
|
| 1482 |
-
$seconds_to_add = ( $hours_to_add * HOUR_IN_SECONDS ) + ( $minutes_to_add * MINUTE_IN_SECONDS );
|
| 1483 |
-
if ( 0 !== $seconds_to_add ) {
|
| 1484 |
-
$interval = static::interval( "PT{$seconds_to_add}S" );
|
| 1485 |
-
}
|
| 1486 |
-
|
| 1487 |
-
$start_of_day->setTime( '0', '0', '0' );
|
| 1488 |
-
$end_of_day->setTime( '23', '59', '59' );
|
| 1489 |
-
|
| 1490 |
-
if ( 0 !== $seconds_to_add ) {
|
| 1491 |
-
$start_of_day->add( $interval );
|
| 1492 |
-
$end_of_day->add( $interval );
|
| 1493 |
-
}
|
| 1494 |
-
|
| 1495 |
-
if ( $end_of_day <= $date_obj && $date_obj >= $start_of_day ) {
|
| 1496 |
-
return $start_of_day;
|
| 1497 |
-
}
|
| 1498 |
-
|
| 1499 |
-
$end_of_day->sub( static::interval( 'P1D' ) );
|
| 1500 |
-
|
| 1501 |
-
if ( $end_of_day > $date_obj ) {
|
| 1502 |
-
$start_of_day->sub( static::interval( 'P1D' ) );
|
| 1503 |
-
}
|
| 1504 |
-
|
| 1505 |
-
return $start_of_day;
|
| 1506 |
-
}
|
| 1507 |
-
|
| 1508 |
-
/**
|
| 1509 |
-
* Builds and returns a `DateInterval` object from the interval specification.
|
| 1510 |
-
*
|
| 1511 |
-
* For performance purposes the use of `DateInterval` specifications is preferred, so `P1D` is better than
|
| 1512 |
-
* `1 day`.
|
| 1513 |
-
*
|
| 1514 |
-
* @since 4.10.2
|
| 1515 |
-
*
|
| 1516 |
-
* @return DateInterval The built date interval object.
|
| 1517 |
-
*/
|
| 1518 |
-
public static function interval( $interval_spec ) {
|
| 1519 |
-
try {
|
| 1520 |
-
$interval = new \DateInterval( $interval_spec );
|
| 1521 |
-
} catch ( \Exception $e ) {
|
| 1522 |
-
$interval = DateInterval::createFromDateString( $interval_spec );
|
| 1523 |
-
}
|
| 1524 |
-
|
| 1525 |
-
return $interval;
|
| 1526 |
-
}
|
| 1527 |
-
|
| 1528 |
-
/**
|
| 1529 |
-
* Builds the immutable version of a date from a string, integer (timestamp) or \DateTime object.
|
| 1530 |
-
*
|
| 1531 |
-
* It's the immutable version of the `Tribe__Date_Utils::build_date_object` method.
|
| 1532 |
-
*
|
| 1533 |
-
* @since 4.10.2
|
| 1534 |
-
*
|
| 1535 |
-
* @param string|DateTime|int $datetime A `strtotime` parse-able string, a DateTime object or
|
| 1536 |
-
* a timestamp; defaults to `now`.
|
| 1537 |
-
* @param string|DateTimeZone|null $timezone A timezone string, UTC offset or DateTimeZone object;
|
| 1538 |
-
* defaults to the site timezone; this parameter is ignored
|
| 1539 |
-
* if the `$datetime` parameter is a DatTime object.
|
| 1540 |
-
* @param bool $with_fallback Whether to return a DateTime object even when the date data is
|
| 1541 |
-
* invalid or not; defaults to `true`.
|
| 1542 |
-
*
|
| 1543 |
-
* @return DateTimeImmutable|false A DateTime object built using the specified date, time and timezone; if
|
| 1544 |
-
* `$with_fallback` is set to `false` then `false` will be returned if a
|
| 1545 |
-
* DateTime object could not be built.
|
| 1546 |
-
*/
|
| 1547 |
-
static function immutable( $datetime = 'now', $timezone = null, $with_fallback = true ) {
|
| 1548 |
-
if ( $datetime instanceof DateTimeImmutable ) {
|
| 1549 |
-
return $datetime;
|
| 1550 |
-
}
|
| 1551 |
-
|
| 1552 |
-
if ( $datetime instanceof DateTime ) {
|
| 1553 |
-
return Date_I18n_Immutable::createFromMutable( $datetime );
|
| 1554 |
-
}
|
| 1555 |
-
|
| 1556 |
-
$mutable = static::build_date_object( $datetime, $timezone, $with_fallback );
|
| 1557 |
-
|
| 1558 |
-
if ( false === $mutable ) {
|
| 1559 |
-
return false;
|
| 1560 |
-
}
|
| 1561 |
-
|
| 1562 |
-
$cache_key = md5( ( __METHOD__ . $mutable->getTimezone()->getName() . $mutable->getTimestamp() ) );
|
| 1563 |
-
$cache = tribe( 'cache' );
|
| 1564 |
-
|
| 1565 |
-
if ( false !== $cached = $cache[ $cache_key ] ) {
|
| 1566 |
-
return $cached;
|
| 1567 |
-
}
|
| 1568 |
-
|
| 1569 |
-
$immutable = Date_I18n_Immutable::createFromMutable( $mutable );
|
| 1570 |
-
|
| 1571 |
-
$cache[ $cache_key ] = $immutable;
|
| 1572 |
-
|
| 1573 |
-
return $immutable;
|
| 1574 |
-
}
|
| 1575 |
-
|
| 1576 |
-
/**
|
| 1577 |
-
* Builds a date object from a given datetime and timezone.
|
| 1578 |
-
*
|
| 1579 |
-
* An alias of the `Tribe__Date_Utils::build_date_object` function.
|
| 1580 |
-
*
|
| 1581 |
-
* @since 4.10.2
|
| 1582 |
-
*
|
| 1583 |
-
* @param string|DateTime|int $datetime A `strtotime` parse-able string, a DateTime object or
|
| 1584 |
-
* a timestamp; defaults to `now`.
|
| 1585 |
-
* @param string|DateTimeZone|null $timezone A timezone string, UTC offset or DateTimeZone object;
|
| 1586 |
-
* defaults to the site timezone; this parameter is ignored
|
| 1587 |
-
* if the `$datetime` parameter is a DatTime object.
|
| 1588 |
-
* @param bool $with_fallback Whether to return a DateTime object even when the date data is
|
| 1589 |
-
* invalid or not; defaults to `true`.
|
| 1590 |
-
*
|
| 1591 |
-
* @return DateTime|false A DateTime object built using the specified date, time and timezone; if `$with_fallback`
|
| 1592 |
-
* is set to `false` then `false` will be returned if a DateTime object could not be built.
|
| 1593 |
-
*/
|
| 1594 |
-
public static function mutable( $datetime = 'now', $timezone = null, $with_fallback = true ) {
|
| 1595 |
-
return static::build_date_object( $datetime, $timezone, $with_fallback );
|
| 1596 |
}
|
| 1597 |
}
|
| 1598 |
}
|
| 3 |
* Date utility functions used throughout TEC + Addons
|
| 4 |
*/
|
| 5 |
|
|
|
|
|
|
|
|
|
|
| 6 |
// Don't load directly
|
| 7 |
|
| 8 |
if ( ! defined( 'ABSPATH' ) ) {
|
| 23 |
const DBTIMEFORMAT = 'H:i:s';
|
| 24 |
const DBYEARMONTHTIMEFORMAT = 'Y-m';
|
| 25 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 26 |
private static $localized_months_full = array();
|
| 27 |
private static $localized_months_short = array();
|
| 28 |
private static $localized_weekdays = array();
|
| 29 |
private static $localized_months = array();
|
| 30 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 31 |
/**
|
| 32 |
* Try to format a Date to the Default Datepicker format
|
| 33 |
*
|
| 39 |
*/
|
| 40 |
public static function maybe_format_from_datepicker( $date, $datepicker = null ) {
|
| 41 |
if ( ! is_numeric( $datepicker ) ) {
|
| 42 |
+
$datepicker = tribe_get_option( 'datepickerFormat' );
|
| 43 |
}
|
| 44 |
|
| 45 |
if ( is_numeric( $datepicker ) ) {
|
| 46 |
$datepicker = self::datepicker_formats( $datepicker );
|
| 47 |
}
|
| 48 |
|
| 49 |
+
$default_datepicker = self::datepicker_formats( 0 );
|
| 50 |
|
| 51 |
// If the current datepicker is the default we don't care
|
| 52 |
if ( $datepicker === $default_datepicker ) {
|
| 66 |
|
| 67 |
// The datepicker has issues when a period separator and no leading zero is used. Those formats are purposefully omitted.
|
| 68 |
$formats = array(
|
| 69 |
+
'Y-m-d',
|
| 70 |
+
'n/j/Y',
|
| 71 |
+
'm/d/Y',
|
| 72 |
+
'j/n/Y',
|
| 73 |
+
'd/m/Y',
|
| 74 |
+
'n-j-Y',
|
| 75 |
+
'm-d-Y',
|
| 76 |
+
'j-n-Y',
|
| 77 |
+
'd-m-Y',
|
| 78 |
+
'Y.m.d',
|
| 79 |
+
'm.d.Y',
|
| 80 |
+
'd.m.Y',
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 81 |
);
|
| 82 |
|
| 83 |
if ( is_null( $translate ) ) {
|
| 84 |
return $formats;
|
| 85 |
}
|
| 86 |
|
| 87 |
+
return isset( $formats[ $translate ] ) ? $formats[ $translate ] : $formats[0];
|
| 88 |
}
|
| 89 |
|
| 90 |
/**
|
| 220 |
return date( $format, $date );
|
| 221 |
}
|
| 222 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 223 |
/**
|
| 224 |
* Returns the time only.
|
| 225 |
*
|
| 1191 |
return clone $datetime;
|
| 1192 |
}
|
| 1193 |
|
| 1194 |
+
if ( class_exists('DateTimeImmutable') && $datetime instanceof DateTimeImmutable ) {
|
| 1195 |
// Return the mutable version of the date.
|
| 1196 |
+
return new DateTime( $datetime->format( 'Y-m-d H:i:s' ), $datetime->getTimezone() );
|
| 1197 |
}
|
| 1198 |
|
| 1199 |
$timezone_object = null;
|
|
|
|
| 1200 |
|
| 1201 |
try {
|
| 1202 |
// PHP 5.2 will not throw an exception but will generate an error.
|
| 1203 |
$utc = new DateTimeZone( 'UTC' );
|
|
|
|
| 1204 |
|
| 1205 |
if ( self::is_timestamp( $datetime ) ) {
|
| 1206 |
+
// Timestamps timezone is always UTC.
|
| 1207 |
+
return new DateTime( '@' . $datetime, $utc );
|
|
|
|
| 1208 |
}
|
| 1209 |
|
| 1210 |
+
$timezone_object = Tribe__Timezones::build_timezone_object( $timezone );
|
| 1211 |
+
|
| 1212 |
set_error_handler( 'tribe_catch_and_throw' );
|
| 1213 |
+
$date = new DateTime( $datetime, $timezone_object );
|
| 1214 |
restore_error_handler();
|
| 1215 |
} catch ( Exception $e ) {
|
|
|
|
|
|
|
|
|
|
| 1216 |
if ( $timezone_object === null ) {
|
| 1217 |
$timezone_object = Tribe__Timezones::build_timezone_object( $timezone );
|
| 1218 |
}
|
| 1219 |
|
| 1220 |
return $with_fallback
|
| 1221 |
+
? new DateTime( 'now', $timezone_object )
|
| 1222 |
: false;
|
| 1223 |
}
|
| 1224 |
|
| 1236 |
* like `strtotime`, or not.
|
| 1237 |
*/
|
| 1238 |
public static function is_valid_date( $date ) {
|
| 1239 |
+
return self::build_date_object( $date, null, false ) instanceof DateTime;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1240 |
}
|
| 1241 |
}
|
| 1242 |
}
|
common/src/Tribe/Debug_Bar/Panels/Context.php
CHANGED
|
@@ -76,8 +76,8 @@ class Tribe__Debug_Bar__Panels__Context extends Debug_Bar_Panel {
|
|
| 76 |
|
| 77 |
$html .= '<tr>';
|
| 78 |
$html .= '<td><code>' . $key . '</code></td>';
|
| 79 |
-
$html .= '<td><code>' . ( isset( $context[ $key ] ) ?
|
| 80 |
-
$html .= '<td>' . ( false !== $orm_arg_key ? '<code>' .
|
| 81 |
$html .= '<td><code>' . ( isset( $locations[ $key ]['read'] ) ? 'yes' : 'no' ) . '</code></td>';
|
| 82 |
$html .= '<td><code>' . ( isset( $locations[ $key ]['write'] ) ? 'yes' : 'no' ) . '</code></td>';
|
| 83 |
$html .= '</tr>';
|
| 76 |
|
| 77 |
$html .= '<tr>';
|
| 78 |
$html .= '<td><code>' . $key . '</code></td>';
|
| 79 |
+
$html .= '<td><code>' . ( isset( $context[ $key ] ) ? $context[ $key ] : 'undefined' ) . '</code></td>';
|
| 80 |
+
$html .= '<td>' . ( false !== $orm_arg_key ? '<code>' . $orm_arg_key . ' => ' . $orm_arg_value . '</code>' : '' ) . '</td>';
|
| 81 |
$html .= '<td><code>' . ( isset( $locations[ $key ]['read'] ) ? 'yes' : 'no' ) . '</code></td>';
|
| 82 |
$html .= '<td><code>' . ( isset( $locations[ $key ]['write'] ) ? 'yes' : 'no' ) . '</code></td>';
|
| 83 |
$html .= '</tr>';
|
common/src/Tribe/Debug_Bar/Panels/Json_Ld.php
DELETED
|
@@ -1,84 +0,0 @@
|
|
| 1 |
-
<?php
|
| 2 |
-
/**
|
| 3 |
-
* JSON-LD information Debug Bar panel.
|
| 4 |
-
*
|
| 5 |
-
* @since 4.11.2
|
| 6 |
-
*
|
| 7 |
-
* @package Tribe\Debug_Bar\Panels
|
| 8 |
-
*/
|
| 9 |
-
|
| 10 |
-
class Tribe__Debug_Bar__Panels__Json_Ld extends Debug_Bar_Panel {
|
| 11 |
-
/**
|
| 12 |
-
* Returns the Panel name.
|
| 13 |
-
*
|
| 14 |
-
* @since 4.11.2
|
| 15 |
-
*
|
| 16 |
-
* @param null $title The panel input title.
|
| 17 |
-
*
|
| 18 |
-
* @return string The panel title
|
| 19 |
-
*/
|
| 20 |
-
public function title( $title = null ) {
|
| 21 |
-
return __( 'Modern Tribe JSON-LD Data', 'tribe-common' );
|
| 22 |
-
}
|
| 23 |
-
|
| 24 |
-
/**
|
| 25 |
-
* Renders the panel contents.
|
| 26 |
-
*
|
| 27 |
-
* @since 4.9.5
|
| 28 |
-
*/
|
| 29 |
-
public function render() {
|
| 30 |
-
$html = '<style>
|
| 31 |
-
#mt-debug-bar .mt-debug-bar-title {
|
| 32 |
-
margin-bottom: 1em;
|
| 33 |
-
}
|
| 34 |
-
#mt-debug-bar .mt-debug-bar-section {
|
| 35 |
-
padding: .5em .5em .5em 1em;
|
| 36 |
-
}
|
| 37 |
-
</style>';
|
| 38 |
-
$html .= '<div id="mt-debug-bar" class="mt-debug-bar-json-ld">';
|
| 39 |
-
|
| 40 |
-
$html .= '<header class="mt-debug-bar-title"><h2>' . esc_html__( 'Modern Tribe JSON-LD Data',
|
| 41 |
-
'tribe-common' ) . '</h2></header>';
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
$json_ld_data = array_filter( (array) tribe_cache()['json-ld-data'] );
|
| 45 |
-
|
| 46 |
-
if ( ! empty( $json_ld_data ) ) {
|
| 47 |
-
$html .= '<div class="mt-debug-bar-section">';
|
| 48 |
-
$html .= sprintf(
|
| 49 |
-
'<header>The request produced %d JSON-LD data %s.</header><br>',
|
| 50 |
-
count( $json_ld_data ),
|
| 51 |
-
count( $json_ld_data ) > 1 ? 'scripts' : 'script'
|
| 52 |
-
);
|
| 53 |
-
|
| 54 |
-
$html .= '<p>Copy the code below and paste it into ' .
|
| 55 |
-
'<a href="https://search.google.com/structured-data/testing-tool/u/0/" target="_blank">' .
|
| 56 |
-
'Google\'s Structured Data Testing Tool' .
|
| 57 |
-
'</a>' .
|
| 58 |
-
' to test it using the Code Snippet option.</p><br>';
|
| 59 |
-
|
| 60 |
-
foreach ( $json_ld_data as $full_entry ) {
|
| 61 |
-
preg_match(
|
| 62 |
-
'/(?<open>^\\s*<script[^>]*?>\\s*)(?<json>.*)(?<close>\\s<\\/script>)$/uism',
|
| 63 |
-
$full_entry,
|
| 64 |
-
$frags
|
| 65 |
-
);
|
| 66 |
-
|
| 67 |
-
if ( isset( $frags['open'], $frags['json'], $frags['close'] ) ) {
|
| 68 |
-
// Let's try and format it if we've got all the pieces.
|
| 69 |
-
$full_entry = $frags['open']
|
| 70 |
-
. json_encode( json_decode( $frags['json'], true ), JSON_PRETTY_PRINT )
|
| 71 |
-
. $frags['close'];
|
| 72 |
-
}
|
| 73 |
-
|
| 74 |
-
$html .= sprintf( '<pre><code>%s</code></pre>', esc_html( $full_entry ) );
|
| 75 |
-
}
|
| 76 |
-
|
| 77 |
-
$html .= '</div>';
|
| 78 |
-
}
|
| 79 |
-
|
| 80 |
-
$html .= '</div>';
|
| 81 |
-
|
| 82 |
-
echo $html;
|
| 83 |
-
}
|
| 84 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
common/src/Tribe/Dependency.php
CHANGED
|
@@ -4,7 +4,7 @@ defined( 'WPINC' ) or die;
|
|
| 4 |
|
| 5 |
if ( ! class_exists( 'Tribe__Dependency' ) ) {
|
| 6 |
/**
|
| 7 |
-
* Tracks which
|
| 8 |
*/
|
| 9 |
class Tribe__Dependency {
|
| 10 |
|
|
@@ -44,12 +44,13 @@ if ( ! class_exists( 'Tribe__Dependency' ) ) {
|
|
| 44 |
*
|
| 45 |
* @since 4.9
|
| 46 |
*
|
| 47 |
-
* @param string
|
| 48 |
-
* @param null|string
|
| 49 |
-
* @param null|string
|
| 50 |
-
* @param array
|
| 51 |
*/
|
| 52 |
public function add_registered_plugin( $main_class, $version = null, $path = null, $dependencies = array() ) {
|
|
|
|
| 53 |
$plugin = array(
|
| 54 |
'class' => $main_class,
|
| 55 |
'version' => $version,
|
|
@@ -62,6 +63,7 @@ if ( ! class_exists( 'Tribe__Dependency' ) ) {
|
|
| 62 |
if ( $path ) {
|
| 63 |
$this->admin_messages[ $main_class ] = new Tribe__Admin__Notice__Plugin_Download( $path );
|
| 64 |
}
|
|
|
|
| 65 |
}
|
| 66 |
|
| 67 |
/**
|
|
@@ -83,6 +85,7 @@ if ( ! class_exists( 'Tribe__Dependency' ) ) {
|
|
| 83 |
* @param string $path Path to the main plugin/bootstrap file
|
| 84 |
*/
|
| 85 |
public function add_active_plugin( $main_class, $version = null, $path = null ) {
|
|
|
|
| 86 |
$plugin = array(
|
| 87 |
'class' => $main_class,
|
| 88 |
'version' => $version,
|
|
@@ -228,6 +231,7 @@ if ( ! class_exists( 'Tribe__Dependency' ) ) {
|
|
| 228 |
* @return bool
|
| 229 |
*/
|
| 230 |
public function is_plugin_version( $main_class, $version, $compare = '>=' ) {
|
|
|
|
| 231 |
//active plugin check to see if the correct version is active
|
| 232 |
if ( ! $this->is_plugin_active( $main_class ) ) {
|
| 233 |
return false;
|
|
@@ -250,6 +254,7 @@ if ( ! class_exists( 'Tribe__Dependency' ) ) {
|
|
| 250 |
* @return bool
|
| 251 |
*/
|
| 252 |
public function is_plugin_version_registered( $main_class, $version, $compare = '>=' ) {
|
|
|
|
| 253 |
//registered plugin check if addon as it tests if it might load
|
| 254 |
if ( ! $this->is_plugin_registered( $main_class ) ) {
|
| 255 |
return false;
|
|
@@ -268,6 +273,7 @@ if ( ! class_exists( 'Tribe__Dependency' ) ) {
|
|
| 268 |
* @return bool
|
| 269 |
*/
|
| 270 |
public function has_requisite_plugins( $plugins_required = array() ) {
|
|
|
|
| 271 |
foreach ( $plugins_required as $class => $version ) {
|
| 272 |
// Return false if the plugin is not set or is a lesser version
|
| 273 |
if ( ! $this->is_plugin_active( $class ) ) {
|
|
@@ -296,30 +302,31 @@ if ( ! class_exists( 'Tribe__Dependency' ) ) {
|
|
| 296 |
}
|
| 297 |
|
| 298 |
/**
|
| 299 |
-
* Gets all dependencies or single class requirements
|
| 300 |
-
*
|
|
|
|
| 301 |
*
|
| 302 |
* @since 4.9
|
| 303 |
*
|
| 304 |
-
* @param array
|
| 305 |
-
* @param array
|
| 306 |
-
* @param bool
|
| 307 |
*
|
| 308 |
-
* @return
|
| 309 |
*/
|
| 310 |
public function has_valid_dependencies( $plugin, $dependencies = array(), $addon = false ) {
|
|
|
|
| 311 |
if ( empty( $dependencies ) ) {
|
| 312 |
return true;
|
| 313 |
}
|
| 314 |
|
| 315 |
$failed_dependency = 0;
|
| 316 |
-
|
| 317 |
-
$tribe_plugins = new Tribe__Plugins();
|
| 318 |
|
| 319 |
foreach ( $dependencies as $class => $version ) {
|
| 320 |
|
| 321 |
// if no class for add-on
|
| 322 |
-
$checked_plugin
|
| 323 |
if ( $addon && empty( $checked_plugin ) ) {
|
| 324 |
continue;
|
| 325 |
}
|
|
@@ -329,6 +336,15 @@ if ( ! class_exists( 'Tribe__Dependency' ) ) {
|
|
| 329 |
continue;
|
| 330 |
}
|
| 331 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 332 |
$dependent_plugin = $tribe_plugins->get_plugin_by_class( $class );
|
| 333 |
|
| 334 |
$pue = $this->get_pue_from_class( $dependent_plugin['class'] );
|
|
@@ -409,11 +425,11 @@ if ( ! class_exists( 'Tribe__Dependency' ) ) {
|
|
| 409 |
*
|
| 410 |
* @since 4.9
|
| 411 |
*
|
| 412 |
-
* @param
|
| 413 |
-
* @param
|
| 414 |
-
* @param
|
| 415 |
-
* @param array
|
| 416 |
-
* @param array
|
| 417 |
*/
|
| 418 |
public function register_plugin( $file_path, $main_class, $version, $classes_req = array(), $dependencies = array() ) {
|
| 419 |
/**
|
|
@@ -475,7 +491,11 @@ if ( ! class_exists( 'Tribe__Dependency' ) ) {
|
|
| 475 |
*
|
| 476 |
* @since 4.9
|
| 477 |
*
|
|
|
|
| 478 |
* @param string $main_class The Main/base class for this plugin
|
|
|
|
|
|
|
|
|
|
| 479 |
*
|
| 480 |
* @return bool Indicates if plugin should continue initialization
|
| 481 |
*/
|
|
@@ -483,25 +503,25 @@ if ( ! class_exists( 'Tribe__Dependency' ) ) {
|
|
| 483 |
|
| 484 |
$parent_dependencies = $co_dependencies = $addon_dependencies = 0;
|
| 485 |
|
| 486 |
-
//
|
| 487 |
$plugin = $this->get_registered_plugin( $main_class );
|
| 488 |
if ( empty( $plugin ) ) {
|
| 489 |
return false;
|
| 490 |
}
|
| 491 |
|
| 492 |
-
//
|
| 493 |
if ( ! empty( $plugin['dependencies']['parent-dependencies'] ) ) {
|
| 494 |
$parent_dependencies = $this->has_valid_dependencies( $plugin, $plugin['dependencies']['parent-dependencies'] );
|
| 495 |
}
|
| 496 |
-
//
|
| 497 |
if ( ! empty( $plugin['dependencies']['co-dependencies'] ) ) {
|
| 498 |
$co_dependencies = $this->has_valid_dependencies( $plugin, $plugin['dependencies']['co-dependencies'] );
|
| 499 |
}
|
| 500 |
|
| 501 |
-
//
|
| 502 |
$addon_dependencies = $this->check_addon_dependencies( $main_class );
|
| 503 |
|
| 504 |
-
//
|
| 505 |
if ( ! $parent_dependencies && ! $co_dependencies && ! $addon_dependencies ) {
|
| 506 |
$this->add_active_plugin( $main_class, $plugin['version'], $plugin['path'] );
|
| 507 |
|
|
@@ -509,6 +529,7 @@ if ( ! class_exists( 'Tribe__Dependency' ) ) {
|
|
| 509 |
}
|
| 510 |
|
| 511 |
return false;
|
|
|
|
| 512 |
}
|
| 513 |
|
| 514 |
/**
|
|
@@ -516,32 +537,29 @@ if ( ! class_exists( 'Tribe__Dependency' ) ) {
|
|
| 516 |
*
|
| 517 |
* @since 4.9
|
| 518 |
*
|
| 519 |
-
* @param string
|
| 520 |
*
|
| 521 |
-
* @return bool
|
| 522 |
*/
|
| 523 |
protected function check_addon_dependencies( $main_class ) {
|
|
|
|
|
|
|
|
|
|
| 524 |
foreach ( $this->registered_plugins as $registered ) {
|
| 525 |
if ( empty( $registered['dependencies']['addon-dependencies'][ $main_class ] ) ) {
|
| 526 |
continue;
|
| 527 |
}
|
| 528 |
|
| 529 |
-
$
|
| 530 |
-
$check = $this->has_valid_dependencies( $registered, $dependencies, true );
|
| 531 |
-
|
| 532 |
-
// A value of `true` or `0` indicates there are no failing checks. So here we check for ints gt 0.
|
| 533 |
-
if ( is_int( $check ) && $check > 0 ) {
|
| 534 |
-
return true;
|
| 535 |
-
}
|
| 536 |
}
|
| 537 |
|
| 538 |
-
return
|
| 539 |
}
|
| 540 |
|
| 541 |
/**
|
| 542 |
* Static Singleton Factory Method
|
| 543 |
*
|
| 544 |
-
* @deprecated 4.9.12 We shouldn't be
|
| 545 |
*
|
| 546 |
* @return self
|
| 547 |
*/
|
|
@@ -550,4 +568,4 @@ if ( ! class_exists( 'Tribe__Dependency' ) ) {
|
|
| 550 |
}
|
| 551 |
}
|
| 552 |
|
| 553 |
-
}
|
| 4 |
|
| 5 |
if ( ! class_exists( 'Tribe__Dependency' ) ) {
|
| 6 |
/**
|
| 7 |
+
* Tracks which tribe plugins are currently activated
|
| 8 |
*/
|
| 9 |
class Tribe__Dependency {
|
| 10 |
|
| 44 |
*
|
| 45 |
* @since 4.9
|
| 46 |
*
|
| 47 |
+
* @param string $main_class Main/base class for this plugin
|
| 48 |
+
* @param null|string $version Version number of plugin
|
| 49 |
+
* @param null|string $path Path to the main plugin/bootstrap file
|
| 50 |
+
* @param array $dependencies An array of dependencies for a plugin
|
| 51 |
*/
|
| 52 |
public function add_registered_plugin( $main_class, $version = null, $path = null, $dependencies = array() ) {
|
| 53 |
+
|
| 54 |
$plugin = array(
|
| 55 |
'class' => $main_class,
|
| 56 |
'version' => $version,
|
| 63 |
if ( $path ) {
|
| 64 |
$this->admin_messages[ $main_class ] = new Tribe__Admin__Notice__Plugin_Download( $path );
|
| 65 |
}
|
| 66 |
+
|
| 67 |
}
|
| 68 |
|
| 69 |
/**
|
| 85 |
* @param string $path Path to the main plugin/bootstrap file
|
| 86 |
*/
|
| 87 |
public function add_active_plugin( $main_class, $version = null, $path = null ) {
|
| 88 |
+
|
| 89 |
$plugin = array(
|
| 90 |
'class' => $main_class,
|
| 91 |
'version' => $version,
|
| 231 |
* @return bool
|
| 232 |
*/
|
| 233 |
public function is_plugin_version( $main_class, $version, $compare = '>=' ) {
|
| 234 |
+
|
| 235 |
//active plugin check to see if the correct version is active
|
| 236 |
if ( ! $this->is_plugin_active( $main_class ) ) {
|
| 237 |
return false;
|
| 254 |
* @return bool
|
| 255 |
*/
|
| 256 |
public function is_plugin_version_registered( $main_class, $version, $compare = '>=' ) {
|
| 257 |
+
|
| 258 |
//registered plugin check if addon as it tests if it might load
|
| 259 |
if ( ! $this->is_plugin_registered( $main_class ) ) {
|
| 260 |
return false;
|
| 273 |
* @return bool
|
| 274 |
*/
|
| 275 |
public function has_requisite_plugins( $plugins_required = array() ) {
|
| 276 |
+
|
| 277 |
foreach ( $plugins_required as $class => $version ) {
|
| 278 |
// Return false if the plugin is not set or is a lesser version
|
| 279 |
if ( ! $this->is_plugin_active( $class ) ) {
|
| 302 |
}
|
| 303 |
|
| 304 |
/**
|
| 305 |
+
* Gets all dependencies or single class requirements
|
| 306 |
+
* if parent, co, add does not exist use array as is
|
| 307 |
+
* if they do exist check each one in turn
|
| 308 |
*
|
| 309 |
* @since 4.9
|
| 310 |
*
|
| 311 |
+
* @param array $plugin An array of data for given registered plugin
|
| 312 |
+
* @param array $dependencies An array of dependencies for a plugin
|
| 313 |
+
* @param bool $addon Indicates if the plugin is an add-on for The Events Calendar or Event Tickets
|
| 314 |
*
|
| 315 |
+
* @return bool returns false if any dependency is invalid
|
| 316 |
*/
|
| 317 |
public function has_valid_dependencies( $plugin, $dependencies = array(), $addon = false ) {
|
| 318 |
+
|
| 319 |
if ( empty( $dependencies ) ) {
|
| 320 |
return true;
|
| 321 |
}
|
| 322 |
|
| 323 |
$failed_dependency = 0;
|
| 324 |
+
$tribe_plugins = new Tribe__Plugins();
|
|
|
|
| 325 |
|
| 326 |
foreach ( $dependencies as $class => $version ) {
|
| 327 |
|
| 328 |
// if no class for add-on
|
| 329 |
+
$checked_plugin = $this->get_registered_plugin( $class );
|
| 330 |
if ( $addon && empty( $checked_plugin ) ) {
|
| 331 |
continue;
|
| 332 |
}
|
| 336 |
continue;
|
| 337 |
}
|
| 338 |
|
| 339 |
+
if ( $class === $checked_plugin['class'] ) {
|
| 340 |
+
/*
|
| 341 |
+
* If the required plugin class is the same we're checking we clear the version to keep the message
|
| 342 |
+
* clear and redirect users to the latest version download link in place of providing a wrong
|
| 343 |
+
* version number.
|
| 344 |
+
*/
|
| 345 |
+
$version = '';
|
| 346 |
+
}
|
| 347 |
+
|
| 348 |
$dependent_plugin = $tribe_plugins->get_plugin_by_class( $class );
|
| 349 |
|
| 350 |
$pue = $this->get_pue_from_class( $dependent_plugin['class'] );
|
| 425 |
*
|
| 426 |
* @since 4.9
|
| 427 |
*
|
| 428 |
+
* @param $file_path
|
| 429 |
+
* @param $main_class
|
| 430 |
+
* @param $version
|
| 431 |
+
* @param array $classes_req
|
| 432 |
+
* @param array $dependencies
|
| 433 |
*/
|
| 434 |
public function register_plugin( $file_path, $main_class, $version, $classes_req = array(), $dependencies = array() ) {
|
| 435 |
/**
|
| 491 |
*
|
| 492 |
* @since 4.9
|
| 493 |
*
|
| 494 |
+
* @param string $file_path Full file path to the base plugin file
|
| 495 |
* @param string $main_class The Main/base class for this plugin
|
| 496 |
+
* @param string $version The version
|
| 497 |
+
* @param array $classes_req Any Main class files/tribe plugins required for this to run
|
| 498 |
+
* @param array $dependencies an array of dependencies to check
|
| 499 |
*
|
| 500 |
* @return bool Indicates if plugin should continue initialization
|
| 501 |
*/
|
| 503 |
|
| 504 |
$parent_dependencies = $co_dependencies = $addon_dependencies = 0;
|
| 505 |
|
| 506 |
+
//check if plugin is registered, if not return false
|
| 507 |
$plugin = $this->get_registered_plugin( $main_class );
|
| 508 |
if ( empty( $plugin ) ) {
|
| 509 |
return false;
|
| 510 |
}
|
| 511 |
|
| 512 |
+
// check parent dependencies in add-on
|
| 513 |
if ( ! empty( $plugin['dependencies']['parent-dependencies'] ) ) {
|
| 514 |
$parent_dependencies = $this->has_valid_dependencies( $plugin, $plugin['dependencies']['parent-dependencies'] );
|
| 515 |
}
|
| 516 |
+
//check co-dependencies in add-on
|
| 517 |
if ( ! empty( $plugin['dependencies']['co-dependencies'] ) ) {
|
| 518 |
$co_dependencies = $this->has_valid_dependencies( $plugin, $plugin['dependencies']['co-dependencies'] );
|
| 519 |
}
|
| 520 |
|
| 521 |
+
//check add-on dependencies from parent
|
| 522 |
$addon_dependencies = $this->check_addon_dependencies( $main_class );
|
| 523 |
|
| 524 |
+
//if good then we set as active plugin and continue to load
|
| 525 |
if ( ! $parent_dependencies && ! $co_dependencies && ! $addon_dependencies ) {
|
| 526 |
$this->add_active_plugin( $main_class, $plugin['version'], $plugin['path'] );
|
| 527 |
|
| 529 |
}
|
| 530 |
|
| 531 |
return false;
|
| 532 |
+
|
| 533 |
}
|
| 534 |
|
| 535 |
/**
|
| 537 |
*
|
| 538 |
* @since 4.9
|
| 539 |
*
|
| 540 |
+
* @param string $main_class a string of the main class for the plugin being checked
|
| 541 |
*
|
| 542 |
+
* @return bool returns false if any dependency is invalid
|
| 543 |
*/
|
| 544 |
protected function check_addon_dependencies( $main_class ) {
|
| 545 |
+
|
| 546 |
+
$addon_dependencies = 0;
|
| 547 |
+
|
| 548 |
foreach ( $this->registered_plugins as $registered ) {
|
| 549 |
if ( empty( $registered['dependencies']['addon-dependencies'][ $main_class ] ) ) {
|
| 550 |
continue;
|
| 551 |
}
|
| 552 |
|
| 553 |
+
$addon_dependencies = $this->has_valid_dependencies( $registered, $registered['dependencies']['addon-dependencies'], true );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 554 |
}
|
| 555 |
|
| 556 |
+
return $addon_dependencies;
|
| 557 |
}
|
| 558 |
|
| 559 |
/**
|
| 560 |
* Static Singleton Factory Method
|
| 561 |
*
|
| 562 |
+
* @deprecated 4.9.12 We shouldn't be handlign singletons internally.
|
| 563 |
*
|
| 564 |
* @return self
|
| 565 |
*/
|
| 568 |
}
|
| 569 |
}
|
| 570 |
|
| 571 |
+
}
|
common/src/Tribe/Dialog/View.php
DELETED
|
@@ -1,526 +0,0 @@
|
|
| 1 |
-
<?php
|
| 2 |
-
|
| 3 |
-
namespace Tribe\Dialog;
|
| 4 |
-
|
| 5 |
-
/**
|
| 6 |
-
* Class View
|
| 7 |
-
*
|
| 8 |
-
* @since 4.10.0
|
| 9 |
-
*/
|
| 10 |
-
class View extends \Tribe__Template {
|
| 11 |
-
/**
|
| 12 |
-
* Where in the themes we will look for templates.
|
| 13 |
-
*
|
| 14 |
-
* @since 4.10.0
|
| 15 |
-
*
|
| 16 |
-
* @var string
|
| 17 |
-
*/
|
| 18 |
-
public $template_namespace = 'dialogs';
|
| 19 |
-
|
| 20 |
-
/**
|
| 21 |
-
* View constructor
|
| 22 |
-
*
|
| 23 |
-
* @since 4.10.0
|
| 24 |
-
*/
|
| 25 |
-
public function __construct() {
|
| 26 |
-
$this->set_template_origin( \Tribe__Main::instance() );
|
| 27 |
-
$this->set_template_folder( 'src/views/dialog' );
|
| 28 |
-
|
| 29 |
-
// Configures this templating class to extract variables.
|
| 30 |
-
$this->set_template_context_extract( true );
|
| 31 |
-
|
| 32 |
-
// Uses the public folders.
|
| 33 |
-
$this->set_template_folder_lookup( true );
|
| 34 |
-
}
|
| 35 |
-
|
| 36 |
-
/**
|
| 37 |
-
* Public wrapper for build method.
|
| 38 |
-
* Contains all the logic/validation checks.
|
| 39 |
-
*
|
| 40 |
-
* @since 4.10.0
|
| 41 |
-
*
|
| 42 |
-
* @param string $content Content as an HTML string.
|
| 43 |
-
* @param array $args {
|
| 44 |
-
* List of arguments to override dialog template.
|
| 45 |
-
*
|
| 46 |
-
* @type string $button_id The ID for the trigger button (optional).
|
| 47 |
-
* @type array $button_classes Any desired classes for the trigger button (optional).
|
| 48 |
-
* @type boolean $button_disabled Should the button be disabled (optional).
|
| 49 |
-
* @type string $button_text The text for the dialog trigger button ("Open the dialog window").
|
| 50 |
-
* @type string $button_type The type for the trigger button (optional).
|
| 51 |
-
* @type string $button_value The value for the trigger button (optional).
|
| 52 |
-
* @type string $close_event The dialog close event hook name (`tribe_dialog_close_dialog`).
|
| 53 |
-
* @type string $content_classes The dialog content classes ("tribe-dialog__content").
|
| 54 |
-
* @type array $context Any additional context data you need to expose to this file (optional).
|
| 55 |
-
* @type string $id The unique ID for this dialog (`uniqid()`).
|
| 56 |
-
* @type string $show_event The dialog event show hook name (`tribe_dialog_show_dialog`).
|
| 57 |
-
* @type string $template The dialog template name (dialog).
|
| 58 |
-
* @type string $title The dialog title (optional).
|
| 59 |
-
* @type string $trigger_classes Classes for the dialog trigger ("tribe_dialog_trigger").
|
| 60 |
-
*
|
| 61 |
-
* Dialog script option overrides.
|
| 62 |
-
*
|
| 63 |
-
* @type string $append_target The dialog will be inserted after the button, you could supply a selector string here to override (optional).
|
| 64 |
-
* @type boolean $body_lock Whether to lock the body while dialog open (false).
|
| 65 |
-
* @type string $close_button_aria_label Aria label for the close button ("Close this dialog window").
|
| 66 |
-
* @type string $close_button_classes Classes for the close button ("tribe-dialog__close-button").
|
| 67 |
-
* @type string $content_wrapper_classes Dialog content wrapper classes. This wrapper includes the close button ("tribe-dialog__wrapper").
|
| 68 |
-
* @type string $effect CSS effect on open. none or fade (optional).
|
| 69 |
-
* @type string $effect_easing A css easing string to apply ("ease-in-out").
|
| 70 |
-
* @type int $effect_speed CSS effect speed in milliseconds (optional).
|
| 71 |
-
* @type string $overlay_classes The dialog overlay classes ("tribe-dialog__overlay").
|
| 72 |
-
* @type boolean $overlay_click_closes If clicking the overlay closes the dialog (false).
|
| 73 |
-
* @type string $wrapper_classes The wrapper class for the dialog ("tribe-dialog").
|
| 74 |
-
* }
|
| 75 |
-
* @param string $id The unique ID for this dialog. Gets prepended to the data attributes. Generated if not passed (`uniqid()`).
|
| 76 |
-
* @param boolean $echo Whether to echo the script or to return it (default: true).
|
| 77 |
-
*
|
| 78 |
-
* @return string An HTML string of the dialog.
|
| 79 |
-
*/
|
| 80 |
-
public function render_dialog( $content, $args = [], $id = null, $echo = true ) {
|
| 81 |
-
// Check for content to be passed.
|
| 82 |
-
if ( empty( $content ) ) {
|
| 83 |
-
return '';
|
| 84 |
-
}
|
| 85 |
-
|
| 86 |
-
// Generate an ID if we weren't passed one.
|
| 87 |
-
if ( is_null( $id ) ) {
|
| 88 |
-
$id = \uniqid();
|
| 89 |
-
}
|
| 90 |
-
|
| 91 |
-
/** @var \Tribe__Assets $assets */
|
| 92 |
-
$assets = tribe( 'assets' );
|
| 93 |
-
$assets->enqueue_group( 'tribe-dialog' );
|
| 94 |
-
|
| 95 |
-
$html = $this->build_dialog( $content, $id, $args );
|
| 96 |
-
|
| 97 |
-
if ( ! $echo ) {
|
| 98 |
-
return $html;
|
| 99 |
-
}
|
| 100 |
-
|
| 101 |
-
echo $html;
|
| 102 |
-
}
|
| 103 |
-
|
| 104 |
-
/**
|
| 105 |
-
* Syntactic sugar for `render_dialog()` to make creating modals easier.
|
| 106 |
-
* Adds sensible defaults for modals.
|
| 107 |
-
*
|
| 108 |
-
* @since 4.10.0
|
| 109 |
-
*
|
| 110 |
-
* @param string $content Content as an HTML string.
|
| 111 |
-
* @param array $args {
|
| 112 |
-
* List of arguments to override dialog template.
|
| 113 |
-
*
|
| 114 |
-
* @type string $button_id The ID for the trigger button (optional).
|
| 115 |
-
* @type array $button_classes Any desired classes for the trigger button (optional).
|
| 116 |
-
* @type boolean $button_disabled Should the button be disabled (optional).
|
| 117 |
-
* @type string $button_text The text for the dialog trigger button ("Open the modal window").
|
| 118 |
-
* @type string $button_type The type for the trigger button (optional).
|
| 119 |
-
* @type string $button_value The value for the trigger button (optional).
|
| 120 |
-
* @type string $close_event The dialog close event hook name (`tribe_dialog_close_modal`).
|
| 121 |
-
* @type string $content_classes The dialog content classes ("tribe-dialog__content tribe-modal__content").
|
| 122 |
-
* @type string $title_classes The dialog title classes ("tribe-dialog__title tribe-modal__title").
|
| 123 |
-
* @type array $context Any additional context data you need to expose to this file (optional).
|
| 124 |
-
* @type string $id The unique ID for this dialog (`uniqid()`).
|
| 125 |
-
* @type string $show_event The dialog event hook name (`tribe_dialog_show_modal`).
|
| 126 |
-
* @type string $template The dialog template name (modal).
|
| 127 |
-
* @type string $title The dialog title (optional).
|
| 128 |
-
* @type string $trigger_classes Classes for the dialog trigger ("tribe_dialog_trigger").
|
| 129 |
-
*
|
| 130 |
-
* Dialog script option overrides.
|
| 131 |
-
*
|
| 132 |
-
* @type string $append_target The dialog will be inserted after the button, you could supply a selector string here to override ("body").
|
| 133 |
-
* @type boolean $body_lock Whether to lock the body while dialog open (true).
|
| 134 |
-
* @type string $close_button_aria_label Aria label for the close button ("Close this modal window").
|
| 135 |
-
* @type string $close_button_classes Classes for the close button ("tribe-dialog__close-button tribe-modal__close-button").
|
| 136 |
-
* @type string $content_wrapper_classes Dialog content wrapper classes. This wrapper includes the close button ("tribe-dialog__wrapper tribe-modal__wrapper").
|
| 137 |
-
* @type string $effect CSS effect on open. none or fade ("fade").
|
| 138 |
-
* @type string $effect_easing A css easing string to apply ("ease-in-out").
|
| 139 |
-
* @type int $effect_speed CSS effect speed in milliseconds (300).
|
| 140 |
-
* @type string $overlay_classes The dialog overlay classes ("tribe-dialog__overlay tribe-modal__overlay").
|
| 141 |
-
* @type boolean $overlay_click_closes If clicking the overlay closes the dialog (true).
|
| 142 |
-
* @type string $wrapper_classes The wrapper class for the dialog ("tribe-dialog").
|
| 143 |
-
* }
|
| 144 |
-
* @param string $id The unique ID for this dialog. Gets prepended to the data attributes. Generated if not passed (`uniqid()`).
|
| 145 |
-
* @param boolean $echo Whether to echo the script or to return it (default: true).
|
| 146 |
-
*
|
| 147 |
-
* @return string An HTML string of the dialog.
|
| 148 |
-
*/
|
| 149 |
-
public function render_modal( $content, $args = [], $id = null, $echo = true ) {
|
| 150 |
-
$default_args = [
|
| 151 |
-
'append_target' => '',
|
| 152 |
-
'body_lock' => true,
|
| 153 |
-
'button_text' => __( 'Open the modal window', 'tribe-common' ),
|
| 154 |
-
'close_button_aria_label' => __( 'Close this modal window', 'tribe-common' ),
|
| 155 |
-
'close_button_classes' => 'tribe-dialog__close-button tribe-modal__close-button',
|
| 156 |
-
'close_event' => 'tribe_dialog_close_modal',
|
| 157 |
-
'content_classes' => 'tribe-dialog__content tribe-modal__content',
|
| 158 |
-
'content_wrapper_classes' => 'tribe-dialog__wrapper tribe-modal__wrapper',
|
| 159 |
-
'effect' => 'fade',
|
| 160 |
-
'effect_speed' => 300,
|
| 161 |
-
'overlay_classes' => 'tribe-dialog__overlay tribe-modal__overlay',
|
| 162 |
-
'overlay_click_closes' => true,
|
| 163 |
-
'show_event' => 'tribe_dialog_show_modal',
|
| 164 |
-
'template' => 'modal',
|
| 165 |
-
'title_classes' => [ 'tribe-dialog__title', 'tribe-modal__title' ],
|
| 166 |
-
];
|
| 167 |
-
|
| 168 |
-
$args = wp_parse_args( $args, $default_args );
|
| 169 |
-
|
| 170 |
-
$this->render_dialog( $content, $args, $id, $echo );
|
| 171 |
-
}
|
| 172 |
-
|
| 173 |
-
/**
|
| 174 |
-
* Syntactic sugar for `render_dialog()` to make creating custom confirmation dialogs easier.
|
| 175 |
-
* Adds sensible defaults for confirmation dialogs.
|
| 176 |
-
*
|
| 177 |
-
* @since 4.10.0
|
| 178 |
-
*
|
| 179 |
-
* @param string $content Content as an HTML string.
|
| 180 |
-
* @param array $args {
|
| 181 |
-
* List of arguments to override dialog template.
|
| 182 |
-
*
|
| 183 |
-
* @type string $button_id The ID for the trigger button (optional).
|
| 184 |
-
* @type array $button_classes Any desired classes for the trigger button (optional).
|
| 185 |
-
* @type boolean $button_disabled Should the button be disabled (optional).
|
| 186 |
-
* @type string $button_text The text for the dialog trigger button ("Open the dialog window").
|
| 187 |
-
* @type string $button_type The type for the trigger button (optional).
|
| 188 |
-
* @type string $button_value The value for the trigger button (optional).
|
| 189 |
-
* @type string $cancel_button_text Text for the "Cancel" button ("Cancel").
|
| 190 |
-
* @type string $content_classes The dialog content classes ("tribe-dialog__content tribe-confirm__content").
|
| 191 |
-
* @type string $continue_button_text Text for the "Continue" button ("Confirm").
|
| 192 |
-
* @type array $context Any additional context data you need to expose to this file (optional).
|
| 193 |
-
* @type string $id The unique ID for this dialog (`uniqid()`).
|
| 194 |
-
* @type string $template The dialog template name (confirm).
|
| 195 |
-
* @type string $title The dialog title (optional).
|
| 196 |
-
* @type string $trigger_classes Classes for the dialog trigger ("tribe_dialog_trigger").
|
| 197 |
-
*
|
| 198 |
-
* Dialog script option overrides.
|
| 199 |
-
*
|
| 200 |
-
* @type string $append_target The dialog will be inserted after the button, you could supply a selector string here to override (optional).
|
| 201 |
-
* @type boolean $body_lock Whether to lock the body while dialog open (true).
|
| 202 |
-
* @type string $close_button_aria_label Aria label for the close button (optional).
|
| 203 |
-
* @type string $close_button_classes Classes for the close button ("tribe-dialog__close-button--hidden").
|
| 204 |
-
* @type string $close_event The dialog close event hook name (`tribe_dialog_close_confirm`).
|
| 205 |
-
* @type string $content_wrapper_classes Dialog content wrapper classes. This wrapper includes the close button ("tribe-dialog__wrapper tribe-confirm__wrapper").
|
| 206 |
-
* @type string $effect CSS effect on open. none or fade (optional).
|
| 207 |
-
* @type string $effect_easing A css easing string to apply ("ease-in-out").
|
| 208 |
-
* @type int $effect_speed CSS effect speed in milliseconds (optional).
|
| 209 |
-
* @type string $overlay_classes The dialog overlay classes ("tribe-dialog__overlay tribe-confirm__overlay").
|
| 210 |
-
* @type boolean $overlay_click_closes If clicking the overlay closes the dialog (false).
|
| 211 |
-
* @type string $show_event The dialog event hook name (`tribe_dialog_show_confirm`).
|
| 212 |
-
* @type string $wrapper_classes The wrapper class for the dialog ("tribe-dialog").
|
| 213 |
-
* }
|
| 214 |
-
* @param string $id The unique ID for this dialog. Gets prepended to the data attributes. Generated if not passed (`uniqid()`).
|
| 215 |
-
* @param boolean $echo Whether to echo the script or to return it (default: true).
|
| 216 |
-
*
|
| 217 |
-
* @return string An HTML string of the dialog.
|
| 218 |
-
*/
|
| 219 |
-
public function render_confirm( $content, $args = [], $id = null, $echo = true ) {
|
| 220 |
-
$default_args = [
|
| 221 |
-
'body_lock' => true,
|
| 222 |
-
'cancel_button_text' => __( 'Cancel', 'tribe-common' ),
|
| 223 |
-
'continue_button_text' => __( 'Confirm', 'tribe-common' ),
|
| 224 |
-
'close_button_aria_label' => '',
|
| 225 |
-
'close_button_classes' => 'tribe-dialog__close-button--hidden',
|
| 226 |
-
'close_event' => 'tribe_dialog_close_confirm',
|
| 227 |
-
'content_classes' => 'tribe-dialog__content tribe-confirm__content',
|
| 228 |
-
'content_wrapper_classes' => 'tribe-dialog__wrapper tribe-confirm__wrapper',
|
| 229 |
-
'overlay_classes' => 'tribe-dialog__overlay tribe-confirm__overlay',
|
| 230 |
-
'show_event' => 'tribe_dialog_show_confirm',
|
| 231 |
-
'template' => 'confirm',
|
| 232 |
-
'title_classes' => [ 'tribe-dialog__title', 'tribe-confirm__title' ],
|
| 233 |
-
];
|
| 234 |
-
|
| 235 |
-
$args = wp_parse_args( $args, $default_args );
|
| 236 |
-
|
| 237 |
-
$this->render_dialog( $content, $args, $id, $echo );
|
| 238 |
-
}
|
| 239 |
-
|
| 240 |
-
/**
|
| 241 |
-
* Syntactic sugar for `render_dialog()` to make creating custom alerts easier.
|
| 242 |
-
* Adds sensible defaults for alerts.
|
| 243 |
-
*
|
| 244 |
-
* @since 4.10.0
|
| 245 |
-
*
|
| 246 |
-
* @param string $content Content as an HTML string.
|
| 247 |
-
* @param array $args {
|
| 248 |
-
* List of arguments to override dialog template.
|
| 249 |
-
*
|
| 250 |
-
* @type string $alert_button_text Text for the "OK" button ("OK").
|
| 251 |
-
* @type string $button_id The ID for the trigger button (optional).
|
| 252 |
-
* @type array $button_classes Any desired classes for the trigger button (optional).
|
| 253 |
-
* @type boolean $button_disabled Should the button be disabled (optional).
|
| 254 |
-
* @type string $button_text The text for the dialog trigger button ("Open the dialog window").
|
| 255 |
-
* @type string $button_type The type for the trigger button (optional).
|
| 256 |
-
* @type string $button_value The value for the trigger button (optional).
|
| 257 |
-
* @type string $content_classes The dialog content classes ("tribe-dialog__content tribe-alert__content").
|
| 258 |
-
* @type string $title_classes The dialog title classes ("tribe-dialog__title tribe-alert__title").
|
| 259 |
-
* @type array $context Any additional context data you need to expose to this file (optional).
|
| 260 |
-
* @type string $id The unique ID for this dialog (`uniqid()`).
|
| 261 |
-
* @type string $template The dialog template name (alert).
|
| 262 |
-
* @type string $title The dialog title (optional).
|
| 263 |
-
* @type string $trigger_classes Classes for the dialog trigger ("tribe_dialog_trigger").
|
| 264 |
-
*
|
| 265 |
-
* Dialog script option overrides.
|
| 266 |
-
*
|
| 267 |
-
* @type string $append_target The dialog will be inserted after the button, you could supply a selector string here to override (optional).
|
| 268 |
-
* @type boolean $body_lock Whether to lock the body while dialog open (true).
|
| 269 |
-
* @type string $close_button_aria_label Aria label for the close button (optional).
|
| 270 |
-
* @type string $close_button_classes Classes for the close button ("tribe-dialog__close-button--hidden").
|
| 271 |
-
* @type string $close_event The dialog close event hook name (`tribe_dialog_close_alert`).
|
| 272 |
-
* @type string $content_wrapper_classes Dialog content wrapper classes. This wrapper includes the close button ("tribe-dialog__wrapper tribe-alert__wrapper").
|
| 273 |
-
* @type string $effect CSS effect on open. none or fade (optional).
|
| 274 |
-
* @type string $effect_easing A css easing string to apply ("ease-in-out").
|
| 275 |
-
* @type int $effect_speed CSS effect speed in milliseconds (optional).
|
| 276 |
-
* @type string $overlay_classes The dialog overlay classes ("tribe-dialog__overlay tribe-alert__overlay").
|
| 277 |
-
* @type boolean $overlay_click_closes If clicking the overlay closes the dialog (false).
|
| 278 |
-
* @type string $show_event The dialog event hook name (`tribe_dialog_show_alert`).
|
| 279 |
-
* @type string $wrapper_classes The wrapper class for the dialog ("tribe-dialog").
|
| 280 |
-
* }
|
| 281 |
-
* @param string $id The unique ID for this dialog. Gets prepended to the data attributes. Generated if not passed (`uniqid()`).
|
| 282 |
-
* @param boolean $echo Whether to echo the script or to return it (default: true).
|
| 283 |
-
*
|
| 284 |
-
* @return string An HTML string of the dialog.
|
| 285 |
-
*/
|
| 286 |
-
public function render_alert( $content, $args = [], $id = null, $echo = true ) {
|
| 287 |
-
$default_args = [
|
| 288 |
-
'alert_button_text' => __( 'OK', 'tribe-common' ),
|
| 289 |
-
'body_lock' => true,
|
| 290 |
-
'close_button_aria_label' => '',
|
| 291 |
-
'close_button_classes' => 'tribe-dialog__close-button--hidden',
|
| 292 |
-
'close_event' => 'tribe_dialog_close_alert',
|
| 293 |
-
'content_classes' => 'tribe-dialog__content tribe-alert__content',
|
| 294 |
-
'content_wrapper_classes' => 'tribe-dialog__wrapper tribe-alert__wrapper',
|
| 295 |
-
'overlay_classes' => 'tribe-dialog__overlay tribe-alert__overlay',
|
| 296 |
-
'show_event' => 'tribe_dialog_show_alert',
|
| 297 |
-
'template' => 'alert',
|
| 298 |
-
'title_classes' => [ 'tribe-dialog__title', 'tribe-alert__title' ],
|
| 299 |
-
];
|
| 300 |
-
|
| 301 |
-
$args = wp_parse_args( $args, $default_args );
|
| 302 |
-
|
| 303 |
-
$this->render_dialog( $content, $args, $id, $echo );
|
| 304 |
-
}
|
| 305 |
-
|
| 306 |
-
/**
|
| 307 |
-
* Factory method for dialog HTML
|
| 308 |
-
*
|
| 309 |
-
* @since 4.10.0
|
| 310 |
-
*
|
| 311 |
-
* @param string $content HTML dialog content.
|
| 312 |
-
* @param string $id The unique ID for this dialog (`uniqid()`) Gets prepended to the data attributes.
|
| 313 |
-
* @param array $args {
|
| 314 |
-
* List of arguments to override dialog template.
|
| 315 |
-
*
|
| 316 |
-
* @type string $button_id The ID for the trigger button (optional).
|
| 317 |
-
* @type array $button_classes Any desired classes for the trigger button (optional).
|
| 318 |
-
* @type boolean $button_disabled Should the button be disabled (optional).
|
| 319 |
-
* @type string $button_text The text for the dialog trigger button ("Open the dialog window").
|
| 320 |
-
* @type string $button_type The type for the trigger button (optional).
|
| 321 |
-
* @type string $button_value The value for the trigger button (optional).
|
| 322 |
-
* @type string $close_event The dialog event hook name (`tribe_dialog_close_dialog`).
|
| 323 |
-
* @type string $content_classes The dialog content classes ("tribe-dialog__content").
|
| 324 |
-
* @type string $title_classes The dialog title classes ("tribe-dialog__title").
|
| 325 |
-
* @type array $context Any additional context data you need to expose to this file (optional).
|
| 326 |
-
* @type string $id The unique ID for this dialog (`uniqid()`).
|
| 327 |
-
* @type string $show_event The dialog event hook name (`tribe_dialog_show_dialog`).
|
| 328 |
-
* @type string $template The dialog template name (dialog).
|
| 329 |
-
* @type string $title The dialog title (optional).
|
| 330 |
-
* @type string $trigger_classes Classes for the dialog trigger ("tribe_dialog_trigger").
|
| 331 |
-
*
|
| 332 |
-
* Dialog script option overrides.
|
| 333 |
-
*
|
| 334 |
-
* @type string $append_target The dialog will be inserted after the button, you could supply a selector string here to override (optional).
|
| 335 |
-
* @type boolean $body_lock Whether to lock the body while dialog open (false).
|
| 336 |
-
* @type string $close_button_aria_label Aria label for the close button ("Close this dialog window").
|
| 337 |
-
* @type string $close_button_classes Classes for the close button ("tribe-dialog__close-button").
|
| 338 |
-
* @type string $content_wrapper_classes Dialog content wrapper classes. This wrapper includes the close button ("tribe-dialog__wrapper").
|
| 339 |
-
* @type string $effect CSS effect on open. none or fade (optional).
|
| 340 |
-
* @type string $effect_easing A css easing string to apply ("ease-in-out").
|
| 341 |
-
* @type int $effect_speed CSS effect speed in milliseconds (optional).
|
| 342 |
-
* @type string $overlay_classes The dialog overlay classes ("tribe-dialog__overlay").
|
| 343 |
-
* @type boolean $overlay_click_closes If clicking the overlay closes the dialog (false).
|
| 344 |
-
* @type string $wrapper_classes The wrapper class for the dialog ("tribe-dialog").
|
| 345 |
-
* }
|
| 346 |
-
*
|
| 347 |
-
* @return string An HTML string of the dialog.
|
| 348 |
-
*/
|
| 349 |
-
private function build_dialog( $content, $id, $args ) {
|
| 350 |
-
$default_args = [
|
| 351 |
-
'button_classes' => '',
|
| 352 |
-
'button_disabled' => false,
|
| 353 |
-
'button_id' => '',
|
| 354 |
-
'button_name' => '',
|
| 355 |
-
'button_text' => __( 'Open the dialog window', 'tribe-common' ),
|
| 356 |
-
'button_type' => '',
|
| 357 |
-
'button_value' => '',
|
| 358 |
-
'close_event' => 'tribe_dialog_close_dialog',
|
| 359 |
-
'content_classes' => 'tribe-dialog__content',
|
| 360 |
-
'context' => '',
|
| 361 |
-
'show_event' => 'tribe_dialog_show_dialog',
|
| 362 |
-
'template' => 'dialog',
|
| 363 |
-
'title_classes' => 'tribe-dialog__title',
|
| 364 |
-
'title' => '',
|
| 365 |
-
'trigger_classes' => 'tribe_dialog_trigger',
|
| 366 |
-
// Dialog script options.
|
| 367 |
-
'append_target' => '', // The dialog will be inserted after the button, you could supply a selector string here to override.
|
| 368 |
-
'body_lock' => false, // Lock the body while dialog open?
|
| 369 |
-
'close_button_aria_label' => __( 'Close this dialog window', 'tribe-common' ), // Aria label for close button.
|
| 370 |
-
'close_button_classes' => 'tribe-dialog__close-button', // Classes for close button.
|
| 371 |
-
'content_wrapper_classes' => 'tribe-dialog__wrapper', // Dialog content classes.
|
| 372 |
-
'effect' => 'none', // None or fade (for now).
|
| 373 |
-
'effect_speed' => 0, // Effect speed in milliseconds.
|
| 374 |
-
'effect_easing' => 'ease-in-out', // A css easing string.
|
| 375 |
-
'overlay_classes' => 'tribe-dialog__overlay', // Overlay classes.
|
| 376 |
-
'overlay_click_closes' => false, // Clicking overlay closes dialog.
|
| 377 |
-
'wrapper_classes' => 'tribe-dialog', // The wrapper class for the dialog.
|
| 378 |
-
];
|
| 379 |
-
|
| 380 |
-
$args = wp_parse_args( $args, $default_args );
|
| 381 |
-
|
| 382 |
-
$args[ 'content' ] = $content;
|
| 383 |
-
$args[ 'id' ] = $id;
|
| 384 |
-
|
| 385 |
-
/**
|
| 386 |
-
* Allow us to filter the dialog arguments.
|
| 387 |
-
*
|
| 388 |
-
* @since 4.10.0
|
| 389 |
-
*
|
| 390 |
-
* @param array $args The dialog arguments.
|
| 391 |
-
* @param string $content HTML content string.
|
| 392 |
-
*/
|
| 393 |
-
$args = apply_filters( 'tribe_dialog_args', $args, $content );
|
| 394 |
-
|
| 395 |
-
$template = $args[ 'template' ];
|
| 396 |
-
/**
|
| 397 |
-
* Allow us to filter the dialog template name.
|
| 398 |
-
*
|
| 399 |
-
* @since 4.10.0
|
| 400 |
-
*
|
| 401 |
-
* @param string $template The dialog template name.
|
| 402 |
-
* @param array $args The dialog arguments.
|
| 403 |
-
*/
|
| 404 |
-
$template_name = apply_filters( 'tribe_dialog_template', $template, $args );
|
| 405 |
-
|
| 406 |
-
ob_start();
|
| 407 |
-
|
| 408 |
-
$this->template( $template_name, $args, true );
|
| 409 |
-
|
| 410 |
-
$this->get_dialog_script( $args );
|
| 411 |
-
|
| 412 |
-
$html = ob_get_clean();
|
| 413 |
-
|
| 414 |
-
/**
|
| 415 |
-
* Allow us to filter the dialog output (HTML string).
|
| 416 |
-
*
|
| 417 |
-
* @since 4.10.0
|
| 418 |
-
*
|
| 419 |
-
* @param string $html The dialog HTML string.
|
| 420 |
-
* @param array $args The dialog arguments.
|
| 421 |
-
*/
|
| 422 |
-
return apply_filters( 'tribe_dialog_html', $html, $args );
|
| 423 |
-
}
|
| 424 |
-
|
| 425 |
-
/**
|
| 426 |
-
* Get dialog <script> to be rendered.
|
| 427 |
-
*
|
| 428 |
-
* @since 4.10.0
|
| 429 |
-
*
|
| 430 |
-
* @param array $args List of arguments for the dialog script. See \Tribe\Dialog\View->build_dialog().
|
| 431 |
-
* @param boolean $echo Whether to echo the script or to return it (default: true).
|
| 432 |
-
*
|
| 433 |
-
* @return string|void The dialog <script> HTML or nothing if $echo is true.
|
| 434 |
-
*/
|
| 435 |
-
public function get_dialog_script( $args, $echo = true ) {
|
| 436 |
-
$args = [
|
| 437 |
-
'appendTarget' => $args[ 'append_target' ],
|
| 438 |
-
'bodyLock' => $args[ 'body_lock' ],
|
| 439 |
-
'closeButtonAriaLabel' => $args[ 'close_button_aria_label' ],
|
| 440 |
-
'closeButtonClasses' => $args[ 'close_button_classes' ],
|
| 441 |
-
'closeEvent' => $args[ 'close_event' ],
|
| 442 |
-
'contentClasses' => $args[ 'content_wrapper_classes' ],
|
| 443 |
-
'effect' => $args[ 'effect' ],
|
| 444 |
-
'effectEasing' => $args[ 'effect_easing' ],
|
| 445 |
-
'effectSpeed' => $args[ 'effect_speed' ],
|
| 446 |
-
'id' => $args[ 'id' ],
|
| 447 |
-
'overlayClasses' => $args[ 'overlay_classes' ],
|
| 448 |
-
'overlayClickCloses' => $args[ 'overlay_click_closes' ],
|
| 449 |
-
'showEvent' => $args[ 'show_event' ],
|
| 450 |
-
'closeEvent' => $args[ 'close_event' ],
|
| 451 |
-
'template' => $args[ 'template' ],
|
| 452 |
-
'wrapperClasses' => esc_attr( $args[ 'wrapper_classes' ] ),
|
| 453 |
-
];
|
| 454 |
-
|
| 455 |
-
/**
|
| 456 |
-
* Allows for modifying the arguments before they are passed to the dialog script.
|
| 457 |
-
*
|
| 458 |
-
* @since 4.10.0
|
| 459 |
-
*
|
| 460 |
-
* @param array $args List of arguments to override dialog script. See \Tribe\Dialog\View->build_dialog().
|
| 461 |
-
*/
|
| 462 |
-
$args = apply_filters( 'tribe_dialog_script_args', $args );
|
| 463 |
-
|
| 464 |
-
// Escape all argument values.
|
| 465 |
-
$args = array_map( 'esc_html', $args );
|
| 466 |
-
|
| 467 |
-
$args[ 'trigger' ] = "[data-js='" . esc_attr( 'trigger-dialog-' . $args[ 'id' ] ) . "' ]";
|
| 468 |
-
|
| 469 |
-
ob_start();
|
| 470 |
-
?>
|
| 471 |
-
<script>
|
| 472 |
-
var tribe = tribe || {};
|
| 473 |
-
tribe.dialogs = tribe.dialogs || [];
|
| 474 |
-
tribe.dialogs.dialogs = tribe.dialogs.dialogs || [];
|
| 475 |
-
|
| 476 |
-
tribe.dialogs.dialogs.push( <?php echo json_encode( $args ); ?> );
|
| 477 |
-
|
| 478 |
-
<?php
|
| 479 |
-
/**
|
| 480 |
-
* Allows for injecting additional scripts (button actions, etc).
|
| 481 |
-
*
|
| 482 |
-
* @since 4.10.0
|
| 483 |
-
*
|
| 484 |
-
* @param array $args List of arguments to override dialog script. See \Tribe\Dialog\View->build_dialog().
|
| 485 |
-
*/
|
| 486 |
-
do_action( 'tribe_dialog_additional_scripts', $args );
|
| 487 |
-
|
| 488 |
-
/**
|
| 489 |
-
* Allows for injecting additional scripts (button actions, etc) by template.
|
| 490 |
-
*
|
| 491 |
-
* @since 4.10.0
|
| 492 |
-
*
|
| 493 |
-
* @param array $args List of arguments to override dialog script. See \Tribe\Dialog\View->build_dialog().
|
| 494 |
-
*/
|
| 495 |
-
do_action( 'tribe_dialog_additional_scripts_' . $args[ 'template' ], $args );
|
| 496 |
-
|
| 497 |
-
/**
|
| 498 |
-
* Allows for injecting additional scripts (button actions, etc) by dialog ID.
|
| 499 |
-
*
|
| 500 |
-
* @since 4.10.0
|
| 501 |
-
*
|
| 502 |
-
* @param array $args List of arguments to override dialog script. See \Tribe\Dialog\View->build_dialog().
|
| 503 |
-
*/
|
| 504 |
-
do_action( 'tribe_dialog_additional_scripts_' . $args[ 'id' ], $args );
|
| 505 |
-
?>
|
| 506 |
-
</script>
|
| 507 |
-
<?php
|
| 508 |
-
$html = ob_get_clean();
|
| 509 |
-
|
| 510 |
-
/**
|
| 511 |
-
* Allows for modifying the HTML before it is echoed or returned.
|
| 512 |
-
*
|
| 513 |
-
* @since 4.10.0
|
| 514 |
-
*
|
| 515 |
-
* @param array $args List of arguments to override dialog script. See \Tribe\Dialog\View->build_dialog().
|
| 516 |
-
*/
|
| 517 |
-
$html = apply_filters( 'tribe_dialog_script_html', $html );
|
| 518 |
-
|
| 519 |
-
if ( $echo ) {
|
| 520 |
-
echo $html;
|
| 521 |
-
return;
|
| 522 |
-
}
|
| 523 |
-
|
| 524 |
-
return $html;
|
| 525 |
-
}
|
| 526 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
common/src/Tribe/Editor.php
CHANGED
|
@@ -27,22 +27,10 @@ class Tribe__Editor {
|
|
| 27 |
* @return bool
|
| 28 |
*/
|
| 29 |
public function should_load_blocks() {
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
$should_load_blocks = $gutenberg && $blocks && ! $classic;
|
| 35 |
-
|
| 36 |
-
/**
|
| 37 |
-
* Filters whether the Blocks Editor should be activated or not.
|
| 38 |
-
*
|
| 39 |
-
* @since 4.12.0
|
| 40 |
-
*
|
| 41 |
-
* @param bool $should_load_blocks Whether the blocks editor should be activated or not.
|
| 42 |
-
*/
|
| 43 |
-
$should_load_blocks = (bool) apply_filters( 'tribe_editor_should_load_blocks', $should_load_blocks );
|
| 44 |
-
|
| 45 |
-
return $should_load_blocks;
|
| 46 |
}
|
| 47 |
|
| 48 |
/**
|
|
@@ -222,35 +210,4 @@ class Tribe__Editor {
|
|
| 222 |
|
| 223 |
return $is_classic_editor_request || $disabled_by_plugin || $disabled_by_filter;
|
| 224 |
}
|
| 225 |
-
|
| 226 |
-
/**
|
| 227 |
-
* Whether the events are being served using Blocks or the Classical Editor.
|
| 228 |
-
*
|
| 229 |
-
* @since 4.12.0
|
| 230 |
-
*
|
| 231 |
-
* @return bool True if using Blocks. False if using the Classical Editor.
|
| 232 |
-
*/
|
| 233 |
-
public function is_events_using_blocks() {
|
| 234 |
-
/**
|
| 235 |
-
* Whether the event is being served through blocks
|
| 236 |
-
* or the classical editor.
|
| 237 |
-
*
|
| 238 |
-
* @since 4.12.0
|
| 239 |
-
*
|
| 240 |
-
* @param bool $is_using_blocks True if using blocks. False if using the classical editor.
|
| 241 |
-
*/
|
| 242 |
-
$is_using_blocks = apply_filters( 'tribe_is_using_blocks', null );
|
| 243 |
-
|
| 244 |
-
// Early bail: The filter was overridden to return either true or false.
|
| 245 |
-
if ( null !== $is_using_blocks ) {
|
| 246 |
-
return $is_using_blocks;
|
| 247 |
-
}
|
| 248 |
-
|
| 249 |
-
// Early bail: The site itself is not using blocks.
|
| 250 |
-
if ( ! $this->should_load_blocks() ) {
|
| 251 |
-
return false;
|
| 252 |
-
}
|
| 253 |
-
|
| 254 |
-
return tribe_is_truthy( tribe_get_option( 'toggle_blocks_editor' ) );
|
| 255 |
-
}
|
| 256 |
}
|
| 27 |
* @return bool
|
| 28 |
*/
|
| 29 |
public function should_load_blocks() {
|
| 30 |
+
return (
|
| 31 |
+
$this->is_gutenberg_active() || $this->is_wp_version()
|
| 32 |
+
)
|
| 33 |
+
&& $this->is_blocks_editor_active();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 34 |
}
|
| 35 |
|
| 36 |
/**
|
| 210 |
|
| 211 |
return $is_classic_editor_request || $disabled_by_plugin || $disabled_by_filter;
|
| 212 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 213 |
}
|
common/src/Tribe/Editor/Blocks/Abstract.php
CHANGED
|
@@ -38,7 +38,7 @@ implements Tribe__Editor__Blocks__Interface {
|
|
| 38 |
return $this->namespace;
|
| 39 |
}
|
| 40 |
|
| 41 |
-
|
| 42 |
* Return the block attributes
|
| 43 |
*
|
| 44 |
* @since 4.8
|
|
@@ -69,7 +69,7 @@ implements Tribe__Editor__Blocks__Interface {
|
|
| 69 |
return $attributes;
|
| 70 |
}
|
| 71 |
|
| 72 |
-
|
| 73 |
* Return the block default attributes
|
| 74 |
*
|
| 75 |
* @since 4.8
|
|
@@ -203,39 +203,5 @@ implements Tribe__Editor__Blocks__Interface {
|
|
| 203 |
*/
|
| 204 |
public function hook() {
|
| 205 |
}
|
| 206 |
-
|
| 207 |
-
/**
|
| 208 |
-
* Returns the block data for the block editor.
|
| 209 |
-
*
|
| 210 |
-
* @since 4.12.0
|
| 211 |
-
*
|
| 212 |
-
* @return array<string,mixed> The block editor data.
|
| 213 |
-
*/
|
| 214 |
-
public function block_data() {
|
| 215 |
-
$block_data = [
|
| 216 |
-
'id' => $this->slug(),
|
| 217 |
-
];
|
| 218 |
-
|
| 219 |
-
/**
|
| 220 |
-
* Filters the block data.
|
| 221 |
-
*
|
| 222 |
-
* @since 4.12.0
|
| 223 |
-
*
|
| 224 |
-
* @param array $block_data The block data.
|
| 225 |
-
* @param object $this The current object.
|
| 226 |
-
*/
|
| 227 |
-
$block_data = apply_filters( 'tribe_block_block_data', $block_data, $this );
|
| 228 |
-
|
| 229 |
-
/**
|
| 230 |
-
* Filters the block data for the block.
|
| 231 |
-
*
|
| 232 |
-
* @since 4.12.0
|
| 233 |
-
*
|
| 234 |
-
* @param array $block_data The block data.
|
| 235 |
-
* @param object $this The current object.
|
| 236 |
-
*/
|
| 237 |
-
$block_data = apply_filters( 'tribe_block_block_data_' . $this->slug(), $block_data, $this );
|
| 238 |
-
|
| 239 |
-
return $block_data;
|
| 240 |
-
}
|
| 241 |
}
|
|
|
| 38 |
return $this->namespace;
|
| 39 |
}
|
| 40 |
|
| 41 |
+
/*
|
| 42 |
* Return the block attributes
|
| 43 |
*
|
| 44 |
* @since 4.8
|
| 69 |
return $attributes;
|
| 70 |
}
|
| 71 |
|
| 72 |
+
/*
|
| 73 |
* Return the block default attributes
|
| 74 |
*
|
| 75 |
* @since 4.8
|
| 203 |
*/
|
| 204 |
public function hook() {
|
| 205 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 206 |
}
|
| 207 |
+
|
common/src/Tribe/Editor/Configuration.php
CHANGED
|
@@ -39,7 +39,6 @@ class Tribe__Editor__Configuration implements Tribe__Editor__Configuration_Inter
|
|
| 39 |
'countries' => tribe( 'languages.locations' )->get_countries(),
|
| 40 |
'usStates' => Tribe__View_Helpers::loadStates(),
|
| 41 |
),
|
| 42 |
-
'blocks' => [],
|
| 43 |
);
|
| 44 |
|
| 45 |
/**
|
| 39 |
'countries' => tribe( 'languages.locations' )->get_countries(),
|
| 40 |
'usStates' => Tribe__View_Helpers::loadStates(),
|
| 41 |
),
|
|
|
|
| 42 |
);
|
| 43 |
|
| 44 |
/**
|
common/src/Tribe/Extension.php
CHANGED
|
@@ -160,54 +160,25 @@ abstract class Tribe__Extension {
|
|
| 160 |
* Checks if the extension has permission to run, if so runs init() in child class
|
| 161 |
*/
|
| 162 |
final public function register() {
|
| 163 |
-
$extension_file = $this->get_plugin_file();
|
| 164 |
-
$extension_class_name = $this->get( 'class' );
|
| 165 |
-
$extension_version = $this->get_version();
|
| 166 |
-
$plugins_required = $this->get( 'requires', [] );
|
| 167 |
-
|
| 168 |
tribe_register_plugin(
|
| 169 |
-
$
|
| 170 |
-
$
|
| 171 |
-
$
|
| 172 |
-
$
|
| 173 |
);
|
| 174 |
|
| 175 |
$dependency = Tribe__Dependency::instance();
|
| 176 |
|
| 177 |
// check requisite plugins are active for this extension
|
| 178 |
-
$is_plugin_authorized = $dependency->has_requisite_plugins( $
|
| 179 |
-
|
| 180 |
-
/**
|
| 181 |
-
* Explicitly disallow an extension, such as a core plugin having absorbed/replaced its functionality.
|
| 182 |
-
*
|
| 183 |
-
* @since 4.12.2
|
| 184 |
-
*
|
| 185 |
-
* @param bool $is_disallowed False by default.
|
| 186 |
-
* @param string $extension_class_name This extension's class name string
|
| 187 |
-
* (without initial forward slash for namespaced classes).
|
| 188 |
-
* @param Tribe__Extension $this_instance This extension class' instance.
|
| 189 |
-
*/
|
| 190 |
-
$is_disallowed = (bool) apply_filters( 'tribe_extension_is_disallowed', false, $extension_class_name, $this );
|
| 191 |
-
|
| 192 |
-
if ( $is_disallowed ) {
|
| 193 |
-
if (
|
| 194 |
-
is_admin()
|
| 195 |
-
&& current_user_can( 'activate_plugins' )
|
| 196 |
-
) {
|
| 197 |
-
tribe_notice( 'tribe_extension_is_disallowed', [ $this, 'notice_disallowed' ], [ 'type' => 'error' ] );
|
| 198 |
-
}
|
| 199 |
-
|
| 200 |
-
deactivate_plugins( $extension_file, true );
|
| 201 |
-
|
| 202 |
-
return;
|
| 203 |
-
}
|
| 204 |
|
| 205 |
if ( $is_plugin_authorized ) {
|
| 206 |
$this->init();
|
| 207 |
|
| 208 |
-
//
|
| 209 |
-
$dependency->add_active_plugin( $
|
| 210 |
}
|
|
|
|
| 211 |
}
|
| 212 |
|
| 213 |
/**
|
|
@@ -258,7 +229,7 @@ abstract class Tribe__Extension {
|
|
| 258 |
}
|
| 259 |
|
| 260 |
/**
|
| 261 |
-
*
|
| 262 |
*
|
| 263 |
* @return string Action/hook
|
| 264 |
*/
|
|
@@ -407,25 +378,6 @@ abstract class Tribe__Extension {
|
|
| 407 |
);
|
| 408 |
}
|
| 409 |
|
| 410 |
-
/**
|
| 411 |
-
* Gets the error message about being explicitly disallowed.
|
| 412 |
-
*
|
| 413 |
-
* @since 4.12.2
|
| 414 |
-
*
|
| 415 |
-
* @return string Notice text.
|
| 416 |
-
*/
|
| 417 |
-
public function notice_disallowed() {
|
| 418 |
-
return sprintf(
|
| 419 |
-
'<p><strong>%1$s:</strong> %2$s</p>',
|
| 420 |
-
$this->get_name(),
|
| 421 |
-
esc_html_x(
|
| 422 |
-
"This extension has been programmatically disallowed. The most common reason is due to another Modern Tribe plugin having absorbed or replaced this extension's functionality. This extension plugin has been deactivated, and you should likely delete it.",
|
| 423 |
-
'extension disallowed',
|
| 424 |
-
'tribe-common'
|
| 425 |
-
)
|
| 426 |
-
);
|
| 427 |
-
}
|
| 428 |
-
|
| 429 |
/**
|
| 430 |
* Prevent cloning the singleton with 'clone' operator
|
| 431 |
*
|
| 160 |
* Checks if the extension has permission to run, if so runs init() in child class
|
| 161 |
*/
|
| 162 |
final public function register() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 163 |
tribe_register_plugin(
|
| 164 |
+
$this->get_plugin_file(),
|
| 165 |
+
$this->get( 'class' ),
|
| 166 |
+
$this->get_version(),
|
| 167 |
+
$this->get( 'requires', array() )
|
| 168 |
);
|
| 169 |
|
| 170 |
$dependency = Tribe__Dependency::instance();
|
| 171 |
|
| 172 |
// check requisite plugins are active for this extension
|
| 173 |
+
$is_plugin_authorized = $dependency->has_requisite_plugins( $this->get( 'requires', array() ) );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 174 |
|
| 175 |
if ( $is_plugin_authorized ) {
|
| 176 |
$this->init();
|
| 177 |
|
| 178 |
+
//add extension as active to dependency checker
|
| 179 |
+
$dependency->add_active_plugin( $this->get( 'class' ), $this->get_version(), $this->get_plugin_file() );
|
| 180 |
}
|
| 181 |
+
|
| 182 |
}
|
| 183 |
|
| 184 |
/**
|
| 229 |
}
|
| 230 |
|
| 231 |
/**
|
| 232 |
+
* Get's the action/hook for the extensions init()
|
| 233 |
*
|
| 234 |
* @return string Action/hook
|
| 235 |
*/
|
| 378 |
);
|
| 379 |
}
|
| 380 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 381 |
/**
|
| 382 |
* Prevent cloning the singleton with 'clone' operator
|
| 383 |
*
|
common/src/Tribe/Feature_Detection.php
CHANGED
|
@@ -6,8 +6,6 @@
|
|
| 6 |
* @since 4.7.23
|
| 7 |
*/
|
| 8 |
|
| 9 |
-
use Tribe__Utils__Array as Arr;
|
| 10 |
-
|
| 11 |
/**
|
| 12 |
* Class Tribe__Feature_Detection
|
| 13 |
*
|
|
@@ -22,17 +20,6 @@ class Tribe__Feature_Detection {
|
|
| 22 |
*/
|
| 23 |
public static $transient = 'tribe_feature_detection';
|
| 24 |
|
| 25 |
-
/**
|
| 26 |
-
* A set of example byte sizes of result sets.
|
| 27 |
-
*
|
| 28 |
-
* @since 4.10.2
|
| 29 |
-
*
|
| 30 |
-
* @var array
|
| 31 |
-
*/
|
| 32 |
-
public static $example_size = [
|
| 33 |
-
'post_result' => 6000,
|
| 34 |
-
];
|
| 35 |
-
|
| 36 |
/**
|
| 37 |
* The name of the option that will be used to indicate a feature detection is running.
|
| 38 |
*
|
|
@@ -162,97 +149,4 @@ class Tribe__Feature_Detection {
|
|
| 162 |
|
| 163 |
return ! empty( $lock_option );
|
| 164 |
}
|
| 165 |
-
|
| 166 |
-
/**
|
| 167 |
-
* Returns the value of the `max_allowed_packet` MYSQL variable, if set, or a default value.
|
| 168 |
-
*
|
| 169 |
-
* @since 4.10.2
|
| 170 |
-
*
|
| 171 |
-
* @return int The byte size of the `max_allowed_packet` MYSQL variable.
|
| 172 |
-
*/
|
| 173 |
-
public function get_mysql_max_packet_size() {
|
| 174 |
-
/**
|
| 175 |
-
* Filters the value of the `max_allowed_packet` variable before it's read from the database.
|
| 176 |
-
*
|
| 177 |
-
* If the value returned from this filter is not `null`, then it will be assumed to be the value.
|
| 178 |
-
*
|
| 179 |
-
* @since 4.10.2
|
| 180 |
-
*
|
| 181 |
-
* @param int $mysql_max_packet_size The value of the `max_allowed_packet` variable, initially `null`.
|
| 182 |
-
*/
|
| 183 |
-
$mysql_max_packet_size = apply_filters( 'tribe_max_allowed_packet_size', null );
|
| 184 |
-
|
| 185 |
-
if ( null !== $mysql_max_packet_size ) {
|
| 186 |
-
return absint( $mysql_max_packet_size );
|
| 187 |
-
}
|
| 188 |
-
|
| 189 |
-
/** @var Tribe__Cache $cache */
|
| 190 |
-
$cache = tribe( 'cache' );
|
| 191 |
-
|
| 192 |
-
$cached = $cache->get( 'max_allowed_packet' );
|
| 193 |
-
|
| 194 |
-
if ( false !== $cached ) {
|
| 195 |
-
return $cached;
|
| 196 |
-
}
|
| 197 |
-
|
| 198 |
-
global $wpdb;
|
| 199 |
-
$mysql_max_packet_size = $wpdb->get_var( "SHOW VARIABLES LIKE 'max_allowed_packet'", 1 );
|
| 200 |
-
// At min set it to 2 MBs.
|
| 201 |
-
$mysql_max_packet_size = absint( max( absint( $mysql_max_packet_size ), 2097152 ) );
|
| 202 |
-
|
| 203 |
-
$cache->set( 'max_allowed_packet', $mysql_max_packet_size, WEEK_IN_SECONDS );
|
| 204 |
-
|
| 205 |
-
return $mysql_max_packet_size;
|
| 206 |
-
}
|
| 207 |
-
|
| 208 |
-
/**
|
| 209 |
-
* Returns the suggested SQL LIMIT value, based on the `max_allowed_packet` size and example string length.
|
| 210 |
-
*
|
| 211 |
-
* This is useful to size "reasonable" LIMITs when dealing with either very long queries or potentially long
|
| 212 |
-
* result sets.
|
| 213 |
-
*
|
| 214 |
-
* @since 4.10.2
|
| 215 |
-
*
|
| 216 |
-
* @param string $example_string The example string.
|
| 217 |
-
*
|
| 218 |
-
* @return int The suggested LIMIT value.
|
| 219 |
-
*/
|
| 220 |
-
public function mysql_limit_for_string( $example_string ) {
|
| 221 |
-
$byte_size = function_exists( 'mb_strlen' )
|
| 222 |
-
? mb_strlen( $example_string )
|
| 223 |
-
: strlen( $example_string );
|
| 224 |
-
|
| 225 |
-
return $this->mysql_limit_for_size( $byte_size );
|
| 226 |
-
}
|
| 227 |
-
|
| 228 |
-
/**
|
| 229 |
-
* Returns the SQL LIMIT for a byte size, in relation to the `max_allowed_packet` value.
|
| 230 |
-
*
|
| 231 |
-
* @since 4.10.2
|
| 232 |
-
*
|
| 233 |
-
* @param int $byte_size The byte size to check.
|
| 234 |
-
*
|
| 235 |
-
* @return int The SQL LIMIT value.
|
| 236 |
-
*/
|
| 237 |
-
public function mysql_limit_for_size( $byte_size ) {
|
| 238 |
-
return absint( floor( $this->get_mysql_max_packet_size() / $byte_size ) * 0.8 );
|
| 239 |
-
}
|
| 240 |
-
|
| 241 |
-
/**
|
| 242 |
-
* Provides the SQL LIMIT value, in relation to the `max_allowed_packet` value, for a pre-existing example.
|
| 243 |
-
*
|
| 244 |
-
* Defaults to the complete post result example string if the example is not found.
|
| 245 |
-
*
|
| 246 |
-
* @since 4.10.2
|
| 247 |
-
*
|
| 248 |
-
* @param string $example The name of the example to return. See the `Tribe__Feature_Detection::$example_sizes`
|
| 249 |
-
* prop for the available examples. Defaults to the `post_result` one.
|
| 250 |
-
*
|
| 251 |
-
* @return int The SQL LIMIT value for the example.
|
| 252 |
-
*/
|
| 253 |
-
public function mysql_limit_for_example( $example ) {
|
| 254 |
-
$example_size = Arr::get( static::$example_size, $example, static::$example_size['post_result'] );
|
| 255 |
-
|
| 256 |
-
return $this->mysql_limit_for_size( $example_size );
|
| 257 |
-
}
|
| 258 |
}
|
| 6 |
* @since 4.7.23
|
| 7 |
*/
|
| 8 |
|
|
|
|
|
|
|
| 9 |
/**
|
| 10 |
* Class Tribe__Feature_Detection
|
| 11 |
*
|
| 20 |
*/
|
| 21 |
public static $transient = 'tribe_feature_detection';
|
| 22 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 23 |
/**
|
| 24 |
* The name of the option that will be used to indicate a feature detection is running.
|
| 25 |
*
|
| 149 |
|
| 150 |
return ! empty( $lock_option );
|
| 151 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 152 |
}
|
common/src/Tribe/Field.php
CHANGED
|
@@ -89,7 +89,6 @@ if ( ! class_exists( 'Tribe__Field' ) ) {
|
|
| 89 |
'can_be_empty' => false,
|
| 90 |
'clear_after' => true,
|
| 91 |
'tooltip_first' => false,
|
| 92 |
-
'allow_clear' => false,
|
| 93 |
);
|
| 94 |
|
| 95 |
// a list of valid field types, to prevent screwy behavior
|
|
@@ -188,7 +187,6 @@ if ( ! class_exists( 'Tribe__Field' ) ) {
|
|
| 188 |
$can_be_empty = (bool) $args['can_be_empty'];
|
| 189 |
$clear_after = (bool) $args['clear_after'];
|
| 190 |
$tooltip_first = (bool) $args['tooltip_first'];
|
| 191 |
-
$allow_clear = (bool) $args['allow_clear'];
|
| 192 |
|
| 193 |
// set the ID
|
| 194 |
$this->id = apply_filters( 'tribe_field_id', $id );
|
|
@@ -617,9 +615,6 @@ if ( ! class_exists( 'Tribe__Field' ) ) {
|
|
| 617 |
$field .= $this->do_field_name();
|
| 618 |
$field .= " id='{$this->id}-select'";
|
| 619 |
$field .= " class='tribe-dropdown'";
|
| 620 |
-
if ( empty( $this->allow_clear ) ) {
|
| 621 |
-
$field .= " data-prevent-clear='true'";
|
| 622 |
-
}
|
| 623 |
$field .= '>';
|
| 624 |
foreach ( $this->options as $option_id => $title ) {
|
| 625 |
$field .= '<option value="' . esc_attr( $option_id ) . '"';
|
| 89 |
'can_be_empty' => false,
|
| 90 |
'clear_after' => true,
|
| 91 |
'tooltip_first' => false,
|
|
|
|
| 92 |
);
|
| 93 |
|
| 94 |
// a list of valid field types, to prevent screwy behavior
|
| 187 |
$can_be_empty = (bool) $args['can_be_empty'];
|
| 188 |
$clear_after = (bool) $args['clear_after'];
|
| 189 |
$tooltip_first = (bool) $args['tooltip_first'];
|
|
|
|
| 190 |
|
| 191 |
// set the ID
|
| 192 |
$this->id = apply_filters( 'tribe_field_id', $id );
|
| 615 |
$field .= $this->do_field_name();
|
| 616 |
$field .= " id='{$this->id}-select'";
|
| 617 |
$field .= " class='tribe-dropdown'";
|
|
|
|
|
|
|
|
|
|
| 618 |
$field .= '>';
|
| 619 |
foreach ( $this->options as $option_id => $title ) {
|
| 620 |
$field .= '<option value="' . esc_attr( $option_id ) . '"';
|
common/src/Tribe/Freemius.php
CHANGED
|
@@ -15,9 +15,8 @@ class Tribe__Freemius {
|
|
| 15 |
private $instances = [];
|
| 16 |
|
| 17 |
/**
|
| 18 |
-
*
|
| 19 |
-
*
|
| 20 |
-
* Freemius class should only be loaded once since it will be registered as a Singleton.
|
| 21 |
*
|
| 22 |
* @since 4.9.5
|
| 23 |
*/
|
| 15 |
private $instances = [];
|
| 16 |
|
| 17 |
/**
|
| 18 |
+
* Loading of the vendor files for Freemius vendor
|
| 19 |
+
* Freemius class should only be loaded once since it will be registred as a Singleton
|
|
|
|
| 20 |
*
|
| 21 |
* @since 4.9.5
|
| 22 |
*/
|
common/src/Tribe/Image/Uploader.php
CHANGED
|
@@ -29,14 +29,13 @@ class Tribe__Image__Uploader {
|
|
| 29 |
*/
|
| 30 |
public static function reset_cache() {
|
| 31 |
self::$attachment_guids_cache = false;
|
| 32 |
-
self::$original_urls_cache
|
| 33 |
}
|
| 34 |
|
| 35 |
/**
|
| 36 |
* Uploads a file and creates the media attachment or simply returns the attachment ID if existing.
|
| 37 |
*
|
| 38 |
-
* @return int|bool The attachment post ID if the uploading and attachment is successful or the ID refers to an
|
| 39 |
-
* attachment;
|
| 40 |
* `false` otherwise.
|
| 41 |
*/
|
| 42 |
public function upload_and_get_attachment_id() {
|
|
@@ -44,66 +43,18 @@ class Tribe__Image__Uploader {
|
|
| 44 |
return false;
|
| 45 |
}
|
| 46 |
|
| 47 |
-
$existing = false;
|
| 48 |
-
|
| 49 |
if ( is_string( $this->featured_image ) && ! is_numeric( $this->featured_image ) ) {
|
| 50 |
-
|
| 51 |
-
$id = $this->
|
| 52 |
-
if ( ! $id ) {
|
| 53 |
-
$id = $this->upload_file( $this->featured_image );
|
| 54 |
-
$id = $this->maybe_retry_upload( $id );
|
| 55 |
-
}
|
| 56 |
-
$existing = (bool) $id;
|
| 57 |
} elseif ( $post = get_post( $this->featured_image ) ) {
|
| 58 |
$id = $post && 'attachment' === $post->post_type ? $this->featured_image : false;
|
| 59 |
} else {
|
| 60 |
$id = false;
|
| 61 |
}
|
| 62 |
|
| 63 |
-
do_action(
|
| 64 |
-
'tribe_log',
|
| 65 |
-
'debug',
|
| 66 |
-
__CLASS__,
|
| 67 |
-
[
|
| 68 |
-
'featured_image' => $this->featured_image,
|
| 69 |
-
'exists' => $existing,
|
| 70 |
-
'id' => $id,
|
| 71 |
-
]
|
| 72 |
-
);
|
| 73 |
-
|
| 74 |
return $id;
|
| 75 |
}
|
| 76 |
|
| 77 |
-
/**
|
| 78 |
-
* Retry to upload an image after it failed as was provided, try to decode the URL as in some cases the
|
| 79 |
-
* original URL might be encoded HTML components such as: "&" and some CDNs does not handle well different URLs
|
| 80 |
-
* as they were provided so we try to recreate the original URL where it might be required.
|
| 81 |
-
*
|
| 82 |
-
* @since 4.11.5
|
| 83 |
-
*
|
| 84 |
-
* @param int|bool $id The id of the attachment if was uploaded correctly, false otherwise.
|
| 85 |
-
*
|
| 86 |
-
* @return int The ID of the attachment after the upload retry.
|
| 87 |
-
*/
|
| 88 |
-
protected function maybe_retry_upload( $id ) {
|
| 89 |
-
if ( $id ) {
|
| 90 |
-
do_action( 'tribe_log', 'debug', __CLASS__, [ 'message' => "ID: {$id} is already a valid one." ] );
|
| 91 |
-
|
| 92 |
-
return $id;
|
| 93 |
-
}
|
| 94 |
-
|
| 95 |
-
$decoded = esc_url_raw( html_entity_decode( $this->featured_image ) );
|
| 96 |
-
|
| 97 |
-
do_action( 'tribe_log', 'debug', __CLASS__, [
|
| 98 |
-
'message' => 'Retry upload decoding the URL of the image',
|
| 99 |
-
'url' => $this->featured_image,
|
| 100 |
-
'decoded' => $decoded,
|
| 101 |
-
] );
|
| 102 |
-
|
| 103 |
-
// Maybe the URL was encoded and we need to convert it to a valid URL.
|
| 104 |
-
return $this->upload_file( $decoded );
|
| 105 |
-
}
|
| 106 |
-
|
| 107 |
/**
|
| 108 |
* @param string $file_url
|
| 109 |
*
|
|
@@ -113,147 +64,105 @@ class Tribe__Image__Uploader {
|
|
| 113 |
/**
|
| 114 |
* Allow plugins to enable local URL uploads, mainly used for testing.
|
| 115 |
*
|
| 116 |
-
* @since 4.9.5
|
| 117 |
-
*
|
| 118 |
* @param bool $allow_local_urls Whether to allow local URLs.
|
| 119 |
* @param string $file_url File URL.
|
|
|
|
|
|
|
| 120 |
*/
|
| 121 |
$allow_local_urls = apply_filters( 'tribe_image_uploader_local_urls', false, $file_url );
|
| 122 |
|
| 123 |
-
if ( !
|
| 124 |
return false;
|
| 125 |
}
|
| 126 |
|
| 127 |
-
|
| 128 |
-
|
| 129 |
-
|
| 130 |
-
|
| 131 |
-
|
| 132 |
-
$is_local = false;
|
| 133 |
-
// This is a local file no need to fetch it from the wire.
|
| 134 |
-
if ( $allow_local_urls && file_exists( $file_url ) ) {
|
| 135 |
-
$file = $file_url;
|
| 136 |
-
$is_local = true;
|
| 137 |
-
} else {
|
| 138 |
-
/**
|
| 139 |
-
* Some CDN services will append query arguments to the image URL; removing
|
| 140 |
-
* them now has the potential of blocking the image fetching completely so we
|
| 141 |
-
* let them be here.
|
| 142 |
-
*/
|
| 143 |
-
$file = download_url( $file_url );
|
| 144 |
-
if ( is_wp_error( $file ) ) {
|
| 145 |
-
do_action( 'tribe_log', 'error', __CLASS__, [
|
| 146 |
-
'message' => $file->get_error_message(),
|
| 147 |
-
'url' => $file_url,
|
| 148 |
-
'error' => $file,
|
| 149 |
-
] );
|
| 150 |
-
|
| 151 |
-
return false;
|
| 152 |
-
}
|
| 153 |
-
}
|
| 154 |
-
|
| 155 |
-
// Upload file into WP and leave WP handle the resize and such.
|
| 156 |
-
$attachment_id = media_handle_sideload( [
|
| 157 |
-
'name' => $this->create_file_name( $file ),
|
| 158 |
-
'tmp_name' => $file,
|
| 159 |
-
'post_mime_type' => 'image',
|
| 160 |
-
] );
|
| 161 |
|
| 162 |
-
|
| 163 |
-
|
| 164 |
-
|
| 165 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 166 |
|
| 167 |
-
|
| 168 |
-
do_action( 'tribe_log', 'error', __CLASS__, [
|
| 169 |
-
'message' => $attachment_id->get_error_message(),
|
| 170 |
-
'url' => $file_url,
|
| 171 |
-
'error' => $attachment_id,
|
| 172 |
-
] );
|
| 173 |
|
| 174 |
return false;
|
| 175 |
}
|
| 176 |
|
| 177 |
-
|
| 178 |
|
| 179 |
-
$
|
| 180 |
-
|
|
|
|
| 181 |
|
| 182 |
-
|
| 183 |
-
// Only update the cache if is a valid attachment.
|
| 184 |
-
if ( $attachment_post instanceof WP_Post ) {
|
| 185 |
-
self::$attachment_guids_cache[ $attachment_post->guid ] = $attachment_id;
|
| 186 |
-
self::$original_urls_cache[ $file_url ] = $attachment_id;
|
| 187 |
}
|
| 188 |
|
| 189 |
-
|
| 190 |
-
}
|
| 191 |
-
|
| 192 |
-
/**
|
| 193 |
-
* WordPress requires to have an extension in all all files as uses `wp_check_filetype` which uses the extension
|
| 194 |
-
* of the file to define if a file is valid or not, in this case the extension might not be present in some URLs of
|
| 195 |
-
* attachments or media files, in those cases we try to guess the right extension using the mime of the file as
|
| 196 |
-
* an alternative, if the $filename is a path we can verify the mime type using native WP functions.
|
| 197 |
-
*
|
| 198 |
-
* @since 4.11.5
|
| 199 |
-
*
|
| 200 |
-
* @param string $filename The name of the file or URL.
|
| 201 |
-
*
|
| 202 |
-
* @return string Returned a file name with an extension if is not already part of the file name.
|
| 203 |
-
*/
|
| 204 |
-
protected function create_file_name( $filename ) {
|
| 205 |
-
/**
|
| 206 |
* We use the path basename only here to provided WordPress with a good filename
|
| 207 |
* that will allow it to correctly detect and validate the extension.
|
| 208 |
*/
|
| 209 |
-
$path
|
|
|
|
| 210 |
|
| 211 |
-
|
| 212 |
-
|
|
|
|
| 213 |
|
| 214 |
-
|
| 215 |
-
if ( ! empty( $properties['type'] ) ) {
|
| 216 |
-
return $name;
|
| 217 |
}
|
| 218 |
|
| 219 |
-
|
| 220 |
-
if ( !
|
| 221 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 222 |
}
|
| 223 |
|
| 224 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 225 |
|
| 226 |
-
|
| 227 |
-
if ( $mime === '' ) {
|
| 228 |
-
return $name;
|
| 229 |
-
}
|
| 230 |
|
| 231 |
-
|
| 232 |
-
$mime_to_extensions = array_flip( wp_get_mime_types() );
|
| 233 |
|
| 234 |
-
|
| 235 |
-
|
| 236 |
-
return $name;
|
| 237 |
-
}
|
| 238 |
|
| 239 |
-
|
| 240 |
-
$
|
|
|
|
|
|
|
|
|
|
| 241 |
|
| 242 |
-
|
| 243 |
-
return implode( '.', [ $name, reset( $parts ) ] );
|
| 244 |
}
|
| 245 |
|
| 246 |
protected function get_attachment_ID_from_url( $featured_image ) {
|
| 247 |
$this->maybe_init_attachment_guids_cache();
|
| 248 |
$this->maybe_init_attachment_original_urls_cache();
|
| 249 |
|
| 250 |
-
$guids_cache
|
| 251 |
$original_urls_cache = self::$original_urls_cache;
|
| 252 |
if ( isset( $guids_cache[ $featured_image ] ) ) {
|
| 253 |
return $guids_cache[ $featured_image ];
|
| 254 |
-
}
|
| 255 |
-
|
| 256 |
-
if ( isset( $original_urls_cache[ $featured_image ] ) ) {
|
| 257 |
return $original_urls_cache[ $featured_image ];
|
| 258 |
}
|
| 259 |
|
|
@@ -267,11 +176,11 @@ class Tribe__Image__Uploader {
|
|
| 267 |
$guids = $wpdb->get_results( "SELECT ID, guid FROM $wpdb->posts where post_type = 'attachment'" );
|
| 268 |
|
| 269 |
if ( $guids ) {
|
| 270 |
-
$keys
|
| 271 |
-
$values
|
| 272 |
self::$attachment_guids_cache = array_combine( $keys, $values );
|
| 273 |
} else {
|
| 274 |
-
self::$attachment_guids_cache =
|
| 275 |
}
|
| 276 |
}
|
| 277 |
}
|
|
@@ -289,11 +198,11 @@ class Tribe__Image__Uploader {
|
|
| 289 |
" );
|
| 290 |
|
| 291 |
if ( $original_urls ) {
|
| 292 |
-
$keys
|
| 293 |
-
$values
|
| 294 |
self::$original_urls_cache = array_combine( $keys, $values );
|
| 295 |
} else {
|
| 296 |
-
self::$original_urls_cache =
|
| 297 |
}
|
| 298 |
}
|
| 299 |
}
|
|
@@ -305,7 +214,7 @@ class Tribe__Image__Uploader {
|
|
| 305 |
* @since 4.7.22
|
| 306 |
*
|
| 307 |
* @param string $unused_error_code The error numeric code.
|
| 308 |
-
* @param string $message
|
| 309 |
*
|
| 310 |
* @throws RuntimeException To pass the error as an exception to
|
| 311 |
* the handler.
|
| 29 |
*/
|
| 30 |
public static function reset_cache() {
|
| 31 |
self::$attachment_guids_cache = false;
|
| 32 |
+
self::$original_urls_cache = false;
|
| 33 |
}
|
| 34 |
|
| 35 |
/**
|
| 36 |
* Uploads a file and creates the media attachment or simply returns the attachment ID if existing.
|
| 37 |
*
|
| 38 |
+
* @return int|bool The attachment post ID if the uploading and attachment is successful or the ID refers to an attachment;
|
|
|
|
| 39 |
* `false` otherwise.
|
| 40 |
*/
|
| 41 |
public function upload_and_get_attachment_id() {
|
| 43 |
return false;
|
| 44 |
}
|
| 45 |
|
|
|
|
|
|
|
| 46 |
if ( is_string( $this->featured_image ) && ! is_numeric( $this->featured_image ) ) {
|
| 47 |
+
$existing = $this->get_attachment_ID_from_url( $this->featured_image );
|
| 48 |
+
$id = $existing ? $existing : $this->upload_file( $this->featured_image );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 49 |
} elseif ( $post = get_post( $this->featured_image ) ) {
|
| 50 |
$id = $post && 'attachment' === $post->post_type ? $this->featured_image : false;
|
| 51 |
} else {
|
| 52 |
$id = false;
|
| 53 |
}
|
| 54 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 55 |
return $id;
|
| 56 |
}
|
| 57 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 58 |
/**
|
| 59 |
* @param string $file_url
|
| 60 |
*
|
| 64 |
/**
|
| 65 |
* Allow plugins to enable local URL uploads, mainly used for testing.
|
| 66 |
*
|
|
|
|
|
|
|
| 67 |
* @param bool $allow_local_urls Whether to allow local URLs.
|
| 68 |
* @param string $file_url File URL.
|
| 69 |
+
*
|
| 70 |
+
* @since 4.9.5
|
| 71 |
*/
|
| 72 |
$allow_local_urls = apply_filters( 'tribe_image_uploader_local_urls', false, $file_url );
|
| 73 |
|
| 74 |
+
if ( ! filter_var( $file_url, FILTER_VALIDATE_URL ) && ! $allow_local_urls ) {
|
| 75 |
return false;
|
| 76 |
}
|
| 77 |
|
| 78 |
+
/*
|
| 79 |
+
* Since `file_get_contents` would fail silently we set an explicit
|
| 80 |
+
* error handler to catch the content of error.s.
|
| 81 |
+
*/
|
| 82 |
+
set_error_handler( array( $this, 'handle_error' ) );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 83 |
|
| 84 |
+
/*
|
| 85 |
+
* Some CDN services will append query arguments to the image URL; removing
|
| 86 |
+
* them now has the potential of blocking the image fetching completely so we
|
| 87 |
+
* let them be here.
|
| 88 |
+
*/
|
| 89 |
+
try {
|
| 90 |
+
$contents = file_get_contents( $file_url );
|
| 91 |
+
} catch ( Exception $e ) {
|
| 92 |
+
$message = sprintf( 'Could not upload image file "%s": with message "%s"', $file_url, $e->getMessage() );
|
| 93 |
+
tribe( 'logger' )->log_error( $message, 'Image Uploader' );
|
| 94 |
|
| 95 |
+
restore_error_handler();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 96 |
|
| 97 |
return false;
|
| 98 |
}
|
| 99 |
|
| 100 |
+
restore_error_handler();
|
| 101 |
|
| 102 |
+
if ( false === $contents ) {
|
| 103 |
+
$message = sprintf( 'Could not upload image file "%s": failed getting the contents.', $file_url );
|
| 104 |
+
tribe( 'logger' )->log_error( $message, 'Image Uploader' );
|
| 105 |
|
| 106 |
+
return false;
|
|
|
|
|
|
|
|
|
|
|
|
|
| 107 |
}
|
| 108 |
|
| 109 |
+
/*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 110 |
* We use the path basename only here to provided WordPress with a good filename
|
| 111 |
* that will allow it to correctly detect and validate the extension.
|
| 112 |
*/
|
| 113 |
+
$path = parse_url( $file_url, PHP_URL_PATH );
|
| 114 |
+
$upload = wp_upload_bits( basename( $path ), null, $contents );
|
| 115 |
|
| 116 |
+
if ( isset( $upload['error'] ) && $upload['error'] ) {
|
| 117 |
+
$message = sprintf( 'Could not upload image file "%s" with message "%s"', $file_url, $upload['error'] );
|
| 118 |
+
tribe( 'logger' )->log_error( $message, 'Image Uploader' );
|
| 119 |
|
| 120 |
+
return false;
|
|
|
|
|
|
|
| 121 |
}
|
| 122 |
|
| 123 |
+
$type = '';
|
| 124 |
+
if ( ! empty( $upload['type'] ) ) {
|
| 125 |
+
$type = $upload['type'];
|
| 126 |
+
} else {
|
| 127 |
+
$mime = wp_check_filetype( $upload['file'] );
|
| 128 |
+
if ( $mime ) {
|
| 129 |
+
$type = $mime['type'];
|
| 130 |
+
}
|
| 131 |
}
|
| 132 |
|
| 133 |
+
$attachment = array(
|
| 134 |
+
'post_title' => basename( $upload['file'] ),
|
| 135 |
+
'post_content' => '',
|
| 136 |
+
'post_type' => 'attachment',
|
| 137 |
+
'post_mime_type' => $type,
|
| 138 |
+
'guid' => $upload['url'],
|
| 139 |
+
);
|
| 140 |
|
| 141 |
+
$id = wp_insert_attachment( $attachment, $upload['file'] );
|
|
|
|
|
|
|
|
|
|
| 142 |
|
| 143 |
+
require_once( ABSPATH . 'wp-admin/includes/image.php' );
|
|
|
|
| 144 |
|
| 145 |
+
wp_update_attachment_metadata( $id, wp_generate_attachment_metadata( $id, $upload['file'] ) );
|
| 146 |
+
update_post_meta( $id, '_tribe_importer_original_url', $file_url );
|
|
|
|
|
|
|
| 147 |
|
| 148 |
+
$this->maybe_init_attachment_guids_cache();
|
| 149 |
+
$this->maybe_init_attachment_original_urls_cache();
|
| 150 |
+
|
| 151 |
+
self::$attachment_guids_cache[ get_post( $id )->guid ] = $id;
|
| 152 |
+
self::$original_urls_cache[ $file_url ] = $id;
|
| 153 |
|
| 154 |
+
return $id;
|
|
|
|
| 155 |
}
|
| 156 |
|
| 157 |
protected function get_attachment_ID_from_url( $featured_image ) {
|
| 158 |
$this->maybe_init_attachment_guids_cache();
|
| 159 |
$this->maybe_init_attachment_original_urls_cache();
|
| 160 |
|
| 161 |
+
$guids_cache = self::$attachment_guids_cache;
|
| 162 |
$original_urls_cache = self::$original_urls_cache;
|
| 163 |
if ( isset( $guids_cache[ $featured_image ] ) ) {
|
| 164 |
return $guids_cache[ $featured_image ];
|
| 165 |
+
} elseif ( isset( $original_urls_cache[ $featured_image ] ) ) {
|
|
|
|
|
|
|
| 166 |
return $original_urls_cache[ $featured_image ];
|
| 167 |
}
|
| 168 |
|
| 176 |
$guids = $wpdb->get_results( "SELECT ID, guid FROM $wpdb->posts where post_type = 'attachment'" );
|
| 177 |
|
| 178 |
if ( $guids ) {
|
| 179 |
+
$keys = wp_list_pluck( $guids, 'guid' );
|
| 180 |
+
$values = wp_list_pluck( $guids, 'ID' );
|
| 181 |
self::$attachment_guids_cache = array_combine( $keys, $values );
|
| 182 |
} else {
|
| 183 |
+
self::$attachment_guids_cache = array();
|
| 184 |
}
|
| 185 |
}
|
| 186 |
}
|
| 198 |
" );
|
| 199 |
|
| 200 |
if ( $original_urls ) {
|
| 201 |
+
$keys = wp_list_pluck( $original_urls, 'meta_value' );
|
| 202 |
+
$values = wp_list_pluck( $original_urls, 'ID' );
|
| 203 |
self::$original_urls_cache = array_combine( $keys, $values );
|
| 204 |
} else {
|
| 205 |
+
self::$original_urls_cache = array();
|
| 206 |
}
|
| 207 |
}
|
| 208 |
}
|
| 214 |
* @since 4.7.22
|
| 215 |
*
|
| 216 |
* @param string $unused_error_code The error numeric code.
|
| 217 |
+
* @param string $message The error message.
|
| 218 |
*
|
| 219 |
* @throws RuntimeException To pass the error as an exception to
|
| 220 |
* the handler.
|
common/src/Tribe/Languages/Locations.php
CHANGED
|
@@ -135,7 +135,7 @@ class Tribe__Languages__Locations {
|
|
| 135 |
'TF' => esc_html__( 'French Southern Territories', 'tribe-common' ),
|
| 136 |
'GA' => esc_html__( 'Gabon', 'tribe-common' ),
|
| 137 |
'GM' => esc_html__( 'Gambia', 'tribe-common' ),
|
| 138 |
-
'GE' =>
|
| 139 |
'DE' => esc_html__( 'Germany', 'tribe-common' ),
|
| 140 |
'GH' => esc_html__( 'Ghana', 'tribe-common' ),
|
| 141 |
'GI' => esc_html__( 'Gibraltar', 'tribe-common' ),
|
|
@@ -182,6 +182,7 @@ class Tribe__Languages__Locations {
|
|
| 182 |
'LT' => esc_html__( 'Lithuania', 'tribe-common' ),
|
| 183 |
'LU' => esc_html__( 'Luxembourg', 'tribe-common' ),
|
| 184 |
'MO' => esc_html__( 'Macau', 'tribe-common' ),
|
|
|
|
| 185 |
'MG' => esc_html__( 'Madagascar', 'tribe-common' ),
|
| 186 |
'MW' => esc_html__( 'Malawi', 'tribe-common' ),
|
| 187 |
'MY' => esc_html__( 'Malaysia', 'tribe-common' ),
|
|
@@ -214,7 +215,6 @@ class Tribe__Languages__Locations {
|
|
| 214 |
'NG' => esc_html__( 'Nigeria', 'tribe-common' ),
|
| 215 |
'NU' => esc_html__( 'Niue', 'tribe-common' ),
|
| 216 |
'NF' => esc_html__( 'Norfolk Island', 'tribe-common' ),
|
| 217 |
-
'MK' => esc_html__( 'North Macedonia', 'tribe-common' ),
|
| 218 |
'MP' => esc_html__( 'Northern Mariana Islands', 'tribe-common' ),
|
| 219 |
'NO' => esc_html__( 'Norway', 'tribe-common' ),
|
| 220 |
'OM' => esc_html__( 'Oman', 'tribe-common' ),
|
|
@@ -331,7 +331,7 @@ class Tribe__Languages__Locations {
|
|
| 331 |
'DE' => esc_html__( 'Delaware', 'tribe-common' ),
|
| 332 |
'DC' => esc_html__( 'District of Columbia', 'tribe-common' ),
|
| 333 |
'FL' => esc_html__( 'Florida', 'tribe-common' ),
|
| 334 |
-
'GA' =>
|
| 335 |
'HI' => esc_html__( 'Hawaii', 'tribe-common' ),
|
| 336 |
'ID' => esc_html__( 'Idaho', 'tribe-common' ),
|
| 337 |
'IL' => esc_html__( 'Illinois', 'tribe-common' ),
|
| 135 |
'TF' => esc_html__( 'French Southern Territories', 'tribe-common' ),
|
| 136 |
'GA' => esc_html__( 'Gabon', 'tribe-common' ),
|
| 137 |
'GM' => esc_html__( 'Gambia', 'tribe-common' ),
|
| 138 |
+
'GE' => esc_html__( 'Georgia', 'tribe-common' ),
|
| 139 |
'DE' => esc_html__( 'Germany', 'tribe-common' ),
|
| 140 |
'GH' => esc_html__( 'Ghana', 'tribe-common' ),
|
| 141 |
'GI' => esc_html__( 'Gibraltar', 'tribe-common' ),
|
| 182 |
'LT' => esc_html__( 'Lithuania', 'tribe-common' ),
|
| 183 |
'LU' => esc_html__( 'Luxembourg', 'tribe-common' ),
|
| 184 |
'MO' => esc_html__( 'Macau', 'tribe-common' ),
|
| 185 |
+
'MK' => esc_html__( 'Macedonia', 'tribe-common' ),
|
| 186 |
'MG' => esc_html__( 'Madagascar', 'tribe-common' ),
|
| 187 |
'MW' => esc_html__( 'Malawi', 'tribe-common' ),
|
| 188 |
'MY' => esc_html__( 'Malaysia', 'tribe-common' ),
|
| 215 |
'NG' => esc_html__( 'Nigeria', 'tribe-common' ),
|
| 216 |
'NU' => esc_html__( 'Niue', 'tribe-common' ),
|
| 217 |
'NF' => esc_html__( 'Norfolk Island', 'tribe-common' ),
|
|
|
|
| 218 |
'MP' => esc_html__( 'Northern Mariana Islands', 'tribe-common' ),
|
| 219 |
'NO' => esc_html__( 'Norway', 'tribe-common' ),
|
| 220 |
'OM' => esc_html__( 'Oman', 'tribe-common' ),
|
| 331 |
'DE' => esc_html__( 'Delaware', 'tribe-common' ),
|
| 332 |
'DC' => esc_html__( 'District of Columbia', 'tribe-common' ),
|
| 333 |
'FL' => esc_html__( 'Florida', 'tribe-common' ),
|
| 334 |
+
'GA' => esc_html__( 'Georgia', 'tribe-common' ),
|
| 335 |
'HI' => esc_html__( 'Hawaii', 'tribe-common' ),
|
| 336 |
'ID' => esc_html__( 'Idaho', 'tribe-common' ),
|
| 337 |
'IL' => esc_html__( 'Illinois', 'tribe-common' ),
|
common/src/Tribe/Log.php
CHANGED
|
@@ -282,9 +282,6 @@ class Tribe__Log {
|
|
| 282 |
public function set_current_logger( $engine ) {
|
| 283 |
$available_engines = $this->get_logging_engines();
|
| 284 |
|
| 285 |
-
// Make sure to de-duplicate the slashes on class names.
|
| 286 |
-
$engine = str_replace( '\\\\', '\\', $engine );
|
| 287 |
-
|
| 288 |
if ( ! isset( $available_engines[ $engine ] ) ) {
|
| 289 |
throw new Exception( sprintf( __( 'Cannot set %s as the current logging engine', 'tribe-common' ), $engine ) );
|
| 290 |
}
|
| 282 |
public function set_current_logger( $engine ) {
|
| 283 |
$available_engines = $this->get_logging_engines();
|
| 284 |
|
|
|
|
|
|
|
|
|
|
| 285 |
if ( ! isset( $available_engines[ $engine ] ) ) {
|
| 286 |
throw new Exception( sprintf( __( 'Cannot set %s as the current logging engine', 'tribe-common' ), $engine ) );
|
| 287 |
}
|
common/src/Tribe/Log/Action_Logger.php
DELETED
|
@@ -1,125 +0,0 @@
|
|
| 1 |
-
<?php
|
| 2 |
-
/**
|
| 3 |
-
* Hooks the `tribe_log` action based logger under the existing one for back-compatibility.
|
| 4 |
-
*
|
| 5 |
-
* @since 4.9.16
|
| 6 |
-
*
|
| 7 |
-
* @package Tribe\Log
|
| 8 |
-
*/
|
| 9 |
-
|
| 10 |
-
namespace Tribe\Log;
|
| 11 |
-
|
| 12 |
-
use Monolog\Logger;
|
| 13 |
-
use Tribe__Log;
|
| 14 |
-
|
| 15 |
-
/**
|
| 16 |
-
* Class Action_Logger
|
| 17 |
-
*
|
| 18 |
-
* @since 4.9.16
|
| 19 |
-
*
|
| 20 |
-
* @package Tribe\Log
|
| 21 |
-
*/
|
| 22 |
-
class Action_Logger implements \Tribe__Log__Logger {
|
| 23 |
-
|
| 24 |
-
/**
|
| 25 |
-
* {@inheritDoc}
|
| 26 |
-
*
|
| 27 |
-
* @since 4.9.16
|
| 28 |
-
*/
|
| 29 |
-
public function is_available() {
|
| 30 |
-
return true;
|
| 31 |
-
}
|
| 32 |
-
|
| 33 |
-
/**
|
| 34 |
-
* {@inheritDoc}
|
| 35 |
-
*
|
| 36 |
-
* @since 4.9.16
|
| 37 |
-
*/
|
| 38 |
-
public function get_name() {
|
| 39 |
-
return __( 'Action-based Logger', 'tribe-common' );
|
| 40 |
-
}
|
| 41 |
-
|
| 42 |
-
/**
|
| 43 |
-
* {@inheritDoc}
|
| 44 |
-
*
|
| 45 |
-
* @since 4.9.16
|
| 46 |
-
*/
|
| 47 |
-
public function log( $entry, $type = Tribe__Log::DEBUG, $src = '' ) {
|
| 48 |
-
$message = empty( $src ) ? $entry : $src . ': ' . $entry;
|
| 49 |
-
|
| 50 |
-
do_action( 'tribe_log', $this->translate_log_level( $type ), $message );
|
| 51 |
-
}
|
| 52 |
-
|
| 53 |
-
/**
|
| 54 |
-
* Translates the log types used by `Tribe__Log` to those used by Monolog.
|
| 55 |
-
*
|
| 56 |
-
* @since 4.9.16
|
| 57 |
-
*
|
| 58 |
-
* @param string $type The `Tribe__Log` log type.
|
| 59 |
-
*
|
| 60 |
-
* @return int The Monolog equivalent of the current level.
|
| 61 |
-
*/
|
| 62 |
-
protected function translate_log_level( $type ) {
|
| 63 |
-
switch ( $type ) {
|
| 64 |
-
case Tribe__Log::DEBUG:
|
| 65 |
-
return Logger::DEBUG;
|
| 66 |
-
case Tribe__Log::ERROR:
|
| 67 |
-
return Logger::ERROR;
|
| 68 |
-
case Tribe__Log::WARNING:
|
| 69 |
-
return Logger::WARNING;
|
| 70 |
-
case Tribe__Log::SUCCESS:
|
| 71 |
-
default:
|
| 72 |
-
return Logger::INFO;
|
| 73 |
-
}
|
| 74 |
-
}
|
| 75 |
-
|
| 76 |
-
/**
|
| 77 |
-
* {@inheritDoc}
|
| 78 |
-
*
|
| 79 |
-
* @since 4.9.16
|
| 80 |
-
*/
|
| 81 |
-
public function retrieve( $limit = 0, array $args = array() ) {
|
| 82 |
-
return [
|
| 83 |
-
[
|
| 84 |
-
'message' => __(
|
| 85 |
-
'The Action Logger will dispatch any logging message using the "tribe_log" action writing, by ' .
|
| 86 |
-
'default, to the PHP error log.',
|
| 87 |
-
'tribe-common' )
|
| 88 |
-
],
|
| 89 |
-
];
|
| 90 |
-
}
|
| 91 |
-
|
| 92 |
-
/**
|
| 93 |
-
* {@inheritDoc}
|
| 94 |
-
*
|
| 95 |
-
* @since 4.9.16
|
| 96 |
-
*/
|
| 97 |
-
public function list_available_logs() {
|
| 98 |
-
return [];
|
| 99 |
-
}
|
| 100 |
-
|
| 101 |
-
/**
|
| 102 |
-
* Changes the Monolog logger channel to the specified one.
|
| 103 |
-
*
|
| 104 |
-
* @since 4.9.16
|
| 105 |
-
*
|
| 106 |
-
* @param string $log_identifier The channel to switch to.
|
| 107 |
-
* @param bool $create Unused by this class.
|
| 108 |
-
*
|
| 109 |
-
* @return bool The exit status of the channel change.
|
| 110 |
-
*
|
| 111 |
-
* @uses \Tribe\Log\Monolog_Logger::set_channel().
|
| 112 |
-
*/
|
| 113 |
-
public function use_log( $log_identifier, $create = false ) {
|
| 114 |
-
return tribe( 'monolog' )->set_global_channel( $log_identifier );
|
| 115 |
-
}
|
| 116 |
-
|
| 117 |
-
/**
|
| 118 |
-
* {@inheritDoc}
|
| 119 |
-
*
|
| 120 |
-
* @since 4.9.16
|
| 121 |
-
*/
|
| 122 |
-
public function cleanup() {
|
| 123 |
-
return true;
|
| 124 |
-
}
|
| 125 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
common/src/Tribe/Log/Canonical_Formatter.php
DELETED
|
@@ -1,101 +0,0 @@
|
|
| 1 |
-
<?php
|
| 2 |
-
/**
|
| 3 |
-
* ${CARET}
|
| 4 |
-
*
|
| 5 |
-
* @since 4.9.16
|
| 6 |
-
*
|
| 7 |
-
* @package Tribe\Log
|
| 8 |
-
*/
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
namespace Tribe\Log;
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
use Monolog\Formatter\LineFormatter;
|
| 15 |
-
|
| 16 |
-
class Canonical_Formatter extends LineFormatter {
|
| 17 |
-
|
| 18 |
-
/**
|
| 19 |
-
* Formats a log record.
|
| 20 |
-
*
|
| 21 |
-
* @since 4.9.16
|
| 22 |
-
*
|
| 23 |
-
* @param array $record A record to format.
|
| 24 |
-
*
|
| 25 |
-
* @return mixed The formatted record.
|
| 26 |
-
*/
|
| 27 |
-
public function format( array $record ) {
|
| 28 |
-
$has_context = ! empty( $record['context'] );
|
| 29 |
-
|
| 30 |
-
if ( $has_context ) {
|
| 31 |
-
$record['message'] = $this->format_record_message( $record );
|
| 32 |
-
|
| 33 |
-
$this->format = 'tribe-canonical-line channel=%channel% %message%';
|
| 34 |
-
} else {
|
| 35 |
-
// Fall-back on a standard format if the message does not have a context.
|
| 36 |
-
$this->format = 'tribe.%channel%.%level_name%: %message%';
|
| 37 |
-
}
|
| 38 |
-
|
| 39 |
-
return parent::format( $record );
|
| 40 |
-
}
|
| 41 |
-
|
| 42 |
-
/**
|
| 43 |
-
* Formats the record to the canonical format.
|
| 44 |
-
*
|
| 45 |
-
* @since 4.9.16
|
| 46 |
-
*
|
| 47 |
-
* @param array $record The record to process.
|
| 48 |
-
*
|
| 49 |
-
* @return string The formatted message, as built from the record context and message, in the format `<key>=<value>`.
|
| 50 |
-
*/
|
| 51 |
-
protected function format_record_message( array $record ) {
|
| 52 |
-
$message = [];
|
| 53 |
-
$extra = [];
|
| 54 |
-
|
| 55 |
-
$extra['level'] = isset( $record['level_name'] ) ? strtolower( $record['level_name'] ) : 'debug';
|
| 56 |
-
|
| 57 |
-
if ( ! empty( $record['message'] ) ) {
|
| 58 |
-
// Use the message as the source.
|
| 59 |
-
$extra['source'] = $this->escape_quotes( $record['message'] );
|
| 60 |
-
}
|
| 61 |
-
|
| 62 |
-
$context = $record['context'];
|
| 63 |
-
$context = array_merge( $extra, $context );
|
| 64 |
-
|
| 65 |
-
foreach ( $context as $key => $value ) {
|
| 66 |
-
$escape = false;
|
| 67 |
-
|
| 68 |
-
if ( is_bool( $value ) ) {
|
| 69 |
-
$value = $value ? 'true' : 'false';
|
| 70 |
-
} elseif ( ! is_scalar( $value ) ) {
|
| 71 |
-
$value = json_encode( $value );
|
| 72 |
-
if ( false === $value ) {
|
| 73 |
-
$value = 'malformed';
|
| 74 |
-
} else {
|
| 75 |
-
$escape = true;
|
| 76 |
-
}
|
| 77 |
-
}
|
| 78 |
-
|
| 79 |
-
if ( $escape || ( is_string( $value ) && preg_match( '~[\\\\/\\s]+~', $value ) ) ) {
|
| 80 |
-
$value = '"' . $this->escape_quotes( $value ) . '"';
|
| 81 |
-
}
|
| 82 |
-
|
| 83 |
-
$message[] = "{$key}={$value}";
|
| 84 |
-
}
|
| 85 |
-
|
| 86 |
-
return implode( ' ', $message );
|
| 87 |
-
}
|
| 88 |
-
|
| 89 |
-
/**
|
| 90 |
-
* Escapes the double quotes in a string.
|
| 91 |
-
*
|
| 92 |
-
* @since 4.9.16
|
| 93 |
-
*
|
| 94 |
-
* @param string $string The string to escape the quotes in.
|
| 95 |
-
*
|
| 96 |
-
* @return string The string, with the quotes escaped.
|
| 97 |
-
*/
|
| 98 |
-
protected function escape_quotes( $string ) {
|
| 99 |
-
return str_replace( '"', '\\"', $string ) ;
|
| 100 |
-
}
|
| 101 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
common/src/Tribe/Log/File_Logger.php
CHANGED
|
@@ -27,7 +27,7 @@ class Tribe__Log__File_Logger implements Tribe__Log__Logger {
|
|
| 27 |
*
|
| 28 |
* @var string $log_dir
|
| 29 |
*/
|
| 30 |
-
$this->log_dir = apply_filters( 'tribe_file_logger_directory',
|
| 31 |
}
|
| 32 |
|
| 33 |
/**
|
| 27 |
*
|
| 28 |
* @var string $log_dir
|
| 29 |
*/
|
| 30 |
+
$this->log_dir = apply_filters( 'tribe_file_logger_directory', sys_get_temp_dir() );
|
| 31 |
}
|
| 32 |
|
| 33 |
/**
|
common/src/Tribe/Log/Monolog_Logger.php
DELETED
|
@@ -1,54 +0,0 @@
|
|
| 1 |
-
<?php
|
| 2 |
-
/**
|
| 3 |
-
* An extension of the base Monolog logger to add our need to replace the instance, and global, loggers.
|
| 4 |
-
*
|
| 5 |
-
* @since 4.9.16
|
| 6 |
-
*
|
| 7 |
-
* @package Tribe\Log
|
| 8 |
-
*/
|
| 9 |
-
|
| 10 |
-
namespace Tribe\Log;
|
| 11 |
-
|
| 12 |
-
use Monolog\Logger;
|
| 13 |
-
|
| 14 |
-
/**
|
| 15 |
-
* Class Monolog_Logger
|
| 16 |
-
*
|
| 17 |
-
* @since 4.9.16
|
| 18 |
-
*
|
| 19 |
-
* @package Tribe\Log
|
| 20 |
-
*/
|
| 21 |
-
class Monolog_Logger extends Logger {
|
| 22 |
-
/**
|
| 23 |
-
* @since 4.9.16
|
| 24 |
-
*/
|
| 25 |
-
const DEFAULT_CHANNEL = 'default';
|
| 26 |
-
|
| 27 |
-
/**
|
| 28 |
-
* Resets the global channel to the default one.
|
| 29 |
-
*
|
| 30 |
-
* @since 4.9.16
|
| 31 |
-
*
|
| 32 |
-
* @return bool Whether the channel reset
|
| 33 |
-
*/
|
| 34 |
-
public function reset_global_channel() {
|
| 35 |
-
return $this->set_global_channel( static::DEFAULT_CHANNEL );
|
| 36 |
-
}
|
| 37 |
-
|
| 38 |
-
/**
|
| 39 |
-
* Clones this logger and replaces it in the `tribe` container.
|
| 40 |
-
*
|
| 41 |
-
* @since 4.9.16
|
| 42 |
-
*
|
| 43 |
-
* @param string $channel The new logger name, also referred to as "channel" (hence the method name).
|
| 44 |
-
*
|
| 45 |
-
* @return bool Whether the channel change was successful or not.
|
| 46 |
-
*/
|
| 47 |
-
public function set_global_channel( $channel ) {
|
| 48 |
-
$new = $this->withName( $channel );
|
| 49 |
-
tribe_register( Logger::class, $new );
|
| 50 |
-
tribe_register( 'monolog', $new );
|
| 51 |
-
|
| 52 |
-
return $channel === tribe( 'monolog' )->getName();
|
| 53 |
-
}
|
| 54 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
common/src/Tribe/Log/README.md
DELETED
|
@@ -1,154 +0,0 @@
|
|
| 1 |
-
# Monolog-based logging
|
| 2 |
-
|
| 3 |
-
We've introduced a [Monolog based](https://github.com/Seldaek/monolog) logger in our common libraries.
|
| 4 |
-
You can find more information about all the possibilities this opens [on the library documentaion](https://seldaek.github.io/monolog/), but this document will serve as an introduction to the essentials of its day to day use.
|
| 5 |
-
|
| 6 |
-
## When should I log?
|
| 7 |
-
|
| 8 |
-
Whenever you feel you might have to debug this in the future and could use that information.
|
| 9 |
-
|
| 10 |
-
> Pro tip: if you, as a developer, find yourself using `var_dump` and `error_log` a lot, then you should log instead. Someone, someday, will have your same issue.
|
| 11 |
-
|
| 12 |
-
Worried about "spamming" the logs? [Read here](#logging-levels--or-stuff-does-not-appear-in-the-log).
|
| 13 |
-
|
| 14 |
-
## This will deprecate the old logger, but not yet
|
| 15 |
-
|
| 16 |
-
At first we're not replacing the "old" logger with this new one, we're just asking you **to stop using the old logger** in your code from now on and use the new, Monolog-based, one.
|
| 17 |
-
The old logger still offers file-based logging and connections to the UI the new logger is not yet offering; the current implementation will allow us, in the future, to log **everything** with the Monolog-based logger, but, currently, intercepting log messages from the "old" logger requires manual activation, see the following section.
|
| 18 |
-
|
| 19 |
-
To be clear: this is what we mean by "old" or "legacy" logger:
|
| 20 |
-
|
| 21 |
-
```php
|
| 22 |
-
<?php
|
| 23 |
-
tribe( 'logger' )->log_debug( 'Some debug information', 'The source' );
|
| 24 |
-
tribe( 'logger' )->log( 'Some information', Tribe__Log::DEBUG, 'The source' );
|
| 25 |
-
```
|
| 26 |
-
|
| 27 |
-
### Intercepting legacy logger logs with the new Monolog logger
|
| 28 |
-
|
| 29 |
-
The Monolog-based logger will handle logging coming from the legacy logger only if explicitly told so.
|
| 30 |
-
|
| 31 |
-
You can activate this function with this code:
|
| 32 |
-
|
| 33 |
-
```php
|
| 34 |
-
<?php
|
| 35 |
-
add_filter( 'tribe_log_use_action_logger', '__return_true' );
|
| 36 |
-
```
|
| 37 |
-
|
| 38 |
-
Once this is in your code any call to the legacy logger wil be redirected to the new one.
|
| 39 |
-
|
| 40 |
-
## Using the logger
|
| 41 |
-
|
| 42 |
-
The new logger listens on the `tribe_log` action.
|
| 43 |
-
By default it will log to the `default` channel (see [Monolog documentation for more information about channels](https://seldaek.github.io/monolog/doc/01-usage.html#leveraging-channels)).
|
| 44 |
-
|
| 45 |
-
So the code below will log a **debug** to the **default** channel with a source of **ea_client**:
|
| 46 |
-
|
| 47 |
-
```php
|
| 48 |
-
<?php
|
| 49 |
-
do_action(
|
| 50 |
-
'tribe_log',
|
| 51 |
-
'debug',
|
| 52 |
-
'ea_client',
|
| 53 |
-
[ 'action' => 'updated', 'post_id' => $id, 'origin' => $origin ]
|
| 54 |
-
);
|
| 55 |
-
```
|
| 56 |
-
|
| 57 |
-
The logger listening on the action will consume three parameters:
|
| 58 |
-
|
| 59 |
-
1. `level` - `debug` in the example; is the level of the log; available levels, in increasing value of urgency are: `debug`, `info`, `notice`, `warning`, `error`, `critical`, `alert`, `emergency`. Use each level wisely.
|
| 60 |
-
2. `source` - `ea_client` in this example; is the source of the log; this is a human-readable value; consistency is king here.
|
| 61 |
-
3. `context` - the array in this example; this is an associative array that will be logged to define the context of the log. Think of this as something that will provide the details required to unpack what **was** happening when the log entry was created. Provide enough context to make it clear, but avoid bloating it.
|
| 62 |
-
|
| 63 |
-
## Where are my logs?
|
| 64 |
-
|
| 65 |
-
The initial implementation of the new logger will write, by default, to the **PHP error** log.
|
| 66 |
-
|
| 67 |
-
We're using Monolog to allow us, and third parties, to "attach" and "deatach" loggers as required.
|
| 68 |
-
By default we're formatting logs using canonical lines( read more [here](https://brandur.org/logfmt) and [here](https://blog.codeship.com/logfmt-a-log-format-thats-easy-to-read-and-write/)) to make our log entries both human-readable and machine parsable (e.g. by a tool like [this](https://www.npmjs.com/package/logfmt)).
|
| 69 |
-
|
| 70 |
-
The output format of the example above would be this:
|
| 71 |
-
|
| 72 |
-
```
|
| 73 |
-
[22-Aug-2019 15:50:42 UTC] tribe-canonical-line channel=default level=debug source=ea_client action=updated post_id=23 origin=ical
|
| 74 |
-
```
|
| 75 |
-
|
| 76 |
-
What about legacy logs?
|
| 77 |
-
Their format would not be formatted to the canonical line style:
|
| 78 |
-
|
| 79 |
-
```
|
| 80 |
-
[22-Aug-2019 16:03:33 UTC] tribe.default.DEBUG: The source: debug information
|
| 81 |
-
```
|
| 82 |
-
|
| 83 |
-
### Logging levels ( or "stuff does not appear in the log")
|
| 84 |
-
|
| 85 |
-
By default we're only logging Warnings and above.
|
| 86 |
-
This means all your `debug` level logs are being ignored.
|
| 87 |
-
|
| 88 |
-
In production we do not want to fill people logs with pointless information, but you can control the level of logging: any log equal or above the specified level will be logged.
|
| 89 |
-
|
| 90 |
-
You can control the logging level with the `tribe_log_level` filter:
|
| 91 |
-
|
| 92 |
-
```php
|
| 93 |
-
<?php
|
| 94 |
-
add_filter(
|
| 95 |
-
'tribe_log_level',
|
| 96 |
-
static function () {
|
| 97 |
-
// Only log errors or above.
|
| 98 |
-
return Monolog\Logger::ERROR;
|
| 99 |
-
}
|
| 100 |
-
);
|
| 101 |
-
```
|
| 102 |
-
|
| 103 |
-
### Logging channels
|
| 104 |
-
|
| 105 |
-
The default logging channel is `default`, you've seen that in the example log lines above.
|
| 106 |
-
|
| 107 |
-
But how can I change the channel?
|
| 108 |
-
|
| 109 |
-
Easy:
|
| 110 |
-
|
| 111 |
-
```php
|
| 112 |
-
<?php
|
| 113 |
-
tribe( 'monolog' )->set_global_channel( 'my_channel' );
|
| 114 |
-
do_action( 'tribe_log', 'debug', 'my_source', [ 'foo' => 'bar' ] );
|
| 115 |
-
tribe( 'logger' )->log_debug( 'Some debug information', 'My source' );
|
| 116 |
-
```
|
| 117 |
-
|
| 118 |
-
You can do the same using the legacy logger, [if enabled][0527-0003]:
|
| 119 |
-
|
| 120 |
-
```php
|
| 121 |
-
<?php
|
| 122 |
-
tribe( 'logger' )->use_log( 'my_channel' );
|
| 123 |
-
```
|
| 124 |
-
|
| 125 |
-
Any log produced after the call will log to the `my_channel` channel; this will apply to the legacy logger too ([if redirected][0527-0003]):
|
| 126 |
-
|
| 127 |
-
```
|
| 128 |
-
[22-Aug-2019 15:50:42 UTC] tribe-canonical-line channel=default level=debug source=ea_client action=updated post_id=23 origin=ical
|
| 129 |
-
[22-Aug-2019 15:51:13 UTC] tribe-canonical-line channel=my_channel level=debug source=my_source foo=bar
|
| 130 |
-
[22-Aug-2019 16:03:33 UTC] tribe.my_channel.DEBUG: My source: Some debug information
|
| 131 |
-
```
|
| 132 |
-
|
| 133 |
-
## I want to use this right now to debug my code
|
| 134 |
-
|
| 135 |
-
Copy and paste this in a plugin, or must-use plugin.
|
| 136 |
-
If you're using a plugin remember to activate it.
|
| 137 |
-
|
| 138 |
-
```php
|
| 139 |
-
<?php
|
| 140 |
-
/**
|
| 141 |
-
* Plugin Name: Modern Tribe Logger Control
|
| 142 |
-
* Plugin Description: Control the behavior of Modern Tribe Monolog-based logger.
|
| 143 |
-
*/
|
| 144 |
-
add_filter(
|
| 145 |
-
'tribe_log_level',
|
| 146 |
-
static function () {
|
| 147 |
-
// Control the min level of logging.
|
| 148 |
-
return Monolog\Logger::DEBUG;
|
| 149 |
-
}
|
| 150 |
-
);
|
| 151 |
-
|
| 152 |
-
// Redirect legacy logger calls.
|
| 153 |
-
add_filter( 'tribe_log_use_action_logger', '__return_true' );
|
| 154 |
-
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
common/src/Tribe/Log/Service_Provider.php
DELETED
|
@@ -1,148 +0,0 @@
|
|
| 1 |
-
<?php
|
| 2 |
-
/**
|
| 3 |
-
* ${CARET}
|
| 4 |
-
*
|
| 5 |
-
* @since 4.9.16
|
| 6 |
-
*
|
| 7 |
-
* @package Tribe\Log
|
| 8 |
-
*/
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
namespace Tribe\Log;
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
use Monolog\Handler\ErrorLogHandler;
|
| 15 |
-
use Monolog\Logger;
|
| 16 |
-
|
| 17 |
-
class Service_Provider extends \tad_DI52_ServiceProvider {
|
| 18 |
-
|
| 19 |
-
/**
|
| 20 |
-
* Binds and sets up implementations.
|
| 21 |
-
*
|
| 22 |
-
* @since 4.9.16
|
| 23 |
-
*/
|
| 24 |
-
public function register() {
|
| 25 |
-
$this->container->singleton( Logger::class, [ $this, 'build_logger' ] );
|
| 26 |
-
$this->container->singleton( 'monolog',
|
| 27 |
-
function () {
|
| 28 |
-
return $this->container->make( Logger::class );
|
| 29 |
-
}
|
| 30 |
-
);
|
| 31 |
-
|
| 32 |
-
add_action( 'tribe_log', [ $this, 'dispatch_log' ], 10, 3 );
|
| 33 |
-
|
| 34 |
-
/**
|
| 35 |
-
* Filters whether to make the Action Logger available as logger or not.
|
| 36 |
-
*
|
| 37 |
-
* @since 4.9.16
|
| 38 |
-
*
|
| 39 |
-
* @param bool $use_action_logger Whether to allow logging messages from the \Tribe\Log\Logger class using the
|
| 40 |
-
* `tribe_log` action or not.
|
| 41 |
-
*/
|
| 42 |
-
$use_action_logger = apply_filters( 'tribe_log_use_action_logger', false );
|
| 43 |
-
|
| 44 |
-
if ( $use_action_logger ) {
|
| 45 |
-
add_filter( 'tribe_common_logging_engines', [ $this, 'add_logging_engine' ] );
|
| 46 |
-
}
|
| 47 |
-
}
|
| 48 |
-
|
| 49 |
-
/**
|
| 50 |
-
* Builds and returns the Monolog Logger instance that will listen to the `tribe_log` action.
|
| 51 |
-
*
|
| 52 |
-
* To avoid the over-head introduced by filtering the filters are applied here, only once, when the instance is
|
| 53 |
-
* first built. Any later call will use the singleton instance stored in the container.
|
| 54 |
-
*
|
| 55 |
-
* @since 4.9.16
|
| 56 |
-
*
|
| 57 |
-
* @return Logger
|
| 58 |
-
*/
|
| 59 |
-
public function build_logger() {
|
| 60 |
-
/**
|
| 61 |
-
* Filters the level of the messages that will be logged.
|
| 62 |
-
*
|
| 63 |
-
* The threshold is inclusive of the level; it default to log any warning and above.
|
| 64 |
-
*
|
| 65 |
-
* @since 4.9.16
|
| 66 |
-
*
|
| 67 |
-
* @param int The threshold level; if the level of a message is this level or above, then it will be logged.
|
| 68 |
-
*
|
| 69 |
-
* @see \Monolog\Logger for possible levels.
|
| 70 |
-
*/
|
| 71 |
-
$level_threshold = apply_filters( 'tribe_log_level', Logger::WARNING );
|
| 72 |
-
|
| 73 |
-
$error_log_handler = new ErrorLogHandler( null, $level_threshold );
|
| 74 |
-
|
| 75 |
-
/**
|
| 76 |
-
* Filters whether to use canonical format for the logs or not.
|
| 77 |
-
*
|
| 78 |
-
* @since 4.9.16
|
| 79 |
-
*
|
| 80 |
-
* @param bool $use_canonical_format Whether to use canonical format for the logs or not; defaults to `true`.
|
| 81 |
-
*/
|
| 82 |
-
$use_canonical_format = apply_filters( 'tribe_log_canonical', true );
|
| 83 |
-
|
| 84 |
-
if ( $use_canonical_format ) {
|
| 85 |
-
$error_log_handler->setFormatter( new Canonical_Formatter() );
|
| 86 |
-
}
|
| 87 |
-
|
| 88 |
-
$handlers = [
|
| 89 |
-
'default' => $error_log_handler
|
| 90 |
-
];
|
| 91 |
-
|
| 92 |
-
/**
|
| 93 |
-
* Filters the list of handlers that will handle dispatched log messages.
|
| 94 |
-
*
|
| 95 |
-
* All handlers should implement the `\Monolog\Handler\HandlerInterface`.
|
| 96 |
-
*
|
| 97 |
-
* @since 4.9.16
|
| 98 |
-
*
|
| 99 |
-
* @param array $handlers An array of default log handlers.
|
| 100 |
-
*/
|
| 101 |
-
$handlers = apply_filters( 'tribe_log_handlers', $handlers );
|
| 102 |
-
|
| 103 |
-
// Monolog will log to stderr when no handlers are set.
|
| 104 |
-
$logger = new Monolog_Logger( Monolog_Logger::DEFAULT_CHANNEL );
|
| 105 |
-
|
| 106 |
-
$logger->setHandlers( $handlers );
|
| 107 |
-
|
| 108 |
-
return $logger;
|
| 109 |
-
}
|
| 110 |
-
|
| 111 |
-
/**
|
| 112 |
-
* Dispatch a message of a specific level.
|
| 113 |
-
*
|
| 114 |
-
* Available levels are: `debug`, `info`, `notice`, `warning`, `error`, `critical`, `alert`, `emergency`.
|
| 115 |
-
*
|
| 116 |
-
* @since 4.9.16
|
| 117 |
-
*
|
| 118 |
-
* @param string|int $level Either the log level or the log pretty name, see long description.
|
| 119 |
-
* @param string $message The message to log.
|
| 120 |
-
* @param array $context An array of values to define the context.
|
| 121 |
-
*
|
| 122 |
-
* @see \Monolog\Logger for the log level constants and names.
|
| 123 |
-
*/
|
| 124 |
-
public function dispatch_log( $level = 'debug', $message = '', array $context = [] ) {
|
| 125 |
-
// Goes from something like `debug` to `100`.
|
| 126 |
-
$level = is_numeric( $level ) ? $level : Logger::toMonologLevel( $level );
|
| 127 |
-
|
| 128 |
-
/** @var Logger $logger */
|
| 129 |
-
$logger = $this->container->make( Logger::class );
|
| 130 |
-
|
| 131 |
-
$logger->log( $level, $message, $context );
|
| 132 |
-
}
|
| 133 |
-
|
| 134 |
-
/**
|
| 135 |
-
* Makes the action-based logging engine available in the backend.
|
| 136 |
-
*
|
| 137 |
-
* @since 4.9.16
|
| 138 |
-
*
|
| 139 |
-
* @param array $logging_engines An array of available logging engines.
|
| 140 |
-
*
|
| 141 |
-
* @return array The updated array of logging engines.
|
| 142 |
-
*/
|
| 143 |
-
public function add_logging_engine( array $logging_engines = [] ) {
|
| 144 |
-
$logging_engines[ Action_Logger::class ] = new Action_Logger();
|
| 145 |
-
|
| 146 |
-
return $logging_engines;
|
| 147 |
-
}
|
| 148 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
common/src/Tribe/Main.php
CHANGED
|
@@ -17,7 +17,7 @@ class Tribe__Main {
|
|
| 17 |
const OPTIONNAME = 'tribe_events_calendar_options';
|
| 18 |
const OPTIONNAMENETWORK = 'tribe_events_calendar_network_options';
|
| 19 |
|
| 20 |
-
const VERSION = '4.
|
| 21 |
|
| 22 |
const FEED_URL = 'https://theeventscalendar.com/feed/';
|
| 23 |
|
|
@@ -55,6 +55,7 @@ class Tribe__Main {
|
|
| 55 |
/**
|
| 56 |
* Constructor for Common Class
|
| 57 |
*
|
|
|
|
| 58 |
* We are using a `public` constructor here for backwards compatibility.
|
| 59 |
*
|
| 60 |
* The way our code used to work we would have `new Tribe__Main()` called directly
|
|
@@ -85,10 +86,8 @@ class Tribe__Main {
|
|
| 85 |
$parent_plugin_dir = trailingslashit( plugin_basename( $this->plugin_path ) );
|
| 86 |
$this->plugin_url = plugins_url( $parent_plugin_dir === $this->plugin_dir ? $this->plugin_dir : $parent_plugin_dir );
|
| 87 |
|
| 88 |
-
$this
|
| 89 |
-
|
| 90 |
-
add_action( 'plugins_loaded', [ $this, 'plugins_loaded' ], 1 );
|
| 91 |
-
add_action( 'tribe_common_loaded', [ $this, 'tribe_common_app_store' ], 10 );
|
| 92 |
}
|
| 93 |
|
| 94 |
/**
|
|
@@ -96,6 +95,8 @@ class Tribe__Main {
|
|
| 96 |
*/
|
| 97 |
public function plugins_loaded() {
|
| 98 |
|
|
|
|
|
|
|
| 99 |
$this->init_autoloading();
|
| 100 |
|
| 101 |
$this->bind_implementations();
|
|
@@ -127,7 +128,7 @@ class Tribe__Main {
|
|
| 127 |
|
| 128 |
$autoloader = Tribe__Autoloader::instance();
|
| 129 |
|
| 130 |
-
$prefixes =
|
| 131 |
$autoloader->register_prefixes( $prefixes );
|
| 132 |
|
| 133 |
foreach ( glob( $this->plugin_path . 'src/deprecated/*.php' ) as $file ) {
|
|
@@ -167,7 +168,6 @@ class Tribe__Main {
|
|
| 167 |
require_once $this->plugin_path . 'src/functions/template-tags/general.php';
|
| 168 |
require_once $this->plugin_path . 'src/functions/template-tags/date.php';
|
| 169 |
require_once $this->plugin_path . 'src/functions/template-tags/html.php';
|
| 170 |
-
require_once $this->plugin_path . 'src/functions/template-tags/post.php';
|
| 171 |
|
| 172 |
Tribe__Debug::instance();
|
| 173 |
tribe( 'assets' );
|
|
@@ -192,8 +192,8 @@ class Tribe__Main {
|
|
| 192 |
[ 'tribe-query-string', 'utils/query-string.js' ],
|
| 193 |
[ 'tribe-clipboard', 'vendor/clipboard/clipboard.js' ],
|
| 194 |
[ 'datatables', 'vendor/datatables/datatables.js', [ 'jquery' ] ],
|
| 195 |
-
[ 'tribe-select2', 'vendor/tribe-
|
| 196 |
-
[ 'tribe-select2-css', 'vendor/tribe-
|
| 197 |
[ 'tribe-utils-camelcase', 'utils-camelcase.js', [ 'underscore' ] ],
|
| 198 |
[ 'tribe-moment', 'vendor/momentjs/moment.js' ],
|
| 199 |
[ 'tribe-tooltipster', 'vendor/tooltipster/tooltipster.bundle.js', [ 'jquery' ] ],
|
|
@@ -214,8 +214,8 @@ class Tribe__Main {
|
|
| 214 |
tribe_assets(
|
| 215 |
$this,
|
| 216 |
[
|
| 217 |
-
[ 'tribe-
|
| 218 |
-
[ 'tribe-common-
|
| 219 |
],
|
| 220 |
null
|
| 221 |
);
|
|
@@ -223,22 +223,21 @@ class Tribe__Main {
|
|
| 223 |
// These ones will be enqueued on `admin_enqueue_scripts` if the conditional method on filter is met
|
| 224 |
tribe_assets(
|
| 225 |
$this,
|
| 226 |
-
|
| 227 |
-
|
| 228 |
-
|
| 229 |
-
|
| 230 |
-
|
| 231 |
-
|
| 232 |
-
|
| 233 |
-
|
| 234 |
-
|
| 235 |
-
|
| 236 |
-
],
|
| 237 |
'admin_enqueue_scripts',
|
| 238 |
-
|
| 239 |
-
'conditionals' =>
|
| 240 |
'priority' => 5,
|
| 241 |
-
|
| 242 |
);
|
| 243 |
|
| 244 |
tribe_asset(
|
|
@@ -260,44 +259,13 @@ class Tribe__Main {
|
|
| 260 |
'admin_enqueue_scripts',
|
| 261 |
[
|
| 262 |
'conditionals' => [ $this, 'should_load_common_admin_css' ],
|
| 263 |
-
'priority'
|
| 264 |
]
|
| 265 |
);
|
| 266 |
|
| 267 |
tribe( Tribe__Admin__Help_Page::class )->register_assets();
|
| 268 |
}
|
| 269 |
|
| 270 |
-
/**
|
| 271 |
-
* Load Common's text domain, then fire the hook for other plugins to do the same.
|
| 272 |
-
*
|
| 273 |
-
* Make sure this fires on 'init', per WordPress best practices.
|
| 274 |
-
*
|
| 275 |
-
* @since 4.12.0
|
| 276 |
-
*
|
| 277 |
-
* @return bool
|
| 278 |
-
*/
|
| 279 |
-
public function hook_load_text_domain() {
|
| 280 |
-
$loaded = $this->load_text_domain(
|
| 281 |
-
'tribe-common',
|
| 282 |
-
basename( dirname( dirname( dirname( dirname( __FILE__ ) ) ) ) ) . '/common/lang/'
|
| 283 |
-
);
|
| 284 |
-
|
| 285 |
-
/**
|
| 286 |
-
* After attempting (hopefully successfully) to load Common's text domain.
|
| 287 |
-
*
|
| 288 |
-
* Load other plugin text domains on this hook, but make sure they're setup on this hook prior to 'init'.
|
| 289 |
-
*
|
| 290 |
-
* @since 4.12.0
|
| 291 |
-
*
|
| 292 |
-
* @param bool $loaded Whether or not Common's text domain was loaded.
|
| 293 |
-
*
|
| 294 |
-
* @return bool
|
| 295 |
-
*/
|
| 296 |
-
do_action( 'tribe_load_text_domains', $loaded );
|
| 297 |
-
|
| 298 |
-
return $loaded;
|
| 299 |
-
}
|
| 300 |
-
|
| 301 |
/**
|
| 302 |
* Load All localization data create by `asset.data`
|
| 303 |
*
|
|
@@ -308,11 +276,11 @@ class Tribe__Main {
|
|
| 308 |
public function load_localize_data() {
|
| 309 |
$datepicker_months = array_values( Tribe__Date_Utils::get_localized_months_full() );
|
| 310 |
|
| 311 |
-
tribe( 'asset.data' )->add( 'tribe_l10n_datatables',
|
| 312 |
-
'aria' =>
|
| 313 |
'sort_ascending' => __( ': activate to sort column ascending', 'tribe-common' ),
|
| 314 |
'sort_descending' => __( ': activate to sort column descending', 'tribe-common' ),
|
| 315 |
-
|
| 316 |
'length_menu' => __( 'Show _MENU_ entries', 'tribe-common' ),
|
| 317 |
'empty_table' => __( 'No data available in table', 'tribe-common' ),
|
| 318 |
'info' => __( 'Showing _START_ to _END_ of _TOTAL_ entries', 'tribe-common' ),
|
|
@@ -323,19 +291,19 @@ class Tribe__Main {
|
|
| 323 |
'all_selected_text' => __( 'All items on this page were selected. ', 'tribe-common' ),
|
| 324 |
'select_all_link' => __( 'Select all pages', 'tribe-common' ),
|
| 325 |
'clear_selection' => __( 'Clear Selection.', 'tribe-common' ),
|
| 326 |
-
'pagination' =>
|
| 327 |
'all' => __( 'All', 'tribe-common' ),
|
| 328 |
'next' => __( 'Next', 'tribe-common' ),
|
| 329 |
'previous' => __( 'Previous', 'tribe-common' ),
|
| 330 |
-
|
| 331 |
-
'select' =>
|
| 332 |
-
'rows' =>
|
| 333 |
0 => '',
|
| 334 |
'_' => __( ': Selected %d rows', 'tribe-common' ),
|
| 335 |
1 => __( ': Selected 1 row', 'tribe-common' ),
|
| 336 |
-
|
| 337 |
-
|
| 338 |
-
'datepicker' =>
|
| 339 |
'dayNames' => Tribe__Date_Utils::get_localized_weekdays_full(),
|
| 340 |
'dayNamesShort' => Tribe__Date_Utils::get_localized_weekdays_short(),
|
| 341 |
'dayNamesMin' => Tribe__Date_Utils::get_localized_weekdays_initial(),
|
|
@@ -348,38 +316,28 @@ class Tribe__Main {
|
|
| 348 |
'closeText' => esc_html__( 'Done', 'the-events-calendar' ),
|
| 349 |
'today' => esc_html__( 'Today', 'the-events-calendar' ),
|
| 350 |
'clear' => esc_html__( 'Clear', 'the-events-calendar' ),
|
| 351 |
-
|
| 352 |
-
|
| 353 |
}
|
| 354 |
|
| 355 |
/**
|
| 356 |
* Adds core hooks
|
| 357 |
*/
|
| 358 |
public function add_hooks() {
|
| 359 |
-
add_action( 'plugins_loaded',
|
| 360 |
-
add_action( 'plugins_loaded',
|
| 361 |
|
| 362 |
// Register for the assets to be available everywhere
|
| 363 |
-
add_action( 'tribe_common_loaded',
|
| 364 |
-
add_action( 'init',
|
| 365 |
-
add_action( '
|
| 366 |
-
add_action( '
|
| 367 |
-
|
| 368 |
-
|
| 369 |
-
|
| 370 |
-
add_action( 'wp_footer', [ $this, 'toggle_js_class' ] );
|
| 371 |
}
|
| 372 |
|
| 373 |
-
|
| 374 |
-
* Adds `tribe-no-js` class to all pages when common is active.
|
| 375 |
-
*
|
| 376 |
-
* @since 4.3.4
|
| 377 |
-
*
|
| 378 |
-
* @param array|string $classes Previous classes on body.
|
| 379 |
-
*
|
| 380 |
-
* @return array All classes that will be printed on `<body>`.
|
| 381 |
-
*/
|
| 382 |
-
public function add_js_class( $classes = [] ) {
|
| 383 |
if ( ! is_array( $classes ) ) {
|
| 384 |
$classes = explode( ' ', $classes );
|
| 385 |
}
|
|
@@ -389,13 +347,6 @@ class Tribe__Main {
|
|
| 389 |
return array_filter( array_unique( $classes ) );
|
| 390 |
}
|
| 391 |
|
| 392 |
-
/**
|
| 393 |
-
* Removes `tribe-no-js` and replaces with `tribe-js` when the Javascript of the page is enabled.
|
| 394 |
-
*
|
| 395 |
-
* @since 4.3.4
|
| 396 |
-
*
|
| 397 |
-
* @return void This method only prints HTML to the screen no return.
|
| 398 |
-
*/
|
| 399 |
public function toggle_js_class() {
|
| 400 |
?>
|
| 401 |
<script>
|
|
@@ -415,7 +366,7 @@ class Tribe__Main {
|
|
| 415 |
*
|
| 416 |
* @since 4.5.7
|
| 417 |
*
|
| 418 |
-
* @return bool
|
| 419 |
*/
|
| 420 |
public function should_load_common_admin_css() {
|
| 421 |
$helper = Tribe__Admin__Helpers::instance();
|
|
@@ -435,15 +386,13 @@ class Tribe__Main {
|
|
| 435 |
|
| 436 |
/**
|
| 437 |
* A Helper method to load text domain
|
| 438 |
-
* First it tries to load the wp-content/languages translation then if falls to the
|
| 439 |
-
*
|
| 440 |
-
* @since 4.0.1 Introduced.
|
| 441 |
-
* @since 4.2 Included $domain and $dir params.
|
| 442 |
*
|
| 443 |
-
* @param string
|
| 444 |
-
* @param string
|
| 445 |
*
|
| 446 |
-
* @return bool If it was able to load the text domain
|
| 447 |
*/
|
| 448 |
public function load_text_domain( $domain, $dir = false ) {
|
| 449 |
// Added safety just in case this runs twice...
|
|
@@ -455,13 +404,13 @@ class Tribe__Main {
|
|
| 455 |
$plugin_rel_path = WP_LANG_DIR . '/plugins/';
|
| 456 |
|
| 457 |
/**
|
| 458 |
-
* Allows users to filter the file location for a given text domain
|
| 459 |
* Be careful when using this filter, it will apply across the whole plugin suite.
|
| 460 |
*
|
| 461 |
-
* @param string $plugin_rel_path The relative path for the language files
|
| 462 |
-
* @param string $domain Which plugin domain we are trying to load
|
| 463 |
-
* @param string $locale Which Language we will load
|
| 464 |
-
* @param string|bool $dir If there was a custom directory passed on the method call
|
| 465 |
*/
|
| 466 |
$plugin_rel_path = apply_filters( 'tribe_load_text_domain', $plugin_rel_path, $domain, $locale, $dir );
|
| 467 |
|
|
@@ -475,21 +424,11 @@ class Tribe__Main {
|
|
| 475 |
}
|
| 476 |
|
| 477 |
/**
|
| 478 |
-
* Returns the post types registered by Tribe plugins
|
| 479 |
-
*
|
| 480 |
-
* @since 4.0.1 Introduced the method.
|
| 481 |
-
*
|
| 482 |
-
* @return array Slugs for all Post Types registered.
|
| 483 |
*/
|
| 484 |
public static function get_post_types() {
|
| 485 |
-
|
| 486 |
-
|
| 487 |
-
*
|
| 488 |
-
* @since 4.0.1
|
| 489 |
-
*
|
| 490 |
-
* @param array Slugs for all Post Types registered.
|
| 491 |
-
*/
|
| 492 |
-
return apply_filters( 'tribe_post_types', [] );
|
| 493 |
}
|
| 494 |
|
| 495 |
/**
|
|
@@ -500,6 +439,7 @@ class Tribe__Main {
|
|
| 500 |
* @param $insert_array
|
| 501 |
*
|
| 502 |
* @return array
|
|
|
|
| 503 |
*/
|
| 504 |
public static function array_insert_after_key( $key, $source_array, $insert_array ) {
|
| 505 |
if ( array_key_exists( $key, $source_array ) ) {
|
|
@@ -551,6 +491,26 @@ class Tribe__Main {
|
|
| 551 |
return $candidate_post instanceof WP_Post ? $candidate_post->ID : false;
|
| 552 |
}
|
| 553 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 554 |
/**
|
| 555 |
* Adds a hook
|
| 556 |
*
|
|
@@ -568,7 +528,6 @@ class Tribe__Main {
|
|
| 568 |
*/
|
| 569 |
public function tribe_plugins_loaded() {
|
| 570 |
tribe( 'admin.notice.php.version' );
|
| 571 |
-
tribe( 'cache' );
|
| 572 |
tribe_singleton( 'feature-detection', 'Tribe__Feature_Detection' );
|
| 573 |
tribe_register_provider( 'Tribe__Service_Providers__Processes' );
|
| 574 |
|
|
@@ -586,26 +545,22 @@ class Tribe__Main {
|
|
| 586 |
|
| 587 |
/**
|
| 588 |
* Registers the slug bound to the implementations in the container.
|
| 589 |
-
*
|
| 590 |
-
* @since 4.4
|
| 591 |
-
*
|
| 592 |
-
* @return void Implementation of components loader doesnt return anything.
|
| 593 |
*/
|
| 594 |
public function bind_implementations() {
|
| 595 |
tribe_singleton( 'settings.manager', 'Tribe__Settings_Manager' );
|
| 596 |
-
tribe_singleton( 'settings', 'Tribe__Settings',
|
| 597 |
-
tribe_singleton( 'ajax.dropdown', 'Tribe__Ajax__Dropdown',
|
| 598 |
tribe_singleton( 'assets', 'Tribe__Assets' );
|
| 599 |
-
tribe_singleton( 'assets.pipeline', 'Tribe__Assets_Pipeline',
|
| 600 |
-
tribe_singleton( 'asset.data', 'Tribe__Asset__Data',
|
| 601 |
tribe_singleton( 'admin.helpers', 'Tribe__Admin__Helpers' );
|
| 602 |
-
tribe_singleton( 'tracker', 'Tribe__Tracker',
|
| 603 |
-
tribe_singleton( 'chunker', 'Tribe__Meta__Chunker',
|
| 604 |
-
tribe_singleton( 'cache', 'Tribe__Cache'
|
| 605 |
tribe_singleton( 'languages.locations', 'Tribe__Languages__Locations' );
|
| 606 |
tribe_singleton( 'plugins.api', new Tribe__Plugins_API );
|
| 607 |
tribe_singleton( 'logger', 'Tribe__Log' );
|
| 608 |
-
tribe_singleton( 'cost-utils',
|
| 609 |
tribe_singleton( 'post-duplicate.strategy-factory', 'Tribe__Duplicate__Strategy_Factory' );
|
| 610 |
tribe_singleton( 'post-duplicate', 'Tribe__Duplicate__Post' );
|
| 611 |
tribe_singleton( 'context', 'Tribe__Context' );
|
|
@@ -620,38 +575,17 @@ class Tribe__Main {
|
|
| 620 |
|
| 621 |
tribe_singleton( Tribe__Admin__Help_Page::class, Tribe__Admin__Help_Page::class );
|
| 622 |
|
| 623 |
-
tribe_singleton( 'admin.notice.php.version', 'Tribe__Admin__Notice__Php_Version',
|
| 624 |
-
tribe_singleton( 'admin.notice.marketing', 'Tribe__Admin__Notice__Marketing',
|
| 625 |
|
| 626 |
tribe_register_provider( Tribe__Editor__Provider::class );
|
| 627 |
tribe_register_provider( Tribe__Service_Providers__Debug_Bar::class );
|
| 628 |
-
tribe_register_provider(
|
| 629 |
-
tribe_register_provider(
|
| 630 |
-
tribe_register_provider( Tribe\Service_Providers\Dialog::class );
|
| 631 |
-
tribe_register_provider( Tribe\Service_Providers\PUE::class );
|
| 632 |
-
tribe_register_provider( Tribe\Service_Providers\Shortcodes::class );
|
| 633 |
-
tribe_register_provider( Tribe\Log\Service_Provider::class );
|
| 634 |
-
}
|
| 635 |
|
| 636 |
-
|
| 637 |
-
* Create the Promoter connector singleton early to allow hook into the filters early.
|
| 638 |
-
*
|
| 639 |
-
* Add a filter to determine_current_user during the setup of common library.
|
| 640 |
-
*
|
| 641 |
-
* @since 4.9.20
|
| 642 |
-
*
|
| 643 |
-
* @return void Internal method without any return.
|
| 644 |
-
*/
|
| 645 |
-
public function promoter_connector() {
|
| 646 |
-
tribe_singleton( 'promoter.connector', 'Tribe__Promoter__Connector' );
|
| 647 |
-
|
| 648 |
-
add_filter(
|
| 649 |
-
'determine_current_user',
|
| 650 |
-
tribe_callback( 'promoter.connector', 'authenticate_user_with_connector' )
|
| 651 |
-
);
|
| 652 |
}
|
| 653 |
|
| 654 |
-
|
| 655 |
/************************
|
| 656 |
* *
|
| 657 |
* Deprecated Methods *
|
|
@@ -659,26 +593,6 @@ class Tribe__Main {
|
|
| 659 |
************************/
|
| 660 |
// @codingStandardsIgnoreStart
|
| 661 |
|
| 662 |
-
/**
|
| 663 |
-
* Helper function to indicate whether the current execution context is AJAX
|
| 664 |
-
*
|
| 665 |
-
* This method exists to allow us test code that behaves differently depending on the execution
|
| 666 |
-
* context.
|
| 667 |
-
*
|
| 668 |
-
* @since 4.0
|
| 669 |
-
*
|
| 670 |
-
* @todo Add warning with '_deprecated_function'
|
| 671 |
-
*
|
| 672 |
-
* @param bool $doing_ajax An injectable status to override the `DOING_AJAX` check.
|
| 673 |
-
*
|
| 674 |
-
* @deprecated 4.7.12
|
| 675 |
-
*
|
| 676 |
-
* @return boolean
|
| 677 |
-
*/
|
| 678 |
-
public function doing_ajax( $doing_ajax = null ) {
|
| 679 |
-
return tribe( 'context' )->doing_ajax( $doing_ajax );
|
| 680 |
-
}
|
| 681 |
-
|
| 682 |
/**
|
| 683 |
* Manages PUE license key notifications.
|
| 684 |
*
|
| 17 |
const OPTIONNAME = 'tribe_events_calendar_options';
|
| 18 |
const OPTIONNAMENETWORK = 'tribe_events_calendar_network_options';
|
| 19 |
|
| 20 |
+
const VERSION = '4.9.15.1';
|
| 21 |
|
| 22 |
const FEED_URL = 'https://theeventscalendar.com/feed/';
|
| 23 |
|
| 55 |
/**
|
| 56 |
* Constructor for Common Class
|
| 57 |
*
|
| 58 |
+
* @access public
|
| 59 |
* We are using a `public` constructor here for backwards compatibility.
|
| 60 |
*
|
| 61 |
* The way our code used to work we would have `new Tribe__Main()` called directly
|
| 86 |
$parent_plugin_dir = trailingslashit( plugin_basename( $this->plugin_path ) );
|
| 87 |
$this->plugin_url = plugins_url( $parent_plugin_dir === $this->plugin_dir ? $this->plugin_dir : $parent_plugin_dir );
|
| 88 |
|
| 89 |
+
add_action( 'plugins_loaded', array( $this, 'plugins_loaded' ), 1 );
|
| 90 |
+
add_action( 'tribe_common_loaded', array( $this, 'tribe_common_app_store' ), 10 );
|
|
|
|
|
|
|
| 91 |
}
|
| 92 |
|
| 93 |
/**
|
| 95 |
*/
|
| 96 |
public function plugins_loaded() {
|
| 97 |
|
| 98 |
+
$this->load_text_domain( 'tribe-common', basename( dirname( dirname( dirname( dirname( __FILE__ ) ) ) ) ) . '/common/lang/' );
|
| 99 |
+
|
| 100 |
$this->init_autoloading();
|
| 101 |
|
| 102 |
$this->bind_implementations();
|
| 128 |
|
| 129 |
$autoloader = Tribe__Autoloader::instance();
|
| 130 |
|
| 131 |
+
$prefixes = array( 'Tribe__' => dirname( __FILE__ ) );
|
| 132 |
$autoloader->register_prefixes( $prefixes );
|
| 133 |
|
| 134 |
foreach ( glob( $this->plugin_path . 'src/deprecated/*.php' ) as $file ) {
|
| 168 |
require_once $this->plugin_path . 'src/functions/template-tags/general.php';
|
| 169 |
require_once $this->plugin_path . 'src/functions/template-tags/date.php';
|
| 170 |
require_once $this->plugin_path . 'src/functions/template-tags/html.php';
|
|
|
|
| 171 |
|
| 172 |
Tribe__Debug::instance();
|
| 173 |
tribe( 'assets' );
|
| 192 |
[ 'tribe-query-string', 'utils/query-string.js' ],
|
| 193 |
[ 'tribe-clipboard', 'vendor/clipboard/clipboard.js' ],
|
| 194 |
[ 'datatables', 'vendor/datatables/datatables.js', [ 'jquery' ] ],
|
| 195 |
+
[ 'tribe-select2', 'vendor/tribe-select2/select2.js', [ 'jquery' ] ],
|
| 196 |
+
[ 'tribe-select2-css', 'vendor/tribe-select2/select2.css' ],
|
| 197 |
[ 'tribe-utils-camelcase', 'utils-camelcase.js', [ 'underscore' ] ],
|
| 198 |
[ 'tribe-moment', 'vendor/momentjs/moment.js' ],
|
| 199 |
[ 'tribe-tooltipster', 'vendor/tooltipster/tooltipster.bundle.js', [ 'jquery' ] ],
|
| 214 |
tribe_assets(
|
| 215 |
$this,
|
| 216 |
[
|
| 217 |
+
[ 'tribe-reset-style', 'reset.css' ],
|
| 218 |
+
[ 'tribe-common-style', 'common.css', [ 'tribe-reset-style' ] ],
|
| 219 |
],
|
| 220 |
null
|
| 221 |
);
|
| 223 |
// These ones will be enqueued on `admin_enqueue_scripts` if the conditional method on filter is met
|
| 224 |
tribe_assets(
|
| 225 |
$this,
|
| 226 |
+
array(
|
| 227 |
+
array( 'tribe-buttonset', 'buttonset.js', array( 'jquery', 'underscore' ) ),
|
| 228 |
+
array( 'tribe-common-admin', 'tribe-common-admin.css', array( 'tribe-dependency-style', 'tribe-bumpdown-css', 'tribe-buttonset-style', 'tribe-select2-css' ) ),
|
| 229 |
+
array( 'tribe-validation', 'validation.js', array( 'jquery', 'underscore', 'tribe-common', 'tribe-utils-camelcase', 'tribe-tooltipster' ) ),
|
| 230 |
+
array( 'tribe-validation-style', 'validation.css', array( 'tribe-tooltipster-css' ) ),
|
| 231 |
+
array( 'tribe-dependency', 'dependency.js', array( 'jquery', 'underscore', 'tribe-common' ) ),
|
| 232 |
+
array( 'tribe-dependency-style', 'dependency.css', array( 'tribe-select2-css' ) ),
|
| 233 |
+
array( 'tribe-pue-notices', 'pue-notices.js', array( 'jquery' ) ),
|
| 234 |
+
array( 'tribe-datepicker', 'datepicker.css' ),
|
| 235 |
+
),
|
|
|
|
| 236 |
'admin_enqueue_scripts',
|
| 237 |
+
array(
|
| 238 |
+
'conditionals' => array( $this, 'should_load_common_admin_css' ),
|
| 239 |
'priority' => 5,
|
| 240 |
+
)
|
| 241 |
);
|
| 242 |
|
| 243 |
tribe_asset(
|
| 259 |
'admin_enqueue_scripts',
|
| 260 |
[
|
| 261 |
'conditionals' => [ $this, 'should_load_common_admin_css' ],
|
| 262 |
+
'priority' => 5,
|
| 263 |
]
|
| 264 |
);
|
| 265 |
|
| 266 |
tribe( Tribe__Admin__Help_Page::class )->register_assets();
|
| 267 |
}
|
| 268 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 269 |
/**
|
| 270 |
* Load All localization data create by `asset.data`
|
| 271 |
*
|
| 276 |
public function load_localize_data() {
|
| 277 |
$datepicker_months = array_values( Tribe__Date_Utils::get_localized_months_full() );
|
| 278 |
|
| 279 |
+
tribe( 'asset.data' )->add( 'tribe_l10n_datatables', array(
|
| 280 |
+
'aria' => array(
|
| 281 |
'sort_ascending' => __( ': activate to sort column ascending', 'tribe-common' ),
|
| 282 |
'sort_descending' => __( ': activate to sort column descending', 'tribe-common' ),
|
| 283 |
+
),
|
| 284 |
'length_menu' => __( 'Show _MENU_ entries', 'tribe-common' ),
|
| 285 |
'empty_table' => __( 'No data available in table', 'tribe-common' ),
|
| 286 |
'info' => __( 'Showing _START_ to _END_ of _TOTAL_ entries', 'tribe-common' ),
|
| 291 |
'all_selected_text' => __( 'All items on this page were selected. ', 'tribe-common' ),
|
| 292 |
'select_all_link' => __( 'Select all pages', 'tribe-common' ),
|
| 293 |
'clear_selection' => __( 'Clear Selection.', 'tribe-common' ),
|
| 294 |
+
'pagination' => array(
|
| 295 |
'all' => __( 'All', 'tribe-common' ),
|
| 296 |
'next' => __( 'Next', 'tribe-common' ),
|
| 297 |
'previous' => __( 'Previous', 'tribe-common' ),
|
| 298 |
+
),
|
| 299 |
+
'select' => array(
|
| 300 |
+
'rows' => array(
|
| 301 |
0 => '',
|
| 302 |
'_' => __( ': Selected %d rows', 'tribe-common' ),
|
| 303 |
1 => __( ': Selected 1 row', 'tribe-common' ),
|
| 304 |
+
),
|
| 305 |
+
),
|
| 306 |
+
'datepicker' => array(
|
| 307 |
'dayNames' => Tribe__Date_Utils::get_localized_weekdays_full(),
|
| 308 |
'dayNamesShort' => Tribe__Date_Utils::get_localized_weekdays_short(),
|
| 309 |
'dayNamesMin' => Tribe__Date_Utils::get_localized_weekdays_initial(),
|
| 316 |
'closeText' => esc_html__( 'Done', 'the-events-calendar' ),
|
| 317 |
'today' => esc_html__( 'Today', 'the-events-calendar' ),
|
| 318 |
'clear' => esc_html__( 'Clear', 'the-events-calendar' ),
|
| 319 |
+
),
|
| 320 |
+
) );
|
| 321 |
}
|
| 322 |
|
| 323 |
/**
|
| 324 |
* Adds core hooks
|
| 325 |
*/
|
| 326 |
public function add_hooks() {
|
| 327 |
+
add_action( 'plugins_loaded', array( 'Tribe__App_Shop', 'instance' ) );
|
| 328 |
+
add_action( 'plugins_loaded', array( $this, 'tribe_plugins_loaded' ), PHP_INT_MAX );
|
| 329 |
|
| 330 |
// Register for the assets to be available everywhere
|
| 331 |
+
add_action( 'tribe_common_loaded', array( $this, 'load_assets' ), 1 );
|
| 332 |
+
add_action( 'init', array( $this, 'load_localize_data' ) );
|
| 333 |
+
add_action( 'plugins_loaded', array( 'Tribe__Admin__Notices', 'instance' ), 1 );
|
| 334 |
+
add_action( 'admin_enqueue_scripts', array( $this, 'store_admin_notices' ) );
|
| 335 |
+
|
| 336 |
+
add_filter( 'body_class', array( $this, 'add_js_class' ) );
|
| 337 |
+
add_action( 'wp_footer', array( $this, 'toggle_js_class' ) );
|
|
|
|
| 338 |
}
|
| 339 |
|
| 340 |
+
public function add_js_class( $classes = array() ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 341 |
if ( ! is_array( $classes ) ) {
|
| 342 |
$classes = explode( ' ', $classes );
|
| 343 |
}
|
| 347 |
return array_filter( array_unique( $classes ) );
|
| 348 |
}
|
| 349 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 350 |
public function toggle_js_class() {
|
| 351 |
?>
|
| 352 |
<script>
|
| 366 |
*
|
| 367 |
* @since 4.5.7
|
| 368 |
*
|
| 369 |
+
* @return bool
|
| 370 |
*/
|
| 371 |
public function should_load_common_admin_css() {
|
| 372 |
$helper = Tribe__Admin__Helpers::instance();
|
| 386 |
|
| 387 |
/**
|
| 388 |
* A Helper method to load text domain
|
| 389 |
+
* First it tries to load the wp-content/languages translation then if falls to the
|
| 390 |
+
* try to load $dir language files
|
|
|
|
|
|
|
| 391 |
*
|
| 392 |
+
* @param string $domain The text domain that will be loaded
|
| 393 |
+
* @param string $dir What directory should be used to try to load if the default doenst work
|
| 394 |
*
|
| 395 |
+
* @return bool If it was able to load the text domain
|
| 396 |
*/
|
| 397 |
public function load_text_domain( $domain, $dir = false ) {
|
| 398 |
// Added safety just in case this runs twice...
|
| 404 |
$plugin_rel_path = WP_LANG_DIR . '/plugins/';
|
| 405 |
|
| 406 |
/**
|
| 407 |
+
* Allows users to filter the file location for a given text domain
|
| 408 |
* Be careful when using this filter, it will apply across the whole plugin suite.
|
| 409 |
*
|
| 410 |
+
* @param string $plugin_rel_path The relative path for the language files
|
| 411 |
+
* @param string $domain Which plugin domain we are trying to load
|
| 412 |
+
* @param string $locale Which Language we will load
|
| 413 |
+
* @param string|bool $dir If there was a custom directory passed on the method call
|
| 414 |
*/
|
| 415 |
$plugin_rel_path = apply_filters( 'tribe_load_text_domain', $plugin_rel_path, $domain, $locale, $dir );
|
| 416 |
|
| 424 |
}
|
| 425 |
|
| 426 |
/**
|
| 427 |
+
* Returns the post types registered by Tribe plugins
|
|
|
|
|
|
|
|
|
|
|
|
|
| 428 |
*/
|
| 429 |
public static function get_post_types() {
|
| 430 |
+
// we default the post type array to empty in tribe-common. Plugins like TEC add to it
|
| 431 |
+
return apply_filters( 'tribe_post_types', array() );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 432 |
}
|
| 433 |
|
| 434 |
/**
|
| 439 |
* @param $insert_array
|
| 440 |
*
|
| 441 |
* @return array
|
| 442 |
+
*
|
| 443 |
*/
|
| 444 |
public static function array_insert_after_key( $key, $source_array, $insert_array ) {
|
| 445 |
if ( array_key_exists( $key, $source_array ) ) {
|
| 491 |
return $candidate_post instanceof WP_Post ? $candidate_post->ID : false;
|
| 492 |
}
|
| 493 |
|
| 494 |
+
/**
|
| 495 |
+
* Helper function to indicate whether the current execution context is AJAX
|
| 496 |
+
*
|
| 497 |
+
* This method exists to allow us test code that behaves differently depending on the execution
|
| 498 |
+
* context.
|
| 499 |
+
*
|
| 500 |
+
* @since 4.0
|
| 501 |
+
*
|
| 502 |
+
* @todo Add warning with '_deprecated_function'
|
| 503 |
+
*
|
| 504 |
+
* @param bool $doing_ajax An injectable status to override the `DOING_AJAX` check.
|
| 505 |
+
*
|
| 506 |
+
* @deprecated 4.7.12
|
| 507 |
+
*
|
| 508 |
+
* @return boolean
|
| 509 |
+
*/
|
| 510 |
+
public function doing_ajax( $doing_ajax = null ) {
|
| 511 |
+
return tribe( 'context' )->doing_ajax( $doing_ajax );
|
| 512 |
+
}
|
| 513 |
+
|
| 514 |
/**
|
| 515 |
* Adds a hook
|
| 516 |
*
|
| 528 |
*/
|
| 529 |
public function tribe_plugins_loaded() {
|
| 530 |
tribe( 'admin.notice.php.version' );
|
|
|
|
| 531 |
tribe_singleton( 'feature-detection', 'Tribe__Feature_Detection' );
|
| 532 |
tribe_register_provider( 'Tribe__Service_Providers__Processes' );
|
| 533 |
|
| 545 |
|
| 546 |
/**
|
| 547 |
* Registers the slug bound to the implementations in the container.
|
|
|
|
|
|
|
|
|
|
|
|
|
| 548 |
*/
|
| 549 |
public function bind_implementations() {
|
| 550 |
tribe_singleton( 'settings.manager', 'Tribe__Settings_Manager' );
|
| 551 |
+
tribe_singleton( 'settings', 'Tribe__Settings', array( 'hook' ) );
|
| 552 |
+
tribe_singleton( 'ajax.dropdown', 'Tribe__Ajax__Dropdown', array( 'hook' ) );
|
| 553 |
tribe_singleton( 'assets', 'Tribe__Assets' );
|
| 554 |
+
tribe_singleton( 'assets.pipeline', 'Tribe__Assets_Pipeline', array( 'hook' ) );
|
| 555 |
+
tribe_singleton( 'asset.data', 'Tribe__Asset__Data', array( 'hook' ) );
|
| 556 |
tribe_singleton( 'admin.helpers', 'Tribe__Admin__Helpers' );
|
| 557 |
+
tribe_singleton( 'tracker', 'Tribe__Tracker', array( 'hook' ) );
|
| 558 |
+
tribe_singleton( 'chunker', 'Tribe__Meta__Chunker', array( 'set_post_types', 'hook' ) );
|
| 559 |
+
tribe_singleton( 'cache', 'Tribe__Cache' );
|
| 560 |
tribe_singleton( 'languages.locations', 'Tribe__Languages__Locations' );
|
| 561 |
tribe_singleton( 'plugins.api', new Tribe__Plugins_API );
|
| 562 |
tribe_singleton( 'logger', 'Tribe__Log' );
|
| 563 |
+
tribe_singleton( 'cost-utils', array( 'Tribe__Cost_Utils', 'instance' ) );
|
| 564 |
tribe_singleton( 'post-duplicate.strategy-factory', 'Tribe__Duplicate__Strategy_Factory' );
|
| 565 |
tribe_singleton( 'post-duplicate', 'Tribe__Duplicate__Post' );
|
| 566 |
tribe_singleton( 'context', 'Tribe__Context' );
|
| 575 |
|
| 576 |
tribe_singleton( Tribe__Admin__Help_Page::class, Tribe__Admin__Help_Page::class );
|
| 577 |
|
| 578 |
+
tribe_singleton( 'admin.notice.php.version', 'Tribe__Admin__Notice__Php_Version', array( 'hook' ) );
|
| 579 |
+
tribe_singleton( 'admin.notice.marketing', 'Tribe__Admin__Notice__Marketing', array( 'hook' ) );
|
| 580 |
|
| 581 |
tribe_register_provider( Tribe__Editor__Provider::class );
|
| 582 |
tribe_register_provider( Tribe__Service_Providers__Debug_Bar::class );
|
| 583 |
+
tribe_register_provider( Tribe__Service_Providers__Promoter_Connector::class );
|
| 584 |
+
tribe_register_provider( Tribe__Service_Providers__Tooltip::class );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 585 |
|
| 586 |
+
tribe_register_provider( Tribe\Service_Providers\PUE::class );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 587 |
}
|
| 588 |
|
|
|
|
| 589 |
/************************
|
| 590 |
* *
|
| 591 |
* Deprecated Methods *
|
| 593 |
************************/
|
| 594 |
// @codingStandardsIgnoreStart
|
| 595 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 596 |
/**
|
| 597 |
* Manages PUE license key notifications.
|
| 598 |
*
|
common/src/Tribe/Models/Post_Types/Base.php
DELETED
|
@@ -1,206 +0,0 @@
|
|
| 1 |
-
<?php
|
| 2 |
-
/**
|
| 3 |
-
* The base, abstract, class modeling a post.
|
| 4 |
-
*
|
| 5 |
-
* @since 4.9.18
|
| 6 |
-
*
|
| 7 |
-
* @package Tribe\Models\Post_Types
|
| 8 |
-
*/
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
namespace Tribe\Models\Post_Types;
|
| 12 |
-
|
| 13 |
-
use Tribe__Cache as Cache;
|
| 14 |
-
use Tribe__Cache_Listener as Cache_Listener;
|
| 15 |
-
|
| 16 |
-
/**
|
| 17 |
-
* Class Base
|
| 18 |
-
*
|
| 19 |
-
* @since 4.9.18
|
| 20 |
-
*
|
| 21 |
-
* @package Tribe\Models\Post_Types
|
| 22 |
-
*/
|
| 23 |
-
abstract class Base {
|
| 24 |
-
/**
|
| 25 |
-
* The post object base for this post type instance.
|
| 26 |
-
*
|
| 27 |
-
* @since 4.9.18
|
| 28 |
-
*
|
| 29 |
-
* @var \WP_Post
|
| 30 |
-
*/
|
| 31 |
-
protected $post;
|
| 32 |
-
|
| 33 |
-
/**
|
| 34 |
-
* Builds, and returns, a post type model from a given post.
|
| 35 |
-
*
|
| 36 |
-
* @since 4.9.18
|
| 37 |
-
*
|
| 38 |
-
* @param \WP_Post|int $post The post ID or post object.
|
| 39 |
-
*
|
| 40 |
-
* @return Base|Nothing Either the built Post Type model, or a Nothing model if the post does not exist.
|
| 41 |
-
*/
|
| 42 |
-
public static function from_post( $post ) {
|
| 43 |
-
$post = get_post( $post );
|
| 44 |
-
|
| 45 |
-
if ( ! $post instanceof \WP_Post ) {
|
| 46 |
-
return new Nothing();
|
| 47 |
-
}
|
| 48 |
-
|
| 49 |
-
$instance = new static;
|
| 50 |
-
$instance->post = $post;
|
| 51 |
-
|
| 52 |
-
return $instance;
|
| 53 |
-
}
|
| 54 |
-
|
| 55 |
-
/**
|
| 56 |
-
* Returns the slug that will be prefixed to the cache key for the model.
|
| 57 |
-
*
|
| 58 |
-
* @since 4.9.18
|
| 59 |
-
*
|
| 60 |
-
* @return string The slug that will be prefixed to the cache key for the model.
|
| 61 |
-
*/
|
| 62 |
-
abstract protected function get_cache_slug();
|
| 63 |
-
|
| 64 |
-
/**
|
| 65 |
-
* Returns the cached model properties for the specified filter, if any.
|
| 66 |
-
*
|
| 67 |
-
* @since 4.9.18
|
| 68 |
-
*
|
| 69 |
-
* @param string $filter Type of filter to apply, used here as the stored post values might change.
|
| 70 |
-
*
|
| 71 |
-
* @return array|false An array of model properties, or `false` if not found.
|
| 72 |
-
*/
|
| 73 |
-
protected function get_cached_properties( $filter ) {
|
| 74 |
-
$cache_slug = $this->get_cache_slug();
|
| 75 |
-
|
| 76 |
-
if ( empty( $cache_slug ) ) {
|
| 77 |
-
return false;
|
| 78 |
-
}
|
| 79 |
-
|
| 80 |
-
// Cache by post ID and filter.
|
| 81 |
-
$cache_key = $cache_slug . '_' . $this->post->ID . '_' . $filter;
|
| 82 |
-
|
| 83 |
-
return ( new Cache() )->get( $cache_key, Cache_Listener::TRIGGER_SAVE_POST );
|
| 84 |
-
}
|
| 85 |
-
|
| 86 |
-
/**
|
| 87 |
-
* Builds and returns the properties for the model.
|
| 88 |
-
*
|
| 89 |
-
* In this method child classes should also implement any caching trigger mechanism, if any.
|
| 90 |
-
*
|
| 91 |
-
* @since 4.9.18
|
| 92 |
-
*
|
| 93 |
-
* @param string $filter The type of filter to build the properties for.
|
| 94 |
-
*
|
| 95 |
-
* @return array An array of built properties.
|
| 96 |
-
*/
|
| 97 |
-
abstract protected function build_properties( $filter );
|
| 98 |
-
|
| 99 |
-
/**
|
| 100 |
-
* Returns an array of the model properties.
|
| 101 |
-
*
|
| 102 |
-
* @since 4.9.18
|
| 103 |
-
*
|
| 104 |
-
* @param string $filter The type of filter to get the properties for.
|
| 105 |
-
*
|
| 106 |
-
* @return array The model properties. This value might be cached.
|
| 107 |
-
*/
|
| 108 |
-
protected function get_properties( $filter ) {
|
| 109 |
-
$cached = $this->get_cached_properties( $filter);
|
| 110 |
-
|
| 111 |
-
if ( false !== $cached ) {
|
| 112 |
-
return $cached;
|
| 113 |
-
}
|
| 114 |
-
|
| 115 |
-
$props = $this->build_properties( $filter );
|
| 116 |
-
|
| 117 |
-
$cache_slug = $this->get_cache_slug();
|
| 118 |
-
|
| 119 |
-
/**
|
| 120 |
-
* Filters the array of properties that will be used to decorate the post object handled by the class.
|
| 121 |
-
*
|
| 122 |
-
* @since 4.9.18
|
| 123 |
-
*
|
| 124 |
-
* @param array $props An associative array of all the properties that will be set on the "decorated" post
|
| 125 |
-
* object.
|
| 126 |
-
* @param \WP_Post $post The post object handled by the class.
|
| 127 |
-
*/
|
| 128 |
-
$props = apply_filters( "tribe_post_type_{$cache_slug}_properties", $props, $this->post );
|
| 129 |
-
|
| 130 |
-
return $props;
|
| 131 |
-
}
|
| 132 |
-
|
| 133 |
-
/**
|
| 134 |
-
* Returns the WP_Post version of this model.
|
| 135 |
-
*
|
| 136 |
-
* @since 4.9.18
|
| 137 |
-
*
|
| 138 |
-
* @param string $output The required return type. One of OBJECT, ARRAY_A, or ARRAY_N, which correspond to a WP_Post
|
| 139 |
-
* object,an associative array, or a numeric array, respectively.
|
| 140 |
-
* @param string $filter Type of filter to apply. Accepts 'raw', 'edit', 'db', or 'display' and other formats
|
| 141 |
-
* supported by the specific type implementation.
|
| 142 |
-
*
|
| 143 |
-
* @return \WP_Post|array|null The post object version of this post type model or `null` if the post is not valid.
|
| 144 |
-
*/
|
| 145 |
-
public function to_post( $output = OBJECT, $filter = 'raw' ) {
|
| 146 |
-
$properties = $this->get_properties( $filter );
|
| 147 |
-
|
| 148 |
-
// Clone the post to avoid side effects.
|
| 149 |
-
$post = clone $this->post;
|
| 150 |
-
|
| 151 |
-
// And decorate the clone with the properties.
|
| 152 |
-
foreach ( $properties as $key => $value ) {
|
| 153 |
-
$post->{$key} = $value;
|
| 154 |
-
}
|
| 155 |
-
|
| 156 |
-
switch ( $output ) {
|
| 157 |
-
case ARRAY_A:
|
| 158 |
-
return (array) $post;
|
| 159 |
-
case ARRAY_N:
|
| 160 |
-
return array_values( (array) $post );
|
| 161 |
-
case OBJECT:
|
| 162 |
-
default;
|
| 163 |
-
return $post;
|
| 164 |
-
}
|
| 165 |
-
}
|
| 166 |
-
|
| 167 |
-
/**
|
| 168 |
-
* Returns the closure that should be used to cache the post type model when, and if, caching it is required.
|
| 169 |
-
*
|
| 170 |
-
* @since 4.9.18
|
| 171 |
-
*
|
| 172 |
-
* @param string $filter The kind of filter applied to the model.
|
| 173 |
-
*
|
| 174 |
-
* @return callable The closure, or callable, that should be used to cache this model when, and if, required.
|
| 175 |
-
*/
|
| 176 |
-
protected function get_caching_callback( $filter ) {
|
| 177 |
-
$cache_slug = $this->get_cache_slug();
|
| 178 |
-
|
| 179 |
-
if ( empty( $cache_slug ) ) {
|
| 180 |
-
return '__return_true';
|
| 181 |
-
}
|
| 182 |
-
|
| 183 |
-
$callback = null;
|
| 184 |
-
|
| 185 |
-
if ( wp_using_ext_object_cache() ) {
|
| 186 |
-
/*
|
| 187 |
-
* If any real caching is in place , then define a function to cache this event when, and if, one of the
|
| 188 |
-
* lazy properties is loaded.
|
| 189 |
-
* Cache by post ID and filter.
|
| 190 |
-
*/
|
| 191 |
-
$cache_key = $cache_slug . '_' . $this->post->ID . '_' . $filter;
|
| 192 |
-
$cache = new Cache();
|
| 193 |
-
$callback = function () use ( $cache, $cache_key, $filter ) {
|
| 194 |
-
$properties = $this->get_properties( $filter );
|
| 195 |
-
|
| 196 |
-
/*
|
| 197 |
-
* Cache without expiration, but only until a post of the types managed by The Events Calendar is
|
| 198 |
-
* updated or created.
|
| 199 |
-
*/
|
| 200 |
-
$cache->set( $cache_key, $properties, 0, Cache_Listener::TRIGGER_SAVE_POST );
|
| 201 |
-
};
|
| 202 |
-
}
|
| 203 |
-
|
| 204 |
-
return $callback;
|
| 205 |
-
}
|
| 206 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
common/src/Tribe/Models/Post_Types/Nothing.php
DELETED
|
@@ -1,44 +0,0 @@
|
|
| 1 |
-
<?php
|
| 2 |
-
/**
|
| 3 |
-
* Models a non existing post.
|
| 4 |
-
*
|
| 5 |
-
* The reason for this class existence is to allow method chaining to happen without errors and to return a consistent
|
| 6 |
-
* model type from methods.
|
| 7 |
-
*
|
| 8 |
-
* @since 4.9.18
|
| 9 |
-
*
|
| 10 |
-
* @package Tribe\Models\Post_Types
|
| 11 |
-
*/
|
| 12 |
-
|
| 13 |
-
namespace Tribe\Models\Post_Types;
|
| 14 |
-
|
| 15 |
-
/**
|
| 16 |
-
* Class Nothing
|
| 17 |
-
*
|
| 18 |
-
* @since 4.9.18
|
| 19 |
-
*
|
| 20 |
-
* @package Tribe\Models\Post_Types
|
| 21 |
-
*/
|
| 22 |
-
class Nothing extends Base {
|
| 23 |
-
|
| 24 |
-
/**
|
| 25 |
-
* {@inheritDoc}
|
| 26 |
-
*/
|
| 27 |
-
protected function get_cache_slug() {
|
| 28 |
-
return '';
|
| 29 |
-
}
|
| 30 |
-
|
| 31 |
-
/**
|
| 32 |
-
* {@inheritDoc}
|
| 33 |
-
*/
|
| 34 |
-
protected function build_properties( $filter ) {
|
| 35 |
-
return [];
|
| 36 |
-
}
|
| 37 |
-
|
| 38 |
-
/**
|
| 39 |
-
* {@inheritDoc}
|
| 40 |
-
*/
|
| 41 |
-
public function to_post( $output = OBJECT, $filter = 'raw' ) {
|
| 42 |
-
return null;
|
| 43 |
-
}
|
| 44 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
common/src/Tribe/PUE/Checker.php
CHANGED
|
@@ -61,7 +61,7 @@ if ( ! class_exists( 'Tribe__PUE__Checker' ) ) {
|
|
| 61 |
*
|
| 62 |
* @var array
|
| 63 |
*/
|
| 64 |
-
private $download_query =
|
| 65 |
|
| 66 |
/**
|
| 67 |
* The context in which this license key is used. May be 'component'
|
|
@@ -138,14 +138,14 @@ if ( ! class_exists( 'Tribe__PUE__Checker' ) ) {
|
|
| 138 |
*
|
| 139 |
* @var array
|
| 140 |
*/
|
| 141 |
-
private static $stats =
|
| 142 |
|
| 143 |
/**
|
| 144 |
* Full Stats
|
| 145 |
*
|
| 146 |
* @var array
|
| 147 |
*/
|
| 148 |
-
private static $stats_full =
|
| 149 |
|
| 150 |
/**
|
| 151 |
* Class constructor.
|
|
@@ -166,7 +166,7 @@ if ( ! class_exists( 'Tribe__PUE__Checker' ) ) {
|
|
| 166 |
* }
|
| 167 |
* @param string $plugin_file fully qualified path to the main plugin file.
|
| 168 |
*/
|
| 169 |
-
public function __construct( $pue_update_url, $slug = '', $options =
|
| 170 |
$this->set_slug( $slug );
|
| 171 |
$this->set_plugin_file( $plugin_file );
|
| 172 |
$this->set_options( $options );
|
|
@@ -180,30 +180,30 @@ if ( ! class_exists( 'Tribe__PUE__Checker' ) ) {
|
|
| 180 |
*/
|
| 181 |
public function hooks() {
|
| 182 |
// Override requests for plugin information
|
| 183 |
-
add_filter( 'plugins_api',
|
| 184 |
|
| 185 |
// Check for updates when the WP updates are checked and inject our update if needed.
|
| 186 |
// Only add filter if the TRIBE_DISABLE_PUE constant is not set as true and where
|
| 187 |
// the context is not 'service'
|
| 188 |
if ( ( ! defined( 'TRIBE_DISABLE_PUE' ) || true !== TRIBE_DISABLE_PUE ) && 'service' !== $this->context ) {
|
| 189 |
-
add_filter( 'pre_set_site_transient_update_plugins',
|
| 190 |
}
|
| 191 |
|
| 192 |
-
add_filter( 'tribe_licensable_addons',
|
| 193 |
-
add_action( 'tribe_license_fields',
|
| 194 |
-
add_action( 'tribe_settings_after_content_tab_licenses',
|
| 195 |
-
add_action( 'tribe_settings_success_message',
|
| 196 |
-
add_action( 'load-plugins.php',
|
| 197 |
|
| 198 |
// Key validation
|
| 199 |
-
add_filter( 'tribe_settings_save_field_value',
|
| 200 |
-
add_action( 'wp_ajax_pue-validate-key_' . $this->get_slug(),
|
| 201 |
-
add_filter( 'tribe-pue-install-keys',
|
| 202 |
-
add_action( 'admin_enqueue_scripts',
|
| 203 |
-
add_action( 'admin_init',
|
| 204 |
|
| 205 |
// Package name
|
| 206 |
-
add_filter( 'upgrader_pre_download',
|
| 207 |
}
|
| 208 |
|
| 209 |
/********************** Getter / Setter Functions **********************/
|
|
@@ -319,16 +319,16 @@ if ( ! class_exists( 'Tribe__PUE__Checker' ) ) {
|
|
| 319 |
*
|
| 320 |
* @param array $options
|
| 321 |
*/
|
| 322 |
-
private function set_options( $options =
|
| 323 |
|
| 324 |
$options = wp_parse_args(
|
| 325 |
-
$options,
|
| 326 |
'pue_option_name' => 'external_updates-' . $this->get_slug(),
|
| 327 |
'apikey' => '',
|
| 328 |
'check_period' => 12,
|
| 329 |
'context' => 'component',
|
| 330 |
'plugin_name' => '',
|
| 331 |
-
|
| 332 |
);
|
| 333 |
|
| 334 |
$this->pue_option_name = $options['pue_option_name'];
|
|
@@ -343,7 +343,7 @@ if ( ! class_exists( 'Tribe__PUE__Checker' ) ) {
|
|
| 343 |
*
|
| 344 |
* @param array $download_query
|
| 345 |
*/
|
| 346 |
-
private function set_download_query( $download_query =
|
| 347 |
|
| 348 |
if ( ! empty( $download_query ) ) {
|
| 349 |
$this->download_query = $download_query;
|
|
@@ -392,7 +392,7 @@ if ( ! class_exists( 'Tribe__PUE__Checker' ) ) {
|
|
| 392 |
*
|
| 393 |
* @param array $validate_query
|
| 394 |
*/
|
| 395 |
-
private function set_validate_query( $validate_query =
|
| 396 |
|
| 397 |
if ( ! empty( $validate_query ) ) {
|
| 398 |
$this->validate_query = $validate_query;
|
|
@@ -472,7 +472,7 @@ if ( ! class_exists( 'Tribe__PUE__Checker' ) ) {
|
|
| 472 |
*
|
| 473 |
* @return array list of addons
|
| 474 |
*/
|
| 475 |
-
public function build_addon_list( $addons =
|
| 476 |
$addons[] = $this->get_plugin_name();
|
| 477 |
|
| 478 |
return $addons;
|
|
@@ -487,12 +487,12 @@ if ( ! class_exists( 'Tribe__PUE__Checker' ) ) {
|
|
| 487 |
*/
|
| 488 |
public function do_license_key_fields( $fields ) {
|
| 489 |
// common fields whether licenses should be hidden or not
|
| 490 |
-
$to_insert =
|
| 491 |
-
$this->pue_install_key . '-heading' =>
|
| 492 |
'type' => 'heading',
|
| 493 |
'label' => $this->get_plugin_name(),
|
| 494 |
-
|
| 495 |
-
|
| 496 |
|
| 497 |
$no_license_tooltip = esc_html__( 'A valid license key is required for support and updates', 'tribe-common' );
|
| 498 |
if ( 'event-aggregator' === $this->get_slug() ) {
|
|
@@ -505,7 +505,7 @@ if ( ! class_exists( 'Tribe__PUE__Checker' ) ) {
|
|
| 505 |
|
| 506 |
// we want to inject the following license settings at the end of the licenses tab
|
| 507 |
if ( $this->should_show_network_editable_license() ) {
|
| 508 |
-
$to_insert[ $this->pue_install_key ] =
|
| 509 |
'type' => 'license_key',
|
| 510 |
'size' => 'large',
|
| 511 |
'validation_type' => 'license_key',
|
|
@@ -514,9 +514,9 @@ if ( ! class_exists( 'Tribe__PUE__Checker' ) ) {
|
|
| 514 |
'tooltip' => $no_license_tooltip,
|
| 515 |
'parent_option' => false,
|
| 516 |
'network_option' => true,
|
| 517 |
-
|
| 518 |
} elseif ( $this->should_show_subsite_editable_license() ) {
|
| 519 |
-
$to_insert[ $this->pue_install_key ] =
|
| 520 |
'type' => 'license_key',
|
| 521 |
'size' => 'large',
|
| 522 |
'validation_type' => 'license_key',
|
|
@@ -525,28 +525,28 @@ if ( ! class_exists( 'Tribe__PUE__Checker' ) ) {
|
|
| 525 |
'tooltip' => $no_license_tooltip,
|
| 526 |
'parent_option' => false,
|
| 527 |
'network_option' => false,
|
| 528 |
-
|
| 529 |
} elseif ( $this->should_show_overrideable_license() ) {
|
| 530 |
-
$to_insert[ $this->pue_install_key . '-state' ] =
|
| 531 |
'type' => 'html',
|
| 532 |
'label' => sprintf( esc_attr__( 'License Key Status:', 'tribe-common' ) ),
|
| 533 |
-
'label_attributes' =>
|
| 534 |
'html' => sprintf( '<p>%s</p>', $this->get_network_license_state_string() ),
|
| 535 |
-
|
| 536 |
|
| 537 |
$override_id = $this->pue_install_key . '-override';
|
| 538 |
|
| 539 |
-
$to_insert[ $override_id ] =
|
| 540 |
'type' => 'checkbox_bool',
|
| 541 |
'label' => esc_html__( 'Override network license key', 'tribe-common' ),
|
| 542 |
'tooltip' => esc_html__( 'Check this box if you wish to override the network license key with your own', 'tribe-common' ),
|
| 543 |
'default' => false,
|
| 544 |
'validation_type' => 'boolean',
|
| 545 |
'parent_option' => false,
|
| 546 |
-
'attributes' =>
|
| 547 |
-
|
| 548 |
|
| 549 |
-
$to_insert[ $this->pue_install_key ] =
|
| 550 |
'type' => 'license_key',
|
| 551 |
'size' => 'large',
|
| 552 |
'validation_type' => 'license_key',
|
|
@@ -555,18 +555,18 @@ if ( ! class_exists( 'Tribe__PUE__Checker' ) ) {
|
|
| 555 |
'parent_option' => false,
|
| 556 |
'network_option' => false,
|
| 557 |
'class' => 'tribe-dependent',
|
| 558 |
-
'fieldset_attributes' =>
|
| 559 |
'data-depends' => '#' . $override_id . '-field',
|
| 560 |
'data-condition-checked' => true,
|
| 561 |
-
|
| 562 |
-
|
| 563 |
} else {
|
| 564 |
-
$to_insert[ $this->pue_install_key . '-state' ] =
|
| 565 |
'type' => 'html',
|
| 566 |
'label' => sprintf( esc_attr__( 'License Key Status:', 'tribe-common' ) ),
|
| 567 |
-
'label_attributes' =>
|
| 568 |
'html' => sprintf( '<p>%s</p>', $this->get_network_license_state_string() ),
|
| 569 |
-
|
| 570 |
}
|
| 571 |
|
| 572 |
$fields = self::array_insert_after_key( 'tribe-form-content-start', $fields, $to_insert );
|
|
@@ -663,16 +663,16 @@ if ( ! class_exists( 'Tribe__PUE__Checker' ) ) {
|
|
| 663 |
|
| 664 |
global $wpdb;
|
| 665 |
|
| 666 |
-
$stats =
|
| 667 |
-
'versions' =>
|
| 668 |
'wp' => sanitize_text_field( $GLOBALS['wp_version'] ),
|
| 669 |
-
|
| 670 |
-
'network' =>
|
| 671 |
'multisite' => 0,
|
| 672 |
'network_activated' => 0,
|
| 673 |
'active_sites' => 1,
|
| 674 |
-
|
| 675 |
-
|
| 676 |
|
| 677 |
if ( is_multisite() ) {
|
| 678 |
$sql_count = "
|
|
@@ -728,18 +728,18 @@ if ( ! class_exists( 'Tribe__PUE__Checker' ) ) {
|
|
| 728 |
}
|
| 729 |
}
|
| 730 |
|
| 731 |
-
$stats['versions'] =
|
| 732 |
'wp' => sanitize_text_field( $GLOBALS['wp_version'] ),
|
| 733 |
'php' => sanitize_text_field( phpversion() ),
|
| 734 |
'mysql' => sanitize_text_field( $wpdb->db_version() ),
|
| 735 |
-
|
| 736 |
|
| 737 |
-
$stats['theme'] =
|
| 738 |
'name' => sanitize_text_field( $theme->get( 'Name' ) ),
|
| 739 |
'version' => sanitize_text_field( $theme->get( 'Version' ) ),
|
| 740 |
'stylesheet' => sanitize_text_field( $theme->get_stylesheet() ),
|
| 741 |
'template' => sanitize_text_field( $theme->get_template() ),
|
| 742 |
-
|
| 743 |
|
| 744 |
$stats['site_language'] = sanitize_text_field( get_locale() );
|
| 745 |
$stats['user_language'] = sanitize_text_field( get_user_locale() );
|
|
@@ -747,13 +747,13 @@ if ( ! class_exists( 'Tribe__PUE__Checker' ) ) {
|
|
| 747 |
$stats['wp_debug'] = (int) ( defined( 'WP_DEBUG' ) && WP_DEBUG );
|
| 748 |
$stats['site_timezone'] = sanitize_text_field( $timezone );
|
| 749 |
|
| 750 |
-
$stats['totals'] =
|
| 751 |
'all_post_types' => (int) $wpdb->get_var( "SELECT COUNT(*) FROM `{$wpdb->posts}`" ),
|
| 752 |
'events' => (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM `{$wpdb->posts}` WHERE post_type = %s", 'tribe_events' ) ),
|
| 753 |
'venues' => (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM `{$wpdb->posts}` WHERE post_type = %s", 'tribe_venue' ) ),
|
| 754 |
'organizers' => (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM `{$wpdb->posts}` WHERE post_type = %s", 'tribe_organizer' ) ),
|
| 755 |
'event_categories' => (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM `{$wpdb->term_taxonomy}` WHERE taxonomy = %s", 'tribe_events_cat' ) ),
|
| 756 |
-
|
| 757 |
|
| 758 |
self::$stats_full = $stats;
|
| 759 |
|
|
@@ -841,15 +841,7 @@ if ( ! class_exists( 'Tribe__PUE__Checker' ) ) {
|
|
| 841 |
$class_name = $autoloader->get_prefix_by_slug( $this->get_slug() );
|
| 842 |
|
| 843 |
if ( $class_name ) {
|
| 844 |
-
$
|
| 845 |
-
|
| 846 |
-
if ( $is_namespaced ) {
|
| 847 |
-
// Handle class prefixes like Tribe\Plugin\.
|
| 848 |
-
$class_name .= 'PUE\Helper';
|
| 849 |
-
} else {
|
| 850 |
-
// Handle class prefixes like Tribe__Plugin__.
|
| 851 |
-
$class_name .= 'PUE__Helper';
|
| 852 |
-
}
|
| 853 |
|
| 854 |
if ( constant( $class_name . '::DATA' ) ) {
|
| 855 |
$license_key = constant( $class_name . '::DATA' );
|
|
@@ -900,7 +892,7 @@ if ( ! class_exists( 'Tribe__PUE__Checker' ) ) {
|
|
| 900 |
* @return array An associative array containing the license status response.
|
| 901 |
*/
|
| 902 |
public function validate_key( $key, $network = false ) {
|
| 903 |
-
$response =
|
| 904 |
$response['status'] = 0;
|
| 905 |
|
| 906 |
if ( ! $key ) {
|
|
@@ -985,23 +977,22 @@ if ( ! class_exists( 'Tribe__PUE__Checker' ) ) {
|
|
| 985 |
* Echo JSON results for key validation
|
| 986 |
*/
|
| 987 |
public function ajax_validate_key() {
|
|
|
|
| 988 |
$key = isset( $_POST['key'] ) ? wp_unslash( $_POST['key'] ) : null;
|
| 989 |
$nonce = isset( $_POST['_wpnonce'] ) ? wp_unslash( $_POST['_wpnonce'] ) : null;
|
| 990 |
|
| 991 |
-
if (
|
| 992 |
-
|
| 993 |
-
|| false === wp_verify_nonce( $nonce, 'pue-validate-key_' . $this->get_slug() )
|
| 994 |
-
) {
|
| 995 |
-
$response = [
|
| 996 |
'status' => 0,
|
| 997 |
'message' => __( 'Please refresh the page and try your request again.', 'tribe-common' ),
|
| 998 |
-
|
| 999 |
} else {
|
| 1000 |
$response = $this->validate_key( $key );
|
| 1001 |
}
|
| 1002 |
|
| 1003 |
echo json_encode( $response );
|
| 1004 |
exit;
|
|
|
|
| 1005 |
}
|
| 1006 |
|
| 1007 |
/**
|
|
@@ -1091,7 +1082,7 @@ if ( ! class_exists( 'Tribe__PUE__Checker' ) ) {
|
|
| 1091 |
}
|
| 1092 |
|
| 1093 |
$state = $this->get_state();
|
| 1094 |
-
$messages =
|
| 1095 |
$plugin_updates = get_plugin_updates();
|
| 1096 |
$update_available = isset( $plugin_updates[ $this->plugin_file ] );
|
| 1097 |
|
|
@@ -1141,12 +1132,12 @@ if ( ! class_exists( 'Tribe__PUE__Checker' ) ) {
|
|
| 1141 |
$message_row_html
|
| 1142 |
);
|
| 1143 |
|
| 1144 |
-
$this->plugin_notice =
|
| 1145 |
'slug' => $this->plugin_file,
|
| 1146 |
'message_row_html' => $message_row_html,
|
| 1147 |
-
|
| 1148 |
|
| 1149 |
-
add_filter( 'tribe_plugin_notices',
|
| 1150 |
|
| 1151 |
}
|
| 1152 |
|
|
@@ -1243,7 +1234,7 @@ if ( ! class_exists( 'Tribe__PUE__Checker' ) ) {
|
|
| 1243 |
*
|
| 1244 |
* @return string $plugin_info
|
| 1245 |
*/
|
| 1246 |
-
public function request_info( $query_args =
|
| 1247 |
$query_args = apply_filters( 'tribe_puc_request_info_query_args-' . $this->get_slug(), $query_args );
|
| 1248 |
|
| 1249 |
// Cache the API call so it only needs to be made once per plugin per page load.
|
|
@@ -1265,13 +1256,13 @@ if ( ! class_exists( 'Tribe__PUE__Checker' ) ) {
|
|
| 1265 |
}
|
| 1266 |
|
| 1267 |
//Various options for the wp_remote_get() call. Plugins can filter these, too.
|
| 1268 |
-
$options =
|
| 1269 |
'body' => $query_args,
|
| 1270 |
'timeout' => 15, //seconds
|
| 1271 |
-
'headers' =>
|
| 1272 |
'Accept' => 'application/json',
|
| 1273 |
-
|
| 1274 |
-
|
| 1275 |
$options = apply_filters( 'tribe_puc_request_info_options-' . $this->get_slug(), $options );
|
| 1276 |
|
| 1277 |
$url = sprintf( '%s/api/plugins/v2/license/validate', $this->get_pue_update_url() );
|
|
@@ -1335,7 +1326,6 @@ if ( ! class_exists( 'Tribe__PUE__Checker' ) ) {
|
|
| 1335 |
if ( isset( $plugin_info->api_invalid ) ) {
|
| 1336 |
$plugin_info = Tribe__PUE__Utility::from_plugin_info( $plugin_info );
|
| 1337 |
$plugin_info->license_error = $this->get_api_message( $plugin_info );
|
| 1338 |
-
|
| 1339 |
return $plugin_info;
|
| 1340 |
}
|
| 1341 |
|
|
@@ -1343,7 +1333,7 @@ if ( ! class_exists( 'Tribe__PUE__Checker' ) ) {
|
|
| 1343 |
$this->update_key( $plugin_info->new_install_key );
|
| 1344 |
}
|
| 1345 |
|
| 1346 |
-
//
|
| 1347 |
$download_query = $this->get_download_query();
|
| 1348 |
|
| 1349 |
if ( ! empty( $download_query ) ) {
|
|
@@ -1424,7 +1414,7 @@ if ( ! class_exists( 'Tribe__PUE__Checker' ) ) {
|
|
| 1424 |
*
|
| 1425 |
* @return array
|
| 1426 |
*/
|
| 1427 |
-
public function check_for_updates( $updates =
|
| 1428 |
$state = $this->get_state( $force_recheck );
|
| 1429 |
|
| 1430 |
$state->lastCheck = time();
|
|
@@ -1435,12 +1425,12 @@ if ( ! class_exists( 'Tribe__PUE__Checker' ) ) {
|
|
| 1435 |
|
| 1436 |
$state->update = $this->request_update();
|
| 1437 |
|
| 1438 |
-
// If a null update was returned, skip
|
| 1439 |
if ( null !== $state->update ) {
|
| 1440 |
-
//
|
| 1441 |
if ( version_compare( $state->update->version, $this->get_installed_version(), '>' ) ) {
|
| 1442 |
if ( empty( $updates ) ) {
|
| 1443 |
-
$updates = (object)
|
| 1444 |
}
|
| 1445 |
|
| 1446 |
$updates->response[ $this->get_plugin_file() ] = $state->update->to_wp_format();
|
|
@@ -1474,7 +1464,7 @@ if ( ! class_exists( 'Tribe__PUE__Checker' ) ) {
|
|
| 1474 |
}
|
| 1475 |
|
| 1476 |
if ( 'service' !== $this->context ) {
|
| 1477 |
-
$this->check_for_updates(
|
| 1478 |
}
|
| 1479 |
|
| 1480 |
$network_option = false;
|
|
@@ -1614,7 +1604,7 @@ if ( ! class_exists( 'Tribe__PUE__Checker' ) ) {
|
|
| 1614 |
* @return array $keys
|
| 1615 |
*
|
| 1616 |
*/
|
| 1617 |
-
public function return_install_key( $keys =
|
| 1618 |
$key = $this->get_key();
|
| 1619 |
|
| 1620 |
if ( ! empty( $key ) ) {
|
|
@@ -1665,9 +1655,9 @@ if ( ! class_exists( 'Tribe__PUE__Checker' ) ) {
|
|
| 1665 |
return false;
|
| 1666 |
}
|
| 1667 |
|
| 1668 |
-
$map =
|
| 1669 |
'event-aggregator/event-aggregator.php' => 'the-events-calendar/the-events-calendar.php',
|
| 1670 |
-
|
| 1671 |
|
| 1672 |
$plugin_file = $this->get_plugin_file();
|
| 1673 |
|
|
@@ -1692,11 +1682,11 @@ if ( ! class_exists( 'Tribe__PUE__Checker' ) ) {
|
|
| 1692 |
* @return string The localized state string.
|
| 1693 |
*/
|
| 1694 |
protected function get_network_license_state_string() {
|
| 1695 |
-
$states =
|
| 1696 |
'licensed' => esc_html__( 'A valid license has been entered by your network administrator.', 'tribe-common' ),
|
| 1697 |
'not-licensed' => esc_html__( 'No license entered. Consult your network administrator.', 'tribe-common' ),
|
| 1698 |
'expired' => esc_html__( 'Expired license. Consult your network administrator.', 'tribe-common' ),
|
| 1699 |
-
|
| 1700 |
|
| 1701 |
$response = $this->validate_key( $this->get_key( 'network' ), true );
|
| 1702 |
|
| 61 |
*
|
| 62 |
* @var array
|
| 63 |
*/
|
| 64 |
+
private $download_query = array();
|
| 65 |
|
| 66 |
/**
|
| 67 |
* The context in which this license key is used. May be 'component'
|
| 138 |
*
|
| 139 |
* @var array
|
| 140 |
*/
|
| 141 |
+
private static $stats = array();
|
| 142 |
|
| 143 |
/**
|
| 144 |
* Full Stats
|
| 145 |
*
|
| 146 |
* @var array
|
| 147 |
*/
|
| 148 |
+
private static $stats_full = array();
|
| 149 |
|
| 150 |
/**
|
| 151 |
* Class constructor.
|
| 166 |
* }
|
| 167 |
* @param string $plugin_file fully qualified path to the main plugin file.
|
| 168 |
*/
|
| 169 |
+
public function __construct( $pue_update_url, $slug = '', $options = array(), $plugin_file = '' ) {
|
| 170 |
$this->set_slug( $slug );
|
| 171 |
$this->set_plugin_file( $plugin_file );
|
| 172 |
$this->set_options( $options );
|
| 180 |
*/
|
| 181 |
public function hooks() {
|
| 182 |
// Override requests for plugin information
|
| 183 |
+
add_filter( 'plugins_api', array( $this, 'inject_info' ), 10, 3 );
|
| 184 |
|
| 185 |
// Check for updates when the WP updates are checked and inject our update if needed.
|
| 186 |
// Only add filter if the TRIBE_DISABLE_PUE constant is not set as true and where
|
| 187 |
// the context is not 'service'
|
| 188 |
if ( ( ! defined( 'TRIBE_DISABLE_PUE' ) || true !== TRIBE_DISABLE_PUE ) && 'service' !== $this->context ) {
|
| 189 |
+
add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_for_updates' ) );
|
| 190 |
}
|
| 191 |
|
| 192 |
+
add_filter( 'tribe_licensable_addons', array( $this, 'build_addon_list' ) );
|
| 193 |
+
add_action( 'tribe_license_fields', array( $this, 'do_license_key_fields' ) );
|
| 194 |
+
add_action( 'tribe_settings_after_content_tab_licenses', array( $this, 'do_license_key_javascript' ) );
|
| 195 |
+
add_action( 'tribe_settings_success_message', array( $this, 'do_license_key_success_message' ), 10, 2 );
|
| 196 |
+
add_action( 'load-plugins.php', array( $this, 'remove_default_inline_update_msg' ), 50 );
|
| 197 |
|
| 198 |
// Key validation
|
| 199 |
+
add_filter( 'tribe_settings_save_field_value', array( $this, 'check_for_api_key_error' ), 10, 3 );
|
| 200 |
+
add_action( 'wp_ajax_pue-validate-key_' . $this->get_slug(), array( $this, 'ajax_validate_key' ) );
|
| 201 |
+
add_filter( 'tribe-pue-install-keys', array( $this, 'return_install_key' ) );
|
| 202 |
+
add_action( 'admin_enqueue_scripts', array( $this, 'maybe_display_json_error_on_plugins_page' ), 1 );
|
| 203 |
+
add_action( 'admin_init', array( $this, 'general_notifications' ) );
|
| 204 |
|
| 205 |
// Package name
|
| 206 |
+
add_filter( 'upgrader_pre_download', array( Tribe__PUE__Package_Handler::instance(), 'filter_upgrader_pre_download' ), 5, 3 );
|
| 207 |
}
|
| 208 |
|
| 209 |
/********************** Getter / Setter Functions **********************/
|
| 319 |
*
|
| 320 |
* @param array $options
|
| 321 |
*/
|
| 322 |
+
private function set_options( $options = array() ) {
|
| 323 |
|
| 324 |
$options = wp_parse_args(
|
| 325 |
+
$options, array(
|
| 326 |
'pue_option_name' => 'external_updates-' . $this->get_slug(),
|
| 327 |
'apikey' => '',
|
| 328 |
'check_period' => 12,
|
| 329 |
'context' => 'component',
|
| 330 |
'plugin_name' => '',
|
| 331 |
+
)
|
| 332 |
);
|
| 333 |
|
| 334 |
$this->pue_option_name = $options['pue_option_name'];
|
| 343 |
*
|
| 344 |
* @param array $download_query
|
| 345 |
*/
|
| 346 |
+
private function set_download_query( $download_query = array() ) {
|
| 347 |
|
| 348 |
if ( ! empty( $download_query ) ) {
|
| 349 |
$this->download_query = $download_query;
|
| 392 |
*
|
| 393 |
* @param array $validate_query
|
| 394 |
*/
|
| 395 |
+
private function set_validate_query( $validate_query = array() ) {
|
| 396 |
|
| 397 |
if ( ! empty( $validate_query ) ) {
|
| 398 |
$this->validate_query = $validate_query;
|
| 472 |
*
|
| 473 |
* @return array list of addons
|
| 474 |
*/
|
| 475 |
+
public function build_addon_list( $addons = array() ) {
|
| 476 |
$addons[] = $this->get_plugin_name();
|
| 477 |
|
| 478 |
return $addons;
|
| 487 |
*/
|
| 488 |
public function do_license_key_fields( $fields ) {
|
| 489 |
// common fields whether licenses should be hidden or not
|
| 490 |
+
$to_insert = array(
|
| 491 |
+
$this->pue_install_key . '-heading' => array(
|
| 492 |
'type' => 'heading',
|
| 493 |
'label' => $this->get_plugin_name(),
|
| 494 |
+
),
|
| 495 |
+
);
|
| 496 |
|
| 497 |
$no_license_tooltip = esc_html__( 'A valid license key is required for support and updates', 'tribe-common' );
|
| 498 |
if ( 'event-aggregator' === $this->get_slug() ) {
|
| 505 |
|
| 506 |
// we want to inject the following license settings at the end of the licenses tab
|
| 507 |
if ( $this->should_show_network_editable_license() ) {
|
| 508 |
+
$to_insert[ $this->pue_install_key ] = array(
|
| 509 |
'type' => 'license_key',
|
| 510 |
'size' => 'large',
|
| 511 |
'validation_type' => 'license_key',
|
| 514 |
'tooltip' => $no_license_tooltip,
|
| 515 |
'parent_option' => false,
|
| 516 |
'network_option' => true,
|
| 517 |
+
);
|
| 518 |
} elseif ( $this->should_show_subsite_editable_license() ) {
|
| 519 |
+
$to_insert[ $this->pue_install_key ] = array(
|
| 520 |
'type' => 'license_key',
|
| 521 |
'size' => 'large',
|
| 522 |
'validation_type' => 'license_key',
|
| 525 |
'tooltip' => $no_license_tooltip,
|
| 526 |
'parent_option' => false,
|
| 527 |
'network_option' => false,
|
| 528 |
+
);
|
| 529 |
} elseif ( $this->should_show_overrideable_license() ) {
|
| 530 |
+
$to_insert[ $this->pue_install_key . '-state' ] = array(
|
| 531 |
'type' => 'html',
|
| 532 |
'label' => sprintf( esc_attr__( 'License Key Status:', 'tribe-common' ) ),
|
| 533 |
+
'label_attributes' => array( 'style' => 'width:auto;' ),
|
| 534 |
'html' => sprintf( '<p>%s</p>', $this->get_network_license_state_string() ),
|
| 535 |
+
);
|
| 536 |
|
| 537 |
$override_id = $this->pue_install_key . '-override';
|
| 538 |
|
| 539 |
+
$to_insert[ $override_id ] = array(
|
| 540 |
'type' => 'checkbox_bool',
|
| 541 |
'label' => esc_html__( 'Override network license key', 'tribe-common' ),
|
| 542 |
'tooltip' => esc_html__( 'Check this box if you wish to override the network license key with your own', 'tribe-common' ),
|
| 543 |
'default' => false,
|
| 544 |
'validation_type' => 'boolean',
|
| 545 |
'parent_option' => false,
|
| 546 |
+
'attributes' => array( 'id' => $override_id . '-field' ),
|
| 547 |
+
);
|
| 548 |
|
| 549 |
+
$to_insert[ $this->pue_install_key ] = array(
|
| 550 |
'type' => 'license_key',
|
| 551 |
'size' => 'large',
|
| 552 |
'validation_type' => 'license_key',
|
| 555 |
'parent_option' => false,
|
| 556 |
'network_option' => false,
|
| 557 |
'class' => 'tribe-dependent',
|
| 558 |
+
'fieldset_attributes' => array(
|
| 559 |
'data-depends' => '#' . $override_id . '-field',
|
| 560 |
'data-condition-checked' => true,
|
| 561 |
+
),
|
| 562 |
+
);
|
| 563 |
} else {
|
| 564 |
+
$to_insert[ $this->pue_install_key . '-state' ] = array(
|
| 565 |
'type' => 'html',
|
| 566 |
'label' => sprintf( esc_attr__( 'License Key Status:', 'tribe-common' ) ),
|
| 567 |
+
'label_attributes' => array( 'style' => 'width:auto;' ),
|
| 568 |
'html' => sprintf( '<p>%s</p>', $this->get_network_license_state_string() ),
|
| 569 |
+
);
|
| 570 |
}
|
| 571 |
|
| 572 |
$fields = self::array_insert_after_key( 'tribe-form-content-start', $fields, $to_insert );
|
| 663 |
|
| 664 |
global $wpdb;
|
| 665 |
|
| 666 |
+
$stats = array(
|
| 667 |
+
'versions' => array(
|
| 668 |
'wp' => sanitize_text_field( $GLOBALS['wp_version'] ),
|
| 669 |
+
),
|
| 670 |
+
'network' => array(
|
| 671 |
'multisite' => 0,
|
| 672 |
'network_activated' => 0,
|
| 673 |
'active_sites' => 1,
|
| 674 |
+
),
|
| 675 |
+
);
|
| 676 |
|
| 677 |
if ( is_multisite() ) {
|
| 678 |
$sql_count = "
|
| 728 |
}
|
| 729 |
}
|
| 730 |
|
| 731 |
+
$stats['versions'] = array(
|
| 732 |
'wp' => sanitize_text_field( $GLOBALS['wp_version'] ),
|
| 733 |
'php' => sanitize_text_field( phpversion() ),
|
| 734 |
'mysql' => sanitize_text_field( $wpdb->db_version() ),
|
| 735 |
+
);
|
| 736 |
|
| 737 |
+
$stats['theme'] = array(
|
| 738 |
'name' => sanitize_text_field( $theme->get( 'Name' ) ),
|
| 739 |
'version' => sanitize_text_field( $theme->get( 'Version' ) ),
|
| 740 |
'stylesheet' => sanitize_text_field( $theme->get_stylesheet() ),
|
| 741 |
'template' => sanitize_text_field( $theme->get_template() ),
|
| 742 |
+
);
|
| 743 |
|
| 744 |
$stats['site_language'] = sanitize_text_field( get_locale() );
|
| 745 |
$stats['user_language'] = sanitize_text_field( get_user_locale() );
|
| 747 |
$stats['wp_debug'] = (int) ( defined( 'WP_DEBUG' ) && WP_DEBUG );
|
| 748 |
$stats['site_timezone'] = sanitize_text_field( $timezone );
|
| 749 |
|
| 750 |
+
$stats['totals'] = array(
|
| 751 |
'all_post_types' => (int) $wpdb->get_var( "SELECT COUNT(*) FROM `{$wpdb->posts}`" ),
|
| 752 |
'events' => (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM `{$wpdb->posts}` WHERE post_type = %s", 'tribe_events' ) ),
|
| 753 |
'venues' => (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM `{$wpdb->posts}` WHERE post_type = %s", 'tribe_venue' ) ),
|
| 754 |
'organizers' => (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM `{$wpdb->posts}` WHERE post_type = %s", 'tribe_organizer' ) ),
|
| 755 |
'event_categories' => (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM `{$wpdb->term_taxonomy}` WHERE taxonomy = %s", 'tribe_events_cat' ) ),
|
| 756 |
+
);
|
| 757 |
|
| 758 |
self::$stats_full = $stats;
|
| 759 |
|
| 841 |
$class_name = $autoloader->get_prefix_by_slug( $this->get_slug() );
|
| 842 |
|
| 843 |
if ( $class_name ) {
|
| 844 |
+
$class_name .= 'PUE__Helper';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 845 |
|
| 846 |
if ( constant( $class_name . '::DATA' ) ) {
|
| 847 |
$license_key = constant( $class_name . '::DATA' );
|
| 892 |
* @return array An associative array containing the license status response.
|
| 893 |
*/
|
| 894 |
public function validate_key( $key, $network = false ) {
|
| 895 |
+
$response = array();
|
| 896 |
$response['status'] = 0;
|
| 897 |
|
| 898 |
if ( ! $key ) {
|
| 977 |
* Echo JSON results for key validation
|
| 978 |
*/
|
| 979 |
public function ajax_validate_key() {
|
| 980 |
+
|
| 981 |
$key = isset( $_POST['key'] ) ? wp_unslash( $_POST['key'] ) : null;
|
| 982 |
$nonce = isset( $_POST['_wpnonce'] ) ? wp_unslash( $_POST['_wpnonce'] ) : null;
|
| 983 |
|
| 984 |
+
if ( empty( $nonce ) || false === wp_verify_nonce( $nonce, 'pue-validate-key_' . $this->get_slug() ) ) {
|
| 985 |
+
$response = array(
|
|
|
|
|
|
|
|
|
|
| 986 |
'status' => 0,
|
| 987 |
'message' => __( 'Please refresh the page and try your request again.', 'tribe-common' ),
|
| 988 |
+
);
|
| 989 |
} else {
|
| 990 |
$response = $this->validate_key( $key );
|
| 991 |
}
|
| 992 |
|
| 993 |
echo json_encode( $response );
|
| 994 |
exit;
|
| 995 |
+
|
| 996 |
}
|
| 997 |
|
| 998 |
/**
|
| 1082 |
}
|
| 1083 |
|
| 1084 |
$state = $this->get_state();
|
| 1085 |
+
$messages = array();
|
| 1086 |
$plugin_updates = get_plugin_updates();
|
| 1087 |
$update_available = isset( $plugin_updates[ $this->plugin_file ] );
|
| 1088 |
|
| 1132 |
$message_row_html
|
| 1133 |
);
|
| 1134 |
|
| 1135 |
+
$this->plugin_notice = array(
|
| 1136 |
'slug' => $this->plugin_file,
|
| 1137 |
'message_row_html' => $message_row_html,
|
| 1138 |
+
);
|
| 1139 |
|
| 1140 |
+
add_filter( 'tribe_plugin_notices', array( $this, 'add_notice_to_plugin_notices' ) );
|
| 1141 |
|
| 1142 |
}
|
| 1143 |
|
| 1234 |
*
|
| 1235 |
* @return string $plugin_info
|
| 1236 |
*/
|
| 1237 |
+
public function request_info( $query_args = array() ) {
|
| 1238 |
$query_args = apply_filters( 'tribe_puc_request_info_query_args-' . $this->get_slug(), $query_args );
|
| 1239 |
|
| 1240 |
// Cache the API call so it only needs to be made once per plugin per page load.
|
| 1256 |
}
|
| 1257 |
|
| 1258 |
//Various options for the wp_remote_get() call. Plugins can filter these, too.
|
| 1259 |
+
$options = array(
|
| 1260 |
'body' => $query_args,
|
| 1261 |
'timeout' => 15, //seconds
|
| 1262 |
+
'headers' => array(
|
| 1263 |
'Accept' => 'application/json',
|
| 1264 |
+
),
|
| 1265 |
+
);
|
| 1266 |
$options = apply_filters( 'tribe_puc_request_info_options-' . $this->get_slug(), $options );
|
| 1267 |
|
| 1268 |
$url = sprintf( '%s/api/plugins/v2/license/validate', $this->get_pue_update_url() );
|
| 1326 |
if ( isset( $plugin_info->api_invalid ) ) {
|
| 1327 |
$plugin_info = Tribe__PUE__Utility::from_plugin_info( $plugin_info );
|
| 1328 |
$plugin_info->license_error = $this->get_api_message( $plugin_info );
|
|
|
|
| 1329 |
return $plugin_info;
|
| 1330 |
}
|
| 1331 |
|
| 1333 |
$this->update_key( $plugin_info->new_install_key );
|
| 1334 |
}
|
| 1335 |
|
| 1336 |
+
//need to correct the download url so it contains the custom user data (i.e. api and any other paramaters)
|
| 1337 |
$download_query = $this->get_download_query();
|
| 1338 |
|
| 1339 |
if ( ! empty( $download_query ) ) {
|
| 1414 |
*
|
| 1415 |
* @return array
|
| 1416 |
*/
|
| 1417 |
+
public function check_for_updates( $updates = array(), $force_recheck = false ) {
|
| 1418 |
$state = $this->get_state( $force_recheck );
|
| 1419 |
|
| 1420 |
$state->lastCheck = time();
|
| 1425 |
|
| 1426 |
$state->update = $this->request_update();
|
| 1427 |
|
| 1428 |
+
// If a null update was returned, skip the end of the function.
|
| 1429 |
if ( null !== $state->update ) {
|
| 1430 |
+
//Is there an update to insert?
|
| 1431 |
if ( version_compare( $state->update->version, $this->get_installed_version(), '>' ) ) {
|
| 1432 |
if ( empty( $updates ) ) {
|
| 1433 |
+
$updates = (object) array( 'response' => array() );
|
| 1434 |
}
|
| 1435 |
|
| 1436 |
$updates->response[ $this->get_plugin_file() ] = $state->update->to_wp_format();
|
| 1464 |
}
|
| 1465 |
|
| 1466 |
if ( 'service' !== $this->context ) {
|
| 1467 |
+
$this->check_for_updates( array(), true );
|
| 1468 |
}
|
| 1469 |
|
| 1470 |
$network_option = false;
|
| 1604 |
* @return array $keys
|
| 1605 |
*
|
| 1606 |
*/
|
| 1607 |
+
public function return_install_key( $keys = array() ) {
|
| 1608 |
$key = $this->get_key();
|
| 1609 |
|
| 1610 |
if ( ! empty( $key ) ) {
|
| 1655 |
return false;
|
| 1656 |
}
|
| 1657 |
|
| 1658 |
+
$map = array(
|
| 1659 |
'event-aggregator/event-aggregator.php' => 'the-events-calendar/the-events-calendar.php',
|
| 1660 |
+
);
|
| 1661 |
|
| 1662 |
$plugin_file = $this->get_plugin_file();
|
| 1663 |
|
| 1682 |
* @return string The localized state string.
|
| 1683 |
*/
|
| 1684 |
protected function get_network_license_state_string() {
|
| 1685 |
+
$states = array(
|
| 1686 |
'licensed' => esc_html__( 'A valid license has been entered by your network administrator.', 'tribe-common' ),
|
| 1687 |
'not-licensed' => esc_html__( 'No license entered. Consult your network administrator.', 'tribe-common' ),
|
| 1688 |
'expired' => esc_html__( 'Expired license. Consult your network administrator.', 'tribe-common' ),
|
| 1689 |
+
);
|
| 1690 |
|
| 1691 |
$response = $this->validate_key( $this->get_key( 'network' ), true );
|
| 1692 |
|
common/src/Tribe/PUE/Update_Prevention.php
CHANGED
|
@@ -178,7 +178,7 @@ class Update_Prevention {
|
|
| 178 |
$plugins_classes = array_keys( $incompatible_plugins );
|
| 179 |
$plugins_list_html = tribe( 'pue.notices' )->get_formatted_plugin_names_from_classes( $plugins_classes );
|
| 180 |
|
| 181 |
-
$link_read_more = '<a href="http://m.tri.be/1aev" target="_blank">' . esc_html__( 'Read
|
| 182 |
|
| 183 |
$message = sprintf(
|
| 184 |
esc_html__( 'Your update failed due to an incompatibility between the version (%1$s) of the %2$s you tried to update to and the version of %3$s that you are using. %4$s', 'tribe-common' ),
|
| 178 |
$plugins_classes = array_keys( $incompatible_plugins );
|
| 179 |
$plugins_list_html = tribe( 'pue.notices' )->get_formatted_plugin_names_from_classes( $plugins_classes );
|
| 180 |
|
| 181 |
+
$link_read_more = '<a href="http://m.tri.be/1aev" target="_blank">' . esc_html__( 'Read More.', 'tribe-common' ) . '</a>';
|
| 182 |
|
| 183 |
$message = sprintf(
|
| 184 |
esc_html__( 'Your update failed due to an incompatibility between the version (%1$s) of the %2$s you tried to update to and the version of %3$s that you are using. %4$s', 'tribe-common' ),
|
common/src/Tribe/Plugins.php
CHANGED
|
@@ -9,71 +9,71 @@ if ( ! class_exists( 'Tribe__Plugins' ) ) {
|
|
| 9 |
class Tribe__Plugins {
|
| 10 |
|
| 11 |
/**
|
| 12 |
-
* A list of tribe plugin's details in this
|
| 13 |
*
|
| 14 |
-
*
|
| 15 |
* 'short_name' => Common name for the plugin, used in places such as WP Admin messages
|
| 16 |
* 'class' => Main plugin class
|
| 17 |
* 'thickbox_url' => Download or purchase URL for plugin from within /wp-admin/ thickbox
|
| 18 |
-
*
|
| 19 |
*/
|
| 20 |
-
private $tribe_plugins =
|
| 21 |
-
|
| 22 |
'short_name' => 'Event Tickets',
|
| 23 |
'class' => 'Tribe__Tickets__Main',
|
| 24 |
'thickbox_url' => 'plugin-install.php?tab=plugin-information&plugin=event-tickets&TB_iframe=true',
|
| 25 |
-
|
| 26 |
-
|
| 27 |
'short_name' => 'Event Tickets Plus',
|
| 28 |
'class' => 'Tribe__Tickets_Plus__Main',
|
| 29 |
-
'thickbox_url' => '
|
| 30 |
-
|
| 31 |
-
|
| 32 |
'short_name' => 'The Events Calendar',
|
| 33 |
'class' => 'Tribe__Events__Main',
|
| 34 |
'thickbox_url' => 'plugin-install.php?tab=plugin-information&plugin=the-events-calendar&TB_iframe=true',
|
| 35 |
-
|
| 36 |
-
|
| 37 |
'short_name' => 'Events Calendar Pro',
|
| 38 |
'class' => 'Tribe__Events__Pro__Main',
|
| 39 |
-
'thickbox_url' => '
|
| 40 |
-
|
| 41 |
-
|
| 42 |
'short_name' => 'Community Events',
|
| 43 |
'class' => 'Tribe__Events__Community__Main',
|
| 44 |
-
'thickbox_url' => '
|
| 45 |
-
|
| 46 |
-
|
| 47 |
'short_name' => 'Community Tickets',
|
| 48 |
'class' => 'Tribe__Events__Community__Tickets__Main',
|
| 49 |
-
'thickbox_url' => '
|
| 50 |
-
|
| 51 |
-
|
| 52 |
'short_name' => 'Filter Bar',
|
| 53 |
'class' => 'Tribe__Events__Filterbar__View',
|
| 54 |
-
'thickbox_url' => '
|
| 55 |
-
|
| 56 |
-
|
| 57 |
'short_name' => 'Facebook Events',
|
| 58 |
'class' => 'Tribe__Events__Facebook__Importer',
|
| 59 |
-
'thickbox_url' => '
|
| 60 |
-
|
| 61 |
-
|
| 62 |
'short_name' => 'iCal Importer',
|
| 63 |
'class' => 'Tribe__Events__Ical_Importer__Main',
|
| 64 |
-
'thickbox_url' => '
|
| 65 |
-
|
| 66 |
-
|
| 67 |
'short_name' => 'Eventbrite Tickets',
|
| 68 |
'class' => 'Tribe__Events__Tickets__Eventbrite__Main',
|
| 69 |
-
'thickbox_url' => '
|
| 70 |
-
|
| 71 |
-
|
| 72 |
'short_name' => 'Advanced Post Manager',
|
| 73 |
'class' => 'Tribe_APM',
|
| 74 |
'thickbox_url' => 'plugin-install.php?tab=plugin-information&plugin=advanced-post-manager&TB_iframe=true',
|
| 75 |
-
|
| 76 |
-
|
| 77 |
|
| 78 |
/**
|
| 79 |
* Searches the plugin list for key/value pair and return the full details for that plugin
|
|
@@ -84,7 +84,7 @@ if ( ! class_exists( 'Tribe__Plugins' ) ) {
|
|
| 84 |
* @return array|null
|
| 85 |
*/
|
| 86 |
public function get_plugin_by_key( $search_key, $search_val ) {
|
| 87 |
-
foreach ( $this->
|
| 88 |
if ( isset( $plugin[ $search_key ] ) && $plugin[ $search_key ] === $search_val ) {
|
| 89 |
return $plugin;
|
| 90 |
}
|
|
@@ -131,37 +131,5 @@ if ( ! class_exists( 'Tribe__Plugins' ) ) {
|
|
| 131 |
return apply_filters( 'tribe_plugins_get_list', $this->tribe_plugins );
|
| 132 |
}
|
| 133 |
|
| 134 |
-
/**
|
| 135 |
-
* Checks if given plugin is active. Usually a Modern Tribe plugin.
|
| 136 |
-
*
|
| 137 |
-
* @param string $plugin_name The name of the plugin. Each plugin defines their name upon hooking on the filter.
|
| 138 |
-
*
|
| 139 |
-
* @since 4.12.1
|
| 140 |
-
*
|
| 141 |
-
* @return bool True if plugin is active. False if plugin is not active.
|
| 142 |
-
*/
|
| 143 |
-
public static function is_active( $plugin_name ) {
|
| 144 |
-
if ( ! did_action( "plugins_loaded" ) ) {
|
| 145 |
-
_doing_it_wrong(
|
| 146 |
-
__METHOD__,
|
| 147 |
-
__( 'Using this function before "plugins_loaded" action has fired can return unreliable results.', 'tribe-common' ),
|
| 148 |
-
'TBD'
|
| 149 |
-
);
|
| 150 |
-
}
|
| 151 |
-
|
| 152 |
-
/**
|
| 153 |
-
* Filters the array that each Tribe plugin overrides to
|
| 154 |
-
* set itself as active when this function is called.
|
| 155 |
-
*
|
| 156 |
-
* @example [ 'the-events-calendar' => true, 'event-tickets' => true ]
|
| 157 |
-
*
|
| 158 |
-
* @since 4.12.1
|
| 159 |
-
*
|
| 160 |
-
* @return array Plugin slugs as keys and bool as value for whether it's active or not.
|
| 161 |
-
*/
|
| 162 |
-
$plugins = apply_filters( 'tribe_active_plugins', [] );
|
| 163 |
-
|
| 164 |
-
return isset( $plugins[ $plugin_name ] ) && tribe_is_truthy( $plugins[ $plugin_name ] );
|
| 165 |
-
}
|
| 166 |
}
|
| 167 |
}
|
| 9 |
class Tribe__Plugins {
|
| 10 |
|
| 11 |
/**
|
| 12 |
+
* A list of tribe plugin's details in this format:
|
| 13 |
*
|
| 14 |
+
* array(
|
| 15 |
* 'short_name' => Common name for the plugin, used in places such as WP Admin messages
|
| 16 |
* 'class' => Main plugin class
|
| 17 |
* 'thickbox_url' => Download or purchase URL for plugin from within /wp-admin/ thickbox
|
| 18 |
+
* )
|
| 19 |
*/
|
| 20 |
+
private $tribe_plugins = array(
|
| 21 |
+
array(
|
| 22 |
'short_name' => 'Event Tickets',
|
| 23 |
'class' => 'Tribe__Tickets__Main',
|
| 24 |
'thickbox_url' => 'plugin-install.php?tab=plugin-information&plugin=event-tickets&TB_iframe=true',
|
| 25 |
+
),
|
| 26 |
+
array(
|
| 27 |
'short_name' => 'Event Tickets Plus',
|
| 28 |
'class' => 'Tribe__Tickets_Plus__Main',
|
| 29 |
+
'thickbox_url' => '//theeventscalendar.com/product/wordpress-event-tickets-plus/?TB_iframe=true',
|
| 30 |
+
),
|
| 31 |
+
array(
|
| 32 |
'short_name' => 'The Events Calendar',
|
| 33 |
'class' => 'Tribe__Events__Main',
|
| 34 |
'thickbox_url' => 'plugin-install.php?tab=plugin-information&plugin=the-events-calendar&TB_iframe=true',
|
| 35 |
+
),
|
| 36 |
+
array(
|
| 37 |
'short_name' => 'Events Calendar Pro',
|
| 38 |
'class' => 'Tribe__Events__Pro__Main',
|
| 39 |
+
'thickbox_url' => '//theeventscalendar.com/product/wordpress-events-calendar-pro/?TB_iframe=true',
|
| 40 |
+
),
|
| 41 |
+
array(
|
| 42 |
'short_name' => 'Community Events',
|
| 43 |
'class' => 'Tribe__Events__Community__Main',
|
| 44 |
+
'thickbox_url' => '//theeventscalendar.com/product/wordpress-community-events/?TB_iframe=true',
|
| 45 |
+
),
|
| 46 |
+
array(
|
| 47 |
'short_name' => 'Community Tickets',
|
| 48 |
'class' => 'Tribe__Events__Community__Tickets__Main',
|
| 49 |
+
'thickbox_url' => '//theeventscalendar.com/product/community-tickets/?TB_iframe=true',
|
| 50 |
+
),
|
| 51 |
+
array(
|
| 52 |
'short_name' => 'Filter Bar',
|
| 53 |
'class' => 'Tribe__Events__Filterbar__View',
|
| 54 |
+
'thickbox_url' => '//theeventscalendar.com/product/wordpress-events-filterbar/?TB_iframe=true',
|
| 55 |
+
),
|
| 56 |
+
array(
|
| 57 |
'short_name' => 'Facebook Events',
|
| 58 |
'class' => 'Tribe__Events__Facebook__Importer',
|
| 59 |
+
'thickbox_url' => '//theeventscalendar.com/product/facebook-events/?TB_iframe=true',
|
| 60 |
+
),
|
| 61 |
+
array(
|
| 62 |
'short_name' => 'iCal Importer',
|
| 63 |
'class' => 'Tribe__Events__Ical_Importer__Main',
|
| 64 |
+
'thickbox_url' => '//theeventscalendar.com/product/ical-importer/?TB_iframe=true',
|
| 65 |
+
),
|
| 66 |
+
array(
|
| 67 |
'short_name' => 'Eventbrite Tickets',
|
| 68 |
'class' => 'Tribe__Events__Tickets__Eventbrite__Main',
|
| 69 |
+
'thickbox_url' => '//theeventscalendar.com/product/wordpress-eventbrite-tickets/?TB_iframe=true',
|
| 70 |
+
),
|
| 71 |
+
array(
|
| 72 |
'short_name' => 'Advanced Post Manager',
|
| 73 |
'class' => 'Tribe_APM',
|
| 74 |
'thickbox_url' => 'plugin-install.php?tab=plugin-information&plugin=advanced-post-manager&TB_iframe=true',
|
| 75 |
+
),
|
| 76 |
+
);
|
| 77 |
|
| 78 |
/**
|
| 79 |
* Searches the plugin list for key/value pair and return the full details for that plugin
|
| 84 |
* @return array|null
|
| 85 |
*/
|
| 86 |
public function get_plugin_by_key( $search_key, $search_val ) {
|
| 87 |
+
foreach ( $this->tribe_plugins as $plugin ) {
|
| 88 |
if ( isset( $plugin[ $search_key ] ) && $plugin[ $search_key ] === $search_val ) {
|
| 89 |
return $plugin;
|
| 90 |
}
|
| 131 |
return apply_filters( 'tribe_plugins_get_list', $this->tribe_plugins );
|
| 132 |
}
|
| 133 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 134 |
}
|
| 135 |
}
|
common/src/Tribe/Post_Transient.php
CHANGED
|
@@ -29,7 +29,6 @@ class Tribe__Post_Transient {
|
|
| 29 |
* @param int $post_id The Post ID, can also be a WP_Post
|
| 30 |
* @param string $transient Post Meta to Fetch
|
| 31 |
*
|
| 32 |
-
* @return mixed Value stored on the Post Transient.
|
| 33 |
*/
|
| 34 |
public function get( $post_id, $transient ) {
|
| 35 |
global $_wp_using_ext_object_cache;
|
|
@@ -98,11 +97,10 @@ class Tribe__Post_Transient {
|
|
| 98 |
*
|
| 99 |
* @since 4.1
|
| 100 |
*
|
| 101 |
-
* @param int $post_id The Post ID, can also be a WP_Post
|
| 102 |
-
* @param string $transient Post Meta to Delete
|
| 103 |
-
* @param string $value Only delete if the value Matches
|
| 104 |
*
|
| 105 |
-
* @return boolean If we were able to delete the transient.
|
| 106 |
*/
|
| 107 |
public function delete( $post_id, $transient, $value = null ) {
|
| 108 |
global $_wp_using_ext_object_cache;
|
|
@@ -151,16 +149,15 @@ class Tribe__Post_Transient {
|
|
| 151 |
}
|
| 152 |
|
| 153 |
/**
|
| 154 |
-
* Sets a new value for the Transient
|
| 155 |
*
|
| 156 |
* @since 4.1
|
| 157 |
*
|
| 158 |
-
* @param int $post_id The Post ID, can also be a WP_Post
|
| 159 |
-
* @param string $transient Post Meta to set
|
| 160 |
-
* @param string $value Only delete if the value Matches
|
| 161 |
-
* @param int $expiration How long this transient will be valid, in seconds
|
| 162 |
*
|
| 163 |
-
* @return int|false Meta ID on success, false on failure.
|
| 164 |
*/
|
| 165 |
public function set( $post_id, $transient, $value, $expiration = 0 ) {
|
| 166 |
global $_wp_using_ext_object_cache;
|
|
@@ -211,4 +208,6 @@ class Tribe__Post_Transient {
|
|
| 211 |
|
| 212 |
return $result;
|
| 213 |
}
|
|
|
|
|
|
|
| 214 |
}
|
| 29 |
* @param int $post_id The Post ID, can also be a WP_Post
|
| 30 |
* @param string $transient Post Meta to Fetch
|
| 31 |
*
|
|
|
|
| 32 |
*/
|
| 33 |
public function get( $post_id, $transient ) {
|
| 34 |
global $_wp_using_ext_object_cache;
|
| 97 |
*
|
| 98 |
* @since 4.1
|
| 99 |
*
|
| 100 |
+
* @param int $post_id The Post ID, can also be a WP_Post
|
| 101 |
+
* @param string $transient Post Meta to Delete
|
| 102 |
+
* @param string $value Only delete if the value Matches
|
| 103 |
*
|
|
|
|
| 104 |
*/
|
| 105 |
public function delete( $post_id, $transient, $value = null ) {
|
| 106 |
global $_wp_using_ext_object_cache;
|
| 149 |
}
|
| 150 |
|
| 151 |
/**
|
| 152 |
+
* Sets a new value for the Transient
|
| 153 |
*
|
| 154 |
* @since 4.1
|
| 155 |
*
|
| 156 |
+
* @param int $post_id The Post ID, can also be a WP_Post
|
| 157 |
+
* @param string $transient Post Meta to set
|
| 158 |
+
* @param string $value Only delete if the value Matches
|
| 159 |
+
* @param int $expiration How long this transient will be valid, in seconds
|
| 160 |
*
|
|
|
|
| 161 |
*/
|
| 162 |
public function set( $post_id, $transient, $value, $expiration = 0 ) {
|
| 163 |
global $_wp_using_ext_object_cache;
|
| 208 |
|
| 209 |
return $result;
|
| 210 |
}
|
| 211 |
+
|
| 212 |
+
|
| 213 |
}
|
common/src/Tribe/Process/Handler.php
CHANGED
|
@@ -147,22 +147,6 @@ abstract class Tribe__Process__Handler {
|
|
| 147 |
|
| 148 |
check_ajax_referer( $this->identifier, 'nonce' );
|
| 149 |
|
| 150 |
-
// Let's make sure to hydrate date from the request if not set.
|
| 151 |
-
if ( count( array_filter( $data_source ) ) < 1 ) {
|
| 152 |
-
$data_source = $_POST;
|
| 153 |
-
}
|
| 154 |
-
|
| 155 |
-
do_action(
|
| 156 |
-
'tribe_log',
|
| 157 |
-
'debug',
|
| 158 |
-
$this->identifier,
|
| 159 |
-
[
|
| 160 |
-
'action' => 'async_handling',
|
| 161 |
-
'data_source' => $data_source,
|
| 162 |
-
'payload' => $_POST,
|
| 163 |
-
]
|
| 164 |
-
);
|
| 165 |
-
|
| 166 |
$this->handle( $data_source );
|
| 167 |
|
| 168 |
wp_die();
|
|
@@ -175,12 +159,6 @@ abstract class Tribe__Process__Handler {
|
|
| 175 |
*/
|
| 176 |
wp_clear_scheduled_hook( $this->healthcheck_cron_hook_id, [ $data_source ] );
|
| 177 |
|
| 178 |
-
do_action(
|
| 179 |
-
'tribe_log',
|
| 180 |
-
'debug',
|
| 181 |
-
$this->identifier,
|
| 182 |
-
array_merge( [ 'action' => 'cron_handling' ], $data_source ) );
|
| 183 |
-
|
| 184 |
$this->handle( $data_source );
|
| 185 |
}
|
| 186 |
|
|
@@ -198,8 +176,6 @@ abstract class Tribe__Process__Handler {
|
|
| 198 |
( defined( 'TRIBE_NO_ASYNC' ) && true === TRIBE_NO_ASYNC )
|
| 199 |
|| true === (bool) getenv( 'TRIBE_NO_ASYNC' )
|
| 200 |
) {
|
| 201 |
-
do_action( 'tribe_log', 'debug', $this->identifier, [ 'action' => 'sync_handle', 'data' => $this->data ] );
|
| 202 |
-
|
| 203 |
return $this->sync_handle( $this->data );
|
| 204 |
}
|
| 205 |
|
|
@@ -207,8 +183,6 @@ abstract class Tribe__Process__Handler {
|
|
| 207 |
$url = add_query_arg( $this->get_query_args(), $this->get_query_url() );
|
| 208 |
$args = $this->get_post_args();
|
| 209 |
|
| 210 |
-
do_action( 'tribe_log', 'debug', $this->identifier, [ 'action' => 'async_dispatch', 'data' => $this->data ] );
|
| 211 |
-
|
| 212 |
return wp_remote_post( esc_url_raw( $url ), $args );
|
| 213 |
}
|
| 214 |
|
|
@@ -227,21 +201,7 @@ abstract class Tribe__Process__Handler {
|
|
| 227 |
$class = get_class( $this );
|
| 228 |
$src = call_user_func( [ $class, 'action' ] );
|
| 229 |
$logger->log( 'Could not schedule event for cron-based handling', Tribe__Log::ERROR, $src );
|
| 230 |
-
|
| 231 |
-
do_action(
|
| 232 |
-
'tribe_log',
|
| 233 |
-
'error',
|
| 234 |
-
$this->identifier,
|
| 235 |
-
[ 'action' => 'schedule_cron', 'data' => $this->data ]
|
| 236 |
-
);
|
| 237 |
}
|
| 238 |
-
|
| 239 |
-
do_action(
|
| 240 |
-
'tribe_log',
|
| 241 |
-
'debug',
|
| 242 |
-
$this->identifier,
|
| 243 |
-
[ 'action' => 'schedule_cron', 'data' => $this->data ]
|
| 244 |
-
);
|
| 245 |
}
|
| 246 |
|
| 247 |
return true;
|
| 147 |
|
| 148 |
check_ajax_referer( $this->identifier, 'nonce' );
|
| 149 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 150 |
$this->handle( $data_source );
|
| 151 |
|
| 152 |
wp_die();
|
| 159 |
*/
|
| 160 |
wp_clear_scheduled_hook( $this->healthcheck_cron_hook_id, [ $data_source ] );
|
| 161 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 162 |
$this->handle( $data_source );
|
| 163 |
}
|
| 164 |
|
| 176 |
( defined( 'TRIBE_NO_ASYNC' ) && true === TRIBE_NO_ASYNC )
|
| 177 |
|| true === (bool) getenv( 'TRIBE_NO_ASYNC' )
|
| 178 |
) {
|
|
|
|
|
|
|
| 179 |
return $this->sync_handle( $this->data );
|
| 180 |
}
|
| 181 |
|
| 183 |
$url = add_query_arg( $this->get_query_args(), $this->get_query_url() );
|
| 184 |
$args = $this->get_post_args();
|
| 185 |
|
|
|
|
|
|
|
| 186 |
return wp_remote_post( esc_url_raw( $url ), $args );
|
| 187 |
}
|
| 188 |
|
| 201 |
$class = get_class( $this );
|
| 202 |
$src = call_user_func( [ $class, 'action' ] );
|
| 203 |
$logger->log( 'Could not schedule event for cron-based handling', Tribe__Log::ERROR, $src );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 204 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 205 |
}
|
| 206 |
|
| 207 |
return true;
|
common/src/Tribe/Process/Post_Thumbnail_Setter.php
CHANGED
|
@@ -2,6 +2,7 @@
|
|
| 2 |
|
| 3 |
/**
|
| 4 |
* Class Tribe__Process__Post_Thumbnail_Setter
|
|
|
|
| 5 |
*
|
| 6 |
* Handles upload and setting of a post thumbnail in an async process.
|
| 7 |
* Example usage:
|
|
@@ -41,14 +42,7 @@ class Tribe__Process__Post_Thumbnail_Setter extends Tribe__Process__Handler {
|
|
| 41 |
throw new InvalidArgumentException( 'Post ID and featured image should be set before trying to dispatch.' );
|
| 42 |
}
|
| 43 |
|
| 44 |
-
$data
|
| 45 |
-
'post_id' => $this->post_id,
|
| 46 |
-
'post_thumbnail' => trim( $this->post_thumbnail ),
|
| 47 |
-
];
|
| 48 |
-
|
| 49 |
-
$this->data( $data );
|
| 50 |
-
|
| 51 |
-
do_action( 'tribe_log', 'debug', $this->identifier, $data );
|
| 52 |
|
| 53 |
return parent::dispatch();
|
| 54 |
}
|
|
@@ -85,11 +79,10 @@ class Tribe__Process__Post_Thumbnail_Setter extends Tribe__Process__Handler {
|
|
| 85 |
*
|
| 86 |
* @since 4.7.12
|
| 87 |
*
|
| 88 |
-
* @
|
| 89 |
-
*
|
| 90 |
* @see Tribe__Process__Post_Thumbnail_Setter::sync_handle()
|
| 91 |
*
|
| 92 |
-
* @
|
| 93 |
*/
|
| 94 |
protected function handle( array $data_source = null ) {
|
| 95 |
$this->sync_handle( $data_source );
|
|
@@ -99,77 +92,40 @@ class Tribe__Process__Post_Thumbnail_Setter extends Tribe__Process__Handler {
|
|
| 99 |
* {@inheritdoc}
|
| 100 |
*/
|
| 101 |
public function sync_handle( array $data_source = null ) {
|
| 102 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 103 |
|
| 104 |
$data_source = isset( $data_source ) ? $data_source : $_POST;
|
| 105 |
|
| 106 |
if ( ! isset( $data_source['post_id'], $data_source['post_thumbnail'] ) ) {
|
| 107 |
-
do_action( 'tribe_log', 'error', $this->identifier, [ 'data' => $data_source, ] );
|
| 108 |
-
|
| 109 |
return 0;
|
| 110 |
}
|
| 111 |
|
| 112 |
$id = filter_var( $data_source['post_id'], FILTER_SANITIZE_NUMBER_INT );
|
| 113 |
$post_thumbnail = filter_var( $data_source['post_thumbnail'], FILTER_SANITIZE_STRING );
|
| 114 |
|
| 115 |
-
|
| 116 |
-
'status' => 'fetching thumbnail',
|
| 117 |
-
'post_thumbnail' => $post_thumbnail,
|
| 118 |
-
'post_id' => $id,
|
| 119 |
-
] );
|
| 120 |
|
| 121 |
$thumbnail_id = tribe_upload_image( $post_thumbnail );
|
| 122 |
|
| 123 |
if ( false === $thumbnail_id ) {
|
| 124 |
-
|
| 125 |
-
'tribe_log',
|
| 126 |
-
'error',
|
| 127 |
-
$this->identifier,
|
| 128 |
-
[
|
| 129 |
-
'action' => 'fetch',
|
| 130 |
-
'post_thumbnail' => $post_thumbnail,
|
| 131 |
-
'post_id' => $id,
|
| 132 |
-
'status' => 'could not fetch',
|
| 133 |
-
]
|
| 134 |
-
);
|
| 135 |
|
| 136 |
return 0;
|
| 137 |
}
|
| 138 |
|
| 139 |
-
$set =
|
| 140 |
-
if ( (int) get_post_thumbnail_id( $id ) !== (int) $thumbnail_id ) {
|
| 141 |
-
$set = set_post_thumbnail( $id, $thumbnail_id );
|
| 142 |
-
}
|
| 143 |
|
| 144 |
if ( false === $set ) {
|
| 145 |
-
|
| 146 |
-
'tribe_log',
|
| 147 |
-
'error',
|
| 148 |
-
$this->identifier,
|
| 149 |
-
[
|
| 150 |
-
'action' => 'set',
|
| 151 |
-
'post_thumbnail' => $post_thumbnail,
|
| 152 |
-
'attachment_id' => $thumbnail_id,
|
| 153 |
-
'post_id' => $id,
|
| 154 |
-
'status' => 'unable to set thumbnail',
|
| 155 |
-
]
|
| 156 |
-
);
|
| 157 |
|
| 158 |
return $thumbnail_id;
|
| 159 |
}
|
| 160 |
|
| 161 |
-
|
| 162 |
-
'tribe_log',
|
| 163 |
-
'debug',
|
| 164 |
-
$this->identifier,
|
| 165 |
-
[
|
| 166 |
-
'action' => 'set',
|
| 167 |
-
'post_thumbnail' => $post_thumbnail,
|
| 168 |
-
'attachment_id' => $thumbnail_id,
|
| 169 |
-
'post_id' => $id,
|
| 170 |
-
'status' => 'completed - attachment created and linked to the post',
|
| 171 |
-
]
|
| 172 |
-
);
|
| 173 |
|
| 174 |
return $thumbnail_id;
|
| 175 |
}
|
| 2 |
|
| 3 |
/**
|
| 4 |
* Class Tribe__Process__Post_Thumbnail_Setter
|
| 5 |
+
|
| 6 |
*
|
| 7 |
* Handles upload and setting of a post thumbnail in an async process.
|
| 8 |
* Example usage:
|
| 42 |
throw new InvalidArgumentException( 'Post ID and featured image should be set before trying to dispatch.' );
|
| 43 |
}
|
| 44 |
|
| 45 |
+
$this->data( array( 'post_id' => $this->post_id, 'post_thumbnail' => trim( $this->post_thumbnail ) ) );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 46 |
|
| 47 |
return parent::dispatch();
|
| 48 |
}
|
| 79 |
*
|
| 80 |
* @since 4.7.12
|
| 81 |
*
|
| 82 |
+
* @see tribe_upload_image()
|
|
|
|
| 83 |
* @see Tribe__Process__Post_Thumbnail_Setter::sync_handle()
|
| 84 |
*
|
| 85 |
+
* @param array|null $data_source An optional source of data.
|
| 86 |
*/
|
| 87 |
protected function handle( array $data_source = null ) {
|
| 88 |
$this->sync_handle( $data_source );
|
| 92 |
* {@inheritdoc}
|
| 93 |
*/
|
| 94 |
public function sync_handle( array $data_source = null ) {
|
| 95 |
+
/** @var Tribe__Log $logger */
|
| 96 |
+
$logger = tribe( 'logger' );
|
| 97 |
+
$log_src = 'Featured image setter';
|
| 98 |
+
|
| 99 |
+
$logger->log_debug( "(ID: {$this->identifier}) - handling request.", $log_src );
|
| 100 |
|
| 101 |
$data_source = isset( $data_source ) ? $data_source : $_POST;
|
| 102 |
|
| 103 |
if ( ! isset( $data_source['post_id'], $data_source['post_thumbnail'] ) ) {
|
|
|
|
|
|
|
| 104 |
return 0;
|
| 105 |
}
|
| 106 |
|
| 107 |
$id = filter_var( $data_source['post_id'], FILTER_SANITIZE_NUMBER_INT );
|
| 108 |
$post_thumbnail = filter_var( $data_source['post_thumbnail'], FILTER_SANITIZE_STRING );
|
| 109 |
|
| 110 |
+
$logger->log_debug( "(ID: {$this->identifier}) - fetching {$post_thumbnail} for post {$id}", $log_src );
|
|
|
|
|
|
|
|
|
|
|
|
|
| 111 |
|
| 112 |
$thumbnail_id = tribe_upload_image( $post_thumbnail );
|
| 113 |
|
| 114 |
if ( false === $thumbnail_id ) {
|
| 115 |
+
$logger->log_debug( "(ID: {$this->identifier}) - could not fetch {$post_thumbnail} for post {$id}, done.", $log_src );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 116 |
|
| 117 |
return 0;
|
| 118 |
}
|
| 119 |
|
| 120 |
+
$set = set_post_thumbnail( $id, $thumbnail_id );
|
|
|
|
|
|
|
|
|
|
| 121 |
|
| 122 |
if ( false === $set ) {
|
| 123 |
+
$logger->log_debug( "(ID: {$this->identifier}) - fetched {$post_thumbnail}, created attachment with ID {$thumbnail_id}, unable to set thumbnail for post {$id}, done.", $log_src );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 124 |
|
| 125 |
return $thumbnail_id;
|
| 126 |
}
|
| 127 |
|
| 128 |
+
$logger->log_debug( "(ID: {$this->identifier}) - fetched {$post_thumbnail}, created attachment with ID {$thumbnail_id}, set thumbnail for post {$id}, done.", $log_src );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 129 |
|
| 130 |
return $thumbnail_id;
|
| 131 |
}
|
common/src/Tribe/Promoter/Auth.php
CHANGED
|
@@ -21,6 +21,16 @@ class Tribe__Promoter__Auth {
|
|
| 21 |
*/
|
| 22 |
public function __construct( Tribe__Promoter__Connector $connector ) {
|
| 23 |
$this->connector = $connector;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 24 |
}
|
| 25 |
|
| 26 |
/**
|
| 21 |
*/
|
| 22 |
public function __construct( Tribe__Promoter__Connector $connector ) {
|
| 23 |
$this->connector = $connector;
|
| 24 |
+
$this->hook();
|
| 25 |
+
}
|
| 26 |
+
|
| 27 |
+
/**
|
| 28 |
+
* Attach hooks to this class.
|
| 29 |
+
*
|
| 30 |
+
* @since 4.9.12
|
| 31 |
+
*/
|
| 32 |
+
public function hook() {
|
| 33 |
+
add_filter( 'tribe_promoter_secret_key', [ $this, 'filter_promoter_secret_key' ] );
|
| 34 |
}
|
| 35 |
|
| 36 |
/**
|
common/src/Tribe/Promoter/Connector.php
CHANGED
|
@@ -1,9 +1,7 @@
|
|
| 1 |
<?php
|
| 2 |
|
| 3 |
/**
|
| 4 |
-
* Custom class for communicating with the Promoter Auth Connector
|
| 5 |
-
* early in the process and many functions that come from utils are not available during the
|
| 6 |
-
* execution of the methods from this class
|
| 7 |
*
|
| 8 |
* @since 4.9
|
| 9 |
*/
|
|
@@ -26,11 +24,13 @@ class Tribe__Promoter__Connector {
|
|
| 26 |
* @since 4.9
|
| 27 |
*/
|
| 28 |
public function base_url() {
|
|
|
|
|
|
|
| 29 |
if ( defined( 'TRIBE_PROMOTER_AUTH_CONNECTOR_URL' ) ) {
|
| 30 |
-
|
| 31 |
}
|
| 32 |
|
| 33 |
-
return
|
| 34 |
}
|
| 35 |
|
| 36 |
/**
|
|
@@ -48,18 +48,22 @@ class Tribe__Promoter__Connector {
|
|
| 48 |
public function authorize_with_connector( $user_id, $secret_key, $promoter_key, $license_key ) {
|
| 49 |
$url = $this->base_url() . 'connect';
|
| 50 |
|
| 51 |
-
$payload =
|
| 52 |
'clientSecret' => $secret_key,
|
| 53 |
-
'licenseKey'
|
| 54 |
-
'userId'
|
| 55 |
-
|
|
|
|
|
|
|
| 56 |
|
| 57 |
$token = \Firebase\JWT\JWT::encode( $payload, $promoter_key );
|
| 58 |
|
| 59 |
-
$
|
| 60 |
-
'body'
|
| 61 |
'sslverify' => false,
|
| 62 |
-
|
|
|
|
|
|
|
| 63 |
|
| 64 |
return (bool) $response;
|
| 65 |
}
|
|
@@ -76,13 +80,7 @@ class Tribe__Promoter__Connector {
|
|
| 76 |
public function authenticate_user_with_connector( $user_id ) {
|
| 77 |
$this->authorized = false;
|
| 78 |
|
| 79 |
-
|
| 80 |
-
if ( ! empty( $user_id ) ) {
|
| 81 |
-
$this->authorized = true;
|
| 82 |
-
return $user_id;
|
| 83 |
-
}
|
| 84 |
-
|
| 85 |
-
$token = $this->get_token();
|
| 86 |
|
| 87 |
if ( empty( $token ) ) {
|
| 88 |
return $user_id;
|
|
@@ -90,10 +88,12 @@ class Tribe__Promoter__Connector {
|
|
| 90 |
|
| 91 |
$url = $this->base_url() . 'connect/auth';
|
| 92 |
|
| 93 |
-
$
|
| 94 |
-
'body'
|
| 95 |
'sslverify' => false,
|
| 96 |
-
|
|
|
|
|
|
|
| 97 |
|
| 98 |
if ( ! $response ) {
|
| 99 |
return $user_id;
|
|
@@ -104,63 +104,6 @@ class Tribe__Promoter__Connector {
|
|
| 104 |
return $response;
|
| 105 |
}
|
| 106 |
|
| 107 |
-
/**
|
| 108 |
-
* Get the token either from a request or a header
|
| 109 |
-
*
|
| 110 |
-
* @since 4.9.20
|
| 111 |
-
*
|
| 112 |
-
* @return mixed
|
| 113 |
-
*/
|
| 114 |
-
protected function get_token() {
|
| 115 |
-
$request_token = $this->get_token_from_request();
|
| 116 |
-
|
| 117 |
-
return ( $request_token )
|
| 118 |
-
? sanitize_text_field( $request_token )
|
| 119 |
-
: $this->get_token_from_headers();
|
| 120 |
-
}
|
| 121 |
-
|
| 122 |
-
/**
|
| 123 |
-
* Get the token from a Request variable if present, otherwise fallback to `null`
|
| 124 |
-
*
|
| 125 |
-
* @since 4.9.20
|
| 126 |
-
*
|
| 127 |
-
* @return mixed
|
| 128 |
-
*/
|
| 129 |
-
protected function get_token_from_request() {
|
| 130 |
-
// Used in favor of tribe_get_request_var as at this point tribe_get_request_var is not defined.
|
| 131 |
-
return \Tribe__Utils__Array::get_in_any(
|
| 132 |
-
[ $_GET, $_POST, $_REQUEST ],
|
| 133 |
-
'tribe_promoter_auth_token'
|
| 134 |
-
);
|
| 135 |
-
}
|
| 136 |
-
|
| 137 |
-
/**
|
| 138 |
-
* Get the token directly from a Bearer Authentication Header, for hosts that
|
| 139 |
-
* does not support large Query strings
|
| 140 |
-
*
|
| 141 |
-
* @since 4.9.20
|
| 142 |
-
*
|
| 143 |
-
* @return mixed
|
| 144 |
-
*/
|
| 145 |
-
protected function get_token_from_headers() {
|
| 146 |
-
$headers = [
|
| 147 |
-
'HTTP_AUTHORIZATION',
|
| 148 |
-
'REDIRECT_HTTP_AUTHORIZATION',
|
| 149 |
-
];
|
| 150 |
-
|
| 151 |
-
foreach ( $headers as $header ) {
|
| 152 |
-
if ( empty( $_SERVER[ $header ] ) ) {
|
| 153 |
-
continue;
|
| 154 |
-
}
|
| 155 |
-
|
| 156 |
-
list( $token ) = sscanf( $_SERVER[ $header ], 'Bearer %s' );
|
| 157 |
-
|
| 158 |
-
if ( $token ) {
|
| 159 |
-
return sanitize_text_field( $token );
|
| 160 |
-
}
|
| 161 |
-
}
|
| 162 |
-
}
|
| 163 |
-
|
| 164 |
/**
|
| 165 |
* Notify the Promoter app of changes within this system.
|
| 166 |
*
|
|
@@ -171,7 +114,7 @@ class Tribe__Promoter__Connector {
|
|
| 171 |
public function notify_promoter_of_changes( $post_id ) {
|
| 172 |
$post_type = get_post_type( $post_id );
|
| 173 |
|
| 174 |
-
if ( ! in_array( $post_type,
|
| 175 |
return;
|
| 176 |
}
|
| 177 |
|
|
@@ -190,19 +133,19 @@ class Tribe__Promoter__Connector {
|
|
| 190 |
return;
|
| 191 |
}
|
| 192 |
|
| 193 |
-
$payload =
|
| 194 |
'licenseKey' => $license_key,
|
| 195 |
-
'sourceId'
|
| 196 |
-
|
| 197 |
|
| 198 |
$token = \Firebase\JWT\JWT::encode( $payload, $secret_key );
|
| 199 |
|
| 200 |
$url = $this->base_url() . 'connect/notify';
|
| 201 |
|
| 202 |
-
$args =
|
| 203 |
-
'body'
|
| 204 |
'sslverify' => false,
|
| 205 |
-
|
| 206 |
|
| 207 |
$this->make_call( $url, $args );
|
| 208 |
}
|
|
@@ -240,7 +183,15 @@ class Tribe__Promoter__Connector {
|
|
| 240 |
$code = wp_remote_retrieve_response_code( $response );
|
| 241 |
$body = wp_remote_retrieve_body( $response );
|
| 242 |
|
| 243 |
-
if ( is_wp_error( $response )
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 244 |
return false;
|
| 245 |
}
|
| 246 |
|
|
@@ -257,4 +208,5 @@ class Tribe__Promoter__Connector {
|
|
| 257 |
public function is_user_authorized() {
|
| 258 |
return $this->authorized;
|
| 259 |
}
|
|
|
|
| 260 |
}
|
| 1 |
<?php
|
| 2 |
|
| 3 |
/**
|
| 4 |
+
* Custom class for communicating with the Promoter Auth Connector
|
|
|
|
|
|
|
| 5 |
*
|
| 6 |
* @since 4.9
|
| 7 |
*/
|
| 24 |
* @since 4.9
|
| 25 |
*/
|
| 26 |
public function base_url() {
|
| 27 |
+
$url = 'https://us-central1-promoter-auth-connector.cloudfunctions.net/promoterConnector/';
|
| 28 |
+
|
| 29 |
if ( defined( 'TRIBE_PROMOTER_AUTH_CONNECTOR_URL' ) ) {
|
| 30 |
+
$url = TRIBE_PROMOTER_AUTH_CONNECTOR_URL;
|
| 31 |
}
|
| 32 |
|
| 33 |
+
return $url;
|
| 34 |
}
|
| 35 |
|
| 36 |
/**
|
| 48 |
public function authorize_with_connector( $user_id, $secret_key, $promoter_key, $license_key ) {
|
| 49 |
$url = $this->base_url() . 'connect';
|
| 50 |
|
| 51 |
+
$payload = array(
|
| 52 |
'clientSecret' => $secret_key,
|
| 53 |
+
'licenseKey' => $license_key,
|
| 54 |
+
'userId' => $user_id,
|
| 55 |
+
);
|
| 56 |
+
|
| 57 |
+
tribe( 'logger' )->log( $url );
|
| 58 |
|
| 59 |
$token = \Firebase\JWT\JWT::encode( $payload, $promoter_key );
|
| 60 |
|
| 61 |
+
$args = array(
|
| 62 |
+
'body' => array( 'token' => $token ),
|
| 63 |
'sslverify' => false,
|
| 64 |
+
);
|
| 65 |
+
|
| 66 |
+
$response = $this->make_call( $url, $args );
|
| 67 |
|
| 68 |
return (bool) $response;
|
| 69 |
}
|
| 80 |
public function authenticate_user_with_connector( $user_id ) {
|
| 81 |
$this->authorized = false;
|
| 82 |
|
| 83 |
+
$token = tribe_get_request_var( 'tribe_promoter_auth_token' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 84 |
|
| 85 |
if ( empty( $token ) ) {
|
| 86 |
return $user_id;
|
| 88 |
|
| 89 |
$url = $this->base_url() . 'connect/auth';
|
| 90 |
|
| 91 |
+
$args = array(
|
| 92 |
+
'body' => array( 'token' => $token ),
|
| 93 |
'sslverify' => false,
|
| 94 |
+
);
|
| 95 |
+
|
| 96 |
+
$response = $this->make_call( $url, $args );
|
| 97 |
|
| 98 |
if ( ! $response ) {
|
| 99 |
return $user_id;
|
| 104 |
return $response;
|
| 105 |
}
|
| 106 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 107 |
/**
|
| 108 |
* Notify the Promoter app of changes within this system.
|
| 109 |
*
|
| 114 |
public function notify_promoter_of_changes( $post_id ) {
|
| 115 |
$post_type = get_post_type( $post_id );
|
| 116 |
|
| 117 |
+
if ( ! in_array( $post_type, array( 'tribe_events', 'tribe_tickets' ), true ) ) {
|
| 118 |
return;
|
| 119 |
}
|
| 120 |
|
| 133 |
return;
|
| 134 |
}
|
| 135 |
|
| 136 |
+
$payload = array(
|
| 137 |
'licenseKey' => $license_key,
|
| 138 |
+
'sourceId' => $post_id,
|
| 139 |
+
);
|
| 140 |
|
| 141 |
$token = \Firebase\JWT\JWT::encode( $payload, $secret_key );
|
| 142 |
|
| 143 |
$url = $this->base_url() . 'connect/notify';
|
| 144 |
|
| 145 |
+
$args = array(
|
| 146 |
+
'body' => array( 'token' => $token ),
|
| 147 |
'sslverify' => false,
|
| 148 |
+
);
|
| 149 |
|
| 150 |
$this->make_call( $url, $args );
|
| 151 |
}
|
| 183 |
$code = wp_remote_retrieve_response_code( $response );
|
| 184 |
$body = wp_remote_retrieve_body( $response );
|
| 185 |
|
| 186 |
+
if ( is_wp_error( $response ) ) {
|
| 187 |
+
tribe( 'logger' )->log( $response->get_error_message() );
|
| 188 |
+
|
| 189 |
+
return false;
|
| 190 |
+
}
|
| 191 |
+
|
| 192 |
+
if ( $code > 299 ) {
|
| 193 |
+
tribe( 'logger' )->log( $body, 0 );
|
| 194 |
+
|
| 195 |
return false;
|
| 196 |
}
|
| 197 |
|
| 208 |
public function is_user_authorized() {
|
| 209 |
return $this->authorized;
|
| 210 |
}
|
| 211 |
+
|
| 212 |
}
|
common/src/Tribe/Repository.php
CHANGED
|
@@ -5,8 +5,6 @@ use Tribe__Utils__Array as Arr;
|
|
| 5 |
abstract class Tribe__Repository
|
| 6 |
implements Tribe__Repository__Interface {
|
| 7 |
|
| 8 |
-
const MAX_NUMBER_OF_POSTS_PER_PAGE = 99999999999;
|
| 9 |
-
|
| 10 |
/**
|
| 11 |
* @var array An array of keys that cannot be updated on this repository.
|
| 12 |
*/
|
|
@@ -561,10 +559,6 @@ abstract class Tribe__Repository
|
|
| 561 |
public function build_query( $use_query_builder = true ) {
|
| 562 |
$query = null;
|
| 563 |
|
| 564 |
-
if ( array_key_exists( 'void_query', $this->query_args ) && false !== $this->query_args['void_query'] ) {
|
| 565 |
-
$this->void_query = true;
|
| 566 |
-
}
|
| 567 |
-
|
| 568 |
// We'll let the query builder decide if the query has to be rebuilt or not.
|
| 569 |
if ( $use_query_builder && null !== $this->query_builder ) {
|
| 570 |
$query = $this->build_query_with_builder();
|
|
@@ -839,10 +833,6 @@ abstract class Tribe__Repository
|
|
| 839 |
if ( ! empty( $query->request ) ) {
|
| 840 |
$ids = $this->get_ids();
|
| 841 |
|
| 842 |
-
if ( empty( $ids ) ) {
|
| 843 |
-
return null;
|
| 844 |
-
}
|
| 845 |
-
|
| 846 |
return $return_id ? reset( $ids ) : $this->format_item( reset( $ids ) );
|
| 847 |
}
|
| 848 |
|
|
@@ -903,10 +893,6 @@ abstract class Tribe__Repository
|
|
| 903 |
if ( ! empty( $query->request ) ) {
|
| 904 |
$ids = $this->get_ids();
|
| 905 |
|
| 906 |
-
if ( empty( $ids ) ) {
|
| 907 |
-
return null;
|
| 908 |
-
}
|
| 909 |
-
|
| 910 |
return $return_id ? end( $ids ) : $this->format_item( end( $ids ) );
|
| 911 |
}
|
| 912 |
|
|
@@ -1074,9 +1060,7 @@ abstract class Tribe__Repository
|
|
| 1074 |
* {@inheritdoc}
|
| 1075 |
*/
|
| 1076 |
public function by( $key, $value = null ) {
|
| 1077 |
-
if ( $this->void_query
|
| 1078 |
-
$this->void_query = true;
|
| 1079 |
-
|
| 1080 |
// No point in doing more computations if the query is void.
|
| 1081 |
return $this;
|
| 1082 |
}
|
|
@@ -1564,9 +1548,9 @@ abstract class Tribe__Repository
|
|
| 1564 |
* Filters the query to only return posts that are related, via a meta key, to posts
|
| 1565 |
* that satisfy a condition.
|
| 1566 |
*
|
| 1567 |
-
* @param string|array $meta_keys One
|
| 1568 |
* to another post type.
|
| 1569 |
-
* @param string $compare The SQL
|
| 1570 |
* @param string $field One (a column in the `posts` table) that should match
|
| 1571 |
* the comparison criteria; required if the comparison operator is not `EXISTS` or
|
| 1572 |
* `NOT EXISTS`.
|
|
@@ -1583,10 +1567,9 @@ abstract class Tribe__Repository
|
|
| 1583 |
if ( empty( $field ) || empty( $values ) ) {
|
| 1584 |
throw Tribe__Repository__Usage_Error::because_this_comparison_operator_requires_fields_and_values( $meta_keys, $compare, $this );
|
| 1585 |
}
|
|
|
|
| 1586 |
}
|
| 1587 |
|
| 1588 |
-
$field = esc_sql( $field );
|
| 1589 |
-
|
| 1590 |
/** @var wpdb $wpdb */
|
| 1591 |
global $wpdb;
|
| 1592 |
$p = $this->sql_slug( 'meta_related_post', $compare, $meta_keys );
|
|
@@ -1613,90 +1596,6 @@ abstract class Tribe__Repository
|
|
| 1613 |
return $this;
|
| 1614 |
}
|
| 1615 |
|
| 1616 |
-
/**
|
| 1617 |
-
* Filters the query to only return posts that are related, via a meta key, to posts
|
| 1618 |
-
* that satisfy a condition.
|
| 1619 |
-
*
|
| 1620 |
-
* @since 4.10.3
|
| 1621 |
-
*
|
| 1622 |
-
* @throws Tribe__Repository__Usage_Error If the comparison operator requires and no value provided.
|
| 1623 |
-
*
|
| 1624 |
-
* @param string|array $meta_keys One or more `meta_keys` relating the queried post type(s)
|
| 1625 |
-
* to another post type.
|
| 1626 |
-
* @param string $compare The SQL comparison operator.
|
| 1627 |
-
* @param string $meta_field One (a column in the `postmeta` table) that should match
|
| 1628 |
-
* the comparison criteria; required if the comparison operator is not `EXISTS` or
|
| 1629 |
-
* `NOT EXISTS`.
|
| 1630 |
-
* @param string|array $meta_values One or more values the post field(s) should be compared to;
|
| 1631 |
-
* required if the comparison operator is not `EXISTS` or `NOT EXISTS`.
|
| 1632 |
-
* @param boolean $or_not_exists Whether or not to also include a clause to check if value IS NULL.
|
| 1633 |
-
* Example with this as true: `value = X OR value IS NULL`.
|
| 1634 |
-
*
|
| 1635 |
-
* @return $this
|
| 1636 |
-
*/
|
| 1637 |
-
public function where_meta_related_by_meta( $meta_keys, $compare, $meta_field = null, $meta_values = null, $or_not_exists = false ) {
|
| 1638 |
-
$meta_keys = Tribe__Utils__Array::list_to_array( $meta_keys );
|
| 1639 |
-
|
| 1640 |
-
if ( ! in_array( $compare, array( 'EXISTS', 'NOT EXISTS' ), true ) ) {
|
| 1641 |
-
if ( empty( $meta_field ) || empty( $meta_values ) ) {
|
| 1642 |
-
throw Tribe__Repository__Usage_Error::because_this_comparison_operator_requires_fields_and_values( $meta_keys, $compare, $this );
|
| 1643 |
-
}
|
| 1644 |
-
}
|
| 1645 |
-
|
| 1646 |
-
$meta_field = esc_sql( $meta_field );
|
| 1647 |
-
|
| 1648 |
-
/** @var wpdb $wpdb */
|
| 1649 |
-
global $wpdb;
|
| 1650 |
-
|
| 1651 |
-
$pm = $this->sql_slug( 'post_meta_related_post_meta', $compare, $meta_keys );
|
| 1652 |
-
$pmm = $this->sql_slug( 'meta_post_meta_related_post_meta', $compare, $meta_keys );
|
| 1653 |
-
|
| 1654 |
-
$this->filter_query->join( "LEFT JOIN {$wpdb->postmeta} {$pm} ON {$pm}.post_id = {$wpdb->posts}.ID" );
|
| 1655 |
-
$this->filter_query->join( "
|
| 1656 |
-
LEFT JOIN {$wpdb->postmeta} {$pmm}
|
| 1657 |
-
ON {$pmm}.post_id = {$pm}.meta_value
|
| 1658 |
-
AND {$pmm}.meta_key = '{$meta_field}'
|
| 1659 |
-
" );
|
| 1660 |
-
|
| 1661 |
-
$keys_in = $this->prepare_interval( $meta_keys );
|
| 1662 |
-
|
| 1663 |
-
if ( 'EXISTS' === $compare ) {
|
| 1664 |
-
$this->filter_query->where( "
|
| 1665 |
-
{$pm}.meta_key IN {$keys_in}
|
| 1666 |
-
AND {$pmm}.meta_id IS NOT NULL
|
| 1667 |
-
" );
|
| 1668 |
-
} elseif ( 'NOT EXISTS' === $compare ) {
|
| 1669 |
-
$this->filter_query->where( "
|
| 1670 |
-
{$pm}.meta_key IN {$keys_in}
|
| 1671 |
-
AND {$pmm}.meta_id IS NULL
|
| 1672 |
-
" );
|
| 1673 |
-
} else {
|
| 1674 |
-
if ( in_array( $compare, static::$multi_value_keys, true ) ) {
|
| 1675 |
-
$meta_values = $this->prepare_interval( $meta_values );
|
| 1676 |
-
} else {
|
| 1677 |
-
$meta_values = $this->prepare_value( $meta_values );
|
| 1678 |
-
}
|
| 1679 |
-
|
| 1680 |
-
$clause = "{$pmm}.meta_value {$compare} {$meta_values}";
|
| 1681 |
-
|
| 1682 |
-
if ( $or_not_exists ) {
|
| 1683 |
-
$clause = "
|
| 1684 |
-
(
|
| 1685 |
-
{$clause}
|
| 1686 |
-
OR {$pmm}.meta_id IS NULL
|
| 1687 |
-
)
|
| 1688 |
-
";
|
| 1689 |
-
}
|
| 1690 |
-
|
| 1691 |
-
$this->filter_query->where( "
|
| 1692 |
-
{$pm}.meta_key IN {$keys_in}
|
| 1693 |
-
AND {$clause}
|
| 1694 |
-
" );
|
| 1695 |
-
}
|
| 1696 |
-
|
| 1697 |
-
return $this;
|
| 1698 |
-
}
|
| 1699 |
-
|
| 1700 |
/**
|
| 1701 |
* Builds a fenced group of WHERE clauses that will be used with OR logic.
|
| 1702 |
*
|
|
@@ -2884,7 +2783,7 @@ abstract class Tribe__Repository
|
|
| 2884 |
|
| 2885 |
$created = call_user_func( $this->get_create_callback( $postarr ), $postarr );
|
| 2886 |
|
| 2887 |
-
$post =
|
| 2888 |
|
| 2889 |
return $post instanceof WP_Post && $post->ID === $created ? $post : false;
|
| 2890 |
}
|
|
@@ -3169,38 +3068,20 @@ abstract class Tribe__Repository
|
|
| 3169 |
*/
|
| 3170 |
$query_args = apply_filters( "tribe_repository_{$this->filter_name}_query_args", $query_args, $query, $this );
|
| 3171 |
|
| 3172 |
-
|
| 3173 |
-
|
| 3174 |
-
*
|
| 3175 |
-
* This should only be used if doing creating pagination for performance purposes.
|
| 3176 |
-
*
|
| 3177 |
-
* @since 4.11.0
|
| 3178 |
-
*
|
| 3179 |
-
* @param null|int $filtered_offset Offset parameter setting.
|
| 3180 |
-
* @param array $query_args List of query arguments.
|
| 3181 |
-
*/
|
| 3182 |
-
$filtered_offset = apply_filters( 'tribe_repository_query_arg_offset_override', null, $query_args );
|
| 3183 |
-
|
| 3184 |
-
if ( $filtered_offset || isset( $query_args['offset'] ) ) {
|
| 3185 |
$per_page = (int) Tribe__Utils__Array::get( $query_args, 'posts_per_page', get_option( 'posts_per_page' ) );
|
|
|
|
| 3186 |
|
| 3187 |
-
|
| 3188 |
-
|
| 3189 |
-
|
| 3190 |
-
$offset = absint( $query_args['offset'] );
|
| 3191 |
-
$page = (int) Tribe__Utils__Array::get( $query_args, 'paged', 1 );
|
| 3192 |
|
| 3193 |
-
|
| 3194 |
-
|
| 3195 |
-
|
| 3196 |
-
|
| 3197 |
-
|
| 3198 |
-
* is used, on the same repository, more than once.
|
| 3199 |
-
*/
|
| 3200 |
-
unset( $this->query_args['offset'] );
|
| 3201 |
-
}
|
| 3202 |
-
|
| 3203 |
-
$query_args['posts_per_page'] = $per_page === -1 ? self::MAX_NUMBER_OF_POSTS_PER_PAGE : $per_page;
|
| 3204 |
}
|
| 3205 |
|
| 3206 |
foreach ( $query_args as $key => $value ) {
|
| 5 |
abstract class Tribe__Repository
|
| 6 |
implements Tribe__Repository__Interface {
|
| 7 |
|
|
|
|
|
|
|
| 8 |
/**
|
| 9 |
* @var array An array of keys that cannot be updated on this repository.
|
| 10 |
*/
|
| 559 |
public function build_query( $use_query_builder = true ) {
|
| 560 |
$query = null;
|
| 561 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 562 |
// We'll let the query builder decide if the query has to be rebuilt or not.
|
| 563 |
if ( $use_query_builder && null !== $this->query_builder ) {
|
| 564 |
$query = $this->build_query_with_builder();
|
| 833 |
if ( ! empty( $query->request ) ) {
|
| 834 |
$ids = $this->get_ids();
|
| 835 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 836 |
return $return_id ? reset( $ids ) : $this->format_item( reset( $ids ) );
|
| 837 |
}
|
| 838 |
|
| 893 |
if ( ! empty( $query->request ) ) {
|
| 894 |
$ids = $this->get_ids();
|
| 895 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 896 |
return $return_id ? end( $ids ) : $this->format_item( end( $ids ) );
|
| 897 |
}
|
| 898 |
|
| 1060 |
* {@inheritdoc}
|
| 1061 |
*/
|
| 1062 |
public function by( $key, $value = null ) {
|
| 1063 |
+
if ( $this->void_query ) {
|
|
|
|
|
|
|
| 1064 |
// No point in doing more computations if the query is void.
|
| 1065 |
return $this;
|
| 1066 |
}
|
| 1548 |
* Filters the query to only return posts that are related, via a meta key, to posts
|
| 1549 |
* that satisfy a condition.
|
| 1550 |
*
|
| 1551 |
+
* @param string|array $meta_keys One ore more `meta_keys` relating the queried post type(s)
|
| 1552 |
* to another post type.
|
| 1553 |
+
* @param string $compare The SQL compoarison operator.
|
| 1554 |
* @param string $field One (a column in the `posts` table) that should match
|
| 1555 |
* the comparison criteria; required if the comparison operator is not `EXISTS` or
|
| 1556 |
* `NOT EXISTS`.
|
| 1567 |
if ( empty( $field ) || empty( $values ) ) {
|
| 1568 |
throw Tribe__Repository__Usage_Error::because_this_comparison_operator_requires_fields_and_values( $meta_keys, $compare, $this );
|
| 1569 |
}
|
| 1570 |
+
$field = esc_sql( $field );
|
| 1571 |
}
|
| 1572 |
|
|
|
|
|
|
|
| 1573 |
/** @var wpdb $wpdb */
|
| 1574 |
global $wpdb;
|
| 1575 |
$p = $this->sql_slug( 'meta_related_post', $compare, $meta_keys );
|
| 1596 |
return $this;
|
| 1597 |
}
|
| 1598 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1599 |
/**
|
| 1600 |
* Builds a fenced group of WHERE clauses that will be used with OR logic.
|
| 1601 |
*
|
| 2783 |
|
| 2784 |
$created = call_user_func( $this->get_create_callback( $postarr ), $postarr );
|
| 2785 |
|
| 2786 |
+
$post = get_post( $created );
|
| 2787 |
|
| 2788 |
return $post instanceof WP_Post && $post->ID === $created ? $post : false;
|
| 2789 |
}
|
| 3068 |
*/
|
| 3069 |
$query_args = apply_filters( "tribe_repository_{$this->filter_name}_query_args", $query_args, $query, $this );
|
| 3070 |
|
| 3071 |
+
if ( isset( $query_args['offset'] ) ) {
|
| 3072 |
+
$offset = absint( $query_args['offset'] );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3073 |
$per_page = (int) Tribe__Utils__Array::get( $query_args, 'posts_per_page', get_option( 'posts_per_page' ) );
|
| 3074 |
+
$page = (int) Tribe__Utils__Array::get( $query_args, 'paged', 1 );
|
| 3075 |
|
| 3076 |
+
$real_offset = $per_page === - 1 ? $offset : ( $per_page * ( $page - 1 ) ) + $offset;
|
| 3077 |
+
$query_args['offset'] = $real_offset;
|
| 3078 |
+
$query_args['posts_per_page'] = $per_page === - 1 ? 99999999999 : $per_page;
|
|
|
|
|
|
|
| 3079 |
|
| 3080 |
+
/**
|
| 3081 |
+
* Unset the `offset` query argument to avoid applying it multiple times when this method
|
| 3082 |
+
* is used, on the same repository, more than once.
|
| 3083 |
+
*/
|
| 3084 |
+
unset( $this->query_args['offset'] );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3085 |
}
|
| 3086 |
|
| 3087 |
foreach ( $query_args as $key => $value ) {
|
common/src/Tribe/Repository/Core_Read_Interface.php
DELETED
|
@@ -1,402 +0,0 @@
|
|
| 1 |
-
<?php
|
| 2 |
-
/**
|
| 3 |
-
* The "core" read interface for repositories.
|
| 4 |
-
*
|
| 5 |
-
* This interface is the minimal one a repository should implement to be called such.
|
| 6 |
-
*
|
| 7 |
-
* @since 4.10.2
|
| 8 |
-
*
|
| 9 |
-
* @package Tribe\Repository
|
| 10 |
-
*/
|
| 11 |
-
|
| 12 |
-
namespace Tribe\Repository;
|
| 13 |
-
|
| 14 |
-
use Tribe__Repository__Read_Interface;
|
| 15 |
-
use WP_Post;
|
| 16 |
-
|
| 17 |
-
/**
|
| 18 |
-
* Class Core_Read_Interface
|
| 19 |
-
*
|
| 20 |
-
* @since 4.10.2
|
| 21 |
-
*
|
| 22 |
-
* @package Tribe\Repository
|
| 23 |
-
*/
|
| 24 |
-
interface Core_Read_Interface {
|
| 25 |
-
/**
|
| 26 |
-
* Batch filter application method.
|
| 27 |
-
*
|
| 28 |
-
* This is the same as calling `by` multiple times with different arguments.
|
| 29 |
-
*
|
| 30 |
-
* @since 4.7.19
|
| 31 |
-
*
|
| 32 |
-
* @param array $args An associative array of arguments to filter
|
| 33 |
-
* the posts by in the shape [ <key>, <value> ]. * * @return Tribe__Repository__Read_Interface
|
| 34 |
-
*/
|
| 35 |
-
public function by_args( array $args );
|
| 36 |
-
|
| 37 |
-
/**
|
| 38 |
-
* Applies a filter to the query.
|
| 39 |
-
*
|
| 40 |
-
* While the signature only shows 2 arguments additional arguments will be passed
|
| 41 |
-
* to the schema filters.
|
| 42 |
-
*
|
| 43 |
-
* @since 4.7.19
|
| 44 |
-
*
|
| 45 |
-
* @param string $key
|
| 46 |
-
* @param mixed $value
|
| 47 |
-
* @param mixed ...$args Additional, optional, call arguments that will be passed to
|
| 48 |
-
* the schema.
|
| 49 |
-
*
|
| 50 |
-
* @return Tribe__Repository__Read_Interface
|
| 51 |
-
*/
|
| 52 |
-
public function by( $key, $value = null );
|
| 53 |
-
|
| 54 |
-
/**
|
| 55 |
-
* Just an alias of the `by` method to allow for easier reading.
|
| 56 |
-
*
|
| 57 |
-
* @since 4.7.19
|
| 58 |
-
*
|
| 59 |
-
* @param string $key
|
| 60 |
-
* @param mixed $value
|
| 61 |
-
*
|
| 62 |
-
* @return Tribe__Repository__Read_Interface
|
| 63 |
-
*/
|
| 64 |
-
public function where( $key, $value = null );
|
| 65 |
-
|
| 66 |
-
/**
|
| 67 |
-
* Sets the page of posts to fetch.
|
| 68 |
-
*
|
| 69 |
-
* Mind that this implementation does not support a `by( 'page', 2 )`
|
| 70 |
-
* filter to force more readable code.
|
| 71 |
-
*
|
| 72 |
-
* @since 4.7.19
|
| 73 |
-
*
|
| 74 |
-
* @param int $page
|
| 75 |
-
*
|
| 76 |
-
* @return Tribe__Repository__Read_Interface
|
| 77 |
-
*/
|
| 78 |
-
public function page( $page );
|
| 79 |
-
|
| 80 |
-
/**
|
| 81 |
-
* Sets the number of posts to retrieve per page.
|
| 82 |
-
*
|
| 83 |
-
* Mind that this implementation does not support a `by( 'per_page', 5 )`
|
| 84 |
-
* filter to force more readable code; by default posts per page is set to
|
| 85 |
-
* the pagination defaults for the post type.
|
| 86 |
-
*
|
| 87 |
-
* @param int $per_page
|
| 88 |
-
*
|
| 89 |
-
* @return Tribe__Repository__Read_Interface
|
| 90 |
-
*/
|
| 91 |
-
public function per_page( $per_page );
|
| 92 |
-
|
| 93 |
-
/**
|
| 94 |
-
* Returns the number of posts found matching the query.
|
| 95 |
-
*
|
| 96 |
-
* Mind that this value ignores the offset returning the
|
| 97 |
-
* number of results if limits where not applied.
|
| 98 |
-
*
|
| 99 |
-
* @since 4.7.19
|
| 100 |
-
*
|
| 101 |
-
* @return int
|
| 102 |
-
*/
|
| 103 |
-
public function found();
|
| 104 |
-
|
| 105 |
-
/**
|
| 106 |
-
* Returns all posts matching the query.
|
| 107 |
-
*
|
| 108 |
-
* Mind that "all" means "all the posts matching all the filters" so pagination applies.
|
| 109 |
-
*
|
| 110 |
-
* @return array
|
| 111 |
-
*/
|
| 112 |
-
public function all();
|
| 113 |
-
|
| 114 |
-
/**
|
| 115 |
-
* Sets the offset on the query.
|
| 116 |
-
*
|
| 117 |
-
* Mind that this implementation does not support a `by( 'offset', 2 )`
|
| 118 |
-
* filter to force more readable code.
|
| 119 |
-
*
|
| 120 |
-
* @since 4.7.19
|
| 121 |
-
*
|
| 122 |
-
* @param int $offset
|
| 123 |
-
* @param bool $increment Whether to increment the offset by the value
|
| 124 |
-
* or replace it.
|
| 125 |
-
*
|
| 126 |
-
* @return Tribe__Repository__Read_Interface
|
| 127 |
-
*/
|
| 128 |
-
public function offset( $offset, $increment = false );
|
| 129 |
-
|
| 130 |
-
/**
|
| 131 |
-
* Sets the order on the query.
|
| 132 |
-
*
|
| 133 |
-
* Mind that this implementation does not support a `by( 'order', 2 )`
|
| 134 |
-
* filter to force more readable code.
|
| 135 |
-
*
|
| 136 |
-
* @since 4.7.19
|
| 137 |
-
*
|
| 138 |
-
* @param string $order
|
| 139 |
-
*
|
| 140 |
-
* @return Tribe__Repository__Read_Interface
|
| 141 |
-
*/
|
| 142 |
-
public function order( $order = 'ASC' );
|
| 143 |
-
|
| 144 |
-
/**
|
| 145 |
-
* Sets the order criteria results should be fetched by.
|
| 146 |
-
*
|
| 147 |
-
* Mind that this implementation does not support a `by( 'order_by', 'title' )`
|
| 148 |
-
* filter to force more readable code.
|
| 149 |
-
*
|
| 150 |
-
* @since 4.7.19
|
| 151 |
-
*
|
| 152 |
-
* @param string $order_by The post field, custom field or alias key to order posts by.
|
| 153 |
-
* @param string $order The order direction; optional; shortcut for the `order` method; defaults
|
| 154 |
-
* to `DESC`.
|
| 155 |
-
*
|
| 156 |
-
* @return Tribe__Repository__Read_Interface
|
| 157 |
-
*/
|
| 158 |
-
public function order_by( $order_by, $order = 'DESC' );
|
| 159 |
-
|
| 160 |
-
/**
|
| 161 |
-
* Sets the fields that should be returned by the query.
|
| 162 |
-
*
|
| 163 |
-
* Mind that this implementation does not support a `by( 'fields', 'ids' )`
|
| 164 |
-
* filter to force more readable code.
|
| 165 |
-
*
|
| 166 |
-
* @since 4.7.19
|
| 167 |
-
*
|
| 168 |
-
* @param string $fields
|
| 169 |
-
*
|
| 170 |
-
* @return Tribe__Repository__Read_Interface
|
| 171 |
-
*/
|
| 172 |
-
public function fields( $fields );
|
| 173 |
-
|
| 174 |
-
/**
|
| 175 |
-
* Sugar method to set the `post__in` argument.
|
| 176 |
-
*
|
| 177 |
-
* Successive calls will stack, not replace each one.
|
| 178 |
-
*
|
| 179 |
-
* @since 4.7.19
|
| 180 |
-
*
|
| 181 |
-
* @param array|int $post_ids
|
| 182 |
-
*
|
| 183 |
-
* @return Tribe__Repository__Read_Interface
|
| 184 |
-
*/
|
| 185 |
-
public function in( $post_ids );
|
| 186 |
-
|
| 187 |
-
/**
|
| 188 |
-
* Sugar method to set the `post__not_in` argument.
|
| 189 |
-
*
|
| 190 |
-
* Successive calls will stack, not replace each one.
|
| 191 |
-
*
|
| 192 |
-
* @since 4.7.19
|
| 193 |
-
*
|
| 194 |
-
* @param array|int $post_ids
|
| 195 |
-
*
|
| 196 |
-
* @return Tribe__Repository__Read_Interface
|
| 197 |
-
*/
|
| 198 |
-
public function not_in( $post_ids );
|
| 199 |
-
|
| 200 |
-
/**
|
| 201 |
-
* Sugar method to set the `post_parent__in` argument.
|
| 202 |
-
*
|
| 203 |
-
* Successive calls will stack, not replace each one.
|
| 204 |
-
*
|
| 205 |
-
* @since 4.7.19
|
| 206 |
-
*
|
| 207 |
-
* @param array|int $post_id
|
| 208 |
-
*
|
| 209 |
-
* @return Tribe__Repository__Read_Interface
|
| 210 |
-
*/
|
| 211 |
-
public function parent( $post_id );
|
| 212 |
-
|
| 213 |
-
/**
|
| 214 |
-
* Sugar method to set the `post_parent__in` argument.
|
| 215 |
-
*
|
| 216 |
-
* Successive calls will stack, not replace each one.
|
| 217 |
-
*
|
| 218 |
-
* @since 4.7.19
|
| 219 |
-
*
|
| 220 |
-
* @param array $post_ids
|
| 221 |
-
*
|
| 222 |
-
* @return Tribe__Repository__Read_Interface
|
| 223 |
-
*/
|
| 224 |
-
public function parent_in( $post_ids );
|
| 225 |
-
|
| 226 |
-
/**
|
| 227 |
-
* Sugar method to set the `post_parent__not_in` argument.
|
| 228 |
-
*
|
| 229 |
-
* Successive calls will stack, not replace each one.
|
| 230 |
-
*
|
| 231 |
-
* @since 4.7.19
|
| 232 |
-
*
|
| 233 |
-
* @param array $post_ids
|
| 234 |
-
*
|
| 235 |
-
* @return Tribe__Repository__Read_Interface
|
| 236 |
-
*/
|
| 237 |
-
public function parent_not_in( $post_ids );
|
| 238 |
-
|
| 239 |
-
/**
|
| 240 |
-
* Sugar method to set the `s` argument.
|
| 241 |
-
*
|
| 242 |
-
* Successive calls will replace the search string.
|
| 243 |
-
* This is the default WordPress searh, to search by title,
|
| 244 |
-
* content or excerpt only use the `title`, `content`, `excerpt` filters.
|
| 245 |
-
*
|
| 246 |
-
* @param $search
|
| 247 |
-
*
|
| 248 |
-
* @return Tribe__Repository__Read_Interface
|
| 249 |
-
*/
|
| 250 |
-
public function search( $search );
|
| 251 |
-
|
| 252 |
-
/**
|
| 253 |
-
* Returns the number of posts found matching the query in the current page.
|
| 254 |
-
*
|
| 255 |
-
* While the `found` method will return the number of posts found
|
| 256 |
-
* across all pages this method will only return the number of
|
| 257 |
-
* posts found in the current page.
|
| 258 |
-
* Differently from the `found` method this method will apply the
|
| 259 |
-
* offset if set.
|
| 260 |
-
*
|
| 261 |
-
* @since 4.7.19
|
| 262 |
-
*
|
| 263 |
-
* @return int
|
| 264 |
-
*/
|
| 265 |
-
public function count();
|
| 266 |
-
|
| 267 |
-
/**
|
| 268 |
-
* Returns the first post of the page matching the current query.
|
| 269 |
-
*
|
| 270 |
-
* If, by default or because set with the `per_page` method, all
|
| 271 |
-
* posts matching the query should be returned then this will be
|
| 272 |
-
* the first post of all those matching the query.
|
| 273 |
-
*
|
| 274 |
-
* @since 4.7.19
|
| 275 |
-
*
|
| 276 |
-
* @return WP_Post|mixed|null
|
| 277 |
-
*
|
| 278 |
-
* @see Tribe__Repository__Read_Interface::per_page()
|
| 279 |
-
*/
|
| 280 |
-
public function first();
|
| 281 |
-
|
| 282 |
-
/**
|
| 283 |
-
* Returns the last post of the page matching the current query.
|
| 284 |
-
*
|
| 285 |
-
* If, by default or because set with the `per_page` method, all
|
| 286 |
-
* posts matching the query should be returned then this will be
|
| 287 |
-
* the last post of all those matching the query.
|
| 288 |
-
*
|
| 289 |
-
* @since 4.7.19
|
| 290 |
-
*
|
| 291 |
-
* @return WP_Post|mixed|null
|
| 292 |
-
*
|
| 293 |
-
* @see Tribe__Repository__Read_Interface::per_page()
|
| 294 |
-
*/
|
| 295 |
-
public function last();
|
| 296 |
-
|
| 297 |
-
/**
|
| 298 |
-
* Returns the nth post (1-based) of the page matching the current query.
|
| 299 |
-
*
|
| 300 |
-
* Being 1-based the second post can be fetched using `nth( 2 )`.
|
| 301 |
-
* If, by default or because set with the `per_page` method, all
|
| 302 |
-
* posts matching the query should be returned then this will be
|
| 303 |
-
* the nth post of all those matching the query.
|
| 304 |
-
*
|
| 305 |
-
* @since 4.7.19
|
| 306 |
-
*
|
| 307 |
-
* @param int $n
|
| 308 |
-
*
|
| 309 |
-
* @return WP_Post|mixed|null
|
| 310 |
-
*
|
| 311 |
-
* @see Tribe__Repository__Read_Interface::per_page()
|
| 312 |
-
*/
|
| 313 |
-
public function nth( $n );
|
| 314 |
-
|
| 315 |
-
/**
|
| 316 |
-
* Returns the first n posts of the page matching the current query.
|
| 317 |
-
*
|
| 318 |
-
* If, by default or because set with the `per_page` method, all
|
| 319 |
-
* posts matching the query should be returned then this method will
|
| 320 |
-
* return the first n posts of all those matching the query.
|
| 321 |
-
*
|
| 322 |
-
* @since 4.7.19
|
| 323 |
-
*
|
| 324 |
-
* @return array An array of posts matching the query.
|
| 325 |
-
*
|
| 326 |
-
* @see Tribe__Repository__Read_Interface::per_page()
|
| 327 |
-
*/
|
| 328 |
-
public function take( $n );
|
| 329 |
-
|
| 330 |
-
/**
|
| 331 |
-
* Plucks a field from all results and returns it.
|
| 332 |
-
*
|
| 333 |
-
* This method will implicitly build and use a `WP_List_Util` instance on the return
|
| 334 |
-
* value of a call to the `all` method.
|
| 335 |
-
*
|
| 336 |
-
* @since 4.9.5
|
| 337 |
-
*
|
| 338 |
-
* @param string $field The field to pluck from each result.
|
| 339 |
-
*
|
| 340 |
-
* @return array An array of the plucked results.
|
| 341 |
-
*
|
| 342 |
-
* @see \wp_list_pluck()
|
| 343 |
-
*/
|
| 344 |
-
public function pluck( $field );
|
| 345 |
-
|
| 346 |
-
/**
|
| 347 |
-
* Filters the results according to the specified criteria.
|
| 348 |
-
*
|
| 349 |
-
* This method will implicitly build and use a `WP_List_Util` instance on the return
|
| 350 |
-
* value of a call to the `all` method.
|
| 351 |
-
*
|
| 352 |
-
* @since 4.9.5
|
| 353 |
-
*
|
| 354 |
-
* @param array $args Optional. An array of key => value arguments to match
|
| 355 |
-
* against each object. Default empty array.
|
| 356 |
-
* @param string $operator Optional. The logical operation to perform. 'AND' means
|
| 357 |
-
* all elements from the array must match. 'OR' means only
|
| 358 |
-
* one element needs to match. 'NOT' means no elements may
|
| 359 |
-
* match. Default 'AND'.
|
| 360 |
-
*
|
| 361 |
-
* @return array An array of the filtered results.
|
| 362 |
-
*
|
| 363 |
-
* @see \wp_list_filter()
|
| 364 |
-
*/
|
| 365 |
-
public function filter( $args = array(), $operator = 'AND' );
|
| 366 |
-
|
| 367 |
-
/**
|
| 368 |
-
* Sorts the results according to the specified criteria.
|
| 369 |
-
*
|
| 370 |
-
* This method will implicitly build and use a `WP_List_Util` instance on the return
|
| 371 |
-
* value of a call to the `all` method.
|
| 372 |
-
*
|
| 373 |
-
* @since 4.9.5
|
| 374 |
-
*
|
| 375 |
-
* @param string|array $orderby Optional. Either the field name to order by or an array
|
| 376 |
-
* of multiple orderby fields as $orderby => $order.
|
| 377 |
-
* @param string $order Optional. Either 'ASC' or 'DESC'. Only used if $orderby
|
| 378 |
-
* is a string.
|
| 379 |
-
* @param bool $preserve_keys Optional. Whether to preserve keys. Default false.
|
| 380 |
-
*
|
| 381 |
-
* @return array An array of the sorted results.
|
| 382 |
-
*
|
| 383 |
-
* @see \wp_list_sort()
|
| 384 |
-
*/
|
| 385 |
-
public function sort( $orderby = array(), $order = 'ASC', $preserve_keys = false );
|
| 386 |
-
|
| 387 |
-
/**
|
| 388 |
-
* Builds a collection on the result of the `all()` method call.
|
| 389 |
-
*
|
| 390 |
-
* @since 4.9.5
|
| 391 |
-
*
|
| 392 |
-
* @return \Tribe__Utils__Post_Collection
|
| 393 |
-
*/
|
| 394 |
-
public function collect();
|
| 395 |
-
|
| 396 |
-
/**
|
| 397 |
-
* Gets the ids of the posts matching the query.
|
| 398 |
-
*
|
| 399 |
-
* @return array An array containing the post IDs to update.
|
| 400 |
-
*/
|
| 401 |
-
public function get_ids();
|
| 402 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
common/src/Tribe/Repository/Filter_Validation.php
DELETED
|
@@ -1,61 +0,0 @@
|
|
| 1 |
-
<?php
|
| 2 |
-
/**
|
| 3 |
-
* Provides methods to validate repository filters.
|
| 4 |
-
*
|
| 5 |
-
* @since 4.10.2
|
| 6 |
-
*
|
| 7 |
-
* @package Tribe\Repository
|
| 8 |
-
*/
|
| 9 |
-
|
| 10 |
-
namespace Tribe\Repository;
|
| 11 |
-
|
| 12 |
-
use Tribe__Repository__Usage_Error as Usage_Error;
|
| 13 |
-
use Tribe__Utils__Array as Arr;
|
| 14 |
-
|
| 15 |
-
trait Filter_Validation {
|
| 16 |
-
/**
|
| 17 |
-
* Checks the passed arguments to make sure they are the correct number and nature.
|
| 18 |
-
*
|
| 19 |
-
* This method requires the class using it to define a `static::$filter_args_map` property in the shape:
|
| 20 |
-
* ```
|
| 21 |
-
* [
|
| 22 |
-
* <filter> => [ <arg_name> => <arg_validation_callback> ]
|
| 23 |
-
* ]
|
| 24 |
-
* ```
|
| 25 |
-
*
|
| 26 |
-
* @since 4.10.2
|
| 27 |
-
*
|
| 28 |
-
* @param string $filter The name of the filter currently validating.
|
| 29 |
-
* @param array $call_args The current filter call args, usually `func_get_args()`.
|
| 30 |
-
*
|
| 31 |
-
* @throws Usage_Error If there is a definition for the filter and the argument count or nature is not correct.
|
| 32 |
-
*/
|
| 33 |
-
protected function ensure_args_for_filter( $filter, array $call_args ) {
|
| 34 |
-
$map = isset( static::$filter_args_map ) ? static::$filter_args_map : false;
|
| 35 |
-
|
| 36 |
-
if ( empty( $map ) ) {
|
| 37 |
-
return;
|
| 38 |
-
}
|
| 39 |
-
|
| 40 |
-
$required_args = Arr::get( $filter, $map, false );
|
| 41 |
-
|
| 42 |
-
if ( false === $required_args ) {
|
| 43 |
-
return;
|
| 44 |
-
}
|
| 45 |
-
|
| 46 |
-
if ( count( $required_args ) !== count( $call_args ) ) {
|
| 47 |
-
throw Usage_Error::because_filter_requires_args( $filter, array_keys( $required_args ) );
|
| 48 |
-
}
|
| 49 |
-
|
| 50 |
-
$iterator = new \MultipleIterator();
|
| 51 |
-
$iterator->attachIterator( new \ArrayIterator( array_keys( $required_args ) ) );
|
| 52 |
-
$iterator->attachIterator( new \ArrayIterator( array_values( $required_args ) ) );
|
| 53 |
-
$iterator->attachIterator( new \ArrayIterator( $call_args ) );
|
| 54 |
-
|
| 55 |
-
foreach ( $required_args as list( $arg_name, $validator, $input ) ) {
|
| 56 |
-
if ( empty( $validator( $input ) ) ) {
|
| 57 |
-
throw Usage_Error::because_filter_arg_is_not_valid( $filter, $arg_name );
|
| 58 |
-
}
|
| 59 |
-
}
|
| 60 |
-
}
|
| 61 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
common/src/Tribe/Repository/Interface.php
CHANGED
|
@@ -186,6 +186,13 @@ interface Tribe__Repository__Interface
|
|
| 186 |
*/
|
| 187 |
public function by_related_to_between( $by_meta_keys, $min, $max, $keys = null, $values = null );
|
| 188 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 189 |
/**
|
| 190 |
* Adds an entry to the repository filter schema.
|
| 191 |
*
|
| 186 |
*/
|
| 187 |
public function by_related_to_between( $by_meta_keys, $min, $max, $keys = null, $values = null );
|
| 188 |
|
| 189 |
+
/**
|
| 190 |
+
* Gets the ids of the posts matching the query.
|
| 191 |
+
*
|
| 192 |
+
* @return array An array containing the post IDs to update.
|
| 193 |
+
*/
|
| 194 |
+
public function get_ids();
|
| 195 |
+
|
| 196 |
/**
|
| 197 |
* Adds an entry to the repository filter schema.
|
| 198 |
*
|
common/src/Tribe/Repository/Query_Filters.php
CHANGED
|
@@ -7,13 +7,6 @@
|
|
| 7 |
*/
|
| 8 |
class Tribe__Repository__Query_Filters {
|
| 9 |
|
| 10 |
-
/**
|
| 11 |
-
* Indicates something has to happen "after" something else. The specific meaning is contextual.
|
| 12 |
-
*
|
| 13 |
-
* @since 4.9.21
|
| 14 |
-
*/
|
| 15 |
-
CONST AFTER = 'after:';
|
| 16 |
-
|
| 17 |
/**
|
| 18 |
* @var array
|
| 19 |
*/
|
|
@@ -700,42 +693,18 @@ class Tribe__Repository__Query_Filters {
|
|
| 700 |
*
|
| 701 |
* @since 4.9.5
|
| 702 |
* @since 4.9.14 Added the `$id` and `$override` parameters.
|
| 703 |
-
*
|
| 704 |
-
*
|
| 705 |
-
* @param string
|
| 706 |
-
*
|
| 707 |
-
* e.g. `[ '_meta_1' => 'ASC', '_meta_2' => 'DESC' ]`. If a simple array is
|
| 708 |
-
* passed, then the order will be set to the default one for each entry.
|
| 709 |
-
* This arguments supports the same formats of the `WP_Query` `orderby` argument.
|
| 710 |
-
* @param null|string $id Optional ORDER ID to prevent duplicating order-by clauses.
|
| 711 |
-
* @param boolean $override Whether to override the clause if another by the same ID exists.
|
| 712 |
-
* @param bool $after Whether to append the order by clause to the ones managed by WordPress or not.
|
| 713 |
-
* Defaults to `false`,to prepend them to the ones managed by WordPress.
|
| 714 |
*/
|
| 715 |
-
public function orderby( $orderby, $id = null, $override = false
|
| 716 |
-
$orderby_key = $after ? static::AFTER . 'orderby' : 'orderby';
|
| 717 |
-
$entries = [];
|
| 718 |
-
|
| 719 |
-
foreach ( (array) $orderby as $key => $value ) {
|
| 720 |
-
/*
|
| 721 |
-
* As WordPress does, we support "simple" entries, like `[ 'menu_order', 'post_date' ]` and entries in the
|
| 722 |
-
* shape `[ 'menu_order' => 'ASC', 'post_date' => 'DESC' ]`.
|
| 723 |
-
*/
|
| 724 |
-
$the_orderby = is_numeric( $key ) ? $value : $key;
|
| 725 |
-
$the_order = is_numeric( $key ) ? 'DESC' : $value;
|
| 726 |
-
|
| 727 |
-
$entries[] = [ $the_orderby, $the_order ];
|
| 728 |
-
}
|
| 729 |
-
|
| 730 |
-
$id = $id ?: 'default';
|
| 731 |
-
|
| 732 |
-
// Use the `$id` parameter to allow later method calls to replace values set in previous calls.
|
| 733 |
if ( $id ) {
|
| 734 |
-
if ( $override || ! isset( $this->query_vars[
|
| 735 |
-
$this->query_vars[
|
| 736 |
}
|
| 737 |
} else {
|
| 738 |
-
$this->query_vars[
|
| 739 |
}
|
| 740 |
|
| 741 |
if ( ! has_filter( 'posts_orderby', array( $this, 'filter_posts_orderby' ) ) ) {
|
|
@@ -973,46 +942,23 @@ class Tribe__Repository__Query_Filters {
|
|
| 973 |
*
|
| 974 |
* @since 4.9.5
|
| 975 |
*
|
| 976 |
-
* @param string $orderby
|
| 977 |
-
* @param WP_Query $query
|
| 978 |
*
|
| 979 |
-
* @return string
|
| 980 |
*/
|
| 981 |
public function filter_posts_orderby( $orderby, WP_Query $query ) {
|
| 982 |
if ( $query !== $this->current_query ) {
|
| 983 |
return $orderby;
|
| 984 |
}
|
| 985 |
|
| 986 |
-
if ( empty( $this->query_vars['orderby'] )
|
| 987 |
return $orderby;
|
| 988 |
}
|
| 989 |
|
| 990 |
-
$
|
| 991 |
-
|
| 992 |
-
/*
|
| 993 |
-
* Entries will be set, from the `orderby` method, to the `[ [ <orderby>, <order> ], [ <orderby>, <order> ] ]`
|
| 994 |
-
* format.
|
| 995 |
-
*/
|
| 996 |
-
$build_entry = static function ( $entries ) {
|
| 997 |
-
$buffer = [];
|
| 998 |
-
|
| 999 |
-
foreach ( $entries as list( $orderby, $order ) ) {
|
| 1000 |
-
$buffer[] = sprintf( '%s %s', $orderby, $order );
|
| 1001 |
-
}
|
| 1002 |
-
|
| 1003 |
-
return implode( ', ', $buffer );
|
| 1004 |
-
};
|
| 1005 |
-
|
| 1006 |
-
if ( ! empty( $this->query_vars['orderby'] ) ) {
|
| 1007 |
-
$before = implode( ', ', array_map( $build_entry, $this->query_vars['orderby'] ) );
|
| 1008 |
-
$frags = [ $before, $orderby ];
|
| 1009 |
-
}
|
| 1010 |
-
|
| 1011 |
-
if ( ! empty( $this->query_vars[ static::AFTER . 'orderby' ] ) ) {
|
| 1012 |
-
$frags[] = implode( ', ', array_map( $build_entry, $this->query_vars[ static::AFTER . 'orderby' ] ) );
|
| 1013 |
-
}
|
| 1014 |
|
| 1015 |
-
return implode( ', ', $
|
| 1016 |
}
|
| 1017 |
|
| 1018 |
/**
|
| 7 |
*/
|
| 8 |
class Tribe__Repository__Query_Filters {
|
| 9 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10 |
/**
|
| 11 |
* @var array
|
| 12 |
*/
|
| 693 |
*
|
| 694 |
* @since 4.9.5
|
| 695 |
* @since 4.9.14 Added the `$id` and `$override` parameters.
|
| 696 |
+
*
|
| 697 |
+
* @param string $orderby The order by criteria.
|
| 698 |
+
* @param null|string $id Optional ORDER ID to prevent duplicating order-by clauses..
|
| 699 |
+
* @param boolean $override Whether to override the clause if another by the same ID exists.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 700 |
*/
|
| 701 |
+
public function orderby( $orderby, $id = null , $override = false) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 702 |
if ( $id ) {
|
| 703 |
+
if ( $override || ! isset( $this->query_vars['orderby'][ $id ] ) ) {
|
| 704 |
+
$this->query_vars['orderby'][ $id ] = $orderby;
|
| 705 |
}
|
| 706 |
} else {
|
| 707 |
+
$this->query_vars['orderby'][] = $orderby;
|
| 708 |
}
|
| 709 |
|
| 710 |
if ( ! has_filter( 'posts_orderby', array( $this, 'filter_posts_orderby' ) ) ) {
|
| 942 |
*
|
| 943 |
* @since 4.9.5
|
| 944 |
*
|
| 945 |
+
* @param string $orderby
|
| 946 |
+
* @param WP_Query $query
|
| 947 |
*
|
| 948 |
+
* @return string
|
| 949 |
*/
|
| 950 |
public function filter_posts_orderby( $orderby, WP_Query $query ) {
|
| 951 |
if ( $query !== $this->current_query ) {
|
| 952 |
return $orderby;
|
| 953 |
}
|
| 954 |
|
| 955 |
+
if ( empty( $this->query_vars['orderby'] ) ) {
|
| 956 |
return $orderby;
|
| 957 |
}
|
| 958 |
|
| 959 |
+
$order = $query->get( 'order', 'ASC' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 960 |
|
| 961 |
+
return implode( ' ' . $order . ', ', $this->query_vars['orderby'] ) . ' ' . $order . ', ' . $orderby;
|
| 962 |
}
|
| 963 |
|
| 964 |
/**
|
common/src/Tribe/Repository/Read_Interface.php
CHANGED
|
@@ -1,14 +1,166 @@
|
|
| 1 |
<?php
|
| 2 |
|
| 3 |
-
use Tribe\Repository\Core_Read_Interface;
|
| 4 |
-
|
| 5 |
/**
|
| 6 |
* Interface Tribe__Repository__Read_Interface
|
| 7 |
*
|
| 8 |
-
*
|
| 9 |
* @since 4.7.19
|
| 10 |
*/
|
| 11 |
-
interface Tribe__Repository__Read_Interface extends Tribe__Repository__Setter_Interface
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 12 |
/**
|
| 13 |
* Sets the permission that should be used to get the posts.
|
| 14 |
*
|
|
@@ -21,6 +173,162 @@ interface Tribe__Repository__Read_Interface extends Tribe__Repository__Setter_In
|
|
| 21 |
*/
|
| 22 |
public function permission( $permission );
|
| 23 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 24 |
/**
|
| 25 |
* Fetches a single instance of the post type handled by the repository by
|
| 26 |
* the primary key.
|
|
@@ -170,4 +478,70 @@ interface Tribe__Repository__Read_Interface extends Tribe__Repository__Setter_In
|
|
| 170 |
* @return WP_Query A query object ready to return, and operate, on the posts.
|
| 171 |
*/
|
| 172 |
public function get_query_for_posts( array $posts );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 173 |
}
|
| 1 |
<?php
|
| 2 |
|
|
|
|
|
|
|
| 3 |
/**
|
| 4 |
* Interface Tribe__Repository__Read_Interface
|
| 5 |
*
|
|
|
|
| 6 |
* @since 4.7.19
|
| 7 |
*/
|
| 8 |
+
interface Tribe__Repository__Read_Interface extends Tribe__Repository__Setter_Interface {
|
| 9 |
+
/**
|
| 10 |
+
* Batch filter application method.
|
| 11 |
+
*
|
| 12 |
+
* This is the same as calling `by` multiple times with different arguments.
|
| 13 |
+
*
|
| 14 |
+
* @since 4.7.19
|
| 15 |
+
*
|
| 16 |
+
* @param array $args An associative array of arguments to filter
|
| 17 |
+
* the posts by in the shape [ <key>, <value> ]. * * @return Tribe__Repository__Read_Interface */
|
| 18 |
+
public function by_args( array $args );
|
| 19 |
+
|
| 20 |
+
/**
|
| 21 |
+
* Batch filter application method.
|
| 22 |
+
*
|
| 23 |
+
* This is the same as calling `where` multiple times with different arguments.
|
| 24 |
+
*
|
| 25 |
+
* T
|
| 26 |
+
|
| 27 |
+
/**
|
| 28 |
+
* Applies a filter to the query.
|
| 29 |
+
*
|
| 30 |
+
* While the signature only shows 2 arguments additional arguments will be passed
|
| 31 |
+
* to the schema filters.
|
| 32 |
+
*
|
| 33 |
+
* @since 4.7.19
|
| 34 |
+
*
|
| 35 |
+
* @param string $key
|
| 36 |
+
* @param mixed $value
|
| 37 |
+
* @param mixed ...$args Additional, optional, call arguments that will be passed to
|
| 38 |
+
* the schema.
|
| 39 |
+
*
|
| 40 |
+
* @return Tribe__Repository__Read_Interface
|
| 41 |
+
*/
|
| 42 |
+
public function by( $key, $value = null );
|
| 43 |
+
|
| 44 |
+
/**
|
| 45 |
+
* Just an alias of the `by` method to allow for easier reading.
|
| 46 |
+
*
|
| 47 |
+
* @since 4.7.19
|
| 48 |
+
*
|
| 49 |
+
* @param string $key
|
| 50 |
+
* @param mixed $value
|
| 51 |
+
*
|
| 52 |
+
* @return Tribe__Repository__Read_Interface
|
| 53 |
+
*/
|
| 54 |
+
public function where( $key, $value = null );
|
| 55 |
+
|
| 56 |
+
/**
|
| 57 |
+
* Sets the page of posts to fetch.
|
| 58 |
+
*
|
| 59 |
+
* Mind that this implementation does not support a `by( 'page', 2 )`
|
| 60 |
+
* filter to force more readable code.
|
| 61 |
+
*
|
| 62 |
+
* @since 4.7.19
|
| 63 |
+
*
|
| 64 |
+
* @param int $page
|
| 65 |
+
*
|
| 66 |
+
* @return Tribe__Repository__Read_Interface
|
| 67 |
+
*/
|
| 68 |
+
public function page( $page );
|
| 69 |
+
|
| 70 |
+
/**
|
| 71 |
+
* Sets the number of posts to retrieve per page.
|
| 72 |
+
*
|
| 73 |
+
* Mind that this implementation does not support a `by( 'per_page', 5 )`
|
| 74 |
+
* filter to force more readable code; by default posts per page is set to
|
| 75 |
+
* the pagination defaults for the post type.
|
| 76 |
+
*
|
| 77 |
+
* @param int $per_page
|
| 78 |
+
*
|
| 79 |
+
* @return Tribe__Repository__Read_Interface
|
| 80 |
+
*/
|
| 81 |
+
public function per_page( $per_page );
|
| 82 |
+
|
| 83 |
+
/**
|
| 84 |
+
* Returns the number of posts found matching the query.
|
| 85 |
+
*
|
| 86 |
+
* Mind that this value ignores the offset returning the
|
| 87 |
+
* number of results if limits where not applied.
|
| 88 |
+
*
|
| 89 |
+
* @since 4.7.19
|
| 90 |
+
*
|
| 91 |
+
* @return int
|
| 92 |
+
*/
|
| 93 |
+
public function found();
|
| 94 |
+
|
| 95 |
+
/**
|
| 96 |
+
* Returns all posts matching the query.
|
| 97 |
+
*
|
| 98 |
+
* Mind that "all" means "all the posts matching all the filters" so pagination applies.
|
| 99 |
+
*
|
| 100 |
+
* @return array
|
| 101 |
+
*/
|
| 102 |
+
public function all();
|
| 103 |
+
|
| 104 |
+
/**
|
| 105 |
+
* Sets the offset on the query.
|
| 106 |
+
*
|
| 107 |
+
* Mind that this implementation does not support a `by( 'offset', 2 )`
|
| 108 |
+
* filter to force more readable code.
|
| 109 |
+
*
|
| 110 |
+
* @since 4.7.19
|
| 111 |
+
*
|
| 112 |
+
* @param int $offset
|
| 113 |
+
* @param bool $increment Whether to increment the offset by the value
|
| 114 |
+
* or replace it.
|
| 115 |
+
*
|
| 116 |
+
* @return Tribe__Repository__Read_Interface
|
| 117 |
+
*/
|
| 118 |
+
public function offset( $offset, $increment = false );
|
| 119 |
+
|
| 120 |
+
/**
|
| 121 |
+
* Sets the order on the query.
|
| 122 |
+
*
|
| 123 |
+
* Mind that this implementation does not support a `by( 'order', 2 )`
|
| 124 |
+
* filter to force more readable code.
|
| 125 |
+
*
|
| 126 |
+
* @since 4.7.19
|
| 127 |
+
*
|
| 128 |
+
* @param string $order
|
| 129 |
+
*
|
| 130 |
+
* @return Tribe__Repository__Read_Interface
|
| 131 |
+
*/
|
| 132 |
+
public function order( $order = 'ASC' );
|
| 133 |
+
|
| 134 |
+
/**
|
| 135 |
+
* Sets the order criteria results should be fetched by.
|
| 136 |
+
*
|
| 137 |
+
* Mind that this implementation does not support a `by( 'order_by', 'title' )`
|
| 138 |
+
* filter to force more readable code.
|
| 139 |
+
*
|
| 140 |
+
* @since 4.7.19
|
| 141 |
+
*
|
| 142 |
+
* @param string $order_by The post field, custom field or alias key to order posts by.
|
| 143 |
+
* @param string $order The order direction; optional; shortcut for the `order` method; defaults
|
| 144 |
+
* to `DESC`.
|
| 145 |
+
*
|
| 146 |
+
* @return Tribe__Repository__Read_Interface
|
| 147 |
+
*/
|
| 148 |
+
public function order_by( $order_by, $order = 'DESC' );
|
| 149 |
+
|
| 150 |
+
/**
|
| 151 |
+
* Sets the fields that should be returned by the query.
|
| 152 |
+
*
|
| 153 |
+
* Mind that this implementation does not support a `by( 'fields', 'ids' )`
|
| 154 |
+
* filter to force more readable code.
|
| 155 |
+
*
|
| 156 |
+
* @since 4.7.19
|
| 157 |
+
*
|
| 158 |
+
* @param string $fields
|
| 159 |
+
*
|
| 160 |
+
* @return Tribe__Repository__Read_Interface
|
| 161 |
+
*/
|
| 162 |
+
public function fields( $fields );
|
| 163 |
+
|
| 164 |
/**
|
| 165 |
* Sets the permission that should be used to get the posts.
|
| 166 |
*
|
| 173 |
*/
|
| 174 |
public function permission( $permission );
|
| 175 |
|
| 176 |
+
/**
|
| 177 |
+
* Sugar method to set the `post__in` argument.
|
| 178 |
+
*
|
| 179 |
+
* Successive calls will stack, not replace each one.
|
| 180 |
+
*
|
| 181 |
+
* @since 4.7.19
|
| 182 |
+
*
|
| 183 |
+
* @param array|int $post_ids
|
| 184 |
+
*
|
| 185 |
+
* @return Tribe__Repository__Read_Interface
|
| 186 |
+
*/
|
| 187 |
+
public function in( $post_ids );
|
| 188 |
+
|
| 189 |
+
/**
|
| 190 |
+
* Sugar method to set the `post__not_in` argument.
|
| 191 |
+
*
|
| 192 |
+
* Successive calls will stack, not replace each one.
|
| 193 |
+
*
|
| 194 |
+
* @since 4.7.19
|
| 195 |
+
*
|
| 196 |
+
* @param array|int $post_ids
|
| 197 |
+
*
|
| 198 |
+
* @return Tribe__Repository__Read_Interface
|
| 199 |
+
*/
|
| 200 |
+
public function not_in( $post_ids );
|
| 201 |
+
|
| 202 |
+
/**
|
| 203 |
+
* Sugar method to set the `post_parent__in` argument.
|
| 204 |
+
*
|
| 205 |
+
* Successive calls will stack, not replace each one.
|
| 206 |
+
*
|
| 207 |
+
* @since 4.7.19
|
| 208 |
+
*
|
| 209 |
+
* @param array|int $post_id
|
| 210 |
+
*
|
| 211 |
+
* @return Tribe__Repository__Read_Interface
|
| 212 |
+
*/
|
| 213 |
+
public function parent( $post_id );
|
| 214 |
+
|
| 215 |
+
/**
|
| 216 |
+
* Sugar method to set the `post_parent__in` argument.
|
| 217 |
+
*
|
| 218 |
+
* Successive calls will stack, not replace each one.
|
| 219 |
+
*
|
| 220 |
+
* @since 4.7.19
|
| 221 |
+
*
|
| 222 |
+
* @param array $post_ids
|
| 223 |
+
*
|
| 224 |
+
* @return Tribe__Repository__Read_Interface
|
| 225 |
+
*/
|
| 226 |
+
public function parent_in( $post_ids );
|
| 227 |
+
|
| 228 |
+
/**
|
| 229 |
+
* Sugar method to set the `post_parent__not_in` argument.
|
| 230 |
+
*
|
| 231 |
+
* Successive calls will stack, not replace each one.
|
| 232 |
+
*
|
| 233 |
+
* @since 4.7.19
|
| 234 |
+
*
|
| 235 |
+
* @param array $post_ids
|
| 236 |
+
*
|
| 237 |
+
* @return Tribe__Repository__Read_Interface
|
| 238 |
+
*/
|
| 239 |
+
public function parent_not_in( $post_ids );
|
| 240 |
+
|
| 241 |
+
/**
|
| 242 |
+
* Sugar method to set the `s` argument.
|
| 243 |
+
*
|
| 244 |
+
* Successive calls will replace the search string.
|
| 245 |
+
* This is the default WordPress searh, to search by title,
|
| 246 |
+
* content or excerpt only use the `title`, `content`, `excerpt` filters.
|
| 247 |
+
*
|
| 248 |
+
* @param $search
|
| 249 |
+
*
|
| 250 |
+
* @return Tribe__Repository__Read_Interface
|
| 251 |
+
*/
|
| 252 |
+
public function search( $search );
|
| 253 |
+
|
| 254 |
+
/**
|
| 255 |
+
* Returns the number of posts found matching the query in the current page.
|
| 256 |
+
*
|
| 257 |
+
* While the `found` method will return the number of posts found
|
| 258 |
+
* across all pages this method will only return the number of
|
| 259 |
+
* posts found in the current page.
|
| 260 |
+
* Differently from the `found` method this method will apply the
|
| 261 |
+
* offset if set.
|
| 262 |
+
*
|
| 263 |
+
* @since 4.7.19
|
| 264 |
+
*
|
| 265 |
+
* @return int
|
| 266 |
+
*/
|
| 267 |
+
public function count();
|
| 268 |
+
|
| 269 |
+
/**
|
| 270 |
+
* Returns the first post of the page matching the current query.
|
| 271 |
+
*
|
| 272 |
+
* If, by default or because set with the `per_page` method, all
|
| 273 |
+
* posts matching the query should be returned then this will be
|
| 274 |
+
* the first post of all those matching the query.
|
| 275 |
+
*
|
| 276 |
+
* @since 4.7.19
|
| 277 |
+
*
|
| 278 |
+
* @return WP_Post|mixed|null
|
| 279 |
+
*
|
| 280 |
+
* @see Tribe__Repository__Read_Interface::per_page()
|
| 281 |
+
*/
|
| 282 |
+
public function first();
|
| 283 |
+
|
| 284 |
+
/**
|
| 285 |
+
* Returns the last post of the page matching the current query.
|
| 286 |
+
*
|
| 287 |
+
* If, by default or because set with the `per_page` method, all
|
| 288 |
+
* posts matching the query should be returned then this will be
|
| 289 |
+
* the last post of all those matching the query.
|
| 290 |
+
*
|
| 291 |
+
* @since 4.7.19
|
| 292 |
+
*
|
| 293 |
+
* @return WP_Post|mixed|null
|
| 294 |
+
*
|
| 295 |
+
* @see Tribe__Repository__Read_Interface::per_page()
|
| 296 |
+
*/
|
| 297 |
+
public function last();
|
| 298 |
+
|
| 299 |
+
/**
|
| 300 |
+
* Returns the nth post (1-based) of the page matching the current query.
|
| 301 |
+
*
|
| 302 |
+
* Being 1-based the second post can be fetched using `nth( 2 )`.
|
| 303 |
+
* If, by default or because set with the `per_page` method, all
|
| 304 |
+
* posts matching the query should be returned then this will be
|
| 305 |
+
* the nth post of all those matching the query.
|
| 306 |
+
*
|
| 307 |
+
* @since 4.7.19
|
| 308 |
+
*
|
| 309 |
+
* @param int $n
|
| 310 |
+
*
|
| 311 |
+
* @return WP_Post|mixed|null
|
| 312 |
+
*
|
| 313 |
+
* @see Tribe__Repository__Read_Interface::per_page()
|
| 314 |
+
*/
|
| 315 |
+
public function nth( $n );
|
| 316 |
+
|
| 317 |
+
/**
|
| 318 |
+
* Returns the first n posts of the page matching the current query.
|
| 319 |
+
*
|
| 320 |
+
* If, by default or because set with the `per_page` method, all
|
| 321 |
+
* posts matching the query should be returned then this method will
|
| 322 |
+
* return the first n posts of all those matching the query.
|
| 323 |
+
*
|
| 324 |
+
* @since 4.7.19
|
| 325 |
+
*
|
| 326 |
+
* @return array An array of posts matching the query.
|
| 327 |
+
*
|
| 328 |
+
* @see Tribe__Repository__Read_Interface::per_page()
|
| 329 |
+
*/
|
| 330 |
+
public function take( $n );
|
| 331 |
+
|
| 332 |
/**
|
| 333 |
* Fetches a single instance of the post type handled by the repository by
|
| 334 |
* the primary key.
|
| 478 |
* @return WP_Query A query object ready to return, and operate, on the posts.
|
| 479 |
*/
|
| 480 |
public function get_query_for_posts( array $posts );
|
| 481 |
+
|
| 482 |
+
/**
|
| 483 |
+
* Plucks a field from all results and returns it.
|
| 484 |
+
*
|
| 485 |
+
* This method will implicitly build and use a `WP_List_Util` instance on the return
|
| 486 |
+
* value of a call to the `all` method.
|
| 487 |
+
*
|
| 488 |
+
* @since 4.9.5
|
| 489 |
+
*
|
| 490 |
+
* @param string $field The field to pluck from each result.
|
| 491 |
+
*
|
| 492 |
+
* @return array An array of the plucked results.
|
| 493 |
+
*
|
| 494 |
+
* @see \wp_list_pluck()
|
| 495 |
+
*/
|
| 496 |
+
public function pluck( $field );
|
| 497 |
+
|
| 498 |
+
/**
|
| 499 |
+
* Filters the results according to the specified criteria.
|
| 500 |
+
*
|
| 501 |
+
* This method will implicitly build and use a `WP_List_Util` instance on the return
|
| 502 |
+
* value of a call to the `all` method.
|
| 503 |
+
*
|
| 504 |
+
* @since 4.9.5
|
| 505 |
+
*
|
| 506 |
+
* @param array $args Optional. An array of key => value arguments to match
|
| 507 |
+
* against each object. Default empty array.
|
| 508 |
+
* @param string $operator Optional. The logical operation to perform. 'AND' means
|
| 509 |
+
* all elements from the array must match. 'OR' means only
|
| 510 |
+
* one element needs to match. 'NOT' means no elements may
|
| 511 |
+
* match. Default 'AND'.
|
| 512 |
+
*
|
| 513 |
+
* @return array An array of the filtered results.
|
| 514 |
+
*
|
| 515 |
+
* @see \wp_list_filter()
|
| 516 |
+
*/
|
| 517 |
+
public function filter( $args = array(), $operator = 'AND' );
|
| 518 |
+
|
| 519 |
+
/**
|
| 520 |
+
* Sorts the results according to the specified criteria.
|
| 521 |
+
*
|
| 522 |
+
* This method will implicitly build and use a `WP_List_Util` instance on the return
|
| 523 |
+
* value of a call to the `all` method.
|
| 524 |
+
*
|
| 525 |
+
* @since 4.9.5
|
| 526 |
+
*
|
| 527 |
+
* @param string|array $orderby Optional. Either the field name to order by or an array
|
| 528 |
+
* of multiple orderby fields as $orderby => $order.
|
| 529 |
+
* @param string $order Optional. Either 'ASC' or 'DESC'. Only used if $orderby
|
| 530 |
+
* is a string.
|
| 531 |
+
* @param bool $preserve_keys Optional. Whether to preserve keys. Default false.
|
| 532 |
+
*
|
| 533 |
+
* @return array An array of the sorted results.
|
| 534 |
+
*
|
| 535 |
+
* @see \wp_list_sort()
|
| 536 |
+
*/
|
| 537 |
+
public function sort( $orderby = array(), $order = 'ASC', $preserve_keys = false );
|
| 538 |
+
|
| 539 |
+
/**
|
| 540 |
+
* Builds a collection on the result of the `all()` method call.
|
| 541 |
+
*
|
| 542 |
+
* @since 4.9.5
|
| 543 |
+
*
|
| 544 |
+
* @return \Tribe__Utils__Post_Collection
|
| 545 |
+
*/
|
| 546 |
+
public function collect();
|
| 547 |
}
|
common/src/Tribe/Repository/Usage_Error.php
CHANGED
|
@@ -244,45 +244,4 @@ class Tribe__Repository__Usage_Error extends Exception {
|
|
| 244 |
public static function because_query_cannot_be_set_after_it_ran() {
|
| 245 |
return new self( "You are trying to set the repository query after it ran!" );
|
| 246 |
}
|
| 247 |
-
|
| 248 |
-
/**
|
| 249 |
-
* Indicates the client code is trying to call a filter without the correct number of req. parameters.
|
| 250 |
-
*
|
| 251 |
-
* @since 4.10.2
|
| 252 |
-
*
|
| 253 |
-
* @param string $filter The called filter.
|
| 254 |
-
* @param array $required_args The human-readable name of the required arguments.
|
| 255 |
-
*
|
| 256 |
-
* @return static A ready to throw instance of the class.
|
| 257 |
-
*/
|
| 258 |
-
public static function because_filter_requires_args( $filter, array $required_args ) {
|
| 259 |
-
return new static(
|
| 260 |
-
sprintf(
|
| 261 |
-
'The "%s" filter requires %d arguments: %s',
|
| 262 |
-
$filter,
|
| 263 |
-
count( $required_args ),
|
| 264 |
-
implode( ', ', $required_args )
|
| 265 |
-
)
|
| 266 |
-
);
|
| 267 |
-
}
|
| 268 |
-
|
| 269 |
-
/**
|
| 270 |
-
* Indicates the client code is trying to call a filter with an invalid parameter.
|
| 271 |
-
*
|
| 272 |
-
* @since 4.10.2
|
| 273 |
-
*
|
| 274 |
-
* @param string $filter The called filter.
|
| 275 |
-
* @param string $arg_name The human-readable name of the parameter.
|
| 276 |
-
*
|
| 277 |
-
* @return static A ready to throw instance of the class.
|
| 278 |
-
*/
|
| 279 |
-
public static function because_filter_arg_is_not_valid( $filter, $arg_name ) {
|
| 280 |
-
return new static(
|
| 281 |
-
sprintf(
|
| 282 |
-
'The "%s" filter "%s" argument is not valid.',
|
| 283 |
-
$filter,
|
| 284 |
-
$arg_name
|
| 285 |
-
)
|
| 286 |
-
);
|
| 287 |
-
}
|
| 288 |
}
|
| 244 |
public static function because_query_cannot_be_set_after_it_ran() {
|
| 245 |
return new self( "You are trying to set the repository query after it ran!" );
|
| 246 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 247 |
}
|
common/src/Tribe/Rewrite.php
CHANGED
|
@@ -26,14 +26,6 @@ class Tribe__Rewrite {
|
|
| 26 |
* @var static
|
| 27 |
*/
|
| 28 |
public static $instance;
|
| 29 |
-
/**
|
| 30 |
-
* A delimiter used to separate a localized matcher from its base in the format `<loc_matcher><delim><base>`.
|
| 31 |
-
*
|
| 32 |
-
* @since 4.11.5
|
| 33 |
-
*
|
| 34 |
-
* @var string
|
| 35 |
-
*/
|
| 36 |
-
protected static $localized_matcher_delimiter = '~';
|
| 37 |
|
| 38 |
/**
|
| 39 |
* WP_Rewrite Instance
|
|
@@ -197,17 +189,6 @@ class Tribe__Rewrite {
|
|
| 197 |
remove_action( 'shutdown', [ $this, 'dump_cache' ] );
|
| 198 |
}
|
| 199 |
|
| 200 |
-
/**
|
| 201 |
-
* Determines if we have plain permalink.
|
| 202 |
-
*
|
| 203 |
-
* @since 4.11.2
|
| 204 |
-
*
|
| 205 |
-
* @return bool If we use plain permalink or not.
|
| 206 |
-
*/
|
| 207 |
-
public static function is_plain_permalink() {
|
| 208 |
-
return tribe_context()->is( 'plain_permalink' );
|
| 209 |
-
}
|
| 210 |
-
|
| 211 |
/**
|
| 212 |
* Get the base slugs for the rewrite rules.
|
| 213 |
*
|
|
@@ -426,11 +407,8 @@ class Tribe__Rewrite {
|
|
| 426 |
$query = (string) parse_url( $url, PHP_URL_QUERY );
|
| 427 |
wp_parse_str( $query, $query_vars );
|
| 428 |
|
| 429 |
-
//
|
| 430 |
-
$query_vars = array_filter( $query_vars, 'is_scalar' );
|
| 431 |
-
|
| 432 |
if ( isset( $query_vars['paged'] ) && 1 === (int) $query_vars['paged'] ) {
|
| 433 |
-
// Remove the `paged` query var if it's 1.
|
| 434 |
unset( $query_vars['paged'] );
|
| 435 |
}
|
| 436 |
|
|
@@ -438,16 +416,10 @@ class Tribe__Rewrite {
|
|
| 438 |
|
| 439 |
$our_rules = $this->get_handled_rewrite_rules();
|
| 440 |
$handled_query_vars = $this->get_rules_query_vars( $our_rules );
|
| 441 |
-
$handled_post_types = $this->get_post_types();
|
| 442 |
|
| 443 |
if (
|
| 444 |
-
// The rules we handle should not be empty.
|
| 445 |
empty( $our_rules )
|
| 446 |
-
|| ! (
|
| 447 |
-
// Supported post types should be either keys or values, of the `post_type` argument, in the query vars.
|
| 448 |
-
count( array_intersect_key( array_flip( $handled_post_types ), $query_vars ) )
|
| 449 |
-
|| in_array( Arr::get( $query_vars, 'post_type', 'post' ), $handled_post_types, true )
|
| 450 |
-
)
|
| 451 |
) {
|
| 452 |
$wp_canonical = redirect_canonical( $canonical_url, false );
|
| 453 |
if ( empty( $wp_canonical ) ) {
|
|
@@ -513,38 +485,16 @@ class Tribe__Rewrite {
|
|
| 513 |
return '';
|
| 514 |
}
|
| 515 |
|
| 516 |
-
if ( isset( $localized_matcher['localized_slug'] ) ) {
|
| 517 |
-
// If available, then return the localized slug instead of inferring it as we do below.
|
| 518 |
-
return $localized_matcher['localized_slug'];
|
| 519 |
-
}
|
| 520 |
-
|
| 521 |
/*
|
| 522 |
* We use `end` as, by default, the localized version of the slug in the current language will be at the
|
| 523 |
* end of the array.
|
|
|
|
| 524 |
*/
|
| 525 |
return end( $localized_matcher['localized_slugs'] );
|
| 526 |
}, $localized_matchers );
|
| 527 |
|
| 528 |
// Include dynamic matchers now.
|
| 529 |
$replace = array_merge( $dynamic_matchers, $replace );
|
| 530 |
-
|
| 531 |
-
/*
|
| 532 |
-
* Prune from the replacements the empty values. This will resolve conflicts (e.g. single and archive w/
|
| 533 |
-
* same slug) as no two can be true at the same time.
|
| 534 |
-
* Remove the `<delim><base>` prefix added to localized matchers, if any.
|
| 535 |
-
*/
|
| 536 |
-
$replace = array_filter( $replace );
|
| 537 |
-
$replace = array_combine(
|
| 538 |
-
array_map( static function ( $key ) {
|
| 539 |
-
return preg_replace(
|
| 540 |
-
'/' . preg_quote( Tribe__Rewrite::$localized_matcher_delimiter ) . '\\w*$/',
|
| 541 |
-
'',
|
| 542 |
-
$key
|
| 543 |
-
);
|
| 544 |
-
}, array_keys( $replace ) ),
|
| 545 |
-
$replace
|
| 546 |
-
);
|
| 547 |
-
|
| 548 |
$replaced = str_replace( array_keys( $replace ), $replace, $link_template );
|
| 549 |
|
| 550 |
// Remove trailing chars.
|
|
@@ -600,45 +550,21 @@ class Tribe__Rewrite {
|
|
| 600 |
* @return array An array of rewrite rules handled by the implementation in the shape `[ <regex> => <path> ]`.
|
| 601 |
*/
|
| 602 |
protected function get_handled_rewrite_rules() {
|
| 603 |
-
static $cache_var_name = __METHOD__;
|
| 604 |
-
|
| 605 |
-
$our_rules = tribe_get_var( $cache_var_name, null );
|
| 606 |
-
|
| 607 |
// We need to make sure we are have WP_Rewrite setup
|
| 608 |
if ( ! $this->rewrite ) {
|
| 609 |
$this->setup();
|
| 610 |
}
|
| 611 |
|
| 612 |
-
|
| 613 |
-
|
| 614 |
-
|
| 615 |
-
|
| 616 |
-
|
| 617 |
-
|
| 618 |
-
|
| 619 |
-
|
| 620 |
-
return preg_match( $pattern, $rule_query_string );
|
| 621 |
-
}
|
| 622 |
-
);
|
| 623 |
-
|
| 624 |
-
tribe_set_var( $cache_var_name, $our_rules );
|
| 625 |
-
}
|
| 626 |
-
|
| 627 |
-
/**
|
| 628 |
-
* Filters the list of rewrite rules handled by our code to add or remove some as required.
|
| 629 |
-
*
|
| 630 |
-
* @since 4.9.18
|
| 631 |
-
*
|
| 632 |
-
* @param array $our_rules An array of rewrite rules handled by our code, in the shape
|
| 633 |
-
* `[ <rewrite_rule_regex_pattern> => <query_string> ]`.
|
| 634 |
-
* E.g. `[ '(?:events)/(?:list)/?$' => 'index.php?post_type=tribe_events&eventDisplay=list' ]`.
|
| 635 |
-
* @param array<string,string> All the current rewrite rules, before any filtering is applied; these have the
|
| 636 |
-
* same `<pattern => rewrite >` format as the previous argument, which is the
|
| 637 |
-
* format used by WordPress rewrite rules.
|
| 638 |
-
*/
|
| 639 |
-
$our_rules = apply_filters( 'tribe_rewrite_handled_rewrite_rules', $our_rules, $all_rules );
|
| 640 |
|
| 641 |
-
return $
|
| 642 |
}
|
| 643 |
|
| 644 |
/**
|
|
@@ -649,25 +575,13 @@ class Tribe__Rewrite {
|
|
| 649 |
* @return array A map of localized regex matchers in the shape `[ <localized_regex> => <query_var> ]`.
|
| 650 |
*/
|
| 651 |
protected function get_localized_matchers() {
|
| 652 |
-
static $cache_var_name = __METHOD__;
|
| 653 |
-
|
| 654 |
$bases = (array) $this->get_bases();
|
| 655 |
-
|
| 656 |
$query_var_map = $this->get_matcher_to_query_var_map();
|
| 657 |
|
| 658 |
-
$localized_matchers =
|
| 659 |
-
|
| 660 |
foreach ( $bases as $base => $localized_matcher ) {
|
| 661 |
-
// Use the base too to allow possible conflicts if the slugs are the same for single and archive.
|
| 662 |
-
$localized_matcher_key = $localized_matcher . static::$localized_matcher_delimiter . $base;
|
| 663 |
-
|
| 664 |
-
if ( isset( $localized_matchers[ $localized_matcher_key ] ) ) {
|
| 665 |
-
continue;
|
| 666 |
-
}
|
| 667 |
-
|
| 668 |
if ( isset( $query_var_map[ $base ] ) ) {
|
| 669 |
-
$localized_matchers[ $
|
| 670 |
-
'base' => $base,
|
| 671 |
'query_var' => $query_var_map[ $base ],
|
| 672 |
'en_slug' => $base,
|
| 673 |
'localized_slugs' => [ $base ],
|
|
@@ -677,7 +591,7 @@ class Tribe__Rewrite {
|
|
| 677 |
if ( ! empty( $buffer['slugs'] ) ) {
|
| 678 |
$slugs = explode( '|', $buffer['slugs'] );
|
| 679 |
|
| 680 |
-
$localized_matchers[ $
|
| 681 |
static function ( $localized_slug ) {
|
| 682 |
return str_replace( '\-', '-', $localized_slug );
|
| 683 |
},
|
|
@@ -685,18 +599,16 @@ class Tribe__Rewrite {
|
|
| 685 |
);
|
| 686 |
|
| 687 |
// The English version is the first.
|
| 688 |
-
$localized_matchers[ $
|
| 689 |
}
|
| 690 |
}
|
| 691 |
}
|
| 692 |
|
| 693 |
-
tribe_set_var( $cache_var_name, $localized_matchers );
|
| 694 |
-
|
| 695 |
return $localized_matchers;
|
| 696 |
}
|
| 697 |
|
| 698 |
/**
|
| 699 |
-
* Returns a map relating
|
| 700 |
*
|
| 701 |
* @since 4.9.11
|
| 702 |
*
|
|
@@ -718,33 +630,13 @@ class Tribe__Rewrite {
|
|
| 718 |
* @return array A list of all the query vars handled in the rules.
|
| 719 |
*/
|
| 720 |
protected function get_rules_query_vars( array $rules ) {
|
| 721 |
-
|
| 722 |
-
|
| 723 |
-
|
| 724 |
-
$cache_key = md5( json_encode( $rules ) );
|
| 725 |
-
|
| 726 |
-
if ( ! isset( $cached_rules[ $cache_key ] ) ) {
|
| 727 |
-
$cached_rules[ $cache_key ] = array_unique(
|
| 728 |
-
array_filter(
|
| 729 |
-
array_merge(
|
| 730 |
-
[],
|
| 731 |
-
...array_values(
|
| 732 |
-
array_map(
|
| 733 |
-
static function ( $rule_string ) {
|
| 734 |
-
wp_parse_str( parse_url( $rule_string, PHP_URL_QUERY ), $vars );
|
| 735 |
-
return array_keys( $vars );
|
| 736 |
-
},
|
| 737 |
-
$rules
|
| 738 |
-
)
|
| 739 |
-
)
|
| 740 |
-
)
|
| 741 |
-
)
|
| 742 |
-
);
|
| 743 |
|
| 744 |
-
|
| 745 |
-
|
| 746 |
-
|
| 747 |
-
return $cached_rules[ $cache_key ];
|
| 748 |
}
|
| 749 |
|
| 750 |
/**
|
|
@@ -809,8 +701,6 @@ class Tribe__Rewrite {
|
|
| 809 |
* Returns a list of post types supported by the implementation.
|
| 810 |
*
|
| 811 |
* @since 4.9.11
|
| 812 |
-
*
|
| 813 |
-
* @return array<string> An array of post types supported and handled by the rewrite implementation.
|
| 814 |
*/
|
| 815 |
protected function get_post_types() {
|
| 816 |
throw new BadMethodCallException( 'Method get_post_types should be implemented by extending classes.' );
|
|
@@ -1018,11 +908,6 @@ class Tribe__Rewrite {
|
|
| 1018 |
$query_vars = array_merge( $url_query_vars, $query_vars );
|
| 1019 |
}
|
| 1020 |
|
| 1021 |
-
// Prune the query vars to drop the empty `page` or `paged` ones.
|
| 1022 |
-
$query_vars = array_filter( $query_vars, static function ( $value, $key ) {
|
| 1023 |
-
return ! in_array( $key, [ 'paged', 'page' ] ) || (int) $value !== 0;
|
| 1024 |
-
}, ARRAY_FILTER_USE_BOTH );
|
| 1025 |
-
|
| 1026 |
/**
|
| 1027 |
* Filters the array of parsed query variables after the class logic has been applied to it.
|
| 1028 |
*
|
|
@@ -1078,7 +963,7 @@ class Tribe__Rewrite {
|
|
| 1078 |
return home_url();
|
| 1079 |
}
|
| 1080 |
|
| 1081 |
-
$clean = $this->get_canonical_url( add_query_arg( $parsed_vars, home_url(
|
| 1082 |
|
| 1083 |
$this->clean_url_cache[ $url ] = $clean;
|
| 1084 |
|
| 26 |
* @var static
|
| 27 |
*/
|
| 28 |
public static $instance;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 29 |
|
| 30 |
/**
|
| 31 |
* WP_Rewrite Instance
|
| 189 |
remove_action( 'shutdown', [ $this, 'dump_cache' ] );
|
| 190 |
}
|
| 191 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 192 |
/**
|
| 193 |
* Get the base slugs for the rewrite rules.
|
| 194 |
*
|
| 407 |
$query = (string) parse_url( $url, PHP_URL_QUERY );
|
| 408 |
wp_parse_str( $query, $query_vars );
|
| 409 |
|
| 410 |
+
// Remove the `paged` query var if it's 1.
|
|
|
|
|
|
|
| 411 |
if ( isset( $query_vars['paged'] ) && 1 === (int) $query_vars['paged'] ) {
|
|
|
|
| 412 |
unset( $query_vars['paged'] );
|
| 413 |
}
|
| 414 |
|
| 416 |
|
| 417 |
$our_rules = $this->get_handled_rewrite_rules();
|
| 418 |
$handled_query_vars = $this->get_rules_query_vars( $our_rules );
|
|
|
|
| 419 |
|
| 420 |
if (
|
|
|
|
| 421 |
empty( $our_rules )
|
| 422 |
+
|| ! in_array( Arr::get( $query_vars, 'post_type', 'post' ), $this->get_post_types(), true )
|
|
|
|
|
|
|
|
|
|
|
|
|
| 423 |
) {
|
| 424 |
$wp_canonical = redirect_canonical( $canonical_url, false );
|
| 425 |
if ( empty( $wp_canonical ) ) {
|
| 485 |
return '';
|
| 486 |
}
|
| 487 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 488 |
/*
|
| 489 |
* We use `end` as, by default, the localized version of the slug in the current language will be at the
|
| 490 |
* end of the array.
|
| 491 |
+
* @todo here we should keep a map, that has to generated at permalink flush time, to map locales/slugs.
|
| 492 |
*/
|
| 493 |
return end( $localized_matcher['localized_slugs'] );
|
| 494 |
}, $localized_matchers );
|
| 495 |
|
| 496 |
// Include dynamic matchers now.
|
| 497 |
$replace = array_merge( $dynamic_matchers, $replace );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 498 |
$replaced = str_replace( array_keys( $replace ), $replace, $link_template );
|
| 499 |
|
| 500 |
// Remove trailing chars.
|
| 550 |
* @return array An array of rewrite rules handled by the implementation in the shape `[ <regex> => <path> ]`.
|
| 551 |
*/
|
| 552 |
protected function get_handled_rewrite_rules() {
|
|
|
|
|
|
|
|
|
|
|
|
|
| 553 |
// We need to make sure we are have WP_Rewrite setup
|
| 554 |
if ( ! $this->rewrite ) {
|
| 555 |
$this->setup();
|
| 556 |
}
|
| 557 |
|
| 558 |
+
// While this is specific to The Events Calendar we're handling a small enough post type base to keep it here.
|
| 559 |
+
$pattern = '/post_type=tribe_(events|venue|organizer)/';
|
| 560 |
+
// Reverse the rules to try and match the most complex first.
|
| 561 |
+
$rules = isset( $this->rewrite->rules ) ? (array) $this->rewrite->rules : [];
|
| 562 |
+
$handled_rewrite_rules = array_filter( $rules,
|
| 563 |
+
static function ( $rule_query_string ) use ( $pattern ) {
|
| 564 |
+
return preg_match( $pattern, $rule_query_string );
|
| 565 |
+
} );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 566 |
|
| 567 |
+
return $handled_rewrite_rules;
|
| 568 |
}
|
| 569 |
|
| 570 |
/**
|
| 575 |
* @return array A map of localized regex matchers in the shape `[ <localized_regex> => <query_var> ]`.
|
| 576 |
*/
|
| 577 |
protected function get_localized_matchers() {
|
|
|
|
|
|
|
| 578 |
$bases = (array) $this->get_bases();
|
|
|
|
| 579 |
$query_var_map = $this->get_matcher_to_query_var_map();
|
| 580 |
|
| 581 |
+
$localized_matchers = [];
|
|
|
|
| 582 |
foreach ( $bases as $base => $localized_matcher ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 583 |
if ( isset( $query_var_map[ $base ] ) ) {
|
| 584 |
+
$localized_matchers[ $localized_matcher ] = [
|
|
|
|
| 585 |
'query_var' => $query_var_map[ $base ],
|
| 586 |
'en_slug' => $base,
|
| 587 |
'localized_slugs' => [ $base ],
|
| 591 |
if ( ! empty( $buffer['slugs'] ) ) {
|
| 592 |
$slugs = explode( '|', $buffer['slugs'] );
|
| 593 |
|
| 594 |
+
$localized_matchers[ $localized_matcher ]['localized_slugs'] = array_map(
|
| 595 |
static function ( $localized_slug ) {
|
| 596 |
return str_replace( '\-', '-', $localized_slug );
|
| 597 |
},
|
| 599 |
);
|
| 600 |
|
| 601 |
// The English version is the first.
|
| 602 |
+
$localized_matchers[ $localized_matcher ]['en_slug'] = reset( $slugs );
|
| 603 |
}
|
| 604 |
}
|
| 605 |
}
|
| 606 |
|
|
|
|
|
|
|
| 607 |
return $localized_matchers;
|
| 608 |
}
|
| 609 |
|
| 610 |
/**
|
| 611 |
+
* Returns a map relating localize matcher slugs to the corresponding query var.
|
| 612 |
*
|
| 613 |
* @since 4.9.11
|
| 614 |
*
|
| 630 |
* @return array A list of all the query vars handled in the rules.
|
| 631 |
*/
|
| 632 |
protected function get_rules_query_vars( array $rules ) {
|
| 633 |
+
return array_unique( array_filter( array_merge( [], ...
|
| 634 |
+
array_values( array_map( static function ( $rule_string ) {
|
| 635 |
+
wp_parse_str( parse_url( $rule_string, PHP_URL_QUERY ), $vars );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 636 |
|
| 637 |
+
return array_keys( $vars );
|
| 638 |
+
}, $rules ) ) ) )
|
| 639 |
+
);
|
|
|
|
| 640 |
}
|
| 641 |
|
| 642 |
/**
|
| 701 |
* Returns a list of post types supported by the implementation.
|
| 702 |
*
|
| 703 |
* @since 4.9.11
|
|
|
|
|
|
|
| 704 |
*/
|
| 705 |
protected function get_post_types() {
|
| 706 |
throw new BadMethodCallException( 'Method get_post_types should be implemented by extending classes.' );
|
| 908 |
$query_vars = array_merge( $url_query_vars, $query_vars );
|
| 909 |
}
|
| 910 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 911 |
/**
|
| 912 |
* Filters the array of parsed query variables after the class logic has been applied to it.
|
| 913 |
*
|
| 963 |
return home_url();
|
| 964 |
}
|
| 965 |
|
| 966 |
+
$clean = $this->get_canonical_url( add_query_arg( $parsed_vars, home_url() ) );
|
| 967 |
|
| 968 |
$this->clean_url_cache[ $url ] = $clean;
|
| 969 |
|
common/src/Tribe/Service_Providers/Debug_Bar.php
CHANGED
|
@@ -1,5 +1,4 @@
|
|
| 1 |
<?php
|
| 2 |
-
|
| 3 |
/**
|
| 4 |
* Hooks and manages the plugins Debug Bar integrations.
|
| 5 |
*
|
|
@@ -35,7 +34,6 @@ class Tribe__Service_Providers__Debug_Bar extends tad_DI52_ServiceProvider {
|
|
| 35 |
*/
|
| 36 |
$tribe_panels = apply_filters( 'tribe_debug_bar_panels', array(
|
| 37 |
new Tribe__Debug_Bar__Panels__Context(),
|
| 38 |
-
new Tribe__Debug_Bar__Panels__Json_Ld(),
|
| 39 |
) );
|
| 40 |
|
| 41 |
if ( count( $tribe_panels ) > 0 ) {
|
| 1 |
<?php
|
|
|
|
| 2 |
/**
|
| 3 |
* Hooks and manages the plugins Debug Bar integrations.
|
| 4 |
*
|
| 34 |
*/
|
| 35 |
$tribe_panels = apply_filters( 'tribe_debug_bar_panels', array(
|
| 36 |
new Tribe__Debug_Bar__Panels__Context(),
|
|
|
|
| 37 |
) );
|
| 38 |
|
| 39 |
if ( count( $tribe_panels ) > 0 ) {
|
common/src/Tribe/Service_Providers/Dialog.php
DELETED
|
@@ -1,110 +0,0 @@
|
|
| 1 |
-
<?php
|
| 2 |
-
|
| 3 |
-
namespace Tribe\Service_Providers;
|
| 4 |
-
|
| 5 |
-
/**
|
| 6 |
-
* Class Dialog
|
| 7 |
-
*
|
| 8 |
-
* @since 4.10.0
|
| 9 |
-
*
|
| 10 |
-
* Handles the registration and creation of our async process handlers.
|
| 11 |
-
*/
|
| 12 |
-
class Dialog extends \tad_DI52_ServiceProvider {
|
| 13 |
-
|
| 14 |
-
/**
|
| 15 |
-
* Binds and sets up implementations.
|
| 16 |
-
*
|
| 17 |
-
* @since 4.10.0
|
| 18 |
-
*/
|
| 19 |
-
public function register() {
|
| 20 |
-
tribe_singleton( 'dialog.view', '\Tribe\Dialog\View' );
|
| 21 |
-
|
| 22 |
-
/**
|
| 23 |
-
* Allows plugins to hook into the register action to register views, etc
|
| 24 |
-
*
|
| 25 |
-
* @since 4.10.0
|
| 26 |
-
*
|
| 27 |
-
* @param Tribe\Service_Providers\Dialog $dialog
|
| 28 |
-
*/
|
| 29 |
-
do_action( 'tribe_dialog_register', $this );
|
| 30 |
-
|
| 31 |
-
$this->hooks();
|
| 32 |
-
}
|
| 33 |
-
|
| 34 |
-
/**
|
| 35 |
-
* Set up hooks for classes.
|
| 36 |
-
*
|
| 37 |
-
* @since 4.10.0
|
| 38 |
-
*/
|
| 39 |
-
private function hooks() {
|
| 40 |
-
add_action( 'tribe_common_loaded', [ $this, 'register_dialog_assets' ] );
|
| 41 |
-
add_filter( 'tribe_template_public_namespace', [ $this, 'template_public_namespace' ], 10, 2 );
|
| 42 |
-
|
| 43 |
-
/**
|
| 44 |
-
* Allows plugins to hook into the hooks action to register their own hooks
|
| 45 |
-
*
|
| 46 |
-
* @since 4.10.0
|
| 47 |
-
*
|
| 48 |
-
* @param Tribe\Service_Providers\Dialog $dialog
|
| 49 |
-
*/
|
| 50 |
-
do_action( 'tribe_dialog_hooks', $this );
|
| 51 |
-
}
|
| 52 |
-
|
| 53 |
-
/**
|
| 54 |
-
* {@inheritdoc}
|
| 55 |
-
*
|
| 56 |
-
* @since 4.10.0
|
| 57 |
-
*/
|
| 58 |
-
public function template_public_namespace( $namespace, $obj ) {
|
| 59 |
-
if ( ! empty( $obj->template_namespace ) && 'dialog' === $obj->template_namespace ) {
|
| 60 |
-
array_push( $namespace, 'dialog' );
|
| 61 |
-
}
|
| 62 |
-
|
| 63 |
-
return $namespace;
|
| 64 |
-
}
|
| 65 |
-
|
| 66 |
-
/**
|
| 67 |
-
* Register assets associated with dialog
|
| 68 |
-
*
|
| 69 |
-
* @since 4.10.0
|
| 70 |
-
*/
|
| 71 |
-
public function register_dialog_assets() {
|
| 72 |
-
$main = \Tribe__Main::instance();
|
| 73 |
-
|
| 74 |
-
tribe_asset(
|
| 75 |
-
$main,
|
| 76 |
-
'tribe-dialog',
|
| 77 |
-
'dialog.css',
|
| 78 |
-
[],
|
| 79 |
-
[],
|
| 80 |
-
[ 'groups' => 'tribe-dialog' ]
|
| 81 |
-
);
|
| 82 |
-
|
| 83 |
-
tribe_asset(
|
| 84 |
-
$main,
|
| 85 |
-
'mt-a11y-dialog',
|
| 86 |
-
'vendor/faction23/a11y-dialog/a11y-dialog.js',
|
| 87 |
-
[ 'underscore', 'tribe-common' ],
|
| 88 |
-
[],
|
| 89 |
-
[ 'groups' => 'tribe-dialog' ]
|
| 90 |
-
);
|
| 91 |
-
|
| 92 |
-
tribe_asset(
|
| 93 |
-
$main,
|
| 94 |
-
'tribe-dialog-js',
|
| 95 |
-
'dialog.js',
|
| 96 |
-
[ 'mt-a11y-dialog' ],
|
| 97 |
-
[],
|
| 98 |
-
[ 'groups' => 'tribe-dialog' ]
|
| 99 |
-
);
|
| 100 |
-
|
| 101 |
-
/**
|
| 102 |
-
* Allows plugins to hook into the assets action to register their own assets
|
| 103 |
-
*
|
| 104 |
-
* @since 4.10.0
|
| 105 |
-
*
|
| 106 |
-
* @param Tribe\Service_Providers\Dialog $dialog
|
| 107 |
-
*/
|
| 108 |
-
do_action( 'tribe_dialog_assets_registered', $this );
|
| 109 |
-
}
|
| 110 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
common/src/Tribe/Service_Providers/{Promoter.php → Promoter_Connector.php}
RENAMED
|
@@ -7,13 +7,14 @@
|
|
| 7 |
*
|
| 8 |
* Handles the registration and creation of our async process handlers.
|
| 9 |
*/
|
| 10 |
-
class
|
| 11 |
|
| 12 |
/**
|
| 13 |
* Binds and sets up implementations.
|
| 14 |
*/
|
| 15 |
public function register() {
|
| 16 |
tribe_singleton( 'promoter.auth', 'Tribe__Promoter__Auth' );
|
|
|
|
| 17 |
tribe_singleton( 'promoter.pue', 'Tribe__Promoter__PUE', array( 'load' ) );
|
| 18 |
tribe_singleton( 'promoter.view', 'Tribe__Promoter__View' );
|
| 19 |
|
|
@@ -26,14 +27,11 @@ class Tribe__Service_Providers__Promoter extends tad_DI52_ServiceProvider {
|
|
| 26 |
private function hook() {
|
| 27 |
add_action( 'template_redirect', tribe_callback( 'promoter.view', 'display_auth_check_view' ), 10, 0 );
|
| 28 |
add_action( 'init', tribe_callback( 'promoter.view', 'add_rewrites' ) );
|
|
|
|
|
|
|
| 29 |
|
| 30 |
tribe( 'promoter.pue' );
|
| 31 |
|
| 32 |
-
add_filter(
|
| 33 |
-
'tribe_promoter_secret_key',
|
| 34 |
-
tribe_callback( 'promoter.auth', 'filter_promoter_secret_key' )
|
| 35 |
-
);
|
| 36 |
-
|
| 37 |
// The usage of a high priority so we can push the icon to the end
|
| 38 |
add_action( 'admin_bar_menu', array( $this, 'add_promoter_logo_on_admin_bar' ), 1000 );
|
| 39 |
add_action( 'tribe_common_loaded', array( $this, 'add_promoter_assets' ) );
|
| 7 |
*
|
| 8 |
* Handles the registration and creation of our async process handlers.
|
| 9 |
*/
|
| 10 |
+
class Tribe__Service_Providers__Promoter_Connector extends tad_DI52_ServiceProvider {
|
| 11 |
|
| 12 |
/**
|
| 13 |
* Binds and sets up implementations.
|
| 14 |
*/
|
| 15 |
public function register() {
|
| 16 |
tribe_singleton( 'promoter.auth', 'Tribe__Promoter__Auth' );
|
| 17 |
+
tribe_singleton( 'promoter.connector', 'Tribe__Promoter__Connector' );
|
| 18 |
tribe_singleton( 'promoter.pue', 'Tribe__Promoter__PUE', array( 'load' ) );
|
| 19 |
tribe_singleton( 'promoter.view', 'Tribe__Promoter__View' );
|
| 20 |
|
| 27 |
private function hook() {
|
| 28 |
add_action( 'template_redirect', tribe_callback( 'promoter.view', 'display_auth_check_view' ), 10, 0 );
|
| 29 |
add_action( 'init', tribe_callback( 'promoter.view', 'add_rewrites' ) );
|
| 30 |
+
// Add early-firing filter for user auth on REST.
|
| 31 |
+
add_filter( 'determine_current_user', tribe_callback( 'promoter.connector', 'authenticate_user_with_connector' ), 10, 1 );
|
| 32 |
|
| 33 |
tribe( 'promoter.pue' );
|
| 34 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 35 |
// The usage of a high priority so we can push the icon to the end
|
| 36 |
add_action( 'admin_bar_menu', array( $this, 'add_promoter_logo_on_admin_bar' ), 1000 );
|
| 37 |
add_action( 'tribe_common_loaded', array( $this, 'add_promoter_assets' ) );
|
common/src/Tribe/Service_Providers/Shortcodes.php
DELETED
|
@@ -1,80 +0,0 @@
|
|
| 1 |
-
<?php
|
| 2 |
-
namespace Tribe\Service_Providers;
|
| 3 |
-
|
| 4 |
-
use Tribe\Shortcode\Manager;
|
| 5 |
-
|
| 6 |
-
/**
|
| 7 |
-
* Class Shortcode
|
| 8 |
-
*
|
| 9 |
-
* @since 4.12.0
|
| 10 |
-
*
|
| 11 |
-
* @package Tribe\Service_Providers
|
| 12 |
-
*/
|
| 13 |
-
class Shortcodes extends \tad_DI52_ServiceProvider {
|
| 14 |
-
|
| 15 |
-
/**
|
| 16 |
-
* Binds and sets up implementations.
|
| 17 |
-
*
|
| 18 |
-
* @since 4.12.0
|
| 19 |
-
*/
|
| 20 |
-
public function register() {
|
| 21 |
-
if ( ! static::is_active() ) {
|
| 22 |
-
return;
|
| 23 |
-
}
|
| 24 |
-
|
| 25 |
-
$this->container->singleton( Manager::class, Manager::class );
|
| 26 |
-
|
| 27 |
-
$this->register_hooks();
|
| 28 |
-
$this->register_assets();
|
| 29 |
-
|
| 30 |
-
$this->container->singleton( static::class, $this );
|
| 31 |
-
}
|
| 32 |
-
|
| 33 |
-
/**
|
| 34 |
-
* Static method wrapper around a filter to allow full deactivation of this provider
|
| 35 |
-
*
|
| 36 |
-
* @since 4.12.0
|
| 37 |
-
*
|
| 38 |
-
* @return boolean If this service provider is active.
|
| 39 |
-
*/
|
| 40 |
-
public static function is_active() {
|
| 41 |
-
/**
|
| 42 |
-
* Allows filtering to deactivate all shortcodes loading.
|
| 43 |
-
*
|
| 44 |
-
* @since 4.12.0
|
| 45 |
-
*
|
| 46 |
-
* @param boolean $is_active If shortcodes should be loaded or not.
|
| 47 |
-
*/
|
| 48 |
-
return apply_filters( 'tribe_shortcodes_is_active', true );
|
| 49 |
-
}
|
| 50 |
-
|
| 51 |
-
/**
|
| 52 |
-
* Register all the assets associated with this service provider.
|
| 53 |
-
*
|
| 54 |
-
* @since 4.12.0
|
| 55 |
-
*/
|
| 56 |
-
protected function register_assets() {
|
| 57 |
-
|
| 58 |
-
}
|
| 59 |
-
|
| 60 |
-
/**
|
| 61 |
-
* Registers the provider handling all the 1st level filters and actions for this service provider.
|
| 62 |
-
*
|
| 63 |
-
* @since 4.12.0
|
| 64 |
-
*/
|
| 65 |
-
protected function register_hooks() {
|
| 66 |
-
add_action( 'init', [ $this, 'action_add_shortcodes' ], 20 );
|
| 67 |
-
}
|
| 68 |
-
|
| 69 |
-
/**
|
| 70 |
-
* Adds the new shortcodes, this normally will trigger on `init@P20` due to how we the
|
| 71 |
-
* v1 is added on `init@P10` and we remove them on `init@P15`.
|
| 72 |
-
*
|
| 73 |
-
* It's important to leave gaps on priority for better injection.
|
| 74 |
-
*
|
| 75 |
-
* @since 4.12.0
|
| 76 |
-
*/
|
| 77 |
-
public function action_add_shortcodes() {
|
| 78 |
-
$this->container->make( Manager::class )->add_shortcodes();
|
| 79 |
-
}
|
| 80 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
common/src/Tribe/Service_Providers/Tooltip.php
CHANGED
|
@@ -1,5 +1,4 @@
|
|
| 1 |
<?php
|
| 2 |
-
namespace Tribe\Service_Providers;
|
| 3 |
|
| 4 |
/**
|
| 5 |
* Class Tribe__Service_Providers__Tooltip
|
|
@@ -8,7 +7,7 @@ namespace Tribe\Service_Providers;
|
|
| 8 |
*
|
| 9 |
* Handles the registration and creation of our async process handlers.
|
| 10 |
*/
|
| 11 |
-
class
|
| 12 |
|
| 13 |
/**
|
| 14 |
* Binds and sets up implementations.
|
|
@@ -16,7 +15,7 @@ class Tooltip extends \tad_DI52_ServiceProvider {
|
|
| 16 |
* @since 4.9.8
|
| 17 |
*/
|
| 18 |
public function register() {
|
| 19 |
-
tribe_singleton( 'tooltip.view', '
|
| 20 |
|
| 21 |
$this->hook();
|
| 22 |
}
|
|
@@ -36,24 +35,20 @@ class Tooltip extends \tad_DI52_ServiceProvider {
|
|
| 36 |
* @since 4.9.8
|
| 37 |
*/
|
| 38 |
public function add_tooltip_assets() {
|
| 39 |
-
$main = \Tribe__Main::instance();
|
| 40 |
-
|
| 41 |
tribe_asset(
|
| 42 |
-
|
| 43 |
-
'tribe-tooltip',
|
| 44 |
'tooltip.css',
|
| 45 |
-
[
|
| 46 |
-
[ 'wp_enqueue_scripts', 'admin_enqueue_scripts' ]
|
| 47 |
-
[ 'groups' => 'tribe-tooltip' ]
|
| 48 |
);
|
| 49 |
|
| 50 |
tribe_asset(
|
| 51 |
-
|
| 52 |
'tribe-tooltip-js',
|
| 53 |
'tooltip.js',
|
| 54 |
-
[ 'jquery', 'tribe-common' ],
|
| 55 |
[],
|
| 56 |
-
[ '
|
| 57 |
);
|
| 58 |
}
|
| 59 |
}
|
| 1 |
<?php
|
|
|
|
| 2 |
|
| 3 |
/**
|
| 4 |
* Class Tribe__Service_Providers__Tooltip
|
| 7 |
*
|
| 8 |
* Handles the registration and creation of our async process handlers.
|
| 9 |
*/
|
| 10 |
+
class Tribe__Service_Providers__Tooltip extends tad_DI52_ServiceProvider {
|
| 11 |
|
| 12 |
/**
|
| 13 |
* Binds and sets up implementations.
|
| 15 |
* @since 4.9.8
|
| 16 |
*/
|
| 17 |
public function register() {
|
| 18 |
+
tribe_singleton( 'tooltip.view', 'Tribe__Tooltip__View' );
|
| 19 |
|
| 20 |
$this->hook();
|
| 21 |
}
|
| 35 |
* @since 4.9.8
|
| 36 |
*/
|
| 37 |
public function add_tooltip_assets() {
|
|
|
|
|
|
|
| 38 |
tribe_asset(
|
| 39 |
+
Tribe__Main::instance(),
|
| 40 |
+
'tribe-tooltip-css',
|
| 41 |
'tooltip.css',
|
| 42 |
+
[],
|
| 43 |
+
[ 'wp_enqueue_scripts', 'admin_enqueue_scripts' ]
|
|
|
|
| 44 |
);
|
| 45 |
|
| 46 |
tribe_asset(
|
| 47 |
+
Tribe__Main::instance(),
|
| 48 |
'tribe-tooltip-js',
|
| 49 |
'tooltip.js',
|
|
|
|
| 50 |
[],
|
| 51 |
+
[ 'wp_enqueue_scripts', 'admin_enqueue_scripts' ]
|
| 52 |
);
|
| 53 |
}
|
| 54 |
}
|
common/src/Tribe/Settings.php
CHANGED
|
@@ -295,51 +295,45 @@ if ( ! class_exists( 'Tribe__Settings' ) ) {
|
|
| 295 |
* @return void
|
| 296 |
*/
|
| 297 |
public function initTabs() {
|
| 298 |
-
if (
|
| 299 |
-
|
| 300 |
-
|
| 301 |
-
|
| 302 |
-
|
| 303 |
-
|
| 304 |
-
|
| 305 |
-
|
| 306 |
-
|
| 307 |
-
|
| 308 |
-
|
| 309 |
-
|
| 310 |
-
|
| 311 |
-
|
| 312 |
-
|
| 313 |
-
|
| 314 |
-
|
| 315 |
-
|
| 316 |
-
|
| 317 |
-
|
| 318 |
-
|
| 319 |
-
|
| 320 |
-
|
| 321 |
-
|
| 322 |
-
|
| 323 |
-
|
| 324 |
-
|
| 325 |
-
|
| 326 |
-
|
| 327 |
-
|
| 328 |
-
|
| 329 |
-
|
| 330 |
-
|
| 331 |
-
|
| 332 |
-
|
| 333 |
-
|
| 334 |
-
|
| 335 |
-
|
| 336 |
-
);
|
| 337 |
}
|
| 338 |
-
|
| 339 |
-
$this->fields_for_save = (array) apply_filters( 'tribe_settings_fields', [] );
|
| 340 |
-
do_action( 'tribe_settings_after_do_tabs' );
|
| 341 |
-
$this->fields = (array) apply_filters( 'tribe_settings_fields', [] );
|
| 342 |
-
$this->validate();
|
| 343 |
}
|
| 344 |
|
| 345 |
/**
|
| 295 |
* @return void
|
| 296 |
*/
|
| 297 |
public function initTabs() {
|
| 298 |
+
if ( isset( $_GET['page'] ) && $_GET['page'] == $this->adminSlug ) {
|
| 299 |
+
// Load settings tab-specific helpers and enhancements
|
| 300 |
+
Tribe__Admin__Live_Date_Preview::instance();
|
| 301 |
+
|
| 302 |
+
do_action( 'tribe_settings_do_tabs' ); // this is the hook to use to add new tabs
|
| 303 |
+
$this->tabs = (array) apply_filters( 'tribe_settings_tabs', array() );
|
| 304 |
+
$this->allTabs = (array) apply_filters( 'tribe_settings_all_tabs', array() );
|
| 305 |
+
$this->noSaveTabs = (array) apply_filters( 'tribe_settings_no_save_tabs', array() );
|
| 306 |
+
if ( is_network_admin() ) {
|
| 307 |
+
$this->defaultTab = apply_filters( 'tribe_settings_default_tab_network', 'network' );
|
| 308 |
+
$this->currentTab = apply_filters( 'tribe_settings_current_tab', ( isset( $_GET['tab'] ) && $_GET['tab'] ) ? esc_attr( $_GET['tab'] ) : $this->defaultTab );
|
| 309 |
+
$this->url = apply_filters(
|
| 310 |
+
'tribe_settings_url', add_query_arg(
|
| 311 |
+
array(
|
| 312 |
+
'page' => $this->adminSlug,
|
| 313 |
+
'tab' => $this->currentTab,
|
| 314 |
+
), network_admin_url( 'settings.php' )
|
| 315 |
+
)
|
| 316 |
+
);
|
| 317 |
+
}
|
| 318 |
+
if ( ! is_network_admin() ) {
|
| 319 |
+
$tabs_keys = array_keys( $this->tabs );
|
| 320 |
+
$this->defaultTab = in_array( apply_filters( 'tribe_settings_default_tab', 'general' ), $tabs_keys ) ? apply_filters( 'tribe_settings_default_tab', 'general' ) : $tabs_keys[0];
|
| 321 |
+
$this->currentTab = apply_filters( 'tribe_settings_current_tab', ( isset( $_GET['tab'] ) && $_GET['tab'] ) ? esc_attr( $_GET['tab'] ) : $this->defaultTab );
|
| 322 |
+
$this->url = apply_filters(
|
| 323 |
+
'tribe_settings_url', add_query_arg(
|
| 324 |
+
array(
|
| 325 |
+
'page' => $this->adminSlug,
|
| 326 |
+
'tab' => $this->currentTab,
|
| 327 |
+
),
|
| 328 |
+
admin_url( self::$parent_page )
|
| 329 |
+
)
|
| 330 |
+
);
|
| 331 |
+
}
|
| 332 |
+
$this->fields_for_save = (array) apply_filters( 'tribe_settings_fields', array() );
|
| 333 |
+
do_action( 'tribe_settings_after_do_tabs' );
|
| 334 |
+
$this->fields = (array) apply_filters( 'tribe_settings_fields', array() );
|
| 335 |
+
$this->validate();
|
|
|
|
| 336 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 337 |
}
|
| 338 |
|
| 339 |
/**
|
common/src/Tribe/Settings_Manager.php
CHANGED
|
@@ -1,7 +1,6 @@
|
|
| 1 |
<?php
|
| 2 |
-
class Tribe__Settings_Manager {
|
| 3 |
-
const OPTION_CACHE_VAR_NAME = 'Tribe__Settings_Manager:option_cache';
|
| 4 |
|
|
|
|
| 5 |
protected static $network_options;
|
| 6 |
public static $tribe_events_mu_defaults;
|
| 7 |
|
|
@@ -30,28 +29,6 @@ class Tribe__Settings_Manager {
|
|
| 30 |
add_action( 'tribe_settings_do_tabs', array( $this, 'do_setting_tabs' ) );
|
| 31 |
add_action( 'tribe_settings_do_tabs', array( $this, 'do_network_settings_tab' ), 400 );
|
| 32 |
add_action( 'tribe_settings_validate_tab_network', array( $this, 'save_all_tabs_hidden' ) );
|
| 33 |
-
add_action( 'updated_option', [ $this, 'update_options_cache' ], 10, 3 );
|
| 34 |
-
}
|
| 35 |
-
|
| 36 |
-
/**
|
| 37 |
-
* For performance reasons our options are saved in memory, but we need to make sure we update it when WordPress
|
| 38 |
-
* updates the variable directly.
|
| 39 |
-
*
|
| 40 |
-
* @since 4.11.0
|
| 41 |
-
*
|
| 42 |
-
* @param string $option Name of the updated option.
|
| 43 |
-
* @param mixed $old_value The old option value.
|
| 44 |
-
* @param mixed $value The new option value.
|
| 45 |
-
*
|
| 46 |
-
* @return void
|
| 47 |
-
*/
|
| 48 |
-
public function update_options_cache( $option, $old_value, $value ) {
|
| 49 |
-
// Bail when no our option.
|
| 50 |
-
if ( Tribe__Main::OPTIONNAME !== $option ) {
|
| 51 |
-
return;
|
| 52 |
-
}
|
| 53 |
-
|
| 54 |
-
tribe_set_var( self::OPTION_CACHE_VAR_NAME, $value );
|
| 55 |
}
|
| 56 |
|
| 57 |
/**
|
|
@@ -69,9 +46,6 @@ class Tribe__Settings_Manager {
|
|
| 69 |
* @return void
|
| 70 |
*/
|
| 71 |
public function do_setting_tabs() {
|
| 72 |
-
// Make sure Thickbox is available regardless of which admin page we're on
|
| 73 |
-
add_thickbox();
|
| 74 |
-
|
| 75 |
include_once Tribe__Main::instance()->plugin_path . 'src/admin-views/tribe-options-general.php';
|
| 76 |
include_once Tribe__Main::instance()->plugin_path . 'src/admin-views/tribe-options-display.php';
|
| 77 |
|
|
@@ -89,14 +63,11 @@ class Tribe__Settings_Manager {
|
|
| 89 |
* @return array of options
|
| 90 |
*/
|
| 91 |
public static function get_options() {
|
| 92 |
-
$options =
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
$options = (
|
| 96 |
-
|
| 97 |
-
tribe_set_var( self::OPTION_CACHE_VAR_NAME, $options );
|
| 98 |
-
}
|
| 99 |
-
|
| 100 |
return $options;
|
| 101 |
}
|
| 102 |
|
|
@@ -112,7 +83,7 @@ class Tribe__Settings_Manager {
|
|
| 112 |
if ( ! $option_name ) {
|
| 113 |
return null;
|
| 114 |
}
|
| 115 |
-
$options =
|
| 116 |
|
| 117 |
$option = $default;
|
| 118 |
if ( array_key_exists( $option_name, $options ) ) {
|
|
@@ -136,16 +107,10 @@ class Tribe__Settings_Manager {
|
|
| 136 |
if ( ! is_array( $options ) ) {
|
| 137 |
return false;
|
| 138 |
}
|
| 139 |
-
if (
|
| 140 |
$options = apply_filters( 'tribe-events-save-options', $options );
|
| 141 |
}
|
| 142 |
-
|
| 143 |
-
|
| 144 |
-
if ( $updated ) {
|
| 145 |
-
tribe_set_var( self::OPTION_CACHE_VAR_NAME, $options );
|
| 146 |
-
}
|
| 147 |
-
|
| 148 |
-
return $updated;
|
| 149 |
}
|
| 150 |
|
| 151 |
/**
|
|
@@ -157,10 +122,10 @@ class Tribe__Settings_Manager {
|
|
| 157 |
* @return bool
|
| 158 |
*/
|
| 159 |
public static function set_option( $name, $value ) {
|
|
|
|
|
|
|
| 160 |
$options = self::get_options();
|
| 161 |
-
$
|
| 162 |
-
|
| 163 |
-
return self::set_options( $options );
|
| 164 |
}
|
| 165 |
|
| 166 |
/**
|
|
@@ -171,7 +136,7 @@ class Tribe__Settings_Manager {
|
|
| 171 |
*/
|
| 172 |
public static function get_network_options() {
|
| 173 |
if ( ! isset( self::$network_options ) ) {
|
| 174 |
-
$options
|
| 175 |
self::$network_options = apply_filters( 'tribe_get_network_options', $options );
|
| 176 |
}
|
| 177 |
|
| 1 |
<?php
|
|
|
|
|
|
|
| 2 |
|
| 3 |
+
class Tribe__Settings_Manager {
|
| 4 |
protected static $network_options;
|
| 5 |
public static $tribe_events_mu_defaults;
|
| 6 |
|
| 29 |
add_action( 'tribe_settings_do_tabs', array( $this, 'do_setting_tabs' ) );
|
| 30 |
add_action( 'tribe_settings_do_tabs', array( $this, 'do_network_settings_tab' ), 400 );
|
| 31 |
add_action( 'tribe_settings_validate_tab_network', array( $this, 'save_all_tabs_hidden' ) );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 32 |
}
|
| 33 |
|
| 34 |
/**
|
| 46 |
* @return void
|
| 47 |
*/
|
| 48 |
public function do_setting_tabs() {
|
|
|
|
|
|
|
|
|
|
| 49 |
include_once Tribe__Main::instance()->plugin_path . 'src/admin-views/tribe-options-general.php';
|
| 50 |
include_once Tribe__Main::instance()->plugin_path . 'src/admin-views/tribe-options-display.php';
|
| 51 |
|
| 63 |
* @return array of options
|
| 64 |
*/
|
| 65 |
public static function get_options() {
|
| 66 |
+
$options = (array) get_option( Tribe__Main::OPTIONNAME, array() );
|
| 67 |
+
if ( has_filter( 'tribe_get_options' ) ) {
|
| 68 |
+
_deprecated_function( 'tribe_get_options', '3.10', 'option_' . Tribe__Main::OPTIONNAME );
|
| 69 |
+
$options = apply_filters( 'tribe_get_options', $options );
|
| 70 |
+
}
|
|
|
|
|
|
|
|
|
|
| 71 |
return $options;
|
| 72 |
}
|
| 73 |
|
| 83 |
if ( ! $option_name ) {
|
| 84 |
return null;
|
| 85 |
}
|
| 86 |
+
$options = self::get_options();
|
| 87 |
|
| 88 |
$option = $default;
|
| 89 |
if ( array_key_exists( $option_name, $options ) ) {
|
| 107 |
if ( ! is_array( $options ) ) {
|
| 108 |
return false;
|
| 109 |
}
|
| 110 |
+
if ( $apply_filters == true ) {
|
| 111 |
$options = apply_filters( 'tribe-events-save-options', $options );
|
| 112 |
}
|
| 113 |
+
return update_option( Tribe__Main::OPTIONNAME, $options );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 114 |
}
|
| 115 |
|
| 116 |
/**
|
| 122 |
* @return bool
|
| 123 |
*/
|
| 124 |
public static function set_option( $name, $value ) {
|
| 125 |
+
$newOption = array();
|
| 126 |
+
$newOption[ $name ] = $value;
|
| 127 |
$options = self::get_options();
|
| 128 |
+
return self::set_options( wp_parse_args( $newOption, $options ) );
|
|
|
|
|
|
|
| 129 |
}
|
| 130 |
|
| 131 |
/**
|
| 136 |
*/
|
| 137 |
public static function get_network_options() {
|
| 138 |
if ( ! isset( self::$network_options ) ) {
|
| 139 |
+
$options = get_site_option( Tribe__Main::OPTIONNAMENETWORK, array() );
|
| 140 |
self::$network_options = apply_filters( 'tribe_get_network_options', $options );
|
| 141 |
}
|
| 142 |
|
common/src/Tribe/Shortcode/Manager.php
DELETED
|
@@ -1,107 +0,0 @@
|
|
| 1 |
-
<?php
|
| 2 |
-
/**
|
| 3 |
-
* Shortcodes manager for Tribe plugins.
|
| 4 |
-
*
|
| 5 |
-
* @package Tribe\Shortcode
|
| 6 |
-
* @since 4.12.0
|
| 7 |
-
*/
|
| 8 |
-
namespace Tribe\Shortcode;
|
| 9 |
-
|
| 10 |
-
/**
|
| 11 |
-
* Class Shortcode Manager.
|
| 12 |
-
*
|
| 13 |
-
* @since 4.12.0
|
| 14 |
-
*
|
| 15 |
-
* @package Tribe\Shortcode
|
| 16 |
-
*/
|
| 17 |
-
class Manager {
|
| 18 |
-
/**
|
| 19 |
-
* Get the list of shortcodes available for handling.
|
| 20 |
-
*
|
| 21 |
-
* @since 4.12.0
|
| 22 |
-
*
|
| 23 |
-
* @return array An associative array of shortcodes in the shape `[ <slug> => <class> ]`
|
| 24 |
-
*/
|
| 25 |
-
public function get_registered_shortcodes() {
|
| 26 |
-
$shortcodes = [];
|
| 27 |
-
|
| 28 |
-
/**
|
| 29 |
-
* Allow the registering of shortcodes into the our Tribe plugins.
|
| 30 |
-
*
|
| 31 |
-
* @since 4.12.0
|
| 32 |
-
*
|
| 33 |
-
* @var array An associative array of shortcodes in the shape `[ <slug> => <class> ]`.
|
| 34 |
-
*/
|
| 35 |
-
$shortcodes = apply_filters( 'tribe_shortcodes', $shortcodes );
|
| 36 |
-
|
| 37 |
-
return $shortcodes;
|
| 38 |
-
}
|
| 39 |
-
|
| 40 |
-
/**
|
| 41 |
-
* Verifies if a given shortcode slug is registered for handling.
|
| 42 |
-
*
|
| 43 |
-
* @since 4.12.0
|
| 44 |
-
*
|
| 45 |
-
* @param string $slug Which slug we are checking if is registered.
|
| 46 |
-
*
|
| 47 |
-
* @return bool Whether a shortcode is registered or not.
|
| 48 |
-
*/
|
| 49 |
-
public function is_shortcode_registered( $slug ) {
|
| 50 |
-
$registered_shortcodes = $this->get_registered_shortcodes();
|
| 51 |
-
return isset( $registered_shortcodes[ $slug ] );
|
| 52 |
-
}
|
| 53 |
-
|
| 54 |
-
/**
|
| 55 |
-
* Verifies if a given shortcode class name is registered for handling.
|
| 56 |
-
*
|
| 57 |
-
* @since 4.12.0
|
| 58 |
-
*
|
| 59 |
-
* @param string $class_name Which class name we are checking if is registered.
|
| 60 |
-
*
|
| 61 |
-
* @return bool Whether a shortcode is registered, by class.
|
| 62 |
-
*/
|
| 63 |
-
public function is_shortcode_registered_by_class( $class_name ) {
|
| 64 |
-
$registered_shortcodes = $this->get_registered_shortcodes();
|
| 65 |
-
return in_array( $class_name, $registered_shortcodes );
|
| 66 |
-
}
|
| 67 |
-
|
| 68 |
-
/**
|
| 69 |
-
* Add new shortcodes handler to catch the correct strings.
|
| 70 |
-
*
|
| 71 |
-
* @since 4.12.0
|
| 72 |
-
*/
|
| 73 |
-
public function add_shortcodes() {
|
| 74 |
-
$registered_shortcodes = $this->get_registered_shortcodes();
|
| 75 |
-
|
| 76 |
-
// Add to WordPress all of the registered Shortcodes
|
| 77 |
-
foreach ( $registered_shortcodes as $shortcode => $class_name ) {
|
| 78 |
-
add_shortcode( $shortcode, [ $this, 'render_shortcode' ] );
|
| 79 |
-
}
|
| 80 |
-
}
|
| 81 |
-
|
| 82 |
-
/**
|
| 83 |
-
* Makes sure we are correctly handling the Shortcodes we manage.
|
| 84 |
-
*
|
| 85 |
-
* @since 4.12.0
|
| 86 |
-
*
|
| 87 |
-
* @param array $arguments Set of arguments passed to the Shortcode at hand.
|
| 88 |
-
* @param string $content Contents passed to the shortcode, inside of the open and close brackets.
|
| 89 |
-
* @param string $shortcode Which shortcode tag are we handling here.
|
| 90 |
-
*
|
| 91 |
-
* @return string The rendered shortcode HTML.
|
| 92 |
-
*/
|
| 93 |
-
public function render_shortcode( $arguments, $content, $shortcode ) {
|
| 94 |
-
$registered_shortcodes = $this->get_registered_shortcodes();
|
| 95 |
-
|
| 96 |
-
// Bail when we try to handle an unregistered shortcode (shouldn't happen)
|
| 97 |
-
if ( ! $this->is_shortcode_registered( $shortcode ) ) {
|
| 98 |
-
return false;
|
| 99 |
-
}
|
| 100 |
-
|
| 101 |
-
/** @var Shortcode_Interface $instance */
|
| 102 |
-
$instance = new $registered_shortcodes[ $shortcode ];
|
| 103 |
-
$instance->setup( $arguments, $content );
|
| 104 |
-
|
| 105 |
-
return $instance->get_html();
|
| 106 |
-
}
|
| 107 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
common/src/Tribe/Shortcode/Shortcode_Abstract.php
DELETED
|
@@ -1,247 +0,0 @@
|
|
| 1 |
-
<?php
|
| 2 |
-
|
| 3 |
-
namespace Tribe\Shortcode;
|
| 4 |
-
|
| 5 |
-
use Tribe__Utils__Array as Arr;
|
| 6 |
-
|
| 7 |
-
/**
|
| 8 |
-
* The abstract all shortcodes should implement.
|
| 9 |
-
*
|
| 10 |
-
* @package Tribe\Shortcode
|
| 11 |
-
*
|
| 12 |
-
* @since 4.12.0
|
| 13 |
-
*/
|
| 14 |
-
abstract class Shortcode_Abstract implements Shortcode_Interface {
|
| 15 |
-
/**
|
| 16 |
-
* Slug of the current shortcode.
|
| 17 |
-
*
|
| 18 |
-
* @since 4.12.0
|
| 19 |
-
*
|
| 20 |
-
* @var string
|
| 21 |
-
*/
|
| 22 |
-
protected $slug;
|
| 23 |
-
|
| 24 |
-
/**
|
| 25 |
-
* Default arguments to be merged into final arguments of the shortcode.
|
| 26 |
-
*
|
| 27 |
-
* @since 4.12.0
|
| 28 |
-
*
|
| 29 |
-
* @var array
|
| 30 |
-
*/
|
| 31 |
-
protected $default_arguments = [];
|
| 32 |
-
|
| 33 |
-
/**
|
| 34 |
-
* Array map allowing aliased shortcode arguments.
|
| 35 |
-
*
|
| 36 |
-
* The array keys are aliases of the array values (i.e. the "real" shortcode attributes to parse).
|
| 37 |
-
* Example array: [ 'alias' => 'canonical', 'from' => 'to', 'that' => 'becomes_this' ]
|
| 38 |
-
* Example shortcode usage: [some_tag alias=17 to='Fred'] will be parsed as [some_tag canonical=17 to='Fred']
|
| 39 |
-
*
|
| 40 |
-
* @since 4.12.2
|
| 41 |
-
*
|
| 42 |
-
* @var array<string,string>
|
| 43 |
-
*/
|
| 44 |
-
protected $aliased_arguments = [];
|
| 45 |
-
|
| 46 |
-
/**
|
| 47 |
-
* Array of callbacks for arguments validation.
|
| 48 |
-
*
|
| 49 |
-
* @since 4.12.0
|
| 50 |
-
*
|
| 51 |
-
* @var array
|
| 52 |
-
*/
|
| 53 |
-
protected $validate_arguments_map = [];
|
| 54 |
-
|
| 55 |
-
/**
|
| 56 |
-
* Arguments of the current shortcode.
|
| 57 |
-
*
|
| 58 |
-
* @since 4.12.0
|
| 59 |
-
*
|
| 60 |
-
* @var array
|
| 61 |
-
*/
|
| 62 |
-
protected $arguments;
|
| 63 |
-
|
| 64 |
-
/**
|
| 65 |
-
* Content of the current shortcode.
|
| 66 |
-
*
|
| 67 |
-
* @since 4.12.0
|
| 68 |
-
*
|
| 69 |
-
* @var string
|
| 70 |
-
*/
|
| 71 |
-
protected $content;
|
| 72 |
-
|
| 73 |
-
/**
|
| 74 |
-
* {@inheritDoc}
|
| 75 |
-
*/
|
| 76 |
-
public function setup( $arguments, $content ) {
|
| 77 |
-
$this->arguments = $this->parse_arguments( (array) $arguments );
|
| 78 |
-
$this->content = $content;
|
| 79 |
-
}
|
| 80 |
-
|
| 81 |
-
/**
|
| 82 |
-
* {@inheritDoc}
|
| 83 |
-
*/
|
| 84 |
-
public function set_aliased_arguments( array $alias_map ) {
|
| 85 |
-
$this->aliased_arguments = Arr::filter_to_flat_scalar_associative_array( (array) $alias_map );
|
| 86 |
-
}
|
| 87 |
-
|
| 88 |
-
/**
|
| 89 |
-
* {@inheritDoc}
|
| 90 |
-
*/
|
| 91 |
-
public function get_aliased_arguments() {
|
| 92 |
-
return $this->aliased_arguments;
|
| 93 |
-
}
|
| 94 |
-
|
| 95 |
-
/**
|
| 96 |
-
* {@inheritDoc}
|
| 97 |
-
*/
|
| 98 |
-
public function parse_arguments( array $arguments ) {
|
| 99 |
-
$arguments = Arr::parse_associative_array_alias( (array) $arguments, (array) $this->get_aliased_arguments() );
|
| 100 |
-
$arguments = shortcode_atts( $this->get_default_arguments(), $arguments, $this->slug );
|
| 101 |
-
|
| 102 |
-
return $this->validate_arguments( $arguments );
|
| 103 |
-
}
|
| 104 |
-
|
| 105 |
-
/**
|
| 106 |
-
* {@inheritDoc}
|
| 107 |
-
*/
|
| 108 |
-
public function validate_arguments( array $arguments ) {
|
| 109 |
-
$validate_arguments_map = $this->get_validated_arguments_map();
|
| 110 |
-
foreach ( $validate_arguments_map as $key => $callback ) {
|
| 111 |
-
$arguments[ $key ] = $callback( isset( $arguments[ $key ] ) ? $arguments[ $key ] : null );
|
| 112 |
-
}
|
| 113 |
-
|
| 114 |
-
return $arguments;
|
| 115 |
-
}
|
| 116 |
-
|
| 117 |
-
/**
|
| 118 |
-
* {@inheritDoc}
|
| 119 |
-
*/
|
| 120 |
-
public function get_registration_slug() {
|
| 121 |
-
return $this->slug;
|
| 122 |
-
}
|
| 123 |
-
|
| 124 |
-
/**
|
| 125 |
-
* {@inheritDoc}
|
| 126 |
-
*/
|
| 127 |
-
public function get_validated_arguments_map() {
|
| 128 |
-
/**
|
| 129 |
-
* Applies a filter to instance arguments validation callbacks.
|
| 130 |
-
*
|
| 131 |
-
* @since 4.12.0
|
| 132 |
-
*
|
| 133 |
-
* @param array $validate_arguments_map Current set of callbacks for arguments.
|
| 134 |
-
* @param static $instance Which instance of shortcode we are dealing with.
|
| 135 |
-
*/
|
| 136 |
-
$validate_arguments_map = apply_filters( 'tribe_shortcode_validate_arguments_map', $this->validate_arguments_map, $this );
|
| 137 |
-
|
| 138 |
-
$registration_slug = $this->get_registration_slug();
|
| 139 |
-
|
| 140 |
-
/**
|
| 141 |
-
* Applies a filter to instance arguments validation callbacks based on the registration slug of the shortcode.
|
| 142 |
-
*
|
| 143 |
-
* @since 4.12.0
|
| 144 |
-
*
|
| 145 |
-
* @param array $validate_arguments_map Current set of callbacks for arguments.
|
| 146 |
-
* @param static $instance Which instance of shortcode we are dealing with.
|
| 147 |
-
*/
|
| 148 |
-
$validate_arguments_map = apply_filters( "tribe__shortcode_{$registration_slug}_validate_arguments_map", $validate_arguments_map, $this );
|
| 149 |
-
|
| 150 |
-
return $validate_arguments_map;
|
| 151 |
-
}
|
| 152 |
-
|
| 153 |
-
/**
|
| 154 |
-
* {@inheritDoc}
|
| 155 |
-
*/
|
| 156 |
-
public function get_arguments() {
|
| 157 |
-
/**
|
| 158 |
-
* Applies a filter to instance arguments.
|
| 159 |
-
*
|
| 160 |
-
* @since 4.12.0
|
| 161 |
-
*
|
| 162 |
-
* @param array $arguments Current set of arguments.
|
| 163 |
-
* @param static $instance Which instance of shortcode we are dealing with.
|
| 164 |
-
*/
|
| 165 |
-
$arguments = apply_filters( 'tribe_shortcode_arguments', $this->arguments, $this );
|
| 166 |
-
|
| 167 |
-
$registration_slug = $this->get_registration_slug();
|
| 168 |
-
|
| 169 |
-
/**
|
| 170 |
-
* Applies a filter to instance arguments based on the registration slug of the shortcode.
|
| 171 |
-
*
|
| 172 |
-
* @since 4.12.0
|
| 173 |
-
*
|
| 174 |
-
* @param array $arguments Current set of arguments.
|
| 175 |
-
* @param static $instance Which instance of shortcode we are dealing with.
|
| 176 |
-
*/
|
| 177 |
-
$arguments = apply_filters( "tribe_shortcode_{$registration_slug}_arguments", $arguments, $this );
|
| 178 |
-
|
| 179 |
-
return $arguments;
|
| 180 |
-
}
|
| 181 |
-
|
| 182 |
-
/**
|
| 183 |
-
* {@inheritDoc}
|
| 184 |
-
*/
|
| 185 |
-
public function get_argument( $index, $default = null ) {
|
| 186 |
-
$arguments = $this->get_arguments();
|
| 187 |
-
$argument = Arr::get( $arguments, $index, $default );
|
| 188 |
-
|
| 189 |
-
/**
|
| 190 |
-
* Applies a filter to a specific shortcode argument, catch all for all shortcodes.
|
| 191 |
-
*
|
| 192 |
-
* @since 4.12.0
|
| 193 |
-
*
|
| 194 |
-
* @param mixed $argument The argument.
|
| 195 |
-
* @param array $index Which index we indent to fetch from the arguments.
|
| 196 |
-
* @param array $default Default value if it doesn't exist.
|
| 197 |
-
* @param static $instance Which instance of shortcode we are dealing with.
|
| 198 |
-
*/
|
| 199 |
-
$argument = apply_filters( 'tribe_shortcode_argument', $argument, $index, $default, $this );
|
| 200 |
-
|
| 201 |
-
$registration_slug = $this->get_registration_slug();
|
| 202 |
-
|
| 203 |
-
/**
|
| 204 |
-
* Applies a filter to a specific shortcode argument, to a particular registration slug.
|
| 205 |
-
*
|
| 206 |
-
* @since 4.12.0
|
| 207 |
-
*
|
| 208 |
-
* @param mixed $argument The argument value.
|
| 209 |
-
* @param array $index Which index we indent to fetch from the arguments.
|
| 210 |
-
* @param array $default Default value if it doesn't exist.
|
| 211 |
-
* @param static $instance Which instance of shortcode we are dealing with.
|
| 212 |
-
*/
|
| 213 |
-
$argument = apply_filters( "tribe_shortcode_{$registration_slug}_argument", $argument, $index, $default, $this );
|
| 214 |
-
|
| 215 |
-
return $argument;
|
| 216 |
-
}
|
| 217 |
-
|
| 218 |
-
/**
|
| 219 |
-
* {@inheritDoc}
|
| 220 |
-
*/
|
| 221 |
-
public function get_default_arguments() {
|
| 222 |
-
/**
|
| 223 |
-
* Applies a filter to instance default arguments.
|
| 224 |
-
*
|
| 225 |
-
* @since 4.12.0
|
| 226 |
-
*
|
| 227 |
-
* @param array $default_arguments Current set of default arguments.
|
| 228 |
-
* @param static $instance Which instance of shortcode we are dealing with.
|
| 229 |
-
*/
|
| 230 |
-
$default_arguments = apply_filters( 'tribe_shortcode_default_arguments', $this->default_arguments, $this );
|
| 231 |
-
|
| 232 |
-
$registration_slug = $this->get_registration_slug();
|
| 233 |
-
|
| 234 |
-
/**
|
| 235 |
-
* Applies a filter to instance default arguments based on the registration slug of the shortcode.
|
| 236 |
-
*
|
| 237 |
-
* @since 4.12.0
|
| 238 |
-
*
|
| 239 |
-
* @param array $default_arguments Current set of default arguments.
|
| 240 |
-
* @param static $instance Which instance of shortcode we are dealing with.
|
| 241 |
-
*/
|
| 242 |
-
$default_arguments = apply_filters( "tribe_shortcode_{$registration_slug}_default_arguments", $default_arguments, $this );
|
| 243 |
-
|
| 244 |
-
return $default_arguments;
|
| 245 |
-
}
|
| 246 |
-
|
| 247 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
common/src/Tribe/Shortcode/Shortcode_Interface.php
DELETED
|
@@ -1,125 +0,0 @@
|
|
| 1 |
-
<?php
|
| 2 |
-
|
| 3 |
-
namespace Tribe\Shortcode;
|
| 4 |
-
|
| 5 |
-
/**
|
| 6 |
-
* Interface Shortcode_Interface
|
| 7 |
-
*
|
| 8 |
-
* @package Tribe\Shortcode
|
| 9 |
-
*
|
| 10 |
-
* @since 4.12.0
|
| 11 |
-
*/
|
| 12 |
-
interface Shortcode_Interface {
|
| 13 |
-
|
| 14 |
-
/**
|
| 15 |
-
* Returns the shortcode slug that allows the shortcode to be built via the shortcode class by slug.
|
| 16 |
-
*
|
| 17 |
-
* @since 4.12.0
|
| 18 |
-
*
|
| 19 |
-
* @return string The shortcode slug.
|
| 20 |
-
*/
|
| 21 |
-
public function get_registration_slug();
|
| 22 |
-
|
| 23 |
-
/**
|
| 24 |
-
* Configures the base variables for an instance of shortcode.
|
| 25 |
-
*
|
| 26 |
-
* @since 4.12.0
|
| 27 |
-
*
|
| 28 |
-
* @param array|string $arguments Set of arguments passed to the Shortcode at hand. Empty string if no args.
|
| 29 |
-
* @param string $content Contents passed to the shortcode, inside of the open and close brackets.
|
| 30 |
-
*/
|
| 31 |
-
public function setup( $arguments, $content );
|
| 32 |
-
|
| 33 |
-
/**
|
| 34 |
-
* Sets the aliased arguments array.
|
| 35 |
-
*
|
| 36 |
-
* @see Tribe__Utils__Array::parse_associative_array_alias() The expected format.
|
| 37 |
-
*
|
| 38 |
-
* @since 4.12.2
|
| 39 |
-
*
|
| 40 |
-
* @param array $alias_map An associative array of aliases: key as alias, value as mapped canonical.
|
| 41 |
-
* Example: [ 'alias' => 'canonical', 'from' => 'to', 'that' => 'becomes_this' ]
|
| 42 |
-
*/
|
| 43 |
-
public function set_aliased_arguments( array $alias_map );
|
| 44 |
-
|
| 45 |
-
/**
|
| 46 |
-
* Gets the aliased arguments array.
|
| 47 |
-
*
|
| 48 |
-
* @since 4.12.2
|
| 49 |
-
*
|
| 50 |
-
* @return array<string,string> The associative array map of aliases and their canonical arguments.
|
| 51 |
-
*/
|
| 52 |
-
public function get_aliased_arguments();
|
| 53 |
-
|
| 54 |
-
/**
|
| 55 |
-
* Returns the arguments for the shortcode parsed correctly with defaults applied.
|
| 56 |
-
*
|
| 57 |
-
* @since 4.12.0
|
| 58 |
-
*
|
| 59 |
-
* @param array $arguments Set of arguments passed to the Shortcode at hand.
|
| 60 |
-
*
|
| 61 |
-
* @return array<string,mixed> The parsed shortcode arguments map.
|
| 62 |
-
*/
|
| 63 |
-
public function parse_arguments( array $arguments );
|
| 64 |
-
|
| 65 |
-
/**
|
| 66 |
-
* Returns the array of arguments for this shortcode after applying the validation callbacks.
|
| 67 |
-
*
|
| 68 |
-
* @since 4.12.0
|
| 69 |
-
*
|
| 70 |
-
* @param array $arguments Set of arguments passed to the Shortcode at hand.
|
| 71 |
-
*
|
| 72 |
-
* @return array<string,mixed> The validated shortcode arguments map.
|
| 73 |
-
*/
|
| 74 |
-
public function validate_arguments( array $arguments );
|
| 75 |
-
|
| 76 |
-
/**
|
| 77 |
-
* Returns the array of callbacks for this shortcode's arguments.
|
| 78 |
-
*
|
| 79 |
-
* @since 4.12.0
|
| 80 |
-
*
|
| 81 |
-
* @return array<string,mixed> A map of the shortcode arguments that have survived validation.
|
| 82 |
-
*/
|
| 83 |
-
public function get_validated_arguments_map();
|
| 84 |
-
|
| 85 |
-
/**
|
| 86 |
-
* Returns a shortcode default arguments.
|
| 87 |
-
*
|
| 88 |
-
* @since 4.12.0
|
| 89 |
-
*
|
| 90 |
-
* @return array<string,mixed> The shortcode default arguments map.
|
| 91 |
-
*/
|
| 92 |
-
public function get_default_arguments();
|
| 93 |
-
|
| 94 |
-
/**
|
| 95 |
-
* Returns a shortcode arguments after been parsed.
|
| 96 |
-
*
|
| 97 |
-
* @since 4.12.0
|
| 98 |
-
*
|
| 99 |
-
* @return array<string,mixed> The shortcode arguments, as set by the user in the shortcode string.
|
| 100 |
-
*/
|
| 101 |
-
public function get_arguments();
|
| 102 |
-
|
| 103 |
-
/**
|
| 104 |
-
* Returns a shortcode argument after it has been parsed.
|
| 105 |
-
*
|
| 106 |
-
* @since 4.12.0
|
| 107 |
-
*
|
| 108 |
-
* @param array|string $index Which index we indent to fetch from the arguments.
|
| 109 |
-
* @param array $default Default value if it doesn't exist.
|
| 110 |
-
*
|
| 111 |
-
* @uses Tribe__Utils__Array::get For index fetching and Default.
|
| 112 |
-
*
|
| 113 |
-
* @return mixed Value for the Index passed as the first argument.
|
| 114 |
-
*/
|
| 115 |
-
public function get_argument( $index, $default = null );
|
| 116 |
-
|
| 117 |
-
/**
|
| 118 |
-
* Returns a shortcode's HTML.
|
| 119 |
-
*
|
| 120 |
-
* @since 4.12.0
|
| 121 |
-
*
|
| 122 |
-
* @return string The shortcode rendered HTML code.
|
| 123 |
-
*/
|
| 124 |
-
public function get_html();
|
| 125 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
common/src/Tribe/Support.php
CHANGED
|
@@ -87,7 +87,7 @@ if ( ! class_exists( 'Tribe__Support' ) ) {
|
|
| 87 |
$plugin .= sprintf( ' by %s', $plugin_details['Author'] );
|
| 88 |
}
|
| 89 |
if ( ! empty( $plugin_details['AuthorURI'] ) ) {
|
| 90 |
-
$plugin .= sprintf( '
|
| 91 |
}
|
| 92 |
$plugins[] = $plugin;
|
| 93 |
}
|
|
@@ -106,7 +106,7 @@ if ( ! class_exists( 'Tribe__Support' ) ) {
|
|
| 106 |
$plugin .= sprintf( ' by %s', $plugin_details['Author'] );
|
| 107 |
}
|
| 108 |
if ( ! empty( $plugin_details['AuthorURI'] ) ) {
|
| 109 |
-
$plugin .= sprintf( '
|
| 110 |
}
|
| 111 |
$network_plugins[] = $plugin;
|
| 112 |
}
|
|
@@ -124,7 +124,7 @@ if ( ! class_exists( 'Tribe__Support' ) ) {
|
|
| 124 |
$plugin .= sprintf( ' by %s', $v['Author'] );
|
| 125 |
}
|
| 126 |
if ( ! empty( $v['AuthorURI'] ) ) {
|
| 127 |
-
$plugin .= sprintf( '
|
| 128 |
}
|
| 129 |
$mu_plugins[] = $plugin;
|
| 130 |
}
|
|
@@ -164,17 +164,6 @@ if ( ! class_exists( 'Tribe__Support' ) ) {
|
|
| 164 |
$php_info[ $php_var ] = $val;
|
| 165 |
}
|
| 166 |
|
| 167 |
-
$homepage = get_option( 'show_on_front' );
|
| 168 |
-
$homepage_page_id = get_option( 'page_on_front' );
|
| 169 |
-
|
| 170 |
-
if ( 'page' === $homepage ) {
|
| 171 |
-
if ( -10 === (int) $homepage_page_id ) {
|
| 172 |
-
$homepage_page_id .= ' (Main Events Page)';
|
| 173 |
-
} else {
|
| 174 |
-
$homepage_page_id .= ' (' . esc_html( get_the_title( $homepage_page_id ) ) . ')';
|
| 175 |
-
}
|
| 176 |
-
}
|
| 177 |
-
|
| 178 |
$site_url = get_site_url();
|
| 179 |
$systeminfo = array(
|
| 180 |
'Home URL' => get_home_url(),
|
|
@@ -186,8 +175,6 @@ if ( ! class_exists( 'Tribe__Support' ) ) {
|
|
| 186 |
'Install keys' => $keys,
|
| 187 |
'WordPress version' => get_bloginfo( 'version' ),
|
| 188 |
'Permalink Structure' => $site_url . get_option( 'permalink_structure' ),
|
| 189 |
-
'Your homepage displays' => $homepage,
|
| 190 |
-
'Homepage page ID' => $homepage_page_id,
|
| 191 |
'PHP version' => phpversion(),
|
| 192 |
'PHP' => $php_info,
|
| 193 |
'Server' => $server[0],
|
|
@@ -287,7 +274,7 @@ if ( ! class_exists( 'Tribe__Support' ) ) {
|
|
| 287 |
}
|
| 288 |
|
| 289 |
/**
|
| 290 |
-
* Logs the
|
| 291 |
*/
|
| 292 |
public function log_rewrite_rule_purge() {
|
| 293 |
$this->rewrite_rules_purged = true;
|
| 87 |
$plugin .= sprintf( ' by %s', $plugin_details['Author'] );
|
| 88 |
}
|
| 89 |
if ( ! empty( $plugin_details['AuthorURI'] ) ) {
|
| 90 |
+
$plugin .= sprintf( '(%s)', $plugin_details['AuthorURI'] );
|
| 91 |
}
|
| 92 |
$plugins[] = $plugin;
|
| 93 |
}
|
| 106 |
$plugin .= sprintf( ' by %s', $plugin_details['Author'] );
|
| 107 |
}
|
| 108 |
if ( ! empty( $plugin_details['AuthorURI'] ) ) {
|
| 109 |
+
$plugin .= sprintf( '(%s)', $plugin_details['AuthorURI'] );
|
| 110 |
}
|
| 111 |
$network_plugins[] = $plugin;
|
| 112 |
}
|
| 124 |
$plugin .= sprintf( ' by %s', $v['Author'] );
|
| 125 |
}
|
| 126 |
if ( ! empty( $v['AuthorURI'] ) ) {
|
| 127 |
+
$plugin .= sprintf( '(%s)', $v['AuthorURI'] );
|
| 128 |
}
|
| 129 |
$mu_plugins[] = $plugin;
|
| 130 |
}
|
| 164 |
$php_info[ $php_var ] = $val;
|
| 165 |
}
|
| 166 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 167 |
$site_url = get_site_url();
|
| 168 |
$systeminfo = array(
|
| 169 |
'Home URL' => get_home_url(),
|
| 175 |
'Install keys' => $keys,
|
| 176 |
'WordPress version' => get_bloginfo( 'version' ),
|
| 177 |
'Permalink Structure' => $site_url . get_option( 'permalink_structure' ),
|
|
|
|
|
|
|
| 178 |
'PHP version' => phpversion(),
|
| 179 |
'PHP' => $php_info,
|
| 180 |
'Server' => $server[0],
|
| 274 |
}
|
| 275 |
|
| 276 |
/**
|
| 277 |
+
* Logs the occurence of rewrite rule purging
|
| 278 |
*/
|
| 279 |
public function log_rewrite_rule_purge() {
|
| 280 |
$this->rewrite_rules_purged = true;
|
common/src/Tribe/Template.php
CHANGED
|
@@ -1,6 +1,6 @@
|
|
| 1 |
<?php
|
| 2 |
|
| 3 |
-
use Tribe\
|
| 4 |
|
| 5 |
class Tribe__Template {
|
| 6 |
/**
|
|
@@ -40,16 +40,7 @@ class Tribe__Template {
|
|
| 40 |
protected $global = array();
|
| 41 |
|
| 42 |
/**
|
| 43 |
-
*
|
| 44 |
-
*
|
| 45 |
-
* @since 4.10.2
|
| 46 |
-
*
|
| 47 |
-
* @var string[]
|
| 48 |
-
*/
|
| 49 |
-
protected $template_origin_base_folder = [ 'src', 'views' ];
|
| 50 |
-
|
| 51 |
-
/**
|
| 52 |
-
* Allow changing if class will extract data from the local context
|
| 53 |
*
|
| 54 |
* @since 4.6.2
|
| 55 |
*
|
|
@@ -57,15 +48,6 @@ class Tribe__Template {
|
|
| 57 |
*/
|
| 58 |
protected $template_context_extract = false;
|
| 59 |
|
| 60 |
-
/**
|
| 61 |
-
* Current template hook name.
|
| 62 |
-
*
|
| 63 |
-
* @since 4.12.1
|
| 64 |
-
*
|
| 65 |
-
* @var string|null
|
| 66 |
-
*/
|
| 67 |
-
protected $template_current_hook_name;
|
| 68 |
-
|
| 69 |
/**
|
| 70 |
* Base template for where to look for template
|
| 71 |
*
|
|
@@ -84,15 +66,6 @@ class Tribe__Template {
|
|
| 84 |
*/
|
| 85 |
protected $template_folder_lookup = false;
|
| 86 |
|
| 87 |
-
/**
|
| 88 |
-
* Create a class variable for the include path, to avoid conflicting with extract.
|
| 89 |
-
*
|
| 90 |
-
* @since 4.11.0
|
| 91 |
-
*
|
| 92 |
-
* @var string
|
| 93 |
-
*/
|
| 94 |
-
protected $template_current_file_path;
|
| 95 |
-
|
| 96 |
/**
|
| 97 |
* Configures the class origin plugin path
|
| 98 |
*
|
|
@@ -110,33 +83,19 @@ class Tribe__Template {
|
|
| 110 |
if ( is_string( $origin ) ) {
|
| 111 |
// Origin needs to be a class with a `instance` method
|
| 112 |
if ( class_exists( $origin ) && method_exists( $origin, 'instance' ) ) {
|
| 113 |
-
$origin = call_user_func(
|
| 114 |
}
|
| 115 |
}
|
| 116 |
|
| 117 |
-
if (
|
| 118 |
-
empty( $origin->plugin_path )
|
| 119 |
-
&& empty( $origin->pluginPath )
|
| 120 |
-
&& ! is_dir( $origin )
|
| 121 |
-
) {
|
| 122 |
throw new InvalidArgumentException( 'Invalid Origin Class for Template Instance' );
|
| 123 |
}
|
| 124 |
|
| 125 |
-
if ( is_string( $origin ) ) {
|
| 126 |
-
$this->template_base_path = array_filter(
|
| 127 |
-
(array) explode(
|
| 128 |
-
'/',
|
| 129 |
-
untrailingslashit( $origin )
|
| 130 |
-
)
|
| 131 |
-
);
|
| 132 |
-
} else {
|
| 133 |
$this->origin = $origin;
|
| 134 |
-
|
| 135 |
-
|
| 136 |
-
|
| 137 |
-
? $this->origin->plugin_path
|
| 138 |
-
: $this->origin->pluginPath
|
| 139 |
-
);
|
| 140 |
}
|
| 141 |
|
| 142 |
return $this;
|
|
@@ -168,23 +127,12 @@ class Tribe__Template {
|
|
| 168 |
return $this;
|
| 169 |
}
|
| 170 |
|
| 171 |
-
/**
|
| 172 |
-
* Returns the array for which folder this template instance is looking into.
|
| 173 |
-
*
|
| 174 |
-
* @since 4.11.0
|
| 175 |
-
*
|
| 176 |
-
* @return array Current folder we are looking for templates.
|
| 177 |
-
*/
|
| 178 |
-
public function get_template_folder() {
|
| 179 |
-
return $this->folder;
|
| 180 |
-
}
|
| 181 |
-
|
| 182 |
/**
|
| 183 |
* Configures the class with the base folder in relation to the Origin
|
| 184 |
*
|
| 185 |
* @since 4.7.20
|
| 186 |
*
|
| 187 |
-
* @param mixed
|
| 188 |
*
|
| 189 |
* @return self
|
| 190 |
*/
|
|
@@ -194,17 +142,6 @@ class Tribe__Template {
|
|
| 194 |
return $this;
|
| 195 |
}
|
| 196 |
|
| 197 |
-
/**
|
| 198 |
-
* Gets in this instance of the template engine whether we are looking public folders like themes.
|
| 199 |
-
*
|
| 200 |
-
* @since 4.12.1
|
| 201 |
-
*
|
| 202 |
-
* @return bool Whether we are looking into theme folders.
|
| 203 |
-
*/
|
| 204 |
-
public function get_template_folder_lookup() {
|
| 205 |
-
return $this->template_folder_lookup;
|
| 206 |
-
}
|
| 207 |
-
|
| 208 |
/**
|
| 209 |
* Configures the class global context
|
| 210 |
*
|
|
@@ -237,32 +174,6 @@ class Tribe__Template {
|
|
| 237 |
return $this;
|
| 238 |
}
|
| 239 |
|
| 240 |
-
/**
|
| 241 |
-
* Set the current hook name for the template include.
|
| 242 |
-
*
|
| 243 |
-
* @since 4.12.1
|
| 244 |
-
*
|
| 245 |
-
* @param string $value Which value will be saved as the current hookname.
|
| 246 |
-
*
|
| 247 |
-
* @return self Allow daisy-chaining.
|
| 248 |
-
*/
|
| 249 |
-
public function set_template_current_hook_name( $value ) {
|
| 250 |
-
$this->template_current_hook_name = (string) $value;
|
| 251 |
-
|
| 252 |
-
return $this;
|
| 253 |
-
}
|
| 254 |
-
|
| 255 |
-
/**
|
| 256 |
-
* Gets the hook name for the current template setup.
|
| 257 |
-
*
|
| 258 |
-
* @since 4.12.1
|
| 259 |
-
*
|
| 260 |
-
* @return string Hook name currently set on the class.
|
| 261 |
-
*/
|
| 262 |
-
public function get_template_current_hook_name() {
|
| 263 |
-
return $this->template_current_hook_name;
|
| 264 |
-
}
|
| 265 |
-
|
| 266 |
/**
|
| 267 |
* Sets a Index inside of the global or local context
|
| 268 |
* Final to prevent extending the class when the `get` already exists on the child class
|
|
@@ -345,14 +256,14 @@ class Tribe__Template {
|
|
| 345 |
*
|
| 346 |
* @return array
|
| 347 |
*/
|
| 348 |
-
public function merge_context( $context =
|
| 349 |
// Allow for simple null usage as well as array() for nothing
|
| 350 |
if ( is_null( $context ) ) {
|
| 351 |
-
$context =
|
| 352 |
}
|
| 353 |
|
| 354 |
-
// Applies
|
| 355 |
-
$context = wp_parse_args( (array) $context, $this->
|
| 356 |
|
| 357 |
/**
|
| 358 |
* Allows filtering the Local context
|
|
@@ -399,20 +310,15 @@ class Tribe__Template {
|
|
| 399 |
* in the theme's directory.
|
| 400 |
*
|
| 401 |
* @since 4.7.20
|
| 402 |
-
* @since 4.11.0 Added param $plugin_namespace.
|
| 403 |
*
|
| 404 |
-
* @
|
| 405 |
-
*
|
| 406 |
-
* @return array Namespace where we to look for templates.
|
| 407 |
*/
|
| 408 |
-
protected function get_template_public_namespace(
|
| 409 |
-
$namespace =
|
| 410 |
'tribe',
|
| 411 |
-
|
| 412 |
|
| 413 |
-
if ( ! empty( $
|
| 414 |
-
$namespace[] = $plugin_namespace;
|
| 415 |
-
} elseif ( ! empty( $this->origin->template_namespace ) ) {
|
| 416 |
$namespace[] = $this->origin->template_namespace;
|
| 417 |
}
|
| 418 |
|
|
@@ -428,46 +334,17 @@ class Tribe__Template {
|
|
| 428 |
}
|
| 429 |
|
| 430 |
/**
|
| 431 |
-
* Fetches
|
| 432 |
-
*
|
| 433 |
-
* @since 4.10.2
|
| 434 |
-
*
|
| 435 |
-
* @return array The base folders we look for templates in the origin plugin.
|
| 436 |
-
*/
|
| 437 |
-
public function get_template_origin_base_folder() {
|
| 438 |
-
/**
|
| 439 |
-
* Allows filtering of the base path for templates.
|
| 440 |
-
*
|
| 441 |
-
* @since 4.10.2
|
| 442 |
-
*
|
| 443 |
-
* @param array $namespace Which is the base folder we will look for files in the plugin.
|
| 444 |
-
* @param self $template Current instance of the Tribe__Template.
|
| 445 |
-
*/
|
| 446 |
-
return apply_filters( 'tribe_template_origin_base_folder', $this->template_origin_base_folder, $this );
|
| 447 |
-
}
|
| 448 |
-
|
| 449 |
-
/**
|
| 450 |
-
* Fetches the path for locating files given a base folder normally theme related.
|
| 451 |
*
|
| 452 |
* @since 4.7.20
|
| 453 |
-
* @since 4.11.0 Added the param $namespace.
|
| 454 |
*
|
| 455 |
-
* @param mixed $base
|
| 456 |
-
* @param string $namespace Adds the plugin namespace to the path returned.
|
| 457 |
*
|
| 458 |
-
* @return string
|
| 459 |
*/
|
| 460 |
-
protected function get_template_public_path( $base
|
| 461 |
-
|
| 462 |
// Craft the plugin Path
|
| 463 |
-
$path = array_merge( (array) $base, (array) $this->get_template_public_namespace(
|
| 464 |
-
|
| 465 |
-
// Pick up if the folder needs to be aded to the public template path.
|
| 466 |
-
$folder = array_diff( $this->folder, $this->get_template_origin_base_folder() );
|
| 467 |
-
|
| 468 |
-
if ( ! empty( $folder ) ) {
|
| 469 |
-
$path = array_merge( $path, $folder );
|
| 470 |
-
}
|
| 471 |
|
| 472 |
// Implode to avoid Window Problems
|
| 473 |
$path = implode( DIRECTORY_SEPARATOR, $path );
|
|
@@ -491,13 +368,27 @@ class Tribe__Template {
|
|
| 491 |
* @return array
|
| 492 |
*/
|
| 493 |
protected function get_template_path_list() {
|
| 494 |
-
$folders =
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 495 |
|
| 496 |
-
$folders[
|
| 497 |
-
'id'
|
| 498 |
-
'priority'
|
| 499 |
-
'path'
|
| 500 |
-
|
| 501 |
|
| 502 |
/**
|
| 503 |
* Allows filtering of the list of folders in which we will look for the
|
|
@@ -508,46 +399,7 @@ class Tribe__Template {
|
|
| 508 |
* @param array $folders Complete path to include the base public folder
|
| 509 |
* @param self $template Current instance of the Tribe__Template
|
| 510 |
*/
|
| 511 |
-
$folders =
|
| 512 |
-
|
| 513 |
-
uasort( $folders, 'tribe_sort_by_priority' );
|
| 514 |
-
|
| 515 |
-
return $folders;
|
| 516 |
-
}
|
| 517 |
-
|
| 518 |
-
/**
|
| 519 |
-
* Get the list of theme related folders we will look up for the template.
|
| 520 |
-
*
|
| 521 |
-
* @since 4.11.0
|
| 522 |
-
*
|
| 523 |
-
* @param string $namespace Which plugin namespace we are looking for.
|
| 524 |
-
*
|
| 525 |
-
* @return array
|
| 526 |
-
*/
|
| 527 |
-
protected function get_template_theme_path_list( $namespace ) {
|
| 528 |
-
$folders = [];
|
| 529 |
-
|
| 530 |
-
$folders['child-theme'] = [
|
| 531 |
-
'id' => 'child-theme',
|
| 532 |
-
'priority' => 10,
|
| 533 |
-
'path' => $this->get_template_public_path( STYLESHEETPATH, $namespace ),
|
| 534 |
-
];
|
| 535 |
-
$folders['parent-theme'] = [
|
| 536 |
-
'id' => 'parent-theme',
|
| 537 |
-
'priority' => 15,
|
| 538 |
-
'path' => $this->get_template_public_path( TEMPLATEPATH, $namespace ),
|
| 539 |
-
];
|
| 540 |
-
|
| 541 |
-
/**
|
| 542 |
-
* Allows filtering of the list of theme folders in which we will look for the template.
|
| 543 |
-
*
|
| 544 |
-
* @since 4.11.0
|
| 545 |
-
*
|
| 546 |
-
* @param array $folders Complete path to include the base public folder.
|
| 547 |
-
* @param string $namespace Loads the files from a specified folder from the themes.
|
| 548 |
-
* @param self $template Current instance of the Tribe__Template.
|
| 549 |
-
*/
|
| 550 |
-
$folders = (array) apply_filters( 'tribe_template_theme_path_list', $folders, $namespace, $this );
|
| 551 |
|
| 552 |
uasort( $folders, 'tribe_sort_by_priority' );
|
| 553 |
|
|
@@ -570,12 +422,11 @@ class Tribe__Template {
|
|
| 570 |
$name = (array) explode( '/', $name );
|
| 571 |
}
|
| 572 |
|
| 573 |
-
$folders
|
| 574 |
-
$found_file = false;
|
| 575 |
-
$namespace = false;
|
| 576 |
|
| 577 |
foreach ( $folders as $folder ) {
|
| 578 |
-
|
|
|
|
| 579 |
continue;
|
| 580 |
}
|
| 581 |
|
|
@@ -587,272 +438,64 @@ class Tribe__Template {
|
|
| 587 |
|
| 588 |
// Skip non-existent files
|
| 589 |
if ( file_exists( $file ) ) {
|
| 590 |
-
|
| 591 |
-
|
| 592 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 593 |
}
|
| 594 |
}
|
| 595 |
|
| 596 |
-
if ( $this->get_template_folder_lookup() ) {
|
| 597 |
-
$theme_folders = $this->get_template_theme_path_list( $namespace );
|
| 598 |
-
|
| 599 |
-
foreach ( $theme_folders as $folder ) {
|
| 600 |
-
if ( empty( $folder['path'] ) ) {
|
| 601 |
-
continue;
|
| 602 |
-
}
|
| 603 |
-
|
| 604 |
-
// Build the File Path
|
| 605 |
-
$file = implode( DIRECTORY_SEPARATOR, array_merge( (array) $folder['path'], $name ) );
|
| 606 |
-
|
| 607 |
-
// Append the Extension to the file path
|
| 608 |
-
$file .= '.php';
|
| 609 |
-
|
| 610 |
-
// Skip non-existent files
|
| 611 |
-
if ( file_exists( $file ) ) {
|
| 612 |
-
$found_file = $file;
|
| 613 |
-
break;
|
| 614 |
-
}
|
| 615 |
-
}
|
| 616 |
-
}
|
| 617 |
-
|
| 618 |
-
if ( $found_file ) {
|
| 619 |
-
/**
|
| 620 |
-
* A more Specific Filter that will include the template name
|
| 621 |
-
*
|
| 622 |
-
* @since 4.6.2
|
| 623 |
-
* @since 4.7.20 The $name param no longer contains the extension
|
| 624 |
-
*
|
| 625 |
-
* @param string $file Complete path to include the PHP File
|
| 626 |
-
* @param array $name Template name
|
| 627 |
-
* @param self $template Current instance of the Tribe__Template
|
| 628 |
-
*/
|
| 629 |
-
return apply_filters( 'tribe_template_file', $found_file, $name, $this );
|
| 630 |
-
}
|
| 631 |
-
|
| 632 |
// Couldn't find a template on the Stack
|
| 633 |
return false;
|
| 634 |
}
|
| 635 |
|
| 636 |
-
/**
|
| 637 |
-
* Runs the entry point hooks and filters.
|
| 638 |
-
*
|
| 639 |
-
* @param string $entry_point_name The name of the entry point.
|
| 640 |
-
* @param boolean $echo If we should also print the entry point content.
|
| 641 |
-
*
|
| 642 |
-
* @return null|string `null` if an entry point is disabled or the entry point HTML.
|
| 643 |
-
*/
|
| 644 |
-
public function do_entry_point( $entry_point_name, $echo = true ) {
|
| 645 |
-
$hook_name = $this->get_template_current_hook_name();
|
| 646 |
-
|
| 647 |
-
/**
|
| 648 |
-
* Filter if the entry points are enabled.
|
| 649 |
-
*
|
| 650 |
-
* @since 4.12.1
|
| 651 |
-
*
|
| 652 |
-
* @param boolean $is_enabled Is entry_point enabled.
|
| 653 |
-
* @param string $hook_name For which template include this entry point belongs.
|
| 654 |
-
* @param string $entry_point_name Which entry point specifically we are triggering.
|
| 655 |
-
* @param self $template Current instance of the template class doing this entry point.
|
| 656 |
-
*/
|
| 657 |
-
$is_entry_point_enabled = apply_filters( 'tribe_template_entry_point_is_enabled', true, $hook_name, $entry_point_name, $this );
|
| 658 |
-
|
| 659 |
-
if ( ! $is_entry_point_enabled ) {
|
| 660 |
-
return null;
|
| 661 |
-
}
|
| 662 |
-
|
| 663 |
-
ob_start();
|
| 664 |
-
|
| 665 |
-
if ( has_action( "tribe_template_entry_point:$hook_name" ) ) {
|
| 666 |
-
/**
|
| 667 |
-
* Generic entry point action for the current template.
|
| 668 |
-
*
|
| 669 |
-
* @since 4.12.1
|
| 670 |
-
*
|
| 671 |
-
* @param string $hook_name For which template include this entry point belongs.
|
| 672 |
-
* @param string $entry_point_name Which entry point specifically we are triggering.
|
| 673 |
-
* @param self $template Current instance of the template class doing this entry point.
|
| 674 |
-
*/
|
| 675 |
-
do_action( "tribe_template_entry_point:$hook_name", $hook_name, $entry_point_name, $this );
|
| 676 |
-
}
|
| 677 |
-
|
| 678 |
-
if ( has_action( "tribe_template_entry_point:$hook_name:$entry_point_name" ) ) {
|
| 679 |
-
/**
|
| 680 |
-
* Specific named entry point action called.
|
| 681 |
-
*
|
| 682 |
-
* @since 4.12.1
|
| 683 |
-
*
|
| 684 |
-
* @param string $hook_name For which template include this entry point belongs.
|
| 685 |
-
* @param string $entry_point_name Which entry point specifically we are triggering.
|
| 686 |
-
* @param self $template Current instance of the template class doing this entry point.
|
| 687 |
-
*/
|
| 688 |
-
do_action( "tribe_template_entry_point:$hook_name:$entry_point_name", $hook_name, $entry_point_name, $this );
|
| 689 |
-
}
|
| 690 |
-
|
| 691 |
-
$html = ob_get_clean();
|
| 692 |
-
|
| 693 |
-
if ( has_filter( "tribe_template_entry_point_html:$hook_name" ) ) {
|
| 694 |
-
/**
|
| 695 |
-
* Generic entry point action for the current template.
|
| 696 |
-
*
|
| 697 |
-
* @since 4.12.1
|
| 698 |
-
*
|
| 699 |
-
* @param string $html HTML returned and/or echoed for this for this entry point.
|
| 700 |
-
* @param string $hook_name For which template include this entry point belongs.
|
| 701 |
-
* @param string $entry_point_name Which entry point specifically we are triggering.
|
| 702 |
-
* @param self $template Current instance of the template class doing this entry point.
|
| 703 |
-
*/
|
| 704 |
-
$html = apply_filters( "tribe_template_entry_point_html:$hook_name", $html, $hook_name, $entry_point_name, $this );
|
| 705 |
-
}
|
| 706 |
-
|
| 707 |
-
if ( has_filter( "tribe_template_entry_point_html:$hook_name:$entry_point_name" ) ) {
|
| 708 |
-
/**
|
| 709 |
-
* Specific named entry point action called.
|
| 710 |
-
*
|
| 711 |
-
* @since 4.12.1
|
| 712 |
-
*
|
| 713 |
-
* @param string $html HTML returned and/or echoed for this for this entry point.
|
| 714 |
-
* @param string $hook_name For which template include this entry point belongs.
|
| 715 |
-
* @param string $entry_point_name Which entry point specifically we are triggering.
|
| 716 |
-
* @param self $template Current instance of the template class doing this entry point.
|
| 717 |
-
*/
|
| 718 |
-
$html = apply_filters( "tribe_template_entry_point_html:$hook_name:$entry_point_name", $html, $hook_name, $entry_point_name, $this );
|
| 719 |
-
}
|
| 720 |
-
|
| 721 |
-
if ( $echo ) {
|
| 722 |
-
echo $html;
|
| 723 |
-
}
|
| 724 |
-
|
| 725 |
-
return $html;
|
| 726 |
-
}
|
| 727 |
-
|
| 728 |
/**
|
| 729 |
* A very simple method to include a Template, allowing filtering and additions using hooks.
|
| 730 |
*
|
| 731 |
* @since 4.6.2
|
| 732 |
*
|
| 733 |
-
* @param string
|
| 734 |
-
*
|
| 735 |
-
* @param
|
| 736 |
-
* @param boolean $echo If we should also print the Template
|
| 737 |
*
|
| 738 |
* @return string|false Either the final content HTML or `false` if no template could be found.
|
| 739 |
*/
|
| 740 |
-
public function template( $name, $context =
|
| 741 |
-
|
| 742 |
-
|
| 743 |
-
|
| 744 |
-
|
| 745 |
-
/**
|
| 746 |
-
* Allow users to disable templates before rendering it by returning empty string.
|
| 747 |
-
*
|
| 748 |
-
* @since 4.12.0
|
| 749 |
-
*
|
| 750 |
-
* @param string null Whether to continue displaying the template or not.
|
| 751 |
-
* @param array $name Template name.
|
| 752 |
-
* @param array $context Any context data you need to expose to this file.
|
| 753 |
-
* @param boolean $echo If we should also print the Template.
|
| 754 |
-
*/
|
| 755 |
-
$done = apply_filters( 'tribe_template_done', null, $name, $context, $echo );
|
| 756 |
-
|
| 757 |
-
if ( null !== $done ) {
|
| 758 |
-
return false;
|
| 759 |
}
|
| 760 |
|
| 761 |
-
//
|
| 762 |
-
$
|
| 763 |
|
| 764 |
-
|
| 765 |
-
|
| 766 |
-
|
| 767 |
-
|
| 768 |
-
$name = (array) explode( '/', $name );
|
| 769 |
-
}
|
| 770 |
-
|
| 771 |
-
// Clean this Variable
|
| 772 |
-
$name = array_map( 'sanitize_title_with_dashes', $name );
|
| 773 |
-
|
| 774 |
-
$template_names[ $cache_name_key ] = $name;
|
| 775 |
}
|
| 776 |
|
| 777 |
-
//
|
| 778 |
-
|
| 779 |
-
! isset( $file_exists[ $cache_name_key ] )
|
| 780 |
-
|| ! isset( $files[ $cache_name_key ] )
|
| 781 |
-
) {
|
| 782 |
-
// Check if the file exists
|
| 783 |
-
$files[ $cache_name_key ] = $file = $this->get_template_file( $name );
|
| 784 |
-
|
| 785 |
-
// Check if it's a valid variable
|
| 786 |
-
if ( ! $file ) {
|
| 787 |
-
return $file_exists[ $cache_name_key ] = false;
|
| 788 |
-
}
|
| 789 |
-
|
| 790 |
-
// Before we load the file we check if it exists
|
| 791 |
-
if ( ! file_exists( $file ) ) {
|
| 792 |
-
return $file_exists[ $cache_name_key ] = false;
|
| 793 |
-
}
|
| 794 |
|
| 795 |
-
|
| 796 |
-
|
| 797 |
|
| 798 |
-
//
|
| 799 |
-
if ( ! $
|
| 800 |
return false;
|
| 801 |
}
|
| 802 |
|
| 803 |
-
//
|
| 804 |
-
$file
|
| 805 |
-
|
| 806 |
-
$origin_folder_appendix = array_diff( $this->folder, $this->template_origin_base_folder );
|
| 807 |
-
|
| 808 |
-
if ( $origin_namespace = $this->template_get_origin_namespace( $file ) ) {
|
| 809 |
-
$legacy_namespace = array_merge( (array) $origin_namespace, $name );
|
| 810 |
-
$namespace = array_merge( (array) $origin_namespace, $origin_folder_appendix, $name );
|
| 811 |
-
} else {
|
| 812 |
-
$legacy_namespace = $name;
|
| 813 |
-
$namespace = array_merge( $origin_folder_appendix, $legacy_namespace );
|
| 814 |
-
}
|
| 815 |
-
|
| 816 |
-
// Setup the Hook name.
|
| 817 |
-
$legacy_hook_name = implode( '/', $legacy_namespace );
|
| 818 |
-
$hook_name = implode( '/', $namespace );
|
| 819 |
-
|
| 820 |
-
$prev_hook_name = $this->get_template_current_hook_name();
|
| 821 |
-
|
| 822 |
-
// Store the current hook name for the purposes of entry-points.
|
| 823 |
-
$this->set_template_current_hook_name( $hook_name );
|
| 824 |
-
|
| 825 |
-
/**
|
| 826 |
-
* Allow users to filter the HTML before rendering
|
| 827 |
-
*
|
| 828 |
-
* @since 4.11.0
|
| 829 |
-
*
|
| 830 |
-
* @param string $html The initial HTML
|
| 831 |
-
* @param string $file Complete path to include the PHP File
|
| 832 |
-
* @param array $name Template name
|
| 833 |
-
* @param self $template Current instance of the Tribe__Template
|
| 834 |
-
*/
|
| 835 |
-
$pre_html = apply_filters( 'tribe_template_pre_html', null, $file, $name, $this );
|
| 836 |
-
|
| 837 |
-
/**
|
| 838 |
-
* Allow users to filter the HTML by the name before rendering
|
| 839 |
-
*
|
| 840 |
-
* E.g.:
|
| 841 |
-
* `tribe_template_pre_html:events/blocks/parts/details`
|
| 842 |
-
* `tribe_template_pre_html:events/embed`
|
| 843 |
-
* `tribe_template_pre_html:tickets/login-to-purchase`
|
| 844 |
-
*
|
| 845 |
-
* @since 4.11.0
|
| 846 |
-
*
|
| 847 |
-
* @param string $html The initial HTML
|
| 848 |
-
* @param string $file Complete path to include the PHP File
|
| 849 |
-
* @param array $name Template name
|
| 850 |
-
* @param self $template Current instance of the Tribe__Template
|
| 851 |
-
*/
|
| 852 |
-
$pre_html = apply_filters( "tribe_template_pre_html:$hook_name", $pre_html, $file, $name, $this );
|
| 853 |
-
|
| 854 |
-
if ( null !== $pre_html ) {
|
| 855 |
-
return $pre_html;
|
| 856 |
}
|
| 857 |
|
| 858 |
ob_start();
|
|
@@ -864,7 +507,7 @@ class Tribe__Template {
|
|
| 864 |
* Fires an Action before including the template file
|
| 865 |
*
|
| 866 |
* @since 4.6.2
|
| 867 |
-
* @since 4.7.20 The $name param no
|
| 868 |
*
|
| 869 |
* @param string $file Complete path to include the PHP File
|
| 870 |
* @param array $name Template name
|
|
@@ -872,23 +515,6 @@ class Tribe__Template {
|
|
| 872 |
*/
|
| 873 |
do_action( 'tribe_template_before_include', $file, $name, $this );
|
| 874 |
|
| 875 |
-
/**
|
| 876 |
-
* Fires an Action for a given template name before including the template file
|
| 877 |
-
*
|
| 878 |
-
* E.g.:
|
| 879 |
-
* `tribe_template_before_include:events/blocks/parts/details`
|
| 880 |
-
* `tribe_template_before_include:events/embed`
|
| 881 |
-
* `tribe_template_before_include:tickets/login-to-purchase`
|
| 882 |
-
*
|
| 883 |
-
* @deprecated 4.11.0
|
| 884 |
-
* @since 4.7.20
|
| 885 |
-
*
|
| 886 |
-
* @param string $file Complete path to include the PHP File
|
| 887 |
-
* @param array $name Template name
|
| 888 |
-
* @param self $template Current instance of the Tribe__Template
|
| 889 |
-
*/
|
| 890 |
-
do_action( "tribe_template_before_include:$legacy_hook_name", $file, $name, $this );
|
| 891 |
-
|
| 892 |
/**
|
| 893 |
* Fires an Action for a given template name before including the template file
|
| 894 |
*
|
|
@@ -905,13 +531,29 @@ class Tribe__Template {
|
|
| 905 |
*/
|
| 906 |
do_action( "tribe_template_before_include:$hook_name", $file, $name, $this );
|
| 907 |
|
| 908 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 909 |
|
| 910 |
/**
|
| 911 |
* Fires an Action after including the template file
|
| 912 |
*
|
| 913 |
* @since 4.6.2
|
| 914 |
-
* @since 4.7.20 The $name param no
|
| 915 |
*
|
| 916 |
* @param string $file Complete path to include the PHP File
|
| 917 |
* @param array $name Template name
|
|
@@ -919,23 +561,6 @@ class Tribe__Template {
|
|
| 919 |
*/
|
| 920 |
do_action( 'tribe_template_after_include', $file, $name, $this );
|
| 921 |
|
| 922 |
-
/**
|
| 923 |
-
* Fires an Action for a given template name after including the template file
|
| 924 |
-
*
|
| 925 |
-
* E.g.:
|
| 926 |
-
* `tribe_template_after_include:events/blocks/parts/details`
|
| 927 |
-
* `tribe_template_after_include:events/embed`
|
| 928 |
-
* `tribe_template_after_include:tickets/login-to-purchase`
|
| 929 |
-
*
|
| 930 |
-
* @deprecated 4.11.0
|
| 931 |
-
* @since 4.7.20
|
| 932 |
-
*
|
| 933 |
-
* @param string $file Complete path to include the PHP File
|
| 934 |
-
* @param array $name Template name
|
| 935 |
-
* @param self $template Current instance of the Tribe__Template
|
| 936 |
-
*/
|
| 937 |
-
do_action( "tribe_template_after_include:$legacy_hook_name", $file, $name, $this );
|
| 938 |
-
|
| 939 |
/**
|
| 940 |
* Fires an Action for a given template name after including the template file
|
| 941 |
*
|
|
@@ -959,7 +584,7 @@ class Tribe__Template {
|
|
| 959 |
* Allow users to filter the final HTML
|
| 960 |
*
|
| 961 |
* @since 4.6.2
|
| 962 |
-
* @since 4.7.20 The $name param no
|
| 963 |
*
|
| 964 |
* @param string $html The final HTML
|
| 965 |
* @param string $file Complete path to include the PHP File
|
|
@@ -968,24 +593,6 @@ class Tribe__Template {
|
|
| 968 |
*/
|
| 969 |
$html = apply_filters( 'tribe_template_html', $html, $file, $name, $this );
|
| 970 |
|
| 971 |
-
/**
|
| 972 |
-
* Allow users to filter the final HTML by the name
|
| 973 |
-
*
|
| 974 |
-
* E.g.:
|
| 975 |
-
* `tribe_template_html:events/blocks/parts/details`
|
| 976 |
-
* `tribe_template_html:events/embed`
|
| 977 |
-
* `tribe_template_html:tickets/login-to-purchase`
|
| 978 |
-
*
|
| 979 |
-
* @deprecated 4.11.0
|
| 980 |
-
* @since 4.7.20
|
| 981 |
-
*
|
| 982 |
-
* @param string $html The final HTML
|
| 983 |
-
* @param string $file Complete path to include the PHP File
|
| 984 |
-
* @param array $name Template name
|
| 985 |
-
* @param self $template Current instance of the Tribe__Template
|
| 986 |
-
*/
|
| 987 |
-
$html = apply_filters( "tribe_template_html:$legacy_hook_name", $html, $file, $name, $this );
|
| 988 |
-
|
| 989 |
/**
|
| 990 |
* Allow users to filter the final HTML by the name
|
| 991 |
*
|
|
@@ -1003,146 +610,13 @@ class Tribe__Template {
|
|
| 1003 |
*/
|
| 1004 |
$html = apply_filters( "tribe_template_html:$hook_name", $html, $file, $name, $this );
|
| 1005 |
|
| 1006 |
-
// Tries to hook container entry points in the HTML.
|
| 1007 |
-
$html = $this->template_hook_container_entry_points( $html );
|
| 1008 |
-
|
| 1009 |
if ( $echo ) {
|
| 1010 |
echo $html;
|
| 1011 |
}
|
| 1012 |
|
| 1013 |
-
// Revert the current hook name.
|
| 1014 |
-
$this->set_template_current_hook_name( $prev_hook_name );
|
| 1015 |
-
|
| 1016 |
return $html;
|
| 1017 |
}
|
| 1018 |
|
| 1019 |
-
/**
|
| 1020 |
-
* Run the hooks for the container entry points.
|
| 1021 |
-
*
|
| 1022 |
-
* @since 4.12.1
|
| 1023 |
-
*
|
| 1024 |
-
* @param string $html The html of the current template.
|
| 1025 |
-
*
|
| 1026 |
-
* @return string|false Either the final entry point content HTML or `false` if no entry point could be found or set to false.
|
| 1027 |
-
*/
|
| 1028 |
-
private function template_hook_container_entry_points( $html ) {
|
| 1029 |
-
|
| 1030 |
-
$matches = $this->get_entry_point_matches( $html );
|
| 1031 |
-
$html_matches = $matches[0];
|
| 1032 |
-
|
| 1033 |
-
if ( 0 === count( $html_matches ) ) {
|
| 1034 |
-
return $html;
|
| 1035 |
-
}
|
| 1036 |
-
|
| 1037 |
-
$html_tags = $matches['tag'];
|
| 1038 |
-
$html_tags_ends = $matches['is_end'];
|
| 1039 |
-
|
| 1040 |
-
// Get first and last tags.
|
| 1041 |
-
$first_tag = reset( $html_tags );
|
| 1042 |
-
$last_tag = end( $html_tags );
|
| 1043 |
-
|
| 1044 |
-
// Determine if first last tags are tag ends.
|
| 1045 |
-
$first_tag_is_end = '/' === reset( $html_tags_ends );
|
| 1046 |
-
$last_tag_is_end = '/' === end( $html_tags_ends );
|
| 1047 |
-
|
| 1048 |
-
// When first and last tag are not the same, bail.
|
| 1049 |
-
if ( $first_tag !== $last_tag ) {
|
| 1050 |
-
return $html;
|
| 1051 |
-
}
|
| 1052 |
-
|
| 1053 |
-
// If the first tag is a html tag end, bail.
|
| 1054 |
-
if ( $first_tag_is_end ) {
|
| 1055 |
-
return $html;
|
| 1056 |
-
}
|
| 1057 |
-
|
| 1058 |
-
// If the last tag is not and html tag end, bail.
|
| 1059 |
-
if ( ! $last_tag_is_end ) {
|
| 1060 |
-
return $html;
|
| 1061 |
-
}
|
| 1062 |
-
|
| 1063 |
-
$first_tag_html = reset( $html_matches );
|
| 1064 |
-
$last_tag_html = end( $html_matches );
|
| 1065 |
-
|
| 1066 |
-
$open_container_entry_point_html = $this->do_entry_point( 'after_container_open', false );
|
| 1067 |
-
$close_container_entry_point_html = $this->do_entry_point( 'before_container_close', false );
|
| 1068 |
-
|
| 1069 |
-
$html = Strings::replace_first( $first_tag_html, $first_tag_html . $open_container_entry_point_html, $html );
|
| 1070 |
-
$html = Strings::replace_last( $last_tag_html, $close_container_entry_point_html . $last_tag_html, $html );
|
| 1071 |
-
|
| 1072 |
-
return $html;
|
| 1073 |
-
}
|
| 1074 |
-
|
| 1075 |
-
/**
|
| 1076 |
-
* Based on a path it determines what is the namespace that should be used.
|
| 1077 |
-
*
|
| 1078 |
-
* @since 4.11.0
|
| 1079 |
-
*
|
| 1080 |
-
* @param string $path Which file we are going to load.
|
| 1081 |
-
*
|
| 1082 |
-
* @return string|false The found namespace for that path or false.
|
| 1083 |
-
*/
|
| 1084 |
-
public function template_get_origin_namespace( $path ) {
|
| 1085 |
-
$matching_namespace = false;
|
| 1086 |
-
/**
|
| 1087 |
-
* Allows more namespaces to be added based on the path of the file we are loading.
|
| 1088 |
-
*
|
| 1089 |
-
* @since 4.11.0
|
| 1090 |
-
*
|
| 1091 |
-
* @param array $namespace_map Indexed array containing the namespace as the key and path to `strpos`.
|
| 1092 |
-
* @param string $path Path we will do the `strpos` to validate a given namespace.
|
| 1093 |
-
* @param self $template Current instance of the template class.
|
| 1094 |
-
*/
|
| 1095 |
-
$namespace_map = (array) apply_filters( 'tribe_template_origin_namespace_map', [], $path, $this );
|
| 1096 |
-
|
| 1097 |
-
foreach ( $namespace_map as $namespace => $contains_string ) {
|
| 1098 |
-
// Skip when we dont have the namespace path.
|
| 1099 |
-
if ( false === strpos( $path, $contains_string ) ) {
|
| 1100 |
-
continue;
|
| 1101 |
-
}
|
| 1102 |
-
|
| 1103 |
-
$matching_namespace = $namespace;
|
| 1104 |
-
|
| 1105 |
-
// Once the first namespace is found it breaks out.
|
| 1106 |
-
break;
|
| 1107 |
-
}
|
| 1108 |
-
|
| 1109 |
-
if ( empty( $matching_namespace ) && ! empty( $this->origin->template_namespace ) ) {
|
| 1110 |
-
$matching_namespace = $this->origin->template_namespace;
|
| 1111 |
-
}
|
| 1112 |
-
|
| 1113 |
-
return $matching_namespace;
|
| 1114 |
-
}
|
| 1115 |
-
|
| 1116 |
-
/**
|
| 1117 |
-
* Includes a give PHP inside of a safe context.
|
| 1118 |
-
*
|
| 1119 |
-
* This method is required to prevent template files messing with local variables used inside of the
|
| 1120 |
-
* `self::template` method. Also shelters the template loading from any possible variables that could
|
| 1121 |
-
* be overwritten by the context.
|
| 1122 |
-
*
|
| 1123 |
-
* @since 4.11.0
|
| 1124 |
-
*
|
| 1125 |
-
* @param string $file Which file will be included with safe context.
|
| 1126 |
-
*
|
| 1127 |
-
* @return void
|
| 1128 |
-
*/
|
| 1129 |
-
public function template_safe_include( $file ) {
|
| 1130 |
-
// We use this instance variable to prevent collisions.
|
| 1131 |
-
$this->template_current_file_path = $file;
|
| 1132 |
-
unset( $file );
|
| 1133 |
-
|
| 1134 |
-
// Only do this if really needed (by default it wont).
|
| 1135 |
-
if ( true === $this->template_context_extract && ! empty( $this->context ) ) {
|
| 1136 |
-
// Make any provided variables available in the template variable scope.
|
| 1137 |
-
extract( $this->context ); // @phpcs:ignore
|
| 1138 |
-
}
|
| 1139 |
-
|
| 1140 |
-
include $this->template_current_file_path;
|
| 1141 |
-
|
| 1142 |
-
// After the include we reset the variable.
|
| 1143 |
-
unset( $this->template_current_file_path );
|
| 1144 |
-
}
|
| 1145 |
-
|
| 1146 |
/**
|
| 1147 |
* Sets a number of values at the same time.
|
| 1148 |
*
|
|
@@ -1193,38 +667,4 @@ class Tribe__Template {
|
|
| 1193 |
public function get_values() {
|
| 1194 |
return array_merge( $this->get_global_values(), $this->get_local_values() );
|
| 1195 |
}
|
| 1196 |
-
|
| 1197 |
-
/**
|
| 1198 |
-
* Get the Entry Point Matches.
|
| 1199 |
-
*
|
| 1200 |
-
* @since 4.12.1
|
| 1201 |
-
*
|
| 1202 |
-
* @param string $html The html of the current template.
|
| 1203 |
-
*
|
| 1204 |
-
* @return array An array of matches from the regular expression.
|
| 1205 |
-
*/
|
| 1206 |
-
private function get_entry_point_matches( $html ) {
|
| 1207 |
-
// Set up cache key using current hook name.
|
| 1208 |
-
$hook_name = $this->get_template_current_hook_name();
|
| 1209 |
-
$key = "tribe_template_entry_point_cache:{$hook_name}";
|
| 1210 |
-
|
| 1211 |
-
// Get cache instance.
|
| 1212 |
-
$cache = tribe_cache();
|
| 1213 |
-
|
| 1214 |
-
// Get cached value (if set).
|
| 1215 |
-
$cached = $cache[ $key ];
|
| 1216 |
-
|
| 1217 |
-
if ( false !== $cached ) {
|
| 1218 |
-
return $cached;
|
| 1219 |
-
}
|
| 1220 |
-
|
| 1221 |
-
$regexp = '/<(?<is_end>\/)*(?<tag>[A-Z0-9]*)(?:\b)*[^>]*>/mi';
|
| 1222 |
-
|
| 1223 |
-
preg_match_all( $regexp, $html, $matches );
|
| 1224 |
-
|
| 1225 |
-
$cache[ $key ] = $matches;
|
| 1226 |
-
|
| 1227 |
-
return $matches;
|
| 1228 |
-
}
|
| 1229 |
-
|
| 1230 |
}
|
| 1 |
<?php
|
| 2 |
|
| 3 |
+
use Tribe\Events\Views\V2\Template;
|
| 4 |
|
| 5 |
class Tribe__Template {
|
| 6 |
/**
|
| 40 |
protected $global = array();
|
| 41 |
|
| 42 |
/**
|
| 43 |
+
* Allow chaing if class will extract data from the local context
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 44 |
*
|
| 45 |
* @since 4.6.2
|
| 46 |
*
|
| 48 |
*/
|
| 49 |
protected $template_context_extract = false;
|
| 50 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 51 |
/**
|
| 52 |
* Base template for where to look for template
|
| 53 |
*
|
| 66 |
*/
|
| 67 |
protected $template_folder_lookup = false;
|
| 68 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 69 |
/**
|
| 70 |
* Configures the class origin plugin path
|
| 71 |
*
|
| 83 |
if ( is_string( $origin ) ) {
|
| 84 |
// Origin needs to be a class with a `instance` method
|
| 85 |
if ( class_exists( $origin ) && method_exists( $origin, 'instance' ) ) {
|
| 86 |
+
$origin = call_user_func( array( $origin, 'instance' ) );
|
| 87 |
}
|
| 88 |
}
|
| 89 |
|
| 90 |
+
if ( empty( $origin->plugin_path ) && empty( $origin->pluginPath ) && ! is_dir( $origin ) ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
| 91 |
throw new InvalidArgumentException( 'Invalid Origin Class for Template Instance' );
|
| 92 |
}
|
| 93 |
|
| 94 |
+
if ( ! is_string( $origin ) ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 95 |
$this->origin = $origin;
|
| 96 |
+
$this->template_base_path = untrailingslashit( ! empty( $this->origin->plugin_path ) ? $this->origin->plugin_path : $this->origin->pluginPath );
|
| 97 |
+
} else {
|
| 98 |
+
$this->template_base_path = untrailingslashit( (array) explode( '/', $origin ) );
|
|
|
|
|
|
|
|
|
|
| 99 |
}
|
| 100 |
|
| 101 |
return $this;
|
| 127 |
return $this;
|
| 128 |
}
|
| 129 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 130 |
/**
|
| 131 |
* Configures the class with the base folder in relation to the Origin
|
| 132 |
*
|
| 133 |
* @since 4.7.20
|
| 134 |
*
|
| 135 |
+
* @param mixed $use Should we look for template files in the list of folders
|
| 136 |
*
|
| 137 |
* @return self
|
| 138 |
*/
|
| 142 |
return $this;
|
| 143 |
}
|
| 144 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 145 |
/**
|
| 146 |
* Configures the class global context
|
| 147 |
*
|
| 174 |
return $this;
|
| 175 |
}
|
| 176 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 177 |
/**
|
| 178 |
* Sets a Index inside of the global or local context
|
| 179 |
* Final to prevent extending the class when the `get` already exists on the child class
|
| 256 |
*
|
| 257 |
* @return array
|
| 258 |
*/
|
| 259 |
+
public function merge_context( $context = array(), $file = null, $name = null ) {
|
| 260 |
// Allow for simple null usage as well as array() for nothing
|
| 261 |
if ( is_null( $context ) ) {
|
| 262 |
+
$context = array();
|
| 263 |
}
|
| 264 |
|
| 265 |
+
// Applies local context on top of Global one
|
| 266 |
+
$context = wp_parse_args( (array) $context, $this->global );
|
| 267 |
|
| 268 |
/**
|
| 269 |
* Allows filtering the Local context
|
| 310 |
* in the theme's directory.
|
| 311 |
*
|
| 312 |
* @since 4.7.20
|
|
|
|
| 313 |
*
|
| 314 |
+
* @return array
|
|
|
|
|
|
|
| 315 |
*/
|
| 316 |
+
protected function get_template_public_namespace() {
|
| 317 |
+
$namespace = array(
|
| 318 |
'tribe',
|
| 319 |
+
);
|
| 320 |
|
| 321 |
+
if ( ! empty( $this->origin->template_namespace ) ) {
|
|
|
|
|
|
|
| 322 |
$namespace[] = $this->origin->template_namespace;
|
| 323 |
}
|
| 324 |
|
| 334 |
}
|
| 335 |
|
| 336 |
/**
|
| 337 |
+
* Fetches the path for locating files given a base folder normally theme related
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 338 |
*
|
| 339 |
* @since 4.7.20
|
|
|
|
| 340 |
*
|
| 341 |
+
* @param mixed $base Base path to look into
|
|
|
|
| 342 |
*
|
| 343 |
+
* @return string
|
| 344 |
*/
|
| 345 |
+
protected function get_template_public_path( $base ) {
|
|
|
|
| 346 |
// Craft the plugin Path
|
| 347 |
+
$path = array_merge( (array) $base, (array) $this->get_template_public_namespace() );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 348 |
|
| 349 |
// Implode to avoid Window Problems
|
| 350 |
$path = implode( DIRECTORY_SEPARATOR, $path );
|
| 368 |
* @return array
|
| 369 |
*/
|
| 370 |
protected function get_template_path_list() {
|
| 371 |
+
$folders = array();
|
| 372 |
+
|
| 373 |
+
// Only look into public folders if we tell to use folders
|
| 374 |
+
if ( $this->template_folder_lookup ) {
|
| 375 |
+
$folders[] = array(
|
| 376 |
+
'id' => 'child-theme',
|
| 377 |
+
'priority' => 10,
|
| 378 |
+
'path' => $this->get_template_public_path( STYLESHEETPATH ),
|
| 379 |
+
);
|
| 380 |
+
$folders[] = array(
|
| 381 |
+
'id' => 'parent-theme',
|
| 382 |
+
'priority' => 15,
|
| 383 |
+
'path' => $this->get_template_public_path( TEMPLATEPATH ),
|
| 384 |
+
);
|
| 385 |
+
}
|
| 386 |
|
| 387 |
+
$folders[] = array(
|
| 388 |
+
'id' => 'plugin',
|
| 389 |
+
'priority' => 20,
|
| 390 |
+
'path' => $this->get_template_plugin_path(),
|
| 391 |
+
);
|
| 392 |
|
| 393 |
/**
|
| 394 |
* Allows filtering of the list of folders in which we will look for the
|
| 399 |
* @param array $folders Complete path to include the base public folder
|
| 400 |
* @param self $template Current instance of the Tribe__Template
|
| 401 |
*/
|
| 402 |
+
$folders = apply_filters( 'tribe_template_path_list', $folders, $this );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 403 |
|
| 404 |
uasort( $folders, 'tribe_sort_by_priority' );
|
| 405 |
|
| 422 |
$name = (array) explode( '/', $name );
|
| 423 |
}
|
| 424 |
|
| 425 |
+
$folders = $this->get_template_path_list();
|
|
|
|
|
|
|
| 426 |
|
| 427 |
foreach ( $folders as $folder ) {
|
| 428 |
+
$folder['path'] = trim( $folder['path'] );
|
| 429 |
+
if ( ! $folder['path'] ) {
|
| 430 |
continue;
|
| 431 |
}
|
| 432 |
|
| 438 |
|
| 439 |
// Skip non-existent files
|
| 440 |
if ( file_exists( $file ) ) {
|
| 441 |
+
/**
|
| 442 |
+
* A more Specific Filter that will include the template name
|
| 443 |
+
*
|
| 444 |
+
* @since 4.6.2
|
| 445 |
+
* @since 4.7.20 The $name param no longers contains the extension
|
| 446 |
+
*
|
| 447 |
+
* @param string $file Complete path to include the PHP File
|
| 448 |
+
* @param array $name Template name
|
| 449 |
+
* @param self $template Current instance of the Tribe__Template
|
| 450 |
+
*/
|
| 451 |
+
return apply_filters( 'tribe_template_file', $file, $name, $this );
|
| 452 |
}
|
| 453 |
}
|
| 454 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 455 |
// Couldn't find a template on the Stack
|
| 456 |
return false;
|
| 457 |
}
|
| 458 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 459 |
/**
|
| 460 |
* A very simple method to include a Template, allowing filtering and additions using hooks.
|
| 461 |
*
|
| 462 |
* @since 4.6.2
|
| 463 |
*
|
| 464 |
+
* @param string $name Which file we are talking about including
|
| 465 |
+
* @param array $context Any context data you need to expose to this file
|
| 466 |
+
* @param boolean $echo If we should also print the Template
|
|
|
|
| 467 |
*
|
| 468 |
* @return string|false Either the final content HTML or `false` if no template could be found.
|
| 469 |
*/
|
| 470 |
+
public function template( $name, $context = array(), $echo = true ) {
|
| 471 |
+
// If name is String make it an Array
|
| 472 |
+
if ( is_string( $name ) ) {
|
| 473 |
+
$name = (array) explode( '/', $name );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 474 |
}
|
| 475 |
|
| 476 |
+
// Clean this Variable
|
| 477 |
+
$name = array_map( 'sanitize_title_with_dashes', $name );
|
| 478 |
|
| 479 |
+
if ( ! empty( $this->origin->template_namespace ) ) {
|
| 480 |
+
$namespace = array_merge( (array) $this->origin->template_namespace, $name );
|
| 481 |
+
} else {
|
| 482 |
+
$namespace = $name;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 483 |
}
|
| 484 |
|
| 485 |
+
// Setup the Hook name
|
| 486 |
+
$hook_name = implode( '/', $namespace );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 487 |
|
| 488 |
+
// Check if the file exists
|
| 489 |
+
$file = $this->get_template_file( $name );
|
| 490 |
|
| 491 |
+
// Check if it's a valid variable
|
| 492 |
+
if ( ! $file ) {
|
| 493 |
return false;
|
| 494 |
}
|
| 495 |
|
| 496 |
+
// Before we load the file we check if it exists
|
| 497 |
+
if ( ! file_exists( $file ) ) {
|
| 498 |
+
return false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 499 |
}
|
| 500 |
|
| 501 |
ob_start();
|
| 507 |
* Fires an Action before including the template file
|
| 508 |
*
|
| 509 |
* @since 4.6.2
|
| 510 |
+
* @since 4.7.20 The $name param no longers contains the extension
|
| 511 |
*
|
| 512 |
* @param string $file Complete path to include the PHP File
|
| 513 |
* @param array $name Template name
|
| 515 |
*/
|
| 516 |
do_action( 'tribe_template_before_include', $file, $name, $this );
|
| 517 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 518 |
/**
|
| 519 |
* Fires an Action for a given template name before including the template file
|
| 520 |
*
|
| 531 |
*/
|
| 532 |
do_action( "tribe_template_before_include:$hook_name", $file, $name, $this );
|
| 533 |
|
| 534 |
+
// Only do this if really needed (by default it wont).
|
| 535 |
+
if ( true === $this->template_context_extract && ! empty( $this->context ) ) {
|
| 536 |
+
// We don't allow Extrating of a variable called $name
|
| 537 |
+
if ( isset( $this->context['name'] ) ) {
|
| 538 |
+
unset( $this->context['name'] );
|
| 539 |
+
}
|
| 540 |
+
|
| 541 |
+
// We don't allow the extraction of a variable called `$file`.
|
| 542 |
+
if ( isset( $this->context['file'] ) ) {
|
| 543 |
+
unset( $this->context['file'] );
|
| 544 |
+
}
|
| 545 |
+
|
| 546 |
+
// Make any provided variables available in the template variable scope.
|
| 547 |
+
extract( $this->context ); // @codingStandardsIgnoreLine
|
| 548 |
+
}
|
| 549 |
+
|
| 550 |
+
include $file;
|
| 551 |
|
| 552 |
/**
|
| 553 |
* Fires an Action after including the template file
|
| 554 |
*
|
| 555 |
* @since 4.6.2
|
| 556 |
+
* @since 4.7.20 The $name param no longers contains the extension
|
| 557 |
*
|
| 558 |
* @param string $file Complete path to include the PHP File
|
| 559 |
* @param array $name Template name
|
| 561 |
*/
|
| 562 |
do_action( 'tribe_template_after_include', $file, $name, $this );
|
| 563 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 564 |
/**
|
| 565 |
* Fires an Action for a given template name after including the template file
|
| 566 |
*
|
| 584 |
* Allow users to filter the final HTML
|
| 585 |
*
|
| 586 |
* @since 4.6.2
|
| 587 |
+
* @since 4.7.20 The $name param no longers contains the extension
|
| 588 |
*
|
| 589 |
* @param string $html The final HTML
|
| 590 |
* @param string $file Complete path to include the PHP File
|
| 593 |
*/
|
| 594 |
$html = apply_filters( 'tribe_template_html', $html, $file, $name, $this );
|
| 595 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 596 |
/**
|
| 597 |
* Allow users to filter the final HTML by the name
|
| 598 |
*
|
| 610 |
*/
|
| 611 |
$html = apply_filters( "tribe_template_html:$hook_name", $html, $file, $name, $this );
|
| 612 |
|
|
|
|
|
|
|
|
|
|
| 613 |
if ( $echo ) {
|
| 614 |
echo $html;
|
| 615 |
}
|
| 616 |
|
|
|
|
|
|
|
|
|
|
| 617 |
return $html;
|
| 618 |
}
|
| 619 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 620 |
/**
|
| 621 |
* Sets a number of values at the same time.
|
| 622 |
*
|
| 667 |
public function get_values() {
|
| 668 |
return array_merge( $this->get_global_values(), $this->get_local_values() );
|
| 669 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 670 |
}
|
common/src/Tribe/Timezones.php
CHANGED
|
@@ -10,6 +10,7 @@ class Tribe__Timezones {
|
|
| 10 |
const SITE_TIMEZONE = 'site';
|
| 11 |
const EVENT_TIMEZONE = 'event';
|
| 12 |
|
|
|
|
| 13 |
/**
|
| 14 |
* Container for reusable DateTimeZone objects.
|
| 15 |
*
|
|
@@ -17,6 +18,7 @@ class Tribe__Timezones {
|
|
| 17 |
*/
|
| 18 |
protected static $timezones = array();
|
| 19 |
|
|
|
|
| 20 |
public static function init() {
|
| 21 |
self::invalidate_caches();
|
| 22 |
}
|
|
@@ -579,13 +581,6 @@ class Tribe__Timezones {
|
|
| 579 |
return $timezone;
|
| 580 |
}
|
| 581 |
|
| 582 |
-
/** @var Tribe__Cache $cache */
|
| 583 |
-
$cache = tribe('cache');
|
| 584 |
-
|
| 585 |
-
if ( is_string( $timezone ) && $cached = $cache[ __METHOD__ . $timezone ] ) {
|
| 586 |
-
return clone $cached;
|
| 587 |
-
}
|
| 588 |
-
|
| 589 |
$timezone = null === $timezone ? self::wp_timezone_string() : $timezone;
|
| 590 |
|
| 591 |
try {
|
|
@@ -594,10 +589,6 @@ class Tribe__Timezones {
|
|
| 594 |
return new DateTimeZone( 'UTC' );
|
| 595 |
}
|
| 596 |
|
| 597 |
-
if ( is_string( $timezone ) ) {
|
| 598 |
-
$cache[ __METHOD__ . $timezone ] = $object;
|
| 599 |
-
}
|
| 600 |
-
|
| 601 |
return $object;
|
| 602 |
}
|
| 603 |
|
| 10 |
const SITE_TIMEZONE = 'site';
|
| 11 |
const EVENT_TIMEZONE = 'event';
|
| 12 |
|
| 13 |
+
|
| 14 |
/**
|
| 15 |
* Container for reusable DateTimeZone objects.
|
| 16 |
*
|
| 18 |
*/
|
| 19 |
protected static $timezones = array();
|
| 20 |
|
| 21 |
+
|
| 22 |
public static function init() {
|
| 23 |
self::invalidate_caches();
|
| 24 |
}
|
| 581 |
return $timezone;
|
| 582 |
}
|
| 583 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 584 |
$timezone = null === $timezone ? self::wp_timezone_string() : $timezone;
|
| 585 |
|
| 586 |
try {
|
| 589 |
return new DateTimeZone( 'UTC' );
|
| 590 |
}
|
| 591 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 592 |
return $object;
|
| 593 |
}
|
| 594 |
|
common/src/Tribe/Tooltip/View.php
CHANGED
|
@@ -1,30 +1,19 @@
|
|
| 1 |
<?php
|
| 2 |
|
| 3 |
-
namespace Tribe\Tooltip;
|
| 4 |
-
|
| 5 |
/**
|
| 6 |
-
* Class
|
| 7 |
*
|
| 8 |
* @since 4.9.8
|
| 9 |
*/
|
| 10 |
-
class
|
| 11 |
|
| 12 |
/**
|
| 13 |
-
*
|
| 14 |
-
*
|
| 15 |
-
* @since 4.10.2
|
| 16 |
-
*
|
| 17 |
-
* @var string
|
| 18 |
-
*/
|
| 19 |
-
public $template_namespace = 'tooltips';
|
| 20 |
-
|
| 21 |
-
/**
|
| 22 |
-
* View constructor.
|
| 23 |
*
|
| 24 |
* @since 4.9.8
|
| 25 |
*/
|
| 26 |
public function __construct() {
|
| 27 |
-
$this->set_template_origin(
|
| 28 |
$this->set_template_folder( 'src/views/tooltip' );
|
| 29 |
|
| 30 |
// Configures this templating class to extract variables
|
|
@@ -40,15 +29,7 @@ class View extends \Tribe__Template {
|
|
| 40 |
* @since 4.9.8
|
| 41 |
*
|
| 42 |
* @param array|string $message Array of messages or single message as string.
|
| 43 |
-
* @param array $args
|
| 44 |
-
* List of arguments to override tooltip template.
|
| 45 |
-
*
|
| 46 |
-
* @var array $context Any additional context data you need to expose to this file (optional).
|
| 47 |
-
* @var string $classes Additional classes for the icon span (optional).
|
| 48 |
-
* @var string $direction Direction the tooltip should be from the trigger (down).
|
| 49 |
-
* @var string $icon dashicon classname to use, without the `dashicon-` (info).
|
| 50 |
-
* @var string $wrap_classes Classes for the tooltip wrapper (optional).
|
| 51 |
-
* }
|
| 52 |
* @return string A string of html for the tooltip.
|
| 53 |
*/
|
| 54 |
public function render_tooltip( $message, $args = [] ) {
|
|
@@ -56,10 +37,6 @@ class View extends \Tribe__Template {
|
|
| 56 |
return;
|
| 57 |
}
|
| 58 |
|
| 59 |
-
/** @var \Tribe__Assets $assets */
|
| 60 |
-
$assets = tribe( 'assets' );
|
| 61 |
-
$assets->enqueue_group( 'tribe-tooltip' );
|
| 62 |
-
|
| 63 |
$html = $this->build_tooltip( $message, $args );
|
| 64 |
|
| 65 |
return $html;
|
|
@@ -71,23 +48,15 @@ class View extends \Tribe__Template {
|
|
| 71 |
* @since 4.9.8
|
| 72 |
*
|
| 73 |
* @param array|string $message array of messages or single message as string.
|
| 74 |
-
* @param array $args
|
| 75 |
-
* List of arguments to override tooltip template.
|
| 76 |
-
*
|
| 77 |
-
* @var array $context Any additional context data you need to expose to this file (optional).
|
| 78 |
-
* @var string $classes Additional classes for the icon span (optional).
|
| 79 |
-
* @var string $direction Direction the tooltip should be from the trigger (down).
|
| 80 |
-
* @var string $icon dashicon classname to use, without the `dashicon-` (info).
|
| 81 |
-
* @var string $wrap_classes Classes for the tooltip wrapper (optional).
|
| 82 |
-
* }
|
| 83 |
* @return string A string of html for the tooltip.
|
| 84 |
*/
|
| 85 |
private function build_tooltip( $message, $original_args ) {
|
| 86 |
$default_args = [
|
| 87 |
'classes' => '',
|
| 88 |
-
'context' => '',
|
| 89 |
-
'direction' => 'down',
|
| 90 |
'icon' => 'info',
|
|
|
|
|
|
|
| 91 |
'wrap_classes' => '',
|
| 92 |
];
|
| 93 |
|
| 1 |
<?php
|
| 2 |
|
|
|
|
|
|
|
| 3 |
/**
|
| 4 |
+
* Class Tribe__Tooltip__View
|
| 5 |
*
|
| 6 |
* @since 4.9.8
|
| 7 |
*/
|
| 8 |
+
class Tribe__Tooltip__View extends Tribe__Template {
|
| 9 |
|
| 10 |
/**
|
| 11 |
+
* Tribe__Tooltip__View constructor.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 12 |
*
|
| 13 |
* @since 4.9.8
|
| 14 |
*/
|
| 15 |
public function __construct() {
|
| 16 |
+
$this->set_template_origin( Tribe__Main::instance() );
|
| 17 |
$this->set_template_folder( 'src/views/tooltip' );
|
| 18 |
|
| 19 |
// Configures this templating class to extract variables
|
| 29 |
* @since 4.9.8
|
| 30 |
*
|
| 31 |
* @param array|string $message Array of messages or single message as string.
|
| 32 |
+
* @param array $args Extra arguments.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 33 |
* @return string A string of html for the tooltip.
|
| 34 |
*/
|
| 35 |
public function render_tooltip( $message, $args = [] ) {
|
| 37 |
return;
|
| 38 |
}
|
| 39 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 40 |
$html = $this->build_tooltip( $message, $args );
|
| 41 |
|
| 42 |
return $html;
|
| 48 |
* @since 4.9.8
|
| 49 |
*
|
| 50 |
* @param array|string $message array of messages or single message as string.
|
| 51 |
+
* @param array $args Extra arguments, defaults include icon, classes, direction, and context (for the filters).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 52 |
* @return string A string of html for the tooltip.
|
| 53 |
*/
|
| 54 |
private function build_tooltip( $message, $original_args ) {
|
| 55 |
$default_args = [
|
| 56 |
'classes' => '',
|
|
|
|
|
|
|
| 57 |
'icon' => 'info',
|
| 58 |
+
'direction' => 'down',
|
| 59 |
+
'context' => '',
|
| 60 |
'wrap_classes' => '',
|
| 61 |
];
|
| 62 |
|
common/src/Tribe/Traits/Cache_User.php
CHANGED
|
@@ -125,21 +125,4 @@ trait Cache_User {
|
|
| 125 |
}
|
| 126 |
}
|
| 127 |
}
|
| 128 |
-
|
| 129 |
-
/**
|
| 130 |
-
* Resets the instance caches for the this instance.
|
| 131 |
-
*
|
| 132 |
-
* @since 4.11.0
|
| 133 |
-
*
|
| 134 |
-
* @return string[] A list of the emptied cache properties.
|
| 135 |
-
*/
|
| 136 |
-
public function reset_caches() {
|
| 137 |
-
$emptied = [];
|
| 138 |
-
foreach ( array_keys( $this->caches ) as $key ) {
|
| 139 |
-
$emptied[] = $key;
|
| 140 |
-
$this->{"{$key}_cache"} = [];
|
| 141 |
-
}
|
| 142 |
-
|
| 143 |
-
return $emptied;
|
| 144 |
-
}
|
| 145 |
}
|
| 125 |
}
|
| 126 |
}
|
| 127 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 128 |
}
|
common/src/Tribe/Utils/Array.php
CHANGED
|
@@ -442,84 +442,5 @@ if ( ! class_exists( 'Tribe__Utils__Array' ) ) {
|
|
| 442 |
|
| 443 |
return $default;
|
| 444 |
}
|
| 445 |
-
|
| 446 |
-
/**
|
| 447 |
-
* Discards everything other than array values having string keys and scalar values, ensuring a
|
| 448 |
-
* one-dimensional, associative array result.
|
| 449 |
-
*
|
| 450 |
-
* @link https://www.php.net/manual/language.types.array.php Keys cast to non-strings will be discarded.
|
| 451 |
-
*
|
| 452 |
-
* @since 4.12.2
|
| 453 |
-
*
|
| 454 |
-
* @param array $array
|
| 455 |
-
*
|
| 456 |
-
* @return array Associative or empty array.
|
| 457 |
-
*/
|
| 458 |
-
public static function filter_to_flat_scalar_associative_array( array $array ) {
|
| 459 |
-
$result = [];
|
| 460 |
-
|
| 461 |
-
if ( ! is_array( $array ) ) {
|
| 462 |
-
return $result;
|
| 463 |
-
}
|
| 464 |
-
|
| 465 |
-
foreach ( $array as $k => $v ) {
|
| 466 |
-
if ( ! is_string( $k ) ) {
|
| 467 |
-
continue;
|
| 468 |
-
}
|
| 469 |
-
|
| 470 |
-
if ( ! is_scalar( $v ) ) {
|
| 471 |
-
continue;
|
| 472 |
-
}
|
| 473 |
-
|
| 474 |
-
$result[ $k ] = $v;
|
| 475 |
-
}
|
| 476 |
-
|
| 477 |
-
return $result;
|
| 478 |
-
}
|
| 479 |
-
|
| 480 |
-
/**
|
| 481 |
-
* Build an array from migrating aliased key values to their canonical key values, removing all alias keys.
|
| 482 |
-
*
|
| 483 |
-
* If the original array has values for both the alias and its canonical, keep the canonical's value and
|
| 484 |
-
* discard the alias' value.
|
| 485 |
-
*
|
| 486 |
-
* @since 4.12.2
|
| 487 |
-
*
|
| 488 |
-
* @param array $original An associative array of values, such as passed shortcode arguments.
|
| 489 |
-
* @param array $alias_map An associative array of aliases: key as alias, value as mapped canonical.
|
| 490 |
-
* Example: [ 'alias' => 'canonical', 'from' => 'to', 'that' => 'becomes_this' ]
|
| 491 |
-
*
|
| 492 |
-
* @return array
|
| 493 |
-
*/
|
| 494 |
-
public static function parse_associative_array_alias( array $original, array $alias_map ) {
|
| 495 |
-
// Ensure array values.
|
| 496 |
-
$original = (array) $original;
|
| 497 |
-
$alias_map = static::filter_to_flat_scalar_associative_array( (array) $alias_map );
|
| 498 |
-
|
| 499 |
-
// Fail gracefully if alias array wasn't setup as [ 'from' => 'to' ].
|
| 500 |
-
if ( empty( $alias_map ) ) {
|
| 501 |
-
return $original;
|
| 502 |
-
}
|
| 503 |
-
|
| 504 |
-
$result = $original;
|
| 505 |
-
|
| 506 |
-
// Parse aliases.
|
| 507 |
-
foreach ( $alias_map as $from => $to ) {
|
| 508 |
-
// If this alias isn't in use, go onto the next.
|
| 509 |
-
if ( ! isset( $result[ $from ] ) ) {
|
| 510 |
-
continue;
|
| 511 |
-
}
|
| 512 |
-
|
| 513 |
-
// Only allow setting alias value if canonical value is not already present.
|
| 514 |
-
if ( ! isset( $result[ $to ] ) ) {
|
| 515 |
-
$result[ $to ] = $result[ $from ];
|
| 516 |
-
}
|
| 517 |
-
|
| 518 |
-
// Always remove the alias key.
|
| 519 |
-
unset( $result[ $from ] );
|
| 520 |
-
}
|
| 521 |
-
|
| 522 |
-
return $result;
|
| 523 |
-
}
|
| 524 |
}
|
| 525 |
}
|
| 442 |
|
| 443 |
return $default;
|
| 444 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 445 |
}
|
| 446 |
}
|
common/src/Tribe/Utils/Collection_Interface.php
CHANGED
|
@@ -16,7 +16,7 @@ namespace Tribe\Utils;
|
|
| 16 |
* @since 4.9.14
|
| 17 |
* @package Tribe\Utils
|
| 18 |
*/
|
| 19 |
-
interface Collection_Interface extends \ArrayAccess, \SeekableIterator, \Countable, \Serializable
|
| 20 |
/**
|
| 21 |
* Returns all the items in the collection.
|
| 22 |
*
|
| 16 |
* @since 4.9.14
|
| 17 |
* @package Tribe\Utils
|
| 18 |
*/
|
| 19 |
+
interface Collection_Interface extends \ArrayAccess, \SeekableIterator, \Countable, \Serializable {
|
| 20 |
/**
|
| 21 |
* Returns all the items in the collection.
|
| 22 |
*
|
common/src/Tribe/Utils/Collection_Trait.php
CHANGED
|
@@ -152,27 +152,14 @@ trait Collection_Trait {
|
|
| 152 |
* {@inheritDoc}
|
| 153 |
*/
|
| 154 |
public function serialize() {
|
| 155 |
-
|
| 156 |
-
|
| 157 |
-
if ( method_exists( $this, 'before_serialize' ) ) {
|
| 158 |
-
$to_serialize = $this->before_serialize( $this->all() );
|
| 159 |
-
}
|
| 160 |
-
|
| 161 |
-
return serialize( $to_serialize );
|
| 162 |
}
|
| 163 |
|
| 164 |
/**
|
| 165 |
* {@inheritDoc}
|
| 166 |
*/
|
| 167 |
public function unserialize( $serialized ) {
|
| 168 |
-
$
|
| 169 |
-
|
| 170 |
-
if ( method_exists( $this, 'custom_unserialize' ) ) {
|
| 171 |
-
$this->items = $this->custom_unserialize( $to_unserialize );
|
| 172 |
-
return;
|
| 173 |
-
}
|
| 174 |
-
|
| 175 |
-
$this->items = unserialize( $to_unserialize );
|
| 176 |
}
|
| 177 |
|
| 178 |
/**
|
|
@@ -181,27 +168,4 @@ trait Collection_Trait {
|
|
| 181 |
public function seek( $position ) {
|
| 182 |
$this->items_index = $position;
|
| 183 |
}
|
| 184 |
-
|
| 185 |
-
/**
|
| 186 |
-
* Applies a filter callback to each element of this collection changing the collection elements to only those
|
| 187 |
-
* passing the filter.
|
| 188 |
-
*
|
| 189 |
-
* @since 4.10.2
|
| 190 |
-
*
|
| 191 |
-
* @param callable $filter_callback The filter callback that will be applied to each element of the collection; the
|
| 192 |
-
* callback will receive the element as parameter.
|
| 193 |
-
*
|
| 194 |
-
* @return Collection_Trait A new collection instance, that contains only the elements that passed the filter.
|
| 195 |
-
*/
|
| 196 |
-
public function filter( $filter_callback ) {
|
| 197 |
-
if ( $this->count() === 0 ) {
|
| 198 |
-
// If there is nothing to filter to begin with, just return this.
|
| 199 |
-
return $this;
|
| 200 |
-
}
|
| 201 |
-
|
| 202 |
-
$filtered = new static();
|
| 203 |
-
$filtered->items = array_filter( $this->all(), $filter_callback );
|
| 204 |
-
|
| 205 |
-
return $filtered;
|
| 206 |
-
}
|
| 207 |
}
|
| 152 |
* {@inheritDoc}
|
| 153 |
*/
|
| 154 |
public function serialize() {
|
| 155 |
+
return serialize( $this->all() );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 156 |
}
|
| 157 |
|
| 158 |
/**
|
| 159 |
* {@inheritDoc}
|
| 160 |
*/
|
| 161 |
public function unserialize( $serialized ) {
|
| 162 |
+
$this->items = unserialize( $serialized );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 163 |
}
|
| 164 |
|
| 165 |
/**
|
| 168 |
public function seek( $position ) {
|
| 169 |
$this->items_index = $position;
|
| 170 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 171 |
}
|
common/src/Tribe/Utils/Date_I18n.php
DELETED
|
@@ -1,48 +0,0 @@
|
|
| 1 |
-
<?php
|
| 2 |
-
/**
|
| 3 |
-
* Extends DateTime and includes translation capabilities.
|
| 4 |
-
*
|
| 5 |
-
* @package Tribe\Utils
|
| 6 |
-
* @since 4.11.0
|
| 7 |
-
*/
|
| 8 |
-
namespace Tribe\Utils;
|
| 9 |
-
|
| 10 |
-
use Tribe__Date_Utils as Dates;
|
| 11 |
-
use DateTime;
|
| 12 |
-
use DateTimeImmutable;
|
| 13 |
-
|
| 14 |
-
/**
|
| 15 |
-
* Class Date i18n
|
| 16 |
-
*
|
| 17 |
-
* @package Tribe\Utils
|
| 18 |
-
* @since 4.11.0
|
| 19 |
-
*/
|
| 20 |
-
class Date_I18n extends DateTime {
|
| 21 |
-
/**
|
| 22 |
-
* {@inheritDoc}
|
| 23 |
-
*
|
| 24 |
-
* @return Date_I18n Localizable variation of DateTime.
|
| 25 |
-
*/
|
| 26 |
-
public static function createFromImmutable( $datetime ) {
|
| 27 |
-
$date_object = new self;
|
| 28 |
-
$date_object->setTimestamp( $datetime->getTimestamp() );
|
| 29 |
-
$date_object->setTimezone( $datetime->getTimezone() );
|
| 30 |
-
return $date_object;
|
| 31 |
-
}
|
| 32 |
-
|
| 33 |
-
/**
|
| 34 |
-
* Returns a translated string using the params from this DateTime instance.
|
| 35 |
-
*
|
| 36 |
-
* @since 4.11.0
|
| 37 |
-
*
|
| 38 |
-
* @param string $date_format Format to be used in the translation.
|
| 39 |
-
*
|
| 40 |
-
* @return string Translated date.
|
| 41 |
-
*/
|
| 42 |
-
public function format_i18n( $date_format ) {
|
| 43 |
-
$unix_with_tz = $this->getTimestamp() + $this->getOffset();
|
| 44 |
-
$translated = date_i18n( $date_format, $unix_with_tz );
|
| 45 |
-
|
| 46 |
-
return $translated;
|
| 47 |
-
}
|
| 48 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
common/src/Tribe/Utils/Date_I18n_Immutable.php
DELETED
|
@@ -1,48 +0,0 @@
|
|
| 1 |
-
<?php
|
| 2 |
-
/**
|
| 3 |
-
* Extends DateTimeImmutable and includes translation capabilities.
|
| 4 |
-
*
|
| 5 |
-
* @since 4.11.0
|
| 6 |
-
* @package Tribe\Utils
|
| 7 |
-
*/
|
| 8 |
-
|
| 9 |
-
namespace Tribe\Utils;
|
| 10 |
-
|
| 11 |
-
use DateTimeImmutable;
|
| 12 |
-
|
| 13 |
-
/**
|
| 14 |
-
* Class Date i18n Immutable
|
| 15 |
-
*
|
| 16 |
-
* @since 4.11.0
|
| 17 |
-
* @package Tribe\Utils
|
| 18 |
-
*/
|
| 19 |
-
class Date_I18n_Immutable extends DateTimeImmutable {
|
| 20 |
-
/**
|
| 21 |
-
* {@inheritDoc}
|
| 22 |
-
*
|
| 23 |
-
* @return Date_I18n_Immutable Localizable variation of DateTimeImmutable.
|
| 24 |
-
*/
|
| 25 |
-
public static function createFromMutable( $datetime ) {
|
| 26 |
-
$date_object = new self;
|
| 27 |
-
$date_object = $date_object->setTimestamp( $datetime->getTimestamp() );
|
| 28 |
-
$date_object = $date_object->setTimezone( $datetime->getTimezone() );
|
| 29 |
-
|
| 30 |
-
return $date_object;
|
| 31 |
-
}
|
| 32 |
-
|
| 33 |
-
/**
|
| 34 |
-
* Returns a translated string using the params from this Immutable DateTime instance.
|
| 35 |
-
*
|
| 36 |
-
* @since 4.11.0
|
| 37 |
-
*
|
| 38 |
-
* @param string $date_format Format to be used in the translation.
|
| 39 |
-
*
|
| 40 |
-
* @return string Translated date.
|
| 41 |
-
*/
|
| 42 |
-
public function format_i18n( $date_format ) {
|
| 43 |
-
$unix_with_tz = $this->getTimestamp() + $this->getOffset();
|
| 44 |
-
$translated = date_i18n( $date_format, $unix_with_tz );
|
| 45 |
-
|
| 46 |
-
return $translated;
|
| 47 |
-
}
|
| 48 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
common/src/Tribe/Utils/Lazy_Collection.php
CHANGED
|
@@ -33,7 +33,6 @@ namespace Tribe\Utils;
|
|
| 33 |
*/
|
| 34 |
class Lazy_Collection implements Collection_Interface {
|
| 35 |
use Collection_Trait;
|
| 36 |
-
use Lazy_Events;
|
| 37 |
|
| 38 |
/**
|
| 39 |
* The callback in charge of providing the elements.
|
|
@@ -85,7 +84,6 @@ class Lazy_Collection implements Collection_Interface {
|
|
| 85 |
|
| 86 |
$items = call_user_func( $this->callback );
|
| 87 |
$this->items = (array) $items;
|
| 88 |
-
$this->resolved();
|
| 89 |
}
|
| 90 |
|
| 91 |
/**
|
|
@@ -107,11 +105,4 @@ class Lazy_Collection implements Collection_Interface {
|
|
| 107 |
|
| 108 |
return null;
|
| 109 |
}
|
| 110 |
-
|
| 111 |
-
/**
|
| 112 |
-
* {@inheritDoc}
|
| 113 |
-
*/
|
| 114 |
-
public function jsonSerialize() {
|
| 115 |
-
return $this->all();
|
| 116 |
-
}
|
| 117 |
}
|
| 33 |
*/
|
| 34 |
class Lazy_Collection implements Collection_Interface {
|
| 35 |
use Collection_Trait;
|
|
|
|
| 36 |
|
| 37 |
/**
|
| 38 |
* The callback in charge of providing the elements.
|
| 84 |
|
| 85 |
$items = call_user_func( $this->callback );
|
| 86 |
$this->items = (array) $items;
|
|
|
|
| 87 |
}
|
| 88 |
|
| 89 |
/**
|
| 105 |
|
| 106 |
return null;
|
| 107 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 108 |
}
|
common/src/Tribe/Utils/Lazy_Events.php
DELETED
|
@@ -1,172 +0,0 @@
|
|
| 1 |
-
<?php
|
| 2 |
-
/**
|
| 3 |
-
* Provides methods for "lazy" objects to act upon life cycle events.
|
| 4 |
-
*
|
| 5 |
-
* @since 4.9.16
|
| 6 |
-
*
|
| 7 |
-
* @example
|
| 8 |
-
* ```php
|
| 9 |
-
* class Lazy_List_Of_Stuff {
|
| 10 |
-
* use Tribe\Utils\Lazy_Events;
|
| 11 |
-
*
|
| 12 |
-
* protected $list;
|
| 13 |
-
*
|
| 14 |
-
* public function fetch_list(){
|
| 15 |
-
* $cached = wp_cache_get( 'list_of_stuff_one' );
|
| 16 |
-
*
|
| 17 |
-
* if( false !== $cached ){
|
| 18 |
-
* return $cached;
|
| 19 |
-
*
|
| 20 |
-
* if( null === $this->list ){
|
| 21 |
-
* $this->list = really_expensive_calculation();
|
| 22 |
-
* }
|
| 23 |
-
*
|
| 24 |
-
* $this->resolved();
|
| 25 |
-
* }
|
| 26 |
-
*
|
| 27 |
-
* return $this->list;
|
| 28 |
-
* }
|
| 29 |
-
* }
|
| 30 |
-
*
|
| 31 |
-
* class Lazy_Value {
|
| 32 |
-
* use Tribe\Utils\Lazy_Events;
|
| 33 |
-
*
|
| 34 |
-
* protected $value;
|
| 35 |
-
*
|
| 36 |
-
* public function calculate_value(){
|
| 37 |
-
* $cached = wp_cache_get( 'expensive_value' );
|
| 38 |
-
*
|
| 39 |
-
* if( false !== $cached ){
|
| 40 |
-
* return $cached;
|
| 41 |
-
*
|
| 42 |
-
* if( null === $this->value ){
|
| 43 |
-
* $this->value = really_expensive_calculation();
|
| 44 |
-
* }
|
| 45 |
-
*
|
| 46 |
-
* $this->resolved();
|
| 47 |
-
* }
|
| 48 |
-
*
|
| 49 |
-
* return $this->value;
|
| 50 |
-
* }
|
| 51 |
-
* }
|
| 52 |
-
*
|
| 53 |
-
* class List_And_Value {
|
| 54 |
-
* protected $list;
|
| 55 |
-
* protected $value;
|
| 56 |
-
*
|
| 57 |
-
* public function __construct( Lazy_List_Of_Stuff $list, Lazy_Value $value ){
|
| 58 |
-
* $this->list = $list;
|
| 59 |
-
* $this->value = $value;
|
| 60 |
-
* $this->list->on_resolve( [ $this, 'cache' ] );
|
| 61 |
-
* $this->value->on_resolve( [ $this, 'cache' ] );
|
| 62 |
-
* }
|
| 63 |
-
*
|
| 64 |
-
* public function cache(){
|
| 65 |
-
* wp_cache_set( 'list_and_value', [
|
| 66 |
-
* 'list' => $this->list->fetch_list(),
|
| 67 |
-
* 'value' => $this->value->calculate_value(),
|
| 68 |
-
* ]);
|
| 69 |
-
* }
|
| 70 |
-
*
|
| 71 |
-
* public function get_list(){
|
| 72 |
-
* $cached = wp_cache_get( 'list_and_value' );
|
| 73 |
-
*
|
| 74 |
-
* return $cached ? $cached['list'] : $this->list->fetch_list();
|
| 75 |
-
* }
|
| 76 |
-
*
|
| 77 |
-
* public function get_value(){
|
| 78 |
-
* $cached = wp_cache_get( 'list_and_value' );
|
| 79 |
-
*
|
| 80 |
-
* return $cached ? $cached['value'] : $this->value->fetch_value();
|
| 81 |
-
* }
|
| 82 |
-
* }
|
| 83 |
-
*
|
| 84 |
-
*
|
| 85 |
-
* $list = new Lazy_List_Of_Stuff();
|
| 86 |
-
* $value = new Lazy_Value();
|
| 87 |
-
* $list_and_value = new List_And_Value( $list, $value );
|
| 88 |
-
*
|
| 89 |
-
* // Accessing `value` will make it so that `list` too will be cached.
|
| 90 |
-
* $list_and_value->get_value();
|
| 91 |
-
* ````
|
| 92 |
-
*
|
| 93 |
-
* @package Tribe\Utils
|
| 94 |
-
*/
|
| 95 |
-
|
| 96 |
-
namespace Tribe\Utils;
|
| 97 |
-
|
| 98 |
-
/**
|
| 99 |
-
* Trait Lazy_Events
|
| 100 |
-
*
|
| 101 |
-
* @since 4.9.16
|
| 102 |
-
*
|
| 103 |
-
* @package Tribe\Utils
|
| 104 |
-
*
|
| 105 |
-
* @property string $lazy_resolve_action The action to which the trait will hook to run the callback if the object
|
| 106 |
-
* resolved. Using classes should define the property if the default `shutdown`
|
| 107 |
-
* one is not correct.
|
| 108 |
-
* @property int $lazy_resolve_priority The priority at which the resolution callback will be hooked on the
|
| 109 |
-
* `$lazy_resolve_action`; defaults to `10`.
|
| 110 |
-
*/
|
| 111 |
-
trait Lazy_Events {
|
| 112 |
-
|
| 113 |
-
/**
|
| 114 |
-
* The callback that will be called when, and if, the lazy object resolved at least once.
|
| 115 |
-
*
|
| 116 |
-
* @since 4.9.16
|
| 117 |
-
*
|
| 118 |
-
* @var
|
| 119 |
-
*/
|
| 120 |
-
protected $lazy_resolve_callback;
|
| 121 |
-
|
| 122 |
-
/**
|
| 123 |
-
* Sets the callback that will be hooked to the resolve action when, and if, the `resolved` method is called.
|
| 124 |
-
*
|
| 125 |
-
* @since 4.9.16
|
| 126 |
-
*
|
| 127 |
-
* @param callable $callback The callback that will be hooked on the `$lazy_resolve_action` (defaults to `shutdown`)
|
| 128 |
-
* if the `resolved` method is called.
|
| 129 |
-
*
|
| 130 |
-
* @return static The object instance.
|
| 131 |
-
*
|
| 132 |
-
* @see Lazy_Events::resolved()
|
| 133 |
-
*/
|
| 134 |
-
public function on_resolve( callable $callback = null ) {
|
| 135 |
-
if ( null === $callback ) {
|
| 136 |
-
return $this;
|
| 137 |
-
}
|
| 138 |
-
|
| 139 |
-
$this->lazy_resolve_callback = $callback;
|
| 140 |
-
|
| 141 |
-
return $this;
|
| 142 |
-
}
|
| 143 |
-
|
| 144 |
-
/**
|
| 145 |
-
* Hooks the `$lazy_resolve_callback` to the `$lazy_resolve_action` with the `$lazy_resolve_priority` if set.
|
| 146 |
-
*
|
| 147 |
-
* @since 4.9.16
|
| 148 |
-
*/
|
| 149 |
-
protected function resolved() {
|
| 150 |
-
if ( empty( $this->lazy_resolve_callback ) ) {
|
| 151 |
-
return;
|
| 152 |
-
}
|
| 153 |
-
|
| 154 |
-
$action = property_exists( $this, 'lazy_resolve_action' ) ?
|
| 155 |
-
$this->lazy_resolve_action
|
| 156 |
-
: 'shutdown';
|
| 157 |
-
$priority = property_exists( $this, 'lazy_resolve_priority' ) ?
|
| 158 |
-
$this->lazy_resolve_priority
|
| 159 |
-
: 10;
|
| 160 |
-
|
| 161 |
-
$hooked = has_action( $action, $this->lazy_resolve_callback );
|
| 162 |
-
|
| 163 |
-
// Let's play it safe and move the resoloution as late as possible.
|
| 164 |
-
$new_priority = false !== $hooked ? max( $hooked, $priority ) : $priority;
|
| 165 |
-
|
| 166 |
-
if ( is_numeric( $hooked ) && $hooked !== $new_priority ) {
|
| 167 |
-
remove_action( $action, $this->lazy_resolve_callback, $hooked );
|
| 168 |
-
}
|
| 169 |
-
|
| 170 |
-
add_action( $action, $this->lazy_resolve_callback, $new_priority );
|
| 171 |
-
}
|
| 172 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
common/src/Tribe/Utils/Lazy_String.php
DELETED
|
@@ -1,141 +0,0 @@
|
|
| 1 |
-
<?php
|
| 2 |
-
/**
|
| 3 |
-
* A string lazily built, suited to any string value that might be costly to be built.
|
| 4 |
-
*
|
| 5 |
-
* @since 4.9.16
|
| 6 |
-
*
|
| 7 |
-
* @package Tribe\Utils
|
| 8 |
-
*/
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
namespace Tribe\Utils;
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
class Lazy_String implements \Serializable, \JsonSerializable {
|
| 15 |
-
use Lazy_Events;
|
| 16 |
-
|
| 17 |
-
/**
|
| 18 |
-
* The string value produced by the callback, cached.
|
| 19 |
-
*
|
| 20 |
-
* @since 4.9.16
|
| 21 |
-
*
|
| 22 |
-
* @var string
|
| 23 |
-
*/
|
| 24 |
-
protected $string;
|
| 25 |
-
|
| 26 |
-
/**
|
| 27 |
-
* The callback that will be used to set the string value when called the first time.
|
| 28 |
-
*
|
| 29 |
-
* @since 4.9.16
|
| 30 |
-
*
|
| 31 |
-
* @var callable
|
| 32 |
-
*/
|
| 33 |
-
protected $value_callback;
|
| 34 |
-
|
| 35 |
-
/**
|
| 36 |
-
* The callback that will be used to escape the string in the `escaped()` method..
|
| 37 |
-
*
|
| 38 |
-
* @since 4.9.16
|
| 39 |
-
*
|
| 40 |
-
* @var callable
|
| 41 |
-
*/
|
| 42 |
-
protected $escape_callback;
|
| 43 |
-
|
| 44 |
-
/**
|
| 45 |
-
* The escaped string value.
|
| 46 |
-
*
|
| 47 |
-
* @since 4.9.16
|
| 48 |
-
*
|
| 49 |
-
* @var string
|
| 50 |
-
*/
|
| 51 |
-
protected $escaped;
|
| 52 |
-
|
| 53 |
-
/**
|
| 54 |
-
* Lazy_String constructor.
|
| 55 |
-
*
|
| 56 |
-
* @param callable $callback The callback that will be used to populate the string on the first fetch.
|
| 57 |
-
* @param string|false $escape_callback The callback that will be used to escape the string in the `escaped`
|
| 58 |
-
* method.
|
| 59 |
-
*/
|
| 60 |
-
public function __construct( callable $callback, $escape_callback = 'esc_html' ) {
|
| 61 |
-
$this->value_callback = $callback;
|
| 62 |
-
$this->escape_callback = $escape_callback;
|
| 63 |
-
}
|
| 64 |
-
|
| 65 |
-
/**
|
| 66 |
-
* Inits, and returns, the string value of the string.
|
| 67 |
-
*
|
| 68 |
-
* @since 4.9.16
|
| 69 |
-
*
|
| 70 |
-
* @return string The unescaped string value.
|
| 71 |
-
*/
|
| 72 |
-
public function __toString() {
|
| 73 |
-
if ( null === $this->string ) {
|
| 74 |
-
$this->string = call_user_func( $this->value_callback );
|
| 75 |
-
$this->resolved();
|
| 76 |
-
}
|
| 77 |
-
|
| 78 |
-
return $this->string;
|
| 79 |
-
}
|
| 80 |
-
|
| 81 |
-
/**
|
| 82 |
-
* Returns the HTML ready, escaped version of the string.
|
| 83 |
-
*
|
| 84 |
-
* @since 4.9.16
|
| 85 |
-
*
|
| 86 |
-
* @return string The escaped version of the string.
|
| 87 |
-
*/
|
| 88 |
-
public function escaped() {
|
| 89 |
-
if ( null !== $this->escaped ) {
|
| 90 |
-
return $this->escaped;
|
| 91 |
-
}
|
| 92 |
-
|
| 93 |
-
$this->escaped = empty( $this->escape_callback )
|
| 94 |
-
? $this->__toString()
|
| 95 |
-
: call_user_func( $this->escape_callback, $this->__toString() );
|
| 96 |
-
|
| 97 |
-
return $this->escaped;
|
| 98 |
-
}
|
| 99 |
-
|
| 100 |
-
/**
|
| 101 |
-
* Returns the string value, just a proxy of the `__toString` method.
|
| 102 |
-
*
|
| 103 |
-
* @since 4.9.16
|
| 104 |
-
*
|
| 105 |
-
* @return string The string value.
|
| 106 |
-
*/
|
| 107 |
-
public function value() {
|
| 108 |
-
return $this->__toString();
|
| 109 |
-
}
|
| 110 |
-
|
| 111 |
-
/**
|
| 112 |
-
* {@inheritDoc}
|
| 113 |
-
*
|
| 114 |
-
* @since 4.9.16
|
| 115 |
-
*/
|
| 116 |
-
public function serialize() {
|
| 117 |
-
$serialized = serialize( [ $this->__toString(), $this->escaped() ] );
|
| 118 |
-
|
| 119 |
-
unset( $this->value_callback, $this->escape_callback );
|
| 120 |
-
|
| 121 |
-
return $serialized;
|
| 122 |
-
}
|
| 123 |
-
|
| 124 |
-
/**
|
| 125 |
-
* {@inheritDoc}
|
| 126 |
-
*
|
| 127 |
-
* @since 4.9.16
|
| 128 |
-
*/
|
| 129 |
-
public function unserialize( $serialized ) {
|
| 130 |
-
list( $string, $escaped ) = unserialize( $serialized );
|
| 131 |
-
$this->string = $string;
|
| 132 |
-
$this->escaped = $escaped;
|
| 133 |
-
}
|
| 134 |
-
|
| 135 |
-
/**
|
| 136 |
-
* {@inheritDoc}
|
| 137 |
-
*/
|
| 138 |
-
public function jsonSerialize() {
|
| 139 |
-
return $this->value();
|
| 140 |
-
}
|
| 141 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
common/src/Tribe/Utils/Post_Thumbnail.php
CHANGED
|
@@ -28,8 +28,6 @@ use Tribe__Utils__Array as Arr;
|
|
| 28 |
* @package Tribe\Utils
|
| 29 |
*/
|
| 30 |
class Post_Thumbnail implements \ArrayAccess, \Serializable {
|
| 31 |
-
use Lazy_Events;
|
| 32 |
-
|
| 33 |
/**
|
| 34 |
* An array of the site image sizes, including the `full` one.
|
| 35 |
*
|
|
@@ -57,24 +55,6 @@ class Post_Thumbnail implements \ArrayAccess, \Serializable {
|
|
| 57 |
*/
|
| 58 |
protected $data;
|
| 59 |
|
| 60 |
-
/**
|
| 61 |
-
* A flag property indicating whether the post thumbnail for the post exists or not.
|
| 62 |
-
*
|
| 63 |
-
* @since 4.9.16
|
| 64 |
-
*
|
| 65 |
-
* @var bool
|
| 66 |
-
*/
|
| 67 |
-
protected $exists;
|
| 68 |
-
|
| 69 |
-
/**
|
| 70 |
-
* The post ID, if any, of the post thumbnail.
|
| 71 |
-
*
|
| 72 |
-
* @since 4.9.16
|
| 73 |
-
*
|
| 74 |
-
* @var int
|
| 75 |
-
*/
|
| 76 |
-
protected $thumbnail_id;
|
| 77 |
-
|
| 78 |
/**
|
| 79 |
* Post_Images constructor.
|
| 80 |
*
|
|
@@ -88,10 +68,6 @@ class Post_Thumbnail implements \ArrayAccess, \Serializable {
|
|
| 88 |
* {@inheritDoc}
|
| 89 |
*/
|
| 90 |
public function __get( $property ) {
|
| 91 |
-
if ( 'exists' === $property ) {
|
| 92 |
-
return $this->exists();
|
| 93 |
-
}
|
| 94 |
-
|
| 95 |
return $this->offsetGet( $property );
|
| 96 |
}
|
| 97 |
|
|
@@ -99,10 +75,6 @@ class Post_Thumbnail implements \ArrayAccess, \Serializable {
|
|
| 99 |
* {@inheritDoc}
|
| 100 |
*/
|
| 101 |
public function __set( $property, $value ) {
|
| 102 |
-
if ( 'exists' === $property ) {
|
| 103 |
-
throw new \InvalidArgumentException( 'The `Post_Thumbnail::exists` property cannot be set.' );
|
| 104 |
-
}
|
| 105 |
-
|
| 106 |
$this->offsetSet( $property, $value );
|
| 107 |
}
|
| 108 |
|
|
@@ -147,68 +119,47 @@ class Post_Thumbnail implements \ArrayAccess, \Serializable {
|
|
| 147 |
* @return array An array of objects containing the post thumbnail data.
|
| 148 |
*/
|
| 149 |
public function fetch_data() {
|
| 150 |
-
static $cache_thumbnail = [];
|
| 151 |
-
|
| 152 |
-
if ( ! $this->exists() ) {
|
| 153 |
-
return [];
|
| 154 |
-
}
|
| 155 |
-
|
| 156 |
if ( null !== $this->data ) {
|
| 157 |
return $this->data;
|
| 158 |
}
|
| 159 |
|
| 160 |
-
$
|
| 161 |
-
$
|
| 162 |
-
|
| 163 |
-
$cache_key = empty( $thumbnail_id ) ? -1 : $thumbnail_id;
|
| 164 |
-
|
| 165 |
-
if ( empty( $cache_thumbnail[ $cache_key ] ) ) {
|
| 166 |
-
$thumbnail_data = array_combine(
|
| 167 |
-
$image_sizes,
|
| 168 |
-
array_map(
|
| 169 |
-
static function( $size ) use ( $thumbnail_id ) {
|
| 170 |
-
static $cache_size_data = [];
|
| 171 |
|
| 172 |
-
|
| 173 |
-
$size_data_cache_key = "{$size_data_cache_key}:{$size}";
|
| 174 |
|
| 175 |
-
|
| 176 |
-
|
| 177 |
-
|
| 178 |
-
|
| 179 |
-
$size_data = $cache_size_data[ $size_data_cache_key ];
|
| 180 |
|
| 181 |
-
|
| 182 |
-
|
| 183 |
-
|
| 184 |
-
|
| 185 |
-
|
| 186 |
-
'is_intermediate' => false,
|
| 187 |
-
];
|
| 188 |
-
}
|
| 189 |
|
|
|
|
| 190 |
return (object) [
|
| 191 |
-
'url' =>
|
| 192 |
-
'width' =>
|
| 193 |
-
'height' =>
|
| 194 |
-
'is_intermediate' =>
|
| 195 |
];
|
| 196 |
-
}
|
| 197 |
-
|
| 198 |
-
|
| 199 |
-
|
| 200 |
-
|
| 201 |
-
|
| 202 |
-
|
| 203 |
-
|
| 204 |
-
|
| 205 |
-
|
| 206 |
-
|
| 207 |
-
|
| 208 |
-
|
| 209 |
-
|
| 210 |
-
|
| 211 |
-
}
|
| 212 |
|
| 213 |
/**
|
| 214 |
* Filters the post thumbnail data and information that will be returned for a specific post.
|
|
@@ -220,9 +171,7 @@ class Post_Thumbnail implements \ArrayAccess, \Serializable {
|
|
| 220 |
* @param array $thumbnail_data The thumbnail data for the post.
|
| 221 |
* @param int $post_id The ID of the post the data is for.
|
| 222 |
*/
|
| 223 |
-
$thumbnail_data = apply_filters( 'tribe_post_thumbnail_data', $
|
| 224 |
-
|
| 225 |
-
$this->resolved();
|
| 226 |
|
| 227 |
return $thumbnail_data;
|
| 228 |
}
|
|
@@ -286,45 +235,16 @@ class Post_Thumbnail implements \ArrayAccess, \Serializable {
|
|
| 286 |
$data = $this->fetch_data();
|
| 287 |
$data['post_id'] = $this->post_id;
|
| 288 |
|
| 289 |
-
return
|
| 290 |
}
|
| 291 |
|
| 292 |
/**
|
| 293 |
* {@inheritDoc}
|
| 294 |
*/
|
| 295 |
public function unserialize( $serialized ) {
|
| 296 |
-
$data
|
| 297 |
-
array_walk( $data, static function ( &$data_entry ) {
|
| 298 |
-
if ( is_array( $data_entry ) ) {
|
| 299 |
-
$data_entry = (object) $data_entry;
|
| 300 |
-
}
|
| 301 |
-
} );
|
| 302 |
$this->post_id = $data['post_id'];
|
| 303 |
unset( $data['post_id'] );
|
| 304 |
-
$this->data =
|
| 305 |
-
}
|
| 306 |
-
|
| 307 |
-
/**
|
| 308 |
-
* Returns whether a post thumbnail is set for the post or not.
|
| 309 |
-
*
|
| 310 |
-
* @since 4.9.16
|
| 311 |
-
*
|
| 312 |
-
* @return bool Whether a post thumbnail is set for the post or not.
|
| 313 |
-
*/
|
| 314 |
-
public function exists() {
|
| 315 |
-
if ( null !== $this->exists ) {
|
| 316 |
-
return $this->exists;
|
| 317 |
-
}
|
| 318 |
-
|
| 319 |
-
$thumbnail_id = get_post_thumbnail_id( $this->post_id );
|
| 320 |
-
|
| 321 |
-
if ( empty( $thumbnail_id ) ) {
|
| 322 |
-
$this->exists = false;
|
| 323 |
-
} else {
|
| 324 |
-
$this->thumbnail_id = $thumbnail_id;
|
| 325 |
-
$this->exists = true;
|
| 326 |
-
}
|
| 327 |
-
|
| 328 |
-
return $this->exists;
|
| 329 |
}
|
| 330 |
}
|
| 28 |
* @package Tribe\Utils
|
| 29 |
*/
|
| 30 |
class Post_Thumbnail implements \ArrayAccess, \Serializable {
|
|
|
|
|
|
|
| 31 |
/**
|
| 32 |
* An array of the site image sizes, including the `full` one.
|
| 33 |
*
|
| 55 |
*/
|
| 56 |
protected $data;
|
| 57 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 58 |
/**
|
| 59 |
* Post_Images constructor.
|
| 60 |
*
|
| 68 |
* {@inheritDoc}
|
| 69 |
*/
|
| 70 |
public function __get( $property ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
| 71 |
return $this->offsetGet( $property );
|
| 72 |
}
|
| 73 |
|
| 75 |
* {@inheritDoc}
|
| 76 |
*/
|
| 77 |
public function __set( $property, $value ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
| 78 |
$this->offsetSet( $property, $value );
|
| 79 |
}
|
| 80 |
|
| 119 |
* @return array An array of objects containing the post thumbnail data.
|
| 120 |
*/
|
| 121 |
public function fetch_data() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 122 |
if ( null !== $this->data ) {
|
| 123 |
return $this->data;
|
| 124 |
}
|
| 125 |
|
| 126 |
+
$post_id = $this->post_id;
|
| 127 |
+
$image_sizes = $this->get_image_sizes();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 128 |
|
| 129 |
+
$thumbnail_id = get_post_thumbnail_id( $post_id );
|
|
|
|
| 130 |
|
| 131 |
+
if ( empty( $thumbnail_id ) ) {
|
| 132 |
+
return [];
|
| 133 |
+
}
|
|
|
|
|
|
|
| 134 |
|
| 135 |
+
$thumbnail_data = array_combine(
|
| 136 |
+
$image_sizes,
|
| 137 |
+
array_map(
|
| 138 |
+
static function ( $size ) use ( $thumbnail_id ) {
|
| 139 |
+
$size_data = wp_get_attachment_image_src( $thumbnail_id, $size );
|
|
|
|
|
|
|
|
|
|
| 140 |
|
| 141 |
+
if ( false === $size_data ) {
|
| 142 |
return (object) [
|
| 143 |
+
'url' => '',
|
| 144 |
+
'width' => '',
|
| 145 |
+
'height' => '',
|
| 146 |
+
'is_intermediate' => false,
|
| 147 |
];
|
| 148 |
+
}
|
| 149 |
+
|
| 150 |
+
return (object) [
|
| 151 |
+
'url' => Arr::get( $size_data, 0, '' ),
|
| 152 |
+
'width' => Arr::get( $size_data, 1, '' ),
|
| 153 |
+
'heigth' => Arr::get( $size_data, 2, '' ),
|
| 154 |
+
'is_intermediate' => (bool) Arr::get( $size_data, 3, false ),
|
| 155 |
+
];
|
| 156 |
+
},
|
| 157 |
+
$image_sizes
|
| 158 |
+
)
|
| 159 |
+
);
|
| 160 |
+
|
| 161 |
+
$srcset = wp_get_attachment_image_srcset( $thumbnail_id );
|
| 162 |
+
$thumbnail_data['srcset'] = ! empty( $srcset ) ? $srcset : false;
|
|
|
|
| 163 |
|
| 164 |
/**
|
| 165 |
* Filters the post thumbnail data and information that will be returned for a specific post.
|
| 171 |
* @param array $thumbnail_data The thumbnail data for the post.
|
| 172 |
* @param int $post_id The ID of the post the data is for.
|
| 173 |
*/
|
| 174 |
+
$thumbnail_data = apply_filters( 'tribe_post_thumbnail_data', $thumbnail_data, $post_id );
|
|
|
|
|
|
|
| 175 |
|
| 176 |
return $thumbnail_data;
|
| 177 |
}
|
| 235 |
$data = $this->fetch_data();
|
| 236 |
$data['post_id'] = $this->post_id;
|
| 237 |
|
| 238 |
+
return serialize( $data );
|
| 239 |
}
|
| 240 |
|
| 241 |
/**
|
| 242 |
* {@inheritDoc}
|
| 243 |
*/
|
| 244 |
public function unserialize( $serialized ) {
|
| 245 |
+
$data = unserialize( $serialized );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 246 |
$this->post_id = $data['post_id'];
|
| 247 |
unset( $data['post_id'] );
|
| 248 |
+
$this->data = $data;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 249 |
}
|
| 250 |
}
|
common/src/Tribe/Utils/Query.php
DELETED
|
@@ -1,72 +0,0 @@
|
|
| 1 |
-
<?php
|
| 2 |
-
/**
|
| 3 |
-
* Provides utility method related to the creation and manipulation of queries and query objects.
|
| 4 |
-
*
|
| 5 |
-
* @since 4.9.21
|
| 6 |
-
*
|
| 7 |
-
* @package Tribe\Utils
|
| 8 |
-
*/
|
| 9 |
-
|
| 10 |
-
namespace Tribe\Utils;
|
| 11 |
-
|
| 12 |
-
/**
|
| 13 |
-
* Class Query
|
| 14 |
-
*
|
| 15 |
-
* @since 4.9.21
|
| 16 |
-
*
|
| 17 |
-
* @package Tribe\Utils
|
| 18 |
-
*/
|
| 19 |
-
class Query {
|
| 20 |
-
|
| 21 |
-
/**
|
| 22 |
-
* Builds a new `WP_Query` object and sets the post, and accessory flags, on it.
|
| 23 |
-
*
|
| 24 |
-
* The query is built to yield to run a query that will yield no result and to have a `request` property that
|
| 25 |
-
* will never yield results; calls on the `WP_Query::get_posts` method are filtered to always return the post set.
|
| 26 |
-
* Queries built by this function can be spotted by looking for the `tribe_mock_query` property.
|
| 27 |
-
*
|
| 28 |
-
* @since 4.9.21
|
| 29 |
-
*
|
| 30 |
-
* @param array $posts The array of posts that should be used to build the query.
|
| 31 |
-
*
|
| 32 |
-
* @return \WP_Query The new WP_Query object, built to reflect the posts passed to it.
|
| 33 |
-
*/
|
| 34 |
-
public static function for_posts( array $posts = [] ) {
|
| 35 |
-
if ( empty( $posts ) ) {
|
| 36 |
-
$posts = [];
|
| 37 |
-
}
|
| 38 |
-
|
| 39 |
-
$query = new \WP_Query();
|
| 40 |
-
$query->posts = $posts;
|
| 41 |
-
$query->found_posts = count( $posts );
|
| 42 |
-
$query->post = reset( $posts );
|
| 43 |
-
$query->query = [ 'p' => 0 ];
|
| 44 |
-
$query->tribe_mock_query = true;
|
| 45 |
-
global $wpdb;
|
| 46 |
-
// Use a query that will never yield results.
|
| 47 |
-
$query->request = "SELECT ID FROM {$wpdb->posts} WHERE 1=0";
|
| 48 |
-
|
| 49 |
-
// Return the same set of posts on each method requiring posts.
|
| 50 |
-
$filter_posts_pre_query = static function ( $the_posts, $the_query ) use ( $posts, $query ) {
|
| 51 |
-
if ( $the_query !== $query ) {
|
| 52 |
-
return $the_posts;
|
| 53 |
-
}
|
| 54 |
-
|
| 55 |
-
$fields = $query->get( 'fields', false );
|
| 56 |
-
// We assume some uniformity here.
|
| 57 |
-
$posts_are_objects = ! is_numeric( reset( $posts ) );
|
| 58 |
-
|
| 59 |
-
switch ( $fields ) {
|
| 60 |
-
case 'ids':
|
| 61 |
-
return $posts_are_objects ? wp_list_pluck( $posts, 'ID' ) : $posts;
|
| 62 |
-
case 'id=>parent':
|
| 63 |
-
default:
|
| 64 |
-
return $posts_are_objects ? $posts : array_map( 'get_post', $posts );
|
| 65 |
-
}
|
| 66 |
-
};
|
| 67 |
-
|
| 68 |
-
add_filter( 'posts_pre_query', $filter_posts_pre_query, 10, 2 );
|
| 69 |
-
|
| 70 |
-
return $query;
|
| 71 |
-
}
|
| 72 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
common/src/Tribe/Utils/Strings.php
DELETED
|
@@ -1,65 +0,0 @@
|
|
| 1 |
-
<?php
|
| 2 |
-
/**
|
| 3 |
-
* String Utilities
|
| 4 |
-
*
|
| 5 |
-
* @since 4.12.1
|
| 6 |
-
* @package Tribe\Utils
|
| 7 |
-
*/
|
| 8 |
-
|
| 9 |
-
namespace Tribe\Utils;
|
| 10 |
-
|
| 11 |
-
/**
|
| 12 |
-
* Class Strings
|
| 13 |
-
*
|
| 14 |
-
* @since 4.12.1
|
| 15 |
-
*
|
| 16 |
-
* @package Tribe\Utils
|
| 17 |
-
*/
|
| 18 |
-
class Strings {
|
| 19 |
-
|
| 20 |
-
/**
|
| 21 |
-
* Replace the first occurrence of a given value in the string.
|
| 22 |
-
*
|
| 23 |
-
* @since 4.12.1
|
| 24 |
-
*
|
| 25 |
-
* @param string $search The string to search for and replace.
|
| 26 |
-
* @param string $replace The replacement string.
|
| 27 |
-
* @param string $subject The string to do the search and replace from.
|
| 28 |
-
*
|
| 29 |
-
* @return string The string with the first occurrence of a given value replaced.
|
| 30 |
-
*/
|
| 31 |
-
public static function replace_first( $search, $replace, $subject ) {
|
| 32 |
-
if ( '' === $search ) {
|
| 33 |
-
return $subject;
|
| 34 |
-
}
|
| 35 |
-
|
| 36 |
-
$position = strpos( $subject, $search );
|
| 37 |
-
|
| 38 |
-
if ( $position !== false ) {
|
| 39 |
-
return substr_replace( $subject, $replace, $position, strlen( $search ) );
|
| 40 |
-
}
|
| 41 |
-
|
| 42 |
-
return $subject;
|
| 43 |
-
}
|
| 44 |
-
|
| 45 |
-
/**
|
| 46 |
-
* Replace the last occurrence of a given value in the string.
|
| 47 |
-
*
|
| 48 |
-
* @since 4.12.1
|
| 49 |
-
*
|
| 50 |
-
* @param string $search The string to search for and replace.
|
| 51 |
-
* @param string $replace The replacement string.
|
| 52 |
-
* @param string $subject The string to do the search and replace from.
|
| 53 |
-
*
|
| 54 |
-
* @return string The string with the last occurrence of a given value replaced.
|
| 55 |
-
*/
|
| 56 |
-
public static function replace_last( $search, $replace, $subject ) {
|
| 57 |
-
$position = strrpos( $subject, $search );
|
| 58 |
-
|
| 59 |
-
if ( $position !== false ) {
|
| 60 |
-
return substr_replace( $subject, $replace, $position, strlen( $search ) );
|
| 61 |
-
}
|
| 62 |
-
|
| 63 |
-
return $subject;
|
| 64 |
-
}
|
| 65 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
common/src/Tribe/Validate.php
CHANGED
|
@@ -109,6 +109,8 @@ if ( ! class_exists( 'Tribe__Validate' ) ) {
|
|
| 109 |
|
| 110 |
/**
|
| 111 |
* validates a field as a string containing only letters and numbers
|
|
|
|
|
|
|
| 112 |
*/
|
| 113 |
public function alpha_numeric() {
|
| 114 |
if ( preg_match( '/^[a-zA-Z0-9]+$/', $this->value ) ) {
|
|
@@ -122,6 +124,8 @@ if ( ! class_exists( 'Tribe__Validate' ) ) {
|
|
| 122 |
/**
|
| 123 |
* validates a field as a string containing only letters,
|
| 124 |
* numbers and carriage returns
|
|
|
|
|
|
|
| 125 |
*/
|
| 126 |
public function alpha_numeric_multi_line() {
|
| 127 |
if ( preg_match( '/^[a-zA-Z0-9\s]+$/', $this->value ) ) {
|
|
@@ -136,6 +140,8 @@ if ( ! class_exists( 'Tribe__Validate' ) ) {
|
|
| 136 |
/**
|
| 137 |
* Validates a field as a string containing only letters,
|
| 138 |
* numbers, dots and carriage returns
|
|
|
|
|
|
|
| 139 |
*/
|
| 140 |
public function alpha_numeric_multi_line_with_dots_and_dashes() {
|
| 141 |
if ( preg_match( '/^[a-zA-Z0-9\s.-]+$/', $this->value ) ) {
|
|
@@ -150,6 +156,8 @@ if ( ! class_exists( 'Tribe__Validate' ) ) {
|
|
| 150 |
/**
|
| 151 |
* Validates a field as a string containing only letters,
|
| 152 |
* numbers, dashes and underscores
|
|
|
|
|
|
|
| 153 |
*/
|
| 154 |
public function alpha_numeric_with_dashes_and_underscores() {
|
| 155 |
$this->value = trim( $this->value );
|
|
@@ -165,6 +173,8 @@ if ( ! class_exists( 'Tribe__Validate' ) ) {
|
|
| 165 |
* Validates a field as just "not empty".
|
| 166 |
*
|
| 167 |
* @since 4.7.6
|
|
|
|
|
|
|
| 168 |
*/
|
| 169 |
public function not_empty() {
|
| 170 |
$this->value = trim( $this->value );
|
|
@@ -179,6 +189,8 @@ if ( ! class_exists( 'Tribe__Validate' ) ) {
|
|
| 179 |
|
| 180 |
/**
|
| 181 |
* validates a field as being positive decimal
|
|
|
|
|
|
|
| 182 |
*/
|
| 183 |
public function positive_decimal() {
|
| 184 |
if ( preg_match( '/^[0-9]+(\.[0-9]+)?$/', $this->value ) && $this->value > 0 ) {
|
|
@@ -191,6 +203,8 @@ if ( ! class_exists( 'Tribe__Validate' ) ) {
|
|
| 191 |
|
| 192 |
/**
|
| 193 |
* validates a field as being positive decimal or percent
|
|
|
|
|
|
|
| 194 |
*/
|
| 195 |
public function positive_decimal_or_percent() {
|
| 196 |
if ( preg_match( '/^[0-9]+(\.[0-9]+)?%?$/', $this->value ) && $this->value > 0 ) {
|
|
@@ -203,6 +217,8 @@ if ( ! class_exists( 'Tribe__Validate' ) ) {
|
|
| 203 |
|
| 204 |
/**
|
| 205 |
* validates a field as being positive integers
|
|
|
|
|
|
|
| 206 |
*/
|
| 207 |
public function positive_int() {
|
| 208 |
if ( preg_match( '/^[0-9]+$/', $this->value ) && $this->value > 0 ) {
|
|
@@ -221,6 +237,8 @@ if ( ! class_exists( 'Tribe__Validate' ) ) {
|
|
| 221 |
* with a similar name: positive_int(). This method WILL validate whole numbers that go beyond
|
| 222 |
* values that PHP's int type supports, however, if someone enters something like that, that's
|
| 223 |
* on them. Smart people do smart things.
|
|
|
|
|
|
|
| 224 |
*/
|
| 225 |
public function int() {
|
| 226 |
if ( preg_match( '/^-?[0-9]+$/', $this->value ) ) {
|
|
@@ -233,16 +251,15 @@ if ( ! class_exists( 'Tribe__Validate' ) ) {
|
|
| 233 |
|
| 234 |
/**
|
| 235 |
* validates & sanitizes fields as URL slugs
|
|
|
|
|
|
|
| 236 |
*/
|
| 237 |
public function slug() {
|
| 238 |
$maybe_valid_value = esc_url_raw( $this->value );
|
| 239 |
|
| 240 |
// esc_url_raw does the work of validating chars, but returns the checked string with a
|
| 241 |
// prepended URL protocol; so let's use strpos to match the values.
|
| 242 |
-
if (
|
| 243 |
-
! empty( $maybe_valid_value )
|
| 244 |
-
&& false !== strpos( $maybe_valid_value, $this->value )
|
| 245 |
-
) {
|
| 246 |
$this->result->valid = true;
|
| 247 |
$this->value = sanitize_title( $this->value );
|
| 248 |
} else {
|
|
@@ -253,6 +270,8 @@ if ( ! class_exists( 'Tribe__Validate' ) ) {
|
|
| 253 |
|
| 254 |
/**
|
| 255 |
* validates & sanitizes fields as URLs
|
|
|
|
|
|
|
| 256 |
*/
|
| 257 |
public function url() {
|
| 258 |
|
|
@@ -260,13 +279,15 @@ if ( ! class_exists( 'Tribe__Validate' ) ) {
|
|
| 260 |
$this->result->valid = true;
|
| 261 |
} else {
|
| 262 |
$this->result->valid = false;
|
| 263 |
-
$this->result->error = sprintf( esc_html__( '%s must be a valid URL.', 'tribe-common' ), $this->label );
|
| 264 |
}
|
| 265 |
}
|
| 266 |
|
| 267 |
/**
|
| 268 |
* validates fields that have options (radios, dropdowns, etc.)
|
| 269 |
* by making sure the value is part of the options array
|
|
|
|
|
|
|
| 270 |
*/
|
| 271 |
public function options() {
|
| 272 |
if ( array_key_exists( $this->value, $this->field['options'] ) ) {
|
|
@@ -307,8 +328,10 @@ if ( ! class_exists( 'Tribe__Validate' ) ) {
|
|
| 307 |
/**
|
| 308 |
* validates fields that have options (radios, dropdowns, etc.)
|
| 309 |
* by making sure the value is part of the options array
|
| 310 |
-
* then combines the value into an array
|
| 311 |
* and name from the option
|
|
|
|
|
|
|
| 312 |
*/
|
| 313 |
public function options_with_label() {
|
| 314 |
if ( array_key_exists( $this->value, $this->field['options'] ) ) {
|
|
@@ -327,6 +350,8 @@ if ( ! class_exists( 'Tribe__Validate' ) ) {
|
|
| 327 |
* validates a field as not being able to be the same
|
| 328 |
* as the specified value as specified in
|
| 329 |
* $this->additional_args['compare_name']
|
|
|
|
|
|
|
| 330 |
*/
|
| 331 |
public function cannot_be_the_same_as() {
|
| 332 |
if ( ! isset( $this->additional_args['compare'] ) ) {
|
|
@@ -348,6 +373,8 @@ if ( ! class_exists( 'Tribe__Validate' ) ) {
|
|
| 348 |
|
| 349 |
/**
|
| 350 |
* validates a field as being a number or a percentage
|
|
|
|
|
|
|
| 351 |
*/
|
| 352 |
public function number_or_percent() {
|
| 353 |
if ( preg_match( '/^[0-9]+%{0,1}$/', $this->value ) ) {
|
|
@@ -360,6 +387,8 @@ if ( ! class_exists( 'Tribe__Validate' ) ) {
|
|
| 360 |
|
| 361 |
/**
|
| 362 |
* sanitizes an html field
|
|
|
|
|
|
|
| 363 |
*/
|
| 364 |
public function html() {
|
| 365 |
$this->value = balanceTags( $this->value );
|
|
@@ -368,6 +397,8 @@ if ( ! class_exists( 'Tribe__Validate' ) ) {
|
|
| 368 |
|
| 369 |
/**
|
| 370 |
* sanitizes a license key
|
|
|
|
|
|
|
| 371 |
*/
|
| 372 |
public function license_key() {
|
| 373 |
$this->value = trim( $this->value );
|
|
@@ -376,14 +407,18 @@ if ( ! class_exists( 'Tribe__Validate' ) ) {
|
|
| 376 |
|
| 377 |
/**
|
| 378 |
* sanitizes a textarea field
|
|
|
|
|
|
|
| 379 |
*/
|
| 380 |
public function textarea() {
|
| 381 |
-
$this->value = wp_kses( $this->value,
|
| 382 |
$this->result->valid = true;
|
| 383 |
}
|
| 384 |
|
| 385 |
/**
|
| 386 |
-
* sanitizes a field as
|
|
|
|
|
|
|
| 387 |
*/
|
| 388 |
public function boolean() {
|
| 389 |
$this->value = (bool) $this->value;
|
|
@@ -392,6 +427,8 @@ if ( ! class_exists( 'Tribe__Validate' ) ) {
|
|
| 392 |
|
| 393 |
/**
|
| 394 |
* validates a Google Maps Zoom field
|
|
|
|
|
|
|
| 395 |
*/
|
| 396 |
public function google_maps_zoom() {
|
| 397 |
if ( preg_match( '/^([0-9]|[0-1][0-9]|2[0-1])$/', $this->value ) ) {
|
|
@@ -404,7 +441,9 @@ if ( ! class_exists( 'Tribe__Validate' ) ) {
|
|
| 404 |
|
| 405 |
/**
|
| 406 |
* validates a field as being part of an address
|
| 407 |
-
* allows for letters, numbers,
|
|
|
|
|
|
|
| 408 |
*/
|
| 409 |
public function address() {
|
| 410 |
$this->value = stripslashes( $this->value );
|
|
@@ -418,7 +457,9 @@ if ( ! class_exists( 'Tribe__Validate' ) ) {
|
|
| 418 |
|
| 419 |
/**
|
| 420 |
* validates a field as being a city or province
|
| 421 |
-
* allows for letters,
|
|
|
|
|
|
|
| 422 |
*/
|
| 423 |
public function city_or_province() {
|
| 424 |
$this->value = stripslashes( $this->value );
|
|
@@ -432,6 +473,8 @@ if ( ! class_exists( 'Tribe__Validate' ) ) {
|
|
| 432 |
|
| 433 |
/**
|
| 434 |
* validates a field as being a zip code
|
|
|
|
|
|
|
| 435 |
*/
|
| 436 |
public function zip() {
|
| 437 |
if ( preg_match( '/^[0-9]{5}$/', $this->value ) ) {
|
|
@@ -444,6 +487,8 @@ if ( ! class_exists( 'Tribe__Validate' ) ) {
|
|
| 444 |
|
| 445 |
/**
|
| 446 |
* validates a field as being a phone number
|
|
|
|
|
|
|
| 447 |
*/
|
| 448 |
public function phone() {
|
| 449 |
if ( preg_match( '/^[0-9\(\)\+ -]+$/', $this->value ) ) {
|
|
@@ -456,6 +501,8 @@ if ( ! class_exists( 'Tribe__Validate' ) ) {
|
|
| 456 |
|
| 457 |
/**
|
| 458 |
* validates & sanitizes a field as being a country list
|
|
|
|
|
|
|
| 459 |
*/
|
| 460 |
public function country_list() {
|
| 461 |
$country_rows = explode( "\n", $this->value );
|
|
@@ -477,6 +524,8 @@ if ( ! class_exists( 'Tribe__Validate' ) ) {
|
|
| 477 |
/**
|
| 478 |
* automatically validate a field regardless of the value
|
| 479 |
* Don't use this unless you know what you are doing
|
|
|
|
|
|
|
| 480 |
*/
|
| 481 |
public function none() {
|
| 482 |
$this->result->valid = true;
|
| 109 |
|
| 110 |
/**
|
| 111 |
* validates a field as a string containing only letters and numbers
|
| 112 |
+
*
|
| 113 |
+
* @return stdClass validation result object
|
| 114 |
*/
|
| 115 |
public function alpha_numeric() {
|
| 116 |
if ( preg_match( '/^[a-zA-Z0-9]+$/', $this->value ) ) {
|
| 124 |
/**
|
| 125 |
* validates a field as a string containing only letters,
|
| 126 |
* numbers and carriage returns
|
| 127 |
+
*
|
| 128 |
+
* @return stdClass validation result object
|
| 129 |
*/
|
| 130 |
public function alpha_numeric_multi_line() {
|
| 131 |
if ( preg_match( '/^[a-zA-Z0-9\s]+$/', $this->value ) ) {
|
| 140 |
/**
|
| 141 |
* Validates a field as a string containing only letters,
|
| 142 |
* numbers, dots and carriage returns
|
| 143 |
+
*
|
| 144 |
+
* @return stdClass validation result object
|
| 145 |
*/
|
| 146 |
public function alpha_numeric_multi_line_with_dots_and_dashes() {
|
| 147 |
if ( preg_match( '/^[a-zA-Z0-9\s.-]+$/', $this->value ) ) {
|
| 156 |
/**
|
| 157 |
* Validates a field as a string containing only letters,
|
| 158 |
* numbers, dashes and underscores
|
| 159 |
+
*
|
| 160 |
+
* @return stdClass validation result object
|
| 161 |
*/
|
| 162 |
public function alpha_numeric_with_dashes_and_underscores() {
|
| 163 |
$this->value = trim( $this->value );
|
| 173 |
* Validates a field as just "not empty".
|
| 174 |
*
|
| 175 |
* @since 4.7.6
|
| 176 |
+
*
|
| 177 |
+
* @return stdClass validation result object
|
| 178 |
*/
|
| 179 |
public function not_empty() {
|
| 180 |
$this->value = trim( $this->value );
|
| 189 |
|
| 190 |
/**
|
| 191 |
* validates a field as being positive decimal
|
| 192 |
+
*
|
| 193 |
+
* @return stdClass validation result object
|
| 194 |
*/
|
| 195 |
public function positive_decimal() {
|
| 196 |
if ( preg_match( '/^[0-9]+(\.[0-9]+)?$/', $this->value ) && $this->value > 0 ) {
|
| 203 |
|
| 204 |
/**
|
| 205 |
* validates a field as being positive decimal or percent
|
| 206 |
+
*
|
| 207 |
+
* @return stdClass validation result object
|
| 208 |
*/
|
| 209 |
public function positive_decimal_or_percent() {
|
| 210 |
if ( preg_match( '/^[0-9]+(\.[0-9]+)?%?$/', $this->value ) && $this->value > 0 ) {
|
| 217 |
|
| 218 |
/**
|
| 219 |
* validates a field as being positive integers
|
| 220 |
+
*
|
| 221 |
+
* @return stdClass validation result object
|
| 222 |
*/
|
| 223 |
public function positive_int() {
|
| 224 |
if ( preg_match( '/^[0-9]+$/', $this->value ) && $this->value > 0 ) {
|
| 237 |
* with a similar name: positive_int(). This method WILL validate whole numbers that go beyond
|
| 238 |
* values that PHP's int type supports, however, if someone enters something like that, that's
|
| 239 |
* on them. Smart people do smart things.
|
| 240 |
+
*
|
| 241 |
+
* @return stdClass validation result object
|
| 242 |
*/
|
| 243 |
public function int() {
|
| 244 |
if ( preg_match( '/^-?[0-9]+$/', $this->value ) ) {
|
| 251 |
|
| 252 |
/**
|
| 253 |
* validates & sanitizes fields as URL slugs
|
| 254 |
+
*
|
| 255 |
+
* @return stdClass validation result object
|
| 256 |
*/
|
| 257 |
public function slug() {
|
| 258 |
$maybe_valid_value = esc_url_raw( $this->value );
|
| 259 |
|
| 260 |
// esc_url_raw does the work of validating chars, but returns the checked string with a
|
| 261 |
// prepended URL protocol; so let's use strpos to match the values.
|
| 262 |
+
if ( false !== strpos( $maybe_valid_value, $this->value ) ) {
|
|
|
|
|
|
|
|
|
|
| 263 |
$this->result->valid = true;
|
| 264 |
$this->value = sanitize_title( $this->value );
|
| 265 |
} else {
|
| 270 |
|
| 271 |
/**
|
| 272 |
* validates & sanitizes fields as URLs
|
| 273 |
+
*
|
| 274 |
+
* @return stdClass validation result object
|
| 275 |
*/
|
| 276 |
public function url() {
|
| 277 |
|
| 279 |
$this->result->valid = true;
|
| 280 |
} else {
|
| 281 |
$this->result->valid = false;
|
| 282 |
+
$this->result->error = sprintf( esc_html__( '%s must be a valid absolute URL.', 'tribe-common' ), $this->label );
|
| 283 |
}
|
| 284 |
}
|
| 285 |
|
| 286 |
/**
|
| 287 |
* validates fields that have options (radios, dropdowns, etc.)
|
| 288 |
* by making sure the value is part of the options array
|
| 289 |
+
*
|
| 290 |
+
* @return stdClass validation result object
|
| 291 |
*/
|
| 292 |
public function options() {
|
| 293 |
if ( array_key_exists( $this->value, $this->field['options'] ) ) {
|
| 328 |
/**
|
| 329 |
* validates fields that have options (radios, dropdowns, etc.)
|
| 330 |
* by making sure the value is part of the options array
|
| 331 |
+
* then combines the value into an array containg the value
|
| 332 |
* and name from the option
|
| 333 |
+
*
|
| 334 |
+
* @return stdClass validation result object
|
| 335 |
*/
|
| 336 |
public function options_with_label() {
|
| 337 |
if ( array_key_exists( $this->value, $this->field['options'] ) ) {
|
| 350 |
* validates a field as not being able to be the same
|
| 351 |
* as the specified value as specified in
|
| 352 |
* $this->additional_args['compare_name']
|
| 353 |
+
*
|
| 354 |
+
* @return stdClass validation result object
|
| 355 |
*/
|
| 356 |
public function cannot_be_the_same_as() {
|
| 357 |
if ( ! isset( $this->additional_args['compare'] ) ) {
|
| 373 |
|
| 374 |
/**
|
| 375 |
* validates a field as being a number or a percentage
|
| 376 |
+
*
|
| 377 |
+
* @return stdClass validation result object
|
| 378 |
*/
|
| 379 |
public function number_or_percent() {
|
| 380 |
if ( preg_match( '/^[0-9]+%{0,1}$/', $this->value ) ) {
|
| 387 |
|
| 388 |
/**
|
| 389 |
* sanitizes an html field
|
| 390 |
+
*
|
| 391 |
+
* @return stdClass validation result object
|
| 392 |
*/
|
| 393 |
public function html() {
|
| 394 |
$this->value = balanceTags( $this->value );
|
| 397 |
|
| 398 |
/**
|
| 399 |
* sanitizes a license key
|
| 400 |
+
*
|
| 401 |
+
* @return stdClass validation result object
|
| 402 |
*/
|
| 403 |
public function license_key() {
|
| 404 |
$this->value = trim( $this->value );
|
| 407 |
|
| 408 |
/**
|
| 409 |
* sanitizes a textarea field
|
| 410 |
+
*
|
| 411 |
+
* @return stdClass validation result object
|
| 412 |
*/
|
| 413 |
public function textarea() {
|
| 414 |
+
$this->value = wp_kses( $this->value, array() );
|
| 415 |
$this->result->valid = true;
|
| 416 |
}
|
| 417 |
|
| 418 |
/**
|
| 419 |
+
* sanitizes a field as beeing a boolean
|
| 420 |
+
*
|
| 421 |
+
* @return stdClass validation result object
|
| 422 |
*/
|
| 423 |
public function boolean() {
|
| 424 |
$this->value = (bool) $this->value;
|
| 427 |
|
| 428 |
/**
|
| 429 |
* validates a Google Maps Zoom field
|
| 430 |
+
*
|
| 431 |
+
* @return stdClass validation result object
|
| 432 |
*/
|
| 433 |
public function google_maps_zoom() {
|
| 434 |
if ( preg_match( '/^([0-9]|[0-1][0-9]|2[0-1])$/', $this->value ) ) {
|
| 441 |
|
| 442 |
/**
|
| 443 |
* validates a field as being part of an address
|
| 444 |
+
* allows for letters, numbers, dashses and spaces only
|
| 445 |
+
*
|
| 446 |
+
* @return stdClass validation result object
|
| 447 |
*/
|
| 448 |
public function address() {
|
| 449 |
$this->value = stripslashes( $this->value );
|
| 457 |
|
| 458 |
/**
|
| 459 |
* validates a field as being a city or province
|
| 460 |
+
* allows for letters, dashses and spaces only
|
| 461 |
+
*
|
| 462 |
+
* @return stdClass validation result object
|
| 463 |
*/
|
| 464 |
public function city_or_province() {
|
| 465 |
$this->value = stripslashes( $this->value );
|
| 473 |
|
| 474 |
/**
|
| 475 |
* validates a field as being a zip code
|
| 476 |
+
*
|
| 477 |
+
* @return stdClass validation result object
|
| 478 |
*/
|
| 479 |
public function zip() {
|
| 480 |
if ( preg_match( '/^[0-9]{5}$/', $this->value ) ) {
|
| 487 |
|
| 488 |
/**
|
| 489 |
* validates a field as being a phone number
|
| 490 |
+
*
|
| 491 |
+
* @return stdClass validation result object
|
| 492 |
*/
|
| 493 |
public function phone() {
|
| 494 |
if ( preg_match( '/^[0-9\(\)\+ -]+$/', $this->value ) ) {
|
| 501 |
|
| 502 |
/**
|
| 503 |
* validates & sanitizes a field as being a country list
|
| 504 |
+
*
|
| 505 |
+
* @return stdClass validation result object
|
| 506 |
*/
|
| 507 |
public function country_list() {
|
| 508 |
$country_rows = explode( "\n", $this->value );
|
| 524 |
/**
|
| 525 |
* automatically validate a field regardless of the value
|
| 526 |
* Don't use this unless you know what you are doing
|
| 527 |
+
*
|
| 528 |
+
* @return stdClass validation result object
|
| 529 |
*/
|
| 530 |
public function none() {
|
| 531 |
$this->result->valid = true;
|
common/src/Tribe/Validator/Base.php
CHANGED
|
@@ -158,9 +158,7 @@ class Tribe__Validator__Base implements Tribe__Validator__Interface {
|
|
| 158 |
public function is_image( $image ) {
|
| 159 |
if ( $this->is_numeric( $image ) ) {
|
| 160 |
return wp_attachment_is_image( $image );
|
| 161 |
-
}
|
| 162 |
-
|
| 163 |
-
if ( is_string( $image ) ) {
|
| 164 |
$response = wp_remote_head( $image );
|
| 165 |
|
| 166 |
if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) {
|
| 158 |
public function is_image( $image ) {
|
| 159 |
if ( $this->is_numeric( $image ) ) {
|
| 160 |
return wp_attachment_is_image( $image );
|
| 161 |
+
} elseif ( is_string( $image ) ) {
|
|
|
|
|
|
|
| 162 |
$response = wp_remote_head( $image );
|
| 163 |
|
| 164 |
if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) {
|
common/src/Tribe/View_Helpers.php
CHANGED
|
@@ -20,18 +20,10 @@ if ( ! class_exists( 'Tribe__View_Helpers' ) ) {
|
|
| 20 |
* @return array The countries array.
|
| 21 |
*/
|
| 22 |
public static function constructCountries( $postId = '', $useDefault = true ) {
|
| 23 |
-
static $cache_var_name = __METHOD__;
|
| 24 |
-
|
| 25 |
-
$countries = tribe_get_var( $cache_var_name, null );
|
| 26 |
-
|
| 27 |
-
if ( $countries ) {
|
| 28 |
-
return $countries;
|
| 29 |
-
}
|
| 30 |
-
|
| 31 |
$eventCountries = tribe_get_option( 'tribeEventsCountries' );
|
| 32 |
|
| 33 |
if ( $eventCountries != '' ) {
|
| 34 |
-
$countries =
|
| 35 |
|
| 36 |
$country_rows = explode( "\n", $eventCountries );
|
| 37 |
foreach ( $country_rows as $crow ) {
|
|
@@ -73,11 +65,11 @@ if ( ! class_exists( 'Tribe__View_Helpers' ) ) {
|
|
| 73 |
$countries = array( '' => $selectCountry ) + $countries;
|
| 74 |
array_unique( $countries );
|
| 75 |
}
|
| 76 |
-
}
|
| 77 |
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
|
|
|
| 81 |
}
|
| 82 |
|
| 83 |
/**
|
| 20 |
* @return array The countries array.
|
| 21 |
*/
|
| 22 |
public static function constructCountries( $postId = '', $useDefault = true ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 23 |
$eventCountries = tribe_get_option( 'tribeEventsCountries' );
|
| 24 |
|
| 25 |
if ( $eventCountries != '' ) {
|
| 26 |
+
$countries = array();
|
| 27 |
|
| 28 |
$country_rows = explode( "\n", $eventCountries );
|
| 29 |
foreach ( $country_rows as $crow ) {
|
| 65 |
$countries = array( '' => $selectCountry ) + $countries;
|
| 66 |
array_unique( $countries );
|
| 67 |
}
|
|
|
|
| 68 |
|
| 69 |
+
return $countries;
|
| 70 |
+
} else {
|
| 71 |
+
return $countries;
|
| 72 |
+
}
|
| 73 |
}
|
| 74 |
|
| 75 |
/**
|
common/src/admin-views/tribe-options-display.php
CHANGED
|
@@ -31,12 +31,12 @@ $displayTab = array(
|
|
| 31 |
)
|
| 32 |
. '</p>',
|
| 33 |
),
|
| 34 |
-
'datepickerFormat' =>
|
| 35 |
'type' => 'dropdown',
|
| 36 |
-
'label' => esc_html__( '
|
| 37 |
-
'tooltip' => esc_html__( 'Select the date format
|
| 38 |
-
'default' =>
|
| 39 |
-
'options' =>
|
| 40 |
'0' => date( 'Y-m-d', $sample_date ),
|
| 41 |
'1' => date( 'n/j/Y', $sample_date ),
|
| 42 |
'2' => date( 'm/d/Y', $sample_date ),
|
|
@@ -49,13 +49,13 @@ $displayTab = array(
|
|
| 49 |
'9' => date( 'Y.m.d', $sample_date ),
|
| 50 |
'10' => date( 'm.d.Y', $sample_date ),
|
| 51 |
'11' => date( 'd.m.Y', $sample_date ),
|
| 52 |
-
|
| 53 |
'validation_type' => 'options',
|
| 54 |
-
|
| 55 |
-
'tribe-form-content-end' =>
|
| 56 |
'type' => 'html',
|
| 57 |
'html' => '</div>',
|
| 58 |
-
|
| 59 |
)
|
| 60 |
),
|
| 61 |
);
|
| 31 |
)
|
| 32 |
. '</p>',
|
| 33 |
),
|
| 34 |
+
'datepickerFormat' => array(
|
| 35 |
'type' => 'dropdown',
|
| 36 |
+
'label' => esc_html__( 'Datepicker Date Format', 'tribe-common' ),
|
| 37 |
+
'tooltip' => esc_html__( 'Select the date format to use in datepickers', 'tribe-common' ),
|
| 38 |
+
'default' => 'Y-m-d',
|
| 39 |
+
'options' => array(
|
| 40 |
'0' => date( 'Y-m-d', $sample_date ),
|
| 41 |
'1' => date( 'n/j/Y', $sample_date ),
|
| 42 |
'2' => date( 'm/d/Y', $sample_date ),
|
| 49 |
'9' => date( 'Y.m.d', $sample_date ),
|
| 50 |
'10' => date( 'm.d.Y', $sample_date ),
|
| 51 |
'11' => date( 'd.m.Y', $sample_date ),
|
| 52 |
+
),
|
| 53 |
'validation_type' => 'options',
|
| 54 |
+
),
|
| 55 |
+
'tribe-form-content-end' => array(
|
| 56 |
'type' => 'html',
|
| 57 |
'html' => '</div>',
|
| 58 |
+
),
|
| 59 |
)
|
| 60 |
),
|
| 61 |
);
|
common/src/admin-views/tribe-options-general.php
CHANGED
|
@@ -1,77 +1,74 @@
|
|
| 1 |
<?php
|
| 2 |
|
| 3 |
-
$generalTabFields =
|
| 4 |
-
'info-start' =>
|
| 5 |
'type' => 'html',
|
| 6 |
'html' => '<div id="modern-tribe-info"><img src="' . plugins_url( 'resources/images/modern-tribe@2x.png', dirname( __FILE__ ) ) . '" alt="Modern Tribe Inc." title="Modern Tribe Inc.">',
|
| 7 |
-
|
| 8 |
-
'event-tickets-info' =>
|
| 9 |
'type' => 'html',
|
| 10 |
'html' => '<p>' . sprintf( esc_html__( 'Thank you for using Event Tickets! All of us at Modern Tribe sincerely appreciate your support and we\'re excited to see you using our plugins. Check out our handy %1$sNew User Primer%2$s to get started.', 'tribe-common' ), '<a href="http://m.tri.be/18nd">', '</a>' ) . '</p>',
|
| 11 |
'conditional' => ! class_exists( 'Tribe__Events__Main' ),
|
| 12 |
-
|
| 13 |
-
'event-tickets-upsell-info' =>
|
| 14 |
'type' => 'html',
|
| 15 |
'html' => '<p>' . sprintf( esc_html__( 'Optimize your site\'s event listings with %1$sThe Events Calendar%2$s, our free calendar plugin. Looking for additional functionality including recurring events, user-submission, advanced ticket sales and more? Check out our %3$spremium add-ons%4$s.', 'tribe-common' ), '<a href="http://m.tri.be/18x6">', '</a>', '<a href="http://m.tri.be/18x5">', '</a>' ) . '</p>',
|
| 16 |
'conditional' => ! class_exists( 'Tribe__Events__Main' ),
|
| 17 |
-
|
| 18 |
-
'upsell-info' =>
|
| 19 |
'type' => 'html',
|
| 20 |
'html' => '<p>' . esc_html__( 'Looking for additional functionality including recurring events, custom meta, community events, ticket sales and more?', 'tribe-common' ) . ' <a href="' . Tribe__Main::$tec_url . 'products/?utm_source=generaltab&utm_medium=plugin-tec&utm_campaign=in-app">' . esc_html__( 'Check out the available add-ons', 'tribe-common' ) . '</a>.</p>',
|
| 21 |
'conditional' => ( ! defined( 'TRIBE_HIDE_UPSELL' ) || ! TRIBE_HIDE_UPSELL ) && class_exists( 'Tribe__Events__Main' ),
|
| 22 |
-
|
| 23 |
-
'donate-link-heading' =>
|
| 24 |
'type' => 'heading',
|
| 25 |
'label' => esc_html__( 'We hope our plugin is helping you out.', 'tribe-common' ),
|
| 26 |
'conditional' => class_exists( 'Tribe__Events__Main' ),
|
| 27 |
-
|
| 28 |
-
'donate-link-info' =>
|
| 29 |
'type' => 'html',
|
| 30 |
'html' => '<p>' . esc_html__( 'Are you thinking "Wow, this plugin is amazing! I should say thanks to Modern Tribe for all their hard work." The greatest thanks we could ask for is recognition. Add a small text-only link at the bottom of your calendar pointing to The Events Calendar project.', 'tribe-common' ) . '<br><a href="' . esc_url( plugins_url( 'resources/images/donate-link-screenshot.png', dirname( __FILE__ ) ) ) . '" class="thickbox">' . esc_html__( 'See an example of the link', 'tribe-common' ) . '</a>.</p>',
|
| 31 |
'conditional' => class_exists( 'Tribe__Events__Main' ),
|
| 32 |
-
|
| 33 |
-
'donate-link' =>
|
| 34 |
'type' => 'checkbox_bool',
|
| 35 |
'label' => esc_html__( 'Show The Events Calendar link', 'tribe-common' ),
|
| 36 |
'default' => false,
|
| 37 |
'validation_type' => 'boolean',
|
| 38 |
'conditional' => class_exists( 'Tribe__Events__Main' ),
|
| 39 |
-
|
| 40 |
-
'info-end' =>
|
| 41 |
'type' => 'html',
|
| 42 |
'html' => '</div>',
|
| 43 |
-
|
| 44 |
-
'tribe-form-content-start' =>
|
| 45 |
'type' => 'html',
|
| 46 |
'html' => '<div class="tribe-settings-form-wrap">',
|
| 47 |
-
|
| 48 |
-
|
| 49 |
|
| 50 |
if ( is_super_admin() ) {
|
| 51 |
-
$generalTabFields['debugEvents'] =
|
| 52 |
'type' => 'checkbox_bool',
|
| 53 |
'label' => esc_html__( 'Debug mode', 'tribe-common' ),
|
| 54 |
-
'tooltip' => sprintf(
|
| 55 |
-
esc_html__(
|
| 56 |
-
'Enable this option to log debug information. By default this will log to your server PHP error log. If you\'d like to see the log messages in your browser, then we recommend that you install the %s and look for the "Tribe" tab in the debug output.',
|
| 57 |
-
'tribe-common'
|
| 58 |
-
),
|
| 59 |
-
'<a href="https://wordpress.org/extend/plugins/debug-bar/" target="_blank">' . esc_html__( 'Debug Bar Plugin', 'tribe-common' ) . '</a>'
|
| 60 |
-
),
|
| 61 |
'default' => false,
|
| 62 |
'validation_type' => 'boolean',
|
| 63 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 64 |
}
|
| 65 |
|
| 66 |
// Closes form
|
| 67 |
-
$generalTabFields['tribe-form-content-end'] =
|
| 68 |
'type' => 'html',
|
| 69 |
'html' => '</div>',
|
| 70 |
-
|
| 71 |
|
| 72 |
|
| 73 |
-
$generalTab =
|
| 74 |
'priority' => 10,
|
| 75 |
'fields' => apply_filters( 'tribe_general_settings_tab_fields', $generalTabFields ),
|
| 76 |
-
|
| 77 |
|
| 1 |
<?php
|
| 2 |
|
| 3 |
+
$generalTabFields = array(
|
| 4 |
+
'info-start' => array(
|
| 5 |
'type' => 'html',
|
| 6 |
'html' => '<div id="modern-tribe-info"><img src="' . plugins_url( 'resources/images/modern-tribe@2x.png', dirname( __FILE__ ) ) . '" alt="Modern Tribe Inc." title="Modern Tribe Inc.">',
|
| 7 |
+
),
|
| 8 |
+
'event-tickets-info' => array(
|
| 9 |
'type' => 'html',
|
| 10 |
'html' => '<p>' . sprintf( esc_html__( 'Thank you for using Event Tickets! All of us at Modern Tribe sincerely appreciate your support and we\'re excited to see you using our plugins. Check out our handy %1$sNew User Primer%2$s to get started.', 'tribe-common' ), '<a href="http://m.tri.be/18nd">', '</a>' ) . '</p>',
|
| 11 |
'conditional' => ! class_exists( 'Tribe__Events__Main' ),
|
| 12 |
+
),
|
| 13 |
+
'event-tickets-upsell-info' => array(
|
| 14 |
'type' => 'html',
|
| 15 |
'html' => '<p>' . sprintf( esc_html__( 'Optimize your site\'s event listings with %1$sThe Events Calendar%2$s, our free calendar plugin. Looking for additional functionality including recurring events, user-submission, advanced ticket sales and more? Check out our %3$spremium add-ons%4$s.', 'tribe-common' ), '<a href="http://m.tri.be/18x6">', '</a>', '<a href="http://m.tri.be/18x5">', '</a>' ) . '</p>',
|
| 16 |
'conditional' => ! class_exists( 'Tribe__Events__Main' ),
|
| 17 |
+
),
|
| 18 |
+
'upsell-info' => array(
|
| 19 |
'type' => 'html',
|
| 20 |
'html' => '<p>' . esc_html__( 'Looking for additional functionality including recurring events, custom meta, community events, ticket sales and more?', 'tribe-common' ) . ' <a href="' . Tribe__Main::$tec_url . 'products/?utm_source=generaltab&utm_medium=plugin-tec&utm_campaign=in-app">' . esc_html__( 'Check out the available add-ons', 'tribe-common' ) . '</a>.</p>',
|
| 21 |
'conditional' => ( ! defined( 'TRIBE_HIDE_UPSELL' ) || ! TRIBE_HIDE_UPSELL ) && class_exists( 'Tribe__Events__Main' ),
|
| 22 |
+
),
|
| 23 |
+
'donate-link-heading' => array(
|
| 24 |
'type' => 'heading',
|
| 25 |
'label' => esc_html__( 'We hope our plugin is helping you out.', 'tribe-common' ),
|
| 26 |
'conditional' => class_exists( 'Tribe__Events__Main' ),
|
| 27 |
+
),
|
| 28 |
+
'donate-link-info' => array(
|
| 29 |
'type' => 'html',
|
| 30 |
'html' => '<p>' . esc_html__( 'Are you thinking "Wow, this plugin is amazing! I should say thanks to Modern Tribe for all their hard work." The greatest thanks we could ask for is recognition. Add a small text-only link at the bottom of your calendar pointing to The Events Calendar project.', 'tribe-common' ) . '<br><a href="' . esc_url( plugins_url( 'resources/images/donate-link-screenshot.png', dirname( __FILE__ ) ) ) . '" class="thickbox">' . esc_html__( 'See an example of the link', 'tribe-common' ) . '</a>.</p>',
|
| 31 |
'conditional' => class_exists( 'Tribe__Events__Main' ),
|
| 32 |
+
),
|
| 33 |
+
'donate-link' => array(
|
| 34 |
'type' => 'checkbox_bool',
|
| 35 |
'label' => esc_html__( 'Show The Events Calendar link', 'tribe-common' ),
|
| 36 |
'default' => false,
|
| 37 |
'validation_type' => 'boolean',
|
| 38 |
'conditional' => class_exists( 'Tribe__Events__Main' ),
|
| 39 |
+
),
|
| 40 |
+
'info-end' => array(
|
| 41 |
'type' => 'html',
|
| 42 |
'html' => '</div>',
|
| 43 |
+
),
|
| 44 |
+
'tribe-form-content-start' => array(
|
| 45 |
'type' => 'html',
|
| 46 |
'html' => '<div class="tribe-settings-form-wrap">',
|
| 47 |
+
),
|
| 48 |
+
);
|
| 49 |
|
| 50 |
if ( is_super_admin() ) {
|
| 51 |
+
$generalTabFields['debugEvents'] = array(
|
| 52 |
'type' => 'checkbox_bool',
|
| 53 |
'label' => esc_html__( 'Debug mode', 'tribe-common' ),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 54 |
'default' => false,
|
| 55 |
'validation_type' => 'boolean',
|
| 56 |
+
);
|
| 57 |
+
$generalTabFields['debugEventsHelper'] = array(
|
| 58 |
+
'type' => 'html',
|
| 59 |
+
'html' => '<p class="tribe-field-indent tribe-field-description description" style="max-width:400px;">' . sprintf( esc_html__( 'Enable this option to log debug information. By default this will log to your server PHP error log. If you\'d like to see the log messages in your browser, then we recommend that you install the %s and look for the "Tribe" tab in the debug output.', 'tribe-common' ), '<a href="https://wordpress.org/extend/plugins/debug-bar/" target="_blank">' . esc_html__( 'Debug Bar Plugin', 'tribe-common' ) . '</a>' ) . '</p>',
|
| 60 |
+
);
|
| 61 |
}
|
| 62 |
|
| 63 |
// Closes form
|
| 64 |
+
$generalTabFields['tribe-form-content-end'] = array(
|
| 65 |
'type' => 'html',
|
| 66 |
'html' => '</div>',
|
| 67 |
+
);
|
| 68 |
|
| 69 |
|
| 70 |
+
$generalTab = array(
|
| 71 |
'priority' => 10,
|
| 72 |
'fields' => apply_filters( 'tribe_general_settings_tab_fields', $generalTabFields ),
|
| 73 |
+
);
|
| 74 |
|
common/src/functions/multibyte.php
CHANGED
|
@@ -160,34 +160,3 @@ if ( ! function_exists( 'tribe_uc_first_letter' ) ) {
|
|
| 160 |
return $letter;
|
| 161 |
}
|
| 162 |
}
|
| 163 |
-
|
| 164 |
-
if ( ! function_exists( 'tribe_strpos' ) ) {
|
| 165 |
-
/**
|
| 166 |
-
* Find the numeric position of the first occurrence of needle in the haystack string using multibyte function if available.
|
| 167 |
-
*
|
| 168 |
-
* @since 4.9.19
|
| 169 |
-
*
|
| 170 |
-
* @param string $haystack The string to search in.
|
| 171 |
-
* @param string $needle The string to find in haystack.
|
| 172 |
-
* @param int $offset The search offset. If it is not specified, 0 is used. A negative offset counts from the end of the string.
|
| 173 |
-
*
|
| 174 |
-
* @return int|false The numeric position of the first occurrence of needle in the haystack string. If needle is not found, it returns false.
|
| 175 |
-
*
|
| 176 |
-
* @see strpos The fallback function used if mb_strpos does not exist.
|
| 177 |
-
* @see mb_strpos The multibyte compatible version of strpos.
|
| 178 |
-
*/
|
| 179 |
-
function tribe_strpos( $haystack, $needle, $offset = 0 ) {
|
| 180 |
-
if ( function_exists( 'mb_strpos' ) ) {
|
| 181 |
-
$encoding = tribe_detect_encoding( $haystack );
|
| 182 |
-
|
| 183 |
-
// Use encoding if it was detected.
|
| 184 |
-
if ( $encoding ) {
|
| 185 |
-
return mb_strpos( $haystack, $needle, $offset, $encoding );
|
| 186 |
-
}
|
| 187 |
-
|
| 188 |
-
return mb_strpos( $haystack, $needle, $offset );
|
| 189 |
-
}
|
| 190 |
-
|
| 191 |
-
return strpos( $haystack, $needle, $offset );
|
| 192 |
-
}
|
| 193 |
-
}
|
| 160 |
return $letter;
|
| 161 |
}
|
| 162 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
common/src/functions/template-tags/date.php
CHANGED
|
@@ -277,8 +277,6 @@ if ( ! function_exists( 'tribe_get_start_date' ) ) {
|
|
| 277 |
* @return string|null Date
|
| 278 |
*/
|
| 279 |
function tribe_get_start_date( $event = null, $display_time = true, $date_format = '', $timezone = null ) {
|
| 280 |
-
static $cache_var_name = __FUNCTION__;
|
| 281 |
-
|
| 282 |
if ( is_null( $event ) ) {
|
| 283 |
global $post;
|
| 284 |
$event = $post;
|
|
@@ -292,23 +290,15 @@ if ( ! function_exists( 'tribe_get_start_date' ) ) {
|
|
| 292 |
return '';
|
| 293 |
}
|
| 294 |
|
| 295 |
-
|
| 296 |
-
|
| 297 |
-
|
| 298 |
-
if ( ! isset( $start_dates[ $cache_key ] ) ) {
|
| 299 |
-
if ( Tribe__Date_Utils::is_all_day( get_post_meta( $event->ID, '_EventAllDay', true ) ) ) {
|
| 300 |
-
$display_time = false;
|
| 301 |
-
}
|
| 302 |
-
|
| 303 |
-
// @todo move timezones to Common
|
| 304 |
-
if ( class_exists( 'Tribe__Events__Timezones' ) ) {
|
| 305 |
-
$start_date = Tribe__Events__Timezones::event_start_timestamp( $event->ID, $timezone );
|
| 306 |
-
} else {
|
| 307 |
-
return null;
|
| 308 |
-
}
|
| 309 |
|
| 310 |
-
|
| 311 |
-
|
|
|
|
|
|
|
|
|
|
| 312 |
}
|
| 313 |
|
| 314 |
/**
|
|
@@ -317,7 +307,7 @@ if ( ! function_exists( 'tribe_get_start_date' ) ) {
|
|
| 317 |
* @param string $start_date
|
| 318 |
* @param WP_Post $event
|
| 319 |
*/
|
| 320 |
-
return apply_filters( 'tribe_get_start_date', $
|
| 321 |
}
|
| 322 |
}
|
| 323 |
|
|
@@ -339,8 +329,6 @@ if ( ! function_exists( 'tribe_get_end_date' ) ) {
|
|
| 339 |
* @return string|null Date
|
| 340 |
*/
|
| 341 |
function tribe_get_end_date( $event = null, $display_time = true, $date_format = '', $timezone = null ) {
|
| 342 |
-
static $cache_var_name = __FUNCTION__;
|
| 343 |
-
|
| 344 |
if ( is_null( $event ) ) {
|
| 345 |
global $post;
|
| 346 |
$event = $post;
|
|
@@ -354,23 +342,15 @@ if ( ! function_exists( 'tribe_get_end_date' ) ) {
|
|
| 354 |
return '';
|
| 355 |
}
|
| 356 |
|
| 357 |
-
|
| 358 |
-
|
| 359 |
-
|
| 360 |
-
if ( ! isset( $end_dates[ $cache_key ] ) ) {
|
| 361 |
-
if ( Tribe__Date_Utils::is_all_day( get_post_meta( $event->ID, '_EventAllDay', true ) ) ) {
|
| 362 |
-
$display_time = false;
|
| 363 |
-
}
|
| 364 |
-
|
| 365 |
-
// @todo move timezones to Common
|
| 366 |
-
if ( class_exists( 'Tribe__Events__Timezones' ) ) {
|
| 367 |
-
$end_date = Tribe__Events__Timezones::event_end_timestamp( $event->ID );
|
| 368 |
-
} else {
|
| 369 |
-
return null;
|
| 370 |
-
}
|
| 371 |
|
| 372 |
-
|
| 373 |
-
|
|
|
|
|
|
|
|
|
|
| 374 |
}
|
| 375 |
|
| 376 |
/**
|
|
@@ -379,7 +359,7 @@ if ( ! function_exists( 'tribe_get_end_date' ) ) {
|
|
| 379 |
* @param string $end_date
|
| 380 |
* @param WP_Post $event
|
| 381 |
*/
|
| 382 |
-
return apply_filters( 'tribe_get_end_date', $
|
| 383 |
}
|
| 384 |
}
|
| 385 |
|
| 277 |
* @return string|null Date
|
| 278 |
*/
|
| 279 |
function tribe_get_start_date( $event = null, $display_time = true, $date_format = '', $timezone = null ) {
|
|
|
|
|
|
|
| 280 |
if ( is_null( $event ) ) {
|
| 281 |
global $post;
|
| 282 |
$event = $post;
|
| 290 |
return '';
|
| 291 |
}
|
| 292 |
|
| 293 |
+
if ( Tribe__Date_Utils::is_all_day( get_post_meta( $event->ID, '_EventAllDay', true ) ) ) {
|
| 294 |
+
$display_time = false;
|
| 295 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 296 |
|
| 297 |
+
// @todo move timezones to Common
|
| 298 |
+
if ( class_exists( 'Tribe__Events__Timezones' ) ) {
|
| 299 |
+
$start_date = Tribe__Events__Timezones::event_start_timestamp( $event->ID, $timezone );
|
| 300 |
+
} else {
|
| 301 |
+
return null;
|
| 302 |
}
|
| 303 |
|
| 304 |
/**
|
| 307 |
* @param string $start_date
|
| 308 |
* @param WP_Post $event
|
| 309 |
*/
|
| 310 |
+
return apply_filters( 'tribe_get_start_date', tribe_format_date( $start_date, $display_time, $date_format ), $event );
|
| 311 |
}
|
| 312 |
}
|
| 313 |
|
| 329 |
* @return string|null Date
|
| 330 |
*/
|
| 331 |
function tribe_get_end_date( $event = null, $display_time = true, $date_format = '', $timezone = null ) {
|
|
|
|
|
|
|
| 332 |
if ( is_null( $event ) ) {
|
| 333 |
global $post;
|
| 334 |
$event = $post;
|
| 342 |
return '';
|
| 343 |
}
|
| 344 |
|
| 345 |
+
if ( Tribe__Date_Utils::is_all_day( get_post_meta( $event->ID, '_EventAllDay', true ) ) ) {
|
| 346 |
+
$display_time = false;
|
| 347 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 348 |
|
| 349 |
+
// @todo move timezones to Common
|
| 350 |
+
if ( class_exists( 'Tribe__Events__Timezones' ) ) {
|
| 351 |
+
$end_date = Tribe__Events__Timezones::event_end_timestamp( $event->ID );
|
| 352 |
+
} else {
|
| 353 |
+
return null;
|
| 354 |
}
|
| 355 |
|
| 356 |
/**
|
| 359 |
* @param string $end_date
|
| 360 |
* @param WP_Post $event
|
| 361 |
*/
|
| 362 |
+
return apply_filters( 'tribe_get_end_date', tribe_format_date( $end_date, $display_time, $date_format ), $event );
|
| 363 |
}
|
| 364 |
}
|
| 365 |
|
common/src/functions/template-tags/general.php
CHANGED
|
@@ -215,15 +215,7 @@ if ( ! function_exists( 'tribe_get_time_format' ) ) {
|
|
| 215 |
* @return mixed|void
|
| 216 |
*/
|
| 217 |
function tribe_get_time_format( ) {
|
| 218 |
-
|
| 219 |
-
|
| 220 |
-
$format = tribe_get_var( $cache_var_name, null );
|
| 221 |
-
|
| 222 |
-
if ( ! $format ) {
|
| 223 |
-
$format = get_option( 'time_format' );
|
| 224 |
-
tribe_set_var( $cache_var_name, $format );
|
| 225 |
-
}
|
| 226 |
-
|
| 227 |
return apply_filters( 'tribe_time_format', $format );
|
| 228 |
}
|
| 229 |
}//end if
|
|
@@ -596,49 +588,43 @@ function tribe_register_error( $indexes, $message ) {
|
|
| 596 |
*
|
| 597 |
* @since 4.3
|
| 598 |
*
|
| 599 |
-
* @param
|
| 600 |
-
* @param
|
| 601 |
-
* @param
|
| 602 |
-
* @param
|
| 603 |
-
* @param
|
| 604 |
-
*
|
| 605 |
-
* @param array $arguments See `Tribe__Assets::register()` for more info.
|
| 606 |
*
|
| 607 |
-
* @return
|
| 608 |
*/
|
| 609 |
-
function tribe_asset( $origin, $slug, $file, $deps =
|
| 610 |
-
|
| 611 |
-
$assets = tribe( 'assets' );
|
| 612 |
-
|
| 613 |
-
return $assets->register( $origin, $slug, $file, $deps, $action, $arguments );
|
| 614 |
}
|
| 615 |
|
| 616 |
/**
|
| 617 |
-
* Shortcut for Tribe__Assets::enqueue()
|
|
|
|
|
|
|
| 618 |
*
|
| 619 |
-
* @
|
| 620 |
*
|
| 621 |
-
* @
|
| 622 |
*/
|
| 623 |
function tribe_asset_enqueue( $slug ) {
|
| 624 |
-
|
| 625 |
-
$assets = tribe( 'assets' );
|
| 626 |
-
|
| 627 |
-
$assets->enqueue( $slug );
|
| 628 |
}
|
| 629 |
|
| 630 |
/**
|
| 631 |
-
* Shortcut for Tribe__Assets::enqueue_group() include assets by groups
|
|
|
|
|
|
|
| 632 |
*
|
| 633 |
-
* @
|
| 634 |
*
|
| 635 |
-
* @
|
| 636 |
*/
|
| 637 |
function tribe_asset_enqueue_group( $group ) {
|
| 638 |
-
|
| 639 |
-
$assets = tribe( 'assets' );
|
| 640 |
-
|
| 641 |
-
$assets->enqueue_group( $group );
|
| 642 |
}
|
| 643 |
|
| 644 |
/**
|
|
@@ -765,17 +751,4 @@ if ( ! function_exists( 'tribe_context' ) ) {
|
|
| 765 |
|
| 766 |
return $context;
|
| 767 |
}
|
| 768 |
-
}
|
| 769 |
-
|
| 770 |
-
if ( ! function_exists( 'tribe_cache' ) ) {
|
| 771 |
-
/**
|
| 772 |
-
* Returns the current Tribe Cache instance.
|
| 773 |
-
*
|
| 774 |
-
* @since 4.11.2
|
| 775 |
-
*
|
| 776 |
-
* @return Tribe__Cache The current cache instance.
|
| 777 |
-
*/
|
| 778 |
-
function tribe_cache() {
|
| 779 |
-
return tribe( 'cache' );
|
| 780 |
-
}
|
| 781 |
-
}
|
| 215 |
* @return mixed|void
|
| 216 |
*/
|
| 217 |
function tribe_get_time_format( ) {
|
| 218 |
+
$format = get_option( 'time_format' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 219 |
return apply_filters( 'tribe_time_format', $format );
|
| 220 |
}
|
| 221 |
}//end if
|
| 588 |
*
|
| 589 |
* @since 4.3
|
| 590 |
*
|
| 591 |
+
* @param object $origin The main Object for the plugin you are enqueueing the script/style for
|
| 592 |
+
* @param string $slug Slug to save the asset
|
| 593 |
+
* @param string $file Which file will be loaded, either CSS or JS
|
| 594 |
+
* @param array $deps Dependencies
|
| 595 |
+
* @param string $action A WordPress Action, needs to happen after: `wp_enqueue_scripts`, `admin_enqueue_scripts`, or `login_enqueue_scripts`
|
| 596 |
+
* @param array $arguments Look at `Tribe__Assets::register()` for more info
|
|
|
|
| 597 |
*
|
| 598 |
+
* @return array Which Assets was registered
|
| 599 |
*/
|
| 600 |
+
function tribe_asset( $origin, $slug, $file, $deps = array(), $action = null, $arguments = array() ) {
|
| 601 |
+
return tribe( 'assets' )->register( $origin, $slug, $file, $deps, $action, $arguments );
|
|
|
|
|
|
|
|
|
|
| 602 |
}
|
| 603 |
|
| 604 |
/**
|
| 605 |
+
* Shortcut for Tribe__Assets::enqueue(), include assets
|
| 606 |
+
*
|
| 607 |
+
* @since 4.7
|
| 608 |
*
|
| 609 |
+
* @param string|array $slug Slug to enqueue
|
| 610 |
*
|
| 611 |
+
* @return string
|
| 612 |
*/
|
| 613 |
function tribe_asset_enqueue( $slug ) {
|
| 614 |
+
return tribe( 'assets' )->enqueue( $slug );
|
|
|
|
|
|
|
|
|
|
| 615 |
}
|
| 616 |
|
| 617 |
/**
|
| 618 |
+
* Shortcut for Tribe__Assets::enqueue_group() include assets by groups
|
| 619 |
+
*
|
| 620 |
+
* @since 4.7
|
| 621 |
*
|
| 622 |
+
* @param string|array $group Which group(s) should be enqueued
|
| 623 |
*
|
| 624 |
+
* @return string
|
| 625 |
*/
|
| 626 |
function tribe_asset_enqueue_group( $group ) {
|
| 627 |
+
return tribe( 'assets' )->enqueue_group( $group );
|
|
|
|
|
|
|
|
|
|
| 628 |
}
|
| 629 |
|
| 630 |
/**
|
| 751 |
|
| 752 |
return $context;
|
| 753 |
}
|
| 754 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
common/src/functions/template-tags/html.php
CHANGED
|
@@ -31,71 +31,3 @@ function tribe_classes() {
|
|
| 31 |
$element_classes = new Element_Classes( func_get_args() );
|
| 32 |
echo $element_classes->get_attribute();
|
| 33 |
}
|
| 34 |
-
|
| 35 |
-
/**
|
| 36 |
-
* Get attributes for required fields.
|
| 37 |
-
*
|
| 38 |
-
* @since 4.10.0
|
| 39 |
-
*
|
| 40 |
-
* @param boolean $required If the field is required.
|
| 41 |
-
* @param boolean $echo Whether to echo the string or return it.
|
| 42 |
-
*
|
| 43 |
-
* @return string|void If echo is false, returns $required_string.
|
| 44 |
-
*/
|
| 45 |
-
function tribe_required( $required, $echo = true ) {
|
| 46 |
-
if ( $required ) {
|
| 47 |
-
$required_string = 'required aria-required="true"';
|
| 48 |
-
|
| 49 |
-
if ( ! $echo ) {
|
| 50 |
-
return $required_string;
|
| 51 |
-
} else {
|
| 52 |
-
echo $required_string;
|
| 53 |
-
}
|
| 54 |
-
}
|
| 55 |
-
}
|
| 56 |
-
|
| 57 |
-
/**
|
| 58 |
-
* Get string for required field labels.
|
| 59 |
-
*
|
| 60 |
-
* @since 4.10.0
|
| 61 |
-
*
|
| 62 |
-
* @param boolean $required If the field is required.
|
| 63 |
-
* @param boolean $echo Whether to echo the string or return it.
|
| 64 |
-
*
|
| 65 |
-
* @return string|void If echo is false, returns $required_string.
|
| 66 |
-
*/
|
| 67 |
-
function tribe_required_label( $required, $echo = true ) {
|
| 68 |
-
if ( $required ) {
|
| 69 |
-
$required_string = '<span class="screen-reader-text">'
|
| 70 |
-
. esc_html_x( '(required)', 'The associated field is required.', 'tribe-common' )
|
| 71 |
-
. '</span><span class="tribe-required" aria-hidden="true" role="presentation">*</span>';
|
| 72 |
-
|
| 73 |
-
if ( ! $echo ) {
|
| 74 |
-
return $required_string;
|
| 75 |
-
} else {
|
| 76 |
-
echo $required_string;
|
| 77 |
-
}
|
| 78 |
-
}
|
| 79 |
-
}
|
| 80 |
-
|
| 81 |
-
/**
|
| 82 |
-
* Get attributes for disabled fields.
|
| 83 |
-
*
|
| 84 |
-
* @since 4.10.0
|
| 85 |
-
*
|
| 86 |
-
* @param boolean $disabled If the field is disabled.
|
| 87 |
-
* @param boolean $echo Whether to echo the string or return it.
|
| 88 |
-
*
|
| 89 |
-
* @return string|void If echo is false, returns $disabled_string.
|
| 90 |
-
*/
|
| 91 |
-
function tribe_disabled( $disabled, $echo = true ) {
|
| 92 |
-
if ( $disabled ) {
|
| 93 |
-
$disabled_string = 'disabled aria-disabled="true"';
|
| 94 |
-
|
| 95 |
-
if ( ! $echo ) {
|
| 96 |
-
return $disabled_string;
|
| 97 |
-
} else {
|
| 98 |
-
echo $disabled_string;
|
| 99 |
-
}
|
| 100 |
-
}
|
| 101 |
-
}
|
| 31 |
$element_classes = new Element_Classes( func_get_args() );
|
| 32 |
echo $element_classes->get_attribute();
|
| 33 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
common/src/functions/template-tags/post.php
DELETED
|
@@ -1,97 +0,0 @@
|
|
| 1 |
-
<?php
|
| 2 |
-
|
| 3 |
-
/**
|
| 4 |
-
* Gets the post content. Basically a wrapper around `get_the_content` that will prevent warnings on PHP 7.3
|
| 5 |
-
* and be compatible with WP 5.3
|
| 6 |
-
*
|
| 7 |
-
* @since 4.9.23
|
| 8 |
-
*
|
| 9 |
-
* @global WP_Post $post Current post on the loop
|
| 10 |
-
* @global string $wp_version Which version of WordPress we are currently dealing with
|
| 11 |
-
*
|
| 12 |
-
* @param string $more_link_text Optional. Content for when there is more text.
|
| 13 |
-
* @param bool $strip_teaser Optional. Strip teaser content before the more text. Default is false.
|
| 14 |
-
* @param WP_Post|object|int $post_id Optional. WP_Post instance or Post ID/object. Default is null.
|
| 15 |
-
*
|
| 16 |
-
* @return string
|
| 17 |
-
*/
|
| 18 |
-
function tribe_get_the_content( $more_link_text = null, $strip_teaser = false, $post_id = null ) {
|
| 19 |
-
global $post, $wp_version;
|
| 20 |
-
|
| 21 |
-
// Save the global post to be able to restore it later.
|
| 22 |
-
$previous_post = $post;
|
| 23 |
-
|
| 24 |
-
$post = get_post( $post_id );
|
| 25 |
-
|
| 26 |
-
// Pass in the third param when dealing with WP version 5.2 or higher.
|
| 27 |
-
if ( version_compare( $wp_version, '5.2', '>=' ) ) {
|
| 28 |
-
$content = get_the_content( $more_link_text, $strip_teaser, $post );
|
| 29 |
-
} else {
|
| 30 |
-
$content = get_the_content( $more_link_text, $strip_teaser );
|
| 31 |
-
}
|
| 32 |
-
|
| 33 |
-
if ( ! doing_filter( 'the_content' ) ) {
|
| 34 |
-
/**
|
| 35 |
-
* Filters the post content.
|
| 36 |
-
*
|
| 37 |
-
* @since 0.71 of WordPress
|
| 38 |
-
*
|
| 39 |
-
* @param string $content Content of the current post.
|
| 40 |
-
*/
|
| 41 |
-
$content = apply_filters( 'the_content', $content );
|
| 42 |
-
}
|
| 43 |
-
|
| 44 |
-
$content = str_replace( ']]>', ']]>', $content );
|
| 45 |
-
|
| 46 |
-
$post = $previous_post;
|
| 47 |
-
|
| 48 |
-
return $content;
|
| 49 |
-
}
|
| 50 |
-
|
| 51 |
-
/**
|
| 52 |
-
* Prints the post content.
|
| 53 |
-
*
|
| 54 |
-
* @since 4.9.23
|
| 55 |
-
*
|
| 56 |
-
* @global WP_Post $post Current post on the loop
|
| 57 |
-
* @global string $wp_version Which version of WordPress we are currently dealing with
|
| 58 |
-
*
|
| 59 |
-
* @param string $more_link_text Optional. Content for when there is more text.
|
| 60 |
-
* @param bool $strip_teaser Optional. Strip teaser content before the more text. Default is false.
|
| 61 |
-
* @param WP_Post|object|int $post_id Optional. WP_Post instance or Post ID/object. Default is null.
|
| 62 |
-
*
|
| 63 |
-
* @return void
|
| 64 |
-
*/
|
| 65 |
-
function tribe_the_content( $more_link_text = null, $strip_teaser = false, $post_id = null ) {
|
| 66 |
-
echo tribe_get_the_content( $more_link_text, $strip_teaser, $post_id );
|
| 67 |
-
}
|
| 68 |
-
|
| 69 |
-
/**
|
| 70 |
-
* Wrapper for post_class function that allows us to in-memory cache
|
| 71 |
-
*
|
| 72 |
-
* @since 4.11.0
|
| 73 |
-
*
|
| 74 |
-
* @param string|string[] $class Space-separated string or array of class names to add to the class list.
|
| 75 |
-
* @param int|WP_Post $post Optional. Post ID or post object.
|
| 76 |
-
*
|
| 77 |
-
* @return string[] Array of class names.
|
| 78 |
-
*/
|
| 79 |
-
function tribe_get_post_class( $class, $post ) {
|
| 80 |
-
static $post_classes = [];
|
| 81 |
-
|
| 82 |
-
if ( is_numeric( $post ) ) {
|
| 83 |
-
$post_id = $post;
|
| 84 |
-
} else {
|
| 85 |
-
$post_id = $post->ID;
|
| 86 |
-
}
|
| 87 |
-
|
| 88 |
-
if ( ! isset( $post_classes[ $post_id ] ) ) {
|
| 89 |
-
$post_classes[ $post_id ] = get_post_class( [], $post );
|
| 90 |
-
}
|
| 91 |
-
|
| 92 |
-
if ( ! is_array( $class ) ) {
|
| 93 |
-
$class = explode( ' ', $class );
|
| 94 |
-
}
|
| 95 |
-
|
| 96 |
-
return array_merge( $class, $post_classes[ $post_id ] );
|
| 97 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
common/src/functions/utils.php
CHANGED
|
@@ -36,10 +36,14 @@ if ( ! function_exists( 'tribe_register_plugin' ) ) {
|
|
| 36 |
* @param string $version The version
|
| 37 |
* @param array $classes_req Any Main class files/tribe plugins required for this to run
|
| 38 |
* @param array $dependencies an array of dependencies to check
|
|
|
|
|
|
|
| 39 |
*/
|
| 40 |
-
function tribe_register_plugin( $file_path, $main_class, $version, $classes_req =
|
| 41 |
-
|
|
|
|
| 42 |
$tribe_dependency->register_plugin( $file_path, $main_class, $version, $classes_req, $dependencies );
|
|
|
|
| 43 |
}
|
| 44 |
}
|
| 45 |
|
|
@@ -49,14 +53,13 @@ if ( ! function_exists( 'tribe_check_plugin' ) ) {
|
|
| 49 |
*
|
| 50 |
* @since 4.9
|
| 51 |
*
|
| 52 |
-
* @param string $main_class
|
| 53 |
*
|
| 54 |
* @return bool Indicates if plugin should continue initialization
|
| 55 |
*/
|
| 56 |
function tribe_check_plugin( $main_class ) {
|
| 57 |
|
| 58 |
-
$tribe_dependency
|
| 59 |
-
|
| 60 |
return $tribe_dependency->check_plugin( $main_class );
|
| 61 |
|
| 62 |
}
|
|
@@ -67,13 +70,12 @@ if ( ! function_exists( 'tribe_append_path' ) ) {
|
|
| 67 |
* Append a path fragment to a URL preserving query arguments
|
| 68 |
* and fragments.
|
| 69 |
*
|
| 70 |
-
* @
|
| 71 |
-
*
|
| 72 |
* @param string $path The path to append to the existing, if any, one., e.g. `/some/path`
|
| 73 |
*
|
| 74 |
-
* @param string $url A full URL in the `http://example.com/?query=var#frag` format.
|
| 75 |
-
*
|
| 76 |
* @return mixed|string
|
|
|
|
|
|
|
| 77 |
*/
|
| 78 |
function tribe_append_path( $url, $path ) {
|
| 79 |
$path = trim( $path, '/' );
|
|
@@ -134,9 +136,7 @@ if ( ! function_exists( 'tribe_get_request_var' ) ) {
|
|
| 134 |
*
|
| 135 |
* The variable being tested for can be an array if you wish to find a nested value.
|
| 136 |
*
|
| 137 |
-
* @
|
| 138 |
-
*
|
| 139 |
-
* @see Tribe__Utils__Array::get()
|
| 140 |
*
|
| 141 |
* @param string|array $var
|
| 142 |
* @param mixed $default
|
|
@@ -144,8 +144,7 @@ if ( ! function_exists( 'tribe_get_request_var' ) ) {
|
|
| 144 |
* @return mixed
|
| 145 |
*/
|
| 146 |
function tribe_get_request_var( $var, $default = null ) {
|
| 147 |
-
|
| 148 |
-
return tribe_sanitize_deep( $unsafe );
|
| 149 |
}
|
| 150 |
}
|
| 151 |
|
|
@@ -156,7 +155,7 @@ if ( ! function_exists( 'tribe_get_global_query_object' ) ) {
|
|
| 156 |
*
|
| 157 |
* @since 4.7.8
|
| 158 |
*
|
| 159 |
-
* @return
|
| 160 |
*/
|
| 161 |
function tribe_get_global_query_object() {
|
| 162 |
global $wp_query;
|
|
@@ -193,7 +192,7 @@ if ( ! function_exists( 'tribe_is_truthy' ) ) {
|
|
| 193 |
*
|
| 194 |
* @param array $truthy_strings
|
| 195 |
*/
|
| 196 |
-
$truthy_strings = (array) apply_filters( 'tribe_is_truthy_strings',
|
| 197 |
'1',
|
| 198 |
'enable',
|
| 199 |
'enabled',
|
|
@@ -201,7 +200,7 @@ if ( ! function_exists( 'tribe_is_truthy' ) ) {
|
|
| 201 |
'y',
|
| 202 |
'yes',
|
| 203 |
'true',
|
| 204 |
-
|
| 205 |
// Makes sure we are dealing with lowercase for testing
|
| 206 |
if ( is_string( $var ) ) {
|
| 207 |
$var = strtolower( $var );
|
|
@@ -226,13 +225,12 @@ if ( ! function_exists( 'tribe_sort_by_priority' ) ) {
|
|
| 226 |
/**
|
| 227 |
* Sorting function based on Priority
|
| 228 |
*
|
| 229 |
-
* @since 4.7.20
|
| 230 |
-
*
|
| 231 |
-
* @param object|array $b Second subject to compare
|
| 232 |
-
*
|
| 233 |
* @param object|array $a First Subject to compare
|
|
|
|
| 234 |
*
|
| 235 |
* @return int
|
|
|
|
|
|
|
| 236 |
*/
|
| 237 |
function tribe_sort_by_priority( $a, $b ) {
|
| 238 |
if ( is_array( $a ) ) {
|
|
@@ -255,20 +253,20 @@ if ( ! function_exists( 'tribe_normalize_terms_list' ) ) {
|
|
| 255 |
/**
|
| 256 |
* Normalizes a list of terms to a list of fields.
|
| 257 |
*
|
| 258 |
-
* @
|
| 259 |
-
*
|
| 260 |
* @param string $taxonomy The terms taxonomy.
|
| 261 |
-
* @param string $field
|
| 262 |
-
*
|
|
|
|
| 263 |
*
|
| 264 |
* @return array An array of the valid normalized terms.
|
| 265 |
*/
|
| 266 |
function tribe_normalize_terms_list( $terms, $taxonomy, $field = 'term_id' ) {
|
| 267 |
if ( ! is_array( $terms ) ) {
|
| 268 |
-
$terms =
|
| 269 |
}
|
| 270 |
|
| 271 |
-
$normalized =
|
| 272 |
foreach ( $terms as $term ) {
|
| 273 |
if ( is_object( $term ) && ! empty( $term->{$field} ) ) {
|
| 274 |
$normalized[] = $term->{$field};
|
|
@@ -291,13 +289,12 @@ if ( ! function_exists( 'tribe_normalize_terms_list' ) ) {
|
|
| 291 |
}
|
| 292 |
|
| 293 |
if ( ! function_exists( 'tribe_upload_image' ) ) {
|
| 294 |
-
/**
|
| 295 |
-
* @see Tribe__Image__Uploader::upload_and_get_attachment_id()
|
| 296 |
-
*
|
| 297 |
-
* @param string|int $image The path to an image file, an image URL or an attachment post ID.
|
| 298 |
*
|
| 299 |
* @return int|bool The attachment post ID if the uploading and attachment is successful or the ID refers to an attachment;
|
| 300 |
* `false` otherwise.
|
|
|
|
|
|
|
| 301 |
*/
|
| 302 |
function tribe_upload_image( $image ) {
|
| 303 |
$uploader = new Tribe__Image__Uploader( $image );
|
|
@@ -334,9 +331,9 @@ if ( ! function_exists( 'tribe_retrieve_object_by_hook' ) ) {
|
|
| 334 |
*
|
| 335 |
* @since 4.5.8
|
| 336 |
*
|
| 337 |
-
* @param string
|
| 338 |
-
* @param string
|
| 339 |
-
* @param int
|
| 340 |
*
|
| 341 |
* @return object|false
|
| 342 |
*/
|
|
@@ -409,7 +406,7 @@ if ( ! function_exists( 'tribe_post_exists' ) ) {
|
|
| 409 |
global $wpdb;
|
| 410 |
|
| 411 |
$query_template = "SELECT ID FROM {$wpdb->posts} WHERE %s";
|
| 412 |
-
$query_vars =
|
| 413 |
$where = '';
|
| 414 |
|
| 415 |
if ( is_numeric( $post_id_or_name ) ) {
|
|
@@ -498,9 +495,10 @@ if ( ! function_exists( 'tribe_catch_and_throw' ) ) {
|
|
| 498 |
*
|
| 499 |
* @since 4.9.5
|
| 500 |
*
|
|
|
|
|
|
|
| 501 |
* @see set_error_handler()
|
| 502 |
* @see restore_error_handler()
|
| 503 |
-
* @throws RuntimeException The message will be the error message, the code will be the error code.
|
| 504 |
*/
|
| 505 |
function tribe_catch_and_throw( $errno, $errstr ) {
|
| 506 |
throw new RuntimeException( $errstr, $errno );
|
|
@@ -551,15 +549,15 @@ if ( ! function_exists( 'tribe_unfenced_regex' ) ) {
|
|
| 551 |
return $regex;
|
| 552 |
}
|
| 553 |
|
| 554 |
-
$str_fence
|
| 555 |
// Let's pick a fence char the string itself is not using.
|
| 556 |
$fence_char = '~' === $str_fence ? '#' : '~';
|
| 557 |
-
$pattern
|
| 558 |
-
|
| 559 |
-
|
| 560 |
-
|
| 561 |
-
|
| 562 |
-
|
| 563 |
|
| 564 |
return preg_replace( $pattern, '$1', $regex );
|
| 565 |
}
|
|
@@ -579,11 +577,9 @@ if ( ! function_exists( 'has_blocks' ) ) {
|
|
| 579 |
* you should use the block parser on post content.
|
| 580 |
*
|
| 581 |
* @since 4.8
|
| 582 |
-
*
|
| 583 |
-
* @see https://github.com/WordPress/gutenberg/blob/73d9759116dde896931f4d152f186147a57889fe/lib/register.php#L313-L337s
|
| 584 |
*
|
| 585 |
* @param int|string|WP_Post|null $post Optional. Post content, post ID, or post object. Defaults to global $post.
|
| 586 |
-
*
|
| 587 |
* @return bool Whether the post has blocks.
|
| 588 |
*/
|
| 589 |
function has_blocks( $post = null ) {
|
|
@@ -593,7 +589,6 @@ if ( ! function_exists( 'has_blocks' ) ) {
|
|
| 593 |
$post = $wp_post->post_content;
|
| 594 |
}
|
| 595 |
}
|
| 596 |
-
|
| 597 |
return false !== strpos( (string) $post, '<!-- wp:' );
|
| 598 |
}
|
| 599 |
}
|
|
@@ -602,456 +597,45 @@ if ( ! function_exists( 'tribe_register_rest_route' ) ) {
|
|
| 602 |
/**
|
| 603 |
* Wrapper function for `register_rest_route` to allow for filtering any Tribe REST API endpoint.
|
| 604 |
*
|
| 605 |
-
* @
|
| 606 |
-
*
|
| 607 |
* @param string $route The base URL for route you are adding.
|
| 608 |
* @param array $args Optional. Either an array of options for the endpoint, or an array of arrays for
|
| 609 |
* multiple methods. Default empty array.
|
| 610 |
* @param bool $override Optional. If the route already exists, should we override it? True overrides,
|
| 611 |
* false merges (with newer overriding if duplicate keys exist). Default false.
|
| 612 |
*
|
| 613 |
-
* @param string $namespace The first URL segment after core prefix. Should be unique to your package/plugin.
|
| 614 |
-
*
|
| 615 |
* @return bool True on success, false on error.
|
|
|
|
|
|
|
| 616 |
*/
|
| 617 |
-
function tribe_register_rest_route( $namespace, $route, $args =
|
| 618 |
/**
|
| 619 |
* Allow plugins to customize REST API arguments and callbacks.
|
| 620 |
*
|
| 621 |
-
* @
|
| 622 |
-
*
|
| 623 |
* @param string $namespace The first URL segment after core prefix. Should be unique to your package/plugin.
|
| 624 |
* @param string $route The base URL for route you are adding.
|
| 625 |
* @param bool $override Optional. If the route already exists, should we override it? True overrides,
|
| 626 |
* false merges (with newer overriding if duplicate keys exist). Default false.
|
| 627 |
*
|
| 628 |
-
* @
|
| 629 |
-
* multiple methods. Default empty array.
|
| 630 |
*/
|
| 631 |
$args = apply_filters( 'tribe_register_rest_route_args_' . $namespace . $route, $args, $namespace, $route, $override );
|
| 632 |
|
| 633 |
/**
|
| 634 |
* Allow plugins to customize REST API arguments and callbacks.
|
| 635 |
*
|
| 636 |
-
* @
|
| 637 |
-
*
|
| 638 |
* @param string $namespace The first URL segment after core prefix. Should be unique to your package/plugin.
|
| 639 |
* @param string $route The base URL for route you are adding.
|
| 640 |
* @param bool $override Optional. If the route already exists, should we override it? True overrides,
|
| 641 |
* false merges (with newer overriding if duplicate keys exist). Default false.
|
| 642 |
*
|
| 643 |
-
* @
|
| 644 |
-
* multiple methods. Default empty array.
|
| 645 |
*/
|
| 646 |
$args = apply_filters( 'tribe_register_rest_route_args', $args, $namespace, $route, $override );
|
| 647 |
-
|
| 648 |
return register_rest_route( $namespace, $route, $args, $override );
|
| 649 |
}
|
| 650 |
-
}
|
| 651 |
-
|
| 652 |
-
if ( ! function_exists( 'tribe_get_class_instance' ) ) {
|
| 653 |
-
/**
|
| 654 |
-
* Gets the class instance / Tribe Container from the passed object or string.
|
| 655 |
-
*
|
| 656 |
-
* @since 4.10.0
|
| 657 |
-
*
|
| 658 |
-
* @see \tad_DI52_Container::isBound()
|
| 659 |
-
* @see \tribe()
|
| 660 |
-
*
|
| 661 |
-
* @param string|object $class The plugin class' singleton name, class name, or instance.
|
| 662 |
-
*
|
| 663 |
-
* @return mixed|object|Tribe__Container|null Null if not found, else the result from tribe().
|
| 664 |
-
*/
|
| 665 |
-
function tribe_get_class_instance( $class ) {
|
| 666 |
-
if ( is_object( $class ) ) {
|
| 667 |
-
return $class;
|
| 668 |
-
}
|
| 669 |
-
|
| 670 |
-
if ( ! is_string( $class ) ) {
|
| 671 |
-
return null;
|
| 672 |
-
}
|
| 673 |
-
|
| 674 |
-
// Check if class exists and has instance getter method.
|
| 675 |
-
if ( class_exists( $class ) ) {
|
| 676 |
-
if ( method_exists( $class, 'instance' ) ) {
|
| 677 |
-
return $class::instance();
|
| 678 |
-
}
|
| 679 |
-
|
| 680 |
-
if ( method_exists( $class, 'get_instance' ) ) {
|
| 681 |
-
return $class::get_instance();
|
| 682 |
-
}
|
| 683 |
-
}
|
| 684 |
-
|
| 685 |
-
try {
|
| 686 |
-
return tribe( $class );
|
| 687 |
-
} catch ( \RuntimeException $exception ) {
|
| 688 |
-
return null;
|
| 689 |
-
}
|
| 690 |
-
}
|
| 691 |
-
}
|
| 692 |
-
|
| 693 |
-
if ( ! function_exists( 'tribe_get_least_version_ever_installed' ) ) {
|
| 694 |
-
/**
|
| 695 |
-
* Gets the lowest version number ever installed for the specified class of a plugin having a
|
| 696 |
-
* `version_history_slug` property or a `VERSION` constant (i.e. Main classes).
|
| 697 |
-
*
|
| 698 |
-
* If user initially installed v2, downgraded to v1, then updated to v3, this will return v1.
|
| 699 |
-
* If no historical version records, fallback is the class' current version.
|
| 700 |
-
* If no version info found, it will return false.
|
| 701 |
-
* Zero may have been logged as a past version but gets ignored.
|
| 702 |
-
*
|
| 703 |
-
* @since 4.10.0
|
| 704 |
-
*
|
| 705 |
-
* @param string|object $class The plugin class' singleton name, class name, or instance.
|
| 706 |
-
*
|
| 707 |
-
* @return string|boolean The SemVer version string or false if no info found.
|
| 708 |
-
*/
|
| 709 |
-
function tribe_get_least_version_ever_installed( $class ) {
|
| 710 |
-
$instance = tribe_get_class_instance( $class );
|
| 711 |
-
|
| 712 |
-
if ( $instance ) {
|
| 713 |
-
// Try for the version history first.
|
| 714 |
-
if ( ! empty( $instance->version_history_slug ) ) {
|
| 715 |
-
$history = (array) Tribe__Settings_Manager::get_option( $instance->version_history_slug );
|
| 716 |
-
|
| 717 |
-
// '0' may be logged as a version number, which isn't useful, so we remove it
|
| 718 |
-
$history = array_filter( $history );
|
| 719 |
-
$history = array_unique( $history );
|
| 720 |
-
|
| 721 |
-
if ( ! empty( $history ) ) {
|
| 722 |
-
// Sort the array so smallest version number is first (likely how the array is stored anyway)
|
| 723 |
-
usort( $history, 'version_compare' );
|
| 724 |
-
|
| 725 |
-
return array_shift( $history );
|
| 726 |
-
}
|
| 727 |
-
}
|
| 728 |
-
|
| 729 |
-
// Fall back to the current plugin version.
|
| 730 |
-
if ( defined( get_class( $instance ) . '::VERSION' ) ) {
|
| 731 |
-
return $instance::VERSION;
|
| 732 |
-
}
|
| 733 |
-
}
|
| 734 |
-
|
| 735 |
-
// No version set.
|
| 736 |
-
return false;
|
| 737 |
-
}
|
| 738 |
-
}
|
| 739 |
-
|
| 740 |
-
if ( ! function_exists( 'tribe_get_greatest_version_ever_installed' ) ) {
|
| 741 |
-
/**
|
| 742 |
-
* Gets the highest version number ever installed for the specified class of a plugin having a
|
| 743 |
-
* `version_history_slug` property or a `VERSION` constant (i.e. Main classes).
|
| 744 |
-
*
|
| 745 |
-
* If user initially installed v2, updated to v3, then downgraded to v2, this will return v3.
|
| 746 |
-
* If no historical version records, fallback is the class' current version.
|
| 747 |
-
* If no version info found, it will return false.
|
| 748 |
-
* Zero may have been logged as a past version but gets ignored.
|
| 749 |
-
*
|
| 750 |
-
* @since 4.10.0
|
| 751 |
-
*
|
| 752 |
-
* @see \tribe_get_currently_installed_version() To get the current version, even if it's not the greatest.
|
| 753 |
-
*
|
| 754 |
-
* @param string|object $class The plugin class' singleton name, class name, or instance.
|
| 755 |
-
*
|
| 756 |
-
* @return string|boolean The SemVer version string or false if no info found.
|
| 757 |
-
*/
|
| 758 |
-
function tribe_get_greatest_version_ever_installed( $class ) {
|
| 759 |
-
$instance = tribe_get_class_instance( $class );
|
| 760 |
-
|
| 761 |
-
if ( $instance ) {
|
| 762 |
-
// Try for the version history first.
|
| 763 |
-
if ( ! empty( $instance->version_history_slug ) ) {
|
| 764 |
-
$history = (array) Tribe__Settings_Manager::get_option( $instance->version_history_slug );
|
| 765 |
-
|
| 766 |
-
// '0' may be logged as a version number, which isn't useful, so we remove it
|
| 767 |
-
$history = array_filter( $history );
|
| 768 |
-
$history = array_unique( $history );
|
| 769 |
-
|
| 770 |
-
if ( ! empty( $history ) ) {
|
| 771 |
-
// Sort the array so smallest version number is first (likely how the array is stored anyway)
|
| 772 |
-
usort( $history, 'version_compare' );
|
| 773 |
-
|
| 774 |
-
return array_pop( $history );
|
| 775 |
-
}
|
| 776 |
-
}
|
| 777 |
-
|
| 778 |
-
// Fall back to the current plugin version.
|
| 779 |
-
if ( defined( get_class( $instance ) . '::VERSION' ) ) {
|
| 780 |
-
return $instance::VERSION;
|
| 781 |
-
}
|
| 782 |
-
}
|
| 783 |
-
|
| 784 |
-
// No version set.
|
| 785 |
-
return false;
|
| 786 |
-
}
|
| 787 |
-
}
|
| 788 |
-
|
| 789 |
-
if ( ! function_exists( 'tribe_get_first_ever_installed_version' ) ) {
|
| 790 |
-
/**
|
| 791 |
-
* Gets the initially-recorded version number installed for the specified class of a plugin having a
|
| 792 |
-
* `version_history_slug` property or a `VERSION` constant (i.e. Main classes).
|
| 793 |
-
*
|
| 794 |
-
* If user initially installed v2, downgraded to v1, then updated to v3, this will return v2.
|
| 795 |
-
* If no historical version records, fallback is the class' current version.
|
| 796 |
-
* If no version info found, it will return false.
|
| 797 |
-
* Zero may have been logged as a past version but gets ignored.
|
| 798 |
-
*
|
| 799 |
-
* @since 4.10.0
|
| 800 |
-
*
|
| 801 |
-
* @param string|object $class The plugin class' singleton name, class name, or instance.
|
| 802 |
-
*
|
| 803 |
-
* @return string|boolean The SemVer version string or false if no info found.
|
| 804 |
-
*/
|
| 805 |
-
function tribe_get_first_ever_installed_version( $class ) {
|
| 806 |
-
$instance = tribe_get_class_instance( $class );
|
| 807 |
-
|
| 808 |
-
if ( $instance ) {
|
| 809 |
-
// Try for the version history first.
|
| 810 |
-
if ( ! empty( $instance->version_history_slug ) ) {
|
| 811 |
-
$history = (array) Tribe__Settings_Manager::get_option( $instance->version_history_slug );
|
| 812 |
-
|
| 813 |
-
// '0' may be logged as a version number, which isn't useful, so we remove it
|
| 814 |
-
while (
|
| 815 |
-
! empty( $history )
|
| 816 |
-
&& empty( $history[0] )
|
| 817 |
-
) {
|
| 818 |
-
array_shift( $history );
|
| 819 |
-
}
|
| 820 |
-
|
| 821 |
-
// Found it so return it
|
| 822 |
-
if ( ! empty( $history[0] ) ) {
|
| 823 |
-
return $history[0];
|
| 824 |
-
}
|
| 825 |
-
}
|
| 826 |
-
|
| 827 |
-
// Fall back to the current plugin version.
|
| 828 |
-
if ( defined( get_class( $instance ) . '::VERSION' ) ) {
|
| 829 |
-
return $instance::VERSION;
|
| 830 |
-
}
|
| 831 |
-
}
|
| 832 |
-
|
| 833 |
-
// No version set.
|
| 834 |
-
return false;
|
| 835 |
-
}
|
| 836 |
-
}
|
| 837 |
-
|
| 838 |
-
if ( ! function_exists( 'tribe_get_currently_installed_version' ) ) {
|
| 839 |
-
/**
|
| 840 |
-
* Gets the current version number installed for the specified class of a plugin having a
|
| 841 |
-
* `VERSION` constant (i.e. Main classes)--different logic than related functions.
|
| 842 |
-
*
|
| 843 |
-
* If user initially installed v2, downgraded to v1, then updated to v3, this will return v3.
|
| 844 |
-
* Only looks at the class' current version, else false.
|
| 845 |
-
*
|
| 846 |
-
* @since 4.10.0
|
| 847 |
-
*
|
| 848 |
-
* @see \tribe_get_greatest_version_ever_installed() To get the greatest ever installed, even if not the current.
|
| 849 |
-
*
|
| 850 |
-
* @param string|object $class The plugin class' singleton name, class name, or instance.
|
| 851 |
-
*
|
| 852 |
-
* @return string|boolean The SemVer version string or false if no info found.
|
| 853 |
-
*/
|
| 854 |
-
function tribe_get_currently_installed_version( $class ) {
|
| 855 |
-
$instance = tribe_get_class_instance( $class );
|
| 856 |
-
|
| 857 |
-
if ( $instance ) {
|
| 858 |
-
// First try for class constant (different logic from the other similar functions).
|
| 859 |
-
if ( defined( get_class( $instance ) . '::VERSION' ) ) {
|
| 860 |
-
return $instance::VERSION;
|
| 861 |
-
}
|
| 862 |
-
}
|
| 863 |
-
|
| 864 |
-
// No version set.
|
| 865 |
-
return false;
|
| 866 |
-
}
|
| 867 |
-
}
|
| 868 |
-
|
| 869 |
-
if ( ! function_exists( 'tribe_installed_before' ) ) {
|
| 870 |
-
/**
|
| 871 |
-
* Checks if a plugin's initially-installed version was prior to the passed version.
|
| 872 |
-
* If no info found, it will assume the plugin is old and return true.
|
| 873 |
-
*
|
| 874 |
-
* @since 4.10.0
|
| 875 |
-
*
|
| 876 |
-
* @param string|object $class The plugin class' singleton name, class name, or instance.
|
| 877 |
-
* @param string $version The SemVer version string to compare.
|
| 878 |
-
*
|
| 879 |
-
* @return boolean Whether the plugin was installed prior to the passed version.
|
| 880 |
-
*/
|
| 881 |
-
function tribe_installed_before( $class, $version ) {
|
| 882 |
-
$install_version = tribe_get_first_ever_installed_version( $class );
|
| 883 |
-
|
| 884 |
-
// If no install version, let's assume it's been here a while.
|
| 885 |
-
if ( empty( $install_version ) ) {
|
| 886 |
-
return true;
|
| 887 |
-
}
|
| 888 |
-
|
| 889 |
-
return 0 > version_compare( $install_version, $version );
|
| 890 |
-
}
|
| 891 |
-
}
|
| 892 |
-
|
| 893 |
-
if ( ! function_exists( 'tribe_installed_after' ) ) {
|
| 894 |
-
/**
|
| 895 |
-
* Checks if a plugin's initially-installed version was after the passed version.
|
| 896 |
-
* If no info found, it will assume the plugin is old and return false.
|
| 897 |
-
*
|
| 898 |
-
* @since 4.10.0
|
| 899 |
-
*
|
| 900 |
-
* @param string|object $class The plugin class' singleton name, class name, or instance.
|
| 901 |
-
* @param string $version The SemVer version string to compare.
|
| 902 |
-
*
|
| 903 |
-
* @return boolean Whether the plugin was installed after the passed version.
|
| 904 |
-
*/
|
| 905 |
-
function tribe_installed_after( $class, $version ) {
|
| 906 |
-
$install_version = tribe_get_first_ever_installed_version( $class );
|
| 907 |
-
|
| 908 |
-
// If no install version, let's assume it's been here a while.
|
| 909 |
-
if ( empty( $install_version ) ) {
|
| 910 |
-
return false;
|
| 911 |
-
}
|
| 912 |
-
|
| 913 |
-
return 0 < version_compare( $install_version, $version );
|
| 914 |
-
}
|
| 915 |
-
}
|
| 916 |
-
|
| 917 |
-
if ( ! function_exists( 'tribe_installed_on' ) ) {
|
| 918 |
-
/**
|
| 919 |
-
* Checks if a plugin was installed at/on the passed version.
|
| 920 |
-
* If no info found, it will assume the plugin is old and return false.
|
| 921 |
-
*
|
| 922 |
-
* @since 4.10.0
|
| 923 |
-
*
|
| 924 |
-
* @param string|object $class The plugin class' singleton name, class name, or instance.
|
| 925 |
-
* @param string $version The SemVer version string to compare.
|
| 926 |
-
*
|
| 927 |
-
* @return boolean Whether the plugin was installed at/on the passed version.
|
| 928 |
-
*/
|
| 929 |
-
function tribe_installed_on( $class, $version ) {
|
| 930 |
-
$install_version = tribe_get_first_ever_installed_version( $class );
|
| 931 |
-
|
| 932 |
-
// If no install version, let's assume it's been here a while.
|
| 933 |
-
if ( empty( $install_version ) ) {
|
| 934 |
-
return false;
|
| 935 |
-
}
|
| 936 |
-
|
| 937 |
-
return 0 === version_compare( $install_version, $version );
|
| 938 |
-
}
|
| 939 |
-
}
|
| 940 |
-
|
| 941 |
-
if ( ! function_exists( 'tribe_get_request_vars' ) ) {
|
| 942 |
-
/**
|
| 943 |
-
* Returns the sanitized version of the `$_REQUEST` super-global array.
|
| 944 |
-
*
|
| 945 |
-
* Note: the return value is cached. It will be resolve the first time the function is called, per HTTP request,
|
| 946 |
-
* then the same return value will be returned. After the function has been called the first time, changes to the
|
| 947 |
-
* `$_REQUEST` super-global will NOT be reflected in the function return value.
|
| 948 |
-
* Call the function with `$refresh` set to `true` to refresh the function value.
|
| 949 |
-
*
|
| 950 |
-
* @since 4.9.18
|
| 951 |
-
*
|
| 952 |
-
* @param bool $refresh Whether to parse the `$_REQUEST` cache again and refresh the cache or not; defaults to
|
| 953 |
-
* `false`.
|
| 954 |
-
*
|
| 955 |
-
* @return array The sanitized version of the `$_REQUEST` super-global.
|
| 956 |
-
*/
|
| 957 |
-
function tribe_get_request_vars( $refresh = false ) {
|
| 958 |
-
static $cache;
|
| 959 |
-
|
| 960 |
-
if ( ! isset( $_REQUEST ) ) {
|
| 961 |
-
return [];
|
| 962 |
-
}
|
| 963 |
-
|
| 964 |
-
if ( null !== $cache && ! $refresh ) {
|
| 965 |
-
return $cache;
|
| 966 |
-
}
|
| 967 |
-
|
| 968 |
-
$cache = array_combine(
|
| 969 |
-
array_keys( $_REQUEST ),
|
| 970 |
-
array_map( static function ( $v )
|
| 971 |
-
{
|
| 972 |
-
return filter_var( $v, FILTER_SANITIZE_STRING );
|
| 973 |
-
},
|
| 974 |
-
$_REQUEST )
|
| 975 |
-
);
|
| 976 |
-
|
| 977 |
-
return $cache;
|
| 978 |
-
}
|
| 979 |
-
}
|
| 980 |
-
|
| 981 |
-
if ( ! function_exists( 'tribe_sanitize_deep' ) ) {
|
| 982 |
-
|
| 983 |
-
/**
|
| 984 |
-
* Sanitizes a value according to its type.
|
| 985 |
-
*
|
| 986 |
-
* The function will recursively sanitize array values.
|
| 987 |
-
*
|
| 988 |
-
* @since 4.9.20
|
| 989 |
-
*
|
| 990 |
-
* @param mixed $value The value, or values, to sanitize.
|
| 991 |
-
*
|
| 992 |
-
* @return mixed|null Either the sanitized version of the value, or `null` if the value is not a string, number or
|
| 993 |
-
* array.
|
| 994 |
-
*/
|
| 995 |
-
function tribe_sanitize_deep( &$value ) {
|
| 996 |
-
if ( is_bool( $value ) ) {
|
| 997 |
-
return $value;
|
| 998 |
-
}
|
| 999 |
-
if ( is_string( $value ) ) {
|
| 1000 |
-
$value = filter_var( $value, FILTER_SANITIZE_STRING );
|
| 1001 |
-
return $value;
|
| 1002 |
-
}
|
| 1003 |
-
if ( is_int( $value ) ) {
|
| 1004 |
-
$value = filter_var( $value, FILTER_VALIDATE_INT );
|
| 1005 |
-
return $value;
|
| 1006 |
-
}
|
| 1007 |
-
if ( is_float( $value ) ) {
|
| 1008 |
-
$value = filter_var( $value, FILTER_VALIDATE_FLOAT );
|
| 1009 |
-
return $value;
|
| 1010 |
-
}
|
| 1011 |
-
if ( is_array( $value ) ) {
|
| 1012 |
-
array_walk( $value, 'tribe_sanitize_deep' );
|
| 1013 |
-
return $value;
|
| 1014 |
-
}
|
| 1015 |
-
|
| 1016 |
-
return null;
|
| 1017 |
-
}
|
| 1018 |
-
}
|
| 1019 |
-
|
| 1020 |
-
if ( ! function_exists( 'tribe_get_query_var' ) ) {
|
| 1021 |
-
/**
|
| 1022 |
-
* Returns a query var parsing an input URL.
|
| 1023 |
-
*
|
| 1024 |
-
* @since 4.9.23
|
| 1025 |
-
*
|
| 1026 |
-
* @param string $url The URL to parse.
|
| 1027 |
-
* @param string|array $query_arg The query variable(s) to parse and return.
|
| 1028 |
-
* @param mixed|null $default The default value to return if the URL cannot be parsed, or the query variable is
|
| 1029 |
-
* not found.
|
| 1030 |
-
*
|
| 1031 |
-
* @return mixed|null The query variable value, if set, or the default value.
|
| 1032 |
-
*/
|
| 1033 |
-
function tribe_get_query_var( $url, $query_arg, $default = null ) {
|
| 1034 |
-
if ( empty( $url ) ) {
|
| 1035 |
-
return $default;
|
| 1036 |
-
}
|
| 1037 |
-
|
| 1038 |
-
$query = wp_parse_url( $url, PHP_URL_QUERY );
|
| 1039 |
-
|
| 1040 |
-
if ( empty( $query ) ) {
|
| 1041 |
-
return $default;
|
| 1042 |
-
}
|
| 1043 |
-
|
| 1044 |
-
wp_parse_str( $query, $parsed );
|
| 1045 |
-
|
| 1046 |
-
if ( ! is_array( $query_arg ) ) {
|
| 1047 |
-
return Tribe__Utils__Array::get( $parsed, $query_arg, $default );
|
| 1048 |
-
}
|
| 1049 |
-
|
| 1050 |
-
$query_args = (array) ( $query_arg );
|
| 1051 |
-
|
| 1052 |
-
return array_intersect_key(
|
| 1053 |
-
(array) $parsed,
|
| 1054 |
-
array_combine( $query_args, $query_args )
|
| 1055 |
-
);
|
| 1056 |
-
}
|
| 1057 |
-
}
|
| 36 |
* @param string $version The version
|
| 37 |
* @param array $classes_req Any Main class files/tribe plugins required for this to run
|
| 38 |
* @param array $dependencies an array of dependencies to check
|
| 39 |
+
*
|
| 40 |
+
* @return bool Indicates if plugin should continue initialization
|
| 41 |
*/
|
| 42 |
+
function tribe_register_plugin( $file_path, $main_class, $version, $classes_req = array(), $dependencies = array() ) {
|
| 43 |
+
|
| 44 |
+
$tribe_dependency = Tribe__Dependency::instance();
|
| 45 |
$tribe_dependency->register_plugin( $file_path, $main_class, $version, $classes_req, $dependencies );
|
| 46 |
+
|
| 47 |
}
|
| 48 |
}
|
| 49 |
|
| 53 |
*
|
| 54 |
* @since 4.9
|
| 55 |
*
|
| 56 |
+
* @param string $main_class The Main/base class for this plugin
|
| 57 |
*
|
| 58 |
* @return bool Indicates if plugin should continue initialization
|
| 59 |
*/
|
| 60 |
function tribe_check_plugin( $main_class ) {
|
| 61 |
|
| 62 |
+
$tribe_dependency = Tribe__Dependency::instance();
|
|
|
|
| 63 |
return $tribe_dependency->check_plugin( $main_class );
|
| 64 |
|
| 65 |
}
|
| 70 |
* Append a path fragment to a URL preserving query arguments
|
| 71 |
* and fragments.
|
| 72 |
*
|
| 73 |
+
* @param string $url A full URL in the `http://example.com/?query=var#frag` format.
|
|
|
|
| 74 |
* @param string $path The path to append to the existing, if any, one., e.g. `/some/path`
|
| 75 |
*
|
|
|
|
|
|
|
| 76 |
* @return mixed|string
|
| 77 |
+
*
|
| 78 |
+
* @since 4.3
|
| 79 |
*/
|
| 80 |
function tribe_append_path( $url, $path ) {
|
| 81 |
$path = trim( $path, '/' );
|
| 136 |
*
|
| 137 |
* The variable being tested for can be an array if you wish to find a nested value.
|
| 138 |
*
|
| 139 |
+
* @see Tribe__Utils__Array::get()
|
|
|
|
|
|
|
| 140 |
*
|
| 141 |
* @param string|array $var
|
| 142 |
* @param mixed $default
|
| 144 |
* @return mixed
|
| 145 |
*/
|
| 146 |
function tribe_get_request_var( $var, $default = null ) {
|
| 147 |
+
return Tribe__Utils__Array::get_in_any( array( $_GET, $_POST ), $var, $default );
|
|
|
|
| 148 |
}
|
| 149 |
}
|
| 150 |
|
| 155 |
*
|
| 156 |
* @since 4.7.8
|
| 157 |
*
|
| 158 |
+
* @return object The $wp_query, the $wp_the_query if $wp_query empty, null otherwise.
|
| 159 |
*/
|
| 160 |
function tribe_get_global_query_object() {
|
| 161 |
global $wp_query;
|
| 192 |
*
|
| 193 |
* @param array $truthy_strings
|
| 194 |
*/
|
| 195 |
+
$truthy_strings = (array) apply_filters( 'tribe_is_truthy_strings', array(
|
| 196 |
'1',
|
| 197 |
'enable',
|
| 198 |
'enabled',
|
| 200 |
'y',
|
| 201 |
'yes',
|
| 202 |
'true',
|
| 203 |
+
) );
|
| 204 |
// Makes sure we are dealing with lowercase for testing
|
| 205 |
if ( is_string( $var ) ) {
|
| 206 |
$var = strtolower( $var );
|
| 225 |
/**
|
| 226 |
* Sorting function based on Priority
|
| 227 |
*
|
|
|
|
|
|
|
|
|
|
|
|
|
| 228 |
* @param object|array $a First Subject to compare
|
| 229 |
+
* @param object|array $b Second subject to compare
|
| 230 |
*
|
| 231 |
* @return int
|
| 232 |
+
* @since 4.7.20
|
| 233 |
+
*
|
| 234 |
*/
|
| 235 |
function tribe_sort_by_priority( $a, $b ) {
|
| 236 |
if ( is_array( $a ) ) {
|
| 253 |
/**
|
| 254 |
* Normalizes a list of terms to a list of fields.
|
| 255 |
*
|
| 256 |
+
* @param $terms A term or array of terms to normalize.
|
|
|
|
| 257 |
* @param string $taxonomy The terms taxonomy.
|
| 258 |
+
* @param string $field Teh fields the terms should be normalized to.
|
| 259 |
+
*
|
| 260 |
+
* @since 4.5
|
| 261 |
*
|
| 262 |
* @return array An array of the valid normalized terms.
|
| 263 |
*/
|
| 264 |
function tribe_normalize_terms_list( $terms, $taxonomy, $field = 'term_id' ) {
|
| 265 |
if ( ! is_array( $terms ) ) {
|
| 266 |
+
$terms = array( $terms );
|
| 267 |
}
|
| 268 |
|
| 269 |
+
$normalized = array();
|
| 270 |
foreach ( $terms as $term ) {
|
| 271 |
if ( is_object( $term ) && ! empty( $term->{$field} ) ) {
|
| 272 |
$normalized[] = $term->{$field};
|
| 289 |
}
|
| 290 |
|
| 291 |
if ( ! function_exists( 'tribe_upload_image' ) ) {
|
| 292 |
+
/** * @param string|int $image The path to an image file, an image URL or an attachment post ID.
|
|
|
|
|
|
|
|
|
|
| 293 |
*
|
| 294 |
* @return int|bool The attachment post ID if the uploading and attachment is successful or the ID refers to an attachment;
|
| 295 |
* `false` otherwise.
|
| 296 |
+
*
|
| 297 |
+
* @see Tribe__Image__Uploader::upload_and_get_attachment_id()
|
| 298 |
*/
|
| 299 |
function tribe_upload_image( $image ) {
|
| 300 |
$uploader = new Tribe__Image__Uploader( $image );
|
| 331 |
*
|
| 332 |
* @since 4.5.8
|
| 333 |
*
|
| 334 |
+
* @param string $class_name
|
| 335 |
+
* @param string $hook
|
| 336 |
+
* @param int $priority
|
| 337 |
*
|
| 338 |
* @return object|false
|
| 339 |
*/
|
| 406 |
global $wpdb;
|
| 407 |
|
| 408 |
$query_template = "SELECT ID FROM {$wpdb->posts} WHERE %s";
|
| 409 |
+
$query_vars = array();
|
| 410 |
$where = '';
|
| 411 |
|
| 412 |
if ( is_numeric( $post_id_or_name ) ) {
|
| 495 |
*
|
| 496 |
* @since 4.9.5
|
| 497 |
*
|
| 498 |
+
* @throws RuntimeException The message will be the error message, the code will be the error code.
|
| 499 |
+
*
|
| 500 |
* @see set_error_handler()
|
| 501 |
* @see restore_error_handler()
|
|
|
|
| 502 |
*/
|
| 503 |
function tribe_catch_and_throw( $errno, $errstr ) {
|
| 504 |
throw new RuntimeException( $errstr, $errno );
|
| 549 |
return $regex;
|
| 550 |
}
|
| 551 |
|
| 552 |
+
$str_fence = $regex[0];
|
| 553 |
// Let's pick a fence char the string itself is not using.
|
| 554 |
$fence_char = '~' === $str_fence ? '#' : '~';
|
| 555 |
+
$pattern = $fence_char
|
| 556 |
+
. preg_quote( $str_fence, $fence_char ) // the opening fence
|
| 557 |
+
. '(.*)' // keep anything after the opening fence, group 1
|
| 558 |
+
. preg_quote( $str_fence, $fence_char ) // the closing fence
|
| 559 |
+
. '.*' // any modifier after the closing fence
|
| 560 |
+
. $fence_char;
|
| 561 |
|
| 562 |
return preg_replace( $pattern, '$1', $regex );
|
| 563 |
}
|
| 577 |
* you should use the block parser on post content.
|
| 578 |
*
|
| 579 |
* @since 4.8
|
| 580 |
+
* @see https://github.com/WordPress/gutenberg/blob/73d9759116dde896931f4d152f186147a57889fe/lib/register.php#L313-L337s
|
|
|
|
| 581 |
*
|
| 582 |
* @param int|string|WP_Post|null $post Optional. Post content, post ID, or post object. Defaults to global $post.
|
|
|
|
| 583 |
* @return bool Whether the post has blocks.
|
| 584 |
*/
|
| 585 |
function has_blocks( $post = null ) {
|
| 589 |
$post = $wp_post->post_content;
|
| 590 |
}
|
| 591 |
}
|
|
|
|
| 592 |
return false !== strpos( (string) $post, '<!-- wp:' );
|
| 593 |
}
|
| 594 |
}
|
| 597 |
/**
|
| 598 |
* Wrapper function for `register_rest_route` to allow for filtering any Tribe REST API endpoint.
|
| 599 |
*
|
| 600 |
+
* @param string $namespace The first URL segment after core prefix. Should be unique to your package/plugin.
|
|
|
|
| 601 |
* @param string $route The base URL for route you are adding.
|
| 602 |
* @param array $args Optional. Either an array of options for the endpoint, or an array of arrays for
|
| 603 |
* multiple methods. Default empty array.
|
| 604 |
* @param bool $override Optional. If the route already exists, should we override it? True overrides,
|
| 605 |
* false merges (with newer overriding if duplicate keys exist). Default false.
|
| 606 |
*
|
|
|
|
|
|
|
| 607 |
* @return bool True on success, false on error.
|
| 608 |
+
*
|
| 609 |
+
* @since 4.9.12
|
| 610 |
*/
|
| 611 |
+
function tribe_register_rest_route( $namespace, $route, $args = array(), $override = false ) {
|
| 612 |
/**
|
| 613 |
* Allow plugins to customize REST API arguments and callbacks.
|
| 614 |
*
|
| 615 |
+
* @param array $args Either an array of options for the endpoint, or an array of arrays for
|
| 616 |
+
* multiple methods. Default empty array.
|
| 617 |
* @param string $namespace The first URL segment after core prefix. Should be unique to your package/plugin.
|
| 618 |
* @param string $route The base URL for route you are adding.
|
| 619 |
* @param bool $override Optional. If the route already exists, should we override it? True overrides,
|
| 620 |
* false merges (with newer overriding if duplicate keys exist). Default false.
|
| 621 |
*
|
| 622 |
+
* @since 4.9.12
|
|
|
|
| 623 |
*/
|
| 624 |
$args = apply_filters( 'tribe_register_rest_route_args_' . $namespace . $route, $args, $namespace, $route, $override );
|
| 625 |
|
| 626 |
/**
|
| 627 |
* Allow plugins to customize REST API arguments and callbacks.
|
| 628 |
*
|
| 629 |
+
* @param array $args Either an array of options for the endpoint, or an array of arrays for
|
| 630 |
+
* multiple methods. Default empty array.
|
| 631 |
* @param string $namespace The first URL segment after core prefix. Should be unique to your package/plugin.
|
| 632 |
* @param string $route The base URL for route you are adding.
|
| 633 |
* @param bool $override Optional. If the route already exists, should we override it? True overrides,
|
| 634 |
* false merges (with newer overriding if duplicate keys exist). Default false.
|
| 635 |
*
|
| 636 |
+
* @since 4.9.12
|
|
|
|
| 637 |
*/
|
| 638 |
$args = apply_filters( 'tribe_register_rest_route_args', $args, $namespace, $route, $override );
|
|
|
|
| 639 |
return register_rest_route( $namespace, $route, $args, $override );
|
| 640 |
}
|
| 641 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
common/src/modules/components/form/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
| 1 |
+
export { default as Select } from './select';
|
common/src/modules/components/form/select/component.js
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import React, { PureComponent } from 'react';
|
| 5 |
+
import PropTypes from 'prop-types';
|
| 6 |
+
import { noop, partial, find } from 'lodash';
|
| 7 |
+
import classnames from 'classnames';
|
| 8 |
+
import {
|
| 9 |
+
Dropdown,
|
| 10 |
+
Dashicon,
|
| 11 |
+
} from '@wordpress/components';
|
| 12 |
+
import { ScrollTo, ScrollArea } from 'react-scroll-to';
|
| 13 |
+
|
| 14 |
+
/**
|
| 15 |
+
* Internal dependencies
|
| 16 |
+
*/
|
| 17 |
+
import { PreventBlockClose } from '@moderntribe/common/components';
|
| 18 |
+
import './style.pcss';
|
| 19 |
+
|
| 20 |
+
export default class Select extends PureComponent {
|
| 21 |
+
static propTypes = {
|
| 22 |
+
options: PropTypes.shape( {
|
| 23 |
+
label: PropTypes.string,
|
| 24 |
+
value: PropTypes.any,
|
| 25 |
+
} ),
|
| 26 |
+
onOptionClick: PropTypes.func.isRequired,
|
| 27 |
+
optionClassName: PropTypes.string,
|
| 28 |
+
isOpen: PropTypes.bool.isRequired,
|
| 29 |
+
value: PropTypes.any,
|
| 30 |
+
className: PropTypes.string,
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
static defaultProps = {
|
| 34 |
+
onOptionClick: noop,
|
| 35 |
+
isOpen: true,
|
| 36 |
+
optionClassName: '',
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
+
_onOptionClick = ( onClose, value, e ) => {
|
| 40 |
+
this.props.onOptionClick( value, e );
|
| 41 |
+
onClose();
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
get selected() {
|
| 45 |
+
return find( this.props.options, option => option.value === this.props.value );
|
| 46 |
+
}
|
| 47 |
+
|
| 48 |
+
get label() {
|
| 49 |
+
const selected = this.selected;
|
| 50 |
+
return selected && selected.label;
|
| 51 |
+
}
|
| 52 |
+
|
| 53 |
+
renderOptions = ( onClose ) => (
|
| 54 |
+
this.props.options.map( ( option ) => (
|
| 55 |
+
<button
|
| 56 |
+
className={ classnames(
|
| 57 |
+
'tribe-common-form-select__options__option',
|
| 58 |
+
this.props.optionClassName
|
| 59 |
+
) }
|
| 60 |
+
key={ option.value }
|
| 61 |
+
onClick={ partial( this._onOptionClick, onClose, option.value ) }
|
| 62 |
+
role="menuitem"
|
| 63 |
+
type="button"
|
| 64 |
+
value={ option.value }
|
| 65 |
+
>
|
| 66 |
+
{ option.label }
|
| 67 |
+
</button>
|
| 68 |
+
) )
|
| 69 |
+
)
|
| 70 |
+
|
| 71 |
+
renderToggle = ( { onToggle, isOpen } ) => (
|
| 72 |
+
<div className="tribe-common-form-select__toggle">
|
| 73 |
+
<button
|
| 74 |
+
type="button"
|
| 75 |
+
aria-expanded={ isOpen }
|
| 76 |
+
onClick={ onToggle }
|
| 77 |
+
>
|
| 78 |
+
<span>{ this.label }</span>
|
| 79 |
+
<Dashicon
|
| 80 |
+
className="btn--icon"
|
| 81 |
+
icon={ isOpen ? 'arrow-up' : 'arrow-down' }
|
| 82 |
+
/>
|
| 83 |
+
</button>
|
| 84 |
+
</div>
|
| 85 |
+
)
|
| 86 |
+
|
| 87 |
+
renderContent = ( { onClose } ) => (
|
| 88 |
+
<ScrollTo>
|
| 89 |
+
{ () => (
|
| 90 |
+
<PreventBlockClose>
|
| 91 |
+
<ScrollArea
|
| 92 |
+
role="menu"
|
| 93 |
+
className={ classnames( 'tribe-common-form-select__options' ) }
|
| 94 |
+
>
|
| 95 |
+
{ this.renderOptions( onClose ) }
|
| 96 |
+
</ScrollArea>
|
| 97 |
+
</PreventBlockClose>
|
| 98 |
+
) }
|
| 99 |
+
</ScrollTo>
|
| 100 |
+
|
| 101 |
+
);
|
| 102 |
+
|
| 103 |
+
render() {
|
| 104 |
+
return (
|
| 105 |
+
<Dropdown
|
| 106 |
+
className={ classnames( 'tribe-common-form-select',
|
| 107 |
+
this.props.className
|
| 108 |
+
) }
|
| 109 |
+
position="bottom center"
|
| 110 |
+
contentClassName="tribe-common-form-select__content"
|
| 111 |
+
renderToggle={ this.renderToggle }
|
| 112 |
+
renderContent={ this.renderContent }
|
| 113 |
+
/>
|
| 114 |
+
);
|
| 115 |
+
}
|
| 116 |
+
}
|
common/src/modules/components/form/select/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
| 1 |
+
export { default } from './component';
|
common/src/modules/components/form/select/style.pcss
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
.tribe-common-form-select {
|
| 2 |
+
display: flex;
|
| 3 |
+
|
| 4 |
+
& > div {
|
| 5 |
+
flex: 0 0 auto;
|
| 6 |
+
min-width: 193px;
|
| 7 |
+
}
|
| 8 |
+
|
| 9 |
+
&__toggle {
|
| 10 |
+
background-color: #FFF;
|
| 11 |
+
border-radius: 2px;
|
| 12 |
+
border: 2px solid #EAEBEC;
|
| 13 |
+
|
| 14 |
+
& button {
|
| 15 |
+
align-items: center;
|
| 16 |
+
background-color: #FEFFFE;
|
| 17 |
+
border: none;
|
| 18 |
+
color: #545D66;
|
| 19 |
+
display: flex;
|
| 20 |
+
font-family: Helvetica, sans-serif;
|
| 21 |
+
font-size: 16px;
|
| 22 |
+
font-weight: 400;
|
| 23 |
+
font-weight: normal;
|
| 24 |
+
justify-content: center;
|
| 25 |
+
line-height: 1.5;
|
| 26 |
+
padding: 6px 10px;
|
| 27 |
+
text-align: left;
|
| 28 |
+
text-decoration: none;
|
| 29 |
+
width: 100%;
|
| 30 |
+
|
| 31 |
+
& > span {
|
| 32 |
+
flex: 1;
|
| 33 |
+
}
|
| 34 |
+
}
|
| 35 |
+
}
|
| 36 |
+
|
| 37 |
+
&__options {
|
| 38 |
+
|
| 39 |
+
&__option {
|
| 40 |
+
background: transparent;
|
| 41 |
+
border: 0;
|
| 42 |
+
color: #555d66;
|
| 43 |
+
cursor: pointer;
|
| 44 |
+
display: block;
|
| 45 |
+
line-height: 20px;
|
| 46 |
+
padding: 5px 12px;
|
| 47 |
+
text-align: left;
|
| 48 |
+
width: 100%;
|
| 49 |
+
|
| 50 |
+
&:hover {
|
| 51 |
+
background-color: #009fd4;
|
| 52 |
+
color: #fff;
|
| 53 |
+
}
|
| 54 |
+
}
|
| 55 |
+
}
|
| 56 |
+
}
|
common/src/modules/components/index.js
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* eslint-disable max-len */
|
| 2 |
+
export { default as PluginBlockHooks } from '@moderntribe/common/components/plugin-block-hooks';
|
| 3 |
+
export { default as PreventBlockClose } from '@moderntribe/common/components/prevent-block-close';
|
| 4 |
+
export * from './form';
|
| 5 |
+
|
common/src/modules/components/plugin-block-hooks/__tests__/__snapshots__/plugin-block-hooks.spec.js.snap
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
| 2 |
+
|
| 3 |
+
exports[`PluginBlockHooks should match snapshot 1`] = `
|
| 4 |
+
<div
|
| 5 |
+
className="tribe-common__plugin-block-hook"
|
| 6 |
+
>
|
| 7 |
+
<InnerBlocks
|
| 8 |
+
template={
|
| 9 |
+
Array [
|
| 10 |
+
Array [
|
| 11 |
+
"tribe/event-datetime",
|
| 12 |
+
Object {},
|
| 13 |
+
],
|
| 14 |
+
Array [
|
| 15 |
+
"tribe/event-pro-recurring",
|
| 16 |
+
Object {},
|
| 17 |
+
],
|
| 18 |
+
Array [
|
| 19 |
+
"tribe/event-pro-exclusion",
|
| 20 |
+
Object {},
|
| 21 |
+
],
|
| 22 |
+
]
|
| 23 |
+
}
|
| 24 |
+
templateInsertUpdatesSelection={false}
|
| 25 |
+
/>
|
| 26 |
+
</div>
|
| 27 |
+
`;
|
| 28 |
+
|
| 29 |
+
exports[`PluginBlockHooks should not hook in unregistered blocks 1`] = `
|
| 30 |
+
<div
|
| 31 |
+
className="tribe-common__plugin-block-hook"
|
| 32 |
+
>
|
| 33 |
+
<InnerBlocks
|
| 34 |
+
template={
|
| 35 |
+
Array [
|
| 36 |
+
Array [
|
| 37 |
+
"tribe/event-datetime",
|
| 38 |
+
Object {},
|
| 39 |
+
],
|
| 40 |
+
Array [
|
| 41 |
+
"tribe/event-pro-recurring",
|
| 42 |
+
Object {},
|
| 43 |
+
],
|
| 44 |
+
Array [
|
| 45 |
+
"tribe/event-pro-exclusion",
|
| 46 |
+
Object {},
|
| 47 |
+
],
|
| 48 |
+
]
|
| 49 |
+
}
|
| 50 |
+
templateInsertUpdatesSelection={false}
|
| 51 |
+
/>
|
| 52 |
+
</div>
|
| 53 |
+
`;
|
| 54 |
+
|
| 55 |
+
exports[`PluginBlockHooks should only render events templates 1`] = `
|
| 56 |
+
<div
|
| 57 |
+
className="tribe-common__plugin-block-hook"
|
| 58 |
+
>
|
| 59 |
+
<InnerBlocks
|
| 60 |
+
template={
|
| 61 |
+
Array [
|
| 62 |
+
Array [
|
| 63 |
+
"tribe/event-datetime",
|
| 64 |
+
Object {},
|
| 65 |
+
],
|
| 66 |
+
]
|
| 67 |
+
}
|
| 68 |
+
templateInsertUpdatesSelection={false}
|
| 69 |
+
/>
|
| 70 |
+
</div>
|
| 71 |
+
`;
|
| 72 |
+
|
| 73 |
+
exports[`PluginBlockHooks should only render events-pro templates 1`] = `
|
| 74 |
+
<div
|
| 75 |
+
className="tribe-common__plugin-block-hook"
|
| 76 |
+
>
|
| 77 |
+
<InnerBlocks
|
| 78 |
+
template={
|
| 79 |
+
Array [
|
| 80 |
+
Array [
|
| 81 |
+
"tribe/event-pro-recurring",
|
| 82 |
+
Object {},
|
| 83 |
+
],
|
| 84 |
+
Array [
|
| 85 |
+
"tribe/event-pro-exclusion",
|
| 86 |
+
Object {},
|
| 87 |
+
],
|
| 88 |
+
]
|
| 89 |
+
}
|
| 90 |
+
templateInsertUpdatesSelection={false}
|
| 91 |
+
/>
|
| 92 |
+
</div>
|
| 93 |
+
`;
|
| 94 |
+
|
| 95 |
+
exports[`PluginBlockHooks should recursively hook blocks 1`] = `
|
| 96 |
+
<div
|
| 97 |
+
className="tribe-common__plugin-block-hook"
|
| 98 |
+
>
|
| 99 |
+
<InnerBlocks
|
| 100 |
+
template={
|
| 101 |
+
Array [
|
| 102 |
+
Array [
|
| 103 |
+
"tribe/event-pro-recurring",
|
| 104 |
+
Object {},
|
| 105 |
+
],
|
| 106 |
+
Array [
|
| 107 |
+
"tribe/event-cool-container1",
|
| 108 |
+
Object {},
|
| 109 |
+
Array [
|
| 110 |
+
Array [
|
| 111 |
+
"tribe/event-pro-recurring",
|
| 112 |
+
Object {},
|
| 113 |
+
],
|
| 114 |
+
Array [
|
| 115 |
+
"tribe/event-cool-container2",
|
| 116 |
+
Object {},
|
| 117 |
+
Array [
|
| 118 |
+
Array [
|
| 119 |
+
"tribe/event-pro-recurring",
|
| 120 |
+
Object {},
|
| 121 |
+
],
|
| 122 |
+
],
|
| 123 |
+
],
|
| 124 |
+
],
|
| 125 |
+
],
|
| 126 |
+
]
|
| 127 |
+
}
|
| 128 |
+
templateInsertUpdatesSelection={false}
|
| 129 |
+
/>
|
| 130 |
+
</div>
|
| 131 |
+
`;
|
common/src/modules/components/plugin-block-hooks/__tests__/plugin-block-hooks.spec.js
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External Dependencies
|
| 3 |
+
*/
|
| 4 |
+
import React from 'react';
|
| 5 |
+
import renderer from 'react-test-renderer';
|
| 6 |
+
|
| 7 |
+
/**
|
| 8 |
+
* Internal Dependencies
|
| 9 |
+
*/
|
| 10 |
+
import PluginBlockHooks from '../component';
|
| 11 |
+
|
| 12 |
+
jest.mock( '@wordpress/editor', () => ( {
|
| 13 |
+
InnerBlocks: 'InnerBlocks',
|
| 14 |
+
} ) );
|
| 15 |
+
jest.mock( '@wordpress/data', () => ( {
|
| 16 |
+
select: jest.fn( () => ( {
|
| 17 |
+
getBlockTypes: jest.fn( () => ( [
|
| 18 |
+
{ name: 'tribe/event-datetime' },
|
| 19 |
+
{ name: 'tribe/event-pro-recurring' },
|
| 20 |
+
{ name: 'tribe/event-pro-exclusion' },
|
| 21 |
+
{ name: 'tribe/event-cool-container1' },
|
| 22 |
+
{ name: 'tribe/event-cool-container2' },
|
| 23 |
+
] ) ),
|
| 24 |
+
} ) ),
|
| 25 |
+
} ) );
|
| 26 |
+
|
| 27 |
+
describe( 'PluginBlockHooks', () => {
|
| 28 |
+
let props;
|
| 29 |
+
beforeEach( () => {
|
| 30 |
+
props = {
|
| 31 |
+
plugins: [ 'events', 'events-pro', 'events-cool' ],
|
| 32 |
+
pluginTemplates: {
|
| 33 |
+
'events': [
|
| 34 |
+
[ 'tribe/event-datetime', {}],
|
| 35 |
+
],
|
| 36 |
+
'events-pro': [
|
| 37 |
+
[ 'tribe/event-pro-recurring', {}],
|
| 38 |
+
[ 'tribe/event-pro-exclusion', {}],
|
| 39 |
+
],
|
| 40 |
+
},
|
| 41 |
+
};
|
| 42 |
+
} );
|
| 43 |
+
|
| 44 |
+
test( 'should match snapshot', () => {
|
| 45 |
+
const component = renderer.create(
|
| 46 |
+
<PluginBlockHooks { ...props } />
|
| 47 |
+
);
|
| 48 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 49 |
+
} );
|
| 50 |
+
test( 'should only render events templates', () => {
|
| 51 |
+
props.plugins = props.plugins.filter( plugin => plugin === 'events' );
|
| 52 |
+
const component = renderer.create(
|
| 53 |
+
<PluginBlockHooks { ...props } />
|
| 54 |
+
);
|
| 55 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 56 |
+
} );
|
| 57 |
+
test( 'should only render events-pro templates', () => {
|
| 58 |
+
props.plugins = props.plugins.filter( plugin => plugin === 'events-pro' );
|
| 59 |
+
const component = renderer.create(
|
| 60 |
+
<PluginBlockHooks { ...props } />
|
| 61 |
+
);
|
| 62 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 63 |
+
} );
|
| 64 |
+
test( 'should not hook in unregistered blocks', () => {
|
| 65 |
+
props.pluginTemplates.events.push( [ 'i-dont-exist', {}] );
|
| 66 |
+
const component = renderer.create(
|
| 67 |
+
<PluginBlockHooks { ...props } />
|
| 68 |
+
);
|
| 69 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 70 |
+
} );
|
| 71 |
+
test( 'should recursively hook blocks', () => {
|
| 72 |
+
delete props.pluginTemplates.events;
|
| 73 |
+
delete props.pluginTemplates[ 'events-pro' ];
|
| 74 |
+
props.pluginTemplates[ 'events-cool' ] = [
|
| 75 |
+
[ 'tribe/event-pro-recurring', {}],
|
| 76 |
+
[ 'tribe/event-cool-container1', {}, [
|
| 77 |
+
[ 'tribe/event-pro-recurring', {}],
|
| 78 |
+
[ 'tribe/event-cool-container2', {}, [
|
| 79 |
+
[ 'tribe/event-pro-recurring', {}],
|
| 80 |
+
[ 'dont-register-me', {}],
|
| 81 |
+
] ],
|
| 82 |
+
[ 'dont-register-2me', {}],
|
| 83 |
+
],
|
| 84 |
+
[ 'dont-register-me', {}],
|
| 85 |
+
],
|
| 86 |
+
];
|
| 87 |
+
const component = renderer.create(
|
| 88 |
+
<PluginBlockHooks { ...props } />
|
| 89 |
+
);
|
| 90 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 91 |
+
} );
|
| 92 |
+
} );
|
common/src/modules/components/plugin-block-hooks/component.js
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import React, { PureComponent } from 'react';
|
| 5 |
+
import PropTypes from 'prop-types';
|
| 6 |
+
import { map, reduce, includes, isArray } from 'lodash';
|
| 7 |
+
import { InnerBlocks } from '@wordpress/editor';
|
| 8 |
+
import { select } from '@wordpress/data';
|
| 9 |
+
import './style.pcss';
|
| 10 |
+
|
| 11 |
+
/**
|
| 12 |
+
* Allows for dynamic plugin templates based on current plugins available
|
| 13 |
+
* utilizing InnerBlocks api
|
| 14 |
+
*
|
| 15 |
+
* @export
|
| 16 |
+
* @class PluginBlockHooks
|
| 17 |
+
* @extends {PureComponent}
|
| 18 |
+
*/
|
| 19 |
+
export default class PluginBlockHooks extends PureComponent {
|
| 20 |
+
static propTypes = {
|
| 21 |
+
allowedBlocks: PropTypes.arrayOf( PropTypes.string ),
|
| 22 |
+
layouts: PropTypes.oneOfType( [
|
| 23 |
+
PropTypes.object,
|
| 24 |
+
PropTypes.arrayOf( PropTypes.object ),
|
| 25 |
+
] ),
|
| 26 |
+
/**
|
| 27 |
+
* Plugins to be used
|
| 28 |
+
*/
|
| 29 |
+
plugins: PropTypes.arrayOf( PropTypes.string ).isRequired,
|
| 30 |
+
/**
|
| 31 |
+
* Plugin template structure needed to properly
|
| 32 |
+
* register new templates for each plugin
|
| 33 |
+
*
|
| 34 |
+
*
|
| 35 |
+
* ```js
|
| 36 |
+
* {
|
| 37 |
+
* 'events': [
|
| 38 |
+
* [ 'tribe/event-datetime', {}],
|
| 39 |
+
* ],
|
| 40 |
+
* 'events-pro': [
|
| 41 |
+
* [ 'tribe/event-pro-recurring', {}],
|
| 42 |
+
* [ 'tribe/event-pro-exclusion', {}],
|
| 43 |
+
* ],
|
| 44 |
+
* 'events-cool': [
|
| 45 |
+
* [ 'tribe/event-cool-container', {}, [
|
| 46 |
+
* [ 'tribe/event-cool-column', {}],
|
| 47 |
+
* [ 'tribe/event-cool-column', {}],
|
| 48 |
+
* ]]
|
| 49 |
+
* ],
|
| 50 |
+
* }
|
| 51 |
+
* ```
|
| 52 |
+
*/
|
| 53 |
+
pluginTemplates: PropTypes.objectOf( PropTypes.arrayOf( PropTypes.array ) ),
|
| 54 |
+
templateInsertUpdatesSelection: PropTypes.bool.isRequired,
|
| 55 |
+
templateLock: PropTypes.oneOf( [
|
| 56 |
+
'all',
|
| 57 |
+
'insert',
|
| 58 |
+
false,
|
| 59 |
+
] ),
|
| 60 |
+
}
|
| 61 |
+
|
| 62 |
+
static defaultProps = {
|
| 63 |
+
templateInsertUpdatesSelection: false,
|
| 64 |
+
}
|
| 65 |
+
|
| 66 |
+
/**
|
| 67 |
+
* Registered block names from core
|
| 68 |
+
*
|
| 69 |
+
* @readonly
|
| 70 |
+
* @memberof PluginBlockHooks
|
| 71 |
+
* @returns {Array} block names
|
| 72 |
+
*/
|
| 73 |
+
get registeredBlockNames() {
|
| 74 |
+
const blockTypes = select( 'core/blocks' ).getBlockTypes();
|
| 75 |
+
return map( blockTypes, block => block.name );
|
| 76 |
+
}
|
| 77 |
+
|
| 78 |
+
/**
|
| 79 |
+
* Template for InnerBlocks
|
| 80 |
+
*
|
| 81 |
+
* @readonly
|
| 82 |
+
* @memberof PluginBlockHooks
|
| 83 |
+
* @returns {Array} template
|
| 84 |
+
*/
|
| 85 |
+
get template() {
|
| 86 |
+
const blockNames = this.registeredBlockNames;
|
| 87 |
+
return this.props.plugins.reduce( ( acc, plugin ) => {
|
| 88 |
+
const pluginTemplate = this.props.pluginTemplates[ plugin ];
|
| 89 |
+
if ( pluginTemplate ) {
|
| 90 |
+
// Block needs to be registered, otherwise it's dropped
|
| 91 |
+
const blockTemplates = this.filterPluginTemplates( blockNames, pluginTemplate );
|
| 92 |
+
return [
|
| 93 |
+
...acc,
|
| 94 |
+
...blockTemplates,
|
| 95 |
+
];
|
| 96 |
+
}
|
| 97 |
+
return acc;
|
| 98 |
+
}, [] );
|
| 99 |
+
}
|
| 100 |
+
|
| 101 |
+
/**
|
| 102 |
+
* Recursively filters out unregistered blocks
|
| 103 |
+
*
|
| 104 |
+
* @param {Array} blockNames block names currently registered
|
| 105 |
+
* @param {Array} pluginTemplate Template for plugins
|
| 106 |
+
* @returns {Array} Array of plugin template
|
| 107 |
+
*/
|
| 108 |
+
filterPluginTemplates( blockNames, pluginTemplate ) {
|
| 109 |
+
return reduce( pluginTemplate, ( acc, [ name, attributes, nestedBlockTemplates ] ) => {
|
| 110 |
+
if ( includes( blockNames, name ) ) {
|
| 111 |
+
const blockTemplate = isArray( nestedBlockTemplates )
|
| 112 |
+
? [ name, attributes, /* Recursive call */ this.filterPluginTemplates( blockNames, nestedBlockTemplates ) ] // eslint-disable-line max-len
|
| 113 |
+
: [ name, attributes ];
|
| 114 |
+
|
| 115 |
+
return [
|
| 116 |
+
...acc,
|
| 117 |
+
blockTemplate,
|
| 118 |
+
];
|
| 119 |
+
}
|
| 120 |
+
|
| 121 |
+
return acc;
|
| 122 |
+
}, [] );
|
| 123 |
+
}
|
| 124 |
+
|
| 125 |
+
render() {
|
| 126 |
+
return (
|
| 127 |
+
<div className="tribe-common__plugin-block-hook">
|
| 128 |
+
<InnerBlocks
|
| 129 |
+
allowedBlocks={ this.props.allowedBlocks }
|
| 130 |
+
layouts={ this.props.layouts }
|
| 131 |
+
template={ this.template }
|
| 132 |
+
templateInsertUpdatesSelection={ this.props.templateInsertUpdatesSelection }
|
| 133 |
+
templateLock={ this.props.templateLock }
|
| 134 |
+
/>
|
| 135 |
+
</div>
|
| 136 |
+
);
|
| 137 |
+
}
|
| 138 |
+
}
|
common/src/modules/components/plugin-block-hooks/container.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import { connect } from 'react-redux';
|
| 5 |
+
import { compose } from 'redux';
|
| 6 |
+
|
| 7 |
+
/**
|
| 8 |
+
* Internal Dependencies
|
| 9 |
+
*/
|
| 10 |
+
import { selectors } from '@moderntribe/common/data/plugins';
|
| 11 |
+
import { withStore } from '@moderntribe/common/hoc';
|
| 12 |
+
import PluginBlockHooks from './component';
|
| 13 |
+
|
| 14 |
+
const mapStateToProps = ( state, ownProps ) => ( {
|
| 15 |
+
plugins: selectors.getPlugins( state ),
|
| 16 |
+
} );
|
| 17 |
+
|
| 18 |
+
export default compose(
|
| 19 |
+
withStore(),
|
| 20 |
+
connect( mapStateToProps ),
|
| 21 |
+
)( PluginBlockHooks );
|
common/src/modules/components/plugin-block-hooks/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
| 1 |
+
export { default } from './container';
|
common/src/modules/components/plugin-block-hooks/style.pcss
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
.tribe-common__plugin-block-hook {
|
| 2 |
+
|
| 3 |
+
& .editor-inner-blocks {
|
| 4 |
+
|
| 5 |
+
& .editor-block-list__layout {
|
| 6 |
+
margin: 0;
|
| 7 |
+
|
| 8 |
+
& .editor-block-list__block {
|
| 9 |
+
margin: 0;
|
| 10 |
+
max-width: 100% !important;
|
| 11 |
+
padding: 0;
|
| 12 |
+
|
| 13 |
+
&.is-selected > .editor-block-list__block-edit:before,
|
| 14 |
+
&.is-selected-parent > .editor-block-list__block-edit:before,
|
| 15 |
+
&.is-hovered > .editor-block-list__block-edit:before {
|
| 16 |
+
outline: none;
|
| 17 |
+
}
|
| 18 |
+
|
| 19 |
+
& .editor-block-list__block-edit {
|
| 20 |
+
margin: 0;
|
| 21 |
+
|
| 22 |
+
&:before {
|
| 23 |
+
outline: none;
|
| 24 |
+
}
|
| 25 |
+
|
| 26 |
+
& .editor-block-contextual-toolbar {
|
| 27 |
+
display: none;
|
| 28 |
+
}
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
{
|
| 32 |
+
outline: none;
|
| 33 |
+
}
|
| 34 |
+
}
|
| 35 |
+
}
|
| 36 |
+
}
|
| 37 |
+
}
|
common/src/modules/components/prevent-block-close/__tests__/component.spec.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import React from 'react';
|
| 2 |
+
import PreventBlockClose from '../component';
|
| 3 |
+
|
| 4 |
+
describe( 'PreventBlockClose', () => {
|
| 5 |
+
test( 'should match snapshot', () => {
|
| 6 |
+
const component = mount(
|
| 7 |
+
<PreventBlockClose>
|
| 8 |
+
<span>Test children</span>
|
| 9 |
+
</PreventBlockClose>
|
| 10 |
+
);
|
| 11 |
+
const child = component.find( 'span' );
|
| 12 |
+
expect( child ).toHaveLength( 1 );
|
| 13 |
+
expect( child.text() ).toEqual( "Test children" );
|
| 14 |
+
} );
|
| 15 |
+
} );
|
common/src/modules/components/prevent-block-close/component.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External Dependencies
|
| 3 |
+
*/
|
| 4 |
+
import React, { PureComponent } from 'react';
|
| 5 |
+
import PropTypes from 'prop-types';
|
| 6 |
+
|
| 7 |
+
/**
|
| 8 |
+
* Internal Dependencies
|
| 9 |
+
*/
|
| 10 |
+
import { intercept, EVENT_NAMESPACE } from '@moderntribe/common/hoc/with-block-closer';
|
| 11 |
+
|
| 12 |
+
export default class PreventBlockClose extends PureComponent {
|
| 13 |
+
static propTypes = {
|
| 14 |
+
children: PropTypes.node.isRequired,
|
| 15 |
+
}
|
| 16 |
+
|
| 17 |
+
nodeRef = React.createRef();
|
| 18 |
+
|
| 19 |
+
componentDidMount() {
|
| 20 |
+
this.node.addEventListener( EVENT_NAMESPACE, intercept );
|
| 21 |
+
}
|
| 22 |
+
|
| 23 |
+
componentWillUnmount() {
|
| 24 |
+
this.node.removeEventListener( EVENT_NAMESPACE, intercept );
|
| 25 |
+
}
|
| 26 |
+
|
| 27 |
+
get node() {
|
| 28 |
+
return this.nodeRef.current;
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
render() {
|
| 32 |
+
return (
|
| 33 |
+
<div ref={ this.nodeRef }>
|
| 34 |
+
{ this.props.children }
|
| 35 |
+
</div>
|
| 36 |
+
);
|
| 37 |
+
}
|
| 38 |
+
}
|
common/src/modules/components/prevent-block-close/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
| 1 |
+
export { default } from './component';
|
common/src/modules/data/__tests__/utils.test.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* Internal dependencies
|
| 3 |
+
*/
|
| 4 |
+
import { PREFIX_COMMON_STORE } from '@moderntribe/common/data/utils';
|
| 5 |
+
|
| 6 |
+
describe( 'prefix', () => {
|
| 7 |
+
it( 'Should return the prefix', () => {
|
| 8 |
+
expect( PREFIX_COMMON_STORE ).toBe('@@MT/COMMON');
|
| 9 |
+
} );
|
| 10 |
+
} );
|
common/src/modules/data/editor/post-types.js
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
| 1 |
+
export const EVENT = 'tribe_events';
|
| 2 |
+
export const VENUE = 'tribe_venue';
|
| 3 |
+
export const ORGANIZER = 'tribe_organizer';
|
common/src/modules/data/forms/__tests__/__snapshots__/actions.test.js.snap
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
| 2 |
+
|
| 3 |
+
exports[`[STORE] - Form actions Add volatile action 1`] = `
|
| 4 |
+
Object {
|
| 5 |
+
"payload": Object {
|
| 6 |
+
"id": 20,
|
| 7 |
+
},
|
| 8 |
+
"type": "@@MT/COMMON/ADD_VOLATILE_ID",
|
| 9 |
+
}
|
| 10 |
+
`;
|
| 11 |
+
|
| 12 |
+
exports[`[STORE] - Form actions Clear form action 1`] = `
|
| 13 |
+
Object {
|
| 14 |
+
"payload": Object {
|
| 15 |
+
"id": 20,
|
| 16 |
+
},
|
| 17 |
+
"type": "@@MT/COMMON/CLEAR_FORM",
|
| 18 |
+
}
|
| 19 |
+
`;
|
| 20 |
+
|
| 21 |
+
exports[`[STORE] - Form actions Create draft entry 1`] = `
|
| 22 |
+
Object {
|
| 23 |
+
"payload": Object {
|
| 24 |
+
"fields": Object {
|
| 25 |
+
"title": "Modern Tribe",
|
| 26 |
+
},
|
| 27 |
+
"id": 20,
|
| 28 |
+
},
|
| 29 |
+
"type": "@@MT/COMMON/CREATE_FORM_DRAFT",
|
| 30 |
+
}
|
| 31 |
+
`;
|
| 32 |
+
|
| 33 |
+
exports[`[STORE] - Form actions Edit the entry action 1`] = `
|
| 34 |
+
Object {
|
| 35 |
+
"payload": Object {
|
| 36 |
+
"fields": Object {
|
| 37 |
+
"title": "Tribe",
|
| 38 |
+
},
|
| 39 |
+
"id": 20,
|
| 40 |
+
},
|
| 41 |
+
"type": "@@MT/COMMON/EDIT_FORM_ENTRY",
|
| 42 |
+
}
|
| 43 |
+
`;
|
| 44 |
+
|
| 45 |
+
exports[`[STORE] - Form actions Register form action 1`] = `
|
| 46 |
+
Object {
|
| 47 |
+
"payload": Object {
|
| 48 |
+
"id": 20,
|
| 49 |
+
"type": "tribe_organizers",
|
| 50 |
+
},
|
| 51 |
+
"type": "@@MT/COMMON/ADD_FORM",
|
| 52 |
+
}
|
| 53 |
+
`;
|
| 54 |
+
|
| 55 |
+
exports[`[STORE] - Form actions Remove volatile action 1`] = `
|
| 56 |
+
Object {
|
| 57 |
+
"payload": Object {
|
| 58 |
+
"id": 20,
|
| 59 |
+
},
|
| 60 |
+
"type": "@@MT/COMMON/REMOVE_VOLATILE_ID",
|
| 61 |
+
}
|
| 62 |
+
`;
|
| 63 |
+
|
| 64 |
+
exports[`[STORE] - Form actions Set saving action 1`] = `
|
| 65 |
+
Object {
|
| 66 |
+
"payload": Object {
|
| 67 |
+
"id": 20,
|
| 68 |
+
"saving": true,
|
| 69 |
+
},
|
| 70 |
+
"type": "@@MT/COMMON/SET_SAVING_FORM",
|
| 71 |
+
}
|
| 72 |
+
`;
|
| 73 |
+
|
| 74 |
+
exports[`[STORE] - Form actions Set saving action 2`] = `
|
| 75 |
+
Object {
|
| 76 |
+
"payload": Object {
|
| 77 |
+
"id": 20,
|
| 78 |
+
"saving": false,
|
| 79 |
+
},
|
| 80 |
+
"type": "@@MT/COMMON/SET_SAVING_FORM",
|
| 81 |
+
}
|
| 82 |
+
`;
|
| 83 |
+
|
| 84 |
+
exports[`[STORE] - Form actions Set submit form 1`] = `
|
| 85 |
+
Object {
|
| 86 |
+
"payload": Object {
|
| 87 |
+
"id": 20,
|
| 88 |
+
},
|
| 89 |
+
"type": "@@MT/COMMON/SUBMIT_FORM",
|
| 90 |
+
}
|
| 91 |
+
`;
|
| 92 |
+
|
| 93 |
+
exports[`[STORE] - form thunk actions Maybe remove entry action with details 1`] = `
|
| 94 |
+
Array [
|
| 95 |
+
Object {
|
| 96 |
+
"meta": Object {
|
| 97 |
+
"actions": Object {
|
| 98 |
+
"success": [Function],
|
| 99 |
+
},
|
| 100 |
+
"path": "tribe_venue/21",
|
| 101 |
+
},
|
| 102 |
+
"type": "@@MT/COMMON/WP_REQUEST",
|
| 103 |
+
},
|
| 104 |
+
]
|
| 105 |
+
`;
|
| 106 |
+
|
| 107 |
+
exports[`[STORE] - form thunk actions Maybe remove entry action without details 1`] = `Array []`;
|
| 108 |
+
|
| 109 |
+
exports[`[STORE] - form thunk actions Send the form action when creating 1`] = `
|
| 110 |
+
Array [
|
| 111 |
+
Object {
|
| 112 |
+
"meta": Object {
|
| 113 |
+
"actions": Object {
|
| 114 |
+
"error": [Function],
|
| 115 |
+
"start": [Function],
|
| 116 |
+
"success": [Function],
|
| 117 |
+
},
|
| 118 |
+
"params": Object {
|
| 119 |
+
"body": "{\\"title\\":\\"Modern Tribe\\"}",
|
| 120 |
+
"method": "POST",
|
| 121 |
+
},
|
| 122 |
+
"path": "tribe_organizer",
|
| 123 |
+
},
|
| 124 |
+
"type": "@@MT/COMMON/WP_REQUEST",
|
| 125 |
+
},
|
| 126 |
+
]
|
| 127 |
+
`;
|
| 128 |
+
|
| 129 |
+
exports[`[STORE] - form thunk actions Send the form when editing 1`] = `
|
| 130 |
+
Array [
|
| 131 |
+
Object {
|
| 132 |
+
"meta": Object {
|
| 133 |
+
"actions": Object {
|
| 134 |
+
"error": [Function],
|
| 135 |
+
"start": [Function],
|
| 136 |
+
"success": [Function],
|
| 137 |
+
},
|
| 138 |
+
"params": Object {
|
| 139 |
+
"body": "{\\"title\\":\\"Tribe\\"}",
|
| 140 |
+
"method": "PUT",
|
| 141 |
+
},
|
| 142 |
+
"path": "tribe_venue/21",
|
| 143 |
+
},
|
| 144 |
+
"type": "@@MT/COMMON/WP_REQUEST",
|
| 145 |
+
},
|
| 146 |
+
]
|
| 147 |
+
`;
|
common/src/modules/data/forms/__tests__/actions.test.js
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import configureStore from 'redux-mock-store';
|
| 5 |
+
import thunk from 'redux-thunk';
|
| 6 |
+
/**
|
| 7 |
+
* Internal dependencies
|
| 8 |
+
*/
|
| 9 |
+
import { actions } from '@moderntribe/common/data/forms';
|
| 10 |
+
|
| 11 |
+
const middlewares = [ thunk ];
|
| 12 |
+
const mockStore = configureStore( middlewares );
|
| 13 |
+
|
| 14 |
+
describe( '[STORE] - Form actions', () => {
|
| 15 |
+
test( 'Register form action', () => {
|
| 16 |
+
expect( actions.registerForm( 20, 'tribe_organizers' ) ).toMatchSnapshot();
|
| 17 |
+
} );
|
| 18 |
+
|
| 19 |
+
test( 'Create draft entry', () => {
|
| 20 |
+
expect( actions.createDraft( 20, { title: 'Modern Tribe' } ) ).toMatchSnapshot();
|
| 21 |
+
} );
|
| 22 |
+
|
| 23 |
+
test( 'Edit the entry action', () => {
|
| 24 |
+
expect( actions.editEntry( 20, { title: 'Tribe' } ) ).toMatchSnapshot();
|
| 25 |
+
} );
|
| 26 |
+
|
| 27 |
+
test( 'Clear form action', () => {
|
| 28 |
+
expect( actions.clearForm( 20 ) ).toMatchSnapshot();
|
| 29 |
+
} );
|
| 30 |
+
|
| 31 |
+
test( 'Set submit form', () => {
|
| 32 |
+
expect( actions.setSubmit( 20 ) ).toMatchSnapshot();
|
| 33 |
+
} );
|
| 34 |
+
|
| 35 |
+
test( 'Set saving action', () => {
|
| 36 |
+
expect( actions.setSaving( 20, true ) ).toMatchSnapshot();
|
| 37 |
+
expect( actions.setSaving( 20, false ) ).toMatchSnapshot();
|
| 38 |
+
} );
|
| 39 |
+
|
| 40 |
+
test( 'Add volatile action', () => {
|
| 41 |
+
expect( actions.addVolatile( 20 ) ).toMatchSnapshot();
|
| 42 |
+
} );
|
| 43 |
+
|
| 44 |
+
test( 'Remove volatile action', () => {
|
| 45 |
+
expect( actions.removeVolatile( 20 ) ).toMatchSnapshot();
|
| 46 |
+
} );
|
| 47 |
+
} );
|
| 48 |
+
|
| 49 |
+
describe( '[STORE] - form thunk actions', () => {
|
| 50 |
+
let store = {};
|
| 51 |
+
beforeAll( () => {
|
| 52 |
+
store = mockStore( {
|
| 53 |
+
events: {
|
| 54 |
+
},
|
| 55 |
+
forms: {
|
| 56 |
+
byId: {
|
| 57 |
+
20: {
|
| 58 |
+
create: true,
|
| 59 |
+
type: 'tribe_organizer',
|
| 60 |
+
fields: {},
|
| 61 |
+
},
|
| 62 |
+
21: {
|
| 63 |
+
create: false,
|
| 64 |
+
type: 'tribe_venue',
|
| 65 |
+
fields: {
|
| 66 |
+
id: 21,
|
| 67 |
+
},
|
| 68 |
+
},
|
| 69 |
+
},
|
| 70 |
+
volatile: [],
|
| 71 |
+
},
|
| 72 |
+
} );
|
| 73 |
+
} );
|
| 74 |
+
|
| 75 |
+
afterEach( () => store.clearActions() );
|
| 76 |
+
|
| 77 |
+
test( 'Send the form action when creating', () => {
|
| 78 |
+
store.dispatch( actions.sendForm( 20, { title: 'Modern Tribe' } ) );
|
| 79 |
+
expect( store.getActions() ).toMatchSnapshot();
|
| 80 |
+
} );
|
| 81 |
+
|
| 82 |
+
test( 'Send the form when editing', () => {
|
| 83 |
+
store.dispatch( actions.sendForm( 21, { title: 'Tribe' } ) );
|
| 84 |
+
expect( store.getActions() ).toMatchSnapshot();
|
| 85 |
+
} );
|
| 86 |
+
|
| 87 |
+
test( 'Maybe remove entry action without details', () => {
|
| 88 |
+
store.dispatch( actions.maybeRemoveEntry( 20, {} ) );
|
| 89 |
+
expect( store.getActions() ).toMatchSnapshot();
|
| 90 |
+
} );
|
| 91 |
+
|
| 92 |
+
test( 'Maybe remove entry action with details', () => {
|
| 93 |
+
store.dispatch( actions.maybeRemoveEntry( 21, { id: 21, title: 'Modern Tribe' } ) );
|
| 94 |
+
expect( store.getActions() ).toMatchSnapshot();
|
| 95 |
+
} );
|
| 96 |
+
} );
|
common/src/modules/data/forms/__tests__/reducer.test.js
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* Internal dependencies
|
| 3 |
+
*/
|
| 4 |
+
import reducer, { actions } from '@moderntribe/common/data/forms';
|
| 5 |
+
import form, { DEFAULT_STATE } from '@moderntribe/common/data/forms/reducers/form';
|
| 6 |
+
|
| 7 |
+
jest.mock( '@moderntribe/common/data/forms/reducers/form', () => {
|
| 8 |
+
const original = require.requireActual( '@moderntribe/common/data/forms/reducers/form' );
|
| 9 |
+
return {
|
| 10 |
+
__esModule: true,
|
| 11 |
+
...original,
|
| 12 |
+
default: jest.fn( ( state = original.DEFAULT_STATE ) => state ),
|
| 13 |
+
};
|
| 14 |
+
} );
|
| 15 |
+
|
| 16 |
+
jest.mock( '@moderntribe/common/data/forms/reducers/volatile', () => {
|
| 17 |
+
return {
|
| 18 |
+
__esModule: true,
|
| 19 |
+
default: jest.fn( ( state = [] ) => state ),
|
| 20 |
+
};
|
| 21 |
+
} );
|
| 22 |
+
|
| 23 |
+
describe( '[STORE] - form reducer', () => {
|
| 24 |
+
beforeEach( () => {
|
| 25 |
+
form.mockClear();
|
| 26 |
+
} );
|
| 27 |
+
|
| 28 |
+
it( 'Should return the default state', () => {
|
| 29 |
+
expect( reducer( undefined, {} ) ).toEqual( { byId: {}, volatile: [] } );
|
| 30 |
+
} );
|
| 31 |
+
|
| 32 |
+
it( 'Should add a new form', () => {
|
| 33 |
+
const state = {
|
| 34 |
+
byId: {},
|
| 35 |
+
volatile: [],
|
| 36 |
+
};
|
| 37 |
+
expect( reducer( state, actions.registerForm( 20, 'tribe_organizer' ) ) ).toEqual( {
|
| 38 |
+
byId: {
|
| 39 |
+
20: DEFAULT_STATE,
|
| 40 |
+
},
|
| 41 |
+
volatile: [],
|
| 42 |
+
} );
|
| 43 |
+
} );
|
| 44 |
+
|
| 45 |
+
it( 'Should pass the actions to the child reducer when block not present', () => {
|
| 46 |
+
const groupAction = [
|
| 47 |
+
actions.registerForm( 10, 'tribe_venue' ),
|
| 48 |
+
actions.editEntry( 20, { title: 'Modern tribe' } ),
|
| 49 |
+
actions.createDraft( 20, { title: 'Tribe' } ),
|
| 50 |
+
actions.setSubmit( 20 ),
|
| 51 |
+
actions.clearForm( 20 ),
|
| 52 |
+
actions.setSaving( 20, true ),
|
| 53 |
+
];
|
| 54 |
+
|
| 55 |
+
groupAction.forEach( ( action ) => {
|
| 56 |
+
reducer( {}, action );
|
| 57 |
+
expect( form ).toHaveBeenCalledWith( undefined, action );
|
| 58 |
+
expect( form ).toHaveBeenCalledTimes( 1 );
|
| 59 |
+
form.mockClear();
|
| 60 |
+
} );
|
| 61 |
+
} );
|
| 62 |
+
|
| 63 |
+
it( 'It should pass the block to the child reducer', () => {
|
| 64 |
+
const groupAction = [
|
| 65 |
+
actions.registerForm( 10, 'tribe_venue' ),
|
| 66 |
+
actions.editEntry( 20, { title: 'Modern tribe' } ),
|
| 67 |
+
actions.createDraft( 20, { title: 'Tribe' } ),
|
| 68 |
+
actions.setSubmit( 20 ),
|
| 69 |
+
actions.clearForm( 20 ),
|
| 70 |
+
actions.setSaving( 20, true ),
|
| 71 |
+
];
|
| 72 |
+
|
| 73 |
+
const state = {
|
| 74 |
+
byId: {
|
| 75 |
+
10: DEFAULT_STATE,
|
| 76 |
+
20: DEFAULT_STATE,
|
| 77 |
+
},
|
| 78 |
+
};
|
| 79 |
+
|
| 80 |
+
groupAction.forEach( ( action ) => {
|
| 81 |
+
reducer( state, action );
|
| 82 |
+
expect( form ).toHaveBeenCalledWith( DEFAULT_STATE, action );
|
| 83 |
+
expect( form ).toHaveBeenCalledTimes( 1 );
|
| 84 |
+
form.mockClear();
|
| 85 |
+
} );
|
| 86 |
+
} );
|
| 87 |
+
} );
|
| 88 |
+
|
common/src/modules/data/forms/__tests__/selectors.test.js
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import { selectors } from '@moderntribe/common/data/forms';
|
| 5 |
+
import { DEFAULT_STATE } from '@moderntribe/common/data/forms/reducers/form';
|
| 6 |
+
|
| 7 |
+
const state = {
|
| 8 |
+
events: {
|
| 9 |
+
},
|
| 10 |
+
forms: {
|
| 11 |
+
byId: {
|
| 12 |
+
99: {
|
| 13 |
+
...DEFAULT_STATE,
|
| 14 |
+
type: 'tribe_organizers',
|
| 15 |
+
create: true,
|
| 16 |
+
fields: {
|
| 17 |
+
name: 'Modern Tribe',
|
| 18 |
+
description: 'The Next Generation of Digital Agency',
|
| 19 |
+
},
|
| 20 |
+
},
|
| 21 |
+
100: {
|
| 22 |
+
...DEFAULT_STATE,
|
| 23 |
+
edit: true,
|
| 24 |
+
},
|
| 25 |
+
101: {
|
| 26 |
+
...DEFAULT_STATE,
|
| 27 |
+
submit: true,
|
| 28 |
+
},
|
| 29 |
+
102: {
|
| 30 |
+
...DEFAULT_STATE,
|
| 31 |
+
saving: true,
|
| 32 |
+
},
|
| 33 |
+
},
|
| 34 |
+
volatile: [ 100, 102 ],
|
| 35 |
+
},
|
| 36 |
+
};
|
| 37 |
+
|
| 38 |
+
describe( '[STORE] - Forms selectors', () => {
|
| 39 |
+
it( 'Should return the forms blocks', () => {
|
| 40 |
+
expect( selectors.formSelector( state, { name: 99 } ) ).toEqual( state.forms.byId[ '99' ] );
|
| 41 |
+
expect( selectors.formSelector( state, { name: 100 } ) ).toEqual( state.forms.byId[ '100' ] );
|
| 42 |
+
expect( selectors.formSelector( state, { name: 200 } ) ).toBe( undefined );
|
| 43 |
+
} );
|
| 44 |
+
|
| 45 |
+
it( 'Should return the form type', () => {
|
| 46 |
+
expect( selectors.getFormType( state, { name: 99 } ) ).toBe( 'tribe_organizers' );
|
| 47 |
+
expect( selectors.getFormType( state, { name: 100 } ) ).toBe( DEFAULT_STATE.type );
|
| 48 |
+
} );
|
| 49 |
+
|
| 50 |
+
it( 'Should return the edit value', () => {
|
| 51 |
+
expect( selectors.getFormEdit( state, { name: 100 } ) ).toBe( true );
|
| 52 |
+
expect( selectors.getFormEdit( state, { name: 99 } ) ).toBe( false );
|
| 53 |
+
expect( selectors.getFormEdit( state, { name: 101 } ) ).toBe( false );
|
| 54 |
+
expect( selectors.getFormEdit( state, { name: 102 } ) ).toBe( false );
|
| 55 |
+
} );
|
| 56 |
+
|
| 57 |
+
it( 'Should return the create value', () => {
|
| 58 |
+
expect( selectors.getFormCreate( state, { name: 99 } ) ).toBe( true );
|
| 59 |
+
expect( selectors.getFormCreate( state, { name: 100 } ) ).toBe( false );
|
| 60 |
+
expect( selectors.getFormCreate( state, { name: 101 } ) ).toBe( false );
|
| 61 |
+
expect( selectors.getFormCreate( state, { name: 102 } ) ).toBe( false );
|
| 62 |
+
} );
|
| 63 |
+
|
| 64 |
+
it( 'Should return the submit value', () => {
|
| 65 |
+
expect( selectors.getFormSubmit( state, { name: 101 } ) ).toBe( true );
|
| 66 |
+
expect( selectors.getFormSubmit( state, { name: 99 } ) ).toBe( false );
|
| 67 |
+
expect( selectors.getFormSubmit( state, { name: 100 } ) ).toBe( false );
|
| 68 |
+
expect( selectors.getFormSubmit( state, { name: 102 } ) ).toBe( false );
|
| 69 |
+
} );
|
| 70 |
+
|
| 71 |
+
it( 'Should return the saving value', () => {
|
| 72 |
+
expect( selectors.getFormSaving( state, { name: 102 } ) ).toBe( true );
|
| 73 |
+
expect( selectors.getFormSaving( state, { name: 99 } ) ).toBe( false );
|
| 74 |
+
expect( selectors.getFormSaving( state, { name: 100 } ) ).toBe( false );
|
| 75 |
+
expect( selectors.getFormSaving( state, { name: 101 } ) ).toBe( false );
|
| 76 |
+
} );
|
| 77 |
+
|
| 78 |
+
it( 'Should return the form fields', () => {
|
| 79 |
+
expect( selectors.getFormFields( state, { name: 99 } ) )
|
| 80 |
+
.toEqual( state.forms.byId[ '99' ].fields );
|
| 81 |
+
expect( selectors.getFormFields( state, { name: 100 } ) ).toEqual( {} );
|
| 82 |
+
expect( selectors.getFormFields( state, { name: 101 } ) ).toEqual( {} );
|
| 83 |
+
expect( selectors.getFormFields( state, { name: 102 } ) ).toEqual( {} );
|
| 84 |
+
} );
|
| 85 |
+
|
| 86 |
+
it( 'Should return the volatile fields', () => {
|
| 87 |
+
expect( selectors.getVolatile( state ) ).toEqual( [ 100, 102 ] );
|
| 88 |
+
} );
|
| 89 |
+
} );
|
common/src/modules/data/forms/__tests__/types.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* Internal dependencies
|
| 3 |
+
*/
|
| 4 |
+
import { types } from '@moderntribe/common/data/forms';
|
| 5 |
+
import { PREFIX_COMMON_STORE } from '@moderntribe/common/data/utils';
|
| 6 |
+
|
| 7 |
+
describe( '[STORE] - Form types', () => {
|
| 8 |
+
it( 'Should return the types values', () => {
|
| 9 |
+
expect( types.REMOVE_VOLATILE_ID ).toBe( `${ PREFIX_COMMON_STORE }/REMOVE_VOLATILE_ID` );
|
| 10 |
+
expect( types.ADD_VOLATILE_ID ).toBe( `${ PREFIX_COMMON_STORE }/ADD_VOLATILE_ID` );
|
| 11 |
+
expect( types.ADD_FORM ).toBe( `${ PREFIX_COMMON_STORE }/ADD_FORM` );
|
| 12 |
+
expect( types.SET_SAVING_FORM ).toBe( `${ PREFIX_COMMON_STORE }/SET_SAVING_FORM` );
|
| 13 |
+
expect( types.SUBMIT_FORM ).toBe( `${ PREFIX_COMMON_STORE }/SUBMIT_FORM` );
|
| 14 |
+
expect( types.CREATE_FORM_DRAFT ).toBe( `${ PREFIX_COMMON_STORE }/CREATE_FORM_DRAFT` );
|
| 15 |
+
expect( types.EDIT_FORM_ENTRY ).toBe( `${ PREFIX_COMMON_STORE }/EDIT_FORM_ENTRY` );
|
| 16 |
+
expect( types.SET_FORM_FIELDS ).toBe( `${ PREFIX_COMMON_STORE }/SET_FORM_FIELDS` );
|
| 17 |
+
expect( types.CLEAR_FORM ).toBe( `${ PREFIX_COMMON_STORE }/CLEAR_FORM` );
|
| 18 |
+
} );
|
| 19 |
+
} );
|
common/src/modules/data/forms/actions.js
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import { isEmpty, get } from 'lodash';
|
| 5 |
+
|
| 6 |
+
/**
|
| 7 |
+
* Internal dependencies
|
| 8 |
+
*/
|
| 9 |
+
import { actions as requestActions } from '@moderntribe/common/store/middlewares/request';
|
| 10 |
+
|
| 11 |
+
import * as types from './types';
|
| 12 |
+
import * as selectors from './selectors';
|
| 13 |
+
|
| 14 |
+
export const registerForm = ( id, type ) => ( {
|
| 15 |
+
type: types.ADD_FORM,
|
| 16 |
+
payload: {
|
| 17 |
+
id,
|
| 18 |
+
type,
|
| 19 |
+
},
|
| 20 |
+
} );
|
| 21 |
+
|
| 22 |
+
export const clearForm = ( id ) => ( {
|
| 23 |
+
type: types.CLEAR_FORM,
|
| 24 |
+
payload: {
|
| 25 |
+
id,
|
| 26 |
+
},
|
| 27 |
+
} );
|
| 28 |
+
|
| 29 |
+
export const createDraft = ( id, fields ) => ( {
|
| 30 |
+
type: types.CREATE_FORM_DRAFT,
|
| 31 |
+
payload: {
|
| 32 |
+
id,
|
| 33 |
+
fields,
|
| 34 |
+
},
|
| 35 |
+
} );
|
| 36 |
+
|
| 37 |
+
export const editEntry = ( id, fields ) => ( {
|
| 38 |
+
type: types.EDIT_FORM_ENTRY,
|
| 39 |
+
payload: {
|
| 40 |
+
id,
|
| 41 |
+
fields,
|
| 42 |
+
},
|
| 43 |
+
} );
|
| 44 |
+
|
| 45 |
+
export const setSubmit = ( id ) => ( {
|
| 46 |
+
type: types.SUBMIT_FORM,
|
| 47 |
+
payload: {
|
| 48 |
+
id,
|
| 49 |
+
},
|
| 50 |
+
} );
|
| 51 |
+
|
| 52 |
+
export const setSaving = ( id, saving ) => ( {
|
| 53 |
+
type: types.SET_SAVING_FORM,
|
| 54 |
+
payload: {
|
| 55 |
+
id,
|
| 56 |
+
saving,
|
| 57 |
+
},
|
| 58 |
+
} );
|
| 59 |
+
|
| 60 |
+
export const addVolatile = ( id ) => ( {
|
| 61 |
+
type: types.ADD_VOLATILE_ID,
|
| 62 |
+
payload: {
|
| 63 |
+
id,
|
| 64 |
+
},
|
| 65 |
+
} );
|
| 66 |
+
|
| 67 |
+
export const removeVolatile = ( id ) => ( {
|
| 68 |
+
type: types.REMOVE_VOLATILE_ID,
|
| 69 |
+
payload: {
|
| 70 |
+
id,
|
| 71 |
+
},
|
| 72 |
+
} );
|
| 73 |
+
|
| 74 |
+
export const sendForm = ( id, fields = {}, completed ) => ( dispatch, getState ) => {
|
| 75 |
+
const state = getState();
|
| 76 |
+
const props = { name: id };
|
| 77 |
+
const type = selectors.getFormType( state, props );
|
| 78 |
+
const create = selectors.getFormCreate( state, props );
|
| 79 |
+
const details = selectors.getFormFields( state, props );
|
| 80 |
+
const saving = selectors.getFormSaving( state, props );
|
| 81 |
+
|
| 82 |
+
if ( saving ) {
|
| 83 |
+
return;
|
| 84 |
+
}
|
| 85 |
+
|
| 86 |
+
const path = create
|
| 87 |
+
? `${ type }`
|
| 88 |
+
: `${ type }/${ details.id }`;
|
| 89 |
+
|
| 90 |
+
const options = {
|
| 91 |
+
path,
|
| 92 |
+
params: {
|
| 93 |
+
method: create ? 'POST' : 'PUT',
|
| 94 |
+
body: JSON.stringify( fields ),
|
| 95 |
+
},
|
| 96 |
+
actions: {
|
| 97 |
+
start: () => dispatch( setSaving( id, true ) ),
|
| 98 |
+
success: ( { body } ) => {
|
| 99 |
+
const postID = get( body, 'id', '' );
|
| 100 |
+
|
| 101 |
+
if ( create && postID ) {
|
| 102 |
+
dispatch( addVolatile( postID ) );
|
| 103 |
+
}
|
| 104 |
+
completed( body );
|
| 105 |
+
dispatch( clearForm( id ) );
|
| 106 |
+
dispatch( setSaving( id, false ) );
|
| 107 |
+
},
|
| 108 |
+
error: () => {
|
| 109 |
+
dispatch( clearForm( id ) );
|
| 110 |
+
dispatch( setSaving( id, false ) );
|
| 111 |
+
},
|
| 112 |
+
},
|
| 113 |
+
};
|
| 114 |
+
dispatch( requestActions.wpRequest( options ) );
|
| 115 |
+
};
|
| 116 |
+
|
| 117 |
+
const deleteEntry = ( dispatch ) => ( path ) => ( { body } ) => {
|
| 118 |
+
const { id, status } = body;
|
| 119 |
+
|
| 120 |
+
if ( 'draft' !== status ) {
|
| 121 |
+
dispatch( removeVolatile( id ) );
|
| 122 |
+
return;
|
| 123 |
+
}
|
| 124 |
+
|
| 125 |
+
const options = {
|
| 126 |
+
path,
|
| 127 |
+
params: {
|
| 128 |
+
method: 'DELETE',
|
| 129 |
+
},
|
| 130 |
+
actions: {
|
| 131 |
+
success: () => dispatch( removeVolatile( id ) ),
|
| 132 |
+
},
|
| 133 |
+
};
|
| 134 |
+
dispatch( requestActions.wpRequest( options ) );
|
| 135 |
+
};
|
| 136 |
+
|
| 137 |
+
export const maybeRemoveEntry = ( id, details = {} ) => ( dispatch, getState ) => {
|
| 138 |
+
const state = getState();
|
| 139 |
+
const type = selectors.getFormType( state, { name: id } );
|
| 140 |
+
|
| 141 |
+
if ( isEmpty( details ) ) {
|
| 142 |
+
return;
|
| 143 |
+
}
|
| 144 |
+
|
| 145 |
+
const path = `${ type }/${ details.id }`;
|
| 146 |
+
const options = {
|
| 147 |
+
path,
|
| 148 |
+
actions: {
|
| 149 |
+
success: deleteEntry( dispatch )( path ),
|
| 150 |
+
},
|
| 151 |
+
};
|
| 152 |
+
dispatch( requestActions.wpRequest( options ) );
|
| 153 |
+
};
|
common/src/modules/data/forms/index.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* Internal dependencies
|
| 3 |
+
*/
|
| 4 |
+
import reducer from './reducer';
|
| 5 |
+
|
| 6 |
+
import * as types from './types';
|
| 7 |
+
import * as actions from './actions';
|
| 8 |
+
import * as selectors from './selectors';
|
| 9 |
+
|
| 10 |
+
export default reducer;
|
| 11 |
+
|
| 12 |
+
export { types, actions, selectors };
|
common/src/modules/data/forms/reducer.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import { combineReducers } from 'redux';
|
| 5 |
+
|
| 6 |
+
/**
|
| 7 |
+
* Internal dependencies
|
| 8 |
+
*/
|
| 9 |
+
import * as types from './types';
|
| 10 |
+
import { form, volatile } from './reducers';
|
| 11 |
+
|
| 12 |
+
const byId = ( state = {}, action ) => {
|
| 13 |
+
switch ( action.type ) {
|
| 14 |
+
case types.ADD_FORM:
|
| 15 |
+
case types.CLEAR_FORM:
|
| 16 |
+
case types.SET_FORM_FIELDS:
|
| 17 |
+
case types.CREATE_FORM_DRAFT:
|
| 18 |
+
case types.EDIT_FORM_ENTRY:
|
| 19 |
+
case types.SUBMIT_FORM:
|
| 20 |
+
case types.SET_SAVING_FORM:
|
| 21 |
+
return {
|
| 22 |
+
...state,
|
| 23 |
+
[ action.payload.id ]: form( state[ action.payload.id ], action ),
|
| 24 |
+
};
|
| 25 |
+
default:
|
| 26 |
+
return state;
|
| 27 |
+
}
|
| 28 |
+
};
|
| 29 |
+
|
| 30 |
+
export default combineReducers( {
|
| 31 |
+
byId,
|
| 32 |
+
volatile,
|
| 33 |
+
} );
|
common/src/modules/data/forms/reducers/__tests__/__snapshots__/form.test.js.snap
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
| 2 |
+
|
| 3 |
+
exports[`[STORE] - form reducer Should add a new form 1`] = `
|
| 4 |
+
Object {
|
| 5 |
+
"create": false,
|
| 6 |
+
"edit": false,
|
| 7 |
+
"fields": Object {},
|
| 8 |
+
"saving": false,
|
| 9 |
+
"submit": false,
|
| 10 |
+
"type": "tribe_organizers",
|
| 11 |
+
}
|
| 12 |
+
`;
|
| 13 |
+
|
| 14 |
+
exports[`[STORE] - form reducer Should clear a form 1`] = `
|
| 15 |
+
Object {
|
| 16 |
+
"create": false,
|
| 17 |
+
"edit": false,
|
| 18 |
+
"fields": Object {},
|
| 19 |
+
"saving": false,
|
| 20 |
+
"submit": false,
|
| 21 |
+
"type": "tribe_organizers",
|
| 22 |
+
}
|
| 23 |
+
`;
|
| 24 |
+
|
| 25 |
+
exports[`[STORE] - form reducer Should create a form draft 1`] = `
|
| 26 |
+
Object {
|
| 27 |
+
"create": true,
|
| 28 |
+
"edit": false,
|
| 29 |
+
"fields": Object {
|
| 30 |
+
"id": 20,
|
| 31 |
+
"title": "Modern Tribe",
|
| 32 |
+
},
|
| 33 |
+
"saving": false,
|
| 34 |
+
"submit": false,
|
| 35 |
+
"type": "tribe_events",
|
| 36 |
+
}
|
| 37 |
+
`;
|
| 38 |
+
|
| 39 |
+
exports[`[STORE] - form reducer Should edit the form entry 1`] = `
|
| 40 |
+
Object {
|
| 41 |
+
"create": false,
|
| 42 |
+
"edit": true,
|
| 43 |
+
"fields": Object {
|
| 44 |
+
"description": "",
|
| 45 |
+
"title": "Tribe",
|
| 46 |
+
},
|
| 47 |
+
"saving": false,
|
| 48 |
+
"submit": false,
|
| 49 |
+
"type": "tribe_events",
|
| 50 |
+
}
|
| 51 |
+
`;
|
| 52 |
+
|
| 53 |
+
exports[`[STORE] - form reducer Should submit the form 1`] = `
|
| 54 |
+
Object {
|
| 55 |
+
"create": false,
|
| 56 |
+
"edit": false,
|
| 57 |
+
"fields": Object {},
|
| 58 |
+
"saving": false,
|
| 59 |
+
"submit": true,
|
| 60 |
+
"type": "tribe_events",
|
| 61 |
+
}
|
| 62 |
+
`;
|
| 63 |
+
|
| 64 |
+
exports[`[STORE] - form reducer Should toggle the saving form flag 1`] = `
|
| 65 |
+
Object {
|
| 66 |
+
"create": false,
|
| 67 |
+
"edit": false,
|
| 68 |
+
"fields": Object {},
|
| 69 |
+
"saving": true,
|
| 70 |
+
"submit": false,
|
| 71 |
+
"type": "tribe_events",
|
| 72 |
+
}
|
| 73 |
+
`;
|
| 74 |
+
|
| 75 |
+
exports[`[STORE] - form reducer Should toggle the saving form flag 2`] = `
|
| 76 |
+
Object {
|
| 77 |
+
"create": false,
|
| 78 |
+
"edit": false,
|
| 79 |
+
"fields": Object {},
|
| 80 |
+
"saving": false,
|
| 81 |
+
"submit": false,
|
| 82 |
+
"type": "tribe_events",
|
| 83 |
+
}
|
| 84 |
+
`;
|
common/src/modules/data/forms/reducers/__tests__/form.test.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* Internal dependencies
|
| 3 |
+
*/
|
| 4 |
+
import { form } from '@moderntribe/common/data/forms/reducers';
|
| 5 |
+
import { actions } from '@moderntribe/common/data/forms';
|
| 6 |
+
import { DEFAULT_STATE } from '@moderntribe/common/data/forms/reducers/form';
|
| 7 |
+
|
| 8 |
+
describe( '[STORE] - form reducer', () => {
|
| 9 |
+
it( 'Should return the default state', () => {
|
| 10 |
+
expect( form( undefined, {} ) ).toEqual( DEFAULT_STATE );
|
| 11 |
+
} );
|
| 12 |
+
|
| 13 |
+
it( 'Should add a new form', () => {
|
| 14 |
+
expect( form( DEFAULT_STATE, actions.registerForm( 20, 'tribe_organizers' ) ) ).toMatchSnapshot();
|
| 15 |
+
} );
|
| 16 |
+
|
| 17 |
+
it( 'Should clear a form', () => {
|
| 18 |
+
const state = {
|
| 19 |
+
...DEFAULT_STATE,
|
| 20 |
+
type: 'tribe_organizers',
|
| 21 |
+
};
|
| 22 |
+
expect( form( state, actions.clearForm( 20 ) ) ).toMatchSnapshot();
|
| 23 |
+
} );
|
| 24 |
+
|
| 25 |
+
it( 'Should create a form draft', () => {
|
| 26 |
+
const fields = {
|
| 27 |
+
id: 20,
|
| 28 |
+
title: 'Modern Tribe',
|
| 29 |
+
};
|
| 30 |
+
expect( form( DEFAULT_STATE, actions.createDraft( 20, fields ) ) ).toMatchSnapshot();
|
| 31 |
+
} );
|
| 32 |
+
|
| 33 |
+
it( 'Should toggle the saving form flag', () => {
|
| 34 |
+
expect( form( DEFAULT_STATE, actions.setSaving( 20, true ) ) ).toMatchSnapshot();
|
| 35 |
+
expect( form( DEFAULT_STATE, actions.setSaving( 20, false ) ) ).toMatchSnapshot();
|
| 36 |
+
} );
|
| 37 |
+
|
| 38 |
+
it( 'Should edit the form entry', () => {
|
| 39 |
+
const fields = {
|
| 40 |
+
title: 'Tribe',
|
| 41 |
+
description: '',
|
| 42 |
+
};
|
| 43 |
+
expect( form( DEFAULT_STATE, actions.editEntry( 20, fields ) ) ).toMatchSnapshot();
|
| 44 |
+
} );
|
| 45 |
+
|
| 46 |
+
it( 'Should submit the form', () => {
|
| 47 |
+
expect( form( DEFAULT_STATE, actions.setSubmit( 20 ) ) ).toMatchSnapshot();
|
| 48 |
+
} );
|
| 49 |
+
} );
|
common/src/modules/data/forms/reducers/__tests__/volatile.test.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* Internal dependencies
|
| 3 |
+
*/
|
| 4 |
+
import { volatile } from '@moderntribe/common/data/forms/reducers';
|
| 5 |
+
import { actions } from '@moderntribe/common/data/forms';
|
| 6 |
+
|
| 7 |
+
describe( '[STORE] - Volatile reducer', () => {
|
| 8 |
+
it( 'Should return the default state', () => {
|
| 9 |
+
expect( volatile( undefined, {} ) ).toEqual( [] );
|
| 10 |
+
} );
|
| 11 |
+
|
| 12 |
+
it( 'Should add a new volatile value', () => {
|
| 13 |
+
expect( volatile( [], actions.addVolatile( 20 ) ) ).toEqual( [ 20 ] );
|
| 14 |
+
expect( volatile( [ 20 ], actions.addVolatile( 10 ) ) ).toEqual( [ 20, 10 ] );
|
| 15 |
+
} );
|
| 16 |
+
|
| 17 |
+
it( 'Should remove a volatile value', () => {
|
| 18 |
+
expect( volatile( [], actions.removeVolatile( 20 ) ) ).toEqual( [] );
|
| 19 |
+
expect( volatile( [ 20, 10 ], actions.removeVolatile( 20 ) ) ).toEqual( [ 10 ] );
|
| 20 |
+
expect( volatile( [ 20, 10 ], actions.removeVolatile( 10 ) ) ).toEqual( [ 20 ] );
|
| 21 |
+
expect( volatile( [ 10 ], actions.removeVolatile( 10 ) ) ).toEqual( [] );
|
| 22 |
+
} );
|
| 23 |
+
} );
|
common/src/modules/data/forms/reducers/form.js
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* Internal dependencies
|
| 3 |
+
*/
|
| 4 |
+
import { EVENT } from '@moderntribe/common/data/editor/post-types';
|
| 5 |
+
import * as types from '@moderntribe/common/data/forms/types';
|
| 6 |
+
|
| 7 |
+
export const DEFAULT_STATE = {
|
| 8 |
+
edit: false,
|
| 9 |
+
create: false,
|
| 10 |
+
submit: false,
|
| 11 |
+
saving: false,
|
| 12 |
+
fields: {},
|
| 13 |
+
type: EVENT,
|
| 14 |
+
};
|
| 15 |
+
|
| 16 |
+
export default ( state = DEFAULT_STATE, action ) => {
|
| 17 |
+
switch ( action.type ) {
|
| 18 |
+
case types.ADD_FORM:
|
| 19 |
+
return {
|
| 20 |
+
...state,
|
| 21 |
+
type: action.payload.type,
|
| 22 |
+
};
|
| 23 |
+
case types.CLEAR_FORM:
|
| 24 |
+
return {
|
| 25 |
+
...state,
|
| 26 |
+
...DEFAULT_STATE,
|
| 27 |
+
type: state.type,
|
| 28 |
+
};
|
| 29 |
+
case types.CREATE_FORM_DRAFT:
|
| 30 |
+
return {
|
| 31 |
+
...state,
|
| 32 |
+
submit: false,
|
| 33 |
+
edit: false,
|
| 34 |
+
create: true,
|
| 35 |
+
fields: action.payload.fields,
|
| 36 |
+
};
|
| 37 |
+
case types.SET_SAVING_FORM:
|
| 38 |
+
return {
|
| 39 |
+
...state,
|
| 40 |
+
saving: action.payload.saving,
|
| 41 |
+
};
|
| 42 |
+
case types.EDIT_FORM_ENTRY:
|
| 43 |
+
return {
|
| 44 |
+
...state,
|
| 45 |
+
create: false,
|
| 46 |
+
submit: false,
|
| 47 |
+
edit: true,
|
| 48 |
+
fields: action.payload.fields,
|
| 49 |
+
};
|
| 50 |
+
case types.SUBMIT_FORM:
|
| 51 |
+
return {
|
| 52 |
+
...state,
|
| 53 |
+
submit: true,
|
| 54 |
+
};
|
| 55 |
+
default:
|
| 56 |
+
return state;
|
| 57 |
+
}
|
| 58 |
+
};
|
common/src/modules/data/forms/reducers/index.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
| 1 |
+
export { default as form } from './form';
|
| 2 |
+
export { default as volatile } from './volatile';
|
common/src/modules/data/forms/reducers/volatile.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* Internal dependencies
|
| 3 |
+
*/
|
| 4 |
+
import * as types from '@moderntribe/common/data/forms/types';
|
| 5 |
+
|
| 6 |
+
export default ( state = [], action ) => {
|
| 7 |
+
switch ( action.type ) {
|
| 8 |
+
case types.ADD_VOLATILE_ID:
|
| 9 |
+
return [ ...state, action.payload.id ];
|
| 10 |
+
case types.REMOVE_VOLATILE_ID:
|
| 11 |
+
return state.filter( ( id ) => id !== action.payload.id );
|
| 12 |
+
default:
|
| 13 |
+
return state;
|
| 14 |
+
}
|
| 15 |
+
};
|
common/src/modules/data/forms/selectors.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import { createSelector } from 'reselect';
|
| 5 |
+
import { DEFAULT_STATE } from './reducers/form';
|
| 6 |
+
|
| 7 |
+
export const formSelector = ( state, props ) => state.forms.byId[ props.name ];
|
| 8 |
+
|
| 9 |
+
export const getFormType = createSelector(
|
| 10 |
+
[ formSelector ],
|
| 11 |
+
( block ) => block ? block.type : DEFAULT_STATE.type
|
| 12 |
+
);
|
| 13 |
+
|
| 14 |
+
export const getFormEdit = createSelector(
|
| 15 |
+
[ formSelector ],
|
| 16 |
+
( block ) => block ? block.edit : DEFAULT_STATE.edit
|
| 17 |
+
);
|
| 18 |
+
|
| 19 |
+
export const getFormCreate = createSelector(
|
| 20 |
+
[ formSelector ],
|
| 21 |
+
( block ) => block ? block.create : DEFAULT_STATE.create,
|
| 22 |
+
);
|
| 23 |
+
|
| 24 |
+
export const getFormSubmit = createSelector(
|
| 25 |
+
[ formSelector ],
|
| 26 |
+
( block ) => block ? block.submit : DEFAULT_STATE.submit
|
| 27 |
+
);
|
| 28 |
+
|
| 29 |
+
export const getFormFields = createSelector(
|
| 30 |
+
[ formSelector ],
|
| 31 |
+
( block ) => block ? block.fields : DEFAULT_STATE.fields,
|
| 32 |
+
);
|
| 33 |
+
|
| 34 |
+
export const getFormSaving = createSelector(
|
| 35 |
+
[ formSelector ],
|
| 36 |
+
( block ) => block ? block.saving : DEFAULT_STATE.saving
|
| 37 |
+
);
|
| 38 |
+
|
| 39 |
+
export const getVolatile = ( state ) => state.forms.volatile;
|
common/src/modules/data/forms/types.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* Internal dependencies
|
| 3 |
+
*/
|
| 4 |
+
import { PREFIX_COMMON_STORE } from '@moderntribe/common/data/utils';
|
| 5 |
+
|
| 6 |
+
export const ADD_FORM = `${ PREFIX_COMMON_STORE }/ADD_FORM`;
|
| 7 |
+
export const SET_FORM_FIELDS = `${ PREFIX_COMMON_STORE }/SET_FORM_FIELDS`;
|
| 8 |
+
export const CREATE_FORM_DRAFT = `${ PREFIX_COMMON_STORE }/CREATE_FORM_DRAFT`;
|
| 9 |
+
export const EDIT_FORM_ENTRY = `${ PREFIX_COMMON_STORE }/EDIT_FORM_ENTRY`;
|
| 10 |
+
export const SUBMIT_FORM = `${ PREFIX_COMMON_STORE }/SUBMIT_FORM`;
|
| 11 |
+
export const CLEAR_FORM = `${ PREFIX_COMMON_STORE }/CLEAR_FORM`;
|
| 12 |
+
export const SET_SAVING_FORM = `${ PREFIX_COMMON_STORE }/SET_SAVING_FORM`;
|
| 13 |
+
|
| 14 |
+
export const ADD_VOLATILE_ID = `${ PREFIX_COMMON_STORE }/ADD_VOLATILE_ID`;
|
| 15 |
+
export const REMOVE_VOLATILE_ID = `${ PREFIX_COMMON_STORE }/REMOVE_VOLATILE_ID`;
|
common/src/modules/data/index.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* Internal Dependencies
|
| 3 |
+
*/
|
| 4 |
+
import * as editor from './editor/post-types';
|
| 5 |
+
import * as forms from './forms';
|
| 6 |
+
import * as plugins from './plugins';
|
| 7 |
+
export { default } from './reducers';
|
| 8 |
+
|
| 9 |
+
export { editor, forms, plugins };
|
common/src/modules/data/plugins/__tests__/__snapshots__/actions.test.js.snap
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
| 2 |
+
|
| 3 |
+
exports[`Plugin actions Add Plugin 1`] = `
|
| 4 |
+
Object {
|
| 5 |
+
"payload": Object {
|
| 6 |
+
"name": "events",
|
| 7 |
+
},
|
| 8 |
+
"type": "@@MT/COMMON/ADD_PLUGIN",
|
| 9 |
+
}
|
| 10 |
+
`;
|
| 11 |
+
|
| 12 |
+
exports[`Plugin actions Remove Plugin 1`] = `
|
| 13 |
+
Object {
|
| 14 |
+
"payload": Object {
|
| 15 |
+
"name": "events",
|
| 16 |
+
},
|
| 17 |
+
"type": "@@MT/COMMON/REMOVE_PLUGIN",
|
| 18 |
+
}
|
| 19 |
+
`;
|
common/src/modules/data/plugins/__tests__/actions.test.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* Internal dependencies
|
| 3 |
+
*/
|
| 4 |
+
import { actions } from '@moderntribe/common/data/plugins';
|
| 5 |
+
|
| 6 |
+
describe( 'Plugin actions', () => {
|
| 7 |
+
test( 'Add Plugin', () => {
|
| 8 |
+
expect( actions.addPlugin( 'events' ) ).toMatchSnapshot();
|
| 9 |
+
} );
|
| 10 |
+
|
| 11 |
+
test( 'Remove Plugin', () => {
|
| 12 |
+
expect( actions.removePlugin( 'events' ) ).toMatchSnapshot();
|
| 13 |
+
} );
|
| 14 |
+
} );
|
common/src/modules/data/plugins/__tests__/reducer.test.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* Internal dependencies
|
| 3 |
+
*/
|
| 4 |
+
import reducer, { actions } from '@moderntribe/common/data/plugins';
|
| 5 |
+
|
| 6 |
+
describe( 'Plugins reducer', () => {
|
| 7 |
+
it( 'Should return the default state', () => {
|
| 8 |
+
expect( reducer( undefined, {} ) ).toEqual( [] );
|
| 9 |
+
} );
|
| 10 |
+
|
| 11 |
+
it( 'Should add a new plugin as active', () => {
|
| 12 |
+
expect( reducer( {}, actions.addPlugin( 'events' ) ) ).toEqual( [ 'events' ] );
|
| 13 |
+
} );
|
| 14 |
+
|
| 15 |
+
it( 'Should avoid adding duplicates entries', () => {
|
| 16 |
+
const state = reducer( {}, actions.addPlugin( 'events' ) );
|
| 17 |
+
expect( reducer( state, actions.addPlugin( 'events' ) ) ).toEqual( [ 'events' ] );
|
| 18 |
+
} );
|
| 19 |
+
|
| 20 |
+
it( 'Should remove the plugin from the reducer', () => {
|
| 21 |
+
const state = reducer( {}, actions.addPlugin( 'events' ) );
|
| 22 |
+
expect( state ).toEqual( [ 'events' ] );
|
| 23 |
+
expect( reducer( state, actions.removePlugin( 'events' ) ) ).toEqual( [] );
|
| 24 |
+
} );
|
| 25 |
+
} );
|
common/src/modules/data/plugins/__tests__/selectors.test.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* Internal dependencies
|
| 3 |
+
*/
|
| 4 |
+
import { selectors } from '@moderntribe/common/data/plugins';
|
| 5 |
+
|
| 6 |
+
describe( 'Plugin selectors', () => {
|
| 7 |
+
let state;
|
| 8 |
+
|
| 9 |
+
beforeEach( () => {
|
| 10 |
+
state = {
|
| 11 |
+
plugins: [ 'events' ],
|
| 12 |
+
};
|
| 13 |
+
} );
|
| 14 |
+
|
| 15 |
+
it( 'should have plugin', () => {
|
| 16 |
+
expect( selectors.hasPlugin( state, 'events' ) ).toEqual( true );
|
| 17 |
+
expect( selectors.hasPlugin( state )( 'events' ) ).toEqual( true );
|
| 18 |
+
} );
|
| 19 |
+
it( 'should not have plugin', () => {
|
| 20 |
+
expect( selectors.hasPlugin( state, 'events-pro' ) ).toEqual( false );
|
| 21 |
+
expect( selectors.hasPlugin( state )( 'events-pro' ) ).toEqual( false );
|
| 22 |
+
} );
|
| 23 |
+
} );
|
common/src/modules/data/plugins/__tests__/types.test.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* Internal dependencies
|
| 3 |
+
*/
|
| 4 |
+
import { PREFIX_COMMON_STORE } from '@moderntribe/common/data/utils';
|
| 5 |
+
import { types } from '@moderntribe/common/data/plugins';
|
| 6 |
+
|
| 7 |
+
describe( 'Plugin types', () => {
|
| 8 |
+
it( 'Should return the types with a prefix', () => {
|
| 9 |
+
expect( types.ADD_PLUGIN ).toBe( `${ PREFIX_COMMON_STORE }/ADD_PLUGIN` );
|
| 10 |
+
expect( types.REMOVE_PLUGIN ).toBe( `${ PREFIX_COMMON_STORE }/REMOVE_PLUGIN` );
|
| 11 |
+
} );
|
| 12 |
+
} );
|
common/src/modules/data/plugins/actions.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* Internal dependencies
|
| 3 |
+
*/
|
| 4 |
+
import * as types from './types';
|
| 5 |
+
|
| 6 |
+
export const addPlugin = ( name ) => ( {
|
| 7 |
+
type: types.ADD_PLUGIN,
|
| 8 |
+
payload: {
|
| 9 |
+
name,
|
| 10 |
+
},
|
| 11 |
+
} );
|
| 12 |
+
|
| 13 |
+
export const removePlugin = ( name ) => ( {
|
| 14 |
+
type: types.REMOVE_PLUGIN,
|
| 15 |
+
payload: {
|
| 16 |
+
name,
|
| 17 |
+
},
|
| 18 |
+
} );
|
common/src/modules/data/plugins/constants.js
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
export const EVENTS_PLUGIN = 'events';
|
| 2 |
+
export const EVENTS_PRO_PLUGIN = 'events-pro';
|
| 3 |
+
export const TICKETS = 'tickets';
|
| 4 |
+
export const TICKETS_PLUS = 'tickets-plus';
|
common/src/modules/data/plugins/index.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* Internal dependencies
|
| 3 |
+
*/
|
| 4 |
+
import reducer from './reducer';
|
| 5 |
+
import * as types from './types';
|
| 6 |
+
import * as actions from './actions';
|
| 7 |
+
import * as selectors from './selectors';
|
| 8 |
+
import * as constants from './constants';
|
| 9 |
+
import * as proptypes from './proptypes';
|
| 10 |
+
|
| 11 |
+
export default reducer;
|
| 12 |
+
export { types, actions, selectors, constants, proptypes };
|
common/src/modules/data/plugins/proptypes.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External Dependencies
|
| 3 |
+
*/
|
| 4 |
+
import PropTypes from 'prop-types';
|
| 5 |
+
|
| 6 |
+
//
|
| 7 |
+
// ─── VENDOR ─────────────────────────────────────────────────────────────────────
|
| 8 |
+
//
|
| 9 |
+
|
| 10 |
+
export const ReactSelectOption = PropTypes.shape( {
|
| 11 |
+
label: PropTypes.string.isRequired,
|
| 12 |
+
value: PropTypes.any.isRequired,
|
| 13 |
+
} );
|
| 14 |
+
|
| 15 |
+
export const ReactSelectOptions = PropTypes.arrayOf( ReactSelectOption );
|
common/src/modules/data/plugins/reducer.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import { uniq } from 'lodash';
|
| 5 |
+
|
| 6 |
+
/**
|
| 7 |
+
* Internal dependencies
|
| 8 |
+
*/
|
| 9 |
+
import { types } from '@moderntribe/common/data/plugins';
|
| 10 |
+
|
| 11 |
+
export default ( state = [], action ) => {
|
| 12 |
+
switch ( action.type ) {
|
| 13 |
+
case types.ADD_PLUGIN:
|
| 14 |
+
return uniq( [ ...state, action.payload.name ] );
|
| 15 |
+
case types.REMOVE_PLUGIN:
|
| 16 |
+
return [ ...state ].filter( ( pluginName ) => pluginName !== action.payload.name );
|
| 17 |
+
default:
|
| 18 |
+
return state;
|
| 19 |
+
}
|
| 20 |
+
};
|
common/src/modules/data/plugins/selectors.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import { includes } from 'lodash';
|
| 5 |
+
import { curry } from 'lodash/fp';
|
| 6 |
+
|
| 7 |
+
export const getPlugins = ( state ) => state.plugins;
|
| 8 |
+
|
| 9 |
+
export const hasPlugin = curry( ( state, plugin ) => includes( getPlugins( state ), plugin ) );
|
common/src/modules/data/plugins/types.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* Internal dependencies
|
| 3 |
+
*/
|
| 4 |
+
import { PREFIX_COMMON_STORE } from '@moderntribe/common/data/utils';
|
| 5 |
+
|
| 6 |
+
export const ADD_PLUGIN = `${ PREFIX_COMMON_STORE }/ADD_PLUGIN`;
|
| 7 |
+
export const REMOVE_PLUGIN = `${ PREFIX_COMMON_STORE }/REMOVE_PLUGIN`;
|
common/src/modules/data/reducers.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import { setupCreateReducer } from '@nfen/redux-reducer-injector';
|
| 5 |
+
import forms from './forms';
|
| 6 |
+
|
| 7 |
+
/**
|
| 8 |
+
* Internal dependencies
|
| 9 |
+
*/
|
| 10 |
+
import plugins from './plugins';
|
| 11 |
+
|
| 12 |
+
export default setupCreateReducer( {
|
| 13 |
+
plugins,
|
| 14 |
+
forms,
|
| 15 |
+
} );
|
common/src/modules/data/utils.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
| 1 |
+
export const PREFIX_COMMON_STORE = '@@MT/COMMON';
|
common/src/modules/elements/accordion/__tests__/__snapshots__/element.test.js.snap
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
| 2 |
+
|
| 3 |
+
exports[`Accordion Element renders an accordion 1`] = `
|
| 4 |
+
<div
|
| 5 |
+
aria-multiselectable="true"
|
| 6 |
+
className="tribe-editor__accordion"
|
| 7 |
+
role="tablist"
|
| 8 |
+
>
|
| 9 |
+
<article
|
| 10 |
+
className="tribe-editor__accordion__row"
|
| 11 |
+
>
|
| 12 |
+
<button
|
| 13 |
+
aria-controls="accordion-content-123"
|
| 14 |
+
aria-expanded="false"
|
| 15 |
+
aria-selected="false"
|
| 16 |
+
className="tribe-editor__button tribe-editor__accordion__row-header header-class"
|
| 17 |
+
id="accordion-header-123"
|
| 18 |
+
onClick={[Function]}
|
| 19 |
+
role="tab"
|
| 20 |
+
type="button"
|
| 21 |
+
>
|
| 22 |
+
this is header
|
| 23 |
+
</button>
|
| 24 |
+
<div
|
| 25 |
+
aria-hidden="true"
|
| 26 |
+
aria-labelledby="accordion-header-123"
|
| 27 |
+
className="tribe-editor__accordion__row-content content-class"
|
| 28 |
+
id="accordion-content-123"
|
| 29 |
+
role="tabpanel"
|
| 30 |
+
>
|
| 31 |
+
this is a content
|
| 32 |
+
</div>
|
| 33 |
+
</article>
|
| 34 |
+
</div>
|
| 35 |
+
`;
|
| 36 |
+
|
| 37 |
+
exports[`Accordion Element renders an accordion with wrapper class 1`] = `
|
| 38 |
+
<div
|
| 39 |
+
aria-multiselectable="true"
|
| 40 |
+
className="tribe-editor__accordion test-class"
|
| 41 |
+
role="tablist"
|
| 42 |
+
>
|
| 43 |
+
<article
|
| 44 |
+
className="tribe-editor__accordion__row"
|
| 45 |
+
>
|
| 46 |
+
<button
|
| 47 |
+
aria-controls="accordion-content-123"
|
| 48 |
+
aria-expanded="false"
|
| 49 |
+
aria-selected="false"
|
| 50 |
+
className="tribe-editor__button tribe-editor__accordion__row-header header-class"
|
| 51 |
+
id="accordion-header-123"
|
| 52 |
+
onClick={[Function]}
|
| 53 |
+
role="tab"
|
| 54 |
+
type="button"
|
| 55 |
+
>
|
| 56 |
+
this is header
|
| 57 |
+
</button>
|
| 58 |
+
<div
|
| 59 |
+
aria-hidden="true"
|
| 60 |
+
aria-labelledby="accordion-header-123"
|
| 61 |
+
className="tribe-editor__accordion__row-content content-class"
|
| 62 |
+
id="accordion-content-123"
|
| 63 |
+
role="tabpanel"
|
| 64 |
+
>
|
| 65 |
+
this is a content
|
| 66 |
+
</div>
|
| 67 |
+
</article>
|
| 68 |
+
</div>
|
| 69 |
+
`;
|
| 70 |
+
|
| 71 |
+
exports[`Accordion Element renders null 1`] = `null`;
|
common/src/modules/elements/accordion/__tests__/element.test.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import React from 'react';
|
| 5 |
+
import renderer from 'react-test-renderer';
|
| 6 |
+
import { noop } from 'lodash';
|
| 7 |
+
|
| 8 |
+
/**
|
| 9 |
+
* Internal dependencies
|
| 10 |
+
*/
|
| 11 |
+
import { Accordion } from '@moderntribe/common/elements';
|
| 12 |
+
|
| 13 |
+
let rows;
|
| 14 |
+
|
| 15 |
+
describe( 'Accordion Element', () => {
|
| 16 |
+
beforeEach( () => {
|
| 17 |
+
rows = [
|
| 18 |
+
{
|
| 19 |
+
accordionId: '123',
|
| 20 |
+
content: 'this is a content',
|
| 21 |
+
contentClassName: 'content-class',
|
| 22 |
+
header: 'this is header',
|
| 23 |
+
headerClassName: 'header-class',
|
| 24 |
+
onClick: noop,
|
| 25 |
+
onClose: noop,
|
| 26 |
+
onOpen: noop,
|
| 27 |
+
},
|
| 28 |
+
];
|
| 29 |
+
} );
|
| 30 |
+
|
| 31 |
+
it( 'renders null', () => {
|
| 32 |
+
const component = renderer.create( <Accordion /> );
|
| 33 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 34 |
+
} );
|
| 35 |
+
|
| 36 |
+
it( 'renders an accordion', () => {
|
| 37 |
+
const component = renderer.create( <Accordion rows={ rows } /> );
|
| 38 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 39 |
+
} );
|
| 40 |
+
|
| 41 |
+
it( 'renders an accordion with wrapper class', () => {
|
| 42 |
+
const component = renderer.create( <Accordion className="test-class" rows={ rows } /> );
|
| 43 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 44 |
+
} );
|
| 45 |
+
} );
|
common/src/modules/elements/accordion/element.js
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import React from 'react';
|
| 5 |
+
import PropTypes from 'prop-types';
|
| 6 |
+
import classNames from 'classnames';
|
| 7 |
+
|
| 8 |
+
/**
|
| 9 |
+
* Internal dependencies
|
| 10 |
+
*/
|
| 11 |
+
import Row from './row/template';
|
| 12 |
+
import './style.pcss';
|
| 13 |
+
|
| 14 |
+
const Accordion = ( {
|
| 15 |
+
className,
|
| 16 |
+
containerAttrs,
|
| 17 |
+
rows,
|
| 18 |
+
} ) => (
|
| 19 |
+
rows.length
|
| 20 |
+
? (
|
| 21 |
+
<div
|
| 22 |
+
aria-multiselectable="true"
|
| 23 |
+
className={ classNames(
|
| 24 |
+
'tribe-editor__accordion',
|
| 25 |
+
className,
|
| 26 |
+
) }
|
| 27 |
+
role="tablist"
|
| 28 |
+
{ ...containerAttrs }
|
| 29 |
+
>
|
| 30 |
+
{ rows.map( ( row, index ) => (
|
| 31 |
+
<Row key={ index } { ...row } />
|
| 32 |
+
) ) }
|
| 33 |
+
</div>
|
| 34 |
+
)
|
| 35 |
+
: null
|
| 36 |
+
);
|
| 37 |
+
|
| 38 |
+
Accordion.defaultProps = {
|
| 39 |
+
containerAttrs: {},
|
| 40 |
+
rows: [],
|
| 41 |
+
};
|
| 42 |
+
|
| 43 |
+
Accordion.propTypes = {
|
| 44 |
+
className: PropTypes.string,
|
| 45 |
+
containerAttrs: PropTypes.object,
|
| 46 |
+
rows: PropTypes.arrayOf( PropTypes.shape( {
|
| 47 |
+
accordionId: PropTypes.string.isRequired,
|
| 48 |
+
content: PropTypes.node,
|
| 49 |
+
contentClassName: PropTypes.string,
|
| 50 |
+
header: PropTypes.node,
|
| 51 |
+
headerClassName: PropTypes.string,
|
| 52 |
+
onClick: PropTypes.func,
|
| 53 |
+
onClose: PropTypes.func,
|
| 54 |
+
onOpen: PropTypes.func,
|
| 55 |
+
} ).isRequired ).isRequired,
|
| 56 |
+
};
|
| 57 |
+
|
| 58 |
+
export default Accordion;
|
common/src/modules/elements/accordion/row/__tests__/__snapshots__/template.test.js.snap
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
| 2 |
+
|
| 3 |
+
exports[`Accordion Row Element renders an accordion row 1`] = `
|
| 4 |
+
<article
|
| 5 |
+
className="tribe-editor__accordion__row"
|
| 6 |
+
>
|
| 7 |
+
<button
|
| 8 |
+
aria-controls="accordion-content-123"
|
| 9 |
+
aria-expanded="false"
|
| 10 |
+
aria-selected="false"
|
| 11 |
+
className="tribe-editor__button tribe-editor__accordion__row-header header-class"
|
| 12 |
+
data-attr="header-attr-value"
|
| 13 |
+
id="accordion-header-123"
|
| 14 |
+
onClick={[Function]}
|
| 15 |
+
role="tab"
|
| 16 |
+
type="button"
|
| 17 |
+
>
|
| 18 |
+
this is header
|
| 19 |
+
</button>
|
| 20 |
+
<div
|
| 21 |
+
aria-hidden="true"
|
| 22 |
+
aria-labelledby="accordion-header-123"
|
| 23 |
+
className="tribe-editor__accordion__row-content content-class"
|
| 24 |
+
data-attr="content-attr-value"
|
| 25 |
+
id="accordion-content-123"
|
| 26 |
+
role="tabpanel"
|
| 27 |
+
>
|
| 28 |
+
this is a content
|
| 29 |
+
</div>
|
| 30 |
+
</article>
|
| 31 |
+
`;
|
common/src/modules/elements/accordion/row/__tests__/template.test.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import React from 'react';
|
| 5 |
+
|
| 6 |
+
/**
|
| 7 |
+
* Internal dependencies
|
| 8 |
+
*/
|
| 9 |
+
import Row from '@moderntribe/common/elements/accordion/row/template';
|
| 10 |
+
|
| 11 |
+
let row;
|
| 12 |
+
|
| 13 |
+
describe( 'Accordion Row Element', () => {
|
| 14 |
+
beforeEach( () => {
|
| 15 |
+
row = {
|
| 16 |
+
accordionId: '123',
|
| 17 |
+
content: 'this is a content',
|
| 18 |
+
contentAttrs: { 'data-attr': 'content-attr-value' },
|
| 19 |
+
contentClassName: 'content-class',
|
| 20 |
+
header: 'this is header',
|
| 21 |
+
headerAttrs: { 'data-attr': 'header-attr-value' },
|
| 22 |
+
headerClassName: 'header-class',
|
| 23 |
+
onClick: jest.fn(),
|
| 24 |
+
onClose: jest.fn(),
|
| 25 |
+
onOpen: jest.fn(),
|
| 26 |
+
};
|
| 27 |
+
} );
|
| 28 |
+
|
| 29 |
+
it( 'renders an accordion row', () => {
|
| 30 |
+
const component = renderer.create( <Row { ...row } /> );
|
| 31 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 32 |
+
} );
|
| 33 |
+
|
| 34 |
+
it( 'executes onClick handler', () => {
|
| 35 |
+
const component = mount( <Row { ...row } /> );
|
| 36 |
+
component.find( 'button' ).simulate( 'click' );
|
| 37 |
+
expect( row.onClick ).toHaveBeenCalled();
|
| 38 |
+
expect( row.onClick ).toHaveBeenCalledTimes( 1 );
|
| 39 |
+
} );
|
| 40 |
+
|
| 41 |
+
it( 'executes onOpen and onClose handlers', async () => {
|
| 42 |
+
const component = mount( <Row { ...row } /> );
|
| 43 |
+
component.find( 'button' ).simulate( 'click' );
|
| 44 |
+
await setTimeout( () => {
|
| 45 |
+
component.find( 'button' ).simulate( 'click' );
|
| 46 |
+
setTimeout( () => {
|
| 47 |
+
expect( row.onOpen ).toHaveBeenCalled();
|
| 48 |
+
expect( row.onOpen ).toHaveBeenCalledTimes( 1 );
|
| 49 |
+
expect( row.onClose ).toHaveBeenCalled();
|
| 50 |
+
expect( row.onClose ).toHaveBeenCalledTimes( 1 );
|
| 51 |
+
expect( row.onClick ).toHaveBeenCalled();
|
| 52 |
+
expect( row.onClick ).toHaveBeenCalledTimes( 2 );
|
| 53 |
+
}, 250 );
|
| 54 |
+
}, 250 );
|
| 55 |
+
} );
|
| 56 |
+
} );
|
common/src/modules/elements/accordion/row/template.js
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import React, { PureComponent } from 'react';
|
| 5 |
+
import PropTypes from 'prop-types';
|
| 6 |
+
import classNames from 'classnames';
|
| 7 |
+
|
| 8 |
+
/**
|
| 9 |
+
* Internal dependencies
|
| 10 |
+
*/
|
| 11 |
+
import Button from '@moderntribe/common/elements/button/element';
|
| 12 |
+
import { slide } from '@moderntribe/common/utils';
|
| 13 |
+
|
| 14 |
+
class Row extends PureComponent {
|
| 15 |
+
static propTypes = {
|
| 16 |
+
accordionId: PropTypes.string.isRequired,
|
| 17 |
+
content: PropTypes.node,
|
| 18 |
+
contentAttrs: PropTypes.object,
|
| 19 |
+
contentClassName: PropTypes.string,
|
| 20 |
+
header: PropTypes.node,
|
| 21 |
+
headerAttrs: PropTypes.object,
|
| 22 |
+
headerClassName: PropTypes.string,
|
| 23 |
+
onClick: PropTypes.func,
|
| 24 |
+
onClose: PropTypes.func,
|
| 25 |
+
onOpen: PropTypes.func,
|
| 26 |
+
};
|
| 27 |
+
|
| 28 |
+
static defaultProps = {
|
| 29 |
+
contentAttrs: {},
|
| 30 |
+
headerAttrs: {},
|
| 31 |
+
};
|
| 32 |
+
|
| 33 |
+
constructor( props ) {
|
| 34 |
+
super( props );
|
| 35 |
+
this.state = {
|
| 36 |
+
isActive: false,
|
| 37 |
+
};
|
| 38 |
+
this.headerId = `accordion-header-${ this.props.accordionId }`;
|
| 39 |
+
this.contentId = `accordion-content-${ this.props.accordionId }`;
|
| 40 |
+
}
|
| 41 |
+
|
| 42 |
+
getHeaderAttrs = () => {
|
| 43 |
+
const _isActive = this.state.isActive ? 'true' : 'false';
|
| 44 |
+
return {
|
| 45 |
+
'aria-controls': this.contentId,
|
| 46 |
+
'aria-expanded': _isActive,
|
| 47 |
+
'aria-selected': _isActive,
|
| 48 |
+
id: this.headerId,
|
| 49 |
+
role: 'tab',
|
| 50 |
+
...this.props.headerAttrs,
|
| 51 |
+
};
|
| 52 |
+
};
|
| 53 |
+
|
| 54 |
+
getContentAttrs = () => ( {
|
| 55 |
+
'aria-hidden': this.state.isActive ? 'false' : 'true',
|
| 56 |
+
'aria-labelledby': this.headerId,
|
| 57 |
+
id: this.contentId,
|
| 58 |
+
role: 'tabpanel',
|
| 59 |
+
...this.props.contentAttrs,
|
| 60 |
+
} );
|
| 61 |
+
|
| 62 |
+
onClose = ( parent, e ) => () => {
|
| 63 |
+
parent.classList.remove( 'closing' );
|
| 64 |
+
parent.classList.add( 'closed' );
|
| 65 |
+
this.props.onClose && this.props.onClose( e );
|
| 66 |
+
};
|
| 67 |
+
|
| 68 |
+
onOpen = ( parent, e ) => () => {
|
| 69 |
+
parent.classList.remove( 'opening' );
|
| 70 |
+
parent.classList.add( 'open' );
|
| 71 |
+
this.props.onOpen && this.props.onOpen( e );
|
| 72 |
+
};
|
| 73 |
+
|
| 74 |
+
onClick = ( e ) => {
|
| 75 |
+
const { contentId, onClick } = this.props;
|
| 76 |
+
const parent = e.currentTarget.parentNode;
|
| 77 |
+
const content = e.currentTarget.nextElementSibling;
|
| 78 |
+
|
| 79 |
+
this.state.isActive
|
| 80 |
+
? parent.classList.add( 'closing' )
|
| 81 |
+
: parent.classList.add( 'opening' );
|
| 82 |
+
this.state.isActive
|
| 83 |
+
? slide.up( content, contentId, 200, this.onClose( parent, e ) )
|
| 84 |
+
: slide.down( content, contentId, 200, this.onOpen( parent, e ) );
|
| 85 |
+
|
| 86 |
+
onClick && onClick( e );
|
| 87 |
+
this.setState( ( state ) => ( { isActive: ! state.isActive } ) );
|
| 88 |
+
};
|
| 89 |
+
|
| 90 |
+
render() {
|
| 91 |
+
const {
|
| 92 |
+
content,
|
| 93 |
+
contentClassName,
|
| 94 |
+
header,
|
| 95 |
+
headerClassName,
|
| 96 |
+
} = this.props;
|
| 97 |
+
|
| 98 |
+
return (
|
| 99 |
+
<article
|
| 100 |
+
className={ classNames(
|
| 101 |
+
'tribe-editor__accordion__row',
|
| 102 |
+
{ active: this.state.isActive },
|
| 103 |
+
) }
|
| 104 |
+
>
|
| 105 |
+
<Button
|
| 106 |
+
className={ classNames(
|
| 107 |
+
'tribe-editor__accordion__row-header',
|
| 108 |
+
headerClassName,
|
| 109 |
+
) }
|
| 110 |
+
onClick={ ( e ) => this.onClick( e ) }
|
| 111 |
+
{ ...this.getHeaderAttrs() }
|
| 112 |
+
>
|
| 113 |
+
{ header }
|
| 114 |
+
</Button>
|
| 115 |
+
<div
|
| 116 |
+
className={ classNames(
|
| 117 |
+
'tribe-editor__accordion__row-content',
|
| 118 |
+
contentClassName,
|
| 119 |
+
) }
|
| 120 |
+
{ ...this.getContentAttrs() }
|
| 121 |
+
>
|
| 122 |
+
{ content }
|
| 123 |
+
</div>
|
| 124 |
+
</article>
|
| 125 |
+
);
|
| 126 |
+
}
|
| 127 |
+
}
|
| 128 |
+
|
| 129 |
+
export default Row;
|
common/src/modules/elements/accordion/style.pcss
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
.tribe-editor__accordion__row-content {
|
| 2 |
+
max-height: 0;
|
| 3 |
+
overflow: hidden;
|
| 4 |
+
|
| 5 |
+
&.active {
|
| 6 |
+
max-height: none;
|
| 7 |
+
}
|
| 8 |
+
}
|
common/src/modules/elements/block-icon/index.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import React from 'react';
|
| 5 |
+
|
| 6 |
+
/**
|
| 7 |
+
* Internal dependencies
|
| 8 |
+
*/
|
| 9 |
+
import { TEC } from '@moderntribe/common/icons';
|
| 10 |
+
import './style.pcss';
|
| 11 |
+
|
| 12 |
+
export default () => (
|
| 13 |
+
<div className="tribe-editor__icons__container tribe-editor__icons--tec">
|
| 14 |
+
<TEC />
|
| 15 |
+
</div>
|
| 16 |
+
);
|
common/src/modules/elements/block-icon/style.pcss
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
.editor-block-inspector__card {
|
| 2 |
+
.tribe-editor__icons__container {
|
| 3 |
+
padding: 4px;
|
| 4 |
+
display: flex;
|
| 5 |
+
align-items: center;
|
| 6 |
+
justify-content: center;
|
| 7 |
+
|
| 8 |
+
svg {
|
| 9 |
+
width: 28px;
|
| 10 |
+
height: 28px;
|
| 11 |
+
}
|
| 12 |
+
}
|
| 13 |
+
|
| 14 |
+
.tribe-editor__icons--tec {
|
| 15 |
+
background-color: #199FD1;
|
| 16 |
+
}
|
| 17 |
+
}
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
button[class^='editor-block-list-item-tribe-'], button[class*=' editor-block-list-item-tribe-'] {
|
| 21 |
+
svg {
|
| 22 |
+
color: #16a0d6;
|
| 23 |
+
}
|
| 24 |
+
}
|
common/src/modules/elements/button/__tests__/__snapshots__/element.test.js.snap
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
| 2 |
+
|
| 3 |
+
exports[`Button Element renders button 1`] = `
|
| 4 |
+
<button
|
| 5 |
+
className="tribe-editor__button"
|
| 6 |
+
onClick={[Function]}
|
| 7 |
+
type="button"
|
| 8 |
+
/>
|
| 9 |
+
`;
|
| 10 |
+
|
| 11 |
+
exports[`Button Element renders button with class 1`] = `
|
| 12 |
+
<button
|
| 13 |
+
className="tribe-editor__button test-class"
|
| 14 |
+
onClick={[Function]}
|
| 15 |
+
type="button"
|
| 16 |
+
/>
|
| 17 |
+
`;
|
| 18 |
+
|
| 19 |
+
exports[`Button Element renders button with extra attributes 1`] = `
|
| 20 |
+
<button
|
| 21 |
+
className="tribe-editor__button"
|
| 22 |
+
hello="world"
|
| 23 |
+
onClick={[Function]}
|
| 24 |
+
test="one-two-three"
|
| 25 |
+
type="button"
|
| 26 |
+
/>
|
| 27 |
+
`;
|
| 28 |
+
|
| 29 |
+
exports[`Button Element renders button with label 1`] = `
|
| 30 |
+
<button
|
| 31 |
+
className="tribe-editor__button"
|
| 32 |
+
onClick={[Function]}
|
| 33 |
+
type="button"
|
| 34 |
+
>
|
| 35 |
+
Hello
|
| 36 |
+
</button>
|
| 37 |
+
`;
|
| 38 |
+
|
| 39 |
+
exports[`Button Element renders button with onClick handler 1`] = `
|
| 40 |
+
<button
|
| 41 |
+
className="tribe-editor__button"
|
| 42 |
+
onClick={[MockFunction]}
|
| 43 |
+
type="button"
|
| 44 |
+
/>
|
| 45 |
+
`;
|
| 46 |
+
|
| 47 |
+
exports[`Button Element renders button with set type 1`] = `
|
| 48 |
+
<button
|
| 49 |
+
className="tribe-editor__button"
|
| 50 |
+
onClick={[Function]}
|
| 51 |
+
type="submit"
|
| 52 |
+
/>
|
| 53 |
+
`;
|
| 54 |
+
|
| 55 |
+
exports[`Button Element renders disabled button 1`] = `
|
| 56 |
+
<button
|
| 57 |
+
className="tribe-editor__button"
|
| 58 |
+
disabled={true}
|
| 59 |
+
onClick={[Function]}
|
| 60 |
+
type="button"
|
| 61 |
+
/>
|
| 62 |
+
`;
|
common/src/modules/elements/button/__tests__/element.test.js
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import React from 'react';
|
| 5 |
+
import renderer from 'react-test-renderer';
|
| 6 |
+
|
| 7 |
+
/**
|
| 8 |
+
* Internal dependencies
|
| 9 |
+
*/
|
| 10 |
+
import { Button } from '@moderntribe/common/elements';
|
| 11 |
+
|
| 12 |
+
describe( 'Button Element', () => {
|
| 13 |
+
it( 'renders button', () => {
|
| 14 |
+
const component = renderer.create( <Button /> );
|
| 15 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 16 |
+
} );
|
| 17 |
+
|
| 18 |
+
it( 'renders button with class', () => {
|
| 19 |
+
const component = renderer.create( <Button className="test-class" /> );
|
| 20 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 21 |
+
} );
|
| 22 |
+
|
| 23 |
+
it( 'renders disabled button', () => {
|
| 24 |
+
const component = renderer.create( <Button isDisabled={ true } /> );
|
| 25 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 26 |
+
} );
|
| 27 |
+
|
| 28 |
+
it( 'renders button with label', () => {
|
| 29 |
+
const component = renderer.create( <Button>Hello</Button> );
|
| 30 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 31 |
+
} );
|
| 32 |
+
|
| 33 |
+
it( 'renders button with onClick handler', () => {
|
| 34 |
+
const onClick = jest.fn();
|
| 35 |
+
const component = renderer.create( <Button onClick={ onClick } /> );
|
| 36 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 37 |
+
} );
|
| 38 |
+
|
| 39 |
+
it( 'executes the onClick handler', () => {
|
| 40 |
+
const onClick = jest.fn();
|
| 41 |
+
const component = mount( <Button onClick={ onClick } /> );
|
| 42 |
+
component.find( 'button' ).simulate( 'click' );
|
| 43 |
+
expect( onClick ).toHaveBeenCalled();
|
| 44 |
+
expect( onClick ).toHaveBeenCalledTimes( 1 );
|
| 45 |
+
} );
|
| 46 |
+
|
| 47 |
+
it( 'renders button with set type', () => {
|
| 48 |
+
const component = renderer.create( <Button type="submit" /> );
|
| 49 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 50 |
+
} );
|
| 51 |
+
|
| 52 |
+
it( 'renders button with extra attributes', () => {
|
| 53 |
+
const attrs = {
|
| 54 |
+
test: 'one-two-three',
|
| 55 |
+
hello: 'world',
|
| 56 |
+
};
|
| 57 |
+
const component = renderer.create( <Button { ...attrs } /> );
|
| 58 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 59 |
+
} );
|
| 60 |
+
} );
|
common/src/modules/elements/button/element.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import React, { PureComponent } from 'react';
|
| 5 |
+
import PropTypes from 'prop-types';
|
| 6 |
+
import classNames from 'classnames';
|
| 7 |
+
import { noop } from 'lodash';
|
| 8 |
+
|
| 9 |
+
/**
|
| 10 |
+
* Internal dependencies
|
| 11 |
+
*/
|
| 12 |
+
import './style.pcss';
|
| 13 |
+
|
| 14 |
+
class Button extends PureComponent {
|
| 15 |
+
static defaultProps = {
|
| 16 |
+
onClick: noop,
|
| 17 |
+
type: 'button',
|
| 18 |
+
};
|
| 19 |
+
|
| 20 |
+
static propTypes = {
|
| 21 |
+
className: PropTypes.oneOfType( [
|
| 22 |
+
PropTypes.string,
|
| 23 |
+
PropTypes.arrayOf( PropTypes.string ),
|
| 24 |
+
PropTypes.object,
|
| 25 |
+
] ),
|
| 26 |
+
isDisabled: PropTypes.bool,
|
| 27 |
+
children: PropTypes.node,
|
| 28 |
+
onClick: PropTypes.func,
|
| 29 |
+
type: PropTypes.string,
|
| 30 |
+
};
|
| 31 |
+
|
| 32 |
+
render() {
|
| 33 |
+
const {
|
| 34 |
+
children,
|
| 35 |
+
className,
|
| 36 |
+
isDisabled,
|
| 37 |
+
onClick,
|
| 38 |
+
type,
|
| 39 |
+
...rest
|
| 40 |
+
} = this.props;
|
| 41 |
+
|
| 42 |
+
return (
|
| 43 |
+
<button
|
| 44 |
+
className={ classNames( 'tribe-editor__button', className ) }
|
| 45 |
+
disabled={ isDisabled }
|
| 46 |
+
type={ type }
|
| 47 |
+
onClick={ onClick }
|
| 48 |
+
{ ...rest }
|
| 49 |
+
>
|
| 50 |
+
{ children }
|
| 51 |
+
</button>
|
| 52 |
+
);
|
| 53 |
+
}
|
| 54 |
+
}
|
| 55 |
+
|
| 56 |
+
export default Button;
|
common/src/modules/elements/button/style.pcss
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* basic styles are in .tribe-editor__btn, this is kepted for backward compatibility */
|
| 2 |
+
.tribe-editor__btn--label {
|
| 3 |
+
background-color: transparent;
|
| 4 |
+
border: none;
|
| 5 |
+
padding: 0;
|
| 6 |
+
margin: 0;
|
| 7 |
+
text-align: left;
|
| 8 |
+
}
|
| 9 |
+
|
| 10 |
+
.tribe-editor__button {
|
| 11 |
+
|
| 12 |
+
&,
|
| 13 |
+
/* extra editor-styles-wrapper class to override gutenberg styles */
|
| 14 |
+
.editor-styles-wrapper & {
|
| 15 |
+
|
| 16 |
+
background-color: transparent;
|
| 17 |
+
border: none;
|
| 18 |
+
padding: 0;
|
| 19 |
+
margin: 0;
|
| 20 |
+
font-family: 'Helvetica', 'sans-serif';
|
| 21 |
+
cursor: pointer;
|
| 22 |
+
|
| 23 |
+
&[disabled] {
|
| 24 |
+
cursor: default;
|
| 25 |
+
}
|
| 26 |
+
}
|
| 27 |
+
}
|
| 28 |
+
|
| 29 |
+
.tribe-editor__button--sm {
|
| 30 |
+
|
| 31 |
+
&,
|
| 32 |
+
/* extra editor-styles-wrapper class to override gutenberg styles */
|
| 33 |
+
.editor-styles-wrapper & {
|
| 34 |
+
|
| 35 |
+
background-color: #009fd4;
|
| 36 |
+
color: #ffffff;
|
| 37 |
+
padding: 11px 16px 9px;
|
| 38 |
+
font-size: 15px;
|
| 39 |
+
font-weight: bold;
|
| 40 |
+
line-height: 18px;
|
| 41 |
+
transition: background-color 0.2s ease;
|
| 42 |
+
|
| 43 |
+
&:hover,
|
| 44 |
+
&:focus {
|
| 45 |
+
background-color: #007bb4;
|
| 46 |
+
}
|
| 47 |
+
|
| 48 |
+
&[disabled] {
|
| 49 |
+
|
| 50 |
+
&,
|
| 51 |
+
&:hover,
|
| 52 |
+
&:focus {
|
| 53 |
+
background-color: #f3f4f5;
|
| 54 |
+
color: #8d949b;
|
| 55 |
+
}
|
| 56 |
+
}
|
| 57 |
+
}
|
| 58 |
+
}
|
common/src/modules/elements/checkbox-input/__tests__/__snapshots__/element.test.js.snap
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
| 2 |
+
|
| 3 |
+
exports[`Input element Should render the component 1`] = `
|
| 4 |
+
<input
|
| 5 |
+
className="tribe-editor__input tribe-editor__input--checkbox"
|
| 6 |
+
type="checkbox"
|
| 7 |
+
/>
|
| 8 |
+
`;
|
| 9 |
+
|
| 10 |
+
exports[`Input element Should render the component with checked 1`] = `
|
| 11 |
+
<input
|
| 12 |
+
checked={true}
|
| 13 |
+
className="tribe-editor__input tribe-editor__input--checkbox"
|
| 14 |
+
type="checkbox"
|
| 15 |
+
/>
|
| 16 |
+
`;
|
| 17 |
+
|
| 18 |
+
exports[`Input element Should render the component with checked 2`] = `
|
| 19 |
+
<input
|
| 20 |
+
checked={false}
|
| 21 |
+
className="tribe-editor__input tribe-editor__input--checkbox"
|
| 22 |
+
type="checkbox"
|
| 23 |
+
/>
|
| 24 |
+
`;
|
| 25 |
+
|
| 26 |
+
exports[`Input element Should render the component with class 1`] = `
|
| 27 |
+
<input
|
| 28 |
+
className="tribe-editor__input tribe-editor__input--checkbox checkbox-class"
|
| 29 |
+
type="checkbox"
|
| 30 |
+
/>
|
| 31 |
+
`;
|
| 32 |
+
|
| 33 |
+
exports[`Input element Should render the component with extra props 1`] = `
|
| 34 |
+
<input
|
| 35 |
+
className="tribe-editor__input tribe-editor__input--checkbox"
|
| 36 |
+
id="checkbox-id"
|
| 37 |
+
type="checkbox"
|
| 38 |
+
/>
|
| 39 |
+
`;
|
| 40 |
+
|
| 41 |
+
exports[`Input element Should render the component with onChange handler 1`] = `
|
| 42 |
+
<input
|
| 43 |
+
className="tribe-editor__input tribe-editor__input--checkbox"
|
| 44 |
+
onChange={[Function]}
|
| 45 |
+
type="checkbox"
|
| 46 |
+
/>
|
| 47 |
+
`;
|
common/src/modules/elements/checkbox-input/__tests__/element.test.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import React from 'react';
|
| 5 |
+
import { noop } from 'lodash';
|
| 6 |
+
|
| 7 |
+
/**
|
| 8 |
+
* Internal dependencies
|
| 9 |
+
*/
|
| 10 |
+
import CheckboxInput from '../element.js';
|
| 11 |
+
|
| 12 |
+
describe( 'Input element', () => {
|
| 13 |
+
it( 'Should render the component', () => {
|
| 14 |
+
const component = renderer.create( <CheckboxInput /> );
|
| 15 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 16 |
+
} );
|
| 17 |
+
|
| 18 |
+
it( 'Should render the component with checked', () => {
|
| 19 |
+
const component1 = renderer.create( <CheckboxInput checked={ true } /> );
|
| 20 |
+
expect( component1.toJSON() ).toMatchSnapshot();
|
| 21 |
+
const component2 = renderer.create( <CheckboxInput checked={ false } /> );
|
| 22 |
+
expect( component2.toJSON() ).toMatchSnapshot();
|
| 23 |
+
} );
|
| 24 |
+
|
| 25 |
+
it( 'Should render the component with class', () => {
|
| 26 |
+
const component = renderer.create( <CheckboxInput className="checkbox-class" /> );
|
| 27 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 28 |
+
} );
|
| 29 |
+
|
| 30 |
+
it( 'Should render the component with onChange handler', () => {
|
| 31 |
+
const component = renderer.create( <CheckboxInput onChange={ noop } /> );
|
| 32 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 33 |
+
} );
|
| 34 |
+
|
| 35 |
+
it( 'Should render the component with extra props', () => {
|
| 36 |
+
const component = renderer.create( <CheckboxInput id="checkbox-id" /> );
|
| 37 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 38 |
+
} );
|
| 39 |
+
} );
|
common/src/modules/elements/checkbox-input/element.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External Dependencies
|
| 3 |
+
*/
|
| 4 |
+
import React from 'react';
|
| 5 |
+
import PropTypes from 'prop-types';
|
| 6 |
+
import classNames from 'classnames';
|
| 7 |
+
|
| 8 |
+
/**
|
| 9 |
+
* Internal dependencies
|
| 10 |
+
*/
|
| 11 |
+
import Input from '@moderntribe/common/elements/input/element';
|
| 12 |
+
import './style.pcss';
|
| 13 |
+
|
| 14 |
+
const CheckboxInput = ( {
|
| 15 |
+
checked,
|
| 16 |
+
className,
|
| 17 |
+
onChange,
|
| 18 |
+
...rest
|
| 19 |
+
} ) => (
|
| 20 |
+
<Input
|
| 21 |
+
checked={ checked }
|
| 22 |
+
className={ classNames( 'tribe-editor__input--checkbox', className ) }
|
| 23 |
+
onChange={ onChange }
|
| 24 |
+
type="checkbox"
|
| 25 |
+
{ ...rest }
|
| 26 |
+
/>
|
| 27 |
+
);
|
| 28 |
+
|
| 29 |
+
CheckboxInput.propTypes = {
|
| 30 |
+
checked: PropTypes.bool,
|
| 31 |
+
className: PropTypes.string,
|
| 32 |
+
onChange: PropTypes.func,
|
| 33 |
+
};
|
| 34 |
+
|
| 35 |
+
export default CheckboxInput;
|
common/src/modules/elements/checkbox-input/style.pcss
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* increased specificity required to override gutenberg editor styles */
|
| 2 |
+
input[type=checkbox].tribe-editor__input--checkbox {
|
| 3 |
+
background-color: #ffffff;
|
| 4 |
+
border: 1px solid #E0E5E9;
|
| 5 |
+
border-radius: 0;
|
| 6 |
+
|
| 7 |
+
&:focus {
|
| 8 |
+
border: 1px solid #E0E5E9;
|
| 9 |
+
box-shadow: 0 0 0 1px #E0E5E9;
|
| 10 |
+
}
|
| 11 |
+
|
| 12 |
+
&:checked {
|
| 13 |
+
background-color: #ffffff;
|
| 14 |
+
border: 1px solid #E0E5E9;
|
| 15 |
+
|
| 16 |
+
&:focus {
|
| 17 |
+
border: 1px solid #E0E5E9;
|
| 18 |
+
box-shadow: 0 0 0 1px #E0E5E9;
|
| 19 |
+
}
|
| 20 |
+
|
| 21 |
+
&:before {
|
| 22 |
+
color: #11A0D2;
|
| 23 |
+
}
|
| 24 |
+
}
|
| 25 |
+
}
|
common/src/modules/elements/checkbox/__tests__/__snapshots__/element.test.js.snap
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
| 2 |
+
|
| 3 |
+
exports[`Checkbox Element renders checkbox 1`] = `
|
| 4 |
+
<div
|
| 5 |
+
className="tribe-editor__checkbox"
|
| 6 |
+
>
|
| 7 |
+
<input
|
| 8 |
+
checked={false}
|
| 9 |
+
className="tribe-editor__input tribe-editor__input--checkbox tribe-editor__checkbox__input"
|
| 10 |
+
onChange={[Function]}
|
| 11 |
+
type="checkbox"
|
| 12 |
+
/>
|
| 13 |
+
<label
|
| 14 |
+
className="tribe-editor__checkbox__label"
|
| 15 |
+
/>
|
| 16 |
+
</div>
|
| 17 |
+
`;
|
| 18 |
+
|
| 19 |
+
exports[`Checkbox Element renders checkbox with class 1`] = `
|
| 20 |
+
<div
|
| 21 |
+
className="tribe-editor__checkbox test-class"
|
| 22 |
+
>
|
| 23 |
+
<input
|
| 24 |
+
checked={false}
|
| 25 |
+
className="tribe-editor__input tribe-editor__input--checkbox tribe-editor__checkbox__input"
|
| 26 |
+
onChange={[Function]}
|
| 27 |
+
type="checkbox"
|
| 28 |
+
/>
|
| 29 |
+
<label
|
| 30 |
+
className="tribe-editor__checkbox__label"
|
| 31 |
+
/>
|
| 32 |
+
</div>
|
| 33 |
+
`;
|
| 34 |
+
|
| 35 |
+
exports[`Checkbox Element renders checkbox with id 1`] = `
|
| 36 |
+
<div
|
| 37 |
+
className="tribe-editor__checkbox"
|
| 38 |
+
>
|
| 39 |
+
<input
|
| 40 |
+
checked={false}
|
| 41 |
+
className="tribe-editor__input tribe-editor__input--checkbox tribe-editor__checkbox__input"
|
| 42 |
+
id="test-id"
|
| 43 |
+
onChange={[Function]}
|
| 44 |
+
type="checkbox"
|
| 45 |
+
/>
|
| 46 |
+
<label
|
| 47 |
+
className="tribe-editor__checkbox__label"
|
| 48 |
+
htmlFor="test-id"
|
| 49 |
+
/>
|
| 50 |
+
</div>
|
| 51 |
+
`;
|
| 52 |
+
|
| 53 |
+
exports[`Checkbox Element renders checkbox with label 1`] = `
|
| 54 |
+
<div
|
| 55 |
+
className="tribe-editor__checkbox"
|
| 56 |
+
>
|
| 57 |
+
<input
|
| 58 |
+
checked={false}
|
| 59 |
+
className="tribe-editor__input tribe-editor__input--checkbox tribe-editor__checkbox__input"
|
| 60 |
+
onChange={[Function]}
|
| 61 |
+
type="checkbox"
|
| 62 |
+
/>
|
| 63 |
+
<label
|
| 64 |
+
className="tribe-editor__checkbox__label"
|
| 65 |
+
>
|
| 66 |
+
Test Label
|
| 67 |
+
</label>
|
| 68 |
+
</div>
|
| 69 |
+
`;
|
| 70 |
+
|
| 71 |
+
exports[`Checkbox Element renders checkbox with name 1`] = `
|
| 72 |
+
<div
|
| 73 |
+
className="tribe-editor__checkbox"
|
| 74 |
+
>
|
| 75 |
+
<input
|
| 76 |
+
checked={false}
|
| 77 |
+
className="tribe-editor__input tribe-editor__input--checkbox tribe-editor__checkbox__input"
|
| 78 |
+
name="test-name"
|
| 79 |
+
onChange={[Function]}
|
| 80 |
+
type="checkbox"
|
| 81 |
+
/>
|
| 82 |
+
<label
|
| 83 |
+
className="tribe-editor__checkbox__label"
|
| 84 |
+
/>
|
| 85 |
+
</div>
|
| 86 |
+
`;
|
| 87 |
+
|
| 88 |
+
exports[`Checkbox Element renders checkbox with onChange handler 1`] = `
|
| 89 |
+
<div
|
| 90 |
+
className="tribe-editor__checkbox"
|
| 91 |
+
>
|
| 92 |
+
<input
|
| 93 |
+
checked={false}
|
| 94 |
+
className="tribe-editor__input tribe-editor__input--checkbox tribe-editor__checkbox__input"
|
| 95 |
+
onChange={[MockFunction]}
|
| 96 |
+
type="checkbox"
|
| 97 |
+
/>
|
| 98 |
+
<label
|
| 99 |
+
className="tribe-editor__checkbox__label"
|
| 100 |
+
/>
|
| 101 |
+
</div>
|
| 102 |
+
`;
|
| 103 |
+
|
| 104 |
+
exports[`Checkbox Element renders checkbox with value 1`] = `
|
| 105 |
+
<div
|
| 106 |
+
className="tribe-editor__checkbox"
|
| 107 |
+
>
|
| 108 |
+
<input
|
| 109 |
+
checked={false}
|
| 110 |
+
className="tribe-editor__input tribe-editor__input--checkbox tribe-editor__checkbox__input"
|
| 111 |
+
onChange={[Function]}
|
| 112 |
+
type="checkbox"
|
| 113 |
+
value="Test Value"
|
| 114 |
+
/>
|
| 115 |
+
<label
|
| 116 |
+
className="tribe-editor__checkbox__label"
|
| 117 |
+
/>
|
| 118 |
+
</div>
|
| 119 |
+
`;
|
| 120 |
+
|
| 121 |
+
exports[`Checkbox Element renders checked checkbox 1`] = `
|
| 122 |
+
<div
|
| 123 |
+
className="tribe-editor__checkbox"
|
| 124 |
+
>
|
| 125 |
+
<input
|
| 126 |
+
checked={true}
|
| 127 |
+
className="tribe-editor__input tribe-editor__input--checkbox tribe-editor__checkbox__input"
|
| 128 |
+
onChange={[Function]}
|
| 129 |
+
type="checkbox"
|
| 130 |
+
/>
|
| 131 |
+
<label
|
| 132 |
+
className="tribe-editor__checkbox__label"
|
| 133 |
+
/>
|
| 134 |
+
</div>
|
| 135 |
+
`;
|
| 136 |
+
|
| 137 |
+
exports[`Checkbox Element renders disabled checkbox 1`] = `
|
| 138 |
+
<div
|
| 139 |
+
className="tribe-editor__checkbox"
|
| 140 |
+
>
|
| 141 |
+
<input
|
| 142 |
+
checked={false}
|
| 143 |
+
className="tribe-editor__input tribe-editor__input--checkbox tribe-editor__checkbox__input"
|
| 144 |
+
disabled={true}
|
| 145 |
+
onChange={[Function]}
|
| 146 |
+
type="checkbox"
|
| 147 |
+
/>
|
| 148 |
+
<label
|
| 149 |
+
className="tribe-editor__checkbox__label"
|
| 150 |
+
/>
|
| 151 |
+
</div>
|
| 152 |
+
`;
|
| 153 |
+
|
| 154 |
+
exports[`Checkbox Element renders unchecked checkbox 1`] = `
|
| 155 |
+
<div
|
| 156 |
+
className="tribe-editor__checkbox"
|
| 157 |
+
>
|
| 158 |
+
<input
|
| 159 |
+
checked={false}
|
| 160 |
+
className="tribe-editor__input tribe-editor__input--checkbox tribe-editor__checkbox__input"
|
| 161 |
+
onChange={[Function]}
|
| 162 |
+
type="checkbox"
|
| 163 |
+
/>
|
| 164 |
+
<label
|
| 165 |
+
className="tribe-editor__checkbox__label"
|
| 166 |
+
/>
|
| 167 |
+
</div>
|
| 168 |
+
`;
|
common/src/modules/elements/checkbox/__tests__/element.test.js
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import React from 'react';
|
| 5 |
+
|
| 6 |
+
/**
|
| 7 |
+
* Internal dependencies
|
| 8 |
+
*/
|
| 9 |
+
import { Checkbox } from '@moderntribe/common/elements';
|
| 10 |
+
|
| 11 |
+
describe( 'Checkbox Element', () => {
|
| 12 |
+
it( 'renders checkbox', () => {
|
| 13 |
+
const component = renderer.create( <Checkbox /> );
|
| 14 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 15 |
+
} );
|
| 16 |
+
|
| 17 |
+
it( 'renders checked checkbox', () => {
|
| 18 |
+
const component = renderer.create( <Checkbox checked={ true } /> );
|
| 19 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 20 |
+
} );
|
| 21 |
+
|
| 22 |
+
it( 'renders unchecked checkbox', () => {
|
| 23 |
+
const component = renderer.create( <Checkbox checked={ false } /> );
|
| 24 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 25 |
+
} );
|
| 26 |
+
|
| 27 |
+
it( 'renders checkbox with class', () => {
|
| 28 |
+
const component = renderer.create( <Checkbox className="test-class" /> );
|
| 29 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 30 |
+
} );
|
| 31 |
+
|
| 32 |
+
it( 'renders disabled checkbox', () => {
|
| 33 |
+
const component = renderer.create( <Checkbox disabled={ true } /> );
|
| 34 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 35 |
+
} );
|
| 36 |
+
|
| 37 |
+
it( 'renders checkbox with id', () => {
|
| 38 |
+
const component = renderer.create( <Checkbox id="test-id" /> );
|
| 39 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 40 |
+
} );
|
| 41 |
+
|
| 42 |
+
it( 'renders checkbox with label', () => {
|
| 43 |
+
const component = renderer.create( <Checkbox label="Test Label" /> );
|
| 44 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 45 |
+
} );
|
| 46 |
+
|
| 47 |
+
it( 'renders checkbox with name', () => {
|
| 48 |
+
const component = renderer.create( <Checkbox name="test-name" /> );
|
| 49 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 50 |
+
} );
|
| 51 |
+
|
| 52 |
+
it( 'renders checkbox with value', () => {
|
| 53 |
+
const component = renderer.create( <Checkbox value="Test Value" /> );
|
| 54 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 55 |
+
} );
|
| 56 |
+
|
| 57 |
+
it( 'renders checkbox with onChange handler', () => {
|
| 58 |
+
const onChange = jest.fn();
|
| 59 |
+
const component = renderer.create( <Checkbox onChange={ onChange } /> );
|
| 60 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 61 |
+
} );
|
| 62 |
+
|
| 63 |
+
it( 'executes checkbox with onChange handler', () => {
|
| 64 |
+
const onChange = jest.fn();
|
| 65 |
+
const component = mount( <Checkbox onChange={ onChange } /> );
|
| 66 |
+
component.find( 'input' ).simulate( 'change' );
|
| 67 |
+
expect( onChange ).toHaveBeenCalled();
|
| 68 |
+
expect( onChange ).toHaveBeenCalledTimes( 1 );
|
| 69 |
+
} );
|
| 70 |
+
} );
|
common/src/modules/elements/checkbox/element.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import React from 'react';
|
| 5 |
+
import PropTypes from 'prop-types';
|
| 6 |
+
import classNames from 'classnames';
|
| 7 |
+
import { noop } from 'lodash';
|
| 8 |
+
|
| 9 |
+
/**
|
| 10 |
+
* Internal dependencies
|
| 11 |
+
*/
|
| 12 |
+
import { CheckboxInput } from '@moderntribe/common/elements';
|
| 13 |
+
|
| 14 |
+
const Checkbox = ( {
|
| 15 |
+
checked,
|
| 16 |
+
className,
|
| 17 |
+
disabled,
|
| 18 |
+
id,
|
| 19 |
+
label,
|
| 20 |
+
onChange,
|
| 21 |
+
name,
|
| 22 |
+
value,
|
| 23 |
+
} ) => {
|
| 24 |
+
return (
|
| 25 |
+
<div className={ classNames( 'tribe-editor__checkbox', className ) }>
|
| 26 |
+
<CheckboxInput
|
| 27 |
+
checked={ checked }
|
| 28 |
+
className="tribe-editor__checkbox__input"
|
| 29 |
+
disabled={ disabled }
|
| 30 |
+
id={ id }
|
| 31 |
+
name={ name }
|
| 32 |
+
onChange={ onChange }
|
| 33 |
+
value={ value }
|
| 34 |
+
/>
|
| 35 |
+
<label
|
| 36 |
+
className="tribe-editor__checkbox__label"
|
| 37 |
+
htmlFor={ id }
|
| 38 |
+
>
|
| 39 |
+
{ label }
|
| 40 |
+
</label>
|
| 41 |
+
</div>
|
| 42 |
+
);
|
| 43 |
+
};
|
| 44 |
+
|
| 45 |
+
Checkbox.defaultProps = {
|
| 46 |
+
checked: false,
|
| 47 |
+
onChange: noop,
|
| 48 |
+
}
|
| 49 |
+
|
| 50 |
+
Checkbox.propTypes = {
|
| 51 |
+
checked: PropTypes.bool.isRequired,
|
| 52 |
+
className: PropTypes.string,
|
| 53 |
+
disabled: PropTypes.bool,
|
| 54 |
+
id: PropTypes.string,
|
| 55 |
+
label: PropTypes.node,
|
| 56 |
+
name: PropTypes.string,
|
| 57 |
+
onChange: PropTypes.func,
|
| 58 |
+
value: PropTypes.string,
|
| 59 |
+
};
|
| 60 |
+
|
| 61 |
+
export default Checkbox;
|
common/src/modules/elements/counter/__tests__/__snapshots__/element.test.js.snap
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
| 2 |
+
|
| 3 |
+
exports[`Counter Element renders counter 1`] = `
|
| 4 |
+
<div
|
| 5 |
+
className="tribe-editor__counter"
|
| 6 |
+
>
|
| 7 |
+
<span
|
| 8 |
+
className="tribe-editor__counter__count"
|
| 9 |
+
/>
|
| 10 |
+
<span
|
| 11 |
+
className="tribe-editor__counter__label"
|
| 12 |
+
/>
|
| 13 |
+
</div>
|
| 14 |
+
`;
|
| 15 |
+
|
| 16 |
+
exports[`Counter Element renders counter with class 1`] = `
|
| 17 |
+
<div
|
| 18 |
+
className="tribe-editor__counter test-class"
|
| 19 |
+
>
|
| 20 |
+
<span
|
| 21 |
+
className="tribe-editor__counter__count"
|
| 22 |
+
/>
|
| 23 |
+
<span
|
| 24 |
+
className="tribe-editor__counter__label"
|
| 25 |
+
/>
|
| 26 |
+
</div>
|
| 27 |
+
`;
|
| 28 |
+
|
| 29 |
+
exports[`Counter Element renders counter with count 1`] = `
|
| 30 |
+
<div
|
| 31 |
+
className="tribe-editor__counter"
|
| 32 |
+
>
|
| 33 |
+
<span
|
| 34 |
+
className="tribe-editor__counter__count"
|
| 35 |
+
>
|
| 36 |
+
42
|
| 37 |
+
</span>
|
| 38 |
+
<span
|
| 39 |
+
className="tribe-editor__counter__label"
|
| 40 |
+
/>
|
| 41 |
+
</div>
|
| 42 |
+
`;
|
| 43 |
+
|
| 44 |
+
exports[`Counter Element renders counter with label 1`] = `
|
| 45 |
+
<div
|
| 46 |
+
className="tribe-editor__counter"
|
| 47 |
+
>
|
| 48 |
+
<span
|
| 49 |
+
className="tribe-editor__counter__count"
|
| 50 |
+
/>
|
| 51 |
+
<span
|
| 52 |
+
className="tribe-editor__counter__label"
|
| 53 |
+
>
|
| 54 |
+
test-label
|
| 55 |
+
</span>
|
| 56 |
+
</div>
|
| 57 |
+
`;
|
common/src/modules/elements/counter/__tests__/element.test.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import React from 'react';
|
| 5 |
+
import renderer from 'react-test-renderer';
|
| 6 |
+
|
| 7 |
+
/**
|
| 8 |
+
* Internal dependencies
|
| 9 |
+
*/
|
| 10 |
+
import { Counter } from '@moderntribe/common/elements';
|
| 11 |
+
|
| 12 |
+
describe( 'Counter Element', () => {
|
| 13 |
+
it( 'renders counter', () => {
|
| 14 |
+
const component = renderer.create( <Counter /> );
|
| 15 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 16 |
+
} );
|
| 17 |
+
|
| 18 |
+
it( 'renders counter with class', () => {
|
| 19 |
+
const component = renderer.create( <Counter className="test-class" /> );
|
| 20 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 21 |
+
} );
|
| 22 |
+
|
| 23 |
+
it( 'renders counter with count', () => {
|
| 24 |
+
const component = renderer.create( <Counter count={ 42 } /> );
|
| 25 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 26 |
+
} );
|
| 27 |
+
|
| 28 |
+
it( 'renders counter with label', () => {
|
| 29 |
+
const component = renderer.create( <Counter label="test-label" /> );
|
| 30 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 31 |
+
} );
|
| 32 |
+
} );
|
common/src/modules/elements/counter/element.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import React from 'react';
|
| 5 |
+
import PropTypes from 'prop-types';
|
| 6 |
+
import classNames from 'classnames';
|
| 7 |
+
|
| 8 |
+
/**
|
| 9 |
+
* Internal dependencies
|
| 10 |
+
*/
|
| 11 |
+
import './style.pcss';
|
| 12 |
+
|
| 13 |
+
const Counter = ( {
|
| 14 |
+
className,
|
| 15 |
+
count,
|
| 16 |
+
label,
|
| 17 |
+
} ) => (
|
| 18 |
+
<div className={ classNames(
|
| 19 |
+
'tribe-editor__counter',
|
| 20 |
+
className,
|
| 21 |
+
) }>
|
| 22 |
+
<span className="tribe-editor__counter__count">
|
| 23 |
+
{ count }
|
| 24 |
+
</span>
|
| 25 |
+
<span className="tribe-editor__counter__label">
|
| 26 |
+
{ label }
|
| 27 |
+
</span>
|
| 28 |
+
</div>
|
| 29 |
+
);
|
| 30 |
+
|
| 31 |
+
Counter.propTypes = {
|
| 32 |
+
className: PropTypes.string,
|
| 33 |
+
count: PropTypes.number,
|
| 34 |
+
label: PropTypes.string,
|
| 35 |
+
};
|
| 36 |
+
|
| 37 |
+
export default Counter;
|
common/src/modules/elements/counter/style.pcss
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
.tribe-editor__counter {
|
| 2 |
+
display: flex;
|
| 3 |
+
flex-direction: column;
|
| 4 |
+
align-items: center;
|
| 5 |
+
}
|
| 6 |
+
|
| 7 |
+
.tribe-editor__counter__count {
|
| 8 |
+
flex: none;
|
| 9 |
+
color: #AEB4BB;
|
| 10 |
+
font-size: 32px;
|
| 11 |
+
font-weight: bold;
|
| 12 |
+
line-height: 40px;
|
| 13 |
+
margin-bottom: 10px;
|
| 14 |
+
}
|
| 15 |
+
|
| 16 |
+
.tribe-editor__counter__label {
|
| 17 |
+
flex: none;
|
| 18 |
+
color: #AEB4BB;
|
| 19 |
+
font-size: 12px;
|
| 20 |
+
line-height: 14px;
|
| 21 |
+
letter-spacing: 0.04px;
|
| 22 |
+
}
|
common/src/modules/elements/creatable-select/__tests__/__snapshots__/element.test.js.snap
ADDED
|
@@ -0,0 +1,241 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
| 2 |
+
|
| 3 |
+
exports[`CreatableSelect element Should render the component 1`] = `
|
| 4 |
+
<div
|
| 5 |
+
className="css-10nd86i tribe-editor__creatable-select"
|
| 6 |
+
onKeyDown={[Function]}
|
| 7 |
+
>
|
| 8 |
+
<div
|
| 9 |
+
className="css-vj8t7z tribe-editor__creatable-select__control"
|
| 10 |
+
onMouseDown={[Function]}
|
| 11 |
+
onTouchEnd={[Function]}
|
| 12 |
+
>
|
| 13 |
+
<div
|
| 14 |
+
className="css-1hwfws3 tribe-editor__creatable-select__value-container"
|
| 15 |
+
>
|
| 16 |
+
<div
|
| 17 |
+
className="css-1492t68 tribe-editor__creatable-select__placeholder"
|
| 18 |
+
>
|
| 19 |
+
Select...
|
| 20 |
+
</div>
|
| 21 |
+
<div
|
| 22 |
+
className="css-1g6gooi"
|
| 23 |
+
>
|
| 24 |
+
<div
|
| 25 |
+
className="tribe-editor__creatable-select__input"
|
| 26 |
+
style={
|
| 27 |
+
Object {
|
| 28 |
+
"display": "inline-block",
|
| 29 |
+
}
|
| 30 |
+
}
|
| 31 |
+
>
|
| 32 |
+
<input
|
| 33 |
+
aria-autocomplete="list"
|
| 34 |
+
autoCapitalize="none"
|
| 35 |
+
autoComplete="off"
|
| 36 |
+
autoCorrect="off"
|
| 37 |
+
disabled={false}
|
| 38 |
+
id="react-select-2-input"
|
| 39 |
+
onBlur={[Function]}
|
| 40 |
+
onChange={[Function]}
|
| 41 |
+
onFocus={[Function]}
|
| 42 |
+
spellCheck="false"
|
| 43 |
+
style={
|
| 44 |
+
Object {
|
| 45 |
+
"background": 0,
|
| 46 |
+
"border": 0,
|
| 47 |
+
"boxSizing": "content-box",
|
| 48 |
+
"color": "inherit",
|
| 49 |
+
"fontSize": "inherit",
|
| 50 |
+
"opacity": 1,
|
| 51 |
+
"outline": 0,
|
| 52 |
+
"padding": 0,
|
| 53 |
+
"width": "1px",
|
| 54 |
+
}
|
| 55 |
+
}
|
| 56 |
+
tabIndex="0"
|
| 57 |
+
type="text"
|
| 58 |
+
value=""
|
| 59 |
+
/>
|
| 60 |
+
<div
|
| 61 |
+
style={
|
| 62 |
+
Object {
|
| 63 |
+
"height": 0,
|
| 64 |
+
"left": 0,
|
| 65 |
+
"overflow": "scroll",
|
| 66 |
+
"position": "absolute",
|
| 67 |
+
"top": 0,
|
| 68 |
+
"visibility": "hidden",
|
| 69 |
+
"whiteSpace": "pre",
|
| 70 |
+
}
|
| 71 |
+
}
|
| 72 |
+
>
|
| 73 |
+
|
| 74 |
+
</div>
|
| 75 |
+
</div>
|
| 76 |
+
</div>
|
| 77 |
+
</div>
|
| 78 |
+
<div
|
| 79 |
+
className="css-1wy0on6 tribe-editor__creatable-select__indicators"
|
| 80 |
+
>
|
| 81 |
+
<div
|
| 82 |
+
aria-hidden="true"
|
| 83 |
+
className="css-1ep9fjw tribe-editor__creatable-select__indicator tribe-editor__creatable-select__dropdown-indicator"
|
| 84 |
+
onMouseDown={[Function]}
|
| 85 |
+
onTouchEnd={[Function]}
|
| 86 |
+
>
|
| 87 |
+
<span
|
| 88 |
+
className="tribe-editor__creatable-select__dropdown-indicator"
|
| 89 |
+
>
|
| 90 |
+
arrow-down
|
| 91 |
+
</span>
|
| 92 |
+
</div>
|
| 93 |
+
</div>
|
| 94 |
+
</div>
|
| 95 |
+
</div>
|
| 96 |
+
`;
|
| 97 |
+
|
| 98 |
+
exports[`CreatableSelect element Should render the component with class 1`] = `
|
| 99 |
+
<div
|
| 100 |
+
className="css-10nd86i tribe-editor__creatable-select test-class"
|
| 101 |
+
onKeyDown={[Function]}
|
| 102 |
+
>
|
| 103 |
+
<div
|
| 104 |
+
className="css-vj8t7z tribe-editor__creatable-select__control"
|
| 105 |
+
onMouseDown={[Function]}
|
| 106 |
+
onTouchEnd={[Function]}
|
| 107 |
+
>
|
| 108 |
+
<div
|
| 109 |
+
className="css-1hwfws3 tribe-editor__creatable-select__value-container"
|
| 110 |
+
>
|
| 111 |
+
<div
|
| 112 |
+
className="css-1492t68 tribe-editor__creatable-select__placeholder"
|
| 113 |
+
>
|
| 114 |
+
Select...
|
| 115 |
+
</div>
|
| 116 |
+
<div
|
| 117 |
+
className="css-1g6gooi"
|
| 118 |
+
>
|
| 119 |
+
<div
|
| 120 |
+
className="tribe-editor__creatable-select__input"
|
| 121 |
+
style={
|
| 122 |
+
Object {
|
| 123 |
+
"display": "inline-block",
|
| 124 |
+
}
|
| 125 |
+
}
|
| 126 |
+
>
|
| 127 |
+
<input
|
| 128 |
+
aria-autocomplete="list"
|
| 129 |
+
autoCapitalize="none"
|
| 130 |
+
autoComplete="off"
|
| 131 |
+
autoCorrect="off"
|
| 132 |
+
disabled={false}
|
| 133 |
+
id="react-select-3-input"
|
| 134 |
+
onBlur={[Function]}
|
| 135 |
+
onChange={[Function]}
|
| 136 |
+
onFocus={[Function]}
|
| 137 |
+
spellCheck="false"
|
| 138 |
+
style={
|
| 139 |
+
Object {
|
| 140 |
+
"background": 0,
|
| 141 |
+
"border": 0,
|
| 142 |
+
"boxSizing": "content-box",
|
| 143 |
+
"color": "inherit",
|
| 144 |
+
"fontSize": "inherit",
|
| 145 |
+
"opacity": 1,
|
| 146 |
+
"outline": 0,
|
| 147 |
+
"padding": 0,
|
| 148 |
+
"width": "1px",
|
| 149 |
+
}
|
| 150 |
+
}
|
| 151 |
+
tabIndex="0"
|
| 152 |
+
type="text"
|
| 153 |
+
value=""
|
| 154 |
+
/>
|
| 155 |
+
<div
|
| 156 |
+
style={
|
| 157 |
+
Object {
|
| 158 |
+
"height": 0,
|
| 159 |
+
"left": 0,
|
| 160 |
+
"overflow": "scroll",
|
| 161 |
+
"position": "absolute",
|
| 162 |
+
"top": 0,
|
| 163 |
+
"visibility": "hidden",
|
| 164 |
+
"whiteSpace": "pre",
|
| 165 |
+
}
|
| 166 |
+
}
|
| 167 |
+
>
|
| 168 |
+
|
| 169 |
+
</div>
|
| 170 |
+
</div>
|
| 171 |
+
</div>
|
| 172 |
+
</div>
|
| 173 |
+
<div
|
| 174 |
+
className="css-1wy0on6 tribe-editor__creatable-select__indicators"
|
| 175 |
+
>
|
| 176 |
+
<div
|
| 177 |
+
aria-hidden="true"
|
| 178 |
+
className="css-1ep9fjw tribe-editor__creatable-select__indicator tribe-editor__creatable-select__dropdown-indicator"
|
| 179 |
+
onMouseDown={[Function]}
|
| 180 |
+
onTouchEnd={[Function]}
|
| 181 |
+
>
|
| 182 |
+
<span
|
| 183 |
+
className="tribe-editor__creatable-select__dropdown-indicator"
|
| 184 |
+
>
|
| 185 |
+
arrow-down
|
| 186 |
+
</span>
|
| 187 |
+
</div>
|
| 188 |
+
</div>
|
| 189 |
+
</div>
|
| 190 |
+
</div>
|
| 191 |
+
`;
|
| 192 |
+
|
| 193 |
+
exports[`CreatableSelect element Should render the component with extra props 1`] = `
|
| 194 |
+
<div
|
| 195 |
+
className="css-10nd86i tribe-editor__creatable-select"
|
| 196 |
+
onKeyDown={[Function]}
|
| 197 |
+
>
|
| 198 |
+
<div
|
| 199 |
+
className="css-vj8t7z tribe-editor__creatable-select__control"
|
| 200 |
+
onMouseDown={[Function]}
|
| 201 |
+
onTouchEnd={[Function]}
|
| 202 |
+
>
|
| 203 |
+
<div
|
| 204 |
+
className="css-1hwfws3 tribe-editor__creatable-select__value-container"
|
| 205 |
+
>
|
| 206 |
+
<div
|
| 207 |
+
className="css-1492t68 tribe-editor__creatable-select__placeholder"
|
| 208 |
+
>
|
| 209 |
+
Select...
|
| 210 |
+
</div>
|
| 211 |
+
<input
|
| 212 |
+
className="css-14uuagi"
|
| 213 |
+
disabled={false}
|
| 214 |
+
id="react-select-4-input"
|
| 215 |
+
onBlur={[Function]}
|
| 216 |
+
onChange={[Function]}
|
| 217 |
+
onFocus={[Function]}
|
| 218 |
+
readOnly={true}
|
| 219 |
+
tabIndex="0"
|
| 220 |
+
value=""
|
| 221 |
+
/>
|
| 222 |
+
</div>
|
| 223 |
+
<div
|
| 224 |
+
className="css-1wy0on6 tribe-editor__creatable-select__indicators"
|
| 225 |
+
>
|
| 226 |
+
<div
|
| 227 |
+
aria-hidden="true"
|
| 228 |
+
className="css-1ep9fjw tribe-editor__creatable-select__indicator tribe-editor__creatable-select__dropdown-indicator"
|
| 229 |
+
onMouseDown={[Function]}
|
| 230 |
+
onTouchEnd={[Function]}
|
| 231 |
+
>
|
| 232 |
+
<span
|
| 233 |
+
className="tribe-editor__creatable-select__dropdown-indicator"
|
| 234 |
+
>
|
| 235 |
+
arrow-down
|
| 236 |
+
</span>
|
| 237 |
+
</div>
|
| 238 |
+
</div>
|
| 239 |
+
</div>
|
| 240 |
+
</div>
|
| 241 |
+
`;
|
common/src/modules/elements/creatable-select/__tests__/element.test.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import React from 'react';
|
| 5 |
+
|
| 6 |
+
/**
|
| 7 |
+
* Internal dependencies
|
| 8 |
+
*/
|
| 9 |
+
import CreatableSelect from '../element.js';
|
| 10 |
+
|
| 11 |
+
const options = [
|
| 12 |
+
{ label: 'Test 1', value: 'test-1' },
|
| 13 |
+
{ label: 'Test 2', value: 'test-2' },
|
| 14 |
+
];
|
| 15 |
+
|
| 16 |
+
describe( 'CreatableSelect element', () => {
|
| 17 |
+
it( 'Should render the component', () => {
|
| 18 |
+
const component = renderer.create( <CreatableSelect options={ options } /> );
|
| 19 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 20 |
+
} );
|
| 21 |
+
|
| 22 |
+
it( 'Should render the component with class', () => {
|
| 23 |
+
const component = renderer.create( <CreatableSelect options={ options } className="test-class" /> );
|
| 24 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 25 |
+
} );
|
| 26 |
+
|
| 27 |
+
it( 'Should render the component with extra props', () => {
|
| 28 |
+
const component = renderer.create( <CreatableSelect options={ options } isSearchable={ false } /> );
|
| 29 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 30 |
+
} );
|
| 31 |
+
} );
|
common/src/modules/elements/creatable-select/element.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import React from 'react';
|
| 5 |
+
import PropTypes from 'prop-types';
|
| 6 |
+
import classNames from 'classnames';
|
| 7 |
+
import { components } from 'react-select';
|
| 8 |
+
import ReactCreatableSelect from 'react-select/lib/Creatable';
|
| 9 |
+
import { Dashicon } from '@wordpress/components';
|
| 10 |
+
|
| 11 |
+
/**
|
| 12 |
+
* Internal dependencies
|
| 13 |
+
*/
|
| 14 |
+
import './style.pcss';
|
| 15 |
+
|
| 16 |
+
const DropdownIndicator = ( props ) => (
|
| 17 |
+
components.DropdownIndicator && (
|
| 18 |
+
<components.DropdownIndicator { ...props }>
|
| 19 |
+
<Dashicon
|
| 20 |
+
className="tribe-editor__creatable-select__dropdown-indicator"
|
| 21 |
+
icon={ 'arrow-down' }
|
| 22 |
+
/>
|
| 23 |
+
</components.DropdownIndicator>
|
| 24 |
+
)
|
| 25 |
+
);
|
| 26 |
+
|
| 27 |
+
const IndicatorSeparator = () => null;
|
| 28 |
+
|
| 29 |
+
/**
|
| 30 |
+
* There seems to be an issue with Creatable and a custom isValidNewOption
|
| 31 |
+
* prop needs to be passed in for this to work.
|
| 32 |
+
*
|
| 33 |
+
* See:
|
| 34 |
+
* - https://github.com/JedWatson/react-select/issues/2630
|
| 35 |
+
* - https://github.com/JedWatson/react-select/issues/2944
|
| 36 |
+
*/
|
| 37 |
+
const CreatableSelect = ( { className, ...rest } ) => (
|
| 38 |
+
<ReactCreatableSelect
|
| 39 |
+
className={ classNames( 'tribe-editor__creatable-select', className ) }
|
| 40 |
+
classNamePrefix="tribe-editor__creatable-select"
|
| 41 |
+
components={ { DropdownIndicator, IndicatorSeparator } }
|
| 42 |
+
{ ...rest }
|
| 43 |
+
/>
|
| 44 |
+
);
|
| 45 |
+
|
| 46 |
+
CreatableSelect.propTypes = {
|
| 47 |
+
className: PropTypes.string,
|
| 48 |
+
};
|
| 49 |
+
|
| 50 |
+
export default CreatableSelect;
|
common/src/modules/elements/creatable-select/style.pcss
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
.tribe-editor__creatable-select {
|
| 2 |
+
|
| 3 |
+
.tribe-editor__creatable-select__control {
|
| 4 |
+
height: 40px;
|
| 5 |
+
border: 1px solid #E1E3E6;
|
| 6 |
+
border-radius: 3px;
|
| 7 |
+
background-color: #FFFFFF;
|
| 8 |
+
|
| 9 |
+
&:hover {
|
| 10 |
+
border: 1px solid #E1E3E6;
|
| 11 |
+
}
|
| 12 |
+
|
| 13 |
+
&--is-focused {
|
| 14 |
+
box-shadow: none;
|
| 15 |
+
}
|
| 16 |
+
}
|
| 17 |
+
|
| 18 |
+
.tribe-editor__creatable-select__value-container {
|
| 19 |
+
padding: 2px 5px 2px 15px;
|
| 20 |
+
}
|
| 21 |
+
|
| 22 |
+
.tribe-editor__creatable-select__single-value {
|
| 23 |
+
margin: 0;
|
| 24 |
+
max-width: calc(100% - 15px);
|
| 25 |
+
font-size: 16px;
|
| 26 |
+
line-height: 1.5;
|
| 27 |
+
}
|
| 28 |
+
|
| 29 |
+
.tribe-editor__creatable-select__input {
|
| 30 |
+
font-size: 16px;
|
| 31 |
+
|
| 32 |
+
& > input {
|
| 33 |
+
margin: 0;
|
| 34 |
+
line-height: 1.5;
|
| 35 |
+
|
| 36 |
+
&,
|
| 37 |
+
&:focus {
|
| 38 |
+
box-shadow: none;
|
| 39 |
+
}
|
| 40 |
+
}
|
| 41 |
+
}
|
| 42 |
+
|
| 43 |
+
svg.tribe-editor__creatable-select__dropdown-indicator {
|
| 44 |
+
fill: #555D66;
|
| 45 |
+
}
|
| 46 |
+
|
| 47 |
+
.tribe-editor__creatable-select__menu {
|
| 48 |
+
margin: 0;
|
| 49 |
+
border: 1px solid #E1E3E6;
|
| 50 |
+
border-top: none;
|
| 51 |
+
border-radius: 0;
|
| 52 |
+
border-bottom-left-radius: 3px;
|
| 53 |
+
border-bottom-right-radius: 3px;
|
| 54 |
+
box-shadow: none;
|
| 55 |
+
transform: translateY(-7px);
|
| 56 |
+
}
|
| 57 |
+
|
| 58 |
+
.tribe-editor__creatable-select__menu-list {
|
| 59 |
+
padding: 0;
|
| 60 |
+
}
|
| 61 |
+
|
| 62 |
+
.tribe-editor__creatable-select__option {
|
| 63 |
+
font-size: 16px;
|
| 64 |
+
line-height: 1.5;
|
| 65 |
+
padding: 3px 15px;
|
| 66 |
+
|
| 67 |
+
&--is-focused {
|
| 68 |
+
background-color: #E7F5FA;
|
| 69 |
+
}
|
| 70 |
+
|
| 71 |
+
&--is-selected {
|
| 72 |
+
background-color: #11A0D2;
|
| 73 |
+
}
|
| 74 |
+
}
|
| 75 |
+
}
|
common/src/modules/elements/day-picker-input/element.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import React from 'react';
|
| 5 |
+
import classNames from 'classnames';
|
| 6 |
+
import 'react-day-picker/lib/style.css';
|
| 7 |
+
import ReactDayPickerInput from 'react-day-picker/DayPickerInput';
|
| 8 |
+
|
| 9 |
+
/**
|
| 10 |
+
* Internal dependencies
|
| 11 |
+
*/
|
| 12 |
+
import './style.pcss';
|
| 13 |
+
|
| 14 |
+
const DayPickerInput = ( props ) => (
|
| 15 |
+
<ReactDayPickerInput
|
| 16 |
+
classNames={ {
|
| 17 |
+
container: classNames(
|
| 18 |
+
'tribe-editor__day-picker-input',
|
| 19 |
+
'DayPickerInput',
|
| 20 |
+
),
|
| 21 |
+
overlayWrapper: classNames(
|
| 22 |
+
'tribe-editor__day-picker-input__overlay-wrapper',
|
| 23 |
+
'DayPickerInput-OverlayWrapper',
|
| 24 |
+
),
|
| 25 |
+
overlay: classNames(
|
| 26 |
+
'tribe-editor__day-picker-input__overlay',
|
| 27 |
+
'DayPickerInput-Overlay',
|
| 28 |
+
),
|
| 29 |
+
} }
|
| 30 |
+
{ ...props }
|
| 31 |
+
/>
|
| 32 |
+
);
|
| 33 |
+
|
| 34 |
+
export default DayPickerInput;
|
common/src/modules/elements/day-picker-input/style.pcss
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
.tribe-editor__day-picker-input.DayPickerInput {
|
| 2 |
+
|
| 3 |
+
& > input {
|
| 4 |
+
border: 1px solid #e1e3e6;
|
| 5 |
+
color: #545d66;
|
| 6 |
+
font-size: 16px;
|
| 7 |
+
line-height: 24px;
|
| 8 |
+
padding: 7px 15px;
|
| 9 |
+
width: 100%;
|
| 10 |
+
height: 40px;
|
| 11 |
+
|
| 12 |
+
&:disabled {
|
| 13 |
+
color: #AEB4BB;
|
| 14 |
+
}
|
| 15 |
+
}
|
| 16 |
+
}
|
| 17 |
+
|
| 18 |
+
/* -----------------------------------------------------------
|
| 19 |
+
DayPicker Input Calender Styles
|
| 20 |
+
----------------------------------------------------------- */
|
| 21 |
+
|
| 22 |
+
.tribe-editor__day-picker-input {
|
| 23 |
+
|
| 24 |
+
.DayPickerInput-Overlay {
|
| 25 |
+
padding: 20px;
|
| 26 |
+
z-index: 10;
|
| 27 |
+
}
|
| 28 |
+
|
| 29 |
+
.DayPicker {
|
| 30 |
+
width: 100%;
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
.DayPicker-Month {
|
| 34 |
+
margin: 0;
|
| 35 |
+
}
|
| 36 |
+
|
| 37 |
+
.DayPicker-Caption > div,
|
| 38 |
+
.DayPicker-Weekday,
|
| 39 |
+
.DayPicker-Day {
|
| 40 |
+
color: #545d66;
|
| 41 |
+
font-family: 'Helvetica', 'sans-serif';
|
| 42 |
+
font-weight: normal;
|
| 43 |
+
}
|
| 44 |
+
|
| 45 |
+
.DayPicker-Caption > div {
|
| 46 |
+
font-size: 16px;
|
| 47 |
+
margin-bottom: 12px;
|
| 48 |
+
text-align: center;
|
| 49 |
+
}
|
| 50 |
+
|
| 51 |
+
.DayPicker-Weekday {
|
| 52 |
+
font-size: 12px;
|
| 53 |
+
}
|
| 54 |
+
|
| 55 |
+
.DayPicker-Day {
|
| 56 |
+
font-size: 14px;
|
| 57 |
+
|
| 58 |
+
&:hover {
|
| 59 |
+
color: #007bb4;
|
| 60 |
+
background-color: #ffffff;
|
| 61 |
+
}
|
| 62 |
+
}
|
| 63 |
+
|
| 64 |
+
.DayPicker-Day--today {
|
| 65 |
+
color: #545D66;
|
| 66 |
+
}
|
| 67 |
+
|
| 68 |
+
.DayPicker-Day--disabled {
|
| 69 |
+
pointer-events: none;
|
| 70 |
+
color: #cccccc;
|
| 71 |
+
}
|
| 72 |
+
|
| 73 |
+
.DayPicker-Day--selected:not(.DayPicker-Day--outside) {
|
| 74 |
+
border-radius: 0;
|
| 75 |
+
background-color: #009fd4;
|
| 76 |
+
color: #ffffff;
|
| 77 |
+
|
| 78 |
+
&:hover {
|
| 79 |
+
background-color: #007bb4;
|
| 80 |
+
color: #ffffff;
|
| 81 |
+
}
|
| 82 |
+
}
|
| 83 |
+
|
| 84 |
+
.DayPicker-NavButton--prev {
|
| 85 |
+
left: 0;
|
| 86 |
+
top: 0;
|
| 87 |
+
}
|
| 88 |
+
|
| 89 |
+
.DayPicker-NavButton--next {
|
| 90 |
+
right: 0;
|
| 91 |
+
top: 0;
|
| 92 |
+
}
|
| 93 |
+
|
| 94 |
+
.DayPicker:not(.DayPicker--interactionDisabled) .DayPicker-Day:not(.DayPicker-Day--disabled):not(.DayPicker-Day--selected):not(.DayPicker-Day--outside) {
|
| 95 |
+
|
| 96 |
+
&:hover {
|
| 97 |
+
background-color: #ffffff;
|
| 98 |
+
}
|
| 99 |
+
}
|
| 100 |
+
|
| 101 |
+
.DayPicker-Day--selected:not(.DayPicker-Day--start):not(.DayPicker-Day--end):not(.DayPicker-Day--outside) {
|
| 102 |
+
background-color: #e7f5fa;
|
| 103 |
+
color: #545d66;
|
| 104 |
+
|
| 105 |
+
&:hover {
|
| 106 |
+
color: #007bb4;
|
| 107 |
+
}
|
| 108 |
+
}
|
| 109 |
+
}
|
common/src/modules/elements/heading/__tests__/__snapshots__/element.test.js.snap
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
| 2 |
+
|
| 3 |
+
exports[`<Heading> <h1> 1`] = `
|
| 4 |
+
<h1
|
| 5 |
+
className="tribe-editor__heading tribe-editor__heading--h1"
|
| 6 |
+
>
|
| 7 |
+
Modern Tribe
|
| 8 |
+
</h1>
|
| 9 |
+
`;
|
| 10 |
+
|
| 11 |
+
exports[`<Heading> <h2> 1`] = `
|
| 12 |
+
<h2
|
| 13 |
+
className="tribe-editor__heading tribe-editor__heading--h2"
|
| 14 |
+
>
|
| 15 |
+
Modern Tribe
|
| 16 |
+
</h2>
|
| 17 |
+
`;
|
| 18 |
+
|
| 19 |
+
exports[`<Heading> <h3> 1`] = `
|
| 20 |
+
<h3
|
| 21 |
+
className="tribe-editor__heading tribe-editor__heading--h3"
|
| 22 |
+
>
|
| 23 |
+
Modern Tribe
|
| 24 |
+
</h3>
|
| 25 |
+
`;
|
| 26 |
+
|
| 27 |
+
exports[`<Heading> <h4> 1`] = `
|
| 28 |
+
<h4
|
| 29 |
+
className="tribe-editor__heading tribe-editor__heading--h4"
|
| 30 |
+
>
|
| 31 |
+
Modern Tribe
|
| 32 |
+
</h4>
|
| 33 |
+
`;
|
| 34 |
+
|
| 35 |
+
exports[`<Heading> <h5> 1`] = `
|
| 36 |
+
<h5
|
| 37 |
+
className="tribe-editor__heading tribe-editor__heading--h5"
|
| 38 |
+
>
|
| 39 |
+
Modern Tribe
|
| 40 |
+
</h5>
|
| 41 |
+
`;
|
| 42 |
+
|
| 43 |
+
exports[`<Heading> <h6> 1`] = `
|
| 44 |
+
<h6
|
| 45 |
+
className="tribe-editor__heading tribe-editor__heading--h6"
|
| 46 |
+
>
|
| 47 |
+
Modern Tribe
|
| 48 |
+
</h6>
|
| 49 |
+
`;
|
common/src/modules/elements/heading/__tests__/element.test.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import React from 'react';
|
| 2 |
+
|
| 3 |
+
import Heading from '../element';
|
| 4 |
+
|
| 5 |
+
describe( '<Heading>', () => {
|
| 6 |
+
test( '<h1>', () => {
|
| 7 |
+
const component = renderer.create(
|
| 8 |
+
<Heading level={ 1 }>Modern Tribe</Heading>,
|
| 9 |
+
);
|
| 10 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 11 |
+
} );
|
| 12 |
+
|
| 13 |
+
test( '<h2>', () => {
|
| 14 |
+
const component = renderer.create(
|
| 15 |
+
<Heading level={ 2 }>Modern Tribe</Heading>,
|
| 16 |
+
);
|
| 17 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 18 |
+
} );
|
| 19 |
+
|
| 20 |
+
test( '<h3>', () => {
|
| 21 |
+
const component = renderer.create(
|
| 22 |
+
<Heading level={ 3 }>Modern Tribe</Heading>,
|
| 23 |
+
);
|
| 24 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 25 |
+
} );
|
| 26 |
+
|
| 27 |
+
test( '<h4>', () => {
|
| 28 |
+
const component = renderer.create(
|
| 29 |
+
<Heading level={ 4 }>Modern Tribe</Heading>,
|
| 30 |
+
);
|
| 31 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 32 |
+
} );
|
| 33 |
+
|
| 34 |
+
test( '<h5>', () => {
|
| 35 |
+
const component = renderer.create(
|
| 36 |
+
<Heading level={ 5 }>Modern Tribe</Heading>,
|
| 37 |
+
);
|
| 38 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 39 |
+
} );
|
| 40 |
+
|
| 41 |
+
test( '<h6>', () => {
|
| 42 |
+
const component = renderer.create(
|
| 43 |
+
<Heading level={ 6 }>Modern Tribe</Heading>,
|
| 44 |
+
);
|
| 45 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 46 |
+
} );
|
| 47 |
+
} );
|
common/src/modules/elements/heading/element.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import React from 'react';
|
| 5 |
+
import PropTypes from 'prop-types';
|
| 6 |
+
import classNames from 'classnames';
|
| 7 |
+
|
| 8 |
+
/**
|
| 9 |
+
* Internal dependencies
|
| 10 |
+
*/
|
| 11 |
+
import './style.pcss';
|
| 12 |
+
|
| 13 |
+
const Heading = ( { level, children, className } ) => {
|
| 14 |
+
const HeadingLevel = `h${ level }`;
|
| 15 |
+
const headingClassName = classNames(
|
| 16 |
+
'tribe-editor__heading',
|
| 17 |
+
`tribe-editor__heading--h${ level }`,
|
| 18 |
+
className,
|
| 19 |
+
);
|
| 20 |
+
return (
|
| 21 |
+
<HeadingLevel className={ headingClassName }>
|
| 22 |
+
{ children }
|
| 23 |
+
</HeadingLevel>
|
| 24 |
+
);
|
| 25 |
+
};
|
| 26 |
+
|
| 27 |
+
Heading.propTypes = {
|
| 28 |
+
children: PropTypes.node.isRequired,
|
| 29 |
+
level: PropTypes.oneOf( [ 1, 2, 3, 4, 5, 6 ] ).isRequired,
|
| 30 |
+
};
|
| 31 |
+
|
| 32 |
+
export default Heading;
|
common/src/modules/elements/heading/style.pcss
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
.tribe-editor__heading {
|
| 2 |
+
font-family: 'Helvetica', 'Arial', 'sans-serif';
|
| 3 |
+
color: #000;
|
| 4 |
+
}
|
| 5 |
+
|
| 6 |
+
.tribe-editor__heading--h1 {
|
| 7 |
+
font-size: 2.375rem; /* 38pts */
|
| 8 |
+
}
|
| 9 |
+
|
| 10 |
+
.tribe-editor__heading--h2 {
|
| 11 |
+
font-size: 1.3125rem; /* 21pts */
|
| 12 |
+
}
|
| 13 |
+
|
| 14 |
+
.tribe-editor__heading--h3 {
|
| 15 |
+
font-size: 1rem; /* 16pts */
|
| 16 |
+
}
|
common/src/modules/elements/image-upload/__tests__/__snapshots__/element.test.js.snap
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
| 2 |
+
|
| 3 |
+
exports[`ImageUpload renders the component 1`] = `
|
| 4 |
+
<div
|
| 5 |
+
className="tribe-editor__image-upload"
|
| 6 |
+
>
|
| 7 |
+
<div
|
| 8 |
+
className="tribe-editor__image-upload__content"
|
| 9 |
+
>
|
| 10 |
+
<button>
|
| 11 |
+
Media Upload
|
| 12 |
+
</button>
|
| 13 |
+
</div>
|
| 14 |
+
</div>
|
| 15 |
+
`;
|
| 16 |
+
|
| 17 |
+
exports[`ImageUpload renders upload image button 1`] = `
|
| 18 |
+
<div
|
| 19 |
+
className="tribe-editor__image-upload"
|
| 20 |
+
>
|
| 21 |
+
<div
|
| 22 |
+
className="tribe-editor__image-upload__content"
|
| 23 |
+
>
|
| 24 |
+
<button>
|
| 25 |
+
Media Upload
|
| 26 |
+
</button>
|
| 27 |
+
</div>
|
| 28 |
+
</div>
|
| 29 |
+
`;
|
| 30 |
+
|
| 31 |
+
exports[`ImageUpload renders uploaded image 1`] = `
|
| 32 |
+
<div
|
| 33 |
+
className="tribe-editor__image-upload tribe-editor__image-upload--has-image"
|
| 34 |
+
>
|
| 35 |
+
<div
|
| 36 |
+
className="tribe-editor__image-upload__content"
|
| 37 |
+
>
|
| 38 |
+
<div
|
| 39 |
+
className="tribe-editor__image-upload__image-wrapper"
|
| 40 |
+
>
|
| 41 |
+
<img
|
| 42 |
+
alt="test-alt"
|
| 43 |
+
className="tribe-editor__image tribe-editor__image-upload__image"
|
| 44 |
+
src="test-src"
|
| 45 |
+
/>
|
| 46 |
+
<button
|
| 47 |
+
className="tribe-editor__button tribe-editor__image-upload__remove-button"
|
| 48 |
+
onClick={[MockFunction]}
|
| 49 |
+
type="button"
|
| 50 |
+
>
|
| 51 |
+
<span>
|
| 52 |
+
icon
|
| 53 |
+
</span>
|
| 54 |
+
<span
|
| 55 |
+
className="tribe-editor__image-upload__remove-button-text"
|
| 56 |
+
>
|
| 57 |
+
remove
|
| 58 |
+
</span>
|
| 59 |
+
</button>
|
| 60 |
+
</div>
|
| 61 |
+
</div>
|
| 62 |
+
</div>
|
| 63 |
+
`;
|
| 64 |
+
|
| 65 |
+
exports[`ImageUpload renders with class 1`] = `
|
| 66 |
+
<div
|
| 67 |
+
className="tribe-editor__image-upload test-class"
|
| 68 |
+
>
|
| 69 |
+
<div
|
| 70 |
+
className="tribe-editor__image-upload__content"
|
| 71 |
+
>
|
| 72 |
+
<button>
|
| 73 |
+
Media Upload
|
| 74 |
+
</button>
|
| 75 |
+
</div>
|
| 76 |
+
</div>
|
| 77 |
+
`;
|
| 78 |
+
|
| 79 |
+
exports[`ImageUpload renders with description 1`] = `
|
| 80 |
+
<div
|
| 81 |
+
className="tribe-editor__image-upload"
|
| 82 |
+
>
|
| 83 |
+
<div
|
| 84 |
+
className="tribe-editor__image-upload__content"
|
| 85 |
+
>
|
| 86 |
+
<p
|
| 87 |
+
className="tribe-editor__image-upload__description"
|
| 88 |
+
>
|
| 89 |
+
The Next Generation of Digital Agency
|
| 90 |
+
</p>
|
| 91 |
+
<button>
|
| 92 |
+
Media Upload
|
| 93 |
+
</button>
|
| 94 |
+
</div>
|
| 95 |
+
</div>
|
| 96 |
+
`;
|
| 97 |
+
|
| 98 |
+
exports[`ImageUpload renders with title 1`] = `
|
| 99 |
+
<div
|
| 100 |
+
className="tribe-editor__image-upload"
|
| 101 |
+
>
|
| 102 |
+
<h3
|
| 103 |
+
className="tribe-editor__image-upload__title"
|
| 104 |
+
>
|
| 105 |
+
Modern Tribe
|
| 106 |
+
</h3>
|
| 107 |
+
<div
|
| 108 |
+
className="tribe-editor__image-upload__content"
|
| 109 |
+
>
|
| 110 |
+
<button>
|
| 111 |
+
Media Upload
|
| 112 |
+
</button>
|
| 113 |
+
</div>
|
| 114 |
+
</div>
|
| 115 |
+
`;
|
| 116 |
+
|
| 117 |
+
exports[`renderImage renders the image and button 1`] = `
|
| 118 |
+
<div
|
| 119 |
+
className="tribe-editor__image-upload__image-wrapper"
|
| 120 |
+
>
|
| 121 |
+
<img
|
| 122 |
+
alt="test-alt"
|
| 123 |
+
className="tribe-editor__image tribe-editor__image-upload__image"
|
| 124 |
+
src="test-src"
|
| 125 |
+
/>
|
| 126 |
+
<button
|
| 127 |
+
className="tribe-editor__button tribe-editor__image-upload__remove-button"
|
| 128 |
+
disabled={false}
|
| 129 |
+
onClick={[MockFunction]}
|
| 130 |
+
type="button"
|
| 131 |
+
>
|
| 132 |
+
<span>
|
| 133 |
+
icon
|
| 134 |
+
</span>
|
| 135 |
+
<span
|
| 136 |
+
className="tribe-editor__image-upload__remove-button-text"
|
| 137 |
+
>
|
| 138 |
+
remove
|
| 139 |
+
</span>
|
| 140 |
+
</button>
|
| 141 |
+
</div>
|
| 142 |
+
`;
|
| 143 |
+
|
| 144 |
+
exports[`renderImage renders the image and disabled button 1`] = `
|
| 145 |
+
<div
|
| 146 |
+
className="tribe-editor__image-upload__image-wrapper"
|
| 147 |
+
>
|
| 148 |
+
<img
|
| 149 |
+
alt="test-alt"
|
| 150 |
+
className="tribe-editor__image tribe-editor__image-upload__image"
|
| 151 |
+
src="test-src"
|
| 152 |
+
/>
|
| 153 |
+
<button
|
| 154 |
+
className="tribe-editor__button tribe-editor__image-upload__remove-button"
|
| 155 |
+
disabled={true}
|
| 156 |
+
onClick={[MockFunction]}
|
| 157 |
+
type="button"
|
| 158 |
+
>
|
| 159 |
+
<span>
|
| 160 |
+
icon
|
| 161 |
+
</span>
|
| 162 |
+
<span
|
| 163 |
+
className="tribe-editor__image-upload__remove-button-text"
|
| 164 |
+
>
|
| 165 |
+
remove
|
| 166 |
+
</span>
|
| 167 |
+
</button>
|
| 168 |
+
</div>
|
| 169 |
+
`;
|
| 170 |
+
|
| 171 |
+
exports[`renderImageUploadButton renders the button 1`] = `
|
| 172 |
+
<button
|
| 173 |
+
className="tribe-editor__button tribe-editor__button--sm tribe-editor__image-upload__upload-button"
|
| 174 |
+
disabled={false}
|
| 175 |
+
onClick={[MockFunction]}
|
| 176 |
+
type="button"
|
| 177 |
+
>
|
| 178 |
+
label
|
| 179 |
+
</button>
|
| 180 |
+
`;
|
| 181 |
+
|
| 182 |
+
exports[`renderImageUploadButton renders the button disabled 1`] = `
|
| 183 |
+
<button
|
| 184 |
+
className="tribe-editor__button tribe-editor__button--sm tribe-editor__image-upload__upload-button"
|
| 185 |
+
disabled={true}
|
| 186 |
+
onClick={[MockFunction]}
|
| 187 |
+
type="button"
|
| 188 |
+
>
|
| 189 |
+
label
|
| 190 |
+
</button>
|
| 191 |
+
`;
|
common/src/modules/elements/image-upload/__tests__/element.test.js
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import React from 'react';
|
| 5 |
+
|
| 6 |
+
/**
|
| 7 |
+
* Internal dependencies
|
| 8 |
+
*/
|
| 9 |
+
import ImageUpload, {
|
| 10 |
+
renderImageUploadButton,
|
| 11 |
+
renderImage,
|
| 12 |
+
} from '@moderntribe/common/elements/image-upload/element';
|
| 13 |
+
|
| 14 |
+
jest.mock( '@wordpress/editor', () => ( {
|
| 15 |
+
MediaUpload: () => ( <button>Media Upload</button> ),
|
| 16 |
+
} ) );
|
| 17 |
+
|
| 18 |
+
jest.mock( '@moderntribe/common/icons', () => ( {
|
| 19 |
+
Close: () => <span>icon</span>,
|
| 20 |
+
} ) );
|
| 21 |
+
|
| 22 |
+
describe( 'renderImageUploadButton', () => {
|
| 23 |
+
const open = jest.fn();
|
| 24 |
+
|
| 25 |
+
afterEach( () => {
|
| 26 |
+
open.mockClear();
|
| 27 |
+
} );
|
| 28 |
+
|
| 29 |
+
it( 'renders the button', () => {
|
| 30 |
+
const component = renderer.create( renderImageUploadButton( false, 'label' )( { open } ) );
|
| 31 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 32 |
+
} );
|
| 33 |
+
|
| 34 |
+
it( 'renders the button disabled', () => {
|
| 35 |
+
const component = renderer.create( renderImageUploadButton( true, 'label' )( { open } ) );
|
| 36 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 37 |
+
} );
|
| 38 |
+
|
| 39 |
+
it( 'executes the open action when the mediaUpload is fired', () => {
|
| 40 |
+
const component = mount( renderImageUploadButton( false, 'label' )( { open } ) );
|
| 41 |
+
component.find( 'button' ).simulate( 'click' );
|
| 42 |
+
expect( open ).toHaveBeenCalled();
|
| 43 |
+
expect( open ).toHaveBeenCalledTimes( 1 );
|
| 44 |
+
} );
|
| 45 |
+
} );
|
| 46 |
+
|
| 47 |
+
describe( 'renderImage', () => {
|
| 48 |
+
const onRemove = jest.fn();
|
| 49 |
+
const image = {
|
| 50 |
+
id: 42,
|
| 51 |
+
src: 'test-src',
|
| 52 |
+
alt: 'test-alt',
|
| 53 |
+
};
|
| 54 |
+
|
| 55 |
+
afterEach( () => {
|
| 56 |
+
onRemove.mockClear();
|
| 57 |
+
} );
|
| 58 |
+
|
| 59 |
+
it( 'renders the image and button', () => {
|
| 60 |
+
const component = renderer.create( renderImage( false, image, onRemove ) );
|
| 61 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 62 |
+
} );
|
| 63 |
+
|
| 64 |
+
it( 'renders the image and disabled button', () => {
|
| 65 |
+
const component = renderer.create( renderImage( true, image, onRemove ) );
|
| 66 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 67 |
+
} );
|
| 68 |
+
|
| 69 |
+
it( 'executes onRemove on click', () => {
|
| 70 |
+
const component = mount( renderImage( false, image, onRemove ) );
|
| 71 |
+
component.find( 'button' ).simulate( 'click' );
|
| 72 |
+
expect( onRemove ).toHaveBeenCalled();
|
| 73 |
+
expect( onRemove ).toHaveBeenCalledTimes( 1 );
|
| 74 |
+
} );
|
| 75 |
+
} );
|
| 76 |
+
|
| 77 |
+
describe( 'ImageUpload', () => {
|
| 78 |
+
const onRemove = jest.fn();
|
| 79 |
+
const onSelect = jest.fn();
|
| 80 |
+
let image;
|
| 81 |
+
|
| 82 |
+
beforeEach( () => {
|
| 83 |
+
image = {
|
| 84 |
+
id: 0,
|
| 85 |
+
src: '',
|
| 86 |
+
alt: '',
|
| 87 |
+
};
|
| 88 |
+
} );
|
| 89 |
+
|
| 90 |
+
afterEach( () => {
|
| 91 |
+
onRemove.mockClear();
|
| 92 |
+
onSelect.mockClear();
|
| 93 |
+
} );
|
| 94 |
+
|
| 95 |
+
it( 'renders the component', () => {
|
| 96 |
+
const component = renderer.create(
|
| 97 |
+
<ImageUpload
|
| 98 |
+
image={ image }
|
| 99 |
+
onSelect={ onSelect }
|
| 100 |
+
onRemove={ onRemove }
|
| 101 |
+
/>
|
| 102 |
+
);
|
| 103 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 104 |
+
} );
|
| 105 |
+
|
| 106 |
+
it( 'renders with title', () => {
|
| 107 |
+
const component = renderer.create(
|
| 108 |
+
<ImageUpload
|
| 109 |
+
image={ image }
|
| 110 |
+
onSelect={ onSelect }
|
| 111 |
+
onRemove={ onRemove }
|
| 112 |
+
title="Modern Tribe"
|
| 113 |
+
/>
|
| 114 |
+
);
|
| 115 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 116 |
+
} );
|
| 117 |
+
|
| 118 |
+
it( 'renders with description', () => {
|
| 119 |
+
const component = renderer.create(
|
| 120 |
+
<ImageUpload
|
| 121 |
+
image={ image }
|
| 122 |
+
onSelect={ onSelect}
|
| 123 |
+
onRemove={ onRemove }
|
| 124 |
+
description="The Next Generation of Digital Agency"
|
| 125 |
+
/>
|
| 126 |
+
);
|
| 127 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 128 |
+
} );
|
| 129 |
+
|
| 130 |
+
it( 'renders with class', () => {
|
| 131 |
+
const component = renderer.create(
|
| 132 |
+
<ImageUpload
|
| 133 |
+
image={ image }
|
| 134 |
+
onSelect={ onSelect }
|
| 135 |
+
onRemove={ onRemove }
|
| 136 |
+
className="test-class"
|
| 137 |
+
/>
|
| 138 |
+
);
|
| 139 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 140 |
+
} );
|
| 141 |
+
|
| 142 |
+
it( 'renders uploaded image', () => {
|
| 143 |
+
image = {
|
| 144 |
+
id: 42,
|
| 145 |
+
src: 'test-src',
|
| 146 |
+
alt: 'test-alt',
|
| 147 |
+
};
|
| 148 |
+
const component = renderer.create(
|
| 149 |
+
<ImageUpload
|
| 150 |
+
image={ image }
|
| 151 |
+
onSelect={ onSelect }
|
| 152 |
+
onRemove={ onRemove }
|
| 153 |
+
/>
|
| 154 |
+
);
|
| 155 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 156 |
+
} );
|
| 157 |
+
|
| 158 |
+
it( 'renders upload image button', () => {
|
| 159 |
+
const component = renderer.create(
|
| 160 |
+
<ImageUpload
|
| 161 |
+
image={ image }
|
| 162 |
+
onSelect={ onSelect }
|
| 163 |
+
onRemove={ onRemove }
|
| 164 |
+
/>
|
| 165 |
+
);
|
| 166 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 167 |
+
} );
|
| 168 |
+
} );
|
common/src/modules/elements/image-upload/element.js
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import React from 'react';
|
| 5 |
+
import PropTypes from 'prop-types';
|
| 6 |
+
import classNames from 'classnames';
|
| 7 |
+
import { noop } from 'lodash';
|
| 8 |
+
|
| 9 |
+
/**
|
| 10 |
+
* WordPress dependencies
|
| 11 |
+
*/
|
| 12 |
+
import { __ } from '@wordpress/i18n';
|
| 13 |
+
import { MediaUpload } from '@wordpress/editor';
|
| 14 |
+
|
| 15 |
+
/**
|
| 16 |
+
* Internal dependencies
|
| 17 |
+
*/
|
| 18 |
+
import { Button, Image } from '@moderntribe/common/elements';
|
| 19 |
+
import { Close as CloseIcon } from '@moderntribe/common/icons';
|
| 20 |
+
import './style.pcss';
|
| 21 |
+
|
| 22 |
+
export const renderImageUploadButton = ( disabled, label ) => ( { open } ) => (
|
| 23 |
+
<Button
|
| 24 |
+
onClick={ open }
|
| 25 |
+
className={ [ 'tribe-editor__button--sm', 'tribe-editor__image-upload__upload-button' ] }
|
| 26 |
+
disabled={ disabled }
|
| 27 |
+
>
|
| 28 |
+
{ label }
|
| 29 |
+
</Button>
|
| 30 |
+
);
|
| 31 |
+
|
| 32 |
+
export const renderImage = ( disabled, image, onRemove ) => (
|
| 33 |
+
<div className="tribe-editor__image-upload__image-wrapper">
|
| 34 |
+
<Image
|
| 35 |
+
src={ image.src }
|
| 36 |
+
alt={ image.alt }
|
| 37 |
+
className="tribe-editor__image-upload__image"
|
| 38 |
+
/>
|
| 39 |
+
<Button
|
| 40 |
+
className="tribe-editor__image-upload__remove-button"
|
| 41 |
+
onClick={ onRemove }
|
| 42 |
+
disabled={ disabled }
|
| 43 |
+
>
|
| 44 |
+
<CloseIcon />
|
| 45 |
+
<span className="tribe-editor__image-upload__remove-button-text">
|
| 46 |
+
{ __( 'remove', 'tribe-common' ) }
|
| 47 |
+
</span>
|
| 48 |
+
</Button>
|
| 49 |
+
</div>
|
| 50 |
+
);
|
| 51 |
+
|
| 52 |
+
const ImageUpload = ( {
|
| 53 |
+
buttonDisabled,
|
| 54 |
+
buttonLabel,
|
| 55 |
+
className,
|
| 56 |
+
description,
|
| 57 |
+
image,
|
| 58 |
+
onRemove,
|
| 59 |
+
onSelect,
|
| 60 |
+
removeButtonDisabled,
|
| 61 |
+
title,
|
| 62 |
+
} ) => {
|
| 63 |
+
const hasImageClass = { 'tribe-editor__image-upload--has-image': image.id };
|
| 64 |
+
|
| 65 |
+
return (
|
| 66 |
+
<div className={ classNames(
|
| 67 |
+
'tribe-editor__image-upload',
|
| 68 |
+
hasImageClass,
|
| 69 |
+
className,
|
| 70 |
+
) }>
|
| 71 |
+
{ title && <h3 className="tribe-editor__image-upload__title">{ title }</h3> }
|
| 72 |
+
<div className="tribe-editor__image-upload__content">
|
| 73 |
+
{ description && (
|
| 74 |
+
<p className="tribe-editor__image-upload__description">{ description }</p>
|
| 75 |
+
) }
|
| 76 |
+
{
|
| 77 |
+
image.id
|
| 78 |
+
? renderImage( removeButtonDisabled, image, onRemove )
|
| 79 |
+
: (
|
| 80 |
+
<MediaUpload
|
| 81 |
+
onSelect={ onSelect }
|
| 82 |
+
type="image"
|
| 83 |
+
render={ renderImageUploadButton( buttonDisabled, buttonLabel ) }
|
| 84 |
+
value={ image.id }
|
| 85 |
+
/>
|
| 86 |
+
)
|
| 87 |
+
}
|
| 88 |
+
</div>
|
| 89 |
+
</div>
|
| 90 |
+
);
|
| 91 |
+
};
|
| 92 |
+
|
| 93 |
+
ImageUpload.propTypes = {
|
| 94 |
+
buttonDisabled: PropTypes.bool,
|
| 95 |
+
buttonLabel: PropTypes.string,
|
| 96 |
+
className: PropTypes.string,
|
| 97 |
+
description: PropTypes.string,
|
| 98 |
+
image: PropTypes.shape( {
|
| 99 |
+
alt: PropTypes.string.isRequired,
|
| 100 |
+
id: PropTypes.number.isRequired,
|
| 101 |
+
src: PropTypes.string.isRequired,
|
| 102 |
+
} ).isRequired,
|
| 103 |
+
onRemove: PropTypes.func.isRequired,
|
| 104 |
+
onSelect: PropTypes.func.isRequired,
|
| 105 |
+
removeButtonDisabled: PropTypes.bool,
|
| 106 |
+
title: PropTypes.string,
|
| 107 |
+
};
|
| 108 |
+
|
| 109 |
+
ImageUpload.defaultProps = {
|
| 110 |
+
onRemove: noop,
|
| 111 |
+
onSelect: noop,
|
| 112 |
+
};
|
| 113 |
+
|
| 114 |
+
export default ImageUpload;
|
common/src/modules/elements/image-upload/style.pcss
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
.tribe-editor__image-upload {}
|
| 2 |
+
|
| 3 |
+
.tribe-editor__image-upload__title {
|
| 4 |
+
|
| 5 |
+
/* extra classes to override gutenberg styles for h3 */
|
| 6 |
+
.edit-post-visual-editor .editor-block-list__block & {
|
| 7 |
+
padding: 0;
|
| 8 |
+
margin: 0 0 12px;
|
| 9 |
+
color: #000000;
|
| 10 |
+
font-size: 15px;
|
| 11 |
+
font-weight: bold;
|
| 12 |
+
line-height: 18px;
|
| 13 |
+
}
|
| 14 |
+
}
|
| 15 |
+
|
| 16 |
+
.tribe-editor__image-upload__content {
|
| 17 |
+
display: flex;
|
| 18 |
+
justify-content: space-between;
|
| 19 |
+
align-items: center;
|
| 20 |
+
|
| 21 |
+
.tribe-editor__image-upload--has-image & {
|
| 22 |
+
align-items: flex-start;
|
| 23 |
+
}
|
| 24 |
+
}
|
| 25 |
+
|
| 26 |
+
p.tribe-editor__image-upload__description {
|
| 27 |
+
|
| 28 |
+
.tribe-editor__image-upload__content & {
|
| 29 |
+
flex: none;
|
| 30 |
+
width: 52%;
|
| 31 |
+
font-family: Helvetica, sans-serif, arial;
|
| 32 |
+
font-size: 14px;
|
| 33 |
+
color: #545D66;
|
| 34 |
+
line-height: 18px;
|
| 35 |
+
margin: 0;
|
| 36 |
+
}
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
+
.tribe-editor__image-upload__upload-button {
|
| 40 |
+
flex: none;
|
| 41 |
+
margin-right: 10px;
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
.tribe-editor__image-upload__image-wrapper {
|
| 45 |
+
flex: none;
|
| 46 |
+
width: 42%;
|
| 47 |
+
max-width: 325px;
|
| 48 |
+
padding-left: 25px;
|
| 49 |
+
position: relative;
|
| 50 |
+
}
|
| 51 |
+
|
| 52 |
+
.tribe-editor__image-upload__remove-button {
|
| 53 |
+
position: absolute;
|
| 54 |
+
top: 10px;
|
| 55 |
+
right: 10px;
|
| 56 |
+
width: 32px;
|
| 57 |
+
height: 32px;
|
| 58 |
+
padding: 8px;
|
| 59 |
+
border-radius: 50%;
|
| 60 |
+
background-color: #F8F9FB;
|
| 61 |
+
|
| 62 |
+
& > svg {
|
| 63 |
+
|
| 64 |
+
&,
|
| 65 |
+
& path {
|
| 66 |
+
fill: #545D66;
|
| 67 |
+
}
|
| 68 |
+
}
|
| 69 |
+
|
| 70 |
+
&:hover,
|
| 71 |
+
&:focus {
|
| 72 |
+
|
| 73 |
+
& > svg {
|
| 74 |
+
|
| 75 |
+
&,
|
| 76 |
+
& path {
|
| 77 |
+
fill: #009FD4;
|
| 78 |
+
}
|
| 79 |
+
}
|
| 80 |
+
}
|
| 81 |
+
|
| 82 |
+
&:disabled {
|
| 83 |
+
|
| 84 |
+
&,
|
| 85 |
+
&:hover,
|
| 86 |
+
&:focus {
|
| 87 |
+
|
| 88 |
+
& > svg {
|
| 89 |
+
|
| 90 |
+
&,
|
| 91 |
+
& path {
|
| 92 |
+
fill: #AEB4BB;
|
| 93 |
+
}
|
| 94 |
+
}
|
| 95 |
+
}
|
| 96 |
+
}
|
| 97 |
+
}
|
| 98 |
+
|
| 99 |
+
/* visually hide remove button text */
|
| 100 |
+
.tribe-editor__image-upload__remove-button-text {
|
| 101 |
+
border: 0;
|
| 102 |
+
clip: rect(0 0 0 0);
|
| 103 |
+
height: 1px;
|
| 104 |
+
margin: -1px;
|
| 105 |
+
overflow: hidden;
|
| 106 |
+
padding: 0;
|
| 107 |
+
position: absolute;
|
| 108 |
+
width: 1px;
|
| 109 |
+
}
|
common/src/modules/elements/image/__tests__/__snapshots__/element.test.js.snap
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
| 2 |
+
|
| 3 |
+
exports[`Image Element renders image 1`] = `
|
| 4 |
+
<img
|
| 5 |
+
alt="test-alt"
|
| 6 |
+
className="tribe-editor__image"
|
| 7 |
+
src="test-src"
|
| 8 |
+
/>
|
| 9 |
+
`;
|
| 10 |
+
|
| 11 |
+
exports[`Image Element renders image with class 1`] = `
|
| 12 |
+
<img
|
| 13 |
+
alt="test-alt"
|
| 14 |
+
className="tribe-editor__image test-class"
|
| 15 |
+
src="test-src"
|
| 16 |
+
/>
|
| 17 |
+
`;
|
| 18 |
+
|
| 19 |
+
exports[`Image Element renders image with extra props 1`] = `
|
| 20 |
+
<img
|
| 21 |
+
alt="test-alt"
|
| 22 |
+
className="tribe-editor__image"
|
| 23 |
+
height="42"
|
| 24 |
+
src="test-src"
|
| 25 |
+
width="42"
|
| 26 |
+
/>
|
| 27 |
+
`;
|
common/src/modules/elements/image/__tests__/element.test.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import React from 'react';
|
| 5 |
+
|
| 6 |
+
/**
|
| 7 |
+
* Internal dependencies
|
| 8 |
+
*/
|
| 9 |
+
import { Image } from '@moderntribe/common/elements';
|
| 10 |
+
|
| 11 |
+
let imageProps;
|
| 12 |
+
|
| 13 |
+
describe( 'Image Element', () => {
|
| 14 |
+
beforeEach( () => {
|
| 15 |
+
imageProps = {
|
| 16 |
+
src: 'test-src',
|
| 17 |
+
alt: 'test-alt',
|
| 18 |
+
};
|
| 19 |
+
} );
|
| 20 |
+
|
| 21 |
+
it( 'renders image', () => {
|
| 22 |
+
const component = renderer.create( <Image { ...imageProps } /> );
|
| 23 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 24 |
+
} );
|
| 25 |
+
|
| 26 |
+
it( 'renders image with class', () => {
|
| 27 |
+
imageProps.className = 'test-class';
|
| 28 |
+
const component = renderer.create( <Image { ...imageProps } /> );
|
| 29 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 30 |
+
} );
|
| 31 |
+
|
| 32 |
+
it( 'renders image with extra props', () => {
|
| 33 |
+
imageProps.width = "42";
|
| 34 |
+
imageProps.height = "42";
|
| 35 |
+
const component = renderer.create( <Image { ...imageProps } /> );
|
| 36 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 37 |
+
} );
|
| 38 |
+
} );
|
common/src/modules/elements/image/element.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import React from 'react';
|
| 5 |
+
import PropTypes from 'prop-types';
|
| 6 |
+
import classNames from 'classnames';
|
| 7 |
+
|
| 8 |
+
const Image = ( {
|
| 9 |
+
alt,
|
| 10 |
+
className,
|
| 11 |
+
src,
|
| 12 |
+
...rest,
|
| 13 |
+
} ) => (
|
| 14 |
+
<img
|
| 15 |
+
src={ src }
|
| 16 |
+
alt={ alt }
|
| 17 |
+
className={ classNames( 'tribe-editor__image', className ) }
|
| 18 |
+
{ ...rest }
|
| 19 |
+
/>
|
| 20 |
+
);
|
| 21 |
+
|
| 22 |
+
Image.propTypes = {
|
| 23 |
+
alt: PropTypes.string.isRequired,
|
| 24 |
+
className: PropTypes.string,
|
| 25 |
+
src: PropTypes.string.isRequired,
|
| 26 |
+
};
|
| 27 |
+
|
| 28 |
+
export default Image;
|
common/src/modules/elements/index.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
export { default as Accordion } from './accordion/element';
|
| 2 |
+
export { default as BlockIcon } from '@moderntribe/common/elements/block-icon';
|
| 3 |
+
export { default as Button } from './button/element';
|
| 4 |
+
|
| 5 |
+
export { default as Counter } from './counter/element';
|
| 6 |
+
export { default as Image } from './image/element';
|
| 7 |
+
export { default as ImageUpload } from './image-upload/element';
|
| 8 |
+
export { default as LabeledItem } from './labeled-item/element';
|
| 9 |
+
export { default as LabelWithLink } from './label-with-link/element';
|
| 10 |
+
export { default as LabelWithModal } from './label-with-modal/element';
|
| 11 |
+
export { default as Link } from './link/element';
|
| 12 |
+
export { default as ModalButton } from './modal-button/element';
|
| 13 |
+
export { default as TimePicker } from './time-picker/element';
|
| 14 |
+
export { default as Tooltip } from './tooltip/element';
|
| 15 |
+
export { default as DayPickerInput } from './day-picker-input/element';
|
| 16 |
+
export { default as CreatableSelect } from './creatable-select/element';
|
| 17 |
+
export { default as Placeholder } from './placeholder/element';
|
| 18 |
+
export { default as Heading } from './heading/element';
|
| 19 |
+
export { default as Paragraph } from './paragraph/element';
|
| 20 |
+
|
| 21 |
+
// Inputs
|
| 22 |
+
export { default as Input } from './input/element';
|
| 23 |
+
export { default as UrlInput } from './url-input/element';
|
| 24 |
+
export { default as NumberInput } from './number-input/element';
|
| 25 |
+
export { default as Radio } from './radio/element';
|
| 26 |
+
export { default as RadioInput } from './radio-input/element';
|
| 27 |
+
export { default as Checkbox } from './checkbox/element';
|
| 28 |
+
export { default as CheckboxInput } from './checkbox-input/element';
|
| 29 |
+
export { default as Select } from './select/element';
|
| 30 |
+
export { default as Textarea } from './textarea/element';
|
| 31 |
+
|
| 32 |
+
/**
|
| 33 |
+
* @todo move this into Editor Module
|
| 34 |
+
*/
|
| 35 |
+
|
| 36 |
+
import './style.pcss'
|
common/src/modules/elements/input/__tests__/__snapshots__/element.test.js.snap
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
| 2 |
+
|
| 3 |
+
exports[`Input element Should render the component 1`] = `
|
| 4 |
+
<input
|
| 5 |
+
className="tribe-editor__input"
|
| 6 |
+
type="text"
|
| 7 |
+
/>
|
| 8 |
+
`;
|
| 9 |
+
|
| 10 |
+
exports[`Input element Should render the component with class 1`] = `
|
| 11 |
+
<input
|
| 12 |
+
className="tribe-editor__input input-class"
|
| 13 |
+
type="text"
|
| 14 |
+
/>
|
| 15 |
+
`;
|
| 16 |
+
|
| 17 |
+
exports[`Input element Should render the component with extra props 1`] = `
|
| 18 |
+
<input
|
| 19 |
+
className="tribe-editor__input"
|
| 20 |
+
onChange={[Function]}
|
| 21 |
+
type="text"
|
| 22 |
+
/>
|
| 23 |
+
`;
|
common/src/modules/elements/input/__tests__/element.test.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import React from 'react';
|
| 5 |
+
import renderer from 'react-test-renderer';
|
| 6 |
+
import { noop } from 'lodash';
|
| 7 |
+
|
| 8 |
+
/**
|
| 9 |
+
* Internal dependencies
|
| 10 |
+
*/
|
| 11 |
+
import Input from '../element.js';
|
| 12 |
+
|
| 13 |
+
describe( 'Input element', () => {
|
| 14 |
+
it( 'Should render the component', () => {
|
| 15 |
+
const component = renderer.create( <Input type="text" /> );
|
| 16 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 17 |
+
} );
|
| 18 |
+
|
| 19 |
+
it( 'Should render the component with class', () => {
|
| 20 |
+
const component = renderer.create( <Input type="text" className="input-class" /> );
|
| 21 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 22 |
+
} );
|
| 23 |
+
|
| 24 |
+
it( 'Should render the component with extra props', () => {
|
| 25 |
+
const component = renderer.create( <Input type="text" onChange={ noop } /> );
|
| 26 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 27 |
+
} );
|
| 28 |
+
} );
|
common/src/modules/elements/input/element.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External Dependencies
|
| 3 |
+
*/
|
| 4 |
+
import React from 'react';
|
| 5 |
+
import PropTypes from 'prop-types';
|
| 6 |
+
import classNames from 'classnames';
|
| 7 |
+
|
| 8 |
+
/**
|
| 9 |
+
* Internal dependencies
|
| 10 |
+
*/
|
| 11 |
+
import './style.pcss';
|
| 12 |
+
|
| 13 |
+
const Input = ( {
|
| 14 |
+
className,
|
| 15 |
+
type,
|
| 16 |
+
...rest,
|
| 17 |
+
} ) => (
|
| 18 |
+
<input
|
| 19 |
+
className={ classNames( 'tribe-editor__input', className ) }
|
| 20 |
+
type={ type }
|
| 21 |
+
{ ...rest }
|
| 22 |
+
/>
|
| 23 |
+
);
|
| 24 |
+
|
| 25 |
+
Input.propTypes = {
|
| 26 |
+
className: PropTypes.string,
|
| 27 |
+
type: PropTypes.string.isRequired,
|
| 28 |
+
};
|
| 29 |
+
|
| 30 |
+
export default Input;
|
common/src/modules/elements/input/style.pcss
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* increased specificity required to override gutenberg editor styles */
|
| 2 |
+
input.tribe-editor__input {
|
| 3 |
+
|
| 4 |
+
/* this list will grow with more input types used */
|
| 5 |
+
&[type=number],
|
| 6 |
+
&[type=text] {
|
| 7 |
+
color: #000000;
|
| 8 |
+
font-size: 16px;
|
| 9 |
+
line-height: 24px;
|
| 10 |
+
border: 1px solid #E1E3E6;
|
| 11 |
+
padding: 7px 15px;
|
| 12 |
+
margin: 0;
|
| 13 |
+
height: 40px;
|
| 14 |
+
|
| 15 |
+
&:focus {
|
| 16 |
+
color: #000000;
|
| 17 |
+
box-shadow: none;
|
| 18 |
+
outline: none;
|
| 19 |
+
}
|
| 20 |
+
|
| 21 |
+
&:disabled {
|
| 22 |
+
color: #AEB4BB;
|
| 23 |
+
}
|
| 24 |
+
}
|
| 25 |
+
}
|
common/src/modules/elements/label-with-link/__tests__/__snapshots__/element.test.js.snap
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
| 2 |
+
|
| 3 |
+
exports[`Label With Link Element renders a label with link 1`] = `
|
| 4 |
+
<div
|
| 5 |
+
className="tribe-editor__labeled-item tribe-editor__label-with-link"
|
| 6 |
+
>
|
| 7 |
+
<span
|
| 8 |
+
className="tribe-editor__labeled-item__label"
|
| 9 |
+
/>
|
| 10 |
+
<a
|
| 11 |
+
className="tribe-editor__link tribe-editor__label-with-link__link"
|
| 12 |
+
href="#"
|
| 13 |
+
>
|
| 14 |
+
test-text
|
| 15 |
+
</a>
|
| 16 |
+
</div>
|
| 17 |
+
`;
|
| 18 |
+
|
| 19 |
+
exports[`Label With Link Element renders a label with link with class 1`] = `
|
| 20 |
+
<div
|
| 21 |
+
className="tribe-editor__labeled-item tribe-editor__label-with-link test-class"
|
| 22 |
+
>
|
| 23 |
+
<span
|
| 24 |
+
className="tribe-editor__labeled-item__label"
|
| 25 |
+
/>
|
| 26 |
+
<a
|
| 27 |
+
className="tribe-editor__link tribe-editor__label-with-link__link"
|
| 28 |
+
href="#"
|
| 29 |
+
>
|
| 30 |
+
test-text
|
| 31 |
+
</a>
|
| 32 |
+
</div>
|
| 33 |
+
`;
|
| 34 |
+
|
| 35 |
+
exports[`Label With Link Element renders a label with link with label 1`] = `
|
| 36 |
+
<div
|
| 37 |
+
className="tribe-editor__labeled-item tribe-editor__label-with-link"
|
| 38 |
+
>
|
| 39 |
+
<span
|
| 40 |
+
className="tribe-editor__labeled-item__label"
|
| 41 |
+
>
|
| 42 |
+
test label
|
| 43 |
+
</span>
|
| 44 |
+
<a
|
| 45 |
+
className="tribe-editor__link tribe-editor__label-with-link__link"
|
| 46 |
+
href="#"
|
| 47 |
+
>
|
| 48 |
+
test-text
|
| 49 |
+
</a>
|
| 50 |
+
</div>
|
| 51 |
+
`;
|
common/src/modules/elements/label-with-link/__tests__/element.test.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import React from 'react';
|
| 5 |
+
|
| 6 |
+
/**
|
| 7 |
+
* Internal dependencies
|
| 8 |
+
*/
|
| 9 |
+
import LabelWithLink from '../element';
|
| 10 |
+
|
| 11 |
+
describe( 'Label With Link Element', () => {
|
| 12 |
+
it( 'renders a label with link', () => {
|
| 13 |
+
const component = renderer.create(
|
| 14 |
+
<LabelWithLink linkHref="#" linkText="test-text" />
|
| 15 |
+
);
|
| 16 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 17 |
+
} );
|
| 18 |
+
|
| 19 |
+
it( 'renders a label with link with class', () => {
|
| 20 |
+
const component = renderer.create(
|
| 21 |
+
<LabelWithLink linkHref="#" linkText="test-text" className="test-class" />
|
| 22 |
+
);
|
| 23 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 24 |
+
} );
|
| 25 |
+
|
| 26 |
+
it( 'renders a label with link with label', () => {
|
| 27 |
+
const component = renderer.create(
|
| 28 |
+
<LabelWithLink linkHref="#" linkText="test-text" label="test label" />
|
| 29 |
+
);
|
| 30 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 31 |
+
} );
|
| 32 |
+
} );
|
common/src/modules/elements/label-with-link/element.js
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import React from 'react';
|
| 5 |
+
import PropTypes from 'prop-types';
|
| 6 |
+
import classNames from 'classnames';
|
| 7 |
+
|
| 8 |
+
/**
|
| 9 |
+
* Internal dependencies
|
| 10 |
+
*/
|
| 11 |
+
import Button from '@moderntribe/common/elements/button/element';
|
| 12 |
+
import LabeledItem from '@moderntribe/common/elements/labeled-item/element';
|
| 13 |
+
import Link from '@moderntribe/common/elements/link/element';
|
| 14 |
+
import './style.pcss';
|
| 15 |
+
|
| 16 |
+
const LabelWithLink = ( {
|
| 17 |
+
className,
|
| 18 |
+
label,
|
| 19 |
+
linkDisabled,
|
| 20 |
+
linkHref,
|
| 21 |
+
linkTarget,
|
| 22 |
+
linkText,
|
| 23 |
+
} ) => {
|
| 24 |
+
const getLink = () => {
|
| 25 |
+
const linkClass = 'tribe-editor__label-with-link__link';
|
| 26 |
+
|
| 27 |
+
return linkDisabled
|
| 28 |
+
? (
|
| 29 |
+
<Button
|
| 30 |
+
className={ classNames( linkClass, `${ linkClass }--disabled` ) }
|
| 31 |
+
disabled={ true }
|
| 32 |
+
>
|
| 33 |
+
{ linkText }
|
| 34 |
+
</Button>
|
| 35 |
+
)
|
| 36 |
+
: (
|
| 37 |
+
<Link
|
| 38 |
+
className={ linkClass }
|
| 39 |
+
href={ linkHref }
|
| 40 |
+
target={ linkTarget }
|
| 41 |
+
>
|
| 42 |
+
{ linkText }
|
| 43 |
+
</Link>
|
| 44 |
+
);
|
| 45 |
+
};
|
| 46 |
+
|
| 47 |
+
return (
|
| 48 |
+
<LabeledItem
|
| 49 |
+
className={ classNames( 'tribe-editor__label-with-link', className ) }
|
| 50 |
+
label={ label }
|
| 51 |
+
>
|
| 52 |
+
{ getLink() }
|
| 53 |
+
</LabeledItem>
|
| 54 |
+
);
|
| 55 |
+
};
|
| 56 |
+
|
| 57 |
+
LabelWithLink.propTypes = {
|
| 58 |
+
className: PropTypes.string,
|
| 59 |
+
label: PropTypes.node,
|
| 60 |
+
linkDisabled: PropTypes.bool,
|
| 61 |
+
linkHref: PropTypes.string.isRequired,
|
| 62 |
+
linkTarget: PropTypes.string,
|
| 63 |
+
linkText: PropTypes.string,
|
| 64 |
+
};
|
| 65 |
+
|
| 66 |
+
export default LabelWithLink;
|
common/src/modules/elements/label-with-link/style.pcss
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
.tribe-editor__label-with-link {
|
| 2 |
+
|
| 3 |
+
.tribe-editor__rsvp &,
|
| 4 |
+
.tribe-editor__ticket & {
|
| 5 |
+
display: flex;
|
| 6 |
+
align-items: center;
|
| 7 |
+
background-color: #FFFFFF;
|
| 8 |
+
padding: 10px 17px;
|
| 9 |
+
border: 1px solid #E1E3E6;
|
| 10 |
+
}
|
| 11 |
+
|
| 12 |
+
.tribe-editor__labeled-item__label {
|
| 13 |
+
|
| 14 |
+
.tribe-editor__rsvp &,
|
| 15 |
+
.tribe-editor__ticket & {
|
| 16 |
+
flex: auto;
|
| 17 |
+
color: #545D66;
|
| 18 |
+
font-size: 15px;
|
| 19 |
+
font-weight: bold;
|
| 20 |
+
line-height: 18px;
|
| 21 |
+
letter-spacing: 0.38px;
|
| 22 |
+
padding-right: 10px;
|
| 23 |
+
}
|
| 24 |
+
}
|
| 25 |
+
|
| 26 |
+
.tribe-editor__label-with-link__link {
|
| 27 |
+
|
| 28 |
+
.tribe-editor__rsvp &,
|
| 29 |
+
.tribe-editor__ticket & {
|
| 30 |
+
flex: none;
|
| 31 |
+
color: #009FD4;
|
| 32 |
+
font-size: 15px;
|
| 33 |
+
font-weight: bold;
|
| 34 |
+
line-height: 18px;
|
| 35 |
+
letter-spacing: 0.38px;
|
| 36 |
+
text-decoration: none;
|
| 37 |
+
box-shadow: none;
|
| 38 |
+
transition: color 0.2s ease;
|
| 39 |
+
|
| 40 |
+
&:hover,
|
| 41 |
+
&:focus {
|
| 42 |
+
color: #007BB4;
|
| 43 |
+
}
|
| 44 |
+
}
|
| 45 |
+
}
|
| 46 |
+
|
| 47 |
+
.tribe-editor__label-with-link__link.tribe-editor__label-with-link__link--disabled {
|
| 48 |
+
|
| 49 |
+
.tribe-editor__rsvp &,
|
| 50 |
+
.tribe-editor__ticket & {
|
| 51 |
+
color: #AEB4BB;
|
| 52 |
+
}
|
| 53 |
+
}
|
| 54 |
+
}
|
common/src/modules/elements/label-with-modal/__tests__/__snapshots__/element.test.js.snap
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
| 2 |
+
|
| 3 |
+
exports[`Label With Modal Element renders a label with modal 1`] = `
|
| 4 |
+
<div
|
| 5 |
+
className="tribe-editor__labeled-item tribe-editor__label-with-modal"
|
| 6 |
+
>
|
| 7 |
+
<span
|
| 8 |
+
className="tribe-editor__labeled-item__label"
|
| 9 |
+
/>
|
| 10 |
+
<div
|
| 11 |
+
className="tribe-editor__modal-button tribe-editor__label-with-modal__modal-button"
|
| 12 |
+
>
|
| 13 |
+
<button
|
| 14 |
+
className="tribe-editor__button tribe-editor__modal-button__button"
|
| 15 |
+
onClick={[Function]}
|
| 16 |
+
type="button"
|
| 17 |
+
/>
|
| 18 |
+
</div>
|
| 19 |
+
</div>
|
| 20 |
+
`;
|
| 21 |
+
|
| 22 |
+
exports[`Label With Modal Element renders a label with modal with class 1`] = `
|
| 23 |
+
<div
|
| 24 |
+
className="tribe-editor__labeled-item tribe-editor__label-with-modal test-class"
|
| 25 |
+
>
|
| 26 |
+
<span
|
| 27 |
+
className="tribe-editor__labeled-item__label"
|
| 28 |
+
/>
|
| 29 |
+
<div
|
| 30 |
+
className="tribe-editor__modal-button tribe-editor__label-with-modal__modal-button"
|
| 31 |
+
>
|
| 32 |
+
<button
|
| 33 |
+
className="tribe-editor__button tribe-editor__modal-button__button"
|
| 34 |
+
onClick={[Function]}
|
| 35 |
+
type="button"
|
| 36 |
+
/>
|
| 37 |
+
</div>
|
| 38 |
+
</div>
|
| 39 |
+
`;
|
| 40 |
+
|
| 41 |
+
exports[`Label With Modal Element renders a label with modal with label 1`] = `
|
| 42 |
+
<div
|
| 43 |
+
className="tribe-editor__labeled-item tribe-editor__label-with-modal"
|
| 44 |
+
>
|
| 45 |
+
<span
|
| 46 |
+
className="tribe-editor__labeled-item__label"
|
| 47 |
+
>
|
| 48 |
+
test label
|
| 49 |
+
</span>
|
| 50 |
+
<div
|
| 51 |
+
className="tribe-editor__modal-button tribe-editor__label-with-modal__modal-button"
|
| 52 |
+
>
|
| 53 |
+
<button
|
| 54 |
+
className="tribe-editor__button tribe-editor__modal-button__button"
|
| 55 |
+
onClick={[Function]}
|
| 56 |
+
type="button"
|
| 57 |
+
/>
|
| 58 |
+
</div>
|
| 59 |
+
</div>
|
| 60 |
+
`;
|
common/src/modules/elements/label-with-modal/__tests__/element.test.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import React from 'react';
|
| 5 |
+
|
| 6 |
+
/**
|
| 7 |
+
* Internal dependencies
|
| 8 |
+
*/
|
| 9 |
+
import LabelWithModal from '@moderntribe/common/elements/label-with-modal/element';
|
| 10 |
+
|
| 11 |
+
describe( 'Label With Modal Element', () => {
|
| 12 |
+
it( 'renders a label with modal', () => {
|
| 13 |
+
const component = renderer.create( <LabelWithModal /> );
|
| 14 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 15 |
+
} );
|
| 16 |
+
|
| 17 |
+
it( 'renders a label with modal with class', () => {
|
| 18 |
+
const component = renderer.create( <LabelWithModal className="test-class" /> );
|
| 19 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 20 |
+
} );
|
| 21 |
+
|
| 22 |
+
it( 'renders a label with modal with label', () => {
|
| 23 |
+
const component = renderer.create( <LabelWithModal label="test label" /> );
|
| 24 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 25 |
+
} );
|
| 26 |
+
} );
|
common/src/modules/elements/label-with-modal/element.js
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import React from 'react';
|
| 5 |
+
import PropTypes from 'prop-types';
|
| 6 |
+
import classNames from 'classnames';
|
| 7 |
+
import { noop } from 'lodash';
|
| 8 |
+
|
| 9 |
+
/**
|
| 10 |
+
* Internal dependencies
|
| 11 |
+
*/
|
| 12 |
+
import LabeledItem from '@moderntribe/common/elements/labeled-item/element';
|
| 13 |
+
import ModalButton from '@moderntribe/common/elements/modal-button/element';
|
| 14 |
+
import './style.pcss';
|
| 15 |
+
|
| 16 |
+
const LabelWithModal = ( {
|
| 17 |
+
className,
|
| 18 |
+
isOpen,
|
| 19 |
+
label,
|
| 20 |
+
modalButtonDisabled,
|
| 21 |
+
modalButtonLabel,
|
| 22 |
+
modalClassName,
|
| 23 |
+
modalContent,
|
| 24 |
+
modalOverlayClassName,
|
| 25 |
+
modalTitle,
|
| 26 |
+
onClick,
|
| 27 |
+
onClose,
|
| 28 |
+
onOpen,
|
| 29 |
+
} ) => (
|
| 30 |
+
<LabeledItem
|
| 31 |
+
className={ classNames( 'tribe-editor__label-with-modal', className ) }
|
| 32 |
+
label={ label }
|
| 33 |
+
>
|
| 34 |
+
<ModalButton
|
| 35 |
+
className="tribe-editor__label-with-modal__modal-button"
|
| 36 |
+
disabled={ modalButtonDisabled }
|
| 37 |
+
isOpen={ isOpen }
|
| 38 |
+
label={ modalButtonLabel }
|
| 39 |
+
modalClassName={ modalClassName }
|
| 40 |
+
modalContent={ modalContent }
|
| 41 |
+
modalOverlayClassName={ modalOverlayClassName }
|
| 42 |
+
modalTitle={ modalTitle }
|
| 43 |
+
onClick={ onClick }
|
| 44 |
+
onClose={ onClose }
|
| 45 |
+
onOpen={ onOpen }
|
| 46 |
+
/>
|
| 47 |
+
</LabeledItem>
|
| 48 |
+
);
|
| 49 |
+
|
| 50 |
+
LabelWithModal.defaultProps = {
|
| 51 |
+
onClick: noop,
|
| 52 |
+
onClose: noop,
|
| 53 |
+
onOpen: noop,
|
| 54 |
+
};
|
| 55 |
+
|
| 56 |
+
LabelWithModal.propTypes = {
|
| 57 |
+
className: PropTypes.string,
|
| 58 |
+
isOpen: PropTypes.bool,
|
| 59 |
+
label: PropTypes.node,
|
| 60 |
+
modalButtonDisabled: PropTypes.bool,
|
| 61 |
+
modalButtonLabel: PropTypes.string,
|
| 62 |
+
modalClassName: PropTypes.string,
|
| 63 |
+
modalContent: PropTypes.node,
|
| 64 |
+
modalOverlayClassName: PropTypes.string,
|
| 65 |
+
modalTitle: PropTypes.string,
|
| 66 |
+
onClick: PropTypes.func,
|
| 67 |
+
onClose: PropTypes.func,
|
| 68 |
+
onOpen: PropTypes.func,
|
| 69 |
+
};
|
| 70 |
+
|
| 71 |
+
export default LabelWithModal;
|
common/src/modules/elements/label-with-modal/style.pcss
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
.tribe-editor__label-with-modal {
|
| 2 |
+
display: flex;
|
| 3 |
+
align-items: center;
|
| 4 |
+
background-color: #FFFFFF;
|
| 5 |
+
padding: 11px 17px;
|
| 6 |
+
border: 1px solid #E1E3E6;
|
| 7 |
+
height: 40px;
|
| 8 |
+
}
|
| 9 |
+
|
| 10 |
+
.tribe-editor__labeled-item__label {
|
| 11 |
+
|
| 12 |
+
.tribe-editor__label-with-modal & {
|
| 13 |
+
flex: auto;
|
| 14 |
+
color: #545D66;
|
| 15 |
+
font-size: 15px;
|
| 16 |
+
font-weight: bold;
|
| 17 |
+
line-height: 18px;
|
| 18 |
+
letter-spacing: 0.38px;
|
| 19 |
+
}
|
| 20 |
+
}
|
| 21 |
+
|
| 22 |
+
.tribe-editor__label-with-modal__modal-button {
|
| 23 |
+
|
| 24 |
+
.tribe-editor__label-with-modal & {
|
| 25 |
+
flex: none;
|
| 26 |
+
}
|
| 27 |
+
}
|
| 28 |
+
|
| 29 |
+
.tribe-editor__modal-button__button {
|
| 30 |
+
|
| 31 |
+
.tribe-editor__label-with-modal & {
|
| 32 |
+
color: #009FD4;
|
| 33 |
+
font-size: 15px;
|
| 34 |
+
font-weight: bold;
|
| 35 |
+
line-height: 18px;
|
| 36 |
+
letter-spacing: 0.38px;
|
| 37 |
+
transition: color 0.2s ease;
|
| 38 |
+
|
| 39 |
+
&:hover,
|
| 40 |
+
&:focus {
|
| 41 |
+
color: #007BB4;
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
&:disabled {
|
| 45 |
+
|
| 46 |
+
&,
|
| 47 |
+
&:hover,
|
| 48 |
+
&:focus {
|
| 49 |
+
color: #AEB4BB;
|
| 50 |
+
}
|
| 51 |
+
}
|
| 52 |
+
}
|
| 53 |
+
}
|
common/src/modules/elements/labeled-item/__tests__/__snapshots__/element.test.js.snap
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
| 2 |
+
|
| 3 |
+
exports[`Labeled Item Element renders labeled item 1`] = `
|
| 4 |
+
<div
|
| 5 |
+
className="tribe-editor__labeled-item"
|
| 6 |
+
>
|
| 7 |
+
<span
|
| 8 |
+
className="tribe-editor__labeled-item__label"
|
| 9 |
+
/>
|
| 10 |
+
Test
|
| 11 |
+
</div>
|
| 12 |
+
`;
|
| 13 |
+
|
| 14 |
+
exports[`Labeled Item Element renders labeled item with class 1`] = `
|
| 15 |
+
<div
|
| 16 |
+
className="tribe-editor__labeled-item test-class"
|
| 17 |
+
>
|
| 18 |
+
<span
|
| 19 |
+
className="tribe-editor__labeled-item__label"
|
| 20 |
+
/>
|
| 21 |
+
Test
|
| 22 |
+
</div>
|
| 23 |
+
`;
|
| 24 |
+
|
| 25 |
+
exports[`Labeled Item Element renders labeled item with label 1`] = `
|
| 26 |
+
<div
|
| 27 |
+
className="tribe-editor__labeled-item"
|
| 28 |
+
>
|
| 29 |
+
<span
|
| 30 |
+
className="tribe-editor__labeled-item__label"
|
| 31 |
+
>
|
| 32 |
+
test label
|
| 33 |
+
</span>
|
| 34 |
+
Test
|
| 35 |
+
</div>
|
| 36 |
+
`;
|
| 37 |
+
|
| 38 |
+
exports[`Labeled Item Element renders labeled item with label element and for id 1`] = `
|
| 39 |
+
<div
|
| 40 |
+
className="tribe-editor__labeled-item"
|
| 41 |
+
>
|
| 42 |
+
<label
|
| 43 |
+
className="tribe-editor__labeled-item__label"
|
| 44 |
+
htmlFor="test-id"
|
| 45 |
+
>
|
| 46 |
+
test label
|
| 47 |
+
</label>
|
| 48 |
+
Test
|
| 49 |
+
</div>
|
| 50 |
+
`;
|
common/src/modules/elements/labeled-item/__tests__/element.test.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import React from 'react';
|
| 5 |
+
|
| 6 |
+
/**
|
| 7 |
+
* Internal dependencies
|
| 8 |
+
*/
|
| 9 |
+
import { LabeledItem } from '@moderntribe/common/elements';
|
| 10 |
+
|
| 11 |
+
describe( 'Labeled Item Element', () => {
|
| 12 |
+
it( 'renders labeled item', () => {
|
| 13 |
+
const component = renderer.create( <LabeledItem>Test</LabeledItem> );
|
| 14 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 15 |
+
} );
|
| 16 |
+
|
| 17 |
+
it( 'renders labeled item with class', () => {
|
| 18 |
+
const component = renderer.create( <LabeledItem className="test-class">Test</LabeledItem> );
|
| 19 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 20 |
+
} );
|
| 21 |
+
|
| 22 |
+
it( 'renders labeled item with label', () => {
|
| 23 |
+
const component = renderer.create( <LabeledItem label="test label">Test</LabeledItem> );
|
| 24 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 25 |
+
} );
|
| 26 |
+
|
| 27 |
+
it( 'renders labeled item with label element and for id', () => {
|
| 28 |
+
const component = renderer.create(
|
| 29 |
+
<LabeledItem
|
| 30 |
+
label="test label"
|
| 31 |
+
isLabel={ true }
|
| 32 |
+
forId="test-id"
|
| 33 |
+
>
|
| 34 |
+
Test
|
| 35 |
+
</LabeledItem>
|
| 36 |
+
);
|
| 37 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 38 |
+
} );
|
| 39 |
+
} );
|
common/src/modules/elements/labeled-item/element.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import React from 'react';
|
| 5 |
+
import PropTypes from 'prop-types';
|
| 6 |
+
import classNames from 'classnames';
|
| 7 |
+
|
| 8 |
+
const LabeledItem = ( {
|
| 9 |
+
className,
|
| 10 |
+
forId,
|
| 11 |
+
isLabel,
|
| 12 |
+
label,
|
| 13 |
+
children,
|
| 14 |
+
} ) => {
|
| 15 |
+
const renderLabel = (
|
| 16 |
+
isLabel
|
| 17 |
+
? (
|
| 18 |
+
<label className="tribe-editor__labeled-item__label" htmlFor={ forId }>
|
| 19 |
+
{ label }
|
| 20 |
+
</label>
|
| 21 |
+
)
|
| 22 |
+
: (
|
| 23 |
+
<span className="tribe-editor__labeled-item__label">
|
| 24 |
+
{ label }
|
| 25 |
+
</span>
|
| 26 |
+
)
|
| 27 |
+
);
|
| 28 |
+
|
| 29 |
+
return (
|
| 30 |
+
<div className={ classNames(
|
| 31 |
+
'tribe-editor__labeled-item',
|
| 32 |
+
className,
|
| 33 |
+
) }>
|
| 34 |
+
{ renderLabel }
|
| 35 |
+
{ children }
|
| 36 |
+
</div>
|
| 37 |
+
);
|
| 38 |
+
};
|
| 39 |
+
|
| 40 |
+
LabeledItem.defaultProps = {
|
| 41 |
+
isLabel: false,
|
| 42 |
+
};
|
| 43 |
+
|
| 44 |
+
LabeledItem.propTypes = {
|
| 45 |
+
className: PropTypes.string,
|
| 46 |
+
isLabel: PropTypes.bool.isRequired,
|
| 47 |
+
forId: PropTypes.string,
|
| 48 |
+
label: PropTypes.node,
|
| 49 |
+
children: PropTypes.node.isRequired,
|
| 50 |
+
};
|
| 51 |
+
|
| 52 |
+
export default LabeledItem;
|
common/src/modules/elements/link/__tests__/__snapshots__/element.test.js.snap
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
| 2 |
+
|
| 3 |
+
exports[`Link Element renders button with class 1`] = `
|
| 4 |
+
<a
|
| 5 |
+
className="tribe-editor__link test-class"
|
| 6 |
+
href="#"
|
| 7 |
+
>
|
| 8 |
+
label
|
| 9 |
+
</a>
|
| 10 |
+
`;
|
| 11 |
+
|
| 12 |
+
exports[`Link Element renders button with prop 1`] = `
|
| 13 |
+
<a
|
| 14 |
+
className="tribe-editor__link"
|
| 15 |
+
href="#"
|
| 16 |
+
title="title"
|
| 17 |
+
>
|
| 18 |
+
label
|
| 19 |
+
</a>
|
| 20 |
+
`;
|
| 21 |
+
|
| 22 |
+
exports[`Link Element renders button with target 1`] = `
|
| 23 |
+
<a
|
| 24 |
+
className="tribe-editor__link"
|
| 25 |
+
href="#"
|
| 26 |
+
rel="noopener noreferrer"
|
| 27 |
+
target="_blank"
|
| 28 |
+
>
|
| 29 |
+
label
|
| 30 |
+
</a>
|
| 31 |
+
`;
|
| 32 |
+
|
| 33 |
+
exports[`Link Element renders link 1`] = `
|
| 34 |
+
<a
|
| 35 |
+
className="tribe-editor__link"
|
| 36 |
+
href="#"
|
| 37 |
+
>
|
| 38 |
+
label
|
| 39 |
+
</a>
|
| 40 |
+
`;
|
common/src/modules/elements/link/__tests__/element.test.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import React from 'react';
|
| 5 |
+
|
| 6 |
+
/**
|
| 7 |
+
* Internal dependencies
|
| 8 |
+
*/
|
| 9 |
+
import Link from '../element.js';
|
| 10 |
+
|
| 11 |
+
describe( 'Link Element', () => {
|
| 12 |
+
it( 'renders link', () => {
|
| 13 |
+
const component = renderer.create(
|
| 14 |
+
<Link href="#">label</Link>
|
| 15 |
+
);
|
| 16 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 17 |
+
} );
|
| 18 |
+
|
| 19 |
+
it( 'renders button with class', () => {
|
| 20 |
+
const component = renderer.create(
|
| 21 |
+
<Link className="test-class" href="#">label</Link>
|
| 22 |
+
);
|
| 23 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 24 |
+
} );
|
| 25 |
+
|
| 26 |
+
it( 'renders button with target', () => {
|
| 27 |
+
const component = renderer.create(
|
| 28 |
+
<Link href="#" target="_blank">label</Link>
|
| 29 |
+
);
|
| 30 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 31 |
+
} );
|
| 32 |
+
|
| 33 |
+
it( 'renders button with prop', () => {
|
| 34 |
+
const component = renderer.create(
|
| 35 |
+
<Link href="#" title="title">label</Link>
|
| 36 |
+
);
|
| 37 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 38 |
+
} );
|
| 39 |
+
} );
|
common/src/modules/elements/link/element.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import React from 'react';
|
| 5 |
+
import PropTypes from 'prop-types';
|
| 6 |
+
import classNames from 'classnames';
|
| 7 |
+
|
| 8 |
+
const Link = ( {
|
| 9 |
+
children,
|
| 10 |
+
className,
|
| 11 |
+
href,
|
| 12 |
+
target,
|
| 13 |
+
...props,
|
| 14 |
+
} ) => {
|
| 15 |
+
const getProps = () => {
|
| 16 |
+
const elemProps = { ...props };
|
| 17 |
+
|
| 18 |
+
if ( target === '_blank' ) {
|
| 19 |
+
elemProps.rel = 'noopener noreferrer';
|
| 20 |
+
}
|
| 21 |
+
|
| 22 |
+
return elemProps;
|
| 23 |
+
};
|
| 24 |
+
|
| 25 |
+
return (
|
| 26 |
+
<a
|
| 27 |
+
className={ classNames( 'tribe-editor__link', className ) }
|
| 28 |
+
href={ href }
|
| 29 |
+
target={ target }
|
| 30 |
+
{ ...getProps() }
|
| 31 |
+
>
|
| 32 |
+
{ children }
|
| 33 |
+
</a>
|
| 34 |
+
);
|
| 35 |
+
};
|
| 36 |
+
|
| 37 |
+
Link.propTypes = {
|
| 38 |
+
children: PropTypes.node,
|
| 39 |
+
className: PropTypes.string,
|
| 40 |
+
href: PropTypes.string.isRequired,
|
| 41 |
+
target: PropTypes.string,
|
| 42 |
+
};
|
| 43 |
+
|
| 44 |
+
export default Link;
|
common/src/modules/elements/modal-button/__tests__/__snapshots__/element.test.js.snap
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
| 2 |
+
|
| 3 |
+
exports[`Modal Button Element renders a modal button 1`] = `
|
| 4 |
+
<div
|
| 5 |
+
className="tribe-editor__modal-button"
|
| 6 |
+
>
|
| 7 |
+
<button
|
| 8 |
+
className="tribe-editor__button tribe-editor__modal-button__button"
|
| 9 |
+
onClick={[Function]}
|
| 10 |
+
type="button"
|
| 11 |
+
/>
|
| 12 |
+
</div>
|
| 13 |
+
`;
|
| 14 |
+
|
| 15 |
+
exports[`Modal Button Element renders a modal button with class 1`] = `
|
| 16 |
+
<div
|
| 17 |
+
className="tribe-editor__modal-button test-class"
|
| 18 |
+
>
|
| 19 |
+
<button
|
| 20 |
+
className="tribe-editor__button tribe-editor__modal-button__button"
|
| 21 |
+
onClick={[Function]}
|
| 22 |
+
type="button"
|
| 23 |
+
/>
|
| 24 |
+
</div>
|
| 25 |
+
`;
|
| 26 |
+
|
| 27 |
+
exports[`Modal Button Element renders a modal button with label 1`] = `
|
| 28 |
+
<div
|
| 29 |
+
className="tribe-editor__modal-button"
|
| 30 |
+
>
|
| 31 |
+
<button
|
| 32 |
+
className="tribe-editor__button tribe-editor__modal-button__button"
|
| 33 |
+
onClick={[Function]}
|
| 34 |
+
type="button"
|
| 35 |
+
>
|
| 36 |
+
Test Label
|
| 37 |
+
</button>
|
| 38 |
+
</div>
|
| 39 |
+
`;
|
| 40 |
+
|
| 41 |
+
exports[`Modal Button Element renders a modal button with onClick handler 1`] = `
|
| 42 |
+
<div
|
| 43 |
+
className="tribe-editor__modal-button"
|
| 44 |
+
>
|
| 45 |
+
<button
|
| 46 |
+
className="tribe-editor__button tribe-editor__modal-button__button"
|
| 47 |
+
onClick={[Function]}
|
| 48 |
+
type="button"
|
| 49 |
+
/>
|
| 50 |
+
</div>
|
| 51 |
+
`;
|
common/src/modules/elements/modal-button/__tests__/element.test.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import React from 'react';
|
| 5 |
+
import { noop } from 'lodash';
|
| 6 |
+
|
| 7 |
+
/**
|
| 8 |
+
* Internal dependencies
|
| 9 |
+
*/
|
| 10 |
+
import ModalButton from '@moderntribe/common/elements/modal-button/element';
|
| 11 |
+
|
| 12 |
+
describe( 'Modal Button Element', () => {
|
| 13 |
+
it( 'renders a modal button', () => {
|
| 14 |
+
const component = renderer.create( <ModalButton /> );
|
| 15 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 16 |
+
} );
|
| 17 |
+
|
| 18 |
+
it( 'renders a modal button with class', () => {
|
| 19 |
+
const component = renderer.create( <ModalButton className="test-class" /> );
|
| 20 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 21 |
+
} );
|
| 22 |
+
|
| 23 |
+
it( 'renders a modal button with onClick handler', () => {
|
| 24 |
+
const component = renderer.create( <ModalButton onClick={ noop } /> );
|
| 25 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 26 |
+
} );
|
| 27 |
+
|
| 28 |
+
it( 'renders a modal button with label', () => {
|
| 29 |
+
const component = renderer.create( <ModalButton label="Test Label" /> );
|
| 30 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 31 |
+
} );
|
| 32 |
+
|
| 33 |
+
it( 'executes onClick and onOpen handlers', () => {
|
| 34 |
+
const props = {
|
| 35 |
+
onClick: jest.fn(),
|
| 36 |
+
onOpen: jest.fn(),
|
| 37 |
+
};
|
| 38 |
+
|
| 39 |
+
const component = mount( <ModalButton { ...props } /> );
|
| 40 |
+
component.find( 'button.tribe-editor__modal-button__button' ).simulate( 'click' );
|
| 41 |
+
expect( props.onClick ).toHaveBeenCalled();
|
| 42 |
+
expect( props.onClick ).toHaveBeenCalledTimes( 1 );
|
| 43 |
+
expect( props.onOpen ).toHaveBeenCalled();
|
| 44 |
+
expect( props.onOpen ).toHaveBeenCalledTimes( 1 );
|
| 45 |
+
} );
|
| 46 |
+
} );
|
common/src/modules/elements/modal-button/element.js
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import React, { PureComponent } from 'react';
|
| 5 |
+
import PropTypes from 'prop-types';
|
| 6 |
+
import classNames from 'classnames';
|
| 7 |
+
|
| 8 |
+
/**
|
| 9 |
+
* WordPress dependencies
|
| 10 |
+
*/
|
| 11 |
+
import { Modal } from '@wordpress/components';
|
| 12 |
+
|
| 13 |
+
/**
|
| 14 |
+
* Internal dependencies
|
| 15 |
+
*/
|
| 16 |
+
import Button from '@moderntribe/common/elements/button/element';
|
| 17 |
+
|
| 18 |
+
class ModalButton extends PureComponent {
|
| 19 |
+
static propTypes = {
|
| 20 |
+
className: PropTypes.string,
|
| 21 |
+
disabled: PropTypes.bool,
|
| 22 |
+
isOpen: PropTypes.bool,
|
| 23 |
+
label: PropTypes.string,
|
| 24 |
+
modalClassName: PropTypes.string,
|
| 25 |
+
modalContent: PropTypes.node,
|
| 26 |
+
modalOverlayClassName: PropTypes.string,
|
| 27 |
+
modalTitle: PropTypes.string,
|
| 28 |
+
onClick: PropTypes.func,
|
| 29 |
+
onClose: PropTypes.func,
|
| 30 |
+
onOpen: PropTypes.func,
|
| 31 |
+
};
|
| 32 |
+
|
| 33 |
+
constructor( props ) {
|
| 34 |
+
super( props );
|
| 35 |
+
this.state = {
|
| 36 |
+
isOpen: false,
|
| 37 |
+
};
|
| 38 |
+
}
|
| 39 |
+
|
| 40 |
+
onClick = ( e ) => {
|
| 41 |
+
this.props.onClick && this.props.onClick( e );
|
| 42 |
+
this.onOpen();
|
| 43 |
+
this.props.isOpen === undefined && this.setState( { isOpen: true } );
|
| 44 |
+
};
|
| 45 |
+
|
| 46 |
+
onRequestClose = () => {
|
| 47 |
+
this.onClose();
|
| 48 |
+
this.props.isOpen === undefined && this.setState( { isOpen: false } );
|
| 49 |
+
}
|
| 50 |
+
|
| 51 |
+
onOpen = () => this.props.onOpen && this.props.onOpen();
|
| 52 |
+
|
| 53 |
+
onClose = () => this.props.onClose && this.props.onClose();
|
| 54 |
+
|
| 55 |
+
renderModal = () => {
|
| 56 |
+
const {
|
| 57 |
+
modalClassName,
|
| 58 |
+
modalContent,
|
| 59 |
+
modalOverlayClassName,
|
| 60 |
+
modalTitle,
|
| 61 |
+
} = this.props;
|
| 62 |
+
|
| 63 |
+
const isOpen = this.props.isOpen !== undefined ? this.props.isOpen : this.state.isOpen;
|
| 64 |
+
|
| 65 |
+
return ( isOpen && (
|
| 66 |
+
<Modal
|
| 67 |
+
className={ classNames(
|
| 68 |
+
'tribe-editor__modal-button__modal-content',
|
| 69 |
+
modalClassName,
|
| 70 |
+
) }
|
| 71 |
+
onRequestClose={ this.onRequestClose }
|
| 72 |
+
overlayClassName={ classNames(
|
| 73 |
+
'tribe-editor__modal-button__modal-overlay',
|
| 74 |
+
modalOverlayClassName,
|
| 75 |
+
) }
|
| 76 |
+
title={ modalTitle }
|
| 77 |
+
>
|
| 78 |
+
{ modalContent }
|
| 79 |
+
</Modal>
|
| 80 |
+
) );
|
| 81 |
+
};
|
| 82 |
+
|
| 83 |
+
render() {
|
| 84 |
+
const { className, disabled, label } = this.props;
|
| 85 |
+
return (
|
| 86 |
+
<div className={ classNames(
|
| 87 |
+
'tribe-editor__modal-button',
|
| 88 |
+
className,
|
| 89 |
+
) }>
|
| 90 |
+
<Button
|
| 91 |
+
className="tribe-editor__modal-button__button"
|
| 92 |
+
onClick={ this.onClick }
|
| 93 |
+
disabled={ disabled }
|
| 94 |
+
>
|
| 95 |
+
{ label }
|
| 96 |
+
</Button>
|
| 97 |
+
{ this.renderModal() }
|
| 98 |
+
</div>
|
| 99 |
+
);
|
| 100 |
+
}
|
| 101 |
+
}
|
| 102 |
+
|
| 103 |
+
export default ModalButton;
|
common/src/modules/elements/number-input/__tests__/__snapshots__/element.test.js.snap
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
| 2 |
+
|
| 3 |
+
exports[`Input element Should render the component 1`] = `
|
| 4 |
+
<input
|
| 5 |
+
className="tribe-editor__input tribe-editor__input--number"
|
| 6 |
+
type="number"
|
| 7 |
+
/>
|
| 8 |
+
`;
|
| 9 |
+
|
| 10 |
+
exports[`Input element Should render the component with class 1`] = `
|
| 11 |
+
<input
|
| 12 |
+
className="tribe-editor__input tribe-editor__input--number input-class"
|
| 13 |
+
type="number"
|
| 14 |
+
/>
|
| 15 |
+
`;
|
| 16 |
+
|
| 17 |
+
exports[`Input element Should render the component with extra props 1`] = `
|
| 18 |
+
<input
|
| 19 |
+
className="tribe-editor__input tribe-editor__input--number"
|
| 20 |
+
id="input-id"
|
| 21 |
+
type="number"
|
| 22 |
+
/>
|
| 23 |
+
`;
|
| 24 |
+
|
| 25 |
+
exports[`Input element Should render the component with max 1`] = `
|
| 26 |
+
<input
|
| 27 |
+
className="tribe-editor__input tribe-editor__input--number"
|
| 28 |
+
max={42}
|
| 29 |
+
type="number"
|
| 30 |
+
/>
|
| 31 |
+
`;
|
| 32 |
+
|
| 33 |
+
exports[`Input element Should render the component with min 1`] = `
|
| 34 |
+
<input
|
| 35 |
+
className="tribe-editor__input tribe-editor__input--number"
|
| 36 |
+
min={-42}
|
| 37 |
+
type="number"
|
| 38 |
+
/>
|
| 39 |
+
`;
|
| 40 |
+
|
| 41 |
+
exports[`Input element Should render the component with onChange handler 1`] = `
|
| 42 |
+
<input
|
| 43 |
+
className="tribe-editor__input tribe-editor__input--number"
|
| 44 |
+
onChange={[Function]}
|
| 45 |
+
type="number"
|
| 46 |
+
/>
|
| 47 |
+
`;
|
| 48 |
+
|
| 49 |
+
exports[`Input element Should render the component with step 1`] = `
|
| 50 |
+
<input
|
| 51 |
+
className="tribe-editor__input tribe-editor__input--number"
|
| 52 |
+
step={10}
|
| 53 |
+
type="number"
|
| 54 |
+
/>
|
| 55 |
+
`;
|
common/src/modules/elements/number-input/__tests__/element.test.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import React from 'react';
|
| 5 |
+
import { noop } from 'lodash';
|
| 6 |
+
|
| 7 |
+
/**
|
| 8 |
+
* Internal dependencies
|
| 9 |
+
*/
|
| 10 |
+
import NumberInput from '../element.js';
|
| 11 |
+
|
| 12 |
+
describe( 'Input element', () => {
|
| 13 |
+
it( 'Should render the component', () => {
|
| 14 |
+
const component = renderer.create( <NumberInput /> );
|
| 15 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 16 |
+
} );
|
| 17 |
+
|
| 18 |
+
it( 'Should render the component with class', () => {
|
| 19 |
+
const component = renderer.create( <NumberInput className="input-class" /> );
|
| 20 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 21 |
+
} );
|
| 22 |
+
|
| 23 |
+
it( 'Should render the component with max', () => {
|
| 24 |
+
const component = renderer.create( <NumberInput max={ 42 } /> );
|
| 25 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 26 |
+
} );
|
| 27 |
+
|
| 28 |
+
it( 'Should render the component with min', () => {
|
| 29 |
+
const component = renderer.create( <NumberInput min={ -42 } /> );
|
| 30 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 31 |
+
} );
|
| 32 |
+
|
| 33 |
+
it( 'Should render the component with onChange handler', () => {
|
| 34 |
+
const component = renderer.create( <NumberInput onChange={ noop } /> );
|
| 35 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 36 |
+
} );
|
| 37 |
+
|
| 38 |
+
it( 'Should render the component with step', () => {
|
| 39 |
+
const component = renderer.create( <NumberInput step={ 10 } /> );
|
| 40 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 41 |
+
} );
|
| 42 |
+
|
| 43 |
+
it( 'Should render the component with extra props', () => {
|
| 44 |
+
const component = renderer.create( <NumberInput id="input-id" /> );
|
| 45 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 46 |
+
} );
|
| 47 |
+
} );
|
common/src/modules/elements/number-input/element.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External Dependencies
|
| 3 |
+
*/
|
| 4 |
+
import React from 'react';
|
| 5 |
+
import PropTypes from 'prop-types';
|
| 6 |
+
import classNames from 'classnames';
|
| 7 |
+
|
| 8 |
+
/**
|
| 9 |
+
* Internal dependencies
|
| 10 |
+
*/
|
| 11 |
+
import Input from '@moderntribe/common/elements/input/element';
|
| 12 |
+
|
| 13 |
+
const NumberInput = ( {
|
| 14 |
+
className,
|
| 15 |
+
max,
|
| 16 |
+
min,
|
| 17 |
+
onChange,
|
| 18 |
+
step,
|
| 19 |
+
...rest
|
| 20 |
+
} ) => (
|
| 21 |
+
<Input
|
| 22 |
+
className={ classNames( 'tribe-editor__input--number', className ) }
|
| 23 |
+
max={ max }
|
| 24 |
+
min={ min }
|
| 25 |
+
onChange={ onChange }
|
| 26 |
+
step={ step }
|
| 27 |
+
type="number"
|
| 28 |
+
{ ...rest }
|
| 29 |
+
/>
|
| 30 |
+
);
|
| 31 |
+
|
| 32 |
+
NumberInput.propTypes = {
|
| 33 |
+
className: PropTypes.string,
|
| 34 |
+
max: PropTypes.number,
|
| 35 |
+
min: PropTypes.number,
|
| 36 |
+
onChange: PropTypes.func,
|
| 37 |
+
step: PropTypes.number,
|
| 38 |
+
};
|
| 39 |
+
|
| 40 |
+
export default NumberInput;
|
common/src/modules/elements/paragraph/__tests__/__snapshots__/element.test.js.snap
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
| 2 |
+
|
| 3 |
+
exports[`<Paragraph> default paragraph 1`] = `
|
| 4 |
+
<p
|
| 5 |
+
className="tribe-editor__paragraph tribe-editor__paragraph--medium"
|
| 6 |
+
>
|
| 7 |
+
Modern Tribe
|
| 8 |
+
</p>
|
| 9 |
+
`;
|
| 10 |
+
|
| 11 |
+
exports[`<Paragraph> smaller paragraph 1`] = `
|
| 12 |
+
<p
|
| 13 |
+
className="tribe-editor__paragraph tribe-editor__paragraph--small"
|
| 14 |
+
>
|
| 15 |
+
Modern Tribe
|
| 16 |
+
</p>
|
| 17 |
+
`;
|
common/src/modules/elements/paragraph/__tests__/element.test.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import React from 'react';
|
| 2 |
+
|
| 3 |
+
import Paragraph, { SIZES } from '../element';
|
| 4 |
+
|
| 5 |
+
describe( '<Paragraph>', () => {
|
| 6 |
+
test( 'default paragraph', () => {
|
| 7 |
+
const component = renderer.create(
|
| 8 |
+
<Paragraph>Modern Tribe</Paragraph>,
|
| 9 |
+
);
|
| 10 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 11 |
+
} );
|
| 12 |
+
|
| 13 |
+
test( 'smaller paragraph', () => {
|
| 14 |
+
const component = renderer.create(
|
| 15 |
+
<Paragraph size={ SIZES.small }>Modern Tribe</Paragraph>,
|
| 16 |
+
);
|
| 17 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 18 |
+
} );
|
| 19 |
+
} );
|
common/src/modules/elements/paragraph/element.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import React from 'react';
|
| 5 |
+
import PropTypes from 'prop-types';
|
| 6 |
+
import classNames from 'classnames';
|
| 7 |
+
|
| 8 |
+
/**
|
| 9 |
+
* Internal dependencies
|
| 10 |
+
*/
|
| 11 |
+
import './style.pcss';
|
| 12 |
+
|
| 13 |
+
export const SIZES = {
|
| 14 |
+
medium: 'medium',
|
| 15 |
+
small: 'small',
|
| 16 |
+
};
|
| 17 |
+
|
| 18 |
+
const Paragraph = ( { children, size, className } ) => (
|
| 19 |
+
<p
|
| 20 |
+
className={
|
| 21 |
+
classNames(
|
| 22 |
+
'tribe-editor__paragraph',
|
| 23 |
+
`tribe-editor__paragraph--${ size }`,
|
| 24 |
+
className,
|
| 25 |
+
)
|
| 26 |
+
}
|
| 27 |
+
>
|
| 28 |
+
{ children }
|
| 29 |
+
</p>
|
| 30 |
+
);
|
| 31 |
+
|
| 32 |
+
Paragraph.propTypes = {
|
| 33 |
+
children: PropTypes.node.isRequired,
|
| 34 |
+
size: PropTypes.oneOf( Object.keys( SIZES ) ),
|
| 35 |
+
};
|
| 36 |
+
|
| 37 |
+
Paragraph.defaultProps = {
|
| 38 |
+
size: SIZES.medium,
|
| 39 |
+
};
|
| 40 |
+
|
| 41 |
+
export default Paragraph;
|
common/src/modules/elements/paragraph/style.pcss
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
.tribe-editor__paragraph {
|
| 2 |
+
font-family: 'Helvetica', 'Arial', 'sans-serif';
|
| 3 |
+
line-height: 1.5;
|
| 4 |
+
font-weight: normal;
|
| 5 |
+
|
| 6 |
+
&--medium {
|
| 7 |
+
/* 16pt */
|
| 8 |
+
font-size: 1rem;
|
| 9 |
+
}
|
| 10 |
+
|
| 11 |
+
&--small {
|
| 12 |
+
/* 14pt */
|
| 13 |
+
font-size: 0.875rem;
|
| 14 |
+
}
|
| 15 |
+
|
| 16 |
+
a {
|
| 17 |
+
color: #11A0D2;
|
| 18 |
+
|
| 19 |
+
&:hover {
|
| 20 |
+
text-decoration: none;
|
| 21 |
+
color: #007BB4;
|
| 22 |
+
}
|
| 23 |
+
}
|
| 24 |
+
}
|
common/src/modules/elements/placeholder/__tests__/__snapshots__/element.test.js.snap
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
| 2 |
+
|
| 3 |
+
exports[`<Placeholder> component Custom Class name attached 1`] = `
|
| 4 |
+
<div
|
| 5 |
+
className="tribe-editor__placeholder custom-class-name"
|
| 6 |
+
>
|
| 7 |
+
Custom Text
|
| 8 |
+
</div>
|
| 9 |
+
`;
|
| 10 |
+
|
| 11 |
+
exports[`<Placeholder> component Default behavior 1`] = `
|
| 12 |
+
<div
|
| 13 |
+
className="tribe-editor__placeholder"
|
| 14 |
+
>
|
| 15 |
+
Custom Text
|
| 16 |
+
</div>
|
| 17 |
+
`;
|
common/src/modules/elements/placeholder/__tests__/element.test.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import React from 'react';
|
| 2 |
+
import Placeholder from '../element';
|
| 3 |
+
|
| 4 |
+
describe( '<Placeholder> component', () => {
|
| 5 |
+
test( 'Default behavior', () => {
|
| 6 |
+
const component = renderer.create(
|
| 7 |
+
<Placeholder>Custom Text</Placeholder>
|
| 8 |
+
);
|
| 9 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 10 |
+
} );
|
| 11 |
+
|
| 12 |
+
test( 'Custom Class name attached', () => {
|
| 13 |
+
const component = renderer.create(
|
| 14 |
+
<Placeholder className='custom-class-name'>Custom Text</Placeholder>
|
| 15 |
+
);
|
| 16 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 17 |
+
} );
|
| 18 |
+
} );
|
common/src/modules/elements/placeholder/element.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import React from 'react';
|
| 5 |
+
import PropTypes from 'prop-types';
|
| 6 |
+
import classNames from 'classnames';
|
| 7 |
+
|
| 8 |
+
/**
|
| 9 |
+
* Internal dependencies
|
| 10 |
+
*/
|
| 11 |
+
import './style.pcss';
|
| 12 |
+
|
| 13 |
+
const Placeholder = ( { children, className } ) => (
|
| 14 |
+
<div className={ classNames( 'tribe-editor__placeholder', className ) }>
|
| 15 |
+
{ children }
|
| 16 |
+
</div>
|
| 17 |
+
);
|
| 18 |
+
|
| 19 |
+
Placeholder.propTypes = {
|
| 20 |
+
children: PropTypes.node.isRequired,
|
| 21 |
+
};
|
| 22 |
+
|
| 23 |
+
export default Placeholder;
|
common/src/modules/elements/placeholder/style.pcss
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
.tribe-editor__placeholder {
|
| 2 |
+
border: 2px dashed #E1E3E6;
|
| 3 |
+
padding: 12px 15px 14px;
|
| 4 |
+
text-align: center;
|
| 5 |
+
font-family: 'Helvetica', 'Arial', 'sans-serif';
|
| 6 |
+
font-size: 1rem;
|
| 7 |
+
line-height: 1.5;
|
| 8 |
+
font-weight: bold;
|
| 9 |
+
color: #8D949B;
|
| 10 |
+
min-width: 260px;
|
| 11 |
+
display: inline-block;
|
| 12 |
+
}
|
common/src/modules/elements/radio-input/element.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External Dependencies
|
| 3 |
+
*/
|
| 4 |
+
import React from 'react';
|
| 5 |
+
import PropTypes from 'prop-types';
|
| 6 |
+
import classNames from 'classnames';
|
| 7 |
+
|
| 8 |
+
/**
|
| 9 |
+
* Internal dependencies
|
| 10 |
+
*/
|
| 11 |
+
import Input from '@moderntribe/common/elements/input/element';
|
| 12 |
+
|
| 13 |
+
const RadioInput = ( { checked, className, onChange, ...rest } ) => (
|
| 14 |
+
<Input
|
| 15 |
+
checked={ checked }
|
| 16 |
+
className={ classNames( 'tribe-editor__input--radio', className ) }
|
| 17 |
+
onChange={ onChange }
|
| 18 |
+
type="radio"
|
| 19 |
+
{ ...rest }
|
| 20 |
+
/>
|
| 21 |
+
);
|
| 22 |
+
|
| 23 |
+
RadioInput.propTypes = {
|
| 24 |
+
checked: PropTypes.bool,
|
| 25 |
+
className: PropTypes.string,
|
| 26 |
+
onChange: PropTypes.func,
|
| 27 |
+
};
|
| 28 |
+
|
| 29 |
+
export default RadioInput;
|
common/src/modules/elements/radio/element.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import React from 'react';
|
| 5 |
+
import PropTypes from 'prop-types';
|
| 6 |
+
import classNames from 'classnames';
|
| 7 |
+
import { noop } from 'lodash';
|
| 8 |
+
|
| 9 |
+
/**
|
| 10 |
+
* Internal dependencies
|
| 11 |
+
*/
|
| 12 |
+
import { RadioInput } from '@moderntribe/common/elements';
|
| 13 |
+
|
| 14 |
+
const Radio = ( { checked, className, disabled, id, label, onChange, name, value } ) => (
|
| 15 |
+
<div className={ classNames( 'tribe-editor__radio', className ) }>
|
| 16 |
+
<RadioInput
|
| 17 |
+
checked={ checked }
|
| 18 |
+
className="tribe-editor__radio__input"
|
| 19 |
+
disabled={ disabled }
|
| 20 |
+
id={ id }
|
| 21 |
+
name={ name }
|
| 22 |
+
onChange={ onChange }
|
| 23 |
+
value={ value }
|
| 24 |
+
/>
|
| 25 |
+
<label
|
| 26 |
+
className="tribe-editor__radio_label"
|
| 27 |
+
htmlFor={ id }
|
| 28 |
+
>
|
| 29 |
+
{ label }
|
| 30 |
+
</label>
|
| 31 |
+
</div>
|
| 32 |
+
);
|
| 33 |
+
|
| 34 |
+
Radio.defaultProps = {
|
| 35 |
+
checked: false,
|
| 36 |
+
onChange: noop,
|
| 37 |
+
};
|
| 38 |
+
|
| 39 |
+
Radio.propTypes = {
|
| 40 |
+
checked: PropTypes.bool.isRequired,
|
| 41 |
+
className: PropTypes.string,
|
| 42 |
+
disabled: PropTypes.bool,
|
| 43 |
+
id: PropTypes.string,
|
| 44 |
+
label: PropTypes.string,
|
| 45 |
+
name: PropTypes.string,
|
| 46 |
+
onChange: PropTypes.func,
|
| 47 |
+
value: PropTypes.string,
|
| 48 |
+
};
|
| 49 |
+
|
| 50 |
+
export default Radio;
|
common/src/modules/elements/select/__tests__/__snapshots__/element.test.js.snap
ADDED
|
@@ -0,0 +1,241 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
| 2 |
+
|
| 3 |
+
exports[`Select element Should render the component 1`] = `
|
| 4 |
+
<div
|
| 5 |
+
className="css-10nd86i tribe-editor__select"
|
| 6 |
+
onKeyDown={[Function]}
|
| 7 |
+
>
|
| 8 |
+
<div
|
| 9 |
+
className="css-vj8t7z tribe-editor__select__control"
|
| 10 |
+
onMouseDown={[Function]}
|
| 11 |
+
onTouchEnd={[Function]}
|
| 12 |
+
>
|
| 13 |
+
<div
|
| 14 |
+
className="css-1hwfws3 tribe-editor__select__value-container"
|
| 15 |
+
>
|
| 16 |
+
<div
|
| 17 |
+
className="css-1492t68 tribe-editor__select__placeholder"
|
| 18 |
+
>
|
| 19 |
+
Select...
|
| 20 |
+
</div>
|
| 21 |
+
<div
|
| 22 |
+
className="css-1g6gooi"
|
| 23 |
+
>
|
| 24 |
+
<div
|
| 25 |
+
className="tribe-editor__select__input"
|
| 26 |
+
style={
|
| 27 |
+
Object {
|
| 28 |
+
"display": "inline-block",
|
| 29 |
+
}
|
| 30 |
+
}
|
| 31 |
+
>
|
| 32 |
+
<input
|
| 33 |
+
aria-autocomplete="list"
|
| 34 |
+
autoCapitalize="none"
|
| 35 |
+
autoComplete="off"
|
| 36 |
+
autoCorrect="off"
|
| 37 |
+
disabled={false}
|
| 38 |
+
id="react-select-2-input"
|
| 39 |
+
onBlur={[Function]}
|
| 40 |
+
onChange={[Function]}
|
| 41 |
+
onFocus={[Function]}
|
| 42 |
+
spellCheck="false"
|
| 43 |
+
style={
|
| 44 |
+
Object {
|
| 45 |
+
"background": 0,
|
| 46 |
+
"border": 0,
|
| 47 |
+
"boxSizing": "content-box",
|
| 48 |
+
"color": "inherit",
|
| 49 |
+
"fontSize": "inherit",
|
| 50 |
+
"opacity": 1,
|
| 51 |
+
"outline": 0,
|
| 52 |
+
"padding": 0,
|
| 53 |
+
"width": "1px",
|
| 54 |
+
}
|
| 55 |
+
}
|
| 56 |
+
tabIndex="0"
|
| 57 |
+
type="text"
|
| 58 |
+
value=""
|
| 59 |
+
/>
|
| 60 |
+
<div
|
| 61 |
+
style={
|
| 62 |
+
Object {
|
| 63 |
+
"height": 0,
|
| 64 |
+
"left": 0,
|
| 65 |
+
"overflow": "scroll",
|
| 66 |
+
"position": "absolute",
|
| 67 |
+
"top": 0,
|
| 68 |
+
"visibility": "hidden",
|
| 69 |
+
"whiteSpace": "pre",
|
| 70 |
+
}
|
| 71 |
+
}
|
| 72 |
+
>
|
| 73 |
+
|
| 74 |
+
</div>
|
| 75 |
+
</div>
|
| 76 |
+
</div>
|
| 77 |
+
</div>
|
| 78 |
+
<div
|
| 79 |
+
className="css-1wy0on6 tribe-editor__select__indicators"
|
| 80 |
+
>
|
| 81 |
+
<div
|
| 82 |
+
aria-hidden="true"
|
| 83 |
+
className="css-1ep9fjw tribe-editor__select__indicator tribe-editor__select__dropdown-indicator"
|
| 84 |
+
onMouseDown={[Function]}
|
| 85 |
+
onTouchEnd={[Function]}
|
| 86 |
+
>
|
| 87 |
+
<span
|
| 88 |
+
className="tribe-editor__select__dropdown-indicator"
|
| 89 |
+
>
|
| 90 |
+
arrow-down
|
| 91 |
+
</span>
|
| 92 |
+
</div>
|
| 93 |
+
</div>
|
| 94 |
+
</div>
|
| 95 |
+
</div>
|
| 96 |
+
`;
|
| 97 |
+
|
| 98 |
+
exports[`Select element Should render the component with class 1`] = `
|
| 99 |
+
<div
|
| 100 |
+
className="css-10nd86i tribe-editor__select test-class"
|
| 101 |
+
onKeyDown={[Function]}
|
| 102 |
+
>
|
| 103 |
+
<div
|
| 104 |
+
className="css-vj8t7z tribe-editor__select__control"
|
| 105 |
+
onMouseDown={[Function]}
|
| 106 |
+
onTouchEnd={[Function]}
|
| 107 |
+
>
|
| 108 |
+
<div
|
| 109 |
+
className="css-1hwfws3 tribe-editor__select__value-container"
|
| 110 |
+
>
|
| 111 |
+
<div
|
| 112 |
+
className="css-1492t68 tribe-editor__select__placeholder"
|
| 113 |
+
>
|
| 114 |
+
Select...
|
| 115 |
+
</div>
|
| 116 |
+
<div
|
| 117 |
+
className="css-1g6gooi"
|
| 118 |
+
>
|
| 119 |
+
<div
|
| 120 |
+
className="tribe-editor__select__input"
|
| 121 |
+
style={
|
| 122 |
+
Object {
|
| 123 |
+
"display": "inline-block",
|
| 124 |
+
}
|
| 125 |
+
}
|
| 126 |
+
>
|
| 127 |
+
<input
|
| 128 |
+
aria-autocomplete="list"
|
| 129 |
+
autoCapitalize="none"
|
| 130 |
+
autoComplete="off"
|
| 131 |
+
autoCorrect="off"
|
| 132 |
+
disabled={false}
|
| 133 |
+
id="react-select-3-input"
|
| 134 |
+
onBlur={[Function]}
|
| 135 |
+
onChange={[Function]}
|
| 136 |
+
onFocus={[Function]}
|
| 137 |
+
spellCheck="false"
|
| 138 |
+
style={
|
| 139 |
+
Object {
|
| 140 |
+
"background": 0,
|
| 141 |
+
"border": 0,
|
| 142 |
+
"boxSizing": "content-box",
|
| 143 |
+
"color": "inherit",
|
| 144 |
+
"fontSize": "inherit",
|
| 145 |
+
"opacity": 1,
|
| 146 |
+
"outline": 0,
|
| 147 |
+
"padding": 0,
|
| 148 |
+
"width": "1px",
|
| 149 |
+
}
|
| 150 |
+
}
|
| 151 |
+
tabIndex="0"
|
| 152 |
+
type="text"
|
| 153 |
+
value=""
|
| 154 |
+
/>
|
| 155 |
+
<div
|
| 156 |
+
style={
|
| 157 |
+
Object {
|
| 158 |
+
"height": 0,
|
| 159 |
+
"left": 0,
|
| 160 |
+
"overflow": "scroll",
|
| 161 |
+
"position": "absolute",
|
| 162 |
+
"top": 0,
|
| 163 |
+
"visibility": "hidden",
|
| 164 |
+
"whiteSpace": "pre",
|
| 165 |
+
}
|
| 166 |
+
}
|
| 167 |
+
>
|
| 168 |
+
|
| 169 |
+
</div>
|
| 170 |
+
</div>
|
| 171 |
+
</div>
|
| 172 |
+
</div>
|
| 173 |
+
<div
|
| 174 |
+
className="css-1wy0on6 tribe-editor__select__indicators"
|
| 175 |
+
>
|
| 176 |
+
<div
|
| 177 |
+
aria-hidden="true"
|
| 178 |
+
className="css-1ep9fjw tribe-editor__select__indicator tribe-editor__select__dropdown-indicator"
|
| 179 |
+
onMouseDown={[Function]}
|
| 180 |
+
onTouchEnd={[Function]}
|
| 181 |
+
>
|
| 182 |
+
<span
|
| 183 |
+
className="tribe-editor__select__dropdown-indicator"
|
| 184 |
+
>
|
| 185 |
+
arrow-down
|
| 186 |
+
</span>
|
| 187 |
+
</div>
|
| 188 |
+
</div>
|
| 189 |
+
</div>
|
| 190 |
+
</div>
|
| 191 |
+
`;
|
| 192 |
+
|
| 193 |
+
exports[`Select element Should render the component with extra props 1`] = `
|
| 194 |
+
<div
|
| 195 |
+
className="css-10nd86i tribe-editor__select"
|
| 196 |
+
onKeyDown={[Function]}
|
| 197 |
+
>
|
| 198 |
+
<div
|
| 199 |
+
className="css-vj8t7z tribe-editor__select__control"
|
| 200 |
+
onMouseDown={[Function]}
|
| 201 |
+
onTouchEnd={[Function]}
|
| 202 |
+
>
|
| 203 |
+
<div
|
| 204 |
+
className="css-1hwfws3 tribe-editor__select__value-container"
|
| 205 |
+
>
|
| 206 |
+
<div
|
| 207 |
+
className="css-1492t68 tribe-editor__select__placeholder"
|
| 208 |
+
>
|
| 209 |
+
Select...
|
| 210 |
+
</div>
|
| 211 |
+
<input
|
| 212 |
+
className="css-14uuagi"
|
| 213 |
+
disabled={false}
|
| 214 |
+
id="react-select-4-input"
|
| 215 |
+
onBlur={[Function]}
|
| 216 |
+
onChange={[Function]}
|
| 217 |
+
onFocus={[Function]}
|
| 218 |
+
readOnly={true}
|
| 219 |
+
tabIndex="0"
|
| 220 |
+
value=""
|
| 221 |
+
/>
|
| 222 |
+
</div>
|
| 223 |
+
<div
|
| 224 |
+
className="css-1wy0on6 tribe-editor__select__indicators"
|
| 225 |
+
>
|
| 226 |
+
<div
|
| 227 |
+
aria-hidden="true"
|
| 228 |
+
className="css-1ep9fjw tribe-editor__select__indicator tribe-editor__select__dropdown-indicator"
|
| 229 |
+
onMouseDown={[Function]}
|
| 230 |
+
onTouchEnd={[Function]}
|
| 231 |
+
>
|
| 232 |
+
<span
|
| 233 |
+
className="tribe-editor__select__dropdown-indicator"
|
| 234 |
+
>
|
| 235 |
+
arrow-down
|
| 236 |
+
</span>
|
| 237 |
+
</div>
|
| 238 |
+
</div>
|
| 239 |
+
</div>
|
| 240 |
+
</div>
|
| 241 |
+
`;
|
common/src/modules/elements/select/__tests__/element.test.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import React from 'react';
|
| 5 |
+
|
| 6 |
+
/**
|
| 7 |
+
* Internal dependencies
|
| 8 |
+
*/
|
| 9 |
+
import Select from '../element.js';
|
| 10 |
+
|
| 11 |
+
const options = [
|
| 12 |
+
{ label: 'Test 1', value: 'test-1' },
|
| 13 |
+
{ label: 'Test 2', value: 'test-2' },
|
| 14 |
+
];
|
| 15 |
+
|
| 16 |
+
describe( 'Select element', () => {
|
| 17 |
+
it( 'Should render the component', () => {
|
| 18 |
+
const component = renderer.create( <Select options={ options } /> );
|
| 19 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 20 |
+
} );
|
| 21 |
+
|
| 22 |
+
it( 'Should render the component with class', () => {
|
| 23 |
+
const component = renderer.create( <Select options={ options } className="test-class" /> );
|
| 24 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 25 |
+
} );
|
| 26 |
+
|
| 27 |
+
it( 'Should render the component with extra props', () => {
|
| 28 |
+
const component = renderer.create( <Select options={ options } isSearchable={ false } /> );
|
| 29 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 30 |
+
} );
|
| 31 |
+
} );
|
common/src/modules/elements/select/element.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import React from 'react';
|
| 5 |
+
import PropTypes from 'prop-types';
|
| 6 |
+
import classNames from 'classnames';
|
| 7 |
+
import ReactSelect, { components } from 'react-select';
|
| 8 |
+
import { Dashicon } from '@wordpress/components';
|
| 9 |
+
|
| 10 |
+
/**
|
| 11 |
+
* Internal dependencies
|
| 12 |
+
*/
|
| 13 |
+
import './style.pcss';
|
| 14 |
+
|
| 15 |
+
const DropdownIndicator = ( props ) => (
|
| 16 |
+
components.DropdownIndicator && (
|
| 17 |
+
<components.DropdownIndicator { ...props }>
|
| 18 |
+
<Dashicon
|
| 19 |
+
className="tribe-editor__select__dropdown-indicator"
|
| 20 |
+
icon={ 'arrow-down' }
|
| 21 |
+
/>
|
| 22 |
+
</components.DropdownIndicator>
|
| 23 |
+
)
|
| 24 |
+
);
|
| 25 |
+
|
| 26 |
+
const IndicatorSeparator = () => null;
|
| 27 |
+
|
| 28 |
+
const Select = ( { className, ...rest } ) => (
|
| 29 |
+
<ReactSelect
|
| 30 |
+
className={ classNames( 'tribe-editor__select', className ) }
|
| 31 |
+
classNamePrefix="tribe-editor__select"
|
| 32 |
+
components={ { DropdownIndicator, IndicatorSeparator } }
|
| 33 |
+
{ ...rest }
|
| 34 |
+
/>
|
| 35 |
+
);
|
| 36 |
+
|
| 37 |
+
Select.propTypes = {
|
| 38 |
+
className: PropTypes.string,
|
| 39 |
+
};
|
| 40 |
+
|
| 41 |
+
export default Select;
|
common/src/modules/elements/select/style.pcss
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
.tribe-editor__select {
|
| 2 |
+
|
| 3 |
+
.tribe-editor__select__control {
|
| 4 |
+
height: 46px;
|
| 5 |
+
border: 1px solid #E1E3E6;
|
| 6 |
+
border-radius: 3px;
|
| 7 |
+
background-color: #FFFFFF;
|
| 8 |
+
|
| 9 |
+
&:hover {
|
| 10 |
+
border: 1px solid #E1E3E6;
|
| 11 |
+
}
|
| 12 |
+
|
| 13 |
+
&--is-focused {
|
| 14 |
+
box-shadow: none;
|
| 15 |
+
}
|
| 16 |
+
}
|
| 17 |
+
|
| 18 |
+
.tribe-editor__select__value-container {
|
| 19 |
+
padding: 2px 10px 2px 15px;
|
| 20 |
+
}
|
| 21 |
+
|
| 22 |
+
.tribe-editor__select__single-value {
|
| 23 |
+
margin: 0;
|
| 24 |
+
max-width: calc(100% - 15px);
|
| 25 |
+
font-size: 16px;
|
| 26 |
+
line-height: 1.5;
|
| 27 |
+
}
|
| 28 |
+
|
| 29 |
+
.tribe-editor__select__input {
|
| 30 |
+
font-size: 16px;
|
| 31 |
+
|
| 32 |
+
& > input {
|
| 33 |
+
margin: 0;
|
| 34 |
+
line-height: 1.5;
|
| 35 |
+
}
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
svg.tribe-editor__select__dropdown-indicator {
|
| 39 |
+
fill: #555D66;
|
| 40 |
+
}
|
| 41 |
+
|
| 42 |
+
.tribe-editor__select__menu {
|
| 43 |
+
margin: 0;
|
| 44 |
+
border: 1px solid #E1E3E6;
|
| 45 |
+
border-top: none;
|
| 46 |
+
border-radius: 0;
|
| 47 |
+
border-bottom-left-radius: 3px;
|
| 48 |
+
border-bottom-right-radius: 3px;
|
| 49 |
+
box-shadow: none;
|
| 50 |
+
transform: translateY(-7px);
|
| 51 |
+
z-index: 10;
|
| 52 |
+
}
|
| 53 |
+
|
| 54 |
+
.tribe-editor__select__menu-list {
|
| 55 |
+
padding: 0;
|
| 56 |
+
}
|
| 57 |
+
|
| 58 |
+
.tribe-editor__select__option {
|
| 59 |
+
font-size: 16px;
|
| 60 |
+
line-height: 1.5;
|
| 61 |
+
padding: 3px 15px;
|
| 62 |
+
|
| 63 |
+
&--is-focused {
|
| 64 |
+
background-color: #E7F5FA;
|
| 65 |
+
}
|
| 66 |
+
|
| 67 |
+
&--is-selected {
|
| 68 |
+
background-color: #11A0D2;
|
| 69 |
+
}
|
| 70 |
+
}
|
| 71 |
+
|
| 72 |
+
&--is-disabled {
|
| 73 |
+
|
| 74 |
+
svg.tribe-editor__select__dropdown-indicator {
|
| 75 |
+
fill: #AEB4BB;
|
| 76 |
+
}
|
| 77 |
+
}
|
| 78 |
+
}
|
common/src/modules/elements/style.pcss
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
| 1 |
+
.post-type-tribe_events .editor-styles-wrapper {
|
| 2 |
+
max-width: none!important;
|
| 3 |
+
}
|
common/src/modules/elements/textarea/element.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External Dependencies
|
| 3 |
+
*/
|
| 4 |
+
import React from 'react';
|
| 5 |
+
import PropTypes from 'prop-types';
|
| 6 |
+
import classNames from 'classnames';
|
| 7 |
+
|
| 8 |
+
/**
|
| 9 |
+
* Internal dependencies
|
| 10 |
+
*/
|
| 11 |
+
|
| 12 |
+
const Textarea = ( { className, ...rest } ) => (
|
| 13 |
+
<textarea className={ classNames( 'tribe-editor__textarea', className ) } { ...rest } />
|
| 14 |
+
);
|
| 15 |
+
|
| 16 |
+
Textarea.propTypes = {
|
| 17 |
+
className: PropTypes.string,
|
| 18 |
+
};
|
| 19 |
+
|
| 20 |
+
export default Textarea;
|
common/src/modules/elements/time-picker/element.js
ADDED
|
@@ -0,0 +1,204 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import React, { Fragment } from 'react';
|
| 5 |
+
import PropTypes from 'prop-types';
|
| 6 |
+
import moment from 'moment';
|
| 7 |
+
import { noop } from 'lodash';
|
| 8 |
+
import classNames from 'classnames';
|
| 9 |
+
import { ScrollTo, ScrollArea } from 'react-scroll-to';
|
| 10 |
+
|
| 11 |
+
/**
|
| 12 |
+
* WordPress dependencies
|
| 13 |
+
*/
|
| 14 |
+
import {
|
| 15 |
+
Dropdown,
|
| 16 |
+
Dashicon,
|
| 17 |
+
} from '@wordpress/components';
|
| 18 |
+
import { __ } from '@wordpress/i18n';
|
| 19 |
+
|
| 20 |
+
/**
|
| 21 |
+
* Internal dependencies
|
| 22 |
+
*/
|
| 23 |
+
import { PreventBlockClose } from '@moderntribe/common/components';
|
| 24 |
+
import Button from '@moderntribe/common/elements/button/element';
|
| 25 |
+
import Input from '@moderntribe/common/elements/input/element';
|
| 26 |
+
import {
|
| 27 |
+
date as dateUtil,
|
| 28 |
+
moment as momentUtil,
|
| 29 |
+
time as timeUtil,
|
| 30 |
+
TribePropTypes,
|
| 31 |
+
} from '@moderntribe/common/utils';
|
| 32 |
+
import './style.pcss';
|
| 33 |
+
|
| 34 |
+
const TimePicker = ( {
|
| 35 |
+
allDay,
|
| 36 |
+
current,
|
| 37 |
+
disabled,
|
| 38 |
+
end,
|
| 39 |
+
onBlur,
|
| 40 |
+
onChange,
|
| 41 |
+
onClick,
|
| 42 |
+
onFocus,
|
| 43 |
+
showAllDay,
|
| 44 |
+
start,
|
| 45 |
+
step,
|
| 46 |
+
timeFormat,
|
| 47 |
+
} ) => {
|
| 48 |
+
|
| 49 |
+
const renderLabel = ( onAllDayClick ) => {
|
| 50 |
+
if ( allDay ) {
|
| 51 |
+
return (
|
| 52 |
+
<Button
|
| 53 |
+
className="tribe-editor__timepicker__all-day-btn"
|
| 54 |
+
disabled={ disabled }
|
| 55 |
+
onClick={ onAllDayClick }
|
| 56 |
+
>
|
| 57 |
+
{ __( 'All Day', 'tribe-common' ) }
|
| 58 |
+
</Button>
|
| 59 |
+
);
|
| 60 |
+
}
|
| 61 |
+
|
| 62 |
+
return (
|
| 63 |
+
<Input
|
| 64 |
+
className="tribe-editor__timepicker__input"
|
| 65 |
+
disabled={ disabled }
|
| 66 |
+
onBlur={ onBlur }
|
| 67 |
+
onChange={ onChange }
|
| 68 |
+
onFocus={ onFocus }
|
| 69 |
+
type="text"
|
| 70 |
+
value={ current }
|
| 71 |
+
/>
|
| 72 |
+
);
|
| 73 |
+
};
|
| 74 |
+
|
| 75 |
+
const renderToggle = ( { onToggle, isOpen } ) => (
|
| 76 |
+
<Fragment>
|
| 77 |
+
{ renderLabel( onToggle ) }
|
| 78 |
+
<Button
|
| 79 |
+
aria-expanded={ isOpen }
|
| 80 |
+
className="tribe-editor__timepicker__toggle-btn"
|
| 81 |
+
disabled={ disabled }
|
| 82 |
+
onClick={ onToggle }
|
| 83 |
+
>
|
| 84 |
+
<Dashicon
|
| 85 |
+
className="tribe-editor__timepicker__toggle-btn-icon"
|
| 86 |
+
icon={ isOpen ? 'arrow-up' : 'arrow-down' }
|
| 87 |
+
/>
|
| 88 |
+
</Button>
|
| 89 |
+
</Fragment>
|
| 90 |
+
);
|
| 91 |
+
|
| 92 |
+
const getItems = () => {
|
| 93 |
+
const items = [];
|
| 94 |
+
|
| 95 |
+
const startSeconds = timeUtil.toSeconds( start, timeUtil.TIME_FORMAT_HH_MM );
|
| 96 |
+
const endSeconds = timeUtil.toSeconds( end, timeUtil.TIME_FORMAT_HH_MM );
|
| 97 |
+
|
| 98 |
+
const currentMoment = moment( current, momentUtil.TIME_FORMAT );
|
| 99 |
+
|
| 100 |
+
for ( let time = startSeconds; time <= endSeconds; time += step ) {
|
| 101 |
+
let isCurrent = false;
|
| 102 |
+
if ( currentMoment.isValid() ) {
|
| 103 |
+
const currentTime = momentUtil.toTime24Hr( currentMoment );
|
| 104 |
+
isCurrent = time === timeUtil.toSeconds( currentTime, timeUtil.TIME_FORMAT_HH_MM );
|
| 105 |
+
}
|
| 106 |
+
|
| 107 |
+
items.push( {
|
| 108 |
+
value: time,
|
| 109 |
+
text: formatLabel( time ),
|
| 110 |
+
isCurrent,
|
| 111 |
+
} );
|
| 112 |
+
}
|
| 113 |
+
|
| 114 |
+
return items;
|
| 115 |
+
};
|
| 116 |
+
|
| 117 |
+
const formatLabel = ( seconds ) => {
|
| 118 |
+
return momentUtil.setTimeInSeconds( moment(), seconds ).format( momentUtil.toFormat( timeFormat ) );
|
| 119 |
+
};
|
| 120 |
+
|
| 121 |
+
const renderItem = ( item, onClose ) => {
|
| 122 |
+
const itemClasses = {
|
| 123 |
+
'tribe-editor__timepicker__item': true,
|
| 124 |
+
'tribe-editor__timepicker__item--current': item.isCurrent && ! allDay,
|
| 125 |
+
};
|
| 126 |
+
|
| 127 |
+
return (
|
| 128 |
+
<Button
|
| 129 |
+
key={ `time-${ item.value }` }
|
| 130 |
+
className={ classNames( itemClasses ) }
|
| 131 |
+
value={ item.value }
|
| 132 |
+
onClick={ () => onClick( item.value, onClose ) }
|
| 133 |
+
>
|
| 134 |
+
{ item.text }
|
| 135 |
+
</Button>
|
| 136 |
+
);
|
| 137 |
+
};
|
| 138 |
+
|
| 139 |
+
const renderContent = ( { onClose } ) => (
|
| 140 |
+
<ScrollTo>
|
| 141 |
+
{ () => (
|
| 142 |
+
<PreventBlockClose>
|
| 143 |
+
<ScrollArea
|
| 144 |
+
key="tribe-element-timepicker-items"
|
| 145 |
+
className="tribe-editor__timepicker__items"
|
| 146 |
+
>
|
| 147 |
+
{ showAllDay && renderItem(
|
| 148 |
+
{ text: __( 'All Day', 'tribe-common' ), value: 'all-day' },
|
| 149 |
+
onClose,
|
| 150 |
+
) }
|
| 151 |
+
{ getItems().map( ( item ) => renderItem( item, onClose ) ) }
|
| 152 |
+
</ScrollArea>
|
| 153 |
+
</PreventBlockClose>
|
| 154 |
+
) }
|
| 155 |
+
</ScrollTo>
|
| 156 |
+
);
|
| 157 |
+
|
| 158 |
+
return (
|
| 159 |
+
<div
|
| 160 |
+
key="tribe-element-timepicker"
|
| 161 |
+
className="tribe-editor__timepicker"
|
| 162 |
+
>
|
| 163 |
+
<Dropdown
|
| 164 |
+
className="tribe-editor__timepicker__toggle"
|
| 165 |
+
contentClassName="tribe-editor__timepicker__content"
|
| 166 |
+
position="bottom center"
|
| 167 |
+
renderToggle={ renderToggle }
|
| 168 |
+
renderContent={ renderContent }
|
| 169 |
+
/>
|
| 170 |
+
</div>
|
| 171 |
+
);
|
| 172 |
+
};
|
| 173 |
+
|
| 174 |
+
TimePicker.defaultProps = {
|
| 175 |
+
allDay: false,
|
| 176 |
+
onBlur: noop,
|
| 177 |
+
onChange: noop,
|
| 178 |
+
onClick: noop,
|
| 179 |
+
onFocus: noop,
|
| 180 |
+
step: timeUtil.HALF_HOUR_IN_SECONDS,
|
| 181 |
+
timeFormat: dateUtil.FORMATS.WP.time,
|
| 182 |
+
};
|
| 183 |
+
|
| 184 |
+
TimePicker.propTypes = {
|
| 185 |
+
/**
|
| 186 |
+
* TribePropTypes.timeFormat check for string formatted as a time
|
| 187 |
+
* using 24h clock in hh:mm format
|
| 188 |
+
* e.g. 00:24, 03:57, 21:12
|
| 189 |
+
*/
|
| 190 |
+
allDay: PropTypes.bool,
|
| 191 |
+
current: PropTypes.string,
|
| 192 |
+
disabled: PropTypes.bool,
|
| 193 |
+
end: TribePropTypes.timeFormat.isRequired,
|
| 194 |
+
onBlur: PropTypes.func,
|
| 195 |
+
onChange: PropTypes.func,
|
| 196 |
+
onClick: PropTypes.func,
|
| 197 |
+
onFocus: PropTypes.func,
|
| 198 |
+
showAllDay: PropTypes.bool,
|
| 199 |
+
start: TribePropTypes.timeFormat.isRequired,
|
| 200 |
+
step: PropTypes.number,
|
| 201 |
+
timeFormat: PropTypes.string,
|
| 202 |
+
};
|
| 203 |
+
|
| 204 |
+
export default TimePicker;
|
common/src/modules/elements/time-picker/style.pcss
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
.tribe-editor__timepicker {
|
| 2 |
+
display: inline-block;
|
| 3 |
+
}
|
| 4 |
+
|
| 5 |
+
.tribe-editor__timepicker__toggle {
|
| 6 |
+
background-color: #FFF;
|
| 7 |
+
border: 1px solid #e1e3e6;
|
| 8 |
+
border-radius: 2px;
|
| 9 |
+
display: flex;
|
| 10 |
+
align-items: center;
|
| 11 |
+
justify-content: center;
|
| 12 |
+
|
| 13 |
+
input.tribe-editor__timepicker__input[type="text"] {
|
| 14 |
+
font-family: Helvetica, sans-serif;
|
| 15 |
+
font-size: 14px;
|
| 16 |
+
line-height: 1.5;
|
| 17 |
+
padding: 6px 0 6px 10px;
|
| 18 |
+
border: none;
|
| 19 |
+
width: 80px;
|
| 20 |
+
}
|
| 21 |
+
|
| 22 |
+
button.tribe-editor__timepicker__toggle-btn {
|
| 23 |
+
padding: 10px;
|
| 24 |
+
|
| 25 |
+
&:disabled > svg.dashicon {
|
| 26 |
+
fill: #AEB4BB;
|
| 27 |
+
}
|
| 28 |
+
}
|
| 29 |
+
|
| 30 |
+
button.tribe-editor__timepicker__all-day-btn {
|
| 31 |
+
color: #545D66;
|
| 32 |
+
line-height: 20px;
|
| 33 |
+
padding: 6px 10px 6px;
|
| 34 |
+
text-decoration: none;
|
| 35 |
+
display: flex;
|
| 36 |
+
align-items: center;
|
| 37 |
+
justify-content: center;
|
| 38 |
+
}
|
| 39 |
+
}
|
| 40 |
+
|
| 41 |
+
.tribe-editor__timepicker__content {
|
| 42 |
+
|
| 43 |
+
&.components-popover {
|
| 44 |
+
|
| 45 |
+
.components-popover__content {
|
| 46 |
+
min-width: 110px;
|
| 47 |
+
}
|
| 48 |
+
}
|
| 49 |
+
|
| 50 |
+
.tribe-editor__timepicker__items {
|
| 51 |
+
height: 250px;
|
| 52 |
+
overflow: auto;
|
| 53 |
+
|
| 54 |
+
.components-placeholder {
|
| 55 |
+
height: inherit;
|
| 56 |
+
}
|
| 57 |
+
}
|
| 58 |
+
|
| 59 |
+
.tribe-editor__timepicker__item {
|
| 60 |
+
display: block;
|
| 61 |
+
width: 100%;
|
| 62 |
+
color: #555d66;
|
| 63 |
+
padding: 5px 12px;
|
| 64 |
+
cursor: pointer;
|
| 65 |
+
border-bottom: 1px solid #e2e4e7;
|
| 66 |
+
line-height: 20px;
|
| 67 |
+
background: transparent;
|
| 68 |
+
text-align: left;
|
| 69 |
+
|
| 70 |
+
&:hover,
|
| 71 |
+
&:focus {
|
| 72 |
+
background-color: #e7f5fa;
|
| 73 |
+
}
|
| 74 |
+
|
| 75 |
+
&--current {
|
| 76 |
+
color: #ffffff;
|
| 77 |
+
background-color: #009fd4;
|
| 78 |
+
|
| 79 |
+
&:hover,
|
| 80 |
+
&:focus {
|
| 81 |
+
color: #ffffff;
|
| 82 |
+
background-color: #009fd4;
|
| 83 |
+
}
|
| 84 |
+
}
|
| 85 |
+
}
|
| 86 |
+
}
|
common/src/modules/elements/tooltip/__tests__/__snapshots__/element.test.js.snap
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
| 2 |
+
|
| 3 |
+
exports[`Tooltip Element renders a tooltip 1`] = `
|
| 4 |
+
<div>
|
| 5 |
+
<span>
|
| 6 |
+
here is the tooltip text
|
| 7 |
+
</span>
|
| 8 |
+
<span>
|
| 9 |
+
bottom left
|
| 10 |
+
</span>
|
| 11 |
+
<span>
|
| 12 |
+
<button
|
| 13 |
+
aria-label="here is the tooltip text"
|
| 14 |
+
className="tribe-editor__button tribe-editor__tooltip-label label-class-name"
|
| 15 |
+
onClick={[Function]}
|
| 16 |
+
type="button"
|
| 17 |
+
>
|
| 18 |
+
some label
|
| 19 |
+
</button>
|
| 20 |
+
</span>
|
| 21 |
+
</div>
|
| 22 |
+
`;
|
common/src/modules/elements/tooltip/__tests__/element.test.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import React from 'react';
|
| 5 |
+
import renderer from 'react-test-renderer';
|
| 6 |
+
|
| 7 |
+
/**
|
| 8 |
+
* Internal dependencies
|
| 9 |
+
*/
|
| 10 |
+
import Tooltip from '@moderntribe/common/elements/tooltip/element';
|
| 11 |
+
|
| 12 |
+
jest.mock( '@wordpress/components', () => ( {
|
| 13 |
+
Tooltip: ({ text, position, children }) => (
|
| 14 |
+
<div>
|
| 15 |
+
<span>{ text }</span>
|
| 16 |
+
<span>{ position }</span>
|
| 17 |
+
<span>{ children }</span>
|
| 18 |
+
</div>
|
| 19 |
+
),
|
| 20 |
+
} ) );
|
| 21 |
+
|
| 22 |
+
describe( 'Tooltip Element', () => {
|
| 23 |
+
it( 'renders a tooltip', () => {
|
| 24 |
+
const props = {
|
| 25 |
+
label: 'some label',
|
| 26 |
+
labelClassName: 'label-class-name',
|
| 27 |
+
position: 'bottom left',
|
| 28 |
+
text: 'here is the tooltip text',
|
| 29 |
+
};
|
| 30 |
+
const component = renderer.create( <Tooltip { ...props } />)
|
| 31 |
+
expect( component.toJSON() ).toMatchSnapshot()
|
| 32 |
+
} );
|
| 33 |
+
} );
|
common/src/modules/elements/tooltip/element.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import React, { PureComponent } from 'react';
|
| 5 |
+
import PropTypes from 'prop-types';
|
| 6 |
+
import classNames from 'classnames';
|
| 7 |
+
|
| 8 |
+
/**
|
| 9 |
+
* WordPress dependencies
|
| 10 |
+
*/
|
| 11 |
+
import { Tooltip as WpTooltip } from '@wordpress/components';
|
| 12 |
+
|
| 13 |
+
/**
|
| 14 |
+
* Internal dependencies
|
| 15 |
+
*/
|
| 16 |
+
import { Button } from '@moderntribe/common/elements';
|
| 17 |
+
|
| 18 |
+
class Tooltip extends PureComponent {
|
| 19 |
+
static defaultProps = {
|
| 20 |
+
position: 'top right',
|
| 21 |
+
text: '',
|
| 22 |
+
};
|
| 23 |
+
|
| 24 |
+
static propTypes = {
|
| 25 |
+
disabled: PropTypes.bool,
|
| 26 |
+
label: PropTypes.node,
|
| 27 |
+
labelClassName: PropTypes.string,
|
| 28 |
+
position: PropTypes.oneOf( [
|
| 29 |
+
'top left',
|
| 30 |
+
'top center',
|
| 31 |
+
'top right',
|
| 32 |
+
'bottom left',
|
| 33 |
+
'bottom center',
|
| 34 |
+
'bottom right',
|
| 35 |
+
] ),
|
| 36 |
+
text: PropTypes.string,
|
| 37 |
+
};
|
| 38 |
+
|
| 39 |
+
render() {
|
| 40 |
+
const { disabled, label, labelClassName, position, text } = this.props;
|
| 41 |
+
|
| 42 |
+
return (
|
| 43 |
+
<WpTooltip text={ text } position={ position }>
|
| 44 |
+
<Button
|
| 45 |
+
aria-label={ text }
|
| 46 |
+
className={ classNames( 'tribe-editor__tooltip-label', labelClassName ) }
|
| 47 |
+
disabled={ disabled }
|
| 48 |
+
>
|
| 49 |
+
{ label }
|
| 50 |
+
</Button>
|
| 51 |
+
</WpTooltip>
|
| 52 |
+
);
|
| 53 |
+
}
|
| 54 |
+
}
|
| 55 |
+
|
| 56 |
+
export default Tooltip;
|
common/src/modules/elements/tooltip/style.pcss
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
.components-tooltip {
|
| 2 |
+
|
| 3 |
+
.components-popover__content {
|
| 4 |
+
white-space: normal;
|
| 5 |
+
min-width: 350px;
|
| 6 |
+
max-width: 600px;
|
| 7 |
+
}
|
| 8 |
+
|
| 9 |
+
&:not(.is-mobile) {
|
| 10 |
+
.components-popover__content {
|
| 11 |
+
min-width: 350px;
|
| 12 |
+
}
|
| 13 |
+
}
|
| 14 |
+
}
|
common/src/modules/elements/url-input/element.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External Dependencies
|
| 3 |
+
*/
|
| 4 |
+
import React from 'react';
|
| 5 |
+
import PropTypes from 'prop-types';
|
| 6 |
+
import classNames from 'classnames';
|
| 7 |
+
|
| 8 |
+
/**
|
| 9 |
+
* Internal dependencies
|
| 10 |
+
*/
|
| 11 |
+
import Input from '@moderntribe/common/elements/input/element';
|
| 12 |
+
|
| 13 |
+
const UrlInput = ( { checked, className, onChange, ...rest } ) => (
|
| 14 |
+
<Input
|
| 15 |
+
type="url"
|
| 16 |
+
className={ classNames( 'tribe-editor__input--url', className ) }
|
| 17 |
+
onChange={ onChange }
|
| 18 |
+
{ ...rest }
|
| 19 |
+
/>
|
| 20 |
+
);
|
| 21 |
+
|
| 22 |
+
UrlInput.propTypes = {
|
| 23 |
+
className: PropTypes.string,
|
| 24 |
+
onChange: PropTypes.func,
|
| 25 |
+
};
|
| 26 |
+
|
| 27 |
+
export default UrlInput;
|
common/src/modules/hoc/__tests__/__snapshots__/with-form.test.js.snap
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
| 2 |
+
|
| 3 |
+
exports[`HOC - With Form Should register the postType by dispatching the actions 1`] = `
|
| 4 |
+
Array [
|
| 5 |
+
Object {
|
| 6 |
+
"payload": Object {
|
| 7 |
+
"id": "posts",
|
| 8 |
+
"type": "post",
|
| 9 |
+
},
|
| 10 |
+
"type": "@@MT/COMMON/ADD_FORM",
|
| 11 |
+
},
|
| 12 |
+
]
|
| 13 |
+
`;
|
| 14 |
+
|
| 15 |
+
exports[`HOC - With Form Should render a component 1`] = `
|
| 16 |
+
<div>
|
| 17 |
+
With Form!
|
| 18 |
+
</div>
|
| 19 |
+
`;
|
common/src/modules/hoc/__tests__/__snapshots__/with-save-data.test.js.snap
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
| 2 |
+
|
| 3 |
+
exports[`HOC - With Details Should render a component 1`] = `
|
| 4 |
+
<div
|
| 5 |
+
attributes={
|
| 6 |
+
Object {
|
| 7 |
+
"description": "",
|
| 8 |
+
"organizers": Array [],
|
| 9 |
+
"title": "Modern Tribe",
|
| 10 |
+
}
|
| 11 |
+
}
|
| 12 |
+
description="The Next Generation of Digital Agency"
|
| 13 |
+
isolated={false}
|
| 14 |
+
name="tribe/event"
|
| 15 |
+
onBlockCreated={[Function]}
|
| 16 |
+
onBlockRemoved={[Function]}
|
| 17 |
+
organizers={Array []}
|
| 18 |
+
setAttributes={[MockFunction]}
|
| 19 |
+
setInitialState={
|
| 20 |
+
[MockFunction] {
|
| 21 |
+
"calls": Array [
|
| 22 |
+
Array [
|
| 23 |
+
Object {
|
| 24 |
+
"attributes": Object {
|
| 25 |
+
"description": "",
|
| 26 |
+
"organizers": Array [],
|
| 27 |
+
"title": "Modern Tribe",
|
| 28 |
+
},
|
| 29 |
+
"description": "The Next Generation of Digital Agency",
|
| 30 |
+
"get": [Function],
|
| 31 |
+
"isolated": false,
|
| 32 |
+
"name": "tribe/event",
|
| 33 |
+
"onBlockCreated": [Function],
|
| 34 |
+
"onBlockRemoved": [Function],
|
| 35 |
+
"organizers": Array [],
|
| 36 |
+
"setAttributes": [MockFunction],
|
| 37 |
+
"setInitialState": [MockFunction] {
|
| 38 |
+
"calls": [Circular],
|
| 39 |
+
"results": Array [
|
| 40 |
+
Object {
|
| 41 |
+
"isThrow": false,
|
| 42 |
+
"value": undefined,
|
| 43 |
+
},
|
| 44 |
+
],
|
| 45 |
+
},
|
| 46 |
+
"title": "Modern Tribe!",
|
| 47 |
+
},
|
| 48 |
+
],
|
| 49 |
+
],
|
| 50 |
+
"results": Array [
|
| 51 |
+
Object {
|
| 52 |
+
"isThrow": false,
|
| 53 |
+
"value": undefined,
|
| 54 |
+
},
|
| 55 |
+
],
|
| 56 |
+
}
|
| 57 |
+
}
|
| 58 |
+
title="Modern Tribe!"
|
| 59 |
+
>
|
| 60 |
+
With Save Data!
|
| 61 |
+
</div>
|
| 62 |
+
`;
|
common/src/modules/hoc/__tests__/__snapshots__/with-store.test.js.snap
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
| 2 |
+
|
| 3 |
+
exports[`HOC - With Store Should add the store property 1`] = `
|
| 4 |
+
<div
|
| 5 |
+
store={
|
| 6 |
+
Object {
|
| 7 |
+
"dispatch": [Function],
|
| 8 |
+
"getState": [Function],
|
| 9 |
+
"injectReducers": [Function],
|
| 10 |
+
"injectedReducers": Object {},
|
| 11 |
+
"replaceReducer": [Function],
|
| 12 |
+
"run": [Function],
|
| 13 |
+
"subscribe": [Function],
|
| 14 |
+
Symbol(observable): [Function],
|
| 15 |
+
}
|
| 16 |
+
}
|
| 17 |
+
/>
|
| 18 |
+
`;
|
common/src/modules/hoc/__tests__/with-form.test.js
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import renderer from 'react-test-renderer';
|
| 5 |
+
import React from 'react';
|
| 6 |
+
import configureStore from 'redux-mock-store';
|
| 7 |
+
import thunk from 'redux-thunk';
|
| 8 |
+
|
| 9 |
+
/**
|
| 10 |
+
* Internal dependencies
|
| 11 |
+
*/
|
| 12 |
+
import { withForm } from '@moderntribe/common/hoc';
|
| 13 |
+
|
| 14 |
+
const initialState = {
|
| 15 |
+
events: {
|
| 16 |
+
},
|
| 17 |
+
forms: {
|
| 18 |
+
byId: {},
|
| 19 |
+
},
|
| 20 |
+
};
|
| 21 |
+
// here it is possible to pass in any middleware if needed into //configureStore
|
| 22 |
+
const mockStore = configureStore( [ thunk ] );
|
| 23 |
+
const store = mockStore( initialState );
|
| 24 |
+
|
| 25 |
+
const Block = () => <div>With Form!</div>;
|
| 26 |
+
let setFormID;
|
| 27 |
+
let Wrapper;
|
| 28 |
+
let component;
|
| 29 |
+
let instance;
|
| 30 |
+
|
| 31 |
+
describe( 'HOC - With Form', () => {
|
| 32 |
+
beforeEach( () => {
|
| 33 |
+
setFormID = jest.fn( () => 'posts' );
|
| 34 |
+
Wrapper = withForm( setFormID )( Block );
|
| 35 |
+
component = renderer.create( <Wrapper store={ store } postType="post"/> );
|
| 36 |
+
instance = component.root;
|
| 37 |
+
} );
|
| 38 |
+
|
| 39 |
+
afterEach( () => {
|
| 40 |
+
mockStore( initialState );
|
| 41 |
+
store.clearActions();
|
| 42 |
+
setFormID.mockClear();
|
| 43 |
+
} );
|
| 44 |
+
|
| 45 |
+
it( 'Should render a component', () => {
|
| 46 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 47 |
+
} );
|
| 48 |
+
|
| 49 |
+
it( 'Should render the inner component', () => {
|
| 50 |
+
expect( instance ).not.toBe( null );
|
| 51 |
+
expect( () => instance.findByType( Block ) ).not.toThrowError();
|
| 52 |
+
} );
|
| 53 |
+
|
| 54 |
+
it( 'Should attach the form properties', () => {
|
| 55 |
+
const expected = {
|
| 56 |
+
edit: false,
|
| 57 |
+
create: false,
|
| 58 |
+
fields: {},
|
| 59 |
+
submit: false,
|
| 60 |
+
};
|
| 61 |
+
expect( instance.findByType( Block ).props ).toMatchObject( expected );
|
| 62 |
+
} );
|
| 63 |
+
|
| 64 |
+
it( 'Should have properties as functions', () => {
|
| 65 |
+
const props = instance.findByType( Block ).props;
|
| 66 |
+
const expectedProps = [
|
| 67 |
+
'maybeRemoveEntry',
|
| 68 |
+
'setSubmit',
|
| 69 |
+
'sendForm',
|
| 70 |
+
'editEntry',
|
| 71 |
+
'createDraft',
|
| 72 |
+
];
|
| 73 |
+
|
| 74 |
+
expectedProps.forEach( ( property ) => {
|
| 75 |
+
expect( props[ property ] ).not.toBeUndefined();
|
| 76 |
+
expect( typeof props[ property ] ).toBe( 'function' );
|
| 77 |
+
} );
|
| 78 |
+
} );
|
| 79 |
+
|
| 80 |
+
it( 'Should register the postType by dispatching the actions', () => {
|
| 81 |
+
expect( store.getActions() ).toMatchSnapshot();
|
| 82 |
+
} );
|
| 83 |
+
|
| 84 |
+
it( 'Should register the ID of the form', () => {
|
| 85 |
+
expect( setFormID ).toHaveBeenCalled();
|
| 86 |
+
expect( setFormID ).toHaveBeenCalledTimes( 3 );
|
| 87 |
+
} );
|
| 88 |
+
} );
|
| 89 |
+
|
common/src/modules/hoc/__tests__/with-save-data.test.js
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import renderer from 'react-test-renderer';
|
| 5 |
+
import React from 'react';
|
| 6 |
+
|
| 7 |
+
/**
|
| 8 |
+
* Internal dependencies
|
| 9 |
+
*/
|
| 10 |
+
import { withSaveData } from '@moderntribe/common/hoc';
|
| 11 |
+
|
| 12 |
+
const Block = ( props ) => <div { ...props }>With Save Data!</div>;
|
| 13 |
+
const props = {
|
| 14 |
+
name: 'tribe/event',
|
| 15 |
+
setInitialState: jest.fn(),
|
| 16 |
+
setAttributes: jest.fn(),
|
| 17 |
+
title: 'Modern Tribe!',
|
| 18 |
+
description: 'The Next Generation of Digital Agency',
|
| 19 |
+
organizers: [],
|
| 20 |
+
attributes: {
|
| 21 |
+
title: 'Modern Tribe',
|
| 22 |
+
description: '',
|
| 23 |
+
organizers: [],
|
| 24 |
+
},
|
| 25 |
+
};
|
| 26 |
+
|
| 27 |
+
describe( 'HOC - With Details', () => {
|
| 28 |
+
let Wrapper;
|
| 29 |
+
let component;
|
| 30 |
+
let instance;
|
| 31 |
+
|
| 32 |
+
beforeEach( () => {
|
| 33 |
+
Wrapper = withSaveData()( Block );
|
| 34 |
+
component = renderer.create( <Wrapper { ...props } /> );
|
| 35 |
+
instance = component.root;
|
| 36 |
+
} );
|
| 37 |
+
|
| 38 |
+
afterEach( () => {
|
| 39 |
+
props.setInitialState.mockClear();
|
| 40 |
+
props.setAttributes.mockClear();
|
| 41 |
+
component.getInstance().unregisterBlock();
|
| 42 |
+
} );
|
| 43 |
+
|
| 44 |
+
it( 'Should render a component', () => {
|
| 45 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 46 |
+
} );
|
| 47 |
+
|
| 48 |
+
it( 'Should render the inner component', () => {
|
| 49 |
+
expect( instance ).not.toBe( null );
|
| 50 |
+
expect( () => instance.findByType( Block ) ).not.toThrowError();
|
| 51 |
+
} );
|
| 52 |
+
|
| 53 |
+
it( 'Should set the initial state', () => {
|
| 54 |
+
expect( props.setInitialState ).toHaveBeenCalled();
|
| 55 |
+
expect( props.setInitialState ).toHaveBeenCalledTimes( 1 );
|
| 56 |
+
} );
|
| 57 |
+
|
| 58 |
+
it( 'Should generate the attributes', () => {
|
| 59 |
+
const HOC = component.getInstance();
|
| 60 |
+
expect( HOC.attrs ).toEqual( props.attributes );
|
| 61 |
+
} );
|
| 62 |
+
|
| 63 |
+
it( 'Should generate the keys', () => {
|
| 64 |
+
const HOC = component.getInstance();
|
| 65 |
+
expect( HOC.keys ).toEqual( Object.keys( props.attributes ) );
|
| 66 |
+
} );
|
| 67 |
+
|
| 68 |
+
it( 'Simulate componentDidUpdate call', () => {
|
| 69 |
+
const wrapper = shallow( <Wrapper { ...props } /> );
|
| 70 |
+
const wrapperInstance = wrapper.instance();
|
| 71 |
+
expect( wrapperInstance.calculateDiff() ).toEqual( {
|
| 72 |
+
description: 'The Next Generation of Digital Agency',
|
| 73 |
+
title: 'Modern Tribe!',
|
| 74 |
+
} );
|
| 75 |
+
wrapper.setProps( {
|
| 76 |
+
attributes: {
|
| 77 |
+
title: 'Modern Tribe!',
|
| 78 |
+
description: 'The Next Generation of Digital Agency',
|
| 79 |
+
organizers: [],
|
| 80 |
+
}
|
| 81 |
+
} );
|
| 82 |
+
expect( wrapperInstance.calculateDiff() ).toEqual( {} );
|
| 83 |
+
wrapper.setProps( {
|
| 84 |
+
organizers: [ 3 ],
|
| 85 |
+
attributes: {
|
| 86 |
+
title: 'Modern Tribe!',
|
| 87 |
+
description: 'The Next Generation of Digital Agency',
|
| 88 |
+
organizers: [ 3 ],
|
| 89 |
+
},
|
| 90 |
+
} );
|
| 91 |
+
expect( wrapperInstance.calculateDiff() ).toEqual( {} );
|
| 92 |
+
wrapper.setProps( {
|
| 93 |
+
organizers: [ 2, 3 ],
|
| 94 |
+
attributes: {
|
| 95 |
+
title: 'Modern Tribe!',
|
| 96 |
+
description: 'The Next Generation of Digital Agency',
|
| 97 |
+
organizers: [ 3, 2 ],
|
| 98 |
+
},
|
| 99 |
+
} );
|
| 100 |
+
expect( wrapperInstance.calculateDiff() ).toEqual( { organizers: [ 2, 3 ] } );
|
| 101 |
+
wrapperInstance.unregisterBlock();
|
| 102 |
+
} );
|
| 103 |
+
|
| 104 |
+
it( 'Should calculate the diff', () => {
|
| 105 |
+
const HOC = component.getInstance();
|
| 106 |
+
const expected = {
|
| 107 |
+
title: props.title,
|
| 108 |
+
description: props.description,
|
| 109 |
+
};
|
| 110 |
+
expect( HOC.calculateDiff() ).toEqual( expected );
|
| 111 |
+
} );
|
| 112 |
+
|
| 113 |
+
it( 'Should count a single block', () => {
|
| 114 |
+
const HOC = component.getInstance();
|
| 115 |
+
expect( HOC.blockCount() ).toBe( 1 );
|
| 116 |
+
} );
|
| 117 |
+
} );
|
| 118 |
+
|
| 119 |
+
describe( 'HOC - With Details on multiple instances', () => {
|
| 120 |
+
afterEach( () => {
|
| 121 |
+
props.setInitialState.mockClear();
|
| 122 |
+
props.setAttributes.mockClear();
|
| 123 |
+
} );
|
| 124 |
+
|
| 125 |
+
it( 'Should register the initial state just once', () => {
|
| 126 |
+
const WrapperComponent = withSaveData()( Block );
|
| 127 |
+
|
| 128 |
+
renderer.create( <WrapperComponent { ...props } /> );
|
| 129 |
+
renderer.create( <WrapperComponent { ...props } /> );
|
| 130 |
+
renderer.create( <WrapperComponent { ...props } /> );
|
| 131 |
+
|
| 132 |
+
expect( props.setInitialState ).toHaveBeenCalled();
|
| 133 |
+
expect( props.setInitialState ).toHaveBeenCalledTimes( 1 );
|
| 134 |
+
} );
|
| 135 |
+
|
| 136 |
+
it( 'Should register the state multiple times on non isolated instances', () => {
|
| 137 |
+
const WrapperComponent = withSaveData()( Block );
|
| 138 |
+
props.isolated = true;
|
| 139 |
+
renderer.create( <WrapperComponent { ...props } /> );
|
| 140 |
+
renderer.create( <WrapperComponent { ...props } /> );
|
| 141 |
+
renderer.create( <WrapperComponent { ...props } /> );
|
| 142 |
+
|
| 143 |
+
expect( props.setInitialState ).toHaveBeenCalled();
|
| 144 |
+
expect( props.setInitialState ).toHaveBeenCalledTimes( 3 );
|
| 145 |
+
} );
|
| 146 |
+
} );
|
| 147 |
+
|
| 148 |
+
describe( 'HOC - test life cycle callbacks', () => {
|
| 149 |
+
let Wrapper;
|
| 150 |
+
let component;
|
| 151 |
+
let instance;
|
| 152 |
+
let properties = {};
|
| 153 |
+
|
| 154 |
+
beforeAll( () => {
|
| 155 |
+
props.onBlockCreated = jest.fn();
|
| 156 |
+
props.onBlockRemoved = jest.fn();
|
| 157 |
+
});
|
| 158 |
+
|
| 159 |
+
beforeEach( () => {
|
| 160 |
+
Wrapper = withSaveData()( Block );
|
| 161 |
+
component = renderer.create( <Wrapper { ...props } /> );
|
| 162 |
+
instance = component.root;
|
| 163 |
+
properties = instance.props;
|
| 164 |
+
} );
|
| 165 |
+
|
| 166 |
+
afterEach( () => {
|
| 167 |
+
props.setInitialState.mockClear();
|
| 168 |
+
props.setAttributes.mockClear();
|
| 169 |
+
props.onBlockCreated.mockClear();
|
| 170 |
+
props.onBlockRemoved.mockClear();
|
| 171 |
+
} );
|
| 172 |
+
|
| 173 |
+
afterAll( () => {
|
| 174 |
+
delete props.onBlockCreated;
|
| 175 |
+
delete props.onBlockRemoved;
|
| 176 |
+
} );
|
| 177 |
+
|
| 178 |
+
it( 'Should call the onBlockCreated callback on mount', () => {
|
| 179 |
+
expect( props.onBlockCreated ).toHaveBeenCalled();
|
| 180 |
+
expect( props.onBlockCreated ).toHaveBeenCalledWith( properties );
|
| 181 |
+
expect( props.onBlockRemoved ).not.toHaveBeenCalled();
|
| 182 |
+
} );
|
| 183 |
+
|
| 184 |
+
it( 'Should call the onBlockRemoved callback on unmount of the block', () => {
|
| 185 |
+
component.unmount();
|
| 186 |
+
expect( props.onBlockCreated ).toHaveBeenCalled();
|
| 187 |
+
expect( props.onBlockCreated ).toHaveBeenCalledWith( properties );
|
| 188 |
+
expect( props.onBlockRemoved ).toHaveBeenCalled();
|
| 189 |
+
expect( props.onBlockRemoved ).toHaveBeenCalledWith( properties );
|
| 190 |
+
} );
|
| 191 |
+
} );
|
common/src/modules/hoc/__tests__/with-selected.test.js
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import React from 'react';
|
| 5 |
+
|
| 6 |
+
/**
|
| 7 |
+
* Internal dependencies
|
| 8 |
+
*/
|
| 9 |
+
import { withSelected } from '@moderntribe/common/hoc';
|
| 10 |
+
|
| 11 |
+
const Block = () => ( <div>With Selected!</div> );
|
| 12 |
+
|
| 13 |
+
describe( 'withSelected', () => {
|
| 14 |
+
let HOC;
|
| 15 |
+
const onFocus = jest.fn();
|
| 16 |
+
const onBlur = jest.fn();
|
| 17 |
+
const props = {
|
| 18 |
+
onBlockFocus: onFocus,
|
| 19 |
+
onBlockBlur: onBlur,
|
| 20 |
+
};
|
| 21 |
+
|
| 22 |
+
beforeEach( () => {
|
| 23 |
+
HOC = withSelected()( Block );
|
| 24 |
+
} );
|
| 25 |
+
|
| 26 |
+
afterEach( () => {
|
| 27 |
+
props.onBlockFocus.mockClear();
|
| 28 |
+
props.onBlockBlur.mockClear();
|
| 29 |
+
} );
|
| 30 |
+
|
| 31 |
+
test( 'onBlur called when is not selected on mount', () => {
|
| 32 |
+
props.isSelected = false;
|
| 33 |
+
const component = mount( <HOC { ...props } /> );
|
| 34 |
+
expect( props.onBlockBlur ).toHaveBeenCalled();
|
| 35 |
+
expect( props.onBlockFocus ).not.toHaveBeenCalled();
|
| 36 |
+
} );
|
| 37 |
+
|
| 38 |
+
test( 'onFocus called when is selected on mount', () => {
|
| 39 |
+
props.isSelected = true;
|
| 40 |
+
const component = mount( <HOC { ...props } /> );
|
| 41 |
+
expect( props.onBlockFocus ).toHaveBeenCalled();
|
| 42 |
+
expect( props.onBlockBlur ).not.toHaveBeenCalled();
|
| 43 |
+
} );
|
| 44 |
+
|
| 45 |
+
test( 'trigger focus when isSelected changes after mounted', () => {
|
| 46 |
+
props.isSelected = false;
|
| 47 |
+
const component = mount( <HOC { ...props } /> );
|
| 48 |
+
expect( props.onBlockBlur ).toHaveBeenCalled();
|
| 49 |
+
expect( props.onBlockFocus ).not.toHaveBeenCalled();
|
| 50 |
+
|
| 51 |
+
props.onBlockBlur.mockClear();
|
| 52 |
+
props.onBlockFocus.mockClear();
|
| 53 |
+
|
| 54 |
+
component.setProps( { isSelected: true } );
|
| 55 |
+
|
| 56 |
+
expect( props.onBlockFocus ).toHaveBeenCalled();
|
| 57 |
+
expect( props.onBlockBlur ).not.toHaveBeenCalled();
|
| 58 |
+
} );
|
| 59 |
+
|
| 60 |
+
test( 'trigger onBlur when isSelected changes after mounted', () => {
|
| 61 |
+
props.isSelected = true;
|
| 62 |
+
const component = mount( <HOC { ...props } /> );
|
| 63 |
+
expect( props.onBlockFocus ).toHaveBeenCalled();
|
| 64 |
+
expect( props.onBlockBlur ).not.toHaveBeenCalled();
|
| 65 |
+
|
| 66 |
+
props.onBlockBlur.mockClear();
|
| 67 |
+
props.onBlockFocus.mockClear();
|
| 68 |
+
|
| 69 |
+
component.setProps( { isSelected: false } );
|
| 70 |
+
|
| 71 |
+
expect( props.onBlockBlur ).toHaveBeenCalled();
|
| 72 |
+
expect( props.onBlockFocus ).not.toHaveBeenCalled();
|
| 73 |
+
} );
|
| 74 |
+
|
| 75 |
+
test( 'blue and focus on the different props changes', () => {
|
| 76 |
+
props.isSelected = false;
|
| 77 |
+
const component = mount( <HOC { ...props } /> );
|
| 78 |
+
expect( props.onBlockBlur ).toHaveBeenCalled();
|
| 79 |
+
expect( props.onBlockFocus ).not.toHaveBeenCalled();
|
| 80 |
+
|
| 81 |
+
props.onBlockBlur.mockClear();
|
| 82 |
+
props.onBlockFocus.mockClear();
|
| 83 |
+
|
| 84 |
+
component.setProps( { isSelected: true } );
|
| 85 |
+
|
| 86 |
+
expect( props.onBlockFocus ).toHaveBeenCalled();
|
| 87 |
+
expect( props.onBlockBlur ).not.toHaveBeenCalled();
|
| 88 |
+
|
| 89 |
+
props.onBlockBlur.mockClear();
|
| 90 |
+
props.onBlockFocus.mockClear();
|
| 91 |
+
|
| 92 |
+
component.setProps( { isSelected: false } );
|
| 93 |
+
|
| 94 |
+
expect( props.onBlockBlur ).toHaveBeenCalled();
|
| 95 |
+
expect( props.onBlockFocus ).not.toHaveBeenCalled();
|
| 96 |
+
} );
|
| 97 |
+
} );
|
common/src/modules/hoc/__tests__/with-store.test.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import renderer from 'react-test-renderer';
|
| 5 |
+
import React from 'react';
|
| 6 |
+
|
| 7 |
+
/**
|
| 8 |
+
* Internal dependencies
|
| 9 |
+
*/
|
| 10 |
+
import { withStore } from '@moderntribe/common/hoc';
|
| 11 |
+
|
| 12 |
+
describe( 'HOC - With Store', () => {
|
| 13 |
+
it( 'Should add the store property', () => {
|
| 14 |
+
const Block = ( props ) => <div { ...props } />;
|
| 15 |
+
const Wrapper = withStore()( Block );
|
| 16 |
+
const component = renderer.create( <Wrapper /> );
|
| 17 |
+
expect( component.toJSON() ).toMatchSnapshot();
|
| 18 |
+
|
| 19 |
+
const instance = component.root;
|
| 20 |
+
expect( instance ).not.toBe( null );
|
| 21 |
+
const props = instance.findByType( Block ).props;
|
| 22 |
+
expect( props ).toHaveProperty( 'store' );
|
| 23 |
+
const { store } = props;
|
| 24 |
+
expect( store ).toHaveProperty( 'dispatch' );
|
| 25 |
+
expect( store ).toHaveProperty( 'getState' );
|
| 26 |
+
} );
|
| 27 |
+
} );
|
| 28 |
+
|
common/src/modules/hoc/index.js
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
export { default as withStore } from './with-store';
|
| 2 |
+
export { default as withSaveData } from './with-save-data';
|
| 3 |
+
export { default as withForm } from './with-form';
|
| 4 |
+
export { default as withBlockCloser } from './with-block-closer';
|
| 5 |
+
export { default as withSelected } from './with-selected';
|
common/src/modules/hoc/with-block-closer.js
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* eslint-disable max-len */
|
| 2 |
+
/**
|
| 3 |
+
* External dependencies
|
| 4 |
+
*/
|
| 5 |
+
import React, { PureComponent } from 'react';
|
| 6 |
+
import PropTypes from 'prop-types';
|
| 7 |
+
import { noop } from 'lodash';
|
| 8 |
+
|
| 9 |
+
const ESCAPE_KEY = 27;
|
| 10 |
+
export const EVENT_NAMESPACE = 'tribe:click:proxy';
|
| 11 |
+
export const dispatch = ( e ) => {
|
| 12 |
+
e.target.dispatchEvent( new CustomEvent( EVENT_NAMESPACE, { bubbles: true } ) );
|
| 13 |
+
};
|
| 14 |
+
export const intercept = e => e.stopPropagation();
|
| 15 |
+
|
| 16 |
+
export default ( WrappedComponent ) => {
|
| 17 |
+
/**
|
| 18 |
+
* Prevents clicks on block or blacklisted DOM elements
|
| 19 |
+
* from closing the block
|
| 20 |
+
*
|
| 21 |
+
* @class WithBlockCloser
|
| 22 |
+
* @extends {PureComponent}
|
| 23 |
+
*/
|
| 24 |
+
class WithBlockCloser extends PureComponent {
|
| 25 |
+
static displayName = `WithBlockCloser( ${ WrappedComponent.displayName || WrappedComponent.name || 'Component ' }`
|
| 26 |
+
|
| 27 |
+
static propTypes = {
|
| 28 |
+
onClose: PropTypes.func.isRequired,
|
| 29 |
+
classNameClickBlacklist: PropTypes.arrayOf( PropTypes.string ).isRequired,
|
| 30 |
+
isOpen: PropTypes.bool.isRequired,
|
| 31 |
+
};
|
| 32 |
+
|
| 33 |
+
static defaultProps = {
|
| 34 |
+
classNameClickBlacklist: [ '.edit-post-sidebar' ],
|
| 35 |
+
onClose: noop,
|
| 36 |
+
isOpen: false,
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
+
nodeRef = React.createRef();
|
| 40 |
+
_eventNamespace = EVENT_NAMESPACE;
|
| 41 |
+
|
| 42 |
+
/**
|
| 43 |
+
* dispatches custom events
|
| 44 |
+
*
|
| 45 |
+
* @memberof WithBlockCloser
|
| 46 |
+
* @param {Event} e event
|
| 47 |
+
*/
|
| 48 |
+
_dispatchClickProxyEvent = dispatch;
|
| 49 |
+
|
| 50 |
+
// Prevent CustomEvents from propagating to document proxy listeners
|
| 51 |
+
_interceptClickProxyEvent = intercept;
|
| 52 |
+
|
| 53 |
+
/**
|
| 54 |
+
* keydown handler
|
| 55 |
+
*
|
| 56 |
+
* @memberof WithBlockCloser
|
| 57 |
+
* @param {Event} e event
|
| 58 |
+
*/
|
| 59 |
+
handleKeyDown = ( e ) => {
|
| 60 |
+
if ( e.keyCode === ESCAPE_KEY ) {
|
| 61 |
+
this.props.onClose();
|
| 62 |
+
}
|
| 63 |
+
}
|
| 64 |
+
|
| 65 |
+
handleClick = () => this.props.onClose()
|
| 66 |
+
|
| 67 |
+
componentDidMount() {
|
| 68 |
+
this.props.isOpen && this._addEventListeners();
|
| 69 |
+
}
|
| 70 |
+
|
| 71 |
+
componentDidUpdate( prevProps ) {
|
| 72 |
+
if ( prevProps.isOpen !== this.props.isOpen ) {
|
| 73 |
+
this.props.isOpen
|
| 74 |
+
? this._addEventListeners()
|
| 75 |
+
: this._removeEventListeners();
|
| 76 |
+
}
|
| 77 |
+
}
|
| 78 |
+
|
| 79 |
+
componentWillUnmount() {
|
| 80 |
+
this._removeEventListeners();
|
| 81 |
+
}
|
| 82 |
+
|
| 83 |
+
get blacklistedNodes() {
|
| 84 |
+
const classNames = this.props.classNameClickBlacklist.join( ', ' );
|
| 85 |
+
return Array.from( document.querySelectorAll( classNames ) );
|
| 86 |
+
}
|
| 87 |
+
|
| 88 |
+
get node() {
|
| 89 |
+
return this.nodeRef.current;
|
| 90 |
+
}
|
| 91 |
+
|
| 92 |
+
_addEventListeners() {
|
| 93 |
+
// Intercept custom events bubbled in block or blacklisted nodes
|
| 94 |
+
this.node.addEventListener( this._eventNamespace, this._interceptClickProxyEvent );
|
| 95 |
+
this.blacklistedNodes.forEach(
|
| 96 |
+
node => node.addEventListener( this._eventNamespace, this._interceptClickProxyEvent )
|
| 97 |
+
);
|
| 98 |
+
|
| 99 |
+
// Wait to receive custom events, if not intercepted, then go to click handler
|
| 100 |
+
document.addEventListener( this._eventNamespace, this.handleClick );
|
| 101 |
+
// Dispatch custom event on regular clicks
|
| 102 |
+
document.addEventListener( 'click', this._dispatchClickProxyEvent );
|
| 103 |
+
|
| 104 |
+
// Close on certain keypresses
|
| 105 |
+
document.addEventListener( 'keydown', this.handleKeyDown );
|
| 106 |
+
}
|
| 107 |
+
|
| 108 |
+
_removeEventListeners() {
|
| 109 |
+
this.node.removeEventListener( this._eventNamespace, this._interceptClickProxyEvent );
|
| 110 |
+
this.blacklistedNodes.forEach(
|
| 111 |
+
node => node.removeEventListener( this._eventNamespace, this._interceptClickProxyEvent )
|
| 112 |
+
);
|
| 113 |
+
|
| 114 |
+
document.removeEventListener( 'keydown', this.handleKeyDown );
|
| 115 |
+
document.removeEventListener( this._eventNamespace, this.handleClick );
|
| 116 |
+
document.removeEventListener( 'click', this._dispatchClickProxyEvent );
|
| 117 |
+
}
|
| 118 |
+
|
| 119 |
+
render() {
|
| 120 |
+
return (
|
| 121 |
+
<div ref={ this.nodeRef }>
|
| 122 |
+
<WrappedComponent { ...this.props } />
|
| 123 |
+
</div>
|
| 124 |
+
);
|
| 125 |
+
}
|
| 126 |
+
}
|
| 127 |
+
|
| 128 |
+
return WithBlockCloser;
|
| 129 |
+
};
|
common/src/modules/hoc/with-form.js
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import React, { Component } from 'react';
|
| 5 |
+
import PropTypes from 'prop-types';
|
| 6 |
+
import { bindActionCreators } from 'redux';
|
| 7 |
+
import { connect } from 'react-redux';
|
| 8 |
+
import { noop } from 'lodash';
|
| 9 |
+
|
| 10 |
+
/**
|
| 11 |
+
* Internal dependencies
|
| 12 |
+
*/
|
| 13 |
+
import { actions, selectors } from '@moderntribe/common/data/forms';
|
| 14 |
+
|
| 15 |
+
/**
|
| 16 |
+
* HOC that register a new object associated with set of fields for a form
|
| 17 |
+
*
|
| 18 |
+
* @param {function} getName Function used to set the name of the form, has a props param to generate the name
|
| 19 |
+
* @returns {function(*): *} Returns a function that takes a Component as argument and returns a component.
|
| 20 |
+
*/
|
| 21 |
+
export default ( getName = noop ) => ( WrappedComponent ) => {
|
| 22 |
+
class WithForm extends Component {
|
| 23 |
+
static propTypes = {
|
| 24 |
+
registerForm: PropTypes.func,
|
| 25 |
+
postType: PropTypes.string,
|
| 26 |
+
};
|
| 27 |
+
|
| 28 |
+
componentDidMount() {
|
| 29 |
+
const name = getName( this.props );
|
| 30 |
+
const { registerForm, postType } = this.props;
|
| 31 |
+
registerForm( name, postType );
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
render() {
|
| 35 |
+
return <WrappedComponent { ...this.props } { ...this.additionalProps() } />;
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
additionalProps() {
|
| 39 |
+
const {
|
| 40 |
+
createDraft,
|
| 41 |
+
sendForm,
|
| 42 |
+
setSubmit,
|
| 43 |
+
editEntry,
|
| 44 |
+
maybeRemoveEntry,
|
| 45 |
+
} = this.props;
|
| 46 |
+
const name = getName( this.props );
|
| 47 |
+
return {
|
| 48 |
+
createDraft: ( fieldsObject ) => createDraft( name, fieldsObject ),
|
| 49 |
+
editEntry: ( fieldsObject ) => editEntry( name, fieldsObject ),
|
| 50 |
+
sendForm: ( fieldsObject, callback ) => sendForm( name, fieldsObject, callback ),
|
| 51 |
+
setSubmit: () => setSubmit( name ),
|
| 52 |
+
maybeRemoveEntry: ( details ) => maybeRemoveEntry( name, details ),
|
| 53 |
+
};
|
| 54 |
+
}
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
const mapStateToProps = ( state, props ) => {
|
| 58 |
+
const name = getName( props );
|
| 59 |
+
const modifiedProps = { name };
|
| 60 |
+
return {
|
| 61 |
+
edit: selectors.getFormEdit( state, modifiedProps ),
|
| 62 |
+
create: selectors.getFormCreate( state, modifiedProps ),
|
| 63 |
+
fields: selectors.getFormFields( state, modifiedProps ),
|
| 64 |
+
submit: selectors.getFormSubmit( state, modifiedProps ),
|
| 65 |
+
};
|
| 66 |
+
};
|
| 67 |
+
|
| 68 |
+
const mapDispatchToProps = ( dispatch ) => bindActionCreators( actions, dispatch );
|
| 69 |
+
|
| 70 |
+
return connect( mapStateToProps, mapDispatchToProps )( WithForm );
|
| 71 |
+
};
|
{src/modules/blocks → common/src/modules}/hoc/with-save-data.js
RENAMED
|
@@ -1,9 +1,3 @@
|
|
| 1 |
-
/**
|
| 2 |
-
* @todo: This is just a holder for ET blocks until the block editor UX work.
|
| 3 |
-
* The `withSaveData()` HOC needs to be removed from common. Until the
|
| 4 |
-
* block editor UX work, this will live here.
|
| 5 |
-
*/
|
| 6 |
-
|
| 7 |
/**
|
| 8 |
* External dependencies
|
| 9 |
*/
|
|
@@ -158,3 +152,4 @@ export default ( selectedAttributes = null ) => ( WrappedComponent ) => {
|
|
| 158 |
|
| 159 |
return WithSaveData;
|
| 160 |
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
/**
|
| 2 |
* External dependencies
|
| 3 |
*/
|
| 152 |
|
| 153 |
return WithSaveData;
|
| 154 |
};
|
| 155 |
+
|
common/src/modules/hoc/with-selected.js
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import React, { Component } from 'react';
|
| 5 |
+
import PropTypes from 'prop-types';
|
| 6 |
+
import {
|
| 7 |
+
noop,
|
| 8 |
+
} from 'lodash';
|
| 9 |
+
|
| 10 |
+
/**
|
| 11 |
+
* Higher order component that executes two functions:
|
| 12 |
+
*
|
| 13 |
+
* - `onBlockFocus` when the block is selected
|
| 14 |
+
* - `onBlockBlur` when the block losses focus after being selected
|
| 15 |
+
*
|
| 16 |
+
* @returns {function} Return a new HOC
|
| 17 |
+
*/
|
| 18 |
+
export default () => ( WrappedComponent ) => {
|
| 19 |
+
class WithSelected extends Component {
|
| 20 |
+
static defaultProps = {
|
| 21 |
+
isSelected: false,
|
| 22 |
+
onBlockFocus: noop,
|
| 23 |
+
onBlockBlur: noop,
|
| 24 |
+
};
|
| 25 |
+
|
| 26 |
+
static propTypes = {
|
| 27 |
+
onBlockFocus: PropTypes.func,
|
| 28 |
+
onBlockBlur: PropTypes.func,
|
| 29 |
+
isSelected: PropTypes.bool,
|
| 30 |
+
};
|
| 31 |
+
|
| 32 |
+
componentDidMount() {
|
| 33 |
+
const { isSelected, onBlockFocus, onBlockBlur } = this.props;
|
| 34 |
+
if ( isSelected ) {
|
| 35 |
+
onBlockFocus();
|
| 36 |
+
} else {
|
| 37 |
+
onBlockBlur();
|
| 38 |
+
}
|
| 39 |
+
}
|
| 40 |
+
|
| 41 |
+
componentDidUpdate( prevProps ) {
|
| 42 |
+
const { isSelected, onBlockFocus, onBlockBlur } = this.props;
|
| 43 |
+
|
| 44 |
+
if ( prevProps.isSelected === isSelected ) {
|
| 45 |
+
return;
|
| 46 |
+
}
|
| 47 |
+
|
| 48 |
+
if ( isSelected ) {
|
| 49 |
+
onBlockFocus();
|
| 50 |
+
} else {
|
| 51 |
+
onBlockBlur();
|
| 52 |
+
}
|
| 53 |
+
}
|
| 54 |
+
|
| 55 |
+
render() {
|
| 56 |
+
return <WrappedComponent { ...this.props } />;
|
| 57 |
+
}
|
| 58 |
+
}
|
| 59 |
+
|
| 60 |
+
WithSelected.displayName = `WithIsSelected( ${ WrappedComponent.displayName || WrappedComponent.name || 'Component ' }`;
|
| 61 |
+
|
| 62 |
+
return WithSelected;
|
| 63 |
+
};
|
| 64 |
+
|
common/src/modules/hoc/with-store.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import React from 'react';
|
| 5 |
+
|
| 6 |
+
/**
|
| 7 |
+
* Internal dependencies
|
| 8 |
+
*/
|
| 9 |
+
import { store } from '@moderntribe/common/store';
|
| 10 |
+
|
| 11 |
+
const getStore = () => store;
|
| 12 |
+
|
| 13 |
+
export default ( additionalProps = {} ) => ( WrappedComponent ) => {
|
| 14 |
+
|
| 15 |
+
const WithStore = ( props ) => {
|
| 16 |
+
const extraProps = {
|
| 17 |
+
...additionalProps,
|
| 18 |
+
store: getStore(),
|
| 19 |
+
};
|
| 20 |
+
|
| 21 |
+
return <WrappedComponent { ...props } { ...extraProps } />;
|
| 22 |
+
};
|
| 23 |
+
|
| 24 |
+
return WithStore;
|
| 25 |
+
|
| 26 |
+
};
|
common/src/modules/package.json
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"name": "@moderntribe/common",
|
| 3 |
+
"version": "0.3.2-alpha",
|
| 4 |
+
"description": "Common Blocks Editor modules",
|
| 5 |
+
"main": "src/resources/main.js",
|
| 6 |
+
"scripts": {},
|
| 7 |
+
"keywords": [
|
| 8 |
+
"gutenberg",
|
| 9 |
+
"common"
|
| 10 |
+
],
|
| 11 |
+
"private": true,
|
| 12 |
+
"repository": "git+https://github.com/moderntribe/tribe-common.git",
|
| 13 |
+
"author": "Modern Tribe",
|
| 14 |
+
"license": "GPL-2.0-or-later",
|
| 15 |
+
"dependencies": {
|
| 16 |
+
}
|
| 17 |
+
}
|
common/src/modules/store/configure-store.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import { createStore, applyMiddleware } from 'redux';
|
| 5 |
+
import { composeWithDevTools } from 'redux-devtools-extension/developmentOnly';
|
| 6 |
+
import { augmentStore } from '@nfen/redux-reducer-injector';
|
| 7 |
+
import thunk from 'redux-thunk';
|
| 8 |
+
import createSagaMiddleware from 'redux-saga';
|
| 9 |
+
|
| 10 |
+
/**
|
| 11 |
+
* Internal dependencies
|
| 12 |
+
*/
|
| 13 |
+
import reducer from '@moderntribe/common/data';
|
| 14 |
+
import { wpRequest } from './middlewares';
|
| 15 |
+
|
| 16 |
+
const sagaMiddleware = createSagaMiddleware();
|
| 17 |
+
|
| 18 |
+
export default () => {
|
| 19 |
+
if ( window.__tribe_common_store__ ) {
|
| 20 |
+
return window.__tribe_common_store__;
|
| 21 |
+
}
|
| 22 |
+
|
| 23 |
+
const middlewares = [
|
| 24 |
+
thunk,
|
| 25 |
+
sagaMiddleware,
|
| 26 |
+
wpRequest,
|
| 27 |
+
];
|
| 28 |
+
|
| 29 |
+
const composeEnhancers = composeWithDevTools( { name: 'tribe/common' } );
|
| 30 |
+
|
| 31 |
+
const store = createStore( reducer( {} ), composeEnhancers( applyMiddleware( ...middlewares ) ) );
|
| 32 |
+
augmentStore( reducer, store );
|
| 33 |
+
store.run = sagaMiddleware.run;
|
| 34 |
+
window.__tribe_common_store__ = store;
|
| 35 |
+
|
| 36 |
+
return store;
|
| 37 |
+
};
|
common/src/modules/store/index.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import 'regenerator-runtime/runtime';
|
| 5 |
+
|
| 6 |
+
/**
|
| 7 |
+
* Internal dependencies
|
| 8 |
+
*/
|
| 9 |
+
import configureStore from './configure-store';
|
| 10 |
+
import * as middlewares from './middlewares';
|
| 11 |
+
|
| 12 |
+
export const store = configureStore();
|
| 13 |
+
export { middlewares };
|
common/src/modules/store/middlewares/index.js
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
| 1 |
+
export { default as wpRequest } from './request';
|
| 2 |
+
import * as request from './request';
|
| 3 |
+
export { request };
|
common/src/modules/store/middlewares/request/__tests__/__snapshots__/actions.test.js.snap
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
| 2 |
+
|
| 3 |
+
exports[`[STORE] - Request actions WP Request action 1`] = `
|
| 4 |
+
Object {
|
| 5 |
+
"meta": Object {
|
| 6 |
+
"actions": Object {},
|
| 7 |
+
"path": "tribe_organizer/1225",
|
| 8 |
+
},
|
| 9 |
+
"type": "@@MT/COMMON/WP_REQUEST",
|
| 10 |
+
}
|
| 11 |
+
`;
|
common/src/modules/store/middlewares/request/__tests__/actions.test.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* Internal dependencies
|
| 3 |
+
*/
|
| 4 |
+
import { actions } from '@moderntribe/common/store/middlewares/request';
|
| 5 |
+
|
| 6 |
+
describe( '[STORE] - Request actions', () => {
|
| 7 |
+
test( 'WP Request action', () => {
|
| 8 |
+
const meta = {
|
| 9 |
+
path: 'tribe_organizer/1225',
|
| 10 |
+
actions: {},
|
| 11 |
+
};
|
| 12 |
+
expect( actions.wpRequest( meta ) ).toMatchSnapshot();
|
| 13 |
+
} );
|
| 14 |
+
} );
|
common/src/modules/store/middlewares/request/__tests__/types.test.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* Internal dependencies
|
| 3 |
+
*/
|
| 4 |
+
import { PREFIX_COMMON_STORE } from '@moderntribe/common/data/utils';
|
| 5 |
+
import { types } from '@moderntribe/common/store/middlewares/request';
|
| 6 |
+
|
| 7 |
+
describe( '[STORE] - Request types', () => {
|
| 8 |
+
it( 'Should return the types values', () => {
|
| 9 |
+
expect( types.WP_REQUEST ).toBe( `${ PREFIX_COMMON_STORE }/WP_REQUEST` );
|
| 10 |
+
} );
|
| 11 |
+
} );
|
common/src/modules/store/middlewares/request/__tests__/utils.test.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* Internal dependencies
|
| 3 |
+
*/
|
| 4 |
+
import { utils } from '@moderntribe/common/store/middlewares/request';
|
| 5 |
+
|
| 6 |
+
const wpParamsExpected = {
|
| 7 |
+
orderby: 'title',
|
| 8 |
+
status: [ 'draft', 'publish' ],
|
| 9 |
+
order: 'asc',
|
| 10 |
+
page: 1,
|
| 11 |
+
};
|
| 12 |
+
|
| 13 |
+
describe( 'Request utils', () => {
|
| 14 |
+
it( 'Should generate the WP params', () => {
|
| 15 |
+
expect( utils.toWpParams( {} ) ).toEqual( wpParamsExpected );
|
| 16 |
+
} );
|
| 17 |
+
|
| 18 |
+
it( 'Should order by relevance if has search', () => {
|
| 19 |
+
expect( utils.toWpParams( { search: 'tribe' } ) )
|
| 20 |
+
.toEqual( {
|
| 21 |
+
...wpParamsExpected,
|
| 22 |
+
search: 'tribe',
|
| 23 |
+
orderby: 'relevance',
|
| 24 |
+
} );
|
| 25 |
+
} );
|
| 26 |
+
|
| 27 |
+
it( 'Should update the exclude parameter', () => {
|
| 28 |
+
expect( utils.toWpParams( { exclude: [] } ) ).toEqual( wpParamsExpected );
|
| 29 |
+
expect( utils.toWpParams( { exclude: [ 1, 2 ] } ) )
|
| 30 |
+
.toEqual( {
|
| 31 |
+
...wpParamsExpected,
|
| 32 |
+
exclude: [ 1, 2 ],
|
| 33 |
+
} );
|
| 34 |
+
} );
|
| 35 |
+
|
| 36 |
+
it( 'Should generate a WP Query', () => {
|
| 37 |
+
expect( utils.toWPQuery() ).toBe( 'orderby=title&status=draft%2Cpublish&order=asc&page=1' );
|
| 38 |
+
expect( utils.toWPQuery( { search: 'Modern Tribe' } ) )
|
| 39 |
+
.toBe( 'orderby=relevance&status=draft%2Cpublish&order=asc&page=1&search=Modern%20Tribe' );
|
| 40 |
+
} );
|
| 41 |
+
|
| 42 |
+
it( 'Should return the total of pages', () => {
|
| 43 |
+
const headers = new Headers();
|
| 44 |
+
headers.append( 'x-wp-totalpages', 5 );
|
| 45 |
+
expect( headers.get( 'x-wp-totalpages' ) ).toBe( '5' );
|
| 46 |
+
expect( utils.getTotalPages( headers ) ).toBe( 5 );
|
| 47 |
+
|
| 48 |
+
headers.set( 'x-wp-totalpages', '5' );
|
| 49 |
+
expect( headers.get( 'x-wp-totalpages' ) ).toBe( '5' );
|
| 50 |
+
expect( utils.getTotalPages( headers ) ).toBe( 5 );
|
| 51 |
+
|
| 52 |
+
headers.set( 'x-wp-totalpages', '5.3' );
|
| 53 |
+
expect( headers.get( 'x-wp-totalpages' ) ).toBe( '5.3' );
|
| 54 |
+
expect( utils.getTotalPages( headers ) ).toBe( 5 );
|
| 55 |
+
|
| 56 |
+
headers.delete( 'x-wp-totalpages' );
|
| 57 |
+
headers.set( 'x-wp', 5 );
|
| 58 |
+
expect( utils.getTotalPages( headers ) ).toBe( 0 );
|
| 59 |
+
expect( utils.getTotalPages( new Headers() ) ).toBe( 0 );
|
| 60 |
+
} );
|
| 61 |
+
} );
|
common/src/modules/store/middlewares/request/__tests__/wp-request.test.js
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* Internal dependencies
|
| 3 |
+
*/
|
| 4 |
+
import wpRequest, { actions } from '@moderntribe/common/store/middlewares/request';
|
| 5 |
+
|
| 6 |
+
let create;
|
| 7 |
+
const nextMock = jest.fn();
|
| 8 |
+
const meta = {
|
| 9 |
+
path: '',
|
| 10 |
+
params: {},
|
| 11 |
+
actions: {
|
| 12 |
+
none: jest.fn(),
|
| 13 |
+
start: jest.fn(),
|
| 14 |
+
success: jest.fn(),
|
| 15 |
+
error: jest.fn(),
|
| 16 |
+
},
|
| 17 |
+
};
|
| 18 |
+
|
| 19 |
+
describe( '[STORE] - wp-request middleware', () => {
|
| 20 |
+
let _fetch;
|
| 21 |
+
beforeAll( () => {
|
| 22 |
+
create = () => {
|
| 23 |
+
const invoke = ( action ) => wpRequest()( nextMock )( action );
|
| 24 |
+
return { next: nextMock, invoke };
|
| 25 |
+
};
|
| 26 |
+
_fetch = global.fetch;
|
| 27 |
+
} );
|
| 28 |
+
|
| 29 |
+
afterEach( () => {
|
| 30 |
+
global.fetch = _fetch;
|
| 31 |
+
} );
|
| 32 |
+
|
| 33 |
+
afterEach( () => {
|
| 34 |
+
nextMock.mockClear();
|
| 35 |
+
meta.actions.start.mockClear();
|
| 36 |
+
meta.actions.error.mockClear();
|
| 37 |
+
meta.actions.none.mockClear();
|
| 38 |
+
meta.actions.success.mockClear();
|
| 39 |
+
window.wp.apiRequest = undefined;
|
| 40 |
+
} );
|
| 41 |
+
|
| 42 |
+
it( 'Should move through a unknown action', () => {
|
| 43 |
+
const { next, invoke } = create();
|
| 44 |
+
const action = { type: 'UNKNOWN' };
|
| 45 |
+
invoke( action );
|
| 46 |
+
|
| 47 |
+
expect( next ).toHaveBeenCalled();
|
| 48 |
+
expect( next ).toHaveBeenCalledTimes( 1 );
|
| 49 |
+
expect( next ).toHaveBeenCalledWith( action );
|
| 50 |
+
} );
|
| 51 |
+
|
| 52 |
+
it( 'Should execute the none action if the path is empty', () => {
|
| 53 |
+
const { next, invoke } = create();
|
| 54 |
+
const action = actions.wpRequest( meta );
|
| 55 |
+
invoke( action );
|
| 56 |
+
|
| 57 |
+
expect( next ).toHaveBeenCalled();
|
| 58 |
+
expect( next ).toHaveBeenCalledTimes( 1 );
|
| 59 |
+
expect( next ).toHaveBeenCalledWith( action );
|
| 60 |
+
expect( meta.actions.none ).toHaveBeenCalled();
|
| 61 |
+
expect( meta.actions.none ).toHaveBeenCalledTimes( 1 );
|
| 62 |
+
expect( meta.actions.none ).toHaveBeenLastCalledWith( meta.path );
|
| 63 |
+
expect( meta.actions.start ).not.toHaveBeenCalled();
|
| 64 |
+
expect( meta.actions.success ).not.toHaveBeenCalled();
|
| 65 |
+
expect( meta.actions.error ).not.toHaveBeenCalled();
|
| 66 |
+
} );
|
| 67 |
+
|
| 68 |
+
it( 'Should execute the correct actions on success', async () => {
|
| 69 |
+
const { invoke } = create();
|
| 70 |
+
|
| 71 |
+
const body = {
|
| 72 |
+
id: 1217,
|
| 73 |
+
date: '2018-05-26T23:07:05',
|
| 74 |
+
meta: {},
|
| 75 |
+
};
|
| 76 |
+
|
| 77 |
+
const headers = new Headers();
|
| 78 |
+
|
| 79 |
+
global.fetch = jest.fn().mockImplementation( () =>
|
| 80 |
+
Promise.resolve( {
|
| 81 |
+
ok: true,
|
| 82 |
+
status: 200,
|
| 83 |
+
json: () => body,
|
| 84 |
+
headers,
|
| 85 |
+
} ),
|
| 86 |
+
);
|
| 87 |
+
|
| 88 |
+
await invoke( actions.wpRequest( { ...meta, path: 'tribe_organizer/1217' } ) );
|
| 89 |
+
|
| 90 |
+
expect.assertions( 8 );
|
| 91 |
+
expect( meta.actions.none ).not.toHaveBeenCalled();
|
| 92 |
+
expect( meta.actions.error ).not.toHaveBeenCalled();
|
| 93 |
+
expect( meta.actions.start ).toHaveBeenCalledWith( 'wp/v2/tribe_organizer/1217', {} );
|
| 94 |
+
expect( meta.actions.start ).toHaveBeenCalled();
|
| 95 |
+
expect( meta.actions.start ).toHaveBeenCalledTimes( 1 );
|
| 96 |
+
expect( meta.actions.success ).toHaveBeenCalled();
|
| 97 |
+
expect( meta.actions.success )
|
| 98 |
+
.toHaveBeenCalledWith( { body, headers } );
|
| 99 |
+
expect( meta.actions.success ).toHaveBeenCalledTimes( 1 );
|
| 100 |
+
} );
|
| 101 |
+
|
| 102 |
+
it( 'execute success actions on 201 response code - creation code', async () => {
|
| 103 |
+
const { invoke } = create();
|
| 104 |
+
|
| 105 |
+
const body = {
|
| 106 |
+
id: 201,
|
| 107 |
+
date: '2018-05-26T23:07:05',
|
| 108 |
+
meta: {
|
| 109 |
+
title: 'Creating a post....'
|
| 110 |
+
},
|
| 111 |
+
};
|
| 112 |
+
|
| 113 |
+
const headers = new Headers();
|
| 114 |
+
|
| 115 |
+
global.fetch = jest.fn().mockImplementation( () =>
|
| 116 |
+
Promise.resolve( {
|
| 117 |
+
ok: true,
|
| 118 |
+
status: 201,
|
| 119 |
+
json: () => body,
|
| 120 |
+
headers,
|
| 121 |
+
} ),
|
| 122 |
+
);
|
| 123 |
+
|
| 124 |
+
await invoke( actions.wpRequest( { ...meta, path: 'tribe_organizer/1217' } ) );
|
| 125 |
+
|
| 126 |
+
expect.assertions( 8 );
|
| 127 |
+
expect( meta.actions.none ).not.toHaveBeenCalled();
|
| 128 |
+
expect( meta.actions.error ).not.toHaveBeenCalled();
|
| 129 |
+
expect( meta.actions.start ).toHaveBeenCalledWith( 'wp/v2/tribe_organizer/1217', {} );
|
| 130 |
+
expect( meta.actions.start ).toHaveBeenCalled();
|
| 131 |
+
expect( meta.actions.start ).toHaveBeenCalledTimes( 1 );
|
| 132 |
+
expect( meta.actions.success ).toHaveBeenCalled();
|
| 133 |
+
expect( meta.actions.success ).toHaveBeenCalledWith( { body, headers } );
|
| 134 |
+
expect( meta.actions.success ).toHaveBeenCalledTimes( 1 );
|
| 135 |
+
} );
|
| 136 |
+
|
| 137 |
+
it( 'Should reject on 404 status code', async () => {
|
| 138 |
+
const { invoke } = create();
|
| 139 |
+
|
| 140 |
+
global.fetch = jest.fn().mockImplementation( () => Promise.resolve( { status: 404 } ) );
|
| 141 |
+
|
| 142 |
+
const error = await invoke( actions.wpRequest( { ...meta, path: 'tribe_organizer/1217' } ) );
|
| 143 |
+
expect.assertions( 6 );
|
| 144 |
+
expect( meta.actions.none ).not.toHaveBeenCalled();
|
| 145 |
+
expect( meta.actions.success ).not.toHaveBeenCalled();
|
| 146 |
+
expect( meta.actions.start ).toHaveBeenCalled();
|
| 147 |
+
expect( meta.actions.start ).toHaveBeenCalledWith( 'wp/v2/tribe_organizer/1217', {} );
|
| 148 |
+
expect( meta.actions.error ).toHaveBeenCalled();
|
| 149 |
+
expect( meta.actions.error ).toHaveBeenCalledWith( error );
|
| 150 |
+
} );
|
| 151 |
+
|
| 152 |
+
it( 'Should execute the correct actions on failure', async () => {
|
| 153 |
+
const { invoke } = create();
|
| 154 |
+
|
| 155 |
+
global.fetch = jest.fn().mockImplementation( () => Promise.reject( 'Wrong path' ) );
|
| 156 |
+
|
| 157 |
+
const error = await invoke( actions.wpRequest( {
|
| 158 |
+
...meta,
|
| 159 |
+
path: 'tribe_organizer/1217//////',
|
| 160 |
+
} ) );
|
| 161 |
+
expect.assertions( 6 );
|
| 162 |
+
expect( meta.actions.none ).not.toHaveBeenCalled();
|
| 163 |
+
expect( meta.actions.success ).not.toHaveBeenCalled();
|
| 164 |
+
expect( meta.actions.start ).toHaveBeenCalled();
|
| 165 |
+
expect( meta.actions.start ).toHaveBeenCalledWith( 'wp/v2/tribe_organizer/1217//////', {} );
|
| 166 |
+
expect( meta.actions.error ).toHaveBeenCalled();
|
| 167 |
+
expect( meta.actions.error ).toHaveBeenCalledWith( error );
|
| 168 |
+
} );
|
| 169 |
+
} );
|
common/src/modules/store/middlewares/request/actions.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* Internal dependencies
|
| 3 |
+
*/
|
| 4 |
+
import * as types from './types';
|
| 5 |
+
|
| 6 |
+
export const wpRequest = ( meta ) => ( {
|
| 7 |
+
type: types.WP_REQUEST,
|
| 8 |
+
meta,
|
| 9 |
+
} );
|
common/src/modules/store/middlewares/request/index.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* Internal dependencies
|
| 3 |
+
*/
|
| 4 |
+
import * as types from './types';
|
| 5 |
+
import * as actions from './actions';
|
| 6 |
+
import * as utils from './utils';
|
| 7 |
+
|
| 8 |
+
export { default } from './wp-request';
|
| 9 |
+
export { types, actions, utils };
|
common/src/modules/store/middlewares/request/types.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* Internal dependencies
|
| 3 |
+
*/
|
| 4 |
+
import { PREFIX_COMMON_STORE } from '@moderntribe/common/data/utils';
|
| 5 |
+
|
| 6 |
+
export const WP_REQUEST = `${ PREFIX_COMMON_STORE }/WP_REQUEST`;
|
common/src/modules/store/middlewares/request/utils.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import { isEmpty, isUndefined } from 'lodash';
|
| 5 |
+
import { stringify } from 'querystringify';
|
| 6 |
+
|
| 7 |
+
export const toWpParams = ( args = {} ) => {
|
| 8 |
+
const params = {
|
| 9 |
+
orderby: 'title',
|
| 10 |
+
status: [ 'draft', 'publish' ],
|
| 11 |
+
order: 'asc',
|
| 12 |
+
page: 1,
|
| 13 |
+
...args,
|
| 14 |
+
};
|
| 15 |
+
|
| 16 |
+
if ( ! isUndefined( params.search ) && ! isEmpty( params.search ) ) {
|
| 17 |
+
params.orderby = 'relevance';
|
| 18 |
+
}
|
| 19 |
+
|
| 20 |
+
if ( isEmpty( params.exclude ) ) {
|
| 21 |
+
delete params.exclude;
|
| 22 |
+
}
|
| 23 |
+
|
| 24 |
+
return params;
|
| 25 |
+
};
|
| 26 |
+
|
| 27 |
+
export const toWPQuery = ( args = {} ) => stringify( toWpParams( args ) );
|
| 28 |
+
|
| 29 |
+
export const getTotalPages = ( headers ) => {
|
| 30 |
+
const totalPages = parseInt( headers.get( 'x-wp-totalpages' ), 10 );
|
| 31 |
+
return isNaN( totalPages ) ? 0 : totalPages;
|
| 32 |
+
};
|
common/src/modules/store/middlewares/request/wp-request.js
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import { noop, get, inRange } from 'lodash';
|
| 5 |
+
import 'whatwg-fetch';
|
| 6 |
+
|
| 7 |
+
/**
|
| 8 |
+
* Internal dependencies
|
| 9 |
+
*/
|
| 10 |
+
import { rest } from '@moderntribe/common/utils/globals';
|
| 11 |
+
import { types } from '@moderntribe/common/store/middlewares/request';
|
| 12 |
+
|
| 13 |
+
export default () => ( next ) => async ( action ) => {
|
| 14 |
+
if ( action.type !== types.WP_REQUEST ) {
|
| 15 |
+
return next( action );
|
| 16 |
+
}
|
| 17 |
+
|
| 18 |
+
const { meta = {} } = action;
|
| 19 |
+
|
| 20 |
+
const {
|
| 21 |
+
path = '',
|
| 22 |
+
params = {},
|
| 23 |
+
} = meta;
|
| 24 |
+
|
| 25 |
+
next( action );
|
| 26 |
+
|
| 27 |
+
const { url = '', nonce = {} } = rest();
|
| 28 |
+
const wpRESTNonce = nonce.wp_rest || '';
|
| 29 |
+
const namespaces = rest.namespaces || {};
|
| 30 |
+
const core = namespaces.core || 'wp/v2';
|
| 31 |
+
const BASE = `${ url }${ core }`;
|
| 32 |
+
|
| 33 |
+
const actions = {
|
| 34 |
+
start: noop,
|
| 35 |
+
success: noop,
|
| 36 |
+
error: noop,
|
| 37 |
+
none: noop,
|
| 38 |
+
...get( meta, 'actions', {} ),
|
| 39 |
+
};
|
| 40 |
+
|
| 41 |
+
if ( path === '' ) {
|
| 42 |
+
actions.none( path );
|
| 43 |
+
return;
|
| 44 |
+
}
|
| 45 |
+
|
| 46 |
+
const endpoint = `${ BASE }/${ path }`;
|
| 47 |
+
|
| 48 |
+
actions.start( endpoint, params );
|
| 49 |
+
|
| 50 |
+
const headers = {
|
| 51 |
+
'Accept': 'application/json',
|
| 52 |
+
'Content-Type': 'application/json',
|
| 53 |
+
...get( params, 'headers', {} ),
|
| 54 |
+
'X-WP-Nonce': wpRESTNonce,
|
| 55 |
+
};
|
| 56 |
+
|
| 57 |
+
try {
|
| 58 |
+
const response = await fetch( endpoint, {
|
| 59 |
+
...params,
|
| 60 |
+
credentials: 'include',
|
| 61 |
+
headers,
|
| 62 |
+
} );
|
| 63 |
+
|
| 64 |
+
const { status } = response;
|
| 65 |
+
// inRange includes 200 but excludes 300 from the range so it's from 200 up to 299
|
| 66 |
+
if ( ! inRange( status, 200, 300 ) ) {
|
| 67 |
+
throw response;
|
| 68 |
+
}
|
| 69 |
+
const body = await response.json();
|
| 70 |
+
actions.success( { body, headers: response.headers } );
|
| 71 |
+
return [ response, body ];
|
| 72 |
+
} catch ( error ) {
|
| 73 |
+
actions.error( error );
|
| 74 |
+
return error;
|
| 75 |
+
}
|
| 76 |
+
};
|
common/src/modules/utils/__tests__/__snapshots__/globals.test.js.snap
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
| 2 |
+
|
| 3 |
+
exports[`Tests for globals.js Should match the default value for the globals values 1`] = `
|
| 4 |
+
Object {
|
| 5 |
+
"common": Object {
|
| 6 |
+
"countries": Object {},
|
| 7 |
+
"rest": Object {
|
| 8 |
+
"namespaces": Object {
|
| 9 |
+
"core": "wp/v2",
|
| 10 |
+
},
|
| 11 |
+
"nonce": Object {
|
| 12 |
+
"add_ticket_nonce": "0878f40fb2",
|
| 13 |
+
"wp_rest": "cedcd6967b",
|
| 14 |
+
},
|
| 15 |
+
"url": "http://gutenberg.local/wp-json/",
|
| 16 |
+
},
|
| 17 |
+
"settings": Object {},
|
| 18 |
+
"usStates": Object {},
|
| 19 |
+
},
|
| 20 |
+
"tec": Object {
|
| 21 |
+
"googleMap": Object {},
|
| 22 |
+
},
|
| 23 |
+
"tickets": Object {
|
| 24 |
+
"default_currency": "$",
|
| 25 |
+
"default_provider": "Tribe__Tickets_Plus__Commerce__WooCommerce__Main",
|
| 26 |
+
"providers": Array [
|
| 27 |
+
Object {
|
| 28 |
+
"class": "Tribe__Tickets_Plus__Commerce__WooCommerce__Main",
|
| 29 |
+
"currency": "$",
|
| 30 |
+
"currency_position": "prefix",
|
| 31 |
+
"name": "WooCommerce",
|
| 32 |
+
},
|
| 33 |
+
],
|
| 34 |
+
},
|
| 35 |
+
}
|
| 36 |
+
`;
|
| 37 |
+
|
| 38 |
+
exports[`Tests for globals.js Should match the default value for the globals values 2`] = `
|
| 39 |
+
Object {
|
| 40 |
+
"common": Object {
|
| 41 |
+
"countries": Object {},
|
| 42 |
+
"rest": Object {
|
| 43 |
+
"namespaces": Object {
|
| 44 |
+
"core": "wp/v2",
|
| 45 |
+
},
|
| 46 |
+
"nonce": Object {
|
| 47 |
+
"add_ticket_nonce": "0878f40fb2",
|
| 48 |
+
"wp_rest": "cedcd6967b",
|
| 49 |
+
},
|
| 50 |
+
"url": "http://gutenberg.local/wp-json/",
|
| 51 |
+
},
|
| 52 |
+
"settings": Object {},
|
| 53 |
+
"usStates": Object {},
|
| 54 |
+
},
|
| 55 |
+
"tec": Object {
|
| 56 |
+
"googleMap": Object {},
|
| 57 |
+
},
|
| 58 |
+
"tickets": Object {
|
| 59 |
+
"default_currency": "$",
|
| 60 |
+
"default_provider": "Tribe__Tickets_Plus__Commerce__WooCommerce__Main",
|
| 61 |
+
"providers": Array [
|
| 62 |
+
Object {
|
| 63 |
+
"class": "Tribe__Tickets_Plus__Commerce__WooCommerce__Main",
|
| 64 |
+
"currency": "$",
|
| 65 |
+
"currency_position": "prefix",
|
| 66 |
+
"name": "WooCommerce",
|
| 67 |
+
},
|
| 68 |
+
],
|
| 69 |
+
},
|
| 70 |
+
}
|
| 71 |
+
`;
|
| 72 |
+
|
| 73 |
+
exports[`Tests for globals.js get default value 1`] = `Array []`;
|
| 74 |
+
|
| 75 |
+
exports[`Tests for globals.js rest value 1`] = `
|
| 76 |
+
Object {
|
| 77 |
+
"namespaces": Object {
|
| 78 |
+
"core": "wp/v2",
|
| 79 |
+
},
|
| 80 |
+
"nonce": Object {
|
| 81 |
+
"add_ticket_nonce": "0878f40fb2",
|
| 82 |
+
"wp_rest": "cedcd6967b",
|
| 83 |
+
},
|
| 84 |
+
"url": "http://gutenberg.local/wp-json/",
|
| 85 |
+
}
|
| 86 |
+
`;
|
| 87 |
+
|
| 88 |
+
exports[`Tests for globals.js rest value 2`] = `
|
| 89 |
+
Object {
|
| 90 |
+
"add_ticket_nonce": "0878f40fb2",
|
| 91 |
+
"wp_rest": "cedcd6967b",
|
| 92 |
+
}
|
| 93 |
+
`;
|
common/src/modules/utils/__tests__/__snapshots__/time.test.js.snap
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
| 2 |
+
|
| 3 |
+
exports[`Tests for time.js fromMilliseconds() test 1`] = `"Argument \`ms\` provided to \`fromMilliseconds\` is not a number or is NaN."`;
|
| 4 |
+
|
| 5 |
+
exports[`Tests for time.js fromMilliseconds() test 2`] = `"Argument \`ms\` provided to \`fromMilliseconds\` is not a number or is NaN."`;
|
| 6 |
+
|
| 7 |
+
exports[`Tests for time.js fromMilliseconds() test 3`] = `"Argument \`format\` provided to \`formatTime\` is not a recognized format."`;
|
| 8 |
+
|
| 9 |
+
exports[`Tests for time.js fromSeconds() test 1`] = `"Argument \`s\` provided to \`fromSeconds\` is not a number or is NaN."`;
|
| 10 |
+
|
| 11 |
+
exports[`Tests for time.js fromSeconds() test 2`] = `"Argument \`s\` provided to \`fromSeconds\` is not a number or is NaN."`;
|
| 12 |
+
|
| 13 |
+
exports[`Tests for time.js fromSeconds() test 3`] = `"Argument \`format\` provided to \`formatTime\` is not a recognized format."`;
|
| 14 |
+
|
| 15 |
+
exports[`Tests for time.js toMilliseconds() test 1`] = `"Argument \`time\` provided to \`toMilliseconds\` is not a recognized format."`;
|
| 16 |
+
|
| 17 |
+
exports[`Tests for time.js toMilliseconds() test 2`] = `"Argument \`time\` provided to \`toMilliseconds\` is not a recognized format."`;
|
| 18 |
+
|
| 19 |
+
exports[`Tests for time.js toMilliseconds() test 3`] = `"Argument \`time\` provided to \`toMilliseconds\` is not a recognized format."`;
|
| 20 |
+
|
| 21 |
+
exports[`Tests for time.js toMilliseconds() test 4`] = `"Argument \`time\` provided to \`toMilliseconds\` contains minutes or seconds greater than 59."`;
|
| 22 |
+
|
| 23 |
+
exports[`Tests for time.js toMilliseconds() test 5`] = `"Argument \`format\` provided to \`toMilliseconds\` is not a recognized format."`;
|
| 24 |
+
|
| 25 |
+
exports[`Tests for time.js toSeconds() test 1`] = `"Argument \`time\` provided to \`toMilliseconds\` is not a recognized format."`;
|
| 26 |
+
|
| 27 |
+
exports[`Tests for time.js toSeconds() test 2`] = `"Argument \`time\` provided to \`toMilliseconds\` is not a recognized format."`;
|
| 28 |
+
|
| 29 |
+
exports[`Tests for time.js toSeconds() test 3`] = `"Argument \`time\` provided to \`toMilliseconds\` is not a recognized format."`;
|
| 30 |
+
|
| 31 |
+
exports[`Tests for time.js toSeconds() test 4`] = `"Argument \`time\` provided to \`toMilliseconds\` contains minutes or seconds greater than 59."`;
|
| 32 |
+
|
| 33 |
+
exports[`Tests for time.js toSeconds() test 5`] = `"Argument \`format\` provided to \`toMilliseconds\` is not a recognized format."`;
|
common/src/modules/utils/__tests__/date.test.js
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* Internal dependencies
|
| 3 |
+
*/
|
| 4 |
+
import { date, moment as momentUtil } from '@moderntribe/common/utils';
|
| 5 |
+
import moment from 'moment';
|
| 6 |
+
|
| 7 |
+
const {
|
| 8 |
+
FORMATS,
|
| 9 |
+
TODAY,
|
| 10 |
+
timezones,
|
| 11 |
+
timezonesAsSelectData,
|
| 12 |
+
toNaturalLanguage,
|
| 13 |
+
rangeToNaturalLanguage,
|
| 14 |
+
labelToDate,
|
| 15 |
+
} = date;
|
| 16 |
+
|
| 17 |
+
jest.mock( '@moderntribe/common/utils/timezone', () => ( {
|
| 18 |
+
getItems: () => [
|
| 19 |
+
{
|
| 20 |
+
options: [
|
| 21 |
+
{
|
| 22 |
+
key: 'America/Argentina/Buenos_Aires',
|
| 23 |
+
text: 'Argentina - Buenos Aires',
|
| 24 |
+
},
|
| 25 |
+
],
|
| 26 |
+
},
|
| 27 |
+
{
|
| 28 |
+
options: [
|
| 29 |
+
{
|
| 30 |
+
key: 'America/Argentina/Catamarca',
|
| 31 |
+
text: 'Argentina - Catamarca',
|
| 32 |
+
},
|
| 33 |
+
],
|
| 34 |
+
},
|
| 35 |
+
],
|
| 36 |
+
} ) );
|
| 37 |
+
|
| 38 |
+
afterAll( () => {
|
| 39 |
+
jest.unmock( '@moderntribe/common/utils/timezone' );
|
| 40 |
+
} );
|
| 41 |
+
|
| 42 |
+
describe( 'Tests for date.js', () => {
|
| 43 |
+
test( 'formats', () => {
|
| 44 |
+
const draft = {
|
| 45 |
+
TIME: 'HH:mm:ss',
|
| 46 |
+
DATE_TIME: 'YYYY-MM-DD HH:mm:ss',
|
| 47 |
+
WP: {
|
| 48 |
+
time: 'g:i a',
|
| 49 |
+
time24Hr: 'H:i',
|
| 50 |
+
date: 'F j, Y',
|
| 51 |
+
datetime: 'F j, Y g:i a',
|
| 52 |
+
dateNoYear: 'F j',
|
| 53 |
+
},
|
| 54 |
+
DATABASE: {
|
| 55 |
+
date: 'Y-m-d',
|
| 56 |
+
datetime: 'Y-m-d H:i:s',
|
| 57 |
+
time: 'H:i:s',
|
| 58 |
+
},
|
| 59 |
+
TIMEZONE: {
|
| 60 |
+
string: 'UTC',
|
| 61 |
+
},
|
| 62 |
+
};
|
| 63 |
+
expect( FORMATS ).toEqual( draft );
|
| 64 |
+
} );
|
| 65 |
+
|
| 66 |
+
test( 'today', () => {
|
| 67 |
+
const now = new Date();
|
| 68 |
+
expect( TODAY ).toBeInstanceOf( Date );
|
| 69 |
+
expect( TODAY ).hasOwnProperty( 'getDay' );
|
| 70 |
+
expect( TODAY.getDay() ).toEqual( now.getDay() );
|
| 71 |
+
} );
|
| 72 |
+
|
| 73 |
+
test( 'timezones', () => {
|
| 74 |
+
const expected = [
|
| 75 |
+
{
|
| 76 |
+
key: 'America/Argentina/Buenos_Aires',
|
| 77 |
+
text: 'Argentina - Buenos Aires',
|
| 78 |
+
},
|
| 79 |
+
{
|
| 80 |
+
key: 'America/Argentina/Catamarca',
|
| 81 |
+
text: 'Argentina - Catamarca',
|
| 82 |
+
},
|
| 83 |
+
];
|
| 84 |
+
expect( timezones() ).toEqual( expected );
|
| 85 |
+
} );
|
| 86 |
+
|
| 87 |
+
test( 'timezonesAsSelectData', () => {
|
| 88 |
+
const expected = [
|
| 89 |
+
{
|
| 90 |
+
value: 'America/Argentina/Buenos_Aires',
|
| 91 |
+
label: 'Argentina - Buenos Aires',
|
| 92 |
+
},
|
| 93 |
+
{
|
| 94 |
+
value: 'America/Argentina/Catamarca',
|
| 95 |
+
label: 'Argentina - Catamarca',
|
| 96 |
+
},
|
| 97 |
+
];
|
| 98 |
+
expect( timezonesAsSelectData() ).toEqual( expected );
|
| 99 |
+
} );
|
| 100 |
+
|
| 101 |
+
describe( 'toNaturalLanguage', () => {
|
| 102 |
+
it( 'Should return empty string when non parsed', () => {
|
| 103 |
+
const defaultDetail = { month: '', day: '', year: '', time: '' };
|
| 104 |
+
expect( toNaturalLanguage( {} ) ).toEqual( { moment: null, text: '', detail: defaultDetail, isValid: false } );
|
| 105 |
+
expect( toNaturalLanguage( { date: undefined } ) ).toEqual( {
|
| 106 |
+
moment: undefined,
|
| 107 |
+
text: '',
|
| 108 |
+
detail: defaultDetail,
|
| 109 |
+
isValid: false
|
| 110 |
+
} );
|
| 111 |
+
expect( toNaturalLanguage( { date: '' } ) ).toEqual( {
|
| 112 |
+
moment: '',
|
| 113 |
+
text: '',
|
| 114 |
+
detail: defaultDetail,
|
| 115 |
+
isValid: false
|
| 116 |
+
} );
|
| 117 |
+
} );
|
| 118 |
+
|
| 119 |
+
it( 'Should return the parsed date', () => {
|
| 120 |
+
expect( toNaturalLanguage( { date: '2018-05-04 17:00:00' } ) )
|
| 121 |
+
.toEqual( {
|
| 122 |
+
moment: momentUtil.toMoment( '2018-05-04 17:00:00' ),
|
| 123 |
+
text: 'May 4 2018 5:00 pm',
|
| 124 |
+
detail: {
|
| 125 |
+
month: 'May',
|
| 126 |
+
day: '4',
|
| 127 |
+
year: '2018',
|
| 128 |
+
time: '5:00 pm',
|
| 129 |
+
},
|
| 130 |
+
isValid: true,
|
| 131 |
+
} );
|
| 132 |
+
expect( toNaturalLanguage( { date: '2019-12-24 12:00:00' } ) )
|
| 133 |
+
.toEqual( {
|
| 134 |
+
moment: momentUtil.toMoment( '2019-12-24 12:00:00' ),
|
| 135 |
+
text: 'December 24 2019 12:00 pm',
|
| 136 |
+
detail: {
|
| 137 |
+
month: 'December',
|
| 138 |
+
day: '24',
|
| 139 |
+
year: '2019',
|
| 140 |
+
time: '12:00 pm',
|
| 141 |
+
},
|
| 142 |
+
isValid: true,
|
| 143 |
+
} );
|
| 144 |
+
} );
|
| 145 |
+
} );
|
| 146 |
+
|
| 147 |
+
describe( 'rangeToNaturalLanguage', () => {
|
| 148 |
+
it( 'Should return empty string when range is invalid', () => {
|
| 149 |
+
expect( rangeToNaturalLanguage( null, null ) ).toBe( '' );
|
| 150 |
+
expect( rangeToNaturalLanguage( undefined, undefined ) ).toBe( '' );
|
| 151 |
+
expect( rangeToNaturalLanguage( '', '' ) ).toBe( '' );
|
| 152 |
+
} );
|
| 153 |
+
|
| 154 |
+
it( 'Should return only the start date', () => {
|
| 155 |
+
expect( rangeToNaturalLanguage( '2019-12-24 12:00:00' ) )
|
| 156 |
+
.toBe( 'December 24 2019 at 12:00 pm' );
|
| 157 |
+
expect( rangeToNaturalLanguage( '2019-12-24 12:00:00', '' ) )
|
| 158 |
+
.toBe( 'December 24 2019 at 12:00 pm' );
|
| 159 |
+
} );
|
| 160 |
+
|
| 161 |
+
it( 'Should return the range with time on same day', () => {
|
| 162 |
+
expect( rangeToNaturalLanguage( '2019-12-24 12:00:00', '2019-12-24 17:00:00' ) )
|
| 163 |
+
.toBe( 'December 24 2019 at 12:00 pm - 5:00 pm' );
|
| 164 |
+
} );
|
| 165 |
+
|
| 166 |
+
it( 'Should return the range without year on same year', () => {
|
| 167 |
+
expect( rangeToNaturalLanguage( '2019-12-24 12:00:00', '2019-12-29 17:00:00' ) )
|
| 168 |
+
.toBe( 'December 24 2019 at 12:00 pm - December 29 at 5:00 pm' );
|
| 169 |
+
} );
|
| 170 |
+
|
| 171 |
+
it( 'Should return the range on different years', () => {
|
| 172 |
+
expect( rangeToNaturalLanguage( '2019-12-24 12:00:00', '2020-12-24 17:00:00' ) )
|
| 173 |
+
.toBe( 'December 24 2019 at 12:00 pm - December 24 2020 at 5:00 pm' );
|
| 174 |
+
} );
|
| 175 |
+
} );
|
| 176 |
+
|
| 177 |
+
describe( 'labelToDate - be aware chrono module is being mocked to avoid parsing', () => {
|
| 178 |
+
test( 'Default value when date is invalid', () => {
|
| 179 |
+
expect( labelToDate() ).toEqual( { start: null, end: null } );
|
| 180 |
+
} );
|
| 181 |
+
|
| 182 |
+
test( 'Valid dates', () => {
|
| 183 |
+
const momentDate = moment( '12-25-1995', 'MM-DD-YYYY' );
|
| 184 |
+
expect( labelToDate( momentDate ) )
|
| 185 |
+
.toEqual( { start: momentUtil.toDateTime( momentDate ), end: momentUtil.toDateTime( momentDate ) } );
|
| 186 |
+
} );
|
| 187 |
+
} );
|
| 188 |
+
|
| 189 |
+
} );
|
common/src/modules/utils/__tests__/dom.test.js
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* Internal dependencies
|
| 3 |
+
*/
|
| 4 |
+
import {
|
| 5 |
+
hasClass,
|
| 6 |
+
isRootNode,
|
| 7 |
+
searchParent,
|
| 8 |
+
} from '@moderntribe/common/utils/dom';
|
| 9 |
+
|
| 10 |
+
describe( 'Tests for dom.js', () => {
|
| 11 |
+
beforeAll( () => {
|
| 12 |
+
window.document.body.classList.add( 'one', 'two' );
|
| 13 |
+
} );
|
| 14 |
+
|
| 15 |
+
afterAll( () => {
|
| 16 |
+
window.document.body.classList.remove( 'one', 'two' );
|
| 17 |
+
} );
|
| 18 |
+
|
| 19 |
+
describe( 'hasClass dom utility', () => {
|
| 20 |
+
it( 'Should return false when the dom element does not have any class', () => {
|
| 21 |
+
expect( hasClass( window.document.body, [] ) ).toBe( false );
|
| 22 |
+
expect( hasClass( window.document.body, [ 'five', 'seven' ] ) ).toBe( false );
|
| 23 |
+
expect( hasClass( window.document.body, [ 'eight' ] ) ).toBe( false );
|
| 24 |
+
} );
|
| 25 |
+
|
| 26 |
+
it( 'Should return true whe the dom element has any of the classes', () => {
|
| 27 |
+
expect( hasClass( window.document.body, [ 'one', 'two' ] ) ).toBe( true );
|
| 28 |
+
expect( hasClass( window.document.body, [ 'two', 'one' ] ) ).toBe( true );
|
| 29 |
+
expect( hasClass( window.document.body, [ 'four', 'two' ] ) ).toBe( true );
|
| 30 |
+
expect( hasClass( window.document.body, [ 'one', 'five' ] ) ).toBe( true );
|
| 31 |
+
expect( hasClass( window.document.body, [ 'nostyle', 'six', 'seven', 'one' ] ) ).toBe( true );
|
| 32 |
+
} );
|
| 33 |
+
} );
|
| 34 |
+
|
| 35 |
+
test( 'Test for searchParent', () => {
|
| 36 |
+
expect( searchParent( null ) ).toBeFalsy();
|
| 37 |
+
const treeWithNode = {
|
| 38 |
+
parentNode: {
|
| 39 |
+
value: 10,
|
| 40 |
+
parentNode: {
|
| 41 |
+
value: 20,
|
| 42 |
+
},
|
| 43 |
+
},
|
| 44 |
+
};
|
| 45 |
+
|
| 46 |
+
const callback = jest.fn( ( node ) => node.value === 20 );
|
| 47 |
+
const result = searchParent( treeWithNode, callback );
|
| 48 |
+
expect( callback ).toBeCalled();
|
| 49 |
+
expect( callback ).toBeCalledWith( { value: 20 } );
|
| 50 |
+
expect( result ).toBeTruthy();
|
| 51 |
+
|
| 52 |
+
const treeWithoutNode = {
|
| 53 |
+
parentNode: {
|
| 54 |
+
parentNode: {
|
| 55 |
+
parentNode: {
|
| 56 |
+
top: {
|
| 57 |
+
document: 'global',
|
| 58 |
+
},
|
| 59 |
+
},
|
| 60 |
+
},
|
| 61 |
+
},
|
| 62 |
+
};
|
| 63 |
+
|
| 64 |
+
expect( searchParent( treeWithoutNode ) ).toBeFalsy();
|
| 65 |
+
} );
|
| 66 |
+
|
| 67 |
+
test( 'Test for isRootNode', () => {
|
| 68 |
+
expect( isRootNode( null ) ).toBeFalsy();
|
| 69 |
+
expect( isRootNode( 'text' ) ).toBeFalsy();
|
| 70 |
+
expect( isRootNode( window.document.body ) ).toBeFalsy();
|
| 71 |
+
expect( isRootNode( window.document ) ).toBeTruthy();
|
| 72 |
+
} );
|
| 73 |
+
} );
|
common/src/modules/utils/__tests__/globals.test.js
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* Internal dependencies
|
| 3 |
+
*/
|
| 4 |
+
import {
|
| 5 |
+
google,
|
| 6 |
+
mapsAPI,
|
| 7 |
+
settings,
|
| 8 |
+
list,
|
| 9 |
+
get,
|
| 10 |
+
config,
|
| 11 |
+
rest,
|
| 12 |
+
restNonce,
|
| 13 |
+
} from '@moderntribe/common/utils/globals';
|
| 14 |
+
|
| 15 |
+
describe( 'Tests for globals.js', () => {
|
| 16 |
+
|
| 17 |
+
beforeAll( () => {
|
| 18 |
+
window.tribe_editor_config = {
|
| 19 |
+
common: {
|
| 20 |
+
countries: {},
|
| 21 |
+
usStates: {},
|
| 22 |
+
settings: {},
|
| 23 |
+
rest: {
|
| 24 |
+
namespaces: {
|
| 25 |
+
core: 'wp/v2',
|
| 26 |
+
},
|
| 27 |
+
nonce: {
|
| 28 |
+
wp_rest: 'cedcd6967b',
|
| 29 |
+
add_ticket_nonce: '0878f40fb2',
|
| 30 |
+
},
|
| 31 |
+
url: 'http://gutenberg.local/wp-json/',
|
| 32 |
+
},
|
| 33 |
+
},
|
| 34 |
+
tec: {
|
| 35 |
+
googleMap: {},
|
| 36 |
+
},
|
| 37 |
+
tickets: {
|
| 38 |
+
providers: [ {
|
| 39 |
+
class: 'Tribe__Tickets_Plus__Commerce__WooCommerce__Main',
|
| 40 |
+
currency: '$',
|
| 41 |
+
currency_position: 'prefix',
|
| 42 |
+
name: 'WooCommerce',
|
| 43 |
+
} ],
|
| 44 |
+
default_provider: 'Tribe__Tickets_Plus__Commerce__WooCommerce__Main',
|
| 45 |
+
default_currency: '$',
|
| 46 |
+
},
|
| 47 |
+
};
|
| 48 |
+
} );
|
| 49 |
+
|
| 50 |
+
test( 'Should match the default value for the globals values', () => {
|
| 51 |
+
expect( get( 'random' ) ).toBe( undefined );
|
| 52 |
+
expect( get( 'google' ) ).toBe( undefined );
|
| 53 |
+
expect( google() ).toBe( undefined );
|
| 54 |
+
expect( get( 'tribe_editor_config' ) ).toMatchSnapshot();
|
| 55 |
+
expect( settings() ).toEqual( {} );
|
| 56 |
+
expect( mapsAPI() ).toEqual( {} );
|
| 57 |
+
expect( list() ).toEqual( {
|
| 58 |
+
countries: {},
|
| 59 |
+
us_states: {},
|
| 60 |
+
} );
|
| 61 |
+
expect( config() ).toMatchSnapshot();
|
| 62 |
+
} );
|
| 63 |
+
|
| 64 |
+
test( 'get default value', () => {
|
| 65 |
+
expect( get( 'UNKNOWN', 10 ) ).toBe( 10 );
|
| 66 |
+
expect( get( 'tribe_js_config', [] ) ).toMatchSnapshot();
|
| 67 |
+
} );
|
| 68 |
+
|
| 69 |
+
test( 'rest value', () => {
|
| 70 |
+
expect( rest() ).toMatchSnapshot();
|
| 71 |
+
expect( restNonce() ).toMatchSnapshot();
|
| 72 |
+
} );
|
| 73 |
+
|
| 74 |
+
afterAll( () => {
|
| 75 |
+
delete window.tribe_editor_config;
|
| 76 |
+
} );
|
| 77 |
+
} );
|
| 78 |
+
|
| 79 |
+
describe( 'Test default values on globals', () => {
|
| 80 |
+
test( 'rest default values', () => {
|
| 81 |
+
expect( rest() ).toEqual( {} );
|
| 82 |
+
expect( restNonce() ).toEqual( {} );
|
| 83 |
+
} );
|
| 84 |
+
} );
|
common/src/modules/utils/__tests__/input.test.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* Internal dependencies
|
| 3 |
+
*/
|
| 4 |
+
import { sendValue } from '@moderntribe/common/utils/input';
|
| 5 |
+
|
| 6 |
+
describe( 'Tests for input.js', () => {
|
| 7 |
+
const event = {
|
| 8 |
+
target: {
|
| 9 |
+
value: 'Sample',
|
| 10 |
+
},
|
| 11 |
+
};
|
| 12 |
+
|
| 13 |
+
test( 'Callback being executed', () => {
|
| 14 |
+
const mockCallback = jest.fn();
|
| 15 |
+
sendValue( mockCallback )( event );
|
| 16 |
+
expect( mockCallback ).toHaveBeenCalled();
|
| 17 |
+
expect( mockCallback ).toHaveBeenCalledTimes( 1 );
|
| 18 |
+
expect( mockCallback ).toHaveBeenCalledWith( 'Sample' );
|
| 19 |
+
} );
|
| 20 |
+
} );
|
common/src/modules/utils/__tests__/moment.test.js
ADDED
|
@@ -0,0 +1,332 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import moment from 'moment/moment';
|
| 5 |
+
|
| 6 |
+
/**
|
| 7 |
+
* Internal dependencies
|
| 8 |
+
*/
|
| 9 |
+
import {
|
| 10 |
+
date,
|
| 11 |
+
moment as momentUtil,
|
| 12 |
+
time,
|
| 13 |
+
} from '@moderntribe/common/utils';
|
| 14 |
+
|
| 15 |
+
const FORMAT = 'MM-DD-YYYY HH:mm:ss';
|
| 16 |
+
|
| 17 |
+
describe( 'Tests for moment.js', () => {
|
| 18 |
+
let console;
|
| 19 |
+
beforeAll( () => {
|
| 20 |
+
console = window.console;
|
| 21 |
+
window.console = {
|
| 22 |
+
...console,
|
| 23 |
+
warn: jest.fn(),
|
| 24 |
+
};
|
| 25 |
+
} );
|
| 26 |
+
|
| 27 |
+
afterAll( () => {
|
| 28 |
+
window.console = console;
|
| 29 |
+
} );
|
| 30 |
+
|
| 31 |
+
test( 'TIME_FORMAT', () => {
|
| 32 |
+
expect( momentUtil.TIME_FORMAT ).toEqual( 'h:mm a' );
|
| 33 |
+
} );
|
| 34 |
+
|
| 35 |
+
test( 'roundTime', () => {
|
| 36 |
+
const test1 = momentUtil.roundTime(
|
| 37 |
+
moment( '05-09-2018 12:26:02', FORMAT ),
|
| 38 |
+
);
|
| 39 |
+
expect( test1 ).toBeInstanceOf( moment );
|
| 40 |
+
expect( test1.hour() ).toEqual( 12 );
|
| 41 |
+
expect( test1.minutes() ).toEqual( 0 );
|
| 42 |
+
expect( test1.seconds() ).toEqual( 0 );
|
| 43 |
+
|
| 44 |
+
const test2 = momentUtil.roundTime(
|
| 45 |
+
moment( '05-09-2018 15:30:02', FORMAT ),
|
| 46 |
+
);
|
| 47 |
+
expect( test2 ).toBeInstanceOf( moment );
|
| 48 |
+
expect( test2.hour() ).toEqual( 15 );
|
| 49 |
+
expect( test2.minutes() ).toEqual( 30 );
|
| 50 |
+
expect( test2.seconds() ).toEqual( 0 );
|
| 51 |
+
|
| 52 |
+
const test3 = momentUtil.roundTime(
|
| 53 |
+
moment( '05-09-2018 23:59:59', FORMAT ),
|
| 54 |
+
);
|
| 55 |
+
expect( test3 ).toBeInstanceOf( moment );
|
| 56 |
+
expect( test3.hour() ).toEqual( 23 );
|
| 57 |
+
expect( test3.minutes() ).toEqual( 30 );
|
| 58 |
+
expect( test3.seconds() ).toEqual( 0 );
|
| 59 |
+
|
| 60 |
+
const test4 = momentUtil.roundTime(
|
| 61 |
+
moment( '05-09-2018 08:01:59', FORMAT ),
|
| 62 |
+
);
|
| 63 |
+
expect( test4 ).toBeInstanceOf( moment );
|
| 64 |
+
expect( test4.hour() ).toEqual( 8 );
|
| 65 |
+
expect( test4.minutes() ).toEqual( 0 );
|
| 66 |
+
expect( test4.seconds() ).toEqual( 0 );
|
| 67 |
+
} );
|
| 68 |
+
|
| 69 |
+
test( 'toMoment', () => {
|
| 70 |
+
const input = momentUtil.toMoment( new Date( 'January 2, 2015 08:01:59 UTC' ).toISOString() );
|
| 71 |
+
|
| 72 |
+
expect( input ).toBeInstanceOf( moment );
|
| 73 |
+
expect( input.date() ).toEqual( 2 );
|
| 74 |
+
expect( input.month() ).toEqual( 0 );
|
| 75 |
+
expect( input.year() ).toEqual( 2015 );
|
| 76 |
+
expect( input.hour() ).toEqual( 8 );
|
| 77 |
+
expect( input.minutes() ).toEqual( 1 );
|
| 78 |
+
expect( input.seconds() ).toEqual( 59 );
|
| 79 |
+
expect( input.milliseconds() ).toEqual( 0 );
|
| 80 |
+
expect( input.format( FORMAT ) ).toEqual( '01-02-2015 08:01:59' );
|
| 81 |
+
} );
|
| 82 |
+
|
| 83 |
+
test( 'replaceDate', () => {
|
| 84 |
+
expect( () => momentUtil.replaceDate( 'Sample string', 123123 ) ).toThrowError();
|
| 85 |
+
|
| 86 |
+
const a = moment( '02-28-2010 14:24:40', FORMAT );
|
| 87 |
+
const b = moment( '05-10-2012 20:14:20', FORMAT );
|
| 88 |
+
|
| 89 |
+
const replaced = momentUtil.replaceDate( a, b );
|
| 90 |
+
expect( replaced ).toBeInstanceOf( moment );
|
| 91 |
+
expect( replaced.date() ).toEqual( 10 );
|
| 92 |
+
expect( replaced.month() ).toEqual( 4 );
|
| 93 |
+
expect( replaced.year() ).toEqual( 2012 );
|
| 94 |
+
expect( replaced.hour() ).toEqual( 14 );
|
| 95 |
+
expect( replaced.minute() ).toEqual( 24 );
|
| 96 |
+
expect( replaced.second() ).toEqual( 40 );
|
| 97 |
+
expect( replaced.format( FORMAT ) ).toEqual( '05-10-2012 14:24:40' );
|
| 98 |
+
} );
|
| 99 |
+
|
| 100 |
+
test( 'setTimeInSeconds', () => {
|
| 101 |
+
expect( () => momentUtil.setTimeInSeconds( 'Sample String', 123123 ) ).toThrowError();
|
| 102 |
+
|
| 103 |
+
const a = moment( '02-28-2010 14:24:40', FORMAT );
|
| 104 |
+
const SECONDS = ( 12.5 ) * 60 * 60;
|
| 105 |
+
const replaced = momentUtil.setTimeInSeconds( a, SECONDS );
|
| 106 |
+
expect( replaced ).toBeInstanceOf( moment );
|
| 107 |
+
expect( replaced.date() ).toEqual( 28 );
|
| 108 |
+
expect( replaced.month() ).toEqual( 1 );
|
| 109 |
+
expect( replaced.year() ).toEqual( 2010 );
|
| 110 |
+
expect( replaced.hour() ).toEqual( 12 );
|
| 111 |
+
expect( replaced.minute() ).toEqual( 30 );
|
| 112 |
+
expect( replaced.seconds() ).toEqual( 0 );
|
| 113 |
+
expect( replaced.milliseconds() ).toEqual( 0 );
|
| 114 |
+
|
| 115 |
+
const test2 = momentUtil.setTimeInSeconds( a, 0 );
|
| 116 |
+
expect( test2.date() ).toEqual( 28 );
|
| 117 |
+
expect( test2.month() ).toEqual( 1 );
|
| 118 |
+
expect( test2.year() ).toEqual( 2010 );
|
| 119 |
+
expect( test2.hour() ).toEqual( 0 );
|
| 120 |
+
expect( test2.minute() ).toEqual( 0 );
|
| 121 |
+
expect( test2.seconds() ).toEqual( 0 );
|
| 122 |
+
expect( test2.milliseconds() ).toEqual( 0 );
|
| 123 |
+
} );
|
| 124 |
+
|
| 125 |
+
test( 'totalSeconds', () => {
|
| 126 |
+
expect( momentUtil.totalSeconds( null ) ).toEqual( 0 );
|
| 127 |
+
expect( momentUtil.totalSeconds( new Date() ) ).toEqual( 0 );
|
| 128 |
+
expect( momentUtil.totalSeconds( moment().startOf( 'day' ) ) ).toEqual( 0 );
|
| 129 |
+
expect( momentUtil.totalSeconds( moment( 'May 23, 2018 12:30 am', 'MMM D, YYYY k:m a' ) ) )
|
| 130 |
+
.toEqual( time.HALF_HOUR_IN_SECONDS );
|
| 131 |
+
} );
|
| 132 |
+
|
| 133 |
+
test( 'toDateTime', () => {
|
| 134 |
+
const converted = momentUtil.toDateTime( moment() );
|
| 135 |
+
expect( typeof converted ).toBe( 'string' );
|
| 136 |
+
const format = momentUtil.toFormat( date.FORMATS.DATABASE.datetime );
|
| 137 |
+
expect( converted ).toBe( moment().format( format ) );
|
| 138 |
+
} );
|
| 139 |
+
|
| 140 |
+
test( 'toDate', () => {
|
| 141 |
+
const converted = momentUtil.toDate( moment() );
|
| 142 |
+
expect( typeof converted ).toBe( 'string' );
|
| 143 |
+
expect( typeof converted ).toBe( 'string' );
|
| 144 |
+
const format = momentUtil.toFormat( date.FORMATS.WP.date );
|
| 145 |
+
expect( converted ).toBe( moment().format( format ) );
|
| 146 |
+
} );
|
| 147 |
+
|
| 148 |
+
test( 'toDateNoYear', () => {
|
| 149 |
+
const converted = momentUtil.toDateNoYear( moment() );
|
| 150 |
+
expect( typeof converted ).toBe( 'string' );
|
| 151 |
+
expect( converted ).toBe( moment().format( 'MMMM D' ) );
|
| 152 |
+
} );
|
| 153 |
+
|
| 154 |
+
test( 'toTime', () => {
|
| 155 |
+
const converted = momentUtil.toTime( moment() );
|
| 156 |
+
expect( typeof converted ).toBe( 'string' );
|
| 157 |
+
expect( converted ).toBe( moment().format( 'h:mm a' ) );
|
| 158 |
+
} );
|
| 159 |
+
|
| 160 |
+
test( 'toTime24Hr', () => {
|
| 161 |
+
const converted = momentUtil.toTime24Hr( moment() );
|
| 162 |
+
expect( typeof converted ).toBe( 'string' );
|
| 163 |
+
expect( converted ).toBe( moment().format( 'HH:mm' ) );
|
| 164 |
+
} );
|
| 165 |
+
|
| 166 |
+
test( 'toDatabaseDate', () => {
|
| 167 |
+
const converted = momentUtil.toDatabaseDate( moment() );
|
| 168 |
+
expect( typeof converted ).toBe( 'string' );
|
| 169 |
+
expect( converted ).toBe( moment().format( 'YYYY-MM-DD' ) );
|
| 170 |
+
} );
|
| 171 |
+
|
| 172 |
+
test( 'toDatabaseTime', () => {
|
| 173 |
+
const converted = momentUtil.toDatabaseTime( moment() );
|
| 174 |
+
expect( typeof converted ).toBe( 'string' );
|
| 175 |
+
expect( converted ).toBe( moment().format( 'HH:mm:ss' ) );
|
| 176 |
+
} );
|
| 177 |
+
|
| 178 |
+
test( 'toDatePicker', () => {
|
| 179 |
+
const converted = momentUtil.toDatePicker( moment() );
|
| 180 |
+
expect( typeof converted ).toBe( 'string' );
|
| 181 |
+
expect( converted ).toBe( moment().format( 'YYYY-MM-DDTHH:mm:ss' ) );
|
| 182 |
+
} );
|
| 183 |
+
|
| 184 |
+
test( 'isSameDay', () => {
|
| 185 |
+
expect( momentUtil.isSameDay() ).toBe( false );
|
| 186 |
+
expect( momentUtil.isSameDay( false, '' ) ).toBe( false );
|
| 187 |
+
expect( momentUtil.isSameDay( 0, null ) ).toBe( false );
|
| 188 |
+
expect( momentUtil.isSameDay( moment(), moment().endOf( 'day' ) ) ).toBeTruthy();
|
| 189 |
+
expect( momentUtil.isSameDay( moment().endOf( 'day' ), moment().endOf( 'day' ) ) ).toBeTruthy();
|
| 190 |
+
expect( momentUtil.isSameDay( moment(), moment().add( 10, 'days' ) ) ).toBeFalsy();
|
| 191 |
+
expect( momentUtil.isSameDay( new Date(), new Date() ) ).toBeTruthy();
|
| 192 |
+
} );
|
| 193 |
+
|
| 194 |
+
test( 'isSameMonth', () => {
|
| 195 |
+
const date = moment( 'October 8, 2018 5:30 pm', 'MMMM D, Y h:mm a' );
|
| 196 |
+
|
| 197 |
+
expect( momentUtil.isSameMonth() ).toBe( false );
|
| 198 |
+
expect( momentUtil.isSameMonth( false, '' ) ).toBe( false );
|
| 199 |
+
expect( momentUtil.isSameMonth( 0, null ) ).toBe( false );
|
| 200 |
+
expect( momentUtil.isSameMonth( date, date.clone().add( 24, 'days' ) ) ).toBe( false );
|
| 201 |
+
expect( momentUtil.isSameMonth( date, date.clone().add( 23, 'days' ) ) ).toBe( true );
|
| 202 |
+
expect( momentUtil.isSameMonth( date, date.clone().endOf( 'month' ) ) ).toBe( true );
|
| 203 |
+
expect( momentUtil.isSameMonth( date.clone().endOf( 'month' ), date.clone().endOf( 'month' ) ) ).toBe( true );
|
| 204 |
+
expect( momentUtil.isSameMonth( date, date.clone().add( 10, 'days' ) ) ).toBe( true );
|
| 205 |
+
expect( momentUtil.isSameMonth( date, date ) ).toBe( true );
|
| 206 |
+
} );
|
| 207 |
+
|
| 208 |
+
test( 'isSameYear', () => {
|
| 209 |
+
expect( momentUtil.isSameYear(
|
| 210 |
+
moment( 'May 23, 2018 12:30 am', 'MMM D, YYYY k:m a' ),
|
| 211 |
+
moment( 'September 15, 2018 5:30 am', 'MMM D, YYYY k:m a' )
|
| 212 |
+
) ).toBeTruthy();
|
| 213 |
+
expect( momentUtil.isSameYear(
|
| 214 |
+
moment( 'May 23, 2022 12:30 am', 'MMM D, YYYY k:m a' ),
|
| 215 |
+
moment( 'September 15, 2022 5:30 am', 'MMM D, YYYY k:m a' )
|
| 216 |
+
) ).toBeTruthy();
|
| 217 |
+
expect( momentUtil.isSameYear(
|
| 218 |
+
moment( 'May 23, 2018 12:30 am', 'MMM D, YYYY k:m a' ),
|
| 219 |
+
moment( 'September 15, 2022 5:30 am', 'MMM D, YYYY k:m a' )
|
| 220 |
+
) ).toBeFalsy();
|
| 221 |
+
} );
|
| 222 |
+
|
| 223 |
+
test( 'toMomentFromDate', () => {
|
| 224 |
+
expect( () => momentUtil.toMomentFromDate( '' ) ).toThrowError();
|
| 225 |
+
expect( () => momentUtil.toMomentFromDate( moment() ) ).toThrowError();
|
| 226 |
+
Date.now = jest.fn( () => '2018-05-04T05:23:19.000Z' );
|
| 227 |
+
const format = 'YYYY-MM-DD HH:mm:ss';
|
| 228 |
+
const now = new Date( 'December 17, 2015 03:24:00' );
|
| 229 |
+
expect( momentUtil.toMomentFromDate( now ) ).toBeInstanceOf( moment );
|
| 230 |
+
const expected = momentUtil.toMomentFromDate( now ).format( format );
|
| 231 |
+
expect( expected ).toBe( '2015-12-17 00:00:00' );
|
| 232 |
+
} );
|
| 233 |
+
|
| 234 |
+
test( 'toFormat', () => {
|
| 235 |
+
expect( momentUtil.toFormat( '' ) ).toEqual( '' );
|
| 236 |
+
expect( momentUtil.toFormat( 'Y-m-d H:i:s' ) ).toEqual( 'YYYY-MM-DD HH:mm:ss' );
|
| 237 |
+
expect( momentUtil.toFormat( 'F j, Y g:i a' ) ).toEqual( 'MMMM D, YYYY h:mm a' );
|
| 238 |
+
expect( momentUtil.toFormat( 'tLBIOPTZcr' ) ).toEqual( '' );
|
| 239 |
+
expect( momentUtil.toFormat( 'd' ) ).toEqual( 'DD' );
|
| 240 |
+
expect( momentUtil.toFormat( 'D' ) ).toEqual( 'ddd' );
|
| 241 |
+
expect( momentUtil.toFormat( 'j' ) ).toEqual( 'D' );
|
| 242 |
+
expect( momentUtil.toFormat( 'l' ) ).toEqual( 'dddd' );
|
| 243 |
+
expect( momentUtil.toFormat( 'N' ) ).toEqual( 'E' );
|
| 244 |
+
expect( momentUtil.toFormat( 'S' ) ).toEqual( 'o' );
|
| 245 |
+
expect( momentUtil.toFormat( 'w' ) ).toEqual( 'e' );
|
| 246 |
+
expect( momentUtil.toFormat( 'z' ) ).toEqual( 'DDD' );
|
| 247 |
+
expect( momentUtil.toFormat( 'W' ) ).toEqual( 'W' );
|
| 248 |
+
expect( momentUtil.toFormat( 'F' ) ).toEqual( 'MMMM' );
|
| 249 |
+
expect( momentUtil.toFormat( 'm' ) ).toEqual( 'MM' );
|
| 250 |
+
expect( momentUtil.toFormat( 'M' ) ).toEqual( 'MMM' );
|
| 251 |
+
expect( momentUtil.toFormat( 'n' ) ).toEqual( 'M' );
|
| 252 |
+
expect( momentUtil.toFormat( 'o' ) ).toEqual( 'YYYY' );
|
| 253 |
+
expect( momentUtil.toFormat( 'Y' ) ).toEqual( 'YYYY' );
|
| 254 |
+
expect( momentUtil.toFormat( 'y' ) ).toEqual( 'YY' );
|
| 255 |
+
expect( momentUtil.toFormat( 'a' ) ).toEqual( 'a' );
|
| 256 |
+
expect( momentUtil.toFormat( 'A' ) ).toEqual( 'A' );
|
| 257 |
+
expect( momentUtil.toFormat( 'g' ) ).toEqual( 'h' );
|
| 258 |
+
expect( momentUtil.toFormat( 'G' ) ).toEqual( 'H' );
|
| 259 |
+
expect( momentUtil.toFormat( 'h' ) ).toEqual( 'hh' );
|
| 260 |
+
expect( momentUtil.toFormat( 'H' ) ).toEqual( 'HH' );
|
| 261 |
+
expect( momentUtil.toFormat( 'i' ) ).toEqual( 'mm' );
|
| 262 |
+
expect( momentUtil.toFormat( 's' ) ).toEqual( 'ss' );
|
| 263 |
+
expect( momentUtil.toFormat( 'u' ) ).toEqual( 'SSS' );
|
| 264 |
+
expect( momentUtil.toFormat( 'e' ) ).toEqual( 'zz' );
|
| 265 |
+
expect( momentUtil.toFormat( 'U' ) ).toEqual( 'X' );
|
| 266 |
+
} );
|
| 267 |
+
|
| 268 |
+
describe( 'parseFormats', () => {
|
| 269 |
+
test( 'Use DB format', () => {
|
| 270 |
+
const format = 'YYYY-MM-DD HH:mm:ss';
|
| 271 |
+
const expected = momentUtil.parseFormats( '2019-11-19 22:32:00' );
|
| 272 |
+
expect( expected.format( format ) ).toBe( '2019-11-19 22:32:00' );
|
| 273 |
+
} );
|
| 274 |
+
|
| 275 |
+
test( 'Use WP datetime format', () => {
|
| 276 |
+
const format = 'MMMM D, YYYY h:mm a';
|
| 277 |
+
const expected = momentUtil.parseFormats( 'November 19, 2019 10:32 pm' );
|
| 278 |
+
expect( expected.format( format ) ).toBe( 'November 19, 2019 10:32 pm' );
|
| 279 |
+
} );
|
| 280 |
+
|
| 281 |
+
test( 'Invalid date', () => {
|
| 282 |
+
Date.now = jest.fn( () => new Date( 'July 1, 2018 00:07:31 UTC' ).toISOString() );
|
| 283 |
+
const format = 'YYYY-MM-DD HH:mm:ss';
|
| 284 |
+
const expected = momentUtil.parseFormats( 'No date!' );
|
| 285 |
+
expect( expected.format( format ) ).toBe( '2018-07-01 00:07:31' );
|
| 286 |
+
expect( window.console.warn ).toHaveBeenCalled();
|
| 287 |
+
} );
|
| 288 |
+
} );
|
| 289 |
+
|
| 290 |
+
describe( 'resetTimes', () => {
|
| 291 |
+
const format = 'YYYY-MM-DD HH:mm:ss';
|
| 292 |
+
it( 'Should add an hour in seconds', () => {
|
| 293 |
+
const startMoment = moment( new Date( 'July 19, 2018 19:30:00 UTC' ).toISOString() );
|
| 294 |
+
const { start, end } = momentUtil.resetTimes( startMoment );
|
| 295 |
+
expect( start.format( format ) ).toBe( '2018-07-19 19:30:00' );
|
| 296 |
+
expect( end.format( format ) ).toBe( '2018-07-19 20:30:00' );
|
| 297 |
+
} );
|
| 298 |
+
|
| 299 |
+
it( 'Should add hour in seconds on start of the day', () => {
|
| 300 |
+
const startMoment = moment( new Date( 'July 19, 2018 00:00:00 UTC' ).toISOString() );
|
| 301 |
+
const { start, end } = momentUtil.resetTimes( startMoment );
|
| 302 |
+
expect( start.format( format ) ).toBe( '2018-07-19 00:00:00' );
|
| 303 |
+
expect( end.format( format ) ).toBe( '2018-07-19 01:00:00' );
|
| 304 |
+
} );
|
| 305 |
+
|
| 306 |
+
it( 'Should prevent overflow to the next day', () => {
|
| 307 |
+
const startMoment = moment( new Date( 'July 19, 2018 23:59:59 UTC' ).toISOString() );
|
| 308 |
+
const { start, end } = momentUtil.resetTimes( startMoment );
|
| 309 |
+
expect( start.format( format ) ).toBe( '2018-07-19 22:59:59' );
|
| 310 |
+
expect( end.format( format ) ).toBe( '2018-07-19 23:59:59' );
|
| 311 |
+
} );
|
| 312 |
+
} );
|
| 313 |
+
|
| 314 |
+
describe( 'adjustStart', () => {
|
| 315 |
+
const format = 'YYYY-MM-DD HH:mm:ss';
|
| 316 |
+
it( 'Should keep the same order when start is before', () => {
|
| 317 |
+
const start = moment( new Date( 'July 10, 2018 14:30:00 UTC' ).toISOString() );
|
| 318 |
+
const end = moment( new Date( 'July 10, 2018 20:35:00 UTC' ).toISOString() );
|
| 319 |
+
const output = momentUtil.adjustStart( start, end );
|
| 320 |
+
expect( output.start.format( format ) ).toBe( '2018-07-10 14:30:00' );
|
| 321 |
+
expect( output.end.format( format ) ).toBe( '2018-07-10 20:35:00' );
|
| 322 |
+
} );
|
| 323 |
+
|
| 324 |
+
it( 'Should adjust the start and end time', () => {
|
| 325 |
+
const start = moment( new Date( 'July 10, 2018 20:35:00 UTC' ).toISOString() );
|
| 326 |
+
const end = moment( new Date( 'July 10, 2018 10:30:00 UTC' ).toISOString() );
|
| 327 |
+
const output = momentUtil.adjustStart( start, end );
|
| 328 |
+
expect( output.start.format( format ) ).toBe( '2018-07-10 20:35:00' );
|
| 329 |
+
expect( output.end.format( format ) ).toBe( '2018-07-10 21:35:00' );
|
| 330 |
+
} );
|
| 331 |
+
} );
|
| 332 |
+
} );
|
common/src/modules/utils/__tests__/number.test.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* Internal dependencies
|
| 3 |
+
*/
|
| 4 |
+
import { percentage } from '@moderntribe/common/utils/number';
|
| 5 |
+
|
| 6 |
+
describe( 'percentage', () => {
|
| 7 |
+
test( 'with default values', () => {
|
| 8 |
+
expect( percentage() ).toBe( 0 );
|
| 9 |
+
} );
|
| 10 |
+
|
| 11 |
+
test( 'with non numbers', () => {
|
| 12 |
+
expect( () => percentage( 'modern', 'tribe' ) ).toThrow();
|
| 13 |
+
} );
|
| 14 |
+
|
| 15 |
+
test( 'limits outside 100 percent', () => {
|
| 16 |
+
expect( percentage( 120, 100 ) ).toBe( 120 );
|
| 17 |
+
expect( percentage( 1220, 100 ) ).toBe( 1220 );
|
| 18 |
+
expect( percentage( 101, 100 ) ).toBe( 101 );
|
| 19 |
+
expect( percentage( 100, 100 ) ).toBe( 100 );
|
| 20 |
+
} );
|
| 21 |
+
|
| 22 |
+
test( 'common cases', () => {
|
| 23 |
+
expect( percentage( 10, 100 ) ).toBe( 10 );
|
| 24 |
+
expect( percentage( 17, 100 ) ).toBe( 17 );
|
| 25 |
+
expect( percentage( 20, 1000 ) ).toBe( 2 );
|
| 26 |
+
expect( percentage( 155, 1000 ) ).toBe( 15.5 );
|
| 27 |
+
expect( percentage( 999, 1000 ) ).toBe( 99.9 );
|
| 28 |
+
expect( percentage( 1000, 1000 ) ).toBe( 100 );
|
| 29 |
+
} );
|
| 30 |
+
|
| 31 |
+
test( 'negative percentages', () => {
|
| 32 |
+
expect( percentage( -10, 100 ) ).toBe( -10 );
|
| 33 |
+
expect( percentage( -80, 100 ) ).toBe( -80 );
|
| 34 |
+
expect( percentage( -200, 100 ) ).toBe( -200 );
|
| 35 |
+
} );
|
| 36 |
+
} );
|
common/src/modules/utils/__tests__/proptypes.test.js
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import { noop } from 'lodash';
|
| 5 |
+
|
| 6 |
+
/**
|
| 7 |
+
* Internal dependencies
|
| 8 |
+
*/
|
| 9 |
+
import * as proptypes from '@moderntribe/common/utils/proptypes';
|
| 10 |
+
|
| 11 |
+
describe( 'Tests for proptypes utils', () => {
|
| 12 |
+
describe( 'createChainableValidator', () => {
|
| 13 |
+
it( 'should not return an error when prop is undefined and is not required', () => {
|
| 14 |
+
const props = {};
|
| 15 |
+
const chainedValidator = jest.fn( proptypes.createChainableValidator( noop ) );
|
| 16 |
+
chainedValidator( props, 'time', 'component' );
|
| 17 |
+
|
| 18 |
+
expect( chainedValidator ).toHaveReturned();
|
| 19 |
+
expect( chainedValidator ).toHaveReturnedWith( null );
|
| 20 |
+
} );
|
| 21 |
+
|
| 22 |
+
it( 'should return an error when prop is undefined and is required', () => {
|
| 23 |
+
const props = {};
|
| 24 |
+
const chainedValidator = jest.fn( proptypes.createChainableValidator( noop ).isRequired );
|
| 25 |
+
chainedValidator( props, 'time', 'component' );
|
| 26 |
+
|
| 27 |
+
expect( chainedValidator ).toHaveReturned();
|
| 28 |
+
expect( chainedValidator ).toHaveReturnedWith( Error( 'The prop `time` is marked as required in `component`, but its value is `undefined`.' ) );
|
| 29 |
+
} );
|
| 30 |
+
|
| 31 |
+
it( 'should return an error when prop is null and is required', () => {
|
| 32 |
+
const props = {
|
| 33 |
+
time: null,
|
| 34 |
+
};
|
| 35 |
+
const chainedValidator = jest.fn( proptypes.createChainableValidator( noop ).isRequired );
|
| 36 |
+
chainedValidator( props, 'time', 'component' );
|
| 37 |
+
|
| 38 |
+
expect( chainedValidator ).toHaveReturned();
|
| 39 |
+
expect( chainedValidator ).toHaveReturnedWith( Error( 'The prop `time` is marked as required in `component`, but its value is `null`.' ) );
|
| 40 |
+
} );
|
| 41 |
+
|
| 42 |
+
it( 'should call the validator when prop is provided, not undefined or null, and is not required', () => {
|
| 43 |
+
const props = {
|
| 44 |
+
time: '15:34',
|
| 45 |
+
};
|
| 46 |
+
const validator = jest.fn( noop );
|
| 47 |
+
const chainedValidator = jest.fn( proptypes.createChainableValidator( validator ) );
|
| 48 |
+
chainedValidator( props, 'time', 'component' );
|
| 49 |
+
|
| 50 |
+
expect( validator ).toHaveBeenCalled();
|
| 51 |
+
expect( validator ).toHaveBeenCalledTimes( 1 );
|
| 52 |
+
} );
|
| 53 |
+
|
| 54 |
+
it( 'should call the validator when prop is provided, not undefined or null, and is required', () => {
|
| 55 |
+
const props = {
|
| 56 |
+
time: '15:34',
|
| 57 |
+
};
|
| 58 |
+
const validator = jest.fn( noop );
|
| 59 |
+
const chainedValidator = jest.fn( proptypes.createChainableValidator( validator ).isRequired );
|
| 60 |
+
chainedValidator( props, 'time', 'component' );
|
| 61 |
+
|
| 62 |
+
expect( validator ).toHaveBeenCalled();
|
| 63 |
+
expect( validator ).toHaveBeenCalledTimes( 1 );
|
| 64 |
+
} );
|
| 65 |
+
} );
|
| 66 |
+
|
| 67 |
+
describe( 'timeRegex', () => {
|
| 68 |
+
it( 'should return true when provided proper time formatted string', () => {
|
| 69 |
+
expect( proptypes.timeRegex.test( '00:00' ) ).toEqual( true );
|
| 70 |
+
expect( proptypes.timeRegex.test( '23:59' ) ).toEqual( true );
|
| 71 |
+
expect( proptypes.timeRegex.test( '12:42' ) ).toEqual( true );
|
| 72 |
+
expect( proptypes.timeRegex.test( '03:01' ) ).toEqual( true );
|
| 73 |
+
expect( proptypes.timeRegex.test( '19:47' ) ).toEqual( true );
|
| 74 |
+
expect( proptypes.timeRegex.test( '05:56' ) ).toEqual( true );
|
| 75 |
+
expect( proptypes.timeRegex.test( '14:11' ) ).toEqual( true );
|
| 76 |
+
} );
|
| 77 |
+
|
| 78 |
+
it( 'should return false when not provided proper time formatted string', () => {
|
| 79 |
+
expect( proptypes.timeRegex.test( 'random string' ) ).toEqual( false );
|
| 80 |
+
expect( proptypes.timeRegex.test( '-00:00' ) ).toEqual( false );
|
| 81 |
+
expect( proptypes.timeRegex.test( '24:00' ) ).toEqual( false );
|
| 82 |
+
expect( proptypes.timeRegex.test( '00:60' ) ).toEqual( false );
|
| 83 |
+
expect( proptypes.timeRegex.test( '24:60' ) ).toEqual( false );
|
| 84 |
+
expect( proptypes.timeRegex.test( '75:93' ) ).toEqual( false );
|
| 85 |
+
expect( proptypes.timeRegex.test( '90:90' ) ).toEqual( false );
|
| 86 |
+
} );
|
| 87 |
+
} );
|
| 88 |
+
|
| 89 |
+
describe( 'timeFormat', () => {
|
| 90 |
+
it( 'should not return an error when provided proper time formatted string', () => {
|
| 91 |
+
const props = {
|
| 92 |
+
time: '15:34',
|
| 93 |
+
};
|
| 94 |
+
const timeFormat = jest.fn( () => proptypes.timeFormat( props, 'time', 'component' ) );
|
| 95 |
+
timeFormat();
|
| 96 |
+
|
| 97 |
+
expect( timeFormat ).toHaveReturned();
|
| 98 |
+
expect( timeFormat ).toHaveReturnedWith( null );
|
| 99 |
+
} );
|
| 100 |
+
|
| 101 |
+
it( 'should return an error when not provided a string', () => {
|
| 102 |
+
const props = {
|
| 103 |
+
time: true,
|
| 104 |
+
};
|
| 105 |
+
const timeFormat = jest.fn( () => proptypes.timeFormat( props, 'time', 'component' ) );
|
| 106 |
+
timeFormat();
|
| 107 |
+
|
| 108 |
+
expect( timeFormat ).toHaveReturned();
|
| 109 |
+
expect( timeFormat ).toHaveReturnedWith( Error( 'Invalid prop `time` of type `boolean` supplied to `component`, expected `string`.' ) );
|
| 110 |
+
} );
|
| 111 |
+
|
| 112 |
+
it( 'should return an error when not provided proper time format', () => {
|
| 113 |
+
const props = {
|
| 114 |
+
time: 'random string',
|
| 115 |
+
};
|
| 116 |
+
const timeFormat = jest.fn( () => proptypes.timeFormat( props, 'time', 'component' ) );
|
| 117 |
+
timeFormat();
|
| 118 |
+
|
| 119 |
+
expect( timeFormat ).toHaveReturned();
|
| 120 |
+
expect( timeFormat ).toHaveReturnedWith( Error( 'Invalid prop `time` format supplied to `component`, expected `hh:mm`.' ) );
|
| 121 |
+
} );
|
| 122 |
+
} );
|
| 123 |
+
|
| 124 |
+
describe( 'nullType', () => {
|
| 125 |
+
test( 'valid prop types', () => {
|
| 126 |
+
const props = {
|
| 127 |
+
name: null,
|
| 128 |
+
}
|
| 129 |
+
const format = jest.fn( () => proptypes.nullType( props, 'name', 'Test Type' ) );
|
| 130 |
+
format();
|
| 131 |
+
expect( format ).toHaveReturned();
|
| 132 |
+
expect( format ).toHaveReturnedWith( undefined );
|
| 133 |
+
} );
|
| 134 |
+
|
| 135 |
+
test( 'invalid prop types', () => {
|
| 136 |
+
const props = {
|
| 137 |
+
name: 'Modern Tribe',
|
| 138 |
+
}
|
| 139 |
+
const format = jest.fn( () => proptypes.nullType( props, 'name', 'Test Type' ) );
|
| 140 |
+
format();
|
| 141 |
+
expect( format ).toHaveReturned();
|
| 142 |
+
expect( format ).toHaveReturnedWith( Error( 'Invalid prop: `name` supplied to `Test Type`, expect null.') );
|
| 143 |
+
} );
|
| 144 |
+
} );
|
| 145 |
+
} );
|
common/src/modules/utils/__tests__/range.test.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* Internal dependencies
|
| 3 |
+
*/
|
| 4 |
+
import {
|
| 5 |
+
parseChars,
|
| 6 |
+
extractParts,
|
| 7 |
+
parser,
|
| 8 |
+
isFree,
|
| 9 |
+
} from '@moderntribe/common/utils/range';
|
| 10 |
+
|
| 11 |
+
describe( 'Tests for range.js', () => {
|
| 12 |
+
test( 'parseChars', () => {
|
| 13 |
+
expect( parseChars( '' ) ).toEqual( '' );
|
| 14 |
+
expect( parseChars( '12312312321321 123123123123' ) ).toEqual( '12312312321321 123123123123' );
|
| 15 |
+
expect( parseChars( '1"$!%$&/)=(=?^^Ǩ¨_:;' ) ).toEqual( '1' );
|
| 16 |
+
expect( parseChars( ',.-¨¨*^^?=)(/&%$·"!ª12' ) ).toEqual( ',.-12' );
|
| 17 |
+
expect( parseChars( '1-2-3-!"·$%&4-5-6$,.-' ) ).toEqual( '1-2-3-4-5-6,.-' );
|
| 18 |
+
} );
|
| 19 |
+
|
| 20 |
+
test( 'extractParts', () => {
|
| 21 |
+
expect( extractParts( '' ) ).toEqual( [] );
|
| 22 |
+
expect( extractParts( '12' ) ).toEqual( [ '12' ] );
|
| 23 |
+
expect( extractParts( '12 - 23' ) ).toEqual( [ '12', '23' ] );
|
| 24 |
+
expect( extractParts( '12.23 - ' ) ).toEqual( [ '12.23' ] );
|
| 25 |
+
expect( extractParts( '12.23 - 5,10' ) ).toEqual( [ '12.23', '5.10' ] );
|
| 26 |
+
expect( extractParts( '12.23 - - - - - 5,10' ) ).toEqual( [ '12.23', '5.10' ] );
|
| 27 |
+
expect( extractParts( '- - - - - 12.23 - 5,10' ) ).toEqual( [ '12.23', '5.10' ] );
|
| 28 |
+
expect( extractParts( '......,,,,12.23 - 5,10' ) ).toEqual( [ '12.23', '5.10' ] );
|
| 29 |
+
expect( extractParts( '.12.23 - 5,10.....,,,,' ) ).toEqual( [ '12.23', '5.10' ] );
|
| 30 |
+
expect( extractParts( '12.2.....3 ,-. 5,10' ) ).toEqual( [ '12.20', '5.10' ] );
|
| 31 |
+
expect( extractParts( '1-2-3-!"·$%&4-5-6$,.-' ) ).toEqual( [ '1', '2' ] );
|
| 32 |
+
expect( extractParts( '12.23 ,-. ----5,,,,,,10' ) ).toEqual( [ '12.23', '5' ] );
|
| 33 |
+
} );
|
| 34 |
+
|
| 35 |
+
test( 'parser', () => {
|
| 36 |
+
expect( parser( '' ) ).toEqual( '' );
|
| 37 |
+
expect( parser( 'cupidatat occaecat' ) ).toEqual( '' );
|
| 38 |
+
expect( parser( 'cupidatat 12 occaecat - 1,2' ) ).toEqual( '1.20 - 12' );
|
| 39 |
+
expect( parser( '1,2 cupidatat 12 occaecat' ) ).toEqual( '1.20' );
|
| 40 |
+
expect( parser( '1-2-1-1-1-1' ) ).toEqual( '1 - 2' );
|
| 41 |
+
expect( parser( '......,,,,12.23 - 5,10' ) ).toEqual( '5.10 - 12.23' );
|
| 42 |
+
expect( parser( '2.2.....3 ,-. 2,10' ) ).toEqual( '2.10 - 2.20' );
|
| 43 |
+
expect( parser( '12.23 ,-. ----5,,,,,,10' ) ).toEqual( '5 - 12.23' );
|
| 44 |
+
expect( parser( '1-2-3-!"·$%&4-5-6$,.-' ) ).toEqual( '1 - 2' );
|
| 45 |
+
expect( parser( ',.-¨¨*^^?=)(/&%$·"!ª12' ) ).toEqual( '12' );
|
| 46 |
+
expect( parser( '10 - 10' ) ).toEqual( '10' );
|
| 47 |
+
expect( parser( '0' ) ).toEqual( '' );
|
| 48 |
+
expect( parser( '0.0' ) ).toEqual( '' );
|
| 49 |
+
expect( parser( '0 -' ) ).toEqual( '' );
|
| 50 |
+
expect( parser( '0 - 0' ) ).toEqual( '' );
|
| 51 |
+
expect( parser( '0.0 - 0' ) ).toEqual( '' );
|
| 52 |
+
expect( parser( '0.0 - 0.5' ) ).toEqual( '0.00 - 0.50' );
|
| 53 |
+
} );
|
| 54 |
+
|
| 55 |
+
test( 'isFree', () => {
|
| 56 |
+
expect( isFree( '' ) ).toEqual( false );
|
| 57 |
+
expect( isFree( '0.12' ) ).toEqual( false );
|
| 58 |
+
expect( isFree( '0 - 0.12' ) ).toEqual( false );
|
| 59 |
+
expect( isFree( '0.12 - 0' ) ).toEqual( false );
|
| 60 |
+
expect( isFree( '0' ) ).toEqual( true );
|
| 61 |
+
expect( isFree( '0.0' ) ).toEqual( true );
|
| 62 |
+
expect( isFree( '0 - 0' ) ).toEqual( true );
|
| 63 |
+
expect( isFree( '0.0 - 0.0' ) ).toEqual( true );
|
| 64 |
+
} );
|
| 65 |
+
} );
|
common/src/modules/utils/__tests__/slide.test.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* Internal dependencies
|
| 3 |
+
*/
|
| 4 |
+
import { checkRequestIds } from '@moderntribe/common/utils/slide';
|
| 5 |
+
|
| 6 |
+
describe( 'Tests for slide.js', () => {
|
| 7 |
+
it( 'should return null for up and down', () => {
|
| 8 |
+
const ids = checkRequestIds( 'test-id' );
|
| 9 |
+
expect( ids.up ).toEqual( null );
|
| 10 |
+
expect( ids.down ).toEqual( null );
|
| 11 |
+
} );
|
| 12 |
+
} );
|
common/src/modules/utils/__tests__/string.test.js
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* Internal dependencies
|
| 3 |
+
*/
|
| 4 |
+
import {
|
| 5 |
+
isTruthy,
|
| 6 |
+
isFalsy,
|
| 7 |
+
replaceWithObject,
|
| 8 |
+
getWords,
|
| 9 |
+
wordsAsList,
|
| 10 |
+
normalize,
|
| 11 |
+
toBlockName,
|
| 12 |
+
} from '@moderntribe/common/utils/string';
|
| 13 |
+
|
| 14 |
+
describe( 'Tests for string.js', () => {
|
| 15 |
+
test( 'isTruthy', () => {
|
| 16 |
+
expect( isTruthy( 'Sample string' ) ).toEqual( false );
|
| 17 |
+
expect( isTruthy( '0' ) ).toEqual( false );
|
| 18 |
+
expect( isTruthy( 'false' ) ).toEqual( false );
|
| 19 |
+
expect( isTruthy( '1' ) ).toEqual( true );
|
| 20 |
+
expect( isTruthy( 'yes' ) ).toEqual( true );
|
| 21 |
+
expect( isTruthy( 'true' ) ).toEqual( true );
|
| 22 |
+
} );
|
| 23 |
+
|
| 24 |
+
test( 'isFalsy', () => {
|
| 25 |
+
expect( isFalsy( 'Sample string' ) ).toEqual( false );
|
| 26 |
+
expect( isFalsy( '1' ) ).toEqual( false );
|
| 27 |
+
expect( isFalsy( 'true' ) ).toEqual( false );
|
| 28 |
+
expect( isFalsy( '' ) ).toEqual( true );
|
| 29 |
+
expect( isFalsy( '0' ) ).toEqual( true );
|
| 30 |
+
expect( isFalsy( 'no' ) ).toEqual( true );
|
| 31 |
+
expect( isFalsy( 'false' ) ).toEqual( true );
|
| 32 |
+
} );
|
| 33 |
+
|
| 34 |
+
test( 'replaceWithObject', () => {
|
| 35 |
+
expect( replaceWithObject() ).toEqual( '' );
|
| 36 |
+
expect( replaceWithObject( '', {} ) ).toEqual( '' );
|
| 37 |
+
expect( replaceWithObject( 'abcd' ) ).toEqual( 'abcd' );
|
| 38 |
+
expect( replaceWithObject( 'abcd', { z: 'a' } ) ).toEqual( 'abcd' );
|
| 39 |
+
expect( replaceWithObject( 'abcd', { a: 'b', c: 'd' } ) ).toEqual( 'bbdd' );
|
| 40 |
+
expect( replaceWithObject( 'abcd', { a: '', c: '' } ) ).toEqual( 'bd' );
|
| 41 |
+
} );
|
| 42 |
+
|
| 43 |
+
describe( 'getWords', () => {
|
| 44 |
+
test( 'when strings are formed correctly', () => {
|
| 45 |
+
expect( getWords( 'Modern Tribe' ) ).toEqual( [ 'Modern', 'Tribe' ] );
|
| 46 |
+
expect( getWords( 'The Next Generation of Digital Agency' ) )
|
| 47 |
+
.toEqual( [ 'The', 'Next', 'Generation', 'of', 'Digital', 'Agency' ] );
|
| 48 |
+
expect( getWords( 'A list with numbers: 1, 2, 3' ) )
|
| 49 |
+
.toEqual( [ 'A', 'list', 'with', 'numbers:', '1,', '2,', '3' ] );
|
| 50 |
+
} );
|
| 51 |
+
|
| 52 |
+
test( 'Words with multiple spaces on it', () => {
|
| 53 |
+
expect( getWords( ' Modern Tribe ' ) ).toEqual( [ 'Modern', 'Tribe' ] );
|
| 54 |
+
} );
|
| 55 |
+
} );
|
| 56 |
+
|
| 57 |
+
describe( 'applySeparatorsAsCheckboxList', () => {
|
| 58 |
+
test( 'Single word no separator is applied', () => {
|
| 59 |
+
expect( wordsAsList( [ 'Modern' ] ) ).toEqual( 'Modern' );
|
| 60 |
+
} );
|
| 61 |
+
|
| 62 |
+
test( 'Two words last separator is applied', () => {
|
| 63 |
+
expect( wordsAsList( getWords( 'Modern Tribe' ) ) ).toEqual( 'Modern & Tribe' );
|
| 64 |
+
expect( wordsAsList( getWords( 'Events Calendar' ), ',', ' - ' ) )
|
| 65 |
+
.toEqual( 'Events - Calendar' );
|
| 66 |
+
} );
|
| 67 |
+
|
| 68 |
+
test( 'A large number of words', () => {
|
| 69 |
+
expect(
|
| 70 |
+
wordsAsList( [ 'Dog', 'Cat', 'Hamster', 'Parrot', 'Spider', 'Goldfish' ] ),
|
| 71 |
+
).toEqual( 'Dog, Cat, Hamster, Parrot, Spider & Goldfish' );
|
| 72 |
+
} );
|
| 73 |
+
|
| 74 |
+
test( 'Custom separators', () => {
|
| 75 |
+
expect(
|
| 76 |
+
wordsAsList( [ 'Dog', 'Cat', 'Hamster', 'Parrot', 'Spider', 'Goldfish' ], ' - ', ' => ' ),
|
| 77 |
+
).toEqual( 'Dog - Cat - Hamster - Parrot - Spider => Goldfish' );
|
| 78 |
+
} );
|
| 79 |
+
} );
|
| 80 |
+
|
| 81 |
+
describe( 'normalize', () => {
|
| 82 |
+
test( 'single words', () => {
|
| 83 |
+
expect( normalize( 'modern' ) ).toEqual( 'modern' );
|
| 84 |
+
expect( normalize( 'TRIBE' ) ).toEqual( 'tribe' );
|
| 85 |
+
} );
|
| 86 |
+
|
| 87 |
+
test( 'multiple words', () => {
|
| 88 |
+
expect( normalize( 'Modern Tribe' ) ).toEqual( 'modern-tribe' );
|
| 89 |
+
expect( normalize( 'https://theeventscalendar.com/' ) )
|
| 90 |
+
.toEqual( 'httpstheeventscalendarcom' );
|
| 91 |
+
} );
|
| 92 |
+
|
| 93 |
+
test( 'Multiple spaces', () => {
|
| 94 |
+
expect( normalize( ' modern TriBe' ) ).toEqual( 'modern-tribe' );
|
| 95 |
+
} );
|
| 96 |
+
|
| 97 |
+
test( 'non words', () => {
|
| 98 |
+
expect( normalize( ' 12312321-,-.(()=^^ ¨¨:;:_¨¨Ç *¿?=)(/&%$·"!.+' ) ).toEqual( '' );
|
| 99 |
+
} );
|
| 100 |
+
|
| 101 |
+
test( 'non strings types', () => {
|
| 102 |
+
expect( normalize( undefined ) ).toBe( '' );
|
| 103 |
+
expect( normalize( [] ) ).toBe( '' );
|
| 104 |
+
expect( normalize( [] ) ).toBe( '' );
|
| 105 |
+
expect( normalize( null ) ).toBe( '' );
|
| 106 |
+
expect( normalize( 1 ) ).toBe( '' );
|
| 107 |
+
} );
|
| 108 |
+
} );
|
| 109 |
+
|
| 110 |
+
describe( 'toBlockName', () => {
|
| 111 |
+
test( 'words', () => {
|
| 112 |
+
expect( toBlockName( 'modern tribe' ) )
|
| 113 |
+
.toBe( 'moderntribe' );
|
| 114 |
+
expect( toBlockName( 'https://theeventscalendar.com/' ) )
|
| 115 |
+
.toBe( 'httpstheeventscalendarcom' );
|
| 116 |
+
} );
|
| 117 |
+
|
| 118 |
+
test( 'non valid characters of a block', () => {
|
| 119 |
+
expect( toBlockName( '_ecp_custom_2' ) ).toBe( 'ecpcustom2' );
|
| 120 |
+
expect( toBlockName( 'ecp-custom-2' ) ).toBe( 'ecp-custom-2' );
|
| 121 |
+
expect( toBlockName( '„…–~~}][‚|#¢∞ecp-custom-2;:_¨¨Ç¨^^=)(/&%$·"!' ) )
|
| 122 |
+
.toBe( 'ecp-custom-2' );
|
| 123 |
+
expect( toBlockName( '„…– ~~}] [‚|#¢∞ecp-custom-2;:_¨ ¨Ç¨^^=)(/ &%$·"!' ) )
|
| 124 |
+
.toBe( 'ecp-custom-2' );
|
| 125 |
+
} );
|
| 126 |
+
|
| 127 |
+
test( 'non strings types', () => {
|
| 128 |
+
expect( toBlockName( undefined ) ).toBe( '' );
|
| 129 |
+
expect( toBlockName( [] ) ).toBe( '' );
|
| 130 |
+
expect( toBlockName( [] ) ).toBe( '' );
|
| 131 |
+
expect( toBlockName( null ) ).toBe( '' );
|
| 132 |
+
expect( toBlockName( 1 ) ).toBe( '' );
|
| 133 |
+
} );
|
| 134 |
+
} );
|
| 135 |
+
} );
|
common/src/modules/utils/__tests__/time.test.js
ADDED
|
@@ -0,0 +1,222 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* Internal dependencies
|
| 3 |
+
*/
|
| 4 |
+
import { time } from '@moderntribe/common/utils';
|
| 5 |
+
import { roundTime } from '../moment';
|
| 6 |
+
|
| 7 |
+
describe( 'Tests for time.js', () => {
|
| 8 |
+
test( 'MINUTE_IN_SECONDS', () => {
|
| 9 |
+
expect( time.MINUTE_IN_SECONDS ).toEqual( 60 );
|
| 10 |
+
} );
|
| 11 |
+
|
| 12 |
+
test( 'HALF_HOUR_IN_SECONDS', () => {
|
| 13 |
+
expect( time.HALF_HOUR_IN_SECONDS ).toEqual( 1800 );
|
| 14 |
+
} );
|
| 15 |
+
|
| 16 |
+
test( 'HOUR_IN_SECONDS', () => {
|
| 17 |
+
expect( time.HOUR_IN_SECONDS ).toEqual( 3600 );
|
| 18 |
+
} );
|
| 19 |
+
|
| 20 |
+
test( 'DAY_IN_SECONDS', () => {
|
| 21 |
+
expect( time.DAY_IN_SECONDS ).toEqual( 86400 );
|
| 22 |
+
} );
|
| 23 |
+
|
| 24 |
+
test( 'roundTime', () => {
|
| 25 |
+
expect( time.roundTime( '01:23:54.423', time.TIME_FORMAT_HH_MM_SS_SSS ) )
|
| 26 |
+
.toEqual( '01:00:00.000' );
|
| 27 |
+
expect( time.roundTime( '14:46:13.042', time.TIME_FORMAT_HH_MM_SS_SSS ) )
|
| 28 |
+
.toEqual( '14:30:00.000' );
|
| 29 |
+
expect( time.roundTime( '01:23:54', time.TIME_FORMAT_HH_MM_SS ) )
|
| 30 |
+
.toEqual( '01:00:00' );
|
| 31 |
+
expect( time.roundTime( '14:46:13', time.TIME_FORMAT_HH_MM_SS ) )
|
| 32 |
+
.toEqual( '14:30:00' );
|
| 33 |
+
expect( time.roundTime( '01:23', time.TIME_FORMAT_HH_MM ) )
|
| 34 |
+
.toEqual( '01:00' );
|
| 35 |
+
expect( time.roundTime( '14:46', time.TIME_FORMAT_HH_MM ) )
|
| 36 |
+
.toEqual( '14:30' );
|
| 37 |
+
expect( time.roundTime( '23:54.423', time.TIME_FORMAT_MM_SS_SSS ) )
|
| 38 |
+
.toEqual( '00:00.000' );
|
| 39 |
+
expect( time.roundTime( '46:13.042', time.TIME_FORMAT_MM_SS_SSS ) )
|
| 40 |
+
.toEqual( '30:00.000' );
|
| 41 |
+
expect( time.roundTime( '23:54', time.TIME_FORMAT_MM_SS ) )
|
| 42 |
+
.toEqual( '00:00' );
|
| 43 |
+
expect( time.roundTime( '46:13', time.TIME_FORMAT_MM_SS ) )
|
| 44 |
+
.toEqual( '30:00' );
|
| 45 |
+
} );
|
| 46 |
+
|
| 47 |
+
test( 'START_OF_DAY', () => {
|
| 48 |
+
expect( time.START_OF_DAY ).toEqual( '00:00' );
|
| 49 |
+
} );
|
| 50 |
+
|
| 51 |
+
test( 'END_OF_DAY', () => {
|
| 52 |
+
expect( time.END_OF_DAY ).toEqual( '23:59' );
|
| 53 |
+
} );
|
| 54 |
+
|
| 55 |
+
test( 'TIME_FORMAT_HH_MM_SS_SSS', () => {
|
| 56 |
+
expect( time.TIME_FORMAT_HH_MM_SS_SSS ).toEqual( 'hh:mm:ss.sss' );
|
| 57 |
+
} );
|
| 58 |
+
|
| 59 |
+
test( 'TIME_FORMAT_HH_MM_SS', () => {
|
| 60 |
+
expect( time.TIME_FORMAT_HH_MM_SS ).toEqual( 'hh:mm:ss' );
|
| 61 |
+
} );
|
| 62 |
+
|
| 63 |
+
test( 'TIME_FORMAT_HH_MM', () => {
|
| 64 |
+
expect( time.TIME_FORMAT_HH_MM ).toEqual( 'hh:mm' );
|
| 65 |
+
} );
|
| 66 |
+
|
| 67 |
+
test( 'TIME_FORMAT_MM_SS_SSS', () => {
|
| 68 |
+
expect( time.TIME_FORMAT_MM_SS_SSS ).toEqual( 'mm:ss.sss' );
|
| 69 |
+
} );
|
| 70 |
+
|
| 71 |
+
test( 'TIME_FORMAT_MM_SS', () => {
|
| 72 |
+
expect( time.TIME_FORMAT_MM_SS ).toEqual( 'mm:ss' );
|
| 73 |
+
} );
|
| 74 |
+
|
| 75 |
+
test( 'HOUR_IN_MS', () => {
|
| 76 |
+
expect( time.HOUR_IN_MS ).toEqual( 3600000 );
|
| 77 |
+
} );
|
| 78 |
+
|
| 79 |
+
test( 'MINUTE_IN_MS', () => {
|
| 80 |
+
expect( time.MINUTE_IN_MS ).toEqual( 60000 );
|
| 81 |
+
} );
|
| 82 |
+
|
| 83 |
+
test( 'SECOND_IN_MS', () => {
|
| 84 |
+
expect( time.SECOND_IN_MS ).toEqual( 1000 );
|
| 85 |
+
} );
|
| 86 |
+
|
| 87 |
+
/**
|
| 88 |
+
* Below are tests copied from the hh-mm-ss library and adjusted to use
|
| 89 |
+
* Jest instead of Tape for testing.
|
| 90 |
+
* Link: https://github.com/Goldob/hh-mm-ss/blob/master/test/index.js
|
| 91 |
+
*/
|
| 92 |
+
test( 'fromMilliseconds() test', () => {
|
| 93 |
+
// Basic functionality
|
| 94 |
+
expect( time.fromMilliseconds( 75000 ) ).toEqual( '01:15' );
|
| 95 |
+
expect( time.fromMilliseconds( 442800000 ) ).toEqual( '123:00:00' );
|
| 96 |
+
expect( time.fromMilliseconds( 90576 ) ).toEqual( '01:30.576' );
|
| 97 |
+
expect( time.fromMilliseconds( -157250 ) ).toEqual( '-02:37.250' );
|
| 98 |
+
|
| 99 |
+
// Output formatting
|
| 100 |
+
expect( time.fromMilliseconds( 38000, 'mm:ss.sss' ) ).toEqual( '00:38.000' );
|
| 101 |
+
expect( time.fromMilliseconds( 0, 'hh:mm:ss' ) ).toEqual( '00:00:00' );
|
| 102 |
+
expect( time.fromMilliseconds( 3600000, 'mm:ss' ) ).toEqual( '01:00:00' );
|
| 103 |
+
expect( time.fromMilliseconds( 4500000, 'hh:mm' ) ).toEqual( '01:15' );
|
| 104 |
+
expect( time.fromMilliseconds( -9900000, 'hh:mm' ) ).toEqual( '-02:45' );
|
| 105 |
+
|
| 106 |
+
// Input validation
|
| 107 |
+
expect( () => time.fromMilliseconds( null ) ).toThrowErrorMatchingSnapshot();
|
| 108 |
+
expect( () => time.fromMilliseconds('text') ).toThrowErrorMatchingSnapshot();
|
| 109 |
+
expect( () => time.fromMilliseconds(0, 'mm:hh:ss') ).toThrowErrorMatchingSnapshot();
|
| 110 |
+
} );
|
| 111 |
+
|
| 112 |
+
test( 'fromSeconds() test', () => {
|
| 113 |
+
// Basic functionality
|
| 114 |
+
expect( time.fromSeconds( 75 ) ).toEqual( '01:15' );
|
| 115 |
+
expect( time.fromSeconds( 442800 ) ).toEqual( '123:00:00' );
|
| 116 |
+
expect( time.fromSeconds( -442800 ) ).toEqual( '-123:00:00' );
|
| 117 |
+
|
| 118 |
+
// Output formatting
|
| 119 |
+
expect( time.fromSeconds( 38, 'mm:ss.sss' ) ).toEqual( '00:38.000' );
|
| 120 |
+
expect( time.fromSeconds( 0, 'hh:mm:ss' ) ).toEqual( '00:00:00' );
|
| 121 |
+
expect( time.fromSeconds( 3600, 'mm:ss' ) ).toEqual( '01:00:00' );
|
| 122 |
+
expect( time.fromSeconds( 4500, 'hh:mm' ) ).toEqual( '01:15' );
|
| 123 |
+
expect( time.fromSeconds( -9900, 'hh:mm' ) ).toEqual( '-02:45' );
|
| 124 |
+
|
| 125 |
+
// Input validation
|
| 126 |
+
expect( () => time.fromSeconds( null ) ).toThrowErrorMatchingSnapshot();
|
| 127 |
+
expect( () => time.fromSeconds( 'text' ) ).toThrowErrorMatchingSnapshot();
|
| 128 |
+
expect( () => time.fromSeconds( 0, 'mm:hh:ss' ) ).toThrowErrorMatchingSnapshot();
|
| 129 |
+
} );
|
| 130 |
+
|
| 131 |
+
test( 'toMilliseconds() test', () => {
|
| 132 |
+
// Basic functionality
|
| 133 |
+
expect( time.toMilliseconds( '01:05:17' ) ).toEqual( 3917000 );
|
| 134 |
+
expect( time.toMilliseconds( '137:00:00.0' ) ).toEqual( 493200000 );
|
| 135 |
+
expect( time.toMilliseconds( '00:10.230' ) ).toEqual( 10230 );
|
| 136 |
+
expect( time.toMilliseconds( '00:00:07.10845' ) ).toEqual( 7108 );
|
| 137 |
+
expect( time.toMilliseconds( '-02:07:12' ) ).toEqual( -7632000 );
|
| 138 |
+
expect( time.toMilliseconds( '02:00' ) ).toEqual( 120000 );
|
| 139 |
+
expect( time.toMilliseconds( '02:00', 'hh:mm' ) ).toEqual( 7200000 );
|
| 140 |
+
expect( time.toMilliseconds( '-04:35', 'hh:mm' ) ).toEqual( -16500000 );
|
| 141 |
+
expect( time.toMilliseconds( '00:00:07.10845', 'hh:mm' ) ).toEqual( 7108 );
|
| 142 |
+
|
| 143 |
+
// Input validation
|
| 144 |
+
expect( () => time.toMilliseconds( '13:05:02:11' ) ).toThrowErrorMatchingSnapshot();
|
| 145 |
+
expect( () => time.toMilliseconds( '153' ) ).toThrowErrorMatchingSnapshot();
|
| 146 |
+
expect( () => time.toMilliseconds( null ) ).toThrowErrorMatchingSnapshot();
|
| 147 |
+
expect( () => time.toMilliseconds( '00:62' ) ).toThrowErrorMatchingSnapshot();
|
| 148 |
+
expect( () => time.toMilliseconds( '01:30', 'mm:hh:ss' ) ).toThrowErrorMatchingSnapshot();
|
| 149 |
+
} );
|
| 150 |
+
|
| 151 |
+
test( 'toSeconds() test', () => {
|
| 152 |
+
// Basic functionality
|
| 153 |
+
expect( time.toSeconds( '01:05:17' ) ).toEqual( 3917 );
|
| 154 |
+
expect( time.toSeconds( '137:00:00.0' ) ).toEqual( 493200 );
|
| 155 |
+
expect( time.toSeconds( '00:10.230' ) ).toEqual( 10 );
|
| 156 |
+
expect( time.toSeconds( '00:00:07.10845' ) ).toEqual( 7 );
|
| 157 |
+
expect( time.toSeconds( '-02:07:12' ) ).toEqual( -7632 );
|
| 158 |
+
expect( time.toSeconds( '02:00' ) ).toEqual( 120 );
|
| 159 |
+
expect( time.toSeconds( '02:00', 'hh:mm' ) ).toEqual( 7200 );
|
| 160 |
+
expect( time.toSeconds( '-04:35', 'hh:mm' ) ).toEqual( -16500 );
|
| 161 |
+
expect( time.toSeconds( '00:00:07.10845', 'hh:mm' ) ).toEqual( 7 );
|
| 162 |
+
|
| 163 |
+
// Input validation
|
| 164 |
+
expect( () => time.toSeconds( '13:05:02:11' ) ).toThrowErrorMatchingSnapshot();
|
| 165 |
+
expect( () => time.toSeconds( '153' ) ).toThrowErrorMatchingSnapshot();
|
| 166 |
+
expect( () => time.toSeconds( null ) ).toThrowErrorMatchingSnapshot();
|
| 167 |
+
expect( () => time.toSeconds( '00:62' ) ).toThrowErrorMatchingSnapshot();
|
| 168 |
+
expect( () => time.toSeconds( '01:30', 'mm:hh:ss' ) ).toThrowErrorMatchingSnapshot();
|
| 169 |
+
} );
|
| 170 |
+
|
| 171 |
+
test( 'symmetrical conversion test', () => {
|
| 172 |
+
/*
|
| 173 |
+
* fromMilliseconds() and toMilliseconds() for all formats
|
| 174 |
+
*/
|
| 175 |
+
|
| 176 |
+
// 90000ms = 1m 30s
|
| 177 |
+
expect( time.toMilliseconds( time.fromMilliseconds( 90000, 'mm:ss' ), 'mm:ss' ) ).toEqual( 90000 );
|
| 178 |
+
expect( time.toMilliseconds( time.fromMilliseconds( 90000, 'mm:ss.sss' ), 'mm:ss.sss' ) ).toEqual( 90000 );
|
| 179 |
+
expect( time.toMilliseconds( time.fromMilliseconds( 90000, 'hh:mm' ), 'hh:mm' ) ).toEqual( 90000 );
|
| 180 |
+
expect( time.toMilliseconds( time.fromMilliseconds( 90000, 'hh:mm:ss' ), 'hh:mm:ss' ) ).toEqual( 90000 );
|
| 181 |
+
expect( time.toMilliseconds( time.fromMilliseconds( 90000, 'hh:mm:ss.sss' ), 'hh:mm:ss.sss' ) ).toEqual( 90000 );
|
| 182 |
+
|
| 183 |
+
// 7517245ms = 2h 5m 17.245s
|
| 184 |
+
expect( time.toMilliseconds( time.fromMilliseconds( 7517245, 'mm:ss' ), 'mm:ss' ) ).toEqual( 7517245 );
|
| 185 |
+
expect( time.toMilliseconds( time.fromMilliseconds( 7517245, 'mm:ss.sss' ), 'mm:ss.sss' ) ).toEqual( 7517245 );
|
| 186 |
+
expect( time.toMilliseconds( time.fromMilliseconds( 7517245, 'hh:mm' ), 'hh:mm' ) ).toEqual( 7517245 );
|
| 187 |
+
expect( time.toMilliseconds( time.fromMilliseconds( 7517245, 'hh:mm:ss' ), 'hh:mm:ss' ) ).toEqual( 7517245 );
|
| 188 |
+
expect( time.toMilliseconds( time.fromMilliseconds( 7517245, 'hh:mm:ss.sss' ), 'hh:mm:ss.sss' ) ).toEqual( 7517245 );
|
| 189 |
+
|
| 190 |
+
// -10800000ms = -3h
|
| 191 |
+
expect( time.toMilliseconds( time.fromMilliseconds( -10800000, 'mm:ss' ), 'mm:ss' ) ).toEqual( -10800000 );
|
| 192 |
+
expect( time.toMilliseconds( time.fromMilliseconds( -10800000, 'mm:ss.sss' ), 'mm:ss.sss' ) ).toEqual( -10800000 );
|
| 193 |
+
expect( time.toMilliseconds( time.fromMilliseconds( -10800000, 'hh:mm' ), 'hh:mm' ) ).toEqual( -10800000 );
|
| 194 |
+
expect( time.toMilliseconds( time.fromMilliseconds( -10800000, 'hh:mm:ss' ), 'hh:mm:ss' ) ).toEqual( -10800000 );
|
| 195 |
+
expect( time.toMilliseconds( time.fromMilliseconds( -10800000, 'hh:mm:ss.sss' ), 'hh:mm:ss.sss' ) ).toEqual( -10800000 );
|
| 196 |
+
|
| 197 |
+
/*
|
| 198 |
+
* fromSeconds() and toMilliseconds() for all formats
|
| 199 |
+
*/
|
| 200 |
+
|
| 201 |
+
// 930s = 15m 30s
|
| 202 |
+
expect( time.toSeconds( time.fromSeconds( 930, 'mm:ss' ), 'mm:ss') ).toEqual( 930 );
|
| 203 |
+
expect( time.toSeconds( time.fromSeconds( 930, 'mm:ss.sss' ), 'mm:ss.sss') ).toEqual( 930 );
|
| 204 |
+
expect( time.toSeconds( time.fromSeconds( 930, 'hh:mm' ), 'hh:mm') ).toEqual( 930 );
|
| 205 |
+
expect( time.toSeconds( time.fromSeconds( 930, 'hh:mm:ss' ), 'hh:mm:ss') ).toEqual( 930 );
|
| 206 |
+
expect( time.toSeconds( time.fromSeconds( 930, 'hh:mm:ss.sss' ), 'hh:mm:ss.sss') ).toEqual( 930 );
|
| 207 |
+
|
| 208 |
+
// 4850s = 1h 20m 50s
|
| 209 |
+
expect( time.toSeconds( time.fromSeconds( 4850, 'mm:ss' ), 'mm:ss') ).toEqual( 4850 );
|
| 210 |
+
expect( time.toSeconds( time.fromSeconds( 4850, 'mm:ss.sss' ), 'mm:ss.sss') ).toEqual( 4850 );
|
| 211 |
+
expect( time.toSeconds( time.fromSeconds( 4850, 'hh:mm' ), 'hh:mm') ).toEqual( 4850 );
|
| 212 |
+
expect( time.toSeconds( time.fromSeconds( 4850, 'hh:mm:ss' ), 'hh:mm:ss') ).toEqual( 4850 );
|
| 213 |
+
expect( time.toSeconds( time.fromSeconds( 4850, 'hh:mm:ss.sss' ), 'hh:mm:ss.sss') ).toEqual( 4850 );
|
| 214 |
+
|
| 215 |
+
// -300s = -5m
|
| 216 |
+
expect( time.toSeconds( time.fromSeconds( -300, 'mm:ss' ), 'mm:ss') ).toEqual( -300 );
|
| 217 |
+
expect( time.toSeconds( time.fromSeconds( -300, 'mm:ss.sss' ), 'mm:ss.sss') ).toEqual( -300 );
|
| 218 |
+
expect( time.toSeconds( time.fromSeconds( -300, 'hh:mm' ), 'hh:mm') ).toEqual( -300 );
|
| 219 |
+
expect( time.toSeconds( time.fromSeconds( -300, 'hh:mm:ss' ), 'hh:mm:ss') ).toEqual( -300 );
|
| 220 |
+
expect( time.toSeconds( time.fromSeconds( -300, 'hh:mm:ss.sss' ), 'hh:mm:ss.sss') ).toEqual( -300 );
|
| 221 |
+
} );
|
| 222 |
+
} );
|
common/src/modules/utils/api.js
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { rest } from '@moderntribe/common/utils/globals';
|
| 2 |
+
import 'whatwg-fetch';
|
| 3 |
+
|
| 4 |
+
/**
|
| 5 |
+
* Send a request into a wp-json endpoint
|
| 6 |
+
*
|
| 7 |
+
* @param {Object} params An object with the following properties:
|
| 8 |
+
* - path: Path for the endpoint
|
| 9 |
+
* - headers: Array of extra headers for the request
|
| 10 |
+
* - initParams: Params send into the fetch along with headers and credentials
|
| 11 |
+
* - namespace: Endpoint namespace default to `wp/v2`
|
| 12 |
+
*
|
| 13 |
+
* @returns {Promise<Response>} return a fetch promise
|
| 14 |
+
*/
|
| 15 |
+
export const wpREST = async ( params ) => {
|
| 16 |
+
const { url = '', nonce = {}, namespaces = {} } = rest();
|
| 17 |
+
|
| 18 |
+
/**
|
| 19 |
+
* @todo refactor this method as for more details look into:
|
| 20 |
+
* - https://github.com/moderntribe/events-gutenberg/pull/346#discussion_r222217138
|
| 21 |
+
*/
|
| 22 |
+
const options = {
|
| 23 |
+
path: '',
|
| 24 |
+
headers: {},
|
| 25 |
+
initParams: {},
|
| 26 |
+
namespace: namespaces.core || 'wp/v2',
|
| 27 |
+
...params,
|
| 28 |
+
};
|
| 29 |
+
|
| 30 |
+
const endpoint = `${ url }${ options.namespace }/${ options.path }`;
|
| 31 |
+
|
| 32 |
+
const headers = {
|
| 33 |
+
'X-WP-Nonce': nonce.wp_rest || '',
|
| 34 |
+
...options.headers,
|
| 35 |
+
};
|
| 36 |
+
|
| 37 |
+
try {
|
| 38 |
+
const response = await fetch( endpoint, {
|
| 39 |
+
...options.initParams,
|
| 40 |
+
credentials: 'include',
|
| 41 |
+
headers,
|
| 42 |
+
} );
|
| 43 |
+
|
| 44 |
+
let data = {};
|
| 45 |
+
|
| 46 |
+
if ( response.ok ) {
|
| 47 |
+
data = await response.json();
|
| 48 |
+
}
|
| 49 |
+
|
| 50 |
+
return {
|
| 51 |
+
response,
|
| 52 |
+
data,
|
| 53 |
+
};
|
| 54 |
+
} catch ( e ) {
|
| 55 |
+
throw e;
|
| 56 |
+
}
|
| 57 |
+
};
|
common/src/modules/utils/date.js
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import { identity } from 'lodash';
|
| 5 |
+
import chrono from 'chrono-node';
|
| 6 |
+
|
| 7 |
+
/**
|
| 8 |
+
* Wordpress dependencies
|
| 9 |
+
*/
|
| 10 |
+
import { __ } from '@wordpress/i18n';
|
| 11 |
+
|
| 12 |
+
/**
|
| 13 |
+
* Internal dependencies
|
| 14 |
+
*/
|
| 15 |
+
import {
|
| 16 |
+
moment as momentUtil,
|
| 17 |
+
timezone as timezoneUtil,
|
| 18 |
+
} from '@moderntribe/common/utils';
|
| 19 |
+
import { dateSettings } from '@moderntribe/common/utils/globals';
|
| 20 |
+
|
| 21 |
+
const formats = dateSettings() && dateSettings().formats ? dateSettings().formats : {};
|
| 22 |
+
const timezone = dateSettings() && dateSettings().formats ? dateSettings().formats : {};
|
| 23 |
+
|
| 24 |
+
export const FORMATS = {
|
| 25 |
+
TIME: 'HH:mm:ss',
|
| 26 |
+
DATE_TIME: 'YYYY-MM-DD HH:mm:ss',
|
| 27 |
+
WP: {
|
| 28 |
+
time: 'g:i a',
|
| 29 |
+
time24Hr: 'H:i',
|
| 30 |
+
date: 'F j, Y',
|
| 31 |
+
datetime: 'F j, Y g:i a',
|
| 32 |
+
dateNoYear: 'F j',
|
| 33 |
+
...formats,
|
| 34 |
+
},
|
| 35 |
+
TIMEZONE: {
|
| 36 |
+
string: 'UTC',
|
| 37 |
+
...timezone,
|
| 38 |
+
},
|
| 39 |
+
DATABASE: {
|
| 40 |
+
date: 'Y-m-d',
|
| 41 |
+
datetime: 'Y-m-d H:i:s',
|
| 42 |
+
time: 'H:i:s',
|
| 43 |
+
},
|
| 44 |
+
};
|
| 45 |
+
|
| 46 |
+
export const TODAY = new Date();
|
| 47 |
+
|
| 48 |
+
export const timezonesAsSelectData = () => {
|
| 49 |
+
return timezones().map( ( tzone ) => ( {
|
| 50 |
+
value: tzone.key,
|
| 51 |
+
label: tzone.text,
|
| 52 |
+
} ) );
|
| 53 |
+
};
|
| 54 |
+
|
| 55 |
+
export const timezones = () => {
|
| 56 |
+
return timezoneUtil.getItems()
|
| 57 |
+
.map( ( group ) => group.options || [] )
|
| 58 |
+
.reduce( ( prev, current ) => [ ...prev, ...current ], [] );
|
| 59 |
+
};
|
| 60 |
+
|
| 61 |
+
export const toNaturalLanguage = ( params = {} ) => {
|
| 62 |
+
const options = {
|
| 63 |
+
date: null,
|
| 64 |
+
format: {
|
| 65 |
+
month: 'MMMM',
|
| 66 |
+
day: 'D',
|
| 67 |
+
year: 'YYYY',
|
| 68 |
+
time: momentUtil.toFormat( FORMATS.WP.time ),
|
| 69 |
+
},
|
| 70 |
+
separator: '',
|
| 71 |
+
...params,
|
| 72 |
+
};
|
| 73 |
+
|
| 74 |
+
const parsed = {
|
| 75 |
+
text: '',
|
| 76 |
+
moment: options.date && momentUtil.toMoment( options.date ),
|
| 77 |
+
detail: {
|
| 78 |
+
day: '',
|
| 79 |
+
month: '',
|
| 80 |
+
year: '',
|
| 81 |
+
time: '',
|
| 82 |
+
},
|
| 83 |
+
isValid: false,
|
| 84 |
+
};
|
| 85 |
+
|
| 86 |
+
parsed.isValid = Boolean( parsed.moment && parsed.moment.isValid() );
|
| 87 |
+
|
| 88 |
+
if ( parsed.isValid ) {
|
| 89 |
+
parsed.detail = {
|
| 90 |
+
month: `${ parsed.moment.format( options.format.month ) }`,
|
| 91 |
+
day: `${ parsed.moment.format( options.format.day ) }`,
|
| 92 |
+
year: `${ parsed.moment.format( options.format.year ) }`,
|
| 93 |
+
time: `${ parsed.moment.format( options.format.time ) }`,
|
| 94 |
+
};
|
| 95 |
+
const { detail } = parsed;
|
| 96 |
+
parsed.text = `${ detail.month } ${ detail.day } ${ detail.year } ${ options.separator } ${ detail.time }`;
|
| 97 |
+
}
|
| 98 |
+
return parsed;
|
| 99 |
+
};
|
| 100 |
+
|
| 101 |
+
export const rangeToNaturalLanguage = ( start = '', end = '', separators = {} ) => {
|
| 102 |
+
const separatorOptions = {
|
| 103 |
+
time: __( 'at', 'tribe-common' ),
|
| 104 |
+
date: ' - ',
|
| 105 |
+
...separators,
|
| 106 |
+
};
|
| 107 |
+
const from = toNaturalLanguage( { date: start, separator: separatorOptions.time } );
|
| 108 |
+
const to = toNaturalLanguage( { date: end, separator: separatorOptions.time } );
|
| 109 |
+
const parts = [ from.text ];
|
| 110 |
+
|
| 111 |
+
if ( from.isValid && to.isValid ) {
|
| 112 |
+
if ( momentUtil.isSameDay( from.moment, to.moment ) ) {
|
| 113 |
+
/**
|
| 114 |
+
* If both dates are happening on the same day the only relevant thing is the time on the second
|
| 115 |
+
* part of the string (to keep string cleaner).
|
| 116 |
+
*
|
| 117 |
+
* - Current behavior 'Oct 8 2018 at 12:00 pm - Oct 8 2018 at 12:30 pm'
|
| 118 |
+
* - New behavior: 'Oct 8 2018 at 12:00 pm - 12:30 pm'
|
| 119 |
+
*/
|
| 120 |
+
parts.push( to.detail.time );
|
| 121 |
+
} else if ( momentUtil.isSameMonth( from.moment, to.moment ) ) {
|
| 122 |
+
/**
|
| 123 |
+
* If both dates are happening on the same month and not on the same day but during the same year
|
| 124 |
+
* we don't need to show the same year twice.
|
| 125 |
+
*
|
| 126 |
+
* - Current Behavior: 'Oct 8 2018 at 12:00 pm - Oct 24 2018 12:30 pm'
|
| 127 |
+
* - New Behavior: 'Oct 8 2018 at 12:00 pm - Oct 24 12:30 pm'
|
| 128 |
+
*/
|
| 129 |
+
parts.push( `${ to.detail.month } ${ to.detail.day } ${ separatorOptions.time } ${ to.detail.time }` );
|
| 130 |
+
} else {
|
| 131 |
+
// Otherwise just use the full text
|
| 132 |
+
parts.push( to.text );
|
| 133 |
+
}
|
| 134 |
+
}
|
| 135 |
+
|
| 136 |
+
return parts.filter( identity ).join( separatorOptions.date );
|
| 137 |
+
};
|
| 138 |
+
|
| 139 |
+
export const labelToDate = ( label ) => {
|
| 140 |
+
const [ parsed ] = chrono.parse( label );
|
| 141 |
+
const dates = {
|
| 142 |
+
start: null,
|
| 143 |
+
end: null,
|
| 144 |
+
};
|
| 145 |
+
if ( parsed ) {
|
| 146 |
+
const { start, end } = parsed;
|
| 147 |
+
dates.start = start ? momentUtil.toDateTime( momentUtil.toMoment( start.date() ) ) : null;
|
| 148 |
+
dates.end = end ? momentUtil.toDateTime( momentUtil.toMoment( end.date() ) ) : null;
|
| 149 |
+
}
|
| 150 |
+
return dates;
|
| 151 |
+
};
|
common/src/modules/utils/dom.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import { noop } from 'lodash';
|
| 5 |
+
|
| 6 |
+
/**
|
| 7 |
+
* Test if a node element has a class present on it
|
| 8 |
+
*
|
| 9 |
+
* @param {HTMLElement|Element} node The node where to look for the class names
|
| 10 |
+
* @param {array} classNames List of class names as an array of strings
|
| 11 |
+
* @returns {boolean} `true` if has any of the classes or false if does not have any
|
| 12 |
+
*/
|
| 13 |
+
export const hasClass = ( node, classNames = [] ) => {
|
| 14 |
+
for ( let i = 0; i < classNames.length; i++ ) {
|
| 15 |
+
if ( node.classList.contains( classNames[ i ] ) ) {
|
| 16 |
+
return true;
|
| 17 |
+
}
|
| 18 |
+
}
|
| 19 |
+
return false;
|
| 20 |
+
};
|
| 21 |
+
|
| 22 |
+
/**
|
| 23 |
+
* Utility to search the parent of a node looking from the current node Up to the highest
|
| 24 |
+
* node on the DOM Tree
|
| 25 |
+
*
|
| 26 |
+
* @param {(DOMElement|object)} node - The DOM node where the search starts
|
| 27 |
+
* @param {function} callback - Is executed on every iteration, it should return a boolean
|
| 28 |
+
* @returns {boolean} Returns tre if the callback returns true with any of the parents.
|
| 29 |
+
*/
|
| 30 |
+
export const searchParent = ( node = {}, callback = noop ) => {
|
| 31 |
+
let found = false;
|
| 32 |
+
let testNode = node;
|
| 33 |
+
do {
|
| 34 |
+
if ( testNode ) {
|
| 35 |
+
found = callback( testNode );
|
| 36 |
+
}
|
| 37 |
+
const nextNode = testNode && testNode.parentNode ? testNode.parentNode : null;
|
| 38 |
+
testNode = isRootNode( nextNode ) ? null : nextNode;
|
| 39 |
+
} while ( ! found && testNode !== null );
|
| 40 |
+
|
| 41 |
+
return found;
|
| 42 |
+
};
|
| 43 |
+
|
| 44 |
+
/**
|
| 45 |
+
* Test if a node is the same as the root element or the base node of the document.
|
| 46 |
+
*
|
| 47 |
+
* @param {Element} node A Document Node
|
| 48 |
+
* @returns {boolean} true if node is the root Node Document
|
| 49 |
+
*/
|
| 50 |
+
export const isRootNode = ( node ) => node === window.top.document;
|
common/src/modules/utils/get-hidden-height.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* @function getHiddenHeight
|
| 3 |
+
* @desc gets the height of hidden objects.
|
| 4 |
+
*/
|
| 5 |
+
|
| 6 |
+
const getHiddenHeight = ( el ) => {
|
| 7 |
+
const width = el.clientWidth;
|
| 8 |
+
const element = el;
|
| 9 |
+
|
| 10 |
+
element.style.visibility = 'hidden';
|
| 11 |
+
element.style.height = 'auto';
|
| 12 |
+
element.style.maxHeight = 'none';
|
| 13 |
+
element.style.position = 'fixed';
|
| 14 |
+
element.style.width = `${width}px`;
|
| 15 |
+
|
| 16 |
+
const tHeight = element.offsetHeight;
|
| 17 |
+
|
| 18 |
+
element.style.visibility = '';
|
| 19 |
+
element.style.height = '';
|
| 20 |
+
element.style.maxHeight = '';
|
| 21 |
+
element.style.width = '';
|
| 22 |
+
element.style.position = '';
|
| 23 |
+
element.style.zIndex = '';
|
| 24 |
+
|
| 25 |
+
return tHeight;
|
| 26 |
+
};
|
| 27 |
+
|
| 28 |
+
export default getHiddenHeight;
|
common/src/modules/utils/globals.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* @todo: handle globals in a better way
|
| 3 |
+
*/
|
| 4 |
+
export const get = ( key, defaultValue ) => window[ key ] || defaultValue;
|
| 5 |
+
export const google = () => get( 'google' );
|
| 6 |
+
|
| 7 |
+
// Localized Config
|
| 8 |
+
export const config = () => get( 'tribe_editor_config', {} );
|
| 9 |
+
|
| 10 |
+
// Common
|
| 11 |
+
export const common = () => config().common || {};
|
| 12 |
+
export const adminUrl = () => common().adminUrl || '';
|
| 13 |
+
export const rest = () => common().rest || {};
|
| 14 |
+
export const restNonce = () => rest().nonce || {};
|
| 15 |
+
export const dateSettings = () => common().dateSettings || {};
|
| 16 |
+
export const editorConstants = () => common().constants || {};
|
| 17 |
+
export const list = () => ( {
|
| 18 |
+
countries: common().countries || {},
|
| 19 |
+
us_states: common().usStates || {},
|
| 20 |
+
} );
|
| 21 |
+
|
| 22 |
+
// TEC
|
| 23 |
+
export const tec = () => config().events || {};
|
| 24 |
+
export const editor = () => tec().editor || {};
|
| 25 |
+
export const settings = () => tec().settings || {};
|
| 26 |
+
export const mapsAPI = () => tec().googleMap || {};
|
| 27 |
+
export const priceSettings = () => tec().priceSettings || {};
|
| 28 |
+
export const tecDateSettings = () => tec().dateSettings || {};
|
| 29 |
+
export const timezoneHtml = () => tec().timezoneHTML || '';
|
| 30 |
+
export const defaultTimes = () => tec().defaultTimes || {};
|
| 31 |
+
|
| 32 |
+
// PRO
|
| 33 |
+
export const pro = () => config().eventsPRO || {};
|
| 34 |
+
export const editorDefaults = () => pro().defaults || {};
|
| 35 |
+
|
| 36 |
+
// Tickets
|
| 37 |
+
export const tickets = () => config().tickets || {};
|
common/src/modules/utils/index.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import * as date from './date';
|
| 2 |
+
import * as dom from './dom';
|
| 3 |
+
import * as globals from './globals';
|
| 4 |
+
import * as input from './input';
|
| 5 |
+
import * as moment from './moment';
|
| 6 |
+
import * as range from './range';
|
| 7 |
+
import * as slide from './slide';
|
| 8 |
+
import * as string from './string';
|
| 9 |
+
import * as time from './time';
|
| 10 |
+
import * as timezone from './timezone';
|
| 11 |
+
import * as number from './number';
|
| 12 |
+
import * as api from './api';
|
| 13 |
+
|
| 14 |
+
export { date };
|
| 15 |
+
export { dom };
|
| 16 |
+
export { default as getHiddenHeight } from './get-hidden-height';
|
| 17 |
+
export { globals };
|
| 18 |
+
export { input };
|
| 19 |
+
export { moment };
|
| 20 |
+
export { range };
|
| 21 |
+
export { slide };
|
| 22 |
+
export { string };
|
| 23 |
+
export { time };
|
| 24 |
+
export { timezone };
|
| 25 |
+
export { number };
|
| 26 |
+
export { api };
|
| 27 |
+
export { default as TribePropTypes } from './proptypes';
|
common/src/modules/utils/input.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* Allow to set a function (callback) as the parameter of onChange which will send the value of the
|
| 3 |
+
* event into the callback to avoid arrow functions around props of components.
|
| 4 |
+
*
|
| 5 |
+
* @param {Function} callback executed once the event is fired.
|
| 6 |
+
* @return {Function} Function executed by the event to extract the value
|
| 7 |
+
*/
|
| 8 |
+
export const sendValue = ( callback ) => ( event ) => {
|
| 9 |
+
const { target = {} } = event;
|
| 10 |
+
const { value = '' } = target;
|
| 11 |
+
callback( value );
|
| 12 |
+
};
|
common/src/modules/utils/moment.js
ADDED
|
@@ -0,0 +1,332 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import { isString } from 'lodash';
|
| 5 |
+
import moment, { isMoment } from 'moment';
|
| 6 |
+
|
| 7 |
+
/**
|
| 8 |
+
* Internal dependencies
|
| 9 |
+
*/
|
| 10 |
+
import {
|
| 11 |
+
date as dateUtil,
|
| 12 |
+
time,
|
| 13 |
+
string,
|
| 14 |
+
} from '@moderntribe/common/utils';
|
| 15 |
+
|
| 16 |
+
export const TIME_FORMAT = 'h:mm a';
|
| 17 |
+
|
| 18 |
+
/**
|
| 19 |
+
* Make sure the format provided matches the spec used by moment.js
|
| 20 |
+
*
|
| 21 |
+
* @param {string} format The format to be converted to a moment format
|
| 22 |
+
* @returns {string} return a moment.js valid format
|
| 23 |
+
*/
|
| 24 |
+
export const toFormat = ( format ) => {
|
| 25 |
+
const replacements = {
|
| 26 |
+
d: 'DD',
|
| 27 |
+
D: 'ddd',
|
| 28 |
+
j: 'D',
|
| 29 |
+
l: 'dddd',
|
| 30 |
+
N: 'E',
|
| 31 |
+
S: 'o',
|
| 32 |
+
w: 'e',
|
| 33 |
+
z: 'DDD',
|
| 34 |
+
W: 'W',
|
| 35 |
+
F: 'MMMM',
|
| 36 |
+
m: 'MM',
|
| 37 |
+
M: 'MMM',
|
| 38 |
+
n: 'M',
|
| 39 |
+
t: '', // no equivalent
|
| 40 |
+
L: '', // no equivalent
|
| 41 |
+
o: 'YYYY',
|
| 42 |
+
Y: 'YYYY',
|
| 43 |
+
y: 'YY',
|
| 44 |
+
a: 'a',
|
| 45 |
+
A: 'A',
|
| 46 |
+
B: '', // no equivalent
|
| 47 |
+
g: 'h',
|
| 48 |
+
G: 'H',
|
| 49 |
+
h: 'hh',
|
| 50 |
+
H: 'HH',
|
| 51 |
+
i: 'mm',
|
| 52 |
+
s: 'ss',
|
| 53 |
+
u: 'SSS',
|
| 54 |
+
e: 'zz', // deprecated since version 1.6.0 of moment.js
|
| 55 |
+
I: '', // no equivalent
|
| 56 |
+
O: '', // no equivalent
|
| 57 |
+
P: '', // no equivalent
|
| 58 |
+
T: '', // no equivalent
|
| 59 |
+
Z: '', // no equivalent
|
| 60 |
+
c: '', // no equivalent
|
| 61 |
+
r: '', // no equivalent
|
| 62 |
+
U: 'X',
|
| 63 |
+
};
|
| 64 |
+
|
| 65 |
+
return string.replaceWithObject( format, replacements );
|
| 66 |
+
};
|
| 67 |
+
|
| 68 |
+
/**
|
| 69 |
+
* Round the time of a moment object if the minutes on the date is lower than 30 will set to 0 if
|
| 70 |
+
* is greater will se 30 so is either 30 or 0.
|
| 71 |
+
*
|
| 72 |
+
* @param {moment} date Make sure the date is rounded between 0 or 30 minutes
|
| 73 |
+
* @returns {moment} A moment object
|
| 74 |
+
*/
|
| 75 |
+
export const roundTime = ( date ) => {
|
| 76 |
+
if ( ! isMoment( date ) ) {
|
| 77 |
+
return date;
|
| 78 |
+
}
|
| 79 |
+
|
| 80 |
+
let minutes = date.minute();
|
| 81 |
+
if ( minutes >= 30 ) {
|
| 82 |
+
minutes = ( minutes % 30 );
|
| 83 |
+
}
|
| 84 |
+
|
| 85 |
+
return date
|
| 86 |
+
.clone()
|
| 87 |
+
.subtract( minutes, 'm' )
|
| 88 |
+
.seconds( 0 );
|
| 89 |
+
};
|
| 90 |
+
|
| 91 |
+
/**
|
| 92 |
+
* Parse multiple formats in a date to ensure the generated dates are valid
|
| 93 |
+
*
|
| 94 |
+
* @param {string} date The date to be converted
|
| 95 |
+
* @param {array} formats The list of formats used to format
|
| 96 |
+
* @returns {moment} moment Object with the date or current date if is non valid
|
| 97 |
+
*/
|
| 98 |
+
export const parseFormats = ( date, formats = [ dateUtil.FORMATS.DATABASE.datetime, dateUtil.FORMATS.WP.datetime ] ) => {
|
| 99 |
+
for ( let i = 0; i < formats.length; i ++ ) {
|
| 100 |
+
const format = formats[ i ];
|
| 101 |
+
const result = toMoment( date, format );
|
| 102 |
+
if ( result.isValid() ) {
|
| 103 |
+
return result;
|
| 104 |
+
}
|
| 105 |
+
}
|
| 106 |
+
|
| 107 |
+
const noFormat = moment( date );
|
| 108 |
+
return noFormat.isValid() ? noFormat : moment();
|
| 109 |
+
};
|
| 110 |
+
|
| 111 |
+
/**
|
| 112 |
+
* Convert a Date() object into a Moment.js object avoiding warnings of different formats
|
| 113 |
+
* used by Date
|
| 114 |
+
*
|
| 115 |
+
* @param {(Date|moment|string)} date The date to be converted.
|
| 116 |
+
* @param {string} format The format of the data to be used
|
| 117 |
+
* @param {bool} Force the parse of the format default to true
|
| 118 |
+
* @returns {moment} A moment object
|
| 119 |
+
*/
|
| 120 |
+
export const toMoment = ( date, format = dateUtil.FORMATS.DATABASE.datetime, parseFormat = true ) => {
|
| 121 |
+
if ( isMoment( date ) || date instanceof Date ) {
|
| 122 |
+
return moment( date );
|
| 123 |
+
} else if ( isString( date ) ) {
|
| 124 |
+
return moment( date, parseFormat ? toFormat( format ) : format );
|
| 125 |
+
}
|
| 126 |
+
|
| 127 |
+
return moment();
|
| 128 |
+
};
|
| 129 |
+
|
| 130 |
+
export const toMomentFromDate = ( date ) => {
|
| 131 |
+
if ( ! ( date instanceof Date ) ) {
|
| 132 |
+
throw new Error( 'Make sure your date is an instance of Date' );
|
| 133 |
+
}
|
| 134 |
+
|
| 135 |
+
const year = date.getFullYear();
|
| 136 |
+
const month = date.getMonth();
|
| 137 |
+
const day = date.getDate();
|
| 138 |
+
|
| 139 |
+
return moment()
|
| 140 |
+
.year( year )
|
| 141 |
+
.month( month )
|
| 142 |
+
.date( day )
|
| 143 |
+
.startOf( 'day' );
|
| 144 |
+
};
|
| 145 |
+
|
| 146 |
+
/**
|
| 147 |
+
* Convert a Date() object or date string and time into a moment object
|
| 148 |
+
*
|
| 149 |
+
* @param {(Date|moment|string)} date The date to be converted.
|
| 150 |
+
* @param {string} time The time string in HH:mm format..
|
| 151 |
+
* @returns {moment} A moment object
|
| 152 |
+
*/
|
| 153 |
+
export const toMomentFromDateTime = ( date, time ) => {
|
| 154 |
+
const [ hours, minutes ] = time.split( ':' );
|
| 155 |
+
return moment( date ).hours( hours ).minutes( minutes );
|
| 156 |
+
};
|
| 157 |
+
|
| 158 |
+
/**
|
| 159 |
+
* Replace the date of a moment object with another date from another moment object
|
| 160 |
+
*
|
| 161 |
+
* @param {moment} original The moment object where the date is going to be replaced
|
| 162 |
+
* @param {moment} replaced The moment object where the date to be used to replace is located
|
| 163 |
+
* @returns {moment} A moment object where the date is replaced
|
| 164 |
+
*/
|
| 165 |
+
export const replaceDate = ( original, replaced ) => {
|
| 166 |
+
if ( ! isMoment( original ) || ! isMoment( replaced ) ) {
|
| 167 |
+
throw new Error( 'Make sure your values are instances of moment' );
|
| 168 |
+
}
|
| 169 |
+
|
| 170 |
+
return original
|
| 171 |
+
.year( replaced.year() )
|
| 172 |
+
.month( replaced.month() )
|
| 173 |
+
.date( replaced.date() );
|
| 174 |
+
};
|
| 175 |
+
|
| 176 |
+
/**
|
| 177 |
+
* Set time in seconds to a moment object
|
| 178 |
+
*
|
| 179 |
+
* @param {moment} original The original moment where the date is going to be set
|
| 180 |
+
* @param {number} seconds Amount of seconds to be set to the moment object.
|
| 181 |
+
* @returns {moment} A moment object with the new date
|
| 182 |
+
*/
|
| 183 |
+
export const setTimeInSeconds = ( original, seconds = 0 ) => {
|
| 184 |
+
if ( ! isMoment( original ) ) {
|
| 185 |
+
throw new Error( 'Make sure your values are instances of moment' );
|
| 186 |
+
}
|
| 187 |
+
|
| 188 |
+
if ( seconds < 0 ) {
|
| 189 |
+
return original;
|
| 190 |
+
}
|
| 191 |
+
|
| 192 |
+
return original
|
| 193 |
+
.startOf( 'day' )
|
| 194 |
+
.seconds( seconds || original.seconds() );
|
| 195 |
+
};
|
| 196 |
+
|
| 197 |
+
/**
|
| 198 |
+
* Total seconds of a current date from moment
|
| 199 |
+
*
|
| 200 |
+
* @param {moment} date The date to compare on the current day
|
| 201 |
+
* @returns {int} Total of seconds from start of the day to the current moment,
|
| 202 |
+
*/
|
| 203 |
+
export const totalSeconds = ( date ) => {
|
| 204 |
+
if ( ! date || ! isMoment( date ) ) {
|
| 205 |
+
return 0;
|
| 206 |
+
}
|
| 207 |
+
return date.diff( moment( date ).startOf( 'day' ), 'seconds' );
|
| 208 |
+
};
|
| 209 |
+
|
| 210 |
+
/**
|
| 211 |
+
* Convert a moment object into a WP date time format
|
| 212 |
+
*
|
| 213 |
+
* @param {moment} date A moment date object
|
| 214 |
+
* @param {string} format Format used to output the date
|
| 215 |
+
* @returns {string} A date time format
|
| 216 |
+
*/
|
| 217 |
+
export const toDateTime = ( date, format = dateUtil.FORMATS.DATABASE.datetime ) => (
|
| 218 |
+
date.format( toFormat( format ) )
|
| 219 |
+
);
|
| 220 |
+
|
| 221 |
+
export const toDate = ( date, format = dateUtil.FORMATS.WP.date ) => (
|
| 222 |
+
date.format( toFormat( format ) )
|
| 223 |
+
);
|
| 224 |
+
|
| 225 |
+
export const toDateNoYear = ( date, format = dateUtil.FORMATS.WP.dateNoYear ) => (
|
| 226 |
+
date.format( toFormat( format ) )
|
| 227 |
+
);
|
| 228 |
+
|
| 229 |
+
export const toTime = ( date, format = dateUtil.FORMATS.WP.time ) => (
|
| 230 |
+
date.format( toFormat( format ) )
|
| 231 |
+
);
|
| 232 |
+
|
| 233 |
+
export const toTime24Hr = ( date, format = dateUtil.FORMATS.WP.time24Hr ) => (
|
| 234 |
+
date.format( toFormat( format ) )
|
| 235 |
+
);
|
| 236 |
+
|
| 237 |
+
export const toDatabaseDate = ( date, format = dateUtil.FORMATS.DATABASE.date ) => (
|
| 238 |
+
date.format( toFormat( format ) )
|
| 239 |
+
);
|
| 240 |
+
|
| 241 |
+
export const toDatabaseTime = ( date, format = dateUtil.FORMATS.DATABASE.time ) => (
|
| 242 |
+
date.format( toFormat( format ) )
|
| 243 |
+
);
|
| 244 |
+
|
| 245 |
+
export const toDatePicker = ( date = moment(), format = 'YYYY-MM-DDTHH:mm:ss' ) => (
|
| 246 |
+
date.format( format )
|
| 247 |
+
);
|
| 248 |
+
|
| 249 |
+
/**
|
| 250 |
+
* Test if the start and end dates are the same day.
|
| 251 |
+
*
|
| 252 |
+
* @param {moment} start The start date
|
| 253 |
+
* @param {(moment|String)} end The end date
|
| 254 |
+
* @returns {boolean} if the start and end dates are the same day
|
| 255 |
+
*/
|
| 256 |
+
export const isSameDay = ( start, end ) => {
|
| 257 |
+
|
| 258 |
+
if ( ! start || ! end ) {
|
| 259 |
+
return false;
|
| 260 |
+
}
|
| 261 |
+
|
| 262 |
+
return moment( start ).isSame( end, 'day' );
|
| 263 |
+
};
|
| 264 |
+
|
| 265 |
+
/**
|
| 266 |
+
* Test if two moment objects are in the same month
|
| 267 |
+
*
|
| 268 |
+
* @param {moment} start The start moment
|
| 269 |
+
* @param {moment} end The end moment
|
| 270 |
+
* @returns {boolean} true if start and end are on the same month
|
| 271 |
+
*/
|
| 272 |
+
export const isSameMonth = ( start, end ) => {
|
| 273 |
+
|
| 274 |
+
if ( ! start || ! end ) {
|
| 275 |
+
return false;
|
| 276 |
+
}
|
| 277 |
+
|
| 278 |
+
return moment( start ).isSame( end, 'month' );
|
| 279 |
+
};
|
| 280 |
+
|
| 281 |
+
/**
|
| 282 |
+
* Test if the start and end dates have the same year.
|
| 283 |
+
*
|
| 284 |
+
* @param {moment} start The start date
|
| 285 |
+
* @param {(moment|String)} end The end date
|
| 286 |
+
* @returns {boolean} if the start and end dates have the same year
|
| 287 |
+
*/
|
| 288 |
+
export const isSameYear = ( start, end ) => (
|
| 289 |
+
toMoment( start ).isSame( toMoment( end ), 'year' )
|
| 290 |
+
);
|
| 291 |
+
|
| 292 |
+
/**
|
| 293 |
+
* Reset the time of an event by creating an object with start and end ensuring the end event is
|
| 294 |
+
* after the start date and both are on the same day if the start is one hour before the end of the
|
| 295 |
+
* day it will remove an hour of the start to ensure both start / end happen on the same day
|
| 296 |
+
*
|
| 297 |
+
* @param {moment} start The start date
|
| 298 |
+
* @returns {{start: {moment}, end: {moment}}} Object with two keys: start, end
|
| 299 |
+
*/
|
| 300 |
+
export const resetTimes = ( start ) => {
|
| 301 |
+
const testMoment = start.clone().add( time.HOUR_IN_SECONDS, 'seconds' );
|
| 302 |
+
|
| 303 |
+
// Rollback an hour before adding half an hour as we are on the edge of the day
|
| 304 |
+
if ( ! isSameDay( start, testMoment ) ) {
|
| 305 |
+
start.subtract( time.HOUR_IN_SECONDS, 'seconds' );
|
| 306 |
+
}
|
| 307 |
+
|
| 308 |
+
const end = start.clone().add( time.HOUR_IN_SECONDS, 'seconds' );
|
| 309 |
+
|
| 310 |
+
return {
|
| 311 |
+
start,
|
| 312 |
+
end,
|
| 313 |
+
};
|
| 314 |
+
};
|
| 315 |
+
|
| 316 |
+
/**
|
| 317 |
+
* Make sure the start time is always before the end time
|
| 318 |
+
*
|
| 319 |
+
* @param {moment} start The start date
|
| 320 |
+
* @param {moment} end The end date
|
| 321 |
+
* @returns {{start: {moment}, end: {moment}}} Object with two keys: start, end
|
| 322 |
+
*/
|
| 323 |
+
export const adjustStart = ( start, end ) => {
|
| 324 |
+
if ( end.isSameOrBefore( start ) ) {
|
| 325 |
+
return resetTimes( start );
|
| 326 |
+
}
|
| 327 |
+
|
| 328 |
+
return {
|
| 329 |
+
start,
|
| 330 |
+
end,
|
| 331 |
+
};
|
| 332 |
+
};
|
common/src/modules/utils/number.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* Calculate the percentage of two numbers
|
| 3 |
+
*
|
| 4 |
+
* @param {number} value Initial value from where to take the percentage
|
| 5 |
+
* @param {number} total Total value to get the percentage relative to this value
|
| 6 |
+
* @returns {number} total percentage value
|
| 7 |
+
*/
|
| 8 |
+
export const percentage = ( value = 0, total = 0 ) => {
|
| 9 |
+
if ( total === 0 ) {
|
| 10 |
+
return 0;
|
| 11 |
+
}
|
| 12 |
+
|
| 13 |
+
const result = Number.parseFloat( ( value / total ) * 100 );
|
| 14 |
+
|
| 15 |
+
if ( isNaN( result ) ) {
|
| 16 |
+
throw new RangeError(
|
| 17 |
+
`Make sure ${value} and ${total} are valid numbers, operation result in NaN value`
|
| 18 |
+
);
|
| 19 |
+
}
|
| 20 |
+
|
| 21 |
+
return result;
|
| 22 |
+
};
|
common/src/modules/utils/proptypes.js
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* Create chainable validator with isRequired check
|
| 3 |
+
* @param {function} validator
|
| 4 |
+
*/
|
| 5 |
+
export const createChainableValidator = ( validator ) => {
|
| 6 |
+
const createChainedValidator = (
|
| 7 |
+
isRequired,
|
| 8 |
+
props,
|
| 9 |
+
propName,
|
| 10 |
+
componentName,
|
| 11 |
+
) => {
|
| 12 |
+
const propValue = props[ propName ];
|
| 13 |
+
|
| 14 |
+
if ( propValue == null ) {
|
| 15 |
+
if ( isRequired ) {
|
| 16 |
+
if ( propValue === null ) {
|
| 17 |
+
/* eslint-disable-next-line max-len */
|
| 18 |
+
return new Error( `The prop \`${propName}\` is marked as required in \`${componentName}\`, but its value is \`null\`.` );
|
| 19 |
+
}
|
| 20 |
+
/* eslint-disable-next-line max-len */
|
| 21 |
+
return new Error( `The prop \`${propName}\` is marked as required in \`${componentName}\`, but its value is \`undefined\`.` );
|
| 22 |
+
}
|
| 23 |
+
return null;
|
| 24 |
+
} else {
|
| 25 |
+
return validator( props, propName, componentName );
|
| 26 |
+
}
|
| 27 |
+
};
|
| 28 |
+
|
| 29 |
+
const chainedValidator = createChainedValidator.bind( null, false );
|
| 30 |
+
chainedValidator.isRequired = createChainedValidator.bind( null, true );
|
| 31 |
+
|
| 32 |
+
return chainedValidator;
|
| 33 |
+
}
|
| 34 |
+
|
| 35 |
+
export const timeRegex = /^([01]?[0-9]|2[0-3]):[0-5][0-9]$/;
|
| 36 |
+
|
| 37 |
+
/**
|
| 38 |
+
* PropTypes check for type string and time format using 24h clock in hh:mm format
|
| 39 |
+
* e.g. 00:24, 03:57, 21:12
|
| 40 |
+
*
|
| 41 |
+
* @param {object} props
|
| 42 |
+
* @param {string} propName
|
| 43 |
+
* @param {string} componentName
|
| 44 |
+
*/
|
| 45 |
+
export const timeFormat = ( props, propName, componentName ) => {
|
| 46 |
+
const propValue = props[ propName ];
|
| 47 |
+
|
| 48 |
+
if ( typeof propValue !== 'string' ) {
|
| 49 |
+
const type = typeof propValue;
|
| 50 |
+
/* eslint-disable-next-line max-len */
|
| 51 |
+
return new Error( `Invalid prop \`${propName}\` of type \`${type}\` supplied to \`${componentName}\`, expected \`string\`.` );
|
| 52 |
+
}
|
| 53 |
+
|
| 54 |
+
if ( ! timeRegex.test( propValue ) ) {
|
| 55 |
+
/* eslint-disable-next-line max-len */
|
| 56 |
+
return new Error( `Invalid prop \`${propName}\` format supplied to \`${componentName}\`, expected \`hh:mm\`.` );
|
| 57 |
+
}
|
| 58 |
+
|
| 59 |
+
return null;
|
| 60 |
+
};
|
| 61 |
+
|
| 62 |
+
export const nullType = ( props, propName, componentName ) => {
|
| 63 |
+
if ( null !== props[ propName ] ) {
|
| 64 |
+
return new Error(
|
| 65 |
+
`Invalid prop: \`${propName}\` supplied to \`${ componentName }\`, expect null.`
|
| 66 |
+
);
|
| 67 |
+
}
|
| 68 |
+
}
|
| 69 |
+
|
| 70 |
+
export default {
|
| 71 |
+
timeFormat: createChainableValidator( timeFormat ),
|
| 72 |
+
nullType: createChainableValidator( nullType ),
|
| 73 |
+
};
|
common/src/modules/utils/range.js
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import { trim, isEmpty, split } from 'lodash';
|
| 5 |
+
|
| 6 |
+
/**
|
| 7 |
+
* Parse a string into a range type of string {a} - {b} where a and b are numbers
|
| 8 |
+
*
|
| 9 |
+
* @param {string} input The original string
|
| 10 |
+
* @returns {string} A formatted range string.
|
| 11 |
+
*/
|
| 12 |
+
export const parser = ( input ) => {
|
| 13 |
+
const range = trim( input );
|
| 14 |
+
|
| 15 |
+
if ( isEmpty( range ) ) {
|
| 16 |
+
return range;
|
| 17 |
+
}
|
| 18 |
+
|
| 19 |
+
const chars = parseChars( input );
|
| 20 |
+
|
| 21 |
+
if ( isEmpty( chars ) ) {
|
| 22 |
+
return chars;
|
| 23 |
+
}
|
| 24 |
+
|
| 25 |
+
const [ a, b ] = extractParts( chars );
|
| 26 |
+
const [ num_a, num_b ] = [ parseFloat( a ), parseFloat( b ) ];
|
| 27 |
+
|
| 28 |
+
if ( ! num_b || num_b === num_a ) {
|
| 29 |
+
return num_a === 0 ? '' : trim( a );
|
| 30 |
+
}
|
| 31 |
+
|
| 32 |
+
return num_a >= num_b ? `${ trim( b ) } - ${ trim( a ) }` : `${ trim( a ) } - ${ trim( b ) }`;
|
| 33 |
+
};
|
| 34 |
+
|
| 35 |
+
/**
|
| 36 |
+
* Remove any char that is not a: number, dash, dot or comma.
|
| 37 |
+
*
|
| 38 |
+
* @param {string} input The string from where to extract the chars
|
| 39 |
+
* @returns {string} A string with only valid chars
|
| 40 |
+
*/
|
| 41 |
+
export const parseChars = ( input = '' ) => (
|
| 42 |
+
split( input, ' ' )
|
| 43 |
+
.map( ( part ) => {
|
| 44 |
+
// Remove anything that is not a number a period or a dash
|
| 45 |
+
return part.replace( /[^0-9.,-]/g, '' );
|
| 46 |
+
} )
|
| 47 |
+
.join( ' ' )
|
| 48 |
+
.trim()
|
| 49 |
+
);
|
| 50 |
+
|
| 51 |
+
/**
|
| 52 |
+
* Extract only valid numbers from the string
|
| 53 |
+
*
|
| 54 |
+
* @param {string} chars The chars to be split into parts.
|
| 55 |
+
* @returns {array} An array with the parts
|
| 56 |
+
*/
|
| 57 |
+
export const extractParts = ( chars ) => (
|
| 58 |
+
split( chars.replace( /,/g, '.' ), '-' )
|
| 59 |
+
// Convert , into . so we can parse into numbers
|
| 60 |
+
.map( ( item ) => {
|
| 61 |
+
const re = /([0-9]+(.[0-9]+)?)/g;
|
| 62 |
+
const result = re.exec( item.trim() );
|
| 63 |
+
return null === result ? '' : result[ 1 ];
|
| 64 |
+
} )
|
| 65 |
+
.filter( ( item ) => ! isEmpty( item ) )
|
| 66 |
+
.map( ( item ) => {
|
| 67 |
+
// If the user input the price with decimals (even .00) we want to keep them
|
| 68 |
+
const decimals = 0 < item.indexOf( '.' ) ? 2 : 0;
|
| 69 |
+
return parseFloat( item ).toFixed( decimals );
|
| 70 |
+
} )
|
| 71 |
+
.filter( ( item ) => ! isNaN( item ) )
|
| 72 |
+
.slice( 0, 2 )
|
| 73 |
+
);
|
| 74 |
+
|
| 75 |
+
/**
|
| 76 |
+
* Test to see if an input range is free of cost
|
| 77 |
+
*
|
| 78 |
+
* @param {string} input Range input
|
| 79 |
+
* @returns {boolean} true if the event has 0 on all parts of the range, false otherwise
|
| 80 |
+
*/
|
| 81 |
+
export const isFree = ( input ) => {
|
| 82 |
+
const parts = split( input, '-' );
|
| 83 |
+
const test = parts
|
| 84 |
+
.map( ( item ) => parseFloat( item ) )
|
| 85 |
+
.filter( ( item ) => ! isNaN( item ) )
|
| 86 |
+
.filter( ( item ) => item === 0 );
|
| 87 |
+
|
| 88 |
+
return parts.length === test.length;
|
| 89 |
+
};
|
common/src/modules/utils/slide.js
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* Element to slide gets the following CSS:
|
| 3 |
+
* max-height: 0;
|
| 4 |
+
* overflow: hidden;
|
| 5 |
+
*/
|
| 6 |
+
import BezierEasing from 'bezier-easing';
|
| 7 |
+
import getHiddenHeight from './get-hidden-height';
|
| 8 |
+
|
| 9 |
+
const ease = BezierEasing( 0.25, 0.1, 0.25, 1 );
|
| 10 |
+
|
| 11 |
+
const requestIds = {};
|
| 12 |
+
|
| 13 |
+
/**
|
| 14 |
+
* Check that request id exists, if not create an entry
|
| 15 |
+
* @param {string} id Unique ID of animation
|
| 16 |
+
*/
|
| 17 |
+
export const checkRequestIds = ( id ) => {
|
| 18 |
+
if ( ! requestIds[ id ] ) {
|
| 19 |
+
requestIds[ id ] = {
|
| 20 |
+
up: null,
|
| 21 |
+
down: null,
|
| 22 |
+
};
|
| 23 |
+
}
|
| 24 |
+
|
| 25 |
+
return requestIds[ id ];
|
| 26 |
+
};
|
| 27 |
+
|
| 28 |
+
/**
|
| 29 |
+
* Cancel animations with request id
|
| 30 |
+
* @param {string} id Unique ID of animation
|
| 31 |
+
*/
|
| 32 |
+
const cancelAnimations = ( id ) => {
|
| 33 |
+
if ( requestIds[ id ].up ) {
|
| 34 |
+
window.cancelAnimationFrame( requestIds[ id ].up );
|
| 35 |
+
requestIds[ id ].up = null;
|
| 36 |
+
}
|
| 37 |
+
if ( requestIds[ id ].down ) {
|
| 38 |
+
window.cancelAnimationFrame( requestIds[ id ].down );
|
| 39 |
+
requestIds[ id ].down = null;
|
| 40 |
+
}
|
| 41 |
+
};
|
| 42 |
+
|
| 43 |
+
/**
|
| 44 |
+
* Like jQuery's slideDown function
|
| 45 |
+
* @param {Node} elem Element to show and hide
|
| 46 |
+
* @param {string} id Unique ID of animation
|
| 47 |
+
* @param {int} time Length of animation in ms
|
| 48 |
+
* @param {function} callback Callback function
|
| 49 |
+
*/
|
| 50 |
+
export const down = ( elem, id, time = 400, callback = null ) => {
|
| 51 |
+
const startHeight = elem.offsetHeight;
|
| 52 |
+
const endHeight = getHiddenHeight( elem );
|
| 53 |
+
let startTime = null;
|
| 54 |
+
elem.style.maxHeight = '0';
|
| 55 |
+
|
| 56 |
+
checkRequestIds( id );
|
| 57 |
+
cancelAnimations( id );
|
| 58 |
+
|
| 59 |
+
const step = ( timestamp ) => {
|
| 60 |
+
if ( ! startTime ) {
|
| 61 |
+
startTime = timestamp;
|
| 62 |
+
}
|
| 63 |
+
const timeDiff = timestamp - startTime;
|
| 64 |
+
const progress = ease( timeDiff / time );
|
| 65 |
+
const height = ( progress * ( endHeight - startHeight ) ) + startHeight;
|
| 66 |
+
elem.style.maxHeight = `${height}px`;
|
| 67 |
+
|
| 68 |
+
if ( timeDiff < time ) {
|
| 69 |
+
requestIds[ id ].down = window.requestAnimationFrame( step );
|
| 70 |
+
} else {
|
| 71 |
+
requestIds[ id ].down = null;
|
| 72 |
+
elem.style.maxHeight = 'none';
|
| 73 |
+
if ( callback ) {
|
| 74 |
+
callback();
|
| 75 |
+
}
|
| 76 |
+
}
|
| 77 |
+
};
|
| 78 |
+
|
| 79 |
+
requestIds[ id ].down = window.requestAnimationFrame( step );
|
| 80 |
+
};
|
| 81 |
+
|
| 82 |
+
/**
|
| 83 |
+
* Slide element up
|
| 84 |
+
* @param {Node} elem Element to show and hide
|
| 85 |
+
* @param {string} id Unique ID of animation
|
| 86 |
+
* @param {int} time Length of animation in ms
|
| 87 |
+
* @param {function} callback Callback function
|
| 88 |
+
*/
|
| 89 |
+
export const up = ( elem, id, time = 400, callback = null ) => {
|
| 90 |
+
const startHeight = elem.offsetHeight;
|
| 91 |
+
const endHeight = 0;
|
| 92 |
+
let startTime = null;
|
| 93 |
+
elem.style.maxHeight = `${startHeight}px`;
|
| 94 |
+
|
| 95 |
+
checkRequestIds( id );
|
| 96 |
+
cancelAnimations( id );
|
| 97 |
+
|
| 98 |
+
const step = ( timestamp ) => {
|
| 99 |
+
if ( ! startTime ) {
|
| 100 |
+
startTime = timestamp;
|
| 101 |
+
}
|
| 102 |
+
const timeDiff = timestamp - startTime;
|
| 103 |
+
const progress = ease( timeDiff / time );
|
| 104 |
+
const height = ( progress * ( endHeight - startHeight ) ) + startHeight;
|
| 105 |
+
elem.style.maxHeight = `${height}px`;
|
| 106 |
+
|
| 107 |
+
if ( timeDiff < time ) {
|
| 108 |
+
requestIds[ id ].up = window.requestAnimationFrame( step );
|
| 109 |
+
} else {
|
| 110 |
+
requestIds[ id ].up = null;
|
| 111 |
+
elem.style.maxHeight = '0';
|
| 112 |
+
if ( callback ) {
|
| 113 |
+
callback();
|
| 114 |
+
}
|
| 115 |
+
}
|
| 116 |
+
};
|
| 117 |
+
|
| 118 |
+
requestIds[ id ].up = window.requestAnimationFrame( step );
|
| 119 |
+
};
|
common/src/modules/utils/string.js
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import { escapeRegExp, isUndefined, isString, identity } from 'lodash';
|
| 5 |
+
|
| 6 |
+
/**
|
| 7 |
+
* Test if a string is equivalent to a true value
|
| 8 |
+
*
|
| 9 |
+
* @param {string} value The value to be tested
|
| 10 |
+
* @returns {boolean} true if the value is a valid "true" value.
|
| 11 |
+
*/
|
| 12 |
+
export const isTruthy = ( value ) => {
|
| 13 |
+
const validValues = [
|
| 14 |
+
'true',
|
| 15 |
+
'yes',
|
| 16 |
+
'1',
|
| 17 |
+
];
|
| 18 |
+
return validValues.indexOf( value ) !== -1;
|
| 19 |
+
};
|
| 20 |
+
|
| 21 |
+
/**
|
| 22 |
+
* Test if a string is equivalent to a false value
|
| 23 |
+
*
|
| 24 |
+
* @param {string} value The value to be tested
|
| 25 |
+
* @returns {boolean} true if the value is a valid "false" value.
|
| 26 |
+
*/
|
| 27 |
+
export const isFalsy = ( value ) => {
|
| 28 |
+
const validValues = [
|
| 29 |
+
'false',
|
| 30 |
+
'no',
|
| 31 |
+
'0',
|
| 32 |
+
'',
|
| 33 |
+
];
|
| 34 |
+
return validValues.indexOf( value ) !== -1;
|
| 35 |
+
};
|
| 36 |
+
|
| 37 |
+
export const replaceWithObject = ( str = '', pairs = {} ) => {
|
| 38 |
+
const substrs = Object.keys( pairs ).map( escapeRegExp );
|
| 39 |
+
return str.split( RegExp( `(${ substrs.join( '|' ) })` ) )
|
| 40 |
+
.map( part => isUndefined( pairs[ part ] ) ? part : pairs[ part ] )
|
| 41 |
+
.join( '' );
|
| 42 |
+
};
|
| 43 |
+
|
| 44 |
+
/**
|
| 45 |
+
* Extract the words from a string into an array of words removing all the empty spaces.
|
| 46 |
+
*
|
| 47 |
+
* @param {string} text The initial text
|
| 48 |
+
* @returns {array} Return an array with the words
|
| 49 |
+
*/
|
| 50 |
+
export const getWords = ( text = '' ) => {
|
| 51 |
+
if ( ! isString( text ) ) {
|
| 52 |
+
return [];
|
| 53 |
+
}
|
| 54 |
+
return text.split( /\s/ ).filter( identity );
|
| 55 |
+
};
|
| 56 |
+
|
| 57 |
+
/**
|
| 58 |
+
* Apply separators specifically for check box style list where if there are more than 2 words the first
|
| 59 |
+
* separators except the last is different from the rest, and if there are only 2 words it only uses
|
| 60 |
+
* the last separator instead
|
| 61 |
+
*
|
| 62 |
+
* @param {array} words The list of words to join
|
| 63 |
+
* @param {string} startSeparator the separator applied if there are more than 2 words between all the words except the last one
|
| 64 |
+
* @param {string} endSeparator separator applied between the last words
|
| 65 |
+
* @returns {string} return a string with custom separators between words
|
| 66 |
+
*/
|
| 67 |
+
export const wordsAsList = ( words, startSeparator = ', ', endSeparator = ' & ' ) => {
|
| 68 |
+
if ( words.length <= 1 ) {
|
| 69 |
+
return words.join( '' );
|
| 70 |
+
} else {
|
| 71 |
+
const start = words.slice( 0, words.length - 1 ).join( startSeparator );
|
| 72 |
+
const last = words[ words.length - 1 ];
|
| 73 |
+
return `${ start }${ endSeparator }${ last }`;
|
| 74 |
+
}
|
| 75 |
+
};
|
| 76 |
+
|
| 77 |
+
/**
|
| 78 |
+
* Creates a string that only contains a-z characters, useful specially for keys
|
| 79 |
+
*
|
| 80 |
+
* @param {string} text Then ame to be normalized
|
| 81 |
+
* @returns {string} A formatted string with no spacing and only a-z chars
|
| 82 |
+
*/
|
| 83 |
+
export const normalize = ( text = '' ) => {
|
| 84 |
+
if ( ! isString( text ) ) {
|
| 85 |
+
return '';
|
| 86 |
+
}
|
| 87 |
+
return text.toLowerCase()
|
| 88 |
+
// Remove any non word or space
|
| 89 |
+
.replace( /[^a-z\s]/g, '' )
|
| 90 |
+
.trim()
|
| 91 |
+
.replace( /\s+/g, '-' );
|
| 92 |
+
};
|
| 93 |
+
|
| 94 |
+
/**
|
| 95 |
+
* Remove invalid characters from a string that aren't consider as valid for a block name.
|
| 96 |
+
*
|
| 97 |
+
* @since 4.8
|
| 98 |
+
*
|
| 99 |
+
* @param {string} text The text to be formatted as block name
|
| 100 |
+
* @returns {string} The formatted text
|
| 101 |
+
*/
|
| 102 |
+
export const toBlockName = ( text = '' ) => {
|
| 103 |
+
if ( ! isString( text ) ) {
|
| 104 |
+
return '';
|
| 105 |
+
}
|
| 106 |
+
|
| 107 |
+
// Remove any non numeric, a-z or - value
|
| 108 |
+
return text.replace(/[^a-zA-Z0-9-]/g, '' );
|
| 109 |
+
}
|
common/src/modules/utils/time.js
ADDED
|
@@ -0,0 +1,207 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import zeroFill from 'zero-fill';
|
| 5 |
+
|
| 6 |
+
export const MINUTE_IN_SECONDS = 60;
|
| 7 |
+
export const HALF_HOUR_IN_SECONDS = MINUTE_IN_SECONDS * 30;
|
| 8 |
+
export const HOUR_IN_SECONDS = 60 * MINUTE_IN_SECONDS;
|
| 9 |
+
export const DAY_IN_SECONDS = 24 * HOUR_IN_SECONDS;
|
| 10 |
+
|
| 11 |
+
export const START_OF_DAY = '00:00';
|
| 12 |
+
export const END_OF_DAY = '23:59';
|
| 13 |
+
|
| 14 |
+
/**
|
| 15 |
+
* Round the time of a time string
|
| 16 |
+
* If the minutes is lower than 30, it will round the minutes to 0
|
| 17 |
+
* If the minutes is greater than or equal to 30, it will round the minutes to 30
|
| 18 |
+
*
|
| 19 |
+
* @param {string} time
|
| 20 |
+
* @returns {moment} A moment object
|
| 21 |
+
*/
|
| 22 |
+
export const roundTime = ( time, format = TIME_FORMAT_MM_SS ) => {
|
| 23 |
+
const seconds = toSeconds( time, format );
|
| 24 |
+
const overage = seconds % ( MINUTE_IN_SECONDS * 30 );
|
| 25 |
+
const roundedSeconds = seconds - overage;
|
| 26 |
+
return fromSeconds( roundedSeconds, format );
|
| 27 |
+
}
|
| 28 |
+
|
| 29 |
+
/**
|
| 30 |
+
* The code below is copied from the library hh-mm-ss
|
| 31 |
+
* Link: https://www.npmjs.com/package/hh-mm-ss
|
| 32 |
+
* The code has been copied so that Modern Tribe can maintain this library
|
| 33 |
+
* internally and adjust as needed.
|
| 34 |
+
*/
|
| 35 |
+
export const TIME_FORMAT_HH_MM_SS_SSS = 'hh:mm:ss.sss';
|
| 36 |
+
export const TIME_FORMAT_HH_MM_SS = 'hh:mm:ss';
|
| 37 |
+
export const TIME_FORMAT_HH_MM = 'hh:mm';
|
| 38 |
+
export const TIME_FORMAT_MM_SS_SSS = 'mm:ss.sss';
|
| 39 |
+
export const TIME_FORMAT_MM_SS = 'mm:ss';
|
| 40 |
+
|
| 41 |
+
export const SECOND_IN_MS = 1000;
|
| 42 |
+
export const MINUTE_IN_MS = MINUTE_IN_SECONDS * SECOND_IN_MS;
|
| 43 |
+
export const HOUR_IN_MS = HOUR_IN_SECONDS * SECOND_IN_MS;
|
| 44 |
+
|
| 45 |
+
/**
|
| 46 |
+
* Converts milliseconds to time in the format provided
|
| 47 |
+
*
|
| 48 |
+
* @param {int} ms Milliseconds to convert from
|
| 49 |
+
* @param {string} format Format of time to convert to
|
| 50 |
+
* @returns {string} Time string equivalent of milliseconds in format provided
|
| 51 |
+
*/
|
| 52 |
+
export const fromMilliseconds = ( ms, format = TIME_FORMAT_MM_SS ) => {
|
| 53 |
+
if ( typeof ms !== 'number' || Number.isNaN( ms ) ) {
|
| 54 |
+
/* eslint-disable-next-line max-len */
|
| 55 |
+
throw new Error( 'Argument `ms` provided to `fromMilliseconds` is not a number or is NaN.' );
|
| 56 |
+
}
|
| 57 |
+
|
| 58 |
+
const absMs = Math.abs( ms );
|
| 59 |
+
|
| 60 |
+
const negative = ( ms < 0 );
|
| 61 |
+
const hours = Math.floor( absMs / HOUR_IN_MS );
|
| 62 |
+
const minutes = Math.floor( absMs % HOUR_IN_MS / MINUTE_IN_MS );
|
| 63 |
+
const seconds = Math.floor( absMs % MINUTE_IN_MS / SECOND_IN_MS );
|
| 64 |
+
const miliseconds = Math.floor( absMs % SECOND_IN_MS );
|
| 65 |
+
|
| 66 |
+
return formatTime( {
|
| 67 |
+
negative,
|
| 68 |
+
hours,
|
| 69 |
+
minutes,
|
| 70 |
+
seconds,
|
| 71 |
+
miliseconds,
|
| 72 |
+
}, format );
|
| 73 |
+
};
|
| 74 |
+
|
| 75 |
+
/**
|
| 76 |
+
* Converts seconds to time in the format provided
|
| 77 |
+
*
|
| 78 |
+
* @param {int} s Seconds to convert from
|
| 79 |
+
* @param {string} format Format of time to convert to
|
| 80 |
+
* @returns {string} Time string equivalent of seconds in format provided
|
| 81 |
+
*/
|
| 82 |
+
export const fromSeconds = ( s, format = TIME_FORMAT_MM_SS ) => {
|
| 83 |
+
if ( typeof s !== 'number' || Number.isNaN( s ) ) {
|
| 84 |
+
/* eslint-disable-next-line max-len */
|
| 85 |
+
throw new Error( 'Argument `s` provided to `fromSeconds` is not a number or is NaN.' );
|
| 86 |
+
}
|
| 87 |
+
|
| 88 |
+
const ms = s * SECOND_IN_MS;
|
| 89 |
+
|
| 90 |
+
return fromMilliseconds( ms, format );
|
| 91 |
+
};
|
| 92 |
+
|
| 93 |
+
/**
|
| 94 |
+
* Converts time in the format provided to milliseconds
|
| 95 |
+
*
|
| 96 |
+
* @param {string} time Time string to convert from
|
| 97 |
+
* @param {string} format Format of time to convert from
|
| 98 |
+
* @returns {int} Milliseconds equivalent of time string in format provided
|
| 99 |
+
*/
|
| 100 |
+
export const toMilliseconds = ( time, format = TIME_FORMAT_MM_SS ) => {
|
| 101 |
+
let re;
|
| 102 |
+
|
| 103 |
+
if ( [
|
| 104 |
+
TIME_FORMAT_HH_MM_SS_SSS,
|
| 105 |
+
TIME_FORMAT_HH_MM_SS,
|
| 106 |
+
TIME_FORMAT_MM_SS_SSS,
|
| 107 |
+
TIME_FORMAT_MM_SS,
|
| 108 |
+
].includes( format ) ) {
|
| 109 |
+
re = /^(-)?(?:(\d\d+):)?(\d\d):(\d\d)(\.\d+)?$/;
|
| 110 |
+
} else if ( format === TIME_FORMAT_HH_MM ) {
|
| 111 |
+
re = /^(-)?(\d\d):(\d\d)(?::(\d\d)(?:(\.\d+))?)?$/;
|
| 112 |
+
} else {
|
| 113 |
+
/* eslint-disable-next-line max-len */
|
| 114 |
+
throw new Error( 'Argument `format` provided to `toMilliseconds` is not a recognized format.' );
|
| 115 |
+
}
|
| 116 |
+
|
| 117 |
+
const result = re.exec( time );
|
| 118 |
+
if ( ! result ) {
|
| 119 |
+
/* eslint-disable-next-line max-len */
|
| 120 |
+
throw new Error( 'Argument `time` provided to `toMilliseconds` is not a recognized format.' );
|
| 121 |
+
}
|
| 122 |
+
|
| 123 |
+
const negative = result[ 1 ] === '-';
|
| 124 |
+
const hours = result[ 2 ] | 0;
|
| 125 |
+
const minutes = result[ 3 ] | 0;
|
| 126 |
+
const seconds = result[ 4 ] | 0;
|
| 127 |
+
const miliseconds = Math.floor( 1000 * result[ 5 ] | 0 );
|
| 128 |
+
|
| 129 |
+
if ( minutes >= 60 || seconds >= 60 ) {
|
| 130 |
+
/* eslint-disable-next-line max-len */
|
| 131 |
+
throw new Error( 'Argument `time` provided to `toMilliseconds` contains minutes or seconds greater than 59.' );
|
| 132 |
+
}
|
| 133 |
+
|
| 134 |
+
return ( negative ? -1 : 1 ) * (
|
| 135 |
+
hours * HOUR_IN_MS
|
| 136 |
+
+ minutes * MINUTE_IN_MS
|
| 137 |
+
+ seconds * SECOND_IN_MS
|
| 138 |
+
+ miliseconds
|
| 139 |
+
);
|
| 140 |
+
};
|
| 141 |
+
|
| 142 |
+
/**
|
| 143 |
+
* Converts time in the format provided to seconds
|
| 144 |
+
*
|
| 145 |
+
* @param {string} time Time string to convert from
|
| 146 |
+
* @param {string} format Format of time to convert from
|
| 147 |
+
* @returns {int} Seconds equivalent of time string in format provided
|
| 148 |
+
*/
|
| 149 |
+
export const toSeconds = ( time, format = TIME_FORMAT_MM_SS ) => {
|
| 150 |
+
const ms = toMilliseconds( time, format );
|
| 151 |
+
return Math.floor( ms / SECOND_IN_MS );
|
| 152 |
+
};
|
| 153 |
+
|
| 154 |
+
/**
|
| 155 |
+
* Formats time object to time string in the format provided
|
| 156 |
+
*
|
| 157 |
+
* @param {object} time Time object to format from
|
| 158 |
+
* @param {string} format Format of time to format to
|
| 159 |
+
* @returns {string} Time string in format provided
|
| 160 |
+
*/
|
| 161 |
+
export const formatTime = ( time, format ) => {
|
| 162 |
+
let showMs;
|
| 163 |
+
let showSc;
|
| 164 |
+
let showHr;
|
| 165 |
+
|
| 166 |
+
switch ( format ) {
|
| 167 |
+
case TIME_FORMAT_HH_MM_SS_SSS:
|
| 168 |
+
showMs = true;
|
| 169 |
+
showSc = true;
|
| 170 |
+
showHr = true;
|
| 171 |
+
break;
|
| 172 |
+
case TIME_FORMAT_HH_MM_SS:
|
| 173 |
+
showMs = ! ! time.miliseconds;
|
| 174 |
+
showSc = true;
|
| 175 |
+
showHr = true;
|
| 176 |
+
break;
|
| 177 |
+
case TIME_FORMAT_HH_MM:
|
| 178 |
+
showMs = ! ! time.miliseconds;
|
| 179 |
+
showSc = showMs || ! ! time.seconds;
|
| 180 |
+
showHr = true;
|
| 181 |
+
break;
|
| 182 |
+
case TIME_FORMAT_MM_SS_SSS:
|
| 183 |
+
showMs = true;
|
| 184 |
+
showSc = true;
|
| 185 |
+
showHr = ! ! time.hours;
|
| 186 |
+
break;
|
| 187 |
+
case TIME_FORMAT_MM_SS:
|
| 188 |
+
showMs = ! ! time.miliseconds;
|
| 189 |
+
showSc = true;
|
| 190 |
+
showHr = ! ! time.hours;
|
| 191 |
+
break;
|
| 192 |
+
default:
|
| 193 |
+
/* eslint-disable-next-line max-len */
|
| 194 |
+
throw new Error( 'Argument `format` provided to `formatTime` is not a recognized format.' );
|
| 195 |
+
}
|
| 196 |
+
|
| 197 |
+
const hh = zeroFill( 2, time.hours );
|
| 198 |
+
const mm = zeroFill( 2, time.minutes );
|
| 199 |
+
const ss = zeroFill( 2, time.seconds );
|
| 200 |
+
const sss = zeroFill( 3, time.miliseconds );
|
| 201 |
+
|
| 202 |
+
return ( time.negative ? '-' : '' ) + ( showHr ? (
|
| 203 |
+
showMs ? `${hh}:${mm}:${ss}.${sss}` : showSc ? `${hh}:${mm}:${ss}` : `${hh}:${mm}`
|
| 204 |
+
) : (
|
| 205 |
+
showMs ? `${mm}:${ss}.${sss}` : `${mm}:${ss}`
|
| 206 |
+
) );
|
| 207 |
+
};
|
common/src/modules/utils/timezone.js
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* External dependencies
|
| 3 |
+
*/
|
| 4 |
+
import { find, flatten, map, get } from 'lodash';
|
| 5 |
+
|
| 6 |
+
/**
|
| 7 |
+
* Internal dependencies
|
| 8 |
+
*/
|
| 9 |
+
import { timezoneHtml } from '@moderntribe/common/utils/globals';
|
| 10 |
+
|
| 11 |
+
/**
|
| 12 |
+
* Module Code
|
| 13 |
+
*/
|
| 14 |
+
|
| 15 |
+
let timezoneOpts;
|
| 16 |
+
|
| 17 |
+
export const getTimezoneOpts = () => {
|
| 18 |
+
// Verify if we have it in cache solved
|
| 19 |
+
if ( timezoneOpts ) {
|
| 20 |
+
return timezoneOpts;
|
| 21 |
+
}
|
| 22 |
+
|
| 23 |
+
const $timezoneOpts = jQuery( timezoneHtml() );
|
| 24 |
+
const groups = [];
|
| 25 |
+
let number = 0;
|
| 26 |
+
|
| 27 |
+
$timezoneOpts.each( ( index, item ) => {
|
| 28 |
+
const $group = jQuery( item );
|
| 29 |
+
|
| 30 |
+
if ( ! $group.is( 'optgroup' ) ) {
|
| 31 |
+
return;
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
number++;
|
| 35 |
+
|
| 36 |
+
const label = $group.attr( 'label' );
|
| 37 |
+
const group = {
|
| 38 |
+
key: label,
|
| 39 |
+
text: label,
|
| 40 |
+
options: [],
|
| 41 |
+
};
|
| 42 |
+
|
| 43 |
+
$group.find( 'option' ).each( ( optIndex, optionEl ) => {
|
| 44 |
+
number++;
|
| 45 |
+
|
| 46 |
+
const $option = jQuery( optionEl );
|
| 47 |
+
group.options.push( {
|
| 48 |
+
key: $option.val(),
|
| 49 |
+
text: $option.text(),
|
| 50 |
+
index: number,
|
| 51 |
+
} );
|
| 52 |
+
} );
|
| 53 |
+
|
| 54 |
+
groups.push( group );
|
| 55 |
+
} );
|
| 56 |
+
|
| 57 |
+
// Save it in a cache
|
| 58 |
+
timezoneOpts = groups;
|
| 59 |
+
|
| 60 |
+
return groups;
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
export const getItems = ( searchFor ) => {
|
| 64 |
+
const groups = getTimezoneOpts();
|
| 65 |
+
|
| 66 |
+
if ( searchFor ) {
|
| 67 |
+
const opts = flatten( map( groups, 'options' ) );
|
| 68 |
+
return find( opts, searchFor );
|
| 69 |
+
}
|
| 70 |
+
|
| 71 |
+
return groups;
|
| 72 |
+
}
|
common/src/resources/css/accessibility.css
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* This CSS file was auto-generated via PostCSS
|
| 3 |
+
*
|
| 4 |
+
* Contributors should avoid editing this file, but instead edit the associated
|
| 5 |
+
* src/resources/postcss/ file. For more information, check out our engineering
|
| 6 |
+
* docs on how we handle CSS in our engineering docs.
|
| 7 |
+
*
|
| 8 |
+
* @see: http://moderntribe.github.io/products-engineering/css/
|
| 9 |
+
*/
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
/**
|
| 13 |
+
* Following rules set in this article about accessibility elements
|
| 14 |
+
*
|
| 15 |
+
* @link https://medium.com/@jessebeach/beware-smushed-off-screen-accessible-text-5952a4c2cbfe
|
| 16 |
+
*/
|
| 17 |
+
.tribe-js .tribe-accessible-js-hidden {
|
| 18 |
+
clip: rect( 1px 1px 1px 1px ); /* IE 6/7 */
|
| 19 |
+
clip: rect( 1px, 1px, 1px, 1px );
|
| 20 |
+
height: 1px;
|
| 21 |
+
overflow: hidden;
|
| 22 |
+
position: absolute;
|
| 23 |
+
white-space: nowrap; /* added line */
|
| 24 |
+
width: 1px;
|
| 25 |
+
}
|
| 26 |
+
.tribe-accessible-hidden {
|
| 27 |
+
clip: rect( 1px 1px 1px 1px ); /* IE 6/7 */
|
| 28 |
+
clip: rect( 1px, 1px, 1px, 1px );
|
| 29 |
+
height: 1px;
|
| 30 |
+
overflow: hidden;
|
| 31 |
+
position: absolute;
|
| 32 |
+
white-space: nowrap; /* added line */
|
| 33 |
+
width: 1px;
|
| 34 |
+
}
|
common/src/resources/css/app-shop.css
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* This CSS file was auto-generated via PostCSS
|
| 3 |
+
*
|
| 4 |
+
* Contributors should avoid editing this file, but instead edit the associated
|
| 5 |
+
* src/resources/postcss/ file. For more information, check out our engineering
|
| 6 |
+
* docs on how we handle CSS in our engineering docs.
|
| 7 |
+
*
|
| 8 |
+
* @see: http://moderntribe.github.io/products-engineering/css/
|
| 9 |
+
*/
|
| 10 |
+
|
| 11 |
+
#tribe-app-shop {
|
| 12 |
+
max-width: 960px;
|
| 13 |
+
}
|
| 14 |
+
|
| 15 |
+
#tribe-app-shop .addon-grid {
|
| 16 |
+
width: 100%;
|
| 17 |
+
}
|
| 18 |
+
|
| 19 |
+
#tribe-app-shop .header h1 {
|
| 20 |
+
display: inline-block;
|
| 21 |
+
}
|
| 22 |
+
|
| 23 |
+
#tribe-app-shop .header .button {
|
| 24 |
+
margin-top: 10px;
|
| 25 |
+
}
|
| 26 |
+
|
| 27 |
+
#tribe-app-shop .tribe-addon {
|
| 28 |
+
background-color: #fff;
|
| 29 |
+
border-bottom: 1px solid #dfdfdf;
|
| 30 |
+
display: inline-block;
|
| 31 |
+
margin: 0 15px 15px 0;
|
| 32 |
+
overflow: hidden;
|
| 33 |
+
padding: 0;
|
| 34 |
+
position: relative;
|
| 35 |
+
vertical-align: top;
|
| 36 |
+
width: 300px;
|
| 37 |
+
border-radius: 3px 3px 3px 3px;
|
| 38 |
+
box-sizing: border-box;
|
| 39 |
+
}
|
| 40 |
+
|
| 41 |
+
#tribe-app-shop .tribe-addon h4 {
|
| 42 |
+
font-size: 1.17em;
|
| 43 |
+
margin: 15px 0;
|
| 44 |
+
}
|
| 45 |
+
|
| 46 |
+
#tribe-app-shop .tribe-addon h4 a {
|
| 47 |
+
text-decoration: none;
|
| 48 |
+
}
|
| 49 |
+
|
| 50 |
+
#tribe-app-shop .tribe-addon .button {
|
| 51 |
+
bottom: 15px;
|
| 52 |
+
display: block;
|
| 53 |
+
position: absolute;
|
| 54 |
+
}
|
| 55 |
+
|
| 56 |
+
#tribe-app-shop .tribe-addon .button-disabled {
|
| 57 |
+
padding-left: 3px;
|
| 58 |
+
}
|
| 59 |
+
|
| 60 |
+
#tribe-app-shop .tribe-addon .button-disabled .dashicons {
|
| 61 |
+
font-size: 28px;
|
| 62 |
+
padding-right: 9px;
|
| 63 |
+
}
|
| 64 |
+
|
| 65 |
+
#tribe-app-shop .tribe-addon .caption {
|
| 66 |
+
padding: 0 15px 45px 15px;
|
| 67 |
+
}
|
| 68 |
+
|
| 69 |
+
#tribe-app-shop .tribe-addon .thumb img {
|
| 70 |
+
height: 228px;
|
| 71 |
+
max-width: 100%;
|
| 72 |
+
width: 300px;
|
| 73 |
+
}
|
| 74 |
+
|
| 75 |
+
#tribe-app-shop .tribe-addon.first {
|
| 76 |
+
margin: 20px 0;
|
| 77 |
+
overflow: hidden;
|
| 78 |
+
padding: 0;
|
| 79 |
+
width: 937px;
|
| 80 |
+
}
|
| 81 |
+
|
| 82 |
+
#tribe-app-shop .tribe-addon.first h4 {
|
| 83 |
+
font-size: 20px;
|
| 84 |
+
line-height: 1.4;
|
| 85 |
+
margin: 15px 0 0 0;
|
| 86 |
+
}
|
| 87 |
+
|
| 88 |
+
#tribe-app-shop .tribe-addon.first .caption {
|
| 89 |
+
display: inline-block;
|
| 90 |
+
padding-left: 20px;
|
| 91 |
+
width: 600px;
|
| 92 |
+
}
|
| 93 |
+
|
| 94 |
+
#tribe-app-shop .tribe-addon.first .thumb {
|
| 95 |
+
float: left;
|
| 96 |
+
height: 228px;
|
| 97 |
+
width: 300px;
|
| 98 |
+
}
|
| 99 |
+
|
| 100 |
+
#tribe-app-shop .tribe-installed-headline {
|
| 101 |
+
margin-bottom: 20px;
|
| 102 |
+
}
|
common/src/resources/css/app/components.css
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
| 1 |
+
.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout{margin:0}.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block{margin:0;max-width:100%!important;padding:0}.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block.is-hovered>.editor-block-list__block-edit:before,.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block.is-selected-parent>.editor-block-list__block-edit:before,.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block.is-selected>.editor-block-list__block-edit:before{outline:none}.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block .editor-block-list__block-edit{margin:0}.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block .editor-block-list__block-edit:before{outline:none}.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block .editor-block-list__block-edit .editor-block-contextual-toolbar{display:none}.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block{outline:none}
|
| 2 |
+
.tribe-common-form-select{display:flex}.tribe-common-form-select>div{flex:0 0 auto;min-width:193px}.tribe-common-form-select__toggle{background-color:#fff;border-radius:2px;border:2px solid #eaebec}.tribe-common-form-select__toggle button{align-items:center;background-color:#fefffe;border:none;color:#545d66;display:flex;font-family:Helvetica,sans-serif;font-size:16px;font-weight:400;justify-content:center;line-height:1.5;padding:6px 10px;text-align:left;text-decoration:none;width:100%}.tribe-common-form-select__toggle button>span{flex:1}.tribe-common-form-select__options__option{background:transparent;border:0;color:#555d66;cursor:pointer;display:block;line-height:20px;padding:5px 12px;text-align:left;width:100%}.tribe-common-form-select__options__option:hover{background-color:#009fd4;color:#fff}
|
common/src/resources/css/app/components.min.css
CHANGED
|
@@ -1,2 +1,2 @@
|
|
| 1 |
-
.tribe-common__plugin-block-hook .
|
| 2 |
-
.tribe-common-form-select{display
|
| 1 |
+
.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout{margin:0}.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block{margin:0;max-width:100%!important;padding:0}.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block.is-hovered>.editor-block-list__block-edit:before,.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block.is-selected-parent>.editor-block-list__block-edit:before,.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block.is-selected>.editor-block-list__block-edit:before{outline:none}.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block .editor-block-list__block-edit{margin:0}.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block .editor-block-list__block-edit:before{outline:none}.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block .editor-block-list__block-edit .editor-block-contextual-toolbar{display:none}.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block{outline:none}
|
| 2 |
+
.tribe-common-form-select{display:flex}.tribe-common-form-select>div{flex:0 0 auto;min-width:193px}.tribe-common-form-select__toggle{background-color:#fff;border-radius:2px;border:2px solid #eaebec}.tribe-common-form-select__toggle button{align-items:center;background-color:#fefffe;border:none;color:#545d66;display:flex;font-family:Helvetica,sans-serif;font-size:16px;font-weight:400;justify-content:center;line-height:1.5;padding:6px 10px;text-align:left;text-decoration:none;width:100%}.tribe-common-form-select__toggle button>span{flex:1}.tribe-common-form-select__options__option{background:transparent;border:0;color:#555d66;cursor:pointer;display:block;line-height:20px;padding:5px 12px;text-align:left;width:100%}.tribe-common-form-select__options__option:hover{background-color:#009fd4;color:#fff}
|
common/src/resources/css/app/elements.css
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
.tribe-editor__btn--label{background-color:transparent;border:none;padding:0;margin:0;text-align:left}.editor-styles-wrapper .tribe-editor__button,.tribe-editor__button{background-color:transparent;border:none;padding:0;margin:0;font-family:Helvetica,"sans-serif";cursor:pointer}.editor-styles-wrapper .tribe-editor__button[disabled],.tribe-editor__button[disabled]{cursor:default}.editor-styles-wrapper .tribe-editor__button--sm,.tribe-editor__button--sm{background-color:#009fd4;color:#fff;padding:11px 16px 9px;font-size:15px;font-weight:700;line-height:18px;transition:background-color .2s ease}.editor-styles-wrapper .tribe-editor__button--sm:focus,.editor-styles-wrapper .tribe-editor__button--sm:hover,.tribe-editor__button--sm:focus,.tribe-editor__button--sm:hover{background-color:#007bb4}.editor-styles-wrapper .tribe-editor__button--sm[disabled],.editor-styles-wrapper .tribe-editor__button--sm[disabled]:focus,.editor-styles-wrapper .tribe-editor__button--sm[disabled]:hover,.tribe-editor__button--sm[disabled],.tribe-editor__button--sm[disabled]:focus,.tribe-editor__button--sm[disabled]:hover{background-color:#f3f4f5;color:#8d949b}
|
| 2 |
+
.tribe-editor__accordion__row-content{max-height:0;overflow:hidden}.tribe-editor__accordion__row-content.active{max-height:none}
|
| 3 |
+
.editor-block-inspector__card .tribe-editor__icons__container{padding:4px;display:flex;align-items:center;justify-content:center}.editor-block-inspector__card .tribe-editor__icons__container svg{width:28px;height:28px}.editor-block-inspector__card .tribe-editor__icons--tec{background-color:#199fd1}button[class*=" editor-block-list-item-tribe-"] svg,button[class^=editor-block-list-item-tribe-] svg{color:#16a0d6}
|
| 4 |
+
.tribe-editor__counter{display:flex;flex-direction:column;align-items:center}.tribe-editor__counter__count{flex:none;color:#aeb4bb;font-size:32px;font-weight:700;line-height:40px;margin-bottom:10px}.tribe-editor__counter__label{flex:none;color:#aeb4bb;font-size:12px;line-height:14px;letter-spacing:.04px}
|
| 5 |
+
.edit-post-visual-editor .editor-block-list__block .tribe-editor__image-upload__title{padding:0;margin:0 0 12px;color:#000;font-size:15px;font-weight:700;line-height:18px}.tribe-editor__image-upload__content{display:flex;justify-content:space-between;align-items:center}.tribe-editor__image-upload--has-image .tribe-editor__image-upload__content{align-items:flex-start}.tribe-editor__image-upload__content p.tribe-editor__image-upload__description{flex:none;width:52%;font-family:Helvetica,sans-serif;font-size:14px;color:#545d66;line-height:18px;margin:0}.tribe-editor__image-upload__upload-button{flex:none;margin-right:10px}.tribe-editor__image-upload__image-wrapper{flex:none;width:42%;max-width:325px;padding-left:25px;position:relative}.tribe-editor__image-upload__remove-button{position:absolute;top:10px;right:10px;width:32px;height:32px;padding:8px;border-radius:50%;background-color:#f8f9fb}.tribe-editor__image-upload__remove-button>svg,.tribe-editor__image-upload__remove-button>svg path{fill:#545d66}.tribe-editor__image-upload__remove-button:focus>svg,.tribe-editor__image-upload__remove-button:focus>svg path,.tribe-editor__image-upload__remove-button:hover>svg,.tribe-editor__image-upload__remove-button:hover>svg path{fill:#009fd4}.tribe-editor__image-upload__remove-button:disabled:focus>svg,.tribe-editor__image-upload__remove-button:disabled:focus>svg path,.tribe-editor__image-upload__remove-button:disabled:hover>svg,.tribe-editor__image-upload__remove-button:disabled:hover>svg path,.tribe-editor__image-upload__remove-button:disabled>svg,.tribe-editor__image-upload__remove-button:disabled>svg path{fill:#aeb4bb}.tribe-editor__image-upload__remove-button-text{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}
|
| 6 |
+
.tribe-editor__rsvp .tribe-editor__label-with-link,.tribe-editor__ticket .tribe-editor__label-with-link{display:flex;align-items:center;background-color:#fff;padding:10px 17px;border:1px solid #e1e3e6}.tribe-editor__rsvp .tribe-editor__label-with-link .tribe-editor__labeled-item__label,.tribe-editor__ticket .tribe-editor__label-with-link .tribe-editor__labeled-item__label{flex:auto;color:#545d66;font-size:15px;font-weight:700;line-height:18px;letter-spacing:.38px;padding-right:10px}.tribe-editor__rsvp .tribe-editor__label-with-link .tribe-editor__label-with-link__link,.tribe-editor__ticket .tribe-editor__label-with-link .tribe-editor__label-with-link__link{flex:none;color:#009fd4;font-size:15px;font-weight:700;line-height:18px;letter-spacing:.38px;text-decoration:none;box-shadow:none;transition:color .2s ease}.tribe-editor__rsvp .tribe-editor__label-with-link .tribe-editor__label-with-link__link:focus,.tribe-editor__rsvp .tribe-editor__label-with-link .tribe-editor__label-with-link__link:hover,.tribe-editor__ticket .tribe-editor__label-with-link .tribe-editor__label-with-link__link:focus,.tribe-editor__ticket .tribe-editor__label-with-link .tribe-editor__label-with-link__link:hover{color:#007bb4}.tribe-editor__rsvp .tribe-editor__label-with-link .tribe-editor__label-with-link__link.tribe-editor__label-with-link__link--disabled,.tribe-editor__ticket .tribe-editor__label-with-link .tribe-editor__label-with-link__link.tribe-editor__label-with-link__link--disabled{color:#aeb4bb}
|
| 7 |
+
.tribe-editor__label-with-modal{display:flex;align-items:center;background-color:#fff;padding:11px 17px;border:1px solid #e1e3e6;height:40px}.tribe-editor__label-with-modal .tribe-editor__labeled-item__label{flex:auto;color:#545d66;font-size:15px;font-weight:700;line-height:18px;letter-spacing:.38px}.tribe-editor__label-with-modal .tribe-editor__label-with-modal__modal-button{flex:none}.tribe-editor__label-with-modal .tribe-editor__modal-button__button{color:#009fd4;font-size:15px;font-weight:700;line-height:18px;letter-spacing:.38px;transition:color .2s ease}.tribe-editor__label-with-modal .tribe-editor__modal-button__button:focus,.tribe-editor__label-with-modal .tribe-editor__modal-button__button:hover{color:#007bb4}.tribe-editor__label-with-modal .tribe-editor__modal-button__button:disabled,.tribe-editor__label-with-modal .tribe-editor__modal-button__button:disabled:focus,.tribe-editor__label-with-modal .tribe-editor__modal-button__button:disabled:hover{color:#aeb4bb}
|
| 8 |
+
.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout{margin:0}.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block{margin:0;max-width:100%!important;padding:0}.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block.is-hovered>.editor-block-list__block-edit:before,.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block.is-selected-parent>.editor-block-list__block-edit:before,.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block.is-selected>.editor-block-list__block-edit:before{outline:none}.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block .editor-block-list__block-edit{margin:0}.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block .editor-block-list__block-edit:before{outline:none}.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block .editor-block-list__block-edit .editor-block-contextual-toolbar{display:none}.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block{outline:none}
|
| 9 |
+
.tribe-common-form-select{display:flex}.tribe-common-form-select>div{flex:0 0 auto;min-width:193px}.tribe-common-form-select__toggle{background-color:#fff;border-radius:2px;border:2px solid #eaebec}.tribe-common-form-select__toggle button{align-items:center;background-color:#fefffe;border:none;color:#545d66;display:flex;font-family:Helvetica,sans-serif;font-size:16px;font-weight:400;justify-content:center;line-height:1.5;padding:6px 10px;text-align:left;text-decoration:none;width:100%}.tribe-common-form-select__toggle button>span{flex:1}.tribe-common-form-select__options__option{background:transparent;border:0;color:#555d66;cursor:pointer;display:block;line-height:20px;padding:5px 12px;text-align:left;width:100%}.tribe-common-form-select__options__option:hover{background-color:#009fd4;color:#fff}
|
| 10 |
+
input.tribe-editor__input[type=number],input.tribe-editor__input[type=text]{color:#000;font-size:16px;line-height:24px;border:1px solid #e1e3e6;padding:7px 15px;margin:0;height:40px}input.tribe-editor__input[type=number]:focus,input.tribe-editor__input[type=text]:focus{color:#000;box-shadow:none;outline:none}input.tribe-editor__input[type=number]:disabled,input.tribe-editor__input[type=text]:disabled{color:#aeb4bb}
|
| 11 |
+
.tribe-editor__timepicker{display:inline-block}.tribe-editor__timepicker__toggle{background-color:#fff;border:1px solid #e1e3e6;border-radius:2px;display:flex;align-items:center;justify-content:center}.tribe-editor__timepicker__toggle input.tribe-editor__timepicker__input[type=text]{font-family:Helvetica,sans-serif;font-size:14px;line-height:1.5;padding:6px 0 6px 10px;border:none;width:80px}.tribe-editor__timepicker__toggle button.tribe-editor__timepicker__toggle-btn{padding:10px}.tribe-editor__timepicker__toggle button.tribe-editor__timepicker__toggle-btn:disabled>svg.dashicon{fill:#aeb4bb}.tribe-editor__timepicker__toggle button.tribe-editor__timepicker__all-day-btn{color:#545d66;line-height:20px;padding:6px 10px;text-decoration:none;display:flex;align-items:center;justify-content:center}.tribe-editor__timepicker__content.components-popover .components-popover__content{min-width:110px}.tribe-editor__timepicker__content .tribe-editor__timepicker__items{height:250px;overflow:auto}.tribe-editor__timepicker__content .tribe-editor__timepicker__items .components-placeholder{height:inherit}.tribe-editor__timepicker__content .tribe-editor__timepicker__item{display:block;width:100%;color:#555d66;padding:5px 12px;cursor:pointer;border-bottom:1px solid #e2e4e7;line-height:20px;background:transparent;text-align:left}.tribe-editor__timepicker__content .tribe-editor__timepicker__item:focus,.tribe-editor__timepicker__content .tribe-editor__timepicker__item:hover{background-color:#e7f5fa}.tribe-editor__timepicker__content .tribe-editor__timepicker__item--current,.tribe-editor__timepicker__content .tribe-editor__timepicker__item--current:focus,.tribe-editor__timepicker__content .tribe-editor__timepicker__item--current:hover{color:#fff;background-color:#009fd4}
|
| 12 |
+
.DayPicker{display:inline-block;font-size:1rem}.DayPicker-wrapper{position:relative;flex-direction:row;padding-bottom:1em;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.DayPicker-Months{display:flex;flex-wrap:wrap;justify-content:center}.DayPicker-Month{display:table;margin:0 1em;margin-top:1em;border-spacing:0;border-collapse:collapse;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.DayPicker-NavButton{position:absolute;top:1em;right:1.5em;left:auto;display:inline-block;margin-top:2px;width:1.25em;height:1.25em;background-position:50%;background-size:50%;background-repeat:no-repeat;color:#8b9898;cursor:pointer}.DayPicker-NavButton:hover{opacity:.8}.DayPicker-NavButton--prev{margin-right:1.5em;background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAwCAYAAAB5R9gVAAAABGdBTUEAALGPC/xhBQAAAVVJREFUWAnN2G0KgjAYwPHpGfRkaZeqvgQaK+hY3SUHrk1YzNLay/OiEFp92I+/Mp2F2Mh2lLISWnflFjzH263RQjzMZ19wgs73ez0o1WmtW+dgA01VxrE3p6l2GLsnBy1VYQOtVSEH/atCCgqpQgKKqYIOiq2CBkqtggLKqQIKgqgCBjpJ2Y5CdJ+zrT9A7HHSTA1dxUdHgzCqJIEwq0SDsKsEg6iqBIEoq/wEcVRZBXFV+QJxV5mBtlDFB5VjYTaGZ2sf4R9PM7U9ZU+lLuaetPP/5Die3ToO1+u+MKtHs06qODB2zBnI/jBd4MPQm1VkY79Tb18gB+C62FdBFsZR6yeIo1YQiLJWMIiqVjQIu1YSCLNWFgijVjYIuhYYCKoWKAiiFgoopxYaKLUWOii2FgkophYp6F3r42W5A9s9OcgNvva8xQaysKXlFytoqdYmQH6tF3toSUo0INq9AAAAAElFTkSuQmCC")}.DayPicker-NavButton--next{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAwCAYAAAB5R9gVAAAABGdBTUEAALGPC/xhBQAAAXRJREFUWAnN119ugjAcwPHWzJ1gnmxzB/BBE0n24m4xfNkTaOL7wOtsl3AXMMb+Vjaa1BG00N8fSEibPpAP3xAKKs2yjzTPH9RAjhEo9WzPr/Vm8zgE0+gXATAxxuxtqeJ9t5tIwv5AtQAApsfT6TPdbp+kUBcgVwvO51KqVhMkXKsVJFXrOkigVhCIs1Y4iKlWZxB1rX4gwlpRIIpa8SDkWmggrFq4IIRaJKCYWnSgnrXIQV1r8YD+1Vrn+bReagysIFfLABRt31v8oBu1xEBttfRbltmfjgEcWh9snUS2kNdBK6WN1vrOWxObWsz+fjxevsxmB1GQDfINWiev83nhaoiB/CoOU438oPrhXS0WpQ9xc1ZQWxWHqUYe0I0qrKCQKjygDlXIQV2r0IF6ViEBxVTBBSFUQQNhVYkHIVeJAtkNsbQ7c1LtzP6FsObhb2rCKv7NBIGoq4SDmKoEgTirXAcJVGkFSVVpgoSrXICGUMUH/QBZNSUy5XWUhwAAAABJRU5ErkJggg==")}.DayPicker-NavButton--interactionDisabled{display:none}.DayPicker-Caption{display:table-caption;margin-bottom:.5em;padding:0 .5em;text-align:left}.DayPicker-Caption>div{font-weight:500;font-size:1.15em}.DayPicker-Weekdays{display:table-header-group;margin-top:1em}.DayPicker-WeekdaysRow{display:table-row}.DayPicker-Weekday{display:table-cell;padding:.5em;color:#8b9898;text-align:center;font-size:.875em}.DayPicker-Weekday abbr[title]{border-bottom:none;text-decoration:none}.DayPicker-Body{display:table-row-group}.DayPicker-Week{display:table-row}.DayPicker-Day{border-radius:50%;text-align:center}.DayPicker-Day,.DayPicker-WeekNumber{display:table-cell;padding:.5em;vertical-align:middle;cursor:pointer}.DayPicker-WeekNumber{min-width:1em;border-right:1px solid #eaecec;color:#8b9898;text-align:right;font-size:.75em}.DayPicker--interactionDisabled .DayPicker-Day{cursor:default}.DayPicker-Footer{padding-top:.5em}.DayPicker-TodayButton{border:none;background-color:transparent;background-image:none;box-shadow:none;color:#4a90e2;font-size:.875em;cursor:pointer}.DayPicker-Day--today{color:#d0021b;font-weight:700}.DayPicker-Day--outside{color:#8b9898;cursor:default}.DayPicker-Day--disabled{color:#dce0e0;cursor:default}.DayPicker-Day--sunday{background-color:#f7f8f8}.DayPicker-Day--sunday:not(.DayPicker-Day--today){color:#dce0e0}.DayPicker-Day--selected:not(.DayPicker-Day--disabled):not(.DayPicker-Day--outside){position:relative;background-color:#4a90e2;color:#f0f8ff}.DayPicker-Day--selected:not(.DayPicker-Day--disabled):not(.DayPicker-Day--outside):hover{background-color:#51a0fa}.DayPicker:not(.DayPicker--interactionDisabled) .DayPicker-Day:not(.DayPicker-Day--disabled):not(.DayPicker-Day--selected):not(.DayPicker-Day--outside):hover{background-color:#f0f8ff}.DayPickerInput{display:inline-block}.DayPickerInput-OverlayWrapper{position:relative}.DayPickerInput-Overlay{position:absolute;left:0;z-index:1;background:#fff;box-shadow:0 2px 5px rgba(0,0,0,.15)}
|
| 13 |
+
.tribe-editor__day-picker-input.DayPickerInput>input{border:1px solid #e1e3e6;color:#545d66;font-size:16px;line-height:24px;padding:7px 15px;width:100%;height:40px}.tribe-editor__day-picker-input.DayPickerInput>input:disabled{color:#aeb4bb}.tribe-editor__day-picker-input .DayPickerInput-Overlay{padding:20px;z-index:10}.tribe-editor__day-picker-input .DayPicker{width:100%}.tribe-editor__day-picker-input .DayPicker-Month{margin:0}.tribe-editor__day-picker-input .DayPicker-Caption>div,.tribe-editor__day-picker-input .DayPicker-Day,.tribe-editor__day-picker-input .DayPicker-Weekday{color:#545d66;font-family:Helvetica,"sans-serif";font-weight:400}.tribe-editor__day-picker-input .DayPicker-Caption>div{font-size:16px;margin-bottom:12px;text-align:center}.tribe-editor__day-picker-input .DayPicker-Weekday{font-size:12px}.tribe-editor__day-picker-input .DayPicker-Day{font-size:14px}.tribe-editor__day-picker-input .DayPicker-Day:hover{color:#007bb4;background-color:#fff}.tribe-editor__day-picker-input .DayPicker-Day--today{color:#545d66}.tribe-editor__day-picker-input .DayPicker-Day--disabled{pointer-events:none;color:#ccc}.tribe-editor__day-picker-input .DayPicker-Day--selected:not(.DayPicker-Day--outside){border-radius:0;background-color:#009fd4;color:#fff}.tribe-editor__day-picker-input .DayPicker-Day--selected:not(.DayPicker-Day--outside):hover{background-color:#007bb4;color:#fff}.tribe-editor__day-picker-input .DayPicker-NavButton--prev{left:0;top:0}.tribe-editor__day-picker-input .DayPicker-NavButton--next{right:0;top:0}.tribe-editor__day-picker-input .DayPicker:not(.DayPicker--interactionDisabled) .DayPicker-Day:not(.DayPicker-Day--disabled):not(.DayPicker-Day--selected):not(.DayPicker-Day--outside):hover{background-color:#fff}.tribe-editor__day-picker-input .DayPicker-Day--selected:not(.DayPicker-Day--start):not(.DayPicker-Day--end):not(.DayPicker-Day--outside){background-color:#e7f5fa;color:#545d66}.tribe-editor__day-picker-input .DayPicker-Day--selected:not(.DayPicker-Day--start):not(.DayPicker-Day--end):not(.DayPicker-Day--outside):hover{color:#007bb4}
|
| 14 |
+
.tribe-editor__creatable-select .tribe-editor__creatable-select__control{height:40px;border:1px solid #e1e3e6;border-radius:3px;background-color:#fff}.tribe-editor__creatable-select .tribe-editor__creatable-select__control:hover{border:1px solid #e1e3e6}.tribe-editor__creatable-select .tribe-editor__creatable-select__control--is-focused{box-shadow:none}.tribe-editor__creatable-select .tribe-editor__creatable-select__value-container{padding:2px 5px 2px 15px}.tribe-editor__creatable-select .tribe-editor__creatable-select__single-value{margin:0;max-width:calc(100% - 15px);font-size:16px;line-height:1.5}.tribe-editor__creatable-select .tribe-editor__creatable-select__input{font-size:16px}.tribe-editor__creatable-select .tribe-editor__creatable-select__input>input{margin:0;line-height:1.5}.tribe-editor__creatable-select .tribe-editor__creatable-select__input>input,.tribe-editor__creatable-select .tribe-editor__creatable-select__input>input:focus{box-shadow:none}.tribe-editor__creatable-select svg.tribe-editor__creatable-select__dropdown-indicator{fill:#555d66}.tribe-editor__creatable-select .tribe-editor__creatable-select__menu{margin:0;border:1px solid #e1e3e6;border-top:none;border-radius:0;border-bottom-left-radius:3px;border-bottom-right-radius:3px;box-shadow:none;-webkit-transform:translateY(-7px);transform:translateY(-7px)}.tribe-editor__creatable-select .tribe-editor__creatable-select__menu-list{padding:0}.tribe-editor__creatable-select .tribe-editor__creatable-select__option{font-size:16px;line-height:1.5;padding:3px 15px}.tribe-editor__creatable-select .tribe-editor__creatable-select__option--is-focused{background-color:#e7f5fa}.tribe-editor__creatable-select .tribe-editor__creatable-select__option--is-selected{background-color:#11a0d2}
|
| 15 |
+
.tribe-editor__placeholder{border:2px dashed #e1e3e6;padding:12px 15px 14px;text-align:center;font-family:Helvetica,Arial,"sans-serif";font-size:1rem;line-height:1.5;font-weight:700;color:#8d949b;min-width:260px;display:inline-block}
|
| 16 |
+
.tribe-editor__heading{font-family:Helvetica,Arial,"sans-serif";color:#000}.tribe-editor__heading--h1{font-size:2.375rem}.tribe-editor__heading--h2{font-size:1.3125rem}.tribe-editor__heading--h3{font-size:1rem}
|
| 17 |
+
.tribe-editor__paragraph{font-family:Helvetica,Arial,"sans-serif";line-height:1.5;font-weight:400}.tribe-editor__paragraph--medium{font-size:1rem}.tribe-editor__paragraph--small{font-size:.875rem}.tribe-editor__paragraph a{color:#11a0d2}.tribe-editor__paragraph a:hover{text-decoration:none;color:#007bb4}
|
| 18 |
+
input[type=checkbox].tribe-editor__input--checkbox{background-color:#fff;border:1px solid #e0e5e9;border-radius:0}input[type=checkbox].tribe-editor__input--checkbox:focus{border:1px solid #e0e5e9;box-shadow:0 0 0 1px #e0e5e9}input[type=checkbox].tribe-editor__input--checkbox:checked{background-color:#fff;border:1px solid #e0e5e9}input[type=checkbox].tribe-editor__input--checkbox:checked:focus{border:1px solid #e0e5e9;box-shadow:0 0 0 1px #e0e5e9}input[type=checkbox].tribe-editor__input--checkbox:checked:before{color:#11a0d2}
|
| 19 |
+
.tribe-editor__select .tribe-editor__select__control{height:46px;border:1px solid #e1e3e6;border-radius:3px;background-color:#fff}.tribe-editor__select .tribe-editor__select__control:hover{border:1px solid #e1e3e6}.tribe-editor__select .tribe-editor__select__control--is-focused{box-shadow:none}.tribe-editor__select .tribe-editor__select__value-container{padding:2px 10px 2px 15px}.tribe-editor__select .tribe-editor__select__single-value{margin:0;max-width:calc(100% - 15px);font-size:16px;line-height:1.5}.tribe-editor__select .tribe-editor__select__input{font-size:16px}.tribe-editor__select .tribe-editor__select__input>input{margin:0;line-height:1.5}.tribe-editor__select svg.tribe-editor__select__dropdown-indicator{fill:#555d66}.tribe-editor__select .tribe-editor__select__menu{margin:0;border:1px solid #e1e3e6;border-top:none;border-radius:0;border-bottom-left-radius:3px;border-bottom-right-radius:3px;box-shadow:none;-webkit-transform:translateY(-7px);transform:translateY(-7px);z-index:10}.tribe-editor__select .tribe-editor__select__menu-list{padding:0}.tribe-editor__select .tribe-editor__select__option{font-size:16px;line-height:1.5;padding:3px 15px}.tribe-editor__select .tribe-editor__select__option--is-focused{background-color:#e7f5fa}.tribe-editor__select .tribe-editor__select__option--is-selected{background-color:#11a0d2}.tribe-editor__select--is-disabled svg.tribe-editor__select__dropdown-indicator{fill:#aeb4bb}
|
| 20 |
+
.post-type-tribe_events .editor-styles-wrapper{max-width:none!important}
|
common/src/resources/css/app/elements.min.css
CHANGED
|
@@ -1,15 +1,15 @@
|
|
| 1 |
-
.tribe-editor__btn--label{background-color:transparent;border:none;padding:0;margin:0;text-align:left}.editor-styles-wrapper .tribe-editor__button,.tribe-editor__button{background-color:transparent;border:none;padding:0;margin:0;font-family:Helvetica,"sans-serif";cursor:pointer}.editor-styles-wrapper .tribe-editor__button[disabled],.tribe-editor__button[disabled]{cursor:default}.editor-styles-wrapper .tribe-editor__button--sm,.tribe-editor__button--sm{background-color:#009fd4;color:#fff;padding:11px 16px 9px;font-size:15px;font-weight:700;line-height:18px
|
| 2 |
.tribe-editor__accordion__row-content{max-height:0;overflow:hidden}.tribe-editor__accordion__row-content.active{max-height:none}
|
| 3 |
-
.editor-block-inspector__card .tribe-editor__icons__container{padding:4px;display
|
| 4 |
-
.tribe-editor__counter{display
|
| 5 |
-
.edit-post-visual-editor .editor-block-list__block .tribe-editor__image-upload__title{padding:0;margin:0 0 12px;color:#000;font-size:15px;font-weight:700;line-height:18px}.tribe-editor__image-upload__content{display
|
| 6 |
-
.tribe-editor__rsvp .tribe-editor__label-with-link,.tribe-editor__ticket .tribe-editor__label-with-link{display
|
| 7 |
-
.tribe-editor__label-with-modal{display
|
| 8 |
-
.tribe-common__plugin-block-hook .
|
| 9 |
-
.tribe-common-form-select{display
|
| 10 |
input.tribe-editor__input[type=number],input.tribe-editor__input[type=text]{color:#000;font-size:16px;line-height:24px;border:1px solid #e1e3e6;padding:7px 15px;margin:0;height:40px}input.tribe-editor__input[type=number]:focus,input.tribe-editor__input[type=text]:focus{color:#000;box-shadow:none;outline:none}input.tribe-editor__input[type=number]:disabled,input.tribe-editor__input[type=text]:disabled{color:#aeb4bb}
|
| 11 |
-
.tribe-editor__timepicker{display:inline-block}.tribe-editor__timepicker__toggle{background-color:#fff;border:1px solid #e1e3e6;border-radius:2px;display
|
| 12 |
-
.DayPicker{display:inline-block;font-size:1rem}.DayPicker-wrapper{position:relative
|
| 13 |
.tribe-editor__day-picker-input.DayPickerInput>input{border:1px solid #e1e3e6;color:#545d66;font-size:16px;line-height:24px;padding:7px 15px;width:100%;height:40px}.tribe-editor__day-picker-input.DayPickerInput>input:disabled{color:#aeb4bb}.tribe-editor__day-picker-input .DayPickerInput-Overlay{padding:20px;z-index:10}.tribe-editor__day-picker-input .DayPicker{width:100%}.tribe-editor__day-picker-input .DayPicker-Month{margin:0}.tribe-editor__day-picker-input .DayPicker-Caption>div,.tribe-editor__day-picker-input .DayPicker-Day,.tribe-editor__day-picker-input .DayPicker-Weekday{color:#545d66;font-family:Helvetica,"sans-serif";font-weight:400}.tribe-editor__day-picker-input .DayPicker-Caption>div{font-size:16px;margin-bottom:12px;text-align:center}.tribe-editor__day-picker-input .DayPicker-Weekday{font-size:12px}.tribe-editor__day-picker-input .DayPicker-Day{font-size:14px}.tribe-editor__day-picker-input .DayPicker-Day:hover{color:#007bb4;background-color:#fff}.tribe-editor__day-picker-input .DayPicker-Day--today{color:#545d66}.tribe-editor__day-picker-input .DayPicker-Day--disabled{pointer-events:none;color:#ccc}.tribe-editor__day-picker-input .DayPicker-Day--selected:not(.DayPicker-Day--outside){border-radius:0;background-color:#009fd4;color:#fff}.tribe-editor__day-picker-input .DayPicker-Day--selected:not(.DayPicker-Day--outside):hover{background-color:#007bb4;color:#fff}.tribe-editor__day-picker-input .DayPicker-NavButton--prev{left:0;top:0}.tribe-editor__day-picker-input .DayPicker-NavButton--next{right:0;top:0}.tribe-editor__day-picker-input .DayPicker:not(.DayPicker--interactionDisabled) .DayPicker-Day:not(.DayPicker-Day--disabled):not(.DayPicker-Day--selected):not(.DayPicker-Day--outside):hover{background-color:#fff}.tribe-editor__day-picker-input .DayPicker-Day--selected:not(.DayPicker-Day--start):not(.DayPicker-Day--end):not(.DayPicker-Day--outside){background-color:#e7f5fa;color:#545d66}.tribe-editor__day-picker-input .DayPicker-Day--selected:not(.DayPicker-Day--start):not(.DayPicker-Day--end):not(.DayPicker-Day--outside):hover{color:#007bb4}
|
| 14 |
.tribe-editor__creatable-select .tribe-editor__creatable-select__control{height:40px;border:1px solid #e1e3e6;border-radius:3px;background-color:#fff}.tribe-editor__creatable-select .tribe-editor__creatable-select__control:hover{border:1px solid #e1e3e6}.tribe-editor__creatable-select .tribe-editor__creatable-select__control--is-focused{box-shadow:none}.tribe-editor__creatable-select .tribe-editor__creatable-select__value-container{padding:2px 5px 2px 15px}.tribe-editor__creatable-select .tribe-editor__creatable-select__single-value{margin:0;max-width:calc(100% - 15px);font-size:16px;line-height:1.5}.tribe-editor__creatable-select .tribe-editor__creatable-select__input{font-size:16px}.tribe-editor__creatable-select .tribe-editor__creatable-select__input>input{margin:0;line-height:1.5}.tribe-editor__creatable-select .tribe-editor__creatable-select__input>input,.tribe-editor__creatable-select .tribe-editor__creatable-select__input>input:focus{box-shadow:none}.tribe-editor__creatable-select svg.tribe-editor__creatable-select__dropdown-indicator{fill:#555d66}.tribe-editor__creatable-select .tribe-editor__creatable-select__menu{margin:0;border:1px solid #e1e3e6;border-top:none;border-radius:0;border-bottom-left-radius:3px;border-bottom-right-radius:3px;box-shadow:none;-webkit-transform:translateY(-7px);transform:translateY(-7px)}.tribe-editor__creatable-select .tribe-editor__creatable-select__menu-list{padding:0}.tribe-editor__creatable-select .tribe-editor__creatable-select__option{font-size:16px;line-height:1.5;padding:3px 15px}.tribe-editor__creatable-select .tribe-editor__creatable-select__option--is-focused{background-color:#e7f5fa}.tribe-editor__creatable-select .tribe-editor__creatable-select__option--is-selected{background-color:#11a0d2}
|
| 15 |
.tribe-editor__placeholder{border:2px dashed #e1e3e6;padding:12px 15px 14px;text-align:center;font-family:Helvetica,Arial,"sans-serif";font-size:1rem;line-height:1.5;font-weight:700;color:#8d949b;min-width:260px;display:inline-block}
|
| 1 |
+
.tribe-editor__btn--label{background-color:transparent;border:none;padding:0;margin:0;text-align:left}.editor-styles-wrapper .tribe-editor__button,.tribe-editor__button{background-color:transparent;border:none;padding:0;margin:0;font-family:Helvetica,"sans-serif";cursor:pointer}.editor-styles-wrapper .tribe-editor__button[disabled],.tribe-editor__button[disabled]{cursor:default}.editor-styles-wrapper .tribe-editor__button--sm,.tribe-editor__button--sm{background-color:#009fd4;color:#fff;padding:11px 16px 9px;font-size:15px;font-weight:700;line-height:18px;transition:background-color .2s ease}.editor-styles-wrapper .tribe-editor__button--sm:focus,.editor-styles-wrapper .tribe-editor__button--sm:hover,.tribe-editor__button--sm:focus,.tribe-editor__button--sm:hover{background-color:#007bb4}.editor-styles-wrapper .tribe-editor__button--sm[disabled],.editor-styles-wrapper .tribe-editor__button--sm[disabled]:focus,.editor-styles-wrapper .tribe-editor__button--sm[disabled]:hover,.tribe-editor__button--sm[disabled],.tribe-editor__button--sm[disabled]:focus,.tribe-editor__button--sm[disabled]:hover{background-color:#f3f4f5;color:#8d949b}
|
| 2 |
.tribe-editor__accordion__row-content{max-height:0;overflow:hidden}.tribe-editor__accordion__row-content.active{max-height:none}
|
| 3 |
+
.editor-block-inspector__card .tribe-editor__icons__container{padding:4px;display:flex;align-items:center;justify-content:center}.editor-block-inspector__card .tribe-editor__icons__container svg{width:28px;height:28px}.editor-block-inspector__card .tribe-editor__icons--tec{background-color:#199fd1}button[class*=" editor-block-list-item-tribe-"] svg,button[class^=editor-block-list-item-tribe-] svg{color:#16a0d6}
|
| 4 |
+
.tribe-editor__counter{display:flex;flex-direction:column;align-items:center}.tribe-editor__counter__count{flex:none;color:#aeb4bb;font-size:32px;font-weight:700;line-height:40px;margin-bottom:10px}.tribe-editor__counter__label{flex:none;color:#aeb4bb;font-size:12px;line-height:14px;letter-spacing:.04px}
|
| 5 |
+
.edit-post-visual-editor .editor-block-list__block .tribe-editor__image-upload__title{padding:0;margin:0 0 12px;color:#000;font-size:15px;font-weight:700;line-height:18px}.tribe-editor__image-upload__content{display:flex;justify-content:space-between;align-items:center}.tribe-editor__image-upload--has-image .tribe-editor__image-upload__content{align-items:flex-start}.tribe-editor__image-upload__content p.tribe-editor__image-upload__description{flex:none;width:52%;font-family:Helvetica,sans-serif;font-size:14px;color:#545d66;line-height:18px;margin:0}.tribe-editor__image-upload__upload-button{flex:none;margin-right:10px}.tribe-editor__image-upload__image-wrapper{flex:none;width:42%;max-width:325px;padding-left:25px;position:relative}.tribe-editor__image-upload__remove-button{position:absolute;top:10px;right:10px;width:32px;height:32px;padding:8px;border-radius:50%;background-color:#f8f9fb}.tribe-editor__image-upload__remove-button>svg,.tribe-editor__image-upload__remove-button>svg path{fill:#545d66}.tribe-editor__image-upload__remove-button:focus>svg,.tribe-editor__image-upload__remove-button:focus>svg path,.tribe-editor__image-upload__remove-button:hover>svg,.tribe-editor__image-upload__remove-button:hover>svg path{fill:#009fd4}.tribe-editor__image-upload__remove-button:disabled:focus>svg,.tribe-editor__image-upload__remove-button:disabled:focus>svg path,.tribe-editor__image-upload__remove-button:disabled:hover>svg,.tribe-editor__image-upload__remove-button:disabled:hover>svg path,.tribe-editor__image-upload__remove-button:disabled>svg,.tribe-editor__image-upload__remove-button:disabled>svg path{fill:#aeb4bb}.tribe-editor__image-upload__remove-button-text{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}
|
| 6 |
+
.tribe-editor__rsvp .tribe-editor__label-with-link,.tribe-editor__ticket .tribe-editor__label-with-link{display:flex;align-items:center;background-color:#fff;padding:10px 17px;border:1px solid #e1e3e6}.tribe-editor__rsvp .tribe-editor__label-with-link .tribe-editor__labeled-item__label,.tribe-editor__ticket .tribe-editor__label-with-link .tribe-editor__labeled-item__label{flex:auto;color:#545d66;font-size:15px;font-weight:700;line-height:18px;letter-spacing:.38px;padding-right:10px}.tribe-editor__rsvp .tribe-editor__label-with-link .tribe-editor__label-with-link__link,.tribe-editor__ticket .tribe-editor__label-with-link .tribe-editor__label-with-link__link{flex:none;color:#009fd4;font-size:15px;font-weight:700;line-height:18px;letter-spacing:.38px;text-decoration:none;box-shadow:none;transition:color .2s ease}.tribe-editor__rsvp .tribe-editor__label-with-link .tribe-editor__label-with-link__link:focus,.tribe-editor__rsvp .tribe-editor__label-with-link .tribe-editor__label-with-link__link:hover,.tribe-editor__ticket .tribe-editor__label-with-link .tribe-editor__label-with-link__link:focus,.tribe-editor__ticket .tribe-editor__label-with-link .tribe-editor__label-with-link__link:hover{color:#007bb4}.tribe-editor__rsvp .tribe-editor__label-with-link .tribe-editor__label-with-link__link.tribe-editor__label-with-link__link--disabled,.tribe-editor__ticket .tribe-editor__label-with-link .tribe-editor__label-with-link__link.tribe-editor__label-with-link__link--disabled{color:#aeb4bb}
|
| 7 |
+
.tribe-editor__label-with-modal{display:flex;align-items:center;background-color:#fff;padding:11px 17px;border:1px solid #e1e3e6;height:40px}.tribe-editor__label-with-modal .tribe-editor__labeled-item__label{flex:auto;color:#545d66;font-size:15px;font-weight:700;line-height:18px;letter-spacing:.38px}.tribe-editor__label-with-modal .tribe-editor__label-with-modal__modal-button{flex:none}.tribe-editor__label-with-modal .tribe-editor__modal-button__button{color:#009fd4;font-size:15px;font-weight:700;line-height:18px;letter-spacing:.38px;transition:color .2s ease}.tribe-editor__label-with-modal .tribe-editor__modal-button__button:focus,.tribe-editor__label-with-modal .tribe-editor__modal-button__button:hover{color:#007bb4}.tribe-editor__label-with-modal .tribe-editor__modal-button__button:disabled,.tribe-editor__label-with-modal .tribe-editor__modal-button__button:disabled:focus,.tribe-editor__label-with-modal .tribe-editor__modal-button__button:disabled:hover{color:#aeb4bb}
|
| 8 |
+
.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout{margin:0}.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block{margin:0;max-width:100%!important;padding:0}.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block.is-hovered>.editor-block-list__block-edit:before,.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block.is-selected-parent>.editor-block-list__block-edit:before,.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block.is-selected>.editor-block-list__block-edit:before{outline:none}.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block .editor-block-list__block-edit{margin:0}.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block .editor-block-list__block-edit:before{outline:none}.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block .editor-block-list__block-edit .editor-block-contextual-toolbar{display:none}.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block{outline:none}
|
| 9 |
+
.tribe-common-form-select{display:flex}.tribe-common-form-select>div{flex:0 0 auto;min-width:193px}.tribe-common-form-select__toggle{background-color:#fff;border-radius:2px;border:2px solid #eaebec}.tribe-common-form-select__toggle button{align-items:center;background-color:#fefffe;border:none;color:#545d66;display:flex;font-family:Helvetica,sans-serif;font-size:16px;font-weight:400;justify-content:center;line-height:1.5;padding:6px 10px;text-align:left;text-decoration:none;width:100%}.tribe-common-form-select__toggle button>span{flex:1}.tribe-common-form-select__options__option{background:transparent;border:0;color:#555d66;cursor:pointer;display:block;line-height:20px;padding:5px 12px;text-align:left;width:100%}.tribe-common-form-select__options__option:hover{background-color:#009fd4;color:#fff}
|
| 10 |
input.tribe-editor__input[type=number],input.tribe-editor__input[type=text]{color:#000;font-size:16px;line-height:24px;border:1px solid #e1e3e6;padding:7px 15px;margin:0;height:40px}input.tribe-editor__input[type=number]:focus,input.tribe-editor__input[type=text]:focus{color:#000;box-shadow:none;outline:none}input.tribe-editor__input[type=number]:disabled,input.tribe-editor__input[type=text]:disabled{color:#aeb4bb}
|
| 11 |
+
.tribe-editor__timepicker{display:inline-block}.tribe-editor__timepicker__toggle{background-color:#fff;border:1px solid #e1e3e6;border-radius:2px;display:flex;align-items:center;justify-content:center}.tribe-editor__timepicker__toggle input.tribe-editor__timepicker__input[type=text]{font-family:Helvetica,sans-serif;font-size:14px;line-height:1.5;padding:6px 0 6px 10px;border:none;width:80px}.tribe-editor__timepicker__toggle button.tribe-editor__timepicker__toggle-btn{padding:10px}.tribe-editor__timepicker__toggle button.tribe-editor__timepicker__toggle-btn:disabled>svg.dashicon{fill:#aeb4bb}.tribe-editor__timepicker__toggle button.tribe-editor__timepicker__all-day-btn{color:#545d66;line-height:20px;padding:6px 10px;text-decoration:none;display:flex;align-items:center;justify-content:center}.tribe-editor__timepicker__content.components-popover .components-popover__content{min-width:110px}.tribe-editor__timepicker__content .tribe-editor__timepicker__items{height:250px;overflow:auto}.tribe-editor__timepicker__content .tribe-editor__timepicker__items .components-placeholder{height:inherit}.tribe-editor__timepicker__content .tribe-editor__timepicker__item{display:block;width:100%;color:#555d66;padding:5px 12px;cursor:pointer;border-bottom:1px solid #e2e4e7;line-height:20px;background:transparent;text-align:left}.tribe-editor__timepicker__content .tribe-editor__timepicker__item:focus,.tribe-editor__timepicker__content .tribe-editor__timepicker__item:hover{background-color:#e7f5fa}.tribe-editor__timepicker__content .tribe-editor__timepicker__item--current,.tribe-editor__timepicker__content .tribe-editor__timepicker__item--current:focus,.tribe-editor__timepicker__content .tribe-editor__timepicker__item--current:hover{color:#fff;background-color:#009fd4}
|
| 12 |
+
.DayPicker{display:inline-block;font-size:1rem}.DayPicker-wrapper{position:relative;flex-direction:row;padding-bottom:1em;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.DayPicker-Months{display:flex;flex-wrap:wrap;justify-content:center}.DayPicker-Month{display:table;margin:0 1em;margin-top:1em;border-spacing:0;border-collapse:collapse;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.DayPicker-NavButton{position:absolute;top:1em;right:1.5em;left:auto;display:inline-block;margin-top:2px;width:1.25em;height:1.25em;background-position:50%;background-size:50%;background-repeat:no-repeat;color:#8b9898;cursor:pointer}.DayPicker-NavButton:hover{opacity:.8}.DayPicker-NavButton--prev{margin-right:1.5em;background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAwCAYAAAB5R9gVAAAABGdBTUEAALGPC/xhBQAAAVVJREFUWAnN2G0KgjAYwPHpGfRkaZeqvgQaK+hY3SUHrk1YzNLay/OiEFp92I+/Mp2F2Mh2lLISWnflFjzH263RQjzMZ19wgs73ez0o1WmtW+dgA01VxrE3p6l2GLsnBy1VYQOtVSEH/atCCgqpQgKKqYIOiq2CBkqtggLKqQIKgqgCBjpJ2Y5CdJ+zrT9A7HHSTA1dxUdHgzCqJIEwq0SDsKsEg6iqBIEoq/wEcVRZBXFV+QJxV5mBtlDFB5VjYTaGZ2sf4R9PM7U9ZU+lLuaetPP/5Die3ToO1+u+MKtHs06qODB2zBnI/jBd4MPQm1VkY79Tb18gB+C62FdBFsZR6yeIo1YQiLJWMIiqVjQIu1YSCLNWFgijVjYIuhYYCKoWKAiiFgoopxYaKLUWOii2FgkophYp6F3r42W5A9s9OcgNvva8xQaysKXlFytoqdYmQH6tF3toSUo0INq9AAAAAElFTkSuQmCC")}.DayPicker-NavButton--next{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAwCAYAAAB5R9gVAAAABGdBTUEAALGPC/xhBQAAAXRJREFUWAnN119ugjAcwPHWzJ1gnmxzB/BBE0n24m4xfNkTaOL7wOtsl3AXMMb+Vjaa1BG00N8fSEibPpAP3xAKKs2yjzTPH9RAjhEo9WzPr/Vm8zgE0+gXATAxxuxtqeJ9t5tIwv5AtQAApsfT6TPdbp+kUBcgVwvO51KqVhMkXKsVJFXrOkigVhCIs1Y4iKlWZxB1rX4gwlpRIIpa8SDkWmggrFq4IIRaJKCYWnSgnrXIQV1r8YD+1Vrn+bReagysIFfLABRt31v8oBu1xEBttfRbltmfjgEcWh9snUS2kNdBK6WN1vrOWxObWsz+fjxevsxmB1GQDfINWiev83nhaoiB/CoOU438oPrhXS0WpQ9xc1ZQWxWHqUYe0I0qrKCQKjygDlXIQV2r0IF6ViEBxVTBBSFUQQNhVYkHIVeJAtkNsbQ7c1LtzP6FsObhb2rCKv7NBIGoq4SDmKoEgTirXAcJVGkFSVVpgoSrXICGUMUH/QBZNSUy5XWUhwAAAABJRU5ErkJggg==")}.DayPicker-NavButton--interactionDisabled{display:none}.DayPicker-Caption{display:table-caption;margin-bottom:.5em;padding:0 .5em;text-align:left}.DayPicker-Caption>div{font-weight:500;font-size:1.15em}.DayPicker-Weekdays{display:table-header-group;margin-top:1em}.DayPicker-WeekdaysRow{display:table-row}.DayPicker-Weekday{display:table-cell;padding:.5em;color:#8b9898;text-align:center;font-size:.875em}.DayPicker-Weekday abbr[title]{border-bottom:none;text-decoration:none}.DayPicker-Body{display:table-row-group}.DayPicker-Week{display:table-row}.DayPicker-Day{border-radius:50%;text-align:center}.DayPicker-Day,.DayPicker-WeekNumber{display:table-cell;padding:.5em;vertical-align:middle;cursor:pointer}.DayPicker-WeekNumber{min-width:1em;border-right:1px solid #eaecec;color:#8b9898;text-align:right;font-size:.75em}.DayPicker--interactionDisabled .DayPicker-Day{cursor:default}.DayPicker-Footer{padding-top:.5em}.DayPicker-TodayButton{border:none;background-color:transparent;background-image:none;box-shadow:none;color:#4a90e2;font-size:.875em;cursor:pointer}.DayPicker-Day--today{color:#d0021b;font-weight:700}.DayPicker-Day--outside{color:#8b9898;cursor:default}.DayPicker-Day--disabled{color:#dce0e0;cursor:default}.DayPicker-Day--sunday{background-color:#f7f8f8}.DayPicker-Day--sunday:not(.DayPicker-Day--today){color:#dce0e0}.DayPicker-Day--selected:not(.DayPicker-Day--disabled):not(.DayPicker-Day--outside){position:relative;background-color:#4a90e2;color:#f0f8ff}.DayPicker-Day--selected:not(.DayPicker-Day--disabled):not(.DayPicker-Day--outside):hover{background-color:#51a0fa}.DayPicker:not(.DayPicker--interactionDisabled) .DayPicker-Day:not(.DayPicker-Day--disabled):not(.DayPicker-Day--selected):not(.DayPicker-Day--outside):hover{background-color:#f0f8ff}.DayPickerInput{display:inline-block}.DayPickerInput-OverlayWrapper{position:relative}.DayPickerInput-Overlay{position:absolute;left:0;z-index:1;background:#fff;box-shadow:0 2px 5px rgba(0,0,0,.15)}
|
| 13 |
.tribe-editor__day-picker-input.DayPickerInput>input{border:1px solid #e1e3e6;color:#545d66;font-size:16px;line-height:24px;padding:7px 15px;width:100%;height:40px}.tribe-editor__day-picker-input.DayPickerInput>input:disabled{color:#aeb4bb}.tribe-editor__day-picker-input .DayPickerInput-Overlay{padding:20px;z-index:10}.tribe-editor__day-picker-input .DayPicker{width:100%}.tribe-editor__day-picker-input .DayPicker-Month{margin:0}.tribe-editor__day-picker-input .DayPicker-Caption>div,.tribe-editor__day-picker-input .DayPicker-Day,.tribe-editor__day-picker-input .DayPicker-Weekday{color:#545d66;font-family:Helvetica,"sans-serif";font-weight:400}.tribe-editor__day-picker-input .DayPicker-Caption>div{font-size:16px;margin-bottom:12px;text-align:center}.tribe-editor__day-picker-input .DayPicker-Weekday{font-size:12px}.tribe-editor__day-picker-input .DayPicker-Day{font-size:14px}.tribe-editor__day-picker-input .DayPicker-Day:hover{color:#007bb4;background-color:#fff}.tribe-editor__day-picker-input .DayPicker-Day--today{color:#545d66}.tribe-editor__day-picker-input .DayPicker-Day--disabled{pointer-events:none;color:#ccc}.tribe-editor__day-picker-input .DayPicker-Day--selected:not(.DayPicker-Day--outside){border-radius:0;background-color:#009fd4;color:#fff}.tribe-editor__day-picker-input .DayPicker-Day--selected:not(.DayPicker-Day--outside):hover{background-color:#007bb4;color:#fff}.tribe-editor__day-picker-input .DayPicker-NavButton--prev{left:0;top:0}.tribe-editor__day-picker-input .DayPicker-NavButton--next{right:0;top:0}.tribe-editor__day-picker-input .DayPicker:not(.DayPicker--interactionDisabled) .DayPicker-Day:not(.DayPicker-Day--disabled):not(.DayPicker-Day--selected):not(.DayPicker-Day--outside):hover{background-color:#fff}.tribe-editor__day-picker-input .DayPicker-Day--selected:not(.DayPicker-Day--start):not(.DayPicker-Day--end):not(.DayPicker-Day--outside){background-color:#e7f5fa;color:#545d66}.tribe-editor__day-picker-input .DayPicker-Day--selected:not(.DayPicker-Day--start):not(.DayPicker-Day--end):not(.DayPicker-Day--outside):hover{color:#007bb4}
|
| 14 |
.tribe-editor__creatable-select .tribe-editor__creatable-select__control{height:40px;border:1px solid #e1e3e6;border-radius:3px;background-color:#fff}.tribe-editor__creatable-select .tribe-editor__creatable-select__control:hover{border:1px solid #e1e3e6}.tribe-editor__creatable-select .tribe-editor__creatable-select__control--is-focused{box-shadow:none}.tribe-editor__creatable-select .tribe-editor__creatable-select__value-container{padding:2px 5px 2px 15px}.tribe-editor__creatable-select .tribe-editor__creatable-select__single-value{margin:0;max-width:calc(100% - 15px);font-size:16px;line-height:1.5}.tribe-editor__creatable-select .tribe-editor__creatable-select__input{font-size:16px}.tribe-editor__creatable-select .tribe-editor__creatable-select__input>input{margin:0;line-height:1.5}.tribe-editor__creatable-select .tribe-editor__creatable-select__input>input,.tribe-editor__creatable-select .tribe-editor__creatable-select__input>input:focus{box-shadow:none}.tribe-editor__creatable-select svg.tribe-editor__creatable-select__dropdown-indicator{fill:#555d66}.tribe-editor__creatable-select .tribe-editor__creatable-select__menu{margin:0;border:1px solid #e1e3e6;border-top:none;border-radius:0;border-bottom-left-radius:3px;border-bottom-right-radius:3px;box-shadow:none;-webkit-transform:translateY(-7px);transform:translateY(-7px)}.tribe-editor__creatable-select .tribe-editor__creatable-select__menu-list{padding:0}.tribe-editor__creatable-select .tribe-editor__creatable-select__option{font-size:16px;line-height:1.5;padding:3px 15px}.tribe-editor__creatable-select .tribe-editor__creatable-select__option--is-focused{background-color:#e7f5fa}.tribe-editor__creatable-select .tribe-editor__creatable-select__option--is-selected{background-color:#11a0d2}
|
| 15 |
.tribe-editor__placeholder{border:2px dashed #e1e3e6;padding:12px 15px 14px;text-align:center;font-family:Helvetica,Arial,"sans-serif";font-size:1rem;line-height:1.5;font-weight:700;color:#8d949b;min-width:260px;display:inline-block}
|
common/src/resources/css/bumpdown.css
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* This CSS file was auto-generated via PostCSS
|
| 3 |
+
*
|
| 4 |
+
* Contributors should avoid editing this file, but instead edit the associated
|
| 5 |
+
* src/resources/postcss/ file. For more information, check out our engineering
|
| 6 |
+
* docs on how we handle CSS in our engineering docs.
|
| 7 |
+
*
|
| 8 |
+
* @see: http://moderntribe.github.io/products-engineering/css/
|
| 9 |
+
*/
|
| 10 |
+
|
| 11 |
+
/* = Bumpdown CSS
|
| 12 |
+
=============================================*/
|
| 13 |
+
.wrap .tribe-bumpdown,
|
| 14 |
+
.tribe-bumpdown,
|
| 15 |
+
.tribe-bumpdown-cell.tribe-bumpdown {
|
| 16 |
+
display: none;
|
| 17 |
+
margin: 1rem 0;
|
| 18 |
+
}
|
| 19 |
+
.wrap .tribe-bumpdown .tribe-bumpdown-content, .tribe-bumpdown .tribe-bumpdown-content, .tribe-bumpdown-cell.tribe-bumpdown .tribe-bumpdown-content {
|
| 20 |
+
background: #f1f1f1;
|
| 21 |
+
padding: 10px 35px 10px 10px;
|
| 22 |
+
font-size: 12px;
|
| 23 |
+
position: relative;
|
| 24 |
+
}
|
| 25 |
+
.tribe-bumpdown-cell.tribe-bumpdown {
|
| 26 |
+
padding: 0;
|
| 27 |
+
}
|
| 28 |
+
#poststuff .tribe-bumpdown h1,
|
| 29 |
+
#poststuff .tribe-bumpdown h2,
|
| 30 |
+
#poststuff .tribe-bumpdown h3,
|
| 31 |
+
#poststuff .tribe-bumpdown h4,
|
| 32 |
+
.tribe-bumpdown h1,
|
| 33 |
+
.tribe-bumpdown h2,
|
| 34 |
+
.tribe-bumpdown h3,
|
| 35 |
+
.tribe-bumpdown h4 {
|
| 36 |
+
padding-left: 0;
|
| 37 |
+
padding-top: 0;
|
| 38 |
+
}
|
| 39 |
+
.tribe-bumpdown-arrow {
|
| 40 |
+
position: absolute;
|
| 41 |
+
width: 0;
|
| 42 |
+
height: 0;
|
| 43 |
+
top: -11px;
|
| 44 |
+
margin-left: -18px;
|
| 45 |
+
border-left: 8px solid transparent;
|
| 46 |
+
border-right: 8px solid transparent;
|
| 47 |
+
|
| 48 |
+
border-bottom: 11px solid #f1f1f1;
|
| 49 |
+
}
|
| 50 |
+
.tribe-bumpdown-close {
|
| 51 |
+
color: #686868;
|
| 52 |
+
cursor: pointer;
|
| 53 |
+
position: absolute;
|
| 54 |
+
right: .5rem;
|
| 55 |
+
top: .5rem;
|
| 56 |
+
z-index: 2;
|
| 57 |
+
}
|
| 58 |
+
.tribe-bumpdown-trigger .target {
|
| 59 |
+
color: #0074a2;
|
| 60 |
+
}
|
| 61 |
+
@media screen and (max-width: 782px) {
|
| 62 |
+
.wrap td.tribe-bumpdown {
|
| 63 |
+
padding-right: 35px;
|
| 64 |
+
}
|
| 65 |
+
|
| 66 |
+
.tribe-bumpdown-arrow {
|
| 67 |
+
margin-left: -15px;
|
| 68 |
+
}
|
| 69 |
+
}
|
common/src/resources/css/buttonset.css
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* This CSS file was auto-generated via PostCSS
|
| 3 |
+
*
|
| 4 |
+
* Contributors should avoid editing this file, but instead edit the associated
|
| 5 |
+
* src/resources/postcss/ file. For more information, check out our engineering
|
| 6 |
+
* docs on how we handle CSS in our engineering docs.
|
| 7 |
+
*
|
| 8 |
+
* @see: http://moderntribe.github.io/products-engineering/css/
|
| 9 |
+
*/
|
| 10 |
+
|
| 11 |
+
.tribe-buttonset .tribe-button-field {
|
| 12 |
+
background-color: #f7f7f7;
|
| 13 |
+
}
|
| 14 |
+
|
| 15 |
+
.tribe-button-field {
|
| 16 |
+
color: #444;
|
| 17 |
+
cursor: pointer;
|
| 18 |
+
display: inline-block;
|
| 19 |
+
text-decoration: none;
|
| 20 |
+
font-size: 13px;
|
| 21 |
+
line-height: 26px;
|
| 22 |
+
height: 28px;
|
| 23 |
+
margin: 0 0 3px;
|
| 24 |
+
padding: 0 10px 1px;
|
| 25 |
+
background-color: #fff;
|
| 26 |
+
border-width: 1px;
|
| 27 |
+
border-style: solid;
|
| 28 |
+
border-color: #ddd;
|
| 29 |
+
-webkit-appearance: none;
|
| 30 |
+
border-radius: 3px;
|
| 31 |
+
white-space: nowrap;
|
| 32 |
+
box-sizing: border-box;
|
| 33 |
+
}
|
| 34 |
+
|
| 35 |
+
.tribe-button-field.tribe-active {
|
| 36 |
+
color: #fff;
|
| 37 |
+
background-color: #585858;
|
| 38 |
+
border-color: #585858;
|
| 39 |
+
}
|
common/src/resources/css/common-full.min.css
DELETED
|
@@ -1 +0,0 @@
|
|
| 1 |
-
.tribe-common figure{line-height:0}.tribe-common figcaption{line-height:normal}.tribe-common a{background-color:transparent;-webkit-text-decoration-skip:objects}.tribe-common abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}.tribe-common code,.tribe-common kbd,.tribe-common pre,.tribe-common samp{font-family:monospace;font-size:1em}.tribe-common b,.tribe-common strong{font-weight:inherit;font-weight:bolder}.tribe-common dfn{font-style:italic}.tribe-common mark{background-color:#ff0;color:#000}.tribe-common small{font-size:80%}.tribe-common sub,.tribe-common sup{font-size:75%;line-height:0}.tribe-common hr{border:0;height:0}.tribe-common button,.tribe-common input[type=button],.tribe-common input[type=email],.tribe-common input[type=password],.tribe-common input[type=reset],.tribe-common input[type=search],.tribe-common input[type=submit],.tribe-common input[type=text],.tribe-common input[type=url],.tribe-common textarea{-webkit-appearance:none;-moz-appearance:none;appearance:none}.tribe-common button,.tribe-common input,.tribe-common optgroup,.tribe-common select,.tribe-common textarea{color:inherit;font:inherit;line-height:normal;-webkit-font-smoothing:antialiased}.tribe-common button,.tribe-common input,.tribe-common select,.tribe-common textarea{outline:0;border-radius:0}.tribe-common select:-moz-focusring{color:transparent;text-shadow:0 0 0 #000}.tribe-common optgroup{font-weight:700}.tribe-common h1,.tribe-common h2,.tribe-common h3,.tribe-common h4,.tribe-common h5,.tribe-common h6,.tribe-common p{font-weight:400;text-rendering:optimizeLegibility}#top .main_color .tribe-common button[disabled],#top.tribe-theme-enfold .tribe-common button[disabled]{opacity:1}.tribe-theme-twentynineteen .tribe-common h1:before,.tribe-theme-twentynineteen .tribe-common h2:before{content:none}.tribe-theme-twentynineteen .tribe-common button,.tribe-theme-twentynineteen .tribe-common input[type=button],.tribe-theme-twentynineteen .tribe-common input[type=reset],.tribe-theme-twentynineteen .tribe-common input[type=submit]{outline:none}.tribe-theme-twentynineteen .tribe-common td,.tribe-theme-twentynineteen .tribe-common th{word-break:normal}.tribe-theme-twentyseventeen .tribe-common h5{letter-spacing:normal;text-transform:none}.tribe-theme-twentyseventeen .tribe-common input[type=text]{border-radius:0}.tribe-theme-twentytwenty .tribe-common{background-color:#fff;letter-spacing:normal}.tribe-theme-twentytwenty .tribe-common input,.tribe-theme-twentytwenty .tribe-common textarea{letter-spacing:normal}.tribe-theme-twentytwenty .tribe-common *{word-break:normal}.tribe-common .tribe-common-form-control-checkbox,.tribe-common .tribe-common-form-control-radio{line-height:0}.tribe-common .tribe-common-form-control-checkbox__label,.tribe-common .tribe-common-form-control-radio__label{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-size:14px;line-height:1.62;font-weight:400;color:#5d5d5d}.tribe-common .tribe-common-form-control-checkbox__input,.tribe-common .tribe-common-form-control-radio__input{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#fff;border:1px solid #141827;height:20px;position:relative;width:20px}.tribe-common .tribe-common-form-control-checkbox__input:active,.tribe-common .tribe-common-form-control-checkbox__input:focus,.tribe-common .tribe-common-form-control-checkbox__input:hover,.tribe-common .tribe-common-form-control-radio__input:active,.tribe-common .tribe-common-form-control-radio__input:focus,.tribe-common .tribe-common-form-control-radio__input:hover{border:1px solid #141827}.tribe-common .tribe-common-form-control-checkbox__input:checked,.tribe-common .tribe-common-form-control-radio__input:checked{background-color:#141827}.tribe-common .tribe-common-form-control-checkbox__input:checked:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='12' height='9' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M10.6.1L3.9 6.8 1.4 4.3c-.1-.1-.3-.1-.4 0l-.8.8c-.1.1-.1.3 0 .4l3.4 3.4c.2.1.4.1.5 0l7.7-7.7c.1-.1.1-.3 0-.4L11 .1c-.1-.1-.3-.1-.4 0z' fill='%23FFF'/%3E%3C/svg%3E");background-repeat:no-repeat;background-size:contain;content:"";display:block;height:9px;left:50%;position:absolute;top:50%;transform:translate(-50%,-50%);width:12px}.tribe-common .tribe-common-form-control-radio__input{border-radius:50%}.tribe-common .tribe-common-form-control-radio__input:checked:before{background-color:#fff;border-radius:50%;content:"";display:block;height:8px;left:50%;position:absolute;top:50%;transform:translate(-50%,-50%);width:8px}#top .main_color .tribe-common .tribe-common-form-control-checkbox__label,#top .main_color .tribe-common .tribe-common-form-control-radio__label,#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-checkbox__label,#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-radio__label{font-weight:400;font-size:14px}.tribe-common .tribe-common-form-control-slider{line-height:0}.tribe-common .tribe-common-form-control-slider__input{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:transparent;border:0}.tribe-common .tribe-common-form-control-slider__input::-webkit-slider-runnable-track{border:none;border-radius:5px;height:10px;margin:5px 0;padding:0;position:relative;transition:background-color .2s ease;background-color:#334aff}.tribe-common .tribe-common-form-control-slider__input::-moz-range-track{border:none;border-radius:5px;height:10px;margin:5px 0;padding:0;position:relative;transition:background-color .2s ease;background-color:#334aff}.tribe-common .tribe-common-form-control-slider__input::-ms-track{background-color:transparent;border-color:transparent;border-width:5px 0;color:transparent;height:10px}.tribe-common .tribe-common-form-control-slider__input::-ms-fill-lower,.tribe-common .tribe-common-form-control-slider__input::-ms-fill-upper{background-color:#334aff;border-radius:10px}.tribe-common .tribe-common-form-control-slider__input::-webkit-slider-thumb{background-color:#fff;border:1px solid #d5d5d5;border-radius:50%;box-shadow:0 2px 5px 0 rgba(0,0,0,.14);height:20px;width:20px;margin-top:-5px;-webkit-appearance:none;appearance:none}.tribe-common .tribe-common-form-control-slider__input::-moz-range-thumb{background-color:#fff;border:1px solid #d5d5d5;border-radius:50%;box-shadow:0 2px 5px 0 rgba(0,0,0,.14);height:20px;width:20px;margin-top:-5px}.tribe-common .tribe-common-form-control-slider__input::-ms-thumb{background-color:#fff;border:1px solid #d5d5d5;border-radius:50%;box-shadow:0 2px 5px 0 rgba(0,0,0,.14);height:20px;width:20px;margin-top:-5px;box-shadow:none;margin-top:-1px}.tribe-common .tribe-common-form-control-slider__label{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-size:12px;line-height:1.38;font-weight:400;color:#5d5d5d}#top .main_color .tribe-common .tribe-common-form-control-slider__label,#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-slider__label{font-weight:400;font-size:12px}.tribe-common .tribe-common-form-control-text__input{font-size:16px;border:0;border-bottom:1px solid #d5d5d5}.tribe-common--breakpoint-medium.tribe-common .tribe-common-form-control-text__input,.tribe-common .tribe-common-form-control-text__input{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;line-height:1.62;font-weight:400}.tribe-common--breakpoint-medium.tribe-common .tribe-common-form-control-text__input{font-size:14px;border:0}.tribe-common .tribe-common-form-control-text__input::-webkit-input-placeholder{color:#5d5d5d;font-style:normal;opacity:1}.tribe-common .tribe-common-form-control-text__input::-moz-placeholder{color:#5d5d5d;font-style:normal;opacity:1}.tribe-common .tribe-common-form-control-text__input:-ms-input-placeholder,.tribe-common .tribe-common-form-control-text__input::-ms-input-placeholder{color:#5d5d5d;font-style:normal;opacity:1}.tribe-common .tribe-common-form-control-text__input::placeholder{color:#5d5d5d;font-style:normal;opacity:1}.tribe-common .tribe-common-form-control-text__input:focus{border-bottom-color:#141827;outline:0}.tribe-theme-twentyseventeen .tribe-common .tribe-common-form-control-text__input{color:#141827}.tribe-theme-twentytwenty .tribe-common .tribe-common-form-control-text__input{line-height:inherit}#top .main_color .tribe-common .tribe-common-form-control-text__input,#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-text__input{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-size:16px;line-height:1.62;font-weight:400;background:#fff;border:0;border-bottom:1px solid #d5d5d5}#top .main_color .tribe-common .tribe-common-form-control-text__input:focus,#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-text__input:focus{border-bottom-color:#141827;box-shadow:none}#top .main_color .tribe-common.tribe-common--breakpoint-medium .tribe-common-form-control-text__input,#top.tribe-theme-enfold .tribe-common.tribe-common--breakpoint-medium .tribe-common-form-control-text__input{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-size:14px;line-height:1.62;font-weight:400;border:0}.tribe-common .tribe-common-form-control-toggle{line-height:0}.tribe-common .tribe-common-form-control-toggle__input{border:none;border-radius:5px;height:10px;margin:5px 0;padding:0;position:relative;transition:background-color .2s ease;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#d5d5d5;width:40px}.tribe-common .tribe-common-form-control-toggle__input:after{background-color:#fff;border:1px solid #d5d5d5;border-radius:50%;box-shadow:0 2px 5px 0 rgba(0,0,0,.14);height:20px;width:20px;content:"";left:0;position:absolute;top:-5px;transition:transform .2s ease}.tribe-common .tribe-common-form-control-toggle__input:checked{background-color:#334aff}.tribe-common .tribe-common-form-control-toggle__input:checked:after{transform:translateX(20px)}.tribe-common .tribe-common-form-control-toggle__label{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-size:12px;line-height:1.38;font-weight:400;color:#5d5d5d}#top .main_color .tribe-common .tribe-common-form-control-toggle__label,#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-toggle__label{font-weight:400;font-size:12px}.tribe-common a,.tribe-common a:active,.tribe-common a:focus,.tribe-common a:hover,.tribe-common a:visited{color:#141827;outline:0;text-decoration:none}.tribe-theme-twentyseventeen .tribe-common a{box-shadow:none}.tribe-theme-twentyseventeen .tribe-common a:focus,.tribe-theme-twentyseventeen .tribe-common a:hover{box-shadow:none;color:#141827}.tribe-theme-twentynineteen .entry .tribe-common a,.tribe-theme-twentynineteen .tribe-common a{text-decoration:none}.tribe-common .tribe-common-anchor{border-bottom:2px solid transparent;transition:border-color .2s ease}.tribe-common .tribe-common-anchor:active,.tribe-common .tribe-common-anchor:focus,.tribe-common .tribe-common-anchor:hover{border-bottom:2px solid #141827}.tribe-common .tribe-common-anchor-alt{border-bottom:2px solid #334aff;color:#141827;transition:color .2s ease}.tribe-common .tribe-common-anchor-alt:active,.tribe-common .tribe-common-anchor-alt:focus,.tribe-common .tribe-common-anchor-alt:hover{border-bottom:2px solid #334aff;color:#334aff}.tribe-common .tribe-common-anchor-thin{border-bottom:1px solid transparent;transition:border-color .2s ease}.tribe-common .tribe-common-anchor-thin:active,.tribe-common .tribe-common-anchor-thin:focus,.tribe-common .tribe-common-anchor-thin:hover{border-bottom:1px solid #141827}.tribe-common .tribe-common-anchor-thin-alt{border-bottom:1px solid #334aff;color:#141827;transition:color .2s ease}.tribe-common .tribe-common-anchor-thin-alt:active,.tribe-common .tribe-common-anchor-thin-alt:focus,.tribe-common .tribe-common-anchor-thin-alt:hover{border-bottom:1px solid #334aff;color:#334aff}.tribe-theme-twentyseventeen .tribe-common .tribe-common-anchor-alt:focus,.tribe-theme-twentyseventeen .tribe-common .tribe-common-anchor-alt:hover,.tribe-theme-twentyseventeen .tribe-common .tribe-common-anchor-thin-alt:focus,.tribe-theme-twentyseventeen .tribe-common .tribe-common-anchor-thin-alt:hover{color:#334aff}.tribe-common .tribe-common-b1{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-size:14px;font-weight:400;line-height:1.62}.tribe-common--breakpoint-medium.tribe-common .tribe-common-b1{font-size:16px;line-height:1.62}.tribe-common .tribe-common-b1--bold{font-weight:700}.tribe-common .tribe-common-b2{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-size:12px;font-weight:400;line-height:1.38}.tribe-common--breakpoint-medium.tribe-common .tribe-common-b2{font-size:14px;line-height:1.62}.tribe-common .tribe-common-b2--bold{font-weight:700}.tribe-common .tribe-common-b3{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-size:11px;font-weight:400;line-height:1.5}.tribe-common--breakpoint-medium.tribe-common .tribe-common-b3{font-size:12px;line-height:1.38}.tribe-common .tribe-common-b3--bold{font-weight:700}.tribe-common--breakpoint-medium.tribe-common .tribe-common-b1--min-medium{font-size:16px;line-height:1.62}.tribe-common--breakpoint-medium.tribe-common .tribe-common-b2--min-medium{font-size:14px;line-height:1.62}.tribe-common--breakpoint-medium.tribe-common .tribe-common-b3--min-medium{font-size:12px;line-height:1.38}.tribe-common .tribe-common-cta{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-size:12px;line-height:1.38;font-weight:400;font-weight:700;border-bottom:2px solid transparent;transition:border-color .2s ease}.tribe-common .tribe-common-cta:active,.tribe-common .tribe-common-cta:focus,.tribe-common .tribe-common-cta:hover{border-bottom:2px solid #141827}.tribe-common .tribe-common-cta--alt{border-bottom:2px solid #334aff;color:#141827;transition:color .2s ease}.tribe-common .tribe-common-cta--alt:active,.tribe-common .tribe-common-cta--alt:focus,.tribe-common .tribe-common-cta--alt:hover{border-bottom:2px solid #334aff;color:#334aff}.tribe-common .tribe-common-cta--thin{border-bottom:1px solid transparent;transition:border-color .2s ease}.tribe-common .tribe-common-cta--thin:active,.tribe-common .tribe-common-cta--thin:focus,.tribe-common .tribe-common-cta--thin:hover{border-bottom:1px solid #141827}.tribe-common .tribe-common-cta--thin-alt{border-bottom:1px solid #334aff;color:#141827;transition:color .2s ease}.tribe-common .tribe-common-cta--thin-alt:active,.tribe-common .tribe-common-cta--thin-alt:focus,.tribe-common .tribe-common-cta--thin-alt:hover{border-bottom:1px solid #334aff;color:#334aff}.tribe-theme-twentyseventeen .tribe-common .tribe-common-cta--alt:focus,.tribe-theme-twentyseventeen .tribe-common .tribe-common-cta--alt:hover,.tribe-theme-twentyseventeen .tribe-common .tribe-common-cta--thin-alt:focus,.tribe-theme-twentyseventeen .tribe-common .tribe-common-cta--thin-alt:hover{color:#334aff}.tribe-common .tribe-common-h1{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-weight:700;font-size:28px;line-height:1.42}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h1{font-size:42px;line-height:1.38}.tribe-common .tribe-common-h2{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-weight:700;font-size:24px;line-height:1.42}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h2{font-size:32px;line-height:1.38}.tribe-common .tribe-common-h3{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-weight:700;font-size:22px;line-height:1.5}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h3{font-size:28px;line-height:1.42}.tribe-common .tribe-common-h4{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-weight:700;font-size:20px;line-height:1.42}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h4{font-size:24px;line-height:1.42}.tribe-common .tribe-common-h5{font-size:18px}.tribe-common .tribe-common-h5,.tribe-common .tribe-common-h6{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-weight:700;line-height:1.5}.tribe-common .tribe-common-h6{font-size:16px}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h6{font-size:16px;line-height:1.62}.tribe-common .tribe-common-h7{font-size:14px;line-height:1.62}.tribe-common .tribe-common-h7,.tribe-common .tribe-common-h8{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-weight:700}.tribe-common .tribe-common-h8{font-size:12px;line-height:1.38}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h3--min-medium{font-size:28px;line-height:1.42}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h4--min-medium{font-size:24px;line-height:1.42}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h5--min-medium{font-size:18px;line-height:1.5}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h6--min-medium{font-size:16px;line-height:1.62}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h7--min-medium{font-size:14px;line-height:1.62}.tribe-common .tribe-common-h--alt{font-weight:400}.tribe-theme-avada #main .tribe-common .tribe-common-h1{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-weight:700;font-size:28px;line-height:1.42}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h1{font-size:42px;line-height:1.38}.tribe-theme-avada #main .tribe-common .tribe-common-h2{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-weight:700;font-size:24px;line-height:1.42}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h2{font-size:32px;line-height:1.38}.tribe-theme-avada #main .tribe-common .tribe-common-h3{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-weight:700;font-size:22px;line-height:1.5}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h3{font-size:28px;line-height:1.42}.tribe-theme-avada #main .tribe-common .tribe-common-h4{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-weight:700;font-size:20px;line-height:1.42}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h4{font-size:24px;line-height:1.42}.tribe-theme-avada #main .tribe-common .tribe-common-h5{font-size:18px}.tribe-theme-avada #main .tribe-common .tribe-common-h5,.tribe-theme-avada #main .tribe-common .tribe-common-h6{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-weight:700;line-height:1.5}.tribe-theme-avada #main .tribe-common .tribe-common-h6{font-size:16px}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h6{font-size:16px;line-height:1.62}.tribe-theme-avada #main .tribe-common .tribe-common-h7{font-size:14px;line-height:1.62}.tribe-theme-avada #main .tribe-common .tribe-common-h7,.tribe-theme-avada #main .tribe-common .tribe-common-h8{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-weight:700}.tribe-theme-avada #main .tribe-common .tribe-common-h8{font-size:12px;line-height:1.38}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h3--min-medium{font-size:28px;line-height:1.42}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h4--min-medium{font-size:24px;line-height:1.42}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h5--min-medium{font-size:18px;line-height:1.5}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h6--min-medium{font-size:16px;line-height:1.62}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h7--min-medium{font-size:14px;line-height:1.62}.tribe-theme-avada #main .tribe-common .tribe-common-h--alt{font-weight:400}.tribe-common button{border:none}.tribe-common button,.tribe-common button:focus,.tribe-common button:hover,.tribe-theme-twentyseventeen .tribe-common button:focus,.tribe-theme-twentyseventeen .tribe-common button:hover{background-color:transparent}.tribe-theme-twentytwenty .tribe-common button{background-color:transparent;text-transform:inherit}.tribe-theme-twentytwenty .tribe-common button:focus,.tribe-theme-twentytwenty .tribe-common button:hover{text-decoration:none}.tribe-common .tribe-common-svgicon--featured{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='16' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 0h16v20l-7.902-5.122L0 20z' fill='%23334AFF'/%3E%3C/svg%3E")}.tribe-theme-enfold .tribe-common th{letter-spacing:0;text-transform:none}.tribe-common .tribe-common-c-btn-border,.tribe-common a.tribe-common-c-btn-border{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-size:12px;line-height:1.38;font-weight:400;border:0;cursor:pointer;display:inline-block;height:auto;padding:0;text-decoration:none;width:auto;background-color:#fff;border:1px solid #d5d5d5;border-radius:4px;text-align:center;transition:color .2s ease,border-color .2s ease;color:#5d5d5d;padding:14px 20px}.tribe-common .tribe-common-c-btn-border:focus,.tribe-common .tribe-common-c-btn-border:hover,.tribe-common a.tribe-common-c-btn-border:focus,.tribe-common a.tribe-common-c-btn-border:hover{background-color:#fff}.tribe-common .tribe-common-c-btn-border:active,.tribe-common a.tribe-common-c-btn-border:active{border-color:#141827}.tribe-common--breakpoint-medium.tribe-common .tribe-common-c-btn-border,.tribe-common--breakpoint-medium.tribe-common a.tribe-common-c-btn-border{padding:6px 15px}.tribe-common .tribe-common-c-btn-border:active,.tribe-common .tribe-common-c-btn-border:focus,.tribe-common .tribe-common-c-btn-border:hover,.tribe-common a.tribe-common-c-btn-border:active,.tribe-common a.tribe-common-c-btn-border:focus,.tribe-common a.tribe-common-c-btn-border:hover{color:#141827}.tribe-common .tribe-common-c-btn-border:disabled,.tribe-common a.tribe-common-c-btn-border:disabled{color:#d5d5d5}.tribe-theme-twentyseventeen .tribe-common .tribe-common-c-btn-border:hover{background-color:#fff}.tribe-common .tribe-common-c-btn-icon{border:0;cursor:pointer;display:inline-block;height:auto;padding:0;text-decoration:none;width:auto}.tribe-common .tribe-common-c-btn-icon--border{background-color:#fff;border:1px solid #d5d5d5;align-items:center;display:inline-flex;height:56px;justify-content:center;transition:none;width:56px}.tribe-common .tribe-common-c-btn-icon--border:focus,.tribe-common .tribe-common-c-btn-icon--border:hover{background-color:#fff}.tribe-common .tribe-common-c-btn-icon--border:active{border-color:#141827}.tribe-theme-twentyseventeen .tribe-common .tribe-common-c-btn-icon--border:hover{background-color:#fff}.tribe-common .tribe-common-c-btn,.tribe-common a.tribe-common-c-btn{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-size:14px;line-height:1.62;font-weight:400;font-weight:700;border:0;cursor:pointer;display:inline-block;height:auto;padding:0;text-decoration:none;width:auto;border-radius:4px;color:#fff;text-align:center;transition:background-color .2s ease;background-color:#334aff;padding:11px 20px;width:100%}.tribe-common--breakpoint-medium.tribe-common .tribe-common-c-btn,.tribe-common--breakpoint-medium.tribe-common a.tribe-common-c-btn{width:auto}.tribe-common .tribe-common-c-btn:focus,.tribe-common .tribe-common-c-btn:hover,.tribe-common a.tribe-common-c-btn:focus,.tribe-common a.tribe-common-c-btn:hover{background-color:rgba(51,74,255,.8)}.tribe-common .tribe-common-c-btn:active,.tribe-common a.tribe-common-c-btn:active{background-color:rgba(51,74,255,.9)}.tribe-common .tribe-common-c-btn:disabled,.tribe-common a.tribe-common-c-btn:disabled{background-color:rgba(51,74,255,.07)}.tribe-theme-twentyseventeen .tribe-common .tribe-common-c-btn:focus,.tribe-theme-twentyseventeen .tribe-common .tribe-common-c-btn:hover{background-color:rgba(51,74,255,.8);color:#fff}.tribe-theme-twentytwenty .tribe-common .tribe-common-c-btn{background-color:#334aff}.tribe-theme-twentytwenty .tribe-common .tribe-common-c-btn:focus,.tribe-theme-twentytwenty .tribe-common .tribe-common-c-btn:hover{background-color:rgba(51,74,255,.8);color:#fff}.tribe-common .tribe-common-c-loader__dot{animation-name:a;animation-duration:2.24s;animation-iteration-count:infinite;animation-direction:normal}.tribe-common .tribe-common-c-loader__dot--first{animation-delay:.45s}.tribe-common .tribe-common-c-loader__dot--second{animation-delay:1.05s}.tribe-common .tribe-common-c-loader__dot--third{animation-delay:1.35s}@keyframes a{50%{background-color:#334aff}}
|
|
|
common/src/resources/css/common-skeleton.min.css
DELETED
|
@@ -1 +0,0 @@
|
|
| 1 |
-
.tribe-common{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-smoothing:antialiased}.tribe-common *{box-sizing:border-box}.tribe-common article,.tribe-common aside,.tribe-common details,.tribe-common figcaption,.tribe-common figure,.tribe-common footer,.tribe-common header,.tribe-common main,.tribe-common menu,.tribe-common nav,.tribe-common section,.tribe-common summary{display:block}.tribe-common svg:not(:root){overflow:hidden}.tribe-common audio,.tribe-common canvas,.tribe-common progress,.tribe-common video{display:inline-block}.tribe-common audio:not([controls]){display:none;height:0}.tribe-common progress{vertical-align:baseline}.tribe-common [hidden],.tribe-common template{display:none}.tribe-common pre{overflow:auto}.tribe-common sub,.tribe-common sup{position:relative;vertical-align:baseline}.tribe-common sup{top:-.5em}.tribe-common sub{bottom:-.25em}.tribe-common button,.tribe-common input,.tribe-common select,.tribe-common textarea{box-sizing:border-box;margin:0}.tribe-common input[type=number]::-webkit-inner-spin-button,.tribe-common input[type=number]::-webkit-outer-spin-button{height:auto}.tribe-common legend{color:inherit;display:table;max-width:100%;white-space:normal}.tribe-common textarea{resize:none;overflow:auto}.tribe-common button,.tribe-common input[type=button],.tribe-common input[type=reset],.tribe-common input[type=submit]{cursor:pointer;overflow:visible}.tribe-common button[disabled],.tribe-common input[disabled]{cursor:default}.tribe-common button::-moz-focus-inner,.tribe-common input::-moz-focus-inner{border:0;padding:0}.tribe-common a,.tribe-common abbr,.tribe-common acronym,.tribe-common address,.tribe-common applet,.tribe-common article,.tribe-common aside,.tribe-common audio,.tribe-common b,.tribe-common big,.tribe-common blockquote,.tribe-common canvas,.tribe-common caption,.tribe-common center,.tribe-common cite,.tribe-common code,.tribe-common dd,.tribe-common del,.tribe-common details,.tribe-common dfn,.tribe-common div,.tribe-common dl,.tribe-common dt,.tribe-common em,.tribe-common embed,.tribe-common fieldset,.tribe-common figcaption,.tribe-common figure,.tribe-common footer,.tribe-common form,.tribe-common h1,.tribe-common h2,.tribe-common h3,.tribe-common h4,.tribe-common h5,.tribe-common h6,.tribe-common header,.tribe-common i,.tribe-common iframe,.tribe-common img,.tribe-common ins,.tribe-common kbd,.tribe-common label,.tribe-common legend,.tribe-common li,.tribe-common main,.tribe-common mark,.tribe-common menu,.tribe-common nav,.tribe-common object,.tribe-common ol,.tribe-common output,.tribe-common p,.tribe-common pre,.tribe-common q,.tribe-common ruby,.tribe-common s,.tribe-common samp,.tribe-common section,.tribe-common small,.tribe-common span,.tribe-common strike,.tribe-common strong,.tribe-common sub,.tribe-common summary,.tribe-common sup,.tribe-common table,.tribe-common tbody,.tribe-common td,.tribe-common tfoot,.tribe-common th,.tribe-common thead,.tribe-common time,.tribe-common tr,.tribe-common tt,.tribe-common u,.tribe-common ul,.tribe-common var,.tribe-common video{margin:0;padding:0;border:0}.tribe-common ol,.tribe-common ul{list-style:none}.tribe-common img{-ms-interpolation-mode:bicubic;height:auto;max-width:100%;border-style:none}.tribe-common embed,.tribe-common iframe,.tribe-common video{max-width:100%;max-height:100%}.tribe-theme-avada input[type=text]{margin:0}.tribe-theme-divi .entry-content .tribe-common table,.tribe-theme-divibody.et-pb-preview #main-content .container .tribe-common table{border:0;margin:0}.tribe-theme-divi .entry-content .tribe-common td,.tribe-theme-divibody.et-pb-preview #main-content .container .tribe-common td{border:0}.tribe-theme-divi #content-area .tribe-common td,.tribe-theme-divi #content-area .tribe-common th,.tribe-theme-divi #content-area .tribe-common tr,.tribe-theme-divi #left-area .tribe-common ul{padding:0}#top .main_color .tribe-common button[disabled],#top.tribe-theme-enfold .tribe-common button[disabled]{cursor:default}#top .main_color .tribe-common form,#top .main_color .tribe-common input,#top.tribe-theme-enfold .tribe-common form,#top.tribe-theme-enfold .tribe-common input{margin:0}.entry-content-wrapper .tribe-common li,.entry-content .tribe-common ol,.entry-content .tribe-common ul,.tribe-theme-genesis .tribe-common ol,.tribe-theme-genesis .tribe-common ul{margin:0;padding:0}.tribe-theme-twentyseventeen .tribe-common div.tribe-dialog{z-index:5!important}.tribe-common .tribe-common-form-control-checkbox__label,.tribe-common .tribe-common-form-control-radio__label{cursor:pointer;display:inline-block;margin-left:11px;vertical-align:middle}.tribe-common .tribe-common-form-control-checkbox__input,.tribe-common .tribe-common-form-control-radio__input{cursor:pointer;display:inline-block;margin:0;vertical-align:middle}#top .main_color .tribe-common .tribe-common-form-control-checkbox__input,#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-checkbox__input{display:inline-block}.tribe-common .tribe-common-form-control-checkbox-radio-group>*{margin-bottom:15px}.tribe-common .tribe-common-form-control-checkbox-radio-group>:last-child{margin-bottom:0}.tribe-common .tribe-common-form-control-slider__input{cursor:pointer;display:inline-block;margin:0;padding:0;width:120px;vertical-align:middle}.tribe-common .tribe-common-form-control-slider__label{cursor:pointer;display:inline-block;margin-left:11px;vertical-align:middle}.tribe-common .tribe-common-form-control-slider--vertical .tribe-common-form-control-slider__label{display:block;margin:0 0 6px}.tribe-common .tribe-common-form-control-text__label{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.tribe-common .tribe-common-form-control-text__input{height:auto;padding:12px 28px 12px 0;width:100%}.tribe-common--breakpoint-medium.tribe-common .tribe-common-form-control-text__input{padding:20px 20px 20px 40px}#top .main_color .tribe-common .tribe-common-form-control-text__input,#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-text__input{padding:12px 28px 12px 0;width:100%}#top .main_color .tribe-common.tribe-common--breakpoint-medium .tribe-common-form-control-text__input,#top.tribe-theme-enfold .tribe-common.tribe-common--breakpoint-medium .tribe-common-form-control-text__input{padding:20px 20px 20px 40px}.tribe-common .tribe-common-form-control-toggle__input,.tribe-common .tribe-common-form-control-toggle__label{cursor:pointer;display:inline-block;vertical-align:middle}.tribe-common .tribe-common-form-control-toggle__label{margin-left:11px}.tribe-common .tribe-common-form-control-toggle--vertical .tribe-common-form-control-toggle__label{display:block;margin:0 0 6px}#top .main_color .tribe-common .tribe-common-form-control-toggle__input,#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-toggle__input{display:inline-block;margin:5px 0}.tribe-common .tribe-common-g-col{min-width:0;width:100%}.tribe-common .tribe-common-g-row{display:flex;flex-wrap:wrap}.tribe-common .tribe-common-g-row--gutters{margin-left:-21px;margin-right:-21px}.tribe-common--breakpoint-medium.tribe-common .tribe-common-g-row--gutters{margin-left:-24px;margin-right:-24px}.tribe-common .tribe-common-g-row--gutters>.tribe-common-g-col{padding-left:21px;padding-right:21px}.tribe-common--breakpoint-medium.tribe-common .tribe-common-g-row--gutters>.tribe-common-g-col{padding-left:24px;padding-right:24px}.tribe-theme-twentynineteen .tribe-common .entry.tribe-common-g-row--gutters{margin-left:-21px;margin-right:-21px;padding:0}.tribe-theme-twentynineteen .tribe-common.tribe-common--breakpoint-medium .entry.tribe-common-g-row--gutters{margin-left:-24px;margin-right:-24px}.tribe-theme-twentynineteen .tribe-common .tribe-common-g-row--gutters>.entry.tribe-common-g-col{margin:0;padding-left:21px;padding-right:21px}.tribe-theme-twentynineteen .tribe-common.tribe-common--breakpoint-medium .tribe-common-g-row--gutters>.entry.tribe-common-g-col{padding-left:24px;padding-right:24px}.tribe-common a{cursor:pointer}.tribe-theme-divi #left-area .tribe-common ul,.tribe-theme-divi .entry-content .tribe-common ul,body.et-pb-preview.tribe-theme-divi #main-content .container .tribe-common ul{list-style-type:none;padding:0}.entry-content .tribe-common ol>li,.entry-content .tribe-common ul>li{list-style-type:none}.tribe-common button{padding:0}.tribe-common .tribe-common-l-container{max-width:1260px;margin-left:auto;margin-right:auto;padding-left:19.5px;padding-right:19.5px;width:100%}.tribe-common--breakpoint-medium.tribe-common .tribe-common-l-container{padding-left:42px;padding-right:42px}.tribe-common .tribe-common-svgicon{background-repeat:no-repeat;background-size:contain}.tribe-common .tribe-common-svgicon--close-secondary{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18'%3E%3Cpath d='M16 2L2 16m14 0L2 2' stroke='%23BABABA' fill='none' fill-rule='evenodd' stroke-linecap='square' stroke-width='2'/%3E%3C/svg%3E")}.tribe-common .tribe-common-svgicon--day{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='21' height='21' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 .503v19.994c0 .278.19.503.424.503h20.152c.234 0 .424-.225.424-.503V.503C21 .225 20.81 0 20.576 0H.424C.19 0 0 .225 0 .503zm1.156.943h18.66v2.7H1.157v-2.7zm0 4.023h18.66V19.55H1.157V5.469zM14.18 14.53v1.747c0 .482.39.874.873.874H16.8a.873.873 0 0 0 .873-.874V14.53a.873.873 0 0 0-.873-.873h-1.747a.873.873 0 0 0-.873.873z' fill='%23141827'/%3E%3C/svg%3E")}.tribe-common .tribe-common-svgicon--list{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 22 22'%3E%3Cg fill='%23141827' fill-rule='evenodd'%3E%3Cpath fill-rule='nonzero' d='M0 .504v20.03c0 .278.19.503.425.503h20.188c.235 0 .425-.225.425-.504V.503c0-.277-.19-.503-.425-.503H.425C.19 0 0 .226 0 .504zm1.158.944h18.695v2.705H1.158V1.448zm0 2.705h18.695v15.432H1.158V4.153z'/%3E%3Cpath d='M13.39 5.731v2.13a1.07 1.07 0 0 0 1.076 1.064h2.154a1.07 1.07 0 0 0 1.077-1.065V5.731a1.07 1.07 0 0 0-1.077-1.064h-2.154A1.07 1.07 0 0 0 13.39 5.73z'/%3E%3Cpath fill-rule='nonzero' d='M8.84 8.937c.286 0 .52-.236.52-.523v-.425a.523.523 0 0 0-.52-.522H4.02a.523.523 0 0 0-.52.522v.425c0 .287.234.523.52.523h4.82zm2.064-2.8c.287 0 .521-.236.521-.523v-.425a.523.523 0 0 0-.52-.522H4.02a.523.523 0 0 0-.521.522v.425c0 .287.234.523.52.523h6.884z'/%3E%3Cpath d='M13.39 12.731v2.13a1.07 1.07 0 0 0 1.076 1.064h2.154a1.07 1.07 0 0 0 1.077-1.065v-2.129a1.07 1.07 0 0 0-1.077-1.064h-2.154a1.07 1.07 0 0 0-1.077 1.064z'/%3E%3Cpath fill-rule='nonzero' d='M8.84 15.937c.286 0 .52-.236.52-.523v-.425a.523.523 0 0 0-.52-.522H4.02a.523.523 0 0 0-.52.522v.425c0 .287.234.523.52.523h4.82zm2.064-2.8c.287 0 .521-.236.521-.523v-.425a.523.523 0 0 0-.52-.522H4.02a.523.523 0 0 0-.521.522v.425c0 .287.234.523.52.523h6.884z'/%3E%3C/g%3E%3C/svg%3E")}.tribe-common .tribe-common-svgicon--map{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 22 22'%3E%3Cg fill='%23141827' fill-rule='nonzero'%3E%3Cg stroke-width='.7'%3E%3Cpath stroke='%23141827' d='M10.67 17.21c.182-.225 4.46-5.527 4.46-8.18 0-2.728-2.085-4.947-4.648-4.947-2.563 0-4.649 2.22-4.649 4.946 0 2.654 4.279 7.956 4.46 8.18a.243.243 0 0 0 .189.092c.072 0 .14-.034.188-.092zM6.33 9.03c0-2.436 1.863-4.418 4.152-4.418 2.29 0 4.152 1.982 4.152 4.417 0 2.16-3.318 6.533-4.152 7.597C9.648 15.562 6.33 11.19 6.33 9.03z'/%3E%3Cpath stroke='%23000' d='M12.055 9.04c0-.911-.706-1.652-1.573-1.652-.868 0-1.574.74-1.574 1.652 0 .91.706 1.652 1.574 1.652.867 0 1.573-.741 1.573-1.652zm-2.85 0c0-.74.573-1.34 1.277-1.34s1.277.6 1.277 1.34c0 .74-.573 1.34-1.277 1.34s-1.277-.6-1.277-1.34z'/%3E%3C/g%3E%3Cpath d='M0 .504v20.03c0 .278.19.503.425.503h20.188c.235 0 .425-.225.425-.504V.503c0-.277-.19-.503-.425-.503H.425C.19 0 0 .226 0 .504zm1.158.944h18.695v2.705H1.158V1.448zm0 2.705h18.695v15.432H1.158V4.153z'/%3E%3C/g%3E%3C/svg%3E")}.tribe-common .tribe-common-svgicon--month{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='22' height='22' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M.637 1.063v19.879c0 .276.189.5.422.5h20.037c.232 0 .421-.224.421-.5V1.062c0-.275-.189-.5-.421-.5H1.059c-.233 0-.422.225-.422.5zM1.787 2H20.34v2.685H1.787V2zm0 4H20.34v14H1.787V6zM8 8.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5zm4 0v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5zm4 0v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5zm-8 4v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5zm4 0v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5zm4 0v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5zm-12 0v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5zm0 4v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5zm4 0v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5zm4 0v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5z' fill='%23141827'/%3E%3C/svg%3E")}.tribe-common .tribe-common-svgicon--no-map{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='92' height='92' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none'%3E%3Cg stroke='%23141827' stroke-width='2.5' transform='translate(2 2)'%3E%3Cpath d='M32.219 88S0 58.674 0 32.281C-.011 15.598 12.685 1.66 29.278.136c16.593-1.523 31.608 9.873 34.627 26.28M32.733 88s2.96-2.693 7.083-7.181' stroke-linecap='round'/%3E%3Ccircle cx='33' cy='33' r='8.905'/%3E%3Ccircle cx='65.127' cy='59.016' r='23.571'/%3E%3C/g%3E%3Cg transform='translate(64.857 47.048)'%3E%3Ccircle fill='%23111' cx='2.839' cy='26.495' r='2.839'/%3E%3Cpath d='M2.642 0v18.925' stroke='%23141827' stroke-width='2.25' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E")}.tribe-common .tribe-common-svgicon--photo{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 21 21'%3E%3Cg fill='%23141827'%3E%3Cpath d='M20.407 0H.577A.565.565 0 0 0 0 .564v19.872c0 .316.254.564.578.564h19.83a.565.565 0 0 0 .577-.564V.564A.565.565 0 0 0 20.407 0zm-.6 1.15v14.868l-2.226-3.427c-.646-.677-1.848-.677-2.495 0l-1.548 1.646-4.482-5.029a1.806 1.806 0 0 0-1.363-.586c-.508 0-1.016.225-1.34.609l-5.175 5.75V1.15h18.628zM1.177 19.85v-3.133l6.053-6.765a.588.588 0 0 1 .462-.203c.162 0 .37.068.485.203l4.921 5.525c.116.113.278.203.44.203.184.022.323-.068.438-.18l1.987-2.12c.185-.203.555-.203.763 0l3.103 4.352v2.14H1.178v-.022z'/%3E%3Cpath d='M14.955 9.041c1.16 0 2.122-.97 2.122-2.187 0-1.218-.94-2.187-2.122-2.187-1.181 0-2.122.97-2.122 2.187 0 1.218.963 2.187 2.122 2.187zm0-3.224c.547 0 1.006.473 1.006 1.037s-.459 1.037-1.006 1.037c-.547 0-1.006-.473-1.006-1.037s.46-1.037 1.006-1.037z'/%3E%3C/g%3E%3C/svg%3E")}.tribe-common .tribe-common-svgicon--week{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='21' height='21' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 .503v19.994c0 .278.19.503.424.503h20.152c.234 0 .424-.225.424-.503V.503C21 .225 20.81 0 20.576 0H.424C.19 0 0 .225 0 .503zm1.156.943h18.66v2.7H1.157v-2.7zm0 4.023h18.66V19.55H1.157V5.469zm6.25 6.537v1.006c0 .278.224.503.502.503h1.006a.503.503 0 0 0 .503-.503v-1.006a.503.503 0 0 0-.503-.502H7.908a.503.503 0 0 0-.503.502zm4.022 0v1.006c0 .278.225.503.503.503h1.006a.503.503 0 0 0 .503-.503v-1.006a.503.503 0 0 0-.503-.502H11.93a.503.503 0 0 0-.503.502zm4.023 0v1.006c0 .278.225.503.503.503h1.006a.503.503 0 0 0 .503-.503v-1.006a.503.503 0 0 0-.503-.502h-1.006a.503.503 0 0 0-.503.502zm-12.069 0v1.006c0 .278.225.503.503.503h1.006a.503.503 0 0 0 .503-.503v-1.006a.503.503 0 0 0-.503-.502H3.885a.503.503 0 0 0-.503.502z' fill='%23141827'/%3E%3C/svg%3E")}.tribe-common .tribe-common-svgicon--featured{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='16' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 0h16v20l-7.902-5.122L0 20z' fill='%23141827'/%3E%3C/svg%3E");height:10px;width:8px}.tribe-common .tribe-common-svgicon--recurring{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='20' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M13.333 3.826c0 .065 0 .13-.02.174 0 .022-.02.065-.02.087a.9.9 0 0 1-.197.37L10.45 7.37a.797.797 0 0 1-.592.26.797.797 0 0 1-.593-.26c-.316-.348-.316-.935 0-1.305l1.225-1.348H6.3c-2.547 0-4.64 2.283-4.64 5.11 0 1.369.474 2.651 1.363 3.608.316.348.316.935 0 1.304A.797.797 0 0 1 2.43 15a.797.797 0 0 1-.593-.26C.652 13.434 0 11.695 0 9.847c0-3.826 2.825-6.935 6.301-6.935h4.208L9.284 1.565c-.316-.348-.316-.935 0-1.304.316-.348.85-.348 1.185 0l2.647 2.913a.952.952 0 0 1 .198.37c0 .021.02.065.02.086v.196zM20 10.152c0 3.826-2.825 6.935-6.301 6.935H9.49l1.225 1.348c.336.348.336.935 0 1.304a.797.797 0 0 1-.593.261.83.83 0 0 1-.592-.26l-2.627-2.936a.948.948 0 0 1-.198-.37c0-.021-.02-.064-.02-.086-.02-.065-.02-.109-.02-.174 0-.065 0-.13.02-.174 0-.022.02-.065.02-.087a.9.9 0 0 1 .198-.37L9.55 12.63c.316-.347.849-.347 1.185 0 .336.348.336.935 0 1.305L9.51 15.283h4.208c2.548 0 4.641-2.283 4.641-5.11 0-1.369-.474-2.651-1.362-3.608a.97.97 0 0 1 0-1.304c.316-.348.849-.348 1.185 0C19.348 6.543 20 8.283 20 10.152z' fill='%23141827'/%3E%3C/svg%3E");height:10px;width:10px}.tribe-common .tribe-common-svgicon--search{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='20' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M20 18.711l-6.044-6.044a7.782 7.782 0 0 0 1.688-4.845c0-2.089-.822-4.044-2.288-5.533C11.866.822 9.91 0 7.822 0S3.778.822 2.29 2.289A7.801 7.801 0 0 0 0 7.822c0 2.09.822 4.045 2.289 5.534a7.801 7.801 0 0 0 5.533 2.288c1.778 0 3.467-.6 4.845-1.688L18.71 20 20 18.711zM3.578 12.067c-2.334-2.334-2.334-6.156 0-8.49a5.968 5.968 0 0 1 4.244-1.755c1.6 0 3.111.622 4.245 1.756 2.333 2.333 2.333 6.155 0 8.489a5.968 5.968 0 0 1-4.245 1.755c-1.6 0-3.11-.622-4.244-1.755z' fill='%235D5D5D'/%3E%3C/svg%3E")}.tribe-common .tribe-common-svgicon--filters{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='17' height='17'%3E%3Cg fill='none' fill-rule='evenodd' stroke='%235D5D5D' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' transform='translate(1 1)'%3E%3Cpath d='M3 3V0m0 15v-2'/%3E%3Ccircle cx='3' cy='9' r='3'/%3E%3Cpath d='M12 9v6'/%3E%3Ccircle cx='12' cy='3' r='3' transform='matrix(1 0 0 -1 0 6)'/%3E%3C/g%3E%3C/svg%3E")}.tribe-common .tribe-common-svgicon--close{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18'%3E%3Cpath d='M16 2L2 16m14 0L2 2' stroke='%235D5D5D' fill='none' fill-rule='evenodd' stroke-linecap='square' stroke-width='2'/%3E%3C/svg%3E")}.tribe-common .tribe-common-a11y-hidden{display:none!important;visibility:hidden}.tribe-common .tribe-common-a11y-visual-hide,.tribe-common .tribe-common-a11y-visual-show{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.tribe-common .tribe-common-c-btn-border,.tribe-common a.tribe-common-c-btn-border{padding:14px 20px;width:100%}.tribe-common--breakpoint-medium.tribe-common .tribe-common-c-btn-border,.tribe-common--breakpoint-medium.tribe-common a.tribe-common-c-btn-border{padding:6px 15px;width:auto}.tribe-common .tribe-common-c-btn-icon:before{background-repeat:no-repeat;background-size:contain;content:"";display:block}.tribe-common .tribe-common-c-btn-icon--caret-left:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='12' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11.916 17.841L10 19.757l-9.9-9.9L10-.041l1.916 1.916-7.983 7.984z' fill='%23BABABA'/%3E%3C/svg%3E");height:20px;width:12px}.tribe-common .tribe-common-c-btn-icon--caret-left:active:before,.tribe-common .tribe-common-c-btn-icon--caret-left:focus:before,.tribe-common .tribe-common-c-btn-icon--caret-left:hover:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='12' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11.916 17.841L10 19.757l-9.9-9.9L10-.041l1.916 1.916-7.983 7.984z' fill='%235D5D5D'/%3E%3C/svg%3E")}.tribe-common .tribe-common-c-btn-icon--caret-left:disabled:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='12' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11.916 17.841L10 19.757l-9.9-9.9L10-.041l1.916 1.916-7.983 7.984z' fill='%23D5D5D5'/%3E%3C/svg%3E")}.tribe-common .tribe-common-c-btn-icon--caret-right:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='12' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M.084 2.159L2 .243l9.9 9.9L2 20.041.084 18.126l7.983-7.984z' fill='%23BABABA'/%3E%3C/svg%3E");height:20px;width:12px}.tribe-common .tribe-common-c-btn-icon--caret-right:active:before,.tribe-common .tribe-common-c-btn-icon--caret-right:focus:before,.tribe-common .tribe-common-c-btn-icon--caret-right:hover:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='12' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M.084 2.159L2 .243l9.9 9.9L2 20.041.084 18.126l7.983-7.984z' fill='%235D5D5D'/%3E%3C/svg%3E")}.tribe-common .tribe-common-c-btn-icon--caret-right:disabled:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='12' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M.084 2.159L2 .243l9.9 9.9L2 20.041.084 18.126l7.983-7.984z' fill='%23D5D5D5'/%3E%3C/svg%3E")}.tribe-common .tribe-common-c-btn-icon--filters:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='17' height='17'%3E%3Cg fill='none' fill-rule='evenodd' stroke='%235D5D5D' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' transform='translate(1 1)'%3E%3Cpath d='M3 3V0m0 15v-2'/%3E%3Ccircle cx='3' cy='9' r='3'/%3E%3Cpath d='M12 9v6'/%3E%3Ccircle cx='12' cy='3' r='3' transform='matrix(1 0 0 -1 0 6)'/%3E%3C/g%3E%3C/svg%3E");height:20px;width:24px}.tribe-common .tribe-common-c-btn-icon--filters:active:before,.tribe-common .tribe-common-c-btn-icon--filters:focus:before,.tribe-common .tribe-common-c-btn-icon--filters:hover:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='17' height='17'%3E%3Cg fill='none' fill-rule='evenodd' stroke='%23141827' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' transform='translate(1 1)'%3E%3Cpath d='M3 3V0m0 15v-2'/%3E%3Ccircle cx='3' cy='9' r='3'/%3E%3Cpath d='M12 9v6'/%3E%3Ccircle cx='12' cy='3' r='3' transform='matrix(1 0 0 -1 0 6)'/%3E%3C/g%3E%3C/svg%3E")}.tribe-common .tribe-common-c-btn-icon--filters:disabled:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='17' height='17'%3E%3Cg fill='none' fill-rule='evenodd' stroke='%23D5D5D5' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' transform='translate(1 1)'%3E%3Cpath d='M3 3V0m0 15v-2'/%3E%3Ccircle cx='3' cy='9' r='3'/%3E%3Cpath d='M12 9v6'/%3E%3Ccircle cx='12' cy='3' r='3' transform='matrix(1 0 0 -1 0 6)'/%3E%3C/g%3E%3C/svg%3E")}.tribe-common .tribe-common-c-btn-icon--search:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='20' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M20 18.711l-6.044-6.044a7.782 7.782 0 0 0 1.688-4.845c0-2.089-.822-4.044-2.288-5.533C11.866.822 9.91 0 7.822 0S3.778.822 2.29 2.289A7.801 7.801 0 0 0 0 7.822c0 2.09.822 4.045 2.289 5.534a7.801 7.801 0 0 0 5.533 2.288c1.778 0 3.467-.6 4.845-1.688L18.71 20 20 18.711zM3.578 12.067c-2.334-2.334-2.334-6.156 0-8.49a5.968 5.968 0 0 1 4.244-1.755c1.6 0 3.111.622 4.245 1.756 2.333 2.333 2.333 6.155 0 8.489a5.968 5.968 0 0 1-4.245 1.755c-1.6 0-3.11-.622-4.244-1.755z' fill='%235D5D5D'/%3E%3C/svg%3E");height:20px;width:20px}.tribe-common .tribe-common-c-btn-icon--search:active:before,.tribe-common .tribe-common-c-btn-icon--search:focus:before,.tribe-common .tribe-common-c-btn-icon--search:hover:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='20' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M20 18.711l-6.044-6.044a7.782 7.782 0 0 0 1.688-4.845c0-2.089-.822-4.044-2.288-5.533C11.866.822 9.91 0 7.822 0S3.778.822 2.29 2.289A7.801 7.801 0 0 0 0 7.822c0 2.09.822 4.045 2.289 5.534a7.801 7.801 0 0 0 5.533 2.288c1.778 0 3.467-.6 4.845-1.688L18.71 20 20 18.711zM3.578 12.067c-2.334-2.334-2.334-6.156 0-8.49a5.968 5.968 0 0 1 4.244-1.755c1.6 0 3.111.622 4.245 1.756 2.333 2.333 2.333 6.155 0 8.489a5.968 5.968 0 0 1-4.245 1.755c-1.6 0-3.11-.622-4.244-1.755z' fill='%23141827'/%3E%3C/svg%3E")}.tribe-common .tribe-common-c-btn-icon--search:disabled:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='20' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M20 18.711l-6.044-6.044a7.782 7.782 0 0 0 1.688-4.845c0-2.089-.822-4.044-2.288-5.533C11.866.822 9.91 0 7.822 0S3.778.822 2.29 2.289A7.801 7.801 0 0 0 0 7.822c0 2.09.822 4.045 2.289 5.534a7.801 7.801 0 0 0 5.533 2.288c1.778 0 3.467-.6 4.845-1.688L18.71 20 20 18.711zM3.578 12.067c-2.334-2.334-2.334-6.156 0-8.49a5.968 5.968 0 0 1 4.244-1.755c1.6 0 3.111.622 4.245 1.756 2.333 2.333 2.333 6.155 0 8.489a5.968 5.968 0 0 1-4.245 1.755c-1.6 0-3.11-.622-4.244-1.755z' fill='%23D5D5D5'/%3E%3C/svg%3E")}.tribe-common .tribe-common-c-btn,.tribe-common a.tribe-common-c-btn{padding:11px 20px;width:100%}.tribe-common--breakpoint-medium.tribe-common .tribe-common-c-btn,.tribe-common--breakpoint-medium.tribe-common a.tribe-common-c-btn{width:auto}.tribe-common .tribe-common-c-image{display:block;height:auto;margin-left:auto;margin-right:auto;width:100%}.tribe-common .tribe-common-c-image--bg{position:relative}.tribe-common .tribe-common-c-image__bg{background:50% no-repeat;background-size:cover;bottom:0;height:100%;left:0;position:absolute;right:0;top:0;width:100%}.tribe-common .tribe-common-c-loader{display:flex;padding-top:192px}.tribe-common--breakpoint-medium.tribe-common .tribe-common-c-loader{padding-top:288px}.tribe-common .tribe-common-c-loader__dot{background-color:rgba(51,74,255,.07);height:15px;width:15px;border-radius:50%}.tribe-common .tribe-common-c-loader__dot:not(:first-of-type){margin-left:8px}
|
|
|
common/src/resources/css/common.css
ADDED
|
@@ -0,0 +1,2264 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* This CSS file was auto-generated via PostCSS
|
| 3 |
+
*
|
| 4 |
+
* Contributors should avoid editing this file, but instead edit the associated
|
| 5 |
+
* src/resources/postcss/ file. For more information, check out our engineering
|
| 6 |
+
* docs on how we handle CSS in our engineering docs.
|
| 7 |
+
*
|
| 8 |
+
* @see: http://moderntribe.github.io/products-engineering/css/
|
| 9 |
+
*/
|
| 10 |
+
|
| 11 |
+
/*
|
| 12 |
+
* Common CSS
|
| 13 |
+
*
|
| 14 |
+
* DO NOT EDIT THIS CSS FILE DIRECTLY.
|
| 15 |
+
* -------------------------------------------------------------
|
| 16 |
+
* This file is just a clearing-house, see the pcss directory
|
| 17 |
+
* and edit the source files found there.
|
| 18 |
+
*/
|
| 19 |
+
|
| 20 |
+
/* Reset */
|
| 21 |
+
|
| 22 |
+
/* -----------------------------------------------------------------------------
|
| 23 |
+
*
|
| 24 |
+
* Normalize "Light"
|
| 25 |
+
*
|
| 26 |
+
* ----------------------------------------------------------------------------- */
|
| 27 |
+
|
| 28 |
+
.tribe-common figure {
|
| 29 |
+
line-height: 0;
|
| 30 |
+
}
|
| 31 |
+
|
| 32 |
+
.tribe-common figcaption {
|
| 33 |
+
line-height: normal;
|
| 34 |
+
}
|
| 35 |
+
|
| 36 |
+
.tribe-common a {
|
| 37 |
+
background-color: transparent;
|
| 38 |
+
-webkit-text-decoration-skip: objects;
|
| 39 |
+
}
|
| 40 |
+
|
| 41 |
+
.tribe-common abbr[title] {
|
| 42 |
+
border-bottom: none;
|
| 43 |
+
text-decoration: underline;
|
| 44 |
+
-webkit-text-decoration: underline dotted;
|
| 45 |
+
text-decoration: underline dotted;
|
| 46 |
+
}
|
| 47 |
+
|
| 48 |
+
.tribe-common code,
|
| 49 |
+
.tribe-common kbd,
|
| 50 |
+
.tribe-common pre,
|
| 51 |
+
.tribe-common samp {
|
| 52 |
+
font-family: monospace;
|
| 53 |
+
font-size: 1em;
|
| 54 |
+
}
|
| 55 |
+
|
| 56 |
+
.tribe-common b,
|
| 57 |
+
.tribe-common strong {
|
| 58 |
+
font-weight: inherit;
|
| 59 |
+
font-weight: bolder;
|
| 60 |
+
}
|
| 61 |
+
|
| 62 |
+
.tribe-common dfn {
|
| 63 |
+
font-style: italic;
|
| 64 |
+
}
|
| 65 |
+
|
| 66 |
+
.tribe-common mark {
|
| 67 |
+
background-color: #ff0;
|
| 68 |
+
color: #000;
|
| 69 |
+
}
|
| 70 |
+
|
| 71 |
+
.tribe-common small {
|
| 72 |
+
font-size: 80%;
|
| 73 |
+
}
|
| 74 |
+
|
| 75 |
+
.tribe-common sub,
|
| 76 |
+
.tribe-common sup {
|
| 77 |
+
font-size: 75%;
|
| 78 |
+
line-height: 0;
|
| 79 |
+
}
|
| 80 |
+
|
| 81 |
+
.tribe-common hr {
|
| 82 |
+
border: 0;
|
| 83 |
+
height: 0;
|
| 84 |
+
}
|
| 85 |
+
|
| 86 |
+
/* Input: Kill browser input chrome */
|
| 87 |
+
|
| 88 |
+
.tribe-common input[type="text"],
|
| 89 |
+
.tribe-common input[type="email"],
|
| 90 |
+
.tribe-common input[type="url"],
|
| 91 |
+
.tribe-common input[type="search"],
|
| 92 |
+
.tribe-common input[type="submit"],
|
| 93 |
+
.tribe-common input[type="password"],
|
| 94 |
+
.tribe-common input[type="reset"],
|
| 95 |
+
.tribe-common input[type="button"],
|
| 96 |
+
.tribe-common button,
|
| 97 |
+
.tribe-common textarea {
|
| 98 |
+
-webkit-appearance: none;
|
| 99 |
+
-moz-appearance: none;
|
| 100 |
+
appearance: none;
|
| 101 |
+
}
|
| 102 |
+
|
| 103 |
+
.tribe-common input,
|
| 104 |
+
.tribe-common button,
|
| 105 |
+
.tribe-common select,
|
| 106 |
+
.tribe-common textarea,
|
| 107 |
+
.tribe-common optgroup {
|
| 108 |
+
color: inherit;
|
| 109 |
+
font: inherit;
|
| 110 |
+
line-height: normal;
|
| 111 |
+
-webkit-font-smoothing: antialiased;
|
| 112 |
+
}
|
| 113 |
+
|
| 114 |
+
.tribe-common input,
|
| 115 |
+
.tribe-common button,
|
| 116 |
+
.tribe-common select,
|
| 117 |
+
.tribe-common textarea {
|
| 118 |
+
outline: 0;
|
| 119 |
+
border-radius: 0;
|
| 120 |
+
}
|
| 121 |
+
|
| 122 |
+
.tribe-common select:-moz-focusring {
|
| 123 |
+
color: transparent;
|
| 124 |
+
text-shadow: 0 0 0 #000;
|
| 125 |
+
}
|
| 126 |
+
|
| 127 |
+
.tribe-common optgroup {
|
| 128 |
+
font-weight: bold;
|
| 129 |
+
}
|
| 130 |
+
|
| 131 |
+
/* -----------------------------------------------------------------------------
|
| 132 |
+
*
|
| 133 |
+
* Reset "Light"
|
| 134 |
+
*
|
| 135 |
+
* ----------------------------------------------------------------------------- */
|
| 136 |
+
|
| 137 |
+
.tribe-common ol,
|
| 138 |
+
.tribe-common ul {
|
| 139 |
+
list-style: none;
|
| 140 |
+
}
|
| 141 |
+
|
| 142 |
+
.tribe-common h1,
|
| 143 |
+
.tribe-common h2,
|
| 144 |
+
.tribe-common h3,
|
| 145 |
+
.tribe-common h4,
|
| 146 |
+
.tribe-common h5,
|
| 147 |
+
.tribe-common h6,
|
| 148 |
+
.tribe-common p {
|
| 149 |
+
font-weight: normal;
|
| 150 |
+
text-rendering: optimizeLegibility;
|
| 151 |
+
}
|
| 152 |
+
|
| 153 |
+
/* Utilities */
|
| 154 |
+
|
| 155 |
+
/* -----------------------------------------------------------------------------
|
| 156 |
+
*
|
| 157 |
+
* Utilities
|
| 158 |
+
*
|
| 159 |
+
* This file is just a clearing-house.
|
| 160 |
+
* Make partials (start with an underscore) for any actual css code.
|
| 161 |
+
*
|
| 162 |
+
* ----------------------------------------------------------------------------- */
|
| 163 |
+
|
| 164 |
+
/* Variables */
|
| 165 |
+
|
| 166 |
+
:root {
|
| 167 |
+
/* -----------------------------------------------------------------------------
|
| 168 |
+
* Borders - Radius
|
| 169 |
+
* ----------------------------------------------------------------------------- */
|
| 170 |
+
|
| 171 |
+
}
|
| 172 |
+
|
| 173 |
+
:root {
|
| 174 |
+
/* -----------------------------------------------------------------------------
|
| 175 |
+
* Box Shadows
|
| 176 |
+
* ----------------------------------------------------------------------------- */
|
| 177 |
+
}
|
| 178 |
+
|
| 179 |
+
:root {
|
| 180 |
+
/* -----------------------------------------------------------------------------
|
| 181 |
+
* Layers of z-index
|
| 182 |
+
* ----------------------------------------------------------------------------- */
|
| 183 |
+
}
|
| 184 |
+
|
| 185 |
+
:root {
|
| 186 |
+
/* -----------------------------------------------------------------------------
|
| 187 |
+
* Colors - Typography
|
| 188 |
+
* ----------------------------------------------------------------------------- */
|
| 189 |
+
|
| 190 |
+
/* -----------------------------------------------------------------------------
|
| 191 |
+
* Colors - Iconography
|
| 192 |
+
* ----------------------------------------------------------------------------- */
|
| 193 |
+
|
| 194 |
+
/* -----------------------------------------------------------------------------
|
| 195 |
+
* Colors - UI
|
| 196 |
+
* ----------------------------------------------------------------------------- */
|
| 197 |
+
|
| 198 |
+
/* -----------------------------------------------------------------------------
|
| 199 |
+
* Colors - Borders & Misc
|
| 200 |
+
* ----------------------------------------------------------------------------- */
|
| 201 |
+
|
| 202 |
+
}
|
| 203 |
+
|
| 204 |
+
:root {
|
| 205 |
+
/* -----------------------------------------------------------------------------
|
| 206 |
+
* Forms - Colors
|
| 207 |
+
* ----------------------------------------------------------------------------- */
|
| 208 |
+
|
| 209 |
+
/* -----------------------------------------------------------------------------
|
| 210 |
+
* Forms - Box Shadows
|
| 211 |
+
* ----------------------------------------------------------------------------- */
|
| 212 |
+
}
|
| 213 |
+
|
| 214 |
+
:root {
|
| 215 |
+
/* -----------------------------------------------------------------------------
|
| 216 |
+
* Gutter - Default
|
| 217 |
+
* ----------------------------------------------------------------------------- */
|
| 218 |
+
|
| 219 |
+
/* -----------------------------------------------------------------------------
|
| 220 |
+
* Gutter - Page
|
| 221 |
+
* ----------------------------------------------------------------------------- */
|
| 222 |
+
|
| 223 |
+
/* -----------------------------------------------------------------------------
|
| 224 |
+
* Grid Width - Default
|
| 225 |
+
* ----------------------------------------------------------------------------- */
|
| 226 |
+
|
| 227 |
+
/* -----------------------------------------------------------------------------
|
| 228 |
+
* Grid Width - Relative
|
| 229 |
+
* ----------------------------------------------------------------------------- */
|
| 230 |
+
}
|
| 231 |
+
|
| 232 |
+
:root {
|
| 233 |
+
/* -----------------------------------------------------------------------------
|
| 234 |
+
* Opacities
|
| 235 |
+
* ----------------------------------------------------------------------------- */
|
| 236 |
+
}
|
| 237 |
+
|
| 238 |
+
:root {
|
| 239 |
+
/* -----------------------------------------------------------------------------
|
| 240 |
+
* Spacers
|
| 241 |
+
* ----------------------------------------------------------------------------- */
|
| 242 |
+
}
|
| 243 |
+
|
| 244 |
+
/* -----------------------------------------------------------------------------
|
| 245 |
+
* SVG - Arrow Right
|
| 246 |
+
* ----------------------------------------------------------------------------- */
|
| 247 |
+
|
| 248 |
+
/* -----------------------------------------------------------------------------
|
| 249 |
+
* SVG - Caret Down
|
| 250 |
+
* ----------------------------------------------------------------------------- */
|
| 251 |
+
|
| 252 |
+
/* -----------------------------------------------------------------------------
|
| 253 |
+
* SVG - Caret Left
|
| 254 |
+
* ----------------------------------------------------------------------------- */
|
| 255 |
+
|
| 256 |
+
/* -----------------------------------------------------------------------------
|
| 257 |
+
* SVG - Caret Right
|
| 258 |
+
* ----------------------------------------------------------------------------- */
|
| 259 |
+
|
| 260 |
+
/* -----------------------------------------------------------------------------
|
| 261 |
+
* SVG - Caret Up
|
| 262 |
+
* ----------------------------------------------------------------------------- */
|
| 263 |
+
|
| 264 |
+
/* -----------------------------------------------------------------------------
|
| 265 |
+
* SVG - Check
|
| 266 |
+
* ----------------------------------------------------------------------------- */
|
| 267 |
+
|
| 268 |
+
/* -----------------------------------------------------------------------------
|
| 269 |
+
* SVG - Day
|
| 270 |
+
* ----------------------------------------------------------------------------- */
|
| 271 |
+
|
| 272 |
+
/* -----------------------------------------------------------------------------
|
| 273 |
+
* SVG - Dropdown
|
| 274 |
+
* ----------------------------------------------------------------------------- */
|
| 275 |
+
|
| 276 |
+
/* -----------------------------------------------------------------------------
|
| 277 |
+
* SVG - Featured
|
| 278 |
+
* ----------------------------------------------------------------------------- */
|
| 279 |
+
|
| 280 |
+
/* -----------------------------------------------------------------------------
|
| 281 |
+
* SVG - Filters
|
| 282 |
+
* ----------------------------------------------------------------------------- */
|
| 283 |
+
|
| 284 |
+
/* -----------------------------------------------------------------------------
|
| 285 |
+
* SVG - List
|
| 286 |
+
* ----------------------------------------------------------------------------- */
|
| 287 |
+
|
| 288 |
+
/* -----------------------------------------------------------------------------
|
| 289 |
+
* SVG - Location
|
| 290 |
+
* ----------------------------------------------------------------------------- */
|
| 291 |
+
|
| 292 |
+
/* -----------------------------------------------------------------------------
|
| 293 |
+
* SVG - Map
|
| 294 |
+
* ----------------------------------------------------------------------------- */
|
| 295 |
+
|
| 296 |
+
/* -----------------------------------------------------------------------------
|
| 297 |
+
* SVG - Month
|
| 298 |
+
* ----------------------------------------------------------------------------- */
|
| 299 |
+
|
| 300 |
+
/* -----------------------------------------------------------------------------
|
| 301 |
+
* SVG - Photo
|
| 302 |
+
* ----------------------------------------------------------------------------- */
|
| 303 |
+
|
| 304 |
+
/* -----------------------------------------------------------------------------
|
| 305 |
+
* SVG - Recurring
|
| 306 |
+
* ----------------------------------------------------------------------------- */
|
| 307 |
+
|
| 308 |
+
/* -----------------------------------------------------------------------------
|
| 309 |
+
* SVG - Reset
|
| 310 |
+
* ----------------------------------------------------------------------------- */
|
| 311 |
+
|
| 312 |
+
/* -----------------------------------------------------------------------------
|
| 313 |
+
* SVG - Search
|
| 314 |
+
* ----------------------------------------------------------------------------- */
|
| 315 |
+
|
| 316 |
+
/* -----------------------------------------------------------------------------
|
| 317 |
+
* SVG - Search Filter
|
| 318 |
+
* ----------------------------------------------------------------------------- */
|
| 319 |
+
|
| 320 |
+
/* -----------------------------------------------------------------------------
|
| 321 |
+
* SVG - Week
|
| 322 |
+
* ----------------------------------------------------------------------------- */
|
| 323 |
+
|
| 324 |
+
:root {
|
| 325 |
+
/* -----------------------------------------------------------------------------
|
| 326 |
+
* Transitions
|
| 327 |
+
* ----------------------------------------------------------------------------- */
|
| 328 |
+
}
|
| 329 |
+
|
| 330 |
+
:root {
|
| 331 |
+
/* -----------------------------------------------------------------------------
|
| 332 |
+
* Font Stacks
|
| 333 |
+
* ----------------------------------------------------------------------------- */
|
| 334 |
+
|
| 335 |
+
/* -----------------------------------------------------------------------------
|
| 336 |
+
* Font Weights
|
| 337 |
+
* ----------------------------------------------------------------------------- */
|
| 338 |
+
|
| 339 |
+
/* -----------------------------------------------------------------------------
|
| 340 |
+
* Font Sizing
|
| 341 |
+
* ----------------------------------------------------------------------------- */
|
| 342 |
+
|
| 343 |
+
/* -----------------------------------------------------------------------------
|
| 344 |
+
* Line Height
|
| 345 |
+
* ----------------------------------------------------------------------------- */
|
| 346 |
+
}
|
| 347 |
+
|
| 348 |
+
/* Mixins */
|
| 349 |
+
|
| 350 |
+
/* -----------------------------------------------------------------------------
|
| 351 |
+
* Body
|
| 352 |
+
* ----------------------------------------------------------------------------- */
|
| 353 |
+
|
| 354 |
+
/* -----------------------------------------------------------------------------
|
| 355 |
+
* Desktop Body 1
|
| 356 |
+
* ----------------------------------------------------------------------------- */
|
| 357 |
+
|
| 358 |
+
/* -----------------------------------------------------------------------------
|
| 359 |
+
* Desktop Body 2
|
| 360 |
+
* ----------------------------------------------------------------------------- */
|
| 361 |
+
|
| 362 |
+
/* -----------------------------------------------------------------------------
|
| 363 |
+
* Desktop Body 3
|
| 364 |
+
* ----------------------------------------------------------------------------- */
|
| 365 |
+
|
| 366 |
+
/* -----------------------------------------------------------------------------
|
| 367 |
+
* Mobile Body 1
|
| 368 |
+
* ----------------------------------------------------------------------------- */
|
| 369 |
+
|
| 370 |
+
/* -----------------------------------------------------------------------------
|
| 371 |
+
* Mobile Body 2
|
| 372 |
+
* ----------------------------------------------------------------------------- */
|
| 373 |
+
|
| 374 |
+
/* -----------------------------------------------------------------------------
|
| 375 |
+
* Mobile Body 3
|
| 376 |
+
* ----------------------------------------------------------------------------- */
|
| 377 |
+
|
| 378 |
+
/* -----------------------------------------------------------------------------
|
| 379 |
+
* Heading
|
| 380 |
+
* ----------------------------------------------------------------------------- */
|
| 381 |
+
|
| 382 |
+
/* -----------------------------------------------------------------------------
|
| 383 |
+
* Heading 1
|
| 384 |
+
* ----------------------------------------------------------------------------- */
|
| 385 |
+
|
| 386 |
+
/* -----------------------------------------------------------------------------
|
| 387 |
+
* Heading 2
|
| 388 |
+
* ----------------------------------------------------------------------------- */
|
| 389 |
+
|
| 390 |
+
/* -----------------------------------------------------------------------------
|
| 391 |
+
* Heading 3
|
| 392 |
+
* ----------------------------------------------------------------------------- */
|
| 393 |
+
|
| 394 |
+
/* -----------------------------------------------------------------------------
|
| 395 |
+
* Heading 4
|
| 396 |
+
* ----------------------------------------------------------------------------- */
|
| 397 |
+
|
| 398 |
+
/* -----------------------------------------------------------------------------
|
| 399 |
+
* Heading 5
|
| 400 |
+
* ----------------------------------------------------------------------------- */
|
| 401 |
+
|
| 402 |
+
/* -----------------------------------------------------------------------------
|
| 403 |
+
* Heading 6
|
| 404 |
+
* ----------------------------------------------------------------------------- */
|
| 405 |
+
|
| 406 |
+
/* -----------------------------------------------------------------------------
|
| 407 |
+
* Heading 7
|
| 408 |
+
* ----------------------------------------------------------------------------- */
|
| 409 |
+
|
| 410 |
+
/* -----------------------------------------------------------------------------
|
| 411 |
+
* Heading 8
|
| 412 |
+
* ----------------------------------------------------------------------------- */
|
| 413 |
+
|
| 414 |
+
/* -----------------------------------------------------------------------------
|
| 415 |
+
* Anchor - Default
|
| 416 |
+
* ----------------------------------------------------------------------------- */
|
| 417 |
+
|
| 418 |
+
/* -----------------------------------------------------------------------------
|
| 419 |
+
* Anchor - Alt
|
| 420 |
+
* ----------------------------------------------------------------------------- */
|
| 421 |
+
|
| 422 |
+
/* -----------------------------------------------------------------------------
|
| 423 |
+
* Anchor - Thin
|
| 424 |
+
* ----------------------------------------------------------------------------- */
|
| 425 |
+
|
| 426 |
+
/* -----------------------------------------------------------------------------
|
| 427 |
+
* Button - Global
|
| 428 |
+
* ----------------------------------------------------------------------------- */
|
| 429 |
+
|
| 430 |
+
/* -----------------------------------------------------------------------------
|
| 431 |
+
* Button - Solid
|
| 432 |
+
* ----------------------------------------------------------------------------- */
|
| 433 |
+
|
| 434 |
+
/* -----------------------------------------------------------------------------
|
| 435 |
+
* Button - Border
|
| 436 |
+
* ----------------------------------------------------------------------------- */
|
| 437 |
+
|
| 438 |
+
/* -----------------------------------------------------------------------------
|
| 439 |
+
* Button - Icon Border
|
| 440 |
+
* ----------------------------------------------------------------------------- */
|
| 441 |
+
|
| 442 |
+
/* -----------------------------------------------------------------------------
|
| 443 |
+
* Sliders & Toggles
|
| 444 |
+
* ----------------------------------------------------------------------------- */
|
| 445 |
+
|
| 446 |
+
/* -----------------------------------------------------------------------------
|
| 447 |
+
* Sliders
|
| 448 |
+
* ----------------------------------------------------------------------------- */
|
| 449 |
+
|
| 450 |
+
/* -----------------------------------------------------------------------------
|
| 451 |
+
* Hidden: Hide from both screenreaders and browsers
|
| 452 |
+
* @author: h5bp.com/u
|
| 453 |
+
* ----------------------------------------------------------------------------- */
|
| 454 |
+
|
| 455 |
+
/* -----------------------------------------------------------------------------
|
| 456 |
+
* Visually Hide: Hide only visually, but have it available for screenreaders
|
| 457 |
+
* @author: h5bp.com/v
|
| 458 |
+
* ----------------------------------------------------------------------------- */
|
| 459 |
+
|
| 460 |
+
/* -----------------------------------------------------------------------------
|
| 461 |
+
* Visually Show: Show element after has been hidden with %visually-hide
|
| 462 |
+
* ----------------------------------------------------------------------------- */
|
| 463 |
+
|
| 464 |
+
/* Base */
|
| 465 |
+
|
| 466 |
+
/* -----------------------------------------------------------------------------
|
| 467 |
+
*
|
| 468 |
+
* Base
|
| 469 |
+
*
|
| 470 |
+
* This file is just a clearing-house.
|
| 471 |
+
* Make partials (start with an underscore) for any actual css code.
|
| 472 |
+
*
|
| 473 |
+
* ----------------------------------------------------------------------------- */
|
| 474 |
+
|
| 475 |
+
/* Forms */
|
| 476 |
+
|
| 477 |
+
.tribe-common {
|
| 478 |
+
|
| 479 |
+
/* -----------------------------------------------------------------------------
|
| 480 |
+
*
|
| 481 |
+
* Form Control: Checkboxes & Radios Theme Overrides
|
| 482 |
+
*
|
| 483 |
+
* ----------------------------------------------------------------------------- */
|
| 484 |
+
|
| 485 |
+
/* -----------------------------------------------------------------------------
|
| 486 |
+
* Form Control: Checkboxes Theme Overrides
|
| 487 |
+
* ----------------------------------------------------------------------------- */
|
| 488 |
+
|
| 489 |
+
/* -----------------------------------------------------------------------------
|
| 490 |
+
* Form Control: Radios Theme Overrides
|
| 491 |
+
* ----------------------------------------------------------------------------- */
|
| 492 |
+
}
|
| 493 |
+
|
| 494 |
+
/* -----------------------------------------------------------------------------
|
| 495 |
+
*
|
| 496 |
+
* Form Control: Checkboxes & Radios
|
| 497 |
+
*
|
| 498 |
+
* Example (Checkboxes):
|
| 499 |
+
* <fieldset>
|
| 500 |
+
* <legend>Legend for Checkboxes</legend>
|
| 501 |
+
* <div class="tribe-common-form-control-checkbox-radio-group">
|
| 502 |
+
* <div class="tribe-common-form-control-checkbox">
|
| 503 |
+
* <input
|
| 504 |
+
* class="tribe-common-form-control-checkbox__input"
|
| 505 |
+
* id="checkboxOne"
|
| 506 |
+
* name="checkboxGroup"
|
| 507 |
+
* type="checkbox"
|
| 508 |
+
* value="checkboxOne"
|
| 509 |
+
* checked="checked"
|
| 510 |
+
* />
|
| 511 |
+
* <label
|
| 512 |
+
* class="tribe-common-form-control-checkbox__label"
|
| 513 |
+
* for="checkboxOne"
|
| 514 |
+
* >
|
| 515 |
+
* Checkbox One
|
| 516 |
+
* </label>
|
| 517 |
+
* </div>
|
| 518 |
+
* <div class="tribe-common-form-control-checkbox">
|
| 519 |
+
* <input
|
| 520 |
+
* class="tribe-common-form-control-checkbox__input"
|
| 521 |
+
* id="checkboxTwo"
|
| 522 |
+
* name="checkboxGroup"
|
| 523 |
+
* type="checkbox"
|
| 524 |
+
* value="checkboxTwo"
|
| 525 |
+
* />
|
| 526 |
+
* <label
|
| 527 |
+
* class="tribe-common-form-control-checkbox__label"
|
| 528 |
+
* for="checkboxTwo"
|
| 529 |
+
* >
|
| 530 |
+
* Checkbox Two
|
| 531 |
+
* </label>
|
| 532 |
+
* </div>
|
| 533 |
+
* </div>
|
| 534 |
+
* </fieldset>
|
| 535 |
+
*
|
| 536 |
+
* Example (Radios):
|
| 537 |
+
* <div class="tribe-common-form-control-checkbox-radio-group">
|
| 538 |
+
* <div class="tribe-common-form-control-radio">
|
| 539 |
+
* <input
|
| 540 |
+
* class="tribe-common-form-control-radio__input"
|
| 541 |
+
* id="radioExample"
|
| 542 |
+
* name="radioExample"
|
| 543 |
+
* type="radio"
|
| 544 |
+
* value="RadioExample"
|
| 545 |
+
* checked="checked"
|
| 546 |
+
* />
|
| 547 |
+
* <label
|
| 548 |
+
* class="tribe-common-form-control-radio__label"
|
| 549 |
+
* for="radioExample"
|
| 550 |
+
* >
|
| 551 |
+
* Radio Example
|
| 552 |
+
* </label>
|
| 553 |
+
* </div>
|
| 554 |
+
* </div>
|
| 555 |
+
*
|
| 556 |
+
* ----------------------------------------------------------------------------- */
|
| 557 |
+
|
| 558 |
+
.tribe-common .tribe-common-form-control-checkbox,
|
| 559 |
+
.tribe-common .tribe-common-form-control-radio {
|
| 560 |
+
line-height: 0;
|
| 561 |
+
}
|
| 562 |
+
|
| 563 |
+
.tribe-common .tribe-common-form-control-checkbox__label,
|
| 564 |
+
.tribe-common .tribe-common-form-control-radio__label {
|
| 565 |
+
color: #141827;
|
| 566 |
+
font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
|
| 567 |
+
font-size: 14px;
|
| 568 |
+
line-height: 1.62;
|
| 569 |
+
font-weight: 400;
|
| 570 |
+
|
| 571 |
+
color: #727272;
|
| 572 |
+
cursor: pointer;
|
| 573 |
+
display: inline-block;
|
| 574 |
+
margin-left: 11px;
|
| 575 |
+
vertical-align: middle;
|
| 576 |
+
}
|
| 577 |
+
|
| 578 |
+
.tribe-common .tribe-common-form-control-checkbox__input,
|
| 579 |
+
.tribe-common .tribe-common-form-control-radio__input {
|
| 580 |
+
-webkit-appearance: none;
|
| 581 |
+
-moz-appearance: none;
|
| 582 |
+
appearance: none;
|
| 583 |
+
background-color: #FFFFFF;
|
| 584 |
+
border: 1px solid #141827;
|
| 585 |
+
cursor: pointer;
|
| 586 |
+
display: inline-block;
|
| 587 |
+
height: 20px;
|
| 588 |
+
margin: 0;
|
| 589 |
+
position: relative;
|
| 590 |
+
vertical-align: middle;
|
| 591 |
+
width: 20px;
|
| 592 |
+
}
|
| 593 |
+
|
| 594 |
+
.tribe-common .tribe-common-form-control-checkbox__input:active,
|
| 595 |
+
.tribe-common .tribe-common-form-control-checkbox__input:focus,
|
| 596 |
+
.tribe-common .tribe-common-form-control-checkbox__input:hover,
|
| 597 |
+
.tribe-common .tribe-common-form-control-radio__input:active,
|
| 598 |
+
.tribe-common .tribe-common-form-control-radio__input:focus,
|
| 599 |
+
.tribe-common .tribe-common-form-control-radio__input:hover {
|
| 600 |
+
border: 1px solid #141827;
|
| 601 |
+
}
|
| 602 |
+
|
| 603 |
+
.tribe-common .tribe-common-form-control-checkbox__input:checked, .tribe-common .tribe-common-form-control-radio__input:checked {
|
| 604 |
+
background-color: #141827;
|
| 605 |
+
}
|
| 606 |
+
|
| 607 |
+
/* -----------------------------------------------------------------------------
|
| 608 |
+
* Form Control: Checkboxes
|
| 609 |
+
* ----------------------------------------------------------------------------- */
|
| 610 |
+
|
| 611 |
+
.tribe-common .tribe-common-form-control-checkbox__input:checked:before {
|
| 612 |
+
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='12' height='9' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M10.6.1L3.9 6.8 1.4 4.3c-.1-.1-.3-.1-.4 0l-.8.8c-.1.1-.1.3 0 .4l3.4 3.4c.2.1.4.1.5 0l7.7-7.7c.1-.1.1-.3 0-.4L11 .1c-.1-.1-.3-.1-.4 0z' fill='%23FFFFFF'/%3E%3C/svg%3E");
|
| 613 |
+
background-repeat: no-repeat;
|
| 614 |
+
background-size: contain;
|
| 615 |
+
content: '';
|
| 616 |
+
display: block;
|
| 617 |
+
height: 9px;
|
| 618 |
+
left: 50%;
|
| 619 |
+
position: absolute;
|
| 620 |
+
top: 50%;
|
| 621 |
+
-webkit-transform: translate(-50%, -50%);
|
| 622 |
+
transform: translate(-50%, -50%);
|
| 623 |
+
width: 12px;
|
| 624 |
+
}
|
| 625 |
+
|
| 626 |
+
/* -----------------------------------------------------------------------------
|
| 627 |
+
* Form Control: Radios
|
| 628 |
+
* ----------------------------------------------------------------------------- */
|
| 629 |
+
|
| 630 |
+
.tribe-common .tribe-common-form-control-radio__input {
|
| 631 |
+
border-radius: 50%;
|
| 632 |
+
}
|
| 633 |
+
|
| 634 |
+
.tribe-common .tribe-common-form-control-radio__input:checked:before {
|
| 635 |
+
background-color: #FFFFFF;
|
| 636 |
+
border-radius: 50%;
|
| 637 |
+
content: '';
|
| 638 |
+
display: block;
|
| 639 |
+
height: 8px;
|
| 640 |
+
left: 50%;
|
| 641 |
+
position: absolute;
|
| 642 |
+
top: 50%;
|
| 643 |
+
-webkit-transform: translate(-50%, -50%);
|
| 644 |
+
transform: translate(-50%, -50%);
|
| 645 |
+
width: 8px;
|
| 646 |
+
}
|
| 647 |
+
|
| 648 |
+
/* -----------------------------------------------------------------------------
|
| 649 |
+
* Theme Overrides - Enfold
|
| 650 |
+
* ----------------------------------------------------------------------------- */
|
| 651 |
+
|
| 652 |
+
#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-checkbox__input {
|
| 653 |
+
display: inline-block;
|
| 654 |
+
}
|
| 655 |
+
|
| 656 |
+
#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-checkbox__label {
|
| 657 |
+
font-weight: 400;
|
| 658 |
+
font-size: 14px;
|
| 659 |
+
}
|
| 660 |
+
|
| 661 |
+
/* -----------------------------------------------------------------------------
|
| 662 |
+
* Theme Overrides - Enfold
|
| 663 |
+
* ----------------------------------------------------------------------------- */
|
| 664 |
+
|
| 665 |
+
#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-radio__label {
|
| 666 |
+
font-weight: 400;
|
| 667 |
+
font-size: 14px;
|
| 668 |
+
}
|
| 669 |
+
|
| 670 |
+
/* -----------------------------------------------------------------------------
|
| 671 |
+
*
|
| 672 |
+
* Form Control: Groups (Checkbox & Radio)
|
| 673 |
+
*
|
| 674 |
+
* Example:
|
| 675 |
+
* <div class="tribe-common-form-control-checkbox-radio-group">
|
| 676 |
+
* <div class="tribe-common-form-control-checkbox">
|
| 677 |
+
* <input id="checkboxOne" name="checkboxGroup" type="checkbox" value="checkboxOne" checked="checked" />
|
| 678 |
+
* <label for="checkboxOne">Checkbox One</label>
|
| 679 |
+
* </div>
|
| 680 |
+
* <div class="tribe-common-form-control-checkbox">
|
| 681 |
+
* <input id="checkboxTwo" name="checkboxGroup" type="checkbox" value="checkboxTwo" />
|
| 682 |
+
* <label for="checkboxTwo">Checkbox two</label>
|
| 683 |
+
* </div>
|
| 684 |
+
* </div>
|
| 685 |
+
*
|
| 686 |
+
* ----------------------------------------------------------------------------- */
|
| 687 |
+
|
| 688 |
+
.tribe-common .tribe-common-form-control-checkbox-radio-group > * {
|
| 689 |
+
margin-bottom: 15px;
|
| 690 |
+
}
|
| 691 |
+
|
| 692 |
+
.tribe-common .tribe-common-form-control-checkbox-radio-group > *:last-child {
|
| 693 |
+
margin-bottom: 0;
|
| 694 |
+
}
|
| 695 |
+
|
| 696 |
+
.tribe-common {
|
| 697 |
+
|
| 698 |
+
/* -----------------------------------------------------------------------------
|
| 699 |
+
*
|
| 700 |
+
* Form Control: Sliders Theme Overrides
|
| 701 |
+
*
|
| 702 |
+
* ----------------------------------------------------------------------------- */
|
| 703 |
+
}
|
| 704 |
+
|
| 705 |
+
/* -----------------------------------------------------------------------------
|
| 706 |
+
*
|
| 707 |
+
* Form Control: Sliders
|
| 708 |
+
*
|
| 709 |
+
* Example (Horizontal):
|
| 710 |
+
* <div class="tribe-common-form-control-slider">
|
| 711 |
+
* <input
|
| 712 |
+
* class="tribe-common-form-control-slider__input"
|
| 713 |
+
* id="sliderOne"
|
| 714 |
+
* type="range"
|
| 715 |
+
* min="0"
|
| 716 |
+
* max="100"
|
| 717 |
+
* value="50"
|
| 718 |
+
* />
|
| 719 |
+
* <label class="tribe-common-form-control-slider__label" for="sliderOne">Slider One</label>
|
| 720 |
+
* </div>
|
| 721 |
+
*
|
| 722 |
+
* Example (Vertical):
|
| 723 |
+
* <div class="tribe-common-form-control-slider tribe-common-form-control-slider--vertical">
|
| 724 |
+
* <label class="tribe-common-form-control-slider__label" for="sliderOne">Slider One</label>
|
| 725 |
+
* <input
|
| 726 |
+
* class="tribe-common-form-control-slider__input"
|
| 727 |
+
* id="sliderOne"
|
| 728 |
+
* type="range"
|
| 729 |
+
* min="0"
|
| 730 |
+
* max="100"
|
| 731 |
+
* value="50"
|
| 732 |
+
* />
|
| 733 |
+
* </div>
|
| 734 |
+
*
|
| 735 |
+
* ----------------------------------------------------------------------------- */
|
| 736 |
+
|
| 737 |
+
.tribe-common .tribe-common-form-control-slider {
|
| 738 |
+
line-height: 0;
|
| 739 |
+
}
|
| 740 |
+
|
| 741 |
+
.tribe-common .tribe-common-form-control-slider__input {
|
| 742 |
+
-webkit-appearance: none;
|
| 743 |
+
-moz-appearance: none;
|
| 744 |
+
appearance: none;
|
| 745 |
+
background-color: transparent;
|
| 746 |
+
border: 0;
|
| 747 |
+
cursor: pointer;
|
| 748 |
+
display: inline-block;
|
| 749 |
+
margin: 0;
|
| 750 |
+
padding: 0;
|
| 751 |
+
width: 120px;
|
| 752 |
+
vertical-align: middle;
|
| 753 |
+
}
|
| 754 |
+
|
| 755 |
+
/* -----------------------------------------------------------------------------
|
| 756 |
+
* Track styles
|
| 757 |
+
* ----------------------------------------------------------------------------- */
|
| 758 |
+
|
| 759 |
+
.tribe-common .tribe-common-form-control-slider__input::-webkit-slider-runnable-track {
|
| 760 |
+
border: none;
|
| 761 |
+
border-radius: 5px;
|
| 762 |
+
height: 10px;
|
| 763 |
+
margin: 5px 0;
|
| 764 |
+
padding: 0;
|
| 765 |
+
position: relative;
|
| 766 |
+
transition: background-color 0.2s ease;
|
| 767 |
+
background-color: #334AFF;
|
| 768 |
+
}
|
| 769 |
+
|
| 770 |
+
.tribe-common .tribe-common-form-control-slider__input::-moz-range-track {
|
| 771 |
+
border: none;
|
| 772 |
+
border-radius: 5px;
|
| 773 |
+
height: 10px;
|
| 774 |
+
margin: 5px 0;
|
| 775 |
+
padding: 0;
|
| 776 |
+
position: relative;
|
| 777 |
+
transition: background-color 0.2s ease;
|
| 778 |
+
background-color: #334AFF;
|
| 779 |
+
}
|
| 780 |
+
|
| 781 |
+
.tribe-common .tribe-common-form-control-slider__input::-ms-track {
|
| 782 |
+
background-color: transparent;
|
| 783 |
+
border-color: transparent;
|
| 784 |
+
border-width: 5px 0;
|
| 785 |
+
color: transparent;
|
| 786 |
+
height: 10px;
|
| 787 |
+
}
|
| 788 |
+
|
| 789 |
+
.tribe-common .tribe-common-form-control-slider__input::-ms-fill-lower,
|
| 790 |
+
.tribe-common .tribe-common-form-control-slider__input::-ms-fill-upper {
|
| 791 |
+
background-color: #334AFF;
|
| 792 |
+
border-radius: 10px;
|
| 793 |
+
}
|
| 794 |
+
|
| 795 |
+
/* -----------------------------------------------------------------------------
|
| 796 |
+
* Thumb styles
|
| 797 |
+
* ----------------------------------------------------------------------------- */
|
| 798 |
+
|
| 799 |
+
.tribe-common .tribe-common-form-control-slider__input::-webkit-slider-thumb {
|
| 800 |
+
background-color: #FFFFFF;
|
| 801 |
+
border: 1px solid #D5D5D5;
|
| 802 |
+
border-radius: 50%;
|
| 803 |
+
box-shadow: 0 2px 5px 0 rgba(0,0,0, 0.14);
|
| 804 |
+
height: 20px;
|
| 805 |
+
width: 20px;
|
| 806 |
+
margin-top: -5px;
|
| 807 |
+
|
| 808 |
+
-webkit-appearance: none;
|
| 809 |
+
|
| 810 |
+
appearance: none;
|
| 811 |
+
}
|
| 812 |
+
|
| 813 |
+
.tribe-common .tribe-common-form-control-slider__input::-moz-range-thumb {
|
| 814 |
+
background-color: #FFFFFF;
|
| 815 |
+
border: 1px solid #D5D5D5;
|
| 816 |
+
border-radius: 50%;
|
| 817 |
+
box-shadow: 0 2px 5px 0 rgba(0,0,0, 0.14);
|
| 818 |
+
height: 20px;
|
| 819 |
+
width: 20px;
|
| 820 |
+
margin-top: -5px;
|
| 821 |
+
}
|
| 822 |
+
|
| 823 |
+
.tribe-common .tribe-common-form-control-slider__input::-ms-thumb {
|
| 824 |
+
background-color: #FFFFFF;
|
| 825 |
+
border: 1px solid #D5D5D5;
|
| 826 |
+
border-radius: 50%;
|
| 827 |
+
box-shadow: 0 2px 5px 0 rgba(0,0,0, 0.14);
|
| 828 |
+
height: 20px;
|
| 829 |
+
width: 20px;
|
| 830 |
+
margin-top: -5px;
|
| 831 |
+
|
| 832 |
+
box-shadow: none;
|
| 833 |
+
margin-top: -1px;
|
| 834 |
+
}
|
| 835 |
+
|
| 836 |
+
.tribe-common .tribe-common-form-control-slider__label {
|
| 837 |
+
color: #141827;
|
| 838 |
+
font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
|
| 839 |
+
font-size: 12px;
|
| 840 |
+
line-height: 1.38;
|
| 841 |
+
font-weight: 400;
|
| 842 |
+
|
| 843 |
+
color: #727272;
|
| 844 |
+
cursor: pointer;
|
| 845 |
+
display: inline-block;
|
| 846 |
+
margin-left: 11px;
|
| 847 |
+
vertical-align: middle;
|
| 848 |
+
}
|
| 849 |
+
|
| 850 |
+
.tribe-common .tribe-common-form-control-slider--vertical .tribe-common-form-control-slider__label {
|
| 851 |
+
display: block;
|
| 852 |
+
margin: 0 0 6px;
|
| 853 |
+
}
|
| 854 |
+
|
| 855 |
+
/* -----------------------------------------------------------------------------
|
| 856 |
+
* Theme Overrides - Enfold
|
| 857 |
+
* ----------------------------------------------------------------------------- */
|
| 858 |
+
|
| 859 |
+
#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-slider__label {
|
| 860 |
+
font-weight: 400;
|
| 861 |
+
font-size: 12px;
|
| 862 |
+
}
|
| 863 |
+
|
| 864 |
+
.tribe-common {
|
| 865 |
+
|
| 866 |
+
/* -----------------------------------------------------------------------------
|
| 867 |
+
*
|
| 868 |
+
* Form Control: Text Theme Overrides
|
| 869 |
+
*
|
| 870 |
+
* ----------------------------------------------------------------------------- */
|
| 871 |
+
}
|
| 872 |
+
|
| 873 |
+
/* .tribe-common-form-control-text {} */
|
| 874 |
+
|
| 875 |
+
.tribe-common .tribe-common-form-control-text__label {
|
| 876 |
+
border: 0;
|
| 877 |
+
clip: rect(0 0 0 0);
|
| 878 |
+
height: 1px;
|
| 879 |
+
margin: -1px;
|
| 880 |
+
overflow: hidden;
|
| 881 |
+
padding: 0;
|
| 882 |
+
position: absolute;
|
| 883 |
+
width: 1px;
|
| 884 |
+
}
|
| 885 |
+
|
| 886 |
+
/* -----------------------------------------------------------------------------
|
| 887 |
+
*
|
| 888 |
+
* Form Control: Text
|
| 889 |
+
*
|
| 890 |
+
* Example:
|
| 891 |
+
* <div class="tribe-common-form-control-text">
|
| 892 |
+
* <label class="tribe-common-form-control-text__label" for="textInput">Text Input</label>
|
| 893 |
+
* <input
|
| 894 |
+
* class="tribe-common-form-control-text__input"
|
| 895 |
+
* id="textInput"
|
| 896 |
+
* name="textInput"
|
| 897 |
+
* type="text"
|
| 898 |
+
* placeholder="Text Input"
|
| 899 |
+
* />
|
| 900 |
+
* </div>
|
| 901 |
+
*
|
| 902 |
+
* ----------------------------------------------------------------------------- */
|
| 903 |
+
|
| 904 |
+
.tribe-common .tribe-common-form-control-text__input {
|
| 905 |
+
color: #141827;
|
| 906 |
+
font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
|
| 907 |
+
font-size: 16px;
|
| 908 |
+
line-height: 1.62;
|
| 909 |
+
font-weight: 400;
|
| 910 |
+
|
| 911 |
+
border: 0;
|
| 912 |
+
border-bottom: 1px solid #D5D5D5;
|
| 913 |
+
height: auto;
|
| 914 |
+
padding: 12px 28px 12px 0;
|
| 915 |
+
width: 100%;
|
| 916 |
+
}
|
| 917 |
+
|
| 918 |
+
.tribe-common .tribe-common-form-control-text__input::-webkit-input-placeholder {
|
| 919 |
+
color: #727272;
|
| 920 |
+
font-style: normal;
|
| 921 |
+
}
|
| 922 |
+
|
| 923 |
+
.tribe-common .tribe-common-form-control-text__input:-ms-input-placeholder {
|
| 924 |
+
color: #727272;
|
| 925 |
+
font-style: normal;
|
| 926 |
+
}
|
| 927 |
+
|
| 928 |
+
.tribe-common .tribe-common-form-control-text__input::-ms-input-placeholder {
|
| 929 |
+
color: #727272;
|
| 930 |
+
font-style: normal;
|
| 931 |
+
}
|
| 932 |
+
|
| 933 |
+
.tribe-common .tribe-common-form-control-text__input::placeholder {
|
| 934 |
+
color: #727272;
|
| 935 |
+
font-style: normal;
|
| 936 |
+
}
|
| 937 |
+
|
| 938 |
+
.tribe-common .tribe-common-form-control-text__input:focus {
|
| 939 |
+
border-bottom-color: #141827;
|
| 940 |
+
outline: 0;
|
| 941 |
+
}
|
| 942 |
+
|
| 943 |
+
/* -------------------------------------------------------------------------
|
| 944 |
+
* Theme Overrides - Twenty Seventeen
|
| 945 |
+
* ------------------------------------------------------------------------- */
|
| 946 |
+
|
| 947 |
+
.tribe-theme-twentyseventeen .tribe-common .tribe-common-form-control-text__input {
|
| 948 |
+
color: #141827;
|
| 949 |
+
}
|
| 950 |
+
|
| 951 |
+
/* -------------------------------------------------------------------------
|
| 952 |
+
* Theme Overrides - Enfold
|
| 953 |
+
* ------------------------------------------------------------------------- */
|
| 954 |
+
|
| 955 |
+
#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-text__input {
|
| 956 |
+
color: #141827;
|
| 957 |
+
font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
|
| 958 |
+
font-size: 16px;
|
| 959 |
+
line-height: 1.62;
|
| 960 |
+
font-weight: 400;
|
| 961 |
+
|
| 962 |
+
border: 0;
|
| 963 |
+
border-bottom: 1px solid #D5D5D5;
|
| 964 |
+
padding: 12px 28px 12px 0;
|
| 965 |
+
width: 100%;
|
| 966 |
+
}
|
| 967 |
+
|
| 968 |
+
#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-text__input:focus {
|
| 969 |
+
border-bottom-color: #141827;
|
| 970 |
+
box-shadow: none;
|
| 971 |
+
}
|
| 972 |
+
|
| 973 |
+
.tribe-common {
|
| 974 |
+
|
| 975 |
+
/* -----------------------------------------------------------------------------
|
| 976 |
+
*
|
| 977 |
+
* Form Control: Toggles Theme Overrides
|
| 978 |
+
*
|
| 979 |
+
* ----------------------------------------------------------------------------- */
|
| 980 |
+
}
|
| 981 |
+
|
| 982 |
+
/* -----------------------------------------------------------------------------
|
| 983 |
+
*
|
| 984 |
+
* Form Control: Toggles
|
| 985 |
+
*
|
| 986 |
+
* Example (Horizontal):
|
| 987 |
+
* <div class="tribe-common-form-control-toggle">
|
| 988 |
+
* <input
|
| 989 |
+
* class="tribe-common-form-control-toggle__input"
|
| 990 |
+
* id="toggleOne"
|
| 991 |
+
* name="toggleGroup"
|
| 992 |
+
* type="checkbox"
|
| 993 |
+
* value="toggleOne"
|
| 994 |
+
* />
|
| 995 |
+
* <label class="tribe-common-form-control-toggle__label" for="toggleOne">Toggle One</label>
|
| 996 |
+
* </div>
|
| 997 |
+
*
|
| 998 |
+
* Example (Vertical):
|
| 999 |
+
* <div class="tribe-common-form-control-toggle tribe-common-form-control-toggle--vertical">
|
| 1000 |
+
* <label class="tribe-common-form-control-toggle__label" for="toggleOne">Toggle One</label>
|
| 1001 |
+
* <input
|
| 1002 |
+
* class="tribe-common-form-control-toggle__input"
|
| 1003 |
+
* id="toggleOne"
|
| 1004 |
+
* name="toggleGroup"
|
| 1005 |
+
* type="checkbox"
|
| 1006 |
+
* value="toggleOne"
|
| 1007 |
+
* />
|
| 1008 |
+
* </div>
|
| 1009 |
+
*
|
| 1010 |
+
* ----------------------------------------------------------------------------- */
|
| 1011 |
+
|
| 1012 |
+
.tribe-common .tribe-common-form-control-toggle {
|
| 1013 |
+
line-height: 0;
|
| 1014 |
+
}
|
| 1015 |
+
|
| 1016 |
+
.tribe-common .tribe-common-form-control-toggle__input {
|
| 1017 |
+
border: none;
|
| 1018 |
+
border-radius: 5px;
|
| 1019 |
+
height: 10px;
|
| 1020 |
+
margin: 5px 0;
|
| 1021 |
+
padding: 0;
|
| 1022 |
+
position: relative;
|
| 1023 |
+
transition: background-color 0.2s ease;
|
| 1024 |
+
|
| 1025 |
+
-webkit-appearance: none;
|
| 1026 |
+
|
| 1027 |
+
-moz-appearance: none;
|
| 1028 |
+
|
| 1029 |
+
appearance: none;
|
| 1030 |
+
background-color: #D5D5D5;
|
| 1031 |
+
cursor: pointer;
|
| 1032 |
+
display: inline-block;
|
| 1033 |
+
vertical-align: middle;
|
| 1034 |
+
width: 40px;
|
| 1035 |
+
}
|
| 1036 |
+
|
| 1037 |
+
.tribe-common .tribe-common-form-control-toggle__input:after {
|
| 1038 |
+
background-color: #FFFFFF;
|
| 1039 |
+
border: 1px solid #D5D5D5;
|
| 1040 |
+
border-radius: 50%;
|
| 1041 |
+
box-shadow: 0 2px 5px 0 rgba(0,0,0, 0.14);
|
| 1042 |
+
height: 20px;
|
| 1043 |
+
width: 20px;
|
| 1044 |
+
|
| 1045 |
+
content: '';
|
| 1046 |
+
left: 0;
|
| 1047 |
+
position: absolute;
|
| 1048 |
+
top: -5px;
|
| 1049 |
+
transition: -webkit-transform 0.2s ease;
|
| 1050 |
+
transition: transform 0.2s ease;
|
| 1051 |
+
transition: transform 0.2s ease, -webkit-transform 0.2s ease;
|
| 1052 |
+
}
|
| 1053 |
+
|
| 1054 |
+
.tribe-common .tribe-common-form-control-toggle__input:checked {
|
| 1055 |
+
background-color: #334AFF;
|
| 1056 |
+
}
|
| 1057 |
+
|
| 1058 |
+
.tribe-common .tribe-common-form-control-toggle__input:checked:after {
|
| 1059 |
+
-webkit-transform: translateX(20px);
|
| 1060 |
+
transform: translateX(20px);
|
| 1061 |
+
}
|
| 1062 |
+
|
| 1063 |
+
.tribe-common .tribe-common-form-control-toggle__label {
|
| 1064 |
+
color: #141827;
|
| 1065 |
+
font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
|
| 1066 |
+
font-size: 12px;
|
| 1067 |
+
line-height: 1.38;
|
| 1068 |
+
font-weight: 400;
|
| 1069 |
+
|
| 1070 |
+
color: #727272;
|
| 1071 |
+
cursor: pointer;
|
| 1072 |
+
display: inline-block;
|
| 1073 |
+
margin-left: 11px;
|
| 1074 |
+
vertical-align: middle;
|
| 1075 |
+
}
|
| 1076 |
+
|
| 1077 |
+
.tribe-common .tribe-common-form-control-toggle--vertical .tribe-common-form-control-toggle__label {
|
| 1078 |
+
display: block;
|
| 1079 |
+
margin: 0 0 6px;
|
| 1080 |
+
}
|
| 1081 |
+
|
| 1082 |
+
/* -----------------------------------------------------------------------------
|
| 1083 |
+
* Theme Overrides - Enfold
|
| 1084 |
+
* ----------------------------------------------------------------------------- */
|
| 1085 |
+
|
| 1086 |
+
#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-toggle__input {
|
| 1087 |
+
display: inline-block;
|
| 1088 |
+
margin: 5px 0;
|
| 1089 |
+
}
|
| 1090 |
+
|
| 1091 |
+
#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-toggle__label {
|
| 1092 |
+
font-weight: 400;
|
| 1093 |
+
font-size: 12px;
|
| 1094 |
+
}
|
| 1095 |
+
|
| 1096 |
+
/* Grid */
|
| 1097 |
+
|
| 1098 |
+
/* -----------------------------------------------------------------------------
|
| 1099 |
+
* Grid: Columns
|
| 1100 |
+
* ----------------------------------------------------------------------------- */
|
| 1101 |
+
|
| 1102 |
+
.tribe-common .tribe-common-g-col {
|
| 1103 |
+
min-width: 0;
|
| 1104 |
+
width: 100%;
|
| 1105 |
+
}
|
| 1106 |
+
|
| 1107 |
+
/* -----------------------------------------------------------------------------
|
| 1108 |
+
*
|
| 1109 |
+
* Grid: Rows
|
| 1110 |
+
*
|
| 1111 |
+
* Example:
|
| 1112 |
+
* <div class="g-row">
|
| 1113 |
+
* <div class="g-col">
|
| 1114 |
+
* <p>Component or another grid layout, perhaps?</p>
|
| 1115 |
+
* </div>
|
| 1116 |
+
* </div>
|
| 1117 |
+
*
|
| 1118 |
+
* ----------------------------------------------------------------------------- */
|
| 1119 |
+
|
| 1120 |
+
.tribe-common .tribe-common-g-row {
|
| 1121 |
+
display: flex;
|
| 1122 |
+
flex-wrap: wrap;
|
| 1123 |
+
}
|
| 1124 |
+
|
| 1125 |
+
.tribe-common .tribe-common-g-row--gutters {
|
| 1126 |
+
margin-left: -21px;
|
| 1127 |
+
margin-right: -21px;
|
| 1128 |
+
}
|
| 1129 |
+
|
| 1130 |
+
.tribe-common .tribe-common-g-row--gutters > .tribe-common-g-col {
|
| 1131 |
+
padding-left: 21px;
|
| 1132 |
+
padding-right: 21px;
|
| 1133 |
+
}
|
| 1134 |
+
|
| 1135 |
+
/* Typography */
|
| 1136 |
+
|
| 1137 |
+
.tribe-common {
|
| 1138 |
+
|
| 1139 |
+
/* -------------------------------------------------------------------------
|
| 1140 |
+
*
|
| 1141 |
+
* Anchor: Theme Overrides
|
| 1142 |
+
*
|
| 1143 |
+
* ------------------------------------------------------------------------- */
|
| 1144 |
+
}
|
| 1145 |
+
|
| 1146 |
+
.tribe-common a {
|
| 1147 |
+
color: #141827;
|
| 1148 |
+
cursor: pointer;
|
| 1149 |
+
outline: 0;
|
| 1150 |
+
text-decoration: none;
|
| 1151 |
+
}
|
| 1152 |
+
|
| 1153 |
+
.tribe-common a:hover,
|
| 1154 |
+
.tribe-common a:focus,
|
| 1155 |
+
.tribe-common a:active,
|
| 1156 |
+
.tribe-common a:visited {
|
| 1157 |
+
color: #141827;
|
| 1158 |
+
outline: 0;
|
| 1159 |
+
text-decoration: none;
|
| 1160 |
+
}
|
| 1161 |
+
|
| 1162 |
+
/* -------------------------------------------------------------------------
|
| 1163 |
+
*
|
| 1164 |
+
* Anchor: Theme Overrides
|
| 1165 |
+
*
|
| 1166 |
+
* ------------------------------------------------------------------------- */
|
| 1167 |
+
|
| 1168 |
+
/* -------------------------------------------------------------------------
|
| 1169 |
+
* Theme Overrides - Twenty Seventeen
|
| 1170 |
+
* ------------------------------------------------------------------------- */
|
| 1171 |
+
|
| 1172 |
+
.tribe-theme-twentyseventeen .tribe-common a:hover,
|
| 1173 |
+
.tribe-theme-twentyseventeen .tribe-common a:focus {
|
| 1174 |
+
box-shadow: none;
|
| 1175 |
+
color: #141827;
|
| 1176 |
+
}
|
| 1177 |
+
|
| 1178 |
+
/* -------------------------------------------------------------------------
|
| 1179 |
+
* Theme Overrides - Twenty Nineteen
|
| 1180 |
+
* ------------------------------------------------------------------------- */
|
| 1181 |
+
|
| 1182 |
+
.tribe-theme-twentynineteen .entry .tribe-common a {
|
| 1183 |
+
text-decoration: none;
|
| 1184 |
+
}
|
| 1185 |
+
|
| 1186 |
+
/* -------------------------------------------------------------------------
|
| 1187 |
+
*
|
| 1188 |
+
* Anchor
|
| 1189 |
+
*
|
| 1190 |
+
* Example:
|
| 1191 |
+
* <a class="tribe-common-anchor">Anchor Text</a>
|
| 1192 |
+
* <a class="tribe-common-anchor-alt">Anchor Alt Text</a>
|
| 1193 |
+
* <a class="tribe-common-anchor-thin">Anchor Thin Text</a>
|
| 1194 |
+
*
|
| 1195 |
+
* ------------------------------------------------------------------------- */
|
| 1196 |
+
|
| 1197 |
+
.tribe-common .tribe-common-anchor {
|
| 1198 |
+
border-bottom: 2px solid transparent;
|
| 1199 |
+
transition: border-color 0.2s ease;
|
| 1200 |
+
}
|
| 1201 |
+
|
| 1202 |
+
.tribe-common .tribe-common-anchor:active,
|
| 1203 |
+
.tribe-common .tribe-common-anchor:focus,
|
| 1204 |
+
.tribe-common .tribe-common-anchor:hover {
|
| 1205 |
+
border-bottom: 2px solid #141827;
|
| 1206 |
+
}
|
| 1207 |
+
|
| 1208 |
+
.tribe-common .tribe-common-anchor-alt {
|
| 1209 |
+
border-bottom: 2px solid #334AFF;
|
| 1210 |
+
color: #141827;
|
| 1211 |
+
transition: color 0.2s ease;
|
| 1212 |
+
}
|
| 1213 |
+
|
| 1214 |
+
.tribe-common .tribe-common-anchor-alt:active,
|
| 1215 |
+
.tribe-common .tribe-common-anchor-alt:focus,
|
| 1216 |
+
.tribe-common .tribe-common-anchor-alt:hover {
|
| 1217 |
+
border-bottom: 2px solid #334AFF;
|
| 1218 |
+
color: #334AFF;
|
| 1219 |
+
}
|
| 1220 |
+
|
| 1221 |
+
.tribe-common .tribe-common-anchor-thin {
|
| 1222 |
+
border-bottom: 1px solid transparent;
|
| 1223 |
+
transition: border-color 0.2s ease;
|
| 1224 |
+
}
|
| 1225 |
+
|
| 1226 |
+
.tribe-common .tribe-common-anchor-thin:active,
|
| 1227 |
+
.tribe-common .tribe-common-anchor-thin:focus,
|
| 1228 |
+
.tribe-common .tribe-common-anchor-thin:hover {
|
| 1229 |
+
border-bottom: 1px solid #141827;
|
| 1230 |
+
}
|
| 1231 |
+
|
| 1232 |
+
/* -------------------------------------------------------------------------
|
| 1233 |
+
* Theme Overrides - Twenty Seventeen
|
| 1234 |
+
* ------------------------------------------------------------------------- */
|
| 1235 |
+
|
| 1236 |
+
.tribe-theme-twentyseventeen .tribe-common .tribe-common-anchor-alt:hover,
|
| 1237 |
+
.tribe-theme-twentyseventeen .tribe-common .tribe-common-anchor-alt:focus {
|
| 1238 |
+
color: #334AFF;
|
| 1239 |
+
}
|
| 1240 |
+
|
| 1241 |
+
/* -------------------------------------------------------------------------
|
| 1242 |
+
* Body 1
|
| 1243 |
+
* ------------------------------------------------------------------------- */
|
| 1244 |
+
|
| 1245 |
+
.tribe-common .tribe-common-b1 {
|
| 1246 |
+
color: #141827;
|
| 1247 |
+
font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
|
| 1248 |
+
font-size: 14px;
|
| 1249 |
+
font-weight: 400;
|
| 1250 |
+
line-height: 1.62;
|
| 1251 |
+
}
|
| 1252 |
+
|
| 1253 |
+
/* -------------------------------------------------------------------------
|
| 1254 |
+
*
|
| 1255 |
+
* Body
|
| 1256 |
+
*
|
| 1257 |
+
* Example:
|
| 1258 |
+
* <p class="tribe-common-b1">Text here</p>
|
| 1259 |
+
*
|
| 1260 |
+
* ------------------------------------------------------------------------- */
|
| 1261 |
+
|
| 1262 |
+
.tribe-common .tribe-common-b1--bold {
|
| 1263 |
+
font-weight: 700;
|
| 1264 |
+
}
|
| 1265 |
+
|
| 1266 |
+
/* -------------------------------------------------------------------------
|
| 1267 |
+
* Body 2
|
| 1268 |
+
* ------------------------------------------------------------------------- */
|
| 1269 |
+
|
| 1270 |
+
.tribe-common .tribe-common-b2 {
|
| 1271 |
+
color: #141827;
|
| 1272 |
+
font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
|
| 1273 |
+
font-size: 12px;
|
| 1274 |
+
font-weight: 400;
|
| 1275 |
+
line-height: 1.38;
|
| 1276 |
+
}
|
| 1277 |
+
|
| 1278 |
+
.tribe-common .tribe-common-b2--bold {
|
| 1279 |
+
font-weight: 700;
|
| 1280 |
+
}
|
| 1281 |
+
|
| 1282 |
+
/* -------------------------------------------------------------------------
|
| 1283 |
+
* Body 3
|
| 1284 |
+
* ------------------------------------------------------------------------- */
|
| 1285 |
+
|
| 1286 |
+
.tribe-common .tribe-common-b3 {
|
| 1287 |
+
color: #141827;
|
| 1288 |
+
font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
|
| 1289 |
+
font-size: 11px;
|
| 1290 |
+
font-weight: 400;
|
| 1291 |
+
line-height: 1.5;
|
| 1292 |
+
}
|
| 1293 |
+
|
| 1294 |
+
.tribe-common .tribe-common-b3--bold {
|
| 1295 |
+
font-weight: 700;
|
| 1296 |
+
}
|
| 1297 |
+
|
| 1298 |
+
/* -------------------------------------------------------------------------
|
| 1299 |
+
* Body 1 for --viewport-medium
|
| 1300 |
+
* ------------------------------------------------------------------------- */
|
| 1301 |
+
|
| 1302 |
+
.tribe-common {
|
| 1303 |
+
|
| 1304 |
+
/* -------------------------------------------------------------------------
|
| 1305 |
+
*
|
| 1306 |
+
* CTA: Theme Overrides
|
| 1307 |
+
*
|
| 1308 |
+
* ------------------------------------------------------------------------- */
|
| 1309 |
+
}
|
| 1310 |
+
|
| 1311 |
+
/* -------------------------------------------------------------------------
|
| 1312 |
+
*
|
| 1313 |
+
* CTA
|
| 1314 |
+
*
|
| 1315 |
+
* Example:
|
| 1316 |
+
* <a class="tribe-common-cta">Link Text</a>
|
| 1317 |
+
* <a class="tribe-common-cta tribe-common-cta--alt">Link Text Alt</a>
|
| 1318 |
+
*
|
| 1319 |
+
* ------------------------------------------------------------------------- */
|
| 1320 |
+
|
| 1321 |
+
.tribe-common .tribe-common-cta {
|
| 1322 |
+
color: #141827;
|
| 1323 |
+
font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
|
| 1324 |
+
font-size: 12px;
|
| 1325 |
+
line-height: 1.38;
|
| 1326 |
+
font-weight: 400;
|
| 1327 |
+
font-weight: 700;
|
| 1328 |
+
border-bottom: 2px solid transparent;
|
| 1329 |
+
transition: border-color 0.2s ease;
|
| 1330 |
+
}
|
| 1331 |
+
|
| 1332 |
+
.tribe-common .tribe-common-cta:active,
|
| 1333 |
+
.tribe-common .tribe-common-cta:focus,
|
| 1334 |
+
.tribe-common .tribe-common-cta:hover {
|
| 1335 |
+
border-bottom: 2px solid #141827;
|
| 1336 |
+
}
|
| 1337 |
+
|
| 1338 |
+
.tribe-common .tribe-common-cta--alt {
|
| 1339 |
+
border-bottom: 2px solid #334AFF;
|
| 1340 |
+
color: #141827;
|
| 1341 |
+
transition: color 0.2s ease;
|
| 1342 |
+
}
|
| 1343 |
+
|
| 1344 |
+
.tribe-common .tribe-common-cta--alt:active,
|
| 1345 |
+
.tribe-common .tribe-common-cta--alt:focus,
|
| 1346 |
+
.tribe-common .tribe-common-cta--alt:hover {
|
| 1347 |
+
border-bottom: 2px solid #334AFF;
|
| 1348 |
+
color: #334AFF;
|
| 1349 |
+
}
|
| 1350 |
+
|
| 1351 |
+
/* -------------------------------------------------------------------------
|
| 1352 |
+
* Theme Overrides - Twenty Seventeen
|
| 1353 |
+
* ------------------------------------------------------------------------- */
|
| 1354 |
+
|
| 1355 |
+
.tribe-theme-twentyseventeen .tribe-common .tribe-common-cta--alt:hover,
|
| 1356 |
+
.tribe-theme-twentyseventeen .tribe-common .tribe-common-cta--alt:focus {
|
| 1357 |
+
color: #334AFF;
|
| 1358 |
+
}
|
| 1359 |
+
|
| 1360 |
+
.tribe-common {
|
| 1361 |
+
/* -------------------------------------------------------------------------
|
| 1362 |
+
*
|
| 1363 |
+
* Heading
|
| 1364 |
+
*
|
| 1365 |
+
* Example:
|
| 1366 |
+
* <h1 class="tribe-common-h1">Heading Text</h1>
|
| 1367 |
+
*
|
| 1368 |
+
* ------------------------------------------------------------------------- */
|
| 1369 |
+
|
| 1370 |
+
/* -------------------------------------------------------------------------
|
| 1371 |
+
*
|
| 1372 |
+
* Heading: Theme Overrides
|
| 1373 |
+
*
|
| 1374 |
+
* ------------------------------------------------------------------------- */
|
| 1375 |
+
}
|
| 1376 |
+
|
| 1377 |
+
/* -------------------------------------------------------------------------
|
| 1378 |
+
* Heading: h1
|
| 1379 |
+
* ------------------------------------------------------------------------- */
|
| 1380 |
+
|
| 1381 |
+
.tribe-common .tribe-common-h1 {
|
| 1382 |
+
color: #141827;
|
| 1383 |
+
font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
|
| 1384 |
+
font-weight: 700;
|
| 1385 |
+
font-size: 28px;
|
| 1386 |
+
line-height: 1.42;
|
| 1387 |
+
}
|
| 1388 |
+
|
| 1389 |
+
/* -------------------------------------------------------------------------
|
| 1390 |
+
* Heading: h2
|
| 1391 |
+
* ------------------------------------------------------------------------- */
|
| 1392 |
+
|
| 1393 |
+
.tribe-common .tribe-common-h2 {
|
| 1394 |
+
color: #141827;
|
| 1395 |
+
font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
|
| 1396 |
+
font-weight: 700;
|
| 1397 |
+
font-size: 24px;
|
| 1398 |
+
line-height: 1.42;
|
| 1399 |
+
}
|
| 1400 |
+
|
| 1401 |
+
/* -------------------------------------------------------------------------
|
| 1402 |
+
* Heading: h3
|
| 1403 |
+
* ------------------------------------------------------------------------- */
|
| 1404 |
+
|
| 1405 |
+
.tribe-common .tribe-common-h3 {
|
| 1406 |
+
color: #141827;
|
| 1407 |
+
font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
|
| 1408 |
+
font-weight: 700;
|
| 1409 |
+
font-size: 22px;
|
| 1410 |
+
line-height: 1.5;
|
| 1411 |
+
}
|
| 1412 |
+
|
| 1413 |
+
/* -------------------------------------------------------------------------
|
| 1414 |
+
* Heading: h4
|
| 1415 |
+
* ------------------------------------------------------------------------- */
|
| 1416 |
+
|
| 1417 |
+
.tribe-common .tribe-common-h4 {
|
| 1418 |
+
color: #141827;
|
| 1419 |
+
font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
|
| 1420 |
+
font-weight: 700;
|
| 1421 |
+
font-size: 20px;
|
| 1422 |
+
line-height: 1.42;
|
| 1423 |
+
}
|
| 1424 |
+
|
| 1425 |
+
/* -------------------------------------------------------------------------
|
| 1426 |
+
* Heading: h5
|
| 1427 |
+
* ------------------------------------------------------------------------- */
|
| 1428 |
+
|
| 1429 |
+
.tribe-common .tribe-common-h5 {
|
| 1430 |
+
color: #141827;
|
| 1431 |
+
font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
|
| 1432 |
+
font-weight: 700;
|
| 1433 |
+
font-size: 18px;
|
| 1434 |
+
line-height: 1.5;
|
| 1435 |
+
}
|
| 1436 |
+
|
| 1437 |
+
/* -------------------------------------------------------------------------
|
| 1438 |
+
* Heading: h6
|
| 1439 |
+
* ------------------------------------------------------------------------- */
|
| 1440 |
+
|
| 1441 |
+
.tribe-common .tribe-common-h6 {
|
| 1442 |
+
color: #141827;
|
| 1443 |
+
font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
|
| 1444 |
+
font-weight: 700;
|
| 1445 |
+
font-size: 16px;
|
| 1446 |
+
line-height: 1.5;
|
| 1447 |
+
}
|
| 1448 |
+
|
| 1449 |
+
/* -------------------------------------------------------------------------
|
| 1450 |
+
* Heading: h7
|
| 1451 |
+
* ------------------------------------------------------------------------- */
|
| 1452 |
+
|
| 1453 |
+
.tribe-common .tribe-common-h7 {
|
| 1454 |
+
color: #141827;
|
| 1455 |
+
font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
|
| 1456 |
+
font-weight: 700;
|
| 1457 |
+
font-size: 14px;
|
| 1458 |
+
line-height: 1.62;
|
| 1459 |
+
}
|
| 1460 |
+
|
| 1461 |
+
/* -------------------------------------------------------------------------
|
| 1462 |
+
* Heading: h8
|
| 1463 |
+
* ------------------------------------------------------------------------- */
|
| 1464 |
+
|
| 1465 |
+
.tribe-common .tribe-common-h8 {
|
| 1466 |
+
color: #141827;
|
| 1467 |
+
font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
|
| 1468 |
+
font-weight: 700;
|
| 1469 |
+
font-size: 12px;
|
| 1470 |
+
line-height: 1.38;
|
| 1471 |
+
}
|
| 1472 |
+
|
| 1473 |
+
/* -------------------------------------------------------------------------
|
| 1474 |
+
* Heading: h3 for --viewport-medium
|
| 1475 |
+
* ------------------------------------------------------------------------- */
|
| 1476 |
+
|
| 1477 |
+
/* -------------------------------------------------------------------------
|
| 1478 |
+
* Heading: h4 for --viewport-medium
|
| 1479 |
+
* ------------------------------------------------------------------------- */
|
| 1480 |
+
|
| 1481 |
+
/* -------------------------------------------------------------------------
|
| 1482 |
+
* Heading: h5 for --viewport-medium
|
| 1483 |
+
* ------------------------------------------------------------------------- */
|
| 1484 |
+
|
| 1485 |
+
/* -------------------------------------------------------------------------
|
| 1486 |
+
* Heading: h6 for --viewport-medium
|
| 1487 |
+
* ------------------------------------------------------------------------- */
|
| 1488 |
+
|
| 1489 |
+
/* -------------------------------------------------------------------------
|
| 1490 |
+
* Heading: h7 for --viewport-medium
|
| 1491 |
+
* ------------------------------------------------------------------------- */
|
| 1492 |
+
|
| 1493 |
+
/* -------------------------------------------------------------------------
|
| 1494 |
+
* Heading: alt style
|
| 1495 |
+
* ------------------------------------------------------------------------- */
|
| 1496 |
+
|
| 1497 |
+
.tribe-common .tribe-common-h--alt {
|
| 1498 |
+
font-weight: 400;
|
| 1499 |
+
}
|
| 1500 |
+
|
| 1501 |
+
/* -------------------------------------------------------------------------
|
| 1502 |
+
* Theme Overrides - Avada
|
| 1503 |
+
* ------------------------------------------------------------------------- */
|
| 1504 |
+
|
| 1505 |
+
/* -------------------------------------------------------------------------
|
| 1506 |
+
* Heading: h1
|
| 1507 |
+
* ------------------------------------------------------------------------- */
|
| 1508 |
+
|
| 1509 |
+
.tribe-theme-avada #main .tribe-common .tribe-common-h1 {
|
| 1510 |
+
color: #141827;
|
| 1511 |
+
font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
|
| 1512 |
+
font-weight: 700;
|
| 1513 |
+
font-size: 28px;
|
| 1514 |
+
line-height: 1.42;
|
| 1515 |
+
}
|
| 1516 |
+
|
| 1517 |
+
/* -------------------------------------------------------------------------
|
| 1518 |
+
* Heading: h2
|
| 1519 |
+
* ------------------------------------------------------------------------- */
|
| 1520 |
+
|
| 1521 |
+
.tribe-theme-avada #main .tribe-common .tribe-common-h2 {
|
| 1522 |
+
color: #141827;
|
| 1523 |
+
font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
|
| 1524 |
+
font-weight: 700;
|
| 1525 |
+
font-size: 24px;
|
| 1526 |
+
line-height: 1.42;
|
| 1527 |
+
}
|
| 1528 |
+
|
| 1529 |
+
/* -------------------------------------------------------------------------
|
| 1530 |
+
* Heading: h3
|
| 1531 |
+
* ------------------------------------------------------------------------- */
|
| 1532 |
+
|
| 1533 |
+
.tribe-theme-avada #main .tribe-common .tribe-common-h3 {
|
| 1534 |
+
color: #141827;
|
| 1535 |
+
font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
|
| 1536 |
+
font-weight: 700;
|
| 1537 |
+
font-size: 22px;
|
| 1538 |
+
line-height: 1.5;
|
| 1539 |
+
}
|
| 1540 |
+
|
| 1541 |
+
/* -------------------------------------------------------------------------
|
| 1542 |
+
* Heading: h4
|
| 1543 |
+
* ------------------------------------------------------------------------- */
|
| 1544 |
+
|
| 1545 |
+
.tribe-theme-avada #main .tribe-common .tribe-common-h4 {
|
| 1546 |
+
color: #141827;
|
| 1547 |
+
font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
|
| 1548 |
+
font-weight: 700;
|
| 1549 |
+
font-size: 20px;
|
| 1550 |
+
line-height: 1.42;
|
| 1551 |
+
}
|
| 1552 |
+
|
| 1553 |
+
/* -------------------------------------------------------------------------
|
| 1554 |
+
* Heading: h5
|
| 1555 |
+
* ------------------------------------------------------------------------- */
|
| 1556 |
+
|
| 1557 |
+
.tribe-theme-avada #main .tribe-common .tribe-common-h5 {
|
| 1558 |
+
color: #141827;
|
| 1559 |
+
font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
|
| 1560 |
+
font-weight: 700;
|
| 1561 |
+
font-size: 18px;
|
| 1562 |
+
line-height: 1.5;
|
| 1563 |
+
}
|
| 1564 |
+
|
| 1565 |
+
/* -------------------------------------------------------------------------
|
| 1566 |
+
* Heading: h6
|
| 1567 |
+
* ------------------------------------------------------------------------- */
|
| 1568 |
+
|
| 1569 |
+
.tribe-theme-avada #main .tribe-common .tribe-common-h6 {
|
| 1570 |
+
color: #141827;
|
| 1571 |
+
font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
|
| 1572 |
+
font-weight: 700;
|
| 1573 |
+
font-size: 16px;
|
| 1574 |
+
line-height: 1.5;
|
| 1575 |
+
}
|
| 1576 |
+
|
| 1577 |
+
/* -------------------------------------------------------------------------
|
| 1578 |
+
* Heading: h7
|
| 1579 |
+
* ------------------------------------------------------------------------- */
|
| 1580 |
+
|
| 1581 |
+
.tribe-theme-avada #main .tribe-common .tribe-common-h7 {
|
| 1582 |
+
color: #141827;
|
| 1583 |
+
font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
|
| 1584 |
+
font-weight: 700;
|
| 1585 |
+
font-size: 14px;
|
| 1586 |
+
line-height: 1.62;
|
| 1587 |
+
}
|
| 1588 |
+
|
| 1589 |
+
/* -------------------------------------------------------------------------
|
| 1590 |
+
* Heading: h8
|
| 1591 |
+
* ------------------------------------------------------------------------- */
|
| 1592 |
+
|
| 1593 |
+
.tribe-theme-avada #main .tribe-common .tribe-common-h8 {
|
| 1594 |
+
color: #141827;
|
| 1595 |
+
font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
|
| 1596 |
+
font-weight: 700;
|
| 1597 |
+
font-size: 12px;
|
| 1598 |
+
line-height: 1.38;
|
| 1599 |
+
}
|
| 1600 |
+
|
| 1601 |
+
/* -------------------------------------------------------------------------
|
| 1602 |
+
* Heading: h3 for --viewport-medium
|
| 1603 |
+
* ------------------------------------------------------------------------- */
|
| 1604 |
+
|
| 1605 |
+
/* -------------------------------------------------------------------------
|
| 1606 |
+
* Heading: h4 for --viewport-medium
|
| 1607 |
+
* ------------------------------------------------------------------------- */
|
| 1608 |
+
|
| 1609 |
+
/* -------------------------------------------------------------------------
|
| 1610 |
+
* Heading: h5 for --viewport-medium
|
| 1611 |
+
* ------------------------------------------------------------------------- */
|
| 1612 |
+
|
| 1613 |
+
/* -------------------------------------------------------------------------
|
| 1614 |
+
* Heading: h6 for --viewport-medium
|
| 1615 |
+
* ------------------------------------------------------------------------- */
|
| 1616 |
+
|
| 1617 |
+
/* -------------------------------------------------------------------------
|
| 1618 |
+
* Heading: h7 for --viewport-medium
|
| 1619 |
+
* ------------------------------------------------------------------------- */
|
| 1620 |
+
|
| 1621 |
+
/* -------------------------------------------------------------------------
|
| 1622 |
+
* Heading: alt style
|
| 1623 |
+
* ------------------------------------------------------------------------- */
|
| 1624 |
+
|
| 1625 |
+
.tribe-theme-avada #main .tribe-common .tribe-common-h--alt {
|
| 1626 |
+
font-weight: 400;
|
| 1627 |
+
}
|
| 1628 |
+
|
| 1629 |
+
.tribe-common {
|
| 1630 |
+
/* -------------------------------------------------------------------------
|
| 1631 |
+
* Lists
|
| 1632 |
+
* ------------------------------------------------------------------------- */
|
| 1633 |
+
|
| 1634 |
+
/* -----------------------------------------------------------------------------
|
| 1635 |
+
*
|
| 1636 |
+
* Lists: Theme Overrides
|
| 1637 |
+
*
|
| 1638 |
+
* ----------------------------------------------------------------------------- */
|
| 1639 |
+
}
|
| 1640 |
+
|
| 1641 |
+
/* -------------------------------------------------------------------------
|
| 1642 |
+
* Theme Overrides - Divi
|
| 1643 |
+
* ------------------------------------------------------------------------- */
|
| 1644 |
+
|
| 1645 |
+
.tribe-theme-divi #left-area .tribe-common ul,
|
| 1646 |
+
.tribe-theme-divi .entry-content .tribe-common ul,
|
| 1647 |
+
body.et-pb-preview.tribe-theme-divi #main-content .container .tribe-common ul {
|
| 1648 |
+
list-style-type: none;
|
| 1649 |
+
padding: 0;
|
| 1650 |
+
}
|
| 1651 |
+
|
| 1652 |
+
/* -------------------------------------------------------------------------
|
| 1653 |
+
* Button
|
| 1654 |
+
* ------------------------------------------------------------------------- */
|
| 1655 |
+
|
| 1656 |
+
.tribe-common button {
|
| 1657 |
+
background-color: transparent;
|
| 1658 |
+
border: none;
|
| 1659 |
+
padding: 0;
|
| 1660 |
+
}
|
| 1661 |
+
|
| 1662 |
+
.tribe-common button:hover,
|
| 1663 |
+
.tribe-common button:focus {
|
| 1664 |
+
background-color: transparent;
|
| 1665 |
+
}
|
| 1666 |
+
|
| 1667 |
+
/* -----------------------------------------------------------------------------
|
| 1668 |
+
*
|
| 1669 |
+
* Layout: Global Content Container
|
| 1670 |
+
*
|
| 1671 |
+
* ----------------------------------------------------------------------------- */
|
| 1672 |
+
|
| 1673 |
+
.tribe-common .tribe-common-l-container {
|
| 1674 |
+
max-width: 1260px;
|
| 1675 |
+
margin-left: auto;
|
| 1676 |
+
margin-right: auto;
|
| 1677 |
+
padding-left: 19.5px;
|
| 1678 |
+
padding-right: 19.5px;
|
| 1679 |
+
width: 100%;
|
| 1680 |
+
}
|
| 1681 |
+
|
| 1682 |
+
/* -------------------------------------------------------------------------
|
| 1683 |
+
* SVG Icons
|
| 1684 |
+
* ------------------------------------------------------------------------- */
|
| 1685 |
+
|
| 1686 |
+
.tribe-common .tribe-common-svgicon {
|
| 1687 |
+
background-repeat: no-repeat;
|
| 1688 |
+
background-size: contain;
|
| 1689 |
+
}
|
| 1690 |
+
|
| 1691 |
+
.tribe-common .tribe-common-svgicon--day {
|
| 1692 |
+
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='21' height='21' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 .503v19.994c0 .278.19.503.424.503h20.152c.234 0 .424-.225.424-.503V.503C21 .225 20.81 0 20.576 0H.424C.19 0 0 .225 0 .503zm1.156.943h18.66v2.7H1.157v-2.7zm0 4.023h18.66V19.55H1.157V5.469zM14.18 14.53v1.747c0 .482.39.874.873.874h1.747a.873.873 0 0 0 .873-.874v-1.747a.873.873 0 0 0-.873-.873h-1.747a.873.873 0 0 0-.873.873z' fill='%23141827' fill-rule='nonzero'/%3E%3C/svg%3E");
|
| 1693 |
+
}
|
| 1694 |
+
|
| 1695 |
+
.tribe-common .tribe-common-svgicon--list {
|
| 1696 |
+
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='21' height='18' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='%23141827' fill-rule='nonzero'%3E%3Cpath d='M19.883 3.272c.342 0 .622-.21.622-.467v-.464c0-.257-.28-.467-.622-.467H7.127c-.342 0-.622.21-.622.467v.464c0 .257.28.467.622.467h12.756zM1.838 4.207a1.75 1.75 0 1 0 0-3.5 1.75 1.75 0 0 0 0 3.5zM19.883 9.98c.342 0 .622-.21.622-.466v-.465c0-.257-.28-.467-.622-.467H7.127c-.342 0-.622.21-.622.467v.465c0 .256.28.466.622.466h12.756zM1.838 10.916a1.75 1.75 0 1 0 0-3.5 1.75 1.75 0 0 0 0 3.5z' fill='%23141827'/%3E%3Cg%3E%3Cpath d='M19.883 16.689c.342 0 .622-.21.622-.467v-.465c0-.256-.28-.466-.622-.466H7.127c-.342 0-.622.21-.622.466v.465c0 .257.28.467.622.467h12.756zM1.838 17.624a1.75 1.75 0 1 0 0-3.5 1.75 1.75 0 0 0 0 3.5z' fill='%23141827'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E");
|
| 1697 |
+
}
|
| 1698 |
+
|
| 1699 |
+
.tribe-common .tribe-common-svgicon--map {
|
| 1700 |
+
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='22' height='21' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cpath stroke='%23141827' stroke-linejoin='round' d='M13.921 11.632H17.5l3.588 8.421H1l3.488-8.421h4.016'/%3E%3Cpath d='M11.32 15.506c.2-.248 4.93-6.108 4.93-9.04 0-3.015-2.305-5.468-5.138-5.468-2.833 0-5.138 2.453-5.138 5.467 0 2.933 4.729 8.793 4.93 9.041a.268.268 0 0 0 .208.101c.08 0 .155-.037.207-.101zm-4.797-9.04c0-2.693 2.058-4.883 4.589-4.883 2.53 0 4.588 2.19 4.588 4.882 0 2.387-3.667 7.22-4.588 8.397-.922-1.177-4.589-6.009-4.589-8.397z' stroke='%23141827' stroke-width='.4' fill='%23141827' fill-rule='nonzero'/%3E%3Cpath d='M12.85 6.477c0-1.007-.78-1.826-1.738-1.826-.96 0-1.74.819-1.74 1.826 0 1.007.78 1.826 1.74 1.826.959 0 1.739-.82 1.739-1.826zm-3.15 0c0-.817.633-1.482 1.412-1.482.778 0 1.41.665 1.41 1.482s-.632 1.482-1.41 1.482c-.779 0-1.412-.665-1.412-1.482z' stroke='%23141827' stroke-width='.7' fill='%23000' fill-rule='nonzero'/%3E%3C/g%3E%3C/svg%3E");
|
| 1701 |
+
}
|
| 1702 |
+
|
| 1703 |
+
.tribe-common .tribe-common-svgicon--month {
|
| 1704 |
+
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='22' height='22' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M.637 1.063v19.879c0 .276.189.5.422.5h20.037c.232 0 .421-.224.421-.5V1.062c0-.275-.189-.5-.421-.5H1.059c-.233 0-.422.225-.422.5zM1.787 2H20.34v2.685H1.787V2zm0 4H20.34v14H1.787V6zM8 8.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5zm4 0v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5zm4 0v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5zm-8 4v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5zm4 0v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5zm4 0v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5zm-12 0v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5zm0 4v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5zm4 0v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5zm4 0v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5z' fill='%23141827' fill-rule='nonzero'/%3E%3C/svg%3E");
|
| 1705 |
+
}
|
| 1706 |
+
|
| 1707 |
+
.tribe-common .tribe-common-svgicon--photo {
|
| 1708 |
+
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='20' height='17' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='%23141827' fill-rule='nonzero'%3E%3Cpath d='M19.348.11H.634a.509.509 0 0 0-.52.508v15.017c0 .284.23.508.52.508h18.714c.29 0 .52-.224.52-.508V.618a.509.509 0 0 0-.52-.508zm-.54 1.035v10.837l-2.87-3.084c-.583-.61-1.664-.61-2.246 0l-1.393 1.481-4.034-4.525a1.625 1.625 0 0 0-1.227-.528 1.6 1.6 0 0 0-1.206.548l-4.657 5.175V1.145h17.632zM1.174 15.108v-2.496l5.448-6.089a.529.529 0 0 1 .415-.182c.146 0 .333.06.437.182l4.429 4.972c.104.102.25.183.395.183.166.02.291-.06.395-.162l1.788-1.908c.167-.183.5-.183.686 0l3.66 3.917v1.603H1.175v-.02z' fill='%23141827'/%3E%3Cpath d='M14.19 5.757c1.044 0 1.91-.872 1.91-1.968s-.846-1.969-1.91-1.969c-1.062 0-1.909.873-1.909 1.969s.866 1.968 1.91 1.968zm0-2.902c.493 0 .907.427.907.934 0 .507-.414.933-.906.933-.492 0-.906-.426-.906-.933 0-.507.414-.934.906-.934z' fill='%23141827'/%3E%3C/g%3E%3C/svg%3E");
|
| 1709 |
+
}
|
| 1710 |
+
|
| 1711 |
+
.tribe-common .tribe-common-svgicon--week {
|
| 1712 |
+
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='21' height='21' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 .503v19.994c0 .278.19.503.424.503h20.152c.234 0 .424-.225.424-.503V.503C21 .225 20.81 0 20.576 0H.424C.19 0 0 .225 0 .503zm1.156.943h18.66v2.7H1.157v-2.7zm0 4.023h18.66V19.55H1.157V5.469zm6.25 6.537v1.006c0 .278.224.503.502.503h1.006a.503.503 0 0 0 .503-.503v-1.006a.503.503 0 0 0-.503-.502H7.908a.503.503 0 0 0-.503.502zm4.022 0v1.006c0 .278.225.503.503.503h1.006a.503.503 0 0 0 .503-.503v-1.006a.503.503 0 0 0-.503-.502H11.93a.503.503 0 0 0-.503.502zm4.023 0v1.006c0 .278.225.503.503.503h1.006a.503.503 0 0 0 .503-.503v-1.006a.503.503 0 0 0-.503-.502h-1.006a.503.503 0 0 0-.503.502zm-12.069 0v1.006c0 .278.225.503.503.503h1.006a.503.503 0 0 0 .503-.503v-1.006a.503.503 0 0 0-.503-.502H3.885a.503.503 0 0 0-.503.502z' fill='%23141827' fill-rule='nonzero'/%3E%3C/svg%3E");
|
| 1713 |
+
}
|
| 1714 |
+
|
| 1715 |
+
.tribe-common .tribe-common-svgicon--featured {
|
| 1716 |
+
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='16' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 0h16v20l-7.902-5.122L0 20z' fill='%23334AFF'/%3E%3C/svg%3E");
|
| 1717 |
+
height: 10px;
|
| 1718 |
+
width: 8px;
|
| 1719 |
+
}
|
| 1720 |
+
|
| 1721 |
+
.tribe-common .tribe-common-svgicon--recurring {
|
| 1722 |
+
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='20' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M13.333 3.826c0 .065 0 .13-.02.174 0 .022-.02.065-.02.087a.9.9 0 0 1-.197.37L10.45 7.37a.797.797 0 0 1-.592.26.797.797 0 0 1-.593-.26c-.316-.348-.316-.935 0-1.305l1.225-1.348H6.3C3.753 4.717 1.66 7 1.66 9.827c0 1.369.474 2.651 1.363 3.608.316.348.316.935 0 1.304A.797.797 0 0 1 2.43 15a.797.797 0 0 1-.593-.26C.652 13.434 0 11.695 0 9.847c0-3.826 2.825-6.935 6.301-6.935h4.208L9.284 1.565c-.316-.348-.316-.935 0-1.304.316-.348.85-.348 1.185 0l2.647 2.913c.099.109.158.239.198.37 0 .021.02.065.02.086v.196zM20 10.152c0 3.826-2.825 6.935-6.301 6.935H9.49l1.225 1.348c.336.348.336.935 0 1.304a.797.797 0 0 1-.593.261.83.83 0 0 1-.592-.26l-2.627-2.936a.948.948 0 0 1-.198-.37c0-.021-.02-.064-.02-.086-.02-.065-.02-.109-.02-.174 0-.065 0-.13.02-.174 0-.022.02-.065.02-.087a.9.9 0 0 1 .198-.37L9.55 12.63c.316-.347.849-.347 1.185 0 .336.348.336.935 0 1.305L9.51 15.283h4.208c2.548 0 4.641-2.283 4.641-5.11 0-1.369-.474-2.651-1.362-3.608a.97.97 0 0 1 0-1.304c.316-.348.849-.348 1.185 0C19.348 6.543 20 8.283 20 10.152z' fill='%23334AFF'/%3E%3C/svg%3E");
|
| 1723 |
+
height: 10px;
|
| 1724 |
+
width: 10px;
|
| 1725 |
+
}
|
| 1726 |
+
|
| 1727 |
+
.tribe-common .tribe-common-svgicon--search {
|
| 1728 |
+
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='20' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M20 18.711l-6.044-6.044a7.782 7.782 0 0 0 1.688-4.845c0-2.089-.822-4.044-2.288-5.533C11.866.822 9.91 0 7.822 0S3.778.822 2.29 2.289A7.801 7.801 0 0 0 0 7.822c0 2.09.822 4.045 2.289 5.534a7.801 7.801 0 0 0 5.533 2.288c1.778 0 3.467-.6 4.845-1.688L18.71 20 20 18.711zM3.578 12.067c-2.334-2.334-2.334-6.156 0-8.49a5.968 5.968 0 0 1 4.244-1.755c1.6 0 3.111.622 4.245 1.756 2.333 2.333 2.333 6.155 0 8.489a5.968 5.968 0 0 1-4.245 1.755c-1.6 0-3.11-.622-4.244-1.755z' fill='%23727272'/%3E%3C/svg%3E");
|
| 1729 |
+
}
|
| 1730 |
+
|
| 1731 |
+
.tribe-common .tribe-common-svgicon--filters {
|
| 1732 |
+
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='17' height='17'%3E%3Cg fill='none' fill-rule='evenodd' stroke='%23727272' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' transform='translate(1 1)'%3E%3Cpath d='M3 3V0M3 15v-2' stroke='%23727272'/%3E%3Ccircle cx='3' cy='9' r='3' stroke='%23727272'/%3E%3Cpath d='M12 9v6' stroke='%23727272'/%3E%3Ccircle cx='12' cy='3' r='3' transform='matrix(1 0 0 -1 0 6)' stroke='%23727272'/%3E%3C/g%3E%3C/svg%3E");
|
| 1733 |
+
}
|
| 1734 |
+
|
| 1735 |
+
.tribe-common {
|
| 1736 |
+
/* -----------------------------------------------------------------------------
|
| 1737 |
+
*
|
| 1738 |
+
* Tables
|
| 1739 |
+
*
|
| 1740 |
+
* ----------------------------------------------------------------------------- */
|
| 1741 |
+
|
| 1742 |
+
/* -----------------------------------------------------------------------------
|
| 1743 |
+
* Tables: Theme Overrides
|
| 1744 |
+
* ----------------------------------------------------------------------------- */
|
| 1745 |
+
}
|
| 1746 |
+
|
| 1747 |
+
/* -----------------------------------------------------------------------------
|
| 1748 |
+
* Theme Overrides - Enfold
|
| 1749 |
+
* ----------------------------------------------------------------------------- */
|
| 1750 |
+
|
| 1751 |
+
.tribe-theme-enfold .tribe-common th {
|
| 1752 |
+
letter-spacing: 0;
|
| 1753 |
+
text-transform: none;
|
| 1754 |
+
}
|
| 1755 |
+
|
| 1756 |
+
/* A11y */
|
| 1757 |
+
|
| 1758 |
+
/* -----------------------------------------------------------------------------
|
| 1759 |
+
*
|
| 1760 |
+
* A11y
|
| 1761 |
+
*
|
| 1762 |
+
* This file is just a clearing-house.
|
| 1763 |
+
* Make partials (start with an underscore) for any actual css code.
|
| 1764 |
+
*
|
| 1765 |
+
* ----------------------------------------------------------------------------- */
|
| 1766 |
+
|
| 1767 |
+
/* -----------------------------------------------------------------------------
|
| 1768 |
+
* Hide from screenreaders & browsers
|
| 1769 |
+
* ----------------------------------------------------------------------------- */
|
| 1770 |
+
|
| 1771 |
+
.tribe-common .tribe-common-a11y-hidden {
|
| 1772 |
+
display: none !important;
|
| 1773 |
+
visibility: hidden;
|
| 1774 |
+
}
|
| 1775 |
+
|
| 1776 |
+
/* -----------------------------------------------------------------------------
|
| 1777 |
+
* Hide from browsers & show for screenreaders
|
| 1778 |
+
* ----------------------------------------------------------------------------- */
|
| 1779 |
+
|
| 1780 |
+
.tribe-common .tribe-common-a11y-visual-hide {
|
| 1781 |
+
border: 0;
|
| 1782 |
+
clip: rect(0 0 0 0);
|
| 1783 |
+
height: 1px;
|
| 1784 |
+
margin: -1px;
|
| 1785 |
+
overflow: hidden;
|
| 1786 |
+
padding: 0;
|
| 1787 |
+
position: absolute;
|
| 1788 |
+
width: 1px;
|
| 1789 |
+
}
|
| 1790 |
+
|
| 1791 |
+
/* -----------------------------------------------------------------------------
|
| 1792 |
+
* Show for browsers & screenreaders
|
| 1793 |
+
* ----------------------------------------------------------------------------- */
|
| 1794 |
+
|
| 1795 |
+
.tribe-common .tribe-common-a11y-visual-show {
|
| 1796 |
+
border: 0;
|
| 1797 |
+
clip: rect(0 0 0 0);
|
| 1798 |
+
height: 1px;
|
| 1799 |
+
margin: -1px;
|
| 1800 |
+
overflow: hidden;
|
| 1801 |
+
padding: 0;
|
| 1802 |
+
position: absolute;
|
| 1803 |
+
width: 1px;
|
| 1804 |
+
}
|
| 1805 |
+
|
| 1806 |
+
/* Components */
|
| 1807 |
+
|
| 1808 |
+
/* -----------------------------------------------------------------------------
|
| 1809 |
+
*
|
| 1810 |
+
* Components
|
| 1811 |
+
*
|
| 1812 |
+
* This file is just a clearing-house.
|
| 1813 |
+
* Make partials (start with an underscore) for any actual css code.
|
| 1814 |
+
*
|
| 1815 |
+
* ----------------------------------------------------------------------------- */
|
| 1816 |
+
|
| 1817 |
+
/* Buttons */
|
| 1818 |
+
|
| 1819 |
+
/* -----------------------------------------------------------------------------
|
| 1820 |
+
*
|
| 1821 |
+
* Button: Border
|
| 1822 |
+
*
|
| 1823 |
+
* Example:
|
| 1824 |
+
* <button class="tribe-common-c-btn-border">...</button>
|
| 1825 |
+
* <a href="#" class="tribe-common-c-btn-border">...</a>
|
| 1826 |
+
*
|
| 1827 |
+
* ----------------------------------------------------------------------------- */
|
| 1828 |
+
|
| 1829 |
+
.tribe-common .tribe-common-c-btn-border,
|
| 1830 |
+
.tribe-common a.tribe-common-c-btn-border {
|
| 1831 |
+
color: #141827;
|
| 1832 |
+
font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
|
| 1833 |
+
font-size: 12px;
|
| 1834 |
+
line-height: 1.38;
|
| 1835 |
+
font-weight: 400;
|
| 1836 |
+
border: 0;
|
| 1837 |
+
cursor: pointer;
|
| 1838 |
+
display: inline-block;
|
| 1839 |
+
height: auto;
|
| 1840 |
+
padding: 0;
|
| 1841 |
+
text-decoration: none;
|
| 1842 |
+
width: auto;
|
| 1843 |
+
background-color: #FFFFFF;
|
| 1844 |
+
border: 1px solid #D5D5D5;
|
| 1845 |
+
border-radius: 4px;
|
| 1846 |
+
text-align: center;
|
| 1847 |
+
transition: color 0.2s ease, border-color 0.2s ease;
|
| 1848 |
+
|
| 1849 |
+
color: #727272;
|
| 1850 |
+
padding: 14px 20px 14px;
|
| 1851 |
+
width: 100%;
|
| 1852 |
+
}
|
| 1853 |
+
|
| 1854 |
+
.tribe-common .tribe-common-c-btn-border:hover,
|
| 1855 |
+
.tribe-common .tribe-common-c-btn-border:focus,
|
| 1856 |
+
.tribe-common a.tribe-common-c-btn-border:hover,
|
| 1857 |
+
.tribe-common a.tribe-common-c-btn-border:focus {
|
| 1858 |
+
background-color: #FFFFFF;
|
| 1859 |
+
}
|
| 1860 |
+
|
| 1861 |
+
.tribe-common .tribe-common-c-btn-border:active, .tribe-common a.tribe-common-c-btn-border:active {
|
| 1862 |
+
border-color: #141827;
|
| 1863 |
+
}
|
| 1864 |
+
|
| 1865 |
+
.tribe-common .tribe-common-c-btn-border:active,
|
| 1866 |
+
.tribe-common .tribe-common-c-btn-border:focus,
|
| 1867 |
+
.tribe-common .tribe-common-c-btn-border:hover,
|
| 1868 |
+
.tribe-common a.tribe-common-c-btn-border:active,
|
| 1869 |
+
.tribe-common a.tribe-common-c-btn-border:focus,
|
| 1870 |
+
.tribe-common a.tribe-common-c-btn-border:hover {
|
| 1871 |
+
color: #141827;
|
| 1872 |
+
}
|
| 1873 |
+
|
| 1874 |
+
.tribe-common .tribe-common-c-btn-border:disabled, .tribe-common a.tribe-common-c-btn-border:disabled {
|
| 1875 |
+
color: #D5D5D5
|
| 1876 |
+
}
|
| 1877 |
+
|
| 1878 |
+
/* -----------------------------------------------------------------------------
|
| 1879 |
+
*
|
| 1880 |
+
* Button: Icon
|
| 1881 |
+
*
|
| 1882 |
+
* Example:
|
| 1883 |
+
* <button class="tribe-common-c-btn-icon tribe-common-c-btn-icon--filter">...</button>
|
| 1884 |
+
* <a href="#" class="tribe-common-c-btn-icon tribe-common-c-btn-icon--filter">...</a>
|
| 1885 |
+
*
|
| 1886 |
+
* ----------------------------------------------------------------------------- */
|
| 1887 |
+
|
| 1888 |
+
.tribe-common .tribe-common-c-btn-icon {
|
| 1889 |
+
border: 0;
|
| 1890 |
+
cursor: pointer;
|
| 1891 |
+
display: inline-block;
|
| 1892 |
+
height: auto;
|
| 1893 |
+
padding: 0;
|
| 1894 |
+
text-decoration: none;
|
| 1895 |
+
width: auto;
|
| 1896 |
+
}
|
| 1897 |
+
|
| 1898 |
+
.tribe-common .tribe-common-c-btn-icon:before {
|
| 1899 |
+
background-repeat: no-repeat;
|
| 1900 |
+
background-size: contain;
|
| 1901 |
+
content: '';
|
| 1902 |
+
display: block;
|
| 1903 |
+
}
|
| 1904 |
+
|
| 1905 |
+
/* -----------------------------------------------------------------------------
|
| 1906 |
+
*
|
| 1907 |
+
* Button: Icon Border
|
| 1908 |
+
*
|
| 1909 |
+
* Example:
|
| 1910 |
+
* <button class="tribe-common-c-btn-icon tribe-common-c-btn-icon--border tribe-common-c-btn-icon--filter">...</button>
|
| 1911 |
+
* <a href="#" class="tribe-common-c-btn-icon tribe-common-c-btn-icon--border tribe-common-c-btn-icon--filter">...</a>
|
| 1912 |
+
*
|
| 1913 |
+
* ----------------------------------------------------------------------------- */
|
| 1914 |
+
|
| 1915 |
+
.tribe-common .tribe-common-c-btn-icon--border {
|
| 1916 |
+
background-color: #FFFFFF;
|
| 1917 |
+
border: 1px solid #D5D5D5;
|
| 1918 |
+
align-items: center;
|
| 1919 |
+
display: inline-flex;
|
| 1920 |
+
height: 56px;
|
| 1921 |
+
justify-content: center;
|
| 1922 |
+
transition: none;
|
| 1923 |
+
width: 56px;
|
| 1924 |
+
}
|
| 1925 |
+
|
| 1926 |
+
.tribe-common .tribe-common-c-btn-icon--border:hover,
|
| 1927 |
+
.tribe-common .tribe-common-c-btn-icon--border:focus {
|
| 1928 |
+
background-color: #FFFFFF;
|
| 1929 |
+
}
|
| 1930 |
+
|
| 1931 |
+
.tribe-common .tribe-common-c-btn-icon--border:active {
|
| 1932 |
+
border-color: #141827;
|
| 1933 |
+
}
|
| 1934 |
+
|
| 1935 |
+
/* -----------------------------------------------------------------------------
|
| 1936 |
+
* Button: Icon Caret Left
|
| 1937 |
+
* ----------------------------------------------------------------------------- */
|
| 1938 |
+
|
| 1939 |
+
.tribe-common .tribe-common-c-btn-icon--caret-left:before {
|
| 1940 |
+
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='12' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11.916 17.841L10 19.757l-9.9-9.9L10-.041l1.916 1.916-7.983 7.984z' fill='%23BABABA'/%3E%3C/svg%3E");
|
| 1941 |
+
height: 20px;
|
| 1942 |
+
width: 12px;
|
| 1943 |
+
}
|
| 1944 |
+
|
| 1945 |
+
.tribe-common .tribe-common-c-btn-icon--caret-left:active:before, .tribe-common .tribe-common-c-btn-icon--caret-left:hover:before, .tribe-common .tribe-common-c-btn-icon--caret-left:focus:before {
|
| 1946 |
+
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='12' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11.916 17.841L10 19.757l-9.9-9.9L10-.041l1.916 1.916-7.983 7.984z' fill='%23727272'/%3E%3C/svg%3E");
|
| 1947 |
+
}
|
| 1948 |
+
|
| 1949 |
+
.tribe-common .tribe-common-c-btn-icon--caret-left:disabled:before {
|
| 1950 |
+
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='12' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11.916 17.841L10 19.757l-9.9-9.9L10-.041l1.916 1.916-7.983 7.984z' fill='%23D5D5D5'/%3E%3C/svg%3E");
|
| 1951 |
+
}
|
| 1952 |
+
|
| 1953 |
+
/* -----------------------------------------------------------------------------
|
| 1954 |
+
* Button: Icon Caret Right
|
| 1955 |
+
* ----------------------------------------------------------------------------- */
|
| 1956 |
+
|
| 1957 |
+
.tribe-common .tribe-common-c-btn-icon--caret-right:before {
|
| 1958 |
+
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='12' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M.084 2.159L2 .243l9.9 9.9L2 20.041.084 18.126l7.983-7.984z' fill='%23BABABA'/%3E%3C/svg%3E");
|
| 1959 |
+
height: 20px;
|
| 1960 |
+
width: 12px;
|
| 1961 |
+
}
|
| 1962 |
+
|
| 1963 |
+
.tribe-common .tribe-common-c-btn-icon--caret-right:active:before, .tribe-common .tribe-common-c-btn-icon--caret-right:hover:before, .tribe-common .tribe-common-c-btn-icon--caret-right:focus:before {
|
| 1964 |
+
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='12' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M.084 2.159L2 .243l9.9 9.9L2 20.041.084 18.126l7.983-7.984z' fill='%23727272'/%3E%3C/svg%3E");
|
| 1965 |
+
}
|
| 1966 |
+
|
| 1967 |
+
.tribe-common .tribe-common-c-btn-icon--caret-right:disabled:before {
|
| 1968 |
+
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='12' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M.084 2.159L2 .243l9.9 9.9L2 20.041.084 18.126l7.983-7.984z' fill='%23D5D5D5'/%3E%3C/svg%3E");
|
| 1969 |
+
}
|
| 1970 |
+
|
| 1971 |
+
/* -----------------------------------------------------------------------------
|
| 1972 |
+
* Button: Icon Filters
|
| 1973 |
+
* ----------------------------------------------------------------------------- */
|
| 1974 |
+
|
| 1975 |
+
.tribe-common .tribe-common-c-btn-icon--filters:before {
|
| 1976 |
+
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='17' height='17'%3E%3Cg fill='none' fill-rule='evenodd' stroke='%23727272' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' transform='translate(1 1)'%3E%3Cpath d='M3 3V0M3 15v-2' stroke='%23727272'/%3E%3Ccircle cx='3' cy='9' r='3' stroke='%23727272'/%3E%3Cpath d='M12 9v6' stroke='%23727272'/%3E%3Ccircle cx='12' cy='3' r='3' transform='matrix(1 0 0 -1 0 6)' stroke='%23727272'/%3E%3C/g%3E%3C/svg%3E");
|
| 1977 |
+
height: 20px;
|
| 1978 |
+
width: 24px;
|
| 1979 |
+
}
|
| 1980 |
+
|
| 1981 |
+
.tribe-common .tribe-common-c-btn-icon--filters:active:before, .tribe-common .tribe-common-c-btn-icon--filters:hover:before, .tribe-common .tribe-common-c-btn-icon--filters:focus:before {
|
| 1982 |
+
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='17' height='17'%3E%3Cg fill='none' fill-rule='evenodd' stroke='%23727272' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' transform='translate(1 1)'%3E%3Cpath d='M3 3V0M3 15v-2' stroke='%23141827'/%3E%3Ccircle cx='3' cy='9' r='3' stroke='%23141827'/%3E%3Cpath d='M12 9v6' stroke='%23141827'/%3E%3Ccircle cx='12' cy='3' r='3' transform='matrix(1 0 0 -1 0 6)' stroke='%23141827'/%3E%3C/g%3E%3C/svg%3E");
|
| 1983 |
+
}
|
| 1984 |
+
|
| 1985 |
+
.tribe-common .tribe-common-c-btn-icon--filters:disabled:before {
|
| 1986 |
+
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='17' height='17'%3E%3Cg fill='none' fill-rule='evenodd' stroke='%23727272' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' transform='translate(1 1)'%3E%3Cpath d='M3 3V0M3 15v-2' stroke='%23D5D5D5'/%3E%3Ccircle cx='3' cy='9' r='3' stroke='%23D5D5D5'/%3E%3Cpath d='M12 9v6' stroke='%23D5D5D5'/%3E%3Ccircle cx='12' cy='3' r='3' transform='matrix(1 0 0 -1 0 6)' stroke='%23D5D5D5'/%3E%3C/g%3E%3C/svg%3E");
|
| 1987 |
+
}
|
| 1988 |
+
|
| 1989 |
+
/* -----------------------------------------------------------------------------
|
| 1990 |
+
* Button: Icon Search
|
| 1991 |
+
* ----------------------------------------------------------------------------- */
|
| 1992 |
+
|
| 1993 |
+
.tribe-common .tribe-common-c-btn-icon--search:before {
|
| 1994 |
+
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='20' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M20 18.711l-6.044-6.044a7.782 7.782 0 0 0 1.688-4.845c0-2.089-.822-4.044-2.288-5.533C11.866.822 9.91 0 7.822 0S3.778.822 2.29 2.289A7.801 7.801 0 0 0 0 7.822c0 2.09.822 4.045 2.289 5.534a7.801 7.801 0 0 0 5.533 2.288c1.778 0 3.467-.6 4.845-1.688L18.71 20 20 18.711zM3.578 12.067c-2.334-2.334-2.334-6.156 0-8.49a5.968 5.968 0 0 1 4.244-1.755c1.6 0 3.111.622 4.245 1.756 2.333 2.333 2.333 6.155 0 8.489a5.968 5.968 0 0 1-4.245 1.755c-1.6 0-3.11-.622-4.244-1.755z' fill='%23727272'/%3E%3C/svg%3E");
|
| 1995 |
+
height: 20px;
|
| 1996 |
+
width: 20px;
|
| 1997 |
+
}
|
| 1998 |
+
|
| 1999 |
+
.tribe-common .tribe-common-c-btn-icon--search:active:before, .tribe-common .tribe-common-c-btn-icon--search:hover:before, .tribe-common .tribe-common-c-btn-icon--search:focus:before {
|
| 2000 |
+
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='20' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M20 18.711l-6.044-6.044a7.782 7.782 0 0 0 1.688-4.845c0-2.089-.822-4.044-2.288-5.533C11.866.822 9.91 0 7.822 0S3.778.822 2.29 2.289A7.801 7.801 0 0 0 0 7.822c0 2.09.822 4.045 2.289 5.534a7.801 7.801 0 0 0 5.533 2.288c1.778 0 3.467-.6 4.845-1.688L18.71 20 20 18.711zM3.578 12.067c-2.334-2.334-2.334-6.156 0-8.49a5.968 5.968 0 0 1 4.244-1.755c1.6 0 3.111.622 4.245 1.756 2.333 2.333 2.333 6.155 0 8.489a5.968 5.968 0 0 1-4.245 1.755c-1.6 0-3.11-.622-4.244-1.755z' fill='%23141827'/%3E%3C/svg%3E");
|
| 2001 |
+
}
|
| 2002 |
+
|
| 2003 |
+
.tribe-common .tribe-common-c-btn-icon--search:disabled:before {
|
| 2004 |
+
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='20' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M20 18.711l-6.044-6.044a7.782 7.782 0 0 0 1.688-4.845c0-2.089-.822-4.044-2.288-5.533C11.866.822 9.91 0 7.822 0S3.778.822 2.29 2.289A7.801 7.801 0 0 0 0 7.822c0 2.09.822 4.045 2.289 5.534a7.801 7.801 0 0 0 5.533 2.288c1.778 0 3.467-.6 4.845-1.688L18.71 20 20 18.711zM3.578 12.067c-2.334-2.334-2.334-6.156 0-8.49a5.968 5.968 0 0 1 4.244-1.755c1.6 0 3.111.622 4.245 1.756 2.333 2.333 2.333 6.155 0 8.489a5.968 5.968 0 0 1-4.245 1.755c-1.6 0-3.11-.622-4.244-1.755z' fill='%23D5D5D5'/%3E%3C/svg%3E");
|
| 2005 |
+
}
|
| 2006 |
+
|
| 2007 |
+
/* -----------------------------------------------------------------------------
|
| 2008 |
+
*
|
| 2009 |
+
* Button: Solid
|
| 2010 |
+
*
|
| 2011 |
+
* Example:
|
| 2012 |
+
* <button class="tribe-common-c-btn">...</button>
|
| 2013 |
+
* <a href="#" class="tribe-common-c-btn">...</a>
|
| 2014 |
+
*
|
| 2015 |
+
* ----------------------------------------------------------------------------- */
|
| 2016 |
+
|
| 2017 |
+
.tribe-common .tribe-common-c-btn,
|
| 2018 |
+
.tribe-common a.tribe-common-c-btn {
|
| 2019 |
+
color: #141827;
|
| 2020 |
+
font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
|
| 2021 |
+
font-size: 14px;
|
| 2022 |
+
line-height: 1.62;
|
| 2023 |
+
font-weight: 400;
|
| 2024 |
+
font-weight: 700;
|
| 2025 |
+
border: 0;
|
| 2026 |
+
cursor: pointer;
|
| 2027 |
+
display: inline-block;
|
| 2028 |
+
height: auto;
|
| 2029 |
+
padding: 0;
|
| 2030 |
+
text-decoration: none;
|
| 2031 |
+
width: auto;
|
| 2032 |
+
border-radius: 4px;
|
| 2033 |
+
color: #FFFFFF;
|
| 2034 |
+
text-align: center;
|
| 2035 |
+
transition: background-color 0.2s ease;
|
| 2036 |
+
|
| 2037 |
+
background-color: #334AFF;
|
| 2038 |
+
padding: 11px 20px 11px;
|
| 2039 |
+
width: 100%;
|
| 2040 |
+
}
|
| 2041 |
+
|
| 2042 |
+
.tribe-common .tribe-common-c-btn:focus,
|
| 2043 |
+
.tribe-common .tribe-common-c-btn:hover,
|
| 2044 |
+
.tribe-common a.tribe-common-c-btn:focus,
|
| 2045 |
+
.tribe-common a.tribe-common-c-btn:hover {
|
| 2046 |
+
background-color: rgba(51,74,255, 0.8);
|
| 2047 |
+
}
|
| 2048 |
+
|
| 2049 |
+
.tribe-common .tribe-common-c-btn:active, .tribe-common a.tribe-common-c-btn:active {
|
| 2050 |
+
background-color: rgba(51,74,255, 0.9);
|
| 2051 |
+
}
|
| 2052 |
+
|
| 2053 |
+
.tribe-common .tribe-common-c-btn:disabled, .tribe-common a.tribe-common-c-btn:disabled {
|
| 2054 |
+
background-color: rgba(51,74,255, 0.07);
|
| 2055 |
+
}
|
| 2056 |
+
|
| 2057 |
+
/* -----------------------------------------------------------------------------
|
| 2058 |
+
*
|
| 2059 |
+
* Component: Image
|
| 2060 |
+
*
|
| 2061 |
+
* Example (Regular):
|
| 2062 |
+
* <img src="#" alt="" class="tribe-common-c-image" />
|
| 2063 |
+
*
|
| 2064 |
+
* Example (Background):
|
| 2065 |
+
* <div class="tribe-common-c-image tribe-common-c-image--bg">
|
| 2066 |
+
* <div class="tribe-common-c-image__bg"></div>
|
| 2067 |
+
* </div>
|
| 2068 |
+
*
|
| 2069 |
+
* ----------------------------------------------------------------------------- */
|
| 2070 |
+
|
| 2071 |
+
.tribe-common .tribe-common-c-image {
|
| 2072 |
+
display: block;
|
| 2073 |
+
height: auto;
|
| 2074 |
+
margin-left: auto;
|
| 2075 |
+
margin-right: auto;
|
| 2076 |
+
width: 100%;
|
| 2077 |
+
}
|
| 2078 |
+
|
| 2079 |
+
.tribe-common .tribe-common-c-image--bg {
|
| 2080 |
+
position: relative;
|
| 2081 |
+
}
|
| 2082 |
+
|
| 2083 |
+
.tribe-common .tribe-common-c-image__bg {
|
| 2084 |
+
background: center center no-repeat;
|
| 2085 |
+
background-size: cover;
|
| 2086 |
+
bottom: 0;
|
| 2087 |
+
height: 100%;
|
| 2088 |
+
left: 0;
|
| 2089 |
+
position: absolute;
|
| 2090 |
+
right: 0;
|
| 2091 |
+
top: 0;
|
| 2092 |
+
width: 100%;
|
| 2093 |
+
}
|
| 2094 |
+
|
| 2095 |
+
@media (min-width: 768px) {
|
| 2096 |
+
|
| 2097 |
+
.tribe-common .tribe-common-form-control-text__input {
|
| 2098 |
+
color: #141827;
|
| 2099 |
+
font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
|
| 2100 |
+
font-size: 14px;
|
| 2101 |
+
line-height: 1.62;
|
| 2102 |
+
font-weight: 400;
|
| 2103 |
+
|
| 2104 |
+
border: 0;
|
| 2105 |
+
padding: 20px 20px 20px 40px
|
| 2106 |
+
}
|
| 2107 |
+
|
| 2108 |
+
#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-text__input {
|
| 2109 |
+
color: #141827;
|
| 2110 |
+
font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
|
| 2111 |
+
font-size: 14px;
|
| 2112 |
+
line-height: 1.62;
|
| 2113 |
+
font-weight: 400;
|
| 2114 |
+
|
| 2115 |
+
border: 0;
|
| 2116 |
+
padding: 20px 20px 20px 40px
|
| 2117 |
+
}
|
| 2118 |
+
|
| 2119 |
+
.tribe-common .tribe-common-g-row--gutters {
|
| 2120 |
+
margin-left: -24px;
|
| 2121 |
+
margin-right: -24px
|
| 2122 |
+
}
|
| 2123 |
+
|
| 2124 |
+
.tribe-common .tribe-common-g-row--gutters > .tribe-common-g-col {
|
| 2125 |
+
padding-left: 24px;
|
| 2126 |
+
padding-right: 24px
|
| 2127 |
+
}
|
| 2128 |
+
|
| 2129 |
+
.tribe-common .tribe-common-b1 {
|
| 2130 |
+
font-size: 16px;
|
| 2131 |
+
line-height: 1.62
|
| 2132 |
+
}
|
| 2133 |
+
|
| 2134 |
+
.tribe-common .tribe-common-b2 {
|
| 2135 |
+
font-size: 14px;
|
| 2136 |
+
line-height: 1.62
|
| 2137 |
+
}
|
| 2138 |
+
|
| 2139 |
+
.tribe-common .tribe-common-b3 {
|
| 2140 |
+
font-size: 12px;
|
| 2141 |
+
line-height: 1.38
|
| 2142 |
+
}
|
| 2143 |
+
|
| 2144 |
+
.tribe-common .tribe-common-b1--min-medium {
|
| 2145 |
+
font-size: 16px;
|
| 2146 |
+
line-height: 1.62
|
| 2147 |
+
}
|
| 2148 |
+
|
| 2149 |
+
.tribe-common .tribe-common-h1 {
|
| 2150 |
+
font-size: 42px;
|
| 2151 |
+
line-height: 1.38
|
| 2152 |
+
}
|
| 2153 |
+
|
| 2154 |
+
.tribe-common .tribe-common-h2 {
|
| 2155 |
+
font-size: 32px;
|
| 2156 |
+
line-height: 1.38
|
| 2157 |
+
}
|
| 2158 |
+
|
| 2159 |
+
.tribe-common .tribe-common-h3 {
|
| 2160 |
+
font-size: 28px;
|
| 2161 |
+
line-height: 1.42
|
| 2162 |
+
}
|
| 2163 |
+
|
| 2164 |
+
.tribe-common .tribe-common-h4 {
|
| 2165 |
+
font-size: 24px;
|
| 2166 |
+
line-height: 1.42
|
| 2167 |
+
}
|
| 2168 |
+
|
| 2169 |
+
.tribe-common .tribe-common-h6 {
|
| 2170 |
+
font-size: 16px;
|
| 2171 |
+
line-height: 1.62
|
| 2172 |
+
}
|
| 2173 |
+
|
| 2174 |
+
.tribe-common .tribe-common-h3--min-medium {
|
| 2175 |
+
font-size: 28px;
|
| 2176 |
+
line-height: 1.42
|
| 2177 |
+
}
|
| 2178 |
+
|
| 2179 |
+
.tribe-common .tribe-common-h4--min-medium {
|
| 2180 |
+
font-size: 24px;
|
| 2181 |
+
line-height: 1.42
|
| 2182 |
+
}
|
| 2183 |
+
|
| 2184 |
+
.tribe-common .tribe-common-h5--min-medium {
|
| 2185 |
+
font-size: 18px;
|
| 2186 |
+
line-height: 1.5
|
| 2187 |
+
}
|
| 2188 |
+
|
| 2189 |
+
.tribe-common .tribe-common-h6--min-medium {
|
| 2190 |
+
font-size: 16px;
|
| 2191 |
+
line-height: 1.62
|
| 2192 |
+
}
|
| 2193 |
+
|
| 2194 |
+
.tribe-common .tribe-common-h7--min-medium {
|
| 2195 |
+
font-size: 14px;
|
| 2196 |
+
line-height: 1.62
|
| 2197 |
+
}
|
| 2198 |
+
|
| 2199 |
+
.tribe-theme-avada #main .tribe-common .tribe-common-h1 {
|
| 2200 |
+
font-size: 42px;
|
| 2201 |
+
line-height: 1.38
|
| 2202 |
+
}
|
| 2203 |
+
|
| 2204 |
+
.tribe-theme-avada #main .tribe-common .tribe-common-h2 {
|
| 2205 |
+
font-size: 32px;
|
| 2206 |
+
line-height: 1.38
|
| 2207 |
+
}
|
| 2208 |
+
|
| 2209 |
+
.tribe-theme-avada #main .tribe-common .tribe-common-h3 {
|
| 2210 |
+
font-size: 28px;
|
| 2211 |
+
line-height: 1.42
|
| 2212 |
+
}
|
| 2213 |
+
|
| 2214 |
+
.tribe-theme-avada #main .tribe-common .tribe-common-h4 {
|
| 2215 |
+
font-size: 24px;
|
| 2216 |
+
line-height: 1.42
|
| 2217 |
+
}
|
| 2218 |
+
|
| 2219 |
+
.tribe-theme-avada #main .tribe-common .tribe-common-h6 {
|
| 2220 |
+
font-size: 16px;
|
| 2221 |
+
line-height: 1.62
|
| 2222 |
+
}
|
| 2223 |
+
|
| 2224 |
+
.tribe-theme-avada #main .tribe-common .tribe-common-h3--min-medium {
|
| 2225 |
+
font-size: 28px;
|
| 2226 |
+
line-height: 1.42
|
| 2227 |
+
}
|
| 2228 |
+
|
| 2229 |
+
.tribe-theme-avada #main .tribe-common .tribe-common-h4--min-medium {
|
| 2230 |
+
font-size: 24px;
|
| 2231 |
+
line-height: 1.42
|
| 2232 |
+
}
|
| 2233 |
+
|
| 2234 |
+
.tribe-theme-avada #main .tribe-common .tribe-common-h5--min-medium {
|
| 2235 |
+
font-size: 18px;
|
| 2236 |
+
line-height: 1.5
|
| 2237 |
+
}
|
| 2238 |
+
|
| 2239 |
+
.tribe-theme-avada #main .tribe-common .tribe-common-h6--min-medium {
|
| 2240 |
+
font-size: 16px;
|
| 2241 |
+
line-height: 1.62
|
| 2242 |
+
}
|
| 2243 |
+
|
| 2244 |
+
.tribe-theme-avada #main .tribe-common .tribe-common-h7--min-medium {
|
| 2245 |
+
font-size: 14px;
|
| 2246 |
+
line-height: 1.62
|
| 2247 |
+
}
|
| 2248 |
+
|
| 2249 |
+
.tribe-common .tribe-common-l-container {
|
| 2250 |
+
padding-left: 42px;
|
| 2251 |
+
padding-right: 42px
|
| 2252 |
+
}
|
| 2253 |
+
|
| 2254 |
+
.tribe-common .tribe-common-c-btn-border,
|
| 2255 |
+
.tribe-common a.tribe-common-c-btn-border {
|
| 2256 |
+
padding: 6px 15px;
|
| 2257 |
+
width: auto
|
| 2258 |
+
}
|
| 2259 |
+
|
| 2260 |
+
.tribe-common .tribe-common-c-btn,
|
| 2261 |
+
.tribe-common a.tribe-common-c-btn {
|
| 2262 |
+
width: auto
|
| 2263 |
+
}
|
| 2264 |
+
}
|
common/src/resources/css/common.min.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
| 1 |
+
.tribe-common figure{line-height:0}.tribe-common figcaption{line-height:normal}.tribe-common a{background-color:transparent;-webkit-text-decoration-skip:objects}.tribe-common abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}.tribe-common code,.tribe-common kbd,.tribe-common pre,.tribe-common samp{font-family:monospace;font-size:1em}.tribe-common b,.tribe-common strong{font-weight:inherit;font-weight:bolder}.tribe-common dfn{font-style:italic}.tribe-common mark{background-color:#ff0;color:#000}.tribe-common small{font-size:80%}.tribe-common sub,.tribe-common sup{font-size:75%;line-height:0}.tribe-common hr{border:0;height:0}.tribe-common button,.tribe-common input[type=button],.tribe-common input[type=email],.tribe-common input[type=password],.tribe-common input[type=reset],.tribe-common input[type=search],.tribe-common input[type=submit],.tribe-common input[type=text],.tribe-common input[type=url],.tribe-common textarea{-webkit-appearance:none;-moz-appearance:none;appearance:none}.tribe-common button,.tribe-common input,.tribe-common optgroup,.tribe-common select,.tribe-common textarea{color:inherit;font:inherit;line-height:normal;-webkit-font-smoothing:antialiased}.tribe-common button,.tribe-common input,.tribe-common select,.tribe-common textarea{outline:0;border-radius:0}.tribe-common select:-moz-focusring{color:transparent;text-shadow:0 0 0 #000}.tribe-common optgroup{font-weight:700}.tribe-common ol,.tribe-common ul{list-style:none}.tribe-common h1,.tribe-common h2,.tribe-common h3,.tribe-common h4,.tribe-common h5,.tribe-common h6,.tribe-common p{font-weight:400;text-rendering:optimizeLegibility}.tribe-common .tribe-common-form-control-checkbox,.tribe-common .tribe-common-form-control-radio{line-height:0}.tribe-common .tribe-common-form-control-checkbox__label,.tribe-common .tribe-common-form-control-radio__label{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-size:14px;line-height:1.62;font-weight:400;color:#727272;cursor:pointer;display:inline-block;margin-left:11px;vertical-align:middle}.tribe-common .tribe-common-form-control-checkbox__input,.tribe-common .tribe-common-form-control-radio__input{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#fff;border:1px solid #141827;cursor:pointer;display:inline-block;height:20px;margin:0;position:relative;vertical-align:middle;width:20px}.tribe-common .tribe-common-form-control-checkbox__input:active,.tribe-common .tribe-common-form-control-checkbox__input:focus,.tribe-common .tribe-common-form-control-checkbox__input:hover,.tribe-common .tribe-common-form-control-radio__input:active,.tribe-common .tribe-common-form-control-radio__input:focus,.tribe-common .tribe-common-form-control-radio__input:hover{border:1px solid #141827}.tribe-common .tribe-common-form-control-checkbox__input:checked,.tribe-common .tribe-common-form-control-radio__input:checked{background-color:#141827}.tribe-common .tribe-common-form-control-checkbox__input:checked:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='12' height='9' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M10.6.1L3.9 6.8 1.4 4.3c-.1-.1-.3-.1-.4 0l-.8.8c-.1.1-.1.3 0 .4l3.4 3.4c.2.1.4.1.5 0l7.7-7.7c.1-.1.1-.3 0-.4L11 .1c-.1-.1-.3-.1-.4 0z' fill='%23FFF'/%3E%3C/svg%3E");background-repeat:no-repeat;background-size:contain;content:"";display:block;height:9px;left:50%;position:absolute;top:50%;transform:translate(-50%,-50%);width:12px}.tribe-common .tribe-common-form-control-radio__input{border-radius:50%}.tribe-common .tribe-common-form-control-radio__input:checked:before{background-color:#fff;border-radius:50%;content:"";display:block;height:8px;left:50%;position:absolute;top:50%;transform:translate(-50%,-50%);width:8px}#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-checkbox__input{display:inline-block}#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-checkbox__label,#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-radio__label{font-weight:400;font-size:14px}.tribe-common .tribe-common-form-control-checkbox-radio-group>*{margin-bottom:15px}.tribe-common .tribe-common-form-control-checkbox-radio-group>:last-child{margin-bottom:0}.tribe-common .tribe-common-form-control-slider{line-height:0}.tribe-common .tribe-common-form-control-slider__input{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:transparent;border:0;cursor:pointer;display:inline-block;margin:0;padding:0;width:120px;vertical-align:middle}.tribe-common .tribe-common-form-control-slider__input::-webkit-slider-runnable-track{border:none;border-radius:5px;height:10px;margin:5px 0;padding:0;position:relative;transition:background-color .2s ease;background-color:#334aff}.tribe-common .tribe-common-form-control-slider__input::-moz-range-track{border:none;border-radius:5px;height:10px;margin:5px 0;padding:0;position:relative;transition:background-color .2s ease;background-color:#334aff}.tribe-common .tribe-common-form-control-slider__input::-ms-track{background-color:transparent;border-color:transparent;border-width:5px 0;color:transparent;height:10px}.tribe-common .tribe-common-form-control-slider__input::-ms-fill-lower,.tribe-common .tribe-common-form-control-slider__input::-ms-fill-upper{background-color:#334aff;border-radius:10px}.tribe-common .tribe-common-form-control-slider__input::-webkit-slider-thumb{background-color:#fff;border:1px solid #d5d5d5;border-radius:50%;box-shadow:0 2px 5px 0 rgba(0,0,0,.14);height:20px;width:20px;margin-top:-5px;-webkit-appearance:none;appearance:none}.tribe-common .tribe-common-form-control-slider__input::-moz-range-thumb{background-color:#fff;border:1px solid #d5d5d5;border-radius:50%;box-shadow:0 2px 5px 0 rgba(0,0,0,.14);height:20px;width:20px;margin-top:-5px}.tribe-common .tribe-common-form-control-slider__input::-ms-thumb{background-color:#fff;border:1px solid #d5d5d5;border-radius:50%;box-shadow:0 2px 5px 0 rgba(0,0,0,.14);height:20px;width:20px;margin-top:-5px;box-shadow:none;margin-top:-1px}.tribe-common .tribe-common-form-control-slider__label{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-size:12px;line-height:1.38;font-weight:400;color:#727272;cursor:pointer;display:inline-block;margin-left:11px;vertical-align:middle}.tribe-common .tribe-common-form-control-slider--vertical .tribe-common-form-control-slider__label{display:block;margin:0 0 6px}#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-slider__label{font-weight:400;font-size:12px}.tribe-common .tribe-common-form-control-text__label{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.tribe-common .tribe-common-form-control-text__input{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-size:16px;line-height:1.62;font-weight:400;border:0;border-bottom:1px solid #d5d5d5;height:auto;padding:12px 28px 12px 0;width:100%}.tribe-common .tribe-common-form-control-text__input::-webkit-input-placeholder{color:#727272;font-style:normal}.tribe-common .tribe-common-form-control-text__input:-ms-input-placeholder,.tribe-common .tribe-common-form-control-text__input::-ms-input-placeholder{color:#727272;font-style:normal}.tribe-common .tribe-common-form-control-text__input::placeholder{color:#727272;font-style:normal}.tribe-common .tribe-common-form-control-text__input:focus{border-bottom-color:#141827;outline:0}.tribe-theme-twentyseventeen .tribe-common .tribe-common-form-control-text__input{color:#141827}#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-text__input{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-size:16px;line-height:1.62;font-weight:400;border:0;border-bottom:1px solid #d5d5d5;padding:12px 28px 12px 0;width:100%}#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-text__input:focus{border-bottom-color:#141827;box-shadow:none}.tribe-common .tribe-common-form-control-toggle{line-height:0}.tribe-common .tribe-common-form-control-toggle__input{border:none;border-radius:5px;height:10px;margin:5px 0;padding:0;position:relative;transition:background-color .2s ease;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#d5d5d5;cursor:pointer;display:inline-block;vertical-align:middle;width:40px}.tribe-common .tribe-common-form-control-toggle__input:after{background-color:#fff;border:1px solid #d5d5d5;border-radius:50%;box-shadow:0 2px 5px 0 rgba(0,0,0,.14);height:20px;width:20px;content:"";left:0;position:absolute;top:-5px;transition:transform .2s ease}.tribe-common .tribe-common-form-control-toggle__input:checked{background-color:#334aff}.tribe-common .tribe-common-form-control-toggle__input:checked:after{transform:translateX(20px)}.tribe-common .tribe-common-form-control-toggle__label{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-size:12px;line-height:1.38;font-weight:400;color:#727272;cursor:pointer;display:inline-block;margin-left:11px;vertical-align:middle}.tribe-common .tribe-common-form-control-toggle--vertical .tribe-common-form-control-toggle__label{display:block;margin:0 0 6px}#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-toggle__input{display:inline-block;margin:5px 0}#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-toggle__label{font-weight:400;font-size:12px}.tribe-common .tribe-common-g-col{min-width:0;width:100%}.tribe-common .tribe-common-g-row{display:flex;flex-wrap:wrap}.tribe-common .tribe-common-g-row--gutters{margin-left:-21px;margin-right:-21px}.tribe-common .tribe-common-g-row--gutters>.tribe-common-g-col{padding-left:21px;padding-right:21px}.tribe-common a{cursor:pointer}.tribe-common a,.tribe-common a:active,.tribe-common a:focus,.tribe-common a:hover,.tribe-common a:visited{color:#141827;outline:0;text-decoration:none}.tribe-theme-twentyseventeen .tribe-common a:focus,.tribe-theme-twentyseventeen .tribe-common a:hover{box-shadow:none;color:#141827}.tribe-theme-twentynineteen .entry .tribe-common a{text-decoration:none}.tribe-common .tribe-common-anchor{border-bottom:2px solid transparent;transition:border-color .2s ease}.tribe-common .tribe-common-anchor:active,.tribe-common .tribe-common-anchor:focus,.tribe-common .tribe-common-anchor:hover{border-bottom:2px solid #141827}.tribe-common .tribe-common-anchor-alt{border-bottom:2px solid #334aff;color:#141827;transition:color .2s ease}.tribe-common .tribe-common-anchor-alt:active,.tribe-common .tribe-common-anchor-alt:focus,.tribe-common .tribe-common-anchor-alt:hover{border-bottom:2px solid #334aff;color:#334aff}.tribe-common .tribe-common-anchor-thin{border-bottom:1px solid transparent;transition:border-color .2s ease}.tribe-common .tribe-common-anchor-thin:active,.tribe-common .tribe-common-anchor-thin:focus,.tribe-common .tribe-common-anchor-thin:hover{border-bottom:1px solid #141827}.tribe-theme-twentyseventeen .tribe-common .tribe-common-anchor-alt:focus,.tribe-theme-twentyseventeen .tribe-common .tribe-common-anchor-alt:hover{color:#334aff}.tribe-common .tribe-common-b1{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-size:14px;font-weight:400;line-height:1.62}.tribe-common .tribe-common-b1--bold{font-weight:700}.tribe-common .tribe-common-b2{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-size:12px;font-weight:400;line-height:1.38}.tribe-common .tribe-common-b2--bold{font-weight:700}.tribe-common .tribe-common-b3{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-size:11px;font-weight:400;line-height:1.5}.tribe-common .tribe-common-b3--bold{font-weight:700}.tribe-common .tribe-common-cta{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-size:12px;line-height:1.38;font-weight:400;font-weight:700;border-bottom:2px solid transparent;transition:border-color .2s ease}.tribe-common .tribe-common-cta:active,.tribe-common .tribe-common-cta:focus,.tribe-common .tribe-common-cta:hover{border-bottom:2px solid #141827}.tribe-common .tribe-common-cta--alt{border-bottom:2px solid #334aff;color:#141827;transition:color .2s ease}.tribe-common .tribe-common-cta--alt:active,.tribe-common .tribe-common-cta--alt:focus,.tribe-common .tribe-common-cta--alt:hover{border-bottom:2px solid #334aff;color:#334aff}.tribe-theme-twentyseventeen .tribe-common .tribe-common-cta--alt:focus,.tribe-theme-twentyseventeen .tribe-common .tribe-common-cta--alt:hover{color:#334aff}.tribe-common .tribe-common-h1{font-size:28px}.tribe-common .tribe-common-h1,.tribe-common .tribe-common-h2{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-weight:700;line-height:1.42}.tribe-common .tribe-common-h2{font-size:24px}.tribe-common .tribe-common-h3{font-size:22px;line-height:1.5}.tribe-common .tribe-common-h3,.tribe-common .tribe-common-h4{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-weight:700}.tribe-common .tribe-common-h4{font-size:20px;line-height:1.42}.tribe-common .tribe-common-h5{font-size:18px}.tribe-common .tribe-common-h5,.tribe-common .tribe-common-h6{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-weight:700;line-height:1.5}.tribe-common .tribe-common-h6{font-size:16px}.tribe-common .tribe-common-h7{font-size:14px;line-height:1.62}.tribe-common .tribe-common-h7,.tribe-common .tribe-common-h8{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-weight:700}.tribe-common .tribe-common-h8{font-size:12px;line-height:1.38}.tribe-common .tribe-common-h--alt{font-weight:400}.tribe-theme-avada #main .tribe-common .tribe-common-h1{font-size:28px}.tribe-theme-avada #main .tribe-common .tribe-common-h1,.tribe-theme-avada #main .tribe-common .tribe-common-h2{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-weight:700;line-height:1.42}.tribe-theme-avada #main .tribe-common .tribe-common-h2{font-size:24px}.tribe-theme-avada #main .tribe-common .tribe-common-h3{font-size:22px;line-height:1.5}.tribe-theme-avada #main .tribe-common .tribe-common-h3,.tribe-theme-avada #main .tribe-common .tribe-common-h4{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-weight:700}.tribe-theme-avada #main .tribe-common .tribe-common-h4{font-size:20px;line-height:1.42}.tribe-theme-avada #main .tribe-common .tribe-common-h5{font-size:18px}.tribe-theme-avada #main .tribe-common .tribe-common-h5,.tribe-theme-avada #main .tribe-common .tribe-common-h6{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-weight:700;line-height:1.5}.tribe-theme-avada #main .tribe-common .tribe-common-h6{font-size:16px}.tribe-theme-avada #main .tribe-common .tribe-common-h7{font-size:14px;line-height:1.62}.tribe-theme-avada #main .tribe-common .tribe-common-h7,.tribe-theme-avada #main .tribe-common .tribe-common-h8{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-weight:700}.tribe-theme-avada #main .tribe-common .tribe-common-h8{font-size:12px;line-height:1.38}.tribe-theme-avada #main .tribe-common .tribe-common-h--alt{font-weight:400}.tribe-theme-divi #left-area .tribe-common ul,.tribe-theme-divi .entry-content .tribe-common ul,body.et-pb-preview.tribe-theme-divi #main-content .container .tribe-common ul{list-style-type:none;padding:0}.tribe-common button{border:none;padding:0}.tribe-common button,.tribe-common button:focus,.tribe-common button:hover{background-color:transparent}.tribe-common .tribe-common-l-container{max-width:1260px;margin-left:auto;margin-right:auto;padding-left:19.5px;padding-right:19.5px;width:100%}.tribe-common .tribe-common-svgicon{background-repeat:no-repeat;background-size:contain}.tribe-common .tribe-common-svgicon--day{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='21' height='21' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 .503v19.994c0 .278.19.503.424.503h20.152c.234 0 .424-.225.424-.503V.503C21 .225 20.81 0 20.576 0H.424C.19 0 0 .225 0 .503zm1.156.943h18.66v2.7H1.157v-2.7zm0 4.023h18.66V19.55H1.157V5.469zM14.18 14.53v1.747c0 .482.39.874.873.874H16.8a.873.873 0 0 0 .873-.874V14.53a.873.873 0 0 0-.873-.873h-1.747a.873.873 0 0 0-.873.873z' fill='%23141827'/%3E%3C/svg%3E")}.tribe-common .tribe-common-svgicon--list{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='21' height='18' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='%23141827'%3E%3Cpath d='M19.883 3.272c.342 0 .622-.21.622-.467v-.464c0-.257-.28-.467-.622-.467H7.127c-.342 0-.622.21-.622.467v.464c0 .257.28.467.622.467h12.756zm-18.045.935a1.75 1.75 0 1 0 0-3.5 1.75 1.75 0 0 0 0 3.5zM19.883 9.98c.342 0 .622-.21.622-.466v-.465c0-.257-.28-.467-.622-.467H7.127c-.342 0-.622.21-.622.467v.465c0 .256.28.466.622.466h12.756zm-18.045.936a1.75 1.75 0 1 0 0-3.5 1.75 1.75 0 0 0 0 3.5zM19.883 16.689c.342 0 .622-.21.622-.467v-.465c0-.256-.28-.466-.622-.466H7.127c-.342 0-.622.21-.622.466v.465c0 .257.28.467.622.467h12.756zm-18.045.935a1.75 1.75 0 1 0 0-3.5 1.75 1.75 0 0 0 0 3.5z'/%3E%3C/g%3E%3C/svg%3E")}.tribe-common .tribe-common-svgicon--map{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='22' height='21' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd' stroke='%23141827'%3E%3Cpath stroke-linejoin='round' d='M13.921 11.632H17.5l3.588 8.421H1l3.488-8.421h4.016'/%3E%3Cpath d='M11.32 15.506c.2-.248 4.93-6.108 4.93-9.04 0-3.015-2.305-5.468-5.138-5.468-2.833 0-5.138 2.453-5.138 5.467 0 2.933 4.729 8.793 4.93 9.041a.268.268 0 0 0 .208.101c.08 0 .155-.037.207-.101zm-4.797-9.04c0-2.693 2.058-4.883 4.589-4.883 2.53 0 4.588 2.19 4.588 4.882 0 2.387-3.667 7.22-4.588 8.397-.922-1.177-4.589-6.009-4.589-8.397z' stroke-width='.4' fill='%23141827' fill-rule='nonzero'/%3E%3Cpath d='M12.85 6.477c0-1.007-.78-1.826-1.738-1.826-.96 0-1.74.819-1.74 1.826 0 1.007.78 1.826 1.74 1.826.959 0 1.739-.82 1.739-1.826zm-3.15 0c0-.817.633-1.482 1.412-1.482.778 0 1.41.665 1.41 1.482s-.632 1.482-1.41 1.482c-.779 0-1.412-.665-1.412-1.482z' stroke-width='.7' fill='%23000' fill-rule='nonzero'/%3E%3C/g%3E%3C/svg%3E")}.tribe-common .tribe-common-svgicon--month{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='22' height='22' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M.637 1.063v19.879c0 .276.189.5.422.5h20.037c.232 0 .421-.224.421-.5V1.062c0-.275-.189-.5-.421-.5H1.059c-.233 0-.422.225-.422.5zM1.787 2H20.34v2.685H1.787V2zm0 4H20.34v14H1.787V6zM8 8.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5zm4 0v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5zm4 0v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5zm-8 4v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5zm4 0v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5zm4 0v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5zm-12 0v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5zm0 4v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5zm4 0v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5zm4 0v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5z' fill='%23141827'/%3E%3C/svg%3E")}.tribe-common .tribe-common-svgicon--photo{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='20' height='17' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='%23141827'%3E%3Cpath d='M19.348.11H.634a.509.509 0 0 0-.52.508v15.017c0 .284.23.508.52.508h18.714a.51.51 0 0 0 .52-.508V.618a.509.509 0 0 0-.52-.508zm-.54 1.035v10.837l-2.87-3.084c-.583-.61-1.664-.61-2.246 0l-1.393 1.481-4.034-4.525a1.625 1.625 0 0 0-1.227-.528 1.6 1.6 0 0 0-1.206.548l-4.657 5.175V1.145h17.632zM1.174 15.108v-2.496l5.448-6.089a.529.529 0 0 1 .415-.182c.146 0 .333.06.437.182l4.429 4.972c.104.102.25.183.395.183.166.02.291-.06.395-.162l1.788-1.908c.167-.183.5-.183.686 0l3.66 3.917v1.603H1.175v-.02z'/%3E%3Cpath d='M14.19 5.757c1.044 0 1.91-.872 1.91-1.968s-.846-1.969-1.91-1.969c-1.062 0-1.909.873-1.909 1.969s.866 1.968 1.91 1.968zm0-2.902c.493 0 .907.427.907.934 0 .507-.414.933-.906.933-.492 0-.906-.426-.906-.933 0-.507.414-.934.906-.934z'/%3E%3C/g%3E%3C/svg%3E")}.tribe-common .tribe-common-svgicon--week{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='21' height='21' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 .503v19.994c0 .278.19.503.424.503h20.152c.234 0 .424-.225.424-.503V.503C21 .225 20.81 0 20.576 0H.424C.19 0 0 .225 0 .503zm1.156.943h18.66v2.7H1.157v-2.7zm0 4.023h18.66V19.55H1.157V5.469zm6.25 6.537v1.006c0 .278.224.503.502.503h1.006a.503.503 0 0 0 .503-.503v-1.006a.503.503 0 0 0-.503-.502H7.908a.503.503 0 0 0-.503.502zm4.022 0v1.006c0 .278.225.503.503.503h1.006a.503.503 0 0 0 .503-.503v-1.006a.503.503 0 0 0-.503-.502H11.93a.503.503 0 0 0-.503.502zm4.023 0v1.006c0 .278.225.503.503.503h1.006a.503.503 0 0 0 .503-.503v-1.006a.503.503 0 0 0-.503-.502h-1.006a.503.503 0 0 0-.503.502zm-12.069 0v1.006c0 .278.225.503.503.503h1.006a.503.503 0 0 0 .503-.503v-1.006a.503.503 0 0 0-.503-.502H3.885a.503.503 0 0 0-.503.502z' fill='%23141827'/%3E%3C/svg%3E")}.tribe-common .tribe-common-svgicon--featured{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='16' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 0h16v20l-7.902-5.122L0 20z' fill='%23334AFF'/%3E%3C/svg%3E");height:10px;width:8px}.tribe-common .tribe-common-svgicon--recurring{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='20' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M13.333 3.826c0 .065 0 .13-.02.174 0 .022-.02.065-.02.087a.9.9 0 0 1-.197.37L10.45 7.37a.797.797 0 0 1-.592.26.797.797 0 0 1-.593-.26c-.316-.348-.316-.935 0-1.305l1.225-1.348H6.3c-2.547 0-4.64 2.283-4.64 5.11 0 1.369.474 2.651 1.363 3.608.316.348.316.935 0 1.304A.797.797 0 0 1 2.43 15a.797.797 0 0 1-.593-.26C.652 13.434 0 11.695 0 9.847c0-3.826 2.825-6.935 6.301-6.935h4.208L9.284 1.565c-.316-.348-.316-.935 0-1.304.316-.348.85-.348 1.185 0l2.647 2.913a.952.952 0 0 1 .198.37c0 .021.02.065.02.086v.196zM20 10.152c0 3.826-2.825 6.935-6.301 6.935H9.49l1.225 1.348c.336.348.336.935 0 1.304a.797.797 0 0 1-.593.261.83.83 0 0 1-.592-.26l-2.627-2.936a.948.948 0 0 1-.198-.37c0-.021-.02-.064-.02-.086-.02-.065-.02-.109-.02-.174 0-.065 0-.13.02-.174 0-.022.02-.065.02-.087a.9.9 0 0 1 .198-.37L9.55 12.63c.316-.347.849-.347 1.185 0 .336.348.336.935 0 1.305L9.51 15.283h4.208c2.548 0 4.641-2.283 4.641-5.11 0-1.369-.474-2.651-1.362-3.608a.97.97 0 0 1 0-1.304c.316-.348.849-.348 1.185 0C19.348 6.543 20 8.283 20 10.152z' fill='%23334AFF'/%3E%3C/svg%3E");height:10px;width:10px}.tribe-common .tribe-common-svgicon--search{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='20' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M20 18.711l-6.044-6.044a7.782 7.782 0 0 0 1.688-4.845c0-2.089-.822-4.044-2.288-5.533C11.866.822 9.91 0 7.822 0S3.778.822 2.29 2.289A7.801 7.801 0 0 0 0 7.822c0 2.09.822 4.045 2.289 5.534a7.801 7.801 0 0 0 5.533 2.288c1.778 0 3.467-.6 4.845-1.688L18.71 20 20 18.711zM3.578 12.067c-2.334-2.334-2.334-6.156 0-8.49a5.968 5.968 0 0 1 4.244-1.755c1.6 0 3.111.622 4.245 1.756 2.333 2.333 2.333 6.155 0 8.489a5.968 5.968 0 0 1-4.245 1.755c-1.6 0-3.11-.622-4.244-1.755z' fill='%23727272'/%3E%3C/svg%3E")}.tribe-common .tribe-common-svgicon--filters{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='17' height='17'%3E%3Cg fill='none' fill-rule='evenodd' stroke='%23727272' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' transform='translate(1 1)'%3E%3Cpath d='M3 3V0m0 15v-2'/%3E%3Ccircle cx='3' cy='9' r='3'/%3E%3Cpath d='M12 9v6'/%3E%3Ccircle cx='12' cy='3' r='3' transform='matrix(1 0 0 -1 0 6)'/%3E%3C/g%3E%3C/svg%3E")}.tribe-theme-enfold .tribe-common th{letter-spacing:0;text-transform:none}.tribe-common .tribe-common-a11y-hidden{display:none!important;visibility:hidden}.tribe-common .tribe-common-a11y-visual-hide,.tribe-common .tribe-common-a11y-visual-show{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.tribe-common .tribe-common-c-btn-border,.tribe-common a.tribe-common-c-btn-border{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-size:12px;line-height:1.38;font-weight:400;border:0;cursor:pointer;display:inline-block;height:auto;padding:0;text-decoration:none;width:auto;background-color:#fff;border:1px solid #d5d5d5;border-radius:4px;text-align:center;transition:color .2s ease,border-color .2s ease;color:#727272;padding:14px 20px;width:100%}.tribe-common .tribe-common-c-btn-border:focus,.tribe-common .tribe-common-c-btn-border:hover,.tribe-common a.tribe-common-c-btn-border:focus,.tribe-common a.tribe-common-c-btn-border:hover{background-color:#fff}.tribe-common .tribe-common-c-btn-border:active,.tribe-common a.tribe-common-c-btn-border:active{border-color:#141827}.tribe-common .tribe-common-c-btn-border:active,.tribe-common .tribe-common-c-btn-border:focus,.tribe-common .tribe-common-c-btn-border:hover,.tribe-common a.tribe-common-c-btn-border:active,.tribe-common a.tribe-common-c-btn-border:focus,.tribe-common a.tribe-common-c-btn-border:hover{color:#141827}.tribe-common .tribe-common-c-btn-border:disabled,.tribe-common a.tribe-common-c-btn-border:disabled{color:#d5d5d5}.tribe-common .tribe-common-c-btn-icon{border:0;cursor:pointer;display:inline-block;height:auto;padding:0;text-decoration:none;width:auto}.tribe-common .tribe-common-c-btn-icon:before{background-repeat:no-repeat;background-size:contain;content:"";display:block}.tribe-common .tribe-common-c-btn-icon--border{background-color:#fff;border:1px solid #d5d5d5;align-items:center;display:inline-flex;height:56px;justify-content:center;transition:none;width:56px}.tribe-common .tribe-common-c-btn-icon--border:focus,.tribe-common .tribe-common-c-btn-icon--border:hover{background-color:#fff}.tribe-common .tribe-common-c-btn-icon--border:active{border-color:#141827}.tribe-common .tribe-common-c-btn-icon--caret-left:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='12' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11.916 17.841L10 19.757l-9.9-9.9L10-.041l1.916 1.916-7.983 7.984z' fill='%23BABABA'/%3E%3C/svg%3E");height:20px;width:12px}.tribe-common .tribe-common-c-btn-icon--caret-left:active:before,.tribe-common .tribe-common-c-btn-icon--caret-left:focus:before,.tribe-common .tribe-common-c-btn-icon--caret-left:hover:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='12' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11.916 17.841L10 19.757l-9.9-9.9L10-.041l1.916 1.916-7.983 7.984z' fill='%23727272'/%3E%3C/svg%3E")}.tribe-common .tribe-common-c-btn-icon--caret-left:disabled:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='12' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11.916 17.841L10 19.757l-9.9-9.9L10-.041l1.916 1.916-7.983 7.984z' fill='%23D5D5D5'/%3E%3C/svg%3E")}.tribe-common .tribe-common-c-btn-icon--caret-right:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='12' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M.084 2.159L2 .243l9.9 9.9L2 20.041.084 18.126l7.983-7.984z' fill='%23BABABA'/%3E%3C/svg%3E");height:20px;width:12px}.tribe-common .tribe-common-c-btn-icon--caret-right:active:before,.tribe-common .tribe-common-c-btn-icon--caret-right:focus:before,.tribe-common .tribe-common-c-btn-icon--caret-right:hover:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='12' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M.084 2.159L2 .243l9.9 9.9L2 20.041.084 18.126l7.983-7.984z' fill='%23727272'/%3E%3C/svg%3E")}.tribe-common .tribe-common-c-btn-icon--caret-right:disabled:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='12' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M.084 2.159L2 .243l9.9 9.9L2 20.041.084 18.126l7.983-7.984z' fill='%23D5D5D5'/%3E%3C/svg%3E")}.tribe-common .tribe-common-c-btn-icon--filters:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='17' height='17'%3E%3Cg fill='none' fill-rule='evenodd' stroke='%23727272' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' transform='translate(1 1)'%3E%3Cpath d='M3 3V0m0 15v-2'/%3E%3Ccircle cx='3' cy='9' r='3'/%3E%3Cpath d='M12 9v6'/%3E%3Ccircle cx='12' cy='3' r='3' transform='matrix(1 0 0 -1 0 6)'/%3E%3C/g%3E%3C/svg%3E");height:20px;width:24px}.tribe-common .tribe-common-c-btn-icon--filters:active:before,.tribe-common .tribe-common-c-btn-icon--filters:focus:before,.tribe-common .tribe-common-c-btn-icon--filters:hover:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='17' height='17'%3E%3Cg fill='none' fill-rule='evenodd' stroke='%23141827' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' transform='translate(1 1)'%3E%3Cpath d='M3 3V0m0 15v-2'/%3E%3Ccircle cx='3' cy='9' r='3'/%3E%3Cpath d='M12 9v6'/%3E%3Ccircle cx='12' cy='3' r='3' transform='matrix(1 0 0 -1 0 6)'/%3E%3C/g%3E%3C/svg%3E")}.tribe-common .tribe-common-c-btn-icon--filters:disabled:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='17' height='17'%3E%3Cg fill='none' fill-rule='evenodd' stroke='%23D5D5D5' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' transform='translate(1 1)'%3E%3Cpath d='M3 3V0m0 15v-2'/%3E%3Ccircle cx='3' cy='9' r='3'/%3E%3Cpath d='M12 9v6'/%3E%3Ccircle cx='12' cy='3' r='3' transform='matrix(1 0 0 -1 0 6)'/%3E%3C/g%3E%3C/svg%3E")}.tribe-common .tribe-common-c-btn-icon--search:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='20' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M20 18.711l-6.044-6.044a7.782 7.782 0 0 0 1.688-4.845c0-2.089-.822-4.044-2.288-5.533C11.866.822 9.91 0 7.822 0S3.778.822 2.29 2.289A7.801 7.801 0 0 0 0 7.822c0 2.09.822 4.045 2.289 5.534a7.801 7.801 0 0 0 5.533 2.288c1.778 0 3.467-.6 4.845-1.688L18.71 20 20 18.711zM3.578 12.067c-2.334-2.334-2.334-6.156 0-8.49a5.968 5.968 0 0 1 4.244-1.755c1.6 0 3.111.622 4.245 1.756 2.333 2.333 2.333 6.155 0 8.489a5.968 5.968 0 0 1-4.245 1.755c-1.6 0-3.11-.622-4.244-1.755z' fill='%23727272'/%3E%3C/svg%3E");height:20px;width:20px}.tribe-common .tribe-common-c-btn-icon--search:active:before,.tribe-common .tribe-common-c-btn-icon--search:focus:before,.tribe-common .tribe-common-c-btn-icon--search:hover:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='20' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M20 18.711l-6.044-6.044a7.782 7.782 0 0 0 1.688-4.845c0-2.089-.822-4.044-2.288-5.533C11.866.822 9.91 0 7.822 0S3.778.822 2.29 2.289A7.801 7.801 0 0 0 0 7.822c0 2.09.822 4.045 2.289 5.534a7.801 7.801 0 0 0 5.533 2.288c1.778 0 3.467-.6 4.845-1.688L18.71 20 20 18.711zM3.578 12.067c-2.334-2.334-2.334-6.156 0-8.49a5.968 5.968 0 0 1 4.244-1.755c1.6 0 3.111.622 4.245 1.756 2.333 2.333 2.333 6.155 0 8.489a5.968 5.968 0 0 1-4.245 1.755c-1.6 0-3.11-.622-4.244-1.755z' fill='%23141827'/%3E%3C/svg%3E")}.tribe-common .tribe-common-c-btn-icon--search:disabled:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='20' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M20 18.711l-6.044-6.044a7.782 7.782 0 0 0 1.688-4.845c0-2.089-.822-4.044-2.288-5.533C11.866.822 9.91 0 7.822 0S3.778.822 2.29 2.289A7.801 7.801 0 0 0 0 7.822c0 2.09.822 4.045 2.289 5.534a7.801 7.801 0 0 0 5.533 2.288c1.778 0 3.467-.6 4.845-1.688L18.71 20 20 18.711zM3.578 12.067c-2.334-2.334-2.334-6.156 0-8.49a5.968 5.968 0 0 1 4.244-1.755c1.6 0 3.111.622 4.245 1.756 2.333 2.333 2.333 6.155 0 8.489a5.968 5.968 0 0 1-4.245 1.755c-1.6 0-3.11-.622-4.244-1.755z' fill='%23D5D5D5'/%3E%3C/svg%3E")}.tribe-common .tribe-common-c-btn,.tribe-common a.tribe-common-c-btn{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-size:14px;line-height:1.62;font-weight:400;font-weight:700;border:0;cursor:pointer;display:inline-block;height:auto;padding:0;text-decoration:none;width:auto;border-radius:4px;color:#fff;text-align:center;transition:background-color .2s ease;background-color:#334aff;padding:11px 20px;width:100%}.tribe-common .tribe-common-c-btn:focus,.tribe-common .tribe-common-c-btn:hover,.tribe-common a.tribe-common-c-btn:focus,.tribe-common a.tribe-common-c-btn:hover{background-color:rgba(51,74,255,.8)}.tribe-common .tribe-common-c-btn:active,.tribe-common a.tribe-common-c-btn:active{background-color:rgba(51,74,255,.9)}.tribe-common .tribe-common-c-btn:disabled,.tribe-common a.tribe-common-c-btn:disabled{background-color:rgba(51,74,255,.07)}.tribe-common .tribe-common-c-image{display:block;height:auto;margin-left:auto;margin-right:auto;width:100%}.tribe-common .tribe-common-c-image--bg{position:relative}.tribe-common .tribe-common-c-image__bg{background:50% no-repeat;background-size:cover;bottom:0;height:100%;left:0;position:absolute;right:0;top:0;width:100%}@media (min-width:768px){#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-text__input,.tribe-common .tribe-common-form-control-text__input{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-size:14px;line-height:1.62;font-weight:400;border:0;padding:20px 20px 20px 40px}.tribe-common .tribe-common-g-row--gutters{margin-left:-24px;margin-right:-24px}.tribe-common .tribe-common-g-row--gutters>.tribe-common-g-col{padding-left:24px;padding-right:24px}.tribe-common .tribe-common-b1{font-size:16px;line-height:1.62}.tribe-common .tribe-common-b2{font-size:14px;line-height:1.62}.tribe-common .tribe-common-b3{font-size:12px;line-height:1.38}.tribe-common .tribe-common-b1--min-medium{font-size:16px;line-height:1.62}.tribe-common .tribe-common-h1{font-size:42px;line-height:1.38}.tribe-common .tribe-common-h2{font-size:32px;line-height:1.38}.tribe-common .tribe-common-h3{font-size:28px;line-height:1.42}.tribe-common .tribe-common-h4{font-size:24px;line-height:1.42}.tribe-common .tribe-common-h6{font-size:16px;line-height:1.62}.tribe-common .tribe-common-h3--min-medium{font-size:28px;line-height:1.42}.tribe-common .tribe-common-h4--min-medium{font-size:24px;line-height:1.42}.tribe-common .tribe-common-h5--min-medium{font-size:18px;line-height:1.5}.tribe-common .tribe-common-h6--min-medium{font-size:16px;line-height:1.62}.tribe-common .tribe-common-h7--min-medium{font-size:14px;line-height:1.62}.tribe-theme-avada #main .tribe-common .tribe-common-h1{font-size:42px;line-height:1.38}.tribe-theme-avada #main .tribe-common .tribe-common-h2{font-size:32px;line-height:1.38}.tribe-theme-avada #main .tribe-common .tribe-common-h3{font-size:28px;line-height:1.42}.tribe-theme-avada #main .tribe-common .tribe-common-h4{font-size:24px;lin
|
