nopriv_plugin_actions(); if (EMR_CAPABILITY !== false) { if (is_array(EMR_CAPABILITY)) { $this->general_cap = EMR_CAPABILITY[0]; $this->user_cap = EMR_CAPABILITY[1]; if (! current_user_can($this->general_cap) && ! current_user_can($this->user_cap)) { return; } } else { $this->general_cap = EMR_CAPABILITY; if (! current_user_can($this->general_cap)) { return; } } } elseif (! current_user_can('upload_files')) { return; } $this->plugin_actions(); // init } public function adminInit() { $this->features['replace'] = true; // does nothing just for completeness $this->features['background'] = apply_filters('emr/feature/background', true); } public function filesystem() { return new FileSystem(); } public function uiHelper() { return Uihelper::getInstance(); } public function useFeature($name) { // If for some obscure reason, it's called earlier or out of admin, still load the features. if (count($this->features) === 0) { $this->adminInit(); } switch($name) { case 'background': $bool = $this->features['background']; break; default: $bool = false; break; } return $bool; } public static function get() { if (is_null(self::$instance)) { self::$instance = new EnableMediaReplacePlugin(); } $log = Log::getInstance(); if (Log::debugIsActive()) { $uploaddir = wp_upload_dir(null, false, false); if (isset($uploaddir['basedir'])) { $log->setLogPath($uploaddir['basedir'] . "/emr_log"); } } return self::$instance; } // Actions for EMR that always need to hook protected function nopriv_plugin_actions() { // shortcode add_shortcode('file_modified', array($this, 'get_modified_date')); } public function plugin_actions() { $this->plugin_path = plugin_dir_path(EMR_ROOT_FILE); $this->plugin_url = plugin_dir_url(EMR_ROOT_FILE); // loads the dismiss hook. $notices = Notices::getInstance(); // init plugin add_action('admin_menu', array($this,'menu')); add_action('submenu_file', array($this, 'hide_sub_menu')); add_action('admin_init', array($this,'init')); add_action( 'current_screen', array($this, 'setScreen') ); // annoying workaround for notices in edit-attachment screen add_action('admin_enqueue_scripts', array($this,'admin_scripts')); // content filters add_filter('media_row_actions', array($this,'add_media_action'), 10, 2); add_action('attachment_submitbox_misc_actions', array($this,'admin_date_replaced_media_on_edit_media_screen'), 91); //add_filter('upload_mimes', array($this,'add_mime_types'), 1, 1); // notices add_action('admin_notices', array($this,'display_notices')); add_action('network_admin_notices', array($this,'display_network_notices')); add_action('wp_ajax_emr_dismiss_notices', array($this,'dismiss_notices')); // editors add_action('add_meta_boxes_attachment', array($this, 'add_meta_boxes'), 10, 2); add_filter('attachment_fields_to_edit', array($this, 'attachment_editor'), 10, 2); /** Just after an image is replaced, try to browser decache the images */ if (isset($_GET['emr_replaced']) && intval($_GET['emr_replaced'] == 1)) { add_filter('wp_get_attachment_image_src', array($this, 'attempt_uncache_image'), 10, 4); // adds a metabox to list thumbnails. This is a cache reset hidden as feature. //add_action( 'add_meta_boxes', function () { ); add_filter('postbox_classes_attachment_emr-showthumbs-box', function ($classes) { $classes[] = 'closed'; return $classes; }); } } /** * Register this file in WordPress so we can call it with a ?page= GET var. * To suppress it in the menu we give it an empty menu title. */ public function menu() { $title = esc_html__("Replace media", "enable-media-replace"); $title = (isset($_REQUEST['action']) && ($_REQUEST['action'] === 'emr_prepare_remove')) ? esc_html__("Remove background", "enable-media-replace") : $title; add_submenu_page('upload.php',$title, $title, 'upload_files', 'enable-media-replace/enable-media-replace.php', array($this, 'route')); } public function hide_sub_menu($submenu_file) { global $plugin_page; // Select another submenu item to highlight (optional). if ( $plugin_page && $plugin_page == 'enable-media-replace/enable-media-replace.php' ) { $submenu_file = 'upload.php'; } // Hide the submenu. remove_submenu_page( 'upload.php', 'enable-media-replace/enable-media-replace.php' ); return $submenu_file; } /** * Initialize this plugin. Called by 'admin_init' hook. * */ public function init() { load_plugin_textdomain('enable-media-replace', false, basename(dirname(EMR_ROOT_FILE)) . '/languages'); // Load Submodules new Externals(); new Ajax(); } public function setScreen() { $screen = get_current_screen(); $notice_pages = array('attachment', 'media_page_enable-media-replace/enable-media-replace', 'upload' ); if ( in_array($screen->id, $notice_pages) ) { $notices = Notices::getInstance(); add_action('admin_notices', array($notices, 'admin_notices')); // previous page / init time } // var_dump($screen); } /** Load EMR views based on request */ public function route() { global $plugin_page; switch ($plugin_page) { case 'enable-media-replace/enable-media-replace.php': $action = isset($_GET['action']) ? sanitize_text_field($_GET['action']) : ''; wp_enqueue_style('emr_style'); wp_enqueue_script('jquery-ui-datepicker'); wp_enqueue_style('jquery-ui-datepicker'); wp_enqueue_script('emr_admin'); $this->uiHelper()->featureNotice(); if (! check_admin_referer($action, '_wpnonce')) { die('Invalid Nonce'); } // @todo Later this should be move to it's own controller, and built view from there. if ($action == 'media_replace') { if (array_key_exists("attachment_id", $_GET) && intval($_GET["attachment_id"]) > 0) { wp_enqueue_script('emr_upsell'); require_once($this->plugin_path . "views/popup.php"); // warning variables like $action be overwritten here. } } elseif ($action == 'media_replace_upload') { require_once($this->plugin_path . 'views/upload.php'); } elseif ('emr_prepare_remove' === $action && $this->useFeature('background')) { $attachment_id = intval($_GET['attachment_id']); $attachment = get_post($attachment_id); //We're adding a timestamp to the image URL for cache busting wp_enqueue_script('emr_remove_bg'); wp_enqueue_style('emr_style'); wp_enqueue_style('emr-remove-background'); wp_enqueue_script('emr_upsell'); require_once($this->plugin_path . "views/prepare-remove-background.php"); } elseif ('do_background_replace' === $action && check_admin_referer($action, '_wpnonce') && $this->useFeature('background') ) { require_once($this->plugin_path . 'views/do-replace-background.php'); } else { exit('Something went wrong loading page, please try again'); } break; } } public function getPluginURL($path = '') { return plugins_url($path, EMR_ROOT_FILE); } /** register styles and scripts * * Nothing should ever by -enqueued- here, just registered. */ public function admin_scripts() { if (is_rtl()) { wp_register_style('emr_style', plugins_url('css/admin.rtl.css', EMR_ROOT_FILE)); } else { wp_register_style('emr_style', plugins_url('css/admin.css', EMR_ROOT_FILE)); } wp_register_style('emr_edit-attachment', plugins_url('css/edit_attachment.css', EMR_ROOT_FILE)); wp_register_style('emr-remove-background', plugins_url('css/remove_background.css', EMR_ROOT_FILE)); $mimes = array_values(get_allowed_mime_types()); wp_register_script('emr_admin', plugins_url('js/emr_admin.js', EMR_ROOT_FILE), array('jquery'), EMR_VERSION, true); $emr_options = array( 'dateFormat' => $this->convertdate(get_option('date_format')), 'maxfilesize' => wp_max_upload_size(), 'allowed_mime' => $mimes, ); wp_register_script('emr_upsell', plugins_url('js/upsell.js', EMR_ROOT_FILE), array('jquery'), EMR_VERSION, true); wp_localize_script('emr_upsell', 'emr_upsell', array( 'ajax' => admin_url('admin-ajax.php'), 'installing' => __('Installing ...', 'enable-media-replace'), )); $ts = time(); $ajax_url = admin_url('admin-ajax.php'); wp_register_script('emr_remove_bg', plugins_url('js/remove_bg.js', EMR_ROOT_FILE), array('jquery'), EMR_VERSION, true); wp_localize_script('emr_remove_bg', 'emrObject', array( 'ajax_url' => $ajax_url, 'nonce' => wp_create_nonce('emr_remove_background') )); if (Log::debugIsActive()) { $emr_options['is_debug'] = true; } wp_localize_script('emr_admin', 'emr_options', $emr_options); } /** Utility function for the Jquery UI Datepicker */ public function convertdate($sFormat) { switch ($sFormat) { //Predefined WP date formats case 'F j, Y': return( 'MM dd, yy' ); break; case 'Y/m/d': return( 'yy/mm/dd' ); break; case 'm/d/Y': return( 'mm/dd/yy' ); break; case 'd/m/Y': default: return( 'dd/mm/yy' ); break; } } public function checkImagePermission($post) { if (! is_object($post)) { return false; } $post_id = $post->ID; $post_type = $post->post_type; $author_id = $post->post_author; if ($post_type !== 'attachment') return false; if (is_null($post_id) || intval($post_id) >! 0) { return false; } if ($this->general_cap === false && $this->user_cap === false) { if (current_user_can('edit_post', $post_id) === true) { return true; } } elseif (current_user_can($this->general_cap)) { return true; } elseif (current_user_can($this->user_cap) && $author_id == get_current_user_id()) { return true; } return false; } /** Get the URL to the media replace page * @param $attach_id The attachment ID to replace * @return Admin URL to the page. */ protected function getMediaReplaceURL($attach_id) { $url = admin_url("upload.php"); $url = add_query_arg(array( 'page' => 'enable-media-replace/enable-media-replace.php', 'action' => 'media_replace', 'attachment_id' => $attach_id, ), $url); return $url; } protected function getRemoveBgURL($attach_id) { $url = admin_url("upload.php"); $url = add_query_arg(array( 'page' => 'enable-media-replace/enable-media-replace.php', 'action' => 'emr_prepare_remove', 'attachment_id' => $attach_id, ), $url); return $url; } public function add_meta_boxes($post) { // Because some plugins don't like to play by the rules. if (is_null($post) || ! is_object($post) ) { return false; } if (! $this->checkImagePermission($post)) { return; } add_meta_box('emr-replace-box', __('Replace Media', 'enable-media-replace'), array($this, 'replace_meta_box'), 'attachment', 'side', 'low'); if (isset($_GET['emr_replaced']) && intval($_GET['emr_replaced'] == 1)) { add_meta_box('emr-showthumbs-box', __('Replaced Thumbnails Preview', 'enable-media-replace'), array($this, 'show_thumbs_box'), 'attachment', 'side', 'low'); } } public function replace_meta_box($post) { //Replace media button $replace_url = $this->getMediaReplaceURL($post->ID); $replace_action = "media_replace"; $replace_editurl = wp_nonce_url($replace_url, $replace_action); $replace_link = "href=\"$replace_editurl\""; echo "
" . esc_html__("Upload a new file", "enable-media-replace") . "
" . esc_html__("To replace the current file, click the link and upload a replacement file.", "enable-media-replace") . "
"; //Remove background button $removeBg_url = $this->getRemoveBgURL($post->ID); $removeBg_action = "emr_prepare_remove"; $removeBg_editurl = wp_nonce_url($removeBg_url, $removeBg_action); $removeBg_link = "href=\"$removeBg_editurl\""; if ($this->uiHelper()->isBackgroundRemovable($post)) { echo "" . esc_html__("Remove background", "enable-media-replace") . "
" . esc_html__("To remove the background, click the link and select the options.", "enable-media-replace") . "
"; } } public function show_thumbs_box($post) { if (! $this->checkImagePermission($post)) { return; } wp_enqueue_style('emr_edit-attachment'); $meta = wp_get_attachment_metadata($post->ID); if (! isset($meta['sizes'])) { echo __('Thumbnails were not generated', 'enable-media-replace'); return false; } if (function_exists('wp_get_original_image_url')) { // indicating WP 5.3+ $source_url = wp_get_original_image_url($post->ID); // oldway will give -scaled in case of scaling. $source_url_oldway = wp_get_attachment_url($post->ID); if ($source_url !== $source_url_oldway) { echo "