/** * Delete the specified post from the triple store. * * @param array|int $post An array of post data */ function rl_delete_post($post) { $post_id = is_numeric($post) ? $post : $post->ID; // hide all entities that are not referenced by any published post. foreach (wl_core_get_related_entity_ids($post_id) as $entity_id) { // check if there is at least one referencing post published. $is_published = array_reduce(wl_core_get_related_post_ids($entity_id), function ($carry, $item) { $post = get_post($item); return $carry || 'publish' === $post->post_status; }); // set the entity to draft if no referencing posts are published. if (!$is_published) { wl_update_post_status($entity_id, 'draft'); } } // get the entity URI (valid also for posts) $uri_esc = wl_sparql_escape_uri(wl_get_entity_uri($post_id)); wl_write_log("rl_delete_post [ post id :: {$post_id} ][ uri esc :: {$uri_esc} ]"); // create the SPARQL statement by joining the SPARQL prefixes and deleting any known predicate. $stmt = rl_sparql_prefixes(); foreach (wl_predicates() as $predicate) { $stmt .= "DELETE { <{$uri_esc}> {$predicate} ?o . } WHERE { <{$uri_esc}> {$predicate} ?o . };\n" . "DELETE { ?s {$predicate} <{$uri_esc}> . } WHERE { ?s {$predicate} <{$uri_esc}> . };\n"; } // if the post is an entity and has exported properties, delete the related predicates. if (WL_ENTITY_TYPE_NAME === $post->post_type) { $type = wl_entity_type_taxonomy_get_type($post->ID); if (isset($type['custom_fields'])) { foreach ($type['custom_fields'] as $field => $params) { // TODO: enclose in <> only if predicate starts with http(s):// $predicate = '<' . $params['predicate'] . '>'; $stmt .= "DELETE { <{$uri_esc}> {$predicate} ?o . } WHERE { <{$uri_esc}> {$predicate} ?o . };\n"; } } } // finally execute the query. rl_execute_sparql_update_query($stmt); }
/** * Execute the provided query against the SPARQL SELECT Redlink end-point and return the response. * * @param string $query A SPARQL query. * @param string $accept The mime type for the response format (default = 'text/csv'). * * @return WP_Response|WP_Error A WP_Response instance in successful otherwise a WP_Error. */ function rl_sparql_select($query) { // Prepare the SPARQL statement by prepending the default namespaces. $sparql = rl_sparql_prefixes() . "\n" . $query; // Get the SPARQL SELECT URL. $url = wl_configuration_get_query_select_url('csv') . urlencode($sparql); // Prepare the request. $args = unserialize(WL_REDLINK_API_HTTP_OPTIONS); // Send the request. wl_write_log("SPARQL Select [ sparql :: {$sparql} ][ url :: {$url} ][ args :: " . var_export($args, true) . " ]"); return wp_remote_get($url, $args); }
/** * Push the provided entity post to Redlink. * * @param object $entity_post An entity post instance. */ function wl_push_entity_post_to_redlink($entity_post) { // Get the Entity service instance to perform actions related to entities. $entity_service = Wordlift_Entity_Service::get_instance(); // Only handle published entities. if (!$entity_service->is_entity($entity_post->ID) || 'publish' !== $entity_post->post_status) { wl_write_log("wl_push_entity_post_to_redlink : not an entity or not published [ post type :: {$entity_post->post_type} ][ post status :: {$entity_post->post_status} ]"); return; } // get the entity URI and the SPARQL escaped version. $uri = wl_get_entity_uri($entity_post->ID); $uri_e = wl_sparql_escape_uri($uri); // If the URI ends with a trailing slash, then we have a problem. if ('/' === substr($uri, -1, 1)) { wl_write_log("wl_push_entity_post_to_redlink : the URI is invalid [ post ID :: {$entity_post->ID} ][ URI :: {$uri} ]"); return; } // Get the site language in order to define the literals language. $site_language = wl_configuration_get_site_language(); // get the title and content as label and description. $label = wordlift_esc_sparql($entity_post->post_title); $descr = wordlift_esc_sparql(wp_strip_all_tags(strip_shortcodes($entity_post->post_content))); $permalink = wl_sparql_escape_uri(get_permalink($entity_post->ID)); // wl_write_log( "wl_push_entity_post_to_redlink [ entity post id :: $entity_post->ID ][ uri :: $uri ][ label :: $label ]" ); // create a new empty statement. $delete_stmt = ''; $sparql = ''; // delete on RL all statements regarding properties set from WL (necessary when changing entity type) $all_custom_fields = wl_entity_taxonomy_get_custom_fields(); $predicates_to_be_deleted = array(); foreach ($all_custom_fields as $type => $fields) { foreach ($fields as $cf) { $predicate = $cf['predicate']; if (!in_array($predicate, $predicates_to_be_deleted)) { $predicates_to_be_deleted[] = $predicate; $delete_stmt .= "DELETE { <{$uri_e}> <{$predicate}> ?o } WHERE { <{$uri_e}> <{$predicate}> ?o };\n"; } } } // set the same as. $same_as = wl_schema_get_value($entity_post->ID, 'sameAs'); foreach ($same_as as $same_as_uri) { $same_as_uri_esc = wl_sparql_escape_uri($same_as_uri); $sparql .= "<{$uri_e}> owl:sameAs <{$same_as_uri_esc}> . \n"; } // set the label $sparql .= "<{$uri_e}> rdfs:label \"{$label}\"@{$site_language} . \n"; // Set the alternative labels. $alt_labels = $entity_service->get_alternative_labels($entity_post->ID); foreach ($alt_labels as $alt_label) { $sparql .= sprintf('<%s> rdfs:label "%s"@%s . ', $uri_e, Wordlift_Query_Builder::escape_value($alt_label), $site_language); } // set the URL $sparql .= "<{$uri_e}> schema:url <{$permalink}> . \n"; // set the description. if (!empty($descr)) { $sparql .= "<{$uri_e}> schema:description \"{$descr}\"@{$site_language} . \n"; } $main_type = wl_entity_type_taxonomy_get_type($entity_post->ID); if (null != $main_type) { $main_type_uri = wl_sparql_escape_uri($main_type['uri']); $sparql .= " <{$uri_e}> a <{$main_type_uri}> . \n"; // The type define custom fields that hold additional data about the entity. // For example Events may have start/end dates, Places may have coordinates. // The value in the export fields must be rewritten as triple predicates, this // is what we're going to do here. // wl_write_log( 'wl_push_entity_post_to_redlink : checking if entity has export fields [ type :: ' . var_export( $main_type, true ) . ' ]' ); if (isset($main_type['custom_fields'])) { foreach ($main_type['custom_fields'] as $field => $settings) { // wl_write_log( "wl_push_entity_post_to_redlink : entity has export fields" ); $predicate = wordlift_esc_sparql($settings['predicate']); if (!isset($settings['export_type']) || empty($settings['export_type'])) { $type = null; } else { $type = $settings['export_type']; } foreach (get_post_meta($entity_post->ID, $field) as $value) { $sparql .= " <{$uri_e}> <{$predicate}> "; if (!is_null($type) && substr($type, 0, 4) == 'http') { // Type is defined by a raw uri (es. http://schema.org/PostalAddress) // Extract uri if the value is numeric if (is_numeric($value)) { $value = wl_get_entity_uri($value); } $sparql .= '<' . wl_sparql_escape_uri($value) . '>'; } else { // Type is defined in another way (es. xsd:double) $sparql .= '"' . wordlift_esc_sparql($value) . '"^^' . wordlift_esc_sparql($type); } $sparql .= " . \n"; } } } } // Get the entity types. $type_uris = wl_get_entity_rdf_types($entity_post->ID); // Support type are only schema.org ones: it could be null foreach ($type_uris as $type_uri) { $type_uri = wl_sparql_escape_uri($type_uri); $sparql .= "<{$uri_e}> a <{$type_uri}> . \n"; } // get related entities. $related_entities_ids = wl_core_get_related_entity_ids($entity_post->ID); if (is_array($related_entities_ids)) { foreach ($related_entities_ids as $entity_post_id) { $related_entity_uri = wl_sparql_escape_uri(wl_get_entity_uri($entity_post_id)); // create a two-way relationship. $sparql .= " <{$uri_e}> dct:relation <{$related_entity_uri}> . \n"; $sparql .= " <{$related_entity_uri}> dct:relation <{$uri_e}> . \n"; } } // Add SPARQL stmts to write the schema:image. $sparql .= wl_get_sparql_images($uri, $entity_post->ID); $query = rl_sparql_prefixes() . <<<EOF {$delete_stmt} DELETE { <{$uri_e}> rdfs:label ?o } WHERE { <{$uri_e}> rdfs:label ?o }; DELETE { <{$uri_e}> owl:sameAs ?o . } WHERE { <{$uri_e}> owl:sameAs ?o . }; DELETE { <{$uri_e}> schema:description ?o . } WHERE { <{$uri_e}> schema:description ?o . }; DELETE { <{$uri_e}> schema:url ?o . } WHERE { <{$uri_e}> schema:url ?o . }; DELETE { <{$uri_e}> a ?o . } WHERE { <{$uri_e}> a ?o . }; DELETE { <{$uri_e}> dct:relation ?o . } WHERE { <{$uri_e}> dct:relation ?o . }; DELETE { <{$uri_e}> schema:image ?o . } WHERE { <{$uri_e}> schema:image ?o . }; INSERT DATA { {$sparql} }; EOF; rl_execute_sparql_update_query($query); }
/** * This function is called by the *flush_rewrite_rules_hard* hook. It recalculates the URI for all the posts. * * @since 3.0.0 * * @uses rl_sparql_prefixes() to get the SPARQL prefixes. * @uses wordlift_esc_sparql() to escape the SPARQL query. * @uses wl_get_entity_uri() to get an entity URI. * @uses rl_execute_sparql_update_query() to post the DELETE and INSERT queries. * * @param bool $hard True if the rewrite involves configuration updates in Apache/IIS. */ function wl_flush_rewrite_rules_hard($hard) { // Get all published posts. $posts = get_posts(array('posts_per_page' => -1, 'post_type' => 'any', 'post_status' => 'publish')); // Holds the delete part of the query. $delete_query = rl_sparql_prefixes(); // Holds the insert part of the query. $insert_query = 'INSERT DATA { '; // Cycle in each post to build the query. foreach ($posts as $post) { // Ignore revisions. if (wp_is_post_revision($post->ID)) { continue; } // Get the entity URI. $uri = wl_sparql_escape_uri(wl_get_entity_uri($post->ID)); // Get the post URL. $url = wl_sparql_escape_uri(get_permalink($post->ID)); // Prepare the DELETE and INSERT commands. $delete_query .= "DELETE { <{$uri}> schema:url ?u . } WHERE { <{$uri}> schema:url ?u . };\n"; $insert_query .= " <{$uri}> schema:url <{$url}> . \n"; // wl_write_log( "[ uri :: $uri ][ url :: $url ]" ); } $insert_query .= ' };'; // Execute the query. rl_execute_sparql_update_query($delete_query . $insert_query); }
/** * Push the provided entity post to Redlink. * * @param object $entity_post An entity post instance. */ function wl_push_entity_post_to_redlink($entity_post) { // Only handle published entities. if ('entity' !== $entity_post->post_type or 'publish' !== $entity_post->post_status) { wl_write_log("wl_push_entity_post_to_redlink : not an entity or not published [ post type :: {$entity_post->post_type} ][ post status :: {$entity_post->post_status} ]"); return; } // get the entity URI and the SPARQL escaped version. $uri = wl_get_entity_uri($entity_post->ID); $uri_e = wl_sparql_escape_uri($uri); // If the URI ends with a trailing slash, then we have a problem. if ('/' === substr($uri, -1, 1)) { wl_write_log("wl_push_entity_post_to_redlink : the URI is invalid [ post ID :: {$entity_post->ID} ][ URI :: {$uri} ]"); return; } // Get the site language in order to define the literals language. $site_language = wl_configuration_get_site_language(); // get the title and content as label and description. $label = wordlift_esc_sparql($entity_post->post_title); $descr = wordlift_esc_sparql($entity_post->post_content); $permalink = wl_sparql_escape_uri(get_permalink($entity_post->ID)); wl_write_log("wl_push_entity_post_to_redlink [ entity post id :: {$entity_post->ID} ][ uri :: {$uri} ][ label :: {$label} ]"); // create a new empty statement. $delete_stmt = ''; $sparql = ''; // set the same as. $same_as = wl_schema_get_value($entity_post->ID, 'sameAs'); foreach ($same_as as $same_as_uri) { $same_as_uri_esc = wl_sparql_escape_uri($same_as_uri); $sparql .= "<{$uri_e}> owl:sameAs <{$same_as_uri_esc}> . \n"; } // set the label $sparql .= "<{$uri_e}> rdfs:label \"{$label}\"@{$site_language} . \n"; // set the URL $sparql .= "<{$uri_e}> schema:url <{$permalink}> . \n"; // set the description. if (!empty($descr)) { $sparql .= "<{$uri_e}> schema:description \"{$descr}\"@{$site_language} . \n"; } $main_type = wl_entity_type_taxonomy_get_type($entity_post->ID); if (null != $main_type) { $main_type_uri = wl_sparql_escape_uri($main_type['uri']); $sparql .= " <{$uri_e}> a <{$main_type_uri}> . \n"; // The type define custom fields that hold additional data about the entity. // For example Events may have start/end dates, Places may have coordinates. // The value in the export fields must be rewritten as triple predicates, this // is what we're going to do here. wl_write_log('wl_push_entity_post_to_redlink : checking if entity has export fields [ type :: ' . var_export($main_type, true) . ' ]'); if (isset($main_type['custom_fields'])) { foreach ($main_type['custom_fields'] as $field => $settings) { wl_write_log("wl_push_entity_post_to_redlink : entity has export fields"); $predicate = wordlift_esc_sparql($settings['predicate']); if (!isset($settings['export_type']) || empty($settings['export_type'])) { $type = null; } else { $type = $settings['export_type']; } // add the delete statement for later execution. $delete_stmt .= "DELETE { <{$uri_e}> <{$predicate}> ?o } WHERE { <{$uri_e}> <{$predicate}> ?o };\n"; foreach (get_post_meta($entity_post->ID, $field) as $value) { $sparql .= " <{$uri_e}> <{$predicate}> "; // Establish triple's <object> type if (is_null($type)) { // No type $sparql .= '<' . wl_sparql_escape_uri($value) . '>'; } else { $sparql .= '"' . wordlift_esc_sparql($value) . '"^^'; if (substr($type, 0, 4) == 'http') { // Type is defined by a raw uri (es. http://schema.org/PostalAddress) $sparql .= '<' . wl_sparql_escape_uri($type) . '>'; } else { // Type is defined in another way (es. xsd:double) $sparql .= wordlift_esc_sparql($type); } } $sparql .= " . \n"; } } } } // Get the entity types. $type_uris = wl_get_entity_rdf_types($entity_post->ID); // Support type are only schema.org ones: it could by null foreach ($type_uris as $type_uri) { $type_uri = wl_sparql_escape_uri($type_uri); $sparql .= "<{$uri_e}> a <{$type_uri}> . \n"; } // get related entities. $related_entities_ids = wl_core_get_related_entitY_ids($entity_post->ID); if (is_array($related_entities_ids)) { foreach ($related_entities_ids as $entity_post_id) { $related_entity_uri = wl_sparql_escape_uri(wl_get_entity_uri($entity_post_id)); // create a two-way relationship. $sparql .= " <{$uri_e}> dct:relation <{$related_entity_uri}> . \n"; $sparql .= " <{$related_entity_uri}> dct:relation <{$uri_e}> . \n"; } } // Add SPARQL stmts to write the schema:image. $sparql .= wl_get_sparql_images($uri, $entity_post->ID); $query = rl_sparql_prefixes() . <<<EOF {$delete_stmt} DELETE { <{$uri_e}> rdfs:label ?o } WHERE { <{$uri_e}> rdfs:label ?o }; DELETE { <{$uri_e}> owl:sameAs ?o . } WHERE { <{$uri_e}> owl:sameAs ?o . }; DELETE { <{$uri_e}> schema:description ?o . } WHERE { <{$uri_e}> schema:description ?o . }; DELETE { <{$uri_e}> schema:url ?o . } WHERE { <{$uri_e}> schema:url ?o . }; DELETE { <{$uri_e}> a ?o . } WHERE { <{$uri_e}> a ?o . }; DELETE { <{$uri_e}> dct:relation ?o . } WHERE { <{$uri_e}> dct:relation ?o . }; DELETE { <{$uri_e}> schema:image ?o . } WHERE { <{$uri_e}> schema:image ?o . }; DELETE { <{$uri_e}> geo:lat ?o . } WHERE { <{$uri_e}> geo:lat ?o . }; DELETE { <{$uri_e}> geo:long ?o . } WHERE { <{$uri_e}> geo:long ?o . }; INSERT DATA { {$sparql} }; EOF; rl_execute_sparql_update_query($query); }
/** * Called when a user is updated. * * @param int $user_id The user ID. * * @return true if successful otherwise false. */ function wl_update_user_profile($user_id) { wl_write_log("wl_update_user_profile [ user id :: {$user_id} ]"); // Get the site language setting. $language = wl_configuration_get_site_language(); // Get the user. $user = get_userdata($user_id); // Get the user URI. $uri = wl_sparql_escape_uri(wl_get_user_uri($user_id)); // Get the first/last name and the posts URL. $first_name = wordlift_esc_sparql($user->first_name); $last_name = wordlift_esc_sparql($user->last_name); $posts_url = wl_sparql_escape_uri(get_author_posts_url($user_id)); $query = rl_sparql_prefixes(); $query .= <<<EOF DELETE { <{$uri}> schema:givenName ?o } WHERE { <{$uri}> schema:givenName ?o }; DELETE { <{$uri}> schema:familyName ?o } WHERE { <{$uri}> schema:familyName ?o }; DELETE { <{$uri}> schema:url ?o } WHERE { <{$uri}> schema:url ?o }; INSERT DATA { <{$uri}> schema:givenName '{$first_name}'@{$language} . <{$uri}> schema:familyName '{$last_name}'@{$language} . <{$uri}> schema:url <{$posts_url}> . } EOF; // Execute the query. return rl_execute_sparql_update_query($query); }