Version Description
- First version of the public relationship API that will be sustainable also for many-to-many relationships.
- Added a warning about dropping the PHP 5.2 support (which is no longer officially supported anyway) in the near future.
- Fixed: Using the_title filter without the mandatory $id argument.
- Fixed: Deprecated function notice in PHP 7.2.
Download this release
Release Info
Developer | zaantar |
Plugin | Toolset Types – Custom Post Types, Custom Fields and Taxonomies |
Version | 2.2.22 |
Comparing to | |
See all releases |
Code changes from version 2.2.21 to 2.2.22
- application/autoload_classmap.php +8 -8
- application/controllers/{utils → admin_notice}/utils.php +0 -0
- application/controllers/ajax.php +42 -205
- application/controllers/asset/manager.php +9 -1
- application/models/field/{type/definition → gateway}/checkbox.php +0 -0
- application/models/field/{type/definition → gateway}/checkboxes.php +0 -0
- application/models/field/{type/definition → gateway}/date.php +0 -0
- application/models/field/{type/definition → gateway}/numeric.php +0 -0
- application/models/field/{type/definition → gateway}/radio.php +0 -0
- application/models/field/{type/definition → gateway}/select.php +0 -0
- application/models/field/{type/definition → gateway}/singular.php +0 -0
- readme.txt +8 -2
- vendor/autoload.php +1 -1
- vendor/composer/autoload_classmap.php +154 -61
- vendor/composer/autoload_real.php +7 -7
- vendor/composer/autoload_static.php +159 -66
- vendor/composer/installed.json +15 -9
- vendor/otgs/installer/changelog.txt +10 -0
- vendor/otgs/installer/includes/class-installer-theme.php +2 -2
- vendor/otgs/installer/includes/class-otgs-installer-filename-hooks.php +33 -0
- vendor/otgs/installer/includes/class-otgs-installer-php-functions.php +29 -0
- vendor/otgs/installer/includes/class-wp-installer.php +67 -46
- vendor/otgs/installer/installer.php +6 -2
- vendor/otgs/installer/loader.php +1 -1
- vendor/toolset/toolset-common/api.php +31 -0
- vendor/toolset/toolset-common/autoload_classmap.php +73 -7
- vendor/toolset/toolset-common/bootstrap.php +35 -2
- vendor/toolset/toolset-common/changelog.md +49 -19
- vendor/toolset/toolset-common/debug/main.js +4 -3
- vendor/toolset/toolset-common/debug/main.twig +2 -3
- vendor/toolset/toolset-common/functions.php +0 -9
- vendor/toolset/toolset-common/inc/autoloaded/admin.php +32 -0
- vendor/toolset/toolset-common/inc/{controller → autoloaded}/admin/notices.php +6 -1
- vendor/toolset/toolset-common/inc/autoloaded/ajax_handler/get_ct_block_preview.php +50 -0
- vendor/toolset/toolset-common/inc/autoloaded/ajax_handler/get_post_by_id.php +54 -0
- vendor/toolset/toolset-common/inc/autoloaded/ajax_handler/get_term_by_id.php +54 -0
- vendor/toolset/toolset-common/inc/autoloaded/ajax_handler/get_user_by_id.php +54 -0
- vendor/toolset/toolset-common/inc/autoloaded/ajax_handler/get_view_block_preview.php +142 -0
- vendor/toolset/toolset-common/inc/autoloaded/ajax_handler/intermediary_post_cleanup.php +85 -0
- vendor/toolset/toolset-common/inc/autoloaded/ajax_handler/migrate_to_m2m.php +26 -14
- vendor/toolset/toolset-common/inc/autoloaded/ajax_handler/select2_suggest_posts_by_title.php +134 -0
- vendor/toolset/toolset-common/inc/autoloaded/ajax_handler/select2_suggest_terms.php +71 -0
- vendor/toolset/toolset-common/inc/autoloaded/ajax_handler/select2_suggest_users.php +75 -0
- vendor/toolset/toolset-common/inc/{controller → autoloaded}/asset_manager.php +0 -0
- vendor/toolset/toolset-common/inc/{controller → autoloaded}/constants.php +0 -0
- vendor/toolset/toolset-common/inc/autoloaded/cron/cron.php +182 -0
- vendor/toolset/toolset-common/inc/autoloaded/cron/event.php +37 -0
- vendor/toolset/toolset-common/inc/autoloaded/cron/event_interface.php +45 -0
- vendor/toolset/toolset-common/inc/autoloaded/element/element.php +28 -73
- vendor/toolset/toolset-common/inc/autoloaded/element/element_factory.php +92 -11
- vendor/toolset/toolset-common/inc/autoloaded/element/i_element.php +40 -12
- vendor/toolset/toolset-common/inc/autoloaded/element/i_post.php +29 -1
- vendor/toolset/toolset-common/inc/autoloaded/element/post.php +124 -8
- vendor/toolset/toolset-common/inc/autoloaded/element/post_translation_set.php +160 -20
- vendor/toolset/toolset-common/inc/autoloaded/field/definition.php +10 -1
- vendor/toolset/toolset-common/inc/autoloaded/field/definition_abstract.php +1 -1
- vendor/toolset/toolset-common/inc/autoloaded/field/definition_factory.php +9 -9
- vendor/toolset/toolset-common/inc/autoloaded/field/definition_factory_interface.php +212 -0
- vendor/toolset/toolset-common/inc/autoloaded/field/definition_factory_post.php +1 -1
- vendor/toolset/toolset-common/inc/autoloaded/field/definition_factory_term.php +1 -1
- vendor/toolset/toolset-common/inc/autoloaded/field/definition_factory_user.php +1 -1
- vendor/toolset/toolset-common/inc/autoloaded/field/definition_interface.php +71 -0
- vendor/toolset/toolset-common/inc/autoloaded/field/definition_post.php +9 -1
- vendor/toolset/toolset-common/inc/autoloaded/field/definition_term.php +8 -0
- vendor/toolset/toolset-common/inc/autoloaded/field/definition_user.php +8 -0
- vendor/toolset/toolset-common/inc/autoloaded/field/group.php +2 -2
- vendor/toolset/toolset-common/inc/autoloaded/files.php +54 -0
- vendor/toolset/toolset-common/inc/autoloaded/naming_helper.php +1 -1
- vendor/toolset/toolset-common/inc/autoloaded/post_type/abstract.php +125 -0
- vendor/toolset/toolset-common/inc/autoloaded/post_type/excluded_list.php +1 -0
- vendor/toolset/toolset-common/inc/autoloaded/post_type/from_types.php +40 -3
- vendor/toolset/toolset-common/inc/autoloaded/post_type/i_post_type.php +37 -0
- vendor/toolset/toolset-common/inc/autoloaded/post_type/i_post_type_from_types.php +22 -0
- vendor/toolset/toolset-common/inc/autoloaded/post_type/query.php +12 -1
- vendor/toolset/toolset-common/inc/autoloaded/post_type/registered.php +4 -2
- vendor/toolset/toolset-common/inc/autoloaded/post_type/repository.php +7 -3
- vendor/toolset/toolset-common/inc/autoloaded/relationship_service.php +27 -3
- vendor/toolset/toolset-common/inc/autoloaded/renderer/output_template/abstract.php +48 -0
- vendor/toolset/toolset-common/inc/autoloaded/renderer/output_template/interface.php +23 -0
- vendor/toolset/toolset-common/inc/autoloaded/renderer/output_template/phtml.php +29 -0
- vendor/toolset/toolset-common/inc/autoloaded/renderer/output_template/static.php +12 -0
- vendor/toolset/toolset-common/inc/autoloaded/renderer/output_template/twig.php +70 -0
- vendor/toolset/toolset-common/inc/autoloaded/renderer/output_template_factory.php +102 -0
- vendor/toolset/toolset-common/inc/autoloaded/renderer/output_template_repository.php +63 -0
- vendor/toolset/toolset-common/inc/autoloaded/renderer/output_template_repository_abstract.php +79 -0
- vendor/toolset/toolset-common/inc/autoloaded/renderer/renderer.php +228 -0
- vendor/toolset/toolset-common/inc/autoloaded/result_set.php +7 -2
- vendor/toolset/toolset-common/inc/autoloaded/wp_query_adjustments/abstract.php +170 -0
- vendor/toolset/toolset-common/inc/autoloaded/wp_query_adjustments/legacy_relationships.php +141 -0
- vendor/toolset/toolset-common/inc/autoloaded/wp_query_adjustments/loader.php +25 -0
- vendor/toolset/toolset-common/inc/autoloaded/wp_query_adjustments/m2m.php +251 -0
- vendor/toolset/toolset-common/inc/autoloaded/wp_query_adjustments/table_join_manager.php +172 -0
- vendor/toolset/toolset-common/inc/autoloaded/wpdb_user.php +30 -0
- vendor/toolset/toolset-common/inc/autoloaded/wpml_utils.php +53 -28
- vendor/toolset/toolset-common/inc/m2m/association.php +0 -191
- vendor/toolset/toolset-common/inc/m2m/association/association.php +472 -0
- vendor/toolset/toolset-common/inc/m2m/association/cleanup/association.php +73 -0
- vendor/toolset/toolset-common/inc/m2m/association/cleanup/cron_event.php +45 -0
- vendor/toolset/toolset-common/inc/m2m/association/cleanup/cron_handler.php +57 -0
- vendor/toolset/toolset-common/inc/m2m/association/cleanup/dangling_intermediary_posts.php +189 -0
- vendor/toolset/toolset-common/inc/m2m/association/cleanup/factory.php +61 -0
- vendor/toolset/toolset-common/inc/m2m/association/cleanup/post.php +295 -0
- vendor/toolset/toolset-common/inc/m2m/association/cleanup/troubleshooting_section.php +115 -0
- vendor/toolset/toolset-common/inc/m2m/association/factory.php +96 -0
- vendor/toolset/toolset-common/inc/m2m/{i_association.php → association/interface.php} +36 -2
- vendor/toolset/toolset-common/inc/m2m/association/intermediary_post_persistence.php +273 -0
- vendor/toolset/toolset-common/inc/m2m/association/persistence.php +160 -0
- vendor/toolset/toolset-common/inc/m2m/association/query/association_query.php +244 -0
- vendor/toolset/toolset-common/inc/m2m/association/query/association_query_v2.php +994 -0
- vendor/toolset/toolset-common/inc/m2m/association/query/condition/abstract.php +22 -0
- vendor/toolset/toolset-common/inc/m2m/association/query/condition/association_id.php +39 -0
- vendor/toolset/toolset-common/inc/m2m/association/query/condition/element_id.php +65 -0
- vendor/toolset/toolset-common/inc/m2m/association/query/condition/element_id_and_domain.php +109 -0
- vendor/toolset/toolset-common/inc/m2m/association/query/condition/element_status.php +118 -0
- vendor/toolset/toolset-common/inc/m2m/association/query/condition/empty_intermediary.php +20 -0
- vendor/toolset/toolset-common/inc/m2m/association/query/condition/exclude_element.php +16 -0
- vendor/toolset/toolset-common/inc/m2m/association/query/condition/has_active_relationship.php +18 -0
- vendor/toolset/toolset-common/inc/m2m/association/query/condition/has_domain.php +86 -0
- vendor/toolset/toolset-common/inc/m2m/association/query/condition/has_domain_and_type.php +98 -0
- vendor/toolset/toolset-common/inc/m2m/association/query/condition/has_legacy_relationship.php +18 -0
- vendor/toolset/toolset-common/inc/m2m/association/query/condition/has_type.php +100 -0
- vendor/toolset/toolset-common/inc/m2m/association/query/condition/interface.php +14 -0
- vendor/toolset/toolset-common/inc/m2m/association/query/condition/postmeta.php +78 -0
- vendor/toolset/toolset-common/inc/m2m/association/query/condition/relationship_flag.php +55 -0
- vendor/toolset/toolset-common/inc/m2m/association/query/condition/relationship_id.php +41 -0
- vendor/toolset/toolset-common/inc/m2m/association/query/condition/search.php +92 -0
- vendor/toolset/toolset-common/inc/m2m/association/query/condition/wp_query.php +288 -0
- vendor/toolset/toolset-common/inc/m2m/association/query/condition_factory.php +322 -0
- vendor/toolset/toolset-common/inc/m2m/association/query/element_selector/abstract.php +95 -0
- vendor/toolset/toolset-common/inc/m2m/association/query/element_selector/default.php +94 -0
- vendor/toolset/toolset-common/inc/m2m/association/query/element_selector/interface.php +93 -0
- vendor/toolset/toolset-common/inc/m2m/association/query/element_selector/provider.php +113 -0
- vendor/toolset/toolset-common/inc/m2m/association/query/element_selector/wpml.php +257 -0
- vendor/toolset/toolset-common/inc/m2m/association/query/orderby/abstract.php +50 -0
- vendor/toolset/toolset-common/inc/m2m/association/query/orderby/interface.php +36 -0
- vendor/toolset/toolset-common/inc/m2m/association/query/orderby/nothing.php +21 -0
- vendor/toolset/toolset-common/inc/m2m/association/query/orderby/postmeta.php +87 -0
- vendor/toolset/toolset-common/inc/m2m/association/query/orderby/title.php +52 -0
- vendor/toolset/toolset-common/inc/m2m/association/query/orderby_factory.php +40 -0
- vendor/toolset/toolset-common/inc/m2m/association/query/restriction/interface.php +35 -0
- vendor/toolset/toolset-common/inc/m2m/association/query/result_transformation/association_instance.php +145 -0
- vendor/toolset/toolset-common/inc/m2m/association/query/result_transformation/association_uid.php +39 -0
- vendor/toolset/toolset-common/inc/m2m/association/query/result_transformation/element_id.php +52 -0
- vendor/toolset/toolset-common/inc/m2m/association/query/result_transformation/element_instance.php +129 -0
- vendor/toolset/toolset-common/inc/m2m/association/query/result_transformation/interface.php +35 -0
- vendor/toolset/toolset-common/inc/m2m/association/query/sql_expression_builder.php +139 -0
- vendor/toolset/toolset-common/inc/m2m/association/query/table_join_manager.php +209 -0
- vendor/toolset/toolset-common/inc/m2m/association/query/wpdb_wrapper.php +84 -0
- vendor/toolset/toolset-common/inc/m2m/association/translator.php +236 -0
- vendor/toolset/toolset-common/inc/m2m/association_base.php +0 -193
- vendor/toolset/toolset-common/inc/m2m/association_query.php +0 -932
- vendor/toolset/toolset-common/inc/m2m/association_repository.php +0 -260
- vendor/toolset/toolset-common/inc/m2m/association_transitional.php +0 -61
- vendor/toolset/toolset-common/inc/m2m/association_translation_set.php +0 -135
- vendor/toolset/toolset-common/inc/m2m/autoload_classmap.php +101 -51
- vendor/toolset/toolset-common/inc/m2m/cardinality.php +2 -2
- vendor/toolset/toolset-common/inc/m2m/controller.php +113 -52
- vendor/toolset/toolset-common/inc/m2m/database/operations.php +166 -108
- vendor/toolset/toolset-common/inc/m2m/driver.php +23 -424
- vendor/toolset/toolset-common/inc/m2m/driver_base.php +43 -4
- vendor/toolset/toolset-common/inc/m2m/element_type.php +5 -5
- vendor/toolset/toolset-common/inc/m2m/migration/associations.php +222 -0
- vendor/toolset/toolset-common/inc/m2m/{migration.php → migration/controller.php} +94 -53
- vendor/toolset/toolset-common/inc/m2m/migration/post_translation.php +213 -0
- vendor/toolset/toolset-common/inc/m2m/migration_associations.php +0 -119
- vendor/toolset/toolset-common/inc/m2m/multilingual_mode.php +0 -236
- vendor/toolset/toolset-common/inc/m2m/potential_association/distinct_post_query.php +56 -12
- vendor/toolset/toolset-common/inc/m2m/potential_association/query_interface.php +16 -1
- vendor/toolset/toolset-common/inc/m2m/potential_association/query_posts.php +52 -31
- vendor/toolset/toolset-common/inc/m2m/query/comparison_operator.php +28 -0
- vendor/toolset/toolset-common/inc/m2m/{relationship_query → query}/condition/and.php +9 -4
- vendor/toolset/toolset-common/inc/m2m/query/condition/contradiction.php +30 -0
- vendor/toolset/toolset-common/inc/m2m/{relationship_query/condition/i_condition.php → query/condition/interface.php} +2 -6
- vendor/toolset/toolset-common/inc/m2m/{relationship_query → query}/condition/operator.php +8 -6
- vendor/toolset/toolset-common/inc/m2m/{relationship_query → query}/condition/or.php +4 -4
- vendor/toolset/toolset-common/inc/m2m/{relationship_query → query}/condition/tautology.php +10 -1
- vendor/toolset/toolset-common/inc/m2m/{query_factory.php → query/factory.php} +12 -4
- vendor/toolset/toolset-common/inc/m2m/query_base.php +1 -0
- vendor/toolset/toolset-common/inc/m2m/{definition → relationship/definition}/definition.php +37 -24
- vendor/toolset/toolset-common/inc/m2m/{definition → relationship/definition}/factory.php +0 -0
- vendor/toolset/toolset-common/inc/m2m/{definition → relationship/definition}/interface.php +29 -3
- vendor/toolset/toolset-common/inc/m2m/{definition → relationship/definition}/persistence.php +76 -1
- vendor/toolset/toolset-common/inc/m2m/{definition → relationship/definition}/repository.php +1 -28
- vendor/toolset/toolset-common/inc/m2m/{definition → relationship/definition}/translator.php +1 -1
- vendor/toolset/toolset-common/inc/m2m/{relationship_query → relationship/query}/cardinality_match/conjunction.php +0 -0
- vendor/toolset/toolset-common/inc/m2m/{relationship_query → relationship/query}/cardinality_match/factory.php +0 -0
- vendor/toolset/toolset-common/inc/m2m/{relationship_query → relationship/query}/cardinality_match/interface.php +0 -0
- vendor/toolset/toolset-common/inc/m2m/{relationship_query → relationship/query}/cardinality_match/operators.php +0 -0
- vendor/toolset/toolset-common/inc/m2m/{relationship_query → relationship/query}/cardinality_match/single.php +0 -0
- vendor/toolset/toolset-common/inc/m2m/{relationship_query → relationship/query}/condition/abstract.php +0 -0
- vendor/toolset/toolset-common/inc/m2m/{relationship_query → relationship/query}/condition/has_active_types.php +0 -0
- vendor/toolset/toolset-common/inc/m2m/{relationship_query → relationship/query}/condition/has_cardinality.php +0 -0
- vendor/toolset/toolset-common/inc/m2m/{relationship_query → relationship/query}/condition/has_domain.php +2 -1
- vendor/toolset/toolset-common/inc/m2m/relationship/query/condition/interface.php +10 -0
- vendor/toolset/toolset-common/inc/m2m/{relationship_query → relationship/query}/condition/is_active.php +0 -0
- vendor/toolset/toolset-common/inc/m2m/{relationship_query → relationship/query}/condition/is_boolean_flag.php +0 -0
- vendor/toolset/toolset-common/inc/m2m/{relationship_query → relationship/query}/condition/is_legacy.php +0 -0
- vendor/toolset/toolset-common/inc/m2m/{relationship_query → relationship/query}/condition/origin.php +0 -0
- vendor/toolset/toolset-common/inc/m2m/{relationship_query → relationship/query}/condition/type.php +1 -1
- vendor/toolset/toolset-common/inc/m2m/{relationship_query → relationship/query}/condition_factory.php +6 -6
- vendor/toolset/toolset-common/inc/m2m/{relationship_query → relationship/query}/relationship_query.php +0 -0
- vendor/toolset/toolset-common/inc/m2m/{relationship_query → relationship/query}/relationship_query_v2.php +77 -2
- vendor/toolset/toolset-common/inc/m2m/{relationship_query → relationship/query}/sql_expression_builder.php +7 -9
- vendor/toolset/toolset-common/inc/m2m/{relationship_role → relationship/role}/abstract.php +0 -0
- vendor/toolset/toolset-common/inc/m2m/{relationship_role → relationship/role}/child.php +0 -0
- vendor/toolset/toolset-common/inc/m2m/{relationship_role → relationship/role}/interface.php +0 -0
- vendor/toolset/toolset-common/inc/m2m/{relationship_role → relationship/role}/intermediary.php +0 -0
- vendor/toolset/toolset-common/inc/m2m/{relationship_role → relationship/role}/parent.php +0 -0
- vendor/toolset/toolset-common/inc/m2m/{relationship_role → relationship/role}/parent_child_interface.php +0 -0
- vendor/toolset/toolset-common/inc/m2m/{relationship_role → relationship/role}/role.php +64 -0
- vendor/toolset/toolset-common/inc/m2m/{scope.php → relationship/scope.php} +0 -0
- vendor/toolset/toolset-common/inc/m2m/{slug_validator.php → relationship/slug_validator.php} +0 -0
- vendor/toolset/toolset-common/inc/m2m/utils.php +26 -0
- vendor/toolset/toolset-common/inc/m2m/wpml_interoperability.php +0 -645
- vendor/toolset/toolset-common/inc/public_api/legacy_relationships.php +338 -0
- vendor/toolset/toolset-common/inc/public_api/loader.php +35 -0
- vendor/toolset/toolset-common/inc/public_api/m2m.php +309 -0
- vendor/toolset/toolset-common/inc/toolset.ajax.class.php +128 -53
- vendor/toolset/toolset-common/inc/toolset.assets.manager.class.php +50 -2
- vendor/toolset/toolset-common/inc/toolset.css.component.class.php +2 -1
- vendor/toolset/toolset-common/inc/toolset.menu.class.php +6 -6
- vendor/toolset/toolset-common/inc/toolset.shortcode.generator.class.php +133 -159
- vendor/toolset/toolset-common/inc/toolset.wpml.compatibility.class.php +380 -12
- vendor/toolset/toolset-common/lib/whip/CHANGELOG.md +34 -0
- vendor/toolset/toolset-common/lib/whip/LICENSE +21 -0
- vendor/toolset/toolset-common/lib/whip/README.md +94 -0
- vendor/toolset/toolset-common/lib/whip/src/Whip_Configuration.php +54 -0
- vendor/toolset/toolset-common/lib/whip/src/Whip_Host.php +88 -0
- vendor/toolset/toolset-common/lib/whip/src/Whip_MessageDismisser.php +45 -0
- vendor/toolset/toolset-common/lib/whip/src/Whip_MessageFormatter.php +37 -0
- vendor/toolset/toolset-common/lib/whip/src/Whip_MessagesManager.php +83 -0
- vendor/toolset/toolset-common/lib/whip/src/Whip_RequirementsChecker.php +148 -0
- vendor/toolset/toolset-common/lib/whip/src/Whip_VersionRequirement.php +133 -0
- vendor/toolset/toolset-common/lib/whip/src/Whip_WPDismissOption.php +36 -0
- vendor/toolset/toolset-common/lib/whip/src/Whip_WPMessageDismissListener.php +51 -0
- vendor/toolset/toolset-common/lib/whip/src/configs/default.php +5 -0
- vendor/toolset/toolset-common/lib/whip/src/configs/version.php +3 -0
- vendor/toolset/toolset-common/lib/whip/src/exceptions/Whip_EmptyProperty.php +10 -0
- vendor/toolset/toolset-common/lib/whip/src/exceptions/Whip_InvalidOperatorType.php +22 -0
- vendor/toolset/toolset-common/lib/whip/src/exceptions/Whip_InvalidType.php +18 -0
- vendor/toolset/toolset-common/lib/whip/src/exceptions/Whip_InvalidVersionComparisonString.php +19 -0
- vendor/toolset/toolset-common/lib/whip/src/facades/wordpress.php +36 -0
- vendor/toolset/toolset-common/lib/whip/src/interfaces/Whip_DismissStorage.php +24 -0
- vendor/toolset/toolset-common/lib/whip/src/interfaces/Whip_Listener.php +15 -0
- vendor/toolset/toolset-common/lib/whip/src/interfaces/Whip_Message.php +8 -0
- vendor/toolset/toolset-common/lib/whip/src/interfaces/Whip_MessagePresenter.php +10 -0
- vendor/toolset/toolset-common/lib/whip/src/interfaces/Whip_Requirement.php +8 -0
- vendor/toolset/toolset-common/lib/whip/src/interfaces/Whip_VersionDetector.php +21 -0
- vendor/toolset/toolset-common/lib/whip/src/messages/Whip_BasicMessage.php +42 -0
- vendor/toolset/toolset-common/lib/whip/src/messages/Whip_HostMessage.php +56 -0
- vendor/toolset/toolset-common/lib/whip/src/messages/Whip_InvalidVersionRequirementMessage.php +37 -0
- vendor/toolset/toolset-common/lib/whip/src/messages/Whip_NullMessage.php +13 -0
- vendor/toolset/toolset-common/lib/whip/src/messages/Whip_UpgradePhpMessage.php +50 -0
- vendor/toolset/toolset-common/lib/whip/src/presenters/Whip_WPMessagePresenter.php +83 -0
- vendor/toolset/toolset-common/loader.php +2 -2
- vendor/toolset/toolset-common/recreate_classmap.sh +2 -1
- vendor/toolset/toolset-common/res/css/toolset-dialogs.css +86 -8
- vendor/toolset/toolset-common/res/css/toolset-notifications.css +10 -0
- vendor/toolset/toolset-common/res/js/toolset-bs-component-grids.js +8 -0
- vendor/toolset/toolset-common/res/js/toolset-media-manager.js +152 -0
- vendor/toolset/toolset-common/res/js/toolset-shortcode.js +155 -23
- vendor/toolset/toolset-common/res/lib/parsley/parsley.css +33 -0
- vendor/toolset/toolset-common/res/lib/parsley/parsley.js +2438 -0
application/autoload_classmap.php
CHANGED
@@ -46,15 +46,15 @@ return array(
|
|
46 |
'Types_Field_Group_User_Factory' => dirname( __FILE__ ) . '/models/field/group/user_factory.php',
|
47 |
'Types_Fields_Conditional' => dirname( __FILE__ ) . '/../vendor/toolset/types/includes/classes/class.types.fields.conditional.php',
|
48 |
'Types_Field_Type_Converter' => dirname( __FILE__ ) . '/controllers/field/type_converter.php',
|
49 |
-
'Types_Field_Type_Definition_Checkbox' => dirname( __FILE__ ) . '/models/field/
|
50 |
-
'Types_Field_Type_Definition_Checkboxes' => dirname( __FILE__ ) . '/models/field/
|
51 |
-
'Types_Field_Type_Definition_Date' => dirname( __FILE__ ) . '/models/field/
|
52 |
'Types_Field_Type_Definition' => dirname( __FILE__ ) . '/models/field/type/definition.php',
|
53 |
'Types_Field_Type_Definition_Factory' => dirname( __FILE__ ) . '/models/field/type/definition_factory.php',
|
54 |
-
'Types_Field_Type_Definition_Numeric' => dirname( __FILE__ ) . '/models/field/
|
55 |
-
'Types_Field_Type_Definition_Radio' => dirname( __FILE__ ) . '/models/field/
|
56 |
-
'Types_Field_Type_Definition_Select' => dirname( __FILE__ ) . '/models/field/
|
57 |
-
'Types_Field_Type_Definition_Singular' => dirname( __FILE__ ) . '/models/field/
|
58 |
'Types_Field_Utils' => dirname( __FILE__ ) . '/controllers/field/utils.php',
|
59 |
'Types_Frontend' => dirname( __FILE__ ) . '/controllers/frontend.php',
|
60 |
'Types_Helper_Condition_Archive_Exists' => dirname( __FILE__ ) . '/models/helper/condition/archive/exists.php',
|
@@ -133,7 +133,7 @@ return array(
|
|
133 |
'Types_Taxonomy' => dirname( __FILE__ ) . '/models/taxonomy.php',
|
134 |
'Types_Twig_Autoloader' => dirname( __FILE__ ) . '/controllers/twig_autoloader.php',
|
135 |
'Types_Upgrade' => dirname( __FILE__ ) . '/controllers/upgrade.php',
|
136 |
-
'Types_Utils' => dirname( __FILE__ ) . '/controllers/
|
137 |
'Types_Utils_Post_Type_Option' => dirname( __FILE__ ) . '/controllers/utils/post_type_option.php',
|
138 |
'Types_Wpml_Field_Group' => dirname( __FILE__ ) . '/models/wpml/field_group.php',
|
139 |
'Types_Wpml_Field_Group_String_Description' => dirname( __FILE__ ) . '/models/wpml/field/group/string/description.php',
|
46 |
'Types_Field_Group_User_Factory' => dirname( __FILE__ ) . '/models/field/group/user_factory.php',
|
47 |
'Types_Fields_Conditional' => dirname( __FILE__ ) . '/../vendor/toolset/types/includes/classes/class.types.fields.conditional.php',
|
48 |
'Types_Field_Type_Converter' => dirname( __FILE__ ) . '/controllers/field/type_converter.php',
|
49 |
+
'Types_Field_Type_Definition_Checkbox' => dirname( __FILE__ ) . '/models/field/gateway/checkbox.php',
|
50 |
+
'Types_Field_Type_Definition_Checkboxes' => dirname( __FILE__ ) . '/models/field/gateway/checkboxes.php',
|
51 |
+
'Types_Field_Type_Definition_Date' => dirname( __FILE__ ) . '/models/field/gateway/date.php',
|
52 |
'Types_Field_Type_Definition' => dirname( __FILE__ ) . '/models/field/type/definition.php',
|
53 |
'Types_Field_Type_Definition_Factory' => dirname( __FILE__ ) . '/models/field/type/definition_factory.php',
|
54 |
+
'Types_Field_Type_Definition_Numeric' => dirname( __FILE__ ) . '/models/field/gateway/numeric.php',
|
55 |
+
'Types_Field_Type_Definition_Radio' => dirname( __FILE__ ) . '/models/field/gateway/radio.php',
|
56 |
+
'Types_Field_Type_Definition_Select' => dirname( __FILE__ ) . '/models/field/gateway/select.php',
|
57 |
+
'Types_Field_Type_Definition_Singular' => dirname( __FILE__ ) . '/models/field/gateway/singular.php',
|
58 |
'Types_Field_Utils' => dirname( __FILE__ ) . '/controllers/field/utils.php',
|
59 |
'Types_Frontend' => dirname( __FILE__ ) . '/controllers/frontend.php',
|
60 |
'Types_Helper_Condition_Archive_Exists' => dirname( __FILE__ ) . '/models/helper/condition/archive/exists.php',
|
133 |
'Types_Taxonomy' => dirname( __FILE__ ) . '/models/taxonomy.php',
|
134 |
'Types_Twig_Autoloader' => dirname( __FILE__ ) . '/controllers/twig_autoloader.php',
|
135 |
'Types_Upgrade' => dirname( __FILE__ ) . '/controllers/upgrade.php',
|
136 |
+
'Types_Utils' => dirname( __FILE__ ) . '/controllers/admin_notice/utils.php',
|
137 |
'Types_Utils_Post_Type_Option' => dirname( __FILE__ ) . '/controllers/utils/post_type_option.php',
|
138 |
'Types_Wpml_Field_Group' => dirname( __FILE__ ) . '/models/wpml/field_group.php',
|
139 |
'Types_Wpml_Field_Group_String_Description' => dirname( __FILE__ ) . '/models/wpml/field/group/string/description.php',
|
application/controllers/{utils → admin_notice}/utils.php
RENAMED
File without changes
|
application/controllers/ajax.php
CHANGED
@@ -3,237 +3,74 @@
|
|
3 |
/**
|
4 |
* Main AJAX call controller for Types.
|
5 |
*
|
6 |
-
*
|
7 |
*
|
8 |
-
*
|
9 |
*
|
10 |
-
*
|
11 |
-
* can be used.
|
12 |
-
* 2. Action names (without a prefix) should be defined as constants, and be part of the Types_Ajax::$callbacks array.
|
13 |
-
* 3. For each action, there should be a dedicated class implementing the Types_Ajax_Handler_Interface. Name of the class
|
14 |
-
* must be Types_Ajax_Handler_{%capitalized_action_name}. So for example, for a hook to
|
15 |
-
* 'wp_ajax_types_field_control_action' you need to create a class 'Types_Ajax_Handler_Field_Control_Action'.
|
16 |
-
* 4. All callbacks must use the ajax_begin() and ajax_finish() methods.
|
17 |
*
|
18 |
* @since 2.0
|
19 |
*/
|
20 |
-
|
|
|
21 |
|
22 |
// Action names
|
23 |
const CALLBACK_FIELD_CONTROL_ACTION = 'field_control_action';
|
24 |
const CALLBACK_CHECK_SLUG_CONFLICTS = 'check_slug_conflicts';
|
25 |
-
const CALLBACK_SETTINGS_ACTION
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
const
|
30 |
-
|
31 |
-
|
32 |
-
const
|
33 |
-
|
34 |
-
const DELIMITER = '_';
|
35 |
-
|
36 |
-
|
37 |
-
private static $instance;
|
38 |
-
|
39 |
-
|
40 |
-
public static function get_instance() {
|
41 |
-
if( null == self::$instance ) {
|
42 |
-
self::$instance = new self();
|
43 |
-
}
|
44 |
-
return self::$instance;
|
45 |
-
}
|
46 |
-
|
47 |
-
|
48 |
-
public static function initialize() {
|
49 |
-
$instance = self::get_instance();
|
50 |
-
|
51 |
-
$instance->register_callbacks();
|
52 |
-
$instance->additional_ajax_init();
|
53 |
-
}
|
54 |
-
|
55 |
-
|
56 |
-
private function __clone() { }
|
57 |
-
|
58 |
-
|
59 |
-
private function __construct() { }
|
60 |
|
61 |
|
62 |
private static $callbacks = array(
|
63 |
self::CALLBACK_FIELD_CONTROL_ACTION,
|
64 |
self::CALLBACK_CHECK_SLUG_CONFLICTS,
|
65 |
self::CALLBACK_SETTINGS_ACTION,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
66 |
);
|
67 |
|
68 |
|
69 |
-
private $
|
70 |
|
71 |
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
* Each callback is registered as a "types_{$callback}" action and needs to have a "callback_{$callback_name}"
|
76 |
-
* method in this class.
|
77 |
-
*
|
78 |
-
* @since 2.0
|
79 |
-
*/
|
80 |
-
private function register_callbacks() {
|
81 |
-
|
82 |
-
if( $this->callbacks_registered ) {
|
83 |
-
return;
|
84 |
-
}
|
85 |
-
|
86 |
-
foreach( self::$callbacks as $callback_name ) {
|
87 |
-
add_action( 'wp_ajax_types_' . $callback_name, array( $this, self::CALLBACK_PREFIX . $callback_name ) );
|
88 |
-
}
|
89 |
-
|
90 |
-
$this->callbacks_registered = true;
|
91 |
-
|
92 |
-
}
|
93 |
-
|
94 |
-
|
95 |
-
public function get_action_js_name( $action ) {
|
96 |
-
return 'types_' . $action;
|
97 |
-
}
|
98 |
-
|
99 |
-
|
100 |
-
/**
|
101 |
-
* Handle a call to undefined method on this class, hopefully an AJAX call.
|
102 |
-
*
|
103 |
-
* @param string $name Method name.
|
104 |
-
* @param array $parameters Method parameters.
|
105 |
-
* @since 2.1
|
106 |
-
*/
|
107 |
-
public function __call( $name, $parameters ) {
|
108 |
-
// Check for the callback prefix in the method name
|
109 |
-
$name_parts = explode( self::DELIMITER, $name );
|
110 |
-
if( 0 !== strcmp( $name_parts[0] . self::DELIMITER, self::CALLBACK_PREFIX ) ) {
|
111 |
-
// Not a callback, resign.
|
112 |
-
return;
|
113 |
-
}
|
114 |
-
|
115 |
-
// Deduct the handler class name from the callback name
|
116 |
-
unset( $name_parts[0] );
|
117 |
-
$class_name = implode( self::DELIMITER, $name_parts );
|
118 |
-
$class_name = strtolower( $class_name );
|
119 |
-
$class_name = mb_convert_case( $class_name, MB_CASE_TITLE );
|
120 |
-
$class_name = self::HANDLER_CLASS_PREFIX . $class_name;
|
121 |
-
|
122 |
-
// Obtain an instance of the handler class.
|
123 |
-
try {
|
124 |
-
/** @var Types_Ajax_Handler_Interface $handler */
|
125 |
-
$handler = new $class_name( $this );
|
126 |
-
} catch( Exception $e ) {
|
127 |
-
// The handler class could not have been instantiated, resign.
|
128 |
-
return;
|
129 |
-
}
|
130 |
-
|
131 |
-
// Success
|
132 |
-
$handler->process_call( $parameters );
|
133 |
-
}
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
/**
|
138 |
-
* Perform basic authentication check.
|
139 |
-
*
|
140 |
-
* Check user capability and nonce. Dies with an error message (wp_json_error() by default) if the authentization
|
141 |
-
* is not successful.
|
142 |
-
*
|
143 |
-
* @param array $args Arguments (
|
144 |
-
* @type string $nonce Name of the nonce that should be verified. Mandatory
|
145 |
-
* @type string $nonce_parameter Name of the parameter containing nonce value.
|
146 |
-
* Optional, defaults to "wpnonce".
|
147 |
-
* @type string $parameter_source Determines where the function should look for the nonce parameter.
|
148 |
-
* Allowed values are 'get' and 'post'. Optional, defaults to 'post'.
|
149 |
-
* @type string $capability_needed Capability that user has to have in order to pass the check.
|
150 |
-
* Optional, default is "manage_options".
|
151 |
-
* @type string $type_of_death How to indicate failure:
|
152 |
-
* - 'die': Call wp_json_error with array( 'type' => 'capability'|'nonce', 'message' => $error_message )
|
153 |
-
* - 'return': Do not die, just return the error array as above.
|
154 |
-
* Optional, default is 'die'.
|
155 |
-
* )
|
156 |
-
*
|
157 |
-
* @return array|void
|
158 |
-
*
|
159 |
-
* @since 2.0
|
160 |
-
*/
|
161 |
-
private function ajax_authenticate( $args = array() ) {
|
162 |
-
// Read arguments
|
163 |
-
$type_of_death = wpcf_getarr( $args, 'type_of_death', 'die', array( 'die', 'return' ) );
|
164 |
-
$nonce_name = wpcf_getarr( $args, 'nonce' );
|
165 |
-
$nonce_parameter = wpcf_getarr( $args, 'nonce_parameter', 'wpnonce' );
|
166 |
-
$capability_needed = wpcf_getarr( $args, 'capability_needed', 'manage_options' );
|
167 |
-
$parameter_source_name = wpcf_getarr( $args, 'parameter_source', 'post', array( 'get', 'post' ) );
|
168 |
-
$parameter_source = ( $parameter_source_name == 'get' ) ? $_GET : $_POST;
|
169 |
-
|
170 |
-
$is_error = false;
|
171 |
-
$error_message = null;
|
172 |
-
$error_type = null;
|
173 |
-
|
174 |
-
// Check permissions
|
175 |
-
if ( ! current_user_can( $capability_needed ) ) {
|
176 |
-
$error_message = __( 'You do not have permissions for that.', 'wpcf' );
|
177 |
-
$error_type = 'capability';
|
178 |
-
$is_error = true;
|
179 |
-
}
|
180 |
-
|
181 |
-
// Check nonce
|
182 |
-
if ( !$is_error && !wp_verify_nonce( wpcf_getarr( $parameter_source, $nonce_parameter, '' ), $nonce_name ) ) {
|
183 |
-
$error_message = __( 'Your security credentials have expired. Please reload the page to get new ones.', 'wpcf' );
|
184 |
-
$error_type = 'nonce';
|
185 |
-
$is_error = true;
|
186 |
-
}
|
187 |
-
|
188 |
-
if( $is_error ) {
|
189 |
-
$error_description = array( 'type' => $error_type, 'message' => $error_message );
|
190 |
-
switch( $type_of_death ) {
|
191 |
-
|
192 |
-
case 'die':
|
193 |
-
wp_send_json_error( $error_description );
|
194 |
-
break;
|
195 |
-
|
196 |
-
case 'return':
|
197 |
-
default:
|
198 |
-
return $error_description;
|
199 |
-
}
|
200 |
}
|
201 |
-
|
202 |
-
return true;
|
203 |
}
|
204 |
|
205 |
-
|
206 |
/**
|
207 |
-
*
|
208 |
-
*
|
209 |
-
*
|
210 |
-
*
|
211 |
-
* @param array $args See ajax_authenticate for details
|
212 |
-
* @return array|void
|
213 |
-
* @since 2.0
|
214 |
*/
|
215 |
-
|
216 |
-
return
|
217 |
}
|
218 |
|
219 |
|
220 |
/**
|
221 |
-
*
|
222 |
-
*
|
223 |
-
*
|
224 |
-
*
|
225 |
-
* To be extended in the future.
|
226 |
-
*
|
227 |
-
* @param array $response Custom response data
|
228 |
-
* @param bool $is_success
|
229 |
-
* @since 2.0
|
230 |
*/
|
231 |
-
|
232 |
-
|
233 |
-
wp_send_json_success( $response );
|
234 |
-
} else {
|
235 |
-
wp_send_json_error( $response );
|
236 |
-
}
|
237 |
}
|
238 |
|
239 |
|
@@ -245,7 +82,7 @@ final class Types_Ajax {
|
|
245 |
*
|
246 |
* @since 2.1
|
247 |
*/
|
248 |
-
|
249 |
|
250 |
// On the Add Term page, we need to initialize the page controller WPCF_GUI_Term_Field_Editing
|
251 |
// so that it saves term fields (if there are any).
|
@@ -258,7 +95,7 @@ final class Types_Ajax {
|
|
258 |
// in those functions are set to true (which means that the call was not handled).
|
259 |
add_action( 'wp_ajax_wpcf_ajax', array( $this, 'do_legacy_wpcf_ajax' ) );
|
260 |
}
|
261 |
-
|
262 |
|
263 |
/**
|
264 |
* On the Add Term page, we need to initialize the page controller WPCF_GUI_Term_Field_Editing
|
@@ -275,8 +112,8 @@ final class Types_Ajax {
|
|
275 |
// to edit-{$taxonomy}. When creating the term on the post edit page, for example, the screen is not set. We use
|
276 |
// this to further limit the resource wasting. However, initializing the controller even if it's not supposed to
|
277 |
// will not lead to any errors - it gives up gracefully.
|
278 |
-
$action =
|
279 |
-
$screen =
|
280 |
if( 'add-tag' == $action && null !== $screen ) {
|
281 |
WPCF_GUI_Term_Field_Editing::initialize();
|
282 |
}
|
3 |
/**
|
4 |
* Main AJAX call controller for Types.
|
5 |
*
|
6 |
+
* This class can be used in any way only after the Common Library is loaded.
|
7 |
*
|
8 |
+
* Please read the important usage instructions for the superclass:
|
9 |
*
|
10 |
+
* @inheritdoc
|
|
|
|
|
|
|
|
|
|
|
|
|
11 |
*
|
12 |
* @since 2.0
|
13 |
*/
|
14 |
+
class Types_Ajax extends Toolset_Ajax {
|
15 |
+
const HANDLER_CLASS_PREFIX = 'Types_Ajax_Handler_';
|
16 |
|
17 |
// Action names
|
18 |
const CALLBACK_FIELD_CONTROL_ACTION = 'field_control_action';
|
19 |
const CALLBACK_CHECK_SLUG_CONFLICTS = 'check_slug_conflicts';
|
20 |
+
const CALLBACK_SETTINGS_ACTION = 'settings_action';
|
21 |
+
const CALLBACK_M2M_MIGRATION_PREVIEW_RELATIONSHIPS = 'm2m_migration_preview_relationships';
|
22 |
+
const CALLBACK_M2M_MIGRATION_PREVIEW_ASSOCIATIONS = 'm2m_migration_preview_associations';
|
23 |
+
const CALLBACK_CUSTOM_FIELDS_ACTION = 'custom_fields_action';
|
24 |
+
const CALLBACK_RELATIONSHIPS_ACTION = 'relationships_action';
|
25 |
+
const CALLBACK_RELATED_CONTENT_ACTION = 'related_content_action';
|
26 |
+
const CALLBACK_FIELD_GROUP_EDIT_ACTION = 'field_group_edit_action';
|
27 |
+
const CALLBACK_REPEATABLE_GROUP = 'repeatable_group';
|
28 |
+
const CALLBACK_POST_REFERENCE_FIELD = 'post_reference_field';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
|
30 |
|
31 |
private static $callbacks = array(
|
32 |
self::CALLBACK_FIELD_CONTROL_ACTION,
|
33 |
self::CALLBACK_CHECK_SLUG_CONFLICTS,
|
34 |
self::CALLBACK_SETTINGS_ACTION,
|
35 |
+
self::CALLBACK_M2M_MIGRATION_PREVIEW_RELATIONSHIPS,
|
36 |
+
self::CALLBACK_M2M_MIGRATION_PREVIEW_ASSOCIATIONS,
|
37 |
+
self::CALLBACK_CUSTOM_FIELDS_ACTION,
|
38 |
+
self::CALLBACK_RELATIONSHIPS_ACTION,
|
39 |
+
self::CALLBACK_RELATED_CONTENT_ACTION,
|
40 |
+
self::CALLBACK_FIELD_GROUP_EDIT_ACTION,
|
41 |
+
self::CALLBACK_REPEATABLE_GROUP,
|
42 |
+
self::CALLBACK_POST_REFERENCE_FIELD,
|
43 |
);
|
44 |
|
45 |
|
46 |
+
private static $types_instance;
|
47 |
|
48 |
|
49 |
+
public static function get_instance() {
|
50 |
+
if( null === self::$types_instance ) {
|
51 |
+
self::$types_instance = new self();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
52 |
}
|
53 |
+
return self::$types_instance;
|
|
|
54 |
}
|
55 |
|
|
|
56 |
/**
|
57 |
+
* @inheritdoc
|
58 |
+
* @param bool $capitalized
|
59 |
+
* @return string
|
60 |
+
* @since m2m
|
|
|
|
|
|
|
61 |
*/
|
62 |
+
protected function get_plugin_slug( $capitalized = false ) {
|
63 |
+
return ( $capitalized ? 'Types' : 'types' );
|
64 |
}
|
65 |
|
66 |
|
67 |
/**
|
68 |
+
* @inheritdoc
|
69 |
+
* @return array
|
70 |
+
* @since m2m
|
|
|
|
|
|
|
|
|
|
|
|
|
71 |
*/
|
72 |
+
protected function get_callback_names() {
|
73 |
+
return self::$callbacks;
|
|
|
|
|
|
|
|
|
74 |
}
|
75 |
|
76 |
|
82 |
*
|
83 |
* @since 2.1
|
84 |
*/
|
85 |
+
protected function additional_ajax_init() {
|
86 |
|
87 |
// On the Add Term page, we need to initialize the page controller WPCF_GUI_Term_Field_Editing
|
88 |
// so that it saves term fields (if there are any).
|
95 |
// in those functions are set to true (which means that the call was not handled).
|
96 |
add_action( 'wp_ajax_wpcf_ajax', array( $this, 'do_legacy_wpcf_ajax' ) );
|
97 |
}
|
98 |
+
|
99 |
|
100 |
/**
|
101 |
* On the Add Term page, we need to initialize the page controller WPCF_GUI_Term_Field_Editing
|
112 |
// to edit-{$taxonomy}. When creating the term on the post edit page, for example, the screen is not set. We use
|
113 |
// this to further limit the resource wasting. However, initializing the controller even if it's not supposed to
|
114 |
// will not lead to any errors - it gives up gracefully.
|
115 |
+
$action = toolset_getpost( 'action' );
|
116 |
+
$screen = toolset_getpost( 'screen', null );
|
117 |
if( 'add-tag' == $action && null !== $screen ) {
|
118 |
WPCF_GUI_Term_Field_Editing::initialize();
|
119 |
}
|
application/controllers/asset/manager.php
CHANGED
@@ -25,11 +25,19 @@ final class Types_Asset_Manager extends Toolset_Assets_Manager {
|
|
25 |
const SCRIPT_ADDITIONAL_VALIDATION_RULES = 'wpcf-form-validation-additional';
|
26 |
|
27 |
|
|
|
|
|
|
|
|
|
28 |
/**
|
29 |
* @return Types_Asset_Manager
|
30 |
*/
|
31 |
static public function get_instance() {
|
32 |
-
|
|
|
|
|
|
|
|
|
33 |
}
|
34 |
|
35 |
|
25 |
const SCRIPT_ADDITIONAL_VALIDATION_RULES = 'wpcf-form-validation-additional';
|
26 |
|
27 |
|
28 |
+
|
29 |
+
private static $types_instance;
|
30 |
+
|
31 |
+
|
32 |
/**
|
33 |
* @return Types_Asset_Manager
|
34 |
*/
|
35 |
static public function get_instance() {
|
36 |
+
if( null === self::$types_instance ) {
|
37 |
+
self::$types_instance = new self();
|
38 |
+
}
|
39 |
+
|
40 |
+
return self::$types_instance;
|
41 |
}
|
42 |
|
43 |
|
application/models/field/{type/definition → gateway}/checkbox.php
RENAMED
File without changes
|
application/models/field/{type/definition → gateway}/checkboxes.php
RENAMED
File without changes
|
application/models/field/{type/definition → gateway}/date.php
RENAMED
File without changes
|
application/models/field/{type/definition → gateway}/numeric.php
RENAMED
File without changes
|
application/models/field/{type/definition → gateway}/radio.php
RENAMED
File without changes
|
application/models/field/{type/definition → gateway}/select.php
RENAMED
File without changes
|
application/models/field/{type/definition → gateway}/singular.php
RENAMED
File without changes
|
readme.txt
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
=== Toolset Types - Custom Post Types, Custom Fields and Taxonomies ===
|
2 |
-
Contributors: AmirHelzer, brucepearson, christianglingener, jadpm, zaantar
|
3 |
Donate link: http://wp-types.com
|
4 |
Tags: CMS, custom field, custom fields, custom post type, custom post types, field, fields post, post type, post types, taxonomies, taxonomy, toolset
|
5 |
Text Domain: wpcf
|
@@ -7,7 +7,7 @@ Domain Path: /embedded/locale
|
|
7 |
License: GPLv2
|
8 |
Requires at least: 3.7
|
9 |
Tested up to: 4.9
|
10 |
-
Stable tag: 2.2.
|
11 |
|
12 |
The complete and reliable plugin for managing custom post types, custom taxonomies and custom fields.
|
13 |
|
@@ -158,6 +158,12 @@ Additionally, Types is the only plugin that lets you define parent/child relatio
|
|
158 |
|
159 |
== Changelog ==
|
160 |
|
|
|
|
|
|
|
|
|
|
|
|
|
161 |
= 2.2.21 =
|
162 |
* Fixed a compatibility issue with Beaver Builder
|
163 |
* Fixed an issue with extra backslashes when using quotes in field name
|
1 |
=== Toolset Types - Custom Post Types, Custom Fields and Taxonomies ===
|
2 |
+
Contributors: AmirHelzer, brucepearson, christianglingener, jadpm, zaantar, jmilczarek, kouratoras, displaynone
|
3 |
Donate link: http://wp-types.com
|
4 |
Tags: CMS, custom field, custom fields, custom post type, custom post types, field, fields post, post type, post types, taxonomies, taxonomy, toolset
|
5 |
Text Domain: wpcf
|
7 |
License: GPLv2
|
8 |
Requires at least: 3.7
|
9 |
Tested up to: 4.9
|
10 |
+
Stable tag: 2.2.22
|
11 |
|
12 |
The complete and reliable plugin for managing custom post types, custom taxonomies and custom fields.
|
13 |
|
158 |
|
159 |
== Changelog ==
|
160 |
|
161 |
+
= 2.2.22 =
|
162 |
+
* First version of the public relationship API that will be sustainable also for many-to-many relationships.
|
163 |
+
* Added a warning about dropping the PHP 5.2 support (which is no longer officially supported anyway) in the near future.
|
164 |
+
* Fixed: Using the_title filter without the mandatory $id argument.
|
165 |
+
* Fixed: Deprecated function notice in PHP 7.2.
|
166 |
+
|
167 |
= 2.2.21 =
|
168 |
* Fixed a compatibility issue with Beaver Builder
|
169 |
* Fixed an issue with extra backslashes when using quotes in field name
|
vendor/autoload.php
CHANGED
@@ -4,4 +4,4 @@
|
|
4 |
|
5 |
require_once __DIR__ . '/composer/autoload_real.php';
|
6 |
|
7 |
-
return
|
4 |
|
5 |
require_once __DIR__ . '/composer/autoload_real.php';
|
6 |
|
7 |
+
return ComposerAutoloaderInitc3c1dc77e2581741c891ff7b2bf920aa::getLoader();
|
vendor/composer/autoload_classmap.php
CHANGED
@@ -96,24 +96,33 @@ return array(
|
|
96 |
'FieldFactory' => $vendorDir . '/toolset/toolset-common/toolset-forms/classes/class.field_factory.php',
|
97 |
'FormAbstract' => $vendorDir . '/toolset/toolset-common/toolset-forms/classes/abstract.form.php',
|
98 |
'FormFactory' => $vendorDir . '/toolset/toolset-common/toolset-forms/classes/class.form_factory.php',
|
99 |
-
'IToolset_Association' => $vendorDir . '/toolset/toolset-common/inc/m2m/
|
|
|
|
|
|
|
|
|
|
|
|
|
100 |
'IToolset_Element' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/element/i_element.php',
|
|
|
101 |
'IToolset_Post' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/element/i_post.php',
|
102 |
'IToolset_Post_Type' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/post_type/i_post_type.php',
|
103 |
'IToolset_Post_Type_From_Types' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/post_type/i_post_type_from_types.php',
|
104 |
'IToolset_Post_Type_Registered' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/post_type/i_post_type_registered.php',
|
105 |
'IToolset_Potential_Association_Query' => $vendorDir . '/toolset/toolset-common/inc/m2m/potential_association/query_interface.php',
|
106 |
'IToolset_Query' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/i_query.php',
|
|
|
107 |
'IToolset_Relationship_Database_Issue' => $vendorDir . '/toolset/toolset-common/inc/m2m/database/issue/interface.php',
|
108 |
-
'IToolset_Relationship_Definition' => $vendorDir . '/toolset/toolset-common/inc/m2m/definition/interface.php',
|
109 |
'IToolset_Relationship_Origin' => $vendorDir . '/toolset/toolset-common/inc/m2m/origin/interface.php',
|
110 |
-
'IToolset_Relationship_Query_Cardinality_Match' => $vendorDir . '/toolset/toolset-common/inc/m2m/
|
111 |
-
'IToolset_Relationship_Query_Condition' => $vendorDir . '/toolset/toolset-common/inc/m2m/
|
112 |
-
'IToolset_Relationship_Role' => $vendorDir . '/toolset/toolset-common/inc/m2m/
|
113 |
-
'IToolset_Relationship_Role_Parent_Child' => $vendorDir . '/toolset/toolset-common/inc/m2m/
|
114 |
'IToolset_Upgrade_Command' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/upgrade/command_interface.php',
|
115 |
'ReCaptchaResponse' => $vendorDir . '/toolset/toolset-common/toolset-forms/js/recaptcha-php-1.11/recaptchalib.php',
|
116 |
'Toolset_Admin_Bar_Menu' => $vendorDir . '/toolset/toolset-common/inc/toolset.admin.bar.menu.class.php',
|
|
|
117 |
'Toolset_Admin_Notice_Abstract' => $vendorDir . '/toolset/toolset-common/utility/admin/notice/abstract.php',
|
118 |
'Toolset_Admin_Notice_Dismissible' => $vendorDir . '/toolset/toolset-common/utility/admin/notice/dismissible.php',
|
119 |
'Toolset_Admin_Notice_Error' => $vendorDir . '/toolset/toolset-common/utility/admin/notice/error.php',
|
@@ -126,17 +135,72 @@ return array(
|
|
126 |
'Toolset_Admin_Notices_Manager' => $vendorDir . '/toolset/toolset-common/utility/admin/notices/manager.php',
|
127 |
'Toolset_Ajax' => $vendorDir . '/toolset/toolset-common/inc/toolset.ajax.class.php',
|
128 |
'Toolset_Ajax_Handler_Abstract' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/ajax_handler/abstract.php',
|
|
|
|
|
|
|
|
|
|
|
129 |
'Toolset_Ajax_Handler_Interface' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/ajax_handler/interface.php',
|
|
|
130 |
'Toolset_Ajax_Handler_Migrate_To_M2M' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/ajax_handler/migrate_to_m2m.php',
|
|
|
|
|
|
|
131 |
'Toolset_ArrayUtils' => $vendorDir . '/toolset/toolset-common/utility/utils.php',
|
132 |
-
'Toolset_Asset_Manager' => $vendorDir . '/toolset/toolset-common/inc/
|
133 |
'Toolset_Assets_Manager' => $vendorDir . '/toolset/toolset-common/inc/toolset.assets.manager.class.php',
|
134 |
-
'Toolset_Association' => $vendorDir . '/toolset/toolset-common/inc/m2m/association.php',
|
135 |
-
'
|
136 |
-
'
|
137 |
-
'
|
138 |
-
'
|
139 |
-
'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
140 |
'Toolset_Bootstrap_Loader' => $vendorDir . '/toolset/toolset-common/inc/toolset.bootstrap.loader.class.php',
|
141 |
'Toolset_Common_Autoloader' => $vendorDir . '/toolset/toolset-common/utility/autoloader.php',
|
142 |
'Toolset_Common_Bootstrap' => $vendorDir . '/toolset/toolset-common/bootstrap.php',
|
@@ -150,11 +214,14 @@ return array(
|
|
150 |
'Toolset_Condition_Plugin_Layouts_Missing' => $vendorDir . '/toolset/toolset-common/utility/condition/plugin/layouts/missing.php',
|
151 |
'Toolset_Condition_Plugin_Layouts_No_Items' => $vendorDir . '/toolset/toolset-common/utility/condition/plugin/layouts/no-items.php',
|
152 |
'Toolset_Condition_Plugin_Types_Active' => $vendorDir . '/toolset/toolset-common/utility/condition/plugin/types/active.php',
|
|
|
153 |
'Toolset_Condition_Plugin_Types_Missing' => $vendorDir . '/toolset/toolset-common/utility/condition/plugin/types/missing.php',
|
154 |
'Toolset_Condition_Plugin_Types_Ready_For_M2M' => $vendorDir . '/toolset/toolset-common/utility/condition/plugin/types/ready_for_m2m.php',
|
155 |
'Toolset_Condition_Plugin_Views_Active' => $vendorDir . '/toolset/toolset-common/utility/condition/plugin/views/active.php',
|
156 |
'Toolset_Condition_Plugin_Views_Missing' => $vendorDir . '/toolset/toolset-common/utility/condition/plugin/views/missing.php',
|
157 |
'Toolset_Condition_Plugin_Wpml_Doesnt_Support_M2m' => $vendorDir . '/toolset/toolset-common/utility/condition/plugin/wpml/doesnt_support_m2m.php',
|
|
|
|
|
158 |
'Toolset_Condition_Theme_Avada_Not_Active_Or_Greater_Equal_5_0' => $vendorDir . '/toolset/toolset-common/utility/condition/theme/avada/not-active-or-greater-equal-5-0.php',
|
159 |
'Toolset_Condition_Theme_Layouts_Support_Native_Available' => $vendorDir . '/toolset/toolset-common/utility/condition/theme/layouts-support/native/available.php',
|
160 |
'Toolset_Condition_Theme_Layouts_Support_Native_Missing' => $vendorDir . '/toolset/toolset-common/utility/condition/theme/layouts-support/native/missing.php',
|
@@ -169,8 +236,10 @@ return array(
|
|
169 |
'Toolset_Condition_Theme_Toolset_Based_Active' => $vendorDir . '/toolset/toolset-common/utility/condition/theme/toolset-based/active.php',
|
170 |
'Toolset_Condition_Theme_Toolset_Based_Inactive' => $vendorDir . '/toolset/toolset-common/utility/condition/theme/toolset-based/inactive.php',
|
171 |
'Toolset_Condition_User_Role_Admin' => $vendorDir . '/toolset/toolset-common/utility/condition/user/role/admin.php',
|
172 |
-
'Toolset_Constants' => $vendorDir . '/toolset/toolset-common/inc/
|
173 |
-
'Toolset_Controller_Admin_Notices' => $vendorDir . '/toolset/toolset-common/inc/
|
|
|
|
|
174 |
'Toolset_CssComponent' => $vendorDir . '/toolset/toolset-common/inc/toolset.css.component.class.php',
|
175 |
'Toolset_Date' => $vendorDir . '/toolset/toolset-common/expression-parser/parser.php',
|
176 |
'Toolset_DateParser' => $vendorDir . '/toolset/toolset-common/expression-parser/parser.php',
|
@@ -196,10 +265,12 @@ return array(
|
|
196 |
'Toolset_Field_Definition' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/field/definition.php',
|
197 |
'Toolset_Field_Definition_Abstract' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/field/definition_abstract.php',
|
198 |
'Toolset_Field_Definition_Factory' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/field/definition_factory.php',
|
|
|
199 |
'Toolset_Field_Definition_Factory_Post' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/field/definition_factory_post.php',
|
200 |
'Toolset_Field_Definition_Factory_Term' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/field/definition_factory_term.php',
|
201 |
'Toolset_Field_Definition_Factory_User' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/field/definition_factory_user.php',
|
202 |
'Toolset_Field_Definition_Generic' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/field/definition_generic.php',
|
|
|
203 |
'Toolset_Field_Definition_Post' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/field/definition_post.php',
|
204 |
'Toolset_Field_Definition_Term' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/field/definition_term.php',
|
205 |
'Toolset_Field_Definition_User' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/field/definition_user.php',
|
@@ -245,6 +316,7 @@ return array(
|
|
245 |
'Toolset_Field_Type_Definition_Select' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/field/type/definition/select.php',
|
246 |
'Toolset_Field_Type_Definition_Singular' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/field/type/definition/singular.php',
|
247 |
'Toolset_Field_Utils' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/field/utils.php',
|
|
|
248 |
'Toolset_Functions' => $vendorDir . '/toolset/toolset-common/expression-parser/parser.php',
|
249 |
'Toolset_Gui_Base' => $vendorDir . '/toolset/toolset-common/utility/gui-base/main.php',
|
250 |
'Toolset_HelpVideo' => $vendorDir . '/toolset/toolset-common/utility/help-videos/toolset-help-videos.php',
|
@@ -254,9 +326,17 @@ return array(
|
|
254 |
'Toolset_Menu' => $vendorDir . '/toolset/toolset-common/inc/toolset.menu.class.php',
|
255 |
'Toolset_Naming_Helper' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/naming_helper.php',
|
256 |
'Toolset_Object_Relationship' => $vendorDir . '/toolset/toolset-common/inc/toolset.object.relationship.class.php',
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
257 |
'Toolset_Parser' => $vendorDir . '/toolset/toolset-common/expression-parser/parser.php',
|
258 |
'Toolset_Post' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/element/post.php',
|
259 |
'Toolset_Post_Translation_Set' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/element/post_translation_set.php',
|
|
|
260 |
'Toolset_Post_Type_Exclude_List' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/post_type/excluded_list.php',
|
261 |
'Toolset_Post_Type_Factory' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/post_type/factory.php',
|
262 |
'Toolset_Post_Type_From_Types' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/post_type/from_types.php',
|
@@ -268,63 +348,67 @@ return array(
|
|
268 |
'Toolset_Potential_Association_Query_Factory' => $vendorDir . '/toolset/toolset-common/inc/m2m/potential_association/query_factory.php',
|
269 |
'Toolset_Potential_Association_Query_Posts' => $vendorDir . '/toolset/toolset-common/inc/m2m/potential_association/query_posts.php',
|
270 |
'Toolset_Promotion' => $vendorDir . '/toolset/toolset-common/inc/toolset.promotion.class.php',
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
271 |
'Toolset_Regex' => $vendorDir . '/toolset/toolset-common/expression-parser/parser.php',
|
272 |
'Toolset_Relationship_Cardinality' => $vendorDir . '/toolset/toolset-common/inc/m2m/cardinality.php',
|
273 |
'Toolset_Relationship_Controller' => $vendorDir . '/toolset/toolset-common/inc/m2m/controller.php',
|
274 |
'Toolset_Relationship_Database_Issue_Missing_Element' => $vendorDir . '/toolset/toolset-common/inc/m2m/database/issue/missing_element.php',
|
275 |
'Toolset_Relationship_Database_Operations' => $vendorDir . '/toolset/toolset-common/inc/m2m/database/operations.php',
|
276 |
'Toolset_Relationship_Database_Unique_Table_Alias' => $vendorDir . '/toolset/toolset-common/inc/m2m/database/unique_table_alias.php',
|
277 |
-
'Toolset_Relationship_Definition' => $vendorDir . '/toolset/toolset-common/inc/m2m/definition/definition.php',
|
278 |
-
'Toolset_Relationship_Definition_Factory' => $vendorDir . '/toolset/toolset-common/inc/m2m/definition/factory.php',
|
279 |
-
'Toolset_Relationship_Definition_Persistence' => $vendorDir . '/toolset/toolset-common/inc/m2m/definition/persistence.php',
|
280 |
-
'Toolset_Relationship_Definition_Repository' => $vendorDir . '/toolset/toolset-common/inc/m2m/definition/repository.php',
|
281 |
-
'Toolset_Relationship_Definition_Translator' => $vendorDir . '/toolset/toolset-common/inc/m2m/definition/translator.php',
|
282 |
'Toolset_Relationship_Distinct_Post_Query' => $vendorDir . '/toolset/toolset-common/inc/m2m/potential_association/distinct_post_query.php',
|
283 |
'Toolset_Relationship_Driver' => $vendorDir . '/toolset/toolset-common/inc/m2m/driver.php',
|
284 |
'Toolset_Relationship_Driver_Base' => $vendorDir . '/toolset/toolset-common/inc/m2m/driver_base.php',
|
285 |
'Toolset_Relationship_Element_Type' => $vendorDir . '/toolset/toolset-common/inc/m2m/element_type.php',
|
286 |
-
'Toolset_Relationship_Migration' => $vendorDir . '/toolset/toolset-common/inc/m2m/migration.php',
|
287 |
-
'Toolset_Relationship_Migration_Associations' => $vendorDir . '/toolset/toolset-common/inc/m2m/
|
288 |
-
'
|
|
|
289 |
'Toolset_Relationship_Origin_Post_Reference_Field' => $vendorDir . '/toolset/toolset-common/inc/m2m/origin/post_reference_field.php',
|
290 |
'Toolset_Relationship_Origin_Repeatable_Group' => $vendorDir . '/toolset/toolset-common/inc/m2m/origin/repeatable_group.php',
|
291 |
'Toolset_Relationship_Origin_Wizard' => $vendorDir . '/toolset/toolset-common/inc/m2m/origin/wizard.php',
|
292 |
-
'Toolset_Relationship_Query' => $vendorDir . '/toolset/toolset-common/inc/m2m/
|
293 |
'Toolset_Relationship_Query_Base' => $vendorDir . '/toolset/toolset-common/inc/m2m/query_base.php',
|
294 |
'Toolset_Relationship_Query_Cache' => $vendorDir . '/toolset/toolset-common/inc/m2m/query_cache.php',
|
295 |
-
'Toolset_Relationship_Query_Cardinality_Match_Conjunction' => $vendorDir . '/toolset/toolset-common/inc/m2m/
|
296 |
-
'Toolset_Relationship_Query_Cardinality_Match_Factory' => $vendorDir . '/toolset/toolset-common/inc/m2m/
|
297 |
-
'Toolset_Relationship_Query_Cardinality_Match_Operators' => $vendorDir . '/toolset/toolset-common/inc/m2m/
|
298 |
-
'Toolset_Relationship_Query_Cardinality_Match_Single' => $vendorDir . '/toolset/toolset-common/inc/m2m/
|
299 |
-
'Toolset_Relationship_Query_Condition' => $vendorDir . '/toolset/toolset-common/inc/m2m/
|
300 |
-
'
|
301 |
-
'
|
302 |
-
'
|
303 |
-
'
|
304 |
-
'
|
305 |
-
'
|
306 |
-
'
|
307 |
-
'
|
308 |
-
'
|
309 |
-
'
|
310 |
-
'
|
311 |
-
'
|
312 |
-
'
|
313 |
-
'
|
314 |
-
'
|
315 |
-
'
|
316 |
-
'
|
317 |
-
'
|
318 |
-
'Toolset_Relationship_Role_Child' => $vendorDir . '/toolset/toolset-common/inc/m2m/relationship_role/child.php',
|
319 |
-
'Toolset_Relationship_Role_Intermediary' => $vendorDir . '/toolset/toolset-common/inc/m2m/relationship_role/intermediary.php',
|
320 |
-
'Toolset_Relationship_Role_Parent' => $vendorDir . '/toolset/toolset-common/inc/m2m/relationship_role/parent.php',
|
321 |
-
'Toolset_Relationship_Scope' => $vendorDir . '/toolset/toolset-common/inc/m2m/scope.php',
|
322 |
'Toolset_Relationship_Service' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/relationship_service.php',
|
323 |
-
'Toolset_Relationship_Slug_Validator' => $vendorDir . '/toolset/toolset-common/inc/m2m/slug_validator.php',
|
324 |
'Toolset_Relationship_Table_Name' => $vendorDir . '/toolset/toolset-common/inc/m2m/database/table_name.php',
|
325 |
'Toolset_Relationship_Utils' => $vendorDir . '/toolset/toolset-common/inc/m2m/utils.php',
|
326 |
-
'Toolset_Relationship_WPML_Interoperability' => $vendorDir . '/toolset/toolset-common/inc/m2m/wpml_interoperability.php',
|
327 |
'Toolset_Relevanssi_Compatibility' => $vendorDir . '/toolset/toolset-common/inc/toolset.relevanssi.compatibility.class.php',
|
|
|
328 |
'Toolset_Result' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/result.php',
|
329 |
'Toolset_Result_Set' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/result_set.php',
|
330 |
'Toolset_Result_Updated' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/result_updated.php',
|
@@ -340,6 +424,7 @@ return array(
|
|
340 |
'Toolset_Shortcode_Transformer' => $vendorDir . '/toolset/toolset-common/inc/toolset.shortcode.transformer.class.php',
|
341 |
'Toolset_Stack' => $vendorDir . '/toolset/toolset-common/expression-parser/parser.php',
|
342 |
'Toolset_Style' => $vendorDir . '/toolset/toolset-common/inc/toolset.assets.manager.class.php',
|
|
|
343 |
'Toolset_Tokenizer' => $vendorDir . '/toolset/toolset-common/expression-parser/parser.php',
|
344 |
'Toolset_Twig_Autoloader' => $vendorDir . '/toolset/toolset-common/utility/gui-base/twig_autoloader.php',
|
345 |
'Toolset_Twig_Dialog_Box' => $vendorDir . '/toolset/toolset-common/utility/gui-base/twig_dialog_box.php',
|
@@ -356,6 +441,7 @@ return array(
|
|
356 |
'Toolset_User_Editors_Editor_Basic' => $vendorDir . '/toolset/toolset-common/user-editors/editor/basic.php',
|
357 |
'Toolset_User_Editors_Editor_Beaver' => $vendorDir . '/toolset/toolset-common/user-editors/editor/beaver.php',
|
358 |
'Toolset_User_Editors_Editor_Divi' => $vendorDir . '/toolset/toolset-common/user-editors/editor/divi.php',
|
|
|
359 |
'Toolset_User_Editors_Editor_Interface' => $vendorDir . '/toolset/toolset-common/user-editors/editor/interface.php',
|
360 |
'Toolset_User_Editors_Editor_Native' => $vendorDir . '/toolset/toolset-common/user-editors/editor/native.php',
|
361 |
'Toolset_User_Editors_Editor_Screen_Abstract' => $vendorDir . '/toolset/toolset-common/user-editors/editor/screen/abstract.php',
|
@@ -366,6 +452,7 @@ return array(
|
|
366 |
'Toolset_User_Editors_Editor_Screen_Beaver_Frontend_Editor' => $vendorDir . '/toolset/toolset-common/user-editors/editor/screen/beaver/frontend-editor.php',
|
367 |
'Toolset_User_Editors_Editor_Screen_Divi_Backend' => $vendorDir . '/toolset/toolset-common/user-editors/editor/screen/divi/backend.php',
|
368 |
'Toolset_User_Editors_Editor_Screen_Divi_Frontend' => $vendorDir . '/toolset/toolset-common/user-editors/editor/screen/divi/frontend.php',
|
|
|
369 |
'Toolset_User_Editors_Editor_Screen_Interface' => $vendorDir . '/toolset/toolset-common/user-editors/editor/screen/interface.php',
|
370 |
'Toolset_User_Editors_Editor_Screen_Native_Backend' => $vendorDir . '/toolset/toolset-common/user-editors/editor/screen/native/backend.php',
|
371 |
'Toolset_User_Editors_Editor_Screen_Visual_Composer_Backend' => $vendorDir . '/toolset/toolset-common/user-editors/editor/screen/visual-composer/backend.php',
|
@@ -385,6 +472,12 @@ return array(
|
|
385 |
'Toolset_VideoDetachedPage' => $vendorDir . '/toolset/toolset-common/utility/help-videos/toolset-help-videos.php',
|
386 |
'Toolset_WPLogger' => $vendorDir . '/toolset/toolset-common/inc/toolset.wplogger.class.php',
|
387 |
'Toolset_WPML_Compatibility' => $vendorDir . '/toolset/toolset-common/inc/toolset.wpml.compatibility.class.php',
|
|
|
|
|
|
|
|
|
|
|
|
|
388 |
'Toolset_Wpml_Utils' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/wpml_utils.php',
|
389 |
'Twig_Autoloader' => $vendorDir . '/twig/twig/lib/Twig/Autoloader.php',
|
390 |
'Twig_BaseNodeVisitor' => $vendorDir . '/twig/twig/lib/Twig/BaseNodeVisitor.php',
|
@@ -611,14 +704,14 @@ return array(
|
|
611 |
'Types_Field_Group_User_Factory' => $baseDir . '/application/models/field/group/user_factory.php',
|
612 |
'Types_Field_Type_Converter' => $baseDir . '/application/controllers/field/type_converter.php',
|
613 |
'Types_Field_Type_Definition' => $baseDir . '/application/models/field/type/definition.php',
|
614 |
-
'Types_Field_Type_Definition_Checkbox' => $baseDir . '/application/models/field/
|
615 |
-
'Types_Field_Type_Definition_Checkboxes' => $baseDir . '/application/models/field/
|
616 |
-
'Types_Field_Type_Definition_Date' => $baseDir . '/application/models/field/
|
617 |
'Types_Field_Type_Definition_Factory' => $baseDir . '/application/models/field/type/definition_factory.php',
|
618 |
-
'Types_Field_Type_Definition_Numeric' => $baseDir . '/application/models/field/
|
619 |
-
'Types_Field_Type_Definition_Radio' => $baseDir . '/application/models/field/
|
620 |
-
'Types_Field_Type_Definition_Select' => $baseDir . '/application/models/field/
|
621 |
-
'Types_Field_Type_Definition_Singular' => $baseDir . '/application/models/field/
|
622 |
'Types_Field_Utils' => $baseDir . '/application/controllers/field/utils.php',
|
623 |
'Types_Frontend' => $baseDir . '/application/controllers/frontend.php',
|
624 |
'Types_Helper_Condition' => $baseDir . '/application/models/helper/condition.php',
|
@@ -697,7 +790,7 @@ return array(
|
|
697 |
'Types_Taxonomy' => $baseDir . '/application/models/taxonomy.php',
|
698 |
'Types_Twig_Autoloader' => $baseDir . '/application/controllers/twig_autoloader.php',
|
699 |
'Types_Upgrade' => $baseDir . '/application/controllers/upgrade.php',
|
700 |
-
'Types_Utils' => $baseDir . '/application/controllers/
|
701 |
'Types_Utils_Post_Type_Option' => $baseDir . '/application/controllers/utils/post_type_option.php',
|
702 |
'Types_Wpml_Field_Group' => $baseDir . '/application/models/wpml/field_group.php',
|
703 |
'Types_Wpml_Field_Group_String' => $baseDir . '/application/models/wpml/field/group/string.php',
|
96 |
'FieldFactory' => $vendorDir . '/toolset/toolset-common/toolset-forms/classes/class.field_factory.php',
|
97 |
'FormAbstract' => $vendorDir . '/toolset/toolset-common/toolset-forms/classes/abstract.form.php',
|
98 |
'FormFactory' => $vendorDir . '/toolset/toolset-common/toolset-forms/classes/class.form_factory.php',
|
99 |
+
'IToolset_Association' => $vendorDir . '/toolset/toolset-common/inc/m2m/association/interface.php',
|
100 |
+
'IToolset_Association_Query_Condition' => $vendorDir . '/toolset/toolset-common/inc/m2m/association/query/condition/interface.php',
|
101 |
+
'IToolset_Association_Query_Element_Selector' => $vendorDir . '/toolset/toolset-common/inc/m2m/association/query/element_selector/interface.php',
|
102 |
+
'IToolset_Association_Query_Orderby' => $vendorDir . '/toolset/toolset-common/inc/m2m/association/query/orderby/interface.php',
|
103 |
+
'IToolset_Association_Query_Restriction' => $vendorDir . '/toolset/toolset-common/inc/m2m/association/query/restriction/interface.php',
|
104 |
+
'IToolset_Association_Query_Result_Transformation' => $vendorDir . '/toolset/toolset-common/inc/m2m/association/query/result_transformation/interface.php',
|
105 |
+
'IToolset_Cron_Event' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/cron/event_interface.php',
|
106 |
'IToolset_Element' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/element/i_element.php',
|
107 |
+
'IToolset_Output_Template' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/renderer/output_template/interface.php',
|
108 |
'IToolset_Post' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/element/i_post.php',
|
109 |
'IToolset_Post_Type' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/post_type/i_post_type.php',
|
110 |
'IToolset_Post_Type_From_Types' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/post_type/i_post_type_from_types.php',
|
111 |
'IToolset_Post_Type_Registered' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/post_type/i_post_type_registered.php',
|
112 |
'IToolset_Potential_Association_Query' => $vendorDir . '/toolset/toolset-common/inc/m2m/potential_association/query_interface.php',
|
113 |
'IToolset_Query' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/i_query.php',
|
114 |
+
'IToolset_Query_Condition' => $vendorDir . '/toolset/toolset-common/inc/m2m/query/condition/interface.php',
|
115 |
'IToolset_Relationship_Database_Issue' => $vendorDir . '/toolset/toolset-common/inc/m2m/database/issue/interface.php',
|
116 |
+
'IToolset_Relationship_Definition' => $vendorDir . '/toolset/toolset-common/inc/m2m/relationship/definition/interface.php',
|
117 |
'IToolset_Relationship_Origin' => $vendorDir . '/toolset/toolset-common/inc/m2m/origin/interface.php',
|
118 |
+
'IToolset_Relationship_Query_Cardinality_Match' => $vendorDir . '/toolset/toolset-common/inc/m2m/relationship/query/cardinality_match/interface.php',
|
119 |
+
'IToolset_Relationship_Query_Condition' => $vendorDir . '/toolset/toolset-common/inc/m2m/relationship/query/condition/interface.php',
|
120 |
+
'IToolset_Relationship_Role' => $vendorDir . '/toolset/toolset-common/inc/m2m/relationship/role/interface.php',
|
121 |
+
'IToolset_Relationship_Role_Parent_Child' => $vendorDir . '/toolset/toolset-common/inc/m2m/relationship/role/parent_child_interface.php',
|
122 |
'IToolset_Upgrade_Command' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/upgrade/command_interface.php',
|
123 |
'ReCaptchaResponse' => $vendorDir . '/toolset/toolset-common/toolset-forms/js/recaptcha-php-1.11/recaptchalib.php',
|
124 |
'Toolset_Admin_Bar_Menu' => $vendorDir . '/toolset/toolset-common/inc/toolset.admin.bar.menu.class.php',
|
125 |
+
'Toolset_Admin_Controller' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/admin.php',
|
126 |
'Toolset_Admin_Notice_Abstract' => $vendorDir . '/toolset/toolset-common/utility/admin/notice/abstract.php',
|
127 |
'Toolset_Admin_Notice_Dismissible' => $vendorDir . '/toolset/toolset-common/utility/admin/notice/dismissible.php',
|
128 |
'Toolset_Admin_Notice_Error' => $vendorDir . '/toolset/toolset-common/utility/admin/notice/error.php',
|
135 |
'Toolset_Admin_Notices_Manager' => $vendorDir . '/toolset/toolset-common/utility/admin/notices/manager.php',
|
136 |
'Toolset_Ajax' => $vendorDir . '/toolset/toolset-common/inc/toolset.ajax.class.php',
|
137 |
'Toolset_Ajax_Handler_Abstract' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/ajax_handler/abstract.php',
|
138 |
+
'Toolset_Ajax_Handler_Get_Content_Template_Block_Preview' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/ajax_handler/get_ct_block_preview.php',
|
139 |
+
'Toolset_Ajax_Handler_Get_Post_By_Id' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/ajax_handler/get_post_by_id.php',
|
140 |
+
'Toolset_Ajax_Handler_Get_Term_By_Id' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/ajax_handler/get_term_by_id.php',
|
141 |
+
'Toolset_Ajax_Handler_Get_User_By_Id' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/ajax_handler/get_user_by_id.php',
|
142 |
+
'Toolset_Ajax_Handler_Get_View_Block_Preview' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/ajax_handler/get_view_block_preview.php',
|
143 |
'Toolset_Ajax_Handler_Interface' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/ajax_handler/interface.php',
|
144 |
+
'Toolset_Ajax_Handler_Intermediary_Post_Cleanup' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/ajax_handler/intermediary_post_cleanup.php',
|
145 |
'Toolset_Ajax_Handler_Migrate_To_M2M' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/ajax_handler/migrate_to_m2m.php',
|
146 |
+
'Toolset_Ajax_Handler_Select2_Suggest_Posts_By_Title' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/ajax_handler/select2_suggest_posts_by_title.php',
|
147 |
+
'Toolset_Ajax_Handler_Select2_Suggest_Terms' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/ajax_handler/select2_suggest_terms.php',
|
148 |
+
'Toolset_Ajax_Handler_Select2_Suggest_Users' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/ajax_handler/select2_suggest_users.php',
|
149 |
'Toolset_ArrayUtils' => $vendorDir . '/toolset/toolset-common/utility/utils.php',
|
150 |
+
'Toolset_Asset_Manager' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/asset_manager.php',
|
151 |
'Toolset_Assets_Manager' => $vendorDir . '/toolset/toolset-common/inc/toolset.assets.manager.class.php',
|
152 |
+
'Toolset_Association' => $vendorDir . '/toolset/toolset-common/inc/m2m/association/association.php',
|
153 |
+
'Toolset_Association_Cleanup_Association' => $vendorDir . '/toolset/toolset-common/inc/m2m/association/cleanup/association.php',
|
154 |
+
'Toolset_Association_Cleanup_Cron_Event' => $vendorDir . '/toolset/toolset-common/inc/m2m/association/cleanup/cron_event.php',
|
155 |
+
'Toolset_Association_Cleanup_Cron_Handler' => $vendorDir . '/toolset/toolset-common/inc/m2m/association/cleanup/cron_handler.php',
|
156 |
+
'Toolset_Association_Cleanup_Dangling_Intermediary_Posts' => $vendorDir . '/toolset/toolset-common/inc/m2m/association/cleanup/dangling_intermediary_posts.php',
|
157 |
+
'Toolset_Association_Cleanup_Factory' => $vendorDir . '/toolset/toolset-common/inc/m2m/association/cleanup/factory.php',
|
158 |
+
'Toolset_Association_Cleanup_Post' => $vendorDir . '/toolset/toolset-common/inc/m2m/association/cleanup/post.php',
|
159 |
+
'Toolset_Association_Cleanup_Troubleshooting_Section' => $vendorDir . '/toolset/toolset-common/inc/m2m/association/cleanup/troubleshooting_section.php',
|
160 |
+
'Toolset_Association_Factory' => $vendorDir . '/toolset/toolset-common/inc/m2m/association/factory.php',
|
161 |
+
'Toolset_Association_Intermediary_Post_Persistence' => $vendorDir . '/toolset/toolset-common/inc/m2m/association/intermediary_post_persistence.php',
|
162 |
+
'Toolset_Association_Persistence' => $vendorDir . '/toolset/toolset-common/inc/m2m/association/persistence.php',
|
163 |
+
'Toolset_Association_Query' => $vendorDir . '/toolset/toolset-common/inc/m2m/association/query/association_query.php',
|
164 |
+
'Toolset_Association_Query_Condition' => $vendorDir . '/toolset/toolset-common/inc/m2m/association/query/condition/abstract.php',
|
165 |
+
'Toolset_Association_Query_Condition_Association_Id' => $vendorDir . '/toolset/toolset-common/inc/m2m/association/query/condition/association_id.php',
|
166 |
+
'Toolset_Association_Query_Condition_Element_Id' => $vendorDir . '/toolset/toolset-common/inc/m2m/association/query/condition/element_id.php',
|
167 |
+
'Toolset_Association_Query_Condition_Element_Id_And_Domain' => $vendorDir . '/toolset/toolset-common/inc/m2m/association/query/condition/element_id_and_domain.php',
|
168 |
+
'Toolset_Association_Query_Condition_Element_Status' => $vendorDir . '/toolset/toolset-common/inc/m2m/association/query/condition/element_status.php',
|
169 |
+
'Toolset_Association_Query_Condition_Empty_Intermediary' => $vendorDir . '/toolset/toolset-common/inc/m2m/association/query/condition/empty_intermediary.php',
|
170 |
+
'Toolset_Association_Query_Condition_Exclude_Element' => $vendorDir . '/toolset/toolset-common/inc/m2m/association/query/condition/exclude_element.php',
|
171 |
+
'Toolset_Association_Query_Condition_Factory' => $vendorDir . '/toolset/toolset-common/inc/m2m/association/query/condition_factory.php',
|
172 |
+
'Toolset_Association_Query_Condition_Has_Active_Relationship' => $vendorDir . '/toolset/toolset-common/inc/m2m/association/query/condition/has_active_relationship.php',
|
173 |
+
'Toolset_Association_Query_Condition_Has_Domain' => $vendorDir . '/toolset/toolset-common/inc/m2m/association/query/condition/has_domain.php',
|
174 |
+
'Toolset_Association_Query_Condition_Has_Domain_And_Type' => $vendorDir . '/toolset/toolset-common/inc/m2m/association/query/condition/has_domain_and_type.php',
|
175 |
+
'Toolset_Association_Query_Condition_Has_Legacy_Relationship' => $vendorDir . '/toolset/toolset-common/inc/m2m/association/query/condition/has_legacy_relationship.php',
|
176 |
+
'Toolset_Association_Query_Condition_Has_Type' => $vendorDir . '/toolset/toolset-common/inc/m2m/association/query/condition/has_type.php',
|
177 |
+
'Toolset_Association_Query_Condition_Postmeta' => $vendorDir . '/toolset/toolset-common/inc/m2m/association/query/condition/postmeta.php',
|
178 |
+
'Toolset_Association_Query_Condition_Relationship_Flag' => $vendorDir . '/toolset/toolset-common/inc/m2m/association/query/condition/relationship_flag.php',
|
179 |
+
'Toolset_Association_Query_Condition_Relationship_Id' => $vendorDir . '/toolset/toolset-common/inc/m2m/association/query/condition/relationship_id.php',
|
180 |
+
'Toolset_Association_Query_Condition_Search' => $vendorDir . '/toolset/toolset-common/inc/m2m/association/query/condition/search.php',
|
181 |
+
'Toolset_Association_Query_Condition_Wp_Query' => $vendorDir . '/toolset/toolset-common/inc/m2m/association/query/condition/wp_query.php',
|
182 |
+
'Toolset_Association_Query_Element_Selector_Abstract' => $vendorDir . '/toolset/toolset-common/inc/m2m/association/query/element_selector/abstract.php',
|
183 |
+
'Toolset_Association_Query_Element_Selector_Default' => $vendorDir . '/toolset/toolset-common/inc/m2m/association/query/element_selector/default.php',
|
184 |
+
'Toolset_Association_Query_Element_Selector_Provider' => $vendorDir . '/toolset/toolset-common/inc/m2m/association/query/element_selector/provider.php',
|
185 |
+
'Toolset_Association_Query_Element_Selector_Wpml' => $vendorDir . '/toolset/toolset-common/inc/m2m/association/query/element_selector/wpml.php',
|
186 |
+
'Toolset_Association_Query_Orderby' => $vendorDir . '/toolset/toolset-common/inc/m2m/association/query/orderby/abstract.php',
|
187 |
+
'Toolset_Association_Query_Orderby_Factory' => $vendorDir . '/toolset/toolset-common/inc/m2m/association/query/orderby_factory.php',
|
188 |
+
'Toolset_Association_Query_Orderby_Nothing' => $vendorDir . '/toolset/toolset-common/inc/m2m/association/query/orderby/nothing.php',
|
189 |
+
'Toolset_Association_Query_Orderby_Postmeta' => $vendorDir . '/toolset/toolset-common/inc/m2m/association/query/orderby/postmeta.php',
|
190 |
+
'Toolset_Association_Query_Orderby_Title' => $vendorDir . '/toolset/toolset-common/inc/m2m/association/query/orderby/title.php',
|
191 |
+
'Toolset_Association_Query_Result_Transformation_Association_Instance' => $vendorDir . '/toolset/toolset-common/inc/m2m/association/query/result_transformation/association_instance.php',
|
192 |
+
'Toolset_Association_Query_Result_Transformation_Association_Uid' => $vendorDir . '/toolset/toolset-common/inc/m2m/association/query/result_transformation/association_uid.php',
|
193 |
+
'Toolset_Association_Query_Result_Transformation_Element_Id' => $vendorDir . '/toolset/toolset-common/inc/m2m/association/query/result_transformation/element_id.php',
|
194 |
+
'Toolset_Association_Query_Result_Transformation_Element_Instance' => $vendorDir . '/toolset/toolset-common/inc/m2m/association/query/result_transformation/element_instance.php',
|
195 |
+
'Toolset_Association_Query_Sql_Expression_Builder' => $vendorDir . '/toolset/toolset-common/inc/m2m/association/query/sql_expression_builder.php',
|
196 |
+
'Toolset_Association_Query_Table_Join_Manager' => $vendorDir . '/toolset/toolset-common/inc/m2m/association/query/table_join_manager.php',
|
197 |
+
'Toolset_Association_Query_V2' => $vendorDir . '/toolset/toolset-common/inc/m2m/association/query/association_query_v2.php',
|
198 |
+
'Toolset_Association_Query_Wpdb_Wrapper' => $vendorDir . '/toolset/toolset-common/inc/m2m/association/query/wpdb_wrapper.php',
|
199 |
+
'Toolset_Association_Translator' => $vendorDir . '/toolset/toolset-common/inc/m2m/association/translator.php',
|
200 |
+
'Toolset_Blocks' => $vendorDir . '/toolset/toolset-common/toolset-blocks/toolset-blocks.php',
|
201 |
+
'Toolset_Blocks_Content_Template' => $vendorDir . '/toolset/toolset-common/toolset-blocks/blocks/ct/ct.php',
|
202 |
+
'Toolset_Blocks_Custom_HTML' => $vendorDir . '/toolset/toolset-common/toolset-blocks/blocks/custom-html/custom-html.php',
|
203 |
+
'Toolset_Blocks_View' => $vendorDir . '/toolset/toolset-common/toolset-blocks/blocks/view/view.php',
|
204 |
'Toolset_Bootstrap_Loader' => $vendorDir . '/toolset/toolset-common/inc/toolset.bootstrap.loader.class.php',
|
205 |
'Toolset_Common_Autoloader' => $vendorDir . '/toolset/toolset-common/utility/autoloader.php',
|
206 |
'Toolset_Common_Bootstrap' => $vendorDir . '/toolset/toolset-common/bootstrap.php',
|
214 |
'Toolset_Condition_Plugin_Layouts_Missing' => $vendorDir . '/toolset/toolset-common/utility/condition/plugin/layouts/missing.php',
|
215 |
'Toolset_Condition_Plugin_Layouts_No_Items' => $vendorDir . '/toolset/toolset-common/utility/condition/plugin/layouts/no-items.php',
|
216 |
'Toolset_Condition_Plugin_Types_Active' => $vendorDir . '/toolset/toolset-common/utility/condition/plugin/types/active.php',
|
217 |
+
'Toolset_Condition_Plugin_Types_Has_Legacy_Relationships' => $vendorDir . '/toolset/toolset-common/utility/condition/plugin/types/has_legacy_relationships.php',
|
218 |
'Toolset_Condition_Plugin_Types_Missing' => $vendorDir . '/toolset/toolset-common/utility/condition/plugin/types/missing.php',
|
219 |
'Toolset_Condition_Plugin_Types_Ready_For_M2M' => $vendorDir . '/toolset/toolset-common/utility/condition/plugin/types/ready_for_m2m.php',
|
220 |
'Toolset_Condition_Plugin_Views_Active' => $vendorDir . '/toolset/toolset-common/utility/condition/plugin/views/active.php',
|
221 |
'Toolset_Condition_Plugin_Views_Missing' => $vendorDir . '/toolset/toolset-common/utility/condition/plugin/views/missing.php',
|
222 |
'Toolset_Condition_Plugin_Wpml_Doesnt_Support_M2m' => $vendorDir . '/toolset/toolset-common/utility/condition/plugin/wpml/doesnt_support_m2m.php',
|
223 |
+
'Toolset_Condition_Plugin_Wpml_Is_Active_And_Configured' => $vendorDir . '/toolset/toolset-common/utility/condition/plugin/wpml/is_active_and_configured.php',
|
224 |
+
'Toolset_Condition_Plugin_Wpml_Is_Current_Language_Default' => $vendorDir . '/toolset/toolset-common/utility/condition/plugin/wpml/is_current_language_default.php',
|
225 |
'Toolset_Condition_Theme_Avada_Not_Active_Or_Greater_Equal_5_0' => $vendorDir . '/toolset/toolset-common/utility/condition/theme/avada/not-active-or-greater-equal-5-0.php',
|
226 |
'Toolset_Condition_Theme_Layouts_Support_Native_Available' => $vendorDir . '/toolset/toolset-common/utility/condition/theme/layouts-support/native/available.php',
|
227 |
'Toolset_Condition_Theme_Layouts_Support_Native_Missing' => $vendorDir . '/toolset/toolset-common/utility/condition/theme/layouts-support/native/missing.php',
|
236 |
'Toolset_Condition_Theme_Toolset_Based_Active' => $vendorDir . '/toolset/toolset-common/utility/condition/theme/toolset-based/active.php',
|
237 |
'Toolset_Condition_Theme_Toolset_Based_Inactive' => $vendorDir . '/toolset/toolset-common/utility/condition/theme/toolset-based/inactive.php',
|
238 |
'Toolset_Condition_User_Role_Admin' => $vendorDir . '/toolset/toolset-common/utility/condition/user/role/admin.php',
|
239 |
+
'Toolset_Constants' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/constants.php',
|
240 |
+
'Toolset_Controller_Admin_Notices' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/admin/notices.php',
|
241 |
+
'Toolset_Cron' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/cron/cron.php',
|
242 |
+
'Toolset_Cron_Event' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/cron/event.php',
|
243 |
'Toolset_CssComponent' => $vendorDir . '/toolset/toolset-common/inc/toolset.css.component.class.php',
|
244 |
'Toolset_Date' => $vendorDir . '/toolset/toolset-common/expression-parser/parser.php',
|
245 |
'Toolset_DateParser' => $vendorDir . '/toolset/toolset-common/expression-parser/parser.php',
|
265 |
'Toolset_Field_Definition' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/field/definition.php',
|
266 |
'Toolset_Field_Definition_Abstract' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/field/definition_abstract.php',
|
267 |
'Toolset_Field_Definition_Factory' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/field/definition_factory.php',
|
268 |
+
'Toolset_Field_Definition_Factory_Interface' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/field/definition_factory_interface.php',
|
269 |
'Toolset_Field_Definition_Factory_Post' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/field/definition_factory_post.php',
|
270 |
'Toolset_Field_Definition_Factory_Term' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/field/definition_factory_term.php',
|
271 |
'Toolset_Field_Definition_Factory_User' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/field/definition_factory_user.php',
|
272 |
'Toolset_Field_Definition_Generic' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/field/definition_generic.php',
|
273 |
+
'Toolset_Field_Definition_Interface' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/field/definition_interface.php',
|
274 |
'Toolset_Field_Definition_Post' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/field/definition_post.php',
|
275 |
'Toolset_Field_Definition_Term' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/field/definition_term.php',
|
276 |
'Toolset_Field_Definition_User' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/field/definition_user.php',
|
316 |
'Toolset_Field_Type_Definition_Select' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/field/type/definition/select.php',
|
317 |
'Toolset_Field_Type_Definition_Singular' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/field/type/definition/singular.php',
|
318 |
'Toolset_Field_Utils' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/field/utils.php',
|
319 |
+
'Toolset_Files' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/files.php',
|
320 |
'Toolset_Functions' => $vendorDir . '/toolset/toolset-common/expression-parser/parser.php',
|
321 |
'Toolset_Gui_Base' => $vendorDir . '/toolset/toolset-common/utility/gui-base/main.php',
|
322 |
'Toolset_HelpVideo' => $vendorDir . '/toolset/toolset-common/utility/help-videos/toolset-help-videos.php',
|
326 |
'Toolset_Menu' => $vendorDir . '/toolset/toolset-common/inc/toolset.menu.class.php',
|
327 |
'Toolset_Naming_Helper' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/naming_helper.php',
|
328 |
'Toolset_Object_Relationship' => $vendorDir . '/toolset/toolset-common/inc/toolset.object.relationship.class.php',
|
329 |
+
'Toolset_Output_Template' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/renderer/output_template/abstract.php',
|
330 |
+
'Toolset_Output_Template_Factory' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/renderer/output_template_factory.php',
|
331 |
+
'Toolset_Output_Template_Phtml' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/renderer/output_template/phtml.php',
|
332 |
+
'Toolset_Output_Template_Repository' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/renderer/output_template_repository.php',
|
333 |
+
'Toolset_Output_Template_Repository_Abstract' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/renderer/output_template_repository_abstract.php',
|
334 |
+
'Toolset_Output_Template_Static' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/renderer/output_template/static.php',
|
335 |
+
'Toolset_Output_Template_Twig' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/renderer/output_template/twig.php',
|
336 |
'Toolset_Parser' => $vendorDir . '/toolset/toolset-common/expression-parser/parser.php',
|
337 |
'Toolset_Post' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/element/post.php',
|
338 |
'Toolset_Post_Translation_Set' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/element/post_translation_set.php',
|
339 |
+
'Toolset_Post_Type_Abstract' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/post_type/abstract.php',
|
340 |
'Toolset_Post_Type_Exclude_List' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/post_type/excluded_list.php',
|
341 |
'Toolset_Post_Type_Factory' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/post_type/factory.php',
|
342 |
'Toolset_Post_Type_From_Types' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/post_type/from_types.php',
|
348 |
'Toolset_Potential_Association_Query_Factory' => $vendorDir . '/toolset/toolset-common/inc/m2m/potential_association/query_factory.php',
|
349 |
'Toolset_Potential_Association_Query_Posts' => $vendorDir . '/toolset/toolset-common/inc/m2m/potential_association/query_posts.php',
|
350 |
'Toolset_Promotion' => $vendorDir . '/toolset/toolset-common/inc/toolset.promotion.class.php',
|
351 |
+
'Toolset_Public_API_Loader' => $vendorDir . '/toolset/toolset-common/inc/public_api/loader.php',
|
352 |
+
'Toolset_Query_Comparison_Operator' => $vendorDir . '/toolset/toolset-common/inc/m2m/query/comparison_operator.php',
|
353 |
+
'Toolset_Query_Condition_And' => $vendorDir . '/toolset/toolset-common/inc/m2m/query/condition/and.php',
|
354 |
+
'Toolset_Query_Condition_Contradiction' => $vendorDir . '/toolset/toolset-common/inc/m2m/query/condition/contradiction.php',
|
355 |
+
'Toolset_Query_Condition_Operator' => $vendorDir . '/toolset/toolset-common/inc/m2m/query/condition/operator.php',
|
356 |
+
'Toolset_Query_Condition_Or' => $vendorDir . '/toolset/toolset-common/inc/m2m/query/condition/or.php',
|
357 |
+
'Toolset_Query_Condition_Tautology' => $vendorDir . '/toolset/toolset-common/inc/m2m/query/condition/tautology.php',
|
358 |
'Toolset_Regex' => $vendorDir . '/toolset/toolset-common/expression-parser/parser.php',
|
359 |
'Toolset_Relationship_Cardinality' => $vendorDir . '/toolset/toolset-common/inc/m2m/cardinality.php',
|
360 |
'Toolset_Relationship_Controller' => $vendorDir . '/toolset/toolset-common/inc/m2m/controller.php',
|
361 |
'Toolset_Relationship_Database_Issue_Missing_Element' => $vendorDir . '/toolset/toolset-common/inc/m2m/database/issue/missing_element.php',
|
362 |
'Toolset_Relationship_Database_Operations' => $vendorDir . '/toolset/toolset-common/inc/m2m/database/operations.php',
|
363 |
'Toolset_Relationship_Database_Unique_Table_Alias' => $vendorDir . '/toolset/toolset-common/inc/m2m/database/unique_table_alias.php',
|
364 |
+
'Toolset_Relationship_Definition' => $vendorDir . '/toolset/toolset-common/inc/m2m/relationship/definition/definition.php',
|
365 |
+
'Toolset_Relationship_Definition_Factory' => $vendorDir . '/toolset/toolset-common/inc/m2m/relationship/definition/factory.php',
|
366 |
+
'Toolset_Relationship_Definition_Persistence' => $vendorDir . '/toolset/toolset-common/inc/m2m/relationship/definition/persistence.php',
|
367 |
+
'Toolset_Relationship_Definition_Repository' => $vendorDir . '/toolset/toolset-common/inc/m2m/relationship/definition/repository.php',
|
368 |
+
'Toolset_Relationship_Definition_Translator' => $vendorDir . '/toolset/toolset-common/inc/m2m/relationship/definition/translator.php',
|
369 |
'Toolset_Relationship_Distinct_Post_Query' => $vendorDir . '/toolset/toolset-common/inc/m2m/potential_association/distinct_post_query.php',
|
370 |
'Toolset_Relationship_Driver' => $vendorDir . '/toolset/toolset-common/inc/m2m/driver.php',
|
371 |
'Toolset_Relationship_Driver_Base' => $vendorDir . '/toolset/toolset-common/inc/m2m/driver_base.php',
|
372 |
'Toolset_Relationship_Element_Type' => $vendorDir . '/toolset/toolset-common/inc/m2m/element_type.php',
|
373 |
+
'Toolset_Relationship_Migration' => $vendorDir . '/toolset/toolset-common/inc/m2m/migration/controller.php',
|
374 |
+
'Toolset_Relationship_Migration_Associations' => $vendorDir . '/toolset/toolset-common/inc/m2m/migration/associations.php',
|
375 |
+
'Toolset_Relationship_Migration_Controller' => $vendorDir . '/toolset/toolset-common/inc/m2m/migration/controller.php',
|
376 |
+
'Toolset_Relationship_Migration_Post_Translation' => $vendorDir . '/toolset/toolset-common/inc/m2m/migration/post_translation.php',
|
377 |
'Toolset_Relationship_Origin_Post_Reference_Field' => $vendorDir . '/toolset/toolset-common/inc/m2m/origin/post_reference_field.php',
|
378 |
'Toolset_Relationship_Origin_Repeatable_Group' => $vendorDir . '/toolset/toolset-common/inc/m2m/origin/repeatable_group.php',
|
379 |
'Toolset_Relationship_Origin_Wizard' => $vendorDir . '/toolset/toolset-common/inc/m2m/origin/wizard.php',
|
380 |
+
'Toolset_Relationship_Query' => $vendorDir . '/toolset/toolset-common/inc/m2m/relationship/query/relationship_query.php',
|
381 |
'Toolset_Relationship_Query_Base' => $vendorDir . '/toolset/toolset-common/inc/m2m/query_base.php',
|
382 |
'Toolset_Relationship_Query_Cache' => $vendorDir . '/toolset/toolset-common/inc/m2m/query_cache.php',
|
383 |
+
'Toolset_Relationship_Query_Cardinality_Match_Conjunction' => $vendorDir . '/toolset/toolset-common/inc/m2m/relationship/query/cardinality_match/conjunction.php',
|
384 |
+
'Toolset_Relationship_Query_Cardinality_Match_Factory' => $vendorDir . '/toolset/toolset-common/inc/m2m/relationship/query/cardinality_match/factory.php',
|
385 |
+
'Toolset_Relationship_Query_Cardinality_Match_Operators' => $vendorDir . '/toolset/toolset-common/inc/m2m/relationship/query/cardinality_match/operators.php',
|
386 |
+
'Toolset_Relationship_Query_Cardinality_Match_Single' => $vendorDir . '/toolset/toolset-common/inc/m2m/relationship/query/cardinality_match/single.php',
|
387 |
+
'Toolset_Relationship_Query_Condition' => $vendorDir . '/toolset/toolset-common/inc/m2m/relationship/query/condition/abstract.php',
|
388 |
+
'Toolset_Relationship_Query_Condition_Factory' => $vendorDir . '/toolset/toolset-common/inc/m2m/relationship/query/condition_factory.php',
|
389 |
+
'Toolset_Relationship_Query_Condition_Has_Active_Types' => $vendorDir . '/toolset/toolset-common/inc/m2m/relationship/query/condition/has_active_types.php',
|
390 |
+
'Toolset_Relationship_Query_Condition_Has_Cardinality' => $vendorDir . '/toolset/toolset-common/inc/m2m/relationship/query/condition/has_cardinality.php',
|
391 |
+
'Toolset_Relationship_Query_Condition_Has_Domain' => $vendorDir . '/toolset/toolset-common/inc/m2m/relationship/query/condition/has_domain.php',
|
392 |
+
'Toolset_Relationship_Query_Condition_Is_Active' => $vendorDir . '/toolset/toolset-common/inc/m2m/relationship/query/condition/is_active.php',
|
393 |
+
'Toolset_Relationship_Query_Condition_Is_Boolean_Flag' => $vendorDir . '/toolset/toolset-common/inc/m2m/relationship/query/condition/is_boolean_flag.php',
|
394 |
+
'Toolset_Relationship_Query_Condition_Is_Legacy' => $vendorDir . '/toolset/toolset-common/inc/m2m/relationship/query/condition/is_legacy.php',
|
395 |
+
'Toolset_Relationship_Query_Condition_Origin' => $vendorDir . '/toolset/toolset-common/inc/m2m/relationship/query/condition/origin.php',
|
396 |
+
'Toolset_Relationship_Query_Condition_Type' => $vendorDir . '/toolset/toolset-common/inc/m2m/relationship/query/condition/type.php',
|
397 |
+
'Toolset_Relationship_Query_Factory' => $vendorDir . '/toolset/toolset-common/inc/m2m/query/factory.php',
|
398 |
+
'Toolset_Relationship_Query_Sql_Expression_Builder' => $vendorDir . '/toolset/toolset-common/inc/m2m/relationship/query/sql_expression_builder.php',
|
399 |
+
'Toolset_Relationship_Query_V2' => $vendorDir . '/toolset/toolset-common/inc/m2m/relationship/query/relationship_query_v2.php',
|
400 |
+
'Toolset_Relationship_Role' => $vendorDir . '/toolset/toolset-common/inc/m2m/relationship/role/role.php',
|
401 |
+
'Toolset_Relationship_Role_Abstract' => $vendorDir . '/toolset/toolset-common/inc/m2m/relationship/role/abstract.php',
|
402 |
+
'Toolset_Relationship_Role_Child' => $vendorDir . '/toolset/toolset-common/inc/m2m/relationship/role/child.php',
|
403 |
+
'Toolset_Relationship_Role_Intermediary' => $vendorDir . '/toolset/toolset-common/inc/m2m/relationship/role/intermediary.php',
|
404 |
+
'Toolset_Relationship_Role_Parent' => $vendorDir . '/toolset/toolset-common/inc/m2m/relationship/role/parent.php',
|
405 |
+
'Toolset_Relationship_Scope' => $vendorDir . '/toolset/toolset-common/inc/m2m/relationship/scope.php',
|
|
|
|
|
|
|
|
|
406 |
'Toolset_Relationship_Service' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/relationship_service.php',
|
407 |
+
'Toolset_Relationship_Slug_Validator' => $vendorDir . '/toolset/toolset-common/inc/m2m/relationship/slug_validator.php',
|
408 |
'Toolset_Relationship_Table_Name' => $vendorDir . '/toolset/toolset-common/inc/m2m/database/table_name.php',
|
409 |
'Toolset_Relationship_Utils' => $vendorDir . '/toolset/toolset-common/inc/m2m/utils.php',
|
|
|
410 |
'Toolset_Relevanssi_Compatibility' => $vendorDir . '/toolset/toolset-common/inc/toolset.relevanssi.compatibility.class.php',
|
411 |
+
'Toolset_Renderer' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/renderer/renderer.php',
|
412 |
'Toolset_Result' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/result.php',
|
413 |
'Toolset_Result_Set' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/result_set.php',
|
414 |
'Toolset_Result_Updated' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/result_updated.php',
|
424 |
'Toolset_Shortcode_Transformer' => $vendorDir . '/toolset/toolset-common/inc/toolset.shortcode.transformer.class.php',
|
425 |
'Toolset_Stack' => $vendorDir . '/toolset/toolset-common/expression-parser/parser.php',
|
426 |
'Toolset_Style' => $vendorDir . '/toolset/toolset-common/inc/toolset.assets.manager.class.php',
|
427 |
+
'Toolset_Template_Dialog_Box' => $vendorDir . '/toolset/toolset-common/utility/gui-base/template_dialog_box.php',
|
428 |
'Toolset_Tokenizer' => $vendorDir . '/toolset/toolset-common/expression-parser/parser.php',
|
429 |
'Toolset_Twig_Autoloader' => $vendorDir . '/toolset/toolset-common/utility/gui-base/twig_autoloader.php',
|
430 |
'Toolset_Twig_Dialog_Box' => $vendorDir . '/toolset/toolset-common/utility/gui-base/twig_dialog_box.php',
|
441 |
'Toolset_User_Editors_Editor_Basic' => $vendorDir . '/toolset/toolset-common/user-editors/editor/basic.php',
|
442 |
'Toolset_User_Editors_Editor_Beaver' => $vendorDir . '/toolset/toolset-common/user-editors/editor/beaver.php',
|
443 |
'Toolset_User_Editors_Editor_Divi' => $vendorDir . '/toolset/toolset-common/user-editors/editor/divi.php',
|
444 |
+
'Toolset_User_Editors_Editor_Gutenberg' => $vendorDir . '/toolset/toolset-common/user-editors/editor/gutenberg.php',
|
445 |
'Toolset_User_Editors_Editor_Interface' => $vendorDir . '/toolset/toolset-common/user-editors/editor/interface.php',
|
446 |
'Toolset_User_Editors_Editor_Native' => $vendorDir . '/toolset/toolset-common/user-editors/editor/native.php',
|
447 |
'Toolset_User_Editors_Editor_Screen_Abstract' => $vendorDir . '/toolset/toolset-common/user-editors/editor/screen/abstract.php',
|
452 |
'Toolset_User_Editors_Editor_Screen_Beaver_Frontend_Editor' => $vendorDir . '/toolset/toolset-common/user-editors/editor/screen/beaver/frontend-editor.php',
|
453 |
'Toolset_User_Editors_Editor_Screen_Divi_Backend' => $vendorDir . '/toolset/toolset-common/user-editors/editor/screen/divi/backend.php',
|
454 |
'Toolset_User_Editors_Editor_Screen_Divi_Frontend' => $vendorDir . '/toolset/toolset-common/user-editors/editor/screen/divi/frontend.php',
|
455 |
+
'Toolset_User_Editors_Editor_Screen_Gutenberg_Backend' => $vendorDir . '/toolset/toolset-common/user-editors/editor/screen/gutenberg/backend.php',
|
456 |
'Toolset_User_Editors_Editor_Screen_Interface' => $vendorDir . '/toolset/toolset-common/user-editors/editor/screen/interface.php',
|
457 |
'Toolset_User_Editors_Editor_Screen_Native_Backend' => $vendorDir . '/toolset/toolset-common/user-editors/editor/screen/native/backend.php',
|
458 |
'Toolset_User_Editors_Editor_Screen_Visual_Composer_Backend' => $vendorDir . '/toolset/toolset-common/user-editors/editor/screen/visual-composer/backend.php',
|
472 |
'Toolset_VideoDetachedPage' => $vendorDir . '/toolset/toolset-common/utility/help-videos/toolset-help-videos.php',
|
473 |
'Toolset_WPLogger' => $vendorDir . '/toolset/toolset-common/inc/toolset.wplogger.class.php',
|
474 |
'Toolset_WPML_Compatibility' => $vendorDir . '/toolset/toolset-common/inc/toolset.wpml.compatibility.class.php',
|
475 |
+
'Toolset_Wp_Query_Adjustments' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/wp_query_adjustments/abstract.php',
|
476 |
+
'Toolset_Wp_Query_Adjustments_Legacy_Relationships' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/wp_query_adjustments/legacy_relationships.php',
|
477 |
+
'Toolset_Wp_Query_Adjustments_Loader' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/wp_query_adjustments/loader.php',
|
478 |
+
'Toolset_Wp_Query_Adjustments_M2m' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/wp_query_adjustments/m2m.php',
|
479 |
+
'Toolset_Wp_Query_Adjustments_Table_Join_Manager' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/wp_query_adjustments/table_join_manager.php',
|
480 |
+
'Toolset_Wpdb_User' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/wpdb_user.php',
|
481 |
'Toolset_Wpml_Utils' => $vendorDir . '/toolset/toolset-common/inc/autoloaded/wpml_utils.php',
|
482 |
'Twig_Autoloader' => $vendorDir . '/twig/twig/lib/Twig/Autoloader.php',
|
483 |
'Twig_BaseNodeVisitor' => $vendorDir . '/twig/twig/lib/Twig/BaseNodeVisitor.php',
|
704 |
'Types_Field_Group_User_Factory' => $baseDir . '/application/models/field/group/user_factory.php',
|
705 |
'Types_Field_Type_Converter' => $baseDir . '/application/controllers/field/type_converter.php',
|
706 |
'Types_Field_Type_Definition' => $baseDir . '/application/models/field/type/definition.php',
|
707 |
+
'Types_Field_Type_Definition_Checkbox' => $baseDir . '/application/models/field/gateway/checkbox.php',
|
708 |
+
'Types_Field_Type_Definition_Checkboxes' => $baseDir . '/application/models/field/gateway/checkboxes.php',
|
709 |
+
'Types_Field_Type_Definition_Date' => $baseDir . '/application/models/field/gateway/date.php',
|
710 |
'Types_Field_Type_Definition_Factory' => $baseDir . '/application/models/field/type/definition_factory.php',
|
711 |
+
'Types_Field_Type_Definition_Numeric' => $baseDir . '/application/models/field/gateway/numeric.php',
|
712 |
+
'Types_Field_Type_Definition_Radio' => $baseDir . '/application/models/field/gateway/radio.php',
|
713 |
+
'Types_Field_Type_Definition_Select' => $baseDir . '/application/models/field/gateway/select.php',
|
714 |
+
'Types_Field_Type_Definition_Singular' => $baseDir . '/application/models/field/gateway/singular.php',
|
715 |
'Types_Field_Utils' => $baseDir . '/application/controllers/field/utils.php',
|
716 |
'Types_Frontend' => $baseDir . '/application/controllers/frontend.php',
|
717 |
'Types_Helper_Condition' => $baseDir . '/application/models/helper/condition.php',
|
790 |
'Types_Taxonomy' => $baseDir . '/application/models/taxonomy.php',
|
791 |
'Types_Twig_Autoloader' => $baseDir . '/application/controllers/twig_autoloader.php',
|
792 |
'Types_Upgrade' => $baseDir . '/application/controllers/upgrade.php',
|
793 |
+
'Types_Utils' => $baseDir . '/application/controllers/admin_notice/utils.php',
|
794 |
'Types_Utils_Post_Type_Option' => $baseDir . '/application/controllers/utils/post_type_option.php',
|
795 |
'Types_Wpml_Field_Group' => $baseDir . '/application/models/wpml/field_group.php',
|
796 |
'Types_Wpml_Field_Group_String' => $baseDir . '/application/models/wpml/field/group/string.php',
|
vendor/composer/autoload_real.php
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
|
3 |
// autoload_real.php @generated by Composer
|
4 |
|
5 |
-
class
|
6 |
{
|
7 |
private static $loader;
|
8 |
|
@@ -19,15 +19,15 @@ class ComposerAutoloaderInita469bff8809f0826cf254ebc61c9ca28
|
|
19 |
return self::$loader;
|
20 |
}
|
21 |
|
22 |
-
spl_autoload_register(array('
|
23 |
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
|
24 |
-
spl_autoload_unregister(array('
|
25 |
|
26 |
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
|
27 |
if ($useStaticLoader) {
|
28 |
require_once __DIR__ . '/autoload_static.php';
|
29 |
|
30 |
-
call_user_func(\Composer\Autoload\
|
31 |
} else {
|
32 |
$map = require __DIR__ . '/autoload_namespaces.php';
|
33 |
foreach ($map as $namespace => $path) {
|
@@ -48,19 +48,19 @@ class ComposerAutoloaderInita469bff8809f0826cf254ebc61c9ca28
|
|
48 |
$loader->register(true);
|
49 |
|
50 |
if ($useStaticLoader) {
|
51 |
-
$includeFiles = Composer\Autoload\
|
52 |
} else {
|
53 |
$includeFiles = require __DIR__ . '/autoload_files.php';
|
54 |
}
|
55 |
foreach ($includeFiles as $fileIdentifier => $file) {
|
56 |
-
|
57 |
}
|
58 |
|
59 |
return $loader;
|
60 |
}
|
61 |
}
|
62 |
|
63 |
-
function
|
64 |
{
|
65 |
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
|
66 |
require $file;
|
2 |
|
3 |
// autoload_real.php @generated by Composer
|
4 |
|
5 |
+
class ComposerAutoloaderInitc3c1dc77e2581741c891ff7b2bf920aa
|
6 |
{
|
7 |
private static $loader;
|
8 |
|
19 |
return self::$loader;
|
20 |
}
|
21 |
|
22 |
+
spl_autoload_register(array('ComposerAutoloaderInitc3c1dc77e2581741c891ff7b2bf920aa', 'loadClassLoader'), true, true);
|
23 |
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
|
24 |
+
spl_autoload_unregister(array('ComposerAutoloaderInitc3c1dc77e2581741c891ff7b2bf920aa', 'loadClassLoader'));
|
25 |
|
26 |
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
|
27 |
if ($useStaticLoader) {
|
28 |
require_once __DIR__ . '/autoload_static.php';
|
29 |
|
30 |
+
call_user_func(\Composer\Autoload\ComposerStaticInitc3c1dc77e2581741c891ff7b2bf920aa::getInitializer($loader));
|
31 |
} else {
|
32 |
$map = require __DIR__ . '/autoload_namespaces.php';
|
33 |
foreach ($map as $namespace => $path) {
|
48 |
$loader->register(true);
|
49 |
|
50 |
if ($useStaticLoader) {
|
51 |
+
$includeFiles = Composer\Autoload\ComposerStaticInitc3c1dc77e2581741c891ff7b2bf920aa::$files;
|
52 |
} else {
|
53 |
$includeFiles = require __DIR__ . '/autoload_files.php';
|
54 |
}
|
55 |
foreach ($includeFiles as $fileIdentifier => $file) {
|
56 |
+
composerRequirec3c1dc77e2581741c891ff7b2bf920aa($fileIdentifier, $file);
|
57 |
}
|
58 |
|
59 |
return $loader;
|
60 |
}
|
61 |
}
|
62 |
|
63 |
+
function composerRequirec3c1dc77e2581741c891ff7b2bf920aa($fileIdentifier, $file)
|
64 |
{
|
65 |
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
|
66 |
require $file;
|
vendor/composer/autoload_static.php
CHANGED
@@ -4,7 +4,7 @@
|
|
4 |
|
5 |
namespace Composer\Autoload;
|
6 |
|
7 |
-
class
|
8 |
{
|
9 |
public static $files = array (
|
10 |
'a52c1eba913b4ecdd3571194b37baea9' => __DIR__ . '/../..' . '/application/functions.php',
|
@@ -125,24 +125,33 @@ class ComposerStaticInita469bff8809f0826cf254ebc61c9ca28
|
|
125 |
'FieldFactory' => __DIR__ . '/..' . '/toolset/toolset-common/toolset-forms/classes/class.field_factory.php',
|
126 |
'FormAbstract' => __DIR__ . '/..' . '/toolset/toolset-common/toolset-forms/classes/abstract.form.php',
|
127 |
'FormFactory' => __DIR__ . '/..' . '/toolset/toolset-common/toolset-forms/classes/class.form_factory.php',
|
128 |
-
'IToolset_Association' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/
|
|
|
|
|
|
|
|
|
|
|
|
|
129 |
'IToolset_Element' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/element/i_element.php',
|
|
|
130 |
'IToolset_Post' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/element/i_post.php',
|
131 |
'IToolset_Post_Type' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/post_type/i_post_type.php',
|
132 |
'IToolset_Post_Type_From_Types' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/post_type/i_post_type_from_types.php',
|
133 |
'IToolset_Post_Type_Registered' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/post_type/i_post_type_registered.php',
|
134 |
'IToolset_Potential_Association_Query' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/potential_association/query_interface.php',
|
135 |
'IToolset_Query' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/i_query.php',
|
|
|
136 |
'IToolset_Relationship_Database_Issue' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/database/issue/interface.php',
|
137 |
-
'IToolset_Relationship_Definition' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/definition/interface.php',
|
138 |
'IToolset_Relationship_Origin' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/origin/interface.php',
|
139 |
-
'IToolset_Relationship_Query_Cardinality_Match' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/
|
140 |
-
'IToolset_Relationship_Query_Condition' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/
|
141 |
-
'IToolset_Relationship_Role' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/
|
142 |
-
'IToolset_Relationship_Role_Parent_Child' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/
|
143 |
'IToolset_Upgrade_Command' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/upgrade/command_interface.php',
|
144 |
'ReCaptchaResponse' => __DIR__ . '/..' . '/toolset/toolset-common/toolset-forms/js/recaptcha-php-1.11/recaptchalib.php',
|
145 |
'Toolset_Admin_Bar_Menu' => __DIR__ . '/..' . '/toolset/toolset-common/inc/toolset.admin.bar.menu.class.php',
|
|
|
146 |
'Toolset_Admin_Notice_Abstract' => __DIR__ . '/..' . '/toolset/toolset-common/utility/admin/notice/abstract.php',
|
147 |
'Toolset_Admin_Notice_Dismissible' => __DIR__ . '/..' . '/toolset/toolset-common/utility/admin/notice/dismissible.php',
|
148 |
'Toolset_Admin_Notice_Error' => __DIR__ . '/..' . '/toolset/toolset-common/utility/admin/notice/error.php',
|
@@ -155,17 +164,72 @@ class ComposerStaticInita469bff8809f0826cf254ebc61c9ca28
|
|
155 |
'Toolset_Admin_Notices_Manager' => __DIR__ . '/..' . '/toolset/toolset-common/utility/admin/notices/manager.php',
|
156 |
'Toolset_Ajax' => __DIR__ . '/..' . '/toolset/toolset-common/inc/toolset.ajax.class.php',
|
157 |
'Toolset_Ajax_Handler_Abstract' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/ajax_handler/abstract.php',
|
|
|
|
|
|
|
|
|
|
|
158 |
'Toolset_Ajax_Handler_Interface' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/ajax_handler/interface.php',
|
|
|
159 |
'Toolset_Ajax_Handler_Migrate_To_M2M' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/ajax_handler/migrate_to_m2m.php',
|
|
|
|
|
|
|
160 |
'Toolset_ArrayUtils' => __DIR__ . '/..' . '/toolset/toolset-common/utility/utils.php',
|
161 |
-
'Toolset_Asset_Manager' => __DIR__ . '/..' . '/toolset/toolset-common/inc/
|
162 |
'Toolset_Assets_Manager' => __DIR__ . '/..' . '/toolset/toolset-common/inc/toolset.assets.manager.class.php',
|
163 |
-
'Toolset_Association' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/association.php',
|
164 |
-
'
|
165 |
-
'
|
166 |
-
'
|
167 |
-
'
|
168 |
-
'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
169 |
'Toolset_Bootstrap_Loader' => __DIR__ . '/..' . '/toolset/toolset-common/inc/toolset.bootstrap.loader.class.php',
|
170 |
'Toolset_Common_Autoloader' => __DIR__ . '/..' . '/toolset/toolset-common/utility/autoloader.php',
|
171 |
'Toolset_Common_Bootstrap' => __DIR__ . '/..' . '/toolset/toolset-common/bootstrap.php',
|
@@ -179,11 +243,14 @@ class ComposerStaticInita469bff8809f0826cf254ebc61c9ca28
|
|
179 |
'Toolset_Condition_Plugin_Layouts_Missing' => __DIR__ . '/..' . '/toolset/toolset-common/utility/condition/plugin/layouts/missing.php',
|
180 |
'Toolset_Condition_Plugin_Layouts_No_Items' => __DIR__ . '/..' . '/toolset/toolset-common/utility/condition/plugin/layouts/no-items.php',
|
181 |
'Toolset_Condition_Plugin_Types_Active' => __DIR__ . '/..' . '/toolset/toolset-common/utility/condition/plugin/types/active.php',
|
|
|
182 |
'Toolset_Condition_Plugin_Types_Missing' => __DIR__ . '/..' . '/toolset/toolset-common/utility/condition/plugin/types/missing.php',
|
183 |
'Toolset_Condition_Plugin_Types_Ready_For_M2M' => __DIR__ . '/..' . '/toolset/toolset-common/utility/condition/plugin/types/ready_for_m2m.php',
|
184 |
'Toolset_Condition_Plugin_Views_Active' => __DIR__ . '/..' . '/toolset/toolset-common/utility/condition/plugin/views/active.php',
|
185 |
'Toolset_Condition_Plugin_Views_Missing' => __DIR__ . '/..' . '/toolset/toolset-common/utility/condition/plugin/views/missing.php',
|
186 |
'Toolset_Condition_Plugin_Wpml_Doesnt_Support_M2m' => __DIR__ . '/..' . '/toolset/toolset-common/utility/condition/plugin/wpml/doesnt_support_m2m.php',
|
|
|
|
|
187 |
'Toolset_Condition_Theme_Avada_Not_Active_Or_Greater_Equal_5_0' => __DIR__ . '/..' . '/toolset/toolset-common/utility/condition/theme/avada/not-active-or-greater-equal-5-0.php',
|
188 |
'Toolset_Condition_Theme_Layouts_Support_Native_Available' => __DIR__ . '/..' . '/toolset/toolset-common/utility/condition/theme/layouts-support/native/available.php',
|
189 |
'Toolset_Condition_Theme_Layouts_Support_Native_Missing' => __DIR__ . '/..' . '/toolset/toolset-common/utility/condition/theme/layouts-support/native/missing.php',
|
@@ -198,8 +265,10 @@ class ComposerStaticInita469bff8809f0826cf254ebc61c9ca28
|
|
198 |
'Toolset_Condition_Theme_Toolset_Based_Active' => __DIR__ . '/..' . '/toolset/toolset-common/utility/condition/theme/toolset-based/active.php',
|
199 |
'Toolset_Condition_Theme_Toolset_Based_Inactive' => __DIR__ . '/..' . '/toolset/toolset-common/utility/condition/theme/toolset-based/inactive.php',
|
200 |
'Toolset_Condition_User_Role_Admin' => __DIR__ . '/..' . '/toolset/toolset-common/utility/condition/user/role/admin.php',
|
201 |
-
'Toolset_Constants' => __DIR__ . '/..' . '/toolset/toolset-common/inc/
|
202 |
-
'Toolset_Controller_Admin_Notices' => __DIR__ . '/..' . '/toolset/toolset-common/inc/
|
|
|
|
|
203 |
'Toolset_CssComponent' => __DIR__ . '/..' . '/toolset/toolset-common/inc/toolset.css.component.class.php',
|
204 |
'Toolset_Date' => __DIR__ . '/..' . '/toolset/toolset-common/expression-parser/parser.php',
|
205 |
'Toolset_DateParser' => __DIR__ . '/..' . '/toolset/toolset-common/expression-parser/parser.php',
|
@@ -225,10 +294,12 @@ class ComposerStaticInita469bff8809f0826cf254ebc61c9ca28
|
|
225 |
'Toolset_Field_Definition' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/field/definition.php',
|
226 |
'Toolset_Field_Definition_Abstract' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/field/definition_abstract.php',
|
227 |
'Toolset_Field_Definition_Factory' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/field/definition_factory.php',
|
|
|
228 |
'Toolset_Field_Definition_Factory_Post' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/field/definition_factory_post.php',
|
229 |
'Toolset_Field_Definition_Factory_Term' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/field/definition_factory_term.php',
|
230 |
'Toolset_Field_Definition_Factory_User' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/field/definition_factory_user.php',
|
231 |
'Toolset_Field_Definition_Generic' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/field/definition_generic.php',
|
|
|
232 |
'Toolset_Field_Definition_Post' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/field/definition_post.php',
|
233 |
'Toolset_Field_Definition_Term' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/field/definition_term.php',
|
234 |
'Toolset_Field_Definition_User' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/field/definition_user.php',
|
@@ -274,6 +345,7 @@ class ComposerStaticInita469bff8809f0826cf254ebc61c9ca28
|
|
274 |
'Toolset_Field_Type_Definition_Select' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/field/type/definition/select.php',
|
275 |
'Toolset_Field_Type_Definition_Singular' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/field/type/definition/singular.php',
|
276 |
'Toolset_Field_Utils' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/field/utils.php',
|
|
|
277 |
'Toolset_Functions' => __DIR__ . '/..' . '/toolset/toolset-common/expression-parser/parser.php',
|
278 |
'Toolset_Gui_Base' => __DIR__ . '/..' . '/toolset/toolset-common/utility/gui-base/main.php',
|
279 |
'Toolset_HelpVideo' => __DIR__ . '/..' . '/toolset/toolset-common/utility/help-videos/toolset-help-videos.php',
|
@@ -283,9 +355,17 @@ class ComposerStaticInita469bff8809f0826cf254ebc61c9ca28
|
|
283 |
'Toolset_Menu' => __DIR__ . '/..' . '/toolset/toolset-common/inc/toolset.menu.class.php',
|
284 |
'Toolset_Naming_Helper' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/naming_helper.php',
|
285 |
'Toolset_Object_Relationship' => __DIR__ . '/..' . '/toolset/toolset-common/inc/toolset.object.relationship.class.php',
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
286 |
'Toolset_Parser' => __DIR__ . '/..' . '/toolset/toolset-common/expression-parser/parser.php',
|
287 |
'Toolset_Post' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/element/post.php',
|
288 |
'Toolset_Post_Translation_Set' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/element/post_translation_set.php',
|
|
|
289 |
'Toolset_Post_Type_Exclude_List' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/post_type/excluded_list.php',
|
290 |
'Toolset_Post_Type_Factory' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/post_type/factory.php',
|
291 |
'Toolset_Post_Type_From_Types' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/post_type/from_types.php',
|
@@ -297,63 +377,67 @@ class ComposerStaticInita469bff8809f0826cf254ebc61c9ca28
|
|
297 |
'Toolset_Potential_Association_Query_Factory' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/potential_association/query_factory.php',
|
298 |
'Toolset_Potential_Association_Query_Posts' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/potential_association/query_posts.php',
|
299 |
'Toolset_Promotion' => __DIR__ . '/..' . '/toolset/toolset-common/inc/toolset.promotion.class.php',
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
300 |
'Toolset_Regex' => __DIR__ . '/..' . '/toolset/toolset-common/expression-parser/parser.php',
|
301 |
'Toolset_Relationship_Cardinality' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/cardinality.php',
|
302 |
'Toolset_Relationship_Controller' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/controller.php',
|
303 |
'Toolset_Relationship_Database_Issue_Missing_Element' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/database/issue/missing_element.php',
|
304 |
'Toolset_Relationship_Database_Operations' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/database/operations.php',
|
305 |
'Toolset_Relationship_Database_Unique_Table_Alias' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/database/unique_table_alias.php',
|
306 |
-
'Toolset_Relationship_Definition' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/definition/definition.php',
|
307 |
-
'Toolset_Relationship_Definition_Factory' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/definition/factory.php',
|
308 |
-
'Toolset_Relationship_Definition_Persistence' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/definition/persistence.php',
|
309 |
-
'Toolset_Relationship_Definition_Repository' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/definition/repository.php',
|
310 |
-
'Toolset_Relationship_Definition_Translator' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/definition/translator.php',
|
311 |
'Toolset_Relationship_Distinct_Post_Query' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/potential_association/distinct_post_query.php',
|
312 |
'Toolset_Relationship_Driver' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/driver.php',
|
313 |
'Toolset_Relationship_Driver_Base' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/driver_base.php',
|
314 |
'Toolset_Relationship_Element_Type' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/element_type.php',
|
315 |
-
'Toolset_Relationship_Migration' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/migration.php',
|
316 |
-
'Toolset_Relationship_Migration_Associations' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/
|
317 |
-
'
|
|
|
318 |
'Toolset_Relationship_Origin_Post_Reference_Field' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/origin/post_reference_field.php',
|
319 |
'Toolset_Relationship_Origin_Repeatable_Group' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/origin/repeatable_group.php',
|
320 |
'Toolset_Relationship_Origin_Wizard' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/origin/wizard.php',
|
321 |
-
'Toolset_Relationship_Query' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/
|
322 |
'Toolset_Relationship_Query_Base' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/query_base.php',
|
323 |
'Toolset_Relationship_Query_Cache' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/query_cache.php',
|
324 |
-
'Toolset_Relationship_Query_Cardinality_Match_Conjunction' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/
|
325 |
-
'Toolset_Relationship_Query_Cardinality_Match_Factory' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/
|
326 |
-
'Toolset_Relationship_Query_Cardinality_Match_Operators' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/
|
327 |
-
'Toolset_Relationship_Query_Cardinality_Match_Single' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/
|
328 |
-
'Toolset_Relationship_Query_Condition' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/
|
329 |
-
'
|
330 |
-
'
|
331 |
-
'
|
332 |
-
'
|
333 |
-
'
|
334 |
-
'
|
335 |
-
'
|
336 |
-
'
|
337 |
-
'
|
338 |
-
'
|
339 |
-
'
|
340 |
-
'
|
341 |
-
'
|
342 |
-
'
|
343 |
-
'
|
344 |
-
'
|
345 |
-
'
|
346 |
-
'
|
347 |
-
'Toolset_Relationship_Role_Child' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/relationship_role/child.php',
|
348 |
-
'Toolset_Relationship_Role_Intermediary' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/relationship_role/intermediary.php',
|
349 |
-
'Toolset_Relationship_Role_Parent' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/relationship_role/parent.php',
|
350 |
-
'Toolset_Relationship_Scope' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/scope.php',
|
351 |
'Toolset_Relationship_Service' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/relationship_service.php',
|
352 |
-
'Toolset_Relationship_Slug_Validator' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/slug_validator.php',
|
353 |
'Toolset_Relationship_Table_Name' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/database/table_name.php',
|
354 |
'Toolset_Relationship_Utils' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/utils.php',
|
355 |
-
'Toolset_Relationship_WPML_Interoperability' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/wpml_interoperability.php',
|
356 |
'Toolset_Relevanssi_Compatibility' => __DIR__ . '/..' . '/toolset/toolset-common/inc/toolset.relevanssi.compatibility.class.php',
|
|
|
357 |
'Toolset_Result' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/result.php',
|
358 |
'Toolset_Result_Set' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/result_set.php',
|
359 |
'Toolset_Result_Updated' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/result_updated.php',
|
@@ -369,6 +453,7 @@ class ComposerStaticInita469bff8809f0826cf254ebc61c9ca28
|
|
369 |
'Toolset_Shortcode_Transformer' => __DIR__ . '/..' . '/toolset/toolset-common/inc/toolset.shortcode.transformer.class.php',
|
370 |
'Toolset_Stack' => __DIR__ . '/..' . '/toolset/toolset-common/expression-parser/parser.php',
|
371 |
'Toolset_Style' => __DIR__ . '/..' . '/toolset/toolset-common/inc/toolset.assets.manager.class.php',
|
|
|
372 |
'Toolset_Tokenizer' => __DIR__ . '/..' . '/toolset/toolset-common/expression-parser/parser.php',
|
373 |
'Toolset_Twig_Autoloader' => __DIR__ . '/..' . '/toolset/toolset-common/utility/gui-base/twig_autoloader.php',
|
374 |
'Toolset_Twig_Dialog_Box' => __DIR__ . '/..' . '/toolset/toolset-common/utility/gui-base/twig_dialog_box.php',
|
@@ -385,6 +470,7 @@ class ComposerStaticInita469bff8809f0826cf254ebc61c9ca28
|
|
385 |
'Toolset_User_Editors_Editor_Basic' => __DIR__ . '/..' . '/toolset/toolset-common/user-editors/editor/basic.php',
|
386 |
'Toolset_User_Editors_Editor_Beaver' => __DIR__ . '/..' . '/toolset/toolset-common/user-editors/editor/beaver.php',
|
387 |
'Toolset_User_Editors_Editor_Divi' => __DIR__ . '/..' . '/toolset/toolset-common/user-editors/editor/divi.php',
|
|
|
388 |
'Toolset_User_Editors_Editor_Interface' => __DIR__ . '/..' . '/toolset/toolset-common/user-editors/editor/interface.php',
|
389 |
'Toolset_User_Editors_Editor_Native' => __DIR__ . '/..' . '/toolset/toolset-common/user-editors/editor/native.php',
|
390 |
'Toolset_User_Editors_Editor_Screen_Abstract' => __DIR__ . '/..' . '/toolset/toolset-common/user-editors/editor/screen/abstract.php',
|
@@ -395,6 +481,7 @@ class ComposerStaticInita469bff8809f0826cf254ebc61c9ca28
|
|
395 |
'Toolset_User_Editors_Editor_Screen_Beaver_Frontend_Editor' => __DIR__ . '/..' . '/toolset/toolset-common/user-editors/editor/screen/beaver/frontend-editor.php',
|
396 |
'Toolset_User_Editors_Editor_Screen_Divi_Backend' => __DIR__ . '/..' . '/toolset/toolset-common/user-editors/editor/screen/divi/backend.php',
|
397 |
'Toolset_User_Editors_Editor_Screen_Divi_Frontend' => __DIR__ . '/..' . '/toolset/toolset-common/user-editors/editor/screen/divi/frontend.php',
|
|
|
398 |
'Toolset_User_Editors_Editor_Screen_Interface' => __DIR__ . '/..' . '/toolset/toolset-common/user-editors/editor/screen/interface.php',
|
399 |
'Toolset_User_Editors_Editor_Screen_Native_Backend' => __DIR__ . '/..' . '/toolset/toolset-common/user-editors/editor/screen/native/backend.php',
|
400 |
'Toolset_User_Editors_Editor_Screen_Visual_Composer_Backend' => __DIR__ . '/..' . '/toolset/toolset-common/user-editors/editor/screen/visual-composer/backend.php',
|
@@ -414,6 +501,12 @@ class ComposerStaticInita469bff8809f0826cf254ebc61c9ca28
|
|
414 |
'Toolset_VideoDetachedPage' => __DIR__ . '/..' . '/toolset/toolset-common/utility/help-videos/toolset-help-videos.php',
|
415 |
'Toolset_WPLogger' => __DIR__ . '/..' . '/toolset/toolset-common/inc/toolset.wplogger.class.php',
|
416 |
'Toolset_WPML_Compatibility' => __DIR__ . '/..' . '/toolset/toolset-common/inc/toolset.wpml.compatibility.class.php',
|
|
|
|
|
|
|
|
|
|
|
|
|
417 |
'Toolset_Wpml_Utils' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/wpml_utils.php',
|
418 |
'Twig_Autoloader' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Autoloader.php',
|
419 |
'Twig_BaseNodeVisitor' => __DIR__ . '/..' . '/twig/twig/lib/Twig/BaseNodeVisitor.php',
|
@@ -640,14 +733,14 @@ class ComposerStaticInita469bff8809f0826cf254ebc61c9ca28
|
|
640 |
'Types_Field_Group_User_Factory' => __DIR__ . '/../..' . '/application/models/field/group/user_factory.php',
|
641 |
'Types_Field_Type_Converter' => __DIR__ . '/../..' . '/application/controllers/field/type_converter.php',
|
642 |
'Types_Field_Type_Definition' => __DIR__ . '/../..' . '/application/models/field/type/definition.php',
|
643 |
-
'Types_Field_Type_Definition_Checkbox' => __DIR__ . '/../..' . '/application/models/field/
|
644 |
-
'Types_Field_Type_Definition_Checkboxes' => __DIR__ . '/../..' . '/application/models/field/
|
645 |
-
'Types_Field_Type_Definition_Date' => __DIR__ . '/../..' . '/application/models/field/
|
646 |
'Types_Field_Type_Definition_Factory' => __DIR__ . '/../..' . '/application/models/field/type/definition_factory.php',
|
647 |
-
'Types_Field_Type_Definition_Numeric' => __DIR__ . '/../..' . '/application/models/field/
|
648 |
-
'Types_Field_Type_Definition_Radio' => __DIR__ . '/../..' . '/application/models/field/
|
649 |
-
'Types_Field_Type_Definition_Select' => __DIR__ . '/../..' . '/application/models/field/
|
650 |
-
'Types_Field_Type_Definition_Singular' => __DIR__ . '/../..' . '/application/models/field/
|
651 |
'Types_Field_Utils' => __DIR__ . '/../..' . '/application/controllers/field/utils.php',
|
652 |
'Types_Frontend' => __DIR__ . '/../..' . '/application/controllers/frontend.php',
|
653 |
'Types_Helper_Condition' => __DIR__ . '/../..' . '/application/models/helper/condition.php',
|
@@ -726,7 +819,7 @@ class ComposerStaticInita469bff8809f0826cf254ebc61c9ca28
|
|
726 |
'Types_Taxonomy' => __DIR__ . '/../..' . '/application/models/taxonomy.php',
|
727 |
'Types_Twig_Autoloader' => __DIR__ . '/../..' . '/application/controllers/twig_autoloader.php',
|
728 |
'Types_Upgrade' => __DIR__ . '/../..' . '/application/controllers/upgrade.php',
|
729 |
-
'Types_Utils' => __DIR__ . '/../..' . '/application/controllers/
|
730 |
'Types_Utils_Post_Type_Option' => __DIR__ . '/../..' . '/application/controllers/utils/post_type_option.php',
|
731 |
'Types_Wpml_Field_Group' => __DIR__ . '/../..' . '/application/models/wpml/field_group.php',
|
732 |
'Types_Wpml_Field_Group_String' => __DIR__ . '/../..' . '/application/models/wpml/field/group/string.php',
|
@@ -776,10 +869,10 @@ class ComposerStaticInita469bff8809f0826cf254ebc61c9ca28
|
|
776 |
public static function getInitializer(ClassLoader $loader)
|
777 |
{
|
778 |
return \Closure::bind(function () use ($loader) {
|
779 |
-
$loader->prefixLengthsPsr4 =
|
780 |
-
$loader->prefixDirsPsr4 =
|
781 |
-
$loader->prefixesPsr0 =
|
782 |
-
$loader->classMap =
|
783 |
|
784 |
}, null, ClassLoader::class);
|
785 |
}
|
4 |
|
5 |
namespace Composer\Autoload;
|
6 |
|
7 |
+
class ComposerStaticInitc3c1dc77e2581741c891ff7b2bf920aa
|
8 |
{
|
9 |
public static $files = array (
|
10 |
'a52c1eba913b4ecdd3571194b37baea9' => __DIR__ . '/../..' . '/application/functions.php',
|
125 |
'FieldFactory' => __DIR__ . '/..' . '/toolset/toolset-common/toolset-forms/classes/class.field_factory.php',
|
126 |
'FormAbstract' => __DIR__ . '/..' . '/toolset/toolset-common/toolset-forms/classes/abstract.form.php',
|
127 |
'FormFactory' => __DIR__ . '/..' . '/toolset/toolset-common/toolset-forms/classes/class.form_factory.php',
|
128 |
+
'IToolset_Association' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/association/interface.php',
|
129 |
+
'IToolset_Association_Query_Condition' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/association/query/condition/interface.php',
|
130 |
+
'IToolset_Association_Query_Element_Selector' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/association/query/element_selector/interface.php',
|
131 |
+
'IToolset_Association_Query_Orderby' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/association/query/orderby/interface.php',
|
132 |
+
'IToolset_Association_Query_Restriction' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/association/query/restriction/interface.php',
|
133 |
+
'IToolset_Association_Query_Result_Transformation' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/association/query/result_transformation/interface.php',
|
134 |
+
'IToolset_Cron_Event' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/cron/event_interface.php',
|
135 |
'IToolset_Element' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/element/i_element.php',
|
136 |
+
'IToolset_Output_Template' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/renderer/output_template/interface.php',
|
137 |
'IToolset_Post' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/element/i_post.php',
|
138 |
'IToolset_Post_Type' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/post_type/i_post_type.php',
|
139 |
'IToolset_Post_Type_From_Types' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/post_type/i_post_type_from_types.php',
|
140 |
'IToolset_Post_Type_Registered' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/post_type/i_post_type_registered.php',
|
141 |
'IToolset_Potential_Association_Query' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/potential_association/query_interface.php',
|
142 |
'IToolset_Query' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/i_query.php',
|
143 |
+
'IToolset_Query_Condition' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/query/condition/interface.php',
|
144 |
'IToolset_Relationship_Database_Issue' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/database/issue/interface.php',
|
145 |
+
'IToolset_Relationship_Definition' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/relationship/definition/interface.php',
|
146 |
'IToolset_Relationship_Origin' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/origin/interface.php',
|
147 |
+
'IToolset_Relationship_Query_Cardinality_Match' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/relationship/query/cardinality_match/interface.php',
|
148 |
+
'IToolset_Relationship_Query_Condition' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/relationship/query/condition/interface.php',
|
149 |
+
'IToolset_Relationship_Role' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/relationship/role/interface.php',
|
150 |
+
'IToolset_Relationship_Role_Parent_Child' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/relationship/role/parent_child_interface.php',
|
151 |
'IToolset_Upgrade_Command' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/upgrade/command_interface.php',
|
152 |
'ReCaptchaResponse' => __DIR__ . '/..' . '/toolset/toolset-common/toolset-forms/js/recaptcha-php-1.11/recaptchalib.php',
|
153 |
'Toolset_Admin_Bar_Menu' => __DIR__ . '/..' . '/toolset/toolset-common/inc/toolset.admin.bar.menu.class.php',
|
154 |
+
'Toolset_Admin_Controller' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/admin.php',
|
155 |
'Toolset_Admin_Notice_Abstract' => __DIR__ . '/..' . '/toolset/toolset-common/utility/admin/notice/abstract.php',
|
156 |
'Toolset_Admin_Notice_Dismissible' => __DIR__ . '/..' . '/toolset/toolset-common/utility/admin/notice/dismissible.php',
|
157 |
'Toolset_Admin_Notice_Error' => __DIR__ . '/..' . '/toolset/toolset-common/utility/admin/notice/error.php',
|
164 |
'Toolset_Admin_Notices_Manager' => __DIR__ . '/..' . '/toolset/toolset-common/utility/admin/notices/manager.php',
|
165 |
'Toolset_Ajax' => __DIR__ . '/..' . '/toolset/toolset-common/inc/toolset.ajax.class.php',
|
166 |
'Toolset_Ajax_Handler_Abstract' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/ajax_handler/abstract.php',
|
167 |
+
'Toolset_Ajax_Handler_Get_Content_Template_Block_Preview' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/ajax_handler/get_ct_block_preview.php',
|
168 |
+
'Toolset_Ajax_Handler_Get_Post_By_Id' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/ajax_handler/get_post_by_id.php',
|
169 |
+
'Toolset_Ajax_Handler_Get_Term_By_Id' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/ajax_handler/get_term_by_id.php',
|
170 |
+
'Toolset_Ajax_Handler_Get_User_By_Id' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/ajax_handler/get_user_by_id.php',
|
171 |
+
'Toolset_Ajax_Handler_Get_View_Block_Preview' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/ajax_handler/get_view_block_preview.php',
|
172 |
'Toolset_Ajax_Handler_Interface' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/ajax_handler/interface.php',
|
173 |
+
'Toolset_Ajax_Handler_Intermediary_Post_Cleanup' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/ajax_handler/intermediary_post_cleanup.php',
|
174 |
'Toolset_Ajax_Handler_Migrate_To_M2M' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/ajax_handler/migrate_to_m2m.php',
|
175 |
+
'Toolset_Ajax_Handler_Select2_Suggest_Posts_By_Title' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/ajax_handler/select2_suggest_posts_by_title.php',
|
176 |
+
'Toolset_Ajax_Handler_Select2_Suggest_Terms' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/ajax_handler/select2_suggest_terms.php',
|
177 |
+
'Toolset_Ajax_Handler_Select2_Suggest_Users' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/ajax_handler/select2_suggest_users.php',
|
178 |
'Toolset_ArrayUtils' => __DIR__ . '/..' . '/toolset/toolset-common/utility/utils.php',
|
179 |
+
'Toolset_Asset_Manager' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/asset_manager.php',
|
180 |
'Toolset_Assets_Manager' => __DIR__ . '/..' . '/toolset/toolset-common/inc/toolset.assets.manager.class.php',
|
181 |
+
'Toolset_Association' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/association/association.php',
|
182 |
+
'Toolset_Association_Cleanup_Association' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/association/cleanup/association.php',
|
183 |
+
'Toolset_Association_Cleanup_Cron_Event' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/association/cleanup/cron_event.php',
|
184 |
+
'Toolset_Association_Cleanup_Cron_Handler' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/association/cleanup/cron_handler.php',
|
185 |
+
'Toolset_Association_Cleanup_Dangling_Intermediary_Posts' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/association/cleanup/dangling_intermediary_posts.php',
|
186 |
+
'Toolset_Association_Cleanup_Factory' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/association/cleanup/factory.php',
|
187 |
+
'Toolset_Association_Cleanup_Post' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/association/cleanup/post.php',
|
188 |
+
'Toolset_Association_Cleanup_Troubleshooting_Section' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/association/cleanup/troubleshooting_section.php',
|
189 |
+
'Toolset_Association_Factory' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/association/factory.php',
|
190 |
+
'Toolset_Association_Intermediary_Post_Persistence' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/association/intermediary_post_persistence.php',
|
191 |
+
'Toolset_Association_Persistence' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/association/persistence.php',
|
192 |
+
'Toolset_Association_Query' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/association/query/association_query.php',
|
193 |
+
'Toolset_Association_Query_Condition' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/association/query/condition/abstract.php',
|
194 |
+
'Toolset_Association_Query_Condition_Association_Id' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/association/query/condition/association_id.php',
|
195 |
+
'Toolset_Association_Query_Condition_Element_Id' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/association/query/condition/element_id.php',
|
196 |
+
'Toolset_Association_Query_Condition_Element_Id_And_Domain' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/association/query/condition/element_id_and_domain.php',
|
197 |
+
'Toolset_Association_Query_Condition_Element_Status' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/association/query/condition/element_status.php',
|
198 |
+
'Toolset_Association_Query_Condition_Empty_Intermediary' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/association/query/condition/empty_intermediary.php',
|
199 |
+
'Toolset_Association_Query_Condition_Exclude_Element' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/association/query/condition/exclude_element.php',
|
200 |
+
'Toolset_Association_Query_Condition_Factory' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/association/query/condition_factory.php',
|
201 |
+
'Toolset_Association_Query_Condition_Has_Active_Relationship' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/association/query/condition/has_active_relationship.php',
|
202 |
+
'Toolset_Association_Query_Condition_Has_Domain' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/association/query/condition/has_domain.php',
|
203 |
+
'Toolset_Association_Query_Condition_Has_Domain_And_Type' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/association/query/condition/has_domain_and_type.php',
|
204 |
+
'Toolset_Association_Query_Condition_Has_Legacy_Relationship' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/association/query/condition/has_legacy_relationship.php',
|
205 |
+
'Toolset_Association_Query_Condition_Has_Type' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/association/query/condition/has_type.php',
|
206 |
+
'Toolset_Association_Query_Condition_Postmeta' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/association/query/condition/postmeta.php',
|
207 |
+
'Toolset_Association_Query_Condition_Relationship_Flag' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/association/query/condition/relationship_flag.php',
|
208 |
+
'Toolset_Association_Query_Condition_Relationship_Id' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/association/query/condition/relationship_id.php',
|
209 |
+
'Toolset_Association_Query_Condition_Search' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/association/query/condition/search.php',
|
210 |
+
'Toolset_Association_Query_Condition_Wp_Query' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/association/query/condition/wp_query.php',
|
211 |
+
'Toolset_Association_Query_Element_Selector_Abstract' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/association/query/element_selector/abstract.php',
|
212 |
+
'Toolset_Association_Query_Element_Selector_Default' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/association/query/element_selector/default.php',
|
213 |
+
'Toolset_Association_Query_Element_Selector_Provider' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/association/query/element_selector/provider.php',
|
214 |
+
'Toolset_Association_Query_Element_Selector_Wpml' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/association/query/element_selector/wpml.php',
|
215 |
+
'Toolset_Association_Query_Orderby' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/association/query/orderby/abstract.php',
|
216 |
+
'Toolset_Association_Query_Orderby_Factory' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/association/query/orderby_factory.php',
|
217 |
+
'Toolset_Association_Query_Orderby_Nothing' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/association/query/orderby/nothing.php',
|
218 |
+
'Toolset_Association_Query_Orderby_Postmeta' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/association/query/orderby/postmeta.php',
|
219 |
+
'Toolset_Association_Query_Orderby_Title' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/association/query/orderby/title.php',
|
220 |
+
'Toolset_Association_Query_Result_Transformation_Association_Instance' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/association/query/result_transformation/association_instance.php',
|
221 |
+
'Toolset_Association_Query_Result_Transformation_Association_Uid' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/association/query/result_transformation/association_uid.php',
|
222 |
+
'Toolset_Association_Query_Result_Transformation_Element_Id' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/association/query/result_transformation/element_id.php',
|
223 |
+
'Toolset_Association_Query_Result_Transformation_Element_Instance' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/association/query/result_transformation/element_instance.php',
|
224 |
+
'Toolset_Association_Query_Sql_Expression_Builder' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/association/query/sql_expression_builder.php',
|
225 |
+
'Toolset_Association_Query_Table_Join_Manager' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/association/query/table_join_manager.php',
|
226 |
+
'Toolset_Association_Query_V2' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/association/query/association_query_v2.php',
|
227 |
+
'Toolset_Association_Query_Wpdb_Wrapper' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/association/query/wpdb_wrapper.php',
|
228 |
+
'Toolset_Association_Translator' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/association/translator.php',
|
229 |
+
'Toolset_Blocks' => __DIR__ . '/..' . '/toolset/toolset-common/toolset-blocks/toolset-blocks.php',
|
230 |
+
'Toolset_Blocks_Content_Template' => __DIR__ . '/..' . '/toolset/toolset-common/toolset-blocks/blocks/ct/ct.php',
|
231 |
+
'Toolset_Blocks_Custom_HTML' => __DIR__ . '/..' . '/toolset/toolset-common/toolset-blocks/blocks/custom-html/custom-html.php',
|
232 |
+
'Toolset_Blocks_View' => __DIR__ . '/..' . '/toolset/toolset-common/toolset-blocks/blocks/view/view.php',
|
233 |
'Toolset_Bootstrap_Loader' => __DIR__ . '/..' . '/toolset/toolset-common/inc/toolset.bootstrap.loader.class.php',
|
234 |
'Toolset_Common_Autoloader' => __DIR__ . '/..' . '/toolset/toolset-common/utility/autoloader.php',
|
235 |
'Toolset_Common_Bootstrap' => __DIR__ . '/..' . '/toolset/toolset-common/bootstrap.php',
|
243 |
'Toolset_Condition_Plugin_Layouts_Missing' => __DIR__ . '/..' . '/toolset/toolset-common/utility/condition/plugin/layouts/missing.php',
|
244 |
'Toolset_Condition_Plugin_Layouts_No_Items' => __DIR__ . '/..' . '/toolset/toolset-common/utility/condition/plugin/layouts/no-items.php',
|
245 |
'Toolset_Condition_Plugin_Types_Active' => __DIR__ . '/..' . '/toolset/toolset-common/utility/condition/plugin/types/active.php',
|
246 |
+
'Toolset_Condition_Plugin_Types_Has_Legacy_Relationships' => __DIR__ . '/..' . '/toolset/toolset-common/utility/condition/plugin/types/has_legacy_relationships.php',
|
247 |
'Toolset_Condition_Plugin_Types_Missing' => __DIR__ . '/..' . '/toolset/toolset-common/utility/condition/plugin/types/missing.php',
|
248 |
'Toolset_Condition_Plugin_Types_Ready_For_M2M' => __DIR__ . '/..' . '/toolset/toolset-common/utility/condition/plugin/types/ready_for_m2m.php',
|
249 |
'Toolset_Condition_Plugin_Views_Active' => __DIR__ . '/..' . '/toolset/toolset-common/utility/condition/plugin/views/active.php',
|
250 |
'Toolset_Condition_Plugin_Views_Missing' => __DIR__ . '/..' . '/toolset/toolset-common/utility/condition/plugin/views/missing.php',
|
251 |
'Toolset_Condition_Plugin_Wpml_Doesnt_Support_M2m' => __DIR__ . '/..' . '/toolset/toolset-common/utility/condition/plugin/wpml/doesnt_support_m2m.php',
|
252 |
+
'Toolset_Condition_Plugin_Wpml_Is_Active_And_Configured' => __DIR__ . '/..' . '/toolset/toolset-common/utility/condition/plugin/wpml/is_active_and_configured.php',
|
253 |
+
'Toolset_Condition_Plugin_Wpml_Is_Current_Language_Default' => __DIR__ . '/..' . '/toolset/toolset-common/utility/condition/plugin/wpml/is_current_language_default.php',
|
254 |
'Toolset_Condition_Theme_Avada_Not_Active_Or_Greater_Equal_5_0' => __DIR__ . '/..' . '/toolset/toolset-common/utility/condition/theme/avada/not-active-or-greater-equal-5-0.php',
|
255 |
'Toolset_Condition_Theme_Layouts_Support_Native_Available' => __DIR__ . '/..' . '/toolset/toolset-common/utility/condition/theme/layouts-support/native/available.php',
|
256 |
'Toolset_Condition_Theme_Layouts_Support_Native_Missing' => __DIR__ . '/..' . '/toolset/toolset-common/utility/condition/theme/layouts-support/native/missing.php',
|
265 |
'Toolset_Condition_Theme_Toolset_Based_Active' => __DIR__ . '/..' . '/toolset/toolset-common/utility/condition/theme/toolset-based/active.php',
|
266 |
'Toolset_Condition_Theme_Toolset_Based_Inactive' => __DIR__ . '/..' . '/toolset/toolset-common/utility/condition/theme/toolset-based/inactive.php',
|
267 |
'Toolset_Condition_User_Role_Admin' => __DIR__ . '/..' . '/toolset/toolset-common/utility/condition/user/role/admin.php',
|
268 |
+
'Toolset_Constants' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/constants.php',
|
269 |
+
'Toolset_Controller_Admin_Notices' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/admin/notices.php',
|
270 |
+
'Toolset_Cron' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/cron/cron.php',
|
271 |
+
'Toolset_Cron_Event' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/cron/event.php',
|
272 |
'Toolset_CssComponent' => __DIR__ . '/..' . '/toolset/toolset-common/inc/toolset.css.component.class.php',
|
273 |
'Toolset_Date' => __DIR__ . '/..' . '/toolset/toolset-common/expression-parser/parser.php',
|
274 |
'Toolset_DateParser' => __DIR__ . '/..' . '/toolset/toolset-common/expression-parser/parser.php',
|
294 |
'Toolset_Field_Definition' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/field/definition.php',
|
295 |
'Toolset_Field_Definition_Abstract' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/field/definition_abstract.php',
|
296 |
'Toolset_Field_Definition_Factory' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/field/definition_factory.php',
|
297 |
+
'Toolset_Field_Definition_Factory_Interface' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/field/definition_factory_interface.php',
|
298 |
'Toolset_Field_Definition_Factory_Post' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/field/definition_factory_post.php',
|
299 |
'Toolset_Field_Definition_Factory_Term' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/field/definition_factory_term.php',
|
300 |
'Toolset_Field_Definition_Factory_User' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/field/definition_factory_user.php',
|
301 |
'Toolset_Field_Definition_Generic' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/field/definition_generic.php',
|
302 |
+
'Toolset_Field_Definition_Interface' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/field/definition_interface.php',
|
303 |
'Toolset_Field_Definition_Post' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/field/definition_post.php',
|
304 |
'Toolset_Field_Definition_Term' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/field/definition_term.php',
|
305 |
'Toolset_Field_Definition_User' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/field/definition_user.php',
|
345 |
'Toolset_Field_Type_Definition_Select' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/field/type/definition/select.php',
|
346 |
'Toolset_Field_Type_Definition_Singular' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/field/type/definition/singular.php',
|
347 |
'Toolset_Field_Utils' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/field/utils.php',
|
348 |
+
'Toolset_Files' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/files.php',
|
349 |
'Toolset_Functions' => __DIR__ . '/..' . '/toolset/toolset-common/expression-parser/parser.php',
|
350 |
'Toolset_Gui_Base' => __DIR__ . '/..' . '/toolset/toolset-common/utility/gui-base/main.php',
|
351 |
'Toolset_HelpVideo' => __DIR__ . '/..' . '/toolset/toolset-common/utility/help-videos/toolset-help-videos.php',
|
355 |
'Toolset_Menu' => __DIR__ . '/..' . '/toolset/toolset-common/inc/toolset.menu.class.php',
|
356 |
'Toolset_Naming_Helper' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/naming_helper.php',
|
357 |
'Toolset_Object_Relationship' => __DIR__ . '/..' . '/toolset/toolset-common/inc/toolset.object.relationship.class.php',
|
358 |
+
'Toolset_Output_Template' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/renderer/output_template/abstract.php',
|
359 |
+
'Toolset_Output_Template_Factory' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/renderer/output_template_factory.php',
|
360 |
+
'Toolset_Output_Template_Phtml' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/renderer/output_template/phtml.php',
|
361 |
+
'Toolset_Output_Template_Repository' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/renderer/output_template_repository.php',
|
362 |
+
'Toolset_Output_Template_Repository_Abstract' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/renderer/output_template_repository_abstract.php',
|
363 |
+
'Toolset_Output_Template_Static' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/renderer/output_template/static.php',
|
364 |
+
'Toolset_Output_Template_Twig' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/renderer/output_template/twig.php',
|
365 |
'Toolset_Parser' => __DIR__ . '/..' . '/toolset/toolset-common/expression-parser/parser.php',
|
366 |
'Toolset_Post' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/element/post.php',
|
367 |
'Toolset_Post_Translation_Set' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/element/post_translation_set.php',
|
368 |
+
'Toolset_Post_Type_Abstract' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/post_type/abstract.php',
|
369 |
'Toolset_Post_Type_Exclude_List' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/post_type/excluded_list.php',
|
370 |
'Toolset_Post_Type_Factory' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/post_type/factory.php',
|
371 |
'Toolset_Post_Type_From_Types' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/post_type/from_types.php',
|
377 |
'Toolset_Potential_Association_Query_Factory' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/potential_association/query_factory.php',
|
378 |
'Toolset_Potential_Association_Query_Posts' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/potential_association/query_posts.php',
|
379 |
'Toolset_Promotion' => __DIR__ . '/..' . '/toolset/toolset-common/inc/toolset.promotion.class.php',
|
380 |
+
'Toolset_Public_API_Loader' => __DIR__ . '/..' . '/toolset/toolset-common/inc/public_api/loader.php',
|
381 |
+
'Toolset_Query_Comparison_Operator' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/query/comparison_operator.php',
|
382 |
+
'Toolset_Query_Condition_And' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/query/condition/and.php',
|
383 |
+
'Toolset_Query_Condition_Contradiction' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/query/condition/contradiction.php',
|
384 |
+
'Toolset_Query_Condition_Operator' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/query/condition/operator.php',
|
385 |
+
'Toolset_Query_Condition_Or' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/query/condition/or.php',
|
386 |
+
'Toolset_Query_Condition_Tautology' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/query/condition/tautology.php',
|
387 |
'Toolset_Regex' => __DIR__ . '/..' . '/toolset/toolset-common/expression-parser/parser.php',
|
388 |
'Toolset_Relationship_Cardinality' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/cardinality.php',
|
389 |
'Toolset_Relationship_Controller' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/controller.php',
|
390 |
'Toolset_Relationship_Database_Issue_Missing_Element' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/database/issue/missing_element.php',
|
391 |
'Toolset_Relationship_Database_Operations' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/database/operations.php',
|
392 |
'Toolset_Relationship_Database_Unique_Table_Alias' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/database/unique_table_alias.php',
|
393 |
+
'Toolset_Relationship_Definition' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/relationship/definition/definition.php',
|
394 |
+
'Toolset_Relationship_Definition_Factory' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/relationship/definition/factory.php',
|
395 |
+
'Toolset_Relationship_Definition_Persistence' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/relationship/definition/persistence.php',
|
396 |
+
'Toolset_Relationship_Definition_Repository' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/relationship/definition/repository.php',
|
397 |
+
'Toolset_Relationship_Definition_Translator' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/relationship/definition/translator.php',
|
398 |
'Toolset_Relationship_Distinct_Post_Query' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/potential_association/distinct_post_query.php',
|
399 |
'Toolset_Relationship_Driver' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/driver.php',
|
400 |
'Toolset_Relationship_Driver_Base' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/driver_base.php',
|
401 |
'Toolset_Relationship_Element_Type' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/element_type.php',
|
402 |
+
'Toolset_Relationship_Migration' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/migration/controller.php',
|
403 |
+
'Toolset_Relationship_Migration_Associations' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/migration/associations.php',
|
404 |
+
'Toolset_Relationship_Migration_Controller' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/migration/controller.php',
|
405 |
+
'Toolset_Relationship_Migration_Post_Translation' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/migration/post_translation.php',
|
406 |
'Toolset_Relationship_Origin_Post_Reference_Field' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/origin/post_reference_field.php',
|
407 |
'Toolset_Relationship_Origin_Repeatable_Group' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/origin/repeatable_group.php',
|
408 |
'Toolset_Relationship_Origin_Wizard' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/origin/wizard.php',
|
409 |
+
'Toolset_Relationship_Query' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/relationship/query/relationship_query.php',
|
410 |
'Toolset_Relationship_Query_Base' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/query_base.php',
|
411 |
'Toolset_Relationship_Query_Cache' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/query_cache.php',
|
412 |
+
'Toolset_Relationship_Query_Cardinality_Match_Conjunction' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/relationship/query/cardinality_match/conjunction.php',
|
413 |
+
'Toolset_Relationship_Query_Cardinality_Match_Factory' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/relationship/query/cardinality_match/factory.php',
|
414 |
+
'Toolset_Relationship_Query_Cardinality_Match_Operators' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/relationship/query/cardinality_match/operators.php',
|
415 |
+
'Toolset_Relationship_Query_Cardinality_Match_Single' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/relationship/query/cardinality_match/single.php',
|
416 |
+
'Toolset_Relationship_Query_Condition' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/relationship/query/condition/abstract.php',
|
417 |
+
'Toolset_Relationship_Query_Condition_Factory' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/relationship/query/condition_factory.php',
|
418 |
+
'Toolset_Relationship_Query_Condition_Has_Active_Types' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/relationship/query/condition/has_active_types.php',
|
419 |
+
'Toolset_Relationship_Query_Condition_Has_Cardinality' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/relationship/query/condition/has_cardinality.php',
|
420 |
+
'Toolset_Relationship_Query_Condition_Has_Domain' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/relationship/query/condition/has_domain.php',
|
421 |
+
'Toolset_Relationship_Query_Condition_Is_Active' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/relationship/query/condition/is_active.php',
|
422 |
+
'Toolset_Relationship_Query_Condition_Is_Boolean_Flag' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/relationship/query/condition/is_boolean_flag.php',
|
423 |
+
'Toolset_Relationship_Query_Condition_Is_Legacy' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/relationship/query/condition/is_legacy.php',
|
424 |
+
'Toolset_Relationship_Query_Condition_Origin' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/relationship/query/condition/origin.php',
|
425 |
+
'Toolset_Relationship_Query_Condition_Type' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/relationship/query/condition/type.php',
|
426 |
+
'Toolset_Relationship_Query_Factory' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/query/factory.php',
|
427 |
+
'Toolset_Relationship_Query_Sql_Expression_Builder' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/relationship/query/sql_expression_builder.php',
|
428 |
+
'Toolset_Relationship_Query_V2' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/relationship/query/relationship_query_v2.php',
|
429 |
+
'Toolset_Relationship_Role' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/relationship/role/role.php',
|
430 |
+
'Toolset_Relationship_Role_Abstract' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/relationship/role/abstract.php',
|
431 |
+
'Toolset_Relationship_Role_Child' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/relationship/role/child.php',
|
432 |
+
'Toolset_Relationship_Role_Intermediary' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/relationship/role/intermediary.php',
|
433 |
+
'Toolset_Relationship_Role_Parent' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/relationship/role/parent.php',
|
434 |
+
'Toolset_Relationship_Scope' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/relationship/scope.php',
|
|
|
|
|
|
|
|
|
435 |
'Toolset_Relationship_Service' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/relationship_service.php',
|
436 |
+
'Toolset_Relationship_Slug_Validator' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/relationship/slug_validator.php',
|
437 |
'Toolset_Relationship_Table_Name' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/database/table_name.php',
|
438 |
'Toolset_Relationship_Utils' => __DIR__ . '/..' . '/toolset/toolset-common/inc/m2m/utils.php',
|
|
|
439 |
'Toolset_Relevanssi_Compatibility' => __DIR__ . '/..' . '/toolset/toolset-common/inc/toolset.relevanssi.compatibility.class.php',
|
440 |
+
'Toolset_Renderer' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/renderer/renderer.php',
|
441 |
'Toolset_Result' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/result.php',
|
442 |
'Toolset_Result_Set' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/result_set.php',
|
443 |
'Toolset_Result_Updated' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/result_updated.php',
|
453 |
'Toolset_Shortcode_Transformer' => __DIR__ . '/..' . '/toolset/toolset-common/inc/toolset.shortcode.transformer.class.php',
|
454 |
'Toolset_Stack' => __DIR__ . '/..' . '/toolset/toolset-common/expression-parser/parser.php',
|
455 |
'Toolset_Style' => __DIR__ . '/..' . '/toolset/toolset-common/inc/toolset.assets.manager.class.php',
|
456 |
+
'Toolset_Template_Dialog_Box' => __DIR__ . '/..' . '/toolset/toolset-common/utility/gui-base/template_dialog_box.php',
|
457 |
'Toolset_Tokenizer' => __DIR__ . '/..' . '/toolset/toolset-common/expression-parser/parser.php',
|
458 |
'Toolset_Twig_Autoloader' => __DIR__ . '/..' . '/toolset/toolset-common/utility/gui-base/twig_autoloader.php',
|
459 |
'Toolset_Twig_Dialog_Box' => __DIR__ . '/..' . '/toolset/toolset-common/utility/gui-base/twig_dialog_box.php',
|
470 |
'Toolset_User_Editors_Editor_Basic' => __DIR__ . '/..' . '/toolset/toolset-common/user-editors/editor/basic.php',
|
471 |
'Toolset_User_Editors_Editor_Beaver' => __DIR__ . '/..' . '/toolset/toolset-common/user-editors/editor/beaver.php',
|
472 |
'Toolset_User_Editors_Editor_Divi' => __DIR__ . '/..' . '/toolset/toolset-common/user-editors/editor/divi.php',
|
473 |
+
'Toolset_User_Editors_Editor_Gutenberg' => __DIR__ . '/..' . '/toolset/toolset-common/user-editors/editor/gutenberg.php',
|
474 |
'Toolset_User_Editors_Editor_Interface' => __DIR__ . '/..' . '/toolset/toolset-common/user-editors/editor/interface.php',
|
475 |
'Toolset_User_Editors_Editor_Native' => __DIR__ . '/..' . '/toolset/toolset-common/user-editors/editor/native.php',
|
476 |
'Toolset_User_Editors_Editor_Screen_Abstract' => __DIR__ . '/..' . '/toolset/toolset-common/user-editors/editor/screen/abstract.php',
|
481 |
'Toolset_User_Editors_Editor_Screen_Beaver_Frontend_Editor' => __DIR__ . '/..' . '/toolset/toolset-common/user-editors/editor/screen/beaver/frontend-editor.php',
|
482 |
'Toolset_User_Editors_Editor_Screen_Divi_Backend' => __DIR__ . '/..' . '/toolset/toolset-common/user-editors/editor/screen/divi/backend.php',
|
483 |
'Toolset_User_Editors_Editor_Screen_Divi_Frontend' => __DIR__ . '/..' . '/toolset/toolset-common/user-editors/editor/screen/divi/frontend.php',
|
484 |
+
'Toolset_User_Editors_Editor_Screen_Gutenberg_Backend' => __DIR__ . '/..' . '/toolset/toolset-common/user-editors/editor/screen/gutenberg/backend.php',
|
485 |
'Toolset_User_Editors_Editor_Screen_Interface' => __DIR__ . '/..' . '/toolset/toolset-common/user-editors/editor/screen/interface.php',
|
486 |
'Toolset_User_Editors_Editor_Screen_Native_Backend' => __DIR__ . '/..' . '/toolset/toolset-common/user-editors/editor/screen/native/backend.php',
|
487 |
'Toolset_User_Editors_Editor_Screen_Visual_Composer_Backend' => __DIR__ . '/..' . '/toolset/toolset-common/user-editors/editor/screen/visual-composer/backend.php',
|
501 |
'Toolset_VideoDetachedPage' => __DIR__ . '/..' . '/toolset/toolset-common/utility/help-videos/toolset-help-videos.php',
|
502 |
'Toolset_WPLogger' => __DIR__ . '/..' . '/toolset/toolset-common/inc/toolset.wplogger.class.php',
|
503 |
'Toolset_WPML_Compatibility' => __DIR__ . '/..' . '/toolset/toolset-common/inc/toolset.wpml.compatibility.class.php',
|
504 |
+
'Toolset_Wp_Query_Adjustments' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/wp_query_adjustments/abstract.php',
|
505 |
+
'Toolset_Wp_Query_Adjustments_Legacy_Relationships' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/wp_query_adjustments/legacy_relationships.php',
|
506 |
+
'Toolset_Wp_Query_Adjustments_Loader' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/wp_query_adjustments/loader.php',
|
507 |
+
'Toolset_Wp_Query_Adjustments_M2m' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/wp_query_adjustments/m2m.php',
|
508 |
+
'Toolset_Wp_Query_Adjustments_Table_Join_Manager' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/wp_query_adjustments/table_join_manager.php',
|
509 |
+
'Toolset_Wpdb_User' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/wpdb_user.php',
|
510 |
'Toolset_Wpml_Utils' => __DIR__ . '/..' . '/toolset/toolset-common/inc/autoloaded/wpml_utils.php',
|
511 |
'Twig_Autoloader' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Autoloader.php',
|
512 |
'Twig_BaseNodeVisitor' => __DIR__ . '/..' . '/twig/twig/lib/Twig/BaseNodeVisitor.php',
|
733 |
'Types_Field_Group_User_Factory' => __DIR__ . '/../..' . '/application/models/field/group/user_factory.php',
|
734 |
'Types_Field_Type_Converter' => __DIR__ . '/../..' . '/application/controllers/field/type_converter.php',
|
735 |
'Types_Field_Type_Definition' => __DIR__ . '/../..' . '/application/models/field/type/definition.php',
|
736 |
+
'Types_Field_Type_Definition_Checkbox' => __DIR__ . '/../..' . '/application/models/field/gateway/checkbox.php',
|
737 |
+
'Types_Field_Type_Definition_Checkboxes' => __DIR__ . '/../..' . '/application/models/field/gateway/checkboxes.php',
|
738 |
+
'Types_Field_Type_Definition_Date' => __DIR__ . '/../..' . '/application/models/field/gateway/date.php',
|
739 |
'Types_Field_Type_Definition_Factory' => __DIR__ . '/../..' . '/application/models/field/type/definition_factory.php',
|
740 |
+
'Types_Field_Type_Definition_Numeric' => __DIR__ . '/../..' . '/application/models/field/gateway/numeric.php',
|
741 |
+
'Types_Field_Type_Definition_Radio' => __DIR__ . '/../..' . '/application/models/field/gateway/radio.php',
|
742 |
+
'Types_Field_Type_Definition_Select' => __DIR__ . '/../..' . '/application/models/field/gateway/select.php',
|
743 |
+
'Types_Field_Type_Definition_Singular' => __DIR__ . '/../..' . '/application/models/field/gateway/singular.php',
|
744 |
'Types_Field_Utils' => __DIR__ . '/../..' . '/application/controllers/field/utils.php',
|
745 |
'Types_Frontend' => __DIR__ . '/../..' . '/application/controllers/frontend.php',
|
746 |
'Types_Helper_Condition' => __DIR__ . '/../..' . '/application/models/helper/condition.php',
|
819 |
'Types_Taxonomy' => __DIR__ . '/../..' . '/application/models/taxonomy.php',
|
820 |
'Types_Twig_Autoloader' => __DIR__ . '/../..' . '/application/controllers/twig_autoloader.php',
|
821 |
'Types_Upgrade' => __DIR__ . '/../..' . '/application/controllers/upgrade.php',
|
822 |
+
'Types_Utils' => __DIR__ . '/../..' . '/application/controllers/admin_notice/utils.php',
|
823 |
'Types_Utils_Post_Type_Option' => __DIR__ . '/../..' . '/application/controllers/utils/post_type_option.php',
|
824 |
'Types_Wpml_Field_Group' => __DIR__ . '/../..' . '/application/models/wpml/field_group.php',
|
825 |
'Types_Wpml_Field_Group_String' => __DIR__ . '/../..' . '/application/models/wpml/field/group/string.php',
|
869 |
public static function getInitializer(ClassLoader $loader)
|
870 |
{
|
871 |
return \Closure::bind(function () use ($loader) {
|
872 |
+
$loader->prefixLengthsPsr4 = ComposerStaticInitc3c1dc77e2581741c891ff7b2bf920aa::$prefixLengthsPsr4;
|
873 |
+
$loader->prefixDirsPsr4 = ComposerStaticInitc3c1dc77e2581741c891ff7b2bf920aa::$prefixDirsPsr4;
|
874 |
+
$loader->prefixesPsr0 = ComposerStaticInitc3c1dc77e2581741c891ff7b2bf920aa::$prefixesPsr0;
|
875 |
+
$loader->classMap = ComposerStaticInitc3c1dc77e2581741c891ff7b2bf920aa::$classMap;
|
876 |
|
877 |
}, null, ClassLoader::class);
|
878 |
}
|
vendor/composer/installed.json
CHANGED
@@ -120,12 +120,12 @@
|
|
120 |
},
|
121 |
{
|
122 |
"name": "otgs/installer",
|
123 |
-
"version": "1.8.
|
124 |
-
"version_normalized": "1.8.
|
125 |
"source": {
|
126 |
"type": "git",
|
127 |
"url": "ssh://git@git.onthegosystems.com:10022/installer/installer.git",
|
128 |
-
"reference": "
|
129 |
},
|
130 |
"require": {
|
131 |
"composer/installers": "~1.0",
|
@@ -134,7 +134,7 @@
|
|
134 |
"require-dev": {
|
135 |
"phpunit/phpunit": "~4.5"
|
136 |
},
|
137 |
-
"time": "
|
138 |
"type": "library",
|
139 |
"extra": {
|
140 |
"branch-alias": {
|
@@ -149,7 +149,7 @@
|
|
149 |
]
|
150 |
},
|
151 |
"license": [
|
152 |
-
"GPL-2.0"
|
153 |
],
|
154 |
"authors": [
|
155 |
{
|
@@ -217,12 +217,12 @@
|
|
217 |
},
|
218 |
{
|
219 |
"name": "toolset/toolset-common",
|
220 |
-
"version": "2.
|
221 |
-
"version_normalized": "2.
|
222 |
"source": {
|
223 |
"type": "git",
|
224 |
"url": "ssh://git@git.onthegosystems.com:10022/toolset/toolset-common.git",
|
225 |
-
"reference": "
|
226 |
},
|
227 |
"require": {
|
228 |
"php": ">=5.2.0"
|
@@ -233,7 +233,7 @@
|
|
233 |
"otgs/unit-tests-framework": "~1.2.0",
|
234 |
"phpunit/php-token-stream": "<2.0"
|
235 |
},
|
236 |
-
"time": "
|
237 |
"type": "library",
|
238 |
"extra": {
|
239 |
"branch-alias": {
|
@@ -248,11 +248,17 @@
|
|
248 |
"expression-parser/",
|
249 |
"inc/",
|
250 |
"toolset-forms/",
|
|
|
251 |
"user-editors/",
|
252 |
"utility/",
|
253 |
"bootstrap.php"
|
254 |
]
|
255 |
},
|
|
|
|
|
|
|
|
|
|
|
256 |
"scripts": {
|
257 |
"test": [
|
258 |
"phpunit"
|
120 |
},
|
121 |
{
|
122 |
"name": "otgs/installer",
|
123 |
+
"version": "1.8.8",
|
124 |
+
"version_normalized": "1.8.8.0",
|
125 |
"source": {
|
126 |
"type": "git",
|
127 |
"url": "ssh://git@git.onthegosystems.com:10022/installer/installer.git",
|
128 |
+
"reference": "4f33032eed7d02bf2cd1871706d249370ecf7032"
|
129 |
},
|
130 |
"require": {
|
131 |
"composer/installers": "~1.0",
|
134 |
"require-dev": {
|
135 |
"phpunit/phpunit": "~4.5"
|
136 |
},
|
137 |
+
"time": "2018-03-01T13:01:25+00:00",
|
138 |
"type": "library",
|
139 |
"extra": {
|
140 |
"branch-alias": {
|
149 |
]
|
150 |
},
|
151 |
"license": [
|
152 |
+
"GPL-2.0-or-later"
|
153 |
],
|
154 |
"authors": [
|
155 |
{
|
217 |
},
|
218 |
{
|
219 |
"name": "toolset/toolset-common",
|
220 |
+
"version": "2.6.2",
|
221 |
+
"version_normalized": "2.6.2.0",
|
222 |
"source": {
|
223 |
"type": "git",
|
224 |
"url": "ssh://git@git.onthegosystems.com:10022/toolset/toolset-common.git",
|
225 |
+
"reference": "f8084f2b13708b5589842bb8b1ab6a4c77a8e9ac"
|
226 |
},
|
227 |
"require": {
|
228 |
"php": ">=5.2.0"
|
233 |
"otgs/unit-tests-framework": "~1.2.0",
|
234 |
"phpunit/php-token-stream": "<2.0"
|
235 |
},
|
236 |
+
"time": "2018-03-01T14:00:14+00:00",
|
237 |
"type": "library",
|
238 |
"extra": {
|
239 |
"branch-alias": {
|
248 |
"expression-parser/",
|
249 |
"inc/",
|
250 |
"toolset-forms/",
|
251 |
+
"toolset-blocks/",
|
252 |
"user-editors/",
|
253 |
"utility/",
|
254 |
"bootstrap.php"
|
255 |
]
|
256 |
},
|
257 |
+
"autoload-dev": {
|
258 |
+
"classmap": [
|
259 |
+
"tests/res/stubs"
|
260 |
+
]
|
261 |
+
},
|
262 |
"scripts": {
|
263 |
"test": [
|
264 |
"phpunit"
|
vendor/otgs/installer/changelog.txt
CHANGED
@@ -1,3 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
= 1.8.2 =
|
2 |
* Bug fix: registration warning was shown for free plugins
|
3 |
|
1 |
+
= 1.8.8 =
|
2 |
+
* Fixed some conficts
|
3 |
+
|
4 |
+
= 1.8.7 =
|
5 |
+
* Updated version numbers to all files
|
6 |
+
|
7 |
+
= 1.8.6 =
|
8 |
+
* Bug fix: When Windows file paths were longer than 256 chars updating of plugins wasn't possible
|
9 |
+
* Bug fix: PHP 7.2 warnings
|
10 |
+
|
11 |
= 1.8.2 =
|
12 |
* Bug fix: registration warning was shown for free plugins
|
13 |
|
vendor/otgs/installer/includes/class-installer-theme.php
CHANGED
@@ -936,7 +936,7 @@ class Installer_Theme_Class {
|
|
936 |
public function installer_theme_filter_themes_by_subscription( $themes, $active_tab ) {
|
937 |
|
938 |
//Step1, we only filter OTGS themes
|
939 |
-
$orig = count( $themes );
|
940 |
if ( in_array( $active_tab, $this->theme_repo ) ) {
|
941 |
//OTGS Theme
|
942 |
//Step2, we retrieved the available themes based on client subscription
|
@@ -959,7 +959,7 @@ class Installer_Theme_Class {
|
|
959 |
}
|
960 |
}
|
961 |
}
|
962 |
-
$new = count( $themes );
|
963 |
if ( $orig != $new ) {
|
964 |
//It is filtered
|
965 |
$themes = array_values( $themes );
|
936 |
public function installer_theme_filter_themes_by_subscription( $themes, $active_tab ) {
|
937 |
|
938 |
//Step1, we only filter OTGS themes
|
939 |
+
$orig = is_array( $themes ) ? count( $themes ) : 0;
|
940 |
if ( in_array( $active_tab, $this->theme_repo ) ) {
|
941 |
//OTGS Theme
|
942 |
//Step2, we retrieved the available themes based on client subscription
|
959 |
}
|
960 |
}
|
961 |
}
|
962 |
+
$new = is_array( $themes ) ? count( $themes ) : 0;
|
963 |
if ( $orig != $new ) {
|
964 |
//It is filtered
|
965 |
$themes = array_values( $themes );
|
vendor/otgs/installer/includes/class-otgs-installer-filename-hooks.php
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class OTGS_Installer_Filename_Hooks {
|
4 |
+
|
5 |
+
/**
|
6 |
+
* @var OTGS_Installer_PHP_Functions
|
7 |
+
*/
|
8 |
+
private $built_in_functions;
|
9 |
+
|
10 |
+
public function __construct( OTGS_Installer_PHP_Functions $built_in_functions ) {
|
11 |
+
$this->built_in_functions = $built_in_functions;
|
12 |
+
}
|
13 |
+
|
14 |
+
public function add_hooks() {
|
15 |
+
if ( in_array( $this->built_in_functions->constant( 'PHP_OS' ), array( 'WIN32', 'WINNT', 'Windows' ), true ) ) {
|
16 |
+
add_filter( 'wp_unique_filename', array( $this, 'fix_filename_for_win' ), 10, 3 );
|
17 |
+
}
|
18 |
+
}
|
19 |
+
|
20 |
+
/**
|
21 |
+
* @param string $filename
|
22 |
+
* @param string $ext
|
23 |
+
* @param string $dir
|
24 |
+
*
|
25 |
+
* @return string
|
26 |
+
*/
|
27 |
+
public function fix_filename_for_win( $filename, $ext, $dir ) {
|
28 |
+
if ( $dir === get_temp_dir() ) {
|
29 |
+
return md5( $filename . $this->built_in_functions->time() ) . 'tmp';
|
30 |
+
}
|
31 |
+
return $filename;
|
32 |
+
}
|
33 |
+
}
|
vendor/otgs/installer/includes/class-otgs-installer-php-functions.php
ADDED
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class OTGS_Installer_PHP_Functions {
|
4 |
+
|
5 |
+
/**
|
6 |
+
* @param string $constant_name
|
7 |
+
*
|
8 |
+
* @return bool
|
9 |
+
*/
|
10 |
+
public function defined( $constant_name ) {
|
11 |
+
return defined( $constant_name );
|
12 |
+
}
|
13 |
+
|
14 |
+
/**
|
15 |
+
* @param string $constant_name
|
16 |
+
*
|
17 |
+
* @return string|int|null
|
18 |
+
*/
|
19 |
+
public function constant( $constant_name ) {
|
20 |
+
return $this->defined( $constant_name ) ? constant( $constant_name ) : null;
|
21 |
+
}
|
22 |
+
|
23 |
+
/**
|
24 |
+
* @return int
|
25 |
+
*/
|
26 |
+
public function time() {
|
27 |
+
return time();
|
28 |
+
}
|
29 |
+
}
|
vendor/otgs/installer/includes/class-wp-installer.php
CHANGED
@@ -302,24 +302,19 @@ final class WP_Installer {
|
|
302 |
foreach ( $this->settings['repositories'] as $repository_id => $repository ) {
|
303 |
|
304 |
foreach ( $repository['data']['packages'] as $package ) {
|
305 |
-
|
306 |
foreach ( $package['products'] as $product ) {
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
);
|
317 |
}
|
318 |
-
|
319 |
}
|
320 |
-
|
321 |
}
|
322 |
-
|
323 |
}
|
324 |
|
325 |
foreach ( $plugins as $plugin_id => $plugin ) {
|
@@ -547,7 +542,7 @@ final class WP_Installer {
|
|
547 |
);
|
548 |
|
549 |
if ( ! empty( $response['error'] ) ) {
|
550 |
-
$this->remove_site_key( $repository_id );
|
551 |
|
552 |
$this->admin_messages[] = array(
|
553 |
'type' => 'error',
|
@@ -652,6 +647,19 @@ final class WP_Installer {
|
|
652 |
return $site_url;
|
653 |
}
|
654 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
655 |
public function show_site_key_nags() {
|
656 |
$screen = get_current_screen();
|
657 |
|
@@ -1016,8 +1024,10 @@ final class WP_Installer {
|
|
1016 |
// downloads
|
1017 |
if ( isset( $subscription_type ) && ! $expired && ( $product['subscription_type'] == $subscription_type || $product['subscription_type_equivalent'] == $subscription_type ) ) {
|
1018 |
|
1019 |
-
|
1020 |
-
|
|
|
|
|
1021 |
}
|
1022 |
|
1023 |
}
|
@@ -1162,7 +1172,8 @@ final class WP_Installer {
|
|
1162 |
$this->settings['repositories'][ $repository_id ]['subscription'] = array(
|
1163 |
'key' => $site_key,
|
1164 |
'data' => $subscription_data,
|
1165 |
-
'registered_by' => get_current_user_id()
|
|
|
1166 |
);
|
1167 |
$this->save_settings();
|
1168 |
} else {
|
@@ -1209,11 +1220,13 @@ final class WP_Installer {
|
|
1209 |
return WP_Installer::get_repository_site_key( $repository_id );
|
1210 |
}
|
1211 |
|
1212 |
-
public function remove_site_key( $repository_id ) {
|
1213 |
if ( isset( $this->settings['repositories'][ $repository_id ] ) ) {
|
1214 |
unset( $this->settings['repositories'][ $repository_id ]['subscription'] );
|
1215 |
$this->save_settings();
|
1216 |
-
$
|
|
|
|
|
1217 |
}
|
1218 |
}
|
1219 |
|
@@ -1565,20 +1578,22 @@ final class WP_Installer {
|
|
1565 |
|
1566 |
foreach ( $package['products'] as $product ) {
|
1567 |
|
1568 |
-
|
|
|
1569 |
|
1570 |
-
|
1571 |
|
1572 |
-
|
1573 |
|
1574 |
-
|
1575 |
|
1576 |
-
|
|
|
|
|
1577 |
|
1578 |
}
|
1579 |
|
1580 |
}
|
1581 |
-
|
1582 |
}
|
1583 |
|
1584 |
}
|
@@ -2249,33 +2264,30 @@ final class WP_Installer {
|
|
2249 |
}
|
2250 |
|
2251 |
foreach ( $repository['data']['packages'] as $package ) {
|
2252 |
-
|
2253 |
foreach ( $package['products'] as $product ) {
|
|
|
|
|
2254 |
|
2255 |
-
|
|
|
|
|
|
|
2256 |
|
2257 |
-
|
2258 |
-
if ( ! empty( $download['free-on-wporg'] ) && $download['channel'] == WP_Installer_Channels::CHANNEL_PRODUCTION ) {
|
2259 |
-
continue;
|
2260 |
-
}
|
2261 |
|
2262 |
-
|
|
|
|
|
|
|
|
|
|
|
2263 |
|
2264 |
-
if ( ! $site_key || ! $this->plugin_is_registered( $repository_id, $download['slug'] ) ) {
|
2265 |
-
add_action( "after_plugin_row_" . $plugin_id, array(
|
2266 |
-
$this,
|
2267 |
-
'show_purchase_notice_under_plugin'
|
2268 |
-
), 10, 3 );
|
2269 |
}
|
2270 |
|
2271 |
}
|
2272 |
-
|
2273 |
}
|
2274 |
-
|
2275 |
}
|
2276 |
-
|
2277 |
}
|
2278 |
-
|
2279 |
}
|
2280 |
|
2281 |
}
|
@@ -2554,11 +2566,11 @@ final class WP_Installer {
|
|
2554 |
}
|
2555 |
|
2556 |
// order parents
|
2557 |
-
usort( $ordered_packages, array( $this, '
|
2558 |
//order sub-packages
|
2559 |
foreach ( $ordered_packages as $package_id => $package ) {
|
2560 |
if ( ! empty( $package['sub-packages'] ) ) {
|
2561 |
-
|
2562 |
}
|
2563 |
}
|
2564 |
|
@@ -2571,8 +2583,8 @@ final class WP_Installer {
|
|
2571 |
|
2572 |
}
|
2573 |
|
2574 |
-
public function
|
2575 |
-
|
2576 |
}
|
2577 |
|
2578 |
public function get_support_tag_by_name( $name, $repository ) {
|
@@ -2765,4 +2777,13 @@ final class WP_Installer {
|
|
2765 |
|
2766 |
}
|
2767 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2768 |
}
|
302 |
foreach ( $this->settings['repositories'] as $repository_id => $repository ) {
|
303 |
|
304 |
foreach ( $repository['data']['packages'] as $package ) {
|
|
|
305 |
foreach ( $package['products'] as $product ) {
|
306 |
+
if ( $this->has_plugins( $product ) ) {
|
307 |
+
foreach ( $product['plugins'] as $plugin_slug ) {
|
308 |
+
$download = $this->settings['repositories'][ $repository_id ]['data']['downloads']['plugins'][ $plugin_slug ];
|
309 |
+
if ( ! isset( $repositories_plugins[ $repository_id ][ $download['slug'] ] ) ) {
|
310 |
+
$repositories_plugins[ $repository_id ][ $download['slug'] ] = array(
|
311 |
+
'name' => $download['name'],
|
312 |
+
'registered' => $this->plugin_is_registered( $repository_id, $download['slug'] ) ? 1 : 0
|
313 |
+
);
|
314 |
+
}
|
|
|
315 |
}
|
|
|
316 |
}
|
|
|
317 |
}
|
|
|
318 |
}
|
319 |
|
320 |
foreach ( $plugins as $plugin_id => $plugin ) {
|
542 |
);
|
543 |
|
544 |
if ( ! empty( $response['error'] ) ) {
|
545 |
+
$this->remove_site_key( $repository_id, false );
|
546 |
|
547 |
$this->admin_messages[] = array(
|
548 |
'type' => 'error',
|
647 |
return $site_url;
|
648 |
}
|
649 |
|
650 |
+
/**
|
651 |
+
* @param string $repository_id
|
652 |
+
*
|
653 |
+
* @return string|null
|
654 |
+
*/
|
655 |
+
public function get_registered_site_url( $repository_id ) {
|
656 |
+
if ( isset( $this->settings['repositories'][ $repository_id ]['subscription']['site_url'] ) ) {
|
657 |
+
return $this->settings['repositories'][ $repository_id ]['subscription']['site_url'];
|
658 |
+
}
|
659 |
+
|
660 |
+
return null;
|
661 |
+
}
|
662 |
+
|
663 |
public function show_site_key_nags() {
|
664 |
$screen = get_current_screen();
|
665 |
|
1024 |
// downloads
|
1025 |
if ( isset( $subscription_type ) && ! $expired && ( $product['subscription_type'] == $subscription_type || $product['subscription_type_equivalent'] == $subscription_type ) ) {
|
1026 |
|
1027 |
+
if ( $this->has_plugins( $product ) ) {
|
1028 |
+
foreach ( $product['plugins'] as $plugin_slug ) {
|
1029 |
+
$row['downloads'][ $plugin_slug ] = $this->settings['repositories'][ $repository_id ]['data']['downloads']['plugins'][ $plugin_slug ];
|
1030 |
+
}
|
1031 |
}
|
1032 |
|
1033 |
}
|
1172 |
$this->settings['repositories'][ $repository_id ]['subscription'] = array(
|
1173 |
'key' => $site_key,
|
1174 |
'data' => $subscription_data,
|
1175 |
+
'registered_by' => get_current_user_id(),
|
1176 |
+
'site_url' => get_site_url(),
|
1177 |
);
|
1178 |
$this->save_settings();
|
1179 |
} else {
|
1220 |
return WP_Installer::get_repository_site_key( $repository_id );
|
1221 |
}
|
1222 |
|
1223 |
+
public function remove_site_key( $repository_id, $refresh_repositories_data = true ) {
|
1224 |
if ( isset( $this->settings['repositories'][ $repository_id ] ) ) {
|
1225 |
unset( $this->settings['repositories'][ $repository_id ]['subscription'] );
|
1226 |
$this->save_settings();
|
1227 |
+
if( $refresh_repositories_data ){
|
1228 |
+
$this->refresh_repositories_data();
|
1229 |
+
}
|
1230 |
}
|
1231 |
}
|
1232 |
|
1578 |
|
1579 |
foreach ( $package['products'] as $product ) {
|
1580 |
|
1581 |
+
if ( $this->has_plugins( $product ) ) {
|
1582 |
+
foreach ( $product['plugins'] as $plugin_slug ) {
|
1583 |
|
1584 |
+
$download = $this->settings['repositories'][ $repository_id ]['data']['downloads']['plugins'][ $plugin_slug ];
|
1585 |
|
1586 |
+
if ( $download['slug'] == $slug || $download['name'] == $plugin['Name'] || $download['name'] == $plugin['Title'] ) { //match order: slug, name, title
|
1587 |
|
1588 |
+
if ( isset( $subscriptions_with_warnings[ $product['subscription_type'] ] ) ) {
|
1589 |
|
1590 |
+
$this->_plugins_renew_warnings[ $plugin_id ] = $subscriptions_with_warnings[ $product['subscription_type'] ];
|
1591 |
+
|
1592 |
+
}
|
1593 |
|
1594 |
}
|
1595 |
|
1596 |
}
|
|
|
1597 |
}
|
1598 |
|
1599 |
}
|
2264 |
}
|
2265 |
|
2266 |
foreach ( $repository['data']['packages'] as $package ) {
|
|
|
2267 |
foreach ( $package['products'] as $product ) {
|
2268 |
+
if ( $this->has_plugins( $product ) ) {
|
2269 |
+
foreach ( $product['plugins'] as $plugin_slug ) {
|
2270 |
|
2271 |
+
$download = $this->settings['repositories'][ $repository_id ]['data']['downloads']['plugins'][ $plugin_slug ];
|
2272 |
+
if ( ! empty( $download['free-on-wporg'] ) && $download['channel'] == WP_Installer_Channels::CHANNEL_PRODUCTION ) {
|
2273 |
+
continue;
|
2274 |
+
}
|
2275 |
|
2276 |
+
if ( $download['slug'] == $slug || $download['name'] == $name ) {
|
|
|
|
|
|
|
2277 |
|
2278 |
+
if ( ! $site_key || ! $this->plugin_is_registered( $repository_id, $download['slug'] ) ) {
|
2279 |
+
add_action( "after_plugin_row_" . $plugin_id, array(
|
2280 |
+
$this,
|
2281 |
+
'show_purchase_notice_under_plugin'
|
2282 |
+
), 10, 3 );
|
2283 |
+
}
|
2284 |
|
|
|
|
|
|
|
|
|
|
|
2285 |
}
|
2286 |
|
2287 |
}
|
|
|
2288 |
}
|
|
|
2289 |
}
|
|
|
2290 |
}
|
|
|
2291 |
}
|
2292 |
|
2293 |
}
|
2566 |
}
|
2567 |
|
2568 |
// order parents
|
2569 |
+
usort( $ordered_packages, array( $this, 'compare_package_order' ) );
|
2570 |
//order sub-packages
|
2571 |
foreach ( $ordered_packages as $package_id => $package ) {
|
2572 |
if ( ! empty( $package['sub-packages'] ) ) {
|
2573 |
+
usort( $ordered_packages[ $package_id ]['sub-packages'], array( $this, 'compare_package_order' ) );
|
2574 |
}
|
2575 |
}
|
2576 |
|
2583 |
|
2584 |
}
|
2585 |
|
2586 |
+
public function compare_package_order($a, $b) {
|
2587 |
+
return $a['order'] > $b['order'];
|
2588 |
}
|
2589 |
|
2590 |
public function get_support_tag_by_name( $name, $repository ) {
|
2777 |
|
2778 |
}
|
2779 |
|
2780 |
+
/**
|
2781 |
+
* @param array $product
|
2782 |
+
*
|
2783 |
+
* @return bool
|
2784 |
+
*/
|
2785 |
+
private function has_plugins( $product ) {
|
2786 |
+
return isset( $product['plugins'] ) && is_array( $product['plugins'] );
|
2787 |
+
}
|
2788 |
+
|
2789 |
}
|
vendor/otgs/installer/installer.php
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
<?php
|
2 |
-
define( 'WP_INSTALLER_VERSION', '1.8.
|
3 |
|
4 |
include_once dirname( __FILE__ ) . '/includes/functions-core.php';
|
5 |
include_once dirname( __FILE__ ) . '/includes/class-wp-installer.php';
|
@@ -9,10 +9,14 @@ include_once WP_Installer()->plugin_path() . '/includes/class-translation-servic
|
|
9 |
include_once WP_Installer()->plugin_path() . '/includes/class-installer-dependencies.php';
|
10 |
include_once WP_Installer()->plugin_path() . '/includes/class-wp-installer-channels.php';
|
11 |
|
|
|
|
|
|
|
12 |
include_once WP_Installer()->plugin_path() . '/includes/functions-templates.php';
|
13 |
|
14 |
// Initialization
|
15 |
WP_Installer();
|
16 |
WP_Installer_Channels();
|
17 |
|
18 |
-
|
|
1 |
<?php
|
2 |
+
define( 'WP_INSTALLER_VERSION', '1.8.8' );
|
3 |
|
4 |
include_once dirname( __FILE__ ) . '/includes/functions-core.php';
|
5 |
include_once dirname( __FILE__ ) . '/includes/class-wp-installer.php';
|
9 |
include_once WP_Installer()->plugin_path() . '/includes/class-installer-dependencies.php';
|
10 |
include_once WP_Installer()->plugin_path() . '/includes/class-wp-installer-channels.php';
|
11 |
|
12 |
+
include_once WP_Installer()->plugin_path() . '/includes/class-otgs-installer-filename-hooks.php';
|
13 |
+
include_once WP_Installer()->plugin_path() . '/includes/class-otgs-installer-php-functions.php';
|
14 |
+
|
15 |
include_once WP_Installer()->plugin_path() . '/includes/functions-templates.php';
|
16 |
|
17 |
// Initialization
|
18 |
WP_Installer();
|
19 |
WP_Installer_Channels();
|
20 |
|
21 |
+
$filename_hooks = new OTGS_Installer_Filename_Hooks( new OTGS_Installer_PHP_Functions() );
|
22 |
+
$filename_hooks->add_hooks();
|
vendor/otgs/installer/loader.php
CHANGED
@@ -19,7 +19,7 @@ $wp_installer_instance = dirname(__FILE__) . '/installer.php';
|
|
19 |
global $wp_installer_instances;
|
20 |
$wp_installer_instances[$wp_installer_instance] = array(
|
21 |
'bootfile' => $wp_installer_instance,
|
22 |
-
'version' => '1.8.
|
23 |
);
|
24 |
|
25 |
|
19 |
global $wp_installer_instances;
|
20 |
$wp_installer_instances[$wp_installer_instance] = array(
|
21 |
'bootfile' => $wp_installer_instance,
|
22 |
+
'version' => '1.8.8'
|
23 |
);
|
24 |
|
25 |
|
vendor/toolset/toolset-common/api.php
ADDED
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* List of all available public filters.
|
4 |
+
*
|
5 |
+
* These filters should only be used to get data (by using apply_filters()) and not be extended (by using add_filter())
|
6 |
+
*/
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Filter: toolset_m2m_translated_relationships
|
10 |
+
* to get all relationships, which include at least one translated post type
|
11 |
+
*
|
12 |
+
* @param mixed $user_value will be returned if no relationships with translated post types are available
|
13 |
+
*
|
14 |
+
* @return IToolset_Relationship_Definition[]
|
15 |
+
* @since m2m
|
16 |
+
*/
|
17 |
+
if( ! function_exists( 'toolset_filter_toolset_m2m_translated_relationships' ) ) {
|
18 |
+
function toolset_filter_toolset_m2m_translated_relationships( $user_value ) {
|
19 |
+
do_action( 'toolset_do_m2m_full_init' );
|
20 |
+
|
21 |
+
if( ! apply_filters( 'toolset_is_m2m_enabled', false ) ) {
|
22 |
+
// m2m not active
|
23 |
+
return $user_value;
|
24 |
+
}
|
25 |
+
|
26 |
+
$relationships_with_translated_types = Toolset_Relationship_Utils::get_all_translated_relationships();
|
27 |
+
return ! empty( $relationships_with_translated_types ) ? $relationships_with_translated_types : $user_value;
|
28 |
+
}
|
29 |
+
}
|
30 |
+
|
31 |
+
add_filter( 'toolset_m2m_translated_relationships', 'toolset_filter_toolset_m2m_translated_relationships' );
|
vendor/toolset/toolset-common/autoload_classmap.php
CHANGED
@@ -1,27 +1,43 @@
|
|
1 |
<?php
|
2 |
// Generated by ZF2's ./bin/classmap_generator.php
|
3 |
return array(
|
|
|
4 |
'IToolset_Element' => dirname( __FILE__ ) . '/inc/autoloaded/element/i_element.php',
|
|
|
5 |
'IToolset_Post' => dirname( __FILE__ ) . '/inc/autoloaded/element/i_post.php',
|
6 |
'IToolset_Post_Type' => dirname( __FILE__ ) . '/inc/autoloaded/post_type/i_post_type.php',
|
7 |
'IToolset_Post_Type_From_Types' => dirname( __FILE__ ) . '/inc/autoloaded/post_type/i_post_type_from_types.php',
|
8 |
'IToolset_Post_Type_Registered' => dirname( __FILE__ ) . '/inc/autoloaded/post_type/i_post_type_registered.php',
|
9 |
'IToolset_Query' => dirname( __FILE__ ) . '/inc/autoloaded/i_query.php',
|
10 |
'IToolset_Upgrade_Command' => dirname( __FILE__ ) . '/inc/autoloaded/upgrade/command_interface.php',
|
|
|
11 |
'Toolset_Admin_Notice_Abstract' => dirname( __FILE__ ) . '/utility/admin/notice/abstract.php',
|
12 |
'Toolset_Admin_Notice_Dismissible' => dirname( __FILE__ ) . '/utility/admin/notice/dismissible.php',
|
13 |
'Toolset_Admin_Notice_Error' => dirname( __FILE__ ) . '/utility/admin/notice/error.php',
|
14 |
'Toolset_Admin_Notice_Interface' => dirname( __FILE__ ) . '/utility/admin/notice/interface.php',
|
15 |
'Toolset_Admin_Notice_Layouts_Help' => dirname( __FILE__ ) . '/utility/admin/notice/layouts/help.php',
|
16 |
'Toolset_Admin_Notice_Required_Action' => dirname( __FILE__ ) . '/utility/admin/notice/required/action.php',
|
17 |
-
'Toolset_Admin_Notices_Manager' => dirname( __FILE__ ) . '/utility/admin/notices/manager.php',
|
18 |
'Toolset_Admin_Notice_Success' => dirname( __FILE__ ) . '/utility/admin/notice/success.php',
|
19 |
'Toolset_Admin_Notice_Undismissible' => dirname( __FILE__ ) . '/utility/admin/notice/undismissible.php',
|
20 |
'Toolset_Admin_Notice_Warning' => dirname( __FILE__ ) . '/utility/admin/notice/warning.php',
|
|
|
21 |
'Toolset_Ajax_Handler_Abstract' => dirname( __FILE__ ) . '/inc/autoloaded/ajax_handler/abstract.php',
|
|
|
|
|
|
|
|
|
|
|
22 |
'Toolset_Ajax_Handler_Interface' => dirname( __FILE__ ) . '/inc/autoloaded/ajax_handler/interface.php',
|
|
|
23 |
'Toolset_Ajax_Handler_Migrate_To_M2M' => dirname( __FILE__ ) . '/inc/autoloaded/ajax_handler/migrate_to_m2m.php',
|
24 |
-
'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
25 |
'Toolset_Condition_Interface' => dirname( __FILE__ ) . '/utility/condition/interface.php',
|
26 |
'Toolset_Condition_Plugin_Access_Active' => dirname( __FILE__ ) . '/utility/condition/plugin/access/active.php',
|
27 |
'Toolset_Condition_Plugin_Access_Missing' => dirname( __FILE__ ) . '/utility/condition/plugin/access/missing.php',
|
@@ -32,11 +48,14 @@ return array(
|
|
32 |
'Toolset_Condition_Plugin_Layouts_Missing' => dirname( __FILE__ ) . '/utility/condition/plugin/layouts/missing.php',
|
33 |
'Toolset_Condition_Plugin_Layouts_No_Items' => dirname( __FILE__ ) . '/utility/condition/plugin/layouts/no-items.php',
|
34 |
'Toolset_Condition_Plugin_Types_Active' => dirname( __FILE__ ) . '/utility/condition/plugin/types/active.php',
|
|
|
35 |
'Toolset_Condition_Plugin_Types_Missing' => dirname( __FILE__ ) . '/utility/condition/plugin/types/missing.php',
|
36 |
'Toolset_Condition_Plugin_Types_Ready_For_M2M' => dirname( __FILE__ ) . '/utility/condition/plugin/types/ready_for_m2m.php',
|
37 |
'Toolset_Condition_Plugin_Views_Active' => dirname( __FILE__ ) . '/utility/condition/plugin/views/active.php',
|
38 |
'Toolset_Condition_Plugin_Views_Missing' => dirname( __FILE__ ) . '/utility/condition/plugin/views/missing.php',
|
39 |
'Toolset_Condition_Plugin_Wpml_Doesnt_Support_M2m' => dirname( __FILE__ ) . '/utility/condition/plugin/wpml/doesnt_support_m2m.php',
|
|
|
|
|
40 |
'Toolset_Condition_Theme_Avada_Not_Active_Or_Greater_Equal_5_0' => dirname( __FILE__ ) . '/utility/condition/theme/avada/not-active-or-greater-equal-5-0.php',
|
41 |
'Toolset_Condition_Theme_Layouts_Support_Native_Available' => dirname( __FILE__ ) . '/utility/condition/theme/layouts-support/native/available.php',
|
42 |
'Toolset_Condition_Theme_Layouts_Support_Native_Missing' => dirname( __FILE__ ) . '/utility/condition/theme/layouts-support/native/missing.php',
|
@@ -51,8 +70,10 @@ return array(
|
|
51 |
'Toolset_Condition_Theme_Toolset_Based_Active' => dirname( __FILE__ ) . '/utility/condition/theme/toolset-based/active.php',
|
52 |
'Toolset_Condition_Theme_Toolset_Based_Inactive' => dirname( __FILE__ ) . '/utility/condition/theme/toolset-based/inactive.php',
|
53 |
'Toolset_Condition_User_Role_Admin' => dirname( __FILE__ ) . '/utility/condition/user/role/admin.php',
|
54 |
-
'Toolset_Constants' => dirname( __FILE__ ) . '/inc/
|
55 |
-
'Toolset_Controller_Admin_Notices' => dirname( __FILE__ ) . '/inc/
|
|
|
|
|
56 |
'Toolset_Date' => dirname( __FILE__ ) . '/expression-parser/parser.php',
|
57 |
'Toolset_DateParser' => dirname( __FILE__ ) . '/expression-parser/parser.php',
|
58 |
'Toolset_Date_Utils' => dirname( __FILE__ ) . '/inc/autoloaded/date_utils.php',
|
@@ -71,13 +92,15 @@ return array(
|
|
71 |
'Toolset_Field_Data_Mapper_Checkboxes' => dirname( __FILE__ ) . '/inc/autoloaded/field/data_mapper/checkboxes.php',
|
72 |
'Toolset_Field_Data_Mapper_Identity' => dirname( __FILE__ ) . '/inc/autoloaded/field/data_mapper/identity.php',
|
73 |
'Toolset_Field_Data_Saver' => dirname( __FILE__ ) . '/inc/autoloaded/field/data_saver.php',
|
74 |
-
'Toolset_Field_Definition_Abstract' => dirname( __FILE__ ) . '/inc/autoloaded/field/definition_abstract.php',
|
75 |
'Toolset_Field_Definition' => dirname( __FILE__ ) . '/inc/autoloaded/field/definition.php',
|
|
|
76 |
'Toolset_Field_Definition_Factory' => dirname( __FILE__ ) . '/inc/autoloaded/field/definition_factory.php',
|
|
|
77 |
'Toolset_Field_Definition_Factory_Post' => dirname( __FILE__ ) . '/inc/autoloaded/field/definition_factory_post.php',
|
78 |
'Toolset_Field_Definition_Factory_Term' => dirname( __FILE__ ) . '/inc/autoloaded/field/definition_factory_term.php',
|
79 |
'Toolset_Field_Definition_Factory_User' => dirname( __FILE__ ) . '/inc/autoloaded/field/definition_factory_user.php',
|
80 |
'Toolset_Field_Definition_Generic' => dirname( __FILE__ ) . '/inc/autoloaded/field/definition_generic.php',
|
|
|
81 |
'Toolset_Field_Definition_Post' => dirname( __FILE__ ) . '/inc/autoloaded/field/definition_post.php',
|
82 |
'Toolset_Field_Definition_Term' => dirname( __FILE__ ) . '/inc/autoloaded/field/definition_term.php',
|
83 |
'Toolset_Field_Definition_User' => dirname( __FILE__ ) . '/inc/autoloaded/field/definition_user.php',
|
@@ -89,8 +112,8 @@ return array(
|
|
89 |
'Toolset_Field_Group_Term_Factory' => dirname( __FILE__ ) . '/inc/autoloaded/field/group/term_factory.php',
|
90 |
'Toolset_Field_Group_User' => dirname( __FILE__ ) . '/inc/autoloaded/field/group/user.php',
|
91 |
'Toolset_Field_Group_User_Factory' => dirname( __FILE__ ) . '/inc/autoloaded/field/group/user_factory.php',
|
92 |
-
'Toolset_Field_Instance_Abstract' => dirname( __FILE__ ) . '/inc/autoloaded/field/instance_abstract.php',
|
93 |
'Toolset_Field_Instance' => dirname( __FILE__ ) . '/inc/autoloaded/field/instance.php',
|
|
|
94 |
'Toolset_Field_Instance_Post' => dirname( __FILE__ ) . '/inc/autoloaded/field/instance_post.php',
|
95 |
'Toolset_Field_Instance_Term' => dirname( __FILE__ ) . '/inc/autoloaded/field/instance_term.php',
|
96 |
'Toolset_Field_Instance_Unsaved' => dirname( __FILE__ ) . '/inc/autoloaded/field/instance_unsaved.php',
|
@@ -113,21 +136,30 @@ return array(
|
|
113 |
'Toolset_Field_Renderer_Purpose' => dirname( __FILE__ ) . '/inc/autoloaded/field/renderer/purpose.php',
|
114 |
'Toolset_Field_Renderer_Toolset_Forms' => dirname( __FILE__ ) . '/inc/autoloaded/field/renderer/toolset_forms.php',
|
115 |
'Toolset_Field_Renderer_Toolset_Forms_Repeatable_Group' => dirname( __FILE__ ) . '/inc/autoloaded/field/renderer/toolset_forms_repeatable_group.php',
|
|
|
116 |
'Toolset_Field_Type_Definition_Checkbox' => dirname( __FILE__ ) . '/inc/autoloaded/field/type/definition/checkbox.php',
|
117 |
'Toolset_Field_Type_Definition_Checkboxes' => dirname( __FILE__ ) . '/inc/autoloaded/field/type/definition/checkboxes.php',
|
118 |
'Toolset_Field_Type_Definition_Date' => dirname( __FILE__ ) . '/inc/autoloaded/field/type/definition/date.php',
|
119 |
-
'Toolset_Field_Type_Definition' => dirname( __FILE__ ) . '/inc/autoloaded/field/type/definition.php',
|
120 |
'Toolset_Field_Type_Definition_Factory' => dirname( __FILE__ ) . '/inc/autoloaded/field/type/definition_factory.php',
|
121 |
'Toolset_Field_Type_Definition_Numeric' => dirname( __FILE__ ) . '/inc/autoloaded/field/type/definition/numeric.php',
|
122 |
'Toolset_Field_Type_Definition_Radio' => dirname( __FILE__ ) . '/inc/autoloaded/field/type/definition/radio.php',
|
123 |
'Toolset_Field_Type_Definition_Select' => dirname( __FILE__ ) . '/inc/autoloaded/field/type/definition/select.php',
|
124 |
'Toolset_Field_Type_Definition_Singular' => dirname( __FILE__ ) . '/inc/autoloaded/field/type/definition/singular.php',
|
125 |
'Toolset_Field_Utils' => dirname( __FILE__ ) . '/inc/autoloaded/field/utils.php',
|
|
|
126 |
'Toolset_Functions' => dirname( __FILE__ ) . '/expression-parser/parser.php',
|
127 |
'Toolset_Naming_Helper' => dirname( __FILE__ ) . '/inc/autoloaded/naming_helper.php',
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
128 |
'Toolset_Parser' => dirname( __FILE__ ) . '/expression-parser/parser.php',
|
129 |
'Toolset_Post' => dirname( __FILE__ ) . '/inc/autoloaded/element/post.php',
|
130 |
'Toolset_Post_Translation_Set' => dirname( __FILE__ ) . '/inc/autoloaded/element/post_translation_set.php',
|
|
|
131 |
'Toolset_Post_Type_Exclude_List' => dirname( __FILE__ ) . '/inc/autoloaded/post_type/excluded_list.php',
|
132 |
'Toolset_Post_Type_Factory' => dirname( __FILE__ ) . '/inc/autoloaded/post_type/factory.php',
|
133 |
'Toolset_Post_Type_From_Types' => dirname( __FILE__ ) . '/inc/autoloaded/post_type/from_types.php',
|
@@ -138,6 +170,7 @@ return array(
|
|
138 |
'Toolset_Post_Type_Repository' => dirname( __FILE__ ) . '/inc/autoloaded/post_type/repository.php',
|
139 |
'Toolset_Regex' => dirname( __FILE__ ) . '/expression-parser/parser.php',
|
140 |
'Toolset_Relationship_Service' => dirname( __FILE__ ) . '/inc/autoloaded/relationship_service.php',
|
|
|
141 |
'Toolset_Result' => dirname( __FILE__ ) . '/inc/autoloaded/result.php',
|
142 |
'Toolset_Result_Set' => dirname( __FILE__ ) . '/inc/autoloaded/result_set.php',
|
143 |
'Toolset_Result_Updated' => dirname( __FILE__ ) . '/inc/autoloaded/result_updated.php',
|
@@ -159,6 +192,7 @@ return array(
|
|
159 |
'Toolset_User_Editors_Editor_Basic' => dirname( __FILE__ ) . '/user-editors/editor/basic.php',
|
160 |
'Toolset_User_Editors_Editor_Beaver' => dirname( __FILE__ ) . '/user-editors/editor/beaver.php',
|
161 |
'Toolset_User_Editors_Editor_Divi' => dirname( __FILE__ ) . '/user-editors/editor/divi.php',
|
|
|
162 |
'Toolset_User_Editors_Editor_Interface' => dirname( __FILE__ ) . '/user-editors/editor/interface.php',
|
163 |
'Toolset_User_Editors_Editor_Native' => dirname( __FILE__ ) . '/user-editors/editor/native.php',
|
164 |
'Toolset_User_Editors_Editor_Screen_Abstract' => dirname( __FILE__ ) . '/user-editors/editor/screen/abstract.php',
|
@@ -169,6 +203,7 @@ return array(
|
|
169 |
'Toolset_User_Editors_Editor_Screen_Beaver_Frontend_Editor' => dirname( __FILE__ ) . '/user-editors/editor/screen/beaver/frontend-editor.php',
|
170 |
'Toolset_User_Editors_Editor_Screen_Divi_Backend' => dirname( __FILE__ ) . '/user-editors/editor/screen/divi/backend.php',
|
171 |
'Toolset_User_Editors_Editor_Screen_Divi_Frontend' => dirname( __FILE__ ) . '/user-editors/editor/screen/divi/frontend.php',
|
|
|
172 |
'Toolset_User_Editors_Editor_Screen_Interface' => dirname( __FILE__ ) . '/user-editors/editor/screen/interface.php',
|
173 |
'Toolset_User_Editors_Editor_Screen_Native_Backend' => dirname( __FILE__ ) . '/user-editors/editor/screen/native/backend.php',
|
174 |
'Toolset_User_Editors_Editor_Screen_Visual_Composer_Backend' => dirname( __FILE__ ) . '/user-editors/editor/screen/visual-composer/backend.php',
|
@@ -184,5 +219,36 @@ return array(
|
|
184 |
'Toolset_User_Editors_Medium_Screen_Content_Template_Frontend' => dirname( __FILE__ ) . '/user-editors/medium/screen/content-template/frontend.php',
|
185 |
'Toolset_User_Editors_Medium_Screen_Content_Template_Frontend_Editor' => dirname( __FILE__ ) . '/user-editors/medium/screen/content-template/frontend-editor.php',
|
186 |
'Toolset_User_Editors_Medium_Screen_Interface' => dirname( __FILE__ ) . '/user-editors/medium/screen/interface.php',
|
|
|
|
|
|
|
|
|
|
|
|
|
187 |
'Toolset_Wpml_Utils' => dirname( __FILE__ ) . '/inc/autoloaded/wpml_utils.php',
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
188 |
);
|
1 |
<?php
|
2 |
// Generated by ZF2's ./bin/classmap_generator.php
|
3 |
return array(
|
4 |
+
'IToolset_Cron_Event' => dirname( __FILE__ ) . '/inc/autoloaded/cron/event_interface.php',
|
5 |
'IToolset_Element' => dirname( __FILE__ ) . '/inc/autoloaded/element/i_element.php',
|
6 |
+
'IToolset_Output_Template' => dirname( __FILE__ ) . '/inc/autoloaded/renderer/output_template/interface.php',
|
7 |
'IToolset_Post' => dirname( __FILE__ ) . '/inc/autoloaded/element/i_post.php',
|
8 |
'IToolset_Post_Type' => dirname( __FILE__ ) . '/inc/autoloaded/post_type/i_post_type.php',
|
9 |
'IToolset_Post_Type_From_Types' => dirname( __FILE__ ) . '/inc/autoloaded/post_type/i_post_type_from_types.php',
|
10 |
'IToolset_Post_Type_Registered' => dirname( __FILE__ ) . '/inc/autoloaded/post_type/i_post_type_registered.php',
|
11 |
'IToolset_Query' => dirname( __FILE__ ) . '/inc/autoloaded/i_query.php',
|
12 |
'IToolset_Upgrade_Command' => dirname( __FILE__ ) . '/inc/autoloaded/upgrade/command_interface.php',
|
13 |
+
'Toolset_Admin_Controller' => dirname( __FILE__ ) . '/inc/autoloaded/admin.php',
|
14 |
'Toolset_Admin_Notice_Abstract' => dirname( __FILE__ ) . '/utility/admin/notice/abstract.php',
|
15 |
'Toolset_Admin_Notice_Dismissible' => dirname( __FILE__ ) . '/utility/admin/notice/dismissible.php',
|
16 |
'Toolset_Admin_Notice_Error' => dirname( __FILE__ ) . '/utility/admin/notice/error.php',
|
17 |
'Toolset_Admin_Notice_Interface' => dirname( __FILE__ ) . '/utility/admin/notice/interface.php',
|
18 |
'Toolset_Admin_Notice_Layouts_Help' => dirname( __FILE__ ) . '/utility/admin/notice/layouts/help.php',
|
19 |
'Toolset_Admin_Notice_Required_Action' => dirname( __FILE__ ) . '/utility/admin/notice/required/action.php',
|
|
|
20 |
'Toolset_Admin_Notice_Success' => dirname( __FILE__ ) . '/utility/admin/notice/success.php',
|
21 |
'Toolset_Admin_Notice_Undismissible' => dirname( __FILE__ ) . '/utility/admin/notice/undismissible.php',
|
22 |
'Toolset_Admin_Notice_Warning' => dirname( __FILE__ ) . '/utility/admin/notice/warning.php',
|
23 |
+
'Toolset_Admin_Notices_Manager' => dirname( __FILE__ ) . '/utility/admin/notices/manager.php',
|
24 |
'Toolset_Ajax_Handler_Abstract' => dirname( __FILE__ ) . '/inc/autoloaded/ajax_handler/abstract.php',
|
25 |
+
'Toolset_Ajax_Handler_Get_Content_Template_Block_Preview' => dirname( __FILE__ ) . '/inc/autoloaded/ajax_handler/get_ct_block_preview.php',
|
26 |
+
'Toolset_Ajax_Handler_Get_Post_By_Id' => dirname( __FILE__ ) . '/inc/autoloaded/ajax_handler/get_post_by_id.php',
|
27 |
+
'Toolset_Ajax_Handler_Get_Term_By_Id' => dirname( __FILE__ ) . '/inc/autoloaded/ajax_handler/get_term_by_id.php',
|
28 |
+
'Toolset_Ajax_Handler_Get_User_By_Id' => dirname( __FILE__ ) . '/inc/autoloaded/ajax_handler/get_user_by_id.php',
|
29 |
+
'Toolset_Ajax_Handler_Get_View_Block_Preview' => dirname( __FILE__ ) . '/inc/autoloaded/ajax_handler/get_view_block_preview.php',
|
30 |
'Toolset_Ajax_Handler_Interface' => dirname( __FILE__ ) . '/inc/autoloaded/ajax_handler/interface.php',
|
31 |
+
'Toolset_Ajax_Handler_Intermediary_Post_Cleanup' => dirname( __FILE__ ) . '/inc/autoloaded/ajax_handler/intermediary_post_cleanup.php',
|
32 |
'Toolset_Ajax_Handler_Migrate_To_M2M' => dirname( __FILE__ ) . '/inc/autoloaded/ajax_handler/migrate_to_m2m.php',
|
33 |
+
'Toolset_Ajax_Handler_Select2_Suggest_Posts_By_Title' => dirname( __FILE__ ) . '/inc/autoloaded/ajax_handler/select2_suggest_posts_by_title.php',
|
34 |
+
'Toolset_Ajax_Handler_Select2_Suggest_Terms' => dirname( __FILE__ ) . '/inc/autoloaded/ajax_handler/select2_suggest_terms.php',
|
35 |
+
'Toolset_Ajax_Handler_Select2_Suggest_Users' => dirname( __FILE__ ) . '/inc/autoloaded/ajax_handler/select2_suggest_users.php',
|
36 |
+
'Toolset_Asset_Manager' => dirname( __FILE__ ) . '/inc/autoloaded/asset_manager.php',
|
37 |
+
'Toolset_Blocks' => dirname( __FILE__ ) . '/toolset-blocks/toolset-blocks.php',
|
38 |
+
'Toolset_Blocks_Content_Template' => dirname( __FILE__ ) . '/toolset-blocks/blocks/ct/ct.php',
|
39 |
+
'Toolset_Blocks_Custom_HTML' => dirname( __FILE__ ) . '/toolset-blocks/blocks/custom-html/custom-html.php',
|
40 |
+
'Toolset_Blocks_View' => dirname( __FILE__ ) . '/toolset-blocks/blocks/view/view.php',
|
41 |
'Toolset_Condition_Interface' => dirname( __FILE__ ) . '/utility/condition/interface.php',
|
42 |
'Toolset_Condition_Plugin_Access_Active' => dirname( __FILE__ ) . '/utility/condition/plugin/access/active.php',
|
43 |
'Toolset_Condition_Plugin_Access_Missing' => dirname( __FILE__ ) . '/utility/condition/plugin/access/missing.php',
|
48 |
'Toolset_Condition_Plugin_Layouts_Missing' => dirname( __FILE__ ) . '/utility/condition/plugin/layouts/missing.php',
|
49 |
'Toolset_Condition_Plugin_Layouts_No_Items' => dirname( __FILE__ ) . '/utility/condition/plugin/layouts/no-items.php',
|
50 |
'Toolset_Condition_Plugin_Types_Active' => dirname( __FILE__ ) . '/utility/condition/plugin/types/active.php',
|
51 |
+
'Toolset_Condition_Plugin_Types_Has_Legacy_Relationships' => dirname( __FILE__ ) . '/utility/condition/plugin/types/has_legacy_relationships.php',
|
52 |
'Toolset_Condition_Plugin_Types_Missing' => dirname( __FILE__ ) . '/utility/condition/plugin/types/missing.php',
|
53 |
'Toolset_Condition_Plugin_Types_Ready_For_M2M' => dirname( __FILE__ ) . '/utility/condition/plugin/types/ready_for_m2m.php',
|
54 |
'Toolset_Condition_Plugin_Views_Active' => dirname( __FILE__ ) . '/utility/condition/plugin/views/active.php',
|
55 |
'Toolset_Condition_Plugin_Views_Missing' => dirname( __FILE__ ) . '/utility/condition/plugin/views/missing.php',
|
56 |
'Toolset_Condition_Plugin_Wpml_Doesnt_Support_M2m' => dirname( __FILE__ ) . '/utility/condition/plugin/wpml/doesnt_support_m2m.php',
|
57 |
+
'Toolset_Condition_Plugin_Wpml_Is_Active_And_Configured' => dirname( __FILE__ ) . '/utility/condition/plugin/wpml/is_active_and_configured.php',
|
58 |
+
'Toolset_Condition_Plugin_Wpml_Is_Current_Language_Default' => dirname( __FILE__ ) . '/utility/condition/plugin/wpml/is_current_language_default.php',
|
59 |
'Toolset_Condition_Theme_Avada_Not_Active_Or_Greater_Equal_5_0' => dirname( __FILE__ ) . '/utility/condition/theme/avada/not-active-or-greater-equal-5-0.php',
|
60 |
'Toolset_Condition_Theme_Layouts_Support_Native_Available' => dirname( __FILE__ ) . '/utility/condition/theme/layouts-support/native/available.php',
|
61 |
'Toolset_Condition_Theme_Layouts_Support_Native_Missing' => dirname( __FILE__ ) . '/utility/condition/theme/layouts-support/native/missing.php',
|
70 |
'Toolset_Condition_Theme_Toolset_Based_Active' => dirname( __FILE__ ) . '/utility/condition/theme/toolset-based/active.php',
|
71 |
'Toolset_Condition_Theme_Toolset_Based_Inactive' => dirname( __FILE__ ) . '/utility/condition/theme/toolset-based/inactive.php',
|
72 |
'Toolset_Condition_User_Role_Admin' => dirname( __FILE__ ) . '/utility/condition/user/role/admin.php',
|
73 |
+
'Toolset_Constants' => dirname( __FILE__ ) . '/inc/autoloaded/constants.php',
|
74 |
+
'Toolset_Controller_Admin_Notices' => dirname( __FILE__ ) . '/inc/autoloaded/admin/notices.php',
|
75 |
+
'Toolset_Cron' => dirname( __FILE__ ) . '/inc/autoloaded/cron/cron.php',
|
76 |
+
'Toolset_Cron_Event' => dirname( __FILE__ ) . '/inc/autoloaded/cron/event.php',
|
77 |
'Toolset_Date' => dirname( __FILE__ ) . '/expression-parser/parser.php',
|
78 |
'Toolset_DateParser' => dirname( __FILE__ ) . '/expression-parser/parser.php',
|
79 |
'Toolset_Date_Utils' => dirname( __FILE__ ) . '/inc/autoloaded/date_utils.php',
|
92 |
'Toolset_Field_Data_Mapper_Checkboxes' => dirname( __FILE__ ) . '/inc/autoloaded/field/data_mapper/checkboxes.php',
|
93 |
'Toolset_Field_Data_Mapper_Identity' => dirname( __FILE__ ) . '/inc/autoloaded/field/data_mapper/identity.php',
|
94 |
'Toolset_Field_Data_Saver' => dirname( __FILE__ ) . '/inc/autoloaded/field/data_saver.php',
|
|
|
95 |
'Toolset_Field_Definition' => dirname( __FILE__ ) . '/inc/autoloaded/field/definition.php',
|
96 |
+
'Toolset_Field_Definition_Abstract' => dirname( __FILE__ ) . '/inc/autoloaded/field/definition_abstract.php',
|
97 |
'Toolset_Field_Definition_Factory' => dirname( __FILE__ ) . '/inc/autoloaded/field/definition_factory.php',
|
98 |
+
'Toolset_Field_Definition_Factory_Interface' => dirname( __FILE__ ) . '/inc/autoloaded/field/definition_factory_interface.php',
|
99 |
'Toolset_Field_Definition_Factory_Post' => dirname( __FILE__ ) . '/inc/autoloaded/field/definition_factory_post.php',
|
100 |
'Toolset_Field_Definition_Factory_Term' => dirname( __FILE__ ) . '/inc/autoloaded/field/definition_factory_term.php',
|
101 |
'Toolset_Field_Definition_Factory_User' => dirname( __FILE__ ) . '/inc/autoloaded/field/definition_factory_user.php',
|
102 |
'Toolset_Field_Definition_Generic' => dirname( __FILE__ ) . '/inc/autoloaded/field/definition_generic.php',
|
103 |
+
'Toolset_Field_Definition_Interface' => dirname( __FILE__ ) . '/inc/autoloaded/field/definition_interface.php',
|
104 |
'Toolset_Field_Definition_Post' => dirname( __FILE__ ) . '/inc/autoloaded/field/definition_post.php',
|
105 |
'Toolset_Field_Definition_Term' => dirname( __FILE__ ) . '/inc/autoloaded/field/definition_term.php',
|
106 |
'Toolset_Field_Definition_User' => dirname( __FILE__ ) . '/inc/autoloaded/field/definition_user.php',
|
112 |
'Toolset_Field_Group_Term_Factory' => dirname( __FILE__ ) . '/inc/autoloaded/field/group/term_factory.php',
|
113 |
'Toolset_Field_Group_User' => dirname( __FILE__ ) . '/inc/autoloaded/field/group/user.php',
|
114 |
'Toolset_Field_Group_User_Factory' => dirname( __FILE__ ) . '/inc/autoloaded/field/group/user_factory.php',
|
|
|
115 |
'Toolset_Field_Instance' => dirname( __FILE__ ) . '/inc/autoloaded/field/instance.php',
|
116 |
+
'Toolset_Field_Instance_Abstract' => dirname( __FILE__ ) . '/inc/autoloaded/field/instance_abstract.php',
|
117 |
'Toolset_Field_Instance_Post' => dirname( __FILE__ ) . '/inc/autoloaded/field/instance_post.php',
|
118 |
'Toolset_Field_Instance_Term' => dirname( __FILE__ ) . '/inc/autoloaded/field/instance_term.php',
|
119 |
'Toolset_Field_Instance_Unsaved' => dirname( __FILE__ ) . '/inc/autoloaded/field/instance_unsaved.php',
|
136 |
'Toolset_Field_Renderer_Purpose' => dirname( __FILE__ ) . '/inc/autoloaded/field/renderer/purpose.php',
|
137 |
'Toolset_Field_Renderer_Toolset_Forms' => dirname( __FILE__ ) . '/inc/autoloaded/field/renderer/toolset_forms.php',
|
138 |
'Toolset_Field_Renderer_Toolset_Forms_Repeatable_Group' => dirname( __FILE__ ) . '/inc/autoloaded/field/renderer/toolset_forms_repeatable_group.php',
|
139 |
+
'Toolset_Field_Type_Definition' => dirname( __FILE__ ) . '/inc/autoloaded/field/type/definition.php',
|
140 |
'Toolset_Field_Type_Definition_Checkbox' => dirname( __FILE__ ) . '/inc/autoloaded/field/type/definition/checkbox.php',
|
141 |
'Toolset_Field_Type_Definition_Checkboxes' => dirname( __FILE__ ) . '/inc/autoloaded/field/type/definition/checkboxes.php',
|
142 |
'Toolset_Field_Type_Definition_Date' => dirname( __FILE__ ) . '/inc/autoloaded/field/type/definition/date.php',
|
|
|
143 |
'Toolset_Field_Type_Definition_Factory' => dirname( __FILE__ ) . '/inc/autoloaded/field/type/definition_factory.php',
|
144 |
'Toolset_Field_Type_Definition_Numeric' => dirname( __FILE__ ) . '/inc/autoloaded/field/type/definition/numeric.php',
|
145 |
'Toolset_Field_Type_Definition_Radio' => dirname( __FILE__ ) . '/inc/autoloaded/field/type/definition/radio.php',
|
146 |
'Toolset_Field_Type_Definition_Select' => dirname( __FILE__ ) . '/inc/autoloaded/field/type/definition/select.php',
|
147 |
'Toolset_Field_Type_Definition_Singular' => dirname( __FILE__ ) . '/inc/autoloaded/field/type/definition/singular.php',
|
148 |
'Toolset_Field_Utils' => dirname( __FILE__ ) . '/inc/autoloaded/field/utils.php',
|
149 |
+
'Toolset_Files' => dirname( __FILE__ ) . '/inc/autoloaded/files.php',
|
150 |
'Toolset_Functions' => dirname( __FILE__ ) . '/expression-parser/parser.php',
|
151 |
'Toolset_Naming_Helper' => dirname( __FILE__ ) . '/inc/autoloaded/naming_helper.php',
|
152 |
+
'Toolset_Output_Template' => dirname( __FILE__ ) . '/inc/autoloaded/renderer/output_template/abstract.php',
|
153 |
+
'Toolset_Output_Template_Factory' => dirname( __FILE__ ) . '/inc/autoloaded/renderer/output_template_factory.php',
|
154 |
+
'Toolset_Output_Template_Phtml' => dirname( __FILE__ ) . '/inc/autoloaded/renderer/output_template/phtml.php',
|
155 |
+
'Toolset_Output_Template_Repository' => dirname( __FILE__ ) . '/inc/autoloaded/renderer/output_template_repository.php',
|
156 |
+
'Toolset_Output_Template_Repository_Abstract' => dirname( __FILE__ ) . '/inc/autoloaded/renderer/output_template_repository_abstract.php',
|
157 |
+
'Toolset_Output_Template_Static' => dirname( __FILE__ ) . '/inc/autoloaded/renderer/output_template/static.php',
|
158 |
+
'Toolset_Output_Template_Twig' => dirname( __FILE__ ) . '/inc/autoloaded/renderer/output_template/twig.php',
|
159 |
'Toolset_Parser' => dirname( __FILE__ ) . '/expression-parser/parser.php',
|
160 |
'Toolset_Post' => dirname( __FILE__ ) . '/inc/autoloaded/element/post.php',
|
161 |
'Toolset_Post_Translation_Set' => dirname( __FILE__ ) . '/inc/autoloaded/element/post_translation_set.php',
|
162 |
+
'Toolset_Post_Type_Abstract' => dirname( __FILE__ ) . '/inc/autoloaded/post_type/abstract.php',
|
163 |
'Toolset_Post_Type_Exclude_List' => dirname( __FILE__ ) . '/inc/autoloaded/post_type/excluded_list.php',
|
164 |
'Toolset_Post_Type_Factory' => dirname( __FILE__ ) . '/inc/autoloaded/post_type/factory.php',
|
165 |
'Toolset_Post_Type_From_Types' => dirname( __FILE__ ) . '/inc/autoloaded/post_type/from_types.php',
|
170 |
'Toolset_Post_Type_Repository' => dirname( __FILE__ ) . '/inc/autoloaded/post_type/repository.php',
|
171 |
'Toolset_Regex' => dirname( __FILE__ ) . '/expression-parser/parser.php',
|
172 |
'Toolset_Relationship_Service' => dirname( __FILE__ ) . '/inc/autoloaded/relationship_service.php',
|
173 |
+
'Toolset_Renderer' => dirname( __FILE__ ) . '/inc/autoloaded/renderer/renderer.php',
|
174 |
'Toolset_Result' => dirname( __FILE__ ) . '/inc/autoloaded/result.php',
|
175 |
'Toolset_Result_Set' => dirname( __FILE__ ) . '/inc/autoloaded/result_set.php',
|
176 |
'Toolset_Result_Updated' => dirname( __FILE__ ) . '/inc/autoloaded/result_updated.php',
|
192 |
'Toolset_User_Editors_Editor_Basic' => dirname( __FILE__ ) . '/user-editors/editor/basic.php',
|
193 |
'Toolset_User_Editors_Editor_Beaver' => dirname( __FILE__ ) . '/user-editors/editor/beaver.php',
|
194 |
'Toolset_User_Editors_Editor_Divi' => dirname( __FILE__ ) . '/user-editors/editor/divi.php',
|
195 |
+
'Toolset_User_Editors_Editor_Gutenberg' => dirname( __FILE__ ) . '/user-editors/editor/gutenberg.php',
|
196 |
'Toolset_User_Editors_Editor_Interface' => dirname( __FILE__ ) . '/user-editors/editor/interface.php',
|
197 |
'Toolset_User_Editors_Editor_Native' => dirname( __FILE__ ) . '/user-editors/editor/native.php',
|
198 |
'Toolset_User_Editors_Editor_Screen_Abstract' => dirname( __FILE__ ) . '/user-editors/editor/screen/abstract.php',
|
203 |
'Toolset_User_Editors_Editor_Screen_Beaver_Frontend_Editor' => dirname( __FILE__ ) . '/user-editors/editor/screen/beaver/frontend-editor.php',
|
204 |
'Toolset_User_Editors_Editor_Screen_Divi_Backend' => dirname( __FILE__ ) . '/user-editors/editor/screen/divi/backend.php',
|
205 |
'Toolset_User_Editors_Editor_Screen_Divi_Frontend' => dirname( __FILE__ ) . '/user-editors/editor/screen/divi/frontend.php',
|
206 |
+
'Toolset_User_Editors_Editor_Screen_Gutenberg_Backend' => dirname( __FILE__ ) . '/user-editors/editor/screen/gutenberg/backend.php',
|
207 |
'Toolset_User_Editors_Editor_Screen_Interface' => dirname( __FILE__ ) . '/user-editors/editor/screen/interface.php',
|
208 |
'Toolset_User_Editors_Editor_Screen_Native_Backend' => dirname( __FILE__ ) . '/user-editors/editor/screen/native/backend.php',
|
209 |
'Toolset_User_Editors_Editor_Screen_Visual_Composer_Backend' => dirname( __FILE__ ) . '/user-editors/editor/screen/visual-composer/backend.php',
|
219 |
'Toolset_User_Editors_Medium_Screen_Content_Template_Frontend' => dirname( __FILE__ ) . '/user-editors/medium/screen/content-template/frontend.php',
|
220 |
'Toolset_User_Editors_Medium_Screen_Content_Template_Frontend_Editor' => dirname( __FILE__ ) . '/user-editors/medium/screen/content-template/frontend-editor.php',
|
221 |
'Toolset_User_Editors_Medium_Screen_Interface' => dirname( __FILE__ ) . '/user-editors/medium/screen/interface.php',
|
222 |
+
'Toolset_Wp_Query_Adjustments' => dirname( __FILE__ ) . '/inc/autoloaded/wp_query_adjustments/abstract.php',
|
223 |
+
'Toolset_Wp_Query_Adjustments_Legacy_Relationships' => dirname( __FILE__ ) . '/inc/autoloaded/wp_query_adjustments/legacy_relationships.php',
|
224 |
+
'Toolset_Wp_Query_Adjustments_Loader' => dirname( __FILE__ ) . '/inc/autoloaded/wp_query_adjustments/loader.php',
|
225 |
+
'Toolset_Wp_Query_Adjustments_M2m' => dirname( __FILE__ ) . '/inc/autoloaded/wp_query_adjustments/m2m.php',
|
226 |
+
'Toolset_Wp_Query_Adjustments_Table_Join_Manager' => dirname( __FILE__ ) . '/inc/autoloaded/wp_query_adjustments/table_join_manager.php',
|
227 |
+
'Toolset_Wpdb_User' => dirname( __FILE__ ) . '/inc/autoloaded/wpdb_user.php',
|
228 |
'Toolset_Wpml_Utils' => dirname( __FILE__ ) . '/inc/autoloaded/wpml_utils.php',
|
229 |
+
'Whip_BasicMessage' => dirname( __FILE__ ) . '/lib/whip/src/messages/Whip_BasicMessage.php',
|
230 |
+
'Whip_Configuration' => dirname( __FILE__ ) . '/lib/whip/src/Whip_Configuration.php',
|
231 |
+
'Whip_DismissStorage' => dirname( __FILE__ ) . '/lib/whip/src/interfaces/Whip_DismissStorage.php',
|
232 |
+
'Whip_EmptyProperty' => dirname( __FILE__ ) . '/lib/whip/src/exceptions/Whip_EmptyProperty.php',
|
233 |
+
'Whip_Host' => dirname( __FILE__ ) . '/lib/whip/src/Whip_Host.php',
|
234 |
+
'Whip_HostMessage' => dirname( __FILE__ ) . '/lib/whip/src/messages/Whip_HostMessage.php',
|
235 |
+
'Whip_InvalidOperatorType' => dirname( __FILE__ ) . '/lib/whip/src/exceptions/Whip_InvalidOperatorType.php',
|
236 |
+
'Whip_InvalidType' => dirname( __FILE__ ) . '/lib/whip/src/exceptions/Whip_InvalidType.php',
|
237 |
+
'Whip_InvalidVersionComparisonString' => dirname( __FILE__ ) . '/lib/whip/src/exceptions/Whip_InvalidVersionComparisonString.php',
|
238 |
+
'Whip_InvalidVersionRequirementMessage' => dirname( __FILE__ ) . '/lib/whip/src/messages/Whip_InvalidVersionRequirementMessage.php',
|
239 |
+
'Whip_Listener' => dirname( __FILE__ ) . '/lib/whip/src/interfaces/Whip_Listener.php',
|
240 |
+
'Whip_Message' => dirname( __FILE__ ) . '/lib/whip/src/interfaces/Whip_Message.php',
|
241 |
+
'Whip_MessageDismisser' => dirname( __FILE__ ) . '/lib/whip/src/Whip_MessageDismisser.php',
|
242 |
+
'Whip_MessageFormatter' => dirname( __FILE__ ) . '/lib/whip/src/Whip_MessageFormatter.php',
|
243 |
+
'Whip_MessagePresenter' => dirname( __FILE__ ) . '/lib/whip/src/interfaces/Whip_MessagePresenter.php',
|
244 |
+
'Whip_MessagesManager' => dirname( __FILE__ ) . '/lib/whip/src/Whip_MessagesManager.php',
|
245 |
+
'Whip_NullMessage' => dirname( __FILE__ ) . '/lib/whip/src/messages/Whip_NullMessage.php',
|
246 |
+
'Whip_Requirement' => dirname( __FILE__ ) . '/lib/whip/src/interfaces/Whip_Requirement.php',
|
247 |
+
'Whip_RequirementsChecker' => dirname( __FILE__ ) . '/lib/whip/src/Whip_RequirementsChecker.php',
|
248 |
+
'Whip_UpgradePhpMessage' => dirname( __FILE__ ) . '/lib/whip/src/messages/Whip_UpgradePhpMessage.php',
|
249 |
+
'Whip_VersionDetector' => dirname( __FILE__ ) . '/lib/whip/src/interfaces/Whip_VersionDetector.php',
|
250 |
+
'Whip_VersionRequirement' => dirname( __FILE__ ) . '/lib/whip/src/Whip_VersionRequirement.php',
|
251 |
+
'Whip_WPDismissOption' => dirname( __FILE__ ) . '/lib/whip/src/Whip_WPDismissOption.php',
|
252 |
+
'Whip_WPMessageDismissListener' => dirname( __FILE__ ) . '/lib/whip/src/Whip_WPMessageDismissListener.php',
|
253 |
+
'Whip_WPMessagePresenter' => dirname( __FILE__ ) . '/lib/whip/src/presenters/Whip_WPMessagePresenter.php',
|
254 |
);
|
vendor/toolset/toolset-common/bootstrap.php
CHANGED
@@ -46,8 +46,10 @@ class Toolset_Common_Bootstrap {
|
|
46 |
|
47 |
// Names of various sections/modules of the common library that can be loaded.
|
48 |
const TOOLSET_AUTOLOADER = 'toolset_autoloader';
|
|
|
49 |
const TOOLSET_DEBUG = 'toolset_debug';
|
50 |
const TOOLSET_FORMS = 'toolset_forms';
|
|
|
51 |
const TOOLSET_VISUAL_EDITOR = 'toolset_visual_editor';
|
52 |
const TOOLSET_PARSER = 'toolset_parser';
|
53 |
const TOOLSET_USER_EDITOR = 'toolset_user_editor';
|
@@ -187,6 +189,11 @@ class Toolset_Common_Bootstrap {
|
|
187 |
$this->register_toolset_forms();
|
188 |
}
|
189 |
|
|
|
|
|
|
|
|
|
|
|
190 |
// Maybe register the editor addon
|
191 |
if ( $this->should_load_section( $load, self::TOOLSET_VISUAL_EDITOR ) ) {
|
192 |
$this->register_visual_editor();
|
@@ -321,7 +328,7 @@ class Toolset_Common_Bootstrap {
|
|
321 |
|
322 |
if ( ! class_exists( 'Toolset_Bootstrap_Loader', false ) ) {
|
323 |
require_once( TOOLSET_COMMON_PATH . '/inc/toolset.bootstrap.loader.class.php' );
|
324 |
-
|
325 |
}
|
326 |
|
327 |
// Load Admin Notices Manager
|
@@ -332,7 +339,6 @@ class Toolset_Common_Bootstrap {
|
|
332 |
|
333 |
// Load Admin Notices Controller (user of our Toolset_Admin_Notices_Manager)
|
334 |
if( ! class_exists( 'Toolset_Controller_Admin_Notices', false ) ) {
|
335 |
-
require_once( TOOLSET_COMMON_PATH . '/inc/controller/admin/notices.php' );
|
336 |
new Toolset_Controller_Admin_Notices();
|
337 |
}
|
338 |
|
@@ -357,6 +363,19 @@ class Toolset_Common_Bootstrap {
|
|
357 |
|
358 |
$this->register_relationships();
|
359 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
360 |
$this->apply_filters_on_sections_loaded( 'toolset_register_include_section' );
|
361 |
}
|
362 |
}
|
@@ -375,6 +394,11 @@ class Toolset_Common_Bootstrap {
|
|
375 |
require_once TOOLSET_COMMON_PATH . '/utility/utils.php';
|
376 |
}
|
377 |
|
|
|
|
|
|
|
|
|
|
|
378 |
// Although this is full of DDL prefixes, we need to actually port before using it.
|
379 |
if ( ! $this->is_section_loaded( self::TOOLSET_DIALOGS ) ) {
|
380 |
$this->add_section_loaded( self::TOOLSET_DIALOGS );
|
@@ -421,6 +445,15 @@ class Toolset_Common_Bootstrap {
|
|
421 |
}
|
422 |
}
|
423 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
424 |
public function register_visual_editor() {
|
425 |
|
426 |
if ( ! $this->is_section_loaded( self::TOOLSET_VISUAL_EDITOR ) ) {
|
46 |
|
47 |
// Names of various sections/modules of the common library that can be loaded.
|
48 |
const TOOLSET_AUTOLOADER = 'toolset_autoloader';
|
49 |
+
const TOOLSET_API = 'toolset_api';
|
50 |
const TOOLSET_DEBUG = 'toolset_debug';
|
51 |
const TOOLSET_FORMS = 'toolset_forms';
|
52 |
+
const TOOLSET_BLOCKS = 'toolset_blocks';
|
53 |
const TOOLSET_VISUAL_EDITOR = 'toolset_visual_editor';
|
54 |
const TOOLSET_PARSER = 'toolset_parser';
|
55 |
const TOOLSET_USER_EDITOR = 'toolset_user_editor';
|
189 |
$this->register_toolset_forms();
|
190 |
}
|
191 |
|
192 |
+
// Maybe register Toolset blocks
|
193 |
+
if ( $this->should_load_section( $load, self::TOOLSET_BLOCKS ) ) {
|
194 |
+
$this->register_toolset_blocks();
|
195 |
+
}
|
196 |
+
|
197 |
// Maybe register the editor addon
|
198 |
if ( $this->should_load_section( $load, self::TOOLSET_VISUAL_EDITOR ) ) {
|
199 |
$this->register_visual_editor();
|
328 |
|
329 |
if ( ! class_exists( 'Toolset_Bootstrap_Loader', false ) ) {
|
330 |
require_once( TOOLSET_COMMON_PATH . '/inc/toolset.bootstrap.loader.class.php' );
|
331 |
+
Toolset_Bootstrap_Loader::getInstance();
|
332 |
}
|
333 |
|
334 |
// Load Admin Notices Manager
|
339 |
|
340 |
// Load Admin Notices Controller (user of our Toolset_Admin_Notices_Manager)
|
341 |
if( ! class_exists( 'Toolset_Controller_Admin_Notices', false ) ) {
|
|
|
342 |
new Toolset_Controller_Admin_Notices();
|
343 |
}
|
344 |
|
363 |
|
364 |
$this->register_relationships();
|
365 |
|
366 |
+
// Initialize the admin controller for various tasks if we're in the backend.
|
367 |
+
if( self::MODE_ADMIN === $this->get_request_mode() ) {
|
368 |
+
$admin_controller = new Toolset_Admin_Controller();
|
369 |
+
$admin_controller->initialize();
|
370 |
+
}
|
371 |
+
|
372 |
+
require_once TOOLSET_COMMON_PATH . '/inc/public_api/loader.php';
|
373 |
+
$public_api_loader = new Toolset_Public_API_Loader();
|
374 |
+
$public_api_loader->initialize();
|
375 |
+
|
376 |
+
$wp_query_adjustments = new Toolset_Wp_Query_Adjustments_Loader();
|
377 |
+
$wp_query_adjustments->initialize();
|
378 |
+
|
379 |
$this->apply_filters_on_sections_loaded( 'toolset_register_include_section' );
|
380 |
}
|
381 |
}
|
394 |
require_once TOOLSET_COMMON_PATH . '/utility/utils.php';
|
395 |
}
|
396 |
|
397 |
+
if ( ! $this->is_section_loaded( self::TOOLSET_API ) ) {
|
398 |
+
$this->add_section_loaded( self::TOOLSET_API );
|
399 |
+
require_once TOOLSET_COMMON_PATH . '/api.php';
|
400 |
+
}
|
401 |
+
|
402 |
// Although this is full of DDL prefixes, we need to actually port before using it.
|
403 |
if ( ! $this->is_section_loaded( self::TOOLSET_DIALOGS ) ) {
|
404 |
$this->add_section_loaded( self::TOOLSET_DIALOGS );
|
445 |
}
|
446 |
}
|
447 |
|
448 |
+
public function register_toolset_blocks() {
|
449 |
+
if ( ! $this->is_section_loaded( self::TOOLSET_BLOCKS ) ) {
|
450 |
+
$this->add_section_loaded( self::TOOLSET_BLOCKS );
|
451 |
+
$toolset_blocks = new Toolset_Blocks();
|
452 |
+
$toolset_blocks->load_blocks();
|
453 |
+
$this->apply_filters_on_sections_loaded( 'toolset_register_toolset_blocks_section' );
|
454 |
+
}
|
455 |
+
}
|
456 |
+
|
457 |
public function register_visual_editor() {
|
458 |
|
459 |
if ( ! $this->is_section_loaded( self::TOOLSET_VISUAL_EDITOR ) ) {
|
vendor/toolset/toolset-common/changelog.md
CHANGED
@@ -1,7 +1,37 @@
|
|
1 |
# Toolset Common Library
|
2 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
## 2.5.8
|
4 |
-
* New admin notice about Types becoming commercial
|
|
|
5 |
|
6 |
## 2.5.7
|
7 |
* (toolsetcommon-305) Improve the database structure for relationships and associations.
|
@@ -10,7 +40,7 @@
|
|
10 |
* Many improvements to the m2m API, especially to the relationship query.
|
11 |
* (toolsetcommon-328) Enforce cardinality limits when creating associations between two elements.
|
12 |
* (toolsetcommon-330) Prevent upgrade routines from running repeatedly. Fix a m2m activation issue.
|
13 |
-
* (toolsetcommon-249) The Toolset_Twig_Autoloader now bails out when it's possible to load the Twig_Environment class.
|
14 |
|
15 |
## 2.5.6
|
16 |
* Fixed a but that prevented CRED attributes offered as select2 instances from getting their values in the final shortcode.
|
@@ -92,7 +122,7 @@
|
|
92 |
- Only include the jQuery datepicker stylesheet on demand when the current page contains a datepicker from Toolset.
|
93 |
- Include the user editors in the common bootstrap class.
|
94 |
- toolsetcommon-127, toolsetcommon-55: Include knockout.js
|
95 |
-
- toolsetcommon-139: Clean up Toolset_Assets_Manager and define constants for asset handles
|
96 |
- toolsetcommon-144: Added Toolset_Admin_Notices_Manager
|
97 |
- toolsetcommon-137: Make the toolset-forms classes autoloaded.
|
98 |
- toolsetcommon-72: Implemented a classmap-based autoloader for all Toolset plugins.
|
@@ -105,7 +135,7 @@
|
|
105 |
|
106 |
## 2.2.9
|
107 |
|
108 |
-
- Fix a validation issue for file, audio, video and embed fields affecting Types.
|
109 |
Allow URLs with non-latin characters, but only for URLs that point to attachments
|
110 |
from the Media Library (validated by WordPress media upload mechanism) (types-1013).
|
111 |
- Improve the validation for non-required Skype fields (toolsetcommon-128).
|
@@ -118,7 +148,7 @@
|
|
118 |
- Extend WPToolset_Cake_Validation with the "url2" validation as a counterpart to the validation method in JQuery UI (types-988).
|
119 |
|
120 |
## 2.2.5 (November 5, 2016)
|
121 |
-
|
122 |
- Thorough check for security vulnerabilities.
|
123 |
|
124 |
## 2.2.4 (November 2, 2016)
|
@@ -140,9 +170,9 @@
|
|
140 |
- Added an internal Toolset compatibility class
|
141 |
|
142 |
## 2.2.1 (August 25, 2016)
|
143 |
-
|
144 |
- Avoid translating the Toolset top level admin menu label
|
145 |
-
|
146 |
## 2.2 (August 24, 2016)
|
147 |
|
148 |
- Added compatibility classes for Relevanssi and Beaver Builder
|
@@ -168,11 +198,11 @@
|
|
168 |
- Fixed various bugs
|
169 |
|
170 |
## 1.9.2 (March 17, 2016)
|
171 |
-
|
172 |
- Fixed issue in validation messages on Amazon S3
|
173 |
|
174 |
## 1.9.1 (March 15, 2016)
|
175 |
-
|
176 |
- Added control to filter array to prevent exceptions
|
177 |
- Prevented error when object does not have property or key is not set in array filter callback
|
178 |
- Fixed glitch in validation library
|
@@ -180,7 +210,7 @@
|
|
180 |
- Fixed search terms with language translation
|
181 |
|
182 |
## 1.9 (February 15, 2016)
|
183 |
-
|
184 |
- Tagged for Types 1.9, Views 1.12, CRED 1.5, Layouts 1.5 and Access 1.2.8
|
185 |
- Updated parser.php constructors for PHP7 compatibility.
|
186 |
- Updated the adodb time library for PHP7 compatibility.
|
@@ -188,7 +218,7 @@
|
|
188 |
- New utils.
|
189 |
|
190 |
## 1.8 (November 10, 2015)
|
191 |
-
|
192 |
- Tagged for Views 1.11.1, Types 1.8.9 and CRED 1.4.2
|
193 |
- Improved the media manager script.
|
194 |
- Added helper functions for dealing with $_GET, $_POST and arrays.
|
@@ -197,23 +227,23 @@
|
|
197 |
- Improved usermeta fields management in CRED forms.
|
198 |
|
199 |
## 1.7 (October 30, 2015)
|
200 |
-
|
201 |
- Tagged for Views 1.11 and Layouts 1.4
|
202 |
|
203 |
## 1.6.2 (September 25, 2015)
|
204 |
-
|
205 |
- Tagged for CRED 1.4, Types 1.8.2
|
206 |
|
207 |
## 1.6.1 (August 17, 2015)
|
208 |
-
|
209 |
- Tagged for Composer Types 1.8, Views 1.10, CRED 1.4 and Layouts 1.3
|
210 |
|
211 |
## 1.6 (June 11, 2015)
|
212 |
-
|
213 |
- Tagged for Types 1.7, Views 1.9 and Layouts 1.2
|
214 |
|
215 |
## 1.5 (Apr 1, 2015)
|
216 |
-
|
217 |
- Tagged for Types 1.6.6, Views 1.8, CRED 1.3.6 and Layouts 1.1.
|
218 |
- Fixed issue when there is more than one CRED form on a page with the same taxonomy.
|
219 |
- Fixed a little problem with edit skype button modal window - was too narrow.
|
@@ -224,16 +254,16 @@ https://wp-types.com/forums/topic/populate-select-field-in-wpcf-um-group/
|
|
224 |
- Updated CakePHP validation URL method to allow new TLD's.
|
225 |
|
226 |
## 1.4 (Feb 2 2015)
|
227 |
-
|
228 |
- Tagged for Views 1.7, Types 1.6.5, CRED 1.3.5 and Layouts 1.0 beta1
|
229 |
- Updated Installer to 1.5
|
230 |
|
231 |
## 1.3.1 (Dec 16 2014)
|
232 |
-
|
233 |
- Tagged for Views 1.7 beta1 and Layouts 1.0 beta1
|
234 |
- Fixed issue about Editor addon and ACF compatibility
|
235 |
- Fixed issue about branding loader
|
236 |
|
237 |
## 1.3 (Dec 15 2014)
|
238 |
-
|
239 |
- Tagged for Views 1.7 beta1 and Layouts 1.0 beta1
|
1 |
# Toolset Common Library
|
2 |
|
3 |
+
## 2.6.2
|
4 |
+
* Various minor bugfixes.
|
5 |
+
* (toolsetcommon-290) First version of the public relationship API for both legacy and m2m relationships.
|
6 |
+
* (types-1436) Removed a notice about Types becoming commercial if there's no Types 2.2.* version or below active.
|
7 |
+
|
8 |
+
## 2.6.1
|
9 |
+
* Fixed an issue regarding the Gutenberg integration with the extension of the Custom HTML block.
|
10 |
+
* Fixed a link to documentation about relationships and WPML.
|
11 |
+
* Removed a final keyword on some classes.
|
12 |
+
|
13 |
+
## 2.6.0
|
14 |
+
* Released with Types 2.3-b3, Views 2.6-b2 and CRED 2.0-b1
|
15 |
+
* Breaking change in the Toolset_Ajax implementation and subclassing mechanism.
|
16 |
+
|
17 |
+
## 2.5.10
|
18 |
+
* (toolsetcommon-315) Added a WHIP package warning about dropping the PHP 5.2 support.
|
19 |
+
* (toolsetcommon-361) Types custom fields can't be saved
|
20 |
+
* (toolsetcommon-334) Introduce a new, more flexible version of the association query class.
|
21 |
+
* (toolsetcommon-345) Delete the intermediary post when an association is deleted.
|
22 |
+
* (toolsetcommon-346, toolsetcommon-349, toolsetcommon-355, toolsetcommon-370, toolsetcommon-359) Heavy changes to the m2m API to bring WPML support.
|
23 |
+
* (toolsetcommon-368) Create intermediary posts even if there are no association fields
|
24 |
+
* (toolsetcommon-351) Make sure that the translation mode of a post type involved in a relationship cannot be changed
|
25 |
+
* (types-1376) Fixed: Post Type API does not update relationships when post type slug is changed.
|
26 |
+
* (types-1413) Fixed: Bug when creating an association with a translatable IPT in a non-default language.
|
27 |
+
|
28 |
+
## 2.5.9
|
29 |
+
* Released with Views 2.5.2, CRED 1.9.4 and Layouts 2.2
|
30 |
+
* (types-1339) Prevent PHP errors when offering to display data from a legacy Types relationship when the parent side post type no longer exists.
|
31 |
+
|
32 |
## 2.5.8
|
33 |
+
* New admin notice about Types becoming commercial.
|
34 |
+
* (toolsetcommon-339) Extend the relationship query with a mechanism to obtain the total number of found rows.
|
35 |
|
36 |
## 2.5.7
|
37 |
* (toolsetcommon-305) Improve the database structure for relationships and associations.
|
40 |
* Many improvements to the m2m API, especially to the relationship query.
|
41 |
* (toolsetcommon-328) Enforce cardinality limits when creating associations between two elements.
|
42 |
* (toolsetcommon-330) Prevent upgrade routines from running repeatedly. Fix a m2m activation issue.
|
43 |
+
* (toolsetcommon-249) The Toolset_Twig_Autoloader now bails out when it's possible to load the Twig_Environment class.
|
44 |
|
45 |
## 2.5.6
|
46 |
* Fixed a but that prevented CRED attributes offered as select2 instances from getting their values in the final shortcode.
|
122 |
- Only include the jQuery datepicker stylesheet on demand when the current page contains a datepicker from Toolset.
|
123 |
- Include the user editors in the common bootstrap class.
|
124 |
- toolsetcommon-127, toolsetcommon-55: Include knockout.js
|
125 |
+
- toolsetcommon-139: Clean up Toolset_Assets_Manager and define constants for asset handles
|
126 |
- toolsetcommon-144: Added Toolset_Admin_Notices_Manager
|
127 |
- toolsetcommon-137: Make the toolset-forms classes autoloaded.
|
128 |
- toolsetcommon-72: Implemented a classmap-based autoloader for all Toolset plugins.
|
135 |
|
136 |
## 2.2.9
|
137 |
|
138 |
+
- Fix a validation issue for file, audio, video and embed fields affecting Types.
|
139 |
Allow URLs with non-latin characters, but only for URLs that point to attachments
|
140 |
from the Media Library (validated by WordPress media upload mechanism) (types-1013).
|
141 |
- Improve the validation for non-required Skype fields (toolsetcommon-128).
|
148 |
- Extend WPToolset_Cake_Validation with the "url2" validation as a counterpart to the validation method in JQuery UI (types-988).
|
149 |
|
150 |
## 2.2.5 (November 5, 2016)
|
151 |
+
|
152 |
- Thorough check for security vulnerabilities.
|
153 |
|
154 |
## 2.2.4 (November 2, 2016)
|
170 |
- Added an internal Toolset compatibility class
|
171 |
|
172 |
## 2.2.1 (August 25, 2016)
|
173 |
+
|
174 |
- Avoid translating the Toolset top level admin menu label
|
175 |
+
|
176 |
## 2.2 (August 24, 2016)
|
177 |
|
178 |
- Added compatibility classes for Relevanssi and Beaver Builder
|
198 |
- Fixed various bugs
|
199 |
|
200 |
## 1.9.2 (March 17, 2016)
|
201 |
+
|
202 |
- Fixed issue in validation messages on Amazon S3
|
203 |
|
204 |
## 1.9.1 (March 15, 2016)
|
205 |
+
|
206 |
- Added control to filter array to prevent exceptions
|
207 |
- Prevented error when object does not have property or key is not set in array filter callback
|
208 |
- Fixed glitch in validation library
|
210 |
- Fixed search terms with language translation
|
211 |
|
212 |
## 1.9 (February 15, 2016)
|
213 |
+
|
214 |
- Tagged for Types 1.9, Views 1.12, CRED 1.5, Layouts 1.5 and Access 1.2.8
|
215 |
- Updated parser.php constructors for PHP7 compatibility.
|
216 |
- Updated the adodb time library for PHP7 compatibility.
|
218 |
- New utils.
|
219 |
|
220 |
## 1.8 (November 10, 2015)
|
221 |
+
|
222 |
- Tagged for Views 1.11.1, Types 1.8.9 and CRED 1.4.2
|
223 |
- Improved the media manager script.
|
224 |
- Added helper functions for dealing with $_GET, $_POST and arrays.
|
227 |
- Improved usermeta fields management in CRED forms.
|
228 |
|
229 |
## 1.7 (October 30, 2015)
|
230 |
+
|
231 |
- Tagged for Views 1.11 and Layouts 1.4
|
232 |
|
233 |
## 1.6.2 (September 25, 2015)
|
234 |
+
|
235 |
- Tagged for CRED 1.4, Types 1.8.2
|
236 |
|
237 |
## 1.6.1 (August 17, 2015)
|
238 |
+
|
239 |
- Tagged for Composer Types 1.8, Views 1.10, CRED 1.4 and Layouts 1.3
|
240 |
|
241 |
## 1.6 (June 11, 2015)
|
242 |
+
|
243 |
- Tagged for Types 1.7, Views 1.9 and Layouts 1.2
|
244 |
|
245 |
## 1.5 (Apr 1, 2015)
|
246 |
+
|
247 |
- Tagged for Types 1.6.6, Views 1.8, CRED 1.3.6 and Layouts 1.1.
|
248 |
- Fixed issue when there is more than one CRED form on a page with the same taxonomy.
|
249 |
- Fixed a little problem with edit skype button modal window - was too narrow.
|
254 |
- Updated CakePHP validation URL method to allow new TLD's.
|
255 |
|
256 |
## 1.4 (Feb 2 2015)
|
257 |
+
|
258 |
- Tagged for Views 1.7, Types 1.6.5, CRED 1.3.5 and Layouts 1.0 beta1
|
259 |
- Updated Installer to 1.5
|
260 |
|
261 |
## 1.3.1 (Dec 16 2014)
|
262 |
+
|
263 |
- Tagged for Views 1.7 beta1 and Layouts 1.0 beta1
|
264 |
- Fixed issue about Editor addon and ACF compatibility
|
265 |
- Fixed issue about branding loader
|
266 |
|
267 |
## 1.3 (Dec 15 2014)
|
268 |
+
|
269 |
- Tagged for Views 1.7 beta1 and Layouts 1.0 beta1
|
vendor/toolset/toolset-common/debug/main.js
CHANGED
@@ -76,9 +76,9 @@ Toolset.Gui.TroubleshootingPage = function($) {
|
|
76 |
vm.buttonClass = ko.pureComputed(function() {
|
77 |
if(vm.canProceed()) {
|
78 |
if(vm.isDangerous) {
|
79 |
-
return 'button-primary toolset-red-button';
|
80 |
} else {
|
81 |
-
return '
|
82 |
}
|
83 |
} else {
|
84 |
return 'button-secondary';
|
@@ -91,7 +91,7 @@ Toolset.Gui.TroubleshootingPage = function($) {
|
|
91 |
|
92 |
|
93 |
vm.isOutputEmpty = ko.computed(function() {
|
94 |
-
return (0
|
95 |
});
|
96 |
|
97 |
|
@@ -194,6 +194,7 @@ Toolset.Gui.TroubleshootingPage = function($) {
|
|
194 |
success: function (originalResponse) {
|
195 |
var response = WPV_Toolset.Utils.Ajax.parseResponse(originalResponse);
|
196 |
|
|
|
197 |
self.debug('AJAX response', actionData, originalResponse);
|
198 |
|
199 |
if (response.success) {
|
76 |
vm.buttonClass = ko.pureComputed(function() {
|
77 |
if(vm.canProceed()) {
|
78 |
if(vm.isDangerous) {
|
79 |
+
return 'button button-primary toolset-red-button';
|
80 |
} else {
|
81 |
+
return 'button button-primary';
|
82 |
}
|
83 |
} else {
|
84 |
return 'button-secondary';
|
91 |
|
92 |
|
93 |
vm.isOutputEmpty = ko.computed(function() {
|
94 |
+
return (0 === vm.output().length);
|
95 |
});
|
96 |
|
97 |
|
194 |
success: function (originalResponse) {
|
195 |
var response = WPV_Toolset.Utils.Ajax.parseResponse(originalResponse);
|
196 |
|
197 |
+
// noinspection JSUnusedAssignment
|
198 |
self.debug('AJAX response', actionData, originalResponse);
|
199 |
|
200 |
if (response.success) {
|
vendor/toolset/toolset-common/debug/main.twig
CHANGED
@@ -51,10 +51,9 @@
|
|
51 |
</label>
|
52 |
</p>
|
53 |
|
54 |
-
<span class="spinner"
|
55 |
|
56 |
-
<button
|
57 |
-
data-bind="
|
58 |
text: buttonLabel,
|
59 |
enable: canProceed,
|
60 |
attr: { class: buttonClass() },
|
51 |
</label>
|
52 |
</p>
|
53 |
|
54 |
+
<span class="spinner" data-bind="style: { visibility: (isInProgress() ? 'visible' : 'hidden') }"></span>
|
55 |
|
56 |
+
<button data-bind="
|
|
|
57 |
text: buttonLabel,
|
58 |
enable: canProceed,
|
59 |
attr: { class: buttonClass() },
|
vendor/toolset/toolset-common/functions.php
DELETED
@@ -1,9 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
_doing_it_wrong(
|
4 |
-
'toolset-common/functions.php',
|
5 |
-
'The file functions.php in Toolset Common is deprecated and will be removed before next release. The functions are now defined in another file that\'s being automatically loaded by Toolset_Common_Bootstrap. Please stop including this file!',
|
6 |
-
'Toolset Common Library 2.1'
|
7 |
-
);
|
8 |
-
|
9 |
-
require_once dirname( __FILE__ ) . '/inc/toolset.function.helpers.php';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/toolset/toolset-common/inc/autoloaded/admin.php
ADDED
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Main controller for Toolset Common tasks in the backend.
|
5 |
+
*
|
6 |
+
* This class has to be loaded only after the autoloader is initialized.
|
7 |
+
*
|
8 |
+
* @since 2.5.7
|
9 |
+
*/
|
10 |
+
class Toolset_Admin_Controller {
|
11 |
+
|
12 |
+
|
13 |
+
public function initialize() {
|
14 |
+
$this->load_whip();
|
15 |
+
}
|
16 |
+
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Show a customized WHIP notice for PHP 5.2 users.
|
20 |
+
*/
|
21 |
+
private function load_whip() {
|
22 |
+
if ( 'index.php' !== $GLOBALS['pagenow'] && current_user_can( 'manage_options' ) ) {
|
23 |
+
return;
|
24 |
+
}
|
25 |
+
|
26 |
+
require_once TOOLSET_COMMON_PATH . '/lib/whip/src/facades/wordpress.php';
|
27 |
+
|
28 |
+
add_filter( 'whip_hosting_page_url_wordpress', '__return_true' );
|
29 |
+
whip_wp_check_versions( array( 'php' => '>=5.3' ) );
|
30 |
+
}
|
31 |
+
|
32 |
+
}
|
vendor/toolset/toolset-common/inc/{controller → autoloaded}/admin/notices.php
RENAMED
@@ -357,6 +357,11 @@ class Toolset_Controller_Admin_Notices {
|
|
357 |
return false;
|
358 |
}
|
359 |
|
|
|
|
|
|
|
|
|
|
|
360 |
$notice = new Toolset_Admin_Notice_Dismissible( 'types_free_version_support_ends', '', $this->constants );
|
361 |
$notice->set_content( $this->tpl_path . '/types-free-version-ends.phtml' );
|
362 |
Toolset_Admin_Notices_Manager::add_notice( $notice );
|
@@ -492,4 +497,4 @@ class Toolset_Controller_Admin_Notices {
|
|
492 |
Toolset_Admin_Notices_Manager::add_notice( $notice );
|
493 |
}
|
494 |
|
495 |
-
}
|
357 |
return false;
|
358 |
}
|
359 |
|
360 |
+
$is_m2m_ready = new Toolset_Condition_Plugin_Types_Ready_For_M2M();
|
361 |
+
if ( $is_m2m_ready->is_met() ) {
|
362 |
+
return false;
|
363 |
+
}
|
364 |
+
|
365 |
$notice = new Toolset_Admin_Notice_Dismissible( 'types_free_version_support_ends', '', $this->constants );
|
366 |
$notice->set_content( $this->tpl_path . '/types-free-version-ends.phtml' );
|
367 |
Toolset_Admin_Notices_Manager::add_notice( $notice );
|
497 |
Toolset_Admin_Notices_Manager::add_notice( $notice );
|
498 |
}
|
499 |
|
500 |
+
}
|
vendor/toolset/toolset-common/inc/autoloaded/ajax_handler/get_ct_block_preview.php
ADDED
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Handles AJAX calls to get the Content Template block preview.
|
5 |
+
*
|
6 |
+
* @since m2m
|
7 |
+
*/
|
8 |
+
class Toolset_Ajax_Handler_Get_Content_Template_Block_Preview extends Toolset_Ajax_Handler_Abstract {
|
9 |
+
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @param array $arguments Original action arguments.
|
13 |
+
*
|
14 |
+
* @return void
|
15 |
+
*/
|
16 |
+
function process_call( $arguments ) {
|
17 |
+
|
18 |
+
$this->ajax_begin(
|
19 |
+
array(
|
20 |
+
'nonce' => Toolset_Ajax::CALLBACK_GET_CONTENT_TEMPLATE_BLOCK_PREVIEW,
|
21 |
+
'is_public' => false,
|
22 |
+
)
|
23 |
+
);
|
24 |
+
|
25 |
+
$ct_post_name = sanitize_text_field( toolset_getpost( 'ct_post_name', '' ) );
|
26 |
+
|
27 |
+
if ( empty( $ct_post_name ) ) {
|
28 |
+
$this->ajax_finish( array( 'message' => __( 'Content Template not set.', 'wpv-views' ) ), false );
|
29 |
+
}
|
30 |
+
|
31 |
+
$args = array(
|
32 |
+
'name' => $ct_post_name,
|
33 |
+
'posts_per_page' => 1,
|
34 |
+
'post_type' => 'view-template',
|
35 |
+
'post_status' => 'publish',
|
36 |
+
);
|
37 |
+
|
38 |
+
$ct = get_posts( $args );
|
39 |
+
|
40 |
+
if (
|
41 |
+
null !== $ct
|
42 |
+
&& count( $ct ) == 1
|
43 |
+
) {
|
44 |
+
$ct_post_content = str_replace( "\t", ' ', str_replace( "\n", '<br />', $ct[0]->post_content ) );
|
45 |
+
$this->ajax_finish( $ct_post_content, true );
|
46 |
+
}
|
47 |
+
|
48 |
+
$this->ajax_finish( array( 'message' => sprintf( __( 'Error while retrieving the Content Template preview. The selected Content Template (Slug: "%s") was not found.', 'wpv-views' ), $ct_post_name ) ), false );
|
49 |
+
}
|
50 |
+
}
|
vendor/toolset/toolset-common/inc/autoloaded/ajax_handler/get_post_by_id.php
ADDED
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Handles AJAX calls to get a post title by its ID.
|
5 |
+
*
|
6 |
+
* @since m2m
|
7 |
+
*/
|
8 |
+
class Toolset_Ajax_Handler_Get_Post_By_Id extends Toolset_Ajax_Handler_Abstract {
|
9 |
+
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @param array $arguments Original action arguments.
|
13 |
+
*
|
14 |
+
* @return void
|
15 |
+
*/
|
16 |
+
function process_call( $arguments ) {
|
17 |
+
|
18 |
+
$this->ajax_begin(
|
19 |
+
array(
|
20 |
+
'nonce' => Toolset_Ajax::CALLBACK_GET_POST_BY_ID,
|
21 |
+
'is_public' => true
|
22 |
+
)
|
23 |
+
);
|
24 |
+
|
25 |
+
// Read and validate input
|
26 |
+
$s = toolset_getpost( 's' );
|
27 |
+
|
28 |
+
|
29 |
+
if ( empty( $s ) ) {
|
30 |
+
$this->ajax_finish( array( 'message' => __( 'Wrong or missing query.', 'wpv-views' ) ), false );
|
31 |
+
}
|
32 |
+
|
33 |
+
global $wpdb;
|
34 |
+
|
35 |
+
$result = $wpdb->get_var(
|
36 |
+
$wpdb->prepare(
|
37 |
+
"SELECT post_title
|
38 |
+
FROM {$wpdb->posts}
|
39 |
+
WHERE ID = %d
|
40 |
+
LIMIT 1",
|
41 |
+
$s
|
42 |
+
)
|
43 |
+
);
|
44 |
+
|
45 |
+
if ( isset( $result ) ) {
|
46 |
+
$output = array( 'label' => $result );
|
47 |
+
$this->ajax_finish( $output, true );
|
48 |
+
}
|
49 |
+
|
50 |
+
$this->ajax_finish( array( 'message' => __( 'Error while retrieving result.', 'wpv-views' ) ), false );
|
51 |
+
|
52 |
+
}
|
53 |
+
|
54 |
+
}
|
vendor/toolset/toolset-common/inc/autoloaded/ajax_handler/get_term_by_id.php
ADDED
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Handles AJAX calls to get a term name by its ID.
|
5 |
+
*
|
6 |
+
* @since m2m
|
7 |
+
*/
|
8 |
+
class Toolset_Ajax_Handler_Get_Term_By_Id extends Toolset_Ajax_Handler_Abstract {
|
9 |
+
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @param array $arguments Original action arguments.
|
13 |
+
*
|
14 |
+
* @return void
|
15 |
+
*/
|
16 |
+
function process_call( $arguments ) {
|
17 |
+
|
18 |
+
$this->ajax_begin(
|
19 |
+
array(
|
20 |
+
'nonce' => Toolset_Ajax::CALLBACK_GET_TERM_BY_ID,
|
21 |
+
'is_public' => true
|
22 |
+
)
|
23 |
+
);
|
24 |
+
|
25 |
+
// Read and validate input
|
26 |
+
$s = toolset_getpost( 's' );
|
27 |
+
|
28 |
+
|
29 |
+
if ( empty( $s ) ) {
|
30 |
+
$this->ajax_finish( array( 'message' => __( 'Wrong or missing query.', 'wpv-views' ) ), false );
|
31 |
+
}
|
32 |
+
|
33 |
+
global $wpdb;
|
34 |
+
|
35 |
+
$result = $wpdb->get_var(
|
36 |
+
$wpdb->prepare(
|
37 |
+
"SELECT name
|
38 |
+
FROM {$wpdb->terms}
|
39 |
+
WHERE term_id = %d
|
40 |
+
LIMIT 1",
|
41 |
+
$s
|
42 |
+
)
|
43 |
+
);
|
44 |
+
|
45 |
+
if ( isset( $result ) ) {
|
46 |
+
$output = array( 'label' => $result );
|
47 |
+
$this->ajax_finish( $output, true );
|
48 |
+
}
|
49 |
+
|
50 |
+
$this->ajax_finish( array( 'message' => __( 'Error while retrieving result.', 'wpv-views' ) ), false );
|
51 |
+
|
52 |
+
}
|
53 |
+
|
54 |
+
}
|
vendor/toolset/toolset-common/inc/autoloaded/ajax_handler/get_user_by_id.php
ADDED
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Handles AJAX calls to get an user display name by its ID.
|
5 |
+
*
|
6 |
+
* @since m2m
|
7 |
+
*/
|
8 |
+
class Toolset_Ajax_Handler_Get_User_By_Id extends Toolset_Ajax_Handler_Abstract {
|
9 |
+
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @param array $arguments Original action arguments.
|
13 |
+
*
|
14 |
+
* @return void
|
15 |
+
*/
|
16 |
+
function process_call( $arguments ) {
|
17 |
+
|
18 |
+
$this->ajax_begin(
|
19 |
+
array(
|
20 |
+
'nonce' => Toolset_Ajax::CALLBACK_GET_USER_BY_ID,
|
21 |
+
'is_public' => true
|
22 |
+
)
|
23 |
+
);
|
24 |
+
|
25 |
+
// Read and validate input
|
26 |
+
$s = toolset_getpost( 's' );
|
27 |
+
|
28 |
+
|
29 |
+
if ( empty( $s ) ) {
|
30 |
+
$this->ajax_finish( array( 'message' => __( 'Wrong or missing query.', 'wpv-views' ) ), false );
|
31 |
+
}
|
32 |
+
|
33 |
+
global $wpdb;
|
34 |
+
|
35 |
+
$result = $wpdb->get_var(
|
36 |
+
$wpdb->prepare(
|
37 |
+
"SELECT display_name
|
38 |
+
FROM {$wpdb->users}
|
39 |
+
WHERE ID = %d
|
40 |
+
LIMIT 1",
|
41 |
+
$s
|
42 |
+
)
|
43 |
+
);
|
44 |
+
|
45 |
+
if ( isset( $result ) ) {
|
46 |
+
$output = array( 'label' => $result );
|
47 |
+
$this->ajax_finish( $output, true );
|
48 |
+
}
|
49 |
+
|
50 |
+
$this->ajax_finish( array( 'message' => __( 'Error while retrieving result.', 'wpv-views' ) ), false );
|
51 |
+
|
52 |
+
}
|
53 |
+
|
54 |
+
}
|
vendor/toolset/toolset-common/inc/autoloaded/ajax_handler/get_view_block_preview.php
ADDED
@@ -0,0 +1,142 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Handles AJAX calls to get the view block preview.
|
5 |
+
*
|
6 |
+
* @since m2m
|
7 |
+
*/
|
8 |
+
class Toolset_Ajax_Handler_Get_View_Block_Preview extends Toolset_Ajax_Handler_Abstract {
|
9 |
+
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @param array $arguments Original action arguments.
|
13 |
+
*
|
14 |
+
* @return void
|
15 |
+
*/
|
16 |
+
function process_call( $arguments ) {
|
17 |
+
|
18 |
+
$this->ajax_begin(
|
19 |
+
array(
|
20 |
+
'nonce' => Toolset_Ajax::CALLBACK_GET_VIEW_BLOCK_PREVIEW,
|
21 |
+
'is_public' => false,
|
22 |
+
)
|
23 |
+
);
|
24 |
+
|
25 |
+
$view_id = isset( $_POST['view_id'] ) ? sanitize_text_field( $_POST['view_id'] ) : '';
|
26 |
+
|
27 |
+
if ( empty( $view_id ) ) {
|
28 |
+
$this->ajax_finish( array( 'message' => __( 'View ID not set.', 'wpv-views' ) ), false );
|
29 |
+
}
|
30 |
+
|
31 |
+
global $WP_Views;
|
32 |
+
|
33 |
+
$view = WPV_View_Base::get_instance( $view_id );
|
34 |
+
if ( null !== $view ) {
|
35 |
+
$limit = sanitize_text_field( toolset_getpost( 'limit', -1 ) );
|
36 |
+
$offset = sanitize_text_field( toolset_getpost( 'offset', 0 ) );
|
37 |
+
$orderby = sanitize_text_field( toolset_getpost( 'orderby', '' ) );
|
38 |
+
$order = sanitize_text_field( toolset_getpost( 'order', '' ) );
|
39 |
+
$secondary_order_by = sanitize_text_field( toolset_getpost( 'secondaryOrderby', '' ) );
|
40 |
+
$secondary_order = sanitize_text_field( toolset_getpost( 'secondaryOrder', '' ) );
|
41 |
+
|
42 |
+
//$view_settings = apply_filters( 'wpv_filter_wpv_get_view_settings', array(), $view_id );
|
43 |
+
$view_settings = null !== $view ? $view->view_settings : null;
|
44 |
+
//$view_meta = apply_filters( 'wpv_filter_wpv_get_view_layout_settings', array(), $view_id );
|
45 |
+
$view_meta = null !== $view ? $view->loop_settings : null;
|
46 |
+
|
47 |
+
$has_parametric_search = $WP_Views->does_view_have_form_controls( $view_id );
|
48 |
+
$has_submit = false;
|
49 |
+
$has_extra_attributes = get_view_allowed_attributes( $view_id );
|
50 |
+
|
51 |
+
if ( isset( $view_settings['filter_meta_html'] ) ) {
|
52 |
+
$filter_meta_html = $view_settings['filter_meta_html'];
|
53 |
+
|
54 |
+
if ( strpos( $filter_meta_html, '[wpv-filter-submit' ) !== false ) {
|
55 |
+
$has_submit = true;
|
56 |
+
}
|
57 |
+
}
|
58 |
+
|
59 |
+
$view_purpose = '';
|
60 |
+
|
61 |
+
if ( $view->is_a_view() ) {
|
62 |
+
$view_output = get_view_query_results(
|
63 |
+
$view_id,
|
64 |
+
null,
|
65 |
+
null,
|
66 |
+
array(
|
67 |
+
'limit' => $limit,
|
68 |
+
'offset' => $offset,
|
69 |
+
'orderby' => $orderby,
|
70 |
+
'order' => $order,
|
71 |
+
'orderby_second' => $secondary_order_by,
|
72 |
+
'order_second' => $secondary_order,
|
73 |
+
)
|
74 |
+
);
|
75 |
+
if ( ! isset( $view_settings['view_purpose'] ) ) {
|
76 |
+
$view_settings['view_purpose'] = 'full';
|
77 |
+
}
|
78 |
+
switch ( $view_settings['view_purpose'] ) {
|
79 |
+
case 'all':
|
80 |
+
$view_purpose = __( 'Display all results', 'wpv-views' );
|
81 |
+
break;
|
82 |
+
|
83 |
+
case 'pagination':
|
84 |
+
$view_purpose = __( 'Display the results with pagination', 'wpv-views' );
|
85 |
+
break;
|
86 |
+
|
87 |
+
case 'slider':
|
88 |
+
$view_purpose = __( 'Display the results as a slider', 'wpv-views' );
|
89 |
+
break;
|
90 |
+
|
91 |
+
case 'parametric':
|
92 |
+
$view_purpose = __( 'Custom search', 'wpv-views' );
|
93 |
+
break;
|
94 |
+
case 'full':
|
95 |
+
$view_purpose = __( 'Displays a fully customized display', 'wpv-views' );
|
96 |
+
break;
|
97 |
+
}
|
98 |
+
} else {
|
99 |
+
$view_output = array();
|
100 |
+
|
101 |
+
if (
|
102 |
+
'bootstrap-grid' === $view_meta['style']
|
103 |
+
|| 'table' === $view_meta['style']
|
104 |
+
) {
|
105 |
+
if ( 'bootstrap-grid' === $view_meta['style'] ) {
|
106 |
+
$col_number = $view_meta['bootstrap_grid_cols'];
|
107 |
+
} else {
|
108 |
+
$col_number = $view_meta['table_cols'];
|
109 |
+
}
|
110 |
+
|
111 |
+
// add 2 rows of items.
|
112 |
+
for ( $i = 1; $i <= 2 * $col_number; $i++ ) {
|
113 |
+
$item = new stdClass();
|
114 |
+
$item->post_title = sprintf( __( 'Post %d', 'wp-views' ), $i );
|
115 |
+
$view_output[] = $item;
|
116 |
+
}
|
117 |
+
} else {
|
118 |
+
// just add 3 items
|
119 |
+
for ( $i = 1; $i <= 3; $i++ ) {
|
120 |
+
$item = new stdClass();
|
121 |
+
$item->post_title = sprintf( __( 'Post %d', 'wp-views' ), $i );
|
122 |
+
$view_output[] = $item;
|
123 |
+
}
|
124 |
+
}
|
125 |
+
}
|
126 |
+
|
127 |
+
$output = array(
|
128 |
+
'view_title' => null !== $view ? $view->title : '',
|
129 |
+
'view_purpose' => $view_purpose,
|
130 |
+
'view_meta' => $view_meta,
|
131 |
+
'view_output' => $view_output,
|
132 |
+
'hasCustomSearch' => $has_parametric_search,
|
133 |
+
'hasSubmit' => $has_submit,
|
134 |
+
'hasExtraAttributes' => $has_extra_attributes,
|
135 |
+
);
|
136 |
+
|
137 |
+
$this->ajax_finish( $output, true );
|
138 |
+
}
|
139 |
+
|
140 |
+
$this->ajax_finish( array( 'message' => sprintf( __( 'Error while retrieving the View preview. The selected View (ID: %s) was not found.', 'wpv-views' ), $view_id ) ), false );
|
141 |
+
}
|
142 |
+
}
|
vendor/toolset/toolset-common/inc/autoloaded/ajax_handler/intermediary_post_cleanup.php
ADDED
@@ -0,0 +1,85 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Handles an AJAX call coming from the Troubleshooting page that is supposed to clean all the dangling intermediary
|
5 |
+
* posts.
|
6 |
+
*
|
7 |
+
* Continues until there are no posts left to delete.
|
8 |
+
*
|
9 |
+
* See Toolset_Association_Cleanup_Dangling_Intermediary_Posts for details.
|
10 |
+
*
|
11 |
+
* @since 2.5.10
|
12 |
+
*/
|
13 |
+
class Toolset_Ajax_Handler_Intermediary_Post_Cleanup extends Toolset_Ajax_Handler_Abstract {
|
14 |
+
|
15 |
+
|
16 |
+
/** @var Toolset_Association_Cleanup_Factory */
|
17 |
+
private $cleanup_factory;
|
18 |
+
|
19 |
+
|
20 |
+
/** @var Toolset_Cron */
|
21 |
+
private $cron;
|
22 |
+
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Toolset_Ajax_Handler_Intermediary_Post_Cleanup constructor.
|
26 |
+
*
|
27 |
+
* @param Toolset_Ajax $ajax_manager
|
28 |
+
* @param Toolset_Association_Cleanup_Factory|null $cleanup_factory_di
|
29 |
+
* @param Toolset_Cron|null $cron_di
|
30 |
+
*/
|
31 |
+
public function __construct(
|
32 |
+
Toolset_Ajax $ajax_manager,
|
33 |
+
Toolset_Association_Cleanup_Factory $cleanup_factory_di = null,
|
34 |
+
Toolset_Cron $cron_di = null
|
35 |
+
) {
|
36 |
+
parent::__construct( $ajax_manager );
|
37 |
+
|
38 |
+
$this->cleanup_factory = $cleanup_factory_di ?: new Toolset_Association_Cleanup_Factory();
|
39 |
+
$this->cron = $cron_di ?: Toolset_Cron::get_instance();
|
40 |
+
}
|
41 |
+
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Processes the Ajax call
|
45 |
+
*
|
46 |
+
* @param array $arguments Original action arguments.
|
47 |
+
*
|
48 |
+
* @return void
|
49 |
+
*/
|
50 |
+
function process_call( $arguments ) {
|
51 |
+
$this->ajax_begin( array( 'nonce' => Toolset_Ajax::CALLBACK_INTERMEDIARY_POST_CLEANUP ) );
|
52 |
+
|
53 |
+
$current_step = (int) toolset_getpost( 'current_step' );
|
54 |
+
$cleanup = $this->cleanup_factory->dangling_intermediary_posts();
|
55 |
+
$cleanup->do_batch();
|
56 |
+
|
57 |
+
$number_of_deleted_posts = $cleanup->get_deleted_posts();
|
58 |
+
|
59 |
+
// This will consequently hide the admin notice about dangling intermediary posts needing to be deleted.
|
60 |
+
if( ! $cleanup->has_remaining_posts() ) {
|
61 |
+
$event = $this->cleanup_factory->cron_event();
|
62 |
+
$this->cron->unschedule_event( $event );
|
63 |
+
}
|
64 |
+
|
65 |
+
$message = sprintf(
|
66 |
+
(
|
67 |
+
$cleanup->has_remaining_posts()
|
68 |
+
? __( 'Deleted %d dangling intermediary posts...', 'wpcf' )
|
69 |
+
: __( 'Deleted %d dangling intermediary posts. Operation completed.', 'wpcf' )
|
70 |
+
),
|
71 |
+
$number_of_deleted_posts
|
72 |
+
);
|
73 |
+
|
74 |
+
$this->ajax_finish(
|
75 |
+
array(
|
76 |
+
'continue' => $cleanup->has_remaining_posts(),
|
77 |
+
'message' => $message,
|
78 |
+
'ajax_arguments' => array(
|
79 |
+
'current_step' => $current_step + 1
|
80 |
+
)
|
81 |
+
)
|
82 |
+
);
|
83 |
+
}
|
84 |
+
|
85 |
+
}
|
vendor/toolset/toolset-common/inc/autoloaded/ajax_handler/migrate_to_m2m.php
CHANGED
@@ -26,14 +26,21 @@ class Toolset_Ajax_Handler_Migrate_To_M2M extends Toolset_Ajax_Handler_Abstract
|
|
26 |
/** @var Toolset_Relationship_Controller */
|
27 |
private $relationship_controller;
|
28 |
|
29 |
-
/** @var null|
|
30 |
private $migration_controller;
|
31 |
|
32 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
33 |
public function __construct(
|
34 |
$ajax_manager,
|
35 |
Toolset_Relationship_Controller $di_relationship_controller = null,
|
36 |
-
|
37 |
) {
|
38 |
parent::__construct( $ajax_manager );
|
39 |
|
@@ -49,7 +56,7 @@ class Toolset_Ajax_Handler_Migrate_To_M2M extends Toolset_Ajax_Handler_Abstract
|
|
49 |
|
50 |
private function get_migration_controller() {
|
51 |
if( null === $this->migration_controller ) {
|
52 |
-
$this->migration_controller = new
|
53 |
}
|
54 |
return $this->migration_controller;
|
55 |
}
|
@@ -73,6 +80,7 @@ class Toolset_Ajax_Handler_Migrate_To_M2M extends Toolset_Ajax_Handler_Abstract
|
|
73 |
$migration_controller = $this->get_migration_controller();
|
74 |
|
75 |
$step_number = (int) toolset_getarr( $_POST, 'step', 0 );
|
|
|
76 |
|
77 |
// If this is set to false, the migration process halts (there will not be another AJAX call)
|
78 |
$continue = true;
|
@@ -100,11 +108,9 @@ class Toolset_Ajax_Handler_Migrate_To_M2M extends Toolset_Ajax_Handler_Abstract
|
|
100 |
switch ( $current_phase ) {
|
101 |
|
102 |
case self::PHASE_DBDELTA: {
|
103 |
-
|
104 |
$continue = $this->phase_dbdelta( $step_number , $migration_controller, $results, $next_phase );
|
105 |
-
|
106 |
-
|
107 |
-
}
|
108 |
|
109 |
case self::PHASE_DEFINITION_MIGRATION: {
|
110 |
// Second step - (re)create relationship definitions.
|
@@ -130,8 +136,15 @@ class Toolset_Ajax_Handler_Migrate_To_M2M extends Toolset_Ajax_Handler_Abstract
|
|
130 |
|
131 |
$migration_step = $step_number - $steps_before_association_migration;
|
132 |
$offset = $items_per_step * $migration_step;
|
|
|
|
|
133 |
|
134 |
-
$data_migration_result = $migration_controller->migrate_associations(
|
|
|
|
|
|
|
|
|
|
|
135 |
|
136 |
// Decide if we have to continue.
|
137 |
if ( $data_migration_result instanceof Toolset_Result_Updated
|
@@ -151,9 +164,6 @@ class Toolset_Ajax_Handler_Migrate_To_M2M extends Toolset_Ajax_Handler_Abstract
|
|
151 |
$next_phase = self::PHASE_FINISH;
|
152 |
}
|
153 |
|
154 |
-
} else {
|
155 |
-
// Fail or a result without count of updated items.
|
156 |
-
$results->add( $data_migration_result );
|
157 |
}
|
158 |
|
159 |
break;
|
@@ -172,14 +182,16 @@ class Toolset_Ajax_Handler_Migrate_To_M2M extends Toolset_Ajax_Handler_Abstract
|
|
172 |
|
173 |
$this->ajax_finish(
|
174 |
array(
|
175 |
-
'message' => $results->concat_messages( "\n" ),
|
176 |
'continue' => $continue,
|
177 |
'previous_phase' => $current_phase,
|
178 |
'is_complete_success' => $results->is_complete_success(),
|
179 |
'ajax_arguments' => array(
|
180 |
'step' => $step_number + 1,
|
181 |
'phase' => $next_phase,
|
182 |
-
'first_phase_step' => $steps_before_association_migration
|
|
|
|
|
183 |
)
|
184 |
),
|
185 |
true // the call is a success, it doesn't say anything about the actual operation
|
@@ -193,7 +205,7 @@ class Toolset_Ajax_Handler_Migrate_To_M2M extends Toolset_Ajax_Handler_Abstract
|
|
193 |
* This involves changing database structure.
|
194 |
*
|
195 |
* @param int $step_number Current step of this phase.
|
196 |
-
* @param
|
197 |
* @param Toolset_Result_Set $results
|
198 |
* @param int $next_phase The ID of the phase that should follow after this step. Must be set to current phase initially.
|
199 |
*
|
26 |
/** @var Toolset_Relationship_Controller */
|
27 |
private $relationship_controller;
|
28 |
|
29 |
+
/** @var null|Toolset_Relationship_Migration_Controller */
|
30 |
private $migration_controller;
|
31 |
|
32 |
|
33 |
+
/**
|
34 |
+
* Toolset_Ajax_Handler_Migrate_To_M2M constructor.
|
35 |
+
*
|
36 |
+
* @param Toolset_Ajax $ajax_manager
|
37 |
+
* @param Toolset_Relationship_Controller|null $di_relationship_controller
|
38 |
+
* @param Toolset_Relationship_Migration_Controller|null $di_migration_controller
|
39 |
+
*/
|
40 |
public function __construct(
|
41 |
$ajax_manager,
|
42 |
Toolset_Relationship_Controller $di_relationship_controller = null,
|
43 |
+
Toolset_Relationship_Migration_Controller $di_migration_controller = null
|
44 |
) {
|
45 |
parent::__construct( $ajax_manager );
|
46 |
|
56 |
|
57 |
private function get_migration_controller() {
|
58 |
if( null === $this->migration_controller ) {
|
59 |
+
$this->migration_controller = new Toolset_Relationship_Migration_Controller();
|
60 |
}
|
61 |
return $this->migration_controller;
|
62 |
}
|
80 |
$migration_controller = $this->get_migration_controller();
|
81 |
|
82 |
$step_number = (int) toolset_getarr( $_POST, 'step', 0 );
|
83 |
+
$options = toolset_ensarr( toolset_getarr( $_POST, 'options' ) );
|
84 |
|
85 |
// If this is set to false, the migration process halts (there will not be another AJAX call)
|
86 |
$continue = true;
|
108 |
switch ( $current_phase ) {
|
109 |
|
110 |
case self::PHASE_DBDELTA: {
|
|
|
111 |
$continue = $this->phase_dbdelta( $step_number , $migration_controller, $results, $next_phase );
|
112 |
+
break;
|
113 |
+
}
|
|
|
114 |
|
115 |
case self::PHASE_DEFINITION_MIGRATION: {
|
116 |
// Second step - (re)create relationship definitions.
|
136 |
|
137 |
$migration_step = $step_number - $steps_before_association_migration;
|
138 |
$offset = $items_per_step * $migration_step;
|
139 |
+
$create_default_language_if_missing = ( 'create' === toolset_getarr( $options, 'posts_without_default_translation' ) );
|
140 |
+
$copy_post_content_when_creating = (bool) toolset_getarr( $options, 'copy_content_when_creating_posts' );
|
141 |
|
142 |
+
$data_migration_result = $migration_controller->migrate_associations(
|
143 |
+
$offset, $items_per_step, $create_default_language_if_missing, $copy_post_content_when_creating
|
144 |
+
);
|
145 |
+
|
146 |
+
// Always add the original result, as it may contain additional information, even in case of success.
|
147 |
+
$results->add( $data_migration_result );
|
148 |
|
149 |
// Decide if we have to continue.
|
150 |
if ( $data_migration_result instanceof Toolset_Result_Updated
|
164 |
$next_phase = self::PHASE_FINISH;
|
165 |
}
|
166 |
|
|
|
|
|
|
|
167 |
}
|
168 |
|
169 |
break;
|
182 |
|
183 |
$this->ajax_finish(
|
184 |
array(
|
185 |
+
'message' => $results->concat_messages( "\n> " ),
|
186 |
'continue' => $continue,
|
187 |
'previous_phase' => $current_phase,
|
188 |
'is_complete_success' => $results->is_complete_success(),
|
189 |
'ajax_arguments' => array(
|
190 |
'step' => $step_number + 1,
|
191 |
'phase' => $next_phase,
|
192 |
+
'first_phase_step' => $steps_before_association_migration,
|
193 |
+
// pass the unchanged options so that they're available for all migration steps
|
194 |
+
'options' => $options
|
195 |
)
|
196 |
),
|
197 |
true // the call is a success, it doesn't say anything about the actual operation
|
205 |
* This involves changing database structure.
|
206 |
*
|
207 |
* @param int $step_number Current step of this phase.
|
208 |
+
* @param Toolset_Relationship_Migration_Controller $migration_controller
|
209 |
* @param Toolset_Result_Set $results
|
210 |
* @param int $next_phase The ID of the phase that should follow after this step. Must be set to current phase initially.
|
211 |
*
|
vendor/toolset/toolset-common/inc/autoloaded/ajax_handler/select2_suggest_posts_by_title.php
ADDED
@@ -0,0 +1,134 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Handles toolset_select2 instances that suggest post by title.
|
5 |
+
*
|
6 |
+
* If a given post type is not provided, it will return results in any post type but the excluded ones.
|
7 |
+
* If a return value among [ 'ID', 'post_name' ] is not provided, it will return result built upon post ID.
|
8 |
+
*
|
9 |
+
* @since m2m
|
10 |
+
*/
|
11 |
+
class Toolset_Ajax_Handler_Select2_Suggest_Posts_By_Title extends Toolset_Ajax_Handler_Abstract {
|
12 |
+
|
13 |
+
|
14 |
+
/**
|
15 |
+
* @param array $arguments Original action arguments.
|
16 |
+
*
|
17 |
+
* @return void
|
18 |
+
*/
|
19 |
+
function process_call( $arguments ) {
|
20 |
+
|
21 |
+
$this->ajax_begin(
|
22 |
+
array(
|
23 |
+
'nonce' => Toolset_Ajax::CALLBACK_SELECT2_SUGGEST_POSTS_BY_TITLE,
|
24 |
+
'is_public' => true
|
25 |
+
)
|
26 |
+
);
|
27 |
+
|
28 |
+
// Read and validate input
|
29 |
+
$s = toolset_getpost( 's' );
|
30 |
+
|
31 |
+
|
32 |
+
if ( empty( $s ) ) {
|
33 |
+
$this->ajax_finish( array( 'message' => __( 'Wrong or missing query.', 'wpv-views' ) ), false );
|
34 |
+
}
|
35 |
+
|
36 |
+
$return = toolset_getpost( 'valueType' );
|
37 |
+
$return = in_array( $return, array( 'ID', 'post_name' ) )
|
38 |
+
? $return
|
39 |
+
: 'ID';
|
40 |
+
|
41 |
+
global $wpdb;
|
42 |
+
$values_to_prepare = array();
|
43 |
+
|
44 |
+
if ( method_exists( $wpdb, 'esc_like' ) ) {
|
45 |
+
$s = '%' . $wpdb->esc_like( $s ) . '%';
|
46 |
+
} else {
|
47 |
+
$s = '%' . like_escape( esc_sql( $s ) ) . '%';
|
48 |
+
}
|
49 |
+
|
50 |
+
$values_to_prepare[] = $s;
|
51 |
+
|
52 |
+
$post_type_query = '';
|
53 |
+
$force_post_type = toolset_getpost( 'postType' );
|
54 |
+
if ( empty( $force_post_type ) ) {
|
55 |
+
$toolset_post_type_exclude = new Toolset_Post_Type_Exclude_List();
|
56 |
+
$toolset_post_type_exclude_list = $toolset_post_type_exclude->get();
|
57 |
+
$toolset_post_type_exclude_list_string = "'" . implode( "', '", $toolset_post_type_exclude_list ) . "'";
|
58 |
+
|
59 |
+
$post_type_query = "AND post_type NOT IN ( {$toolset_post_type_exclude_list_string} ) ";
|
60 |
+
} else {
|
61 |
+
$post_type_query = "AND post_type = %s ";
|
62 |
+
$values_to_prepare[] = $force_post_type;
|
63 |
+
}
|
64 |
+
|
65 |
+
$toolset_post_type_exclude = new Toolset_Post_Type_Exclude_List();
|
66 |
+
$toolset_post_type_exclude_list = $toolset_post_type_exclude->get();
|
67 |
+
$toolset_post_type_exclude_list_string = "'" . implode( "', '", $toolset_post_type_exclude_list ) . "'";
|
68 |
+
|
69 |
+
$results = $wpdb->get_results(
|
70 |
+
$wpdb->prepare(
|
71 |
+
"SELECT ID, post_type, post_title, post_name
|
72 |
+
FROM {$wpdb->posts}
|
73 |
+
WHERE post_title LIKE %s
|
74 |
+
AND post_status = 'publish'
|
75 |
+
{$post_type_query}
|
76 |
+
LIMIT 0, 15",
|
77 |
+
$values_to_prepare
|
78 |
+
)
|
79 |
+
);
|
80 |
+
|
81 |
+
|
82 |
+
if (
|
83 |
+
isset( $results )
|
84 |
+
&& ! empty( $results )
|
85 |
+
) {
|
86 |
+
|
87 |
+
$final = array();
|
88 |
+
|
89 |
+
if ( is_array( $results ) ) {
|
90 |
+
|
91 |
+
// create list of unique post types in result set
|
92 |
+
$selected_post_types = array_map( array( $this,'get_post_type' ), $results );
|
93 |
+
$unique_post_types = array_unique( $selected_post_types );
|
94 |
+
|
95 |
+
|
96 |
+
foreach ( $unique_post_types as $key => $post_type ) {
|
97 |
+
$post_type_details = get_post_type_object( $post_type );
|
98 |
+
$final[ $post_type ] = array(
|
99 |
+
'text' => $post_type_details->label,
|
100 |
+
'children' => array()
|
101 |
+
);
|
102 |
+
}
|
103 |
+
foreach ( $results as $result ) {
|
104 |
+
$final[ $result->post_type ]['children'][] = array(
|
105 |
+
'id' => $result->$return,
|
106 |
+
'text' => $result->post_title
|
107 |
+
);
|
108 |
+
}
|
109 |
+
|
110 |
+
$final = array_values( $final );
|
111 |
+
|
112 |
+
}
|
113 |
+
$this->ajax_finish( $final, true );
|
114 |
+
|
115 |
+
} else {
|
116 |
+
// return empty result set
|
117 |
+
$result = array();
|
118 |
+
$this->ajax_finish( $result, true );
|
119 |
+
}
|
120 |
+
|
121 |
+
$this->ajax_finish( array( 'message' => __( 'Error while retrieving result.', 'wpv-views' ) ), false );
|
122 |
+
|
123 |
+
}
|
124 |
+
|
125 |
+
/**
|
126 |
+
* Return only post type from post object, used for array_map
|
127 |
+
* @param $one_post
|
128 |
+
* @return string
|
129 |
+
*/
|
130 |
+
private function get_post_type( $one_post ){
|
131 |
+
return $one_post->post_type;
|
132 |
+
}
|
133 |
+
|
134 |
+
}
|
vendor/toolset/toolset-common/inc/autoloaded/ajax_handler/select2_suggest_terms.php
ADDED
@@ -0,0 +1,71 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Handles toolset_select2 instances that suggest terms.
|
5 |
+
*
|
6 |
+
* @since m2m
|
7 |
+
*/
|
8 |
+
class Toolset_Ajax_Handler_Select2_Suggest_Terms extends Toolset_Ajax_Handler_Abstract {
|
9 |
+
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @param array $arguments Original action arguments.
|
13 |
+
*
|
14 |
+
* @return void
|
15 |
+
*/
|
16 |
+
function process_call( $arguments ) {
|
17 |
+
|
18 |
+
$this->ajax_begin(
|
19 |
+
array(
|
20 |
+
'nonce' => Toolset_Ajax::CALLBACK_SELECT2_SUGGEST_TERMS,
|
21 |
+
'is_public' => true
|
22 |
+
)
|
23 |
+
);
|
24 |
+
|
25 |
+
// Read and validate input
|
26 |
+
$s = toolset_getpost( 's' );
|
27 |
+
|
28 |
+
|
29 |
+
if ( empty( $s ) ) {
|
30 |
+
$this->ajax_finish( array( 'message' => __( 'Wrong or missing query.', 'wpv-views' ) ), false );
|
31 |
+
}
|
32 |
+
|
33 |
+
global $wpdb;
|
34 |
+
|
35 |
+
if ( method_exists( $wpdb, 'esc_like' ) ) {
|
36 |
+
$s = '%' . $wpdb->esc_like( $s ) . '%';
|
37 |
+
} else {
|
38 |
+
$s = '%' . like_escape( esc_sql( $s ) ) . '%';
|
39 |
+
}
|
40 |
+
|
41 |
+
$results = $wpdb->get_results(
|
42 |
+
$wpdb->prepare(
|
43 |
+
"SELECT term_id, name
|
44 |
+
FROM {$wpdb->terms}
|
45 |
+
WHERE name LIKE %s
|
46 |
+
LIMIT 0, 15",
|
47 |
+
$s
|
48 |
+
)
|
49 |
+
);
|
50 |
+
|
51 |
+
if (
|
52 |
+
isset( $results )
|
53 |
+
&& ! empty( $results )
|
54 |
+
) {
|
55 |
+
$output = array();
|
56 |
+
if ( is_array( $results ) ) {
|
57 |
+
foreach ( $results as $result ) {
|
58 |
+
$output[] = array(
|
59 |
+
'text' => $result->name,
|
60 |
+
'id' => $result->term_id,
|
61 |
+
);
|
62 |
+
}
|
63 |
+
}
|
64 |
+
$this->ajax_finish( $output, true );
|
65 |
+
}
|
66 |
+
|
67 |
+
$this->ajax_finish( array( 'message' => __( 'Error while retrieving result.', 'wpv-views' ) ), false );
|
68 |
+
|
69 |
+
}
|
70 |
+
|
71 |
+
}
|
vendor/toolset/toolset-common/inc/autoloaded/ajax_handler/select2_suggest_users.php
ADDED
@@ -0,0 +1,75 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Handles toolset_select2 instances that suggest users.
|
5 |
+
*
|
6 |
+
* @since m2m
|
7 |
+
*/
|
8 |
+
class Toolset_Ajax_Handler_Select2_Suggest_Users extends Toolset_Ajax_Handler_Abstract {
|
9 |
+
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @param array $arguments Original action arguments.
|
13 |
+
*
|
14 |
+
* @return void
|
15 |
+
*/
|
16 |
+
function process_call( $arguments ) {
|
17 |
+
|
18 |
+
$this->ajax_begin(
|
19 |
+
array(
|
20 |
+
'nonce' => Toolset_Ajax::CALLBACK_SELECT2_SUGGEST_USERS,
|
21 |
+
'is_public' => true
|
22 |
+
)
|
23 |
+
);
|
24 |
+
|
25 |
+
// Read and validate input
|
26 |
+
$s = toolset_getpost( 's' );
|
27 |
+
|
28 |
+
|
29 |
+
if ( empty( $s ) ) {
|
30 |
+
$this->ajax_finish( array( 'message' => __( 'Wrong or missing query.', 'wpv-views' ) ), false );
|
31 |
+
}
|
32 |
+
|
33 |
+
global $wpdb;
|
34 |
+
|
35 |
+
if ( method_exists( $wpdb, 'esc_like' ) ) {
|
36 |
+
$s = '%' . $wpdb->esc_like( $s ) . '%';
|
37 |
+
} else {
|
38 |
+
$s = '%' . like_escape( esc_sql( $s ) ) . '%';
|
39 |
+
}
|
40 |
+
|
41 |
+
$results = $wpdb->get_results(
|
42 |
+
$wpdb->prepare(
|
43 |
+
"SELECT ID, display_name
|
44 |
+
FROM {$wpdb->users}
|
45 |
+
WHERE display_name LIKE %s
|
46 |
+
OR user_login LIKE %s
|
47 |
+
OR user_nicename LIKE %s
|
48 |
+
LIMIT 0, 15",
|
49 |
+
$s,
|
50 |
+
$s,
|
51 |
+
$s
|
52 |
+
)
|
53 |
+
);
|
54 |
+
|
55 |
+
if (
|
56 |
+
isset( $results )
|
57 |
+
&& ! empty( $results )
|
58 |
+
) {
|
59 |
+
$output = array();
|
60 |
+
if ( is_array( $results ) ) {
|
61 |
+
foreach ( $results as $result ) {
|
62 |
+
$output[] = array(
|
63 |
+
'text' => $result->display_name,
|
64 |
+
'id' => $result->ID,
|
65 |
+
);
|
66 |
+
}
|
67 |
+
}
|
68 |
+
$this->ajax_finish( $output, true );
|
69 |
+
}
|
70 |
+
|
71 |
+
$this->ajax_finish( array( 'message' => __( 'Error while retrieving result.', 'wpv-views' ) ), false );
|
72 |
+
|
73 |
+
}
|
74 |
+
|
75 |
+
}
|
vendor/toolset/toolset-common/inc/{controller → autoloaded}/asset_manager.php
RENAMED
File without changes
|
vendor/toolset/toolset-common/inc/{controller → autoloaded}/constants.php
RENAMED
File without changes
|
vendor/toolset/toolset-common/inc/autoloaded/cron/cron.php
ADDED
@@ -0,0 +1,182 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Helper class for interaction with WP-Cron.
|
5 |
+
*
|
6 |
+
* Allows scheduling and unscheduling events easier with by allowing events to be defined
|
7 |
+
* as objects implementing the IToolset_Cront_Event interface. Additionally, it tracks
|
8 |
+
* scheduled events by plugin they come from and allows then batch unscheduling when given plugin
|
9 |
+
* is being deactivated.
|
10 |
+
*
|
11 |
+
* If a plugin is using WP-Cron, it should also include a deactivation hook that will handle this
|
12 |
+
* unscheduling.
|
13 |
+
*
|
14 |
+
* For m2m WP-Cron events originating from Toolset Common, the "types" plugin slug should be used,
|
15 |
+
* since without Types, there is no m2m functionality to speak of.
|
16 |
+
*
|
17 |
+
* Note that events of IToolset_Cront_Event are supposed to have a slug. This slug must
|
18 |
+
* be unique throughout Toolset. The event hook (action which will be called by WP-Cron) is built
|
19 |
+
* from the HOOK_PREFIX and this unique slug (see get_hook_name()).
|
20 |
+
*
|
21 |
+
* If two events have different arguments, they are *not* considered equal by WP-Cron.
|
22 |
+
* Be sure to thoroughly test such a scenario with this API.
|
23 |
+
*
|
24 |
+
* @link https://developer.wordpress.org/plugins/cron/
|
25 |
+
* @since 2.5.10
|
26 |
+
*/
|
27 |
+
class Toolset_Cron {
|
28 |
+
|
29 |
+
|
30 |
+
/** Prefix of each event hook. Must not be changed, otherwise existing events will break. */
|
31 |
+
const HOOK_PREFIX = 'toolset_cron_';
|
32 |
+
|
33 |
+
|
34 |
+
/** Option where the event information is stored (slug + parent plugin) */
|
35 |
+
const SCHEDULED_EVENTS_OPTION = 'toolset_cron_events';
|
36 |
+
|
37 |
+
|
38 |
+
/** @var Toolset_Cron */
|
39 |
+
private static $instance;
|
40 |
+
|
41 |
+
|
42 |
+
/**
|
43 |
+
* @return Toolset_Cron
|
44 |
+
*/
|
45 |
+
public static function get_instance() {
|
46 |
+
if( null === self::$instance ) {
|
47 |
+
self::$instance = new self();
|
48 |
+
}
|
49 |
+
return self::$instance;
|
50 |
+
}
|
51 |
+
|
52 |
+
|
53 |
+
/**
|
54 |
+
* Schedule a new event if it's not scheduled already.
|
55 |
+
*
|
56 |
+
* @param IToolset_Cron_Event $event
|
57 |
+
*
|
58 |
+
* @return Toolset_Result Will succeed if an event is scheduled (now or before).
|
59 |
+
*/
|
60 |
+
public function schedule_event( IToolset_Cron_Event $event ) {
|
61 |
+
if( $this->is_scheduled( $event ) ) {
|
62 |
+
return new Toolset_Result( true );
|
63 |
+
}
|
64 |
+
|
65 |
+
$result = wp_schedule_event(
|
66 |
+
time(), $event->get_interval(), $this->get_hook_name( $event ), $event->get_args()
|
67 |
+
);
|
68 |
+
|
69 |
+
$is_success = ( false !== $result );
|
70 |
+
|
71 |
+
if( $is_success ) {
|
72 |
+
$this->save_event( $event );
|
73 |
+
}
|
74 |
+
|
75 |
+
return new Toolset_Result( $is_success );
|
76 |
+
}
|
77 |
+
|
78 |
+
|
79 |
+
/**
|
80 |
+
* True if an event is already scheduled.
|
81 |
+
*
|
82 |
+
* @param IToolset_Cron_Event $event
|
83 |
+
*
|
84 |
+
* @return bool
|
85 |
+
*/
|
86 |
+
public function is_scheduled( IToolset_Cron_Event $event ) {
|
87 |
+
$timestamp = wp_next_scheduled( $this->get_hook_name( $event ), $event->get_args() );
|
88 |
+
return ( false !== $timestamp );
|
89 |
+
}
|
90 |
+
|
91 |
+
|
92 |
+
/**
|
93 |
+
* Get a full name of the hook that will be called when WP-Cron executes the event.
|
94 |
+
*
|
95 |
+
* @param IToolset_Cron_Event $event
|
96 |
+
*
|
97 |
+
* @return string
|
98 |
+
*/
|
99 |
+
public function get_hook_name( IToolset_Cron_Event $event ) {
|
100 |
+
return $this->get_hook_from_slug( $event->get_unique_slug() );
|
101 |
+
}
|
102 |
+
|
103 |
+
|
104 |
+
/**
|
105 |
+
* @param string $event_slug
|
106 |
+
*
|
107 |
+
* @return string
|
108 |
+
*/
|
109 |
+
private function get_hook_from_slug( $event_slug ) {
|
110 |
+
return self::HOOK_PREFIX . $event_slug;
|
111 |
+
}
|
112 |
+
|
113 |
+
|
114 |
+
/**
|
115 |
+
* Save the newly scheduled event into the option, so that we know what to deactivate
|
116 |
+
* when a Toolset plugin is being deactivated.
|
117 |
+
*
|
118 |
+
* @param IToolset_Cron_Event $event
|
119 |
+
*/
|
120 |
+
private function save_event( IToolset_Cron_Event $event ) {
|
121 |
+
$events = toolset_ensarr( get_option( self::SCHEDULED_EVENTS_OPTION ) );
|
122 |
+
$events[ $event->get_unique_slug() ] = array(
|
123 |
+
'slug' => $event->get_unique_slug(),
|
124 |
+
'plugin' => $event->get_parent_plugin()
|
125 |
+
);
|
126 |
+
update_option( self::SCHEDULED_EVENTS_OPTION, $events, false );
|
127 |
+
}
|
128 |
+
|
129 |
+
|
130 |
+
/**
|
131 |
+
* Remove an event from the stored option when it was unscheduled.
|
132 |
+
*
|
133 |
+
* @param string $event_unique_slug
|
134 |
+
*/
|
135 |
+
private function remove_event( $event_unique_slug ) {
|
136 |
+
$events = toolset_ensarr( get_option( self::SCHEDULED_EVENTS_OPTION ) );
|
137 |
+
unset( $events[ $event_unique_slug ] );
|
138 |
+
update_option( self::SCHEDULED_EVENTS_OPTION, $events, false );
|
139 |
+
}
|
140 |
+
|
141 |
+
|
142 |
+
/**
|
143 |
+
* Unschedule an event.
|
144 |
+
*
|
145 |
+
* @param IToolset_Cron_Event $event
|
146 |
+
*
|
147 |
+
* @return Toolset_Result Will succeed if the event was unscheduled or if it there was
|
148 |
+
* nothing to unschedule.
|
149 |
+
*/
|
150 |
+
public function unschedule_event( IToolset_Cron_Event $event ) {
|
151 |
+
if( ! $this->is_scheduled( $event ) ) {
|
152 |
+
return new Toolset_Result( true );
|
153 |
+
}
|
154 |
+
|
155 |
+
$timestamp = wp_next_scheduled( $this->get_hook_name( $event ), $event->get_args() );
|
156 |
+
$result = wp_unschedule_event( $timestamp, $this->get_hook_name( $event ) );
|
157 |
+
|
158 |
+
$was_unscheduled = ( false !== $result );
|
159 |
+
|
160 |
+
$this->remove_event( $event->get_unique_slug() );
|
161 |
+
|
162 |
+
return new Toolset_Result( $was_unscheduled );
|
163 |
+
}
|
164 |
+
|
165 |
+
|
166 |
+
/**
|
167 |
+
* This should be called when a plugin that uses Toolset_Cron is being deactivated.
|
168 |
+
*
|
169 |
+
* @param string $plugin_slug
|
170 |
+
*/
|
171 |
+
public function on_plugin_deactivation( $plugin_slug ) {
|
172 |
+
$events = toolset_ensarr( get_option( self::SCHEDULED_EVENTS_OPTION ) );
|
173 |
+
foreach( $events as $event_unique_slug => $event ) {
|
174 |
+
$event_parent_plugin = toolset_getarr( $event, 'plugin' );
|
175 |
+
if( $event_parent_plugin === $plugin_slug ) {
|
176 |
+
wp_unschedule_hook( $this->get_hook_from_slug( $event_unique_slug ) );
|
177 |
+
$this->remove_event( $event_unique_slug );
|
178 |
+
}
|
179 |
+
}
|
180 |
+
}
|
181 |
+
|
182 |
+
}
|
vendor/toolset/toolset-common/inc/autoloaded/cron/event.php
ADDED
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Basic IToolset_Cron_Event implementation.
|
5 |
+
*
|
6 |
+
* @since 2.5.10
|
7 |
+
*/
|
8 |
+
abstract class Toolset_Cron_Event implements IToolset_Cron_Event {
|
9 |
+
|
10 |
+
|
11 |
+
// These are guaranteed WP-Cron intervals. Anything else is site-specific.
|
12 |
+
const INTERVAL_HOURLY = 'hourly';
|
13 |
+
const INTERVAL_TWICE_DAILY = 'twicedaily';
|
14 |
+
const INTERVAL_DAILY = 'daily';
|
15 |
+
|
16 |
+
|
17 |
+
/**
|
18 |
+
* @inheritdoc
|
19 |
+
*
|
20 |
+
* @return string
|
21 |
+
*/
|
22 |
+
public function get_interval() {
|
23 |
+
return self::INTERVAL_DAILY;
|
24 |
+
}
|
25 |
+
|
26 |
+
|
27 |
+
/**
|
28 |
+
* @inheritdoc
|
29 |
+
*
|
30 |
+
* @return array
|
31 |
+
*/
|
32 |
+
public function get_args() {
|
33 |
+
return array();
|
34 |
+
}
|
35 |
+
|
36 |
+
|
37 |
+
}
|
vendor/toolset/toolset-common/inc/autoloaded/cron/event_interface.php
ADDED
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* An interface that represents a WP-Cron event, to be used with Toolset_Cron.
|
5 |
+
*
|
6 |
+
* @since 2.5.10
|
7 |
+
*/
|
8 |
+
interface IToolset_Cron_Event {
|
9 |
+
|
10 |
+
/**
|
11 |
+
* Event slug.
|
12 |
+
*
|
13 |
+
* Needs to be unique throughout Toolset.
|
14 |
+
*
|
15 |
+
* @return string
|
16 |
+
*/
|
17 |
+
public function get_unique_slug();
|
18 |
+
|
19 |
+
|
20 |
+
/**
|
21 |
+
* A valid WP-Cron interval. Check Toolset_Cron_Event constants for values that are available
|
22 |
+
* at all times.
|
23 |
+
*
|
24 |
+
* @return string
|
25 |
+
*/
|
26 |
+
public function get_interval();
|
27 |
+
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Arguments that will be passed to the event hook when executed.
|
31 |
+
*
|
32 |
+
* @return array
|
33 |
+
*/
|
34 |
+
public function get_args();
|
35 |
+
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Slug of the plugin that owns this event. If the plugin uses Toolset_Cron properly,
|
39 |
+
* the right events will be unscheduled if the plugin is deactivated.
|
40 |
+
*
|
41 |
+
* @return string
|
42 |
+
*/
|
43 |
+
public function get_parent_plugin();
|
44 |
+
|
45 |
+
}
|
vendor/toolset/toolset-common/inc/autoloaded/element/element.php
CHANGED
@@ -54,88 +54,17 @@ abstract class Toolset_Element implements IToolset_Element {
|
|
54 |
*
|
55 |
* @param string $domain Valid element domain as defined in Toolset_Field_Utils.
|
56 |
* @param mixed $object_source Source of the underlying object that will be recognized by the specific element class.
|
57 |
-
* It also recognizes translation sets (array of sources, indexed by language code) for posts.
|
58 |
*
|
59 |
* @return IToolset_Element
|
60 |
* @since m2m
|
61 |
* @deprecated Use Toolset_Element_Factory::get_element() instead.
|
62 |
*/
|
63 |
public static function get_instance( $domain, $object_source ) {
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
/*case Toolset_Field_Utils::DOMAIN_POSTS:
|
68 |
-
|
69 |
-
if( $object_source instanceof IToolset_Post ) {
|
70 |
-
// todo handle Toolset_Post where we should be returning Toolset_Post_Translation_Set
|
71 |
-
return $object_source;
|
72 |
-
|
73 |
-
}
|
74 |
-
|
75 |
-
if( Toolset_WPML_Compatibility::get_instance()->is_wpml_active_and_configured() ) {
|
76 |
-
|
77 |
-
// If we got a post object and we know it's not translatable, we don't need to bother.
|
78 |
-
//
|
79 |
-
// Without the post object (when we get only an ID, for example), we won't bother for performance reasons.
|
80 |
-
if( $object_source instanceof WP_Post && ! Toolset_Wpml_Utils::is_post_type_translatable( $object_source->post_type ) ) {
|
81 |
-
return self::get_untranslated_instance( $domain, $object_source );
|
82 |
-
}
|
83 |
-
|
84 |
-
if( ! is_array( $object_source ) ) {
|
85 |
-
$object_source = array( $object_source );
|
86 |
-
}
|
87 |
-
|
88 |
-
$translated_posts = array();
|
89 |
-
|
90 |
-
// Get a Toolset_Post for each translation
|
91 |
-
foreach( $object_source as $language_code => $post_id ) {
|
92 |
-
|
93 |
-
if( ! is_string( $language_code ) || empty( $language_code ) ) {
|
94 |
-
// no (known) language here
|
95 |
-
$language_code = null;
|
96 |
-
}
|
97 |
-
|
98 |
-
$post = Toolset_Post::get_instance( $post_id, $language_code );
|
99 |
-
|
100 |
-
$translated_posts[ $post->get_language() ] = $post;
|
101 |
-
}
|
102 |
-
|
103 |
-
return new Toolset_Post_Translation_Set( $translated_posts );
|
104 |
-
|
105 |
-
}
|
106 |
-
|
107 |
-
// No WPML, simply return the post object.
|
108 |
-
return self::get_untranslated_instance( $domain, $object_source );*/
|
109 |
-
|
110 |
-
|
111 |
-
default:
|
112 |
-
return self::get_untranslated_instance( $domain, $object_source );
|
113 |
-
}
|
114 |
}
|
115 |
|
116 |
|
117 |
-
/**
|
118 |
-
* Get an element instance without attempting translation.
|
119 |
-
*
|
120 |
-
* Use with care. Normally you should never need this one and stick with get_instance().
|
121 |
-
*
|
122 |
-
* @param string $domain Valid element domain as defined in Toolset_Field_Utils.
|
123 |
-
* @param mixed $object_source Source of the underlying object that will be recognized by the specific element class.
|
124 |
-
*
|
125 |
-
* @return IToolset_Element
|
126 |
-
*/
|
127 |
-
public static function get_untranslated_instance( $domain, $object_source ) {
|
128 |
-
switch( $domain ) {
|
129 |
-
case Toolset_Field_Utils::DOMAIN_POSTS:
|
130 |
-
return Toolset_Post::get_instance( $object_source );
|
131 |
-
case Toolset_Field_Utils::DOMAIN_TERMS:
|
132 |
-
case Toolset_Field_Utils::DOMAIN_USERS:
|
133 |
-
throw new RuntimeException( 'Not implemented.' );
|
134 |
-
default:
|
135 |
-
throw new InvalidArgumentException( 'Invalid domain name.' );
|
136 |
-
}
|
137 |
-
}
|
138 |
-
|
139 |
|
140 |
/**
|
141 |
* @return string One of the Toolset_Field_Utils::get_domains() values.
|
@@ -322,4 +251,30 @@ abstract class Toolset_Element implements IToolset_Element {
|
|
322 |
return false;
|
323 |
}
|
324 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
325 |
}
|
54 |
*
|
55 |
* @param string $domain Valid element domain as defined in Toolset_Field_Utils.
|
56 |
* @param mixed $object_source Source of the underlying object that will be recognized by the specific element class.
|
|
|
57 |
*
|
58 |
* @return IToolset_Element
|
59 |
* @since m2m
|
60 |
* @deprecated Use Toolset_Element_Factory::get_element() instead.
|
61 |
*/
|
62 |
public static function get_instance( $domain, $object_source ) {
|
63 |
+
$factory = new Toolset_Element_Factory();
|
64 |
+
return $factory->get_element( $domain, $object_source );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
65 |
}
|
66 |
|
67 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
68 |
|
69 |
/**
|
70 |
* @return string One of the Toolset_Field_Utils::get_domains() values.
|
251 |
return false;
|
252 |
}
|
253 |
|
254 |
+
|
255 |
+
/**
|
256 |
+
* @inheritdoc
|
257 |
+
*
|
258 |
+
* @param string $language_code
|
259 |
+
* @param bool $exact_match_only
|
260 |
+
*
|
261 |
+
* @return IToolset_Element|null
|
262 |
+
*/
|
263 |
+
public function translate( $language_code, $exact_match_only = false ) {
|
264 |
+
// We can afford this even for posts. If WPML is active at all, all posts will be
|
265 |
+
// instantiated as translation sets.
|
266 |
+
return $this;
|
267 |
+
}
|
268 |
+
|
269 |
+
|
270 |
+
/**
|
271 |
+
* @inheritdoc
|
272 |
+
*
|
273 |
+
* @return int
|
274 |
+
* @since 2.5.10
|
275 |
+
*/
|
276 |
+
public function get_default_language_id() {
|
277 |
+
return $this->get_id();
|
278 |
+
}
|
279 |
+
|
280 |
}
|
vendor/toolset/toolset-common/inc/autoloaded/element/element_factory.php
CHANGED
@@ -3,41 +3,122 @@
|
|
3 |
/**
|
4 |
* Factory for IToolset_Element.
|
5 |
*
|
6 |
-
* Note: Currently used only for the purpose of unit test mocking. Eventually the relevant code should be moved here.
|
7 |
-
*
|
8 |
* @since m2m
|
|
|
|
|
|
|
9 |
*/
|
10 |
class Toolset_Element_Factory {
|
11 |
|
12 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
/**
|
14 |
* Get an element instance based on it's domain.
|
15 |
*
|
16 |
* @param string $domain Valid element domain as defined in Toolset_Field_Utils.
|
17 |
-
* @param mixed $object_source Source of the underlying object that will be recognized by the specific element
|
18 |
-
* It also recognizes translation sets (array of sources, indexed by language code) for posts.
|
19 |
*
|
20 |
* @return IToolset_Element
|
|
|
21 |
* @since m2m
|
22 |
*/
|
23 |
public function get_element( $domain, $object_source ) {
|
24 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
25 |
}
|
26 |
|
27 |
|
28 |
/**
|
29 |
* Instantiate the post.
|
30 |
*
|
31 |
-
*
|
32 |
-
*
|
|
|
|
|
33 |
*
|
34 |
-
* @param
|
35 |
-
* @param null|string $language_code
|
|
|
36 |
*
|
37 |
* @return Toolset_Post
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
38 |
*/
|
39 |
-
public function
|
40 |
-
|
|
|
|
|
|
|
41 |
}
|
42 |
|
43 |
}
|
3 |
/**
|
4 |
* Factory for IToolset_Element.
|
5 |
*
|
|
|
|
|
6 |
* @since m2m
|
7 |
+
* @since 2.5.10 The get_post() method is open to external use and can return the post translation
|
8 |
+
* set as well, if WPML is active. get_post_untranslated() can be used instead of the previous
|
9 |
+
* get_post() implementation.
|
10 |
*/
|
11 |
class Toolset_Element_Factory {
|
12 |
|
13 |
|
14 |
+
/** @var Toolset_Condition_Plugin_Wpml_Is_Active_And_Configured */
|
15 |
+
private $is_wpml_active;
|
16 |
+
|
17 |
+
|
18 |
+
/** @var Toolset_WPML_Compatibility */
|
19 |
+
private $wpml_service;
|
20 |
+
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Toolset_Element_Factory constructor.
|
24 |
+
*
|
25 |
+
* @param Toolset_Condition_Plugin_Wpml_Is_Active_And_Configured|null $is_wpml_active
|
26 |
+
* @param Toolset_WPML_Compatibility|null $wpml_service
|
27 |
+
*/
|
28 |
+
public function __construct(
|
29 |
+
Toolset_Condition_Plugin_Wpml_Is_Active_And_Configured $is_wpml_active = null,
|
30 |
+
Toolset_WPML_Compatibility $wpml_service = null
|
31 |
+
) {
|
32 |
+
$this->is_wpml_active = ( null === $is_wpml_active ? new Toolset_Condition_Plugin_Wpml_Is_Active_And_Configured() : $is_wpml_active );
|
33 |
+
$this->wpml_service = ( null === $wpml_service ? Toolset_WPML_Compatibility::get_instance() : $wpml_service );
|
34 |
+
}
|
35 |
+
|
36 |
+
|
37 |
/**
|
38 |
* Get an element instance based on it's domain.
|
39 |
*
|
40 |
* @param string $domain Valid element domain as defined in Toolset_Field_Utils.
|
41 |
+
* @param mixed $object_source Source of the underlying object that will be recognized by the specific element
|
42 |
+
* class. It also recognizes translation sets (array of sources, indexed by language code) for posts.
|
43 |
*
|
44 |
* @return IToolset_Element
|
45 |
+
* @throws Toolset_Element_Exception_Element_Doesnt_Exist
|
46 |
* @since m2m
|
47 |
*/
|
48 |
public function get_element( $domain, $object_source ) {
|
49 |
+
switch( $domain ) {
|
50 |
+
case Toolset_Element_Domain::POSTS:
|
51 |
+
return $this->get_post( $object_source );
|
52 |
+
|
53 |
+
case Toolset_Element_Domain::TERMS:
|
54 |
+
case Toolset_Element_Domain::USERS:
|
55 |
+
throw new RuntimeException( 'Not implemented.' );
|
56 |
+
}
|
57 |
+
|
58 |
+
throw new InvalidArgumentException( 'Invalid domain name.' );
|
59 |
+
}
|
60 |
+
|
61 |
+
|
62 |
+
/**
|
63 |
+
* Instantiate the post.
|
64 |
+
*
|
65 |
+
* @param int|WP_Post $object_source
|
66 |
+
*
|
67 |
+
* @return IToolset_Post
|
68 |
+
* @throws Toolset_Element_Exception_Element_Doesnt_Exist
|
69 |
+
*/
|
70 |
+
public function get_post( $object_source ) {
|
71 |
+
if( $this->is_wpml_active->is_met() ) {
|
72 |
+
|
73 |
+
if( ! $object_source instanceof WP_Post
|
74 |
+
|| $this->wpml_service->is_post_type_translatable( $object_source->post_type )
|
75 |
+
) {
|
76 |
+
// Either we don't know the post type yet or we know it is translatable.
|
77 |
+
return $this->get_post_translation_set( $object_source );
|
78 |
+
}
|
79 |
+
}
|
80 |
+
|
81 |
+
return $this->get_post_untranslated( $object_source );
|
82 |
}
|
83 |
|
84 |
|
85 |
/**
|
86 |
* Instantiate the post.
|
87 |
*
|
88 |
+
* This is an WPML-unaware version that will always return a Toolset_Post instance.
|
89 |
+
* Use only in cases where this is explicitly needed.
|
90 |
+
*
|
91 |
+
* Otherwise, for instantiating Toolset elements, you should use the get_element() method.
|
92 |
*
|
93 |
+
* @param int|WP_Post $object_source
|
94 |
+
* @param null|string $language_code Language of the post being created.
|
95 |
+
* If it's passed here, it might save one WPML interaction later when requested.
|
96 |
*
|
97 |
* @return Toolset_Post
|
98 |
+
* @throws Toolset_Element_Exception_Element_Doesnt_Exist
|
99 |
+
*/
|
100 |
+
public function get_post_untranslated( $object_source, $language_code = null ) {
|
101 |
+
return new Toolset_Post(
|
102 |
+
$object_source, $language_code, null, null, $this
|
103 |
+
);
|
104 |
+
}
|
105 |
+
|
106 |
+
|
107 |
+
/**
|
108 |
+
* Instantiate the post as a translation set.
|
109 |
+
*
|
110 |
+
* This method must not be used when WPML is not active, and there should be no reasonable need to use
|
111 |
+
* it instead of get_element() or get_post().
|
112 |
+
*
|
113 |
+
* @param array|WP_Post|int $object_source
|
114 |
+
*
|
115 |
+
* @return Toolset_Post_Translation_Set
|
116 |
*/
|
117 |
+
public function get_post_translation_set( $object_source ) {
|
118 |
+
if( ! is_array( $object_source ) ) {
|
119 |
+
$object_source = array( $object_source );
|
120 |
+
}
|
121 |
+
return new Toolset_Post_Translation_Set( $object_source, $this->wpml_service, $this );
|
122 |
}
|
123 |
|
124 |
}
|
vendor/toolset/toolset-common/inc/autoloaded/element/i_element.php
CHANGED
@@ -15,19 +15,19 @@ interface IToolset_Element {
|
|
15 |
/**
|
16 |
* @return string One of the Toolset_Field_Utils::get_domains() values.
|
17 |
*/
|
18 |
-
function get_domain();
|
19 |
|
20 |
|
21 |
/**
|
22 |
* @return int ID of the underlying object.
|
23 |
*/
|
24 |
-
function get_id();
|
25 |
|
26 |
|
27 |
/**
|
28 |
* @return string Element title.
|
29 |
*/
|
30 |
-
function get_title();
|
31 |
|
32 |
|
33 |
/**
|
@@ -36,13 +36,13 @@ interface IToolset_Element {
|
|
36 |
* @return void
|
37 |
* @since m2m
|
38 |
*/
|
39 |
-
function initialize_fields();
|
40 |
|
41 |
|
42 |
/**
|
43 |
* @return bool
|
44 |
*/
|
45 |
-
function are_fields_loaded();
|
46 |
|
47 |
|
48 |
/**
|
@@ -51,7 +51,7 @@ interface IToolset_Element {
|
|
51 |
* @return mixed Depends on the implementation.
|
52 |
* @since m2m
|
53 |
*/
|
54 |
-
function get_underlying_object();
|
55 |
|
56 |
|
57 |
/**
|
@@ -65,7 +65,7 @@ interface IToolset_Element {
|
|
65 |
* @throws InvalidArgumentException When the field source has a wrong type.
|
66 |
* @since m2m
|
67 |
*/
|
68 |
-
function has_field( $field_source );
|
69 |
|
70 |
|
71 |
/**
|
@@ -77,7 +77,7 @@ interface IToolset_Element {
|
|
77 |
* @return Toolset_Field_Instance
|
78 |
* @throws InvalidArgumentException When the field source has a wrong type.
|
79 |
*/
|
80 |
-
function get_field( $field_source );
|
81 |
|
82 |
|
83 |
/**
|
@@ -86,10 +86,10 @@ interface IToolset_Element {
|
|
86 |
* @return Toolset_Field_Instance[]
|
87 |
* @since m2m
|
88 |
*/
|
89 |
-
function get_fields();
|
90 |
|
91 |
|
92 |
-
function get_field_count();
|
93 |
|
94 |
|
95 |
/**
|
@@ -97,7 +97,7 @@ interface IToolset_Element {
|
|
97 |
*
|
98 |
* @return bool
|
99 |
*/
|
100 |
-
function is_translatable();
|
101 |
|
102 |
|
103 |
/**
|
@@ -106,5 +106,33 @@ interface IToolset_Element {
|
|
106 |
* @return string Language code or an empty string if not applicable.
|
107 |
* @since m2m
|
108 |
*/
|
109 |
-
function get_language();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
110 |
}
|
15 |
/**
|
16 |
* @return string One of the Toolset_Field_Utils::get_domains() values.
|
17 |
*/
|
18 |
+
public function get_domain();
|
19 |
|
20 |
|
21 |
/**
|
22 |
* @return int ID of the underlying object.
|
23 |
*/
|
24 |
+
public function get_id();
|
25 |
|
26 |
|
27 |
/**
|
28 |
* @return string Element title.
|
29 |
*/
|
30 |
+
public function get_title();
|
31 |
|
32 |
|
33 |
/**
|
36 |
* @return void
|
37 |
* @since m2m
|
38 |
*/
|
39 |
+
public function initialize_fields();
|
40 |
|
41 |
|
42 |
/**
|
43 |
* @return bool
|
44 |
*/
|
45 |
+
public function are_fields_loaded();
|
46 |
|
47 |
|
48 |
/**
|
51 |
* @return mixed Depends on the implementation.
|
52 |
* @since m2m
|
53 |
*/
|
54 |
+
public function get_underlying_object();
|
55 |
|
56 |
|
57 |
/**
|
65 |
* @throws InvalidArgumentException When the field source has a wrong type.
|
66 |
* @since m2m
|
67 |
*/
|
68 |
+
public function has_field( $field_source );
|
69 |
|
70 |
|
71 |
/**
|
77 |
* @return Toolset_Field_Instance
|
78 |
* @throws InvalidArgumentException When the field source has a wrong type.
|
79 |
*/
|
80 |
+
public function get_field( $field_source );
|
81 |
|
82 |
|
83 |
/**
|
86 |
* @return Toolset_Field_Instance[]
|
87 |
* @since m2m
|
88 |
*/
|
89 |
+
public function get_fields();
|
90 |
|
91 |
|
92 |
+
public function get_field_count();
|
93 |
|
94 |
|
95 |
/**
|
97 |
*
|
98 |
* @return bool
|
99 |
*/
|
100 |
+
public function is_translatable();
|
101 |
|
102 |
|
103 |
/**
|
106 |
* @return string Language code or an empty string if not applicable.
|
107 |
* @since m2m
|
108 |
*/
|
109 |
+
public function get_language();
|
110 |
+
|
111 |
+
|
112 |
+
/**
|
113 |
+
* Return an element translation.
|
114 |
+
*
|
115 |
+
* If the element domain and type are non-translatable, it will return itself.
|
116 |
+
*
|
117 |
+
* If the element could be translated to the target language but is not,
|
118 |
+
* the return value will depend on the $exact_match_only parameter:
|
119 |
+
* If it's true, it will return null. Otherwise, it will return the best possible
|
120 |
+
* translation (default language/original/any).
|
121 |
+
*
|
122 |
+
* @param string $language_code
|
123 |
+
* @param bool $exact_match_only
|
124 |
+
*
|
125 |
+
* @return IToolset_Element|null
|
126 |
+
* @since 2.5.10
|
127 |
+
*/
|
128 |
+
public function translate( $language_code, $exact_match_only = false );
|
129 |
+
|
130 |
+
|
131 |
+
/**
|
132 |
+
* ID of the element in the default language or same as get_id() if not applicable.
|
133 |
+
*
|
134 |
+
* @return int
|
135 |
+
* @since 2.5.10
|
136 |
+
*/
|
137 |
+
public function get_default_language_id();
|
138 |
}
|
vendor/toolset/toolset-common/inc/autoloaded/element/i_post.php
CHANGED
@@ -15,6 +15,13 @@ interface IToolset_Post extends IToolset_Element {
|
|
15 |
public function get_type();
|
16 |
|
17 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
18 |
/**
|
19 |
* @return string Post title
|
20 |
* @since m2m
|
@@ -33,7 +40,28 @@ interface IToolset_Post extends IToolset_Element {
|
|
33 |
|
34 |
/**
|
35 |
* @return string Post slug
|
36 |
-
* @since
|
37 |
*/
|
38 |
public function get_slug();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
39 |
}
|
15 |
public function get_type();
|
16 |
|
17 |
|
18 |
+
/**
|
19 |
+
* @return IToolset_Post_Type|null
|
20 |
+
* @since 2.5.10
|
21 |
+
*/
|
22 |
+
public function get_type_object();
|
23 |
+
|
24 |
+
|
25 |
/**
|
26 |
* @return string Post title
|
27 |
* @since m2m
|
40 |
|
41 |
/**
|
42 |
* @return string Post slug
|
43 |
+
* @since m2m
|
44 |
*/
|
45 |
public function get_slug();
|
46 |
+
|
47 |
+
|
48 |
+
/**
|
49 |
+
* @return bool
|
50 |
+
* @since 2.5.10
|
51 |
+
*/
|
52 |
+
public function is_revision();
|
53 |
+
|
54 |
+
|
55 |
+
/**
|
56 |
+
* @return int ID of the post author.
|
57 |
+
* @since 2.5.11
|
58 |
+
*/
|
59 |
+
public function get_author();
|
60 |
+
|
61 |
+
|
62 |
+
/**
|
63 |
+
* @return int The trid of the translation set if WPML is active and the post is part of one, zero otherwise.
|
64 |
+
* @since 2.5.11
|
65 |
+
*/
|
66 |
+
public function get_trid();
|
67 |
}
|
vendor/toolset/toolset-common/inc/autoloaded/element/post.php
CHANGED
@@ -5,12 +5,17 @@
|
|
5 |
*
|
6 |
* Simplifies the access to field instances and associations.
|
7 |
*
|
|
|
|
|
8 |
* @since m2m
|
9 |
*/
|
10 |
class Toolset_Post extends Toolset_Element implements IToolset_Post {
|
11 |
|
|
|
|
|
12 |
const SORTORDER_META_KEY = 'toolset-post-sortorder';
|
13 |
|
|
|
14 |
/** @var WP_Post */
|
15 |
private $post;
|
16 |
|
@@ -19,6 +24,15 @@ class Toolset_Post extends Toolset_Element implements IToolset_Post {
|
|
19 |
private $language_code = null;
|
20 |
|
21 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
22 |
/**
|
23 |
* Toolset_Element constructor.
|
24 |
*
|
@@ -27,11 +41,22 @@ class Toolset_Post extends Toolset_Element implements IToolset_Post {
|
|
27 |
* "this post has no language", while null can be passed if this unknown (and it will be
|
28 |
* determined first time it's needed).
|
29 |
* @param null|Toolset_Field_Group_Post_Factory $group_post_factory DI for phpunit
|
|
|
|
|
|
|
30 |
*
|
31 |
* @throws Toolset_Element_Exception_Element_Doesnt_Exist
|
32 |
* @since m2m
|
33 |
*/
|
34 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
35 |
|
36 |
if( Toolset_Utils::is_natural_numeric( $object_source ) ) {
|
37 |
$post = WP_Post::get_instance( $object_source );
|
@@ -53,8 +78,9 @@ class Toolset_Post extends Toolset_Element implements IToolset_Post {
|
|
53 |
parent::__construct( $post, $group_post_factory );
|
54 |
|
55 |
$this->post = $post;
|
56 |
-
|
57 |
$this->language_code = $language_code;
|
|
|
|
|
58 |
}
|
59 |
|
60 |
|
@@ -70,16 +96,18 @@ class Toolset_Post extends Toolset_Element implements IToolset_Post {
|
|
70 |
* @deprecated Use Toolset_Element_Factory::get_post() instead.
|
71 |
*
|
72 |
* @return Toolset_Post
|
|
|
73 |
*/
|
74 |
public static function get_instance( $object_source, $language_code = null ) {
|
75 |
-
|
|
|
76 |
}
|
77 |
|
78 |
|
79 |
/**
|
80 |
* @return string One of the Toolset_Field_Utils::get_domains() values.
|
81 |
*/
|
82 |
-
public function get_domain() { return
|
83 |
|
84 |
|
85 |
/**
|
@@ -121,7 +149,7 @@ class Toolset_Post extends Toolset_Element implements IToolset_Post {
|
|
121 |
* @return bool
|
122 |
*/
|
123 |
public function is_translatable() {
|
124 |
-
return
|
125 |
}
|
126 |
|
127 |
|
@@ -129,10 +157,9 @@ class Toolset_Post extends Toolset_Element implements IToolset_Post {
|
|
129 |
* @inheritdoc
|
130 |
* @return string
|
131 |
*/
|
132 |
-
function get_language() {
|
133 |
if( null === $this->language_code ) {
|
134 |
-
$
|
135 |
-
$this->language_code = toolset_getarr( $post_language_details, 'language_code', '' );
|
136 |
}
|
137 |
|
138 |
return $this->language_code;
|
@@ -159,4 +186,93 @@ class Toolset_Post extends Toolset_Element implements IToolset_Post {
|
|
159 |
}
|
160 |
|
161 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
162 |
}
|
5 |
*
|
6 |
* Simplifies the access to field instances and associations.
|
7 |
*
|
8 |
+
* Always use Toolset_Element_Factory to instantiate this class.
|
9 |
+
*
|
10 |
* @since m2m
|
11 |
*/
|
12 |
class Toolset_Post extends Toolset_Element implements IToolset_Post {
|
13 |
|
14 |
+
|
15 |
+
// FIXME document this
|
16 |
const SORTORDER_META_KEY = 'toolset-post-sortorder';
|
17 |
|
18 |
+
|
19 |
/** @var WP_Post */
|
20 |
private $post;
|
21 |
|
24 |
private $language_code = null;
|
25 |
|
26 |
|
27 |
+
private $_post_type_repository;
|
28 |
+
|
29 |
+
private $element_factory;
|
30 |
+
|
31 |
+
|
32 |
+
/** @var Toolset_WPML_Compatibility */
|
33 |
+
private $wpml_service;
|
34 |
+
|
35 |
+
|
36 |
/**
|
37 |
* Toolset_Element constructor.
|
38 |
*
|
41 |
* "this post has no language", while null can be passed if this unknown (and it will be
|
42 |
* determined first time it's needed).
|
43 |
* @param null|Toolset_Field_Group_Post_Factory $group_post_factory DI for phpunit
|
44 |
+
* @param Toolset_Post_Type_Repository|null $post_type_repository_di
|
45 |
+
* @param Toolset_Element_Factory|null $element_factory_di
|
46 |
+
* @param Toolset_WPML_Compatibility|null $wpml_service_di
|
47 |
*
|
48 |
* @throws Toolset_Element_Exception_Element_Doesnt_Exist
|
49 |
* @since m2m
|
50 |
*/
|
51 |
+
public function __construct(
|
52 |
+
$object_source,
|
53 |
+
$language_code = null,
|
54 |
+
$group_post_factory = null,
|
55 |
+
Toolset_Post_Type_Repository $post_type_repository_di = null,
|
56 |
+
Toolset_Element_Factory $element_factory_di = null,
|
57 |
+
Toolset_WPML_Compatibility $wpml_service_di = null
|
58 |
+
) {
|
59 |
+
$this->_post_type_repository = $post_type_repository_di;
|
60 |
|
61 |
if( Toolset_Utils::is_natural_numeric( $object_source ) ) {
|
62 |
$post = WP_Post::get_instance( $object_source );
|
78 |
parent::__construct( $post, $group_post_factory );
|
79 |
|
80 |
$this->post = $post;
|
|
|
81 |
$this->language_code = $language_code;
|
82 |
+
$this->element_factory = ( null === $element_factory_di ? new Toolset_Element_Factory() : $element_factory_di );
|
83 |
+
$this->wpml_service = ( null === $wpml_service_di ? Toolset_WPML_Compatibility::get_instance() : $wpml_service_di );
|
84 |
}
|
85 |
|
86 |
|
96 |
* @deprecated Use Toolset_Element_Factory::get_post() instead.
|
97 |
*
|
98 |
* @return Toolset_Post
|
99 |
+
* @throws Toolset_Element_Exception_Element_Doesnt_Exist
|
100 |
*/
|
101 |
public static function get_instance( $object_source, $language_code = null ) {
|
102 |
+
$element_factory = new Toolset_Element_Factory();
|
103 |
+
return $element_factory->get_post_untranslated( $object_source, $language_code );
|
104 |
}
|
105 |
|
106 |
|
107 |
/**
|
108 |
* @return string One of the Toolset_Field_Utils::get_domains() values.
|
109 |
*/
|
110 |
+
public function get_domain() { return Toolset_Element_Domain::POSTS; }
|
111 |
|
112 |
|
113 |
/**
|
149 |
* @return bool
|
150 |
*/
|
151 |
public function is_translatable() {
|
152 |
+
return $this->wpml_service->is_post_type_translatable( $this->get_type() );
|
153 |
}
|
154 |
|
155 |
|
157 |
* @inheritdoc
|
158 |
* @return string
|
159 |
*/
|
160 |
+
public function get_language() {
|
161 |
if( null === $this->language_code ) {
|
162 |
+
$this->language_code = $this->wpml_service->get_post_language( $this->get_id() );
|
|
|
163 |
}
|
164 |
|
165 |
return $this->language_code;
|
186 |
}
|
187 |
|
188 |
|
189 |
+
protected function get_post_type_repository() {
|
190 |
+
if( null === $this->_post_type_repository ) {
|
191 |
+
$this->_post_type_repository = Toolset_Post_Type_Repository::get_instance();
|
192 |
+
}
|
193 |
+
|
194 |
+
return $this->_post_type_repository;
|
195 |
+
}
|
196 |
+
|
197 |
+
|
198 |
+
/**
|
199 |
+
* @return IToolset_Post_Type|null
|
200 |
+
* @since 2.5.10
|
201 |
+
*/
|
202 |
+
public function get_type_object() {
|
203 |
+
return $this->get_post_type_repository()->get( $this->get_type() );
|
204 |
+
}
|
205 |
+
|
206 |
+
|
207 |
+
/**
|
208 |
+
* @inheritdoc
|
209 |
+
*
|
210 |
+
* @param string $language_code
|
211 |
+
* @param bool $exact_match_only
|
212 |
+
*
|
213 |
+
* @return IToolset_Element|null
|
214 |
+
*/
|
215 |
+
public function translate( $language_code, $exact_match_only = false ) {
|
216 |
+
if( ! $this->is_translatable() ) {
|
217 |
+
return $this;
|
218 |
+
}
|
219 |
+
|
220 |
+
// This could happen only in very rare cases, when WPML is active,
|
221 |
+
// someone obtains a translation set from Toolset_Element_Factory,
|
222 |
+
// calls translate() on it, which would return this instance, and then
|
223 |
+
// they call translate() again... and here we are.
|
224 |
+
$translation_set = $this->element_factory->get_post_translation_set( array( $this ) );
|
225 |
+
return $translation_set->translate( $language_code, $exact_match_only );
|
226 |
+
}
|
227 |
+
|
228 |
+
|
229 |
+
/**
|
230 |
+
* @inheritdoc
|
231 |
+
*
|
232 |
+
* @return int
|
233 |
+
* @since 2.5.10
|
234 |
+
*/
|
235 |
+
public function get_default_language_id() {
|
236 |
+
if( ! $this->is_translatable() ) {
|
237 |
+
return $this->get_id();
|
238 |
+
}
|
239 |
+
|
240 |
+
// This could happen only in very rare cases, when WPML is active,
|
241 |
+
// someone obtains a translation set from Toolset_Element_Factory,
|
242 |
+
// calls translate() on it, which would return this instance, and then
|
243 |
+
// they call this method... and here we are.
|
244 |
+
$translation_set = $this->element_factory->get_post_translation_set( array( $this ) );
|
245 |
+
return $translation_set->get_default_language_id();
|
246 |
+
}
|
247 |
+
|
248 |
+
|
249 |
+
/**
|
250 |
+
* @return bool
|
251 |
+
* @since 2.5.10
|
252 |
+
*/
|
253 |
+
public function is_revision() {
|
254 |
+
return ( 'revision' === $this->get_type() );
|
255 |
+
}
|
256 |
+
|
257 |
+
|
258 |
+
/**
|
259 |
+
* @inheritdoc
|
260 |
+
*
|
261 |
+
* @return int
|
262 |
+
* @since 2.5.11
|
263 |
+
*/
|
264 |
+
public function get_author() {
|
265 |
+
return (int) $this->post->post_author;
|
266 |
+
}
|
267 |
+
|
268 |
+
|
269 |
+
/**
|
270 |
+
* @inheritdoc
|
271 |
+
*
|
272 |
+
* @return int
|
273 |
+
* @since 2.5.11
|
274 |
+
*/
|
275 |
+
public function get_trid() {
|
276 |
+
return $this->wpml_service->get_post_trid( $this->get_id() );
|
277 |
+
}
|
278 |
}
|
vendor/toolset/toolset-common/inc/autoloaded/element/post_translation_set.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
/**
|
4 |
* Represents a set of post translations.
|
5 |
*
|
6 |
-
* This class can act as a single post, working as a proxy to one
|
7 |
*
|
8 |
* Each of the interface methods has an additional parameter where a language code may be specified. If it isn't,
|
9 |
* the best available translation will be chosen: current language > default language > original post language.
|
@@ -11,7 +11,7 @@
|
|
11 |
* In all other aspects, these methods act exactly the same way as in Toolset_Post.
|
12 |
*
|
13 |
* Note: It is not possible to instantiate this class when WPML is not active. You should always
|
14 |
-
* use
|
15 |
*
|
16 |
* @since m2m
|
17 |
*/
|
@@ -30,17 +30,46 @@ class Toolset_Post_Translation_Set implements IToolset_Post {
|
|
30 |
private $best_translation_for = array();
|
31 |
|
32 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
33 |
/**
|
34 |
* Toolset_Post_Translation_Set constructor.
|
35 |
*
|
36 |
* @param Toolset_Post[] $translations Array of this post's translations indexed by language codes.
|
37 |
* It doesn't need to be complete, but having these values ready can improve performance.
|
|
|
|
|
|
|
38 |
*
|
39 |
* @since m2m
|
|
|
40 |
*/
|
41 |
-
public function __construct(
|
42 |
-
|
43 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
44 |
throw new RuntimeException( 'Attempted to use a post translation set while WPML was inactive' );
|
45 |
}
|
46 |
|
@@ -50,15 +79,18 @@ class Toolset_Post_Translation_Set implements IToolset_Post {
|
|
50 |
|
51 |
foreach ( $translations as $translation ) {
|
52 |
if ( ! $translation instanceof Toolset_Post ) {
|
53 |
-
$translation =
|
54 |
}
|
55 |
|
56 |
$this->translations[ $translation->get_language() ] = $translation;
|
57 |
}
|
58 |
|
59 |
-
|
60 |
-
|
61 |
-
|
|
|
|
|
|
|
62 |
}
|
63 |
|
64 |
|
@@ -76,9 +108,12 @@ class Toolset_Post_Translation_Set implements IToolset_Post {
|
|
76 |
//
|
77 |
// Notice that $return_original_if_missing is set to false by default, so we'll not get a result that's not
|
78 |
// truly translated.
|
79 |
-
|
|
|
|
|
|
|
|
|
80 |
|
81 |
-
// fixme handle when there's no translation and the same ID is returned as the starting one
|
82 |
return $id;
|
83 |
}
|
84 |
|
@@ -98,7 +133,7 @@ class Toolset_Post_Translation_Set implements IToolset_Post {
|
|
98 |
if ( ! array_key_exists( $language_code, $this->translations ) ) {
|
99 |
$translated_post_id = $this->fetch_translation( $language_code );
|
100 |
if ( $translated_post_id !== 0 ) {
|
101 |
-
$translation =
|
102 |
} else {
|
103 |
$translation = null;
|
104 |
}
|
@@ -124,12 +159,15 @@ class Toolset_Post_Translation_Set implements IToolset_Post {
|
|
124 |
* @return Toolset_Post
|
125 |
*/
|
126 |
private function get_original_translation() {
|
127 |
-
$translated_post_id = $this->fetch_translation(
|
|
|
|
|
|
|
128 |
|
129 |
$post_language_details = apply_filters( 'wpml_post_language_details', null, $translated_post_id );
|
130 |
$language_code = toolset_getarr( $post_language_details, 'language_code' );
|
131 |
|
132 |
-
$translation =
|
133 |
|
134 |
// Store it in cache only if we got a language code. At this point I don't trust anything.
|
135 |
if ( is_string( $language_code ) && ! empty( $language_code ) ) {
|
@@ -152,7 +190,7 @@ class Toolset_Post_Translation_Set implements IToolset_Post {
|
|
152 |
private function get_best_translation( $language_code = null ) {
|
153 |
|
154 |
if ( null === $language_code ) {
|
155 |
-
$language_code =
|
156 |
}
|
157 |
|
158 |
if( array_key_exists( $language_code, $this->best_translation_for ) ) {
|
@@ -162,7 +200,7 @@ class Toolset_Post_Translation_Set implements IToolset_Post {
|
|
162 |
if ( $this->is_translated_to( $language_code ) ) {
|
163 |
$post = $this->get_translation( $language_code );
|
164 |
} else {
|
165 |
-
$default_language =
|
166 |
if ( $this->is_translated_to( $default_language ) ) {
|
167 |
$post = $this->get_translation( $default_language );
|
168 |
} else {
|
@@ -180,9 +218,10 @@ class Toolset_Post_Translation_Set implements IToolset_Post {
|
|
180 |
* @return string One of the Toolset_Field_Utils::get_domains() values.
|
181 |
*/
|
182 |
public function get_domain() {
|
183 |
-
return
|
184 |
}
|
185 |
|
|
|
186 |
/**
|
187 |
* @param null|string $language_code If null, the best translation will be selected automatically.
|
188 |
*
|
@@ -203,7 +242,7 @@ class Toolset_Post_Translation_Set implements IToolset_Post {
|
|
203 |
}
|
204 |
|
205 |
|
206 |
-
|
207 |
* @param null|string $language_code If null, the best translation will be selected automatically.
|
208 |
*
|
209 |
* @return string Post type slug.
|
@@ -226,6 +265,7 @@ class Toolset_Post_Translation_Set implements IToolset_Post {
|
|
226 |
$this->get_best_translation( $language_code )->initialize_fields();
|
227 |
}
|
228 |
|
|
|
229 |
/**
|
230 |
* @param null|string $language_code If null, the best translation will be selected automatically.
|
231 |
*
|
@@ -235,6 +275,7 @@ class Toolset_Post_Translation_Set implements IToolset_Post {
|
|
235 |
return $this->get_best_translation( $language_code )->are_fields_loaded();
|
236 |
}
|
237 |
|
|
|
238 |
/**
|
239 |
* Get the object this model is wrapped around.
|
240 |
*
|
@@ -294,6 +335,7 @@ class Toolset_Post_Translation_Set implements IToolset_Post {
|
|
294 |
return $this->get_best_translation( $language_code )->get_fields();
|
295 |
}
|
296 |
|
|
|
297 |
/**
|
298 |
* @param null|string $language_code If null, the best translation will be selected automatically.
|
299 |
*
|
@@ -308,8 +350,10 @@ class Toolset_Post_Translation_Set implements IToolset_Post {
|
|
308 |
* @return bool
|
309 |
*/
|
310 |
function is_translatable() {
|
311 |
-
//
|
312 |
-
|
|
|
|
|
313 |
}
|
314 |
|
315 |
|
@@ -337,6 +381,7 @@ class Toolset_Post_Translation_Set implements IToolset_Post {
|
|
337 |
return $this->get_best_translation( $language_code )->get_slug();
|
338 |
}
|
339 |
|
|
|
340 |
/**
|
341 |
* @param string $title New post title
|
342 |
*
|
@@ -348,4 +393,99 @@ class Toolset_Post_Translation_Set implements IToolset_Post {
|
|
348 |
public function set_title( $title, $language_code = null ) {
|
349 |
$this->get_best_translation( $language_code )->set_title( $title );
|
350 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
351 |
}
|
3 |
/**
|
4 |
* Represents a set of post translations.
|
5 |
*
|
6 |
+
* This class can act as a single post, working as a proxy to one of its translations.
|
7 |
*
|
8 |
* Each of the interface methods has an additional parameter where a language code may be specified. If it isn't,
|
9 |
* the best available translation will be chosen: current language > default language > original post language.
|
11 |
* In all other aspects, these methods act exactly the same way as in Toolset_Post.
|
12 |
*
|
13 |
* Note: It is not possible to instantiate this class when WPML is not active. You should always
|
14 |
+
* use Toolset_Elemen_Factory::get_post() instead of reinventing its logic elsewhere.
|
15 |
*
|
16 |
* @since m2m
|
17 |
*/
|
30 |
private $best_translation_for = array();
|
31 |
|
32 |
|
33 |
+
/** @var Toolset_WPML_Compatibility */
|
34 |
+
private $wpml_service;
|
35 |
+
|
36 |
+
|
37 |
+
/** @var Toolset_Element_Factory */
|
38 |
+
private $element_factory;
|
39 |
+
|
40 |
+
|
41 |
+
/** @var null|Toolset_Post_Type_Repository */
|
42 |
+
private $_post_type_repository;
|
43 |
+
|
44 |
+
|
45 |
+
/** @var null|int */
|
46 |
+
private $_trid;
|
47 |
+
|
48 |
+
|
49 |
/**
|
50 |
* Toolset_Post_Translation_Set constructor.
|
51 |
*
|
52 |
* @param Toolset_Post[] $translations Array of this post's translations indexed by language codes.
|
53 |
* It doesn't need to be complete, but having these values ready can improve performance.
|
54 |
+
* @param Toolset_WPML_Compatibility|null $wpml_service_di
|
55 |
+
* @param Toolset_Element_Factory|null $element_factory_di
|
56 |
+
* @param Toolset_Post_Type_Repository|null $post_type_repository_di
|
57 |
*
|
58 |
* @since m2m
|
59 |
+
* @throws Toolset_Element_Exception_Element_Doesnt_Exist
|
60 |
*/
|
61 |
+
public function __construct(
|
62 |
+
$translations,
|
63 |
+
Toolset_WPML_Compatibility $wpml_service_di = null,
|
64 |
+
Toolset_Element_Factory $element_factory_di = null,
|
65 |
+
Toolset_Post_Type_Repository $post_type_repository_di = null
|
66 |
+
) {
|
67 |
+
|
68 |
+
$this->wpml_service = ( null === $wpml_service_di ? Toolset_WPML_Compatibility::get_instance() : $wpml_service_di );
|
69 |
+
$this->element_factory = ( null === $element_factory_di ? new Toolset_Element_Factory() : $element_factory_di );
|
70 |
+
$this->_post_type_repository = $post_type_repository_di;
|
71 |
+
|
72 |
+
if ( ! $this->wpml_service->is_wpml_active_and_configured() ) {
|
73 |
throw new RuntimeException( 'Attempted to use a post translation set while WPML was inactive' );
|
74 |
}
|
75 |
|
79 |
|
80 |
foreach ( $translations as $translation ) {
|
81 |
if ( ! $translation instanceof Toolset_Post ) {
|
82 |
+
$translation = $this->element_factory->get_post_untranslated( $translation );
|
83 |
}
|
84 |
|
85 |
$this->translations[ $translation->get_language() ] = $translation;
|
86 |
}
|
87 |
|
88 |
+
if( array_key_exists( $this->wpml_service->get_default_language(), $this->translations ) ) {
|
89 |
+
$this->starting_post_id = $this->translations[ $this->wpml_service->get_default_language() ]->get_id();
|
90 |
+
} else {
|
91 |
+
$some_translation = reset( $this->translations );
|
92 |
+
$this->starting_post_id = $some_translation->get_id();
|
93 |
+
}
|
94 |
}
|
95 |
|
96 |
|
108 |
//
|
109 |
// Notice that $return_original_if_missing is set to false by default, so we'll not get a result that's not
|
110 |
// truly translated.
|
111 |
+
//
|
112 |
+
// P.S.: Can't use get_type() for the third argument because that requires having a
|
113 |
+
// post instance and it could create an infinite recursion. Luckily, WPML interprets the 'any'
|
114 |
+
// type as "any post type".
|
115 |
+
$id = (int) apply_filters( 'wpml_object_id', $this->starting_post_id, 'any', $return_original_if_missing, $language_code );
|
116 |
|
|
|
117 |
return $id;
|
118 |
}
|
119 |
|
133 |
if ( ! array_key_exists( $language_code, $this->translations ) ) {
|
134 |
$translated_post_id = $this->fetch_translation( $language_code );
|
135 |
if ( $translated_post_id !== 0 ) {
|
136 |
+
$translation = $this->element_factory->get_post_untranslated( $translated_post_id, $language_code );
|
137 |
} else {
|
138 |
$translation = null;
|
139 |
}
|
159 |
* @return Toolset_Post
|
160 |
*/
|
161 |
private function get_original_translation() {
|
162 |
+
$translated_post_id = $this->fetch_translation(
|
163 |
+
$this->wpml_service->get_default_language(),
|
164 |
+
true
|
165 |
+
);
|
166 |
|
167 |
$post_language_details = apply_filters( 'wpml_post_language_details', null, $translated_post_id );
|
168 |
$language_code = toolset_getarr( $post_language_details, 'language_code' );
|
169 |
|
170 |
+
$translation = $this->element_factory->get_post_untranslated( $translated_post_id, $language_code );
|
171 |
|
172 |
// Store it in cache only if we got a language code. At this point I don't trust anything.
|
173 |
if ( is_string( $language_code ) && ! empty( $language_code ) ) {
|
190 |
private function get_best_translation( $language_code = null ) {
|
191 |
|
192 |
if ( null === $language_code ) {
|
193 |
+
$language_code = $this->wpml_service->get_current_language();
|
194 |
}
|
195 |
|
196 |
if( array_key_exists( $language_code, $this->best_translation_for ) ) {
|
200 |
if ( $this->is_translated_to( $language_code ) ) {
|
201 |
$post = $this->get_translation( $language_code );
|
202 |
} else {
|
203 |
+
$default_language = $this->wpml_service->get_default_language();
|
204 |
if ( $this->is_translated_to( $default_language ) ) {
|
205 |
$post = $this->get_translation( $default_language );
|
206 |
} else {
|
218 |
* @return string One of the Toolset_Field_Utils::get_domains() values.
|
219 |
*/
|
220 |
public function get_domain() {
|
221 |
+
return Toolset_Element_Domain::POSTS;
|
222 |
}
|
223 |
|
224 |
+
|
225 |
/**
|
226 |
* @param null|string $language_code If null, the best translation will be selected automatically.
|
227 |
*
|
242 |
}
|
243 |
|
244 |
|
245 |
+
/**
|
246 |
* @param null|string $language_code If null, the best translation will be selected automatically.
|
247 |
*
|
248 |
* @return string Post type slug.
|
265 |
$this->get_best_translation( $language_code )->initialize_fields();
|
266 |
}
|
267 |
|
268 |
+
|
269 |
/**
|
270 |
* @param null|string $language_code If null, the best translation will be selected automatically.
|
271 |
*
|
275 |
return $this->get_best_translation( $language_code )->are_fields_loaded();
|
276 |
}
|
277 |
|
278 |
+
|
279 |
/**
|
280 |
* Get the object this model is wrapped around.
|
281 |
*
|
335 |
return $this->get_best_translation( $language_code )->get_fields();
|
336 |
}
|
337 |
|
338 |
+
|
339 |
/**
|
340 |
* @param null|string $language_code If null, the best translation will be selected automatically.
|
341 |
*
|
350 |
* @return bool
|
351 |
*/
|
352 |
function is_translatable() {
|
353 |
+
// Assumption: get_type() is the same for all translations, so it doesn't
|
354 |
+
// matter which one gets picked up. If this doesn't work as expected,
|
355 |
+
// the site has way more serious problems.
|
356 |
+
return $this->wpml_service->is_post_type_translatable( $this->get_type() );
|
357 |
}
|
358 |
|
359 |
|
381 |
return $this->get_best_translation( $language_code )->get_slug();
|
382 |
}
|
383 |
|
384 |
+
|
385 |
/**
|
386 |
* @param string $title New post title
|
387 |
*
|
393 |
public function set_title( $title, $language_code = null ) {
|
394 |
$this->get_best_translation( $language_code )->set_title( $title );
|
395 |
}
|
396 |
+
|
397 |
+
|
398 |
+
protected function get_post_type_repository() {
|
399 |
+
if( null === $this->_post_type_repository ) {
|
400 |
+
$this->_post_type_repository = Toolset_Post_Type_Repository::get_instance();
|
401 |
+
}
|
402 |
+
|
403 |
+
return $this->_post_type_repository;
|
404 |
+
}
|
405 |
+
|
406 |
+
|
407 |
+
/**
|
408 |
+
* @return IToolset_Post_Type|null
|
409 |
+
* @since 2.5.10
|
410 |
+
*/
|
411 |
+
public function get_type_object() {
|
412 |
+
return $this->get_post_type_repository()->get( $this->get_type() );
|
413 |
+
}
|
414 |
+
|
415 |
+
|
416 |
+
/**
|
417 |
+
* Return an element translation.
|
418 |
+
*
|
419 |
+
* If the element domain and type are non-translatable, it will return itself.
|
420 |
+
*
|
421 |
+
* If the element could be translated to the target language but is not,
|
422 |
+
* the return value will depend on the $exact_match_only parameter:
|
423 |
+
* If it's true, it will return null. Otherwise, it will return the best possible
|
424 |
+
* translation (default language/original/any).
|
425 |
+
*
|
426 |
+
* @param string $language_code
|
427 |
+
* @param bool $exact_match_only
|
428 |
+
*
|
429 |
+
* @return IToolset_Element|null
|
430 |
+
*/
|
431 |
+
public function translate( $language_code, $exact_match_only = false ) {
|
432 |
+
if( $exact_match_only && $this->is_translatable() ) {
|
433 |
+
return $this->get_translation( $language_code );
|
434 |
+
} else {
|
435 |
+
return $this->get_best_translation( $language_code );
|
436 |
+
}
|
437 |
+
}
|
438 |
+
|
439 |
+
|
440 |
+
/**
|
441 |
+
* @inheritdoc
|
442 |
+
*
|
443 |
+
* @return int
|
444 |
+
* @since 2.5.10
|
445 |
+
*/
|
446 |
+
public function get_default_language_id() {
|
447 |
+
$translation = $this->get_translation( $this->wpml_service->get_default_language() );
|
448 |
+
if( null === $translation ) {
|
449 |
+
return 0;
|
450 |
+
}
|
451 |
+
|
452 |
+
return $translation->get_id();
|
453 |
+
}
|
454 |
+
|
455 |
+
/**
|
456 |
+
* @param string|null $language_code
|
457 |
+
*
|
458 |
+
* @return bool
|
459 |
+
* @since 2.5.10
|
460 |
+
*/
|
461 |
+
public function is_revision( $language_code = null ) {
|
462 |
+
return $this->get_best_translation( $language_code )->is_revision();
|
463 |
+
}
|
464 |
+
|
465 |
+
|
466 |
+
/**
|
467 |
+
* @inheritdoc
|
468 |
+
*
|
469 |
+
* @param string|null $language_code
|
470 |
+
*
|
471 |
+
* @return int
|
472 |
+
* @since 2.5.11
|
473 |
+
*/
|
474 |
+
public function get_author( $language_code = null ) {
|
475 |
+
return $this->get_best_translation( $language_code )->get_author();
|
476 |
+
}
|
477 |
+
|
478 |
+
|
479 |
+
/**
|
480 |
+
* @inheritdoc
|
481 |
+
*
|
482 |
+
* @return int
|
483 |
+
* @since 2.5.11
|
484 |
+
*/
|
485 |
+
public function get_trid() {
|
486 |
+
if( null === $this->_trid ) {
|
487 |
+
$this->_trid = $this->wpml_service->get_post_trid( $this->starting_post_id );
|
488 |
+
}
|
489 |
+
return $this->_trid;
|
490 |
+
}
|
491 |
}
|
vendor/toolset/toolset-common/inc/autoloaded/field/definition.php
CHANGED
@@ -120,7 +120,9 @@ abstract class Toolset_Field_Definition extends Toolset_Field_Definition_Abstrac
|
|
120 |
if( $this->get_is_required() && !empty( $display_name ) ) {
|
121 |
$display_name .= '*';
|
122 |
}
|
123 |
-
|
|
|
|
|
124 |
}
|
125 |
|
126 |
|
@@ -579,6 +581,13 @@ abstract class Toolset_Field_Definition extends Toolset_Field_Definition_Abstrac
|
|
579 |
}
|
580 |
|
581 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
582 |
/**
|
583 |
* Create an instance of the field for a specific element.
|
584 |
*
|
120 |
if( $this->get_is_required() && !empty( $display_name ) ) {
|
121 |
$display_name .= '*';
|
122 |
}
|
123 |
+
|
124 |
+
// we need to get rid of auto added slashes (WP Core adds them)
|
125 |
+
return stripslashes( $display_name );
|
126 |
}
|
127 |
|
128 |
|
581 |
}
|
582 |
|
583 |
|
584 |
+
/**
|
585 |
+
* @return string Domain where this field belongs to.
|
586 |
+
* @since 2.5.8
|
587 |
+
*/
|
588 |
+
public abstract function get_domain();
|
589 |
+
|
590 |
+
|
591 |
/**
|
592 |
* Create an instance of the field for a specific element.
|
593 |
*
|
vendor/toolset/toolset-common/inc/autoloaded/field/definition_abstract.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
/**
|
4 |
* Abstract of a field definition (common interface and code for generic and Types field definitions).
|
5 |
*/
|
6 |
-
abstract class Toolset_Field_Definition_Abstract {
|
7 |
|
8 |
/**
|
9 |
* @return string Field definition slug.
|
3 |
/**
|
4 |
* Abstract of a field definition (common interface and code for generic and Types field definitions).
|
5 |
*/
|
6 |
+
abstract class Toolset_Field_Definition_Abstract implements Toolset_Field_Definition_Interface {
|
7 |
|
8 |
/**
|
9 |
* @return string Field definition slug.
|
vendor/toolset/toolset-common/inc/autoloaded/field/definition_factory.php
CHANGED
@@ -7,7 +7,7 @@
|
|
7 |
*
|
8 |
* @since 1.9
|
9 |
*/
|
10 |
-
abstract class Toolset_Field_Definition_Factory {
|
11 |
|
12 |
/**
|
13 |
* Singleton parent.
|
@@ -275,9 +275,9 @@ abstract class Toolset_Field_Definition_Factory {
|
|
275 |
|
276 |
/**
|
277 |
* Update the option that stores field definitions for current domain with new value.
|
278 |
-
*
|
279 |
* This is a low-level method. No validation or sanitization is performed whatsoever.
|
280 |
-
*
|
281 |
* @param array $updated_value New value to be stored.
|
282 |
* @since 2.0
|
283 |
*/
|
@@ -333,7 +333,7 @@ abstract class Toolset_Field_Definition_Factory {
|
|
333 |
foreach ( $field_slugs as $slug ) {
|
334 |
$field_definition = $this->load_field_definition( $slug );
|
335 |
if ( null != $field_definition ) {
|
336 |
-
$field_definitions[] = $field_definition;
|
337 |
}
|
338 |
}
|
339 |
|
@@ -629,7 +629,7 @@ abstract class Toolset_Field_Definition_Factory {
|
|
629 |
$slug_to_delete = $field_definiton->get_slug();
|
630 |
$this->erase_field_definition_from_options( $slug_to_delete );
|
631 |
}
|
632 |
-
|
633 |
return $is_success;
|
634 |
}
|
635 |
|
@@ -686,8 +686,8 @@ abstract class Toolset_Field_Definition_Factory {
|
|
686 |
|
687 |
|
688 |
/**
|
689 |
-
* Temporary workaround to access field definitions on a very deep level.
|
690 |
-
*
|
691 |
* @param $field_slug
|
692 |
* @param $definition_array
|
693 |
* @deprecated Do not use, it will be removed.
|
@@ -701,7 +701,7 @@ abstract class Toolset_Field_Definition_Factory {
|
|
701 |
/**
|
702 |
* Temporary workaround to access field definitions on a very deep level.
|
703 |
* Do not use, it will be removed.
|
704 |
-
*
|
705 |
* @return string
|
706 |
* @deprecated Do not use, it will be removed.
|
707 |
* @since 2.1
|
@@ -711,4 +711,4 @@ abstract class Toolset_Field_Definition_Factory {
|
|
711 |
}
|
712 |
|
713 |
|
714 |
-
}
|
7 |
*
|
8 |
* @since 1.9
|
9 |
*/
|
10 |
+
abstract class Toolset_Field_Definition_Factory implements Toolset_Field_Definition_Factory_Interface {
|
11 |
|
12 |
/**
|
13 |
* Singleton parent.
|
275 |
|
276 |
/**
|
277 |
* Update the option that stores field definitions for current domain with new value.
|
278 |
+
*
|
279 |
* This is a low-level method. No validation or sanitization is performed whatsoever.
|
280 |
+
*
|
281 |
* @param array $updated_value New value to be stored.
|
282 |
* @since 2.0
|
283 |
*/
|
333 |
foreach ( $field_slugs as $slug ) {
|
334 |
$field_definition = $this->load_field_definition( $slug );
|
335 |
if ( null != $field_definition ) {
|
336 |
+
$field_definitions[ $slug ] = $field_definition;
|
337 |
}
|
338 |
}
|
339 |
|
629 |
$slug_to_delete = $field_definiton->get_slug();
|
630 |
$this->erase_field_definition_from_options( $slug_to_delete );
|
631 |
}
|
632 |
+
|
633 |
return $is_success;
|
634 |
}
|
635 |
|
686 |
|
687 |
|
688 |
/**
|
689 |
+
* Temporary workaround to access field definitions on a very deep level.
|
690 |
+
*
|
691 |
* @param $field_slug
|
692 |
* @param $definition_array
|
693 |
* @deprecated Do not use, it will be removed.
|
701 |
/**
|
702 |
* Temporary workaround to access field definitions on a very deep level.
|
703 |
* Do not use, it will be removed.
|
704 |
+
*
|
705 |
* @return string
|
706 |
* @deprecated Do not use, it will be removed.
|
707 |
* @since 2.1
|
711 |
}
|
712 |
|
713 |
|
714 |
+
}
|
vendor/toolset/toolset-common/inc/autoloaded/field/definition_factory_interface.php
ADDED
@@ -0,0 +1,212 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Interface for field definitions factory.
|
5 |
+
*
|
6 |
+
* @since 2.3
|
7 |
+
*/
|
8 |
+
interface Toolset_Field_Definition_Factory_Interface {
|
9 |
+
/**
|
10 |
+
* Load an existing field definition.
|
11 |
+
*
|
12 |
+
* For now, we're using legacy code to read fields from the options table.
|
13 |
+
*
|
14 |
+
* Note that field definitions for fields not currently managed by Types may be loaded as well.
|
15 |
+
*
|
16 |
+
* @param string $field_key Key used to store the field configuration in options, or field slug (which should be
|
17 |
+
* equal to the key).
|
18 |
+
*
|
19 |
+
* @return null|Toolset_Field_Definition Field definition or null if it can't be loaded.
|
20 |
+
*/
|
21 |
+
public function load_field_definition( $field_key );
|
22 |
+
|
23 |
+
|
24 |
+
/**
|
25 |
+
* This method is to be used only for bringing existing fields under Types control.
|
26 |
+
*
|
27 |
+
* At this point it is assumed that there doesn't exist any field definition for given meta_key.
|
28 |
+
* See Toolset_Field_Utils::start_managing_field() for details.
|
29 |
+
*
|
30 |
+
* Maybe the usage could be wider, but that is not yet clear from the legacy code. The behaviour is slightly
|
31 |
+
* different for meta_keys with the wpcf- prefix from the ones without it. More details in the code.
|
32 |
+
*
|
33 |
+
* The field will be created as a text field.
|
34 |
+
*
|
35 |
+
* @param string $meta_key Field meta key.
|
36 |
+
*
|
37 |
+
* @return string|false New field slug on success, false otherwise.
|
38 |
+
* @since 2.0
|
39 |
+
*/
|
40 |
+
public function create_field_definition_for_existing_fields( $meta_key );
|
41 |
+
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Removes a single field definition from the storage of existing instances.
|
45 |
+
*
|
46 |
+
* It also completely clears the cache of the (legacy) wpcf_admin_fields_get_fields.
|
47 |
+
* Note that this method is public only temporarily and that this is not a mere cache clearing.
|
48 |
+
*
|
49 |
+
* @param string|null $field_slug If null, the cache will be emptied completely.
|
50 |
+
*/
|
51 |
+
public function clear_definition_storage( $field_slug = null );
|
52 |
+
|
53 |
+
|
54 |
+
/**
|
55 |
+
* Determine if there exists any Types field definition (within the domain) that uses this key.
|
56 |
+
*
|
57 |
+
* @param string $meta_key
|
58 |
+
* @param string [$return='boolean'] For 'boolean', the method simply returns true/false answer, for 'definition'
|
59 |
+
* it returns either the field definition instance or null if no such one exists.
|
60 |
+
*
|
61 |
+
* @return bool|Toolset_Field_Definition|null
|
62 |
+
* @since 1.9
|
63 |
+
*/
|
64 |
+
public function meta_key_belongs_to_types_field( $meta_key, $return = 'boolean' );
|
65 |
+
|
66 |
+
|
67 |
+
/**
|
68 |
+
* @return Toolset_Field_Group_Factory
|
69 |
+
* @since 2.0
|
70 |
+
*/
|
71 |
+
public function get_group_factory();
|
72 |
+
|
73 |
+
|
74 |
+
/**
|
75 |
+
* @return Toolset_Field_Definition_Generic[] Definitions of all generic fields that exist in the database within
|
76 |
+
* current domain.
|
77 |
+
*/
|
78 |
+
public function load_generic_field_definitions();
|
79 |
+
|
80 |
+
|
81 |
+
/**
|
82 |
+
* @return Toolset_Field_Definition_Abstract[] All field definitions (generic and Types-controlled).
|
83 |
+
*/
|
84 |
+
public function load_all_definitions();
|
85 |
+
|
86 |
+
|
87 |
+
/**
|
88 |
+
* Reorder an array of field definitions.
|
89 |
+
*
|
90 |
+
* @param Toolset_Field_Definition_Abstract[] $definitions
|
91 |
+
* @param string $orderby 'name'|'slug'|'is_under_types_control'|'field_type'
|
92 |
+
* @param string $order 'asc'|'desc'
|
93 |
+
*
|
94 |
+
* @return Toolset_Field_Definition_Abstract[] Reordered array.
|
95 |
+
*/
|
96 |
+
public function order_definitions( $definitions, $orderby = 'name', $order = 'asc' );
|
97 |
+
|
98 |
+
|
99 |
+
/**
|
100 |
+
* Compare function for ordering by name in order_definitions().
|
101 |
+
*
|
102 |
+
* @param $first Toolset_Field_Definition_Abstract
|
103 |
+
* @param $second Toolset_Field_Definition_Abstract
|
104 |
+
*
|
105 |
+
* @return int
|
106 |
+
*/
|
107 |
+
public function compare_definitions_by_name( $first, $second );
|
108 |
+
|
109 |
+
|
110 |
+
/**
|
111 |
+
* Compare function for ordering by slug in order_definitions().
|
112 |
+
*
|
113 |
+
* @param $first Toolset_Field_Definition_Abstract
|
114 |
+
* @param $second Toolset_Field_Definition_Abstract
|
115 |
+
*
|
116 |
+
* @return int
|
117 |
+
*/
|
118 |
+
public function compare_definitions_by_slug( $first, $second );
|
119 |
+
|
120 |
+
|
121 |
+
/**
|
122 |
+
* Compare function for ordering by the Types control status in order_definitions().
|
123 |
+
*
|
124 |
+
* @param $first Toolset_Field_Definition_Abstract
|
125 |
+
* @param $second Toolset_Field_Definition_Abstract
|
126 |
+
*
|
127 |
+
* @return int
|
128 |
+
*/
|
129 |
+
public function compare_definition_by_types_control( $first, $second );
|
130 |
+
|
131 |
+
|
132 |
+
/**
|
133 |
+
* Compare function for ordering by field type in order_definitions().
|
134 |
+
*
|
135 |
+
* @param $first Toolset_Field_Definition_Abstract
|
136 |
+
* @param $second Toolset_Field_Definition_Abstract
|
137 |
+
*
|
138 |
+
* @return int
|
139 |
+
*/
|
140 |
+
public function compare_definitions_by_field_type( $first, $second );
|
141 |
+
|
142 |
+
|
143 |
+
/**
|
144 |
+
* Query field definitions.
|
145 |
+
*
|
146 |
+
* @param array $args Following arguments are recognized:
|
147 |
+
*
|
148 |
+
* - filter: What field definitions should be retrieved: 'types'|'generic'|'all'
|
149 |
+
* - orderby: 'name'|'slug'|'is_under_types_control'|'field_type'
|
150 |
+
* - order: 'asc'|'desc'
|
151 |
+
* - search: String for fulltext search.
|
152 |
+
* - field_type: string|array Field type slug(s). Allowed only for Types fields.
|
153 |
+
* - group_id: int Field group ID where this field belongs to. Allowed only for Types fields.
|
154 |
+
* - group_slug: string Slug of an existing firld group where this field belongs to. If defined, overrides
|
155 |
+
* the group_id argument. Allowed only for Types fields.
|
156 |
+
*
|
157 |
+
* @return Toolset_Field_Definition_Abstract[] Field definitions that match query arguments.
|
158 |
+
*
|
159 |
+
* @since 1.9
|
160 |
+
*/
|
161 |
+
public function query_definitions( $args );
|
162 |
+
|
163 |
+
|
164 |
+
/**
|
165 |
+
* Permanently delete field definition.
|
166 |
+
*
|
167 |
+
* That means:
|
168 |
+
* - remove it from all field groups,
|
169 |
+
* - delete field data from the database (sic!) and
|
170 |
+
* - delete the definition itself.
|
171 |
+
*
|
172 |
+
* After calling this method, the field definition object passed as parameter should never be used again.
|
173 |
+
*
|
174 |
+
* @param Toolset_Field_Definition_Abstract $field_definiton
|
175 |
+
*
|
176 |
+
* @return bool
|
177 |
+
*/
|
178 |
+
public function delete_definition( Toolset_Field_Definition_Abstract $field_definiton );
|
179 |
+
|
180 |
+
|
181 |
+
/**
|
182 |
+
* Update existing field definition.
|
183 |
+
*
|
184 |
+
* @param Toolset_Field_Definition_Abstract $field_definition
|
185 |
+
*
|
186 |
+
* @throws InvalidArgumentException
|
187 |
+
* @return bool True when the update was successful, false otherwise.
|
188 |
+
* @since 2.0
|
189 |
+
*/
|
190 |
+
public function update_definition( Toolset_Field_Definition_Abstract $field_definition );
|
191 |
+
|
192 |
+
|
193 |
+
/**
|
194 |
+
* Temporary workaround to access field definitions on a very deep level.
|
195 |
+
*
|
196 |
+
* @param $field_slug
|
197 |
+
* @param $definition_array
|
198 |
+
* @deprecated Do not use, it will be removed.
|
199 |
+
* @since 2.1
|
200 |
+
*/
|
201 |
+
public function set_field_definition_workaround( $field_slug, $definition_array );
|
202 |
+
|
203 |
+
/**
|
204 |
+
* Temporary workaround to access field definitions on a very deep level.
|
205 |
+
* Do not use, it will be removed.
|
206 |
+
*
|
207 |
+
* @return string
|
208 |
+
* @deprecated Do not use, it will be removed.
|
209 |
+
* @since 2.1
|
210 |
+
*/
|
211 |
+
public function get_option_name_workaround();
|
212 |
+
}
|
vendor/toolset/toolset-common/inc/autoloaded/field/definition_factory_post.php
CHANGED
@@ -5,7 +5,7 @@
|
|
5 |
*
|
6 |
* @since 2.0
|
7 |
*/
|
8 |
-
|
9 |
|
10 |
|
11 |
/** Name of the option used to store field definitions. */
|
5 |
*
|
6 |
* @since 2.0
|
7 |
*/
|
8 |
+
class Toolset_Field_Definition_Factory_Post extends Toolset_Field_Definition_Factory {
|
9 |
|
10 |
|
11 |
/** Name of the option used to store field definitions. */
|
vendor/toolset/toolset-common/inc/autoloaded/field/definition_factory_term.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
/**
|
4 |
* Factory for term field definitions.
|
5 |
*/
|
6 |
-
|
7 |
|
8 |
/**
|
9 |
* Name of the option used to store term field definitions.
|
3 |
/**
|
4 |
* Factory for term field definitions.
|
5 |
*/
|
6 |
+
class Toolset_Field_Definition_Factory_Term extends Toolset_Field_Definition_Factory {
|
7 |
|
8 |
/**
|
9 |
* Name of the option used to store term field definitions.
|
vendor/toolset/toolset-common/inc/autoloaded/field/definition_factory_user.php
CHANGED
@@ -5,7 +5,7 @@
|
|
5 |
*
|
6 |
* @since 2.0
|
7 |
*/
|
8 |
-
|
9 |
|
10 |
|
11 |
/** Name of the option used to store field definitions. */
|
5 |
*
|
6 |
* @since 2.0
|
7 |
*/
|
8 |
+
class Toolset_Field_Definition_Factory_User extends Toolset_Field_Definition_Factory {
|
9 |
|
10 |
|
11 |
/** Name of the option used to store field definitions. */
|
vendor/toolset/toolset-common/inc/autoloaded/field/definition_interface.php
ADDED
@@ -0,0 +1,71 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Interface of a field definition
|
5 |
+
*
|
6 |
+
* @since 2.3
|
7 |
+
*/
|
8 |
+
interface Toolset_Field_Definition_Interface {
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @return string Field definition slug.
|
12 |
+
*/
|
13 |
+
public function get_slug();
|
14 |
+
|
15 |
+
|
16 |
+
/**
|
17 |
+
* @return string Field definition display name.
|
18 |
+
*/
|
19 |
+
public function get_name();
|
20 |
+
|
21 |
+
|
22 |
+
/**
|
23 |
+
* @return string Description provided by the user.
|
24 |
+
*/
|
25 |
+
public function get_description();
|
26 |
+
|
27 |
+
|
28 |
+
/**
|
29 |
+
* @return string Meta key used to store values of these fields.
|
30 |
+
*/
|
31 |
+
public function get_meta_key();
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Determine whether the field is currently under Types control.
|
35 |
+
*
|
36 |
+
* @return mixed
|
37 |
+
*/
|
38 |
+
public function is_under_types_control();
|
39 |
+
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @return Toolset_Field_Group[]
|
43 |
+
*/
|
44 |
+
public function get_associated_groups();
|
45 |
+
|
46 |
+
|
47 |
+
/**
|
48 |
+
* Does the field definition match a certain string?
|
49 |
+
*
|
50 |
+
* Searches it's name and slug.
|
51 |
+
*
|
52 |
+
* @param string $search_string
|
53 |
+
* @return bool
|
54 |
+
*/
|
55 |
+
public function is_match( $search_string );
|
56 |
+
|
57 |
+
|
58 |
+
/**
|
59 |
+
* Get field definition data as an associative array for coversion to JSON.
|
60 |
+
*
|
61 |
+
* Doesn't return the JSON string directly because child classes may reuse this method and add their own
|
62 |
+
* properties.
|
63 |
+
*
|
64 |
+
* Guaranteed properties are: isUnderTypesControl, slug, displayName, groups.
|
65 |
+
*
|
66 |
+
* @return array
|
67 |
+
* @since 2.0
|
68 |
+
*/
|
69 |
+
public function to_json();
|
70 |
+
|
71 |
+
}
|
vendor/toolset/toolset-common/inc/autoloaded/field/definition_post.php
CHANGED
@@ -7,7 +7,7 @@
|
|
7 |
*
|
8 |
* @since 2.0
|
9 |
*/
|
10 |
-
|
11 |
|
12 |
/**
|
13 |
* Get an accessor for a specific field instance.
|
@@ -84,4 +84,12 @@ final class Toolset_Field_Definition_Post extends Toolset_Field_Definition {
|
|
84 |
return new Toolset_Field_Instance_Post( $this, $element_id );
|
85 |
}
|
86 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
87 |
}
|
7 |
*
|
8 |
* @since 2.0
|
9 |
*/
|
10 |
+
class Toolset_Field_Definition_Post extends Toolset_Field_Definition {
|
11 |
|
12 |
/**
|
13 |
* Get an accessor for a specific field instance.
|
84 |
return new Toolset_Field_Instance_Post( $this, $element_id );
|
85 |
}
|
86 |
|
87 |
+
|
88 |
+
/**
|
89 |
+
* @return string Domain where this field belongs to.
|
90 |
+
* @since 2.5.8
|
91 |
+
*/
|
92 |
+
public function get_domain() {
|
93 |
+
return Toolset_Element_Domain::POSTS;
|
94 |
+
}
|
95 |
}
|
vendor/toolset/toolset-common/inc/autoloaded/field/definition_term.php
CHANGED
@@ -82,4 +82,12 @@ class Toolset_Field_Definition_Term extends Toolset_Field_Definition {
|
|
82 |
return new Toolset_Field_Instance_Term( $this, $element_id );
|
83 |
}
|
84 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
85 |
}
|
82 |
return new Toolset_Field_Instance_Term( $this, $element_id );
|
83 |
}
|
84 |
|
85 |
+
|
86 |
+
/**
|
87 |
+
* @return string Domain where this field belongs to.
|
88 |
+
* @since 2.5.8
|
89 |
+
*/
|
90 |
+
public function get_domain() {
|
91 |
+
return Toolset_Element_Domain::TERMS;
|
92 |
+
}
|
93 |
}
|
vendor/toolset/toolset-common/inc/autoloaded/field/definition_user.php
CHANGED
@@ -79,4 +79,12 @@ class Toolset_Field_Definition_User extends Toolset_Field_Definition {
|
|
79 |
throw new RuntimeException( 'Not implemented.' );
|
80 |
}
|
81 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
82 |
}
|
79 |
throw new RuntimeException( 'Not implemented.' );
|
80 |
}
|
81 |
|
82 |
+
|
83 |
+
/**
|
84 |
+
* @return string Domain where this field belongs to.
|
85 |
+
* @since 2.5.8
|
86 |
+
*/
|
87 |
+
public function get_domain() {
|
88 |
+
return Toolset_Element_Domain::USERS;
|
89 |
+
}
|
90 |
}
|
vendor/toolset/toolset-common/inc/autoloaded/field/group.php
CHANGED
@@ -38,7 +38,7 @@ abstract class Toolset_Field_Group {
|
|
38 |
/**
|
39 |
* @var WP_Post Post object that represents the field group.
|
40 |
*/
|
41 |
-
|
42 |
|
43 |
|
44 |
/** @var Toolset_Post_Type_Repository|null */
|
@@ -513,7 +513,7 @@ abstract class Toolset_Field_Group {
|
|
513 |
if ( $type_input instanceof IToolset_Post_Type ) {
|
514 |
$post_type_slug = $type_input->get_slug();
|
515 |
$post_type = $type_input;
|
516 |
-
} elseif( is_string( $type_input ) ) {
|
517 |
$post_type_slug = $type_input;
|
518 |
$post_type = null;
|
519 |
} else {
|
38 |
/**
|
39 |
* @var WP_Post Post object that represents the field group.
|
40 |
*/
|
41 |
+
protected $post;
|
42 |
|
43 |
|
44 |
/** @var Toolset_Post_Type_Repository|null */
|
513 |
if ( $type_input instanceof IToolset_Post_Type ) {
|
514 |
$post_type_slug = $type_input->get_slug();
|
515 |
$post_type = $type_input;
|
516 |
+
} elseif( is_string( $type_input ) || is_int( $type_input )) {
|
517 |
$post_type_slug = $type_input;
|
518 |
$post_type = null;
|
519 |
} else {
|
vendor/toolset/toolset-common/inc/autoloaded/files.php
ADDED
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Wrapper for a mockable access to file functions.
|
5 |
+
*
|
6 |
+
* The principle is similar to Toolset_Constants.
|
7 |
+
*
|
8 |
+
* Note: Use this *only* if you need it in unit tests!
|
9 |
+
*
|
10 |
+
* @since 2.5.7
|
11 |
+
*/
|
12 |
+
class Toolset_Files {
|
13 |
+
|
14 |
+
/**
|
15 |
+
* is_file()
|
16 |
+
*
|
17 |
+
* @link http://php.net/manual/en/function.is-file.php
|
18 |
+
* @param string $path
|
19 |
+
* @return bool
|
20 |
+
*/
|
21 |
+
public function is_file( $path ) {
|
22 |
+
return is_file( $path );
|
23 |
+
}
|
24 |
+
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Extract provided context variable, include the file and return the output.
|
28 |
+
*
|
29 |
+
* @param string $filename
|
30 |
+
* @param array $context_vars
|
31 |
+
*
|
32 |
+
* @return string
|
33 |
+
*/
|
34 |
+
public function get_include_file_output( $filename, $context_vars = array() ) {
|
35 |
+
ob_start();
|
36 |
+
extract( $context_vars );
|
37 |
+
include $filename;
|
38 |
+
$output = ob_get_clean();
|
39 |
+
return $output;
|
40 |
+
}
|
41 |
+
|
42 |
+
|
43 |
+
/**
|
44 |
+
* file_get_contents()
|
45 |
+
*
|
46 |
+
* @link http://php.net/manual/en/function.file-get-contents.php
|
47 |
+
* @param string $filename
|
48 |
+
* @return bool|string
|
49 |
+
*/
|
50 |
+
public function file_get_contents( $filename ) {
|
51 |
+
return file_get_contents( $filename );
|
52 |
+
}
|
53 |
+
|
54 |
+
}
|
vendor/toolset/toolset-common/inc/autoloaded/naming_helper.php
CHANGED
@@ -298,7 +298,7 @@ class Toolset_Naming_Helper {
|
|
298 |
get_post_types( array(), 'names' )
|
299 |
);
|
300 |
|
301 |
-
if( in_array( $value, $post_types ) ) {
|
302 |
$conflict = array(
|
303 |
'conflicting_id' => $value,
|
304 |
'message' => sprintf(
|
298 |
get_post_types( array(), 'names' )
|
299 |
);
|
300 |
|
301 |
+
if( in_array( $value, $post_types, true ) ) {
|
302 |
$conflict = array(
|
303 |
'conflicting_id' => $value,
|
304 |
'message' => sprintf(
|
vendor/toolset/toolset-common/inc/autoloaded/post_type/abstract.php
ADDED
@@ -0,0 +1,125 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Shared functionality for all kinds of post types.
|
5 |
+
*
|
6 |
+
* @since 2.5.10
|
7 |
+
*/
|
8 |
+
abstract class Toolset_Post_Type_Abstract implements IToolset_Post_Type {
|
9 |
+
|
10 |
+
|
11 |
+
/** @var Toolset_WPML_Compatibility|null */
|
12 |
+
private $_wpml_compatibility;
|
13 |
+
|
14 |
+
|
15 |
+
/** @var Toolset_Relationship_Query_Factory|null */
|
16 |
+
private $_relationship_definition_query_factory;
|
17 |
+
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Toolset_Post_Type_Abstract constructor.
|
21 |
+
*
|
22 |
+
* @param Toolset_WPML_Compatibility|null $wpml_compatibility_di
|
23 |
+
* @param null|Toolset_Relationship_Query_Factory $relationship_definition_query_factory_di
|
24 |
+
*/
|
25 |
+
public function __construct(
|
26 |
+
Toolset_WPML_Compatibility $wpml_compatibility_di = null,
|
27 |
+
$relationship_definition_query_factory_di = null
|
28 |
+
) {
|
29 |
+
$this->_wpml_compatibility = $wpml_compatibility_di;
|
30 |
+
$this->_relationship_definition_query_factory = $relationship_definition_query_factory_di;
|
31 |
+
}
|
32 |
+
|
33 |
+
|
34 |
+
/**
|
35 |
+
* @return Toolset_WPML_Compatibility
|
36 |
+
*/
|
37 |
+
protected function get_wpml_compatibility() {
|
38 |
+
if( null === $this->_wpml_compatibility ) {
|
39 |
+
$this->_wpml_compatibility = Toolset_WPML_Compatibility::get_instance();
|
40 |
+
}
|
41 |
+
return $this->_wpml_compatibility;
|
42 |
+
}
|
43 |
+
|
44 |
+
|
45 |
+
/**
|
46 |
+
* @return Toolset_Relationship_Query_V2
|
47 |
+
*/
|
48 |
+
protected function get_relationship_definition_query() {
|
49 |
+
if( null === $this->_relationship_definition_query_factory ) {
|
50 |
+
if ( ! apply_filters( 'toolset_is_m2m_enabled', false ) ) {
|
51 |
+
throw new InvalidArgumentException( 'Trying to use m2m functionality without m2m enabled.' );
|
52 |
+
}
|
53 |
+
|
54 |
+
do_action( 'toolset_do_m2m_full_init' );
|
55 |
+
|
56 |
+
$this->_relationship_definition_query_factory = new Toolset_Relationship_Query_Factory();
|
57 |
+
}
|
58 |
+
|
59 |
+
return $this->_relationship_definition_query_factory->relationships_v2();
|
60 |
+
}
|
61 |
+
|
62 |
+
|
63 |
+
/**
|
64 |
+
* @inheritdoc
|
65 |
+
* @return bool
|
66 |
+
*/
|
67 |
+
public function is_translatable() {
|
68 |
+
return $this->get_wpml_compatibility()->is_post_type_translatable( $this->get_slug() );
|
69 |
+
}
|
70 |
+
|
71 |
+
|
72 |
+
/**
|
73 |
+
* @inheritdoc
|
74 |
+
* @return bool
|
75 |
+
*/
|
76 |
+
public function is_in_display_as_translated_mode() {
|
77 |
+
return $this->get_wpml_compatibility()->is_post_type_display_as_translated( $this->get_slug() );
|
78 |
+
}
|
79 |
+
|
80 |
+
/**
|
81 |
+
* @inheritdoc
|
82 |
+
* @return bool
|
83 |
+
*/
|
84 |
+
public function can_be_used_in_relationship() {
|
85 |
+
if( ! $this->get_wpml_compatibility()->is_wpml_active_and_configured() ) {
|
86 |
+
// no wpml = no limitations on relationships
|
87 |
+
return true;
|
88 |
+
}
|
89 |
+
|
90 |
+
if( ! $this->is_translatable() ) {
|
91 |
+
// no translation mode selected = all good
|
92 |
+
return true;
|
93 |
+
}
|
94 |
+
|
95 |
+
if( $this->is_in_display_as_translated_mode() ) {
|
96 |
+
// "display as translated" mode selected = all good
|
97 |
+
return true;
|
98 |
+
}
|
99 |
+
|
100 |
+
return false;
|
101 |
+
}
|
102 |
+
|
103 |
+
|
104 |
+
/**
|
105 |
+
* @inheritdoc
|
106 |
+
*
|
107 |
+
* Note: This operation may be rather expensive.
|
108 |
+
*
|
109 |
+
* @return bool
|
110 |
+
*/
|
111 |
+
public function is_involved_in_relationship() {
|
112 |
+
if( $this->is_intermediary() ) {
|
113 |
+
return true;
|
114 |
+
}
|
115 |
+
|
116 |
+
$query = $this->get_relationship_definition_query();
|
117 |
+
|
118 |
+
$results = $query
|
119 |
+
->add( $query->has_domain_and_type( $this->get_slug(), Toolset_Element_Domain::POSTS ) )
|
120 |
+
->get_results();
|
121 |
+
|
122 |
+
return ( count( $results ) > 0 );
|
123 |
+
}
|
124 |
+
|
125 |
+
}
|
vendor/toolset/toolset-common/inc/autoloaded/post_type/excluded_list.php
CHANGED
@@ -10,6 +10,7 @@ class Toolset_Post_Type_Exclude_List {
|
|
10 |
private static $initial_list = array(
|
11 |
'cred-form',
|
12 |
'cred-user-form',
|
|
|
13 |
'custom_css',
|
14 |
'customize_changeset',
|
15 |
'dd_layouts',
|
10 |
private static $initial_list = array(
|
11 |
'cred-form',
|
12 |
'cred-user-form',
|
13 |
+
'cred_rel_form',
|
14 |
'custom_css',
|
15 |
'customize_changeset',
|
16 |
'dd_layouts',
|
vendor/toolset/toolset-common/inc/autoloaded/post_type/from_types.php
CHANGED
@@ -10,7 +10,7 @@
|
|
10 |
*
|
11 |
* @since m2m
|
12 |
*/
|
13 |
-
class Toolset_Post_Type_From_Types implements IToolset_Post_Type_From_Types {
|
14 |
|
15 |
/** @var string Post type slug */
|
16 |
private $slug;
|
@@ -50,6 +50,11 @@ class Toolset_Post_Type_From_Types implements IToolset_Post_Type_From_Types {
|
|
50 |
|
51 |
const DEF_PUBLIC = 'public';
|
52 |
|
|
|
|
|
|
|
|
|
|
|
53 |
|
54 |
/**
|
55 |
* Toolset_Post_Type_From_Types constructor.
|
@@ -59,11 +64,16 @@ class Toolset_Post_Type_From_Types implements IToolset_Post_Type_From_Types {
|
|
59 |
* @param IToolset_Post_Type_Registered|null $registered_post_type If the post type is registered on the site,
|
60 |
* this must not be null.
|
61 |
* @param Toolset_Constants|null $constants_di
|
|
|
62 |
*/
|
63 |
public function __construct(
|
64 |
-
$slug, $definition,
|
65 |
-
|
|
|
|
|
66 |
) {
|
|
|
|
|
67 |
$this->slug = $slug;
|
68 |
|
69 |
/**
|
@@ -442,6 +452,30 @@ class Toolset_Post_Type_From_Types implements IToolset_Post_Type_From_Types {
|
|
442 |
}
|
443 |
|
444 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
445 |
/**
|
446 |
* Set the flag indicating whether this post type acts as a repeating field group.
|
447 |
*
|
@@ -449,6 +483,9 @@ class Toolset_Post_Type_From_Types implements IToolset_Post_Type_From_Types {
|
|
449 |
*/
|
450 |
public function set_is_repeating_field_group( $value ) {
|
451 |
$this->set_flag_to_definition( self::DEF_IS_REPEATING_FIELD_GROUP, (bool) $value );
|
|
|
|
|
|
|
452 |
$this->set_is_public( false );
|
453 |
}
|
454 |
|
10 |
*
|
11 |
* @since m2m
|
12 |
*/
|
13 |
+
class Toolset_Post_Type_From_Types extends Toolset_Post_Type_Abstract implements IToolset_Post_Type_From_Types {
|
14 |
|
15 |
/** @var string Post type slug */
|
16 |
private $slug;
|
50 |
|
51 |
const DEF_PUBLIC = 'public';
|
52 |
|
53 |
+
const DEF_DISABLED = 'disabled';
|
54 |
+
|
55 |
+
// Do not rename this value, it's hardcoded in Types (because of timing issues).
|
56 |
+
const DEF_NEEDS_FLUSH_REWRITE_RULES = '_needs_flush_rewrite_rules';
|
57 |
+
|
58 |
|
59 |
/**
|
60 |
* Toolset_Post_Type_From_Types constructor.
|
64 |
* @param IToolset_Post_Type_Registered|null $registered_post_type If the post type is registered on the site,
|
65 |
* this must not be null.
|
66 |
* @param Toolset_Constants|null $constants_di
|
67 |
+
* @param Toolset_WPML_Compatibility|null $wpml_compatibility_di
|
68 |
*/
|
69 |
public function __construct(
|
70 |
+
$slug, $definition,
|
71 |
+
IToolset_Post_Type_Registered $registered_post_type = null,
|
72 |
+
Toolset_Constants $constants_di = null,
|
73 |
+
Toolset_WPML_Compatibility $wpml_compatibility_di = null
|
74 |
) {
|
75 |
+
parent::__construct( $wpml_compatibility_di );
|
76 |
+
|
77 |
$this->slug = $slug;
|
78 |
|
79 |
/**
|
452 |
}
|
453 |
|
454 |
|
455 |
+
/**
|
456 |
+
* @inheritdoc
|
457 |
+
* @return bool
|
458 |
+
*/
|
459 |
+
public function is_disabled() {
|
460 |
+
return (
|
461 |
+
'1' === toolset_getarr( $this->definition, self::DEF_DISABLED, '', array( '1', '' ) )
|
462 |
+
);
|
463 |
+
}
|
464 |
+
|
465 |
+
|
466 |
+
/**
|
467 |
+
* Set the 'disabled' option of the post type.
|
468 |
+
*
|
469 |
+
* @param bool $value
|
470 |
+
*/
|
471 |
+
public function set_is_disabled( $value ) {
|
472 |
+
if( $value ){
|
473 |
+
$this->definition[ self::DEF_DISABLED ] = '1';
|
474 |
+
} else {
|
475 |
+
unset( $this->definition[ self::DEF_DISABLED ] );
|
476 |
+
}
|
477 |
+
}
|
478 |
+
|
479 |
/**
|
480 |
* Set the flag indicating whether this post type acts as a repeating field group.
|
481 |
*
|
483 |
*/
|
484 |
public function set_is_repeating_field_group( $value ) {
|
485 |
$this->set_flag_to_definition( self::DEF_IS_REPEATING_FIELD_GROUP, (bool) $value );
|
486 |
+
if ( $value ) {
|
487 |
+
$this->definition['supports'] = array( 'post_title', 'author', 'custom-fields', 'revisions' );
|
488 |
+
}
|
489 |
$this->set_is_public( false );
|
490 |
}
|
491 |
|
vendor/toolset/toolset-common/inc/autoloaded/post_type/i_post_type.php
CHANGED
@@ -98,4 +98,41 @@ interface IToolset_Post_Type {
|
|
98 |
*/
|
99 |
public function allows_field_group( Toolset_Field_Group $field_group );
|
100 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
101 |
}
|
98 |
*/
|
99 |
public function allows_field_group( Toolset_Field_Group $field_group );
|
100 |
|
101 |
+
|
102 |
+
/**
|
103 |
+
* Check if the post type is translatable by WPML.
|
104 |
+
*
|
105 |
+
* @return bool
|
106 |
+
* @since 2.5.10
|
107 |
+
*/
|
108 |
+
public function is_translatable();
|
109 |
+
|
110 |
+
|
111 |
+
/**
|
112 |
+
* Check if the post type is translatable and has the "display as translated" mode.
|
113 |
+
*
|
114 |
+
* @return bool
|
115 |
+
* @since 2.5.10
|
116 |
+
*/
|
117 |
+
public function is_in_display_as_translated_mode();
|
118 |
+
|
119 |
+
|
120 |
+
/**
|
121 |
+
* Check if the post type can be used in a relationship.
|
122 |
+
*
|
123 |
+
* @return bool
|
124 |
+
* @since 2.5.10
|
125 |
+
*/
|
126 |
+
public function can_be_used_in_relationship();
|
127 |
+
|
128 |
+
|
129 |
+
/**
|
130 |
+
* Check if the post type is already used in an existing relationship.
|
131 |
+
*
|
132 |
+
* Needs m2m.
|
133 |
+
*
|
134 |
+
* @return bool
|
135 |
+
* @since 2.5.11
|
136 |
+
*/
|
137 |
+
public function is_involved_in_relationship();
|
138 |
}
|
vendor/toolset/toolset-common/inc/autoloaded/post_type/i_post_type_from_types.php
CHANGED
@@ -62,4 +62,26 @@ interface IToolset_Post_Type_From_Types extends IToolset_Post_Type {
|
|
62 |
* @param string $new_value
|
63 |
*/
|
64 |
public function set_slug( $new_value );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
65 |
}
|
62 |
* @param string $new_value
|
63 |
*/
|
64 |
public function set_slug( $new_value );
|
65 |
+
|
66 |
+
|
67 |
+
/**
|
68 |
+
* Set the 'public' option of the post type.
|
69 |
+
*
|
70 |
+
* @param bool $value
|
71 |
+
*/
|
72 |
+
public function set_is_public( $value );
|
73 |
+
|
74 |
+
|
75 |
+
/**
|
76 |
+
* Set the 'disabled' option of the post type.
|
77 |
+
*
|
78 |
+
* @param bool $value
|
79 |
+
*/
|
80 |
+
public function set_is_disabled( $value );
|
81 |
+
|
82 |
+
|
83 |
+
/**
|
84 |
+
* @return bool Corresponds with the disabled status of the post type.
|
85 |
+
*/
|
86 |
+
public function is_disabled();
|
87 |
}
|
vendor/toolset/toolset-common/inc/autoloaded/post_type/query.php
CHANGED
@@ -15,6 +15,7 @@
|
|
15 |
* for arbitrary use like standard post types)? If there's no query for this, is_intermediary
|
16 |
* or is_repeating_field_group, this query argument defaults to false. Providing null will return
|
17 |
* both special and non-special post types.
|
|
|
18 |
*
|
19 |
* Feel free to extend this with new query arguments.
|
20 |
*
|
@@ -30,6 +31,8 @@ class Toolset_Post_Type_Query {
|
|
30 |
const IS_EXCLUDED = 'is_excluded';
|
31 |
const IS_PUBLIC = 'is_public';
|
32 |
const IS_REGISTERED = 'is_registered';
|
|
|
|
|
33 |
|
34 |
const RETURN_TYPE = 'return';
|
35 |
|
@@ -96,7 +99,15 @@ class Toolset_Post_Type_Query {
|
|
96 |
self::IS_REGISTERED => array(
|
97 |
'callback' => array( $this, 'filter_bool_property' ),
|
98 |
'filter_args' => 'is_registered'
|
99 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
100 |
);
|
101 |
|
102 |
$this->post_type_repository = (
|
15 |
* for arbitrary use like standard post types)? If there's no query for this, is_intermediary
|
16 |
* or is_repeating_field_group, this query argument defaults to false. Providing null will return
|
17 |
* both special and non-special post types.
|
18 |
+
* ...
|
19 |
*
|
20 |
* Feel free to extend this with new query arguments.
|
21 |
*
|
31 |
const IS_EXCLUDED = 'is_excluded';
|
32 |
const IS_PUBLIC = 'is_public';
|
33 |
const IS_REGISTERED = 'is_registered';
|
34 |
+
const IS_INVOLVED_IN_RELATIONSHIP = 'is_involved_in_relationship';
|
35 |
+
const IS_TRANSLATABLE = 'is_translatable';
|
36 |
|
37 |
const RETURN_TYPE = 'return';
|
38 |
|
99 |
self::IS_REGISTERED => array(
|
100 |
'callback' => array( $this, 'filter_bool_property' ),
|
101 |
'filter_args' => 'is_registered'
|
102 |
+
),
|
103 |
+
self::IS_INVOLVED_IN_RELATIONSHIP => array(
|
104 |
+
'callback' => array( $this, 'filter_bool_property' ),
|
105 |
+
'filter_args' => 'is_involved_in_relationship'
|
106 |
+
),
|
107 |
+
self::IS_TRANSLATABLE => array(
|
108 |
+
'callback' => array( $this, 'filter_bool_property' ),
|
109 |
+
'filter_args' => 'is_translatable'
|
110 |
+
),
|
111 |
);
|
112 |
|
113 |
$this->post_type_repository = (
|
vendor/toolset/toolset-common/inc/autoloaded/post_type/registered.php
CHANGED
@@ -7,7 +7,7 @@
|
|
7 |
*
|
8 |
* @since m2m
|
9 |
*/
|
10 |
-
class Toolset_Post_Type_Registered implements IToolset_Post_Type_Registered {
|
11 |
|
12 |
|
13 |
/** @var WP_Post_Type */
|
@@ -21,8 +21,10 @@ class Toolset_Post_Type_Registered implements IToolset_Post_Type_Registered {
|
|
21 |
* Toolset_Post_Type_Registered constructor.
|
22 |
*
|
23 |
* @param WP_Post_Type $wp_post_type The core object representing the post type.
|
|
|
24 |
*/
|
25 |
-
public function __construct( WP_Post_Type $wp_post_type ) {
|
|
|
26 |
$this->wp_post_type = $wp_post_type;
|
27 |
}
|
28 |
|
7 |
*
|
8 |
* @since m2m
|
9 |
*/
|
10 |
+
class Toolset_Post_Type_Registered extends Toolset_Post_Type_Abstract implements IToolset_Post_Type_Registered {
|
11 |
|
12 |
|
13 |
/** @var WP_Post_Type */
|
21 |
* Toolset_Post_Type_Registered constructor.
|
22 |
*
|
23 |
* @param WP_Post_Type $wp_post_type The core object representing the post type.
|
24 |
+
* @param Toolset_WPML_Compatibility|null $wpml_compatibility_di
|
25 |
*/
|
26 |
+
public function __construct( WP_Post_Type $wp_post_type, Toolset_WPML_Compatibility $wpml_compatibility_di = null ) {
|
27 |
+
parent::__construct( $wpml_compatibility_di );
|
28 |
$this->wp_post_type = $wp_post_type;
|
29 |
}
|
30 |
|
vendor/toolset/toolset-common/inc/autoloaded/post_type/repository.php
CHANGED
@@ -240,12 +240,13 @@ class Toolset_Post_Type_Repository {
|
|
240 |
// wpcf_custom_types_register_translation( $post_type, $definition );
|
241 |
// }
|
242 |
|
243 |
-
// Note: this has to run on the next page load
|
244 |
-
// flush_rewrite_rules();
|
245 |
-
|
246 |
$custom_types = get_option( self::POST_TYPES_OPTION_NAME, array() );
|
247 |
|
248 |
$post_type_definition = $post_type->get_definition();
|
|
|
|
|
|
|
|
|
249 |
$custom_types[ $post_type->get_slug() ] = $post_type_definition;
|
250 |
|
251 |
update_option( self::POST_TYPES_OPTION_NAME, $custom_types, true );
|
@@ -370,6 +371,9 @@ class Toolset_Post_Type_Repository {
|
|
370 |
)
|
371 |
);
|
372 |
|
|
|
|
|
|
|
373 |
if( $wpdb->last_error ) {
|
374 |
throw new RuntimeException( 'The posts could not be updated: ' . $wpdb->last_error );
|
375 |
}
|
240 |
// wpcf_custom_types_register_translation( $post_type, $definition );
|
241 |
// }
|
242 |
|
|
|
|
|
|
|
243 |
$custom_types = get_option( self::POST_TYPES_OPTION_NAME, array() );
|
244 |
|
245 |
$post_type_definition = $post_type->get_definition();
|
246 |
+
|
247 |
+
// Signal Types to run flush_rewrite_rules() after registering the post type.
|
248 |
+
$post_type_definition[ Toolset_Post_Type_From_Types::DEF_NEEDS_FLUSH_REWRITE_RULES ] = true;
|
249 |
+
|
250 |
$custom_types[ $post_type->get_slug() ] = $post_type_definition;
|
251 |
|
252 |
update_option( self::POST_TYPES_OPTION_NAME, $custom_types, true );
|
371 |
)
|
372 |
);
|
373 |
|
374 |
+
// announce to Types that a post type has been renamed
|
375 |
+
do_action( 'wpcf_post_type_renamed', $new_slug, $old_slug );
|
376 |
+
|
377 |
if( $wpdb->last_error ) {
|
378 |
throw new RuntimeException( 'The posts could not be updated: ' . $wpdb->last_error );
|
379 |
}
|
vendor/toolset/toolset-common/inc/autoloaded/relationship_service.php
CHANGED
@@ -63,6 +63,10 @@ class Toolset_Relationship_Service {
|
|
63 |
$child_id,
|
64 |
$parent_slug = null
|
65 |
) {
|
|
|
|
|
|
|
|
|
66 |
$qry_args = array(
|
67 |
Toolset_Association_Query::QUERY_RELATIONSHIP_SLUG => $relationship->get_slug(),
|
68 |
Toolset_Association_Query::QUERY_CHILD_ID => $child_id,
|
@@ -90,6 +94,10 @@ class Toolset_Relationship_Service {
|
|
90 |
$parent_id,
|
91 |
$child_slug = null
|
92 |
) {
|
|
|
|
|
|
|
|
|
93 |
$qry_args = array(
|
94 |
Toolset_Association_Query::QUERY_RELATIONSHIP_SLUG => $relationship->get_slug(),
|
95 |
Toolset_Association_Query::QUERY_PARENT_ID => $parent_id,
|
@@ -113,6 +121,10 @@ class Toolset_Relationship_Service {
|
|
113 |
*
|
114 |
*/
|
115 |
public function find_intermediary_by_relationship_and_child_id( IToolset_Relationship_Definition $relationship, $post_id ) {
|
|
|
|
|
|
|
|
|
116 |
$qry_args = array(
|
117 |
Toolset_Association_Query::QUERY_RELATIONSHIP_SLUG => $relationship->get_slug(),
|
118 |
Toolset_Association_Query::QUERY_CHILD_ID => $post_id,
|
@@ -132,6 +144,10 @@ class Toolset_Relationship_Service {
|
|
132 |
*
|
133 |
*/
|
134 |
public function find_intermediary_by_relationship_and_parent_id( IToolset_Relationship_Definition $relationship, $post_id ) {
|
|
|
|
|
|
|
|
|
135 |
$qry_args = array(
|
136 |
Toolset_Association_Query::QUERY_RELATIONSHIP_SLUG => $relationship->get_slug(),
|
137 |
Toolset_Association_Query::QUERY_PARENT_ID => $post_id,
|
@@ -170,9 +186,13 @@ class Toolset_Relationship_Service {
|
|
170 |
* @internal param string $child_slug
|
171 |
*/
|
172 |
public function find_children_ids_by_parent_id( $parent_id, $children_args = array() ) {
|
|
|
|
|
|
|
|
|
173 |
$children_args = wp_parse_args( $children_args, array(
|
174 |
'post_type' => 'any',
|
175 |
-
'post_status' => '
|
176 |
'numberposts' => -1,
|
177 |
'suppress_filters' => 0,
|
178 |
) );
|
@@ -193,7 +213,7 @@ class Toolset_Relationship_Service {
|
|
193 |
*/
|
194 |
public function find_associations_by_id( $post_id ) {
|
195 |
if( ! $this->is_m2m_enabled() ) {
|
196 |
-
return
|
197 |
}
|
198 |
|
199 |
$associations_parent = $this->find_associations_by_parent_id( $post_id );
|
@@ -252,7 +272,7 @@ class Toolset_Relationship_Service {
|
|
252 |
*/
|
253 |
public function find_parents_by_child_id_and_parent_slug( $child_id, $parent_slug ) {
|
254 |
if( ! $this->is_m2m_enabled() ) {
|
255 |
-
return
|
256 |
}
|
257 |
|
258 |
$associations = $this->find_associations_by_child_id( $child_id );
|
@@ -285,6 +305,10 @@ class Toolset_Relationship_Service {
|
|
285 |
* @return bool|int
|
286 |
*/
|
287 |
public function legacy_find_parent_id_by_child_id_and_parent_slug( $child_id, $parent_slug ) {
|
|
|
|
|
|
|
|
|
288 |
$parent_slug = sanitize_title( $parent_slug );
|
289 |
|
290 |
$option_key = '_wpcf_belongs_' . $parent_slug . '_id';
|
63 |
$child_id,
|
64 |
$parent_slug = null
|
65 |
) {
|
66 |
+
if( ! $this->is_m2m_enabled() ) {
|
67 |
+
return false;
|
68 |
+
}
|
69 |
+
|
70 |
$qry_args = array(
|
71 |
Toolset_Association_Query::QUERY_RELATIONSHIP_SLUG => $relationship->get_slug(),
|
72 |
Toolset_Association_Query::QUERY_CHILD_ID => $child_id,
|
94 |
$parent_id,
|
95 |
$child_slug = null
|
96 |
) {
|
97 |
+
if( ! $this->is_m2m_enabled() ) {
|
98 |
+
return false;
|
99 |
+
}
|
100 |
+
|
101 |
$qry_args = array(
|
102 |
Toolset_Association_Query::QUERY_RELATIONSHIP_SLUG => $relationship->get_slug(),
|
103 |
Toolset_Association_Query::QUERY_PARENT_ID => $parent_id,
|
121 |
*
|
122 |
*/
|
123 |
public function find_intermediary_by_relationship_and_child_id( IToolset_Relationship_Definition $relationship, $post_id ) {
|
124 |
+
if( ! $this->is_m2m_enabled() ) {
|
125 |
+
return false;
|
126 |
+
}
|
127 |
+
|
128 |
$qry_args = array(
|
129 |
Toolset_Association_Query::QUERY_RELATIONSHIP_SLUG => $relationship->get_slug(),
|
130 |
Toolset_Association_Query::QUERY_CHILD_ID => $post_id,
|
144 |
*
|
145 |
*/
|
146 |
public function find_intermediary_by_relationship_and_parent_id( IToolset_Relationship_Definition $relationship, $post_id ) {
|
147 |
+
if( ! $this->is_m2m_enabled() ) {
|
148 |
+
return false;
|
149 |
+
}
|
150 |
+
|
151 |
$qry_args = array(
|
152 |
Toolset_Association_Query::QUERY_RELATIONSHIP_SLUG => $relationship->get_slug(),
|
153 |
Toolset_Association_Query::QUERY_PARENT_ID => $post_id,
|
186 |
* @internal param string $child_slug
|
187 |
*/
|
188 |
public function find_children_ids_by_parent_id( $parent_id, $children_args = array() ) {
|
189 |
+
if( ! $this->is_m2m_enabled() ) {
|
190 |
+
return false;
|
191 |
+
}
|
192 |
+
|
193 |
$children_args = wp_parse_args( $children_args, array(
|
194 |
'post_type' => 'any',
|
195 |
+
'post_status' => 'publish',
|
196 |
'numberposts' => -1,
|
197 |
'suppress_filters' => 0,
|
198 |
) );
|
213 |
*/
|
214 |
public function find_associations_by_id( $post_id ) {
|
215 |
if( ! $this->is_m2m_enabled() ) {
|
216 |
+
return array();
|
217 |
}
|
218 |
|
219 |
$associations_parent = $this->find_associations_by_parent_id( $post_id );
|
272 |
*/
|
273 |
public function find_parents_by_child_id_and_parent_slug( $child_id, $parent_slug ) {
|
274 |
if( ! $this->is_m2m_enabled() ) {
|
275 |
+
return array();
|
276 |
}
|
277 |
|
278 |
$associations = $this->find_associations_by_child_id( $child_id );
|
305 |
* @return bool|int
|
306 |
*/
|
307 |
public function legacy_find_parent_id_by_child_id_and_parent_slug( $child_id, $parent_slug ) {
|
308 |
+
if( ! $this->is_m2m_enabled() ) {
|
309 |
+
return false;
|
310 |
+
}
|
311 |
+
|
312 |
$parent_slug = sanitize_title( $parent_slug );
|
313 |
|
314 |
$option_key = '_wpcf_belongs_' . $parent_slug . '_id';
|
vendor/toolset/toolset-common/inc/autoloaded/renderer/output_template/abstract.php
ADDED
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Common functionality for all template types.
|
5 |
+
*
|
6 |
+
* @since 2.5.9
|
7 |
+
*/
|
8 |
+
abstract class Toolset_Output_Template implements IToolset_Output_Template {
|
9 |
+
|
10 |
+
|
11 |
+
/** @var string */
|
12 |
+
protected $base_path;
|
13 |
+
|
14 |
+
|
15 |
+
/** @var string */
|
16 |
+
protected $template_name;
|
17 |
+
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Toolset_Output_Template constructor.
|
21 |
+
*
|
22 |
+
* @param string $base_path
|
23 |
+
* @param string $template_name
|
24 |
+
*/
|
25 |
+
public function __construct( $base_path, $template_name ) {
|
26 |
+
$this->base_path = $base_path;
|
27 |
+
$this->template_name = $template_name;
|
28 |
+
}
|
29 |
+
|
30 |
+
|
31 |
+
/**
|
32 |
+
* @inheritdoc
|
33 |
+
* @return string
|
34 |
+
*/
|
35 |
+
public function get_full_path() {
|
36 |
+
return trailingslashit( $this->base_path ) . $this->template_name;
|
37 |
+
}
|
38 |
+
|
39 |
+
|
40 |
+
/**
|
41 |
+
* @inheritdoc
|
42 |
+
* @return string
|
43 |
+
*/
|
44 |
+
public function get_name() {
|
45 |
+
return $this->template_name;
|
46 |
+
}
|
47 |
+
|
48 |
+
}
|
vendor/toolset/toolset-common/inc/autoloaded/renderer/output_template/interface.php
ADDED
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Interface for output templates.
|
5 |
+
*
|
6 |
+
* See Toolset_Renderer for detailed usage instructions.
|
7 |
+
*
|
8 |
+
* @since 2.5.9
|
9 |
+
*/
|
10 |
+
interface IToolset_Output_Template {
|
11 |
+
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @return string Full path to the template file.
|
15 |
+
*/
|
16 |
+
public function get_full_path();
|
17 |
+
|
18 |
+
|
19 |
+
/**
|
20 |
+
* @return string Name of the template.
|
21 |
+
*/
|
22 |
+
public function get_name();
|
23 |
+
}
|
vendor/toolset/toolset-common/inc/autoloaded/renderer/output_template/phtml.php
ADDED
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Template for static files.
|
5 |
+
*
|
6 |
+
* @since 2.5.9
|
7 |
+
*/
|
8 |
+
class Toolset_Output_Template_Phtml extends Toolset_Output_Template {
|
9 |
+
|
10 |
+
|
11 |
+
const FILE_EXTENSION = '.phtml';
|
12 |
+
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Toolset_Output_Template_Phtml constructor.
|
16 |
+
*
|
17 |
+
* @param string $base_path
|
18 |
+
* @param string $template_name
|
19 |
+
* @throws InvalidArgumentException Thrown if a file with a wrong suffix is provided.
|
20 |
+
*/
|
21 |
+
public function __construct( $base_path, $template_name ) {
|
22 |
+
|
23 |
+
if( self::FILE_EXTENSION !== substr( $template_name, - strlen( self::FILE_EXTENSION ) ) ) {
|
24 |
+
throw new InvalidArgumentException( 'Provided template file is not a PHTML.' );
|
25 |
+
}
|
26 |
+
|
27 |
+
parent::__construct( $base_path, $template_name );
|
28 |
+
}
|
29 |
+
}
|
vendor/toolset/toolset-common/inc/autoloaded/renderer/output_template/static.php
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Template for static files.
|
5 |
+
*
|
6 |
+
* Nothing to do here, we just use a different class to recognize the template type.
|
7 |
+
*
|
8 |
+
* @since 2.5.9
|
9 |
+
*/
|
10 |
+
class Toolset_Output_Template_Static extends Toolset_Output_Template {
|
11 |
+
|
12 |
+
}
|
vendor/toolset/toolset-common/inc/autoloaded/renderer/output_template/twig.php
ADDED
@@ -0,0 +1,70 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Template for Twig templates.
|
5 |
+
*
|
6 |
+
* @since 2.5.9
|
7 |
+
*/
|
8 |
+
class Toolset_Output_Template_Twig extends Toolset_Output_Template {
|
9 |
+
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @var array Namespaces that the Twig environment requires to render this template properly.
|
13 |
+
*/
|
14 |
+
private $twig_namespaces;
|
15 |
+
|
16 |
+
|
17 |
+
/**
|
18 |
+
* @var null|string Hash created from the requirements for Twig environment,
|
19 |
+
* which allows to reuse these environments.
|
20 |
+
*/
|
21 |
+
private $environment_hash = null;
|
22 |
+
|
23 |
+
|
24 |
+
const FILE_EXTENSION = '.twig';
|
25 |
+
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Toolset_Output_Template_Twig constructor.
|
29 |
+
*
|
30 |
+
* @param string $base_path
|
31 |
+
* @param string $template_name
|
32 |
+
* @param array $twig_namespaces
|
33 |
+
* @throws InvalidArgumentException if a file with a wrong suffix is provided.
|
34 |
+
*/
|
35 |
+
public function __construct( $base_path, $template_name, $twig_namespaces = array() ) {
|
36 |
+
|
37 |
+
if( self::FILE_EXTENSION !== substr( $template_name, - strlen( self::FILE_EXTENSION ) ) ) {
|
38 |
+
throw new InvalidArgumentException( 'Provided template file is not a Twig template.' );
|
39 |
+
}
|
40 |
+
|
41 |
+
parent::__construct( $base_path, $template_name );
|
42 |
+
|
43 |
+
$this->twig_namespaces = toolset_ensarr( $twig_namespaces );
|
44 |
+
}
|
45 |
+
|
46 |
+
|
47 |
+
/**
|
48 |
+
* @return array Get the namespaces required for the Twig environment.
|
49 |
+
*/
|
50 |
+
public function get_twig_namespaces() {
|
51 |
+
return $this->twig_namespaces;
|
52 |
+
}
|
53 |
+
|
54 |
+
|
55 |
+
/**
|
56 |
+
* @return string Hash created from the requirements for Twig environment,
|
57 |
+
* which allows to reuse these environments.
|
58 |
+
*/
|
59 |
+
public function get_twig_environment_hash() {
|
60 |
+
if( null === $this->environment_hash ) {
|
61 |
+
$hash_source = '';
|
62 |
+
foreach ( $this->twig_namespaces as $namespace => $namespace_path ) {
|
63 |
+
$hash_source .= $namespace . '-->' . $namespace_path . ';';
|
64 |
+
}
|
65 |
+
$this->environment_hash = md5( $hash_source );
|
66 |
+
}
|
67 |
+
return $this->environment_hash;
|
68 |
+
}
|
69 |
+
|
70 |
+
}
|
vendor/toolset/toolset-common/inc/autoloaded/renderer/output_template_factory.php
ADDED
@@ -0,0 +1,102 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Factory for IToolset_Output_Template.
|
5 |
+
*
|
6 |
+
* It should be needed only by Toolset_Output_Template_Repository_Abstract and its subclasses.
|
7 |
+
*
|
8 |
+
* @since 2.5.9
|
9 |
+
*/
|
10 |
+
class Toolset_Output_Template_Factory {
|
11 |
+
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @param string $base_path
|
15 |
+
* @param string $template_name
|
16 |
+
*
|
17 |
+
* @return Toolset_Output_Template_Static
|
18 |
+
*/
|
19 |
+
public function static_template( $base_path, $template_name ) {
|
20 |
+
return new Toolset_Output_Template_Static( $base_path, $template_name );
|
21 |
+
}
|
22 |
+
|
23 |
+
|
24 |
+
/**
|
25 |
+
* @param string $base_path
|
26 |
+
* @param string $template_name
|
27 |
+
*
|
28 |
+
* @return Toolset_Output_Template_Phtml
|
29 |
+
*/
|
30 |
+
public function phtml_template( $base_path, $template_name ) {
|
31 |
+
return new Toolset_Output_Template_Phtml( $base_path, $template_name );
|
32 |
+
}
|
33 |
+
|
34 |
+
|
35 |
+
/**
|
36 |
+
* @param string $base_path
|
37 |
+
* @param string $template_name
|
38 |
+
* @param array $twig_namespaces
|
39 |
+
*
|
40 |
+
* @return Toolset_Output_Template_Twig
|
41 |
+
*/
|
42 |
+
public function twig_template( $base_path, $template_name, $twig_namespaces ) {
|
43 |
+
// Add the main namespace as a base path, in case it's missing.
|
44 |
+
// If the template doesn't use it, no harm done.
|
45 |
+
if( ! array_key_exists( '__main__', $twig_namespaces ) ) {
|
46 |
+
$twig_namespaces['__main__'] = $base_path;
|
47 |
+
}
|
48 |
+
return new Toolset_Output_Template_Twig( $base_path, $template_name, $twig_namespaces );
|
49 |
+
}
|
50 |
+
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Create the right type of template object according to the suffix of the template name.
|
54 |
+
*
|
55 |
+
* @param string $base_path
|
56 |
+
* @param string $template_name
|
57 |
+
* @param array $twig_namespaces
|
58 |
+
*
|
59 |
+
* @return IToolset_Output_Template
|
60 |
+
* @throws RuntimeException Thrown if the template type is not recognized (wrong suffix).
|
61 |
+
*/
|
62 |
+
public function create_by_suffix( $base_path, $template_name, $twig_namespaces = array() ) {
|
63 |
+
$file_suffix = $this->get_suffix( $template_name );
|
64 |
+
|
65 |
+
switch( $file_suffix ) {
|
66 |
+
case 'twig':
|
67 |
+
return $this->twig_template( $base_path, $template_name, $twig_namespaces );
|
68 |
+
case 'phtml':
|
69 |
+
return $this->phtml_template( $base_path, $template_name );
|
70 |
+
case 'html':
|
71 |
+
return $this->static_template( $base_path, $template_name );
|
72 |
+
default:
|
73 |
+
throw new RuntimeException( 'Template type not recognized from the suffix.' );
|
74 |
+
}
|
75 |
+
}
|
76 |
+
|
77 |
+
|
78 |
+
/**
|
79 |
+
* Get a suffix from the file name.
|
80 |
+
*
|
81 |
+
* @param string $template_name
|
82 |
+
*
|
83 |
+
* @return bool|string The suffix or false if it's not detected.
|
84 |
+
*/
|
85 |
+
private function get_suffix( $template_name ) {
|
86 |
+
$name_parts = explode( '.', $template_name );
|
87 |
+
|
88 |
+
if( count( $name_parts ) < 2 ) {
|
89 |
+
return false;
|
90 |
+
}
|
91 |
+
|
92 |
+
$extension = end( $name_parts );
|
93 |
+
|
94 |
+
if( empty( $extension ) ) {
|
95 |
+
return false;
|
96 |
+
}
|
97 |
+
|
98 |
+
return $extension;
|
99 |
+
}
|
100 |
+
|
101 |
+
|
102 |
+
}
|
vendor/toolset/toolset-common/inc/autoloaded/renderer/output_template_repository.php
ADDED
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Repository for templates in Toolset Common.
|
5 |
+
*
|
6 |
+
* See Toolset_Renderer for a detailed usage instructions.
|
7 |
+
*
|
8 |
+
* @since 2.5.9
|
9 |
+
*/
|
10 |
+
class Toolset_Output_Template_Repository extends Toolset_Output_Template_Repository_Abstract {
|
11 |
+
|
12 |
+
// Names of the templates go here and to $templates
|
13 |
+
//
|
14 |
+
//
|
15 |
+
|
16 |
+
const FAUX_TEMPLATE = 'faux_template.twig';
|
17 |
+
|
18 |
+
|
19 |
+
/**
|
20 |
+
* @var array Template definitions.
|
21 |
+
*/
|
22 |
+
private $templates = array(
|
23 |
+
self::FAUX_TEMPLATE => array(
|
24 |
+
'base_path' => null,
|
25 |
+
'namespaces' => array()
|
26 |
+
)
|
27 |
+
);
|
28 |
+
|
29 |
+
|
30 |
+
/** @var Toolset_Output_Template_Repository */
|
31 |
+
private static $instance;
|
32 |
+
|
33 |
+
|
34 |
+
/**
|
35 |
+
* @return Toolset_Output_Template_Repository
|
36 |
+
*/
|
37 |
+
public static function get_instance() {
|
38 |
+
if( null === self::$instance ) {
|
39 |
+
self::$instance = new self();
|
40 |
+
}
|
41 |
+
|
42 |
+
return self::$instance;
|
43 |
+
}
|
44 |
+
|
45 |
+
|
46 |
+
/**
|
47 |
+
* @inheritdoc
|
48 |
+
* @return string
|
49 |
+
*/
|
50 |
+
protected function get_default_base_path() {
|
51 |
+
return $this->constants->constant( 'TOOLSET_COMMON_PATH' ) . '/utility/gui-base/twig-templates';
|
52 |
+
}
|
53 |
+
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Get the array with template definitions.
|
57 |
+
*
|
58 |
+
* @return array
|
59 |
+
*/
|
60 |
+
protected function get_templates() {
|
61 |
+
return $this->templates;
|
62 |
+
}
|
63 |
+
}
|
vendor/toolset/toolset-common/inc/autoloaded/renderer/output_template_repository_abstract.php
ADDED
@@ -0,0 +1,79 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Repository for templates that can be subclassed to use in your plugin with Toolset_Renderer.
|
5 |
+
*
|
6 |
+
* @since 2.5.9
|
7 |
+
*/
|
8 |
+
abstract class Toolset_Output_Template_Repository_Abstract {
|
9 |
+
|
10 |
+
|
11 |
+
/** @var Toolset_Output_Template_Factory */
|
12 |
+
private $template_factory;
|
13 |
+
|
14 |
+
|
15 |
+
/** @var Toolset_Constants */
|
16 |
+
protected $constants;
|
17 |
+
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Toolset_Output_Template_Repository_Abstract constructor.
|
21 |
+
*
|
22 |
+
* @param Toolset_Output_Template_Factory|null $template_factory_di
|
23 |
+
* @param Toolset_Constants|null $constants_di
|
24 |
+
*/
|
25 |
+
public function __construct(
|
26 |
+
Toolset_Output_Template_Factory $template_factory_di = null,
|
27 |
+
Toolset_Constants $constants_di = null
|
28 |
+
) {
|
29 |
+
$this->template_factory = (
|
30 |
+
null === $template_factory_di
|
31 |
+
? new Toolset_Output_Template_Factory()
|
32 |
+
: $template_factory_di
|
33 |
+
);
|
34 |
+
|
35 |
+
$this->constants = (
|
36 |
+
null === $constants_di
|
37 |
+
? new Toolset_Constants()
|
38 |
+
: $constants_di
|
39 |
+
);
|
40 |
+
}
|
41 |
+
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Get the array with template definitions.
|
45 |
+
*
|
46 |
+
* @return array
|
47 |
+
*/
|
48 |
+
abstract protected function get_templates();
|
49 |
+
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Load a template from its name.
|
53 |
+
*
|
54 |
+
* @param string $template_name
|
55 |
+
*
|
56 |
+
* @return IToolset_Output_Template
|
57 |
+
* @throws InvalidArgumentException
|
58 |
+
*/
|
59 |
+
public function get( $template_name ) {
|
60 |
+
$templates = $this->get_templates();
|
61 |
+
if( ! array_key_exists( $template_name, $templates ) ) {
|
62 |
+
throw new InvalidArgumentException( 'Template is not defined' );
|
63 |
+
}
|
64 |
+
|
65 |
+
$template_definition = toolset_ensarr( $templates[ $template_name ] );
|
66 |
+
$base_path = toolset_getarr( $template_definition, 'base_path', $this->get_default_base_path() );
|
67 |
+
$namespaces = toolset_ensarr( toolset_getarr( $template_definition, 'namespaces' ) );
|
68 |
+
|
69 |
+
return $this->template_factory->create_by_suffix( $base_path, $template_name, $namespaces );
|
70 |
+
}
|
71 |
+
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Get the default base path for templates.
|
75 |
+
*
|
76 |
+
* @return string
|
77 |
+
*/
|
78 |
+
abstract protected function get_default_base_path();
|
79 |
+
}
|
vendor/toolset/toolset-common/inc/autoloaded/renderer/renderer.php
ADDED
@@ -0,0 +1,228 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Entry point for the template rendering API.
|
5 |
+
*
|
6 |
+
* How it works:
|
7 |
+
*
|
8 |
+
* Each template file is registered in Toolset_Output_Template_Repository or in another subclass of
|
9 |
+
* Toolset_Output_Template_Repository if it's contained only in a specific plugin. The registration already
|
10 |
+
* includes everything necessary for rendering the template (path and also required namespaces in case of
|
11 |
+
* Twig templates), except the template context (which is for passing along dynamic data at the time of rendering).
|
12 |
+
*
|
13 |
+
* So far, three types of templates are supported:
|
14 |
+
* - static templates (.html)
|
15 |
+
* - PHTML (PHP + HTML) (.phtml)
|
16 |
+
* - Twig templates (.twig)
|
17 |
+
*
|
18 |
+
* The difference between static templates and PHTML is that the latter can be passed some context information
|
19 |
+
* at the time of rendering, while the former is truly static without any sort of context.
|
20 |
+
*
|
21 |
+
* Toolset_Renderer accepts the template as an IToolset_Output_Template instance (which is provided by the repository)
|
22 |
+
* and uses the correct mechanism to render it (print or return).
|
23 |
+
*
|
24 |
+
* For Twig templates, there's a caching mechanism that reuses the same Twig environment if two templates have identical
|
25 |
+
* Twig namespaces.
|
26 |
+
*
|
27 |
+
* Usage:
|
28 |
+
*
|
29 |
+
* 1. Choose where to put your template. If it's in Toolset Common, use the Toolset_Output_Template_Repository class.
|
30 |
+
* Otherwise you may need to subclass Toolset_Output_Template_Repository_Abstract to add plugin-specific templates.
|
31 |
+
* 2. Define your template in the repository class. The template name must be the name of the actual template file.
|
32 |
+
* The filename suffis is relevant: "twig" for Twig templates, "phtml" for PHTML ones and "html" for static templates.
|
33 |
+
* Nothing else will be accepted.
|
34 |
+
* 3. Use the renderer like this:
|
35 |
+
*
|
36 |
+
* $template_repository = MyPlugin_Output_Template_Repository::get_instance()
|
37 |
+
* $renderer = Toolset_Renderer::get_instance();
|
38 |
+
* $output = $renderer->render(
|
39 |
+
* $template_repository->get( MyPlugin_Output_Template_Repository::MY_TEMPLATE ),
|
40 |
+
* $context,
|
41 |
+
* false // do not print but return the result
|
42 |
+
* );
|
43 |
+
*
|
44 |
+
* Note: Except reusable templates in Toolset Common, you may also use the template directly
|
45 |
+
* instead of registering it inside a template repository class, if you prefer.
|
46 |
+
*
|
47 |
+
* @since 2.5.9
|
48 |
+
*/
|
49 |
+
class Toolset_Renderer {
|
50 |
+
|
51 |
+
|
52 |
+
/** @var Toolset_Renderer */
|
53 |
+
private static $instance;
|
54 |
+
|
55 |
+
|
56 |
+
/** @var null|Toolset_Gui_Base */
|
57 |
+
private $_gui_base;
|
58 |
+
|
59 |
+
|
60 |
+
/** @var Toolset_Files */
|
61 |
+
private $files;
|
62 |
+
|
63 |
+
|
64 |
+
/** @var Twig_Environment[] */
|
65 |
+
private $twig_environments = array();
|
66 |
+
|
67 |
+
|
68 |
+
/**
|
69 |
+
* Toolset_Renderer constructor.
|
70 |
+
*
|
71 |
+
* @param Toolset_Gui_Base|null $gui_base_di
|
72 |
+
* @param Toolset_Files|null $files_di
|
73 |
+
*/
|
74 |
+
public function __construct(
|
75 |
+
Toolset_Gui_Base $gui_base_di = null,
|
76 |
+
Toolset_Files $files_di = null
|
77 |
+
) {
|
78 |
+
$this->_gui_base = $gui_base_di;
|
79 |
+
$this->files = ( null === $files_di ? new Toolset_Files() : $files_di );
|
80 |
+
}
|
81 |
+
|
82 |
+
|
83 |
+
/**
|
84 |
+
* @return Toolset_Renderer
|
85 |
+
*/
|
86 |
+
public static function get_instance() {
|
87 |
+
if ( null === self::$instance ) {
|
88 |
+
self::$instance = new self();
|
89 |
+
}
|
90 |
+
|
91 |
+
return self::$instance;
|
92 |
+
}
|
93 |
+
|
94 |
+
|
95 |
+
/**
|
96 |
+
* Render a template.
|
97 |
+
*
|
98 |
+
* @param IToolset_Output_Template $template
|
99 |
+
* @param mixed $context Arbitrary context that will be passed to the template, depending
|
100 |
+
* on its type.
|
101 |
+
* @param bool $echo Should the output be echoed?
|
102 |
+
*
|
103 |
+
* @return string
|
104 |
+
* @throws Twig_Error_Loader In case of incorrect Twig configuration.
|
105 |
+
* @throws Twig_Error_Runtime In case of incorrect Twig configuration.
|
106 |
+
* @throws Twig_Error_Syntax In case of incorrect Twig configuration.
|
107 |
+
*/
|
108 |
+
public function render( IToolset_Output_Template $template, $context, $echo = true ) {
|
109 |
+
|
110 |
+
if( $template instanceof Toolset_Output_Template_Twig ) {
|
111 |
+
$output = $this->render_twig_template( $template, $context );
|
112 |
+
} elseif( $template instanceof Toolset_Output_Template_Phtml ) {
|
113 |
+
$output = $this->render_phtml_template( $template, $context );
|
114 |
+
} else {
|
115 |
+
$output = $this->render_static_template( $template );
|
116 |
+
}
|
117 |
+
|
118 |
+
if( $echo ) {
|
119 |
+
echo $output;
|
120 |
+
}
|
121 |
+
|
122 |
+
return $output;
|
123 |
+
}
|
124 |
+
|
125 |
+
|
126 |
+
/**
|
127 |
+
* Render the given PHTML/HTML template.
|
128 |
+
*
|
129 |
+
* @param Toolset_Output_Template $template The path of the template to render.
|
130 |
+
* @param mixed $context The context of the template for passing some additional data to the template, if needed.
|
131 |
+
*
|
132 |
+
* @return string The template output.
|
133 |
+
*/
|
134 |
+
private function render_phtml_template( $template, $context ) {
|
135 |
+
$template_path = $template->get_full_path();
|
136 |
+
$template_output = '';
|
137 |
+
if ( $this->files->is_file( $template_path ) ) {
|
138 |
+
$template_output = $this->files->get_include_file_output(
|
139 |
+
$template_path, array( 'context' => $context )
|
140 |
+
);
|
141 |
+
}
|
142 |
+
|
143 |
+
return $template_output;
|
144 |
+
}
|
145 |
+
|
146 |
+
|
147 |
+
/**
|
148 |
+
* @param IToolset_Output_Template $template
|
149 |
+
*
|
150 |
+
* @return string
|
151 |
+
*/
|
152 |
+
private function render_static_template( $template ) {
|
153 |
+
if( ! $this->files->is_file( $template->get_full_path() ) ) {
|
154 |
+
return '';
|
155 |
+
}
|
156 |
+
|
157 |
+
$output = $this->files->file_get_contents( $template->get_full_path() );
|
158 |
+
|
159 |
+
if( false === $output ) {
|
160 |
+
return '';
|
161 |
+
}
|
162 |
+
|
163 |
+
return $output;
|
164 |
+
}
|
165 |
+
|
166 |
+
|
167 |
+
/**
|
168 |
+
* @param Toolset_Output_Template_Twig $template
|
169 |
+
* @param array $context
|
170 |
+
*
|
171 |
+
* @return string
|
172 |
+
* @throws Twig_Error_Loader In case of incorrect Twig configuration.
|
173 |
+
* @throws Twig_Error_Runtime In case of incorrect Twig configuration.
|
174 |
+
* @throws Twig_Error_Syntax In case of incorrect Twig configuration.
|
175 |
+
*/
|
176 |
+
private function render_twig_template( Toolset_Output_Template_Twig $template, $context ) {
|
177 |
+
|
178 |
+
$twig = $this->get_twig(
|
179 |
+
$template->get_twig_namespaces(),
|
180 |
+
$template->get_twig_environment_hash()
|
181 |
+
);
|
182 |
+
|
183 |
+
return $twig->render( $template->get_name(), $context );
|
184 |
+
}
|
185 |
+
|
186 |
+
|
187 |
+
/**
|
188 |
+
* Returns GUI Base
|
189 |
+
*
|
190 |
+
* @return Toolset_Gui_Base
|
191 |
+
* @since m2m
|
192 |
+
*/
|
193 |
+
private function get_gui_base() {
|
194 |
+
if( null === $this->_gui_base ) {
|
195 |
+
$toolset_common_bootstrap = Toolset_Common_Bootstrap::get_instance();
|
196 |
+
$toolset_common_bootstrap->register_gui_base();
|
197 |
+
|
198 |
+
$gui_base = Toolset_Gui_Base::get_instance();
|
199 |
+
$gui_base->init();
|
200 |
+
|
201 |
+
$this->_gui_base = $gui_base;
|
202 |
+
}
|
203 |
+
|
204 |
+
return $this->_gui_base;
|
205 |
+
}
|
206 |
+
|
207 |
+
|
208 |
+
/**
|
209 |
+
* Retrieve a Twig environment initialized by the Toolset GUI base.
|
210 |
+
*
|
211 |
+
* @param string[] $namespaces
|
212 |
+
* @param string $hash
|
213 |
+
*
|
214 |
+
* @return Twig_Environment In case of incorrect Twig configuration.
|
215 |
+
* @since m2m
|
216 |
+
* @throws Twig_Error_Loader In case of incorrect Twig configuration.
|
217 |
+
*/
|
218 |
+
private function get_twig( $namespaces, $hash ) {
|
219 |
+
if( ! array_key_exists( $hash, $this->twig_environments ) ) {
|
220 |
+
$gui_base = $this->get_gui_base();
|
221 |
+
$this->twig_environments[ $hash ] = $gui_base->create_twig_environment( $namespaces );
|
222 |
+
}
|
223 |
+
|
224 |
+
return $this->twig_environments[ $hash ];
|
225 |
+
}
|
226 |
+
|
227 |
+
|
228 |
+
}
|
vendor/toolset/toolset-common/inc/autoloaded/result_set.php
CHANGED
@@ -15,6 +15,10 @@
|
|
15 |
*/
|
16 |
class Toolset_Result_Set {
|
17 |
|
|
|
|
|
|
|
|
|
18 |
/** @var array Mixed array of Toolset_Result and Toolset_Result_Set instances. */
|
19 |
private $results = array();
|
20 |
|
@@ -199,11 +203,12 @@ class Toolset_Result_Set {
|
|
199 |
/**
|
200 |
* Turn the whole result set into a (simplified) result.
|
201 |
*
|
|
|
202 |
* @return Toolset_Result
|
203 |
* @since 2.3
|
204 |
*/
|
205 |
-
public function aggregate() {
|
206 |
-
return new Toolset_Result( $this->is_complete_success(), $this->concat_messages() );
|
207 |
}
|
208 |
|
209 |
}
|
15 |
*/
|
16 |
class Toolset_Result_Set {
|
17 |
|
18 |
+
|
19 |
+
const DEFAULT_SEPARATOR = '; ';
|
20 |
+
|
21 |
+
|
22 |
/** @var array Mixed array of Toolset_Result and Toolset_Result_Set instances. */
|
23 |
private $results = array();
|
24 |
|
203 |
/**
|
204 |
* Turn the whole result set into a (simplified) result.
|
205 |
*
|
206 |
+
* @param string $separator
|
207 |
* @return Toolset_Result
|
208 |
* @since 2.3
|
209 |
*/
|
210 |
+
public function aggregate( $separator = self::DEFAULT_SEPARATOR ) {
|
211 |
+
return new Toolset_Result( $this->is_complete_success(), $this->concat_messages( $separator ) );
|
212 |
}
|
213 |
|
214 |
}
|
vendor/toolset/toolset-common/inc/autoloaded/wp_query_adjustments/abstract.php
ADDED
@@ -0,0 +1,170 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Adjusts the WP_Query functionality.
|
5 |
+
*
|
6 |
+
* Covers the need for querying by post relationship by adding a new query argument 'toolset_relationships'.
|
7 |
+
*
|
8 |
+
* Usage:
|
9 |
+
*
|
10 |
+
* $query = new WP_Query( array(
|
11 |
+
* ...,
|
12 |
+
* 'toolset_relationships' => array(
|
13 |
+
* // ... relationship args
|
14 |
+
* )
|
15 |
+
* );
|
16 |
+
*
|
17 |
+
* The relationship arguments can contain one or multiple conditions. Each condition is represented by
|
18 |
+
* a nested associative array, but if there is only a single condition, it doesn't have to be nested.
|
19 |
+
*
|
20 |
+
* If multiple conditions are used, they're handled as conjunctions (AND).
|
21 |
+
*
|
22 |
+
* Each condition array has these elements:
|
23 |
+
*
|
24 |
+
* - 'role': 'parent'|'child'|'intermediary' - role of the queried post (the one that will be included in the results).
|
25 |
+
* Optional, default is 'child'.
|
26 |
+
* - 'related_to': int|WP_Post - post to which the results are connected. Mandatory.
|
27 |
+
* - 'relationship': string|string[] - relationship identified either by its slug or by a pair of the parent and child post types.
|
28 |
+
* The array variant can be used only for legacy relationships (or those migrated from the legacy implementation).
|
29 |
+
* The relationship slug variant will obviously work only if m2m is already enabled. Mandatory.
|
30 |
+
* - 'role_to_query_by': 'parent'|'child'|'intermediary'|'other'. Role of the 'related_to' post in the relationship.
|
31 |
+
* 'other' means the opposite of 'role' and can be used only if 'role' is 'parent' or 'child'.
|
32 |
+
* Optional, default is 'other'.
|
33 |
+
*
|
34 |
+
* Examples:
|
35 |
+
*
|
36 |
+
* // Single condition
|
37 |
+
* $query = new WP_Query( array(
|
38 |
+
* ...,
|
39 |
+
* 'toolset_relationships' => array(
|
40 |
+
* 'role' => 'child',
|
41 |
+
* 'related_to' => $parent_post,
|
42 |
+
* 'relationship' => array( 'parent_type', 'post_type' )
|
43 |
+
* )
|
44 |
+
* );
|
45 |
+
*
|
46 |
+
* // Multiple conditions
|
47 |
+
* //
|
48 |
+
* // Query posts that are children of $parent_post in the relationship between 'parent_type' and 'post_type'
|
49 |
+
* // migrated from the legacy implementation and at the same time parents of $child_post
|
50 |
+
* // in the relationship 'another_relationship' (because we used the slug, this will work only if
|
51 |
+
* // m2m is enabled).
|
52 |
+
* //
|
53 |
+
* $query = new WP_Query( array(
|
54 |
+
* ...,
|
55 |
+
* 'toolset_relationships' => array(
|
56 |
+
* array(
|
57 |
+
* 'role' => 'child',
|
58 |
+
* 'related_to' => $parent_post,
|
59 |
+
* 'relationship' => array( 'parent_type', 'post_type' )
|
60 |
+
* ),
|
61 |
+
* array(
|
62 |
+
* 'role' => 'parent',
|
63 |
+
* 'related_to' => $child_post,
|
64 |
+
* 'relationship' => 'another_relationship'
|
65 |
+
*
|
66 |
+
* )
|
67 |
+
* );
|
68 |
+
*
|
69 |
+
* @since 2.6.1
|
70 |
+
*/
|
71 |
+
abstract class Toolset_Wp_Query_Adjustments extends Toolset_Wpdb_User {
|
72 |
+
|
73 |
+
// Must not be changed, third-party software depends on it.
|
74 |
+
const RELATIONSHIP_QUERY_ARG = 'toolset_relationships';
|
75 |
+
|
76 |
+
|
77 |
+
/**
|
78 |
+
* Initialize the query adjustments.
|
79 |
+
*/
|
80 |
+
public function initialize() {
|
81 |
+
add_action( 'pre_get_posts', array( $this, 'check_custom_query_args' ) );
|
82 |
+
}
|
83 |
+
|
84 |
+
|
85 |
+
/**
|
86 |
+
* Using the approach described here: http://www.danielauener.com/extend-wp_query-with-custom-parameters/
|
87 |
+
*
|
88 |
+
* @param $query
|
89 |
+
*/
|
90 |
+
public function check_custom_query_args( $query ) {
|
91 |
+
if( ! $query instanceof WP_Query ) {
|
92 |
+
// Something weird is happening.
|
93 |
+
return;
|
94 |
+
}
|
95 |
+
|
96 |
+
if( array_key_exists( self::RELATIONSHIP_QUERY_ARG, $query->query_vars ) ) {
|
97 |
+
$query->{self::RELATIONSHIP_QUERY_ARG} = $query->query_vars[ self::RELATIONSHIP_QUERY_ARG ];
|
98 |
+
}
|
99 |
+
}
|
100 |
+
|
101 |
+
|
102 |
+
/**
|
103 |
+
* Get the table join manager object attached to the WP_Query instance or create and attach a new one.
|
104 |
+
*
|
105 |
+
* @param WP_Query $query
|
106 |
+
*
|
107 |
+
* @return Toolset_Wp_Query_Adjustments_Table_Join_Manager
|
108 |
+
*/
|
109 |
+
protected function get_table_join_manager( WP_Query $query ) {
|
110 |
+
// This is a dirty hack but still cleanest considering we need to use this object
|
111 |
+
// in different callbacks from WP_Query.
|
112 |
+
$property_name = 'toolset_join_manager';
|
113 |
+
if( ! property_exists( $query, $property_name ) ) {
|
114 |
+
$query->{$property_name} = new Toolset_Wp_Query_Adjustments_Table_Join_Manager();
|
115 |
+
}
|
116 |
+
return $query->{$property_name};
|
117 |
+
}
|
118 |
+
|
119 |
+
|
120 |
+
/**
|
121 |
+
* Turn the relationship query argument into an array of conditions.
|
122 |
+
*
|
123 |
+
* @param array $query_args
|
124 |
+
*
|
125 |
+
* @return array
|
126 |
+
* @throws InvalidArgumentException
|
127 |
+
*/
|
128 |
+
protected function normalize_relationship_query_args( $query_args ) {
|
129 |
+
$has_strings = $this->array_has_strings( $query_args );
|
130 |
+
$has_arrays = $this->array_has_arrays( $query_args );
|
131 |
+
|
132 |
+
if( $has_arrays && $has_strings ) {
|
133 |
+
// Can't have both.
|
134 |
+
throw new InvalidArgumentException( 'The toolset_relationship query argument contains mixed content (arrays and string values).' );
|
135 |
+
}
|
136 |
+
|
137 |
+
if( $has_strings ) {
|
138 |
+
return array( $query_args );
|
139 |
+
}
|
140 |
+
|
141 |
+
return $query_args;
|
142 |
+
}
|
143 |
+
|
144 |
+
|
145 |
+
private function array_has_strings( $array ) {
|
146 |
+
foreach( $array as $element ) {
|
147 |
+
if( is_string( $element ) ) {
|
148 |
+
return true;
|
149 |
+
}
|
150 |
+
}
|
151 |
+
|
152 |
+
return false;
|
153 |
+
}
|
154 |
+
|
155 |
+
|
156 |
+
private function array_has_arrays( $array ) {
|
157 |
+
foreach( $array as $key => $element ) {
|
158 |
+
// The "relationship" element will not be considered as a nested condition.
|
159 |
+
// If there is something weird going on, it will fail later on during the validation
|
160 |
+
// of individual parameters.
|
161 |
+
if( is_array( $element ) && 'relationship' !== $key ) {
|
162 |
+
return true;
|
163 |
+
}
|
164 |
+
}
|
165 |
+
|
166 |
+
return false;
|
167 |
+
|
168 |
+
}
|
169 |
+
|
170 |
+
}
|
vendor/toolset/toolset-common/inc/autoloaded/wp_query_adjustments/legacy_relationships.php
ADDED
@@ -0,0 +1,141 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Adjust the WP_Query functionality for legacy post relationships.
|
5 |
+
*
|
6 |
+
* This assumes m2m is *not* enabled.
|
7 |
+
*
|
8 |
+
* See the superclass for details.
|
9 |
+
*
|
10 |
+
* @since 2.6.1
|
11 |
+
*/
|
12 |
+
class Toolset_Wp_Query_Adjustments_Legacy_Relationships extends Toolset_Wp_Query_Adjustments {
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Call to register required hook.
|
16 |
+
*/
|
17 |
+
public function initialize() {
|
18 |
+
add_action( 'pre_get_posts', array( $this, 'convert_toolset_relationships_argument_to_meta_query' ) );
|
19 |
+
}
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Will convert 'toolset_relationship' argument to 'meta_query' of WP_Query
|
23 |
+
*
|
24 |
+
* @action pre_get_posts
|
25 |
+
*
|
26 |
+
* @param $query
|
27 |
+
*/
|
28 |
+
public function convert_toolset_relationships_argument_to_meta_query( $query ) {
|
29 |
+
if( ! $query instanceof WP_Query ) {
|
30 |
+
// Something weird is happening.
|
31 |
+
return;
|
32 |
+
}
|
33 |
+
|
34 |
+
if( ! array_key_exists( self::RELATIONSHIP_QUERY_ARG, $query->query_vars ) ) {
|
35 |
+
// 'toolset_relationship' argument is not used
|
36 |
+
return;
|
37 |
+
}
|
38 |
+
|
39 |
+
// get meta_query
|
40 |
+
$meta_query = $this->get_meta_query_by_toolset_argument( $query->query_vars[ self::RELATIONSHIP_QUERY_ARG ] );
|
41 |
+
|
42 |
+
if( ! empty( $meta_query ) ) {
|
43 |
+
if( ! isset( $query->query_vars['meta_query'] ) ) {
|
44 |
+
// no meta_query yet, open collection
|
45 |
+
$query->query_vars['meta_query'] = array();
|
46 |
+
}
|
47 |
+
// add our converted 'toolset_relationship' argument to the WP_Query
|
48 |
+
$query->query_vars['meta_query'][] = $meta_query;
|
49 |
+
};
|
50 |
+
|
51 |
+
// important to unset our argument, otherwise each get_posts call will append the same conditions again
|
52 |
+
unset( $query->query_vars[ self::RELATIONSHIP_QUERY_ARG ] );
|
53 |
+
}
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Get all conditions of 'toolset_relationships' and store them to $this->meta_query_conditions.
|
57 |
+
*
|
58 |
+
* @param $toolset_relationships The 'toolset_relationships' argument
|
59 |
+
*
|
60 |
+
* @return array
|
61 |
+
*/
|
62 |
+
private function get_meta_query_by_toolset_argument( $toolset_relationships ) {
|
63 |
+
if( ! is_array( reset( $toolset_relationships ) ) ) {
|
64 |
+
// normalise array
|
65 |
+
$toolset_relationships = array( $toolset_relationships );
|
66 |
+
}
|
67 |
+
|
68 |
+
$meta_query = array();
|
69 |
+
|
70 |
+
foreach( $toolset_relationships as $condition ) {
|
71 |
+
if( ! $condition = $this->valid_query_array( $condition ) ){
|
72 |
+
// slug of relationships is not supported by legacy
|
73 |
+
continue;
|
74 |
+
}
|
75 |
+
|
76 |
+
// normalise related_to value to be an integer
|
77 |
+
$related_to = $condition['related_to'] instanceof WP_Post
|
78 |
+
? (int) $condition['related_to']->ID
|
79 |
+
: (int) $condition['related_to'];
|
80 |
+
|
81 |
+
$meta_query[] = array(
|
82 |
+
'key' => '_wpcf_belongs_'.reset( $condition['relationship'] ).'_id',
|
83 |
+
'value' => $related_to,
|
84 |
+
'compare' => '=',
|
85 |
+
);
|
86 |
+
}
|
87 |
+
|
88 |
+
if( ! empty( $meta_query ) ) {
|
89 |
+
$meta_query['relation'] = 'AND';
|
90 |
+
}
|
91 |
+
|
92 |
+
return $meta_query;
|
93 |
+
}
|
94 |
+
|
95 |
+
/**
|
96 |
+
* Validation of a condition array. For legacy we have a more strict validation
|
97 |
+
* than for m2m as a bunch of features is not available for legacy relationships
|
98 |
+
*
|
99 |
+
* @param $condition
|
100 |
+
*
|
101 |
+
* @return bool
|
102 |
+
*/
|
103 |
+
private function valid_query_array( $condition ) {
|
104 |
+
if( ! isset( $condition['related_to'] ) ) {
|
105 |
+
// required
|
106 |
+
throw new InvalidArgumentException( "WP_Query > 'toolset_relationships' requires 'related_to' key." );
|
107 |
+
}
|
108 |
+
|
109 |
+
if( ( ! is_numeric( $condition['related_to'] ) || strpos( $condition['related_to'], '.' ) !== false )
|
110 |
+
&& ! $condition['related_to'] instanceof WP_Post ) // no WP_Post
|
111 |
+
{
|
112 |
+
// no integer NOR object of WP_Post
|
113 |
+
throw new InvalidArgumentException( "WP_Query > 'toolset_relationships' > 'related_to' must be a post_ID or a WP_Post object." );
|
114 |
+
}
|
115 |
+
|
116 |
+
if( ! isset( $condition['relationship'] ) // not set at all
|
117 |
+
|| ! is_array( $condition[ 'relationship' ] ) // no array, which is not possible for legacy relationship
|
118 |
+
|| ! is_string( reset( $condition[ 'relationship' ] ) ) // first array element is no string -> not valid
|
119 |
+
) {
|
120 |
+
throw new InvalidArgumentException( "WP_Query > 'toolset_relationships' > 'relationship' must be an array( 'parent_slug', 'child_slug' )." );
|
121 |
+
}
|
122 |
+
|
123 |
+
if( ! isset( $condition['role'] ) && ! isset( $condition['role_to_query_by'] ) ) {
|
124 |
+
// default value
|
125 |
+
$condition['role'] = 'child';
|
126 |
+
}
|
127 |
+
|
128 |
+
if( isset( $condition['role'] ) && $condition['role'] != 'child' ) {
|
129 |
+
// only child role is possible for legacy
|
130 |
+
throw new InvalidArgumentException( "WP_Query > 'toolset_relationships' > 'role' invalid value. You can only use 'child' for legacy relationships." );
|
131 |
+
}
|
132 |
+
|
133 |
+
if( isset( $condition['role_to_query_by'] ) && ( $condition['role_to_query_by'] == 'child' || $condition['role_to_query_by'] == 'intermediary' ) ) {
|
134 |
+
// not possible to query by child or intermediary
|
135 |
+
throw new InvalidArgumentException( "WP_Query > 'toolset_relationships' > 'role_to_query_by' invalid value. You can only use 'parent' for legacy relationships." );
|
136 |
+
}
|
137 |
+
|
138 |
+
// all fine
|
139 |
+
return $condition;
|
140 |
+
}
|
141 |
+
}
|
vendor/toolset/toolset-common/inc/autoloaded/wp_query_adjustments/loader.php
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Apply WP_Query adjustments.
|
5 |
+
*
|
6 |
+
* Depending on the status of the m2m functionality, a proper adjustment class will be instantiated
|
7 |
+
* to allow for querying by post relationship in a sustainable way.
|
8 |
+
*
|
9 |
+
* @since 2.6.1
|
10 |
+
*/
|
11 |
+
class Toolset_Wp_Query_Adjustments_Loader {
|
12 |
+
|
13 |
+
|
14 |
+
public function initialize() {
|
15 |
+
|
16 |
+
if( apply_filters( 'toolset_is_m2m_enabled', false ) ) {
|
17 |
+
$adjustments = new Toolset_Wp_Query_Adjustments_M2m();
|
18 |
+
} else {
|
19 |
+
$adjustments = new Toolset_Wp_Query_Adjustments_Legacy_Relationships();
|
20 |
+
}
|
21 |
+
|
22 |
+
$adjustments->initialize();
|
23 |
+
}
|
24 |
+
|
25 |
+
}
|
vendor/toolset/toolset-common/inc/autoloaded/wp_query_adjustments/m2m.php
ADDED
@@ -0,0 +1,251 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Adjust the WP_Query functionality for m2m relationships.
|
5 |
+
*
|
6 |
+
* This assumes m2m is enabled.
|
7 |
+
*
|
8 |
+
* See the superclass for details.
|
9 |
+
*
|
10 |
+
* @since 2.6.1
|
11 |
+
*/
|
12 |
+
class Toolset_Wp_Query_Adjustments_M2m extends Toolset_Wp_Query_Adjustments {
|
13 |
+
|
14 |
+
|
15 |
+
/** @var Toolset_Relationship_Database_Operations|null */
|
16 |
+
private $_database_operations;
|
17 |
+
|
18 |
+
|
19 |
+
/** @var null|Toolset_Element_Factory */
|
20 |
+
private $_element_factory;
|
21 |
+
|
22 |
+
|
23 |
+
/**
|
24 |
+
* Toolset_Wp_Query_Adjustments_M2m constructor.
|
25 |
+
*
|
26 |
+
* @param wpdb|null $wpdb_di
|
27 |
+
* @param Toolset_Relationship_Database_Operations|null $database_operations_di
|
28 |
+
* @param Toolset_Element_Factory|null $element_factory_di
|
29 |
+
*/
|
30 |
+
public function __construct(
|
31 |
+
wpdb $wpdb_di = null,
|
32 |
+
Toolset_Relationship_Database_Operations $database_operations_di = null,
|
33 |
+
Toolset_Element_Factory $element_factory_di = null
|
34 |
+
|
35 |
+
) {
|
36 |
+
parent::__construct( $wpdb_di );
|
37 |
+
$this->_database_operations = $database_operations_di;
|
38 |
+
$this->_element_factory = $element_factory_di;
|
39 |
+
}
|
40 |
+
|
41 |
+
|
42 |
+
/**
|
43 |
+
* @inheritdoc
|
44 |
+
*/
|
45 |
+
public function initialize() {
|
46 |
+
parent::initialize();
|
47 |
+
|
48 |
+
do_action( 'toolset_do_m2m_full_init' );
|
49 |
+
|
50 |
+
add_filter( 'posts_where', array( $this, 'posts_where' ), 10, 2 );
|
51 |
+
add_filter( 'posts_join', array( $this, 'posts_join' ), 10, 2 );
|
52 |
+
}
|
53 |
+
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Add conditions to the WHERE clause.
|
57 |
+
*
|
58 |
+
* @param string $where
|
59 |
+
* @param WP_Query $wp_query
|
60 |
+
*
|
61 |
+
* @return string
|
62 |
+
* @throws Toolset_Element_Exception_Element_Doesnt_Exist
|
63 |
+
*/
|
64 |
+
public function posts_where( $where, $wp_query ) {
|
65 |
+
if( property_exists( $wp_query, self::RELATIONSHIP_QUERY_ARG ) ) {
|
66 |
+
$where = $this->add_relationship_query_where( $where, $wp_query->{self::RELATIONSHIP_QUERY_ARG}, $wp_query );
|
67 |
+
}
|
68 |
+
return $where;
|
69 |
+
}
|
70 |
+
|
71 |
+
|
72 |
+
/**
|
73 |
+
* Add tables to the JOIN clause.
|
74 |
+
*
|
75 |
+
* @param string $join
|
76 |
+
* @param WP_Query $wp_query
|
77 |
+
*
|
78 |
+
* @return string
|
79 |
+
*/
|
80 |
+
public function posts_join( $join, $wp_query ) {
|
81 |
+
if( property_exists( $wp_query, self::RELATIONSHIP_QUERY_ARG ) ) {
|
82 |
+
$join = $this->add_relationship_query_join( $join, $wp_query );
|
83 |
+
}
|
84 |
+
return $join;
|
85 |
+
}
|
86 |
+
|
87 |
+
|
88 |
+
/**
|
89 |
+
* @param string $where
|
90 |
+
* @param array $relationship_query
|
91 |
+
* @param WP_Query $wp_query
|
92 |
+
*
|
93 |
+
* @return string
|
94 |
+
* @throws Toolset_Element_Exception_Element_Doesnt_Exist
|
95 |
+
*/
|
96 |
+
private function add_relationship_query_where( $where, $relationship_query, WP_Query $wp_query ) {
|
97 |
+
$relationship_query = $this->normalize_relationship_query_args( $relationship_query );
|
98 |
+
|
99 |
+
foreach( $relationship_query as $query_condition ) {
|
100 |
+
$where .= ' ' . $this->add_relationship_query_condition( $query_condition, $wp_query );
|
101 |
+
}
|
102 |
+
|
103 |
+
return $where;
|
104 |
+
}
|
105 |
+
|
106 |
+
|
107 |
+
/**
|
108 |
+
* @param $query_condition
|
109 |
+
* @param WP_Query $wp_query
|
110 |
+
*
|
111 |
+
* @return string
|
112 |
+
*/
|
113 |
+
private function add_relationship_query_condition( $query_condition, WP_Query $wp_query ) {
|
114 |
+
$relationship_slug = $this->get_relationship_slug( $query_condition );
|
115 |
+
$related_to_post = $this->get_post( $query_condition );
|
116 |
+
|
117 |
+
if( null === $relationship_slug || null === $related_to_post ) {
|
118 |
+
// The relationship or the post doesn't exist but it is not a misconfiguration of the
|
119 |
+
// wp_query argument - we just return no results.
|
120 |
+
return ' AND 0 = 1 ';
|
121 |
+
}
|
122 |
+
|
123 |
+
$role_to_return = $this->get_role( $query_condition, 'role' );
|
124 |
+
$associations_table = $this->get_table_join_manager( $wp_query )->associations_table( $relationship_slug, $role_to_return );
|
125 |
+
|
126 |
+
$role_to_query_by = $this->get_role( $query_condition, 'role_to_query_by', $role_to_return );
|
127 |
+
$role_to_query_by_column = $this->get_database_operations()->role_to_column( $role_to_query_by );
|
128 |
+
|
129 |
+
$clause = $this->wpdb->prepare(
|
130 |
+
" AND $associations_table.$role_to_query_by_column = %d ",
|
131 |
+
$related_to_post->get_default_language_id()
|
132 |
+
);
|
133 |
+
|
134 |
+
return $clause;
|
135 |
+
}
|
136 |
+
|
137 |
+
|
138 |
+
private function add_relationship_query_join( $join, $wp_query ) {
|
139 |
+
// Just add the tables from the JOIN manager which has been filled by data during the processing
|
140 |
+
// of the posts_where filter (it comes before posts_join)
|
141 |
+
return $join . ' ' . $this->get_table_join_manager( $wp_query )->get_join_clauses() . ' ';
|
142 |
+
}
|
143 |
+
|
144 |
+
|
145 |
+
/**
|
146 |
+
* Resolve the relationship slug from a given query condition.
|
147 |
+
*
|
148 |
+
* Also supports an array with a pair of post types that identify a legacy relationship.
|
149 |
+
*
|
150 |
+
* @param array $query_condition
|
151 |
+
*
|
152 |
+
* @return string
|
153 |
+
* @throws InvalidArgumentException
|
154 |
+
*/
|
155 |
+
private function get_relationship_slug( $query_condition ) {
|
156 |
+
$relationship = toolset_getarr( $query_condition, 'relationship' );
|
157 |
+
|
158 |
+
if( is_array( $relationship ) ) {
|
159 |
+
if( count( $relationship ) !== 2 ) {
|
160 |
+
throw new InvalidArgumentException( 'Invalid relationship query argument.' );
|
161 |
+
}
|
162 |
+
|
163 |
+
$relationship_definition = Toolset_Relationship_Definition_Repository::get_instance()->get_legacy_definition(
|
164 |
+
$relationship[0], $relationship[1]
|
165 |
+
);
|
166 |
+
} elseif( ! is_string( $relationship ) || empty( $relationship ) ) {
|
167 |
+
throw new InvalidArgumentException( 'Invalid relationship query argument.' );
|
168 |
+
} else {
|
169 |
+
$relationship_definition = Toolset_Relationship_Definition_Repository::get_instance()->get_definition( $relationship );
|
170 |
+
}
|
171 |
+
|
172 |
+
if( null === $relationship_definition ) {
|
173 |
+
return null;
|
174 |
+
}
|
175 |
+
|
176 |
+
return $relationship_definition->get_slug();
|
177 |
+
}
|
178 |
+
|
179 |
+
|
180 |
+
/**
|
181 |
+
* Resolve the role object from the query condition.
|
182 |
+
*
|
183 |
+
* @param string[] $query_condition
|
184 |
+
* @param string $key Key of the element in the query condition that contains the role name.
|
185 |
+
* @param IToolset_Relationship_Role|null $other_role If this is provided and is a parent or child,
|
186 |
+
* the role in $key can be empty/other - the opposite of $other_role will be used in that case.
|
187 |
+
*
|
188 |
+
* @return IToolset_Relationship_Role
|
189 |
+
*/
|
190 |
+
private function get_role( $query_condition, $key, IToolset_Relationship_Role $other_role = null ) {
|
191 |
+
$role_name = toolset_getarr( $query_condition, $key, 'other' );
|
192 |
+
|
193 |
+
if( 'other' === $role_name && $other_role instanceof IToolset_Relationship_Role_Parent_Child ) {
|
194 |
+
return $other_role->other();
|
195 |
+
}
|
196 |
+
|
197 |
+
return Toolset_Relationship_Role::role_from_name( $role_name );
|
198 |
+
}
|
199 |
+
|
200 |
+
|
201 |
+
/**
|
202 |
+
* @return Toolset_Relationship_Database_Operations
|
203 |
+
*/
|
204 |
+
private function get_database_operations() {
|
205 |
+
if( null === $this->_database_operations ) {
|
206 |
+
$this->_database_operations = Toolset_Relationship_Database_Operations::get_instance();
|
207 |
+
}
|
208 |
+
|
209 |
+
return $this->_database_operations;
|
210 |
+
}
|
211 |
+
|
212 |
+
|
213 |
+
/**
|
214 |
+
* @return Toolset_Element_Factory
|
215 |
+
*/
|
216 |
+
private function get_element_factory() {
|
217 |
+
if( null === $this->_element_factory ) {
|
218 |
+
$this->_element_factory = new Toolset_Element_Factory();
|
219 |
+
}
|
220 |
+
|
221 |
+
return $this->_element_factory;
|
222 |
+
}
|
223 |
+
|
224 |
+
|
225 |
+
/**
|
226 |
+
* Get the "related_to" post from the query condition array.
|
227 |
+
*
|
228 |
+
* @param $query_condition
|
229 |
+
*
|
230 |
+
* @return IToolset_Post
|
231 |
+
*/
|
232 |
+
private function get_post( $query_condition ) {
|
233 |
+
$related_to_post_id = toolset_getarr( $query_condition, 'related_to' );
|
234 |
+
if( $related_to_post_id instanceof WP_Post ) {
|
235 |
+
$related_to_post_id = $related_to_post_id->ID;
|
236 |
+
} elseif( ! Toolset_Utils::is_natural_numeric( $related_to_post_id ) ) {
|
237 |
+
throw new InvalidArgumentException( 'Invalid relationship query argument.' );
|
238 |
+
} else {
|
239 |
+
$related_to_post_id = (int) $related_to_post_id;
|
240 |
+
}
|
241 |
+
|
242 |
+
try {
|
243 |
+
$post = $this->get_element_factory()->get_post( $related_to_post_id );
|
244 |
+
} catch ( Toolset_Element_Exception_Element_Doesnt_Exist $e ) {
|
245 |
+
return null;
|
246 |
+
}
|
247 |
+
|
248 |
+
return $post;
|
249 |
+
}
|
250 |
+
|
251 |
+
}
|
vendor/toolset/toolset-common/inc/autoloaded/wp_query_adjustments/table_join_manager.php
ADDED
@@ -0,0 +1,172 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Collect the JOINed tables in Toolset_Wp_Query_Adjustments_M2m and generate the JOIN clause.
|
5 |
+
*
|
6 |
+
* @since 2.6.1
|
7 |
+
*/
|
8 |
+
class Toolset_Wp_Query_Adjustments_Table_Join_Manager extends Toolset_Wpdb_User {
|
9 |
+
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @var string[][] Unique aliases for the associations table, indexed by a relationship slug and a role name.
|
13 |
+
*/
|
14 |
+
private $joins = array();
|
15 |
+
|
16 |
+
|
17 |
+
/** @var Toolset_Relationship_Table_Name */
|
18 |
+
private $table_name;
|
19 |
+
|
20 |
+
|
21 |
+
/** @var Toolset_Relationship_Database_Unique_Table_Alias */
|
22 |
+
private $uniqe_table_alias;
|
23 |
+
|
24 |
+
|
25 |
+
/** @var Toolset_Relationship_Database_Operations */
|
26 |
+
private $database_operations;
|
27 |
+
|
28 |
+
|
29 |
+
/** @var Toolset_Relationship_Definition_Repository */
|
30 |
+
private $definition_repository;
|
31 |
+
|
32 |
+
|
33 |
+
/** @var Toolset_WPML_Compatibility */
|
34 |
+
private $wpml_service;
|
35 |
+
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Toolset_Wp_Query_Adjustments_Table_Join_Manager constructor.
|
39 |
+
*
|
40 |
+
* @param wpdb|null $wpdb_di
|
41 |
+
* @param Toolset_Relationship_Database_Unique_Table_Alias|null $unique_table_alias_di
|
42 |
+
* @param Toolset_Relationship_Table_Name|null $table_name_di
|
43 |
+
* @param Toolset_Relationship_Database_Operations|null $database_operations_di
|
44 |
+
* @param Toolset_Relationship_Definition_Repository|null $definition_repository_di
|
45 |
+
* @param Toolset_WPML_Compatibility|null $wpml_service_di
|
46 |
+
*/
|
47 |
+
public function __construct(
|
48 |
+
wpdb $wpdb_di = null,
|
49 |
+
Toolset_Relationship_Database_Unique_Table_Alias $unique_table_alias_di = null,
|
50 |
+
Toolset_Relationship_Table_Name $table_name_di = null,
|
51 |
+
Toolset_Relationship_Database_Operations $database_operations_di = null,
|
52 |
+
Toolset_Relationship_Definition_Repository $definition_repository_di = null,
|
53 |
+
Toolset_WPML_Compatibility $wpml_service_di = null
|
54 |
+
) {
|
55 |
+
parent::__construct( $wpdb_di );
|
56 |
+
$this->uniqe_table_alias = $unique_table_alias_di ?: new Toolset_Relationship_Database_Unique_Table_Alias();
|
57 |
+
$this->table_name = $table_name_di ?: new Toolset_Relationship_Table_Name();
|
58 |
+
$this->database_operations = $database_operations_di ?: Toolset_Relationship_Database_Operations::get_instance();
|
59 |
+
$this->definition_repository = $definition_repository_di ?: Toolset_Relationship_Definition_Repository::get_instance();
|
60 |
+
$this->wpml_service = $wpml_service_di ?: Toolset_WPML_Compatibility::get_instance();
|
61 |
+
}
|
62 |
+
|
63 |
+
|
64 |
+
/**
|
65 |
+
* Generate the JOIN clause based on previously made requests for table aliases.
|
66 |
+
*
|
67 |
+
* @return string
|
68 |
+
*/
|
69 |
+
public function get_join_clauses() {
|
70 |
+
$results = '';
|
71 |
+
|
72 |
+
foreach( $this->joins as $relationship_slug => $role_joins ) {
|
73 |
+
foreach( $role_joins as $role_name => $table_alias ) {
|
74 |
+
$results .= $this->get_single_join_clause( $relationship_slug, $table_alias, $role_name );
|
75 |
+
}
|
76 |
+
}
|
77 |
+
|
78 |
+
return $results;
|
79 |
+
}
|
80 |
+
|
81 |
+
|
82 |
+
private function get_single_join_clause( $relationship_slug, $associations_table_alias, $role_name ) {
|
83 |
+
|
84 |
+
$element_id_column = $this->database_operations->role_to_column( $role_name );
|
85 |
+
$relationship_definition = $this->definition_repository->get_definition( $relationship_slug );
|
86 |
+
|
87 |
+
if( null === $relationship_definition ) {
|
88 |
+
// This should have failed already during the WHERE clause processing and never get to this point.
|
89 |
+
throw new InvalidArgumentException( 'Unknown relationship "' . sanitize_text_field( $relationship_slug ) . '".' );
|
90 |
+
}
|
91 |
+
|
92 |
+
$relationship_id = $relationship_definition->get_row_id();
|
93 |
+
|
94 |
+
if( $this->wpml_service->is_wpml_active_and_configured() ) {
|
95 |
+
return $this->get_single_join_clause_for_wpml( $relationship_id, $associations_table_alias, $element_id_column );
|
96 |
+
}
|
97 |
+
|
98 |
+
return $this->wpdb->prepare(
|
99 |
+
"JOIN {$this->table_name->association_table()} AS {$associations_table_alias} ON (
|
100 |
+
wp_posts.ID = {$associations_table_alias}.{$element_id_column}
|
101 |
+
AND {$associations_table_alias}.relationship_id = %d
|
102 |
+
) ",
|
103 |
+
$relationship_id
|
104 |
+
);
|
105 |
+
}
|
106 |
+
|
107 |
+
|
108 |
+
/**
|
109 |
+
* Join the associations table by either using the wp_posts.ID directly or by
|
110 |
+
* translating it to the default language first.
|
111 |
+
*
|
112 |
+
* @param int $relationship_id
|
113 |
+
* @param string $associations_table_alias
|
114 |
+
* @param string $element_id_column
|
115 |
+
*
|
116 |
+
* @return string
|
117 |
+
*/
|
118 |
+
private function get_single_join_clause_for_wpml( $relationship_id, $associations_table_alias, $element_id_column ) {
|
119 |
+
|
120 |
+
$clause = $this->wpdb->prepare(
|
121 |
+
"
|
122 |
+
# join the icl_translations table independently from WPML's 't'
|
123 |
+
# because that one may not be joined at all time, but we
|
124 |
+
# need it always - this is safer than trying to reuse the 't' one
|
125 |
+
LEFT JOIN {$this->wpml_service->icl_translations_table_name()} AS toolset_post_t ON (
|
126 |
+
wp_posts.ID = toolset_post_t.element_id
|
127 |
+
AND toolset_post_t.element_type = CONCAT('post_', wp_posts.post_type)
|
128 |
+
) LEFT JOIN {$this->wpml_service->icl_translations_table_name()} AS toolset_post_dl ON (
|
129 |
+
toolset_post_t.trid = toolset_post_dl.trid
|
130 |
+
AND toolset_post_dl.language_code = %s
|
131 |
+
) JOIN {$this->table_name->association_table()} AS {$associations_table_alias} ON (
|
132 |
+
(
|
133 |
+
# join the association row if either the post ID matches the
|
134 |
+
# proper column in the associations table or if the ID of the default
|
135 |
+
# language version of the post matches it
|
136 |
+
wp_posts.ID = {$associations_table_alias}.{$element_id_column}
|
137 |
+
OR toolset_post_dl.element_id = {$associations_table_alias}.{$element_id_column}
|
138 |
+
)
|
139 |
+
AND {$associations_table_alias}.relationship_id = %d
|
140 |
+
)",
|
141 |
+
$this->wpml_service->get_default_language(),
|
142 |
+
$relationship_id
|
143 |
+
);
|
144 |
+
|
145 |
+
return $clause;
|
146 |
+
}
|
147 |
+
|
148 |
+
|
149 |
+
/**
|
150 |
+
* Request an alias for the associations table.
|
151 |
+
*
|
152 |
+
* The table will be JOINed on wp_posts.ID by a given relationship slug and element role.
|
153 |
+
*
|
154 |
+
* @param string $relationship_slug
|
155 |
+
* @param IToolset_Relationship_Role $role
|
156 |
+
*
|
157 |
+
* @return string
|
158 |
+
*/
|
159 |
+
public function associations_table( $relationship_slug, IToolset_Relationship_Role $role ) {
|
160 |
+
if( ! array_key_exists( $relationship_slug, $this->joins ) ) {
|
161 |
+
$this->joins[ $relationship_slug ] = array();
|
162 |
+
}
|
163 |
+
|
164 |
+
if( ! array_key_exists( $role->get_name(), $this->joins[ $relationship_slug ] ) ) {
|
165 |
+
$unique_alias = $this->uniqe_table_alias->generate( $this->table_name->association_table(), true );
|
166 |
+
$this->joins[ $relationship_slug ][ $role->get_name() ] = $unique_alias;
|
167 |
+
}
|
168 |
+
|
169 |
+
return $this->joins[ $relationship_slug ][ $role->get_name() ];
|
170 |
+
}
|
171 |
+
|
172 |
+
}
|
vendor/toolset/toolset-common/inc/autoloaded/wpdb_user.php
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class that uses $wpdb, can be extended to avoid repetition of the dependency injection.
|
5 |
+
*
|
6 |
+
* @since 2.5.10
|
7 |
+
*/
|
8 |
+
abstract class Toolset_Wpdb_User {
|
9 |
+
|
10 |
+
|
11 |
+
/** @var wpdb */
|
12 |
+
protected $wpdb;
|
13 |
+
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Toolset_Wpdb_User constructor.
|
17 |
+
*
|
18 |
+
* @param wpdb|null $wpdb_di
|
19 |
+
*/
|
20 |
+
public function __construct( wpdb $wpdb_di = null ) {
|
21 |
+
global $wpdb;
|
22 |
+
|
23 |
+
if( null === $wpdb_di ) {
|
24 |
+
$this->wpdb = $wpdb;
|
25 |
+
} else {
|
26 |
+
$this->wpdb = $wpdb_di;
|
27 |
+
}
|
28 |
+
}
|
29 |
+
|
30 |
+
}
|
vendor/toolset/toolset-common/inc/autoloaded/wpml_utils.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
/**
|
4 |
* WPML-related helper functions.
|
5 |
*
|
6 |
-
*
|
7 |
*
|
8 |
* @since m2m
|
9 |
*/
|
@@ -12,6 +12,7 @@ class Toolset_Wpml_Utils {
|
|
12 |
|
13 |
/**
|
14 |
* @return string icl_translations table name.
|
|
|
15 |
*/
|
16 |
public static function icl_translations_tn() {
|
17 |
global $wpdb;
|
@@ -89,6 +90,7 @@ class Toolset_Wpml_Utils {
|
|
89 |
* @param int $post_id
|
90 |
* @return int "trid" value or zero.
|
91 |
* @since m2m
|
|
|
92 |
*/
|
93 |
public static function get_post_trid( $post_id ) {
|
94 |
global $wpdb;
|
@@ -116,6 +118,7 @@ class Toolset_Wpml_Utils {
|
|
116 |
* @param int $post_id
|
117 |
* @return int[]
|
118 |
* @since m2m
|
|
|
119 |
*/
|
120 |
public static function get_post_translations_directly( $post_id ) {
|
121 |
|
@@ -133,12 +136,12 @@ class Toolset_Wpml_Utils {
|
|
133 |
}
|
134 |
|
135 |
$query = $wpdb->prepare(
|
136 |
-
"SELECT
|
137 |
-
element_id AS post_id,
|
138 |
-
language_code AS language_code
|
139 |
-
FROM
|
140 |
$icl_translations_table
|
141 |
-
WHERE
|
142 |
element_type LIKE %s
|
143 |
AND trid = %d",
|
144 |
'post_%',
|
@@ -164,15 +167,13 @@ class Toolset_Wpml_Utils {
|
|
164 |
* @param string $post_type_slug
|
165 |
* @return bool
|
166 |
* @since m2m
|
|
|
167 |
*/
|
168 |
public static function is_post_type_translatable( $post_type_slug ) {
|
169 |
-
return (
|
170 |
}
|
171 |
|
172 |
|
173 |
-
private static $current_language = null;
|
174 |
-
|
175 |
-
|
176 |
/**
|
177 |
* Get the current language.
|
178 |
*
|
@@ -180,21 +181,13 @@ class Toolset_Wpml_Utils {
|
|
180 |
*
|
181 |
* @return string
|
182 |
* @since m2m
|
|
|
183 |
*/
|
184 |
public static function get_current_language() {
|
185 |
-
|
186 |
-
null === self::$current_language
|
187 |
-
&& Toolset_WPML_Compatibility::get_instance()->is_wpml_active_and_configured()
|
188 |
-
) {
|
189 |
-
self::$current_language = apply_filters( 'wpml_current_language', null );
|
190 |
-
}
|
191 |
-
return self::$current_language;
|
192 |
}
|
193 |
|
194 |
|
195 |
-
private static $default_language = null;
|
196 |
-
|
197 |
-
|
198 |
/**
|
199 |
* Get the default site language.
|
200 |
*
|
@@ -202,15 +195,10 @@ class Toolset_Wpml_Utils {
|
|
202 |
*
|
203 |
* @return string
|
204 |
* @since m2m
|
|
|
205 |
*/
|
206 |
public static function get_default_language() {
|
207 |
-
|
208 |
-
null === self::$default_language
|
209 |
-
&& Toolset_WPML_Compatibility::get_instance()->is_wpml_active_and_configured()
|
210 |
-
) {
|
211 |
-
self::$default_language = apply_filters( 'wpml_default_language', null );
|
212 |
-
}
|
213 |
-
return self::$default_language;
|
214 |
}
|
215 |
|
216 |
|
@@ -245,4 +233,41 @@ class Toolset_Wpml_Utils {
|
|
245 |
}
|
246 |
}
|
247 |
|
248 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
/**
|
4 |
* WPML-related helper functions.
|
5 |
*
|
6 |
+
* @deprecated Do not add new methods. Merge this class with Toolset_Wpml_Compatibility.
|
7 |
*
|
8 |
* @since m2m
|
9 |
*/
|
12 |
|
13 |
/**
|
14 |
* @return string icl_translations table name.
|
15 |
+
* @deprecated Use Toolset_WPML_Compatibility::icl_translations_table_name
|
16 |
*/
|
17 |
public static function icl_translations_tn() {
|
18 |
global $wpdb;
|
90 |
* @param int $post_id
|
91 |
* @return int "trid" value or zero.
|
92 |
* @since m2m
|
93 |
+
* @deprecated Use Toolset_WPML_Compatibility::get_post_trid
|
94 |
*/
|
95 |
public static function get_post_trid( $post_id ) {
|
96 |
global $wpdb;
|
118 |
* @param int $post_id
|
119 |
* @return int[]
|
120 |
* @since m2m
|
121 |
+
* @deprecated Use Toolset_WPML_Compatibility::get_post_translations_directly
|
122 |
*/
|
123 |
public static function get_post_translations_directly( $post_id ) {
|
124 |
|
136 |
}
|
137 |
|
138 |
$query = $wpdb->prepare(
|
139 |
+
"SELECT
|
140 |
+
element_id AS post_id,
|
141 |
+
language_code AS language_code
|
142 |
+
FROM
|
143 |
$icl_translations_table
|
144 |
+
WHERE
|
145 |
element_type LIKE %s
|
146 |
AND trid = %d",
|
147 |
'post_%',
|
167 |
* @param string $post_type_slug
|
168 |
* @return bool
|
169 |
* @since m2m
|
170 |
+
* @deprecated Use Toolset_WPML_Compatibility::is_post_type_translatable() instead.
|
171 |
*/
|
172 |
public static function is_post_type_translatable( $post_type_slug ) {
|
173 |
+
return Toolset_WPML_Compatibility::get_instance()->is_post_type_translatable( $post_type_slug );
|
174 |
}
|
175 |
|
176 |
|
|
|
|
|
|
|
177 |
/**
|
178 |
* Get the current language.
|
179 |
*
|
181 |
*
|
182 |
* @return string
|
183 |
* @since m2m
|
184 |
+
* @deprecated Use Toolset_WPML_Compatibility::get_current_language()
|
185 |
*/
|
186 |
public static function get_current_language() {
|
187 |
+
return Toolset_WPML_Compatibility::get_instance()->get_current_language();
|
|
|
|
|
|
|
|
|
|
|
|
|
188 |
}
|
189 |
|
190 |
|
|
|
|
|
|
|
191 |
/**
|
192 |
* Get the default site language.
|
193 |
*
|
195 |
*
|
196 |
* @return string
|
197 |
* @since m2m
|
198 |
+
* @deprecated Use Toolset_WPML_Compatibility::get_default_language()
|
199 |
*/
|
200 |
public static function get_default_language() {
|
201 |
+
return Toolset_WPML_Compatibility::get_instance()->get_default_language();
|
|
|
|
|
|
|
|
|
|
|
|
|
202 |
}
|
203 |
|
204 |
|
233 |
}
|
234 |
}
|
235 |
|
236 |
+
|
237 |
+
/**
|
238 |
+
* Check whether a default language of a post exists.
|
239 |
+
*
|
240 |
+
* Returns true if WPML is not active, as in that case, all posts are considered
|
241 |
+
* to be in the "default" language.
|
242 |
+
*
|
243 |
+
* Also returns true if the provided post itself is in the default language.
|
244 |
+
*
|
245 |
+
* @param int $post_id ID of the post
|
246 |
+
* @return boolean
|
247 |
+
* @since m2m
|
248 |
+
*/
|
249 |
+
public static function has_default_language_translation( $post_id ) {
|
250 |
+
$wpml_service = Toolset_WPML_Compatibility::get_instance();
|
251 |
+
if( ! $wpml_service->is_wpml_active_and_configured() ) {
|
252 |
+
return true;
|
253 |
+
}
|
254 |
+
|
255 |
+
$default_language = $wpml_service->get_default_language();
|
256 |
+
|
257 |
+
$translated_post_id = apply_filters( 'wpml_object_id', (int) $post_id, 'any', false, $default_language );
|
258 |
+
|
259 |
+
return ( null !== $translated_post_id );
|
260 |
+
}
|
261 |
+
|
262 |
+
|
263 |
+
/**
|
264 |
+
* Gets active languages information
|
265 |
+
*
|
266 |
+
* @return array
|
267 |
+
* @since m2m
|
268 |
+
* @link https://wpml.org/documentation/getting-started-guide/language-setup/custom-language-switcher/
|
269 |
+
*/
|
270 |
+
public static function get_active_languages() {
|
271 |
+
return apply_filters( 'wpml_active_languages', null, '' );
|
272 |
+
}
|
273 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/association.php
DELETED
@@ -1,191 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Translation-unaware m2m association between two elements.
|
5 |
-
*
|
6 |
-
* This can be used only when the multilingual mode is off/transitional
|
7 |
-
*
|
8 |
-
* Not to be used directly outside of the m2m API.
|
9 |
-
*
|
10 |
-
* @since m2m
|
11 |
-
*/
|
12 |
-
class Toolset_Association extends Toolset_Association_Base {
|
13 |
-
|
14 |
-
|
15 |
-
/** @var int[] IDs of elements, always complete. */
|
16 |
-
private $element_ids = array();
|
17 |
-
|
18 |
-
/** @var int */
|
19 |
-
private $intermediary_id;
|
20 |
-
|
21 |
-
|
22 |
-
/**
|
23 |
-
* Toolset_Association constructor.
|
24 |
-
*
|
25 |
-
* See superclass for parameter description.
|
26 |
-
*
|
27 |
-
* It is assumed that the relationship definition uses the Toolset_Relationship_Driver driver.
|
28 |
-
*
|
29 |
-
* @param int $trid Translation group ID.
|
30 |
-
* @param Toolset_Relationship_Definition $relationship_definition
|
31 |
-
* @param array $element_sources Associative array with both element keys. Each item can be either an ID
|
32 |
-
* or a matching Toolset_Element instance.
|
33 |
-
* @param int|Toolset_Post $intermediary_source Intermediary post with association fields or its ID. If a
|
34 |
-
* Toolset_Post instance is provided, it must have the type matching with the relationship definition.
|
35 |
-
*
|
36 |
-
* @since m2m
|
37 |
-
*/
|
38 |
-
public function __construct(
|
39 |
-
$trid, Toolset_Relationship_Definition $relationship_definition, $element_sources, $intermediary_source
|
40 |
-
) {
|
41 |
-
|
42 |
-
parent::__construct( $trid, $relationship_definition );
|
43 |
-
|
44 |
-
foreach( Toolset_Relationship_Role::parent_child_role_names() as $element_role ) {
|
45 |
-
$element_source = toolset_getarr( $element_sources, $element_role, null );
|
46 |
-
|
47 |
-
if( is_array( $element_source ) && 1 === count( $element_source ) ) {
|
48 |
-
$element_source = array_pop( $element_source );
|
49 |
-
}
|
50 |
-
|
51 |
-
if( $element_source instanceof Toolset_Element ) {
|
52 |
-
$this->element_ids[ $element_role ] = $element_source->get_id();
|
53 |
-
$this->elements[ $element_role ] = $element_source;
|
54 |
-
} elseif( Toolset_Utils::is_natural_numeric( $element_source ) ) {
|
55 |
-
$this->element_ids[ $element_role ] = $element_source;
|
56 |
-
} else {
|
57 |
-
throw new InvalidArgumentException( 'Invalid or missing element source.' );
|
58 |
-
}
|
59 |
-
}
|
60 |
-
|
61 |
-
if( is_array( $intermediary_source ) && 1 === count( $intermediary_source ) ) {
|
62 |
-
$intermediary_source = array_pop( $intermediary_source );
|
63 |
-
}
|
64 |
-
|
65 |
-
// Intermediary posts needs special care, as always.
|
66 |
-
if( Toolset_Utils::is_nonnegative_integer( $intermediary_source ) ) {
|
67 |
-
$this->intermediary_id = (int) $intermediary_source;
|
68 |
-
} elseif( $intermediary_source instanceof Toolset_Post ) {
|
69 |
-
/** @var Toolset_Relationship_Driver $driver */
|
70 |
-
$driver = $this->get_definition()->get_driver();
|
71 |
-
if( $intermediary_source->get_type() != $driver->get_intermediary_post_type() ) {
|
72 |
-
throw new InvalidArgumentException( 'Invalid post type of the intermediary post.');
|
73 |
-
}
|
74 |
-
|
75 |
-
$this->intermediary_id = $intermediary_source->get_id();
|
76 |
-
$this->intermediary_post = $intermediary_source;
|
77 |
-
} else {
|
78 |
-
throw new InvalidArgumentException( 'Invalid intermediary post source.' );
|
79 |
-
}
|
80 |
-
}
|
81 |
-
|
82 |
-
|
83 |
-
/**
|
84 |
-
* Get an ID of an element in the associaton.
|
85 |
-
*
|
86 |
-
* @param string $element_role Must be a valid role.
|
87 |
-
*
|
88 |
-
* @return int
|
89 |
-
* @since m2m
|
90 |
-
*/
|
91 |
-
protected function get_element_id( $element_role ) {
|
92 |
-
return $this->element_ids[ $element_role ];
|
93 |
-
}
|
94 |
-
|
95 |
-
|
96 |
-
/**
|
97 |
-
* Get an association element.
|
98 |
-
*
|
99 |
-
* Instantiates an element from its ID if that hasn't been done yet.
|
100 |
-
*
|
101 |
-
* @param string $element_role
|
102 |
-
* @return Toolset_Element
|
103 |
-
* @throws InvalidArgumentException
|
104 |
-
* @since m2m
|
105 |
-
*/
|
106 |
-
public function get_element( $element_role ) {
|
107 |
-
self::validate_element_role( $element_role );
|
108 |
-
if( ! array_key_exists( $element_role, $this->elements ) ) {
|
109 |
-
$this->elements[ $element_role ] = Toolset_Element::get_instance(
|
110 |
-
$this->get_element_domain( $element_role ),
|
111 |
-
$this->get_element_id( $element_role )
|
112 |
-
);
|
113 |
-
}
|
114 |
-
|
115 |
-
return $this->elements[ $element_role ];
|
116 |
-
}
|
117 |
-
|
118 |
-
|
119 |
-
/**
|
120 |
-
* @inheritdoc
|
121 |
-
* @return null|Toolset_Post
|
122 |
-
*/
|
123 |
-
protected function get_intermediary_post() {
|
124 |
-
if( 0 === $this->intermediary_id ) {
|
125 |
-
return null;
|
126 |
-
}
|
127 |
-
|
128 |
-
if( null === $this->intermediary_post ) {
|
129 |
-
try {
|
130 |
-
$this->intermediary_post = Toolset_Element::get_instance( Toolset_Field_Utils::DOMAIN_POSTS, $this->intermediary_id );
|
131 |
-
} catch( Exception $e ) {
|
132 |
-
// We couldn't load the post, it probably doesn't exist. Reset the ID to avoid checking again.
|
133 |
-
$this->intermediary_id = 0;
|
134 |
-
}
|
135 |
-
}
|
136 |
-
|
137 |
-
return $this->intermediary_post;
|
138 |
-
}
|
139 |
-
|
140 |
-
|
141 |
-
/**
|
142 |
-
* @inheritdoc
|
143 |
-
* @return bool|Toolset_Field_Instance[]
|
144 |
-
*/
|
145 |
-
public function get_fields() {
|
146 |
-
if( ! $this->has_fields() ) {
|
147 |
-
return false;
|
148 |
-
}
|
149 |
-
|
150 |
-
return $this->intermediary_post->get_fields();
|
151 |
-
}
|
152 |
-
|
153 |
-
|
154 |
-
/**
|
155 |
-
* @inheritdoc
|
156 |
-
* @param string|Toolset_Field_Definition $field_source
|
157 |
-
* @return bool|Toolset_Field_Instance
|
158 |
-
*/
|
159 |
-
public function get_field( $field_source ) {
|
160 |
-
if( ! $this->has_fields() ) {
|
161 |
-
return false;
|
162 |
-
}
|
163 |
-
|
164 |
-
return $this->intermediary_post->get_field( $field_source );
|
165 |
-
}
|
166 |
-
|
167 |
-
|
168 |
-
/**
|
169 |
-
* Get the ID of the intermediary post with association fields.
|
170 |
-
*
|
171 |
-
* Required for the [types] shortcode, but use with consideration.
|
172 |
-
*
|
173 |
-
* @return int Post ID or zero if no post exists.
|
174 |
-
* @since m2m
|
175 |
-
*/
|
176 |
-
public function get_intermediary_id() {
|
177 |
-
return $this->intermediary_id;
|
178 |
-
}
|
179 |
-
|
180 |
-
|
181 |
-
/**
|
182 |
-
* @return bool
|
183 |
-
* @since m2m
|
184 |
-
*/
|
185 |
-
public function has_intermediary_post() {
|
186 |
-
return ( 0 != $this->get_intermediary_id() );
|
187 |
-
}
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/toolset/toolset-common/inc/m2m/association/association.php
ADDED
@@ -0,0 +1,472 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Translation-unaware m2m association between two elements.
|
5 |
+
*
|
6 |
+
* This can be used only when the multilingual mode is off/transitional
|
7 |
+
*
|
8 |
+
* Not to be used directly outside of the m2m API.
|
9 |
+
*
|
10 |
+
* @since m2m
|
11 |
+
* @refactoring!!!! Store intermediary ID and post object in the same way as the other elements.
|
12 |
+
*/
|
13 |
+
class Toolset_Association implements IToolset_Association {
|
14 |
+
|
15 |
+
|
16 |
+
/**
|
17 |
+
* @var int[] IDs of elements, always complete.
|
18 |
+
*
|
19 |
+
* However, in case we deal with translatable elements, this will hold only the IDs
|
20 |
+
* of the default language versions, so these values can't be always used directly.
|
21 |
+
* get_element_id() will handle the translation if necessary.
|
22 |
+
*/
|
23 |
+
private $element_ids = array();
|
24 |
+
|
25 |
+
|
26 |
+
/**
|
27 |
+
* @var int Intermediary post ID or zero if there is no intermediary post at all.
|
28 |
+
*
|
29 |
+
* See the note for $element_ids. Same goes here.
|
30 |
+
*/
|
31 |
+
private $intermediary_id;
|
32 |
+
|
33 |
+
|
34 |
+
/** @var Toolset_Relationship_Definition */
|
35 |
+
private $relationship_definition;
|
36 |
+
|
37 |
+
|
38 |
+
/**
|
39 |
+
* @var Toolset_Element[] Actual elements, loaded on demand. Use self::get_element() to obtain them.
|
40 |
+
*/
|
41 |
+
protected $elements = array();
|
42 |
+
|
43 |
+
|
44 |
+
/**
|
45 |
+
* @var int Translation group ID.
|
46 |
+
*/
|
47 |
+
private $uid;
|
48 |
+
|
49 |
+
|
50 |
+
/**
|
51 |
+
* @var null|IToolset_Post
|
52 |
+
*/
|
53 |
+
protected $intermediary_post;
|
54 |
+
|
55 |
+
|
56 |
+
/** @var Toolset_WPML_Compatibility */
|
57 |
+
private $wpml_service;
|
58 |
+
|
59 |
+
|
60 |
+
/** @var Toolset_Element_Factory */
|
61 |
+
private $_element_factory;
|
62 |
+
|
63 |
+
|
64 |
+
/** @noinspection PhpDocRedundantThrowsInspection */
|
65 |
+
/**
|
66 |
+
* Toolset_Association constructor.
|
67 |
+
*
|
68 |
+
* Note that no checks about elements with respect to the relationship definition are being performed here.
|
69 |
+
* The caller needs to ensure everything is valid (domains, types, other conditions). This is handled well in the
|
70 |
+
* association factory.
|
71 |
+
*
|
72 |
+
* It is assumed that the relationship definition uses the Toolset_Relationship_Driver driver.
|
73 |
+
*
|
74 |
+
* @param int $uid Unique association ID.
|
75 |
+
* @param Toolset_Relationship_Definition $relationship_definition
|
76 |
+
* @param array $element_sources Associative array with both element keys. Each item can be either an ID
|
77 |
+
* or a matching Toolset_Element instance.
|
78 |
+
* @param int|Toolset_Post $intermediary_source Intermediary post with association fields or its ID. If a
|
79 |
+
* Toolset_Post instance is provided, it must have the type matching with the relationship definition.
|
80 |
+
* @param Toolset_WPML_Compatibility|null $wpml_service_di
|
81 |
+
* @param Toolset_Element_Factory|null $element_factory_di
|
82 |
+
* @throws Toolset_Element_Exception_Element_Doesnt_Exist
|
83 |
+
* @since m2m
|
84 |
+
*/
|
85 |
+
public function __construct(
|
86 |
+
$uid,
|
87 |
+
Toolset_Relationship_Definition $relationship_definition,
|
88 |
+
$element_sources,
|
89 |
+
$intermediary_source,
|
90 |
+
Toolset_WPML_Compatibility $wpml_service_di = null,
|
91 |
+
Toolset_Element_Factory $element_factory_di = null
|
92 |
+
) {
|
93 |
+
$this->wpml_service = ( null === $wpml_service_di ? Toolset_WPML_Compatibility::get_instance() : $wpml_service_di );
|
94 |
+
$this->_element_factory = ( null === $element_factory_di ? new Toolset_Element_Factory( null, $wpml_service_di ) : $element_factory_di );
|
95 |
+
|
96 |
+
if( ! Toolset_Utils::is_nonnegative_numeric( $uid ) ) {
|
97 |
+
throw new InvalidArgumentException();
|
98 |
+
}
|
99 |
+
|
100 |
+
$this->relationship_definition = $relationship_definition;
|
101 |
+
$this->uid = (int) $uid;
|
102 |
+
|
103 |
+
foreach( Toolset_Relationship_Role::parent_child_role_names() as $element_role ) {
|
104 |
+
$element_source = toolset_getarr( $element_sources, $element_role, null );
|
105 |
+
$this->store_element( $element_source, $element_role );
|
106 |
+
}
|
107 |
+
|
108 |
+
$this->store_element( $intermediary_source, Toolset_Relationship_Role::INTERMEDIARY );
|
109 |
+
}
|
110 |
+
|
111 |
+
|
112 |
+
/**
|
113 |
+
* Understand the element source and store it properly without wasting too much performance.
|
114 |
+
*
|
115 |
+
* Sometimes, the association is getting only element IDs, other times, it will get existing
|
116 |
+
* IToolset_Element instances, or a mix thereof. If possible, we wait with instantiating the
|
117 |
+
* elements as long as possible, to reduce memory and performance requirements.
|
118 |
+
*
|
119 |
+
* However, if WPML is active and there's a risk of some of those IDs or elements being
|
120 |
+
* translated, we need to make sure that we store only element IDs in the default language.
|
121 |
+
* In that case, we will have to instantiate the element and translate it.
|
122 |
+
*
|
123 |
+
* Note: For historical reasons, this will also survive an array with a single item,
|
124 |
+
* which is the actual element source.
|
125 |
+
*
|
126 |
+
* @param int|string|IToolset_Element|array $element_source
|
127 |
+
* @param string $role_name
|
128 |
+
*
|
129 |
+
* @throws Toolset_Element_Exception_Element_Doesnt_Exist
|
130 |
+
*/
|
131 |
+
private function store_element( $element_source, $role_name ) {
|
132 |
+
$is_intermediary = Toolset_Relationship_Role::INTERMEDIARY === $role_name;
|
133 |
+
|
134 |
+
if( is_array( $element_source ) && 1 === count( $element_source ) ) {
|
135 |
+
$element_source = array_pop( $element_source );
|
136 |
+
}
|
137 |
+
|
138 |
+
if(
|
139 |
+
$is_intermediary
|
140 |
+
&& is_numeric( $element_source )
|
141 |
+
&& 0 === (int) $element_source
|
142 |
+
) {
|
143 |
+
// No intermediary post.
|
144 |
+
$this->intermediary_id = 0;
|
145 |
+
return;
|
146 |
+
}
|
147 |
+
|
148 |
+
if( $this->can_be_translated() ) {
|
149 |
+
// There's a chance we might need a translation.
|
150 |
+
try {
|
151 |
+
if( $element_source instanceof IToolset_Element ) {
|
152 |
+
$element = $element_source;
|
153 |
+
} else {
|
154 |
+
$element = $this->get_element_factory()->get_element(
|
155 |
+
$this->get_definition()->get_domain( Toolset_Relationship_Role::role_from_name( $role_name ) ),
|
156 |
+
(int) $element_source
|
157 |
+
);
|
158 |
+
}
|
159 |
+
|
160 |
+
$element_id = $element->translate( $this->wpml_service->get_default_language() )->get_id();
|
161 |
+
|
162 |
+
} catch( Toolset_Element_Exception_Element_Doesnt_Exist $e ) {
|
163 |
+
// We'll survive only a missing intermediary post.
|
164 |
+
if( ! $is_intermediary ) {
|
165 |
+
throw $e;
|
166 |
+
}
|
167 |
+
|
168 |
+
$element = null;
|
169 |
+
$element_id = 0;
|
170 |
+
}
|
171 |
+
} elseif( $element_source instanceof IToolset_Element ) {
|
172 |
+
// No translations from now on.
|
173 |
+
|
174 |
+
$element = $element_source;
|
175 |
+
$element_id = $element_source->get_id();
|
176 |
+
} elseif( Toolset_Utils::is_natural_numeric( $element_source ) ) {
|
177 |
+
$element = null;
|
178 |
+
$element_id = (int) $element_source;
|
179 |
+
} else {
|
180 |
+
throw new InvalidArgumentException( 'Invalid or missing element source.' );
|
181 |
+
}
|
182 |
+
|
183 |
+
if( $is_intermediary ) {
|
184 |
+
$this->intermediary_id = $element_id;
|
185 |
+
if( null !== $element ) {
|
186 |
+
$this->intermediary_post = $element;
|
187 |
+
}
|
188 |
+
} else {
|
189 |
+
$this->element_ids[ $role_name ] = $element_id;
|
190 |
+
if( null !== $element ) {
|
191 |
+
$this->elements[ $role_name ] = $element;
|
192 |
+
}
|
193 |
+
}
|
194 |
+
|
195 |
+
}
|
196 |
+
|
197 |
+
|
198 |
+
private function can_be_translated() {
|
199 |
+
return (
|
200 |
+
$this->wpml_service->is_wpml_active_and_configured()
|
201 |
+
&& $this->get_definition()->is_translatable()
|
202 |
+
);
|
203 |
+
}
|
204 |
+
|
205 |
+
|
206 |
+
/**
|
207 |
+
* @return Toolset_Relationship_Definition
|
208 |
+
*/
|
209 |
+
public function get_definition() { return $this->relationship_definition; }
|
210 |
+
|
211 |
+
|
212 |
+
/**
|
213 |
+
* Get domain of selected association element.
|
214 |
+
*
|
215 |
+
* @param string $element_role
|
216 |
+
*
|
217 |
+
* @return string Valid domain name as defined in Toolset_Field_Utils.
|
218 |
+
* @since m2m
|
219 |
+
*/
|
220 |
+
protected function get_element_domain( $element_role ) {
|
221 |
+
$relationship_definition = $this->get_definition();
|
222 |
+
$element_type = $relationship_definition->get_element_type( $element_role );
|
223 |
+
return $element_type->get_domain();
|
224 |
+
}
|
225 |
+
|
226 |
+
|
227 |
+
/**
|
228 |
+
* Get an ID of an element in the associaton.
|
229 |
+
*
|
230 |
+
* @param string|IToolset_Relationship_Role $element_role Must be a valid role.
|
231 |
+
*
|
232 |
+
* @return int
|
233 |
+
* @since m2m
|
234 |
+
* @throws Toolset_Element_Exception_Element_Doesnt_Exist
|
235 |
+
*/
|
236 |
+
public function get_element_id( $element_role ) {
|
237 |
+
$element_role_name = Toolset_Relationship_Role::name_from_role( $element_role );
|
238 |
+
|
239 |
+
if( ! $this->can_be_translated() ) {
|
240 |
+
if( Toolset_Relationship_Role::INTERMEDIARY === $element_role_name ) {
|
241 |
+
return $this->intermediary_id;
|
242 |
+
}
|
243 |
+
|
244 |
+
return $this->element_ids[ $element_role_name ];
|
245 |
+
}
|
246 |
+
|
247 |
+
// We have to use the actual element because we might have to return
|
248 |
+
// a translated ID.
|
249 |
+
$element = $this->get_element( $element_role_name );
|
250 |
+
|
251 |
+
if( null === $element ) {
|
252 |
+
// Intermediary post which doesn't exist.
|
253 |
+
return 0;
|
254 |
+
}
|
255 |
+
|
256 |
+
return $element->get_id();
|
257 |
+
}
|
258 |
+
|
259 |
+
|
260 |
+
/**
|
261 |
+
* Get an association element.
|
262 |
+
*
|
263 |
+
* Instantiates an element from its ID if that hasn't been done yet.
|
264 |
+
*
|
265 |
+
* @param string $element_role
|
266 |
+
*
|
267 |
+
* @return IToolset_Element|null
|
268 |
+
* @throws InvalidArgumentException
|
269 |
+
* @since m2m
|
270 |
+
* @throws Toolset_Element_Exception_Element_Doesnt_Exist
|
271 |
+
*/
|
272 |
+
public function get_element( $element_role ) {
|
273 |
+
$element_role_name = Toolset_Relationship_Role::name_from_role( $element_role );
|
274 |
+
|
275 |
+
if( Toolset_Relationship_Role::INTERMEDIARY === $element_role_name ) {
|
276 |
+
return $this->get_intermediary_post();
|
277 |
+
}
|
278 |
+
|
279 |
+
if(
|
280 |
+
! array_key_exists( $element_role_name, $this->elements )
|
281 |
+
|| null === $this->elements[ $element_role_name ]
|
282 |
+
) {
|
283 |
+
$this->elements[ $element_role_name ] = $this->get_element_factory()->get_element(
|
284 |
+
$this->get_element_domain( $element_role_name ),
|
285 |
+
$this->get_element_id( $element_role_name )
|
286 |
+
);
|
287 |
+
}
|
288 |
+
|
289 |
+
return $this->elements[ $element_role_name ];
|
290 |
+
}
|
291 |
+
|
292 |
+
|
293 |
+
/**
|
294 |
+
* Check that the element role is valid.
|
295 |
+
*
|
296 |
+
* @param string $element_role
|
297 |
+
*
|
298 |
+
* @throws InvalidArgumentException
|
299 |
+
* @since m2m
|
300 |
+
* @deprecated Use methods in Toolset_Relationship_Role instead.
|
301 |
+
*/
|
302 |
+
public static function validate_element_role( $element_role ) {
|
303 |
+
if( ! in_array( $element_role, Toolset_Relationship_Role::parent_child_role_names() ) ) {
|
304 |
+
throw new InvalidArgumentException( 'Invalid element key.' );
|
305 |
+
}
|
306 |
+
}
|
307 |
+
|
308 |
+
|
309 |
+
/**
|
310 |
+
* Shortcut to the relationship driver.
|
311 |
+
*
|
312 |
+
* @return Toolset_Relationship_Driver_Base
|
313 |
+
*/
|
314 |
+
public function get_driver() {
|
315 |
+
$relationship_definition = $this->get_definition();
|
316 |
+
return $relationship_definition->get_driver();
|
317 |
+
}
|
318 |
+
|
319 |
+
|
320 |
+
/**
|
321 |
+
* Get the unique identifier for the association.
|
322 |
+
*
|
323 |
+
* An integer value indicates that it's an ID from the associations table.
|
324 |
+
*
|
325 |
+
* It may be zero for associations that are not persisted yet.
|
326 |
+
*
|
327 |
+
* @return int
|
328 |
+
* @since m2m
|
329 |
+
*/
|
330 |
+
public function get_uid() {
|
331 |
+
return $this->uid;
|
332 |
+
}
|
333 |
+
|
334 |
+
|
335 |
+
/**
|
336 |
+
* Get the translation group ID of the association.
|
337 |
+
*
|
338 |
+
* @return int Translation group ID or zero if not supported.
|
339 |
+
* @deprecated Use get_uid() instead.
|
340 |
+
*/
|
341 |
+
public function get_trid() {
|
342 |
+
return $this->uid;
|
343 |
+
}
|
344 |
+
|
345 |
+
|
346 |
+
|
347 |
+
/**
|
348 |
+
* @inheritdoc
|
349 |
+
* @return null|IToolset_Post
|
350 |
+
*/
|
351 |
+
protected function get_intermediary_post() {
|
352 |
+
if( 0 === $this->intermediary_id ) {
|
353 |
+
return null;
|
354 |
+
}
|
355 |
+
|
356 |
+
if( null === $this->intermediary_post ) {
|
357 |
+
try {
|
358 |
+
$this->intermediary_post = $this->get_element_factory()->get_post( $this->intermediary_id );
|
359 |
+
} catch( Exception $e ) {
|
360 |
+
// We couldn't load the post, it probably doesn't exist. Reset the ID to avoid checking again.
|
361 |
+
$this->intermediary_id = 0;
|
362 |
+
}
|
363 |
+
}
|
364 |
+
|
365 |
+
return $this->intermediary_post;
|
366 |
+
}
|
367 |
+
|
368 |
+
|
369 |
+
/**
|
370 |
+
* @inheritdoc
|
371 |
+
* @return bool|Toolset_Field_Instance[]
|
372 |
+
*/
|
373 |
+
public function get_fields() {
|
374 |
+
if( ! $this->has_fields() ) {
|
375 |
+
return false;
|
376 |
+
}
|
377 |
+
|
378 |
+
return $this->get_intermediary_post()->get_fields();
|
379 |
+
}
|
380 |
+
|
381 |
+
|
382 |
+
/**
|
383 |
+
* @inheritdoc
|
384 |
+
* @param string|Toolset_Field_Definition $field_source
|
385 |
+
* @return bool|Toolset_Field_Instance
|
386 |
+
*/
|
387 |
+
public function get_field( $field_source ) {
|
388 |
+
if( ! $this->has_fields() ) {
|
389 |
+
return false;
|
390 |
+
}
|
391 |
+
|
392 |
+
return $this->get_intermediary_post()->get_field( $field_source );
|
393 |
+
}
|
394 |
+
|
395 |
+
|
396 |
+
/**
|
397 |
+
* Get the ID of the intermediary post with association fields.
|
398 |
+
*
|
399 |
+
* Required for the [types] shortcode, but use with consideration.
|
400 |
+
*
|
401 |
+
* @return int Post ID or zero if no post exists.
|
402 |
+
* @since m2m
|
403 |
+
*/
|
404 |
+
public function get_intermediary_id() {
|
405 |
+
if( ! $this->can_be_translated() ) {
|
406 |
+
return $this->intermediary_id;
|
407 |
+
}
|
408 |
+
|
409 |
+
// We have to go through the post object because it might be translated.
|
410 |
+
$intermediary_post = $this->get_intermediary_post();
|
411 |
+
if( null === $intermediary_post ) {
|
412 |
+
return 0;
|
413 |
+
}
|
414 |
+
return $intermediary_post->get_id();
|
415 |
+
}
|
416 |
+
|
417 |
+
|
418 |
+
/**
|
419 |
+
* @return bool
|
420 |
+
* @since m2m
|
421 |
+
*/
|
422 |
+
public function has_intermediary_post() {
|
423 |
+
return ( 0 !== $this->get_intermediary_id() );
|
424 |
+
}
|
425 |
+
|
426 |
+
|
427 |
+
/**
|
428 |
+
* @return Toolset_Element_Factory
|
429 |
+
*/
|
430 |
+
private function get_element_factory() {
|
431 |
+
if( null === $this->_element_factory ) {
|
432 |
+
$this->_element_factory = new Toolset_Element_Factory();
|
433 |
+
}
|
434 |
+
|
435 |
+
return $this->_element_factory;
|
436 |
+
}
|
437 |
+
|
438 |
+
|
439 |
+
/**
|
440 |
+
* @inheritdoc
|
441 |
+
*
|
442 |
+
* This needs to be called (internally) before accessing the intermediary post object.
|
443 |
+
*
|
444 |
+
* @return bool
|
445 |
+
* @since m2m
|
446 |
+
*/
|
447 |
+
public function has_fields() {
|
448 |
+
$intermediary_post = $this->get_intermediary_post();
|
449 |
+
|
450 |
+
if ( null === $intermediary_post ) {
|
451 |
+
return false;
|
452 |
+
}
|
453 |
+
|
454 |
+
return ( $intermediary_post->get_field_count() > 0 );
|
455 |
+
}
|
456 |
+
|
457 |
+
|
458 |
+
/**
|
459 |
+
* @inheritdoc
|
460 |
+
*
|
461 |
+
* @param string|Toolset_Field_Definition $field_source
|
462 |
+
* @return bool
|
463 |
+
*/
|
464 |
+
public function has_field( $field_source ) {
|
465 |
+
if( ! $this->has_fields() ) {
|
466 |
+
return false;
|
467 |
+
}
|
468 |
+
|
469 |
+
return $this->get_intermediary_post()->has_field( $field_source );
|
470 |
+
}
|
471 |
+
|
472 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/association/cleanup/association.php
ADDED
@@ -0,0 +1,73 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Removes a single association from the database and cleans up after.
|
5 |
+
*
|
6 |
+
* That means also deleting the intermediary post, if it exists.
|
7 |
+
*
|
8 |
+
* @since 2.5.10
|
9 |
+
*/
|
10 |
+
class Toolset_Association_Cleanup_Association extends Toolset_Wpdb_User {
|
11 |
+
|
12 |
+
|
13 |
+
/** @var Toolset_Relationship_Table_Name */
|
14 |
+
private $table_name;
|
15 |
+
|
16 |
+
|
17 |
+
/** @var Toolset_Association_Intermediary_Post_Persistence|null */
|
18 |
+
private $_intermediary_post_persistence;
|
19 |
+
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Toolset_Association_Cleanup_Association constructor.
|
23 |
+
*
|
24 |
+
* @param Toolset_Relationship_Table_Name|null $table_name_di
|
25 |
+
* @param wpdb|null $wpdb_di
|
26 |
+
* @param Toolset_Association_Intermediary_Post_Persistence|null $intermediary_post_persistence_di
|
27 |
+
*/
|
28 |
+
public function __construct(
|
29 |
+
Toolset_Relationship_Table_Name $table_name_di = null,
|
30 |
+
wpdb $wpdb_di = null,
|
31 |
+
Toolset_Association_Intermediary_Post_Persistence $intermediary_post_persistence_di = null
|
32 |
+
) {
|
33 |
+
parent::__construct( $wpdb_di );
|
34 |
+
$this->table_name = $table_name_di ?: new Toolset_Relationship_Table_Name();
|
35 |
+
$this->_intermediary_post_persistence = $intermediary_post_persistence_di;
|
36 |
+
}
|
37 |
+
|
38 |
+
|
39 |
+
/**
|
40 |
+
* @return Toolset_Association_Intermediary_Post_Persistence
|
41 |
+
*/
|
42 |
+
private function get_intermediary_post_persistence() {
|
43 |
+
if( null === $this->_intermediary_post_persistence ) {
|
44 |
+
$this->_intermediary_post_persistence = new Toolset_Association_Intermediary_Post_Persistence();
|
45 |
+
}
|
46 |
+
return $this->_intermediary_post_persistence;
|
47 |
+
}
|
48 |
+
|
49 |
+
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Permanently delete the provided association.
|
53 |
+
*
|
54 |
+
* @param IToolset_Association $association Association to delete. Do not use the instance
|
55 |
+
* after passing it to this method.
|
56 |
+
*
|
57 |
+
* @return Toolset_Result
|
58 |
+
*/
|
59 |
+
public function delete( IToolset_Association $association ) {
|
60 |
+
$this->get_intermediary_post_persistence()->maybe_delete_intermediary_post( $association );
|
61 |
+
|
62 |
+
$rows_updated = $this->wpdb->delete(
|
63 |
+
$this->table_name->association_table(),
|
64 |
+
array( 'id' => $association->get_uid() ),
|
65 |
+
'%d'
|
66 |
+
);
|
67 |
+
|
68 |
+
$is_success = ( false !== $rows_updated || 1 === $rows_updated );
|
69 |
+
|
70 |
+
return new Toolset_Result( $is_success );
|
71 |
+
}
|
72 |
+
|
73 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/association/cleanup/cron_event.php
ADDED
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* A WP-Cron event definition.
|
5 |
+
*
|
6 |
+
* The event hook is added in Toolset_Relationship_Controller.
|
7 |
+
*
|
8 |
+
* This event should be scheduled when there are dangling intermediary posts that need to be removed.
|
9 |
+
*
|
10 |
+
* @since 2.5.10
|
11 |
+
*/
|
12 |
+
class Toolset_Association_Cleanup_Cron_Event extends Toolset_Cron_Event {
|
13 |
+
|
14 |
+
|
15 |
+
/**
|
16 |
+
* @inheritdoc
|
17 |
+
*
|
18 |
+
* @return string
|
19 |
+
*/
|
20 |
+
public function get_unique_slug() {
|
21 |
+
return 'cleanup_dangling_intermediary_posts';
|
22 |
+
}
|
23 |
+
|
24 |
+
|
25 |
+
/**
|
26 |
+
* @inheritdoc
|
27 |
+
*
|
28 |
+
* @return string
|
29 |
+
*/
|
30 |
+
public function get_parent_plugin() {
|
31 |
+
return 'types';
|
32 |
+
}
|
33 |
+
|
34 |
+
|
35 |
+
/**
|
36 |
+
* @inheritdoc
|
37 |
+
*
|
38 |
+
* @return string
|
39 |
+
*/
|
40 |
+
public function get_interval() {
|
41 |
+
return Toolset_Cron_Event::INTERVAL_HOURLY;
|
42 |
+
}
|
43 |
+
|
44 |
+
|
45 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/association/cleanup/cron_handler.php
ADDED
@@ -0,0 +1,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Handle the Toolset_Association_Cleanup_Cron_Event event.
|
5 |
+
*
|
6 |
+
* Perform the cleanup action and unschedule the event in case there are no dangling
|
7 |
+
* intermediary posts left.
|
8 |
+
*
|
9 |
+
* @since 2.5.10
|
10 |
+
*/
|
11 |
+
class Toolset_Association_Cleanup_Cron_Handler {
|
12 |
+
|
13 |
+
|
14 |
+
/** @var Toolset_Association_Cleanup_Factory */
|
15 |
+
private $cleanup_factory;
|
16 |
+
|
17 |
+
|
18 |
+
/** @var Toolset_Cron */
|
19 |
+
private $cron;
|
20 |
+
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Toolset_Association_Cleanup_Cron_Handler constructor.
|
24 |
+
*
|
25 |
+
* @param Toolset_Association_Cleanup_Factory $cleanup_factory
|
26 |
+
* @param Toolset_Cron|null $cron_di
|
27 |
+
*/
|
28 |
+
public function __construct(
|
29 |
+
Toolset_Association_Cleanup_Factory $cleanup_factory,
|
30 |
+
Toolset_Cron $cron_di = null
|
31 |
+
) {
|
32 |
+
$this->cleanup_factory = $cleanup_factory;
|
33 |
+
$this->cron = $cron_di ?: Toolset_Cron::get_instance();
|
34 |
+
}
|
35 |
+
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Handle the WP-Cron event.
|
39 |
+
*/
|
40 |
+
public function handle_event() {
|
41 |
+
$cleanup = $this->cleanup_factory->dangling_intermediary_posts();
|
42 |
+
$cleanup->do_batch();
|
43 |
+
|
44 |
+
if( ! $cleanup->has_remaining_posts() ) {
|
45 |
+
$this->unschedule_event();
|
46 |
+
}
|
47 |
+
}
|
48 |
+
|
49 |
+
|
50 |
+
private function unschedule_event() {
|
51 |
+
$event = $this->cleanup_factory->cron_event();
|
52 |
+
$this->cron->unschedule_event( $event );
|
53 |
+
}
|
54 |
+
|
55 |
+
|
56 |
+
|
57 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/association/cleanup/dangling_intermediary_posts.php
ADDED
@@ -0,0 +1,189 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Delete a batch of dangling intermediary posts (DIP).
|
5 |
+
*
|
6 |
+
* A DIP is a post belonging to an intermediary post type that is not involved in an association
|
7 |
+
* and is not a translation of any such post. DIPs should not exist and this class queries
|
8 |
+
* and permanently deletes them.
|
9 |
+
*
|
10 |
+
* Only a single batch is deleted on each pass because this might be an expensive operation
|
11 |
+
* which can be called from various contexts like WP-Cron or an user-triggered batch process.
|
12 |
+
*
|
13 |
+
* @since 2.5.10
|
14 |
+
*/
|
15 |
+
class Toolset_Association_Cleanup_Dangling_Intermediary_Posts extends Toolset_Wpdb_User {
|
16 |
+
|
17 |
+
|
18 |
+
/** @var Toolset_Relationship_Query_Factory */
|
19 |
+
private $query_factory;
|
20 |
+
|
21 |
+
|
22 |
+
/** @var bool After a batch is performed, this will be set to false if there are no more DIPs. */
|
23 |
+
private $has_remaining_posts = true;
|
24 |
+
|
25 |
+
|
26 |
+
/** @var Toolset_Relationship_Table_Name */
|
27 |
+
private $table_name;
|
28 |
+
|
29 |
+
|
30 |
+
/** @var Toolset_WPML_Compatibility */
|
31 |
+
private $wpml_service;
|
32 |
+
|
33 |
+
|
34 |
+
/** @var Toolset_Post_Type_Query_Factory */
|
35 |
+
private $post_type_query_factory;
|
36 |
+
|
37 |
+
|
38 |
+
private $deleted_posts = 0;
|
39 |
+
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Toolset_Association_Cleanup_Dangling_Intermediary_Posts constructor.
|
43 |
+
*
|
44 |
+
* @param Toolset_Relationship_Query_Factory|null $query_factory_di
|
45 |
+
* @param wpdb|null $wpdb_di
|
46 |
+
* @param Toolset_Relationship_Table_Name|null $table_name_di
|
47 |
+
* @param Toolset_WPML_Compatibility|null $wpml_service_di
|
48 |
+
* @param Toolset_Post_Type_Query_Factory|null $post_type_query_factory_di
|
49 |
+
*/
|
50 |
+
public function __construct(
|
51 |
+
Toolset_Relationship_Query_Factory $query_factory_di = null,
|
52 |
+
wpdb $wpdb_di = null,
|
53 |
+
Toolset_Relationship_Table_Name $table_name_di = null,
|
54 |
+
Toolset_WPML_Compatibility $wpml_service_di = null,
|
55 |
+
Toolset_Post_Type_Query_Factory $post_type_query_factory_di = null
|
56 |
+
) {
|
57 |
+
parent::__construct( $wpdb_di );
|
58 |
+
$this->query_factory = $query_factory_di ?: new Toolset_Relationship_Query_Factory();
|
59 |
+
$this->table_name = $table_name_di ?: new Toolset_Relationship_Table_Name( $wpdb_di );
|
60 |
+
$this->wpml_service = $wpml_service_di ?: Toolset_WPML_Compatibility::get_instance();
|
61 |
+
$this->post_type_query_factory = $post_type_query_factory_di ?: new Toolset_Post_Type_Query_Factory();
|
62 |
+
}
|
63 |
+
|
64 |
+
|
65 |
+
/**
|
66 |
+
* Perform one batch of DIP deletions.
|
67 |
+
*
|
68 |
+
* @since 2.5.10
|
69 |
+
*/
|
70 |
+
public function do_batch() {
|
71 |
+
$post_ids = array_map( 'intval', $this->get_post_ids() );
|
72 |
+
foreach( $post_ids as $post_to_delete ) {
|
73 |
+
add_filter( Toolset_Association_Cleanup_Post::IS_DELETING_FILTER, '__return_true' );
|
74 |
+
wp_delete_post( $post_to_delete, true );
|
75 |
+
remove_filter( Toolset_Association_Cleanup_Post::IS_DELETING_FILTER, '__return_true' );
|
76 |
+
}
|
77 |
+
|
78 |
+
$this->deleted_posts = count( $post_ids );
|
79 |
+
}
|
80 |
+
|
81 |
+
|
82 |
+
private function get_post_ids() {
|
83 |
+
$post_ids = $this->wpdb->get_col( $this->build_query() );
|
84 |
+
|
85 |
+
$found_rows = (int) $this->wpdb->get_var( 'SELECT FOUND_ROWS()' );
|
86 |
+
$this->has_remaining_posts = ( $found_rows > Toolset_Association_Cleanup_Post::DELETE_POSTS_PER_BATCH );
|
87 |
+
|
88 |
+
return $post_ids;
|
89 |
+
}
|
90 |
+
|
91 |
+
|
92 |
+
/**
|
93 |
+
* After a batch operation was performed, this will return false if there are no
|
94 |
+
* remaining DIPs to be deleted. Otherwise returns true.
|
95 |
+
*
|
96 |
+
* @return bool
|
97 |
+
*/
|
98 |
+
public function has_remaining_posts() {
|
99 |
+
return $this->has_remaining_posts;
|
100 |
+
}
|
101 |
+
|
102 |
+
|
103 |
+
/**
|
104 |
+
* After a batch operation was performed, this will return the number of posts
|
105 |
+
* that have actually been deleted.
|
106 |
+
*
|
107 |
+
* @return int
|
108 |
+
*/
|
109 |
+
public function get_deleted_posts() {
|
110 |
+
return $this->deleted_posts;
|
111 |
+
}
|
112 |
+
|
113 |
+
|
114 |
+
/**
|
115 |
+
* Build a query for DIPs depending on WPML status.
|
116 |
+
*
|
117 |
+
* @return string Valid and safe MySQL query string.
|
118 |
+
*/
|
119 |
+
private function build_query() {
|
120 |
+
$ipts = '\'' . implode( '\', \'', esc_sql( $this->get_intermediary_post_types() ) ) . '\'';
|
121 |
+
$limit = (int) Toolset_Association_Cleanup_Post::DELETE_POSTS_PER_BATCH;
|
122 |
+
|
123 |
+
if( $this->wpml_service->is_wpml_active_and_configured() ) {
|
124 |
+
$icl_translations = $this->wpdb->prefix . 'icl_translations';
|
125 |
+
$default_language = esc_sql( $this->wpml_service->get_default_language() );
|
126 |
+
|
127 |
+
// Main goal: Query posts of given types that are neither used as intermediary posts directly
|
128 |
+
// nor as translations of intermediary posts.
|
129 |
+
// We achieve that by doing a LEFT JOINs and then checking if the columns in
|
130 |
+
// joined tables are NULL (no match).
|
131 |
+
$query = "
|
132 |
+
SELECT SQL_CALC_FOUND_ROWS post.ID
|
133 |
+
FROM {$this->wpdb->posts} AS post
|
134 |
+
LEFT JOIN {$this->table_name->association_table()} AS association
|
135 |
+
ON (post.ID = association.intermediary_id)
|
136 |
+
LEFT JOIN {$icl_translations} AS translation
|
137 |
+
ON (
|
138 |
+
post.ID = translation.element_id
|
139 |
+
AND translation.element_type LIKE 'post_%'
|
140 |
+
AND translation.language_code != '{$default_language}'
|
141 |
+
)
|
142 |
+
LEFT JOIN {$icl_translations} AS default_language_translation
|
143 |
+
ON (
|
144 |
+
translation.trid = default_language_translation.trid
|
145 |
+
AND default_language_translation.language_code = '{$default_language}'
|
146 |
+
)
|
147 |
+
LEFT JOIN {$this->table_name->association_table()} AS default_language_association
|
148 |
+
ON(
|
149 |
+
default_language_association.intermediary_id = default_language_translation.element_id
|
150 |
+
)
|
151 |
+
WHERE
|
152 |
+
association.intermediary_id IS NULL
|
153 |
+
AND default_language_association.intermediary_id IS NULL
|
154 |
+
AND post.post_type IN ({$ipts})
|
155 |
+
LIMIT {$limit}";
|
156 |
+
|
157 |
+
} else {
|
158 |
+
// Ditto but without the WPML part, as the icl_translations table probably doesn't
|
159 |
+
// even exist.
|
160 |
+
$query = "
|
161 |
+
SELECT SQL_CALC_FOUND_ROWS post.ID
|
162 |
+
FROM {$this->wpdb->posts} AS post
|
163 |
+
LEFT JOIN {$this->table_name->association_table()} AS association
|
164 |
+
ON (post.ID = association.intermediary_id)
|
165 |
+
WHERE
|
166 |
+
association.intermediary_id IS NULL
|
167 |
+
AND post.post_type IN ({$ipts})
|
168 |
+
LIMIT {$limit}";
|
169 |
+
}
|
170 |
+
|
171 |
+
return $query;
|
172 |
+
}
|
173 |
+
|
174 |
+
|
175 |
+
/**
|
176 |
+
* @return string[] IPT slugs.
|
177 |
+
*/
|
178 |
+
private function get_intermediary_post_types() {
|
179 |
+
$query = $this->post_type_query_factory->create(
|
180 |
+
array(
|
181 |
+
'is_intermediary' => true,
|
182 |
+
'return' => 'slug'
|
183 |
+
)
|
184 |
+
);
|
185 |
+
|
186 |
+
return $query->get_results();
|
187 |
+
}
|
188 |
+
|
189 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/association/cleanup/factory.php
ADDED
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Factory for objects handling cleaning up and removing m2m-related data.
|
5 |
+
*
|
6 |
+
* @since 2.5.10
|
7 |
+
*/
|
8 |
+
class Toolset_Association_Cleanup_Factory {
|
9 |
+
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @return Toolset_Association_Cleanup_Post
|
13 |
+
*/
|
14 |
+
public function post() {
|
15 |
+
return new Toolset_Association_Cleanup_Post(
|
16 |
+
null, null, null, null, null, $this
|
17 |
+
);
|
18 |
+
}
|
19 |
+
|
20 |
+
|
21 |
+
/**
|
22 |
+
* @return Toolset_Association_Cleanup_Association
|
23 |
+
*/
|
24 |
+
public function association() {
|
25 |
+
return new Toolset_Association_Cleanup_Association();
|
26 |
+
}
|
27 |
+
|
28 |
+
|
29 |
+
/**
|
30 |
+
* @return Toolset_Association_Cleanup_Cron_Handler
|
31 |
+
*/
|
32 |
+
public function cron_handler() {
|
33 |
+
return new Toolset_Association_Cleanup_Cron_Handler( $this );
|
34 |
+
}
|
35 |
+
|
36 |
+
|
37 |
+
/**
|
38 |
+
* @return Toolset_Association_Cleanup_Dangling_Intermediary_Posts
|
39 |
+
*/
|
40 |
+
public function dangling_intermediary_posts() {
|
41 |
+
return new Toolset_Association_Cleanup_Dangling_Intermediary_Posts();
|
42 |
+
}
|
43 |
+
|
44 |
+
|
45 |
+
/**
|
46 |
+
* @return Toolset_Association_Cleanup_Cron_Event
|
47 |
+
*/
|
48 |
+
public function cron_event() {
|
49 |
+
return new Toolset_Association_Cleanup_Cron_Event();
|
50 |
+
}
|
51 |
+
|
52 |
+
|
53 |
+
/**
|
54 |
+
* @return Toolset_Association_Cleanup_Troubleshooting_Section
|
55 |
+
*/
|
56 |
+
public function troubeshooting_section() {
|
57 |
+
return new Toolset_Association_Cleanup_Troubleshooting_Section( $this );
|
58 |
+
}
|
59 |
+
|
60 |
+
|
61 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/association/cleanup/post.php
ADDED
@@ -0,0 +1,295 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Perform a cleanup after a single post has been deleted.
|
5 |
+
*
|
6 |
+
* Needs to be hooked to the before_delete_post action.
|
7 |
+
*
|
8 |
+
* Short version:
|
9 |
+
*
|
10 |
+
* This situation is much more tricky than when just deleting a single association. One post
|
11 |
+
* can be involved in many associations and deleting those might trigger also deleting of
|
12 |
+
* intermediary posts and their translations.
|
13 |
+
*
|
14 |
+
* Long version:
|
15 |
+
*
|
16 |
+
* Associations themselves can be handled with a single MySQL query,
|
17 |
+
* but for deleting intermediary posts, we have to perform consecutive wp_delete_post() calls,
|
18 |
+
* which in turn may trigger further deletions if those intermediary posts are translated
|
19 |
+
* to more languages.
|
20 |
+
*
|
21 |
+
* We simply cannot afford to delete all intermediary posts at once, because that might be
|
22 |
+
* easily much more than the server can handle, and we can't immediately show a
|
23 |
+
* batch deletion dialog because we don't know in which context the initial post is deleted.
|
24 |
+
* It may be even during an AJAX call or whatnot.
|
25 |
+
*
|
26 |
+
* The problem is that we don't want to have lingering intermediary posts because the user
|
27 |
+
* might use them in a View, for example, and assume that an intermediary post == an association.
|
28 |
+
*
|
29 |
+
* Here, a compromise solution is implemented: We immediately delete a certain number of
|
30 |
+
* intermediary posts, which will cover 99% of these cases, and for the remaining 1%
|
31 |
+
* of big deletions, offer a clean-up routine on the Toolset Troubleshooting page.
|
32 |
+
*
|
33 |
+
* If we detect that such a cleanup is needed, we'll display a notice until the user goes
|
34 |
+
* to the troubleshooting page and clicks the button.
|
35 |
+
*
|
36 |
+
* On top of that, a CRON job will be created to complete the cleanup if the user doesn't
|
37 |
+
* take action soon enough.
|
38 |
+
*
|
39 |
+
* @since 2.5.10
|
40 |
+
*/
|
41 |
+
class Toolset_Association_Cleanup_Post extends Toolset_Wpdb_User {
|
42 |
+
|
43 |
+
|
44 |
+
const DELETE_POSTS_PER_BATCH = 25;
|
45 |
+
|
46 |
+
|
47 |
+
const IS_DELETING_FILTER = 'toolset_is_deleting_intermediary_post';
|
48 |
+
|
49 |
+
|
50 |
+
/** @var Toolset_Element_Factory */
|
51 |
+
private $element_factory;
|
52 |
+
|
53 |
+
|
54 |
+
/** @var Toolset_Relationship_Query_Factory */
|
55 |
+
private $query_factory;
|
56 |
+
|
57 |
+
|
58 |
+
/** @var Toolset_Relationship_Table_Name */
|
59 |
+
private $table_name;
|
60 |
+
|
61 |
+
|
62 |
+
/** @var null|Toolset_Cron */
|
63 |
+
private $_cron;
|
64 |
+
|
65 |
+
|
66 |
+
/** @var null|Toolset_Association_Cleanup_Factory */
|
67 |
+
private $_cleanup_factory;
|
68 |
+
|
69 |
+
|
70 |
+
/** @var Toolset_WPML_Compatibility */
|
71 |
+
private $wpml_service;
|
72 |
+
|
73 |
+
|
74 |
+
/** @var null|Toolset_Association_Intermediary_Post_Persistence */
|
75 |
+
private $_ip_persistence;
|
76 |
+
|
77 |
+
|
78 |
+
/**
|
79 |
+
* Toolset_Association_Cleanup_Post constructor.
|
80 |
+
*
|
81 |
+
* @param Toolset_Element_Factory|null $element_factory_di
|
82 |
+
* @param Toolset_Relationship_Query_Factory|null $query_factory_di
|
83 |
+
* @param Toolset_Relationship_Table_Name|null $table_name_di
|
84 |
+
* @param wpdb|null $wpdb_di
|
85 |
+
* @param Toolset_Cron|null $cron_di
|
86 |
+
* @param Toolset_Association_Cleanup_Factory|null $cleanup_factory_di
|
87 |
+
* @param Toolset_WPML_Compatibility|null $wpml_service_di
|
88 |
+
* @param Toolset_Association_Intermediary_Post_Persistence|null $intermediary_post_persistence_di
|
89 |
+
*/
|
90 |
+
public function __construct(
|
91 |
+
Toolset_Element_Factory $element_factory_di = null,
|
92 |
+
Toolset_Relationship_Query_Factory $query_factory_di = null,
|
93 |
+
Toolset_Relationship_Table_Name $table_name_di = null,
|
94 |
+
wpdb $wpdb_di = null,
|
95 |
+
Toolset_Cron $cron_di = null,
|
96 |
+
Toolset_Association_Cleanup_Factory $cleanup_factory_di = null,
|
97 |
+
Toolset_WPML_Compatibility $wpml_service_di = null,
|
98 |
+
Toolset_Association_Intermediary_Post_Persistence $intermediary_post_persistence_di = null
|
99 |
+
) {
|
100 |
+
parent::__construct( null );
|
101 |
+
$this->element_factory = $element_factory_di ?: new Toolset_Element_Factory();
|
102 |
+
$this->query_factory = $query_factory_di ?: new Toolset_Relationship_Query_Factory();
|
103 |
+
$this->table_name = $table_name_di ?: new Toolset_Relationship_Table_Name();
|
104 |
+
$this->_cron = $cron_di;
|
105 |
+
$this->_cleanup_factory = $cleanup_factory_di;
|
106 |
+
$this->wpml_service = $wpml_service_di ?: Toolset_WPML_Compatibility::get_instance();
|
107 |
+
$this->_ip_persistence = $intermediary_post_persistence_di;
|
108 |
+
}
|
109 |
+
|
110 |
+
|
111 |
+
/**
|
112 |
+
* Clean up affected associations before a post is permanently deleted.
|
113 |
+
*
|
114 |
+
* @param int $post_id
|
115 |
+
*/
|
116 |
+
public function cleanup( $post_id ) {
|
117 |
+
$is_deleting_association = apply_filters( self::IS_DELETING_FILTER, false );
|
118 |
+
|
119 |
+
if( $is_deleting_association ) {
|
120 |
+
// Prevent an infinite recursion if a single association is being deleted.
|
121 |
+
// If we got here, it means that the association's intermediary post is about to
|
122 |
+
// be deleted and everything else is already handled either
|
123 |
+
// in Toolset_Association_Cleanup_Association, or within this class.
|
124 |
+
return;
|
125 |
+
}
|
126 |
+
|
127 |
+
try {
|
128 |
+
$post = $this->element_factory->get_post_untranslated( $post_id );
|
129 |
+
|
130 |
+
} /** @noinspection PhpRedundantCatchClauseInspection */
|
131 |
+
catch( Toolset_Element_Exception_Element_Doesnt_Exist $e ) {
|
132 |
+
// The post is already gone, do nothing.
|
133 |
+
return;
|
134 |
+
}
|
135 |
+
|
136 |
+
if( $post->is_revision() ) {
|
137 |
+
// No need to handle revisions. They're not supposed to have any
|
138 |
+
// associations at all. Just let WordPress proceed with the deletion.
|
139 |
+
return;
|
140 |
+
}
|
141 |
+
|
142 |
+
if( ! $this->is_involved_in_association_directly( $post ) ) {
|
143 |
+
// A post may be a translation of another post that is involved in an association
|
144 |
+
// as a parent, a child or an intermediary post. But in any of these cases, we don't
|
145 |
+
// have to delete anything. Not even the intermediary post translation. We allow even such
|
146 |
+
// scenarios as having a translatable intermediary post type but non-translatable
|
147 |
+
// parent and child.
|
148 |
+
//
|
149 |
+
// Intermediary post translations will be deleted only when the whole association is deleted
|
150 |
+
// or they can be deleted manually, if the user cares about it.
|
151 |
+
return;
|
152 |
+
}
|
153 |
+
|
154 |
+
// The post was directly involved in an association - either it's non-translatable
|
155 |
+
// or in the default language. We delete the associations and we're done.
|
156 |
+
$this->delete_associations_involving_post( $post );
|
157 |
+
}
|
158 |
+
|
159 |
+
|
160 |
+
/**
|
161 |
+
* @param IToolset_Post $post
|
162 |
+
*
|
163 |
+
* @return bool
|
164 |
+
*/
|
165 |
+
private function is_involved_in_association_directly( IToolset_Post $post ) {
|
166 |
+
$query = $this->query_factory->associations_v2();
|
167 |
+
|
168 |
+
$found_rows = $query
|
169 |
+
->add( $query->element(
|
170 |
+
$post, null, true, false
|
171 |
+
) )
|
172 |
+
->do_not_add_default_conditions()
|
173 |
+
->get_found_rows_directly();
|
174 |
+
|
175 |
+
return ( $found_rows > 0 );
|
176 |
+
}
|
177 |
+
|
178 |
+
|
179 |
+
/**
|
180 |
+
* @param IToolset_Post $post
|
181 |
+
*/
|
182 |
+
private function delete_associations_involving_post( IToolset_Post $post ) {
|
183 |
+
$this->delete_involved_intermediary_posts( $post );
|
184 |
+
$this->delete_association_rows( $post );
|
185 |
+
}
|
186 |
+
|
187 |
+
|
188 |
+
/**
|
189 |
+
* Delete all the affected association rows from the database.
|
190 |
+
*
|
191 |
+
* @param IToolset_Post $post
|
192 |
+
*
|
193 |
+
* @return Toolset_Result
|
194 |
+
*/
|
195 |
+
private function delete_association_rows( IToolset_Post $post ) {
|
196 |
+
$associations = $this->table_name->association_table();
|
197 |
+
$relationships = $this->table_name->relationship_table();
|
198 |
+
|
199 |
+
$query = $this->wpdb->prepare(
|
200 |
+
"DELETE association
|
201 |
+
FROM {$associations} AS association
|
202 |
+
JOIN {$relationships} AS relationship
|
203 |
+
ON ( association.relationship_id = relationship.id )
|
204 |
+
WHERE
|
205 |
+
( relationship.parent_domain = 'posts' AND parent_id = %d )
|
206 |
+
OR ( relationship.child_domain = 'posts' AND child_id = %d )
|
207 |
+
OR ( intermediary_id = %d )",
|
208 |
+
$post->get_id(),
|
209 |
+
$post->get_id(),
|
210 |
+
$post->get_id()
|
211 |
+
);
|
212 |
+
|
213 |
+
$deleted_rows = $this->wpdb->query( $query );
|
214 |
+
|
215 |
+
return new Toolset_Result( $deleted_rows > 0 );
|
216 |
+
}
|
217 |
+
|
218 |
+
|
219 |
+
/**
|
220 |
+
* Delete a first batch of intermediary posts that should be removed together
|
221 |
+
* with the association. If some intermediary posts remain, set up a CRON job and an admin notice
|
222 |
+
* for the user.
|
223 |
+
*
|
224 |
+
* @param IToolset_Post $post
|
225 |
+
*/
|
226 |
+
private function delete_involved_intermediary_posts( IToolset_Post $post ) {
|
227 |
+
$query = $this->query_factory->associations_v2();
|
228 |
+
|
229 |
+
$intermediary_post_ids = $query
|
230 |
+
->add( $query->do_or(
|
231 |
+
// Not intermediary posts. If the element is an intermediary post,
|
232 |
+
// we need to exclude it (it's already being deleted) and we wouldn't get any other
|
233 |
+
// associations where it's involved.
|
234 |
+
$query->element( $post, new Toolset_Relationship_Role_Parent(), true, false ),
|
235 |
+
$query->element( $post, new Toolset_Relationship_Role_Child(), true, false )
|
236 |
+
) )
|
237 |
+
->do_not_add_default_conditions()
|
238 |
+
->limit( self::DELETE_POSTS_PER_BATCH )
|
239 |
+
->return_element_ids( new Toolset_Relationship_Role_Intermediary() )
|
240 |
+
->need_found_rows()
|
241 |
+
->get_results();
|
242 |
+
|
243 |
+
foreach( $intermediary_post_ids as $intermediary_post_id ) {
|
244 |
+
// This will also delete post translations.
|
245 |
+
$this->get_intermediary_post_persistence()->delete_intermediary_post( $intermediary_post_id );
|
246 |
+
}
|
247 |
+
|
248 |
+
if( $query->get_found_rows() > self::DELETE_POSTS_PER_BATCH ) {
|
249 |
+
// Some dangling posts are left, there's too much of them to be deleted at once.
|
250 |
+
// Schedule a WP-Cron event to delete them by batches until there are none left.
|
251 |
+
$this->schedule_dangling_post_removal();
|
252 |
+
}
|
253 |
+
}
|
254 |
+
|
255 |
+
|
256 |
+
/**
|
257 |
+
* @return Toolset_Association_Cleanup_Factory
|
258 |
+
*/
|
259 |
+
private function get_cleanup_factory() {
|
260 |
+
if( null === $this->_cleanup_factory ) {
|
261 |
+
$this->_cleanup_factory = new Toolset_Association_Cleanup_Factory();
|
262 |
+
}
|
263 |
+
return $this->_cleanup_factory;
|
264 |
+
}
|
265 |
+
|
266 |
+
|
267 |
+
/**
|
268 |
+
* @return Toolset_Cron
|
269 |
+
*/
|
270 |
+
private function get_cron() {
|
271 |
+
if( null === $this->_cron ) {
|
272 |
+
$this->_cron = Toolset_Cron::get_instance();
|
273 |
+
}
|
274 |
+
return $this->_cron;
|
275 |
+
}
|
276 |
+
|
277 |
+
|
278 |
+
private function schedule_dangling_post_removal() {
|
279 |
+
$cron_event = $this->get_cleanup_factory()->cron_event();
|
280 |
+
$this->get_cron()->schedule_event( $cron_event );
|
281 |
+
}
|
282 |
+
|
283 |
+
|
284 |
+
/**
|
285 |
+
* @return Toolset_Association_Intermediary_Post_Persistence
|
286 |
+
*/
|
287 |
+
private function get_intermediary_post_persistence() {
|
288 |
+
if( null === $this->_ip_persistence ) {
|
289 |
+
$this->_ip_persistence = new Toolset_Association_Intermediary_Post_Persistence();
|
290 |
+
}
|
291 |
+
return $this->_ip_persistence;
|
292 |
+
}
|
293 |
+
|
294 |
+
|
295 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/association/cleanup/troubleshooting_section.php
ADDED
@@ -0,0 +1,115 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Manage the troubleshooting section for manually deleting dangling intermediary posts.
|
5 |
+
*
|
6 |
+
* @since 2.5.10
|
7 |
+
*/
|
8 |
+
class Toolset_Association_Cleanup_Troubleshooting_Section {
|
9 |
+
|
10 |
+
|
11 |
+
const TROUBLESHOOTING_SECTION_SLUG = 'cleanup_intermediary_posts';
|
12 |
+
|
13 |
+
|
14 |
+
/**
|
15 |
+
* @var Toolset_Association_Cleanup_Factory
|
16 |
+
*/
|
17 |
+
private $cleanup_factory;
|
18 |
+
|
19 |
+
|
20 |
+
/**
|
21 |
+
* @var Toolset_Cron
|
22 |
+
*/
|
23 |
+
private $cron;
|
24 |
+
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Toolset_Association_Cleanup_Troubleshooting_Section constructor.
|
28 |
+
*
|
29 |
+
* @param Toolset_Association_Cleanup_Factory $cleanup_factory
|
30 |
+
* @param Toolset_Cron|null $cron_di
|
31 |
+
*/
|
32 |
+
public function __construct(
|
33 |
+
Toolset_Association_Cleanup_Factory $cleanup_factory,
|
34 |
+
Toolset_Cron $cron_di = null
|
35 |
+
) {
|
36 |
+
$this->cleanup_factory = $cleanup_factory;
|
37 |
+
$this->cron = $cron_di ?: Toolset_Cron::get_instance();
|
38 |
+
}
|
39 |
+
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Find out whether there are posts to clean up.
|
43 |
+
*
|
44 |
+
* Instead of running the query, we just check whether the cleanup WP-Cron job is already scheduled.
|
45 |
+
*
|
46 |
+
* @return bool
|
47 |
+
*/
|
48 |
+
public function is_cleanup_needed() {
|
49 |
+
$cron_event = $this->cleanup_factory->cron_event();
|
50 |
+
|
51 |
+
// Note: This may give us false positives: There may be a WP-Cron event executed later during this request,
|
52 |
+
// which will delete all remaining DIPs. Unfortunately, we have no way of predicting that reliably.
|
53 |
+
//
|
54 |
+
// This will be happening if there are exactly between ($x+1) and ($x*2) DIPs,
|
55 |
+
// where $x = Toolset_Association_Cleanup_Post::DELETE_POSTS_PER_BATCH.
|
56 |
+
return $this->cron->is_scheduled( $cron_event );
|
57 |
+
}
|
58 |
+
|
59 |
+
|
60 |
+
/**
|
61 |
+
* Register the troubleshooting section and a dismissable admin notice that will point towards it.
|
62 |
+
*/
|
63 |
+
public function register() {
|
64 |
+
add_filter( 'toolset_get_troubleshooting_sections', array( $this, 'add_troubleshooting_section' ) );
|
65 |
+
add_action( 'toolset_admin_notices_manager_show_notices', array( $this, 'add_notice' ) );
|
66 |
+
}
|
67 |
+
|
68 |
+
|
69 |
+
/**
|
70 |
+
* Add new troubleshooting section definition.
|
71 |
+
*
|
72 |
+
* @param array $sections
|
73 |
+
*
|
74 |
+
* @return array
|
75 |
+
*/
|
76 |
+
public function add_troubleshooting_section( $sections ) {
|
77 |
+
$sections[ self::TROUBLESHOOTING_SECTION_SLUG ] = array(
|
78 |
+
'title' => __( 'Delete leftover intermediary posts', 'wpcf' ),
|
79 |
+
'description' => __( 'After deleting a large number of associations, there are some intermediary posts left. It was not possible to delete them at once. You can either delete them manually or ignore the issue, and they will be gradually removed automatically. This is only important if you use intermediary posts on the front-end directly, for example in a View.', 'wpcf'),
|
80 |
+
'button_label' => __( 'Delete leftover posts', 'wpcf' ),
|
81 |
+
'is_dangerous' => false,
|
82 |
+
'action_name' => Toolset_Ajax::get_instance()->get_action_js_name( Toolset_Ajax::CALLBACK_INTERMEDIARY_POST_CLEANUP ),
|
83 |
+
'nonce' => wp_create_nonce( Toolset_Ajax::CALLBACK_INTERMEDIARY_POST_CLEANUP ),
|
84 |
+
'ajax_arguments' => array( 'current_step' => 1 )
|
85 |
+
);
|
86 |
+
return $sections;
|
87 |
+
}
|
88 |
+
|
89 |
+
|
90 |
+
/**
|
91 |
+
* Show an admin notice if there are dangling intermediary posts.
|
92 |
+
*
|
93 |
+
* @param array $notices
|
94 |
+
*
|
95 |
+
* @return array
|
96 |
+
* @throws Exception
|
97 |
+
*/
|
98 |
+
public function add_notice( $notices ) {
|
99 |
+
if( $this->is_cleanup_needed() ) {
|
100 |
+
$notices[] = new Toolset_Admin_Notice_Dismissible(
|
101 |
+
self::TROUBLESHOOTING_SECTION_SLUG,
|
102 |
+
sprintf(
|
103 |
+
__( 'There may be some leftover intermediary posts that need to be deleted. You can do it manually on the %s or ignore this message and wait until they\'re deleted automatically.', 'wpcf' ),
|
104 |
+
sprintf(
|
105 |
+
'<a href="%s">%s</a>',
|
106 |
+
esc_attr( add_query_arg( array( 'page' => Toolset_Menu::TROUBLESHOOTING_PAGE_SLUG ), admin_url( 'admin.php' ) ) ),
|
107 |
+
__( 'Troubleshooting Page', 'wpcf' )
|
108 |
+
)
|
109 |
+
)
|
110 |
+
);
|
111 |
+
}
|
112 |
+
return $notices;
|
113 |
+
}
|
114 |
+
|
115 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/association/factory.php
ADDED
@@ -0,0 +1,96 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Factory for instantiating IToolset_Association objects.
|
5 |
+
*
|
6 |
+
* This should not be used from outside
|
7 |
+
* of the m2m API. Everything required for working with associations should be
|
8 |
+
* implemented on IToolset_Relationship_Definition.
|
9 |
+
*
|
10 |
+
* @since 2.5.8
|
11 |
+
*/
|
12 |
+
class Toolset_Association_Factory {
|
13 |
+
|
14 |
+
|
15 |
+
/** @var Toolset_Relationship_Definition_Repository */
|
16 |
+
private $definition_repository;
|
17 |
+
|
18 |
+
|
19 |
+
/** @var Toolset_Element_Factory|null */
|
20 |
+
private $_element_factory;
|
21 |
+
|
22 |
+
|
23 |
+
/** @var null|Toolset_WPML_Compatibility */
|
24 |
+
private $_wpml_service;
|
25 |
+
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Toolset_Association_Factory constructor.
|
29 |
+
*
|
30 |
+
* @param Toolset_Relationship_Definition_Repository|null $definition_repository_di
|
31 |
+
* @param Toolset_Element_Factory|null $element_factory_di
|
32 |
+
* @param Toolset_WPML_Compatibility|null $wpml_service_di
|
33 |
+
*/
|
34 |
+
public function __construct(
|
35 |
+
Toolset_Relationship_Definition_Repository $definition_repository_di = null,
|
36 |
+
Toolset_Element_Factory $element_factory_di = null,
|
37 |
+
Toolset_WPML_Compatibility $wpml_service_di = null
|
38 |
+
) {
|
39 |
+
$this->definition_repository = ( null === $definition_repository_di ? Toolset_Relationship_Definition_Repository::get_instance() : $definition_repository_di );
|
40 |
+
$this->_element_factory = $element_factory_di;
|
41 |
+
$this->_wpml_service = $wpml_service_di;
|
42 |
+
}
|
43 |
+
|
44 |
+
|
45 |
+
/**
|
46 |
+
* @param Toolset_Relationship_Definition $relationship
|
47 |
+
* @param int|IToolset_Element $parent_id
|
48 |
+
* @param int|IToolset_Element $child_id
|
49 |
+
* @param int|IToolset_Post $intermediary_id
|
50 |
+
* @param int $association_uid Can be zero for associations that are not stored in the database yet.
|
51 |
+
*
|
52 |
+
* @return IToolset_Association
|
53 |
+
* @throws Toolset_Element_Exception_Element_Doesnt_Exist
|
54 |
+
*/
|
55 |
+
public function create(
|
56 |
+
Toolset_Relationship_Definition $relationship,
|
57 |
+
$parent_id, $child_id, $intermediary_id, $association_uid = 0
|
58 |
+
) {
|
59 |
+
return new Toolset_Association(
|
60 |
+
$association_uid,
|
61 |
+
$relationship,
|
62 |
+
array(
|
63 |
+
Toolset_Relationship_Role::PARENT => $parent_id,
|
64 |
+
Toolset_Relationship_Role::CHILD => $child_id
|
65 |
+
),
|
66 |
+
$intermediary_id,
|
67 |
+
$this->_wpml_service,
|
68 |
+
$this->_element_factory
|
69 |
+
);
|
70 |
+
}
|
71 |
+
|
72 |
+
|
73 |
+
/**
|
74 |
+
* @param int $relationship_id
|
75 |
+
* @param int $parent_id
|
76 |
+
* @param int $child_id
|
77 |
+
* @param int $intermediary_id
|
78 |
+
* @param int $association_uid Can be zero for associations that are not stored in the database yet.
|
79 |
+
*
|
80 |
+
* @return IToolset_Association
|
81 |
+
* @throws RuntimeException Thrown if an invalid relationship slug is provided.
|
82 |
+
* @throws Toolset_Element_Exception_Element_Doesnt_Exist
|
83 |
+
*/
|
84 |
+
public function create_by_relationship_id(
|
85 |
+
$relationship_id,
|
86 |
+
$parent_id, $child_id, $intermediary_id, $association_uid = 0
|
87 |
+
) {
|
88 |
+
$relationship = $this->definition_repository->get_definition_by_row_id( $relationship_id );
|
89 |
+
if( null === $relationship ) {
|
90 |
+
throw new RuntimeException( 'Relationship doesn\'t exist.' );
|
91 |
+
}
|
92 |
+
|
93 |
+
return $this->create( $relationship, $parent_id, $child_id, $intermediary_id, $association_uid );
|
94 |
+
}
|
95 |
+
|
96 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/{i_association.php → association/interface.php}
RENAMED
@@ -73,15 +73,30 @@ interface IToolset_Association {
|
|
73 |
*
|
74 |
* Instantiates an element from its ID if that hasn't been done yet.
|
75 |
*
|
76 |
-
* @param
|
|
|
|
|
|
|
77 |
*
|
78 |
-
* @return Toolset_Element
|
79 |
* @throws InvalidArgumentException
|
80 |
* @since m2m
|
81 |
*/
|
82 |
public function get_element( $element_role );
|
83 |
|
84 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
85 |
/**
|
86 |
* Check that the element role is valid.
|
87 |
*
|
@@ -100,4 +115,23 @@ interface IToolset_Association {
|
|
100 |
*/
|
101 |
public function get_driver();
|
102 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
103 |
}
|
73 |
*
|
74 |
* Instantiates an element from its ID if that hasn't been done yet.
|
75 |
*
|
76 |
+
* @param IToolset_Relationship_Role $element_role
|
77 |
+
*
|
78 |
+
* @return Toolset_Element|null Null can be returned for the intermediary role, if there is no
|
79 |
+
* intermediary post.
|
80 |
*
|
|
|
81 |
* @throws InvalidArgumentException
|
82 |
* @since m2m
|
83 |
*/
|
84 |
public function get_element( $element_role );
|
85 |
|
86 |
|
87 |
+
/**
|
88 |
+
* Get an ID of the association element.
|
89 |
+
*
|
90 |
+
* Note that if WPML is active and the element is translated, this will return the ID of the
|
91 |
+
* translation.
|
92 |
+
*
|
93 |
+
* @param IToolset_Relationship_Role $element_role
|
94 |
+
*
|
95 |
+
* @return int
|
96 |
+
*/
|
97 |
+
public function get_element_id( $element_role );
|
98 |
+
|
99 |
+
|
100 |
/**
|
101 |
* Check that the element role is valid.
|
102 |
*
|
115 |
*/
|
116 |
public function get_driver();
|
117 |
|
118 |
+
|
119 |
+
/**
|
120 |
+
* Get the ID of the intermediary post with association fields.
|
121 |
+
*
|
122 |
+
* Use with consideration.
|
123 |
+
*
|
124 |
+
* @return int Post ID or zero if no post exists.
|
125 |
+
* @since 2.5.8
|
126 |
+
*/
|
127 |
+
public function get_intermediary_id();
|
128 |
+
|
129 |
+
|
130 |
+
/**
|
131 |
+
* Check whether an intermediary post exists for this association.
|
132 |
+
*
|
133 |
+
* @return bool
|
134 |
+
* @since 2.5.10
|
135 |
+
*/
|
136 |
+
public function has_intermediary_post();
|
137 |
}
|
vendor/toolset/toolset-common/inc/m2m/association/intermediary_post_persistence.php
ADDED
@@ -0,0 +1,273 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Helper class for extra association operations
|
5 |
+
*
|
6 |
+
* @since m2m
|
7 |
+
*/
|
8 |
+
class Toolset_Association_Intermediary_Post_Persistence {
|
9 |
+
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Number of items handled each loop
|
13 |
+
*/
|
14 |
+
const DEFAULT_LIMIT = 50;
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Relationship definition, the associations depend on a relationship, that is why it is neccesary.
|
18 |
+
*
|
19 |
+
* @var IToolset_Relationship_Definition
|
20 |
+
* @since m2m
|
21 |
+
*/
|
22 |
+
private $relationship;
|
23 |
+
|
24 |
+
|
25 |
+
/** @var Toolset_WPML_Compatibility */
|
26 |
+
private $wpml_service;
|
27 |
+
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Class constructor
|
31 |
+
*
|
32 |
+
* @param IToolset_Relationship_Definition $relationship Relationship.
|
33 |
+
* @param Toolset_WPML_Compatibility|null $wpml_service_di
|
34 |
+
*
|
35 |
+
* @since m2m
|
36 |
+
*/
|
37 |
+
public function __construct(
|
38 |
+
IToolset_Relationship_Definition $relationship = null,
|
39 |
+
Toolset_WPML_Compatibility $wpml_service_di = null
|
40 |
+
) {
|
41 |
+
// todo Consider passing this specifically to methods that need it.
|
42 |
+
$this->relationship = $relationship;
|
43 |
+
$this->wpml_service = $wpml_service_di ?: Toolset_WPML_Compatibility::get_instance();
|
44 |
+
}
|
45 |
+
|
46 |
+
|
47 |
+
/**
|
48 |
+
* Create an intermediary post for a new association.
|
49 |
+
*
|
50 |
+
* @param int $parent_id Association parent id.
|
51 |
+
* @param int $child_id Association child id.
|
52 |
+
*
|
53 |
+
* @return int|null ID of the new post or null if the post creation failed.
|
54 |
+
* @since m2m
|
55 |
+
*/
|
56 |
+
public function create_intermediary_post( $parent_id, $child_id ) {
|
57 |
+
$post_type = $this->relationship->get_intermediary_post_type();
|
58 |
+
|
59 |
+
if ( null === $post_type ) {
|
60 |
+
return null;
|
61 |
+
}
|
62 |
+
|
63 |
+
|
64 |
+
/**
|
65 |
+
* toolset_build_intermediary_post_title
|
66 |
+
*
|
67 |
+
* Allow for overriding the post title of an intermediary post.
|
68 |
+
*
|
69 |
+
* @param string $post_title Post title default value.
|
70 |
+
* @param string $relationship_slug
|
71 |
+
* @param int $parent_id
|
72 |
+
* @param int $child_id
|
73 |
+
*
|
74 |
+
* @since m2m
|
75 |
+
*/
|
76 |
+
$post_title = wp_strip_all_tags(
|
77 |
+
apply_filters(
|
78 |
+
'toolset_build_intermediary_post_title',
|
79 |
+
$this->get_default_intermediary_post_title( $parent_id, $child_id ),
|
80 |
+
$this->relationship->get_slug(),
|
81 |
+
$parent_id,
|
82 |
+
$child_id
|
83 |
+
)
|
84 |
+
);
|
85 |
+
|
86 |
+
/**
|
87 |
+
* toolset_build_intermediary_post_name
|
88 |
+
*
|
89 |
+
* Allow for overriding the post name (slug) of an intermediary post.
|
90 |
+
*
|
91 |
+
* @param string $post_slug Post slug default value.
|
92 |
+
* @param string $relationship_slug
|
93 |
+
* @param int $parent_id
|
94 |
+
* @param int $child_id
|
95 |
+
*
|
96 |
+
* @since m2m
|
97 |
+
*/
|
98 |
+
$post_name = apply_filters(
|
99 |
+
'toolset_build_intermediary_post_name',
|
100 |
+
$post_title,
|
101 |
+
$this->relationship->get_slug(),
|
102 |
+
$parent_id,
|
103 |
+
$child_id
|
104 |
+
);
|
105 |
+
|
106 |
+
// Intermediary posts need to be always created in the default language, even if the IPT
|
107 |
+
// is translatable. Otherwise, it will not be possible to persist the association
|
108 |
+
// (it requires a default language translation of all involved elements).
|
109 |
+
$needs_wpml_lang_switch = (
|
110 |
+
$this->wpml_service->is_wpml_active_and_configured()
|
111 |
+
&& ! $this->wpml_service->is_current_language_default()
|
112 |
+
);
|
113 |
+
|
114 |
+
if( $needs_wpml_lang_switch ) {
|
115 |
+
$this->wpml_service->switch_language( $this->wpml_service->get_default_language() );
|
116 |
+
}
|
117 |
+
|
118 |
+
$result = wp_insert_post(
|
119 |
+
array(
|
120 |
+
'post_type' => $post_type,
|
121 |
+
'post_title' => $post_title,
|
122 |
+
'post_name' => $post_name,
|
123 |
+
'post_content' => '',
|
124 |
+
'post_status' => 'publish'
|
125 |
+
),
|
126 |
+
true
|
127 |
+
);
|
128 |
+
|
129 |
+
if( $needs_wpml_lang_switch ) {
|
130 |
+
$this->wpml_service->switch_language_back();
|
131 |
+
}
|
132 |
+
|
133 |
+
if ( $result instanceof WP_Error ) {
|
134 |
+
return null;
|
135 |
+
}
|
136 |
+
|
137 |
+
return $result;
|
138 |
+
}
|
139 |
+
|
140 |
+
/**
|
141 |
+
* Returns the default name for an association intermediary post.
|
142 |
+
*
|
143 |
+
* @param int $parent_id Association parent id.
|
144 |
+
* @param int $child_id Association child id.
|
145 |
+
*
|
146 |
+
* @return string
|
147 |
+
* @since m2m
|
148 |
+
*/
|
149 |
+
private function get_default_intermediary_post_title( $parent_id, $child_id ) {
|
150 |
+
return sprintf(
|
151 |
+
'%s: %d - %d',
|
152 |
+
$this->relationship->get_display_name(),
|
153 |
+
$parent_id,
|
154 |
+
$child_id
|
155 |
+
);
|
156 |
+
}
|
157 |
+
|
158 |
+
|
159 |
+
/**
|
160 |
+
* It there are associations belonging to the definition, intermediary post without field values has to be created.
|
161 |
+
*
|
162 |
+
* @param int $limit The number of associations in a loop.
|
163 |
+
* @since 2.3
|
164 |
+
*/
|
165 |
+
public function create_empty_associations_intermediary_posts( $limit = 0 ) {
|
166 |
+
if ( (int) $limit <= 0 ) {
|
167 |
+
$limit = self::DEFAULT_LIMIT;
|
168 |
+
}
|
169 |
+
|
170 |
+
$association_query = new Toolset_Association_Query_V2();
|
171 |
+
$association_query->add( $association_query->relationship( $this->relationship ) );
|
172 |
+
$association_query->add( new Toolset_Association_Query_Condition_Empty_Intermediary() );
|
173 |
+
$association_query->limit( $limit );
|
174 |
+
$associations = $association_query->get_results();
|
175 |
+
foreach ( $associations as $association ) {
|
176 |
+
if ( ! $association->get_intermediary_id() ) {
|
177 |
+
$this->create_empty_association_intermediary_post( $association );
|
178 |
+
}
|
179 |
+
}
|
180 |
+
}
|
181 |
+
|
182 |
+
|
183 |
+
|
184 |
+
/**
|
185 |
+
* Creates an empty association intermediary post
|
186 |
+
*
|
187 |
+
* @param IToolset_Association $association Association.
|
188 |
+
* @return int Post ID
|
189 |
+
* @since m2m
|
190 |
+
*/
|
191 |
+
public function create_empty_association_intermediary_post( $association ) {
|
192 |
+
$intermediary_id = (int) $this->create_intermediary_post(
|
193 |
+
$association->get_element( new Toolset_Relationship_Role_Parent() )->get_id(),
|
194 |
+
$association->get_element( new Toolset_Relationship_Role_Child() )->get_id()
|
195 |
+
);
|
196 |
+
if ( $intermediary_id ) {
|
197 |
+
$database_operations = new Toolset_Relationship_Database_Operations();
|
198 |
+
$database_operations->update_association_intermediary_id( $association->get_uid(), $intermediary_id );
|
199 |
+
}
|
200 |
+
return $intermediary_id;
|
201 |
+
}
|
202 |
+
|
203 |
+
|
204 |
+
/**
|
205 |
+
* Delete the intermediary post if it exists and it's not disabled by a filter.
|
206 |
+
*
|
207 |
+
* This also deletes all its translations.
|
208 |
+
*
|
209 |
+
* @param IToolset_Association $association
|
210 |
+
*/
|
211 |
+
public function maybe_delete_intermediary_post( IToolset_Association $association ) {
|
212 |
+
if ( $association->has_intermediary_post() ) {
|
213 |
+
$intermediary_id = $association->get_element( new Toolset_Relationship_Role_Intermediary() )
|
214 |
+
->get_default_language_id();
|
215 |
+
$this->delete_intermediary_post( $intermediary_id );
|
216 |
+
}
|
217 |
+
}
|
218 |
+
|
219 |
+
|
220 |
+
/**
|
221 |
+
* Delete the intermediary post if it's not disabled by a filter.
|
222 |
+
*
|
223 |
+
* This also deletes all its translations.
|
224 |
+
*
|
225 |
+
* @param $post_id
|
226 |
+
*/
|
227 |
+
public function delete_intermediary_post( $post_id ) {
|
228 |
+
|
229 |
+
/**
|
230 |
+
* toolset_deleting_association_intermediary_post
|
231 |
+
*
|
232 |
+
* Notify about deleting the intermediary post and allow avoiding it.
|
233 |
+
*
|
234 |
+
* @param bool $delete_post Whether the post should be deleted.
|
235 |
+
* @param int $intermediary_id ID of the intermediary post.
|
236 |
+
*/
|
237 |
+
$delete_post = apply_filters(
|
238 |
+
'toolset_deleting_association_intermediary_post',
|
239 |
+
true,
|
240 |
+
$post_id
|
241 |
+
);
|
242 |
+
|
243 |
+
if ( $delete_post ) {
|
244 |
+
add_filter( Toolset_Association_Cleanup_Post::IS_DELETING_FILTER, '__return_true' );
|
245 |
+
|
246 |
+
// We also need to delete post translations, because WPML doesn't handle that at all.
|
247 |
+
// This is out of the scope of the association query, so we'll query for translations
|
248 |
+
// individually, per post which we're deleting.
|
249 |
+
$this->delete_post_translations( $post_id );
|
250 |
+
|
251 |
+
wp_delete_post( $post_id );
|
252 |
+
remove_filter( Toolset_Association_Cleanup_Post::IS_DELETING_FILTER, '__return_true' );
|
253 |
+
}
|
254 |
+
}
|
255 |
+
|
256 |
+
|
257 |
+
/**
|
258 |
+
* Delete posts which are translations of the provided post.
|
259 |
+
*
|
260 |
+
* Thanks to the implementation of Toolset_WPML_Compatibility::get_post_translations_directly(), this
|
261 |
+
* is safe without WPML as well.
|
262 |
+
*
|
263 |
+
* @param int $post_id
|
264 |
+
*/
|
265 |
+
private function delete_post_translations( $post_id ) {
|
266 |
+
$post_translations = $this->wpml_service->get_post_translations_directly( $post_id );
|
267 |
+
foreach( $post_translations as $post_translation_id ) {
|
268 |
+
wp_delete_post( $post_translation_id, true );
|
269 |
+
}
|
270 |
+
}
|
271 |
+
|
272 |
+
|
273 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/association/persistence.php
ADDED
@@ -0,0 +1,160 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Handles the persistence of associations, from IToolset_Association object
|
5 |
+
* to a wpdb call and back.
|
6 |
+
*
|
7 |
+
* Like Toolset_Relationship_Definition_Persistence, this should not be used from outside
|
8 |
+
* of the m2m API. Everything required for working with associations should be
|
9 |
+
* implemented on IToolset_Relationship_Definition.
|
10 |
+
*
|
11 |
+
* @since 2.5.8
|
12 |
+
*/
|
13 |
+
class Toolset_Association_Persistence {
|
14 |
+
|
15 |
+
|
16 |
+
/** @var Toolset_Association_Factory */
|
17 |
+
private $association_factory;
|
18 |
+
|
19 |
+
|
20 |
+
/** @var Toolset_Relationship_Table_Name */
|
21 |
+
private $table_name;
|
22 |
+
|
23 |
+
|
24 |
+
/** @var wpdb */
|
25 |
+
private $wpdb;
|
26 |
+
|
27 |
+
|
28 |
+
/** @var Toolset_Association_Translator */
|
29 |
+
private $association_translator;
|
30 |
+
|
31 |
+
|
32 |
+
/** @var null|Toolset_Association_Cleanup_Factory */
|
33 |
+
protected $_cleanup_factory;
|
34 |
+
|
35 |
+
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Toolset_Association_Persistence constructor.
|
39 |
+
*
|
40 |
+
* @param Toolset_Association_Factory|null $association_factory_di
|
41 |
+
* @param Toolset_Relationship_Table_Name|null $table_name_di
|
42 |
+
* @param wpdb|null $wpdb_di
|
43 |
+
* @param Toolset_Association_Translator|null $association_translator_di
|
44 |
+
* @param Toolset_Association_Cleanup_Factory|null $cleanup_factory_di
|
45 |
+
*/
|
46 |
+
public function __construct(
|
47 |
+
Toolset_Association_Factory $association_factory_di = null,
|
48 |
+
Toolset_Relationship_Table_Name $table_name_di = null,
|
49 |
+
wpdb $wpdb_di = null,
|
50 |
+
Toolset_Association_Translator $association_translator_di = null,
|
51 |
+
Toolset_Association_Cleanup_Factory $cleanup_factory_di = null
|
52 |
+
) {
|
53 |
+
$this->association_factory = ( null === $association_factory_di ? new Toolset_Association_Factory() : $association_factory_di );
|
54 |
+
$this->table_name = ( null === $table_name_di ? new Toolset_Relationship_Table_Name() : $table_name_di );
|
55 |
+
$this->association_translator = ( null === $association_translator_di ? new Toolset_Association_Translator() : $association_translator_di );
|
56 |
+
global $wpdb;
|
57 |
+
$this->wpdb = ( null === $wpdb_di ? $wpdb : $wpdb_di );
|
58 |
+
$this->_cleanup_factory = $cleanup_factory_di;
|
59 |
+
}
|
60 |
+
|
61 |
+
|
62 |
+
/**
|
63 |
+
* Load a native association from the database.
|
64 |
+
*
|
65 |
+
* @param int $association_uid Association UID.
|
66 |
+
*
|
67 |
+
* @return null|IToolset_Association The association instance
|
68 |
+
* or null if it couln't have been loaded.
|
69 |
+
* @deprecated Do not use this outside of the m2m API, instead, use the association query.
|
70 |
+
*/
|
71 |
+
public function load_association_by_uid( $association_uid ) {
|
72 |
+
$associations_table = $this->table_name->association_table();
|
73 |
+
|
74 |
+
$query = $this->wpdb->prepare(
|
75 |
+
"SELECT * FROM {$associations_table} WHERE trid = %d",
|
76 |
+
$association_uid
|
77 |
+
);
|
78 |
+
|
79 |
+
$row = $this->wpdb->get_row( $query );
|
80 |
+
|
81 |
+
if ( ! $row ) {
|
82 |
+
return null;
|
83 |
+
}
|
84 |
+
|
85 |
+
$relationship = Toolset_Relationship_Definition_Repository::get_instance()
|
86 |
+
->get_definition_by_row_id( $row->relationship_id );
|
87 |
+
|
88 |
+
if ( null === $relationship ) {
|
89 |
+
return null;
|
90 |
+
}
|
91 |
+
|
92 |
+
try {
|
93 |
+
return $this->association_factory->create(
|
94 |
+
$relationship,
|
95 |
+
(int) $row->parent_id,
|
96 |
+
(int) $row->child_id,
|
97 |
+
(int) $row->intermediary_id,
|
98 |
+
(int) $row->id
|
99 |
+
);
|
100 |
+
} catch( Exception $e ) {
|
101 |
+
return null;
|
102 |
+
}
|
103 |
+
}
|
104 |
+
|
105 |
+
|
106 |
+
/**
|
107 |
+
* Insert a new association in the database.
|
108 |
+
*
|
109 |
+
* @param IToolset_Association $association
|
110 |
+
*
|
111 |
+
* @return IToolset_Association
|
112 |
+
* @throws Toolset_Element_Exception_Element_Doesnt_Exist
|
113 |
+
*/
|
114 |
+
public function insert_association( IToolset_Association $association ) {
|
115 |
+
$row = $this->association_translator->to_database_row( $association );
|
116 |
+
|
117 |
+
$this->wpdb->insert(
|
118 |
+
$this->table_name->association_table(),
|
119 |
+
$row,
|
120 |
+
$this->association_translator->get_database_row_formats()
|
121 |
+
);
|
122 |
+
|
123 |
+
$row['id'] = $this->wpdb->insert_id;
|
124 |
+
|
125 |
+
$updated_association = $this->association_translator->from_database_row( (object) $row );
|
126 |
+
|
127 |
+
return $updated_association;
|
128 |
+
}
|
129 |
+
|
130 |
+
|
131 |
+
/**
|
132 |
+
* Delete an association from the database.
|
133 |
+
*
|
134 |
+
* Also delete an intermediary post if it exists.
|
135 |
+
*
|
136 |
+
* @param IToolset_Association $association
|
137 |
+
*
|
138 |
+
* @return Toolset_Result
|
139 |
+
* @since m2m
|
140 |
+
*/
|
141 |
+
public function delete_association( IToolset_Association $association ) {
|
142 |
+
$cleanup = $this->get_cleanup_factory()->association();
|
143 |
+
return $cleanup->delete( $association );
|
144 |
+
}
|
145 |
+
|
146 |
+
|
147 |
+
/**
|
148 |
+
* @return Toolset_Association_Cleanup_Factory
|
149 |
+
*/
|
150 |
+
private function get_cleanup_factory() {
|
151 |
+
if( null === $this->_cleanup_factory ) {
|
152 |
+
$this->_cleanup_factory = new Toolset_Association_Cleanup_Factory();
|
153 |
+
}
|
154 |
+
|
155 |
+
return $this->_cleanup_factory;
|
156 |
+
}
|
157 |
+
|
158 |
+
|
159 |
+
|
160 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/association/query/association_query.php
ADDED
@@ -0,0 +1,244 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* A class for querying associations and associated elements.
|
5 |
+
*
|
6 |
+
* Usage:
|
7 |
+
*
|
8 |
+
* $query = new Toolset_Association_Query( $args );
|
9 |
+
* $results = $query->get_results();
|
10 |
+
*
|
11 |
+
* Notes:
|
12 |
+
*
|
13 |
+
* - For now, it supports only the native associations (they're the only ones we have).
|
14 |
+
* - If you need to query by some parameters that are not supported, either create a feature request about it or
|
15 |
+
* submit a merge request rather than going around the query and touching the database directly.
|
16 |
+
*
|
17 |
+
* WARNING: This got deprecated and was turned into a complatibility layer for Toolset_Association_Query_V2.
|
18 |
+
*
|
19 |
+
* @since m2m
|
20 |
+
* @deprecated Since 2.5.8. Use Toolset_Association_Query instead.
|
21 |
+
*/
|
22 |
+
class Toolset_Association_Query extends Toolset_Relationship_Query_Base {
|
23 |
+
|
24 |
+
/** @var string One of the RETURN_* constants determining what kind of output should be provided. */
|
25 |
+
private $return;
|
26 |
+
|
27 |
+
/** @var bool */
|
28 |
+
protected $dont_count_found_rows;
|
29 |
+
|
30 |
+
const OPTION_USE_CACHED_RESULTS = 'use_cached_results';
|
31 |
+
const OPTION_CACHE_RESULTS = 'cache_results';
|
32 |
+
const OPTION_RETURN = 'return';
|
33 |
+
const OPTION_DONT_COUNT_FOUND_ROWS = 'no_found_rows';
|
34 |
+
const QUERY_OFFSET = 'offset';
|
35 |
+
const QUERY_LIMIT = 'limit';
|
36 |
+
const QUERY_SELECT_FIELDS = 'select_fields';
|
37 |
+
const QUERY_RELATIONSHIP_SLUG = 'relationship_slug';
|
38 |
+
const QUERY_RELATIONSHIP_ID = 'relationship_id';
|
39 |
+
const QUERY_PARENT_ID = 'parent_id';
|
40 |
+
const QUERY_CHILD_ID = 'child_id';
|
41 |
+
const QUERY_PARENT_DOMAIN = 'parent_domain';
|
42 |
+
const QUERY_PARENT_QUERY = 'parent_query';
|
43 |
+
const QUERY_CHILD_DOMAIN = 'child_domain';
|
44 |
+
const QUERY_CHILD_QUERY = 'child_query';
|
45 |
+
const QUERY_LANGUAGE = 'language';
|
46 |
+
const QUERY_HAS_TRASHED_POSTS = 'has_trashed_posts';
|
47 |
+
const RETURN_ASSOCIATION_IDS = 'association_ids';
|
48 |
+
const RETURN_ASSOCIATIONS = 'associations';
|
49 |
+
const RETURN_PARENT_IDS = 'parent_ids';
|
50 |
+
const RETURN_CHILD_IDS = 'child_ids';
|
51 |
+
const RETURN_PARENTS = 'parents';
|
52 |
+
const RETURN_CHILDREN = 'children';
|
53 |
+
const LANGUAGE_ALL = 'all';
|
54 |
+
const GROUP_CONCAT_SEPARATOR = ',';
|
55 |
+
|
56 |
+
|
57 |
+
/**
|
58 |
+
* Parse query arguments, store them sanitized as options or in the $query_vars array.
|
59 |
+
*
|
60 |
+
* @param array $query
|
61 |
+
*/
|
62 |
+
protected function parse_query( $query ) {
|
63 |
+
|
64 |
+
$this->use_cached_results = (bool) toolset_getarr( $query, self::OPTION_USE_CACHED_RESULTS, true );
|
65 |
+
$this->cache_results = (bool) toolset_getarr( $query, self::OPTION_CACHE_RESULTS, true );
|
66 |
+
$this->return = toolset_getarr( $query, self::OPTION_RETURN, self::RETURN_ASSOCIATIONS, $this->get_return_options() );
|
67 |
+
$this->dont_count_found_rows = (bool) toolset_getarr( $query, self::OPTION_DONT_COUNT_FOUND_ROWS, false );
|
68 |
+
|
69 |
+
// Default value of these needs to be null
|
70 |
+
$this->parse_query_arg( $query, self::QUERY_RELATIONSHIP_SLUG, 'strval' );
|
71 |
+
$this->parse_query_arg( $query, self::QUERY_RELATIONSHIP_ID, 'absint' );
|
72 |
+
$this->parse_query_arg( $query, self::QUERY_PARENT_ID, 'absint' );
|
73 |
+
$this->parse_query_arg( $query, self::QUERY_CHILD_ID, 'absint' );
|
74 |
+
$this->parse_query_arg( $query, self::QUERY_LIMIT, 'absint' );
|
75 |
+
$this->parse_query_arg( $query, self::QUERY_OFFSET, 'absint' );
|
76 |
+
$this->parse_query_arg( $query, self::QUERY_SELECT_FIELDS, null, array() );
|
77 |
+
$this->parse_query_arg( $query, self::QUERY_PARENT_DOMAIN, null, null, array( Toolset_Field_Utils::DOMAIN_POSTS ) );
|
78 |
+
$this->parse_query_arg( $query, self::QUERY_PARENT_QUERY, null );
|
79 |
+
$this->parse_query_arg( $query, self::QUERY_CHILD_DOMAIN, null, null, array( Toolset_Field_Utils::DOMAIN_POSTS ) );
|
80 |
+
$this->parse_query_arg( $query, self::QUERY_CHILD_QUERY, null );
|
81 |
+
$this->parse_query_arg( $query, self::QUERY_HAS_TRASHED_POSTS, 'boolval' );
|
82 |
+
}
|
83 |
+
|
84 |
+
|
85 |
+
/**
|
86 |
+
* Perform the query and get results.
|
87 |
+
*
|
88 |
+
* Depending on query arguments, the results may be cached.
|
89 |
+
*
|
90 |
+
* @return int[]|IToolset_Element[]|IToolset_Association[] Array of results, depending on query arguments.
|
91 |
+
*/
|
92 |
+
public function get_results() {
|
93 |
+
$q = new Toolset_Association_Query_V2();
|
94 |
+
|
95 |
+
if ( $this->has_query_var( self::QUERY_RELATIONSHIP_SLUG ) ) {
|
96 |
+
$relationship_slug = $this->get_query_var( self::QUERY_RELATIONSHIP_SLUG );
|
97 |
+
$q->add( $q->relationship_slug( $relationship_slug ) );
|
98 |
+
}
|
99 |
+
|
100 |
+
if ( $this->has_query_var( self::QUERY_RELATIONSHIP_ID ) ) {
|
101 |
+
$relationship_id = $this->get_query_var( self::QUERY_RELATIONSHIP_ID );
|
102 |
+
$q->add( $q->relationship_id( $relationship_id ) );
|
103 |
+
}
|
104 |
+
|
105 |
+
if ( $this->has_query_var( self::QUERY_PARENT_ID ) ) {
|
106 |
+
$q->add( $q->parent_id( $this->get_query_var( self::QUERY_PARENT_ID ) ) );
|
107 |
+
}
|
108 |
+
|
109 |
+
if ( $this->has_query_var( self::QUERY_HAS_TRASHED_POSTS ) ) {
|
110 |
+
$include_trash = $this->get_query_var( self::QUERY_HAS_TRASHED_POSTS );
|
111 |
+
if ( $include_trash ) {
|
112 |
+
$q->add(
|
113 |
+
$q->do_and(
|
114 |
+
$q->element_status( 'any', new Toolset_Relationship_Role_Parent() ),
|
115 |
+
$q->element_status( 'any', new Toolset_Relationship_Role_Child() )
|
116 |
+
)
|
117 |
+
);
|
118 |
+
}
|
119 |
+
}
|
120 |
+
|
121 |
+
if ( $this->has_query_var( self::QUERY_CHILD_ID ) ) {
|
122 |
+
$q->add( $q->child_id( $this->get_query_var( self::QUERY_CHILD_ID ) ) );
|
123 |
+
}
|
124 |
+
|
125 |
+
if ( $this->has_query_var( self::QUERY_PARENT_DOMAIN ) ) {
|
126 |
+
$q->add( $q->has_domain( $this->get_query_var( self::QUERY_PARENT_DOMAIN ), new Toolset_Relationship_Role_Parent() ) );
|
127 |
+
}
|
128 |
+
|
129 |
+
if ( $this->has_query_var( self::QUERY_CHILD_DOMAIN ) ) {
|
130 |
+
$q->add( $q->has_domain( $this->get_query_var( self::QUERY_CHILD_DOMAIN ), new Toolset_Relationship_Role_Child() ) );
|
131 |
+
}
|
132 |
+
|
133 |
+
if( $this->has_query_var( self::QUERY_PARENT_QUERY ) ) {
|
134 |
+
$q->add( $q->wp_query( new Toolset_Relationship_Role_Parent(), $this->get_query_var( self::QUERY_PARENT_QUERY ), 'i_know_what_i_am_doing' ) );
|
135 |
+
}
|
136 |
+
|
137 |
+
if( $this->has_query_var( self::QUERY_CHILD_QUERY ) ) {
|
138 |
+
$q->add( $q->wp_query( new Toolset_Relationship_Role_Child(), $this->get_query_var( self::QUERY_CHILD_QUERY ), 'i_know_what_i_am_doing' ) );
|
139 |
+
}
|
140 |
+
|
141 |
+
if( $this->need_row_count() ) {
|
142 |
+
$q->need_found_rows();
|
143 |
+
}
|
144 |
+
|
145 |
+
if ( $this->has_query_var( self::QUERY_LIMIT ) ) {
|
146 |
+
$q->limit( $this->get_query_var( self::QUERY_LIMIT ) );
|
147 |
+
if ( $this->has_query_var( self::QUERY_OFFSET ) ) {
|
148 |
+
$q->offset( $this->get_query_var( self::QUERY_OFFSET ) );
|
149 |
+
}
|
150 |
+
} else {
|
151 |
+
// Toolset_Association_Query worked without a limit set by the user
|
152 |
+
// Toolset_Association_Query_V2 requires that the user sets a limit, otherwise FATAL ERROR
|
153 |
+
// For backward compatibility we're adding limit 1000 if no specific limit set by the user
|
154 |
+
$q->limit( 1000 );
|
155 |
+
}
|
156 |
+
|
157 |
+
switch( $this->return ) {
|
158 |
+
case self::RETURN_ASSOCIATION_IDS:
|
159 |
+
$q->return_association_uids();
|
160 |
+
break;
|
161 |
+
case self::RETURN_ASSOCIATIONS:
|
162 |
+
$q->return_association_instances();
|
163 |
+
break;
|
164 |
+
case self::RETURN_PARENT_IDS:
|
165 |
+
$q->return_element_ids( new Toolset_Relationship_Role_Parent() );
|
166 |
+
break;
|
167 |
+
case self::RETURN_CHILD_IDS:
|
168 |
+
$q->return_element_ids( new Toolset_Relationship_Role_Child() );
|
169 |
+
break;
|
170 |
+
case self::RETURN_PARENTS:
|
171 |
+
$q->return_element_instances( new Toolset_Relationship_Role_Parent() );
|
172 |
+
break;
|
173 |
+
case self::RETURN_CHILDREN:
|
174 |
+
$q->return_element_instances( new Toolset_Relationship_Role_Child() );
|
175 |
+
break;
|
176 |
+
}
|
177 |
+
|
178 |
+
return $q->get_results();
|
179 |
+
}
|
180 |
+
|
181 |
+
|
182 |
+
|
183 |
+
protected function get_subject_name_for_cache() {
|
184 |
+
return 'associations';
|
185 |
+
}
|
186 |
+
|
187 |
+
|
188 |
+
/**
|
189 |
+
* Build the MySQL statement for querying the data, depending on query variables.
|
190 |
+
*
|
191 |
+
* @return string MySQL query statement.
|
192 |
+
* @since m2m
|
193 |
+
*/
|
194 |
+
protected function build_sql_statement() {
|
195 |
+
return '';
|
196 |
+
}
|
197 |
+
|
198 |
+
|
199 |
+
/**
|
200 |
+
* @inheritdoc
|
201 |
+
* @return string
|
202 |
+
*/
|
203 |
+
protected function get_results_type() {
|
204 |
+
return ARRAY_A;
|
205 |
+
}
|
206 |
+
|
207 |
+
|
208 |
+
/**
|
209 |
+
* @return string[] Possible values for the 'return' query argument.
|
210 |
+
*/
|
211 |
+
private function get_return_options() {
|
212 |
+
return array(
|
213 |
+
self::RETURN_ASSOCIATIONS,
|
214 |
+
self::RETURN_ASSOCIATION_IDS,
|
215 |
+
self::RETURN_CHILD_IDS,
|
216 |
+
self::RETURN_CHILDREN,
|
217 |
+
self::RETURN_PARENT_IDS,
|
218 |
+
self::RETURN_PARENTS
|
219 |
+
);
|
220 |
+
}
|
221 |
+
|
222 |
+
|
223 |
+
/**
|
224 |
+
* Determine if SQL_CALC_FOUND_ROWS should be part of the MySQL statement.
|
225 |
+
*
|
226 |
+
* @return bool
|
227 |
+
*/
|
228 |
+
private function need_row_count() {
|
229 |
+
return ( ! $this->dont_count_found_rows && $this->has_query_var( self::QUERY_LIMIT ) );
|
230 |
+
}
|
231 |
+
|
232 |
+
|
233 |
+
/**
|
234 |
+
* Process raw output from $wpdb.
|
235 |
+
*
|
236 |
+
* @param array $rows
|
237 |
+
*
|
238 |
+
* @return array
|
239 |
+
*/
|
240 |
+
protected function postprocess_results( $rows ) {
|
241 |
+
return array();
|
242 |
+
}
|
243 |
+
|
244 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/association/query/association_query_v2.php
ADDED
@@ -0,0 +1,994 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Association query class with a more OOP/functional approach.
|
5 |
+
*
|
6 |
+
* Replaces Toolset_Association_Query.
|
7 |
+
*
|
8 |
+
* Allows for chaining query conditions and avoiding passing query arguments as associative arrays.
|
9 |
+
* It makes it also possible to build queries with nested AND & OR statements in an arbitrary way.
|
10 |
+
* The object model may be complex but all the complexity is hidden from the user, they need to know
|
11 |
+
* only the methods on this class.
|
12 |
+
*
|
13 |
+
* Example usage:
|
14 |
+
*
|
15 |
+
* $query = new Toolset_Association_Query_V2();
|
16 |
+
*
|
17 |
+
* $results = $query
|
18 |
+
* ->add(
|
19 |
+
* $query->has_domain( 'posts', new Toolset_Relationship_Role_Parent() )
|
20 |
+
* )
|
21 |
+
* ->add(
|
22 |
+
* $query->do_or(
|
23 |
+
* $query->has_type( 'attachment', new Toolset_Relationship_Role_Parent() ),
|
24 |
+
* $query->do_and(
|
25 |
+
* $query->has_type( 'page', new Toolset_Relationship_Role_Child() ),
|
26 |
+
* $query->has_type( 'post', new Toolset_Relationship_Role_Child() ),
|
27 |
+
* )
|
28 |
+
* )
|
29 |
+
* )
|
30 |
+
* ->add(
|
31 |
+
* $query->search( 'some string', new Toolset_Relationship_Role_Parent() )
|
32 |
+
* )
|
33 |
+
* ->order_by_field_value( $custom_field_definition )
|
34 |
+
* ->order( 'DESC' )
|
35 |
+
* ->limit( 50 )
|
36 |
+
* ->offset( 100 )
|
37 |
+
* ->return_association_instances()
|
38 |
+
* ->get_results();
|
39 |
+
*
|
40 |
+
* Note about default conditions:
|
41 |
+
* - If no element status (element_status() or has_available_elements()) condition is used when constructing the query,
|
42 |
+
* has_available_elements() is used.
|
43 |
+
* - If no has_active_relationship() condition is used when constructing the query, has_active_relationship(true)
|
44 |
+
* is used.
|
45 |
+
* - This mechanism doesn't recognize where, how and if these conditions are actually applied, so even
|
46 |
+
* $query->do_if( false, $query->has_active_relationship( true ) ) will disable the default
|
47 |
+
* has_active_relationship() condition.
|
48 |
+
* - You can prevent the adding of default conditions by $query->do_not_add_default_conditions().
|
49 |
+
*
|
50 |
+
* @since 2.5.8
|
51 |
+
*/
|
52 |
+
class Toolset_Association_Query_V2 extends Toolset_Wpdb_User implements IToolset_Query {
|
53 |
+
|
54 |
+
|
55 |
+
/** @var IToolset_Association_Query_Condition[] */
|
56 |
+
private $conditions = array();
|
57 |
+
|
58 |
+
/** @var Toolset_Relationship_Database_Unique_Table_Alias */
|
59 |
+
private $unique_table_alias;
|
60 |
+
|
61 |
+
/** @var Toolset_Association_Query_Condition_Factory */
|
62 |
+
private $condition_factory;
|
63 |
+
|
64 |
+
/** @var Toolset_Association_Query_Sql_Expression_Builder */
|
65 |
+
private $expression_builder;
|
66 |
+
|
67 |
+
/** @var bool */
|
68 |
+
private $should_add_default_conditions = true;
|
69 |
+
|
70 |
+
/** @var bool */
|
71 |
+
private $has_active_relationship_condition = false;
|
72 |
+
|
73 |
+
/** @var bool */
|
74 |
+
private $has_element_status_condition = false;
|
75 |
+
|
76 |
+
/** @var Toolset_Association_Translator */
|
77 |
+
private $association_translator;
|
78 |
+
|
79 |
+
/** @var Toolset_Relationship_Definition_Repository|null */
|
80 |
+
private $_definition_repository;
|
81 |
+
|
82 |
+
/** @var Toolset_Association_Query_Table_Join_Manager */
|
83 |
+
private $join_manager;
|
84 |
+
|
85 |
+
/** @var IToolset_Association_Query_Result_Transformation */
|
86 |
+
private $result_transformation;
|
87 |
+
|
88 |
+
/** @var int|null */
|
89 |
+
private $limit = null;
|
90 |
+
|
91 |
+
/** @var int */
|
92 |
+
private $offset = 0;
|
93 |
+
|
94 |
+
/** @var IToolset_Association_Query_Orderby|null */
|
95 |
+
private $orderby = null;
|
96 |
+
|
97 |
+
/** @var string */
|
98 |
+
private $order = 'ASC';
|
99 |
+
|
100 |
+
/** @var bool */
|
101 |
+
private $need_found_rows = false;
|
102 |
+
|
103 |
+
/** @var int|null */
|
104 |
+
private $found_rows;
|
105 |
+
|
106 |
+
/** @var Toolset_Association_Query_Orderby_Factory */
|
107 |
+
private $orderby_factory;
|
108 |
+
|
109 |
+
/** @var bool Remember whether get_results() was called. */
|
110 |
+
private $was_used = false;
|
111 |
+
|
112 |
+
/** @var Toolset_Association_Query_Element_Selector_Provider */
|
113 |
+
private $element_selector_provider;
|
114 |
+
|
115 |
+
/** @var IToolset_Association_Query_Restriction[] */
|
116 |
+
private $restrictions = array();
|
117 |
+
|
118 |
+
|
119 |
+
/**
|
120 |
+
* Toolset_Association_Query_V2 constructor.
|
121 |
+
*
|
122 |
+
* @param wpdb|null $wpdb_di
|
123 |
+
* @param Toolset_Relationship_Database_Unique_Table_Alias|null $unique_table_alias_di
|
124 |
+
* @param Toolset_Association_Query_Sql_Expression_Builder|null $expression_builder_di
|
125 |
+
* @param Toolset_Association_Query_Condition_Factory|null $condition_factory_di
|
126 |
+
* @param Toolset_Association_Translator|null $association_translator_di
|
127 |
+
* @param Toolset_Relationship_Definition_Repository|null $definition_repository_di
|
128 |
+
* @param Toolset_Association_Query_Table_Join_Manager|null $join_manager_di
|
129 |
+
* @param Toolset_Association_Query_Orderby_Factory|null $orderby_factory_di
|
130 |
+
* @param Toolset_Association_Query_Element_Selector_Provider|null $element_selector_provider_di
|
131 |
+
*/
|
132 |
+
public function __construct(
|
133 |
+
wpdb $wpdb_di = null,
|
134 |
+
Toolset_Relationship_Database_Unique_Table_Alias $unique_table_alias_di = null,
|
135 |
+
Toolset_Association_Query_Sql_Expression_Builder $expression_builder_di = null,
|
136 |
+
Toolset_Association_Query_Condition_Factory $condition_factory_di = null,
|
137 |
+
Toolset_Association_Translator $association_translator_di = null,
|
138 |
+
Toolset_Relationship_Definition_Repository $definition_repository_di = null,
|
139 |
+
Toolset_Association_Query_Table_Join_Manager $join_manager_di = null,
|
140 |
+
Toolset_Association_Query_Orderby_Factory $orderby_factory_di = null,
|
141 |
+
Toolset_Association_Query_Element_Selector_Provider $element_selector_provider_di = null
|
142 |
+
) {
|
143 |
+
parent::__construct( $wpdb_di );
|
144 |
+
$this->unique_table_alias = $unique_table_alias_di ?: new Toolset_Relationship_Database_Unique_Table_Alias();
|
145 |
+
$this->condition_factory = $condition_factory_di ?: new Toolset_Association_Query_Condition_Factory();
|
146 |
+
$this->association_translator = $association_translator_di ?: new Toolset_Association_Translator();
|
147 |
+
$this->join_manager = $join_manager_di ?: new Toolset_Association_Query_Table_Join_Manager( $this->unique_table_alias );
|
148 |
+
$this->expression_builder = $expression_builder_di ?: new Toolset_Association_Query_Sql_Expression_Builder( $this->join_manager );
|
149 |
+
$this->orderby_factory = $orderby_factory_di ?: new Toolset_Association_Query_Orderby_Factory();
|
150 |
+
$this->element_selector_provider = $element_selector_provider_di ?: new Toolset_Association_Query_Element_Selector_Provider();
|
151 |
+
$this->_definition_repository = $definition_repository_di;
|
152 |
+
}
|
153 |
+
|
154 |
+
|
155 |
+
|
156 |
+
/**
|
157 |
+
* Add another condition to the query.
|
158 |
+
*
|
159 |
+
* @param IToolset_Association_Query_Condition $condition
|
160 |
+
* @return $this
|
161 |
+
*/
|
162 |
+
public function add( IToolset_Association_Query_Condition $condition ) {
|
163 |
+
$this->conditions[] = $condition;
|
164 |
+
return $this;
|
165 |
+
}
|
166 |
+
|
167 |
+
|
168 |
+
/**
|
169 |
+
* Allow for adding query restrictions to reduce its complexity
|
170 |
+
* right after all conditions have been added.
|
171 |
+
*
|
172 |
+
* @param IToolset_Association_Query_Condition $root_condition
|
173 |
+
*/
|
174 |
+
private function maybe_add_restrictions( IToolset_Association_Query_Condition $root_condition ) {
|
175 |
+
// Nothing to do yet.
|
176 |
+
}
|
177 |
+
|
178 |
+
|
179 |
+
/**
|
180 |
+
* Basically, this sets default query parameters.
|
181 |
+
*
|
182 |
+
* The method needs to stay idempotent.
|
183 |
+
*/
|
184 |
+
private function add_default_conditions() {
|
185 |
+
if ( ! $this->should_add_default_conditions ) {
|
186 |
+
return;
|
187 |
+
}
|
188 |
+
|
189 |
+
if( ! $this->has_element_status_condition ) {
|
190 |
+
$this->add( $this->has_available_elements() );
|
191 |
+
}
|
192 |
+
|
193 |
+
if( ! $this->has_active_relationship_condition ) {
|
194 |
+
$this->add( $this->has_active_relationship() );
|
195 |
+
}
|
196 |
+
}
|
197 |
+
|
198 |
+
|
199 |
+
/**
|
200 |
+
* Prevent the query from adding any default conditions. WYSIWYG.
|
201 |
+
*
|
202 |
+
* @return $this
|
203 |
+
*/
|
204 |
+
public function do_not_add_default_conditions() {
|
205 |
+
$this->should_add_default_conditions = false;
|
206 |
+
return $this;
|
207 |
+
}
|
208 |
+
|
209 |
+
|
210 |
+
/**
|
211 |
+
* @return IToolset_Association_Query_Condition MySQL WHERE clause for the query.
|
212 |
+
*/
|
213 |
+
private function build_root_condition() {
|
214 |
+
$this->add_default_conditions();
|
215 |
+
return $this->condition_factory->do_and( $this->conditions );
|
216 |
+
}
|
217 |
+
|
218 |
+
|
219 |
+
/**
|
220 |
+
* Build a complete MySQL query from the conditions.
|
221 |
+
*
|
222 |
+
* @return string
|
223 |
+
* @throws RuntimeException If no query limit is set.
|
224 |
+
*/
|
225 |
+
private function build_sql_query() {
|
226 |
+
$root_condition = $this->build_root_condition();
|
227 |
+
$this->maybe_add_restrictions( $root_condition );
|
228 |
+
|
229 |
+
if( null === $this->orderby ) {
|
230 |
+
$this->dont_order();
|
231 |
+
}
|
232 |
+
|
233 |
+
$this->orderby->set_order( $this->order );
|
234 |
+
|
235 |
+
if( null === $this->limit ) {
|
236 |
+
throw new RuntimeException(
|
237 |
+
'The query limit has not been set. This is necessary to ensure the scalability.'
|
238 |
+
);
|
239 |
+
}
|
240 |
+
|
241 |
+
return $this->expression_builder->build(
|
242 |
+
$root_condition,
|
243 |
+
$this->offset,
|
244 |
+
$this->limit,
|
245 |
+
$this->orderby,
|
246 |
+
$this->element_selector_provider->get_selector(),
|
247 |
+
$this->need_found_rows,
|
248 |
+
$this->result_transformation
|
249 |
+
);
|
250 |
+
}
|
251 |
+
|
252 |
+
|
253 |
+
|
254 |
+
/**
|
255 |
+
* Apply stored conditions and perform the query.
|
256 |
+
*
|
257 |
+
* @return IToolset_Association[]|int[]|IToolset_Element[]
|
258 |
+
*/
|
259 |
+
public function get_results() {
|
260 |
+
|
261 |
+
if( $this->was_used ) {
|
262 |
+
_doing_it_wrong(
|
263 |
+
__FUNCTION__,
|
264 |
+
'The association query object should not be reused. Create a new instance if you need to run another query.',
|
265 |
+
TOOLSET_COMMON_VERSION
|
266 |
+
);
|
267 |
+
}
|
268 |
+
|
269 |
+
$this->was_used = true;
|
270 |
+
|
271 |
+
// Default value if no result transformation was selected.
|
272 |
+
if( null === $this->result_transformation ) {
|
273 |
+
$this->return_association_instances();
|
274 |
+
}
|
275 |
+
|
276 |
+
$this->apply_restrictions();
|
277 |
+
|
278 |
+
// We do this only after restrictions have been applied.
|
279 |
+
$this->element_selector_provider->create_selector(
|
280 |
+
$this->unique_table_alias, $this->join_manager, $this
|
281 |
+
);
|
282 |
+
|
283 |
+
$query = $this->build_sql_query();
|
284 |
+
$rows = toolset_ensarr( $this->wpdb->get_results( $query ) );
|
285 |
+
|
286 |
+
if( $this->need_found_rows ) {
|
287 |
+
$this->found_rows = (int) $this->wpdb->get_var( 'SELECT FOUND_ROWS()' );
|
288 |
+
}
|
289 |
+
|
290 |
+
$results = array();
|
291 |
+
foreach( $rows as $row ) {
|
292 |
+
$result = $this->result_transformation->transform( $row, $this->element_selector_provider->get_selector() );
|
293 |
+
|
294 |
+
if ( null !== $result ) {
|
295 |
+
$results[] = $result;
|
296 |
+
}
|
297 |
+
}
|
298 |
+
|
299 |
+
$this->clear_restrictions();
|
300 |
+
|
301 |
+
return $results;
|
302 |
+
}
|
303 |
+
|
304 |
+
|
305 |
+
|
306 |
+
/**
|
307 |
+
* Chain multiple conditions with OR.
|
308 |
+
*
|
309 |
+
* The whole statement will evaluate to true if at least one of provided conditions is true.
|
310 |
+
*
|
311 |
+
* @param IToolset_Association_Query_Condition[] [$condition1, $condition2, ...]
|
312 |
+
* @return IToolset_Association_Query_Condition
|
313 |
+
*/
|
314 |
+
public function do_or() {
|
315 |
+
return $this->condition_factory->do_or( func_get_args() );
|
316 |
+
}
|
317 |
+
|
318 |
+
|
319 |
+
/**
|
320 |
+
* Chain multiple conditions with AND.
|
321 |
+
*
|
322 |
+
* The whole statement will evaluate to true if all provided conditions are true.
|
323 |
+
*
|
324 |
+
* @param IToolset_Association_Query_Condition[] [$condition1, $condition2, ...]
|
325 |
+
* @return IToolset_Association_Query_Condition
|
326 |
+
*/
|
327 |
+
public function do_and() {
|
328 |
+
return $this->condition_factory->do_and( func_get_args() );
|
329 |
+
}
|
330 |
+
|
331 |
+
|
332 |
+
/**
|
333 |
+
* Choose a query condition depending on a boolean expression.
|
334 |
+
*
|
335 |
+
* @param bool $statement A boolean condition statement.
|
336 |
+
* @param IToolset_Association_Query_Condition $if_branch Query condition that will be used
|
337 |
+
* if the statement is true.
|
338 |
+
* @param IToolset_Association_Query_Condition|null $else_branch Query condition that will be
|
339 |
+
* used if the statement is false. If none is provided, a tautology is used (always true).
|
340 |
+
*
|
341 |
+
* @return IToolset_Association_Query_Condition
|
342 |
+
* @since 2.5.6
|
343 |
+
*/
|
344 |
+
public function do_if(
|
345 |
+
$statement,
|
346 |
+
IToolset_Association_Query_Condition $if_branch,
|
347 |
+
IToolset_Association_Query_Condition $else_branch = null
|
348 |
+
) {
|
349 |
+
if( $statement ) {
|
350 |
+
return $if_branch;
|
351 |
+
} elseif( null !== $else_branch ) {
|
352 |
+
return $else_branch;
|
353 |
+
} else {
|
354 |
+
return $this->condition_factory->tautology();
|
355 |
+
}
|
356 |
+
}
|
357 |
+
|
358 |
+
|
359 |
+
/**
|
360 |
+
* Query by a row ID of a relationship definition.
|
361 |
+
*
|
362 |
+
* @param int $relationship_id
|
363 |
+
* @return IToolset_Association_Query_Condition
|
364 |
+
*/
|
365 |
+
public function relationship_id( $relationship_id ) {
|
366 |
+
return $this->condition_factory->relationship_id( $relationship_id );
|
367 |
+
}
|
368 |
+
|
369 |
+
|
370 |
+
/**
|
371 |
+
* Query by a relationship definition.
|
372 |
+
*
|
373 |
+
* @param IToolset_Relationship_Definition $relationship_definition
|
374 |
+
* @return IToolset_Association_Query_Condition
|
375 |
+
*/
|
376 |
+
public function relationship( IToolset_Relationship_Definition $relationship_definition ) {
|
377 |
+
return $this->relationship_id( $relationship_definition->get_row_id() );
|
378 |
+
}
|
379 |
+
|
380 |
+
|
381 |
+
/**
|
382 |
+
* Query by a relationship definition slug.
|
383 |
+
*
|
384 |
+
* @param string $slug
|
385 |
+
* @return IToolset_Association_Query_Condition
|
386 |
+
*/
|
387 |
+
public function relationship_slug( $slug ) {
|
388 |
+
$definition = $this->get_definition_repository()->get_definition( $slug );
|
389 |
+
if( null === $definition ) {
|
390 |
+
return $this->condition_factory->contradiction();
|
391 |
+
}
|
392 |
+
|
393 |
+
return $this->relationship( $definition );
|
394 |
+
}
|
395 |
+
|
396 |
+
|
397 |
+
/**
|
398 |
+
* @return Toolset_Relationship_Definition_Repository
|
399 |
+
*/
|
400 |
+
private function get_definition_repository() {
|
401 |
+
if( null === $this->_definition_repository ) {
|
402 |
+
$this->_definition_repository = Toolset_Relationship_Definition_Repository::get_instance();
|
403 |
+
}
|
404 |
+
|
405 |
+
return $this->_definition_repository;
|
406 |
+
}
|
407 |
+
|
408 |
+
|
409 |
+
/**
|
410 |
+
* Query by an ID of an element in the selected role.
|
411 |
+
*
|
412 |
+
* Warning: This is an WPML-unaware query.
|
413 |
+
*
|
414 |
+
* @param int $element_id
|
415 |
+
* @param IToolset_Relationship_Role_Parent_Child $for_role
|
416 |
+
* @param bool $need_wpml_unaware_query Set this to true to avoid a _doing_it_wrong notice.
|
417 |
+
*
|
418 |
+
* @return IToolset_Association_Query_Condition
|
419 |
+
*/
|
420 |
+
public function element_id(
|
421 |
+
$element_id, IToolset_Relationship_Role_Parent_Child $for_role, $need_wpml_unaware_query = true
|
422 |
+
) {
|
423 |
+
if( ! $need_wpml_unaware_query ) {
|
424 |
+
// This is to ensure a smooth transition from using element_id() everywhere to doing it only
|
425 |
+
// in cases where it's explicitly needed. We can remove this after the final release.
|
426 |
+
trigger_error(
|
427 |
+
'You are using the element_id() condition in the association query. '
|
428 |
+
. 'However, this condition is WPML-unaware. Consider using element_id_and_domain() instead '
|
429 |
+
.'or, if you really need to ignore element translations, set the new $need_wpml_unaware_query to true.',
|
430 |
+
E_NOTICE
|
431 |
+
);
|
432 |
+
}
|
433 |
+
return $this->condition_factory->element_id( $element_id, $for_role, $this->element_selector_provider );
|
434 |
+
}
|
435 |
+
|
436 |
+
|
437 |
+
/**
|
438 |
+
* Query by an ID of an element in the selected role.
|
439 |
+
*
|
440 |
+
* @param int $element_id
|
441 |
+
* @param string $domain
|
442 |
+
* @param IToolset_Relationship_Role $for_role
|
443 |
+
* @param bool $query_original_element If true, the query will check the element ID in the original language
|
444 |
+
* as stored in the association table. Default is false.
|
445 |
+
* @param bool $translate_provided_id If true, this will try to translate the element ID (if
|
446 |
+
* applicable on the domain) and use the translated one in the final condition. Default is true.
|
447 |
+
*
|
448 |
+
* @return Toolset_Association_Query_Condition_Element_Id_And_Domain
|
449 |
+
* @since 2.5.10
|
450 |
+
*/
|
451 |
+
public function element_id_and_domain(
|
452 |
+
$element_id,
|
453 |
+
$domain,
|
454 |
+
IToolset_Relationship_Role $for_role,
|
455 |
+
$query_original_element = false,
|
456 |
+
$translate_provided_id = true
|
457 |
+
) {
|
458 |
+
return $this->condition_factory->element_id_and_domain(
|
459 |
+
$element_id,
|
460 |
+
$domain,
|
461 |
+
$for_role,
|
462 |
+
$this->element_selector_provider,
|
463 |
+
$query_original_element,
|
464 |
+
$translate_provided_id
|
465 |
+
);
|
466 |
+
}
|
467 |
+
|
468 |
+
|
469 |
+
/**
|
470 |
+
* Query by an element in the selected role.
|
471 |
+
*
|
472 |
+
* @param IToolset_Element $element
|
473 |
+
* @param IToolset_Relationship_Role|null $for_role If null is provided, the query will involve all roles.
|
474 |
+
* @param bool $query_original_element If true, the query will check the element ID in the original language
|
475 |
+
* as stored in the association table. Default is false.
|
476 |
+
* @param bool $translate_provided_id If true, this will try to translate the element ID (if
|
477 |
+
* applicable on the domain) and use the translated one in the final condition. Default is true.
|
478 |
+
*
|
479 |
+
* @return IToolset_Association_Query_Condition
|
480 |
+
*/
|
481 |
+
public function element(
|
482 |
+
IToolset_Element $element,
|
483 |
+
IToolset_Relationship_Role $for_role = null,
|
484 |
+
$query_original_element = false,
|
485 |
+
$translate_provided_id = true
|
486 |
+
) {
|
487 |
+
|
488 |
+
if( null === $for_role ) {
|
489 |
+
$conditions = array();
|
490 |
+
foreach( Toolset_Relationship_Role::all() as $role ) {
|
491 |
+
$conditions[] = $this->element(
|
492 |
+
$element, $role, $query_original_element, $translate_provided_id
|
493 |
+
);
|
494 |
+
}
|
495 |
+
return $this->do_or( $conditions );
|
496 |
+
}
|
497 |
+
|
498 |
+
return $this->element_id_and_domain(
|
499 |
+
$element->get_id(), $element->get_domain(), $for_role,
|
500 |
+
$query_original_element, $translate_provided_id
|
501 |
+
);
|
502 |
+
}
|
503 |
+
|
504 |
+
|
505 |
+
/**
|
506 |
+
* Exclude associations with a particular element in the selected role.
|
507 |
+
*
|
508 |
+
* @param IToolset_Element $element
|
509 |
+
* @param IToolset_Relationship_Role $for_role
|
510 |
+
* @param bool $query_original_element If true, the query will check the element ID in the original language
|
511 |
+
* as stored in the association table. Default is false.
|
512 |
+
* @param bool $translate_provided_id If true, this will try to translate the element ID (if
|
513 |
+
* applicable on the domain) and use the translated one in the final condition. Default is true.
|
514 |
+
*
|
515 |
+
* @return IToolset_Association_Query_Condition
|
516 |
+
*/
|
517 |
+
public function exclude_element(
|
518 |
+
IToolset_Element $element,
|
519 |
+
IToolset_Relationship_Role $for_role,
|
520 |
+
$query_original_element = false,
|
521 |
+
$translate_provided_id = true
|
522 |
+
) {
|
523 |
+
return $this->condition_factory->exclude_element(
|
524 |
+
$element->get_id(), $element->get_domain(), $for_role,
|
525 |
+
$this->element_selector_provider,
|
526 |
+
$query_original_element, $translate_provided_id
|
527 |
+
);
|
528 |
+
}
|
529 |
+
|
530 |
+
|
531 |
+
/**
|
532 |
+
* Query by a parent element.
|
533 |
+
*
|
534 |
+
* @param IToolset_Element $element_source
|
535 |
+
* @return IToolset_Association_Query_Condition
|
536 |
+
*/
|
537 |
+
public function parent( IToolset_Element $element_source ) {
|
538 |
+
return $this->element( $element_source, new Toolset_Relationship_Role_Parent() );
|
539 |
+
}
|
540 |
+
|
541 |
+
|
542 |
+
/**
|
543 |
+
* Query by a parent element ID.
|
544 |
+
*
|
545 |
+
* @param int $parent_id
|
546 |
+
* @param string $domain
|
547 |
+
*
|
548 |
+
* @return IToolset_Association_Query_Condition
|
549 |
+
*/
|
550 |
+
public function parent_id( $parent_id, $domain = Toolset_Element_Domain::POSTS ) {
|
551 |
+
return $this->element_id_and_domain( $parent_id, $domain, new Toolset_Relationship_Role_Parent() );
|
552 |
+
}
|
553 |
+
|
554 |
+
|
555 |
+
/**
|
556 |
+
* Query by a child element.
|
557 |
+
*
|
558 |
+
* @param IToolset_Element $element
|
559 |
+
* @return IToolset_Association_Query_Condition
|
560 |
+
*/
|
561 |
+
public function child( IToolset_Element $element ) {
|
562 |
+
return $this->element( $element, new Toolset_Relationship_Role_Child() );
|
563 |
+
}
|
564 |
+
|
565 |
+
|
566 |
+
/**
|
567 |
+
* Query by a child element ID.
|
568 |
+
*
|
569 |
+
* @param int $child_id
|
570 |
+
* @param string $domain
|
571 |
+
*
|
572 |
+
* @return IToolset_Association_Query_Condition
|
573 |
+
*/
|
574 |
+
public function child_id( $child_id, $domain = Toolset_Element_Domain::POSTS ) {
|
575 |
+
return $this->element_id_and_domain( $child_id, $domain, new Toolset_Relationship_Role_Child() );
|
576 |
+
}
|
577 |
+
|
578 |
+
|
579 |
+
/**
|
580 |
+
* Query by an element status.
|
581 |
+
*
|
582 |
+
* @param string $status 'any'|'is_available'|'is_public'. Meaning of these options
|
583 |
+
* is domain-dependant.
|
584 |
+
* @param IToolset_Relationship_Role $for_role
|
585 |
+
*
|
586 |
+
* @return IToolset_Association_Query_Condition
|
587 |
+
*/
|
588 |
+
public function element_status( $status, IToolset_Relationship_Role $for_role ) {
|
589 |
+
$this->has_element_status_condition = true;
|
590 |
+
|
591 |
+
return $this->condition_factory->element_status(
|
592 |
+
$status, $for_role, $this->join_manager, $this->element_selector_provider
|
593 |
+
);
|
594 |
+
}
|
595 |
+
|
596 |
+
|
597 |
+
/**
|
598 |
+
* Query only associations that have both elements available (see element_status()).
|
599 |
+
*
|
600 |
+
* @return IToolset_Association_Query_Condition
|
601 |
+
*/
|
602 |
+
public function has_available_elements() {
|
603 |
+
$conditions = array();
|
604 |
+
|
605 |
+
foreach( Toolset_Relationship_Role::parent_child() as $role ) {
|
606 |
+
$conditions[] = $this->element_status(
|
607 |
+
Toolset_Association_Query_Condition_Element_Status::STATUS_AVAILABLE,
|
608 |
+
$role
|
609 |
+
);
|
610 |
+
}
|
611 |
+
|
612 |
+
return $this->do_and( $conditions );
|
613 |
+
}
|
614 |
+
|
615 |
+
|
616 |
+
/**
|
617 |
+
* Query associations by the activity status of the relationship.
|
618 |
+
*
|
619 |
+
* @param bool $is_active
|
620 |
+
*
|
621 |
+
* @return IToolset_Association_Query_Condition
|
622 |
+
*/
|
623 |
+
public function has_active_relationship( $is_active = true ) {
|
624 |
+
$this->has_active_relationship_condition = true;
|
625 |
+
return $this->condition_factory->has_active_relationship( $is_active, $this->join_manager );
|
626 |
+
}
|
627 |
+
|
628 |
+
|
629 |
+
/**
|
630 |
+
* Query associations by the fact whether the relationship was migrated from the legacy implementation.
|
631 |
+
*
|
632 |
+
* @param bool $needs_legacy_support
|
633 |
+
*
|
634 |
+
* @return IToolset_Association_Query_Condition
|
635 |
+
*/
|
636 |
+
public function has_legacy_relationship( $needs_legacy_support = true ) {
|
637 |
+
return $this->condition_factory->has_legacy_relationship( $needs_legacy_support, $this->join_manager );
|
638 |
+
}
|
639 |
+
|
640 |
+
|
641 |
+
/**
|
642 |
+
* Query associations by the element domain on a specified role.
|
643 |
+
*
|
644 |
+
* @param string $domain
|
645 |
+
* @param IToolset_Relationship_Role_Parent_Child $for_role
|
646 |
+
*
|
647 |
+
* @return IToolset_Association_Query_Condition
|
648 |
+
*/
|
649 |
+
public function has_domain( $domain, IToolset_Relationship_Role_Parent_Child $for_role ) {
|
650 |
+
return $this->condition_factory->has_domain( $domain, $for_role, $this->join_manager );
|
651 |
+
}
|
652 |
+
|
653 |
+
|
654 |
+
/**
|
655 |
+
* Query associations based on element type.
|
656 |
+
*
|
657 |
+
* Warning: This doesn't query for the domain. Make sure you at least add
|
658 |
+
* a separate element domain condition. Otherwise, the results will be unpredictable.
|
659 |
+
*
|
660 |
+
* The best way is to use the has_domain_and_type() condition instead, which whill allow
|
661 |
+
* for some more advanced optimizations.
|
662 |
+
*
|
663 |
+
* @param string $type Element type.
|
664 |
+
* @param IToolset_Relationship_Role_Parent_Child $for_role
|
665 |
+
*
|
666 |
+
* @return IToolset_Association_Query_Condition
|
667 |
+
*/
|
668 |
+
public function has_type( $type, IToolset_Relationship_Role_Parent_Child $for_role ) {
|
669 |
+
return $this->condition_factory->has_type( $type, $for_role, $this->join_manager, $this->unique_table_alias );
|
670 |
+
}
|
671 |
+
|
672 |
+
|
673 |
+
/**
|
674 |
+
* Query associations based on element domain and type.
|
675 |
+
*
|
676 |
+
* @param string $domain Element domain.
|
677 |
+
* @param string $type Element type
|
678 |
+
* @param IToolset_Relationship_Role_Parent_Child $for_role
|
679 |
+
*
|
680 |
+
* @return IToolset_Association_Query_Condition
|
681 |
+
*/
|
682 |
+
public function has_domain_and_type( $domain, $type, IToolset_Relationship_Role_Parent_Child $for_role ) {
|
683 |
+
return $this->condition_factory->has_domain_and_type(
|
684 |
+
$domain, $type, $for_role, $this->join_manager, $this->unique_table_alias
|
685 |
+
);
|
686 |
+
}
|
687 |
+
|
688 |
+
|
689 |
+
/**
|
690 |
+
* Query by a WP_Query arguments applied on an element of a specified role.
|
691 |
+
*
|
692 |
+
* WARNING: It is important that you read the documentation of Toolset_Association_Query_Condition_Wp_Query
|
693 |
+
* before using this.
|
694 |
+
*
|
695 |
+
* @param IToolset_Relationship_Role $for_role
|
696 |
+
* @param array $query_args
|
697 |
+
* @param string|null $confirmation 'i_know_what_i_am_doing'
|
698 |
+
*
|
699 |
+
* @return IToolset_Association_Query_Condition
|
700 |
+
*
|
701 |
+
* @throws InvalidArgumentException Thrown if you don't know what you are doing.
|
702 |
+
*/
|
703 |
+
public function wp_query( IToolset_Relationship_Role $for_role, $query_args, $confirmation = null ) {
|
704 |
+
if( 'i_know_what_i_am_doing' !== $confirmation ) {
|
705 |
+
throw new InvalidArgumentException();
|
706 |
+
}
|
707 |
+
return $this->condition_factory->wp_query( $for_role, $query_args, $this->join_manager, $this->unique_table_alias );
|
708 |
+
}
|
709 |
+
|
710 |
+
|
711 |
+
/**
|
712 |
+
* Query by a string search in elements of a selected role.
|
713 |
+
*
|
714 |
+
* Note that the behaviour may be different per domain.
|
715 |
+
*
|
716 |
+
* @param string $search_string
|
717 |
+
* @param IToolset_Relationship_Role $for_role
|
718 |
+
* @param bool $is_exact
|
719 |
+
*
|
720 |
+
* @return IToolset_Association_Query_Condition
|
721 |
+
*/
|
722 |
+
public function search( $search_string, IToolset_Relationship_Role $for_role, $is_exact = false ) {
|
723 |
+
return $this->condition_factory->search( $search_string, $is_exact, $for_role, $this->join_manager );
|
724 |
+
}
|
725 |
+
|
726 |
+
|
727 |
+
/**
|
728 |
+
* Query by a specific association ID.
|
729 |
+
*
|
730 |
+
* This will also set the limit of the result count to one.
|
731 |
+
*
|
732 |
+
* @param int $association_id
|
733 |
+
*
|
734 |
+
* @return IToolset_Association_Query_Condition
|
735 |
+
*/
|
736 |
+
public function association_id( $association_id ) {
|
737 |
+
$this->limit( 1 );
|
738 |
+
return $this->condition_factory->association_id( $association_id );
|
739 |
+
}
|
740 |
+
|
741 |
+
|
742 |
+
public function meta( $meta_key, $meta_value, $domain, IToolset_Relationship_Role $for_role = null, $comparison = Toolset_Query_Comparison_Operator::EQUALS ) {
|
743 |
+
if( Toolset_Element_Domain::POSTS !== $domain ) {
|
744 |
+
throw new RuntimeException( 'The meta query condition is supported only for the posts domain at the moment.' );
|
745 |
+
}
|
746 |
+
|
747 |
+
if( null === $for_role ) {
|
748 |
+
$queries_per_role = array();
|
749 |
+
foreach( Toolset_Relationship_Role::all() as $role ) {
|
750 |
+
$queries_per_role[] = $this->meta( $meta_key, $meta_value, $domain, $role, $comparison );
|
751 |
+
}
|
752 |
+
return $this->condition_factory->do_and( $queries_per_role );
|
753 |
+
}
|
754 |
+
|
755 |
+
return $this->condition_factory->postmeta( $meta_key, $meta_value, $comparison, $for_role, $this->join_manager );
|
756 |
+
}
|
757 |
+
|
758 |
+
|
759 |
+
/**
|
760 |
+
* Indicate that get_results() should return instances of IToolset_Association.
|
761 |
+
*
|
762 |
+
* @return $this
|
763 |
+
*/
|
764 |
+
public function return_association_instances() {
|
765 |
+
$this->result_transformation = new Toolset_Association_Query_Result_Transformation_Association_Instance();
|
766 |
+
return $this;
|
767 |
+
}
|
768 |
+
|
769 |
+
|
770 |
+
/**
|
771 |
+
* Indicate that get_results() should return UIDs of associations.
|
772 |
+
*
|
773 |
+
* @return $this
|
774 |
+
*/
|
775 |
+
public function return_association_uids() {
|
776 |
+
$this->result_transformation = new Toolset_Association_Query_Result_Transformation_Association_Uid();
|
777 |
+
return $this;
|
778 |
+
}
|
779 |
+
|
780 |
+
|
781 |
+
/**
|
782 |
+
* Indicate that get_results() should return element IDs from a selected role.
|
783 |
+
*
|
784 |
+
* @param IToolset_Relationship_Role $role
|
785 |
+
* @return $this
|
786 |
+
*/
|
787 |
+
public function return_element_ids( IToolset_Relationship_Role $role ) {
|
788 |
+
$this->result_transformation = new Toolset_Association_Query_Result_Transformation_Element_Id( $role );
|
789 |
+
return $this;
|
790 |
+
}
|
791 |
+
|
792 |
+
|
793 |
+
/**
|
794 |
+
* Indicate that get_results() should return IToolset_Element instances from a selected role.
|
795 |
+
*
|
796 |
+
* @param IToolset_Relationship_Role $role
|
797 |
+
* @return $this
|
798 |
+
*/
|
799 |
+
public function return_element_instances( IToolset_Relationship_Role $role ) {
|
800 |
+
$this->result_transformation = new Toolset_Association_Query_Result_Transformation_Element_Instance( $role );
|
801 |
+
return $this;
|
802 |
+
}
|
803 |
+
|
804 |
+
|
805 |
+
/**
|
806 |
+
* Set an offset for the query.
|
807 |
+
*
|
808 |
+
* @param int $value
|
809 |
+
*
|
810 |
+
* @return $this
|
811 |
+
* @throws InvalidArgumentException Thrown if an invalid value is provided.
|
812 |
+
*/
|
813 |
+
public function offset( $value ) {
|
814 |
+
if( ! Toolset_Utils::is_nonnegative_numeric( $value ) ) {
|
815 |
+
throw new InvalidArgumentException( 'Invalid offset value.' );
|
816 |
+
}
|
817 |
+
$this->offset = (int) $value;
|
818 |
+
return $this;
|
819 |
+
}
|
820 |
+
|
821 |
+
|
822 |
+
/**
|
823 |
+
* Limit a number of results for the query.
|
824 |
+
*
|
825 |
+
* Note that by default, the limit is set at a certain value, and the query can never be unlimited.
|
826 |
+
*
|
827 |
+
* @param int $value
|
828 |
+
* @return $this
|
829 |
+
* @throws InvalidArgumentException Thrown if an invalid value is provided.
|
830 |
+
*/
|
831 |
+
public function limit( $value ) {
|
832 |
+
if( ! Toolset_Utils::is_natural_numeric( $value ) ) {
|
833 |
+
throw new InvalidArgumentException( 'Invalid limit value.' );
|
834 |
+
}
|
835 |
+
$this->limit = (int) $value;
|
836 |
+
return $this;
|
837 |
+
}
|
838 |
+
|
839 |
+
|
840 |
+
/**
|
841 |
+
* Set the sorting order.
|
842 |
+
*
|
843 |
+
* @param string $value 'ASC'|'DESC'
|
844 |
+
* @return $this
|
845 |
+
*/
|
846 |
+
public function order( $value ) {
|
847 |
+
$this->order = $value;
|
848 |
+
return $this;
|
849 |
+
}
|
850 |
+
|
851 |
+
|
852 |
+
/**
|
853 |
+
* Indicate whether the query should also retrieve the total number of results.
|
854 |
+
*
|
855 |
+
* This is required for get_found_rows() to work.
|
856 |
+
*
|
857 |
+
* @param bool $is_needed
|
858 |
+
* @return $this
|
859 |
+
*/
|
860 |
+
public function need_found_rows( $is_needed = true ) {
|
861 |
+
$this->need_found_rows = (bool) $is_needed;
|
862 |
+
return $this;
|
863 |
+
}
|
864 |
+
|
865 |
+
|
866 |
+
/**
|
867 |
+
* Return the total number of found results after get_results() was called.
|
868 |
+
*
|
869 |
+
* For this to work, need_found_rows() needs to be called when building the query.
|
870 |
+
*
|
871 |
+
* @return int
|
872 |
+
* @throws RuntimeException
|
873 |
+
*/
|
874 |
+
public function get_found_rows() {
|
875 |
+
if( null === $this->found_rows ) {
|
876 |
+
throw new RuntimeException(
|
877 |
+
'Cannot return the number of found rows because the query was not instructed to obtain them.'
|
878 |
+
);
|
879 |
+
}
|
880 |
+
|
881 |
+
return $this->found_rows;
|
882 |
+
}
|
883 |
+
|
884 |
+
|
885 |
+
/**
|
886 |
+
* Indicate that no result ordering is needed.
|
887 |
+
*
|
888 |
+
* @return $this
|
889 |
+
*/
|
890 |
+
public function dont_order() {
|
891 |
+
$this->orderby = $this->orderby_factory->nothing();
|
892 |
+
return $this;
|
893 |
+
}
|
894 |
+
|
895 |
+
|
896 |
+
/**
|
897 |
+
* Order results by a title of element of given role.
|
898 |
+
*
|
899 |
+
* Note that ordering by intermediary posts will cause the associations without those to be excluded from results.
|
900 |
+
*
|
901 |
+
* @param IToolset_Relationship_Role $for_role
|
902 |
+
* @return $this
|
903 |
+
*/
|
904 |
+
public function order_by_title( IToolset_Relationship_Role $for_role ) {
|
905 |
+
$this->orderby = $this->orderby_factory->title( $for_role, $this->join_manager );
|
906 |
+
return $this;
|
907 |
+
}
|
908 |
+
|
909 |
+
|
910 |
+
/**
|
911 |
+
* Order results by a value of a certain custom field on a selected element role.
|
912 |
+
*
|
913 |
+
* @param Toolset_Field_Definition $field_definition
|
914 |
+
* @param IToolset_Relationship_Role $for_role
|
915 |
+
*
|
916 |
+
* @return $this
|
917 |
+
* @throws RuntimeException Thrown if the element domain is not supported.
|
918 |
+
*/
|
919 |
+
public function order_by_field_value( Toolset_Field_Definition $field_definition, IToolset_Relationship_Role $for_role ) {
|
920 |
+
switch( $field_definition->get_domain() ) {
|
921 |
+
case Toolset_Element_Domain::POSTS:
|
922 |
+
$cast_to_numeric = $field_definition->get_type() instanceof Toolset_Field_Type_Definition_Numeric
|
923 |
+
? 'SIGNED'
|
924 |
+
: null;
|
925 |
+
$this->orderby = $this->orderby_factory->postmeta(
|
926 |
+
$field_definition->get_meta_key(),
|
927 |
+
$for_role,
|
928 |
+
$this->join_manager,
|
929 |
+
$cast_to_numeric
|
930 |
+
);
|
931 |
+
break;
|
932 |
+
default:
|
933 |
+
throw new RuntimeException( 'Element domain not supported.' );
|
934 |
+
}
|
935 |
+
|
936 |
+
return $this;
|
937 |
+
}
|
938 |
+
|
939 |
+
|
940 |
+
/**
|
941 |
+
* Order results by a value of the element metadata.
|
942 |
+
*
|
943 |
+
* @param string $meta_key Meta key that should be used for ordering.
|
944 |
+
* @param string $domain Valid element domain. At the moment, only posts are supported.
|
945 |
+
* @param IToolset_Relationship_Role $for_role Role of the element whose metadata should be used for ordering.
|
946 |
+
* @param bool $is_numeric If true, numeric ordering will be used.
|
947 |
+
*
|
948 |
+
* @return $this
|
949 |
+
* @since 2.6.1
|
950 |
+
* @throws RuntimeException If unsupported element domain is used.
|
951 |
+
* @throws InvalidArgumentException
|
952 |
+
*/
|
953 |
+
public function order_by_meta( $meta_key, $domain, IToolset_Relationship_Role $for_role, $is_numeric = false ) {
|
954 |
+
if( Toolset_Element_Domain::POSTS !== $domain ) {
|
955 |
+
throw new RuntimeException( 'Element domain not supported.' );
|
956 |
+
}
|
957 |
+
|
958 |
+
$cast_to = ( $is_numeric ? 'SIGNED' : null );
|
959 |
+
|
960 |
+
$this->orderby = $this->orderby_factory->postmeta( $meta_key, $for_role, $this->join_manager, $cast_to );
|
961 |
+
|
962 |
+
return $this;
|
963 |
+
}
|
964 |
+
|
965 |
+
|
966 |
+
private function apply_restrictions() {
|
967 |
+
foreach( $this->restrictions as $restriction ) {
|
968 |
+
$restriction->apply();
|
969 |
+
}
|
970 |
+
}
|
971 |
+
|
972 |
+
|
973 |
+
private function clear_restrictions() {
|
974 |
+
foreach( $this->restrictions as $restriction ) {
|
975 |
+
$restriction->clear();
|
976 |
+
}
|
977 |
+
}
|
978 |
+
|
979 |
+
|
980 |
+
/**
|
981 |
+
* Perform the query to only return the number of found rows, if we're not interested in
|
982 |
+
* the actual results.
|
983 |
+
*
|
984 |
+
* @return int Number of results matching the query.
|
985 |
+
*/
|
986 |
+
public function get_found_rows_directly() {
|
987 |
+
$this->need_found_rows()
|
988 |
+
->limit( 1 )
|
989 |
+
->return_association_uids()
|
990 |
+
->get_results();
|
991 |
+
|
992 |
+
return $this->get_found_rows();
|
993 |
+
}
|
994 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/association/query/condition/abstract.php
ADDED
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Condition for the Toolset_Association_Query_V2.
|
5 |
+
*
|
6 |
+
* Provides a wpdb instance to all its subclasses.
|
7 |
+
*
|
8 |
+
* @since 2.5.8
|
9 |
+
*/
|
10 |
+
abstract class Toolset_Association_Query_Condition implements IToolset_Association_Query_Condition {
|
11 |
+
|
12 |
+
|
13 |
+
/**
|
14 |
+
* By default, there is nothing to join.
|
15 |
+
*
|
16 |
+
* @return string
|
17 |
+
*/
|
18 |
+
public function get_join_clause() {
|
19 |
+
return '';
|
20 |
+
}
|
21 |
+
|
22 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/association/query/condition/association_id.php
ADDED
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Condition to query associations by a specific association ID.
|
5 |
+
*
|
6 |
+
* @since 2.5.8
|
7 |
+
*/
|
8 |
+
class Toolset_Association_Query_Condition_Association_Id extends Toolset_Association_Query_Condition {
|
9 |
+
|
10 |
+
|
11 |
+
/** @var int */
|
12 |
+
private $association_id;
|
13 |
+
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Toolset_Association_Query_Condition_Association_Id constructor.
|
17 |
+
*
|
18 |
+
* @param int $association_id
|
19 |
+
* @throws InvalidArgumentException
|
20 |
+
*/
|
21 |
+
public function __construct( $association_id ) {
|
22 |
+
if( ! Toolset_Utils::is_natural_numeric( $association_id ) ) {
|
23 |
+
throw new InvalidArgumentException( 'Invalid association ID.' );
|
24 |
+
}
|
25 |
+
|
26 |
+
$this->association_id = (int) $association_id;
|
27 |
+
}
|
28 |
+
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Get a part of the WHERE clause that applies the condition.
|
32 |
+
*
|
33 |
+
* @return string Valid part of a MySQL query, so that it can be
|
34 |
+
* used in WHERE ( $condition1 ) AND ( $condition2 ) AND ( $condition3 ) ...
|
35 |
+
*/
|
36 |
+
public function get_where_clause() {
|
37 |
+
return sprintf( 'associations.id = %d', $this->association_id );
|
38 |
+
}
|
39 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/association/query/condition/element_id.php
ADDED
@@ -0,0 +1,65 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Condition to query associations by a particular element involved in a particular role.
|
5 |
+
*
|
6 |
+
* Warning: This is not WPML-aware query. It simply compares the provided ID with the ID in
|
7 |
+
* the correct column in the associations table. In most cases, you will need the translation
|
8 |
+
* mechanism to be involved and use Toolset_Association_Query_Condition_Element_Id_And_Domain
|
9 |
+
* instead.
|
10 |
+
*
|
11 |
+
* @since 2.5.8
|
12 |
+
*/
|
13 |
+
class Toolset_Association_Query_Condition_Element_Id extends Toolset_Association_Query_Condition {
|
14 |
+
|
15 |
+
|
16 |
+
/** @var int */
|
17 |
+
private $element_id;
|
18 |
+
|
19 |
+
|
20 |
+
/** @var IToolset_Relationship_Role */
|
21 |
+
private $for_role;
|
22 |
+
|
23 |
+
|
24 |
+
/** @var Toolset_Association_Query_Element_Selector_Provider */
|
25 |
+
private $element_selector_provider;
|
26 |
+
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Toolset_Association_Query_Condition_Element_Id constructor.
|
30 |
+
*
|
31 |
+
* @param int $element_id
|
32 |
+
* @param IToolset_Relationship_Role $for_role
|
33 |
+
* @param Toolset_Association_Query_Element_Selector_Provider $element_selector_provider
|
34 |
+
* @throws InvalidArgumentException
|
35 |
+
*/
|
36 |
+
public function __construct(
|
37 |
+
$element_id,
|
38 |
+
IToolset_Relationship_Role $for_role,
|
39 |
+
Toolset_Association_Query_Element_Selector_Provider $element_selector_provider
|
40 |
+
) {
|
41 |
+
if( ! Toolset_Utils::is_nonnegative_integer( $element_id ) ) {
|
42 |
+
throw new InvalidArgumentException();
|
43 |
+
}
|
44 |
+
|
45 |
+
$this->element_id = (int) $element_id;
|
46 |
+
$this->for_role = $for_role;
|
47 |
+
$this->element_selector_provider = $element_selector_provider;
|
48 |
+
}
|
49 |
+
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Get a part of the WHERE clause that applies the condition.
|
53 |
+
*
|
54 |
+
* @return string Valid part of a MySQL query, so that it can be
|
55 |
+
* used in WHERE ( $condition1 ) AND ( $condition2 ) AND ( $condition3 ) ...
|
56 |
+
*/
|
57 |
+
public function get_where_clause() {
|
58 |
+
$column_name = $this->element_selector_provider
|
59 |
+
->get_selector()
|
60 |
+
->get_element_id_value( $this->for_role, false );
|
61 |
+
|
62 |
+
return sprintf( '%s = %d', $column_name, $this->element_id );
|
63 |
+
}
|
64 |
+
|
65 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/association/query/condition/element_id_and_domain.php
ADDED
@@ -0,0 +1,109 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Condition to query associations by a particular element involved in a particular role.
|
5 |
+
*
|
6 |
+
* @since 2.5.8
|
7 |
+
*/
|
8 |
+
class Toolset_Association_Query_Condition_Element_Id_And_Domain extends Toolset_Association_Query_Condition {
|
9 |
+
|
10 |
+
|
11 |
+
/** @var int */
|
12 |
+
private $element_id;
|
13 |
+
|
14 |
+
|
15 |
+
/** @var IToolset_Relationship_Role */
|
16 |
+
private $for_role;
|
17 |
+
|
18 |
+
|
19 |
+
/** @var Toolset_Association_Query_Element_Selector_Provider */
|
20 |
+
private $element_selector_provider;
|
21 |
+
|
22 |
+
|
23 |
+
/** @var bool */
|
24 |
+
private $translate_provided_id;
|
25 |
+
|
26 |
+
|
27 |
+
/** @var bool */
|
28 |
+
private $query_original_element;
|
29 |
+
|
30 |
+
|
31 |
+
/** @var string */
|
32 |
+
private $domain;
|
33 |
+
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Toolset_Association_Query_Condition_Element_Id constructor.
|
37 |
+
*
|
38 |
+
* @param int $element_id
|
39 |
+
* @param string $domain
|
40 |
+
* @param IToolset_Relationship_Role $for_role
|
41 |
+
* @param Toolset_Association_Query_Element_Selector_Provider $element_selector_provider
|
42 |
+
* @param $query_original_element
|
43 |
+
* @param $translate_provided_id
|
44 |
+
*/
|
45 |
+
public function __construct(
|
46 |
+
$element_id,
|
47 |
+
$domain,
|
48 |
+
IToolset_Relationship_Role $for_role,
|
49 |
+
Toolset_Association_Query_Element_Selector_Provider $element_selector_provider,
|
50 |
+
$query_original_element,
|
51 |
+
$translate_provided_id
|
52 |
+
) {
|
53 |
+
if(
|
54 |
+
! Toolset_Utils::is_nonnegative_integer( $element_id )
|
55 |
+
|| ! in_array( $domain, Toolset_Element_Domain::all(), true )
|
56 |
+
) {
|
57 |
+
throw new InvalidArgumentException();
|
58 |
+
}
|
59 |
+
|
60 |
+
if(
|
61 |
+
$for_role instanceof Toolset_Relationship_Role_Intermediary
|
62 |
+
&& Toolset_Element_Domain::POSTS !== $domain
|
63 |
+
) {
|
64 |
+
throw new InvalidArgumentException( 'Querying by an intermediary post with a wrong element domain.' );
|
65 |
+
}
|
66 |
+
|
67 |
+
$this->element_id = (int) $element_id;
|
68 |
+
$this->domain = $domain;
|
69 |
+
$this->for_role = $for_role;
|
70 |
+
$this->element_selector_provider = $element_selector_provider;
|
71 |
+
$this->translate_provided_id = (bool) $translate_provided_id;
|
72 |
+
$this->query_original_element = (bool) $query_original_element;
|
73 |
+
}
|
74 |
+
|
75 |
+
|
76 |
+
/**
|
77 |
+
* Get a part of the WHERE clause that applies the condition.
|
78 |
+
*
|
79 |
+
* @return string Valid part of a MySQL query, so that it can be
|
80 |
+
* used in WHERE ( $condition1 ) AND ( $condition2 ) AND ( $condition3 ) ...
|
81 |
+
*/
|
82 |
+
public function get_where_clause() {
|
83 |
+
$column_name = $this->element_selector_provider
|
84 |
+
->get_selector()
|
85 |
+
->get_element_id_value(
|
86 |
+
$this->for_role, ! $this->query_original_element
|
87 |
+
);
|
88 |
+
|
89 |
+
return sprintf(
|
90 |
+
'%s %s %d', $column_name, $this->get_operator(), $this->get_element_id_to_query()
|
91 |
+
);
|
92 |
+
}
|
93 |
+
|
94 |
+
|
95 |
+
private function get_element_id_to_query() {
|
96 |
+
if( Toolset_Element_Domain::POSTS === $this->domain && $this->translate_provided_id ) {
|
97 |
+
$element_id = apply_filters( 'wpml_object_id', $this->element_id, 'any', true );
|
98 |
+
return $element_id;
|
99 |
+
}
|
100 |
+
|
101 |
+
return $this->element_id;
|
102 |
+
}
|
103 |
+
|
104 |
+
|
105 |
+
protected function get_operator() {
|
106 |
+
return '=';
|
107 |
+
}
|
108 |
+
|
109 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/association/query/condition/element_status.php
ADDED
@@ -0,0 +1,118 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Condition to query associations by a status of an element in a particular role.
|
5 |
+
*
|
6 |
+
* Allows querying for a specific status or for a set of statuses that may be
|
7 |
+
* depending on other circumstances (e.g. capabilities of the current user).
|
8 |
+
*
|
9 |
+
* Note that the functionality may be different per each domain. Currently, only posts
|
10 |
+
* are supported.
|
11 |
+
*
|
12 |
+
* @since 2.5.8
|
13 |
+
*/
|
14 |
+
class Toolset_Association_Query_Condition_Element_Status extends Toolset_Association_Query_Condition {
|
15 |
+
|
16 |
+
const STATUS_AVAILABLE = 'is_available';
|
17 |
+
const STATUS_PUBLIC = 'is_public';
|
18 |
+
const STATUS_ANY = 'any';
|
19 |
+
|
20 |
+
|
21 |
+
/** @var string */
|
22 |
+
private $status;
|
23 |
+
|
24 |
+
|
25 |
+
/** @var IToolset_Relationship_Role */
|
26 |
+
private $for_role;
|
27 |
+
|
28 |
+
|
29 |
+
/** @var Toolset_Association_Query_Table_Join_Manager */
|
30 |
+
private $join_manager;
|
31 |
+
|
32 |
+
|
33 |
+
/** @var Toolset_Association_Query_Element_Selector_Provider */
|
34 |
+
private $element_selector_provider;
|
35 |
+
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Toolset_Association_Query_Condition_Element_Status constructor.
|
39 |
+
*
|
40 |
+
* @param string $status
|
41 |
+
* @param IToolset_Relationship_Role $for_role
|
42 |
+
* @param Toolset_Association_Query_Table_Join_Manager $join_manager
|
43 |
+
* @param Toolset_Association_Query_Element_Selector_Provider $element_selector_provider
|
44 |
+
* @throws InvalidArgumentException
|
45 |
+
*/
|
46 |
+
public function __construct(
|
47 |
+
$status,
|
48 |
+
IToolset_Relationship_Role $for_role,
|
49 |
+
Toolset_Association_Query_Table_Join_Manager $join_manager,
|
50 |
+
Toolset_Association_Query_Element_Selector_Provider $element_selector_provider
|
51 |
+
) {
|
52 |
+
if(
|
53 |
+
! is_string( $status ) || empty( $status )
|
54 |
+
) {
|
55 |
+
throw new InvalidArgumentException();
|
56 |
+
}
|
57 |
+
|
58 |
+
$this->status = $status;
|
59 |
+
$this->for_role = $for_role;
|
60 |
+
$this->join_manager = $join_manager;
|
61 |
+
$this->element_selector_provider = $element_selector_provider;
|
62 |
+
}
|
63 |
+
|
64 |
+
|
65 |
+
/**
|
66 |
+
* Get a part of the WHERE clause that applies the condition.
|
67 |
+
*
|
68 |
+
* @return string Valid part of a MySQL query, so that it can be
|
69 |
+
* used in WHERE ( $condition1 ) AND ( $condition2 ) AND ( $condition3 ) ...
|
70 |
+
*/
|
71 |
+
public function get_where_clause() {
|
72 |
+
return $this->get_where_clause_for_posts();
|
73 |
+
}
|
74 |
+
|
75 |
+
|
76 |
+
/**
|
77 |
+
* Get the WHERE clause if the domain is known to be posts.
|
78 |
+
*
|
79 |
+
* @return string
|
80 |
+
*/
|
81 |
+
private function get_where_clause_for_posts() {
|
82 |
+
|
83 |
+
$accepted_statuses = array();
|
84 |
+
|
85 |
+
switch( $this->status ) {
|
86 |
+
case self::STATUS_PUBLIC:
|
87 |
+
$accepted_statuses[] = 'publish';
|
88 |
+
break;
|
89 |
+
case self::STATUS_AVAILABLE:
|
90 |
+
$accepted_statuses[] = 'publish';
|
91 |
+
$accepted_statuses[] = 'draft';
|
92 |
+
// FIXME make the logic complete (involving WP_Query business logic and Access)
|
93 |
+
if( current_user_can( 'read_private_posts' ) ) {
|
94 |
+
$accepted_statuses[] = 'private';
|
95 |
+
}
|
96 |
+
break;
|
97 |
+
case self::STATUS_ANY:
|
98 |
+
// Match anything, don't bother with adding a query.
|
99 |
+
return ' 1 = 1 ';
|
100 |
+
default:
|
101 |
+
// Use the status value directly.
|
102 |
+
$accepted_statuses[] = $this->status;
|
103 |
+
}
|
104 |
+
|
105 |
+
if( empty( $accepted_statuses ) ) {
|
106 |
+
// For some reason, we don't allow any post status. Match nothing.
|
107 |
+
return ' 1 = 0 ';
|
108 |
+
}
|
109 |
+
|
110 |
+
$clause = sprintf(
|
111 |
+
' %s.post_status IN ( %s ) ',
|
112 |
+
$this->join_manager->wp_posts( $this->for_role ),
|
113 |
+
'\'' . implode( '\', \'', $accepted_statuses ) . '\''
|
114 |
+
);
|
115 |
+
|
116 |
+
return $clause;
|
117 |
+
}
|
118 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/association/query/condition/empty_intermediary.php
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Condition to query associations without intermediary post. Needed when fields are added and association have to be updated.
|
5 |
+
*
|
6 |
+
* @since 2.5.8
|
7 |
+
*/
|
8 |
+
class Toolset_Association_Query_Condition_Empty_Intermediary extends Toolset_Association_Query_Condition {
|
9 |
+
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Get a part of the WHERE clause that applies the condition.
|
13 |
+
*
|
14 |
+
* @return string Valid part of a MySQL query, so that it can be
|
15 |
+
* used in WHERE ( $condition1 ) AND ( $condition2 ) AND ( $condition3 ) ...
|
16 |
+
*/
|
17 |
+
public function get_where_clause() {
|
18 |
+
return 'associations.intermediary_id = 0';
|
19 |
+
}
|
20 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/association/query/condition/exclude_element.php
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Condition to exclude a particular element from the results.
|
5 |
+
*
|
6 |
+
* See the parent class for details.
|
7 |
+
*
|
8 |
+
* @since 2.5.10
|
9 |
+
*/
|
10 |
+
class Toolset_Association_Query_Condition_Exclude_Element extends Toolset_Association_Query_Condition_Element_Id_And_Domain {
|
11 |
+
|
12 |
+
protected function get_operator() {
|
13 |
+
return '!=';
|
14 |
+
}
|
15 |
+
|
16 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/association/query/condition/has_active_relationship.php
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Query associations by the is_active value of a relationship they belong to.
|
5 |
+
*
|
6 |
+
* @since 2.5.8
|
7 |
+
*/
|
8 |
+
class Toolset_Association_Query_Condition_Has_Active_Relationship extends Toolset_Association_Query_Condition_Relationship_Flag {
|
9 |
+
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @inheritdoc
|
13 |
+
* @return string
|
14 |
+
*/
|
15 |
+
protected function get_flag_name() {
|
16 |
+
return 'is_active';
|
17 |
+
}
|
18 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/association/query/condition/has_domain.php
ADDED
@@ -0,0 +1,86 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Query associations by the domain of selected role.
|
5 |
+
*
|
6 |
+
* @since 2.5.8
|
7 |
+
*/
|
8 |
+
class Toolset_Association_Query_Condition_Has_Domain extends Toolset_Association_Query_Condition {
|
9 |
+
|
10 |
+
|
11 |
+
/** @var Toolset_Association_Query_Table_Join_Manager */
|
12 |
+
private $join_manager;
|
13 |
+
|
14 |
+
|
15 |
+
/** @var IToolset_Relationship_Role_Parent_Child */
|
16 |
+
private $for_role;
|
17 |
+
|
18 |
+
|
19 |
+
/** @var string */
|
20 |
+
private $domain;
|
21 |
+
|
22 |
+
|
23 |
+
/** @var null|Toolset_Relationship_Database_Operations */
|
24 |
+
private $database_operations;
|
25 |
+
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Toolset_Association_Query_Condition_Has_Active_Relationship constructor.
|
29 |
+
*
|
30 |
+
* @param string $domain
|
31 |
+
* @param IToolset_Relationship_Role_Parent_Child $for_role
|
32 |
+
* @param Toolset_Association_Query_Table_Join_Manager $join_manager
|
33 |
+
* @param Toolset_Relationship_Database_Operations|null $database_operations_di
|
34 |
+
*/
|
35 |
+
public function __construct(
|
36 |
+
$domain,
|
37 |
+
IToolset_Relationship_Role_Parent_Child $for_role,
|
38 |
+
Toolset_Association_Query_Table_Join_Manager $join_manager,
|
39 |
+
Toolset_Relationship_Database_Operations $database_operations_di = null
|
40 |
+
) {
|
41 |
+
if( ! in_array( $domain, Toolset_Element_Domain::all(), true ) ) {
|
42 |
+
throw new InvalidArgumentException();
|
43 |
+
}
|
44 |
+
|
45 |
+
$this->domain = $domain;
|
46 |
+
$this->for_role = $for_role;
|
47 |
+
$this->join_manager = $join_manager;
|
48 |
+
$this->database_operations = ( null === $database_operations_di ? new Toolset_Relationship_Database_Operations() : $database_operations_di );
|
49 |
+
}
|
50 |
+
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Get a part of the WHERE clause that applies the condition.
|
54 |
+
*
|
55 |
+
* @return string Valid part of a MySQL query, so that it can be
|
56 |
+
* used in WHERE ( $condition1 ) AND ( $condition2 ) AND ( $condition3 ) ...
|
57 |
+
*/
|
58 |
+
public function get_where_clause() {
|
59 |
+
$relationships_table_alias = $this->join_manager->relationships();
|
60 |
+
$domain_column = $this->database_operations->role_to_column(
|
61 |
+
$this->for_role,
|
62 |
+
Toolset_Relationship_Database_Operations::COLUMN_DOMAIN
|
63 |
+
);
|
64 |
+
|
65 |
+
return sprintf(
|
66 |
+
"%s.%s = '%s'",
|
67 |
+
$relationships_table_alias,
|
68 |
+
$domain_column,
|
69 |
+
esc_sql( $this->domain )
|
70 |
+
);
|
71 |
+
}
|
72 |
+
|
73 |
+
|
74 |
+
/**
|
75 |
+
* @return string The element domain set on this condition.
|
76 |
+
* @since 2.5.10
|
77 |
+
*/
|
78 |
+
public function get_domain() {
|
79 |
+
return $this->domain;
|
80 |
+
}
|
81 |
+
|
82 |
+
|
83 |
+
public function get_for_role() {
|
84 |
+
return $this->for_role;
|
85 |
+
}
|
86 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/association/query/condition/has_domain_and_type.php
ADDED
@@ -0,0 +1,98 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Condition to filter results by element domain and type at the same time.
|
5 |
+
*
|
6 |
+
* Actually, this doesn't do anything but to tie those two together so that the association query
|
7 |
+
* can perform some more advanced optimizations.
|
8 |
+
*
|
9 |
+
* @since m2m
|
10 |
+
*/
|
11 |
+
class Toolset_Association_Query_Condition_Has_Domain_And_Type extends Toolset_Association_Query_Condition {
|
12 |
+
|
13 |
+
|
14 |
+
/** @var string */
|
15 |
+
private $domain;
|
16 |
+
|
17 |
+
|
18 |
+
/** @var string */
|
19 |
+
private $type;
|
20 |
+
|
21 |
+
|
22 |
+
/** @var IToolset_Association_Query_Condition */
|
23 |
+
private $inner_condition;
|
24 |
+
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Toolset_Association_Query_Condition_Has_Type constructor.
|
28 |
+
*
|
29 |
+
* @param IToolset_Relationship_Role_Parent_Child $for_role
|
30 |
+
* @param string $domain
|
31 |
+
* @param string $type
|
32 |
+
* @param Toolset_Association_Query_Table_Join_Manager $join_manager
|
33 |
+
* @param Toolset_Relationship_Database_Unique_Table_Alias $unique_table_alias
|
34 |
+
* @param Toolset_Association_Query_Condition_Factory $condition_factory
|
35 |
+
*/
|
36 |
+
public function __construct(
|
37 |
+
IToolset_Relationship_Role_Parent_Child $for_role,
|
38 |
+
$domain,
|
39 |
+
$type,
|
40 |
+
Toolset_Association_Query_Table_Join_Manager $join_manager,
|
41 |
+
Toolset_Relationship_Database_Unique_Table_Alias $unique_table_alias,
|
42 |
+
Toolset_Association_Query_Condition_Factory $condition_factory
|
43 |
+
) {
|
44 |
+
if(
|
45 |
+
! in_array( $domain, Toolset_Element_Domain::all(), true )
|
46 |
+
|| ! is_string( $type ) || empty( $type )
|
47 |
+
) {
|
48 |
+
throw new InvalidArgumentException();
|
49 |
+
}
|
50 |
+
|
51 |
+
$this->domain = $domain;
|
52 |
+
$this->type = $type;
|
53 |
+
|
54 |
+
$this->inner_condition = $condition_factory->do_and(
|
55 |
+
array(
|
56 |
+
$condition_factory->has_domain( $domain, $for_role, $join_manager ),
|
57 |
+
$condition_factory->has_type( $type, $for_role, $join_manager, $unique_table_alias )
|
58 |
+
)
|
59 |
+
);
|
60 |
+
}
|
61 |
+
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Get a part of the WHERE clause that applies the condition.
|
65 |
+
*
|
66 |
+
* @return string Valid part of a MySQL query, so that it can be
|
67 |
+
* used in WHERE ( $condition1 ) AND ( $condition2 ) AND ( $condition3 ) ...
|
68 |
+
*/
|
69 |
+
public function get_where_clause() {
|
70 |
+
return $this->inner_condition->get_where_clause();
|
71 |
+
}
|
72 |
+
|
73 |
+
|
74 |
+
/**
|
75 |
+
* @inheritdoc
|
76 |
+
*
|
77 |
+
* @return string
|
78 |
+
*/
|
79 |
+
public function get_join_clause() {
|
80 |
+
return $this->inner_condition->get_join_clause();
|
81 |
+
}
|
82 |
+
|
83 |
+
|
84 |
+
/**
|
85 |
+
* @return string The element domain set in this condition.
|
86 |
+
*/
|
87 |
+
public function get_domain() {
|
88 |
+
return $this->domain;
|
89 |
+
}
|
90 |
+
|
91 |
+
|
92 |
+
/**
|
93 |
+
* @return string The element type set in this condition.
|
94 |
+
*/
|
95 |
+
public function get_type() {
|
96 |
+
return $this->type;
|
97 |
+
}
|
98 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/association/query/condition/has_legacy_relationship.php
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Query associations by the fact whether the relationship they belong to was migrated from the legacy implementation or not.
|
5 |
+
*
|
6 |
+
* @since 2.5.8
|
7 |
+
*/
|
8 |
+
class Toolset_Association_Query_Condition_Has_Legacy_Relationship extends Toolset_Association_Query_Condition_Relationship_Flag {
|
9 |
+
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @inheritdoc
|
13 |
+
* @return string
|
14 |
+
*/
|
15 |
+
protected function get_flag_name() {
|
16 |
+
return 'needs_legacy_support';
|
17 |
+
}
|
18 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/association/query/condition/has_type.php
ADDED
@@ -0,0 +1,100 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Condition to query associations by a type (not domain) of elements in the given role.
|
5 |
+
*
|
6 |
+
* @since 2.5.8
|
7 |
+
*/
|
8 |
+
class Toolset_Association_Query_Condition_Has_Type extends Toolset_Association_Query_Condition {
|
9 |
+
|
10 |
+
|
11 |
+
/** @var IToolset_Relationship_Role_Parent_Child */
|
12 |
+
private $for_role;
|
13 |
+
|
14 |
+
|
15 |
+
/** @var string */
|
16 |
+
private $type;
|
17 |
+
|
18 |
+
|
19 |
+
/** @var Toolset_Association_Query_Table_Join_Manager */
|
20 |
+
private $join_manager;
|
21 |
+
|
22 |
+
|
23 |
+
/** @var Toolset_Relationship_Database_Operations */
|
24 |
+
private $database_operations;
|
25 |
+
|
26 |
+
|
27 |
+
/** @var Toolset_Relationship_Table_Name */
|
28 |
+
private $table_name;
|
29 |
+
|
30 |
+
|
31 |
+
/** @var Toolset_Relationship_Database_Unique_Table_Alias */
|
32 |
+
private $unique_table_alias;
|
33 |
+
|
34 |
+
|
35 |
+
/** @var string|null This needs to be set during get_join_clauses(). */
|
36 |
+
private $type_set_table_alias;
|
37 |
+
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Toolset_Association_Query_Condition_Has_Type constructor.
|
41 |
+
*
|
42 |
+
* @param IToolset_Relationship_Role_Parent_Child $for_role
|
43 |
+
* @param string $type
|
44 |
+
* @param Toolset_Association_Query_Table_Join_Manager $join_manager
|
45 |
+
* @param Toolset_Relationship_Database_Unique_Table_Alias $unique_table_alias
|
46 |
+
* @param Toolset_Relationship_Database_Operations|null $database_operations_di
|
47 |
+
* @param Toolset_Relationship_Table_Name|null $table_name_di
|
48 |
+
* @throws InvalidArgumentException
|
49 |
+
*/
|
50 |
+
public function __construct(
|
51 |
+
IToolset_Relationship_Role_Parent_Child $for_role,
|
52 |
+
$type,
|
53 |
+
Toolset_Association_Query_Table_Join_Manager $join_manager,
|
54 |
+
Toolset_Relationship_Database_Unique_Table_Alias $unique_table_alias,
|
55 |
+
Toolset_Relationship_Database_Operations $database_operations_di = null,
|
56 |
+
Toolset_Relationship_Table_Name $table_name_di = null
|
57 |
+
) {
|
58 |
+
if( ! is_string( $type ) || empty( $type ) ) {
|
59 |
+
throw new InvalidArgumentException();
|
60 |
+
}
|
61 |
+
|
62 |
+
$this->for_role = $for_role;
|
63 |
+
$this->type = $type;
|
64 |
+
$this->join_manager = $join_manager;
|
65 |
+
$this->unique_table_alias = $unique_table_alias;
|
66 |
+
$this->database_operations = ( null === $database_operations_di ? new Toolset_Relationship_Database_Operations() : $database_operations_di );
|
67 |
+
$this->table_name = ( null === $table_name_di ? new Toolset_Relationship_Table_Name() : $table_name_di );
|
68 |
+
}
|
69 |
+
|
70 |
+
|
71 |
+
/**
|
72 |
+
* @inheritdoc
|
73 |
+
* @return string
|
74 |
+
*/
|
75 |
+
public function get_join_clause() {
|
76 |
+
$relationships_table = $this->join_manager->relationships();
|
77 |
+
$type_set_column = $this->database_operations->role_to_column(
|
78 |
+
$this->for_role->get_name(),
|
79 |
+
Toolset_Relationship_Database_Operations::COLUMN_TYPES
|
80 |
+
);
|
81 |
+
$type_set_table = $this->table_name->type_set_table();
|
82 |
+
$type_set_table_alias = $this->unique_table_alias->generate( $type_set_table, true );
|
83 |
+
|
84 |
+
$this->type_set_table_alias = $type_set_table_alias;
|
85 |
+
|
86 |
+
return " JOIN $type_set_table AS $type_set_table_alias ON ( $type_set_table_alias.set_id = $relationships_table.$type_set_column ) ";
|
87 |
+
}
|
88 |
+
|
89 |
+
|
90 |
+
/**
|
91 |
+
* Get a part of the WHERE clause that applies the condition.
|
92 |
+
*
|
93 |
+
* @return string Valid part of a MySQL query, so that it can be
|
94 |
+
* used in WHERE ( $condition1 ) AND ( $condition2 ) AND ( $condition3 ) ...
|
95 |
+
*/
|
96 |
+
public function get_where_clause() {
|
97 |
+
return sprintf( "%s.type = '%s'", $this->type_set_table_alias, esc_sql( $this->type ) );
|
98 |
+
}
|
99 |
+
|
100 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/association/query/condition/interface.php
ADDED
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Represents a single condition for the Tooset_Association_Query_V2.
|
5 |
+
*
|
6 |
+
* Note: It is very important that if an Toolset_Association_Query_Element_Selector_Provider instance
|
7 |
+
* is passed to the condition, it doesn't try to obtain the element selector object
|
8 |
+
* within its constructor.
|
9 |
+
*
|
10 |
+
* @since 2.5.8
|
11 |
+
*/
|
12 |
+
interface IToolset_Association_Query_Condition extends IToolset_Query_Condition {
|
13 |
+
|
14 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/association/query/condition/postmeta.php
ADDED
@@ -0,0 +1,78 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Query condition by a postmeta value of a selected element role.
|
5 |
+
*
|
6 |
+
* Note: Using this will immediately exclude all non-post elements.
|
7 |
+
*
|
8 |
+
* @since 2.6.1
|
9 |
+
*/
|
10 |
+
class Toolset_Association_Query_Condition_Postmeta extends Toolset_Association_Query_Condition {
|
11 |
+
|
12 |
+
|
13 |
+
/** @var string */
|
14 |
+
private $meta_key;
|
15 |
+
|
16 |
+
|
17 |
+
/** @var string */
|
18 |
+
private $meta_value;
|
19 |
+
|
20 |
+
|
21 |
+
/** @var string */
|
22 |
+
private $comparison_operator;
|
23 |
+
|
24 |
+
|
25 |
+
/** @var IToolset_Relationship_Role */
|
26 |
+
private $for_role;
|
27 |
+
|
28 |
+
|
29 |
+
/** @var Toolset_Association_Query_Table_Join_Manager */
|
30 |
+
private $join_manager;
|
31 |
+
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Toolset_Association_Query_Condition_Postmeta constructor.
|
35 |
+
*
|
36 |
+
* @param string $meta_key
|
37 |
+
* @param string $meta_value
|
38 |
+
* @param string $comparison_operator
|
39 |
+
* @param IToolset_Relationship_Role $for_role
|
40 |
+
* @param Toolset_Association_Query_Table_Join_Manager $join_manager
|
41 |
+
* @throws InvalidArgumentException
|
42 |
+
*/
|
43 |
+
public function __construct(
|
44 |
+
$meta_key,
|
45 |
+
$meta_value,
|
46 |
+
$comparison_operator,
|
47 |
+
IToolset_Relationship_Role $for_role,
|
48 |
+
Toolset_Association_Query_Table_Join_Manager $join_manager
|
49 |
+
) {
|
50 |
+
if(
|
51 |
+
! is_string( $meta_key ) || empty( $meta_key )
|
52 |
+
|| ! is_string( $meta_value ) || empty( $meta_value )
|
53 |
+
|| ! in_array( $comparison_operator, Toolset_Query_Comparison_Operator::all() )
|
54 |
+
) {
|
55 |
+
throw new InvalidArgumentException();
|
56 |
+
}
|
57 |
+
|
58 |
+
$this->meta_key = $meta_key;
|
59 |
+
$this->meta_value = $meta_value;
|
60 |
+
$this->comparison_operator = $comparison_operator;
|
61 |
+
$this->for_role = $for_role;
|
62 |
+
$this->join_manager = $join_manager;
|
63 |
+
}
|
64 |
+
|
65 |
+
/**
|
66 |
+
* Get a part of the WHERE clause that applies the condition.
|
67 |
+
*
|
68 |
+
* @return string Valid part of a MySQL query, so that it can be
|
69 |
+
* used in WHERE ( $condition1 ) AND ( $condition2 ) AND ( $condition3 ) ...
|
70 |
+
*/
|
71 |
+
public function get_where_clause() {
|
72 |
+
$postmeta = $this->join_manager->wp_postmeta( $this->for_role, $this->meta_key );
|
73 |
+
$meta_value = esc_sql( $this->meta_value );
|
74 |
+
|
75 |
+
return "$postmeta $this->comparison_operator '$meta_value'";
|
76 |
+
}
|
77 |
+
|
78 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/association/query/condition/relationship_flag.php
ADDED
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Query associations by a flag of a relationship they belong to.
|
5 |
+
*
|
6 |
+
* @since 2.5.8
|
7 |
+
*/
|
8 |
+
abstract class Toolset_Association_Query_Condition_Relationship_Flag extends Toolset_Association_Query_Condition {
|
9 |
+
|
10 |
+
|
11 |
+
/** @var Toolset_Association_Query_Table_Join_Manager */
|
12 |
+
private $join_manager;
|
13 |
+
|
14 |
+
|
15 |
+
/** @var bool */
|
16 |
+
private $expected_value;
|
17 |
+
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Toolset_Association_Query_Condition_Has_Active_Relationship constructor.
|
21 |
+
*
|
22 |
+
* @param bool $expected_value
|
23 |
+
* @param Toolset_Association_Query_Table_Join_Manager $join_manager
|
24 |
+
*/
|
25 |
+
public function __construct( $expected_value, Toolset_Association_Query_Table_Join_Manager $join_manager ) {
|
26 |
+
$this->expected_value = (bool) $expected_value;
|
27 |
+
$this->join_manager = $join_manager;
|
28 |
+
}
|
29 |
+
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Get a part of the WHERE clause that applies the condition.
|
33 |
+
*
|
34 |
+
* @return string Valid part of a MySQL query, so that it can be
|
35 |
+
* used in WHERE ( $condition1 ) AND ( $condition2 ) AND ( $condition3 ) ...
|
36 |
+
*/
|
37 |
+
public function get_where_clause() {
|
38 |
+
$relationships_table = $this->join_manager->relationships();
|
39 |
+
|
40 |
+
return sprintf(
|
41 |
+
'%s.%s = %d',
|
42 |
+
$relationships_table,
|
43 |
+
$this->get_flag_name(),
|
44 |
+
$this->expected_value ? 1 : 0
|
45 |
+
);
|
46 |
+
}
|
47 |
+
|
48 |
+
|
49 |
+
/**
|
50 |
+
* Get the name of the column in the relationships table to query by.
|
51 |
+
*
|
52 |
+
* @return string
|
53 |
+
*/
|
54 |
+
protected abstract function get_flag_name();
|
55 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/association/query/condition/relationship_id.php
ADDED
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Condition to query associations by a specific relationship (row) ID.
|
5 |
+
*
|
6 |
+
* @since 2.5.8
|
7 |
+
*/
|
8 |
+
class Toolset_Association_Query_Condition_Relationship_Id extends Toolset_Association_Query_Condition {
|
9 |
+
|
10 |
+
|
11 |
+
/** @var int */
|
12 |
+
private $relationship_id;
|
13 |
+
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Toolset_Association_Query_Condition_Relationship_Id constructor.
|
17 |
+
*
|
18 |
+
* @param int $relationship_id
|
19 |
+
* @throws InvalidArgumentException
|
20 |
+
*/
|
21 |
+
public function __construct( $relationship_id ) {
|
22 |
+
if( ! Toolset_Utils::is_nonnegative_integer( $relationship_id ) ) {
|
23 |
+
throw new InvalidArgumentException();
|
24 |
+
}
|
25 |
+
|
26 |
+
$this->relationship_id = (int) $relationship_id;
|
27 |
+
}
|
28 |
+
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Get a part of the WHERE clause that applies the condition.
|
32 |
+
*
|
33 |
+
* @return string Valid part of a MySQL query, so that it can be
|
34 |
+
* used in WHERE ( $condition1 ) AND ( $condition2 ) AND ( $condition3 ) ...
|
35 |
+
*/
|
36 |
+
public function get_where_clause() {
|
37 |
+
return sprintf( 'associations.relationship_id = %d', $this->relationship_id );
|
38 |
+
}
|
39 |
+
|
40 |
+
|
41 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/association/query/condition/search.php
ADDED
@@ -0,0 +1,92 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Query by searching a text in elements of a given role.
|
5 |
+
*
|
6 |
+
* Note: This currently supports only posts, but in the future, it should be domain-agnostic.
|
7 |
+
*
|
8 |
+
* @since 2.5.8
|
9 |
+
*/
|
10 |
+
class Toolset_Association_Query_Condition_Search extends Toolset_Association_Query_Condition {
|
11 |
+
|
12 |
+
|
13 |
+
/** @var string */
|
14 |
+
private $search_string;
|
15 |
+
|
16 |
+
|
17 |
+
/** @var bool */
|
18 |
+
private $is_exact_search;
|
19 |
+
|
20 |
+
|
21 |
+
/** @var IToolset_Relationship_Role */
|
22 |
+
private $for_role;
|
23 |
+
|
24 |
+
|
25 |
+
/** @var Toolset_Association_Query_Table_Join_Manager */
|
26 |
+
private $join_manager;
|
27 |
+
|
28 |
+
|
29 |
+
/** @var wpdb */
|
30 |
+
private $wpdb;
|
31 |
+
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Toolset_Association_Query_Condition_Search constructor.
|
35 |
+
*
|
36 |
+
* @param string $search_string
|
37 |
+
* @param bool $is_exact_search
|
38 |
+
* @param IToolset_Relationship_Role $for_role
|
39 |
+
* @param Toolset_Association_Query_Table_Join_Manager $join_manager
|
40 |
+
* @param wpdb|null $wpdb_di
|
41 |
+
* @throws InvalidArgumentException
|
42 |
+
*/
|
43 |
+
public function __construct(
|
44 |
+
$search_string,
|
45 |
+
$is_exact_search,
|
46 |
+
IToolset_Relationship_Role $for_role,
|
47 |
+
Toolset_Association_Query_Table_Join_Manager $join_manager,
|
48 |
+
wpdb $wpdb_di = null
|
49 |
+
) {
|
50 |
+
if( ! is_string( $search_string ) || empty( $search_string ) ) {
|
51 |
+
throw new InvalidArgumentException( 'Invalid search string ' . $search_string );
|
52 |
+
}
|
53 |
+
$this->search_string = $search_string;
|
54 |
+
$this->join_manager = $join_manager;
|
55 |
+
$this->is_exact_search = (bool) $is_exact_search;
|
56 |
+
$this->for_role = $for_role;
|
57 |
+
|
58 |
+
global $wpdb;
|
59 |
+
$this->wpdb = ( null === $wpdb_di ? $wpdb : $wpdb_di );
|
60 |
+
}
|
61 |
+
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Get a part of the WHERE clause that applies the condition.
|
65 |
+
*
|
66 |
+
* @return string Valid part of a MySQL query, so that it can be
|
67 |
+
* used in WHERE ( $condition1 ) AND ( $condition2 ) AND ( $condition3 ) ...
|
68 |
+
*/
|
69 |
+
public function get_where_clause() {
|
70 |
+
$wp_posts = $this->join_manager->wp_posts( $this->for_role );
|
71 |
+
$search_string = esc_sql( $this->get_sanitized_search_string() );
|
72 |
+
|
73 |
+
return "{$wp_posts}.post_title LIKE '{$search_string}'
|
74 |
+
OR {$wp_posts}.post_excerpt LIKE '{$search_string}'
|
75 |
+
OR {$wp_posts}.post_content LIKE '{$search_string}'";
|
76 |
+
}
|
77 |
+
|
78 |
+
|
79 |
+
/**
|
80 |
+
* Get a string prepared for using in the query.
|
81 |
+
*
|
82 |
+
* @return string
|
83 |
+
*/
|
84 |
+
private function get_sanitized_search_string() {
|
85 |
+
$s = stripslashes( $this->search_string );
|
86 |
+
$s = str_replace( array( "\r", "\n", "\t" ), '', $s );
|
87 |
+
if( ! $this->is_exact_search ) {
|
88 |
+
$s = '%' . $this->wpdb->esc_like( $s ) . '%';
|
89 |
+
}
|
90 |
+
return $s;
|
91 |
+
}
|
92 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/association/query/condition/wp_query.php
ADDED
@@ -0,0 +1,288 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* A WP_Query condition.
|
5 |
+
*
|
6 |
+
* It allows for filtering the results of the association query by a WP_Query being applied on
|
7 |
+
* elements (posts) of a selected association role.
|
8 |
+
*
|
9 |
+
* WARNINGS and limitations:
|
10 |
+
*
|
11 |
+
* - The process to generate the query abuses WP_Query and is rather expensive in terms of performance.
|
12 |
+
* - This is untested and highly experimental.
|
13 |
+
* The WP_Query hack is so ugly that it's beautiful, if you ask me. But let's see if we actually
|
14 |
+
* put this to an use.
|
15 |
+
* - If used on non-post elements, the results are unpredictable. Never assume you're dealing only
|
16 |
+
* with post relationships.
|
17 |
+
* - Only subsets of WP_Query arguments are supported. Basically, anything that requires joining other
|
18 |
+
* tables than wp_posts should be considered unreliable (in need of extra testing) and if you use
|
19 |
+
* this query condition multiple times inside one association query, overreaching wp_posts
|
20 |
+
* will most definitely cause a collision of table aliases.
|
21 |
+
* - If you intend to use this only for searching elements by a string, please don't.
|
22 |
+
* Use $query->search() instead, which is much lighter and will become domain-agnostic
|
23 |
+
* when another domains become supported.
|
24 |
+
* - This usage of WP_Query doesn't support sticky posts, filter suppressing and WPML language queries.
|
25 |
+
*
|
26 |
+
* @since 2.5.8
|
27 |
+
*/
|
28 |
+
class Toolset_Association_Query_Condition_Wp_Query extends Toolset_Association_Query_Condition {
|
29 |
+
|
30 |
+
|
31 |
+
/** @var IToolset_Relationship_Role */
|
32 |
+
private $for_role;
|
33 |
+
|
34 |
+
|
35 |
+
/** @var array */
|
36 |
+
private $query_args;
|
37 |
+
|
38 |
+
|
39 |
+
/** @var Toolset_Association_Query_Table_Join_Manager */
|
40 |
+
private $join_manager;
|
41 |
+
|
42 |
+
|
43 |
+
/** @var Toolset_Relationship_Query_Factory */
|
44 |
+
private $query_factory;
|
45 |
+
|
46 |
+
|
47 |
+
/** @var array|null Clauses generated by the WP_Query class. */
|
48 |
+
private $wp_query_clauses;
|
49 |
+
|
50 |
+
|
51 |
+
/** @var wpdb */
|
52 |
+
private $wpdb;
|
53 |
+
|
54 |
+
|
55 |
+
/** @var Toolset_Relationship_Database_Unique_Table_Alias */
|
56 |
+
private $unique_table_alias;
|
57 |
+
|
58 |
+
|
59 |
+
/**
|
60 |
+
* Toolset_Association_Query_Condition_Wp_Query constructor.
|
61 |
+
*
|
62 |
+
* @param IToolset_Relationship_Role $for_role
|
63 |
+
* @param array $query_args
|
64 |
+
* @param Toolset_Association_Query_Table_Join_Manager $join_manager
|
65 |
+
* @param Toolset_Relationship_Database_Unique_Table_Alias $unique_table_alias
|
66 |
+
* @param Toolset_Relationship_Query_Factory|null $query_factory_di
|
67 |
+
* @param wpdb|null $wpdb_di
|
68 |
+
* @throws InvalidArgumentException
|
69 |
+
*/
|
70 |
+
public function __construct(
|
71 |
+
IToolset_Relationship_Role $for_role, $query_args,
|
72 |
+
Toolset_Association_Query_Table_Join_Manager $join_manager,
|
73 |
+
Toolset_Relationship_Database_Unique_Table_Alias $unique_table_alias,
|
74 |
+
Toolset_Relationship_Query_Factory $query_factory_di = null,
|
75 |
+
wpdb $wpdb_di = null
|
76 |
+
) {
|
77 |
+
if( ! is_array( $query_args ) ) {
|
78 |
+
throw new InvalidArgumentException();
|
79 |
+
}
|
80 |
+
$this->for_role = $for_role;
|
81 |
+
$this->query_args = $query_args;
|
82 |
+
$this->join_manager = $join_manager;
|
83 |
+
$this->query_factory = ( null === $query_factory_di ? new Toolset_Relationship_Query_Factory() : $query_factory_di );
|
84 |
+
$this->unique_table_alias = $unique_table_alias;
|
85 |
+
if( null === $wpdb_di ) {
|
86 |
+
global $wpdb;
|
87 |
+
$this->wpdb = $wpdb;
|
88 |
+
} else {
|
89 |
+
$this->wpdb = $wpdb_di;
|
90 |
+
}
|
91 |
+
}
|
92 |
+
|
93 |
+
|
94 |
+
/**
|
95 |
+
* Get a part of the WHERE clause that applies the condition.
|
96 |
+
*
|
97 |
+
* @return string Valid part of a MySQL query, so that it can be
|
98 |
+
* used in WHERE ( $condition1 ) AND ( $condition2 ) AND ( $condition3 ) ...
|
99 |
+
*/
|
100 |
+
public function get_where_clause() {
|
101 |
+
$query_clauses = $this->get_wp_query_clauses();
|
102 |
+
|
103 |
+
// The clause starts with AND. I'm not sure about the whitespaces, so this is easier than
|
104 |
+
// parsing and removing the keyword.
|
105 |
+
return ' 1 = 1 ' . $query_clauses['where'];
|
106 |
+
}
|
107 |
+
|
108 |
+
|
109 |
+
/**
|
110 |
+
* @inheritdoc
|
111 |
+
*
|
112 |
+
* @return string
|
113 |
+
*/
|
114 |
+
public function get_join_clause() {
|
115 |
+
$query_clauses = $this->get_wp_query_clauses();
|
116 |
+
$join_clauses = $query_clauses['join'];
|
117 |
+
|
118 |
+
return $join_clauses;
|
119 |
+
}
|
120 |
+
|
121 |
+
|
122 |
+
/**
|
123 |
+
* Retrieve the generated clauses from WP_Query.
|
124 |
+
*
|
125 |
+
* @return string[]
|
126 |
+
*/
|
127 |
+
private function get_wp_query_clauses() {
|
128 |
+
if( null === $this->wp_query_clauses ) {
|
129 |
+
$this->wp_query_clauses = $this->build_wp_query_clauses( $this->query_args );
|
130 |
+
}
|
131 |
+
|
132 |
+
return $this->wp_query_clauses;
|
133 |
+
}
|
134 |
+
|
135 |
+
|
136 |
+
/**
|
137 |
+
* Fool WP_Query into generating MySQL query clauses for given query arguments without actually executing the query.
|
138 |
+
*
|
139 |
+
* It also prevents WPML from modifying the query because filtering by language is handled elsewhere.
|
140 |
+
* It doesn't support sticky posts, filter suppressing and probably some complex use-cases.
|
141 |
+
*
|
142 |
+
* @param array $query_args Arguments for WP_Query.
|
143 |
+
* @return string[] MySQL clauses, for details see the posts_clauses filter.
|
144 |
+
* @since 2.5.8
|
145 |
+
*/
|
146 |
+
private function build_wp_query_clauses( $query_args ) {
|
147 |
+
|
148 |
+
// Sticky posts are handled in a special way after the query takes place, so they would have no
|
149 |
+
// effect in any case. This is a performance optimalization.
|
150 |
+
$query_args['ignore_sticky_posts'] = true;
|
151 |
+
|
152 |
+
// Without this, we won't be able to get the clauses because the posts_clauses filter would not be applied.
|
153 |
+
$query_args['suppress_filters'] = false;
|
154 |
+
|
155 |
+
if( ! isset( $query_args['post_type'] ) ) {
|
156 |
+
// Get all associated post_types if none is defined
|
157 |
+
$query_args['post_type'] = 'any';
|
158 |
+
}
|
159 |
+
|
160 |
+
// This will hold the mysql clauses after WP_Query pushes them through the posts_pre_query filter.
|
161 |
+
$clauses_out = array();
|
162 |
+
|
163 |
+
$catch_clauses = function( $clauses_in ) use( &$clauses_out ) {
|
164 |
+
$clauses_out = $clauses_in;
|
165 |
+
};
|
166 |
+
|
167 |
+
// Filter priority
|
168 |
+
$very_late = 10000;
|
169 |
+
|
170 |
+
add_filter( 'posts_clauses', $catch_clauses, $very_late );
|
171 |
+
|
172 |
+
// Returning a non-null value on the posts_pre_query filter (since WP 4.6) causes that no actual
|
173 |
+
// mysql query takes place in WP_Query::get_posts().
|
174 |
+
$dont_query_anyting = function() { return array(); };
|
175 |
+
add_filter( 'posts_pre_query', $dont_query_anyting, $very_late );
|
176 |
+
|
177 |
+
// Avoid WPML messing with the results because we already know in which language we want to query
|
178 |
+
$current_language = apply_filters( 'wpml_current_language', '' );
|
179 |
+
do_action( 'wpml_switch_language', 'all' );
|
180 |
+
|
181 |
+
// Did you think it can't get any worse? Well... Now we have to override $wpdb
|
182 |
+
// because we need it to use a different name of the wp_posts table. The wrapper object will
|
183 |
+
// forward anything to the original $wpdb instance except the attempt to read the $posts
|
184 |
+
// property. In that case, it will use the join manager to get a proper table alias.
|
185 |
+
//
|
186 |
+
// This hack allows us to use this query condition (at least in a limited way) multiple times
|
187 |
+
// within a single query.
|
188 |
+
global $wpdb;
|
189 |
+
$original_wpdb_object = $wpdb;
|
190 |
+
$wpdb_wrapper = new Toolset_Association_Query_Wpdb_Wrapper(
|
191 |
+
$wpdb, $this->join_manager, $this->for_role
|
192 |
+
);
|
193 |
+
$wpdb = $wpdb_wrapper;
|
194 |
+
|
195 |
+
// This will immediately run the query.
|
196 |
+
$this->query_factory->wp_query( $query_args );
|
197 |
+
|
198 |
+
// Like nothing has ever happened.
|
199 |
+
$wpdb = $original_wpdb_object;
|
200 |
+
|
201 |
+
// Switch back to the current language so that we don't break anything else down the road.
|
202 |
+
do_action( 'wpml_switch_language', $current_language );
|
203 |
+
|
204 |
+
// Clean up
|
205 |
+
remove_filter( 'posts_clauses', $catch_clauses, $very_late );
|
206 |
+
remove_filter( 'posts_pre_query', $dont_query_anyting, $very_late );
|
207 |
+
|
208 |
+
return $this->adjust_table_aliases( $clauses_out );
|
209 |
+
}
|
210 |
+
|
211 |
+
|
212 |
+
/**
|
213 |
+
* Try to avoid table alias collisions if the WP_Query joins further tables.
|
214 |
+
*
|
215 |
+
* @param string[] $query_clauses Array with the query clauses coming from the WP_Query.
|
216 |
+
* @return string[] Updated query clauses array.
|
217 |
+
*/
|
218 |
+
private function adjust_table_aliases( $query_clauses ) {
|
219 |
+
|
220 |
+
$join_clauses = $query_clauses['join'];
|
221 |
+
$where_clauses = $query_clauses['where'];
|
222 |
+
|
223 |
+
$matches = array();
|
224 |
+
|
225 |
+
// Match all JOINs - table name in the second capturing group and optionally also
|
226 |
+
// alias name in the fifth capturing group (it may not be present).
|
227 |
+
preg_match_all(
|
228 |
+
'/JOIN\s+(\w+)\s+(as\s+|AS\s+)?((\w+)\s+)?ON/',
|
229 |
+
$join_clauses, $matches, PREG_SET_ORDER
|
230 |
+
);
|
231 |
+
|
232 |
+
foreach( $matches as $match ) {
|
233 |
+
// Failsafe if something goes wrong.
|
234 |
+
if( ! is_array( $match ) || count( $match ) < 2 ) {
|
235 |
+
continue;
|
236 |
+
}
|
237 |
+
|
238 |
+
$table_name = $match[1];
|
239 |
+
$replace_table_name_in_where = true;
|
240 |
+
|
241 |
+
// wp_posts table needs special handling because its name has already been overridden
|
242 |
+
// (it's always used, while additional JOINs will not be so frequent).
|
243 |
+
if ( $table_name === $this->join_manager->wp_posts( $this->for_role ) ) {
|
244 |
+
$join_clauses = str_replace( $table_name, $this->wpdb->posts, $join_clauses );
|
245 |
+
$replace_table_name_in_where = false;
|
246 |
+
$table_name = $this->wpdb->posts;
|
247 |
+
}
|
248 |
+
|
249 |
+
// This is unique across the whole association query.
|
250 |
+
$unique_alias_name = $this->unique_table_alias->generate( $table_name, true );
|
251 |
+
|
252 |
+
$has_alias = ( count( $match ) === 5 );
|
253 |
+
|
254 |
+
if( $has_alias ) {
|
255 |
+
// We already have an alias, so we keep the original table name
|
256 |
+
// in the "JOIN $table_name AS..." as it is, and just replace the alias by
|
257 |
+
// an unique one.
|
258 |
+
$alias_name = $match[4];
|
259 |
+
$join_clauses = preg_replace( '/'.$table_name.'\s+'.$alias_name.'/', $table_name . ' ' . $unique_alias_name, $join_clauses );
|
260 |
+
$join_clauses = preg_replace( '/([^A-z\_])'.$alias_name.'\./', "$1$unique_alias_name.", $join_clauses );
|
261 |
+
$where_clauses = preg_replace( '/'.$table_name.'\s+'.$alias_name.'/', $table_name . ' ' . $unique_alias_name, $where_clauses );
|
262 |
+
$where_clauses = preg_replace( '/([^A-z\_])'.$alias_name.'\./', "$1$unique_alias_name.", $where_clauses );
|
263 |
+
} else {
|
264 |
+
// There is no alias the table name is used directly - we need to add it.
|
265 |
+
// First, replace the table name with the alias everywhere.
|
266 |
+
$join_clauses = str_replace( $table_name, $unique_alias_name, $join_clauses );
|
267 |
+
// And now, replace back the "JOIN $unique_alias_name" with the actual table name
|
268 |
+
// and add the "AS $unique_alias_name" string.
|
269 |
+
$join_clauses = preg_replace(
|
270 |
+
"/JOIN\s+$unique_alias_name\s+ON/",
|
271 |
+
"JOIN $table_name AS $unique_alias_name ON",
|
272 |
+
$join_clauses
|
273 |
+
);
|
274 |
+
|
275 |
+
// The table/alias usage in the WHERE clause needs to be adjusted as well.
|
276 |
+
// (unless we're dealing with a wp_posts alias)
|
277 |
+
if( $replace_table_name_in_where ) {
|
278 |
+
$where_clauses = str_replace( $table_name, $unique_alias_name, $where_clauses );
|
279 |
+
}
|
280 |
+
}
|
281 |
+
}
|
282 |
+
|
283 |
+
$query_clauses['join'] = $join_clauses;
|
284 |
+
$query_clauses['where'] = $where_clauses;
|
285 |
+
return $query_clauses;
|
286 |
+
}
|
287 |
+
|
288 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/association/query/condition_factory.php
ADDED
@@ -0,0 +1,322 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* A factory for IToolset_Association_Query_Condition implementations.
|
5 |
+
*
|
6 |
+
* @since 2.5.8
|
7 |
+
*/
|
8 |
+
class Toolset_Association_Query_Condition_Factory {
|
9 |
+
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Chain multiple conditions with OR.
|
13 |
+
*
|
14 |
+
* The whole statement will evaluate to true if at least one of provided conditions is true.
|
15 |
+
*
|
16 |
+
* @param IToolset_Association_Query_Condition[] $operands
|
17 |
+
* @return IToolset_Association_Query_Condition
|
18 |
+
*/
|
19 |
+
public function do_or( $operands ) {
|
20 |
+
return new Toolset_Query_Condition_Or( $operands );
|
21 |
+
}
|
22 |
+
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Chain multiple conditions with AN.
|
26 |
+
*
|
27 |
+
* The whole statement will evaluate to true if all provided conditions are true.
|
28 |
+
*
|
29 |
+
* @param IToolset_Association_Query_Condition[] $operands
|
30 |
+
* @return IToolset_Association_Query_Condition
|
31 |
+
*/
|
32 |
+
public function do_and( $operands ) {
|
33 |
+
return new Toolset_Query_Condition_And( $operands );
|
34 |
+
}
|
35 |
+
|
36 |
+
|
37 |
+
/**
|
38 |
+
* A condition that is always true.
|
39 |
+
*
|
40 |
+
* @return IToolset_Association_Query_Condition
|
41 |
+
*/
|
42 |
+
public function tautology() {
|
43 |
+
return new Toolset_Query_Condition_Tautology();
|
44 |
+
}
|
45 |
+
|
46 |
+
|
47 |
+
/**
|
48 |
+
* A condition that is always false.
|
49 |
+
*
|
50 |
+
* @return IToolset_Association_Query_Condition
|
51 |
+
*/
|
52 |
+
public function contradiction() {
|
53 |
+
return new Toolset_Query_Condition_Contradiction();
|
54 |
+
}
|
55 |
+
|
56 |
+
|
57 |
+
/**
|
58 |
+
* Condition to query associations by a specific relationship (row) ID.
|
59 |
+
*
|
60 |
+
* @param int $relationship_id
|
61 |
+
*
|
62 |
+
* @return IToolset_Association_Query_Condition
|
63 |
+
*/
|
64 |
+
public function relationship_id( $relationship_id ) {
|
65 |
+
return new Toolset_Association_Query_Condition_Relationship_Id( $relationship_id );
|
66 |
+
}
|
67 |
+
|
68 |
+
|
69 |
+
/**
|
70 |
+
* Condition to query associations by a particular element involved in a particular role.
|
71 |
+
*
|
72 |
+
* Warning: WPML-unaware implementation.
|
73 |
+
*
|
74 |
+
* @param int $element_id
|
75 |
+
* @param IToolset_Relationship_Role_Parent_Child $for_role
|
76 |
+
* @param Toolset_Association_Query_Element_Selector_Provider $element_selector_provider
|
77 |
+
*
|
78 |
+
* @return IToolset_Association_Query_Condition
|
79 |
+
*/
|
80 |
+
public function element_id(
|
81 |
+
$element_id, IToolset_Relationship_Role_Parent_Child $for_role,
|
82 |
+
Toolset_Association_Query_Element_Selector_Provider $element_selector_provider
|
83 |
+
) {
|
84 |
+
return new Toolset_Association_Query_Condition_Element_Id( $element_id, $for_role, $element_selector_provider );
|
85 |
+
}
|
86 |
+
|
87 |
+
|
88 |
+
/**
|
89 |
+
* Condition to query associations by a particular element involved in a particular role.
|
90 |
+
*
|
91 |
+
* @param int $element_id
|
92 |
+
* @param string $domain
|
93 |
+
* @param IToolset_Relationship_Role $for_role
|
94 |
+
* @param Toolset_Association_Query_Element_Selector_Provider $element_selector_provider
|
95 |
+
* @param $query_original_element
|
96 |
+
* @param $translate_provided_id
|
97 |
+
*
|
98 |
+
* @return Toolset_Association_Query_Condition_Element_Id_And_Domain
|
99 |
+
*/
|
100 |
+
public function element_id_and_domain(
|
101 |
+
$element_id,
|
102 |
+
$domain,
|
103 |
+
IToolset_Relationship_Role $for_role,
|
104 |
+
Toolset_Association_Query_Element_Selector_Provider $element_selector_provider,
|
105 |
+
$query_original_element,
|
106 |
+
$translate_provided_id
|
107 |
+
) {
|
108 |
+
return new Toolset_Association_Query_Condition_Element_Id_And_Domain(
|
109 |
+
$element_id, $domain, $for_role, $element_selector_provider, $query_original_element, $translate_provided_id
|
110 |
+
);
|
111 |
+
}
|
112 |
+
|
113 |
+
|
114 |
+
|
115 |
+
/**
|
116 |
+
* Condition to query associations that do not contain a particular element in a particular role.
|
117 |
+
*
|
118 |
+
* @param int $element_id
|
119 |
+
* @param string $domain
|
120 |
+
* @param IToolset_Relationship_Role $for_role
|
121 |
+
* @param Toolset_Association_Query_Element_Selector_Provider $element_selector_provider
|
122 |
+
* @param $query_original_element
|
123 |
+
* @param $translate_provided_id
|
124 |
+
*
|
125 |
+
* @return Toolset_Association_Query_Condition_Element_Id_And_Domain
|
126 |
+
*/
|
127 |
+
public function exclude_element(
|
128 |
+
$element_id,
|
129 |
+
$domain,
|
130 |
+
IToolset_Relationship_Role $for_role,
|
131 |
+
Toolset_Association_Query_Element_Selector_Provider $element_selector_provider,
|
132 |
+
$query_original_element,
|
133 |
+
$translate_provided_id
|
134 |
+
) {
|
135 |
+
return new Toolset_Association_Query_Condition_Exclude_Element(
|
136 |
+
$element_id, $domain, $for_role, $element_selector_provider, $query_original_element, $translate_provided_id
|
137 |
+
);
|
138 |
+
}
|
139 |
+
|
140 |
+
|
141 |
+
/**
|
142 |
+
* Condition to query associations by a status of an element in a particular role.
|
143 |
+
*
|
144 |
+
* @param string $status
|
145 |
+
* @param IToolset_Relationship_Role $for_role
|
146 |
+
* @param Toolset_Association_Query_Table_Join_Manager $join_manager
|
147 |
+
* @param Toolset_Association_Query_Element_Selector_Provider $element_selector_provider
|
148 |
+
*
|
149 |
+
* @return IToolset_Association_Query_Condition
|
150 |
+
*/
|
151 |
+
public function element_status(
|
152 |
+
$status, IToolset_Relationship_Role $for_role,
|
153 |
+
Toolset_Association_Query_Table_Join_Manager $join_manager,
|
154 |
+
Toolset_Association_Query_Element_Selector_Provider $element_selector_provider
|
155 |
+
) {
|
156 |
+
return new Toolset_Association_Query_Condition_Element_Status(
|
157 |
+
$status, $for_role, $join_manager, $element_selector_provider
|
158 |
+
);
|
159 |
+
}
|
160 |
+
|
161 |
+
|
162 |
+
/**
|
163 |
+
* Query associations by the activity status of the relationship.
|
164 |
+
*
|
165 |
+
* @param bool $is_active
|
166 |
+
* @param Toolset_Association_Query_Table_Join_Manager $join_manager
|
167 |
+
*
|
168 |
+
* @return IToolset_Association_Query_Condition
|
169 |
+
*/
|
170 |
+
public function has_active_relationship( $is_active, Toolset_Association_Query_Table_Join_Manager $join_manager ) {
|
171 |
+
return new Toolset_Association_Query_Condition_Has_Active_Relationship( $is_active, $join_manager );
|
172 |
+
}
|
173 |
+
|
174 |
+
|
175 |
+
/**
|
176 |
+
* Query associations by the element domain on a specified role.
|
177 |
+
*
|
178 |
+
* @param string $domain Domain name.
|
179 |
+
* @param IToolset_Relationship_Role_Parent_Child $for_role
|
180 |
+
* @param Toolset_Association_Query_Table_Join_Manager $join_manager
|
181 |
+
*
|
182 |
+
* @return IToolset_Association_Query_Condition
|
183 |
+
*/
|
184 |
+
public function has_domain(
|
185 |
+
$domain, IToolset_Relationship_Role_Parent_Child $for_role, Toolset_Association_Query_Table_Join_Manager $join_manager
|
186 |
+
) {
|
187 |
+
return new Toolset_Association_Query_Condition_Has_Domain( $domain, $for_role, $join_manager );
|
188 |
+
}
|
189 |
+
|
190 |
+
|
191 |
+
/**
|
192 |
+
* @param bool $needs_legacy_support
|
193 |
+
* @param Toolset_Association_Query_Table_Join_Manager $join_manager
|
194 |
+
*
|
195 |
+
* @return IToolset_Association_Query_Condition
|
196 |
+
*/
|
197 |
+
public function has_legacy_relationship( $needs_legacy_support, Toolset_Association_Query_Table_Join_Manager $join_manager ) {
|
198 |
+
return new Toolset_Association_Query_Condition_Has_Legacy_Relationship( $needs_legacy_support, $join_manager );
|
199 |
+
}
|
200 |
+
|
201 |
+
|
202 |
+
/**
|
203 |
+
* Query associations by element type on a given role.
|
204 |
+
*
|
205 |
+
* Warning: This doesn't query for the domain. Make sure you at least add
|
206 |
+
* a separate element domain condition. Otherwise, the results will be unpredictable.
|
207 |
+
*
|
208 |
+
* The best way is to use the has_domain_and_type() condition instead, which whill allow
|
209 |
+
* for some more advanced optimizations.
|
210 |
+
*
|
211 |
+
* @param string $type
|
212 |
+
* @param IToolset_Relationship_Role_Parent_Child $for_role
|
213 |
+
* @param Toolset_Association_Query_Table_Join_Manager $join_manager
|
214 |
+
* @param Toolset_Relationship_Database_Unique_Table_Alias $unique_table_alias
|
215 |
+
*
|
216 |
+
* @return IToolset_Association_Query_Condition
|
217 |
+
*/
|
218 |
+
public function has_type(
|
219 |
+
$type,
|
220 |
+
IToolset_Relationship_Role_Parent_Child $for_role,
|
221 |
+
Toolset_Association_Query_Table_Join_Manager $join_manager,
|
222 |
+
Toolset_Relationship_Database_Unique_Table_Alias $unique_table_alias
|
223 |
+
) {
|
224 |
+
return new Toolset_Association_Query_Condition_Has_Type( $for_role, $type, $join_manager, $unique_table_alias );
|
225 |
+
}
|
226 |
+
|
227 |
+
|
228 |
+
/**
|
229 |
+
* @param string $domain
|
230 |
+
* @param string $type
|
231 |
+
* @param IToolset_Relationship_Role_Parent_Child $for_role
|
232 |
+
* @param Toolset_Association_Query_Table_Join_Manager $join_manager
|
233 |
+
* @param Toolset_Relationship_Database_Unique_Table_Alias $unique_table_alias
|
234 |
+
*
|
235 |
+
* @return Toolset_Association_Query_Condition_Has_Domain_And_Type
|
236 |
+
*/
|
237 |
+
public function has_domain_and_type(
|
238 |
+
$domain,
|
239 |
+
$type,
|
240 |
+
IToolset_Relationship_Role_Parent_Child $for_role,
|
241 |
+
Toolset_Association_Query_Table_Join_Manager $join_manager,
|
242 |
+
Toolset_Relationship_Database_Unique_Table_Alias $unique_table_alias
|
243 |
+
) {
|
244 |
+
return new Toolset_Association_Query_Condition_Has_Domain_And_Type(
|
245 |
+
$for_role, $domain, $type, $join_manager, $unique_table_alias, $this
|
246 |
+
);
|
247 |
+
}
|
248 |
+
|
249 |
+
|
250 |
+
/**
|
251 |
+
* @param IToolset_Relationship_Role $for_role
|
252 |
+
* @param array $query_args
|
253 |
+
* @param Toolset_Association_Query_Table_Join_Manager $join_manager
|
254 |
+
* @param Toolset_Relationship_Database_Unique_Table_Alias $table_alias
|
255 |
+
*
|
256 |
+
* @return IToolset_Association_Query_Condition
|
257 |
+
*/
|
258 |
+
public function wp_query(
|
259 |
+
IToolset_Relationship_Role $for_role,
|
260 |
+
$query_args,
|
261 |
+
Toolset_Association_Query_Table_Join_Manager $join_manager,
|
262 |
+
Toolset_Relationship_Database_Unique_Table_Alias $table_alias
|
263 |
+
) {
|
264 |
+
return new Toolset_Association_Query_Condition_Wp_Query( $for_role, $query_args, $join_manager, $table_alias );
|
265 |
+
}
|
266 |
+
|
267 |
+
|
268 |
+
/**
|
269 |
+
* @param string $search_string
|
270 |
+
* @param bool $is_exact_search
|
271 |
+
* @param IToolset_Relationship_Role $for_role
|
272 |
+
* @param Toolset_Association_Query_Table_Join_Manager $join_manager
|
273 |
+
*
|
274 |
+
* @return IToolset_Association_Query_Condition
|
275 |
+
*/
|
276 |
+
public function search(
|
277 |
+
$search_string,
|
278 |
+
$is_exact_search,
|
279 |
+
IToolset_Relationship_Role $for_role,
|
280 |
+
Toolset_Association_Query_Table_Join_Manager $join_manager
|
281 |
+
) {
|
282 |
+
return new Toolset_Association_Query_Condition_Search(
|
283 |
+
$search_string, $is_exact_search, $for_role, $join_manager
|
284 |
+
);
|
285 |
+
}
|
286 |
+
|
287 |
+
|
288 |
+
/**
|
289 |
+
* @param int $association_id
|
290 |
+
*
|
291 |
+
* @return IToolset_Association_Query_Condition
|
292 |
+
*/
|
293 |
+
public function association_id( $association_id ) {
|
294 |
+
return new Toolset_Association_Query_Condition_Association_Id( $association_id );
|
295 |
+
}
|
296 |
+
|
297 |
+
|
298 |
+
/**
|
299 |
+
* @param string $meta_key
|
300 |
+
* @param string $meta_value
|
301 |
+
* @param string $comparison_operator
|
302 |
+
* @param IToolset_Relationship_Role $for_role
|
303 |
+
* @param Toolset_Association_Query_Table_Join_Manager $join_manager
|
304 |
+
*
|
305 |
+
* @return Toolset_Association_Query_Condition_Postmeta
|
306 |
+
*/
|
307 |
+
public function postmeta(
|
308 |
+
$meta_key,
|
309 |
+
$meta_value,
|
310 |
+
$comparison_operator,
|
311 |
+
IToolset_Relationship_Role $for_role,
|
312 |
+
Toolset_Association_Query_Table_Join_Manager $join_manager
|
313 |
+
) {
|
314 |
+
return new Toolset_Association_Query_Condition_Postmeta(
|
315 |
+
$meta_key,
|
316 |
+
$meta_value,
|
317 |
+
$comparison_operator,
|
318 |
+
$for_role,
|
319 |
+
$join_manager
|
320 |
+
);
|
321 |
+
}
|
322 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/association/query/element_selector/abstract.php
ADDED
@@ -0,0 +1,95 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Shared functionality for all element selector implementations.
|
5 |
+
*
|
6 |
+
* @since 2.5.10
|
7 |
+
*/
|
8 |
+
abstract class Toolset_Association_Query_Element_Selector_Abstract
|
9 |
+
implements IToolset_Association_Query_Element_Selector
|
10 |
+
{
|
11 |
+
|
12 |
+
/** @var Toolset_Relationship_Database_Operations */
|
13 |
+
protected $database_operations;
|
14 |
+
|
15 |
+
|
16 |
+
/** @var Toolset_Relationship_Database_Unique_Table_Alias */
|
17 |
+
protected $table_alias;
|
18 |
+
|
19 |
+
|
20 |
+
/** @var Toolset_Association_Query_Table_Join_Manager */
|
21 |
+
protected $join_manager;
|
22 |
+
|
23 |
+
|
24 |
+
/** @var wpdb */
|
25 |
+
protected $wpdb;
|
26 |
+
|
27 |
+
|
28 |
+
/** @var Toolset_WPML_Compatibility */
|
29 |
+
protected $wpml_service;
|
30 |
+
|
31 |
+
|
32 |
+
/** @var IToolset_Relationship_Role[] */
|
33 |
+
protected $requested_roles = array();
|
34 |
+
|
35 |
+
|
36 |
+
/**
|
37 |
+
* Toolset_Association_Query_Element_Selector_Abstract constructor.
|
38 |
+
*
|
39 |
+
* @param Toolset_Relationship_Database_Unique_Table_Alias $table_alias
|
40 |
+
* @param Toolset_Association_Query_Table_Join_Manager $join_manager
|
41 |
+
* @param wpdb|null $wpdb_di
|
42 |
+
* @param Toolset_Relationship_Database_Operations|null $database_operations_di
|
43 |
+
* @param Toolset_WPML_Compatibility|null $wpml_compatibility_di
|
44 |
+
*/
|
45 |
+
public function __construct(
|
46 |
+
Toolset_Relationship_Database_Unique_Table_Alias $table_alias,
|
47 |
+
Toolset_Association_Query_Table_Join_Manager $join_manager,
|
48 |
+
wpdb $wpdb_di = null,
|
49 |
+
Toolset_Relationship_Database_Operations $database_operations_di = null,
|
50 |
+
Toolset_WPML_Compatibility $wpml_compatibility_di = null
|
51 |
+
) {
|
52 |
+
$this->table_alias = $table_alias;
|
53 |
+
$this->join_manager = $join_manager;
|
54 |
+
|
55 |
+
$this->database_operations = ( null === $database_operations_di ? new Toolset_Relationship_Database_Operations() : $database_operations_di );
|
56 |
+
$this->wpml_service = ( null === $wpml_compatibility_di ? Toolset_WPML_Compatibility::get_instance() : $wpml_compatibility_di );
|
57 |
+
|
58 |
+
global $wpdb;
|
59 |
+
$this->wpdb = ( null === $wpdb_di ? $wpdb : $wpdb_di );
|
60 |
+
}
|
61 |
+
|
62 |
+
|
63 |
+
/**
|
64 |
+
* @inheritdoc
|
65 |
+
*/
|
66 |
+
public function initialize() {
|
67 |
+
// Nothing to do here.
|
68 |
+
}
|
69 |
+
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Get the element ID column name of the associations table.
|
73 |
+
*
|
74 |
+
* @param IToolset_Relationship_Role $for_role
|
75 |
+
*
|
76 |
+
* @return string
|
77 |
+
*/
|
78 |
+
protected function get_id_column( IToolset_Relationship_Role $for_role ) {
|
79 |
+
return $this->database_operations->role_to_column(
|
80 |
+
$for_role, Toolset_Relationship_Database_Operations::COLUMN_ID
|
81 |
+
);
|
82 |
+
}
|
83 |
+
|
84 |
+
|
85 |
+
/**
|
86 |
+
* @inheritdoc
|
87 |
+
*
|
88 |
+
* @param IToolset_Relationship_Role $role
|
89 |
+
*/
|
90 |
+
public function request_element_in_results( IToolset_Relationship_Role $role ) {
|
91 |
+
$this->requested_roles[ $role->get_name() ] = $role;
|
92 |
+
}
|
93 |
+
|
94 |
+
|
95 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/association/query/element_selector/default.php
ADDED
@@ -0,0 +1,94 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Trivial element selector that works in the standard mode,
|
5 |
+
* if there is no need to translate anything.
|
6 |
+
*
|
7 |
+
* @since 2.5.10
|
8 |
+
*/
|
9 |
+
class Toolset_Association_Query_Element_Selector_Default
|
10 |
+
extends Toolset_Association_Query_Element_Selector_Abstract {
|
11 |
+
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @inheritdoc
|
15 |
+
*
|
16 |
+
* @param IToolset_Relationship_Role $for_role
|
17 |
+
* @param bool $translate_if_possible
|
18 |
+
*
|
19 |
+
* @return string
|
20 |
+
*/
|
21 |
+
public function get_element_id_alias(
|
22 |
+
IToolset_Relationship_Role $for_role, $translate_if_possible = true
|
23 |
+
) {
|
24 |
+
return $this->get_id_column( $for_role );
|
25 |
+
}
|
26 |
+
|
27 |
+
|
28 |
+
/**
|
29 |
+
* @inheritdoc
|
30 |
+
*
|
31 |
+
* @param IToolset_Relationship_Role $for_role
|
32 |
+
* @param bool $translate_if_possible
|
33 |
+
*
|
34 |
+
* @return string
|
35 |
+
*/
|
36 |
+
public function get_element_id_value(
|
37 |
+
IToolset_Relationship_Role $for_role, $translate_if_possible = true
|
38 |
+
) {
|
39 |
+
return $this->get_element_id_alias( $for_role );
|
40 |
+
}
|
41 |
+
|
42 |
+
|
43 |
+
/**
|
44 |
+
* @inheritdoc
|
45 |
+
*
|
46 |
+
* @return string
|
47 |
+
*/
|
48 |
+
public function get_select_clauses() {
|
49 |
+
$results = array();
|
50 |
+
foreach( $this->requested_roles as $role ) {
|
51 |
+
$results[] = $this->get_select_clause_for_role( $role );
|
52 |
+
}
|
53 |
+
|
54 |
+
return ' ' . implode( ', ', $results ) . ' ';
|
55 |
+
}
|
56 |
+
|
57 |
+
|
58 |
+
/**
|
59 |
+
* Generate a SELECT clause for a single role.
|
60 |
+
*
|
61 |
+
* @param IToolset_Relationship_Role $for_role
|
62 |
+
*
|
63 |
+
* @return string
|
64 |
+
*/
|
65 |
+
protected function get_select_clause_for_role( IToolset_Relationship_Role $for_role ) {
|
66 |
+
return sprintf(
|
67 |
+
'associations.%s AS %s',
|
68 |
+
$this->get_id_column( $for_role ),
|
69 |
+
$this->get_element_id_alias( $for_role )
|
70 |
+
);
|
71 |
+
}
|
72 |
+
|
73 |
+
|
74 |
+
/**
|
75 |
+
* @inheritdoc
|
76 |
+
*
|
77 |
+
* @return string
|
78 |
+
*/
|
79 |
+
public function get_join_clauses() {
|
80 |
+
return '';
|
81 |
+
}
|
82 |
+
|
83 |
+
|
84 |
+
/**
|
85 |
+
* Tell whether there may be a different element ID value for the current and the default language.
|
86 |
+
*
|
87 |
+
* @param IToolset_Relationship_Role $role
|
88 |
+
*
|
89 |
+
* @return mixed
|
90 |
+
*/
|
91 |
+
public function has_element_id_translated( IToolset_Relationship_Role $role ) {
|
92 |
+
return false;
|
93 |
+
}
|
94 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/association/query/element_selector/interface.php
ADDED
@@ -0,0 +1,93 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Manages the way element IDs are obtained when building the MySQL query for associations.
|
5 |
+
*
|
6 |
+
* Generates SELECT clauses for the element IDs. Allows for injecting additional JOIN clauses
|
7 |
+
* into the final query.
|
8 |
+
*
|
9 |
+
* @since 2.5.10
|
10 |
+
*/
|
11 |
+
interface IToolset_Association_Query_Element_Selector {
|
12 |
+
|
13 |
+
|
14 |
+
/**
|
15 |
+
* The element selector needs to be initialized early so that it can interact
|
16 |
+
* with the join manager object, if needed.
|
17 |
+
*
|
18 |
+
* See Toolset_Association_Query_Sql_Expression_Builder::build() for detailed information.
|
19 |
+
*
|
20 |
+
* @return void
|
21 |
+
*/
|
22 |
+
public function initialize();
|
23 |
+
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Get an alias for an element ID that will be used in the SELECT clause.
|
27 |
+
*
|
28 |
+
* @param IToolset_Relationship_Role $for_role
|
29 |
+
* @param bool $translate_if_possible
|
30 |
+
*
|
31 |
+
* @return string
|
32 |
+
*/
|
33 |
+
public function get_element_id_alias(
|
34 |
+
IToolset_Relationship_Role $for_role, $translate_if_possible = true
|
35 |
+
);
|
36 |
+
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Tell whether there may be a different element ID value for the current and the default language.
|
40 |
+
*
|
41 |
+
* @param IToolset_Relationship_Role $role
|
42 |
+
*
|
43 |
+
* @return mixed
|
44 |
+
*/
|
45 |
+
public function has_element_id_translated( IToolset_Relationship_Role $role );
|
46 |
+
|
47 |
+
|
48 |
+
/**
|
49 |
+
* Get a name of the table and the column that contains an element ID.
|
50 |
+
*
|
51 |
+
* This is different from the alias because it can be used within the query itself
|
52 |
+
* for other purposes.
|
53 |
+
*
|
54 |
+
* @param IToolset_Relationship_Role $for_role
|
55 |
+
* @param bool $translate_if_possible
|
56 |
+
*
|
57 |
+
* @return string Unambiguous "column" or "table.column" that contains ID of the element.
|
58 |
+
*/
|
59 |
+
public function get_element_id_value(
|
60 |
+
IToolset_Relationship_Role $for_role, $translate_if_possible = true
|
61 |
+
);
|
62 |
+
|
63 |
+
|
64 |
+
/**
|
65 |
+
* Get all the select clauses for all the element IDs.
|
66 |
+
*
|
67 |
+
* Individual clauses must be connected with a comma, but there must not be
|
68 |
+
* a trailing comma present.
|
69 |
+
*
|
70 |
+
* @return string
|
71 |
+
*/
|
72 |
+
public function get_select_clauses();
|
73 |
+
|
74 |
+
|
75 |
+
/**
|
76 |
+
* Get all JOIN clauses that need to be included in the query.
|
77 |
+
*
|
78 |
+
* The only assumption these JOINs can make is that there might be the relationships table joined
|
79 |
+
* first (if the element selector requires it). Anything else coming from the join manager
|
80 |
+
* will be joined after.
|
81 |
+
*
|
82 |
+
* @return string
|
83 |
+
*/
|
84 |
+
public function get_join_clauses();
|
85 |
+
|
86 |
+
|
87 |
+
/**
|
88 |
+
* @param IToolset_Relationship_Role $role
|
89 |
+
*
|
90 |
+
* @return void
|
91 |
+
*/
|
92 |
+
public function request_element_in_results( IToolset_Relationship_Role $role );
|
93 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/association/query/element_selector/provider.php
ADDED
@@ -0,0 +1,113 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Provider for the element selector.
|
5 |
+
*
|
6 |
+
* It creates the correct one depending on the state of WPML and the current language
|
7 |
+
* and then keeps providing the same instance every time.
|
8 |
+
*
|
9 |
+
* Together with the restriction that condition classes must not use the element selector
|
10 |
+
* in their constructor, this allows us to inject this dependency to query conditions
|
11 |
+
* but wait until all conditions are instantiated before we decide which element selector
|
12 |
+
* to actually use.
|
13 |
+
*
|
14 |
+
* @since 2.5.10
|
15 |
+
*/
|
16 |
+
class Toolset_Association_Query_Element_Selector_Provider {
|
17 |
+
|
18 |
+
|
19 |
+
const FILTER_WPML_SELECTOR = 'toolset_association_query_use_wpml_element_selector';
|
20 |
+
|
21 |
+
|
22 |
+
/** @var Toolset_Condition_Plugin_Wpml_Is_Active_And_Configured */
|
23 |
+
private $is_wpml_active;
|
24 |
+
|
25 |
+
|
26 |
+
/** @var Toolset_Condition_Plugin_Wpml_Is_Current_Language_Default */
|
27 |
+
private $is_current_language_default;
|
28 |
+
|
29 |
+
|
30 |
+
/** @var IToolset_Association_Query_Element_Selector|null */
|
31 |
+
private $selector;
|
32 |
+
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Toolset_Association_Query_Element_Selector_Provider constructor.
|
36 |
+
*
|
37 |
+
* @param Toolset_Condition_Plugin_Wpml_Is_Active_And_Configured|null $is_wpml_active_di
|
38 |
+
* @param Toolset_Condition_Plugin_Wpml_Is_Current_Language_Default|null $is_current_language_default_di
|
39 |
+
*/
|
40 |
+
public function __construct(
|
41 |
+
Toolset_Condition_Plugin_Wpml_Is_Active_And_Configured $is_wpml_active_di = null,
|
42 |
+
Toolset_Condition_Plugin_Wpml_Is_Current_Language_Default $is_current_language_default_di = null
|
43 |
+
) {
|
44 |
+
$this->is_wpml_active = ( null === $is_wpml_active_di ? new Toolset_Condition_Plugin_Wpml_Is_Active_And_Configured() : $is_wpml_active_di );
|
45 |
+
$this->is_current_language_default = ( null === $is_current_language_default_di ? new Toolset_Condition_Plugin_Wpml_Is_Current_Language_Default() : $is_current_language_default_di );
|
46 |
+
}
|
47 |
+
|
48 |
+
|
49 |
+
/**
|
50 |
+
* Get the selector instance once it has been created.
|
51 |
+
*
|
52 |
+
* @return IToolset_Association_Query_Element_Selector|null
|
53 |
+
*/
|
54 |
+
public function get_selector() {
|
55 |
+
return $this->selector;
|
56 |
+
}
|
57 |
+
|
58 |
+
|
59 |
+
/**
|
60 |
+
* Create an appropriate element selector.
|
61 |
+
*
|
62 |
+
* This can be called only once.
|
63 |
+
*
|
64 |
+
* @param Toolset_Relationship_Database_Unique_Table_Alias $table_alias
|
65 |
+
* @param Toolset_Association_Query_Table_Join_Manager $join_manager
|
66 |
+
* @param Toolset_Association_Query_V2 $query
|
67 |
+
*
|
68 |
+
* @return IToolset_Association_Query_Element_Selector
|
69 |
+
*
|
70 |
+
* @throws InvalidArgumentException
|
71 |
+
*/
|
72 |
+
public function create_selector(
|
73 |
+
Toolset_Relationship_Database_Unique_Table_Alias $table_alias,
|
74 |
+
Toolset_Association_Query_Table_Join_Manager $join_manager,
|
75 |
+
Toolset_Association_Query_V2 $query
|
76 |
+
) {
|
77 |
+
if( null !== $this->selector ) {
|
78 |
+
throw new RuntimeException( 'Element selector for the association query has already been created.' );
|
79 |
+
}
|
80 |
+
|
81 |
+
$this->selector = $this->instantiate_selector( $table_alias, $join_manager, $query );
|
82 |
+
|
83 |
+
return $this->selector;
|
84 |
+
}
|
85 |
+
|
86 |
+
|
87 |
+
/**
|
88 |
+
* @param Toolset_Relationship_Database_Unique_Table_Alias $table_alias
|
89 |
+
* @param Toolset_Association_Query_Table_Join_Manager $join_manager
|
90 |
+
* @param Toolset_Association_Query_V2 $query
|
91 |
+
* @return IToolset_Association_Query_Element_Selector
|
92 |
+
*/
|
93 |
+
private function instantiate_selector(
|
94 |
+
Toolset_Relationship_Database_Unique_Table_Alias $table_alias,
|
95 |
+
Toolset_Association_Query_Table_Join_Manager $join_manager,
|
96 |
+
Toolset_Association_Query_V2 $query
|
97 |
+
) {
|
98 |
+
if(
|
99 |
+
$this->is_wpml_active->is_met()
|
100 |
+
&& ! $this->is_current_language_default->is_met()
|
101 |
+
) {
|
102 |
+
$use_wpml_selector = apply_filters( self::FILTER_WPML_SELECTOR, true, $query );
|
103 |
+
|
104 |
+
if( $use_wpml_selector ) {
|
105 |
+
return new Toolset_Association_Query_Element_Selector_Wpml( $table_alias, $join_manager );
|
106 |
+
}
|
107 |
+
}
|
108 |
+
|
109 |
+
return new Toolset_Association_Query_Element_Selector_Default( $table_alias, $join_manager );
|
110 |
+
}
|
111 |
+
|
112 |
+
|
113 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/association/query/element_selector/wpml.php
ADDED
@@ -0,0 +1,257 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Element selector that translates post elements and chooses the best element ID
|
5 |
+
* (the translated one, but defaults to the original if the translation doesn't exist).
|
6 |
+
*
|
7 |
+
* @since 2.5.10
|
8 |
+
*/
|
9 |
+
class Toolset_Association_Query_Element_Selector_Wpml
|
10 |
+
extends Toolset_Association_Query_Element_Selector_Abstract {
|
11 |
+
|
12 |
+
|
13 |
+
/** @var bool */
|
14 |
+
private $is_ready = false;
|
15 |
+
|
16 |
+
|
17 |
+
/** @var string[] Indexed by role names. */
|
18 |
+
private $select_clauses = array();
|
19 |
+
|
20 |
+
|
21 |
+
/** @var string[] Indexed by role names. */
|
22 |
+
private $join_clauses = array();
|
23 |
+
|
24 |
+
|
25 |
+
/**
|
26 |
+
* @var string[] Aliases for original element IDs that will be used in the SELECT clause.
|
27 |
+
* Indexed by role names.
|
28 |
+
*/
|
29 |
+
private $original_element_id_select_aliases = array();
|
30 |
+
|
31 |
+
|
32 |
+
/**
|
33 |
+
* @var string[] Unambiguous column names for original element IDs that can be used
|
34 |
+
* within the rest of the MySQL query. Indexed by role names.
|
35 |
+
*/
|
36 |
+
private $original_element_id_values = array();
|
37 |
+
|
38 |
+
|
39 |
+
/**
|
40 |
+
* @var string[] Aliases for translated element IDs that will be used in the SELECT clause.
|
41 |
+
* Indexed by role names.
|
42 |
+
*/
|
43 |
+
private $translated_element_id_select_aliases = array();
|
44 |
+
|
45 |
+
|
46 |
+
/**
|
47 |
+
* @var string[] Expressions for translated element IDs that can be used
|
48 |
+
* within the rest of the MySQL query. Indexed by role names.
|
49 |
+
*/
|
50 |
+
private $translated_element_id_values = array();
|
51 |
+
|
52 |
+
|
53 |
+
/** @var IToolset_Relationship_Role[] */
|
54 |
+
private $requested_roles_in_join = array();
|
55 |
+
|
56 |
+
|
57 |
+
/**
|
58 |
+
* @inheritdoc
|
59 |
+
*/
|
60 |
+
public function initialize() {
|
61 |
+
if( $this->is_ready ) {
|
62 |
+
return;
|
63 |
+
}
|
64 |
+
|
65 |
+
foreach( Toolset_Relationship_Role::all() as $role ) {
|
66 |
+
$this->build_data_for_role( $role );
|
67 |
+
}
|
68 |
+
|
69 |
+
$this->is_ready = true;
|
70 |
+
}
|
71 |
+
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Build all parts of the query and other values needed for a single element role.
|
75 |
+
*
|
76 |
+
* @param IToolset_Relationship_Role $for_role
|
77 |
+
*/
|
78 |
+
private function build_data_for_role( IToolset_Relationship_Role $for_role ) {
|
79 |
+
|
80 |
+
// This is hardcoded across the association query classes.
|
81 |
+
$association_alias = 'associations';
|
82 |
+
|
83 |
+
$element_id_column = $this->get_id_column( $for_role );
|
84 |
+
|
85 |
+
// Require the JOIN of the relationships table.
|
86 |
+
$relationships_table_alias = $this->join_manager->relationships();
|
87 |
+
|
88 |
+
// Make sure that we translate only posts.
|
89 |
+
// No check for the intermediary ID because those are always posts by definition.
|
90 |
+
if( $for_role->is_parent_child() ) {
|
91 |
+
$element_domain_column = $this->database_operations->role_to_column(
|
92 |
+
$for_role, Toolset_Relationship_Database_Operations::COLUMN_DOMAIN
|
93 |
+
);
|
94 |
+
$posts_domain = esc_sql( Toolset_Element_Domain::POSTS );
|
95 |
+
// Note: Must end with "AND" so that another query can be concatenated immediately after.
|
96 |
+
$domain_query = "$relationships_table_alias.$element_domain_column = '$posts_domain' AND";
|
97 |
+
} else {
|
98 |
+
$domain_query = "";
|
99 |
+
}
|
100 |
+
|
101 |
+
$original_element_id_alias = 'original_' . $element_id_column;
|
102 |
+
|
103 |
+
// This is, however, usable only for the final SELECT clause as it will not an alias for
|
104 |
+
// an existing column, but for a COALESCE() result.
|
105 |
+
$translated_element_id_alias = 'translated_' . $element_id_column;
|
106 |
+
|
107 |
+
// Generate safe aliases for the icl_translations table.
|
108 |
+
// We need to JOIN it twice to get from the original element ID to the translated one.
|
109 |
+
$icl_translations = $this->wpdb->prefix . 'icl_translations';
|
110 |
+
$icl_translations_for_original = $this->table_alias->generate( $icl_translations, true );
|
111 |
+
$icl_translations_for_translation = $this->table_alias->generate( $icl_translations, true );
|
112 |
+
|
113 |
+
$current_language = esc_sql( $this->wpml_service->get_current_language() );
|
114 |
+
|
115 |
+
// Generate expressions with element IDs. The translated one will default to the original
|
116 |
+
// if no translation is available. This will be also extremely important for domains different
|
117 |
+
// than posts.
|
118 |
+
$translated_or_original_element_id = "COALESCE(
|
119 |
+
$icl_translations_for_translation.element_id, $association_alias.$element_id_column
|
120 |
+
)";
|
121 |
+
$original_element_id = "$association_alias.$element_id_column";
|
122 |
+
|
123 |
+
$this->select_clauses[ $for_role->get_name() ] =
|
124 |
+
"$original_element_id AS $original_element_id_alias,
|
125 |
+
$translated_or_original_element_id AS $translated_element_id_alias";
|
126 |
+
|
127 |
+
// LEFT joins are extremely important here.
|
128 |
+
$this->join_clauses[ $for_role->get_name() ] =
|
129 |
+
"LEFT JOIN $icl_translations AS $icl_translations_for_original
|
130 |
+
ON (
|
131 |
+
$domain_query
|
132 |
+
$icl_translations_for_original.element_id = $original_element_id
|
133 |
+
AND $icl_translations_for_original.element_type LIKE 'post_%'
|
134 |
+
)
|
135 |
+
LEFT JOIN $icl_translations AS $icl_translations_for_translation
|
136 |
+
ON (
|
137 |
+
$icl_translations_for_original.trid = $icl_translations_for_translation.trid
|
138 |
+
AND $icl_translations_for_translation.language_code = '$current_language'
|
139 |
+
)";
|
140 |
+
|
141 |
+
$this->original_element_id_select_aliases[ $for_role->get_name() ] = $original_element_id_alias;
|
142 |
+
$this->original_element_id_values[ $for_role->get_name() ] = $original_element_id;
|
143 |
+
$this->translated_element_id_select_aliases[ $for_role->get_name() ] = $translated_element_id_alias;
|
144 |
+
$this->translated_element_id_values[ $for_role->get_name() ] = $translated_or_original_element_id;
|
145 |
+
}
|
146 |
+
|
147 |
+
|
148 |
+
/**
|
149 |
+
* @inheritdoc
|
150 |
+
*
|
151 |
+
* @param IToolset_Relationship_Role $for_role
|
152 |
+
* @param bool $translate_if_possible
|
153 |
+
*
|
154 |
+
* @return string
|
155 |
+
*/
|
156 |
+
public function get_element_id_alias(
|
157 |
+
IToolset_Relationship_Role $for_role, $translate_if_possible = true
|
158 |
+
) {
|
159 |
+
$this->initialize();
|
160 |
+
$this->request_element_in_results( $for_role );
|
161 |
+
|
162 |
+
if( $translate_if_possible ) {
|
163 |
+
return $this->translated_element_id_select_aliases[ $for_role->get_name() ];
|
164 |
+
} else {
|
165 |
+
return $this->original_element_id_select_aliases[ $for_role->get_name() ];
|
166 |
+
}
|
167 |
+
}
|
168 |
+
|
169 |
+
|
170 |
+
/**
|
171 |
+
* @inheritdoc
|
172 |
+
*
|
173 |
+
* @param IToolset_Relationship_Role $for_role
|
174 |
+
* @param bool $translate_if_possible
|
175 |
+
*
|
176 |
+
* @return string
|
177 |
+
*/
|
178 |
+
public function get_element_id_value(
|
179 |
+
IToolset_Relationship_Role $for_role, $translate_if_possible = true
|
180 |
+
) {
|
181 |
+
$this->initialize();
|
182 |
+
|
183 |
+
// The element value is used only within the query itself, but not within the SELECT clause.
|
184 |
+
$this->request_element_in_join_only( $for_role );
|
185 |
+
|
186 |
+
if( $translate_if_possible ) {
|
187 |
+
return $this->translated_element_id_values[ $for_role->get_name() ];
|
188 |
+
} else {
|
189 |
+
return $this->original_element_id_values[ $for_role->get_name() ];
|
190 |
+
}
|
191 |
+
}
|
192 |
+
|
193 |
+
|
194 |
+
/**
|
195 |
+
* @inheritdoc
|
196 |
+
*
|
197 |
+
* @return string
|
198 |
+
*/
|
199 |
+
public function get_join_clauses() {
|
200 |
+
$this->initialize();
|
201 |
+
|
202 |
+
$requested_join_clauses = array();
|
203 |
+
foreach( $this->requested_roles_in_join as $role ) {
|
204 |
+
$requested_join_clauses[] = $this->join_clauses[ $role->get_name() ];
|
205 |
+
}
|
206 |
+
return ' ' . implode( ' ', $requested_join_clauses ) . ' ';
|
207 |
+
}
|
208 |
+
|
209 |
+
|
210 |
+
/**
|
211 |
+
* @inheritdoc
|
212 |
+
*
|
213 |
+
* @return string
|
214 |
+
*/
|
215 |
+
public function get_select_clauses() {
|
216 |
+
$this->initialize();
|
217 |
+
|
218 |
+
$requested_select_clauses = array();
|
219 |
+
foreach( $this->requested_roles as $role ) {
|
220 |
+
$requested_select_clauses[] = $this->select_clauses[ $role->get_name() ];
|
221 |
+
}
|
222 |
+
return ' ' . implode( ', ', $requested_select_clauses ) . ' ';
|
223 |
+
}
|
224 |
+
|
225 |
+
|
226 |
+
/**
|
227 |
+
* @inheritdoc
|
228 |
+
*
|
229 |
+
* @param IToolset_Relationship_Role $role
|
230 |
+
*/
|
231 |
+
public function request_element_in_results( IToolset_Relationship_Role $role ) {
|
232 |
+
parent::request_element_in_results( $role );
|
233 |
+
|
234 |
+
// Make sure that requested elements in results are superset of those requested in JOINs.
|
235 |
+
$this->request_element_in_join_only( $role );
|
236 |
+
}
|
237 |
+
|
238 |
+
|
239 |
+
/**
|
240 |
+
* @param IToolset_Relationship_Role $role
|
241 |
+
*/
|
242 |
+
public function request_element_in_join_only( IToolset_Relationship_Role $role ) {
|
243 |
+
$this->requested_roles_in_join[ $role->get_name() ] = $role;
|
244 |
+
}
|
245 |
+
|
246 |
+
|
247 |
+
/**
|
248 |
+
* Tell whether there may be a different element ID value for the current and the default language.
|
249 |
+
*
|
250 |
+
* @param IToolset_Relationship_Role $role
|
251 |
+
*
|
252 |
+
* @return mixed
|
253 |
+
*/
|
254 |
+
public function has_element_id_translated( IToolset_Relationship_Role $role ) {
|
255 |
+
return true; // This can be optimized in the future.
|
256 |
+
}
|
257 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/association/query/orderby/abstract.php
ADDED
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Shared functionality for most IToolset_Association_Query_Orderby classes.
|
5 |
+
*
|
6 |
+
* @since 2.5.8
|
7 |
+
*/
|
8 |
+
abstract class Toolset_Association_Query_Orderby implements IToolset_Association_Query_Orderby {
|
9 |
+
|
10 |
+
|
11 |
+
/** @var string */
|
12 |
+
protected $order = 'ASC';
|
13 |
+
|
14 |
+
|
15 |
+
/** @var Toolset_Association_Query_Table_Join_Manager */
|
16 |
+
protected $join_manager;
|
17 |
+
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Toolset_Association_Query_Orderby constructor.
|
21 |
+
*
|
22 |
+
* @param Toolset_Association_Query_Table_Join_Manager $join_manager
|
23 |
+
*/
|
24 |
+
public function __construct( Toolset_Association_Query_Table_Join_Manager $join_manager ) {
|
25 |
+
$this->join_manager = $join_manager;
|
26 |
+
}
|
27 |
+
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Set the direction of sorting.
|
31 |
+
*
|
32 |
+
* @param string $order 'ASC'|'DESC'
|
33 |
+
* @throws InvalidArgumentException
|
34 |
+
*/
|
35 |
+
public function set_order( $order ) {
|
36 |
+
$normalized_value = strtoupper( $order );
|
37 |
+
if( ! in_array( $normalized_value, array( 'ASC', 'DESC' ), true ) ) {
|
38 |
+
throw new InvalidArgumentException( 'Invalid order value.' );
|
39 |
+
}
|
40 |
+
|
41 |
+
$this->order = $normalized_value;
|
42 |
+
}
|
43 |
+
|
44 |
+
|
45 |
+
/**
|
46 |
+
* @inheritdoc
|
47 |
+
*/
|
48 |
+
public function register_joins() { }
|
49 |
+
|
50 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/association/query/orderby/interface.php
ADDED
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Interface for objects that handle the ORDER BY clause when building the association query.
|
5 |
+
*
|
6 |
+
* A dedicated set of classes is needed because sometimes, this also involves joining additional tables.
|
7 |
+
*
|
8 |
+
* @since 2.5.8
|
9 |
+
*/
|
10 |
+
interface IToolset_Association_Query_Orderby {
|
11 |
+
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Set the order direction.
|
15 |
+
*
|
16 |
+
* @param string $order 'ASC'|'DESC'
|
17 |
+
* @return void
|
18 |
+
*/
|
19 |
+
public function set_order( $order );
|
20 |
+
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Build the ORDER BY clause (not including the "ORDER BY" keyword).
|
24 |
+
*
|
25 |
+
* @return string
|
26 |
+
*/
|
27 |
+
public function get_orderby_clause();
|
28 |
+
|
29 |
+
|
30 |
+
/**
|
31 |
+
* If the class uses a join manager, request all needed joins now.
|
32 |
+
*
|
33 |
+
* @return void
|
34 |
+
*/
|
35 |
+
public function register_joins();
|
36 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/association/query/orderby/nothing.php
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Don't order associations by anything.
|
5 |
+
*
|
6 |
+
* @since 2.5.8
|
7 |
+
*/
|
8 |
+
class Toolset_Association_Query_Orderby_Nothing implements IToolset_Association_Query_Orderby {
|
9 |
+
|
10 |
+
public function get_orderby_clause() {
|
11 |
+
return '';
|
12 |
+
}
|
13 |
+
|
14 |
+
public function set_order( $order ) {
|
15 |
+
// Nothing to do here.
|
16 |
+
}
|
17 |
+
|
18 |
+
public function register_joins() {
|
19 |
+
// Nothing to do here.
|
20 |
+
}
|
21 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/association/query/orderby/postmeta.php
ADDED
@@ -0,0 +1,87 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Order associations by a postmeta value of an (post) element of given role.
|
5 |
+
*
|
6 |
+
* Note: Using this on an element of a wrong domain will exclude all associations from the results.
|
7 |
+
*
|
8 |
+
* @since 2.5.8
|
9 |
+
*/
|
10 |
+
class Toolset_Association_Query_Orderby_Postmeta extends Toolset_Association_Query_Orderby {
|
11 |
+
|
12 |
+
|
13 |
+
/** @var IToolset_Relationship_Role */
|
14 |
+
private $for_role;
|
15 |
+
|
16 |
+
|
17 |
+
/** @var string */
|
18 |
+
private $meta_key;
|
19 |
+
|
20 |
+
|
21 |
+
/**
|
22 |
+
* If the metakey needs to be casted into a different type (UNSIGNED, DATE, ..)
|
23 |
+
*
|
24 |
+
* @var string
|
25 |
+
*/
|
26 |
+
private $cast_to;
|
27 |
+
|
28 |
+
|
29 |
+
/**
|
30 |
+
* List of allowed casting types
|
31 |
+
*
|
32 |
+
* @var array
|
33 |
+
*/
|
34 |
+
private $allowed_mysql_types = array( 'SIGNED', 'UNSIGNED', 'DATE', 'DATETIME', 'CHAR' );
|
35 |
+
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Toolset_Association_Query_Orderby_Postmeta constructor.
|
39 |
+
*
|
40 |
+
* @param string $meta_key
|
41 |
+
* @param IToolset_Relationship_Role $role
|
42 |
+
* @param Toolset_Association_Query_Table_Join_Manager $join_manager
|
43 |
+
* @param string $cast_to If the metakey needs to be casted into a different type
|
44 |
+
* @throws InvalidArgumentException
|
45 |
+
*/
|
46 |
+
public function __construct(
|
47 |
+
$meta_key,
|
48 |
+
IToolset_Relationship_Role $role,
|
49 |
+
Toolset_Association_Query_Table_Join_Manager $join_manager,
|
50 |
+
$cast_to = null
|
51 |
+
) {
|
52 |
+
parent::__construct( $join_manager );
|
53 |
+
|
54 |
+
if ( ! is_string( $meta_key ) || empty( $meta_key ) ) {
|
55 |
+
throw new InvalidArgumentException();
|
56 |
+
}
|
57 |
+
|
58 |
+
$this->meta_key = $meta_key;
|
59 |
+
$this->for_role = $role;
|
60 |
+
if ( null !== $cast_to && ! in_array( strtoupper( $cast_to ), $this->allowed_mysql_types, true ) ) {
|
61 |
+
throw new InvalidArgumentException();
|
62 |
+
}
|
63 |
+
$this->cast_to = $cast_to;
|
64 |
+
}
|
65 |
+
|
66 |
+
|
67 |
+
/**
|
68 |
+
* @inheritdoc
|
69 |
+
*/
|
70 |
+
public function register_joins() {
|
71 |
+
$this->join_manager->wp_postmeta( $this->for_role, $this->meta_key );
|
72 |
+
}
|
73 |
+
|
74 |
+
|
75 |
+
/**
|
76 |
+
* @inheritdoc
|
77 |
+
* @return string
|
78 |
+
*/
|
79 |
+
public function get_orderby_clause() {
|
80 |
+
$postmeta_table_alias = $this->join_manager->wp_postmeta( $this->for_role, $this->meta_key );
|
81 |
+
if ( $this->cast_to ) {
|
82 |
+
return "CAST({$postmeta_table_alias}.meta_value AS {$this->cast_to}) {$this->order}";
|
83 |
+
} else {
|
84 |
+
return "{$postmeta_table_alias}.meta_value {$this->order}";
|
85 |
+
}
|
86 |
+
}
|
87 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/association/query/orderby/title.php
ADDED
@@ -0,0 +1,52 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Order associations by title of an element of given role.
|
5 |
+
*
|
6 |
+
* Note: Currently, only the posts domain is supported.
|
7 |
+
*
|
8 |
+
* Note: Ordering by intermediary posts will exclude associations that don't have one.
|
9 |
+
*
|
10 |
+
* @since 2.5.8
|
11 |
+
*/
|
12 |
+
class Toolset_Association_Query_Orderby_Title extends Toolset_Association_Query_Orderby {
|
13 |
+
|
14 |
+
|
15 |
+
/** @var IToolset_Relationship_Role */
|
16 |
+
private $for_role;
|
17 |
+
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Toolset_Association_Query_Orderby_Title constructor.
|
21 |
+
*
|
22 |
+
* @param IToolset_Relationship_Role $role
|
23 |
+
* @param Toolset_Association_Query_Table_Join_Manager $join_manager
|
24 |
+
*/
|
25 |
+
public function __construct(
|
26 |
+
IToolset_Relationship_Role $role,
|
27 |
+
Toolset_Association_Query_Table_Join_Manager $join_manager
|
28 |
+
) {
|
29 |
+
parent::__construct( $join_manager );
|
30 |
+
|
31 |
+
$this->for_role = $role;
|
32 |
+
}
|
33 |
+
|
34 |
+
|
35 |
+
/**
|
36 |
+
* @inheritdoc
|
37 |
+
*/
|
38 |
+
public function register_joins() {
|
39 |
+
$this->join_manager->wp_posts( $this->for_role );
|
40 |
+
}
|
41 |
+
|
42 |
+
|
43 |
+
/**
|
44 |
+
* @inheritdoc
|
45 |
+
* @return string
|
46 |
+
*/
|
47 |
+
public function get_orderby_clause() {
|
48 |
+
$posts_table_alias = $this->join_manager->wp_posts( $this->for_role );
|
49 |
+
|
50 |
+
return "{$posts_table_alias}.post_title {$this->order}";
|
51 |
+
}
|
52 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/association/query/orderby_factory.php
ADDED
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Factory for IToolset_Association_Query_Orderby.
|
5 |
+
*/
|
6 |
+
class Toolset_Association_Query_Orderby_Factory {
|
7 |
+
|
8 |
+
|
9 |
+
/**
|
10 |
+
* @return IToolset_Association_Query_Orderby
|
11 |
+
*/
|
12 |
+
public function nothing() {
|
13 |
+
return new Toolset_Association_Query_Orderby_Nothing();
|
14 |
+
}
|
15 |
+
|
16 |
+
|
17 |
+
/**
|
18 |
+
* @param IToolset_Relationship_Role $role
|
19 |
+
* @param Toolset_Association_Query_Table_Join_Manager $join_manager
|
20 |
+
*
|
21 |
+
* @return IToolset_Association_Query_Orderby
|
22 |
+
*/
|
23 |
+
public function title( IToolset_Relationship_Role $role, Toolset_Association_Query_Table_Join_Manager $join_manager ) {
|
24 |
+
return new Toolset_Association_Query_Orderby_Title( $role, $join_manager );
|
25 |
+
}
|
26 |
+
|
27 |
+
|
28 |
+
/**
|
29 |
+
* @param string $meta_key
|
30 |
+
* @param IToolset_Relationship_Role $role
|
31 |
+
* @param Toolset_Association_Query_Table_Join_Manager $join_manager
|
32 |
+
* @param string|null $cast_to If the metakey needs to be casted into a different type
|
33 |
+
*
|
34 |
+
* @return IToolset_Association_Query_Orderby
|
35 |
+
*/
|
36 |
+
public function postmeta( $meta_key, IToolset_Relationship_Role $role, Toolset_Association_Query_Table_Join_Manager $join_manager, $cast_to = null ) {
|
37 |
+
return new Toolset_Association_Query_Orderby_Postmeta( $meta_key, $role, $join_manager, $cast_to );
|
38 |
+
}
|
39 |
+
|
40 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/association/query/restriction/interface.php
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Represents an object that can restrict the association query in certain cases,
|
5 |
+
* making it less complex and more performant.
|
6 |
+
*
|
7 |
+
* Note: No implementation yet, but ideas:
|
8 |
+
* - disable the WPML version of element selector when it's not needed
|
9 |
+
* - the domain of all elements is known to be something non-translatable
|
10 |
+
* - the post types involved are all known and non-translatable
|
11 |
+
* - if the above is true only for one role, make the element selector use the non-WPML way
|
12 |
+
* only for that role
|
13 |
+
* - etc.
|
14 |
+
*
|
15 |
+
* @since 2.5.10
|
16 |
+
*/
|
17 |
+
interface IToolset_Association_Query_Restriction {
|
18 |
+
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Apply the restrictions.
|
22 |
+
*
|
23 |
+
* @return void
|
24 |
+
*/
|
25 |
+
public function apply();
|
26 |
+
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Clear the restrictions after the query has been run.
|
30 |
+
*
|
31 |
+
* @return void
|
32 |
+
*/
|
33 |
+
public function clear();
|
34 |
+
|
35 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/association/query/result_transformation/association_instance.php
ADDED
@@ -0,0 +1,145 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Transform association query results into instances of IToolset_Association.
|
5 |
+
*
|
6 |
+
* @since 2.5.8
|
7 |
+
*/
|
8 |
+
class Toolset_Association_Query_Result_Transformation_Association_Instance
|
9 |
+
implements IToolset_Association_Query_Result_Transformation {
|
10 |
+
|
11 |
+
|
12 |
+
/** @var Toolset_Association_Translator */
|
13 |
+
private $association_translator;
|
14 |
+
|
15 |
+
|
16 |
+
private $wpml_service;
|
17 |
+
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Toolset_Association_Query_Result_Transformation_Association_Instance constructor.
|
21 |
+
*
|
22 |
+
* @param Toolset_Association_Translator|null $association_translator_di
|
23 |
+
* @param Toolset_WPML_Compatibility|null $wpml_service
|
24 |
+
* @param Toolset_Condition_Plugin_Wpml_Is_Current_Language_Default|null $is_current_language_default_di
|
25 |
+
*/
|
26 |
+
public function __construct(
|
27 |
+
Toolset_Association_Translator $association_translator_di = null,
|
28 |
+
Toolset_WPML_Compatibility $wpml_service = null,
|
29 |
+
Toolset_Condition_Plugin_Wpml_Is_Current_Language_Default $is_current_language_default_di = null
|
30 |
+
) {
|
31 |
+
$this->wpml_service = ( null === $wpml_service ? Toolset_WPML_Compatibility::get_instance() : $wpml_service );
|
32 |
+
$this->association_translator = ( null === $association_translator_di ? new Toolset_Association_Translator() : $association_translator_di );
|
33 |
+
}
|
34 |
+
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @inheritdoc
|
38 |
+
*
|
39 |
+
* @param object $database_row
|
40 |
+
*
|
41 |
+
* @return IToolset_Association
|
42 |
+
*/
|
43 |
+
public function transform( $database_row, IToolset_Association_Query_Element_Selector $element_selector ) {
|
44 |
+
|
45 |
+
try {
|
46 |
+
if (
|
47 |
+
$this->wpml_service->is_wpml_active_and_configured()
|
48 |
+
&& $this->wpml_service->get_current_language() !== $this->wpml_service->get_default_language()
|
49 |
+
) {
|
50 |
+
// There's a chance of having element translations among the results. Let's try.
|
51 |
+
return $this->transform_with_wpml( $database_row, $element_selector );
|
52 |
+
}
|
53 |
+
|
54 |
+
return $this->transform_without_wpml( $database_row, $element_selector );
|
55 |
+
} catch( Toolset_Element_Exception_Element_Doesnt_Exist $e ) {
|
56 |
+
return null;
|
57 |
+
}
|
58 |
+
}
|
59 |
+
|
60 |
+
|
61 |
+
/**
|
62 |
+
* Transform the database row to an association instance if we know that there are no
|
63 |
+
* element translations involved.
|
64 |
+
*
|
65 |
+
* @param object $database_row
|
66 |
+
* @param IToolset_Association_Query_Element_Selector $element_selector
|
67 |
+
* @throws Toolset_Element_Exception_Element_Doesnt_Exist
|
68 |
+
* @return IToolset_Association
|
69 |
+
*/
|
70 |
+
private function transform_without_wpml( $database_row, IToolset_Association_Query_Element_Selector $element_selector ) {
|
71 |
+
$id_column_map = array();
|
72 |
+
foreach( Toolset_Relationship_Role::all() as $role ) {
|
73 |
+
$id_column_map[ $role->get_name() ] = $element_selector->get_element_id_alias( $role );
|
74 |
+
}
|
75 |
+
|
76 |
+
$association = $this->association_translator->from_database_row( $database_row, $id_column_map );
|
77 |
+
|
78 |
+
return $association;
|
79 |
+
|
80 |
+
}
|
81 |
+
|
82 |
+
|
83 |
+
/**
|
84 |
+
* Transform the database row to an association instance if there may be element translations.
|
85 |
+
*
|
86 |
+
* @param object $database_row
|
87 |
+
* @param IToolset_Association_Query_Element_Selector $element_selector
|
88 |
+
*
|
89 |
+
* @return IToolset_Association
|
90 |
+
*/
|
91 |
+
private function transform_with_wpml( $database_row, IToolset_Association_Query_Element_Selector $element_selector ) {
|
92 |
+
|
93 |
+
// The map must contain: role --> language code --> name of the column with element ID.
|
94 |
+
$id_column_map = array();
|
95 |
+
|
96 |
+
foreach( Toolset_Relationship_Role::all() as $role ) {
|
97 |
+
|
98 |
+
$default_language = $this->wpml_service->get_default_language();
|
99 |
+
$default_language_element_id_alias = $element_selector->get_element_id_alias( $role, false );
|
100 |
+
|
101 |
+
if ( $element_selector->has_element_id_translated( $role ) ) {
|
102 |
+
$current_language = $this->wpml_service->get_current_language();
|
103 |
+
$current_language_element_id_alias = $element_selector->get_element_id_alias( $role, true );
|
104 |
+
|
105 |
+
if( $database_row->$current_language_element_id_alias !== $database_row->$default_language_element_id_alias ) {
|
106 |
+
// We finally have two different element IDs - the default language and its translation.
|
107 |
+
$id_column_map[ $role->get_name() ] = array(
|
108 |
+
$current_language => $current_language_element_id_alias,
|
109 |
+
$default_language => $default_language_element_id_alias
|
110 |
+
);
|
111 |
+
continue;
|
112 |
+
}
|
113 |
+
}
|
114 |
+
|
115 |
+
// If we fall through to this point, there is only one (default) language version.
|
116 |
+
$id_column_map[ $role->get_name() ] = array(
|
117 |
+
$default_language => $default_language_element_id_alias,
|
118 |
+
);
|
119 |
+
}
|
120 |
+
|
121 |
+
$association = $this->association_translator->from_translated_database_row(
|
122 |
+
$database_row, $id_column_map
|
123 |
+
);
|
124 |
+
|
125 |
+
return $association;
|
126 |
+
|
127 |
+
}
|
128 |
+
|
129 |
+
|
130 |
+
/**
|
131 |
+
* Talk to the element selector so that it includes only elements that are actually needed.
|
132 |
+
*
|
133 |
+
* @param IToolset_Association_Query_Element_Selector $element_selector
|
134 |
+
*
|
135 |
+
* @return void
|
136 |
+
* @since 2.5.10
|
137 |
+
*/
|
138 |
+
public function request_element_selection( IToolset_Association_Query_Element_Selector $element_selector ) {
|
139 |
+
// Request all element IDs so that we can instantiate the association object.
|
140 |
+
foreach( Toolset_Relationship_Role::all() as $role ) {
|
141 |
+
$element_selector->request_element_in_results( $role );
|
142 |
+
}
|
143 |
+
}
|
144 |
+
|
145 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/association/query/result_transformation/association_uid.php
ADDED
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Transform association query results into association UIDs.
|
5 |
+
*
|
6 |
+
* @since 2.5.8
|
7 |
+
*/
|
8 |
+
class Toolset_Association_Query_Result_Transformation_Association_Uid
|
9 |
+
implements IToolset_Association_Query_Result_Transformation {
|
10 |
+
|
11 |
+
|
12 |
+
/**
|
13 |
+
* @inheritdoc
|
14 |
+
*
|
15 |
+
* @param object $database_row
|
16 |
+
*
|
17 |
+
* @return int
|
18 |
+
*/
|
19 |
+
public function transform(
|
20 |
+
$database_row, IToolset_Association_Query_Element_Selector $element_selector
|
21 |
+
) {
|
22 |
+
return (int) $database_row->id;
|
23 |
+
}
|
24 |
+
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Talk to the element selector so that it includes only elements that are actually needed.
|
28 |
+
*
|
29 |
+
* @param IToolset_Association_Query_Element_Selector $element_selector
|
30 |
+
*
|
31 |
+
* @return void
|
32 |
+
* @since 2.5.10
|
33 |
+
*/
|
34 |
+
public function request_element_selection( IToolset_Association_Query_Element_Selector $element_selector ) {
|
35 |
+
// Nothing to do here, as we're only returing the association UID and don't care
|
36 |
+
// about its elements.
|
37 |
+
}
|
38 |
+
|
39 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/association/query/result_transformation/element_id.php
ADDED
@@ -0,0 +1,52 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Transform association query results into element IDs of chosen role.
|
5 |
+
*
|
6 |
+
* @since 2.5.8
|
7 |
+
*/
|
8 |
+
class Toolset_Association_Query_Result_Transformation_Element_Id
|
9 |
+
implements IToolset_Association_Query_Result_Transformation {
|
10 |
+
|
11 |
+
|
12 |
+
/** @var IToolset_Relationship_Role */
|
13 |
+
private $role;
|
14 |
+
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Toolset_Association_Query_Result_Transformation_Element_Id constructor.
|
18 |
+
*
|
19 |
+
* @param IToolset_Relationship_Role $role
|
20 |
+
*/
|
21 |
+
public function __construct( IToolset_Relationship_Role $role ) {
|
22 |
+
$this->role = $role;
|
23 |
+
}
|
24 |
+
|
25 |
+
|
26 |
+
/**
|
27 |
+
* @inheritdoc
|
28 |
+
*
|
29 |
+
* @param object $database_row
|
30 |
+
*
|
31 |
+
* @return int
|
32 |
+
*/
|
33 |
+
public function transform(
|
34 |
+
$database_row, IToolset_Association_Query_Element_Selector $element_selector
|
35 |
+
) {
|
36 |
+
$column_name = $element_selector->get_element_id_alias( $this->role );
|
37 |
+
return (int) $database_row->$column_name;
|
38 |
+
}
|
39 |
+
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Talk to the element selector so that it includes only elements that are actually needed.
|
43 |
+
*
|
44 |
+
* @param IToolset_Association_Query_Element_Selector $element_selector
|
45 |
+
*
|
46 |
+
* @since 2.5.10
|
47 |
+
*/
|
48 |
+
public function request_element_selection( IToolset_Association_Query_Element_Selector $element_selector ) {
|
49 |
+
// We need only one element here.
|
50 |
+
$element_selector->request_element_in_results( $this->role );
|
51 |
+
}
|
52 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/association/query/result_transformation/element_instance.php
ADDED
@@ -0,0 +1,129 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Transform association query results into instances of elements of the chosen role.
|
5 |
+
*
|
6 |
+
* Note: At the moment, only the posts domain is supported.
|
7 |
+
*
|
8 |
+
* @since 2.5.8
|
9 |
+
*/
|
10 |
+
class Toolset_Association_Query_Result_Transformation_Element_Instance
|
11 |
+
implements IToolset_Association_Query_Result_Transformation {
|
12 |
+
|
13 |
+
|
14 |
+
/** @var IToolset_Relationship_Role */
|
15 |
+
private $role;
|
16 |
+
|
17 |
+
|
18 |
+
/** @var Toolset_Element_Factory */
|
19 |
+
private $element_factory;
|
20 |
+
|
21 |
+
|
22 |
+
private $wpml_service;
|
23 |
+
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Toolset_Association_Query_Result_Transformation_Element_Instance constructor.
|
27 |
+
*
|
28 |
+
* @param IToolset_Relationship_Role $role
|
29 |
+
* @param Toolset_Element_Factory|null $element_factory_di
|
30 |
+
* @param Toolset_WPML_Compatibility|null $wpml_service_di
|
31 |
+
*/
|
32 |
+
public function __construct(
|
33 |
+
IToolset_Relationship_Role $role,
|
34 |
+
Toolset_Element_Factory $element_factory_di = null,
|
35 |
+
Toolset_WPML_Compatibility $wpml_service_di = null
|
36 |
+
) {
|
37 |
+
$this->role = $role;
|
38 |
+
$this->wpml_service = ( null === $wpml_service_di ? Toolset_WPML_Compatibility::get_instance() : $wpml_service_di );
|
39 |
+
$this->element_factory = ( null === $element_factory_di ? new Toolset_Element_Factory() : $element_factory_di );
|
40 |
+
}
|
41 |
+
|
42 |
+
|
43 |
+
/**
|
44 |
+
* @inheritdoc
|
45 |
+
*
|
46 |
+
* Note: This will require some adjustments when other element domains are supported.
|
47 |
+
* The best course will be to instruct $element_selector to also include the relationships
|
48 |
+
* table in request_element_selection() and then obtain the domain information from there.
|
49 |
+
*
|
50 |
+
* @param object $database_row
|
51 |
+
* @return IToolset_Element
|
52 |
+
*/
|
53 |
+
public function transform(
|
54 |
+
$database_row, IToolset_Association_Query_Element_Selector $element_selector
|
55 |
+
) {
|
56 |
+
if(
|
57 |
+
$this->wpml_service->is_wpml_active_and_configured()
|
58 |
+
&& $element_selector->has_element_id_translated( $this->role )
|
59 |
+
&& $this->wpml_service->get_current_language() !== $this->wpml_service->get_default_language()
|
60 |
+
) {
|
61 |
+
// There's a chance of getting two language versions of the element, let's try.
|
62 |
+
return $this->transform_with_wpml( $database_row, $element_selector );
|
63 |
+
}
|
64 |
+
|
65 |
+
$element_id = $this->get_element_id( $database_row, $element_selector, true );
|
66 |
+
return $this->element_factory->get_element( Toolset_Element_Domain::POSTS, $element_id );
|
67 |
+
}
|
68 |
+
|
69 |
+
|
70 |
+
/**
|
71 |
+
* Determine if the desired element has two language versions and if it does,
|
72 |
+
* pass both of them to the factory object when instantiating the IToolset_Element model.
|
73 |
+
*
|
74 |
+
* @param object $database_row
|
75 |
+
* @param IToolset_Association_Query_Element_Selector $element_selector
|
76 |
+
*
|
77 |
+
* @return IToolset_Element
|
78 |
+
* @throws Toolset_Element_Exception_Element_Doesnt_Exist
|
79 |
+
*/
|
80 |
+
private function transform_with_wpml(
|
81 |
+
$database_row, IToolset_Association_Query_Element_Selector $element_selector
|
82 |
+
) {
|
83 |
+
$default_language_element_id = $this->get_element_id( $database_row, $element_selector, false );
|
84 |
+
$current_language_element_id = $this->get_element_id( $database_row, $element_selector, true );
|
85 |
+
|
86 |
+
if( $current_language_element_id === $default_language_element_id ) {
|
87 |
+
// Only a default language is available.
|
88 |
+
return $this->element_factory->get_element( Toolset_Element_Domain::POSTS, $current_language_element_id );
|
89 |
+
}
|
90 |
+
|
91 |
+
$element_ids = array(
|
92 |
+
$this->wpml_service->get_default_language() => $default_language_element_id,
|
93 |
+
$this->wpml_service->get_current_language() => $current_language_element_id
|
94 |
+
);
|
95 |
+
|
96 |
+
return $this->element_factory->get_element( Toolset_Element_Domain::POSTS, $element_ids );
|
97 |
+
}
|
98 |
+
|
99 |
+
|
100 |
+
/**
|
101 |
+
* Read an element ID from the database row.
|
102 |
+
*
|
103 |
+
* @param object $database_row
|
104 |
+
* @param IToolset_Association_Query_Element_Selector $element_selector
|
105 |
+
* @param bool $translate_if_possible Use the default language version or try using a translation?
|
106 |
+
*
|
107 |
+
* @return mixed
|
108 |
+
*/
|
109 |
+
private function get_element_id(
|
110 |
+
$database_row, IToolset_Association_Query_Element_Selector $element_selector, $translate_if_possible
|
111 |
+
) {
|
112 |
+
$column_name = $element_selector->get_element_id_alias( $this->role, $translate_if_possible );
|
113 |
+
return $database_row->$column_name;
|
114 |
+
}
|
115 |
+
|
116 |
+
|
117 |
+
/**
|
118 |
+
* Talk to the element selector so that it includes only elements that are actually needed.
|
119 |
+
*
|
120 |
+
* @param IToolset_Association_Query_Element_Selector $element_selector
|
121 |
+
*
|
122 |
+
* @since 2.5.10
|
123 |
+
*/
|
124 |
+
public function request_element_selection( IToolset_Association_Query_Element_Selector $element_selector ) {
|
125 |
+
// We need only one element here.
|
126 |
+
$element_selector->request_element_in_results( $this->role );
|
127 |
+
}
|
128 |
+
|
129 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/association/query/result_transformation/interface.php
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Interface IToolset_Association_Query_Result_Transformation
|
5 |
+
*
|
6 |
+
* Object that performs a transformation of a single database row from the
|
7 |
+
* association query into a the desired result.
|
8 |
+
*
|
9 |
+
* @since 2.5.8
|
10 |
+
*/
|
11 |
+
interface IToolset_Association_Query_Result_Transformation {
|
12 |
+
|
13 |
+
|
14 |
+
/**
|
15 |
+
* @param object $database_row It is safe to expect only properties that are always
|
16 |
+
* preset in results of a query from Toolset_Association_Query_Sql_Expression_Builder.
|
17 |
+
*
|
18 |
+
* @param IToolset_Association_Query_Element_Selector $element_selector
|
19 |
+
*
|
20 |
+
* @return mixed
|
21 |
+
*/
|
22 |
+
public function transform( $database_row, IToolset_Association_Query_Element_Selector $element_selector );
|
23 |
+
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Talk to the element selector so that it includes only elements that are actually needed.
|
27 |
+
*
|
28 |
+
* @param IToolset_Association_Query_Element_Selector $element_selector
|
29 |
+
*
|
30 |
+
* @return void
|
31 |
+
* @since 2.5.10
|
32 |
+
*/
|
33 |
+
public function request_element_selection( IToolset_Association_Query_Element_Selector $element_selector );
|
34 |
+
|
35 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/association/query/sql_expression_builder.php
ADDED
@@ -0,0 +1,139 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Builds the MySQL expression for the association query.
|
5 |
+
*
|
6 |
+
* @since 2.5.10
|
7 |
+
*/
|
8 |
+
class Toolset_Association_Query_Sql_Expression_Builder {
|
9 |
+
|
10 |
+
|
11 |
+
/** @var Toolset_Relationship_Database_Operations */
|
12 |
+
private $database_operations;
|
13 |
+
|
14 |
+
|
15 |
+
/** @var Toolset_Relationship_Table_Name */
|
16 |
+
private $table_name;
|
17 |
+
|
18 |
+
|
19 |
+
/** @var Toolset_Association_Query_Table_Join_Manager */
|
20 |
+
private $join_manager;
|
21 |
+
|
22 |
+
|
23 |
+
/**
|
24 |
+
* Toolset_Relationship_Query_Sql_Expression_Builder constructor.
|
25 |
+
*
|
26 |
+
* @param Toolset_Association_Query_Table_Join_Manager $join_manager
|
27 |
+
* @param Toolset_Relationship_Table_Name|null $table_name_di
|
28 |
+
* @param Toolset_Relationship_Database_Operations|null $database_operations_di
|
29 |
+
*/
|
30 |
+
public function __construct(
|
31 |
+
Toolset_Association_Query_Table_Join_Manager $join_manager,
|
32 |
+
Toolset_Relationship_Table_Name $table_name_di = null,
|
33 |
+
Toolset_Relationship_Database_Operations $database_operations_di = null
|
34 |
+
) {
|
35 |
+
$this->table_name = ( null === $table_name_di ? new Toolset_Relationship_Table_Name() : $table_name_di );
|
36 |
+
|
37 |
+
$this->database_operations = (
|
38 |
+
null === $database_operations_di
|
39 |
+
? new Toolset_Relationship_Database_Operations()
|
40 |
+
: $database_operations_di
|
41 |
+
);
|
42 |
+
|
43 |
+
$this->join_manager = $join_manager;
|
44 |
+
}
|
45 |
+
|
46 |
+
|
47 |
+
/**
|
48 |
+
* Build a complete MySQL query from the conditions.
|
49 |
+
*
|
50 |
+
* @param IToolset_Association_Query_Condition $root_condition
|
51 |
+
* @param int $offset
|
52 |
+
* @param int $limit
|
53 |
+
* @param IToolset_Association_Query_Orderby $orderby
|
54 |
+
* @param IToolset_Association_Query_Element_Selector $element_selector
|
55 |
+
* @param bool $need_found_rows
|
56 |
+
* @param IToolset_Association_Query_Result_Transformation $result_transformation
|
57 |
+
*
|
58 |
+
* @return string
|
59 |
+
*/
|
60 |
+
public function build(
|
61 |
+
IToolset_Association_Query_Condition $root_condition,
|
62 |
+
$offset,
|
63 |
+
$limit,
|
64 |
+
IToolset_Association_Query_Orderby $orderby,
|
65 |
+
IToolset_Association_Query_Element_Selector $element_selector,
|
66 |
+
$need_found_rows,
|
67 |
+
IToolset_Association_Query_Result_Transformation $result_transformation
|
68 |
+
) {
|
69 |
+
|
70 |
+
$associations_table = $this->table_name->association_table();
|
71 |
+
|
72 |
+
// Before building JOIN clauses, allow the ORDERBY builder also to add its own.
|
73 |
+
$orderby->register_joins();
|
74 |
+
// Same for the element selector. Otherwise the initialization would run
|
75 |
+
// from inside of $this->join_manager->get_join_clause() which is too late.
|
76 |
+
$element_selector->initialize();
|
77 |
+
|
78 |
+
// Conditions can either use the JOIN manager object to share JOINed tables
|
79 |
+
// or handle it entirely on their own. We need to get results from both sources here.
|
80 |
+
//
|
81 |
+
// Timing is extra important here: First, we get the JOIN clauses, so that the conditions
|
82 |
+
// can create table aliases that are later used when building the WHERE clauses.
|
83 |
+
//
|
84 |
+
// Then come ORDER BY clauses.
|
85 |
+
//
|
86 |
+
// Then we ask the result transformation object to talk to the element selector,
|
87 |
+
// and tell it which elements it will need in the select clause. This will
|
88 |
+
// influence the following step as well and can't be done later.
|
89 |
+
//
|
90 |
+
// Then we collect the JOIN clauses from the join manager object, which may have been used also
|
91 |
+
// when building the WHERE or ORDER BY clauses. This also includes JOINs coming from
|
92 |
+
// the element selector.
|
93 |
+
//
|
94 |
+
// Finally, we already know what we're going to need in the results and we can
|
95 |
+
// obtain the optimized select clauses from the element selector.
|
96 |
+
$join_clause = $root_condition->get_join_clause();
|
97 |
+
$where_clause = $root_condition->get_where_clause();
|
98 |
+
$orderby_clause = $orderby->get_orderby_clause();
|
99 |
+
$result_transformation->request_element_selection( $element_selector );
|
100 |
+
$join_clause = $this->join_manager->get_join_clause( $element_selector ) . ' ' . ' ' . $join_clause;
|
101 |
+
$select_elements = $element_selector->get_select_clauses();
|
102 |
+
// End of the timing-critical part.
|
103 |
+
|
104 |
+
$sql_found_rows = ( $need_found_rows ? 'SQL_CALC_FOUND_ROWS' : '' );
|
105 |
+
if( ! empty( $orderby_clause ) ) {
|
106 |
+
$orderby_clause = "ORDER BY $orderby_clause";
|
107 |
+
}
|
108 |
+
|
109 |
+
$limit = (int) $limit;
|
110 |
+
$offset = (int) $offset;
|
111 |
+
|
112 |
+
// Make sure we glue the pieces together well and leave no extra comma at the end
|
113 |
+
// in case $select_elements is empty.
|
114 |
+
$final_select_elements = array(
|
115 |
+
'associations.id AS id',
|
116 |
+
'associations.relationship_id AS relationship_id'
|
117 |
+
);
|
118 |
+
$select_elements_trimmed = trim( $select_elements );
|
119 |
+
if( ! empty( $select_elements_trimmed ) ) {
|
120 |
+
$final_select_elements[] = $select_elements;
|
121 |
+
}
|
122 |
+
$final_select_elements = implode( ', ' . PHP_EOL, $final_select_elements );
|
123 |
+
|
124 |
+
// We rely on all the moving parts which are supposed to have provided properly escaped strings.
|
125 |
+
$query = "
|
126 |
+
SELECT
|
127 |
+
{$sql_found_rows}
|
128 |
+
{$final_select_elements}
|
129 |
+
FROM {$associations_table} AS associations {$join_clause}
|
130 |
+
WHERE {$where_clause}
|
131 |
+
{$orderby_clause}
|
132 |
+
LIMIT {$limit}
|
133 |
+
OFFSET {$offset}";
|
134 |
+
|
135 |
+
return $query;
|
136 |
+
}
|
137 |
+
|
138 |
+
|
139 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/association/query/table_join_manager.php
ADDED
@@ -0,0 +1,209 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Manages JOIN clauses shared between different conditions within one association query.
|
5 |
+
*
|
6 |
+
* Use methods in this class to obtain aliases for the tables you need. By doing that,
|
7 |
+
* those tables will be added to the final JOIN clause. There is no risk of alias
|
8 |
+
* conflicts as long as all conditions use the same instance of
|
9 |
+
* Toolset_Relationship_Database_Unique_Table_Alias as is provided here in the constructor.
|
10 |
+
*
|
11 |
+
* @since 2.5.8
|
12 |
+
*/
|
13 |
+
class Toolset_Association_Query_Table_Join_Manager {
|
14 |
+
|
15 |
+
|
16 |
+
/** @var Toolset_Relationship_Database_Unique_Table_Alias */
|
17 |
+
private $unique_table_alias;
|
18 |
+
|
19 |
+
|
20 |
+
/** @var wpdb */
|
21 |
+
private $wpdb;
|
22 |
+
|
23 |
+
|
24 |
+
/** @var Toolset_Relationship_Database_Operations */
|
25 |
+
private $database_operations;
|
26 |
+
|
27 |
+
|
28 |
+
/** @var Toolset_Relationship_Table_Name */
|
29 |
+
private $table_name;
|
30 |
+
|
31 |
+
|
32 |
+
/** @var string[] Mapping of role names to aliases of JOINed wp_posts table. */
|
33 |
+
private $registered_wp_posts_joins = array();
|
34 |
+
|
35 |
+
|
36 |
+
/** @var string[][] Mapping of role names and meta_keys to aliases of JOINed wp_postmeta table. */
|
37 |
+
private $registered_wp_postmeta_joins = array();
|
38 |
+
|
39 |
+
|
40 |
+
/** @var bool Flag indicating that a relationships table also needs to be JOINed. */
|
41 |
+
private $join_relationships = false;
|
42 |
+
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Toolset_Association_Query_Table_Join_Manager constructor.
|
46 |
+
*
|
47 |
+
* @param Toolset_Relationship_Database_Unique_Table_Alias $unique_table_alias
|
48 |
+
* @param Toolset_Relationship_Database_Operations|null $database_operations_di
|
49 |
+
* @param Toolset_Relationship_Table_Name|null $table_name_di
|
50 |
+
* @param wpdb|null $wpdb_di
|
51 |
+
*/
|
52 |
+
public function __construct(
|
53 |
+
Toolset_Relationship_Database_Unique_Table_Alias $unique_table_alias,
|
54 |
+
Toolset_Relationship_Database_Operations $database_operations_di = null,
|
55 |
+
Toolset_Relationship_Table_Name $table_name_di = null,
|
56 |
+
wpdb $wpdb_di = null
|
57 |
+
) {
|
58 |
+
$this->unique_table_alias = $unique_table_alias;
|
59 |
+
|
60 |
+
if( null === $wpdb_di ) {
|
61 |
+
global $wpdb;
|
62 |
+
$this->wpdb = $wpdb;
|
63 |
+
} else {
|
64 |
+
$this->wpdb = $wpdb_di;
|
65 |
+
}
|
66 |
+
|
67 |
+
$this->database_operations = ( null === $database_operations_di ? new Toolset_Relationship_Database_Operations() : $database_operations_di );
|
68 |
+
$this->table_name = ( null === $table_name_di ? new Toolset_Relationship_Table_Name() : $table_name_di );
|
69 |
+
}
|
70 |
+
|
71 |
+
|
72 |
+
/**
|
73 |
+
* Get an alias for a wp_posts table JOINed on a particular element role.
|
74 |
+
*
|
75 |
+
* @param IToolset_Relationship_Role $for_role
|
76 |
+
* @return string Table alias.
|
77 |
+
*/
|
78 |
+
public function wp_posts( IToolset_Relationship_Role $for_role ) {
|
79 |
+
if( ! array_key_exists( $for_role->get_name(), $this->registered_wp_posts_joins ) ) {
|
80 |
+
$table_alias = $this->unique_table_alias->generate( $this->wpdb->posts, true );
|
81 |
+
$this->registered_wp_posts_joins[ $for_role->get_name() ] = $table_alias;
|
82 |
+
}
|
83 |
+
|
84 |
+
return $this->registered_wp_posts_joins[ $for_role->get_name() ];
|
85 |
+
}
|
86 |
+
|
87 |
+
|
88 |
+
/**
|
89 |
+
* Get an alias for a wp_postmeta table JOINed on a particular element role and a meta_key value.
|
90 |
+
*
|
91 |
+
* This creates LEFT JOIN clauses, so that even with missing postmeta, the end results are not affected.
|
92 |
+
*
|
93 |
+
* @param IToolset_Relationship_Role $for_role
|
94 |
+
* @param string $meta_key
|
95 |
+
*
|
96 |
+
* @return string
|
97 |
+
* @throws InvalidArgumentException
|
98 |
+
*/
|
99 |
+
public function wp_postmeta( IToolset_Relationship_Role $for_role, $meta_key ) {
|
100 |
+
if( ! is_string( $meta_key ) || empty( $meta_key ) ) {
|
101 |
+
throw new InvalidArgumentException();
|
102 |
+
}
|
103 |
+
|
104 |
+
$role_name = $for_role->get_name();
|
105 |
+
|
106 |
+
if(
|
107 |
+
null === toolset_getnest(
|
108 |
+
$this->registered_wp_postmeta_joins, array( $role_name, $meta_key ), null
|
109 |
+
)
|
110 |
+
) {
|
111 |
+
$table_alias = $this->unique_table_alias->generate( $this->wpdb->postmeta, true );
|
112 |
+
|
113 |
+
if( ! isset( $this->registered_wp_postmeta_joins[ $role_name ] ) ) {
|
114 |
+
$this->registered_wp_postmeta_joins[ $role_name ] = array();
|
115 |
+
}
|
116 |
+
|
117 |
+
$this->registered_wp_postmeta_joins[ $role_name ][ $meta_key ] = $table_alias;
|
118 |
+
}
|
119 |
+
|
120 |
+
return $this->registered_wp_postmeta_joins[ $role_name ][ $meta_key ];
|
121 |
+
}
|
122 |
+
|
123 |
+
|
124 |
+
/**
|
125 |
+
* Get an alias for a relationships table JOINed on the relationships_id column.
|
126 |
+
*
|
127 |
+
* @return string
|
128 |
+
*/
|
129 |
+
public function relationships() {
|
130 |
+
$this->join_relationships = true;
|
131 |
+
return 'relationships';
|
132 |
+
}
|
133 |
+
|
134 |
+
|
135 |
+
/**
|
136 |
+
* Build the final MySQL query part containing all requested JOIN clauses.
|
137 |
+
*
|
138 |
+
* @param IToolset_Association_Query_Element_Selector $element_selector
|
139 |
+
*
|
140 |
+
* @return string
|
141 |
+
*/
|
142 |
+
public function get_join_clause( IToolset_Association_Query_Element_Selector $element_selector ) {
|
143 |
+
|
144 |
+
// The order of JOINing is very important here:
|
145 |
+
//
|
146 |
+
// The JOINs coming from the element selector might reference the relationships table.
|
147 |
+
//
|
148 |
+
// Any other JOINs will be most probably referencing the elements, so they
|
149 |
+
// must be added only after the JOINs from the element selector.
|
150 |
+
//
|
151 |
+
// However, we first resolve those additional joins and only after that add the joins
|
152 |
+
// from the element selector. This way, the element selector will know exactly what
|
153 |
+
// element roles it can skip entirely (and save a lot of database performance if we have
|
154 |
+
// WPML active).
|
155 |
+
$results = array();
|
156 |
+
|
157 |
+
// JOINs that come after the relationships table and element selector JOINs
|
158 |
+
// but need to be determined in advance.
|
159 |
+
$additional_joins = array();
|
160 |
+
|
161 |
+
if( $this->join_relationships ) {
|
162 |
+
$results[] = sprintf(
|
163 |
+
' JOIN %s AS relationships ON ( associations.relationship_id = relationships.id ) ',
|
164 |
+
$this->table_name->relationship_table()
|
165 |
+
);
|
166 |
+
}
|
167 |
+
|
168 |
+
foreach( $this->registered_wp_posts_joins as $role_name => $table_alias ) {
|
169 |
+
$id_column_alias = $element_selector->get_element_id_value(
|
170 |
+
Toolset_Relationship_Role::role_from_name( $role_name )
|
171 |
+
);
|
172 |
+
|
173 |
+
$additional_joins[] = sprintf(
|
174 |
+
' JOIN %s AS %s ON (%s.ID = %s) ',
|
175 |
+
$this->wpdb->posts,
|
176 |
+
$table_alias,
|
177 |
+
$table_alias,
|
178 |
+
$id_column_alias
|
179 |
+
);
|
180 |
+
}
|
181 |
+
|
182 |
+
foreach( $this->registered_wp_postmeta_joins as $role_name => $postmeta_list ) {
|
183 |
+
foreach( $postmeta_list as $meta_key => $table_alias ) {
|
184 |
+
$id_column_alias = $element_selector->get_element_id_value(
|
185 |
+
Toolset_Relationship_Role::role_from_name( $role_name )
|
186 |
+
);
|
187 |
+
|
188 |
+
$additional_joins[] = sprintf(
|
189 |
+
" LEFT JOIN %s AS %s ON (%s.post_id = %s AND %s.meta_key = '%s') ",
|
190 |
+
$this->wpdb->postmeta,
|
191 |
+
$table_alias,
|
192 |
+
$table_alias,
|
193 |
+
$id_column_alias,
|
194 |
+
$table_alias,
|
195 |
+
esc_sql( $meta_key )
|
196 |
+
);
|
197 |
+
}
|
198 |
+
}
|
199 |
+
|
200 |
+
$results[] = $element_selector->get_join_clauses();
|
201 |
+
|
202 |
+
// Append the additonal JOINs after the relationships table and tables
|
203 |
+
// for the element ID resolution.
|
204 |
+
$results = array_merge( $results, $additional_joins );
|
205 |
+
|
206 |
+
return ' ' . implode( "\n", $results ) . ' ';
|
207 |
+
}
|
208 |
+
|
209 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/association/query/wpdb_wrapper.php
ADDED
@@ -0,0 +1,84 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* A wrapper class around a wpdb instance that redirects all calls to it, and
|
5 |
+
* allows to use all its properties, but overrides the value of $wpdb->posts to return
|
6 |
+
* an alias instead, that is specific for a selected element role.
|
7 |
+
*
|
8 |
+
* This is being used by Toolset_Association_Query_Condition_Wp_Query, check it for more information.
|
9 |
+
*
|
10 |
+
* @since 2.5.8
|
11 |
+
*/
|
12 |
+
class Toolset_Association_Query_Wpdb_Wrapper {
|
13 |
+
|
14 |
+
|
15 |
+
/** @var wpdb */
|
16 |
+
private $wpdb;
|
17 |
+
|
18 |
+
|
19 |
+
/** @var Toolset_Association_Query_Table_Join_Manager */
|
20 |
+
private $join_manager;
|
21 |
+
|
22 |
+
|
23 |
+
/** @var IToolset_Relationship_Role */
|
24 |
+
private $for_role;
|
25 |
+
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Toolset_Association_Query_Wpdb_Wrapper constructor.
|
29 |
+
*
|
30 |
+
* @param wpdb $wpdb
|
31 |
+
* @param Toolset_Association_Query_Table_Join_Manager $join_manager
|
32 |
+
* @param IToolset_Relationship_Role $for_role
|
33 |
+
*/
|
34 |
+
public function __construct(
|
35 |
+
wpdb $wpdb,
|
36 |
+
Toolset_Association_Query_Table_Join_Manager $join_manager,
|
37 |
+
IToolset_Relationship_Role $for_role
|
38 |
+
) {
|
39 |
+
$this->wpdb = $wpdb;
|
40 |
+
$this->join_manager = $join_manager;
|
41 |
+
$this->for_role = $for_role;
|
42 |
+
}
|
43 |
+
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Get a $wpdb property name.
|
47 |
+
*
|
48 |
+
* Override $wpdb->posts.
|
49 |
+
*
|
50 |
+
* @param string $property_name
|
51 |
+
* @return mixed
|
52 |
+
*/
|
53 |
+
public function __get( $property_name ) {
|
54 |
+
if( 'posts' === $property_name ) {
|
55 |
+
return $this->join_manager->wp_posts( $this->for_role );
|
56 |
+
}
|
57 |
+
|
58 |
+
return $this->wpdb->{$property_name};
|
59 |
+
}
|
60 |
+
|
61 |
+
|
62 |
+
/**
|
63 |
+
* Implement empty() and isset() checks for $wpdb properties.
|
64 |
+
*
|
65 |
+
* @param string $property_name
|
66 |
+
* @return bool
|
67 |
+
*/
|
68 |
+
public function __isset( $property_name ) {
|
69 |
+
return isset( $this->wpdb->{$property_name} );
|
70 |
+
}
|
71 |
+
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Call a method on $wpdb.
|
75 |
+
*
|
76 |
+
* @param string $method_name
|
77 |
+
* @param array $arguments
|
78 |
+
* @return mixed
|
79 |
+
*/
|
80 |
+
public function __call( $method_name, $arguments ) {
|
81 |
+
return call_user_func_array( array( $this->wpdb, $method_name ), $arguments );
|
82 |
+
}
|
83 |
+
|
84 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/association/translator.php
ADDED
@@ -0,0 +1,236 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Translate the association data between the IToolset_Association model and a database row.
|
5 |
+
*
|
6 |
+
* @since 2.5.9
|
7 |
+
*/
|
8 |
+
class Toolset_Association_Translator {
|
9 |
+
|
10 |
+
/** @var Toolset_Relationship_Definition_Repository|null */
|
11 |
+
private $_definition_repository;
|
12 |
+
|
13 |
+
/** @var Toolset_Association_Factory|null */
|
14 |
+
private $_association_factory;
|
15 |
+
|
16 |
+
/** @var null|Toolset_Element_Factory */
|
17 |
+
private $_element_factory;
|
18 |
+
|
19 |
+
|
20 |
+
/** @var Toolset_WPML_Compatibility */
|
21 |
+
private $wpml_service;
|
22 |
+
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Toolset_Association_Translator constructor.
|
26 |
+
*
|
27 |
+
* @param Toolset_Relationship_Definition_Repository|null $definition_repository_di
|
28 |
+
* @param Toolset_Association_Factory|null $association_factory_di
|
29 |
+
* @param Toolset_Element_Factory|null $element_factory_di
|
30 |
+
* @param Toolset_WPML_Compatibility|null $wpml_service_di
|
31 |
+
*/
|
32 |
+
public function __construct(
|
33 |
+
Toolset_Relationship_Definition_Repository $definition_repository_di = null,
|
34 |
+
Toolset_Association_Factory $association_factory_di = null,
|
35 |
+
Toolset_Element_Factory $element_factory_di = null,
|
36 |
+
Toolset_WPML_Compatibility $wpml_service_di = null
|
37 |
+
) {
|
38 |
+
$this->_definition_repository = $definition_repository_di;
|
39 |
+
$this->_association_factory = $association_factory_di;
|
40 |
+
$this->wpml_service = ( null === $wpml_service_di ? Toolset_WPML_Compatibility::get_instance() : $wpml_service_di );
|
41 |
+
$this->_element_factory = $element_factory_di;
|
42 |
+
}
|
43 |
+
|
44 |
+
|
45 |
+
private function get_definition_repository() {
|
46 |
+
if( null === $this->_definition_repository ) {
|
47 |
+
$this->_definition_repository = Toolset_Relationship_Definition_Repository::get_instance();
|
48 |
+
}
|
49 |
+
|
50 |
+
return $this->_definition_repository;
|
51 |
+
}
|
52 |
+
|
53 |
+
|
54 |
+
private function get_association_factory() {
|
55 |
+
if( null === $this->_association_factory ) {
|
56 |
+
$this->_association_factory = new Toolset_Association_Factory();
|
57 |
+
}
|
58 |
+
|
59 |
+
return $this->_association_factory;
|
60 |
+
}
|
61 |
+
|
62 |
+
|
63 |
+
|
64 |
+
/** @noinspection PhpDocRedundantThrowsInspection */
|
65 |
+
/**
|
66 |
+
* @param object $database_row Object returned from the wpdb->get_results() query.
|
67 |
+
* @param null|array $id_column_map Allows for overriding the names of the columns used to
|
68 |
+
* access element IDs. If not null, this must contain a map of columns for all three roles.
|
69 |
+
*
|
70 |
+
* @throws Toolset_Element_Exception_Element_Doesnt_Exist
|
71 |
+
* @return IToolset_Association
|
72 |
+
*/
|
73 |
+
public function from_database_row( $database_row, $id_column_map = null ) {
|
74 |
+
$relationship_definition = $this->get_definition_repository()->get_definition_by_row_id( $database_row->relationship_id );
|
75 |
+
|
76 |
+
if( null === $id_column_map ) {
|
77 |
+
$id_column_map = array(
|
78 |
+
Toolset_Relationship_Role::PARENT => 'parent_id',
|
79 |
+
Toolset_Relationship_Role::CHILD => 'child_id',
|
80 |
+
Toolset_Relationship_Role::INTERMEDIARY => 'intermediary_id',
|
81 |
+
);
|
82 |
+
}
|
83 |
+
|
84 |
+
return $this->get_association_factory()->create(
|
85 |
+
$relationship_definition,
|
86 |
+
(int) $database_row->{$id_column_map[ Toolset_Relationship_Role::PARENT ]},
|
87 |
+
(int) $database_row->{$id_column_map[ Toolset_Relationship_Role::CHILD ]},
|
88 |
+
(int) $database_row->{$id_column_map[ Toolset_Relationship_Role::INTERMEDIARY ]},
|
89 |
+
(int) $database_row->id
|
90 |
+
);
|
91 |
+
}
|
92 |
+
|
93 |
+
|
94 |
+
/**
|
95 |
+
* Translate a database row to an association instance if element translations are available.
|
96 |
+
*
|
97 |
+
* @param object $database_row
|
98 |
+
* @param array $id_column_map Nested associative array with:
|
99 |
+
* role --> language code --> name of the column with the element ID.
|
100 |
+
* In the database row, the IDs may be zero for translated (non-default language) parent
|
101 |
+
* or child or any intermediary posts.
|
102 |
+
*
|
103 |
+
* @return IToolset_Association
|
104 |
+
* @throws Toolset_Element_Exception_Element_Doesnt_Exist
|
105 |
+
*/
|
106 |
+
public function from_translated_database_row( $database_row, $id_column_map ) {
|
107 |
+
$relationship_definition = $this->get_definition_repository()->get_definition_by_row_id( $database_row->relationship_id );
|
108 |
+
|
109 |
+
$association = $this->get_association_factory()->create(
|
110 |
+
$relationship_definition,
|
111 |
+
$this->get_element_in_all_languages( $database_row, $id_column_map, $relationship_definition, new Toolset_Relationship_Role_Parent() ),
|
112 |
+
$this->get_element_in_all_languages( $database_row, $id_column_map, $relationship_definition, new Toolset_Relationship_Role_Child() ),
|
113 |
+
$this->get_element_in_all_languages( $database_row, $id_column_map, $relationship_definition, new Toolset_Relationship_Role_Intermediary() ),
|
114 |
+
(int) $database_row->id
|
115 |
+
);
|
116 |
+
|
117 |
+
return $association;
|
118 |
+
}
|
119 |
+
|
120 |
+
|
121 |
+
/**
|
122 |
+
* Get an element which contains all the available language information.
|
123 |
+
*
|
124 |
+
* @param $database_row
|
125 |
+
* @param array $id_column_map Map as described in from_translated_database_row().
|
126 |
+
* @param IToolset_Relationship_Definition $relationship_definition
|
127 |
+
* @param IToolset_Relationship_Role $for_role
|
128 |
+
*
|
129 |
+
* @return IToolset_Element|IToolset_Post|int Zero can be returned if there is no
|
130 |
+
* intermediary post at all.
|
131 |
+
* @throws Toolset_Element_Exception_Element_Doesnt_Exist
|
132 |
+
*/
|
133 |
+
private function get_element_in_all_languages(
|
134 |
+
$database_row,
|
135 |
+
$id_column_map,
|
136 |
+
IToolset_Relationship_Definition $relationship_definition,
|
137 |
+
IToolset_Relationship_Role $for_role
|
138 |
+
) {
|
139 |
+
$element_ids = array();
|
140 |
+
foreach( $id_column_map[ $for_role->get_name() ] as $language => $column ) {
|
141 |
+
$element_id = (int) $database_row->{$column};
|
142 |
+
if( 0 !== $element_id ) {
|
143 |
+
$element_ids[ $language ] = $element_id;
|
144 |
+
}
|
145 |
+
}
|
146 |
+
|
147 |
+
if( empty( $element_ids ) ) {
|
148 |
+
// This can happen for an intermediary post - no element to instantiate, and
|
149 |
+
// the association will survive.
|
150 |
+
return 0;
|
151 |
+
}
|
152 |
+
|
153 |
+
$element = $this->get_element_factory()->get_element(
|
154 |
+
$relationship_definition->get_element_type( $for_role )->get_domain(),
|
155 |
+
$element_ids
|
156 |
+
);
|
157 |
+
|
158 |
+
return $element;
|
159 |
+
}
|
160 |
+
|
161 |
+
|
162 |
+
/**
|
163 |
+
* @param IToolset_Association $association
|
164 |
+
* @throws RuntimeException
|
165 |
+
* @return array Database row as an associative array.
|
166 |
+
*/
|
167 |
+
public function to_database_row( IToolset_Association $association ) {
|
168 |
+
$row = array(
|
169 |
+
'relationship_id' => $association->get_definition()->get_row_id(),
|
170 |
+
'parent_id' => $this->get_default_language_element_id( $association, new Toolset_Relationship_Role_Parent() ),
|
171 |
+
'child_id' => $this->get_default_language_element_id( $association, new Toolset_Relationship_Role_Child() ),
|
172 |
+
'intermediary_id' => $this->get_default_language_element_id( $association, new Toolset_Relationship_Role_Intermediary() ),
|
173 |
+
);
|
174 |
+
|
175 |
+
return $row;
|
176 |
+
}
|
177 |
+
|
178 |
+
|
179 |
+
/**
|
180 |
+
* Obtain an element ID from the association for the purpose of saving it into database.
|
181 |
+
*
|
182 |
+
* If WPML is active, load the elements and make sure we're getting the ID
|
183 |
+
* of the default language version of the element.
|
184 |
+
*
|
185 |
+
* @param IToolset_Association $association
|
186 |
+
* @param IToolset_Relationship_Role $role
|
187 |
+
* @throws RuntimeException
|
188 |
+
*
|
189 |
+
* @return int
|
190 |
+
*/
|
191 |
+
private function get_default_language_element_id(
|
192 |
+
IToolset_Association $association,
|
193 |
+
IToolset_Relationship_Role $role
|
194 |
+
) {
|
195 |
+
if( ! $this->wpml_service->is_wpml_active_and_configured() ) {
|
196 |
+
return $association->get_element_id( $role );
|
197 |
+
}
|
198 |
+
|
199 |
+
$element = $association->get_element( $role );
|
200 |
+
|
201 |
+
if( null === $element ) {
|
202 |
+
// Intermediary post.
|
203 |
+
return 0;
|
204 |
+
}
|
205 |
+
|
206 |
+
$translation = $element->translate( $this->wpml_service->get_default_language(), true );
|
207 |
+
|
208 |
+
if( null === $translation ) {
|
209 |
+
throw new RuntimeException(
|
210 |
+
'The default language version of an element involved in an association is missing.'
|
211 |
+
);
|
212 |
+
}
|
213 |
+
|
214 |
+
return $translation->get_id();
|
215 |
+
}
|
216 |
+
|
217 |
+
|
218 |
+
/**
|
219 |
+
* @return string[] Column formats for columns as returned by to_database_row().
|
220 |
+
*/
|
221 |
+
public function get_database_row_formats() {
|
222 |
+
return array( '%d', '%d', '%d', '%d' );
|
223 |
+
}
|
224 |
+
|
225 |
+
|
226 |
+
/**
|
227 |
+
* @return Toolset_Element_Factory
|
228 |
+
*/
|
229 |
+
private function get_element_factory() {
|
230 |
+
if( null === $this->_element_factory ) {
|
231 |
+
$this->_element_factory = new Toolset_Element_Factory();
|
232 |
+
}
|
233 |
+
|
234 |
+
return $this->_element_factory;
|
235 |
+
}
|
236 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/association_base.php
DELETED
@@ -1,193 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Represents a single m2m association between two elements.
|
5 |
-
*
|
6 |
-
* Encapsulates the intermediary post and exposes only the generic API for working with association fields.
|
7 |
-
*
|
8 |
-
* There are two implementations, one is translation-aware and one is not.
|
9 |
-
* Both are to be instantiated exclusively through Toolset_Association_Repository.
|
10 |
-
*
|
11 |
-
* @since m2m
|
12 |
-
*/
|
13 |
-
abstract class Toolset_Association_Base implements IToolset_Association {
|
14 |
-
|
15 |
-
|
16 |
-
/** @var Toolset_Relationship_Definition */
|
17 |
-
private $relationship_definition;
|
18 |
-
|
19 |
-
/** @var Toolset_Element[] Actual elements, loaded on demand. Use self::get_element() to obtain them. */
|
20 |
-
protected $elements = array();
|
21 |
-
|
22 |
-
/** @var int Translation group ID. */
|
23 |
-
private $trid;
|
24 |
-
|
25 |
-
/** @var null|IToolset_Post */
|
26 |
-
protected $intermediary_post = null;
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
/**
|
31 |
-
* Toolset_Association_Base constructor.
|
32 |
-
*
|
33 |
-
* Note that no checks about elements with respect to the relationship definition are being performed here.
|
34 |
-
* The caller needs to ensure everything is valid (domains, types, other conditions). This is handled well in the
|
35 |
-
* association factory.
|
36 |
-
*
|
37 |
-
* @param int $trid Association translation ID (acting as an unique identifier).
|
38 |
-
* @param Toolset_Relationship_Definition $relationship_definition
|
39 |
-
* @throws InvalidArgumentException
|
40 |
-
* @since m2m
|
41 |
-
*/
|
42 |
-
public function __construct( $trid, Toolset_Relationship_Definition $relationship_definition ) {
|
43 |
-
|
44 |
-
if( ! Toolset_Utils::is_natural_numeric( $trid ) ) {
|
45 |
-
throw new InvalidArgumentException();
|
46 |
-
}
|
47 |
-
|
48 |
-
$this->relationship_definition = $relationship_definition;
|
49 |
-
|
50 |
-
$this->trid = (int) $trid;
|
51 |
-
|
52 |
-
}
|
53 |
-
|
54 |
-
|
55 |
-
/**
|
56 |
-
* @return Toolset_Relationship_Definition
|
57 |
-
*/
|
58 |
-
public function get_definition() { return $this->relationship_definition; }
|
59 |
-
|
60 |
-
|
61 |
-
/**
|
62 |
-
* Get domain of selected association element.
|
63 |
-
*
|
64 |
-
* @param string $element_role
|
65 |
-
*
|
66 |
-
* @return string Valid domain name as defined in Toolset_Field_Utils.
|
67 |
-
* @since m2m
|
68 |
-
*/
|
69 |
-
protected function get_element_domain( $element_role ) {
|
70 |
-
$relationship_definition = $this->get_definition();
|
71 |
-
$element_type = $relationship_definition->get_element_type( $element_role );
|
72 |
-
return $element_type->get_domain();
|
73 |
-
}
|
74 |
-
|
75 |
-
|
76 |
-
/**
|
77 |
-
* Get an association element.
|
78 |
-
*
|
79 |
-
* Instantiates an element if it hasn't been done yet.
|
80 |
-
*
|
81 |
-
* @param string $element_role
|
82 |
-
* @return Toolset_Element
|
83 |
-
* @throws InvalidArgumentException
|
84 |
-
* @since m2m
|
85 |
-
*/
|
86 |
-
public abstract function get_element( $element_role );
|
87 |
-
|
88 |
-
|
89 |
-
/**
|
90 |
-
* Check that the element role is valid.
|
91 |
-
*
|
92 |
-
* @param string $element_role
|
93 |
-
*
|
94 |
-
* @throws InvalidArgumentException
|
95 |
-
* @since m2m
|
96 |
-
* todo get rid of this, move to the enum
|
97 |
-
*/
|
98 |
-
public static function validate_element_role( $element_role ) {
|
99 |
-
if( ! in_array( $element_role, Toolset_Relationship_Role::parent_child_role_names() ) ) {
|
100 |
-
throw new InvalidArgumentException( 'Invalid element key.' );
|
101 |
-
}
|
102 |
-
}
|
103 |
-
|
104 |
-
|
105 |
-
/**
|
106 |
-
* Shortcut to the relationship driver.
|
107 |
-
*
|
108 |
-
* @return Toolset_Relationship_Driver_Base
|
109 |
-
*/
|
110 |
-
public function get_driver() {
|
111 |
-
$relationship_definition = $this->get_definition();
|
112 |
-
return $relationship_definition->get_driver();
|
113 |
-
}
|
114 |
-
|
115 |
-
|
116 |
-
/**
|
117 |
-
* Get the unique identifier for the association.
|
118 |
-
*
|
119 |
-
* We can use a trid which is unique per translation group (and per association if WPML is not active).
|
120 |
-
* If there's another implementation of associations in the future, it needs to use a string,
|
121 |
-
* perhaps with some sort of a prefix.
|
122 |
-
*
|
123 |
-
* @return int|string
|
124 |
-
* @since m2m
|
125 |
-
*/
|
126 |
-
public function get_uid() {
|
127 |
-
return $this->trid;
|
128 |
-
}
|
129 |
-
|
130 |
-
|
131 |
-
/**
|
132 |
-
* Get the translation group ID of the association.
|
133 |
-
*
|
134 |
-
* @return int Translation group ID or zero if not supported.
|
135 |
-
*/
|
136 |
-
public function get_trid() {
|
137 |
-
return $this->trid;
|
138 |
-
}
|
139 |
-
|
140 |
-
|
141 |
-
/**
|
142 |
-
* Get the intermediary post if it exists.
|
143 |
-
*
|
144 |
-
* @return null|Toolset_Post
|
145 |
-
*/
|
146 |
-
protected abstract function get_intermediary_post();
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
/**
|
151 |
-
* @inheritdoc
|
152 |
-
*
|
153 |
-
* This needs to be called (internally) before accessing the intermediary post object.
|
154 |
-
*
|
155 |
-
* @return bool
|
156 |
-
* @since m2m
|
157 |
-
*/
|
158 |
-
public function has_fields() {
|
159 |
-
|
160 |
-
$intermediary_post = $this->get_intermediary_post();
|
161 |
-
|
162 |
-
if ( null === $intermediary_post ) {
|
163 |
-
return false;
|
164 |
-
}
|
165 |
-
|
166 |
-
return ( $this->intermediary_post->get_field_count() > 0 );
|
167 |
-
}
|
168 |
-
|
169 |
-
|
170 |
-
/**
|
171 |
-
* @inheritdoc
|
172 |
-
*
|
173 |
-
* @param string|Toolset_Field_Definition $field_source
|
174 |
-
* @return bool
|
175 |
-
*/
|
176 |
-
public function has_field( $field_source ) {
|
177 |
-
if( ! $this->has_fields() ) {
|
178 |
-
return false;
|
179 |
-
}
|
180 |
-
|
181 |
-
return $this->intermediary_post->has_field( $field_source );
|
182 |
-
}
|
183 |
-
|
184 |
-
|
185 |
-
/**
|
186 |
-
* @return bool
|
187 |
-
* @since m2m
|
188 |
-
*/
|
189 |
-
public function has_intermediary_post() {
|
190 |
-
return ( null !== $this->get_intermediary_post() );
|
191 |
-
}
|
192 |
-
|
193 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/toolset/toolset-common/inc/m2m/association_query.php
DELETED
@@ -1,932 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* A class for querying associations and associated elements.
|
5 |
-
*
|
6 |
-
* Arguments:
|
7 |
-
* todo document
|
8 |
-
*
|
9 |
-
* Usage:
|
10 |
-
*
|
11 |
-
* $query = new Toolset_Association_Query( $args );
|
12 |
-
* $results = $query->get_results();
|
13 |
-
*
|
14 |
-
* Notes:
|
15 |
-
*
|
16 |
-
* - For now, it supports only the native associations (they're the only ones we have).
|
17 |
-
* - If you need to query by some parameters that are not supported, either create a feature request about it or
|
18 |
-
* submit a merge request rather than going around the query and touching the database directly.
|
19 |
-
*
|
20 |
-
*
|
21 |
-
* @since m2m
|
22 |
-
*/
|
23 |
-
class Toolset_Association_Query extends Toolset_Relationship_Query_Base {
|
24 |
-
|
25 |
-
/** @var string One of the RETURN_* constants determining what kind of output should be provided. */
|
26 |
-
private $return;
|
27 |
-
|
28 |
-
/** @var bool */
|
29 |
-
protected $dont_count_found_rows;
|
30 |
-
|
31 |
-
const OPTION_USE_CACHED_RESULTS = 'use_cached_results';
|
32 |
-
const OPTION_CACHE_RESULTS = 'cache_results';
|
33 |
-
const OPTION_RETURN = 'return';
|
34 |
-
const OPTION_DONT_COUNT_FOUND_ROWS = 'no_found_rows';
|
35 |
-
|
36 |
-
const QUERY_OFFSET = 'offset';
|
37 |
-
const QUERY_LIMIT = 'limit';
|
38 |
-
const QUERY_SELECT_FIELDS = 'select_fields';
|
39 |
-
const QUERY_RELATIONSHIP_SLUG = 'relationship_slug';
|
40 |
-
const QUERY_RELATIONSHIP_ID = 'relationship_id';
|
41 |
-
const QUERY_PARENT_ID = 'parent_id';
|
42 |
-
const QUERY_CHILD_ID = 'child_id';
|
43 |
-
const QUERY_HAS_FIELDS = 'has_fields';
|
44 |
-
const QUERY_PARENT_DOMAIN = 'parent_domain';
|
45 |
-
const QUERY_PARENT_QUERY = 'parent_query';
|
46 |
-
const QUERY_CHILD_DOMAIN = 'child_domain';
|
47 |
-
const QUERY_CHILD_QUERY = 'child_query';
|
48 |
-
const QUERY_LANGUAGE = 'language';
|
49 |
-
const QUERY_HAS_TRASHED_POSTS = 'has_trashed_posts';
|
50 |
-
|
51 |
-
const RETURN_ASSOCIATION_IDS = 'association_ids';
|
52 |
-
const RETURN_ASSOCIATIONS = 'associations';
|
53 |
-
const RETURN_PARENT_IDS = 'parent_ids';
|
54 |
-
const RETURN_CHILD_IDS = 'child_ids';
|
55 |
-
const RETURN_PARENTS = 'parents';
|
56 |
-
const RETURN_CHILDREN = 'children';
|
57 |
-
|
58 |
-
const LANGUAGE_ALL = 'all';
|
59 |
-
|
60 |
-
const GROUP_CONCAT_SEPARATOR = ',';
|
61 |
-
|
62 |
-
|
63 |
-
/**
|
64 |
-
* Parse query arguments, store them sanitized as options or in the $query_vars array.
|
65 |
-
*
|
66 |
-
* @param array $query
|
67 |
-
*/
|
68 |
-
protected function parse_query( $query ) {
|
69 |
-
|
70 |
-
$this->use_cached_results = (bool) toolset_getarr( $query, self::OPTION_USE_CACHED_RESULTS, true );
|
71 |
-
$this->cache_results = (bool) toolset_getarr( $query, self::OPTION_CACHE_RESULTS, true );
|
72 |
-
$this->return = toolset_getarr( $query, self::OPTION_RETURN, self::RETURN_ASSOCIATIONS, $this->get_return_options() );
|
73 |
-
$this->dont_count_found_rows = (bool) toolset_getarr( $query, self::OPTION_DONT_COUNT_FOUND_ROWS, false );
|
74 |
-
|
75 |
-
// Default value of these needs to be null
|
76 |
-
$this->parse_query_arg( $query, self::QUERY_RELATIONSHIP_SLUG, 'strval' );
|
77 |
-
$this->parse_query_arg( $query, self::QUERY_RELATIONSHIP_ID, 'absint' );
|
78 |
-
$this->parse_query_arg( $query, self::QUERY_PARENT_ID, 'absint' );
|
79 |
-
$this->parse_query_arg( $query, self::QUERY_CHILD_ID, 'absint' );
|
80 |
-
$this->parse_query_arg( $query, self::QUERY_LIMIT, 'absint' );
|
81 |
-
$this->parse_query_arg( $query, self::QUERY_OFFSET, 'absint' );
|
82 |
-
$this->parse_query_arg( $query, self::QUERY_SELECT_FIELDS, null, array() );
|
83 |
-
$this->parse_query_arg( $query, self::QUERY_HAS_FIELDS, 'boolval' );
|
84 |
-
$this->parse_query_arg( $query, self::QUERY_PARENT_DOMAIN, null, null, array( Toolset_Field_Utils::DOMAIN_POSTS ) );
|
85 |
-
$this->parse_query_arg( $query, self::QUERY_PARENT_QUERY, null ); // todo sanitize?
|
86 |
-
$this->parse_query_arg( $query, self::QUERY_CHILD_DOMAIN, null, null, array( Toolset_Field_Utils::DOMAIN_POSTS ) );
|
87 |
-
$this->parse_query_arg( $query, self::QUERY_CHILD_QUERY, null ); // todo sanitize?
|
88 |
-
$this->parse_query_arg( $query, self::QUERY_HAS_TRASHED_POSTS, 'boolval' );
|
89 |
-
}
|
90 |
-
|
91 |
-
|
92 |
-
/**
|
93 |
-
* Perform the query and get results.
|
94 |
-
*
|
95 |
-
* Depending on query arguments, the results may be cached.
|
96 |
-
*
|
97 |
-
* @return int[]|IToolset_Element[]|IToolset_Association[] Array of results, depending on query arguments.
|
98 |
-
*/
|
99 |
-
public function get_results() {
|
100 |
-
return parent::get_results();
|
101 |
-
}
|
102 |
-
|
103 |
-
|
104 |
-
protected function get_subject_name_for_cache() {
|
105 |
-
return 'associations';
|
106 |
-
}
|
107 |
-
|
108 |
-
|
109 |
-
/**
|
110 |
-
* Build the MySQL statement for querying the data, depending on query variables.
|
111 |
-
*
|
112 |
-
* @return string MySQL query statement.
|
113 |
-
* @since m2m
|
114 |
-
*/
|
115 |
-
protected function build_sql_statement() {
|
116 |
-
|
117 |
-
global $wpdb;
|
118 |
-
|
119 |
-
/// Condition clauses to be joined with AND.
|
120 |
-
$where_clauses = array();
|
121 |
-
|
122 |
-
$groupby_clauses = array();
|
123 |
-
$orderby_clauses = array();
|
124 |
-
|
125 |
-
// JOIN statements to be concatenated (they need to start with the JOIN keyword and have padding spaces).
|
126 |
-
// The original table to be joined to is the associations one (as 'association').
|
127 |
-
$join_clauses = array();
|
128 |
-
|
129 |
-
$having_clauses = array();
|
130 |
-
|
131 |
-
/// Setting this to true will result in joining the relationships table (as 'relationship').
|
132 |
-
$join_relationships = false;
|
133 |
-
|
134 |
-
/// If this is set to a column name, that column will be used as an post ID to join the wp_posts table
|
135 |
-
/// (as 'wp_posts'). Empty string means that the join is not needed.
|
136 |
-
$join_wp_posts_on = '';
|
137 |
-
|
138 |
-
$association_table = Toolset_Relationship_Table_Name::associations();
|
139 |
-
|
140 |
-
// If we have a query that is not specific to a particular language (association translation),
|
141 |
-
// we can avoid the self-join on the association table because we'll always have the whole
|
142 |
-
// translation group (same trid) in the results, or none of it.
|
143 |
-
//
|
144 |
-
// For example, when querying for a particular relationship slug, we know it isn't language-specific.
|
145 |
-
// On the other hand, querying for a specific parent_id will always get us only a single row for each trid.
|
146 |
-
//
|
147 |
-
// In that case, we must do the self-join in order to retrieve the information for all the relevant languages.
|
148 |
-
$has_language_specific_query = (
|
149 |
-
$this->has_query_var( self::QUERY_LANGUAGE )
|
150 |
-
&& self::LANGUAGE_ALL != $this->get_query_var( self::QUERY_LANGUAGE )
|
151 |
-
);
|
152 |
-
|
153 |
-
// Process individual query arguments.
|
154 |
-
//
|
155 |
-
//
|
156 |
-
if( $this->has_query_var( self::QUERY_RELATIONSHIP_SLUG ) ) {
|
157 |
-
$relationship_slug = $this->get_query_var( self::QUERY_RELATIONSHIP_SLUG );
|
158 |
-
$relationship = Toolset_Relationship_Utils::get_relationship_definition( $relationship_slug );
|
159 |
-
|
160 |
-
if( null === $relationship ) {
|
161 |
-
// This will cause the query to return no results, as there can be no associations
|
162 |
-
// for a non-existent relationship.
|
163 |
-
$relationship_id = 0;
|
164 |
-
} else {
|
165 |
-
$relationship_id = $relationship->get_row_id();
|
166 |
-
}
|
167 |
-
|
168 |
-
$where_clauses[] = $wpdb->prepare(
|
169 |
-
"association.relationship_id = %d",
|
170 |
-
$relationship_id
|
171 |
-
);
|
172 |
-
}
|
173 |
-
|
174 |
-
if( $this->has_query_var( self::QUERY_RELATIONSHIP_ID ) ) {
|
175 |
-
$relationship_id = $this->get_query_var( self::QUERY_RELATIONSHIP_ID );
|
176 |
-
|
177 |
-
$where_clauses[] = $wpdb->prepare(
|
178 |
-
"association.relationship_id = %d",
|
179 |
-
$relationship_id
|
180 |
-
);
|
181 |
-
}
|
182 |
-
|
183 |
-
if( $this->has_query_var( self::QUERY_PARENT_ID ) ) {
|
184 |
-
$where_clauses[] = $wpdb->prepare(
|
185 |
-
"parent_id = %d",
|
186 |
-
$this->get_query_var( self::QUERY_PARENT_ID )
|
187 |
-
);
|
188 |
-
|
189 |
-
$has_language_specific_query = true;
|
190 |
-
}
|
191 |
-
|
192 |
-
if( $this->has_query_var( self::QUERY_HAS_TRASHED_POSTS ) ) {
|
193 |
-
// Note: This is not very nice from the performance point of view, but it's only a hotfix.
|
194 |
-
// The query class will go through a refactoring very soon.
|
195 |
-
$join_clauses[] = " JOIN {$wpdb->posts} as wp_parent_post ON ( wp_parent_post.ID = association.parent_id ) ";
|
196 |
-
$join_clauses[] = " JOIN {$wpdb->posts} as wp_child_post ON ( wp_child_post.ID = association.child_id ) ";
|
197 |
-
|
198 |
-
$operator = ( $this->get_query_var( self::QUERY_HAS_TRASHED_POSTS ) ? '=' : '!=' );
|
199 |
-
$where_clauses[] = "wp_parent_post.post_status $operator 'trash'";
|
200 |
-
$where_clauses[] = "wp_child_post.post_status $operator 'trash'";
|
201 |
-
}
|
202 |
-
|
203 |
-
if( $this->has_query_var( self::QUERY_CHILD_ID ) ) {
|
204 |
-
$where_clauses[] = $wpdb->prepare(
|
205 |
-
"child_id = %d",
|
206 |
-
$this->get_query_var( self::QUERY_CHILD_ID )
|
207 |
-
);
|
208 |
-
|
209 |
-
$has_language_specific_query = true;
|
210 |
-
}
|
211 |
-
|
212 |
-
// Query only associations of relationships that have fields (that means they have an intermediary post type).
|
213 |
-
// todo we might want to handle a situation when an intermediary post type is modified to have no fields.
|
214 |
-
if( $this->has_query_var( self::QUERY_HAS_FIELDS ) ) {
|
215 |
-
$join_relationships = true;
|
216 |
-
$hasnt_fields_comparison = ( $this->get_query_var( self::QUERY_HAS_FIELDS ) ? 'NOT LIKE' : 'LIKE' );
|
217 |
-
$where_clauses[] = "relationship.intermediary_type {$hasnt_fields_comparison} ''";
|
218 |
-
}
|
219 |
-
|
220 |
-
if( $this->has_query_var( self::QUERY_PARENT_DOMAIN ) ) {
|
221 |
-
$join_relationships = true;
|
222 |
-
$where_clauses[] = $wpdb->prepare( 'relationship.parent_domain LIKE %s', $this->get_query_var( self::QUERY_PARENT_DOMAIN ) );
|
223 |
-
}
|
224 |
-
|
225 |
-
if( $this->has_query_var( self::QUERY_CHILD_DOMAIN ) ) {
|
226 |
-
$join_relationships = true;
|
227 |
-
$where_clauses[] = $wpdb->prepare( 'relationship.child_domain LIKE %s', $this->get_query_var( self::QUERY_CHILD_DOMAIN ) );
|
228 |
-
}
|
229 |
-
|
230 |
-
// Filter results by a native WordPress query run on child/parent posts.
|
231 |
-
//
|
232 |
-
// Since currently only post relationships are supported, we're always using WP_Query.
|
233 |
-
// We will obtain the list of MySQL clauses and merge them into our statement without actually querying anything yet.
|
234 |
-
// See get_wp_query_clauses() for the details.
|
235 |
-
$has_parent_query = $this->has_query_var( self::QUERY_PARENT_QUERY );
|
236 |
-
$has_child_query = $this->has_query_var( self::QUERY_CHILD_QUERY );
|
237 |
-
|
238 |
-
if( $has_parent_query && $has_child_query ) {
|
239 |
-
throw new RuntimeException( 'A assocation query cannot join parent and child on a single query.' );
|
240 |
-
}
|
241 |
-
|
242 |
-
if( $has_parent_query || $has_child_query ) {
|
243 |
-
$query_role = $has_child_query
|
244 |
-
? self::QUERY_CHILD_QUERY
|
245 |
-
: self::QUERY_PARENT_QUERY;
|
246 |
-
|
247 |
-
$join_wp_posts_on = $has_child_query
|
248 |
-
? 'child_id'
|
249 |
-
: 'parent_id';
|
250 |
-
|
251 |
-
$query_role = toolset_ensarr( $this->get_query_var( $query_role ) );
|
252 |
-
|
253 |
-
$clauses = $this->get_wp_query_clauses( $query_role );
|
254 |
-
|
255 |
-
// Include additional clauses to the final query.
|
256 |
-
//
|
257 |
-
// This should be safe because in WP_Query everything is properly referenced by table names
|
258 |
-
// and we're joining only custom Toolset tables and wp_posts.
|
259 |
-
//
|
260 |
-
// We're ignoring these clauses:
|
261 |
-
// - fields: because we have a custom mechanism of selecting them
|
262 |
-
// - limits: because those are overridden by offset and limit query args
|
263 |
-
|
264 |
-
// These clauses start with 'AND'
|
265 |
-
$where_clauses[] = ' 1 = 1 ' . $clauses['where'];
|
266 |
-
if( ! empty( $clauses['groupby'] ) ) {
|
267 |
-
$groupby_clauses[] = $clauses['groupby'];
|
268 |
-
}
|
269 |
-
|
270 |
-
if( ! empty( $clauses['join'] ) ) {
|
271 |
-
$join_clauses[] = $clauses['join'];
|
272 |
-
}
|
273 |
-
|
274 |
-
if( ! empty( $clauses['orderby'] ) ) {
|
275 |
-
$orderby_clauses[] = $clauses['orderby'];
|
276 |
-
}
|
277 |
-
|
278 |
-
// most probably yes
|
279 |
-
$has_language_specific_query = true;
|
280 |
-
}
|
281 |
-
|
282 |
-
|
283 |
-
// Determine if we're going to look for translations or not.
|
284 |
-
//
|
285 |
-
// With WPML inactive, the expected behaviour is to ignore all language-related information.
|
286 |
-
//
|
287 |
-
// Note that with the "transitional" multilingual mode, we are ignoring language information
|
288 |
-
// in the associations table, but it is there, and some association translations might have "holes"
|
289 |
-
// in them (missing element IDs where the element is not translated to a particular language).
|
290 |
-
// But at this point, we don't mind. It will be handled as a special case in postprocess_results().
|
291 |
-
if( Toolset_Relationship_Multilingual_Mode::is_on() ) {
|
292 |
-
|
293 |
-
if( $has_language_specific_query ) {
|
294 |
-
|
295 |
-
// Handle the query for a specific language.
|
296 |
-
//
|
297 |
-
// We will query for a single row within each translation group, then join the results with the
|
298 |
-
// association table again in order to get the information in all the languages we need.
|
299 |
-
if( $this->has_query_var( self::QUERY_LANGUAGE ) ) {
|
300 |
-
$preferred_language = $this->get_query_var( self::QUERY_LANGUAGE );
|
301 |
-
} else {
|
302 |
-
$preferred_language = Toolset_Wpml_Utils::get_current_language();
|
303 |
-
}
|
304 |
-
|
305 |
-
if( self::LANGUAGE_ALL != $preferred_language ) {
|
306 |
-
|
307 |
-
// Limit the result only for languages we care about.
|
308 |
-
//
|
309 |
-
// That is: specified language (or the current language), default site language and the
|
310 |
-
// original language of the association.
|
311 |
-
|
312 |
-
$language_clauses = array(
|
313 |
-
$wpdb->prepare( "translation.lang = %s", $preferred_language ),
|
314 |
-
"translation.translation_type IN ('none', 'original')"
|
315 |
-
);
|
316 |
-
|
317 |
-
$default_language = Toolset_Wpml_Utils::get_default_language();
|
318 |
-
if( $default_language !== $preferred_language ) {
|
319 |
-
$language_clauses[] = $wpdb->prepare( "translation.lang = %s", $default_language );
|
320 |
-
}
|
321 |
-
|
322 |
-
$language_clauses = sprintf(
|
323 |
-
'AND ( %s )',
|
324 |
-
implode( ' OR ', $language_clauses )
|
325 |
-
);
|
326 |
-
|
327 |
-
} else {
|
328 |
-
// This happens when specifically querying for all languages but there's another
|
329 |
-
// query argument which is language-specific.
|
330 |
-
$language_clauses = '';
|
331 |
-
}
|
332 |
-
|
333 |
-
$join_clauses[] = "
|
334 |
-
JOIN $association_table AS translation
|
335 |
-
ON (
|
336 |
-
association.trid = translation.trid
|
337 |
-
$language_clauses
|
338 |
-
)
|
339 |
-
";
|
340 |
-
|
341 |
-
$groupby_table = 'translation';
|
342 |
-
|
343 |
-
} else {
|
344 |
-
|
345 |
-
// We're not doing the self-join (there's no need for it because the query is not language-specific),
|
346 |
-
// so we're going to get the data from the associations table directly.
|
347 |
-
$groupby_table = 'association';
|
348 |
-
}
|
349 |
-
|
350 |
-
$groupby_clauses[] = "$groupby_table.trid";
|
351 |
-
|
352 |
-
// Prepare fields for the SELECT clause.
|
353 |
-
//
|
354 |
-
// In this case, we'll be concatenating results for all selected languages within a translation group
|
355 |
-
// in order to be able to use OFFSET and LIMIT consistently (one row == one actual result).
|
356 |
-
$sep = self::GROUP_CONCAT_SEPARATOR;
|
357 |
-
$select_fields = array(
|
358 |
-
'trid' => "$groupby_table.trid",
|
359 |
-
'relationship_id' => "GROUP_CONCAT($groupby_table.relationship_id SEPARATOR '$sep')",
|
360 |
-
'association_id' => "GROUP_CONCAT($groupby_table.id SEPARATOR '$sep')",
|
361 |
-
'lang' => "GROUP_CONCAT($groupby_table.lang SEPARATOR '$sep')",
|
362 |
-
'parent_id' => "GROUP_CONCAT($groupby_table.parent_id SEPARATOR '$sep')",
|
363 |
-
'child_id' => "GROUP_CONCAT($groupby_table.child_id SEPARATOR '$sep')",
|
364 |
-
'intermediary_id' => "GROUP_CONCAT($groupby_table.intermediary_id SEPARATOR '$sep')",
|
365 |
-
);
|
366 |
-
|
367 |
-
} else {
|
368 |
-
|
369 |
-
// The simplest case, there's no need to deal with translations at all.
|
370 |
-
$select_fields = array(
|
371 |
-
'trid' => 'association.trid',
|
372 |
-
'relationship_id' => 'association.relationship_id',
|
373 |
-
'association_id' => 'association.id',
|
374 |
-
'parent_id' => 'association.parent_id',
|
375 |
-
'child_id' => 'association.child_id',
|
376 |
-
'intermediary_id' => 'association.intermediary_id'
|
377 |
-
);
|
378 |
-
}
|
379 |
-
|
380 |
-
|
381 |
-
// Aggregate the information into parts of the final sql statement.
|
382 |
-
//
|
383 |
-
//
|
384 |
-
$sql_found_rows = ( $this->need_row_count() ? 'SQL_CALC_FOUND_ROWS' : '' );
|
385 |
-
|
386 |
-
array_walk( $select_fields, function( &$value, $key ) {
|
387 |
-
$value = $value . ' AS ' . $key;
|
388 |
-
});
|
389 |
-
|
390 |
-
// It could be necessary to add more fields to the select statement, for example due to the DISTINCT statement ORDER BY needs the field to be in the SELECT.
|
391 |
-
$extra_select_fields = $this->get_query_var( self::QUERY_SELECT_FIELDS );
|
392 |
-
if ( ! empty( $extra_select_fields ) ) {
|
393 |
-
$select_fields = array_merge( $select_fields, $extra_select_fields );
|
394 |
-
}
|
395 |
-
$sql_select = implode( ', ', $select_fields );
|
396 |
-
|
397 |
-
$sql_join = '';
|
398 |
-
if( $join_relationships ) {
|
399 |
-
$sql_join .= ' JOIN ' . Toolset_Relationship_Table_Name::relationships() . ' AS relationship
|
400 |
-
ON ( association.relationship_id LIKE relationship.id ) ';
|
401 |
-
}
|
402 |
-
if( ! empty( $join_wp_posts_on ) ) {
|
403 |
-
$sql_join .= " JOIN {$wpdb->posts} ON ( association.{$join_wp_posts_on} = {$wpdb->posts}.ID ) ";
|
404 |
-
}
|
405 |
-
$sql_join .= implode( $join_clauses );
|
406 |
-
|
407 |
-
$sql_from = "$association_table AS association $sql_join";
|
408 |
-
|
409 |
-
$sql_where = (
|
410 |
-
empty( $where_clauses )
|
411 |
-
? ' 1=1 '
|
412 |
-
: implode( ' AND ', $where_clauses )
|
413 |
-
);
|
414 |
-
|
415 |
-
if( $this->has_query_var( self::QUERY_LIMIT ) ) {
|
416 |
-
$sql_limits = 'LIMIT ';
|
417 |
-
if( $this->has_query_var( self::QUERY_OFFSET ) ) {
|
418 |
-
$sql_limits .= $this->get_query_var( self::QUERY_OFFSET ) . ', ';
|
419 |
-
}
|
420 |
-
$sql_limits .= $this->get_query_var( self::QUERY_LIMIT );
|
421 |
-
} else {
|
422 |
-
$sql_limits = '';
|
423 |
-
}
|
424 |
-
|
425 |
-
$sql_groupby = '';
|
426 |
-
if ( ! empty( $groupby_clauses ) ) {
|
427 |
-
$sql_groupby = 'GROUP BY ' . join( ', ', $groupby_clauses );
|
428 |
-
}
|
429 |
-
|
430 |
-
$sql_orderby = '';
|
431 |
-
if ( !empty( $orderby_clauses ) ) {
|
432 |
-
$sql_orderby = 'ORDER BY ' . implode( ', ', $orderby_clauses );
|
433 |
-
}
|
434 |
-
|
435 |
-
$sql_having = '';
|
436 |
-
if( ! empty( $having_clauses ) ) {
|
437 |
-
$sql_having = 'HAVING ( ' . implode( ' ) AND ( ', $having_clauses ) . ' ) ';
|
438 |
-
}
|
439 |
-
|
440 |
-
|
441 |
-
// Finally, one query to bind them all...
|
442 |
-
//
|
443 |
-
//
|
444 |
-
$query = "SELECT $sql_found_rows DISTINCT $sql_select FROM $sql_from WHERE $sql_where $sql_groupby $sql_having $sql_orderby $sql_limits";
|
445 |
-
|
446 |
-
return $query;
|
447 |
-
}
|
448 |
-
|
449 |
-
|
450 |
-
/**
|
451 |
-
* @inheritdoc
|
452 |
-
* @return string
|
453 |
-
*/
|
454 |
-
protected function get_results_type() {
|
455 |
-
return ARRAY_A;
|
456 |
-
}
|
457 |
-
|
458 |
-
|
459 |
-
/**
|
460 |
-
* Process raw output from $wpdb in a way defined by the 'return' query argument.
|
461 |
-
*
|
462 |
-
* @param $rows
|
463 |
-
*
|
464 |
-
* @return int[]|IToolset_Element[]|IToolset_Association[]
|
465 |
-
*/
|
466 |
-
protected function postprocess_results( $rows ) {
|
467 |
-
|
468 |
-
if( Toolset_Relationship_Multilingual_Mode::is_transitional() ) {
|
469 |
-
$rows = $this->preprocess_results_in_transitional_mode( $rows );
|
470 |
-
}
|
471 |
-
|
472 |
-
switch( $this->return ) {
|
473 |
-
case self::RETURN_ASSOCIATION_IDS:
|
474 |
-
return $this->postprocess_association_ids( $rows );
|
475 |
-
case self::RETURN_ASSOCIATIONS:
|
476 |
-
return $this->postprocess_associations( $rows );
|
477 |
-
case self::RETURN_PARENT_IDS:
|
478 |
-
return $this->postprocess_element_ids( $rows, Toolset_Relationship_Role::PARENT );
|
479 |
-
case self::RETURN_CHILD_IDS:
|
480 |
-
return $this->postprocess_element_ids( $rows, Toolset_Relationship_Role::CHILD );
|
481 |
-
case self::RETURN_PARENTS:
|
482 |
-
return $this->postprocess_elements( $rows, Toolset_Relationship_Role::PARENT );
|
483 |
-
case self::RETURN_CHILDREN:
|
484 |
-
return $this->postprocess_elements( $rows, Toolset_Relationship_Role::CHILD );
|
485 |
-
default:
|
486 |
-
// will never happen
|
487 |
-
return null;
|
488 |
-
}
|
489 |
-
|
490 |
-
}
|
491 |
-
|
492 |
-
|
493 |
-
/**
|
494 |
-
* Split single field's concatenated values by language.
|
495 |
-
*
|
496 |
-
* A database row from query results may contain more than one language version of the association,
|
497 |
-
* in which case its values are going to be concatenated in individual fields.
|
498 |
-
*
|
499 |
-
* This method converts a selected field into an associative array of values where keys are language codes.
|
500 |
-
* An empty string is used when there is no language defined.
|
501 |
-
*
|
502 |
-
* @param $row
|
503 |
-
* @param string $field_name
|
504 |
-
* @param null|string[] $language_codes Array of language codes if already extracted before. Must be an exact value.
|
505 |
-
* @param bool $skip_zeros If true, (numeric) zero field values will be skipped.
|
506 |
-
*
|
507 |
-
* @return array Field values with language codes as keys.
|
508 |
-
* @since m2m
|
509 |
-
*/
|
510 |
-
private function get_field_by_language( $row, $field_name, $language_codes = null, $skip_zeros = false ) {
|
511 |
-
|
512 |
-
if( null === $language_codes ) {
|
513 |
-
$language_codes = explode( self::GROUP_CONCAT_SEPARATOR, toolset_getarr( $row, 'lang' ) );
|
514 |
-
}
|
515 |
-
|
516 |
-
$result_count = count( $language_codes );
|
517 |
-
$field_values = explode( self::GROUP_CONCAT_SEPARATOR, toolset_getarr( $row, $field_name ) );
|
518 |
-
|
519 |
-
$results = array();
|
520 |
-
for( $i = 0; $i < $result_count; ++$i ) {
|
521 |
-
$field_value = $field_values[ $i ];
|
522 |
-
|
523 |
-
if( is_numeric( $field_value ) && 0 == $field_value && $skip_zeros ) {
|
524 |
-
continue;
|
525 |
-
}
|
526 |
-
|
527 |
-
$results[ $language_codes[ $i ] ] = $field_value;
|
528 |
-
}
|
529 |
-
|
530 |
-
return $results;
|
531 |
-
}
|
532 |
-
|
533 |
-
|
534 |
-
/**
|
535 |
-
* From raw query results, extract association IDs.
|
536 |
-
*
|
537 |
-
* If the associations are translated, the ID of the best translation is returned.
|
538 |
-
*
|
539 |
-
* @param $rows
|
540 |
-
*
|
541 |
-
* @return int[]
|
542 |
-
* @since m2m
|
543 |
-
*/
|
544 |
-
private function postprocess_association_ids( $rows ) {
|
545 |
-
|
546 |
-
$selected_ids = array();
|
547 |
-
|
548 |
-
foreach( $rows as $row ) {
|
549 |
-
|
550 |
-
$association_ids_by_language = $this->get_field_by_language( $row, 'association_id' );
|
551 |
-
|
552 |
-
$available_translations = array_keys( array_keys( $association_ids_by_language ) );
|
553 |
-
|
554 |
-
// Here we asking to always return any value but the result should make sense - only
|
555 |
-
// relevant languages should be queried by design (unless requesting 'all' languages,
|
556 |
-
// but in that case returning a random translation makes sense).
|
557 |
-
$selected_language = Toolset_Wpml_Utils::choose_best_translation( $available_translations, true );
|
558 |
-
|
559 |
-
$selected_ids[] = (int) toolset_getarr( $association_ids_by_language[ $selected_language ], 'id', 0 );
|
560 |
-
}
|
561 |
-
|
562 |
-
return array_unique( $selected_ids );
|
563 |
-
}
|
564 |
-
|
565 |
-
|
566 |
-
/**
|
567 |
-
* From raw query results, extract element IDs of chosen role.
|
568 |
-
*
|
569 |
-
* If the elements are translated, the ID of the best translation is returned for each of them.
|
570 |
-
*
|
571 |
-
* @param array $rows
|
572 |
-
* @param string $role Toolset_Relationship_Role value.
|
573 |
-
*
|
574 |
-
* @return int[] Element IDs.
|
575 |
-
* @since m2m
|
576 |
-
*/
|
577 |
-
private function postprocess_element_ids( $rows, $role ) {
|
578 |
-
|
579 |
-
$column_name = Toolset_Relationship_Database_Operations::get_instance()->role_to_column( $role );
|
580 |
-
|
581 |
-
if( Toolset_Relationship_Multilingual_Mode::is_on() ) {
|
582 |
-
$results = array();
|
583 |
-
foreach( $rows as $row ) {
|
584 |
-
$element_ids = $this->get_field_by_language( $row, $column_name, null, true );
|
585 |
-
// todo handle empty result (which should never happen)
|
586 |
-
$available_translations = array_keys( $element_ids );
|
587 |
-
$selected_language = Toolset_Wpml_Utils::choose_best_translation( $available_translations, true );
|
588 |
-
$results[] = $element_ids[ $selected_language ];
|
589 |
-
}
|
590 |
-
return $results;
|
591 |
-
} else {
|
592 |
-
return array_unique( wp_list_pluck( $rows, $column_name ) );
|
593 |
-
}
|
594 |
-
|
595 |
-
}
|
596 |
-
|
597 |
-
|
598 |
-
/**
|
599 |
-
* From raw query results, select elements with a certain role (parent or child are supported) and return them
|
600 |
-
* as Toolset_Element instances.
|
601 |
-
*
|
602 |
-
* Posts will also get information about translations if it is part of the results.
|
603 |
-
*
|
604 |
-
* @param array $rows Query results from wpdb.
|
605 |
-
* @param string $role ROLE_PARENT or ROLE_CHILD.
|
606 |
-
*
|
607 |
-
* @return Toolset_Element[]
|
608 |
-
*/
|
609 |
-
private function postprocess_elements( $rows, $role ) {
|
610 |
-
|
611 |
-
$column_name = Toolset_Relationship_Database_Operations::get_instance()->role_to_column( $role );
|
612 |
-
|
613 |
-
$results = array();
|
614 |
-
foreach( $rows as $row ) {
|
615 |
-
|
616 |
-
if( Toolset_Relationship_Multilingual_Mode::is_on() ) {
|
617 |
-
$relationship_slug = $this->get_field_by_language( $row, 'relationship' );
|
618 |
-
$relationship_slug = array_pop( $relationship_slug );
|
619 |
-
$element_source = $this->get_field_by_language( $row, $column_name );
|
620 |
-
} else {
|
621 |
-
$relationship_slug = toolset_getarr( $row, 'relationship' );
|
622 |
-
$element_source = (int) toolset_getarr( $row, $column_name );
|
623 |
-
}
|
624 |
-
|
625 |
-
// We need the relationship definition for determining the element domain.
|
626 |
-
$relationship_definition = Toolset_Relationship_Definition_Repository::get_instance()->get_definition( $relationship_slug );
|
627 |
-
|
628 |
-
// todo handle errors
|
629 |
-
try {
|
630 |
-
$resuts[] = Toolset_Element::get_instance(
|
631 |
-
$relationship_definition->get_domain( $role ),
|
632 |
-
$element_source
|
633 |
-
);
|
634 |
-
} catch(Exception $e) {
|
635 |
-
// skip missing post for now
|
636 |
-
}
|
637 |
-
}
|
638 |
-
|
639 |
-
return $results;
|
640 |
-
}
|
641 |
-
|
642 |
-
|
643 |
-
/**
|
644 |
-
* Use raw query results to return instances of Toolset_Association_Base.
|
645 |
-
*
|
646 |
-
* Even if multiple language variants are present, the associations will always be returned in an original
|
647 |
-
* version.
|
648 |
-
*
|
649 |
-
* @param array $rows
|
650 |
-
*
|
651 |
-
* @return IToolset_Association[]
|
652 |
-
*/
|
653 |
-
private function postprocess_associations( $rows ) {
|
654 |
-
|
655 |
-
$association_repository = Toolset_Association_Repository::get_instance();
|
656 |
-
|
657 |
-
$associations = array();
|
658 |
-
|
659 |
-
foreach( $rows as $row ) {
|
660 |
-
|
661 |
-
if( Toolset_Relationship_Multilingual_Mode::is_on() ) {
|
662 |
-
|
663 |
-
// Prepare language codes to optimize field reading below.
|
664 |
-
//
|
665 |
-
// Note that the language codes need to be in the exact order as in the results
|
666 |
-
// even with duplications.
|
667 |
-
$language_codes = explode( self::GROUP_CONCAT_SEPARATOR, toolset_getarr( $row, 'lang' ) );
|
668 |
-
|
669 |
-
$parent_source = $this->get_field_by_language( $row, 'parent_id', $language_codes, true );
|
670 |
-
$child_source = $this->get_field_by_language( $row, 'child_id', $language_codes, true );
|
671 |
-
|
672 |
-
$intermediary_source = $this->get_field_by_language( $row, 'intermediary_id', $language_codes, true );
|
673 |
-
if( empty( $intermediary_source ) ) {
|
674 |
-
$intermediary_source = 0;
|
675 |
-
}
|
676 |
-
|
677 |
-
// All relationship slugs should be the same, we just grab one of them.
|
678 |
-
$relationship_ids = $this->get_field_by_language( $row, 'relationship_id', $language_codes, true );
|
679 |
-
$relationship_id = (int) array_pop( $relationship_ids );
|
680 |
-
|
681 |
-
} else {
|
682 |
-
|
683 |
-
// Simple scenario, no GROUPBY_CONCAT results.
|
684 |
-
$parent_source = (int) toolset_getarr( $row, 'parent_id' );
|
685 |
-
$child_source = (int) toolset_getarr( $row, 'child_id' );
|
686 |
-
$intermediary_source = (int) toolset_getarr( $row, 'intermediary_id' );
|
687 |
-
$relationship_id = (int) toolset_getarr( $row, 'relationship_id' );
|
688 |
-
|
689 |
-
}
|
690 |
-
|
691 |
-
// todo sanitize, can be string
|
692 |
-
$association_trid = toolset_getarr( $row, 'trid' );
|
693 |
-
|
694 |
-
// Add the association to results.
|
695 |
-
try {
|
696 |
-
$association = $association_repository->instantiate(
|
697 |
-
$relationship_id,
|
698 |
-
$association_trid,
|
699 |
-
array(
|
700 |
-
Toolset_Relationship_Role::PARENT => $parent_source,
|
701 |
-
Toolset_Relationship_Role::CHILD => $child_source,
|
702 |
-
Toolset_Relationship_Role::INTERMEDIARY => $intermediary_source
|
703 |
-
)
|
704 |
-
);
|
705 |
-
|
706 |
-
$associations[] = $association;
|
707 |
-
|
708 |
-
} catch( Exception $e ) {
|
709 |
-
// The association couldn't have been loaded for some reason, we just skip it.
|
710 |
-
continue;
|
711 |
-
}
|
712 |
-
}
|
713 |
-
|
714 |
-
return $associations;
|
715 |
-
}
|
716 |
-
|
717 |
-
|
718 |
-
/**
|
719 |
-
* @return string[] Possible values for the 'return' query argument.
|
720 |
-
*/
|
721 |
-
private function get_return_options() {
|
722 |
-
return array(
|
723 |
-
self::RETURN_ASSOCIATIONS,
|
724 |
-
self::RETURN_ASSOCIATION_IDS,
|
725 |
-
self::RETURN_CHILD_IDS,
|
726 |
-
self::RETURN_CHILDREN,
|
727 |
-
self::RETURN_PARENT_IDS,
|
728 |
-
self::RETURN_PARENTS
|
729 |
-
);
|
730 |
-
}
|
731 |
-
|
732 |
-
|
733 |
-
/**
|
734 |
-
* Determine if SQL_CALC_FOUND_ROWS should be part of the MySQL statement.
|
735 |
-
*
|
736 |
-
* @return bool
|
737 |
-
*/
|
738 |
-
private function need_row_count() {
|
739 |
-
return ( ! $this->dont_count_found_rows && $this->has_query_var( self::QUERY_LIMIT ) );
|
740 |
-
}
|
741 |
-
|
742 |
-
|
743 |
-
/**
|
744 |
-
* Fool WP_Query into generating MySQL query clauses for given query arguments without actually executing the query.
|
745 |
-
*
|
746 |
-
* It also prevents WPML from modifying the query because filtering by language is handled elsewhere.
|
747 |
-
* It doesn't support sticky posts, filter suppressing and probably some complex use-cases.
|
748 |
-
*
|
749 |
-
* @param array $query_args Arguments for WP_Query.
|
750 |
-
* @return string[] MySQL clauses, for details see the posts_clauses filter.
|
751 |
-
* @since m2m
|
752 |
-
*/
|
753 |
-
private function get_wp_query_clauses( $query_args ) {
|
754 |
-
|
755 |
-
// Sticky posts are handled in a special way after the query takes place, so they would have no
|
756 |
-
// effect in any case. This is a performance optimalization.
|
757 |
-
$query_args['ignore_sticky_posts'] = true;
|
758 |
-
|
759 |
-
// Without this, we won't be able to get the clauses because the posts_clauses filter would not be applied.
|
760 |
-
$query_args['suppress_filters'] = false;
|
761 |
-
|
762 |
-
if( ! isset( $query_args['post_type'] ) ) {
|
763 |
-
// Get all associated post_types if none is defined
|
764 |
-
$query_args['post_type'] = 'any';
|
765 |
-
}
|
766 |
-
|
767 |
-
// This will hold the mysql clauses after WP_Query pushes them through the posts_pre_query filter.
|
768 |
-
$clauses_out = array();
|
769 |
-
|
770 |
-
$catch_clauses = function( $clauses_in ) use( &$clauses_out ) {
|
771 |
-
$clauses_out = $clauses_in;
|
772 |
-
};
|
773 |
-
|
774 |
-
// Filter priority
|
775 |
-
$very_late = 10000;
|
776 |
-
|
777 |
-
add_filter( 'posts_clauses', $catch_clauses, $very_late );
|
778 |
-
|
779 |
-
// Returning a non-null value on the posts_pre_query filter (since WP 4.6) causes that no actual
|
780 |
-
// mysql query takes place in WP_Query::get_posts().
|
781 |
-
$dont_query_anyting = function() { return array(); };
|
782 |
-
add_filter( 'posts_pre_query', $dont_query_anyting, $very_late );
|
783 |
-
|
784 |
-
// Avoid WPML messing with the results because we already know in which language we want to query
|
785 |
-
//$current_language = apply_filters( 'wpml_current_language', '' );
|
786 |
-
//do_action( 'wpml_switch_language', 'all' );
|
787 |
-
|
788 |
-
// This will immediately run the query.
|
789 |
-
new WP_Query( $query_args );
|
790 |
-
|
791 |
-
// Switch back to the current language so that we don't break anything else down the road.
|
792 |
-
//do_action( 'wpml_switch_language', $current_language );
|
793 |
-
|
794 |
-
// Clean up
|
795 |
-
remove_filter( 'posts_clauses', $catch_clauses, $very_late );
|
796 |
-
remove_filter( 'posts_pre_query', $dont_query_anyting, $very_late );
|
797 |
-
|
798 |
-
return $clauses_out;
|
799 |
-
}
|
800 |
-
|
801 |
-
|
802 |
-
/**
|
803 |
-
* Make sure that the query results contain the complete information and data integrity is maintained.
|
804 |
-
*
|
805 |
-
* When the multilingual mode is transitional (between switching WPML off and updating the associations
|
806 |
-
* table), we need to behave like it's off (no language information is taken into account) but with
|
807 |
-
* a database where we may have zero element IDs in any place (when a particular element translation
|
808 |
-
* didn't exist).
|
809 |
-
*
|
810 |
-
* In order to fill these holes, we do another query to get the original translation and the row with
|
811 |
-
* untranslatable element IDs (translation type "none"), merge this information and use it as a replacement
|
812 |
-
* when a "hole" is encountered in the original results.
|
813 |
-
*
|
814 |
-
* Furthermore, trid is supposed to be unique for each association, but the transitional mode breaks
|
815 |
-
* this invariant. In order to salvage it, we're going to construct a faux "trid" value which is unique.
|
816 |
-
* This value can be broken down to the original trid and association_id.
|
817 |
-
* Toolset_Association_Transitional was created to handle this rare difference.
|
818 |
-
*
|
819 |
-
* Finally, completing holes in results may lead to having duplicate results (with exactly the same
|
820 |
-
* relationship, (original) trid and triplets of element IDs). We need to get rid of those.
|
821 |
-
*
|
822 |
-
* This approach is rather performance-heavy, but I believe that's acceptable because the transitional
|
823 |
-
* mode is really supposed to be transitional, temporary, just a measure to avoid the site from
|
824 |
-
* breaking when WPML is deactivated.
|
825 |
-
*
|
826 |
-
* @param array $rows Raw output from database.
|
827 |
-
*
|
828 |
-
* @return array Updated and valid results.
|
829 |
-
*
|
830 |
-
* @since m2m
|
831 |
-
*/
|
832 |
-
private function preprocess_results_in_transitional_mode( $rows ) {
|
833 |
-
|
834 |
-
// Get all trids that appear within results
|
835 |
-
//
|
836 |
-
//
|
837 |
-
$trids = array();
|
838 |
-
foreach( $rows as $row ) {
|
839 |
-
$trids[] = (int) toolset_getarr( $row, 'trid' );
|
840 |
-
}
|
841 |
-
$trids = implode( ', ', array_unique( $trids ) );
|
842 |
-
|
843 |
-
// Get original translations and untranslated content for each trid
|
844 |
-
//
|
845 |
-
//
|
846 |
-
global $wpdb;
|
847 |
-
$associations_table = Toolset_Relationship_Table_Name::associations();
|
848 |
-
$trid_original_results = $wpdb->get_results(
|
849 |
-
"SELECT trid, parent_id, child_id, intermediary_id FROM {$associations_table} AS association
|
850 |
-
WHERE association.trid IN ({$trids})
|
851 |
-
AND association.translation_type IN ('original', 'none')",
|
852 |
-
ARRAY_A
|
853 |
-
);
|
854 |
-
|
855 |
-
// Merge nonzero element IDs from those translations
|
856 |
-
//
|
857 |
-
//
|
858 |
-
$trid_completion = array();
|
859 |
-
foreach( $trid_original_results as $row ) {
|
860 |
-
$trid = (int) toolset_getarr( $row, 'trid' );
|
861 |
-
$trid_completion[ $trid ] = $this->merge_rows(
|
862 |
-
toolset_ensarr( toolset_getarr( $trid_completion, $trid ) ),
|
863 |
-
$row
|
864 |
-
);
|
865 |
-
}
|
866 |
-
|
867 |
-
// Fill holes in query results
|
868 |
-
//
|
869 |
-
//
|
870 |
-
$results = array();
|
871 |
-
foreach( $rows as $row ) {
|
872 |
-
$trid = (int) toolset_getarr( $row, 'trid' );
|
873 |
-
$row = $this->merge_rows( $row, $trid_completion[ $trid ] );
|
874 |
-
|
875 |
-
// Avoid duplicating the same row (same meaning equal relationship, trid and element IDs)
|
876 |
-
$row_hash = $this->calculate_row_hash( $row );
|
877 |
-
if( array_key_exists( $row_hash, $results ) ) {
|
878 |
-
continue;
|
879 |
-
}
|
880 |
-
|
881 |
-
// Generate an unique trid for the row since this is not guaranteed in the transitional mode.
|
882 |
-
$id = (int) toolset_getarr( $row, 'association_id' );
|
883 |
-
$row['trid'] = sprintf( '\transitional\%d\%d', $trid, $id );
|
884 |
-
|
885 |
-
$results[ $row_hash ] = $row;
|
886 |
-
}
|
887 |
-
|
888 |
-
return $results;
|
889 |
-
}
|
890 |
-
|
891 |
-
|
892 |
-
/**
|
893 |
-
* Merge element IDs from completion row into the main one if the ID in the main one is zero.
|
894 |
-
*
|
895 |
-
* @param $main
|
896 |
-
* @param $completion
|
897 |
-
*
|
898 |
-
* @return array Main row, updated.
|
899 |
-
*/
|
900 |
-
private function merge_rows( $main, $completion ) {
|
901 |
-
foreach( Toolset_Relationship_Role::all_role_names() as $role ) {
|
902 |
-
$column_name = Toolset_Relationship_Database_Operations::get_instance()->role_to_column( $role );
|
903 |
-
$main_value = (int) toolset_getarr( $main, $column_name );
|
904 |
-
if( 0 === $main_value ) {
|
905 |
-
$main[ $column_name ] = (int) toolset_getarr( $completion, $column_name );
|
906 |
-
}
|
907 |
-
}
|
908 |
-
|
909 |
-
return $main;
|
910 |
-
}
|
911 |
-
|
912 |
-
|
913 |
-
/**
|
914 |
-
* Calculate a md5 hash of a database row, using relationship, trid and element IDs.
|
915 |
-
*
|
916 |
-
* @param $row
|
917 |
-
* @return string md5 hash value.
|
918 |
-
*/
|
919 |
-
private function calculate_row_hash( $row ) {
|
920 |
-
$md5_source = sprintf(
|
921 |
-
"%s_%d_%d_%d_%d",
|
922 |
-
toolset_getarr( $row, 'relationship' ),
|
923 |
-
(int) toolset_getarr( $row, 'trid' ),
|
924 |
-
(int) toolset_getarr( $row, 'parent_id' ),
|
925 |
-
(int) toolset_getarr( $row, 'child_id' ),
|
926 |
-
(int) toolset_getarr( $row, 'intermediary_id' )
|
927 |
-
);
|
928 |
-
|
929 |
-
return md5( $md5_source );
|
930 |
-
}
|
931 |
-
|
932 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/toolset/toolset-common/inc/m2m/association_repository.php
DELETED
@@ -1,260 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Repository for associations.
|
5 |
-
*
|
6 |
-
* Outside m2m API, only this object should be used to obtain instances of the IToolset_Association.
|
7 |
-
* Use it as a singleton in production code.
|
8 |
-
*
|
9 |
-
* @since m2m
|
10 |
-
*/
|
11 |
-
class Toolset_Association_Repository {
|
12 |
-
|
13 |
-
private static $instance;
|
14 |
-
|
15 |
-
/** @var Toolset_Relationship_Database_Operations|null */
|
16 |
-
private $_database_operations;
|
17 |
-
|
18 |
-
/** @var IToolset_Association[] */
|
19 |
-
private $associations_by_uid = array();
|
20 |
-
|
21 |
-
|
22 |
-
public static function get_instance() {
|
23 |
-
if( null === self::$instance ) {
|
24 |
-
self::$instance = new self();
|
25 |
-
}
|
26 |
-
|
27 |
-
return self::$instance;
|
28 |
-
}
|
29 |
-
|
30 |
-
|
31 |
-
public function __construct( Toolset_Relationship_Database_Operations $database_operations_di = null ) {
|
32 |
-
$this->_database_operations = $database_operations_di;
|
33 |
-
}
|
34 |
-
|
35 |
-
|
36 |
-
private function __clone() { }
|
37 |
-
|
38 |
-
|
39 |
-
/**
|
40 |
-
* Get an association by UID.
|
41 |
-
*
|
42 |
-
* Load it from database if needed.
|
43 |
-
*
|
44 |
-
* @param $association_uid
|
45 |
-
*
|
46 |
-
* @return null|IToolset_Association
|
47 |
-
*/
|
48 |
-
public function get( $association_uid ) {
|
49 |
-
if( $this->in_cache( $association_uid ) ) {
|
50 |
-
return $this->from_cache( $association_uid );
|
51 |
-
}
|
52 |
-
|
53 |
-
/**
|
54 |
-
* toolset_get_m2m_association_by_uid
|
55 |
-
*
|
56 |
-
* Allow for loading associations by UID by custom means.
|
57 |
-
*
|
58 |
-
* Note: To be enabled when actually needed.
|
59 |
-
*
|
60 |
-
* @param null $association Default value.
|
61 |
-
* @param int|string $association_uid UID of the association.
|
62 |
-
* @since m2m
|
63 |
-
*/
|
64 |
-
// $association = apply_filters( 'toolset_get_m2m_association_by_uid', null, $association_uid );
|
65 |
-
// if( ! $association instanceof IToolset_Association ) {
|
66 |
-
$association = $this->load_association_by_uid( $association_uid );
|
67 |
-
// }
|
68 |
-
|
69 |
-
$this->to_cache( $association_uid, $association );
|
70 |
-
|
71 |
-
return $association;
|
72 |
-
}
|
73 |
-
|
74 |
-
|
75 |
-
private function in_cache( $association_uid ) {
|
76 |
-
return array_key_exists( $association_uid, $this->associations_by_uid );
|
77 |
-
}
|
78 |
-
|
79 |
-
|
80 |
-
private function from_cache( $association_uid ) {
|
81 |
-
return $this->associations_by_uid[ $association_uid ];
|
82 |
-
}
|
83 |
-
|
84 |
-
|
85 |
-
private function to_cache( $association_uid, $association ) {
|
86 |
-
$this->associations_by_uid[ $association_uid ] = $association;
|
87 |
-
}
|
88 |
-
|
89 |
-
|
90 |
-
/**
|
91 |
-
* Load a native association from the database.
|
92 |
-
*
|
93 |
-
* @param int $association_uid Association UID.
|
94 |
-
*
|
95 |
-
* @return null|Toolset_Association The association instance or null if it couln't have been loaded.
|
96 |
-
*
|
97 |
-
* todo actually test this - maybe better use the query
|
98 |
-
*/
|
99 |
-
private function load_association_by_uid( $association_uid ) {
|
100 |
-
global $wpdb;
|
101 |
-
|
102 |
-
$associations_tn = Toolset_Relationship_Table_Name::associations();
|
103 |
-
|
104 |
-
$query = $wpdb->prepare( "SELECT * FROM {$associations_tn} WHERE trid = %d", $association_uid );
|
105 |
-
$row = $wpdb->get_row( $query );
|
106 |
-
|
107 |
-
if ( ! $row ) {
|
108 |
-
return null;
|
109 |
-
}
|
110 |
-
|
111 |
-
$relationship_definition = Toolset_Relationship_Definition_Repository::get_instance()
|
112 |
-
->get_definition_by_row_id( $row->relationship_id );
|
113 |
-
|
114 |
-
if ( null === $relationship_definition ) {
|
115 |
-
return null;
|
116 |
-
}
|
117 |
-
|
118 |
-
try {
|
119 |
-
$association = new Toolset_Association(
|
120 |
-
$row->trid,
|
121 |
-
$relationship_definition,
|
122 |
-
array(
|
123 |
-
Toolset_Relationship_Role::PARENT => $row->parent_id,
|
124 |
-
Toolset_Relationship_Role::CHILD => $row->child_id
|
125 |
-
),
|
126 |
-
$row->intermediary_id
|
127 |
-
);
|
128 |
-
|
129 |
-
} catch( Exception $e ) {
|
130 |
-
$association = null;
|
131 |
-
}
|
132 |
-
|
133 |
-
return $association;
|
134 |
-
|
135 |
-
}
|
136 |
-
|
137 |
-
|
138 |
-
/**
|
139 |
-
* Create an association instance from provided values.
|
140 |
-
*
|
141 |
-
* @param int|string|IToolset_Relationship_Definition $relationship_definition_source
|
142 |
-
* @param int|string $association_trid
|
143 |
-
* @param array $element_sources Elements indexed by role names - either Toolset_Element instances or ids (can be mixed).
|
144 |
-
*
|
145 |
-
* @return IToolset_Association
|
146 |
-
* @since m2m
|
147 |
-
*/
|
148 |
-
public function instantiate( $relationship_definition_source, $association_trid, $element_sources ) {
|
149 |
-
|
150 |
-
if( $this->in_cache( $association_trid ) ) {
|
151 |
-
return $this->from_cache( $association_trid );
|
152 |
-
}
|
153 |
-
|
154 |
-
$relationship_definition = Toolset_Relationship_Utils::get_relationship_definition( $relationship_definition_source );
|
155 |
-
if ( ! $relationship_definition instanceof Toolset_Relationship_Definition ) {
|
156 |
-
throw new InvalidArgumentException();
|
157 |
-
}
|
158 |
-
|
159 |
-
// todo Consider moving this part to the relationship driver.
|
160 |
-
// todo That would allow for adding other drivers in the future, and the instantiation
|
161 |
-
// todo and caching within this repository would work out of the box.
|
162 |
-
if(
|
163 |
-
Toolset_Relationship_Multilingual_Mode::is_on()
|
164 |
-
&& $relationship_definition->is_translatable() ) {
|
165 |
-
|
166 |
-
$association = new Toolset_Association_Translation_Set(
|
167 |
-
$association_trid,
|
168 |
-
$relationship_definition,
|
169 |
-
$element_sources
|
170 |
-
);
|
171 |
-
|
172 |
-
} elseif ( Toolset_Relationship_Multilingual_Mode::is_transitional() ) {
|
173 |
-
|
174 |
-
$association = new Toolset_Association_Transitional(
|
175 |
-
$association_trid,
|
176 |
-
$relationship_definition,
|
177 |
-
$element_sources,
|
178 |
-
toolset_getarr( $element_sources, Toolset_Relationship_Role::INTERMEDIARY, 0 )
|
179 |
-
);
|
180 |
-
|
181 |
-
} else {
|
182 |
-
|
183 |
-
$association = new Toolset_Association(
|
184 |
-
$association_trid,
|
185 |
-
$relationship_definition,
|
186 |
-
$element_sources,
|
187 |
-
toolset_getarr( $element_sources, Toolset_Relationship_Role::INTERMEDIARY, 0 )
|
188 |
-
);
|
189 |
-
|
190 |
-
}
|
191 |
-
|
192 |
-
$this->to_cache( $association->get_uid(), $association );
|
193 |
-
|
194 |
-
return $association;
|
195 |
-
}
|
196 |
-
|
197 |
-
|
198 |
-
/**
|
199 |
-
* @return Toolset_Relationship_Database_Operations
|
200 |
-
*/
|
201 |
-
private function get_database_operations() {
|
202 |
-
if( null === $this->_database_operations ) {
|
203 |
-
$this->_database_operations = new Toolset_Relationship_Database_Operations();
|
204 |
-
}
|
205 |
-
|
206 |
-
return $this->_database_operations;
|
207 |
-
}
|
208 |
-
|
209 |
-
|
210 |
-
/**
|
211 |
-
* Delete all associations from given relationship.
|
212 |
-
*
|
213 |
-
* @param IToolset_Relationship_Definition $relationship_definition
|
214 |
-
*
|
215 |
-
* @return Toolset_Result_Updated
|
216 |
-
*/
|
217 |
-
public function remove_by_relationship( IToolset_Relationship_Definition $relationship_definition ) {
|
218 |
-
|
219 |
-
foreach( $this->associations_by_uid as $association_uid => $association ) {
|
220 |
-
if( $association->get_definition()->get_slug() === $relationship_definition->get_slug() ) {
|
221 |
-
unset( $this->associations_by_uid[ $association_uid ] );
|
222 |
-
}
|
223 |
-
}
|
224 |
-
|
225 |
-
/** @var Toolset_Relationship_Definition $relationship_definition */
|
226 |
-
return $this->get_database_operations()->delete_associations_by_relationship( $relationship_definition->get_row_id() );
|
227 |
-
}
|
228 |
-
|
229 |
-
|
230 |
-
/**
|
231 |
-
* @param IToolset_Element $element
|
232 |
-
*/
|
233 |
-
public function delete_associations_involving_element( $element ) {
|
234 |
-
|
235 |
-
$query_parent = new Toolset_Association_Query( array(
|
236 |
-
Toolset_Association_Query::QUERY_PARENT_DOMAIN => $element->get_domain(),
|
237 |
-
Toolset_Association_Query::QUERY_PARENT_ID => $element->get_id(),
|
238 |
-
Toolset_Association_Query::OPTION_RETURN => Toolset_Association_Query::RETURN_ASSOCIATIONS
|
239 |
-
) );
|
240 |
-
|
241 |
-
$associations = $query_parent->get_results();
|
242 |
-
|
243 |
-
$query_child = new Toolset_Association_Query( array(
|
244 |
-
Toolset_Association_Query::QUERY_PARENT_DOMAIN => $element->get_domain(),
|
245 |
-
Toolset_Association_Query::QUERY_PARENT_ID => $element->get_id(),
|
246 |
-
Toolset_Association_Query::OPTION_RETURN => Toolset_Association_Query::RETURN_ASSOCIATIONS
|
247 |
-
) );
|
248 |
-
|
249 |
-
/** @var Toolset_Association[] $associations */
|
250 |
-
$associations = array_merge( $associations, $query_child->get_results() );
|
251 |
-
|
252 |
-
foreach( $associations as $association ) {
|
253 |
-
$definition = $association->get_definition();
|
254 |
-
$driver = $definition->get_driver();
|
255 |
-
$driver->delete_association( $association );
|
256 |
-
}
|
257 |
-
|
258 |
-
}
|
259 |
-
|
260 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/toolset/toolset-common/inc/m2m/association_transitional.php
DELETED
@@ -1,61 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Represents a single, translation-unaware m2m association between two elements in the transitional
|
5 |
-
* multilingual mode.
|
6 |
-
*
|
7 |
-
* The only difference is that in this mode, we get a string instead of a trid, and need to extract the
|
8 |
-
* actual trid for the parent constructor, and use the string as an unique identifier.
|
9 |
-
*
|
10 |
-
* See Toolset_Association_Query::preprocess_results_in_transitional_mode() for more information.
|
11 |
-
*/
|
12 |
-
class Toolset_Association_Transitional extends Toolset_Association {
|
13 |
-
|
14 |
-
|
15 |
-
private $ttrid;
|
16 |
-
|
17 |
-
/**
|
18 |
-
* Unique identifier of the association.
|
19 |
-
*
|
20 |
-
* @return string
|
21 |
-
*/
|
22 |
-
public function get_uid() {
|
23 |
-
return $this->ttrid;
|
24 |
-
}
|
25 |
-
|
26 |
-
|
27 |
-
/**
|
28 |
-
* Toolset_Association_Transitional constructor.
|
29 |
-
*
|
30 |
-
* @param string $ttrid Translation group ID or its string replacement.
|
31 |
-
* @param Toolset_Relationship_Definition $relationship_definition
|
32 |
-
* @param array $element_sources Associative array with both element keys. Each item can be either an ID
|
33 |
-
* or a matching Toolset_Element instance.
|
34 |
-
* @param int|Toolset_Post $intermediary_source Intermediary post with association fields or its ID. If a
|
35 |
-
* Toolset_Post instance is provided, it must have the type matching with the relationship definition.
|
36 |
-
*
|
37 |
-
* @since m2m
|
38 |
-
*/
|
39 |
-
public function __construct(
|
40 |
-
$ttrid, Toolset_Relationship_Definition $relationship_definition, $element_sources, $intermediary_source
|
41 |
-
) {
|
42 |
-
|
43 |
-
if( ! Toolset_Relationship_Multilingual_Mode::is_transitional() ) {
|
44 |
-
throw new RuntimeException( 'Tried to instantiate Toolset_Association_Transitional in a non-transitional mode.' );
|
45 |
-
}
|
46 |
-
|
47 |
-
$ttrid_parts = explode( '\\', $ttrid );
|
48 |
-
if( count( $ttrid_parts ) !== 4 ) {
|
49 |
-
throw new InvalidArgumentException( 'Invalid transitional trid provided.' );
|
50 |
-
}
|
51 |
-
|
52 |
-
$this->ttrid = $ttrid;
|
53 |
-
|
54 |
-
// In the extremely rare case someone explictly asks for a trid, they will get it (although it probably
|
55 |
-
// won't be unique).
|
56 |
-
$trid = (int) $ttrid_parts[2];
|
57 |
-
|
58 |
-
parent::__construct( $trid, $relationship_definition, $element_sources, $intermediary_source );
|
59 |
-
}
|
60 |
-
|
61 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/toolset/toolset-common/inc/m2m/association_translation_set.php
DELETED
@@ -1,135 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Represents a translation set of an association between posts.
|
5 |
-
*
|
6 |
-
* Benefits:
|
7 |
-
* - allows for specifying the preferred language in the rare cases it might be needed
|
8 |
-
* - allows for storing element sources (IDs) with the complete language information but
|
9 |
-
* without instantiating the elements immediately - that improves performance when
|
10 |
-
* instantiating and prevents from a WPML interaction/database queries in the future
|
11 |
-
*
|
12 |
-
* You should never need to use this class directly outside of the m2m API.
|
13 |
-
*
|
14 |
-
* @since m2m
|
15 |
-
*/
|
16 |
-
class Toolset_Association_Translation_Set extends Toolset_Association_Base {
|
17 |
-
|
18 |
-
/**
|
19 |
-
* @var array For each relationship role, there is an element source (something that will be
|
20 |
-
* accepted by Toolset_Element::get_instance()).
|
21 |
-
*/
|
22 |
-
private $element_sources = array();
|
23 |
-
|
24 |
-
|
25 |
-
/**
|
26 |
-
* Toolset_Association_Translation_Set constructor.
|
27 |
-
*
|
28 |
-
* @param int $trid
|
29 |
-
* @param Toolset_Relationship_Definition $relationship_definition
|
30 |
-
* @param array $element_sources
|
31 |
-
*/
|
32 |
-
public function __construct(
|
33 |
-
$trid, Toolset_Relationship_Definition $relationship_definition, $element_sources
|
34 |
-
) {
|
35 |
-
|
36 |
-
if ( ! Toolset_Relationship_Multilingual_Mode::is_on() ) {
|
37 |
-
throw new RuntimeException( 'Attempted to use an association translation set while WPML was inactive' );
|
38 |
-
}
|
39 |
-
|
40 |
-
parent::__construct( $trid, $relationship_definition );
|
41 |
-
|
42 |
-
foreach( Toolset_Relationship_Role::all_role_names() as $role ) {
|
43 |
-
$this->element_sources[ $role ] = toolset_getarr( $element_sources, $role, null );
|
44 |
-
}
|
45 |
-
}
|
46 |
-
|
47 |
-
|
48 |
-
/**
|
49 |
-
* Get an association element.
|
50 |
-
*
|
51 |
-
* Instantiates an element if it hasn't been done yet.
|
52 |
-
*
|
53 |
-
* @param string $element_role
|
54 |
-
*
|
55 |
-
* @return Toolset_Element|null
|
56 |
-
* @throws InvalidArgumentException
|
57 |
-
* @since m2m
|
58 |
-
*/
|
59 |
-
public function get_element( $element_role ) {
|
60 |
-
|
61 |
-
Toolset_Relationship_Role::validate( $element_role );
|
62 |
-
|
63 |
-
if( ! array_key_exists( $element_role, $this->elements ) ) {
|
64 |
-
$element_source = toolset_getarr( $this->element_sources, $element_role, null );
|
65 |
-
|
66 |
-
try {
|
67 |
-
$this->elements[ $element_role ] = Toolset_Element::get_instance(
|
68 |
-
$this->get_element_domain( $element_role ),
|
69 |
-
$element_source
|
70 |
-
);
|
71 |
-
} catch( Exception $e ) {
|
72 |
-
$this->elements[ $element_role ] = null;
|
73 |
-
}
|
74 |
-
}
|
75 |
-
|
76 |
-
return $this->elements[ $element_role ];
|
77 |
-
}
|
78 |
-
|
79 |
-
|
80 |
-
/**
|
81 |
-
* @inheritdoc
|
82 |
-
* @return null|Toolset_Post|Toolset_Post_Translation_Set
|
83 |
-
*/
|
84 |
-
protected function get_intermediary_post() {
|
85 |
-
/** @noinspection PhpIncompatibleReturnTypeInspection */
|
86 |
-
return $this->get_element( Toolset_Relationship_Role::INTERMEDIARY );
|
87 |
-
}
|
88 |
-
|
89 |
-
|
90 |
-
/**
|
91 |
-
* Determine whether the intermediary post exists and supports translations.
|
92 |
-
*
|
93 |
-
* @return bool
|
94 |
-
*/
|
95 |
-
private function is_intermediary_post_translation_set() {
|
96 |
-
return ( $this->has_fields() && $this->get_intermediary_post() instanceof Toolset_Post_Translation_Set );
|
97 |
-
}
|
98 |
-
|
99 |
-
|
100 |
-
/**
|
101 |
-
* @inheritdoc
|
102 |
-
*
|
103 |
-
* @return bool|Toolset_Field_Instance[]
|
104 |
-
*/
|
105 |
-
public function get_fields( $language_code = null ) {
|
106 |
-
if( ! $this->has_fields() ) {
|
107 |
-
return false;
|
108 |
-
}
|
109 |
-
|
110 |
-
if( $this->is_intermediary_post_translation_set() ) {
|
111 |
-
return $this->get_intermediary_post()->get_fields( $language_code );
|
112 |
-
}
|
113 |
-
|
114 |
-
return $this->get_intermediary_post()->get_fields();
|
115 |
-
}
|
116 |
-
|
117 |
-
|
118 |
-
/**
|
119 |
-
* @inheritdoc
|
120 |
-
* @param string|Toolset_Field_Definition $field_source
|
121 |
-
* @return bool|Toolset_Field_Instance
|
122 |
-
*/
|
123 |
-
public function get_field( $field_source, $language_code = null ) {
|
124 |
-
if( ! $this->has_fields() ) {
|
125 |
-
return false;
|
126 |
-
}
|
127 |
-
|
128 |
-
if( $this->is_intermediary_post_translation_set() ) {
|
129 |
-
return $this->get_intermediary_post()->get_field( $field_source, $language_code );
|
130 |
-
}
|
131 |
-
|
132 |
-
return $this->get_intermediary_post()->get_field( $field_source );
|
133 |
-
}
|
134 |
-
|
135 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/toolset/toolset-common/inc/m2m/autoload_classmap.php
CHANGED
@@ -1,75 +1,125 @@
|
|
1 |
<?php
|
2 |
// Generated by ZF2's ./bin/classmap_generator.php
|
3 |
return array(
|
4 |
-
'IToolset_Association' => dirname( __FILE__ ) . '/
|
|
|
|
|
|
|
|
|
|
|
5 |
'IToolset_Potential_Association_Query' => dirname( __FILE__ ) . '/potential_association/query_interface.php',
|
|
|
6 |
'IToolset_Relationship_Database_Issue' => dirname( __FILE__ ) . '/database/issue/interface.php',
|
7 |
-
'IToolset_Relationship_Definition' => dirname( __FILE__ ) . '/definition/interface.php',
|
8 |
'IToolset_Relationship_Origin' => dirname( __FILE__ ) . '/origin/interface.php',
|
9 |
-
'IToolset_Relationship_Query_Cardinality_Match' => dirname( __FILE__ ) . '/
|
10 |
-
'IToolset_Relationship_Query_Condition' => dirname( __FILE__ ) . '/
|
11 |
-
'IToolset_Relationship_Role' => dirname( __FILE__ ) . '/
|
12 |
-
'IToolset_Relationship_Role_Parent_Child' => dirname( __FILE__ ) . '/
|
13 |
-
'
|
14 |
-
'
|
15 |
-
'
|
16 |
-
'
|
17 |
-
'
|
18 |
-
'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19 |
'Toolset_Potential_Association_Query_Factory' => dirname( __FILE__ ) . '/potential_association/query_factory.php',
|
20 |
'Toolset_Potential_Association_Query_Posts' => dirname( __FILE__ ) . '/potential_association/query_posts.php',
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
'Toolset_Relationship_Cardinality' => dirname( __FILE__ ) . '/cardinality.php',
|
22 |
'Toolset_Relationship_Controller' => dirname( __FILE__ ) . '/controller.php',
|
23 |
'Toolset_Relationship_Database_Issue_Missing_Element' => dirname( __FILE__ ) . '/database/issue/missing_element.php',
|
24 |
'Toolset_Relationship_Database_Operations' => dirname( __FILE__ ) . '/database/operations.php',
|
25 |
'Toolset_Relationship_Database_Unique_Table_Alias' => dirname( __FILE__ ) . '/database/unique_table_alias.php',
|
26 |
-
'Toolset_Relationship_Definition' => dirname( __FILE__ ) . '/definition/definition.php',
|
27 |
-
'Toolset_Relationship_Definition_Factory' => dirname( __FILE__ ) . '/definition/factory.php',
|
28 |
-
'Toolset_Relationship_Definition_Persistence' => dirname( __FILE__ ) . '/definition/persistence.php',
|
29 |
-
'Toolset_Relationship_Definition_Repository' => dirname( __FILE__ ) . '/definition/repository.php',
|
30 |
-
'Toolset_Relationship_Definition_Translator' => dirname( __FILE__ ) . '/definition/translator.php',
|
31 |
'Toolset_Relationship_Distinct_Post_Query' => dirname( __FILE__ ) . '/potential_association/distinct_post_query.php',
|
32 |
-
'Toolset_Relationship_Driver_Base' => dirname( __FILE__ ) . '/driver_base.php',
|
33 |
'Toolset_Relationship_Driver' => dirname( __FILE__ ) . '/driver.php',
|
|
|
34 |
'Toolset_Relationship_Element_Type' => dirname( __FILE__ ) . '/element_type.php',
|
35 |
-
'
|
36 |
-
'
|
37 |
-
'
|
|
|
38 |
'Toolset_Relationship_Origin_Post_Reference_Field' => dirname( __FILE__ ) . '/origin/post_reference_field.php',
|
39 |
'Toolset_Relationship_Origin_Repeatable_Group' => dirname( __FILE__ ) . '/origin/repeatable_group.php',
|
40 |
'Toolset_Relationship_Origin_Wizard' => dirname( __FILE__ ) . '/origin/wizard.php',
|
|
|
41 |
'Toolset_Relationship_Query_Base' => dirname( __FILE__ ) . '/query_base.php',
|
42 |
'Toolset_Relationship_Query_Cache' => dirname( __FILE__ ) . '/query_cache.php',
|
43 |
-
'Toolset_Relationship_Query_Cardinality_Match_Conjunction' => dirname( __FILE__ ) . '/
|
44 |
-
'Toolset_Relationship_Query_Cardinality_Match_Factory' => dirname( __FILE__ ) . '/
|
45 |
-
'Toolset_Relationship_Query_Cardinality_Match_Operators' => dirname( __FILE__ ) . '/
|
46 |
-
'Toolset_Relationship_Query_Cardinality_Match_Single' => dirname( __FILE__ ) . '/
|
47 |
-
'
|
48 |
-
'
|
49 |
-
'
|
50 |
-
'
|
51 |
-
'
|
52 |
-
'
|
53 |
-
'
|
54 |
-
'
|
55 |
-
'
|
56 |
-
'
|
57 |
-
'
|
58 |
-
'
|
59 |
-
'
|
60 |
-
'
|
61 |
-
'
|
62 |
-
'
|
63 |
-
'
|
64 |
-
'
|
65 |
-
'
|
66 |
-
'
|
67 |
-
'Toolset_Relationship_Role' => dirname( __FILE__ ) . '/relationship_role/role.php',
|
68 |
-
'Toolset_Relationship_Role_Intermediary' => dirname( __FILE__ ) . '/relationship_role/intermediary.php',
|
69 |
-
'Toolset_Relationship_Role_Parent' => dirname( __FILE__ ) . '/relationship_role/parent.php',
|
70 |
-
'Toolset_Relationship_Scope' => dirname( __FILE__ ) . '/scope.php',
|
71 |
-
'Toolset_Relationship_Slug_Validator' => dirname( __FILE__ ) . '/slug_validator.php',
|
72 |
'Toolset_Relationship_Table_Name' => dirname( __FILE__ ) . '/database/table_name.php',
|
73 |
'Toolset_Relationship_Utils' => dirname( __FILE__ ) . '/utils.php',
|
74 |
-
'Toolset_Relationship_WPML_Interoperability' => dirname( __FILE__ ) . '/wpml_interoperability.php',
|
75 |
);
|
1 |
<?php
|
2 |
// Generated by ZF2's ./bin/classmap_generator.php
|
3 |
return array(
|
4 |
+
'IToolset_Association' => dirname( __FILE__ ) . '/association/interface.php',
|
5 |
+
'IToolset_Association_Query_Condition' => dirname( __FILE__ ) . '/association/query/condition/interface.php',
|
6 |
+
'IToolset_Association_Query_Element_Selector' => dirname( __FILE__ ) . '/association/query/element_selector/interface.php',
|
7 |
+
'IToolset_Association_Query_Orderby' => dirname( __FILE__ ) . '/association/query/orderby/interface.php',
|
8 |
+
'IToolset_Association_Query_Restriction' => dirname( __FILE__ ) . '/association/query/restriction/interface.php',
|
9 |
+
'IToolset_Association_Query_Result_Transformation' => dirname( __FILE__ ) . '/association/query/result_transformation/interface.php',
|
10 |
'IToolset_Potential_Association_Query' => dirname( __FILE__ ) . '/potential_association/query_interface.php',
|
11 |
+
'IToolset_Query_Condition' => dirname( __FILE__ ) . '/query/condition/interface.php',
|
12 |
'IToolset_Relationship_Database_Issue' => dirname( __FILE__ ) . '/database/issue/interface.php',
|
13 |
+
'IToolset_Relationship_Definition' => dirname( __FILE__ ) . '/relationship/definition/interface.php',
|
14 |
'IToolset_Relationship_Origin' => dirname( __FILE__ ) . '/origin/interface.php',
|
15 |
+
'IToolset_Relationship_Query_Cardinality_Match' => dirname( __FILE__ ) . '/relationship/query/cardinality_match/interface.php',
|
16 |
+
'IToolset_Relationship_Query_Condition' => dirname( __FILE__ ) . '/relationship/query/condition/interface.php',
|
17 |
+
'IToolset_Relationship_Role' => dirname( __FILE__ ) . '/relationship/role/interface.php',
|
18 |
+
'IToolset_Relationship_Role_Parent_Child' => dirname( __FILE__ ) . '/relationship/role/parent_child_interface.php',
|
19 |
+
'Toolset_Association' => dirname( __FILE__ ) . '/association/association.php',
|
20 |
+
'Toolset_Association_Cleanup_Association' => dirname( __FILE__ ) . '/association/cleanup/association.php',
|
21 |
+
'Toolset_Association_Cleanup_Cron_Event' => dirname( __FILE__ ) . '/association/cleanup/cron_event.php',
|
22 |
+
'Toolset_Association_Cleanup_Cron_Handler' => dirname( __FILE__ ) . '/association/cleanup/cron_handler.php',
|
23 |
+
'Toolset_Association_Cleanup_Dangling_Intermediary_Posts' => dirname( __FILE__ ) . '/association/cleanup/dangling_intermediary_posts.php',
|
24 |
+
'Toolset_Association_Cleanup_Factory' => dirname( __FILE__ ) . '/association/cleanup/factory.php',
|
25 |
+
'Toolset_Association_Cleanup_Post' => dirname( __FILE__ ) . '/association/cleanup/post.php',
|
26 |
+
'Toolset_Association_Cleanup_Troubleshooting_Section' => dirname( __FILE__ ) . '/association/cleanup/troubleshooting_section.php',
|
27 |
+
'Toolset_Association_Factory' => dirname( __FILE__ ) . '/association/factory.php',
|
28 |
+
'Toolset_Association_Intermediary_Post_Persistence' => dirname( __FILE__ ) . '/association/intermediary_post_persistence.php',
|
29 |
+
'Toolset_Association_Persistence' => dirname( __FILE__ ) . '/association/persistence.php',
|
30 |
+
'Toolset_Association_Query' => dirname( __FILE__ ) . '/association/query/association_query.php',
|
31 |
+
'Toolset_Association_Query_Condition' => dirname( __FILE__ ) . '/association/query/condition/abstract.php',
|
32 |
+
'Toolset_Association_Query_Condition_Association_Id' => dirname( __FILE__ ) . '/association/query/condition/association_id.php',
|
33 |
+
'Toolset_Association_Query_Condition_Element_Id' => dirname( __FILE__ ) . '/association/query/condition/element_id.php',
|
34 |
+
'Toolset_Association_Query_Condition_Element_Id_And_Domain' => dirname( __FILE__ ) . '/association/query/condition/element_id_and_domain.php',
|
35 |
+
'Toolset_Association_Query_Condition_Element_Status' => dirname( __FILE__ ) . '/association/query/condition/element_status.php',
|
36 |
+
'Toolset_Association_Query_Condition_Empty_Intermediary' => dirname( __FILE__ ) . '/association/query/condition/empty_intermediary.php',
|
37 |
+
'Toolset_Association_Query_Condition_Exclude_Element' => dirname( __FILE__ ) . '/association/query/condition/exclude_element.php',
|
38 |
+
'Toolset_Association_Query_Condition_Factory' => dirname( __FILE__ ) . '/association/query/condition_factory.php',
|
39 |
+
'Toolset_Association_Query_Condition_Has_Active_Relationship' => dirname( __FILE__ ) . '/association/query/condition/has_active_relationship.php',
|
40 |
+
'Toolset_Association_Query_Condition_Has_Domain' => dirname( __FILE__ ) . '/association/query/condition/has_domain.php',
|
41 |
+
'Toolset_Association_Query_Condition_Has_Domain_And_Type' => dirname( __FILE__ ) . '/association/query/condition/has_domain_and_type.php',
|
42 |
+
'Toolset_Association_Query_Condition_Has_Legacy_Relationship' => dirname( __FILE__ ) . '/association/query/condition/has_legacy_relationship.php',
|
43 |
+
'Toolset_Association_Query_Condition_Has_Type' => dirname( __FILE__ ) . '/association/query/condition/has_type.php',
|
44 |
+
'Toolset_Association_Query_Condition_Postmeta' => dirname( __FILE__ ) . '/association/query/condition/postmeta.php',
|
45 |
+
'Toolset_Association_Query_Condition_Relationship_Flag' => dirname( __FILE__ ) . '/association/query/condition/relationship_flag.php',
|
46 |
+
'Toolset_Association_Query_Condition_Relationship_Id' => dirname( __FILE__ ) . '/association/query/condition/relationship_id.php',
|
47 |
+
'Toolset_Association_Query_Condition_Search' => dirname( __FILE__ ) . '/association/query/condition/search.php',
|
48 |
+
'Toolset_Association_Query_Condition_Wp_Query' => dirname( __FILE__ ) . '/association/query/condition/wp_query.php',
|
49 |
+
'Toolset_Association_Query_Element_Selector_Abstract' => dirname( __FILE__ ) . '/association/query/element_selector/abstract.php',
|
50 |
+
'Toolset_Association_Query_Element_Selector_Default' => dirname( __FILE__ ) . '/association/query/element_selector/default.php',
|
51 |
+
'Toolset_Association_Query_Element_Selector_Provider' => dirname( __FILE__ ) . '/association/query/element_selector/provider.php',
|
52 |
+
'Toolset_Association_Query_Element_Selector_Wpml' => dirname( __FILE__ ) . '/association/query/element_selector/wpml.php',
|
53 |
+
'Toolset_Association_Query_Orderby' => dirname( __FILE__ ) . '/association/query/orderby/abstract.php',
|
54 |
+
'Toolset_Association_Query_Orderby_Factory' => dirname( __FILE__ ) . '/association/query/orderby_factory.php',
|
55 |
+
'Toolset_Association_Query_Orderby_Nothing' => dirname( __FILE__ ) . '/association/query/orderby/nothing.php',
|
56 |
+
'Toolset_Association_Query_Orderby_Postmeta' => dirname( __FILE__ ) . '/association/query/orderby/postmeta.php',
|
57 |
+
'Toolset_Association_Query_Orderby_Title' => dirname( __FILE__ ) . '/association/query/orderby/title.php',
|
58 |
+
'Toolset_Association_Query_Result_Transformation_Association_Instance' => dirname( __FILE__ ) . '/association/query/result_transformation/association_instance.php',
|
59 |
+
'Toolset_Association_Query_Result_Transformation_Association_Uid' => dirname( __FILE__ ) . '/association/query/result_transformation/association_uid.php',
|
60 |
+
'Toolset_Association_Query_Result_Transformation_Element_Id' => dirname( __FILE__ ) . '/association/query/result_transformation/element_id.php',
|
61 |
+
'Toolset_Association_Query_Result_Transformation_Element_Instance' => dirname( __FILE__ ) . '/association/query/result_transformation/element_instance.php',
|
62 |
+
'Toolset_Association_Query_Sql_Expression_Builder' => dirname( __FILE__ ) . '/association/query/sql_expression_builder.php',
|
63 |
+
'Toolset_Association_Query_Table_Join_Manager' => dirname( __FILE__ ) . '/association/query/table_join_manager.php',
|
64 |
+
'Toolset_Association_Query_V2' => dirname( __FILE__ ) . '/association/query/association_query_v2.php',
|
65 |
+
'Toolset_Association_Query_Wpdb_Wrapper' => dirname( __FILE__ ) . '/association/query/wpdb_wrapper.php',
|
66 |
+
'Toolset_Association_Translator' => dirname( __FILE__ ) . '/association/translator.php',
|
67 |
'Toolset_Potential_Association_Query_Factory' => dirname( __FILE__ ) . '/potential_association/query_factory.php',
|
68 |
'Toolset_Potential_Association_Query_Posts' => dirname( __FILE__ ) . '/potential_association/query_posts.php',
|
69 |
+
'Toolset_Query_Comparison_Operator' => dirname( __FILE__ ) . '/query/comparison_operator.php',
|
70 |
+
'Toolset_Query_Condition_And' => dirname( __FILE__ ) . '/query/condition/and.php',
|
71 |
+
'Toolset_Query_Condition_Contradiction' => dirname( __FILE__ ) . '/query/condition/contradiction.php',
|
72 |
+
'Toolset_Query_Condition_Operator' => dirname( __FILE__ ) . '/query/condition/operator.php',
|
73 |
+
'Toolset_Query_Condition_Or' => dirname( __FILE__ ) . '/query/condition/or.php',
|
74 |
+
'Toolset_Query_Condition_Tautology' => dirname( __FILE__ ) . '/query/condition/tautology.php',
|
75 |
'Toolset_Relationship_Cardinality' => dirname( __FILE__ ) . '/cardinality.php',
|
76 |
'Toolset_Relationship_Controller' => dirname( __FILE__ ) . '/controller.php',
|
77 |
'Toolset_Relationship_Database_Issue_Missing_Element' => dirname( __FILE__ ) . '/database/issue/missing_element.php',
|
78 |
'Toolset_Relationship_Database_Operations' => dirname( __FILE__ ) . '/database/operations.php',
|
79 |
'Toolset_Relationship_Database_Unique_Table_Alias' => dirname( __FILE__ ) . '/database/unique_table_alias.php',
|
80 |
+
'Toolset_Relationship_Definition' => dirname( __FILE__ ) . '/relationship/definition/definition.php',
|
81 |
+
'Toolset_Relationship_Definition_Factory' => dirname( __FILE__ ) . '/relationship/definition/factory.php',
|
82 |
+
'Toolset_Relationship_Definition_Persistence' => dirname( __FILE__ ) . '/relationship/definition/persistence.php',
|
83 |
+
'Toolset_Relationship_Definition_Repository' => dirname( __FILE__ ) . '/relationship/definition/repository.php',
|
84 |
+
'Toolset_Relationship_Definition_Translator' => dirname( __FILE__ ) . '/relationship/definition/translator.php',
|
85 |
'Toolset_Relationship_Distinct_Post_Query' => dirname( __FILE__ ) . '/potential_association/distinct_post_query.php',
|
|
|
86 |
'Toolset_Relationship_Driver' => dirname( __FILE__ ) . '/driver.php',
|
87 |
+
'Toolset_Relationship_Driver_Base' => dirname( __FILE__ ) . '/driver_base.php',
|
88 |
'Toolset_Relationship_Element_Type' => dirname( __FILE__ ) . '/element_type.php',
|
89 |
+
'Toolset_Relationship_Migration' => dirname( __FILE__ ) . '/migration/controller.php',
|
90 |
+
'Toolset_Relationship_Migration_Associations' => dirname( __FILE__ ) . '/migration/associations.php',
|
91 |
+
'Toolset_Relationship_Migration_Controller' => dirname( __FILE__ ) . '/migration/controller.php',
|
92 |
+
'Toolset_Relationship_Migration_Post_Translation' => dirname( __FILE__ ) . '/migration/post_translation.php',
|
93 |
'Toolset_Relationship_Origin_Post_Reference_Field' => dirname( __FILE__ ) . '/origin/post_reference_field.php',
|
94 |
'Toolset_Relationship_Origin_Repeatable_Group' => dirname( __FILE__ ) . '/origin/repeatable_group.php',
|
95 |
'Toolset_Relationship_Origin_Wizard' => dirname( __FILE__ ) . '/origin/wizard.php',
|
96 |
+
'Toolset_Relationship_Query' => dirname( __FILE__ ) . '/relationship/query/relationship_query.php',
|
97 |
'Toolset_Relationship_Query_Base' => dirname( __FILE__ ) . '/query_base.php',
|
98 |
'Toolset_Relationship_Query_Cache' => dirname( __FILE__ ) . '/query_cache.php',
|
99 |
+
'Toolset_Relationship_Query_Cardinality_Match_Conjunction' => dirname( __FILE__ ) . '/relationship/query/cardinality_match/conjunction.php',
|
100 |
+
'Toolset_Relationship_Query_Cardinality_Match_Factory' => dirname( __FILE__ ) . '/relationship/query/cardinality_match/factory.php',
|
101 |
+
'Toolset_Relationship_Query_Cardinality_Match_Operators' => dirname( __FILE__ ) . '/relationship/query/cardinality_match/operators.php',
|
102 |
+
'Toolset_Relationship_Query_Cardinality_Match_Single' => dirname( __FILE__ ) . '/relationship/query/cardinality_match/single.php',
|
103 |
+
'Toolset_Relationship_Query_Condition' => dirname( __FILE__ ) . '/relationship/query/condition/abstract.php',
|
104 |
+
'Toolset_Relationship_Query_Condition_Factory' => dirname( __FILE__ ) . '/relationship/query/condition_factory.php',
|
105 |
+
'Toolset_Relationship_Query_Condition_Has_Active_Types' => dirname( __FILE__ ) . '/relationship/query/condition/has_active_types.php',
|
106 |
+
'Toolset_Relationship_Query_Condition_Has_Cardinality' => dirname( __FILE__ ) . '/relationship/query/condition/has_cardinality.php',
|
107 |
+
'Toolset_Relationship_Query_Condition_Has_Domain' => dirname( __FILE__ ) . '/relationship/query/condition/has_domain.php',
|
108 |
+
'Toolset_Relationship_Query_Condition_Is_Active' => dirname( __FILE__ ) . '/relationship/query/condition/is_active.php',
|
109 |
+
'Toolset_Relationship_Query_Condition_Is_Boolean_Flag' => dirname( __FILE__ ) . '/relationship/query/condition/is_boolean_flag.php',
|
110 |
+
'Toolset_Relationship_Query_Condition_Is_Legacy' => dirname( __FILE__ ) . '/relationship/query/condition/is_legacy.php',
|
111 |
+
'Toolset_Relationship_Query_Condition_Origin' => dirname( __FILE__ ) . '/relationship/query/condition/origin.php',
|
112 |
+
'Toolset_Relationship_Query_Condition_Type' => dirname( __FILE__ ) . '/relationship/query/condition/type.php',
|
113 |
+
'Toolset_Relationship_Query_Factory' => dirname( __FILE__ ) . '/query/factory.php',
|
114 |
+
'Toolset_Relationship_Query_Sql_Expression_Builder' => dirname( __FILE__ ) . '/relationship/query/sql_expression_builder.php',
|
115 |
+
'Toolset_Relationship_Query_V2' => dirname( __FILE__ ) . '/relationship/query/relationship_query_v2.php',
|
116 |
+
'Toolset_Relationship_Role' => dirname( __FILE__ ) . '/relationship/role/role.php',
|
117 |
+
'Toolset_Relationship_Role_Abstract' => dirname( __FILE__ ) . '/relationship/role/abstract.php',
|
118 |
+
'Toolset_Relationship_Role_Child' => dirname( __FILE__ ) . '/relationship/role/child.php',
|
119 |
+
'Toolset_Relationship_Role_Intermediary' => dirname( __FILE__ ) . '/relationship/role/intermediary.php',
|
120 |
+
'Toolset_Relationship_Role_Parent' => dirname( __FILE__ ) . '/relationship/role/parent.php',
|
121 |
+
'Toolset_Relationship_Scope' => dirname( __FILE__ ) . '/relationship/scope.php',
|
122 |
+
'Toolset_Relationship_Slug_Validator' => dirname( __FILE__ ) . '/relationship/slug_validator.php',
|
|
|
|
|
|
|
|
|
|
|
123 |
'Toolset_Relationship_Table_Name' => dirname( __FILE__ ) . '/database/table_name.php',
|
124 |
'Toolset_Relationship_Utils' => dirname( __FILE__ ) . '/utils.php',
|
|
|
125 |
);
|
vendor/toolset/toolset-common/inc/m2m/cardinality.php
CHANGED
@@ -113,7 +113,7 @@ class Toolset_Relationship_Cardinality {
|
|
113 |
private function validiate_limits() {
|
114 |
|
115 |
foreach( $this->limits as $element_role => $element_limits ) {
|
116 |
-
|
117 |
|
118 |
$min = toolset_getarr( $element_limits, self::MIN, self::INVALID_VALUE );
|
119 |
$max = toolset_getarr( $element_limits, self::MAX, self::INVALID_VALUE );
|
@@ -157,7 +157,7 @@ class Toolset_Relationship_Cardinality {
|
|
157 |
* @since m2m
|
158 |
*/
|
159 |
public function get_limit( $element_role, $limit_key = self::MAX ) {
|
160 |
-
|
161 |
self::validate_limit_name( $limit_key );
|
162 |
|
163 |
return $this->limits[ $element_role ][ $limit_key ];
|
113 |
private function validiate_limits() {
|
114 |
|
115 |
foreach( $this->limits as $element_role => $element_limits ) {
|
116 |
+
Toolset_Association::validate_element_role( $element_role );
|
117 |
|
118 |
$min = toolset_getarr( $element_limits, self::MIN, self::INVALID_VALUE );
|
119 |
$max = toolset_getarr( $element_limits, self::MAX, self::INVALID_VALUE );
|
157 |
* @since m2m
|
158 |
*/
|
159 |
public function get_limit( $element_role, $limit_key = self::MAX ) {
|
160 |
+
Toolset_Association::validate_element_role( $element_role );
|
161 |
self::validate_limit_name( $limit_key );
|
162 |
|
163 |
return $this->limits[ $element_role ][ $limit_key ];
|
vendor/toolset/toolset-common/inc/m2m/controller.php
CHANGED
@@ -17,10 +17,21 @@ class Toolset_Relationship_Controller {
|
|
17 |
private $_post_type_query_factory;
|
18 |
|
19 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
20 |
/** @var Toolset_Relationship_Controller|null */
|
21 |
private static $instance;
|
22 |
|
23 |
|
|
|
|
|
|
|
24 |
public static function get_instance() {
|
25 |
if( null == self::$instance ) {
|
26 |
self::$instance = new self();
|
@@ -34,13 +45,26 @@ class Toolset_Relationship_Controller {
|
|
34 |
* Toolset_Relationship_Controller constructor.
|
35 |
*
|
36 |
* @param Toolset_Post_Type_Query_Factory|null $post_type_query_factory_di
|
|
|
|
|
37 |
*/
|
38 |
-
public function __construct(
|
|
|
|
|
|
|
|
|
39 |
$this->_post_type_query_factory = $post_type_query_factory_di;
|
|
|
|
|
40 |
}
|
41 |
|
42 |
|
43 |
const IS_M2M_ENABLED_OPTION = 'toolset_is_m2m_enabled';
|
|
|
|
|
|
|
|
|
|
|
44 |
|
45 |
|
46 |
/**
|
@@ -73,10 +97,12 @@ class Toolset_Relationship_Controller {
|
|
73 |
|
74 |
$is_enabled = get_option( self::IS_M2M_ENABLED_OPTION, null );
|
75 |
|
76 |
-
if
|
|
|
|
|
77 |
$is_enabled = $this->set_initial_m2m_state();
|
78 |
} else {
|
79 |
-
$is_enabled = (
|
80 |
}
|
81 |
|
82 |
/**
|
@@ -111,9 +137,8 @@ class Toolset_Relationship_Controller {
|
|
111 |
return;
|
112 |
}
|
113 |
|
114 |
-
$this->is_core_initialized = true;
|
115 |
-
|
116 |
$this->add_hooks();
|
|
|
117 |
}
|
118 |
|
119 |
|
@@ -141,7 +166,8 @@ class Toolset_Relationship_Controller {
|
|
141 |
// fixme: This is for the purpose of alpha and beta versions: If there's a database problem,
|
142 |
// at least make it fail on every request. Otherwise, we'll just waste a little performance
|
143 |
// on checking that the tables already exist.
|
144 |
-
|
|
|
145 |
$migration->do_native_dbdelta();
|
146 |
|
147 |
$this->is_everything_initialized = true;
|
@@ -187,23 +213,9 @@ class Toolset_Relationship_Controller {
|
|
187 |
return;
|
188 |
}
|
189 |
|
190 |
-
|
191 |
-
|
192 |
-
// Intercept icl_translations table changes
|
193 |
-
//
|
194 |
-
//
|
195 |
|
196 |
-
|
197 |
-
* toolset_use_default_m2m_wpml_interoperability_manager
|
198 |
-
*
|
199 |
-
* Allow for disabling the standard WPML interoperability manager if it's about to be overridden by
|
200 |
-
* something else.
|
201 |
-
*
|
202 |
-
* @since m2m
|
203 |
-
*/
|
204 |
-
if( true == apply_filters( 'toolset_use_default_m2m_wpml_interoperability_manager', true ) ) {
|
205 |
-
// add_action( 'wpml_translation_update', array( $this, 'on_wpml_translation_update' ), 10 );
|
206 |
-
}
|
207 |
|
208 |
/**
|
209 |
* toolset_relationship_query
|
@@ -233,19 +245,16 @@ class Toolset_Relationship_Controller {
|
|
233 |
* @since 2.5.6
|
234 |
*/
|
235 |
add_action( 'toolset_report_m2m_integrity_issue', array( $this, 'report_integrity_issue' ) );
|
236 |
-
}
|
237 |
|
238 |
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
$this
|
247 |
-
$view_manager = Toolset_Relationship_WPML_Interoperability::get_instance();
|
248 |
-
$view_manager->on_wpml_translation_update( $args );
|
249 |
}
|
250 |
|
251 |
|
@@ -255,7 +264,7 @@ class Toolset_Relationship_Controller {
|
|
255 |
* @param $ignored
|
256 |
* @param $query_args
|
257 |
*
|
258 |
-
* @return int[]|
|
259 |
*/
|
260 |
public function on_toolset_relationship_query( /** @noinspection PhpUnusedParameterInspection */ $ignored, $query_args ) {
|
261 |
$this->initialize_full();
|
@@ -280,8 +289,7 @@ class Toolset_Relationship_Controller {
|
|
280 |
|
281 |
$this->initialize_full();
|
282 |
|
283 |
-
$
|
284 |
-
$result = $database->update_type_on_type_sets( $new_slug, $old_slug );
|
285 |
|
286 |
if( $result->is_error() ) {
|
287 |
error_log( $result->get_message() );
|
@@ -323,8 +331,6 @@ class Toolset_Relationship_Controller {
|
|
323 |
* Basically, that means checking if there are any associations with this post and delete them.
|
324 |
* Note that that will also trigger deleting the intermediary post and possibly some owned elements.
|
325 |
*
|
326 |
-
* WIP
|
327 |
-
*
|
328 |
* @param int $post_id
|
329 |
* @since m2m
|
330 |
*/
|
@@ -333,15 +339,12 @@ class Toolset_Relationship_Controller {
|
|
333 |
$this->initialize_full();
|
334 |
|
335 |
try {
|
336 |
-
$
|
337 |
-
|
338 |
-
$assocation_repository = Toolset_Association_Repository::get_instance();
|
339 |
-
$assocation_repository->delete_associations_involving_element( $post );
|
340 |
-
|
341 |
-
// todo Query all post's associations and delete them. That should trigger deleting the intermediary posts and owned elements.
|
342 |
-
|
343 |
} catch( Exception $e ) {
|
344 |
-
|
|
|
|
|
345 |
}
|
346 |
}
|
347 |
|
@@ -360,20 +363,29 @@ class Toolset_Relationship_Controller {
|
|
360 |
* @since m2m
|
361 |
*/
|
362 |
private function set_initial_m2m_state() {
|
363 |
-
$
|
364 |
-
$has_legacy_relationships = ! empty( $legacy_relationships );
|
365 |
-
|
366 |
$is_ready_for_m2m = new Toolset_Condition_Plugin_Types_Ready_For_M2M();
|
367 |
|
368 |
-
$enable_m2m = ( $is_ready_for_m2m->is_met() && ! $has_legacy_relationships );
|
|
|
|
|
|
|
|
|
369 |
|
370 |
if( $enable_m2m ) {
|
371 |
$this->force_autoloader_initialization();
|
372 |
-
$migration = new
|
373 |
$migration->do_native_dbdelta();
|
374 |
}
|
375 |
|
376 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
377 |
return $enable_m2m;
|
378 |
}
|
379 |
|
@@ -403,4 +415,53 @@ class Toolset_Relationship_Controller {
|
|
403 |
$issue->handle();
|
404 |
}
|
405 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
406 |
}
|
17 |
private $_post_type_query_factory;
|
18 |
|
19 |
|
20 |
+
/** @var Toolset_Relationship_Database_Operations|null */
|
21 |
+
private $_database_operations;
|
22 |
+
|
23 |
+
|
24 |
+
/** @var null|Toolset_Association_Cleanup_Factory */
|
25 |
+
private $_cleanup_factory;
|
26 |
+
|
27 |
+
|
28 |
/** @var Toolset_Relationship_Controller|null */
|
29 |
private static $instance;
|
30 |
|
31 |
|
32 |
+
/**
|
33 |
+
* @return Toolset_Relationship_Controller
|
34 |
+
*/
|
35 |
public static function get_instance() {
|
36 |
if( null == self::$instance ) {
|
37 |
self::$instance = new self();
|
45 |
* Toolset_Relationship_Controller constructor.
|
46 |
*
|
47 |
* @param Toolset_Post_Type_Query_Factory|null $post_type_query_factory_di
|
48 |
+
* @param Toolset_Relationship_Database_Operations|null $database_operations_di
|
49 |
+
* @param Toolset_Association_Cleanup_Factory|null $cleanup_factory_di
|
50 |
*/
|
51 |
+
public function __construct(
|
52 |
+
Toolset_Post_Type_Query_Factory $post_type_query_factory_di = null,
|
53 |
+
Toolset_Relationship_Database_Operations $database_operations_di = null,
|
54 |
+
Toolset_Association_Cleanup_Factory $cleanup_factory_di = null
|
55 |
+
) {
|
56 |
$this->_post_type_query_factory = $post_type_query_factory_di;
|
57 |
+
$this->_database_operations = $database_operations_di;
|
58 |
+
$this->_cleanup_factory = $cleanup_factory_di;
|
59 |
}
|
60 |
|
61 |
|
62 |
const IS_M2M_ENABLED_OPTION = 'toolset_is_m2m_enabled';
|
63 |
+
const IS_M2M_ENABLED_YES_VALUE = 'yes';
|
64 |
+
|
65 |
+
// This is not a typo. Initially, we had 'no', but then we changed the algorithm to determine the initial
|
66 |
+
// m2m state, and we have force re-checking.
|
67 |
+
const IS_M2M_ENABLED_NO_VALUE = 'noo';
|
68 |
|
69 |
|
70 |
/**
|
97 |
|
98 |
$is_enabled = get_option( self::IS_M2M_ENABLED_OPTION, null );
|
99 |
|
100 |
+
// We'll force the check again if 'no' is stored, because the algorithm for determining
|
101 |
+
// the initial state has changed since (now a different value for a negative result is used).
|
102 |
+
if( null === $is_enabled || 'no' === $is_enabled ) {
|
103 |
$is_enabled = $this->set_initial_m2m_state();
|
104 |
} else {
|
105 |
+
$is_enabled = ( self::IS_M2M_ENABLED_YES_VALUE === $is_enabled );
|
106 |
}
|
107 |
|
108 |
/**
|
137 |
return;
|
138 |
}
|
139 |
|
|
|
|
|
140 |
$this->add_hooks();
|
141 |
+
$this->is_core_initialized = true;
|
142 |
}
|
143 |
|
144 |
|
166 |
// fixme: This is for the purpose of alpha and beta versions: If there's a database problem,
|
167 |
// at least make it fail on every request. Otherwise, we'll just waste a little performance
|
168 |
// on checking that the tables already exist.
|
169 |
+
// @refactoring
|
170 |
+
$migration = new Toolset_Relationship_Migration_Controller();
|
171 |
$migration->do_native_dbdelta();
|
172 |
|
173 |
$this->is_everything_initialized = true;
|
213 |
return;
|
214 |
}
|
215 |
|
216 |
+
add_action( 'admin_init', array( $this, 'on_admin_init' ) );
|
|
|
|
|
|
|
|
|
217 |
|
218 |
+
add_filter( 'before_delete_post', array( $this, 'on_before_delete_post' ) );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
219 |
|
220 |
/**
|
221 |
* toolset_relationship_query
|
245 |
* @since 2.5.6
|
246 |
*/
|
247 |
add_action( 'toolset_report_m2m_integrity_issue', array( $this, 'report_integrity_issue' ) );
|
|
|
248 |
|
249 |
|
250 |
+
/**
|
251 |
+
* toolset_cron_cleanup_dangling_intermediary_posts
|
252 |
+
*
|
253 |
+
* A WP-Cron event hook defined as Toolset_Association_Cleanup_Cron_Event.
|
254 |
+
*
|
255 |
+
* @since 2.5.10
|
256 |
+
*/
|
257 |
+
add_action( 'toolset_cron_cleanup_dangling_intermediary_posts', array( $this, 'cleanup_dangling_intermediary_posts' ) );
|
|
|
|
|
258 |
}
|
259 |
|
260 |
|
264 |
* @param $ignored
|
265 |
* @param $query_args
|
266 |
*
|
267 |
+
* @return int[]|Toolset_Association[]|Toolset_Element[]
|
268 |
*/
|
269 |
public function on_toolset_relationship_query( /** @noinspection PhpUnusedParameterInspection */ $ignored, $query_args ) {
|
270 |
$this->initialize_full();
|
289 |
|
290 |
$this->initialize_full();
|
291 |
|
292 |
+
$result = $this->get_database_operations()->update_type_on_type_sets( $new_slug, $old_slug );
|
|
|
293 |
|
294 |
if( $result->is_error() ) {
|
295 |
error_log( $result->get_message() );
|
331 |
* Basically, that means checking if there are any associations with this post and delete them.
|
332 |
* Note that that will also trigger deleting the intermediary post and possibly some owned elements.
|
333 |
*
|
|
|
|
|
334 |
* @param int $post_id
|
335 |
* @since m2m
|
336 |
*/
|
339 |
$this->initialize_full();
|
340 |
|
341 |
try {
|
342 |
+
$cleanup = $this->get_cleanup_factory()->post();
|
343 |
+
$cleanup->cleanup( $post_id );
|
|
|
|
|
|
|
|
|
|
|
344 |
} catch( Exception $e ) {
|
345 |
+
// Silently do nothing and avoid disrupting the current process, whatever it is.
|
346 |
+
// In the worst case, any potential dangling db stuff can be sorted out
|
347 |
+
// later on the Troubleshooting page.
|
348 |
}
|
349 |
}
|
350 |
|
363 |
* @since m2m
|
364 |
*/
|
365 |
private function set_initial_m2m_state() {
|
366 |
+
$has_legacy_relationships = new Toolset_Condition_Plugin_Types_Has_Legacy_Relationships();
|
|
|
|
|
367 |
$is_ready_for_m2m = new Toolset_Condition_Plugin_Types_Ready_For_M2M();
|
368 |
|
369 |
+
$enable_m2m = ( $is_ready_for_m2m->is_met() && ! $has_legacy_relationships->is_met() );
|
370 |
+
|
371 |
+
// If there are no relationships but Toolset is not ready for m2m yet (too old Types), we don't
|
372 |
+
// update the option, but keep trying until the update finally comes.
|
373 |
+
$store_m2m_state = $is_ready_for_m2m->is_met();
|
374 |
|
375 |
if( $enable_m2m ) {
|
376 |
$this->force_autoloader_initialization();
|
377 |
+
$migration = new Toolset_Relationship_Migration_Controller();
|
378 |
$migration->do_native_dbdelta();
|
379 |
}
|
380 |
|
381 |
+
if( $store_m2m_state ) {
|
382 |
+
update_option(
|
383 |
+
self::IS_M2M_ENABLED_OPTION,
|
384 |
+
( $enable_m2m ? self::IS_M2M_ENABLED_YES_VALUE : self::IS_M2M_ENABLED_NO_VALUE ),
|
385 |
+
true
|
386 |
+
);
|
387 |
+
}
|
388 |
+
|
389 |
return $enable_m2m;
|
390 |
}
|
391 |
|
415 |
$issue->handle();
|
416 |
}
|
417 |
}
|
418 |
+
|
419 |
+
|
420 |
+
/**
|
421 |
+
* @return Toolset_Relationship_Database_Operations
|
422 |
+
*/
|
423 |
+
private function get_database_operations() {
|
424 |
+
if( null === $this->_database_operations ) {
|
425 |
+
$this->initialize_full();
|
426 |
+
$this->_database_operations = new Toolset_Relationship_Database_Operations();
|
427 |
+
}
|
428 |
+
|
429 |
+
return $this->_database_operations;
|
430 |
+
}
|
431 |
+
|
432 |
+
|
433 |
+
/**
|
434 |
+
* @return Toolset_Association_Cleanup_Factory
|
435 |
+
*/
|
436 |
+
private function get_cleanup_factory() {
|
437 |
+
if( null === $this->_cleanup_factory ) {
|
438 |
+
$this->initialize_full();
|
439 |
+
$this->_cleanup_factory = new Toolset_Association_Cleanup_Factory();
|
440 |
+
}
|
441 |
+
|
442 |
+
return $this->_cleanup_factory;
|
443 |
+
}
|
444 |
+
|
445 |
+
|
446 |
+
/**
|
447 |
+
* Callback for the WP-Cron event defined as Toolset_Association_Cleanup_Cron_Event.
|
448 |
+
*
|
449 |
+
* @since 2.5.10
|
450 |
+
*/
|
451 |
+
public function cleanup_dangling_intermediary_posts() {
|
452 |
+
$this->initialize_full();
|
453 |
+
$cron_handler = $this->get_cleanup_factory()->cron_handler();
|
454 |
+
$cron_handler->handle_event();
|
455 |
+
}
|
456 |
+
|
457 |
+
|
458 |
+
/**
|
459 |
+
* This will run on admin_init:10 if m2m is enabled.
|
460 |
+
*
|
461 |
+
* @since 2.5.10
|
462 |
+
*/
|
463 |
+
public function on_admin_init() {
|
464 |
+
$this->initialize_full();
|
465 |
+
$this->get_cleanup_factory()->troubeshooting_section()->register();
|
466 |
+
}
|
467 |
}
|
vendor/toolset/toolset-common/inc/m2m/database/operations.php
CHANGED
@@ -6,7 +6,7 @@
|
|
6 |
* Throughout m2m API, only these classes should directly touch the database:
|
7 |
*
|
8 |
* - Toolset_Relationship_Database_Operations
|
9 |
-
* -
|
10 |
* - Toolset_Relationship_Driver
|
11 |
* - Toolset_Relationship_Translation_View_Management
|
12 |
* - Toolset_Association_Query
|
@@ -51,7 +51,6 @@ class Toolset_Relationship_Database_Operations {
|
|
51 |
$this->wpdb = $wpdb_di;
|
52 |
}
|
53 |
$this->table_name = ( null === $table_name_di ? new Toolset_Relationship_Table_Name() : $table_name_di );
|
54 |
-
|
55 |
}
|
56 |
|
57 |
|
@@ -85,6 +84,7 @@ class Toolset_Relationship_Database_Operations {
|
|
85 |
*
|
86 |
* @return IToolset_Association|Toolset_Result
|
87 |
* @since m2m
|
|
|
88 |
*/
|
89 |
public static function create_association( $relationship_definition_source, $parent_source, $child_source, $intermediary_id, $instantiate = true ) {
|
90 |
|
@@ -210,7 +210,7 @@ class Toolset_Relationship_Database_Operations {
|
|
210 |
*/
|
211 |
private function create_associations_table() {
|
212 |
|
213 |
-
$association_table_name =
|
214 |
|
215 |
if ( $this->table_exists( $association_table_name ) ) {
|
216 |
return;
|
@@ -219,17 +219,14 @@ class Toolset_Relationship_Database_Operations {
|
|
219 |
// Note that dbDelta is very sensitive about details, almost nothing here is arbitrary.
|
220 |
$query = "CREATE TABLE {$association_table_name} (
|
221 |
id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
translation_type enum('original','translation','none') NOT NULL DEFAULT 'none',
|
229 |
-
PRIMARY KEY id (id),
|
230 |
-
KEY relationship_id (relationship_id),
|
231 |
KEY parent_id (parent_id, relationship_id),
|
232 |
-
KEY child_id (child_id, relationship_id)
|
233 |
) " . $this->get_charset_collate() . ";";
|
234 |
|
235 |
self::dbdelta( $query );
|
@@ -253,36 +250,36 @@ class Toolset_Relationship_Database_Operations {
|
|
253 |
|
254 |
// Note that dbDelta is very sensitive about details, almost nothing here is arbitrary.
|
255 |
$query = "CREATE TABLE {$table_name} (
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
|
287 |
self::dbdelta( $query );
|
288 |
|
@@ -297,44 +294,18 @@ class Toolset_Relationship_Database_Operations {
|
|
297 |
|
298 |
// Note that dbDelta is very sensitive about details, almost nothing here is arbitrary.
|
299 |
$query = "CREATE TABLE {$table_name} (
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
|
308 |
self::dbdelta( $query );
|
309 |
}
|
310 |
|
311 |
|
312 |
-
/**
|
313 |
-
* Get the next unused value for trid (translation ID, grouping different translations of
|
314 |
-
* one association together).
|
315 |
-
*
|
316 |
-
* Assumes that this method will be always called before inserting a new trid, and that
|
317 |
-
* the returned trid is always used.
|
318 |
-
*
|
319 |
-
* @return int
|
320 |
-
*/
|
321 |
-
public static function get_next_trid() {
|
322 |
-
static $next_trid = 0;
|
323 |
-
|
324 |
-
if ( 0 === $next_trid ) {
|
325 |
-
global $wpdb;
|
326 |
-
$associations_table = Toolset_Relationship_Table_Name::associations();
|
327 |
-
$last_trid = $wpdb->get_var( "SELECT MAX(trid) FROM {$associations_table}" );
|
328 |
-
|
329 |
-
// It will be incremented and becomes unique in the next step
|
330 |
-
$next_trid = $last_trid;
|
331 |
-
}
|
332 |
-
|
333 |
-
$next_trid++;
|
334 |
-
|
335 |
-
return $next_trid;
|
336 |
-
}
|
337 |
-
|
338 |
|
339 |
/**
|
340 |
* When a relationship definition slug is renamed, update the association table (where the slug is used as a foreign key).
|
@@ -429,31 +400,31 @@ class Toolset_Relationship_Database_Operations {
|
|
429 |
$child_types_table_alias = 'child_types_table'
|
430 |
) {
|
431 |
return "
|
432 |
-
|
433 |
-
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
-
|
438 |
-
|
439 |
-
|
440 |
-
|
441 |
-
|
442 |
-
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
}
|
458 |
|
459 |
|
@@ -475,9 +446,9 @@ class Toolset_Relationship_Database_Operations {
|
|
475 |
$child_types_table_alias = 'child_types_table'
|
476 |
) {
|
477 |
return "
|
478 |
-
JOIN {$type_set_table_name} AS {$parent_types_table_alias}
|
479 |
ON ({$relationships_table_alias}.parent_types = {$parent_types_table_alias}.set_id )
|
480 |
-
JOIN {$type_set_table_name} AS {$child_types_table_alias}
|
481 |
ON ({$relationships_table_alias}.child_types = {$child_types_table_alias}.set_id )";
|
482 |
}
|
483 |
|
@@ -502,10 +473,10 @@ class Toolset_Relationship_Database_Operations {
|
|
502 |
// The query is so complex because it needs to bring in data from the type set tables. But
|
503 |
// those two joins are very cheap because we don't expect many records here.
|
504 |
$query = "
|
505 |
-
|
506 |
-
|
507 |
-
|
508 |
-
|
509 |
|
510 |
$rows = toolset_ensarr( $this->wpdb->get_results( $query ) );
|
511 |
return $rows;
|
@@ -545,4 +516,91 @@ class Toolset_Relationship_Database_Operations {
|
|
545 |
|
546 |
return new Toolset_Result( $is_success, $message );
|
547 |
}
|
548 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6 |
* Throughout m2m API, only these classes should directly touch the database:
|
7 |
*
|
8 |
* - Toolset_Relationship_Database_Operations
|
9 |
+
* - Toolset_Relationship_Migration_Controller
|
10 |
* - Toolset_Relationship_Driver
|
11 |
* - Toolset_Relationship_Translation_View_Management
|
12 |
* - Toolset_Association_Query
|
51 |
$this->wpdb = $wpdb_di;
|
52 |
}
|
53 |
$this->table_name = ( null === $table_name_di ? new Toolset_Relationship_Table_Name() : $table_name_di );
|
|
|
54 |
}
|
55 |
|
56 |
|
84 |
*
|
85 |
* @return IToolset_Association|Toolset_Result
|
86 |
* @since m2m
|
87 |
+
* @throws Toolset_Element_Exception_Element_Doesnt_Exist
|
88 |
*/
|
89 |
public static function create_association( $relationship_definition_source, $parent_source, $child_source, $intermediary_id, $instantiate = true ) {
|
90 |
|
210 |
*/
|
211 |
private function create_associations_table() {
|
212 |
|
213 |
+
$association_table_name = $this->table_name->association_table();
|
214 |
|
215 |
if ( $this->table_exists( $association_table_name ) ) {
|
216 |
return;
|
219 |
// Note that dbDelta is very sensitive about details, almost nothing here is arbitrary.
|
220 |
$query = "CREATE TABLE {$association_table_name} (
|
221 |
id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
|
222 |
+
relationship_id bigint(20) UNSIGNED NOT NULL,
|
223 |
+
parent_id bigint(20) UNSIGNED NOT NULL,
|
224 |
+
child_id bigint(20) UNSIGNED NOT NULL,
|
225 |
+
intermediary_id bigint(20) UNSIGNED NOT NULL,
|
226 |
+
PRIMARY KEY id (id),
|
227 |
+
KEY relationship_id (relationship_id),
|
|
|
|
|
|
|
228 |
KEY parent_id (parent_id, relationship_id),
|
229 |
+
KEY child_id (child_id, relationship_id)
|
230 |
) " . $this->get_charset_collate() . ";";
|
231 |
|
232 |
self::dbdelta( $query );
|
250 |
|
251 |
// Note that dbDelta is very sensitive about details, almost nothing here is arbitrary.
|
252 |
$query = "CREATE TABLE {$table_name} (
|
253 |
+
id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
|
254 |
+
slug varchar(" . self::MAXIMUM_RELATIONSHIP_SLUG_LENGTH . ") NOT NULL DEFAULT '',
|
255 |
+
display_name_plural varchar(255) NOT NULL DEFAULT '',
|
256 |
+
display_name_singular varchar(255) NOT NULL DEFAULT '',
|
257 |
+
driver varchar(50) NOT NULL DEFAULT '',
|
258 |
+
parent_domain varchar(20) NOT NULL DEFAULT '',
|
259 |
+
parent_types bigint(20) UNSIGNED NOT NULL DEFAULT 0,
|
260 |
+
child_domain varchar(20) NOT NULL DEFAULT '',
|
261 |
+
child_types bigint(20) UNSIGNED NOT NULL DEFAULT 0,
|
262 |
+
intermediary_type varchar(20) NOT NULL DEFAULT '',
|
263 |
+
ownership enum('parent', 'child', 'none') NOT NULL DEFAULT 'none',
|
264 |
+
cardinality_parent_max int(10) NOT NULL DEFAULT -1,
|
265 |
+
cardinality_parent_min int(10) NOT NULL DEFAULT 0,
|
266 |
+
cardinality_child_max int(10) NOT NULL DEFAULT -1,
|
267 |
+
cardinality_child_min int(10) NOT NULL DEFAULT 0,
|
268 |
+
is_distinct tinyint(1) NOT NULL DEFAULT 0,
|
269 |
+
scope longtext NOT NULL DEFAULT '',
|
270 |
+
origin varchar(50) NOT NULL DEFAULT '',
|
271 |
+
role_name_parent varchar(255) NOT NULL DEFAULT '',
|
272 |
+
role_name_child varchar(255) NOT NULL DEFAULT '',
|
273 |
+
role_name_intermediary varchar(255) NOT NULL DEFAULT '',
|
274 |
+
needs_legacy_support tinyint(1) NOT NULL DEFAULT 0,
|
275 |
+
is_active tinyint(1) NOT NULL DEFAULT 0,
|
276 |
+
PRIMARY KEY id (id),
|
277 |
+
KEY slug (slug),
|
278 |
+
KEY is_active (is_active),
|
279 |
+
KEY needs_legacy_support (needs_legacy_support),
|
280 |
+
KEY parent_type (parent_domain, parent_types),
|
281 |
+
KEY child_type (child_domain, child_types)
|
282 |
+
) " . $this->get_charset_collate() . ";";
|
283 |
|
284 |
self::dbdelta( $query );
|
285 |
|
294 |
|
295 |
// Note that dbDelta is very sensitive about details, almost nothing here is arbitrary.
|
296 |
$query = "CREATE TABLE {$table_name} (
|
297 |
+
id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
|
298 |
+
set_id bigint(20) UNSIGNED NOT NULL DEFAULT 0,
|
299 |
+
type varchar(20) NOT NULL DEFAULT '',
|
300 |
+
PRIMARY KEY id (id),
|
301 |
+
KEY set_id (set_id),
|
302 |
+
KEY type (type)
|
303 |
+
) " . $this->get_charset_collate() . ";";
|
304 |
|
305 |
self::dbdelta( $query );
|
306 |
}
|
307 |
|
308 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
309 |
|
310 |
/**
|
311 |
* When a relationship definition slug is renamed, update the association table (where the slug is used as a foreign key).
|
400 |
$child_types_table_alias = 'child_types_table'
|
401 |
) {
|
402 |
return "
|
403 |
+
$relationships_table_alias.id AS id,
|
404 |
+
$relationships_table_alias.slug AS slug,
|
405 |
+
$relationships_table_alias.display_name_plural AS display_name_plural,
|
406 |
+
$relationships_table_alias.display_name_singular AS display_name_singular,
|
407 |
+
$relationships_table_alias.driver AS driver,
|
408 |
+
$relationships_table_alias.parent_domain AS parent_domain,
|
409 |
+
$relationships_table_alias.child_domain AS child_domain,
|
410 |
+
$relationships_table_alias.intermediary_type AS intermediary_type,
|
411 |
+
$relationships_table_alias.ownership AS ownership,
|
412 |
+
$relationships_table_alias.cardinality_parent_max AS cardinality_parent_max,
|
413 |
+
$relationships_table_alias.cardinality_parent_min AS cardinality_parent_min,
|
414 |
+
$relationships_table_alias.cardinality_child_max AS cardinality_child_max,
|
415 |
+
$relationships_table_alias.cardinality_child_min AS cardinality_child_min,
|
416 |
+
$relationships_table_alias.is_distinct AS is_distinct,
|
417 |
+
$relationships_table_alias.scope AS scope,
|
418 |
+
$relationships_table_alias.origin AS origin,
|
419 |
+
$relationships_table_alias.role_name_parent AS role_name_parent,
|
420 |
+
$relationships_table_alias.role_name_child AS role_name_child,
|
421 |
+
$relationships_table_alias.role_name_intermediary AS role_name_intermediary,
|
422 |
+
$relationships_table_alias.needs_legacy_support AS needs_legacy_support,
|
423 |
+
$relationships_table_alias.is_active AS is_active,
|
424 |
+
$relationships_table_alias.parent_types AS parent_types_set_id,
|
425 |
+
$relationships_table_alias.child_types AS child_types_set_id,
|
426 |
+
GROUP_CONCAT(DISTINCT $parent_types_table_alias.type) AS parent_types,
|
427 |
+
GROUP_CONCAT(DISTINCT $child_types_table_alias.type) AS child_types";
|
428 |
}
|
429 |
|
430 |
|
446 |
$child_types_table_alias = 'child_types_table'
|
447 |
) {
|
448 |
return "
|
449 |
+
JOIN {$type_set_table_name} AS {$parent_types_table_alias}
|
450 |
ON ({$relationships_table_alias}.parent_types = {$parent_types_table_alias}.set_id )
|
451 |
+
JOIN {$type_set_table_name} AS {$child_types_table_alias}
|
452 |
ON ({$relationships_table_alias}.child_types = {$child_types_table_alias}.set_id )";
|
453 |
}
|
454 |
|
473 |
// The query is so complex because it needs to bring in data from the type set tables. But
|
474 |
// those two joins are very cheap because we don't expect many records here.
|
475 |
$query = "
|
476 |
+
SELECT {$this->get_standard_relationships_select_clause()}
|
477 |
+
FROM {$relationship_table} AS relationships
|
478 |
+
{$this->get_standard_relationships_join_clause( $type_set_table )}
|
479 |
+
GROUP BY {$this->get_standards_relationship_group_by_clause()}";
|
480 |
|
481 |
$rows = toolset_ensarr( $this->wpdb->get_results( $query ) );
|
482 |
return $rows;
|
516 |
|
517 |
return new Toolset_Result( $is_success, $message );
|
518 |
}
|
519 |
+
|
520 |
+
|
521 |
+
/**
|
522 |
+
* Queries all post's associations and delete them.
|
523 |
+
*
|
524 |
+
* That should trigger deleting the intermediary posts and owned elements.
|
525 |
+
*
|
526 |
+
* @param IToolset_Element $element
|
527 |
+
* @deprecated Should be unused since 2.5.10. Replaced by Toolset_Association_Cleanup_Post.
|
528 |
+
*/
|
529 |
+
public function delete_associations_involving_element( $element ) {
|
530 |
+
|
531 |
+
trigger_error(
|
532 |
+
'Toolset_Relationship_Database_Operations::delete_associations_involving_element() is deprecated and should not be used anymore.',
|
533 |
+
E_USER_NOTICE
|
534 |
+
);
|
535 |
+
|
536 |
+
$query_parent = new Toolset_Association_Query( array(
|
537 |
+
Toolset_Association_Query::QUERY_PARENT_DOMAIN => $element->get_domain(),
|
538 |
+
Toolset_Association_Query::QUERY_PARENT_ID => $element->get_id(),
|
539 |
+
Toolset_Association_Query::OPTION_RETURN => Toolset_Association_Query::RETURN_ASSOCIATIONS
|
540 |
+
) );
|
541 |
+
|
542 |
+
$associations = $query_parent->get_results();
|
543 |
+
|
544 |
+
$query_child = new Toolset_Association_Query( array(
|
545 |
+
Toolset_Association_Query::QUERY_PARENT_DOMAIN => $element->get_domain(),
|
546 |
+
Toolset_Association_Query::QUERY_PARENT_ID => $element->get_id(),
|
547 |
+
Toolset_Association_Query::OPTION_RETURN => Toolset_Association_Query::RETURN_ASSOCIATIONS
|
548 |
+
) );
|
549 |
+
|
550 |
+
/** @var Toolset_Association[] $associations */
|
551 |
+
$associations = array_merge( $associations, $query_child->get_results() );
|
552 |
+
|
553 |
+
foreach( $associations as $association ) {
|
554 |
+
$definition = $association->get_definition();
|
555 |
+
$driver = $definition->get_driver();
|
556 |
+
$driver->delete_association( $association );
|
557 |
+
}
|
558 |
+
|
559 |
+
}
|
560 |
+
|
561 |
+
|
562 |
+
/**
|
563 |
+
* Updates association intermediary post
|
564 |
+
*
|
565 |
+
* @param int $association_id Association trID
|
566 |
+
* @param int $intermediary_id New intermediary ID
|
567 |
+
* @since m2m
|
568 |
+
*/
|
569 |
+
public function update_association_intermediary_id( $association_id, $intermediary_id ) {
|
570 |
+
$this->wpdb->update(
|
571 |
+
$this->table_name->association_table(),
|
572 |
+
array(
|
573 |
+
'intermediary_id' => $intermediary_id,
|
574 |
+
),
|
575 |
+
array(
|
576 |
+
'id' => $association_id,
|
577 |
+
),
|
578 |
+
array( '%d' )
|
579 |
+
);
|
580 |
+
}
|
581 |
+
|
582 |
+
|
583 |
+
/**
|
584 |
+
* Returns the maximun number of associations of a relationship for a parent id and a child id
|
585 |
+
*
|
586 |
+
* @param int $relationship_id Relationship ID.
|
587 |
+
* @param string $role_name Role name.
|
588 |
+
* @return int
|
589 |
+
* @throws InvalidArgumentException In case of error.
|
590 |
+
*/
|
591 |
+
public function count_max_associations( $relationship_id, $role_name ) {
|
592 |
+
if ( ! in_array( $role_name, Toolset_Relationship_Role::parent_child_role_names() ) ) {
|
593 |
+
throw new InvalidArgumentException( 'Wrong role name' );
|
594 |
+
}
|
595 |
+
$count = $this->wpdb->get_var(
|
596 |
+
$this->wpdb->prepare(
|
597 |
+
"SELECT max(n) count
|
598 |
+
FROM (
|
599 |
+
SELECT count(*) n
|
600 |
+
FROM `wp_toolset_associations`
|
601 |
+
WHERE relationship_id = %d
|
602 |
+
GROUP BY {$role_name}_id
|
603 |
+
) count", $relationship_id ) );
|
604 |
+
return $count;
|
605 |
+
}
|
606 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/driver.php
CHANGED
@@ -21,19 +21,18 @@ class Toolset_Relationship_Driver extends Toolset_Relationship_Driver_Base {
|
|
21 |
* @param int|Toolset_Element|WP_Post $child_source
|
22 |
* @param array $args Association arguments:
|
23 |
* - 'intermediary_id': ID of the intermediary post; defaults to zero.
|
24 |
-
* - 'instantiate': bool Whether to return an association on success, or just a result. Default is false
|
25 |
*
|
26 |
-
*
|
27 |
-
*
|
28 |
-
* @
|
29 |
*/
|
30 |
public function create_association( $parent_source, $child_source, $args = array() ) {
|
31 |
|
32 |
$relationship_definition = $this->get_relationship_definition();
|
33 |
|
34 |
// This will throw when the elements don't exist
|
35 |
-
$parent =
|
36 |
-
$child =
|
37 |
|
38 |
// We need to make sure the association is allowed.
|
39 |
$potential_association_query = $this->get_potential_association_query_factory()->create(
|
@@ -49,22 +48,26 @@ class Toolset_Relationship_Driver extends Toolset_Relationship_Driver_Base {
|
|
49 |
|
50 |
$intermediary_id = (int) toolset_getarr( $args, 'intermediary_id', 0 );
|
51 |
|
52 |
-
// Create intermediary post if
|
53 |
-
|
54 |
-
|
55 |
-
$intermediary_id = (int) $
|
56 |
}
|
57 |
|
58 |
-
// Insert the database records as needed, respecting the status of WPML and
|
59 |
-
// existing translations of related items.
|
60 |
-
$intermediary = ( 0 !== $intermediary_id ? Toolset_Post::get_instance( $intermediary_id ) : null );
|
61 |
try {
|
62 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
63 |
} catch( Exception $e ) {
|
64 |
return new Toolset_Result(
|
65 |
false,
|
66 |
sprintf(
|
67 |
-
__( '
|
68 |
$e->getMessage()
|
69 |
)
|
70 |
);
|
@@ -73,9 +76,7 @@ class Toolset_Relationship_Driver extends Toolset_Relationship_Driver_Base {
|
|
73 |
// Get the association instance (in the best language available)
|
74 |
$instantiate_association = (bool) toolset_getarr( $args, 'instantiate', false );
|
75 |
if ( $instantiate_association ) {
|
76 |
-
|
77 |
-
|
78 |
-
return $association;
|
79 |
} else {
|
80 |
return new Toolset_Result( true, __( 'Association created', 'wpcf' ) );
|
81 |
}
|
@@ -83,255 +84,6 @@ class Toolset_Relationship_Driver extends Toolset_Relationship_Driver_Base {
|
|
83 |
}
|
84 |
|
85 |
|
86 |
-
/**
|
87 |
-
* Return one instance of Toolset_Association, choosing the best language version.
|
88 |
-
*
|
89 |
-
* @param $insert_results
|
90 |
-
* @param $relationship_definition
|
91 |
-
*
|
92 |
-
* @return IToolset_Association
|
93 |
-
*/
|
94 |
-
private function instantiate_after_insert( $insert_results, $relationship_definition ) {
|
95 |
-
|
96 |
-
// Prepare results into lang => ID arrays for each element.
|
97 |
-
$element_sources = array(
|
98 |
-
Toolset_Relationship_Role::PARENT => array(),
|
99 |
-
Toolset_Relationship_Role::CHILD => array(),
|
100 |
-
Toolset_Relationship_Role::INTERMEDIARY => array()
|
101 |
-
);
|
102 |
-
|
103 |
-
foreach ( $insert_results as $language_code => $insert_result ) {
|
104 |
-
foreach ( Toolset_Relationship_Role::all_role_names() as $role_name ) {
|
105 |
-
$element_sources[ $role_name ][ $language_code ] = $insert_result['elements'][ $role_name ];
|
106 |
-
}
|
107 |
-
}
|
108 |
-
|
109 |
-
// Get a trid of the association (which is the same for all language versions).
|
110 |
-
$single_language_version = array_slice( $insert_results, 0, 1 );
|
111 |
-
$any_language_version = array_shift( $single_language_version );
|
112 |
-
$trid = $any_language_version['trid'];
|
113 |
-
|
114 |
-
$association = Toolset_Association_Repository::get_instance()->instantiate(
|
115 |
-
$relationship_definition,
|
116 |
-
$trid,
|
117 |
-
$element_sources
|
118 |
-
);
|
119 |
-
|
120 |
-
return $association;
|
121 |
-
}
|
122 |
-
|
123 |
-
|
124 |
-
/**
|
125 |
-
* Get all translations of given element.
|
126 |
-
*
|
127 |
-
* For non-posts, non-translatable posts or when WPML is not active, it will not attempt any translation.
|
128 |
-
*
|
129 |
-
* @param IToolset_Element|null $element
|
130 |
-
*
|
131 |
-
* @return int[] Associative array of post IDs, keys are language codes.
|
132 |
-
*/
|
133 |
-
private function get_post_translations_or_default( $element ) {
|
134 |
-
if ( ! $element instanceof Toolset_Element ) {
|
135 |
-
return array( '' => 0 );
|
136 |
-
} elseif (
|
137 |
-
! $element instanceof Toolset_Post
|
138 |
-
|| ! Toolset_Relationship_Multilingual_Mode::is_on()
|
139 |
-
|| ! $element->is_translatable()
|
140 |
-
) {
|
141 |
-
return array( '' => $element->get_id() );
|
142 |
-
}
|
143 |
-
|
144 |
-
return Toolset_Wpml_Utils::get_post_translations_directly( $element->get_id() );
|
145 |
-
}
|
146 |
-
|
147 |
-
|
148 |
-
/**
|
149 |
-
* Get the complete translation information for given elements, organized into triplets by language.
|
150 |
-
*
|
151 |
-
* If WPML is not active or the element is not translatable, it will have language '' (empty string).
|
152 |
-
* If a particular element translation is missing, there will be a zero instead the translation ID.
|
153 |
-
*
|
154 |
-
* @param IToolset_Element $parent
|
155 |
-
* @param IToolset_Element $child
|
156 |
-
* @param Toolset_Post|null $intermediary
|
157 |
-
*
|
158 |
-
* @return array[string] Associative array of triplets, where keys are language codes and each
|
159 |
-
* triplet always contains items for the parent, child and intermediary post IDs (or zero if
|
160 |
-
* no translation is available).
|
161 |
-
*/
|
162 |
-
private function get_translation_triplets( $parent, $child, $intermediary ) {
|
163 |
-
|
164 |
-
$parent_translations = $this->get_post_translations_or_default( $parent );
|
165 |
-
$child_translations = $this->get_post_translations_or_default( $child );
|
166 |
-
$intermediary_translations = $this->get_post_translations_or_default( $intermediary );
|
167 |
-
|
168 |
-
$present_languages = array_unique(
|
169 |
-
array_merge(
|
170 |
-
array_keys( $parent_translations ),
|
171 |
-
array_keys( $child_translations ),
|
172 |
-
array_keys( $intermediary_translations )
|
173 |
-
)
|
174 |
-
);
|
175 |
-
|
176 |
-
|
177 |
-
$translations = array();
|
178 |
-
foreach ( $present_languages as $language_code ) {
|
179 |
-
$parent_id = toolset_getarr( $parent_translations, $language_code, 0 );
|
180 |
-
$child_id = toolset_getarr( $child_translations, $language_code, 0 );
|
181 |
-
$intermediary_id = toolset_getarr( $intermediary_translations, $language_code, 0 );
|
182 |
-
|
183 |
-
if ( 0 === $parent_id && 0 === $child_id ) {
|
184 |
-
// There are no actual elements to associate, skip this language
|
185 |
-
continue;
|
186 |
-
}
|
187 |
-
|
188 |
-
$translations[ $language_code ] = array(
|
189 |
-
Toolset_Relationship_Role::PARENT => $parent_id,
|
190 |
-
Toolset_Relationship_Role::CHILD => $child_id,
|
191 |
-
Toolset_Relationship_Role::INTERMEDIARY => $intermediary_id
|
192 |
-
);
|
193 |
-
}
|
194 |
-
|
195 |
-
return $translations;
|
196 |
-
}
|
197 |
-
|
198 |
-
|
199 |
-
/**
|
200 |
-
* Get all available translations of given elements and create the appropriate
|
201 |
-
* records in the associations table.
|
202 |
-
*
|
203 |
-
* @param IToolset_Element $parent
|
204 |
-
* @param IToolset_Element $child
|
205 |
-
* @param Toolset_Post|null $intermediary
|
206 |
-
*
|
207 |
-
* @return array Translation results. Each key is a language code (can be an empty string if
|
208 |
-
* the language information is not available) and the item is an associative array with
|
209 |
-
* following elements:
|
210 |
-
* - id: The association ID for this language.
|
211 |
-
* - trid: Association trid (same for all languages).
|
212 |
-
* - elements: A "translation triplet" of element IDs in this language (or 0 where no translation exists)
|
213 |
-
* - translation_type: 'none'|'original'|'translation'
|
214 |
-
*
|
215 |
-
* @since m2m
|
216 |
-
*/
|
217 |
-
private function translate_and_insert( $parent, $child, $intermediary ) {
|
218 |
-
|
219 |
-
global $wpdb;
|
220 |
-
|
221 |
-
$translations = $this->get_translation_triplets( $parent, $child, $intermediary );
|
222 |
-
|
223 |
-
// We're going to need a unique trid to bind translations together.
|
224 |
-
// Even if we don't use WPML, trid is still needed for grouping records in the associations table.
|
225 |
-
$trid = Toolset_Relationship_Database_Operations::get_next_trid();
|
226 |
-
|
227 |
-
$translation_type = 'none';
|
228 |
-
$has_translations = ! ( 1 === count( $translations ) && array_key_exists( '', $translations ) );
|
229 |
-
|
230 |
-
$insert_results = array();
|
231 |
-
foreach ( $translations as $language_code => $elements ) {
|
232 |
-
|
233 |
-
if ( $has_translations ) {
|
234 |
-
$translation_type = $this->determine_translation_type( $elements, $parent, $child, $intermediary, $language_code );
|
235 |
-
}
|
236 |
-
|
237 |
-
$affected_rows = $wpdb->insert(
|
238 |
-
Toolset_Relationship_Table_Name::associations(),
|
239 |
-
array(
|
240 |
-
'relationship_id' => $this->get_relationship_definition()->get_row_id(),
|
241 |
-
'parent_id' => $elements[ Toolset_Relationship_Role::PARENT ],
|
242 |
-
'child_id' => $elements[ Toolset_Relationship_Role::CHILD ],
|
243 |
-
'intermediary_id' => $elements[ Toolset_Relationship_Role::INTERMEDIARY ],
|
244 |
-
'trid' => $trid,
|
245 |
-
'lang' => $language_code,
|
246 |
-
'translation_type' => $translation_type
|
247 |
-
),
|
248 |
-
array(
|
249 |
-
'%s',
|
250 |
-
'%d',
|
251 |
-
'%d',
|
252 |
-
'%d',
|
253 |
-
'%d',
|
254 |
-
'%s',
|
255 |
-
'%s'
|
256 |
-
)
|
257 |
-
);
|
258 |
-
|
259 |
-
if ( false == $affected_rows ) {
|
260 |
-
throw new RuntimeException( __( 'Error when inserting a row in the associations table.', 'wpcf' ) );
|
261 |
-
}
|
262 |
-
|
263 |
-
$association_id = $wpdb->insert_id;
|
264 |
-
|
265 |
-
if ( ! Toolset_Utils::is_natural_numeric( $association_id ) ) {
|
266 |
-
// Not an ID, fail
|
267 |
-
throw new RuntimeException( __( 'Unable to obtain an ID of the newly created association.', 'wpcf' ) );
|
268 |
-
}
|
269 |
-
|
270 |
-
$insert_results[ $language_code ] = array(
|
271 |
-
'id' => $association_id,
|
272 |
-
'trid' => $trid,
|
273 |
-
'elements' => $elements,
|
274 |
-
'translation_type' => $translation_type
|
275 |
-
);
|
276 |
-
|
277 |
-
}
|
278 |
-
|
279 |
-
return $insert_results;
|
280 |
-
}
|
281 |
-
|
282 |
-
|
283 |
-
/**
|
284 |
-
* Compare elements from a particular language version with the original ones and decide the
|
285 |
-
* translation type.
|
286 |
-
*
|
287 |
-
* The match of elements is required per each role, unless the original element is nontranslatable (
|
288 |
-
* or missing). When no language code is provided, the translation type is automatically 'none'.
|
289 |
-
*
|
290 |
-
* @param int[] $elements Element IDs, indexed by role names.
|
291 |
-
* @param IToolset_Element $original_parent
|
292 |
-
* @param IToolset_Element $original_child
|
293 |
-
* @param Toolset_Post|null $original_intermediary
|
294 |
-
* @param string $language_code
|
295 |
-
*
|
296 |
-
* @return string 'none'|'original'|'translation'
|
297 |
-
*/
|
298 |
-
private function determine_translation_type( $elements, $original_parent, $original_child, $original_intermediary, $language_code ) {
|
299 |
-
if ( '' === $language_code ) {
|
300 |
-
return 'none';
|
301 |
-
}
|
302 |
-
|
303 |
-
$is_original = (
|
304 |
-
$this->is_element_original_or_untranslatable( $elements, Toolset_Relationship_Role::PARENT, $original_parent )
|
305 |
-
&& $this->is_element_original_or_untranslatable( $elements, Toolset_Relationship_Role::CHILD, $original_child )
|
306 |
-
&& $this->is_element_original_or_untranslatable( $elements, Toolset_Relationship_Role::INTERMEDIARY, $original_intermediary )
|
307 |
-
);
|
308 |
-
|
309 |
-
return ( $is_original ? 'original' : 'translation' );
|
310 |
-
}
|
311 |
-
|
312 |
-
|
313 |
-
/**
|
314 |
-
* Check if a particular elements match IDs or are untranslatable.
|
315 |
-
*
|
316 |
-
* @param int[] $elements_to_check
|
317 |
-
* @param string $role
|
318 |
-
* @param IToolset_Element $original_element
|
319 |
-
*
|
320 |
-
* @return bool
|
321 |
-
*/
|
322 |
-
private function is_element_original_or_untranslatable( $elements_to_check, $role, $original_element ) {
|
323 |
-
|
324 |
-
$original_element_id = ( null === $original_element ? 0 : $original_element->get_id() );
|
325 |
-
|
326 |
-
$result = (
|
327 |
-
$elements_to_check[ $role ] == $original_element_id
|
328 |
-
|| ! $original_element->is_translatable()
|
329 |
-
);
|
330 |
-
|
331 |
-
return $result;
|
332 |
-
}
|
333 |
-
|
334 |
-
|
335 |
/**
|
336 |
* Get the slug of the indermediary post type that holds association fields.
|
337 |
*
|
@@ -483,173 +235,20 @@ class Toolset_Relationship_Driver extends Toolset_Relationship_Driver_Base {
|
|
483 |
}
|
484 |
|
485 |
|
486 |
-
/**
|
487 |
-
* Create an intermediary post for a new association.
|
488 |
-
*
|
489 |
-
* @param int $parent_id
|
490 |
-
* @param int $child_id
|
491 |
-
*
|
492 |
-
* @return int|null ID of the new post or null if the post creation failed.
|
493 |
-
* @since m2m
|
494 |
-
*/
|
495 |
-
private function create_intermediary_post( $parent_id, $child_id ) {
|
496 |
-
$post_type = $this->get_intermediary_post_type();
|
497 |
-
|
498 |
-
if ( null == $post_type ) {
|
499 |
-
return null;
|
500 |
-
}
|
501 |
-
|
502 |
-
/**
|
503 |
-
* toolset_build_intermediary_post_title
|
504 |
-
*
|
505 |
-
* Allow for overriding the post title of an intermediary post.
|
506 |
-
*
|
507 |
-
* @param string $post_title Post title default value.
|
508 |
-
* @param string $relationship_slug
|
509 |
-
* @param int $parent_id
|
510 |
-
* @param int $child_id
|
511 |
-
*
|
512 |
-
* @since m2m
|
513 |
-
*/
|
514 |
-
$post_title = wp_strip_all_tags(
|
515 |
-
apply_filters(
|
516 |
-
'toolset_build_intermediary_post_title',
|
517 |
-
$this->get_default_intermediary_post_title( $parent_id, $child_id ),
|
518 |
-
$this->get_relationship_slug(),
|
519 |
-
$parent_id,
|
520 |
-
$child_id
|
521 |
-
)
|
522 |
-
);
|
523 |
-
|
524 |
-
/**
|
525 |
-
* toolset_build_intermediary_post_name
|
526 |
-
*
|
527 |
-
* Allow for overriding the post name (slug) of an intermediary post.
|
528 |
-
*
|
529 |
-
* @param string $post_slug Post slug default value.
|
530 |
-
* @param string $relationship_slug
|
531 |
-
* @param int $parent_id
|
532 |
-
* @param int $child_id
|
533 |
-
*
|
534 |
-
* @since m2m
|
535 |
-
*/
|
536 |
-
$post_name = apply_filters(
|
537 |
-
'toolset_build_intermediary_post_name',
|
538 |
-
$post_title,
|
539 |
-
$this->get_relationship_slug(),
|
540 |
-
$parent_id,
|
541 |
-
$child_id
|
542 |
-
);
|
543 |
-
|
544 |
-
$result = wp_insert_post(
|
545 |
-
array(
|
546 |
-
'post_type' => $post_type,
|
547 |
-
'post_title' => $post_title,
|
548 |
-
'post_name' => $post_name,
|
549 |
-
'post_content' => '',
|
550 |
-
'post_status' => 'publish'
|
551 |
-
),
|
552 |
-
true
|
553 |
-
);
|
554 |
-
|
555 |
-
if ( $result instanceof WP_Error ) {
|
556 |
-
return null;
|
557 |
-
} else {
|
558 |
-
return $result;
|
559 |
-
}
|
560 |
-
}
|
561 |
-
|
562 |
-
|
563 |
-
private function get_default_intermediary_post_title( $parent_id, $child_id ) {
|
564 |
-
// Todo improve this - allow for specifying a default template in the relationship definition
|
565 |
-
$relationship_definition = $this->get_relationship_definition();
|
566 |
-
|
567 |
-
return sprintf(
|
568 |
-
'%s: %d - %d',
|
569 |
-
$relationship_definition->get_display_name(),
|
570 |
-
$parent_id,
|
571 |
-
$child_id
|
572 |
-
);
|
573 |
-
}
|
574 |
-
|
575 |
-
|
576 |
/**
|
577 |
* Delete an association from the database.
|
578 |
*
|
579 |
* Also delete an intermediary post if it exists.
|
580 |
*
|
581 |
-
* @param Toolset_Association $association
|
582 |
*
|
583 |
* @return Toolset_Result
|
|
|
|
|
584 |
* @since m2m
|
585 |
*/
|
586 |
public function delete_association( $association ) {
|
587 |
-
|
588 |
-
if ( ! $this->is_association_match( $association ) ) {
|
589 |
-
throw new InvalidArgumentException();
|
590 |
-
}
|
591 |
-
|
592 |
-
// Trigger the association translation view refresh.
|
593 |
-
// fixme probably no longer needed
|
594 |
-
$view_management = Toolset_Relationship_WPML_Interoperability::get_instance();
|
595 |
-
$view_management->before_association_delete( $association );
|
596 |
-
|
597 |
-
$this->maybe_delete_intermediary_post( $association );
|
598 |
-
|
599 |
-
global $wpdb;
|
600 |
-
|
601 |
-
$rows_updated = $wpdb->delete(
|
602 |
-
Toolset_Relationship_Table_Name::associations(),
|
603 |
-
// todo make this clearer - add a method to specifically query for trid
|
604 |
-
array( 'trid' => $association->get_uid() ),
|
605 |
-
'%d'
|
606 |
-
);
|
607 |
-
|
608 |
-
$is_success = ( false !== $rows_updated || 1 === $rows_updated );
|
609 |
-
|
610 |
-
return new Toolset_Result( $is_success );
|
611 |
-
}
|
612 |
-
|
613 |
-
|
614 |
-
/**
|
615 |
-
* Delete the intermediary post if it exists and it's not disabled by a filter.
|
616 |
-
*
|
617 |
-
* fixme probably need to delete its translations too (in that case, rename)
|
618 |
-
*
|
619 |
-
* @param Toolset_Association $association
|
620 |
-
*/
|
621 |
-
private function maybe_delete_intermediary_post( $association ) {
|
622 |
-
|
623 |
-
if ( $association->has_intermediary_post() ) {
|
624 |
-
$intermediary_id = $association->get_intermediary_id();
|
625 |
-
|
626 |
-
/**
|
627 |
-
* toolset_deleting_association_intermediary_post
|
628 |
-
*
|
629 |
-
* Notify about deleting the intermediary post and allow avoiding it.
|
630 |
-
*
|
631 |
-
* @param bool $delete_post Whether the post should be deleted.
|
632 |
-
* @param int $intermediary_id ID of the intermediary post.
|
633 |
-
* @param int $association_uid Unique identifier of the (native) association that is removing it
|
634 |
-
* @param Toolset_Association $association The association object.
|
635 |
-
*/
|
636 |
-
$delete_post = apply_filters(
|
637 |
-
'toolset_deleting_association_intermediary_post',
|
638 |
-
true,
|
639 |
-
$intermediary_id,
|
640 |
-
$association->get_uid(),
|
641 |
-
$association
|
642 |
-
);
|
643 |
-
|
644 |
-
if ( $delete_post ) {
|
645 |
-
wp_delete_post( $intermediary_id );
|
646 |
-
}
|
647 |
-
}
|
648 |
-
}
|
649 |
-
|
650 |
-
|
651 |
-
protected function is_association_match( $association ) {
|
652 |
-
return ( parent::is_association_match( $association ) && $association instanceof Toolset_Association );
|
653 |
}
|
654 |
|
655 |
}
|
21 |
* @param int|Toolset_Element|WP_Post $child_source
|
22 |
* @param array $args Association arguments:
|
23 |
* - 'intermediary_id': ID of the intermediary post; defaults to zero.
|
|
|
24 |
*
|
25 |
+
* @return IToolset_Association|Toolset_Result ID of the new association on success or a result information with an
|
26 |
+
* error.
|
27 |
+
* @throws Toolset_Element_Exception_Element_Doesnt_Exist
|
28 |
*/
|
29 |
public function create_association( $parent_source, $child_source, $args = array() ) {
|
30 |
|
31 |
$relationship_definition = $this->get_relationship_definition();
|
32 |
|
33 |
// This will throw when the elements don't exist
|
34 |
+
$parent = $this->get_element_factory()->get_element( $relationship_definition->get_parent_domain(), $parent_source );
|
35 |
+
$child = $this->get_element_factory()->get_element( $relationship_definition->get_child_domain(), $child_source );
|
36 |
|
37 |
// We need to make sure the association is allowed.
|
38 |
$potential_association_query = $this->get_potential_association_query_factory()->create(
|
48 |
|
49 |
$intermediary_id = (int) toolset_getarr( $args, 'intermediary_id', 0 );
|
50 |
|
51 |
+
// Create intermediary post if doesn't exist.
|
52 |
+
if ( 0 === $intermediary_id ) {
|
53 |
+
$association_helper = new Toolset_Association_Intermediary_Post_Persistence( $relationship_definition );
|
54 |
+
$intermediary_id = (int) $association_helper->create_intermediary_post( $parent->get_id(), $child->get_id() );
|
55 |
}
|
56 |
|
|
|
|
|
|
|
57 |
try {
|
58 |
+
$association = $this->association_factory->create(
|
59 |
+
$relationship_definition,
|
60 |
+
$parent->get_id(),
|
61 |
+
$child->get_id(),
|
62 |
+
$intermediary_id
|
63 |
+
);
|
64 |
+
|
65 |
+
$updated_association = $this->association_persistence->insert_association( $association );
|
66 |
} catch( Exception $e ) {
|
67 |
return new Toolset_Result(
|
68 |
false,
|
69 |
sprintf(
|
70 |
+
__( 'An error occurred when creating an association: %s', 'wpcf' ),
|
71 |
$e->getMessage()
|
72 |
)
|
73 |
);
|
76 |
// Get the association instance (in the best language available)
|
77 |
$instantiate_association = (bool) toolset_getarr( $args, 'instantiate', false );
|
78 |
if ( $instantiate_association ) {
|
79 |
+
return $updated_association;
|
|
|
|
|
80 |
} else {
|
81 |
return new Toolset_Result( true, __( 'Association created', 'wpcf' ) );
|
82 |
}
|
84 |
}
|
85 |
|
86 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
87 |
/**
|
88 |
* Get the slug of the indermediary post type that holds association fields.
|
89 |
*
|
235 |
}
|
236 |
|
237 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
238 |
/**
|
239 |
* Delete an association from the database.
|
240 |
*
|
241 |
* Also delete an intermediary post if it exists.
|
242 |
*
|
243 |
+
* @param Toolset_Association|IToolset_Association $association
|
244 |
*
|
245 |
* @return Toolset_Result
|
246 |
+
*
|
247 |
+
* @deprecated Use Toolset_Association_Persistence::delete_association() instead.
|
248 |
* @since m2m
|
249 |
*/
|
250 |
public function delete_association( $association ) {
|
251 |
+
return $this->association_persistence->delete_association( $association );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
252 |
}
|
253 |
|
254 |
}
|
vendor/toolset/toolset-common/inc/m2m/driver_base.php
CHANGED
@@ -9,30 +9,56 @@
|
|
9 |
*/
|
10 |
abstract class Toolset_Relationship_Driver_Base {
|
11 |
|
|
|
12 |
/** @var Toolset_Relationship_Definition */
|
13 |
private $definition;
|
14 |
|
|
|
15 |
/** @var array Driver setup array provided by the relationship definition. */
|
16 |
private $setup;
|
17 |
|
|
|
18 |
/** @var null|Toolset_Potential_Association_Query_Factory */
|
19 |
private $_potential_association_query_factory;
|
20 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
/**
|
22 |
* Toolset_Relationship_Driver_Base constructor.
|
23 |
*
|
24 |
* @param Toolset_Relationship_Definition $definition Relationship definition that is going to be using this driver.
|
25 |
* @param array $setup Driver setup array provided by the relationship definition.
|
26 |
* @param Toolset_Potential_Association_Query_Factory|null $pa_query_factory_di
|
|
|
|
|
|
|
27 |
*
|
28 |
* @since m2m
|
29 |
*/
|
30 |
public function __construct(
|
31 |
-
Toolset_Relationship_Definition $definition,
|
|
|
|
|
|
|
|
|
|
|
32 |
) {
|
33 |
$this->definition = $definition;
|
34 |
$this->setup = toolset_ensarr( $setup );
|
35 |
$this->_potential_association_query_factory = $pa_query_factory_di;
|
|
|
|
|
|
|
36 |
}
|
37 |
|
38 |
|
@@ -58,7 +84,7 @@ abstract class Toolset_Relationship_Driver_Base {
|
|
58 |
* @param int|Toolset_Element|WP_Post $child_source
|
59 |
* @param array $args Optional arguments, implementation-specific
|
60 |
*
|
61 |
-
* @return
|
62 |
*/
|
63 |
public abstract function create_association( $parent_source, $child_source, $args = array() );
|
64 |
|
@@ -66,7 +92,7 @@ abstract class Toolset_Relationship_Driver_Base {
|
|
66 |
/**
|
67 |
* Delete an association from the database.
|
68 |
*
|
69 |
-
* @param
|
70 |
*
|
71 |
* @return Toolset_Result
|
72 |
* @since m2m
|
@@ -129,7 +155,7 @@ abstract class Toolset_Relationship_Driver_Base {
|
|
129 |
|
130 |
|
131 |
protected function is_association_match( $association ) {
|
132 |
-
return ( $association instanceof
|
133 |
}
|
134 |
|
135 |
|
@@ -144,4 +170,17 @@ abstract class Toolset_Relationship_Driver_Base {
|
|
144 |
|
145 |
return $this->_potential_association_query_factory;
|
146 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
147 |
}
|
9 |
*/
|
10 |
abstract class Toolset_Relationship_Driver_Base {
|
11 |
|
12 |
+
|
13 |
/** @var Toolset_Relationship_Definition */
|
14 |
private $definition;
|
15 |
|
16 |
+
|
17 |
/** @var array Driver setup array provided by the relationship definition. */
|
18 |
private $setup;
|
19 |
|
20 |
+
|
21 |
/** @var null|Toolset_Potential_Association_Query_Factory */
|
22 |
private $_potential_association_query_factory;
|
23 |
|
24 |
+
|
25 |
+
/** @var Toolset_Association_Persistence */
|
26 |
+
protected $association_persistence;
|
27 |
+
|
28 |
+
|
29 |
+
/** @var Toolset_Association_Factory */
|
30 |
+
protected $association_factory;
|
31 |
+
|
32 |
+
/** @var null|Toolset_Element_Factory */
|
33 |
+
private $_element_factory;
|
34 |
+
|
35 |
+
|
36 |
/**
|
37 |
* Toolset_Relationship_Driver_Base constructor.
|
38 |
*
|
39 |
* @param Toolset_Relationship_Definition $definition Relationship definition that is going to be using this driver.
|
40 |
* @param array $setup Driver setup array provided by the relationship definition.
|
41 |
* @param Toolset_Potential_Association_Query_Factory|null $pa_query_factory_di
|
42 |
+
* @param Toolset_Association_Persistence|null $association_persistence_di
|
43 |
+
* @param Toolset_Association_Factory|null $association_factory_di
|
44 |
+
* @param Toolset_Element_Factory|null $element_factory_di
|
45 |
*
|
46 |
* @since m2m
|
47 |
*/
|
48 |
public function __construct(
|
49 |
+
Toolset_Relationship_Definition $definition,
|
50 |
+
$setup,
|
51 |
+
Toolset_Potential_Association_Query_Factory $pa_query_factory_di = null,
|
52 |
+
Toolset_Association_Persistence $association_persistence_di = null,
|
53 |
+
Toolset_Association_Factory $association_factory_di = null,
|
54 |
+
Toolset_Element_Factory $element_factory_di = null
|
55 |
) {
|
56 |
$this->definition = $definition;
|
57 |
$this->setup = toolset_ensarr( $setup );
|
58 |
$this->_potential_association_query_factory = $pa_query_factory_di;
|
59 |
+
$this->association_persistence = $association_persistence_di ?: new Toolset_Association_Persistence();
|
60 |
+
$this->association_factory = $association_factory_di ?: new Toolset_Association_Factory();
|
61 |
+
$this->_element_factory = $element_factory_di;
|
62 |
}
|
63 |
|
64 |
|
84 |
* @param int|Toolset_Element|WP_Post $child_source
|
85 |
* @param array $args Optional arguments, implementation-specific
|
86 |
*
|
87 |
+
* @return Toolset_Association|Toolset_Result ID of the new association on success or a result information with an error.
|
88 |
*/
|
89 |
public abstract function create_association( $parent_source, $child_source, $args = array() );
|
90 |
|
92 |
/**
|
93 |
* Delete an association from the database.
|
94 |
*
|
95 |
+
* @param Toolset_Association $association
|
96 |
*
|
97 |
* @return Toolset_Result
|
98 |
* @since m2m
|
155 |
|
156 |
|
157 |
protected function is_association_match( $association ) {
|
158 |
+
return ( $association instanceof Toolset_Association && $association->get_driver() === $this );
|
159 |
}
|
160 |
|
161 |
|
170 |
|
171 |
return $this->_potential_association_query_factory;
|
172 |
}
|
173 |
+
|
174 |
+
|
175 |
+
/**
|
176 |
+
* @return Toolset_Element_Factory
|
177 |
+
* @since 2.5.9
|
178 |
+
*/
|
179 |
+
protected function get_element_factory() {
|
180 |
+
if( null === $this->_element_factory ) {
|
181 |
+
$this->_element_factory = new Toolset_Element_Factory();
|
182 |
+
}
|
183 |
+
|
184 |
+
return $this->_element_factory;
|
185 |
+
}
|
186 |
}
|
vendor/toolset/toolset-common/inc/m2m/element_type.php
CHANGED
@@ -84,7 +84,7 @@ class Toolset_Relationship_Element_Type {
|
|
84 |
* @since m2m
|
85 |
*/
|
86 |
private static function get_available_domains() {
|
87 |
-
return array(
|
88 |
}
|
89 |
|
90 |
|
@@ -132,7 +132,7 @@ class Toolset_Relationship_Element_Type {
|
|
132 |
public static function build_for_post_type( $post_type_slug ) {
|
133 |
return new self(
|
134 |
array(
|
135 |
-
self::DA_DOMAIN =>
|
136 |
self::DA_TYPES => array( $post_type_slug )
|
137 |
)
|
138 |
);
|
@@ -148,11 +148,11 @@ class Toolset_Relationship_Element_Type {
|
|
148 |
*/
|
149 |
public function is_match( $element ) {
|
150 |
|
151 |
-
if( ! $element instanceof
|
152 |
throw new InvalidArgumentException( 'Invalid element provided.' );
|
153 |
}
|
154 |
|
155 |
-
if( $element->get_domain()
|
156 |
return false;
|
157 |
}
|
158 |
|
@@ -188,7 +188,7 @@ class Toolset_Relationship_Element_Type {
|
|
188 |
|
189 |
$this->is_translatable = false;
|
190 |
|
191 |
-
if(
|
192 |
foreach( $this->get_types() as $post_type_slug ) {
|
193 |
if( Toolset_Wpml_Utils::is_post_type_translatable( $post_type_slug ) ) {
|
194 |
$this->is_translatable = true;
|
84 |
* @since m2m
|
85 |
*/
|
86 |
private static function get_available_domains() {
|
87 |
+
return array( Toolset_Element_Domain::POSTS );
|
88 |
}
|
89 |
|
90 |
|
132 |
public static function build_for_post_type( $post_type_slug ) {
|
133 |
return new self(
|
134 |
array(
|
135 |
+
self::DA_DOMAIN => Toolset_Element_Domain::POSTS,
|
136 |
self::DA_TYPES => array( $post_type_slug )
|
137 |
)
|
138 |
);
|
148 |
*/
|
149 |
public function is_match( $element ) {
|
150 |
|
151 |
+
if( ! $element instanceof IToolset_Element ) {
|
152 |
throw new InvalidArgumentException( 'Invalid element provided.' );
|
153 |
}
|
154 |
|
155 |
+
if( $element->get_domain() !== $this->get_domain() ) {
|
156 |
return false;
|
157 |
}
|
158 |
|
188 |
|
189 |
$this->is_translatable = false;
|
190 |
|
191 |
+
if( Toolset_Element_Domain::POSTS === $this->get_domain() ) {
|
192 |
foreach( $this->get_types() as $post_type_slug ) {
|
193 |
if( Toolset_Wpml_Utils::is_post_type_translatable( $post_type_slug ) ) {
|
194 |
$this->is_translatable = true;
|
vendor/toolset/toolset-common/inc/m2m/migration/associations.php
ADDED
@@ -0,0 +1,222 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Helper class for migrating a single legacy association between two posts into m2m.
|
5 |
+
*
|
6 |
+
* Not to be used outside the m2m API.
|
7 |
+
*
|
8 |
+
* @since m2m
|
9 |
+
*/
|
10 |
+
class Toolset_Relationship_Migration_Associations {
|
11 |
+
|
12 |
+
|
13 |
+
/** @var Toolset_Relationship_Definition_Repository */
|
14 |
+
private $definition_repository;
|
15 |
+
|
16 |
+
|
17 |
+
/** @var Toolset_Element_Factory */
|
18 |
+
private $element_factory;
|
19 |
+
|
20 |
+
|
21 |
+
/** @var Toolset_Potential_Association_Query_Factory */
|
22 |
+
private $potential_association_query_factory;
|
23 |
+
|
24 |
+
|
25 |
+
/** @var bool */
|
26 |
+
private $create_default_language_if_missing;
|
27 |
+
|
28 |
+
|
29 |
+
/** @var bool */
|
30 |
+
private $copy_post_content_when_creating;
|
31 |
+
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Toolset_Relationship_Migration_Associations constructor.
|
35 |
+
*
|
36 |
+
* @param Toolset_Relationship_Definition_Repository $definition_repository
|
37 |
+
* @param bool $create_default_language_if_missing
|
38 |
+
* @param bool $copy_post_content_when_creating
|
39 |
+
* @param Toolset_Element_Factory|null $element_factory_di
|
40 |
+
* @param Toolset_Potential_Association_Query_Factory|null $potential_association_query_factory_di
|
41 |
+
*/
|
42 |
+
public function __construct(
|
43 |
+
Toolset_Relationship_Definition_Repository $definition_repository,
|
44 |
+
$create_default_language_if_missing,
|
45 |
+
$copy_post_content_when_creating,
|
46 |
+
Toolset_Element_Factory $element_factory_di = null,
|
47 |
+
Toolset_Potential_Association_Query_Factory $potential_association_query_factory_di = null
|
48 |
+
) {
|
49 |
+
$this->definition_repository = $definition_repository;
|
50 |
+
$this->create_default_language_if_missing = (bool) $create_default_language_if_missing;
|
51 |
+
$this->copy_post_content_when_creating = (bool) $copy_post_content_when_creating;
|
52 |
+
$this->element_factory = $element_factory_di ?: new Toolset_Element_Factory();
|
53 |
+
$this->potential_association_query_factory = $potential_association_query_factory_di ?: new Toolset_Potential_Association_Query_Factory();
|
54 |
+
}
|
55 |
+
|
56 |
+
|
57 |
+
/**
|
58 |
+
* @param int $parent_id
|
59 |
+
* @param int $child_id
|
60 |
+
* @param int $relationship_slug
|
61 |
+
*
|
62 |
+
* @return Toolset_Result
|
63 |
+
*/
|
64 |
+
public function migrate_association( $parent_id, $child_id, $relationship_slug ) {
|
65 |
+
|
66 |
+
$relationship_definition = $this->definition_repository->get_definition( $relationship_slug );
|
67 |
+
|
68 |
+
if( null == $relationship_definition ) {
|
69 |
+
return new Toolset_Result( false, sprintf( __( 'Relationship definition "%s" not found.', 'wpcf' ), $relationship_slug ) );
|
70 |
+
}
|
71 |
+
|
72 |
+
try {
|
73 |
+
// We specifically require individual posts (element_factory->get_post_untranslated())
|
74 |
+
// and not translation sets (which we might get when using element_factory->get_post()).
|
75 |
+
//
|
76 |
+
// Here, we create an association between two specific posts, no matter their language.
|
77 |
+
// The m2m API always creates the association between default language posts, or fails if unable
|
78 |
+
// to do so.
|
79 |
+
//
|
80 |
+
// If these posts are non-default language versions of already associated posts,
|
81 |
+
// another association will not be created.
|
82 |
+
$parent = $this->element_factory->get_post_untranslated( $parent_id );
|
83 |
+
$child = $this->element_factory->get_post_untranslated( $child_id );
|
84 |
+
|
85 |
+
// Note: This might throw exceptions in some obscure cases, like trying to connect
|
86 |
+
// posts of type that don't belong to the correct relationship.
|
87 |
+
//
|
88 |
+
// Imagine the following situation:
|
89 |
+
// - post A of type "type-a" with ID "42"
|
90 |
+
// - post B of type "type-b"
|
91 |
+
// - post B has has a postmeta "_wpcf_belongs_type-x_id" with value "42"
|
92 |
+
//
|
93 |
+
// When migrating legacy relationships, we'll read post B and
|
94 |
+
// create a new relationship based on the combination of two post types: "type-b", which is the post type
|
95 |
+
// of the currently processed relationship, and "type-x", which is the parent post type, judging
|
96 |
+
// from the postmeta value. That will create a "type-x-type-b" relationship.
|
97 |
+
//
|
98 |
+
// Then, we will try to connect post B with a post with the ID "42" (post A) in a relationship "type-x-type-b".
|
99 |
+
// But this will not be accepted by the IToolset_Potential_Association_Query at all, because post A
|
100 |
+
// has a different post type than "type-x". And voilá... an exception.
|
101 |
+
$potential_association_query = $this->potential_association_query_factory->create(
|
102 |
+
$relationship_definition,
|
103 |
+
new Toolset_Relationship_Role_Child(),
|
104 |
+
$parent
|
105 |
+
);
|
106 |
+
|
107 |
+
// Specifically check whether the element is already associated. This can happen only when
|
108 |
+
// trying to create the same association for posts in different languages, and we want to skip
|
109 |
+
// those cases without triggering a warning.
|
110 |
+
if( $potential_association_query->is_element_already_associated( $child ) ) {
|
111 |
+
return new Toolset_Result(
|
112 |
+
true,
|
113 |
+
sprintf(
|
114 |
+
__( 'Skipping the association between posts #%d (%s) and #%d (%s), because these elements are already associated. This can happen when migrating post translations.', 'wpcf' ),
|
115 |
+
$parent_id,
|
116 |
+
esc_textarea( $parent->get_title() ),
|
117 |
+
$child_id,
|
118 |
+
esc_textarea( $child->get_title() )
|
119 |
+
)
|
120 |
+
);
|
121 |
+
}
|
122 |
+
|
123 |
+
$results = new Toolset_Result_Set();
|
124 |
+
|
125 |
+
// Handle posts without default language versions (if applicable).
|
126 |
+
//
|
127 |
+
// If the situation couldn't be handled according to user's choice, skip the current association
|
128 |
+
// and report the issue immediately.
|
129 |
+
//
|
130 |
+
// Otherwise, we'll print the (positive) output after the association is created successfully.
|
131 |
+
$parent_default_lang_check = $this->check_default_language_version( $parent, $parent, $child );
|
132 |
+
if( ! $parent_default_lang_check->is_success() ) {
|
133 |
+
return $parent_default_lang_check;
|
134 |
+
}
|
135 |
+
$results->add( $parent_default_lang_check );
|
136 |
+
|
137 |
+
$child_default_lang_check = $this->check_default_language_version( $child, $parent, $child );
|
138 |
+
if( ! $child_default_lang_check->is_success() ) {
|
139 |
+
return $child_default_lang_check;
|
140 |
+
}
|
141 |
+
$results->add( $child_default_lang_check );
|
142 |
+
|
143 |
+
// Check for other cases where it's not allowed to create this association.
|
144 |
+
// Those we will report as problems.
|
145 |
+
$can_associate = $potential_association_query->check_single_element( $child, false );
|
146 |
+
} catch( Exception $e ) {
|
147 |
+
$display_message = sprintf(
|
148 |
+
__( 'Unable to migrate an association from post #%d to #%d to a relationship "%s"', 'wpcf'),
|
149 |
+
$parent_id,
|
150 |
+
$child_id,
|
151 |
+
$relationship_slug
|
152 |
+
);
|
153 |
+
return new Toolset_Result( $e, $display_message );
|
154 |
+
}
|
155 |
+
|
156 |
+
if( ! $can_associate->is_success() ) {
|
157 |
+
return new Toolset_Result(
|
158 |
+
false,
|
159 |
+
sprintf(
|
160 |
+
__( 'The association between posts #%d (%s) and #%d (%s) in the relationship "%s" is not allowed: ', 'wpcf' ),
|
161 |
+
$parent->get_id(),
|
162 |
+
esc_textarea( $parent->get_title() ),
|
163 |
+
$child->get_id(),
|
164 |
+
esc_textarea( $child->get_title() ),
|
165 |
+
$relationship_slug
|
166 |
+
)
|
167 |
+
. $can_associate->get_message()
|
168 |
+
);
|
169 |
+
}
|
170 |
+
|
171 |
+
try {
|
172 |
+
$association = $relationship_definition->create_association( $parent_id, $child_id );
|
173 |
+
} catch( Exception $e ) {
|
174 |
+
return new Toolset_Result( $e );
|
175 |
+
}
|
176 |
+
|
177 |
+
if( $association instanceof Toolset_Result ) {
|
178 |
+
$message = ( $association->has_message() ? $association->get_message() : __( 'Error while saving an association to database', 'wpcf' ) );
|
179 |
+
return new Toolset_Result(
|
180 |
+
false,
|
181 |
+
sprintf( "%s\n\tparent: #%d (%s)\n\tchild: #%d (%s)\n\trelationship: \"%s\"",
|
182 |
+
$message,
|
183 |
+
$parent->get_id(),
|
184 |
+
esc_textarea( $parent->get_title() ),
|
185 |
+
$child->get_id(),
|
186 |
+
esc_textarea( $child->get_title() ),
|
187 |
+
$relationship_slug
|
188 |
+
)
|
189 |
+
);
|
190 |
+
}
|
191 |
+
|
192 |
+
// Happy end!
|
193 |
+
$results->add(
|
194 |
+
true,
|
195 |
+
sprintf(
|
196 |
+
__( 'Connected #%d (%s) and #%d (%s) in the relationship "%s".', 'wpcf' ),
|
197 |
+
$parent->get_id(),
|
198 |
+
$parent->get_title(),
|
199 |
+
$child->get_id(),
|
200 |
+
$child->get_title(),
|
201 |
+
$relationship_slug
|
202 |
+
)
|
203 |
+
);
|
204 |
+
|
205 |
+
return $results->aggregate( Toolset_Relationship_Migration_Controller::MESSAGE_SEPARATOR );
|
206 |
+
}
|
207 |
+
|
208 |
+
|
209 |
+
/**
|
210 |
+
* @param IToolset_Post $post The post to check.
|
211 |
+
* @param IToolset_Post $parent Parent post of the association (for logging purposes).
|
212 |
+
* @param IToolset_Post $child Child post of the association (for logging purposes).
|
213 |
+
*
|
214 |
+
* @return Toolset_Result
|
215 |
+
*/
|
216 |
+
private function check_default_language_version( IToolset_Post $post, IToolset_Post $parent, IToolset_Post $child ) {
|
217 |
+
$translation_migration = new Toolset_Relationship_Migration_Post_Translation(
|
218 |
+
$post, $parent, $child, $this->create_default_language_if_missing, $this->copy_post_content_when_creating
|
219 |
+
);
|
220 |
+
return $translation_migration->run();
|
221 |
+
}
|
222 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/{migration.php → migration/controller.php}
RENAMED
@@ -7,17 +7,15 @@
|
|
7 |
*
|
8 |
* @since m2m
|
9 |
*/
|
10 |
-
class
|
11 |
|
12 |
|
13 |
-
|
14 |
-
|
15 |
|
16 |
/** @var Toolset_Relationship_Database_Operations */
|
17 |
private $database_operations;
|
18 |
|
19 |
-
/** @var Toolset_Relationship_Multilingual_Mode */
|
20 |
-
private $multilingual_mode_manager;
|
21 |
|
22 |
/**
|
23 |
* This one needs to be initialized later because it will break when relationship tables don't exist yet.
|
@@ -26,48 +24,50 @@ class Toolset_Relationship_Migration {
|
|
26 |
*/
|
27 |
private $_relationship_definition_repository;
|
28 |
|
|
|
29 |
/** @var Toolset_Relationship_Migration_Associations|null */
|
30 |
private $_association_migrator;
|
31 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
32 |
/**
|
33 |
-
*
|
34 |
*
|
35 |
* @param wpdb|null $wpdb_di
|
36 |
* @param Toolset_Relationship_Database_Operations|null $database_operations_di
|
37 |
-
* @param Toolset_Relationship_Multilingual_Mode|null $multilingual_mode_di
|
38 |
* @param Toolset_Relationship_Definition_Repository|null $relationship_definition_repository_di
|
39 |
* @param Toolset_Relationship_Migration_Associations|null $association_migrator_di
|
|
|
|
|
|
|
40 |
*/
|
41 |
public function __construct(
|
42 |
wpdb $wpdb_di = null,
|
43 |
Toolset_Relationship_Database_Operations $database_operations_di = null,
|
44 |
-
Toolset_Relationship_Multilingual_Mode $multilingual_mode_di = null,
|
45 |
Toolset_Relationship_Definition_Repository $relationship_definition_repository_di = null,
|
46 |
-
Toolset_Relationship_Migration_Associations $association_migrator_di = null
|
|
|
|
|
|
|
47 |
) {
|
48 |
-
|
49 |
-
$this->
|
50 |
-
if( null === $this->wpdb ) {
|
51 |
-
global $wpdb;
|
52 |
-
$this->wpdb = $wpdb;
|
53 |
-
}
|
54 |
-
|
55 |
-
$this->database_operations = (
|
56 |
-
null === $database_operations_di
|
57 |
-
? new Toolset_Relationship_Database_Operations()
|
58 |
-
: $database_operations_di
|
59 |
-
);
|
60 |
-
|
61 |
-
|
62 |
-
$this->multilingual_mode_manager = (
|
63 |
-
null === $multilingual_mode_di
|
64 |
-
? Toolset_Relationship_Multilingual_Mode::get_instance()
|
65 |
-
: $multilingual_mode_di
|
66 |
-
);
|
67 |
-
|
68 |
$this->_relationship_definition_repository = $relationship_definition_repository_di;
|
69 |
-
|
70 |
$this->_association_migrator = $association_migrator_di;
|
|
|
|
|
|
|
71 |
}
|
72 |
|
73 |
|
@@ -80,9 +80,11 @@ class Toolset_Relationship_Migration {
|
|
80 |
}
|
81 |
|
82 |
|
83 |
-
private function get_association_migrator() {
|
84 |
if( null === $this->_association_migrator ) {
|
85 |
-
$this->_association_migrator = new Toolset_Relationship_Migration_Associations(
|
|
|
|
|
86 |
}
|
87 |
|
88 |
return $this->_association_migrator;
|
@@ -96,7 +98,7 @@ class Toolset_Relationship_Migration {
|
|
96 |
*
|
97 |
* @since m2m
|
98 |
*
|
99 |
-
* TODO is it possible to reliably detect dbDelta failure?
|
100 |
*/
|
101 |
public function do_native_dbdelta() {
|
102 |
return $this->database_operations->do_native_dbdelta();
|
@@ -127,8 +129,9 @@ class Toolset_Relationship_Migration {
|
|
127 |
}
|
128 |
|
129 |
$m2m_tables = array(
|
130 |
-
|
131 |
-
|
|
|
132 |
|
133 |
// Obsolete table
|
134 |
$this->wpdb->prefix . 'toolset_association_translations'
|
@@ -156,9 +159,6 @@ class Toolset_Relationship_Migration {
|
|
156 |
$results->add( true, __( 'No tables had to be dropped.', 'wpcf' ) );
|
157 |
}
|
158 |
|
159 |
-
// Disable transitional mode if it was set previously.
|
160 |
-
$this->multilingual_mode_manager->set_mode( Toolset_Relationship_Multilingual_Mode::MODE_OFF );
|
161 |
-
|
162 |
return $results;
|
163 |
}
|
164 |
|
@@ -187,17 +187,47 @@ class Toolset_Relationship_Migration {
|
|
187 |
$child_post_type = $post_type_pair['child'];
|
188 |
$relationship_slug = $post_type_pair['slug'];
|
189 |
|
|
|
|
|
|
|
190 |
$result = $this->create_relationship_definition( $parent_post_type, $child_post_type, $relationship_slug );
|
191 |
$results->add( $result );
|
192 |
}
|
193 |
|
194 |
// Now we need to persist everything
|
|
|
195 |
$this->get_relationship_repository()->save_definitions();
|
196 |
|
197 |
return $results;
|
198 |
}
|
199 |
|
200 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
201 |
/**
|
202 |
* Read the legacy relationships data stored in an option and transform it into array that can be
|
203 |
* processed more easily.
|
@@ -225,14 +255,17 @@ class Toolset_Relationship_Migration {
|
|
225 |
$results = array();
|
226 |
|
227 |
foreach ( $relationships as $parent_post_type => $relationships_per_post_type ) {
|
228 |
-
|
229 |
$relationships_per_post_type = toolset_ensarr( $relationships_per_post_type );
|
230 |
|
231 |
foreach ( $relationships_per_post_type as $child_post_type => $temporarily_ignored ) {
|
|
|
232 |
$results[] = array(
|
233 |
'parent' => $parent_post_type,
|
234 |
'child' => $child_post_type,
|
235 |
-
'slug' => $this->derive_relationship_slug( $parent_post_type, $child_post_type )
|
|
|
|
|
236 |
);
|
237 |
}
|
238 |
}
|
@@ -255,18 +288,19 @@ class Toolset_Relationship_Migration {
|
|
255 |
*/
|
256 |
private function create_relationship_definition( $parent_post_type, $child_post_type, $relationship_slug ) {
|
257 |
|
258 |
-
$
|
259 |
|
260 |
// Overwrite the definition if it already exists.
|
261 |
-
if( $
|
262 |
-
$
|
263 |
}
|
264 |
|
265 |
try {
|
266 |
$parent_type = Toolset_Relationship_Element_Type::build_for_post_type( $parent_post_type );
|
267 |
$child_type = Toolset_Relationship_Element_Type::build_for_post_type( $child_post_type );
|
268 |
|
269 |
-
|
|
|
270 |
|
271 |
// All legacy relationships are one-to-many
|
272 |
$cardinality = new Toolset_Relationship_Cardinality( 1, Toolset_Relationship_Cardinality::INFINITY );
|
@@ -321,10 +355,14 @@ class Toolset_Relationship_Migration {
|
|
321 |
*
|
322 |
* @param int $offset
|
323 |
* @param int $limit
|
|
|
|
|
324 |
*
|
325 |
* @return Toolset_Result_Updated|Toolset_Result_Set
|
326 |
*/
|
327 |
-
public function migrate_associations(
|
|
|
|
|
328 |
|
329 |
$associations_to_migrate = $this->get_associations_to_migrate( $offset, $limit );
|
330 |
|
@@ -336,7 +374,9 @@ class Toolset_Relationship_Migration {
|
|
336 |
$results = new Toolset_Result_Set();
|
337 |
|
338 |
foreach( $associations_to_migrate as $association_to_migrate ) {
|
339 |
-
$result = $this->get_association_migrator(
|
|
|
|
|
340 |
$association_to_migrate['parent_id'],
|
341 |
$association_to_migrate['child_id'],
|
342 |
$association_to_migrate['relationship_slug']
|
@@ -345,7 +385,7 @@ class Toolset_Relationship_Migration {
|
|
345 |
}
|
346 |
|
347 |
if( $results->is_complete_success() ) {
|
348 |
-
return new Toolset_Result_Updated( true, count( $associations_to_migrate ) );
|
349 |
} else {
|
350 |
return $results;
|
351 |
}
|
@@ -419,14 +459,15 @@ class Toolset_Relationship_Migration {
|
|
419 |
* @since m2m
|
420 |
*/
|
421 |
public function finish() {
|
422 |
-
|
423 |
update_option( Toolset_Relationship_Controller::IS_M2M_ENABLED_OPTION, 'yes', true );
|
424 |
-
|
425 |
-
// todo this needs a review
|
426 |
-
// There is no need to update the translation view because we've just properly imported everything.
|
427 |
-
//$wpml_interop = Toolset_Relationship_WPML_Interoperability::get_instance();
|
428 |
-
//$wpml_interop->is_full_refresh_needed( false );
|
429 |
}
|
430 |
|
431 |
}
|
432 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
*
|
8 |
* @since m2m
|
9 |
*/
|
10 |
+
class Toolset_Relationship_Migration_Controller extends Toolset_Wpdb_User {
|
11 |
|
12 |
|
13 |
+
const MESSAGE_SEPARATOR = "\n> ";
|
14 |
+
|
15 |
|
16 |
/** @var Toolset_Relationship_Database_Operations */
|
17 |
private $database_operations;
|
18 |
|
|
|
|
|
19 |
|
20 |
/**
|
21 |
* This one needs to be initialized later because it will break when relationship tables don't exist yet.
|
24 |
*/
|
25 |
private $_relationship_definition_repository;
|
26 |
|
27 |
+
|
28 |
/** @var Toolset_Relationship_Migration_Associations|null */
|
29 |
private $_association_migrator;
|
30 |
|
31 |
+
|
32 |
+
/** @var Toolset_Post_Type_Repository */
|
33 |
+
private $post_type_repository;
|
34 |
+
|
35 |
+
|
36 |
+
/** @var Toolset_Relationship_Table_Name */
|
37 |
+
private $table_name;
|
38 |
+
|
39 |
+
|
40 |
+
/** @var Toolset_WPML_Compatibility */
|
41 |
+
private $wpml_compatibility;
|
42 |
+
|
43 |
+
|
44 |
/**
|
45 |
+
* Toolset_Relationship_Migration_Controller constructor.
|
46 |
*
|
47 |
* @param wpdb|null $wpdb_di
|
48 |
* @param Toolset_Relationship_Database_Operations|null $database_operations_di
|
|
|
49 |
* @param Toolset_Relationship_Definition_Repository|null $relationship_definition_repository_di
|
50 |
* @param Toolset_Relationship_Migration_Associations|null $association_migrator_di
|
51 |
+
* @param Toolset_Relationship_Table_Name|null $table_name_di
|
52 |
+
* @param Toolset_Post_Type_Repository|null $post_type_repository
|
53 |
+
* @param Toolset_WPML_Compatibility|null $wpml_service_di
|
54 |
*/
|
55 |
public function __construct(
|
56 |
wpdb $wpdb_di = null,
|
57 |
Toolset_Relationship_Database_Operations $database_operations_di = null,
|
|
|
58 |
Toolset_Relationship_Definition_Repository $relationship_definition_repository_di = null,
|
59 |
+
Toolset_Relationship_Migration_Associations $association_migrator_di = null,
|
60 |
+
Toolset_Relationship_Table_Name $table_name_di = null,
|
61 |
+
Toolset_Post_Type_Repository $post_type_repository = null,
|
62 |
+
Toolset_WPML_Compatibility $wpml_service_di = null
|
63 |
) {
|
64 |
+
parent::__construct( $wpdb_di );
|
65 |
+
$this->database_operations = $database_operations_di ?: new Toolset_Relationship_Database_Operations();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
66 |
$this->_relationship_definition_repository = $relationship_definition_repository_di;
|
|
|
67 |
$this->_association_migrator = $association_migrator_di;
|
68 |
+
$this->table_name = $table_name_di ?: new Toolset_Relationship_Table_Name();
|
69 |
+
$this->wpml_compatibility = $wpml_service_di ?: Toolset_WPML_Compatibility::get_instance();
|
70 |
+
$this->post_type_repository = $post_type_repository ? $post_type_repository : Toolset_Post_Type_Repository::get_instance();
|
71 |
}
|
72 |
|
73 |
|
80 |
}
|
81 |
|
82 |
|
83 |
+
private function get_association_migrator( $create_default_language_if_missing, $copy_post_content_when_creating ) {
|
84 |
if( null === $this->_association_migrator ) {
|
85 |
+
$this->_association_migrator = new Toolset_Relationship_Migration_Associations(
|
86 |
+
$this->get_relationship_repository(), $create_default_language_if_missing, $copy_post_content_when_creating
|
87 |
+
);
|
88 |
}
|
89 |
|
90 |
return $this->_association_migrator;
|
98 |
*
|
99 |
* @since m2m
|
100 |
*
|
101 |
+
* @refactoring TODO is it possible to reliably detect dbDelta failure?
|
102 |
*/
|
103 |
public function do_native_dbdelta() {
|
104 |
return $this->database_operations->do_native_dbdelta();
|
129 |
}
|
130 |
|
131 |
$m2m_tables = array(
|
132 |
+
$this->table_name->association_table(),
|
133 |
+
$this->table_name->relationship_table(),
|
134 |
+
$this->table_name->type_set_table(),
|
135 |
|
136 |
// Obsolete table
|
137 |
$this->wpdb->prefix . 'toolset_association_translations'
|
159 |
$results->add( true, __( 'No tables had to be dropped.', 'wpcf' ) );
|
160 |
}
|
161 |
|
|
|
|
|
|
|
162 |
return $results;
|
163 |
}
|
164 |
|
187 |
$child_post_type = $post_type_pair['child'];
|
188 |
$relationship_slug = $post_type_pair['slug'];
|
189 |
|
190 |
+
$results->add( $this->check_post_type_translation_mode( $parent_post_type ) );
|
191 |
+
$results->add( $this->check_post_type_translation_mode( $child_post_type ) );
|
192 |
+
|
193 |
$result = $this->create_relationship_definition( $parent_post_type, $child_post_type, $relationship_slug );
|
194 |
$results->add( $result );
|
195 |
}
|
196 |
|
197 |
// Now we need to persist everything
|
198 |
+
/** @noinspection PhpDeprecationInspection */
|
199 |
$this->get_relationship_repository()->save_definitions();
|
200 |
|
201 |
return $results;
|
202 |
}
|
203 |
|
204 |
|
205 |
+
/**
|
206 |
+
* If WPML is active and the given post type has the standard translation mode, switch it to "display as translated".
|
207 |
+
*
|
208 |
+
* @param string $post_type_slug
|
209 |
+
*
|
210 |
+
* @return Toolset_Result
|
211 |
+
* @since 2.5.11
|
212 |
+
*/
|
213 |
+
private function check_post_type_translation_mode( $post_type_slug ) {
|
214 |
+
if( Toolset_WPML_Compatibility::MODE_TRANSLATE !== $this->wpml_compatibility->get_post_type_translation_mode( $post_type_slug ) ) {
|
215 |
+
// This will happen also if WPML is not active at all.
|
216 |
+
return new Toolset_Result( true );
|
217 |
+
}
|
218 |
+
|
219 |
+
// Fix the wrong translation mode.
|
220 |
+
$this->wpml_compatibility->set_post_type_translation_mode( $post_type_slug, Toolset_WPML_Compatibility::MODE_DISPLAY_AS_TRANSLATED );
|
221 |
+
return new Toolset_Result(
|
222 |
+
true,
|
223 |
+
sprintf(
|
224 |
+
__( 'Adjusted the translation mode of the post type "%s" to "display as translated".', 'wpcf' ),
|
225 |
+
sanitize_title( $post_type_slug )
|
226 |
+
)
|
227 |
+
);
|
228 |
+
}
|
229 |
+
|
230 |
+
|
231 |
/**
|
232 |
* Read the legacy relationships data stored in an option and transform it into array that can be
|
233 |
* processed more easily.
|
255 |
$results = array();
|
256 |
|
257 |
foreach ( $relationships as $parent_post_type => $relationships_per_post_type ) {
|
258 |
+
$parent_post_type_obj = $this->post_type_repository->get( $parent_post_type );
|
259 |
$relationships_per_post_type = toolset_ensarr( $relationships_per_post_type );
|
260 |
|
261 |
foreach ( $relationships_per_post_type as $child_post_type => $temporarily_ignored ) {
|
262 |
+
$child_post_type_obj = $this->post_type_repository->get( $child_post_type );
|
263 |
$results[] = array(
|
264 |
'parent' => $parent_post_type,
|
265 |
'child' => $child_post_type,
|
266 |
+
'slug' => $this->derive_relationship_slug( $parent_post_type, $child_post_type ),
|
267 |
+
'parent_can_be_used_in_relationship' => $parent_post_type_obj->can_be_used_in_relationship() ? 1 : 0,
|
268 |
+
'child_can_be_used_in_relationship' => $child_post_type_obj->can_be_used_in_relationship() ? 1 : 0,
|
269 |
);
|
270 |
}
|
271 |
}
|
288 |
*/
|
289 |
private function create_relationship_definition( $parent_post_type, $child_post_type, $relationship_slug ) {
|
290 |
|
291 |
+
$definition_repository = $this->get_relationship_repository();
|
292 |
|
293 |
// Overwrite the definition if it already exists.
|
294 |
+
if( $definition_repository->definition_exists( $relationship_slug ) ) {
|
295 |
+
$definition_repository->remove_definition( $relationship_slug );
|
296 |
}
|
297 |
|
298 |
try {
|
299 |
$parent_type = Toolset_Relationship_Element_Type::build_for_post_type( $parent_post_type );
|
300 |
$child_type = Toolset_Relationship_Element_Type::build_for_post_type( $child_post_type );
|
301 |
|
302 |
+
/** @var Toolset_Relationship_Definition $definition */
|
303 |
+
$definition = $definition_repository->create_definition( $relationship_slug, $parent_type, $child_type );
|
304 |
|
305 |
// All legacy relationships are one-to-many
|
306 |
$cardinality = new Toolset_Relationship_Cardinality( 1, Toolset_Relationship_Cardinality::INFINITY );
|
355 |
*
|
356 |
* @param int $offset
|
357 |
* @param int $limit
|
358 |
+
* @param bool $create_default_language_if_missing
|
359 |
+
* @param bool $copy_post_content_when_creating
|
360 |
*
|
361 |
* @return Toolset_Result_Updated|Toolset_Result_Set
|
362 |
*/
|
363 |
+
public function migrate_associations(
|
364 |
+
$offset, $limit, $create_default_language_if_missing, $copy_post_content_when_creating
|
365 |
+
) {
|
366 |
|
367 |
$associations_to_migrate = $this->get_associations_to_migrate( $offset, $limit );
|
368 |
|
374 |
$results = new Toolset_Result_Set();
|
375 |
|
376 |
foreach( $associations_to_migrate as $association_to_migrate ) {
|
377 |
+
$result = $this->get_association_migrator(
|
378 |
+
$create_default_language_if_missing, $copy_post_content_when_creating
|
379 |
+
)->migrate_association(
|
380 |
$association_to_migrate['parent_id'],
|
381 |
$association_to_migrate['child_id'],
|
382 |
$association_to_migrate['relationship_slug']
|
385 |
}
|
386 |
|
387 |
if( $results->is_complete_success() ) {
|
388 |
+
return new Toolset_Result_Updated( true, count( $associations_to_migrate ), $results->concat_messages( self::MESSAGE_SEPARATOR ) );
|
389 |
} else {
|
390 |
return $results;
|
391 |
}
|
459 |
* @since m2m
|
460 |
*/
|
461 |
public function finish() {
|
|
|
462 |
update_option( Toolset_Relationship_Controller::IS_M2M_ENABLED_OPTION, 'yes', true );
|
|
|
|
|
|
|
|
|
|
|
463 |
}
|
464 |
|
465 |
}
|
466 |
|
467 |
+
|
468 |
+
/**
|
469 |
+
* @deprecated Fallback after class renaming. Use Toolset_Relationship_Migration_Controller instead.
|
470 |
+
*/
|
471 |
+
class Toolset_Relationship_Migration extends Toolset_Relationship_Migration_Controller {
|
472 |
+
|
473 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/migration/post_translation.php
ADDED
@@ -0,0 +1,213 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Handle the creation of a default languge post translation during the m2m migration.
|
5 |
+
*
|
6 |
+
* The behaviour depends on user's settings passed to the constructor.
|
7 |
+
*
|
8 |
+
* @since 2.5.11
|
9 |
+
*/
|
10 |
+
class Toolset_Relationship_Migration_Post_Translation {
|
11 |
+
|
12 |
+
|
13 |
+
/** @var IToolset_Post */
|
14 |
+
private $post;
|
15 |
+
|
16 |
+
|
17 |
+
/** @var IToolset_Post */
|
18 |
+
private $parent;
|
19 |
+
|
20 |
+
|
21 |
+
/** @var IToolset_Post */
|
22 |
+
private $child;
|
23 |
+
|
24 |
+
|
25 |
+
/** @var bool */
|
26 |
+
private $create_default_language_if_missing;
|
27 |
+
|
28 |
+
|
29 |
+
/** @var Toolset_WPML_Compatibility */
|
30 |
+
private $wpml_service;
|
31 |
+
|
32 |
+
|
33 |
+
/** @var bool */
|
34 |
+
private $copy_post_content_when_creating;
|
35 |
+
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Toolset_Relationship_Migration_Post_Translation constructor.
|
39 |
+
*
|
40 |
+
* @param IToolset_Post $post
|
41 |
+
* @param IToolset_Post $parent
|
42 |
+
* @param IToolset_Post $child
|
43 |
+
* @param $create_default_language_if_missing
|
44 |
+
* @param $copy_post_content_when_creating
|
45 |
+
* @param Toolset_WPML_Compatibility|null $wpml_service_di
|
46 |
+
*/
|
47 |
+
public function __construct(
|
48 |
+
IToolset_Post $post, IToolset_Post $parent, IToolset_Post $child,
|
49 |
+
$create_default_language_if_missing,
|
50 |
+
$copy_post_content_when_creating,
|
51 |
+
Toolset_WPML_Compatibility $wpml_service_di = null
|
52 |
+
) {
|
53 |
+
$this->post = $post;
|
54 |
+
$this->parent = $parent;
|
55 |
+
$this->child = $child;
|
56 |
+
$this->create_default_language_if_missing = (bool) $create_default_language_if_missing;
|
57 |
+
$this->copy_post_content_when_creating = (bool) $copy_post_content_when_creating;
|
58 |
+
$this->wpml_service = $wpml_service_di ?: Toolset_WPML_Compatibility::get_instance();
|
59 |
+
}
|
60 |
+
|
61 |
+
|
62 |
+
/**
|
63 |
+
* Check for the missing translation and either create it or report a failure, depending
|
64 |
+
* on the user's choice.
|
65 |
+
*
|
66 |
+
* @return Toolset_Result
|
67 |
+
*/
|
68 |
+
public function run() {
|
69 |
+
if( ! $this->is_missing_default_language_version( $this->post ) ) {
|
70 |
+
return new Toolset_Result( true );
|
71 |
+
}
|
72 |
+
|
73 |
+
if( ! $this->create_default_language_if_missing ) {
|
74 |
+
return new Toolset_Result(
|
75 |
+
false,
|
76 |
+
sprintf(
|
77 |
+
__( 'Skipping the association between posts #%d (%s) and #%d (%s) because #%d doesn\'t have a default language version and you chose to skip such associations.', 'wpcf' ),
|
78 |
+
$this->parent->get_id(),
|
79 |
+
$this->parent->get_title(),
|
80 |
+
$this->child->get_id(),
|
81 |
+
$this->child->get_title(),
|
82 |
+
$this->post->get_id()
|
83 |
+
)
|
84 |
+
);
|
85 |
+
}
|
86 |
+
|
87 |
+
return $this->create_default_language_version( $this->post );
|
88 |
+
}
|
89 |
+
|
90 |
+
|
91 |
+
/**
|
92 |
+
* @param IToolset_Post $post
|
93 |
+
* @return bool
|
94 |
+
*/
|
95 |
+
private function is_missing_default_language_version( IToolset_Post $post ) {
|
96 |
+
if( ! $post->is_translatable() ) {
|
97 |
+
return false;
|
98 |
+
}
|
99 |
+
$default_language_id = $post->get_default_language_id();
|
100 |
+
return ( 0 === $default_language_id );
|
101 |
+
}
|
102 |
+
|
103 |
+
|
104 |
+
/**
|
105 |
+
* @param IToolset_Post $post
|
106 |
+
* @return Toolset_Result
|
107 |
+
*/
|
108 |
+
private function create_default_language_version( IToolset_Post $post ) {
|
109 |
+
if( $this->copy_post_content_when_creating ) {
|
110 |
+
return $this->create_duplicate_default_language_version( $post );
|
111 |
+
}
|
112 |
+
|
113 |
+
return $this->create_clean_default_language_version( $post );
|
114 |
+
}
|
115 |
+
|
116 |
+
|
117 |
+
/**
|
118 |
+
* @param IToolset_Post $post
|
119 |
+
*
|
120 |
+
* @return Toolset_Result
|
121 |
+
*/
|
122 |
+
private function create_clean_default_language_version( IToolset_Post $post ) {
|
123 |
+
// Create the new post, an empty draft with a similar title as the original.
|
124 |
+
$result = wp_insert_post(
|
125 |
+
array(
|
126 |
+
'post_title' => sprintf(
|
127 |
+
'[%s] %s',
|
128 |
+
$this->wpml_service->get_default_language(),
|
129 |
+
$post->get_title()
|
130 |
+
),
|
131 |
+
'post_content' => '',
|
132 |
+
'post_status' => 'draft',
|
133 |
+
'post_author' => $post->get_author(),
|
134 |
+
'post_type' => $post->get_type()
|
135 |
+
),
|
136 |
+
true
|
137 |
+
);
|
138 |
+
|
139 |
+
if( $result instanceof WP_Error ) {
|
140 |
+
return new Toolset_Result( $result );
|
141 |
+
}
|
142 |
+
|
143 |
+
$default_lang_post_id = (int) $result;
|
144 |
+
|
145 |
+
// Set the language of the new post and connect it to the original.
|
146 |
+
$this->wpml_service->add_post_translation( $post, $default_lang_post_id, $this->wpml_service->get_default_language() );
|
147 |
+
|
148 |
+
// Unfortunately, there is no return value from the WPML hook (it's an action), we have to assume it went through.
|
149 |
+
return new Toolset_Result(
|
150 |
+
true,
|
151 |
+
sprintf(
|
152 |
+
__( 'Created a default language translation for post #%d (%s) in draft mode.', 'wpcf' ),
|
153 |
+
$post->get_id(),
|
154 |
+
$post->get_title()
|
155 |
+
)
|
156 |
+
);
|
157 |
+
}
|
158 |
+
|
159 |
+
|
160 |
+
/**
|
161 |
+
* @param IToolset_Post $post
|
162 |
+
*
|
163 |
+
* @return Toolset_Result
|
164 |
+
*/
|
165 |
+
private function create_duplicate_default_language_version( IToolset_Post $post ) {
|
166 |
+
|
167 |
+
// First, create the duplicate (but don't mark it as an actual WPML duplicate to prevent value synchronization)
|
168 |
+
$duplicate_id = $this->wpml_service->create_post_duplicate(
|
169 |
+
$post, $this->wpml_service->get_default_language(), false
|
170 |
+
);
|
171 |
+
|
172 |
+
if( ! $duplicate_id ) {
|
173 |
+
return new Toolset_Result(
|
174 |
+
false,
|
175 |
+
sprintf(
|
176 |
+
__( 'Unable to create a default language translation for post #%d (%s).', 'wpcf' ),
|
177 |
+
$post->get_id(),
|
178 |
+
$post->get_title()
|
179 |
+
)
|
180 |
+
);
|
181 |
+
}
|
182 |
+
|
183 |
+
// Adjust the title and turn it into a draft.
|
184 |
+
$result = wp_update_post(
|
185 |
+
array(
|
186 |
+
'ID' => $duplicate_id,
|
187 |
+
'post_title' => sprintf(
|
188 |
+
'[%s] %s',
|
189 |
+
$this->wpml_service->get_default_language(),
|
190 |
+
$post->get_title()
|
191 |
+
),
|
192 |
+
'post_status' => 'draft',
|
193 |
+
),
|
194 |
+
true
|
195 |
+
);
|
196 |
+
|
197 |
+
|
198 |
+
if( $result instanceof WP_Error ) {
|
199 |
+
return new Toolset_Result( $result );
|
200 |
+
}
|
201 |
+
|
202 |
+
return new Toolset_Result(
|
203 |
+
true,
|
204 |
+
sprintf(
|
205 |
+
__( 'Created a default language translation for post #%d (%s) in draft mode.', 'wpcf' ),
|
206 |
+
$post->get_id(),
|
207 |
+
$post->get_title()
|
208 |
+
)
|
209 |
+
);
|
210 |
+
}
|
211 |
+
|
212 |
+
|
213 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/migration_associations.php
DELETED
@@ -1,119 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Helper class for migrating a single legacy association between two posts into m2m.
|
5 |
-
*
|
6 |
-
* Not to be used outside the m2m API.
|
7 |
-
*
|
8 |
-
* @since m2m
|
9 |
-
*/
|
10 |
-
class Toolset_Relationship_Migration_Associations {
|
11 |
-
|
12 |
-
/** @var Toolset_Relationship_Definition_Repository */
|
13 |
-
private $definition_repository;
|
14 |
-
|
15 |
-
/** @var Toolset_Element_Factory */
|
16 |
-
private $element_factory;
|
17 |
-
|
18 |
-
|
19 |
-
/**
|
20 |
-
* Toolset_Relationship_Migration_Associations constructor.
|
21 |
-
*
|
22 |
-
* @param Toolset_Relationship_Definition_Repository $definition_repository
|
23 |
-
* @param Toolset_Element_Factory|null $element_factory_di
|
24 |
-
*/
|
25 |
-
public function __construct(
|
26 |
-
Toolset_Relationship_Definition_Repository $definition_repository,
|
27 |
-
Toolset_Element_Factory $element_factory_di = null
|
28 |
-
) {
|
29 |
-
|
30 |
-
$this->definition_repository = $definition_repository;
|
31 |
-
|
32 |
-
$this->element_factory = (
|
33 |
-
null === $element_factory_di
|
34 |
-
? new Toolset_Element_Factory()
|
35 |
-
: $element_factory_di
|
36 |
-
);
|
37 |
-
}
|
38 |
-
|
39 |
-
|
40 |
-
/**
|
41 |
-
* @param int $parent_id
|
42 |
-
* @param int $child_id
|
43 |
-
* @param int $relationship_slug
|
44 |
-
*
|
45 |
-
* @return Toolset_Result
|
46 |
-
*/
|
47 |
-
public function migrate_association( $parent_id, $child_id, $relationship_slug ) {
|
48 |
-
|
49 |
-
$relationship_definition = $this->definition_repository->get_definition( $relationship_slug );
|
50 |
-
|
51 |
-
if( null == $relationship_definition ) {
|
52 |
-
return new Toolset_Result( false, sprintf( __( 'Relationship definition "%s" not found.', 'wpcf' ), $relationship_slug ) );
|
53 |
-
}
|
54 |
-
|
55 |
-
try {
|
56 |
-
// We specifically require posts (element_factory->get_post()) and not translation sets (which we might
|
57 |
-
// get when using element_factory->get_element()).
|
58 |
-
//
|
59 |
-
// Here, we create an association between two specific posts. When the WPML/m2m interop is fully
|
60 |
-
// implemented, this will be enough to track associations between all translations of these posts.
|
61 |
-
$parent = $this->element_factory->get_post( $parent_id );
|
62 |
-
$child = $this->element_factory->get_post( $child_id );
|
63 |
-
} catch( Exception $e ) {
|
64 |
-
$display_message = sprintf(
|
65 |
-
__( 'Unable to migrate an association from post #%d to #%d to a relationship "%s"', 'wpcf'),
|
66 |
-
$parent_id,
|
67 |
-
$child_id,
|
68 |
-
$relationship_slug
|
69 |
-
);
|
70 |
-
return new Toolset_Result( $e, $display_message );
|
71 |
-
}
|
72 |
-
|
73 |
-
$potential_association_query_factory = new Toolset_Potential_Association_Query_Factory();
|
74 |
-
$potential_association = $potential_association_query_factory->create(
|
75 |
-
$relationship_definition,
|
76 |
-
new Toolset_Relationship_Role_Child(),
|
77 |
-
$parent
|
78 |
-
);
|
79 |
-
|
80 |
-
if( ! $potential_association->check_single_element( $child ) ) {
|
81 |
-
return new Toolset_Result(
|
82 |
-
false,
|
83 |
-
sprintf(
|
84 |
-
__( 'The association between posts %d and %d is not allowed (maybe it already exists).', 'wpcf' ),
|
85 |
-
$parent->get_id(),
|
86 |
-
$child->get_id()
|
87 |
-
)
|
88 |
-
);
|
89 |
-
}
|
90 |
-
|
91 |
-
try {
|
92 |
-
$association = Toolset_Relationship_Database_Operations::create_association(
|
93 |
-
$relationship_slug,
|
94 |
-
$parent_id,
|
95 |
-
$child_id,
|
96 |
-
0 // no intermediary post
|
97 |
-
);
|
98 |
-
} catch( Exception $e ) {
|
99 |
-
return new Toolset_Result( $e );
|
100 |
-
}
|
101 |
-
|
102 |
-
if( $association instanceof Toolset_Result ) {
|
103 |
-
return new Toolset_Result(
|
104 |
-
false,
|
105 |
-
sprintf( "%s\n\t%s",
|
106 |
-
__( 'Error while saving an association to database.', 'wpcf' ),
|
107 |
-
print_r(
|
108 |
-
array( 'parent_id' => $parent_id, 'child_id' => $child_id, 'relationship_slug' => $relationship_slug ),
|
109 |
-
true
|
110 |
-
)
|
111 |
-
)
|
112 |
-
);
|
113 |
-
} else {
|
114 |
-
return new Toolset_Result( true );
|
115 |
-
}
|
116 |
-
|
117 |
-
}
|
118 |
-
|
119 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/toolset/toolset-common/inc/m2m/multilingual_mode.php
DELETED
@@ -1,236 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Determine (and cache) the m2m multilingual mode.
|
5 |
-
*
|
6 |
-
* m2m API needs to recognize three "multilingual modes" internally:
|
7 |
-
*
|
8 |
-
* 1. off - no support for language filtering (internally: each database row has its own trid and
|
9 |
-
* no other language information is stored)
|
10 |
-
* 2. on - with WPML, results are filtered by language and associations are basically made between
|
11 |
-
* translation groups (internally: rows in the associations of translatable relationships are grouped by
|
12 |
-
* trid, the translation_type is correctly set and such rows can have zeros instead of element IDs if
|
13 |
-
* a translation is missing)
|
14 |
-
* 3. transitional - after WPML is deactivated (internally: database structure is same as for on,
|
15 |
-
* but the behaviour of association query matches off; new associations are created without
|
16 |
-
* translation information)
|
17 |
-
*
|
18 |
-
* The transitional mode is required so that the site can keep working when WPML is deactivated
|
19 |
-
* (even temporarily). Switching from transitional to off needs to be done manually because it requires
|
20 |
-
* a large database update (similar to the migration from legacy post relationships to m2m).
|
21 |
-
*
|
22 |
-
* Most of the m2m API doesn't need to know about the transitional mode, it's the same as "off" in most cases.
|
23 |
-
* The only difference would be Toolset_Association_Query which needs to understand the database structure
|
24 |
-
* of pre-existing records after WPML was deactivated.
|
25 |
-
*
|
26 |
-
* Outside of m2m API, this should never be needed at all.
|
27 |
-
*
|
28 |
-
* @since m2m
|
29 |
-
*/
|
30 |
-
class Toolset_Relationship_Multilingual_Mode {
|
31 |
-
|
32 |
-
private static $instance;
|
33 |
-
|
34 |
-
public static function get_instance() {
|
35 |
-
if( null === self::$instance ) {
|
36 |
-
self::$instance = new self();
|
37 |
-
}
|
38 |
-
return self::$instance;
|
39 |
-
}
|
40 |
-
|
41 |
-
private function __construct() { }
|
42 |
-
|
43 |
-
private function __clone() { }
|
44 |
-
|
45 |
-
|
46 |
-
/**
|
47 |
-
* Is m2m in the multilingual mode?
|
48 |
-
*
|
49 |
-
* This is mostly important for the API internals, there should be no need to use this outside.
|
50 |
-
*
|
51 |
-
* @return bool
|
52 |
-
* @since m2m
|
53 |
-
*/
|
54 |
-
public static function is_on() {
|
55 |
-
return ( self::get_instance()->get_multilingual_mode() === self::MODE_ON );
|
56 |
-
}
|
57 |
-
|
58 |
-
|
59 |
-
/** @var null|string Cache for get_multilingual_mode(), 'on'|'off'|'transitional'. */
|
60 |
-
private $current_multilingual_mode = null;
|
61 |
-
|
62 |
-
|
63 |
-
private $translatable_relationships_exist = null;
|
64 |
-
|
65 |
-
|
66 |
-
const MULTILINGUAL_MODE_OPTION = 'toolset_m2m_multilingual_mode';
|
67 |
-
//const HAS_TRANSLARABLE_RELATIONSHIPS_OPTION = 'toolset_m2m_has_translatable_relationships';
|
68 |
-
|
69 |
-
const MODE_ON = 'on';
|
70 |
-
const MODE_OFF = 'off';
|
71 |
-
const MODE_TRANSITIONAL = 'transitional';
|
72 |
-
|
73 |
-
|
74 |
-
private static function allowed_modes() {
|
75 |
-
return array( self::MODE_OFF, self::MODE_ON, self::MODE_TRANSITIONAL );
|
76 |
-
}
|
77 |
-
|
78 |
-
|
79 |
-
/**
|
80 |
-
* Flush the cache of current multilingual mode.
|
81 |
-
*
|
82 |
-
* This needs to be done after a relationship definition or post type translation settings are updated
|
83 |
-
* (unless reloading a page immediately after).
|
84 |
-
*/
|
85 |
-
public static function flush_cache() {
|
86 |
-
$instance = self::get_instance();
|
87 |
-
$instance->current_multilingual_mode = null;
|
88 |
-
$instance->translatable_relationships_exist = null;
|
89 |
-
}
|
90 |
-
|
91 |
-
|
92 |
-
/**
|
93 |
-
* Determine the exact multilingual mode.
|
94 |
-
*
|
95 |
-
* To be used only by the m2m API and only when the transitional mode needs to be handled separately.
|
96 |
-
* Otherwise, is_multilingual_mode_on() is preferred.
|
97 |
-
*
|
98 |
-
* @return string
|
99 |
-
* @since m2m
|
100 |
-
*/
|
101 |
-
public static function get() {
|
102 |
-
return self::get_instance()->get_multilingual_mode();
|
103 |
-
}
|
104 |
-
|
105 |
-
|
106 |
-
/**
|
107 |
-
* Is m2m in the transitional mode?
|
108 |
-
*
|
109 |
-
* @return bool
|
110 |
-
*/
|
111 |
-
public static function is_transitional() {
|
112 |
-
return ( self::get() === self::MODE_TRANSITIONAL );
|
113 |
-
}
|
114 |
-
|
115 |
-
|
116 |
-
private function get_multilingual_mode() {
|
117 |
-
|
118 |
-
// Allways off since this functionality is about to be removed.
|
119 |
-
return self::MODE_OFF;
|
120 |
-
|
121 |
-
if( null === $this->current_multilingual_mode ) {
|
122 |
-
|
123 |
-
$stored_mode = $this->load_multilingual_mode_option();
|
124 |
-
$current_mode = $this->calculate_multilingual_mode();
|
125 |
-
|
126 |
-
if( $stored_mode !== $current_mode ) {
|
127 |
-
update_option( self::MULTILINGUAL_MODE_OPTION, $current_mode, true );
|
128 |
-
}
|
129 |
-
|
130 |
-
$this->current_multilingual_mode = $current_mode;
|
131 |
-
|
132 |
-
}
|
133 |
-
|
134 |
-
return $this->current_multilingual_mode;
|
135 |
-
}
|
136 |
-
|
137 |
-
|
138 |
-
private function load_multilingual_mode_option() {
|
139 |
-
|
140 |
-
$stored_mode = get_option( self::MULTILINGUAL_MODE_OPTION );
|
141 |
-
if( ! in_array( $stored_mode, self::allowed_modes() ) ) {
|
142 |
-
$stored_mode = 'off';
|
143 |
-
}
|
144 |
-
|
145 |
-
return $stored_mode;
|
146 |
-
}
|
147 |
-
|
148 |
-
|
149 |
-
/**
|
150 |
-
* Calculate what the current multilingual mode should be, based on WPML state,
|
151 |
-
* existence of translatable relationships and previous mode.
|
152 |
-
*
|
153 |
-
* @return string New multilingual mode.
|
154 |
-
* @since m2m
|
155 |
-
*/
|
156 |
-
private function calculate_multilingual_mode() {
|
157 |
-
|
158 |
-
$wpml_interop = Toolset_WPML_Compatibility::get_instance();
|
159 |
-
$is_wpml_active = $wpml_interop->is_wpml_active_and_configured();
|
160 |
-
|
161 |
-
// Note: This can be true only when WPML is active, otherwise it's not possible
|
162 |
-
// to get the translatability status.
|
163 |
-
$translatable_relationships_exist = $this->translatable_relationships_exist();
|
164 |
-
|
165 |
-
// https://code2flow.com/0TjdqR
|
166 |
-
if ( $is_wpml_active && $translatable_relationships_exist && $this->is_wpml_version_supported() ) {
|
167 |
-
$mode = self::MODE_ON;
|
168 |
-
} elseif ( self::MODE_OFF !== $this->load_multilingual_mode_option() ) {
|
169 |
-
// This means that the previous condition was true before (WPML active + translatable relationships).
|
170 |
-
// So we don't need to check for the relationships anymore (which we can't do now anyway) and
|
171 |
-
// at the same time we're not risking switching into transitional mode without having
|
172 |
-
// translatable relationships.
|
173 |
-
$mode = self::MODE_TRANSITIONAL;
|
174 |
-
|
175 |
-
// todo add a notice via Toolset_Admin_Notices_Manager
|
176 |
-
} else {
|
177 |
-
$mode = self::MODE_OFF;
|
178 |
-
}
|
179 |
-
|
180 |
-
return $mode;
|
181 |
-
}
|
182 |
-
|
183 |
-
|
184 |
-
private function is_wpml_version_supported() {
|
185 |
-
$wpml_interop = Toolset_WPML_Compatibility::get_instance();
|
186 |
-
return version_compare( $wpml_interop->get_wpml_version(), Toolset_Relationship_Controller::MINIMAL_WPML_VERSION, '>=' );
|
187 |
-
}
|
188 |
-
|
189 |
-
|
190 |
-
/**
|
191 |
-
* Check if there are any relationship definitions that are translatable.
|
192 |
-
*
|
193 |
-
* @return bool
|
194 |
-
*/
|
195 |
-
private function translatable_relationships_exist() {
|
196 |
-
|
197 |
-
if( null === $this->translatable_relationships_exist ) {
|
198 |
-
|
199 |
-
if ( ! Toolset_WPML_Compatibility::get_instance()->is_wpml_active_and_configured() ) {
|
200 |
-
|
201 |
-
$this->translatable_relationships_exist = false;
|
202 |
-
|
203 |
-
} else {
|
204 |
-
|
205 |
-
// In order to do this, we'd need to reset the value when any relationship definition
|
206 |
-
// is created, updated or removed, or any post type's translation preferences changed.
|
207 |
-
// Seems like an overkill at this point.
|
208 |
-
//$this->translatable_relationships_exist = get_option( self::HAS_TRANSLARABLE_RELATIONSHIPS_OPTION, null );
|
209 |
-
|
210 |
-
if ( null === $this->translatable_relationships_exist ) {
|
211 |
-
$relationship_query = new Toolset_Relationship_Query( array(
|
212 |
-
Toolset_Relationship_Query::QUERY_IS_TRANSLATABLE => true
|
213 |
-
) );
|
214 |
-
|
215 |
-
$results = $relationship_query->get_results();
|
216 |
-
|
217 |
-
$this->translatable_relationships_exist = ( ! empty( $results ) );
|
218 |
-
|
219 |
-
//update_option( self::HAS_TRANSLARABLE_RELATIONSHIPS_OPTION, $this->translatable_relationships_exist, true );
|
220 |
-
}
|
221 |
-
}
|
222 |
-
}
|
223 |
-
|
224 |
-
return $this->translatable_relationships_exist;
|
225 |
-
}
|
226 |
-
|
227 |
-
|
228 |
-
public function set_mode( $new_mode ) {
|
229 |
-
if( ! in_array( $new_mode, self::allowed_modes() ) ) {
|
230 |
-
throw new InvalidArgumentException();
|
231 |
-
}
|
232 |
-
|
233 |
-
update_option( self::MULTILINGUAL_MODE_OPTION, $new_mode, true );
|
234 |
-
}
|
235 |
-
|
236 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/toolset/toolset-common/inc/m2m/potential_association/distinct_post_query.php
CHANGED
@@ -13,11 +13,11 @@
|
|
13 |
*/
|
14 |
class Toolset_Relationship_Distinct_Post_Query {
|
15 |
|
16 |
-
/** @var
|
17 |
private $relationship;
|
18 |
|
19 |
-
/** @var
|
20 |
-
private $
|
21 |
|
22 |
/** @var IToolset_Relationship_Role_Parent_Child */
|
23 |
private $target_role;
|
@@ -28,27 +28,33 @@ class Toolset_Relationship_Distinct_Post_Query {
|
|
28 |
/** @var null|wpdb */
|
29 |
private $_wpdb;
|
30 |
|
|
|
|
|
|
|
31 |
|
32 |
/**
|
33 |
* Toolset_Relationship_Distinct_Post_Query constructor.
|
34 |
*
|
35 |
-
* @param
|
36 |
* @param IToolset_Relationship_Role_Parent_Child $target_role Target role of the relationships (future role of
|
37 |
* the posts that are being queried)
|
38 |
-
* @param
|
39 |
* @param Toolset_Relationship_Table_Name|null $table_names_di
|
40 |
* @param wpdb|null $wpdb_di
|
|
|
41 |
*/
|
42 |
public function __construct(
|
43 |
-
|
44 |
IToolset_Relationship_Role_Parent_Child $target_role,
|
45 |
-
$
|
46 |
Toolset_Relationship_Table_Name $table_names_di = null,
|
47 |
-
wpdb $wpdb_di = null
|
|
|
48 |
) {
|
49 |
$this->relationship = $relationship;
|
50 |
-
$this->
|
51 |
$this->target_role = $target_role;
|
|
|
52 |
|
53 |
$this->_table_names = $table_names_di;
|
54 |
$this->_wpdb = $wpdb_di;
|
@@ -69,8 +75,12 @@ class Toolset_Relationship_Distinct_Post_Query {
|
|
69 |
}
|
70 |
|
71 |
add_filter( 'posts_join', array( $this, 'add_join_clauses' ) );
|
72 |
-
|
73 |
add_filter( 'posts_where', array( $this, 'add_where_clauses' ) );
|
|
|
|
|
|
|
|
|
|
|
74 |
}
|
75 |
|
76 |
|
@@ -83,8 +93,9 @@ class Toolset_Relationship_Distinct_Post_Query {
|
|
83 |
}
|
84 |
|
85 |
remove_filter( 'posts_join', array( $this, 'add_join_clauses' ) );
|
86 |
-
|
87 |
remove_filter( 'posts_where', array( $this, 'add_where_clauses' ) );
|
|
|
|
|
88 |
}
|
89 |
|
90 |
|
@@ -115,6 +126,9 @@ class Toolset_Relationship_Distinct_Post_Query {
|
|
115 |
*
|
116 |
* Otherwise, those columns will be NULL, because we're doing a LEFT JOIN here.
|
117 |
*
|
|
|
|
|
|
|
118 |
* @param string $join
|
119 |
*
|
120 |
* @return string
|
@@ -132,9 +146,31 @@ class Toolset_Relationship_Distinct_Post_Query {
|
|
132 |
AND toolset_associations.{$for_element_column} = %d
|
133 |
) ",
|
134 |
$this->relationship->get_row_id(),
|
135 |
-
$this->
|
136 |
);
|
137 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
138 |
return $join;
|
139 |
}
|
140 |
|
@@ -146,6 +182,9 @@ class Toolset_Relationship_Distinct_Post_Query {
|
|
146 |
* column with $for_element: That means there's no association between the queried
|
147 |
* post and $for_element, and we can offer the post as a result.
|
148 |
*
|
|
|
|
|
|
|
149 |
* @param string $where
|
150 |
*
|
151 |
* @return string
|
@@ -153,6 +192,11 @@ class Toolset_Relationship_Distinct_Post_Query {
|
|
153 |
public function add_where_clauses( $where ) {
|
154 |
$for_element_column = $this->target_role->other() . '_id';
|
155 |
$where .= " AND ( toolset_associations.{$for_element_column} IS NULL ) ";
|
|
|
|
|
|
|
|
|
|
|
156 |
return $where;
|
157 |
}
|
158 |
|
13 |
*/
|
14 |
class Toolset_Relationship_Distinct_Post_Query {
|
15 |
|
16 |
+
/** @var IToolset_Relationship_Definition */
|
17 |
private $relationship;
|
18 |
|
19 |
+
/** @var IToolset_Element */
|
20 |
+
private $for_element;
|
21 |
|
22 |
/** @var IToolset_Relationship_Role_Parent_Child */
|
23 |
private $target_role;
|
28 |
/** @var null|wpdb */
|
29 |
private $_wpdb;
|
30 |
|
31 |
+
/** @var Toolset_WPML_Compatibility */
|
32 |
+
private $wpml_service;
|
33 |
+
|
34 |
|
35 |
/**
|
36 |
* Toolset_Relationship_Distinct_Post_Query constructor.
|
37 |
*
|
38 |
+
* @param IToolset_Relationship_Definition $relationship
|
39 |
* @param IToolset_Relationship_Role_Parent_Child $target_role Target role of the relationships (future role of
|
40 |
* the posts that are being queried)
|
41 |
+
* @param IToolset_Element $for_element ID of the element to check against.
|
42 |
* @param Toolset_Relationship_Table_Name|null $table_names_di
|
43 |
* @param wpdb|null $wpdb_di
|
44 |
+
* @param Toolset_WPML_Compatibility|null $wpml_service_di
|
45 |
*/
|
46 |
public function __construct(
|
47 |
+
IToolset_Relationship_Definition $relationship,
|
48 |
IToolset_Relationship_Role_Parent_Child $target_role,
|
49 |
+
IToolset_Element $for_element,
|
50 |
Toolset_Relationship_Table_Name $table_names_di = null,
|
51 |
+
wpdb $wpdb_di = null,
|
52 |
+
Toolset_WPML_Compatibility $wpml_service_di = null
|
53 |
) {
|
54 |
$this->relationship = $relationship;
|
55 |
+
$this->for_element = $for_element;
|
56 |
$this->target_role = $target_role;
|
57 |
+
$this->wpml_service = $wpml_service_di ?: Toolset_WPML_Compatibility::get_instance();
|
58 |
|
59 |
$this->_table_names = $table_names_di;
|
60 |
$this->_wpdb = $wpdb_di;
|
75 |
}
|
76 |
|
77 |
add_filter( 'posts_join', array( $this, 'add_join_clauses' ) );
|
|
|
78 |
add_filter( 'posts_where', array( $this, 'add_where_clauses' ) );
|
79 |
+
|
80 |
+
// WPML in the back-end filters strictly by the current language by default,
|
81 |
+
// but we need it to include default language posts, too, if the translation to the current language
|
82 |
+
// doesn't exist. This needs to behave consistently in all contexts.
|
83 |
+
add_filter( 'wpml_should_use_display_as_translated_snippet', '__return_true' );
|
84 |
}
|
85 |
|
86 |
|
93 |
}
|
94 |
|
95 |
remove_filter( 'posts_join', array( $this, 'add_join_clauses' ) );
|
|
|
96 |
remove_filter( 'posts_where', array( $this, 'add_where_clauses' ) );
|
97 |
+
|
98 |
+
remove_filter( 'wpml_should_use_display_as_translated_snippet', '__return_true' );
|
99 |
}
|
100 |
|
101 |
|
126 |
*
|
127 |
* Otherwise, those columns will be NULL, because we're doing a LEFT JOIN here.
|
128 |
*
|
129 |
+
* If WPML is active, we also do the same comparison for the default language version of the
|
130 |
+
* queried post, if it exists.
|
131 |
+
*
|
132 |
* @param string $join
|
133 |
*
|
134 |
* @return string
|
146 |
AND toolset_associations.{$for_element_column} = %d
|
147 |
) ",
|
148 |
$this->relationship->get_row_id(),
|
149 |
+
$this->for_element->get_default_language_id()
|
150 |
);
|
151 |
|
152 |
+
if( $this->wpml_service->is_wpml_active_and_configured() ) {
|
153 |
+
$icl_translations = $this->get_wpdb()->prefix . 'icl_translations';
|
154 |
+
$default_language = esc_sql( $this->wpml_service->get_default_language() );
|
155 |
+
$join .= $this->get_wpdb()->prepare(
|
156 |
+
" LEFT JOIN {$icl_translations} AS element_lang_info ON (
|
157 |
+
{$posts_table_name}.ID = element_lang_info.element_id
|
158 |
+
AND element_lang_info.element_type LIKE %s
|
159 |
+
) LEFT JOIN {$icl_translations} AS default_lang_translation ON (
|
160 |
+
element_lang_info.trid = default_lang_translation.trid
|
161 |
+
AND default_lang_translation.language_code = %s
|
162 |
+
) LEFT JOIN {$association_table} AS default_lang_association ON (
|
163 |
+
default_lang_association.relationship_id = %d
|
164 |
+
AND default_lang_translation.element_id = default_lang_association.{$target_element_column}
|
165 |
+
AND default_lang_association.{$for_element_column} = %d
|
166 |
+
) ",
|
167 |
+
'post_%',
|
168 |
+
$default_language,
|
169 |
+
$this->relationship->get_row_id(),
|
170 |
+
$this->for_element->get_default_language_id()
|
171 |
+
);
|
172 |
+
}
|
173 |
+
|
174 |
return $join;
|
175 |
}
|
176 |
|
182 |
* column with $for_element: That means there's no association between the queried
|
183 |
* post and $for_element, and we can offer the post as a result.
|
184 |
*
|
185 |
+
* If WPML is active, we also have to check that there's no default language translation
|
186 |
+
* of the queried post that would be part of such an association.
|
187 |
+
*
|
188 |
* @param string $where
|
189 |
*
|
190 |
* @return string
|
192 |
public function add_where_clauses( $where ) {
|
193 |
$for_element_column = $this->target_role->other() . '_id';
|
194 |
$where .= " AND ( toolset_associations.{$for_element_column} IS NULL ) ";
|
195 |
+
|
196 |
+
if( $this->wpml_service->is_wpml_active_and_configured() ) {
|
197 |
+
$where .= " AND ( default_lang_association.{$for_element_column} IS NULL ) ";
|
198 |
+
}
|
199 |
+
|
200 |
return $where;
|
201 |
}
|
202 |
|
vendor/toolset/toolset-common/inc/m2m/potential_association/query_interface.php
CHANGED
@@ -46,10 +46,12 @@ interface IToolset_Potential_Association_Query extends IToolset_Query {
|
|
46 |
* The relationship, target role and the other element are those provided in the constructor.
|
47 |
*
|
48 |
* @param IToolset_Element $association_candidate Element that wants to be associated.
|
|
|
|
|
49 |
* @return Toolset_Result Result with an user-friendly message in case the association is denied.
|
50 |
* @since 2.5.6
|
51 |
*/
|
52 |
-
public function check_single_element( IToolset_Element $association_candidate );
|
53 |
|
54 |
|
55 |
/**
|
@@ -60,4 +62,17 @@ interface IToolset_Potential_Association_Query extends IToolset_Query {
|
|
60 |
*/
|
61 |
public function can_connect_another_element();
|
62 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
63 |
}
|
46 |
* The relationship, target role and the other element are those provided in the constructor.
|
47 |
*
|
48 |
* @param IToolset_Element $association_candidate Element that wants to be associated.
|
49 |
+
* @param bool $check_is_already_associated Perform the check that the element is already associated for distinct
|
50 |
+
* relationships. Default is true. Set to false only if the check was performed manually before.
|
51 |
* @return Toolset_Result Result with an user-friendly message in case the association is denied.
|
52 |
* @since 2.5.6
|
53 |
*/
|
54 |
+
public function check_single_element( IToolset_Element $association_candidate, $check_is_already_associated = true );
|
55 |
|
56 |
|
57 |
/**
|
62 |
*/
|
63 |
public function can_connect_another_element();
|
64 |
|
65 |
+
|
66 |
+
/**
|
67 |
+
* Check whether there already exists an association between the the target element and the provided one.
|
68 |
+
*
|
69 |
+
* Note that it doesn't always have to be a problem, it depends on whether the relationship is distinct or not.
|
70 |
+
* This was made public to optimize performance during the m2m migration process.
|
71 |
+
*
|
72 |
+
* @param IToolset_Element $element
|
73 |
+
*
|
74 |
+
* @return bool
|
75 |
+
*/
|
76 |
+
public function is_element_already_associated( IToolset_Element $element );
|
77 |
+
|
78 |
}
|
vendor/toolset/toolset-common/inc/m2m/potential_association/query_posts.php
CHANGED
@@ -34,6 +34,9 @@ class Toolset_Potential_Association_Query_Posts implements IToolset_Potential_As
|
|
34 |
private $query_factory;
|
35 |
|
36 |
|
|
|
|
|
|
|
37 |
/**
|
38 |
* Toolset_Potential_Association_Query constructor.
|
39 |
*
|
@@ -47,13 +50,15 @@ class Toolset_Potential_Association_Query_Posts implements IToolset_Potential_As
|
|
47 |
* - page: int
|
48 |
* - wp_query_override: array
|
49 |
* @param Toolset_Relationship_Query_Factory|null $query_factory_di
|
|
|
50 |
*/
|
51 |
public function __construct(
|
52 |
IToolset_Relationship_Definition $relationship,
|
53 |
IToolset_Relationship_Role_Parent_Child $target_role,
|
54 |
IToolset_Element $for_element,
|
55 |
$args,
|
56 |
-
Toolset_Relationship_Query_Factory $query_factory_di = null
|
|
|
57 |
) {
|
58 |
$this->relationship = $relationship;
|
59 |
$this->for_element = $for_element;
|
@@ -65,11 +70,13 @@ class Toolset_Potential_Association_Query_Posts implements IToolset_Potential_As
|
|
65 |
}
|
66 |
|
67 |
$this->query_factory = ( null === $query_factory_di ? new Toolset_Relationship_Query_Factory() : $query_factory_di );
|
|
|
68 |
}
|
69 |
|
70 |
|
71 |
/**
|
72 |
* @return IToolset_Post[]
|
|
|
73 |
*/
|
74 |
public function get_results() {
|
75 |
|
@@ -110,7 +117,7 @@ class Toolset_Potential_Association_Query_Posts implements IToolset_Potential_As
|
|
110 |
$augment_query_for_distinct_relationships = $this->query_factory->distinct_relationship_posts(
|
111 |
$this->relationship,
|
112 |
$this->target_role,
|
113 |
-
$this->for_element
|
114 |
);
|
115 |
|
116 |
$augment_query_for_distinct_relationships->before_query();
|
@@ -164,14 +171,12 @@ class Toolset_Potential_Association_Query_Posts implements IToolset_Potential_As
|
|
164 |
* @param WP_Post[] $wp_posts
|
165 |
*
|
166 |
* @return IToolset_Post[]
|
|
|
167 |
*/
|
168 |
private function transform_results( $wp_posts ) {
|
169 |
$results = array();
|
170 |
foreach( $wp_posts as $wp_post ) {
|
171 |
-
$results[] =
|
172 |
-
Toolset_Field_Utils::DOMAIN_POSTS,
|
173 |
-
$wp_post
|
174 |
-
);
|
175 |
}
|
176 |
|
177 |
return $results;
|
@@ -195,16 +200,22 @@ class Toolset_Potential_Association_Query_Posts implements IToolset_Potential_As
|
|
195 |
* The relationship, target role and the other element are those provided in the constructor.
|
196 |
*
|
197 |
* @param IToolset_Element $association_candidate Element that wants to be associated.
|
|
|
|
|
|
|
198 |
* @return Toolset_Result Result with an user-friendly message in case the association is denied.
|
199 |
* @since 2.5.6
|
200 |
*/
|
201 |
-
public function check_single_element( IToolset_Element $association_candidate ) {
|
202 |
|
203 |
if( ! $this->relationship->get_element_type( $this->target_role )->is_match( $association_candidate ) ) {
|
204 |
return new Toolset_Result( false, __( 'The element has a wrong type or a domain for this relationship.', 'wpcf' ) );
|
205 |
}
|
206 |
|
207 |
-
if( $
|
|
|
|
|
|
|
208 |
return new Toolset_Result( false,
|
209 |
__( 'These two elements are already associated and the relationship doesn\'t allow non-distinct associations.', 'wpcf' )
|
210 |
);
|
@@ -259,21 +270,32 @@ class Toolset_Potential_Association_Query_Posts implements IToolset_Potential_As
|
|
259 |
}
|
260 |
|
261 |
|
262 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
263 |
|
264 |
/** @var IToolset_Element[] $parent_and_child */
|
265 |
$parent_and_child = Toolset_Relationship_Role::sort_elements( $element, $this->for_element, $this->target_role );
|
266 |
|
267 |
-
$query = $this->query_factory->
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
|
|
|
|
|
|
|
|
273 |
|
274 |
-
$
|
275 |
|
276 |
-
return (
|
277 |
}
|
278 |
|
279 |
|
@@ -307,20 +329,19 @@ class Toolset_Potential_Association_Query_Posts implements IToolset_Potential_As
|
|
307 |
private function get_number_of_already_associated_elements(
|
308 |
IToolset_Relationship_Role_Parent_Child $role, IToolset_Element $element
|
309 |
) {
|
310 |
-
$
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
return count( $results );
|
324 |
}
|
325 |
|
326 |
/**
|
34 |
private $query_factory;
|
35 |
|
36 |
|
37 |
+
private $element_factory;
|
38 |
+
|
39 |
+
|
40 |
/**
|
41 |
* Toolset_Potential_Association_Query constructor.
|
42 |
*
|
50 |
* - page: int
|
51 |
* - wp_query_override: array
|
52 |
* @param Toolset_Relationship_Query_Factory|null $query_factory_di
|
53 |
+
* @param Toolset_Element_Factory|null $element_factory_di
|
54 |
*/
|
55 |
public function __construct(
|
56 |
IToolset_Relationship_Definition $relationship,
|
57 |
IToolset_Relationship_Role_Parent_Child $target_role,
|
58 |
IToolset_Element $for_element,
|
59 |
$args,
|
60 |
+
Toolset_Relationship_Query_Factory $query_factory_di = null,
|
61 |
+
Toolset_Element_Factory $element_factory_di = null
|
62 |
) {
|
63 |
$this->relationship = $relationship;
|
64 |
$this->for_element = $for_element;
|
70 |
}
|
71 |
|
72 |
$this->query_factory = ( null === $query_factory_di ? new Toolset_Relationship_Query_Factory() : $query_factory_di );
|
73 |
+
$this->element_factory = ( null === $element_factory_di ? new Toolset_Element_Factory() : $element_factory_di );
|
74 |
}
|
75 |
|
76 |
|
77 |
/**
|
78 |
* @return IToolset_Post[]
|
79 |
+
* @throws Toolset_Element_Exception_Element_Doesnt_Exist
|
80 |
*/
|
81 |
public function get_results() {
|
82 |
|
117 |
$augment_query_for_distinct_relationships = $this->query_factory->distinct_relationship_posts(
|
118 |
$this->relationship,
|
119 |
$this->target_role,
|
120 |
+
$this->for_element
|
121 |
);
|
122 |
|
123 |
$augment_query_for_distinct_relationships->before_query();
|
171 |
* @param WP_Post[] $wp_posts
|
172 |
*
|
173 |
* @return IToolset_Post[]
|
174 |
+
* @throws Toolset_Element_Exception_Element_Doesnt_Exist
|
175 |
*/
|
176 |
private function transform_results( $wp_posts ) {
|
177 |
$results = array();
|
178 |
foreach( $wp_posts as $wp_post ) {
|
179 |
+
$results[] = $this->element_factory->get_post( $wp_post );
|
|
|
|
|
|
|
180 |
}
|
181 |
|
182 |
return $results;
|
200 |
* The relationship, target role and the other element are those provided in the constructor.
|
201 |
*
|
202 |
* @param IToolset_Element $association_candidate Element that wants to be associated.
|
203 |
+
* @param bool $check_is_already_associated Perform the check that the element is already associated for distinct
|
204 |
+
* relationships. Default is true. Set to false only if the check was performed manually before.
|
205 |
+
*
|
206 |
* @return Toolset_Result Result with an user-friendly message in case the association is denied.
|
207 |
* @since 2.5.6
|
208 |
*/
|
209 |
+
public function check_single_element( IToolset_Element $association_candidate, $check_is_already_associated = true ) {
|
210 |
|
211 |
if( ! $this->relationship->get_element_type( $this->target_role )->is_match( $association_candidate ) ) {
|
212 |
return new Toolset_Result( false, __( 'The element has a wrong type or a domain for this relationship.', 'wpcf' ) );
|
213 |
}
|
214 |
|
215 |
+
if( $check_is_already_associated
|
216 |
+
&& $this->relationship->is_distinct()
|
217 |
+
&& $this->is_element_already_associated( $association_candidate )
|
218 |
+
) {
|
219 |
return new Toolset_Result( false,
|
220 |
__( 'These two elements are already associated and the relationship doesn\'t allow non-distinct associations.', 'wpcf' )
|
221 |
);
|
270 |
}
|
271 |
|
272 |
|
273 |
+
/**
|
274 |
+
* @inheritdoc
|
275 |
+
*
|
276 |
+
* @param IToolset_Element $element
|
277 |
+
*
|
278 |
+
* @return bool
|
279 |
+
*/
|
280 |
+
public function is_element_already_associated( IToolset_Element $element ) {
|
281 |
|
282 |
/** @var IToolset_Element[] $parent_and_child */
|
283 |
$parent_and_child = Toolset_Relationship_Role::sort_elements( $element, $this->for_element, $this->target_role );
|
284 |
|
285 |
+
$query = $this->query_factory->associations_v2();
|
286 |
+
|
287 |
+
$query->add( $query->relationship( $this->relationship ) )
|
288 |
+
->add( $query->parent( $parent_and_child[0] ) )
|
289 |
+
->add( $query->child( $parent_and_child[1] ) )
|
290 |
+
->do_not_add_default_conditions() // include all existing associations
|
291 |
+
->limit( 1 ) // because we're not interested in the actual resuls
|
292 |
+
->need_found_rows()
|
293 |
+
->return_association_uids() // ditto
|
294 |
+
->get_results();
|
295 |
|
296 |
+
$result_count = $query->get_found_rows();
|
297 |
|
298 |
+
return ( $result_count > 0 );
|
299 |
}
|
300 |
|
301 |
|
329 |
private function get_number_of_already_associated_elements(
|
330 |
IToolset_Relationship_Role_Parent_Child $role, IToolset_Element $element
|
331 |
) {
|
332 |
+
$query = $this->query_factory->associations_v2();
|
333 |
+
$query
|
334 |
+
->add( $query->relationship_slug( $this->relationship->get_slug() ) )
|
335 |
+
->add( $query->element( $element, $role ) )
|
336 |
+
->do_not_add_default_conditions() // include all existing associations
|
337 |
+
->need_found_rows()
|
338 |
+
->limit( 1 ) // because we're not interested in the actual resuls
|
339 |
+
->return_association_uids() // ditto
|
340 |
+
->get_results();
|
341 |
+
|
342 |
+
$row_count = $query->get_found_rows();
|
343 |
+
|
344 |
+
return $row_count;
|
|
|
345 |
}
|
346 |
|
347 |
/**
|
vendor/toolset/toolset-common/inc/m2m/query/comparison_operator.php
ADDED
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Pseudo-enum that holds possible comparison operators.
|
5 |
+
*
|
6 |
+
* Used, for example, on the meta() query condition.
|
7 |
+
* Can be further extended.
|
8 |
+
*
|
9 |
+
* @since 2.6.1
|
10 |
+
*/
|
11 |
+
class Toolset_Query_Comparison_Operator {
|
12 |
+
|
13 |
+
|
14 |
+
// These need to be valid MySQL operators.
|
15 |
+
const EQUALS = '=';
|
16 |
+
const LIKE = 'LIKE';
|
17 |
+
|
18 |
+
|
19 |
+
/**
|
20 |
+
* All accepted values.
|
21 |
+
*
|
22 |
+
* @return string[]
|
23 |
+
*/
|
24 |
+
public static function all() {
|
25 |
+
return array( self::EQUALS, self::LIKE );
|
26 |
+
}
|
27 |
+
|
28 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/{relationship_query → query}/condition/and.php
RENAMED
@@ -1,11 +1,11 @@
|
|
1 |
<?php
|
2 |
|
3 |
/**
|
4 |
-
* Chains multiple
|
5 |
*
|
6 |
* @since m2m
|
7 |
*/
|
8 |
-
class
|
9 |
|
10 |
|
11 |
/**
|
@@ -33,11 +33,16 @@ class Toolset_Relationship_Query_Condition_And extends Toolset_Relationship_Quer
|
|
33 |
/**
|
34 |
* @inheritdoc
|
35 |
*
|
36 |
-
* @param
|
37 |
*
|
38 |
-
* @return
|
39 |
*/
|
40 |
protected function instantiate_self( $conditions ) {
|
41 |
return new self( $conditions );
|
42 |
}
|
|
|
|
|
|
|
|
|
|
|
43 |
}
|
1 |
<?php
|
2 |
|
3 |
/**
|
4 |
+
* Chains multiple IToolset_Query_Condition with AND.
|
5 |
*
|
6 |
* @since m2m
|
7 |
*/
|
8 |
+
class Toolset_Query_Condition_And extends Toolset_Query_Condition_Operator {
|
9 |
|
10 |
|
11 |
/**
|
33 |
/**
|
34 |
* @inheritdoc
|
35 |
*
|
36 |
+
* @param IToolset_Query_Condition[] $conditions
|
37 |
*
|
38 |
+
* @return Toolset_Query_Condition_And
|
39 |
*/
|
40 |
protected function instantiate_self( $conditions ) {
|
41 |
return new self( $conditions );
|
42 |
}
|
43 |
+
|
44 |
+
|
45 |
+
public function get_inner_conditions() {
|
46 |
+
return $this->conditions;
|
47 |
+
}
|
48 |
}
|
vendor/toolset/toolset-common/inc/m2m/query/condition/contradiction.php
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* A condition that is always false.
|
5 |
+
*
|
6 |
+
* It can be useful in situations where we need to make sure that the query will produce no results
|
7 |
+
* (e.g. querying for something that clearly isn't there).
|
8 |
+
*
|
9 |
+
* @since 2.5.8
|
10 |
+
*/
|
11 |
+
class Toolset_Query_Condition_Contradiction
|
12 |
+
implements IToolset_Relationship_Query_Condition, IToolset_Association_Query_Condition
|
13 |
+
{
|
14 |
+
|
15 |
+
|
16 |
+
public function get_join_clause() {
|
17 |
+
return '';
|
18 |
+
}
|
19 |
+
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Get a part of the WHERE clause that applies the condition.
|
23 |
+
*
|
24 |
+
* @return string Valid part of a MySQL query, so that it can be
|
25 |
+
* used in WHERE ( $condition1 ) AND ( $condition2 ) AND ( $condition3 ) ...
|
26 |
+
*/
|
27 |
+
public function get_where_clause() {
|
28 |
+
return ' 1 = 0 ';
|
29 |
+
}
|
30 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/{relationship_query/condition/i_condition.php → query/condition/interface.php}
RENAMED
@@ -1,11 +1,6 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
|
4 |
-
* Represents a single condition for the Tooset_Relationship_Query_V2.
|
5 |
-
*
|
6 |
-
* @since m2m
|
7 |
-
*/
|
8 |
-
interface IToolset_Relationship_Query_Condition {
|
9 |
|
10 |
/**
|
11 |
* Get a part of the WHERE clause that applies the condition.
|
@@ -25,4 +20,5 @@ interface IToolset_Relationship_Query_Condition {
|
|
25 |
*/
|
26 |
public function get_join_clause();
|
27 |
|
|
|
28 |
}
|
1 |
<?php
|
2 |
|
3 |
+
interface IToolset_Query_Condition {
|
|
|
|
|
|
|
|
|
|
|
4 |
|
5 |
/**
|
6 |
* Get a part of the WHERE clause that applies the condition.
|
20 |
*/
|
21 |
public function get_join_clause();
|
22 |
|
23 |
+
|
24 |
}
|
vendor/toolset/toolset-common/inc/m2m/{relationship_query → query}/condition/operator.php
RENAMED
@@ -5,17 +5,19 @@
|
|
5 |
*
|
6 |
* @since 2.5.4
|
7 |
*/
|
8 |
-
abstract class
|
|
|
|
|
9 |
|
10 |
|
11 |
-
/** @var
|
12 |
protected $conditions = array();
|
13 |
|
14 |
|
15 |
/**
|
16 |
-
*
|
17 |
*
|
18 |
-
* @param
|
19 |
* is provided, it will be handled as a nested $op ($op is the operation):
|
20 |
* ( $condition1 ) $op ( ( $condition2_1 ) $op ( $condition2_2 ) ) $op ...etc.
|
21 |
*/
|
@@ -25,11 +27,11 @@ abstract class Toolset_Relationship_Query_Condition_Operator implements IToolset
|
|
25 |
|
26 |
|
27 |
/**
|
28 |
-
* @param
|
29 |
*/
|
30 |
private function add_conditions( $conditions ) {
|
31 |
foreach( $conditions as $condition ) {
|
32 |
-
if( $condition instanceof
|
33 |
$this->conditions[] = $condition;
|
34 |
} elseif( is_array( $condition ) ) {
|
35 |
if( count( $condition ) === 1 ) {
|
5 |
*
|
6 |
* @since 2.5.4
|
7 |
*/
|
8 |
+
abstract class Toolset_Query_Condition_Operator
|
9 |
+
implements IToolset_Relationship_Query_Condition, IToolset_Association_Query_Condition
|
10 |
+
{
|
11 |
|
12 |
|
13 |
+
/** @var IToolset_Query_Condition[] */
|
14 |
protected $conditions = array();
|
15 |
|
16 |
|
17 |
/**
|
18 |
+
* Toolset_Query_Condition_Operator constructor.
|
19 |
*
|
20 |
+
* @param IToolset_Query_Condition[]|array $conditions If a nested array of conditions
|
21 |
* is provided, it will be handled as a nested $op ($op is the operation):
|
22 |
* ( $condition1 ) $op ( ( $condition2_1 ) $op ( $condition2_2 ) ) $op ...etc.
|
23 |
*/
|
27 |
|
28 |
|
29 |
/**
|
30 |
+
* @param IToolset_Query_Condition[]|array $conditions
|
31 |
*/
|
32 |
private function add_conditions( $conditions ) {
|
33 |
foreach( $conditions as $condition ) {
|
34 |
+
if( $condition instanceof IToolset_Query_Condition ) {
|
35 |
$this->conditions[] = $condition;
|
36 |
} elseif( is_array( $condition ) ) {
|
37 |
if( count( $condition ) === 1 ) {
|
vendor/toolset/toolset-common/inc/m2m/{relationship_query → query}/condition/or.php
RENAMED
@@ -1,11 +1,11 @@
|
|
1 |
<?php
|
2 |
|
3 |
/**
|
4 |
-
* Chains multiple
|
5 |
*
|
6 |
* @since m2m
|
7 |
*/
|
8 |
-
class
|
9 |
|
10 |
|
11 |
/**
|
@@ -32,9 +32,9 @@ class Toolset_Relationship_Query_Condition_Or extends Toolset_Relationship_Query
|
|
32 |
|
33 |
/**
|
34 |
* @inheritdoc
|
35 |
-
* @param
|
36 |
*
|
37 |
-
* @return
|
38 |
*/
|
39 |
protected function instantiate_self( $conditions ) {
|
40 |
return new self( $conditions );
|
1 |
<?php
|
2 |
|
3 |
/**
|
4 |
+
* Chains multiple IToolset_Query_Condition with OR.
|
5 |
*
|
6 |
* @since m2m
|
7 |
*/
|
8 |
+
class Toolset_Query_Condition_Or extends Toolset_Query_Condition_Operator {
|
9 |
|
10 |
|
11 |
/**
|
32 |
|
33 |
/**
|
34 |
* @inheritdoc
|
35 |
+
* @param IToolset_Query_Condition[] $conditions
|
36 |
*
|
37 |
+
* @return IToolset_Query_Condition
|
38 |
*/
|
39 |
protected function instantiate_self( $conditions ) {
|
40 |
return new self( $conditions );
|
vendor/toolset/toolset-common/inc/m2m/{relationship_query → query}/condition/tautology.php
RENAMED
@@ -9,8 +9,17 @@
|
|
9 |
* Remember, the first rule of the Tautology Club is the first rule of the Tautology Club!
|
10 |
*
|
11 |
* @since 2.5.6
|
|
|
12 |
*/
|
13 |
-
class
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
|
15 |
/**
|
16 |
* Get a part of the WHERE clause that applies the condition.
|
9 |
* Remember, the first rule of the Tautology Club is the first rule of the Tautology Club!
|
10 |
*
|
11 |
* @since 2.5.6
|
12 |
+
* @since 2.5.8 Adjusted for usage in Toolset_Association_Query_V2 as well.
|
13 |
*/
|
14 |
+
class Toolset_Query_Condition_Tautology
|
15 |
+
implements IToolset_Relationship_Query_Condition, IToolset_Association_Query_Condition
|
16 |
+
{
|
17 |
+
|
18 |
+
|
19 |
+
public function get_join_clause() {
|
20 |
+
return '';
|
21 |
+
}
|
22 |
+
|
23 |
|
24 |
/**
|
25 |
* Get a part of the WHERE clause that applies the condition.
|
vendor/toolset/toolset-common/inc/m2m/{query_factory.php → query/factory.php}
RENAMED
@@ -13,7 +13,7 @@ class Toolset_Relationship_Query_Factory {
|
|
13 |
* @param $args
|
14 |
*
|
15 |
* @return Toolset_Relationship_Query
|
16 |
-
* @deprecated
|
17 |
*/
|
18 |
public function relationships( $args ) {
|
19 |
return new Toolset_Relationship_Query( $args );
|
@@ -34,7 +34,7 @@ class Toolset_Relationship_Query_Factory {
|
|
34 |
* @param IToolset_Relationship_Definition $relationship
|
35 |
* @param IToolset_Relationship_Role_Parent_Child $target_role Target role of the relationships (future role of
|
36 |
* the posts that are being queried)
|
37 |
-
* @param
|
38 |
* @param Toolset_Relationship_Table_Name|null $table_names_di
|
39 |
* @param wpdb|null $wpdb_di
|
40 |
*
|
@@ -43,14 +43,14 @@ class Toolset_Relationship_Query_Factory {
|
|
43 |
public function distinct_relationship_posts(
|
44 |
IToolset_Relationship_Definition $relationship,
|
45 |
IToolset_Relationship_Role_Parent_Child $target_role,
|
46 |
-
$
|
47 |
Toolset_Relationship_Table_Name $table_names_di = null,
|
48 |
wpdb $wpdb_di = null
|
49 |
) {
|
50 |
return new Toolset_Relationship_Distinct_Post_Query(
|
51 |
$relationship,
|
52 |
$target_role,
|
53 |
-
$
|
54 |
$table_names_di,
|
55 |
$wpdb_di
|
56 |
);
|
@@ -71,9 +71,17 @@ class Toolset_Relationship_Query_Factory {
|
|
71 |
* @param $args
|
72 |
*
|
73 |
* @return Toolset_Association_Query
|
|
|
74 |
*/
|
75 |
public function associations( $args ) {
|
76 |
return new Toolset_Association_Query( $args );
|
77 |
}
|
78 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
79 |
}
|
13 |
* @param $args
|
14 |
*
|
15 |
* @return Toolset_Relationship_Query
|
16 |
+
* @deprecated Use Toolset_Relationship_Query_V2 instead.
|
17 |
*/
|
18 |
public function relationships( $args ) {
|
19 |
return new Toolset_Relationship_Query( $args );
|
34 |
* @param IToolset_Relationship_Definition $relationship
|
35 |
* @param IToolset_Relationship_Role_Parent_Child $target_role Target role of the relationships (future role of
|
36 |
* the posts that are being queried)
|
37 |
+
* @param IToolset_Element $for_element ID of the element to check against.
|
38 |
* @param Toolset_Relationship_Table_Name|null $table_names_di
|
39 |
* @param wpdb|null $wpdb_di
|
40 |
*
|
43 |
public function distinct_relationship_posts(
|
44 |
IToolset_Relationship_Definition $relationship,
|
45 |
IToolset_Relationship_Role_Parent_Child $target_role,
|
46 |
+
IToolset_Element $for_element,
|
47 |
Toolset_Relationship_Table_Name $table_names_di = null,
|
48 |
wpdb $wpdb_di = null
|
49 |
) {
|
50 |
return new Toolset_Relationship_Distinct_Post_Query(
|
51 |
$relationship,
|
52 |
$target_role,
|
53 |
+
$for_element,
|
54 |
$table_names_di,
|
55 |
$wpdb_di
|
56 |
);
|
71 |
* @param $args
|
72 |
*
|
73 |
* @return Toolset_Association_Query
|
74 |
+
* @deprecated Use associations_v2() instead.
|
75 |
*/
|
76 |
public function associations( $args ) {
|
77 |
return new Toolset_Association_Query( $args );
|
78 |
}
|
79 |
|
80 |
+
|
81 |
+
/**
|
82 |
+
* @return Toolset_Association_Query_V2
|
83 |
+
*/
|
84 |
+
public function associations_v2() {
|
85 |
+
return new Toolset_Association_Query_V2();
|
86 |
+
}
|
87 |
}
|
vendor/toolset/toolset-common/inc/m2m/query_base.php
CHANGED
@@ -6,6 +6,7 @@
|
|
6 |
* Contains shared methods, mainly related to query argument processing.
|
7 |
*
|
8 |
* @since m2m
|
|
|
9 |
*/
|
10 |
abstract class Toolset_Relationship_Query_Base {
|
11 |
|
6 |
* Contains shared methods, mainly related to query argument processing.
|
7 |
*
|
8 |
* @since m2m
|
9 |
+
* @deprecated Needed only for old association and relationship query classes. Remove when those are removed.
|
10 |
*/
|
11 |
abstract class Toolset_Relationship_Query_Base {
|
12 |
|
vendor/toolset/toolset-common/inc/m2m/{definition → relationship/definition}/definition.php
RENAMED
@@ -37,7 +37,7 @@ class Toolset_Relationship_Definition implements IToolset_Relationship_Definitio
|
|
37 |
|
38 |
/** @var string */
|
39 |
private $driver_name;
|
40 |
-
|
41 |
/** @var Toolset_Relationship_Element_Type */
|
42 |
private $parent_type;
|
43 |
|
@@ -129,11 +129,7 @@ class Toolset_Relationship_Definition implements IToolset_Relationship_Definitio
|
|
129 |
public function __construct( $definition_array, Toolset_Potential_Association_Query_Factory $potential_association_query_factory_di = null ) {
|
130 |
$this->read_definition_array( $definition_array );
|
131 |
|
132 |
-
$this->potential_association_query_factory = (
|
133 |
-
null === $potential_association_query_factory_di
|
134 |
-
? new Toolset_Potential_Association_Query_Factory()
|
135 |
-
: $potential_association_query_factory_di
|
136 |
-
);
|
137 |
}
|
138 |
|
139 |
|
@@ -145,7 +141,7 @@ class Toolset_Relationship_Definition implements IToolset_Relationship_Definitio
|
|
145 |
* @since m2m
|
146 |
*/
|
147 |
private function read_definition_array( $definition_array ) {
|
148 |
-
|
149 |
$this->slug = sanitize_title( toolset_getarr( $definition_array, self::DA_SLUG ) );
|
150 |
|
151 |
$this->row_id = (int) toolset_getarr( $definition_array, self::DA_ROW_ID );
|
@@ -166,9 +162,9 @@ class Toolset_Relationship_Definition implements IToolset_Relationship_Definitio
|
|
166 |
// All we know is that it's an array that will be passed to the driver when instantiating it.
|
167 |
// From that point it's driver's business.
|
168 |
$this->driver_setup = toolset_ensarr( toolset_getarr( $definition_array, self::DA_DRIVER_SETUP, null ) );
|
169 |
-
|
170 |
$this->parent_type = new Toolset_Relationship_Element_Type( toolset_getarr( $definition_array, self::DA_PARENT_TYPE ) );
|
171 |
-
|
172 |
$this->child_type = new Toolset_Relationship_Element_Type( toolset_getarr( $definition_array, self::DA_CHILD_TYPE ) );
|
173 |
|
174 |
// Defaults to "infinity"
|
@@ -318,7 +314,7 @@ class Toolset_Relationship_Definition implements IToolset_Relationship_Definitio
|
|
318 |
|
319 |
/**
|
320 |
* Get the parent entity type definition.
|
321 |
-
*
|
322 |
* @return Toolset_Relationship_Element_Type
|
323 |
* @since m2m
|
324 |
*/
|
@@ -327,7 +323,7 @@ class Toolset_Relationship_Definition implements IToolset_Relationship_Definitio
|
|
327 |
|
328 |
/**
|
329 |
* Get the child entity type definition.
|
330 |
-
*
|
331 |
* @return Toolset_Relationship_Element_Type
|
332 |
* @since m2m
|
333 |
*/
|
@@ -371,6 +367,10 @@ class Toolset_Relationship_Definition implements IToolset_Relationship_Definitio
|
|
371 |
return $this->get_child_type();
|
372 |
case Toolset_Relationship_Role::PARENT:
|
373 |
return $this->get_parent_type();
|
|
|
|
|
|
|
|
|
374 |
default:
|
375 |
throw new InvalidArgumentException();
|
376 |
}
|
@@ -434,12 +434,12 @@ class Toolset_Relationship_Definition implements IToolset_Relationship_Definitio
|
|
434 |
|
435 |
/**
|
436 |
* Build a definition array for persisting the definition.
|
437 |
-
*
|
438 |
-
* @return array
|
439 |
* @since m2m
|
440 |
*/
|
441 |
public function get_definition_array() {
|
442 |
-
|
443 |
return array(
|
444 |
self::DA_SLUG => $this->get_slug(),
|
445 |
self::DA_DRIVER => $this->get_driver_name(),
|
@@ -455,20 +455,20 @@ class Toolset_Relationship_Definition implements IToolset_Relationship_Definitio
|
|
455 |
self::DA_DISPLAY_NAME_SINGULAR => $this->get_display_name_singular()
|
456 |
);
|
457 |
}
|
458 |
-
|
459 |
-
|
460 |
/** @var Toolset_Relationship_Driver_Base|null */
|
461 |
private $driver = null;
|
462 |
|
463 |
|
464 |
/**
|
465 |
* Get the relationship driver. Initialize it if called for the first time.
|
466 |
-
*
|
467 |
* @return Toolset_Relationship_Driver
|
468 |
* @since m2m
|
469 |
*/
|
470 |
public function get_driver() {
|
471 |
-
|
472 |
if( null === $this->driver ) {
|
473 |
switch( $this->get_driver_name() ) {
|
474 |
case self::DRIVER_NATIVE:
|
@@ -476,7 +476,7 @@ class Toolset_Relationship_Definition implements IToolset_Relationship_Definitio
|
|
476 |
break;
|
477 |
default:
|
478 |
// fail miserably
|
479 |
-
//
|
480 |
// But really - this should never happen because we have a validation
|
481 |
// in read_definition_array().
|
482 |
throw new RuntimeException( 'Unsupported relationship driver.' );
|
@@ -494,7 +494,7 @@ class Toolset_Relationship_Definition implements IToolset_Relationship_Definitio
|
|
494 |
|
495 |
/**
|
496 |
* Update the relationship cardinality.
|
497 |
-
*
|
498 |
* @param Toolset_Relationship_Cardinality $value
|
499 |
* @throws InvalidArgumentException
|
500 |
* @since m2m
|
@@ -503,7 +503,7 @@ class Toolset_Relationship_Definition implements IToolset_Relationship_Definitio
|
|
503 |
if( ! $value instanceof Toolset_Relationship_Cardinality ) {
|
504 |
throw new InvalidArgumentException();
|
505 |
}
|
506 |
-
|
507 |
$this->cardinality = $value;
|
508 |
}
|
509 |
|
@@ -612,7 +612,7 @@ class Toolset_Relationship_Definition implements IToolset_Relationship_Definitio
|
|
612 |
* @param int|WP_Post|Toolset_Element $parent Parent element (of matching domain, type and other conditions)
|
613 |
* @param int|WP_Post|Toolset_Element $child Child element (of matching domain, type and other conditions)
|
614 |
*
|
615 |
-
* @return Toolset_Result|
|
616 |
* @throws RuntimeException when the association cannot be created because of a known reason. The exception would
|
617 |
* contain a displayable error message.
|
618 |
* @throws InvalidArgumentException when the method is used improperly.
|
@@ -633,7 +633,7 @@ class Toolset_Relationship_Definition implements IToolset_Relationship_Definitio
|
|
633 |
|
634 |
|
635 |
/**
|
636 |
-
* Determine or set whether the relationship is distinct, which means that only one association between
|
637 |
* each two elements can exist.
|
638 |
*
|
639 |
* @param null|bool $new_value If a boolean value is provided, it will be set.
|
@@ -859,4 +859,17 @@ class Toolset_Relationship_Definition implements IToolset_Relationship_Definitio
|
|
859 |
return $this->row_id;
|
860 |
}
|
861 |
|
862 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
37 |
|
38 |
/** @var string */
|
39 |
private $driver_name;
|
40 |
+
|
41 |
/** @var Toolset_Relationship_Element_Type */
|
42 |
private $parent_type;
|
43 |
|
129 |
public function __construct( $definition_array, Toolset_Potential_Association_Query_Factory $potential_association_query_factory_di = null ) {
|
130 |
$this->read_definition_array( $definition_array );
|
131 |
|
132 |
+
$this->potential_association_query_factory = ( null === $potential_association_query_factory_di ? new Toolset_Potential_Association_Query_Factory() : $potential_association_query_factory_di );
|
|
|
|
|
|
|
|
|
133 |
}
|
134 |
|
135 |
|
141 |
* @since m2m
|
142 |
*/
|
143 |
private function read_definition_array( $definition_array ) {
|
144 |
+
|
145 |
$this->slug = sanitize_title( toolset_getarr( $definition_array, self::DA_SLUG ) );
|
146 |
|
147 |
$this->row_id = (int) toolset_getarr( $definition_array, self::DA_ROW_ID );
|
162 |
// All we know is that it's an array that will be passed to the driver when instantiating it.
|
163 |
// From that point it's driver's business.
|
164 |
$this->driver_setup = toolset_ensarr( toolset_getarr( $definition_array, self::DA_DRIVER_SETUP, null ) );
|
165 |
+
|
166 |
$this->parent_type = new Toolset_Relationship_Element_Type( toolset_getarr( $definition_array, self::DA_PARENT_TYPE ) );
|
167 |
+
|
168 |
$this->child_type = new Toolset_Relationship_Element_Type( toolset_getarr( $definition_array, self::DA_CHILD_TYPE ) );
|
169 |
|
170 |
// Defaults to "infinity"
|
314 |
|
315 |
/**
|
316 |
* Get the parent entity type definition.
|
317 |
+
*
|
318 |
* @return Toolset_Relationship_Element_Type
|
319 |
* @since m2m
|
320 |
*/
|
323 |
|
324 |
/**
|
325 |
* Get the child entity type definition.
|
326 |
+
*
|
327 |
* @return Toolset_Relationship_Element_Type
|
328 |
* @since m2m
|
329 |
*/
|
367 |
return $this->get_child_type();
|
368 |
case Toolset_Relationship_Role::PARENT:
|
369 |
return $this->get_parent_type();
|
370 |
+
case Toolset_Relationship_Role::INTERMEDIARY:
|
371 |
+
return Toolset_Relationship_Element_Type::build_for_post_type(
|
372 |
+
$this->get_intermediary_post_type()
|
373 |
+
);
|
374 |
default:
|
375 |
throw new InvalidArgumentException();
|
376 |
}
|
434 |
|
435 |
/**
|
436 |
* Build a definition array for persisting the definition.
|
437 |
+
*
|
438 |
+
* @return array
|
439 |
* @since m2m
|
440 |
*/
|
441 |
public function get_definition_array() {
|
442 |
+
|
443 |
return array(
|
444 |
self::DA_SLUG => $this->get_slug(),
|
445 |
self::DA_DRIVER => $this->get_driver_name(),
|
455 |
self::DA_DISPLAY_NAME_SINGULAR => $this->get_display_name_singular()
|
456 |
);
|
457 |
}
|
458 |
+
|
459 |
+
|
460 |
/** @var Toolset_Relationship_Driver_Base|null */
|
461 |
private $driver = null;
|
462 |
|
463 |
|
464 |
/**
|
465 |
* Get the relationship driver. Initialize it if called for the first time.
|
466 |
+
*
|
467 |
* @return Toolset_Relationship_Driver
|
468 |
* @since m2m
|
469 |
*/
|
470 |
public function get_driver() {
|
471 |
+
|
472 |
if( null === $this->driver ) {
|
473 |
switch( $this->get_driver_name() ) {
|
474 |
case self::DRIVER_NATIVE:
|
476 |
break;
|
477 |
default:
|
478 |
// fail miserably
|
479 |
+
//
|
480 |
// But really - this should never happen because we have a validation
|
481 |
// in read_definition_array().
|
482 |
throw new RuntimeException( 'Unsupported relationship driver.' );
|
494 |
|
495 |
/**
|
496 |
* Update the relationship cardinality.
|
497 |
+
*
|
498 |
* @param Toolset_Relationship_Cardinality $value
|
499 |
* @throws InvalidArgumentException
|
500 |
* @since m2m
|
503 |
if( ! $value instanceof Toolset_Relationship_Cardinality ) {
|
504 |
throw new InvalidArgumentException();
|
505 |
}
|
506 |
+
|
507 |
$this->cardinality = $value;
|
508 |
}
|
509 |
|
612 |
* @param int|WP_Post|Toolset_Element $parent Parent element (of matching domain, type and other conditions)
|
613 |
* @param int|WP_Post|Toolset_Element $child Child element (of matching domain, type and other conditions)
|
614 |
*
|
615 |
+
* @return Toolset_Result|IToolset_Association The newly created association or a negative Toolset_Result when it could not have been created.
|
616 |
* @throws RuntimeException when the association cannot be created because of a known reason. The exception would
|
617 |
* contain a displayable error message.
|
618 |
* @throws InvalidArgumentException when the method is used improperly.
|
633 |
|
634 |
|
635 |
/**
|
636 |
+
* Determine or set whether the relationship is distinct, which means that only one association between
|
637 |
* each two elements can exist.
|
638 |
*
|
639 |
* @param null|bool $new_value If a boolean value is provided, it will be set.
|
859 |
return $this->row_id;
|
860 |
}
|
861 |
|
862 |
+
|
863 |
+
/**
|
864 |
+
* Return the number of existing associations belonging to the relationships
|
865 |
+
*
|
866 |
+
* @param string|IToolset_Relationship_Role $role Role.
|
867 |
+
* @return int
|
868 |
+
* @since m2m
|
869 |
+
*/
|
870 |
+
public function get_max_associations( $role ) {
|
871 |
+
$db_operations = Toolset_Relationship_Database_Operations::get_instance();
|
872 |
+
$role_name = $this->role_to_role_name( $role );
|
873 |
+
return $db_operations->count_max_associations( $this->get_row_id(), $role_name );
|
874 |
+
}
|
875 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/{definition → relationship/definition}/factory.php
RENAMED
File without changes
|
vendor/toolset/toolset-common/inc/m2m/{definition → relationship/definition}/interface.php
RENAMED
@@ -172,7 +172,7 @@ interface IToolset_Relationship_Definition {
|
|
172 |
* @param int|WP_Post|IToolset_Element $parent Parent element (of matching domain, type and other conditions)
|
173 |
* @param int|WP_Post|IToolset_Element $child Child element (of matching domain, type and other conditions)
|
174 |
*
|
175 |
-
* @return Toolset_Result|
|
176 |
* @throws RuntimeException when the association cannot be created because of a known reason. The exception would
|
177 |
* contain a displayable error message.
|
178 |
* @throws InvalidArgumentException when the method is used improperly.
|
@@ -273,8 +273,34 @@ interface IToolset_Relationship_Definition {
|
|
273 |
* Can be set by using the origin keyword or the class
|
274 |
*
|
275 |
* @param IToolset_Relationship_Origin|string $origin
|
276 |
-
*
|
277 |
* @since m2m
|
278 |
*/
|
279 |
public function set_origin( $origin );
|
280 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
172 |
* @param int|WP_Post|IToolset_Element $parent Parent element (of matching domain, type and other conditions)
|
173 |
* @param int|WP_Post|IToolset_Element $child Child element (of matching domain, type and other conditions)
|
174 |
*
|
175 |
+
* @return Toolset_Result|IToolset_Association The newly created association or a negative Toolset_Result when it could not have been created.
|
176 |
* @throws RuntimeException when the association cannot be created because of a known reason. The exception would
|
177 |
* contain a displayable error message.
|
178 |
* @throws InvalidArgumentException when the method is used improperly.
|
273 |
* Can be set by using the origin keyword or the class
|
274 |
*
|
275 |
* @param IToolset_Relationship_Origin|string $origin
|
276 |
+
* @return void
|
277 |
* @since m2m
|
278 |
*/
|
279 |
public function set_origin( $origin );
|
280 |
+
|
281 |
+
|
282 |
+
/**
|
283 |
+
* @return int
|
284 |
+
*/
|
285 |
+
public function get_row_id();
|
286 |
+
|
287 |
+
|
288 |
+
/**
|
289 |
+
* Return the number of existing associations belonging to the relationships
|
290 |
+
*
|
291 |
+
* @param string|IToolset_Relationship_Role $role Role.
|
292 |
+
* @return int
|
293 |
+
* @since m2m
|
294 |
+
*/
|
295 |
+
public function get_max_associations( $role );
|
296 |
+
|
297 |
+
|
298 |
+
/**
|
299 |
+
* Get the intermediary post type, if it exists.
|
300 |
+
*
|
301 |
+
* Note that its existence doesn't necessarily mean that there are association fields.
|
302 |
+
*
|
303 |
+
* @return null|string
|
304 |
+
*/
|
305 |
+
public function get_intermediary_post_type();
|
306 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/{definition → relationship/definition}/persistence.php
RENAMED
@@ -21,11 +21,14 @@ class Toolset_Relationship_Definition_Persistence {
|
|
21 |
/** @var Toolset_Relationship_Table_Name */
|
22 |
private $table_name;
|
23 |
|
|
|
|
|
24 |
|
25 |
public function __construct(
|
26 |
wpdb $wpdb_di = null,
|
27 |
Toolset_Relationship_Definition_Translator $definition_translator_di = null,
|
28 |
-
Toolset_Relationship_Table_Name $table_name_di = null
|
|
|
29 |
) {
|
30 |
|
31 |
if( null === $wpdb_di ) {
|
@@ -47,6 +50,12 @@ class Toolset_Relationship_Definition_Persistence {
|
|
47 |
: $table_name_di
|
48 |
);
|
49 |
|
|
|
|
|
|
|
|
|
|
|
|
|
50 |
}
|
51 |
|
52 |
|
@@ -57,6 +66,8 @@ class Toolset_Relationship_Definition_Persistence {
|
|
57 |
* @param Toolset_Relationship_Definition $relationship_definition
|
58 |
*/
|
59 |
public function persist_definition( Toolset_Relationship_Definition $relationship_definition ) {
|
|
|
|
|
60 |
$row = $this->definition_translator->to_database_row( $relationship_definition );
|
61 |
$row = $this->update_definition_type_sets( $relationship_definition, $row );
|
62 |
$this->wpdb->update(
|
@@ -77,6 +88,8 @@ class Toolset_Relationship_Definition_Persistence {
|
|
77 |
* @return null|Toolset_Relationship_Definition
|
78 |
*/
|
79 |
public function insert_definition( Toolset_Relationship_Definition $relationship_definition ) {
|
|
|
|
|
80 |
$row = $this->definition_translator->to_database_row( $relationship_definition );
|
81 |
$row = $this->update_definition_type_sets( $relationship_definition, $row );
|
82 |
|
@@ -232,4 +245,66 @@ class Toolset_Relationship_Definition_Persistence {
|
|
232 |
}
|
233 |
|
234 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
235 |
}
|
21 |
/** @var Toolset_Relationship_Table_Name */
|
22 |
private $table_name;
|
23 |
|
24 |
+
/** @var Toolset_Post_Type_Repository */
|
25 |
+
private $post_type_repository;
|
26 |
|
27 |
public function __construct(
|
28 |
wpdb $wpdb_di = null,
|
29 |
Toolset_Relationship_Definition_Translator $definition_translator_di = null,
|
30 |
+
Toolset_Relationship_Table_Name $table_name_di = null,
|
31 |
+
Toolset_Post_Type_Repository $post_type_repository = null
|
32 |
) {
|
33 |
|
34 |
if( null === $wpdb_di ) {
|
50 |
: $table_name_di
|
51 |
);
|
52 |
|
53 |
+
$this->post_type_repository = (
|
54 |
+
null === $post_type_repository
|
55 |
+
? Toolset_Post_Type_Repository::get_instance()
|
56 |
+
: $post_type_repository
|
57 |
+
);
|
58 |
+
|
59 |
}
|
60 |
|
61 |
|
66 |
* @param Toolset_Relationship_Definition $relationship_definition
|
67 |
*/
|
68 |
public function persist_definition( Toolset_Relationship_Definition $relationship_definition ) {
|
69 |
+
$this->abort_if_invalid_element_types_used( $relationship_definition );
|
70 |
+
|
71 |
$row = $this->definition_translator->to_database_row( $relationship_definition );
|
72 |
$row = $this->update_definition_type_sets( $relationship_definition, $row );
|
73 |
$this->wpdb->update(
|
88 |
* @return null|Toolset_Relationship_Definition
|
89 |
*/
|
90 |
public function insert_definition( Toolset_Relationship_Definition $relationship_definition ) {
|
91 |
+
$this->abort_if_invalid_element_types_used( $relationship_definition );
|
92 |
+
|
93 |
$row = $this->definition_translator->to_database_row( $relationship_definition );
|
94 |
$row = $this->update_definition_type_sets( $relationship_definition, $row );
|
95 |
|
245 |
}
|
246 |
|
247 |
|
248 |
+
/**
|
249 |
+
* This method proofs that the element types are valid for a new relationship. If not: FATAL ERROR is thrown.
|
250 |
+
*
|
251 |
+
* The decision to check it as late as possible is for better backwards compatiblity and possible edge cases.
|
252 |
+
* "Correctly" this check should be done on the contructor of Toolset_Relationship_Element_Type.
|
253 |
+
* BUT it's not impossible to create an invalid relationship just by using the GUI, for example:
|
254 |
+
* Activate Types, create Relationship, deactivate Types, activate WPML, select for previously used post types
|
255 |
+
* "Translatable - only show translated items", activate Types again and you would get an fatal error if this check
|
256 |
+
* would be on the constrcutor of Toolset_Relationship_Element_Type.
|
257 |
+
*
|
258 |
+
* @param Toolset_Relationship_Definition $relationship_definition
|
259 |
+
*/
|
260 |
+
private function abort_if_invalid_element_types_used( Toolset_Relationship_Definition $relationship_definition ) {
|
261 |
+
/**
|
262 |
+
* @var $element_types Toolset_Relationship_Element_Type[]
|
263 |
+
*/
|
264 |
+
$element_types = array(
|
265 |
+
$relationship_definition->get_parent_type(),
|
266 |
+
$relationship_definition->get_child_type()
|
267 |
+
);
|
268 |
+
|
269 |
+
$rfg_involved = false;
|
270 |
+
$error = false;
|
271 |
+
|
272 |
+
foreach( $element_types as $element_type ) {
|
273 |
+
switch( $element_type->get_domain() ) {
|
274 |
+
case Toolset_Element_Domain::POSTS:
|
275 |
+
foreach( $element_type->get_types() as $post_type_string ) {
|
276 |
+
$post_type = $this->post_type_repository->get( $post_type_string );
|
277 |
+
if( null === $post_type ) {
|
278 |
+
throw new RuntimeException(
|
279 |
+
'The post type "' . sanitize_text_field( $post_type_string ) . '" was not found, so it cannot be used in '
|
280 |
+
. 'a relationship, post reference field or in a repeatable field group.'
|
281 |
+
);
|
282 |
+
}
|
283 |
+
|
284 |
+
if( $post_type->is_repeating_field_group() ) {
|
285 |
+
$rfg_involved = true;
|
286 |
+
continue;
|
287 |
+
}
|
288 |
+
|
289 |
+
if( ! $rfg_involved && ! $post_type->can_be_used_in_relationship() ) {
|
290 |
+
$error =
|
291 |
+
'The post type "'.$post_type_string.'" uses the "Translatable - only show translated '
|
292 |
+
. 'items" WPML translation mode. In order to use it in a relationship, switch to '
|
293 |
+
. '"Translatable - use translation if available or fallback to default language mode".';
|
294 |
+
}
|
295 |
+
}
|
296 |
+
break;
|
297 |
+
case Toolset_Element_Domain::TERMS:
|
298 |
+
case Toolset_Element_Domain::USERS:
|
299 |
+
// no restrictions
|
300 |
+
break;
|
301 |
+
}
|
302 |
+
}
|
303 |
+
|
304 |
+
if( ! $rfg_involved && $error ) {
|
305 |
+
// We allow a relationship between RFG and wrong translation mode
|
306 |
+
// This exception should never been thrown, while using the GUI of Types to create Relationships
|
307 |
+
throw new RuntimeException( $error );
|
308 |
+
}
|
309 |
+
}
|
310 |
}
|
vendor/toolset/toolset-common/inc/m2m/{definition → relationship/definition}/repository.php
RENAMED
@@ -33,15 +33,9 @@ class Toolset_Relationship_Definition_Repository {
|
|
33 |
}
|
34 |
|
35 |
|
36 |
-
/** @var Toolset_Association_Repository|null */
|
37 |
-
private $_association_repository;
|
38 |
-
|
39 |
/** @var Toolset_Relationship_Database_Operations|null */
|
40 |
private $_database_operations;
|
41 |
|
42 |
-
/** @var Toolset_Relationship_Definition_Factory|null */
|
43 |
-
private $_definition_factory;
|
44 |
-
|
45 |
/** @var Toolset_Relationship_Definition_Persistence */
|
46 |
private $_definition_persistence;
|
47 |
|
@@ -50,15 +44,11 @@ class Toolset_Relationship_Definition_Repository {
|
|
50 |
|
51 |
|
52 |
public function __construct(
|
53 |
-
Toolset_Association_Repository $association_repository_di = null,
|
54 |
Toolset_Relationship_Database_Operations $database_operations_di = null,
|
55 |
-
Toolset_Relationship_Definition_Factory $definition_factory_di = null,
|
56 |
Toolset_Relationship_Definition_Persistence $definition_persistence_di = null,
|
57 |
Toolset_Relationship_Definition_Translator $definition_translator_di = null
|
58 |
) {
|
59 |
-
$this->_association_repository = $association_repository_di;
|
60 |
$this->_database_operations = $database_operations_di;
|
61 |
-
$this->_definition_factory = $definition_factory_di;
|
62 |
$this->_definition_persistence = $definition_persistence_di;
|
63 |
|
64 |
$this->definition_translator = (
|
@@ -139,7 +129,7 @@ class Toolset_Relationship_Definition_Repository {
|
|
139 |
// fixme: abstract this away
|
140 |
if( $do_cleanup ) {
|
141 |
// delete associations of relationship
|
142 |
-
$toolset_results[] = $this->
|
143 |
|
144 |
$intermediary_post_type = $definition->get_intermediary_post_type();
|
145 |
if( null !== $intermediary_post_type ) {
|
@@ -407,15 +397,6 @@ class Toolset_Relationship_Definition_Repository {
|
|
407 |
}
|
408 |
|
409 |
|
410 |
-
private function get_association_repository() {
|
411 |
-
if( null === $this->_association_repository ) {
|
412 |
-
$this->_association_repository = Toolset_Association_Repository::get_instance();
|
413 |
-
}
|
414 |
-
|
415 |
-
return $this->_association_repository;
|
416 |
-
}
|
417 |
-
|
418 |
-
|
419 |
private function get_database_operations() {
|
420 |
if( null === $this->_database_operations ) {
|
421 |
$this->_database_operations = new Toolset_Relationship_Database_Operations();
|
@@ -424,14 +405,6 @@ class Toolset_Relationship_Definition_Repository {
|
|
424 |
return $this->_database_operations;
|
425 |
}
|
426 |
|
427 |
-
private function get_definition_factory() {
|
428 |
-
if( null === $this->_definition_factory ) {
|
429 |
-
$this->_definition_factory = new Toolset_Relationship_Definition_Factory();
|
430 |
-
}
|
431 |
-
|
432 |
-
return $this->_definition_factory;
|
433 |
-
}
|
434 |
-
|
435 |
|
436 |
private function get_definition_persistence() {
|
437 |
if( null === $this->_definition_persistence ) {
|
33 |
}
|
34 |
|
35 |
|
|
|
|
|
|
|
36 |
/** @var Toolset_Relationship_Database_Operations|null */
|
37 |
private $_database_operations;
|
38 |
|
|
|
|
|
|
|
39 |
/** @var Toolset_Relationship_Definition_Persistence */
|
40 |
private $_definition_persistence;
|
41 |
|
44 |
|
45 |
|
46 |
public function __construct(
|
|
|
47 |
Toolset_Relationship_Database_Operations $database_operations_di = null,
|
|
|
48 |
Toolset_Relationship_Definition_Persistence $definition_persistence_di = null,
|
49 |
Toolset_Relationship_Definition_Translator $definition_translator_di = null
|
50 |
) {
|
|
|
51 |
$this->_database_operations = $database_operations_di;
|
|
|
52 |
$this->_definition_persistence = $definition_persistence_di;
|
53 |
|
54 |
$this->definition_translator = (
|
129 |
// fixme: abstract this away
|
130 |
if( $do_cleanup ) {
|
131 |
// delete associations of relationship
|
132 |
+
$toolset_results[] = $this->get_database_operations()->delete_associations_by_relationship( $definition->get_row_id() );
|
133 |
|
134 |
$intermediary_post_type = $definition->get_intermediary_post_type();
|
135 |
if( null !== $intermediary_post_type ) {
|
397 |
}
|
398 |
|
399 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
400 |
private function get_database_operations() {
|
401 |
if( null === $this->_database_operations ) {
|
402 |
$this->_database_operations = new Toolset_Relationship_Database_Operations();
|
405 |
return $this->_database_operations;
|
406 |
}
|
407 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
408 |
|
409 |
private function get_definition_persistence() {
|
410 |
if( null === $this->_definition_persistence ) {
|
vendor/toolset/toolset-common/inc/m2m/{definition → relationship/definition}/translator.php
RENAMED
@@ -97,7 +97,7 @@ class Toolset_Relationship_Definition_Translator {
|
|
97 |
Toolset_Relationship_Role::CHILD => array(
|
98 |
Toolset_Relationship_Cardinality::MAX => (int) $row->cardinality_child_max,
|
99 |
Toolset_Relationship_Cardinality::MIN => (int) $row->cardinality_child_min
|
100 |
-
)
|
101 |
),
|
102 |
Toolset_Relationship_Definition::DA_DRIVER_SETUP => array(
|
103 |
Toolset_Relationship_Driver::DA_INTERMEDIARY_POST_TYPE => $row->intermediary_type
|
97 |
Toolset_Relationship_Role::CHILD => array(
|
98 |
Toolset_Relationship_Cardinality::MAX => (int) $row->cardinality_child_max,
|
99 |
Toolset_Relationship_Cardinality::MIN => (int) $row->cardinality_child_min
|
100 |
+
),
|
101 |
),
|
102 |
Toolset_Relationship_Definition::DA_DRIVER_SETUP => array(
|
103 |
Toolset_Relationship_Driver::DA_INTERMEDIARY_POST_TYPE => $row->intermediary_type
|
vendor/toolset/toolset-common/inc/m2m/{relationship_query → relationship/query}/cardinality_match/conjunction.php
RENAMED
File without changes
|
vendor/toolset/toolset-common/inc/m2m/{relationship_query → relationship/query}/cardinality_match/factory.php
RENAMED
File without changes
|
vendor/toolset/toolset-common/inc/m2m/{relationship_query → relationship/query}/cardinality_match/interface.php
RENAMED
File without changes
|
vendor/toolset/toolset-common/inc/m2m/{relationship_query → relationship/query}/cardinality_match/operators.php
RENAMED
File without changes
|
vendor/toolset/toolset-common/inc/m2m/{relationship_query → relationship/query}/cardinality_match/single.php
RENAMED
File without changes
|
vendor/toolset/toolset-common/inc/m2m/{relationship_query → relationship/query}/condition/abstract.php
RENAMED
File without changes
|
vendor/toolset/toolset-common/inc/m2m/{relationship_query → relationship/query}/condition/has_active_types.php
RENAMED
File without changes
|
vendor/toolset/toolset-common/inc/m2m/{relationship_query → relationship/query}/condition/has_cardinality.php
RENAMED
File without changes
|
vendor/toolset/toolset-common/inc/m2m/{relationship_query → relationship/query}/condition/has_domain.php
RENAMED
@@ -26,13 +26,14 @@ class Toolset_Relationship_Query_Condition_Has_Domain extends Toolset_Relationsh
|
|
26 |
* @param string $domain_name One of the Toolset_Field_Utils::DOMAIN_* values.
|
27 |
* @param IToolset_Relationship_Role_Parent_Child $role
|
28 |
* @param Toolset_Relationship_Database_Operations|null $database_operations_di
|
|
|
29 |
*/
|
30 |
public function __construct(
|
31 |
$domain_name, IToolset_Relationship_Role_Parent_Child $role,
|
32 |
Toolset_Relationship_Database_Operations $database_operations_di = null
|
33 |
) {
|
34 |
if( ! is_string( $domain_name ) || ! in_array( $domain_name, Toolset_Element_Domain::all() ) ) {
|
35 |
-
throw new InvalidArgumentException();
|
36 |
}
|
37 |
|
38 |
$this->domain_name = $domain_name;
|
26 |
* @param string $domain_name One of the Toolset_Field_Utils::DOMAIN_* values.
|
27 |
* @param IToolset_Relationship_Role_Parent_Child $role
|
28 |
* @param Toolset_Relationship_Database_Operations|null $database_operations_di
|
29 |
+
* @throws InvalidArgumentException
|
30 |
*/
|
31 |
public function __construct(
|
32 |
$domain_name, IToolset_Relationship_Role_Parent_Child $role,
|
33 |
Toolset_Relationship_Database_Operations $database_operations_di = null
|
34 |
) {
|
35 |
if( ! is_string( $domain_name ) || ! in_array( $domain_name, Toolset_Element_Domain::all() ) ) {
|
36 |
+
throw new InvalidArgumentException( 'Invalid element domain provided: ' . sanitize_title( $domain_name ) );
|
37 |
}
|
38 |
|
39 |
$this->domain_name = $domain_name;
|
vendor/toolset/toolset-common/inc/m2m/relationship/query/condition/interface.php
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Represents a single condition for the Tooset_Relationship_Query_V2.
|
5 |
+
*
|
6 |
+
* @since m2m
|
7 |
+
*/
|
8 |
+
interface IToolset_Relationship_Query_Condition extends IToolset_Query_Condition {
|
9 |
+
|
10 |
+
}
|
vendor/toolset/toolset-common/inc/m2m/{relationship_query → relationship/query}/condition/is_active.php
RENAMED
File without changes
|
vendor/toolset/toolset-common/inc/m2m/{relationship_query → relationship/query}/condition/is_boolean_flag.php
RENAMED
File without changes
|
vendor/toolset/toolset-common/inc/m2m/{relationship_query → relationship/query}/condition/is_legacy.php
RENAMED
File without changes
|
vendor/toolset/toolset-common/inc/m2m/{relationship_query → relationship/query}/condition/origin.php
RENAMED
File without changes
|
vendor/toolset/toolset-common/inc/m2m/{relationship_query → relationship/query}/condition/type.php
RENAMED
@@ -24,7 +24,7 @@ class Toolset_Relationship_Query_Condition_Type extends Toolset_Relationship_Que
|
|
24 |
public function __construct(
|
25 |
$type, IToolset_Relationship_Role_Parent_Child $role
|
26 |
) {
|
27 |
-
if( ! is_string( $type ) || empty( $type ) || sanitize_text_field( $type )
|
28 |
throw new InvalidArgumentException();
|
29 |
}
|
30 |
|
24 |
public function __construct(
|
25 |
$type, IToolset_Relationship_Role_Parent_Child $role
|
26 |
) {
|
27 |
+
if( ( ! is_string( $type ) && ! is_int( $type ) ) || empty( $type ) || sanitize_text_field( $type ) != $type ) {
|
28 |
throw new InvalidArgumentException();
|
29 |
}
|
30 |
|
vendor/toolset/toolset-common/inc/m2m/{relationship_query → relationship/query}/condition_factory.php
RENAMED
@@ -16,7 +16,7 @@ class Toolset_Relationship_Query_Condition_Factory {
|
|
16 |
* @return IToolset_Relationship_Query_Condition
|
17 |
*/
|
18 |
public function do_or( $operands ) {
|
19 |
-
return new
|
20 |
}
|
21 |
|
22 |
|
@@ -29,7 +29,7 @@ class Toolset_Relationship_Query_Condition_Factory {
|
|
29 |
* @return IToolset_Relationship_Query_Condition
|
30 |
*/
|
31 |
public function do_and( $operands ) {
|
32 |
-
return new
|
33 |
}
|
34 |
|
35 |
|
@@ -101,7 +101,7 @@ class Toolset_Relationship_Query_Condition_Factory {
|
|
101 |
* @param bool $has_active_post_types
|
102 |
* @param IToolset_Relationship_Role_Parent_Child $in_role
|
103 |
*
|
104 |
-
* @return IToolset_Relationship_Query_Condition
|
105 |
*/
|
106 |
public function has_active_post_types( $has_active_post_types, IToolset_Relationship_Role_Parent_Child $in_role ) {
|
107 |
return new Toolset_Relationship_Query_Condition_Has_Active_Types( $has_active_post_types, $in_role );
|
@@ -113,7 +113,7 @@ class Toolset_Relationship_Query_Condition_Factory {
|
|
113 |
*
|
114 |
* @param IToolset_Relationship_Query_Cardinality_Match $cardinality_match
|
115 |
*
|
116 |
-
* @return
|
117 |
*/
|
118 |
public function has_cardinality( IToolset_Relationship_Query_Cardinality_Match $cardinality_match ) {
|
119 |
return new Toolset_Relationship_Query_Condition_Has_Cardinality( $cardinality_match );
|
@@ -124,10 +124,10 @@ class Toolset_Relationship_Query_Condition_Factory {
|
|
124 |
* A condition that is always true.
|
125 |
*
|
126 |
* @since 2.5.6
|
127 |
-
* @return
|
128 |
*/
|
129 |
public function tautology() {
|
130 |
-
return new
|
131 |
}
|
132 |
|
133 |
|
16 |
* @return IToolset_Relationship_Query_Condition
|
17 |
*/
|
18 |
public function do_or( $operands ) {
|
19 |
+
return new Toolset_Query_Condition_Or( $operands );
|
20 |
}
|
21 |
|
22 |
|
29 |
* @return IToolset_Relationship_Query_Condition
|
30 |
*/
|
31 |
public function do_and( $operands ) {
|
32 |
+
return new Toolset_Query_Condition_And( $operands );
|
33 |
}
|
34 |
|
35 |
|
101 |
* @param bool $has_active_post_types
|
102 |
* @param IToolset_Relationship_Role_Parent_Child $in_role
|
103 |
*
|
104 |
+
* @return IToolset_Relationship_Query_Condition
|
105 |
*/
|
106 |
public function has_active_post_types( $has_active_post_types, IToolset_Relationship_Role_Parent_Child $in_role ) {
|
107 |
return new Toolset_Relationship_Query_Condition_Has_Active_Types( $has_active_post_types, $in_role );
|
113 |
*
|
114 |
* @param IToolset_Relationship_Query_Cardinality_Match $cardinality_match
|
115 |
*
|
116 |
+
* @return IToolset_Relationship_Query_Condition
|
117 |
*/
|
118 |
public function has_cardinality( IToolset_Relationship_Query_Cardinality_Match $cardinality_match ) {
|
119 |
return new Toolset_Relationship_Query_Condition_Has_Cardinality( $cardinality_match );
|
124 |
* A condition that is always true.
|
125 |
*
|
126 |
* @since 2.5.6
|
127 |
+
* @return IToolset_Relationship_Query_Condition
|
128 |
*/
|
129 |
public function tautology() {
|
130 |
+
return new Toolset_Query_Condition_Tautology();
|
131 |
}
|
132 |
|
133 |
|
vendor/toolset/toolset-common/inc/m2m/{relationship_query → relationship/query}/relationship_query.php
RENAMED
File without changes
|
vendor/toolset/toolset-common/inc/m2m/{relationship_query → relationship/query}/relationship_query_v2.php
RENAMED
@@ -74,6 +74,25 @@ class Toolset_Relationship_Query_V2 implements IToolset_Query {
|
|
74 |
private $_cardinality_match_factory;
|
75 |
|
76 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
77 |
/**
|
78 |
* Toolset_Relationship_Query_V2 constructor.
|
79 |
*
|
@@ -168,6 +187,11 @@ class Toolset_Relationship_Query_V2 implements IToolset_Query {
|
|
168 |
*/
|
169 |
private function build_root_condition() {
|
170 |
$this->add_default_conditions();
|
|
|
|
|
|
|
|
|
|
|
171 |
return $this->condition_factory->do_and( $this->conditions );
|
172 |
}
|
173 |
|
@@ -190,9 +214,23 @@ class Toolset_Relationship_Query_V2 implements IToolset_Query {
|
|
190 |
*/
|
191 |
public function get_results() {
|
192 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
193 |
$query = $this->build_sql_query();
|
194 |
$rows = toolset_ensarr( $this->wpdb->get_results( $query ) );
|
195 |
|
|
|
|
|
|
|
|
|
196 |
$results = array();
|
197 |
foreach( $rows as $row ) {
|
198 |
$definition = $this->definition_translator->from_database_row( $row );
|
@@ -213,7 +251,7 @@ class Toolset_Relationship_Query_V2 implements IToolset_Query {
|
|
213 |
*/
|
214 |
private function build_sql_query() {
|
215 |
$root_condition = $this->build_root_condition();
|
216 |
-
return $this->expression_builder->build( $root_condition );
|
217 |
}
|
218 |
|
219 |
|
@@ -231,7 +269,7 @@ class Toolset_Relationship_Query_V2 implements IToolset_Query {
|
|
231 |
|
232 |
|
233 |
/**
|
234 |
-
* Chain multiple conditions with
|
235 |
*
|
236 |
* The whole statement will evaluate to true if all provided conditions are true.
|
237 |
*
|
@@ -424,4 +462,41 @@ class Toolset_Relationship_Query_V2 implements IToolset_Query {
|
|
424 |
}
|
425 |
}
|
426 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
427 |
}
|
74 |
private $_cardinality_match_factory;
|
75 |
|
76 |
|
77 |
+
/** @var bool Remember whether get_results() was called. */
|
78 |
+
private $was_used = false;
|
79 |
+
|
80 |
+
|
81 |
+
/**
|
82 |
+
* @var bool Determines whether the SQL query should also calculate found rows.
|
83 |
+
* @since 2.5.8
|
84 |
+
*/
|
85 |
+
private $need_found_rows = false;
|
86 |
+
|
87 |
+
|
88 |
+
/**
|
89 |
+
* @var int|null Number of total found rows that will be set in get_results() if there was a request
|
90 |
+
* to calculate these, null otherwise.
|
91 |
+
* @since 2.5.8
|
92 |
+
*/
|
93 |
+
private $found_rows;
|
94 |
+
|
95 |
+
|
96 |
/**
|
97 |
* Toolset_Relationship_Query_V2 constructor.
|
98 |
*
|
187 |
*/
|
188 |
private function build_root_condition() {
|
189 |
$this->add_default_conditions();
|
190 |
+
|
191 |
+
if( empty( $this->conditions ) ) {
|
192 |
+
return $this->condition_factory->tautology();
|
193 |
+
}
|
194 |
+
|
195 |
return $this->condition_factory->do_and( $this->conditions );
|
196 |
}
|
197 |
|
214 |
*/
|
215 |
public function get_results() {
|
216 |
|
217 |
+
if( $this->was_used ) {
|
218 |
+
_doing_it_wrong(
|
219 |
+
__FUNCTION__,
|
220 |
+
'The relationship query object should not be reused. Create a new instance if you need to run another query.',
|
221 |
+
TOOLSET_COMMON_VERSION
|
222 |
+
);
|
223 |
+
}
|
224 |
+
|
225 |
+
$this->was_used = true;
|
226 |
+
|
227 |
$query = $this->build_sql_query();
|
228 |
$rows = toolset_ensarr( $this->wpdb->get_results( $query ) );
|
229 |
|
230 |
+
if( $this->need_found_rows ) {
|
231 |
+
$this->found_rows = (int) $this->wpdb->get_var( 'SELECT FOUND_ROWS()' );
|
232 |
+
}
|
233 |
+
|
234 |
$results = array();
|
235 |
foreach( $rows as $row ) {
|
236 |
$definition = $this->definition_translator->from_database_row( $row );
|
251 |
*/
|
252 |
private function build_sql_query() {
|
253 |
$root_condition = $this->build_root_condition();
|
254 |
+
return $this->expression_builder->build( $root_condition, $this->need_found_rows );
|
255 |
}
|
256 |
|
257 |
|
269 |
|
270 |
|
271 |
/**
|
272 |
+
* Chain multiple conditions with AND.
|
273 |
*
|
274 |
* The whole statement will evaluate to true if all provided conditions are true.
|
275 |
*
|
462 |
}
|
463 |
}
|
464 |
|
465 |
+
|
466 |
+
/**
|
467 |
+
* Indicate that the query should also determine the total number of found rows.
|
468 |
+
*
|
469 |
+
* This has to be set to true if you plan using get_found_rows().
|
470 |
+
*
|
471 |
+
* @param bool $is_needed
|
472 |
+
*
|
473 |
+
* @since 2.5.8
|
474 |
+
* @return Toolset_Relationship_Query_V2
|
475 |
+
*/
|
476 |
+
public function need_found_rows( $is_needed = true ) {
|
477 |
+
$this->need_found_rows = (bool) $is_needed;
|
478 |
+
return $this;
|
479 |
+
}
|
480 |
+
|
481 |
+
|
482 |
+
/**
|
483 |
+
* Return a number of found rows.
|
484 |
+
*
|
485 |
+
* This can be called only after get_results() if need_found_rows() was set to true
|
486 |
+
* while building the query. Otherwise, an exception will be thrown.
|
487 |
+
*
|
488 |
+
* @return int
|
489 |
+
* @throws RuntimeException
|
490 |
+
* @since 2.5.8
|
491 |
+
*/
|
492 |
+
public function get_found_rows() {
|
493 |
+
if( null === $this->found_rows ) {
|
494 |
+
throw new RuntimeException(
|
495 |
+
'Cannot return the number of found rows because the query was not instructed to obtain them.'
|
496 |
+
);
|
497 |
+
}
|
498 |
+
|
499 |
+
return (int) $this->found_rows;
|
500 |
+
}
|
501 |
+
|
502 |
}
|
vendor/toolset/toolset-common/inc/m2m/{relationship_query → relationship/query}/sql_expression_builder.php
RENAMED
@@ -27,12 +27,7 @@ class Toolset_Relationship_Query_Sql_Expression_Builder {
|
|
27 |
Toolset_Relationship_Database_Operations $database_operations_di = null
|
28 |
) {
|
29 |
$this->table_name = ( null === $table_name_di ? new Toolset_Relationship_Table_Name() : $table_name_di );
|
30 |
-
|
31 |
-
$this->database_operations = (
|
32 |
-
null === $database_operations_di
|
33 |
-
? new Toolset_Relationship_Database_Operations()
|
34 |
-
: $database_operations_di
|
35 |
-
);
|
36 |
}
|
37 |
|
38 |
|
@@ -42,10 +37,11 @@ class Toolset_Relationship_Query_Sql_Expression_Builder {
|
|
42 |
* Also make sure that the query results will be easily recognizable by Toolset_Relationship_Definition_Translator.
|
43 |
*
|
44 |
* @param IToolset_Relationship_Query_Condition $root_condition
|
45 |
-
*
|
46 |
* @return string
|
|
|
47 |
*/
|
48 |
-
public function build( IToolset_Relationship_Query_Condition $root_condition ) {
|
49 |
|
50 |
$relationship_table = $this->table_name->relationship_table();
|
51 |
$type_set_table = $this->table_name->type_set_table();
|
@@ -59,8 +55,10 @@ class Toolset_Relationship_Query_Sql_Expression_Builder {
|
|
59 |
$root_condition->get_join_clause()
|
60 |
) );
|
61 |
$group_by_clause = $this->database_operations->get_standards_relationship_group_by_clause();
|
|
|
62 |
|
63 |
-
return "SELECT {$
|
|
|
64 |
WHERE {$where_clause} GROUP BY {$group_by_clause}";
|
65 |
|
66 |
}
|
27 |
Toolset_Relationship_Database_Operations $database_operations_di = null
|
28 |
) {
|
29 |
$this->table_name = ( null === $table_name_di ? new Toolset_Relationship_Table_Name() : $table_name_di );
|
30 |
+
$this->database_operations = ( null === $database_operations_di ? new Toolset_Relationship_Database_Operations() : $database_operations_di );
|
|
|
|
|
|
|
|
|
|
|
31 |
}
|
32 |
|
33 |
|
37 |
* Also make sure that the query results will be easily recognizable by Toolset_Relationship_Definition_Translator.
|
38 |
*
|
39 |
* @param IToolset_Relationship_Query_Condition $root_condition
|
40 |
+
* @param bool $need_found_rows
|
41 |
* @return string
|
42 |
+
* @since 2.5.8 Can calculate found rows.
|
43 |
*/
|
44 |
+
public function build( IToolset_Relationship_Query_Condition $root_condition, $need_found_rows ) {
|
45 |
|
46 |
$relationship_table = $this->table_name->relationship_table();
|
47 |
$type_set_table = $this->table_name->type_set_table();
|
55 |
$root_condition->get_join_clause()
|
56 |
) );
|
57 |
$group_by_clause = $this->database_operations->get_standards_relationship_group_by_clause();
|
58 |
+
$sql_found_rows = ( $need_found_rows ? 'SQL_CALC_FOUND_ROWS' : '' );
|
59 |
|
60 |
+
return "SELECT {$sql_found_rows} {$select_clause}
|
61 |
+
FROM {$relationship_table} AS relationships {$join_clause}
|
62 |
WHERE {$where_clause} GROUP BY {$group_by_clause}";
|
63 |
|
64 |
}
|
vendor/toolset/toolset-common/inc/m2m/{relationship_role → relationship/role}/abstract.php
RENAMED
File without changes
|
vendor/toolset/toolset-common/inc/m2m/{relationship_role → relationship/role}/child.php
RENAMED
File without changes
|
vendor/toolset/toolset-common/inc/m2m/{relationship_role → relationship/role}/interface.php
RENAMED
File without changes
|
vendor/toolset/toolset-common/inc/m2m/{relationship_role → relationship/role}/intermediary.php
RENAMED
File without changes
|
vendor/toolset/toolset-common/inc/m2m/{relationship_role → relationship/role}/parent.php
RENAMED
File without changes
|
vendor/toolset/toolset-common/inc/m2m/{relationship_role → relationship/role}/parent_child_interface.php
RENAMED
File without changes
|
vendor/toolset/toolset-common/inc/m2m/{relationship_role → relationship/role}/role.php
RENAMED
@@ -68,6 +68,7 @@ abstract class Toolset_Relationship_Role {
|
|
68 |
return in_array( $role_name, self::all_role_names() );
|
69 |
}
|
70 |
|
|
|
71 |
/**
|
72 |
* Throw an exception if a given role name isn't valid.
|
73 |
*
|
@@ -137,4 +138,67 @@ abstract class Toolset_Relationship_Role {
|
|
137 |
}
|
138 |
|
139 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
140 |
}
|
68 |
return in_array( $role_name, self::all_role_names() );
|
69 |
}
|
70 |
|
71 |
+
|
72 |
/**
|
73 |
* Throw an exception if a given role name isn't valid.
|
74 |
*
|
138 |
}
|
139 |
|
140 |
|
141 |
+
/**
|
142 |
+
* @param string $role_name
|
143 |
+
*
|
144 |
+
* @return IToolset_Relationship_Role
|
145 |
+
*/
|
146 |
+
public static function role_from_name( $role_name ) {
|
147 |
+
if( $role_name instanceof IToolset_Relationship_Role ) {
|
148 |
+
return $role_name;
|
149 |
+
}
|
150 |
+
|
151 |
+
switch( $role_name ) {
|
152 |
+
case self::PARENT:
|
153 |
+
return new Toolset_Relationship_Role_Parent();
|
154 |
+
case self::CHILD:
|
155 |
+
return new Toolset_Relationship_Role_Child();
|
156 |
+
case self::INTERMEDIARY:
|
157 |
+
return new Toolset_Relationship_Role_Intermediary();
|
158 |
+
default:
|
159 |
+
throw new InvalidArgumentException( 'Invalid element role name.' );
|
160 |
+
}
|
161 |
+
}
|
162 |
+
|
163 |
+
|
164 |
+
/**
|
165 |
+
* @param string $role_name
|
166 |
+
*
|
167 |
+
* @return IToolset_Relationship_Role_Parent_Child
|
168 |
+
* @since 2.5.10
|
169 |
+
*/
|
170 |
+
public static function parent_or_child_from_name( $role_name ) {
|
171 |
+
$role = self::role_from_name( $role_name );
|
172 |
+
|
173 |
+
if( $role instanceof Toolset_Relationship_Role_Intermediary ) {
|
174 |
+
throw new InvalidArgumentException( 'Invalid element role name.' );
|
175 |
+
}
|
176 |
+
|
177 |
+
/** @noinspection PhpIncompatibleReturnTypeInspection */
|
178 |
+
return $role;
|
179 |
+
}
|
180 |
+
|
181 |
+
|
182 |
+
/**
|
183 |
+
* @param string|IToolset_Relationship_Role $role_or_name
|
184 |
+
*
|
185 |
+
* @return string
|
186 |
+
*/
|
187 |
+
public static function name_from_role( $role_or_name ) {
|
188 |
+
if( is_string( $role_or_name ) ) {
|
189 |
+
if( ! in_array( $role_or_name, self::all_role_names(), true ) ) {
|
190 |
+
throw new InvalidArgumentException( 'Invalid element role name.' );
|
191 |
+
}
|
192 |
+
|
193 |
+
return $role_or_name;
|
194 |
+
}
|
195 |
+
|
196 |
+
if( ! $role_or_name instanceof IToolset_Relationship_Role ) {
|
197 |
+
throw new InvalidArgumentException();
|
198 |
+
}
|
199 |
+
|
200 |
+
return $role_or_name->get_name();
|
201 |
+
}
|
202 |
+
|
203 |
+
|
204 |
}
|
vendor/toolset/toolset-common/inc/m2m/{scope.php → relationship/scope.php}
RENAMED
File without changes
|
vendor/toolset/toolset-common/inc/m2m/{slug_validator.php → relationship/slug_validator.php}
RENAMED
File without changes
|
vendor/toolset/toolset-common/inc/m2m/utils.php
CHANGED
@@ -28,4 +28,30 @@ class Toolset_Relationship_Utils {
|
|
28 |
return null;
|
29 |
}
|
30 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
31 |
}
|
28 |
return null;
|
29 |
}
|
30 |
|
31 |
+
/**
|
32 |
+
* This method returns all relationships, which includes at least one translated post type
|
33 |
+
*
|
34 |
+
* @param Toolset_Relationship_Definition_Repository|null $relationship_definition_repository
|
35 |
+
*
|
36 |
+
* @return IToolset_Relationship_Definition[]
|
37 |
+
*/
|
38 |
+
public static function get_all_translated_relationships( Toolset_Relationship_Definition_Repository $relationship_definition_repository = null ) {
|
39 |
+
$relationships = $relationship_definition_repository
|
40 |
+
? $relationship_definition_repository->get_definitions()
|
41 |
+
: Toolset_Relationship_Definition_Repository::get_instance()->get_definitions();
|
42 |
+
|
43 |
+
// collect all relationships which include at least one translatable element
|
44 |
+
$relationships_with_translatable_type = array();
|
45 |
+
|
46 |
+
foreach( $relationships as $relationship ) {
|
47 |
+
if( $relationship->get_parent_type()->is_translatable()
|
48 |
+
|| $relationship->get_child_type()->is_translatable() ) {
|
49 |
+
// parent and/or child type is translatable
|
50 |
+
$relationships_with_translatable_type[] = $relationship;
|
51 |
+
}
|
52 |
+
}
|
53 |
+
|
54 |
+
// return collections
|
55 |
+
return $relationships_with_translatable_type;
|
56 |
+
}
|
57 |
}
|
vendor/toolset/toolset-common/inc/m2m/wpml_interoperability.php
DELETED
@@ -1,645 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Keeps the associations table up-to-date with post translations.
|
5 |
-
*
|
6 |
-
* Encapsulates everything that makes changes in the aforementioned table.
|
7 |
-
*
|
8 |
-
* Note that the implementation is quite performance-heavy because the of the extreme importancy of its stability.
|
9 |
-
* It is open for improvements in the future.
|
10 |
-
*
|
11 |
-
* fixme this needs complete review
|
12 |
-
*
|
13 |
-
* @since m2m
|
14 |
-
*/
|
15 |
-
class Toolset_Relationship_WPML_Interoperability {
|
16 |
-
|
17 |
-
private static $instance;
|
18 |
-
|
19 |
-
public static function get_instance() {
|
20 |
-
|
21 |
-
if ( null == self::$instance ) {
|
22 |
-
self::$instance = new self();
|
23 |
-
}
|
24 |
-
|
25 |
-
return self::$instance;
|
26 |
-
}
|
27 |
-
|
28 |
-
|
29 |
-
private function __construct() {
|
30 |
-
}
|
31 |
-
|
32 |
-
private function __clone() {
|
33 |
-
}
|
34 |
-
|
35 |
-
|
36 |
-
const IS_INTEROP_UP_TO_DATE_OPTION = 'toolset_m2m_is_wpml_interop_up_to_date';
|
37 |
-
|
38 |
-
|
39 |
-
/**
|
40 |
-
* Check for the active WPML interoperability support.
|
41 |
-
*
|
42 |
-
* That means, as this returns true, we're going to try to support association translations.
|
43 |
-
*
|
44 |
-
* @return bool
|
45 |
-
*/
|
46 |
-
public function is_interop_active() {
|
47 |
-
|
48 |
-
// todo check WPML plugin versions
|
49 |
-
|
50 |
-
//$is_wpml_active = Toolset_Wpml_Utils::is_wpml_active();
|
51 |
-
|
52 |
-
/**
|
53 |
-
* toolset_is_m2m_wpml_interop_active
|
54 |
-
*
|
55 |
-
* Allows to disable m2m-WPML interoperability (updates of the translation table).
|
56 |
-
*
|
57 |
-
* @since m2m
|
58 |
-
*/
|
59 |
-
return (bool) apply_filters( 'toolset_is_m2m_wpml_interop_active', false );
|
60 |
-
}
|
61 |
-
|
62 |
-
|
63 |
-
/**
|
64 |
-
* Determine whether a full translation view refresh is needed.
|
65 |
-
*
|
66 |
-
* If needed, it updates the underlying WordPress option to properly handle WPML deactivation and re-activation.
|
67 |
-
*
|
68 |
-
* @param null|bool $new_value If a boolean value is provided, it will be used to overwrite the current state.
|
69 |
-
*
|
70 |
-
* @return bool
|
71 |
-
* @since 2.3
|
72 |
-
*/
|
73 |
-
public function is_full_refresh_needed( $new_value = null ) {
|
74 |
-
|
75 |
-
if ( null === $new_value ) {
|
76 |
-
$is_up_to_date = get_option( self::IS_INTEROP_UP_TO_DATE_OPTION, 'no' );
|
77 |
-
$is_up_to_date = ( 'yes' == $is_up_to_date );
|
78 |
-
|
79 |
-
$is_interop_active = $this->is_interop_active();
|
80 |
-
|
81 |
-
if ( $is_up_to_date && ! $is_interop_active ) {
|
82 |
-
// We still think that we're up-to-date with WPML but it has been deactivated
|
83 |
-
// in the meantime.
|
84 |
-
//
|
85 |
-
// When (or if) it is re-activated, we are going to require full refresh.
|
86 |
-
update_option( self::IS_INTEROP_UP_TO_DATE_OPTION, 'no', true );
|
87 |
-
}
|
88 |
-
|
89 |
-
return ( $is_up_to_date && $is_interop_active );
|
90 |
-
} else {
|
91 |
-
update_option( self::IS_INTEROP_UP_TO_DATE_OPTION, ( $new_value ? 'no' : 'yes' ), true );
|
92 |
-
|
93 |
-
return (bool) $new_value;
|
94 |
-
}
|
95 |
-
}
|
96 |
-
|
97 |
-
|
98 |
-
/**
|
99 |
-
* An event that should be triggered whenever an association is inserted in the database.
|
100 |
-
*
|
101 |
-
* @param Toolset_Association $association
|
102 |
-
*
|
103 |
-
* @return Toolset_Result
|
104 |
-
*/
|
105 |
-
public function after_association_insert( $association ) {
|
106 |
-
|
107 |
-
if ( ! $association instanceof Toolset_Association ) {
|
108 |
-
// Nothing to do here
|
109 |
-
return new Toolset_Result( true );
|
110 |
-
}
|
111 |
-
|
112 |
-
if ( ! $this->is_interop_active() ) {
|
113 |
-
return new Toolset_Result( true );
|
114 |
-
}
|
115 |
-
|
116 |
-
$result = $this->refresh_view_for_single_association(
|
117 |
-
$association->get_id(),
|
118 |
-
$association->get_definition(),
|
119 |
-
$association->get_element( Toolset_Relationship_Role::PARENT )->get_id(),
|
120 |
-
$association->get_element( Toolset_Relationship_Role::CHILD )->get_id(),
|
121 |
-
$association->get_intermediary_id()
|
122 |
-
);
|
123 |
-
|
124 |
-
return $result->aggregate();
|
125 |
-
|
126 |
-
}
|
127 |
-
|
128 |
-
|
129 |
-
/**
|
130 |
-
* An event that should be triggered before an association is deleted from the database.
|
131 |
-
*
|
132 |
-
* @param Toolset_Association $association
|
133 |
-
*
|
134 |
-
* @return Toolset_Result
|
135 |
-
*/
|
136 |
-
public function before_association_delete( $association ) {
|
137 |
-
|
138 |
-
if ( ! $association instanceof Toolset_Association ) {
|
139 |
-
// Nothing to do here
|
140 |
-
return new Toolset_Result( true );
|
141 |
-
}
|
142 |
-
|
143 |
-
if ( ! $this->is_interop_active() ) {
|
144 |
-
return new Toolset_Result( true );
|
145 |
-
}
|
146 |
-
|
147 |
-
|
148 |
-
return $this->delete_translation_views_for_single_association( $association->get_id() );
|
149 |
-
|
150 |
-
}
|
151 |
-
|
152 |
-
|
153 |
-
/**
|
154 |
-
* An event that should be triggered when an association is updated in the database (meaning the
|
155 |
-
* record in the associations table).
|
156 |
-
*
|
157 |
-
* @param Toolset_Association $association
|
158 |
-
*
|
159 |
-
* @return Toolset_Result
|
160 |
-
*/
|
161 |
-
public function after_association_update( $association ) {
|
162 |
-
|
163 |
-
if ( ! $association instanceof Toolset_Association ) {
|
164 |
-
// Nothing to do here
|
165 |
-
return new Toolset_Result( true );
|
166 |
-
}
|
167 |
-
|
168 |
-
if ( ! $this->is_interop_active() ) {
|
169 |
-
return new Toolset_Result( true );
|
170 |
-
}
|
171 |
-
|
172 |
-
$results = new Toolset_Result_Set();
|
173 |
-
|
174 |
-
// Here we simply reset everything related to an association and then generate it again.
|
175 |
-
// It could be probably optimized in the future.
|
176 |
-
$results->add(
|
177 |
-
$this->before_association_delete( $association )
|
178 |
-
);
|
179 |
-
|
180 |
-
$results->add(
|
181 |
-
$this->after_association_insert( $association )
|
182 |
-
);
|
183 |
-
|
184 |
-
return $results->aggregate();
|
185 |
-
}
|
186 |
-
|
187 |
-
|
188 |
-
/**
|
189 |
-
* Deletes all translation views related to a single association.
|
190 |
-
*
|
191 |
-
* For handling multiple associations at once, delete_translation_views_for_associations() is preferred.
|
192 |
-
*
|
193 |
-
* @param int $association_id
|
194 |
-
*
|
195 |
-
* @return Toolset_Result
|
196 |
-
* @since m2m
|
197 |
-
*/
|
198 |
-
private function delete_translation_views_for_single_association( $association_id ) {
|
199 |
-
|
200 |
-
global $wpdb;
|
201 |
-
|
202 |
-
$result = $wpdb->delete(
|
203 |
-
Toolset_Relationship_Table_Name::association_translations(),
|
204 |
-
array( 'association_id' => $association_id ),
|
205 |
-
array( '%d ' )
|
206 |
-
);
|
207 |
-
|
208 |
-
return new Toolset_Result( $result !== false );
|
209 |
-
}
|
210 |
-
|
211 |
-
|
212 |
-
/**
|
213 |
-
* Delete view rows for specific associations.
|
214 |
-
*
|
215 |
-
* @param int[] $association_ids
|
216 |
-
*
|
217 |
-
* @since m2m
|
218 |
-
*/
|
219 |
-
private function delete_translation_views_for_associations( $association_ids ) {
|
220 |
-
global $wpdb;
|
221 |
-
|
222 |
-
$view_tn = Toolset_Relationship_Table_Name::association_translations();
|
223 |
-
$query = "DELETE FROM `{$view_tn}`
|
224 |
-
WHERE association_id IN ( " . Toolset_Utils::prepare_mysql_in( $association_ids, '%d' ) . " )";
|
225 |
-
|
226 |
-
$wpdb->query( $query );
|
227 |
-
}
|
228 |
-
|
229 |
-
|
230 |
-
/**
|
231 |
-
* Refresh the association translation MV for a given association between original posts.
|
232 |
-
*
|
233 |
-
* It will scan the icl_translations table for translations of posts (but only where the elements in the associations
|
234 |
-
* actually are posts) and insert one row in the MV for each of them.
|
235 |
-
*
|
236 |
-
* If there are no rows in the icl_translations table for any affected post, which would otherwise result
|
237 |
-
* in doing nothing, we'll insert the row with the original ID manually with empty language code.
|
238 |
-
* That way it will still be possible to query the data.
|
239 |
-
*
|
240 |
-
* @param int $association_id
|
241 |
-
* @param string|Toolset_Relationship_Definition $relationship_source
|
242 |
-
* @param int $original_parent_id
|
243 |
-
* @param int $original_child_id
|
244 |
-
* @param int $original_intermediary_id
|
245 |
-
*
|
246 |
-
* @return Toolset_Result_Set
|
247 |
-
* @since m2m
|
248 |
-
*/
|
249 |
-
private function refresh_view_for_single_association(
|
250 |
-
$association_id, $relationship_source, $original_parent_id, $original_child_id, $original_intermediary_id
|
251 |
-
) {
|
252 |
-
// Sanitize input
|
253 |
-
$element_ids = array(
|
254 |
-
Toolset_Relationship_Role::PARENT => (int) $original_parent_id,
|
255 |
-
Toolset_Relationship_Role::CHILD => (int) $original_child_id
|
256 |
-
);
|
257 |
-
|
258 |
-
$relationship_definition = (
|
259 |
-
$relationship_source instanceof Toolset_Relationship_Definition
|
260 |
-
? $relationship_source
|
261 |
-
: Toolset_Relationship_Definition_Repository::get_instance()->get_definition( $relationship_source )
|
262 |
-
);
|
263 |
-
|
264 |
-
// Refresh the view for all posts that take part in the association.
|
265 |
-
$results = new Toolset_Result_Set();
|
266 |
-
foreach ( Toolset_Relationship_Role::parent_child_role_names() as $element_role ) {
|
267 |
-
if ( $relationship_definition->is_post( $element_role ) ) {
|
268 |
-
$result = $this->refresh_view_for_post_in_association(
|
269 |
-
$element_ids[ $element_role ], $element_role, $relationship_definition->get_slug(), $association_id
|
270 |
-
);
|
271 |
-
|
272 |
-
$results->add( $result );
|
273 |
-
}
|
274 |
-
}
|
275 |
-
|
276 |
-
$result = $this->refresh_view_for_post_in_association(
|
277 |
-
$original_intermediary_id, Toolset_Relationship_Role::INTERMEDIARY, $relationship_definition->get_slug(), $association_id
|
278 |
-
);
|
279 |
-
|
280 |
-
$results->add( $result );
|
281 |
-
|
282 |
-
return $results;
|
283 |
-
}
|
284 |
-
|
285 |
-
|
286 |
-
/**
|
287 |
-
* Refresh the association translation view for one post playing a specific role in one association.
|
288 |
-
*
|
289 |
-
* @param int $post_id
|
290 |
-
* @param string $role One of the Toolset_Relationship_Utils::ROLE_* constants.
|
291 |
-
* @param string $relationship_slug
|
292 |
-
* @param int $association_id
|
293 |
-
*
|
294 |
-
* @return Toolset_Result_Set|Toolset_Result_Updated
|
295 |
-
* @since m2m
|
296 |
-
*/
|
297 |
-
private function refresh_view_for_post_in_association( $post_id, $role, $relationship_slug, $association_id ) {
|
298 |
-
|
299 |
-
if ( 0 == $post_id ) {
|
300 |
-
return new Toolset_Result_Updated( true, 0 );
|
301 |
-
}
|
302 |
-
|
303 |
-
$post_translations = Toolset_Wpml_Utils::get_post_translations_directly( $post_id );
|
304 |
-
|
305 |
-
// Handle missing original post row.
|
306 |
-
if ( ! in_array( $post_id, $post_translations ) ) {
|
307 |
-
$post_translations[''] = $post_id;
|
308 |
-
}
|
309 |
-
|
310 |
-
$insert_format = array( '%d', '%s', '%s', '%d', '%s' );
|
311 |
-
$results = new Toolset_Result_Set();
|
312 |
-
|
313 |
-
global $wpdb;
|
314 |
-
|
315 |
-
// Insert one record per translation.
|
316 |
-
foreach ( $post_translations as $language_code => $translated_post_id ) {
|
317 |
-
$data = array(
|
318 |
-
'association_id' => $association_id,
|
319 |
-
'relationship' => $relationship_slug,
|
320 |
-
'language_code' => $language_code,
|
321 |
-
'post_id' => $translated_post_id,
|
322 |
-
'role' => $role
|
323 |
-
);
|
324 |
-
|
325 |
-
$result = $wpdb->insert( Toolset_Relationship_Table_Name::association_translations(), $data, $insert_format );
|
326 |
-
|
327 |
-
if ( false === $result ) {
|
328 |
-
$results->add(
|
329 |
-
new Toolset_Result(
|
330 |
-
false,
|
331 |
-
sprintf( __( 'Unable to insert a row in the %s table.', 'wpcf' ), Toolset_Relationship_Table_Name::association_translations() )
|
332 |
-
)
|
333 |
-
);
|
334 |
-
} else {
|
335 |
-
$results->add( new Toolset_Result_Updated( true, $result ) );
|
336 |
-
}
|
337 |
-
}
|
338 |
-
|
339 |
-
return $results;
|
340 |
-
}
|
341 |
-
|
342 |
-
|
343 |
-
/**
|
344 |
-
* Hooked into wpml_translation_update, this method refreshes the MV when WPML performs changes
|
345 |
-
* in the icl_translations table.
|
346 |
-
*
|
347 |
-
* Note that if too few information is provided, this might trigger a full refresh of the MV, eventually needing
|
348 |
-
* user's action on very large sites.
|
349 |
-
*
|
350 |
-
* This heavily relies on the fact that a before_delete action is followed by an after_delete one. If WPML
|
351 |
-
* fails to do that, we get a data inconsistency.
|
352 |
-
*
|
353 |
-
* @param array $args Following arguments will be recognized (all of them are optional):
|
354 |
-
* - string $type: insert|update|before_delete|after_delete|element_type_update|reset|before_language_delete,
|
355 |
-
* default is 'update'
|
356 |
-
* - int $trid
|
357 |
-
* - int $element_id
|
358 |
-
* - string $element_type
|
359 |
-
* - int $translation_id
|
360 |
-
* - string $context: post|tax|...
|
361 |
-
* - int $rows_affected
|
362 |
-
* - string $language: Language code for the before_language_delete event.
|
363 |
-
*
|
364 |
-
* @since m2m
|
365 |
-
*/
|
366 |
-
public function on_wpml_translation_update( $args ) {
|
367 |
-
|
368 |
-
return; // this is totally obsolete now
|
369 |
-
// Not checking is_interop_active() here, since this came from WPML.
|
370 |
-
|
371 |
-
$event_type = toolset_getarr( $args, 'type', 'update' );
|
372 |
-
switch ( $event_type ) {
|
373 |
-
|
374 |
-
case 'before_language_delete':
|
375 |
-
$this->handle_wpml_language_delete( toolset_getarr( $args, 'language' ) );
|
376 |
-
break;
|
377 |
-
|
378 |
-
case 'reset':
|
379 |
-
case 'element_type_update':
|
380 |
-
$this->handle_big_wpml_change();
|
381 |
-
break;
|
382 |
-
|
383 |
-
case 'after_delete':
|
384 |
-
$this->after_wpml_translations_deleted();
|
385 |
-
break;
|
386 |
-
|
387 |
-
default:
|
388 |
-
$this->handle_wpml_change_event( $event_type, $args );
|
389 |
-
break;
|
390 |
-
}
|
391 |
-
}
|
392 |
-
|
393 |
-
|
394 |
-
/**
|
395 |
-
* Handle the rare but possible situation when a whole language is deleted.
|
396 |
-
*
|
397 |
-
* We will simply delete everything with the given language_code from the MV.
|
398 |
-
*
|
399 |
-
* @param string $language_code
|
400 |
-
*
|
401 |
-
* @since m2m
|
402 |
-
*/
|
403 |
-
private function handle_wpml_language_delete( $language_code ) {
|
404 |
-
|
405 |
-
global $wpdb;
|
406 |
-
|
407 |
-
$wpdb->delete(
|
408 |
-
Toolset_Relationship_Table_Name::association_translations(),
|
409 |
-
array( 'language_code' => $language_code ),
|
410 |
-
array( '%s' )
|
411 |
-
);
|
412 |
-
}
|
413 |
-
|
414 |
-
|
415 |
-
private function handle_big_wpml_change() {
|
416 |
-
// todo
|
417 |
-
}
|
418 |
-
|
419 |
-
|
420 |
-
/**
|
421 |
-
* @var int[] Association IDs whose view rows have been deleted between before_delete and after_delete WPML events.
|
422 |
-
* @since m2m
|
423 |
-
*/
|
424 |
-
private $associations_without_views = array();
|
425 |
-
|
426 |
-
|
427 |
-
/**
|
428 |
-
* Handle a WPML event that changes icl_translations rows.
|
429 |
-
*
|
430 |
-
* Specifically, this works for: insert, update, before_delete.
|
431 |
-
*
|
432 |
-
* @param $event_type
|
433 |
-
* @param $args
|
434 |
-
*
|
435 |
-
* @since m2m
|
436 |
-
*/
|
437 |
-
private function handle_wpml_change_event( $event_type, $args ) {
|
438 |
-
|
439 |
-
$affected_posts = $this->query_posts_affected_by_wpml_event( $args );
|
440 |
-
|
441 |
-
if ( ! is_array( $affected_posts ) ) {
|
442 |
-
switch ( $affected_posts ) {
|
443 |
-
case self::CHANGE_TRIGGERS_FULL_REFRESH:
|
444 |
-
$this->handle_big_wpml_change();
|
445 |
-
|
446 |
-
return;
|
447 |
-
case self::CHANGE_IRRELEVANT:
|
448 |
-
// Nothing to do here.
|
449 |
-
default:
|
450 |
-
return;
|
451 |
-
}
|
452 |
-
}
|
453 |
-
|
454 |
-
$affected_associations = $this->query_affected_associations( $affected_posts );
|
455 |
-
|
456 |
-
if ( empty( $affected_associations ) ) {
|
457 |
-
return;
|
458 |
-
}
|
459 |
-
|
460 |
-
$this->delete_translation_views_for_associations( $affected_associations );
|
461 |
-
|
462 |
-
if ( 'before_delete' == $event_type ) {
|
463 |
-
// We won't refresh anything just yet, instead we store the IDs of associations whose views we have just
|
464 |
-
// erased, and wait until WPML invokes the after_delete action. Then, we'll do the refresh.
|
465 |
-
$this->associations_without_views = array_merge( $this->associations_without_views, $affected_associations );
|
466 |
-
} else {
|
467 |
-
// Insert or update.
|
468 |
-
$this->refresh_views_for_associations( $affected_associations );
|
469 |
-
}
|
470 |
-
}
|
471 |
-
|
472 |
-
|
473 |
-
/**
|
474 |
-
* Refresh the view after some WPML translations have been deleted.
|
475 |
-
*
|
476 |
-
* This happens during an after_delete event. In before_delete, we have deleted the view rows for possibly
|
477 |
-
* affected associations and stored association IDs. Now, we will take those IDs and refresh the view for
|
478 |
-
* those associations.
|
479 |
-
*
|
480 |
-
* This couldn't have been done sooner because a refresh before the icl_translations rows are actually deleted
|
481 |
-
* would accomplish nothing.
|
482 |
-
*
|
483 |
-
* @since m2m
|
484 |
-
*/
|
485 |
-
private function after_wpml_translations_deleted() {
|
486 |
-
$this->refresh_views_for_associations( $this->associations_without_views );
|
487 |
-
$this->associations_without_views = array();
|
488 |
-
}
|
489 |
-
|
490 |
-
|
491 |
-
// Return values for query_posts_affected_by_wpml_event().
|
492 |
-
const CHANGE_IRRELEVANT = 'irrelevant';
|
493 |
-
|
494 |
-
const CHANGE_TRIGGERS_FULL_REFRESH = 'full_refresh';
|
495 |
-
|
496 |
-
|
497 |
-
/**
|
498 |
-
* From arguments provided by WPML, try to understand what happened and which specific posts (and their
|
499 |
-
* translations) might be affected.
|
500 |
-
*
|
501 |
-
* Note: This can be further optimized, for example by filtering out post types that don't participate in
|
502 |
-
* any relationships (when element_type is provided/will be queried), etc.
|
503 |
-
*
|
504 |
-
* @param array $args
|
505 |
-
*
|
506 |
-
* @return string|int[] An array of post IDs that are affected by the update, CHANGE_IRRELEVANT if no posts
|
507 |
-
* have been affected or CHANGE_TRIGGERS_FULL_REFRESH if the change is too big or unspecific to decide.
|
508 |
-
* @since m2m
|
509 |
-
*/
|
510 |
-
private function query_posts_affected_by_wpml_event( $args ) {
|
511 |
-
|
512 |
-
if ( ! $this->could_be_wpml_post_translation_change( $args ) ) {
|
513 |
-
return self::CHANGE_IRRELEVANT;
|
514 |
-
}
|
515 |
-
|
516 |
-
$trid = $this->get_trid_affected_by_wpml_event( $args );
|
517 |
-
|
518 |
-
if ( 0 == $trid ) {
|
519 |
-
return self::CHANGE_TRIGGERS_FULL_REFRESH;
|
520 |
-
}
|
521 |
-
|
522 |
-
return Toolset_Wpml_Utils::query_elements_by_trid( $trid );
|
523 |
-
}
|
524 |
-
|
525 |
-
|
526 |
-
/**
|
527 |
-
* From arguments provided by WPML, get trid of everything that might be affected.
|
528 |
-
*
|
529 |
-
* See query_posts_affected_by_wpml_event() for details.
|
530 |
-
*
|
531 |
-
* @param array $args
|
532 |
-
*
|
533 |
-
* @return int trid or zero if it can't be determined.
|
534 |
-
*/
|
535 |
-
private function get_trid_affected_by_wpml_event( $args ) {
|
536 |
-
$trid = (int) toolset_getarr( $args, 'trid', 0 );
|
537 |
-
|
538 |
-
// Less expensive query first.
|
539 |
-
if ( 0 == $trid ) {
|
540 |
-
$translation_id = (int) toolset_getarr( $args, 'translation_id', 0 );
|
541 |
-
$trid = Toolset_Wpml_Utils::get_trid_from_translation_id( $translation_id );
|
542 |
-
}
|
543 |
-
|
544 |
-
if ( 0 == $trid ) {
|
545 |
-
$element_id = (int) toolset_getarr( $args, 'element_id', 0 );
|
546 |
-
$element_type = toolset_getarr( $args, 'element_type', 'post%' );
|
547 |
-
$trid = Toolset_Wpml_Utils::get_trid_from_element_id( $element_id, $element_type );
|
548 |
-
}
|
549 |
-
|
550 |
-
return $trid;
|
551 |
-
}
|
552 |
-
|
553 |
-
|
554 |
-
/**
|
555 |
-
* From arguments provided by WPML, decide if the event *could* affect post translations.
|
556 |
-
*
|
557 |
-
* @param array $args
|
558 |
-
*
|
559 |
-
* @return bool
|
560 |
-
* @since m2m
|
561 |
-
*/
|
562 |
-
private function could_be_wpml_post_translation_change( $args ) {
|
563 |
-
|
564 |
-
$context = toolset_getarr( $args, 'context' );
|
565 |
-
$element_type = toolset_getarr( $args, 'element_type' );
|
566 |
-
$has_element_type = ( ! empty( $element_type ) );
|
567 |
-
|
568 |
-
// Theoretically, we still might have the element_type even if no context was given.
|
569 |
-
if ( empty( $context ) && $has_element_type ) {
|
570 |
-
$context = explode( '_', $element_type );
|
571 |
-
$context = $context[0];
|
572 |
-
}
|
573 |
-
|
574 |
-
$has_context = ( ! empty( $context ) );
|
575 |
-
|
576 |
-
if ( $has_context && 'post' != $context ) {
|
577 |
-
return false;
|
578 |
-
} else {
|
579 |
-
return true;
|
580 |
-
}
|
581 |
-
}
|
582 |
-
|
583 |
-
|
584 |
-
/**
|
585 |
-
* Query associations (through the view table) where given posts have a role.
|
586 |
-
*
|
587 |
-
* todo move this to the associations query
|
588 |
-
*
|
589 |
-
* @param int[] $post_ids
|
590 |
-
*
|
591 |
-
* @return int[] Association IDs
|
592 |
-
* @since m2m
|
593 |
-
*/
|
594 |
-
private function query_affected_associations( $post_ids ) {
|
595 |
-
global $wpdb;
|
596 |
-
|
597 |
-
$view_tn = Toolset_Relationship_Table_Name::association_translations();
|
598 |
-
|
599 |
-
$query = "
|
600 |
-
SELECT DISTINCT association_id
|
601 |
-
FROM `{$view_tn}`
|
602 |
-
WHERE post_id IN (" . Toolset_Utils::prepare_mysql_in( $post_ids, '%d' ) . ")";
|
603 |
-
|
604 |
-
$association_ids = $wpdb->get_col( $query );
|
605 |
-
|
606 |
-
return $association_ids;
|
607 |
-
}
|
608 |
-
|
609 |
-
|
610 |
-
/**
|
611 |
-
* Refresh views for a set of association IDs.
|
612 |
-
*
|
613 |
-
* Gets all the association info in one query and then performs per-association refreshes.
|
614 |
-
*
|
615 |
-
* @param $association_ids
|
616 |
-
*
|
617 |
-
* @since m2m
|
618 |
-
*/
|
619 |
-
private function refresh_views_for_associations( $association_ids ) {
|
620 |
-
|
621 |
-
if ( empty( $association_ids ) ) {
|
622 |
-
return;
|
623 |
-
}
|
624 |
-
|
625 |
-
global $wpdb;
|
626 |
-
|
627 |
-
$associations_tn = Toolset_Relationship_Table_Name::associations();
|
628 |
-
$query = "
|
629 |
-
SELECT *
|
630 |
-
FROM `{$associations_tn}`
|
631 |
-
WHERE id IN (" . Toolset_Utils::prepare_mysql_in( $association_ids, '%d' ) . ")";
|
632 |
-
|
633 |
-
$associations = $wpdb->get_results( $query );
|
634 |
-
|
635 |
-
foreach ( $associations as $association ) {
|
636 |
-
$this->refresh_view_for_single_association(
|
637 |
-
$association->id,
|
638 |
-
$association->relationship,
|
639 |
-
$association->parent_id,
|
640 |
-
$association->child_id,
|
641 |
-
$association->intermediary_id
|
642 |
-
);
|
643 |
-
}
|
644 |
-
}
|
645 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/toolset/toolset-common/inc/public_api/legacy_relationships.php
ADDED
@@ -0,0 +1,338 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Public-facing legacy post relationship API.
|
4 |
+
*
|
5 |
+
* Note: This file is included only when m2m is *not* active, so there's no point in checking that anymore.
|
6 |
+
*/
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Query related post if many-to-many relationship functionality is NOT enabled.
|
10 |
+
*
|
11 |
+
* @param int|\WP_Post $query_by_element Post to query by. All results will be posts connected to this one.
|
12 |
+
* @param string[] $relationship Array containing parent post type and child post type.
|
13 |
+
* @param string $query_by_role_name Name of the element role to query by. Accepted values: 'parent'|'child'
|
14 |
+
* @param int $limit Maximum number of returned results ("posts per page").
|
15 |
+
* @param int $offset Result offset ("page number")
|
16 |
+
* @param array $args Additional query arguments. Accepted arguments:
|
17 |
+
* - meta_key, meta_value and meta_compare: Works exactly like in WP_Query. Only limited values are supported for meta_compare ('='|'LIKE').
|
18 |
+
* - s: Text search in the posts.
|
19 |
+
* @param string $return Determines return type. 'post_id' for array of post IDs, 'post_object' for an array of \WP_Post objects.
|
20 |
+
* @param string $role_name_to_return Which posts from the relationship should be returned. Accepted values
|
21 |
+
* are 'parent'|'child', but the value must be different from $query_by_role_name.
|
22 |
+
* If $query_by_role_name is 'parent' or 'child', it is also possible to pass 'other' here.
|
23 |
+
* @param null|string $orderby Determine how the results will be ordered. Accepted values: null, 'title', 'meta_value',
|
24 |
+
* 'meta_value_num'. If the latter two are used, there also needs to be a 'meta_key' argument in $args.
|
25 |
+
* Passing null means no ordering.
|
26 |
+
* @param string $order Accepted values: 'ASC' or 'DESC'.
|
27 |
+
* @param bool $need_found_rows Signal if the query should also determine the total number of results (disregarding pagination).
|
28 |
+
* @param null|&int $found_rows If $need_found_rows is set to true, the total number of results will be set
|
29 |
+
* into the variable passed to this parameter.
|
30 |
+
*
|
31 |
+
* @return int[]|\WP_Post[]
|
32 |
+
* @throws InvalidArgumentException In case of error.
|
33 |
+
*/
|
34 |
+
function toolset_get_related_posts(
|
35 |
+
$query_by_element,
|
36 |
+
$relationship,
|
37 |
+
$query_by_role_name,
|
38 |
+
$limit = 100,
|
39 |
+
$offset = 0,
|
40 |
+
$args = array(),
|
41 |
+
$return = 'post_id',
|
42 |
+
$role_name_to_return = 'other',
|
43 |
+
$orderby = null,
|
44 |
+
$order = 'ASC',
|
45 |
+
$need_found_rows = false,
|
46 |
+
&$found_rows = null
|
47 |
+
) {
|
48 |
+
// Input validation
|
49 |
+
//
|
50 |
+
//
|
51 |
+
if( ! is_array( $relationship ) || count( $relationship ) !== 2 ) {
|
52 |
+
throw new InvalidArgumentException( 'The relationship must be an array containing parent post type and child post type.' );
|
53 |
+
}
|
54 |
+
if ( ! get_post_type_object( $relationship[0] ) || ! get_post_type_object( $relationship[1] ) ) {
|
55 |
+
throw new InvalidArgumentException( 'Invalid relationship post type, please make sure they are valid post types.' );
|
56 |
+
}
|
57 |
+
if ( ! in_array( $query_by_role_name, array( 'parent', 'child', 'intermediary' ) ) ) {
|
58 |
+
throw new InvalidArgumentException( 'The role name to query by is not valid. Allowed values are: "parent", "child"' );
|
59 |
+
}
|
60 |
+
if( ! Toolset_Utils::is_natural_numeric( $query_by_element ) && ! $query_by_element instanceof WP_Post ) {
|
61 |
+
throw new InvalidArgumentException( 'The provided argument for a related element must be either an ID or a WP_Post object.' );
|
62 |
+
}
|
63 |
+
if(
|
64 |
+
! in_array( $role_name_to_return, array( 'parent', 'child', 'intermediary' ) )
|
65 |
+
&& ( 'other' !== $role_name_to_return || 'intermediary' === $query_by_role_name )
|
66 |
+
) {
|
67 |
+
throw new InvalidArgumentException(
|
68 |
+
'The role name to return is not valid. Allowed values are: "parent", "child" or "other" if $query_by_role_name is parent or child.'
|
69 |
+
);
|
70 |
+
}
|
71 |
+
|
72 |
+
if( ! \Toolset_Utils::is_natural_numeric( $limit ) || ! \Toolset_Utils::is_nonnegative_numeric( $offset ) ) {
|
73 |
+
throw new InvalidArgumentException( 'Limit and offset must be non-negative integers.' );
|
74 |
+
}
|
75 |
+
|
76 |
+
if( ! in_array( $return , array( 'post_id', 'post_object' ) ) ) {
|
77 |
+
throw new InvalidArgumentException( 'The provided argument for a return type must be either "post_id" or "post_object".' );
|
78 |
+
}
|
79 |
+
|
80 |
+
if( 'meta_key' === $orderby && ! array_key_exists( 'meta_key', $args ) ) {
|
81 |
+
throw new InvalidArgumentException( 'Cannot use ordering by a meta_key if no meta_key argument is provided.' );
|
82 |
+
}
|
83 |
+
|
84 |
+
if( ! in_array( $order, array( 'ASC', 'DESC' ) ) ) {
|
85 |
+
throw new InvalidArgumentException( 'Allowed order values are only ASC and DESC.' );
|
86 |
+
}
|
87 |
+
|
88 |
+
$legacy_relationships = toolset_ensarr( get_option( 'wpcf_post_relationship', array() ) );
|
89 |
+
|
90 |
+
if(
|
91 |
+
! array_key_exists( $relationship[0], $legacy_relationships )
|
92 |
+
|| ! is_array( $legacy_relationships[ $relationship[0] ] )
|
93 |
+
|| ! array_key_exists( $relationship[1], $legacy_relationships[ $relationship[0] ] )
|
94 |
+
|| ! is_array( $legacy_relationships[ $relationship[0] ][ $relationship[1] ] )
|
95 |
+
) {
|
96 |
+
return array();
|
97 |
+
}
|
98 |
+
|
99 |
+
// For now legacy relationships migration doesn't allow intermediary types and many-to-many, so this is droped from the code
|
100 |
+
/*
|
101 |
+
// Checks if it queries by intermediary post type and it is really an intermediary post type.
|
102 |
+
if ( 'intermediary' == $query_by_element ) {
|
103 |
+
// Number of ocurrences.
|
104 |
+
$ocurrences = array();
|
105 |
+
foreach ( $legacy_relationships as $_post_type => $_children ) {
|
106 |
+
if ( $query_by_element === $_post_type ) {
|
107 |
+
throw new InvalidArgumentException( 'Wrong intermediary post type, it should only be used as a child.' );
|
108 |
+
}
|
109 |
+
foreach ( array_keys( $_children) as $_child ) {
|
110 |
+
if ( ! isset( $ocurrences[ $_child ] ) ) {
|
111 |
+
$ocurrences[ $_child ] = 0;
|
112 |
+
}
|
113 |
+
$ocurrences[ $_child ]++;
|
114 |
+
}
|
115 |
+
}
|
116 |
+
if ( 2 !== $ocurrences[ $query_by_element ] ) {
|
117 |
+
throw new InvalidArgumentException( 'Wrong intermediary post type, it should be connected only to two post types.' );
|
118 |
+
}
|
119 |
+
}
|
120 |
+
*/
|
121 |
+
|
122 |
+
// Order by
|
123 |
+
$order_by = '';
|
124 |
+
if ( $orderby ) {
|
125 |
+
switch ( $orderby ) {
|
126 |
+
case 'title':
|
127 |
+
$order_by = " ORDER BY posts.post_title {$order} ";
|
128 |
+
break;
|
129 |
+
case 'meta_value':
|
130 |
+
$order_by = " ORDER BY mt.meta_value {$order} ";
|
131 |
+
break;
|
132 |
+
case 'meta_value_num':
|
133 |
+
$order_by = " ORDER BY CAST(mt.meta_value AS SIGNED) {$order} ";
|
134 |
+
break;
|
135 |
+
}
|
136 |
+
}
|
137 |
+
|
138 |
+
// $is_many_to_many = isset( $legacy_relationships[ $relationship[0] ] )
|
139 |
+
// && isset( $legacy_relationships[ $relationship[1] ] )
|
140 |
+
// && ! empty ( array_intersect_key( $legacy_relationships[ $relationship[0] ], $legacy_relationships[ $relationship[1] ] ) );
|
141 |
+
|
142 |
+
global $wpdb;
|
143 |
+
|
144 |
+
$where = array( '1=1');
|
145 |
+
$joins = array();
|
146 |
+
$from = " FROM {$wpdb->posts} posts ";
|
147 |
+
|
148 |
+
$query_by_post_id = $query_by_element instanceof WP_Post
|
149 |
+
? $query_by_element->ID
|
150 |
+
: $query_by_element;
|
151 |
+
|
152 |
+
if ( 'other' === $role_name_to_return ) {
|
153 |
+
$post_type = 'parent' === $query_by_role_name
|
154 |
+
? $relationship[1]
|
155 |
+
: $relationship[0];
|
156 |
+
} else {
|
157 |
+
$post_type = 'parent' === $role_name_to_return
|
158 |
+
? $relationship[0]
|
159 |
+
: $relationship[1];
|
160 |
+
}
|
161 |
+
|
162 |
+
// Joins. get_posts can't be used because some times wp_postmeta.post_id is needed and in other cases meta_value,
|
163 |
+
// or joining to wp_postmeta records is required.
|
164 |
+
|
165 |
+
// If querying by intermediary, it always return its parent.
|
166 |
+
// For now legacy relationships migration doesn't allow intermediary types and many-to-many, so this is droped from the code
|
167 |
+
/*
|
168 |
+
if ( 'intermediary' === $query_by_role_name ) {
|
169 |
+
$joins[] = $wpdb->prepare( "JOIN {$wpdb->postmeta} belongs ON
|
170 |
+
belongs.meta_key = %s AND
|
171 |
+
belongs.post_id = %d AND
|
172 |
+
belongs.meta_value = posts.ID", "_wpcf_belongs_{$post_type}_id", $query_by_post_id );
|
173 |
+
} else {
|
174 |
+
if ( $is_many_to_many ) {
|
175 |
+
$other_post_type = $relationship[0] === $post_type
|
176 |
+
? $relationship[1]
|
177 |
+
: $relationship[0];
|
178 |
+
$joins[] = $wpdb->prepare( "JOIN wp_postmeta belongs_intermediary ON
|
179 |
+
belongs_intermediary.meta_key = %s AND
|
180 |
+
belongs_intermediary.meta_value = %d
|
181 |
+
JOIN wp_postmeta belongs_parent ON
|
182 |
+
belongs_parent.meta_key = %s AND
|
183 |
+
belongs_parent.post_id = belongs_intermediary.post_id AND
|
184 |
+
belongs_parent.meta_value = posts.ID", "_wpcf_belongs_{$other_post_type}_id", $query_by_post_id, "_wpcf_belongs_{$post_type}_id" );
|
185 |
+
} else {
|
186 |
+
*/
|
187 |
+
$actual_role_name = $query_by_role_name;
|
188 |
+
if ( 'other' !== $query_by_role_name ) {
|
189 |
+
$actual_role_name = $relationship[0] === $post_type
|
190 |
+
? 'child'
|
191 |
+
: 'parent';
|
192 |
+
}
|
193 |
+
if ( 'parent' === $actual_role_name ) {
|
194 |
+
$joins[] = $wpdb->prepare( "JOIN {$wpdb->postmeta} belongs ON
|
195 |
+
belongs.meta_key = %s AND
|
196 |
+
belongs.meta_value = %d AND
|
197 |
+
belongs.post_id = posts.ID", "_wpcf_belongs_{$relationship[0]}_id", $query_by_post_id );
|
198 |
+
} else if ( 'child' === $actual_role_name ) {
|
199 |
+
$joins[] = $wpdb->prepare( "JOIN {$wpdb->postmeta} belongs ON
|
200 |
+
belongs.meta_key = %s AND
|
201 |
+
belongs.post_id = %d AND
|
202 |
+
belongs.meta_value = posts.ID", "_wpcf_belongs_{$relationship[0]}_id", $query_by_post_id );
|
203 |
+
}
|
204 |
+
/* Eventually dropped
|
205 |
+
}
|
206 |
+
}
|
207 |
+
*/
|
208 |
+
|
209 |
+
// Args (meta_key, meta_value and meta_compare) or searching
|
210 |
+
if ( ! empty( $args['meta_key'] ) && ! empty( $args['meta_value'] ) ) {
|
211 |
+
$meta_query_args = array(
|
212 |
+
array(
|
213 |
+
'key' => $args['meta_key'],
|
214 |
+
'value' => $args['meta_value'],
|
215 |
+
'compare' => $args['meta_compare'] ? $args['meta_compare'] : '=',
|
216 |
+
),
|
217 |
+
);
|
218 |
+
$meta_query = new WP_Meta_Query( $meta_query_args );
|
219 |
+
$mq_sql = $meta_query->get_sql(
|
220 |
+
'post',
|
221 |
+
'posts',
|
222 |
+
'ID'
|
223 |
+
);
|
224 |
+
if ( isset( $mq_sql['join'] ) ) {
|
225 |
+
$joins[] = str_replace(
|
226 |
+
array( $wpdb->postmeta . '.', $wpdb->postmeta ),
|
227 |
+
array( 'mt.', $wpdb->postmeta . ' mt' ),
|
228 |
+
$mq_sql['join']
|
229 |
+
);
|
230 |
+
}
|
231 |
+
if ( isset( $mq_sql['where'] ) ) {
|
232 |
+
$where[] = str_replace( $wpdb->postmeta . '.', 'mt.', $mq_sql['where'] );
|
233 |
+
}
|
234 |
+
}
|
235 |
+
|
236 |
+
// Search
|
237 |
+
if ( ! empty( $args['s'] ) ) {
|
238 |
+
$like = '%' . $args['s'] . '%';
|
239 |
+
$where[] = $wpdb->prepare( " AND ( posts.post_content like %s OR posts.post_title like %s ) ", $like, $like );
|
240 |
+
}
|
241 |
+
|
242 |
+
$joins = implode( "\n", $joins );
|
243 |
+
$where = implode( "\n", $where );
|
244 |
+
$query_fields = 'posts.ID';
|
245 |
+
$found_rows = $need_found_rows ? ' SQL_CALC_FOUND_ROWS ' : '';
|
246 |
+
|
247 |
+
$sql = "SELECT {$found_rows} {$query_fields} {$from}
|
248 |
+
{$joins}
|
249 |
+
WHERE {$where}
|
250 |
+
{$order_by}
|
251 |
+
LIMIT {$offset}, {$limit}";
|
252 |
+
|
253 |
+
$posts = $wpdb->get_results( $sql );
|
254 |
+
|
255 |
+
if ( $need_found_rows ) {
|
256 |
+
$found_rows = $wpdb->num_rows;
|
257 |
+
}
|
258 |
+
|
259 |
+
$result = array();
|
260 |
+
foreach ( $posts as $post ) {
|
261 |
+
$result[] = 'post_id' === $return
|
262 |
+
? (int) $post->ID
|
263 |
+
: get_post( $post->ID );
|
264 |
+
}
|
265 |
+
|
266 |
+
return $result;
|
267 |
+
}
|
268 |
+
|
269 |
+
|
270 |
+
/**
|
271 |
+
* Retrieve an ID of a single related post.
|
272 |
+
*
|
273 |
+
* Note: For more complex cases, use toolset_get_related_posts().
|
274 |
+
*
|
275 |
+
* @param WP_Post|int $post Post whose related post should be returned.
|
276 |
+
* @param string|string[] $relationship Slug of the relationship to query by or an array with the parent and the child post type.
|
277 |
+
* The array variant can be used only to identify relationships that have been migrated from the legacy implementation.
|
278 |
+
* @param string $role_name_to_return Which posts from the relationship should be returned. Accepted values
|
279 |
+
* are 'parent' and 'child'. The relationship needs to have only one possible result in this role,
|
280 |
+
* otherwise an exception will be thrown.
|
281 |
+
*
|
282 |
+
* @return int Post ID or zero if no related post was found.
|
283 |
+
*/
|
284 |
+
function toolset_get_related_post( $post, $relationship, $role_name_to_return = 'parent' ) {
|
285 |
+
// Input validation
|
286 |
+
//
|
287 |
+
//
|
288 |
+
if( ! Toolset_Utils::is_natural_numeric( $post ) && ! $post instanceof WP_Post ) {
|
289 |
+
throw new InvalidArgumentException( 'The provided argument for a related element must be either an ID or a WP_Post object.' );
|
290 |
+
}
|
291 |
+
if( ! is_array( $relationship ) || count( $relationship ) !== 2 ) {
|
292 |
+
throw new InvalidArgumentException( 'The relationship must be an array containing parent post type and child post type.' );
|
293 |
+
}
|
294 |
+
if ( ! get_post_type_object( $relationship[0] ) || ! get_post_type_object( $relationship[1] ) ) {
|
295 |
+
throw new InvalidArgumentException( 'Invalid relationship post type, please make sure they are valid post types.' );
|
296 |
+
}
|
297 |
+
if( ! in_array( $role_name_to_return, array( 'parent', 'child' ) ) ) {
|
298 |
+
throw new InvalidArgumentException( 'The role name to return is not valid. Allowed values are: "parent", "child".' );
|
299 |
+
}
|
300 |
+
$query_by_role_name = 'parent' === $role_name_to_return
|
301 |
+
? 'child'
|
302 |
+
: 'parent';
|
303 |
+
$result = toolset_get_related_posts(
|
304 |
+
$post,
|
305 |
+
$relationship,
|
306 |
+
$query_by_role_name,
|
307 |
+
1,
|
308 |
+
0,
|
309 |
+
array(),
|
310 |
+
'post_id',
|
311 |
+
$role_name_to_return
|
312 |
+
);
|
313 |
+
return isset ( $result[0] ) ? $result[0] : 0;
|
314 |
+
}
|
315 |
+
|
316 |
+
|
317 |
+
/**
|
318 |
+
* Retrieve an ID of the parent post, using a legacy post relationship (migrated from the legacy implementation).
|
319 |
+
*
|
320 |
+
* For this to work, there needs to be a relationship between $target_type and the provided post's type.
|
321 |
+
*
|
322 |
+
* Note: For more complex cases, use toolset_get_related_post() or toolset_get_related_posts().
|
323 |
+
*
|
324 |
+
* @param WP_Post|int $post Post whose parent should be returned.
|
325 |
+
* @param string $target_type Parent post type.
|
326 |
+
*
|
327 |
+
* @return int Post ID or zero if no related post was found.
|
328 |
+
*/
|
329 |
+
function toolset_get_parent_post_by_type( $post, $target_type ) {
|
330 |
+
|
331 |
+
$post = get_post( $post );
|
332 |
+
|
333 |
+
if( ! $post instanceof WP_Post ) {
|
334 |
+
return 0;
|
335 |
+
}
|
336 |
+
|
337 |
+
return toolset_get_related_post( $post, array( $target_type, $post->post_type ) );
|
338 |
+
}
|
vendor/toolset/toolset-common/inc/public_api/loader.php
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// the non-m2m part still needs to support PHP 5.2 for the time being.
|
4 |
+
//namespace OTGS\Toolset\Common\PublicAPI;
|
5 |
+
|
6 |
+
/**
|
7 |
+
* Loads the public-facing API of Toolset Common.
|
8 |
+
*
|
9 |
+
* @since 2.6.1
|
10 |
+
*/
|
11 |
+
class Toolset_Public_API_Loader {
|
12 |
+
|
13 |
+
|
14 |
+
public function initialize() {
|
15 |
+
|
16 |
+
// Note: This could be used for a more generic solution.
|
17 |
+
//$files = glob( '*.php' );
|
18 |
+
//
|
19 |
+
//if( ! is_array( $files ) ) {
|
20 |
+
// // Error when enumerating files, can't do anything about it at this point.
|
21 |
+
// return;
|
22 |
+
//}
|
23 |
+
//
|
24 |
+
//foreach( $files as $file ) {
|
25 |
+
// require_once $file;
|
26 |
+
//}
|
27 |
+
|
28 |
+
if( apply_filters( 'toolset_is_m2m_enabled', false ) ) {
|
29 |
+
require_once TOOLSET_COMMON_PATH . '/inc/public_api/m2m.php';
|
30 |
+
} else {
|
31 |
+
require_once TOOLSET_COMMON_PATH . '/inc/public_api/legacy_relationships.php';
|
32 |
+
}
|
33 |
+
}
|
34 |
+
|
35 |
+
}
|
vendor/toolset/toolset-common/inc/public_api/m2m.php
ADDED
@@ -0,0 +1,309 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Public-facing m2m API.
|
5 |
+
*
|
6 |
+
* Note: This file is included only when m2m is active, so there's no point in checking that anymore.
|
7 |
+
*/
|
8 |
+
|
9 |
+
/**
|
10 |
+
* Query related post if many-to-many relationship functionality is enabled.
|
11 |
+
*
|
12 |
+
* @param int|\WP_Post $query_by_element Post to query by. All results will be posts connected to this one.
|
13 |
+
* @param string|string[] $relationship Slug of the relationship to query by or an array with the parent and the child post type.
|
14 |
+
* The array variant can be used only to identify relationships that have been migrated from the legacy implementation.
|
15 |
+
* @param string $query_by_role_name Name of the element role to query by. Accepted values: 'parent'|'child'|'intermediary'
|
16 |
+
* @param int $limit Maximum number of returned results ("posts per page").
|
17 |
+
* @param int $offset Result offset ("page number")
|
18 |
+
* @param array $args Additional query arguments. Accepted arguments:
|
19 |
+
* - meta_key, meta_value and meta_compare: Works exactly like in WP_Query. Only limited values are supported for meta_compare ('='|'LIKE').
|
20 |
+
* - s: Text search in the posts.
|
21 |
+
* @param string $return Determines return type. 'post_id' for array of post IDs, 'post_object' for an array of \WP_Post objects.
|
22 |
+
* @param string $role_name_to_return Which posts from the relationship should be returned. Accepted values
|
23 |
+
* are 'parent'|'child'|'intermediary', but the value must be different from $query_by_role_name.
|
24 |
+
* If $query_by_role_name is 'parent' or 'child', it is also possible to pass 'other' here.
|
25 |
+
* @param null|string $orderby Determine how the results will be ordered. Accepted values: null, 'title', 'meta_value',
|
26 |
+
* 'meta_value_num'. If the latter two are used, there also needs to be a 'meta_key' argument in $args.
|
27 |
+
* Passing null means no ordering.
|
28 |
+
* @param string $order Accepted values: 'ASC' or 'DESC'.
|
29 |
+
* @param bool $need_found_rows Signal if the query should also determine the total number of results (disregarding pagination).
|
30 |
+
* @param null|&int $found_rows If $need_found_rows is set to true, the total number of results will be set
|
31 |
+
* into the variable passed to this parameter.
|
32 |
+
*
|
33 |
+
* @return int[]|\WP_Post[]
|
34 |
+
*/
|
35 |
+
function toolset_get_related_posts(
|
36 |
+
$query_by_element,
|
37 |
+
$relationship,
|
38 |
+
$query_by_role_name,
|
39 |
+
$limit = 100,
|
40 |
+
$offset = 0,
|
41 |
+
$args = array(),
|
42 |
+
$return = 'post_id',
|
43 |
+
$role_name_to_return = 'other',
|
44 |
+
$orderby = null,
|
45 |
+
$order = 'ASC',
|
46 |
+
$need_found_rows = false,
|
47 |
+
&$found_rows = null
|
48 |
+
) {
|
49 |
+
do_action( 'toolset_do_m2m_full_init' );
|
50 |
+
|
51 |
+
// Input validation
|
52 |
+
//
|
53 |
+
//
|
54 |
+
if( ! is_string( $relationship ) && ! ( is_array( $relationship ) && count( $relationship ) === 2 ) ) {
|
55 |
+
throw new \InvalidArgumentException( 'The relationship must be a string with the relationship slug or an array with two post types.' );
|
56 |
+
}
|
57 |
+
|
58 |
+
if( ! in_array( $query_by_role_name, \Toolset_Relationship_Role::all_role_names() ) ) {
|
59 |
+
throw new \InvalidArgumentException( 'The role name to query by is not valid. Allowed values are: "' . implode( '", "', \Toolset_Relationship_Role::all_role_names() ) . '".' );
|
60 |
+
}
|
61 |
+
|
62 |
+
if(
|
63 |
+
! in_array( $role_name_to_return, \Toolset_Relationship_Role::all_role_names() )
|
64 |
+
&& ( 'other' !== $role_name_to_return || \Toolset_Relationship_Role::INTERMEDIARY === $query_by_role_name )
|
65 |
+
) {
|
66 |
+
throw new \InvalidArgumentException(
|
67 |
+
'The role name to return is not valid. Allowed values are: "' .
|
68 |
+
implode( '", "', \Toolset_Relationship_Role::all_role_names() ) .
|
69 |
+
'" or "other" if $query_by_role_name is parent or child.'
|
70 |
+
);
|
71 |
+
}
|
72 |
+
|
73 |
+
if( ! \Toolset_Utils::is_natural_numeric( $query_by_element ) && ! $query_by_element instanceof \WP_Post ) {
|
74 |
+
throw new \InvalidArgumentException( 'The provided argument for a related element must be either an ID or a WP_Post object.' );
|
75 |
+
}
|
76 |
+
|
77 |
+
if( ! \Toolset_Utils::is_natural_numeric( $limit ) || ! \Toolset_Utils::is_nonnegative_numeric( $offset ) ) {
|
78 |
+
throw new \InvalidArgumentException( 'Limit and offset must be non-negative integers.' );
|
79 |
+
}
|
80 |
+
|
81 |
+
if( ! in_array( $return , array( 'post_id', 'post_object' ) ) ) {
|
82 |
+
throw new \InvalidArgumentException( 'The provided argument for a return type must be either "post_id" or "post_object".' );
|
83 |
+
}
|
84 |
+
|
85 |
+
if( 'meta_key' === $orderby && ! array_key_exists( 'meta_key', $args ) ) {
|
86 |
+
throw new \InvalidArgumentException( 'Cannot use ordering by a meta_key if no meta_key argument is provided.' );
|
87 |
+
}
|
88 |
+
|
89 |
+
if( ! in_array( strtoupper( $order ), array( 'ASC', 'DESC' ) ) ) {
|
90 |
+
throw new \InvalidArgumentException( 'Allowed order values are only ASC and DESC.' );
|
91 |
+
}
|
92 |
+
|
93 |
+
// Input post-processing
|
94 |
+
//
|
95 |
+
//
|
96 |
+
$element_id = (int) ( $query_by_element instanceof \WP_Post ? $query_by_element->ID : $query_by_element );
|
97 |
+
$limit = (int) $limit;
|
98 |
+
$offset = (int) $offset;
|
99 |
+
$query_by_role = \Toolset_Relationship_Role::role_from_name( $query_by_role_name );
|
100 |
+
$need_found_rows = (bool) $need_found_rows;
|
101 |
+
$search = toolset_getarr( $args, 's' );
|
102 |
+
$has_meta_condition = ( array_key_exists( 'meta_key', $args ) && array_key_exists( 'meta_value', $args ) );
|
103 |
+
|
104 |
+
if( 'other' === $role_name_to_return ) {
|
105 |
+
// This will happen only if the $query_by_role not intermediary.
|
106 |
+
/** @var \IToolset_Relationship_Role_Parent_Child $query_by_role */
|
107 |
+
$role_to_return = $query_by_role->other();
|
108 |
+
} else {
|
109 |
+
$role_to_return = \Toolset_Relationship_Role::role_from_name( $role_name_to_return );
|
110 |
+
}
|
111 |
+
|
112 |
+
if( is_array( $relationship ) ) {
|
113 |
+
$definition_repository = Toolset_Relationship_Definition_Repository::get_instance();
|
114 |
+
$relationship_definition = $definition_repository->get_legacy_definition( $relationship[0], $relationship[1] );
|
115 |
+
if( null === $relationship_definition ) {
|
116 |
+
//throw new \InvalidArgumentException( 'There is no relationship between the two provided post types (no migrated one from the legacy implementation).' );
|
117 |
+
return array();
|
118 |
+
}
|
119 |
+
$relationship = $relationship_definition->get_slug();
|
120 |
+
}
|
121 |
+
|
122 |
+
// Build the query
|
123 |
+
//
|
124 |
+
//
|
125 |
+
try {
|
126 |
+
$query = new \Toolset_Association_Query_V2();
|
127 |
+
|
128 |
+
$query->add( $query->relationship_slug( $relationship ) )
|
129 |
+
->add( $query->element_id_and_domain( $element_id, \Toolset_Element_Domain::POSTS, $query_by_role ) )
|
130 |
+
->limit( $limit )
|
131 |
+
->offset( $offset )
|
132 |
+
->order( $order )
|
133 |
+
->need_found_rows( $need_found_rows );
|
134 |
+
|
135 |
+
if ( ! empty( $search ) ) {
|
136 |
+
$query->add( $query->search( $search, $role_to_return ) );
|
137 |
+
}
|
138 |
+
|
139 |
+
if ( $has_meta_condition ) {
|
140 |
+
$query->add(
|
141 |
+
$query->meta(
|
142 |
+
toolset_getarr( $args, 'meta_key' ),
|
143 |
+
toolset_getarr( $args, 'meta_value' ),
|
144 |
+
\Toolset_Element_Domain::POSTS,
|
145 |
+
$role_to_return,
|
146 |
+
toolset_getarr( $args, 'meta_compare', \Toolset_Query_Comparison_Operator::EQUALS )
|
147 |
+
)
|
148 |
+
);
|
149 |
+
}
|
150 |
+
|
151 |
+
if ( 'post_id' === $return ) {
|
152 |
+
$query->return_element_ids( $role_to_return );
|
153 |
+
} else {
|
154 |
+
$query->return_element_instances( $role_to_return );
|
155 |
+
}
|
156 |
+
|
157 |
+
switch ( $orderby ) {
|
158 |
+
case 'title':
|
159 |
+
$query->order_by_title( $role_to_return );
|
160 |
+
break;
|
161 |
+
case 'meta_value':
|
162 |
+
$query->order_by_meta( toolset_getarr( $args, 'meta_key' ), \Toolset_Element_Domain::POSTS, $role_to_return );
|
163 |
+
break;
|
164 |
+
case 'meta_value_num':
|
165 |
+
$query->order_by_meta( toolset_getarr( $args, 'meta_key' ), \Toolset_Element_Domain::POSTS, $role_to_return, true );
|
166 |
+
break;
|
167 |
+
default:
|
168 |
+
$query->dont_order();
|
169 |
+
break;
|
170 |
+
}
|
171 |
+
|
172 |
+
// Get results and post-process them
|
173 |
+
//
|
174 |
+
//
|
175 |
+
$results = $query->get_results();
|
176 |
+
|
177 |
+
if ( $need_found_rows ) {
|
178 |
+
$found_rows = $query->get_found_rows();
|
179 |
+
}
|
180 |
+
|
181 |
+
if ( 'post_id' === $return ) {
|
182 |
+
return $results;
|
183 |
+
} else {
|
184 |
+
$results = array_map(
|
185 |
+
function ( $result ) {
|
186 |
+
/** @var \IToolset_Post $result */
|
187 |
+
return $result->get_underlying_object();
|
188 |
+
}, $results
|
189 |
+
);
|
190 |
+
|
191 |
+
return $results;
|
192 |
+
}
|
193 |
+
} catch ( Exception $e ) {
|
194 |
+
// This is most probably caused by an element not existing, an exception raised from the depth of
|
195 |
+
// the association query - otherwise, there are no reasons for it to fail, all the inputs should be valid.
|
196 |
+
return array();
|
197 |
+
}
|
198 |
+
}
|
199 |
+
|
200 |
+
|
201 |
+
/**
|
202 |
+
* Retrieve an ID of a single related post.
|
203 |
+
*
|
204 |
+
* Note: For more complex cases, use toolset_get_related_posts().
|
205 |
+
*
|
206 |
+
* @param WP_Post|int $post Post whose related post should be returned.
|
207 |
+
* @param string|string[] $relationship Slug of the relationship to query by or an array with the parent and the child post type.
|
208 |
+
* The array variant can be used only to identify relationships that have been migrated from the legacy implementation.
|
209 |
+
* @param string $role_name_to_return Which posts from the relationship should be returned. Accepted values
|
210 |
+
* are 'parent' and 'child'. The relationship needs to have only one possible result in this role,
|
211 |
+
* otherwise an exception will be thrown.
|
212 |
+
*
|
213 |
+
* @return int Post ID or zero if no related post was found.
|
214 |
+
*/
|
215 |
+
function toolset_get_related_post( $post, $relationship, $role_name_to_return = 'parent' ) {
|
216 |
+
|
217 |
+
do_action( 'toolset_do_m2m_full_init' );
|
218 |
+
|
219 |
+
// Input validation and pre-processing
|
220 |
+
//
|
221 |
+
//
|
222 |
+
if( ! is_string( $relationship ) && ! ( is_array( $relationship ) && count( $relationship ) === 2 ) ) {
|
223 |
+
throw new \InvalidArgumentException( 'The relationship must be a string with the relationship slug or an array with two post types.' );
|
224 |
+
}
|
225 |
+
|
226 |
+
$post = get_post( $post );
|
227 |
+
|
228 |
+
if( ! $post instanceof WP_Post ) {
|
229 |
+
return 0;
|
230 |
+
}
|
231 |
+
|
232 |
+
$definition_repository = Toolset_Relationship_Definition_Repository::get_instance();
|
233 |
+
|
234 |
+
if( is_array( $relationship ) ) {
|
235 |
+
$relationship_definition = $definition_repository->get_legacy_definition( $relationship[0], $relationship[1] );
|
236 |
+
} else {
|
237 |
+
$relationship_definition = $definition_repository->get_definition( $relationship );
|
238 |
+
}
|
239 |
+
|
240 |
+
if( null === $relationship_definition ) {
|
241 |
+
return 0;
|
242 |
+
}
|
243 |
+
|
244 |
+
if( $relationship_definition->get_cardinality()->get_limit( $role_name_to_return ) > Toolset_Relationship_Cardinality::ONE_ELEMENT ) {
|
245 |
+
return 0;
|
246 |
+
}
|
247 |
+
|
248 |
+
if( ! in_array( $role_name_to_return, \Toolset_Relationship_Role::parent_child_role_names() ) ) {
|
249 |
+
throw new \InvalidArgumentException(
|
250 |
+
'The role name to return is not valid. Allowed values are: "' .
|
251 |
+
implode( '", "', \Toolset_Relationship_Role::parent_child_role_names() ) .
|
252 |
+
'".'
|
253 |
+
);
|
254 |
+
}
|
255 |
+
|
256 |
+
/** @var IToolset_Relationship_Role_Parent_Child $role_to_return */
|
257 |
+
$role_to_return = \Toolset_Relationship_Role::role_from_name( $role_name_to_return );
|
258 |
+
|
259 |
+
// Query the single result
|
260 |
+
//
|
261 |
+
//
|
262 |
+
|
263 |
+
try {
|
264 |
+
$query = new Toolset_Association_Query_V2();
|
265 |
+
|
266 |
+
$results = $query->add( $query->relationship( $relationship_definition ) )
|
267 |
+
->add( $query->element_id_and_domain( $post->ID, Toolset_Element_Domain::POSTS, $role_to_return->other() ) )
|
268 |
+
->limit( 1 )
|
269 |
+
->return_element_ids( $role_to_return )
|
270 |
+
->get_results();
|
271 |
+
|
272 |
+
} catch ( Exception $e ) {
|
273 |
+
// This is most probably caused by an element not existing, an exception raised from the depth of
|
274 |
+
// the association query - otherwise, there are no reasons for it to fail, all the inputs should be valid.
|
275 |
+
return 0;
|
276 |
+
}
|
277 |
+
|
278 |
+
if( empty( $results ) ) {
|
279 |
+
return 0; // No result.
|
280 |
+
}
|
281 |
+
|
282 |
+
$result = (int) array_pop( $results );
|
283 |
+
|
284 |
+
return $result;
|
285 |
+
}
|
286 |
+
|
287 |
+
|
288 |
+
/**
|
289 |
+
* Retrieve an ID of the parent post, using a legacy post relationship (migrated from the legacy implementation).
|
290 |
+
*
|
291 |
+
* For this to work, there needs to be a relationship between $target_type and the provided post's type.
|
292 |
+
*
|
293 |
+
* Note: For more complex cases, use toolset_get_related_post() or toolset_get_related_posts().
|
294 |
+
*
|
295 |
+
* @param WP_Post|int $post Post whose parent should be returned.
|
296 |
+
* @param string $target_type Parent post type.
|
297 |
+
*
|
298 |
+
* @return int Post ID or zero if no related post was found.
|
299 |
+
*/
|
300 |
+
function toolset_get_parent_post_by_type( $post, $target_type ) {
|
301 |
+
|
302 |
+
$post = get_post( $post );
|
303 |
+
|
304 |
+
if( ! $post instanceof WP_Post ) {
|
305 |
+
return 0;
|
306 |
+
}
|
307 |
+
|
308 |
+
return toolset_get_related_post( $post, array( $target_type, $post->post_type ) );
|
309 |
+
}
|
vendor/toolset/toolset-common/inc/toolset.ajax.class.php
CHANGED
@@ -36,59 +36,129 @@
|
|
36 |
* @since m2m
|
37 |
*/
|
38 |
class Toolset_Ajax {
|
39 |
-
|
|
|
40 |
/** Prefix for the callback method name */
|
41 |
const CALLBACK_PREFIX = 'callback_';
|
42 |
-
|
|
|
43 |
const DELIMITER = '_';
|
44 |
|
|
|
|
|
|
|
|
|
45 |
/**
|
46 |
* @return Toolset_Ajax|false
|
47 |
*/
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
if ( isset( $instances[ $called_class ] ) ) {
|
53 |
-
return $instances[ $called_class ];
|
54 |
-
} else {
|
55 |
-
if ( class_exists( $called_class ) ) {
|
56 |
-
$instances[ $called_class ] = new $called_class();
|
57 |
-
|
58 |
-
return $instances[ $called_class ];
|
59 |
-
} else {
|
60 |
-
// This can unfortunately happen when the get_called_class() workaround for PHP 5.2 misbehaves.
|
61 |
-
return false;
|
62 |
-
}
|
63 |
}
|
|
|
|
|
64 |
}
|
65 |
|
66 |
|
67 |
public static function initialize() {
|
68 |
-
$
|
|
|
|
|
69 |
|
70 |
$instance->register_callbacks();
|
71 |
$instance->additional_ajax_init();
|
72 |
}
|
73 |
|
74 |
|
75 |
-
|
76 |
|
|
|
77 |
|
78 |
-
|
79 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
80 |
|
81 |
-
const CALLBACK_MIGRATE_TO_M2M = 'migrate_to_m2m';
|
82 |
-
|
83 |
|
84 |
protected function get_callback_names() {
|
85 |
return array(
|
86 |
-
self::CALLBACK_MIGRATE_TO_M2M
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
87 |
);
|
88 |
}
|
89 |
|
90 |
|
91 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
92 |
|
93 |
|
94 |
/**
|
@@ -101,34 +171,32 @@ class Toolset_Ajax {
|
|
101 |
*/
|
102 |
private function register_callbacks() {
|
103 |
|
104 |
-
if( $this->callbacks_registered ) {
|
105 |
return;
|
106 |
}
|
107 |
|
108 |
$callback_names = $this->get_callback_names();
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
);
|
115 |
-
}
|
116 |
|
117 |
$this->callbacks_registered = true;
|
118 |
|
119 |
}
|
120 |
-
|
121 |
-
|
122 |
protected function get_plugin_slug( $capitalized = false ) {
|
123 |
return ( $capitalized ? 'Toolset' : 'toolset' );
|
124 |
}
|
125 |
-
|
126 |
-
|
127 |
protected function get_handler_class_prefix() {
|
128 |
-
return $this->get_plugin_slug( true ) . '_Ajax_Handler_';
|
129 |
}
|
130 |
|
131 |
-
|
132 |
public function get_action_js_name( $action ) {
|
133 |
return $this->get_plugin_slug( false ) . self::DELIMITER . $action;
|
134 |
}
|
@@ -139,12 +207,13 @@ class Toolset_Ajax {
|
|
139 |
*
|
140 |
* @param string $name Method name.
|
141 |
* @param array $parameters Method parameters.
|
|
|
142 |
* @since 2.1
|
143 |
*/
|
144 |
public function __call( $name, $parameters ) {
|
145 |
// Check for the callback prefix in the method name
|
146 |
$name_parts = explode( self::DELIMITER, $name );
|
147 |
-
if( 0 !== strcmp( $name_parts[0] . self::DELIMITER, self::CALLBACK_PREFIX ) ) {
|
148 |
// Not a callback, resign.
|
149 |
return;
|
150 |
}
|
@@ -160,7 +229,7 @@ class Toolset_Ajax {
|
|
160 |
try {
|
161 |
/** @var Toolset_Ajax_Handler_Interface $handler */
|
162 |
$handler = new $class_name( $this );
|
163 |
-
} catch( Exception $e ) {
|
164 |
// The handler class could not have been instantiated, resign.
|
165 |
return;
|
166 |
}
|
@@ -170,7 +239,6 @@ class Toolset_Ajax {
|
|
170 |
}
|
171 |
|
172 |
|
173 |
-
|
174 |
/**
|
175 |
* Perform basic authentication check.
|
176 |
*
|
@@ -178,14 +246,17 @@ class Toolset_Ajax {
|
|
178 |
* is not successful.
|
179 |
*
|
180 |
* @param array $args Arguments (
|
181 |
-
*
|
182 |
-
*
|
|
|
183 |
* Optional, defaults to "wpnonce".
|
184 |
-
*
|
185 |
* Allowed values are 'get' and 'post'. Optional, defaults to 'post'.
|
186 |
-
*
|
187 |
* Optional, default is "manage_options".
|
188 |
-
*
|
|
|
|
|
189 |
* - 'die': Call wp_json_error with array( 'type' => 'capability'|'nonce', 'message' => $error_message )
|
190 |
* - 'return': Do not die, just return the error array as above.
|
191 |
* Optional, default is 'die'.
|
@@ -201,6 +272,7 @@ class Toolset_Ajax {
|
|
201 |
$nonce_name = toolset_getarr( $args, 'nonce' );
|
202 |
$nonce_parameter = toolset_getarr( $args, 'nonce_parameter', 'wpnonce' );
|
203 |
$capability_needed = toolset_getarr( $args, 'capability_needed', 'manage_options' );
|
|
|
204 |
$parameter_source_name = toolset_getarr( $args, 'parameter_source', 'post', array( 'get', 'post' ) );
|
205 |
$parameter_source = ( $parameter_source_name == 'get' ) ? $_GET : $_POST;
|
206 |
|
@@ -209,22 +281,22 @@ class Toolset_Ajax {
|
|
209 |
$error_type = null;
|
210 |
|
211 |
// Check permissions
|
212 |
-
if ( ! current_user_can( $capability_needed ) ) {
|
213 |
$error_message = __( 'You do not have permissions for that.', 'wpv-views' );
|
214 |
$error_type = 'capability';
|
215 |
$is_error = true;
|
216 |
}
|
217 |
|
218 |
// Check nonce
|
219 |
-
if (
|
220 |
$error_message = __( 'Your security credentials have expired. Please reload the page to get new ones.', 'wpv-views' );
|
221 |
$error_type = 'nonce';
|
222 |
$is_error = true;
|
223 |
}
|
224 |
|
225 |
-
if( $is_error ) {
|
226 |
$error_description = array( 'type' => $error_type, 'message' => $error_message );
|
227 |
-
switch( $type_of_death ) {
|
228 |
|
229 |
case 'die':
|
230 |
wp_send_json_error( $error_description );
|
@@ -246,6 +318,7 @@ class Toolset_Ajax {
|
|
246 |
* To be extended in the future.
|
247 |
*
|
248 |
* @param array $args See ajax_authenticate for details
|
|
|
249 |
* @return mixed
|
250 |
* @since 2.0
|
251 |
*/
|
@@ -263,10 +336,11 @@ class Toolset_Ajax {
|
|
263 |
*
|
264 |
* @param array $response Custom response data
|
265 |
* @param bool $is_success
|
|
|
266 |
* @since 2.0
|
267 |
*/
|
268 |
public function ajax_finish( $response, $is_success = true ) {
|
269 |
-
if( $is_success ) {
|
270 |
wp_send_json_success( $response );
|
271 |
} else {
|
272 |
wp_send_json_error( $response );
|
@@ -282,6 +356,7 @@ class Toolset_Ajax {
|
|
282 |
*
|
283 |
* @since m2m
|
284 |
*/
|
285 |
-
protected function additional_ajax_init() {
|
286 |
-
|
|
|
287 |
}
|
36 |
* @since m2m
|
37 |
*/
|
38 |
class Toolset_Ajax {
|
39 |
+
|
40 |
+
|
41 |
/** Prefix for the callback method name */
|
42 |
const CALLBACK_PREFIX = 'callback_';
|
43 |
+
|
44 |
+
|
45 |
const DELIMITER = '_';
|
46 |
|
47 |
+
|
48 |
+
private static $instance;
|
49 |
+
|
50 |
+
|
51 |
/**
|
52 |
* @return Toolset_Ajax|false
|
53 |
*/
|
54 |
+
public static function get_instance() {
|
55 |
+
if ( null === self::$instance ) {
|
56 |
+
self::$instance = new self();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
57 |
}
|
58 |
+
|
59 |
+
return self::$instance;
|
60 |
}
|
61 |
|
62 |
|
63 |
public static function initialize() {
|
64 |
+
$called_class = get_called_class();
|
65 |
+
/** @var Toolset_Ajax $instance */
|
66 |
+
$instance = call_user_func( array( $called_class, 'get_instance' ) );
|
67 |
|
68 |
$instance->register_callbacks();
|
69 |
$instance->additional_ajax_init();
|
70 |
}
|
71 |
|
72 |
|
73 |
+
const CALLBACK_MIGRATE_TO_M2M = 'migrate_to_m2m';
|
74 |
|
75 |
+
const CALLBACK_SELECT2_SUGGEST_POSTS_BY_TITLE = 'select2_suggest_posts_by_title';
|
76 |
|
77 |
+
const CALLBACK_SELECT2_SUGGEST_TERMS = 'select2_suggest_terms';
|
78 |
|
79 |
+
const CALLBACK_SELECT2_SUGGEST_USERS = 'select2_suggest_users';
|
80 |
+
|
81 |
+
const CALLBACK_GET_POST_BY_ID = 'get_post_by_id';
|
82 |
+
|
83 |
+
const CALLBACK_GET_TERM_BY_ID = 'get_term_by_id';
|
84 |
+
|
85 |
+
const CALLBACK_GET_USER_BY_ID = 'get_user_by_id';
|
86 |
+
|
87 |
+
const CALLBACK_GET_VIEW_BLOCK_PREVIEW = 'get_view_block_preview';
|
88 |
+
const CALLBACK_GET_CONTENT_TEMPLATE_BLOCK_PREVIEW = 'get_content_template_block_preview';
|
89 |
+
|
90 |
+
const CALLBACK_INTERMEDIARY_POST_CLEANUP = 'intermediary_post_cleanup';
|
91 |
|
|
|
|
|
92 |
|
93 |
protected function get_callback_names() {
|
94 |
return array(
|
95 |
+
self::CALLBACK_MIGRATE_TO_M2M,
|
96 |
+
self::CALLBACK_INTERMEDIARY_POST_CLEANUP,
|
97 |
+
self::CALLBACK_GET_VIEW_BLOCK_PREVIEW,
|
98 |
+
self::CALLBACK_GET_CONTENT_TEMPLATE_BLOCK_PREVIEW,
|
99 |
+
);
|
100 |
+
}
|
101 |
+
|
102 |
+
|
103 |
+
protected function get_public_callback_names() {
|
104 |
+
return array(
|
105 |
+
self::CALLBACK_SELECT2_SUGGEST_POSTS_BY_TITLE,
|
106 |
+
self::CALLBACK_SELECT2_SUGGEST_TERMS,
|
107 |
+
self::CALLBACK_SELECT2_SUGGEST_USERS,
|
108 |
+
self::CALLBACK_GET_POST_BY_ID,
|
109 |
+
self::CALLBACK_GET_TERM_BY_ID,
|
110 |
+
self::CALLBACK_GET_USER_BY_ID,
|
111 |
);
|
112 |
}
|
113 |
|
114 |
|
115 |
+
protected $callbacks_registered = false;
|
116 |
+
|
117 |
+
|
118 |
+
/**
|
119 |
+
* Register privileged callbacks.
|
120 |
+
*
|
121 |
+
* Each callback is registered as a "{$plugin_slug}_{$callback}" action and needs to have a "callback_{$callback_name}"
|
122 |
+
* method in this class.
|
123 |
+
*
|
124 |
+
* Valid for AJAX callbacks executed by logged in users.
|
125 |
+
*
|
126 |
+
* @since m2m
|
127 |
+
*
|
128 |
+
* @param string[] $callback_names
|
129 |
+
*/
|
130 |
+
private function register_priv_callbacks( $callback_names ) {
|
131 |
+
foreach ( $callback_names as $callback_name ) {
|
132 |
+
$action_name = 'wp_ajax_' . $this->get_plugin_slug() . self::DELIMITER . $callback_name;
|
133 |
+
add_action(
|
134 |
+
$action_name,
|
135 |
+
array( $this, self::CALLBACK_PREFIX . $callback_name )
|
136 |
+
);
|
137 |
+
}
|
138 |
+
}
|
139 |
+
|
140 |
+
|
141 |
+
/**
|
142 |
+
* Register unprivileged callbacks.
|
143 |
+
*
|
144 |
+
* Each callback is registered as a "{$plugin_slug}_{$callback}" action and needs to have a "callback_{$callback_name}"
|
145 |
+
* method in this class.
|
146 |
+
*
|
147 |
+
* Valid for AJAX callbacks executed by not logged in users.
|
148 |
+
*
|
149 |
+
* @since m2m
|
150 |
+
*
|
151 |
+
* @param string[] $callback_names
|
152 |
+
*/
|
153 |
+
private function register_nopriv_callbacks( $callback_names ) {
|
154 |
+
foreach ( $callback_names as $callback_name ) {
|
155 |
+
$action_name = 'wp_ajax_nopriv_' . $this->get_plugin_slug() . self::DELIMITER . $callback_name;
|
156 |
+
add_action(
|
157 |
+
$action_name,
|
158 |
+
array( $this, self::CALLBACK_PREFIX . $callback_name )
|
159 |
+
);
|
160 |
+
}
|
161 |
+
}
|
162 |
|
163 |
|
164 |
/**
|
171 |
*/
|
172 |
private function register_callbacks() {
|
173 |
|
174 |
+
if ( $this->callbacks_registered ) {
|
175 |
return;
|
176 |
}
|
177 |
|
178 |
$callback_names = $this->get_callback_names();
|
179 |
+
$this->register_priv_callbacks( $callback_names );
|
180 |
+
|
181 |
+
$public_callback_names = $this->get_public_callback_names();
|
182 |
+
$this->register_priv_callbacks( $public_callback_names );
|
183 |
+
$this->register_nopriv_callbacks( $public_callback_names );
|
|
|
|
|
184 |
|
185 |
$this->callbacks_registered = true;
|
186 |
|
187 |
}
|
188 |
+
|
189 |
+
|
190 |
protected function get_plugin_slug( $capitalized = false ) {
|
191 |
return ( $capitalized ? 'Toolset' : 'toolset' );
|
192 |
}
|
193 |
+
|
194 |
+
|
195 |
protected function get_handler_class_prefix() {
|
196 |
+
return $this->get_plugin_slug( true ) . '_Ajax_Handler_';
|
197 |
}
|
198 |
|
199 |
+
|
200 |
public function get_action_js_name( $action ) {
|
201 |
return $this->get_plugin_slug( false ) . self::DELIMITER . $action;
|
202 |
}
|
207 |
*
|
208 |
* @param string $name Method name.
|
209 |
* @param array $parameters Method parameters.
|
210 |
+
*
|
211 |
* @since 2.1
|
212 |
*/
|
213 |
public function __call( $name, $parameters ) {
|
214 |
// Check for the callback prefix in the method name
|
215 |
$name_parts = explode( self::DELIMITER, $name );
|
216 |
+
if ( 0 !== strcmp( $name_parts[0] . self::DELIMITER, self::CALLBACK_PREFIX ) ) {
|
217 |
// Not a callback, resign.
|
218 |
return;
|
219 |
}
|
229 |
try {
|
230 |
/** @var Toolset_Ajax_Handler_Interface $handler */
|
231 |
$handler = new $class_name( $this );
|
232 |
+
} catch ( Exception $e ) {
|
233 |
// The handler class could not have been instantiated, resign.
|
234 |
return;
|
235 |
}
|
239 |
}
|
240 |
|
241 |
|
|
|
242 |
/**
|
243 |
* Perform basic authentication check.
|
244 |
*
|
246 |
* is not successful.
|
247 |
*
|
248 |
* @param array $args Arguments (
|
249 |
+
*
|
250 |
+
* @type string $nonce Name of the nonce that should be verified. Mandatory
|
251 |
+
* @type string $nonce_parameter Name of the parameter containing nonce value.
|
252 |
* Optional, defaults to "wpnonce".
|
253 |
+
* @type string $parameter_source Determines where the function should look for the nonce parameter.
|
254 |
* Allowed values are 'get' and 'post'. Optional, defaults to 'post'.
|
255 |
+
* @type string $capability_needed Capability that user has to have in order to pass the check.
|
256 |
* Optional, default is "manage_options".
|
257 |
+
* @type bool $is_public Whether the action is publicly available without capability checks.
|
258 |
+
* Optional, default is FALSE.
|
259 |
+
* @type string $type_of_death How to indicate failure:
|
260 |
* - 'die': Call wp_json_error with array( 'type' => 'capability'|'nonce', 'message' => $error_message )
|
261 |
* - 'return': Do not die, just return the error array as above.
|
262 |
* Optional, default is 'die'.
|
272 |
$nonce_name = toolset_getarr( $args, 'nonce' );
|
273 |
$nonce_parameter = toolset_getarr( $args, 'nonce_parameter', 'wpnonce' );
|
274 |
$capability_needed = toolset_getarr( $args, 'capability_needed', 'manage_options' );
|
275 |
+
$is_public = toolset_getarr( $args, 'is_public', false );
|
276 |
$parameter_source_name = toolset_getarr( $args, 'parameter_source', 'post', array( 'get', 'post' ) );
|
277 |
$parameter_source = ( $parameter_source_name == 'get' ) ? $_GET : $_POST;
|
278 |
|
281 |
$error_type = null;
|
282 |
|
283 |
// Check permissions
|
284 |
+
if ( ! $is_public && ! current_user_can( $capability_needed ) ) {
|
285 |
$error_message = __( 'You do not have permissions for that.', 'wpv-views' );
|
286 |
$error_type = 'capability';
|
287 |
$is_error = true;
|
288 |
}
|
289 |
|
290 |
// Check nonce
|
291 |
+
if ( ! $is_error && ! wp_verify_nonce( toolset_getarr( $parameter_source, $nonce_parameter, '' ), $nonce_name ) ) {
|
292 |
$error_message = __( 'Your security credentials have expired. Please reload the page to get new ones.', 'wpv-views' );
|
293 |
$error_type = 'nonce';
|
294 |
$is_error = true;
|
295 |
}
|
296 |
|
297 |
+
if ( $is_error ) {
|
298 |
$error_description = array( 'type' => $error_type, 'message' => $error_message );
|
299 |
+
switch ( $type_of_death ) {
|
300 |
|
301 |
case 'die':
|
302 |
wp_send_json_error( $error_description );
|
318 |
* To be extended in the future.
|
319 |
*
|
320 |
* @param array $args See ajax_authenticate for details
|
321 |
+
*
|
322 |
* @return mixed
|
323 |
* @since 2.0
|
324 |
*/
|
336 |
*
|
337 |
* @param array $response Custom response data
|
338 |
* @param bool $is_success
|
339 |
+
*
|
340 |
* @since 2.0
|
341 |
*/
|
342 |
public function ajax_finish( $response, $is_success = true ) {
|
343 |
+
if ( $is_success ) {
|
344 |
wp_send_json_success( $response );
|
345 |
} else {
|
346 |
wp_send_json_error( $response );
|
356 |
*
|
357 |
* @since m2m
|
358 |
*/
|
359 |
+
protected function additional_ajax_init() {
|
360 |
+
}
|
361 |
+
|
362 |
}
|
vendor/toolset/toolset-common/inc/toolset.assets.manager.class.php
CHANGED
@@ -134,7 +134,7 @@ class Toolset_Script {
|
|
134 |
class Toolset_Assets_Manager {
|
135 |
|
136 |
|
137 |
-
|
138 |
|
139 |
|
140 |
protected $styles = array();
|
@@ -172,6 +172,8 @@ class Toolset_Assets_Manager {
|
|
172 |
|
173 |
const SCRIPT_ICL_EDITOR = 'icl_editor-script';
|
174 |
const SCRIPT_ICL_MEDIA_MANAGER = 'icl_media-manager-js';
|
|
|
|
|
175 |
|
176 |
const SCRIPT_KNOCKOUT = 'knockout';
|
177 |
const SCRIPT_KNOCKOUT_MAPPING = 'knockout-mapping';
|
@@ -193,6 +195,10 @@ class Toolset_Assets_Manager {
|
|
193 |
const SCRIPT_CHOSEN = 'toolset-chosen';
|
194 |
const SCRIPT_CHOSEN_WRAPPER = 'toolset-chosen-wrapper';
|
195 |
|
|
|
|
|
|
|
|
|
196 |
/**
|
197 |
* For compatibility with ACF Plugin that's not using the right handle for this module (wp-event-manager)
|
198 |
* we are using ACF handle to prevent unwanted overrides of window.wp.hooks namespace (******!)
|
@@ -205,6 +211,8 @@ class Toolset_Assets_Manager {
|
|
205 |
//
|
206 |
//
|
207 |
|
|
|
|
|
208 |
const STYLE_CODEMIRROR = 'toolset-meta-html-codemirror-css';
|
209 |
const STYLE_CODEMIRROR_CSS_HINT = 'toolset-meta-html-codemirror-css-hint-css';
|
210 |
|
@@ -305,8 +313,17 @@ class Toolset_Assets_Manager {
|
|
305 |
}
|
306 |
|
307 |
|
|
|
|
|
|
|
|
|
|
|
308 |
public static function get_instance() {
|
309 |
-
|
|
|
|
|
|
|
|
|
310 |
}
|
311 |
|
312 |
|
@@ -390,6 +407,13 @@ class Toolset_Assets_Manager {
|
|
390 |
"5.5.0"
|
391 |
);
|
392 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
393 |
$this->register_style(
|
394 |
self::STYLE_COLORBOX,
|
395 |
$this->assets_url . '/res/lib/colorbox/colorbox.css',
|
@@ -549,6 +573,14 @@ class Toolset_Assets_Manager {
|
|
549 |
true
|
550 |
);
|
551 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
552 |
$this->register_script(
|
553 |
self::SCRIPT_CHOSEN,
|
554 |
$this->assets_url . "/res/lib/chosen/chosen.jquery.js",
|
@@ -706,6 +738,13 @@ class Toolset_Assets_Manager {
|
|
706 |
array( self::SCRIPT_ICL_EDITOR ),
|
707 |
TOOLSET_COMMON_VERSION
|
708 |
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
709 |
|
710 |
$this->register_script(
|
711 |
self::SCRIPT_JSCROLLPANE,
|
@@ -909,6 +948,15 @@ class Toolset_Assets_Manager {
|
|
909 |
}
|
910 |
|
911 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
912 |
public function register_script( $handle, $path = '', $deps = array(), $ver = false, $in_footer = false ) {
|
913 |
if ( ! isset( $this->scripts[ $handle ] ) ) {
|
914 |
$this->scripts[ $handle ] = new Toolset_Script( $handle, $path, $deps, $ver, $in_footer );
|
134 |
class Toolset_Assets_Manager {
|
135 |
|
136 |
|
137 |
+
private static $instance;
|
138 |
|
139 |
|
140 |
protected $styles = array();
|
172 |
|
173 |
const SCRIPT_ICL_EDITOR = 'icl_editor-script';
|
174 |
const SCRIPT_ICL_MEDIA_MANAGER = 'icl_media-manager-js';
|
175 |
+
|
176 |
+
const SCRIPT_TOOLSET_MEDIA_MANAGER = 'toolset-media-manager-js';
|
177 |
|
178 |
const SCRIPT_KNOCKOUT = 'knockout';
|
179 |
const SCRIPT_KNOCKOUT_MAPPING = 'knockout-mapping';
|
195 |
const SCRIPT_CHOSEN = 'toolset-chosen';
|
196 |
const SCRIPT_CHOSEN_WRAPPER = 'toolset-chosen-wrapper';
|
197 |
|
198 |
+
// parsley lib for field validation
|
199 |
+
const SCRIPT_PARSLEY = 'toolset-parsley';
|
200 |
+
|
201 |
+
|
202 |
/**
|
203 |
* For compatibility with ACF Plugin that's not using the right handle for this module (wp-event-manager)
|
204 |
* we are using ACF handle to prevent unwanted overrides of window.wp.hooks namespace (******!)
|
211 |
//
|
212 |
//
|
213 |
|
214 |
+
const STYLE_PARSLEY = 'toolset-parsley-style';
|
215 |
+
|
216 |
const STYLE_CODEMIRROR = 'toolset-meta-html-codemirror-css';
|
217 |
const STYLE_CODEMIRROR_CSS_HINT = 'toolset-meta-html-codemirror-css-hint-css';
|
218 |
|
313 |
}
|
314 |
|
315 |
|
316 |
+
/**
|
317 |
+
* Note: This *can not* be directly used in subclasses.
|
318 |
+
*
|
319 |
+
* @return Toolset_Assets_Manager
|
320 |
+
*/
|
321 |
public static function get_instance() {
|
322 |
+
if( null === self::$instance ) {
|
323 |
+
self::$instance = new self();
|
324 |
+
}
|
325 |
+
|
326 |
+
return self::$instance;
|
327 |
}
|
328 |
|
329 |
|
407 |
"5.5.0"
|
408 |
);
|
409 |
|
410 |
+
$this->register_style(
|
411 |
+
self::STYLE_PARSLEY,
|
412 |
+
$this->assets_url . '/res/lib/parsley/parsley.css',
|
413 |
+
array(),
|
414 |
+
'2.8.0'
|
415 |
+
);
|
416 |
+
|
417 |
$this->register_style(
|
418 |
self::STYLE_COLORBOX,
|
419 |
$this->assets_url . '/res/lib/colorbox/colorbox.css',
|
573 |
true
|
574 |
);
|
575 |
|
576 |
+
$this->register_script(
|
577 |
+
self::SCRIPT_PARSLEY,
|
578 |
+
$this->assets_url . '/res/lib/parsley/parsley.js',
|
579 |
+
array('jquery'),
|
580 |
+
'2.8.0',
|
581 |
+
true
|
582 |
+
);
|
583 |
+
|
584 |
$this->register_script(
|
585 |
self::SCRIPT_CHOSEN,
|
586 |
$this->assets_url . "/res/lib/chosen/chosen.jquery.js",
|
738 |
array( self::SCRIPT_ICL_EDITOR ),
|
739 |
TOOLSET_COMMON_VERSION
|
740 |
);
|
741 |
+
|
742 |
+
$this->register_script(
|
743 |
+
self::SCRIPT_TOOLSET_MEDIA_MANAGER,
|
744 |
+
$this->assets_url . "/res/js/toolset-media-manager.js",
|
745 |
+
array( self::SCRIPT_ICL_EDITOR, self::SCRIPT_TOOLSET_EVENT_MANAGER ),
|
746 |
+
TOOLSET_COMMON_VERSION
|
747 |
+
);
|
748 |
|
749 |
$this->register_script(
|
750 |
self::SCRIPT_JSCROLLPANE,
|
948 |
}
|
949 |
|
950 |
|
951 |
+
public function add_script( Toolset_Script $script ) {
|
952 |
+
if( isset( $this->scripts[ $script->handle ] ) ) {
|
953 |
+
return;
|
954 |
+
}
|
955 |
+
|
956 |
+
$this->scripts[ $script->handle ] = $script;
|
957 |
+
}
|
958 |
+
|
959 |
+
|
960 |
public function register_script( $handle, $path = '', $deps = array(), $ver = false, $in_footer = false ) {
|
961 |
if ( ! isset( $this->scripts[ $handle ] ) ) {
|
962 |
$this->scripts[ $handle ] = new Toolset_Script( $handle, $path, $deps, $ver, $in_footer );
|
vendor/toolset/toolset-common/inc/toolset.css.component.class.php
CHANGED
@@ -305,7 +305,8 @@ if ( ! class_exists( 'Toolset_CssComponent' ) ) {
|
|
305 |
'dd_layouts_edit',
|
306 |
'views-editor',
|
307 |
'ct-editor',
|
308 |
-
'view-archives-editor'
|
|
|
309 |
);
|
310 |
|
311 |
|
305 |
'dd_layouts_edit',
|
306 |
'views-editor',
|
307 |
'ct-editor',
|
308 |
+
'view-archives-editor',
|
309 |
+
'cred_association_form'
|
310 |
);
|
311 |
|
312 |
|
vendor/toolset/toolset-common/inc/toolset.menu.class.php
CHANGED
@@ -22,6 +22,9 @@ if ( ! class_exists( 'Toolset_Menu', false ) ) {
|
|
22 |
*/
|
23 |
class Toolset_Menu {
|
24 |
|
|
|
|
|
|
|
25 |
public $toolset_pages;
|
26 |
|
27 |
public function __construct() {
|
@@ -32,7 +35,6 @@ if ( ! class_exists( 'Toolset_Menu', false ) ) {
|
|
32 |
add_action( 'admin_init', array( &$this, 'admin_init' ), 1 );
|
33 |
add_action( 'admin_menu', array( &$this, 'admin_menu' ) );
|
34 |
add_action( 'admin_enqueue_scripts', array( &$this, 'admin_enqueue_scripts' ) );
|
35 |
-
|
36 |
add_filter( 'toolset_filter_register_menu_pages', array( &$this, 'register_debug_page_in_menu' ), 100 );
|
37 |
}
|
38 |
|
@@ -96,7 +98,6 @@ if ( ! class_exists( 'Toolset_Menu', false ) ) {
|
|
96 |
$this->add_submenu_page( $page, $top_level_page );
|
97 |
}
|
98 |
}
|
99 |
-
|
100 |
}
|
101 |
}
|
102 |
|
@@ -238,10 +239,10 @@ if ( ! class_exists( 'Toolset_Menu', false ) ) {
|
|
238 |
public function register_debug_page_in_menu( $pages ) {
|
239 |
if (
|
240 |
isset( $_GET['page'] )
|
241 |
-
&& $_GET['page']
|
242 |
) {
|
243 |
$pages[] = array(
|
244 |
-
'slug' =>
|
245 |
'menu_title' => __( 'Toolset Debug', 'wpv-views' ),
|
246 |
'page_title' => __( 'Toolset Debug', 'wpv-views' ),
|
247 |
'callback' => array( $this, 'debug_page' )
|
@@ -256,10 +257,9 @@ if ( ! class_exists( 'Toolset_Menu', false ) ) {
|
|
256 |
return $pages;
|
257 |
}
|
258 |
|
259 |
-
public function debug_page() {
|
260 |
|
|
|
261 |
$page = Toolset_Page_Troubleshooting::get_instance();
|
262 |
-
|
263 |
$page->render();
|
264 |
}
|
265 |
|
22 |
*/
|
23 |
class Toolset_Menu {
|
24 |
|
25 |
+
|
26 |
+
const TROUBLESHOOTING_PAGE_SLUG = 'toolset-debug-information';
|
27 |
+
|
28 |
public $toolset_pages;
|
29 |
|
30 |
public function __construct() {
|
35 |
add_action( 'admin_init', array( &$this, 'admin_init' ), 1 );
|
36 |
add_action( 'admin_menu', array( &$this, 'admin_menu' ) );
|
37 |
add_action( 'admin_enqueue_scripts', array( &$this, 'admin_enqueue_scripts' ) );
|
|
|
38 |
add_filter( 'toolset_filter_register_menu_pages', array( &$this, 'register_debug_page_in_menu' ), 100 );
|
39 |
}
|
40 |
|
98 |
$this->add_submenu_page( $page, $top_level_page );
|
99 |
}
|
100 |
}
|
|
|
101 |
}
|
102 |
}
|
103 |
|
239 |
public function register_debug_page_in_menu( $pages ) {
|
240 |
if (
|
241 |
isset( $_GET['page'] )
|
242 |
+
&& $_GET['page'] === self::TROUBLESHOOTING_PAGE_SLUG
|
243 |
) {
|
244 |
$pages[] = array(
|
245 |
+
'slug' => self::TROUBLESHOOTING_PAGE_SLUG,
|
246 |
'menu_title' => __( 'Toolset Debug', 'wpv-views' ),
|
247 |
'page_title' => __( 'Toolset Debug', 'wpv-views' ),
|
248 |
'callback' => array( $this, 'debug_page' )
|
257 |
return $pages;
|
258 |
}
|
259 |
|
|
|
260 |
|
261 |
+
public function debug_page() {
|
262 |
$page = Toolset_Page_Troubleshooting::get_instance();
|
|
|
263 |
$page->render();
|
264 |
}
|
265 |
|
vendor/toolset/toolset-common/inc/toolset.shortcode.generator.class.php
CHANGED
@@ -43,11 +43,6 @@ abstract class Toolset_Shortcode_Generator {
|
|
43 |
|
44 |
add_action( 'toolset_action_require_shortcodes_templates', array( $this, 'print_shortcodes_templates' ) );
|
45 |
|
46 |
-
add_action( 'wp_ajax_toolset_select2_suggest_posts_by_title', array( $this, 'toolset_select2_suggest_posts_by_title' ) );
|
47 |
-
add_action( 'wp_ajax_nopriv_toolset_select2_suggest_posts_by_title', array( $this, 'toolset_select2_suggest_posts_by_title' ) );
|
48 |
-
add_action( 'wp_ajax_toolset_select2_suggest_users', array( $this, 'toolset_select2_suggest_users' ) );
|
49 |
-
add_action( 'wp_ajax_nopriv_toolset_select2_suggest_users', array( $this, 'toolset_select2_suggest_users' ) );
|
50 |
-
|
51 |
add_filter( 'toolset_filter_shortcode_script_i18n', array( $this, 'extend_script_i18n' ) );
|
52 |
}
|
53 |
|
@@ -307,7 +302,7 @@ abstract class Toolset_Shortcode_Generator {
|
|
307 |
#>
|
308 |
<ul class="toolset-shortcode-gui-dialog-item-group js-toolset-shortcode-gui-dialog-item-group">
|
309 |
<# _.each( data.fields, function( fieldData, fieldAttribute ) { #>
|
310 |
-
<li style="width:<# print( columnsWidth ); #>%;float:left;">
|
311 |
<#
|
312 |
fieldData = _.defaults( fieldData, { shortcode: data.shortcode, templates: data.templates } );
|
313 |
fieldData = _.defaults( fieldData, { defaultValue: '', required: false, hidden: false, placeholder: '' } );
|
@@ -323,6 +318,11 @@ abstract class Toolset_Shortcode_Generator {
|
|
323 |
<# } #>
|
324 |
</div>
|
325 |
</script>
|
|
|
|
|
|
|
|
|
|
|
326 |
<script type="text/html" id="tmpl-toolset-shortcode-attribute-text">
|
327 |
<input id="{{{data.shortcode}}}-{{{data.attribute}}}" data-type="text" class="js-shortcode-gui-field large-text<# if ( data.required ) { #> js-toolset-shortcode-gui-required<# } #>" value="{{{data.defaultForceValue}}}" placeholder="{{{data.placeholder}}}" type="text">
|
328 |
</script>
|
@@ -333,13 +333,13 @@ abstract class Toolset_Shortcode_Generator {
|
|
333 |
<label>
|
334 |
<input name="{{{data.shortcode}}}-{{{data.attribute}}}" value="{{{optionKey}}}" class="js-shortcode-gui-field" type="radio"<# if ( optionKey == data.defaultForceValue ) { #> checked="checked"<# } #>>
|
335 |
{{{optionLabel}}}
|
336 |
-
</
|
337 |
</li>
|
338 |
<# }); #>
|
339 |
</ul>
|
340 |
</script>
|
341 |
<script type="text/html" id="tmpl-toolset-shortcode-attribute-select">
|
342 |
-
<select id="{{{data.shortcode}}}-{{{data.attribute}}}" class="js-shortcode-gui-field">
|
343 |
<# _.each( data.options, function( optionLabel, optionKey ) { #>
|
344 |
<option value="{{{optionKey}}}"<# if ( optionKey == data.defaultForceValue ) { #> selected="selected"<# } #>>
|
345 |
{{{optionLabel}}}
|
@@ -375,20 +375,19 @@ abstract class Toolset_Shortcode_Generator {
|
|
375 |
|
376 |
<script type="text/html" id="tmpl-toolset-shortcode-content">
|
377 |
<#
|
378 |
-
data = _.defaults( data, { defaultValue: '', required: false, hidden: false, placeholder: '' } );
|
379 |
-
data = _.defaults( data, { defaultForceValue: data.defaultValue } );
|
380 |
#>
|
381 |
<div class="toolset-shortcode-gui-attribute-wrapper js-toolset-shortcode-gui-content-wrapper" <# if ( data.hidden ) { #> style="display:none"<# } #>>
|
382 |
-
|
383 |
-
<h3>{{{data.label}}}</h3>
|
384 |
-
<# } #>
|
385 |
-
<textarea id="toolset-shortcode-gui-content-{{{data.shortcode}}}" type="text" class="large-text js-toolset-shortcode-gui-content"><# {{{data.defaultValue}}} #></textarea>
|
386 |
<# if ( _.has( data, 'description' ) ) { #>
|
387 |
<p class="description">{{{data.description}}}</p>
|
388 |
<# } #>
|
389 |
</div>
|
390 |
</script>
|
391 |
|
|
|
|
|
392 |
<script type="text/html" id="tmpl-toolset-shortcode-attribute-postSelector">
|
393 |
<ul id="{{{data.shortcode}}}-{{{data.attribute}}}">
|
394 |
<li class="toolset-shortcode-gui-item-selector-option">
|
@@ -449,7 +448,7 @@ abstract class Toolset_Shortcode_Generator {
|
|
449 |
<li class="toolset-shortcode-gui-item-selector-option toolset-shortcode-gui-item-selector-has-related js-toolset-shortcode-gui-item-selector-has-related">
|
450 |
<label for="toolset-shortcode-gui-item-selector-post-id-related">
|
451 |
<input type="radio" class="js-toolset-shortcode-gui-item-selector" id="toolset-shortcode-gui-item-selector-post-id-related" name="toolset_shortcode_gui_object_id" value="related" />
|
452 |
-
<?php echo __( 'The parent of the current post in another post type, set by Types relationship', 'wpv-views' ); ?>
|
453 |
</label>
|
454 |
<div class="toolset-shortcode-gui-item-selector-is-related js-toolset-shortcode-gui-item-selector-is-related" style="display:none">
|
455 |
<ul class="toolset-advanced-setting tolset-mightlong-list" style="padding-top:15px;margin:5px 0 10px;">
|
@@ -461,11 +460,11 @@ abstract class Toolset_Shortcode_Generator {
|
|
461 |
<?php echo sprintf( '<label for="toolset-shortcode-gui-item-selector-post-relationship-id-%s">', $slug ); ?>
|
462 |
<?php echo sprintf(
|
463 |
'<input type="radio" name="related_object" id="toolset-shortcode-gui-item-selector-post-relationship-id-%s" value="$%s" %s />',
|
464 |
-
$slug,
|
465 |
-
$slug,
|
466 |
-
$first
|
467 |
); ?>
|
468 |
-
<?php echo $custom_post_types_relations[ $slug ]['labels']['singular_name']; ?>
|
469 |
</label>
|
470 |
</li>
|
471 |
<?php
|
@@ -481,30 +480,65 @@ abstract class Toolset_Shortcode_Generator {
|
|
481 |
} else {
|
482 |
// m2m relationships
|
483 |
// Make sure m2m classes are registered in the autoloader
|
|
|
484 |
$current_post_type_relationships = $this->get_m2m_current_post_type_relationships( $current_post_type );
|
485 |
|
486 |
-
if ( ! empty( $current_post_type_relationships ) ) {
|
487 |
?>
|
488 |
<li class="toolset-shortcode-gui-item-selector-option toolset-shortcode-gui-item-selector-has-related js-toolset-shortcode-gui-item-selector-has-related">
|
489 |
<label for="toolset-shortcode-gui-item-selector-post-id-related">
|
490 |
<input type="radio" class="js-toolset-shortcode-gui-item-selector" id="toolset-shortcode-gui-item-selector-post-id-related" name="toolset_shortcode_gui_object_id" value="related" />
|
491 |
-
<?php echo __( '
|
492 |
</label>
|
493 |
<div class="toolset-shortcode-gui-item-selector-is-related js-toolset-shortcode-gui-item-selector-is-related" style="display:none">
|
494 |
<ul class="toolset-advanced-setting toolset-mightlong-list" style="padding-top:15px;margin:5px 0 10px;">
|
495 |
<?php
|
496 |
$first = true;
|
497 |
-
foreach ( $current_post_type_relationships as $relationship_data ) {
|
498 |
?>
|
499 |
<li>
|
500 |
<?php echo sprintf( '<label for="toolset-shortcode-gui-item-selector-post-relationship-id-%s">', $relationship_data['id'] ); ?>
|
501 |
<?php echo sprintf(
|
502 |
'<input type="radio" name="related_object" id="toolset-shortcode-gui-item-selector-post-relationship-id-%s" value="%s" %s />',
|
503 |
-
$relationship_data['id'],
|
504 |
-
$relationship_data['value'],
|
505 |
-
$first
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
506 |
); ?>
|
507 |
-
<?php echo $relationship_data['name']; ?>
|
508 |
</label>
|
509 |
</li>
|
510 |
<?php
|
@@ -525,8 +559,16 @@ abstract class Toolset_Shortcode_Generator {
|
|
525 |
<input type="radio" class="js-toolset-shortcode-gui-item-selector" id="toolset-shortcode-gui-item-selector-post-id" name="toolset_shortcode_gui_object_id" value="object_id" />
|
526 |
<?php _e( 'A specific post', 'wpv-views' ); ?>
|
527 |
</label>
|
528 |
-
<div class="toolset-shortcode-gui-item-selector-is-related js-toolset-shortcode-gui-item-selector-is-related" style="display:none">
|
529 |
-
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
530 |
</div>
|
531 |
</li>
|
532 |
</ul>
|
@@ -553,8 +595,16 @@ abstract class Toolset_Shortcode_Generator {
|
|
553 |
<input type="radio" class="js-toolset-shortcode-gui-item-selector" id="toolset-shortcode-gui-item-selector-user-id" name="toolset_shortcode_gui_object_id" value="object_id" />
|
554 |
<?php _e( 'A specific user', 'wpv-views' ); ?>
|
555 |
</label>
|
556 |
-
<div class="toolset-shortcode-gui-item-selector-is-related js-toolset-shortcode-gui-item-selector-is-related" style="display:none">
|
557 |
-
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
558 |
</div>
|
559 |
</li>
|
560 |
</ul>
|
@@ -570,9 +620,9 @@ abstract class Toolset_Shortcode_Generator {
|
|
570 |
isset( $_GET['page'] )
|
571 |
&& in_array( $_GET['page'], array( 'views-editor', 'view-archives-editor' ) )
|
572 |
) {
|
573 |
-
_e( '
|
574 |
} else {
|
575 |
-
_e( '
|
576 |
}
|
577 |
?>
|
578 |
</label>
|
@@ -580,9 +630,16 @@ abstract class Toolset_Shortcode_Generator {
|
|
580 |
<li class="js-toolset-shortcode-gui-item-selector-has-related">
|
581 |
<label>
|
582 |
<input type="radio" name="{{{data.shortcode}}}-select-target-post" class="toolset-shortcode-gui-item-selector js-toolset-shortcode-gui-item-selector" value="object_id" />
|
583 |
-
<?php _e( '
|
584 |
<div class="toolset-shortcode-gui-item-selector-is-related js-toolset-shortcode-gui-item-selector-is-related" style="display:none">
|
585 |
-
<select id="toolset-shortcode-gui-item-selector-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
586 |
</select>
|
587 |
</div>
|
588 |
</label>
|
@@ -594,15 +651,22 @@ abstract class Toolset_Shortcode_Generator {
|
|
594 |
<li>
|
595 |
<label>
|
596 |
<input type="radio" name="{{{data.shortcode}}}-select-target-user" class="toolset-shortcode-gui-item-selector js-toolset-shortcode-gui-item-selector" value="current" checked="checked" />
|
597 |
-
<?php _e( '
|
598 |
</label>
|
599 |
</li>
|
600 |
<li class="js-toolset-shortcode-gui-item-selector-has-related">
|
601 |
<label>
|
602 |
<input type="radio" name="{{{data.shortcode}}}-select-target-user" class="toolset-shortcode-gui-item-selector js-toolset-shortcode-gui-item-selector" value="object_id" />
|
603 |
-
<?php _e( '
|
604 |
<div class="toolset-shortcode-gui-item-selector-is-related js-toolset-shortcode-gui-item-selector-is-related" style="display:none">
|
605 |
-
<select id="toolset-shortcode-gui-item-selector-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
606 |
</select>
|
607 |
</div>
|
608 |
</label>
|
@@ -685,7 +749,11 @@ abstract class Toolset_Shortcode_Generator {
|
|
685 |
&& is_array( $cptr_data['post_relationship']['belongs'] )
|
686 |
) {
|
687 |
$this_belongs = array_keys( $cptr_data['post_relationship']['belongs'] );
|
688 |
-
|
|
|
|
|
|
|
|
|
689 |
}
|
690 |
}
|
691 |
} else if (
|
@@ -728,6 +796,9 @@ abstract class Toolset_Shortcode_Generator {
|
|
728 |
/**
|
729 |
* Get Types one-to-many and one-to-one relationships for a given post type, or all the existing otherwise.
|
730 |
*
|
|
|
|
|
|
|
731 |
* @paran $current_post_type string|null
|
732 |
*
|
733 |
* @return array
|
@@ -735,13 +806,11 @@ abstract class Toolset_Shortcode_Generator {
|
|
735 |
* @since m2m
|
736 |
*/
|
737 |
public function get_m2m_current_post_type_relationships( $current_post_type ) {
|
738 |
-
$current_post_type_relationships = array(
|
739 |
-
|
740 |
-
|
741 |
-
|
742 |
-
}
|
743 |
|
744 |
-
do_action( 'toolset_do_m2m_full_init' );
|
745 |
$query = new Toolset_Relationship_Query_V2();
|
746 |
|
747 |
// Note that we can not use $query->do_if() because it actually runs both branches
|
@@ -753,7 +822,10 @@ abstract class Toolset_Shortcode_Generator {
|
|
753 |
$query->do_and(
|
754 |
$query->has_type( $current_post_type->name, new Toolset_Relationship_Role_Child() ),
|
755 |
$query->has_cardinality( $query->cardinality()->one_to_many() ),
|
756 |
-
$query->
|
|
|
|
|
|
|
757 |
),
|
758 |
$query->has_cardinality( $query->cardinality()->one_to_one() )
|
759 |
)
|
@@ -763,7 +835,10 @@ abstract class Toolset_Shortcode_Generator {
|
|
763 |
$relationship_definitions = $query
|
764 |
->add(
|
765 |
$query->do_and(
|
766 |
-
$query->
|
|
|
|
|
|
|
767 |
$query->do_or(
|
768 |
$query->has_cardinality( $query->cardinality()->one_to_many() ),
|
769 |
$query->has_cardinality( $query->cardinality()->one_to_one() )
|
@@ -787,131 +862,30 @@ abstract class Toolset_Shortcode_Generator {
|
|
787 |
|
788 |
$parents = $relationship_definition->get_parent_type()->get_types();
|
789 |
$parent = $parents[0];
|
|
|
790 |
|
791 |
-
$current_post_type_relationships[] = array(
|
792 |
'name' => $relationship_definition->get_display_name(),
|
793 |
'slug' => $relationship_definition->get_slug(),
|
794 |
'value' => '@' . $relationship_definition->get_slug() . '.'
|
795 |
-
. $
|
796 |
-
|
|
|
|
|
|
|
797 |
),
|
798 |
'id' => $relationship_definition->get_slug() . '-' . $parent,
|
799 |
-
'role_name' => $
|
800 |
-
|
|
|
|
|
|
|
801 |
)
|
802 |
);
|
803 |
}
|
804 |
|
805 |
return $current_post_type_relationships;
|
806 |
}
|
807 |
-
|
808 |
-
public function toolset_select2_suggest_posts_by_title() {
|
809 |
-
if ( ! isset( $_POST['s'] ) ) {
|
810 |
-
$output = array(
|
811 |
-
'message' => __( 'Wrong or missing query.', 'wpv-views' ),
|
812 |
-
);
|
813 |
-
wp_send_json_error( $output );
|
814 |
-
}
|
815 |
-
|
816 |
-
global $wpdb;
|
817 |
-
|
818 |
-
if ( method_exists( $wpdb, 'esc_like' ) ) {
|
819 |
-
$s = '%' . $wpdb->esc_like( $_POST['s'] ) . '%';
|
820 |
-
} else {
|
821 |
-
$s = '%' . like_escape( esc_sql( $_POST['s'] ) ) . '%';
|
822 |
-
}
|
823 |
-
|
824 |
-
$toolset_post_type_exclude = new Toolset_Post_Type_Exclude_List();
|
825 |
-
$toolset_post_type_exclude_list = $toolset_post_type_exclude->get();
|
826 |
-
$toolset_post_type_exclude_list_string = "'" . implode( "', '", $toolset_post_type_exclude_list ) . "'";
|
827 |
-
|
828 |
-
$results = $wpdb->get_results(
|
829 |
-
$wpdb->prepare(
|
830 |
-
"SELECT ID, post_type, post_title
|
831 |
-
FROM {$wpdb->posts}
|
832 |
-
WHERE post_title LIKE %s
|
833 |
-
AND post_status = %s
|
834 |
-
AND post_type NOT IN ( {$toolset_post_type_exclude_list_string} )
|
835 |
-
LIMIT 0, 15",
|
836 |
-
$s,
|
837 |
-
'publish'
|
838 |
-
)
|
839 |
-
);
|
840 |
-
|
841 |
-
if (
|
842 |
-
isset( $results )
|
843 |
-
&& ! empty( $results )
|
844 |
-
) {
|
845 |
-
$output = array();
|
846 |
-
if ( is_array( $results ) ) {
|
847 |
-
foreach ( $results as $result ) {
|
848 |
-
$output[] = array(
|
849 |
-
'text' => $result->post_title . ' (' . $result->post_type . ')',
|
850 |
-
'id' => $result->ID,
|
851 |
-
);
|
852 |
-
}
|
853 |
-
wp_send_json_success( $output );
|
854 |
-
}
|
855 |
-
} else {
|
856 |
-
$output = array(
|
857 |
-
'message' => __( 'Error while retrieving result.', 'wpv-views' ),
|
858 |
-
);
|
859 |
-
wp_send_json_error( $output );
|
860 |
-
}
|
861 |
-
}
|
862 |
-
|
863 |
-
public function toolset_select2_suggest_users() {
|
864 |
-
if ( ! isset( $_POST['s'] ) ) {
|
865 |
-
$output = array(
|
866 |
-
'message' => __( 'Wrong or missing query.', 'wpv-views' ),
|
867 |
-
);
|
868 |
-
wp_send_json_error( $output );
|
869 |
-
}
|
870 |
-
|
871 |
-
global $wpdb;
|
872 |
-
|
873 |
-
|
874 |
-
if ( method_exists( $wpdb, 'esc_like' ) ) {
|
875 |
-
$s = '%' . $wpdb->esc_like( $_POST['s'] ) . '%';
|
876 |
-
} else {
|
877 |
-
$s = '%' . like_escape( esc_sql( $_POST['s'] ) ) . '%';
|
878 |
-
}
|
879 |
-
|
880 |
-
$results = $wpdb->get_results(
|
881 |
-
$wpdb->prepare(
|
882 |
-
"SELECT ID, display_name
|
883 |
-
FROM {$wpdb->users}
|
884 |
-
WHERE display_name LIKE %s
|
885 |
-
OR user_login LIKE %s
|
886 |
-
OR user_nicename LIKE %s
|
887 |
-
LIMIT 0, 15",
|
888 |
-
$s,
|
889 |
-
$s,
|
890 |
-
$s
|
891 |
-
)
|
892 |
-
);
|
893 |
-
|
894 |
-
if (
|
895 |
-
isset( $results )
|
896 |
-
&& ! empty( $results )
|
897 |
-
) {
|
898 |
-
$output = array();
|
899 |
-
if ( is_array( $results ) ) {
|
900 |
-
foreach ( $results as $result ) {
|
901 |
-
$output[] = array(
|
902 |
-
'text' => $result->display_name,
|
903 |
-
'id' => $result->ID,
|
904 |
-
);
|
905 |
-
}
|
906 |
-
wp_send_json_success( $output );
|
907 |
-
}
|
908 |
-
} else {
|
909 |
-
$output = array(
|
910 |
-
'message' => __( 'Error while retrieving result.', 'wpv-views' ),
|
911 |
-
);
|
912 |
-
wp_send_json_error( $output );
|
913 |
-
}
|
914 |
-
}
|
915 |
|
916 |
/**
|
917 |
* Register the Toolset shortcode transformer that will transform shortcode from the new format to the old one
|
43 |
|
44 |
add_action( 'toolset_action_require_shortcodes_templates', array( $this, 'print_shortcodes_templates' ) );
|
45 |
|
|
|
|
|
|
|
|
|
|
|
46 |
add_filter( 'toolset_filter_shortcode_script_i18n', array( $this, 'extend_script_i18n' ) );
|
47 |
}
|
48 |
|
302 |
#>
|
303 |
<ul class="toolset-shortcode-gui-dialog-item-group js-toolset-shortcode-gui-dialog-item-group">
|
304 |
<# _.each( data.fields, function( fieldData, fieldAttribute ) { #>
|
305 |
+
<li style="width:<# print( columnsWidth ); #>%;min-height:1px;float:left;">
|
306 |
<#
|
307 |
fieldData = _.defaults( fieldData, { shortcode: data.shortcode, templates: data.templates } );
|
308 |
fieldData = _.defaults( fieldData, { defaultValue: '', required: false, hidden: false, placeholder: '' } );
|
318 |
<# } #>
|
319 |
</div>
|
320 |
</script>
|
321 |
+
<script type="text/html" id="tmpl-toolset-shortcode-attribute-information">
|
322 |
+
<div id="{{{data.shortcode}}}-{{{data.attribute}}}" class="toolset-alert toolset-alert-info">
|
323 |
+
{{{data.content}}}
|
324 |
+
</div>
|
325 |
+
</script>
|
326 |
<script type="text/html" id="tmpl-toolset-shortcode-attribute-text">
|
327 |
<input id="{{{data.shortcode}}}-{{{data.attribute}}}" data-type="text" class="js-shortcode-gui-field large-text<# if ( data.required ) { #> js-toolset-shortcode-gui-required<# } #>" value="{{{data.defaultForceValue}}}" placeholder="{{{data.placeholder}}}" type="text">
|
328 |
</script>
|
333 |
<label>
|
334 |
<input name="{{{data.shortcode}}}-{{{data.attribute}}}" value="{{{optionKey}}}" class="js-shortcode-gui-field" type="radio"<# if ( optionKey == data.defaultForceValue ) { #> checked="checked"<# } #>>
|
335 |
{{{optionLabel}}}
|
336 |
+
</label>
|
337 |
</li>
|
338 |
<# }); #>
|
339 |
</ul>
|
340 |
</script>
|
341 |
<script type="text/html" id="tmpl-toolset-shortcode-attribute-select">
|
342 |
+
<select id="{{{data.shortcode}}}-{{{data.attribute}}}" class="js-shortcode-gui-field<# if ( data.required ) { #> js-toolset-shortcode-gui-required<# } #>">
|
343 |
<# _.each( data.options, function( optionLabel, optionKey ) { #>
|
344 |
<option value="{{{optionKey}}}"<# if ( optionKey == data.defaultForceValue ) { #> selected="selected"<# } #>>
|
345 |
{{{optionLabel}}}
|
375 |
|
376 |
<script type="text/html" id="tmpl-toolset-shortcode-content">
|
377 |
<#
|
378 |
+
data = _.defaults( data, { defaultValue: '', required: false, hidden: false, placeholder: '' } );
|
379 |
+
data = _.defaults( data, { defaultForceValue: data.defaultValue } );
|
380 |
#>
|
381 |
<div class="toolset-shortcode-gui-attribute-wrapper js-toolset-shortcode-gui-content-wrapper" <# if ( data.hidden ) { #> style="display:none"<# } #>>
|
382 |
+
<textarea id="toolset-shortcode-gui-content-{{{data.shortcode}}}" type="text" class="large-text js-toolset-shortcode-gui-content">{{{data.defaultValue}}}</textarea>
|
|
|
|
|
|
|
383 |
<# if ( _.has( data, 'description' ) ) { #>
|
384 |
<p class="description">{{{data.description}}}</p>
|
385 |
<# } #>
|
386 |
</div>
|
387 |
</script>
|
388 |
|
389 |
+
<?php $toolset_ajax = Toolset_Ajax::get_instance(); ?>
|
390 |
+
|
391 |
<script type="text/html" id="tmpl-toolset-shortcode-attribute-postSelector">
|
392 |
<ul id="{{{data.shortcode}}}-{{{data.attribute}}}">
|
393 |
<li class="toolset-shortcode-gui-item-selector-option">
|
448 |
<li class="toolset-shortcode-gui-item-selector-option toolset-shortcode-gui-item-selector-has-related js-toolset-shortcode-gui-item-selector-has-related">
|
449 |
<label for="toolset-shortcode-gui-item-selector-post-id-related">
|
450 |
<input type="radio" class="js-toolset-shortcode-gui-item-selector" id="toolset-shortcode-gui-item-selector-post-id-related" name="toolset_shortcode_gui_object_id" value="related" />
|
451 |
+
<?php echo __( 'The parent of the current post in another post type, set by a Types relationship', 'wpv-views' ); ?>
|
452 |
</label>
|
453 |
<div class="toolset-shortcode-gui-item-selector-is-related js-toolset-shortcode-gui-item-selector-is-related" style="display:none">
|
454 |
<ul class="toolset-advanced-setting tolset-mightlong-list" style="padding-top:15px;margin:5px 0 10px;">
|
460 |
<?php echo sprintf( '<label for="toolset-shortcode-gui-item-selector-post-relationship-id-%s">', $slug ); ?>
|
461 |
<?php echo sprintf(
|
462 |
'<input type="radio" name="related_object" id="toolset-shortcode-gui-item-selector-post-relationship-id-%s" value="$%s" %s />',
|
463 |
+
esc_attr( $slug ),
|
464 |
+
esc_attr( $slug ),
|
465 |
+
checked( $first, true, false )
|
466 |
); ?>
|
467 |
+
<?php echo esc_html( $custom_post_types_relations[ $slug ]['labels']['singular_name'] ); ?>
|
468 |
</label>
|
469 |
</li>
|
470 |
<?php
|
480 |
} else {
|
481 |
// m2m relationships
|
482 |
// Make sure m2m classes are registered in the autoloader
|
483 |
+
do_action( 'toolset_do_m2m_full_init' );
|
484 |
$current_post_type_relationships = $this->get_m2m_current_post_type_relationships( $current_post_type );
|
485 |
|
486 |
+
if ( ! empty( $current_post_type_relationships[ Toolset_Relationship_Origin_Wizard::ORIGIN_KEYWORD ] ) ) {
|
487 |
?>
|
488 |
<li class="toolset-shortcode-gui-item-selector-option toolset-shortcode-gui-item-selector-has-related js-toolset-shortcode-gui-item-selector-has-related">
|
489 |
<label for="toolset-shortcode-gui-item-selector-post-id-related">
|
490 |
<input type="radio" class="js-toolset-shortcode-gui-item-selector" id="toolset-shortcode-gui-item-selector-post-id-related" name="toolset_shortcode_gui_object_id" value="related" />
|
491 |
+
<?php echo __( 'A post related to the current post, set by a Types relationship', 'wpv-views' ); ?>
|
492 |
</label>
|
493 |
<div class="toolset-shortcode-gui-item-selector-is-related js-toolset-shortcode-gui-item-selector-is-related" style="display:none">
|
494 |
<ul class="toolset-advanced-setting toolset-mightlong-list" style="padding-top:15px;margin:5px 0 10px;">
|
495 |
<?php
|
496 |
$first = true;
|
497 |
+
foreach ( $current_post_type_relationships[ Toolset_Relationship_Origin_Wizard::ORIGIN_KEYWORD ] as $relationship_data ) {
|
498 |
?>
|
499 |
<li>
|
500 |
<?php echo sprintf( '<label for="toolset-shortcode-gui-item-selector-post-relationship-id-%s">', $relationship_data['id'] ); ?>
|
501 |
<?php echo sprintf(
|
502 |
'<input type="radio" name="related_object" id="toolset-shortcode-gui-item-selector-post-relationship-id-%s" value="%s" %s />',
|
503 |
+
esc_attr( $relationship_data['id'] ),
|
504 |
+
esc_attr( $relationship_data['value'] ),
|
505 |
+
checked( $first, true, false )
|
506 |
+
); ?>
|
507 |
+
<?php echo esc_html( $relationship_data['name'] ); ?>
|
508 |
+
</label>
|
509 |
+
</li>
|
510 |
+
<?php
|
511 |
+
$first = false;
|
512 |
+
}
|
513 |
+
?>
|
514 |
+
</ul>
|
515 |
+
</div>
|
516 |
+
</li>
|
517 |
+
<?php
|
518 |
+
}
|
519 |
+
|
520 |
+
if ( ! empty( $current_post_type_relationships[ Toolset_Relationship_Origin_Post_Reference_Field::ORIGIN_KEYWORD ] ) ) {
|
521 |
+
?>
|
522 |
+
<li class="toolset-shortcode-gui-item-selector-option toolset-shortcode-gui-item-selector-has-related js-toolset-shortcode-gui-item-selector-has-related">
|
523 |
+
<label for="toolset-shortcode-gui-item-selector-post-id-referenced">
|
524 |
+
<input type="radio" class="js-toolset-shortcode-gui-item-selector" id="toolset-shortcode-gui-item-selector-post-id-referenced" name="toolset_shortcode_gui_object_id" value="referenced" />
|
525 |
+
<?php echo __( 'A post related to the current post, set by a Types post reference field', 'wpv-views' ); ?>
|
526 |
+
</label>
|
527 |
+
<div class="toolset-shortcode-gui-item-selector-is-related js-toolset-shortcode-gui-item-selector-is-related" style="display:none">
|
528 |
+
<ul class="toolset-advanced-setting toolset-mightlong-list" style="padding-top:15px;margin:5px 0 10px;">
|
529 |
+
<?php
|
530 |
+
$first = true;
|
531 |
+
foreach ( $current_post_type_relationships[ Toolset_Relationship_Origin_Post_Reference_Field::ORIGIN_KEYWORD ] as $relationship_data ) {
|
532 |
+
?>
|
533 |
+
<li>
|
534 |
+
<?php echo sprintf( '<label for="toolset-shortcode-gui-item-selector-post-relationship-id-%s">', $relationship_data['id'] ); ?>
|
535 |
+
<?php echo sprintf(
|
536 |
+
'<input type="radio" name="referenced_object" id="toolset-shortcode-gui-item-selector-post-relationship-id-%s" value="%s" %s />',
|
537 |
+
esc_attr( $relationship_data['id'] ),
|
538 |
+
esc_attr( $relationship_data['value'] ),
|
539 |
+
checked( $first, true, false )
|
540 |
); ?>
|
541 |
+
<?php echo esc_html( $relationship_data['name'] ); ?>
|
542 |
</label>
|
543 |
</li>
|
544 |
<?php
|
559 |
<input type="radio" class="js-toolset-shortcode-gui-item-selector" id="toolset-shortcode-gui-item-selector-post-id" name="toolset_shortcode_gui_object_id" value="object_id" />
|
560 |
<?php _e( 'A specific post', 'wpv-views' ); ?>
|
561 |
</label>
|
562 |
+
<div class="toolset-advanced-setting toolset-shortcode-gui-item-selector-is-related js-toolset-shortcode-gui-item-selector-is-related" style="display:none;padding-top:10px;">
|
563 |
+
<select id="toolset-shortcode-gui-item-selector-post-id-object_id"
|
564 |
+
class="js-toolset-shortcode-gui-item-selector_object_id js-toolset-shortcode-gui-field-ajax-select2"
|
565 |
+
name="specific_object_id"
|
566 |
+
data-action="<?php echo esc_attr( $toolset_ajax->get_action_js_name( Toolset_Ajax::CALLBACK_SELECT2_SUGGEST_POSTS_BY_TITLE ) ); ?>"
|
567 |
+
data-prefill="<?php echo esc_attr( $toolset_ajax->get_action_js_name( Toolset_Ajax::CALLBACK_GET_POST_BY_ID ) ); ?>"
|
568 |
+
data-nonce="<?php echo wp_create_nonce( Toolset_Ajax::CALLBACK_SELECT2_SUGGEST_POSTS_BY_TITLE ); ?>"
|
569 |
+
data-prefill-nonce="<?php echo wp_create_nonce( Toolset_Ajax::CALLBACK_GET_POST_BY_ID ); ?>"
|
570 |
+
data-placeholder="<?php echo esc_attr( __( 'Search for a post by title', 'wpv-views' ) ); ?>">
|
571 |
+
</select>
|
572 |
</div>
|
573 |
</li>
|
574 |
</ul>
|
595 |
<input type="radio" class="js-toolset-shortcode-gui-item-selector" id="toolset-shortcode-gui-item-selector-user-id" name="toolset_shortcode_gui_object_id" value="object_id" />
|
596 |
<?php _e( 'A specific user', 'wpv-views' ); ?>
|
597 |
</label>
|
598 |
+
<div class="toolset-advanced-setting toolset-shortcode-gui-item-selector-is-related js-toolset-shortcode-gui-item-selector-is-related" style="display:none;padding-top:10px;">
|
599 |
+
<select id="toolset-shortcode-gui-item-selector-user-id-object_id"
|
600 |
+
class="js-toolset-shortcode-gui-item-selector_object_id js-toolset-shortcode-gui-field-ajax-select2"
|
601 |
+
name="specific_object_id"
|
602 |
+
data-action="<?php echo esc_attr( $toolset_ajax->get_action_js_name( Toolset_Ajax::CALLBACK_SELECT2_SUGGEST_USERS ) ); ?>"
|
603 |
+
data-prefill="<?php echo esc_attr( $toolset_ajax->get_action_js_name( Toolset_Ajax::CALLBACK_GET_USER_BY_ID ) ); ?>"
|
604 |
+
data-nonce="<?php echo wp_create_nonce( Toolset_Ajax::CALLBACK_SELECT2_SUGGEST_USERS ); ?>"
|
605 |
+
data-prefill-nonce="<?php echo wp_create_nonce( Toolset_Ajax::CALLBACK_GET_USER_BY_ID ); ?>"
|
606 |
+
data-placeholder="<?php echo esc_attr( __( 'Search for a user', 'wpv-views' ) ); ?>">
|
607 |
+
</select>
|
608 |
</div>
|
609 |
</li>
|
610 |
</ul>
|
620 |
isset( $_GET['page'] )
|
621 |
&& in_array( $_GET['page'], array( 'views-editor', 'view-archives-editor' ) )
|
622 |
) {
|
623 |
+
_e( 'The current post in the loop', 'wp-cred' );
|
624 |
} else {
|
625 |
+
_e( 'The current post', 'wp-cred' );
|
626 |
}
|
627 |
?>
|
628 |
</label>
|
630 |
<li class="js-toolset-shortcode-gui-item-selector-has-related">
|
631 |
<label>
|
632 |
<input type="radio" name="{{{data.shortcode}}}-select-target-post" class="toolset-shortcode-gui-item-selector js-toolset-shortcode-gui-item-selector" value="object_id" />
|
633 |
+
<?php _e( 'Another post', 'wp-cred' ); ?>
|
634 |
<div class="toolset-shortcode-gui-item-selector-is-related js-toolset-shortcode-gui-item-selector-is-related" style="display:none">
|
635 |
+
<select id="toolset-shortcode-gui-item-selector-post-id-object_id"
|
636 |
+
class="js-toolset-shortcode-gui-item-selector_object_id js-toolset-shortcode-gui-field-ajax-select2"
|
637 |
+
name="specific_object_id"
|
638 |
+
data-action="<?php echo esc_attr( $toolset_ajax->get_action_js_name( Toolset_Ajax::CALLBACK_SELECT2_SUGGEST_POSTS_BY_TITLE ) ); ?>"
|
639 |
+
data-prefill="<?php echo esc_attr( $toolset_ajax->get_action_js_name( Toolset_Ajax::CALLBACK_GET_POST_BY_ID ) ); ?>"
|
640 |
+
data-nonce="<?php echo wp_create_nonce( Toolset_Ajax::CALLBACK_SELECT2_SUGGEST_POSTS_BY_TITLE ); ?>"
|
641 |
+
data-prefill-nonce="<?php echo wp_create_nonce( Toolset_Ajax::CALLBACK_GET_POST_BY_ID ); ?>"
|
642 |
+
data-placeholder="<?php echo esc_attr( __( 'Search for a post by title', 'wpv-views' ) ); ?>">
|
643 |
</select>
|
644 |
</div>
|
645 |
</label>
|
651 |
<li>
|
652 |
<label>
|
653 |
<input type="radio" name="{{{data.shortcode}}}-select-target-user" class="toolset-shortcode-gui-item-selector js-toolset-shortcode-gui-item-selector" value="current" checked="checked" />
|
654 |
+
<?php _e( 'The current logged in user', 'wp-cred' ); ?>
|
655 |
</label>
|
656 |
</li>
|
657 |
<li class="js-toolset-shortcode-gui-item-selector-has-related">
|
658 |
<label>
|
659 |
<input type="radio" name="{{{data.shortcode}}}-select-target-user" class="toolset-shortcode-gui-item-selector js-toolset-shortcode-gui-item-selector" value="object_id" />
|
660 |
+
<?php _e( 'Another user', 'wp-cred' ); ?>
|
661 |
<div class="toolset-shortcode-gui-item-selector-is-related js-toolset-shortcode-gui-item-selector-is-related" style="display:none">
|
662 |
+
<select id="toolset-shortcode-gui-item-selector-user-id-object_id"
|
663 |
+
class="js-toolset-shortcode-gui-item-selector_object_id js-toolset-shortcode-gui-field-ajax-select2"
|
664 |
+
name="specific_object_id"
|
665 |
+
data-action="<?php echo esc_attr( $toolset_ajax->get_action_js_name( Toolset_Ajax::CALLBACK_SELECT2_SUGGEST_USERS ) ); ?>"
|
666 |
+
data-prefill="<?php echo esc_attr( $toolset_ajax->get_action_js_name( Toolset_Ajax::CALLBACK_GET_USER_BY_ID ) ); ?>"
|
667 |
+
data-nonce="<?php echo wp_create_nonce( Toolset_Ajax::CALLBACK_SELECT2_SUGGEST_USERS ); ?>"
|
668 |
+
data-prefill-nonce="<?php echo wp_create_nonce( Toolset_Ajax::CALLBACK_GET_USER_BY_ID ); ?>"
|
669 |
+
data-placeholder="<?php echo esc_attr( __( 'Search for a user', 'wpv-views' ) ); ?>">
|
670 |
</select>
|
671 |
</div>
|
672 |
</label>
|
749 |
&& is_array( $cptr_data['post_relationship']['belongs'] )
|
750 |
) {
|
751 |
$this_belongs = array_keys( $cptr_data['post_relationship']['belongs'] );
|
752 |
+
foreach ( $this_belongs as $this_belongs_candidate ) {
|
753 |
+
if ( isset( $custom_post_types_relations[ $this_belongs_candidate ] ) ) {
|
754 |
+
$current_post_type_parents[] = $this_belongs_candidate;
|
755 |
+
}
|
756 |
+
}
|
757 |
}
|
758 |
}
|
759 |
} else if (
|
796 |
/**
|
797 |
* Get Types one-to-many and one-to-one relationships for a given post type, or all the existing otherwise.
|
798 |
*
|
799 |
+
* For post reference fields relationships, make sure we alwars offer to insert the parent post data,
|
800 |
+
* as they do support relationships between the same post type, hence the relationship ends get blurred.
|
801 |
+
*
|
802 |
* @paran $current_post_type string|null
|
803 |
*
|
804 |
* @return array
|
806 |
* @since m2m
|
807 |
*/
|
808 |
public function get_m2m_current_post_type_relationships( $current_post_type ) {
|
809 |
+
$current_post_type_relationships = array(
|
810 |
+
Toolset_Relationship_Origin_Wizard::ORIGIN_KEYWORD => array(),
|
811 |
+
Toolset_Relationship_Origin_Post_Reference_Field::ORIGIN_KEYWORD => array()
|
812 |
+
);
|
|
|
813 |
|
|
|
814 |
$query = new Toolset_Relationship_Query_V2();
|
815 |
|
816 |
// Note that we can not use $query->do_if() because it actually runs both branches
|
822 |
$query->do_and(
|
823 |
$query->has_type( $current_post_type->name, new Toolset_Relationship_Role_Child() ),
|
824 |
$query->has_cardinality( $query->cardinality()->one_to_many() ),
|
825 |
+
$query->do_or(
|
826 |
+
$query->origin( Toolset_Relationship_Origin_Wizard::ORIGIN_KEYWORD ),
|
827 |
+
$query->origin( Toolset_Relationship_Origin_Post_Reference_Field::ORIGIN_KEYWORD )
|
828 |
+
)
|
829 |
),
|
830 |
$query->has_cardinality( $query->cardinality()->one_to_one() )
|
831 |
)
|
835 |
$relationship_definitions = $query
|
836 |
->add(
|
837 |
$query->do_and(
|
838 |
+
$query->do_or(
|
839 |
+
$query->origin( Toolset_Relationship_Origin_Wizard::ORIGIN_KEYWORD ),
|
840 |
+
$query->origin( Toolset_Relationship_Origin_Post_Reference_Field::ORIGIN_KEYWORD )
|
841 |
+
),
|
842 |
$query->do_or(
|
843 |
$query->has_cardinality( $query->cardinality()->one_to_many() ),
|
844 |
$query->has_cardinality( $query->cardinality()->one_to_one() )
|
862 |
|
863 |
$parents = $relationship_definition->get_parent_type()->get_types();
|
864 |
$parent = $parents[0];
|
865 |
+
$origin = $relationship_definition->get_origin();
|
866 |
|
867 |
+
$current_post_type_relationships[ $origin->get_origin_keyword() ][] = array(
|
868 |
'name' => $relationship_definition->get_display_name(),
|
869 |
'slug' => $relationship_definition->get_slug(),
|
870 |
'value' => '@' . $relationship_definition->get_slug() . '.'
|
871 |
+
. ( Toolset_Relationship_Origin_Wizard::ORIGIN_KEYWORD === $origin->get_origin_keyword()
|
872 |
+
? $relationship_definition->get_role_name(
|
873 |
+
Toolset_Relationship_Role::other( $given_post_type_role )
|
874 |
+
)
|
875 |
+
: Toolset_Relationship_Role::PARENT
|
876 |
),
|
877 |
'id' => $relationship_definition->get_slug() . '-' . $parent,
|
878 |
+
'role_name' => ( Toolset_Relationship_Origin_Wizard::ORIGIN_KEYWORD === $origin->get_origin_keyword()
|
879 |
+
? $relationship_definition->get_role_name(
|
880 |
+
Toolset_Relationship_Role::other( $given_post_type_role )
|
881 |
+
)
|
882 |
+
: Toolset_Relationship_Role::PARENT
|
883 |
)
|
884 |
);
|
885 |
}
|
886 |
|
887 |
return $current_post_type_relationships;
|
888 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
889 |
|
890 |
/**
|
891 |
* Register the Toolset shortcode transformer that will transform shortcode from the new format to the old one
|
vendor/toolset/toolset-common/inc/toolset.wpml.compatibility.class.php
CHANGED
@@ -4,15 +4,35 @@ if ( ! class_exists( 'Toolset_WPML_Compatibility', false ) ) {
|
|
4 |
|
5 |
|
6 |
/**
|
7 |
-
* Handle the
|
8 |
*
|
9 |
* @since unknown
|
10 |
*/
|
11 |
-
class Toolset_WPML_Compatibility {
|
12 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
private static $instance;
|
14 |
|
15 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
16 |
public static function get_instance() {
|
17 |
if ( null == self::$instance ) {
|
18 |
self::$instance = new self();
|
@@ -27,10 +47,9 @@ if ( ! class_exists( 'Toolset_WPML_Compatibility', false ) ) {
|
|
27 |
}
|
28 |
|
29 |
|
30 |
-
|
31 |
|
32 |
-
|
33 |
-
private function __construct() {
|
34 |
|
35 |
add_action( 'init', array( $this, 'maybe_add_wpml_string_stub_shortcode' ), 100 );
|
36 |
|
@@ -44,8 +63,20 @@ if ( ! class_exists( 'Toolset_WPML_Compatibility', false ) ) {
|
|
44 |
*
|
45 |
* @since 2.3
|
46 |
*/
|
47 |
-
add_filter(
|
|
|
|
|
|
|
|
|
|
|
|
|
48 |
|
|
|
|
|
|
|
|
|
|
|
|
|
49 |
}
|
50 |
|
51 |
|
@@ -75,7 +106,10 @@ if ( ! class_exists( 'Toolset_WPML_Compatibility', false ) ) {
|
|
75 |
* @return string
|
76 |
* @since unknown
|
77 |
*/
|
78 |
-
public function stub_wpml_string_shortcode(
|
|
|
|
|
|
|
79 |
return do_shortcode( $value );
|
80 |
}
|
81 |
|
@@ -94,7 +128,7 @@ if ( ! class_exists( 'Toolset_WPML_Compatibility', false ) ) {
|
|
94 |
|
95 |
static $result = null;
|
96 |
|
97 |
-
if( null === $result || ! $use_cache ) {
|
98 |
global $sitepress;
|
99 |
$is_wpml_active = (
|
100 |
defined( 'ICL_SITEPRESS_VERSION' )
|
@@ -118,10 +152,14 @@ if ( ! class_exists( 'Toolset_WPML_Compatibility', false ) ) {
|
|
118 |
* Instead of calling this directly, use is_wpml_configured_and_active().
|
119 |
*
|
120 |
* @param mixed $default_value Ignored.
|
|
|
121 |
* @return bool
|
122 |
* @since 2.3
|
123 |
*/
|
124 |
-
public function filter_is_wpml_active_and_configured(
|
|
|
|
|
|
|
125 |
return $this->is_wpml_active_and_configured();
|
126 |
}
|
127 |
|
@@ -140,7 +178,7 @@ if ( ! class_exists( 'Toolset_WPML_Compatibility', false ) ) {
|
|
140 |
return false;
|
141 |
}
|
142 |
|
143 |
-
return ( defined( 'WPML_ST_VERSION') );
|
144 |
}
|
145 |
|
146 |
/**
|
@@ -171,6 +209,336 @@ if ( ! class_exists( 'Toolset_WPML_Compatibility', false ) ) {
|
|
171 |
return ( defined( 'ICL_SITEPRESS_VERSION' ) ? ICL_SITEPRESS_VERSION : null );
|
172 |
}
|
173 |
|
174 |
-
}
|
175 |
|
176 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4 |
|
5 |
|
6 |
/**
|
7 |
+
* Handle the basic interactions between WPML and Toolset plugins.
|
8 |
*
|
9 |
* @since unknown
|
10 |
*/
|
11 |
+
class Toolset_WPML_Compatibility extends Toolset_Wpdb_User {
|
12 |
|
13 |
+
|
14 |
+
// Possible WPML translation modes. Use these constants instead of hardcoded strings as they might
|
15 |
+
// change without warning.
|
16 |
+
const MODE_DONT_TRANSLATE = 'dont_translate';
|
17 |
+
const MODE_TRANSLATE = 'translate';
|
18 |
+
const MODE_DISPLAY_AS_TRANSLATED = 'display_as_translated';
|
19 |
+
|
20 |
+
|
21 |
+
/** @var Toolset_WPML_Compatibility */
|
22 |
private static $instance;
|
23 |
|
24 |
|
25 |
+
/** @var null|string Cache for the current language code. */
|
26 |
+
private $current_language;
|
27 |
+
|
28 |
+
/** @var null|string Cache for the default language code. */
|
29 |
+
private $default_language;
|
30 |
+
|
31 |
+
|
32 |
+
/** @var string[] */
|
33 |
+
private $previous_languages = array();
|
34 |
+
|
35 |
+
|
36 |
public static function get_instance() {
|
37 |
if ( null == self::$instance ) {
|
38 |
self::$instance = new self();
|
47 |
}
|
48 |
|
49 |
|
50 |
+
public function __construct( wpdb $wpdb_di = null ) {
|
51 |
|
52 |
+
parent::__construct( $wpdb_di );
|
|
|
53 |
|
54 |
add_action( 'init', array( $this, 'maybe_add_wpml_string_stub_shortcode' ), 100 );
|
55 |
|
63 |
*
|
64 |
* @since 2.3
|
65 |
*/
|
66 |
+
add_filter(
|
67 |
+
'toolset_is_wpml_active_and_configured', array(
|
68 |
+
$this,
|
69 |
+
'filter_is_wpml_active_and_configured'
|
70 |
+
)
|
71 |
+
);
|
72 |
+
|
73 |
|
74 |
+
/**
|
75 |
+
* Shows a warning in WPML if the post type belongs to a relationships and it is not the proper translation mode
|
76 |
+
*
|
77 |
+
* @since m2m
|
78 |
+
*/
|
79 |
+
add_filter( 'wpml_disable_translation_mode_radio', array( $this, 'wpml_disable_translation_mode_radio' ), 10, 3 );
|
80 |
}
|
81 |
|
82 |
|
106 |
* @return string
|
107 |
* @since unknown
|
108 |
*/
|
109 |
+
public function stub_wpml_string_shortcode(
|
110 |
+
/** @noinspection PhpUnusedParameterInspection */
|
111 |
+
$atts, $value
|
112 |
+
) {
|
113 |
return do_shortcode( $value );
|
114 |
}
|
115 |
|
128 |
|
129 |
static $result = null;
|
130 |
|
131 |
+
if ( null === $result || ! $use_cache ) {
|
132 |
global $sitepress;
|
133 |
$is_wpml_active = (
|
134 |
defined( 'ICL_SITEPRESS_VERSION' )
|
152 |
* Instead of calling this directly, use is_wpml_configured_and_active().
|
153 |
*
|
154 |
* @param mixed $default_value Ignored.
|
155 |
+
*
|
156 |
* @return bool
|
157 |
* @since 2.3
|
158 |
*/
|
159 |
+
public function filter_is_wpml_active_and_configured(
|
160 |
+
/** @noinspection PhpUnusedParameterInspection */
|
161 |
+
$default_value
|
162 |
+
) {
|
163 |
return $this->is_wpml_active_and_configured();
|
164 |
}
|
165 |
|
178 |
return false;
|
179 |
}
|
180 |
|
181 |
+
return ( defined( 'WPML_ST_VERSION' ) );
|
182 |
}
|
183 |
|
184 |
/**
|
209 |
return ( defined( 'ICL_SITEPRESS_VERSION' ) ? ICL_SITEPRESS_VERSION : null );
|
210 |
}
|
211 |
|
|
|
212 |
|
213 |
+
/**
|
214 |
+
* Check if a post type is translatable.
|
215 |
+
*
|
216 |
+
* @param string $post_type_slug
|
217 |
+
*
|
218 |
+
* @return bool
|
219 |
+
* @since m2m
|
220 |
+
*/
|
221 |
+
public function is_post_type_translatable( $post_type_slug ) {
|
222 |
+
return (bool) apply_filters( 'wpml_is_translated_post_type', false, $post_type_slug );
|
223 |
+
}
|
224 |
+
|
225 |
+
|
226 |
+
/**
|
227 |
+
* Check if a post type is translatable and in the "display as translated" mode.
|
228 |
+
*
|
229 |
+
* @param string $post_type_slug
|
230 |
+
*
|
231 |
+
* @return bool
|
232 |
+
* @since 2.5.10
|
233 |
+
*/
|
234 |
+
public function is_post_type_display_as_translated( $post_type_slug ) {
|
235 |
+
if ( ! $this->is_post_type_translatable( $post_type_slug ) ) {
|
236 |
+
return false;
|
237 |
+
}
|
238 |
+
|
239 |
+
return (bool) apply_filters( 'wpml_is_display_as_translated_post_type', false, $post_type_slug );
|
240 |
+
}
|
241 |
+
|
242 |
+
|
243 |
+
/**
|
244 |
+
* Get the current language.
|
245 |
+
*
|
246 |
+
* Cached.
|
247 |
+
*
|
248 |
+
* @return string
|
249 |
+
* @since m2m
|
250 |
+
*/
|
251 |
+
public function get_current_language() {
|
252 |
+
if ( null === $this->current_language && $this->is_wpml_active_and_configured() ) {
|
253 |
+
$this->current_language = apply_filters( 'wpml_current_language', null );
|
254 |
+
}
|
255 |
+
|
256 |
+
return $this->current_language;
|
257 |
+
}
|
258 |
+
|
259 |
+
|
260 |
+
/**
|
261 |
+
* Get the default site language.
|
262 |
+
*
|
263 |
+
* Cached.
|
264 |
+
*
|
265 |
+
* @return string
|
266 |
+
* @since m2m
|
267 |
+
*/
|
268 |
+
public function get_default_language() {
|
269 |
+
if ( null === $this->default_language && $this->is_wpml_active_and_configured() ) {
|
270 |
+
$this->default_language = apply_filters( 'wpml_default_language', null );
|
271 |
+
}
|
272 |
+
|
273 |
+
return $this->default_language;
|
274 |
+
}
|
275 |
+
|
276 |
+
|
277 |
+
/**
|
278 |
+
* @return bool True if the site is currently in the default language.
|
279 |
+
* @since 2.5.10
|
280 |
+
*/
|
281 |
+
public function is_current_language_default() {
|
282 |
+
return (
|
283 |
+
! $this->is_wpml_active_and_configured()
|
284 |
+
|| $this->get_default_language() === $this->get_current_language()
|
285 |
+
);
|
286 |
+
}
|
287 |
+
|
288 |
+
|
289 |
+
public function get_post_language( $post_id ) {
|
290 |
+
$post_language_details = apply_filters( 'wpml_post_language_details', null, $post_id );
|
291 |
+
$lang = toolset_getarr( $post_language_details, 'language_code', '' );
|
292 |
+
|
293 |
+
return $lang;
|
294 |
+
}
|
295 |
+
|
296 |
+
|
297 |
+
/**
|
298 |
+
* Get an array of post translation IDs from the icl_translations table, indexed by language codes.
|
299 |
+
*
|
300 |
+
* todo consider using WPML hooks if they're available
|
301 |
+
*
|
302 |
+
* @param int $post_id
|
303 |
+
*
|
304 |
+
* @return int[]
|
305 |
+
* @since 2.5.10
|
306 |
+
*/
|
307 |
+
public function get_post_translations_directly( $post_id ) {
|
308 |
+
|
309 |
+
if ( ! $this->is_wpml_active_and_configured() ) {
|
310 |
+
return array();
|
311 |
+
}
|
312 |
+
|
313 |
+
$icl_translations_table = $this->icl_translations_table_name();
|
314 |
+
$trid = $this->get_post_trid( $post_id );
|
315 |
+
|
316 |
+
if ( null === $trid ) {
|
317 |
+
return array();
|
318 |
+
}
|
319 |
+
|
320 |
+
$query = $this->wpdb->prepare(
|
321 |
+
"SELECT
|
322 |
+
element_id AS post_id,
|
323 |
+
language_code AS language_code
|
324 |
+
FROM
|
325 |
+
$icl_translations_table
|
326 |
+
WHERE
|
327 |
+
element_type LIKE %s
|
328 |
+
AND trid = %d",
|
329 |
+
'post_%',
|
330 |
+
$trid
|
331 |
+
);
|
332 |
+
|
333 |
+
$db_results = $this->wpdb->get_results( $query );
|
334 |
+
|
335 |
+
// Return an associative array of post IDs.
|
336 |
+
$results = array();
|
337 |
+
foreach ( $db_results as $row ) {
|
338 |
+
$results[ $row->language_code ] = (int) $row->post_id;
|
339 |
+
}
|
340 |
+
|
341 |
+
return $results;
|
342 |
+
|
343 |
+
}
|
344 |
+
|
345 |
+
|
346 |
+
/**
|
347 |
+
* Retrieve the translation group ID for a post.
|
348 |
+
*
|
349 |
+
* @param int $post_id
|
350 |
+
*
|
351 |
+
* @return int "trid" value or zero.
|
352 |
+
* @since m2m
|
353 |
+
*/
|
354 |
+
public function get_post_trid( $post_id ) {
|
355 |
+
$icl_translations_table = $this->icl_translations_table_name();
|
356 |
+
|
357 |
+
$query = $this->wpdb->prepare(
|
358 |
+
"SELECT trid
|
359 |
+
FROM `{$icl_translations_table}`
|
360 |
+
WHERE
|
361 |
+
element_type LIKE %s
|
362 |
+
AND element_id = %d
|
363 |
+
LIMIT 1",
|
364 |
+
'post_%',
|
365 |
+
$post_id
|
366 |
+
);
|
367 |
+
|
368 |
+
return (int) $this->wpdb->get_var( $query );
|
369 |
+
}
|
370 |
+
|
371 |
+
|
372 |
+
/**
|
373 |
+
* @return string icl_translations table name.
|
374 |
+
*/
|
375 |
+
public function icl_translations_table_name() {
|
376 |
+
return $this->wpdb->prefix . 'icl_translations';
|
377 |
+
}
|
378 |
+
|
379 |
+
|
380 |
+
/**
|
381 |
+
* Get the translation mode value for a given post type.
|
382 |
+
*
|
383 |
+
* If WPML is not active or the post type doesn't exist, self::MODE_DONT_TRANSLATE will be returned.
|
384 |
+
*
|
385 |
+
* @param string $post_type_slug
|
386 |
+
* @return string
|
387 |
+
* @since 2.5.11
|
388 |
+
*/
|
389 |
+
public function get_post_type_translation_mode( $post_type_slug ) {
|
390 |
+
if(
|
391 |
+
! $this->is_wpml_active_and_configured()
|
392 |
+
|| ! $this->is_post_type_translatable( $post_type_slug )
|
393 |
+
) {
|
394 |
+
return self::MODE_DONT_TRANSLATE;
|
395 |
+
}
|
396 |
+
|
397 |
+
if( $this->is_post_type_display_as_translated( $post_type_slug ) ) {
|
398 |
+
return self::MODE_DISPLAY_AS_TRANSLATED;
|
399 |
+
}
|
400 |
+
|
401 |
+
return self::MODE_TRANSLATE;
|
402 |
+
}
|
403 |
+
|
404 |
+
|
405 |
+
/**
|
406 |
+
* Set the translation mode of given post type.
|
407 |
+
*
|
408 |
+
* @param string $post_type_slug
|
409 |
+
* @param string $translation_mode One of the MODE_ constants defined on this class.
|
410 |
+
* @return void
|
411 |
+
* @throws InvalidArgumentException if WPML is not active or an invalid translation mode is provided.
|
412 |
+
* @since 2.5.11
|
413 |
+
*/
|
414 |
+
public function set_post_type_translation_mode( $post_type_slug, $translation_mode ) {
|
415 |
+
if( ! $this->is_wpml_active_and_configured() ) {
|
416 |
+
throw new InvalidArgumentException( 'Trying to set a post translation mode while WPML is not active.' );
|
417 |
+
}
|
418 |
+
|
419 |
+
$allowed_modes = array( self::MODE_TRANSLATE, self::MODE_DONT_TRANSLATE, self::MODE_DISPLAY_AS_TRANSLATED );
|
420 |
+
|
421 |
+
if( ! in_array( $translation_mode, $allowed_modes ) ) {
|
422 |
+
throw new InvalidArgumentException( 'Trying to set an invalid translation mode for a post type' );
|
423 |
+
}
|
424 |
+
|
425 |
+
do_action( 'wpml_set_translation_mode_for_post_type', $post_type_slug, $translation_mode );
|
426 |
+
}
|
427 |
+
|
428 |
+
|
429 |
+
/**
|
430 |
+
* Set a post as a translation of another post (original).
|
431 |
+
*
|
432 |
+
* @param IToolset_Post $original_post
|
433 |
+
* @param int $translation_post_id ID of the translated post.
|
434 |
+
* @param string $lang_code Language of the translated post.
|
435 |
+
* @throws InvalidArgumentException If called when WPML inactive.
|
436 |
+
* @return void
|
437 |
+
*/
|
438 |
+
public function add_post_translation( IToolset_Post $original_post, $translation_post_id, $lang_code ) {
|
439 |
+
if( ! $this->is_wpml_active_and_configured() ) {
|
440 |
+
throw new InvalidArgumentException( 'Cannot add a post translation if WPML is not active and configured.' );
|
441 |
+
}
|
442 |
+
$element_type = apply_filters( 'wpml_element_type', $original_post->get_type() );
|
443 |
+
|
444 |
+
$set_language_args = array(
|
445 |
+
'element_id' => $translation_post_id,
|
446 |
+
'element_type' => $element_type,
|
447 |
+
'trid' => $original_post->get_trid(),
|
448 |
+
'language_code' => $lang_code,
|
449 |
+
'source_language_code' => $original_post->get_language()
|
450 |
+
);
|
451 |
+
|
452 |
+
do_action( 'wpml_set_element_language_details', $set_language_args );
|
453 |
+
}
|
454 |
+
|
455 |
+
|
456 |
+
/**
|
457 |
+
* Create a duplicate of the given post (using standard WPML mechanism to copy the content).
|
458 |
+
*
|
459 |
+
* Optionally, it is possible to _not_ mark it as an duplicate, but as a regular translation instead.
|
460 |
+
*
|
461 |
+
* @param IToolset_Post $original_post
|
462 |
+
* @param string $lang_code Language of the duplicated post.
|
463 |
+
* @param bool $mark_as_duplicate
|
464 |
+
*
|
465 |
+
* @return int ID of the duplicated post.
|
466 |
+
* @throws InvalidArgumentException If called when WPML inactive.
|
467 |
+
* @throws RuntimeException If it is not possible to perform the call to WPML.
|
468 |
+
*/
|
469 |
+
public function create_post_duplicate( IToolset_Post $original_post, $lang_code, $mark_as_duplicate = true ) {
|
470 |
+
if( ! $this->is_wpml_active_and_configured() ) {
|
471 |
+
throw new InvalidArgumentException( 'Cannot add a post translation if WPML is not active and configured.' );
|
472 |
+
}
|
473 |
+
|
474 |
+
$copied_post_id = apply_filters( 'wpml_copy_post_to_language', $original_post->get_id(), $lang_code, $mark_as_duplicate );
|
475 |
+
|
476 |
+
return (int) $copied_post_id;
|
477 |
+
}
|
478 |
+
|
479 |
+
/**
|
480 |
+
* Shows a warning in WPML if the post type belongs to a relationships and it is not the proper translation mode
|
481 |
+
*
|
482 |
+
* @param array $disabled_state_for_mode Filterable array.
|
483 |
+
* @param int $mode WPML translation mode.
|
484 |
+
* @param string $content_slug Post type slug.
|
485 |
+
* @return array
|
486 |
+
* @since m2m
|
487 |
+
*/
|
488 |
+
public function wpml_disable_translation_mode_radio( $disabled_state_for_mode, $mode, $content_slug ) {
|
489 |
+
do_action( 'toolset_do_m2m_full_init' );
|
490 |
+
if( ! apply_filters( 'toolset_is_m2m_enabled', false ) ) {
|
491 |
+
return $disabled_state_for_mode;
|
492 |
+
}
|
493 |
+
$relationships_query = new Toolset_Relationship_Query_V2();
|
494 |
+
$relationships_query->add( $relationships_query->has_domain( 'posts' ) )
|
495 |
+
->add( $relationships_query->has_type( $content_slug ) )
|
496 |
+
->do_not_add_default_conditions();
|
497 |
+
$relationships = $relationships_query->get_results();
|
498 |
+
|
499 |
+
if ( empty( $relationships ) ) {
|
500 |
+
return $disabled_state_for_mode;
|
501 |
+
}
|
502 |
+
|
503 |
+
foreach ( $relationships as $relationship ) {
|
504 |
+
$types = array_merge( $relationship->get_parent_type()->get_types(), $relationship->get_child_type()->get_types() );
|
505 |
+
if ( in_array( $content_slug, $types, true ) && defined( 'WPML_CONTENT_TYPE_TRANSLATE' ) && $mode == WPML_CONTENT_TYPE_TRANSLATE ) {
|
506 |
+
$disabled_state_for_mode['state'] = true;
|
507 |
+
// translators: Relationship name.
|
508 |
+
$disabled_state_for_mode['reason_message'] = sprintf( __( 'You cannot set this translation mode because the post type is involved in the relationship "%s".', 'wpcf' ), $relationship->get_display_name() ) . ' <a href="https://wp-types.com/documentation/translating-sites-built-with-toolset/translating-related-content/" target="_blank">' . __( 'Learn more' , 'wpcf' ) . '</a>.';
|
509 |
+
return $disabled_state_for_mode;
|
510 |
+
}
|
511 |
+
}
|
512 |
+
return $disabled_state_for_mode;
|
513 |
+
}
|
514 |
+
|
515 |
+
|
516 |
+
|
517 |
+
/**
|
518 |
+
* Switch the current language.
|
519 |
+
*
|
520 |
+
* Warning: You *MUST* revert this by calling switch_language_back() in all cases.
|
521 |
+
*
|
522 |
+
* It is possible to nest these calls, but switch_language() and switch_language_back() must always
|
523 |
+
* come in pairs.
|
524 |
+
*
|
525 |
+
* @param string $lang_code
|
526 |
+
* @since 2.5.10
|
527 |
+
*/
|
528 |
+
public function switch_language( $lang_code ) {
|
529 |
+
array_push( $this->previous_languages, $this->get_current_language() );
|
530 |
+
do_action( 'wpml_switch_language', $lang_code );
|
531 |
+
}
|
532 |
+
|
533 |
+
|
534 |
+
/**
|
535 |
+
* Switch the current language back to the previous value after switch_language().
|
536 |
+
*
|
537 |
+
* @since 2.5.10
|
538 |
+
*/
|
539 |
+
public function switch_language_back() {
|
540 |
+
$lang_code = array_pop( $this->previous_languages );
|
541 |
+
do_action( 'wpml_switch_language', $lang_code );
|
542 |
+
}
|
543 |
+
}
|
544 |
+
}
|
vendor/toolset/toolset-common/lib/whip/CHANGELOG.md
ADDED
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Change Log
|
2 |
+
All notable changes to this project will be documented in this file.
|
3 |
+
|
4 |
+
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
5 |
+
and this project adheres to [Semantic Versioning](http://semver.org/).
|
6 |
+
|
7 |
+
## [1.1.0]
|
8 |
+
### Added
|
9 |
+
* Allow WordPress messages to be dismissed for a period of 4 weeks.
|
10 |
+
|
11 |
+
## [1.0.1]
|
12 |
+
### Fixed
|
13 |
+
* Fix a missing link when the PHP message is switched to the WordPress.org hosting page.
|
14 |
+
|
15 |
+
## [1.0.0]
|
16 |
+
### Changed
|
17 |
+
* Updated screenshot in README
|
18 |
+
|
19 |
+
## [1.0.0-beta.2] - 2017-03-11
|
20 |
+
### Added
|
21 |
+
* Complete PHP version message
|
22 |
+
|
23 |
+
### Changed
|
24 |
+
* Refactor code architecture.
|
25 |
+
* Use PHP version constant instead of function.
|
26 |
+
|
27 |
+
### Fixed
|
28 |
+
* Fix broken version reconciliation.
|
29 |
+
|
30 |
+
## 1.0.0-beta.1 - 2017-02-21
|
31 |
+
* Initial pre-release of whip. A package to nudge users to upgrade their software versions.
|
32 |
+
|
33 |
+
[Unreleased]: https://github.com/yoast/whip/compare/1.0.0-beta.2...HEAD
|
34 |
+
[1.0.0-beta.2]: https://github.com/yoast/whip/compare/1.0.0-beta.1...1.0.0-beta.2
|
vendor/toolset/toolset-common/lib/whip/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
MIT License
|
2 |
+
|
3 |
+
Copyright (c) 2017 Yoast
|
4 |
+
|
5 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6 |
+
of this software and associated documentation files (the "Software"), to deal
|
7 |
+
in the Software without restriction, including without limitation the rights
|
8 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9 |
+
copies of the Software, and to permit persons to whom the Software is
|
10 |
+
furnished to do so, subject to the following conditions:
|
11 |
+
|
12 |
+
The above copyright notice and this permission notice shall be included in all
|
13 |
+
copies or substantial portions of the Software.
|
14 |
+
|
15 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21 |
+
SOFTWARE.
|
vendor/toolset/toolset-common/lib/whip/README.md
ADDED
@@ -0,0 +1,94 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# whip
|
2 |
+
A WordPress package to nudge users to upgrade their software versions (starting with PHP)
|
3 |
+
|
4 |
+
![Screenshot of the WordPress notice](./images/wp-message.png)
|
5 |
+
|
6 |
+
## Requirements
|
7 |
+
|
8 |
+
The following versions of PHP are supported:
|
9 |
+
|
10 |
+
* PHP 5.2
|
11 |
+
* PHP 5.3
|
12 |
+
* PHP 5.4
|
13 |
+
* PHP 5.5
|
14 |
+
* PHP 5.6
|
15 |
+
* PHP 7.0
|
16 |
+
* PHP 7.1
|
17 |
+
|
18 |
+
WordPress is also required for certain functionality:
|
19 |
+
|
20 |
+
* The `WPMessagePresenter` requires WordPress or a function called `add_action`, to hook into WordPress.
|
21 |
+
* The `PHPVersionDetector` requires WordPress or a function called `__`, to translate strings.
|
22 |
+
|
23 |
+
## Installation
|
24 |
+
|
25 |
+
```bash
|
26 |
+
$ composer require yoast/whip
|
27 |
+
```
|
28 |
+
|
29 |
+
## Usage
|
30 |
+
|
31 |
+
The easiest way to use Whip in WordPress is just by using the included function to check the versions. In this case checking if PHP 5.6 or greater is installed:
|
32 |
+
```php
|
33 |
+
whip_wp_check_versions( array(
|
34 |
+
'php' => '>=5.6',
|
35 |
+
) );
|
36 |
+
```
|
37 |
+
|
38 |
+
This will show a message to all users of your plugin on PHP5.2 to PHP 5.5. By default the message will be shown on every page of the admin and to every user. It is up to the implementing plugin to restrict this to certain users and/or pages.
|
39 |
+
|
40 |
+
### Adding a message as a host
|
41 |
+
|
42 |
+
It is possible to add a custom message to the PHP version message by setting specific environment variables:
|
43 |
+
|
44 |
+
```php
|
45 |
+
putenv( "WHIP_NAME_OF_HOST=Name of the host" );
|
46 |
+
putenv( "WHIP_MESSAGE_FROM_HOST_ABOUT_PHP=A message from the host" );
|
47 |
+
```
|
48 |
+
|
49 |
+
The `WHIP_NAME_OF_HOST` environment variable could be reused in the future for showing messages about different software packages.
|
50 |
+
|
51 |
+
Both the name and the message for PHP can also be changed using WordPress filters:
|
52 |
+
```php
|
53 |
+
function my_host__name_for_whip() {
|
54 |
+
return 'Name of the host';
|
55 |
+
}
|
56 |
+
add_filter( 'whip_name_of_host', 'my_host__name_for_whip' );
|
57 |
+
|
58 |
+
function my_host__php_message_for_whip( $message ) {
|
59 |
+
return 'A message from the host';
|
60 |
+
}
|
61 |
+
add_filter( 'whip_message_from_host_about_php', 'my_host__php_message_for_whip' );
|
62 |
+
```
|
63 |
+
|
64 |
+
The WordPress filters can also read the value previously set by the environment variables.
|
65 |
+
|
66 |
+
As a general rule, the filter is the same as the environment variable, but lowercased.
|
67 |
+
|
68 |
+
### Linking to the WordPress.org hosting page
|
69 |
+
|
70 |
+
We have created a hosting overview page on yoast.com which only contains hosts that we've vetted. The PHP message links to this page by default. If you really prefer to link to the WordPress.org hosting page that is possible. Just use the `whip_hosting_page_url_wordpress` filter:
|
71 |
+
|
72 |
+
```php
|
73 |
+
add_filter( 'whip_hosting_page_url_wordpress', '__return_true' );
|
74 |
+
```
|
75 |
+
|
76 |
+
## Backwards compatibility policy
|
77 |
+
|
78 |
+
We follow [semantic versioning][semver] with an extra strict rule for MAJOR versions. We will do a major version bump whenever we add new methods. We have to do this because of the shared namespace in PHP. When this package will be used in multiple plugins we cannot safely add and use a method without bumping a major version. This is because the version without the new method may be autoloaded and then a fatal error occurs.
|
79 |
+
|
80 |
+
This also means that any major version bump is accompanied by a change of all class names in the package. So for version 2 of this package all classes will be postfixed with `_v2`. This prevents fatal errors when two plugins include different versions of this package.
|
81 |
+
|
82 |
+
## Changelog
|
83 |
+
|
84 |
+
|
85 |
+
## Security
|
86 |
+
|
87 |
+
If you discover any security related issues, please email security@yoast.com instead of using the issue tracker.
|
88 |
+
|
89 |
+
## Credits
|
90 |
+
|
91 |
+
* [Team Yoast](https://github.com/yoast)
|
92 |
+
|
93 |
+
|
94 |
+
[semver]: http://semver.org/
|
vendor/toolset/toolset-common/lib/whip/src/Whip_Configuration.php
ADDED
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Whip_Configuration
|
5 |
+
*/
|
6 |
+
class Whip_Configuration {
|
7 |
+
|
8 |
+
/**
|
9 |
+
* @var array
|
10 |
+
*/
|
11 |
+
private $configuration;
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Whip_Configuration constructor.
|
15 |
+
*
|
16 |
+
* @param array $configuration The configuration to use.
|
17 |
+
*
|
18 |
+
* @throws Whip_InvalidType
|
19 |
+
*/
|
20 |
+
public function __construct( $configuration = array() ) {
|
21 |
+
if ( ! is_array( $configuration ) ) {
|
22 |
+
throw new Whip_InvalidType( 'Configuration', gettype( $configuration), "array" );
|
23 |
+
}
|
24 |
+
|
25 |
+
$this->configuration = $configuration;
|
26 |
+
}
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Retrieves the configured version of a particular requirement.
|
30 |
+
* If the requirement does not exist, this returns -1.
|
31 |
+
*
|
32 |
+
* @param Whip_Requirement $requirement The requirement to check.
|
33 |
+
*
|
34 |
+
* @return int The version of the passed requirement that was detected.
|
35 |
+
*/
|
36 |
+
public function configuredVersion( Whip_Requirement $requirement ) {
|
37 |
+
if ( ! $this->hasRequirementConfigured( $requirement ) ) {
|
38 |
+
return -1;
|
39 |
+
}
|
40 |
+
|
41 |
+
return $this->configuration[ $requirement->component() ];
|
42 |
+
}
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Determines whether the passed requirement is present in the configuration.
|
46 |
+
*
|
47 |
+
* @param Whip_Requirement $requirement The requirement to check.
|
48 |
+
*
|
49 |
+
* @return bool Whether or not the requirement is present in the configuration.
|
50 |
+
*/
|
51 |
+
public function hasRequirementConfigured( Whip_Requirement $requirement ) {
|
52 |
+
return array_key_exists( $requirement->component(), $this->configuration );
|
53 |
+
}
|
54 |
+
}
|
vendor/toolset/toolset-common/lib/whip/src/Whip_Host.php
ADDED
@@ -0,0 +1,88 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Represents a host
|
5 |
+
*/
|
6 |
+
class Whip_Host {
|
7 |
+
const HOST_NAME_KEY = 'WHIP_NAME_OF_HOST';
|
8 |
+
const HOSTING_PAGE_FILTER_KEY = 'whip_hosting_page_url_wordpress';
|
9 |
+
|
10 |
+
/**
|
11 |
+
* Retrieves the name of the host if set.
|
12 |
+
*
|
13 |
+
* @return string The name of the host.
|
14 |
+
*/
|
15 |
+
public static function name() {
|
16 |
+
$name = (string) getenv( self::HOST_NAME_KEY );
|
17 |
+
|
18 |
+
return self::filterName( $name );
|
19 |
+
}
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Filters the name if we are in a WordPress context. In a non-WordPress content this function just returns the passed name.
|
23 |
+
*
|
24 |
+
* @param string $name The current name of the host.
|
25 |
+
* @returns string The filtered name of the host.
|
26 |
+
*/
|
27 |
+
private static function filterName( $name ) {
|
28 |
+
if ( function_exists( 'apply_filters' ) ) {
|
29 |
+
return (string) apply_filters( strtolower( self::HOST_NAME_KEY ), $name );
|
30 |
+
}
|
31 |
+
|
32 |
+
return $name;
|
33 |
+
}
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Retrieves the message from the host if set.
|
37 |
+
*
|
38 |
+
* @param string $messageKey The key to use as the environment variable.
|
39 |
+
*
|
40 |
+
* @return string The message as set by the host.
|
41 |
+
*/
|
42 |
+
public static function message( $messageKey ) {
|
43 |
+
$message = (string) getenv( $messageKey );
|
44 |
+
|
45 |
+
return self::filterMessage( $messageKey, $message );
|
46 |
+
}
|
47 |
+
|
48 |
+
/**
|
49 |
+
* Filters the message if we are in a WordPress context. In a non-WordPress content this function just returns the passed message.
|
50 |
+
*
|
51 |
+
* @param string $messageKey The key used for the environment variable.
|
52 |
+
* @param string $message The current message from the host.
|
53 |
+
*
|
54 |
+
* @return string
|
55 |
+
*/
|
56 |
+
private static function filterMessage( $messageKey, $message ) {
|
57 |
+
if ( function_exists( 'apply_filters' ) ) {
|
58 |
+
return (string) apply_filters( strtolower( $messageKey ), $message );
|
59 |
+
}
|
60 |
+
|
61 |
+
return $message;
|
62 |
+
}
|
63 |
+
|
64 |
+
/**
|
65 |
+
* Returns the URL for the hosting page
|
66 |
+
*
|
67 |
+
* @returns string The URL to the hosting overview page.
|
68 |
+
*/
|
69 |
+
public static function hostingPageUrl() {
|
70 |
+
$url = 'https://yoa.st/w3';
|
71 |
+
|
72 |
+
return self::filterHostingPageUrl( $url );
|
73 |
+
}
|
74 |
+
|
75 |
+
/**
|
76 |
+
* Filters the hosting page url if we are in a WordPress context. In a non-WordPress context this function just returns a link to the Yoast hosting page.
|
77 |
+
*
|
78 |
+
* @param string $url The previous URL.
|
79 |
+
* @returns string The new URL to the hosting overview page.
|
80 |
+
*/
|
81 |
+
private static function filterHostingPageUrl( $url ) {
|
82 |
+
if ( function_exists( 'apply_filters' ) && apply_filters( self::HOSTING_PAGE_FILTER_KEY, false ) ) {
|
83 |
+
return 'https://wordpress.org/hosting/';
|
84 |
+
}
|
85 |
+
|
86 |
+
return $url;
|
87 |
+
}
|
88 |
+
}
|
vendor/toolset/toolset-common/lib/whip/src/Whip_MessageDismisser.php
ADDED
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* A class to dismiss messages.
|
5 |
+
*/
|
6 |
+
class Whip_MessageDismisser {
|
7 |
+
|
8 |
+
/** @var Whip_DismissStorage */
|
9 |
+
protected $storage;
|
10 |
+
|
11 |
+
/** @var string */
|
12 |
+
protected $currentTime;
|
13 |
+
|
14 |
+
/** @var int */
|
15 |
+
protected $threshold;
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Whip_MessageDismisser constructor.
|
19 |
+
*
|
20 |
+
* @param int $currentTime The current time.
|
21 |
+
* @param int $threshold The number of seconds the message will be dismissed.
|
22 |
+
* @param Whip_DismissStorage $storage Storage object to manage the dismissal state.
|
23 |
+
*/
|
24 |
+
public function __construct( $currentTime, $threshold, Whip_DismissStorage $storage ) {
|
25 |
+
$this->currentTime = $currentTime;
|
26 |
+
$this->threshold = $threshold;
|
27 |
+
$this->storage = $storage;
|
28 |
+
}
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Saves the version number to the storage to indicate the message as being dismissed.
|
32 |
+
*/
|
33 |
+
public function dismiss() {
|
34 |
+
$this->storage->set( $this->currentTime );
|
35 |
+
}
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Checks if the current time is lower than the stored time extended by the threshold.
|
39 |
+
*
|
40 |
+
* @return bool True when current time is lower than stored value + threshold.
|
41 |
+
*/
|
42 |
+
public function isDismissed() {
|
43 |
+
return ( $this->currentTime <= ( $this->storage->get() + $this->threshold ) );
|
44 |
+
}
|
45 |
+
}
|
vendor/toolset/toolset-common/lib/whip/src/Whip_MessageFormatter.php
ADDED
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* A helper class to format messages
|
5 |
+
*/
|
6 |
+
final class Whip_MessageFormatter {
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Wraps a piece of text in HTML strong tags
|
10 |
+
*
|
11 |
+
* @param string $toWrap The text to wrap.
|
12 |
+
* @return string The wrapped text.
|
13 |
+
*/
|
14 |
+
public static function strong( $toWrap ) {
|
15 |
+
return '<strong>' . $toWrap . '</strong>';
|
16 |
+
}
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Wraps a piece of text in HTML p tags
|
20 |
+
*
|
21 |
+
* @param string $toWrap The text to wrap.
|
22 |
+
* @return string The wrapped text.
|
23 |
+
*/
|
24 |
+
public static function paragraph( $toWrap ) {
|
25 |
+
return '<p>' . $toWrap . '</p>';
|
26 |
+
}
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Wraps a piece of text in HTML p and strong tags
|
30 |
+
*
|
31 |
+
* @param string $toWrap The text to wrap.
|
32 |
+
* @return string The wrapped text.
|
33 |
+
*/
|
34 |
+
public static function strongParagraph( $toWrap ) {
|
35 |
+
return self::paragraph( self::strong( $toWrap ) );
|
36 |
+
}
|
37 |
+
}
|
vendor/toolset/toolset-common/lib/whip/src/Whip_MessagesManager.php
ADDED
@@ -0,0 +1,83 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Manages messages using a global to prevent duplicate messages.
|
5 |
+
*/
|
6 |
+
class Whip_MessagesManager {
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Whip_MessagesManager constructor.
|
10 |
+
*/
|
11 |
+
public function __construct()
|
12 |
+
{
|
13 |
+
if ( ! array_key_exists( 'whip_messages', $GLOBALS ) ) {
|
14 |
+
$GLOBALS['whip_messages'] = array();
|
15 |
+
}
|
16 |
+
}
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Adds a message to the Messages Manager.
|
20 |
+
*
|
21 |
+
* @param Whip_Message $message The message to add.
|
22 |
+
*/
|
23 |
+
public function addMessage( Whip_Message $message ) {
|
24 |
+
$whipVersion = require dirname( __FILE__ ) . '/configs/version.php';
|
25 |
+
|
26 |
+
$GLOBALS[ 'whip_messages' ][$whipVersion] = $message;
|
27 |
+
}
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Determines whether or not there are messages available.
|
31 |
+
*
|
32 |
+
* @return bool Whether or not there are messages available.
|
33 |
+
*/
|
34 |
+
public function hasMessages() {
|
35 |
+
return isset( $GLOBALS['whip_messages'] ) && count( $GLOBALS['whip_messages'] ) > 0;
|
36 |
+
}
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Lists the messages that are currently available.
|
40 |
+
*
|
41 |
+
* @return array The messages that are currently set.
|
42 |
+
*/
|
43 |
+
public function listMessages() {
|
44 |
+
return $GLOBALS[ 'whip_messages' ];
|
45 |
+
}
|
46 |
+
|
47 |
+
/**
|
48 |
+
* Deletes all messages.
|
49 |
+
*/
|
50 |
+
public function deleteMessages() {
|
51 |
+
unset( $GLOBALS[ 'whip_messages' ] );
|
52 |
+
}
|
53 |
+
|
54 |
+
/**
|
55 |
+
* Gets the latest message.
|
56 |
+
*
|
57 |
+
* @return Whip_Message The message. Returns a NullMessage if none is found.
|
58 |
+
*/
|
59 |
+
public function getLatestMessage() {
|
60 |
+
if ( ! $this->hasMessages() ) {
|
61 |
+
return new Whip_NullMessage();
|
62 |
+
}
|
63 |
+
|
64 |
+
$messages = $this->sortByVersion( $this->listMessages() );
|
65 |
+
|
66 |
+
$this->deleteMessages();
|
67 |
+
|
68 |
+
return array_pop( $messages );
|
69 |
+
}
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Sorts the list of messages based on the version number.
|
73 |
+
*
|
74 |
+
* @param array $messages The list of messages to sort.
|
75 |
+
*
|
76 |
+
* @return array The sorted list of messages.
|
77 |
+
*/
|
78 |
+
private function sortByVersion( array $messages ) {
|
79 |
+
uksort( $messages, 'version_compare' );
|
80 |
+
|
81 |
+
return $messages;
|
82 |
+
}
|
83 |
+
}
|
vendor/toolset/toolset-common/lib/whip/src/Whip_RequirementsChecker.php
ADDED
@@ -0,0 +1,148 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Main controller class to require a certain version of software.
|
5 |
+
*/
|
6 |
+
class Whip_RequirementsChecker {
|
7 |
+
|
8 |
+
/**
|
9 |
+
* @var array
|
10 |
+
*/
|
11 |
+
private $requirements;
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @var string
|
15 |
+
*/
|
16 |
+
private $textdomain;
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Whip_RequirementsChecker constructor.
|
20 |
+
*
|
21 |
+
* @param array $configuration The configuration to check.
|
22 |
+
* @param string $textdomain The text domain to use for translations.
|
23 |
+
*/
|
24 |
+
public function __construct( $configuration = array(), $textdomain = 'wordpress' ) {
|
25 |
+
$this->requirements = array();
|
26 |
+
$this->configuration = new Whip_Configuration( $configuration );
|
27 |
+
$this->messageMananger = new Whip_MessagesManager();
|
28 |
+
$this->textdomain = $textdomain;
|
29 |
+
}
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Adds a requirement to the list of requirements if it doesn't already exist.
|
33 |
+
*
|
34 |
+
* @param Whip_Requirement $requirement The requirement to add.
|
35 |
+
*/
|
36 |
+
public function addRequirement( Whip_Requirement $requirement ) {
|
37 |
+
// Only allow unique entries to ensure we're not checking specific combinations multiple times
|
38 |
+
if ( $this->requirementExistsForComponent( $requirement->component() ) ) {
|
39 |
+
return;
|
40 |
+
}
|
41 |
+
|
42 |
+
$this->requirements[] = $requirement;
|
43 |
+
}
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Determines whether or not there are requirements available.
|
47 |
+
*
|
48 |
+
* @return bool Whether or not there are requirements.
|
49 |
+
*/
|
50 |
+
public function hasRequirements() {
|
51 |
+
return $this->totalRequirements() > 0;
|
52 |
+
}
|
53 |
+
|
54 |
+
/**
|
55 |
+
* Gets the total amount of requirements.
|
56 |
+
*
|
57 |
+
* @return int The total amount of requirements.
|
58 |
+
*/
|
59 |
+
public function totalRequirements() {
|
60 |
+
return count( $this->requirements );
|
61 |
+
}
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Determines whether or not a requirement exists for a particular component.
|
65 |
+
*
|
66 |
+
* @param string $component The component to check for.
|
67 |
+
*
|
68 |
+
* @return bool Whether or not the component has a requirement defined.
|
69 |
+
*/
|
70 |
+
public function requirementExistsForComponent( $component ) {
|
71 |
+
foreach ( $this->requirements as $requirement ) {
|
72 |
+
if ( $requirement->component() === $component ) {
|
73 |
+
return true;
|
74 |
+
}
|
75 |
+
}
|
76 |
+
|
77 |
+
return false;
|
78 |
+
}
|
79 |
+
|
80 |
+
/**
|
81 |
+
* Determines whether a requirement has been fulfilled.
|
82 |
+
*
|
83 |
+
* @param Whip_Requirement $requirement The requirement to check.
|
84 |
+
*
|
85 |
+
* @return bool Whether or not the requirement is fulfilled.
|
86 |
+
*/
|
87 |
+
private function requirementIsFulfilled( Whip_Requirement $requirement ) {
|
88 |
+
$available_version = $this->configuration->configuredVersion( $requirement );
|
89 |
+
$required_version = $requirement->version();
|
90 |
+
|
91 |
+
if ( in_array( $requirement->operator(), array( '=', '==', '===' ), true ) ) {
|
92 |
+
return -1 !== version_compare( $available_version, $required_version );
|
93 |
+
}
|
94 |
+
|
95 |
+
return version_compare( $available_version, $required_version, $requirement->operator() );
|
96 |
+
}
|
97 |
+
|
98 |
+
/**
|
99 |
+
* Checks if all requirements are fulfilled and adds a message to the message manager if necessary.
|
100 |
+
*/
|
101 |
+
public function check() {
|
102 |
+
foreach ( $this->requirements as $requirement ) {
|
103 |
+
// Match against config
|
104 |
+
$requirement_fulfilled = $this->requirementIsFulfilled( $requirement );
|
105 |
+
|
106 |
+
if ( $requirement_fulfilled ) {
|
107 |
+
continue;
|
108 |
+
}
|
109 |
+
|
110 |
+
$this->addMissingRequirementMessage( $requirement );
|
111 |
+
}
|
112 |
+
}
|
113 |
+
|
114 |
+
/**
|
115 |
+
* Adds a message to the message manager for requirements that cannot be fulfilled.
|
116 |
+
*
|
117 |
+
* @param Whip_Requirement $requirement The requirement that cannot be fulfilled.
|
118 |
+
*/
|
119 |
+
private function addMissingRequirementMessage( Whip_Requirement $requirement ) {
|
120 |
+
switch ( $requirement->component() ) {
|
121 |
+
case 'php':
|
122 |
+
$this->messageMananger->addMessage( new Whip_UpgradePhpMessage( $this->textdomain ) );
|
123 |
+
break;
|
124 |
+
default:
|
125 |
+
$this->messageMananger->addMessage( new Whip_InvalidVersionRequirementMessage( $requirement, $this->configuration->configuredVersion( $requirement ) ) );
|
126 |
+
break;
|
127 |
+
}
|
128 |
+
}
|
129 |
+
|
130 |
+
/**
|
131 |
+
* Determines whether or not there are messages available.
|
132 |
+
*
|
133 |
+
* @return bool Whether or not there are messages to display.
|
134 |
+
*/
|
135 |
+
public function hasMessages() {
|
136 |
+
return $this->messageMananger->hasMessages();
|
137 |
+
}
|
138 |
+
|
139 |
+
/**
|
140 |
+
* Gets the most recent message from the message manager.
|
141 |
+
*
|
142 |
+
* @return Whip_Message The latest message.
|
143 |
+
*/
|
144 |
+
public function getMostRecentMessage() {
|
145 |
+
return $this->messageMananger->getLatestMessage();
|
146 |
+
}
|
147 |
+
|
148 |
+
}
|
vendor/toolset/toolset-common/lib/whip/src/Whip_VersionRequirement.php
ADDED
@@ -0,0 +1,133 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* A value object containing a version requirement for a component version.
|
5 |
+
*/
|
6 |
+
class Whip_VersionRequirement implements Whip_Requirement {
|
7 |
+
/**
|
8 |
+
* @var string
|
9 |
+
*/
|
10 |
+
private $component;
|
11 |
+
|
12 |
+
/**
|
13 |
+
* @var string
|
14 |
+
*/
|
15 |
+
private $version;
|
16 |
+
|
17 |
+
/**
|
18 |
+
* @var string
|
19 |
+
*/
|
20 |
+
private $operator;
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Whip_Requirement constructor.
|
24 |
+
*
|
25 |
+
* @param string $component
|
26 |
+
* @param string $version
|
27 |
+
* @param string $operator
|
28 |
+
*/
|
29 |
+
public function __construct( $component, $version, $operator = '=' ) {
|
30 |
+
$this->validateParameters( $component, $version, $operator );
|
31 |
+
|
32 |
+
$this->component = $component;
|
33 |
+
$this->version = $version;
|
34 |
+
$this->operator = $operator;
|
35 |
+
}
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Gets the component name defined for the requirement.
|
39 |
+
*
|
40 |
+
* @return string The component name.
|
41 |
+
*/
|
42 |
+
public function component() {
|
43 |
+
return $this->component;
|
44 |
+
}
|
45 |
+
|
46 |
+
/**
|
47 |
+
* Gets the components version defined for the requirement.
|
48 |
+
*
|
49 |
+
* @return string
|
50 |
+
*/
|
51 |
+
public function version() {
|
52 |
+
return $this->version;
|
53 |
+
}
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Returns the operator to use when comparing version numbers.
|
57 |
+
*
|
58 |
+
* @return string The comparison operator.
|
59 |
+
*/
|
60 |
+
public function operator() {
|
61 |
+
return $this->operator;
|
62 |
+
}
|
63 |
+
|
64 |
+
/**
|
65 |
+
* Creates a new version requirement from a comparison string
|
66 |
+
*
|
67 |
+
* @throws Whip_InvalidVersionComparisonString When an invalid version comparison string is passed.
|
68 |
+
*
|
69 |
+
*@param string $component The component for this version requirement.
|
70 |
+
* @param string $comparisonString The comparison string for this version requirement.
|
71 |
+
*
|
72 |
+
*@returns Whip_VersionRequirement The parsed version requirement.
|
73 |
+
*/
|
74 |
+
public static function fromCompareString( $component, $comparisonString ) {
|
75 |
+
|
76 |
+
$matcher = '(' .
|
77 |
+
'(>=?)' . // Matches >= and >.
|
78 |
+
'|' .
|
79 |
+
'(<=?)' . // Matches <= and <.
|
80 |
+
')' .
|
81 |
+
'([^>=<\s]+)'; // Matches anything except >, <, =, and whitespace.
|
82 |
+
|
83 |
+
if ( ! preg_match( '#' . $matcher . '#', $comparisonString, $match ) ) {
|
84 |
+
throw new Whip_InvalidVersionComparisonString( $comparisonString );
|
85 |
+
}
|
86 |
+
|
87 |
+
$version = $match[4];
|
88 |
+
$operator = $match[1];
|
89 |
+
|
90 |
+
return new Whip_VersionRequirement( $component, $version, $operator );
|
91 |
+
}
|
92 |
+
|
93 |
+
/**
|
94 |
+
* Validates the parameters passed to the requirement.
|
95 |
+
*
|
96 |
+
* @param string $component The component name.
|
97 |
+
* @param string $version The component version.
|
98 |
+
* @param string $operator The operator to use when comparing version.
|
99 |
+
*
|
100 |
+
* @throws Whip_EmptyProperty
|
101 |
+
* @throws Whip_InvalidOperatorType
|
102 |
+
* @throws Whip_InvalidType
|
103 |
+
*/
|
104 |
+
private function validateParameters( $component, $version, $operator ) {
|
105 |
+
if ( empty( $component ) ) {
|
106 |
+
throw new Whip_EmptyProperty( 'Component' );
|
107 |
+
}
|
108 |
+
|
109 |
+
if ( !is_string( $component ) ) {
|
110 |
+
throw new Whip_InvalidType( 'Component', 'string', $component );
|
111 |
+
}
|
112 |
+
|
113 |
+
if ( empty( $version ) ) {
|
114 |
+
throw new Whip_EmptyProperty( 'Version' );
|
115 |
+
}
|
116 |
+
|
117 |
+
if ( !is_string( $version ) ) {
|
118 |
+
throw new Whip_InvalidType( 'Version', 'string', $version );
|
119 |
+
}
|
120 |
+
|
121 |
+
if ( empty( $operator ) ) {
|
122 |
+
throw new Whip_EmptyProperty( 'Operator' );
|
123 |
+
}
|
124 |
+
|
125 |
+
if ( !is_string( $operator ) ) {
|
126 |
+
throw new Whip_InvalidType( 'Operator', 'string', $operator );
|
127 |
+
}
|
128 |
+
|
129 |
+
if ( ! in_array( $operator, array( '=', '==', '===', '<', '>', '<=', '>=' ), true ) ) {
|
130 |
+
throw new Whip_InvalidOperatorType( $operator );
|
131 |
+
}
|
132 |
+
}
|
133 |
+
}
|
vendor/toolset/toolset-common/lib/whip/src/Whip_WPDismissOption.php
ADDED
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Represents the WordPress option for saving the dismissed messages.
|
5 |
+
*/
|
6 |
+
class Whip_WPDismissOption implements Whip_DismissStorage {
|
7 |
+
|
8 |
+
/** @var string */
|
9 |
+
protected $optionName = 'whip_dismiss_timestamp';
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Saves the value to the options.
|
13 |
+
*
|
14 |
+
* @param int $dismissedValue The value to save.
|
15 |
+
*
|
16 |
+
* @return bool True when successful.
|
17 |
+
*/
|
18 |
+
public function set( $dismissedValue ) {
|
19 |
+
return update_option( $this->optionName, $dismissedValue );
|
20 |
+
}
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Returns the value of the whip_dismissed option.
|
24 |
+
*
|
25 |
+
* @return int Returns the value of the option or an empty string when not set.
|
26 |
+
*/
|
27 |
+
public function get() {
|
28 |
+
$dismissedOption = get_option( $this->optionName );
|
29 |
+
if ( ! $dismissedOption ) {
|
30 |
+
return 0;
|
31 |
+
}
|
32 |
+
|
33 |
+
return (int) $dismissedOption;
|
34 |
+
}
|
35 |
+
|
36 |
+
}
|
vendor/toolset/toolset-common/lib/whip/src/Whip_WPMessageDismissListener.php
ADDED
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Listener for dismissing a message.
|
5 |
+
*/
|
6 |
+
class Whip_WPMessageDismissListener implements Whip_Listener {
|
7 |
+
|
8 |
+
const ACTION_NAME = 'whip_dismiss';
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @var Whip_MessageDismisser
|
12 |
+
*/
|
13 |
+
protected $dismisser;
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Sets the dismisser attribute.
|
17 |
+
*
|
18 |
+
* @param Whip_MessageDismisser $dismisser The object for dismissing a message.
|
19 |
+
*/
|
20 |
+
public function __construct( Whip_MessageDismisser $dismisser ) {
|
21 |
+
$this->dismisser = $dismisser;
|
22 |
+
}
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Listens to a GET request to fetch the required attributes.
|
26 |
+
*
|
27 |
+
* @return void
|
28 |
+
*/
|
29 |
+
public function listen() {
|
30 |
+
$action = filter_input( INPUT_GET, 'action' );
|
31 |
+
$nonce = filter_input( INPUT_GET, 'nonce' );
|
32 |
+
|
33 |
+
if ( $action === self::ACTION_NAME && wp_verify_nonce( $nonce, self::ACTION_NAME ) ) {
|
34 |
+
$this->dismisser->dismiss();
|
35 |
+
}
|
36 |
+
}
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Creates an url for dismissing the notice.
|
40 |
+
*
|
41 |
+
* @return string The url for dismissing the message.
|
42 |
+
*/
|
43 |
+
public function getDismissURL() {
|
44 |
+
return sprintf(
|
45 |
+
admin_url( 'index.php?action=%1$s&nonce=%2$s' ),
|
46 |
+
self::ACTION_NAME,
|
47 |
+
wp_create_nonce( self::ACTION_NAME )
|
48 |
+
);
|
49 |
+
}
|
50 |
+
|
51 |
+
}
|
vendor/toolset/toolset-common/lib/whip/src/configs/default.php
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
return array(
|
4 |
+
'php' => PHP_VERSION,
|
5 |
+
);
|
vendor/toolset/toolset-common/lib/whip/src/configs/version.php
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
return '1.0.1';
|
vendor/toolset/toolset-common/lib/whip/src/exceptions/Whip_EmptyProperty.php
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class EmptyProperty
|
5 |
+
*/
|
6 |
+
class Whip_EmptyProperty extends Exception {
|
7 |
+
public function __construct( $property ) {
|
8 |
+
parent::__construct( sprintf( '%s cannot be empty.', (string) $property ) );
|
9 |
+
}
|
10 |
+
}
|
vendor/toolset/toolset-common/lib/whip/src/exceptions/Whip_InvalidOperatorType.php
ADDED
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class InvalidOperatorType
|
5 |
+
*/
|
6 |
+
class Whip_InvalidOperatorType extends Exception {
|
7 |
+
|
8 |
+
private $validOperators = array( '=', '==', '===', '<', '>', '<=', '>=' );
|
9 |
+
|
10 |
+
/**
|
11 |
+
* InvalidOperatorType constructor.
|
12 |
+
*
|
13 |
+
* @param string $value
|
14 |
+
*/
|
15 |
+
public function __construct( $value ) {
|
16 |
+
parent::__construct(
|
17 |
+
sprintf( 'Invalid operator of %s used. Please use one of the following operators: %s',
|
18 |
+
$value,
|
19 |
+
implode( ', ', $this->validOperators )
|
20 |
+
) );
|
21 |
+
}
|
22 |
+
}
|
vendor/toolset/toolset-common/lib/whip/src/exceptions/Whip_InvalidType.php
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class InvalidType
|
5 |
+
*/
|
6 |
+
class Whip_InvalidType extends Exception {
|
7 |
+
|
8 |
+
/**
|
9 |
+
* InvalidType constructor.
|
10 |
+
*
|
11 |
+
* @param string $property
|
12 |
+
* @param string $value
|
13 |
+
* @param string $expectedType
|
14 |
+
*/
|
15 |
+
public function __construct( $property, $value, $expectedType ) {
|
16 |
+
parent::__construct( sprintf( '%s should be of type %s. Found %s.', $property, $expectedType, gettype( $value ) ) );
|
17 |
+
}
|
18 |
+
}
|
vendor/toolset/toolset-common/lib/whip/src/exceptions/Whip_InvalidVersionComparisonString.php
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Exception for an invalid version comparison string
|
5 |
+
*/
|
6 |
+
class Whip_InvalidVersionComparisonString extends Exception {
|
7 |
+
|
8 |
+
/**
|
9 |
+
* @param string $value The passed version comparison string.
|
10 |
+
*/
|
11 |
+
public function __construct( $value ) {
|
12 |
+
parent::__construct(
|
13 |
+
sprintf(
|
14 |
+
'Invalid version comparison string. Example of a valid version comparison string: >=5.3. Passed version comparison string: %s',
|
15 |
+
$value
|
16 |
+
)
|
17 |
+
);
|
18 |
+
}
|
19 |
+
}
|
vendor/toolset/toolset-common/lib/whip/src/facades/wordpress.php
ADDED
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
if ( ! function_exists( 'whip_wp_check_versions' ) ) {
|
4 |
+
/**
|
5 |
+
* Facade to quickly check if version requirements are met.
|
6 |
+
*
|
7 |
+
* @param array $requirements The requirements to check.
|
8 |
+
*/
|
9 |
+
function whip_wp_check_versions( $requirements ) {
|
10 |
+
// Only show for admin users.
|
11 |
+
if ( ! is_array( $requirements ) ) {
|
12 |
+
return;
|
13 |
+
}
|
14 |
+
|
15 |
+
$config = include dirname( __FILE__ ) . '/../configs/default.php';
|
16 |
+
$checker = new Whip_RequirementsChecker( $config );
|
17 |
+
|
18 |
+
foreach ( $requirements as $component => $versionComparison ) {
|
19 |
+
$checker->addRequirement( Whip_VersionRequirement::fromCompareString( $component, $versionComparison ) );
|
20 |
+
}
|
21 |
+
|
22 |
+
$checker->check();
|
23 |
+
|
24 |
+
if ( ! $checker->hasMessages() ) {
|
25 |
+
return;
|
26 |
+
}
|
27 |
+
|
28 |
+
$dismissThreshold = WEEK_IN_SECONDS * 4;
|
29 |
+
$dismissMessage = __( 'Remind me again in 4 weeks.', 'wordpress' );
|
30 |
+
|
31 |
+
$dismisser = new Whip_MessageDismisser( time(), $dismissThreshold, new Whip_WPDismissOption() );
|
32 |
+
|
33 |
+
$presenter = new Whip_WPMessagePresenter( $checker->getMostRecentMessage(), $dismisser, $dismissMessage );
|
34 |
+
$presenter->register_hooks();
|
35 |
+
}
|
36 |
+
}
|
vendor/toolset/toolset-common/lib/whip/src/interfaces/Whip_DismissStorage.php
ADDED
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Interface Whip_DismissStorage.
|
5 |
+
*/
|
6 |
+
interface Whip_DismissStorage {
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Saves the value.
|
10 |
+
*
|
11 |
+
* @param int $dismissedValue The value to save.
|
12 |
+
*
|
13 |
+
* @return bool True when successful.
|
14 |
+
*/
|
15 |
+
public function set( $dismissedValue );
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Returns the value.
|
19 |
+
*
|
20 |
+
* @return int The stored value.
|
21 |
+
*/
|
22 |
+
public function get();
|
23 |
+
|
24 |
+
}
|
vendor/toolset/toolset-common/lib/whip/src/interfaces/Whip_Listener.php
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Interface Whip_Listener.
|
5 |
+
*/
|
6 |
+
interface Whip_Listener {
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Method that should implement the listen functionality.
|
10 |
+
*
|
11 |
+
* @return void
|
12 |
+
*/
|
13 |
+
public function listen();
|
14 |
+
|
15 |
+
}
|
vendor/toolset/toolset-common/lib/whip/src/interfaces/Whip_Message.php
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Interface Whip_Message
|
5 |
+
*/
|
6 |
+
interface Whip_Message {
|
7 |
+
public function body();
|
8 |
+
}
|
vendor/toolset/toolset-common/lib/whip/src/interfaces/Whip_MessagePresenter.php
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
|
4 |
+
interface Whip_MessagePresenter {
|
5 |
+
|
6 |
+
/**
|
7 |
+
* Renders the message.
|
8 |
+
*/
|
9 |
+
public function renderMessage();
|
10 |
+
}
|
vendor/toolset/toolset-common/lib/whip/src/interfaces/Whip_Requirement.php
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Interface Whip_Requirement
|
5 |
+
*/
|
6 |
+
interface Whip_Requirement {
|
7 |
+
public function component();
|
8 |
+
}
|
vendor/toolset/toolset-common/lib/whip/src/interfaces/Whip_VersionDetector.php
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* An interface that represents a version detector and message.
|
5 |
+
*/
|
6 |
+
interface Whip_VersionDetector {
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Detects the version of the installed software
|
10 |
+
*
|
11 |
+
* @return string
|
12 |
+
*/
|
13 |
+
public function detect();
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Returns the message that should be shown if a version is not deemed appropriate by the implementation.
|
17 |
+
*
|
18 |
+
* @return string
|
19 |
+
*/
|
20 |
+
public function getMessage();
|
21 |
+
}
|
vendor/toolset/toolset-common/lib/whip/src/messages/Whip_BasicMessage.php
ADDED
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Whip_Message
|
5 |
+
*/
|
6 |
+
class Whip_BasicMessage implements Whip_Message {
|
7 |
+
/**
|
8 |
+
* @var string
|
9 |
+
*/
|
10 |
+
private $body;
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Whip_Message constructor.
|
14 |
+
*
|
15 |
+
* @param string $body
|
16 |
+
*
|
17 |
+
* @throws Whip_EmptyProperty
|
18 |
+
* @throws Whip_InvalidType
|
19 |
+
*/
|
20 |
+
public function __construct($body) {
|
21 |
+
$this->validateParameters( $body );
|
22 |
+
|
23 |
+
$this->body = $body;
|
24 |
+
}
|
25 |
+
|
26 |
+
/**
|
27 |
+
* @return string
|
28 |
+
*/
|
29 |
+
public function body() {
|
30 |
+
return $this->body;
|
31 |
+
}
|
32 |
+
|
33 |
+
private function validateParameters( $body ) {
|
34 |
+
if ( empty( $body ) ) {
|
35 |
+
throw new Whip_EmptyProperty( 'Message body' );
|
36 |
+
}
|
37 |
+
|
38 |
+
if ( ! is_string( $body ) ) {
|
39 |
+
throw new Whip_InvalidType( 'Message body', "string", $body );
|
40 |
+
}
|
41 |
+
}
|
42 |
+
}
|
vendor/toolset/toolset-common/lib/whip/src/messages/Whip_HostMessage.php
ADDED
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Whip_HostMessage
|
5 |
+
*/
|
6 |
+
class Whip_HostMessage implements Whip_Message {
|
7 |
+
|
8 |
+
/**
|
9 |
+
* @var string
|
10 |
+
*/
|
11 |
+
private $textdomain;
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @var string
|
15 |
+
*/
|
16 |
+
private $messageKey;
|
17 |
+
|
18 |
+
/**
|
19 |
+
* @var string
|
20 |
+
*/
|
21 |
+
private $filterKey;
|
22 |
+
|
23 |
+
/**
|
24 |
+
* Whip_Message constructor.
|
25 |
+
*
|
26 |
+
* @param string $messageKey The environment key to use to retrieve the message from.
|
27 |
+
* @param string $textdomain The text domain to use for translations.
|
28 |
+
*/
|
29 |
+
public function __construct( $messageKey, $textdomain ) {
|
30 |
+
$this->textdomain = $textdomain;
|
31 |
+
$this->messageKey = $messageKey;
|
32 |
+
}
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Renders the message body.
|
36 |
+
*
|
37 |
+
* @return string The message body.
|
38 |
+
*/
|
39 |
+
public function body() {
|
40 |
+
$message = array();
|
41 |
+
|
42 |
+
$message[] = Whip_MessageFormatter::strong( $this->title() ) . '<br />';
|
43 |
+
$message[] = Whip_MessageFormatter::paragraph( Whip_Host::message( $this->messageKey, $this->filterKey ) );
|
44 |
+
|
45 |
+
return implode( $message, "\n" );
|
46 |
+
}
|
47 |
+
|
48 |
+
/**
|
49 |
+
* Renders the message title.
|
50 |
+
*
|
51 |
+
* @return string The message title.
|
52 |
+
*/
|
53 |
+
public function title() {
|
54 |
+
return sprintf( __( 'A message from %1$s', $this->textdomain ), Whip_Host::name() );
|
55 |
+
}
|
56 |
+
}
|
vendor/toolset/toolset-common/lib/whip/src/messages/Whip_InvalidVersionRequirementMessage.php
ADDED
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Whip_InvalidVersionMessage
|
5 |
+
*/
|
6 |
+
class Whip_InvalidVersionRequirementMessage implements Whip_Message {
|
7 |
+
|
8 |
+
private $requirement;
|
9 |
+
/**
|
10 |
+
* @var
|
11 |
+
*/
|
12 |
+
private $detected;
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Whip_InvalidVersionRequirementMessage constructor.
|
16 |
+
*
|
17 |
+
* @param Whip_Requirement $requirement
|
18 |
+
* @param $detected
|
19 |
+
*/
|
20 |
+
public function __construct( Whip_VersionRequirement $requirement, $detected )
|
21 |
+
{
|
22 |
+
$this->requirement = $requirement;
|
23 |
+
$this->detected = $detected;
|
24 |
+
}
|
25 |
+
|
26 |
+
/**
|
27 |
+
* @return string
|
28 |
+
*/
|
29 |
+
public function body() {
|
30 |
+
return sprintf(
|
31 |
+
'Invalid version detected for %s. Found %s but expected %s.',
|
32 |
+
$this->requirement->component(),
|
33 |
+
$this->detected,
|
34 |
+
$this->requirement->version()
|
35 |
+
);
|
36 |
+
}
|
37 |
+
}
|
vendor/toolset/toolset-common/lib/whip/src/messages/Whip_NullMessage.php
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Whip_Message
|
5 |
+
*/
|
6 |
+
class Whip_NullMessage implements Whip_Message {
|
7 |
+
/**
|
8 |
+
* @return string
|
9 |
+
*/
|
10 |
+
public function body() {
|
11 |
+
return '';
|
12 |
+
}
|
13 |
+
}
|
vendor/toolset/toolset-common/lib/whip/src/messages/Whip_UpgradePhpMessage.php
ADDED
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Whip_UpgradePhpMessage
|
5 |
+
*/
|
6 |
+
class Whip_UpgradePhpMessage implements Whip_Message {
|
7 |
+
/**
|
8 |
+
* @var string
|
9 |
+
*/
|
10 |
+
private $textdomain;
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Whip_UpgradePhpMessage constructor.
|
14 |
+
*
|
15 |
+
* @param string $textdomain The text domain to use for the translations.
|
16 |
+
*/
|
17 |
+
public function __construct( $textdomain ) {
|
18 |
+
$this->textdomain = $textdomain;
|
19 |
+
}
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Composes the body of the message to display.
|
23 |
+
*
|
24 |
+
* @return string The message to display.
|
25 |
+
*/
|
26 |
+
public function body() {
|
27 |
+
$textdomain = $this->textdomain;
|
28 |
+
|
29 |
+
$message = array();
|
30 |
+
|
31 |
+
$message[] = Whip_MessageFormatter::strongParagraph( __( 'Your site could be faster and more secure with a newer PHP version.', $textdomain ) ) . '<br />';
|
32 |
+
$message[] = Whip_MessageFormatter::paragraph( __( 'Hey, we\'ve noticed that you\'re running an outdated version of PHP. PHP is the programming language that WordPress and Toolset are built on. The version that is currently used for your site is no longer supported. Newer versions of PHP are both faster and more secure. In fact, your version of PHP no longer receives security updates, which is why we\'re sending you to this notice.', $textdomain ) );
|
33 |
+
$message[] = Whip_MessageFormatter::paragraph( __( 'Hosts have the ability to update your PHP version, but sometimes they don\'t dare to do that because they\'re afraid they\'ll break your site.', $textdomain ) );
|
34 |
+
$message[] = Whip_MessageFormatter::strongParagraph( __( 'To which version should I update?', $textdomain ) ) . '<br />';
|
35 |
+
$message[] = Whip_MessageFormatter::paragraph( sprintf( __( 'You should update your PHP version to either 5.6 or to 7.0 or 7.1. On a normal WordPress site, switching to PHP 5.6 should never cause issues. We would however actually recommend you switch to PHP7. There are some plugins that are not ready for PHP7 though, so do some testing first. There is a WordPress plugin that can test whether that\'s an option for you %1$shere%2$s. PHP7 is much faster than PHP 5.6. It\'s also the only PHP version still in active development and therefore the better option for your site in the long run.', $textdomain ), '<a href="https://wordpress.org/plugins/php-compatibility-checker/" target="_blank">', '</a>' ) );
|
36 |
+
|
37 |
+
if ( Whip_Host::name() !== '' ) {
|
38 |
+
$hostMessage = new Whip_HostMessage( 'WHIP_MESSAGE_FROM_HOST_ABOUT_PHP', $textdomain );
|
39 |
+
$message[] = $hostMessage->body();
|
40 |
+
}
|
41 |
+
|
42 |
+
$hostingPageUrl = Whip_Host::hostingPageUrl();
|
43 |
+
|
44 |
+
$message[] = Whip_MessageFormatter::strongParagraph( __( 'Can\'t update? Ask your host!', $textdomain ) ) . '<br />';
|
45 |
+
$message[] = Whip_MessageFormatter::paragraph( sprintf( __( 'If you cannot upgrade your PHP version yourself, you can send an email to your host. There are some %1$sexamples here%2$s. If they don\'t want to upgrade your PHP version, we would suggest you switch hosts. Have a look at one of the recommended %3$sWordPress hosting partners%4$s recommended by Yoast.', $textdomain ), '<a href="https://yoa.st/wh" target="_blank">', '</a>', sprintf( '<a href="%1$s" target="_blank">', esc_url( $hostingPageUrl ) ), '</a>' ) );
|
46 |
+
|
47 |
+
return implode( $message, "\n" );
|
48 |
+
}
|
49 |
+
|
50 |
+
}
|
vendor/toolset/toolset-common/lib/whip/src/presenters/Whip_WPMessagePresenter.php
ADDED
@@ -0,0 +1,83 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* A message presenter to show a WordPress notice.
|
5 |
+
*/
|
6 |
+
class Whip_WPMessagePresenter implements Whip_MessagePresenter {
|
7 |
+
|
8 |
+
/** @var string The string to show to dismiss the message. */
|
9 |
+
private $dismissMessage;
|
10 |
+
|
11 |
+
/** @var Whip_Message The message to be displayed */
|
12 |
+
private $message;
|
13 |
+
|
14 |
+
/** @var Whip_MessageDismisser */
|
15 |
+
private $dismisser;
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Whip_WPMessagePresenter constructor.
|
19 |
+
*
|
20 |
+
* @param Whip_Message $message The message to use in the presenter.
|
21 |
+
* @param Whip_MessageDismisser $dismisser Dismisser object.
|
22 |
+
* @param string $dismissMessage The copy to show to dismiss the message.
|
23 |
+
*/
|
24 |
+
public function __construct( Whip_Message $message, Whip_MessageDismisser $dismisser, $dismissMessage ) {
|
25 |
+
$this->message = $message;
|
26 |
+
$this->dismisser = $dismisser;
|
27 |
+
$this->dismissMessage = $dismissMessage;
|
28 |
+
}
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Registers hooks to WordPress. This is a separate function so you can
|
32 |
+
* control when the hooks are registered.
|
33 |
+
*
|
34 |
+
*/
|
35 |
+
public function register_hooks() {
|
36 |
+
global $whip_admin_notices_added;
|
37 |
+
|
38 |
+
if ( null === $whip_admin_notices_added || ! $whip_admin_notices_added ) {
|
39 |
+
add_action( 'admin_notices', array( $this, 'renderMessage' ) );
|
40 |
+
$whip_admin_notices_added = true;
|
41 |
+
}
|
42 |
+
}
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Renders the messages present in the global to notices.
|
46 |
+
*/
|
47 |
+
public function renderMessage() {
|
48 |
+
$dismissListener = new Whip_WPMessageDismissListener( $this->dismisser );
|
49 |
+
$dismissListener->listen();
|
50 |
+
|
51 |
+
if ( $this->dismisser->isDismissed() ) {
|
52 |
+
return;
|
53 |
+
}
|
54 |
+
|
55 |
+
$dismissButton = sprintf(
|
56 |
+
'<a href="%2$s">%1$s</a>',
|
57 |
+
$this->dismissMessage,
|
58 |
+
$dismissListener->getDismissURL()
|
59 |
+
);
|
60 |
+
|
61 |
+
printf( '<div class="error"><p>%1$s</p><p>%2$s</p></div>', $this->kses( $this->message->body() ), $dismissButton );
|
62 |
+
}
|
63 |
+
|
64 |
+
/**
|
65 |
+
* Removes content from the message that we don't want to show.
|
66 |
+
*
|
67 |
+
* @param string $message The message to clean.
|
68 |
+
*
|
69 |
+
* @return string The cleaned message.
|
70 |
+
*/
|
71 |
+
public function kses( $message ) {
|
72 |
+
return wp_kses( $message, array(
|
73 |
+
'a' => array(
|
74 |
+
'href' => true,
|
75 |
+
'target' => true,
|
76 |
+
),
|
77 |
+
'strong' => true,
|
78 |
+
'p' => true,
|
79 |
+
'ul' => true,
|
80 |
+
'li' => true,
|
81 |
+
) );
|
82 |
+
}
|
83 |
+
}
|
vendor/toolset/toolset-common/loader.php
CHANGED
@@ -27,7 +27,7 @@
|
|
27 |
* Now that we have a unique version for all plugins
|
28 |
* we define the version here
|
29 |
*/
|
30 |
-
$toolset_common_version =
|
31 |
|
32 |
|
33 |
/* ---------------------------------------------------------------------- *\
|
@@ -88,4 +88,4 @@ if ( ! function_exists( 'toolset_common_initialize' ) ) {
|
|
88 |
}
|
89 |
}
|
90 |
}
|
91 |
-
}
|
27 |
* Now that we have a unique version for all plugins
|
28 |
* we define the version here
|
29 |
*/
|
30 |
+
$toolset_common_version = 262000;
|
31 |
|
32 |
|
33 |
/* ---------------------------------------------------------------------- *\
|
88 |
}
|
89 |
}
|
90 |
}
|
91 |
+
}
|
vendor/toolset/toolset-common/recreate_classmap.sh
CHANGED
@@ -42,11 +42,12 @@ echo
|
|
42 |
# the main plugin structure - overwrites existing classmap
|
43 |
echo "Generating classmap for autoloaded classes..."
|
44 |
php "$GENERATOR" --library ./inc/autoloaded --output ./autoload_classmap.php --overwrite
|
45 |
-
php "$GENERATOR" --library ./inc/controller --output ./autoload_classmap.php --append
|
46 |
php "$GENERATOR" --library ./utility/admin --output ./autoload_classmap.php --append
|
47 |
php "$GENERATOR" --library ./utility/condition --output ./autoload_classmap.php --append
|
|
|
48 |
php "$GENERATOR" --library ./user-editors --output ./autoload_classmap.php --append
|
49 |
php "$GENERATOR" --library ./expression-parser --output ./autoload_classmap.php --append
|
|
|
50 |
sort_classmap ./autoload_classmap.php
|
51 |
echo
|
52 |
|
42 |
# the main plugin structure - overwrites existing classmap
|
43 |
echo "Generating classmap for autoloaded classes..."
|
44 |
php "$GENERATOR" --library ./inc/autoloaded --output ./autoload_classmap.php --overwrite
|
|
|
45 |
php "$GENERATOR" --library ./utility/admin --output ./autoload_classmap.php --append
|
46 |
php "$GENERATOR" --library ./utility/condition --output ./autoload_classmap.php --append
|
47 |
+
php "$GENERATOR" --library ./toolset-blocks --output ./autoload_classmap.php --append
|
48 |
php "$GENERATOR" --library ./user-editors --output ./autoload_classmap.php --append
|
49 |
php "$GENERATOR" --library ./expression-parser --output ./autoload_classmap.php --append
|
50 |
+
php "$GENERATOR" --library ./lib/whip/src --output ./autoload_classmap.php --append
|
51 |
sort_classmap ./autoload_classmap.php
|
52 |
echo
|
53 |
|
vendor/toolset/toolset-common/res/css/toolset-dialogs.css
CHANGED
@@ -26,6 +26,12 @@
|
|
26 |
}
|
27 |
.toolset-ui-dialog .ui-dialog-title {
|
28 |
float: none !important;
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
}
|
30 |
.toolset-ui-dialog .ui-widget{
|
31 |
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", "Open Sans", sans-serif;
|
@@ -81,7 +87,7 @@
|
|
81 |
filter: alpha(opacity=70) !important;
|
82 |
z-index: 100101;
|
83 |
}
|
84 |
-
.toolset-ui-dialog .ui-
|
85 |
background: 0 0 !important;
|
86 |
border: none !important;
|
87 |
-webkit-box-shadow: none !important;
|
@@ -98,7 +104,7 @@
|
|
98 |
height: 36px !important;
|
99 |
text-align: center !important;
|
100 |
}
|
101 |
-
.toolset-ui-dialog .ui-
|
102 |
color: #00a0d2 !important;
|
103 |
}
|
104 |
.toolset-ui-dialog .ui-icon {
|
@@ -166,6 +172,14 @@
|
|
166 |
font-size: 11px !important;
|
167 |
letter-spacing: normal;
|
168 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
169 |
/**
|
170 |
* Shortcodes dialogs styles: listing dialog.
|
171 |
*/
|
@@ -302,6 +316,7 @@
|
|
302 |
|
303 |
.toolset-shortcode-gui-dialog-container + .ui-dialog-buttonpane button {
|
304 |
float: left;
|
|
|
305 |
margin-right: 10px;
|
306 |
}
|
307 |
|
@@ -318,13 +333,73 @@
|
|
318 |
.toolset-shortcode-gui-dialog-container .toolset-mightlong-list {
|
319 |
margin: 0;
|
320 |
}
|
321 |
-
.toolset-shortcode-gui-dialog-container
|
322 |
min-height: 24px;
|
323 |
min-width: 45%;
|
324 |
float: left;
|
325 |
padding-right: 4%;
|
326 |
margin: 0 0 6px;
|
327 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
328 |
/*********************************************
|
329 |
Toolset Confirmation Dialog
|
330 |
|
@@ -332,14 +407,13 @@ Toolset Confirmation Dialog
|
|
332 |
|
333 |
*********************************************/
|
334 |
.toolset-confirmation-dialog {
|
|
|
|
|
335 |
display: flex;
|
336 |
}
|
337 |
.toolset-confirmation-dialog-icon {
|
338 |
padding: 17px 15px 20px;
|
339 |
-
box-sizing: border-box;
|
340 |
-
}
|
341 |
-
.toolset-confirmation-dialog-content {
|
342 |
-
padding: 15px;
|
343 |
box-sizing: border-box;
|
344 |
}
|
345 |
@media (min-width: 768px) {
|
@@ -349,5 +423,9 @@ Toolset Confirmation Dialog
|
|
349 |
}
|
350 |
}
|
351 |
.toolset-confirmation-dialog-content {
|
352 |
-
|
|
|
|
|
|
|
|
|
353 |
}
|
26 |
}
|
27 |
.toolset-ui-dialog .ui-dialog-title {
|
28 |
float: none !important;
|
29 |
+
display: block;
|
30 |
+
white-space: nowrap;
|
31 |
+
width: 100%;
|
32 |
+
overflow: hidden;
|
33 |
+
text-overflow: ellipsis;
|
34 |
+
|
35 |
}
|
36 |
.toolset-ui-dialog .ui-widget{
|
37 |
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", "Open Sans", sans-serif;
|
87 |
filter: alpha(opacity=70) !important;
|
88 |
z-index: 100101;
|
89 |
}
|
90 |
+
.toolset-ui-dialog .ui-dialog-titlebar-close {
|
91 |
background: 0 0 !important;
|
92 |
border: none !important;
|
93 |
-webkit-box-shadow: none !important;
|
104 |
height: 36px !important;
|
105 |
text-align: center !important;
|
106 |
}
|
107 |
+
.toolset-ui-dialog .ui-dialog-titlebar-close:hover {
|
108 |
color: #00a0d2 !important;
|
109 |
}
|
110 |
.toolset-ui-dialog .ui-icon {
|
172 |
font-size: 11px !important;
|
173 |
letter-spacing: normal;
|
174 |
}
|
175 |
+
.toolset-ui-dialog .toolset-option-helper-text {
|
176 |
+
display: block;
|
177 |
+
color: #999;
|
178 |
+
font-size: 0.9em;
|
179 |
+
}
|
180 |
+
.toolset-ui-dialog .toolset-option-label-disabled {
|
181 |
+
color: #999;
|
182 |
+
}
|
183 |
/**
|
184 |
* Shortcodes dialogs styles: listing dialog.
|
185 |
*/
|
316 |
|
317 |
.toolset-shortcode-gui-dialog-container + .ui-dialog-buttonpane button {
|
318 |
float: left;
|
319 |
+
margin-left: 0;
|
320 |
margin-right: 10px;
|
321 |
}
|
322 |
|
333 |
.toolset-shortcode-gui-dialog-container .toolset-mightlong-list {
|
334 |
margin: 0;
|
335 |
}
|
336 |
+
.toolset-shortcode-gui-dialog-container .toolset-mightlong-list > li {
|
337 |
min-height: 24px;
|
338 |
min-width: 45%;
|
339 |
float: left;
|
340 |
padding-right: 4%;
|
341 |
margin: 0 0 6px;
|
342 |
}
|
343 |
+
/**
|
344 |
+
* Shortcodes dialogs styles: shortcodes wizard.
|
345 |
+
*/
|
346 |
+
.toolset-shortcode-gui-wizard-options-container {
|
347 |
+
display: flex;
|
348 |
+
text-align: center;
|
349 |
+
}
|
350 |
+
.toolset-shortcode-gui-wizard-option {
|
351 |
+
position: relative;
|
352 |
+
flex: 1;
|
353 |
+
margin: 0 10px 0 0;
|
354 |
+
padding: 10px;
|
355 |
+
background: #fafafa;
|
356 |
+
border: solid 1px #ccc;
|
357 |
+
border-radius: 5px;
|
358 |
+
vertical-align: top;
|
359 |
+
}
|
360 |
+
.toolset-shortcode-gui-wizard-option:last-child {
|
361 |
+
margin: 0;
|
362 |
+
}
|
363 |
+
.toolset-shortcode-gui-wizard-option-selected.toolset-shortcode-gui-wizard-option-has-settings::before,
|
364 |
+
.toolset-shortcode-gui-wizard-option-selected.toolset-shortcode-gui-wizard-option-has-settings::after{
|
365 |
+
content: '';
|
366 |
+
position: absolute;
|
367 |
+
left: 42%;
|
368 |
+
top: 100%;
|
369 |
+
width: 0;
|
370 |
+
height: 0;
|
371 |
+
border-left: 20px solid transparent;
|
372 |
+
border-right: 20px solid transparent;
|
373 |
+
border-top: 20px solid #e4e4e4;
|
374 |
+
clear: both;
|
375 |
+
}
|
376 |
+
.toolset-shortcode-gui-wizard-option-selected.toolset-shortcode-gui-wizard-option-has-settings::before {
|
377 |
+
border-color: #999 transparent transparent transparent;
|
378 |
+
border-width: 21px;
|
379 |
+
}
|
380 |
+
.toolset-shortcode-gui-wizard-option input[type="radio"].toolset-shortcode-gui-wizard-option-hidden {
|
381 |
+
display: none;
|
382 |
+
}
|
383 |
+
.toolset-shortcode-gui-wizard-option-selected {
|
384 |
+
background: #e4e4e4;
|
385 |
+
border-color: #999;
|
386 |
+
}
|
387 |
+
.toolset-shortcode-gui-wizard-option-disabled {
|
388 |
+
background: #fff;
|
389 |
+
}
|
390 |
+
.toolset-shortcode-gui-wizard-option-disabled * {
|
391 |
+
color: #999;
|
392 |
+
}
|
393 |
+
.toolset-shortcode-gui-wizard-option-icon {
|
394 |
+
display: inline-block;
|
395 |
+
width: 100%;
|
396 |
+
padding-bottom: 10px;
|
397 |
+
}
|
398 |
+
.toolset-shortcode-gui-wizard-option-extra {
|
399 |
+
padding: 0 30px;
|
400 |
+
margin-top: 30px;
|
401 |
+
border-top: solid 1px #ccc;
|
402 |
+
}
|
403 |
/*********************************************
|
404 |
Toolset Confirmation Dialog
|
405 |
|
407 |
|
408 |
*********************************************/
|
409 |
.toolset-confirmation-dialog {
|
410 |
+
display: -webkit-box;
|
411 |
+
display: -ms-flexbox;
|
412 |
display: flex;
|
413 |
}
|
414 |
.toolset-confirmation-dialog-icon {
|
415 |
padding: 17px 15px 20px;
|
416 |
+
-webkit-box-sizing: border-box;
|
|
|
|
|
|
|
417 |
box-sizing: border-box;
|
418 |
}
|
419 |
@media (min-width: 768px) {
|
423 |
}
|
424 |
}
|
425 |
.toolset-confirmation-dialog-content {
|
426 |
+
padding: 15px;
|
427 |
+
box-sizing: border-box;
|
428 |
+
}
|
429 |
+
.toolset-confirmation-dialog-content > :first-child {
|
430 |
+
margin-top: 0;
|
431 |
}
|
vendor/toolset/toolset-common/res/css/toolset-notifications.css
CHANGED
@@ -240,6 +240,16 @@ span.toolset-alert {
|
|
240 |
/* TOOLSET POINTERS */
|
241 |
/* ---------------- */
|
242 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
243 |
.wp-toolset-pointer .wp-pointer-content {
|
244 |
border: 1px solid #EF6223;
|
245 |
background: #e9e9e9;
|
240 |
/* TOOLSET POINTERS */
|
241 |
/* ---------------- */
|
242 |
|
243 |
+
.wp-toolset-pointer-trigger {
|
244 |
+
cursor: pointer;
|
245 |
+
color: #0073aa;
|
246 |
+
vertical-align: middle;
|
247 |
+
}
|
248 |
+
|
249 |
+
.wp-toolset-pointer-content {
|
250 |
+
display: none;
|
251 |
+
}
|
252 |
+
|
253 |
.wp-toolset-pointer .wp-pointer-content {
|
254 |
border: 1px solid #EF6223;
|
255 |
background: #e9e9e9;
|
vendor/toolset/toolset-common/res/js/toolset-bs-component-grids.js
CHANGED
@@ -244,6 +244,14 @@ ToolsetCommon.BootstrapCssComponentsGrids = function( $ ) {
|
|
244 |
.find( '.js-code-editor-toolbar > ul' );
|
245 |
appendGridButtonIfMissing( toolbarList, toolbarButton );
|
246 |
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
247 |
case 'content':
|
248 |
// CRED main editors
|
249 |
if (
|
244 |
.find( '.js-code-editor-toolbar > ul' );
|
245 |
appendGridButtonIfMissing( toolbarList, toolbarButton );
|
246 |
break;
|
247 |
+
case 'cred_association_form_content':
|
248 |
+
// CRED association forms editor
|
249 |
+
var toolbarButton = $( button ),
|
250 |
+
toolbarList = editor
|
251 |
+
.closest( '#association_form_content' )
|
252 |
+
.find( '.js-cred-content-editor-toolbar' );
|
253 |
+
appendGridButtonIfMissing( toolbarList, toolbarButton );
|
254 |
+
break;
|
255 |
case 'content':
|
256 |
// CRED main editors
|
257 |
if (
|
vendor/toolset/toolset-common/res/js/toolset-media-manager.js
ADDED
@@ -0,0 +1,152 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* API and helper functions for media buttons over custom editors and inputs.
|
3 |
+
*
|
4 |
+
* @since m2m
|
5 |
+
* @package Toolset
|
6 |
+
* @todo add support for input media buttons, with audio/video/image/file restrictions
|
7 |
+
*/
|
8 |
+
|
9 |
+
var Toolset = Toolset || {};
|
10 |
+
|
11 |
+
var Toolset = Toolset || {};
|
12 |
+
if ( typeof Toolset.mediaManager === "undefined" ) {
|
13 |
+
Toolset.mediaManager = {};
|
14 |
+
}
|
15 |
+
|
16 |
+
Toolset.mediaManager.Class = function( $ ) {
|
17 |
+
|
18 |
+
var self = this;
|
19 |
+
|
20 |
+
self.wpMediaEditor = wp.media.editor;
|
21 |
+
|
22 |
+
self.editorSelector = '.js-toolset-editor-media-manager';
|
23 |
+
self.inputSelector = '.js-toolset-input-media-manager';
|
24 |
+
|
25 |
+
self.instances = {
|
26 |
+
editor: {},
|
27 |
+
input: {}
|
28 |
+
};
|
29 |
+
|
30 |
+
self.getPostId = function( $mediaButton ) {
|
31 |
+
var referredId = $mediaButton.data( 'postid' ),
|
32 |
+
postId = 0;
|
33 |
+
|
34 |
+
if ( referredId ) {
|
35 |
+
postId = parseInt( referredId ) || 0;
|
36 |
+
}
|
37 |
+
|
38 |
+
return postId;
|
39 |
+
};
|
40 |
+
|
41 |
+
self.setTarget = function( $mediaButton ) {
|
42 |
+
var targetId = $mediaButton.data( 'target' );
|
43 |
+
|
44 |
+
if ( targetId ) {
|
45 |
+
window.wpcfActiveEditor = targetId;
|
46 |
+
}
|
47 |
+
};
|
48 |
+
|
49 |
+
self.getInstanceKey = function( postId ) {
|
50 |
+
return 'toolsetMediaFor' + postId;
|
51 |
+
};
|
52 |
+
|
53 |
+
self.setEditorMediaManagerEvents = function( instanceKey ) {
|
54 |
+
// Watch changes in wp-includes/js/media-editor.js
|
55 |
+
var workflow = self.instances.editor[ instanceKey ];
|
56 |
+
|
57 |
+
self.instances.editor[ instanceKey ].on( 'insert', function() {
|
58 |
+
|
59 |
+
var state = self.instances.editor[ instanceKey ].state(),
|
60 |
+
selection = state.get( 'selection' );
|
61 |
+
|
62 |
+
if ( ! selection ) {
|
63 |
+
return;
|
64 |
+
}
|
65 |
+
|
66 |
+
$.when.apply( $, selection.map( function( attachment ) {
|
67 |
+
var display = state.display( attachment ).toJSON();
|
68 |
+
return self.wpMediaEditor.send.attachment( display, attachment.toJSON() );
|
69 |
+
}, self.wpMediaEditor ) ).done( function() {
|
70 |
+
icl_editor.insert( _.toArray( arguments ).join('\n\n') );
|
71 |
+
});
|
72 |
+
});
|
73 |
+
|
74 |
+
workflow.state( 'gallery-edit' ).on( 'update', function( selection ) {
|
75 |
+
icl_editor.insert( wp.media.gallery.shortcode( selection ).string() );
|
76 |
+
}, self.wpMediaEditor );
|
77 |
+
|
78 |
+
workflow.state( 'playlist-edit' ).on( 'update', function( selection ) {
|
79 |
+
icl_editor.insert( wp.media.playlist.shortcode( selection ).string() );
|
80 |
+
}, self.wpMediaEditor );
|
81 |
+
|
82 |
+
workflow.state( 'video-playlist-edit' ).on( 'update', function( selection ) {
|
83 |
+
icl_editor.insert( wp.media.playlist.shortcode( selection ).string() );
|
84 |
+
}, self.wpMediaEditor );
|
85 |
+
|
86 |
+
workflow.state( 'embed' ).on( 'select', function() {
|
87 |
+
var state = workflow.state(),
|
88 |
+
type = state.get( 'type' ),
|
89 |
+
embed = state.props.toJSON();
|
90 |
+
|
91 |
+
embed.url = embed.url || '';
|
92 |
+
|
93 |
+
if ( 'link' === type ) {
|
94 |
+
_.defaults( embed, {
|
95 |
+
linkText: embed.url,
|
96 |
+
linkUrl: embed.url
|
97 |
+
});
|
98 |
+
|
99 |
+
self.wpMediaEditor.send.link( embed ).done( function( resp ) {
|
100 |
+
icl_editor.insert( resp );
|
101 |
+
});
|
102 |
+
|
103 |
+
} else if ( 'image' === type ) {
|
104 |
+
_.defaults( embed, {
|
105 |
+
title: embed.url,
|
106 |
+
linkUrl: '',
|
107 |
+
align: 'none',
|
108 |
+
link: 'none'
|
109 |
+
});
|
110 |
+
|
111 |
+
if ( 'none' === embed.link ) {
|
112 |
+
embed.linkUrl = '';
|
113 |
+
} else if ( 'file' === embed.link ) {
|
114 |
+
embed.linkUrl = embed.url;
|
115 |
+
}
|
116 |
+
|
117 |
+
icl_editor.insert( wp.media.string.image( embed ) );
|
118 |
+
}
|
119 |
+
}, self.wpMediaEditor );
|
120 |
+
};
|
121 |
+
|
122 |
+
$( document ).on( 'click', self.editorSelector, function( e ) {
|
123 |
+
e.preventDefault();
|
124 |
+
var $mediaButton = $( this ),
|
125 |
+
postId = self.getPostId( $mediaButton ),
|
126 |
+
instanceKey = self.getInstanceKey( postId );
|
127 |
+
|
128 |
+
self.setTarget( $mediaButton );
|
129 |
+
|
130 |
+
if ( _.has( self.instances.editor, instanceKey ) ) {
|
131 |
+
self.instances.editor[ instanceKey ].open();
|
132 |
+
return;
|
133 |
+
}
|
134 |
+
|
135 |
+
wp.media.model.settings.post.id = postId;
|
136 |
+
|
137 |
+
self.instances.editor[ instanceKey ] = wp.media({
|
138 |
+
className: 'media-frame js-toolset-media-frame',
|
139 |
+
frame: 'post'
|
140 |
+
});
|
141 |
+
|
142 |
+
self.setEditorMediaManagerEvents( instanceKey );
|
143 |
+
|
144 |
+
self.instances.editor[ instanceKey ].open();
|
145 |
+
|
146 |
+
});
|
147 |
+
|
148 |
+
};
|
149 |
+
|
150 |
+
jQuery( document ).ready( function( $ ) {
|
151 |
+
Toolset.mediaManager.main = new Toolset.mediaManager.Class( $ );
|
152 |
+
});
|
vendor/toolset/toolset-common/res/js/toolset-shortcode.js
CHANGED
@@ -151,7 +151,14 @@ Toolset.shortcodeManager = function( $ ) {
|
|
151 |
*
|
152 |
* @since 2.5.4
|
153 |
*/
|
154 |
-
Toolset.hooks.addFilter( 'toolset-filter-get-crafted-shortcode', self.getCraftedShortcode );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
155 |
|
156 |
/**
|
157 |
* Return the current crafted shortcode with the current dialog GUI attrbutes.
|
@@ -212,6 +219,13 @@ Toolset.shortcodeManager = function( $ ) {
|
|
212 |
*/
|
213 |
Toolset.hooks.addAction( 'toolset-action-shortcode-dialog-loaded', self.initSelect2 );
|
214 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
215 |
return self;
|
216 |
|
217 |
};
|
@@ -230,6 +244,7 @@ Toolset.shortcodeManager = function( $ ) {
|
|
230 |
self.templates.attributeGroupWrapper = wp.template( 'toolset-shortcode-attribute-group-wrapper' );
|
231 |
self.templates.attributes = {
|
232 |
content: wp.template( 'toolset-shortcode-content' ),
|
|
|
233 |
text: wp.template( 'toolset-shortcode-attribute-text' ),
|
234 |
radio: wp.template( 'toolset-shortcode-attribute-radio' ),
|
235 |
select: wp.template( 'toolset-shortcode-attribute-select' ),
|
@@ -368,12 +383,12 @@ Toolset.shortcodeManager = function( $ ) {
|
|
368 |
});
|
369 |
|
370 |
/**
|
371 |
-
* Init select2
|
372 |
*
|
373 |
* @since 2.5.4
|
374 |
*/
|
375 |
-
self.
|
376 |
-
$( '.js-toolset-shortcode-gui-dialog-container .js-toolset-shortcode-gui-field-select2' ).each( function() {
|
377 |
var selector = $( this ),
|
378 |
selectorParent = selector.closest( '.js-toolset-shortcode-gui-dialog-container' );
|
379 |
|
@@ -392,12 +407,16 @@ Toolset.shortcodeManager = function( $ ) {
|
|
392 |
.$dropdown
|
393 |
.addClass( 'toolset_select2-dropdown-in-dialog' );
|
394 |
});
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
|
|
|
|
|
|
|
|
401 |
.addClass( 'js-toolset-shortcode-gui-field-select2-inited' )
|
402 |
.css( { width: '100%' } )
|
403 |
.toolset_select2(
|
@@ -406,18 +425,22 @@ Toolset.shortcodeManager = function( $ ) {
|
|
406 |
dropdownAutoWidth: true,
|
407 |
dropdownParent: selectorParent,
|
408 |
placeholder: selector.data( 'placeholder' ),
|
|
|
409 |
ajax: {
|
410 |
-
url: toolset_shortcode_i18n.ajaxurl
|
411 |
dataType: 'json',
|
412 |
delay: 250,
|
413 |
type: 'post',
|
414 |
data: function( params ) {
|
415 |
return {
|
416 |
-
|
417 |
-
|
|
|
|
|
418 |
};
|
419 |
},
|
420 |
-
processResults: function(
|
|
|
421 |
params.page = params.page || 1;
|
422 |
if ( response.success ) {
|
423 |
return {
|
@@ -435,9 +458,98 @@ Toolset.shortcodeManager = function( $ ) {
|
|
435 |
.data( 'toolset_select2' )
|
436 |
.$dropdown
|
437 |
.addClass( 'toolset_select2-dropdown-in-dialog' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
438 |
});
|
439 |
};
|
440 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
441 |
/**
|
442 |
* Clean validation errors on input change.
|
443 |
*
|
@@ -445,6 +557,13 @@ Toolset.shortcodeManager = function( $ ) {
|
|
445 |
*/
|
446 |
$( document ).on( 'change keyup input cut paste', '.js-toolset-shortcode-gui-dialog-container input, .js-toolset-shortcode-gui-dialog-container select', function() {
|
447 |
$( this ).removeClass( 'toolset-shortcode-gui-invalid-attr js-toolset-shortcode-gui-invalid-attr' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
448 |
});
|
449 |
|
450 |
/**
|
@@ -793,37 +912,44 @@ Toolset.shortcodeManager = function( $ ) {
|
|
793 |
* Get the shortcode crafted with the current dialog shortcode attributes.
|
794 |
*
|
795 |
* @param defaultValue string Initial dummy parameter si this can be used as a filter callback.
|
|
|
796 |
*
|
797 |
* @return string
|
798 |
*
|
799 |
* @since m2m
|
800 |
*/
|
801 |
-
self.getCraftedShortcode = function( defaultValue ) {
|
802 |
-
|
|
|
|
|
|
|
|
|
803 |
}
|
804 |
|
805 |
/**
|
806 |
* Craft a shortcode given the attributes in the currently open dialog.
|
807 |
*
|
|
|
|
|
808 |
* @return string
|
809 |
*
|
810 |
* @since 2.5.4
|
811 |
* @since m2m Add support for postSelector, userSelector, typesViewsTermSelector, typesUserSelector and typesViewsUserSelector attribute types.
|
812 |
*/
|
813 |
-
self.craftShortcode = function() {
|
814 |
-
var shortcodeName = $( '.js-toolset-shortcode-gui-shortcode-handle' ).val(),
|
815 |
shortcodeAttributeString = '',
|
816 |
shortcodeAttributeValues = {},
|
817 |
shortcodeRawAttributeValues = {},
|
818 |
shortcodeContent = '',
|
819 |
shortcodeToInsert = '',
|
820 |
-
shortcodeIsValid = self.validateShortcodeAttributes( $
|
821 |
|
822 |
if ( ! shortcodeIsValid ) {
|
823 |
return;
|
824 |
}
|
825 |
|
826 |
-
$( '.js-toolset-shortcode-gui-attribute-wrapper',
|
827 |
var attributeWrapper = $( this ),
|
828 |
shortcodeAttributeKey = attributeWrapper.data( 'attribute' ),
|
829 |
shortcodeAttributeValue = '',
|
@@ -844,6 +970,9 @@ Toolset.shortcodeManager = function( $ ) {
|
|
844 |
case 'related':
|
845 |
shortcodeAttributeValue = $( '[name="related_object"]:checked', attributeWrapper ).val();
|
846 |
break;
|
|
|
|
|
|
|
847 |
case 'object_id':
|
848 |
shortcodeAttributeValue = $( '.js-toolset-shortcode-gui-item-selector_object_id', attributeWrapper ).val();
|
849 |
case 'parent': // The value is correct out of the box
|
@@ -854,7 +983,7 @@ Toolset.shortcodeManager = function( $ ) {
|
|
854 |
case 'select':
|
855 |
case 'select2':
|
856 |
case 'ajaxSelect2':
|
857 |
-
shortcodeAttributeValue = $('
|
858 |
break;
|
859 |
case 'radio':
|
860 |
case 'radiohtml':
|
@@ -863,6 +992,9 @@ Toolset.shortcodeManager = function( $ ) {
|
|
863 |
case 'checkbox':
|
864 |
shortcodeAttributeValue = $('input:checked', attributeWrapper ).val();
|
865 |
break;
|
|
|
|
|
|
|
866 |
default:
|
867 |
shortcodeAttributeValue = $('input', attributeWrapper ).val();
|
868 |
}
|
@@ -929,8 +1061,8 @@ Toolset.shortcodeManager = function( $ ) {
|
|
929 |
shortcodeToInsert = '[' + shortcodeName + shortcodeAttributeString + ']';
|
930 |
|
931 |
// Shortcodes with content: add it plus the closing shortode tag
|
932 |
-
if ( $( '.js-toolset-shortcode-gui-content' ).length > 0 ) {
|
933 |
-
shortcodeContent = $( '.js-toolset-shortcode-gui-content' ).val();
|
934 |
shortcodeToInsert += shortcodeContent;
|
935 |
shortcodeToInsert += '[/' + shortcodeName + ']';
|
936 |
}
|
151 |
*
|
152 |
* @since 2.5.4
|
153 |
*/
|
154 |
+
Toolset.hooks.addFilter( 'toolset-filter-get-crafted-shortcode', self.getCraftedShortcode, 10, 2 );
|
155 |
+
|
156 |
+
/**
|
157 |
+
* Filter the generated Types shortcode to support shortcodes with different format.
|
158 |
+
*
|
159 |
+
* @since 2.5.4
|
160 |
+
*/
|
161 |
+
Toolset.hooks.addFilter( 'toolset-filter-get-crafted-shortcode', self.secureShortcodeFromSanitizationIfNeeded, 11 );
|
162 |
|
163 |
/**
|
164 |
* Return the current crafted shortcode with the current dialog GUI attrbutes.
|
219 |
*/
|
220 |
Toolset.hooks.addAction( 'toolset-action-shortcode-dialog-loaded', self.initSelect2 );
|
221 |
|
222 |
+
/**
|
223 |
+
* Init a wizard dialog, set the options width, and set the right value as selected.
|
224 |
+
*
|
225 |
+
* @since 2.5.4
|
226 |
+
*/
|
227 |
+
Toolset.hooks.addAction( 'toolset-action-set-shortcode-wizard-gui', self.setShortcodeWizardGui );
|
228 |
+
|
229 |
return self;
|
230 |
|
231 |
};
|
244 |
self.templates.attributeGroupWrapper = wp.template( 'toolset-shortcode-attribute-group-wrapper' );
|
245 |
self.templates.attributes = {
|
246 |
content: wp.template( 'toolset-shortcode-content' ),
|
247 |
+
information: wp.template( 'toolset-shortcode-attribute-information' ),
|
248 |
text: wp.template( 'toolset-shortcode-attribute-text' ),
|
249 |
radio: wp.template( 'toolset-shortcode-attribute-radio' ),
|
250 |
select: wp.template( 'toolset-shortcode-attribute-select' ),
|
383 |
});
|
384 |
|
385 |
/**
|
386 |
+
* Init select2 attributes controls.
|
387 |
*
|
388 |
* @since 2.5.4
|
389 |
*/
|
390 |
+
self.initSelect2Attributes = function() {
|
391 |
+
$( '.js-toolset-shortcode-gui-dialog-container .js-toolset-shortcode-gui-field-select2:not(.js-toolset-shortcode-gui-field-select2-inited)' ).each( function() {
|
392 |
var selector = $( this ),
|
393 |
selectorParent = selector.closest( '.js-toolset-shortcode-gui-dialog-container' );
|
394 |
|
407 |
.$dropdown
|
408 |
.addClass( 'toolset_select2-dropdown-in-dialog' );
|
409 |
});
|
410 |
+
};
|
411 |
+
|
412 |
+
/**
|
413 |
+
* Init the ajaxSelect2 attributes action.
|
414 |
+
*
|
415 |
+
* @since 2.5.4
|
416 |
+
*/
|
417 |
+
self.initSelect2AjaxAction = function( selector ) {
|
418 |
+
var selectorParent = selector.closest( '.js-toolset-shortcode-gui-dialog-container' );
|
419 |
+
selector
|
420 |
.addClass( 'js-toolset-shortcode-gui-field-select2-inited' )
|
421 |
.css( { width: '100%' } )
|
422 |
.toolset_select2(
|
425 |
dropdownAutoWidth: true,
|
426 |
dropdownParent: selectorParent,
|
427 |
placeholder: selector.data( 'placeholder' ),
|
428 |
+
minimumInputLength: 2,
|
429 |
ajax: {
|
430 |
+
url: toolset_shortcode_i18n.ajaxurl,
|
431 |
dataType: 'json',
|
432 |
delay: 250,
|
433 |
type: 'post',
|
434 |
data: function( params ) {
|
435 |
return {
|
436 |
+
action: selector.data( 'action' ),
|
437 |
+
s: params.term,
|
438 |
+
page: params.page,
|
439 |
+
wpnonce: selector.data( 'nonce' )
|
440 |
};
|
441 |
},
|
442 |
+
processResults: function( originalResponse, params ) {
|
443 |
+
var response = WPV_Toolset.Utils.Ajax.parseResponse( originalResponse );
|
444 |
params.page = params.page || 1;
|
445 |
if ( response.success ) {
|
446 |
return {
|
458 |
.data( 'toolset_select2' )
|
459 |
.$dropdown
|
460 |
.addClass( 'toolset_select2-dropdown-in-dialog' );
|
461 |
+
};
|
462 |
+
|
463 |
+
/**
|
464 |
+
* Init ajaxSelect2 attributes controls.
|
465 |
+
* Get the prefill label for any existing value.
|
466 |
+
*
|
467 |
+
* @since 2.5.4
|
468 |
+
*/
|
469 |
+
self.initSelect2AjaxAttributes = function() {
|
470 |
+
$( '.js-toolset-shortcode-gui-dialog-container .js-toolset-shortcode-gui-field-ajax-select2:not(.js-toolset-shortcode-gui-field-select2-inited)' ).each( function() {
|
471 |
+
var selector = $( this );
|
472 |
+
|
473 |
+
if (
|
474 |
+
selector.val()
|
475 |
+
&& selector.data( 'prefill' )
|
476 |
+
) {
|
477 |
+
var prefillData = {
|
478 |
+
action: selector.data( 'prefill' ),
|
479 |
+
wpnonce: selector.data( 'prefill-nonce' ),
|
480 |
+
s: selector.val()
|
481 |
+
};
|
482 |
+
$.ajax({
|
483 |
+
url: toolset_shortcode_i18n.ajaxurl,
|
484 |
+
data: prefillData,
|
485 |
+
type: "post",
|
486 |
+
success: function( originalResponse ) {
|
487 |
+
var response = WPV_Toolset.Utils.Ajax.parseResponse( originalResponse );
|
488 |
+
if ( response.success ) {
|
489 |
+
selector
|
490 |
+
.find( 'option:selected' )
|
491 |
+
.html( response.data.label );
|
492 |
+
} else {
|
493 |
+
selector
|
494 |
+
.find( 'option:selected' )
|
495 |
+
.remove();
|
496 |
+
}
|
497 |
+
self.initSelect2AjaxAction( selector );
|
498 |
+
},
|
499 |
+
error: function ( ajaxContext ) {
|
500 |
+
selector
|
501 |
+
.find( 'option:selected' )
|
502 |
+
.remove();
|
503 |
+
self.initSelect2AjaxAction( selector );
|
504 |
+
}
|
505 |
+
});
|
506 |
+
} else {
|
507 |
+
self.initSelect2AjaxAction( selector );
|
508 |
+
}
|
509 |
+
|
510 |
});
|
511 |
};
|
512 |
|
513 |
+
/**
|
514 |
+
* Init select2 and ajaxSelect2 attributes controls.
|
515 |
+
*
|
516 |
+
* @since 2.5.4
|
517 |
+
*/
|
518 |
+
self.initSelect2 = function() {
|
519 |
+
self.initSelect2Attributes();
|
520 |
+
self.initSelect2AjaxAttributes();
|
521 |
+
};
|
522 |
+
|
523 |
+
/**
|
524 |
+
* Initialize the wizard GUI for a shortcode.
|
525 |
+
*
|
526 |
+
* @param string The value to set as selected
|
527 |
+
*
|
528 |
+
* @since m2m
|
529 |
+
*/
|
530 |
+
self.setShortcodeWizardGui = function( value ) {
|
531 |
+
var $optionsContainer = $( '.js-toolset-shortcode-gui-wizard-options-container', '.js-toolset-shortcode-gui-wizard-container' ),
|
532 |
+
$options = $( '.js-toolset-shortcode-gui-wizard-option', $optionsContainer ),
|
533 |
+
optionsLength = $options.length;
|
534 |
+
|
535 |
+
$( '.toolset-shortcode-gui-wizard-option-selected', $optionsContainer ).removeClass( 'toolset-shortcode-gui-wizard-option-selected' );
|
536 |
+
$optionsContainer.find( 'input[value=' + value + ']' )
|
537 |
+
.prop( 'checked', true )
|
538 |
+
.trigger( 'change' )
|
539 |
+
.closest( '.js-toolset-shortcode-gui-wizard-option' )
|
540 |
+
.addClass( 'toolset-shortcode-gui-wizard-option-selected' );
|
541 |
+
};
|
542 |
+
|
543 |
+
$( document ).on( 'change', '.js-toolset-shortcode-gui-wizard-option input[type=radio]', function() {
|
544 |
+
var $optionsContainer = $( '.js-toolset-shortcode-gui-wizard-options-container', '.js-toolset-shortcode-gui-wizard-container' );
|
545 |
+
|
546 |
+
$( '.toolset-shortcode-gui-wizard-option-selected', $optionsContainer ).removeClass( 'toolset-shortcode-gui-wizard-option-selected' );
|
547 |
+
|
548 |
+
$( 'input[type=radio].toolset-shortcode-gui-wizard-option-hidden:checked', $optionsContainer )
|
549 |
+
.closest( '.js-toolset-shortcode-gui-wizard-option' )
|
550 |
+
.addClass( 'toolset-shortcode-gui-wizard-option-selected' );
|
551 |
+
});
|
552 |
+
|
553 |
/**
|
554 |
* Clean validation errors on input change.
|
555 |
*
|
557 |
*/
|
558 |
$( document ).on( 'change keyup input cut paste', '.js-toolset-shortcode-gui-dialog-container input, .js-toolset-shortcode-gui-dialog-container select', function() {
|
559 |
$( this ).removeClass( 'toolset-shortcode-gui-invalid-attr js-toolset-shortcode-gui-invalid-attr' );
|
560 |
+
if ( $( this ).hasClass( 'toolset_select2-hidden-accessible' ) ) {
|
561 |
+
$( this )
|
562 |
+
.toolset_select2()
|
563 |
+
.data( 'toolset_select2' )
|
564 |
+
.$selection
|
565 |
+
.removeClass( 'toolset-shortcode-gui-invalid-attr js-toolset-shortcode-gui-invalid-attr' );
|
566 |
+
}
|
567 |
});
|
568 |
|
569 |
/**
|
912 |
* Get the shortcode crafted with the current dialog shortcode attributes.
|
913 |
*
|
914 |
* @param defaultValue string Initial dummy parameter si this can be used as a filter callback.
|
915 |
+
* @param $dialog object The jQuery object that holds the dialog to craft the shortcode for.
|
916 |
*
|
917 |
* @return string
|
918 |
*
|
919 |
* @since m2m
|
920 |
*/
|
921 |
+
self.getCraftedShortcode = function( defaultValue, $dialog ) {
|
922 |
+
if ( $dialog == null ) {
|
923 |
+
// Backwards compatibility: before m2m we did not force a dialog to craft the shortcode from
|
924 |
+
$dialog = $( '.js-toolset-shortcode-gui-dialog-container' );
|
925 |
+
}
|
926 |
+
return self.craftShortcode( $dialog );
|
927 |
}
|
928 |
|
929 |
/**
|
930 |
* Craft a shortcode given the attributes in the currently open dialog.
|
931 |
*
|
932 |
+
* @param $dialog object The jQuery object that holds the dialog to craft the shortcode for.
|
933 |
+
*
|
934 |
* @return string
|
935 |
*
|
936 |
* @since 2.5.4
|
937 |
* @since m2m Add support for postSelector, userSelector, typesViewsTermSelector, typesUserSelector and typesViewsUserSelector attribute types.
|
938 |
*/
|
939 |
+
self.craftShortcode = function( $dialog ) {
|
940 |
+
var shortcodeName = $( '.js-toolset-shortcode-gui-shortcode-handle', $dialog ).val(),
|
941 |
shortcodeAttributeString = '',
|
942 |
shortcodeAttributeValues = {},
|
943 |
shortcodeRawAttributeValues = {},
|
944 |
shortcodeContent = '',
|
945 |
shortcodeToInsert = '',
|
946 |
+
shortcodeIsValid = self.validateShortcodeAttributes( $dialog );
|
947 |
|
948 |
if ( ! shortcodeIsValid ) {
|
949 |
return;
|
950 |
}
|
951 |
|
952 |
+
$( '.js-toolset-shortcode-gui-attribute-wrapper', $dialog ).each( function() {
|
953 |
var attributeWrapper = $( this ),
|
954 |
shortcodeAttributeKey = attributeWrapper.data( 'attribute' ),
|
955 |
shortcodeAttributeValue = '',
|
970 |
case 'related':
|
971 |
shortcodeAttributeValue = $( '[name="related_object"]:checked', attributeWrapper ).val();
|
972 |
break;
|
973 |
+
case 'referenced':
|
974 |
+
shortcodeAttributeValue = $( '[name="referenced_object"]:checked', attributeWrapper ).val();
|
975 |
+
break;
|
976 |
case 'object_id':
|
977 |
shortcodeAttributeValue = $( '.js-toolset-shortcode-gui-item-selector_object_id', attributeWrapper ).val();
|
978 |
case 'parent': // The value is correct out of the box
|
983 |
case 'select':
|
984 |
case 'select2':
|
985 |
case 'ajaxSelect2':
|
986 |
+
shortcodeAttributeValue = $('select', attributeWrapper ).val();
|
987 |
break;
|
988 |
case 'radio':
|
989 |
case 'radiohtml':
|
992 |
case 'checkbox':
|
993 |
shortcodeAttributeValue = $('input:checked', attributeWrapper ).val();
|
994 |
break;
|
995 |
+
case 'information':
|
996 |
+
shortcodeAttributeValue = false;
|
997 |
+
break;
|
998 |
default:
|
999 |
shortcodeAttributeValue = $('input', attributeWrapper ).val();
|
1000 |
}
|
1061 |
shortcodeToInsert = '[' + shortcodeName + shortcodeAttributeString + ']';
|
1062 |
|
1063 |
// Shortcodes with content: add it plus the closing shortode tag
|
1064 |
+
if ( $( '.js-toolset-shortcode-gui-content', $dialog ).length > 0 ) {
|
1065 |
+
shortcodeContent = $( '.js-toolset-shortcode-gui-content', $dialog ).val();
|
1066 |
shortcodeToInsert += shortcodeContent;
|
1067 |
shortcodeToInsert += '[/' + shortcodeName + ']';
|
1068 |
}
|
vendor/toolset/toolset-common/res/lib/parsley/parsley.css
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
input.parsley-success,
|
2 |
+
select.parsley-success,
|
3 |
+
textarea.parsley-success {
|
4 |
+
color: #468847;
|
5 |
+
background-color: #DFF0D8;
|
6 |
+
border: 1px solid #D6E9C6;
|
7 |
+
}
|
8 |
+
|
9 |
+
input.parsley-error,
|
10 |
+
select.parsley-error,
|
11 |
+
textarea.parsley-error {
|
12 |
+
color: #B94A48;
|
13 |
+
background-color: #F2DEDE;
|
14 |
+
border: 1px solid #EED3D7;
|
15 |
+
}
|
16 |
+
|
17 |
+
.parsley-errors-list {
|
18 |
+
margin: 2px 0 3px;
|
19 |
+
padding: 0;
|
20 |
+
list-style-type: none;
|
21 |
+
font-size: 0.9em;
|
22 |
+
line-height: 0.9em;
|
23 |
+
opacity: 0;
|
24 |
+
|
25 |
+
transition: all .3s ease-in;
|
26 |
+
-o-transition: all .3s ease-in;
|
27 |
+
-moz-transition: all .3s ease-in;
|
28 |
+
-webkit-transition: all .3s ease-in;
|
29 |
+
}
|
30 |
+
|
31 |
+
.parsley-errors-list.filled {
|
32 |
+
opacity: 1;
|
33 |
+
}
|
vendor/toolset/toolset-common/res/lib/parsley/parsley.js
ADDED
@@ -0,0 +1,2492 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*!
|
2 |
+
* Parsley.js
|
3 |
+
* Version 2.8.0 - built Wed, Sep 13th 2017, 11:04 pm
|
4 |
+
* http://parsleyjs.org
|
5 |
+
* Guillaume Potier - <guillaume@wisembly.com>
|
6 |
+
* Marc-Andre Lafortune - <petroselinum@marc-andre.ca>
|
7 |
+
* MIT Licensed
|
8 |
+
*/
|
9 |
+
|
10 |
+
// The source code below is generated by babel as
|
11 |
+
// Parsley is written in ECMAScript 6
|
12 |
+
//
|
13 |
+
var _slice = Array.prototype.slice;
|
14 |
+
|
15 |
+
var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();
|
16 |
+
|
17 |
+
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
|
18 |
+
|
19 |
+
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } }
|
20 |
+
|
21 |
+
(function (global, factory) {
|
22 |
+
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('jquery')) : typeof define === 'function' && define.amd ? define(['jquery'], factory) : global.parsley = factory(global.jQuery);
|
23 |
+
})(this, function ($) {
|
24 |
+
'use strict';
|
25 |
+
|
26 |
+
var globalID = 1;
|
27 |
+
var pastWarnings = {};
|
28 |
+
|
29 |
+
var Utils = {
|
30 |
+
// Parsley DOM-API
|
31 |
+
// returns object from dom attributes and values
|
32 |
+
attr: function attr(element, namespace, obj) {
|
33 |
+
var i;
|
34 |
+
var attribute;
|
35 |
+
var attributes;
|
36 |
+
var regex = new RegExp('^' + namespace, 'i');
|
37 |
+
|
38 |
+
if ('undefined' === typeof obj) obj = {};else {
|
39 |
+
// Clear all own properties. This won't affect prototype's values
|
40 |
+
for (i in obj) {
|
41 |
+
if (obj.hasOwnProperty(i)) delete obj[i];
|
42 |
+
}
|
43 |
+
}
|
44 |
+
|
45 |
+
if (!element) return obj;
|
46 |
+
|
47 |
+
attributes = element.attributes;
|
48 |
+
for (i = attributes.length; i--;) {
|
49 |
+
attribute = attributes[i];
|
50 |
+
|
51 |
+
if (attribute && attribute.specified && regex.test(attribute.name)) {
|
52 |
+
obj[this.camelize(attribute.name.slice(namespace.length))] = this.deserializeValue(attribute.value);
|
53 |
+
}
|
54 |
+
}
|
55 |
+
|
56 |
+
return obj;
|
57 |
+
},
|
58 |
+
|
59 |
+
checkAttr: function checkAttr(element, namespace, _checkAttr) {
|
60 |
+
return element.hasAttribute(namespace + _checkAttr);
|
61 |
+
},
|
62 |
+
|
63 |
+
setAttr: function setAttr(element, namespace, attr, value) {
|
64 |
+
element.setAttribute(this.dasherize(namespace + attr), String(value));
|
65 |
+
},
|
66 |
+
|
67 |
+
getType: function getType(element) {
|
68 |
+
return element.getAttribute('type') || 'text';
|
69 |
+
},
|
70 |
+
|
71 |
+
generateID: function generateID() {
|
72 |
+
return '' + globalID++;
|
73 |
+
},
|
74 |
+
|
75 |
+
/** Third party functions **/
|
76 |
+
deserializeValue: function deserializeValue(value) {
|
77 |
+
var num;
|
78 |
+
|
79 |
+
try {
|
80 |
+
return value ? value == "true" || (value == "false" ? false : value == "null" ? null : !isNaN(num = Number(value)) ? num : /^[\[\{]/.test(value) ? JSON.parse(value) : value) : value;
|
81 |
+
} catch (e) {
|
82 |
+
return value;
|
83 |
+
}
|
84 |
+
},
|
85 |
+
|
86 |
+
// Zepto camelize function
|
87 |
+
camelize: function camelize(str) {
|
88 |
+
return str.replace(/-+(.)?/g, function (match, chr) {
|
89 |
+
return chr ? chr.toUpperCase() : '';
|
90 |
+
});
|
91 |
+
},
|
92 |
+
|
93 |
+
// Zepto dasherize function
|
94 |
+
dasherize: function dasherize(str) {
|
95 |
+
return str.replace(/::/g, '/').replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2').replace(/([a-z\d])([A-Z])/g, '$1_$2').replace(/_/g, '-').toLowerCase();
|
96 |
+
},
|
97 |
+
|
98 |
+
warn: function warn() {
|
99 |
+
var _window$console;
|
100 |
+
|
101 |
+
if (window.console && 'function' === typeof window.console.warn) (_window$console = window.console).warn.apply(_window$console, arguments);
|
102 |
+
},
|
103 |
+
|
104 |
+
warnOnce: function warnOnce(msg) {
|
105 |
+
if (!pastWarnings[msg]) {
|
106 |
+
pastWarnings[msg] = true;
|
107 |
+
this.warn.apply(this, arguments);
|
108 |
+
}
|
109 |
+
},
|
110 |
+
|
111 |
+
_resetWarnings: function _resetWarnings() {
|
112 |
+
pastWarnings = {};
|
113 |
+
},
|
114 |
+
|
115 |
+
trimString: function trimString(string) {
|
116 |
+
return string.replace(/^\s+|\s+$/g, '');
|
117 |
+
},
|
118 |
+
|
119 |
+
parse: {
|
120 |
+
date: function date(string) {
|
121 |
+
var parsed = string.match(/^(\d{4,})-(\d\d)-(\d\d)$/);
|
122 |
+
if (!parsed) return null;
|
123 |
+
|
124 |
+
var _parsed$map = parsed.map(function (x) {
|
125 |
+
return parseInt(x, 10);
|
126 |
+
});
|
127 |
+
|
128 |
+
var _parsed$map2 = _slicedToArray(_parsed$map, 4);
|
129 |
+
|
130 |
+
var _ = _parsed$map2[0];
|
131 |
+
var year = _parsed$map2[1];
|
132 |
+
var month = _parsed$map2[2];
|
133 |
+
var day = _parsed$map2[3];
|
134 |
+
|
135 |
+
var date = new Date(year, month - 1, day);
|
136 |
+
if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) return null;
|
137 |
+
return date;
|
138 |
+
},
|
139 |
+
string: function string(_string) {
|
140 |
+
return _string;
|
141 |
+
},
|
142 |
+
integer: function integer(string) {
|
143 |
+
if (isNaN(string)) return null;
|
144 |
+
return parseInt(string, 10);
|
145 |
+
},
|
146 |
+
number: function number(string) {
|
147 |
+
if (isNaN(string)) throw null;
|
148 |
+
return parseFloat(string);
|
149 |
+
},
|
150 |
+
'boolean': function _boolean(string) {
|
151 |
+
return !/^\s*false\s*$/i.test(string);
|
152 |
+
},
|
153 |
+
object: function object(string) {
|
154 |
+
return Utils.deserializeValue(string);
|
155 |
+
},
|
156 |
+
regexp: function regexp(_regexp) {
|
157 |
+
var flags = '';
|
158 |
+
|
159 |
+
// Test if RegExp is literal, if not, nothing to be done, otherwise, we need to isolate flags and pattern
|
160 |
+
if (/^\/.*\/(?:[gimy]*)$/.test(_regexp)) {
|
161 |
+
// Replace the regexp literal string with the first match group: ([gimy]*)
|
162 |
+
// If no flag is present, this will be a blank string
|
163 |
+
flags = _regexp.replace(/.*\/([gimy]*)$/, '$1');
|
164 |
+
// Again, replace the regexp literal string with the first match group:
|
165 |
+
// everything excluding the opening and closing slashes and the flags
|
166 |
+
_regexp = _regexp.replace(new RegExp('^/(.*?)/' + flags + '$'), '$1');
|
167 |
+
} else {
|
168 |
+
// Anchor regexp:
|
169 |
+
_regexp = '^' + _regexp + '$';
|
170 |
+
}
|
171 |
+
return new RegExp(_regexp, flags);
|
172 |
+
}
|
173 |
+
},
|
174 |
+
|
175 |
+
parseRequirement: function parseRequirement(requirementType, string) {
|
176 |
+
var converter = this.parse[requirementType || 'string'];
|
177 |
+
if (!converter) throw 'Unknown requirement specification: "' + requirementType + '"';
|
178 |
+
var converted = converter(string);
|
179 |
+
if (converted === null) throw 'Requirement is not a ' + requirementType + ': "' + string + '"';
|
180 |
+
return converted;
|
181 |
+
},
|
182 |
+
|
183 |
+
namespaceEvents: function namespaceEvents(events, namespace) {
|
184 |
+
events = this.trimString(events || '').split(/\s+/);
|
185 |
+
if (!events[0]) return '';
|
186 |
+
return $.map(events, function (evt) {
|
187 |
+
return evt + '.' + namespace;
|
188 |
+
}).join(' ');
|
189 |
+
},
|
190 |
+
|
191 |
+
difference: function difference(array, remove) {
|
192 |
+
// This is O(N^2), should be optimized
|
193 |
+
var result = [];
|
194 |
+
$.each(array, function (_, elem) {
|
195 |
+
if (remove.indexOf(elem) == -1) result.push(elem);
|
196 |
+
});
|
197 |
+
return result;
|
198 |
+
},
|
199 |
+
|
200 |
+
// Alter-ego to native Promise.all, but for jQuery
|
201 |
+
all: function all(promises) {
|
202 |
+
// jQuery treats $.when() and $.when(singlePromise) differently; let's avoid that and add spurious elements
|
203 |
+
return $.when.apply($, _toConsumableArray(promises).concat([42, 42]));
|
204 |
+
},
|
205 |
+
|
206 |
+
// Object.create polyfill, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create#Polyfill
|
207 |
+
objectCreate: Object.create || (function () {
|
208 |
+
var Object = function Object() {};
|
209 |
+
return function (prototype) {
|
210 |
+
if (arguments.length > 1) {
|
211 |
+
throw Error('Second argument not supported');
|
212 |
+
}
|
213 |
+
if (typeof prototype != 'object') {
|
214 |
+
throw TypeError('Argument must be an object');
|
215 |
+
}
|
216 |
+
Object.prototype = prototype;
|
217 |
+
var result = new Object();
|
218 |
+
Object.prototype = null;
|
219 |
+
return result;
|
220 |
+
};
|
221 |
+
})(),
|
222 |
+
|
223 |
+
_SubmitSelector: 'input[type="submit"], button:submit'
|
224 |
+
};
|
225 |
+
|
226 |
+
// All these options could be overriden and specified directly in DOM using
|
227 |
+
// `data-parsley-` default DOM-API
|
228 |
+
// eg: `inputs` can be set in DOM using `data-parsley-inputs="input, textarea"`
|
229 |
+
// eg: `data-parsley-stop-on-first-failing-constraint="false"`
|
230 |
+
|
231 |
+
var Defaults = {
|
232 |
+
// ### General
|
233 |
+
|
234 |
+
// Default data-namespace for DOM API
|
235 |
+
namespace: 'data-parsley-',
|
236 |
+
|
237 |
+
// Supported inputs by default
|
238 |
+
inputs: 'input, textarea, select',
|
239 |
+
|
240 |
+
// Excluded inputs by default
|
241 |
+
excluded: 'input[type=button], input[type=submit], input[type=reset], input[type=hidden]',
|
242 |
+
|
243 |
+
// Stop validating field on highest priority failing constraint
|
244 |
+
priorityEnabled: true,
|
245 |
+
|
246 |
+
// ### Field only
|
247 |
+
|
248 |
+
// identifier used to group together inputs (e.g. radio buttons...)
|
249 |
+
multiple: null,
|
250 |
+
|
251 |
+
// identifier (or array of identifiers) used to validate only a select group of inputs
|
252 |
+
group: null,
|
253 |
+
|
254 |
+
// ### UI
|
255 |
+
// Enable\Disable error messages
|
256 |
+
uiEnabled: true,
|
257 |
+
|
258 |
+
// Key events threshold before validation
|
259 |
+
validationThreshold: 3,
|
260 |
+
|
261 |
+
// Focused field on form validation error. 'first'|'last'|'none'
|
262 |
+
focus: 'first',
|
263 |
+
|
264 |
+
// event(s) that will trigger validation before first failure. eg: `input`...
|
265 |
+
trigger: false,
|
266 |
+
|
267 |
+
// event(s) that will trigger validation after first failure.
|
268 |
+
triggerAfterFailure: 'input',
|
269 |
+
|
270 |
+
// Class that would be added on every failing validation Parsley field
|
271 |
+
errorClass: 'parsley-error',
|
272 |
+
|
273 |
+
// Same for success validation
|
274 |
+
successClass: 'parsley-success',
|
275 |
+
|
276 |
+
// Return the `$element` that will receive these above success or error classes
|
277 |
+
// Could also be (and given directly from DOM) a valid selector like `'#div'`
|
278 |
+
classHandler: function classHandler(Field) {},
|
279 |
+
|
280 |
+
// Return the `$element` where errors will be appended
|
281 |
+
// Could also be (and given directly from DOM) a valid selector like `'#div'`
|
282 |
+
errorsContainer: function errorsContainer(Field) {},
|
283 |
+
|
284 |
+
// ul elem that would receive errors' list
|
285 |
+
errorsWrapper: '<ul class="parsley-errors-list"></ul>',
|
286 |
+
|
287 |
+
// li elem that would receive error message
|
288 |
+
errorTemplate: '<li></li>'
|
289 |
+
};
|
290 |
+
|
291 |
+
var Base = function Base() {
|
292 |
+
this.__id__ = Utils.generateID();
|
293 |
+
};
|
294 |
+
|
295 |
+
Base.prototype = {
|
296 |
+
asyncSupport: true, // Deprecated
|
297 |
+
|
298 |
+
_pipeAccordingToValidationResult: function _pipeAccordingToValidationResult() {
|
299 |
+
var _this = this;
|
300 |
+
|
301 |
+
var pipe = function pipe() {
|
302 |
+
var r = $.Deferred();
|
303 |
+
if (true !== _this.validationResult) r.reject();
|
304 |
+
return r.resolve().promise();
|
305 |
+
};
|
306 |
+
return [pipe, pipe];
|
307 |
+
},
|
308 |
+
|
309 |
+
actualizeOptions: function actualizeOptions() {
|
310 |
+
Utils.attr(this.element, this.options.namespace, this.domOptions);
|
311 |
+
if (this.parent && this.parent.actualizeOptions) this.parent.actualizeOptions();
|
312 |
+
return this;
|
313 |
+
},
|
314 |
+
|
315 |
+
_resetOptions: function _resetOptions(initOptions) {
|
316 |
+
this.domOptions = Utils.objectCreate(this.parent.options);
|
317 |
+
this.options = Utils.objectCreate(this.domOptions);
|
318 |
+
// Shallow copy of ownProperties of initOptions:
|
319 |
+
for (var i in initOptions) {
|
320 |
+
if (initOptions.hasOwnProperty(i)) this.options[i] = initOptions[i];
|
321 |
+
}
|
322 |
+
this.actualizeOptions();
|
323 |
+
},
|
324 |
+
|
325 |
+
_listeners: null,
|
326 |
+
|
327 |
+
// Register a callback for the given event name
|
328 |
+
// Callback is called with context as the first argument and the `this`
|
329 |
+
// The context is the current parsley instance, or window.Parsley if global
|
330 |
+
// A return value of `false` will interrupt the calls
|
331 |
+
on: function on(name, fn) {
|
332 |
+
this._listeners = this._listeners || {};
|
333 |
+
var queue = this._listeners[name] = this._listeners[name] || [];
|
334 |
+
queue.push(fn);
|
335 |
+
|
336 |
+
return this;
|
337 |
+
},
|
338 |
+
|
339 |
+
// Deprecated. Use `on` instead
|
340 |
+
subscribe: function subscribe(name, fn) {
|
341 |
+
$.listenTo(this, name.toLowerCase(), fn);
|
342 |
+
},
|
343 |
+
|
344 |
+
// Unregister a callback (or all if none is given) for the given event name
|
345 |
+
off: function off(name, fn) {
|
346 |
+
var queue = this._listeners && this._listeners[name];
|
347 |
+
if (queue) {
|
348 |
+
if (!fn) {
|
349 |
+
delete this._listeners[name];
|
350 |
+
} else {
|
351 |
+
for (var i = queue.length; i--;) if (queue[i] === fn) queue.splice(i, 1);
|
352 |
+
}
|
353 |
+
}
|
354 |
+
return this;
|
355 |
+
},
|
356 |
+
|
357 |
+
// Deprecated. Use `off`
|
358 |
+
unsubscribe: function unsubscribe(name, fn) {
|
359 |
+
$.unsubscribeTo(this, name.toLowerCase());
|
360 |
+
},
|
361 |
+
|
362 |
+
// Trigger an event of the given name
|
363 |
+
// A return value of `false` interrupts the callback chain
|
364 |
+
// Returns false if execution was interrupted
|
365 |
+
trigger: function trigger(name, target, extraArg) {
|
366 |
+
target = target || this;
|
367 |
+
var queue = this._listeners && this._listeners[name];
|
368 |
+
var result;
|
369 |
+
var parentResult;
|
370 |
+
if (queue) {
|
371 |
+
for (var i = queue.length; i--;) {
|
372 |
+
result = queue[i].call(target, target, extraArg);
|
373 |
+
if (result === false) return result;
|
374 |
+
}
|
375 |
+
}
|
376 |
+
if (this.parent) {
|
377 |
+
return this.parent.trigger(name, target, extraArg);
|
378 |
+
}
|
379 |
+
return true;
|
380 |
+
},
|
381 |
+
|
382 |
+
asyncIsValid: function asyncIsValid(group, force) {
|
383 |
+
Utils.warnOnce("asyncIsValid is deprecated; please use whenValid instead");
|
384 |
+
return this.whenValid({ group: group, force: force });
|
385 |
+
},
|
386 |
+
|
387 |
+
_findRelated: function _findRelated() {
|
388 |
+
return this.options.multiple ? $(this.parent.element.querySelectorAll('[' + this.options.namespace + 'multiple="' + this.options.multiple + '"]')) : this.$element;
|
389 |
+
}
|
390 |
+
};
|
391 |
+
|
392 |
+
var convertArrayRequirement = function convertArrayRequirement(string, length) {
|
393 |
+
var m = string.match(/^\s*\[(.*)\]\s*$/);
|
394 |
+
if (!m) throw 'Requirement is not an array: "' + string + '"';
|
395 |
+
var values = m[1].split(',').map(Utils.trimString);
|
396 |
+
if (values.length !== length) throw 'Requirement has ' + values.length + ' values when ' + length + ' are needed';
|
397 |
+
return values;
|
398 |
+
};
|
399 |
+
|
400 |
+
var convertExtraOptionRequirement = function convertExtraOptionRequirement(requirementSpec, string, extraOptionReader) {
|
401 |
+
var main = null;
|
402 |
+
var extra = {};
|
403 |
+
for (var key in requirementSpec) {
|
404 |
+
if (key) {
|
405 |
+
var value = extraOptionReader(key);
|
406 |
+
if ('string' === typeof value) value = Utils.parseRequirement(requirementSpec[key], value);
|
407 |
+
extra[key] = value;
|
408 |
+
} else {
|
409 |
+
main = Utils.parseRequirement(requirementSpec[key], string);
|
410 |
+
}
|
411 |
+
}
|
412 |
+
return [main, extra];
|
413 |
+
};
|
414 |
+
|
415 |
+
// A Validator needs to implement the methods `validate` and `parseRequirements`
|
416 |
+
|
417 |
+
var Validator = function Validator(spec) {
|
418 |
+
$.extend(true, this, spec);
|
419 |
+
};
|
420 |
+
|
421 |
+
Validator.prototype = {
|
422 |
+
// Returns `true` iff the given `value` is valid according the given requirements.
|
423 |
+
validate: function validate(value, requirementFirstArg) {
|
424 |
+
if (this.fn) {
|
425 |
+
// Legacy style validator
|
426 |
+
|
427 |
+
if (arguments.length > 3) // If more args then value, requirement, instance...
|
428 |
+
requirementFirstArg = [].slice.call(arguments, 1, -1); // Skip first arg (value) and last (instance), combining the rest
|
429 |
+
return this.fn(value, requirementFirstArg);
|
430 |
+
}
|
431 |
+
|
432 |
+
if (Array.isArray(value)) {
|
433 |
+
if (!this.validateMultiple) throw 'Validator `' + this.name + '` does not handle multiple values';
|
434 |
+
return this.validateMultiple.apply(this, arguments);
|
435 |
+
} else {
|
436 |
+
var instance = arguments[arguments.length - 1];
|
437 |
+
if (this.validateDate && instance._isDateInput()) {
|
438 |
+
arguments[0] = Utils.parse.date(arguments[0]);
|
439 |
+
if (arguments[0] === null) return false;
|
440 |
+
return this.validateDate.apply(this, arguments);
|
441 |
+
}
|
442 |
+
if (this.validateNumber) {
|
443 |
+
if (isNaN(value)) return false;
|
444 |
+
arguments[0] = parseFloat(arguments[0]);
|
445 |
+
return this.validateNumber.apply(this, arguments);
|
446 |
+
}
|
447 |
+
if (this.validateString) {
|
448 |
+
return this.validateString.apply(this, arguments);
|
449 |
+
}
|
450 |
+
throw 'Validator `' + this.name + '` only handles multiple values';
|
451 |
+
}
|
452 |
+
},
|
453 |
+
|
454 |
+
// Parses `requirements` into an array of arguments,
|
455 |
+
// according to `this.requirementType`
|
456 |
+
parseRequirements: function parseRequirements(requirements, extraOptionReader) {
|
457 |
+
if ('string' !== typeof requirements) {
|
458 |
+
// Assume requirement already parsed
|
459 |
+
// but make sure we return an array
|
460 |
+
return Array.isArray(requirements) ? requirements : [requirements];
|
461 |
+
}
|
462 |
+
var type = this.requirementType;
|
463 |
+
if (Array.isArray(type)) {
|
464 |
+
var values = convertArrayRequirement(requirements, type.length);
|
465 |
+
for (var i = 0; i < values.length; i++) values[i] = Utils.parseRequirement(type[i], values[i]);
|
466 |
+
return values;
|
467 |
+
} else if ($.isPlainObject(type)) {
|
468 |
+
return convertExtraOptionRequirement(type, requirements, extraOptionReader);
|
469 |
+
} else {
|
470 |
+
return [Utils.parseRequirement(type, requirements)];
|
471 |
+
}
|
472 |
+
},
|
473 |
+
// Defaults:
|
474 |
+
requirementType: 'string',
|
475 |
+
|
476 |
+
priority: 2
|
477 |
+
|
478 |
+
};
|
479 |
+
|
480 |
+
var ValidatorRegistry = function ValidatorRegistry(validators, catalog) {
|
481 |
+
this.__class__ = 'ValidatorRegistry';
|
482 |
+
|
483 |
+
// Default Parsley locale is en
|
484 |
+
this.locale = 'en';
|
485 |
+
|
486 |
+
this.init(validators || {}, catalog || {});
|
487 |
+
};
|
488 |
+
|
489 |
+
var typeTesters = {
|
490 |
+
email: /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i,
|
491 |
+
|
492 |
+
// Follow https://www.w3.org/TR/html5/infrastructure.html#floating-point-numbers
|
493 |
+
number: /^-?(\d*\.)?\d+(e[-+]?\d+)?$/i,
|
494 |
+
|
495 |
+
integer: /^-?\d+$/,
|
496 |
+
|
497 |
+
digits: /^\d+$/,
|
498 |
+
|
499 |
+
alphanum: /^\w+$/i,
|
500 |
+
|
501 |
+
date: {
|
502 |
+
test: function test(value) {
|
503 |
+
return Utils.parse.date(value) !== null;
|
504 |
+
}
|
505 |
+
},
|
506 |
+
|
507 |
+
url: new RegExp("^" +
|
508 |
+
// protocol identifier
|
509 |
+
"(?:(?:https?|ftp)://)?" + // ** mod: make scheme optional
|
510 |
+
// user:pass authentication
|
511 |
+
"(?:\\S+(?::\\S*)?@)?" + "(?:" +
|
512 |
+
// IP address exclusion
|
513 |
+
// private & local networks
|
514 |
+
// "(?!(?:10|127)(?:\\.\\d{1,3}){3})" + // ** mod: allow local networks
|
515 |
+
// "(?!(?:169\\.254|192\\.168)(?:\\.\\d{1,3}){2})" + // ** mod: allow local networks
|
516 |
+
// "(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})" + // ** mod: allow local networks
|
517 |
+
// IP address dotted notation octets
|
518 |
+
// excludes loopback network 0.0.0.0
|
519 |
+
// excludes reserved space >= 224.0.0.0
|
520 |
+
// excludes network & broacast addresses
|
521 |
+
// (first & last IP address of each class)
|
522 |
+
"(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])" + "(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}" + "(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))" + "|" +
|
523 |
+
// host name
|
524 |
+
'(?:(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)' +
|
525 |
+
// domain name
|
526 |
+
'(?:\\.(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)*' +
|
527 |
+
// TLD identifier
|
528 |
+
'(?:\\.(?:[a-z\\u00a1-\\uffff]{2,}))' + ")" +
|
529 |
+
// port number
|
530 |
+
"(?::\\d{2,5})?" +
|
531 |
+
// resource path
|
532 |
+
"(?:/\\S*)?" + "$", 'i')
|
533 |
+
};
|
534 |
+
typeTesters.range = typeTesters.number;
|
535 |
+
|
536 |
+
// See http://stackoverflow.com/a/10454560/8279
|
537 |
+
var decimalPlaces = function decimalPlaces(num) {
|
538 |
+
var match = ('' + num).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/);
|
539 |
+
if (!match) {
|
540 |
+
return 0;
|
541 |
+
}
|
542 |
+
return Math.max(0,
|
543 |
+
// Number of digits right of decimal point.
|
544 |
+
(match[1] ? match[1].length : 0) - (
|
545 |
+
// Adjust for scientific notation.
|
546 |
+
match[2] ? +match[2] : 0));
|
547 |
+
};
|
548 |
+
|
549 |
+
// parseArguments('number', ['1', '2']) => [1, 2]
|
550 |
+
var ValidatorRegistry__parseArguments = function ValidatorRegistry__parseArguments(type, args) {
|
551 |
+
return args.map(Utils.parse[type]);
|
552 |
+
};
|
553 |
+
// operatorToValidator returns a validating function for an operator function, applied to the given type
|
554 |
+
var ValidatorRegistry__operatorToValidator = function ValidatorRegistry__operatorToValidator(type, operator) {
|
555 |
+
return function (value) {
|
556 |
+
for (var _len = arguments.length, requirementsAndInput = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
557 |
+
requirementsAndInput[_key - 1] = arguments[_key];
|
558 |
+
}
|
559 |
+
|
560 |
+
requirementsAndInput.pop(); // Get rid of `input` argument
|
561 |
+
return operator.apply(undefined, [value].concat(_toConsumableArray(ValidatorRegistry__parseArguments(type, requirementsAndInput))));
|
562 |
+
};
|
563 |
+
};
|
564 |
+
|
565 |
+
var ValidatorRegistry__comparisonOperator = function ValidatorRegistry__comparisonOperator(operator) {
|
566 |
+
return {
|
567 |
+
validateDate: ValidatorRegistry__operatorToValidator('date', operator),
|
568 |
+
validateNumber: ValidatorRegistry__operatorToValidator('number', operator),
|
569 |
+
requirementType: operator.length <= 2 ? 'string' : ['string', 'string'], // Support operators with a 1 or 2 requirement(s)
|
570 |
+
priority: 30
|
571 |
+
};
|
572 |
+
};
|
573 |
+
|
574 |
+
ValidatorRegistry.prototype = {
|
575 |
+
init: function init(validators, catalog) {
|
576 |
+
this.catalog = catalog;
|
577 |
+
// Copy prototype's validators:
|
578 |
+
this.validators = _extends({}, this.validators);
|
579 |
+
|
580 |
+
for (var name in validators) this.addValidator(name, validators[name].fn, validators[name].priority);
|
581 |
+
|
582 |
+
window.Parsley.trigger('parsley:validator:init');
|
583 |
+
},
|
584 |
+
|
585 |
+
// Set new messages locale if we have dictionary loaded in ParsleyConfig.i18n
|
586 |
+
setLocale: function setLocale(locale) {
|
587 |
+
if ('undefined' === typeof this.catalog[locale]) throw new Error(locale + ' is not available in the catalog');
|
588 |
+
|
589 |
+
this.locale = locale;
|
590 |
+
|
591 |
+
return this;
|
592 |
+
},
|
593 |
+
|
594 |
+
// Add a new messages catalog for a given locale. Set locale for this catalog if set === `true`
|
595 |
+
addCatalog: function addCatalog(locale, messages, set) {
|
596 |
+
if ('object' === typeof messages) this.catalog[locale] = messages;
|
597 |
+
|
598 |
+
if (true === set) return this.setLocale(locale);
|
599 |
+
|
600 |
+
return this;
|
601 |
+
},
|
602 |
+
|
603 |
+
// Add a specific message for a given constraint in a given locale
|
604 |
+
addMessage: function addMessage(locale, name, message) {
|
605 |
+
if ('undefined' === typeof this.catalog[locale]) this.catalog[locale] = {};
|
606 |
+
|
607 |
+
this.catalog[locale][name] = message;
|
608 |
+
|
609 |
+
return this;
|
610 |
+
},
|
611 |
+
|
612 |
+
// Add messages for a given locale
|
613 |
+
addMessages: function addMessages(locale, nameMessageObject) {
|
614 |
+
for (var name in nameMessageObject) this.addMessage(locale, name, nameMessageObject[name]);
|
615 |
+
|
616 |
+
return this;
|
617 |
+
},
|
618 |
+
|
619 |
+
// Add a new validator
|
620 |
+
//
|
621 |
+
// addValidator('custom', {
|
622 |
+
// requirementType: ['integer', 'integer'],
|
623 |
+
// validateString: function(value, from, to) {},
|
624 |
+
// priority: 22,
|
625 |
+
// messages: {
|
626 |
+
// en: "Hey, that's no good",
|
627 |
+
// fr: "Aye aye, pas bon du tout",
|
628 |
+
// }
|
629 |
+
// })
|
630 |
+
//
|
631 |
+
// Old API was addValidator(name, function, priority)
|
632 |
+
//
|
633 |
+
addValidator: function addValidator(name, arg1, arg2) {
|
634 |
+
if (this.validators[name]) Utils.warn('Validator "' + name + '" is already defined.');else if (Defaults.hasOwnProperty(name)) {
|
635 |
+
Utils.warn('"' + name + '" is a restricted keyword and is not a valid validator name.');
|
636 |
+
return;
|
637 |
+
}
|
638 |
+
return this._setValidator.apply(this, arguments);
|
639 |
+
},
|
640 |
+
|
641 |
+
hasValidator: function hasValidator(name) {
|
642 |
+
return !!this.validators[name];
|
643 |
+
},
|
644 |
+
|
645 |
+
updateValidator: function updateValidator(name, arg1, arg2) {
|
646 |
+
if (!this.validators[name]) {
|
647 |
+
Utils.warn('Validator "' + name + '" is not already defined.');
|
648 |
+
return this.addValidator.apply(this, arguments);
|
649 |
+
}
|
650 |
+
return this._setValidator.apply(this, arguments);
|
651 |
+
},
|
652 |
+
|
653 |
+
removeValidator: function removeValidator(name) {
|
654 |
+
if (!this.validators[name]) Utils.warn('Validator "' + name + '" is not defined.');
|
655 |
+
|
656 |
+
delete this.validators[name];
|
657 |
+
|
658 |
+
return this;
|
659 |
+
},
|
660 |
+
|
661 |
+
_setValidator: function _setValidator(name, validator, priority) {
|
662 |
+
if ('object' !== typeof validator) {
|
663 |
+
// Old style validator, with `fn` and `priority`
|
664 |
+
validator = {
|
665 |
+
fn: validator,
|
666 |
+
priority: priority
|
667 |
+
};
|
668 |
+
}
|
669 |
+
if (!validator.validate) {
|
670 |
+
validator = new Validator(validator);
|
671 |
+
}
|
672 |
+
this.validators[name] = validator;
|
673 |
+
|
674 |
+
for (var locale in validator.messages || {}) this.addMessage(locale, name, validator.messages[locale]);
|
675 |
+
|
676 |
+
return this;
|
677 |
+
},
|
678 |
+
|
679 |
+
getErrorMessage: function getErrorMessage(constraint) {
|
680 |
+
var message;
|
681 |
+
|
682 |
+
// Type constraints are a bit different, we have to match their requirements too to find right error message
|
683 |
+
if ('type' === constraint.name) {
|
684 |
+
var typeMessages = this.catalog[this.locale][constraint.name] || {};
|
685 |
+
message = typeMessages[constraint.requirements];
|
686 |
+
} else message = this.formatMessage(this.catalog[this.locale][constraint.name], constraint.requirements);
|
687 |
+
|
688 |
+
return message || this.catalog[this.locale].defaultMessage || this.catalog.en.defaultMessage;
|
689 |
+
},
|
690 |
+
|
691 |
+
// Kind of light `sprintf()` implementation
|
692 |
+
formatMessage: function formatMessage(string, parameters) {
|
693 |
+
if ('object' === typeof parameters) {
|
694 |
+
for (var i in parameters) string = this.formatMessage(string, parameters[i]);
|
695 |
+
|
696 |
+
return string;
|
697 |
+
}
|
698 |
+
|
699 |
+
return 'string' === typeof string ? string.replace(/%s/i, parameters) : '';
|
700 |
+
},
|
701 |
+
|
702 |
+
// Here is the Parsley default validators list.
|
703 |
+
// A validator is an object with the following key values:
|
704 |
+
// - priority: an integer
|
705 |
+
// - requirement: 'string' (default), 'integer', 'number', 'regexp' or an Array of these
|
706 |
+
// - validateString, validateMultiple, validateNumber: functions returning `true`, `false` or a promise
|
707 |
+
// Alternatively, a validator can be a function that returns such an object
|
708 |
+
//
|
709 |
+
validators: {
|
710 |
+
notblank: {
|
711 |
+
validateString: function validateString(value) {
|
712 |
+
return (/\S/.test(value)
|
713 |
+
);
|
714 |
+
},
|
715 |
+
priority: 2
|
716 |
+
},
|
717 |
+
required: {
|
718 |
+
validateMultiple: function validateMultiple(values) {
|
719 |
+
return values.length > 0;
|
720 |
+
},
|
721 |
+
validateString: function validateString(value) {
|
722 |
+
return (/\S/.test(value)
|
723 |
+
);
|
724 |
+
},
|
725 |
+
priority: 512
|
726 |
+
},
|
727 |
+
type: {
|
728 |
+
validateString: function validateString(value, type) {
|
729 |
+
var _ref = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];
|
730 |
+
|
731 |
+
var _ref$step = _ref.step;
|
732 |
+
var step = _ref$step === undefined ? 'any' : _ref$step;
|
733 |
+
var _ref$base = _ref.base;
|
734 |
+
var base = _ref$base === undefined ? 0 : _ref$base;
|
735 |
+
|
736 |
+
var tester = typeTesters[type];
|
737 |
+
if (!tester) {
|
738 |
+
throw new Error('validator type `' + type + '` is not supported');
|
739 |
+
}
|
740 |
+
if (!tester.test(value)) return false;
|
741 |
+
if ('number' === type) {
|
742 |
+
if (!/^any$/i.test(step || '')) {
|
743 |
+
var nb = Number(value);
|
744 |
+
var decimals = Math.max(decimalPlaces(step), decimalPlaces(base));
|
745 |
+
if (decimalPlaces(nb) > decimals) // Value can't have too many decimals
|
746 |
+
return false;
|
747 |
+
// Be careful of rounding errors by using integers.
|
748 |
+
var toInt = function toInt(f) {
|
749 |
+
return Math.round(f * Math.pow(10, decimals));
|
750 |
+
};
|
751 |
+
if ((toInt(nb) - toInt(base)) % toInt(step) != 0) return false;
|
752 |
+
}
|
753 |
+
}
|
754 |
+
return true;
|
755 |
+
},
|
756 |
+
requirementType: {
|
757 |
+
'': 'string',
|
758 |
+
step: 'string',
|
759 |
+
base: 'number'
|
760 |
+
},
|
761 |
+
priority: 256
|
762 |
+
},
|
763 |
+
pattern: {
|
764 |
+
validateString: function validateString(value, regexp) {
|
765 |
+
return regexp.test(value);
|
766 |
+
},
|
767 |
+
requirementType: 'regexp',
|
768 |
+
priority: 64
|
769 |
+
},
|
770 |
+
minlength: {
|
771 |
+
validateString: function validateString(value, requirement) {
|
772 |
+
return value.length >= requirement;
|
773 |
+
},
|
774 |
+
requirementType: 'integer',
|
775 |
+
priority: 30
|
776 |
+
},
|
777 |
+
maxlength: {
|
778 |
+
validateString: function validateString(value, requirement) {
|
779 |
+
return value.length <= requirement;
|
780 |
+
},
|
781 |
+
requirementType: 'integer',
|
782 |
+
priority: 30
|
783 |
+
},
|
784 |
+
length: {
|
785 |
+
validateString: function validateString(value, min, max) {
|
786 |
+
return value.length >= min && value.length <= max;
|
787 |
+
},
|
788 |
+
requirementType: ['integer', 'integer'],
|
789 |
+
priority: 30
|
790 |
+
},
|
791 |
+
mincheck: {
|
792 |
+
validateMultiple: function validateMultiple(values, requirement) {
|
793 |
+
return values.length >= requirement;
|
794 |
+
},
|
795 |
+
requirementType: 'integer',
|
796 |
+
priority: 30
|
797 |
+
},
|
798 |
+
maxcheck: {
|
799 |
+
validateMultiple: function validateMultiple(values, requirement) {
|
800 |
+
return values.length <= requirement;
|
801 |
+
},
|
802 |
+
requirementType: 'integer',
|
803 |
+
priority: 30
|
804 |
+
},
|
805 |
+
check: {
|
806 |
+
validateMultiple: function validateMultiple(values, min, max) {
|
807 |
+
return values.length >= min && values.length <= max;
|
808 |
+
},
|
809 |
+
requirementType: ['integer', 'integer'],
|
810 |
+
priority: 30
|
811 |
+
},
|
812 |
+
min: ValidatorRegistry__comparisonOperator(function (value, requirement) {
|
813 |
+
return value >= requirement;
|
814 |
+
}),
|
815 |
+
max: ValidatorRegistry__comparisonOperator(function (value, requirement) {
|
816 |
+
return value <= requirement;
|
817 |
+
}),
|
818 |
+
range: ValidatorRegistry__comparisonOperator(function (value, min, max) {
|
819 |
+
return value >= min && value <= max;
|
820 |
+
}),
|
821 |
+
equalto: {
|
822 |
+
validateString: function validateString(value, refOrValue) {
|
823 |
+
var $reference = $(refOrValue);
|
824 |
+
if ($reference.length) return value === $reference.val();else return value === refOrValue;
|
825 |
+
},
|
826 |
+
priority: 256
|
827 |
+
}
|
828 |
+
}
|
829 |
+
};
|
830 |
+
|
831 |
+
var UI = {};
|
832 |
+
|
833 |
+
var diffResults = function diffResults(newResult, oldResult, deep) {
|
834 |
+
var added = [];
|
835 |
+
var kept = [];
|
836 |
+
|
837 |
+
for (var i = 0; i < newResult.length; i++) {
|
838 |
+
var found = false;
|
839 |
+
|
840 |
+
for (var j = 0; j < oldResult.length; j++) if (newResult[i].assert.name === oldResult[j].assert.name) {
|
841 |
+
found = true;
|
842 |
+
break;
|
843 |
+
}
|
844 |
+
|
845 |
+
if (found) kept.push(newResult[i]);else added.push(newResult[i]);
|
846 |
+
}
|
847 |
+
|
848 |
+
return {
|
849 |
+
kept: kept,
|
850 |
+
added: added,
|
851 |
+
removed: !deep ? diffResults(oldResult, newResult, true).added : []
|
852 |
+
};
|
853 |
+
};
|
854 |
+
|
855 |
+
UI.Form = {
|
856 |
+
|
857 |
+
_actualizeTriggers: function _actualizeTriggers() {
|
858 |
+
var _this2 = this;
|
859 |
+
|
860 |
+
this.$element.on('submit.Parsley', function (evt) {
|
861 |
+
_this2.onSubmitValidate(evt);
|
862 |
+
});
|
863 |
+
this.$element.on('click.Parsley', Utils._SubmitSelector, function (evt) {
|
864 |
+
_this2.onSubmitButton(evt);
|
865 |
+
});
|
866 |
+
|
867 |
+
// UI could be disabled
|
868 |
+
if (false === this.options.uiEnabled) return;
|
869 |
+
|
870 |
+
this.element.setAttribute('novalidate', '');
|
871 |
+
},
|
872 |
+
|
873 |
+
focus: function focus() {
|
874 |
+
this._focusedField = null;
|
875 |
+
|
876 |
+
if (true === this.validationResult || 'none' === this.options.focus) return null;
|
877 |
+
|
878 |
+
for (var i = 0; i < this.fields.length; i++) {
|
879 |
+
var field = this.fields[i];
|
880 |
+
if (true !== field.validationResult && field.validationResult.length > 0 && 'undefined' === typeof field.options.noFocus) {
|
881 |
+
this._focusedField = field.$element;
|
882 |
+
if ('first' === this.options.focus) break;
|
883 |
+
}
|
884 |
+
}
|
885 |
+
|
886 |
+
if (null === this._focusedField) return null;
|
887 |
+
|
888 |
+
return this._focusedField.focus();
|
889 |
+
},
|
890 |
+
|
891 |
+
_destroyUI: function _destroyUI() {
|
892 |
+
// Reset all event listeners
|
893 |
+
this.$element.off('.Parsley');
|
894 |
+
}
|
895 |
+
|
896 |
+
};
|
897 |
+
|
898 |
+
UI.Field = {
|
899 |
+
|
900 |
+
_reflowUI: function _reflowUI() {
|
901 |
+
this._buildUI();
|
902 |
+
|
903 |
+
// If this field doesn't have an active UI don't bother doing something
|
904 |
+
if (!this._ui) return;
|
905 |
+
|
906 |
+
// Diff between two validation results
|
907 |
+
var diff = diffResults(this.validationResult, this._ui.lastValidationResult);
|
908 |
+
|
909 |
+
// Then store current validation result for next reflow
|
910 |
+
this._ui.lastValidationResult = this.validationResult;
|
911 |
+
|
912 |
+
// Handle valid / invalid / none field class
|
913 |
+
this._manageStatusClass();
|
914 |
+
|
915 |
+
// Add, remove, updated errors messages
|
916 |
+
this._manageErrorsMessages(diff);
|
917 |
+
|
918 |
+
// Triggers impl
|
919 |
+
this._actualizeTriggers();
|
920 |
+
|
921 |
+
// If field is not valid for the first time, bind keyup trigger to ease UX and quickly inform user
|
922 |
+
if ((diff.kept.length || diff.added.length) && !this._failedOnce) {
|
923 |
+
this._failedOnce = true;
|
924 |
+
this._actualizeTriggers();
|
925 |
+
}
|
926 |
+
},
|
927 |
+
|
928 |
+
// Returns an array of field's error message(s)
|
929 |
+
getErrorsMessages: function getErrorsMessages() {
|
930 |
+
// No error message, field is valid
|
931 |
+
if (true === this.validationResult) return [];
|
932 |
+
|
933 |
+
var messages = [];
|
934 |
+
|
935 |
+
for (var i = 0; i < this.validationResult.length; i++) messages.push(this.validationResult[i].errorMessage || this._getErrorMessage(this.validationResult[i].assert));
|
936 |
+
|
937 |
+
return messages;
|
938 |
+
},
|
939 |
+
|
940 |
+
// It's a goal of Parsley that this method is no longer required [#1073]
|
941 |
+
addError: function addError(name) {
|
942 |
+
var _ref2 = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
|
943 |
+
|
944 |
+
var message = _ref2.message;
|
945 |
+
var assert = _ref2.assert;
|
946 |
+
var _ref2$updateClass = _ref2.updateClass;
|
947 |
+
var updateClass = _ref2$updateClass === undefined ? true : _ref2$updateClass;
|
948 |
+
|
949 |
+
this._buildUI();
|
950 |
+
this._addError(name, { message: message, assert: assert });
|
951 |
+
|
952 |
+
if (updateClass) this._errorClass();
|
953 |
+
},
|
954 |
+
|
955 |
+
// It's a goal of Parsley that this method is no longer required [#1073]
|
956 |
+
updateError: function updateError(name) {
|
957 |
+
var _ref3 = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
|
958 |
+
|
959 |
+
var message = _ref3.message;
|
960 |
+
var assert = _ref3.assert;
|
961 |
+
var _ref3$updateClass = _ref3.updateClass;
|
962 |
+
var updateClass = _ref3$updateClass === undefined ? true : _ref3$updateClass;
|
963 |
+
|
964 |
+
this._buildUI();
|
965 |
+
this._updateError(name, { message: message, assert: assert });
|
966 |
+
|
967 |
+
if (updateClass) this._errorClass();
|
968 |
+
},
|
969 |
+
|
970 |
+
// It's a goal of Parsley that this method is no longer required [#1073]
|
971 |
+
removeError: function removeError(name) {
|
972 |
+
var _ref4 = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
|
973 |
+
|
974 |
+
var _ref4$updateClass = _ref4.updateClass;
|
975 |
+
var updateClass = _ref4$updateClass === undefined ? true : _ref4$updateClass;
|
976 |
+
|
977 |
+
this._buildUI();
|
978 |
+
this._removeError(name);
|
979 |
+
|
980 |
+
// edge case possible here: remove a standard Parsley error that is still failing in this.validationResult
|
981 |
+
// but highly improbable cuz' manually removing a well Parsley handled error makes no sense.
|
982 |
+
if (updateClass) this._manageStatusClass();
|
983 |
+
},
|
984 |
+
|
985 |
+
_manageStatusClass: function _manageStatusClass() {
|
986 |
+
if (this.hasConstraints() && this.needsValidation() && true === this.validationResult) this._successClass();else if (this.validationResult.length > 0) this._errorClass();else this._resetClass();
|
987 |
+
},
|
988 |
+
|
989 |
+
_manageErrorsMessages: function _manageErrorsMessages(diff) {
|
990 |
+
if ('undefined' !== typeof this.options.errorsMessagesDisabled) return;
|
991 |
+
|
992 |
+
// Case where we have errorMessage option that configure an unique field error message, regardless failing validators
|
993 |
+
if ('undefined' !== typeof this.options.errorMessage) {
|
994 |
+
if (diff.added.length || diff.kept.length) {
|
995 |
+
this._insertErrorWrapper();
|
996 |
+
|
997 |
+
if (0 === this._ui.$errorsWrapper.find('.parsley-custom-error-message').length) this._ui.$errorsWrapper.append($(this.options.errorTemplate).addClass('parsley-custom-error-message'));
|
998 |
+
|
999 |
+
return this._ui.$errorsWrapper.addClass('filled').find('.parsley-custom-error-message').html(this.options.errorMessage);
|
1000 |
+
}
|
1001 |
+
|
1002 |
+
return this._ui.$errorsWrapper.removeClass('filled').find('.parsley-custom-error-message').remove();
|
1003 |
+
}
|
1004 |
+
|
1005 |
+
// Show, hide, update failing constraints messages
|
1006 |
+
for (var i = 0; i < diff.removed.length; i++) this._removeError(diff.removed[i].assert.name);
|
1007 |
+
|
1008 |
+
for (i = 0; i < diff.added.length; i++) this._addError(diff.added[i].assert.name, { message: diff.added[i].errorMessage, assert: diff.added[i].assert });
|
1009 |
+
|
1010 |
+
for (i = 0; i < diff.kept.length; i++) this._updateError(diff.kept[i].assert.name, { message: diff.kept[i].errorMessage, assert: diff.kept[i].assert });
|
1011 |
+
},
|
1012 |
+
|
1013 |
+
_addError: function _addError(name, _ref5) {
|
1014 |
+
var message = _ref5.message;
|
1015 |
+
var assert = _ref5.assert;
|
1016 |
+
|
1017 |
+
this._insertErrorWrapper();
|
1018 |
+
this._ui.$errorsWrapper.addClass('filled').append($(this.options.errorTemplate).addClass('parsley-' + name).html(message || this._getErrorMessage(assert)));
|
1019 |
+
},
|
1020 |
+
|
1021 |
+
_updateError: function _updateError(name, _ref6) {
|
1022 |
+
var message = _ref6.message;
|
1023 |
+
var assert = _ref6.assert;
|
1024 |
+
|
1025 |
+
this._ui.$errorsWrapper.addClass('filled').find('.parsley-' + name).html(message || this._getErrorMessage(assert));
|
1026 |
+
},
|
1027 |
+
|
1028 |
+
_removeError: function _removeError(name) {
|
1029 |
+
this._ui.$errorsWrapper.removeClass('filled').find('.parsley-' + name).remove();
|
1030 |
+
},
|
1031 |
+
|
1032 |
+
_getErrorMessage: function _getErrorMessage(constraint) {
|
1033 |
+
var customConstraintErrorMessage = constraint.name + 'Message';
|
1034 |
+
|
1035 |
+
if ('undefined' !== typeof this.options[customConstraintErrorMessage]) return window.Parsley.formatMessage(this.options[customConstraintErrorMessage], constraint.requirements);
|
1036 |
+
|
1037 |
+
return window.Parsley.getErrorMessage(constraint);
|
1038 |
+
},
|
1039 |
+
|
1040 |
+
_buildUI: function _buildUI() {
|
1041 |
+
// UI could be already built or disabled
|
1042 |
+
if (this._ui || false === this.options.uiEnabled) return;
|
1043 |
+
|
1044 |
+
var _ui = {};
|
1045 |
+
|
1046 |
+
// Give field its Parsley id in DOM
|
1047 |
+
this.element.setAttribute(this.options.namespace + 'id', this.__id__);
|
1048 |
+
|
1049 |
+
/** Generate important UI elements and store them in this **/
|
1050 |
+
// $errorClassHandler is the $element that woul have parsley-error and parsley-success classes
|
1051 |
+
_ui.$errorClassHandler = this._manageClassHandler();
|
1052 |
+
|
1053 |
+
// $errorsWrapper is a div that would contain the various field errors, it will be appended into $errorsContainer
|
1054 |
+
_ui.errorsWrapperId = 'parsley-id-' + (this.options.multiple ? 'multiple-' + this.options.multiple : this.__id__);
|
1055 |
+
_ui.$errorsWrapper = $(this.options.errorsWrapper).attr('id', _ui.errorsWrapperId);
|
1056 |
+
|
1057 |
+
// ValidationResult UI storage to detect what have changed bwt two validations, and update DOM accordingly
|
1058 |
+
_ui.lastValidationResult = [];
|
1059 |
+
_ui.validationInformationVisible = false;
|
1060 |
+
|
1061 |
+
// Store it in this for later
|
1062 |
+
this._ui = _ui;
|
1063 |
+
},
|
1064 |
+
|
1065 |
+
// Determine which element will have `parsley-error` and `parsley-success` classes
|
1066 |
+
_manageClassHandler: function _manageClassHandler() {
|
1067 |
+
// Class handled could also be determined by function given in Parsley options
|
1068 |
+
if ('string' === typeof this.options.classHandler && $(this.options.classHandler).length) return $(this.options.classHandler);
|
1069 |
+
|
1070 |
+
// Class handled could also be determined by function given in Parsley options
|
1071 |
+
var $handlerFunction = this.options.classHandler;
|
1072 |
+
|
1073 |
+
// It might also be the function name of a global function
|
1074 |
+
if ('string' === typeof this.options.classHandler && 'function' === typeof window[this.options.classHandler]) $handlerFunction = window[this.options.classHandler];
|
1075 |
+
|
1076 |
+
if ('function' === typeof $handlerFunction) {
|
1077 |
+
var $handler = $handlerFunction.call(this, this);
|
1078 |
+
|
1079 |
+
// If this function returned a valid existing DOM element, go for it
|
1080 |
+
if ('undefined' !== typeof $handler && $handler.length) return $handler;
|
1081 |
+
} else if ('object' === typeof $handlerFunction && $handlerFunction instanceof jQuery && $handlerFunction.length) {
|
1082 |
+
return $handlerFunction;
|
1083 |
+
} else if ($handlerFunction) {
|
1084 |
+
Utils.warn('The class handler `' + $handlerFunction + '` does not exist in DOM nor as a global JS function');
|
1085 |
+
}
|
1086 |
+
|
1087 |
+
return this._inputHolder();
|
1088 |
+
},
|
1089 |
+
|
1090 |
+
_inputHolder: function _inputHolder() {
|
1091 |
+
// if simple element (input, texatrea, select...) it will perfectly host the classes and precede the error container
|
1092 |
+
if (!this.options.multiple || this.element.nodeName === 'SELECT') return this.$element;
|
1093 |
+
|
1094 |
+
// But if multiple element (radio, checkbox), that would be their parent
|
1095 |
+
return this.$element.parent();
|
1096 |
+
},
|
1097 |
+
|
1098 |
+
_insertErrorWrapper: function _insertErrorWrapper() {
|
1099 |
+
var $errorsContainer = this.options.errorsContainer;
|
1100 |
+
|
1101 |
+
// Nothing to do if already inserted
|
1102 |
+
if (0 !== this._ui.$errorsWrapper.parent().length) return this._ui.$errorsWrapper.parent();
|
1103 |
+
|
1104 |
+
if ('string' === typeof $errorsContainer) {
|
1105 |
+
if ($($errorsContainer).length) return $($errorsContainer).append(this._ui.$errorsWrapper);else if ('function' === typeof window[$errorsContainer]) $errorsContainer = window[$errorsContainer];else Utils.warn('The errors container `' + $errorsContainer + '` does not exist in DOM nor as a global JS function');
|
1106 |
+
}
|
1107 |
+
|
1108 |
+
if ('function' === typeof $errorsContainer) $errorsContainer = $errorsContainer.call(this, this);
|
1109 |
+
|
1110 |
+
if ('object' === typeof $errorsContainer && $errorsContainer.length) return $errorsContainer.append(this._ui.$errorsWrapper);
|
1111 |
+
|
1112 |
+
return this._inputHolder().after(this._ui.$errorsWrapper);
|
1113 |
+
},
|
1114 |
+
|
1115 |
+
_actualizeTriggers: function _actualizeTriggers() {
|
1116 |
+
var _this3 = this;
|
1117 |
+
|
1118 |
+
var $toBind = this._findRelated();
|
1119 |
+
var trigger;
|
1120 |
+
|
1121 |
+
// Remove Parsley events already bound on this field
|
1122 |
+
$toBind.off('.Parsley');
|
1123 |
+
if (this._failedOnce) $toBind.on(Utils.namespaceEvents(this.options.triggerAfterFailure, 'Parsley'), function () {
|
1124 |
+
_this3._validateIfNeeded();
|
1125 |
+
});else if (trigger = Utils.namespaceEvents(this.options.trigger, 'Parsley')) {
|
1126 |
+
$toBind.on(trigger, function (event) {
|
1127 |
+
_this3._validateIfNeeded(event);
|
1128 |
+
});
|
1129 |
+
}
|
1130 |
+
},
|
1131 |
+
|
1132 |
+
_validateIfNeeded: function _validateIfNeeded(event) {
|
1133 |
+
var _this4 = this;
|
1134 |
+
|
1135 |
+
// For keyup, keypress, keydown, input... events that could be a little bit obstrusive
|
1136 |
+
// do not validate if val length < min threshold on first validation. Once field have been validated once and info
|
1137 |
+
// about success or failure have been displayed, always validate with this trigger to reflect every yalidation change.
|
1138 |
+
if (event && /key|input/.test(event.type)) if (!(this._ui && this._ui.validationInformationVisible) && this.getValue().length <= this.options.validationThreshold) return;
|
1139 |
+
|
1140 |
+
if (this.options.debounce) {
|
1141 |
+
window.clearTimeout(this._debounced);
|
1142 |
+
this._debounced = window.setTimeout(function () {
|
1143 |
+
return _this4.validate();
|
1144 |
+
}, this.options.debounce);
|
1145 |
+
} else this.validate();
|
1146 |
+
},
|
1147 |
+
|
1148 |
+
_resetUI: function _resetUI() {
|
1149 |
+
// Reset all event listeners
|
1150 |
+
this._failedOnce = false;
|
1151 |
+
this._actualizeTriggers();
|
1152 |
+
|
1153 |
+
// Nothing to do if UI never initialized for this field
|
1154 |
+
if ('undefined' === typeof this._ui) return;
|
1155 |
+
|
1156 |
+
// Reset all errors' li
|
1157 |
+
this._ui.$errorsWrapper.removeClass('filled').children().remove();
|
1158 |
+
|
1159 |
+
// Reset validation class
|
1160 |
+
this._resetClass();
|
1161 |
+
|
1162 |
+
// Reset validation flags and last validation result
|
1163 |
+
this._ui.lastValidationResult = [];
|
1164 |
+
this._ui.validationInformationVisible = false;
|
1165 |
+
},
|
1166 |
+
|
1167 |
+
_destroyUI: function _destroyUI() {
|
1168 |
+
this._resetUI();
|
1169 |
+
|
1170 |
+
if ('undefined' !== typeof this._ui) this._ui.$errorsWrapper.remove();
|
1171 |
+
|
1172 |
+
delete this._ui;
|
1173 |
+
},
|
1174 |
+
|
1175 |
+
_successClass: function _successClass() {
|
1176 |
+
this._ui.validationInformationVisible = true;
|
1177 |
+
this._ui.$errorClassHandler.removeClass(this.options.errorClass).addClass(this.options.successClass);
|
1178 |
+
},
|
1179 |
+
_errorClass: function _errorClass() {
|
1180 |
+
this._ui.validationInformationVisible = true;
|
1181 |
+
this._ui.$errorClassHandler.removeClass(this.options.successClass).addClass(this.options.errorClass);
|
1182 |
+
},
|
1183 |
+
_resetClass: function _resetClass() {
|
1184 |
+
this._ui.$errorClassHandler.removeClass(this.options.successClass).removeClass(this.options.errorClass);
|
1185 |
+
}
|
1186 |
+
};
|
1187 |
+
|
1188 |
+
var Form = function Form(element, domOptions, options) {
|
1189 |
+
this.__class__ = 'Form';
|
1190 |
+
|
1191 |
+
this.element = element;
|
1192 |
+
this.$element = $(element);
|
1193 |
+
this.domOptions = domOptions;
|
1194 |
+
this.options = options;
|
1195 |
+
this.parent = window.Parsley;
|
1196 |
+
|
1197 |
+
this.fields = [];
|
1198 |
+
this.validationResult = null;
|
1199 |
+
};
|
1200 |
+
|
1201 |
+
var Form__statusMapping = { pending: null, resolved: true, rejected: false };
|
1202 |
+
|
1203 |
+
Form.prototype = {
|
1204 |
+
onSubmitValidate: function onSubmitValidate(event) {
|
1205 |
+
var _this5 = this;
|
1206 |
+
|
1207 |
+
// This is a Parsley generated submit event, do not validate, do not prevent, simply exit and keep normal behavior
|
1208 |
+
if (true === event.parsley) return;
|
1209 |
+
|
1210 |
+
// If we didn't come here through a submit button, use the first one in the form
|
1211 |
+
var submitSource = this._submitSource || this.$element.find(Utils._SubmitSelector)[0];
|
1212 |
+
this._submitSource = null;
|
1213 |
+
this.$element.find('.parsley-synthetic-submit-button').prop('disabled', true);
|
1214 |
+
if (submitSource && null !== submitSource.getAttribute('formnovalidate')) return;
|
1215 |
+
|
1216 |
+
window.Parsley._remoteCache = {};
|
1217 |
+
|
1218 |
+
var promise = this.whenValidate({ event: event });
|
1219 |
+
|
1220 |
+
if ('resolved' === promise.state() && false !== this._trigger('submit')) {
|
1221 |
+
// All good, let event go through. We make this distinction because browsers
|
1222 |
+
// differ in their handling of `submit` being called from inside a submit event [#1047]
|
1223 |
+
} else {
|
1224 |
+
// Rejected or pending: cancel this submit
|
1225 |
+
event.stopImmediatePropagation();
|
1226 |
+
event.preventDefault();
|
1227 |
+
if ('pending' === promise.state()) promise.done(function () {
|
1228 |
+
_this5._submit(submitSource);
|
1229 |
+
});
|
1230 |
+
}
|
1231 |
+
},
|
1232 |
+
|
1233 |
+
onSubmitButton: function onSubmitButton(event) {
|
1234 |
+
this._submitSource = event.currentTarget;
|
1235 |
+
},
|
1236 |
+
// internal
|
1237 |
+
// _submit submits the form, this time without going through the validations.
|
1238 |
+
// Care must be taken to "fake" the actual submit button being clicked.
|
1239 |
+
_submit: function _submit(submitSource) {
|
1240 |
+
if (false === this._trigger('submit')) return;
|
1241 |
+
// Add submit button's data
|
1242 |
+
if (submitSource) {
|
1243 |
+
var $synthetic = this.$element.find('.parsley-synthetic-submit-button').prop('disabled', false);
|
1244 |
+
if (0 === $synthetic.length) $synthetic = $('<input class="parsley-synthetic-submit-button" type="hidden">').appendTo(this.$element);
|
1245 |
+
$synthetic.attr({
|
1246 |
+
name: submitSource.getAttribute('name'),
|
1247 |
+
value: submitSource.getAttribute('value')
|
1248 |
+
});
|
1249 |
+
}
|
1250 |
+
|
1251 |
+
this.$element.trigger(_extends($.Event('submit'), { parsley: true }));
|
1252 |
+
},
|
1253 |
+
|
1254 |
+
// Performs validation on fields while triggering events.
|
1255 |
+
// @returns `true` if all validations succeeds, `false`
|
1256 |
+
// if a failure is immediately detected, or `null`
|
1257 |
+
// if dependant on a promise.
|
1258 |
+
// Consider using `whenValidate` instead.
|
1259 |
+
validate: function validate(options) {
|
1260 |
+
if (arguments.length >= 1 && !$.isPlainObject(options)) {
|
1261 |
+
Utils.warnOnce('Calling validate on a parsley form without passing arguments as an object is deprecated.');
|
1262 |
+
|
1263 |
+
var _arguments = _slice.call(arguments);
|
1264 |
+
|
1265 |
+
var group = _arguments[0];
|
1266 |
+
var force = _arguments[1];
|
1267 |
+
var event = _arguments[2];
|
1268 |
+
|
1269 |
+
options = { group: group, force: force, event: event };
|
1270 |
+
}
|
1271 |
+
return Form__statusMapping[this.whenValidate(options).state()];
|
1272 |
+
},
|
1273 |
+
|
1274 |
+
whenValidate: function whenValidate() {
|
1275 |
+
var _Utils$all$done$fail$always,
|
1276 |
+
_this6 = this;
|
1277 |
+
|
1278 |
+
var _ref7 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
|
1279 |
+
|
1280 |
+
var group = _ref7.group;
|
1281 |
+
var force = _ref7.force;
|
1282 |
+
var event = _ref7.event;
|
1283 |
+
|
1284 |
+
this.submitEvent = event;
|
1285 |
+
if (event) {
|
1286 |
+
this.submitEvent = _extends({}, event, { preventDefault: function preventDefault() {
|
1287 |
+
Utils.warnOnce("Using `this.submitEvent.preventDefault()` is deprecated; instead, call `this.validationResult = false`");
|
1288 |
+
_this6.validationResult = false;
|
1289 |
+
} });
|
1290 |
+
}
|
1291 |
+
this.validationResult = true;
|
1292 |
+
|
1293 |
+
// fire validate event to eventually modify things before every validation
|
1294 |
+
this._trigger('validate');
|
1295 |
+
|
1296 |
+
// Refresh form DOM options and form's fields that could have changed
|
1297 |
+
this._refreshFields();
|
1298 |
+
|
1299 |
+
var promises = this._withoutReactualizingFormOptions(function () {
|
1300 |
+
return $.map(_this6.fields, function (field) {
|
1301 |
+
return field.whenValidate({ force: force, group: group });
|
1302 |
+
});
|
1303 |
+
});
|
1304 |
+
|
1305 |
+
return (_Utils$all$done$fail$always = Utils.all(promises).done(function () {
|
1306 |
+
_this6._trigger('success');
|
1307 |
+
}).fail(function () {
|
1308 |
+
_this6.validationResult = false;
|
1309 |
+
_this6.focus();
|
1310 |
+
_this6._trigger('error');
|
1311 |
+
}).always(function () {
|
1312 |
+
_this6._trigger('validated');
|
1313 |
+
})).pipe.apply(_Utils$all$done$fail$always, _toConsumableArray(this._pipeAccordingToValidationResult()));
|
1314 |
+
},
|
1315 |
+
|
1316 |
+
// Iterate over refreshed fields, and stop on first failure.
|
1317 |
+
// Returns `true` if all fields are valid, `false` if a failure is detected
|
1318 |
+
// or `null` if the result depends on an unresolved promise.
|
1319 |
+
// Prefer using `whenValid` instead.
|
1320 |
+
isValid: function isValid(options) {
|
1321 |
+
if (arguments.length >= 1 && !$.isPlainObject(options)) {
|
1322 |
+
Utils.warnOnce('Calling isValid on a parsley form without passing arguments as an object is deprecated.');
|
1323 |
+
|
1324 |
+
var _arguments2 = _slice.call(arguments);
|
1325 |
+
|
1326 |
+
var group = _arguments2[0];
|
1327 |
+
var force = _arguments2[1];
|
1328 |
+
|
1329 |
+
options = { group: group, force: force };
|
1330 |
+
}
|
1331 |
+
return Form__statusMapping[this.whenValid(options).state()];
|
1332 |
+
},
|
1333 |
+
|
1334 |
+
// Iterate over refreshed fields and validate them.
|
1335 |
+
// Returns a promise.
|
1336 |
+
// A validation that immediately fails will interrupt the validations.
|
1337 |
+
whenValid: function whenValid() {
|
1338 |
+
var _this7 = this;
|
1339 |
+
|
1340 |
+
var _ref8 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
|
1341 |
+
|
1342 |
+
var group = _ref8.group;
|
1343 |
+
var force = _ref8.force;
|
1344 |
+
|
1345 |
+
this._refreshFields();
|
1346 |
+
|
1347 |
+
var promises = this._withoutReactualizingFormOptions(function () {
|
1348 |
+
return $.map(_this7.fields, function (field) {
|
1349 |
+
return field.whenValid({ group: group, force: force });
|
1350 |
+
});
|
1351 |
+
});
|
1352 |
+
return Utils.all(promises);
|
1353 |
+
},
|
1354 |
+
|
1355 |
+
refresh: function refresh() {
|
1356 |
+
this._refreshFields();
|
1357 |
+
return this;
|
1358 |
+
},
|
1359 |
+
|
1360 |
+
// Reset UI
|
1361 |
+
reset: function reset() {
|
1362 |
+
// Form case: emit a reset event for each field
|
1363 |
+
for (var i = 0; i < this.fields.length; i++) this.fields[i].reset();
|
1364 |
+
|
1365 |
+
this._trigger('reset');
|
1366 |
+
},
|
1367 |
+
|
1368 |
+
// Destroy Parsley instance (+ UI)
|
1369 |
+
destroy: function destroy() {
|
1370 |
+
// Field case: emit destroy event to clean UI and then destroy stored instance
|
1371 |
+
this._destroyUI();
|
1372 |
+
|
1373 |
+
// Form case: destroy all its fields and then destroy stored instance
|
1374 |
+
for (var i = 0; i < this.fields.length; i++) this.fields[i].destroy();
|
1375 |
+
|
1376 |
+
this.$element.removeData('Parsley');
|
1377 |
+
this._trigger('destroy');
|
1378 |
+
},
|
1379 |
+
|
1380 |
+
_refreshFields: function _refreshFields() {
|
1381 |
+
return this.actualizeOptions()._bindFields();
|
1382 |
+
},
|
1383 |
+
|
1384 |
+
_bindFields: function _bindFields() {
|
1385 |
+
var _this8 = this;
|
1386 |
+
|
1387 |
+
var oldFields = this.fields;
|
1388 |
+
|
1389 |
+
this.fields = [];
|
1390 |
+
this.fieldsMappedById = {};
|
1391 |
+
|
1392 |
+
this._withoutReactualizingFormOptions(function () {
|
1393 |
+
_this8.$element.find(_this8.options.inputs).not(_this8.options.excluded).each(function (_, element) {
|
1394 |
+
var fieldInstance = new window.Parsley.Factory(element, {}, _this8);
|
1395 |
+
|
1396 |
+
// Only add valid and not excluded `Field` and `FieldMultiple` children
|
1397 |
+
if (('Field' === fieldInstance.__class__ || 'FieldMultiple' === fieldInstance.__class__) && true !== fieldInstance.options.excluded) {
|
1398 |
+
var uniqueId = fieldInstance.__class__ + '-' + fieldInstance.__id__;
|
1399 |
+
if ('undefined' === typeof _this8.fieldsMappedById[uniqueId]) {
|
1400 |
+
_this8.fieldsMappedById[uniqueId] = fieldInstance;
|
1401 |
+
_this8.fields.push(fieldInstance);
|
1402 |
+
}
|
1403 |
+
}
|
1404 |
+
});
|
1405 |
+
|
1406 |
+
$.each(Utils.difference(oldFields, _this8.fields), function (_, field) {
|
1407 |
+
field.reset();
|
1408 |
+
});
|
1409 |
+
});
|
1410 |
+
return this;
|
1411 |
+
},
|
1412 |
+
|
1413 |
+
// Internal only.
|
1414 |
+
// Looping on a form's fields to do validation or similar
|
1415 |
+
// will trigger reactualizing options on all of them, which
|
1416 |
+
// in turn will reactualize the form's options.
|
1417 |
+
// To avoid calling actualizeOptions so many times on the form
|
1418 |
+
// for nothing, _withoutReactualizingFormOptions temporarily disables
|
1419 |
+
// the method actualizeOptions on this form while `fn` is called.
|
1420 |
+
_withoutReactualizingFormOptions: function _withoutReactualizingFormOptions(fn) {
|
1421 |
+
var oldActualizeOptions = this.actualizeOptions;
|
1422 |
+
this.actualizeOptions = function () {
|
1423 |
+
return this;
|
1424 |
+
};
|
1425 |
+
var result = fn();
|
1426 |
+
this.actualizeOptions = oldActualizeOptions;
|
1427 |
+
return result;
|
1428 |
+
},
|
1429 |
+
|
1430 |
+
// Internal only.
|
1431 |
+
// Shortcut to trigger an event
|
1432 |
+
// Returns true iff event is not interrupted and default not prevented.
|
1433 |
+
_trigger: function _trigger(eventName) {
|
1434 |
+
return this.trigger('form:' + eventName);
|
1435 |
+
}
|
1436 |
+
|
1437 |
+
};
|
1438 |
+
|
1439 |
+
var Constraint = function Constraint(parsleyField, name, requirements, priority, isDomConstraint) {
|
1440 |
+
var validatorSpec = window.Parsley._validatorRegistry.validators[name];
|
1441 |
+
var validator = new Validator(validatorSpec);
|
1442 |
+
priority = priority || parsleyField.options[name + 'Priority'] || validator.priority;
|
1443 |
+
isDomConstraint = true === isDomConstraint;
|
1444 |
+
|
1445 |
+
_extends(this, {
|
1446 |
+
validator: validator,
|
1447 |
+
name: name,
|
1448 |
+
requirements: requirements,
|
1449 |
+
priority: priority,
|
1450 |
+
isDomConstraint: isDomConstraint
|
1451 |
+
});
|
1452 |
+
this._parseRequirements(parsleyField.options);
|
1453 |
+
};
|
1454 |
+
|
1455 |
+
var capitalize = function capitalize(str) {
|
1456 |
+
var cap = str[0].toUpperCase();
|
1457 |
+
return cap + str.slice(1);
|
1458 |
+
};
|
1459 |
+
|
1460 |
+
Constraint.prototype = {
|
1461 |
+
validate: function validate(value, instance) {
|
1462 |
+
var _validator;
|
1463 |
+
|
1464 |
+
return (_validator = this.validator).validate.apply(_validator, [value].concat(_toConsumableArray(this.requirementList), [instance]));
|
1465 |
+
},
|
1466 |
+
|
1467 |
+
_parseRequirements: function _parseRequirements(options) {
|
1468 |
+
var _this9 = this;
|
1469 |
+
|
1470 |
+
this.requirementList = this.validator.parseRequirements(this.requirements, function (key) {
|
1471 |
+
return options[_this9.name + capitalize(key)];
|
1472 |
+
});
|
1473 |
+
}
|
1474 |
+
};
|
1475 |
+
|
1476 |
+
var Field = function Field(field, domOptions, options, parsleyFormInstance) {
|
1477 |
+
this.__class__ = 'Field';
|
1478 |
+
|
1479 |
+
this.element = field;
|
1480 |
+
this.$element = $(field);
|
1481 |
+
|
1482 |
+
// Set parent if we have one
|
1483 |
+
if ('undefined' !== typeof parsleyFormInstance) {
|
1484 |
+
this.parent = parsleyFormInstance;
|
1485 |
+
}
|
1486 |
+
|
1487 |
+
this.options = options;
|
1488 |
+
this.domOptions = domOptions;
|
1489 |
+
|
1490 |
+
// Initialize some properties
|
1491 |
+
this.constraints = [];
|
1492 |
+
this.constraintsByName = {};
|
1493 |
+
this.validationResult = true;
|
1494 |
+
|
1495 |
+
// Bind constraints
|
1496 |
+
this._bindConstraints();
|
1497 |
+
};
|
1498 |
+
|
1499 |
+
var parsley_field__statusMapping = { pending: null, resolved: true, rejected: false };
|
1500 |
+
|
1501 |
+
Field.prototype = {
|
1502 |
+
// # Public API
|
1503 |
+
// Validate field and trigger some events for mainly `UI`
|
1504 |
+
// @returns `true`, an array of the validators that failed, or
|
1505 |
+
// `null` if validation is not finished. Prefer using whenValidate
|
1506 |
+
validate: function validate(options) {
|
1507 |
+
if (arguments.length >= 1 && !$.isPlainObject(options)) {
|
1508 |
+
Utils.warnOnce('Calling validate on a parsley field without passing arguments as an object is deprecated.');
|
1509 |
+
options = { options: options };
|
1510 |
+
}
|
1511 |
+
var promise = this.whenValidate(options);
|
1512 |
+
if (!promise) // If excluded with `group` option
|
1513 |
+
return true;
|
1514 |
+
switch (promise.state()) {
|
1515 |
+
case 'pending':
|
1516 |
+
return null;
|
1517 |
+
case 'resolved':
|
1518 |
+
return true;
|
1519 |
+
case 'rejected':
|
1520 |
+
return this.validationResult;
|
1521 |
+
}
|
1522 |
+
},
|
1523 |
+
|
1524 |
+
// Validate field and trigger some events for mainly `UI`
|
1525 |
+
// @returns a promise that succeeds only when all validations do
|
1526 |
+
// or `undefined` if field is not in the given `group`.
|
1527 |
+
whenValidate: function whenValidate() {
|
1528 |
+
var _whenValid$always$done$fail$always,
|
1529 |
+
_this10 = this;
|
1530 |
+
|
1531 |
+
var _ref9 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
|
1532 |
+
|
1533 |
+
var force = _ref9.force;
|
1534 |
+
var group = _ref9.group;
|
1535 |
+
|
1536 |
+
// do not validate a field if not the same as given validation group
|
1537 |
+
this.refresh();
|
1538 |
+
if (group && !this._isInGroup(group)) return;
|
1539 |
+
|
1540 |
+
this.value = this.getValue();
|
1541 |
+
|
1542 |
+
// Field Validate event. `this.value` could be altered for custom needs
|
1543 |
+
this._trigger('validate');
|
1544 |
+
|
1545 |
+
return (_whenValid$always$done$fail$always = this.whenValid({ force: force, value: this.value, _refreshed: true }).always(function () {
|
1546 |
+
_this10._reflowUI();
|
1547 |
+
}).done(function () {
|
1548 |
+
_this10._trigger('success');
|
1549 |
+
}).fail(function () {
|
1550 |
+
_this10._trigger('error');
|
1551 |
+
}).always(function () {
|
1552 |
+
_this10._trigger('validated');
|
1553 |
+
})).pipe.apply(_whenValid$always$done$fail$always, _toConsumableArray(this._pipeAccordingToValidationResult()));
|
1554 |
+
},
|
1555 |
+
|
1556 |
+
hasConstraints: function hasConstraints() {
|
1557 |
+
return 0 !== this.constraints.length;
|
1558 |
+
},
|
1559 |
+
|
1560 |
+
// An empty optional field does not need validation
|
1561 |
+
needsValidation: function needsValidation(value) {
|
1562 |
+
if ('undefined' === typeof value) value = this.getValue();
|
1563 |
+
|
1564 |
+
// If a field is empty and not required, it is valid
|
1565 |
+
// Except if `data-parsley-validate-if-empty` explicitely added, useful for some custom validators
|
1566 |
+
if (!value.length && !this._isRequired() && 'undefined' === typeof this.options.validateIfEmpty) return false;
|
1567 |
+
|
1568 |
+
return true;
|
1569 |
+
},
|
1570 |
+
|
1571 |
+
_isInGroup: function _isInGroup(group) {
|
1572 |
+
if (Array.isArray(this.options.group)) return -1 !== $.inArray(group, this.options.group);
|
1573 |
+
return this.options.group === group;
|
1574 |
+
},
|
1575 |
+
|
1576 |
+
// Just validate field. Do not trigger any event.
|
1577 |
+
// Returns `true` iff all constraints pass, `false` if there are failures,
|
1578 |
+
// or `null` if the result can not be determined yet (depends on a promise)
|
1579 |
+
// See also `whenValid`.
|
1580 |
+
isValid: function isValid(options) {
|
1581 |
+
if (arguments.length >= 1 && !$.isPlainObject(options)) {
|
1582 |
+
Utils.warnOnce('Calling isValid on a parsley field without passing arguments as an object is deprecated.');
|
1583 |
+
|
1584 |
+
var _arguments3 = _slice.call(arguments);
|
1585 |
+
|
1586 |
+
var force = _arguments3[0];
|
1587 |
+
var value = _arguments3[1];
|
1588 |
+
|
1589 |
+
options = { force: force, value: value };
|
1590 |
+
}
|
1591 |
+
var promise = this.whenValid(options);
|
1592 |
+
if (!promise) // Excluded via `group`
|
1593 |
+
return true;
|
1594 |
+
return parsley_field__statusMapping[promise.state()];
|
1595 |
+
},
|
1596 |
+
|
1597 |
+
// Just validate field. Do not trigger any event.
|
1598 |
+
// @returns a promise that succeeds only when all validations do
|
1599 |
+
// or `undefined` if the field is not in the given `group`.
|
1600 |
+
// The argument `force` will force validation of empty fields.
|
1601 |
+
// If a `value` is given, it will be validated instead of the value of the input.
|
1602 |
+
whenValid: function whenValid() {
|
1603 |
+
var _this11 = this;
|
1604 |
+
|
1605 |
+
var _ref10 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
|
1606 |
+
|
1607 |
+
var _ref10$force = _ref10.force;
|
1608 |
+
var force = _ref10$force === undefined ? false : _ref10$force;
|
1609 |
+
var value = _ref10.value;
|
1610 |
+
var group = _ref10.group;
|
1611 |
+
var _refreshed = _ref10._refreshed;
|
1612 |
+
|
1613 |
+
// Recompute options and rebind constraints to have latest changes
|
1614 |
+
if (!_refreshed) this.refresh();
|
1615 |
+
// do not validate a field if not the same as given validation group
|
1616 |
+
if (group && !this._isInGroup(group)) return;
|
1617 |
+
|
1618 |
+
this.validationResult = true;
|
1619 |
+
|
1620 |
+
// A field without constraint is valid
|
1621 |
+
if (!this.hasConstraints()) return $.when();
|
1622 |
+
|
1623 |
+
// Value could be passed as argument, needed to add more power to 'field:validate'
|
1624 |
+
if ('undefined' === typeof value || null === value) value = this.getValue();
|
1625 |
+
|
1626 |
+
if (!this.needsValidation(value) && true !== force) return $.when();
|
1627 |
+
|
1628 |
+
var groupedConstraints = this._getGroupedConstraints();
|
1629 |
+
var promises = [];
|
1630 |
+
$.each(groupedConstraints, function (_, constraints) {
|
1631 |
+
// Process one group of constraints at a time, we validate the constraints
|
1632 |
+
// and combine the promises together.
|
1633 |
+
var promise = Utils.all($.map(constraints, function (constraint) {
|
1634 |
+
return _this11._validateConstraint(value, constraint);
|
1635 |
+
}));
|
1636 |
+
promises.push(promise);
|
1637 |
+
if (promise.state() === 'rejected') return false; // Interrupt processing if a group has already failed
|
1638 |
+
});
|
1639 |
+
return Utils.all(promises);
|
1640 |
+
},
|
1641 |
+
|
1642 |
+
// @returns a promise
|
1643 |
+
_validateConstraint: function _validateConstraint(value, constraint) {
|
1644 |
+
var _this12 = this;
|
1645 |
+
|
1646 |
+
var result = constraint.validate(value, this);
|
1647 |
+
// Map false to a failed promise
|
1648 |
+
if (false === result) result = $.Deferred().reject();
|
1649 |
+
// Make sure we return a promise and that we record failures
|
1650 |
+
return Utils.all([result]).fail(function (errorMessage) {
|
1651 |
+
if (!(_this12.validationResult instanceof Array)) _this12.validationResult = [];
|
1652 |
+
_this12.validationResult.push({
|
1653 |
+
assert: constraint,
|
1654 |
+
errorMessage: 'string' === typeof errorMessage && errorMessage
|
1655 |
+
});
|
1656 |
+
});
|
1657 |
+
},
|
1658 |
+
|
1659 |
+
// @returns Parsley field computed value that could be overrided or configured in DOM
|
1660 |
+
getValue: function getValue() {
|
1661 |
+
var value;
|
1662 |
+
|
1663 |
+
// Value could be overriden in DOM or with explicit options
|
1664 |
+
if ('function' === typeof this.options.value) value = this.options.value(this);else if ('undefined' !== typeof this.options.value) value = this.options.value;else value = this.$element.val();
|
1665 |
+
|
1666 |
+
// Handle wrong DOM or configurations
|
1667 |
+
if ('undefined' === typeof value || null === value) return '';
|
1668 |
+
|
1669 |
+
return this._handleWhitespace(value);
|
1670 |
+
},
|
1671 |
+
|
1672 |
+
// Reset UI
|
1673 |
+
reset: function reset() {
|
1674 |
+
this._resetUI();
|
1675 |
+
return this._trigger('reset');
|
1676 |
+
},
|
1677 |
+
|
1678 |
+
// Destroy Parsley instance (+ UI)
|
1679 |
+
destroy: function destroy() {
|
1680 |
+
// Field case: emit destroy event to clean UI and then destroy stored instance
|
1681 |
+
this._destroyUI();
|
1682 |
+
this.$element.removeData('Parsley');
|
1683 |
+
this.$element.removeData('FieldMultiple');
|
1684 |
+
this._trigger('destroy');
|
1685 |
+
},
|
1686 |
+
|
1687 |
+
// Actualize options and rebind constraints
|
1688 |
+
refresh: function refresh() {
|
1689 |
+
this._refreshConstraints();
|
1690 |
+
return this;
|
1691 |
+
},
|
1692 |
+
|
1693 |
+
_refreshConstraints: function _refreshConstraints() {
|
1694 |
+
return this.actualizeOptions()._bindConstraints();
|
1695 |
+
},
|
1696 |
+
|
1697 |
+
refreshConstraints: function refreshConstraints() {
|
1698 |
+
Utils.warnOnce("Parsley's refreshConstraints is deprecated. Please use refresh");
|
1699 |
+
return this.refresh();
|
1700 |
+
},
|
1701 |
+
|
1702 |
+
/**
|
1703 |
+
* Add a new constraint to a field
|
1704 |
+
*
|
1705 |
+
* @param {String} name
|
1706 |
+
* @param {Mixed} requirements optional
|
1707 |
+
* @param {Number} priority optional
|
1708 |
+
* @param {Boolean} isDomConstraint optional
|
1709 |
+
*/
|
1710 |
+
addConstraint: function addConstraint(name, requirements, priority, isDomConstraint) {
|
1711 |
+
|
1712 |
+
if (window.Parsley._validatorRegistry.validators[name]) {
|
1713 |
+
var constraint = new Constraint(this, name, requirements, priority, isDomConstraint);
|
1714 |
+
|
1715 |
+
// if constraint already exist, delete it and push new version
|
1716 |
+
if ('undefined' !== this.constraintsByName[constraint.name]) this.removeConstraint(constraint.name);
|
1717 |
+
|
1718 |
+
this.constraints.push(constraint);
|
1719 |
+
this.constraintsByName[constraint.name] = constraint;
|
1720 |
+
}
|
1721 |
+
|
1722 |
+
return this;
|
1723 |
+
},
|
1724 |
+
|
1725 |
+
// Remove a constraint
|
1726 |
+
removeConstraint: function removeConstraint(name) {
|
1727 |
+
for (var i = 0; i < this.constraints.length; i++) if (name === this.constraints[i].name) {
|
1728 |
+
this.constraints.splice(i, 1);
|
1729 |
+
break;
|
1730 |
+
}
|
1731 |
+
delete this.constraintsByName[name];
|
1732 |
+
return this;
|
1733 |
+
},
|
1734 |
+
|
1735 |
+
// Update a constraint (Remove + re-add)
|
1736 |
+
updateConstraint: function updateConstraint(name, parameters, priority) {
|
1737 |
+
return this.removeConstraint(name).addConstraint(name, parameters, priority);
|
1738 |
+
},
|
1739 |
+
|
1740 |
+
// # Internals
|
1741 |
+
|
1742 |
+
// Internal only.
|
1743 |
+
// Bind constraints from config + options + DOM
|
1744 |
+
_bindConstraints: function _bindConstraints() {
|
1745 |
+
var constraints = [];
|
1746 |
+
var constraintsByName = {};
|
1747 |
+
|
1748 |
+
// clean all existing DOM constraints to only keep javascript user constraints
|
1749 |
+
for (var i = 0; i < this.constraints.length; i++) if (false === this.constraints[i].isDomConstraint) {
|
1750 |
+
constraints.push(this.constraints[i]);
|
1751 |
+
constraintsByName[this.constraints[i].name] = this.constraints[i];
|
1752 |
+
}
|
1753 |
+
|
1754 |
+
this.constraints = constraints;
|
1755 |
+
this.constraintsByName = constraintsByName;
|
1756 |
+
|
1757 |
+
// then re-add Parsley DOM-API constraints
|
1758 |
+
for (var name in this.options) this.addConstraint(name, this.options[name], undefined, true);
|
1759 |
+
|
1760 |
+
// finally, bind special HTML5 constraints
|
1761 |
+
return this._bindHtml5Constraints();
|
1762 |
+
},
|
1763 |
+
|
1764 |
+
// Internal only.
|
1765 |
+
// Bind specific HTML5 constraints to be HTML5 compliant
|
1766 |
+
_bindHtml5Constraints: function _bindHtml5Constraints() {
|
1767 |
+
// html5 required
|
1768 |
+
if (null !== this.element.getAttribute('required')) this.addConstraint('required', true, undefined, true);
|
1769 |
+
|
1770 |
+
// html5 pattern
|
1771 |
+
if (null !== this.element.getAttribute('pattern')) this.addConstraint('pattern', this.element.getAttribute('pattern'), undefined, true);
|
1772 |
+
|
1773 |
+
// range
|
1774 |
+
var min = this.element.getAttribute('min');
|
1775 |
+
var max = this.element.getAttribute('max');
|
1776 |
+
if (null !== min && null !== max) this.addConstraint('range', [min, max], undefined, true);
|
1777 |
+
|
1778 |
+
// HTML5 min
|
1779 |
+
else if (null !== min) this.addConstraint('min', min, undefined, true);
|
1780 |
+
|
1781 |
+
// HTML5 max
|
1782 |
+
else if (null !== max) this.addConstraint('max', max, undefined, true);
|
1783 |
+
|
1784 |
+
// length
|
1785 |
+
if (null !== this.element.getAttribute('minlength') && null !== this.element.getAttribute('maxlength')) this.addConstraint('length', [this.element.getAttribute('minlength'), this.element.getAttribute('maxlength')], undefined, true);
|
1786 |
+
|
1787 |
+
// HTML5 minlength
|
1788 |
+
else if (null !== this.element.getAttribute('minlength')) this.addConstraint('minlength', this.element.getAttribute('minlength'), undefined, true);
|
1789 |
+
|
1790 |
+
// HTML5 maxlength
|
1791 |
+
else if (null !== this.element.getAttribute('maxlength')) this.addConstraint('maxlength', this.element.getAttribute('maxlength'), undefined, true);
|
1792 |
+
|
1793 |
+
// html5 types
|
1794 |
+
var type = Utils.getType(this.element);
|
1795 |
+
|
1796 |
+
// Small special case here for HTML5 number: integer validator if step attribute is undefined or an integer value, number otherwise
|
1797 |
+
if ('number' === type) {
|
1798 |
+
return this.addConstraint('type', ['number', {
|
1799 |
+
step: this.element.getAttribute('step') || '1',
|
1800 |
+
base: min || this.element.getAttribute('value')
|
1801 |
+
}], undefined, true);
|
1802 |
+
// Regular other HTML5 supported types
|
1803 |
+
} else if (/^(email|url|range|date)$/i.test(type)) {
|
1804 |
+
return this.addConstraint('type', type, undefined, true);
|
1805 |
+
}
|
1806 |
+
return this;
|
1807 |
+
},
|
1808 |
+
|
1809 |
+
// Internal only.
|
1810 |
+
// Field is required if have required constraint without `false` value
|
1811 |
+
_isRequired: function _isRequired() {
|
1812 |
+
if ('undefined' === typeof this.constraintsByName.required) return false;
|
1813 |
+
|
1814 |
+
return false !== this.constraintsByName.required.requirements;
|
1815 |
+
},
|
1816 |
+
|
1817 |
+
// Internal only.
|
1818 |
+
// Shortcut to trigger an event
|
1819 |
+
_trigger: function _trigger(eventName) {
|
1820 |
+
return this.trigger('field:' + eventName);
|
1821 |
+
},
|
1822 |
+
|
1823 |
+
// Internal only
|
1824 |
+
// Handles whitespace in a value
|
1825 |
+
// Use `data-parsley-whitespace="squish"` to auto squish input value
|
1826 |
+
// Use `data-parsley-whitespace="trim"` to auto trim input value
|
1827 |
+
_handleWhitespace: function _handleWhitespace(value) {
|
1828 |
+
if (true === this.options.trimValue) Utils.warnOnce('data-parsley-trim-value="true" is deprecated, please use data-parsley-whitespace="trim"');
|
1829 |
+
|
1830 |
+
if ('squish' === this.options.whitespace) value = value.replace(/\s{2,}/g, ' ');
|
1831 |
+
|
1832 |
+
if ('trim' === this.options.whitespace || 'squish' === this.options.whitespace || true === this.options.trimValue) value = Utils.trimString(value);
|
1833 |
+
|
1834 |
+
return value;
|
1835 |
+
},
|
1836 |
+
|
1837 |
+
_isDateInput: function _isDateInput() {
|
1838 |
+
var c = this.constraintsByName.type;
|
1839 |
+
return c && c.requirements === 'date';
|
1840 |
+
},
|
1841 |
+
|
1842 |
+
// Internal only.
|
1843 |
+
// Returns the constraints, grouped by descending priority.
|
1844 |
+
// The result is thus an array of arrays of constraints.
|
1845 |
+
_getGroupedConstraints: function _getGroupedConstraints() {
|
1846 |
+
if (false === this.options.priorityEnabled) return [this.constraints];
|
1847 |
+
|
1848 |
+
var groupedConstraints = [];
|
1849 |
+
var index = {};
|
1850 |
+
|
1851 |
+
// Create array unique of priorities
|
1852 |
+
for (var i = 0; i < this.constraints.length; i++) {
|
1853 |
+
var p = this.constraints[i].priority;
|
1854 |
+
if (!index[p]) groupedConstraints.push(index[p] = []);
|
1855 |
+
index[p].push(this.constraints[i]);
|
1856 |
+
}
|
1857 |
+
// Sort them by priority DESC
|
1858 |
+
groupedConstraints.sort(function (a, b) {
|
1859 |
+
return b[0].priority - a[0].priority;
|
1860 |
+
});
|
1861 |
+
|
1862 |
+
return groupedConstraints;
|
1863 |
+
}
|
1864 |
+
|
1865 |
+
};
|
1866 |
+
|
1867 |
+
var parsley_field = Field;
|
1868 |
+
|
1869 |
+
var Multiple = function Multiple() {
|
1870 |
+
this.__class__ = 'FieldMultiple';
|
1871 |
+
};
|
1872 |
+
|
1873 |
+
Multiple.prototype = {
|
1874 |
+
// Add new `$element` sibling for multiple field
|
1875 |
+
addElement: function addElement($element) {
|
1876 |
+
this.$elements.push($element);
|
1877 |
+
|
1878 |
+
return this;
|
1879 |
+
},
|
1880 |
+
|
1881 |
+
// See `Field._refreshConstraints()`
|
1882 |
+
_refreshConstraints: function _refreshConstraints() {
|
1883 |
+
var fieldConstraints;
|
1884 |
+
|
1885 |
+
this.constraints = [];
|
1886 |
+
|
1887 |
+
// Select multiple special treatment
|
1888 |
+
if (this.element.nodeName === 'SELECT') {
|
1889 |
+
this.actualizeOptions()._bindConstraints();
|
1890 |
+
|
1891 |
+
return this;
|
1892 |
+
}
|
1893 |
+
|
1894 |
+
// Gather all constraints for each input in the multiple group
|
1895 |
+
for (var i = 0; i < this.$elements.length; i++) {
|
1896 |
+
|
1897 |
+
// Check if element have not been dynamically removed since last binding
|
1898 |
+
if (!$('html').has(this.$elements[i]).length) {
|
1899 |
+
this.$elements.splice(i, 1);
|
1900 |
+
continue;
|
1901 |
+
}
|
1902 |
+
|
1903 |
+
fieldConstraints = this.$elements[i].data('FieldMultiple')._refreshConstraints().constraints;
|
1904 |
+
|
1905 |
+
for (var j = 0; j < fieldConstraints.length; j++) this.addConstraint(fieldConstraints[j].name, fieldConstraints[j].requirements, fieldConstraints[j].priority, fieldConstraints[j].isDomConstraint);
|
1906 |
+
}
|
1907 |
+
|
1908 |
+
return this;
|
1909 |
+
},
|
1910 |
+
|
1911 |
+
// See `Field.getValue()`
|
1912 |
+
getValue: function getValue() {
|
1913 |
+
// Value could be overriden in DOM
|
1914 |
+
if ('function' === typeof this.options.value) return this.options.value(this);else if ('undefined' !== typeof this.options.value) return this.options.value;
|
1915 |
+
|
1916 |
+
// Radio input case
|
1917 |
+
if (this.element.nodeName === 'INPUT') {
|
1918 |
+
var type = Utils.getType(this.element);
|
1919 |
+
if (type === 'radio') return this._findRelated().filter(':checked').val() || '';
|
1920 |
+
|
1921 |
+
// checkbox input case
|
1922 |
+
if (type === 'checkbox') {
|
1923 |
+
var values = [];
|
1924 |
+
|
1925 |
+
this._findRelated().filter(':checked').each(function () {
|
1926 |
+
values.push($(this).val());
|
1927 |
+
});
|
1928 |
+
|
1929 |
+
return values;
|
1930 |
+
}
|
1931 |
+
}
|
1932 |
+
|
1933 |
+
// Select multiple case
|
1934 |
+
if (this.element.nodeName === 'SELECT' && null === this.$element.val()) return [];
|
1935 |
+
|
1936 |
+
// Default case that should never happen
|
1937 |
+
return this.$element.val();
|
1938 |
+
},
|
1939 |
+
|
1940 |
+
_init: function _init() {
|
1941 |
+
this.$elements = [this.$element];
|
1942 |
+
|
1943 |
+
return this;
|
1944 |
+
}
|
1945 |
+
};
|
1946 |
+
|
1947 |
+
var Factory = function Factory(element, options, parsleyFormInstance) {
|
1948 |
+
this.element = element;
|
1949 |
+
this.$element = $(element);
|
1950 |
+
|
1951 |
+
// If the element has already been bound, returns its saved Parsley instance
|
1952 |
+
var savedparsleyFormInstance = this.$element.data('Parsley');
|
1953 |
+
if (savedparsleyFormInstance) {
|
1954 |
+
|
1955 |
+
// If the saved instance has been bound without a Form parent and there is one given in this call, add it
|
1956 |
+
if ('undefined' !== typeof parsleyFormInstance && savedparsleyFormInstance.parent === window.Parsley) {
|
1957 |
+
savedparsleyFormInstance.parent = parsleyFormInstance;
|
1958 |
+
savedparsleyFormInstance._resetOptions(savedparsleyFormInstance.options);
|
1959 |
+
}
|
1960 |
+
|
1961 |
+
if ('object' === typeof options) {
|
1962 |
+
_extends(savedparsleyFormInstance.options, options);
|
1963 |
+
}
|
1964 |
+
|
1965 |
+
return savedparsleyFormInstance;
|
1966 |
+
}
|
1967 |
+
|
1968 |
+
// Parsley must be instantiated with a DOM element or jQuery $element
|
1969 |
+
if (!this.$element.length) throw new Error('You must bind Parsley on an existing element.');
|
1970 |
+
|
1971 |
+
if ('undefined' !== typeof parsleyFormInstance && 'Form' !== parsleyFormInstance.__class__) throw new Error('Parent instance must be a Form instance');
|
1972 |
+
|
1973 |
+
this.parent = parsleyFormInstance || window.Parsley;
|
1974 |
+
return this.init(options);
|
1975 |
+
};
|
1976 |
+
|
1977 |
+
Factory.prototype = {
|
1978 |
+
init: function init(options) {
|
1979 |
+
this.__class__ = 'Parsley';
|
1980 |
+
this.__version__ = '2.8.0';
|
1981 |
+
this.__id__ = Utils.generateID();
|
1982 |
+
|
1983 |
+
// Pre-compute options
|
1984 |
+
this._resetOptions(options);
|
1985 |
+
|
1986 |
+
// A Form instance is obviously a `<form>` element but also every node that is not an input and has the `data-parsley-validate` attribute
|
1987 |
+
if (this.element.nodeName === 'FORM' || Utils.checkAttr(this.element, this.options.namespace, 'validate') && !this.$element.is(this.options.inputs)) return this.bind('parsleyForm');
|
1988 |
+
|
1989 |
+
// Every other element is bound as a `Field` or `FieldMultiple`
|
1990 |
+
return this.isMultiple() ? this.handleMultiple() : this.bind('parsleyField');
|
1991 |
+
},
|
1992 |
+
|
1993 |
+
isMultiple: function isMultiple() {
|
1994 |
+
var type = Utils.getType(this.element);
|
1995 |
+
return type === 'radio' || type === 'checkbox' || this.element.nodeName === 'SELECT' && null !== this.element.getAttribute('multiple');
|
1996 |
+
},
|
1997 |
+
|
1998 |
+
// Multiples fields are a real nightmare :(
|
1999 |
+
// Maybe some refactoring would be appreciated here...
|
2000 |
+
handleMultiple: function handleMultiple() {
|
2001 |
+
var _this13 = this;
|
2002 |
+
|
2003 |
+
var name;
|
2004 |
+
var multiple;
|
2005 |
+
var parsleyMultipleInstance;
|
2006 |
+
|
2007 |
+
// Handle multiple name
|
2008 |
+
this.options.multiple = this.options.multiple || (name = this.element.getAttribute('name')) || this.element.getAttribute('id');
|
2009 |
+
|
2010 |
+
// Special select multiple input
|
2011 |
+
if (this.element.nodeName === 'SELECT' && null !== this.element.getAttribute('multiple')) {
|
2012 |
+
this.options.multiple = this.options.multiple || this.__id__;
|
2013 |
+
return this.bind('parsleyFieldMultiple');
|
2014 |
+
|
2015 |
+
// Else for radio / checkboxes, we need a `name` or `data-parsley-multiple` to properly bind it
|
2016 |
+
} else if (!this.options.multiple) {
|
2017 |
+
Utils.warn('To be bound by Parsley, a radio, a checkbox and a multiple select input must have either a name or a multiple option.', this.$element);
|
2018 |
+
return this;
|
2019 |
+
}
|
2020 |
+
|
2021 |
+
// Remove special chars
|
2022 |
+
this.options.multiple = this.options.multiple.replace(/(:|\.|\[|\]|\{|\}|\$)/g, '');
|
2023 |
+
|
2024 |
+
// Add proper `data-parsley-multiple` to siblings if we have a valid multiple name
|
2025 |
+
if (name) {
|
2026 |
+
$('input[name="' + name + '"]').each(function (i, input) {
|
2027 |
+
var type = Utils.getType(input);
|
2028 |
+
if (type === 'radio' || type === 'checkbox') input.setAttribute(_this13.options.namespace + 'multiple', _this13.options.multiple);
|
2029 |
+
});
|
2030 |
+
}
|
2031 |
+
|
2032 |
+
// Check here if we don't already have a related multiple instance saved
|
2033 |
+
var $previouslyRelated = this._findRelated();
|
2034 |
+
for (var i = 0; i < $previouslyRelated.length; i++) {
|
2035 |
+
parsleyMultipleInstance = $($previouslyRelated.get(i)).data('Parsley');
|
2036 |
+
if ('undefined' !== typeof parsleyMultipleInstance) {
|
2037 |
+
|
2038 |
+
if (!this.$element.data('FieldMultiple')) {
|
2039 |
+
parsleyMultipleInstance.addElement(this.$element);
|
2040 |
+
}
|
2041 |
+
|
2042 |
+
break;
|
2043 |
+
}
|
2044 |
+
}
|
2045 |
+
|
2046 |
+
// Create a secret Field instance for every multiple field. It will be stored in `data('FieldMultiple')`
|
2047 |
+
// And will be useful later to access classic `Field` stuff while being in a `FieldMultiple` instance
|
2048 |
+
this.bind('parsleyField', true);
|
2049 |
+
|
2050 |
+
return parsleyMultipleInstance || this.bind('parsleyFieldMultiple');
|
2051 |
+
},
|
2052 |
+
|
2053 |
+
// Return proper `Form`, `Field` or `FieldMultiple`
|
2054 |
+
bind: function bind(type, doNotStore) {
|
2055 |
+
var parsleyInstance;
|
2056 |
+
|
2057 |
+
switch (type) {
|
2058 |
+
case 'parsleyForm':
|
2059 |
+
parsleyInstance = $.extend(new Form(this.element, this.domOptions, this.options), new Base(), window.ParsleyExtend)._bindFields();
|
2060 |
+
break;
|
2061 |
+
case 'parsleyField':
|
2062 |
+
parsleyInstance = $.extend(new parsley_field(this.element, this.domOptions, this.options, this.parent), new Base(), window.ParsleyExtend);
|
2063 |
+
break;
|
2064 |
+
case 'parsleyFieldMultiple':
|
2065 |
+
parsleyInstance = $.extend(new parsley_field(this.element, this.domOptions, this.options, this.parent), new Multiple(), new Base(), window.ParsleyExtend)._init();
|
2066 |
+
break;
|
2067 |
+
default:
|
2068 |
+
throw new Error(type + 'is not a supported Parsley type');
|
2069 |
+
}
|
2070 |
+
|
2071 |
+
if (this.options.multiple) Utils.setAttr(this.element, this.options.namespace, 'multiple', this.options.multiple);
|
2072 |
+
|
2073 |
+
if ('undefined' !== typeof doNotStore) {
|
2074 |
+
this.$element.data('FieldMultiple', parsleyInstance);
|
2075 |
+
|
2076 |
+
return parsleyInstance;
|
2077 |
+
}
|
2078 |
+
|
2079 |
+
// Store the freshly bound instance in a DOM element for later access using jQuery `data()`
|
2080 |
+
this.$element.data('Parsley', parsleyInstance);
|
2081 |
+
|
2082 |
+
// Tell the world we have a new Form or Field instance!
|
2083 |
+
parsleyInstance._actualizeTriggers();
|
2084 |
+
parsleyInstance._trigger('init');
|
2085 |
+
|
2086 |
+
return parsleyInstance;
|
2087 |
+
}
|
2088 |
+
};
|
2089 |
+
|
2090 |
+
var vernums = $.fn.jquery.split('.');
|
2091 |
+
if (parseInt(vernums[0]) <= 1 && parseInt(vernums[1]) < 8) {
|
2092 |
+
throw "The loaded version of jQuery is too old. Please upgrade to 1.8.x or better.";
|
2093 |
+
}
|
2094 |
+
if (!vernums.forEach) {
|
2095 |
+
Utils.warn('Parsley requires ES5 to run properly. Please include https://github.com/es-shims/es5-shim');
|
2096 |
+
}
|
2097 |
+
// Inherit `on`, `off` & `trigger` to Parsley:
|
2098 |
+
var Parsley = _extends(new Base(), {
|
2099 |
+
element: document,
|
2100 |
+
$element: $(document),
|
2101 |
+
actualizeOptions: null,
|
2102 |
+
_resetOptions: null,
|
2103 |
+
Factory: Factory,
|
2104 |
+
version: '2.8.0'
|
2105 |
+
});
|
2106 |
+
|
2107 |
+
// Supplement Field and Form with Base
|
2108 |
+
// This way, the constructors will have access to those methods
|
2109 |
+
_extends(parsley_field.prototype, UI.Field, Base.prototype);
|
2110 |
+
_extends(Form.prototype, UI.Form, Base.prototype);
|
2111 |
+
// Inherit actualizeOptions and _resetOptions:
|
2112 |
+
_extends(Factory.prototype, Base.prototype);
|
2113 |
+
|
2114 |
+
// ### jQuery API
|
2115 |
+
// `$('.elem').parsley(options)` or `$('.elem').psly(options)`
|
2116 |
+
$.fn.parsley = $.fn.psly = function (options) {
|
2117 |
+
if (this.length > 1) {
|
2118 |
+
var instances = [];
|
2119 |
+
|
2120 |
+
this.each(function () {
|
2121 |
+
instances.push($(this).parsley(options));
|
2122 |
+
});
|
2123 |
+
|
2124 |
+
return instances;
|
2125 |
+
}
|
2126 |
+
|
2127 |
+
// Return undefined if applied to non existing DOM element
|
2128 |
+
if (this.length == 0) {
|
2129 |
+
return;
|
2130 |
+
}
|
2131 |
+
|
2132 |
+
return new Factory(this[0], options);
|
2133 |
+
};
|
2134 |
+
|
2135 |
+
// ### Field and Form extension
|
2136 |
+
// Ensure the extension is now defined if it wasn't previously
|
2137 |
+
if ('undefined' === typeof window.ParsleyExtend) window.ParsleyExtend = {};
|
2138 |
+
|
2139 |
+
// ### Parsley config
|
2140 |
+
// Inherit from ParsleyDefault, and copy over any existing values
|
2141 |
+
Parsley.options = _extends(Utils.objectCreate(Defaults), window.ParsleyConfig);
|
2142 |
+
window.ParsleyConfig = Parsley.options; // Old way of accessing global options
|
2143 |
+
|
2144 |
+
// ### Globals
|
2145 |
+
window.Parsley = window.psly = Parsley;
|
2146 |
+
Parsley.Utils = Utils;
|
2147 |
+
window.ParsleyUtils = {};
|
2148 |
+
$.each(Utils, function (key, value) {
|
2149 |
+
if ('function' === typeof value) {
|
2150 |
+
window.ParsleyUtils[key] = function () {
|
2151 |
+
Utils.warnOnce('Accessing `window.ParsleyUtils` is deprecated. Use `window.Parsley.Utils` instead.');
|
2152 |
+
return Utils[key].apply(Utils, arguments);
|
2153 |
+
};
|
2154 |
+
}
|
2155 |
+
});
|
2156 |
+
|
2157 |
+
// ### Define methods that forward to the registry, and deprecate all access except through window.Parsley
|
2158 |
+
var registry = window.Parsley._validatorRegistry = new ValidatorRegistry(window.ParsleyConfig.validators, window.ParsleyConfig.i18n);
|
2159 |
+
window.ParsleyValidator = {};
|
2160 |
+
$.each('setLocale addCatalog addMessage addMessages getErrorMessage formatMessage addValidator updateValidator removeValidator hasValidator'.split(' '), function (i, method) {
|
2161 |
+
window.Parsley[method] = function () {
|
2162 |
+
return registry[method].apply(registry, arguments);
|
2163 |
+
};
|
2164 |
+
window.ParsleyValidator[method] = function () {
|
2165 |
+
var _window$Parsley;
|
2166 |
+
|
2167 |
+
Utils.warnOnce('Accessing the method \'' + method + '\' through Validator is deprecated. Simply call \'window.Parsley.' + method + '(...)\'');
|
2168 |
+
return (_window$Parsley = window.Parsley)[method].apply(_window$Parsley, arguments);
|
2169 |
+
};
|
2170 |
+
});
|
2171 |
+
|
2172 |
+
// ### UI
|
2173 |
+
// Deprecated global object
|
2174 |
+
window.Parsley.UI = UI;
|
2175 |
+
window.ParsleyUI = {
|
2176 |
+
removeError: function removeError(instance, name, doNotUpdateClass) {
|
2177 |
+
var updateClass = true !== doNotUpdateClass;
|
2178 |
+
Utils.warnOnce('Accessing UI is deprecated. Call \'removeError\' on the instance directly. Please comment in issue 1073 as to your need to call this method.');
|
2179 |
+
return instance.removeError(name, { updateClass: updateClass });
|
2180 |
+
},
|
2181 |
+
getErrorsMessages: function getErrorsMessages(instance) {
|
2182 |
+
Utils.warnOnce('Accessing UI is deprecated. Call \'getErrorsMessages\' on the instance directly.');
|
2183 |
+
return instance.getErrorsMessages();
|
2184 |
+
}
|
2185 |
+
};
|
2186 |
+
$.each('addError updateError'.split(' '), function (i, method) {
|
2187 |
+
window.ParsleyUI[method] = function (instance, name, message, assert, doNotUpdateClass) {
|
2188 |
+
var updateClass = true !== doNotUpdateClass;
|
2189 |
+
Utils.warnOnce('Accessing UI is deprecated. Call \'' + method + '\' on the instance directly. Please comment in issue 1073 as to your need to call this method.');
|
2190 |
+
return instance[method](name, { message: message, assert: assert, updateClass: updateClass });
|
2191 |
+
};
|
2192 |
+
});
|
2193 |
+
|
2194 |
+
// ### PARSLEY auto-binding
|
2195 |
+
// Prevent it by setting `ParsleyConfig.autoBind` to `false`
|
2196 |
+
if (false !== window.ParsleyConfig.autoBind) {
|
2197 |
+
$(function () {
|
2198 |
+
// Works only on `data-parsley-validate`.
|
2199 |
+
if ($('[data-parsley-validate]').length) $('[data-parsley-validate]').parsley();
|
2200 |
+
});
|
2201 |
+
}
|
2202 |
+
|
2203 |
+
var o = $({});
|
2204 |
+
var deprecated = function deprecated() {
|
2205 |
+
Utils.warnOnce("Parsley's pubsub module is deprecated; use the 'on' and 'off' methods on parsley instances or window.Parsley");
|
2206 |
+
};
|
2207 |
+
|
2208 |
+
// Returns an event handler that calls `fn` with the arguments it expects
|
2209 |
+
function adapt(fn, context) {
|
2210 |
+
// Store to allow unbinding
|
2211 |
+
if (!fn.parsleyAdaptedCallback) {
|
2212 |
+
fn.parsleyAdaptedCallback = function () {
|
2213 |
+
var args = Array.prototype.slice.call(arguments, 0);
|
2214 |
+
args.unshift(this);
|
2215 |
+
fn.apply(context || o, args);
|
2216 |
+
};
|
2217 |
+
}
|
2218 |
+
return fn.parsleyAdaptedCallback;
|
2219 |
+
}
|
2220 |
+
|
2221 |
+
var eventPrefix = 'parsley:';
|
2222 |
+
// Converts 'parsley:form:validate' into 'form:validate'
|
2223 |
+
function eventName(name) {
|
2224 |
+
if (name.lastIndexOf(eventPrefix, 0) === 0) return name.substr(eventPrefix.length);
|
2225 |
+
return name;
|
2226 |
+
}
|
2227 |
+
|
2228 |
+
// $.listen is deprecated. Use Parsley.on instead.
|
2229 |
+
$.listen = function (name, callback) {
|
2230 |
+
var context;
|
2231 |
+
deprecated();
|
2232 |
+
if ('object' === typeof arguments[1] && 'function' === typeof arguments[2]) {
|
2233 |
+
context = arguments[1];
|
2234 |
+
callback = arguments[2];
|
2235 |
+
}
|
2236 |
+
|
2237 |
+
if ('function' !== typeof callback) throw new Error('Wrong parameters');
|
2238 |
+
|
2239 |
+
window.Parsley.on(eventName(name), adapt(callback, context));
|
2240 |
+
};
|
2241 |
+
|
2242 |
+
$.listenTo = function (instance, name, fn) {
|
2243 |
+
deprecated();
|
2244 |
+
if (!(instance instanceof parsley_field) && !(instance instanceof Form)) throw new Error('Must give Parsley instance');
|
2245 |
+
|
2246 |
+
if ('string' !== typeof name || 'function' !== typeof fn) throw new Error('Wrong parameters');
|
2247 |
+
|
2248 |
+
instance.on(eventName(name), adapt(fn));
|
2249 |
+
};
|
2250 |
+
|
2251 |
+
$.unsubscribe = function (name, fn) {
|
2252 |
+
deprecated();
|
2253 |
+
if ('string' !== typeof name || 'function' !== typeof fn) throw new Error('Wrong arguments');
|
2254 |
+
window.Parsley.off(eventName(name), fn.parsleyAdaptedCallback);
|
2255 |
+
};
|
2256 |
+
|
2257 |
+
$.unsubscribeTo = function (instance, name) {
|
2258 |
+
deprecated();
|
2259 |
+
if (!(instance instanceof parsley_field) && !(instance instanceof Form)) throw new Error('Must give Parsley instance');
|
2260 |
+
instance.off(eventName(name));
|
2261 |
+
};
|
2262 |
+
|
2263 |
+
$.unsubscribeAll = function (name) {
|
2264 |
+
deprecated();
|
2265 |
+
window.Parsley.off(eventName(name));
|
2266 |
+
$('form,input,textarea,select').each(function () {
|
2267 |
+
var instance = $(this).data('Parsley');
|
2268 |
+
if (instance) {
|
2269 |
+
instance.off(eventName(name));
|
2270 |
+
}
|
2271 |
+
});
|
2272 |
+
};
|
2273 |
+
|
2274 |
+
// $.emit is deprecated. Use jQuery events instead.
|
2275 |
+
$.emit = function (name, instance) {
|
2276 |
+
var _instance;
|
2277 |
+
|
2278 |
+
deprecated();
|
2279 |
+
var instanceGiven = instance instanceof parsley_field || instance instanceof Form;
|
2280 |
+
var args = Array.prototype.slice.call(arguments, instanceGiven ? 2 : 1);
|
2281 |
+
args.unshift(eventName(name));
|
2282 |
+
if (!instanceGiven) {
|
2283 |
+
instance = window.Parsley;
|
2284 |
+
}
|
2285 |
+
(_instance = instance).trigger.apply(_instance, _toConsumableArray(args));
|
2286 |
+
};
|
2287 |
+
|
2288 |
+
var pubsub = {};
|
2289 |
+
|
2290 |
+
$.extend(true, Parsley, {
|
2291 |
+
asyncValidators: {
|
2292 |
+
'default': {
|
2293 |
+
fn: function fn(xhr) {
|
2294 |
+
// By default, only status 2xx are deemed successful.
|
2295 |
+
// Note: we use status instead of state() because responses with status 200
|
2296 |
+
// but invalid messages (e.g. an empty body for content type set to JSON) will
|
2297 |
+
// result in state() === 'rejected'.
|
2298 |
+
return xhr.status >= 200 && xhr.status < 300;
|
2299 |
+
},
|
2300 |
+
url: false
|
2301 |
+
},
|
2302 |
+
reverse: {
|
2303 |
+
fn: function fn(xhr) {
|
2304 |
+
// If reverse option is set, a failing ajax request is considered successful
|
2305 |
+
return xhr.status < 200 || xhr.status >= 300;
|
2306 |
+
},
|
2307 |
+
url: false
|
2308 |
+
}
|
2309 |
+
},
|
2310 |
+
|
2311 |
+
addAsyncValidator: function addAsyncValidator(name, fn, url, options) {
|
2312 |
+
Parsley.asyncValidators[name] = {
|
2313 |
+
fn: fn,
|
2314 |
+
url: url || false,
|
2315 |
+
options: options || {}
|
2316 |
+
};
|
2317 |
+
|
2318 |
+
return this;
|
2319 |
+
}
|
2320 |
+
|
2321 |
+
});
|
2322 |
+
|
2323 |
+
Parsley.addValidator('remote', {
|
2324 |
+
requirementType: {
|
2325 |
+
'': 'string',
|
2326 |
+
'validator': 'string',
|
2327 |
+
'reverse': 'boolean',
|
2328 |
+
'options': 'object'
|
2329 |
+
},
|
2330 |
+
|
2331 |
+
validateString: function validateString(value, url, options, instance) {
|
2332 |
+
var data = {};
|
2333 |
+
var ajaxOptions;
|
2334 |
+
var csr;
|
2335 |
+
var validator = options.validator || (true === options.reverse ? 'reverse' : 'default');
|
2336 |
+
|
2337 |
+
if ('undefined' === typeof Parsley.asyncValidators[validator]) throw new Error('Calling an undefined async validator: `' + validator + '`');
|
2338 |
+
|
2339 |
+
url = Parsley.asyncValidators[validator].url || url;
|
2340 |
+
|
2341 |
+
// Fill current value
|
2342 |
+
if (url.indexOf('{value}') > -1) {
|
2343 |
+
url = url.replace('{value}', encodeURIComponent(value));
|
2344 |
+
} else {
|
2345 |
+
data[instance.element.getAttribute('name') || instance.element.getAttribute('id')] = value;
|
2346 |
+
}
|
2347 |
+
|
2348 |
+
// Merge options passed in from the function with the ones in the attribute
|
2349 |
+
var remoteOptions = $.extend(true, options.options || {}, Parsley.asyncValidators[validator].options);
|
2350 |
+
|
2351 |
+
// All `$.ajax(options)` could be overridden or extended directly from DOM in `data-parsley-remote-options`
|
2352 |
+
ajaxOptions = $.extend(true, {}, {
|
2353 |
+
url: url,
|
2354 |
+
data: data,
|
2355 |
+
type: 'GET'
|
2356 |
+
}, remoteOptions);
|
2357 |
+
|
2358 |
+
// Generate store key based on ajax options
|
2359 |
+
instance.trigger('field:ajaxoptions', instance, ajaxOptions);
|
2360 |
+
|
2361 |
+
csr = $.param(ajaxOptions);
|
2362 |
+
|
2363 |
+
// Initialise querry cache
|
2364 |
+
if ('undefined' === typeof Parsley._remoteCache) Parsley._remoteCache = {};
|
2365 |
+
|
2366 |
+
// Try to retrieve stored xhr
|
2367 |
+
var xhr = Parsley._remoteCache[csr] = Parsley._remoteCache[csr] || $.ajax(ajaxOptions);
|
2368 |
+
|
2369 |
+
var handleXhr = function handleXhr() {
|
2370 |
+
var result = Parsley.asyncValidators[validator].fn.call(instance, xhr, url, options);
|
2371 |
+
if (!result) // Map falsy results to rejected promise
|
2372 |
+
result = $.Deferred().reject();
|
2373 |
+
return $.when(result);
|
2374 |
+
};
|
2375 |
+
|
2376 |
+
return xhr.then(handleXhr, handleXhr);
|
2377 |
+
},
|
2378 |
+
|
2379 |
+
priority: -1
|
2380 |
+
});
|
2381 |
+
|
2382 |
+
Parsley.on('form:submit', function () {
|
2383 |
+
Parsley._remoteCache = {};
|
2384 |
+
});
|
2385 |
+
|
2386 |
+
Base.prototype.addAsyncValidator = function () {
|
2387 |
+
Utils.warnOnce('Accessing the method `addAsyncValidator` through an instance is deprecated. Simply call `Parsley.addAsyncValidator(...)`');
|
2388 |
+
return Parsley.addAsyncValidator.apply(Parsley, arguments);
|
2389 |
+
};
|
2390 |
+
|
2391 |
+
// This is included with the Parsley library itself,
|
2392 |
+
// thus there is no use in adding it to your project.
|
2393 |
+
Parsley.addMessages('en', {
|
2394 |
+
defaultMessage: "This value seems to be invalid.",
|
2395 |
+
type: {
|
2396 |
+
email: "This value should be a valid email.",
|
2397 |
+
url: "This value should be a valid url.",
|
2398 |
+
number: "This value should be a valid number.",
|
2399 |
+
integer: "This value should be a valid integer.",
|
2400 |
+
digits: "This value should be digits.",
|
2401 |
+
alphanum: "This value should be alphanumeric."
|
2402 |
+
},
|
2403 |
+
notblank: "This value should not be blank.",
|
2404 |
+
required: "This value is required.",
|
2405 |
+
pattern: "This value seems to be invalid.",
|
2406 |
+
min: "This value should be greater than or equal to %s.",
|
2407 |
+
max: "This value should be lower than or equal to %s.",
|
2408 |
+
range: "This value should be between %s and %s.",
|
2409 |
+
minlength: "This value is too short. It should have %s characters or more.",
|
2410 |
+
maxlength: "This value is too long. It should have %s characters or fewer.",
|
2411 |
+
length: "This value length is invalid. It should be between %s and %s characters long.",
|
2412 |
+
mincheck: "You must select at least %s choices.",
|
2413 |
+
maxcheck: "You must select %s choices or fewer.",
|
2414 |
+
check: "You must select between %s and %s choices.",
|
2415 |
+
equalto: "This value should be the same."
|
2416 |
+
});
|
2417 |
+
|
2418 |
+
Parsley.setLocale('en');
|
2419 |
+
|
2420 |
+
/**
|
2421 |
+
* inputevent - Alleviate browser bugs for input events
|
2422 |
+
* https://github.com/marcandre/inputevent
|
2423 |
+
* @version v0.0.3 - (built Thu, Apr 14th 2016, 5:58 pm)
|
2424 |
+
* @author Marc-Andre Lafortune <github@marc-andre.ca>
|
2425 |
+
* @license MIT
|
2426 |
+
*/
|
2427 |
+
|
2428 |
+
function InputEvent() {
|
2429 |
+
var _this14 = this;
|
2430 |
+
|
2431 |
+
var globals = window || global;
|
2432 |
+
|
2433 |
+
// Slightly odd way construct our object. This way methods are force bound.
|
2434 |
+
// Used to test for duplicate library.
|
2435 |
+
_extends(this, {
|
2436 |
+
|
2437 |
+
// For browsers that do not support isTrusted, assumes event is native.
|
2438 |
+
isNative
|