Edit file File name : media.php Content :<?php if (!defined('UPDRAFTCENTRAL_CLIENT_DIR')) die('No access.'); /** * Handles Media Commands */ class UpdraftCentral_Media_Commands extends UpdraftCentral_Commands { private $switched = false; /** * Function that gets called before every action * * @param string $command a string that corresponds to UDC command to call a certain method for this class. * @param array $data an array of data post or get fields * @param array $extra_info extrainfo use in the udrpc_action, e.g. user_id * * link to udrpc_action main function in class UpdraftCentral_Listener */ public function _pre_action($command, $data, $extra_info) {// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- This function is called from listener.php and $extra_info is being sent. // Here we assign the current blog_id to a variable $blog_id $blog_id = get_current_blog_id(); if (!empty($data['site_id'])) $blog_id = $data['site_id']; if (function_exists('switch_to_blog') && is_multisite() && $blog_id) { $this->switched = switch_to_blog($blog_id); } } /** * Function that gets called after every action * * @param string $command a string that corresponds to UDC command to call a certain method for this class. * @param array $data an array of data post or get fields * @param array $extra_info extrainfo use in the udrpc_action, e.g. user_id * * link to udrpc_action main function in class UpdraftCentral_Listener */ public function _post_action($command, $data, $extra_info) {// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- Unused parameter is present because the caller from UpdraftCentral_Listener class uses 3 arguments. // Here, we're restoring to the current (default) blog before we switched if ($this->switched) restore_current_blog(); } /** * Fetch and retrieves posts based from the submitted parameters * * @param array $params Containing all the needed information to filter the results of the current request * @return array */ public function get_media_items($params) { $error = $this->_validate_capabilities(array('upload_files', 'edit_posts')); if (!empty($error)) return $error; // check paged parameter; if empty set to defaults $paged = !empty($params['paged']) ? (int) $params['paged'] : 1; $numberposts = !empty($params['numberposts']) ? (int) $params['numberposts'] : 10; $offset = ($paged - 1) * $numberposts; $args = array( 'posts_per_page' => $numberposts, 'paged' => $paged, 'offset' => $offset, 'post_type' => 'attachment', 'post_status' => 'inherit', ); if (!empty($params['keyword'])) { $args['s'] = $params['keyword']; } if (!empty($params['category'])) { if (in_array($params['category'], array('detached', 'unattached'))) { $attachment_ids = $this->get_unattached_ids(); } else { $attachment_ids = $this->get_type_ids($params['category']); } $args['post__in'] = $attachment_ids; } if (!empty($params['date'])) { list($monthnum, $year) = explode(':', $params['date']); $args['monthnum'] = $monthnum; $args['year'] = $year; } $query = new WP_Query($args); $result = $query->posts; $count_posts = (int) $query->found_posts; $page_count = 0; if ($count_posts > 0) { $page_count = absint($count_posts / $numberposts); $remainder = absint($count_posts % $numberposts); $page_count = ($remainder > 0) ? ++$page_count : $page_count; } $info = array( 'page' => $paged, 'pages' => $page_count, 'results' => $count_posts, 'items_from' => (($paged * $numberposts) - $numberposts) + 1, 'items_to' => ($paged == $page_count) ? $count_posts : $paged * $numberposts, ); $media_items = array(); if (!empty($result)) { foreach ($result as $item) { $media = $this->get_media_item($item, null, true); if (!empty($media)) { array_push($media_items, $media); } } } $response = array( 'items' => $media_items, 'has_image_editor' => $this->has_image_editor(isset($media_items[0]) ? $media_items[0] : null), 'info' => $info, 'options' => array( 'date' => $this->get_date_options(), 'type' => $this->get_type_options() ) ); return $this->_response($response); } /** * Check whether we have an image editor (e.g. GD, Imagick, etc.) set in place to handle the basic editing * functions such as rotate, crop, etc. If not, then we hide that feature in UpdraftCentral * * @param object $media The media item/object to check * @return boolean */ private function has_image_editor($media) { // Most of the time image library are enabled by default in the php.ini but there's a possbility that users don't // enable them as they have no need for them at the moment or for some other reasons. Thus, we need to confirm // that here through the wp_get_image_editor method. $has_image_editor = true; if (!empty($media)) { if (!function_exists('wp_get_image_editor')) { require_once(ABSPATH.'wp-includes/media.php'); } if (!function_exists('_load_image_to_edit_path')) { require_once(ABSPATH.'wp-admin/includes/image.php'); } $image_editor = wp_get_image_editor(_load_image_to_edit_path($media->ID)); if (is_wp_error($image_editor)) { $has_image_editor = false; } } return $has_image_editor; } /** * Fetch a single media item information * * @param array $params Containing all the needed information to filter the results of the current request * @param array|null $extra_info Additional information from the current request * @param boolean $raw If set, returns the result of the fetch process unwrapped by the response array * @return array */ public function get_media_item($params, $extra_info = null, $raw = false) { $error = $this->_validate_capabilities(array('upload_files', 'edit_posts')); if (!empty($error)) return $error; // Raw means that we need to return the result without wrapping it // with the "$this->_response" function which indicates that the call // was done locally (within the class) and not directly from UpdraftCentral. if ($raw && is_object($params) && isset($params->ID)) { $media = $params; } elseif (is_array($params) && !empty($params['id'])) { $media = get_post($params['id']); } if (!function_exists('get_post_mime_types')) { global $updraftcentral_main; // For a much later version of WP the "get_post_mime_types" is located // in a different folder. So, we make sure that we have it loaded before // actually using it. if (version_compare($updraftcentral_main->get_wordpress_version(), '3.5', '>=')) { require_once(ABSPATH.WPINC.'/post.php'); } else { // For WP 3.4, the "get_post_mime_types" is located in the location provided below. require_once(ABSPATH.'wp-admin/includes/post.php'); } } if (!function_exists('wp_image_editor')) { require_once(ABSPATH.'wp-admin/includes/image-edit.php'); } if (!function_exists('get_media_item')) { require_once(ABSPATH.'wp-admin/includes/template.php'); require_once(ABSPATH.'wp-admin/includes/media.php'); } if ($media) { $thumb = wp_get_attachment_image_src($media->ID, 'thumbnail', true); if (!empty($thumb)) $media->thumb_url = $thumb[0]; $media->url = wp_get_attachment_url($media->ID); $media->parent_post_title = get_the_title($media->post_parent); $media->author = get_the_author_meta('display_name', $media->post_author); $media->filename = basename($media->url); $media->date = date('Y/m/d', strtotime($media->post_date)); $media->upload_date = mysql2date(get_option('date_format'), $media->post_date); $media->filesize = 0; $file = get_attached_file($media->ID); if (!empty($file) && file_exists($file)) { $media->filesize = size_format(filesize($file)); } $media->nonce = wp_create_nonce('image_editor-'.$media->ID); if (false !== strpos($media->post_mime_type, 'image/')) { $meta = wp_get_attachment_metadata($media->ID); $thumb = image_get_intermediate_size($media->ID, 'thumbnail'); $sub_sizes = isset($meta['sizes']) && is_array($meta['sizes']); // Pulling details $sizer = 1; if (isset($meta['width'], $meta['height'])) { $big = max($meta['width'], $meta['height']); $sizer = $big > 400 ? 400 / $big : 1; } $constrained_dims = array(); if ($thumb && $sub_sizes) { $constrained_dims = wp_constrain_dimensions($thumb['width'], $thumb['height'], 160, 120); } $rotate_supported = false; if (function_exists('imagerotate') || wp_image_editor_supports(array('mime_type' => get_post_mime_type($media->ID), 'methods' => array('rotate')))) { $rotate_supported = true; } // Check for alternative text if present $alt = get_post_meta($media->ID, '_wp_attachment_image_alt', true); $media->alt = !empty($alt) ? $alt : ''; // Check whether edited images are restorable $backup_sizes = get_post_meta($media->ID, '_wp_attachment_backup_sizes', true); $can_restore = !empty($backup_sizes) && isset($backup_sizes['full-orig']) && basename($meta['file']) != $backup_sizes['full-orig']['file']; $image_edit_overwrite = (!defined('IMAGE_EDIT_OVERWRITE') || !IMAGE_EDIT_OVERWRITE) ? 0 : 1; $media->misc = array( 'sizer' => $sizer, 'rand' => rand(1, 99999), 'constrained_dims' => $constrained_dims, 'rotate_supported' => (int) $rotate_supported, 'thumb' => $thumb, 'meta' => $meta, 'alt_text' => $alt, 'can_restore' => $can_restore, 'image_edit_overwrite' => $image_edit_overwrite ); } } return $raw ? $media : $this->_response(array('item' => $media)); } /** * Fetch and retrieves posts based from the submitted parameters * * @param array $params Containing all the needed information to filter the results of the current request * @return array */ public function get_posts($params) { $error = $this->_validate_capabilities(array('edit_posts')); if (!empty($error)) return $error; // check paged parameter; if empty set to defaults $paged = !empty($params['paged']) ? (int) $params['paged'] : 1; $numberposts = !empty($params['numberposts']) ? (int) $params['numberposts'] : 10; $offset = ($paged - 1) * $numberposts; $args = array( 'posts_per_page' => $numberposts, 'paged' => $paged, 'offset' => $offset, 'post_type' => 'post', 'post_status' => 'publish,private,draft,pending,future', ); if (!empty($params['keyword'])) { $args['s'] = $params['keyword']; } $query = new WP_Query($args); $result = $query->posts; $count_posts = (int) $query->found_posts; $page_count = 0; if ($count_posts > 0) { $page_count = absint($count_posts / $numberposts); $remainder = absint($count_posts % $numberposts); $page_count = ($remainder > 0) ? ++$page_count : $page_count; } $info = array( 'page' => $paged, 'pages' => $page_count, 'results' => $count_posts, 'items_from' => (($paged * $numberposts) - $numberposts) + 1, 'items_to' => ($paged == $page_count) ? $count_posts : $paged * $numberposts, ); $posts = array(); if (!empty($result)) { foreach ($result as $post) { array_push($posts, array('ID' => $post->ID, 'title' => $post->post_title)); } } $response = array( 'posts' => $posts, 'info' => $info ); return $this->_response($response); } /** * Saves media changes from UpdraftCentral * * @param array $params Containing all the needed information to filter the results of the current request * @return array */ public function save_media_item($params) { $error = $this->_validate_capabilities(array('upload_files', 'edit_posts')); if (!empty($error)) return $error; $args = array( 'post_title' => $params['image_title'], 'post_excerpt' => $params['image_caption'], 'post_content' => $params['image_description'] ); if (!empty($params['new'])) { $args['post_type'] = 'attachment'; $media_id = wp_insert_post($args, true); } else { $args['ID'] = $params['id']; $args['post_modified'] = date('Y-m-d H:i:s'); $args['post_modified_gmt'] = gmdate('Y-m-d H:i:s'); $media_id = wp_update_post($args, true); } if (!empty($media_id)) { // Update alternative text if not empty if (!empty($params['image_alternative_text'])) { update_post_meta($media_id, '_wp_attachment_image_alt', $params['image_alternative_text']); } $result = array( 'status' => 'success', 'item' => $this->get_media_item(array('id' => $media_id), null, true) ); } else { $result = array('status' => 'failed'); } return $this->_response($result); } /** * Executes media action (e.g. attach, detach and delete) * * @param array $params Containing all the needed information to filter the results of the current request * @return array */ public function execute_media_action($params) { global $updraftcentral_host_plugin; $error = $this->_validate_capabilities(array('upload_files', 'edit_posts')); if (!empty($error)) return $error; $result = array(); switch ($params['do']) { case 'attach': global $wpdb; $query_result = $wpdb->query($wpdb->prepare("UPDATE {$wpdb->posts} SET `post_parent` = %d WHERE `post_type` = 'attachment' AND ID = %d", $params['parent_id'], $params['id'])); if (false === $query_result) { $result['error'] = $updraftcentral_host_plugin->retrieve_show_message('failed_to_attach_media'); } else { $result['msg'] = $updraftcentral_host_plugin->retrieve_show_message('media_attached'); } break; case 'detach': global $wpdb; $query_result = $wpdb->query($wpdb->prepare("UPDATE {$wpdb->posts} SET `post_parent` = 0 WHERE `post_type` = 'attachment' AND ID = %d", $params['id'])); if (false === $query_result) { $result['error'] = $updraftcentral_host_plugin->retrieve_show_message('failed_to_detach_media'); } else { $result['msg'] = $updraftcentral_host_plugin->retrieve_show_message('media_detached'); } break; case 'delete': $failed_items = array(); foreach ($params['ids'] as $id) { // Delete permanently if (false === wp_delete_attachment($id, true)) { $failed_items[] = $id; } } if (!empty($failed_items)) { $result['error'] = $updraftcentral_host_plugin->retrieve_show_message('failed_to_delete_media'); $result['items'] = $failed_items; } else { $result['msg'] = $updraftcentral_host_plugin->retrieve_show_message('selected_media_deleted'); } break; default: break; } return $this->_response($result); } /** * Retrieves a collection of formatted dates found for the given post statuses. * It will be used as options for the date filter when managing the media items in UpdraftCentral. * * @return array */ private function get_date_options() { global $wpdb; $options = array(); $date_options = $wpdb->get_col("SELECT DATE_FORMAT(`post_date`, '%M %Y') as `formatted_post_date` FROM {$wpdb->posts} WHERE `post_type` = 'attachment' AND `post_status` = 'inherit' GROUP BY `formatted_post_date` ORDER BY `post_date` DESC"); if (!empty($date_options)) { foreach ($date_options as $monthyear) { $timestr = strtotime($monthyear); $options[] = array('label' => date('F Y', $timestr), 'value' => date('n:Y', $timestr)); } } return $options; } /** * Retrieves mime types that will be use as filter option in UpdraftCentral * * @return array */ private function get_type_options() { global $wpdb, $updraftcentral_host_plugin, $updraftcentral_main; $options = array(); if (!function_exists('get_post_mime_types')) { // For a much later version of WP the "get_post_mime_types" is located // in a different folder. So, we make sure that we have it loaded before // actually using it. if (version_compare($updraftcentral_main->get_wordpress_version(), '3.5', '>=')) { require_once(ABSPATH.WPINC.'/post.php'); } else { // For WP 3.4, the "get_post_mime_types" is located in the location provided below. require_once(ABSPATH.'wp-admin/includes/post.php'); } } $post_mime_types = get_post_mime_types(); $type_options = $wpdb->get_col("SELECT `post_mime_type` FROM {$wpdb->posts} WHERE `post_type` = 'attachment' AND `post_status` = 'inherit' GROUP BY `post_mime_type` ORDER BY `post_mime_type` DESC"); foreach ($post_mime_types as $mime_type => $label) { if (!wp_match_mime_types($mime_type, $type_options)) continue; $options[] = array('label' => $label[0], 'value' => esc_attr($mime_type)); } $options[] = array('label' => $updraftcentral_host_plugin->retrieve_show_message('unattached'), 'value' => 'detached'); return $options; } /** * Retrieves media items that haven't been attached to any posts * * @return array */ private function get_unattached_ids() { global $wpdb; return $wpdb->get_col("SELECT `ID` FROM {$wpdb->posts} WHERE `post_type` = 'attachment' AND `post_status` = 'inherit' AND `post_parent` = '0'"); } /** * Retrieves IDs of media items that has the given mime type * * @param string $type The mime type to search for * @return array */ private function get_type_ids($type) { global $wpdb; return $wpdb->get_col($wpdb->prepare("SELECT `ID` FROM {$wpdb->posts} WHERE `post_type` = 'attachment' AND `post_status` = 'inherit' AND `post_mime_type` LIKE %s", $type.'/%')); } /** * Checks whether we have the required fields submitted and the user has * the capabilities to execute the requested action * * @param array $capabilities The capabilities to check and validate * * @return array|void */ private function _validate_capabilities($capabilities) { foreach ($capabilities as $capability) { if (!current_user_can($capability)) { return $this->_generic_error_response('insufficient_permission'); } } } /** * Populates the $_REQUEST global variable with the submitted data * * @param array $params Submitted data received from UpdraftCentral * @return array */ private function populate_request($params) { if (!empty($params)) { foreach ($params as $key => $value) { $_REQUEST[$key] = $value; } } } /** * Handles image editing requests coming from UpdraftCentral * * @param array $params Containing all the needed information to filter the results of the current request * @return array */ public function image_editor($params) { $error = $this->_validate_capabilities(array('edit_posts')); if (!empty($error)) return $error; $attachment_id = (int) $params['postid']; $this->populate_request($params); if (!function_exists('load_image_to_edit')) { require_once(ABSPATH.'wp-admin/includes/image.php'); } include_once(ABSPATH.'wp-admin/includes/image-edit.php'); $msg = false; switch ($params['do']) { case 'save': case 'scale': $msg = wp_save_image($attachment_id); break; case 'restore': $msg = wp_restore_image($attachment_id); break; } $msg = (false !== $msg) ? json_encode($msg) : $msg; return $this->_response(array('content' => $msg)); } /** * Handles image preview requests coming from UpdraftCentral * * @param array $params Containing all the needed information to filter the results of the current request * @return array */ public function image_preview($params) { $error = $this->_validate_capabilities(array('edit_posts')); if (!empty($error)) return $error; if (!function_exists('load_image_to_edit')) { require_once(ABSPATH.'wp-admin/includes/image.php'); } include_once(ABSPATH.'wp-admin/includes/image-edit.php'); $this->populate_request($params); $post_id = (int) $params['postid']; ob_start(); stream_preview_image($post_id); $content = ob_get_contents(); ob_end_clean(); return $this->_response(array('content' => base64_encode($content))); } } Save