/** * Save the post to the triple store. Also saves the entities locally and on the triple store. * * @since 3.0.0 * * @param int $post_id The post id being saved. */ function wl_linked_data_save_post_and_related_entities($post_id) { // Ignore auto-saves if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) { return; } // get the current post. $post = get_post($post_id); remove_action('wl_linked_data_save_post', 'wl_linked_data_save_post_and_related_entities'); wl_write_log("[ post id :: {$post_id} ][ autosave :: false ][ post type :: {$post->post_type} ]"); // Store mapping between tmp new entities uris and real new entities uri $entities_uri_mapping = array(); // Store classification box mapping $entities_predicates_mapping = null; // Save the entities coming with POST data. if (isset($_POST['wl_entities']) && isset($_POST['wl_boxes'])) { wl_write_log("[ post id :: {$post_id} ][ POST(wl_entities) :: "); wl_write_log(json_encode($_POST['wl_entities'])); wl_write_log("]"); wl_write_log("[ post id :: {$post_id} ][ POST(wl_boxes) :: "); wl_write_log(json_encode($_POST['wl_boxes'], true)); wl_write_log("]"); $entities_via_post = $_POST['wl_entities']; $boxes_via_post = $_POST['wl_boxes']; foreach ($entities_via_post as $entity_uri => $entity) { // Local entities have a tmp uri with 'local-entity-' // These uris need to be rewritten here and replaced in the content if (preg_match('/^local-entity-.+/', $entity_uri) > 0) { // Build the proper uri $uri = sprintf('%s/%s/%s', wl_configuration_get_redlink_dataset_uri(), 'entity', wl_sanitize_uri_path($entity['label'])); // Populate the mapping $entities_uri_mapping[$entity_uri] = $uri; // Override the entity obj $entities_via_post[$entity_uri]['uri'] = $uri; } } // Populate the $entities_predicates_mapping // Local Redlink uris need to be used here foreach ($boxes_via_post as $predicate => $entity_uris) { foreach ($entity_uris as $entity_uri) { wl_write_log("Going to map predicates for uri {$entity_uri} "); // Retrieve the entity label needed to build the uri $label = $entities_via_post[stripslashes($entity_uri)]['label']; $uri = sprintf('%s/%s/%s', wl_configuration_get_redlink_dataset_uri(), 'entity', wl_sanitize_uri_path($label)); wl_write_log("Going to map predicate {$predicate} to uri {$uri} "); $entities_predicates_mapping[$uri][] = $predicate; } } // Save entities and push them to Redlink // TODO: pass also latitude, longitude, etc. wl_save_entities(array_values($entities_via_post), $post_id); } // Replace tmp uris in content post if needed $updated_post_content = $post->post_content; // Save each entity and store the post id. foreach ($entities_uri_mapping as $tmp_uri => $uri) { $updated_post_content = str_replace($tmp_uri, $uri, $updated_post_content); } // Update the post content wp_update_post(array('ID' => $post->ID, 'post_content' => $updated_post_content)); // Extract related/referenced entities from text. $disambiguated_entities = wl_linked_data_content_get_embedded_entities($updated_post_content); // Reset previously saved instances wl_core_delete_relation_instances($post_id); // Save relation instances foreach (array_unique($disambiguated_entities) as $referenced_entity_id) { wl_write_log(" Going to manage relation between Post {$post_id} and {$referenced_entity_id}"); if ($entities_predicates_mapping) { wl_write_log(" Going to manage relation instances according to the following mapping"); // Retrieve the entity uri $referenced_entity_uri = wl_get_entity_uri($referenced_entity_id); // Retrieve predicates for the current uri if (isset($entities_predicates_mapping[$referenced_entity_uri])) { foreach ($entities_predicates_mapping[$referenced_entity_uri] as $predicate) { wl_write_log(" Going to add relation with predicate {$predicate}"); wl_core_add_relation_instance($post_id, $predicate, $referenced_entity_id); } } else { wl_write_log("Entity uri {$referenced_entity_uri} missing in the mapping"); wl_write_log($entities_predicates_mapping); } } else { // Just for unit tests wl_core_add_relation_instance($post_id, 'what', $referenced_entity_id); } // TODO Check if is needed wl_linked_data_push_to_redlink($referenced_entity_id); } // Push the post to Redlink. wl_linked_data_push_to_redlink($post->ID); add_action('wl_linked_data_save_post', 'wl_linked_data_save_post_and_related_entities'); }
/** * Test saving entities passed via a metabox. */ function testEntitiesViaArray() { // Create a post. $post_id = $this->createPost(); $this->assertTrue(is_numeric($post_id)); $post = get_post($post_id); $this->assertNotNull($post); // Read the entities from the mock-up analysis. $analysis_results = wl_parse_file(dirname(__FILE__) . '/' . self::FILENAME . '.json'); $this->assertTrue(is_array($analysis_results)); // For each entity get the label, type, description and thumbnails. $this->assertTrue(isset($analysis_results['entities'])); // Get a reference to the entities. $text_annotations = $analysis_results['text_annotations']; $best_entities = array(); foreach ($text_annotations as $id => $text_annotation) { $entity_annotation = wl_get_entity_annotation_best_match($text_annotation['entities']); $entity = $entity_annotation['entity']; $entity_id = $entity->{'@id'}; if (!array_key_exists($entity_id, $best_entities)) { $best_entities[$entity_id] = $entity; } } // Accumulate the entities in an array. $entities = array(); foreach ($best_entities as $uri => $entity) { // Label if (!isset($entity->{'http://www.w3.org/2000/01/rdf-schema#label'}->{'@value'})) { var_dump($entity); } $this->assertTrue(isset($entity->{'http://www.w3.org/2000/01/rdf-schema#label'}->{'@value'})); $label = $entity->{'http://www.w3.org/2000/01/rdf-schema#label'}->{'@value'}; $this->assertFalse(empty($label)); // Type // $type = wl_get_entity_type($entity); // $this->assertFalse(empty($type)); // Description $description = wl_get_entity_description($entity); $this->assertNotNull($description); // Images $images = wl_get_entity_thumbnails($entity); $this->assertTrue(is_array($images)); // Save the entity to the entities array. $entities = array_merge_recursive($entities, array($uri => array('uri' => $uri, 'label' => $label, 'main_type' => 'http://schema.org/Thing', 'type' => array(), 'description' => $description, 'images' => $images))); } // Save the entities in the array. $entity_posts = wl_save_entities($entities); // Publish $entity_post_ids = array_map(function ($item) { return $item->ID; }, $entity_posts); foreach ($entity_post_ids as $entity_id) { wp_publish_post($entity_id); } // TODO: need to bind entities with posts. wl_core_add_relation_instances($post_id, WL_WHAT_RELATION, $entity_post_ids); $this->assertCount(sizeof($entity_post_ids), wl_core_get_related_entity_ids($post_id)); // TODO: synchronize data. // NOTICE: this requires a published post! wl_linked_data_push_to_redlink($post_id); // Check that the entities are created in WordPress. $this->assertCount(count($entities), $entity_posts); // Check that each entity is bound to the post. $entity_ids = array(); foreach ($entity_posts as $post) { // Store the entity IDs for future checks. array_push($entity_ids, $post->ID); // Get the related posts IDs. $rel_posts = wl_core_get_related_post_ids($post->ID); $this->assertCount(1, $rel_posts); // The post must be the one the test created. $this->assertEquals($post_id, $rel_posts[0]); } // Check that the post references the entities. $rel_entities = wl_core_get_related_entity_ids($post_id); $this->assertEquals(count($entity_ids), count($rel_entities)); foreach ($entity_ids as $id) { $this->assertTrue(in_array($id, $rel_entities)); } // Check that the locally saved entities and the remotely saved ones match. $this->checkEntities($entity_posts); // Check that the locally saved post data match the ones on Redlink. $this->checkPost($post_id); // Check the post references, that they match between local and remote. $this->checkPostReferences($post_id); // Delete the post. $this->deletePost($post_id); }