600 lines
20 KiB
PHP
600 lines
20 KiB
PHP
<?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)));
|
|
}
|
|
}
|