X7ROOT File Manager
Current Path:
/home/hamdjcne/public_html/wp-content/plugins/mediavine-create/lib
home
/
hamdjcne
/
public_html
/
wp-content
/
plugins
/
mediavine-create
/
lib
/
ðŸ“
..
ðŸ“
Exceptions
ðŸ“
api
📄
autoloader-pro.php
(28 B)
📄
class-admin-notices.php
(2.47 KB)
📄
class-api-services.php
(9.23 KB)
📄
class-cache-manager.php
(1.99 KB)
📄
class-custom-content.php
(6.57 KB)
📄
class-data-sync.php
(5.35 KB)
📄
class-permissions.php
(980 B)
📄
class-publish.php
(24.27 KB)
📄
class-restore.php
(3.95 KB)
📄
class-view-loader.php
(7.88 KB)
ðŸ“
creations
ðŸ“
db-interface
📄
feature-flags.php
(681 B)
📄
functions-feature-flags.php
(748 B)
📄
functions-version-check.php
(9.46 KB)
📄
functions.php
(5.36 KB)
ðŸ“
helpers
📄
helpers.php
(631 B)
ðŸ“
i18n
ðŸ“
images
ðŸ“
importer-compatibility
📄
index.php
(28 B)
ðŸ“
json-ld
ðŸ“
nutrition
ðŸ“
product-maps
ðŸ“
products
ðŸ“
relations
ðŸ“
reviews
ðŸ“
revisions
ðŸ“
settings
ðŸ“
settings-group
ðŸ“
shapes
ðŸ“
supplies
ðŸ“
views
Editing: class-publish.php
<?php namespace Mediavine\Create; use Mediavine\MV_DBI; use Mediavine\WordPress\Support\Arr; use Mediavine\WordPress\Support\Str; class Publish extends Plugin { public static function publish( \WP_REST_Request $request, \WP_REST_Response $response ) { $creation_id = $request->get_param( 'id' ); if ( ! $creation_id ) { return new \WP_Error( 404, __( 'Entry Not Found', 'mediavine' ), [ 'message' => __( 'The Creation could not be found', 'mediavine' ), 'class' => 'Mediavine\Create\Publish', 'method' => 'publish', ] ); } $creation = Creations::publish_creation( (int) $creation_id ); $creation->thumbnail_uri = wp_get_attachment_url( $creation->thumbnail_id ); $response = API_Services::set_response_data( $creation, $response ); return $response; } /** * Conditionally Republish Creation at Run Time * @param object $creation Creation DB object * @return object $creation full creation object whether new or original */ public static function maybe_republish( $creation ) { self::do_actions( $creation->id ); $should_republish = false; // $should_republish bool passed on to return prior result, preventing false negatives $should_republish = self::list_link_repair( $creation, $should_republish ); $should_republish = self::remove_associated_post_revisions( $creation, $should_republish ); $should_republish = self::fix_associated_posts_column( $creation, $should_republish ); $should_republish = self::fix_imported_ratings_dates( $creation, $should_republish ); $should_republish = self::fix_canonical_post_id( $creation, $should_republish ); $should_republish = self::fix_create_slug( $creation, $should_republish ); $publish_queue = []; $publish_queue_option = get_option( 'mv_publish_queue' ); if ( ! empty( $publish_queue_option ) ) { $publish_queue = json_decode( $publish_queue_option, true ); } if ( in_array( $creation->id, $publish_queue, true ) ) { $should_republish = true; $publish_queue = array_values( array_filter( $publish_queue, function( $item ) use ( $creation ) { return $item !== $creation->id; } ) ); update_option( 'mv_publish_queue', wp_json_encode( $publish_queue ) ); } if ( empty( $creation->published ) || ! is_array( json_decode( $creation->published, true ) ) ) { $should_republish = true; } if ( $should_republish ) { $creation = \Mediavine\Create\Creations::publish_creation( $creation->id, false ); } return $creation; } /** * Repairs list links on a Create list * * @param object $creation Create card data * @param bool $should_republish Current $should_republish value to potentially be passed on * @return bool True if data updated and republish should happen, false if it doesn't need to happen */ private static function list_link_repair( $creation, $should_republish ) { if ( 'list' !== $creation->type ) { return $should_republish; } $metadata = []; if ( ! empty( $creation->metadata ) ) { $metadata = json_decode( $creation->metadata, true ); } if ( ! empty( $metadata['list_link_repaired'] ) ) { return $should_republish; } $items = self::$models_v2->mv_relations->find( [ 'where' => [ 'creation' => $creation->id, ], ] ); foreach ( $items as &$item ) { if ( 'card' !== $item->content_type ) { continue; } if ( $item->relation_id !== $item->canonical_post_id ) { continue; } $found_creation = self::$models_v2->mv_creations->find_one_by_id( $item->relation_id ); if ( ! empty( $found_creation->canonical_post_id ) ) { $item->url = get_permalink( $found_creation->canonical_post_id ); $updated_item = self::$models_v2->mv_relations->update( [ 'id' => $item->id, 'url' => $item->url, 'canonical_post_id' => $found_creation->canonical_post_id, ] ); } } $metadata['list_link_repaired'] = true; $updated_creation = self::$models_v2->mv_creations->update_without_modified_date( [ 'id' => $creation->id, 'metadata' => wp_json_encode( $metadata ), ] ); return true; } private static function fix_associated_posts_column( $creation, $should_republish ) { if ( empty( $creation->associated_posts ) || Str::contains( 'fixed_associated_posts_column', $creation->metadata ) || Str::contains( '""', $creation->associated_posts ) ) { return $should_republish; } $associated_posts = json_decode( $creation->associated_posts, true ); $associated_posts = wp_json_encode( array_map( 'strval', $associated_posts ) ); $updated_creation = self::$models_v2->mv_creations->update_without_modified_date( [ 'id' => $creation->id, 'associated_posts' => $associated_posts, ] ); if ( is_wp_error( $updated_creation ) ) { return $should_republish; } $metadata = json_decode( $creation->metadata, true ); $metadata['fixed_associated_posts_column'] = true; self::$models_v2->mv_creations->update_without_modified_date( [ 'id' => $creation->id, 'metadata' => wp_json_encode( $metadata ), ] ); return true; } private static function fix_canonical_post_id( $creation, $should_republish ) { // return $should_republish; if ( empty( $creation->canonical_post_id ) ) { return $should_republish; } $associated_posts = ! empty( $creation->associated_posts ) ? json_decode( $creation->associated_posts, true ) : []; if ( empty( $associated_posts ) || in_array( $creation->canonical_post_id, $associated_posts, true ) ) { return $should_republish; } // Use first associated post if found $canonical_post_id = Arr::first( $associated_posts ); // Use original post ID if available and in associated posts if ( ! empty( $creation->original_post_id ) && in_array( $creation->original_post_id, $associated_posts, true ) ) { $canonical_post_id = $creation->original_post_id; } if ( empty( $canonical_post_id ) ) { return $should_republish; } // Update creation with new metadata and associated posts self::$models_v2->mv_creations->update_without_modified_date( [ 'id' => $creation->id, 'canonical_post_id' => $canonical_post_id, ] ); return true; } /** * Fix the slug for a Create post type if incorrect * * We check for '-creation' at the end of the slug. If it's not there then we will * update the slug to include it. This will prevent Yoast SEO Premium from causing * bad page redirects. * * @param object $creation Full creation data * @param bool $should_republish Previous republish value * @return bool True if we should republish or the previous value if no changes are to be made */ static public function fix_create_slug( $creation, $should_republish ) { $metadata = []; if ( ! empty( $creation->metadata ) ) { $metadata = json_decode( $creation->metadata, true ); } if ( ! empty( $metadata['slug_repaired'] ) ) { return $should_republish; } $post_slug = get_post_field( 'post_name', $creation->object_id ); $update_slug = false; if ( ! empty( $post_slug ) ) { $end_of_slug = substr( $post_slug, -9 ); if ( '-creation' !== $end_of_slug ) { $update_slug = true; } } if ( $update_slug ) { $update_post = wp_update_post( [ 'ID' => $creation->object_id, 'post_name' => $post_slug . '-creation', ] ); if ( is_wp_error( $update_post ) ) { return $should_republish; } // Legacy support for old Create post types, and old WP revision support global $wpdb; // Remove any trailing digits // SECURITY CHECKED: This query is properly sanitized. Custom LIKE doesn't work with preparation. $trimmed_slug = preg_replace( '/-[0-9]*$/', '', $post_slug ); $statement = "SELECT * FROM {$wpdb->prefix}posts WHERE post_name LIKE '{$trimmed_slug}%' AND ( post_type = 'mv_create' OR post_type = 'mv_creations' OR post_type = 'mv_products' OR post_type = 'mv_recipes' ) "; $prepared = $wpdb->prepare( $statement, [] ); $matching_posts = $wpdb->get_results( $prepared ); foreach ( $matching_posts as $matching_post ) { if ( ! empty( $matching_post->post_name ) ) { $end_of_slug = substr( $matching_post->post_name, -9 ); if ( '-creation' !== $end_of_slug ) { $update_post = wp_update_post( [ 'ID' => $matching_post->ID, 'post_name' => $matching_post->post_name . '-creation', ] ); if ( is_wp_error( $update_post ) ) { return $should_republish; } } } } } $metadata['slug_repaired'] = true; self::$models_v2->mv_creations->update_without_modified_date( [ 'id' => $creation->id, 'metadata' => wp_json_encode( $metadata ), ] ); return true; } /** * Removes previously associated revisions from a Create card * * @param object $creation Create card data * @param bool $should_republish Current $should_republish value to potentially be passed on * @return bool True if data updated and republish should happen, false if it doesn't need to happen */ private static function remove_associated_post_revisions( $creation, $should_republish ) { $metadata = []; if ( ! empty( $creation->metadata ) ) { $metadata = json_decode( $creation->metadata, true ); } if ( ! empty( $metadata['revisions_removed'] ) ) { return $should_republish; } $associated_posts = []; if ( ! empty( $creation->associated_posts ) ) { $associated_posts = json_decode( $creation->associated_posts ); } foreach ( $associated_posts as $key => $associated_post ) { $post_status = get_post_status( $associated_post ); $allowed_statuses = [ 'publish', 'future', 'draft', 'pending', 'private', ]; if ( ! in_array( $post_status, $allowed_statuses, true ) ) { unset( $associated_posts[ $key ] ); } } $metadata['revisions_removed'] = true; // Update creation with new metadata and associated posts self::$models_v2->mv_creations->update_without_modified_date( [ 'id' => $creation->id, 'metadata' => wp_json_encode( $metadata ), 'associated_posts' => wp_json_encode( array_values( array_unique( $associated_posts ) ) ), ] ); return true; } /** * Fixes review creation dates for imported ratings/reviews. * * Recipe ratings imported previously were assigned a created date on import, * which means all ratings imported for a given recipe had the same date. This function * reassigns any rating creation dates possible. * * Remove December 2019 * * @since 1.4.10 * * @return void */ public static function fix_imported_ratings_dates( $creation, $should_republish ) { global $wpdb; if ( 'recipe' !== $creation->type || ! Str::contains( $creation->metadata, 'import' ) || Str::contains( $creation->metadata, 'fixed_ratings_dates' ) || empty( $creation->original_post_id ) ) { return $should_republish; } $dbi = self::$models_v2->mv_reviews; $statement = "SELECT r.id as id, comment_date AS created, comment_date AS modified FROM {$wpdb->commentmeta} AS cm JOIN {$wpdb->comments} AS c ON (c.comment_ID = cm.comment_id) JOIN {$dbi->table_name} AS r ON (c.comment_author_email=r.author_email) WHERE c.comment_approved = 1 AND cm.meta_key IN ('ERRating', 'cookbook_comment_rating', 'recipe_rating', 'wprm-comment-rating') AND cm.meta_value != 0 AND c.comment_post_ID = %d"; if ( Str::contains( $creation->metadata, [ 'meal_planner', 'recipe_maker' ] ) ) { if ( Str::contains( $creation->metadata, 'meal_planner' ) ) { $table_name = 'mpprecipe_ratings'; } if ( Str::contains( $creation->metadata, 'recipe_maker' ) ) { $table_name = 'wprm_ratings'; } $statement = "SELECT r.id as id, comment_date AS created, comment_date AS modified FROM {$wpdb->prefix}{$table_name} AS ir JOIN {$wpdb->comments} AS c ON (c.comment_ID = ir.comment_id) JOIN {$dbi->table_name} AS r ON (c.comment_author_email=r.author_email) WHERE c.comment_approved = 1 AND c.comment_post_ID = %d"; } // SECURITY CHECKED: This query is properly prepared. $prepared = $wpdb->prepare( $statement, [ $creation->original_post_id ] ); $ratings = $wpdb->get_results( $prepared, ARRAY_A ); foreach ( $ratings as $data ) { $date = date( 'Y-m-d H:i:s' ); $data['created'] = isset( $data['created'] ) ? $data['created'] : $date; $data['modified'] = isset( $data['modified'] ) ? $data['modified'] : $date; if ( is_wp_error( $data ) ) { continue; } // because our insert, upsert, and update methods overwrite `created` and `modified` dates, // we have to manually perform an update here $normalized_data = $dbi->normalize_data( $data ); add_filter( 'query', [ $dbi, 'allow_null' ] ); $wpdb->update( $dbi->table_name, $normalized_data, [ 'id' => $normalized_data['id'] ] ); remove_filter( 'query', [ $dbi, 'allow_null' ] ); } $metadata = json_decode( $creation->metadata, true ); $metadata['fixed_ratings_dates'] = true; // Update creation with new metadata and associated posts self::$models_v2->mv_creations->update_without_modified_date( [ 'id' => $creation->id, 'metadata' => wp_json_encode( $metadata ), ] ); return true; } /** * Add Creations to republish queue. * * @param \WP_REST_Request $request * @param \WP_REST_Response $response * * @return void|bool|array|\WP_REST_Response */ public static function republish_creations( \WP_REST_Request $request, \WP_REST_Response $response ) { $params = $request->get_params(); if ( 'pubeng' !== $params['auth'] ) { return false; } if ( empty( $params['type'] ) ) { return static::add_all_to_publish_queue(); } $query_args = [ 'where' => [ 'type' => $params['type'], ], 'select' => [ 'id', ], 'limit' => 9999, ]; $model = new MV_DBI( 'mv_creations' ); $creations = $model->find( $query_args ); $creation_ids = []; foreach ( $creations as $creation ) { $creation_ids[] = $creation->id; } $publish_queue = static::update_publish_queue( $creation_ids ); $response = API_Services::set_response_data( $publish_queue, $response ); return $response; } public static function do_actions( $id ) { $action_queues = get_option( 'mv_queues', [] ); if ( empty( $action_queues ) ) { return; } $action_queues = json_decode( $action_queues, true ); foreach ( $action_queues as $key => $name ) { $queue = get_option( 'mv_' . $name . '_queue' ); if ( false === $queue || empty( $queue ) || 'null' === $queue ) { unset( $action_queues[ $key ] ); continue; } $queued_ids = json_decode( $queue, true ); if ( ! in_array( (string) $id, $queued_ids, true ) ) { continue; } do_action( 'mv_' . $name . '_queue_action', $id ); $queued_ids = array_values( array_filter( $queued_ids, function( $item ) use ( $id ) { return $item !== $id; } ) ); if ( empty( $queued_ids ) ) { delete_option( 'mv_' . $name . '_queue' ); unset( $action_queues[ $key ] ); continue; } update_option( 'mv_' . $name . '_queue', wp_json_encode( $queued_ids ) ); } update_option( 'mv_queues', wp_json_encode( $action_queues ) ); } public static function selective_update_queue( $creation_ids = [], $name = '' ) { $queue = []; $option = 'mv_' . $name . '_queue'; $queue_option = get_option( $option ); if ( ! empty( $queue_option ) ) { $queue = json_decode( $queue_option, true ); } foreach ( $creation_ids as $id ) { $queue[] = (string) $id; } $queue = array_values( array_unique( $queue ) ); update_option( $option, wp_json_encode( $queue ) ); static::add_to_queues( $name ); return $queue; } public static function add_to_queues( $name ) { $queue_option = get_option( 'mv_queues' ); $queue = []; if ( ! empty( $queue_option ) ) { $queue = json_decode( $queue_option, true ); } $queue[] = $name; $queue = array_values( array_unique( $queue ) ); update_option( 'mv_queues', wp_json_encode( $queue ) ); } /** * Manage queue of items that need to be republished * @param array $creation_ids Numeric Array of Creation IDs * @return array $publish_queue Numeric Array of Creation IDs that need republish */ public static function update_publish_queue( $creation_ids = [] ) { $publish_queue = []; $publish_queue_option = get_option( 'mv_publish_queue' ); if ( ! empty( $publish_queue_option ) ) { $publish_queue = json_decode( $publish_queue_option, true ); } foreach ( $creation_ids as $an_id ) { $publish_queue[] = (string) $an_id; } $publish_queue = array_values( array_unique( $publish_queue ) ); update_option( 'mv_publish_queue', wp_json_encode( $publish_queue ) ); return $publish_queue; } public static function add_all_to_publish_queue() { $model = new MV_DBI( 'mv_creations' ); $creations = $model->find(); $creation_ids = []; foreach ( $creations as $creation ) { $creation_ids[] = $creation->id; } return static::update_publish_queue( $creation_ids ); } public static function prepare_creation( $creation ) { if ( empty( $creation->id ) ) { return new \WP_Error( 404, __( 'Entry Not Found', 'mediavine' ), [ 'message' => __( 'The Creation could not be found', 'mediavine' ) ] ); } unset( $creation->published ); return $creation; } public static function prepare_jsonld( $creation ) { if ( ! $creation->schema_display ) { return $creation; } $JSON_LD = JSON_LD::get_instance(); if ( ! $creation->author ) { $creation->author = \Mediavine\Settings::get_setting( self::$settings_group . '_copyright_attribution' ); } // Pinterest image should not be included in google schema if ( empty( $creation->images ) ) { $json_ld = $JSON_LD->build_json_ld( (array) $creation, $creation->type ); if ( ! empty( $json_ld ) ) { $creation->json_ld = wp_json_encode( $json_ld ); } return $creation; } // Clone used because shallow copy was made, so $cleaned_image_creation passing a // referenced object of $creation (http://php.net/manual/en/language.oop5.cloning.php) $cleaned_image_creation = clone( $creation ); $cleaned = []; foreach ( $cleaned_image_creation->images as $image ) { if ( 'mv_create_vert' === $image['image_size'] ) { continue; } $cleaned[] = $image; } $cleaned_image_creation->images = $cleaned; $json_ld = $JSON_LD->build_json_ld( (array) $cleaned_image_creation, $cleaned_image_creation->type ); if ( ! empty( $json_ld ) ) { $creation->json_ld = wp_json_encode( $json_ld ); } return $creation; } public static function prepare_create_settings( $creation ) { $create_settings = []; $create_settings = apply_filters( 'mv_publish_create_settings', $create_settings ); $creation->create_settings = $create_settings; return $creation; } public static function prepare_supplies( $creation ) { if ( empty( $creation->supplies ) ) { return $creation; } $supplies = $creation->supplies; usort( $supplies, [ 'Mediavine\Create\Supplies', 'sort_supply' ] ); if ( 'recipe' === $creation->type ) { $ingredients = array_filter( $supplies, function( $supply ) { return 'ingredients' === $supply->type; } ); if ( $ingredients ) { $creation->ingredients = Supplies::put_supplies_in_groups_array( $ingredients ); } } if ( 'diy' === $creation->type ) { $materials = array_filter( $supplies, function( $supply ) { return 'materials' === $supply->type; } ); if ( $materials ) { $creation->materials = Supplies::put_supplies_in_groups_array( $materials ); } $tools = array_filter( $supplies, function( $supply ) { return 'tools' === $supply->type; } ); if ( $tools ) { $creation->tools = Supplies::put_supplies_in_groups_array( $tools ); } } unset( $creation->supplies ); return $creation; } public static function prepare_relations( $creation ) { if ( 'list' === $creation->type ) { $relations = $creation->relations; $list_items = array_filter( $relations, function( $item ) { return 'listItems' === $item->type; } ); if ( $list_items ) { $creation->list_items = array_values( $list_items ); } } unset( $creation->relations ); return $creation; } public static function prepare_instructions( $creation ) { $creation->instructions = html_entity_decode( $creation->instructions ); if ( ( 'diy' === $creation->type ) || ( 'recipe' === $creation->type ) ) { $dom = new \DOMDocument; if ( function_exists( 'libxml_use_internal_errors' ) ) { libxml_use_internal_errors( true ); } $load = $dom->loadHTML( mb_convert_encoding( $creation->instructions, 'HTML-ENTITIES', 'UTF-8' ) ); if ( function_exists( 'libxml_use_internal_errors' ) ) { libxml_use_internal_errors( false ); } if ( ! $load ) { return $creation; } $lis = $dom->getElementsByTagName( 'li' ); $i = 1; // start at 1 because it's outputting HTML for instructions, so step 1 should be `mv_create_123_1` foreach ( $lis as $li ) { // the schema outputs the anchor as `mv_create_123_1`, so we do the same here $li->setAttribute( 'id', "mv_create_{$creation->id}_{$i}" ); ++$i; } // Remove the doctype when saving $creation->instructions = preg_replace( '~<(?:!DOCTYPE|/?(?:html|body))[^>]*>\s*~i', '', $dom->saveHTML() ); } return $creation; } public static function prepare_ratings( $creation ) { $rating = Reviews_Models::get_creation_rating( $creation->id ); $rating_count = Reviews_Models::get_creation_rating_count( $creation->id ); if ( $rating && $rating_count ) { $creation->rating = $rating; $creation->rating_count = $rating_count; } return $creation; } public static function prepare_posts( $creation ) { $associated_posts = []; if ( ! empty( $creation->associated_posts ) ) { $associated_posts = json_decode( $creation->associated_posts ); foreach ( $associated_posts as &$post ) { $post = [ 'id' => $post, 'title' => get_the_title( $post ), ]; } } $creation->posts = $associated_posts; return $creation; } /** * Prepares the image data for publishing * * @param object $creation Creation data * @return object Updated creation data */ public static function prepare_images( $creation ) { if ( empty( $creation->thumbnail_id ) && empty( $creation->pinterest_img_id ) ) { return $creation; } if ( empty( $creation->thumbnail_id ) ) { $creation->thumbnail_id = 0; } if ( empty( $creation->pinterest_img_id ) ) { $creation->pinterest_img_id = 0; } $images = Creations::add_images_to_creation( $creation, $creation->thumbnail_id, $creation->pinterest_img_id, $creation->type ); if ( ! empty( $images ) ) { // Make sure we generate base image sizes for published data $images = Images::get_available_image_sizes( $images ); $creation->images = $images; } return $creation; } public static function prepare_times( $creation ) { $times_to_parse = [ 'prep_time', 'active_time', 'additional_time', 'perform_time', 'total_time', ]; // similar to how juration parses time units $units_to_parse = apply_filters( 'mv_time_units_to_parse', [ 'years' => 31536000, 'months' => 2628000, 'days' => 86400, 'hours' => 3600, 'minutes' => 60, 'seconds' => 1, ] ); $times_to_parse = apply_filters( 'mv_times_to_parse', $times_to_parse ); foreach ( $times_to_parse as $time_to_parse ) { if ( empty( $creation->{$time_to_parse} ) ) { $creation->{$time_to_parse} = null; continue; } $seconds = (int) floor( $creation->{$time_to_parse} ); $time_array['original'] = $seconds; $remaining = $seconds; foreach ( $units_to_parse as $unit => $unit_value ) { $value = (int) floor( round( $remaining * 1000 ) / 1000 / $unit_value ); if ( 0 !== $value ) { $time_array[ $unit ] = $value; $remaining = $remaining % $unit_value; } else { $time_array[ $unit ] = 0; } } $creation->{$time_to_parse} = $time_array; } return $creation; } private static function format_supplies( $supplies ) { $formatted = []; foreach ( $supplies as $supply ) { $formatted[ $supply->type ][] = $supply; } return $formatted; } }
Upload File
Create Folder