Enable Media Replace - Version 3.5.0

Version Description

Release date: October 29th 2020 * New: EMR now replaces across all meta tables; * New: the plugin remembers last used settings; * New: integration with the LiteSpeed cache plugin and webserver; * Tweak: manual Logging will no longer work if user is not logged as administrator; * Tweak: added post_id to enable-media-replace-upload-done action args, props to @Jan Stiegler; * Fix: fully works now with Elementor; * Fix: the issue for WP-Bakery and URL-Encoded links is now fixed; * Fix: the plugin should now work with images added through Visual Composer; * Fix: EMR now uses queries instead of WordPress functions, correctly handling slashes and JSON formats; * Fix: -scaled images generated by WordPress are now removed when replacing an image;

Download this release

Release Info

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

Code changes from version 3.4.2 to 3.5.0

build/shortpixel/autoload.php CHANGED
@@ -2,3 +2,4 @@
2
  require_once (dirname(__FILE__) . "/PackageLoader.php");
3
  $loader = new EnableMediaReplace\Build\PackageLoader();
4
  $loader->load(__DIR__);
 
2
  require_once (dirname(__FILE__) . "/PackageLoader.php");
3
  $loader = new EnableMediaReplace\Build\PackageLoader();
4
  $loader->load(__DIR__);
5
+
build/shortpixel/log/src/ShortPixelLogger.php CHANGED
@@ -138,6 +138,17 @@ namespace EnableMediaReplace\ShortPixelLogger;
138
  return;
139
  }
140
 
 
 
 
 
 
 
 
 
 
 
 
141
  // Check where to log to.
142
  if ($this->logPath === false)
143
  {
@@ -237,7 +248,7 @@ namespace EnableMediaReplace\ShortPixelLogger;
237
  $log = self::getInstance();
238
  $log->addLog($message, $level, $args);
239
  }
240
- // Alias, since it goes wrong so often.
241
  public static function addWarning($message, $args = array())
242
  {
243
  self::addWarn($message, $args);
@@ -326,6 +337,7 @@ namespace EnableMediaReplace\ShortPixelLogger;
326
  $controller = $this;
327
 
328
  $template_path = __DIR__ . '/' . $this->template . '.php';
 
329
  if (file_exists($template_path))
330
  {
331
 
138
  return;
139
  }
140
 
141
+ // Force administrator on manuals.
142
+ if ( $this->is_manual_request )
143
+ {
144
+ if (! function_exists('wp_get_current_user')) // not loaded yet
145
+ return false;
146
+
147
+ $user_is_administrator = (current_user_can('manage_options')) ? true : false;
148
+ if (! $user_is_administrator)
149
+ return false;
150
+ }
151
+
152
  // Check where to log to.
153
  if ($this->logPath === false)
154
  {
248
  $log = self::getInstance();
249
  $log->addLog($message, $level, $args);
250
  }
251
+ // Alias, since it goes wrong so often.
252
  public static function addWarning($message, $args = array())
253
  {
254
  self::addWarn($message, $args);
337
  $controller = $this;
338
 
339
  $template_path = __DIR__ . '/' . $this->template . '.php';
340
+ // var_dump( $template_path);
341
  if (file_exists($template_path))
342
  {
343
 
classes/cache.php CHANGED
@@ -1,6 +1,8 @@
1
  <?php
2
  namespace EnableMediaReplace;
3
 
 
 
4
  class emrCache
5
  {
6
  protected $has_supercache = false; // supercache seems to replace quite fine, without our help. @todo Test if this is needed
@@ -8,6 +10,7 @@ class emrCache
8
  protected $has_wpengine = false;
9
  protected $has_fastestcache = false;
10
  protected $has_siteground = false;
 
11
 
12
  public function __construct()
13
  {
@@ -35,6 +38,11 @@ class emrCache
35
  $this->has_siteground = true;
36
  }
37
 
 
 
 
 
 
38
  // @todo WpRocket?
39
  // @todo BlueHost Caching?
40
  }
@@ -78,6 +86,10 @@ class emrCache
78
  if ($this->has_fastestcache)
79
  $this->removeFastestCache();
80
 
 
 
 
 
81
  }
82
 
83
  protected function removeSuperCache()
@@ -118,4 +130,9 @@ class emrCache
118
  sg_cachepress_purge_cache();
119
  }
120
 
 
 
 
 
 
121
  }
1
  <?php
2
  namespace EnableMediaReplace;
3
 
4
+ use EnableMediaReplace\ShortPixelLogger\ShortPixelLogger as Log;
5
+
6
  class emrCache
7
  {
8
  protected $has_supercache = false; // supercache seems to replace quite fine, without our help. @todo Test if this is needed
10
  protected $has_wpengine = false;
11
  protected $has_fastestcache = false;
12
  protected $has_siteground = false;
13
+ protected $has_litespeed = false;
14
 
15
  public function __construct()
16
  {
38
  $this->has_siteground = true;
39
  }
40
 
41
+ if (defined( 'LSCWP_DIR' ))
42
+ {
43
+ $this->has_litespeed = true;
44
+ }
45
+
46
  // @todo WpRocket?
47
  // @todo BlueHost Caching?
48
  }
86
  if ($this->has_fastestcache)
87
  $this->removeFastestCache();
88
 
89
+ if ($this->has_litespeed)
90
+ $this->litespeedReset($post_id);
91
+
92
+ do_action('emr/cache/flush', $post_id);
93
  }
94
 
95
  protected function removeSuperCache()
130
  sg_cachepress_purge_cache();
131
  }
132
 
133
+ protected function litespeedReset($post_id)
134
+ {
135
+ do_action('litespeed_media_reset', $post_id);
136
+ }
137
+
138
  }
classes/emr-plugin.php CHANGED
@@ -91,7 +91,7 @@ class EnableMediaReplacePlugin
91
  load_plugin_textdomain( 'enable-media-replace', false, basename(dirname(EMR_ROOT_FILE) ) . '/languages' );
92
 
93
  // Load Submodules
94
- Log::addDebug('Plugin Init');
95
  $notices = Notices::getInstance();
96
 
97
  // Enqueue notices
91
  load_plugin_textdomain( 'enable-media-replace', false, basename(dirname(EMR_ROOT_FILE) ) . '/languages' );
92
 
93
  // Load Submodules
94
+
95
  $notices = Notices::getInstance();
96
 
97
  // Enqueue notices
classes/external/elementor.php ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace EnableMediaReplace\Externals;
3
+
4
+ class Elementor
5
+ {
6
+ private static $instance;
7
+
8
+ protected $queryKey = 'elementor';
9
+
10
+ public static function getInstance()
11
+ {
12
+ if (is_null(self::$instance))
13
+ self::$instance = new Elementor();
14
+
15
+ return self::$instance;
16
+ }
17
+
18
+ public function __construct()
19
+ {
20
+ if ($this->elementor_is_active()) // elementor is active
21
+ {
22
+ add_filter('emr/replacer/custom_replace_query', array($this, 'addElementor'), 10, 4); // custom query for elementor \ // problem
23
+ add_action('enable-media-replace-upload-done', array($this, 'removeCache') );
24
+ }
25
+ }
26
+
27
+ public function addElementor($items, $base_url, $search_urls, $replace_urls)
28
+ {
29
+ $base_url = $this->addSlash($base_url);
30
+ $el_search_urls = $search_urls; //array_map(array($this, 'addslash'), $search_urls);
31
+ $el_replace_urls = $replace_urls; //array_map(array($this, 'addslash'), $replace_urls);
32
+ $items[$this->queryKey] = array('base_url' => $base_url, 'search_urls' => $el_search_urls, 'replace_urls' => $el_replace_urls);
33
+ return $items;
34
+ }
35
+
36
+ public function addSlash($value)
37
+ {
38
+ global $wpdb;
39
+ $value= ltrim($value, '/'); // for some reason the left / isn't picked up by Mysql.
40
+ $value= str_replace('/', '\/', $value);
41
+ $value = $wpdb->esc_like(($value)); //(wp_slash) / str_replace('/', '\/', $value);
42
+
43
+ return $value;
44
+ }
45
+
46
+ protected function elementor_is_active()
47
+ {
48
+ $bool = false;
49
+
50
+ if (defined('ELEMENTOR_VERSION'))
51
+ $bool = true;
52
+
53
+ return apply_filters('emr/externals/elementor_is_active', $bool); // manual override
54
+ }
55
+
56
+ public function removeCache()
57
+ {
58
+ \Elementor\Plugin::$instance->files_manager->clear_cache();
59
+ }
60
+ }
classes/external/wpbakery.php ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace EnableMediaReplace\Externals;
3
+
4
+
5
+ // Note! This class doubles as integration for both Visual Composer *and* WP Bakery. They both need URLENCODE.
6
+ class WpBakery
7
+ {
8
+ private static $instance;
9
+
10
+ protected $queryKey = 'wpbakery';
11
+
12
+ public static function getInstance()
13
+ {
14
+ if (is_null(self::$instance))
15
+ self::$instance = new WpBakery();
16
+
17
+ return self::$instance;
18
+ }
19
+
20
+ public function __construct()
21
+ {
22
+ if ($this->bakery_is_active()) // elementor is active
23
+ {
24
+ add_filter('emr/replacer/custom_replace_query', array($this, 'addURLEncoded'), 10, 4); // custom query for elementor \ // problem
25
+ }
26
+ }
27
+
28
+ public function addUrlEncoded($items, $base_url, $search_urls, $replace_urls)
29
+ {
30
+ $base_url = $this->addEncode($base_url);
31
+ $el_search_urls = array_map(array($this, 'addEncode'), $search_urls);
32
+ $el_replace_urls = array_map(array($this, 'addEncode'), $replace_urls);
33
+ $items[$this->queryKey] = array('base_url' => $base_url, 'search_urls' => $el_search_urls, 'replace_urls' => $el_replace_urls);
34
+ return $items;
35
+ }
36
+
37
+ public function addEncode($value)
38
+ {
39
+ return urlencode($value);
40
+ }
41
+
42
+ protected function bakery_is_active()
43
+ {
44
+ $bool = false;
45
+
46
+ // did_action -> wpbakery , VCV_version -> detect Visual Composer
47
+ if (did_action('vc_plugins_loaded') || defined('VCV_VERSION'))
48
+ $bool = true;
49
+
50
+ return apply_filters('emr/externals/urlencode_is_active', $bool); // manual override
51
+ }
52
+ }
classes/externals.php CHANGED
@@ -3,6 +3,8 @@ namespace EnableMediaReplace;
3
  use EnableMediaReplace\ShortPixelLogger\ShortPixelLogger as Log;
4
  use EnableMediaReplace\Notices\NoticeController as Notices;
5
 
 
 
6
 
7
  class Externals
8
  {
@@ -11,27 +13,29 @@ class Externals
11
 
12
  protected $messages = array();
13
 
14
-
15
  public function __construct()
16
  {
 
17
  add_filter('emr_display_replace_type_options', array($this, 'get_replace_type'));
18
  add_filter('emr_enable_replace_and_search', array($this, 'get_replacesearch_type'));
19
-
20
  add_action('emr_after_replace_type_options', array($this, 'get_messages'));
21
 
22
-
23
  $this->check();
24
- }
25
 
26
- protected function check()
27
- {
28
- /*if (class_exists('FLBuilder'))
29
- {
30
- $this->replaceSearchType = false;
31
- $this->messages[] = __('Replace and Search feature is not compatible with Beaver Builder.', 'enable-media-replace');
32
- } */
33
  }
34
 
 
 
 
 
 
 
 
 
 
35
  public function get_replace_type($bool)
36
  {
37
  if ($this->replaceType === null)
@@ -54,7 +58,16 @@ class Externals
54
  {
55
  echo '<span class="nofeature-notice"><p>'. $message . '</p></span>';
56
  }
 
57
 
 
 
 
58
  }
59
 
60
- }
 
 
 
 
 
3
  use EnableMediaReplace\ShortPixelLogger\ShortPixelLogger as Log;
4
  use EnableMediaReplace\Notices\NoticeController as Notices;
5
 
6
+ use EnableMediaReplace\Externals\Elementor as Elementor;
7
+ use EnableMediaReplace\Externals\WpBakery as WpBakery;
8
 
9
  class Externals
10
  {
13
 
14
  protected $messages = array();
15
 
 
16
  public function __construct()
17
  {
18
+ // These hooks prevent loading of options when plugin conflicts arise.
19
  add_filter('emr_display_replace_type_options', array($this, 'get_replace_type'));
20
  add_filter('emr_enable_replace_and_search', array($this, 'get_replacesearch_type'));
 
21
  add_action('emr_after_replace_type_options', array($this, 'get_messages'));
22
 
 
23
  $this->check();
 
24
 
25
+ // integrations
26
+ $this->loadElementor();
27
+ $this->loadBakery(); // in case of urlencoded issues, this class should be used probably.
 
 
 
 
28
  }
29
 
30
+ protected function check() // check if any of the options should be disabled due to conflicts
31
+ {
32
+ /*if (class_exists('FLBuilder'))
33
+ {
34
+ $this->replaceSearchType = false;
35
+ $this->messages[] = __('Replace and Search feature is not compatible with Beaver Builder.', 'enable-media-replace');
36
+ } */
37
+ }
38
+
39
  public function get_replace_type($bool)
40
  {
41
  if ($this->replaceType === null)
58
  {
59
  echo '<span class="nofeature-notice"><p>'. $message . '</p></span>';
60
  }
61
+ }
62
 
63
+ public function loadElementor()
64
+ {
65
+ Elementor::getInstance();
66
  }
67
 
68
+ public function loadBakery()
69
+ {
70
+ WpBakery::getInstance();
71
+ }
72
+
73
+ } // class
classes/replacer.php CHANGED
@@ -4,6 +4,8 @@ use \EnableMediaReplace\emrFile as File;
4
  use EnableMediaReplace\ShortPixelLogger\ShortPixelLogger as Log;
5
  use EnableMediaReplace\Notices\NoticeController as Notices;
6
 
 
 
7
  class Replacer
8
  {
9
  protected $post_id;
@@ -235,7 +237,7 @@ class Replacer
235
  $cache = new emrCache();
236
  $cache->flushCache($cache_args);
237
 
238
- do_action("enable-media-replace-upload-done", $this->target_url, $this->source_url);
239
 
240
  return true;
241
  }
@@ -380,6 +382,14 @@ class Replacer
380
  $file = $this->sourceFile->getFullFilePath();
381
  $result = \wp_delete_attachment_files($this->post_id, $meta, $backup_sizes, $file );
382
 
 
 
 
 
 
 
 
 
383
  }
384
 
385
  /** Handle new dates for the replacement */
@@ -417,38 +427,27 @@ class Replacer
417
 
418
  $args = wp_parse_args($args, $defaults);
419
 
420
- global $wpdb;
421
-
422
  // Search-and-replace filename in post database
423
  // @todo Check this with scaled images.
424
- $current_base_url = parse_url($this->source_url, PHP_URL_PATH);// emr_get_match_url( $this->source_url);
425
- $current_base_url = str_replace('.' . pathinfo($current_base_url, PATHINFO_EXTENSION), '', $current_base_url);
426
 
427
 
428
  /** Fail-safe if base_url is a whole directory, don't go search/replace */
429
- if (is_dir($current_base_url))
430
  {
431
- Log::addError('Search Replace tried to replace to directory - ' . $current_base_url);
432
  Notices::addError(__('Fail Safe :: Source Location seems to be a directory.', 'enable-media-replace'));
433
  return;
434
  }
435
 
436
- if (strlen(trim($current_base_url)) == 0)
437
  {
438
- Log::addError('Current Base URL emtpy - ' . $current_base_url);
439
  Notices::addError(__('Fail Safe :: Source Location returned empty string. Not replacing content','enable-media-replace'));
440
  return;
441
  }
442
 
443
-
444
- //$search_files = $this->getFilesFromMetadata($this->source_metadata);
445
- //$replace_files = $this->getFilesFromMetadata($this->target_metadata);
446
- // $arr = $this->getRelativeURLS();
447
-
448
- /*$search_urls = emr_get_file_urls( $this->source_url, $this->source_metadata );
449
- $replace_urls = emr_get_file_urls( $this->target_url, $this->target_metadata );
450
- $replace_urls = array_values(emr_normalize_file_urls( $search_urls, $replace_urls ));*/
451
-
452
  // get relurls of both source and target.
453
  $urls = $this->getRelativeURLS();
454
 
@@ -482,8 +481,8 @@ class Replacer
482
  }
483
  }
484
 
485
- Log::addDebug('Source', $this->source_metadata);
486
- Log::addDebug('Target', $this->target_metadata);
487
  /* If on the other hand, some sizes are available in source, but not in target, try to replace them with something closeby. */
488
  foreach($search_urls as $size => $url)
489
  {
@@ -521,84 +520,151 @@ class Replacer
521
  // 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.
522
  if (count($search_urls) !== count($replace_urls))
523
  {
524
-
525
  Log::addError('Unbalanced Replace Arrays, aborting', array($search_urls, $replace_urls, count($search_urls), count($replace_urls) ));
526
  Notices::addError(__('There was an issue with updating your image URLS: Search and replace have different amount of values. Aborting updating thumbnails', 'enable-media-replace'));
527
  return;
528
  }
529
 
530
  Log::addDebug('Doing meta search and replace -', array($search_urls, $replace_urls) );
531
- Log::addDebug('Searching with BaseuRL ' . $current_base_url);
532
-
533
- /* Search and replace in WP_POSTS */
534
- // Removed $wpdb->remove_placeholder_escape from here, not compatible with WP 4.8
535
- $posts_sql = $wpdb->prepare(
536
- "SELECT ID, post_content FROM $wpdb->posts WHERE post_status = 'publish' AND post_content LIKE %s;",
537
- '%' . $current_base_url . '%');
538
 
539
- // json encodes it all differently. Catch json-like encoded urls
540
- //$json_url = str_replace('/', '\/', ltrim($current_base_url, '/') );
541
 
542
- $postmeta_sql = 'SELECT meta_id, post_id, meta_key, meta_value FROM ' . $wpdb->postmeta . '
543
- WHERE post_id in (SELECT ID from '. $wpdb->posts . ' where post_status = "publish") AND meta_value like %s';
544
- $postmeta_sql = $wpdb->prepare($postmeta_sql, '%' . $current_base_url . '%');
545
 
546
- // 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.
547
- // $postmeta_sql = str_replace('[JSON_URL]', $json_url, $postmeta_sql);
548
-
549
- $rsmeta = $wpdb->get_results($postmeta_sql, ARRAY_A);
 
 
 
 
550
 
551
- $rs = $wpdb->get_results( $posts_sql, ARRAY_A );
 
 
552
 
553
- $number_of_updates = 0;
554
 
555
- Log::addDebug('Queries', array($postmeta_sql, $posts_sql));
556
- Log::addDebug('Queries found ' . count($rs) . ' post rows and ' . count($rsmeta) . ' meta rows');
 
 
 
 
 
 
557
 
 
 
558
 
559
- if ( ! empty( $rs ) ) {
560
- foreach ( $rs AS $rows ) {
561
- $number_of_updates = $number_of_updates + 1;
562
- // replace old URLs with new URLs.
563
- $post_content = $rows["post_content"];
564
- //$post_content = str_replace( $search_urls, $replace_urls, $post_content );
565
 
 
566
  $post_id = $rows['ID'];
567
- $post_ar = array('ID' => $post_id);
568
- $post_ar['post_content'] = $this->replaceContent($post_content, $search_urls, $replace_urls);
569
 
570
- if ($post_ar['post_content'] !== $post_content)
571
  {
572
- $result = wp_update_post($post_ar);
573
- if (is_wp_error($result))
 
 
 
 
 
 
 
 
574
  {
575
  Notice::addError('Something went wrong while replacing' . $result->get_error_message() );
576
  Log::addError('WP-Error during post update', $result);
577
  }
578
  }
579
 
580
- }
581
- }
582
- if (! empty($rsmeta))
583
- {
584
- foreach ($rsmeta as $row)
585
- {
586
- $number_of_updates++;
587
- $content = $row['meta_value'];
588
- $meta_key = $row['meta_key'];
589
- $post_id = $row['post_id'];
590
- $content = $this->replaceContent($content, $search_urls, $replace_urls); //str_replace($search_urls, $replace_urls, $content);
591
-
592
- update_post_meta($post_id, $meta_key, $content);
593
- // $sql = $wpdb->prepare('UPDATE ' . $wpdb->postmeta . ' SET meta_value = %s WHERE meta_id = %d', $content, $row['meta_id'] );
594
- // $wpdb->query($sql);
595
  }
596
  }
597
 
 
 
 
598
 
599
- } // doSearchReplace
 
 
600
 
601
- private function replaceContent($content, $search, $replace)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
602
  {
603
  //$is_serial = false;
604
  $content = maybe_unserialize($content);
@@ -608,11 +674,14 @@ class Replacer
608
  {
609
  Log::addDebug('Found JSON Content');
610
  $content = json_decode($content);
 
611
 
612
  }
613
 
614
  if (is_string($content)) // let's check the normal one first.
615
  {
 
 
616
  $content = str_replace($search, $replace, $content);
617
  }
618
  elseif (is_wp_error($content)) // seen this.
@@ -623,30 +692,48 @@ class Replacer
623
  {
624
  foreach($content as $index => $value)
625
  {
626
- $content[$index] = $this->replaceContent($value, $search, $replace); //str_replace($value, $search, $replace);
 
 
 
 
 
 
627
  }
628
- //return $content;
629
  }
630
  elseif(is_object($content)) // metadata objects, they exist.
631
  {
632
  foreach($content as $key => $value)
633
  {
634
- $content->{$key} = $this->replaceContent($value, $search, $replace); //str_replace($value, $search, $replace);
635
  }
636
- //return $content;
637
  }
638
 
639
- if ($isJson) // convert back to JSON, if this was JSON. Different than serialize which does WP automatically.
640
  {
641
  Log::addDebug('Value was found to be JSON, encoding');
642
  // wp-slash -> WP does stripslashes_deep which destroys JSON
643
- $content = (json_encode($content, JSON_UNESCAPED_SLASHES));
644
  Log::addDebug('Content returning', array($content));
645
  }
 
 
646
 
647
  return $content;
648
  }
649
 
 
 
 
 
 
 
 
 
 
 
 
 
650
  private function getFilesFromMetadata($meta)
651
  {
652
  $fileArray = array();
4
  use EnableMediaReplace\ShortPixelLogger\ShortPixelLogger as Log;
5
  use EnableMediaReplace\Notices\NoticeController as Notices;
6
 
7
+ use EnableMediaReplace\Externals\Elementor as Elementor; // like Skeletor.
8
+
9
  class Replacer
10
  {
11
  protected $post_id;
237
  $cache = new emrCache();
238
  $cache->flushCache($cache_args);
239
 
240
+ do_action("enable-media-replace-upload-done", $this->target_url, $this->source_url, $this->post_id);
241
 
242
  return true;
243
  }
382
  $file = $this->sourceFile->getFullFilePath();
383
  $result = \wp_delete_attachment_files($this->post_id, $meta, $backup_sizes, $file );
384
 
385
+ // If Attached file is not the same path as file, this indicates a -scaled images is in play.
386
+ $attached_file = get_attached_file($this->post_id);
387
+ if ($file !== $attached_file && file_exists($attached_file))
388
+ {
389
+ @unlink($attached_file);
390
+ }
391
+
392
+
393
  }
394
 
395
  /** Handle new dates for the replacement */
427
 
428
  $args = wp_parse_args($args, $defaults);
429
 
 
 
430
  // Search-and-replace filename in post database
431
  // @todo Check this with scaled images.
432
+ $base_url = parse_url($this->source_url, PHP_URL_PATH);// emr_get_match_url( $this->source_url);
433
+ $base_url = str_replace('.' . pathinfo($base_url, PATHINFO_EXTENSION), '', $base_url);
434
 
435
 
436
  /** Fail-safe if base_url is a whole directory, don't go search/replace */
437
+ if (is_dir($base_url))
438
  {
439
+ Log::addError('Search Replace tried to replace to directory - ' . $base_url);
440
  Notices::addError(__('Fail Safe :: Source Location seems to be a directory.', 'enable-media-replace'));
441
  return;
442
  }
443
 
444
+ if (strlen(trim($base_url)) == 0)
445
  {
446
+ Log::addError('Current Base URL emtpy - ' . $base_url);
447
  Notices::addError(__('Fail Safe :: Source Location returned empty string. Not replacing content','enable-media-replace'));
448
  return;
449
  }
450
 
 
 
 
 
 
 
 
 
 
451
  // get relurls of both source and target.
452
  $urls = $this->getRelativeURLS();
453
 
481
  }
482
  }
483
 
484
+ // Log::addDebug('Source', $this->source_metadata);
485
+ // Log::addDebug('Target', $this->target_metadata);
486
  /* If on the other hand, some sizes are available in source, but not in target, try to replace them with something closeby. */
487
  foreach($search_urls as $size => $url)
488
  {
520
  // 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.
521
  if (count($search_urls) !== count($replace_urls))
522
  {
 
523
  Log::addError('Unbalanced Replace Arrays, aborting', array($search_urls, $replace_urls, count($search_urls), count($replace_urls) ));
524
  Notices::addError(__('There was an issue with updating your image URLS: Search and replace have different amount of values. Aborting updating thumbnails', 'enable-media-replace'));
525
  return;
526
  }
527
 
528
  Log::addDebug('Doing meta search and replace -', array($search_urls, $replace_urls) );
529
+ Log::addDebug('Searching with BaseuRL ' . $base_url);
 
 
 
 
 
 
530
 
531
+ do_action('emr/replace_urls', $search_urls, $replace_urls);
532
+ $updated = 0;
533
 
534
+ $updated += $this->doReplaceQuery($base_url, $search_urls, $replace_urls);
 
 
535
 
536
+ $replaceRuns = apply_filters('emr/replacer/custom_replace_query', array(), $base_url, $search_urls, $replace_urls);
537
+ Log::addDebug("REPLACE RUNS", $replaceRuns);
538
+ foreach($replaceRuns as $component => $run)
539
+ {
540
+ Log::addDebug('Running additional replace for : '. $component, $run);
541
+ $updated += $this->doReplaceQuery($run['base_url'], $run['search_urls'], $run['replace_urls']);
542
+ }
543
+ //do_action('')
544
 
545
+ Log::addDebug("Updated Records : " . $updated);
546
+ return $updated;
547
+ } // doSearchReplace
548
 
 
549
 
550
+ private function doReplaceQuery($base_url, $search_urls, $replace_urls)
551
+ {
552
+ global $wpdb;
553
+ /* Search and replace in WP_POSTS */
554
+ // Removed $wpdb->remove_placeholder_escape from here, not compatible with WP 4.8
555
+ $posts_sql = $wpdb->prepare(
556
+ "SELECT ID, post_content FROM $wpdb->posts WHERE post_status = 'publish' AND post_content LIKE %s",
557
+ '%' . $base_url . '%');
558
 
559
+ $rs = $wpdb->get_results( $posts_sql, ARRAY_A );
560
+ $number_of_updates = 0;
561
 
562
+ if ( ! empty( $rs ) ) {
563
+ foreach ( $rs AS $rows ) {
564
+ $number_of_updates = $number_of_updates + 1;
565
+ // replace old URLs with new URLs.
 
 
566
 
567
+ $post_content = $rows["post_content"];
568
  $post_id = $rows['ID'];
569
+ $replaced_content = $this->replaceContent($post_content, $search_urls, $replace_urls);
 
570
 
571
+ if ($replaced_content !== $post_content)
572
  {
573
+ Log::addDebug('POST CONTENT TO SAVE', $replaced_content);
574
+
575
+ // $result = wp_update_post($post_ar);
576
+ $sql = 'UPDATE ' . $wpdb->posts . ' SET post_content = %s WHERE ID = %d';
577
+ $sql = $wpdb->prepare($sql, $replaced_content, $post_id);
578
+
579
+ Log::addDebug("POSt update query " . $sql);
580
+ $result = $wpdb->query($sql);
581
+
582
+ if ($result === false)
583
  {
584
  Notice::addError('Something went wrong while replacing' . $result->get_error_message() );
585
  Log::addError('WP-Error during post update', $result);
586
  }
587
  }
588
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
589
  }
590
  }
591
 
592
+ $number_of_updates += $this->handleMetaData($base_url, $search_urls, $replace_urls);
593
+ return $number_of_updates;
594
+ }
595
 
596
+ private function handleMetaData($url, $search_urls, $replace_urls)
597
+ {
598
+ global $wpdb;
599
 
600
+ $meta_options = apply_filters('emr/metadata_tables', array('post', 'comment', 'term', 'user'));
601
+ $number_of_updates = 0;
602
+
603
+ foreach($meta_options as $type)
604
+ {
605
+ switch($type)
606
+ {
607
+ case "post": // special case.
608
+ $sql = 'SELECT meta_id as id, meta_key, meta_value FROM ' . $wpdb->postmeta . '
609
+ WHERE post_id in (SELECT ID from '. $wpdb->posts . ' where post_status = "publish") AND meta_value like %s';
610
+ $type = 'post';
611
+
612
+ $update_sql = ' UPDATE ' . $wpdb->postmeta . ' SET meta_value = %s WHERE meta_id = %d';
613
+ break;
614
+ default:
615
+ $table = $wpdb->{$type . 'meta'}; // termmeta, commentmeta etc
616
+
617
+ $meta_id = 'meta_id';
618
+ if ($type == 'user')
619
+ $meta_id = 'umeta_id';
620
+
621
+ $sql = 'SELECT ' . $meta_id . ' as id, meta_value FROM ' . $table . '
622
+ WHERE meta_value like %s';
623
+
624
+ $update_sql = " UPDATE $table set meta_value = %s WHERE $meta_id = %d ";
625
+ break;
626
+ }
627
+
628
+ $sql = $wpdb->prepare($sql, '%' . $url . '%');
629
+
630
+ // 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.
631
+ // $postmeta_sql = str_replace('[JSON_URL]', $json_url, $postmeta_sql);
632
+ $rsmeta = $wpdb->get_results($sql, ARRAY_A);
633
+
634
+ if (! empty($rsmeta))
635
+ {
636
+ foreach ($rsmeta as $row)
637
+ {
638
+ $number_of_updates++;
639
+ $content = $row['meta_value'];
640
+
641
+
642
+ $id = $row['id'];
643
+
644
+ $content = $this->replaceContent($content, $search_urls, $replace_urls); //str_replace($search_urls, $replace_urls, $content);
645
+
646
+ $prepared_sql = $wpdb->prepare($update_sql, $content, $id);
647
+
648
+ Log::addDebug('Update Meta SQl' . $prepared_sql);
649
+ $result = $wpdb->query($prepared_sql);
650
+
651
+ }
652
+ }
653
+ } // foreach
654
+
655
+ return $number_of_updates;
656
+ } // function
657
+
658
+
659
+
660
+ /**
661
+ * Replaces Content across several levels of possible data
662
+ * @param $content String The Content to replace
663
+ * @param $search String Search string
664
+ * @param $replace String Replacement String
665
+ * @param $in_deep Boolean. This is use to prevent serialization of sublevels. Only pass back serialized from top.
666
+ */
667
+ private function replaceContent($content, $search, $replace, $in_deep = false)
668
  {
669
  //$is_serial = false;
670
  $content = maybe_unserialize($content);
674
  {
675
  Log::addDebug('Found JSON Content');
676
  $content = json_decode($content);
677
+ Log::addDebug('J/Son Content', $content);
678
 
679
  }
680
 
681
  if (is_string($content)) // let's check the normal one first.
682
  {
683
+ $content = apply_filters('emr/replace/content', $content, $search, $replace);
684
+
685
  $content = str_replace($search, $replace, $content);
686
  }
687
  elseif (is_wp_error($content)) // seen this.
692
  {
693
  foreach($content as $index => $value)
694
  {
695
+ $content[$index] = $this->replaceContent($value, $search, $replace, true); //str_replace($value, $search, $replace);
696
+ if (is_string($index)) // If the key is the URL (sigh)
697
+ {
698
+ $index_replaced = $this->replaceContent($index, $search,$replace, true);
699
+ if ($index_replaced !== $index)
700
+ $content = $this->change_key($content, array($index => $index_replaced));
701
+ }
702
  }
 
703
  }
704
  elseif(is_object($content)) // metadata objects, they exist.
705
  {
706
  foreach($content as $key => $value)
707
  {
708
+ $content->{$key} = $this->replaceContent($value, $search, $replace, true); //str_replace($value, $search, $replace);
709
  }
 
710
  }
711
 
712
+ if ($isJson && $in_deep === false) // convert back to JSON, if this was JSON. Different than serialize which does WP automatically.
713
  {
714
  Log::addDebug('Value was found to be JSON, encoding');
715
  // wp-slash -> WP does stripslashes_deep which destroys JSON
716
+ $content = json_encode($content, JSON_UNESCAPED_SLASHES);
717
  Log::addDebug('Content returning', array($content));
718
  }
719
+ elseif($in_deep === false && (is_array($content) || is_object($content)))
720
+ $content = maybe_serialize($content);
721
 
722
  return $content;
723
  }
724
 
725
+ private function change_key($arr, $set) {
726
+ if (is_array($arr) && is_array($set)) {
727
+ $newArr = array();
728
+ foreach ($arr as $k => $v) {
729
+ $key = array_key_exists( $k, $set) ? $set[$k] : $k;
730
+ $newArr[$key] = is_array($v) ? $this->change_key($v, $set) : $v;
731
+ }
732
+ return $newArr;
733
+ }
734
+ return $arr;
735
+ }
736
+
737
  private function getFilesFromMetadata($meta)
738
  {
739
  $fileArray = array();
enable-media-replace.php CHANGED
@@ -1,24 +1,25 @@
1
  <?php
2
- /*
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.2
7
- Author: ShortPixel
8
- Author URI: https://shortpixel.com
9
- Text Domain: enable-media-replace
10
- Domain Path: /languages
11
- Dual licensed under the MIT and GPL licenses:
12
- http://www.opensource.org/licenses/mit-license.php
13
- http://www.gnu.org/licenses/gpl.html
14
- */
 
15
 
16
  /**
17
  * Main Plugin file
18
  * Set action hooks and add shortcode
19
  *
20
  * @author ShortPixel <https://shortpixel.com>
21
- * @copyright ShortPixel 2018-2019
22
  * @package wordpress
23
  * @subpackage enable-media-replace
24
  *
@@ -26,7 +27,7 @@ http://www.gnu.org/licenses/gpl.html
26
 
27
  namespace EnableMediaReplace;
28
 
29
- define('EMR_VERSION', '3.4.2');
30
 
31
  if ( ! defined( 'ABSPATH' ) ) {
32
  exit; // Exit if accessed directly.
@@ -56,6 +57,15 @@ require_once($plugin_path . 'classes/file.php');
56
  require_once($plugin_path . 'classes/cache.php');
57
  require_once($plugin_path . 'classes/emr-plugin.php');
58
  require_once($plugin_path . 'classes/externals.php');
 
 
59
  require_once($plugin_path . 'thumbnail_updater.php');
60
 
61
  $emr_plugin = EnableMediaReplacePlugin::get();
 
 
 
 
 
 
 
1
  <?php
2
+ /**
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.5.0
7
+ * Author: ShortPixel
8
+ * Author URI: https://shortpixel.com
9
+ * GitHub Plugin URI: https://github.com/short-pixel-optimizer/enable-media-replace
10
+ * Text Domain: enable-media-replace
11
+ * Domain Path: /languages
12
+ * Dual licensed under the MIT and GPL licenses:
13
+ * License URI: http://www.opensource.org/licenses/mit-license.php
14
+ * License URI: http://www.gnu.org/licenses/gpl.html
15
+ */
16
 
17
  /**
18
  * Main Plugin file
19
  * Set action hooks and add shortcode
20
  *
21
  * @author ShortPixel <https://shortpixel.com>
22
+ * @copyright ShortPixel 2018-2020
23
  * @package wordpress
24
  * @subpackage enable-media-replace
25
  *
27
 
28
  namespace EnableMediaReplace;
29
 
30
+ define('EMR_VERSION', '3.5.0');
31
 
32
  if ( ! defined( 'ABSPATH' ) ) {
33
  exit; // Exit if accessed directly.
57
  require_once($plugin_path . 'classes/cache.php');
58
  require_once($plugin_path . 'classes/emr-plugin.php');
59
  require_once($plugin_path . 'classes/externals.php');
60
+ require_once($plugin_path . 'classes/external/elementor.php');
61
+ require_once($plugin_path . 'classes/external/wpbakery.php');
62
  require_once($plugin_path . 'thumbnail_updater.php');
63
 
64
  $emr_plugin = EnableMediaReplacePlugin::get();
65
+
66
+ register_uninstall_hook(__FILE__, 'emr_uninstall');
67
+
68
+ function emr_uninstall()
69
+ {
70
+ delete_option('enable_media_replace');
71
+ }
js/emr_admin.js CHANGED
@@ -101,7 +101,7 @@
101
 
102
  var status = this.checkUpload(file);
103
  this.debug('check upload status ' + status);
104
- this.debug(file.size);
105
 
106
  if (status)
107
  {
101
 
102
  var status = this.checkUpload(file);
103
  this.debug('check upload status ' + status);
104
+ this.debug('file size:' + file.size);
105
 
106
  if (status)
107
  {
readme.txt CHANGED
@@ -2,10 +2,10 @@
2
  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.5
7
  Requires PHP: 5.6
8
- Stable tag: 3.4.2
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,19 @@ If you want more control over the format used to display the time, you can use t
47
 
48
  == Changelog ==
49
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
 
51
  = 3.4.2 =
52
 
2
  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
6
+ Tested up to: 5.7
7
  Requires PHP: 5.6
8
+ Stable tag: 3.5.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.5.0 =
51
+
52
+ Release date: October 29th 2020
53
+ * New: EMR now replaces across all meta tables;
54
+ * New: the plugin remembers last used settings;
55
+ * New: integration with the LiteSpeed cache plugin and webserver;
56
+ * Tweak: manual Logging will no longer work if user is not logged as administrator;
57
+ * Tweak: added `post_id` to `enable-media-replace-upload-done` action args, props to @Jan Stiegler;
58
+ * Fix: fully works now with Elementor;
59
+ * Fix: the issue for WP-Bakery and URL-Encoded links is now fixed;
60
+ * Fix: the plugin should now work with images added through Visual Composer;
61
+ * Fix: EMR now uses queries instead of WordPress functions, correctly handling slashes and JSON formats;
62
+ * Fix: `-scaled` images generated by WordPress are now removed when replacing an image;
63
 
64
  = 3.4.2 =
65
 
views/popup.php CHANGED
@@ -42,7 +42,14 @@ $uiHelper->setSourceSizes($attachment_id);
42
 
43
  $emr = EnableMediaReplacePlugin::get();
44
 
45
-
 
 
 
 
 
 
 
46
 
47
  ?>
48
 
@@ -122,7 +129,7 @@ $url = $uiHelper->getFormUrl($attachment_id);
122
  $search_disabled = (! $enabled_search) ? 'disabled' : '';
123
  ?>
124
  <div class='option replace <?php echo $search_disabled ?>'>
125
- <label for="replace_type_1" ><input CHECKED id="replace_type_1" type="radio" name="replace_type" value="replace" <?php echo $search_disabled ?> > <?php echo esc_html__("Just replace the file", "enable-media-replace"); ?>
126
  </label>
127
 
128
  <p class="howto">
@@ -137,7 +144,7 @@ $url = $uiHelper->getFormUrl($attachment_id);
137
  ?>
138
 
139
  <div class="option searchreplace <?php echo $searchreplace_disabled ?>">
140
- <label for="replace_type_2"><input id="replace_type_2" type="radio" name="replace_type" value="replace_and_search" <?php echo $searchreplace_disabled ?> > <?php echo __("Replace the file, use new file name and update all links", "enable-media-replace"); ?>
141
  </label>
142
 
143
  <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. (If any other websites link to the file directly, those links will no longer work. Be careful.)", "enable-media-replace"), $filename ); ?></p>
@@ -155,12 +162,17 @@ $url = $uiHelper->getFormUrl($attachment_id);
155
  $attachment_current_date = date_i18n('d/M/Y H:i', strtotime($attachment->post_date) );
156
  $time = current_time('mysql');
157
  $date = new \dateTime($time);
 
 
 
 
 
158
  ?>
159
  <p><?php _e('When replacing the media, do you want to:', 'enable-media-replace'); ?></p>
160
  <ul>
161
- <li><label><input type='radio' name='timestamp_replace' value='1' /><?php _e('Replace the date', 'enable-media-replace'); ?></label></li>
162
- <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>
163
- <li><label><input type='radio' name='timestamp_replace' value='3' /><?php _e('Set a Custom Date', 'enable-media-replace'); ?></label></li>
164
  </ul>
165
  <div class='custom_date'>
166
 
@@ -172,9 +184,13 @@ $url = $uiHelper->getFormUrl($attachment_id);
172
  <input type="text" name="custom_minute" class='emr_minute' value="<?php echo $date->format('i'); ?>" />
173
  <input type="hidden" name="custom_date_formatted" value="<?php echo $date->format('Y-m-d'); ?>" />
174
  </div>
175
- <?php if ($subdir = $uiHelper->getRelPathNow()): ?>
 
 
 
 
176
  <div class='location_option'>
177
- <label><input type="checkbox" name="new_location" value="1" /> <?php _e('Put new Upload in Updated Folder: '); ?></label>
178
  <input type="text" name="location_dir" value="<?php echo $subdir ?>" />
179
  </div>
180
  <?php endif; ?>
42
 
43
  $emr = EnableMediaReplacePlugin::get();
44
 
45
+ $defaults = array(
46
+ 'replace_type' => 'replace',
47
+ 'timestamp_replace' => \EnableMediaReplace\Replacer::TIME_UPDATEMODIFIED,
48
+ 'custom_date' => date("Y-m-d H:i:s"),
49
+ 'new_location' => false,
50
+ 'new_location_dir' => false,
51
+ );
52
+ $settings = get_option('enable_media_replace', $defaults);
53
 
54
  ?>
55
 
129
  $search_disabled = (! $enabled_search) ? 'disabled' : '';
130
  ?>
131
  <div class='option replace <?php echo $search_disabled ?>'>
132
+ <label for="replace_type_1" ><input <?php checked('replace', $settings['replace_type']) ?> id="replace_type_1" type="radio" name="replace_type" value="replace" <?php echo $search_disabled ?> > <?php echo esc_html__("Just replace the file", "enable-media-replace"); ?>
133
  </label>
134
 
135
  <p class="howto">
144
  ?>
145
 
146
  <div class="option searchreplace <?php echo $searchreplace_disabled ?>">
147
+ <label for="replace_type_2"><input id="replace_type_2" <?php checked('replace_and_search', $settings['replace_type']) ?> type="radio" name="replace_type" value="replace_and_search" <?php echo $searchreplace_disabled ?> > <?php echo __("Replace the file, use new file name and update all links", "enable-media-replace"); ?>
148
  </label>
149
 
150
  <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. (If any other websites link to the file directly, those links will no longer work. Be careful.)", "enable-media-replace"), $filename ); ?></p>
162
  $attachment_current_date = date_i18n('d/M/Y H:i', strtotime($attachment->post_date) );
163
  $time = current_time('mysql');
164
  $date = new \dateTime($time);
165
+
166
+ if ($settings['timestamp_replace'] == \EnableMediaReplace\Replacer::TIME_CUSTOM)
167
+ {
168
+ $date = new \dateTime($settings['custom_date']);
169
+ }
170
  ?>
171
  <p><?php _e('When replacing the media, do you want to:', 'enable-media-replace'); ?></p>
172
  <ul>
173
+ <li><label><input type='radio' <?php checked('1', $settings['timestamp_replace']) ?> name='timestamp_replace' value='1' /><?php _e('Replace the date', 'enable-media-replace'); ?></label></li>
174
+ <li><label><input type='radio' <?php checked('2', $settings['timestamp_replace']) ?> 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>
175
+ <li><label><input type='radio' <?php checked('3', $settings['timestamp_replace']) ?> name='timestamp_replace' value='3' /><?php _e('Set a Custom Date', 'enable-media-replace'); ?></label></li>
176
  </ul>
177
  <div class='custom_date'>
178
 
184
  <input type="text" name="custom_minute" class='emr_minute' value="<?php echo $date->format('i'); ?>" />
185
  <input type="hidden" name="custom_date_formatted" value="<?php echo $date->format('Y-m-d'); ?>" />
186
  </div>
187
+ <?php if ($subdir = $uiHelper->getRelPathNow()):
188
+
189
+ if ($settings['new_location'] !== false)
190
+ $subdir = $settings['new_location_dir'];
191
+ ?>
192
  <div class='location_option'>
193
+ <label><input type="checkbox" name="new_location" value="1" <?php checked($settings['new_location'], 1); ?> /> <?php _e('Put new Upload in Updated Folder: '); ?></label>
194
  <input type="text" name="location_dir" value="<?php echo $subdir ?>" />
195
  </div>
196
  <?php endif; ?>
views/upload.php CHANGED
@@ -38,6 +38,12 @@ $redirect_success = $uihelper->getSuccesRedirect($post_id);
38
  $do_new_location = isset($_POST['new_location']) ? sanitize_text_field($_POST['new_location']) : false;
39
  $new_location_dir = isset($_POST['location_dir']) ? sanitize_text_field($_POST['location_dir']) : null;
40
 
 
 
 
 
 
 
41
  switch($timestamp_replace)
42
  {
43
  case \EnableMediaReplace\Replacer::TIME_UPDATEALL:
@@ -68,9 +74,12 @@ switch($timestamp_replace)
68
  exit();
69
  }
70
  $datetime = $custom_date->format("Y-m-d H:i:s");
 
71
  break;
72
  }
73
 
 
 
74
  // We have two types: replace / replace_and_search
75
  if ($replace_type == 'replace')
76
  {
38
  $do_new_location = isset($_POST['new_location']) ? sanitize_text_field($_POST['new_location']) : false;
39
  $new_location_dir = isset($_POST['location_dir']) ? sanitize_text_field($_POST['location_dir']) : null;
40
 
41
+ $settings = array(); // save settings and show last loaded.
42
+ $settings['replace_type'] = $replace_type;
43
+ $settings['timestamp_replace'] = $timestamp_replace;
44
+ $settings['new_location'] = $do_new_location;
45
+ $settings['new_location_dir'] = $new_location_dir;
46
+
47
  switch($timestamp_replace)
48
  {
49
  case \EnableMediaReplace\Replacer::TIME_UPDATEALL:
74
  exit();
75
  }
76
  $datetime = $custom_date->format("Y-m-d H:i:s");
77
+ $settings['custom_date'] = $datetime;
78
  break;
79
  }
80
 
81
+ update_option('enable_media_replace', $settings, false);
82
+
83
  // We have two types: replace / replace_and_search
84
  if ($replace_type == 'replace')
85
  {