Permalink
Switch branches/tags
Stoyan0v-feature/468_add-schema-org-website-markup develop feature-/547_Validate-URIs feature/add-keywords-screen-sagas feature/add-keywords-screen feature/add-woocommerce-plugin-filters feature/fix-failing-tests feature/120_changing-entity-type-from-wp-backend-creates-an-inconsistent-situation feature/125_personalize_the_entity_path feature/212_Adding-support-for-the-Accelerated-Mobile-Pages-(AMP)-on-WordLift-Entity-Pages feature/230_download_your_data_from_wordlift feature/278-when-creating-a-new-entity-the-duplicate-warning-appears-for-entity-that-have-been-trashed feature.291_The-calendar-for-startDate-and-endDate-of-an-event-cannot-be-used-for-historical-events feature/296_cant-create-new-entity-over-existing-annotation feature/305_Entity-Types'-widget-should-be-flat feature/305_entity-types-should-be-flat feature/306-entities-from-the-internal-vocabulary-are-not-properly-detected feature/310_favour-jsonld-in-place-of-microdata feature/323_Content-dynamically-posted-should-follow-both-a-chronological-or-a-relevancy-order feature/339_improving_the_import_export_of_the_user_vocabulary feature/342_data_migration feature/343_disable_wikipedia_images feature/345_entity-suggested-when-analyzing-the-content-entity-itself feature/346_add_two_properties feature/349-remove-all-unsupported-languages-from-the-settings feature/352_improve-design-of-the-timeline-widget feature/354_improve-the-navigator-widget-by-adding-links-to-the-images feature/355_Creating-a-Tag-Like-Widget-for-articles feature/369_remove-the-unused-indepth-file feature/370_upgrade-timelinejs-to-3x feature/371_extending-the-list-of-schema-article-properties feature/372_the-layout-of-the-navigator-messes-up-with-long-entity-titles feature/376_Enable-revisions-for-entities feature/383_chord-overlapping-issue feature/389_remove-jetpacks-related-posts-from-entity-pages feature/395-author-missing-from-entities-edit-pages feature/397-review-wordlifts-setup-process feature/398_SEO-improvement--providing-control-over-title-and-description-of-WordLift-Archive-pages- feature/403_Adding-legalName-for-Organization-and-LocalBusiness feature/404_navigator-widget feature/408-remove-the-caching-module feature/412_add-a-toggle-to-disable-wordlift-analysis-on-certain-pages-posts_switch feature/412_add-a-toggle-to-disable-wordlift-analysis-on-certain-pages-posts feature/417-integrate-e2e-tests-in-wordlift feature/418_Do-not-allow-activating-WordLift-on-incompatible-WP's-versions feature/425-move-the-traslator-server-side feature/426_related-articles-needs-to-be-limited-and-or-paginated feature/427_Add-Publisher-field-to-WordLift-Setting-page feature/432_fix-empty-span-issue feature/437_some-found-entities-lack-the-related-text-annotation feature/438_autocomplete-fails-in-metaboxes feature/440_text-annotations-are-too-invasive feature/442_Enable-WordPress-Category-to-Organise-WordLift-Entities feature/446_return-value-of-wl_schema_get_value-not-always-check-to-not-be-null feature/447_Enqueue-of-styles-and-JS-should-be-more-selective-and-limited-to-content-editing-screens feature/447_enqueue-of-styles-and-js-should-be-more-selective feature/451_improve-schema-article-markup feature/453_Need-to-show-alert-and-have-recovery-plan-when-setting/activation-fail-to-get-dataset-uri feature/457_When-the-plugin-is-installed-in-a-directory-not-named--wordlift--initializaton-hook-ignored feature/467_manually-select-an-entity feature/469_chord-rendering-problem-on-firefox feature/477_preserve-alternative-labels feature/481_Improve-authors feature/482_Global-timeline-doesn't-include-events-bound-to-pages feature/484_Check-compatibility-with-WordPress-Multisite-configurations feature/485_add-the-possibility-to-configure-nolink-by-default feature/487_Adding-support-for-editing-categories-when-using-Quick-Edit-from-the-Vocabulary feature/488_make-download-data-more-user-friendly feature/490_Adding-the--WordLift-Entities-Cloud--as-shortcode feature/501_php7-compatibility-check feature/503_Text-domain-is-missing-in-calls-to-_x-translation-API feature/510_add-support-for-reverse feature/511_add-support-for-the-about-property feature/512_Entity-type-listing-page-shows-an--access-not-allowed--in-wordpress-versions-before-4.7 feature/513_synonyms-in-json-ld feature/514_replace-zero-with-plus feature/516_Visual-Composer-tags-appearing-in-the-article's-description feature/518_add-the-type-when-2-or-more-entities-have-the-same-title-using-react feature/518_add-the-type-when-there-are-two-entities-with-same-title feature/524_Adding-support-for-schema.org/Recipe- feature/525_Content-dynamically-posted-should-follow-a-relevancy-order feature/526_Multisite-network-activation-fails-to-create-the-entity-types-on-newly-created-subsites- feature/531_fix-broken-second-chord-widget feature/533_Add-the-schema-wordCount-property-to-schema-Article feature/534_inform-the-editor-when-a-subscription-is-not-active feature/536_hide-labels-that-do-not-have-associated-entities-in-the-faceted-search-widget feature/537_translate-all-labels-in-plugin-faceted-search feature/541_amp-version-of-a-page-with-a-map-displays-a-gray-box feature/546_extend-the-json-ld-and-allow-customizations feature/550_limit-the-number-of-entities feature/552_make-a-content-data-export-compatible-with-google-analytics feature/552_make-content-data-export-comp-with-google feature/558_Link-to-the-settings-page-in-the-message-about-unset-key feature_561/Add-the-capability-to-create-new-entities-in-the-vocabulary- feature/562_Annotate_archival_content_using_my_vocabulary feature/583_Add-sameAs-to-schema.org/publisher-in-JSON-LD feature/584_Adding-aliases-as-link-TITLE-attributes- feature/586_adding-support-for-the-locationcreated-attribute-on-articles feature/587_Sort-entities-in-the-vocabulary-using-an-alphabetical-order feature/595_import-may-fail-with-many-posts-pages feature/#596_Associate-posts-with-entity-raxonomy/leta-post-to-be-equivalent-to-an-entity feature/597-crop-publisher-logo-to-recommended-dimensions feature/597-crop-publisher-logo feature/599_revising-the-order-of-proposed-entities feature/603_rebuild-the-relations-table feature/606_batch-analysis-on-all-posts feature/607_add-autocomplete-api feature/608_integrate-the-autocomplete-widget_try-react-boilerplate feature/608_integrate-the-autocomplete-widget feature/610_Type-in-xsd-dateTime feature/612_Improve-the-performance-of-the-Content-Filter-and-JSON-LD-Generation feature/617_PHP-Notice--ob_clean()--failed-to-delete-buffer feature/618_limit-faceted-search-results feature/626_Cache-JSON-LD,-introduce-an-explicit-caching-layer feature/627_Set-minimal-supported-wordpress-version-to-4.4 feature/631_fix-weird-occurrences-count-box feature/634_add-bulgarian-translation feature/642_allow-to-disable-json-ld feature/644-entities-not-showing-in-classification-box feature/666_chord-shortcode-uses-a-non-existing-post-status-of--published- feature/681-add-editors-wl-entity-read-permissions feature/681-fix-edit-screen-entity-permalink feature/682_capture-the-web-site-url feature/688_various_unit_test_failures feature/702-update-relation-table-when-post-is-deleted feature/713-allow-to-configure-the-target-country feature/715-add-custom-images-directory feature/716-invalidate-cache-in-batch-analysis feature/717-autofix-interpolation-errors feature/719-set-default-entity-type-in-batch-analysis feature/720-add-batch-analysis-filters feature/721-add-minimum-occurences-filter feature/722-batch-analysis-hook-for-updated-entities feature/724-batch-analysis-updates feature/726-set-post-types-to-batch-analysis feature/728-Gutenberg-Integration feature/729-mark-posts-without-content-as-completed-in-batch-analysis feature/736_add-an-option-to-link-only-the-first-entity-occurrence feature/739_change-the-color-background-of-the-wizards-grab-a-key-button-and-link-it-to-the-pricing-page feature/743-flush-cache-when-permalink-structure-is-changed feature/750-add-filters-to-allow-adding-custom-properties feature/752_2nd-level-properties-not-added-to-the-cloud-dataset feature/757-php-7-2-compatibility feature/759-add-offers-and-performer-for-events feature/760_add-a-reference-to-the-articles-being-annotated feature/761_search-rankings-dashboard-page feature/767-add-feedback-screen feature/768-refactor-core-install feature/769-move-wl-insert-triples-filter feature/772-allow-entity-grouping-by-category-in-vocabulary-widget feature/778-set-entities-order-in-vocabulary-widget feature/779-remove-logs-from-abstract-wordlift-install feature/780-add-missing-colons feature/786-add-name-properties-to-linked-dataset feature/787-add-more-recipe-properties feature/788-add-hook-to-wl-metaboxes-save-form feature/790-allow-multiple-gloassary-widgets-in-one-page feature/790-fix-two-vocabulary-widgets feature/791-add-delete-posts-capability-to-entity-post-type feature/792-remove-wl_admin_inject_chord_dialog_dependencies feature/793-convert-html-entities-in-jsonld feature/794-fix-vocabulary-shortcode-order feature/795_display-latest-blog-posts-from-our-website feature/797-assign-article-term-to-posts feature/800-replace-admin-ajax-with-wl-api feature/801-exclude-the-current-post-type-from-bad-slug-post-types feature/801-prevent-post-types-slug-to-match-the-archive-page-slugs feature/803-revise-recipe-structure feature/806-image-in-jsonld-is-missing feature/815_add-wl-schemas-hook feature/830_improve-image-markup-on-amp-pages-to-enhance-the-appearance-in-google-search-results feature/835_add-the-all-entity-types-metabox feature/842_exclude-wordlift-public-bundle-from-wp-rocket-defer feature/848_add-a-filter-to-allow-3rd-parties-to-change-the-TinyMCE-editor-id feature/850_allow-3rd-parties-to-change-the-site-url-and-post-permalink feature/851_add-a-filter-to-allow-3rd-parties-to-change-the-TinyMCE-editor-id-via-JavaScript feature/852_Post-Type-to-Entity-Type-mapping feature/858_WMT-and-SDTT-complain-about-wrong-type-for-location-bound-Places feature/866-Navigator-AMP feature/867-Faceted-Search-AMP feature/868_Remove-wlSettings-from-WP-Rocket-inline-optimization feature/871_add-wordlift-json-ld-markup-to-amp-pages gh-pages hotfix/add-missing-calendar-to-date-field hotfix/fix-post-status-when-post-is-deleted hotfix/prevent-notice-on-initial-install hotfix/prevent-topic-entities-to-cause-fatal-error hotfix/update-translations hotfix/262_posting_a_site_url_on_googleplus_uses_an_entity_title_instead_of_the_post_title hotfix/265_entity_person_created_before_publishing_organization hotfix/282_wrong_entity_url hotfix/318_faceted_search_not_working_on_entity_pages hotfix/333_germanic_umlaut_causing_troubles_when_saving_sameas_links hotfix/334 hotfix/336_navigator_widget_doesnt_show hotfix/340_incompatible_date_widget hotfix/348_double_link hotfix/351_text-annotations-missing-for-found-entities hotfix/363_synonyms_associated_to_other_entities hotfix/366_text-annotations-not-set-with-fusion-core hotfix/368_adding-unneeded-p-tag-for-entity-properties hotfix/382_analysis-error-on-coffee-brewing-methods-com hotfix/386_linked-data-not-saved hotfix/406_jsonld-response-corrupt hotfix/410_triples-not-working-on-the-wordlift-dashboard hotfix/415-wordlift-not-working-after-updating-to-47 hotfix/418-do-not-allow-activating-wordlift-on-incompatible-wp-versions hotfix/429-german-missing-in-supported-languages-list hotfix/430-analysis-selectors-messed-up-in-wp-45-and-lower hotfix/439_entity-preview-is-redirected-to-post hotfix/443_chord-height-is-fixed-when-global-true hotfix/461_entities-highlighted-in-front-end hotfix/462_find-duplicated-entities hotfix/479_entity-slug-changed-by-the-system hotfix/494_cached-html-templates hotfix/495_additional-left-padding-on-entity-tiles hotfix/496_wl-highlight-classes-conflict-with-themes hotfix/497_aggressive-caching-may-serve-old-files hotfix/500_setup_wiard_long_text hotfix/520_selected-entities-lost-with-ie11-and-edge hotfix/521_performance-issues-on-ajax-end-point hotfix/527_error-fetching-angular-animate hotfix/528_fsockopen-loops-indefinitely hotfix/535_incorrect-text-annotation-styles-in-editor hotfix/543_entities-not-published-to-the-linked-data-store hotfix/549_make-wl-compatible-with-wp-4-8 hotfix/556_sparql-queries-fail hotfix/568_trying-to-get-property-of-non-object hotfix/569_explicitly-enabling-an-entity-link-doesnt-work hotfix/570_access-denied-on-wordlift-configuration-screen hotfix/571_faceted-search-not-displaying-correctly hotfix/575_cron-is-unreliable-on-some-web-sites hotfix/576_error-404-on-a-woocommerce-product-page hotfix/577_faceted-search-posts-list-doesnt-show hotfix/593_recipes-mentioned-in-posts-pages-do-not-appear-in-the-json-ld hotfix/601_improve-the-batch-analysis-service hotfix/611_WordLift-slowing-down-RSS-feed hotfix/615_Faceted-Search-generates-a-SQL-error hotfix/633_colon-in-html-messes-the-analysis hotfix/643_Notices-on-capabilities- hotfix/644-entities-not-showing-in-classification-box hotfix/647-remove-duplicate-related-posts hotfix/654_entity-link-always-returning-the-last-blog-post hotfix/661_Ignore-sticky-posts-when-querying-for-entities hotfix/662_old-articles-appear-in-vocabulary hotfix/663_terms-query-may-slow-down-site hotfix/683_incompatibility-with-formidable-forms hotfix/694_permalinks-on-edit-screen-do-not-work-on-fresh-installs hotfix/699_font-awesome-on-the-front-end-may-conflict-with-themes hotfix/707_performance-degrades-in-combination-with-yoast hotfix/711_performance-issues-with-content-filter hotfix/758_amp_post_template_css-casues-php-warning hotfix/770-autocomplete-issue-with-french-symbols-in-link hotfix/771_issue-with-the-typographical-superscript hotfix/773-move-php72-test-to-allowed-failures hotfix/774-update-entity-author-on-user-author-update hotfix/776-jsonld-generation-raises-warning hotfix/777-exit-after-redirecting-to-edit-entity-page hotfix/785-fix-sameas-field hotfix/789-prevent-entities-from-being-set-to-draft hotfix/794-fit-vocabulary-shortcode-order hotfix/802_fix-locales hotfix/818_deleted-entities-appear-as-numbers-in-metaboxes hotfix/819_when-a-post-is-converted-into-entity hotfix/820_wl-api-lost-when-plugin-deactivated-and-activated-back-again hotfix/823_logo-not-available-in-referenced-publisher hotfix/840_wl-api-referenced-using-siteurl-instead-of-homeurl hotfix/846_on-deactivate-ensure-to-delete-the-wl-api-option hotfix/865_Content-Egg-s-angular-clashes-with-WordLift-s-angular jpmacleure-hotfix/565_allow_empty_vocabulary_path_on_compatible_permalink_configuration markkap-#447_limit_enqueue_to_post_edit master purgatory release/3.1.0 release/3.2 release/3.3 release/3.4 release/3.5 release/3.6 release/3.7.0 release/3.8.0 release/3.9.0 release/3.9.6 release/3.10.0 release/3.11.0 release/3.11.1 release/3.11.2 release/3.11.3 release/3.12.0 release/3.12.1 release/3.12.2 release/3.12.3 release/3.12.4 release/3.13.0 release/3.13.1 release/3.13.2 release/3.13.3 release/3.14.0 release/3.14.1 release/3.14.2 release/3.14.3 release/3.14.4 release/3.14.5 release/3.14.6 release/3.15.0 release/3.15.1 release/3.15.2 release/3.15.3 release/3.15.4 release/3.15.5 release/3.15.6 release/3.16.0 release/3.16.1 release/3.16.2 release/3.16.3 release/3.16.4 release/3.16.5 release/3.17.0 release/3.17.1 release/3.17.2 release/3.17.3 release/3.18.0 release/3.18.1 release/3.18.2 release/3.18.3 release/3.18.4 release/3.18.5 release/3.18.6 release/3.19.0 release/3.19.1 release/3.19.2 release/3.19.3 release/3.19.4 release/3.19.5 release/3.19.6 release/3.20.0 revert-649-hotfix/644-entities-not-showing-in-classification-box svn tmp
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
652 lines (578 sloc) 21.2 KB
<?php
/**
* Core Post Entity Relations functions.
*
* @since 3.0.0
* @package Wordlift
* @subpackage Wordlift/modules/core
*/
/**
* Checks if a relation is supported
*
* @param string $predicate Name of the relation: 'what' | 'where' | 'when' | 'who'
*
* @return boolean Return true if supported, false otherwise
*/
function wl_core_check_relation_predicate_is_supported( $predicate ) {
return in_array( $predicate, array(
WL_WHAT_RELATION,
WL_WHEN_RELATION,
WL_WHERE_RELATION,
WL_WHO_RELATION,
) );
}
/**
* Return an array of validation rules used by wl_core_get_posts
*
* @return array in the format field => (array) accepeted_values
*/
function wl_core_get_validation_rules() {
return unserialize( WL_CORE_GET_POSTS_VALIDATION_RULES );
}
/**
* Return the wordlift relation instances table name
*
* @return string Return the wordlift relation instances table name
*/
function wl_core_get_relation_instances_table_name() {
global $wpdb;
$table_name = $wpdb->prefix . WL_DB_RELATION_INSTANCES_TABLE_NAME;
return $table_name;
}
/**
* Create a single relation instance if the given instance does not exist on the table
*
* @param int $subject_id The post ID | The entity post ID.
* @param string $predicate Name of the relation: 'what' | 'where' | 'when' | 'who'
* @param int $object_id The entity post ID.
*
* @uses $wpdb->replace() to perform the query
* @return integer|boolean Return then relation instance ID or false.
*/
function wl_core_add_relation_instance( $subject_id, $predicate, $object_id ) {
// Checks on subject and object
if ( ! is_numeric( $subject_id ) || ! is_numeric( $object_id ) ) {
return false;
}
// Checks on the given relation
if ( ! wl_core_check_relation_predicate_is_supported( $predicate ) ) {
return false;
}
// Prepare interaction with db
global $wpdb;
// Checks passed. Add relation if not exists:
//
// See https://codex.wordpress.org/Class_Reference/wpdb#REPLACE_row
$wpdb->replace(
wl_core_get_relation_instances_table_name(),
array(
'subject_id' => $subject_id,
'predicate' => $predicate,
'object_id' => $object_id,
),
array( '%d', '%s', '%d' )
);
/**
* Hooks: Relation Added.
*
* Fire a hook when a new relation between a post/entity and an entity is
* added (the relation may already exists).
*
* @since 3.16.0
*
* @param int $subject_id The subject {@link WP_Post} id.
* @param string $predicate The predicate.
* @param int $object_id The object {@link WP_Post} id.
*/
do_action( 'wl_relation_added', $subject_id, $predicate, $object_id );
// Return record id
return $wpdb->insert_id;
}
/**
* Remove all relation instances for a given $subject_id and $predicate
* If $predicate is omitted, $predicate filter is not applied
*
* @param int $subject_id The post ID | The entity post ID.
*
* @return boolean False for failure. True for success.
*/
function wl_core_delete_relation_instances( $subject_id ) {
// Checks on subject and object
if ( ! is_numeric( $subject_id ) ) {
return false;
}
// Prepare interaction with db
global $wpdb;
// wl_write_log( "Going to delete relation instances [ subject_id :: $subject_id ]");
// @see https://codex.wordpress.org/it:Riferimento_classi/wpdb#DELETE_di_righe
$wpdb->delete(
wl_core_get_relation_instances_table_name(),
array(
'subject_id' => $subject_id,
),
array( '%d' )
);
/**
* Hooks: Relation Deleted.
*
* The hook is fired after the relations with this post/entity are deleted.
*
* @since 3.16.0
*
* @param int $subject_id The subject {@link WP_Post} id.
*/
do_action( 'wl_relation_deleted', $subject_id );
return true;
}
/**
* Validate filters given as parameters to any *wl_core_get_related_...*
*
* @param array $filters Associative array containing required predicate and post status
*
* @return array Corrected $filters, default is:
* array(
* 'predicate' => null,
* 'status' => null
* );
*/
function wl_core_validate_filters_for_related( $filters ) {
if ( ! is_array( $filters ) ) {
$filters = array();
}
if ( ! isset( $filters['predicate'] ) ) {
$filters['predicate'] = null;
}
if ( ! isset( $filters['status'] ) ) {
$filters['status'] = null;
}
return $filters;
}
///**
// * Find all entities related to a given $subject_id
// * If $predicate is omitted, $predicate filter is not applied
// * @uses wl_core_inner_get_related_entities() to perform the action
// *
// * @param int $subject_id The post ID | The entity post ID.
// * @param array $filters Associative array formed like this:
// * <code>
// * $filters = array(
// * 'predicate' => Name of the relation: [ null | 'what' | 'where' | 'when' | 'who' ], default is null (meaning *any* post status)
// * 'status' => [ null | 'publish' | 'draft' | 'pending' | 'trash' ], default is null (meaning *any* post status)
// * );
// * </code>
// *
// * @return array Array of post entity objects.
// */
//function wl_core_get_related_entities( $subject_id, $filters = array() ) {
//
// $filters = wl_core_validate_filters_for_related( $filters );
//
// return wl_core_inner_get_related_entities( "posts", $subject_id, $filters['predicate'], $filters['status'] );
//}
/**
* Find all entity ids related to a given $subject_id.
*
* If $predicate is omitted, $predicate filter is not applied.
*
* @deprecated use Wordlift_Relation_Service::get_instance()->get_objects( $subject_id, 'ids', $predicate, $status );
*
* @uses wl_core_inner_get_related_entities() to perform the action
*
* @param int $subject_id The post ID | The entity post ID.
* @param array $filters Associative array formed like this:
* <code>
* $filters = array(
* 'predicate' => Name of the relation: [ null | 'what' | 'where' | 'when' | 'who' ], default is null (meaning *any* post status)
* 'status' => [ null | 'publish' | 'draft' | 'pending' | 'trash' ], default is null (meaning *any* post status)
* );
* </code>
*
* @return array Array of post entity objects.
*/
function wl_core_get_related_entity_ids( $subject_id, $filters = array() ) {
$status = isset( $filters['status'] ) ? $filters['status'] : null;
$predicate = isset( $filters['predicate'] ) ? $filters['predicate'] : null;
return Wordlift_Relation_Service::get_instance()->get_objects( $subject_id, 'ids', $predicate, $status );
// $filters = wl_core_validate_filters_for_related( $filters );
//
// return wl_core_inner_get_related_entities( 'post_ids', $subject_id, $filters['predicate'], $filters['status'] );
}
/**
* Get the entities related to the specified {@link WP_Post}.
*
* This function is deprecated and left for compatibility with 3rd parties.
*
* @deprecated use Wordlift_Relation_Service::get_instance()->get_objects()
*
* @param int $subject_id The {@link WP_Post}'s id.
* @param array $filters An array of filters.
*
* @return array An array of {@link WP_Post}s.
*/
function wl_core_get_related_entities( $subject_id, $filters = array() ) {
$ids = wl_core_get_related_entity_ids( $subject_id, $filters );
return array_map( function ( $item ) {
return get_post( $item );
}, $ids );
}
//
///**
// * Find all entity ids related to a given $subject_id
// * If $predicate is omitted, $predicate filter is not applied
// * Do not use it directly. Use wl_core_get_related_entities or wl_core_get_related_entity_ids instead.
// *
// * @param $get
// * @param $item_id
// * @param string $predicate Name of the relation: null | 'what' | 'where' | 'when' | 'who'
// * @param string $post_status Filter by post status null | 'publish' | 'draft' | 'pending' | 'trash'. null means *any* post status
// *
// * @return array Array of ids.
// */
//function wl_core_inner_get_related_entities( $get, $item_id, $predicate = null, $post_status = null ) {
//
// if ( $results = wl_core_get_posts( array(
// 'get' => $get,
// 'post_type' => 'entity',
// 'post_status' => $post_status,
// 'related_to' => $item_id,
// 'as' => 'object',
// 'with_predicate' => $predicate,
// ) )
// ) {
// return $results;
// }
//
// // If wl_core_get_posts return false then an empty array is returned
// return array();
//}
///**
// * Find all posts related to a given $object_id
// * If $predicate is omitted, $predicate filter is not applied
// * @uses wl_core_get_related_posts() to perform the action
// *
// * @param int $object_id The entity ID or the post ID.
// * @param array $filters Associative array formed like this:
// * <code>
// * $filters = array(
// * 'predicate' => Name of the relation: [ null | 'what' | 'where' | 'when' | 'who' ], default is null (meaning *any* post status)
// * 'status' => [ null | 'publish' | 'draft' | 'pending' | 'trash' ], default is null (meaning *any* post status)
// * );
// * </code>
// *
// * @return array Array of objects.
// */
//function wl_core_get_related_posts( $object_id, $filters = array() ) {
//
// $filters = wl_core_validate_filters_for_related( $filters );
//
// return wl_core_inner_get_related_posts( "posts", $object_id, $filters['predicate'], $filters['status'] );
//}
/**
* Find all post ids related to a given $object_id
* If $predicate is omitted, $predicate filter is not applied
*
* @deprecated use Wordlift_Relation_Service::get_instance()->get_article_subjects( $object_id, 'ids', $status );
*
* @uses wl_core_get_related_posts() to perform the action
*
* @param int $object_id The entity ID or the post ID.
* @param array $filters Associative array formed like this:
* <code>
* $filters = array(
* 'predicate' => Name of the relation: [ null | 'what' | 'where' | 'when' | 'who' ], default is null (meaning *any* post status)
* 'status' => [ null | 'publish' | 'draft' | 'pending' | 'trash' ], default is null (meaning *any* post status)
* );
* </code>
*
* @return array Array of objects.
*/
function wl_core_get_related_post_ids( $object_id, $filters = array() ) {
$relation_service = Wordlift_Relation_Service::get_instance();
$status = isset( $filters['status'] ) ? $filters['status'] : null;
$predicate = isset( $filters['predicate'] ) ? $filters['predicate'] : null;
return $relation_service->get_article_subjects( $object_id, 'ids', $predicate, $status );
//
// $filters = wl_core_validate_filters_for_related( $filters );
//
// return wl_core_inner_get_related_posts( 'post_ids', $object_id, $filters['predicate'], $filters['status'] );
}
/**
* Get the posts related to the specified entity {@link WP_Post}.
*
* This function is deprecated and left for compatibility with 3rd parties.
*
* @deprecated use Wordlift_Relation_Service::get_instance()->get_article_subjects()
*
* @param int $subject_id The entity's {@link WP_Post}'s id. If a post/page id
* is provided, then the entities bound to that post/page
* are first loaded.
* @param array $filters An array of filters.
*
* @return array An array of {@link WP_Post}s.
*/
function wl_core_get_related_posts( $subject_id, $filters = array() ) {
$ids = wl_core_get_related_post_ids( $subject_id, $filters );
return array_map( function ( $item ) {
return get_post( $item );
}, $ids );
}
///**
// * Find all posts related to a given $object_id
// * If $predicate is omitted, $predicate filter is not applied
// * Not use it directly. Use wl_core_get_related_posts or wl_core_get_related_posts_ids instead.
// *
// * @param string $get
// * @param int $item_id
// * @param string $predicate Name of the relation: null | 'what' | 'where' | 'when' | 'who'
// * @param string $post_status Filter by post status null | 'publish' | 'draft' | 'pending' | 'trash'. null means *any* post status
// *
// * @return array Array of objects.
// */
//function wl_core_inner_get_related_posts( $get, $item_id, $predicate = null, $post_status = null ) {
//
// // Retrieve the post object
// $post = get_post( $item_id );
// if ( null === $post ) {
// return array();
// }
//
// if ( 'entity' === $post->post_type ) {
// if ( $results = wl_core_get_posts( array(
// 'get' => $get,
// 'post_type' => 'post',
// 'post_status' => $post_status,
// 'related_to' => $item_id,
// 'as' => 'subject',
// 'with_predicate' => $predicate,
// ) )
// ) {
// return $results;
// }
// } else {
// if ( $results = wl_core_get_posts( array(
// 'get' => $get,
// 'post_type' => 'post',
// 'post_status' => $post_status,
// 'post__not_in' => array( $item_id ),
// 'related_to__in' => wl_core_get_related_entity_ids( $post->ID ),
// 'as' => 'subject',
// 'with_predicate' => $predicate,
// ) )
// ) {
// return $results;
// }
// }
//
// // If wl_core_get_posts return false then an empty array is returned
// return array();
//}
/**
* Define a sql statement between wp_posts and wp_wl_relation_instances tables
* It's used by wl_core_get_posts. Implements a subset of WpQuery object
* @see https://codex.wordpress.org/Class_Reference/WP_Query
* Arguments validation is delegated to wl_core_get_posts method.
* Form the array like this:
* <code>
* $args = array(
* 'get' => 'posts', // posts, post_ids, relations, relation_ids
* 'first' => n,
* 'related_to' => 10, // the post/s / entity/ies id / ids
* 'related_to__in' => array(10,20,30)
* 'post__in' => array(10,20,30), // the post/s / entity/ies id / ids
* 'post__not_in' => array(10,20,30), // the post/s / entity/ies id / ids
* 'as' => [ subject | object ],
* 'with_predicate' => [ what | where | when | who ], // null as default value
* 'post_type' => [ post | entity ],
* 'post_status' => [ publish | draft | pending | trash ], default is null (meaning *any* post status)
* );
* </code>
*
* Since 3.15 post_type of 'post' serves as an indication of whether articles
* while a post type of 'entity' means a non article, instead of being used as explicit
* post types for the query.
*
* @param array $args Arguments to be used in the query builder.
*
* @return string|false String representing a sql statement, or false in case of error
*/
function wl_core_sql_query_builder( $args ) {
// Prepare interaction with db
global $wpdb;
// Retrieve Wordlift relation instances table name
$table_name = wl_core_get_relation_instances_table_name();
// When type is set to `post` we're looking for `post`s that are not
// configured as entities.
// When the type is set to `entity` we're looking also for `post`s that are
// configured as entities.
// Since we want Find only articles, based on the entity type, we need
// to figure out the relevant sql statements to add to the join and where
// parts.
if ( 'entity' === $args['post_type'] ) {
$tax_query = array(
'relation' => 'AND',
array(
'taxonomy' => Wordlift_Entity_Type_Taxonomy_Service::TAXONOMY_NAME,
'operator' => 'EXISTS',
),
array(
'taxonomy' => Wordlift_Entity_Type_Taxonomy_Service::TAXONOMY_NAME,
'field' => 'slug',
'terms' => 'article',
'operator' => 'NOT IN',
),
);
} else {
$tax_query = array(
'relation' => 'OR',
array(
'taxonomy' => Wordlift_Entity_Type_Taxonomy_Service::TAXONOMY_NAME,
'operator' => 'NOT EXISTS',
),
array(
'taxonomy' => Wordlift_Entity_Type_Taxonomy_Service::TAXONOMY_NAME,
'field' => 'slug',
'terms' => 'article',
),
);
}
// Use "p" as the table to match the initial join.
$tax_sql = get_tax_sql( $tax_query, 'p', 'ID' );
// Sql Action
$sql = 'SELECT ';
// Determine what has to be returned depending on 'get' argument value
switch ( $args['get'] ) {
case 'posts':
$sql .= 'p.*';
break;
case 'post_ids':
$sql .= 'p.id';
break;
}
// If we look for posts related as objects the JOIN has to be done with the object_id column and viceversa
$join_column = $args['as'] . '_id';
$sql .= " FROM $wpdb->posts as p JOIN $table_name as r ON p.id = r.$join_column";
// Changing left join generate by the tax query into an inner since the term relationship has to exist.
$sql .= str_replace( 'LEFT JOIN', 'INNER JOIN', $tax_sql['join'] );
// Sql add post type filter
$post_types = Wordlift_Entity_Service::valid_entity_post_types();
$sql .= " AND p.post_type IN ('" . join( "', '", esc_sql( $post_types ) ) . "') AND";
// Sql add post status filter
if ( isset( $args['post_status'] ) && ! is_null( $args['post_status'] ) ) {
$sql .= $wpdb->prepare( ' p.post_status = %s AND', $args['post_status'] );
}
// Add filtering conditions
// If we look for posts related as objects this means that
// related_to is a reference for a subject: subject_id is the filtering column
// If we look for posts related as subject this means that
// related_to is reference for an object: object_id is the filtering column
$filtering_column = ( 'object' == $args['as'] ) ? 'subject_id' : 'object_id';
if ( isset( $args['related_to'] ) ) {
$sql .= $wpdb->prepare( " r.$filtering_column = %d", $args['related_to'] );
}
if ( isset( $args['related_to'] ) && isset( $args['related_to__in'] ) ) {
$sql .= ' AND';
}
if ( isset( $args['related_to__in'] ) ) {
$sql .= " r.$filtering_column IN (" . implode( ',', $args['related_to__in'] ) . ')';
// The IDs used for filtering shouldn't be in the results.
$sql .= " AND p.ID NOT IN (" . implode( ',', $args['related_to__in'] ) . ')';
}
if ( isset( $args['post__not_in'] ) ) {
$sql .= ' AND r.' . $args['as'] . '_id NOT IN (' . implode( ',', $args['post__not_in'] ) . ')';
}
if ( isset( $args['post__in'] ) ) {
$sql .= ' AND r.' . $args['as'] . '_id IN (' . implode( ',', $args['post__in'] ) . ')';
}
// Add predicate filter if required.
if ( isset( $args['with_predicate'] ) ) {
// Sql Inner Join clause.
$sql .= $wpdb->prepare( ' AND r.predicate = %s', $args['with_predicate'] );
}
// Add the taxonomy related sql.
$sql .= $tax_sql['where'];
// Add a group by clause to avoid duplicated rows
// @todo: isn't a distinct a better choice?
$sql .= ' GROUP BY p.id';
// @todo: how does `first` represent the limit?
if ( isset( $args['first'] ) && is_numeric( $args['first'] ) ) {
// Sql Inner Join clause.
$sql .= $wpdb->prepare( ' LIMIT %d', $args['first'] );
}
// Close sql statement
$sql .= ';';
return $sql;
}
/**
* Perform a query on db depending on args
* It's responsible for argument validations
* @uses wl_core_sql_query_builder() to compose the sql statement
* @uses wpdb() instance to perform the query
*
* @param array $args Arguments to be used in the query builder.
*
* @param string $returned_type
*
* @return array|false List of WP_Post objects or list of WP_Post ids. False in case of error or invalid params
*/
function wl_core_get_posts( $args, $returned_type = OBJECT ) {
// Merge given args with defaults args value
$args = array_merge( array(
'with_predicate' => null,
'as' => 'subject',
'post_type' => 'post',
'get' => 'posts',
'post_status' => null,
), $args );
// Arguments validation rules
// At least one between related_to and related_to__in has to be set
if ( ! isset( $args['related_to'] ) && ! isset( $args['related_to__in'] ) ) {
return false;
}
if ( isset( $args['related_to'] ) && ! is_numeric( $args['related_to'] ) ) {
return false;
}
// The same check is applied to post_in, post__not_in and related_to__in options
// Only arrays with at least one numeric value are considerad valid
// The argument value is further sanitized in order to clean up not numeric values
foreach (
array(
'post__in',
'post__not_in',
'related_to__in',
) as $option_name
) {
if ( isset( $args[ $option_name ] ) ) {
if ( ! is_array( $args[ $option_name ] ) || 0 == count( array_filter( $args[ $option_name ], "is_numeric" ) ) ) {
return false;
}
// Sanitize value removing non numeric values from the array
$args[ $option_name ] = array_filter( $args[ $option_name ], "is_numeric" );
}
}
// Performing validation rules
foreach ( wl_core_get_validation_rules() as $option_name => $accepeted_values ) {
if ( isset( $args[ $option_name ] ) && ! is_null( $args[ $option_name ] ) ) {
if ( ! in_array( $args[ $option_name ], $accepeted_values ) ) {
return false;
}
}
}
// Prepare interaction with db
global $wpdb;
// Build sql statement with given arguments
$sql_statement = wl_core_sql_query_builder( $args );
// If ids are required, returns a one-dimensional array containing ids.
// Otherwise an array of associative arrays representing the post | relation object
if ( 'post_ids' == $args['get'] ) {
# See https://codex.wordpress.org/Class_Reference/wpdb#SELECT_a_Column
$results = $wpdb->get_col( $sql_statement );
} else {
$results = $wpdb->get_results( $sql_statement, $returned_type );
}
// If there were an error performing the query then false is returned
if ( ! empty( $wpdb->last_error ) ) {
return false;
}
// Finally
return $results;
}