/**
 * Serialize an entity post.
 *
 * @param array $entity The entity post or the entity post id.
 *
 * @return array mixed The entity data array.
 */
function wl_serialize_entity($entity)
{
    $entity = is_numeric($entity) ? get_post($entity) : $entity;
    $type = wl_entity_type_taxonomy_get_type($entity->ID);
    $images = wl_get_image_urls($entity->ID);
    return array('id' => wl_get_entity_uri($entity->ID), 'label' => $entity->post_title, 'description' => wp_strip_all_tags($entity->post_content), 'sameAs' => wl_schema_get_value($entity->ID, 'sameAs'), 'mainType' => str_replace('wl-', '', $type['css_class']), 'types' => wl_get_entity_rdf_types($entity->ID), 'images' => $images);
}
 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 testSavePlaceWithCoordinates()
 {
     $entity_props = array('uri' => 'http://dbpedia.org/resource/Frattocchie', 'label' => 'Frattocchie', 'main_type' => 'http://schema.org/Place', 'description' => 'best place on hearth, where the porchetta freely flows', 'same_as' => array('http://dbpedia.org/resource/Frattocchie', 'http://frattocchie.com/love'), 'properties' => array('latitude' => array(43.21), 'longitude' => 12.34, 'fake' => array('must', 'not', 'be', 'saved')));
     $entity_post = wl_save_entity($entity_props);
     $this->assertNotNull($entity_post);
     // Check that the type is set correctly.
     $this->assertEquals(array('http://schema.org/Place'), wl_schema_get_types($entity_post->ID));
     // Check coordinates
     $this->assertEquals(array(43.21), wl_schema_get_value($entity_post->ID, 'latitude'));
     $this->assertEquals(array(12.34), wl_schema_get_value($entity_post->ID, 'longitude'));
     // Check invalid property
     $this->assertEquals(null, wl_schema_get_value($entity_post->ID, 'fake'));
 }
/**
 * Print wl_field shortcode
 *
 * @param array $atts An array of shortcode attributes.
 * @return string A dom element with requested property value(s).
 */
function wl_shortcode_field($atts)
{
    // Extract attributes and set default values.
    $field_atts = shortcode_atts(array('id' => null, 'name' => null), $atts);
    // Get id of the post
    $entity_id = $field_atts['id'];
    if (is_null($field_atts['id']) || !is_numeric($field_atts['id'])) {
        $entity_id = get_the_ID();
    }
    $property_name = $field_atts['name'];
    if (!is_null($property_name)) {
        $values = wl_schema_get_value($entity_id, $property_name);
    }
    // Return
    if (is_array($values)) {
        return implode(', ', $values);
    } else {
        return null;
    }
}
    function testEntityMetadataAreProperlyUpdated()
    {
        $fake = $this->prepareFakeGlobalPostArrayFromFile('/assets/fake_global_post_array_with_one_entity_linked_as_what.json');
        $_POST = $fake;
        // Retrieve the entity uri (the first key in wl_entities associative aray)
        $original_entity_uri = current(array_keys($fake['wl_entities']));
        // Reference the entity to the post content
        $content = <<<EOF
    <span itemid="{$original_entity_uri}">My entity</span>
EOF;
        // Create a post referincing to the created entity
        $post_id = wl_create_post($content, 'my-post', 'A post', 'draft');
        // Here the entity should have been created
        $original_entity = wl_get_entity_post_by_uri($original_entity_uri);
        $this->assertNotNull($original_entity);
        // Store entity type, images and sameAs (needed later)
        $original_type = wl_schema_get_types($original_entity->ID);
        $original_thumbnails = $this->getThumbs($original_entity->ID);
        $original_sameAs = wl_schema_get_value($original_entity->ID, 'sameAs');
        // Query the same entity using the Redlink URI
        $entity_uri = wl_get_entity_uri($original_entity->ID);
        $e = wl_get_entity_post_by_uri($entity_uri);
        $this->assertEquals($original_entity, $e);
        // The entity description should be the same we expect
        $raw_entity = current(array_values($fake['wl_entities']));
        $this->assertEquals($raw_entity['description'], $original_entity->post_content);
        // The entity is related as what predicate
        $related_entity_ids = wl_core_get_related_entity_ids($post_id, array("predicate" => "what"));
        $this->assertCount(1, $related_entity_ids);
        // Ensure there are no other relation instances
        $relation_instances = wl_tests_get_relation_instances_for($post_id);
        $this->assertCount(1, $relation_instances);
        /* Now Post is saved again with the same mentioned entity:
         * - with different type
         * - with different description
         * - with one more image
         * - with one modified sameAs
         * - as WHO instead fo WHAT
         */
        $fake = $this->prepareFakeGlobalPostArrayFromFile('/assets/fake_global_post_array_with_one_entity_linked_as_who_and_modified_data.json');
        $_POST = $fake;
        // The entity url should be the same we expect
        $raw_entity = current(array_values($fake['wl_entities']));
        $raw_entity_uri = $raw_entity['uri'];
        $new_content = <<<EOF
    <span itemid="{$raw_entity_uri}">My entity</span>
EOF;
        // Update the post content (to force existing entities update)
        wp_update_post(array('ID' => $post_id, 'post_content' => $new_content));
        // Verify the mentioned entity was already into DB...
        $updated_entity = wl_get_entity_post_by_uri($raw_entity_uri);
        $this->assertEquals($original_entity->ID, $updated_entity->ID);
        $this->assertEquals($original_entity->post_title, $updated_entity->post_title);
        // ... but some properties changed!
        $this->assertNotEquals($original_entity, $updated_entity);
        // Verify entity type has been updated
        $updated_type = wl_schema_get_types($updated_entity->ID);
        $this->assertNotEquals($original_type, $updated_type);
        $this->assertEquals(array('http://schema.org/Organization'), $updated_type);
        // Verify entity description has been updated
        $this->assertEquals($raw_entity['description'], $updated_entity->post_content);
        // Verify entity images have been updated (one was added)
        $updated_thumbnails = $this->getThumbs($updated_entity->ID);
        $this->assertNotEquals($original_thumbnails, $updated_thumbnails);
        $this->assertContains($original_thumbnails[0], $updated_thumbnails);
        $this->assertCount(2, $updated_thumbnails);
        // There is one more
        $this->assertContains('Netherlands_vs_Ivory_Coast', $updated_thumbnails[1]);
        // ... about soccer
        // Verify entity sameAs have been updated
        $updated_sameAs = wl_schema_get_value($updated_entity->ID, 'sameAs');
        $this->assertNotEquals($original_sameAs, $updated_sameAs);
        $this->assertContains($original_sameAs[1], $updated_sameAs);
        $this->assertNotContains($original_sameAs[0], $updated_sameAs);
        $this->assertContains('http://sv.dbpedia.org/page/Reason', $updated_sameAs);
        // Verify the entity is now related as who predicate
        $related_entity_ids = wl_core_get_related_entity_ids($post_id, array("predicate" => "who"));
        $this->assertCount(1, $related_entity_ids);
        // Ensure there are no other relation instances
        $relation_instances = wl_tests_get_relation_instances_for($post_id);
        $this->assertCount(1, $relation_instances);
    }
/**
 * Displays the sameAs meta box contents (called by *add_meta_box* callback).
 *
 * @param WP_Post $post The current post.
 */
function wl_entities_sameas_box_content($post)
{
    // Set nonce for both meta (latitude and longitude)
    wl_echo_nonce(WL_CUSTOM_FIELD_SAME_AS);
    // Get sameAs
    $sameAs = implode("\n", wl_schema_get_value($post->ID, 'sameAs'));
    // Print input textarea. The user writes here the sameAs URIs, separated by \n.
    echo '<textarea style="width: 100%;" id="wl_same_as" placeholder="Same As URLs, one per row">' . esc_attr($sameAs) . '</textarea>';
    echo '<div id="wl_same_as_list"></div>';
    // Input tags are updated at each change to contain the rows typed in the textarea
    echo <<<EOF
        <script>
            \$ = jQuery;
            \$(document).ready(function(){
        
                refreshSameAsList();    // refresh now and at every change event
                \$("#wl_same_as").on("change keyup paste", function(){
                    refreshSameAsList();
                });
                
                function refreshSameAsList() {
                    \$("#wl_same_as_list").empty();

                    var sameAsList = \$("#wl_same_as").val();
                    sameAsList = sameAsList.split('\\n');
                    console.log(sameAsList);
                    
                    for(var i=0; i<sameAsList.length; i++){
                        // some validation
                        if(sameAsList[i].indexOf("http") == 0){
        
                            // Refresh input tags
                            \$("#wl_same_as_list").append(
                                '<input type="hidden" name="wl_metaboxes[entity_same_as][' + i + ']" value="' + sameAsList[i] + '" />'
                            );
                        }
                    }
                }
            });
        </script>
EOF;
}
/**
 * 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);
}
    function testEntityAdditionalPropertiesAreSaved()
    {
        $fake = $this->prepareFakeGlobalPostArrayFromFile('/assets/fake_global_post_array_with_a_new_entity_linked_as_where_with_coordinates.json');
        $_POST = $fake;
        // Retrieve the entity uri (the first key in wl_entities associative aray)
        $entity_uri = current(array_keys($fake['wl_entities']));
        // Retrieve the label and compose expected uri
        $raw_entity = current(array_values($fake['wl_entities']));
        $expected_entity_uri = $this->buildEntityUriForLabel($raw_entity['label']);
        // Reference the entity to the post content
        $content = <<<EOF
    <span itemid="{$entity_uri}">My entity</span>
EOF;
        // Create a post referincing to the created entity
        $post_id = wl_create_post($content, 'my-post', 'A post', 'draft');
        // Here the entity should have been created
        $entity = wl_get_entity_post_by_uri($expected_entity_uri);
        $this->assertNotNull($entity);
        // Verify association to post as where
        $related_entity_ids = wl_core_get_related_entity_ids($post_id, array("predicate" => "where"));
        $this->assertEquals(array($entity->ID), $related_entity_ids);
        // Verify schema type
        $this->assertEquals(array('http://schema.org/Place'), wl_schema_get_types($entity->ID));
        // Verify coordinates
        $this->assertEquals(array(43.21), wl_schema_get_value($entity->ID, 'latitude'));
        $this->assertEquals(array(12.34), wl_schema_get_value($entity->ID, 'longitude'));
    }
Beispiel #11
0
/**
 * Get the coordinates for the specified post ID.
 *
 * @param int $post_id The post ID.
 *
 * @return array|null An array of coordinates or null.
 */
function wl_get_coordinates($post_id)
{
    $latitude = wl_schema_get_value($post_id, 'latitude');
    $longitude = wl_schema_get_value($post_id, 'longitude');
    // DO NOT set latitude/longitude to 0/0 as default values. It's a specific place on the globe:
    // "The zero/zero point of this system is located in the Gulf of Guinea about 625 km (390 mi) south of Tema, Ghana."
    return array('latitude' => isset($latitude[0]) && is_numeric($latitude[0]) ? $latitude[0] : '', 'longitude' => isset($longitude[0]) && is_numeric($longitude[0]) ? $longitude[0] : '');
}
/**
 * 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);
}
/**
 * Fills up the microdata_template with entity's values.
 *
 * @param string $entity_id An entity ID.
 * @param string $entity_type Entity type stracture.
 * @param integer $recursion_level Recursion depth level in microdata compiling. Recursion depth limit is defined by WL_MAX_NUM_RECURSIONS_WHEN_PRINTING_MICRODATA constant.
 *
 * @return string The content with embedded microdata.
 */
function wl_content_embed_compile_microdata_template($entity_id, $entity_type, $recursion_level = 0)
{
    wl_write_log("[ entity id :: {$entity_id} ][ entity type :: " . var_export($entity_type, true) . " ][ recursion level :: {$recursion_level} ]");
    $regex = '/{{(.*?)}}/';
    $matches = array();
    if (null === $entity_type) {
        return '';
    }
    $template = $entity_type['microdata_template'];
    // Return empty string if template fields have not been found.
    if (false === preg_match_all($regex, $template, $matches, PREG_SET_ORDER)) {
        return '';
    }
    foreach ($matches as $match) {
        $placeholder = $match[0];
        $field_name = $match[1];
        // Get property value.
        $meta_collection = wl_schema_get_value($entity_id, $field_name);
        // If no value is given, just remove the placeholder from the template
        if (null == $meta_collection) {
            $template = str_replace($placeholder, '', $template);
            continue;
        }
        // What kind of value is it?
        // TODO: Performance issue here: meta type retrieving should be centralized
        $expected_type = wl_get_meta_type($field_name);
        foreach ($meta_collection as $field_value) {
            if (WL_DATA_TYPE_URI == $expected_type) {
                // If is a numeric value we assume it is an ID referencing for an internal entity.
                if (is_numeric($field_value)) {
                    // Found id, get uri.
                    $field_value = wl_get_entity_uri($field_value);
                }
                // Just if the linked entity does exist I can go further with template compiling
                $nested_entity = wl_get_entity_post_by_uri($field_value);
                if (!is_null($nested_entity)) {
                    $content = '<span itemid="' . esc_attr($field_value) . '">' . $nested_entity->post_title . '</span>';
                    $compiled_template = wl_content_embed_item_microdata($content, $field_value, $field_name, ++$recursion_level);
                    $template = str_replace($placeholder, $compiled_template, $template);
                } else {
                    $template = str_replace($placeholder, '', $template);
                }
                continue;
            }
            // Standard condition: field containing a raw value
            $value = '<span itemprop="' . esc_attr($field_name) . '" content="' . esc_attr($field_value) . '"></span>';
            $template = str_replace($placeholder, $value, $template);
        }
    }
    return $template;
}
/**
 * Fills up the microdata_template with entity's values.
 *
 * @param string $entity_id An entity ID.
 * @param string $entity_type Entity type structure.
 * @param integer $recursion_level Recursion depth level in microdata compiling. Recursion depth limit is defined by WL_MAX_NUM_RECURSIONS_WHEN_PRINTING_MICRODATA constant.
 *
 * @return string The content with embedded microdata.
 */
function wl_content_embed_compile_microdata_template($entity_id, $entity_type, $recursion_level = 0)
{
    global $wl_logger;
    if (WP_DEBUG) {
        $wl_logger->trace("Embedding microdata [ entity id :: {$entity_id} ][ entity type :: " . var_export($entity_type, true) . " ][ recursion level :: {$recursion_level} ]");
    }
    $regex = '/{{(.*?)}}/';
    $matches = array();
    if (null === $entity_type) {
        return '';
    }
    $template = $entity_type['microdata_template'];
    // Return empty string if template fields have not been found.
    if (false === preg_match_all($regex, $template, $matches, PREG_SET_ORDER)) {
        return '';
    }
    foreach ($matches as $match) {
        $placeholder = $match[0];
        $field_name = $match[1];
        // Get property value.
        $meta_collection = wl_schema_get_value($entity_id, $field_name);
        // If no value is given, just remove the placeholder from the template
        if (null == $meta_collection) {
            $template = str_replace($placeholder, '', $template);
            continue;
        }
        // What kind of value is it?
        // TODO: Performance issue here: meta type retrieving should be centralized
        $expected_type = wl_get_meta_type($field_name);
        if (WP_DEBUG) {
            $wl_logger->trace("Embedding microdata [ placeholder :: {$placeholder} ][ field name :: {$field_name} ][ meta collection :: " . (is_array($meta_collection) ? var_export($meta_collection, true) : $meta_collection) . " ][ expected type :: {$expected_type} ]");
        }
        foreach ($meta_collection as $field_value) {
            // Quick and dirty patch for #163:
            //  - only apply to URIs, i.e. to properties pointing to another post ( $field_value should be a post ID ),
            //  - check that $field_value is actually a number,
            //  - check that the referenced post is published.
            //  OR
            //  - if the value is empty then we don't display it.
            if (Wordlift_Schema_Service::DATA_TYPE_URI === $expected_type && is_numeric($field_value) && 'publish' !== ($post_status = get_post_status($field_value)) || empty($field_value)) {
                if (WP_DEBUG) {
                    $wl_logger->trace("Microdata refers to a non-published post [ field value :: {$field_value} ][ post status :: {$post_status} ]");
                }
                // Remove the placeholder.
                $template = str_replace($placeholder, '', $template);
                continue;
            }
            if (Wordlift_Schema_Service::DATA_TYPE_URI == $expected_type) {
                // If is a numeric value we assume it is an ID referencing for an internal entity.
                if (is_numeric($field_value)) {
                    // Found id, get uri.
                    $field_value = wl_get_entity_uri($field_value);
                }
                // Just if the linked entity does exist I can go further with template compiling
                $nested_entity = wl_get_entity_post_by_uri($field_value);
                if (!is_null($nested_entity)) {
                    $content = '<span itemid="' . esc_attr($field_value) . '">' . $nested_entity->post_title . '</span>';
                    $compiled_template = wl_content_embed_item_microdata($content, $field_value, $field_name, ++$recursion_level);
                    $template = str_replace($placeholder, $compiled_template, $template);
                } else {
                    $template = str_replace($placeholder, '', $template);
                }
                continue;
            }
            // Standard condition: field containing a raw value
            // For non visible test, schema.org dictates to use the *meta* tag.
            // see http://schema.org/docs/gs.html#advanced_missing
            $value = '<meta itemprop="' . esc_attr($field_name) . '" content="' . esc_attr($field_value) . '" />';
            $template = str_replace($placeholder, $value, $template);
        }
    }
    return $template;
}
Beispiel #15
0
/**
 * Get the coordinates for the specified post ID.
 *
 * @param int $post_id The post ID.
 *
 * @return array|null An array of coordinates or null.
 */
function wl_get_coordinates($post_id)
{
    $latitude = wl_schema_get_value($post_id, 'latitude');
    $longitude = wl_schema_get_value($post_id, 'longitude');
    // Default coords values [0, 0]
    if (!isset($latitude[0]) || !is_numeric($latitude[0])) {
        $latitude = 0.0;
    } else {
        $latitude = floatval($latitude[0]);
    }
    if (!isset($longitude[0]) || !is_numeric($longitude[0])) {
        $longitude = 0.0;
    } else {
        $longitude = floatval($longitude[0]);
    }
    return array('latitude' => $latitude, 'longitude' => $longitude);
}