function testFindByURI() { $entity_post_id = wl_create_post('', 'test_entity', 'Test Entity', 'draft', 'entity'); $entity_uri = wl_get_entity_uri($entity_post_id); wl_schema_set_value($entity_post_id, 'sameAs', 'http://example.org/entity/test_entity'); $same_as_array = wl_schema_get_value($entity_post_id, 'sameAs'); $this->assertTrue(is_array($same_as_array)); $this->assertEquals('http://example.org/entity/test_entity', $same_as_array[0]); wl_schema_set_value($entity_post_id, 'sameAs', array('http://example.org/entity/test_entity', 'http://data.example.org/entity/test_entity')); $same_as_array = wl_schema_get_value($entity_post_id, 'sameAs'); $this->assertTrue(is_array($same_as_array)); $this->assertEquals('http://example.org/entity/test_entity', $same_as_array[0]); $this->assertEquals('http://data.example.org/entity/test_entity', $same_as_array[1]); $post = wl_get_entity_post_by_uri('http://example.org/entity/test_entity'); $this->assertNotNull($post); $post = wl_get_entity_post_by_uri('http://data.example.org/entity/test_entity'); $this->assertNotNull($post); $same_as_uri = 'http://example.org/entity/test_entity2'; $entity_post_id = wl_create_post('', 'test_entity_2', 'Test Entity 2', 'draft', 'entity'); $entity_uri = wl_get_entity_uri($entity_post_id); wl_schema_set_value($entity_post_id, 'sameAs', $same_as_uri); $same_as_array = wl_schema_get_value($entity_post_id, 'sameAs'); $this->assertTrue(is_array($same_as_array)); $this->assertEquals($same_as_uri, $same_as_array[0]); $post = wl_get_entity_post_by_uri('http://example.org/entity/test_entity'); $this->assertNotNull($post); }
/** * Test set- and get- methods for schema properties */ function testSchemaProperty() { $place_id = wl_create_post('Entity 1 Text', 'entity-1', 'Entity 1 Title', 'publish', 'entity'); wl_schema_set_types($place_id, 'Place'); wl_schema_add_value($place_id, 'sameAs', 'http://dbpedia.org/resource/my-place'); wl_schema_add_value($place_id, 'sameAs', 'http://rdf.freebase.com/my-place'); wl_schema_set_value($place_id, 'latitude', 40.12); $event_id = wl_create_post("Entity 2 Text", 'entity-2', "Entity 2 Title", 'publish', 'entity'); wl_schema_set_types($event_id, 'Event'); wl_schema_set_value($event_id, 'sameAs', array('http://rdf.freebase.com/my-event', 'http://dbpedia.org/resource/my-event')); wl_schema_set_value($event_id, 'startDate', '2014-10-21'); // Positive tests $value = wl_schema_get_value($place_id, 'sameAs'); $this->assertEquals(array('http://rdf.freebase.com/my-place', 'http://dbpedia.org/resource/my-place'), $value); $value = wl_schema_get_value($place_id, 'latitude'); $this->assertEquals(array(40.12), $value); $value = wl_schema_get_value($event_id, 'sameAs'); $this->assertEquals(array('http://rdf.freebase.com/my-event', 'http://dbpedia.org/resource/my-event'), $value); $value = wl_schema_get_value($event_id, 'startDate'); $this->assertEquals(array('2014-10-21'), $value); // Negative tests $value = wl_schema_get_value($place_id, null); $this->assertEquals(null, $value); $value = wl_schema_get_value($place_id, 'startDate'); $this->assertEquals(null, $value); $value = wl_schema_get_value($place_id, 'http://invented_url/something'); $this->assertEquals(null, $value); //TODO: manage case of multiple values per property. }
/** * Add a value of the specified property for the entity, where * * @param $post_id numeric The numeric post ID. * @param $property_name string Name of the property (e.g. name, for the http://schema.org/name property). * @param $property_value mixed Value to save into the property (adding to already saved). * * @return array An array of values or NULL in case of no values (or error). */ function wl_schema_add_value($post_id, $property_name, $property_value) { if (!is_array($property_value)) { $property_value = array($property_value); } $old_values = wl_schema_get_value($post_id, $property_name); $merged_property_value = array_unique(array_merge($property_value, $old_values)); wl_schema_set_value($post_id, $property_name, $merged_property_value); }
function testMicrodataCompilingForAnEntityPage() { // A place $place_id = wl_create_post('', 'my-place', 'MyPlace', 'publish', 'entity'); wl_set_entity_main_type($place_id, 'http://schema.org/Place'); wl_schema_set_value($place_id, 'latitude', 40.12); wl_schema_set_value($place_id, 'longitude', 72.3); wl_schema_set_value($place_id, 'streetAddress', 'via del ciuccio 23'); // Compile markup for the given content $compiled_markup = _wl_content_embed_microdata($place_id, ''); $expected_markup = file_get_contents(dirname(__FILE__) . '/assets/microdata_compiling_entity_page.txt'); // Verify correct markup $this->assertEquals($this->prepareMarkup($expected_markup), $this->prepareMarkup($compiled_markup)); }
function testWL_Metabox_Field_uri_data() { // Create an entity of type Person $person_id = wl_create_post('', 'p', 'A person', 'publish', Wordlift_Entity_Service::TYPE_NAME); wl_set_entity_main_type($person_id, 'http://schema.org/Person'); wl_schema_set_value($person_id, 'author', 43); // Create an entity of type CreativeWork $creative_work_id = wl_create_post('', 'cw', 'A creative work', 'publish', Wordlift_Entity_Service::TYPE_NAME); wl_set_entity_main_type($creative_work_id, 'http://schema.org/CreativeWork'); wl_schema_set_value($creative_work_id, 'author', $person_id); // Set authorship // Create fake context global $post; $post = get_post($creative_work_id); // Build a single Field $author_custom_field = $this->getSampleCustomField(Wordlift_Schema_Service::DATA_TYPE_URI); $field = new WL_Metabox_Field_uri($author_custom_field); // Verify data is loaded correctly from DB $field->get_data(); $this->assertEquals(array($person_id), $field->data); // Save new DB values (third value is invalid and fourth is a new entity) $field->save_data(array($person_id, 'http://some-triplestore/person2', null, 'Annibale')); // Verify data is loaded correctly from DB $new_entity = get_page_by_title('Annibale', OBJECT, Wordlift_Entity_Service::TYPE_NAME); $field->get_data(); $this->assertEquals(array($person_id, 'http://some-triplestore/person2', $new_entity->ID), $field->data); }
/** * Save the specified data as an entity in WordPress. This method only create new entities. When an existing entity is * found (by its URI), then the original post is returned. * * @param array $entity_properties, associative array containing: * string 'uri' The entity URI. * string 'label' The entity label. * string 'main_type_uri' The entity type URI. * string 'description' The entity description. * array 'type_uris' An array of entity type URIs. * array 'images' An array of image URLs. * int 'related_post_id' A related post ID. * array 'same_as' An array of sameAs URLs. * * @return null|WP_Post A post instance or null in case of failure. */ function wl_save_entity($entity_properties) { $uri = $entity_properties['uri']; $label = $entity_properties['label']; $type_uri = $entity_properties['main_type_uri']; $description = $entity_properties['description']; $entity_types = $entity_properties['type_uris']; $images = $entity_properties['images']; $related_post_id = $entity_properties['related_post_id']; $same_as = $entity_properties['same_as']; // Avoid errors due to null. if (is_null($entity_types)) { $entity_types = array(); } wl_write_log("[ uri :: {$uri} ][ label :: {$label} ][ type uri :: {$type_uri} ]"); // Prepare properties of the new entity. $params = array('post_status' => is_numeric($related_post_id) ? get_post_status($related_post_id) : 'draft', 'post_type' => WL_ENTITY_TYPE_NAME, 'post_title' => $label, 'post_content' => $description, 'post_excerpt' => ''); // Check whether an entity already exists with the provided URI. $post = wl_get_entity_post_by_uri($uri); if (null !== $post) { // We insert into the params the entity ID, so it will be updated and not inserted. $params['ID'] = $post->ID; } // create or update the post. $post_id = wp_insert_post($params, true); // TODO: handle errors. if (is_wp_error($post_id)) { wl_write_log(': error occurred'); // inform an error occurred. return null; } wl_set_entity_main_type($post_id, $type_uri); // Save the entity types. wl_set_entity_rdf_types($post_id, $entity_types); // Get a dataset URI for the entity. $wl_uri = wl_build_entity_uri($post_id); // Save the entity URI. wl_set_entity_uri($post_id, $wl_uri); // Add the uri to the sameAs data if it's not a local URI. if ($wl_uri !== $uri) { array_push($same_as, $uri); } $new_uri = wl_get_entity_uri($post_id); // Save the sameAs data for the entity. wl_schema_set_value($post_id, 'sameAs', $same_as); // Call hooks. do_action('wl_save_entity', $post_id); wl_write_log("[ post id :: {$post_id} ][ uri :: {$uri} ][ label :: {$label} ][ wl uri :: {$wl_uri} ][ types :: " . implode(',', $entity_types) . " ][ images count :: " . count($images) . " ][ same_as count :: " . count($same_as) . " ]"); foreach ($images as $image_remote_url) { // Check if image is already present in local DB if (strpos($image_remote_url, site_url()) !== false) { // Do nothing. continue; } // Check if there is an existing attachment for this post ID and source URL. $existing_image = wl_get_attachment_for_source_url($post_id, $image_remote_url); // Skip if an existing image is found. if (null !== $existing_image) { continue; } // Save the image and get the local path. $image = wl_save_image($image_remote_url); // Get the local URL. $filename = $image['path']; $url = $image['url']; $content_type = $image['content_type']; $attachment = array('guid' => $url, 'post_title' => $label, 'post_content' => '', 'post_status' => 'inherit', 'post_mime_type' => $content_type); // Create the attachment in WordPress and generate the related metadata. $attachment_id = wp_insert_attachment($attachment, $filename, $post_id); // Set the source URL for the image. wl_set_source_url($attachment_id, $image_remote_url); $attachment_data = wp_generate_attachment_metadata($attachment_id, $filename); wp_update_attachment_metadata($attachment_id, $attachment_data); // Set it as the featured image. set_post_thumbnail($post_id, $attachment_id); } // The entity is pushed to Redlink on save by the function hooked to save_post. // save the entity in the triple store. wl_linked_data_push_to_redlink($post_id); // finally return the entity post. return get_post($post_id); }
/** * Save the specified data as an entity in WordPress. This method only create new entities. When an existing entity is * found (by its URI), then the original post is returned. * * @param array $entity_data, associative array containing: * string 'uri' The entity URI. * string 'label' The entity label. * string 'main_type' The entity type URI. * array 'type' An array of entity type URIs. * string 'description' The entity description. * array 'images' An array of image URLs. * int 'related_post_id' A related post ID. * array 'same_as' An array of sameAs URLs. * * @return null|WP_Post A post instance or null in case of failure. */ function wl_save_entity($entity_data) { $uri = $entity_data['uri']; $label = $entity_data['label']; $type_uri = $entity_data['main_type']; $entity_types = isset($entity_data['type']) ? $entity_data['type'] : array(); $description = $entity_data['description']; $images = isset($entity_data['image']) ? wl_force_to_array($entity_data['image']) : array(); $same_as = isset($entity_data['sameas']) ? wl_force_to_array($entity_data['sameas']) : array(); $related_post_id = isset($entity_data['related_post_id']) ? $entity_data['related_post_id'] : null; $other_properties = isset($entity_data['properties']) ? $entity_data['properties'] : array(); // wl_write_log( "[ uri :: $uri ][ label :: $label ][ type uri :: $type_uri ]" ); // Prepare properties of the new entity. $params = array('post_status' => is_numeric($related_post_id) ? get_post_status($related_post_id) : 'draft', 'post_type' => Wordlift_Entity_Service::TYPE_NAME, 'post_title' => $label, 'post_content' => $description, 'post_excerpt' => ''); // Check whether an entity already exists with the provided URI. $post = wl_get_entity_post_by_uri($uri); if (null !== $post) { // We insert into the params the entity ID, so it will be updated and not inserted. $params['ID'] = $post->ID; // Preserve the current entity status if ('public' === $post->post_status) { $params['post_status'] = $post->post_status; } // Preserve the current entity post_content. $params['post_content'] = $post->post_content; // Preserve the entity post_title to avoid de-synch between WP and RL // See: https://github.com/insideout10/wordlift-plugin/issues/221 $params['post_title'] = $post->post_title; } // If Yoast is installed and active, we temporary remove the save_postdata hook which causes Yoast to "pass over" // the local SEO form values to the created entity (https://github.com/insideout10/wordlift-plugin/issues/156) // Same thing applies to SEO Ultimate (https://github.com/insideout10/wordlift-plugin/issues/148) // This does NOT affect saving an entity from the entity admin page since this function is called when an entity // is created when saving a post. global $wpseo_metabox, $seo_ultimate; if (isset($wpseo_metabox)) { remove_action('wp_insert_post', array($wpseo_metabox, 'save_postdata')); } if (isset($seo_ultimate)) { remove_action('save_post', array($seo_ultimate, 'save_postmeta_box')); } // The fact that we're calling here wp_insert_post is causing issues with plugins (and ourselves too) that hook to // save_post in order to save additional inputs from the edit page. In order to avoid issues, we pop all the hooks // to the save_post and restore them after we saved the entity. // see https://github.com/insideout10/wordlift-plugin/issues/203 // see https://github.com/insideout10/wordlift-plugin/issues/156 // see https://github.com/insideout10/wordlift-plugin/issues/148 global $wp_filter; $save_post_filters = $wp_filter['save_post']; $wp_filter['save_post'] = array(); // create or update the post. $post_id = wp_insert_post($params, true); // Restore all the existing filters. $wp_filter['save_post'] = $save_post_filters; // If Yoast is installed and active, we restore the Yoast save_postdata hook (https://github.com/insideout10/wordlift-plugin/issues/156) if (isset($wpseo_metabox)) { add_action('wp_insert_post', array($wpseo_metabox, 'save_postdata')); } // If SEO Ultimate is installed, add back the hook we removed a few lines above. if (isset($seo_ultimate)) { add_action('save_post', array($seo_ultimate, 'save_postmeta_box'), 10, 2); } // TODO: handle errors. if (is_wp_error($post_id)) { wl_write_log(': error occurred'); // inform an error occurred. return null; } wl_set_entity_main_type($post_id, $type_uri); // Save the entity types. wl_set_entity_rdf_types($post_id, $entity_types); // Get a dataset URI for the entity. $wl_uri = wl_build_entity_uri($post_id); // Save the entity URI. wl_set_entity_uri($post_id, $wl_uri); // Add the uri to the sameAs data if it's not a local URI. if ($wl_uri !== $uri) { array_push($same_as, $uri); } $new_uri = wl_get_entity_uri($post_id); // Save the sameAs data for the entity. wl_schema_set_value($post_id, 'sameAs', $same_as); // Save the other properties (latitude, langitude, startDate, endDate, etc.) foreach ($other_properties as $property_name => $property_value) { wl_schema_set_value($post_id, $property_name, $property_value); } // Call hooks. do_action('wl_save_entity', $post_id); wl_write_log("[ post id :: {$post_id} ][ uri :: {$uri} ][ label :: {$label} ][ wl uri :: {$wl_uri} ][ types :: " . implode(',', $entity_types) . " ][ images count :: " . count($images) . " ][ same_as count :: " . count($same_as) . " ]"); foreach ($images as $image_remote_url) { // Check if image is already present in local DB if (strpos($image_remote_url, site_url()) !== false) { // Do nothing. continue; } // Check if there is an existing attachment for this post ID and source URL. $existing_image = wl_get_attachment_for_source_url($post_id, $image_remote_url); // Skip if an existing image is found. if (null !== $existing_image) { continue; } // Save the image and get the local path. $image = wl_save_image($image_remote_url); // Get the local URL. $filename = $image['path']; $url = $image['url']; $content_type = $image['content_type']; $attachment = array('guid' => $url, 'post_title' => $label, 'post_content' => '', 'post_status' => 'inherit', 'post_mime_type' => $content_type); // Create the attachment in WordPress and generate the related metadata. $attachment_id = wp_insert_attachment($attachment, $filename, $post_id); // Set the source URL for the image. wl_set_source_url($attachment_id, $image_remote_url); $attachment_data = wp_generate_attachment_metadata($attachment_id, $filename); wp_update_attachment_metadata($attachment_id, $attachment_data); // Set it as the featured image. set_post_thumbnail($post_id, $attachment_id); } // The entity is pushed to Redlink on save by the function hooked to save_post. // save the entity in the triple store. wl_linked_data_push_to_redlink($post_id); // finally return the entity post. return get_post($post_id); }
function testMicrodataCompilingRecursivityLimitation() { // A place $place_id = wl_create_post('Just a place', 'my-place', 'MyPlace', 'publish', 'entity'); wl_set_entity_main_type($place_id, 'http://schema.org/Place'); // Trying out both the schema API and the classic WP method wl_schema_set_value($place_id, 'latitude', 40.12); add_post_meta($place_id, WL_CUSTOM_FIELD_GEO_LONGITUDE, 72.3, true); // An Event having as location the place above $event_id = wl_create_post('Just an event', 'my-event', 'MyEvent', 'publish', 'entity'); wl_set_entity_main_type($event_id, 'http://schema.org/Event'); add_post_meta($event_id, WL_CUSTOM_FIELD_CAL_DATE_START, '2014-10-21', true); add_post_meta($event_id, WL_CUSTOM_FIELD_CAL_DATE_END, '2015-10-26', true); wl_schema_set_value($event_id, 'sameAs', array('http://rdf.freebase.com/my-event', 'http://dbpedia.org/resource/my-event')); //wl_schema_set_value($event_id, 'sameAs', 'http://dbpedia.org/resource/my-event'); add_post_meta($event_id, WL_CUSTOM_FIELD_LOCATION, $place_id, true); // Create an annotated post containing the entities $entity_uri = wl_get_entity_uri($event_id); $content = <<<EOF <span itemid="{$entity_uri}">MyEvent</span> EOF; $post_id = wl_create_post($content, 'post', 'A post'); // Set to 0 the recursivity limitation on entity metadata compiling $this->setRecursionDepthLimit(0); // The expected mark-up expects color coding to be on. wl_configuration_set_enable_color_coding(true); // Compile markup for the given content $compiled_markup = _wl_content_embed_microdata($post_id, $content); $expected_markup = file_get_contents(dirname(__FILE__) . '/assets/microdata_compiling_recursivity_limitation.txt'); // Verify correct markup $this->assertEquals($this->prepareMarkup($expected_markup), $this->prepareMarkup($compiled_markup)); $this->setRecursionDepthLimit(1); // Compile markup for the given content $compiled_markup = _wl_content_embed_microdata($post_id, $content); $expected_markup = file_get_contents(dirname(__FILE__) . '/assets/microdata_compiling_for_an_entity_with_nested_entities.txt'); // Verify correct markup $this->assertEquals($this->prepareMarkup($expected_markup), $this->prepareMarkup($compiled_markup)); }
function createSampleEntity() { $entity_post_id = wl_create_post('Lorem Ipsum', 'honda', 'Honda', 'publish', 'entity'); wl_schema_set_value($entity_post_id, 'sameAs', 'http://dbpedia.org/resource/Honda'); }