c1b76676 by Jeff Balicki

media replace

Signed-off-by: Jeff <jeff@gotenzing.com>
1 parent 50aa63ba
Showing 111 changed files with 4805 additions and 0 deletions
1 <?php
2 namespace EnableMediaReplace\Build;
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 {
29 $this->dir = $dir;
30 $composer = $this->getComposerFile();
31
32
33 if(isset($composer["autoload"]["psr-4"])){
34 $this->loadPSR4($composer['autoload']['psr-4']);
35 }
36 if(isset($composer["autoload"]["psr-0"])){
37 $this->loadPSR0($composer['autoload']['psr-0']);
38 }
39 if(isset($composer["autoload"]["files"])){
40 $this->loadFiles($composer["autoload"]["files"]);
41 }
42 }
43
44 public function loadFiles($files){
45 foreach($files as $file){
46 $fullpath = $this->dir."/".$file;
47 if(file_exists($fullpath)){
48 include_once($fullpath);
49 }
50 }
51 }
52
53 public function loadPSR4($namespaces)
54 {
55 $this->loadPSR($namespaces, true);
56 }
57
58 public function loadPSR0($namespaces)
59 {
60 $this->loadPSR($namespaces, false);
61 }
62
63 public function loadPSR($namespaces, $psr4)
64 {
65 $dir = $this->dir;
66 // Foreach namespace specified in the composer, load the given classes
67 foreach ($namespaces as $namespace => $classpaths) {
68 if (!is_array($classpaths)) {
69 $classpaths = array($classpaths);
70 }
71 spl_autoload_register(function ($classname) use ($namespace, $classpaths, $dir, $psr4) {
72 // Check if the namespace matches the class we are looking for
73 if (preg_match("#^".preg_quote($namespace)."#", $classname)) {
74 // Remove the namespace from the file path since it's psr4
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;
86 if (file_exists($fullpath)) {
87 include_once $fullpath;
88 }
89 }
90 }
91 });
92 }
93 }
94 }
1 <?php
2 require_once (__DIR__ . "/PackageLoader.php");
3 $loader = new EnableMediaReplace\Build\PackageLoader();
4 $loader->load(__DIR__);
5
...\ No newline at end of file ...\ No newline at end of file
1 {"name":"EnableMediaReplace\/shortpixelmodules","description":"ShortPixel submodules","type":"function","autoload":{"psr-4":{"EnableMediaReplace\\Notices":"notices\/src","EnableMediaReplace\\ShortPixelLogger":"log\/src","EnableMediaReplace\\FileSystem":"filesystem\/src","EnableMediaReplace\\Replacer":"replacer\/src"}}}
...\ No newline at end of file ...\ No newline at end of file
1 {
2 "name": "shortpixel/filesystem",
3 "description": "ShortPixel FileSystem",
4 "version": 1.0,
5 "type": "library",
6 "license": "MIT",
7 "authors": [
8 {
9 "name": "Bas",
10 "email": "bas@weblogmechanic.com"
11 }
12 ],
13 "minimum-stability": "dev",
14 "require": {},
15 "autoload": {
16 "psr-4": { "ShortPixel\\FileSystem\\" : "src" }
17 }
18 }
1 {
2 "name": "shortpixel/log",
3 "description": "ShortPixel Logging",
4 "version": "1.1.3",
5 "type": "library",
6 "license": "MIT",
7 "authors": [
8 {
9 "name": "Bas",
10 "email": "bas@weblogmechanic.com"
11 }
12 ],
13 "minimum-stability": "dev",
14 "require": {},
15 "autoload": {
16 "psr-4": { "ShortPixel\\ShortPixelLogger\\" : "src" }
17 }
18 }
1 <?php
2 // The data models.
3 namespace EnableMediaReplace\ShortPixelLogger;
4
5
6 class DebugItem
7 {
8 protected $time;
9 protected $level;
10 protected $message;
11 protected $data = array();
12 protected $caller = false; // array when filled
13
14 protected $model;
15
16 const LEVEL_ERROR = 1;
17 const LEVEL_WARN = 2;
18 const LEVEL_INFO = 3;
19 const LEVEL_DEBUG = 4;
20
21 public function __construct($message, $args)
22 {
23 $this->level = $args['level'];
24 $data = $args['data'];
25
26 $this->message = $message;
27 $this->time = microtime(true);
28
29 $this->setCaller();
30
31 // Add message to data if it seems to be some debug variable.
32 if (is_object($this->message) || is_array($this->message))
33 {
34 $data[] = $this->message;
35 $this->message = __('[Data]');
36 }
37 if (is_array($data) && count($data) > 0)
38 {
39 $dataType = $this->getDataType($data);
40 if ($dataType == 1) // singular
41 {
42 $this->data[] = print_r($data, true);
43 }
44 if ($dataType == 2) //array or object.
45 {
46 $count = false;
47 if (gettype($data) == 'array')
48 $count = count($data);
49 elseif(gettype($data) == 'object')
50 $count = count(get_object_vars($data));
51
52 $firstLine = ucfirst(gettype($data)) . ':';
53 if ($count !== false)
54 $firstLine .= ' (' . $count . ')';
55
56 $this->data[] = $firstLine;
57
58 foreach($data as $index => $item)
59 {
60 if (is_object($item) || is_array($item))
61 {
62 $this->data[] = print_r($index, true) . ' ( ' . ucfirst(gettype($item)) . ') => ' . print_r($item, true);
63 }
64 }
65 }
66 } // if
67 elseif (! is_array($data)) // this leaves out empty default arrays
68 {
69 $this->data[] = print_r($data, true);
70 }
71 }
72
73 public function getData()
74 {
75 return array('time' => $this->time, 'level' => $this->level, 'message' => $this->message, 'data' => $this->data, 'caller' => $this->caller);
76 }
77
78 /** Test Data Array for possible values
79 *
80 * Data can be a collection of several debug vars, a single var, or just an normal array. Test if array has single types,
81 * which is a sign the array is not a collection.
82 */
83 protected function getDataType($data)
84 {
85 $single_type = array('integer', 'boolean', 'string');
86 if (in_array(gettype(reset($data)), $single_type))
87 {
88 return 1;
89 }
90 else
91 {
92 return 2;
93 }
94 }
95
96 public function getForFormat()
97 {
98 $data = $this->getData();
99 switch($this->level)
100 {
101 case self::LEVEL_ERROR:
102 $level = 'ERR';
103 $color = "\033[31m";
104 break;
105 case self::LEVEL_WARN:
106 $level = 'WRN';
107 $color = "\033[33m";
108 break;
109 case self::LEVEL_INFO:
110 $level = 'INF';
111 $color = "\033[37m";
112 break;
113 case self::LEVEL_DEBUG:
114 $level = 'DBG';
115 $color = "\033[37m";
116 break;
117
118 }
119 $color_end = "\033[0m";
120
121 $data['color'] = $color;
122 $data['color_end'] = $color_end;
123 $data['level'] = $level;
124
125 return $data;
126
127 //return array('time' => $this->time, 'level' => $level, 'message' => $this->message, 'data' => $this->data, 'color' => $color, 'color_end' => $color_end, 'caller' => $this->caller);
128
129 }
130
131 protected function setCaller()
132 {
133 if(PHP_VERSION_ID < 50400) {
134 $debug=debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
135 } else {
136 $debug=debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS,5);
137 }
138
139 $i = 4;
140 if (isset($debug[$i]))
141 {
142 $info = $debug[$i];
143 $line = isset($info['line']) ? $info['line'] : 'Line unknown';
144 $file = isset($info['file']) ? basename($info['file']) : 'File not set';
145
146 $this->caller = array('line' => $line, 'file' => $file, 'function' => $info['function']);
147 }
148
149
150 }
151
152
153 }
1 <?php
2 // Debug Box to load Log File
3 namespace EnableMediaReplace\ShortPixelLogger;
4 wp_enqueue_script( 'jquery-ui-draggable' );
5
6 ?>
7
8 <style>
9 .sp_debug_wrap
10 {
11 position: relative;
12 clear: both;
13 }
14 .sp_debug_box
15 {
16 position: absolute;
17 right: 0px;
18 top: 50px;
19 background-color: #fff;
20 width: 150px;
21 z-index: 1000000;
22 border: 1px solid #000;
23
24 }
25 .sp_debug_box .header
26 {
27 min-height: 10px;
28 background: #000;
29 color: #fff;
30 padding: 8px
31 }
32 .sp_debug_box .content_box
33 {
34 background: #ccc;
35 }
36 .content_box
37 {
38 padding: 8px;
39 }
40 </style>
41
42 <script language='javascript'>
43 jQuery(document).ready(function($)
44 {
45 $( ".sp_debug_box" ).draggable();
46
47 });
48 </script>
49
50
51 <div class='sp_debug_box'>
52 <div class='header'><?php echo esc_html($view->namespace) ?> Debug Box </div>
53 <a target="_blank" href='<?php echo $view->logLink ?>'>Logfile</a>
54 <div class='content_box'>
55
56 </div>
57 </div>
1 {
2 "name": "shortpixel/notices",
3 "description": "ShortPixel WordPress Notice System",
4 "version": "1.5",
5 "type": "library",
6 "license": "MIT",
7 "authors": [
8 {
9 "name": "Bas",
10 "email": "bas@weblogmechanic.com"
11 }
12 ],
13 "minimum-stability": "dev",
14 "require": {
15 "shortpixel/log" : "1.1.*"
16 },
17 "repositories": [
18 {
19 "packagist.org": false,
20 "type": "path",
21 "url": "../modules/",
22 "options": {
23 "symlink": true
24 }
25 }
26 ],
27
28 "autoload": {
29 "psr-4": { "ShortPixel\\Notices\\" : "src" }
30 }
31 }
1 <?php
2 namespace EnableMediaReplace\Notices;
3 use EnableMediaReplace\ShortPixelLogger\ShortPixelLogger as Log;
4
5 class NoticeController //extends ShortPixelController
6 {
7 protected static $notices = array();
8 protected static $instance = null;
9 protected static $cssHookLoaded = false; // prevent css output more than once.
10
11 protected $notice_displayed = array();
12
13 public $notice_count = 0;
14
15 protected $has_stored = false;
16
17 protected $notice_option = ''; // The wp_options name for notices here.
18
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';
25
26 add_action('wp_ajax_' . $this->notice_option, array($this, 'ajax_action'));
27
28 $this->loadNotices();
29 //$this->loadConfig();
30 }
31
32 public static function getInstance()
33 {
34 if ( self::$instance === null)
35 {
36 self::$instance = new NoticeController();
37 }
38
39 return self::$instance;
40 }
41
42 /** Reset all notices, before loading them, to ensure on updates / activations one starts fresh */
43 public static function resetNotices()
44 {
45 $ns = __NAMESPACE__;
46 $ns = substr($ns, 0, strpos($ns, '\\')); // try to get first part of namespace
47 $result = delete_option($ns . '-notices');
48 }
49
50 /** Load Notices Config File, if any
51 *
52 * [ Future Use ]
53 */
54 public function loadConfig()
55 {
56 return;
57 if (file_exists('../notice_config.json'))
58 {
59 $config = file_get_contents('../notice_config.json');
60 $json_config = json_decode($config);
61 }
62 }
63
64 public function loadIcons($icons)
65 {
66 foreach($icons as $name => $icon)
67 NoticeModel::setIcon($name, $icon);
68 }
69
70
71 protected function loadNotices()
72 {
73 $notices = get_option($this->notice_option, false);
74 $cnotice = (is_array($notices)) ? count($notices) : 0;
75
76 if ($notices !== false && is_array($notices))
77 {
78 $checked = array();
79 foreach($notices as $noticeObj)
80 {
81 if (is_object($noticeObj) && $noticeObj instanceOf NoticeModel)
82 {
83 $checked[] = $noticeObj;
84 }
85 }
86 self::$notices = $checked;
87 $this->has_stored = true;
88 }
89 else {
90 self::$notices = array();
91 $this->has_stored = false;
92 }
93 $this->countNotices();
94 }
95
96
97 protected function addNotice($message, $code, $unique)
98 {
99 $notice = new NoticeModel($message, $code);
100
101 if ($unique)
102 {
103 foreach(self::$notices as $nitem)
104 {
105 if ($nitem->message == $notice->message && $nitem->code == $notice->code) // same message.
106 return $nitem; // return the notice with the same message.
107 }
108 }
109 self::$notices[] = $notice;
110 $this->countNotices();
111
112 $this->update();
113 return $notice;
114 }
115
116 /** Update the notices to store, check what to remove, returns count. */
117 public function update()
118 {
119 if (! is_array(self::$notices) || count(self::$notices) == 0)
120 {
121 if ($this->has_stored)
122 delete_option($this->notice_option);
123
124 return 0;
125 }
126
127 $new_notices = array();
128 foreach(self::$notices as $item)
129 {
130 if (! $item->isDone() )
131 {
132 $new_notices[] = $item;
133 }
134 }
135
136 update_option($this->notice_option, $new_notices);
137 self::$notices = $new_notices;
138
139 return $this->countNotices();
140 }
141
142 public function countNotices()
143 {
144 $this->notice_count = count(self::$notices);
145 return $this->notice_count;
146 }
147
148
149 public function getNotices()
150 {
151 return self::$notices;
152 }
153
154 public function getNoticesForDisplay()
155 {
156 $newNotices = array();
157
158 foreach(self::$notices as $notice)
159 {
160 if ($notice->isDismissed()) // dismissed never displays.
161 continue;
162
163 if ($notice->isPersistent())
164 {
165 $id = $notice->getID();
166 if (! is_null($id) && ! in_array($id, $this->notice_displayed))
167 {
168 $notice->notice_action = $this->notice_option;
169 $newNotices[] = $notice;
170 $this->notice_displayed[] = $id;
171 }
172
173 }
174 else
175 $newNotices[] = $notice;
176
177
178 }
179 return $newNotices;
180 }
181
182
183 public function getNoticeByID($id)
184 {
185 foreach(self::$notices as $notice)
186 {
187 if ($notice->getID() == $id)
188 return $notice;
189 }
190
191 return false;
192 }
193
194 public static function removeNoticeByID($id)
195 {
196 $noticeController = self::getInstance();
197
198 for($i = 0; $i < count(self::$notices); $i++)
199 {
200 $item = self::$notices[$i];
201 if (is_object($item) && $item->getID() == $id)
202 {
203 Log::addDebug('Removing notice with ID ' . $id);
204 unset(self::$notices[$i]);
205 }
206 //if ($notice_item )
207 }
208 $noticeController->update();
209 }
210
211 public function ajax_action()
212 {
213 $response = array('result' => false, 'reason' => '');
214
215 if (isset($_POST['nonce']) && wp_verify_nonce( sanitize_key($_POST['nonce']), 'dismiss') )
216 {
217 if (isset($_POST['plugin_action']) && 'dismiss' == $_POST['plugin_action'] )
218 {
219 $id = (isset($_POST['id'])) ? sanitize_text_field( wp_unslash($_POST['id'])) : null;
220
221 if (! is_null($id))
222 {
223
224 $notice = $this->getNoticeByID($id);
225 }
226 else
227 {
228 $notice = false;
229 }
230
231 if(false !== $notice)
232 {
233 $notice->dismiss();
234 $this->update();
235 $response['result'] = true;
236 }
237 else
238 {
239 Log::addError('Notice not found when dismissing -> ' . $id, self::$notices);
240 $response['result'] = false;
241 $response['reason'] = ' Notice ' . $id . ' not found. ';
242 }
243
244 }
245
246 }
247 else
248 {
249 Log::addError('Wrong Nonce when dismissed notice. ');
250 $response['reason'] = 'wrong nonce';
251 }
252 wp_send_json($response);
253 }
254
255 /** Adds a notice, quick and fast method
256 * @param String $message The Message you want to notify
257 * @param Boolean $unique If unique, check to not repeat notice exact same text in notices. Discard if so
258 * @param int $code A value of messageType as defined in model
259 * @returm Object Instance of noticeModel
260 */
261
262 public static function addNormal($message, $unique = false)
263 {
264 $noticeController = self::getInstance();
265 $notice = $noticeController->addNotice($message, NoticeModel::NOTICE_NORMAL, $unique);
266 return $notice;
267
268 }
269
270 public static function addError($message, $unique = false)
271 {
272 $noticeController = self::getInstance();
273 $notice = $noticeController->addNotice($message, NoticeModel::NOTICE_ERROR, $unique);
274 return $notice;
275
276 }
277
278 public static function addWarning($message, $unique = false)
279 {
280 $noticeController = self::getInstance();
281 $notice = $noticeController->addNotice($message, NoticeModel::NOTICE_WARNING, $unique);
282 return $notice;
283 }
284
285 public static function addSuccess($message, $unique = false)
286 {
287 $noticeController = self::getInstance();
288 $notice = $noticeController->addNotice($message, NoticeModel::NOTICE_SUCCESS, $unique);
289 return $notice;
290
291 }
292
293 public static function addDetail($notice, $detail)
294 {
295 $noticeController = self::getInstance();
296 $notice->addDetail($detail);
297
298 // $notice_id = spl_object_id($notice);
299
300 $noticeController->update();
301 }
302
303 /** Make a regular notice persistent across multiple page loads
304 * @param $notice NoticeModel The Notice to make Persistent
305 * @param $key String Identifier of the persistent notice.
306 * @param $suppress Int When dismissed, time to stay dismissed
307 * @param $callback Function Callable function
308 */
309 public static function makePersistent($notice, $key, $suppress = -1, $callback = null)
310 {
311 $noticeController = self::getInstance();
312 $existing = $noticeController->getNoticeByID($key);
313
314 // if this key already exists, don't allow the new notice to be entered into the array. Remove it since it's already created.
315 if ($existing)
316 {
317 for($i = 0; $i < count(self::$notices); $i++)
318 {
319 $item = self::$notices[$i];
320
321 if ($item->message == $notice->message && $item->getID() == null)
322 {
323 if ($item->message != $existing->message) // allow the persistent message to be updated, if something else is served on this ID
324 {
325 $existing->message = $item->message;
326 }
327 unset(self::$notices[$i]);
328 }
329 //if ($notice_item )
330 }
331 }
332 else
333 {
334 $notice->setPersistent($key, $suppress, $callback); // set this notice persistent.
335 }
336
337 $noticeController->update();
338 }
339
340 public function admin_notices()
341 {
342 if ($this->countNotices() > 0)
343 {
344 if (! self::$cssHookLoaded)
345 {
346 add_action('admin_print_footer_scripts', array($this, 'printNoticeStyle'));
347 self::$cssHookLoaded = true;
348 }
349 foreach($this->getNoticesForDisplay() as $notice)
350 {
351 echo $notice->getForDisplay();
352 }
353 }
354 $this->update(); // puts views, and updates
355 }
356
357
358 public function printNoticeStyle()
359 {
360 if (file_exists(__DIR__ . '/css/notices.css'))
361 {
362 echo '<style>' . esc_html(file_get_contents(__DIR__ . '/css/notices.css')) . '</style>';
363 }
364 else {
365 Log::addDebug('Notices : css/notices.css could not be loaded');
366 }
367 }
368
369
370
371
372 }
1 .shortpixel.shortpixel-notice {
2 min-height: 75px;
3 padding: 8px;
4 display: flex;
5 align-items: center;
6 background: #fff;
7 padding: 1px 12px;
8 box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04);
9 border: 1px solid #c3c4c7;
10 margin: 15px 0;
11 border-left-width: 4px;
12 border-left-color: #72aee6;
13 position: relative;
14 }
15 .shortpixel.shortpixel-notice span {
16 vertical-align: middle;
17 }
18 .shortpixel.shortpixel-notice span.icon {
19 margin: 0 25px 0 0;
20 width: 80px;
21 }
22 .shortpixel.shortpixel-notice span.content {
23 padding: 8px 0;
24 word-wrap: break-word;
25 overflow: hidden;
26 }
27 .shortpixel.shortpixel-notice img {
28 display: inline-block;
29 margin: 0 25px 0 0;
30 max-height: 50px;
31 }
32 .shortpixel.shortpixel-notice .notice-dismiss {
33 margin-top: 6px;
34 }
35 .shortpixel.shortpixel-notice.notice-success {
36 border-left-color: #00a32a;
37 }
38 .shortpixel.shortpixel-notice.notice-warning {
39 border-left-color: #dba617;
40 }
41 .shortpixel.shortpixel-notice.notice-error {
42 border-left-color: #ff0000;
43 }
44 .shortpixel.shortpixel-notice.notice-info {
45 border-left-color: #72aee6;
46 }
47
48 /* In-view notice ( not on top, between the options ) - styled after WP notice */
49 .view-notice {
50 box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.1);
51 border: 4px solid #fff;
52 padding: 1px 12px;
53 }
54 .view-notice p {
55 margin: 1em 0 !important;
56 }
57 .view-notice.warning {
58 border-left-color: #ffb900;
59 }
60
61 .view-notice-row {
62 display: none;
63 }
64
65 /*# sourceMappingURL=notices.css.map */
1 {"version":3,"sourceRoot":"","sources":["notices.scss"],"names":[],"mappings":"AACA;EAGC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EAEC;;AACA;EACC;EACA;;AAED;EAEC;EACA;EACA;;AAKA;EAEE;EACA;EACA;;AAEF;EAEE;;AAGH;EAEC;;AAED;EAEC;;AAED;EAEC;;AAED;EAEE;;;AAIJ;AACA;EAGE;EACA;EAEA;;AACA;EACE;;AAEF;EAEE;;;AAIJ;EAEE","file":"notices.css"}
...\ No newline at end of file ...\ No newline at end of file
1
2 .shortpixel.shortpixel-notice
3 {
4
5 min-height: 75px;
6 padding: 8px;
7 display: flex;
8 align-items: center;
9 background: #fff;
10 padding: 1px 12px;
11 box-shadow: 0 1px 1px rgba(0,0,0,0.04);
12 border: 1px solid #c3c4c7;
13 margin: 15px 0;
14 border-left-width: 4px;
15 border-left-color: #72aee6;
16 position: relative;
17
18 span
19 {
20 vertical-align: middle;
21 &.icon {
22 margin: 0 25px 0 0;
23 width: 80px;
24 }
25 &.content
26 {
27 padding: 8px 0;
28 word-wrap: break-word;
29 overflow: hidden;
30 //display: flex; // magically fixes verticality issues
31 }
32 }
33
34 img
35 {
36 display:inline-block;
37 margin: 0 25px 0 0;
38 max-height: 50px;
39 }
40 .notice-dismiss
41 {
42 margin-top: 6px;
43 }
44
45 &.notice-success
46 {
47 border-left-color: #00a32a;
48 }
49 &.notice-warning
50 {
51 border-left-color: #dba617;
52 }
53 &.notice-error
54 {
55 border-left-color: #ff0000;
56 }
57 &.notice-info
58 {
59 border-left-color: #72aee6;
60 }
61 }
62
63 /* In-view notice ( not on top, between the options ) - styled after WP notice */
64 .view-notice
65 {
66
67 box-shadow: 0 1px 1px 0 rgba( 0, 0, 0, 0.1 );
68 border: 4px solid #fff;
69
70 padding: 1px 12px;
71 p {
72 margin: 1em 0 !important;
73 }
74 &.warning
75 {
76 border-left-color: #ffb900;
77 }
78 }
79
80 .view-notice-row
81 {
82 display: none;
83 }
1 {
2 "name": "shortpixel/replacer",
3 "description": "Content Replacer",
4 "version": 1.1,
5 "type": "library",
6 "license": "MIT",
7 "authors": [
8 {
9 "name": "Bas",
10 "email": "bas@weblogmechanic.com"
11 }
12 ],
13 "minimum-stability": "dev",
14 "require": {},
15 "autoload": {
16 "psr-4": { "ShortPixel\\Replacer\\" : "src" }
17 }
18 }
1 <?php
2 namespace EnableMediaReplace\Replacer\Libraries\Unserialize;
3
4
5 /**
6 * Worker implementation for identifying and skipping false-positives
7 * not to be substituted - like nested serializations in string literals.
8 *
9 * @internal This class should only be used by \Brumann\Polyfill\Unserialize
10 */
11 final class DisallowedClassesSubstitutor
12 {
13 const PATTERN_STRING = '#s:(\d+):(")#';
14 const PATTERN_OBJECT = '#(^|;)O:\d+:"([^"]*)":(\d+):\{#';
15
16 /**
17 * @var string
18 */
19 private $serialized;
20
21 /**
22 * @var string[]
23 */
24 private $allowedClasses;
25
26 /**
27 * Each array item consists of `[<offset-start>, <offset-end>]` and
28 * marks start and end positions of items to be ignored.
29 *
30 * @var array[]
31 */
32 private $ignoreItems = array();
33
34 /**
35 * @param string $serialized
36 * @param string[] $allowedClasses
37 */
38 public function __construct($serialized, array $allowedClasses)
39 {
40 $this->serialized = $serialized;
41 $this->allowedClasses = $allowedClasses;
42
43 $this->buildIgnoreItems();
44 $this->substituteObjects();
45 }
46
47 /**
48 * @return string
49 */
50 public function getSubstitutedSerialized()
51 {
52 return $this->serialized;
53 }
54
55 /**
56 * Identifies items to be ignored - like nested serializations in string literals.
57 */
58 private function buildIgnoreItems()
59 {
60 $offset = 0;
61 while (preg_match(self::PATTERN_STRING, $this->serialized, $matches, PREG_OFFSET_CAPTURE, $offset)) {
62 $length = (int)$matches[1][0]; // given length in serialized data (e.g. `s:123:"` --> 123)
63 $start = $matches[2][1]; // offset position of quote character
64 $end = $start + $length + 1;
65 $offset = $end + 1;
66
67 // serialized string nested in outer serialized string
68 if ($this->ignore($start, $end)) {
69 continue;
70 }
71
72 $this->ignoreItems[] = array($start, $end);
73 }
74 }
75
76 /**
77 * Substitutes disallowed object class names and respects items to be ignored.
78 */
79 private function substituteObjects()
80 {
81 $offset = 0;
82 while (preg_match(self::PATTERN_OBJECT, $this->serialized, $matches, PREG_OFFSET_CAPTURE, $offset)) {
83 $completeMatch = (string)$matches[0][0];
84 $completeLength = strlen($completeMatch);
85 $start = $matches[0][1];
86 $end = $start + $completeLength;
87 $leftBorder = (string)$matches[1][0];
88 $className = (string)$matches[2][0];
89 $objectSize = (int)$matches[3][0];
90 $offset = $end + 1;
91
92 // class name is actually allowed - skip this item
93 if (in_array($className, $this->allowedClasses, true)) {
94 continue;
95 }
96 // serialized object nested in outer serialized string
97 if ($this->ignore($start, $end)) {
98 continue;
99 }
100
101 $incompleteItem = $this->sanitizeItem($className, $leftBorder, $objectSize);
102 $incompleteItemLength = strlen($incompleteItem);
103 $offset = $start + $incompleteItemLength + 1;
104
105 $this->replace($incompleteItem, $start, $end);
106 $this->shift($end, $incompleteItemLength - $completeLength);
107 }
108 }
109
110 /**
111 * Replaces sanitized object class names in serialized data.
112 *
113 * @param string $replacement Sanitized object data
114 * @param int $start Start offset in serialized data
115 * @param int $end End offset in serialized data
116 */
117 private function replace($replacement, $start, $end)
118 {
119 $this->serialized = substr($this->serialized, 0, $start)
120 . $replacement . substr($this->serialized, $end);
121 }
122
123 /**
124 * Whether given offset positions should be ignored.
125 *
126 * @param int $start
127 * @param int $end
128 * @return bool
129 */
130 private function ignore($start, $end)
131 {
132 foreach ($this->ignoreItems as $ignoreItem) {
133 if ($ignoreItem[0] <= $start && $ignoreItem[1] >= $end) {
134 return true;
135 }
136 }
137
138 return false;
139 }
140
141 /**
142 * Shifts offset positions of ignore items by `$size`.
143 * This is necessary whenever object class names have been
144 * substituted which have a different length than before.
145 *
146 * @param int $offset
147 * @param int $size
148 */
149 private function shift($offset, $size)
150 {
151 foreach ($this->ignoreItems as &$ignoreItem) {
152 // only focus on items starting after given offset
153 if ($ignoreItem[0] < $offset) {
154 continue;
155 }
156 $ignoreItem[0] += $size;
157 $ignoreItem[1] += $size;
158 }
159 }
160
161 /**
162 * Sanitizes object class item.
163 *
164 * @param string $className
165 * @param int $leftBorder
166 * @param int $objectSize
167 * @return string
168 */
169 private function sanitizeItem($className, $leftBorder, $objectSize)
170 {
171 return sprintf(
172 '%sO:22:"__PHP_Incomplete_Class":%d:{s:27:"__PHP_Incomplete_Class_Name";%s',
173 $leftBorder,
174 $objectSize + 1, // size of object + 1 for added string
175 \serialize($className)
176 );
177 }
178 }
1 MIT License
2
3 Copyright (c) 2016-2019 Denis Brumann
4
5 Permission is hereby granted, free of charge, to any person obtaining a copy
6 of this software and associated documentation files (the "Software"), to deal
7 in the Software without restriction, including without limitation the rights
8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 copies of the Software, and to permit persons to whom the Software is
10 furnished to do so, subject to the following conditions:
11
12 The above copyright notice and this permission notice shall be included in all
13 copies or substantial portions of the Software.
14
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 SOFTWARE.
1 Polyfill unserialize [![Build Status](https://travis-ci.org/dbrumann/polyfill-unserialize.svg?branch=master)](https://travis-ci.org/dbrumann/polyfill-unserialize)
2 ===
3
4 Backports unserialize options introduced in PHP 7.0 to older PHP versions.
5 This was originally designed as a Proof of Concept for Symfony Issue
6 [#21090](https://github.com/symfony/symfony/pull/21090).
7
8 You can use this package in projects that rely on PHP versions older than
9 PHP 7.0. In case you are using PHP 7.0+ the original `unserialize()` will be
10 used instead.
11
12 From the [documentation](https://secure.php.net/manual/en/function.unserialize.php):
13
14 > **Warning**
15 >
16 > Do not pass untrusted user input to unserialize() regardless of the options
17 > value of allowed_classes. Unserialization can result in code being loaded and
18 > executed due to object instantiation and autoloading, and a malicious user
19 > may be able to exploit this. Use a safe, standard data interchange format
20 > such as JSON (via json_decode() and json_encode()) if you need to pass
21 > serialized data to the user.
22
23 Requirements
24 ------------
25
26 - PHP 5.3+
27
28 Installation
29 ------------
30
31 You can install this package via composer:
32
33 ```bash
34 composer require brumann/polyfill-unserialize "^2.0"
35 ```
36
37 Older versions
38 --------------
39
40 You can find the most recent 1.x versions in the branch with the same name:
41
42 * [dbrumann/polyfill-unserialize/tree/1.x](https://github.com/dbrumann/polyfill-unserialize/tree/1.x)
43
44 Upgrading
45 ---------
46
47 Upgrading from 1.x to 2.0 should be seamless and require no changes to code
48 using the library. There are no changes to the public API, i.e. the names for
49 classes, methods and arguments as well as argument order and types remain the
50 same. Version 2.x uses a completely different approach for substituting
51 disallowed classes, which is why we chose to use a new major release to prevent
52 issues from unknown side effects in existing installations.
53
54 Known Issues
55 ------------
56
57 There is a mismatch in behavior when `allowed_classes` in `$options` is not
58 of the correct type (array or boolean). PHP 7.0 will not issue a warning that
59 an invalid type was provided. This library will trigger a warning, similar to
60 the one PHP 7.1+ will raise and then continue, assuming `false` to make sure
61 no classes are deserialized by accident.
62
63 Tests
64 -----
65
66 You can run the test suite using PHPUnit. It is intentionally not bundled as
67 dev dependency to make sure this package has the lowest restrictions on the
68 implementing system as possible.
69
70 Please read the [PHPUnit Manual](https://phpunit.de/manual/current/en/installation.html)
71 for information how to install it on your system.
72
73 Please make sure to pick a compatible version. If you use PHP 5.6 you should
74 use PHPUnit 5.7.27 and for older PHP versions you should use PHPUnit 4.8.36.
75 Older versions of PHPUnit might not support namespaces, meaning they will not
76 work with the tests. Newer versions only support PHP 7.0+, where this library
77 is not needed anymore.
78
79 You can run the test suite as follows:
80
81 ```bash
82 phpunit -c phpunit.xml.dist tests/
83 ```
84
85 Contributing
86 ------------
87
88 This package is considered feature complete. As such I will likely not update
89 it unless there are security issues.
90
91 Should you find any bugs or have questions, feel free to submit an Issue or a
92 Pull Request on GitHub.
93
94 Development setup
95 -----------------
96
97 This library contains a docker setup for development purposes. This allows
98 running the code on an older PHP version without having to install it locally.
99
100 You can use the setup as follows:
101
102 1. Go into the project directory
103
104 1. Build the docker image
105
106 ```
107 docker build -t polyfill-unserialize .
108 ```
109
110 This will download a debian/jessie container with PHP 5.6 installed. Then
111 it will download an appropriate version of phpunit for this PHP version.
112 It will also download composer. It will set the working directory to `/opt/app`.
113 The resulting image is tagged as `polyfill-unserialize`, which is the name
114 we will refer to, when running the container.
115
116 1. You can then run a container based on the image, which will run your tests
117
118 ```
119 docker run -it --rm --name polyfill-unserialize-dev -v "$PWD":/opt/app polyfill-unserialize
120 ```
121
122 This will run a docker container based on our previously built image.
123 The container will automatically be removed after phpunit finishes.
124 We name the image `polyfill-unserialize-dev`. This makes sure only one
125 instance is running and that we can easily identify a running container by
126 its name, e.g. in order to remove it manually.
127 We mount our current directory into the container's working directory.
128 This ensures that tests run on our current project's state.
129
130 You can repeat the final step as often as you like in order to run the tests.
131 The output should look something like this:
132
133 ```bash
134 dbr:polyfill-unserialize/ (improvement/dev_setup*) $ docker run -it --rm --name polyfill-unserialize-dev -v "$PWD":/opt/app polyfill-unserialize
135 Loading composer repositories with package information
136 Installing dependencies (including require-dev) from lock file
137 Nothing to install or update
138 Generating autoload files
139 PHPUnit 5.7.27 by Sebastian Bergmann and contributors.
140
141 ...................... 22 / 22 (100%)
142
143 Time: 167 ms, Memory: 13.25MB
144
145 OK (22 tests, 31 assertions)
146 ```
147
148 When you are done working on the project you can free up disk space by removing
149 the initially built image:
150
151 ```
152 docker image rm polyfill-unserialize
153 ```
1 <?php
2 namespace EnableMediaReplace\Replacer\Libraries\Unserialize;
3
4 // Taken from : https://github.com/dbrumann/polyfill-unserialize/
5 final class Unserialize
6 {
7 /**
8 * @see https://secure.php.net/manual/en/function.unserialize.php
9 *
10 * @param string $serialized Serialized data
11 * @param array $options Associative array containing options
12 *
13 * @return mixed
14 */
15 public static function unserialize($serialized, array $options = array())
16 {
17 if (PHP_VERSION_ID >= 70000) {
18 return \unserialize($serialized, $options);
19 }
20 if (!array_key_exists('allowed_classes', $options) || true === $options['allowed_classes']) {
21 return \unserialize($serialized);
22 }
23 $allowedClasses = $options['allowed_classes'];
24 if (false === $allowedClasses) {
25 $allowedClasses = array();
26 }
27 if (!is_array($allowedClasses)) {
28 $allowedClasses = array();
29 trigger_error(
30 'unserialize(): allowed_classes option should be array or boolean',
31 E_USER_WARNING
32 );
33 }
34
35 $worker = new DisallowedClassesSubstitutor($serialized, $allowedClasses);
36
37 return \unserialize($worker->getSubstitutedSerialized());
38 }
39 }
1 <?php
2 namespace EnableMediaReplace\Replacer\Modules;
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('shortpixel/replacer/custom_replace_query', array($this, 'addElementor'), 10, 4); // custom query for elementor \ // problem
23 // @todo Fix this for SPIO
24 //add_action('enable-media-replace-upload-done', array($this, 'removeCache') );
25 }
26 }
27
28 public function addElementor($items, $base_url, $search_urls, $replace_urls)
29 {
30 $base_url = $this->addSlash($base_url);
31 $el_search_urls = $search_urls; //array_map(array($this, 'addslash'), $search_urls);
32 $el_replace_urls = $replace_urls; //array_map(array($this, 'addslash'), $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 addSlash($value)
38 {
39 global $wpdb;
40 $value= ltrim($value, '/'); // for some reason the left / isn't picked up by Mysql.
41 $value= str_replace('/', '\/', $value);
42 $value = $wpdb->esc_like(($value)); //(wp_slash) / str_replace('/', '\/', $value);
43
44 return $value;
45 }
46
47 protected function elementor_is_active()
48 {
49 $bool = false;
50
51 if (defined('ELEMENTOR_VERSION'))
52 $bool = true;
53
54 return apply_filters('emr/externals/elementor_is_active', $bool); // manual override
55 }
56
57 public function removeCache()
58 {
59 \Elementor\Plugin::$instance->files_manager->clear_cache();
60 }
61 }
1 <?php
2 namespace EnableMediaReplace\Replacer\Modules;
3 // Note! This class doubles as integration for both Visual Composer *and* WP Bakery. They both need URLENCODE.
4 class WpBakery
5 {
6 private static $instance;
7
8 protected $queryKey = 'wpbakery';
9
10 public static function getInstance()
11 {
12 if (is_null(self::$instance))
13 self::$instance = new WpBakery();
14
15 return self::$instance;
16 }
17
18 public function __construct()
19 {
20 if ($this->bakery_is_active()) // elementor is active
21 {
22 add_filter('shortpixel/replacer/custom_replace_query', array($this, 'addURLEncoded'), 10, 4); // custom query for elementor \ // problem
23 }
24 }
25
26 public function addUrlEncoded($items, $base_url, $search_urls, $replace_urls)
27 {
28 $base_url = $this->addEncode($base_url);
29 $el_search_urls = array_map(array($this, 'addEncode'), $search_urls);
30 $el_replace_urls = array_map(array($this, 'addEncode'), $replace_urls);
31 $items[$this->queryKey] = array('base_url' => $base_url, 'search_urls' => $el_search_urls, 'replace_urls' => $el_replace_urls);
32 return $items;
33 }
34
35 public function addEncode($value)
36 {
37 return urlencode($value);
38 }
39
40 protected function bakery_is_active()
41 {
42 $bool = false;
43
44 // did_action -> wpbakery , VCV_version -> detect Visual Composer
45 if (did_action('vc_plugins_loaded') || defined('VCV_VERSION'))
46 $bool = true;
47
48 return apply_filters('emr/externals/urlencode_is_active', $bool); // manual override
49 }
50 }
1 <?php
2 namespace EnableMediaReplace\Replacer\Modules;
3 use EnableMediaReplace\ShortPixelLogger\ShortPixelLogger as Log;
4
5 // Integration to reset indexes of Yoast (used for Og:image) when something is converted.
6 class YoastSeo
7 {
8
9 private $yoastTable;
10 private static $instance;
11
12 public static function getInstance()
13 {
14 if (is_null(self::$instance))
15 self::$instance = new YoastSeo();
16
17 return self::$instance;
18 }
19
20 public function __construct()
21 {
22 if (true === $this->yoast_is_active()) // elementor is active
23 {
24 global $wpdb;
25 $this->yoastTable = $wpdb->prefix . 'yoast_indexable';
26
27 add_action('shortpixel/replacer/replace_urls', array($this, 'removeIndexes'),10,2);
28 }
29 }
30
31 public function removeIndexes($search_urls, $replace_urls)
32 {
33 global $wpdb;
34
35 $sql = 'DELETE FROM ' . $this->yoastTable . ' WHERE ';
36 $prepare = array();
37
38 $base = isset($search_urls['base']) ? $search_urls['base'] : null;
39 $file = isset($search_urls['file']) ? $search_urls['file'] : null;
40
41 if (! is_null($base))
42 {
43 $querySQL = $sql . ' twitter_image like %s or open_graph_image like %s ';
44 $querySQL = $wpdb->prepare($querySQL, '%' . $base . '%', '%' . $base . '%');
45
46 $wpdb->query($querySQL);
47 }
48
49 if (! is_null($file))
50 {
51 $querySQL = $sql . ' twitter_image like %s or open_graph_image like %s ';
52 $querySQL = $wpdb->prepare($querySQL, '%' . $file . '%', '%' . $file . '%');
53
54 $wpdb->query($querySQL);
55 }
56
57 }
58
59 protected function yoast_is_active()
60 {
61 if (defined('WPSEO_VERSION'))
62 {
63 return true;
64 }
65 return false;
66 }
67
68
69
70
71 }
1 <?php
2 namespace EnableMediaReplace\Controller;
3 use EnableMediaReplace\Notices\NoticeController as Notices;
4 use EnableMediaReplace\ShortPixelLogger\ShortPixelLogger as Log;
5
6
7 if (! defined('ABSPATH')) {
8 exit; // Exit if accessed directly.
9 }
10
11 class RemoteNoticeController
12 {
13 protected static $instance;
14 private $remote_message_endpoint = 'https://api.shortpixel.com/v2/notices.php';
15
16
17 public function __construct()
18 {
19 $this->doRemoteNotices();
20 }
21
22 public static function getInstance()
23 {
24 if ( is_null(self::$instance))
25 {
26 self::$instance = new RemoteNoticeController();
27 }
28
29 return self::$instance;
30 }
31
32 protected function doRemoteNotices()
33 {
34 $notices = $this->get_remote_notices();
35
36 if (! is_array($notices))
37 return;
38
39 foreach($notices as $remoteNotice)
40 {
41 if (! isset($remoteNotice->id) && ! isset($remoteNotice->message))
42 return;
43
44 if (! isset($remoteNotice->type))
45 $remoteNotice->type = 'notice';
46
47 $message = esc_html($remoteNotice->message);
48 $id = sanitize_text_field($remoteNotice->id);
49
50 $noticeController = Notices::getInstance();
51 $noticeObj = $noticeController->getNoticeByID($id);
52
53 // not added to system yet
54 if ($noticeObj === false)
55 {
56 switch ($remoteNotice->type)
57 {
58 case 'warning':
59 $new_notice = Notices::addWarning($message);
60 break;
61 case 'error':
62 $new_notice = Notices::addError($message);
63 break;
64 case 'notice':
65 default:
66 $new_notice = Notices::addNormal($message);
67 break;
68 }
69
70 Notices::makePersistent($new_notice, $id, MONTH_IN_SECONDS);
71 }
72
73 }
74 }
75
76 private function get_remote_notices()
77 {
78 $transient_name = 'emr_remote_notice';
79 $transient_duration = DAY_IN_SECONDS;
80
81
82 // $keyControl = new apiKeyController();
83 //$keyControl->loadKey();
84
85 $notices = get_transient($transient_name);
86 $url = $this->remote_message_endpoint;
87 $url = add_query_arg(array( // has url
88 'version' => EMR_VERSION,
89 'plugin' => 'enable-media-replace',
90 'target' => 4,
91
92 ), $url);
93
94
95 if ( $notices === false || $notices == 'none' ) {
96 $notices_response = wp_safe_remote_request( $url );
97
98 $content = false;
99 if (! is_wp_error( $notices_response ) )
100 {
101 $notices = json_decode($notices_response['body']);
102
103 if (! is_array($notices))
104 $notices = 'none';
105
106 // Save transient anywhere to prevent over-asking when nothing good is there.
107 set_transient( $transient_name, 'true', $transient_duration );
108 }
109 else
110 {
111 set_transient( $transient_name, false, $transient_duration );
112 }
113 }
114
115 return $notices;
116 }
117
118 } // class
1 <?php
2 namespace EnableMediaReplace;
3
4 if (! defined('ABSPATH')) {
5 exit; // Exit if accessed directly.
6 }
7
8 use EnableMediaReplace as emr;
9 use EnableMediaReplace\ShortPixelLogger\ShortPixelLogger as Log;
10
11
12 abstract class ViewController
13 {
14
15 abstract function load();
16
17
18 const ERROR_UPLOAD_PERMISSION = 1;
19 const ERROR_IMAGE_PERMISSION = 2;
20 const ERROR_FORM = 3;
21 const ERROR_TIME = 4;
22 const ERROR_UPDATE_FAILED = 5;
23 const ERROR_SECURITY = 6;
24 const ERROR_UPLOAD_FAILED = 7;
25 const ERROR_NONCE = 8;
26 const ERROR_KEY = 9; // Missing key when replacing backgrounds.
27
28 // These synced with ReplaceController
29 const ERROR_TARGET_EXISTS = 20;
30 const ERROR_DESTINATION_FAIL = 21;
31 const ERROR_COPY_FAILED = 22;
32 const ERROR_UPDATE_POST = 23;
33 const ERROR_DIRECTORY_SECURITY = 24;
34 const ERROR_DIRECTORY_NOTEXIST = 25;
35
36 // Remove Background
37 const ERROR_DOWNLOAD_FAILED = 31;
38
39 protected static $viewsLoaded = array();
40
41 protected $view; // object to use in the view.
42 protected $url; // if controller is home to a page, sets the URL here. For redirects and what not.
43
44
45 public function __construct()
46 {
47 $this->view = new \stdClass;
48 }
49
50 protected function loadView($template = null, $unique = true)
51 {
52 if (is_null($template) )
53 {
54 return false;
55 }
56 elseif (strlen(trim($template)) == 0)
57 {
58 return false;
59 }
60
61 $view = $this->view;
62 $controller = $this;
63 $template_path = emr()->plugin_path('views/' . $template . '.php');
64
65 if (file_exists($template_path) === false)
66 {
67 Log::addError("View $template could not be found in " . $template_path,
68 array('class' => get_class($this)));
69 }
70 elseif ($unique === false || ! in_array($template, self::$viewsLoaded))
71 {
72 include($template_path);
73 self::$viewsLoaded[] = $template;
74 }
75 }
76
77 protected function viewError($errorCode, $errorData = array())
78 {
79 $message = $description = false;
80 switch($errorCode)
81 {
82 case self::ERROR_UPLOAD_PERMISSION:
83 $message = __('You don\'t have permission to upload images. Please refer to your administrator', 'enable-media-replace');
84 break;
85 case self::ERROR_IMAGE_PERMISSION:
86 $message = __('You don\'t have permission to edit this image', 'enable-media-replace');
87 break;
88 case self::ERROR_FORM:
89 $message = __('The form submitted is missing various fields', 'enable-media-replace');
90 break;
91 case self::ERROR_TIME:
92 $message = __('The custom time format submitted is invalid', 'enable-media-replace');
93 break;
94 case self::ERROR_UPDATE_FAILED:
95 $message = __('Updating the WordPress attachment failed', 'enable-media-replace');
96 break;
97 case self::ERROR_SECURITY:
98 $message = __('The file upload has been rejected for security reason. WordPress might not allow uploading this extension or filetype', 'enable-media-replace');
99 break;
100 case self::ERROR_UPLOAD_FAILED:
101 $message = __('The upload from your browser seem to have failed', 'enable-media-replace');
102 break;
103 case self::ERROR_TARGET_EXISTS:
104 $message = __('The target file already exists in this directory. Please try another name / directory', 'enable-media-replace');
105 $description = __('This error is shown because you try to move the image to another folder, which already has this file', 'enable-media-replace');
106 break;
107 case self::ERROR_DESTINATION_FAIL:
108 $message = __('Something went wrong while writing the file or directory', 'enable-media-replace');
109 break;
110 case self::ERROR_COPY_FAILED:
111 $message = __('Copying replacement file to destination failed', 'enable-media-replace');
112 break;
113 case self::ERROR_UPDATE_POST:
114 $message = __('Error updating WordPress post in the database', 'enable-media-replace');
115 break;
116 case self::ERROR_DIRECTORY_SECURITY:
117 $message = __('Specificed directory is outside the upload directory. This is not allowed for security reasons', 'enable-media-replace');
118 $path = isset($errorData['path']) ? $errorData['path'] : false;
119 $basedir = isset($errorData['basedir']) ? $errorData['basedir'] : false;
120
121 if ($path !== false && $basedir !== false)
122 {
123 $description = sprintf(__('Path: %s is not within basedir reported as: %s', 'shortpixel-image-optimiser'), $path, $basedir);
124 }
125 break;
126 case self::ERROR_DIRECTORY_NOTEXIST:
127 $message = __('Specificed new directory does not exist. Path must be a relative path from the upload directory and exist', 'enable-media-replace');
128 break;
129
130 case self::ERROR_NONCE:
131 $message = __('Fail to validate form nonce. Please try again', 'enable-media-replace');
132 $description = __('This can happen when the window is open for a long time and/or there has been a timeout. You can go back to previous screen and try again. If this happens each time when replacing, contact us', 'enable-media-replace');
133 break;
134
135 // Remove Background
136 case self::ERROR_DOWNLOAD_FAILED:
137 $message = __('Replacement Image could not be downloaded or does not exist', 'enable-media-replace');
138 break;
139
140 default:
141 $message = __('An unknown error has occured', 'enable-media-replace');
142 break;
143 }
144
145 if( false !== $message)
146 $this->view->errorMessage = $message;
147
148
149 if (false !== $description)
150 {
151 $this->view->errorDescription = $description;
152 }
153
154
155 $this->loadView('error');
156 exit();
157 }
158
159
160 protected function viewSuccess()
161 {
162 wp_enqueue_script('emr_success');
163 $this->loadView('success');
164 exit();
165 }
166
167 }
1 <?php
2
3 namespace EnableMediaReplace\ViewController;
4
5 use EnableMediaReplace\Replacer\Libraries\Unserialize\Unserialize;
6
7
8 if (! defined('ABSPATH')) {
9 exit; // Exit if accessed directly.
10 }
11
12 use EnableMediaReplace\ShortPixelLogger\ShortPixelLogger as Log;
13 use EnableMediaReplace\Controller\ReplaceController as ReplaceController;
14 use EnableMediaReplace\Api as Api;
15
16 class RemoveBackGroundViewController extends \EnableMediaReplace\ViewController
17 {
18 static $instance;
19
20 public function __construct()
21 {
22 parent::__construct();
23 }
24
25 public static function getInstance()
26 {
27 if (is_null(self::$instance))
28 self::$instance = new RemoveBackgroundViewController();
29
30 return self::$instance;
31 }
32
33 public function load()
34 {
35 if (!current_user_can('upload_files')) {
36 $this->viewError(self::ERROR_UPLOAD_PERMISSION);
37 // wp_die(esc_html__('You do not have permission to upload files.', 'enable-media-replace'));
38 }
39
40
41 $attachment_id = intval($_REQUEST['attachment_id']);
42 $attachment = get_post($attachment_id);
43
44 $uiHelper = \emr()->uiHelper();
45 $uiHelper->setPreviewSizes();
46 $uiHelper->setSourceSizes($attachment_id);
47
48 $replacer = new ReplaceController($attachment_id);
49 $file = $replacer->getSourceFile(true); // for display only
50
51 $defaults = array(
52 'bg_type' => 'transparent',
53 'bg_color' => '#ffffff',
54 'bg_transparency' => 100,
55 );
56 $settings = get_option('enable_media_replace', $defaults);
57 $settings = array_merge($defaults, $settings); // might miss some
58
59 $this->view->attachment = $attachment;
60 $this->view->settings = $settings;
61 $this->view->sourceFile = $file;
62
63 $this->loadView('prepare-remove-background');
64
65 }
66
67 // When the background has been posted - process.
68 public function loadPost()
69 {
70 if ( ! isset( $_POST['emr_nonce'] )
71 || ! wp_verify_nonce( $_POST['emr_nonce'], 'media_remove_background' ))
72 {
73 $this->viewError(self::ERROR_NONCE);
74 }
75
76 $key = isset($_POST['key']) ? sanitize_text_field($_POST['key']) : null;
77 if (is_null($key) || strlen($key) == 0)
78 {
79 $this->viewError(self::ERROR_KEY);
80 //wp_die(esc_html__('Error while sending form (no key). Please try again.', 'enable-media-replace'));
81 }
82
83 $post_id = isset($_POST['ID']) ? intval($_POST['ID']) : null; // sanitize, post_id.
84 if (is_null($post_id)) {
85 $this->viewError(self::ERROR_FORM);
86 // wp_die(esc_html__('Error in request. Please try again', 'enable-media-replace'));
87 }
88
89 $this->setView($post_id);
90 $result = $this->replaceBackground($post_id, $key);
91
92 if (false === $result->success)
93 {
94 $this->view->errorMessage = $result->message;
95 $this->viewError();
96 }
97 elseif (! file_exists($result->image))
98 {
99 $this->viewError(self::ERROR_DOWNLOAD_FAILED);
100 }
101
102 // $result = $replacer->replaceWith($result->image, $source->getFileName() , true);
103 //$params = array();
104 $replaceController = new ReplaceController($post_id);
105 $sourceFile = $replaceController->getSourceFile();
106
107 $datetime = current_time('mysql');
108
109 $params = array(
110 'post_id' => $post_id,
111 'replace_type' => ReplaceController::MODE_REPLACE,
112 'timestamp_replace' => ReplaceController::TIME_UPDATEMODIFIED,
113 'new_date' => $datetime,
114 'is_custom_date' => false,
115 'remove_background' => true,
116 'uploadFile' => $result->image,
117 'new_filename' => $sourceFile->getFileName(),
118 );
119
120
121 $check = $replaceController->setupParams($params);
122 $this->setView($post_id, $params);
123
124 if (false === $check)
125 {
126 $error = $replaceController->returnLastError();
127 $this->viewError($error);
128 }
129
130 $result = $replaceController->run();
131 if (true == $result)
132 {
133 $this->viewSuccess();
134 }
135
136 }
137
138 // Low init might only be w/ post_id ( error handling et al ), most advanced / nicer with params.
139 protected function setView($post_id, $params = array())
140 {
141 $uiHelper = \emr()->uiHelper();
142 $this->view->post_id = $post_id;
143 $this->view->postUrl = $uiHelper->getSuccesRedirect($post_id);
144 $this->view->emrUrl = $uiHelper->getFailedRedirect($post_id);
145
146 }
147
148
149 protected function replaceBackground($post_id, $key)
150 {
151 $api = new Api();
152 $result = $api->handleDownload($key);
153
154 return $result;
155 }
156
157
158
159 } // class
1 <?php
2 namespace EnableMediaReplace\ViewController;
3
4 if (! defined('ABSPATH')) {
5 exit; // Exit if accessed directly.
6 }
7
8 use EnableMediaReplace as emr;
9 use EnableMediaReplace\ShortPixelLogger\ShortPixelLogger as Log;
10 use EnableMediaReplace\Controller\ReplaceController as ReplaceController;
11
12 class ReplaceViewController extends \EnableMediaReplace\ViewController
13 {
14 static $instance;
15
16 public function __construct()
17 {
18 parent::__construct();
19 }
20
21 public static function getInstance()
22 {
23 if (is_null(self::$instance))
24 self::$instance = new ReplaceViewController();
25
26 return self::$instance;
27 }
28
29 public function load()
30 {
31
32 $attachment_id = intval($_GET['attachment_id']);
33 $attachment = get_post($attachment_id);
34
35 if (! \emr()->checkImagePermission($attachment))
36 {
37 $this->viewError(self::ERROR_IMAGE_PERMISSION);
38 wp_die( esc_html__('You do not have permission to upload files for this author.', 'enable-media-replace') );
39 }
40
41 $replacer = new ReplaceController($attachment_id);
42
43 $file = $replacer->getSourceFile(true);
44 /* $filepath = $file->getFullPath();
45 $filename = $file->getFileName();
46 $filetype = $file->getExtension(); */
47 $source_mime = get_post_mime_type($attachment_id);
48
49 $uiHelper = \emr()->uiHelper();
50 $uiHelper->setPreviewSizes();
51 $uiHelper->setSourceSizes($attachment_id);
52
53 $defaults = array(
54 'replace_type' => 'replace',
55 'timestamp_replace' => ReplaceController::TIME_UPDATEMODIFIED,
56 'custom_date' => date("Y-m-d H:i:s"),
57 'new_location' => false,
58 'new_location_dir' => false,
59 );
60 $settings = get_option('enable_media_replace', $defaults);
61
62 $this->view->attachment = $attachment;
63 $this->view->sourceFile = $file;
64 $this->view->sourceMime = $source_mime;
65 $this->view->settings = array_merge($defaults, $settings); // might miss some
66
67 // Indicates if file can be moved to other location. Can't be done when offloaded.
68 $this->view->is_movable = apply_filters('emr/replace/file_is_movable', true, $attachment_id);
69
70 $uploadDir = wp_upload_dir();
71 $basedir = trailingslashit($uploadDir['basedir']);
72
73 $this->view->custom_basedir = $basedir;
74
75
76 $this->loadView('screen');
77
78 }
79
80 }
1 <?php
2 namespace EnableMediaReplace\ViewController;
3
4 if (! defined('ABSPATH')) {
5 exit; // Exit if accessed directly.
6 }
7
8 use EnableMediaReplace as emr;
9 use EnableMediaReplace\ShortPixelLogger\ShortPixelLogger as Log;
10 use EnableMediaReplace\Controller\UploadController as UploadController;
11 use EnableMediaReplace\Controller\ReplaceController as ReplaceController;
12
13
14 class UploadViewController extends \EnableMediaReplace\ViewController
15 {
16 static $instance;
17
18
19 public function __construct()
20 {
21 parent::__construct();
22 }
23
24 public static function getInstance()
25 {
26 if (is_null(self::$instance))
27 self::$instance = new UploadViewController();
28
29 return self::$instance;
30 }
31
32 public function load()
33 {
34
35 // No form submit?
36 if (count($_POST) == 0)
37 {
38 $post_id = isset($_REQUEST['attachment_id']) ? intval($_REQUEST['attachment_id']) : null;
39 $this->setView($post_id);
40
41 if (isset($_GET['emr_success']))
42 {
43 $this->viewSuccess();
44 }
45
46 }
47
48 if ( ! isset( $_POST['emr_nonce'] )
49 || ! wp_verify_nonce( $_POST['emr_nonce'], 'media_replace_upload' ))
50 {
51 $this->viewError(self::ERROR_NONCE);
52 }
53
54 if (!current_user_can('upload_files')) {
55 $this->viewError(self::ERROR_UPLOAD_PERMISSION);
56 // wp_die(esc_html__('You do not have permission to upload files.', 'enable-media-replace'));
57 }
58
59 $post_id = isset($_POST['ID']) ? intval($_POST['ID']) : null; // sanitize, post_id.
60 if (is_null($post_id)) {
61 $this->viewError(self::ERROR_FORM);
62 // wp_die(esc_html__('Error in request. Please try again', 'enable-media-replace'));
63 }
64 $attachment = get_post($post_id);
65
66 if (! emr()->checkImagePermission($attachment)) {
67 $this->viewError(self::ERROR_IMAGE_PERMISSION);
68 // wp_die(esc_html__('You do not have permission to upload files for this author.', 'enable-media-replace'));
69 }
70
71 $params = $this->getPost();
72
73 // UploadController here / replacerController here with save Settings as well? s
74 $this->updateSettings($params);
75 $this->setView($post_id, $params); // set variables needed for view.
76
77 $replaceController = new ReplaceController($post_id);
78 $check = $replaceController->setupParams($params);
79
80 if (false === $check)
81 {
82 $error = $replaceController->returnLastError();
83 $data = $replaceController->returnLastErrorData();
84 $this->viewError($error, $data);
85 }
86
87 $result = $replaceController->run();
88
89 if (true == $result)
90 {
91 $this->viewSuccess();
92 }
93 }
94
95
96 protected function getPost()
97 {
98 $ID = intval($_POST["ID"]); // legacy
99 $replace_type = isset($_POST["replace_type"]) ? sanitize_text_field($_POST["replace_type"]) : false;
100 $timestamp_replace = isset($_POST['timestamp_replace']) ? intval($_POST['timestamp_replace']) : ReplaceController::TIME_UPDATEMODIFIED;
101
102 $remove_background = ( isset( $_POST['remove_after_progress'] ) ) ? true : false;
103
104 $do_new_location = isset($_POST['new_location']) ? true : false;
105 $do_new_location = apply_filters('emr/replace/file_is_movable', $do_new_location, $ID);
106 $new_location_dir = isset($_POST['location_dir']) ? sanitize_text_field($_POST['location_dir']) : null;
107
108 $is_custom_date = false;
109
110 switch ($timestamp_replace) {
111 case ReplaceController::TIME_UPDATEALL:
112 case ReplaceController::TIME_UPDATEMODIFIED:
113 $datetime = current_time('mysql');
114 break;
115 case ReplaceController::TIME_CUSTOM:
116 $custom_date = $_POST['custom_date_formatted'];
117 $custom_hour = str_pad($_POST['custom_hour'], 2, 0, STR_PAD_LEFT);
118 $custom_minute = str_pad($_POST['custom_minute'], 2, 0, STR_PAD_LEFT);
119
120 // create a mysql time representation from what we have.
121 Log::addDebug('Custom Date - ' . $custom_date . ' ' . $custom_hour . ':' . $custom_minute);
122 $custom_date = \DateTime::createFromFormat('Y-m-d G:i', $custom_date . ' ' . $custom_hour . ':' . $custom_minute);
123 if ($custom_date === false) {
124 $this->viewError(self::ERROR_TIME);
125 }
126 $datetime = $custom_date->format("Y-m-d H:i:s");
127 $is_custom_date = true;
128 break;
129 }
130
131 list($uploadFile, $new_filename) = $this->getUpload();
132
133 return array(
134 'post_id' => $ID,
135 'replace_type' => $replace_type,
136 'timestamp_replace' => $timestamp_replace,
137 'new_date' => $datetime,
138 'new_location' => $do_new_location,
139 'location_dir' => $new_location_dir,
140 'is_custom_date' => $is_custom_date,
141 'remove_background' => $remove_background,
142 'uploadFile' => $uploadFile,
143 'new_filename' => $new_filename,
144 );
145
146 }
147
148 // Low init might only be w/ post_id ( error handling et al ), most advanced / nicer with params.
149 protected function setView($post_id, $params = array())
150 {
151 $uiHelper = \emr()->uiHelper();
152 $this->view->post_id = $post_id;
153 $this->view->postUrl = $uiHelper->getSuccesRedirect($post_id);
154 $this->view->emrUrl = $uiHelper->getFailedRedirect($post_id);
155
156 if (isset($params['remove_background']) && true === $params['remove_background'])
157 {
158 $this->view->postUrl = $uiHelper->getBackgroundRemoveRedirect($post_id);
159 }
160 }
161
162
163 protected function updateSettings($params)
164 {
165 $settings = get_option('enable_media_replace', array()); // save settings and show last loaded.
166 $settings['replace_type'] = $params['replace_type'];
167 $settings['timestamp_replace'] = $params['timestamp_replace'];
168 $settings['new_location'] = $params['new_location'];
169 $settings['new_location_dir'] = $params['location_dir'];
170
171 if (true === $params['is_custom_date'])
172 {
173 $settings['custom_date'] = $params['new_date'];
174 }
175 update_option('enable_media_replace', $settings, false);
176
177 }
178
179 protected function getUpload()
180 {
181 if (is_uploaded_file($_FILES["userfile"]["tmp_name"])) {
182 Log::addDebug('Uploaded Files', $_FILES['userfile']);
183
184 // New method for validating that the uploaded file is allowed, using WP:s internal wp_check_filetype_and_ext() function.
185 $filedata = wp_check_filetype_and_ext($_FILES["userfile"]["tmp_name"], $_FILES["userfile"]["name"]);
186
187 Log::addDebug('Data after check', $filedata);
188 if (isset($_FILES['userfile']['error']) && $_FILES['userfile']['error'] > 0) {
189 //$e = new RunTimeException('File Uploaded Failed');
190 //Notices::addError($e->getMessage());
191 // wp_safe_redirect($redirect_error);
192 $this->viewError(self::ERROR_UPDATE_FAILED);
193 // exit();
194 }
195
196 if ($filedata["ext"] == false && ! current_user_can('unfiltered_upload')) {
197 $this->viewError(self::ERROR_SECURITY);
198 }
199
200 // Here we have the uploaded file
201 $new_filename = $_FILES["userfile"]["name"];
202 $new_filetype = $filedata["type"] ? $filedata["type"] : $_FILES['userfile']['type'];
203
204 return array($_FILES["userfile"]["tmp_name"], $new_filename);
205 // Execute hook actions - thanks rubious for the suggestion!
206 }
207 $this->viewError(self::ERROR_UPLOAD_FAILED);
208 }
209
210
211
212
213 } // class
1 <?php
2 namespace EnableMediaReplace;
3
4 use EnableMediaReplace\ShortPixelLogger\ShortPixelLogger as Log;
5 use EnableMediaReplace\Api as Api;
6
7 class Ajax {
8 public function __construct() {
9 $endpoints = array(
10 'remove_background',
11
12 );
13 foreach ( $endpoints as $action ) {
14 add_action( "wp_ajax_emr_{$action}", array( $this, $action ) );
15 }
16 }
17
18 public function remove_background() {
19 if ( $this->check_nonce() ) {
20 $api = new Api;
21 $response = $api->request( $_POST );
22 wp_send_json($response);
23 }
24 else {
25 die('Wrong nonce');
26 }
27 }
28
29 private function check_nonce() {
30 $nonce = isset( $_POST['nonce'] ) ? sanitize_text_field( $_POST['nonce'] ) : '';
31 $action = isset( $_POST['action'] ) ? sanitize_text_field( $_POST['action'] ) : '';
32 return wp_verify_nonce( $nonce, $action );
33 }
34 }
35
36
37 new Ajax();
1 <?php
2 /**
3 * This page contains api class.
4 */
5 namespace EnableMediaReplace;
6
7 use EnableMediaReplace\ShortPixelLogger\ShortPixelLogger as Log;
8 use EnableMediaReplace\Controller\ReplaceController as ReplaceController;
9
10
11 use Exception;
12 use stdClass;
13 /**
14 * This class contains api methods
15 */
16 class Api {
17
18 /**
19 * Request Counter
20 *
21 * @var int $counter
22 */
23 private $counter = 0;
24
25 /**
26 * ShortPixel api url
27 *
28 * @var string $url
29 */
30 private $url = 'http://api.shortpixel.com/v2/free-reducer.php';
31
32 /**
33 * ShortPixel api request headers
34 *
35 * @var array $headers
36 */
37 private $headers = array(
38 'Content-Type: application/json',
39 'Accept: application/json',
40 );
41
42 private $refresh = true; // only first request should be fresh
43
44
45
46 public function __construct()
47 {
48
49 }
50 /**
51 * Create ShortPixel api request
52 *
53 * @param array $data
54 * @return stdClass $result
55 */
56 public function request( array $posted_data ) {
57 $bg_remove = '1';
58 $compression_level = 0; // intval($posted_data['compression_level']); // off for now.
59
60 $attachment_id = isset($_POST['attachment_id']) ? intval($_POST['attachment_id']) : null;
61 $attachment = get_post($attachment_id);
62
63
64 if (is_null($attachment_id))
65 {
66 $result = $this->getResponseObject();
67 $result->success = false;
68 $result->message = __('No attachment ID given', 'enable-media-replace');
69 return $result;
70 }
71
72 if (! emr()->checkImagePermission($attachment)) {
73 $result = $this->getResponseObject();
74 $result->success = false;
75 $result->message = __('No permission for user', 'enable-media-replace');
76 return $result;
77 }
78
79 $replaceController = new ReplaceController($attachment_id);
80 $url = $replaceController->getSourceUrl();
81
82 $settings = get_option('enable_media_replace', array()); // save settings and show last loaded.
83 $settings['bg_type'] = isset($_POST['background']['type']) ? sanitize_text_field($_POST['background']['type']) : false;
84 $settings['bg_color'] = isset($_POST['background']['color']) ? sanitize_text_field($_POST['background']['color']) : '#ffffff'; // default to white.
85 $settings['bg_transparency'] = isset($_POST['background']['transparency']) ? sanitize_text_field($_POST['background']['transparency']) : false;
86
87 update_option('enable_media_replace', $settings, false);
88
89
90 if ( 'solid' === $posted_data['background']['type'] ) {
91 $bg_remove = $posted_data['background']['color'];
92
93 $transparency = isset($posted_data['background']['transparency']) ? intval($posted_data['background']['transparency']) : -1;
94 // if transparancy without acceptable boundaries, add it to color ( as rgba I presume )
95 if ($transparency >= 0 && $transparency < 100)
96 {
97 if ($transparency == 100)
98 $transparency = 'FF';
99
100 // Strpad for lower than 10 should add 09, 08 etc.
101 $bg_remove .= str_pad($transparency, 2, '0', STR_PAD_LEFT);
102 }
103 }
104
105
106
107 $data = array(
108 'plugin_version' => EMR_VERSION,
109 'bg_remove' => $bg_remove,
110 'urllist' => array( urlencode( esc_url($url) ) ),
111 'lossy' => $compression_level,
112 'refresh' => $this->refresh,
113 );
114
115 $request = array(
116 'method' => 'POST',
117 'timeout' => 60,
118 'headers' => $this->headers,
119 'body' => json_encode( $data ),
120
121 );
122
123 $settingsData = '';
124 //unset($settingsData['url']);
125
126 foreach($data as $key => $val)
127 {
128 if ($key == 'urllist' || $key == 'refresh')
129 {
130 continue;
131 }
132 $settingsData .= " $key:$val ";
133 }
134
135
136 //we need to wait a bit until we try to check if the image is ready
137 if ($this->counter > 0)
138 sleep( $this->counter + 3 );
139
140 $this->counter++;
141
142 $result = $this->getResponseObject();
143
144 if ( $this->counter < 10 ) {
145 try {
146
147 Log::addDebug('Sending request', $request);
148 $response = wp_remote_post( $this->url, $request );
149
150 $this->refresh = false;
151
152 if ( is_wp_error( $response ) ) {
153 $result->message = $response->get_error_message();
154 } else {
155
156 $json = json_decode( $response['body'] );
157
158 Log::addDebug('Response Json', $json);
159 if ( is_array( $json ) && '2' === $json[0]->Status->Code ) {
160 $result->success = true;
161
162 if ( '1' === $compression_level || '2' === $compression_level ) {
163 $result->image = $json[0]->LossyURL;
164 } else {
165 $result->image = $json[0]->LosslessURL;
166 }
167
168 $key = $this->handleSuccess($result);
169 $result->key = $key;
170 $result->url = $url;
171 $result->image = add_query_arg('ts', time(), $result->image);
172
173 $result->settings = $settingsData;
174
175 // $this->handleSuccess($result);
176 } elseif ( is_array( $json ) && '1' === $json[0]->Status->Code ) {
177 return $this->request( $posted_data );
178 } else {
179 if (is_array($json))
180 {
181 $result->message = $json[0]->Status->Message;
182 }
183 elseif (is_object($json) && property_exists($json, 'Status'))
184 {
185 $result->message = $json->Status->Message;
186 }
187 }
188 }
189 } catch ( Exception $e ) {
190 $result->message = $e->getMessage();
191 }
192 } else {
193 $result->message = __( 'The background could not be removed in a reasonable amount of time. The file might be too big, or the API could be busy. Please try again later!', 'enable-media-replace' );
194 }
195
196 return $result;
197 }
198
199 public function handleSuccess($result)
200 {
201 // $fs = emr()->filesystem();
202 // $result = $fs->downloadFile($result->image, wp_tempnam($result->image));
203 $nonce = isset($_POST['nonce']) ? sanitize_text_field($_POST['nonce']) : wp_create_nonce();
204 $key = wp_hash($nonce . $result->image, 'logged_in');
205
206 set_transient('emr_' . $key, $result->image, 30 * MINUTE_IN_SECONDS);
207 return $key;
208 }
209
210 public function handleDownload($key)
211 {
212 $url = get_transient('emr_' . $key);
213 $result = $this->getResponseObject();
214
215 if ($url === false)
216 {
217 $result->message = __('This file seems not available anymore. Please try again', 'enable-media-replace');
218 return $result;
219 }
220
221 $fs = emr()->filesystem();
222 $target = wp_tempnam($url);
223
224 $bool = $fs->downloadFile($url, $target);
225
226 if ($bool === false)
227 {
228 $result->message = __('Download failed', 'enable-media-replace');
229 }
230 else {
231 $result->success = true;
232 $result->image = $target;
233 }
234 return $result;
235 }
236
237 protected function getResponseObject()
238 {
239 $result = new stdClass;
240 $result->success = false;
241 $result->image = null;
242 $result->message = null;
243
244 return $result;
245 }
246
247 }
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
9 protected $has_w3tc = false;
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 {
17
18 }
19
20 /** Checks which cache plugins are active on the moment a flush is needed */
21 public function checkCaches()
22 {
23 if ( function_exists( 'w3tc_pgcache_flush' ) )
24 $this->has_w3tc = true;
25
26 if ( function_exists('wp_cache_clean_cache') )
27 $this->has_supercache = true;
28
29 if ( class_exists( 'WpeCommon' ) )
30 $this->has_wpengine = true;
31
32 global $wp_fastest_cache;
33 if ( method_exists( 'WpFastestCache', 'deleteCache' ) && !empty( $wp_fastest_cache ) )
34 $this->has_fastestcache = true;
35
36 // SG SuperCacher
37 if (function_exists('sg_cachepress_purge_cache')) {
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 }
49
50 /* Tries to flush cache there were we have issues
51 *
52 * @param Array $args Argument Array to provide data.
53 */
54 public function flushCache($args)
55 {
56 $defaults = array(
57 'flush_mode' => 'post',
58 'post_id' => 0,
59 );
60
61 $args = wp_parse_args($args, $defaults);
62 $post_id = $args['post_id']; // can be zero!
63
64 // important - first check the available cache plugins
65 $this->checkCaches();
66
67 // general WP
68 if ($args['flush_mode'] === 'post' && $post_id > 0)
69 clean_post_cache($post_id);
70 else
71 wp_cache_flush();
72
73 /* Verified working without.
74 if ($this->has_supercache)
75 $this->removeSuperCache();
76 */
77 if ($this->has_w3tc)
78 $this->removeW3tcCache();
79
80 if ($this->has_wpengine)
81 $this->removeWpeCache();
82
83 if ($this->has_siteground)
84 $this->removeSiteGround();
85
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()
96 {
97 global $file_prefix, $supercachedir;
98 if ( empty( $supercachedir ) && function_exists( 'get_supercache_dir' ) ) {
99 $supercachedir = get_supercache_dir();
100 }
101 wp_cache_clean_cache( $file_prefix );
102 }
103
104 protected function removeW3tcCache()
105 {
106 w3tc_pgcache_flush();
107 }
108
109 protected function removeWpeCache()
110 {
111 if ( method_exists( 'WpeCommon', 'purge_memcached' ) ) {
112 \WpeCommon::purge_memcached();
113 }
114 if ( method_exists( 'WpeCommon', 'clear_maxcdn_cache' ) ) {
115 \WpeCommon::clear_maxcdn_cache();
116 }
117 if ( method_exists( 'WpeCommon', 'purge_varnish_cache' ) ) {
118 \WpeCommon::purge_varnish_cache();
119 }
120 }
121
122 protected function removeFastestCache()
123 {
124 global $wp_fastest_cache;
125 $wp_fastest_cache->deleteCache();
126 }
127
128 protected function removeSiteGround()
129 {
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 }
1 <?php
2
3 // Compatibility functions for old version of WordPress / PHP / Other
4
5
6 /*
7 * Introduced in WP 4.9.7 - https://developer.wordpress.org/reference/functions/wp_delete_attachment_files/
8 * Compat for previous versions.
9 */
10 if (! function_exists('wp_delete_attachment_files'))
11 {
12 function wp_delete_attachment_files($post_id, $meta, $backup_sizes, $file )
13 {
14 global $wpdb;
15 $uploadpath = wp_get_upload_dir();
16 $deleted = true;
17
18 if ( ! empty( $meta['thumb'] ) ) {
19 // Don't delete the thumb if another attachment uses it.
20 if ( ! $wpdb->get_row( $wpdb->prepare( "SELECT meta_id FROM $wpdb->postmeta WHERE meta_key = '_wp_attachment_metadata' AND meta_value LIKE %s AND post_id <> %d", '%' . $wpdb->esc_like( $meta['thumb'] ) . '%', $post_id ) ) ) {
21 $thumbfile = str_replace( wp_basename( $file ), $meta['thumb'], $file );
22 if ( ! empty( $thumbfile ) ) {
23 $thumbfile = path_join( $uploadpath['basedir'], $thumbfile );
24 $thumbdir = path_join( $uploadpath['basedir'], dirname( $file ) );
25
26 if ( ! wp_delete_file_from_directory( $thumbfile, $thumbdir ) ) {
27 $deleted = false;
28 }
29 }
30 }
31 }
32
33 // Remove intermediate and backup images if there are any.
34 if ( isset( $meta['sizes'] ) && is_array( $meta['sizes'] ) ) {
35 $intermediate_dir = path_join( $uploadpath['basedir'], dirname( $file ) );
36 foreach ( $meta['sizes'] as $size => $sizeinfo ) {
37 $intermediate_file = str_replace( wp_basename( $file ), $sizeinfo['file'], $file );
38 if ( ! empty( $intermediate_file ) ) {
39 $intermediate_file = path_join( $uploadpath['basedir'], $intermediate_file );
40
41 if ( ! wp_delete_file_from_directory( $intermediate_file, $intermediate_dir ) ) {
42 $deleted = false;
43 }
44 }
45 }
46 }
47
48 if ( is_array( $backup_sizes ) ) {
49 $del_dir = path_join( $uploadpath['basedir'], dirname( $meta['file'] ) );
50 foreach ( $backup_sizes as $size ) {
51 $del_file = path_join( dirname( $meta['file'] ), $size['file'] );
52 if ( ! empty( $del_file ) ) {
53 $del_file = path_join( $uploadpath['basedir'], $del_file );
54
55 if ( ! wp_delete_file_from_directory( $del_file, $del_dir ) ) {
56 $deleted = false;
57 }
58 }
59 }
60 }
61
62 if ( ! wp_delete_file_from_directory( $file, $uploadpath['basedir'] ) ) {
63 $deleted = false;
64 }
65
66 return $deleted;
67
68 }
69 } // end function
70
71
72 /*
73 * Introduced in WP 4.9.7 - https://developer.wordpress.org/reference/functions/wp_delete_attachment_files/
74 * Compat for previous versions.
75 */
76 if (! function_exists('wp_delete_file_from_directory'))
77 {
78 function wp_delete_file_from_directory( $file, $directory ) {
79 if ( wp_is_stream( $file ) ) {
80 $real_file = wp_normalize_path( $file );
81 $real_directory = wp_normalize_path( $directory );
82 } else {
83 $real_file = realpath( wp_normalize_path( $file ) );
84 $real_directory = realpath( wp_normalize_path( $directory ) );
85 }
86
87 if ( false === $real_file || false === $real_directory || strpos( $real_file, trailingslashit( $real_directory ) ) !== 0 ) {
88 return false;
89 }
90
91 wp_delete_file( $file );
92
93 return true;
94 }
95
96 } // end function
97
98
99 /*
100 * Introduced in WP 4.5.0 - needed for compat function of wp_delete_attachment_files
101 */
102 if (! function_exists('wp_get_upload_dir'))
103 {
104 function wp_get_upload_dir() {
105 return wp_upload_dir( null, false );
106 }
107 }
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 }
1 <?php
2 namespace EnableMediaReplace\Externals;
3
4
5 class SiteOrigin
6 {
7 protected static $instance;
8
9 public function __construct()
10 {
11 if (defined('SITEORIGIN_PANELS_VERSION'))
12 {
13 add_filter('emr/replacer/option_fields', array($this, 'addOption'));
14 }
15 }
16
17 public static function getInstance()
18 {
19 if (is_null(self::$instance))
20 {
21 self::$instance = new SiteOrigin();
22 }
23
24 return self::$instance;
25 }
26
27 public function addOption($options)
28 {
29 $options[] = 'widget_siteorigin-panels-builder';
30 return $options;
31 }
32 } // class
1 <?php
2
3
4 /**
5 * Skin class.
6 *
7 * @since 1.0.0
8 *
9 * @package Envira_Gallery
10 * @author Envira Team
11 */
12 class EMR_Envira_Gallery_Skin extends WP_Upgrader_Skin {
13
14 /**
15 * Primary class constructor.
16 *
17 * @since 1.0.0
18 *
19 * @param array $args Empty array of args (we will use defaults).
20 */
21 public function __construct( $args = array() ) {
22
23 parent::__construct();
24
25 }
26
27 /**
28 * Set the upgrader object and store it as a property in the parent class.
29 *
30 * @since 1.0.0
31 *
32 * @param object $upgrader The upgrader object (passed by reference).
33 */
34 public function set_upgrader( &$upgrader ) {
35
36 if ( is_object( $upgrader ) ) {
37 $this->upgrader =& $upgrader;
38 }
39
40 }
41
42 /**
43 * Set the upgrader result and store it as a property in the parent class.
44 *
45 * @since 1.0.0
46 *
47 * @param object $result The result of the install process.
48 */
49 public function set_result( $result ) {
50
51 $this->result = $result;
52
53 }
54
55 /**
56 * Empty out the header of its HTML content and only check to see if it has
57 * been performed or not.
58 *
59 * @since 1.0.0
60 */
61 public function header() {}
62
63 /**
64 * Empty out the footer of its HTML contents.
65 *
66 * @since 1.0.0
67 */
68 public function footer() {}
69
70 /**
71 * Instead of outputting HTML for errors, json_encode the errors and send them
72 * back to the Ajax script for processing.
73 *
74 * @since 1.0.0
75 *
76 * @param array $errors Array of errors with the install process.
77 */
78 public function error( $errors ) {
79
80 if ( ! empty( $errors ) ) {
81 echo wp_json_encode( array( 'error' => __( 'There was an error installing the addon. Please try again.', 'envira-gallery' ) ) );
82 /* log this for API issues */
83
84 error_log( print_r( $errors, true ) );
85
86 die;
87 }
88
89 }
90
91 /**
92 * Empty out the feedback method to prevent outputting HTML strings as the install
93 * is progressing.
94 *
95 * @since 1.0.0
96 *
97 * @param string $string The feedback string.
98 * @param array ...$args The args.
99 */
100 public function feedback( $string, ...$args ) {}
101
102 }
1 <?php
2
3 add_action( 'wp_ajax_emr_plugin_install', 'emr_plugin_install' );
4
5 function emr_plugin_install() {
6
7 // Run a security check first.
8 check_admin_referer( 'emr-plugin-install', 'nonce' );
9
10 $plugin = isset($_POST['plugin']) ? sanitize_text_field($_POST['plugin']) : null;
11
12 if ( ! current_user_can('install_plugins'))
13 {
14 // Send back a response.
15 wp_send_json(array('result'=> false));
16 die;
17 }
18
19 switch($plugin)
20 {
21 case "envira":
22 $download_url = 'https://downloads.wordpress.org/plugin/envira-gallery-lite.zip';
23 break;
24 case 'spio':
25 $download_url = 'https://downloads.wordpress.org/plugin/shortpixel-image-optimiser.zip';
26 break;
27 case 'spai':
28 $download_url = 'https://downloads.wordpress.org/plugin/shortpixel-adaptive-images.zip';
29 break;
30 }
31
32 // Install the addon.
33 if ( ! is_null($download_url ) ) {
34
35 //$download_url = esc_url_raw( wp_unslash( $_POST['plugin'] ) );
36 global $hook_suffix;
37
38 // Set the current screen to avoid undefined notices.
39 set_current_screen();
40
41 // Prepare variables.
42 $method = '';
43 $url = add_query_arg(
44 array(
45 // 'page' => 'envira-gallery-settings',
46 ),
47 admin_url( 'admin.php' )
48 );
49 $url = esc_url( $url );
50
51 // Start output bufferring to catch the filesystem form if credentials are needed.
52 ob_start();
53 $creds = request_filesystem_credentials( $url, $method, false, false, null );
54 if ( false === $creds ) {
55 $form = ob_get_clean();
56 echo wp_json_encode( array( 'form' => $form ) );
57 die;
58 }
59
60 // If we are not authenticated, make it happen now.
61 if ( ! WP_Filesystem( $creds ) ) {
62 ob_start();
63 request_filesystem_credentials( $url, $method, true, false, null );
64 $form = ob_get_clean();
65 echo wp_json_encode( array( 'form' => $form ) );
66 die;
67 }
68
69 // We do not need any extra credentials if we have gotten this far, so let's install the plugin.
70 require_once (ABSPATH . 'wp-admin/includes/class-wp-upgrader.php');
71 require_once (plugin_dir_path( EMR_ROOT_FILE ) . 'classes/external/upgrader_skin.php');
72
73 // Create the plugin upgrader with our custom skin.
74 $skin = new EMR_Envira_Gallery_Skin();
75 $installer = new Plugin_Upgrader( $skin );
76 $installer->install( $download_url );
77
78 // Flush the cache and return the newly installed plugin basename.
79 wp_cache_flush();
80
81 if ( $installer->plugin_info() ) {
82 $plugin_basename = $installer->plugin_info();
83
84 ob_clean();
85
86
87 wp_send_json_success( array( 'plugin' => $plugin_basename ) );
88
89 die();
90 }
91 }
92
93 // Send back a response.
94 wp_send_json(array('result'=> false));
95 die;
96
97 }
98
99 add_action( 'wp_ajax_emr_plugin_activate', 'emr_activate' );
100
101 /**
102 * Activates an Envira addon.
103 *
104 * @since 1.0.0
105 */
106 function emr_activate() {
107
108 // Run a security check first.
109 check_admin_referer( 'emr-plugin-activate', 'nonce' );
110
111 $plugin = isset($_POST['plugin']) ? sanitize_text_field($_POST['plugin']) : null;
112
113 if ( ! current_user_can('activate_plugins'))
114 {
115 // Send back a response.
116 wp_send_json(array('result'=> false));
117 die;
118 }
119
120
121 switch($plugin)
122 {
123 case "envira":
124 $plugin = 'envira-gallery-lite/envira-gallery-lite.php';
125 break;
126 case 'spio':
127 $plugin = 'shortpixel-image-optimiser/wp-shortpixel.php';
128 break;
129 case 'spai':
130 $plugin = 'shortpixel-adaptive-images/short-pixel-ai.php';
131 break;
132 }
133
134 // Activate the addon.
135 if ( ! is_null($plugin) ) {
136 $activate = activate_plugin( $plugin );
137 if ( is_wp_error( $activate ) ) {
138 echo json_encode( array( 'error' => $activate->get_error_message() ) );
139 die;
140 }
141 }
142
143 echo json_encode( true );
144 die;
145
146 }
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 }
1 <?php
2 namespace EnableMediaReplace;
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 use EnableMediaReplace\Externals\SiteOrigin as SiteOrigin;
9 use EnableMediaReplace\Externals\WPOffload as WPOffload;
10
11
12 class Externals
13 {
14 protected $replaceType = null;
15 protected $replaceSearchType = null;
16
17 protected $messages = array();
18
19 public function __construct()
20 {
21 // These hooks prevent loading of options when plugin conflicts arise.
22 add_filter('emr_display_replace_type_options', array($this, 'get_replace_type'));
23 add_filter('emr_enable_replace_and_search', array($this, 'get_replacesearch_type'));
24 add_action('emr_after_replace_type_options', array($this, 'get_messages'));
25
26 $this->check();
27
28 // integrations
29 $this->loadElementor();
30 $this->loadBakery(); // in case of urlencoded issues, this class should be used probably.
31 $this->loadSiteOrigins();
32 $this->loadWpOffload();
33 }
34
35 protected function check() // check if any of the options should be disabled due to conflicts
36 {
37 /*if (class_exists('FLBuilder'))
38 {
39 $this->replaceSearchType = false;
40 $this->messages[] return true;
41 = __('Replace and Search feature is not compatible with Beaver Builder.', 'enable-media-replace');
42 } */
43 }
44
45 public function get_replace_type($bool)
46 {
47 if ($this->replaceType === null)
48 return $bool;
49
50 return $this->replaceType;
51 }
52
53 public function get_replacesearch_type($bool)
54 {
55 if ($this->replaceSearchType === null)
56 return $bool;
57
58 return $this->replaceSearchType;
59 }
60
61 public function get_messages()
62 {
63 foreach($this->messages as $message)
64 {
65 echo '<span class="nofeature-notice"><p>'. $message . '</p></span>';
66 }
67 }
68
69 public function loadElementor()
70 {
71 Elementor::getInstance();
72 }
73
74 public function loadBakery()
75 {
76 WpBakery::getInstance();
77 }
78
79 public function loadSiteOrigins()
80 {
81 SiteOrigin::getInstance();
82 }
83
84 public function loadWPOffload()
85 {
86 WPOffload::getInstance();
87 }
88
89 } // class
1 <?php
2 namespace EnableMediaReplace;
3
4 // Legacy functions.
5
6 /**
7 * Maybe remove query string from URL.
8 *
9 * @param string $url
10 *
11 * @return string
12 */
13
14 function emr_maybe_remove_query_string( $url ) {
15 $parts = explode( '?', $url );
16
17 return reset( $parts );
18 }
19
20 /**
21 * Remove scheme from URL.
22 *
23 * @param string $url
24 *
25 * @return string
26 */
27 function emr_remove_scheme( $url ) {
28 return preg_replace( '/^(?:http|https):/', '', $url );
29 }
30
31 /**
32 * Remove size from filename (image[-100x100].jpeg).
33 *
34 * @param string $url
35 * @param bool $remove_extension
36 *
37 * @return string
38 */
39 function emr_remove_size_from_filename( $url, $remove_extension = false ) {
40 $url = preg_replace( '/^(\S+)-[0-9]{1,4}x[0-9]{1,4}(\.[a-zA-Z0-9\.]{2,})?/', '$1$2', $url );
41
42 if ( $remove_extension ) {
43 $ext = pathinfo( $url, PATHINFO_EXTENSION );
44 $url = str_replace( ".$ext", '', $url );
45 }
46
47 return $url;
48 }
49
50 /**
51 * Strip an image URL down to bare minimum for matching.
52 *
53 * @param string $url
54 *
55 * @return string
56 */
57 function emr_get_match_url($url) {
58 $url = emr_remove_scheme($url);
59 $url = emr_maybe_remove_query_string($url);
60 $url = emr_remove_size_from_filename($url, true); // and extension is removed.
61 $url = emr_remove_domain_from_filename($url);
62 return $url;
63 }
64
65
66 function emr_remove_domain_from_filename($url) {
67 // Holding place for possible future function
68 $url = str_replace(emr_remove_scheme(get_bloginfo('url')), '', $url);
69 return $url;
70 }
71
72 /**
73 * Build an array of search or replace URLs for given attachment GUID and its metadata.
74 *
75 * @param string $guid
76 * @param array $metadata
77 *
78 * @return array
79 */
80 function emr_get_file_urls( $guid, $metadata ) {
81 $urls = array();
82
83 $guid = emr_remove_scheme( $guid );
84 $guid= emr_remove_domain_from_filename($guid);
85
86 $urls['guid'] = $guid;
87
88 if ( empty( $metadata ) ) {
89 return $urls;
90 }
91
92 $base_url = dirname( $guid );
93
94 if ( ! empty( $metadata['file'] ) ) {
95 $urls['file'] = trailingslashit( $base_url ) . wp_basename( $metadata['file'] );
96 }
97
98 if ( ! empty( $metadata['sizes'] ) ) {
99 foreach ( $metadata['sizes'] as $key => $value ) {
100 $urls[ $key ] = trailingslashit( $base_url ) . wp_basename( $value['file'] );
101 }
102 }
103
104 return $urls;
105 }
106
107 /**
108 * Ensure new search URLs cover known sizes for old attachment.
109 * Falls back to full URL if size not covered (srcset or width/height attributes should compensate).
110 *
111 * @param array $old
112 * @param array $new
113 *
114 * @return array
115 */
116 function emr_normalize_file_urls( $old, $new ) {
117 $result = array();
118
119 if ( empty( $new['guid'] ) ) {
120 return $result;
121 }
122
123 $guid = $new['guid'];
124
125 foreach ( $old as $key => $value ) {
126 $result[ $key ] = empty( $new[ $key ] ) ? $guid : $new[ $key ];
127 }
128
129 return $result;
130 }
1 <?php
2 namespace EnableMediaReplace;
3 use EnableMediaReplace\ShortPixelLogger\ShortPixelLogger as Log;
4 use EnableMediaReplace\Notices\NoticeController as Notices;
5
6 class InstallHelper
7 {
8
9 public static function unInstallPlugin()
10 {
11 delete_option( 'enable_media_replace' );
12 delete_option( 'emr_news' );
13 delete_option( 'emr_url_cache');
14 }
15
16 public static function deactivatePlugin()
17 {
18 Notices::resetNotices();
19 }
20 }
1 {"version":3,"sourceRoot":"","sources":["../scss/_datepicker.scss","../scss/_screens.scss","../scss/admin.scss"],"names":[],"mappings":"AAEA;EACC;EACA;EACA;;;AAID;EACC;EACA;EACA;EACA;EACA;;;AAED;EACC;EACA;EACA;;;AAED;EACC;EACA;;;AAED;AAAA;EAEC;EACA;EACA;EACA;;;AAED;AAAA;EAEC;;;AAED;EACC;;;AAED;EACC;;;AAED;EACC;;;AAED;EACC;;;AAED;AAAA;EAEC;EACA;EACA;EACA;EACA;EACA;;;AAED;EACC;EACA;EACA;;;AAED;EACC;EACA;;;AAED;AAAA;EAEC;;;AAED;EACC;EACA;EACA;EACA;;;AAED;EACC;EACA;EACA;EACA;;;AAED;EACC;EACA;;;AAED;AAAA;EAEC;EACA;EACA;EACA;;;AAED;EACC;EACA;EACA;EACA;EACA;EACA;;;AAED;EACC;EACA;EACA;EACA;EACA;EACA;;;AAED;EACC;;;AAGD;AACA;EACC;;;AAED;EACC;;;AAED;EACC;EACA;;;AAED;EACC;;;AAED;EACC;;;AAED;EACC;;;AAED;AAAA;EAEC;;;AAED;EACC;;;AAED;EACC;EACA;EACA;;;AAGD;AACA;EACC;;;AAED;EACC;EACA;;;AAED;EACC;EACA;;;AAED;EACC;EACA;;;AAED;EACC;EACA;;;AAED;EACC;;;AAED;EACC;;;AAED;AAAA;EAEC;;;AAED;AAAA;EAEC;EACA;;;AAGD;AACA;EACC;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;;;AAED;AAAA;EAEC;;;AAED;EACC;;;AAED;AAAA;AAAA;AAAA;EAIC;;;AAED;AAAA;EAEC;;;AAED;AAAA;EAEC;;;AAGD;AACA;EAAiB;;;AACjB;EAAqB;;;AACrB;EAAsB;;;AACtB;EAAqB;;;AACrB;EAAsB;;;AACtB;EAAqB;;;AACrB;EAAsB;;;AACtB;EAAqB;;;AACrB;EAAsB;;;AACtB;EAAuB;;;AACvB;EAAuB;;;AACvB;EAAwB;;;AACxB;EAAyB;;;AACzB;EAAwB;;;AACxB;EAAyB;;;AACzB;EAAwB;;;AACxB;EAAyB;;;AACzB;EAAwB;;;AACxB;EAAyB;;;AACzB;EAA0B;;;AAC1B;EAA0B;;;AAC1B;EAAqB;;;AACrB;EAAsB;;;AACtB;EAAqB;;;AACrB;EAAsB;;;AACtB;EAAqB;;;AACrB;EAAsB;;;AACtB;EAAqB;;;AACrB;EAAsB;;;AACtB;EAAuB;;;AACvB;EAAyB;;;AACzB;EAAuB;;;AACvB;EAAyB;;;AACzB;EAAyB;;;AACzB;EAAyB;;;AACzB;EAAyB;;;AACzB;EAAyB;;;AACzB;EAA0B;;;AAC1B;EAA2B;;;AAC3B;EAA0B;;;AAC1B;EAA2B;;;AAC3B;EAA0B;;;AAC1B;EAA2B;;;AAC3B;EAA0B;;;AAC1B;EAA2B;;;AAC3B;EAA4B;;;AAC5B;EAA8B;;;AAC9B;EAA4B;;;AAC5B;EAA8B;;;AAC9B;EAA8B;;;AAC9B;EAA8B;;;AAC9B;EAA8B;;;AAC9B;EAA8B;;;AAC9B;EAAgC;;;AAChC;EAAgC;;;AAChC;EAAgC;;;AAChC;EAAgC;;;AAChC;EAA2B;;;AAC3B;EAA2B;;;AAC3B;EAA2B;;;AAC3B;EAA2B;;;AAC3B;EAA4B;;;AAC5B;EAA4B;;;AAC5B;EAA4B;;;AAC5B;EAA4B;;;AAC5B;EAAmB;;;AACnB;EAAwB;;;AACxB;EAAmB;;;AACnB;EAAkB;;;AAClB;EAAmB;;;AACnB;EAAmB;;;AACnB;EAAwB;;;AACxB;EAA6B;;;AAC7B;EAA4B;;;AAC5B;EAAuB;;;AACvB;EAAoB;;;AACpB;EAAsB;;;AACtB;EAAgB;;;AAChB;EAAuB;;;AACvB;EAAqB;;;AACrB;EAAoB;;;AACpB;EAAmB;;;AACnB;EAAkB;;;AAClB;EAAiB;;;AACjB;EAAiB;;;AACjB;EAAkB;;;AAClB;EAAoB;;;AACpB;EAAoB;;;AACpB;EAAe;;;AACf;EAAgB;;;AAChB;EAAgB;;;AAChB;EAAoB;;;AACpB;EAAgB;;;AAChB;EAAkB;;;AAClB;EAAiB;;;AACjB;EAAgB;;;AAChB;EAAsB;;;AACtB;EAAkB;;;AAClB;EAAmB;;;AACnB;EAAkB;;;AAClB;EAAkB;;;AAClB;EAAgB;;;AAChB;EAAiB;;;AACjB;EAAgB;;;AAChB;EAAgB;;;AAChB;EAAkB;;;AAClB;EAAgB;;;AAChB;EAAqB;;;AACrB;EAAiB;;;AACjB;EAAsB;;;AACtB;EAAiB;;;AACjB;EAAsB;;;AACtB;EAAe;;;AACf;EAAqB;;;AACrB;EAAoB;;;AACpB;EAAqB;;;AACrB;EAAgB;;;AAChB;EAAmB;;;AACnB;EAAiB;;;AACjB;EAAiB;;;AACjB;EAAkB;;;AAClB;EAAiB;;;AACjB;EAAgB;;;AAChB;EAAkB;;;AAClB;EAAgB;;;AAChB;EAAiB;;;AACjB;EAAkB;;;AAClB;EAAoB;;;AACpB;EAAqB;;;AACrB;EAAiB;;;AACjB;EAAiB;;;AACjB;EAAgB;;;AAChB;EAAiB;;;AACjB;EAAqB;;;AACrB;EAAqB;;;AACrB;EAAoB;;;AACpB;EAAsB;;;AACtB;AACA;EAAsB;;;AACtB;EAAgB;;;AAChB;EAAiB;;;AACjB;EAAsB;;;AACtB;EAAqB;;;AACrB;EAAiB;;;AACjB;EAAuB;;;AACvB;EAAkB;;;AAClB;EAAqB;;;AACrB;EAAqB;;;AACrB;EAAqB;;;AACrB;EAAqB;;;AACrB;EAAuB;;;AACvB;EAAwB;;;AACxB;EAAwB;;;AACxB;EAA6B;;;AAC7B;EAA6B;;;AAC7B;EAA6B;;;AAC7B;EAA6B;;;AAC7B;EAA0B;;;AAC1B;EAA0B;;;AAC1B;EAA0B;;;AAC1B;EAA0B;;;AAC1B;EAAyB;;;AACzB;EAA0B;;;AAC1B;EAAwB;;;AACxB;EAA4B;;;AAC5B;EAA6B;;;AAC7B;EAA6B;;;AAC7B;EAA4B;;;AAC5B;EAA6B;;;AAC7B;EAA6B;;;AAC7B;EAAgC;;;AAChC;EAAkC;;;AAClC;EAA+B;;;AAC/B;EAAiC;;;AACjC;EAAiC;;;AACjC;EAA4B;;;AAE5B;AACA;AAAA;AAAA;AAAA;EAIC;;;AAED;AAAA;AAAA;AAAA;EAIC;;;AAED;AAAA;AAAA;AAAA;EAIC;;;AAED;AAAA;AAAA;AAAA;EAIC;;;AClaD;EAGC;EACA;EACA;EACA;EACA;;AAEA;EACE;EACD;EACA;EACA;EACA;EACA;EACA;EACA;;AAED;EAEC;;AAGD;EACE;;AAGF;EAAI;;AAGJ;EAAQ;;AAGN;EAAK;;;AChCR;EAIC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACC;EACA;EACA;EACA;EACA;EACA;;AAGD;EAEC;;;AAOA;EAEE;;AACA;EAEE;;AAIL;EAEC;;AAED;EACC;;AAGD;EAGG;EACA;;AAEA;EAEE;EAEA;EACA;EACA;;AAIL;EACC;EACA;EACA;EACA;;AACA;EACC;EACA;;AAMD;EAEE;;AAGA;EAEE;EACH;;AAEG;EAEE;EACA;EACA;EACA;EACA;EACA;EACJ;EACA;EACA;;AAEA;EAAM;;AAEN;EAEC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAED;EACC;;AAEG;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACL;;AAGG;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EAEG;EACA;EACA;EACA;;AAEP;EAEC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EAEA;EACA;EACA;EACA;;AAMG;EAAiC;;AAMjC;EAAM;;AACN;EAAa;;AAEX;EACE;EACA;EACA;;AASZ;EAEE;EACA;EACA;EAEA;EACA;;AACA;EACI;EACA;EACA;;AAIN;EAEE;;AAGF;EAEE;;AAGF;EAEE;EACA;EACA;;AACA;EAEE;EACA;;AAKA;EAEE;;AAEF;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;;AAOR;EAEE;EACA;EACA;EACA;;AAGE;EACE;;AAEF;EAEE;;AAGN;EAEE;;AACA;EACC;EACA;;AAOG;EAEE;;AAMJ;EAAQ;;AAEV;EAEE;EACA;EACA;;AAEF;EAEE;EACA;EACA;;AACA;EACE;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;;AACA;EAEE;EACA;EACA;;AAIN;EAEE;EACA;;AACA;EAEE;EACA;;AAKN;EAEE;EACA;EACA;EACA;;AACA;EAEE;EACA;;AAIJ;EAEG;;AAIH;EAEE;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;EACF;;AACE;EACE;EACA;EACA;EACA;EACA;;AAEJ;EAEE;EACA;;AAEF;EAAO;;AACP;EAAQ;;AACR;EAAQ;;AACR;EAAS;;AACR;EACE;;AAED;EAEE;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACJ;;AAGF;EAAU;;AAER;EAEE;EACA;;AACA;EAAM;EAAkB;EAAmB;;AAU/C;EAEE;;AAEF;EAEE;;AACA;EACC;;AAKH;EAEI;IAEG;;EAEH;IACE;;EACA;IACE;;;AAGR;EAEE;IAAkB;;;AAErB;EAEE;IACE;IACA;IACA;;EAIA;IACE;IACD","file":"admin.css"}
...\ No newline at end of file ...\ No newline at end of file
1 /* Styling for the edit attachment screen */
2 #emr-replace-box .previewwrapper, #emr-showthumbs-box .previewwrapper {
3 display: inline-block;
4 position: relative;
5 clear: both;
6 margin: 3px 0;
7 }
8 #emr-replace-box .previewwrapper img, #emr-showthumbs-box .previewwrapper img {
9 max-width: 100%;
10 }
11 #emr-replace-box .previewwrapper span.label, #emr-showthumbs-box .previewwrapper span.label {
12 font-size: 14px;
13 color: #fff;
14 position: absolute;
15 line-height: 16px;
16 margin-top: -8px;
17 top: 50%;
18 left: 0;
19 right: 0;
20 background: rgba(0, 0, 0, 0.5);
21 text-align: center;
22 padding: 4px 0;
23 }
24
25 /*# sourceMappingURL=edit_attachment.css.map */
1 {"version":3,"sourceRoot":"","sources":["../scss/edit_attachment.scss"],"names":[],"mappings":"AACA;AAGE;EAEE;EACA;EACA;EACA;;AAEA;EAAM;;AACN;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;EAAS;EACT;EACA;EACA","file":"edit_attachment.css"}
...\ No newline at end of file ...\ No newline at end of file
1 #remove-background-form form {
2 display: flex;
3 }
4 #remove-background-form .image_chooser.wrapper {
5 min-height: 0;
6 }
7 #remove-background-form .image_placeholder.is_image {
8 border: none;
9 width: 45%;
10 height: auto;
11 }
12 #remove-background-form .image_placeholder.is_image .textlayer, #remove-background-form .image_placeholder.is_image .image_size {
13 display: none;
14 }
15 #remove-background-form .bad-button {
16 text-align: right;
17 margin-right: 25px;
18 }
19 #remove-background-form .bad-button a {
20 visibility: hidden;
21 }
22 #remove-background-form .overlay {
23 visibility: hidden;
24 display: flex;
25 flex-direction: column;
26 justify-content: center;
27 align-items: center;
28 width: 100%;
29 height: 100%;
30 background-color: rgba(0, 0, 0, 0.2);
31 position: absolute;
32 top: 0;
33 }
34 #remove-background-form .lds-spinner {
35 color: official;
36 display: inline-block;
37 position: relative;
38 width: 80px;
39 height: 80px;
40 }
41 #remove-background-form .lds-spinner div {
42 transform-origin: 40px 40px;
43 animation: lds-spinner 1.2s linear infinite;
44 }
45 #remove-background-form .lds-spinner div:after {
46 content: " ";
47 display: block;
48 position: absolute;
49 top: 3px;
50 left: 37px;
51 width: 6px;
52 height: 18px;
53 border-radius: 20%;
54 background: #fff;
55 }
56 #remove-background-form .lds-spinner div:nth-child(1) {
57 transform: rotate(0deg);
58 animation-delay: -1.1s;
59 }
60 #remove-background-form .lds-spinner div:nth-child(2) {
61 transform: rotate(30deg);
62 animation-delay: -1s;
63 }
64 #remove-background-form .lds-spinner div:nth-child(3) {
65 transform: rotate(60deg);
66 animation-delay: -0.9s;
67 }
68 #remove-background-form .lds-spinner div:nth-child(4) {
69 transform: rotate(90deg);
70 animation-delay: -0.8s;
71 }
72 #remove-background-form .lds-spinner div:nth-child(5) {
73 transform: rotate(120deg);
74 animation-delay: -0.7s;
75 }
76 #remove-background-form .lds-spinner div:nth-child(6) {
77 transform: rotate(150deg);
78 animation-delay: -0.6s;
79 }
80 #remove-background-form .lds-spinner div:nth-child(7) {
81 transform: rotate(180deg);
82 animation-delay: -0.5s;
83 }
84 #remove-background-form .lds-spinner div:nth-child(8) {
85 transform: rotate(210deg);
86 animation-delay: -0.4s;
87 }
88 #remove-background-form .lds-spinner div:nth-child(9) {
89 transform: rotate(240deg);
90 animation-delay: -0.3s;
91 }
92 #remove-background-form .lds-spinner div:nth-child(10) {
93 transform: rotate(270deg);
94 animation-delay: -0.2s;
95 }
96 #remove-background-form .lds-spinner div:nth-child(11) {
97 transform: rotate(300deg);
98 animation-delay: -0.1s;
99 }
100 #remove-background-form .lds-spinner div:nth-child(12) {
101 transform: rotate(330deg);
102 animation-delay: 0s;
103 }
104 @keyframes lds-spinner {
105 0% {
106 opacity: 1;
107 }
108 100% {
109 opacity: 0;
110 }
111 }
112 #remove-background-form * {
113 box-sizing: border-box;
114 }
115 #remove-background-form .img-comp-container {
116 position: relative;
117 height: 200px;
118 /*should be the same height as the images*/
119 }
120 #remove-background-form .img-comp-img {
121 position: absolute;
122 width: auto;
123 height: auto;
124 overflow: hidden;
125 }
126 #remove-background-form .img-comp-img img {
127 display: block;
128 }
129 #remove-background-form .img-comp-slider {
130 position: absolute;
131 z-index: 9;
132 cursor: ew-resize;
133 /*set the appearance of the slider:*/
134 width: 20px;
135 height: 20px;
136 background-color: #2196F3;
137 opacity: 0.7;
138 border-radius: 50%;
139 }
140 #remove-background-form .preview-area {
141 display: flex;
142 justify-content: center;
143 align-items: center;
144 width: 100%;
145 height: 100%;
146 }
147 #remove-background-form .preview-area h1 {
148 color: red !important;
149 }
150
151 /*# sourceMappingURL=remove_background.css.map */
1 {"version":3,"sourceRoot":"","sources":["../scss/remove_background.scss"],"names":[],"mappings":"AAEG;EACA;;AAGD;EACE;;AAEF;EAEE;EACA;EACA;;AACA;EACE;;AAIJ;EAEE;EACA;;AACA;EACC;;AAIH;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAED;EACE;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;;AAEF;EACE;EACA;;AAEF;EACE;EACA;;AAEF;EACE;EACA;;AAEF;EACE;EACA;;AAEF;EACE;EACA;;AAEF;EACE;EACA;;AAEF;EACE;EACA;;AAEF;EACE;EACA;;AAEF;EACE;EACA;;AAEF;EACE;EACA;;AAEF;EACE;EACA;;AAEF;EACC;IACC;;EAED;IACC;;;AAMH;EACC;;AAGD;EACC;EACA;AAAe;;AAGhB;EACC;EACA;EACA;EACA;;AAGD;EACC;;AAGD;EACC;EACA;EACA;AACA;EACA;EACA;EACA;EACA;EACA;;AAGD;EACC;EACA;EACA;EACA;EACA;;AAED;EACC","file":"remove_background.css"}
...\ No newline at end of file ...\ No newline at end of file
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: 4.1.4
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 *
26 */
27
28 define( 'EMR_VERSION', '4.1.4' );
29
30 if ( ! defined( 'ABSPATH' ) ) {
31 exit; // Exit if accessed directly.
32 }
33
34 /* Not sure why we define this?
35 if(!defined("S3_UPLOADS_AUTOENABLE")) {
36 define('S3_UPLOADS_AUTOENABLE', true);
37 } */
38
39 if ( ! defined( 'EMR_ROOT_FILE' ) ) {
40 define( 'EMR_ROOT_FILE', __FILE__ );
41 }
42
43 if ( ! defined( 'SHORTPIXEL_AFFILIATE_CODE' ) ) {
44 define( 'SHORTPIXEL_AFFILIATE_CODE', 'VKG6LYN28044' );
45 }
46
47 /** Usage:
48 * Define in wp-config.php
49 * // User must have this capability to replace all
50 * define('EMR_CAPABILITY' ,'edit_upload_all' );
51 * // User must have first capability to replace all OR second capability to replace only own files
52 * define('EMR_CAPABILITY' ,array('edit_upload_all', 'edit_upload_user') );
53 *
54 *
55 **/
56 if ( ! defined( 'EMR_CAPABILITY' ) ) {
57 define( 'EMR_CAPABILITY', false );
58 }
59
60 /* if (! defined('EMR_CAPABILITY_USERONLY'))
61 define('EMR_CAPABILITY_USERONLY', false); */
62
63 $plugin_path = plugin_dir_path( EMR_ROOT_FILE );
64
65 require_once( $plugin_path . 'build/shortpixel/autoload.php' );
66 require_once( $plugin_path . 'classes/compat.php' );
67 require_once( $plugin_path . 'classes/functions.php' );
68 //require_once( $plugin_path . 'classes/replacer.php' );
69 require_once( $plugin_path . 'classes/uihelper.php' );
70 //require_once( $plugin_path . 'classes/file.php' );
71 require_once( $plugin_path . 'classes/cache.php' );
72 require_once( $plugin_path . 'classes/api.php' );
73 require_once( $plugin_path . 'classes/ajax.php' );
74 require_once( $plugin_path . 'classes/emr-plugin.php' );
75 require_once( $plugin_path . 'classes/installHelper.php' );
76
77 // @todo Needs replacing with PSR-4
78 require_once( $plugin_path . 'classes/Controller/ReplaceController.php');
79 require_once( $plugin_path . 'classes/Controller/RemoteNoticeController.php');
80
81 require_once( $plugin_path . 'classes/ViewController.php');
82 require_once( $plugin_path . 'classes/ViewController/UploadViewController.php');
83 require_once( $plugin_path . 'classes/ViewController/ReplaceViewController.php');
84 require_once( $plugin_path . 'classes/ViewController/RemoveBackgroundViewController.php');
85
86 require_once( $plugin_path . 'classes/externals.php' );
87 require_once( $plugin_path . 'classes/external/elementor.php' );
88 require_once( $plugin_path . 'classes/external/wpbakery.php' );
89 require_once( $plugin_path . 'classes/external/upsell_installer.php' );
90 require_once( $plugin_path . 'classes/external/siteorigin.php' );
91 require_once( $plugin_path . 'classes/external/wp-offload.php' );
92
93 require_once( $plugin_path . 'thumbnail_updater.php' );
94
95 function emr()
96 {
97 return EnableMediaReplace\EnableMediaReplacePlugin::get();
98 }
99 emr(); // runtime.
100
101 //register_uninstall_hook( __FILE__, '\EnableMediaReplace\emr_uninstall' );
102 register_deactivation_hook( __FILE__, array('\EnableMediaReplace\InstallHelper','deactivatePlugin') );
103 register_uninstall_hook(__FILE__, array('\EnableMediaReplace\InstallHelper','uninstallPlugin') );
1 <?php // Silence is golden
...\ No newline at end of file ...\ No newline at end of file
1 <?php // Silence is golden
...\ No newline at end of file ...\ No newline at end of file
1 window.addEventListener('load', function(event) {
2
3 var url = new URL(window.location.href);
4 url.searchParams.set('emr_success', 1);
5
6 var timeout = 10;
7 if (emr_success_options.timeout)
8 timeout = emr_success_options.timeout;
9 var counter = document.getElementById('redirect_counter');
10 var redirectUrl = document.getElementById('redirect_url');
11 var redirected = false;
12
13 counter.textContent = timeout;
14
15 var t = window.setInterval(function () {
16 counter.textContent = timeout;
17 timeout--;
18 if (timeout <= 0 && false == redirected)
19 {
20 window.location.href = redirectUrl;
21 redirected = true;
22 window.clearInterval(t);
23 }
24 }, 1000);
25
26 });
1 jQuery(document).ready(function ($) {
2
3 // Init
4 $('input[type=radio][name=background_type]').on('change', backgroundInputs);
5 $('#bg_transparency').on('input', transparancyOptions);
6
7 backgroundInputs(); // init initial
8 transparancyOptions();
9
10 $('.replace_type.wrapper input').on('change', function () {
11 $('#replace_image_button').prop('disabled', 'disabled');
12 });
13
14 // Remove bg click
15 $('#remove_background_button').on('click', () => {
16 const method = 'POST'
17 const url = emrObject.ajax_url;
18 // const image = emrObject.base_url;
19 const nonce = emrObject.nonce;
20 const attachment_id = $('input[name="ID"]').val();
21 const action = 'emr_remove_background';
22 const bgType = $('input[type=radio][name="background_type"]:checked').val();
23 const cLvl = $('input[type=radio][name="compression_level"]:checked').val();
24 let background = {
25 type: "transparent"
26 }
27
28 background = {
29 type: bgType,
30 color: $('#bg_color').val(),
31 transparency: $('#bg_transparency').val()
32 }
33
34 $.ajax({
35 method,
36 url,
37 data: {
38 action,
39 nonce,
40 attachment_id,
41 background,
42 compression_level : cLvl
43 },
44 beforeSend: function () {
45 $('html, body').animate({
46 scrollTop: $(".emr_upload_form").offset().top
47 }, 1000);
48 $('input[type=radio][name=background_type]').attr('disabled', 'disabled');
49 $('input[type=radio][name=compression_level]').attr('disabled', 'disabled');
50 $('#remove_background_button').attr('disabled', 'disabled');
51 $('h1.response').remove();
52 $('#overlay').css('visibility', 'visible');
53 var preview = $('.image_placeholder').last();
54 preview.find('img').remove();
55 // $('#preview-area').hide();
56 },
57 success: function (response) {
58 var preview = $('.image_placeholder').last();
59
60 if (response.success) {
61
62
63 $('#overlay').css('visibility', 'hidden');
64 preview.find('img').remove();
65 preview.removeClass('is_image not_image is_document');
66
67 $('#replace_image_button').prop('disabled', false);
68
69 var img = new Image();
70 img.src = response.image;
71 img.setAttribute('style', 'height: inherit;');
72
73 preview.prepend(img);
74 // preview.removeClass('not_image');
75 preview.addClass('is_image');
76
77 $('input[name="key"]').val(response.key);
78 $('input[type=radio][name=background_type]').attr('disabled', false);
79 $('input[type=radio][name=compression_level]').attr('disabled', false);
80 $('#remove_background_button').attr('disabled', false);
81
82 var badBg = document.getElementById('bad-background-link');
83 var href = badBg.dataset.link;
84 href = href.replace('{url}', response.url);
85 href = href.replace('{settings}', response.settings);
86
87 badBg.setAttribute('href', href);
88
89 badBg.style.visibility = 'visible';
90 /* $('#removed_image').html(`
91 <div class="img-comp-container">
92 <div class="img-comp-img">
93 <img src="${image}" width="${width}" height="${height}" />
94 </div>
95
96 </div>
97 `); */
98 // initComparisons();
99 }else{
100
101 preview.prepend(`<h1 class='response'>${response.message}</h1>`);
102 $('#remove_background_button').attr('disabled', false)
103 $('input[type=radio][name=background_type]').attr('disabled', false)
104 $('input[type=radio][name=compression_level]').attr('disabled', false)
105 $('#overlay').css('visibility', 'hidden');
106 //$('#preview-area').show();
107 }
108 }
109 })
110 });
111
112 function backgroundInputs () {
113 const bgInputs = $('#solid_selecter');
114 var input = $('input[type=radio][name=background_type]:checked');
115 if (input.val() === 'solid') {
116 bgInputs.show();
117 } else {
118 bgInputs.hide();
119 }
120
121 };
122
123 $('#bg_display_picker').on('input', function () {
124 $('#color_range').html($(this).val());
125 $('#bg_color').val($(this).val());
126 });
127
128 function transparancyOptions() {
129 $('#transparency_range').html($('#bg_transparency').val());
130 };
131
132 });
1 jQuery(document).ready(function($)
2 {
3 $('.emr-installer').on('click', function(e){
4 e.preventDefault();
5 var button = $(this);
6 var plugin = button.data('plugin');
7 var nonce = $('#upsell-nonce').val();
8
9 button.text(emr_upsell.installing);
10
11 var enr_eg_opts = {
12 url: emr_upsell.ajax,
13 type: 'post',
14 async: true,
15 cache: false,
16 dataType: 'json',
17 data: {
18 action: 'emr_plugin_install',
19 nonce: nonce,
20 plugin: plugin //'https://downloads.wordpress.org/plugin/envira-gallery-lite.zip',
21 },
22 success: function(response) {
23 $(button).addClass('hidden');
24
25 $('.emr-activate[data-plugin="' + plugin + '"]').removeClass('hidden');
26
27 },
28 error: function(xhr, textStatus, e) {
29 },
30 };
31
32 $.ajax(enr_eg_opts);
33 });
34
35 $('.emr-activate').on('click', function(e){
36 e.preventDefault();
37
38 var button = $(this);
39 var plugin = button.data('plugin');
40 var nonce = $('#upsell-nonce-activate').val();
41
42 var enr_eg_opts = {
43 url: emr_upsell.ajax,
44 type: 'post',
45 async: true,
46 cache: false,
47 dataType: 'json',
48 data: {
49 action: 'emr_plugin_activate',
50 nonce: nonce,
51 plugin: plugin,
52 },
53 success: function(response) {
54 $(button).addClass('hidden')
55 $('.emr-activate-done[data-plugin="' + plugin + '"]').removeClass('hidden');
56
57 },
58 error: function(xhr, textStatus, e) {
59 },
60 };
61 $.ajax(enr_eg_opts);
62 });
63
64 });
1 msgid ""
2 msgstr ""
3 "Project-Id-Version: enable-media-replace\n"
4 "Report-Msgid-Bugs-To: \n"
5 "POT-Creation-Date: 2010-09-13 14:57+0100\n"
6 "PO-Revision-Date: \n"
7 "Last-Translator: Michael Bering Petersen <michaelbering@gmail.com>\n"
8 "Language-Team: \n"
9 "MIME-Version: 1.0\n"
10 "Content-Type: text/plain; charset=UTF-8\n"
11 "Content-Transfer-Encoding: 8bit\n"
12 "X-Poedit-KeywordsList: __;_e\n"
13 "X-Poedit-Basepath: .\n"
14 "X-Poedit-SearchPath-0: .\n"
15
16 #: enable-media-replace.php:40
17 #: enable-media-replace.php:68
18 msgid "Replace media"
19 msgstr "Udskift media"
20
21 #: enable-media-replace.php:68
22 msgid "Upload a new file"
23 msgstr "Upload en ny fil"
24
25 #: enable-media-replace.php:68
26 msgid "To replace the current file, click the link and upload a replacement."
27 msgstr "Hvis du ønsker at udskifte den aktuelle fil - klik på linket og upload den nye fil."
28
29 #: popup.php:14
30 #: upload.php:21
31 msgid "You do not have permission to upload files."
32 msgstr "Du har ikke tilladelse til at uploade filer."
33
34 #: popup.php:30
35 msgid "Replace Media Upload"
36 msgstr "Replace Media Upload"
37
38 #: popup.php:41
39 msgid "NOTE: You are about to replace the media file"
40 msgstr "OBS: Du er nu ved at overskrive filen,"
41
42 #: popup.php:41
43 msgid "There is no undo. Think about it!"
44 msgstr "Der er ingen mulighed for at fortryde, så tænkt dig godt om inden du accepterer."
45
46 #: popup.php:43
47 msgid "Choose a file to upload from your computer"
48 msgstr "Vælg den fil du ønsker at uploade fra din computer."
49
50 #: popup.php:47
51 msgid "Select media replacement type:"
52 msgstr "Vælg media type:"
53
54 #: popup.php:49
55 msgid "Just replace the file"
56 msgstr "Udskift filen"
57
58 #: popup.php:50
59 msgid "Note: This option requires you to upload a file of the same type ("
60 msgstr "OBS: Denne mulighed kræver at du uploader en fil af samme type ("
61
62 #: popup.php:50
63 msgid ") as the one you are replacing. The name of the attachment will stay the same ("
64 msgstr ") som den du overskriver. Navnet på filen vil forblive det samme ("
65
66 #: popup.php:50
67 msgid ") no matter what the file you upload is called."
68 msgstr ") uanset hvad den fil du uploader hedder."
69
70 #: popup.php:52
71 msgid "Replace the file, use new file name and update all links"
72 msgstr "Overskriv filen, brug det nye fil navn og opdater alle links-"
73
74 #: popup.php:53
75 msgid "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 ("
76 msgstr "OBS: Hvis du vælger denne mulighed - vil filnavnet og filtypen som du er ved at uploade overskrive den gamle fil. Alle links der peger på den nuværende fil ("
77
78 #: popup.php:53
79 msgid ") will be updated to point to the new file name."
80 msgstr ") vil blive opdateret så de peger på den nye fil."
81
82 #: popup.php:55
83 msgid "Upload"
84 msgstr "Upload"
85
86 #: popup.php:55
87 msgid "Cancel"
88 msgstr "Fortryd"
89
1 msgid ""
2 msgstr ""
3 "Project-Id-Version: enable-media-replace\n"
4 "Report-Msgid-Bugs-To: \n"
5 "POT-Creation-Date: 2010-09-13 14:57+0100\n"
6 "PO-Revision-Date: \n"
7 "Last-Translator: Martin Lettner <m.lettner@gmail.com>\n"
8 "Language-Team: \n"
9 "MIME-Version: 1.0\n"
10 "Content-Type: text/plain; charset=UTF-8\n"
11 "Content-Transfer-Encoding: 8bit\n"
12 "X-Poedit-KeywordsList: __;_e\n"
13 "X-Poedit-Basepath: .\n"
14 "X-Poedit-SearchPath-0: .\n"
15
16 #: enable-media-replace.php:40
17 #: enable-media-replace.php:68
18 msgid "Replace media"
19 msgstr "Datei ersetzen"
20
21 #: enable-media-replace.php:68
22 msgid "Upload a new file"
23 msgstr "Eine neue Datei hochladen"
24
25 #: enable-media-replace.php:68
26 msgid "To replace the current file, click the link and upload a replacement."
27 msgstr "Eine neue Datei hochladen, die die aktuelle ersetzen soll."
28
29 #: popup.php:14
30 #: upload.php:21
31 msgid "You do not have permission to upload files."
32 msgstr "Sie haben nicht die benötigten Rechte um Dateien hochzuladen."
33
34 #: popup.php:30
35 msgid "Replace Media Upload"
36 msgstr "Medien-Datei ersetzen"
37
38 #: popup.php:41
39 msgid "NOTE: You are about to replace the media file"
40 msgstr "HINWEIS: Sie sind dabei, eine Datei in der Mediathek zu ersetzen"
41
42 #: popup.php:41
43 msgid "There is no undo. Think about it!"
44 msgstr "Diese Aktion kann nicht rückgängig gemacht werden!"
45
46 #: popup.php:43
47 msgid "Choose a file to upload from your computer"
48 msgstr "Datei vom Computer auswählen:"
49
50 #: popup.php:47
51 msgid "Select media replacement type:"
52 msgstr "Wählen Sie die gewünschte Aktion:"
53
54 #: popup.php:49
55 msgid "Just replace the file"
56 msgstr "Datei einfach ersetzen"
57
58 #: popup.php:50
59 msgid "Note: This option requires you to upload a file of the same type ("
60 msgstr "Hinweis: Die Datei muss vom selben Dateityp sein ("
61
62 #: popup.php:50
63 msgid ") as the one you are replacing. The name of the attachment will stay the same ("
64 msgstr ") wie die Datei, die Sie ersetzen. Der Name der der Datei bleibt erhalten ("
65
66 #: popup.php:50
67 msgid ") no matter what the file you upload is called."
68 msgstr "), ganz egal wie die neue Datei heißt."
69
70 #: popup.php:52
71 msgid "Replace the file, use new file name and update all links"
72 msgstr "Datei ersetzen, aber neuen Dateinamen verwenden und alle Links automatisch aktualisieren"
73
74 #: popup.php:53
75 msgid "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 ("
76 msgstr "Hinweis: Der Name der neuen Datei wird die alte ersetzen. Alle Verweise auf die aktuelle Datei ("
77
78 #: popup.php:53
79 msgid ") will be updated to point to the new file name."
80 msgstr ") werden auf die neue aktualisiert."
81
82 #: popup.php:55
83 msgid "Upload"
84 msgstr "Hochladen"
85
86 #: popup.php:55
87 msgid "Cancel"
88 msgstr "Abbrechen"
89
1 msgid ""
2 msgstr ""
3 "Project-Id-Version: Enable Media Replace\n"
4 "Report-Msgid-Bugs-To: \n"
5 "POT-Creation-Date: 2011-03-24 10:57+0100\n"
6 "PO-Revision-Date: 2011-03-24 11:41+0100\n"
7 "Last-Translator: François Collette <francois.collette@gmail.com>\n"
8 "Language-Team: \n"
9 "MIME-Version: 1.0\n"
10 "Content-Type: text/plain; charset=UTF-8\n"
11 "Content-Transfer-Encoding: 8bit\n"
12 "X-Poedit-KeywordsList: _e;__\n"
13 "X-Poedit-Basepath: .\n"
14 "X-Poedit-SearchPath-0: .\n"
15
16 #: enable-media-replace.php:39
17 #: enable-media-replace.php:67
18 msgid "Replace media"
19 msgstr "Remplacer le média"
20
21 #: enable-media-replace.php:67
22 msgid "Upload a new file"
23 msgstr "Choisir le nouveau fichier"
24
25 #: enable-media-replace.php:67
26 msgid "To replace the current file, click the link and upload a replacement."
27 msgstr "Pour remplacer le fichier actuel, cliquez ci-dessus et choisissez le nouveau fichier."
28
29 #: popup.php:14
30 #: upload.php:3
31 msgid "You do not have permission to upload files."
32 msgstr "Vous n'avez pas la permission d'envoyer des fichiers."
33
34 #: popup.php:30
35 msgid "Replace Media Upload"
36 msgstr "Remplacement de média"
37
38 #: popup.php:46
39 msgid "NOTE: You are about to replace the media file"
40 msgstr "ATTENTION : vous vous apprêtez à remplacer le fichier"
41
42 #: popup.php:46
43 msgid "There is no undo. Think about it!"
44 msgstr "Cette opération est irréversible. Soyez sûr(e) de vous !"
45
46 #: popup.php:48
47 msgid "Choose a file to upload from your computer"
48 msgstr "Envoyez un fichier depuis votre ordinateur :"
49
50 #: popup.php:52
51 msgid "Select media replacement type:"
52 msgstr "Choisissez la méthode de remplacement :"
53
54 #: popup.php:54
55 msgid "Just replace the file"
56 msgstr "Remplacer le fichier seulement"
57
58 #: popup.php:55
59 msgid "Note: This option requires you to upload a file of the same type ("
60 msgstr "Avec cette option, vous devez choisir un fichier du même type ("
61
62 #: popup.php:55
63 msgid ") as the one you are replacing. The name of the attachment will stay the same ("
64 msgstr ") que le précédent. Le nom du fichier actuel ("
65
66 #: popup.php:55
67 msgid ") no matter what the file you upload is called."
68 msgstr ") sera conservé, quel que soit le nom de votre nouveau fichier."
69
70 #: popup.php:57
71 msgid "Replace the file, use new file name and update all links"
72 msgstr "Remplacer le fichier, utiliser le nouveau nom de fichier et mettre à jour tous les liens"
73
74 #: popup.php:58
75 msgid "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 ("
76 msgstr "Avec cette option, le nom et le type de votre nouveau fichier vont remplacer ceux du fichier actuel. Tous les liens vers celui-ci ("
77
78 #: popup.php:58
79 msgid ") will be updated to point to the new file name."
80 msgstr ") seront mis à jour selon le nouveau nom du fichier."
81
82 #: popup.php:60
83 msgid "Upload"
84 msgstr "Envoyer"
85
86 #: popup.php:60
87 msgid "Cancel"
88 msgstr "Annuler"
89
90 #: upload.php:35
91 msgid "File type does not meet security guidelines. Try another."
92 msgstr "Ce type de fichier est incompatible avec les règles de sécurité. Essayez-en un autre."
93
1 msgid ""
2 msgstr ""
3 "Project-Id-Version: Enable Media Replace\n"
4 "Report-Msgid-Bugs-To: \n"
5 "POT-Creation-Date: 2011-03-24 10:57+0100\n"
6 "PO-Revision-Date: 2012-11-27 12:03+0100\n"
7 "Last-Translator: Marco <marco@blackstudio.it>\n"
8 "Language-Team: Black Studio <info@blackstudio.it>\n"
9 "MIME-Version: 1.0\n"
10 "Content-Type: text/plain; charset=UTF-8\n"
11 "Content-Transfer-Encoding: 8bit\n"
12 "X-Poedit-KeywordsList: _e;__\n"
13 "X-Poedit-Basepath: .\n"
14 "X-Poedit-Language: Italian\n"
15 "X-Poedit-Country: ITALY\n"
16 "X-Poedit-SearchPath-0: .\n"
17
18 #: enable-media-replace.php:39
19 #: enable-media-replace.php:67
20 msgid "Replace media"
21 msgstr "Sostituisci file"
22
23 #: enable-media-replace.php:67
24 msgid "Upload a new file"
25 msgstr "Carica un nuovo file"
26
27 #: enable-media-replace.php:67
28 msgid "To replace the current file, click the link and upload a replacement."
29 msgstr "Per sostituire il file corrente, clicca il link e carica un file sostitutivo."
30
31 #: popup.php:14
32 #: upload.php:3
33 msgid "You do not have permission to upload files."
34 msgstr "Non hai sufficienti permessi per caricare file."
35
36 #: popup.php:30
37 msgid "Replace Media Upload"
38 msgstr "Caricamento file sostitutivo"
39
40 #: popup.php:46
41 msgid "NOTE: You are about to replace the media file"
42 msgstr "NOTA: Stai per sostituire il file"
43
44 #: popup.php:46
45 msgid "There is no undo. Think about it!"
46 msgstr "Questa operazione non è reversibile. Fai attenzione!"
47
48 #: popup.php:48
49 msgid "Choose a file to upload from your computer"
50 msgstr "Seleziona un file da caricare dal tuo computer"
51
52 #: popup.php:52
53 msgid "Select media replacement type:"
54 msgstr "Seleziona il tipo di sostituzione:"
55
56 #: popup.php:54
57 msgid "Just replace the file"
58 msgstr "Sostituire semplicemente il file"
59
60 #: popup.php:55
61 msgid "Note: This option requires you to upload a file of the same type ("
62 msgstr "Nota: Questa opzione richiede il caricamento di un file dello stesso tipo ("
63
64 #: popup.php:55
65 msgid ") as the one you are replacing. The name of the attachment will stay the same ("
66 msgstr ") di quello sostituito. Il nome dell'allegato rimarrà invariato ("
67
68 #: popup.php:55
69 msgid ") no matter what the file you upload is called."
70 msgstr ") indipendentemente dal nome del file caricato."
71
72 #: popup.php:57
73 msgid "Replace the file, use new file name and update all links"
74 msgstr "Sostituire il file, usare il nome del nuovo file ed aggiornare tutti i collegamenti"
75
76 #: popup.php:58
77 msgid "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 ("
78 msgstr "Nota: Se selezioni questa opzione, il nome ed il tipo di file che stai per caricare sostituiranno quelli del file precedente. Tutti i collegamenti che puntavano al file precedente ("
79
80 #: popup.php:58
81 msgid ") will be updated to point to the new file name."
82 msgstr ") saranno aggiornati per puntare al nuovo file."
83
84 #: popup.php:60
85 msgid "Upload"
86 msgstr "Carica"
87
88 #: popup.php:60
89 msgid "Cancel"
90 msgstr "Annulla"
91
92 #: upload.php:35
93 msgid "File type does not meet security guidelines. Try another."
94 msgstr "Il tipo di file non rispetta le restrizioni di sicurezza. Riprova con un altro tipo."
95
1 msgid ""
2 msgstr ""
3 "Project-Id-Version: enable-media-replace\n"
4 "Report-Msgid-Bugs-To: \n"
5 "POT-Creation-Date: 2015-01-19 09:00+0900\n"
6 "PO-Revision-Date: \n"
7 "Last-Translator: chacomv\n"
8 "Language-Team: \n"
9 "MIME-Version: 1.0\n"
10 "Content-Type: text/plain; charset=UTF-8\n"
11 "Content-Transfer-Encoding: 8bit\n"
12 "X-Poedit-KeywordsList: __;_e\n"
13 "X-Poedit-Basepath: .\n"
14 "X-Generator: Poedit 1.5.7\n"
15 "X-Poedit-SearchPath-0: .\n"
16
17 #: enable-media-replace.php:40 enable-media-replace.php:79
18 #: enable-media-replace.php:120
19 msgid "Replace media"
20 msgstr "メディアを置換"
21
22 #: enable-media-replace.php:79
23 msgid "Upload a new file"
24 msgstr "新しいファイルをアップロード"
25
26 #: enable-media-replace.php:79
27 msgid "To replace the current file, click the link and upload a replacement."
28 msgstr ""
29 "現在のファイルを置換するには、このリンクをクリックしてアップロードします。"
30
31 #: enable-media-replace.php:168
32 msgid "Revised"
33 msgstr "変更されました"
34
35 #: popup.php:14 upload.php:3
36 msgid "You do not have permission to upload files."
37 msgstr "ファイルをアップロードする権限がありません。"
38
39 #: popup.php:30
40 msgid "Replace Media Upload"
41 msgstr "新しいメディアファイルをアップロード"
42
43 #: popup.php:46
44 msgid "NOTE: You are about to replace the media file"
45 msgstr "※ このメディアを置き換えようとしています。"
46
47 #: popup.php:46
48 msgid "There is no undo. Think about it!"
49 msgstr "元に戻せませんのでご注意ください。"
50
51 #: popup.php:48
52 msgid "Choose a file to upload from your computer"
53 msgstr "コンピューターからアップロードするファイルを選択"
54
55 #: popup.php:52
56 msgid "Select media replacement type:"
57 msgstr "メディアを置換する方式を選択:"
58
59 #: popup.php:54
60 msgid "Just replace the file"
61 msgstr "ファイルの置換のみ"
62
63 #: popup.php:55
64 msgid "Note: This option requires you to upload a file of the same type ("
65 msgstr ""
66 "※ このオプションは、元のファイルと同じファイル形式でアップロードする必要があ"
67 "ります。("
68
69 #: popup.php:55
70 msgid ""
71 ") as the one you are replacing. The name of the attachment will stay the "
72 "same ("
73 msgstr ") ファイル名は同じになります。("
74
75 #: popup.php:55
76 msgid ") no matter what the file you upload is called."
77 msgstr ")"
78
79 #: popup.php:57
80 msgid "Replace the file, use new file name and update all links"
81 msgstr "ファイルを置換して新しいファイル名で全てのリンクを更新する"
82
83 #: popup.php:58
84 msgid ""
85 "Note: If you check this option, the name and type of the file you are about "
86 "to upload will replace the old file. All links pointing to the current file ("
87 msgstr ""
88 "※ このオプションをチェックすると、アップロードしたファイルの名称と形式に置換"
89 "されます。現在のファイル名("
90
91 #: popup.php:58
92 msgid ") will be updated to point to the new file name."
93 msgstr ")へのリンクが全て新しいファイル名に更新されます。"
94
95 #: popup.php:60
96 msgid "Upload"
97 msgstr "アップロード"
98
99 #: popup.php:60
100 msgid "Cancel"
101 msgstr "キャンセル"
102
103 #: upload.php:33
104 msgid "File type does not meet security guidelines. Try another."
105 msgstr ""
106 "ファイル形式がセキュリティ的に許可されません。他の形式をお試しください。"
107
108 #: popup.php:63
109 msgid ""
110 "Please note that if you upload a new image, only embeds/links of the "
111 "original size image will be replaced in your posts."
112 msgstr ""
113 "新しいファイルをアップロードすると、元のサイズの画像へのリンクや埋め込みのみ"
114 "が置換されますのでご注意ください。"
1 msgid ""
2 msgstr ""
3 "Project-Id-Version: enable-media-replace\n"
4 "Report-Msgid-Bugs-To: \n"
5 "POT-Creation-Date: 2010-09-10 20:53+0100\n"
6 "PO-Revision-Date: \n"
7 "Last-Translator: WarmStal D!sign | Ben ter Stal <mail@warmstal.nl>\n"
8 "Language-Team: \n"
9 "MIME-Version: 1.0\n"
10 "Content-Type: text/plain; charset=UTF-8\n"
11 "Content-Transfer-Encoding: 8bit\n"
12 "X-Poedit-KeywordsList: __;_e\n"
13 "X-Poedit-Basepath: .\n"
14 "X-Poedit-SearchPath-0: .\n"
15
16 #: enable-media-replace.php:26
17 #: enable-media-replace.php:45
18 msgid "Replace media"
19 msgstr "Vervangen media"
20
21 #: enable-media-replace.php:45
22 msgid "Upload a new file"
23 msgstr "Uploaden nieuw bestand"
24
25 #: enable-media-replace.php:45
26 msgid "To replace the current file, click the link and upload a replacement."
27 msgstr "Klik om het bestaande bestand te vervangen door een nieuw te uploaden bestand."
28
29 #: popup.php:7
30 #: upload.php:10
31 msgid "You do not have permission to upload files."
32 msgstr "U heeft geen rechten om bestanden te uplaoden"
33
34 #: popup.php:23
35 msgid "Replace Media Upload"
36 msgstr "Replace Media Upload"
37
38 #: popup.php:34
39 msgid "NOTE: You are about to replace the media file"
40 msgstr "Opmerking: U staat op het punt het media bestand"
41
42 #: popup.php:34
43 msgid "There is no undo. Think about it!"
44 msgstr "Deze bewerking kan niet ongedaan worden gemaakt!"
45
46 #: popup.php:36
47 msgid "Choose a file to upload from your computer"
48 msgstr "Selecteer een bestand op de PC om te uploaden"
49
50 #: popup.php:40
51 msgid "Select media replacement type:"
52 msgstr "Selecteer de wijze van vervanging"
53
54 #: popup.php:42
55 msgid "Just replace the file"
56 msgstr "Vervang alleen het bestand"
57
58 #: popup.php:43
59 msgid "Note: This option requires you to upload a file of the same type ("
60 msgstr "Opmerking: voor deze optie moet u een bestand van hetzelfde type uploaden ("
61
62 #: popup.php:43
63 msgid ") as the one you are replacing. The name of the attachment will stay the same ("
64 msgstr ") De naam in de media bibliotheek blijft hetzelfde ("
65
66 #: popup.php:43
67 msgid ") no matter what the file you upload is called."
68 msgstr ") onafhankelijk van de naam van het nieuwe bestand."
69
70 #: popup.php:45
71 msgid "Replace the file, use new file name and update all links"
72 msgstr "Vervang het bestand, gebruik de nieuwe naam en werk alle links bij."
73
74 #: popup.php:46
75 msgid "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 ("
76 msgstr "Opmerking: bij deze keuze wordt het bestand volledig vervangen. Alle links naar het huidige bestand ("
77
78 #: popup.php:46
79 msgid ") will be updated to point to the new file name."
80 msgstr ") worden bijgewerkt naar het nieuwe bestand."
81
82 #: popup.php:48
83 msgid "Upload"
84 msgstr "Uploaden"
85
86 #: popup.php:48
87 msgid "Cancel"
88 msgstr "Annuleren"
89
1 msgid ""
2 msgstr ""
3 "Project-Id-Version: enable-media-replace\n"
4 "Report-Msgid-Bugs-To: \n"
5 "POT-Creation-Date: 2010-09-13 14:57+0100\n"
6 "PO-Revision-Date: \n"
7 "Last-Translator: Roger <rogerhnn@hotmail.com>\n"
8 "Language-Team: Roger Nobrega <rogerhnn@hotmail.com>\n"
9 "MIME-Version: 1.0\n"
10 "Content-Type: text/plain; charset=UTF-8\n"
11 "Content-Transfer-Encoding: 8bit\n"
12 "X-Poedit-KeywordsList: __;_e\n"
13 "X-Poedit-Basepath: .\n"
14 "X-Generator: Poedit 1.5.4\n"
15 "Language: Português - Brasil\n"
16 "X-Poedit-SourceCharset: UTF-8\n"
17 "X-Poedit-SearchPath-0: .\n"
18
19 #: enable-media-replace.php:40 enable-media-replace.php:68
20 msgid "Replace media"
21 msgstr "Substituir mídia"
22
23 #: enable-media-replace.php:68
24 msgid "Upload a new file"
25 msgstr "Enviar novo arquivo"
26
27 #: enable-media-replace.php:68
28 msgid "To replace the current file, click the link and upload a replacement."
29 msgstr ""
30 "Para subtituir o arquivo atual, clique no link e carregue um substituto"
31
32 #: popup.php:14 upload.php:21
33 msgid "You do not have permission to upload files."
34 msgstr "Você não tem permissões para enviar arquivos."
35
36 #: popup.php:30
37 msgid "Replace Media Upload"
38 msgstr "Enviar Mídia Substituta"
39
40 #: popup.php:41
41 msgid "NOTE: You are about to replace the media file"
42 msgstr "NOTA: Você irá substituir o arquivo de mídia"
43
44 #: popup.php:41
45 msgid "There is no undo. Think about it!"
46 msgstr "Não é possível cancelar esta ação."
47
48 #: popup.php:43
49 msgid "Choose a file to upload from your computer"
50 msgstr "Escolha um arquivo para enviar do seu computador"
51
52 #: popup.php:47
53 msgid "Select media replacement type:"
54 msgstr "Selecione o tipo de substituição"
55
56 #: popup.php:49
57 msgid "Just replace the file"
58 msgstr "Apenas substituir arquivo"
59
60 #: popup.php:50
61 msgid "Note: This option requires you to upload a file of the same type ("
62 msgstr "Nota: Esta opção requer o carregamento de um arquivo do mesmo tipo ("
63
64 #: popup.php:50
65 msgid ""
66 ") as the one you are replacing. The name of the attachment will stay the "
67 "same ("
68 msgstr ""
69 ") do que está sendo substituído. O nome do arquivo permanecerá o mesmo("
70
71 #: popup.php:50
72 msgid ") no matter what the file you upload is called."
73 msgstr "), independente do nome do arquivo enviado."
74
75 #: popup.php:52
76 msgid "Replace the file, use new file name and update all links"
77 msgstr ""
78 "Substituir o arquivo, usar o novo nome de arquivo, e atualizar todos os links"
79
80 #: popup.php:53
81 msgid ""
82 "Note: If you check this option, the name and type of the file you are about "
83 "to upload will replace the old file. All links pointing to the current file ("
84 msgstr ""
85 "Nota: Se selecionar esta opção, o nome e tipo do arquivo que você enviar irá "
86 "substituir os do arquivo antigo. Todos os links do arquivo atual ("
87
88 #: popup.php:53
89 msgid ") will be updated to point to the new file name."
90 msgstr ") serão atualizados para o novo arquivo."
91
92 #: popup.php:55
93 msgid "Upload"
94 msgstr "Enviar"
95
96 #: popup.php:55
97 msgid "Cancel"
98 msgstr "Cancelar"
1 msgid ""
2 msgstr ""
3 "Project-Id-Version: enable-media-replace\n"
4 "Report-Msgid-Bugs-To: \n"
5 "POT-Creation-Date: 2017-02-10 08:48+0000\n"
6 "PO-Revision-Date: \n"
7 "Last-Translator: Pedro Mendonça <ped.gaspar@gmail.com>\n"
8 "Language-Team: Pedro Mendonça <ped.gaspar@gmail.com>\n"
9 "Language: pt_PT\n"
10 "MIME-Version: 1.0\n"
11 "Content-Type: text/plain; charset=UTF-8\n"
12 "Content-Transfer-Encoding: 8bit\n"
13 "X-Poedit-KeywordsList: __;_e\n"
14 "X-Poedit-Basepath: ..\n"
15 "X-Generator: Poedit 1.8.11\n"
16 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
17 "X-Poedit-SourceCharset: UTF-8\n"
18 "X-Poedit-WPHeader: enable-media-replace.php\n"
19 "X-Poedit-SearchPath-0: .\n"
20
21 #: enable-media-replace.php:38 enable-media-replace.php:64
22 #: enable-media-replace.php:105
23 msgid "Replace media"
24 msgstr "Substituir multimédia"
25
26 #: enable-media-replace.php:64
27 msgid "Upload a new file"
28 msgstr "Carregar novo ficheiro"
29
30 #: enable-media-replace.php:64
31 msgid "To replace the current file, click the link and upload a replacement."
32 msgstr ""
33 "Para subtituir o ficheiro actual, clique na ligação e carregue um substituto."
34
35 #: enable-media-replace.php:156
36 msgid "Revised"
37 msgstr "Revisto"
38
39 #: popup.php:14 upload.php:3
40 msgid "You do not have permission to upload files."
41 msgstr "Não tem permissão para carregar ficheiros."
42
43 #: popup.php:29
44 msgid "Replace Media Upload"
45 msgstr "Carregar multimédia de substituição"
46
47 #: popup.php:45
48 #, php-format
49 msgid ""
50 "NOTE: You are about to replace the media file \"%s\". There is no undo. "
51 "Think about it!"
52 msgstr ""
53 "NOTA: Está prestes a substituir o ficheiro multimédia \"%s\". Não será "
54 "possível voltar a trás!"
55
56 #: popup.php:47
57 msgid "Choose a file to upload from your computer"
58 msgstr "Escolher um ficheiro para carregar a partir do computador"
59
60 #: popup.php:54
61 msgid "Select media replacement type:"
62 msgstr "Seleccione o tipo de substituição de multimédia:"
63
64 #: popup.php:56
65 msgid "Just replace the file"
66 msgstr "Apenas substituir o ficheiro"
67
68 #: popup.php:57
69 #, php-format
70 msgid ""
71 "Note: This option requires you to upload a file of the same type (%s) as the "
72 "one you are replacing. The name of the attachment will stay the same (%s) no "
73 "matter what the file you upload is called."
74 msgstr ""
75 "Nota: Esta opção requer o carregamento de um ficheiro do mesmo tipo (%s) "
76 "daquele a substituir. O nome do ficheiro permanecerá o mesmo (%s), "
77 "independentemente do nome do ficheiro carregado."
78
79 #: popup.php:60
80 msgid "Replace the file, use new file name and update all links"
81 msgstr ""
82 "Substituir o ficheiro, usar o novo nome de ficheiro e actualizar todas as "
83 "ligações"
84
85 #: popup.php:61
86 #, php-format
87 msgid ""
88 "Note: If you check this option, the name and type of the file you are about "
89 "to upload will replace the old file. All links pointing to the current file "
90 "(%s) will be updated to point to the new file name."
91 msgstr ""
92 "Nota: Se seleccionar esta opção, o nome e tipo do ficheiro que está prestes "
93 "a carregar irá substituir os do ficheiro antigo. Todas as ligações que "
94 "referenciam o ficheiro actual (%s) serão actualizadas de modo a referenciar "
95 "o novo nome de ficheiro."
96
97 #: popup.php:62
98 msgid ""
99 "Please note that if you upload a new image, only embeds/links of the "
100 "original size image will be replaced in your posts."
101 msgstr ""
102 "Por favor tenha em atenção que se carregar uma nova imagem, apenas as "
103 "imagens incorporadas e ligações com o tamanho original serão substituídas "
104 "nos seus artigos."
105
106 #: popup.php:67
107 msgid "Upload"
108 msgstr "Carregar"
109
110 #: popup.php:67
111 msgid "Cancel"
112 msgstr "Cancelar"
113
114 #: upload.php:26
115 #, php-format
116 msgid ""
117 "The file %1$s can not be deleted by the web server, most likely because the "
118 "permissions on the file are wrong."
119 msgstr ""
120 "O ficheiro %1$s não pode ser apagado pelo servidor web, provavelmente porque "
121 "as permissões do ficheiro estão incorrectas."
122
123 #: upload.php:84
124 msgid "File type does not meet security guidelines. Try another."
125 msgstr ""
126 "O tipo de ficheiro não está de acordo com os padrões de segurança. Tente "
127 "outro."
128
129 #. Plugin Name of the plugin/theme
130 msgid "Enable Media Replace"
131 msgstr "Enable Media Replace"
132
133 #. Plugin URI of the plugin/theme
134 msgid "http://www.mansjonasson.se/enable-media-replace"
135 msgstr "http://www.mansjonasson.se/enable-media-replace"
136
137 #. Description of the plugin/theme
138 msgid ""
139 "Enable replacing media files by uploading a new file in the \"Edit Media\" "
140 "section of the WordPress Media Library."
141 msgstr ""
142 "Permite substituir ficheiros multimédia através de carregar um novo ficheiro "
143 "na secção \"Editar multimédia\" da biblioteca multimédia do WordPress."
144
145 #. Author of the plugin/theme
146 msgid "Måns Jonasson"
147 msgstr "Måns Jonasson"
148
149 #. Author URI of the plugin/theme
150 msgid "http://www.mansjonasson.se"
151 msgstr "http://www.mansjonasson.se"
1 msgid ""
2 msgstr ""
3 "Project-Id-Version: enable-media-replace\n"
4 "Report-Msgid-Bugs-To: \n"
5 "POT-Creation-Date: 2010-09-13 14:57+0100\n"
6 "PO-Revision-Date: 2013-01-18 14:58+0400\n"
7 "Last-Translator: Vladislav (me@dsigh.ru)\n"
8 "Language-Team: DigitalSigh\n"
9 "MIME-Version: 1.0\n"
10 "Content-Type: text/plain; charset=UTF-8\n"
11 "Content-Transfer-Encoding: 8bit\n"
12 "X-Poedit-KeywordsList: __;_e\n"
13 "X-Poedit-Basepath: .\n"
14 "X-Poedit-Language: Russian\n"
15 "X-Poedit-Country: RUSSIAN FEDERATION\n"
16 "X-Poedit-SourceCharset: utf-8\n"
17 "X-Poedit-SearchPath-0: .\n"
18 "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11) ? 0 : ((n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20)) ? 1 : 2)\n"
19
20 #: enable-media-replace.php:40
21 #: enable-media-replace.php:68
22 msgid "Replace media"
23 msgstr "Заменить"
24
25 #: enable-media-replace.php:68
26 msgid "Upload a new file"
27 msgstr "Загрузить новый файл"
28
29 #: enable-media-replace.php:68
30 msgid "To replace the current file, click the link and upload a replacement."
31 msgstr "Для того, чтобы заменить текущий файл, нажмите на ссылку и загрузите замену."
32
33 #: popup.php:14
34 #: upload.php:21
35 msgid "You do not have permission to upload files."
36 msgstr "У вас нет прав для загрузки файлов."
37
38 #: popup.php:30
39 msgid "Replace Media Upload"
40 msgstr "Загрузка файла для замены"
41
42 #: popup.php:41
43 msgid "NOTE: You are about to replace the media file"
44 msgstr "ПРИМЕЧАНИЕ: Вы собираетесь заменить медиафайл"
45
46 #: popup.php:41
47 msgid "There is no undo. Think about it!"
48 msgstr "Данную операцию нельзя отменить. Учтите это!"
49
50 #: popup.php:43
51 msgid "Choose a file to upload from your computer"
52 msgstr "Выберите файл для загрузки с вашего компьютера:"
53
54 #: popup.php:47
55 msgid "Select media replacement type:"
56 msgstr "Выберите тип замены:"
57
58 #: popup.php:49
59 msgid "Just replace the file"
60 msgstr "Только заменить файл"
61
62 #: popup.php:50
63 msgid "Note: This option requires you to upload a file of the same type ("
64 msgstr "Этот вариант требуется, если нужно загрузить файл того же типа ("
65
66 #: popup.php:50
67 msgid ") as the one you are replacing. The name of the attachment will stay the same ("
68 msgstr "), как оригинальный. Имя вложения останется тем же ("
69
70 #: popup.php:50
71 msgid ") no matter what the file you upload is called."
72 msgstr ") не зависимо от того, как называется загружаемый файл."
73
74 #: popup.php:52
75 msgid "Replace the file, use new file name and update all links"
76 msgstr "Заменить файл, использовать новое имя и обновить все ссылки"
77
78 #: popup.php:53
79 msgid "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 ("
80 msgstr "Если выбрать этот вариант, то имя и тип файла, который вы собираетесь загрузить, заменят старые. Все ссылки, указывающие на текущий файл ("
81
82 #: popup.php:53
83 msgid ") will be updated to point to the new file name."
84 msgstr ") будут обновлены новыми."
85
86 #: popup.php:55
87 msgid "Upload"
88 msgstr "Загрузить"
89
90 #: popup.php:55
91 msgid "Cancel"
92 msgstr "Отмена"
93
94 #~ msgid "Replace media upload"
95 #~ msgstr "Загрузка файла для замены"