/**
  * Perform redirect depending on entity uri and target
  *
  * @since 3.2.0
  */
 public function ajax_redirect()
 {
     if (!isset($_GET['uri'])) {
         wp_die('Entity uri missing');
     }
     if (!isset($_GET['to'])) {
         wp_die('Redirect target missing');
     }
     // Get the entity uri
     $entity_uri = $_GET['uri'];
     // Get the redirect target
     $target = $_GET['to'];
     if (null === ($entity_id = $this->entity_service->get_entity_post_by_uri($entity_uri))) {
         wp_die('Entity not found');
     }
     switch ($target) {
         case 'edit':
             $redirect_url = get_edit_post_link($entity_id, 'none');
             break;
         case 'lod':
             $redirect_url = self::LOD_ENDPOINT . '/lodview/?IRI=' . urlencode($entity_uri);
             break;
         case 'permalink':
             $redirect_url = get_permalink($entity_id);
             break;
         default:
             wp_die('Unsupported redirect target');
     }
     // Perform the redirect
     wp_safe_redirect($redirect_url);
 }
 /**
  * Test the {@link get_alternative_labels} function by creating an entity and checking that the number of alternative
  * labels matches the one we set via {@link save_post}.
  *
  * @since 3.2.0
  */
 function test_get_alternative_labels()
 {
     $entity_service = Wordlift_Entity_Service::get_instance();
     // Create a test entity.
     $entity_id = wl_create_post('This is Entity 1', 'entity-1', 'Entity 1', 'publish', 'entity');
     wl_set_entity_main_type($entity_id, 'http://schema.org/Thing');
     // Check that we have no alternative labels.
     $this->assertCount(0, $entity_service->get_alternative_labels($entity_id));
     // Call save_post to set the alternative labels, mock the request first.
     $_REQUEST['wl_alternative_label'] = array('ABC 1', 'ABD 2', 'EFG 3');
     $entity_service->save_post($entity_id, null, null);
     // Check that we have 3 alternative labels.
     $this->assertCount(3, $entity_service->get_alternative_labels($entity_id));
     $this->assertCount(2, wl_entity_get_by_title('AB', true));
     // Call save_post to set the alternative labels, mock the request first.
     $_REQUEST['wl_alternative_label'] = array('ABC 1', 'ABD 2');
     $entity_service->save_post($entity_id, null, null);
     // Check that we have 2 alternative labels.
     $this->assertCount(2, $entity_service->get_alternative_labels($entity_id));
     $this->assertCount(2, wl_entity_get_by_title('AB', true));
     // Call save_post to set the alternative labels, mock the request first.
     $_REQUEST['wl_alternative_label'] = array();
     $entity_service->save_post($entity_id, null, null);
     // Check that we have no alternative labels.
     $this->assertCount(0, $entity_service->get_alternative_labels($entity_id));
     $this->assertCount(0, wl_entity_get_by_title('AB'));
 }
 /**
  * Retrieve timeline events.
  *
  * @since 3.1.0
  *
  * @uses wl_core_get_related_entity_ids() to retrieve the entities referenced by the specified post.
  *
  * @param int $post_id The post ID.
  *
  * @return array An array of event posts.
  */
 public function get_events($post_id = null)
 {
     // Get the entity IDs either from the entities related to the specified post or from the last 50 published
     // posts if no post has been specified.
     $ids = is_numeric($post_id) ? wl_core_get_related_entity_ids($post_id) : $this->entity_service->get_all_related_to_last_50_published_posts();
     // Add the post itself if it's an entity.
     if (is_numeric($post_id) && $this->entity_service->is_entity($post_id)) {
         $ids[] = $post_id;
     }
     // If there's no entities, return an empty array right away.
     if (0 === sizeof($ids)) {
         $this->log_service->trace("No events found [ post id :: {$post_id} ]");
         return array();
     }
     $this->log_service->trace("Getting events [ entity ids :: " . join(', ', $ids) . " ]");
     return get_posts(array('post__in' => $ids, 'post_type' => Wordlift_Entity_Service::TYPE_NAME, 'post_status' => 'publish', 'posts_per_page' => -1, 'meta_query' => array('relation' => 'AND', array('key' => Wordlift_Schema_Service::FIELD_DATE_START, 'value' => null, 'compare' => '!='), array('key' => Wordlift_Schema_Service::FIELD_DATE_END, 'value' => null, 'compare' => '!=')), 'tax_query' => array('taxonomy' => Wordlift_Entity_Types_Taxonomy_Service::TAXONOMY_NAME, 'field' => 'slug', 'terms' => 'event')));
 }
예제 #4
0
 /**
  * Test the wl_entity_get_by_title method.
  */
 function testGetByTitle1()
 {
     // We're starting up with no entities, we expect 0 entities.
     $posts_1 = wl_entity_get_by_title('Test Entity');
     $this->assertCount(0, $posts_1);
     // Create an entity and see that it is found.
     $post_id_2 = wl_create_post('Lorem Ipsum', 'test-entity-2', 'Test Entity', 'draft', Wordlift_Entity_Service::TYPE_NAME);
     $posts_2 = wl_entity_get_by_title('Test Entity');
     $this->assertCount(1, $posts_2);
     $this->assertEquals($post_id_2, $posts_2[0]->id);
     // Create another entity and see that it is found too.
     $post_id_3 = wl_create_post('Lorem Ipsum', 'test-entity-3', 'Test Entity', 'publish', Wordlift_Entity_Service::TYPE_NAME);
     $posts_3 = wl_entity_get_by_title('Test Entity');
     $this->assertCount(2, $posts_3);
     $this->assertEquals($post_id_2, $posts_3[0]->id);
     $this->assertEquals($post_id_3, $posts_3[1]->id);
     // Create another entity and see that it is NOT found.
     $post_id_4 = wl_create_post('Lorem Ipsum', 'test-entity-4', 'Test Entity 4', 'publish', Wordlift_Entity_Service::TYPE_NAME);
     $posts_4 = wl_entity_get_by_title('Test Entity');
     $this->assertCount(2, $posts_3);
     $this->assertEquals($post_id_2, $posts_4[0]->id);
     $this->assertEquals($post_id_3, $posts_4[1]->id);
     // Now make a LIKE search by hacking on the search param and see that it is found.
     $posts_5 = wl_entity_get_by_title('Test Entity%');
     $this->assertCount(3, $posts_5);
     $this->assertEquals($post_id_2, $posts_5[0]->id);
     $this->assertEquals($post_id_3, $posts_5[1]->id);
     $this->assertEquals($post_id_4, $posts_5[2]->id);
     // Now make a LIKE search using the $autocomplete param
     $posts_5 = wl_entity_get_by_title('Test Entity', true);
     $this->assertCount(3, $posts_5);
     $this->assertEquals($post_id_2, $posts_5[0]->id);
     $this->assertEquals($post_id_3, $posts_5[1]->id);
     $this->assertEquals($post_id_4, $posts_5[2]->id);
     // Entity service instance
     $entity_service = Wordlift_Entity_Service::get_instance();
     // Verify non existence of 'an alias'
     $this->assertCount(0, wl_entity_get_by_title('an alias', false, true));
     // Assign alias to entity 2 and verify it gets found
     $entity_service->set_alternative_labels($post_id_2, 'an alias');
     $this->assertCount(1, wl_entity_get_by_title('an alias'));
     // The alias above should not be found if we don't ask for aliases
     $this->assertCount(0, wl_entity_get_by_title('an alias', false, false));
 }
 /**
  * Render custom columns
  * @see https://codex.wordpress.org/Plugin_API/Action_Reference/manage_$post_type_posts_custom_column
  *
  * @since 3.3.0
  *
  * @param string $column the current column.
  * @param int $entity_id An entity post id.
  *
  * @return true if the post is an entity otherwise false.
  */
 public function render_custom_columns($column, $entity_id)
 {
     switch ($column) {
         case 'wl_column_related_posts':
             echo count(wl_core_get_related_post_ids($entity_id));
             break;
         case 'wl_column_thumbnail':
             $edit_link = get_edit_post_link($entity_id);
             $thumb = get_the_post_thumbnail($entity_id, array(self::THUMB_SIZE, self::THUMB_SIZE));
             if (!$thumb) {
                 $thumb = "<img src='" . WL_DEFAULT_THUMBNAIL_PATH . "' width='" . self::THUMB_SIZE . "' />";
             }
             echo "<a href='{$edit_link}'>{$thumb}</a>";
             break;
         case 'wl_column_rating':
             $rating = $this->entity_service->get_rating_for($entity_id);
             echo '<i class="wl-traffic-light wl-tl-' . $rating['traffic_light_score'] . '">' . $rating['percentage_score'] . '%</i>';
             break;
     }
 }
/**
 * Retrieve geomap places. If $post_id is null the return places blog wide
 *
 * @uses wl_core_get_related_entities() to retrieve the entities referenced by the specified post.
 *
 * @param int $post_id The post ID.
 *
 * @return array An array of place posts.
 */
function wl_shortcode_geomap_get_places($post_id = null)
{
    // If $post_id is null or is not numeric it means this is a global geomap
    $is_global = is_null($post_id) || !is_numeric($post_id);
    // If the current one is not a global geomap, retrieve related entities ids
    if ($is_global) {
        $related_ids = array();
    } else {
        $related_ids = wl_core_get_related_entity_ids($post_id, array('status' => 'publish'));
        // Also include current entity
        if (Wordlift_Entity_Service::get_instance()->is_entity($post_id)) {
            $related_ids[] = $post_id;
        }
    }
    // If is not a global geomap, an empty $related_ids means that no entities are related to the post
    // An empty array can be returned in this case
    if (!$is_global && empty($related_ids)) {
        return array();
    }
    // Retrieve all 'published' places with geo coordinates defined
    // If $related_ids is not empty, it's used to limit query results to the current post related places
    // Please note that when $place_ids is an empty array, the 'post__in' parameter is not considered in the query
    return get_posts(array('post__in' => $related_ids, 'post_type' => Wordlift_Entity_Service::TYPE_NAME, 'nopaging' => true, 'post_status' => 'publish', 'meta_query' => array('relation' => 'AND', array('key' => Wordlift_Schema_Service::FIELD_GEO_LATITUDE, 'value' => null, 'compare' => '!='), array('key' => Wordlift_Schema_Service::FIELD_GEO_LONGITUDE, 'value' => null, 'compare' => '!=')), 'tax_query' => array('taxonomy' => Wordlift_Entity_Types_Taxonomy_Service::TAXONOMY_NAME, 'field' => 'slug', 'terms' => 'place')));
}
/**
 * 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);
}
 /**
  * Create a Wordlift_Entity_Service instance.
  *
  * @since 3.2.0
  *
  * @param \Wordlift_UI_Service $ui_service The UI service.
  */
 public function __construct($ui_service, $schema_service, $notice_service)
 {
     $this->log_service = Wordlift_Log_Service::get_logger('Wordlift_Entity_Service');
     // Set the UI service.
     $this->ui_service = $ui_service;
     // Set the Schema service.
     $this->schema_service = $schema_service;
     // Set the Schema service.
     $this->notice_service = $notice_service;
     // Set the singleton instance.
     self::$instance = $this;
 }
    function testEntityWithAlternativeLabelIsProperlyOverridden()
    {
        $original_label = uniqid('entity-original', true);
        // Create an entity
        $entity_id = wl_create_post('', 'entity-1', $original_label, 'draft', 'entity');
        // Check that there are no related posts for the entity
        $related_post_ids = wl_core_get_related_post_ids($entity_id, array("predicate" => "what"));
        $this->assertCount(0, $related_post_ids);
        // Generate e label and set it as alternative label for the new entity
        $alternative_label = uniqid('entity-alternative', true);
        Wordlift_Entity_Service::get_instance()->set_alternative_labels($entity_id, $alternative_label);
        // Check that the alternative label is properly set
        $labels = Wordlift_Entity_Service::get_instance()->get_alternative_labels($entity_id);
        $this->assertCount(1, $labels);
        $this->assertContains($alternative_label, $labels);
        // Force post status to publish: this triggers the save_post hook
        wl_update_post_status($entity_id, 'publish');
        // Check that entity label is properly mapped on entity post title
        $this->assertEquals($original_label, get_post($entity_id)->post_title);
        // Notice that the uri is generated trough the original label
        // while the current label is the alternative one
        $fake = $this->prepareFakeGlobalPostArrayFromFile('/assets/fake_global_post_array_with_one_existing_entity_linked_as_what.json', array('CURRENT_URI' => $this->buildEntityUriForLabel($original_label), 'CURRENT_LABEL' => $alternative_label));
        $_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 trough its alternative label
        $content = <<<EOF
    <span itemid="{$original_entity_uri}">{$alternative_label}</span>
EOF;
        // Create a post referincing to the created entity
        $post_id = wl_create_post($content, 'my-post', 'A post', 'draft');
        // Check that entity label is STILL properly mapped on entity post title
        $this->assertEquals($original_label, get_post($entity_id)->post_title);
        $expected_entity_uri = $this->buildEntityUriForLabel($original_label);
        $entity_uri = wl_get_entity_uri($entity_id);
        $this->assertEquals($entity_uri, $expected_entity_uri);
        // And it should be related to the post as what predicate
        $related_entity_ids = wl_core_get_related_entity_ids($post_id, array("predicate" => "what"));
        $this->assertCount(1, $related_entity_ids);
        $this->assertContains($entity_id, $related_entity_ids);
    }