/**
 * Sync the site to Redlink triple store and print out the post title being processed.
 */
function wl_admin_sync_to_redlink()
{
    $posts = get_posts(array('post_type' => 'any', 'posts_per_page' => -1));
    wl_write_log("wl_admin_sync_to_redlink [ post count :: " . sizeof($posts) . " ]");
    foreach ($posts as $post) {
        echo esc_html($post->post_title) . '<br/>';
        wl_linked_data_push_to_redlink($post->ID);
    }
    // Schedule the execution of SPARQL.
    wl_shutdown();
}
/**
 * Saves the values of wordlift metaboxes set in the entity editor page
 */
function wl_entity_metabox_save($post_id)
{
    if (!isset($_POST['wl_metaboxes'])) {
        return;
    }
    // Loop over the wl_metaboxes array and save metaboxes values
    foreach ($_POST['wl_metaboxes'] as $meta_name => $meta_values) {
        // First, verify nonce is set for this meta
        $nonce_name = 'wordlift_' . $meta_name . '_entity_box_nonce';
        $nonce_verify = 'wordlift_' . $meta_name . '_entity_box';
        if (!isset($_POST[$nonce_name])) {
            return $post_id;
        }
        // Verify that the nonce is valid.
        if (!wp_verify_nonce($_POST[$nonce_name], $nonce_verify)) {
            return $post_id;
        }
        // Delete values before updating
        delete_post_meta($post_id, $meta_name);
        // Save the property value(s)
        if (isset($meta_name) && isset($meta_values) && $meta_values !== '') {
            // There can be one or more property values, so we force to array:
            if (!is_array($meta_values)) {
                $meta_values = array($meta_values);
            }
            foreach ($meta_values as $meta_value) {
                // If the meta expects an entity...
                $expecting_uri = wl_get_meta_type($meta_name) === WL_DATA_TYPE_URI;
                // ...and the user inputs an entity that is not present in the db...
                $absent_from_db = is_null(wl_get_entity_post_by_uri($meta_value));
                // ...and that is not a external uri
                $name_is_uri = strpos($meta_value, 'http') === 0;
                if ($expecting_uri && $absent_from_db && !$name_is_uri) {
                    // ...we create a new entity!
                    $new_entity = wl_save_entity('', $meta_value, WL_ENTITY_TYPE_NAME, '');
                    // Assign type
                    $constraints = wl_get_meta_constraints($meta_name);
                    $type = 'http://schema.org/' . $constraints['uri_type'];
                    wl_set_entity_main_type($new_entity->ID, $type);
                    // TODO: directly publish the new entity
                    // Update the value that will be saved as meta
                    $meta_value = wl_get_entity_uri($new_entity->ID);
                }
                // TODO: use WL methods
                add_post_meta($post_id, $meta_name, $meta_value);
            }
        }
    }
    // Push changes on RedLink
    wl_linked_data_push_to_redlink($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_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);
}
Ejemplo n.º 5
0
 /**
  * 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);
 }
Ejemplo n.º 6
0
 public function save_form_data($entity_id)
 {
     // Build Field objects
     $this->instantiate_fields($entity_id);
     // Check if WL metabox form was posted
     if (!isset($_POST['wl_metaboxes'])) {
         return;
     }
     foreach ($this->fields as $field) {
         // Verify nonce
         $valid_nonce = $field->verify_nonce();
         if ($valid_nonce) {
             $posted_data = $_POST['wl_metaboxes'];
             $field_name = $field->meta_name;
             // Each Filed only deals with its values.
             if (isset($posted_data[$field_name])) {
                 $values = $posted_data[$field_name];
                 if (!is_array($values)) {
                     $values = array($values);
                 }
                 // Save data permanently
                 $field->save_data($values);
             }
         }
     }
     wl_linked_data_push_to_redlink($entity_id);
 }