Enable Media Replace - Version 3.4.0

Version Description

Release date: June 9th 2020 * New - In edit media screen EMR notes user who replaced file if this was not uploader; * New - Added Drag and Drop area for files; * New - When replacing with new file name, now also possible to update upload path; * Fix - Various minor CSS tweaks and fixes; * Update of Underlying libraries

Download this release

Release Info

Developer petredobrescu
Plugin Icon 128x128 Enable Media Replace
Version 3.4.0
Comparing to
See all releases

Code changes from version 3.3.12 to 3.4.0

build/shortpixel/PackageLoader.php CHANGED
@@ -3,12 +3,26 @@ namespace EnableMediaReplace\Build;
3
 
4
  class PackageLoader
5
  {
6
- public $dir;
 
7
 
8
- public function getComposerFile()
9
- {
10
- return json_decode(file_get_contents($this->dir."/composer.json"), 1);
11
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
12
 
13
  public function load($dir)
14
  {
@@ -61,7 +75,11 @@ class PackageLoader
61
  if ($psr4) {
62
  $classname = str_replace($namespace, "", $classname);
63
  }
64
- $filename = preg_replace("#\\\\#", "", $classname).".php";
 
 
 
 
65
 
66
  foreach ($classpaths as $classpath) {
67
  $fullpath = trailingslashit($dir) . trailingslashit($classpath) .$filename;
3
 
4
  class PackageLoader
5
  {
6
+ public $dir;
7
+ public $composerFile = false;
8
 
9
+ public function __construct()
10
+ {
11
+
12
+ }
13
+
14
+ public function setComposerFile($filePath)
15
+ {
16
+ $this->composerFile = json_decode(file_get_contents($filePath),1);
17
+ }
18
+
19
+ public function getComposerFile($filePath = false )
20
+ {
21
+ if (! $this->composerFile)
22
+ $this->composerFile = json_decode(file_get_contents($this->dir."/composer.json"), 1);
23
+
24
+ return $this->composerFile;
25
+ }
26
 
27
  public function load($dir)
28
  {
75
  if ($psr4) {
76
  $classname = str_replace($namespace, "", $classname);
77
  }
78
+
79
+ // $filename = preg_replace("#\\\\#", "", $classname).".php";
80
+ // This is fix for nested classes which were losing a /
81
+ $filename = ltrim($classname .'.php', '\\');
82
+ $filename = str_replace('\\','/', $filename);
83
 
84
  foreach ($classpaths as $classpath) {
85
  $fullpath = trailingslashit($dir) . trailingslashit($classpath) .$filename;
build/shortpixel/log/src/ShortPixelLogger.php CHANGED
@@ -250,6 +250,12 @@ namespace EnableMediaReplace\ShortPixelLogger;
250
  $log->addLog($message, $level, $args);
251
  }
252
 
 
 
 
 
 
 
253
  public static function logLevel($level)
254
  {
255
  $log = self::getInstance();
250
  $log->addLog($message, $level, $args);
251
  }
252
 
253
+ /** These should be removed every release. They are temporary only for d'bugging the current release */
254
+ public static function addTemp($message, $args = array())
255
+ {
256
+ self::addDebug($message, $args);
257
+ }
258
+
259
  public static function logLevel($level)
260
  {
261
  $log = self::getInstance();
build/shortpixel/notices/composer.json CHANGED
@@ -1,7 +1,7 @@
1
  {
2
  "name": "shortpixel/notices",
3
  "description": "ShortPixel WordPress Notice System",
4
- "version": "1.3",
5
  "type": "library",
6
  "license": "MIT",
7
  "authors": [
1
  {
2
  "name": "shortpixel/notices",
3
  "description": "ShortPixel WordPress Notice System",
4
+ "version": "1.5",
5
  "type": "library",
6
  "license": "MIT",
7
  "authors": [
build/shortpixel/notices/src/NoticeController.php CHANGED
@@ -19,7 +19,6 @@ class NoticeController //extends ShortPixelController
19
  /** For backward compat. Never call constructor directly. */
20
  public function __construct()
21
  {
22
- // $this->loadModel('notice');
23
  $ns = __NAMESPACE__;
24
  $ns = substr($ns, 0, strpos($ns, '\\')); // try to get first part of namespace
25
  $this->notice_option = $ns . '-notices';
@@ -65,8 +64,6 @@ class NoticeController //extends ShortPixelController
65
  {
66
  $notices = get_option($this->notice_option, false);
67
  $cnotice = (is_array($notices)) ? count($notices) : 0;
68
- if ($cnotice > 0)
69
- Log::addDebug('Notice Control - #num notices' . $cnotice);
70
 
71
  if ($notices !== false && is_array($notices))
72
  {
@@ -90,7 +87,7 @@ class NoticeController //extends ShortPixelController
90
  foreach(self::$notices as $nitem)
91
  {
92
  if ($nitem->message == $notice->message && $nitem->code == $notice->code) // same message.
93
- return $notice; // return the notice with the same message.
94
  }
95
  }
96
  self::$notices[] = $notice;
@@ -141,6 +138,7 @@ class NoticeController //extends ShortPixelController
141
  public function getNoticesForDisplay()
142
  {
143
  $newNotices = array();
 
144
  foreach(self::$notices as $notice)
145
  {
146
  if ($notice->isDismissed()) // dismissed never displays.
@@ -256,7 +254,6 @@ class NoticeController //extends ShortPixelController
256
  $noticeController = self::getInstance();
257
  $notice = $noticeController->addNotice($message, NoticeModel::NOTICE_WARNING, $unique);
258
  return $notice;
259
-
260
  }
261
 
262
  public static function addSuccess($message, $unique = false)
@@ -267,7 +264,23 @@ class NoticeController //extends ShortPixelController
267
 
268
  }
269
 
270
- public static function makePersistent($notice, $key, $suppress = -1)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
271
  {
272
  $noticeController = self::getInstance();
273
  $existing = $noticeController->getNoticeByID($key);
@@ -275,17 +288,24 @@ class NoticeController //extends ShortPixelController
275
  // if this key already exists, don't allow the new notice to be entered into the array. Remove it since it's already created.
276
  if ($existing)
277
  {
278
- for($i = 0; $i < count(self::$notices); $i++)
279
- {
280
- $item = self::$notices[$i];
281
- if ($item->message == $notice->message && $item->getID() == null)
282
- unset(self::$notices[$i]);
283
- //if ($notice_item )
284
- }
 
 
 
 
 
 
 
285
  }
286
  else
287
  {
288
- $notice->setPersistent($key, $suppress); // set this notice persistent.
289
  }
290
 
291
  $noticeController->update();
19
  /** For backward compat. Never call constructor directly. */
20
  public function __construct()
21
  {
 
22
  $ns = __NAMESPACE__;
23
  $ns = substr($ns, 0, strpos($ns, '\\')); // try to get first part of namespace
24
  $this->notice_option = $ns . '-notices';
64
  {
65
  $notices = get_option($this->notice_option, false);
66
  $cnotice = (is_array($notices)) ? count($notices) : 0;
 
 
67
 
68
  if ($notices !== false && is_array($notices))
69
  {
87
  foreach(self::$notices as $nitem)
88
  {
89
  if ($nitem->message == $notice->message && $nitem->code == $notice->code) // same message.
90
+ return $nitem; // return the notice with the same message.
91
  }
92
  }
93
  self::$notices[] = $notice;
138
  public function getNoticesForDisplay()
139
  {
140
  $newNotices = array();
141
+
142
  foreach(self::$notices as $notice)
143
  {
144
  if ($notice->isDismissed()) // dismissed never displays.
254
  $noticeController = self::getInstance();
255
  $notice = $noticeController->addNotice($message, NoticeModel::NOTICE_WARNING, $unique);
256
  return $notice;
 
257
  }
258
 
259
  public static function addSuccess($message, $unique = false)
264
 
265
  }
266
 
267
+ public static function addDetail($notice, $detail)
268
+ {
269
+ $noticeController = self::getInstance();
270
+ $notice->addDetail($detail);
271
+
272
+ // $notice_id = spl_object_id($notice);
273
+
274
+ $noticeController->update();
275
+ }
276
+
277
+ /** Make a regular notice persistent across multiple page loads
278
+ * @param $notice NoticeModel The Notice to make Persistent
279
+ * @param $key String Identifier of the persistent notice.
280
+ * @param $suppress Int When dismissed, time to stay dismissed
281
+ * @param $callback Function Callable function
282
+ */
283
+ public static function makePersistent($notice, $key, $suppress = -1, $callback = null)
284
  {
285
  $noticeController = self::getInstance();
286
  $existing = $noticeController->getNoticeByID($key);
288
  // if this key already exists, don't allow the new notice to be entered into the array. Remove it since it's already created.
289
  if ($existing)
290
  {
291
+ for($i = 0; $i < count(self::$notices); $i++)
292
+ {
293
+ $item = self::$notices[$i];
294
+
295
+ if ($item->message == $notice->message && $item->getID() == null)
296
+ {
297
+ if ($item->message != $existing->message) // allow the persistent message to be updated, if something else is served on this ID
298
+ {
299
+ $existing->message = $item->message;
300
+ }
301
+ unset(self::$notices[$i]);
302
+ }
303
+ //if ($notice_item )
304
+ }
305
  }
306
  else
307
  {
308
+ $notice->setPersistent($key, $suppress, $callback); // set this notice persistent.
309
  }
310
 
311
  $noticeController->update();
build/shortpixel/notices/src/NoticeModel.php CHANGED
@@ -4,6 +4,7 @@ namespace EnableMediaReplace\Notices;
4
  class NoticeModel //extends ShortPixelModel
5
  {
6
  public $message; // The message we want to convey.
 
7
  public $code;
8
 
9
  private $id = null; // used for persistent messages.
@@ -16,6 +17,7 @@ class NoticeModel //extends ShortPixelModel
16
  public $messageType = self::NOTICE_NORMAL;
17
 
18
  public $notice_action; // empty unless for display. Ajax action to talk back to controller.
 
19
 
20
  public static $icons = array();
21
 
@@ -72,15 +74,43 @@ class NoticeModel //extends ShortPixelModel
72
  $this->suppress_until = time() + $this->suppress_period;
73
  }
74
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
  /** Set a notice persistent. Meaning it shows every page load until dismissed.
76
  * @param $key Unique Key of this message. Required
77
  * @param $suppress When dismissed do not show this message again for X amount of time. When -1 it will just be dropped from the Notices and not suppressed
78
  */
79
- public function setPersistent($key, $suppress = -1)
80
  {
81
  $this->id = $key;
82
  $this->is_persistent = true;
83
  $this->suppress_period = $suppress;
 
 
 
 
84
  }
85
 
86
  public static function setIcon($notice_type, $icon)
@@ -111,6 +141,13 @@ class NoticeModel //extends ShortPixelModel
111
 
112
  $icon = '';
113
 
 
 
 
 
 
 
 
114
  switch($this->messageType)
115
  {
116
  case self::NOTICE_ERROR:
@@ -147,9 +184,24 @@ class NoticeModel //extends ShortPixelModel
147
  $class .= 'is-persistent ';
148
  }
149
 
150
- $id = ! is_null($this->id) ? 'id="' . $this->id . '"' : '';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
151
 
152
- $output = "<div $id class='$class'><span class='icon'> " . $icon . "</span> <span class='content'>" . $this->message . "</span></div>";
153
  if ($this->is_persistent && $this->is_removable)
154
  {
155
  $output .= "<script type='text/javascript'>\n" . $this->getDismissJS() . "\n</script>";
@@ -158,6 +210,19 @@ class NoticeModel //extends ShortPixelModel
158
 
159
  }
160
 
 
 
 
 
 
 
 
 
 
 
 
 
 
161
  private function getDismissJS()
162
  {
163
  $url = wp_json_encode(admin_url('admin-ajax.php'));
@@ -168,7 +233,7 @@ class NoticeModel //extends ShortPixelModel
168
 
169
  // $data_string = "{action:'$this->notice_action'}";
170
 
171
- $js = "jQuery(document).on('click','#$this->id button',
172
  function() {
173
  var data = $data;
174
  var url = $url;
4
  class NoticeModel //extends ShortPixelModel
5
  {
6
  public $message; // The message we want to convey.
7
+ public $details = array(); // extra details, like the files involved. Something could be hideable in the future.
8
  public $code;
9
 
10
  private $id = null; // used for persistent messages.
17
  public $messageType = self::NOTICE_NORMAL;
18
 
19
  public $notice_action; // empty unless for display. Ajax action to talk back to controller.
20
+ protected $callback; // empty unless callback is needed
21
 
22
  public static $icons = array();
23
 
74
  $this->suppress_until = time() + $this->suppress_period;
75
  }
76
 
77
+ public function unDismiss()
78
+ {
79
+ $this->is_dismissed = false;
80
+ }
81
+
82
+ public function setDismissedUntil($timestamp)
83
+ {
84
+ $this->suppress_until = $timestamp;
85
+ }
86
+
87
+ /** Support for extra information beyond the message.
88
+ * Can help to not overwhelm users w/ the same message but different file /circumstances.
89
+ */
90
+ public function addDetail($detail, $clean = false)
91
+ {
92
+ if ($clean)
93
+ $this->details = array();
94
+
95
+ if (! in_array($detail, $this->details) )
96
+ $this->details[] = $detail;
97
+ }
98
+
99
+
100
+
101
  /** Set a notice persistent. Meaning it shows every page load until dismissed.
102
  * @param $key Unique Key of this message. Required
103
  * @param $suppress When dismissed do not show this message again for X amount of time. When -1 it will just be dropped from the Notices and not suppressed
104
  */
105
+ public function setPersistent($key, $suppress = -1, $callback = null)
106
  {
107
  $this->id = $key;
108
  $this->is_persistent = true;
109
  $this->suppress_period = $suppress;
110
+ if ( ! is_null($callback) && is_callable($callback))
111
+ {
112
+ $this->callback = $callback;
113
+ }
114
  }
115
 
116
  public static function setIcon($notice_type, $icon)
141
 
142
  $icon = '';
143
 
144
+ if ($this->callback)
145
+ {
146
+ $return = call_user_func($this->callback, $this);
147
+ if ($return === false) // don't display is callback returns false explicitly.
148
+ return;
149
+ }
150
+
151
  switch($this->messageType)
152
  {
153
  case self::NOTICE_ERROR:
184
  $class .= 'is-persistent ';
185
  }
186
 
187
+ $id = ! is_null($this->id) ? $this->id : uniqid();
188
+ //'id="' . $this->id . '"'
189
+ $output = "<div id='$id' class='$class'><span class='icon'> " . $icon . "</span> <span class='content'>" . $this->message;
190
+ if ($this->hasDetails())
191
+ {
192
+ $output .= '<div class="details-wrapper">
193
+ <input type="checkbox" name="detailhider" id="check-' . $id .'">
194
+ <label for="check-' . $id . '" class="show-details"><span>' . __('See Details', 'shortpixel-image-optimiser') . '</span>
195
+ </label>';
196
+
197
+ $output .= "<div class='detail-content-wrapper'><p class='detail-content'>" . $this->parseDetails() . "</p></div>";
198
+ $output .= '<label for="check-' . $id . '" class="hide-details"><span>' . __('Hide Details', 'shortpixel-image-optimiser') . '</span></label>';
199
+
200
+ $output .= '</div>'; // detail rapper
201
+
202
+ }
203
+ $output .= "</span></div>";
204
 
 
205
  if ($this->is_persistent && $this->is_removable)
206
  {
207
  $output .= "<script type='text/javascript'>\n" . $this->getDismissJS() . "\n</script>";
210
 
211
  }
212
 
213
+ protected function hasDetails()
214
+ {
215
+ if (is_array($this->details) && count($this->details) > 0)
216
+ return true;
217
+ else
218
+ return false;
219
+ }
220
+
221
+ protected function parseDetails()
222
+ {
223
+ return implode('<BR>', $this->details);
224
+ }
225
+
226
  private function getDismissJS()
227
  {
228
  $url = wp_json_encode(admin_url('admin-ajax.php'));
233
 
234
  // $data_string = "{action:'$this->notice_action'}";
235
 
236
+ $js = "jQuery(document).on('click','#$this->id button.notice-dismiss',
237
  function() {
238
  var data = $data;
239
  var url = $url;
classes/emr-plugin.php CHANGED
@@ -283,7 +283,7 @@ class EnableMediaReplacePlugin
283
  $form_fields["enable-media-replace"] = array(
284
  "label" => esc_html__("Replace media", "enable-media-replace"),
285
  "input" => "html",
286
- "html" => "<p><a class='button-secondary' $link>" . esc_html__("Upload a new file", "enable-media-replace") . "</a></p>", "helps" => esc_html__("To replace the current file, click the link and upload a replacement.", "enable-media-replace")
287
  );
288
 
289
  return $form_fields;
@@ -359,17 +359,28 @@ class EnableMediaReplacePlugin
359
  return false;
360
 
361
  $post_id = $post->ID;
362
- if ( $post->post_modified == $post->post_date ) {
363
- return;
364
- }
365
 
366
- $modified = date_i18n( __( 'M j, Y @ H:i' ) , strtotime( $post->post_modified ) );
 
 
 
 
367
 
368
- ?>
369
- <div class="misc-pub-section curtime">
370
- <span id="timestamp"><?php echo esc_html__( 'Revised', 'enable-media-replace' ); ?>: <b><?php echo $modified; ?></b></span>
371
- </div>
372
  <?php
 
 
 
 
 
 
 
 
 
 
 
 
 
373
  }
374
 
375
  /** When an image is just replaced, it can stuck in the browser cache making a look like it was not replaced. Try
283
  $form_fields["enable-media-replace"] = array(
284
  "label" => esc_html__("Replace media", "enable-media-replace"),
285
  "input" => "html",
286
+ "html" => "<a class='button-secondary' $link>" . esc_html__("Upload a new file", "enable-media-replace") . "</a>", "helps" => esc_html__("To replace the current file, click the link and upload a replacement.", "enable-media-replace")
287
  );
288
 
289
  return $form_fields;
359
  return false;
360
 
361
  $post_id = $post->ID;
362
+ if ( $post->post_modified !== $post->post_date ) {
 
 
363
 
364
+ $modified = date_i18n( __( 'M j, Y @ H:i' ) , strtotime( $post->post_modified ) );
365
+ ?>
366
+ <div class="misc-pub-section curtime">
367
+ <span id="timestamp"><?php echo esc_html__( 'Revised', 'enable-media-replace' ); ?>: <b><?php echo $modified; ?></b></span>
368
+ </div>
369
 
 
 
 
 
370
  <?php
371
+ }
372
+ $author_id = get_post_meta($post_id, '_emr_replace_author', true);
373
+
374
+ if ($author_id)
375
+ {
376
+ $display_name = get_the_author_meta('display_name', $author_id);
377
+ ?>
378
+ <div class="misc-pub-section replace_author">
379
+ <span><?php echo esc_html__( 'Replaced By', 'enable-media-replace' ); ?>: <b><?php echo $display_name; ?></b></span>
380
+ </div>
381
+ <?php
382
+ }
383
+
384
  }
385
 
386
  /** When an image is just replaced, it can stuck in the browser cache making a look like it was not replaced. Try
classes/replacer.php CHANGED
@@ -21,6 +21,8 @@ class Replacer
21
  protected $target_metadata;
22
  protected $target_url;
23
 
 
 
24
  protected $replaceMode = 1; // replace if nothing is set
25
  protected $timeMode = 1;
26
  protected $datetime = null;
@@ -94,20 +96,25 @@ class Replacer
94
  $this->targetName = $fileName;
95
  //$this->targetFile = new File($file); // this will point to /tmp!
96
 
97
- $this->removeCurrent(); // tries to remove the current files.
98
  $targetFile = $this->getTargetFile();
99
 
100
  if (is_null($targetFile))
101
  {
102
- $ex = __('Target File could not be set. The source file might not be there. In case of search and replace, a filter might prevent this', "enable-media-replace");
103
- throw new \RuntimeException($ex);
 
104
  }
105
 
 
 
106
  $targetFileObj = new File($targetFile);
107
  $result = $targetFileObj->checkAndCreateFolder();
108
  if ($result === false)
109
  Log::addError('Directory creation for targetFile failed');
110
 
 
 
 
111
  /* @todo See if wp_handle_sideload / wp_handle_upload can be more securely used for this */
112
  $result_moved = move_uploaded_file($file,$targetFile);
113
 
@@ -123,7 +130,7 @@ class Replacer
123
  if ($this->sourceFile->getPermissions() > 0)
124
  chmod( $targetFile, $this->sourceFile->getPermissions() ); // restore permissions
125
  else {
126
- // 'Setting permissions failed';
127
  }
128
 
129
  // update the file attached. This is required for wp_get_attachment_url to work.
@@ -149,6 +156,20 @@ class Replacer
149
  wp_update_attachment_metadata( $this->post_id, $metadata );
150
  $this->target_metadata = $metadata;
151
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
152
  if ($this->replaceMode == self::MODE_SEARCHREPLACE)
153
  {
154
  // Write new image title.
@@ -205,6 +226,7 @@ class Replacer
205
 
206
  do_action("enable-media-replace-upload-done", $this->target_url, $this->source_url);
207
 
 
208
  }
209
 
210
  protected function getNewTitle()
@@ -236,6 +258,20 @@ class Replacer
236
  return $this->sourceFile;
237
  }
238
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
239
  /** Returns a full target path to place to new file. Including the file name! **/
240
  protected function getTargetFile()
241
  {
@@ -247,6 +283,16 @@ class Replacer
247
  elseif ($this->replaceMode == self::MODE_SEARCHREPLACE)
248
  {
249
  $path = $this->sourceFile->getFilePath();
 
 
 
 
 
 
 
 
 
 
250
  $unique = wp_unique_filename($path, $this->targetName);
251
 
252
  $new_filename = apply_filters( 'emr_unique_filename', $unique, $path, $this->post_id );
@@ -261,11 +307,12 @@ class Replacer
261
  $targetFile = trailingslashit($upload_dir['path']) . wp_unique_filename($targetFile, $this->targetName);
262
  }
263
  else {
264
- $err = 'EMR could not establish a proper destination for replacement';
 
265
  Log::addError($err);
266
- throw new \RuntimeException($err);
267
- exit($err); // fallback
268
-
269
  }
270
  }
271
 
21
  protected $target_metadata;
22
  protected $target_url;
23
 
24
+ protected $target_location = false; // option for replacing to another target location
25
+
26
  protected $replaceMode = 1; // replace if nothing is set
27
  protected $timeMode = 1;
28
  protected $datetime = null;
96
  $this->targetName = $fileName;
97
  //$this->targetFile = new File($file); // this will point to /tmp!
98
 
 
99
  $targetFile = $this->getTargetFile();
100
 
101
  if (is_null($targetFile))
102
  {
103
+ return null;
104
+ // $ex = __('Target File could not be set. The source file might not be there. In case of search and replace, a filter might prevent this', "enable-media-replace");
105
+ // throw new \RuntimeException($ex);
106
  }
107
 
108
+
109
+
110
  $targetFileObj = new File($targetFile);
111
  $result = $targetFileObj->checkAndCreateFolder();
112
  if ($result === false)
113
  Log::addError('Directory creation for targetFile failed');
114
 
115
+
116
+ $this->removeCurrent(); // tries to remove the current files.
117
+
118
  /* @todo See if wp_handle_sideload / wp_handle_upload can be more securely used for this */
119
  $result_moved = move_uploaded_file($file,$targetFile);
120
 
130
  if ($this->sourceFile->getPermissions() > 0)
131
  chmod( $targetFile, $this->sourceFile->getPermissions() ); // restore permissions
132
  else {
133
+ Log::addWarning('Setting permissions failed');
134
  }
135
 
136
  // update the file attached. This is required for wp_get_attachment_url to work.
156
  wp_update_attachment_metadata( $this->post_id, $metadata );
157
  $this->target_metadata = $metadata;
158
 
159
+ /** If author is different from replacer, note this */
160
+ $author_id = get_post_meta($this->post_id, '_emr_replace_author', true);
161
+ Log::addTemp('Previous Author ID', $author_id);
162
+ if ( intval($this->source_post->post_author) !== get_current_user_id())
163
+ {
164
+ Log::addTemp("THIS AUTHOR NOT THE SAME AS THE OTHER");
165
+ update_post_meta($this->post_id, '_emr_replace_author', get_current_user_id());
166
+ }
167
+ elseif ($author_id)
168
+ {
169
+
170
+ delete_post_meta($this->post_id, '_emr_replace_author');
171
+ }
172
+
173
  if ($this->replaceMode == self::MODE_SEARCHREPLACE)
174
  {
175
  // Write new image title.
226
 
227
  do_action("enable-media-replace-upload-done", $this->target_url, $this->source_url);
228
 
229
+ return true;
230
  }
231
 
232
  protected function getNewTitle()
258
  return $this->sourceFile;
259
  }
260
 
261
+ public function setNewTargetLocation($new_rel_location)
262
+ {
263
+ $uploadDir = wp_upload_dir();
264
+ $newPath = trailingslashit($uploadDir['basedir']) . $new_rel_location;
265
+
266
+ if (! is_dir($newPath))
267
+ {
268
+ Notices::addError(__('Specificed new directory does not exist. Path must be a relative path from the upload directory and exist', 'enable-media-replace'));
269
+ return false;
270
+ }
271
+ $this->target_location = trailingslashit($newPath);
272
+ return true;
273
+ }
274
+
275
  /** Returns a full target path to place to new file. Including the file name! **/
276
  protected function getTargetFile()
277
  {
283
  elseif ($this->replaceMode == self::MODE_SEARCHREPLACE)
284
  {
285
  $path = $this->sourceFile->getFilePath();
286
+ if ($this->target_location) // Replace to another path.
287
+ {
288
+ $otherTarget = new File($this->target_location . $this->targetName);
289
+ if ($otherTarget->exists())
290
+ {
291
+ Notices::addError(__('In specificied directory there is already a file with the same name. Can\'t replace.', 'enable-media-replace'));
292
+ return null;
293
+ }
294
+ $path = $this->target_location; // if all went well.
295
+ }
296
  $unique = wp_unique_filename($path, $this->targetName);
297
 
298
  $new_filename = apply_filters( 'emr_unique_filename', $unique, $path, $this->post_id );
307
  $targetFile = trailingslashit($upload_dir['path']) . wp_unique_filename($targetFile, $this->targetName);
308
  }
309
  else {
310
+ $err = __('EMR could not establish a proper destination for replacement', 'enable-media-replace');
311
+ Notices::addError($err);
312
  Log::addError($err);
313
+ // throw new \RuntimeException($err);
314
+ // exit($err); // fallback
315
+ return null;
316
  }
317
  }
318
 
classes/uihelper.php CHANGED
@@ -348,4 +348,14 @@ class UIHelper
348
  return $sizes;
349
  }
350
 
 
 
 
 
 
 
 
 
 
 
351
  } // class
348
  return $sizes;
349
  }
350
 
351
+ /** For Location Dir replacement. Get the Subdir that is in use now. */
352
+ public function getRelPathNow()
353
+ {
354
+ $uploadDir = wp_upload_dir();
355
+ if (isset($uploadDir['subdir']))
356
+ return ltrim($uploadDir['subdir'], '/');
357
+ else
358
+ return false;
359
+ }
360
+
361
  } // class
css/admin.css CHANGED
@@ -773,6 +773,39 @@
773
  margin: 0 0 15px 0; }
774
  .emr_upload_form .image_chooser.wrapper {
775
  min-height: 350px; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
776
  .emr_upload_form .image_chooser.wrapper .image_previews {
777
  margin: 15px 0; }
778
  .emr_upload_form .image_chooser.wrapper .image_previews .image_placeholder {
@@ -886,6 +919,12 @@
886
  font-size: 20px;
887
  vertical-align: top;
888
  margin-right: 4px; }
 
 
 
 
 
 
889
  .emr_upload_form .form_controls.wrapper {
890
  clear: both;
891
  margin: 8px 0 15px 0;
@@ -894,7 +933,9 @@
894
  .emr_upload_form .form_controls.wrapper .button {
895
  padding-left: 20px;
896
  padding-right: 20px; }
897
- .emr_upload_form .shortpixel-notice {
 
 
898
  background: #fff;
899
  width: 250px;
900
  min-height: 270px;
@@ -903,27 +944,27 @@
903
  margin-bottom: 25px;
904
  float: right;
905
  clear: both; }
906
- .emr_upload_form .shortpixel-notice h3 {
907
  line-height: 1.3em; }
908
- .emr_upload_form .shortpixel-notice.site-speed {
909
  background-color: #dcfdff; }
910
- .emr_upload_form .shortpixel-notice.site-speed .img-wrapper {
911
  text-align: center;
912
  margin: 0 0 25px 0; }
913
- .emr_upload_form .shortpixel-notice.site-speed .img-wrapper img {
914
  max-width: 140px;
915
  max-height: 140px;
916
  margin: 0; }
917
- .emr_upload_form .shortpixel-notice.site-speed h3 {
918
  color: #00d0e5;
919
  font-size: 20px;
920
  text-align: center;
921
  margin: 0;
922
  line-height: 1.3em; }
923
- .emr_upload_form .shortpixel-notice.site-speed .button-wrapper {
924
  text-align: center;
925
  margin-top: 35px; }
926
- .emr_upload_form .shortpixel-notice.site-speed .button-wrapper a {
927
  background-color: #ff0000;
928
  color: #fff;
929
  display: inline-block;
@@ -931,7 +972,7 @@
931
  text-decoration: none;
932
  font-weight: 700;
933
  font-size: 20px; }
934
- .emr_upload_form .shortpixel-notice.site-speed .red {
935
  color: #ff0000; }
936
  @media (max-width: 1200px) {
937
  .emr_upload_form .image_previews {
773
  margin: 0 0 15px 0; }
774
  .emr_upload_form .image_chooser.wrapper {
775
  min-height: 350px; }
776
+ .emr_upload_form .image_chooser.wrapper .emr_drop_area {
777
+ border: 4px dashed #b4b9be;
778
+ max-width: 600px;
779
+ padding: 28px 14px;
780
+ text-align: center;
781
+ position: relative; }
782
+ .emr_upload_form .image_chooser.wrapper .emr_drop_area h1 {
783
+ display: none; }
784
+ .emr_upload_form .image_chooser.wrapper .emr_drop_area .drop-wrapper {
785
+ margin: 0 auto; }
786
+ .emr_upload_form .image_chooser.wrapper .emr_drop_area.drop_breakout {
787
+ position: fixed;
788
+ left: 0;
789
+ right: 0;
790
+ bottom: 0;
791
+ top: 0;
792
+ max-width: none;
793
+ border-color: #83b4d8;
794
+ border-width: 10px;
795
+ z-index: 999999;
796
+ background-color: rgba(68, 68, 68, 0.7); }
797
+ .emr_upload_form .image_chooser.wrapper .emr_drop_area.drop_breakout h1 {
798
+ color: #fff;
799
+ position: absolute;
800
+ font-size: 50px;
801
+ line-height: 50px;
802
+ margin-top: -25px;
803
+ top: 50%;
804
+ width: 100%;
805
+ text-align: center;
806
+ display: block; }
807
+ .emr_upload_form .image_chooser.wrapper .emr_drop_area.drop_breakout .drop-wrapper {
808
+ display: none; }
809
  .emr_upload_form .image_chooser.wrapper .image_previews {
810
  margin: 15px 0; }
811
  .emr_upload_form .image_chooser.wrapper .image_previews .image_placeholder {
919
  font-size: 20px;
920
  vertical-align: top;
921
  margin-right: 4px; }
922
+ .emr_upload_form .options.wrapper .location_option {
923
+ display: none;
924
+ margin-top: 12px; }
925
+ .emr_upload_form .options.wrapper .location_option label {
926
+ vertical-align: baseline;
927
+ margin-right: 8px; }
928
  .emr_upload_form .form_controls.wrapper {
929
  clear: both;
930
  margin: 8px 0 15px 0;
933
  .emr_upload_form .form_controls.wrapper .button {
934
  padding-left: 20px;
935
  padding-right: 20px; }
936
+ .emr_upload_form .shortpixel.notice {
937
+ padding: 12px; }
938
+ .emr_upload_form .shortpixel-offer {
939
  background: #fff;
940
  width: 250px;
941
  min-height: 270px;
944
  margin-bottom: 25px;
945
  float: right;
946
  clear: both; }
947
+ .emr_upload_form .shortpixel-offer h3 {
948
  line-height: 1.3em; }
949
+ .emr_upload_form .shortpixel-offer.site-speed {
950
  background-color: #dcfdff; }
951
+ .emr_upload_form .shortpixel-offer.site-speed .img-wrapper {
952
  text-align: center;
953
  margin: 0 0 25px 0; }
954
+ .emr_upload_form .shortpixel-offer.site-speed .img-wrapper img {
955
  max-width: 140px;
956
  max-height: 140px;
957
  margin: 0; }
958
+ .emr_upload_form .shortpixel-offer.site-speed h3 {
959
  color: #00d0e5;
960
  font-size: 20px;
961
  text-align: center;
962
  margin: 0;
963
  line-height: 1.3em; }
964
+ .emr_upload_form .shortpixel-offer.site-speed .button-wrapper {
965
  text-align: center;
966
  margin-top: 35px; }
967
+ .emr_upload_form .shortpixel-offer.site-speed .button-wrapper a {
968
  background-color: #ff0000;
969
  color: #fff;
970
  display: inline-block;
972
  text-decoration: none;
973
  font-weight: 700;
974
  font-size: 20px; }
975
+ .emr_upload_form .shortpixel-offer.site-speed .red {
976
  color: #ff0000; }
977
  @media (max-width: 1200px) {
978
  .emr_upload_form .image_previews {
enable-media-replace.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: Enable Media Replace
4
  Plugin URI: https://wordpress.org/plugins/enable-media-replace/
5
  Description: Enable replacing media files by uploading a new file in the "Edit Media" section of the WordPress Media Library.
6
- Version: 3.3.12
7
  Author: ShortPixel
8
  Author URI: https://shortpixel.com
9
  Text Domain: enable-media-replace
@@ -25,7 +25,8 @@ http://www.gnu.org/licenses/gpl.html
25
  */
26
 
27
  namespace EnableMediaReplace;
28
- define('EMR_VERSION', '3.3.12');
 
29
 
30
  if ( ! defined( 'ABSPATH' ) ) {
31
  exit; // Exit if accessed directly.
3
  Plugin Name: Enable Media Replace
4
  Plugin URI: https://wordpress.org/plugins/enable-media-replace/
5
  Description: Enable replacing media files by uploading a new file in the "Edit Media" section of the WordPress Media Library.
6
+ Version: 3.4.0
7
  Author: ShortPixel
8
  Author URI: https://shortpixel.com
9
  Text Domain: enable-media-replace
25
  */
26
 
27
  namespace EnableMediaReplace;
28
+
29
+ define('EMR_VERSION', '3.4.0');
30
 
31
  if ( ! defined( 'ABSPATH' ) ) {
32
  exit; // Exit if accessed directly.
js/emr_admin.js CHANGED
@@ -9,8 +9,11 @@
9
 
10
  var is_debug = false;
11
 
 
 
12
  this.init = function()
13
  {
 
14
  if ( emr_options.is_debug)
15
  {
16
  this.is_debug = true;
@@ -18,7 +21,14 @@
18
  }
19
 
20
  $('input[name="timestamp_replace"]').on('change', $.proxy(this.checkCustomDate, this));
 
21
  $('input[name="userfile"]').on('change', $.proxy(this.handleImage, this));
 
 
 
 
 
 
22
  this.checkCustomDate();
23
  this.loadDatePicker();
24
 
@@ -34,8 +44,9 @@
34
  }
35
 
36
  this.updateTextLayer(source, false);
 
37
 
38
- },
39
  this.loadDatePicker = function()
40
  {
41
  $('#emr_datepicker').datepicker({
@@ -156,17 +167,32 @@
156
  if (! is_empty && target_type != source_type)
157
  {
158
  this.debug(target_type + ' not ' + source_type);
159
- this.warningFileType();
 
 
160
  }
161
 
162
  if (! is_empty && emr_options.allowed_mime.indexOf(target_type) == -1)
163
  {
164
  this.debug(target_type + ' not ' + ' in allowed types ');
165
- this.warningMimeType();
 
 
 
166
  }
167
  // this.debug(emr_options.allowed_mime);
168
 
169
- },
 
 
 
 
 
 
 
 
 
 
170
  // replace the text, check if text is there ( or hide ), and fix the layout.
171
  this.updateTextLayer = function (preview, newtext)
172
  {
@@ -236,6 +262,51 @@
236
  {
237
  console.debug(message);
238
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
239
  } // emrIf
240
 
241
  jQuery(document).ready(function($)
9
 
10
  var is_debug = false;
11
 
12
+ var is_dragging = false;
13
+
14
  this.init = function()
15
  {
16
+
17
  if ( emr_options.is_debug)
18
  {
19
  this.is_debug = true;
21
  }
22
 
23
  $('input[name="timestamp_replace"]').on('change', $.proxy(this.checkCustomDate, this));
24
+ $('input[name="replace_type"]').on('change', $.proxy(this.showReplaceOptions, this));
25
  $('input[name="userfile"]').on('change', $.proxy(this.handleImage, this));
26
+
27
+ // DragDrop
28
+ $('.wrap.emr_upload_form').on('dragover', $.proxy(this.dragOverArea, this));
29
+ $('.wrap.emr_upload_form').on('dragleave', $.proxy(this.dragOutArea, this));
30
+ $('.emr_drop_area').on('drop', $.proxy(this.fileDrop, this));
31
+
32
  this.checkCustomDate();
33
  this.loadDatePicker();
34
 
44
  }
45
 
46
  this.updateTextLayer(source, false);
47
+ this.showReplaceOptions();
48
 
49
+ }
50
  this.loadDatePicker = function()
51
  {
52
  $('#emr_datepicker').datepicker({
167
  if (! is_empty && target_type != source_type)
168
  {
169
  this.debug(target_type + ' not ' + source_type);
170
+ var falsePositive = this.checkFalsePositiveType(source_type, target_type);
171
+ if (! falsePositive)
172
+ this.warningFileType();
173
  }
174
 
175
  if (! is_empty && emr_options.allowed_mime.indexOf(target_type) == -1)
176
  {
177
  this.debug(target_type + ' not ' + ' in allowed types ');
178
+ var falsePositive = this.checkFalsePositiveType(source_type, target_type);
179
+
180
+ if (! falsePositive)
181
+ this.warningMimeType();
182
  }
183
  // this.debug(emr_options.allowed_mime);
184
 
185
+ }
186
+ this.checkFalsePositiveType = function(source_type, target_type)
187
+ {
188
+ // windows (sigh) reports application/zip as application/x-zip-compressed. Or something else, why not.
189
+ if (source_type.indexOf('zip') >= 0 && target_type.indexOf('zip') >= 0)
190
+ {
191
+ this.debug('Finding ' + source_type + ' ' + target_type + ' close enough, false positive');
192
+ return true;
193
+ }
194
+ return false;
195
+ }
196
  // replace the text, check if text is there ( or hide ), and fix the layout.
197
  this.updateTextLayer = function (preview, newtext)
198
  {
262
  {
263
  console.debug(message);
264
  }
265
+ this.showReplaceOptions = function(e)
266
+ {
267
+ $('section.options .location_option').hide();
268
+ var replace_option = $('input[name="replace_type"]:checked').val();
269
+ if (replace_option == 'replace_and_search')
270
+ {
271
+ $('section.options .location_option').show();
272
+ }
273
+
274
+ }
275
+ this.dragOverArea = function(e)
276
+ {
277
+ e.preventDefault();
278
+ e.stopPropagation();
279
+
280
+ if ( this.is_dragging)
281
+ return;
282
+
283
+ //this.debug('dragover');
284
+ //$('.emr_drop_area').css('border-color', '#83b4d8');
285
+ $('.emr_drop_area').addClass('drop_breakout');
286
+ this.is_dragging = true;
287
+ }
288
+ this.dragOutArea = function(e)
289
+ {
290
+ e.preventDefault();
291
+ e.stopPropagation();
292
+ // this.debug('dragout');
293
+ //$('.emr_drop_area').css('border-color', '#b4b9be');
294
+ $('.emr_drop_area').removeClass('drop_breakout');
295
+ this.is_dragging = false;
296
+ }
297
+ this.fileDrop = function (e)
298
+ {
299
+ var ev = e.originalEvent;
300
+ this.dragOutArea(e);
301
+ ev.preventDefault();
302
+ e.preventDefault();
303
+
304
+ if (ev.dataTransfer.items) {
305
+ // Use DataTransferItemList interface to access the file(s)
306
+ document.getElementById('userfile').files = ev.dataTransfer.files;
307
+ $('input[name="userfile"]').trigger('change');
308
+ }
309
+ }
310
  } // emrIf
311
 
312
  jQuery(document).ready(function($)
notice.php DELETED
@@ -1,25 +0,0 @@
1
- <div class='notice' id='emr-news' style="padding-top: 7px">
2
- <div style="float:<?php echo (is_rtl()) ? 'left' : 'right' ?>;"><a href="javascript:emrDismissNews()" class="button" style="margin-top:10px;"><?php _e('Dismiss', 'enable-media-replace');?></a></div>
3
- <a href="https://shortpixel.com/wp/af/VKG6LYN28044" target="_blank" style="float: <?php echo (is_rtl()) ? 'right' : 'left' ?>;margin-<?php echo (is_rtl()) ? 'left' : 'right' ?>: 10px;">
4
- <img src="<?php echo plugins_url('img/sp.png', __FILE__ ); ?>" class="emr-sp"/>
5
- </a>
6
- <h3 style="margin:10px;"><?php echo esc_html__('Enable Media Replace is now compatible with ShortPixel!','enable-media-replace');?></h3>
7
- <p style="margin-bottom:0px;">
8
- <?php _e( '<a href="https://shortpixel.com/wp/af/VKG6LYN28044" target="_blank">ShortPixel</a> is an image optimization plugin and if you have it activated, upon replacing an image in Enable Media Replace, the image will be also automatically optimized.', 'enable-media-replace' ); ?>
9
- </p>
10
- <p style="text-align: <?php echo (is_rtl()) ? 'left' : 'right' ?>;margin-top: 0;">
11
- <a href="https://shortpixel.com/wp/af/VKG6LYN28044" target="_blank">&gt;&gt; <?php _e( 'More info', 'enable-media-replace' ); ?></a>
12
- </p>
13
- </div>
14
- <script>
15
- function emrDismissNews() {
16
- jQuery("#emr-news").hide();
17
- var data = { action : 'emr_dismiss_notices'};
18
- jQuery.get('<?php echo admin_url('admin-ajax.php'); ?>', data, function(response) {
19
- data = JSON.parse(response);
20
- if(data["Status"] == 0) {
21
- console.log("dismissed");
22
- }
23
- });
24
- }
25
- </script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
popup.php DELETED
@@ -1,156 +0,0 @@
1
- <?php
2
- /**
3
- * Uploadscreen for selecting and uploading new media file
4
- *
5
- * @author Måns Jonasson <http://www.mansjonasson.se>
6
- * @copyright Måns Jonasson 13 sep 2010
7
- * @version $Revision: 2303 $ | $Date: 2010-09-13 11:12:35 +0200 (ma, 13 sep 2010) $
8
- * @package wordpress
9
- * @subpackage enable-media-replace
10
- *
11
- */
12
-
13
- if ( ! defined( 'ABSPATH' ) )
14
- exit; // Exit if accessed directly.
15
-
16
- if (!current_user_can('upload_files'))
17
- wp_die( esc_html__('You do not have permission to upload files.', 'enable-media-replace') );
18
-
19
- global $wpdb;
20
-
21
- $table_name = $wpdb->prefix . "posts";
22
-
23
- $sql = "SELECT guid, post_mime_type FROM $table_name WHERE ID = " . (int) $_GET["attachment_id"];
24
-
25
- list($current_filename, $current_filetype) = $wpdb->get_row($sql, ARRAY_N);
26
-
27
- $current_fullpath = $current_filename;
28
- $current_filename = substr($current_filename, (strrpos($current_filename, "/") + 1));
29
-
30
-
31
- ?>
32
- <style>
33
- .emr-plugin-button.emr-updating:before {
34
- font: 400 20px/1 dashicons;
35
- display: inline-block;
36
- content: "\f463";
37
- -webkit-animation: rotation 2s infinite linear;
38
- animation: rotation 2s infinite linear;
39
- margin: 3px 5px 0 -2px;
40
- vertical-align: top
41
- }
42
- </style>
43
- <div class="wrap">
44
- <h1><?php echo esc_html__("Replace Media Upload", "enable-media-replace"); ?></h1>
45
-
46
- <?php
47
- $url = admin_url( "upload.php?page=enable-media-replace/enable-media-replace.php&noheader=true&action=media_replace_upload&attachment_id=" . (int) $_GET["attachment_id"]);
48
- $action = "media_replace_upload";
49
- $formurl = wp_nonce_url( $url, $action );
50
- if (FORCE_SSL_ADMIN) {
51
- $formurl = str_replace("http:", "https:", $formurl);
52
- }
53
- ?>
54
-
55
- <form enctype="multipart/form-data" method="post" action="<?php echo $formurl; ?>">
56
- <?php
57
- #wp_nonce_field('enable-media-replace');
58
- $plugins = get_plugins();
59
- $spInstalled = isset($plugins['shortpixel-image-optimiser/wp-shortpixel.php']);
60
- $spActive = is_plugin_active('shortpixel-image-optimiser/wp-shortpixel.php');
61
- ?>
62
- <input type="hidden" name="ID" value="<?php echo (int) $_GET["attachment_id"]; ?>" />
63
- <div id="message" class="updated notice notice-success is-dismissible"><p><?php printf( esc_html__('NOTE: You are about to replace the media file "%s". There is no undo. Think about it!', "enable-media-replace"), $current_filename ); ?></p></div>
64
-
65
- <?php if(!$spInstalled) {?>
66
- <div style="background: #fff;width: 250px;min-height: 270px;border: 1px solid #ccc;float: <?php echo (is_rtl()) ? 'left' : 'right' ?>;padding: 15px;margin: 0 0 10px;">
67
- <h3 class="" style="margin-top: 0;text-align: center;">
68
- <a href="https://shortpixel.com/wp/af/VKG6LYN28044" target="_blank">
69
- <?php echo esc_html__("Optimize your images with ShortPixel, get +50% credits!", "enable-media-replace"); ?>
70
- </a>
71
- </h3>
72
- <div class="" style="text-align: center;">
73
- <a href="https://shortpixel.com/wp/af/VKG6LYN28044" target="_blank">
74
- <img src="https://optimizingmattersblog.files.wordpress.com/2016/10/shortpixel.png">
75
- </a>
76
- </div>
77
- <div class="" style="margin-bottom: 10px;">
78
- <?php echo esc_html__("Get more Google love by compressing your site's images! Check out how much ShortPixel can save your site and get +50% credits when signing up as an Enable Media Replace user! Forever!", "enable-media-replace"); ?>
79
- </div>
80
- <div class=""><div style="text-align: <?php echo (is_rtl()) ? 'left' : 'right' ?>;">
81
- <a class="button button-primary" id="shortpixel-image-optimiser-info" href="https://shortpixel.com/wp/af/VKG6LYN28044" target="_blank">
82
- <?php echo esc_html__("More info", "enable-media-replace"); ?></p>
83
- </a>
84
- </div>
85
- </div>
86
- </div>
87
- <?php } ?>
88
-
89
- <p><?php echo esc_html__("Choose a file to upload from your computer", "enable-media-replace"); ?></p>
90
-
91
- <input type="file" name="userfile" id="userfile" onchange="imageHandle(event);" />
92
- <div>
93
- <img src="<?php echo $current_fullpath ?>" width="150px" height="150px" style="object-fit: cover"/>
94
- <img id="previewImage" src="https://via.placeholder.com/150x150" width="150px" height="150px"/>
95
- </div>
96
-
97
- <?php do_action( 'emr_before_replace_type_options' ); ?>
98
-
99
- <?php $s3pluginExist = class_exists('S3_Uploads'); ?>
100
- <?php if ( apply_filters( 'emr_display_replace_type_options', true ) ) : ?>
101
- <?php if ( ! $s3pluginExist) : ?>
102
- <p><?php echo esc_html__("Select media replacement type:", "enable-media-replace"); ?></p>
103
-
104
- <label for="replace_type_1"><input CHECKED id="replace_type_1" type="radio" name="replace_type" value="replace"> <?php echo esc_html__("Just replace the file", "enable-media-replace"); ?></label>
105
- <p class="howto"><?php printf( esc_html__("Note: This option requires you to upload a file of the same type (%s) as the one you are replacing. The name of the attachment will stay the same (%s) no matter what the file you upload is called.", "enable-media-replace"), $current_filetype, $current_filename ); ?></p>
106
-
107
- <?php endif; ?>
108
- <?php if ( apply_filters( 'emr_enable_replace_and_search', true ) ) : ?>
109
- <label for="replace_type_2"><input <?php echo $s3pluginExist ? 'CHECKED' : '' ?> id="replace_type_2" type="radio" name="replace_type" value="replace_and_search"> <?php echo __("Replace the file, use new file name and update all links", "enable-media-replace"); ?></label>
110
- <p class="howto"><?php printf( esc_html__("Note: If you check this option, the name and type of the file you are about to upload will replace the old file. All links pointing to the current file (%s) will be updated to point to the new file name.", "enable-media-replace"), $current_filename ); ?></p>
111
- <p class="howto"><?php echo esc_html__("Please note that if you upload a new image, only embeds/links of the original size image will be replaced in your posts.", "enable-media-replace"); ?></p>
112
- <?php endif; ?>
113
- <?php else : ?>
114
- <?php if ( ! $s3pluginExist) : ?>
115
- <input type="hidden" name="replace_type" value="replace" />
116
- <?php else : ?>
117
- <input type="hidden" name="replace_type" value="replace_and_search" />
118
- <?php endif; ?>
119
- <?php endif; ?>
120
- <input id="submit" type="submit" class="button button-primary" disabled="disabled" value="<?php echo esc_attr__("Upload", "enable-media-replace"); ?>" />
121
- <a href="#" class="button" onclick="history.back();"><?php echo esc_html__("Cancel", "enable-media-replace"); ?></a>
122
- </form>
123
- </div>
124
- <script>
125
- function imageHandle(event) {
126
- var file = document.getElementById("userfile");
127
- var submit = document.getElementById("submit");
128
- var preview = document.getElementById("previewImage");
129
-
130
- appendPreview(file, preview, event);
131
- enableSubmitButton(file, submit);
132
- }
133
-
134
- function appendPreview(fileSource, preview, event) {
135
- if (fileSource.value) {
136
- var file = fileSource.files[0];
137
- if (file.type.match("image/*")) {
138
- preview.setAttribute("src", window.URL.createObjectURL(file));
139
- preview.setAttribute("style", "object-fit: cover");
140
- } else {
141
- preview.setAttribute("src", "https://dummyimage.com/150x150/ccc/969696.gif&text=File");
142
- preview.removeAttribute("style");
143
- }
144
- } else {
145
- preview.setAttribute("src", "https://via.placeholder.com/150x150");
146
- }
147
- }
148
- function enableSubmitButton(file, submit)
149
- {
150
- if (file.value) {
151
- submit.removeAttribute("disabled");
152
- } else {
153
- submit.setAttribute("disabled", true);
154
- }
155
- }
156
- </script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
readme.txt CHANGED
@@ -3,9 +3,9 @@ Contributors: ShortPixel
3
  Donate link: https://www.paypal.me/resizeImage
4
  Tags: replace, attachment, media, files, replace image, replace jpg, change media, replace media, image, file
5
  Requires at least: 4.9.7
6
- Tested up to: 5.4
7
  Requires PHP: 5.6
8
- Stable tag: 3.3.12
9
 
10
  Easily replace any attached image/file by simply uploading a new file in the Media Library edit view - a real time saver!
11
 
@@ -47,6 +47,15 @@ If you want more control over the format used to display the time, you can use t
47
 
48
  == Changelog ==
49
 
 
 
 
 
 
 
 
 
 
50
  = 3.3.12 =
51
 
52
  Release date: 27th April 2020
3
  Donate link: https://www.paypal.me/resizeImage
4
  Tags: replace, attachment, media, files, replace image, replace jpg, change media, replace media, image, file
5
  Requires at least: 4.9.7
6
+ Tested up to: 5.4.1
7
  Requires PHP: 5.6
8
+ Stable tag: 3.4.0
9
 
10
  Easily replace any attached image/file by simply uploading a new file in the Media Library edit view - a real time saver!
11
 
47
 
48
  == Changelog ==
49
 
50
+ = 3.4.0 =
51
+
52
+ Release date: June 9th 2020
53
+ * New - In edit media screen EMR notes user who replaced file if this was not uploader;
54
+ * New - Added Drag and Drop area for files;
55
+ * New - When replacing with new file name, now also possible to update upload path;
56
+ * Fix - Various minor CSS tweaks and fixes;
57
+ * Update of Underlying libraries
58
+
59
  = 3.3.12 =
60
 
61
  Release date: 27th April 2020
scss/admin.scss CHANGED
@@ -33,6 +33,46 @@
33
  .image_chooser.wrapper
34
  {
35
  min-height: 350px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
  .image_previews
37
  {
38
  margin: 15px 0;
@@ -218,6 +258,16 @@
218
  }
219
  }
220
  } // custom_date
 
 
 
 
 
 
 
 
 
 
221
  }
222
 
223
  .form_controls.wrapper
@@ -233,7 +283,11 @@
233
  }
234
  }
235
 
236
- .shortpixel-notice
 
 
 
 
237
  {
238
  background: #fff;
239
  width: 250px;
33
  .image_chooser.wrapper
34
  {
35
  min-height: 350px;
36
+
37
+ .emr_drop_area
38
+ {
39
+ border: 4px dashed #b4b9be;
40
+ max-width: 600px;
41
+ padding: 28px 14px;
42
+ text-align: center;
43
+ position: relative;
44
+ h1 { display: none; }
45
+ .drop-wrapper
46
+ {
47
+ margin: 0 auto;
48
+
49
+ }
50
+ &.drop_breakout
51
+ {
52
+ position: fixed;
53
+ left: 0;
54
+ right:0;
55
+ bottom: 0;
56
+ top: 0;
57
+ max-width: none;
58
+ border-color: #83b4d8;
59
+ border-width: 10px;
60
+ z-index: 999999;
61
+ background-color: rgba(#444, 0.7);
62
+ h1 {
63
+ color: #fff;
64
+ position: absolute;
65
+ font-size: 50px;
66
+ line-height: 50px;
67
+ margin-top: -25px;
68
+ top: 50%;
69
+ width: 100%;
70
+ text-align: center;
71
+ display: block;
72
+ }
73
+ .drop-wrapper { display: none; }
74
+ }
75
+ }
76
  .image_previews
77
  {
78
  margin: 15px 0;
258
  }
259
  }
260
  } // custom_date
261
+ .location_option
262
+ {
263
+ display: none;
264
+ margin-top: 12px;
265
+ label
266
+ {
267
+ vertical-align: baseline;
268
+ margin-right: 8px;
269
+ }
270
+ }
271
  }
272
 
273
  .form_controls.wrapper
283
  }
284
  }
285
 
286
+ .shortpixel.notice
287
+ {
288
+ padding: 12px;
289
+ }
290
+ .shortpixel-offer
291
  {
292
  background: #fff;
293
  width: 250px;
upload.php DELETED
@@ -1,412 +0,0 @@
1
- <?php
2
- if ( ! defined( 'ABSPATH' ) )
3
- exit; // Exit if accessed directly.
4
-
5
- if (!current_user_can('upload_files'))
6
- wp_die( esc_html__('You do not have permission to upload files.', 'enable-media-replace') );
7
-
8
- // Define DB table names
9
- global $wpdb;
10
- $table_name = $wpdb->prefix . "posts";
11
- $postmeta_table_name = $wpdb->prefix . "postmeta";
12
-
13
- require_once('thumbnail_updater.php');
14
-
15
- /**
16
- * Delete a media file and its thumbnails.
17
- *
18
- * @param string $current_file
19
- * @param array|null $metadta
20
- */
21
- function emr_delete_current_files( $current_file, $metadta = null ) {
22
- // Delete old file
23
-
24
- // Find path of current file
25
- $current_path = substr($current_file, 0, (strrpos($current_file, "/")));
26
-
27
- // Check if old file exists first
28
- if (file_exists($current_file)) {
29
- // Now check for correct file permissions for old file
30
- clearstatcache();
31
- if (is_writable($current_file)) {
32
- // Everything OK; delete the file
33
- unlink($current_file);
34
- }
35
- else {
36
- // File exists, but has wrong permissions. Let the user know.
37
- printf( esc_html__('The file %1$s can not be deleted by the web server, most likely because the permissions on the file are wrong.', "enable-media-replace"), $current_file);
38
- exit;
39
- }
40
- }
41
-
42
- // Delete old resized versions if this was an image
43
- $suffix = substr($current_file, (strlen($current_file)-4));
44
- $prefix = substr($current_file, 0, (strlen($current_file)-4));
45
-
46
- if (strtolower($suffix) === ".pdf") {
47
- $prefix .= "-pdf";
48
- $suffix = ".jpg";
49
- }
50
-
51
- $imgAr = array(".png", ".gif", ".jpg");
52
- if (in_array($suffix, $imgAr)) {
53
- // It's a png/gif/jpg based on file name
54
- // Get thumbnail filenames from metadata
55
- if ( empty( $metadata ) ) {
56
- $metadata = wp_get_attachment_metadata( $_POST["ID"] );
57
- }
58
-
59
- if (is_array($metadata)) { // Added fix for error messages when there is no metadata (but WHY would there not be? I don't know…)
60
- foreach($metadata["sizes"] AS $thissize) {
61
- // Get all filenames and do an unlink() on each one;
62
- $thisfile = $thissize["file"];
63
- // Create array with all old sizes for replacing in posts later
64
- $oldfilesAr[] = $thisfile;
65
- // Look for files and delete them
66
- if (strlen($thisfile)) {
67
- $thisfile = $current_path . "/" . $thissize["file"];
68
- if (file_exists($thisfile)) {
69
- unlink($thisfile);
70
- }
71
- }
72
- }
73
- }
74
- // Old (brutal) method, left here for now
75
- //$mask = $prefix . "-*x*" . $suffix;
76
- //array_map( "unlink", glob( $mask ) );
77
- }
78
- }
79
-
80
- /**
81
- * Maybe remove query string from URL.
82
- *
83
- * @param string $url
84
- *
85
- * @return string
86
- */
87
- function emr_maybe_remove_query_string( $url ) {
88
- $parts = explode( '?', $url );
89
-
90
- return reset( $parts );
91
- }
92
-
93
- /**
94
- * Remove scheme from URL.
95
- *
96
- * @param string $url
97
- *
98
- * @return string
99
- */
100
- function emr_remove_scheme( $url ) {
101
- return preg_replace( '/^(?:http|https):/', '', $url );
102
- }
103
-
104
- /**
105
- * Remove size from filename (image[-100x100].jpeg).
106
- *
107
- * @param string $url
108
- * @param bool $remove_extension
109
- *
110
- * @return string
111
- */
112
- function emr_remove_size_from_filename( $url, $remove_extension = false ) {
113
- $url = preg_replace( '/^(\S+)-[0-9]{1,4}x[0-9]{1,4}(\.[a-zA-Z0-9\.]{2,})?/', '$1$2', $url );
114
-
115
- if ( $remove_extension ) {
116
- $ext = pathinfo( $url, PATHINFO_EXTENSION );
117
- $url = str_replace( ".$ext", '', $url );
118
- }
119
-
120
- return $url;
121
- }
122
-
123
- /**
124
- * Strip an image URL down to bare minimum for matching.
125
- *
126
- * @param string $url
127
- *
128
- * @return string
129
- */
130
- function emr_get_match_url($url) {
131
- $url = emr_remove_scheme($url);
132
- $url = emr_maybe_remove_query_string($url);
133
- $url = emr_remove_size_from_filename($url, true);
134
- $url = emr_remove_domain_from_filename($url);
135
-
136
- return $url;
137
- }
138
-
139
-
140
- function emr_remove_domain_from_filename($url) {
141
- // Holding place for possible future function
142
- $url = str_replace(emr_remove_scheme(get_bloginfo('url')), '', $url);
143
- return $url;
144
- }
145
-
146
- /**
147
- * Build an array of search or replace URLs for given attachment GUID and its metadata.
148
- *
149
- * @param string $guid
150
- * @param array $metadata
151
- *
152
- * @return array
153
- */
154
- function emr_get_file_urls( $guid, $metadata ) {
155
- $urls = array();
156
-
157
- $guid = emr_remove_scheme( $guid );
158
- $guid= emr_remove_domain_from_filename($guid);
159
-
160
- $urls['guid'] = $guid;
161
-
162
- if ( empty( $metadata ) ) {
163
- return $urls;
164
- }
165
-
166
- $base_url = dirname( $guid );
167
-
168
- if ( ! empty( $metadata['file'] ) ) {
169
- $urls['file'] = trailingslashit( $base_url ) . wp_basename( $metadata['file'] );
170
- }
171
-
172
- if ( ! empty( $metadata['sizes'] ) ) {
173
- foreach ( $metadata['sizes'] as $key => $value ) {
174
- $urls[ $key ] = trailingslashit( $base_url ) . wp_basename( $value['file'] );
175
- }
176
- }
177
-
178
- return $urls;
179
- }
180
-
181
- /**
182
- * Ensure new search URLs cover known sizes for old attachment.
183
- * Falls back to full URL if size not covered (srcset or width/height attributes should compensate).
184
- *
185
- * @param array $old
186
- * @param array $new
187
- *
188
- * @return array
189
- */
190
- function emr_normalize_file_urls( $old, $new ) {
191
- $result = array();
192
-
193
- if ( empty( $new['guid'] ) ) {
194
- return $result;
195
- }
196
-
197
- $guid = $new['guid'];
198
-
199
- foreach ( $old as $key => $value ) {
200
- $result[ $key ] = empty( $new[ $key ] ) ? $guid : $new[ $key ];
201
- }
202
-
203
- return $result;
204
- }
205
-
206
- // Get old guid and filetype from DB
207
- $sql = "SELECT post_mime_type FROM $table_name WHERE ID = '" . (int) $_POST["ID"] . "'";
208
- list($current_filetype) = $wpdb->get_row($sql, ARRAY_N);
209
-
210
- // Massage a bunch of vars
211
- $current_guid =wp_get_attachment_url($_POST['ID']);
212
-
213
- $ID = (int) $_POST["ID"];
214
-
215
- $current_file = get_attached_file($ID, apply_filters( 'emr_unfiltered_get_attached_file', true ));
216
- $current_path = substr($current_file, 0, (strrpos($current_file, "/")));
217
- $current_file = preg_replace("|(?<!:)/{2,}|", "/", $current_file);
218
- $current_filename = wp_basename($current_file);
219
- $current_metadata = wp_get_attachment_metadata( $_POST["ID"] );
220
-
221
- $replace_type = $_POST["replace_type"];
222
- // We have two types: replace / replace_and_search
223
-
224
- if (is_uploaded_file($_FILES["userfile"]["tmp_name"])) {
225
-
226
- // New method for validating that the uploaded file is allowed, using WP:s internal wp_check_filetype_and_ext() function.
227
- $filedata = wp_check_filetype_and_ext($_FILES["userfile"]["tmp_name"], $_FILES["userfile"]["name"]);
228
-
229
- if ($filedata["ext"] == "") {
230
- echo esc_html__("File type does not meet security guidelines. Try another.", 'enable-media-replace');
231
- exit;
232
- }
233
-
234
- $thumbUpdater = new ThumbnailUpdater($ID);
235
- $thumbUpdater->setOldMetadata($current_metadata);
236
-
237
- $new_filename = $_FILES["userfile"]["name"];
238
- $new_filesize = $_FILES["userfile"]["size"];
239
- $new_filetype = $filedata["type"];
240
-
241
- // save original file permissions
242
- $original_file_perms = fileperms($current_file) & 0777;
243
-
244
- if ($replace_type == "replace") {
245
- // Drop-in replace and we don't even care if you uploaded something that is the wrong file-type.
246
- // That's your own fault, because we warned you!
247
-
248
- //call replace action to give a chance to plugins like ShortPixel to delete the metadata, backups and cleanup the cache on server
249
- do_action('wp_handle_replace', array('post_id' => $ID));
250
-
251
- emr_delete_current_files( $current_file, $current_metadata );
252
-
253
- $new_filename = wp_unique_filename( $current_path, $current_filename );
254
- $new_filename = apply_filters( 'emr_unique_filename', $current_filename, $current_path, $ID );
255
-
256
- // Move new file to old location, new name
257
- $new_file = $current_path . "/" . $current_filename;
258
- move_uploaded_file($_FILES["userfile"]["tmp_name"], $new_file);
259
-
260
- // Chmod new file to original file permissions
261
- @chmod($current_file, $original_file_perms);
262
-
263
- apply_filters( 'enable_media_replace_title', basename($new_file) ); // Thanks Jonas Lundman (http://wordpress.org/support/topic/add-filter-hook-suggestion-to)
264
-
265
- // Update database file timestamp
266
- $post_date = gmdate( 'Y-m-d H:i:s' );
267
- $sql = $wpdb->prepare(
268
- "UPDATE $table_name SET post_date = '$post_date', post_date_gmt = '$post_date' WHERE ID = %d;",
269
- $ID
270
- );
271
- $wpdb->query($sql);
272
-
273
- //call upload action to give a chance to plugins like Resize Image After Upload to handle the new image
274
- do_action('wp_handle_upload', array('file' => $current_file, 'url' => wp_get_attachment_url($ID), 'type' => $new_filetype));
275
-
276
- // Make thumb and/or update metadata
277
- $metadata = wp_generate_attachment_metadata( $ID, $current_file );
278
- wp_update_attachment_metadata( $ID, $metadata );
279
-
280
- $thumbUpdater->setNewMetadata($metadata);
281
- $thumbUpdater->updateThumbnails();
282
-
283
-
284
- // Trigger possible updates on CDN and other plugins
285
- update_attached_file( $ID, $current_file);
286
-
287
-
288
- } elseif ( 'replace_and_search' == $replace_type && apply_filters( 'emr_enable_replace_and_search', true ) ) {
289
- // Replace file, replace file name, update meta data, replace links pointing to old file name
290
-
291
- //call replace action to give a chance to plugins like ShortPixel to delete the metadata, backups and cleanup the cache on server
292
- do_action('wp_handle_replace', array('post_id' => $ID));
293
-
294
- emr_delete_current_files( $current_file, $current_metadata );
295
-
296
- // Massage new filename to adhere to WordPress standards
297
- $new_filename = wp_unique_filename( $current_path, $new_filename );
298
- $new_filename = apply_filters( 'emr_unique_filename', $new_filename, $current_path, $ID );
299
-
300
- // Move new file to old location, new name
301
- $new_file = $current_path . "/" . $new_filename;
302
- move_uploaded_file($_FILES["userfile"]["tmp_name"], $new_file);
303
-
304
- // Chmod new file to original file permissions
305
- @chmod($current_file, $original_file_perms);
306
-
307
- $new_filetitle = preg_replace('/\.[^.]+$/', '', basename($new_file));
308
- $new_filetitle = apply_filters( 'enable_media_replace_title', $new_filetitle ); // Thanks Jonas Lundman (http://wordpress.org/support/topic/add-filter-hook-suggestion-to)
309
- $new_guid = str_replace($current_filename, $new_filename, $current_guid);
310
-
311
- //call upload action to give a chance to plugins like ShortPixel to handle the new image
312
- //do_action('wp_handle_upload', array('file' => $new_file, 'url' => $new_guid, 'type' => $new_filetype));
313
-
314
- $post_date = gmdate( 'Y-m-d H:i:s' );
315
-
316
- // Update database file name
317
- $sql = $wpdb->prepare(
318
- "UPDATE $table_name SET post_title = '$new_filetitle', post_name = '$new_filetitle', guid = '$new_guid', post_mime_type = '$new_filetype', post_date = '$post_date', post_date_gmt = '$post_date' WHERE ID = %d;",
319
- $ID
320
- );
321
- $wpdb->query($sql);
322
-
323
- // Update the postmeta file name
324
-
325
- // Get old postmeta _wp_attached_file
326
- $sql = $wpdb->prepare(
327
- "SELECT meta_value FROM $postmeta_table_name WHERE meta_key = '_wp_attached_file' AND post_id = %d;",
328
- $ID
329
- );
330
-
331
- $old_meta_name = $wpdb->get_row($sql, ARRAY_A);
332
- $old_meta_name = $old_meta_name["meta_value"];
333
-
334
- // Make new postmeta _wp_attached_file
335
- $new_meta_name = str_replace($current_filename, $new_filename, $old_meta_name);
336
- $sql = $wpdb->prepare(
337
- "UPDATE $postmeta_table_name SET meta_value = '$new_meta_name' WHERE meta_key = '_wp_attached_file' AND post_id = %d;",
338
- $ID
339
- );
340
- $wpdb->query($sql);
341
-
342
- // Make thumb and/or update metadata
343
- $new_metadata = wp_generate_attachment_metadata( $ID, $new_file );
344
- wp_update_attachment_metadata( $ID, $new_metadata );
345
-
346
- // Search-and-replace filename in post database
347
- $current_base_url = emr_get_match_url( $current_guid );
348
-
349
- $sql = $wpdb->prepare(
350
- "SELECT ID, post_content FROM $table_name WHERE post_status = 'publish' AND post_content LIKE %s;",
351
- '%' . $current_base_url . '%'
352
- );
353
-
354
-
355
- $rs = $wpdb->get_results( $sql, ARRAY_A );
356
-
357
- $number_of_updates = 0;
358
-
359
-
360
- if ( ! empty( $rs ) ) {
361
- $search_urls = emr_get_file_urls( $current_guid, $current_metadata );
362
- $replace_urls = emr_get_file_urls( $new_guid, $new_metadata );
363
- $replace_urls = emr_normalize_file_urls( $search_urls, $replace_urls );
364
-
365
-
366
- foreach ( $rs AS $rows ) {
367
-
368
- $number_of_updates = $number_of_updates + 1;
369
-
370
- // replace old URLs with new URLs.
371
- $post_content = $rows["post_content"];
372
- $post_content = str_replace( $search_urls, $replace_urls, $post_content );
373
-
374
- $sql = $wpdb->prepare(
375
- "UPDATE $table_name SET post_content = %s WHERE ID = %d;",
376
- array($post_content, $rows["ID"])
377
- );
378
-
379
- $wpdb->query( $sql );
380
- }
381
- }
382
-
383
- $thumbUpdater->setNewMetadata($new_metadata);
384
- $thumbUpdater->updateThumbnails();
385
-
386
- // Trigger possible updates on CDN and other plugins
387
- update_attached_file( $ID, $new_file );
388
- }
389
-
390
- #echo "Updated: " . $number_of_updates;
391
-
392
- $returnurl = admin_url("/post.php?post={$_POST["ID"]}&action=edit&message=1");
393
-
394
- // Execute hook actions - thanks rubious for the suggestion!
395
- if (isset($new_guid)) { do_action("enable-media-replace-upload-done", $new_guid, $current_guid); }
396
-
397
- } else {
398
- //TODO Better error handling when no file is selected.
399
- //For now just go back to media management
400
- $returnurl = admin_url("upload.php");
401
- }
402
-
403
- if (FORCE_SSL_ADMIN) {
404
- $returnurl = str_replace("http:", "https:", $returnurl);
405
- }
406
-
407
- // Allow developers to override $returnurl
408
- $returnurl = apply_filters('emr_returnurl', $returnurl);
409
-
410
- //save redirection
411
- wp_redirect($returnurl);
412
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
views/popup.php CHANGED
@@ -42,6 +42,8 @@ $uiHelper->setSourceSizes($attachment_id);
42
 
43
  $emr = EnableMediaReplacePlugin::get();
44
 
 
 
45
  ?>
46
 
47
  <div class="wrap emr_upload_form">
@@ -62,8 +64,9 @@ $url = $uiHelper->getFormUrl($attachment_id);
62
  <section class='image_chooser wrapper'>
63
  <div class='section-header'> <?php _e('Choose Replacement Media', 'enable-replace-media'); ?></div>
64
 
 
 
65
  <input type="hidden" name="ID" value="<?php echo $attachment_id ?>" />
66
- <div id="message" class="updated notice notice-success is-dismissible"><p><?php printf( esc_html__('NOTE: You are about to replace the media file "%s". There is no undo. Think about it!', "enable-media-replace"), $filename ); ?></p></div>
67
 
68
  <p><?php echo esc_html__("Choose a file to upload from your computer", "enable-media-replace"); ?></p>
69
  <p><?php printf(__('Maximum file size: <strong>%s</strong>','enable-media-replace'), size_format(wp_max_upload_size() ) ) ?></p>
@@ -74,27 +77,34 @@ $url = $uiHelper->getFormUrl($attachment_id);
74
 
75
  <div class='form-warning mimetype'><p><?php printf(__('Replacement file type doesn\'t seem to be allowed by WordPress. This might cause unexpected issues')); ?></p></div>
76
 
77
- <input type="file" name="userfile" id="userfile" />
78
- <div class='image_previews'>
79
- <?php if (wp_attachment_is('image', $attachment_id) || $source_mime == 'application/pdf')
80
- {
81
- echo $uiHelper->getPreviewImage($attachment_id);
82
- echo $uiHelper->getPreviewImage(-1);
83
- }
84
- else {
85
- if (strlen($filepath) == 0) // check if image in error state.
86
- {
87
- echo $uiHelper->getPreviewError(-1);
88
- echo $uiHelper->getPreviewImage(-1);
89
- }
90
- else {
91
- echo $uiHelper->getPreviewFile($attachment_id);
92
- echo $uiHelper->getPreviewFile(-1);
93
- }
94
-
95
- }
96
- ?>
97
- </div>
 
 
 
 
 
 
 
98
 
99
  </section>
100
 
@@ -147,8 +157,8 @@ $url = $uiHelper->getFormUrl($attachment_id);
147
  ?>
148
  <p><?php _e('When replacing the media, do you want to:', 'enable-media-replace'); ?></p>
149
  <ul>
150
- <li><label><input type='radio' name='timestamp_replace' value='1' checked /><?php _e('Replace the date', 'enable-media-replace'); ?></label></li>
151
- <li><label><input type='radio' name='timestamp_replace' value='2' /><?php printf(__('Keep the date %s(%s)%s', 'enable-media-replace'), "<span class='small'>", $attachment_current_date, "</span>"); ?></label></li>
152
  <li><label><input type='radio' name='timestamp_replace' value='3' /><?php _e('Set a Custom Date', 'enable-media-replace'); ?></label></li>
153
  </ul>
154
  <div class='custom_date'>
@@ -161,7 +171,14 @@ $url = $uiHelper->getFormUrl($attachment_id);
161
  <input type="text" name="custom_minute" class='emr_minute' value="<?php echo $date->format('i'); ?>" />
162
  <input type="hidden" name="custom_date_formatted" value="<?php echo $date->format('Y-m-d'); ?>" />
163
  </div>
 
 
 
 
 
 
164
  </div>
 
165
  </section>
166
  </div>
167
  <section class='form_controls wrapper'>
@@ -180,7 +197,7 @@ $url = $uiHelper->getFormUrl($attachment_id);
180
 
181
  <section class='upsell-wrapper'>
182
  <?php if(! $spInstalled) {?>
183
- <div class='shortpixel-notice'>
184
  <h3 class="" style="margin-top: 0;text-align: center;">
185
  <a href="https://shortpixel.com/wp/af/VKG6LYN28044" target="_blank">
186
  <?php echo esc_html__("Optimize your images with ShortPixel, get +50% credits!", "enable-media-replace"); ?>
@@ -202,7 +219,7 @@ $url = $uiHelper->getFormUrl($attachment_id);
202
  </div>
203
  </div>
204
  <?php } ?>
205
- <div class='shortpixel-notice site-speed'>
206
  <p class='img-wrapper'><img src="<?php echo $emr->getPluginURL('img/shortpixel.png'); ?>" alt='ShortPixel'></p>
207
  <h3><?php printf(__('ARE YOU %s CONCERNED WITH %s YOUR %s %s SITE SPEED? %s', 'enable-media-replace'),'<br>', '<br>','<br>', '<span class="red">','</span>'); ?><br><br>
208
  <?php printf(__('ALLOW ShortPixel %s SPECIALISTS TO %s FIND THE %s SOLUTION FOR YOU.', 'enable-media-replace'), '<br>','<br>','<br>'); ?></h3>
42
 
43
  $emr = EnableMediaReplacePlugin::get();
44
 
45
+
46
+
47
  ?>
48
 
49
  <div class="wrap emr_upload_form">
64
  <section class='image_chooser wrapper'>
65
  <div class='section-header'> <?php _e('Choose Replacement Media', 'enable-replace-media'); ?></div>
66
 
67
+ <div id="message" class=""><strong><?php printf( esc_html__('NOTE: You are about to replace the media file "%s". There is no undo. Think about it!', "enable-media-replace"), $filename ); ?></strong></div>
68
+
69
  <input type="hidden" name="ID" value="<?php echo $attachment_id ?>" />
 
70
 
71
  <p><?php echo esc_html__("Choose a file to upload from your computer", "enable-media-replace"); ?></p>
72
  <p><?php printf(__('Maximum file size: <strong>%s</strong>','enable-media-replace'), size_format(wp_max_upload_size() ) ) ?></p>
77
 
78
  <div class='form-warning mimetype'><p><?php printf(__('Replacement file type doesn\'t seem to be allowed by WordPress. This might cause unexpected issues')); ?></p></div>
79
 
80
+ <div class='emr_drop_area'>
81
+ <div class='drop-wrapper'>
82
+
83
+ <p><input type="file" name="userfile" id="userfile" /></p>
84
+ <h1><?php _e('Drop File Here', 'enable-media-replace'); ?></h1>
85
+ </div>
86
+
87
+ </div>
88
+ <div class='image_previews'>
89
+ <?php if (wp_attachment_is('image', $attachment_id) || $source_mime == 'application/pdf')
90
+ {
91
+ echo $uiHelper->getPreviewImage($attachment_id);
92
+ echo $uiHelper->getPreviewImage(-1);
93
+ }
94
+ else {
95
+ if (strlen($filepath) == 0) // check if image in error state.
96
+ {
97
+ echo $uiHelper->getPreviewError(-1);
98
+ echo $uiHelper->getPreviewImage(-1);
99
+ }
100
+ else {
101
+ echo $uiHelper->getPreviewFile($attachment_id);
102
+ echo $uiHelper->getPreviewFile(-1);
103
+ }
104
+
105
+ }
106
+ ?>
107
+ </div>
108
 
109
  </section>
110
 
157
  ?>
158
  <p><?php _e('When replacing the media, do you want to:', 'enable-media-replace'); ?></p>
159
  <ul>
160
+ <li><label><input type='radio' name='timestamp_replace' value='1' /><?php _e('Replace the date', 'enable-media-replace'); ?></label></li>
161
+ <li><label><input type='radio' name='timestamp_replace' value='2' checked /><?php printf(__('Keep the date %s(%s)%s', 'enable-media-replace'), "<span class='small'>", $attachment_current_date, "</span>"); ?></label></li>
162
  <li><label><input type='radio' name='timestamp_replace' value='3' /><?php _e('Set a Custom Date', 'enable-media-replace'); ?></label></li>
163
  </ul>
164
  <div class='custom_date'>
171
  <input type="text" name="custom_minute" class='emr_minute' value="<?php echo $date->format('i'); ?>" />
172
  <input type="hidden" name="custom_date_formatted" value="<?php echo $date->format('Y-m-d'); ?>" />
173
  </div>
174
+ <?php if ($subdir = $uiHelper->getRelPathNow()): ?>
175
+ <div class='location_option'>
176
+ <label><input type="checkbox" name="new_location" value="1" /> <?php _e('Put new Upload in Updated Folder: '); ?></label>
177
+ <input type="text" name="location_dir" value="<?php echo $subdir ?>" />
178
+ </div>
179
+ <?php endif; ?>
180
  </div>
181
+
182
  </section>
183
  </div>
184
  <section class='form_controls wrapper'>
197
 
198
  <section class='upsell-wrapper'>
199
  <?php if(! $spInstalled) {?>
200
+ <div class='shortpixel-offer'>
201
  <h3 class="" style="margin-top: 0;text-align: center;">
202
  <a href="https://shortpixel.com/wp/af/VKG6LYN28044" target="_blank">
203
  <?php echo esc_html__("Optimize your images with ShortPixel, get +50% credits!", "enable-media-replace"); ?>
219
  </div>
220
  </div>
221
  <?php } ?>
222
+ <div class='shortpixel-offer site-speed'>
223
  <p class='img-wrapper'><img src="<?php echo $emr->getPluginURL('img/shortpixel.png'); ?>" alt='ShortPixel'></p>
224
  <h3><?php printf(__('ARE YOU %s CONCERNED WITH %s YOUR %s %s SITE SPEED? %s', 'enable-media-replace'),'<br>', '<br>','<br>', '<span class="red">','</span>'); ?><br><br>
225
  <?php printf(__('ALLOW ShortPixel %s SPECIALISTS TO %s FIND THE %s SOLUTION FOR YOU.', 'enable-media-replace'), '<br>','<br>','<br>'); ?></h3>
views/upload.php CHANGED
@@ -11,6 +11,7 @@ if (!current_user_can('upload_files'))
11
  wp_die( esc_html__('You do not have permission to upload files.', 'enable-media-replace') );
12
 
13
 
 
14
  /*require_once('classes/replacer.php');
15
  require_once('classes/file.php'); */
16
 
@@ -36,6 +37,9 @@ $timestamp_replace = intval($_POST['timestamp_replace']);
36
  $redirect_error = $uihelper->getFailedRedirect($post_id);
37
  $redirect_success = $uihelper->getSuccesRedirect($post_id);
38
 
 
 
 
39
  switch($timestamp_replace)
40
  {
41
  case \EnableMediaReplace\Replacer::TIME_UPDATEALL:
@@ -73,10 +77,22 @@ switch($timestamp_replace)
73
  if ($replace_type == 'replace')
74
  {
75
  $replacer->setMode(\EnableMediaReplace\Replacer::MODE_REPLACE);
 
76
  }
77
  elseif ( 'replace_and_search' == $replace_type && apply_filters( 'emr_enable_replace_and_search', true ) )
78
  {
79
  $replacer->setMode(\EnableMediaReplace\Replacer::MODE_SEARCHREPLACE);
 
 
 
 
 
 
 
 
 
 
 
80
  }
81
 
82
  $replacer->setTimeMode($timestamp_replace, $datetime);
@@ -114,17 +130,29 @@ if (is_uploaded_file($_FILES["userfile"]["tmp_name"])) {
114
  // Gather all functions that both options do.
115
  do_action('wp_handle_replace', array('post_id' => $post_id));
116
 
 
 
 
 
 
 
 
117
  try
118
  {
119
- $replacer->replaceWith($_FILES["userfile"]["tmp_name"], $new_filename);
120
  }
121
  catch(\RunTimeException $e)
122
  {
123
  Log::addError($e->getMessage());
124
- exit($e->getMessage());
125
  }
126
 
127
- $returnurl = admin_url("/post.php?post={$_POST["ID"]}&action=edit&message=1");
 
 
 
 
 
128
 
129
  // Execute hook actions - thanks rubious for the suggestion!
130
 
11
  wp_die( esc_html__('You do not have permission to upload files.', 'enable-media-replace') );
12
 
13
 
14
+
15
  /*require_once('classes/replacer.php');
16
  require_once('classes/file.php'); */
17
 
37
  $redirect_error = $uihelper->getFailedRedirect($post_id);
38
  $redirect_success = $uihelper->getSuccesRedirect($post_id);
39
 
40
+ $do_new_location = isset($_POST['new_location']) ? sanitize_text_field($_POST['new_location']) : false;
41
+ $new_location_dir = isset($_POST['location_dir']) ? sanitize_text_field($_POST['location_dir']) : null;
42
+
43
  switch($timestamp_replace)
44
  {
45
  case \EnableMediaReplace\Replacer::TIME_UPDATEALL:
77
  if ($replace_type == 'replace')
78
  {
79
  $replacer->setMode(\EnableMediaReplace\Replacer::MODE_REPLACE);
80
+ $mode = \EnableMediaReplace\Replacer::MODE_REPLACE;
81
  }
82
  elseif ( 'replace_and_search' == $replace_type && apply_filters( 'emr_enable_replace_and_search', true ) )
83
  {
84
  $replacer->setMode(\EnableMediaReplace\Replacer::MODE_SEARCHREPLACE);
85
+ $mode = \EnableMediaReplace\Replacer::MODE_SEARCHREPLACE;
86
+
87
+ if ($do_new_location && ! is_null($new_location_dir))
88
+ {
89
+ $result = $replacer->setNewTargetLocation($new_location_dir);
90
+ if (! $result)
91
+ {
92
+ wp_safe_redirect($redirect_error);
93
+ exit();
94
+ }
95
+ }
96
  }
97
 
98
  $replacer->setTimeMode($timestamp_replace, $datetime);
130
  // Gather all functions that both options do.
131
  do_action('wp_handle_replace', array('post_id' => $post_id));
132
 
133
+
134
+ /* if ($mode = \EnableMediaReplace\Replacer::MODE_SEARCHREPLACE && $do_new_location && ! is_null($new_location_dir))
135
+ {
136
+ exit($new_filename);
137
+ $newdirfile = $replacer->newTargetLocation($new_location_dir);
138
+ }
139
+ */
140
  try
141
  {
142
+ $result = $replacer->replaceWith($_FILES["userfile"]["tmp_name"], $new_filename);
143
  }
144
  catch(\RunTimeException $e)
145
  {
146
  Log::addError($e->getMessage());
147
+ // exit($e->getMessage());
148
  }
149
 
150
+ if (is_null($result))
151
+ {
152
+ wp_safe_redirect($redirect_error);
153
+ exit();
154
+ }
155
+ // $returnurl = admin_url("/post.php?post={$_POST["ID"]}&action=edit&message=1");
156
 
157
  // Execute hook actions - thanks rubious for the suggestion!
158