From 0302dc4a84291058ca9777fabf7e10d4c8a8d7ee Mon Sep 17 00:00:00 2001 From: Pedro Dobrescu Date: Tue, 21 Feb 2023 14:35:35 +0200 Subject: [PATCH 01/21] Move back the theme banner to the bottom position --- views/upsell.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/views/upsell.php b/views/upsell.php index f5eb6c8..7dd6a4f 100644 --- a/views/upsell.php +++ b/views/upsell.php @@ -31,13 +31,6 @@
- -
-

ShortPixel Theme

- -
- - @@ -103,7 +96,14 @@ - + + + +
+

ShortPixel Theme

+ +
+ Date: Tue, 21 Feb 2023 23:24:19 +0100 Subject: [PATCH 02/21] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 3d36eff..d44e618 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,9 @@ So `[file_modified id=870]` would display the last time the file with ID 870 was If you want more control over the format used to display the time, you can use the format option, so `[file_modified id=870 format=Y-m-d]` would display the file modification date but not the time. The format string uses [standard PHP date() formatting tags](http://php.net/manual/en/function.date.php). +## Disable background removal +If you don't want to utilize the background removal feature, add `add_filter('emr/feature/background', '__return_false' );` to your functions.php + *** See [Enable Media Replace](http://wordpress.org/plugins/enable-media-replace/) at WordPress.org for more information. From 91ec10643464de461abb932e98adcc3dff077512 Mon Sep 17 00:00:00 2001 From: Aaron Kessler <38891427+jstask82@users.noreply.github.com> Date: Tue, 21 Feb 2023 23:27:42 +0100 Subject: [PATCH 03/21] Update readme.txt --- readme.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/readme.txt b/readme.txt index 819bcd8..7c6a0eb 100644 --- a/readme.txt +++ b/readme.txt @@ -34,6 +34,8 @@ This plugin is very powerful and a must-have for all major websites built with W Similar to replacing media, you can also remove the background of the images from the Media Library! The background removal feature sends the images to ShortPixel's API, removes the background and sends them back in a preview window. If everything looks good, just replace the image with the one that has the background removed! If the source image is a PNG file, you will get a transparent background, while the other images default to a solid white background. You also have the option to choose a different color with an embedded color picker. The background removal feature is still in beta and will be free of charge for a reasonable usage. +If you don't want to utilize the background removal feature, add add_filter('emr/feature/background', '__return_false' ); to your functions.php + #### Show file modification time There is a shortcode that takes the file modification date and displays it in a post or on a page. The code is: From f2296c1f25492915dcfcbcae003dbe3b30e8a008 Mon Sep 17 00:00:00 2001 From: Bas Schuiling Date: Wed, 8 Mar 2023 18:45:52 -0600 Subject: [PATCH 04/21] EMR new version changes - Replacer class -> Replace module - Moved many items to proper classes - Removed redirects in favor or success / error screens --- build/shortpixel/composer.json | 2 +- .../filesystem/src/Model/File/FileModel.php | 2 +- .../notices/src/NoticeController.php | 2 +- build/shortpixel/replacer/composer.json | 18 + .../replacer/src/Modules/Elementor.php | 61 +++ .../replacer/src/Modules/WpBakery.php | 50 ++ .../replacer/src/Modules/YoastSeo.php | 71 +++ build/shortpixel/replacer/src/Replacer.php | 488 +++++++++++++++++ classes/Controller/ReplaceController.php | 497 ++++++++++++++++++ classes/ViewController.php | 136 +++++ .../RemoveBackgroundViewController.php | 155 ++++++ .../ViewController/ReplaceViewController.php | 71 +++ .../ViewController/UploadViewController.php | 221 ++++++++ classes/emr-plugin.php | 51 +- classes/replacer.php | 6 +- classes/uihelper.php | 238 +++++---- composer.json | 3 +- css/admin.css | 140 +++-- css/admin.css.map | 2 +- enable-media-replace.php | 12 +- js/emr_admin.js | 58 +- js/emr_success.js | 21 + js/remove_bg.js | 4 +- scss/_screens.scss | 38 ++ scss/admin.scss | 123 +++-- views/do-replace-background.php | 10 - views/error.php | 29 + views/prepare-remove-background.php | 87 ++- views/{popup.php => screen.php} | 92 ++-- views/success.php | 30 ++ views/upload.php | 11 - 31 files changed, 2362 insertions(+), 367 deletions(-) create mode 100644 build/shortpixel/replacer/composer.json create mode 100644 build/shortpixel/replacer/src/Modules/Elementor.php create mode 100644 build/shortpixel/replacer/src/Modules/WpBakery.php create mode 100644 build/shortpixel/replacer/src/Modules/YoastSeo.php create mode 100644 build/shortpixel/replacer/src/Replacer.php create mode 100644 classes/Controller/ReplaceController.php create mode 100644 classes/ViewController.php create mode 100644 classes/ViewController/RemoveBackgroundViewController.php create mode 100644 classes/ViewController/ReplaceViewController.php create mode 100644 classes/ViewController/UploadViewController.php create mode 100644 js/emr_success.js create mode 100644 scss/_screens.scss create mode 100644 views/error.php rename views/{popup.php => screen.php} (82%) create mode 100644 views/success.php diff --git a/build/shortpixel/composer.json b/build/shortpixel/composer.json index 91d9576..aaa99ea 100644 --- a/build/shortpixel/composer.json +++ b/build/shortpixel/composer.json @@ -1 +1 @@ -{"name":"EnableMediaReplace\/shortpixelmodules","description":"ShortPixel submodules","type":"function","autoload":{"psr-4":{"EnableMediaReplace\\ShortPixelLogger":"log\/src","EnableMediaReplace\\Notices":"notices\/src","EnableMediaReplace\\FileSystem":"filesystem\/src"}}} \ No newline at end of file +{"name":"EnableMediaReplace\/shortpixelmodules","description":"ShortPixel submodules","type":"function","autoload":{"psr-4":{"EnableMediaReplace\\ShortPixelLogger":"log\/src","EnableMediaReplace\\Notices":"notices\/src","EnableMediaReplace\\Replacer":"replacer\/src","EnableMediaReplace\\FileSystem":"filesystem\/src"}}} \ No newline at end of file diff --git a/build/shortpixel/filesystem/src/Model/File/FileModel.php b/build/shortpixel/filesystem/src/Model/File/FileModel.php index 1a6784a..80de549 100644 --- a/build/shortpixel/filesystem/src/Model/File/FileModel.php +++ b/build/shortpixel/filesystem/src/Model/File/FileModel.php @@ -591,7 +591,7 @@ private function relativeToFullPath($path) public function getPermissions() { if (is_null($this->permissions)) - $this->permissions = fileperms($this->fullpath) & 0777; + $this->permissions = fileperms($this->getFullPath()) & 0777; return $this->permissions; } diff --git a/build/shortpixel/notices/src/NoticeController.php b/build/shortpixel/notices/src/NoticeController.php index 7ba8f1f..20370b9 100644 --- a/build/shortpixel/notices/src/NoticeController.php +++ b/build/shortpixel/notices/src/NoticeController.php @@ -220,7 +220,7 @@ public function ajax_action() if (! is_null($id)) { - + $notice = $this->getNoticeByID($id); } else diff --git a/build/shortpixel/replacer/composer.json b/build/shortpixel/replacer/composer.json new file mode 100644 index 0000000..dad4e96 --- /dev/null +++ b/build/shortpixel/replacer/composer.json @@ -0,0 +1,18 @@ +{ + "name": "shortpixel/replacer", + "description": "Content Replacer", + "version": 1.1, + "type": "library", + "license": "MIT", + "authors": [ + { + "name": "Bas", + "email": "bas@weblogmechanic.com" + } + ], + "minimum-stability": "dev", + "require": {}, + "autoload": { + "psr-4": { "ShortPixel\\Replacer\\" : "src" } + } +} diff --git a/build/shortpixel/replacer/src/Modules/Elementor.php b/build/shortpixel/replacer/src/Modules/Elementor.php new file mode 100644 index 0000000..ffdc32f --- /dev/null +++ b/build/shortpixel/replacer/src/Modules/Elementor.php @@ -0,0 +1,61 @@ +elementor_is_active()) // elementor is active + { + add_filter('shortpixel/replacer/custom_replace_query', array($this, 'addElementor'), 10, 4); // custom query for elementor \ // problem + // @todo Fix this for SPIO + //add_action('enable-media-replace-upload-done', array($this, 'removeCache') ); + } + } + + public function addElementor($items, $base_url, $search_urls, $replace_urls) + { + $base_url = $this->addSlash($base_url); + $el_search_urls = $search_urls; //array_map(array($this, 'addslash'), $search_urls); + $el_replace_urls = $replace_urls; //array_map(array($this, 'addslash'), $replace_urls); + $items[$this->queryKey] = array('base_url' => $base_url, 'search_urls' => $el_search_urls, 'replace_urls' => $el_replace_urls); + return $items; + } + + public function addSlash($value) + { + global $wpdb; + $value= ltrim($value, '/'); // for some reason the left / isn't picked up by Mysql. + $value= str_replace('/', '\/', $value); + $value = $wpdb->esc_like(($value)); //(wp_slash) / str_replace('/', '\/', $value); + + return $value; + } + + protected function elementor_is_active() + { + $bool = false; + + if (defined('ELEMENTOR_VERSION')) + $bool = true; + + return apply_filters('emr/externals/elementor_is_active', $bool); // manual override + } + + public function removeCache() + { + \Elementor\Plugin::$instance->files_manager->clear_cache(); + } +} diff --git a/build/shortpixel/replacer/src/Modules/WpBakery.php b/build/shortpixel/replacer/src/Modules/WpBakery.php new file mode 100644 index 0000000..d543e9f --- /dev/null +++ b/build/shortpixel/replacer/src/Modules/WpBakery.php @@ -0,0 +1,50 @@ +bakery_is_active()) // elementor is active + { + add_filter('shortpixel/replacer/custom_replace_query', array($this, 'addURLEncoded'), 10, 4); // custom query for elementor \ // problem + } + } + + public function addUrlEncoded($items, $base_url, $search_urls, $replace_urls) + { + $base_url = $this->addEncode($base_url); + $el_search_urls = array_map(array($this, 'addEncode'), $search_urls); + $el_replace_urls = array_map(array($this, 'addEncode'), $replace_urls); + $items[$this->queryKey] = array('base_url' => $base_url, 'search_urls' => $el_search_urls, 'replace_urls' => $el_replace_urls); + return $items; + } + + public function addEncode($value) + { + return urlencode($value); + } + + protected function bakery_is_active() + { + $bool = false; + + // did_action -> wpbakery , VCV_version -> detect Visual Composer + if (did_action('vc_plugins_loaded') || defined('VCV_VERSION')) + $bool = true; + + return apply_filters('emr/externals/urlencode_is_active', $bool); // manual override + } +} diff --git a/build/shortpixel/replacer/src/Modules/YoastSeo.php b/build/shortpixel/replacer/src/Modules/YoastSeo.php new file mode 100644 index 0000000..2d7f97d --- /dev/null +++ b/build/shortpixel/replacer/src/Modules/YoastSeo.php @@ -0,0 +1,71 @@ +yoast_is_active()) // elementor is active + { + global $wpdb; + $this->yoastTable = $wpdb->prefix . 'yoast_indexable'; + + add_action('shortpixel/replacer/replace_urls', array($this, 'removeIndexes'),10,2); + } + } + + public function removeIndexes($search_urls, $replace_urls) + { + global $wpdb; + + $sql = 'DELETE FROM ' . $this->yoastTable . ' WHERE '; + $prepare = array(); + + $base = isset($search_urls['base']) ? $search_urls['base'] : null; + $file = isset($search_urls['file']) ? $search_urls['file'] : null; + + if (! is_null($base)) + { + $querySQL = $sql . ' twitter_image like %s or open_graph_image like %s '; + $querySQL = $wpdb->prepare($querySQL, '%' . $base . '%', '%' . $base . '%'); + + $wpdb->query($querySQL); + } + + if (! is_null($file)) + { + $querySQL = $sql . ' twitter_image like %s or open_graph_image like %s '; + $querySQL = $wpdb->prepare($querySQL, '%' . $file . '%', '%' . $file . '%'); + + $wpdb->query($querySQL); + } + + } + + protected function yoast_is_active() + { + if (defined('WPSEO_VERSION')) + { + return true; + } + return false; + } + + + + +} diff --git a/build/shortpixel/replacer/src/Replacer.php b/build/shortpixel/replacer/src/Replacer.php new file mode 100644 index 0000000..d4b570f --- /dev/null +++ b/build/shortpixel/replacer/src/Replacer.php @@ -0,0 +1,488 @@ +source_url = $source_url; + ///$this->target_url = $target_url; + $this->loadFormats(); + } + + // Load classes that handle alternative formats that can occur in the metadata / post data. + protected function loadFormats() + { + Modules\Elementor::getInstance(); + Modules\WpBakery::getInstance(); + Modules\YoastSeo::getInstance(); + } + + public function setSource($url) + { + $this->source_url = $url; + } + + public function getSource() + { + return $this->source_url; + } + + public function setTarget($url) + { + $this->target_url = $url; + } + + public function getTarget() + { + return $this->target_url; + } + + public function setSourceMeta($meta) + { + $this->source_metadata = $meta; + } + + public function setTargetMeta($meta) + { + $this->target_metadata = $meta; + } + + public function replace($args = array()) + { + if (is_null($this->source_url) || is_null($this->target_url)) + { + Log::addWarn('Replacer called without source or target '); + return false; + } + $defaults = array( + 'thumbnails_only' => false, + ); + + $errors = array(); + $args = wp_parse_args($args, $defaults); + + // Search-and-replace filename in post database + // @todo Check this with scaled images. + $base_url = parse_url($this->source_url, PHP_URL_PATH);// emr_get_match_url( $this->source_url); + $base_url = str_replace('.' . pathinfo($base_url, PATHINFO_EXTENSION), '', $base_url); + + /** Fail-safe if base_url is a whole directory, don't go search/replace */ + if (is_dir($base_url)) + { + Log::addError('Search Replace tried to replace to directory - ' . $base_url); + $errors[] = __('Fail Safe :: Source Location seems to be a directory.', 'enable-media-replace'); + return $errors; + } + + if (strlen(trim($base_url)) == 0) + { + Log::addError('Current Base URL emtpy - ' . $base_url); + $errors[] = __('Fail Safe :: Source Location returned empty string. Not replacing content','enable-media-replace'); + return $errors; + } + + // get relurls of both source and target. + $urls = $this->getRelativeURLS(); + + + if ($args['thumbnails_only']) + { + foreach($urls as $side => $data) + { + if (isset($data['base'])) + { + unset($urls[$side]['base']); + } + if (isset($data['file'])) + { + unset($urls[$side]['file']); + } + } + } + + $search_urls = $urls['source']; + $replace_urls = $urls['target']; + + /* If the replacement is much larger than the source, there can be more thumbnails. This leads to disbalance in the search/replace arrays. + Remove those from the equation. If the size doesn't exist in the source, it shouldn't be in use either */ + foreach($replace_urls as $size => $url) + { + if (! isset($search_urls[$size])) + { + Log::addDebug('Dropping size ' . $size . ' - not found in source urls'); + unset($replace_urls[$size]); + } + } + + Log::addDebug('Source', $this->source_metadata); + Log::addDebug('Target', $this->target_metadata); + /* If on the other hand, some sizes are available in source, but not in target, try to replace them with something closeby. */ + foreach($search_urls as $size => $url) + { + if (! isset($replace_urls[$size])) + { + $closest = $this->findNearestSize($size); + if ($closest) + { + $sourceUrl = $search_urls[$size]; + $baseurl = trailingslashit(str_replace(wp_basename($sourceUrl), '', $sourceUrl)); + Log::addDebug('Nearest size of source ' . $size . ' for target is ' . $closest); + $replace_urls[$size] = $baseurl . $closest; + } + else + { + Log::addDebug('Unset size ' . $size . ' - no closest found in source'); + } + } + } + + /* If source and target are the same, remove them from replace. This happens when replacing a file with same name, and +/- same dimensions generated. + + After previous loops, for every search there should be a replace size. + */ + foreach($search_urls as $size => $url) + { + $replace_url = isset($replace_urls[$size]) ? $replace_urls[$size] : false; + if ($url == $replace_url) // if source and target as the same, no need for replacing. + { + unset($search_urls[$size]); + unset($replace_urls[$size]); + } + } + + // If the two sides are disbalanced, the str_replace part will cause everything that has an empty replace counterpart to replace it with empty. Unwanted. + if (count($search_urls) !== count($replace_urls)) + { + Log::addError('Unbalanced Replace Arrays, aborting', array($search_urls, $replace_urls, count($search_urls), count($replace_urls) )); + $errors[] = __('There was an issue with updating your image URLS: Search and replace have different amount of values. Aborting updating thumbnails', 'enable-media-replace'); + return $errors; + } + + Log::addDebug('Doing meta search and replace -', array($search_urls, $replace_urls) ); + Log::addDebug('Searching with BaseuRL ' . $base_url); + + do_action('shortpixel/replacer/replace_urls', $search_urls, $replace_urls); + $updated = 0; + + $updated += $this->doReplaceQuery($base_url, $search_urls, $replace_urls); + + $replaceRuns = apply_filters('shortpixel/replacer/custom_replace_query', array(), $base_url, $search_urls, $replace_urls); + Log::addDebug("REPLACE RUNS", $replaceRuns); + foreach($replaceRuns as $component => $run) + { + Log::addDebug('Running additional replace for : '. $component, $run); + $updated += $this->doReplaceQuery($run['base_url'], $run['search_urls'], $run['replace_urls']); + } + //do_action('') + + Log::addDebug("Updated Records : " . $updated); + return $updated; + } + + private function doReplaceQuery($base_url, $search_urls, $replace_urls) + { + global $wpdb; + /* Search and replace in WP_POSTS */ + // Removed $wpdb->remove_placeholder_escape from here, not compatible with WP 4.8 + $posts_sql = $wpdb->prepare( + "SELECT ID, post_content FROM $wpdb->posts WHERE post_status = 'publish' AND post_content LIKE %s", + '%' . $base_url . '%'); + + $rs = $wpdb->get_results( $posts_sql, ARRAY_A ); + $number_of_updates = 0; + + if ( ! empty( $rs ) ) { + foreach ( $rs AS $rows ) { + $number_of_updates = $number_of_updates + 1; + // replace old URLs with new URLs. + + $post_content = $rows["post_content"]; + $post_id = $rows['ID']; + $replaced_content = $this->replaceContent($post_content, $search_urls, $replace_urls); + + if ($replaced_content !== $post_content) + { + + // $result = wp_update_post($post_ar); + $sql = 'UPDATE ' . $wpdb->posts . ' SET post_content = %s WHERE ID = %d'; + $sql = $wpdb->prepare($sql, $replaced_content, $post_id); + + $result = $wpdb->query($sql); + + if ($result === false) + { + Notice::addError('Something went wrong while replacing' . $result->get_error_message() ); + Log::addError('WP-Error during post update', $result); + } + } + + } + } + + $number_of_updates += $this->handleMetaData($base_url, $search_urls, $replace_urls); + return $number_of_updates; + } + + private function handleMetaData($url, $search_urls, $replace_urls) + { + global $wpdb; + + $meta_options = apply_filters('shortpixel/replacer/metadata_tables', array('post', 'comment', 'term', 'user')); + $number_of_updates = 0; + + foreach($meta_options as $type) + { + switch($type) + { + case "post": // special case. + $sql = 'SELECT meta_id as id, meta_key, meta_value FROM ' . $wpdb->postmeta . ' + WHERE post_id in (SELECT ID from '. $wpdb->posts . ' where post_status = "publish") AND meta_value like %s'; + $type = 'post'; + + $update_sql = ' UPDATE ' . $wpdb->postmeta . ' SET meta_value = %s WHERE meta_id = %d'; + break; + default: + $table = $wpdb->{$type . 'meta'}; // termmeta, commentmeta etc + + $meta_id = 'meta_id'; + if ($type == 'user') + $meta_id = 'umeta_id'; + + $sql = 'SELECT ' . $meta_id . ' as id, meta_value FROM ' . $table . ' + WHERE meta_value like %s'; + + $update_sql = " UPDATE $table set meta_value = %s WHERE $meta_id = %d "; + break; + } + + $sql = $wpdb->prepare($sql, '%' . $url . '%'); + + // This is a desparate solution. Can't find anyway for wpdb->prepare not the add extra slashes to the query, which messes up the query. + // $postmeta_sql = str_replace('[JSON_URL]', $json_url, $postmeta_sql); + $rsmeta = $wpdb->get_results($sql, ARRAY_A); + + if (! empty($rsmeta)) + { + foreach ($rsmeta as $row) + { + $number_of_updates++; + $content = $row['meta_value']; + + + $id = $row['id']; + + $content = $this->replaceContent($content, $search_urls, $replace_urls); //str_replace($search_urls, $replace_urls, $content); + + $prepared_sql = $wpdb->prepare($update_sql, $content, $id); + + Log::addDebug('Update Meta SQl' . $prepared_sql); + $result = $wpdb->query($prepared_sql); + + } + } + } // foreach + + return $number_of_updates; + } // function + + + + /** + * Replaces Content across several levels of possible data + * @param $content String The Content to replace + * @param $search String Search string + * @param $replace String Replacement String + * @param $in_deep Boolean. This is use to prevent serialization of sublevels. Only pass back serialized from top. + */ + private function replaceContent($content, $search, $replace, $in_deep = false) + { + //$is_serial = false; + $content = maybe_unserialize($content); + $isJson = $this->isJSON($content); + + if ($isJson) + { + $content = json_decode($content); + Log::addDebug('JSon Content', $content); + } + + if (is_string($content)) // let's check the normal one first. + { + $content = apply_filters('shortpixel/replacer/content', $content, $search, $replace); + + $content = str_replace($search, $replace, $content); + } + elseif (is_wp_error($content)) // seen this. + { + //return $content; // do nothing. + } + elseif (is_array($content) ) // array metadata and such. + { + foreach($content as $index => $value) + { + $content[$index] = $this->replaceContent($value, $search, $replace, true); //str_replace($value, $search, $replace); + if (is_string($index)) // If the key is the URL (sigh) + { + $index_replaced = $this->replaceContent($index, $search,$replace, true); + if ($index_replaced !== $index) + $content = $this->change_key($content, array($index => $index_replaced)); + } + } + } + elseif(is_object($content)) // metadata objects, they exist. + { + foreach($content as $key => $value) + { + $content->{$key} = $this->replaceContent($value, $search, $replace, true); //str_replace($value, $search, $replace); + } + } + + if ($isJson && $in_deep === false) // convert back to JSON, if this was JSON. Different than serialize which does WP automatically. + { + Log::addDebug('Value was found to be JSON, encoding'); + // wp-slash -> WP does stripslashes_deep which destroys JSON + $content = json_encode($content, JSON_UNESCAPED_SLASHES); + Log::addDebug('Content returning', array($content)); + } + elseif($in_deep === false && (is_array($content) || is_object($content))) + $content = maybe_serialize($content); + + return $content; + } + + private function change_key($arr, $set) { + if (is_array($arr) && is_array($set)) { + $newArr = array(); + foreach ($arr as $k => $v) { + $key = array_key_exists( $k, $set) ? $set[$k] : $k; + $newArr[$key] = is_array($v) ? $this->change_key($v, $set) : $v; + } + return $newArr; + } + return $arr; + } + + private function getRelativeURLS() + { + $dataArray = array( + 'source' => array('url' => $this->source_url, 'metadata' => $this->getFilesFromMetadata($this->source_metadata) ), + 'target' => array('url' => $this->target_url, 'metadata' => $this->getFilesFromMetadata($this->target_metadata) ), + ); + + // Log::addDebug('Source Metadata', $this->source_metadata); + // Log::addDebug('Target Metadata', $this->target_metadata); + + $result = array(); + + foreach($dataArray as $index => $item) + { + $result[$index] = array(); + $metadata = $item['metadata']; + + $baseurl = parse_url($item['url'], PHP_URL_PATH); + $result[$index]['base'] = $baseurl; // this is the relpath of the mainfile. + $baseurl = trailingslashit(str_replace( wp_basename($item['url']), '', $baseurl)); // get the relpath of main file. + + foreach($metadata as $name => $filename) + { + $result[$index][$name] = $baseurl . wp_basename($filename); // filename can have a path like 19/08 etc. + } + + } + // Log::addDebug('Relative URLS', $result); + return $result; + } + + + private function getFilesFromMetadata($meta) + { + $fileArray = array(); + if (isset($meta['file'])) + $fileArray['file'] = $meta['file']; + + if (isset($meta['sizes'])) + { + foreach($meta['sizes'] as $name => $data) + { + if (isset($data['file'])) + { + $fileArray[$name] = $data['file']; + } + } + } + return $fileArray; + } + + /** FindNearestsize + * This works on the assumption that when the exact image size name is not available, find the nearest width with the smallest possible difference to impact the site the least. + */ + private function findNearestSize($sizeName) + { + + if (! isset($this->source_metadata['sizes'][$sizeName]) || ! isset($this->target_metadata['width'])) // This can happen with non-image files like PDF. + { + // Check if metadata-less item is a svg file. Just the main file to replace all thumbnails since SVG's don't need thumbnails. + if (strpos($this->target_url, '.svg') !== false) + { + $svg_file = wp_basename($this->target_url); + return $svg_file; // this is the relpath of the mainfile. + } + + return false; + } + $old_width = $this->source_metadata['sizes'][$sizeName]['width']; // the width from size not in new image + $new_width = $this->target_metadata['width']; // default check - the width of the main image + + $diff = abs($old_width - $new_width); + // $closest_file = str_replace($this->relPath, '', $this->newMeta['file']); + $closest_file = wp_basename($this->target_metadata['file']); // mainfile as default + + foreach($this->target_metadata['sizes'] as $sizeName => $data) + { + $thisdiff = abs($old_width - $data['width']); + + if ( $thisdiff < $diff ) + { + $closest_file = $data['file']; + if(is_array($closest_file)) { $closest_file = $closest_file[0];} // HelpScout case 709692915 + if(!empty($closest_file)) { + $diff = $thisdiff; + $found_metasize = true; + } + } + } + + if(empty($closest_file)) return false; + + return $closest_file; + } + + /* Check if given content is JSON format. */ + private function isJSON($content) + { + if (is_array($content) || is_object($content)) + return false; // can never be. + + $json = json_decode($content); + return $json && $json != $content; + } + + +} // class diff --git a/classes/Controller/ReplaceController.php b/classes/Controller/ReplaceController.php new file mode 100644 index 0000000..55daf72 --- /dev/null +++ b/classes/Controller/ReplaceController.php @@ -0,0 +1,497 @@ +post_id = $post_id; + $this->setupSource(); + } + + public function getSourceFile() + { + return $this->sourceFile; + } + + public function setupParams($params) + { + Log::addTemp('Setup Params', $params); + $this->replaceType = ($params['replace_type'] === 'replace_and_search') ? self::MODE_SEARCHREPLACE : self::MODE_REPLACE; + + if ($this->replaceType == self::MODE_SEARCHREPLACE && true === $params['new_location'] && ! is_null($params['location_dir'])) + { + $this->new_location = $params['location_dir']; + } + + $this->timeMode = $params['timestamp_replace']; + $this->newDate = $params['new_date']; + + $this->new_filename = $params['new_filename']; + $this->tmpUploadPath = $params['uploadFile']; + + $targetFile = $this->setupTarget(); + if (is_null($targetFile)) + { + return false; + } + $this->targetFile = $this->fs()->getFile($targetFile); + + return true; + } + + public function returnLastError() + { + return $this->lastError; + } + + public function run() + { + do_action('wp_handle_replace', array('post_id' => $this->post_id)); + + // Set Source / and Source Metadata + $Replacer = new Replacer(); + $source_url = $this->getSourceUrl(); + $Replacer->setSource($source_url); + $Replacer->setSourceMeta(wp_get_attachment_metadata( $this->post_id )); + + $targetFileObj = $this->fs()->getFile($this->targetFile); + $directoryObj = $targetFileObj->getFileDir(); + $result = $directoryObj->check(); + + if ($result === false) + { + Log::addError('Directory creation for targetFile failed'); + } + + $this->removeCurrent(); // tries to remove the current files. + + $fileObj = $this->fs()->getFile($this->tmpUploadPath); + $copied = $fileObj->copy($targetFileObj); + + if (false === $copied) + { + if ($targetFileObj->exists()) + { + Log::addDebug('Copy declared failed, but target available'); + } + else { + $this->lastError = self::ERROR_COPY_FAILED; + } + } + + $deleted = $fileObj->delete(); + if (false === $deleted) + { + Log::addDebug('Temp file could not be removed. Permission issues?'); + } + + $permissions = $this->sourceFile->getPermissions(); + $this->targetFile->resetStatus(); // reinit target file because it came into existence. + + if ($permissions > 0) + chmod( $this->targetFile->getFullPath(), $permissions ); // restore permissions + else { + Log::addWarn('Setting permissions failed'); + } + + // Uspdate the file attached. This is required for wp_get_attachment_url to work. + // Using RawFullPath because FullPath does normalize path, which update_attached_file doesn't so in case of windows / strange Apspaths it fails. + $updated = update_attached_file($this->post_id, $this->targetFile->getRawFullPath() ); + if (! $updated) + { + Log::addError('Update Attached File reports as not updated or same value'); + } + + // Run the filter, so other plugins can hook if needed. + $filtered = apply_filters( 'wp_handle_upload', array( + 'file' => $this->targetFile->getFullPath(), + 'url' => $this->getTargetURL(), + 'type' => $this->targetFile->getMime(), + ), 'sideload'); + + // check if file changed during filter. Set changed to attached file meta properly. + if (isset($filtered['file']) && $filtered['file'] != $this->targetFile->getFullPath() ) + { + update_attached_file($this->post_id, $filtered['file'] ); + $this->targetFile = $this->fs()->getFile($filtered['file']); // handle as a new file + Log::addInfo('WP_Handle_upload filter returned different file', $filtered); + } + + $target_url = $this->getTargetURL(); + $Replacer->setTarget($target_url); + + // Check and update post mimetype, otherwise badly coded plugins cry. + $post_mime = get_post_mime_type($this->post_id); + $target_mime = $this->targetFile->getMime(); + + // update DB post mime type, if somebody decided to mess it up, and the target one is not empty. + if ($target_mime !== $post_mime && strlen($target_mime) > 0) + { + \wp_update_post(array('post_mime_type' => $this->targetFile->getMime(), 'ID' => $this->post_id)); + } + + $target_metadata = wp_generate_attachment_metadata( $this->post_id, $this->targetFile->getFullPath() ); + wp_update_attachment_metadata( $this->post_id, $target_metadata ); + + $Replacer->setTargetMeta($target_metadata); + //$this->target_metadata = $metadata; + + + /** If author is different from replacer, note this */ + $post_author = get_post_field( 'post_author', $this->post_id ); + $author_id = get_post_meta($this->post_id, '_emr_replace_author', true); + + if ( intval($post_author) !== get_current_user_id()) + { + update_post_meta($this->post_id, '_emr_replace_author', get_current_user_id()); + } + elseif ($author_id) + { + delete_post_meta($this->post_id, '_emr_replace_author'); + } + + + if ($this->replaceType == self::MODE_SEARCHREPLACE) + { + // Write new image title. + $title = $this->getNewTitle($target_metadata); + $excerpt = $this->getNewExcerpt($target_metadata); + $update_ar = array('ID' => $this->post_id); + $update_ar['post_title'] = $title; + $update_ar['post_name'] = sanitize_title($title); + if ($excerpt !== false) + { + $update_ar['post_excerpt'] = $excerpt; + } + $update_ar['guid'] = $target_url; //wp_get_attachment_url($this->post_id); + + $post_id = \wp_update_post($update_ar, true); + + global $wpdb; + // update post doesn't update GUID on updates. + $wpdb->update( $wpdb->posts, array( 'guid' => $target_url), array('ID' => $this->post_id) ); + //enable-media-replace-upload-done + + // @todo This error in general ever happens? Replace this one with proper Notices:addError; + if (is_wp_error($post_id)) + { + $this->lastError = self::ERROR_UPDATE_POST; + } + + } + + /// Here run the Replacer Module + $args = array( + 'thumbnails_only' => ($this->replaceType == self::MODE_SEARCHREPLACE) ? false : true, + ); + $Replacer->replace($args); + + // Here Updatedata and a ffew others. + $this->updateDate(); + + // Give the caching a kick. Off pending specifics. + $cache_args = array( + 'flush_mode' => 'post', + 'post_id' => $this->post_id, + ); + + $cache = new emrCache(); + $cache->flushCache($cache_args); + + do_action("enable-media-replace-upload-done", $target_url, $source_url, $this->post_id); + + return true; + } // run + + + protected function setupSource() + { + $source_file = false; + if (function_exists('wp_get_original_image_path')) // WP 5.3+ + { + $source_file = wp_get_original_image_path($this->post_id); + } + + if (false === $source_file) + { + $source_file = trim(get_attached_file($this->post_id, apply_filters( 'emr_unfiltered_get_attached_file', true ))); + } + + /* It happens that the SourceFile returns relative / incomplete when something messes up get_upload_dir with an error something. + This case shoudl be detected here and create a non-relative path anyhow.. + */ + if (! file_exists($source_file) && $source_file && 0 !== strpos( $source_file, '/' ) && ! preg_match( '|^.:\\\|', $source_file ) ) + { + $file = get_post_meta( $this->post_id, '_wp_attached_file', true ); + $uploads = wp_get_upload_dir(); + $source_file = $uploads['basedir'] . "/$source_file"; + } + + Log::addDebug('SourceFile ' . $source_file); + $this->sourceFile = $this->fs()->getFile($source_file); + } + + /** Returns a full target path to place to new file. Including the file name! **/ + protected function setupTarget() + { + $targetPath = null; + if ($this->replaceType == self::MODE_REPLACE) + { + $targetFile = $this->getSourceFile()->getFullPath(); // overwrite source + } + elseif ($this->replaceType == self::MODE_SEARCHREPLACE) + { + $path = (string) $this->getSourceFile()->getFileDir(); + $targetLocation = $this->getNewTargetLocation(); + if (false === is_null($this->new_location)) // Replace to another path. + { + $otherTarget = $this->fs()->getFile($targetLocation . $this->new_filename); + if ($otherTarget->exists()) + { + Notices::addError(__('In specificied directory there is already a file with the same name. Can\'t replace.', 'enable-media-replace')); + $this->lastError = self::ERROR_TARGET_EXISTS; + return null; + } + + $path = $targetLocation; // $this->target_location; // if all went well. + } + //if ($this->sourceFile->getFileName() == $this->targetName) + $targetpath = $path . $this->new_filename; + Log::addTemp('Search/Replace new location', $targetpath); + + + // If the source and target path AND filename are identical, user has wrong mode, just overwrite the sourceFile. + if ($targetpath == $this->sourceFile->getFullPath()) + { + $unique = $this->sourceFile->getFileName(); + $this->replaceMode == self::MODE_REPLACE; + } + else + { + $unique = wp_unique_filename($path, $this->new_filename); + } + $new_filename = apply_filters( 'emr_unique_filename', $unique, $path, $this->post_id ); + $targetFile = trailingslashit($path) . $new_filename; + } + if (is_dir($targetFile)) // this indicates an error with the source. + { + Log::addWarn('TargetFile is directory ' . $targetFile ); + $upload_dir = wp_upload_dir(); + if (isset($upload_dir['path'])) + { + $targetFile = trailingslashit($upload_dir['path']) . wp_unique_filename($targetFile, $this->new_filename); + } + else { + //$err = __('EMR could not establish a proper destination for replacement', 'enable-media-replace'); + //Notices::addError($err); + //Log::addError($err); + return self::ERROR_DESTINATION_FAIL; + // throw new \RuntimeException($err); + // exit($err); // fallback + // return null; + } + } + return $targetFile; + } + + protected function getNewTitle($meta) + { + // get basename without extension + $title = basename($this->targetFile->getFileName(), '.' . $this->targetFile->getExtension()); + // $meta = $this->target_metadata; + + if (isset($meta['image_meta'])) + { + if (isset($meta['image_meta']['title'])) + { + if (strlen($meta['image_meta']['title']) > 0) + { + $title = $meta['image_meta']['title']; + } + } + } + + // Thanks Jonas Lundman (http://wordpress.org/support/topic/add-filter-hook-suggestion-to) + $title = apply_filters( 'enable_media_replace_title', $title ); + + return $title; + } + + protected function getNewExcerpt($meta) + { + // $meta = $this->target_metadata; + $excerpt = false; + + if (isset($meta['image_meta'])) + { + if (isset($meta['image_meta']['caption'])) + { + if (strlen($meta['image_meta']['caption']) > 0) + { + $excerpt = $meta['image_meta']['caption']; + } + } + } + + return $excerpt; + } + + protected function getSourceUrl() + { + if (function_exists('wp_get_original_image_url')) // WP 5.3+ + { + $source_url = wp_get_original_image_url($this->post_id); + if ($source_url === false) // not an image, or borked, try the old way + $source_url = wp_get_attachment_url($this->post_id); + + $source_url = $source_url; + } + else + $source_url = wp_get_attachment_url($this->post_id); + + return $source_url; + } + + /** Handle new dates for the replacement */ + protected function updateDate() + { + global $wpdb; + $post_date = $this->newDate; + $post_date_gmt = get_gmt_from_date($post_date); + + $update_ar = array('ID' => $this->post_id); + if ($this->timeMode == static::TIME_UPDATEALL || $this->timeMode == static::TIME_CUSTOM) + { + $update_ar['post_date'] = $post_date; + $update_ar['post_date_gmt'] = $post_date_gmt; + } + else { + + } + $update_ar['post_modified'] = $post_date; + $update_ar['post_modified_gmt'] = $post_date_gmt; + + $updated = $wpdb->update( $wpdb->posts, $update_ar , array('ID' => $this->post_id) ); + + wp_cache_delete($this->post_id, 'posts'); + + } + + /** Tries to remove all of the old image, without touching the metadata in database + * This might fail on certain files, but this is not an indication of success ( remove might fail, but overwrite can still work) + */ + protected function removeCurrent() + { + $meta = \wp_get_attachment_metadata( $this->post_id ); + $backup_sizes = get_post_meta( $this->post_id, '_wp_attachment_backup_sizes', true ); + + // this must be -scaled if that exists, since wp_delete_attachment_files checks for original_files but doesn't recheck if scaled is included since that the one 'that exists' in WP . $this->source_file replaces original image, not the -scaled one. + $file = $this->sourceFile->getFullPath(); + $result = \wp_delete_attachment_files($this->post_id, $meta, $backup_sizes, $file ); + + // If Attached file is not the same path as file, this indicates a -scaled images is in play. + // Also plugins like Polylang tend to block delete image while there is translation / duplicate item somewhere + // 10/06/22 : Added a hard delete if file still exists. Be gone, hard way. + $attached_file = get_attached_file($this->post_id); + if (file_exists($attached_file)) + { + @unlink($attached_file); + } + + do_action( 'emr_after_remove_current', $this->post_id, $meta, $backup_sizes, $file ); + } + + /** Since WP functions also can't be trusted here in certain cases, create the URL by ourselves */ + protected function getTargetURL() + { + if (is_null($this->targetFile)) + { + Log::addTemp('TargetFile NULL', debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 10)); + } + //$uploads['baseurl'] + $url = wp_get_attachment_url($this->post_id); + $url_basename = basename($url); + + // Seems all worked as normal. + if (strpos($url, '://') >= 0 && $this->targetFile->getFileName() == $url_basename) + return $url; + + // Relative path for some reason + if (strpos($url, '://') === false) + { + $uploads = wp_get_upload_dir(); + $url = str_replace($uploads['basedir'], $uploads['baseurl'], $this->targetFile->getFullPath()); + } + // This can happen when WordPress is not taking from attached file, but wrong /old GUID. Try to replace it to the new one. + elseif ($this->targetFile->getFileName() != $url_basename) + { + $url = str_replace($url_basename, $this->targetFile->getFileName(), $url); + } + + return $url; + + } + + protected function getNewTargetLocation() + { + $uploadDir = wp_upload_dir(); + $new_rel_location = $this->new_location; + $newPath = trailingslashit($uploadDir['basedir']) . $new_rel_location; + + // Detect traversal by making sure the canonical path starts with uploads' basedir. + if (($newPath = realpath($newPath)) && strpos($newPath, $uploadDir['basedir']) !== 0) + { + Notices::addError(__('Specificed directory is outside the upload directory. This is not allowed for security reasons', 'enable-media-replace')); + return false; + } + + if (! is_dir($newPath)) + { + Notices::addError(__('Specificed new directory does not exist. Path must be a relative path from the upload directory and exist', 'enable-media-replace')); + return false; + } + return trailingslashit($newPath); + } + + + private function fs() + { + return emr()->filesystem(); + } +} diff --git a/classes/ViewController.php b/classes/ViewController.php new file mode 100644 index 0000000..4bbe2c3 --- /dev/null +++ b/classes/ViewController.php @@ -0,0 +1,136 @@ +view = new \stdClass; + } + + protected function loadView($template = null, $unique = true) + { + if (is_null($template) ) + { + return false; + } + elseif (strlen(trim($template)) == 0) + { + return false; + } + + $view = $this->view; + $controller = $this; + $template_path = emr()->plugin_path('views/' . $template . '.php'); + + if (file_exists($template_path) === false) + { + Log::addError("View $template could not be found in " . $template_path, + array('class' => get_class($this))); + } + elseif ($unique === false || ! in_array($template, self::$viewsLoaded)) + { + include($template_path); + self::$viewsLoaded[] = $template; + } + } + + protected function viewError($errorCode) + { + $message = false; + switch($errorCode) + { + case self::ERROR_UPLOAD_PERMISSION: + $message = __('You don\'t have permission to upload images. Please refer to your administrator', 'enable-media-replace'); + break; + case self::ERROR_IMAGE_PERMISSION: + $message = __('You don\'t have permission to edit this image', 'enable-media-replace'); + break; + case self::ERROR_FORM: + $message = __('The form submitted is missing various fields', 'enable-media-replace'); + break; + case self::ERROR_TIME: + $message = __('The custom time format submitted is invalid', 'enable-media-replace'); + break; + case self::ERROR_UPDATE_FAILED: + $message = __('Updating the WordPress attachment failed', 'enable-media-replace'); + break; + case self::ERROR_SECURITY: + $message = __('The file upload has been rejected for security reason. WordPress might not allow uploading this extension or filetype', 'enable-media-replace'); + break; + case self::ERROR_UPLOAD_FAILED: + $message = __('The upload from your browser seem to have failed', 'enable-media-replace'); + break; + case self::ERROR_TARGET_EXISTS: + $message = __('The target file already exists in this directory. Please try another name / directory', 'enable-media-replace'); + break; + case self::ERROR_DESTINATION_FAIL: + $message = __('Something went wrong while writing the file', 'enable-media-replace'); + break; + case self::ERROR_NONCE: + $message = __('Fail to validate form nonce. Please try again', 'enable-media-replace'); + break; + + // Remove Background + case self::ERROR_DOWNLOAD_FAILED: + $message = __('Replacement Image could not be downloaded or does not exist', 'enable-media-replace'); + break; + + default: + $message = __('An unknown error has occured', 'enable-media-replace'); + break; + } + + if( false !== $message) + $this->view->errorMessage = $message; + + $this->loadView('error'); + exit(); + } + + + protected function viewSuccess() + { + wp_enqueue_script('emr_success'); + $this->loadView('success'); + exit(); + } + + +} diff --git a/classes/ViewController/RemoveBackgroundViewController.php b/classes/ViewController/RemoveBackgroundViewController.php new file mode 100644 index 0000000..342fc23 --- /dev/null +++ b/classes/ViewController/RemoveBackgroundViewController.php @@ -0,0 +1,155 @@ +viewError(self::ERROR_UPLOAD_PERMISSION); + // wp_die(esc_html__('You do not have permission to upload files.', 'enable-media-replace')); + } + + $attachment_id = intval($_REQUEST['attachment_id']); + $attachment = get_post($attachment_id); + + $uiHelper = \emr()->uiHelper(); + $uiHelper->setPreviewSizes(); + $uiHelper->setSourceSizes($attachment_id); + + $replacer = new ReplaceController($attachment_id); + $file = $replacer->getSourceFile(); + + $defaults = array( + 'bg_type' => 'transparent', + 'bg_color' => '#ffffff', + 'bg_transparency' => 100, + ); + $settings = get_option('enable_media_replace', $defaults); + $settings = array_merge($defaults, $settings); // might miss some + + $this->view->attachment = $attachment; + $this->view->settings = $settings; + $this->view->sourceFile = $file; + + $this->loadView('prepare-remove-background'); + + } + + // When the background has been posted - process. + public function loadPost() + { + if ( ! isset( $_POST['emr_nonce'] ) + || ! wp_verify_nonce( $_POST['emr_nonce'], 'media_remove_background' )) + { + $this->viewError(self::ERROR_NONCE); + } + + $key = isset($_POST['key']) ? sanitize_text_field($_POST['key']) : null; + if (is_null($key) || strlen($key) == 0) + { + $this->viewError(self::ERROR_KEY); + //wp_die(esc_html__('Error while sending form (no key). Please try again.', 'enable-media-replace')); + } + + $post_id = isset($_POST['ID']) ? intval($_POST['ID']) : null; // sanitize, post_id. + if (is_null($post_id)) { + $this->viewError(self::ERROR_FORM); +// wp_die(esc_html__('Error in request. Please try again', 'enable-media-replace')); + } + + $this->setView($post_id); + $result = $this->replaceBackground($post_id, $key); + + if (false === $result->success) + { + $this->view->errorMessage = $result->message; + $this->viewError(); + } + elseif (! file_exists($result->image)) + { + $this->viewError(self::ERROR_DOWNLOAD_FAILED); + } + +// $result = $replacer->replaceWith($result->image, $source->getFileName() , true); +//$params = array(); + $replaceController = new ReplaceController($post_id); + $sourceFile = $replaceController->getSourceFile(); + + $datetime = current_time('mysql'); + + $params = array( + 'post_id' => $post_id, + 'replace_type' => 'replace', + 'timestamp_replace' => $timestamp_replace, + 'new_date' => $datetime, + 'is_custom_date' => false, + 'remove_background' => true, + 'uploadFile' => $result->image, + 'new_filename' => $sourceFile->getFileName(), + ); + + + $check = $replaceController->setupParams($params); + $this->setView($post_id, $params); + + if (false === $check) + { + $error = $replaceController->returnLastError(); + $this->viewError($error); + } + + $result = $replaceController->run(); + if (true == $result) + { + $this->viewSuccess(); + } + + } + + // Low init might only be w/ post_id ( error handling et al ), most advanced / nicer with params. + protected function setView($post_id, $params = array()) + { + $uiHelper = \emr()->uiHelper(); + $this->view->post_id = $post_id; + $this->view->postUrl = $uiHelper->getSuccesRedirect($post_id); + $this->view->emrUrl = $uiHelper->getFailedRedirect($post_id); + + } + + + protected function replaceBackground($post_id, $key) + { + $api = new Api(); + $result = $api->handleDownload($key); + + return $result; + } + + + +} // class diff --git a/classes/ViewController/ReplaceViewController.php b/classes/ViewController/ReplaceViewController.php new file mode 100644 index 0000000..3e95472 --- /dev/null +++ b/classes/ViewController/ReplaceViewController.php @@ -0,0 +1,71 @@ +checkImagePermission($attachment)) + { + $this->viewError(self::ERROR_IMAGE_PERMISSION); + wp_die( esc_html__('You do not have permission to upload files for this author.', 'enable-media-replace') ); + } + + $replacer = new ReplaceController($attachment_id); + + $file = $replacer->getSourceFile(); + /* $filepath = $file->getFullPath(); + $filename = $file->getFileName(); + $filetype = $file->getExtension(); */ + $source_mime = get_post_mime_type($attachment_id); + + $uiHelper = \emr()->uiHelper(); + $uiHelper->setPreviewSizes(); + $uiHelper->setSourceSizes($attachment_id); + + $defaults = array( + 'replace_type' => 'replace', + 'timestamp_replace' => \EnableMediaReplace\Replacer::TIME_UPDATEMODIFIED, + 'custom_date' => date("Y-m-d H:i:s"), + 'new_location' => false, + 'new_location_dir' => false, + ); + $settings = get_option('enable_media_replace', $defaults); + + $this->view->attachment = $attachment; + $this->view->sourceFile = $file; + $this->view->sourceMime = $source_mime; + $this->view->settings = array_merge($defaults, $settings); // might miss some + + $this->loadView('screen'); + + } + +} diff --git a/classes/ViewController/UploadViewController.php b/classes/ViewController/UploadViewController.php new file mode 100644 index 0000000..9e4cbc6 --- /dev/null +++ b/classes/ViewController/UploadViewController.php @@ -0,0 +1,221 @@ +setView($post_id); + + if (isset($_GET['emr_success'])) + { + $this->viewSuccess(); + } + + } + + if ( ! isset( $_POST['emr_nonce'] ) + || ! wp_verify_nonce( $_POST['emr_nonce'], 'media_replace_upload' )) + { + $this->viewError(self::ERROR_NONCE); + } + + if (!current_user_can('upload_files')) { + $this->viewError(self::ERROR_UPLOAD_PERMISSION); + // wp_die(esc_html__('You do not have permission to upload files.', 'enable-media-replace')); + } + + $post_id = isset($_POST['ID']) ? intval($_POST['ID']) : null; // sanitize, post_id. + if (is_null($post_id)) { + $this->viewError(self::ERROR_FORM); +// wp_die(esc_html__('Error in request. Please try again', 'enable-media-replace')); + } + $attachment = get_post($post_id); + + if (! emr()->checkImagePermission($attachment)) { + $this->viewError(self::ERROR_IMAGE_PERMISSION); +// wp_die(esc_html__('You do not have permission to upload files for this author.', 'enable-media-replace')); + } + + $params = $this->getPost(); + + // UploadController here / replacerController here with save Settings as well? s + $this->updateSettings($params); + $this->setView($post_id, $params); // set variables needed for view. + + $replaceController = new ReplaceController($post_id); + $check = $replaceController->setupParams($params); + + if (false === $check) + { + $error = $replaceController->returnLastError(); + $this->viewError($error); + } + + $result = $replaceController->run(); + + if (true == $result) + { + $this->viewSuccess(); + } + } + + + protected function getPost() + { + $ID = intval($_POST["ID"]); // legacy + $replace_type = isset($_POST["replace_type"]) ? sanitize_text_field($_POST["replace_type"]) : false; + $timestamp_replace = isset($_POST['timestamp_replace']) ? intval($_POST['timestamp_replace']) : Replacer::TIME_UPDATEMODIFIED; + + $remove_background = ( isset( $_POST['remove_after_progress'] ) ) ? true : false; + + $do_new_location = isset($_POST['new_location']) ? true : false; + $new_location_dir = isset($_POST['location_dir']) ? sanitize_text_field($_POST['location_dir']) : null; + + $is_custom_date = false; + + switch ($timestamp_replace) { + case \EnableMediaReplace\Replacer::TIME_UPDATEALL: + case \EnableMediaReplace\Replacer::TIME_UPDATEMODIFIED: + $datetime = current_time('mysql'); + break; + case \EnableMediaReplace\Replacer::TIME_CUSTOM: + $custom_date = $_POST['custom_date_formatted']; + $custom_hour = str_pad($_POST['custom_hour'], 2, 0, STR_PAD_LEFT); + $custom_minute = str_pad($_POST['custom_minute'], 2, 0, STR_PAD_LEFT); + + // create a mysql time representation from what we have. + Log::addDebug('Custom Date - ' . $custom_date . ' ' . $custom_hour . ':' . $custom_minute); + $custom_date = \DateTime::createFromFormat('Y-m-d G:i', $custom_date . ' ' . $custom_hour . ':' . $custom_minute); + if ($custom_date === false) { + wp_safe_redirect($redirect_error); + $errors = \DateTime::getLastErrors(); + $error = ''; + if (isset($errors['errors'])) { + $error = implode(',', $errors['errors']); + } + //Notices::addError(sprintf(__('Invalid Custom Date. Please check the custom date values: (%s)', 'enable-media-replace'), $error)); + $this->viewError(self::ERROR_TIME); + //exit(); + } + $datetime = $custom_date->format("Y-m-d H:i:s"); + $is_custom_date = true; + break; + } + + list($uploadFile, $new_filename) = $this->getUpload(); + + return array( + 'post_id' => $ID, + 'replace_type' => $replace_type, + 'timestamp_replace' => $timestamp_replace, + 'new_date' => $datetime, + 'new_location' => $do_new_location, + 'location_dir' => $new_location_dir, + 'is_custom_date' => $is_custom_date, + 'remove_background' => $remove_background, + 'uploadFile' => $uploadFile, + 'new_filename' => $new_filename, + ); + + } + + // Low init might only be w/ post_id ( error handling et al ), most advanced / nicer with params. + protected function setView($post_id, $params = array()) + { + $uiHelper = \emr()->uiHelper(); + $this->view->post_id = $post_id; + $this->view->postUrl = $uiHelper->getSuccesRedirect($post_id); + $this->view->emrUrl = $uiHelper->getFailedRedirect($post_id); + + if (isset($params['remove_background']) && true === $params['remove_background']) + { + $this->view->postUrl = $uiHelper->getBackgroundRemoveRedirect($post_id); + } + } + + + protected function updateSettings($params) + { + $settings = get_option('enable_media_replace', array()); // save settings and show last loaded. + $settings['replace_type'] = $params['replace_type']; + $settings['timestamp_replace'] = $params['timestamp_replace']; + $settings['new_location'] = $params['new_location']; + $settings['new_location_dir'] = $params['location_dir']; + + if (true === $params['is_custom_date']) + { + $settings['custom_date'] = $params['new_date']; + } +Log::addTemp('Saving settings', $settings); + update_option('enable_media_replace', $settings, false); + + } + + protected function getUpload() + { + if (is_uploaded_file($_FILES["userfile"]["tmp_name"])) { + Log::addDebug('Uploaded Files', $_FILES['userfile']); + + // New method for validating that the uploaded file is allowed, using WP:s internal wp_check_filetype_and_ext() function. + $filedata = wp_check_filetype_and_ext($_FILES["userfile"]["tmp_name"], $_FILES["userfile"]["name"]); + + Log::addDebug('Data after check', $filedata); + if (isset($_FILES['userfile']['error']) && $_FILES['userfile']['error'] > 0) { + //$e = new RunTimeException('File Uploaded Failed'); + //Notices::addError($e->getMessage()); + // wp_safe_redirect($redirect_error); + $this->viewError(self::ERROR_UPDATE_FAILED); + // exit(); + } + + if ($filedata["ext"] == false && ! current_user_can('unfiltered_upload')) { +// Log::addWarn('Uploaded File type does not meet security guidelines, aborting'); + $this->viewError(self::ERROR_SECURITY); + } + + // Here we have the uploaded file + $new_filename = $_FILES["userfile"]["name"]; + $new_filetype = $filedata["type"] ? $filedata["type"] : $_FILES['userfile']['type']; + + return array($_FILES["userfile"]["tmp_name"], $new_filename); + // Execute hook actions - thanks rubious for the suggestion! + } + $this->viewError(self::ERROR_UPLOAD_FAILED); + } + + + + +} // class diff --git a/classes/emr-plugin.php b/classes/emr-plugin.php index 3459d45..efab595 100644 --- a/classes/emr-plugin.php +++ b/classes/emr-plugin.php @@ -110,6 +110,7 @@ protected function nopriv_plugin_actions() add_shortcode('file_modified', array($this, 'get_modified_date')); } + public function plugin_actions() { $this->plugin_path = plugin_dir_path(EMR_ROOT_FILE); @@ -204,7 +205,6 @@ public function setScreen() add_action('admin_notices', array($notices, 'admin_notices')); // previous page / init time } - // var_dump($screen); } /** Load EMR views based on request */ @@ -221,23 +221,24 @@ public function route() $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. + + $controller = \EnableMediaReplace\ViewController\ReplaceViewController::getInstance(); + $controller->load(); +// 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'); + + $controller = \EnableMediaReplace\ViewController\UploadViewController::getInstance(); + $controller->load(); + // 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); +// $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'); @@ -245,19 +246,26 @@ public function route() 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"); + + $controller = \EnableMediaReplace\ViewController\RemoveBackgroundViewController::getInstance(); + $controller->load(); + + // 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'); + $controller = \EnableMediaReplace\ViewController\RemoveBackgroundViewController::getInstance(); + $controller->loadPost(); + + // require_once($this->plugin_path . 'views/do-replace-background.php'); } else { + exit('Something went wrong loading page, please try again'); } break; - } + } // Route } public function getPluginURL($path = '') @@ -265,6 +273,15 @@ public function getPluginURL($path = '') return plugins_url($path, EMR_ROOT_FILE); } + public function plugin_path($path = '') + { + $plugin_path = trailingslashit(plugin_dir_path(EMR_ROOT_FILE)); + if ( strlen( $path ) > 0 ) { + $plugin_path .= $path; + } + return $plugin_path; + } + /** register styles and scripts * * Nothing should ever by -enqueued- here, just registered. @@ -314,6 +331,8 @@ public function admin_scripts() } wp_localize_script('emr_admin', 'emr_options', $emr_options); + + wp_register_script('emr_success', plugins_url('js/emr_success.js', EMR_ROOT_FILE), array(), EMR_VERSION, true); } /** Utility function for the Jquery UI Datepicker */ @@ -535,9 +554,9 @@ public function add_media_action($actions, $post) return $actions; } - $url = $this->getMediaReplaceURL($post->ID); + $media_replace_editurl = $this->getMediaReplaceURL($post->ID); $media_replace_action = "media_replace"; - $media_replace_editurl = wp_nonce_url($url, $media_replace_action); + // $media_replace_editurl = wp_nonce_url($url, $media_replace_action); $url = $this->getRemoveBgURL($post->ID); $background_remove_action = "emr_prepare_remove"; $background_remove_editurl = wp_nonce_url($url, $background_remove_action); diff --git a/classes/replacer.php b/classes/replacer.php index 5302e72..cc3fd4b 100644 --- a/classes/replacer.php +++ b/classes/replacer.php @@ -50,7 +50,7 @@ public function __construct($post_id) if (false === $source_file) { - $source_file = trim(get_attached_file($post_id, apply_filters( 'emr_unfiltered_get_attached_file', true ))); + $source_file = trim(get_attached_file($post_id, apply_filters( 'emr_unfiltered_get_attached_file', true ))); } /* It happens that the SourceFile returns relative / incomplete when something messes up get_upload_dir with an error something. @@ -211,6 +211,7 @@ public function replaceWith($file, $fileName) delete_post_meta($this->post_id, '_emr_replace_author'); } + if ($this->replaceMode == self::MODE_SEARCHREPLACE) { // Write new image title. @@ -243,6 +244,8 @@ public function replaceWith($file, $fileName) } // SEARCH REPLACE MODE + +// FROM HERE STATS THE MODULE $args = array( 'thumbnails_only' => ($this->replaceMode == self::MODE_SEARCHREPLACE) ? false : true, ); @@ -433,7 +436,6 @@ protected function getTargetURL() } return $url; - //$this->targetFile } diff --git a/classes/uihelper.php b/classes/uihelper.php index c609189..3ad645b 100644 --- a/classes/uihelper.php +++ b/classes/uihelper.php @@ -43,7 +43,7 @@ public function getFormUrl($attach_id, $action = null) $url = admin_url('upload.php'); $url = add_query_arg(array( 'page' => 'enable-media-replace/enable-media-replace.php', - 'noheader' => true, + // 'noheader' => true, 'action' => $action, 'attachment_id' => $attach_id, )); @@ -64,10 +64,10 @@ public function getFormUrl($attach_id, $action = null) } - public function getSuccesRedirect($post_id) + public function getSuccesRedirect($attach_id) { $url = admin_url('post.php'); - $url = add_query_arg(array('action' => 'edit', 'post' => $post_id, 'emr_replaced' => '1'), $url); + $url = add_query_arg(array('action' => 'edit', 'post' => $attach_id, 'emr_replaced' => '1'), $url); if (isset($_REQUEST['SHORTPIXEL_DEBUG'])) { @@ -87,6 +87,21 @@ public function getSuccesRedirect($post_id) } + public function getBackgroundRemoveRedirect($attach_id) + { + //if ( isset( $_POST['remove_after_progress'] ) ) { + $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); + +// $redirect_success = $url; + return $url; + // } + } + public function getFailedRedirect($attach_id) { $url = admin_url('upload.php'); @@ -124,102 +139,6 @@ public function setSourceSizes($attach_id) } - // Returns Preview Image HTML Output. - public function getPreviewImage($attach_id,$file, $args = array()) - { - $data = false; - - if ($attach_id > 0) - { - $data = $this->getImageSizes($attach_id, $this->preview_size); //wp_get_attachment_image_src($attach_id, $this->preview_size); - /*$file = get_attached_file($attach_id); - - - // If the file is relative, prepend upload dir. - if (! file_exists($file) && $file && 0 !== strpos( $file, '/' ) && ! preg_match( '|^.:\\\|', $file ) ) - { - $file = get_post_meta( $attach_id, '_wp_attached_file', true ); - $uploads = wp_get_upload_dir(); - $file = $uploads['basedir'] . "/$file"; - } - */ - } - - $mime_type = get_post_mime_type($attach_id); - - if (! is_array($data) || ! $file->exists() ) - { - // if attachid higher than zero ( exists ) but not the image, fail, that's an error state. - $icon = ($attach_id < 0) ? '' : 'dashicons-no'; - $is_document = false; - - $defaults = array( - 'width' => $this->preview_width, - 'height' => $this->preview_height, - 'is_image' => false, - 'is_document' => $is_document, - 'icon' => $icon, - 'mime_type' => null, - ); - - $args = wp_parse_args($args, $defaults); - - // failed, it might be this server doens't support PDF thumbnails. Fallback to File preview. - if ($mime_type == 'application/pdf') - { - return $this->getPreviewFile($attach_id, $file); - } - - return $this->getPlaceHolder($args); - } - - $url = $data[0]; - $width = $data[1]; - $height = $data[2]; - - // width - $width_ratio = $height_ratio = 0; - if ($width > $this->preview_max_width) - { - $width_ratio = $width / $this->preview_max_width; - } - if ($height > $this->preview_max_height) // height - { - $height_ratio = $height / $this->preview_max_height; - } - - $ratio = ($width_ratio > $height_ratio) ? $width_ratio : $height_ratio; - - if ($ratio > 0) - { - - $width = floor($width / $ratio); - $height = floor($height / $ratio); - } - - // SVG's without any helpers return around 0 for width / height. Fix preview. - - - // preview width, if source if found, should be set to source. - $this->preview_width = $width; - $this->preview_height = $height; - - $image = ""; - - $defaults = array( - 'width' => $width, - 'height' => $height, - 'image' => $image, - 'mime_type' => $mime_type, - 'file_size' => $file->getFileSize(), - ); - - $args = wp_parse_args($args, $defaults); - - $output = $this->getPlaceHolder($args); - return $output; - } - protected function getImageSizes($attach_id, $size = 'thumbnail') { // We are not using this function, because depending on the theme, it can mess with the dimensions - https://wordpress.stackexchange.com/questions/167525/why-is-wp-get-attachment-image-src-returning-wrong-dimensions @@ -282,6 +201,93 @@ protected function fixSVGSize($data, $file) return $data; } + // Returns Preview Image HTML Output. + public function getPreviewImage($attach_id,$file, $args = array()) + { + $data = false; + + if ($attach_id > 0) + { + $data = $this->getImageSizes($attach_id, $this->preview_size); //wp_get_attachment_image_src($attach_id, $this->preview_size); + } + + $mime_type = get_post_mime_type($attach_id); + + if (! is_array($data) || ! $file->exists() ) + { + // if attachid higher than zero ( exists ) but not the image, fail, that's an error state. + $icon = ($attach_id < 0) ? '' : 'dashicons-no'; + $is_document = false; + + $defaults = array( + 'width' => $this->preview_width, + 'height' => $this->preview_height, + 'is_image' => false, + 'is_document' => $is_document, + 'is_upload' => false, + 'icon' => $icon, + 'mime_type' => null, + ); + + $args = wp_parse_args($args, $defaults); + + // failed, it might be this server doens't support PDF thumbnails. Fallback to File preview. + if ($mime_type == 'application/pdf') + { + return $this->getPreviewFile($attach_id, $file); + } + + return $this->getPlaceHolder($args); + } + + $url = $data[0]; + $width = $data[1]; + $height = $data[2]; + + // width + $width_ratio = $height_ratio = 0; + if ($width > $this->preview_max_width) + { + $width_ratio = $width / $this->preview_max_width; + } + if ($height > $this->preview_max_height) // height + { + $height_ratio = $height / $this->preview_max_height; + } + + $ratio = ($width_ratio > $height_ratio) ? $width_ratio : $height_ratio; + + if ($ratio > 0) + { + + $width = floor($width / $ratio); + $height = floor($height / $ratio); + } + + // SVG's without any helpers return around 0 for width / height. Fix preview. + + + // preview width, if source if found, should be set to source. + $this->preview_width = $width; + $this->preview_height = $height; + + $image = ""; + + $defaults = array( + 'width' => $width, + 'height' => $height, + 'image' => $image, + 'mime_type' => $mime_type, + 'is_upload' => false, + 'file_size' => $file->getFileSize(), + ); + + $args = wp_parse_args($args, $defaults); + + $output = $this->getPlaceHolder($args); + return $output; + } + public function getPreviewError($attach_id) { $args = array( @@ -294,7 +300,7 @@ public function getPreviewError($attach_id) return $output; } - public function getPreviewFile($attach_id, $file) + public function getPreviewFile($attach_id, $file, $args = array()) { if ($attach_id > 0) { @@ -311,15 +317,19 @@ public function getPreviewFile($attach_id, $file) $mime_type = get_post_mime_type($attach_id); } - $args = array( + $defaults = array( 'width' => 300, 'height' => 300, 'is_image' => false, 'is_document' => true, + 'is_upload' => false, 'layer' => $filename, 'mime_type' => $mime_type, 'file_size' => $file->getFileSize(), ); + $args = wp_parse_args($args, $defaults); + + $output = $this->getPlaceHolder($args); return $output; } @@ -356,6 +366,7 @@ public function getPlaceHolder($args) 'layer' => $this->full_width . ' x ' . $this->full_height, 'is_image' => true, 'is_document' => false, + 'is_upload' => false, // indicating right-side upload interface for image. 'mime_type' => false, 'file_size' => false, 'remove_bg_ui' => false, // In process icons et al when removing background, for preview pane. @@ -387,6 +398,11 @@ public function getPlaceHolder($args) $placeholder_class .= ' is_document'; } + if (true == $args['is_upload']) + { + $placeholder_class .= ' upload-file-action'; + } + $filetype = ''; if ($args['mime_type']) { @@ -395,18 +411,30 @@ public function getPlaceHolder($args) $filesize = ($args['file_size']) ? $args['file_size'] : ''; - $background_remove_ui = (isset($args['remove_bg_ui']) && $args['remove_bg_ui'] == true) ? $this->getBgremoveUI() : ''; + $is_backgroundremove_ui = (isset($args['remove_bg_ui']) && $args['remove_bg_ui'] == true); + $background_remove_ui = ($is_backgroundremove_ui) ? $this->getBgremoveUI() : ''; $output = "
"; - $output .= $args['image']; + if (true === $args['is_upload']) + { + $output .= "" . __('New', 'enable-media-replacer') . ""; + $output .= ''; + $output .= '
+ ' . __('Click here to upload or drop file in area', 'enable-media-replace') . ' +
'; + } + else + { + $title = (true === $is_backgroundremove_ui ) ? __('Preview', 'enable-media-replace') : __('Current', 'enable-media-replace'); + $output .= "" . $title . ""; + $output .= $args['image']; + } $output .= "
 
"; $output .= "" . $args['layer'] . ""; $output .= $background_remove_ui; $output .= "
" . $this->convertFileSize($filesize). "
"; $output .= "
"; - - return $output; } diff --git a/composer.json b/composer.json index 43fd0b9..8623d06 100644 --- a/composer.json +++ b/composer.json @@ -14,7 +14,8 @@ "require": { "shortpixel/notices":"@dev", "shortpixel/build" : "@dev", - "shortpixel/filesystem" : "@dev" + "shortpixel/filesystem" : "@dev", + "shortpixel/replacer" : ">=1.0" }, "require-dev": { "phpunit/phpunit": "^9", diff --git a/css/admin.css b/css/admin.css index 6566f22..bc936c8 100644 --- a/css/admin.css +++ b/css/admin.css @@ -984,6 +984,62 @@ border-bottom-right-radius: 3px; } +.enable-media-replace.emr-screen { + width: 90%; + background: #fff; + border: 1px solid #fff; + position: relative; + margin: 30px 0; +} +.enable-media-replace.emr-screen h3 { + font-size: 24px; + position: absolute; + top: -15px; + left: 30px; + padding: 16px 8px; + border: 1px solid #000; + background: #fff; + margin: 0; +} +.enable-media-replace.emr-screen .content { + padding: 32px; +} +.enable-media-replace.emr-screen h1 { + font-weight: 700; +} +.enable-media-replace.emr-screen p { + font-size: 14px; +} +.enable-media-replace.emr-screen .hide { + display: none; +} +.enable-media-replace.emr-screen.error-screen h1 { + color: #ff0000; +} + +#emr-drop-area-active { + position: fixed; + left: 0; + right: 0; + top: 0; + bottom: 0; + z-index: 9999; + display: block; + background: rgba(0, 0, 0, 0.5); + border: 6px dashed #AAA; +} +#emr-drop-area-active h3 { + font-size: 36px; + color: #ddd; + width: 200px; + left: 50%; + top: 50%; + position: absolute; +} +#emr-drop-area-active .drop-wrapper { + margin: 0 auto; +} + .emr_upload_form form { display: flex; } @@ -993,6 +1049,9 @@ .emr_upload_form .editor-wrapper { width: 100%; } +.emr_upload_form .emr_drop_area { + display: none; +} .emr_upload_form .wrapper { padding: 18px; border: 1px solid #ccc; @@ -1003,50 +1062,18 @@ padding: 6px 0; margin: 0 0 15px 0; } +.emr_upload_form .explainer { + font-size: 14px; + color: #555; + max-width: 800px; + margin: 20px 0; +} .emr_upload_form .image_chooser.wrapper { min-height: 350px; } -.emr_upload_form .image_chooser.wrapper .emr_drop_area { - border: 4px dashed #b4b9be; - max-width: 600px; - padding: 28px 14px; - text-align: center; - position: relative; -} -.emr_upload_form .image_chooser.wrapper .emr_drop_area h1 { - display: none; -} -.emr_upload_form .image_chooser.wrapper .emr_drop_area .drop-wrapper { - margin: 0 auto; -} -.emr_upload_form .image_chooser.wrapper .emr_drop_area.drop_breakout { - position: fixed; - left: 0; - right: 0; - bottom: 0; - top: 0; - max-width: none; - border-color: #83b4d8; - border-width: 10px; - z-index: 999999; - background-color: rgba(68, 68, 68, 0.7); -} -.emr_upload_form .image_chooser.wrapper .emr_drop_area.drop_breakout h1 { - color: #fff; - position: absolute; - font-size: 50px; - line-height: 50px; - margin-top: -25px; - top: 50%; - width: 100%; - text-align: center; - display: block; -} -.emr_upload_form .image_chooser.wrapper .emr_drop_area.drop_breakout .drop-wrapper { - display: none; -} .emr_upload_form .image_chooser.wrapper .image_previews { margin: 15px 0; + position: relative; } .emr_upload_form .image_chooser.wrapper .image_previews .image_placeholder { position: relative; @@ -1055,6 +1082,21 @@ margin-bottom: 10px; border: 1px solid #ddd; vertical-align: top; + box-sizing: border-box; + background: #fff; +} +.emr_upload_form .image_chooser.wrapper .image_previews .image_placeholder .upload-title { + text-align: center; + position: absolute; + padding-top: 8px; + line-height: 20px; + font-weight: 700; + width: 100%; + left: 0; + top: 0; +} +.emr_upload_form .image_chooser.wrapper .image_previews .image_placeholder #upload-file { + display: none; } .emr_upload_form .image_chooser.wrapper .image_previews .image_placeholder .textlayer { font-size: 25px; @@ -1068,6 +1110,7 @@ border: 1px dashed #eee; background-color: #333; padding: 8px; + z-index: 5; } .emr_upload_form .image_chooser.wrapper .image_previews .image_placeholder .dashicons { font-size: 60px; @@ -1084,6 +1127,25 @@ bottom: -25px; width: 100%; } +.emr_upload_form .image_chooser.wrapper .image_previews .image_placeholder .drag-and-drop-title { + text-align: center; + font-weight: 400; + font-size: 14px; + width: 100%; + height: 100%; + position: absolute; + cursor: pointer; + top: 0; + left: 0; + z-index: 1; +} +.emr_upload_form .image_chooser.wrapper .image_previews .image_placeholder .drag-and-drop-title span { + position: absolute; + top: 50%; + transform: translate(-50%, -50%); + padding: 5px 10px; + width: 100%; +} .emr_upload_form .image_chooser.wrapper .image_previews .image_placeholder.is_image .dashicons::before, .emr_upload_form .image_chooser.wrapper .image_previews .image_placeholder.is_image .dashicons { display: none; } diff --git a/css/admin.css.map b/css/admin.css.map index 26b57c0..8100da0 100644 --- a/css/admin.css.map +++ b/css/admin.css.map @@ -1 +1 @@ -{"version":3,"sourceRoot":"","sources":["../scss/_datepicker.scss","../scss/admin.scss"],"names":[],"mappings":"AAEA;EACC;EACA;EACA;;;AAID;EACC;EACA;EACA;EACA;EACA;;;AAED;EACC;EACA;EACA;;;AAED;EACC;EACA;;;AAED;AAAA;EAEC;EACA;EACA;EACA;;;AAED;AAAA;EAEC;;;AAED;EACC;;;AAED;EACC;;;AAED;EACC;;;AAED;EACC;;;AAED;AAAA;EAEC;EACA;EACA;EACA;EACA;EACA;;;AAED;EACC;EACA;EACA;;;AAED;EACC;EACA;;;AAED;AAAA;EAEC;;;AAED;EACC;EACA;EACA;EACA;;;AAED;EACC;EACA;EACA;EACA;;;AAED;EACC;EACA;;;AAED;AAAA;EAEC;EACA;EACA;EACA;;;AAED;EACC;EACA;EACA;EACA;EACA;EACA;;;AAED;EACC;EACA;EACA;EACA;EACA;EACA;;;AAED;EACC;;;AAGD;AACA;EACC;;;AAED;EACC;;;AAED;EACC;EACA;;;AAED;EACC;;;AAED;EACC;;;AAED;EACC;;;AAED;AAAA;EAEC;;;AAED;EACC;;;AAED;EACC;EACA;EACA;;;AAGD;AACA;EACC;;;AAED;EACC;EACA;;;AAED;EACC;EACA;;;AAED;EACC;EACA;;;AAED;EACC;EACA;;;AAED;EACC;;;AAED;EACC;;;AAED;AAAA;EAEC;;;AAED;AAAA;EAEC;EACA;;;AAGD;AACA;EACC;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;;;AAED;AAAA;EAEC;;;AAED;EACC;;;AAED;AAAA;AAAA;AAAA;EAIC;;;AAED;AAAA;EAEC;;;AAED;AAAA;EAEC;;;AAGD;AACA;EAAiB;;;AACjB;EAAqB;;;AACrB;EAAsB;;;AACtB;EAAqB;;;AACrB;EAAsB;;;AACtB;EAAqB;;;AACrB;EAAsB;;;AACtB;EAAqB;;;AACrB;EAAsB;;;AACtB;EAAuB;;;AACvB;EAAuB;;;AACvB;EAAwB;;;AACxB;EAAyB;;;AACzB;EAAwB;;;AACxB;EAAyB;;;AACzB;EAAwB;;;AACxB;EAAyB;;;AACzB;EAAwB;;;AACxB;EAAyB;;;AACzB;EAA0B;;;AAC1B;EAA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AAK;;AACL;EAEE;;AAGF;EAEI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EAAgB;;AAGtB;EAEE;;AACA;EAEE;EACA;EACA;EACA;EACA;EACA;;AAEA;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EAEG;EACA;EACA;EACA;;AAID;EAAiC;;AAMjC;EAAM;;AACN;EAAa;;AAEX;EACE;EACA;EACA;;AASZ;EAEE;EACA;EACA;EAEA;EACA;;AACA;EACI;EACA;EACA;;AAIN;EAEE;;AAGF;EAEE;;AAGF;EAEE;EACA;EACA;;AACA;EAEE;EACA;;AAKA;EAEE;;AAEF;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;;AAOR;EAEE;EACA;EACA;EACA;;AAGE;EACE;;AAEF;EAEE;;AAGN;EAEE;;AACA;EACC;EACA;;AAOG;EAEE;;AAMJ;EAAQ;;AAEV;EAEE;EACA;EACA;;AAEF;EAEE;EACA;EACA;;AACA;EACE;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;;AACA;EAEE;EACA;EACA;;AAIN;EAEE;EACA;;AACA;EAEE;EACA;;AAKN;EAEE;EACA;EACA;EACA;;AACA;EAEE;EACA;;AAIJ;EAEG;;AAIH;EAEE;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;EACF;;AACE;EACE;EACA;EACA;EACA;EACA;;AAEJ;EAEE;EACA;;AAEF;EAAO;;AACP;EAAQ;;AACR;EAAQ;;AACR;EAAS;;AACR;EACE;;AAED;EAEE;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACJ;;AAGF;EAAU;;AAER;EAEE;EACA;;AACA;EAAM;EAAkB;EAAmB;;AAU/C;EAEE;;AAEF;EAEE;;AACA;EACC;;AAKH;EAEI;IAEG;;EAEH;IACE;;EACA;IACE;;;AAGR;EAEE;IAAkB;;;AAErB;EAEE;IACE;IACA;IACA;;EAIA;IACE;IACD","file":"admin.css"} \ No newline at end of file +{"version":3,"sourceRoot":"","sources":["../scss/_datepicker.scss","../scss/_screens.scss","../scss/admin.scss"],"names":[],"mappings":"AAEA;EACC;EACA;EACA;;;AAID;EACC;EACA;EACA;EACA;EACA;;;AAED;EACC;EACA;EACA;;;AAED;EACC;EACA;;;AAED;AAAA;EAEC;EACA;EACA;EACA;;;AAED;AAAA;EAEC;;;AAED;EACC;;;AAED;EACC;;;AAED;EACC;;;AAED;EACC;;;AAED;AAAA;EAEC;EACA;EACA;EACA;EACA;EACA;;;AAED;EACC;EACA;EACA;;;AAED;EACC;EACA;;;AAED;AAAA;EAEC;;;AAED;EACC;EACA;EACA;EACA;;;AAED;EACC;EACA;EACA;EACA;;;AAED;EACC;EACA;;;AAED;AAAA;EAEC;EACA;EACA;EACA;;;AAED;EACC;EACA;EACA;EACA;EACA;EACA;;;AAED;EACC;EACA;EACA;EACA;EACA;EACA;;;AAED;EACC;;;AAGD;AACA;EACC;;;AAED;EACC;;;AAED;EACC;EACA;;;AAED;EACC;;;AAED;EACC;;;AAED;EACC;;;AAED;AAAA;EAEC;;;AAED;EACC;;;AAED;EACC;EACA;EACA;;;AAGD;AACA;EACC;;;AAED;EACC;EACA;;;AAED;EACC;EACA;;;AAED;EACC;EACA;;;AAED;EACC;EACA;;;AAED;EACC;;;AAED;EACC;;;AAED;AAAA;EAEC;;;AAED;AAAA;EAEC;EACA;;;AAGD;AACA;EACC;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;;;AAED;AAAA;EAEC;;;AAED;EACC;;;AAED;AAAA;AAAA;AAAA;EAIC;;;AAED;AAAA;EAEC;;;AAED;AAAA;EAEC;;;AAGD;AACA;EAAiB;;;AACjB;EAAqB;;;AACrB;EAAsB;;;AACtB;EAAqB;;;AACrB;EAAsB;;;AACtB;EAAqB;;;AACrB;EAAsB;;;AACtB;EAAqB;;;AACrB;EAAsB;;;AACtB;EAAuB;;;AACvB;EAAuB;;;AACvB;EAAwB;;;AACxB;EAAyB;;;AACzB;EAAwB;;;AACxB;EAAyB;;;AACzB;EAAwB;;;AACxB;EAAyB;;;AACzB;EAAwB;;;AACxB;EAAyB;;;AACzB;EAA0B;;;AAC1B;EAA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GN;EAAK;;;AC/BR;EAIC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACC;EACA;EACA;EACA;EACA;EACA;;AAGD;EAEC;;;AAOA;EAEE;;AACA;EAEE;;AAIL;EAEC;;AAED;EACC;;AAGD;EAGG;EACA;;AAEA;EAEE;EAEA;EACA;EACA;;AAIL;EACC;EACA;EACA;EACA;;AAIA;EAEE;;AAGA;EAEE;EACH;;AAEG;EAEE;EACA;EACA;EACA;EACA;EACA;EACJ;EACA;;AAEA;EAEC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAED;EACC;;AAEG;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACL;;AAGG;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EAEG;EACA;EACA;EACA;;AAEP;EAEC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EAEA;EACA;EACA;EACA;;AAMG;EAAiC;;AAMjC;EAAM;;AACN;EAAa;;AAEX;EACE;EACA;EACA;;AASZ;EAEE;EACA;EACA;EAEA;EACA;;AACA;EACI;EACA;EACA;;AAIN;EAEE;;AAGF;EAEE;;AAGF;EAEE;EACA;EACA;;AACA;EAEE;EACA;;AAKA;EAEE;;AAEF;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;;AAOR;EAEE;EACA;EACA;EACA;;AAGE;EACE;;AAEF;EAEE;;AAGN;EAEE;;AACA;EACC;EACA;;AAOG;EAEE;;AAMJ;EAAQ;;AAEV;EAEE;EACA;EACA;;AAEF;EAEE;EACA;EACA;;AACA;EACE;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;;AACA;EAEE;EACA;EACA;;AAIN;EAEE;EACA;;AACA;EAEE;EACA;;AAKN;EAEE;EACA;EACA;EACA;;AACA;EAEE;EACA;;AAIJ;EAEG;;AAIH;EAEE;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;EACF;;AACE;EACE;EACA;EACA;EACA;EACA;;AAEJ;EAEE;EACA;;AAEF;EAAO;;AACP;EAAQ;;AACR;EAAQ;;AACR;EAAS;;AACR;EACE;;AAED;EAEE;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACJ;;AAGF;EAAU;;AAER;EAEE;EACA;;AACA;EAAM;EAAkB;EAAmB;;AAU/C;EAEE;;AAEF;EAEE;;AACA;EACC;;AAKH;EAEI;IAEG;;EAEH;IACE;;EACA;IACE;;;AAGR;EAEE;IAAkB;;;AAErB;EAEE;IACE;IACA;IACA;;EAIA;IACE;IACD","file":"admin.css"} \ No newline at end of file diff --git a/enable-media-replace.php b/enable-media-replace.php index 3d0a55e..2e9e66f 100644 --- a/enable-media-replace.php +++ b/enable-media-replace.php @@ -25,8 +25,6 @@ * */ -namespace EnableMediaReplace; - define( 'EMR_VERSION', '4.0.3-DEV01' ); if ( ! defined( 'ABSPATH' ) ) { @@ -76,6 +74,14 @@ require_once( $plugin_path . 'classes/emr-plugin.php' ); require_once( $plugin_path . 'classes/installHelper.php' ); +// @todo Needs replacing with PSR-4 +require_once( $plugin_path . 'classes/Controller/ReplaceController.php'); + +require_once( $plugin_path . 'classes/ViewController.php'); +require_once( $plugin_path . 'classes/ViewController/UploadViewController.php'); +require_once( $plugin_path . 'classes/ViewController/ReplaceViewController.php'); +require_once( $plugin_path . 'classes/ViewController/RemoveBackgroundViewController.php'); + require_once( $plugin_path . 'classes/externals.php' ); require_once( $plugin_path . 'classes/external/elementor.php' ); require_once( $plugin_path . 'classes/external/wpbakery.php' ); @@ -86,7 +92,7 @@ function emr() { - return EnableMediaReplacePlugin::get(); + return EnableMediaReplace\EnableMediaReplacePlugin::get(); } emr(); // runtime. diff --git a/js/emr_admin.js b/js/emr_admin.js index a7e8837..4e94ef3 100644 --- a/js/emr_admin.js +++ b/js/emr_admin.js @@ -8,7 +8,6 @@ var target_is_image; var is_debug = false; - var is_dragging = false; this.init = function() @@ -26,9 +25,13 @@ $('.replace_custom_date').on('click', $.proxy(this.updateCustomDate, this)); // DragDrop - $('.wrap.emr_upload_form').on('dragover', $.proxy(this.dragOverArea, this)); - $('.wrap.emr_upload_form').on('dragleave', $.proxy(this.dragOutArea, this)); + $(document).on('dragover', $.proxy(this.dragOverArea, this)); + $(document).on('dragleave', $.proxy(this.dragOutArea, this)); + $('.emr_drop_area').on('drop', $.proxy(this.fileDrop, this)); + $('.upload-file-action').on('click', function () { + var input = document.getElementById('upload-file').click(); + }); this.checkCustomDate(); this.loadDatePicker(); @@ -138,16 +141,19 @@ img.src = window.URL.createObjectURL(file); self = this; - img.setAttribute('style', 'max-width:100%; max-height: 100%;'); img.addEventListener("load", function () { // with formats like svg it can be rough. - var width = img.naturalWidth; - var height = img.naturalHeight; - if (width == 0) + + var width = img.naturalWidth; + var height = img.naturalHeight; + + if (width == 0) width = img.width; if (height == 0) height = img.height; - // $(preview).find('.textlayer').text(img.naturalWidth + ' x ' + img.naturalHeight ); + + img.setAttribute('style', 'z-index:2; position: relative; max-width:100%; max-height: 100%; width: ' + width + 'px; height: ' + height + 'px;'); + self.updateTextLayer(preview, width + ' x ' + height); self.updateFileSize(preview, file); }); @@ -315,33 +321,47 @@ e.preventDefault(); e.stopPropagation(); - if ( this.is_dragging) + if (true == this.is_dragging) return; - //this.debug('dragover'); - //$('.emr_drop_area').css('border-color', '#83b4d8'); - $('.emr_drop_area').addClass('drop_breakout'); + var el = document.getElementById('emr-drop-area'); + var showEl = el.cloneNode(true); + showEl.id = 'emr-drop-area-active'; + + var child = document.body.appendChild(showEl); + + child.addEventListener('drop', this.fileDrop.bind(this), false); + + child.addEventListener('dragover', function(event){ + event.preventDefault(); + }) + + this.is_dragging = true; } + this.dragOutArea = function(e) { e.preventDefault(); e.stopPropagation(); - // this.debug('dragout'); - //$('.emr_drop_area').css('border-color', '#b4b9be'); - $('.emr_drop_area').removeClass('drop_breakout'); + + var removeEl = document.getElementById('emr-drop-area-active'); + if (removeEl !== null) + document.getElementById('emr-drop-area-active').remove(); + this.is_dragging = false; } this.fileDrop = function (e) { - var ev = e.originalEvent; + // var ev = e.originalEvent; this.dragOutArea(e); - ev.preventDefault(); + //ev.preventDefault(); + e.stopPropagation(); e.preventDefault(); - if (ev.dataTransfer.items) { + if (e.dataTransfer.items) { // Use DataTransferItemList interface to access the file(s) - document.getElementById('userfile').files = ev.dataTransfer.files; + document.getElementById('upload-file').files = e.dataTransfer.files; $('input[name="userfile"]').trigger('change'); } } diff --git a/js/emr_success.js b/js/emr_success.js new file mode 100644 index 0000000..c93fd8c --- /dev/null +++ b/js/emr_success.js @@ -0,0 +1,21 @@ +window.addEventListener('load', function(event) { + + var url = new URL(window.location.href); + url.searchParams.set('emr_success', 1); + + var timeout = 3; + var counter = document.getElementById('redirect_counter'); + var redirectUrl = document.getElementById('redirect_url'); + + counter.textContent = timeout; + + var t = window.setInterval(function () { + counter.textContent = timeout; + timeout--; + if (timeout <= 0) + { + window.location.href = redirectUrl; + } + }, 1000); + +}); diff --git a/js/remove_bg.js b/js/remove_bg.js index 8a30571..4c1b6b3 100644 --- a/js/remove_bg.js +++ b/js/remove_bg.js @@ -19,8 +19,8 @@ jQuery(document).ready(function ($) { const nonce = emrObject.nonce; const attachment_id = $('input[name="ID"]').val(); const action = 'emr_remove_background'; - const bgType = $('input[type=radio][name=background_type]:checked').val(); - const cLvl = $('input[type=radio][name=compression_level]:checked').val(); + const bgType = $('input[type=radio][name="background_type"]:checked').val(); + const cLvl = $('input[type=radio][name="compression_level"]:checked').val(); let background = { type: "transparent" } diff --git a/scss/_screens.scss b/scss/_screens.scss new file mode 100644 index 0000000..dbbd5a7 --- /dev/null +++ b/scss/_screens.scss @@ -0,0 +1,38 @@ + +.enable-media-replace.emr-screen +{ + + width: 90%; + background: #fff; + border: 1px solid #fff; + position: relative; + margin: 30px 0; + + h3 { + font-size: 24px; + position: absolute; + top: -15px; + left: 30px; + padding: 16px 8px; + border: 1px solid #000; + background: #fff; + margin: 0; + } + .content + { + padding: 32px; + + } + h1 { + font-weight: 700; + } + + p { font-size: 14px; } + + .hide { display: none; } + + &.error-screen { + h1 { color: #ff0000; } + } + +} diff --git a/scss/admin.scss b/scss/admin.scss index 4c61c45..a98acaa 100644 --- a/scss/admin.scss +++ b/scss/admin.scss @@ -1,5 +1,36 @@ @import 'datepicker'; +@import 'screens'; +#emr-drop-area-active +{ +// border: 4px dashed #b4b9be; +// max-width: 600px; + position: fixed; + left: 0; + right: 0; + top: 0; + bottom: 0; + z-index: 9999; + display: block; + background: rgba(0,0,0,0.5); + border: 6px dashed #AAA; + + h3 { + font-size: 36px; + color: #ddd; + width: 200px; + left: 50%; + top: 50%; + position:absolute; + } + + .drop-wrapper + { + margin: 0 auto; + } +} + +// The main form. .emr_upload_form { form @@ -15,6 +46,9 @@ { width: 100%; } + .emr_drop_area { + display: none; + } .wrapper { @@ -32,52 +66,24 @@ } } + .explainer { + font-size: 14px; + color: #555; + max-width: 800px; + margin: 20px 0; + + } + .image_chooser.wrapper { min-height: 350px; - .emr_drop_area - { - border: 4px dashed #b4b9be; - max-width: 600px; - padding: 28px 14px; - text-align: center; - position: relative; - h1 { display: none; } - .drop-wrapper - { - margin: 0 auto; - } - &.drop_breakout - { - position: fixed; - left: 0; - right:0; - bottom: 0; - top: 0; - max-width: none; - border-color: #83b4d8; - border-width: 10px; - z-index: 999999; - background-color: rgba(#444, 0.7); - h1 { - color: #fff; - position: absolute; - font-size: 50px; - line-height: 50px; - margin-top: -25px; - top: 50%; - width: 100%; - text-align: center; - display: block; - } - .drop-wrapper { display: none; } - } - } .image_previews { margin: 15px 0; + position: relative; + .image_placeholder { position: relative; @@ -86,7 +92,23 @@ margin-bottom: 10px; border: 1px solid #ddd; vertical-align: top; - // max-height: 500px; + box-sizing: border-box; + background: #fff; + + .upload-title + { + text-align: center; + position: absolute; + padding-top: 8px; + line-height: 20px; + font-weight: 700; + width: 100%; + left: 0; + top: 0; + } + #upload-file { + display: none; + } .textlayer { font-size: 25px; @@ -100,6 +122,7 @@ border: 1px dashed #eee; background-color: #333; padding: 8px; + z-index: 5; //max-width: 100%; } .dashicons @@ -120,6 +143,28 @@ bottom: -25px; width: 100%; } + .drag-and-drop-title + { + text-align: center; + font-weight: 400; + font-size: 14px; + width: 100%; + height: 100%; + position: absolute; + cursor: pointer; + top: 0; + left: 0; + z-index: 1; + span { + position: absolute; + // left: 46%; + top: 50%; + transform: translate(-50%,-50%); + padding: 5px 10px; + width: 100%; + + } + } &.is_image { .dashicons::before, .dashicons { display: none } diff --git a/views/do-replace-background.php b/views/do-replace-background.php index fb1871e..b40e059 100644 --- a/views/do-replace-background.php +++ b/views/do-replace-background.php @@ -5,18 +5,11 @@ use EnableMediaReplace\Notices\NoticeController as Notices; use \EnableMediaReplace\Replacer as Replacer; - if (! defined('ABSPATH')) { exit; // Exit if accessed directly. } -if (! check_admin_referer('do_background_replace')) -{ - wp_die(esc_html__('Nonce in form failed. Go back, refresh and try again.', 'enable-media-replace')); -} - $key = isset($_POST['key']) ? sanitize_text_field($_POST['key']) : null; - if (is_null($key) || strlen($key) == 0) { wp_die(esc_html__('Error while sending form (no key). Please try again.', 'enable-media-replace')); @@ -41,9 +34,6 @@ $datetime = current_time('mysql'); $replacer->setTimeMode( \EnableMediaReplace\Replacer::TIME_UPDATEMODIFIED, $datetime); - - - $api = new Api(); $result = $api->handleDownload($key); diff --git a/views/error.php b/views/error.php new file mode 100644 index 0000000..4c3054f --- /dev/null +++ b/views/error.php @@ -0,0 +1,29 @@ + + +
+

+ +
+

+

errorMessage; ?>

+ +

You can return to previous page

+ +
+
+
+ + +uiHelper(); -$attachment_id = intval($_GET['attachment_id']); -$attachment = get_post($attachment_id); +$attachment_id = $view->attachment->ID; +//$attachment_id = intval($_GET['attachment_id']); +//$attachment = get_post($attachment_id); -$replacer = new Replacer($attachment_id); - -$file = $replacer->getSourceFile(); +//$replacer = new Replacer($attachment_id); +//$file = $replacer->getSourceFile(); $uiHelper->setPreviewSizes(); $uiHelper->setSourceSizes($attachment_id); -$base_image = $uiHelper->getPreviewImage($attachment_id, $file ); -$replace_image = $uiHelper->getPreviewImage(-1, $file, array('remove_bg_ui' => true) ); +$base_image = $uiHelper->getPreviewImage($attachment_id, $view->sourceFile ); +$replace_image = $uiHelper->getPreviewImage(-1, $view->sourceFile, array('remove_bg_ui' => true) ); $formurl = $uiHelper->getFormUrl($attachment_id, 'do_background_replace'); -$formurl = wp_nonce_url( $formurl, "do_background_replace" ); +//$formurl = wp_nonce_url( $formurl, "do_background_replace" ); $linebreak = '%0D%0A'; $linebreak_double = $linebreak . $linebreak; $email_subject = __('Bad remove of background report', 'enable-media-replace'); $email_body = sprintf(__('Hello! %s This is a report of a background removal that did not go well %s Url: {url} %s Settings : {settings} %s Thank you! %s', 'enable-media-replace'), $linebreak_double, $linebreak_double, $linebreak, $linebreak_double, $linebreak_double); - $replace_url = add_query_arg(array( 'page' => 'enable-media-replace/enable-media-replace.php', 'action' => 'media_replace', 'attachment_id' => $attachment_id, ), admin_url("upload.php")); -$defaults = array( - 'bg_type' => 'transparent', - 'bg_color' => '#ffffff', - 'bg_transparency' => 100, -); -$settings = get_option('enable_media_replace', $defaults); - -$settings = array_merge($defaults, $settings); // might miss some ?> +
+ + + + @@ -71,7 +67,9 @@
-

Replace this image with another one instead!

+

+ +

@@ -80,7 +78,7 @@

@@ -89,7 +87,7 @@

@@ -97,52 +95,27 @@

- diff --git a/views/popup.php b/views/screen.php similarity index 82% rename from views/popup.php rename to views/screen.php index 44a1537..59c1f60 100644 --- a/views/popup.php +++ b/views/screen.php @@ -1,6 +1,10 @@ prefix . "posts"; -$attachment_id = intval($_GET['attachment_id']); -$attachment = get_post($attachment_id); - -if (! emr()->checkImagePermission($attachment)) -{ - wp_die( esc_html__('You do not have permission to upload files for this author.', 'enable-media-replace') ); -} - -$replacer = new Replacer($attachment_id); - -$file = $replacer->getSourceFile(); -$filepath = $file->getFullPath(); -$filename = $file->getFileName(); -$filetype = $file->getExtension(); -$source_mime = get_post_mime_type($attachment_id); +$attachment_id = $view->attachment->ID; +$settings = $view->settings; +$sourceFile = $view->sourceFile; $uiHelper = emr()->uiHelper(); -$uiHelper->setPreviewSizes(); -$uiHelper->setSourceSizes($attachment_id); - - - -$defaults = array( - 'replace_type' => 'replace', - 'timestamp_replace' => \EnableMediaReplace\Replacer::TIME_UPDATEMODIFIED, - 'custom_date' => date("Y-m-d H:i:s"), - 'new_location' => false, - 'new_location_dir' => false, -); -$settings = get_option('enable_media_replace', $defaults); - -$settings = array_merge($defaults, $settings); // might miss some ?>
+ +

+

getFormUrl($attachment_id); - $formurl = wp_nonce_url( $url, "media_replace_upload" ); + $formurl = $uiHelper->getFormUrl($attachment_id); + //$formurl = wp_nonce_url( $url, "media_replace_upload" ); + if (FORCE_SSL_ADMIN) { $formurl = str_replace("http:", "https:", $formurl); } ?> +
-
+ -

+

You are about to replace getFileName() ?> in your media library. This will be permanent .
You can click on the new image panel and select a file from your computer. You can also drag and drop a file into this window

+

%s','enable-media-replace'), size_format(wp_max_upload_size() ) ) ?>

', ''); ?>

@@ -95,30 +75,24 @@

-
-
- -

-

-
- -
- sourceMime == 'application/pdf') { - echo $uiHelper->getPreviewImage($attachment_id, $file); - echo $uiHelper->getPreviewImage(-1, $file); + echo $uiHelper->getPreviewImage($attachment_id, $sourceFile); + echo $uiHelper->getPreviewImage(-1, $sourceFile, array('is_upload' => true)); } else { - if (strlen($filepath) == 0) // check if image in error state. + if (strlen($sourceFile->getFullPath()) == 0) // check if image in error state. { echo $uiHelper->getPreviewError(-1); - echo $uiHelper->getPreviewImage(-1, $file); + echo $uiHelper->getPreviewImage(-1, $sourceFile, array('is_upload' => true)); } else { - echo $uiHelper->getPreviewFile($attachment_id, $file); - echo $uiHelper->getPreviewFile(-1, $file); + echo $uiHelper->getPreviewFile($attachment_id, $sourceFile); + echo $uiHelper->getPreviewFile(-1, $sourceFile, array('is_upload' => true)); } } @@ -134,7 +108,7 @@ ?>

 

- isBackgroundRemovable($attachment)): ?> + isBackgroundRemovable($view->attachment)): ?>
@@ -164,7 +138,7 @@

- + getExtension(), $sourceFile->getFileName() ); ?>

@@ -181,7 +155,7 @@ -

+

getFileName() ); ?>

@@ -193,12 +167,12 @@
post_date) ); + $attachment_current_date = date_i18n('d/M/Y H:i', strtotime($view->attachment->post_date) ); $attachment_now_date = date_i18n('d/M/Y H:i' ); $time = current_time('mysql'); $date = $nowDate = new \dateTime($time); // default to now. - $attachmentDate = new \dateTime($attachment->post_date); + $attachmentDate = new \dateTime($view->attachment->post_date); if ($settings['timestamp_replace'] == \EnableMediaReplace\Replacer::TIME_CUSTOM) diff --git a/views/success.php b/views/success.php new file mode 100644 index 0000000..2d6fd1d --- /dev/null +++ b/views/success.php @@ -0,0 +1,30 @@ + + + + +prefix . "posts"; -$postmeta_table_name = $wpdb->prefix . "postmeta"; // Starts processing. $uihelper = emr()->uiHelper(); @@ -143,13 +140,6 @@ // Gather all functions that both options do. do_action('wp_handle_replace', array('post_id' => $post_id)); - -/* if ($mode = \EnableMediaReplace\Replacer::MODE_SEARCHREPLACE && $do_new_location && ! is_null($new_location_dir)) - { - exit($new_filename); - $newdirfile = $replacer->newTargetLocation($new_location_dir); - } -*/ try { $result = $replacer->replaceWith($_FILES["userfile"]["tmp_name"], $new_filename); } catch (\RunTimeException $e) { @@ -162,7 +152,6 @@ wp_safe_redirect($redirect_error); exit(); } -// $returnurl = admin_url("/post.php?post={$_POST["ID"]}&action=edit&message=1"); // Execute hook actions - thanks rubious for the suggestion! } else { From f577b86c56ca70438a09e518368ffd752b6b0439 Mon Sep 17 00:00:00 2001 From: Bas Schuiling Date: Thu, 9 Mar 2023 17:39:55 -0600 Subject: [PATCH 05/21] Fix - Check ajax for image permission Fix - Check for timestamp replace on remove background --- .../ViewController/RemoveBackgroundViewController.php | 4 ++-- classes/api.php | 9 +++++++++ js/remove_bg.js | 9 +++++---- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/classes/ViewController/RemoveBackgroundViewController.php b/classes/ViewController/RemoveBackgroundViewController.php index 342fc23..90384dd 100644 --- a/classes/ViewController/RemoveBackgroundViewController.php +++ b/classes/ViewController/RemoveBackgroundViewController.php @@ -104,8 +104,8 @@ public function loadPost() $params = array( 'post_id' => $post_id, - 'replace_type' => 'replace', - 'timestamp_replace' => $timestamp_replace, + 'replace_type' => ReplaceController::MODE_REPLACE, + 'timestamp_replace' => ReplaceController::TIME_UPDATEMODIFIED, 'new_date' => $datetime, 'is_custom_date' => false, 'remove_background' => true, diff --git a/classes/api.php b/classes/api.php index a772eba..2df7418 100644 --- a/classes/api.php +++ b/classes/api.php @@ -56,6 +56,8 @@ public function request( array $posted_data ) { $compression_level = 0; // intval($posted_data['compression_level']); // off for now. $attachment_id = isset($_POST['attachment_id']) ? intval($_POST['attachment_id']) : null; + $attachment = get_post($attachment_id); + if (is_null($attachment_id)) { @@ -65,6 +67,13 @@ public function request( array $posted_data ) { return $result; } + if (! emr()->checkImagePermission($attachment)) { + $result = $this->getResponseObject(); + $result->success = false; + $result->message = __('No permission for user', 'enable-media-replace'); + return $result; + } + $replacer = new Replacer($attachment_id); $url = $replacer->getSourceUrl(); diff --git a/js/remove_bg.js b/js/remove_bg.js index 4c1b6b3..fbb92a9 100644 --- a/js/remove_bg.js +++ b/js/remove_bg.js @@ -45,9 +45,10 @@ jQuery(document).ready(function ($) { $('html, body').animate({ scrollTop: $(".emr_upload_form").offset().top }, 1000); - $('input[type=radio][name=background_type]').attr('disabled', 'disabled') - $('input[type=radio][name=compression_level]').attr('disabled', 'disabled') - $('#remove_background_button').attr('disabled', 'disabled') + $('input[type=radio][name=background_type]').attr('disabled', 'disabled'); + $('input[type=radio][name=compression_level]').attr('disabled', 'disabled'); + $('#remove_background_button').attr('disabled', 'disabled'); + $('h1.response').remove(); $('#overlay').css('visibility', 'visible'); var preview = $('.image_placeholder').last(); preview.find('img').remove(); @@ -97,7 +98,7 @@ jQuery(document).ready(function ($) { // initComparisons(); }else{ - preview.prepend(`

${response.message}

`); + preview.prepend(`

${response.message}

`); $('#remove_background_button').attr('disabled', false) $('input[type=radio][name=background_type]').attr('disabled', false) $('input[type=radio][name=compression_level]').attr('disabled', false) From ed4398542f5ff83ae8d8ac5fda82699cc3bed021 Mon Sep 17 00:00:00 2001 From: Bas Schuiling Date: Mon, 13 Mar 2023 17:14:57 -0600 Subject: [PATCH 06/21] Fix - Date error when custom date wrong Fix - $replaceMode var changed to proper attribute --- classes/Controller/ReplaceController.php | 3 +-- classes/ViewController/UploadViewController.php | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/classes/Controller/ReplaceController.php b/classes/Controller/ReplaceController.php index 55daf72..237c1c3 100644 --- a/classes/Controller/ReplaceController.php +++ b/classes/Controller/ReplaceController.php @@ -295,12 +295,11 @@ protected function setupTarget() $targetpath = $path . $this->new_filename; Log::addTemp('Search/Replace new location', $targetpath); - // If the source and target path AND filename are identical, user has wrong mode, just overwrite the sourceFile. if ($targetpath == $this->sourceFile->getFullPath()) { $unique = $this->sourceFile->getFileName(); - $this->replaceMode == self::MODE_REPLACE; + $this->replaceType == self::MODE_REPLACE; } else { diff --git a/classes/ViewController/UploadViewController.php b/classes/ViewController/UploadViewController.php index 9e4cbc6..5a90c05 100644 --- a/classes/ViewController/UploadViewController.php +++ b/classes/ViewController/UploadViewController.php @@ -119,12 +119,12 @@ protected function getPost() Log::addDebug('Custom Date - ' . $custom_date . ' ' . $custom_hour . ':' . $custom_minute); $custom_date = \DateTime::createFromFormat('Y-m-d G:i', $custom_date . ' ' . $custom_hour . ':' . $custom_minute); if ($custom_date === false) { - wp_safe_redirect($redirect_error); + /*wp_safe_redirect($redirect_error); $errors = \DateTime::getLastErrors(); $error = ''; if (isset($errors['errors'])) { $error = implode(',', $errors['errors']); - } + } */ //Notices::addError(sprintf(__('Invalid Custom Date. Please check the custom date values: (%s)', 'enable-media-replace'), $error)); $this->viewError(self::ERROR_TIME); //exit(); From 4e54be9933b0c605b59697a8513d8b1298436547 Mon Sep 17 00:00:00 2001 From: Bas Schuiling Date: Mon, 13 Mar 2023 17:43:12 -0600 Subject: [PATCH 07/21] Fix for dragOver in webkit --- js/emr_admin.js | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/js/emr_admin.js b/js/emr_admin.js index 4e94ef3..5788ace 100644 --- a/js/emr_admin.js +++ b/js/emr_admin.js @@ -25,8 +25,10 @@ $('.replace_custom_date').on('click', $.proxy(this.updateCustomDate, this)); // DragDrop - $(document).on('dragover', $.proxy(this.dragOverArea, this)); - $(document).on('dragleave', $.proxy(this.dragOutArea, this)); + //$(document).on('dragover', $.proxy(this.dragOverArea, this)); + //$(document).on('dragleave', $.proxy(this.dragOutArea, this)); + document.addEventListener('dragover', this.dragOverArea.bind(this), false ); + document.addEventListener('dragleave', this.dragOutArea.bind(this), false ); $('.emr_drop_area').on('drop', $.proxy(this.fileDrop, this)); $('.upload-file-action').on('click', function () { @@ -342,9 +344,17 @@ this.dragOutArea = function(e) { - e.preventDefault(); - e.stopPropagation(); + // event is not passed on filedrop. remove overlay then. + if (typeof e !== 'undefined') + { + e.preventDefault(); + e.stopPropagation(); + + if (e.clientX != 0 || e.clientY != 0) { + return false; + } + } var removeEl = document.getElementById('emr-drop-area-active'); if (removeEl !== null) document.getElementById('emr-drop-area-active').remove(); @@ -354,7 +364,7 @@ this.fileDrop = function (e) { // var ev = e.originalEvent; - this.dragOutArea(e); + this.dragOutArea(); //ev.preventDefault(); e.stopPropagation(); e.preventDefault(); From f06abd582bb29a14fdaecc46fd4e641226104e45 Mon Sep 17 00:00:00 2001 From: Bas Schuiling Date: Mon, 13 Mar 2023 18:24:00 -0600 Subject: [PATCH 08/21] Fix for mime check Fix for PDF not generating thumbnails --- .../filesystem/src/Model/File/FileModel.php | 12 ++++++++++++ classes/Controller/ReplaceController.php | 17 ++++++++++++----- views/error.php | 1 - 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/build/shortpixel/filesystem/src/Model/File/FileModel.php b/build/shortpixel/filesystem/src/Model/File/FileModel.php index 80de549..300114c 100644 --- a/build/shortpixel/filesystem/src/Model/File/FileModel.php +++ b/build/shortpixel/filesystem/src/Model/File/FileModel.php @@ -416,10 +416,22 @@ public function getMime() if ($this->exists() && ! $this->is_virtual() ) { $this->mime = wp_get_image_mime($this->fullpath); + // If this fails, try another function + if (false === $this->mime) + { + $image_data = wp_check_filetype_and_ext($this->getFullPath(), $this->getFileName()); + if (is_array($image_data) && isset($image_data['type']) && strlen($image_data['type']) > 0) + { + $this->mime = $image_data['type']; + } + + } } else $this->mime = false; + + return $this->mime; } diff --git a/classes/Controller/ReplaceController.php b/classes/Controller/ReplaceController.php index 237c1c3..f6b1366 100644 --- a/classes/Controller/ReplaceController.php +++ b/classes/Controller/ReplaceController.php @@ -99,6 +99,9 @@ public function run() Log::addError('Directory creation for targetFile failed'); } + Log::addTemp("SourceFile", $this->sourceFile); + $permissions = $this->sourceFile->getPermissions(); + $this->removeCurrent(); // tries to remove the current files. $fileObj = $this->fs()->getFile($this->tmpUploadPath); @@ -121,7 +124,6 @@ public function run() Log::addDebug('Temp file could not be removed. Permission issues?'); } - $permissions = $this->sourceFile->getPermissions(); $this->targetFile->resetStatus(); // reinit target file because it came into existence. if ($permissions > 0) @@ -160,6 +162,10 @@ public function run() $post_mime = get_post_mime_type($this->post_id); $target_mime = $this->targetFile->getMime(); +Log::addTemp('Post mime -- ' . $post_mime . ' Target: ' . $target_mime, $this->targetFile); +Log::addTemp('Target Mime ', wp_get_image_mime($this->targetFile->getFullPath())); +Log::addTemp('Check EXT', wp_check_filetype_and_ext($this->targetFile->getFullPath(), $this->targetFile->getFileName())); + // update DB post mime type, if somebody decided to mess it up, and the target one is not empty. if ($target_mime !== $post_mime && strlen($target_mime) > 0) { @@ -282,9 +288,10 @@ protected function setupTarget() if (false === is_null($this->new_location)) // Replace to another path. { $otherTarget = $this->fs()->getFile($targetLocation . $this->new_filename); - if ($otherTarget->exists()) + // Halt if new target exists, but not if it's the same ( overwriting itself ) + if ($otherTarget->exists() && $otherTarget->getFullPath() !== $this->getSourceFile()->getFullPath() ) { - Notices::addError(__('In specificied directory there is already a file with the same name. Can\'t replace.', 'enable-media-replace')); + // Notices::addError(__('In specificied directory there is already a file with the same name. Can\'t replace.', 'enable-media-replace')); $this->lastError = self::ERROR_TARGET_EXISTS; return null; } @@ -293,7 +300,6 @@ protected function setupTarget() } //if ($this->sourceFile->getFileName() == $this->targetName) $targetpath = $path . $this->new_filename; - Log::addTemp('Search/Replace new location', $targetpath); // If the source and target path AND filename are identical, user has wrong mode, just overwrite the sourceFile. if ($targetpath == $this->sourceFile->getFullPath()) @@ -441,7 +447,8 @@ protected function getTargetURL() { if (is_null($this->targetFile)) { - Log::addTemp('TargetFile NULL', debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 10)); + Log::addError('TargetFile NULL ', debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 10)); + return false; } //$uploads['baseurl'] $url = wp_get_attachment_url($this->post_id); diff --git a/views/error.php b/views/error.php index 4c3054f..541b652 100644 --- a/views/error.php +++ b/views/error.php @@ -20,7 +20,6 @@

You can return to previous page

-
From fcb8ab2fc4aad1fdd628b7a0cce52326a20c6161 Mon Sep 17 00:00:00 2001 From: Bas Schuiling Date: Mon, 13 Mar 2023 19:05:17 -0600 Subject: [PATCH 09/21] Fix - issue with illegal / wrong paths Fix - static that shall not be static --- classes/Controller/ReplaceController.php | 35 ++++++++++--------- classes/ViewController.php | 32 ++++++++++++++--- .../ViewController/ReplaceViewController.php | 6 ++++ views/error.php | 7 ++++ views/screen.php | 3 +- 5 files changed, 60 insertions(+), 23 deletions(-) diff --git a/classes/Controller/ReplaceController.php b/classes/Controller/ReplaceController.php index f6b1366..8952f4b 100644 --- a/classes/Controller/ReplaceController.php +++ b/classes/Controller/ReplaceController.php @@ -26,6 +26,8 @@ class ReplaceController const ERROR_DESTINATION_FAIL = 21; const ERROR_COPY_FAILED = 22; const ERROR_UPDATE_POST = 23; + const ERROR_DIRECTORY_SECURITY = 24; + const ERROR_DIRECTORY_NOTEXIST = 25; protected $replaceType; protected $new_location; @@ -91,6 +93,7 @@ public function run() $Replacer->setSourceMeta(wp_get_attachment_metadata( $this->post_id )); $targetFileObj = $this->fs()->getFile($this->targetFile); + var_dump($this->targetFile); $directoryObj = $targetFileObj->getFileDir(); $result = $directoryObj->check(); @@ -162,10 +165,6 @@ public function run() $post_mime = get_post_mime_type($this->post_id); $target_mime = $this->targetFile->getMime(); -Log::addTemp('Post mime -- ' . $post_mime . ' Target: ' . $target_mime, $this->targetFile); -Log::addTemp('Target Mime ', wp_get_image_mime($this->targetFile->getFullPath())); -Log::addTemp('Check EXT', wp_check_filetype_and_ext($this->targetFile->getFullPath(), $this->targetFile->getFileName())); - // update DB post mime type, if somebody decided to mess it up, and the target one is not empty. if ($target_mime !== $post_mime && strlen($target_mime) > 0) { @@ -214,7 +213,7 @@ public function run() $wpdb->update( $wpdb->posts, array( 'guid' => $target_url), array('ID' => $this->post_id) ); //enable-media-replace-upload-done - // @todo This error in general ever happens? Replace this one with proper Notices:addError; + // @todo This error in general ever happens? if (is_wp_error($post_id)) { $this->lastError = self::ERROR_UPDATE_POST; @@ -285,13 +284,17 @@ protected function setupTarget() { $path = (string) $this->getSourceFile()->getFileDir(); $targetLocation = $this->getNewTargetLocation(); + if (false === $targetLocation) + { + return null; + } + if (false === is_null($this->new_location)) // Replace to another path. { $otherTarget = $this->fs()->getFile($targetLocation . $this->new_filename); // Halt if new target exists, but not if it's the same ( overwriting itself ) if ($otherTarget->exists() && $otherTarget->getFullPath() !== $this->getSourceFile()->getFullPath() ) { - // Notices::addError(__('In specificied directory there is already a file with the same name. Can\'t replace.', 'enable-media-replace')); $this->lastError = self::ERROR_TARGET_EXISTS; return null; } @@ -323,13 +326,9 @@ protected function setupTarget() $targetFile = trailingslashit($upload_dir['path']) . wp_unique_filename($targetFile, $this->new_filename); } else { - //$err = __('EMR could not establish a proper destination for replacement', 'enable-media-replace'); - //Notices::addError($err); - //Log::addError($err); - return self::ERROR_DESTINATION_FAIL; - // throw new \RuntimeException($err); - // exit($err); // fallback - // return null; + + $this->lastError = self::ERROR_DESTINATION_FAIL; + return null; } } return $targetFile; @@ -480,16 +479,18 @@ protected function getNewTargetLocation() $new_rel_location = $this->new_location; $newPath = trailingslashit($uploadDir['basedir']) . $new_rel_location; + $realPath = realpath($newPath); + // Detect traversal by making sure the canonical path starts with uploads' basedir. - if (($newPath = realpath($newPath)) && strpos($newPath, $uploadDir['basedir']) !== 0) - { - Notices::addError(__('Specificed directory is outside the upload directory. This is not allowed for security reasons', 'enable-media-replace')); + if ( strpos($realPath, $uploadDir['basedir']) !== 0) + { + $this->lastError = self::ERROR_DIRECTORY_SECURITY; return false; } if (! is_dir($newPath)) { - Notices::addError(__('Specificed new directory does not exist. Path must be a relative path from the upload directory and exist', 'enable-media-replace')); + $this->lastError = self::ERROR_DIRECTORY_NOTEXIST; return false; } return trailingslashit($newPath); diff --git a/classes/ViewController.php b/classes/ViewController.php index 4bbe2c3..0d7a72f 100644 --- a/classes/ViewController.php +++ b/classes/ViewController.php @@ -1,5 +1,4 @@ view = new \stdClass; @@ -73,7 +76,7 @@ protected function loadView($template = null, $unique = true) protected function viewError($errorCode) { - $message = false; + $message = $description = false; switch($errorCode) { case self::ERROR_UPLOAD_PERMISSION: @@ -101,10 +104,24 @@ protected function viewError($errorCode) $message = __('The target file already exists in this directory. Please try another name / directory', 'enable-media-replace'); break; case self::ERROR_DESTINATION_FAIL: - $message = __('Something went wrong while writing the file', 'enable-media-replace'); + $message = __('Something went wrong while writing the file or directory', 'enable-media-replace'); + break; + case self::ERROR_COPY_FAILED: + $message = __('Copying replacement file to destination failed', 'enable-media-replace'); + break; + case self::ERROR_UPDATE_POST: + $message = __('Error updating WordPress post in the database', 'enable-media-replace'); + break; + case self::ERROR_DIRECTORY_SECURITY: + $message = __('Specificed directory is outside the upload directory. This is not allowed for security reasons', 'enable-media-replace'); + break; + case self::ERROR_DIRECTORY_NOTEXIST: + $message = __('Specificed new directory does not exist. Path must be a relative path from the upload directory and exist', 'enable-media-replace'); break; + case self::ERROR_NONCE: $message = __('Fail to validate form nonce. Please try again', 'enable-media-replace'); + $description = __('This can happen when the window is open for a long time and/or there has been a timeout. You can go back to previous screen and try again. If this happens each time when replacing, contact us', 'enable-media-replace'); break; // Remove Background @@ -120,6 +137,12 @@ protected function viewError($errorCode) if( false !== $message) $this->view->errorMessage = $message; + if (false !== $description) + { + $this->view->errorDescription = $description; + } + + $this->loadView('error'); exit(); } @@ -132,5 +155,4 @@ protected function viewSuccess() exit(); } - } diff --git a/classes/ViewController/ReplaceViewController.php b/classes/ViewController/ReplaceViewController.php index 3e95472..d07bbc1 100644 --- a/classes/ViewController/ReplaceViewController.php +++ b/classes/ViewController/ReplaceViewController.php @@ -64,6 +64,12 @@ public function load() $this->view->sourceMime = $source_mime; $this->view->settings = array_merge($defaults, $settings); // might miss some + $uploadDir = wp_upload_dir(); + $basedir = trailingslashit($uploadDir['basedir']); + + $this->view->custom_basedir = $basedir; + + $this->loadView('screen'); } diff --git a/views/error.php b/views/error.php index 541b652..9b9ded3 100644 --- a/views/error.php +++ b/views/error.php @@ -18,8 +18,15 @@

errorMessage; ?>

+ ' . $view->errorDescription . '

'; + } ?> +

You can return to previous page

+ +

', ''); ?>

diff --git a/views/screen.php b/views/screen.php index 59c1f60..c7ef0ea 100644 --- a/views/screen.php +++ b/views/screen.php @@ -211,7 +211,8 @@ class='emr_datepicker' /> ?>
- +
+ custom_basedir ?>
From 9efa9864515aab1a7066d9f88055cba2a26fe1b3 Mon Sep 17 00:00:00 2001 From: Bas Schuiling Date: Fri, 17 Mar 2023 15:24:34 -0600 Subject: [PATCH 10/21] EMR offload --- classes/Controller/RemoteNoticeController.php | 119 +++++++ classes/Controller/ReplaceController.php | 51 ++- .../RemoveBackgroundViewController.php | 2 +- .../ViewController/ReplaceViewController.php | 7 +- .../ViewController/UploadViewController.php | 1 + classes/emr-plugin.php | 27 +- classes/external/wp-offload.php | 332 ++++++++++++++++++ classes/externals.php | 7 + classes/uihelper.php | 3 +- css/admin.css | 4 + css/admin.css.map | 2 +- enable-media-replace.php | 2 + js/emr_admin.js | 5 + js/emr_success.js | 7 +- scss/_screens.scss | 1 + scss/admin.scss | 5 + views/screen.php | 24 +- 17 files changed, 560 insertions(+), 39 deletions(-) create mode 100644 classes/Controller/RemoteNoticeController.php create mode 100644 classes/external/wp-offload.php diff --git a/classes/Controller/RemoteNoticeController.php b/classes/Controller/RemoteNoticeController.php new file mode 100644 index 0000000..8c1a978 --- /dev/null +++ b/classes/Controller/RemoteNoticeController.php @@ -0,0 +1,119 @@ +doRemoteNotices(); + } + + public static function getInstance() + { + if ( is_null(self::$instance)) + { + self::$instance = new RemoteNoticeController(); + } + + return self::$instance; + } + + protected function doRemoteNotices() + { + $notices = $this->get_remote_notices(); + + if (! is_array($notices)) + return; + + foreach($notices as $remoteNotice) + { + if (! isset($remoteNotice->id) && ! isset($remoteNotice->message)) + return; + + if (! isset($remoteNotice->type)) + $remoteNotice->type = 'notice'; + + $message = esc_html($remoteNotice->message); + $id = sanitize_text_field($remoteNotice->id); + + $noticeController = Notices::getInstance(); + $noticeObj = $noticeController->getNoticeByID($id); + + // not added to system yet + if ($noticeObj === false) + { + switch ($remoteNotice->type) + { + case 'warning': + $new_notice = Notices::addWarning($message); + break; + case 'error': + $new_notice = Notices::addError($message); + break; + case 'notice': + default: + $new_notice = Notices::addNormal($message); + break; + } + + Notices::makePersistent($new_notice, $id, MONTH_IN_SECONDS); + } + + } + } + + private function get_remote_notices() + { + $transient_name = 'emr_remote_notice'; + $transient_duration = DAY_IN_SECONDS; + + + // $keyControl = new apiKeyController(); + //$keyControl->loadKey(); + + $notices = get_transient($transient_name); + $url = $this->remote_message_endpoint; + $url = add_query_arg(array( // has url + // 'key' => $keyControl->forceGetApiKey(), + 'version' => EMR_VERSION, + 'plugin' => 'enable-media-replace', + 'target' => 3, + ), $url); + + + if ( $notices === false ) { + $notices_response = wp_safe_remote_request( $url ); + //Log::addTemp('Remote REquest', $notices_response); + + $content = false; + if (! is_wp_error( $notices_response ) ) + { + $notices = json_decode($notices_response['body']); + + if (! is_array($notices)) + $notices = 'none'; + + // Save transient anywhere to prevent over-asking when nothing good is there. + set_transient( $transient_name, $notices, $transient_duration ); + } + else + { + set_transient( $transient_name, false, $transient_duration ); + } + } + + return $notices; + } + +} // class diff --git a/classes/Controller/ReplaceController.php b/classes/Controller/ReplaceController.php index 8952f4b..50e9b94 100644 --- a/classes/Controller/ReplaceController.php +++ b/classes/Controller/ReplaceController.php @@ -13,6 +13,7 @@ class ReplaceController { protected $post_id; protected $sourceFile; + protected $sourceFileUntranslated; protected $targetFile; const MODE_REPLACE = 1; @@ -46,14 +47,22 @@ public function __construct($post_id) $this->setupSource(); } - public function getSourceFile() + /* getSourceFile + * + * @param $untranslated boolean if file is offloaded, this indicates to return remote variant. Used for displaying preview + */ + public function getSourceFile($untranslated = false) { + + if (true === $untranslated && ! is_null($this->sourceFileUntranslated)) + { + return $this->sourceFileUntranslated; + } return $this->sourceFile; } public function setupParams($params) { - Log::addTemp('Setup Params', $params); $this->replaceType = ($params['replace_type'] === 'replace_and_search') ? self::MODE_SEARCHREPLACE : self::MODE_REPLACE; if ($this->replaceType == self::MODE_SEARCHREPLACE && true === $params['new_location'] && ! is_null($params['location_dir'])) @@ -93,7 +102,7 @@ public function run() $Replacer->setSourceMeta(wp_get_attachment_metadata( $this->post_id )); $targetFileObj = $this->fs()->getFile($this->targetFile); - var_dump($this->targetFile); + $directoryObj = $targetFileObj->getFileDir(); $result = $directoryObj->check(); @@ -102,8 +111,7 @@ public function run() Log::addError('Directory creation for targetFile failed'); } - Log::addTemp("SourceFile", $this->sourceFile); - $permissions = $this->sourceFile->getPermissions(); + $permissions = ($this->sourceFile->exists() ) ? $this->sourceFile->getPermissions() : -1; $this->removeCurrent(); // tries to remove the current files. @@ -124,7 +132,7 @@ public function run() $deleted = $fileObj->delete(); if (false === $deleted) { - Log::addDebug('Temp file could not be removed. Permission issues?'); + Log::addWarn('Temp file could not be removed. Permission issues?'); } $this->targetFile->resetStatus(); // reinit target file because it came into existence. @@ -138,6 +146,7 @@ public function run() // Uspdate the file attached. This is required for wp_get_attachment_url to work. // Using RawFullPath because FullPath does normalize path, which update_attached_file doesn't so in case of windows / strange Apspaths it fails. $updated = update_attached_file($this->post_id, $this->targetFile->getRawFullPath() ); + Log::addTemp('Update Attached File', $this->targetFile->getRawFullPath()); if (! $updated) { Log::addError('Update Attached File reports as not updated or same value'); @@ -171,12 +180,17 @@ public function run() \wp_update_post(array('post_mime_type' => $this->targetFile->getMime(), 'ID' => $this->post_id)); } + Log::addTemp('Before generate metadata' . $this->targetFile->getFullPath()); + do_action('emr/converter/prevent-offload', $this->post_id); $target_metadata = wp_generate_attachment_metadata( $this->post_id, $this->targetFile->getFullPath() ); + do_action('emr/converter/prevent-offload-off', $this->post_id); + wp_update_attachment_metadata( $this->post_id, $target_metadata ); $Replacer->setTargetMeta($target_metadata); //$this->target_metadata = $metadata; + Log::addTemp('Target Metadata generated', $target_metadata); /** If author is different from replacer, note this */ $post_author = get_post_field( 'post_author', $this->post_id ); @@ -250,7 +264,13 @@ protected function setupSource() $source_file = false; if (function_exists('wp_get_original_image_path')) // WP 5.3+ { - $source_file = wp_get_original_image_path($this->post_id); + $source_file = wp_get_original_image_path($this->post_id, apply_filters( 'emr_unfiltered_get_attached_file', true )); + // For offload et al to change path if wrong. + $source_file = apply_filters('emr/replace/original_image_path', $source_file, $this->post_id); + Log::addTemp('original path' . $source_file); + } + else { + echo 'FUNCTION NOT EXIST'; } if (false === $source_file) @@ -258,9 +278,24 @@ protected function setupSource() $source_file = trim(get_attached_file($this->post_id, apply_filters( 'emr_unfiltered_get_attached_file', true ))); } + Log::addTemp('Source file initial result', $source_file); + + $sourceFileObj = $this->fs()->getFile($source_file); + if ($sourceFileObj->is_virtual()) + { + $this->sourceFileUntranslated = $this->fs()->getFile($source_file); + $sourcePath = apply_filters('emr/file/virtual/translate', $sourceFileObj->getFullPath(), $sourceFileObj); + + if ($sourceFileObj->getFullPath() !== $sourcePath) + { + $sourceFileObj = $this->fs()->getFile($sourcePath); + $source_file = $sourcePath; + } + } /* It happens that the SourceFile returns relative / incomplete when something messes up get_upload_dir with an error something. This case shoudl be detected here and create a non-relative path anyhow.. */ + if (! file_exists($source_file) && $source_file && 0 !== strpos( $source_file, '/' ) && ! preg_match( '|^.:\\\|', $source_file ) ) { $file = get_post_meta( $this->post_id, '_wp_attached_file', true ); @@ -438,7 +473,7 @@ protected function removeCurrent() @unlink($attached_file); } - do_action( 'emr_after_remove_current', $this->post_id, $meta, $backup_sizes, $file ); + do_action( 'emr_after_remove_current', $this->post_id, $meta, $backup_sizes, $this->sourceFile, $this->targetFile ); } /** Since WP functions also can't be trusted here in certain cases, create the URL by ourselves */ diff --git a/classes/ViewController/RemoveBackgroundViewController.php b/classes/ViewController/RemoveBackgroundViewController.php index 90384dd..1b4b886 100644 --- a/classes/ViewController/RemoveBackgroundViewController.php +++ b/classes/ViewController/RemoveBackgroundViewController.php @@ -42,7 +42,7 @@ public function load() $uiHelper->setSourceSizes($attachment_id); $replacer = new ReplaceController($attachment_id); - $file = $replacer->getSourceFile(); + $file = $replacer->getSourceFile(true); // for display only $defaults = array( 'bg_type' => 'transparent', diff --git a/classes/ViewController/ReplaceViewController.php b/classes/ViewController/ReplaceViewController.php index d07bbc1..368b39d 100644 --- a/classes/ViewController/ReplaceViewController.php +++ b/classes/ViewController/ReplaceViewController.php @@ -40,7 +40,7 @@ public function load() $replacer = new ReplaceController($attachment_id); - $file = $replacer->getSourceFile(); + $file = $replacer->getSourceFile(true); /* $filepath = $file->getFullPath(); $filename = $file->getFileName(); $filetype = $file->getExtension(); */ @@ -64,9 +64,12 @@ public function load() $this->view->sourceMime = $source_mime; $this->view->settings = array_merge($defaults, $settings); // might miss some + // Indicates if file can be moved to other location. Can't be done when offloaded. + $this->view->is_movable = apply_filters('emr/replace/file_is_movable', true, $attachment_id); + $uploadDir = wp_upload_dir(); $basedir = trailingslashit($uploadDir['basedir']); - + $this->view->custom_basedir = $basedir; diff --git a/classes/ViewController/UploadViewController.php b/classes/ViewController/UploadViewController.php index 5a90c05..35efb47 100644 --- a/classes/ViewController/UploadViewController.php +++ b/classes/ViewController/UploadViewController.php @@ -101,6 +101,7 @@ protected function getPost() $remove_background = ( isset( $_POST['remove_after_progress'] ) ) ? true : false; $do_new_location = isset($_POST['new_location']) ? true : false; + $do_new_location = apply_filters('emr/replace/file_is_movable', true, $ID); $new_location_dir = isset($_POST['location_dir']) ? sanitize_text_field($_POST['location_dir']) : null; $is_custom_date = false; diff --git a/classes/emr-plugin.php b/classes/emr-plugin.php index efab595..000a9a7 100644 --- a/classes/emr-plugin.php +++ b/classes/emr-plugin.php @@ -4,6 +4,7 @@ use EnableMediaReplace\ShortPixelLogger\ShortPixelLogger as Log; use EnableMediaReplace\Notices\NoticeController as Notices; use EnableMediaReplace\FileSystem\Controller\FileSystemController as FileSystem; +use EnableMediaReplace\Controller\RemoteNoticeController as RemoteNoticeController; use EnableMediaReplace\Ajax; // Does what a plugin does. @@ -46,7 +47,7 @@ public function runtime() return; } - + new Externals(); $this->plugin_actions(); // init } @@ -55,6 +56,11 @@ public function adminInit() { $this->features['replace'] = true; // does nothing just for completeness $this->features['background'] = apply_filters('emr/feature/background', true); + + load_plugin_textdomain('enable-media-replace', false, basename(dirname(EMR_ROOT_FILE)) . '/languages'); + + // Load Submodules + new Ajax(); } public function filesystem() @@ -122,7 +128,7 @@ public function plugin_actions() // 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')); @@ -178,20 +184,6 @@ public function hide_sub_menu($submenu_file) 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() { @@ -201,9 +193,9 @@ public function setScreen() if ( in_array($screen->id, $notice_pages) && true === emr()->useFeature('background')) { + RemoteNoticeController::getInstance(); // check for remote stuff $notices = Notices::getInstance(); add_action('admin_notices', array($notices, 'admin_notices')); // previous page / init time - } } @@ -502,7 +494,6 @@ public function attachment_editor($form_fields, $post) if (function_exists('get_current_screen')) { $screen = get_current_screen(); - if (! is_null($screen) && $screen->id == 'attachment') { // hide on edit attachment screen. return $form_fields; } diff --git a/classes/external/wp-offload.php b/classes/external/wp-offload.php new file mode 100644 index 0000000..01be3e2 --- /dev/null +++ b/classes/external/wp-offload.php @@ -0,0 +1,332 @@ + source_id lookup, to prevent duplicate queries. + + private static $offloadPrevented = array(); + + + public function __construct() + { + add_action('as3cf_init', array($this, 'init')); + add_filter('shortpixel/image/urltopath', array($this, 'checkIfOffloaded'), 10,2); + + + add_action('emr/converter/prevent-offload', array($this, 'preventOffload'), 10); + add_action('emr/converter/prevent-offload-off', array($this, 'preventOffloadOff'), 10); + add_filter('as3cf_pre_update_attachment_metadata', array($this, 'preventUpdateMetaData'), 10,4); + + + } + + public static function getInstance() + { + if (is_null(self::$instance)) + { + self::$instance = new WPOffload(); + } + + return self::$instance; + } + + public function init($as3cf) + { + if (! class_exists('\DeliciousBrains\WP_Offload_Media\Items\Media_Library_Item')) + { + Notices::addWarning(__('Your S3-Offload plugin version doesn\'t seem to be compatible. Please upgrade the S3-Offload plugin', 'enable-media-replace'), true); + return false; + } + + $this->as3cf = $as3cf; + + if (method_exists($as3cf, 'get_item_handler')) + { + } + else { + Notices::addWarning(__('Your S3-Offload plugin version doesn\'t seem to be compatible. Please upgrade the S3-Offload plugin', 'enable-media-replace'), true); + return false; + } + + add_action('emr_after_remove_current', array($this, 'removeRemote'), 10, 5); + add_filter('emr/file/virtual/translate', array($this, 'getLocalPathByURL')); + add_filter('emr/replace/file_is_movable', array($this, 'isFileMovable'), 10, 2); + + add_filter('emr/replace/original_image_path', array($this, 'checkScaledUrl'), 10,2); + } + + /* + * @param $post_id int The post ID + * @param $meta array Old Metadata before remove + * @param $backup_sizes array WP Backup sizes + * @param $sourceFile Object Source File + * @param $targetFile Object Target File + */ + public function removeRemote($post_id, $meta, $backup_sizes, $sourceFile, $targetFile ) + { +// Always remove because also thumbnails can be different. + $a3cfItem = $this->getItemById($post_id); // MediaItem is AS3CF Object + if ($a3cfItem === false) + { + Log::addDebug('S3-Offload MediaItem not remote - ' . $post_id); + return false; + } + + $remove = \DeliciousBrains\WP_Offload_Media\Items\Remove_Provider_Handler::get_item_handler_key_name(); + $itemHandler = $this->as3cf->get_item_handler($remove); + + $result = $itemHandler->handle($a3cfItem, array( 'verify_exists_on_local' => false)); //handle it then. + // Log::addTemp('Removed remote', $result); + + } + + // @param s3 based URL that which is needed for finding local path + // @return String Filepath. Translated file path + public function getLocalPathByURL($url) + { + $source_id = $this->getSourceIDByURL($url); +//Log::addTemp('Get Local Path SourceID', $source_id); + if ($source_id == false) + { + return false; + } + $item = $this->getItemById($source_id); + + $original_path = $item->original_source_path(); // $values['original_source_path']; + + if (wp_basename($url) !== wp_basename($original_path)) // thumbnails translate to main file. + { + $original_path = str_replace(wp_basename($original_path), wp_basename($url), $original_path); + } + + $fs = emr()->filesystem(); + $base = $fs->getWPUploadBase(); + + $file = $base . $original_path; + return $file; + } + + public function isFileMovable($bool, $attach_id) + { + $item = $this->getItemById($attach_id); + if ($item === false) + { + return $bool; + } + + // Can't move offloaded items. + if (is_object($item)) + { + return false; + } + + } + + public function checkIfOffloaded($bool, $url) + { + + $source_id = $this->sourceCache($url); + + + if (false === $source_id) + { + $extension = substr($url, strrpos($url, '.') + 1); + // If these filetypes are not in the cache, they cannot be found via geSourceyIDByUrl method ( not in path DB ), so it's pointless to try. If they are offloaded, at some point the extra-info might load. + if ($extension == 'webp' || $extension == 'avif') + { + return false; + } + + $source_id = $this->getSourceIDByURL($url); + } + + if ($source_id !== false) + { + return true; + } + else + { + return false; + } + } + + // This is used in the converted. Might be deployed elsewhere for better control. + public function preventOffload($attach_id) + { + self::$offloadPrevented[$attach_id] = true; + } + + public function preventOffloadOff($attach_id) + { + unset(self::$offloadPrevented[$attach_id]); + } + + // When Offload is not offloaded but is created during the process of generate metadata in WP, wp_create_image_subsizes fires an update metadata after just moving the upload, before making any thumbnails. If this is the case and the file has an -scaled / original image setup, the original_source_path becomes the same as the source_path which creates issue later on when dealing with optimizing it, if the file is deleted on local server. Prevent this, and lean on later update metadata. + public function preventUpdateMetaData($bool, $data, $post_id, $old_provider_object) + { + if (isset(self::$offloadPrevented[$post_id])) + { + return true ; // return true to cancel. + } + + return $bool; + + } + + // WP Offload -for some reason - returns the same result of get_attached_file and wp_get_original_image_path , which are different files (one scaled) which then causes a wrong copy action after optimizing the image ( wrong destination download of the remote file ). This happens if offload with delete is on. Attempt to fix the URL to reflect the differences between -scaled and not. + public function checkScaledUrl($filepath, $id) + { + // Original filepath can never have a scaled in there. + // @todo This should probably check -scaled. as string end preventing issues. + if (strpos($filepath, '-scaled') !== false) + { + $filepath = str_replace('-scaled', '', $filepath); + } + return $filepath; + } + + /** @return Returns S3Ofload MediaItem, or false when this does not exist */ + protected function getItemById($id, $create = false) + { + $class = $this->getMediaClass(); + $mediaItem = $class::get_by_source_id($id); + + if (true === $create && $mediaItem === false) + { + $mediaItem = $class::create_from_source_id($id); + } + + return $mediaItem; + } + + protected function getSourceIDByURL($url) + { + $source_id = $this->sourceCache($url); // check cache first. + + if (false === $source_id) // check on the raw url. + { + $class = $this->getMediaClass(); + + $parsedUrl = parse_url($url); + + if (! isset($parsedUrl['scheme']) || ! in_array($parsedUrl['scheme'], array('http','https'))) + { + $url = 'http://' . $url; //str_replace($parsedUrl['scheme'], 'https', $url); + } + + $source = $class::get_item_source_by_remote_url($url); + $source_id = isset($source['id']) ? intval($source['id']) : false; + } + + if (false === $source_id) // check now via the thumbnail hocus. + { + $pattern = '/(.*)-\d+[xX]\d+(\.\w+)/m'; + $url = preg_replace($pattern, '$1$2', $url); + + $source_id = $this->sourceCache($url); // check cache first. + + if (false === $source_id) + { + $source = $class::get_item_source_by_remote_url($url); + $source_id = isset($source['id']) ? intval($source['id']) : false; + } + + } + + // Check issue with double extensions. If say double webp/avif is on, the double extension causes the URL not to be found (ie .jpg) + if (false === $source_id) + { + if (substr_count($parsedUrl['path'], '.') > 1) + { + // Get extension + $ext = substr(strrchr($url, '.'), 1); + + // Remove all extensions from the URL + $checkurl = substr($url, 0, strpos($url,'.')) ; + + // Add back the last one. + $checkurl .= '.' . $ext; + + // Retry + $source_id = $this->sourceCache($checkurl); // check cache first. + + if (false === $source_id) + { + $source = $class::get_item_source_by_remote_url($url); + $source_id = isset($source['id']) ? intval($source['id']) : false; + } + + + } + } + + if ($source_id !== false) + { + + $this->sourceCache($url, $source_id); // cache it. + + // get item + $item = $this->getItemById($source_id); + if (is_object($item) && method_exists($item, 'extra_info')) + { + $baseUrl = str_replace(basename($url),'', $url); + $extra_info = $item->extra_info(); + + if (isset($extra_info['objects'])) + { + foreach($extra_info['objects'] as $extraItem) + { + if (is_array($extraItem) && isset($extraItem['source_file'])) + { + // Add source stuff into cache. + $this->sourceCache($baseUrl . $extraItem['source_file'], $source_id); + } + } + } + } + + return $source_id; + } + + return false; + } + + private function sourceCache($url, $source_id = null) + { + if ($source_id === null && isset($this->sources[$url])) + { + $source_id = $this->sources[$url]; + return $source_id; + } + elseif ($source_id !== null) + { + if (! isset($this->sources[$url])) + { + $this->sources[$url] = $source_id; + } + return $source_id; + } + + return false; + } + + + private function getMediaClass() + { + $class = $this->as3cf->get_source_type_class('media-library'); + return $class; + } + +} diff --git a/classes/externals.php b/classes/externals.php index 6d71d0c..fcc10cd 100644 --- a/classes/externals.php +++ b/classes/externals.php @@ -6,6 +6,7 @@ use EnableMediaReplace\Externals\Elementor as Elementor; use EnableMediaReplace\Externals\WpBakery as WpBakery; use EnableMediaReplace\Externals\SiteOrigin as SiteOrigin; +use EnableMediaReplace\Externals\WPOffload as WPOffload; class Externals @@ -28,6 +29,7 @@ public function __construct() $this->loadElementor(); $this->loadBakery(); // in case of urlencoded issues, this class should be used probably. $this->loadSiteOrigins(); + $this->loadWpOffload(); } protected function check() // check if any of the options should be disabled due to conflicts @@ -78,4 +80,9 @@ public function loadSiteOrigins() SiteOrigin::getInstance(); } + public function loadWPOffload() + { + WPOffload::getInstance(); + } + } // class diff --git a/classes/uihelper.php b/classes/uihelper.php index 3ad645b..f53dbb0 100644 --- a/classes/uihelper.php +++ b/classes/uihelper.php @@ -213,7 +213,7 @@ public function getPreviewImage($attach_id,$file, $args = array()) $mime_type = get_post_mime_type($attach_id); - if (! is_array($data) || ! $file->exists() ) + if (! is_array($data) || (! $file->exists() && ! $file->is_virtual()) ) { // if attachid higher than zero ( exists ) but not the image, fail, that's an error state. $icon = ($attach_id < 0) ? '' : 'dashicons-no'; @@ -228,7 +228,6 @@ public function getPreviewImage($attach_id,$file, $args = array()) 'icon' => $icon, 'mime_type' => null, ); - $args = wp_parse_args($args, $defaults); // failed, it might be this server doens't support PDF thumbnails. Fallback to File preview. diff --git a/css/admin.css b/css/admin.css index bc936c8..1da3917 100644 --- a/css/admin.css +++ b/css/admin.css @@ -1068,6 +1068,10 @@ max-width: 800px; margin: 20px 0; } +.emr_upload_form .explainer .underline { + text-decoration-style: dotted; + text-decoration-line: underline; +} .emr_upload_form .image_chooser.wrapper { min-height: 350px; } diff --git a/css/admin.css.map b/css/admin.css.map index 8100da0..bd85815 100644 --- a/css/admin.css.map +++ b/css/admin.css.map @@ -1 +1 @@ -{"version":3,"sourceRoot":"","sources":["../scss/_datepicker.scss","../scss/_screens.scss","../scss/admin.scss"],"names":[],"mappings":"AAEA;EACC;EACA;EACA;;;AAID;EACC;EACA;EACA;EACA;EACA;;;AAED;EACC;EACA;EACA;;;AAED;EACC;EACA;;;AAED;AAAA;EAEC;EACA;EACA;EACA;;;AAED;AAAA;EAEC;;;AAED;EACC;;;AAED;EACC;;;AAED;EACC;;;AAED;EACC;;;AAED;AAAA;EAEC;EACA;EACA;EACA;EACA;EACA;;;AAED;EACC;EACA;EACA;;;AAED;EACC;EACA;;;AAED;AAAA;EAEC;;;AAED;EACC;EACA;EACA;EACA;;;AAED;EACC;EACA;EACA;EACA;;;AAED;EACC;EACA;;;AAED;AAAA;EAEC;EACA;EACA;EACA;;;AAED;EACC;EACA;EACA;EACA;EACA;EACA;;;AAED;EACC;EACA;EACA;EACA;EACA;EACA;;;AAED;EACC;;;AAGD;AACA;EACC;;;AAED;EACC;;;AAED;EACC;EACA;;;AAED;EACC;;;AAED;EACC;;;AAED;EACC;;;AAED;AAAA;EAEC;;;AAED;EACC;;;AAED;EACC;EACA;EACA;;;AAGD;AACA;EACC;;;AAED;EACC;EACA;;;AAED;EACC;EACA;;;AAED;EACC;EACA;;;AAED;EACC;EACA;;;AAED;EACC;;;AAED;EACC;;;AAED;AAAA;EAEC;;;AAED;AAAA;EAEC;EACA;;;AAGD;AACA;EACC;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;;;AAED;AAAA;EAEC;;;AAED;EACC;;;AAED;AAAA;AAAA;AAAA;EAIC;;;AAED;AAAA;EAEC;;;AAED;AAAA;EAEC;;;AAGD;AACA;EAAiB;;;AACjB;EAAqB;;;AACrB;EAAsB;;;AACtB;EAAqB;;;AACrB;EAAsB;;;AACtB;EAAqB;;;AACrB;EAAsB;;;AACtB;EAAqB;;;AACrB;EAAsB;;;AACtB;EAAuB;;;AACvB;EAAuB;;;AACvB;EAAwB;;;AACxB;EAAyB;;;AACzB;EAAwB;;;AACxB;EAAyB;;;AACzB;EAAwB;;;AACxB;EAAyB;;;AACzB;EAAwB;;;AACxB;EAAyB;;;AACzB;EAA0B;;;AAC1B;EAA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GN;EAAK;;;AC/BR;EAIC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACC;EACA;EACA;EACA;EACA;EACA;;AAGD;EAEC;;;AAOA;EAEE;;AACA;EAEE;;AAIL;EAEC;;AAED;EACC;;AAGD;EAGG;EACA;;AAEA;EAEE;EAEA;EACA;EACA;;AAIL;EACC;EACA;EACA;EACA;;AAIA;EAEE;;AAGA;EAEE;EACH;;AAEG;EAEE;EACA;EACA;EACA;EACA;EACA;EACJ;EACA;;AAEA;EAEC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAED;EACC;;AAEG;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACL;;AAGG;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EAEG;EACA;EACA;EACA;;AAEP;EAEC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EAEA;EACA;EACA;EACA;;AAMG;EAAiC;;AAMjC;EAAM;;AACN;EAAa;;AAEX;EACE;EACA;EACA;;AASZ;EAEE;EACA;EACA;EAEA;EACA;;AACA;EACI;EACA;EACA;;AAIN;EAEE;;AAGF;EAEE;;AAGF;EAEE;EACA;EACA;;AACA;EAEE;EACA;;AAKA;EAEE;;AAEF;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;;AAOR;EAEE;EACA;EACA;EACA;;AAGE;EACE;;AAEF;EAEE;;AAGN;EAEE;;AACA;EACC;EACA;;AAOG;EAEE;;AAMJ;EAAQ;;AAEV;EAEE;EACA;EACA;;AAEF;EAEE;EACA;EACA;;AACA;EACE;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;;AACA;EAEE;EACA;EACA;;AAIN;EAEE;EACA;;AACA;EAEE;EACA;;AAKN;EAEE;EACA;EACA;EACA;;AACA;EAEE;EACA;;AAIJ;EAEG;;AAIH;EAEE;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;EACF;;AACE;EACE;EACA;EACA;EACA;EACA;;AAEJ;EAEE;EACA;;AAEF;EAAO;;AACP;EAAQ;;AACR;EAAQ;;AACR;EAAS;;AACR;EACE;;AAED;EAEE;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACJ;;AAGF;EAAU;;AAER;EAEE;EACA;;AACA;EAAM;EAAkB;EAAmB;;AAU/C;EAEE;;AAEF;EAEE;;AACA;EACC;;AAKH;EAEI;IAEG;;EAEH;IACE;;EACA;IACE;;;AAGR;EAEE;IAAkB;;;AAErB;EAEE;IACE;IACA;IACA;;EAIA;IACE;IACD","file":"admin.css"} \ No newline at end of file +{"version":3,"sourceRoot":"","sources":["../scss/_datepicker.scss","../scss/_screens.scss","../scss/admin.scss"],"names":[],"mappings":"AAEA;EACC;EACA;EACA;;;AAID;EACC;EACA;EACA;EACA;EACA;;;AAED;EACC;EACA;EACA;;;AAED;EACC;EACA;;;AAED;AAAA;EAEC;EACA;EACA;EACA;;;AAED;AAAA;EAEC;;;AAED;EACC;;;AAED;EACC;;;AAED;EACC;;;AAED;EACC;;;AAED;AAAA;EAEC;EACA;EACA;EACA;EACA;EACA;;;AAED;EACC;EACA;EACA;;;AAED;EACC;EACA;;;AAED;AAAA;EAEC;;;AAED;EACC;EACA;EACA;EACA;;;AAED;EACC;EACA;EACA;EACA;;;AAED;EACC;EACA;;;AAED;AAAA;EAEC;EACA;EACA;EACA;;;AAED;EACC;EACA;EACA;EACA;EACA;EACA;;;AAED;EACC;EACA;EACA;EACA;EACA;EACA;;;AAED;EACC;;;AAGD;AACA;EACC;;;AAED;EACC;;;AAED;EACC;EACA;;;AAED;EACC;;;AAED;EACC;;;AAED;EACC;;;AAED;AAAA;EAEC;;;AAED;EACC;;;AAED;EACC;EACA;EACA;;;AAGD;AACA;EACC;;;AAED;EACC;EACA;;;AAED;EACC;EACA;;;AAED;EACC;EACA;;;AAED;EACC;EACA;;;AAED;EACC;;;AAED;EACC;;;AAED;AAAA;EAEC;;;AAED;AAAA;EAEC;EACA;;;AAGD;AACA;EACC;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;;;AAED;AAAA;EAEC;;;AAED;EACC;;;AAED;AAAA;AAAA;AAAA;EAIC;;;AAED;AAAA;EAEC;;;AAED;AAAA;EAEC;;;AAGD;AACA;EAAiB;;;AACjB;EAAqB;;;AACrB;EAAsB;;;AACtB;EAAqB;;;AACrB;EAAsB;;;AACtB;EAAqB;;;AACrB;EAAsB;;;AACtB;EAAqB;;;AACrB;EAAsB;;;AACtB;EAAuB;;;AACvB;EAAuB;;;AACvB;EAAwB;;;AACxB;EAAyB;;;AACzB;EAAwB;;;AACxB;EAAyB;;;AACzB;EAAwB;;;AACxB;EAAyB;;;AACzB;EAAwB;;;AACxB;EAAyB;;;AACzB;EAA0B;;;AAC1B;EAA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GN;EAAK;;;AChCR;EAIC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACC;EACA;EACA;EACA;EACA;EACA;;AAGD;EAEC;;;AAOA;EAEE;;AACA;EAEE;;AAIL;EAEC;;AAED;EACC;;AAGD;EAGG;EACA;;AAEA;EAEE;EAEA;EACA;EACA;;AAIL;EACC;EACA;EACA;EACA;;AACA;EACC;EACA;;AAMD;EAEE;;AAGA;EAEE;EACH;;AAEG;EAEE;EACA;EACA;EACA;EACA;EACA;EACJ;EACA;;AAEA;EAEC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAED;EACC;;AAEG;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACL;;AAGG;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EAEG;EACA;EACA;EACA;;AAEP;EAEC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EAEA;EACA;EACA;EACA;;AAMG;EAAiC;;AAMjC;EAAM;;AACN;EAAa;;AAEX;EACE;EACA;EACA;;AASZ;EAEE;EACA;EACA;EAEA;EACA;;AACA;EACI;EACA;EACA;;AAIN;EAEE;;AAGF;EAEE;;AAGF;EAEE;EACA;EACA;;AACA;EAEE;EACA;;AAKA;EAEE;;AAEF;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;;AAOR;EAEE;EACA;EACA;EACA;;AAGE;EACE;;AAEF;EAEE;;AAGN;EAEE;;AACA;EACC;EACA;;AAOG;EAEE;;AAMJ;EAAQ;;AAEV;EAEE;EACA;EACA;;AAEF;EAEE;EACA;EACA;;AACA;EACE;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;;AACA;EAEE;EACA;EACA;;AAIN;EAEE;EACA;;AACA;EAEE;EACA;;AAKN;EAEE;EACA;EACA;EACA;;AACA;EAEE;EACA;;AAIJ;EAEG;;AAIH;EAEE;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;EACF;;AACE;EACE;EACA;EACA;EACA;EACA;;AAEJ;EAEE;EACA;;AAEF;EAAO;;AACP;EAAQ;;AACR;EAAQ;;AACR;EAAS;;AACR;EACE;;AAED;EAEE;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACJ;;AAGF;EAAU;;AAER;EAEE;EACA;;AACA;EAAM;EAAkB;EAAmB;;AAU/C;EAEE;;AAEF;EAEE;;AACA;EACC;;AAKH;EAEI;IAEG;;EAEH;IACE;;EACA;IACE;;;AAGR;EAEE;IAAkB;;;AAErB;EAEE;IACE;IACA;IACA;;EAIA;IACE;IACD","file":"admin.css"} \ No newline at end of file diff --git a/enable-media-replace.php b/enable-media-replace.php index 4c64c5a..86791b7 100644 --- a/enable-media-replace.php +++ b/enable-media-replace.php @@ -76,6 +76,7 @@ // @todo Needs replacing with PSR-4 require_once( $plugin_path . 'classes/Controller/ReplaceController.php'); +require_once( $plugin_path . 'classes/Controller/RemoteNoticeController.php'); require_once( $plugin_path . 'classes/ViewController.php'); require_once( $plugin_path . 'classes/ViewController/UploadViewController.php'); @@ -87,6 +88,7 @@ require_once( $plugin_path . 'classes/external/wpbakery.php' ); require_once( $plugin_path . 'classes/external/upsell_installer.php' ); require_once( $plugin_path . 'classes/external/siteorigin.php' ); +require_once( $plugin_path . 'classes/external/wp-offload.php' ); require_once( $plugin_path . 'thumbnail_updater.php' ); diff --git a/js/emr_admin.js b/js/emr_admin.js index 5788ace..0cb2d39 100644 --- a/js/emr_admin.js +++ b/js/emr_admin.js @@ -30,6 +30,8 @@ document.addEventListener('dragover', this.dragOverArea.bind(this), false ); document.addEventListener('dragleave', this.dragOutArea.bind(this), false ); + + $('.emr_drop_area').on('drop', $.proxy(this.fileDrop, this)); $('.upload-file-action').on('click', function () { var input = document.getElementById('upload-file').click(); @@ -57,6 +59,7 @@ } + this.loadDatePicker = function() { $('#emr_datepicker').datepicker({ @@ -73,6 +76,7 @@ }, }); } + this.checkCustomDate = function() { if ($('input[name="timestamp_replace"]:checked').val() == 3) @@ -322,6 +326,7 @@ { e.preventDefault(); e.stopPropagation(); + console.log(e); if (true == this.is_dragging) return; diff --git a/js/emr_success.js b/js/emr_success.js index c93fd8c..bac8cf6 100644 --- a/js/emr_success.js +++ b/js/emr_success.js @@ -3,18 +3,21 @@ window.addEventListener('load', function(event) { var url = new URL(window.location.href); url.searchParams.set('emr_success', 1); - var timeout = 3; + var timeout = 10; var counter = document.getElementById('redirect_counter'); var redirectUrl = document.getElementById('redirect_url'); + var redirected = false; counter.textContent = timeout; var t = window.setInterval(function () { counter.textContent = timeout; timeout--; - if (timeout <= 0) + if (timeout <= 0 && false == redirected) { window.location.href = redirectUrl; + redirected = true; + window.clearInterval(t); } }, 1000); diff --git a/scss/_screens.scss b/scss/_screens.scss index dbbd5a7..aeb1d86 100644 --- a/scss/_screens.scss +++ b/scss/_screens.scss @@ -29,6 +29,7 @@ p { font-size: 14px; } + .hide { display: none; } &.error-screen { diff --git a/scss/admin.scss b/scss/admin.scss index a98acaa..b3a2c2f 100644 --- a/scss/admin.scss +++ b/scss/admin.scss @@ -71,6 +71,11 @@ color: #555; max-width: 800px; margin: 20px 0; + .underline { + text-decoration-style: dotted; + text-decoration-line: underline; + } + } diff --git a/views/screen.php b/views/screen.php index c7ef0ea..fd24518 100644 --- a/views/screen.php +++ b/views/screen.php @@ -63,7 +63,7 @@ -

You are about to replace getFileName() ?> in your media library. This will be permanent .
You can click on the new image panel and select a file from your computer. You can also drag and drop a file into this window

+

You are about to replace getFileName() ?> in your media library. This will be permanent .
You can click on the new image panel and select a file from your computer. You can also drag and drop a file into this window

%s','enable-media-replace'), size_format(wp_max_upload_size() ) ) ?>

', ''); ?>

@@ -78,6 +78,7 @@
sourceMime == 'application/pdf') { echo $uiHelper->getPreviewImage($attachment_id, $sourceFile); @@ -123,7 +124,7 @@
-
+
-
+
attachment->post_date) ); @@ -192,8 +193,8 @@ - @   - + @   + @@ -209,12 +210,25 @@ class='emr_datepicker' /> if ($settings['new_location'] !== false) $subdir = $settings['new_location_dir']; ?> + +
+ +
+
+ is_movable): ?>
custom_basedir ?> +
+
From ff935308830c4428c8d8dc147d66ca40d5daf18f Mon Sep 17 00:00:00 2001 From: Bas Schuiling Date: Fri, 17 Mar 2023 15:44:27 -0600 Subject: [PATCH 11/21] Added object-fit to preview --- classes/Controller/RemoteNoticeController.php | 1 - classes/Controller/ReplaceController.php | 10 ---------- classes/ViewController/UploadViewController.php | 1 - classes/external/wp-offload.php | 3 +-- classes/uihelper.php | 1 + css/admin.css | 3 +++ css/admin.css.map | 2 +- scss/admin.scss | 2 ++ 8 files changed, 8 insertions(+), 15 deletions(-) diff --git a/classes/Controller/RemoteNoticeController.php b/classes/Controller/RemoteNoticeController.php index 8c1a978..26d01e4 100644 --- a/classes/Controller/RemoteNoticeController.php +++ b/classes/Controller/RemoteNoticeController.php @@ -94,7 +94,6 @@ private function get_remote_notices() if ( $notices === false ) { $notices_response = wp_safe_remote_request( $url ); - //Log::addTemp('Remote REquest', $notices_response); $content = false; if (! is_wp_error( $notices_response ) ) diff --git a/classes/Controller/ReplaceController.php b/classes/Controller/ReplaceController.php index 50e9b94..08f8472 100644 --- a/classes/Controller/ReplaceController.php +++ b/classes/Controller/ReplaceController.php @@ -146,7 +146,6 @@ public function run() // Uspdate the file attached. This is required for wp_get_attachment_url to work. // Using RawFullPath because FullPath does normalize path, which update_attached_file doesn't so in case of windows / strange Apspaths it fails. $updated = update_attached_file($this->post_id, $this->targetFile->getRawFullPath() ); - Log::addTemp('Update Attached File', $this->targetFile->getRawFullPath()); if (! $updated) { Log::addError('Update Attached File reports as not updated or same value'); @@ -180,7 +179,6 @@ public function run() \wp_update_post(array('post_mime_type' => $this->targetFile->getMime(), 'ID' => $this->post_id)); } - Log::addTemp('Before generate metadata' . $this->targetFile->getFullPath()); do_action('emr/converter/prevent-offload', $this->post_id); $target_metadata = wp_generate_attachment_metadata( $this->post_id, $this->targetFile->getFullPath() ); do_action('emr/converter/prevent-offload-off', $this->post_id); @@ -190,8 +188,6 @@ public function run() $Replacer->setTargetMeta($target_metadata); //$this->target_metadata = $metadata; - Log::addTemp('Target Metadata generated', $target_metadata); - /** If author is different from replacer, note this */ $post_author = get_post_field( 'post_author', $this->post_id ); $author_id = get_post_meta($this->post_id, '_emr_replace_author', true); @@ -267,10 +263,6 @@ protected function setupSource() $source_file = wp_get_original_image_path($this->post_id, apply_filters( 'emr_unfiltered_get_attached_file', true )); // For offload et al to change path if wrong. $source_file = apply_filters('emr/replace/original_image_path', $source_file, $this->post_id); - Log::addTemp('original path' . $source_file); - } - else { - echo 'FUNCTION NOT EXIST'; } if (false === $source_file) @@ -278,8 +270,6 @@ protected function setupSource() $source_file = trim(get_attached_file($this->post_id, apply_filters( 'emr_unfiltered_get_attached_file', true ))); } - Log::addTemp('Source file initial result', $source_file); - $sourceFileObj = $this->fs()->getFile($source_file); if ($sourceFileObj->is_virtual()) { diff --git a/classes/ViewController/UploadViewController.php b/classes/ViewController/UploadViewController.php index 35efb47..c6e71ce 100644 --- a/classes/ViewController/UploadViewController.php +++ b/classes/ViewController/UploadViewController.php @@ -179,7 +179,6 @@ protected function updateSettings($params) { $settings['custom_date'] = $params['new_date']; } -Log::addTemp('Saving settings', $settings); update_option('enable_media_replace', $settings, false); } diff --git a/classes/external/wp-offload.php b/classes/external/wp-offload.php index 01be3e2..aad93e2 100644 --- a/classes/external/wp-offload.php +++ b/classes/external/wp-offload.php @@ -88,7 +88,6 @@ public function removeRemote($post_id, $meta, $backup_sizes, $sourceFile, $targe $itemHandler = $this->as3cf->get_item_handler($remove); $result = $itemHandler->handle($a3cfItem, array( 'verify_exists_on_local' => false)); //handle it then. - // Log::addTemp('Removed remote', $result); } @@ -97,7 +96,7 @@ public function removeRemote($post_id, $meta, $backup_sizes, $sourceFile, $targe public function getLocalPathByURL($url) { $source_id = $this->getSourceIDByURL($url); -//Log::addTemp('Get Local Path SourceID', $source_id); + if ($source_id == false) { return false; diff --git a/classes/uihelper.php b/classes/uihelper.php index f53dbb0..a5e50b2 100644 --- a/classes/uihelper.php +++ b/classes/uihelper.php @@ -271,6 +271,7 @@ public function getPreviewImage($attach_id,$file, $args = array()) $this->preview_height = $height; $image = ""; + // $image = " "; $defaults = array( 'width' => $width, diff --git a/css/admin.css b/css/admin.css index 1da3917..f0145bb 100644 --- a/css/admin.css +++ b/css/admin.css @@ -1089,6 +1089,9 @@ box-sizing: border-box; background: #fff; } +.emr_upload_form .image_chooser.wrapper .image_previews .image_placeholder img { + object-fit: contain; +} .emr_upload_form .image_chooser.wrapper .image_previews .image_placeholder .upload-title { text-align: center; position: absolute; diff --git a/css/admin.css.map b/css/admin.css.map index bd85815..c98ca2c 100644 --- a/css/admin.css.map +++ b/css/admin.css.map @@ -1 +1 @@ -{"version":3,"sourceRoot":"","sources":["../scss/_datepicker.scss","../scss/_screens.scss","../scss/admin.scss"],"names":[],"mappings":"AAEA;EACC;EACA;EACA;;;AAID;EACC;EACA;EACA;EACA;EACA;;;AAED;EACC;EACA;EACA;;;AAED;EACC;EACA;;;AAED;AAAA;EAEC;EACA;EACA;EACA;;;AAED;AAAA;EAEC;;;AAED;EACC;;;AAED;EACC;;;AAED;EACC;;;AAED;EACC;;;AAED;AAAA;EAEC;EACA;EACA;EACA;EACA;EACA;;;AAED;EACC;EACA;EACA;;;AAED;EACC;EACA;;;AAED;AAAA;EAEC;;;AAED;EACC;EACA;EACA;EACA;;;AAED;EACC;EACA;EACA;EACA;;;AAED;EACC;EACA;;;AAED;AAAA;EAEC;EACA;EACA;EACA;;;AAED;EACC;EACA;EACA;EACA;EACA;EACA;;;AAED;EACC;EACA;EACA;EACA;EACA;EACA;;;AAED;EACC;;;AAGD;AACA;EACC;;;AAED;EACC;;;AAED;EACC;EACA;;;AAED;EACC;;;AAED;EACC;;;AAED;EACC;;;AAED;AAAA;EAEC;;;AAED;EACC;;;AAED;EACC;EACA;EACA;;;AAGD;AACA;EACC;;;AAED;EACC;EACA;;;AAED;EACC;EACA;;;AAED;EACC;EACA;;;AAED;EACC;EACA;;;AAED;EACC;;;AAED;EACC;;;AAED;AAAA;EAEC;;;AAED;AAAA;EAEC;EACA;;;AAGD;AACA;EACC;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;;;AAED;AAAA;EAEC;;;AAED;EACC;;;AAED;AAAA;AAAA;AAAA;EAIC;;;AAED;AAAA;EAEC;;;AAED;AAAA;EAEC;;;AAGD;AACA;EAAiB;;;AACjB;EAAqB;;;AACrB;EAAsB;;;AACtB;EAAqB;;;AACrB;EAAsB;;;AACtB;EAAqB;;;AACrB;EAAsB;;;AACtB;EAAqB;;;AACrB;EAAsB;;;AACtB;EAAuB;;;AACvB;EAAuB;;;AACvB;EAAwB;;;AACxB;EAAyB;;;AACzB;EAAwB;;;AACxB;EAAyB;;;AACzB;EAAwB;;;AACxB;EAAyB;;;AACzB;EAAwB;;;AACxB;EAAyB;;;AACzB;EAA0B;;;AAC1B;EAA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GN;EAAK;;;AChCR;EAIC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACC;EACA;EACA;EACA;EACA;EACA;;AAGD;EAEC;;;AAOA;EAEE;;AACA;EAEE;;AAIL;EAEC;;AAED;EACC;;AAGD;EAGG;EACA;;AAEA;EAEE;EAEA;EACA;EACA;;AAIL;EACC;EACA;EACA;EACA;;AACA;EACC;EACA;;AAMD;EAEE;;AAGA;EAEE;EACH;;AAEG;EAEE;EACA;EACA;EACA;EACA;EACA;EACJ;EACA;;AAEA;EAEC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAED;EACC;;AAEG;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACL;;AAGG;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EAEG;EACA;EACA;EACA;;AAEP;EAEC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EAEA;EACA;EACA;EACA;;AAMG;EAAiC;;AAMjC;EAAM;;AACN;EAAa;;AAEX;EACE;EACA;EACA;;AASZ;EAEE;EACA;EACA;EAEA;EACA;;AACA;EACI;EACA;EACA;;AAIN;EAEE;;AAGF;EAEE;;AAGF;EAEE;EACA;EACA;;AACA;EAEE;EACA;;AAKA;EAEE;;AAEF;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;;AAOR;EAEE;EACA;EACA;EACA;;AAGE;EACE;;AAEF;EAEE;;AAGN;EAEE;;AACA;EACC;EACA;;AAOG;EAEE;;AAMJ;EAAQ;;AAEV;EAEE;EACA;EACA;;AAEF;EAEE;EACA;EACA;;AACA;EACE;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;;AACA;EAEE;EACA;EACA;;AAIN;EAEE;EACA;;AACA;EAEE;EACA;;AAKN;EAEE;EACA;EACA;EACA;;AACA;EAEE;EACA;;AAIJ;EAEG;;AAIH;EAEE;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;EACF;;AACE;EACE;EACA;EACA;EACA;EACA;;AAEJ;EAEE;EACA;;AAEF;EAAO;;AACP;EAAQ;;AACR;EAAQ;;AACR;EAAS;;AACR;EACE;;AAED;EAEE;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACJ;;AAGF;EAAU;;AAER;EAEE;EACA;;AACA;EAAM;EAAkB;EAAmB;;AAU/C;EAEE;;AAEF;EAEE;;AACA;EACC;;AAKH;EAEI;IAEG;;EAEH;IACE;;EACA;IACE;;;AAGR;EAEE;IAAkB;;;AAErB;EAEE;IACE;IACA;IACA;;EAIA;IACE;IACD","file":"admin.css"} \ No newline at end of file +{"version":3,"sourceRoot":"","sources":["../scss/_datepicker.scss","../scss/_screens.scss","../scss/admin.scss"],"names":[],"mappings":"AAEA;EACC;EACA;EACA;;;AAID;EACC;EACA;EACA;EACA;EACA;;;AAED;EACC;EACA;EACA;;;AAED;EACC;EACA;;;AAED;AAAA;EAEC;EACA;EACA;EACA;;;AAED;AAAA;EAEC;;;AAED;EACC;;;AAED;EACC;;;AAED;EACC;;;AAED;EACC;;;AAED;AAAA;EAEC;EACA;EACA;EACA;EACA;EACA;;;AAED;EACC;EACA;EACA;;;AAED;EACC;EACA;;;AAED;AAAA;EAEC;;;AAED;EACC;EACA;EACA;EACA;;;AAED;EACC;EACA;EACA;EACA;;;AAED;EACC;EACA;;;AAED;AAAA;EAEC;EACA;EACA;EACA;;;AAED;EACC;EACA;EACA;EACA;EACA;EACA;;;AAED;EACC;EACA;EACA;EACA;EACA;EACA;;;AAED;EACC;;;AAGD;AACA;EACC;;;AAED;EACC;;;AAED;EACC;EACA;;;AAED;EACC;;;AAED;EACC;;;AAED;EACC;;;AAED;AAAA;EAEC;;;AAED;EACC;;;AAED;EACC;EACA;EACA;;;AAGD;AACA;EACC;;;AAED;EACC;EACA;;;AAED;EACC;EACA;;;AAED;EACC;EACA;;;AAED;EACC;EACA;;;AAED;EACC;;;AAED;EACC;;;AAED;AAAA;EAEC;;;AAED;AAAA;EAEC;EACA;;;AAGD;AACA;EACC;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;;;AAED;AAAA;EAEC;;;AAED;EACC;;;AAED;AAAA;AAAA;AAAA;EAIC;;;AAED;AAAA;EAEC;;;AAED;AAAA;EAEC;;;AAGD;AACA;EAAiB;;;AACjB;EAAqB;;;AACrB;EAAsB;;;AACtB;EAAqB;;;AACrB;EAAsB;;;AACtB;EAAqB;;;AACrB;EAAsB;;;AACtB;EAAqB;;;AACrB;EAAsB;;;AACtB;EAAuB;;;AACvB;EAAuB;;;AACvB;EAAwB;;;AACxB;EAAyB;;;AACzB;EAAwB;;;AACxB;EAAyB;;;AACzB;EAAwB;;;AACxB;EAAyB;;;AACzB;EAAwB;;;AACxB;EAAyB;;;AACzB;EAA0B;;;AAC1B;EAA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GN;EAAK;;;AChCR;EAIC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACC;EACA;EACA;EACA;EACA;EACA;;AAGD;EAEC;;;AAOA;EAEE;;AACA;EAEE;;AAIL;EAEC;;AAED;EACC;;AAGD;EAGG;EACA;;AAEA;EAEE;EAEA;EACA;EACA;;AAIL;EACC;EACA;EACA;EACA;;AACA;EACC;EACA;;AAMD;EAEE;;AAGA;EAEE;EACH;;AAEG;EAEE;EACA;EACA;EACA;EACA;EACA;EACJ;EACA;;AAEA;EAAM;;AAEN;EAEC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAED;EACC;;AAEG;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACL;;AAGG;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EAEG;EACA;EACA;EACA;;AAEP;EAEC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EAEA;EACA;EACA;EACA;;AAMG;EAAiC;;AAMjC;EAAM;;AACN;EAAa;;AAEX;EACE;EACA;EACA;;AASZ;EAEE;EACA;EACA;EAEA;EACA;;AACA;EACI;EACA;EACA;;AAIN;EAEE;;AAGF;EAEE;;AAGF;EAEE;EACA;EACA;;AACA;EAEE;EACA;;AAKA;EAEE;;AAEF;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;;AAOR;EAEE;EACA;EACA;EACA;;AAGE;EACE;;AAEF;EAEE;;AAGN;EAEE;;AACA;EACC;EACA;;AAOG;EAEE;;AAMJ;EAAQ;;AAEV;EAEE;EACA;EACA;;AAEF;EAEE;EACA;EACA;;AACA;EACE;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;;AACA;EAEE;EACA;EACA;;AAIN;EAEE;EACA;;AACA;EAEE;EACA;;AAKN;EAEE;EACA;EACA;EACA;;AACA;EAEE;EACA;;AAIJ;EAEG;;AAIH;EAEE;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;EACF;;AACE;EACE;EACA;EACA;EACA;EACA;;AAEJ;EAEE;EACA;;AAEF;EAAO;;AACP;EAAQ;;AACR;EAAQ;;AACR;EAAS;;AACR;EACE;;AAED;EAEE;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACJ;;AAGF;EAAU;;AAER;EAEE;EACA;;AACA;EAAM;EAAkB;EAAmB;;AAU/C;EAEE;;AAEF;EAEE;;AACA;EACC;;AAKH;EAEI;IAEG;;EAEH;IACE;;EACA;IACE;;;AAGR;EAEE;IAAkB;;;AAErB;EAEE;IACE;IACA;IACA;;EAIA;IACE;IACD","file":"admin.css"} \ No newline at end of file diff --git a/scss/admin.scss b/scss/admin.scss index b3a2c2f..cfe34bd 100644 --- a/scss/admin.scss +++ b/scss/admin.scss @@ -100,6 +100,8 @@ box-sizing: border-box; background: #fff; + img { object-fit: contain; } + .upload-title { text-align: center; From d1e3bf46392d39d4360aef337a1c6b9aa357287d Mon Sep 17 00:00:00 2001 From: Bas Schuiling Date: Fri, 17 Mar 2023 15:47:17 -0600 Subject: [PATCH 12/21] Fix - Stops breakage on smaller screen of preview --- css/admin.css | 1 + css/admin.css.map | 2 +- scss/admin.scss | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/css/admin.css b/css/admin.css index f0145bb..ac3c281 100644 --- a/css/admin.css +++ b/css/admin.css @@ -1088,6 +1088,7 @@ vertical-align: top; box-sizing: border-box; background: #fff; + max-width: calc(50% - 25px); } .emr_upload_form .image_chooser.wrapper .image_previews .image_placeholder img { object-fit: contain; diff --git a/css/admin.css.map b/css/admin.css.map index c98ca2c..d5d06e4 100644 --- a/css/admin.css.map +++ b/css/admin.css.map @@ -1 +1 @@ -{"version":3,"sourceRoot":"","sources":["../scss/_datepicker.scss","../scss/_screens.scss","../scss/admin.scss"],"names":[],"mappings":"AAEA;EACC;EACA;EACA;;;AAID;EACC;EACA;EACA;EACA;EACA;;;AAED;EACC;EACA;EACA;;;AAED;EACC;EACA;;;AAED;AAAA;EAEC;EACA;EACA;EACA;;;AAED;AAAA;EAEC;;;AAED;EACC;;;AAED;EACC;;;AAED;EACC;;;AAED;EACC;;;AAED;AAAA;EAEC;EACA;EACA;EACA;EACA;EACA;;;AAED;EACC;EACA;EACA;;;AAED;EACC;EACA;;;AAED;AAAA;EAEC;;;AAED;EACC;EACA;EACA;EACA;;;AAED;EACC;EACA;EACA;EACA;;;AAED;EACC;EACA;;;AAED;AAAA;EAEC;EACA;EACA;EACA;;;AAED;EACC;EACA;EACA;EACA;EACA;EACA;;;AAED;EACC;EACA;EACA;EACA;EACA;EACA;;;AAED;EACC;;;AAGD;AACA;EACC;;;AAED;EACC;;;AAED;EACC;EACA;;;AAED;EACC;;;AAED;EACC;;;AAED;EACC;;;AAED;AAAA;EAEC;;;AAED;EACC;;;AAED;EACC;EACA;EACA;;;AAGD;AACA;EACC;;;AAED;EACC;EACA;;;AAED;EACC;EACA;;;AAED;EACC;EACA;;;AAED;EACC;EACA;;;AAED;EACC;;;AAED;EACC;;;AAED;AAAA;EAEC;;;AAED;AAAA;EAEC;EACA;;;AAGD;AACA;EACC;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;;;AAED;AAAA;EAEC;;;AAED;EACC;;;AAED;AAAA;AAAA;AAAA;EAIC;;;AAED;AAAA;EAEC;;;AAED;AAAA;EAEC;;;AAGD;AACA;EAAiB;;;AACjB;EAAqB;;;AACrB;EAAsB;;;AACtB;EAAqB;;;AACrB;EAAsB;;;AACtB;EAAqB;;;AACrB;EAAsB;;;AACtB;EAAqB;;;AACrB;EAAsB;;;AACtB;EAAuB;;;AACvB;EAAuB;;;AACvB;EAAwB;;;AACxB;EAAyB;;;AACzB;EAAwB;;;AACxB;EAAyB;;;AACzB;EAAwB;;;AACxB;EAAyB;;;AACzB;EAAwB;;;AACxB;EAAyB;;;AACzB;EAA0B;;;AAC1B;EAA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GN;EAAK;;;AChCR;EAIC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACC;EACA;EACA;EACA;EACA;EACA;;AAGD;EAEC;;;AAOA;EAEE;;AACA;EAEE;;AAIL;EAEC;;AAED;EACC;;AAGD;EAGG;EACA;;AAEA;EAEE;EAEA;EACA;EACA;;AAIL;EACC;EACA;EACA;EACA;;AACA;EACC;EACA;;AAMD;EAEE;;AAGA;EAEE;EACH;;AAEG;EAEE;EACA;EACA;EACA;EACA;EACA;EACJ;EACA;;AAEA;EAAM;;AAEN;EAEC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAED;EACC;;AAEG;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACL;;AAGG;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EAEG;EACA;EACA;EACA;;AAEP;EAEC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EAEA;EACA;EACA;EACA;;AAMG;EAAiC;;AAMjC;EAAM;;AACN;EAAa;;AAEX;EACE;EACA;EACA;;AASZ;EAEE;EACA;EACA;EAEA;EACA;;AACA;EACI;EACA;EACA;;AAIN;EAEE;;AAGF;EAEE;;AAGF;EAEE;EACA;EACA;;AACA;EAEE;EACA;;AAKA;EAEE;;AAEF;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;;AAOR;EAEE;EACA;EACA;EACA;;AAGE;EACE;;AAEF;EAEE;;AAGN;EAEE;;AACA;EACC;EACA;;AAOG;EAEE;;AAMJ;EAAQ;;AAEV;EAEE;EACA;EACA;;AAEF;EAEE;EACA;EACA;;AACA;EACE;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;;AACA;EAEE;EACA;EACA;;AAIN;EAEE;EACA;;AACA;EAEE;EACA;;AAKN;EAEE;EACA;EACA;EACA;;AACA;EAEE;EACA;;AAIJ;EAEG;;AAIH;EAEE;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;EACF;;AACE;EACE;EACA;EACA;EACA;EACA;;AAEJ;EAEE;EACA;;AAEF;EAAO;;AACP;EAAQ;;AACR;EAAQ;;AACR;EAAS;;AACR;EACE;;AAED;EAEE;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACJ;;AAGF;EAAU;;AAER;EAEE;EACA;;AACA;EAAM;EAAkB;EAAmB;;AAU/C;EAEE;;AAEF;EAEE;;AACA;EACC;;AAKH;EAEI;IAEG;;EAEH;IACE;;EACA;IACE;;;AAGR;EAEE;IAAkB;;;AAErB;EAEE;IACE;IACA;IACA;;EAIA;IACE;IACD","file":"admin.css"} \ No newline at end of file +{"version":3,"sourceRoot":"","sources":["../scss/_datepicker.scss","../scss/_screens.scss","../scss/admin.scss"],"names":[],"mappings":"AAEA;EACC;EACA;EACA;;;AAID;EACC;EACA;EACA;EACA;EACA;;;AAED;EACC;EACA;EACA;;;AAED;EACC;EACA;;;AAED;AAAA;EAEC;EACA;EACA;EACA;;;AAED;AAAA;EAEC;;;AAED;EACC;;;AAED;EACC;;;AAED;EACC;;;AAED;EACC;;;AAED;AAAA;EAEC;EACA;EACA;EACA;EACA;EACA;;;AAED;EACC;EACA;EACA;;;AAED;EACC;EACA;;;AAED;AAAA;EAEC;;;AAED;EACC;EACA;EACA;EACA;;;AAED;EACC;EACA;EACA;EACA;;;AAED;EACC;EACA;;;AAED;AAAA;EAEC;EACA;EACA;EACA;;;AAED;EACC;EACA;EACA;EACA;EACA;EACA;;;AAED;EACC;EACA;EACA;EACA;EACA;EACA;;;AAED;EACC;;;AAGD;AACA;EACC;;;AAED;EACC;;;AAED;EACC;EACA;;;AAED;EACC;;;AAED;EACC;;;AAED;EACC;;;AAED;AAAA;EAEC;;;AAED;EACC;;;AAED;EACC;EACA;EACA;;;AAGD;AACA;EACC;;;AAED;EACC;EACA;;;AAED;EACC;EACA;;;AAED;EACC;EACA;;;AAED;EACC;EACA;;;AAED;EACC;;;AAED;EACC;;;AAED;AAAA;EAEC;;;AAED;AAAA;EAEC;EACA;;;AAGD;AACA;EACC;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;;;AAED;AAAA;EAEC;;;AAED;EACC;;;AAED;AAAA;AAAA;AAAA;EAIC;;;AAED;AAAA;EAEC;;;AAED;AAAA;EAEC;;;AAGD;AACA;EAAiB;;;AACjB;EAAqB;;;AACrB;EAAsB;;;AACtB;EAAqB;;;AACrB;EAAsB;;;AACtB;EAAqB;;;AACrB;EAAsB;;;AACtB;EAAqB;;;AACrB;EAAsB;;;AACtB;EAAuB;;;AACvB;EAAuB;;;AACvB;EAAwB;;;AACxB;EAAyB;;;AACzB;EAAwB;;;AACxB;EAAyB;;;AACzB;EAAwB;;;AACxB;EAAyB;;;AACzB;EAAwB;;;AACxB;EAAyB;;;AACzB;EAA0B;;;AAC1B;EAA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GN;EAAK;;;AChCR;EAIC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACC;EACA;EACA;EACA;EACA;EACA;;AAGD;EAEC;;;AAOA;EAEE;;AACA;EAEE;;AAIL;EAEC;;AAED;EACC;;AAGD;EAGG;EACA;;AAEA;EAEE;EAEA;EACA;EACA;;AAIL;EACC;EACA;EACA;EACA;;AACA;EACC;EACA;;AAMD;EAEE;;AAGA;EAEE;EACH;;AAEG;EAEE;EACA;EACA;EACA;EACA;EACA;EACJ;EACA;EACA;;AAEA;EAAM;;AAEN;EAEC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAED;EACC;;AAEG;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACL;;AAGG;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EAEG;EACA;EACA;EACA;;AAEP;EAEC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EAEA;EACA;EACA;EACA;;AAMG;EAAiC;;AAMjC;EAAM;;AACN;EAAa;;AAEX;EACE;EACA;EACA;;AASZ;EAEE;EACA;EACA;EAEA;EACA;;AACA;EACI;EACA;EACA;;AAIN;EAEE;;AAGF;EAEE;;AAGF;EAEE;EACA;EACA;;AACA;EAEE;EACA;;AAKA;EAEE;;AAEF;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;;AAOR;EAEE;EACA;EACA;EACA;;AAGE;EACE;;AAEF;EAEE;;AAGN;EAEE;;AACA;EACC;EACA;;AAOG;EAEE;;AAMJ;EAAQ;;AAEV;EAEE;EACA;EACA;;AAEF;EAEE;EACA;EACA;;AACA;EACE;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;;AACA;EAEE;EACA;EACA;;AAIN;EAEE;EACA;;AACA;EAEE;EACA;;AAKN;EAEE;EACA;EACA;EACA;;AACA;EAEE;EACA;;AAIJ;EAEG;;AAIH;EAEE;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;EACF;;AACE;EACE;EACA;EACA;EACA;EACA;;AAEJ;EAEE;EACA;;AAEF;EAAO;;AACP;EAAQ;;AACR;EAAQ;;AACR;EAAS;;AACR;EACE;;AAED;EAEE;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACJ;;AAGF;EAAU;;AAER;EAEE;EACA;;AACA;EAAM;EAAkB;EAAmB;;AAU/C;EAEE;;AAEF;EAEE;;AACA;EACC;;AAKH;EAEI;IAEG;;EAEH;IACE;;EACA;IACE;;;AAGR;EAEE;IAAkB;;;AAErB;EAEE;IACE;IACA;IACA;;EAIA;IACE;IACD","file":"admin.css"} \ No newline at end of file diff --git a/scss/admin.scss b/scss/admin.scss index cfe34bd..e64d6a6 100644 --- a/scss/admin.scss +++ b/scss/admin.scss @@ -99,6 +99,7 @@ vertical-align: top; box-sizing: border-box; background: #fff; + max-width: calc(50% - 25px); img { object-fit: contain; } From de273b24e4ed77593139c859cabfbc0d4402d1b3 Mon Sep 17 00:00:00 2001 From: Pedro Dobrescu Date: Sun, 19 Mar 2023 20:51:14 +0200 Subject: [PATCH 13/21] Bump version --- enable-media-replace.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/enable-media-replace.php b/enable-media-replace.php index 86791b7..4183bf6 100644 --- a/enable-media-replace.php +++ b/enable-media-replace.php @@ -3,7 +3,7 @@ * Plugin Name: Enable Media Replace * Plugin URI: https://wordpress.org/plugins/enable-media-replace/ * Description: Enable replacing media files by uploading a new file in the "Edit Media" section of the WordPress Media Library. - * Version: 4.0.3 + * Version: 4.1.0-DEV01 * Author: ShortPixel * Author URI: https://shortpixel.com * GitHub Plugin URI: https://github.com/short-pixel-optimizer/enable-media-replace @@ -25,7 +25,7 @@ * */ -define( 'EMR_VERSION', '4.0.3-DEV01' ); +define( 'EMR_VERSION', '4.1.0-DEV01' ); if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. From 0332184e5e1451271ff147c743c9c3466bf2d85b Mon Sep 17 00:00:00 2001 From: Bas Schuiling Date: Tue, 21 Mar 2023 12:15:33 -0600 Subject: [PATCH 14/21] Fix - Check for permission on plugin installer --- classes/external/upgrader_skin.php | 1 - classes/external/upsell_installer.php | 15 +++++++++++++++ js/upsell.js | 1 - 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/classes/external/upgrader_skin.php b/classes/external/upgrader_skin.php index 6e92cce..579c9d5 100644 --- a/classes/external/upgrader_skin.php +++ b/classes/external/upgrader_skin.php @@ -81,7 +81,6 @@ public function error( $errors ) { echo wp_json_encode( array( 'error' => __( 'There was an error installing the addon. Please try again.', 'envira-gallery' ) ) ); /* log this for API issues */ - error_log( 'Envira: There was an error installing the addon' ); error_log( print_r( $errors, true ) ); die; diff --git a/classes/external/upsell_installer.php b/classes/external/upsell_installer.php index 97d9e38..3f23ca9 100644 --- a/classes/external/upsell_installer.php +++ b/classes/external/upsell_installer.php @@ -9,6 +9,13 @@ function emr_plugin_install() { $plugin = isset($_POST['plugin']) ? sanitize_text_field($_POST['plugin']) : null; + if ( ! current_user_can('install_plugins')) + { + // Send back a response. + wp_send_json(array('result'=> false)); + die; + } + switch($plugin) { case "envira": @@ -103,6 +110,14 @@ function emr_activate() { $plugin = isset($_POST['plugin']) ? sanitize_text_field($_POST['plugin']) : null; +if ( ! current_user_can('activate_plugins')) +{ + // Send back a response. + wp_send_json(array('result'=> false)); + die; +} + + switch($plugin) { case "envira": diff --git a/js/upsell.js b/js/upsell.js index eba58ca..40bfb88 100644 --- a/js/upsell.js +++ b/js/upsell.js @@ -2,7 +2,6 @@ jQuery(document).ready(function($) { $('.emr-installer').on('click', function(e){ e.preventDefault(); - // var $this = $(this); var button = $(this); var plugin = button.data('plugin'); var nonce = $('#upsell-nonce').val(); From de2d1b3a63d130516a79704579f428e6c4b48837 Mon Sep 17 00:00:00 2001 From: Bas Schuiling Date: Wed, 22 Mar 2023 14:15:20 -0600 Subject: [PATCH 15/21] Changed target on Remote Notice --- classes/Controller/RemoteNoticeController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes/Controller/RemoteNoticeController.php b/classes/Controller/RemoteNoticeController.php index 26d01e4..71fbfab 100644 --- a/classes/Controller/RemoteNoticeController.php +++ b/classes/Controller/RemoteNoticeController.php @@ -88,7 +88,7 @@ private function get_remote_notices() // 'key' => $keyControl->forceGetApiKey(), 'version' => EMR_VERSION, 'plugin' => 'enable-media-replace', - 'target' => 3, + 'target' => '4', ), $url); From 44c4305fa0690bc3c608f883da4d42d74cbe9d7b Mon Sep 17 00:00:00 2001 From: Bas Schuiling Date: Sat, 25 Mar 2023 12:56:56 -0600 Subject: [PATCH 16/21] Adding icons for SPIO notices --- .../filesystem/src/Model/File/FileModel.php | 3 -- .../notices/src/NoticeController.php | 2 +- build/shortpixel/notices/src/css/notices.css | 21 ++++++++++-- .../notices/src/css/notices.css.map | 2 +- build/shortpixel/notices/src/css/notices.scss | 30 +++++++++++++++--- classes/Controller/RemoteNoticeController.php | 6 ++-- classes/emr-plugin.php | 7 ++++ img/notices/robo-cool.png | Bin 0 -> 5640 bytes img/notices/robo-scared.png | Bin 0 -> 6577 bytes img/notices/slider.png | Bin 0 -> 4736 bytes 10 files changed, 56 insertions(+), 15 deletions(-) create mode 100644 img/notices/robo-cool.png create mode 100644 img/notices/robo-scared.png create mode 100644 img/notices/slider.png diff --git a/build/shortpixel/filesystem/src/Model/File/FileModel.php b/build/shortpixel/filesystem/src/Model/File/FileModel.php index 300114c..a5e88dc 100644 --- a/build/shortpixel/filesystem/src/Model/File/FileModel.php +++ b/build/shortpixel/filesystem/src/Model/File/FileModel.php @@ -416,7 +416,6 @@ public function getMime() if ($this->exists() && ! $this->is_virtual() ) { $this->mime = wp_get_image_mime($this->fullpath); - // If this fails, try another function if (false === $this->mime) { $image_data = wp_check_filetype_and_ext($this->getFullPath(), $this->getFileName()); @@ -430,8 +429,6 @@ public function getMime() else $this->mime = false; - - return $this->mime; } diff --git a/build/shortpixel/notices/src/NoticeController.php b/build/shortpixel/notices/src/NoticeController.php index 20370b9..7ba8f1f 100644 --- a/build/shortpixel/notices/src/NoticeController.php +++ b/build/shortpixel/notices/src/NoticeController.php @@ -220,7 +220,7 @@ public function ajax_action() if (! is_null($id)) { - + $notice = $this->getNoticeByID($id); } else diff --git a/build/shortpixel/notices/src/css/notices.css b/build/shortpixel/notices/src/css/notices.css index dc257fb..2cbb148 100644 --- a/build/shortpixel/notices/src/css/notices.css +++ b/build/shortpixel/notices/src/css/notices.css @@ -1,12 +1,29 @@ .shortpixel.shortpixel-notice { + min-height: 75px; padding: 8px; + display: flex; + align-items: center; background: #fff; + padding: 1px 12px; + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04); border: 1px solid #c3c4c7; + margin: 15px 0; border-left-width: 4px; - box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04); - margin: 5px 15px 2px; + border-left-color: #72aee6; position: relative; } +.shortpixel.shortpixel-notice span { + vertical-align: middle; +} +.shortpixel.shortpixel-notice span.icon { + margin: 0 25px 0 0; + width: 80px; +} +.shortpixel.shortpixel-notice span.content { + padding: 8px 0; + word-wrap: break-word; + overflow: hidden; +} .shortpixel.shortpixel-notice img { display: inline-block; margin: 0 25px 0 0; diff --git a/build/shortpixel/notices/src/css/notices.css.map b/build/shortpixel/notices/src/css/notices.css.map index 637fcd8..0182154 100644 --- a/build/shortpixel/notices/src/css/notices.css.map +++ b/build/shortpixel/notices/src/css/notices.css.map @@ -1 +1 @@ -{"version":3,"sourceRoot":"","sources":["notices.scss"],"names":[],"mappings":"AACA;EAIG;EACF;EACA;EACA;EACA;EACA;EACA;;AAEE;EAEE;EACA;EACA;;AAEF;EAEE;;AAGH;EAEC;;AAED;EAEC;;AAED;EAEC;;AAED;EAEE;;;AAIJ;AACA;EAGE;EACA;EAEA;;AACA;EACE;;AAEF;EAEE;;;AAIJ;EAEE","file":"notices.css"} \ No newline at end of file +{"version":3,"sourceRoot":"","sources":["notices.scss"],"names":[],"mappings":"AACA;EAGC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EAEC;;AACA;EACC;EACA;;AAED;EAEC;EACA;EACA;;AAKA;EAEE;EACA;EACA;;AAEF;EAEE;;AAGH;EAEC;;AAED;EAEC;;AAED;EAEC;;AAED;EAEE;;;AAIJ;AACA;EAGE;EACA;EAEA;;AACA;EACE;;AAEF;EAEE;;;AAIJ;EAEE","file":"notices.css"} \ No newline at end of file diff --git a/build/shortpixel/notices/src/css/notices.scss b/build/shortpixel/notices/src/css/notices.scss index 912028c..e851d24 100644 --- a/build/shortpixel/notices/src/css/notices.scss +++ b/build/shortpixel/notices/src/css/notices.scss @@ -1,16 +1,36 @@ .shortpixel.shortpixel-notice { - //padding: 18px; - //min-height: 50px; - padding: 8px; + + min-height: 75px; + padding: 8px; + display: flex; + align-items: center; background: #fff; + padding: 1px 12px; + box-shadow: 0 1px 1px rgba(0,0,0,0.04); border: 1px solid #c3c4c7; + margin: 15px 0; border-left-width: 4px; - box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04); - margin: 5px 15px 2px; + border-left-color: #72aee6; position: relative; + span + { + vertical-align: middle; + &.icon { + margin: 0 25px 0 0; + width: 80px; + } + &.content + { + padding: 8px 0; + word-wrap: break-word; + overflow: hidden; + //display: flex; // magically fixes verticality issues + } + } + img { display:inline-block; diff --git a/classes/Controller/RemoteNoticeController.php b/classes/Controller/RemoteNoticeController.php index 71fbfab..e2f5a9a 100644 --- a/classes/Controller/RemoteNoticeController.php +++ b/classes/Controller/RemoteNoticeController.php @@ -85,14 +85,14 @@ private function get_remote_notices() $notices = get_transient($transient_name); $url = $this->remote_message_endpoint; $url = add_query_arg(array( // has url - // 'key' => $keyControl->forceGetApiKey(), 'version' => EMR_VERSION, 'plugin' => 'enable-media-replace', - 'target' => '4', + 'target' => 4, + ), $url); - if ( $notices === false ) { + if ( $notices === false || $notices == 'none' ) { $notices_response = wp_safe_remote_request( $url ); $content = false; diff --git a/classes/emr-plugin.php b/classes/emr-plugin.php index 000a9a7..fe62f0d 100644 --- a/classes/emr-plugin.php +++ b/classes/emr-plugin.php @@ -195,6 +195,13 @@ public function setScreen() RemoteNoticeController::getInstance(); // check for remote stuff $notices = Notices::getInstance(); + $notices->loadIcons(array( + 'normal' => '', + 'success' => '', + 'warning' => '', + 'error' => '', + )); + add_action('admin_notices', array($notices, 'admin_notices')); // previous page / init time } } diff --git a/img/notices/robo-cool.png b/img/notices/robo-cool.png new file mode 100644 index 0000000000000000000000000000000000000000..b30d49f66a46e287630bded8f3cea55240748dcf GIT binary patch literal 5640 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 O0000 Date: Mon, 27 Mar 2023 10:09:52 -0600 Subject: [PATCH 17/21] Prevent transient storing whole notice --- classes/Controller/RemoteNoticeController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes/Controller/RemoteNoticeController.php b/classes/Controller/RemoteNoticeController.php index e2f5a9a..f371a79 100644 --- a/classes/Controller/RemoteNoticeController.php +++ b/classes/Controller/RemoteNoticeController.php @@ -104,7 +104,7 @@ private function get_remote_notices() $notices = 'none'; // Save transient anywhere to prevent over-asking when nothing good is there. - set_transient( $transient_name, $notices, $transient_duration ); + set_transient( $transient_name, 'true', $transient_duration ); } else { From 1d69eefd95fe56d3da9fe2193b1f00e63b95887e Mon Sep 17 00:00:00 2001 From: Pedro Dobrescu Date: Mon, 27 Mar 2023 20:42:10 +0300 Subject: [PATCH 18/21] Update the success and error messages --- views/error.php | 2 +- views/success.php | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/views/error.php b/views/error.php index 9b9ded3..00e8f4b 100644 --- a/views/error.php +++ b/views/error.php @@ -26,7 +26,7 @@

You can return to previous page

-

', ''); ?>

+

', ''); ?>

diff --git a/views/success.php b/views/success.php index 2d6fd1d..4c29bd2 100644 --- a/views/success.php +++ b/views/success.php @@ -16,10 +16,14 @@

-

Congratualations. Your image has been replaced!

+

+ +

+ +

', ''); ?>

You will be redirect to the image screen in a few seconds. - ( ) or click here to continue + ( ) or click here to continue

From da613822f7aedb48e88a449ed3bfd47408249d44 Mon Sep 17 00:00:00 2001 From: Bas Schuiling Date: Mon, 27 Mar 2023 13:38:07 -0600 Subject: [PATCH 19/21] Translation strings --- views/error.php | 3 ++- views/screen.php | 5 ++++- views/success.php | 9 ++++++--- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/views/error.php b/views/error.php index 00e8f4b..26986c4 100644 --- a/views/error.php +++ b/views/error.php @@ -23,7 +23,8 @@ echo '

' . $view->errorDescription . '

'; } ?> -

You can return to previous page

+

', ''); ?>

', ''); ?>

diff --git a/views/screen.php b/views/screen.php index fd24518..2b9beff 100644 --- a/views/screen.php +++ b/views/screen.php @@ -63,7 +63,10 @@ -

You are about to replace getFileName() ?> in your media library. This will be permanent .
You can click on the new image panel and select a file from your computer. You can also drag and drop a file into this window

+

+ getFullPath() . '">' . $sourceFile->getFileName() . '', '','', '
' ); + ?> +

%s','enable-media-replace'), size_format(wp_max_upload_size() ) ) ?>

', ''); ?>

diff --git a/views/success.php b/views/success.php index 4c29bd2..ad90e76 100644 --- a/views/success.php +++ b/views/success.php @@ -20,10 +20,13 @@

-

', ''); ?>

+

', ''); ?>

+ +

', + '', ''); + ?> -

You will be redirect to the image screen in a few seconds. - ( ) or click here to continue

From 134fff5d8008ad047bfc47a8f4c7caaad9d26b1f Mon Sep 17 00:00:00 2001 From: Bas Schuiling Date: Mon, 27 Mar 2023 14:06:19 -0600 Subject: [PATCH 20/21] esc-url --- views/upsell.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/views/upsell.php b/views/upsell.php index 7dd6a4f..4d35f1a 100644 --- a/views/upsell.php +++ b/views/upsell.php @@ -69,7 +69,7 @@
- ShortPixel + ShortPixel

@@ -100,7 +100,7 @@
-

ShortPixel Theme

+

ShortPixel Theme

From 35b3451a890daebd185ae89938051b28da7c8190 Mon Sep 17 00:00:00 2001 From: Pedro Dobrescu Date: Tue, 28 Mar 2023 11:55:28 +0300 Subject: [PATCH 21/21] Update the readme file and version numbers for the 4.1.0 release --- enable-media-replace.php | 4 ++-- readme.txt | 21 ++++++++++++++++++--- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/enable-media-replace.php b/enable-media-replace.php index 4183bf6..59dcfd3 100644 --- a/enable-media-replace.php +++ b/enable-media-replace.php @@ -3,7 +3,7 @@ * Plugin Name: Enable Media Replace * Plugin URI: https://wordpress.org/plugins/enable-media-replace/ * Description: Enable replacing media files by uploading a new file in the "Edit Media" section of the WordPress Media Library. - * Version: 4.1.0-DEV01 + * Version: 4.1.0 * Author: ShortPixel * Author URI: https://shortpixel.com * GitHub Plugin URI: https://github.com/short-pixel-optimizer/enable-media-replace @@ -25,7 +25,7 @@ * */ -define( 'EMR_VERSION', '4.1.0-DEV01' ); +define( 'EMR_VERSION', '4.1.0' ); if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. diff --git a/readme.txt b/readme.txt index 7c6a0eb..c535c3d 100644 --- a/readme.txt +++ b/readme.txt @@ -5,13 +5,13 @@ Tags: replace, attachment, media, files, replace image, remove background, repla Requires at least: 4.9.7 Tested up to: 6.2 Requires PHP: 5.6 -Stable tag: 4.0.3 +Stable tag: 4.1.0 Easily replace any attached image/file by simply uploading a new file in the Media Library edit view - a real time saver! == Description == -**A free, lightweight and easy to use plugin that allows you to seamlessly replace an image or file in your Media Library by uploading a new file in its place. No more deleting, renaming and re-uploading files! +**A free, lightweight and easy to use plugin that allows you to seamlessly replace an image or file in your Media Library by uploading a new file in its place. No more deleting, renaming and re-uploading files! Now fully compatible with WP Offload Media! New beta feature! You can now remove the background of your images for better integration with eCommerce solutions! Supported by the friendly team that created ShortPixel :)** @@ -34,7 +34,9 @@ This plugin is very powerful and a must-have for all major websites built with W Similar to replacing media, you can also remove the background of the images from the Media Library! The background removal feature sends the images to ShortPixel's API, removes the background and sends them back in a preview window. If everything looks good, just replace the image with the one that has the background removed! If the source image is a PNG file, you will get a transparent background, while the other images default to a solid white background. You also have the option to choose a different color with an embedded color picker. The background removal feature is still in beta and will be free of charge for a reasonable usage. -If you don't want to utilize the background removal feature, add add_filter('emr/feature/background', '__return_false' ); to your functions.php +If you don't want to use the background removal feature, add this line to your theme's functions.php file, or use a plugin like Code Snippets: + +```add_filter( 'emr/feature/background', '__return_false' );``` #### Show file modification time @@ -63,6 +65,19 @@ If you want more control over the format in which the time is shown, you can use == Changelog == += 4.1.0 = + +Release date: March 28, 2023 +* New: Integration with WP Offload Media; items that are offloaded can now be replaced correctly; +* New: Switch to a Replacer module that improves the code and makes it more robust; +* New: Adding an intermediate confirmation page to solve possible redirection issues; +* Tweak: The new image can now be dragged and dropped directly into the preview area; +* Tweak: Improved the display of both the original image and the new image on the replacement screen; +* Tweak: Improved the notification system and added a mechanism for remote notifications; +* Tweak: Updated the texts and banners to look better on the replacement screen; +* Fix: Added documentation in the readme to disable the background removal feature (kudos to @jstask82); +* Fix: Increased the security of the plugin by adding checks for various AJAX calls; + = 4.0.3 = Release date: February 21, 2023