Version Description
Release date: 17th July 2019 * Check if medium size !> 400px, display that one, otherwise smallest. * Fixed: Links not updated when using Advanced Custom Fields * Fixed: Fails silently when file is too big for upload * When source file does not exist, show placeholder instead of failed image load * Fixed: Fatal error when replacing images * Fixed: Not the right time zone on replace * Fixed Beaver Builder incompatibility by not allowing replace with rename. * Fixed: Cannot replace non default Wordpress file types, even those allowed to upload [ Media Library Assistant compat ] * Fixed: error when trying to remove a file that doesn't exist - because the files are actually on another server
Download this release
Release Info
Developer | ShortPixel |
Plugin | Enable Media Replace |
Version | 3.3.2 |
Comparing to | |
See all releases |
Code changes from version 3.3.1 to 3.3.2
- build/shortpixel/PackageLoader.php +73 -0
- build/shortpixel/autoload.php +5 -0
- build/shortpixel/composer.json +1 -0
- build/shortpixel/log/composer.json +18 -0
- build/shortpixel/log/src/DebugItem.php +136 -0
- build/shortpixel/log/src/ShortPixelLogger.php +322 -0
- build/shortpixel/log/src/view-debug-box.php +57 -0
- build/shortpixel/notices/composer.json +31 -0
- build/shortpixel/notices/src/NoticeController.php +194 -0
- build/shortpixel/notices/src/NoticeModel.php +116 -0
- build/shortpixel/notices/src/css/notices.css +21 -0
- build/shortpixel/notices/src/css/notices.scss +39 -0
- classes/emr-plugin.php +33 -5
- classes/externals.php +64 -0
- classes/file.php +22 -1
- classes/replacer.php +61 -15
- classes/uihelper.php +297 -0
- composer.json +25 -0
- css/admin.css +68 -2
- enable-media-replace.php +7 -2
- js/emr_admin.js +164 -16
- readme.txt +31 -18
- scss/admin.scss +103 -4
- thumbnail_updater.php +22 -4
- views/popup.php +72 -61
- views/upload.php +67 -29
build/shortpixel/PackageLoader.php
ADDED
@@ -0,0 +1,73 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace EnableMediaReplace\Build;
|
3 |
+
|
4 |
+
class PackageLoader
|
5 |
+
{
|
6 |
+
public $dir;
|
7 |
+
|
8 |
+
public function getComposerFile()
|
9 |
+
{
|
10 |
+
return json_decode(file_get_contents($this->dir."/composer.json"), 1);
|
11 |
+
}
|
12 |
+
|
13 |
+
public function load($dir)
|
14 |
+
{
|
15 |
+
$this->dir = $dir;
|
16 |
+
$composer = $this->getComposerFile();
|
17 |
+
if(isset($composer["autoload"]["psr-4"])){
|
18 |
+
$this->loadPSR4($composer['autoload']['psr-4']);
|
19 |
+
}
|
20 |
+
if(isset($composer["autoload"]["psr-0"])){
|
21 |
+
$this->loadPSR0($composer['autoload']['psr-0']);
|
22 |
+
}
|
23 |
+
if(isset($composer["autoload"]["files"])){
|
24 |
+
$this->loadFiles($composer["autoload"]["files"]);
|
25 |
+
}
|
26 |
+
}
|
27 |
+
|
28 |
+
public function loadFiles($files){
|
29 |
+
foreach($files as $file){
|
30 |
+
$fullpath = $this->dir."/".$file;
|
31 |
+
if(file_exists($fullpath)){
|
32 |
+
include_once($fullpath);
|
33 |
+
}
|
34 |
+
}
|
35 |
+
}
|
36 |
+
|
37 |
+
public function loadPSR4($namespaces)
|
38 |
+
{
|
39 |
+
$this->loadPSR($namespaces, true);
|
40 |
+
}
|
41 |
+
|
42 |
+
public function loadPSR0($namespaces)
|
43 |
+
{
|
44 |
+
$this->loadPSR($namespaces, false);
|
45 |
+
}
|
46 |
+
|
47 |
+
public function loadPSR($namespaces, $psr4)
|
48 |
+
{
|
49 |
+
$dir = $this->dir;
|
50 |
+
// Foreach namespace specified in the composer, load the given classes
|
51 |
+
foreach ($namespaces as $namespace => $classpaths) {
|
52 |
+
if (!is_array($classpaths)) {
|
53 |
+
$classpaths = array($classpaths);
|
54 |
+
}
|
55 |
+
spl_autoload_register(function ($classname) use ($namespace, $classpaths, $dir, $psr4) {
|
56 |
+
// Check if the namespace matches the class we are looking for
|
57 |
+
if (preg_match("#^".preg_quote($namespace)."#", $classname)) {
|
58 |
+
// Remove the namespace from the file path since it's psr4
|
59 |
+
if ($psr4) {
|
60 |
+
$classname = str_replace($namespace, "", $classname);
|
61 |
+
}
|
62 |
+
$filename = preg_replace("#\\\\#", "/", $classname).".php";
|
63 |
+
foreach ($classpaths as $classpath) {
|
64 |
+
$fullpath = $this->dir."/".$classpath."/$filename";
|
65 |
+
if (file_exists($fullpath)) {
|
66 |
+
include_once $fullpath;
|
67 |
+
}
|
68 |
+
}
|
69 |
+
}
|
70 |
+
});
|
71 |
+
}
|
72 |
+
}
|
73 |
+
}
|
build/shortpixel/autoload.php
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
require_once "PackageLoader.php";
|
3 |
+
$loader = new EnableMediaReplace\Build\PackageLoader();
|
4 |
+
$loader->load(__DIR__);
|
5 |
+
|
build/shortpixel/composer.json
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
{"name":"EnableMediaReplace\/shortpixelmodules","description":"ShortPixel submodules","type":"function","autoload":{"psr-4":{"EnableMediaReplace\\ShortPixelLogger\\":"log\/src\/","EnableMediaReplace\\Notices\\":"notices\/src\/"}}}
|
build/shortpixel/log/composer.json
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"name": "shortpixel/log",
|
3 |
+
"description": "ShortPixel Logging",
|
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\\ShortPixelLogger\\" : "src/" }
|
17 |
+
}
|
18 |
+
}
|
build/shortpixel/log/src/DebugItem.php
ADDED
@@ -0,0 +1,136 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
45 |
+
{
|
46 |
+
foreach($data as $index => $item)
|
47 |
+
{
|
48 |
+
if (is_object($item) || is_array($item))
|
49 |
+
{
|
50 |
+
$this->data[] = print_r($item, true);
|
51 |
+
}
|
52 |
+
}
|
53 |
+
}
|
54 |
+
} // if
|
55 |
+
elseif (! is_array($data)) // this leaves out empty default arrays
|
56 |
+
{
|
57 |
+
$this->data[] = print_r($data, true);
|
58 |
+
}
|
59 |
+
}
|
60 |
+
|
61 |
+
public function getData()
|
62 |
+
{
|
63 |
+
return array('time' => $this->time, 'level' => $this->level, 'message' => $this->message, 'data' => $this->data, 'caller' => $this->caller);
|
64 |
+
}
|
65 |
+
|
66 |
+
/** Test Data Array for possible values
|
67 |
+
*
|
68 |
+
* Data can be a collection of several debug vars, a single var, or just an normal array. Test if array has single types,
|
69 |
+
* which is a sign the array is not a collection.
|
70 |
+
*/
|
71 |
+
protected function getDataType($data)
|
72 |
+
{
|
73 |
+
$single_type = array('integer', 'boolean', 'string');
|
74 |
+
if (in_array(gettype(reset($data)), $single_type))
|
75 |
+
{
|
76 |
+
return 1;
|
77 |
+
}
|
78 |
+
else
|
79 |
+
{
|
80 |
+
return 2;
|
81 |
+
}
|
82 |
+
}
|
83 |
+
|
84 |
+
public function getForFormat()
|
85 |
+
{
|
86 |
+
$data = $this->getData();
|
87 |
+
switch($this->level)
|
88 |
+
{
|
89 |
+
case self::LEVEL_ERROR:
|
90 |
+
$level = 'ERR';
|
91 |
+
$color = "\033[31m";
|
92 |
+
break;
|
93 |
+
case self::LEVEL_WARN:
|
94 |
+
$level = 'WRN';
|
95 |
+
$color = "\033[33m";
|
96 |
+
break;
|
97 |
+
case self::LEVEL_INFO:
|
98 |
+
$level = 'INF';
|
99 |
+
$color = "\033[37m";
|
100 |
+
break;
|
101 |
+
case self::LEVEL_DEBUG:
|
102 |
+
$level = 'DBG';
|
103 |
+
$color = "\033[37m";
|
104 |
+
break;
|
105 |
+
|
106 |
+
}
|
107 |
+
$color_end = "\033[0m";
|
108 |
+
|
109 |
+
$data['color'] = $color;
|
110 |
+
$data['color_end'] = $color_end;
|
111 |
+
$data['level'] = $level;
|
112 |
+
|
113 |
+
return $data;
|
114 |
+
|
115 |
+
//return array('time' => $this->time, 'level' => $level, 'message' => $this->message, 'data' => $this->data, 'color' => $color, 'color_end' => $color_end, 'caller' => $this->caller);
|
116 |
+
|
117 |
+
}
|
118 |
+
|
119 |
+
protected function setCaller()
|
120 |
+
{
|
121 |
+
$debug=debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS,5);
|
122 |
+
$i = 4;
|
123 |
+
if (isset($debug[$i]))
|
124 |
+
{
|
125 |
+
$info = $debug[$i];
|
126 |
+
$line = isset($info['line']) ? $info['line'] : 'Line unknown';
|
127 |
+
$file = isset($info['file']) ? basename($info['file']) : 'File not set';
|
128 |
+
|
129 |
+
$this->caller = array('line' => $line, 'file' => $file, 'function' => $info['function']);
|
130 |
+
}
|
131 |
+
|
132 |
+
|
133 |
+
}
|
134 |
+
|
135 |
+
|
136 |
+
}
|
build/shortpixel/log/src/ShortPixelLogger.php
ADDED
@@ -0,0 +1,322 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace EnableMediaReplace\ShortPixelLogger;
|
3 |
+
|
4 |
+
/*** Logger class
|
5 |
+
*
|
6 |
+
* Class uses the debug data model for keeping log entries.
|
7 |
+
* Logger should not be called before init hook!
|
8 |
+
*/
|
9 |
+
class ShortPixelLogger
|
10 |
+
{
|
11 |
+
static protected $instance = null;
|
12 |
+
protected $start_time;
|
13 |
+
|
14 |
+
protected $is_active = false;
|
15 |
+
protected $is_manual_request = false;
|
16 |
+
protected $show_debug_view = false;
|
17 |
+
|
18 |
+
protected $items = array();
|
19 |
+
protected $logPath = false;
|
20 |
+
protected $logMode = FILE_APPEND;
|
21 |
+
|
22 |
+
protected $logLevel;
|
23 |
+
protected $format = "[ %%time%% ] %%color%% %%level%% %%color_end%% \t %%message%% \t %%caller%% ( %%time_passed%% )";
|
24 |
+
protected $format_data = "\t %%data%% ";
|
25 |
+
|
26 |
+
protected $hooks = array();
|
27 |
+
/* protected $hooks = array(
|
28 |
+
'shortpixel_image_exists' => array('numargs' => 3),
|
29 |
+
'shortpixel_webp_image_base' => array('numargs' => 2),
|
30 |
+
'shortpixel_image_urls' => array('numargs' => 2),
|
31 |
+
); // @todo monitor hooks, but this should be more dynamic. Do when moving to module via config.
|
32 |
+
*/
|
33 |
+
|
34 |
+
// utility
|
35 |
+
private $namespace;
|
36 |
+
private $view;
|
37 |
+
|
38 |
+
protected $template = 'view-debug-box';
|
39 |
+
|
40 |
+
/** Debugger constructor
|
41 |
+
* Two ways to activate the debugger. 1) Define SHORTPIXEL_DEBUG in wp-config.php. Either must be true or a number corresponding to required LogLevel
|
42 |
+
* 2) Put SHORTPIXEL_DEBUG in the request. Either true or number.
|
43 |
+
*/
|
44 |
+
public function __construct()
|
45 |
+
{
|
46 |
+
$this->start_time = microtime(true);
|
47 |
+
$this->logLevel = DebugItem::LEVEL_WARN;
|
48 |
+
|
49 |
+
$ns = __NAMESPACE__;
|
50 |
+
$this->namespace = substr($ns, 0, strpos($ns, '\\')); // try to get first part of namespace
|
51 |
+
|
52 |
+
if ($this->logPath === false)
|
53 |
+
{
|
54 |
+
$upload_dir = wp_upload_dir(null,false,false);
|
55 |
+
$this->logPath = $upload_dir['basedir'] . '/' . $this->namespace . ".log";
|
56 |
+
}
|
57 |
+
|
58 |
+
if (isset($_REQUEST['SHORTPIXEL_DEBUG'])) // manual takes precedence over constants
|
59 |
+
{
|
60 |
+
$this->is_manual_request = true;
|
61 |
+
$this->is_active = true;
|
62 |
+
|
63 |
+
if ($_REQUEST['SHORTPIXEL_DEBUG'] === 'true')
|
64 |
+
{
|
65 |
+
$this->logLevel = DebugItem::LEVEL_INFO;
|
66 |
+
}
|
67 |
+
else {
|
68 |
+
$this->logLevel = intval($_REQUEST['SHORTPIXEL_DEBUG']);
|
69 |
+
}
|
70 |
+
|
71 |
+
}
|
72 |
+
else if ( (defined('SHORTPIXEL_DEBUG') && SHORTPIXEL_DEBUG > 0) )
|
73 |
+
{
|
74 |
+
$this->is_active = true;
|
75 |
+
if (SHORTPIXEL_DEBUG === true)
|
76 |
+
$this->logLevel = DebugItem::LEVEL_INFO;
|
77 |
+
else {
|
78 |
+
$this->logLevel = intval(SHORTPIXEL_DEBUG);
|
79 |
+
}
|
80 |
+
}
|
81 |
+
|
82 |
+
if (defined('SHORTPIXEL_DEBUG_TARGET') && SHORTPIXEL_DEBUG_TARGET || $this->is_manual_request)
|
83 |
+
{
|
84 |
+
//$this->logPath = SHORTPIXEL_BACKUP_FOLDER . "/shortpixel_log";
|
85 |
+
//$this->logMode = defined('SHORTPIXEL_LOG_OVERWRITE') ? 0 : FILE_APPEND;
|
86 |
+
if (defined('SHORTPIXEL_LOG_OVERWRITE')) // if overwrite, do this on init once.
|
87 |
+
file_put_contents($this->logPath,'-- Log Reset -- ' .PHP_EOL);
|
88 |
+
|
89 |
+
}
|
90 |
+
|
91 |
+
/* On Early init, this function might not exist, then queue it when needed */
|
92 |
+
if (! function_exists('wp_get_current_user'))
|
93 |
+
add_action('plugins_loaded', array($this, 'initView'));
|
94 |
+
else
|
95 |
+
$this->initView();
|
96 |
+
|
97 |
+
|
98 |
+
if ($this->is_active && count($this->hooks) > 0)
|
99 |
+
$this->monitorHooks();
|
100 |
+
}
|
101 |
+
|
102 |
+
/** Init the view when needed. Private function ( public because of WP_HOOK )
|
103 |
+
* Never call directly */
|
104 |
+
public function initView()
|
105 |
+
{
|
106 |
+
$user_is_administrator = (current_user_can('manage_options')) ? true : false;
|
107 |
+
|
108 |
+
if ($this->is_active && $this->is_manual_request && $user_is_administrator )
|
109 |
+
{
|
110 |
+
$content_url = content_url();
|
111 |
+
$logPath = $this->logPath;
|
112 |
+
$pathpos = strpos($logPath, 'wp-content') + strlen('wp-content');
|
113 |
+
$logPart = substr($logPath, $pathpos);
|
114 |
+
$logLink = $content_url . $logPart;
|
115 |
+
|
116 |
+
$this->view = new \stdClass;
|
117 |
+
$this->view->logLink = $logLink;
|
118 |
+
add_action('admin_footer', array($this, 'loadView'));
|
119 |
+
}
|
120 |
+
}
|
121 |
+
|
122 |
+
public static function getInstance()
|
123 |
+
{
|
124 |
+
if ( self::$instance === null)
|
125 |
+
{
|
126 |
+
self::$instance = new ShortPixelLogger();
|
127 |
+
}
|
128 |
+
return self::$instance;
|
129 |
+
}
|
130 |
+
|
131 |
+
public function setLogPath($logPath)
|
132 |
+
{
|
133 |
+
$this->logPath = $logPath;
|
134 |
+
}
|
135 |
+
protected static function addLog($message, $level, $data = array())
|
136 |
+
{
|
137 |
+
$log = self::getInstance();
|
138 |
+
|
139 |
+
// don't log anything too low.
|
140 |
+
if ($log->logLevel < $level)
|
141 |
+
{
|
142 |
+
return;
|
143 |
+
}
|
144 |
+
|
145 |
+
$arg = array();
|
146 |
+
$args['level'] = $level;
|
147 |
+
$args['data'] = $data;
|
148 |
+
|
149 |
+
$newItem = new DebugItem($message, $args);
|
150 |
+
$log->items[] = $newItem;
|
151 |
+
|
152 |
+
if ($log->is_active)
|
153 |
+
{
|
154 |
+
$log->write($newItem);
|
155 |
+
}
|
156 |
+
}
|
157 |
+
|
158 |
+
/** Writes to log File. */
|
159 |
+
protected function write($debugItem, $mode = 'file')
|
160 |
+
{
|
161 |
+
$items = $debugItem->getForFormat();
|
162 |
+
$items['time_passed'] = round ( ($items['time'] - $this->start_time), 5);
|
163 |
+
$items['time'] = date('Y-m-d H:i:s', $items['time'] );
|
164 |
+
|
165 |
+
if ( ($items['caller']) && is_array($items['caller']) && count($items['caller']) > 0)
|
166 |
+
{
|
167 |
+
$caller = $items['caller'];
|
168 |
+
$items['caller'] = $caller['file'] . ' in ' . $caller['function'] . '(' . $caller['line'] . ')';
|
169 |
+
}
|
170 |
+
|
171 |
+
$line = $this->formatLine($items);
|
172 |
+
|
173 |
+
if ($this->logPath)
|
174 |
+
{
|
175 |
+
file_put_contents($this->logPath,$line, FILE_APPEND);
|
176 |
+
}
|
177 |
+
else {
|
178 |
+
error_log($line);
|
179 |
+
}
|
180 |
+
}
|
181 |
+
|
182 |
+
protected function formatLine($args = array() )
|
183 |
+
{
|
184 |
+
$line= $this->format;
|
185 |
+
foreach($args as $key => $value)
|
186 |
+
{
|
187 |
+
if (! is_array($value) && ! is_object($value))
|
188 |
+
$line = str_replace('%%' . $key . '%%', $value, $line);
|
189 |
+
}
|
190 |
+
|
191 |
+
$line .= PHP_EOL;
|
192 |
+
|
193 |
+
if (isset($args['data']))
|
194 |
+
{
|
195 |
+
$data = array_filter($args['data']);
|
196 |
+
if (count($data) > 0)
|
197 |
+
{
|
198 |
+
foreach($data as $item)
|
199 |
+
{
|
200 |
+
$line .= $item . PHP_EOL;
|
201 |
+
}
|
202 |
+
}
|
203 |
+
}
|
204 |
+
|
205 |
+
return $line;
|
206 |
+
}
|
207 |
+
|
208 |
+
protected function setLogLevel($level)
|
209 |
+
{
|
210 |
+
$this->logLevel = $level;
|
211 |
+
}
|
212 |
+
|
213 |
+
protected function getEnv($name)
|
214 |
+
{
|
215 |
+
if (isset($this->{$name}))
|
216 |
+
{
|
217 |
+
return $this->{$name};
|
218 |
+
}
|
219 |
+
else {
|
220 |
+
return false;
|
221 |
+
}
|
222 |
+
}
|
223 |
+
|
224 |
+
public static function addError($message, $args = array())
|
225 |
+
{
|
226 |
+
$level = DebugItem::LEVEL_ERROR;
|
227 |
+
static::addLog($message, $level, $args);
|
228 |
+
}
|
229 |
+
public static function addWarn($message, $args = array())
|
230 |
+
{
|
231 |
+
$level = DebugItem::LEVEL_WARN;
|
232 |
+
static::addLog($message, $level, $args);
|
233 |
+
}
|
234 |
+
public static function addInfo($message, $args = array())
|
235 |
+
{
|
236 |
+
$level = DebugItem::LEVEL_INFO;
|
237 |
+
static::addLog($message, $level, $args);
|
238 |
+
}
|
239 |
+
public static function addDebug($message, $args = array())
|
240 |
+
{
|
241 |
+
$level = DebugItem::LEVEL_DEBUG;
|
242 |
+
static::addLog($message, $level, $args);
|
243 |
+
}
|
244 |
+
|
245 |
+
public static function logLevel($level)
|
246 |
+
{
|
247 |
+
$log = self::getInstance();
|
248 |
+
static::addInfo('Changing Log level' . $level);
|
249 |
+
$log->setLogLevel($level);
|
250 |
+
}
|
251 |
+
|
252 |
+
public static function getLogLevel()
|
253 |
+
{
|
254 |
+
$log = self::getInstance();
|
255 |
+
return $log->getEnv('logLevel');
|
256 |
+
}
|
257 |
+
|
258 |
+
public static function isManualDebug()
|
259 |
+
{
|
260 |
+
$log = self::getInstance();
|
261 |
+
return $log->getEnv('is_manual_request');
|
262 |
+
}
|
263 |
+
|
264 |
+
public static function getLogPath()
|
265 |
+
{
|
266 |
+
$log = self::getInstance();
|
267 |
+
return $log->getEnv('logPath');
|
268 |
+
}
|
269 |
+
|
270 |
+
/** Function to test if the debugger is active
|
271 |
+
* @return boolean true when active.
|
272 |
+
*/
|
273 |
+
public static function debugIsActive()
|
274 |
+
{
|
275 |
+
$log = self::getInstance();
|
276 |
+
return $log->getEnv('is_active');
|
277 |
+
}
|
278 |
+
|
279 |
+
protected function monitorHooks()
|
280 |
+
{
|
281 |
+
|
282 |
+
foreach($this->hooks as $hook => $data)
|
283 |
+
{
|
284 |
+
$numargs = isset($data['numargs']) ? $data['numargs'] : 1;
|
285 |
+
$prio = isset($data['priority']) ? $data['priority'] : 10;
|
286 |
+
|
287 |
+
add_filter($hook, function($value) use ($hook) {
|
288 |
+
$args = func_get_args();
|
289 |
+
return $this->logHook($hook, $value, $args); }, $prio, $numargs);
|
290 |
+
}
|
291 |
+
}
|
292 |
+
|
293 |
+
public function logHook($hook, $value, $args)
|
294 |
+
{
|
295 |
+
array_shift($args);
|
296 |
+
self::addInfo('[Hook] - ' . $hook . ' with ' . var_export($value,true), $args);
|
297 |
+
return $value;
|
298 |
+
}
|
299 |
+
|
300 |
+
public function loadView()
|
301 |
+
{
|
302 |
+
// load either param or class template.
|
303 |
+
$template = $this->template;
|
304 |
+
|
305 |
+
$view = $this->view;
|
306 |
+
$view->namespace = $this->namespace;
|
307 |
+
$controller = $this;
|
308 |
+
|
309 |
+
$template_path = __DIR__ . '/' . $this->template . '.php';
|
310 |
+
if (file_exists($template_path))
|
311 |
+
{
|
312 |
+
|
313 |
+
include($template_path);
|
314 |
+
}
|
315 |
+
else {
|
316 |
+
self::addError("View $template could not be found in " . $template_path,
|
317 |
+
array('class' => get_class($this), 'req' => $_REQUEST));
|
318 |
+
}
|
319 |
+
}
|
320 |
+
|
321 |
+
|
322 |
+
} // class debugController
|
build/shortpixel/log/src/view-debug-box.php
ADDED
@@ -0,0 +1,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 $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>
|
build/shortpixel/notices/composer.json
ADDED
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"name": "shortpixel/notices",
|
3 |
+
"description": "ShortPixel WordPress Notice System",
|
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 |
+
"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 |
+
}
|
build/shortpixel/notices/src/NoticeController.php
ADDED
@@ -0,0 +1,194 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
+
public $notice_count = 0;
|
12 |
+
|
13 |
+
protected $has_stored = false;
|
14 |
+
|
15 |
+
protected $notice_option = ''; // The wp_options name for notices here.
|
16 |
+
|
17 |
+
/** For backward compat. Never call constructor directly. */
|
18 |
+
public function __construct()
|
19 |
+
{
|
20 |
+
// $this->loadModel('notice');
|
21 |
+
$ns = __NAMESPACE__;
|
22 |
+
$ns = substr($ns, 0, strpos($ns, '\\')); // try to get first part of namespace
|
23 |
+
$this->notice_option = $ns . '-notices';
|
24 |
+
|
25 |
+
$this->loadNotices();
|
26 |
+
//$this->loadConfig();
|
27 |
+
}
|
28 |
+
|
29 |
+
/** Load Notices Config File, if any
|
30 |
+
*
|
31 |
+
* [ Future Use ]
|
32 |
+
*/
|
33 |
+
public function loadConfig()
|
34 |
+
{
|
35 |
+
if (file_exists('../notice_config.json'))
|
36 |
+
{
|
37 |
+
$config = file_get_contents('../notice_config.json');
|
38 |
+
$json_config = json_decode($config);
|
39 |
+
}
|
40 |
+
}
|
41 |
+
|
42 |
+
public function loadIcons($icons)
|
43 |
+
{
|
44 |
+
foreach($icons as $name => $icon)
|
45 |
+
NoticeModel::setIcon($name, $icon);
|
46 |
+
}
|
47 |
+
|
48 |
+
|
49 |
+
protected function loadNotices()
|
50 |
+
{
|
51 |
+
$notices = get_option($this->notice_option, false);
|
52 |
+
$cnotice = (is_array($notices)) ? count($notices) : 0;
|
53 |
+
Log::addDebug('Notice Control - #num notices' . $cnotice);
|
54 |
+
if ($notices !== false)
|
55 |
+
{
|
56 |
+
self::$notices = $notices;
|
57 |
+
$this->has_stored = true;
|
58 |
+
}
|
59 |
+
else {
|
60 |
+
self::$notices = array();
|
61 |
+
$this->has_stored = false;
|
62 |
+
}
|
63 |
+
$this->countNotices();
|
64 |
+
}
|
65 |
+
|
66 |
+
|
67 |
+
public function addNotice($message, $code)
|
68 |
+
{
|
69 |
+
$notice = new NoticeModel($message, $code);
|
70 |
+
self::$notices[] = $notice;
|
71 |
+
$this->countNotices();
|
72 |
+
Log::addDebug('Adding notice - ', $notice);
|
73 |
+
$this->update();
|
74 |
+
return $notice;
|
75 |
+
}
|
76 |
+
|
77 |
+
/** Update the notices to store, check what to remove, returns count. */
|
78 |
+
public function update()
|
79 |
+
{
|
80 |
+
if (! is_array(self::$notices) || count(self::$notices) == 0)
|
81 |
+
{
|
82 |
+
if ($this->has_stored)
|
83 |
+
delete_option($this->notice_option);
|
84 |
+
|
85 |
+
return 0;
|
86 |
+
}
|
87 |
+
|
88 |
+
$new_notices = array();
|
89 |
+
foreach(self::$notices as $item)
|
90 |
+
{
|
91 |
+
if (! $item->isDone() )
|
92 |
+
{
|
93 |
+
$new_notices[] = $item;
|
94 |
+
}
|
95 |
+
}
|
96 |
+
|
97 |
+
update_option($this->notice_option, $new_notices);
|
98 |
+
self::$notices = $new_notices;
|
99 |
+
|
100 |
+
return $this->countNotices();
|
101 |
+
}
|
102 |
+
|
103 |
+
public function countNotices()
|
104 |
+
{
|
105 |
+
$this->notice_count = count(self::$notices);
|
106 |
+
return $this->notice_count;
|
107 |
+
}
|
108 |
+
|
109 |
+
|
110 |
+
public function getNotices()
|
111 |
+
{
|
112 |
+
return self::$notices;
|
113 |
+
}
|
114 |
+
|
115 |
+
public static function getInstance()
|
116 |
+
{
|
117 |
+
if ( self::$instance === null)
|
118 |
+
{
|
119 |
+
self::$instance = new NoticeController();
|
120 |
+
}
|
121 |
+
|
122 |
+
return self::$instance;
|
123 |
+
}
|
124 |
+
|
125 |
+
/** Adds a notice, quick and fast method
|
126 |
+
* @param String $message The Message you want to notify
|
127 |
+
* @param int $code A value of messageType as defined in model
|
128 |
+
* @returm Object Instance of noticeModel
|
129 |
+
*/
|
130 |
+
|
131 |
+
public static function addNormal($message)
|
132 |
+
{
|
133 |
+
$noticeController = self::getInstance();
|
134 |
+
$notice = $noticeController->addNotice($message, NoticeModel::NOTICE_NORMAL);
|
135 |
+
return $notice;
|
136 |
+
|
137 |
+
}
|
138 |
+
|
139 |
+
public static function addError($message)
|
140 |
+
{
|
141 |
+
$noticeController = self::getInstance();
|
142 |
+
$notice = $noticeController->addNotice($message, NoticeModel::NOTICE_ERROR);
|
143 |
+
return $notice;
|
144 |
+
|
145 |
+
}
|
146 |
+
|
147 |
+
public static function addWarning($message)
|
148 |
+
{
|
149 |
+
$noticeController = self::getInstance();
|
150 |
+
$notice = $noticeController->addNotice($message, NoticeModel::NOTICE_WARNING);
|
151 |
+
return $notice;
|
152 |
+
|
153 |
+
}
|
154 |
+
|
155 |
+
public static function addSuccess($message)
|
156 |
+
{
|
157 |
+
$noticeController = self::getInstance();
|
158 |
+
$notice = $noticeController->addNotice($message, NoticeModel::NOTICE_SUCCESS);
|
159 |
+
return $notice;
|
160 |
+
|
161 |
+
}
|
162 |
+
|
163 |
+
public function admin_notices()
|
164 |
+
{
|
165 |
+
if ($this->countNotices() > 0)
|
166 |
+
{
|
167 |
+
if (! self::$cssHookLoaded)
|
168 |
+
{
|
169 |
+
add_action('admin_print_footer_scripts', array($this, 'printNoticeStyle'));
|
170 |
+
self::$cssHookLoaded = true;
|
171 |
+
}
|
172 |
+
foreach($this->getNotices() as $notice)
|
173 |
+
{
|
174 |
+
echo $notice->getForDisplay();
|
175 |
+
}
|
176 |
+
}
|
177 |
+
$this->update(); // puts views, and updates
|
178 |
+
}
|
179 |
+
|
180 |
+
public function printNoticeStyle()
|
181 |
+
{
|
182 |
+
if (file_exists(__DIR__ . '/css/notices.css'))
|
183 |
+
{
|
184 |
+
echo '<style>' . file_get_contents(__DIR__ . '/css/notices.css') . '</style>';
|
185 |
+
}
|
186 |
+
else {
|
187 |
+
Log::addDebug('Notices : css/notices.css could not be loaded');
|
188 |
+
}
|
189 |
+
}
|
190 |
+
|
191 |
+
|
192 |
+
|
193 |
+
|
194 |
+
}
|
build/shortpixel/notices/src/NoticeModel.php
ADDED
@@ -0,0 +1,116 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace EnableMediaReplace\Notices;
|
3 |
+
|
4 |
+
class NoticeModel //extends ShortPixelModel
|
5 |
+
{
|
6 |
+
protected $message;
|
7 |
+
public $code;
|
8 |
+
|
9 |
+
protected $viewed = false;
|
10 |
+
public $is_persistent = false; // This is a fatal issue, display until something was fixed.
|
11 |
+
public $is_removable = true; // if removable, display a notice dialog with red X or so.
|
12 |
+
public $messageType = self::NOTICE_NORMAL;
|
13 |
+
|
14 |
+
public static $icons = array();
|
15 |
+
|
16 |
+
const NOTICE_NORMAL = 1;
|
17 |
+
const NOTICE_ERROR = 2;
|
18 |
+
const NOTICE_SUCCESS = 3;
|
19 |
+
const NOTICE_WARNING = 4;
|
20 |
+
|
21 |
+
|
22 |
+
public function __construct($message, $messageType = self::NOTICE_NORMAL)
|
23 |
+
{
|
24 |
+
$this->message = $message;
|
25 |
+
$this->messageType = $messageType;
|
26 |
+
|
27 |
+
}
|
28 |
+
|
29 |
+
public function isDone()
|
30 |
+
{
|
31 |
+
if ($this->viewed && ! $this->is_persistent)
|
32 |
+
return true;
|
33 |
+
else
|
34 |
+
return false;
|
35 |
+
|
36 |
+
}
|
37 |
+
|
38 |
+
public static function setIcon($notice_type, $icon)
|
39 |
+
{
|
40 |
+
switch($notice_type)
|
41 |
+
{
|
42 |
+
case 'error':
|
43 |
+
$type = self::NOTICE_ERROR;
|
44 |
+
break;
|
45 |
+
case 'success':
|
46 |
+
$type = self::NOTICE_SUCCESS;
|
47 |
+
break;
|
48 |
+
case 'warning':
|
49 |
+
$type = self::NOTICE_WARNING;
|
50 |
+
break;
|
51 |
+
case 'normal':
|
52 |
+
default:
|
53 |
+
$type = self::NOTICE_NORMAL;
|
54 |
+
break;
|
55 |
+
}
|
56 |
+
self::$icons[$type] = $icon;
|
57 |
+
}
|
58 |
+
|
59 |
+
public function getForDisplay()
|
60 |
+
{
|
61 |
+
$this->viewed = true;
|
62 |
+
$class = 'shortpixel notice ';
|
63 |
+
|
64 |
+
$icon = '';
|
65 |
+
|
66 |
+
switch($this->messageType)
|
67 |
+
{
|
68 |
+
case self::NOTICE_ERROR:
|
69 |
+
$class .= 'notice-error ';
|
70 |
+
$icon = isset(self::$icons[self::NOTICE_ERROR]) ? self::$icons[self::NOTICE_ERROR] : '';
|
71 |
+
//$icon = 'scared';
|
72 |
+
break;
|
73 |
+
case self::NOTICE_SUCCESS:
|
74 |
+
$class .= 'notice-success ';
|
75 |
+
$icon = isset(self::$icons[self::NOTICE_SUCCESS]) ? self::$icons[self::NOTICE_SUCCESS] : '';
|
76 |
+
break;
|
77 |
+
case self::NOTICE_WARNING:
|
78 |
+
$class .= 'notice-warning ';
|
79 |
+
$icon = isset(self::$icons[self::NOTICE_WARNING]) ? self::$icons[self::NOTICE_WARNING] : '';
|
80 |
+
break;
|
81 |
+
case self::NOTICE_NORMAL:
|
82 |
+
$class .= 'notice-info ';
|
83 |
+
$icon = isset(self::$icons[self::NOTICE_NORMAL]) ? self::$icons[self::NOTICE_NORMAL] : '';
|
84 |
+
break;
|
85 |
+
default:
|
86 |
+
$class .= 'notice-info ';
|
87 |
+
$icon = '';
|
88 |
+
break;
|
89 |
+
}
|
90 |
+
|
91 |
+
/*$image = '<img src="' . plugins_url('/shortpixel-image-optimiser/res/img/robo-' . $icon . '.png') . '"
|
92 |
+
srcset="' . plugins_url( 'shortpixel-image-optimiser/res/img/robo-' . $icon . '.png' ) . ' 1x, ' . plugins_url( 'shortpixel-image-optimiser/res/img/robo-' . $icon . '@2x.png') . ' 2x" class="short-pixel-notice-icon">';
|
93 |
+
*/
|
94 |
+
|
95 |
+
if ($this->is_removable)
|
96 |
+
{
|
97 |
+
$class .= 'is-dismissible ';
|
98 |
+
}
|
99 |
+
|
100 |
+
if ($this->is_persistent)
|
101 |
+
{
|
102 |
+
$class .= '';
|
103 |
+
}
|
104 |
+
|
105 |
+
return "<div class='$class'>" . $icon . "<p>" . $this->message . "</p></div>";
|
106 |
+
|
107 |
+
}
|
108 |
+
|
109 |
+
|
110 |
+
|
111 |
+
// @todo Transient save, since that is used in some parts.
|
112 |
+
// save
|
113 |
+
// load
|
114 |
+
|
115 |
+
|
116 |
+
}
|
build/shortpixel/notices/src/css/notices.css
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.shortpixel.notice {
|
2 |
+
padding: 8px; }
|
3 |
+
.shortpixel.notice img {
|
4 |
+
display: inline-block;
|
5 |
+
margin: 0 25px 0 0;
|
6 |
+
max-height: 50px; }
|
7 |
+
.shortpixel.notice .notice-dismiss {
|
8 |
+
margin-top: 10px; }
|
9 |
+
|
10 |
+
/* In-view notice ( not on top, between the options ) - styled after WP notice */
|
11 |
+
.view-notice {
|
12 |
+
box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.1);
|
13 |
+
border: 4px solid #fff;
|
14 |
+
padding: 1px 12px; }
|
15 |
+
.view-notice p {
|
16 |
+
margin: 1em 0 !important; }
|
17 |
+
.view-notice.warning {
|
18 |
+
border-left-color: #ffb900; }
|
19 |
+
|
20 |
+
.view-notice-row {
|
21 |
+
display: none; }
|
build/shortpixel/notices/src/css/notices.scss
ADDED
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
.shortpixel.notice
|
3 |
+
{
|
4 |
+
//padding: 18px;
|
5 |
+
//min-height: 50px;
|
6 |
+
padding: 8px;
|
7 |
+
img
|
8 |
+
{
|
9 |
+
display:inline-block;
|
10 |
+
margin: 0 25px 0 0;
|
11 |
+
max-height: 50px;
|
12 |
+
}
|
13 |
+
.notice-dismiss
|
14 |
+
{
|
15 |
+
margin-top: 10px;
|
16 |
+
}
|
17 |
+
}
|
18 |
+
|
19 |
+
/* In-view notice ( not on top, between the options ) - styled after WP notice */
|
20 |
+
.view-notice
|
21 |
+
{
|
22 |
+
|
23 |
+
box-shadow: 0 1px 1px 0 rgba( 0, 0, 0, 0.1 );
|
24 |
+
border: 4px solid #fff;
|
25 |
+
|
26 |
+
padding: 1px 12px;
|
27 |
+
p {
|
28 |
+
margin: 1em 0 !important;
|
29 |
+
}
|
30 |
+
&.warning
|
31 |
+
{
|
32 |
+
border-left-color: #ffb900;
|
33 |
+
}
|
34 |
+
}
|
35 |
+
|
36 |
+
.view-notice-row
|
37 |
+
{
|
38 |
+
display: none;
|
39 |
+
}
|
classes/emr-plugin.php
CHANGED
@@ -1,19 +1,29 @@
|
|
1 |
<?php
|
2 |
namespace EnableMediaReplace;
|
|
|
|
|
3 |
|
4 |
// Does what a plugin does.
|
5 |
class EnableMediaReplacePlugin
|
6 |
{
|
7 |
|
8 |
protected $plugin_path;
|
|
|
9 |
|
10 |
public function __construct()
|
11 |
{
|
12 |
$this->plugin_actions(); // init
|
|
|
13 |
|
|
|
|
|
|
|
|
|
14 |
|
|
|
15 |
}
|
16 |
|
|
|
17 |
public function plugin_actions()
|
18 |
{
|
19 |
$this->plugin_path = plugin_dir_path(EMR_ROOT_FILE);
|
@@ -51,11 +61,21 @@ class EnableMediaReplacePlugin
|
|
51 |
|
52 |
/**
|
53 |
* Initialize this plugin. Called by 'admin_init' hook.
|
54 |
-
*
|
55 |
*/
|
56 |
public function init()
|
57 |
{
|
58 |
load_plugin_textdomain( 'enable-media-replace', false, basename(dirname(EMR_ROOT_FILE) ) . '/languages' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
59 |
}
|
60 |
|
61 |
/** Load EMR views based on request */
|
@@ -109,7 +129,16 @@ class EnableMediaReplacePlugin
|
|
109 |
}
|
110 |
|
111 |
wp_register_script('emr_admin', plugins_url('js/emr_admin.js', EMR_ROOT_FILE), array('jquery'), false, true );
|
112 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
113 |
|
114 |
}
|
115 |
|
@@ -170,7 +199,7 @@ class EnableMediaReplacePlugin
|
|
170 |
$form_fields["enable-media-replace"] = array(
|
171 |
"label" => esc_html__("Replace media", "enable-media-replace"),
|
172 |
"input" => "html",
|
173 |
-
"html" => "<p><a class='button-secondary'$link>" . esc_html__("Upload a new file", "enable-media-replace") . "</a></p>", "helps" => esc_html__("To replace the current file, click the link and upload a replacement.", "enable-media-replace")
|
174 |
);
|
175 |
|
176 |
return $form_fields;
|
@@ -180,7 +209,6 @@ class EnableMediaReplacePlugin
|
|
180 |
* @param array $mime_types
|
181 |
* @return array
|
182 |
*/
|
183 |
-
|
184 |
public function add_mime_types($mime_types)
|
185 |
{
|
186 |
$mime_types['dat'] = 'text/plain'; // Adding .dat extension
|
@@ -202,7 +230,7 @@ class EnableMediaReplacePlugin
|
|
202 |
} */
|
203 |
$link = "href=\"$editurl\"";
|
204 |
|
205 |
-
$newaction['adddata'] = '<a ' . $link . ' aria-label="' .
|
206 |
return array_merge($actions,$newaction);
|
207 |
}
|
208 |
|
1 |
<?php
|
2 |
namespace EnableMediaReplace;
|
3 |
+
use EnableMediaReplace\ShortPixelLogger\ShortPixelLogger as Log;
|
4 |
+
use EnableMediaReplace\Notices\NoticeController as Notices;
|
5 |
|
6 |
// Does what a plugin does.
|
7 |
class EnableMediaReplacePlugin
|
8 |
{
|
9 |
|
10 |
protected $plugin_path;
|
11 |
+
private static $instance;
|
12 |
|
13 |
public function __construct()
|
14 |
{
|
15 |
$this->plugin_actions(); // init
|
16 |
+
}
|
17 |
|
18 |
+
public static function get()
|
19 |
+
{
|
20 |
+
if (is_null(self::$instance))
|
21 |
+
self::$instance = new EnableMediaReplacePlugin();
|
22 |
|
23 |
+
return self::$instance;
|
24 |
}
|
25 |
|
26 |
+
|
27 |
public function plugin_actions()
|
28 |
{
|
29 |
$this->plugin_path = plugin_dir_path(EMR_ROOT_FILE);
|
61 |
|
62 |
/**
|
63 |
* Initialize this plugin. Called by 'admin_init' hook.
|
64 |
+
*
|
65 |
*/
|
66 |
public function init()
|
67 |
{
|
68 |
load_plugin_textdomain( 'enable-media-replace', false, basename(dirname(EMR_ROOT_FILE) ) . '/languages' );
|
69 |
+
|
70 |
+
// Load Submodules
|
71 |
+
Log::addDebug('Plugin Init');
|
72 |
+
$notices = Notices::getInstance();
|
73 |
+
|
74 |
+
// Enqueue notices
|
75 |
+
add_action('admin_notices', array($notices, 'admin_notices')); // previous page / init time
|
76 |
+
add_action('admin_footer', array($notices, 'admin_notices')); // fresh notices between init - end
|
77 |
+
|
78 |
+
new Externals();
|
79 |
}
|
80 |
|
81 |
/** Load EMR views based on request */
|
129 |
}
|
130 |
|
131 |
wp_register_script('emr_admin', plugins_url('js/emr_admin.js', EMR_ROOT_FILE), array('jquery'), false, true );
|
132 |
+
$emr_options = array(
|
133 |
+
'dateFormat' => $this->convertdate(get_option( 'date_format' )),
|
134 |
+
'maxfilesize' => wp_max_upload_size(),
|
135 |
+
|
136 |
+
);
|
137 |
+
|
138 |
+
if (Log::debugIsActive())
|
139 |
+
$emr_options['is_debug'] = true;
|
140 |
+
|
141 |
+
wp_localize_script('emr_admin', 'emr_options', $emr_options);
|
142 |
|
143 |
}
|
144 |
|
199 |
$form_fields["enable-media-replace"] = array(
|
200 |
"label" => esc_html__("Replace media", "enable-media-replace"),
|
201 |
"input" => "html",
|
202 |
+
"html" => "<p><a class='button-secondary' $link>" . esc_html__("Upload a new file", "enable-media-replace") . "</a></p>", "helps" => esc_html__("To replace the current file, click the link and upload a replacement.", "enable-media-replace")
|
203 |
);
|
204 |
|
205 |
return $form_fields;
|
209 |
* @param array $mime_types
|
210 |
* @return array
|
211 |
*/
|
|
|
212 |
public function add_mime_types($mime_types)
|
213 |
{
|
214 |
$mime_types['dat'] = 'text/plain'; // Adding .dat extension
|
230 |
} */
|
231 |
$link = "href=\"$editurl\"";
|
232 |
|
233 |
+
$newaction['adddata'] = '<a ' . $link . ' aria-label="' . esc_attr__("Replace media", "enable-media-replace") . '" rel="permalink">' . esc_html__("Replace media", "enable-media-replace") . '</a>';
|
234 |
return array_merge($actions,$newaction);
|
235 |
}
|
236 |
|
classes/externals.php
ADDED
@@ -0,0 +1,64 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace EnableMediaReplace;
|
3 |
+
use EnableMediaReplace\ShortPixelLogger\ShortPixelLogger as Log;
|
4 |
+
use EnableMediaReplace\Notices\NoticeController as Notices;
|
5 |
+
|
6 |
+
|
7 |
+
class Externals
|
8 |
+
{
|
9 |
+
protected $replaceType = null;
|
10 |
+
protected $replaceSearchType = null;
|
11 |
+
|
12 |
+
protected $messages = array();
|
13 |
+
|
14 |
+
|
15 |
+
public function __construct()
|
16 |
+
{
|
17 |
+
add_filter('emr_display_replace_type_options', array($this, 'get_replace_type'));
|
18 |
+
add_filter('emr_enable_replace_and_search', array($this, 'get_replacesearch_type'));
|
19 |
+
|
20 |
+
add_action('emr_after_replace_type_options', array($this, 'get_messages'));
|
21 |
+
|
22 |
+
|
23 |
+
$this->check();
|
24 |
+
}
|
25 |
+
|
26 |
+
protected function check()
|
27 |
+
{
|
28 |
+
if (class_exists('FLBuilder'))
|
29 |
+
{
|
30 |
+
$this->replaceSearchType = false;
|
31 |
+
$this->messages[] = __('Replace and Search feature is not compatible with Beaver Builder.', 'enable-media-replace');
|
32 |
+
}
|
33 |
+
}
|
34 |
+
|
35 |
+
public function get_replace_type($bool)
|
36 |
+
{
|
37 |
+
if ($this->replaceType === null)
|
38 |
+
return $bool;
|
39 |
+
|
40 |
+
return $this->replaceType;
|
41 |
+
}
|
42 |
+
|
43 |
+
public function get_replacesearch_type($bool)
|
44 |
+
{
|
45 |
+
if ($this->replaceSearchType === null)
|
46 |
+
return $bool;
|
47 |
+
|
48 |
+
return $this->replaceSearchType;
|
49 |
+
}
|
50 |
+
|
51 |
+
public function get_messages()
|
52 |
+
{
|
53 |
+
foreach($this->messages as $message)
|
54 |
+
{
|
55 |
+
echo '<span class="nofeature-notice"><p>'. $message . '</p></span>';
|
56 |
+
}
|
57 |
+
|
58 |
+
}
|
59 |
+
|
60 |
+
|
61 |
+
|
62 |
+
|
63 |
+
|
64 |
+
}
|
classes/file.php
CHANGED
@@ -1,6 +1,9 @@
|
|
1 |
<?php
|
2 |
namespace EnableMediaReplace;
|
3 |
|
|
|
|
|
|
|
4 |
class emrFile
|
5 |
{
|
6 |
|
@@ -36,7 +39,15 @@ class emrFile
|
|
36 |
// This will *not* be checked, is not meant for permission of validation!
|
37 |
$this->fileMime = (isset($filedata['type'])) ? $filedata['type'] : false;
|
38 |
|
39 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
40 |
}
|
41 |
|
42 |
public function getFullFilePath()
|
@@ -64,11 +75,21 @@ class emrFile
|
|
64 |
return $this->fileName;
|
65 |
}
|
66 |
|
|
|
|
|
|
|
|
|
|
|
67 |
public function getFileMime()
|
68 |
{
|
69 |
return $this->fileMime;
|
70 |
}
|
71 |
|
|
|
|
|
|
|
|
|
|
|
72 |
|
73 |
}
|
74 |
|
1 |
<?php
|
2 |
namespace EnableMediaReplace;
|
3 |
|
4 |
+
use EnableMediaReplace\ShortPixelLogger\ShortPixelLogger as Log;
|
5 |
+
use EnableMediaReplace\Notices\NoticeController as Notices;
|
6 |
+
|
7 |
class emrFile
|
8 |
{
|
9 |
|
39 |
// This will *not* be checked, is not meant for permission of validation!
|
40 |
$this->fileMime = (isset($filedata['type'])) ? $filedata['type'] : false;
|
41 |
|
42 |
+
}
|
43 |
+
|
44 |
+
public function checkAndCreateFolder()
|
45 |
+
{
|
46 |
+
$path = $this->getFilePath();
|
47 |
+
if (! is_dir($path) && ! file_exists($path))
|
48 |
+
{
|
49 |
+
return wp_mkdir_p($path);
|
50 |
+
}
|
51 |
}
|
52 |
|
53 |
public function getFullFilePath()
|
75 |
return $this->fileName;
|
76 |
}
|
77 |
|
78 |
+
public function getFileExtension()
|
79 |
+
{
|
80 |
+
return $this->extension;
|
81 |
+
}
|
82 |
+
|
83 |
public function getFileMime()
|
84 |
{
|
85 |
return $this->fileMime;
|
86 |
}
|
87 |
|
88 |
+
public function exists()
|
89 |
+
{
|
90 |
+
return $this->exists;
|
91 |
+
}
|
92 |
+
|
93 |
|
94 |
}
|
95 |
|
classes/replacer.php
CHANGED
@@ -1,6 +1,8 @@
|
|
1 |
<?php
|
2 |
namespace EnableMediaReplace;
|
3 |
use \EnableMediaReplace\emrFile as File;
|
|
|
|
|
4 |
|
5 |
class Replacer
|
6 |
{
|
@@ -39,6 +41,7 @@ class Replacer
|
|
39 |
$source_file = trim(get_attached_file($post_id, apply_filters( 'emr_unfiltered_get_attached_file', true )));
|
40 |
|
41 |
$this->sourceFile = new File($source_file);
|
|
|
42 |
$this->source_post = get_post($post_id);
|
43 |
$this->source_is_image = wp_attachment_is('image', $this->source_post);
|
44 |
$this->source_metadata = wp_get_attachment_metadata( $post_id );
|
@@ -65,6 +68,7 @@ class Replacer
|
|
65 |
/** Replace the sourceFile with a target
|
66 |
* @param $file String Full Path to the Replacement File. This will usually be an uploaded file in /tmp/
|
67 |
* @param $fileName String The fileName of the uploaded file. This will be used if sourcefile is not to be overwritten.
|
|
|
68 |
*/
|
69 |
public function replaceWith($file, $fileName)
|
70 |
{
|
@@ -78,18 +82,25 @@ class Replacer
|
|
78 |
|
79 |
if (is_null($targetFile))
|
80 |
{
|
81 |
-
|
82 |
-
|
83 |
}
|
84 |
|
|
|
|
|
|
|
|
|
|
|
85 |
/* @todo See if wp_handle_sideload / wp_handle_upload can be more securely used for this */
|
86 |
$result_moved = move_uploaded_file($file,$targetFile);
|
87 |
|
88 |
if (false === $result_moved)
|
89 |
{
|
90 |
-
|
91 |
-
|
92 |
}
|
|
|
|
|
93 |
$this->targetFile = new File($targetFile);
|
94 |
|
95 |
if ($this->sourceFile->getPermissions() > 0)
|
@@ -114,6 +125,7 @@ class Replacer
|
|
114 |
{
|
115 |
update_attached_file($this->post_id, $filtered['file'] );
|
116 |
$this->targetFile = new File($filtered['file']); // handle as a new file
|
|
|
117 |
}
|
118 |
|
119 |
$metadata = wp_generate_attachment_metadata( $this->post_id, $this->targetFile->getFullFilePath() );
|
@@ -134,6 +146,8 @@ class Replacer
|
|
134 |
// update post doesn't update GUID on updates.
|
135 |
$wpdb->update( $wpdb->posts, array( 'guid' => $this->target_url), array('ID' => $this->post_id) );
|
136 |
//enable-media-replace-upload-done
|
|
|
|
|
137 |
if (is_wp_error($post_id))
|
138 |
{
|
139 |
$errors = $post_id->get_error_messages();
|
@@ -147,8 +161,10 @@ class Replacer
|
|
147 |
|
148 |
if(wp_attachment_is_image($this->post_id))
|
149 |
{
|
150 |
-
$this->ThumbnailUpdater->setNewMetadata($
|
151 |
-
$this->ThumbnailUpdater->updateThumbnails();
|
|
|
|
|
152 |
}
|
153 |
|
154 |
// if all set and done, update the date.
|
@@ -168,7 +184,8 @@ class Replacer
|
|
168 |
|
169 |
protected function getNewTitle()
|
170 |
{
|
171 |
-
|
|
|
172 |
$meta = $this->target_metadata;
|
173 |
|
174 |
if (isset($meta['image_meta']))
|
@@ -194,7 +211,7 @@ class Replacer
|
|
194 |
$targetPath = null;
|
195 |
if ($this->replaceMode == self::MODE_REPLACE)
|
196 |
{
|
197 |
-
$
|
198 |
}
|
199 |
elseif ($this->replaceMode == self::MODE_SEARCHREPLACE)
|
200 |
{
|
@@ -202,9 +219,26 @@ class Replacer
|
|
202 |
$unique = wp_unique_filename($path, $this->targetName);
|
203 |
|
204 |
$new_filename = apply_filters( 'emr_unique_filename', $unique, $path, $this->post_id );
|
205 |
-
$
|
206 |
}
|
207 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
208 |
}
|
209 |
|
210 |
/** Tries to remove all of the old image, without touching the metadata in database
|
@@ -212,9 +246,10 @@ class Replacer
|
|
212 |
*/
|
213 |
protected function removeCurrent()
|
214 |
{
|
215 |
-
$meta = wp_get_attachment_metadata( $this->post_id );
|
216 |
$backup_sizes = get_post_meta( $this->post_id, '_wp_attachment_backup_sizes', true );
|
217 |
-
$result = wp_delete_attachment_files($this->post_id, $meta, $backup_sizes, $this->sourceFile->getFullFilePath() );
|
|
|
218 |
}
|
219 |
|
220 |
/** Handle new dates for the replacement */
|
@@ -255,7 +290,14 @@ class Replacer
|
|
255 |
global $wpdb;
|
256 |
|
257 |
// Search-and-replace filename in post database
|
258 |
-
$current_base_url = emr_get_match_url( $this->source_url
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
259 |
|
260 |
/* Search and replace in WP_POSTS */
|
261 |
$posts_sql = $wpdb->remove_placeholder_escape($wpdb->prepare(
|
@@ -277,8 +319,9 @@ class Replacer
|
|
277 |
$replace_urls = emr_get_file_urls( $this->target_url, $this->target_metadata );
|
278 |
$replace_urls = array_values(emr_normalize_file_urls( $search_urls, $replace_urls ));
|
279 |
|
280 |
-
|
281 |
|
|
|
282 |
foreach ( $rs AS $rows ) {
|
283 |
$number_of_updates = $number_of_updates + 1;
|
284 |
// replace old URLs with new URLs.
|
@@ -292,6 +335,9 @@ class Replacer
|
|
292 |
// echo "$sql <BR>";
|
293 |
$wpdb->query( $sql );
|
294 |
}
|
|
|
|
|
|
|
295 |
foreach ($rsmeta as $row)
|
296 |
{
|
297 |
$number_of_updates++;
|
@@ -301,8 +347,8 @@ class Replacer
|
|
301 |
$sql = $wpdb->prepare('UPDATE ' . $wpdb->postmeta . ' SET meta_value = %s WHERE meta_id = %d', $content, $row['meta_id'] );
|
302 |
$wpdb->query($sql);
|
303 |
}
|
|
|
304 |
|
305 |
-
}
|
306 |
|
307 |
} // doSearchReplace
|
308 |
|
1 |
<?php
|
2 |
namespace EnableMediaReplace;
|
3 |
use \EnableMediaReplace\emrFile as File;
|
4 |
+
use EnableMediaReplace\ShortPixelLogger\ShortPixelLogger as Log;
|
5 |
+
use EnableMediaReplace\Notices\NoticeController as Notices;
|
6 |
|
7 |
class Replacer
|
8 |
{
|
41 |
$source_file = trim(get_attached_file($post_id, apply_filters( 'emr_unfiltered_get_attached_file', true )));
|
42 |
|
43 |
$this->sourceFile = new File($source_file);
|
44 |
+
|
45 |
$this->source_post = get_post($post_id);
|
46 |
$this->source_is_image = wp_attachment_is('image', $this->source_post);
|
47 |
$this->source_metadata = wp_get_attachment_metadata( $post_id );
|
68 |
/** Replace the sourceFile with a target
|
69 |
* @param $file String Full Path to the Replacement File. This will usually be an uploaded file in /tmp/
|
70 |
* @param $fileName String The fileName of the uploaded file. This will be used if sourcefile is not to be overwritten.
|
71 |
+
* @throws RunTimeException Can throw exception if something went wrong with the files.
|
72 |
*/
|
73 |
public function replaceWith($file, $fileName)
|
74 |
{
|
82 |
|
83 |
if (is_null($targetFile))
|
84 |
{
|
85 |
+
$ex = __('Target File could not be set. The source file might not be there. In case of search and replace, a filter might prevent this', "enable-media-replace");
|
86 |
+
throw new \RuntimeException($ex);
|
87 |
}
|
88 |
|
89 |
+
$targetFileObj = new File($targetFile);
|
90 |
+
$result = $targetFileObj->checkAndCreateFolder();
|
91 |
+
if ($result === false)
|
92 |
+
Log::addError('Directory creation for targetFile failed');
|
93 |
+
|
94 |
/* @todo See if wp_handle_sideload / wp_handle_upload can be more securely used for this */
|
95 |
$result_moved = move_uploaded_file($file,$targetFile);
|
96 |
|
97 |
if (false === $result_moved)
|
98 |
{
|
99 |
+
$ex = sprintf( esc_html__('The uploaded file could not be moved to %1$s. This is most likely an issue with permissions, or upload failed.', "enable-media-replace"), $targetFile );
|
100 |
+
throw new \RuntimeException($ex);
|
101 |
}
|
102 |
+
|
103 |
+
// init targetFile.
|
104 |
$this->targetFile = new File($targetFile);
|
105 |
|
106 |
if ($this->sourceFile->getPermissions() > 0)
|
125 |
{
|
126 |
update_attached_file($this->post_id, $filtered['file'] );
|
127 |
$this->targetFile = new File($filtered['file']); // handle as a new file
|
128 |
+
Log::addInfo('WP_Handle_upload filter returned different file', $filtered);
|
129 |
}
|
130 |
|
131 |
$metadata = wp_generate_attachment_metadata( $this->post_id, $this->targetFile->getFullFilePath() );
|
146 |
// update post doesn't update GUID on updates.
|
147 |
$wpdb->update( $wpdb->posts, array( 'guid' => $this->target_url), array('ID' => $this->post_id) );
|
148 |
//enable-media-replace-upload-done
|
149 |
+
|
150 |
+
// @todo Replace this one with proper Notices:addError;
|
151 |
if (is_wp_error($post_id))
|
152 |
{
|
153 |
$errors = $post_id->get_error_messages();
|
161 |
|
162 |
if(wp_attachment_is_image($this->post_id))
|
163 |
{
|
164 |
+
$this->ThumbnailUpdater->setNewMetadata($this->target_metadata);
|
165 |
+
$result = $this->ThumbnailUpdater->updateThumbnails();
|
166 |
+
if (false === $result)
|
167 |
+
Log::addWarn('Thumbnail Updater returned false');
|
168 |
}
|
169 |
|
170 |
// if all set and done, update the date.
|
184 |
|
185 |
protected function getNewTitle()
|
186 |
{
|
187 |
+
// get basename without extension
|
188 |
+
$title = basename($this->targetFile->getFileName(), '.' . $this->targetFile->getFileExtension());
|
189 |
$meta = $this->target_metadata;
|
190 |
|
191 |
if (isset($meta['image_meta']))
|
211 |
$targetPath = null;
|
212 |
if ($this->replaceMode == self::MODE_REPLACE)
|
213 |
{
|
214 |
+
$targetFile = $this->sourceFile->getFullFilePath(); // overwrite source
|
215 |
}
|
216 |
elseif ($this->replaceMode == self::MODE_SEARCHREPLACE)
|
217 |
{
|
219 |
$unique = wp_unique_filename($path, $this->targetName);
|
220 |
|
221 |
$new_filename = apply_filters( 'emr_unique_filename', $unique, $path, $this->post_id );
|
222 |
+
$targetFile = trailingslashit($path) . $new_filename;
|
223 |
}
|
224 |
+
if (is_dir($targetFile)) // this indicates an error with the source.
|
225 |
+
{
|
226 |
+
Log::addWarn('TargetFile is directory ' . $targetFile );
|
227 |
+
$upload_dir = wp_upload_dir();
|
228 |
+
if (isset($upload_dir['path']))
|
229 |
+
{
|
230 |
+
$targetFile = trailingslashit($upload_dir['path']) . wp_unique_filename($targetFile, $this->targetName);
|
231 |
+
}
|
232 |
+
else {
|
233 |
+
$err = 'EMR could not establish a proper destination for replacement';
|
234 |
+
Log::addError($err);
|
235 |
+
throw new \RuntimeException($err);
|
236 |
+
exit($err); // fallback
|
237 |
+
|
238 |
+
}
|
239 |
+
}
|
240 |
+
|
241 |
+
return $targetFile;
|
242 |
}
|
243 |
|
244 |
/** Tries to remove all of the old image, without touching the metadata in database
|
246 |
*/
|
247 |
protected function removeCurrent()
|
248 |
{
|
249 |
+
$meta = \wp_get_attachment_metadata( $this->post_id );
|
250 |
$backup_sizes = get_post_meta( $this->post_id, '_wp_attachment_backup_sizes', true );
|
251 |
+
$result = \wp_delete_attachment_files($this->post_id, $meta, $backup_sizes, $this->sourceFile->getFullFilePath() );
|
252 |
+
|
253 |
}
|
254 |
|
255 |
/** Handle new dates for the replacement */
|
290 |
global $wpdb;
|
291 |
|
292 |
// Search-and-replace filename in post database
|
293 |
+
$current_base_url = emr_get_match_url( $this->source_url);
|
294 |
+
|
295 |
+
/** Fail-safe if base_url is a whole directory, don't go search/replace */
|
296 |
+
if (is_dir($current_base_url))
|
297 |
+
{
|
298 |
+
Log::addError('Search Replace tried to replace to directory - ' . $current_base_url);
|
299 |
+
exit('Fail Safe :: Source Location seems to be a directory.');
|
300 |
+
}
|
301 |
|
302 |
/* Search and replace in WP_POSTS */
|
303 |
$posts_sql = $wpdb->remove_placeholder_escape($wpdb->prepare(
|
319 |
$replace_urls = emr_get_file_urls( $this->target_url, $this->target_metadata );
|
320 |
$replace_urls = array_values(emr_normalize_file_urls( $search_urls, $replace_urls ));
|
321 |
|
322 |
+
Log::addDebug('Replacing references', array($search_urls, $replace_urls));
|
323 |
|
324 |
+
if ( ! empty( $rs ) ) {
|
325 |
foreach ( $rs AS $rows ) {
|
326 |
$number_of_updates = $number_of_updates + 1;
|
327 |
// replace old URLs with new URLs.
|
335 |
// echo "$sql <BR>";
|
336 |
$wpdb->query( $sql );
|
337 |
}
|
338 |
+
}
|
339 |
+
if (! empty($rsmeta))
|
340 |
+
{
|
341 |
foreach ($rsmeta as $row)
|
342 |
{
|
343 |
$number_of_updates++;
|
347 |
$sql = $wpdb->prepare('UPDATE ' . $wpdb->postmeta . ' SET meta_value = %s WHERE meta_id = %d', $content, $row['meta_id'] );
|
348 |
$wpdb->query($sql);
|
349 |
}
|
350 |
+
}
|
351 |
|
|
|
352 |
|
353 |
} // doSearchReplace
|
354 |
|
classes/uihelper.php
ADDED
@@ -0,0 +1,297 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace EnableMediaReplace;
|
3 |
+
use EnableMediaReplace\ShortPixelLogger\ShortPixelLogger as Log;
|
4 |
+
use EnableMediaReplace\Notices\NoticeController as Notices;
|
5 |
+
|
6 |
+
/* Collection of functions helping the interface being cleaner. */
|
7 |
+
class UIHelper
|
8 |
+
{
|
9 |
+
protected $preview_size = '';
|
10 |
+
protected $preview_width = 0;
|
11 |
+
protected $preview_height = 0;
|
12 |
+
|
13 |
+
protected $preview_max_height = 500;
|
14 |
+
protected $preview_max_width = 400;
|
15 |
+
|
16 |
+
protected $full_width = 0;
|
17 |
+
protected $full_height = 0;
|
18 |
+
|
19 |
+
public function __construct()
|
20 |
+
{
|
21 |
+
|
22 |
+
}
|
23 |
+
|
24 |
+
|
25 |
+
public function getFormUrl($attach_id)
|
26 |
+
{
|
27 |
+
$url = admin_url('upload.php');
|
28 |
+
$url = add_query_arg(array(
|
29 |
+
'page' => 'enable-media-replace/enable-media-replace.php',
|
30 |
+
'noheader' => true,
|
31 |
+
'action' => 'media_replace_upload',
|
32 |
+
'attachment_id' => $attach_id,
|
33 |
+
));
|
34 |
+
|
35 |
+
if (isset($_REQUEST['SHORTPIXEL_DEBUG']))
|
36 |
+
{
|
37 |
+
$spdebug = $_REQUEST['SHORTPIXEL_DEBUG'];
|
38 |
+
if (is_numeric($spdebug))
|
39 |
+
$spdebug = intval($spdebug);
|
40 |
+
else {
|
41 |
+
$spdebug = sanitize_text_field($spdebug);
|
42 |
+
}
|
43 |
+
|
44 |
+
$url = add_query_arg('SHORTPIXEL_DEBUG', $spdebug, $url);
|
45 |
+
}
|
46 |
+
|
47 |
+
return $url;
|
48 |
+
|
49 |
+
}
|
50 |
+
|
51 |
+
public function getSuccesRedirect($post_id)
|
52 |
+
{
|
53 |
+
$url = admin_url('post.php');
|
54 |
+
$url = add_query_arg(array('action' => 'edit', 'post' => $post_id), $url);
|
55 |
+
|
56 |
+
$url = apply_filters('emr_returnurl', $url);
|
57 |
+
Log::addDebug('Success URL- ' . $url);
|
58 |
+
|
59 |
+
return $url;
|
60 |
+
|
61 |
+
}
|
62 |
+
|
63 |
+
public function getFailedRedirect($attach_id)
|
64 |
+
{
|
65 |
+
$url = admin_url('upload.php');
|
66 |
+
$url = add_query_arg(array(
|
67 |
+
'page' => 'enable-media-replace/enable-media-replace.php',
|
68 |
+
'action' => 'media_replace',
|
69 |
+
'attachment_id' => $attach_id,
|
70 |
+
'_wpnonce' => wp_create_nonce('media_replace'),
|
71 |
+
), $url
|
72 |
+
);
|
73 |
+
|
74 |
+
$url = apply_filters('emr_returnurl_failed', $url);
|
75 |
+
Log::addDebug('Failed URL- ' . $url);
|
76 |
+
return $url;
|
77 |
+
}
|
78 |
+
|
79 |
+
|
80 |
+
|
81 |
+
public function setPreviewSizes()
|
82 |
+
{
|
83 |
+
list($this->preview_size, $this->preview_width, $this->preview_height) = $this->findImageSizeByMax($this->preview_max_width);
|
84 |
+
}
|
85 |
+
|
86 |
+
public function setSourceSizes($attach_id)
|
87 |
+
{
|
88 |
+
$data = wp_get_attachment_image_src($attach_id, 'full');
|
89 |
+
if (is_array($data))
|
90 |
+
{
|
91 |
+
$this->full_width = $data[1];
|
92 |
+
$this->full_height = $data[2];
|
93 |
+
}
|
94 |
+
}
|
95 |
+
|
96 |
+
// Returns Preview Image HTML Output.
|
97 |
+
public function getPreviewImage($attach_id)
|
98 |
+
{
|
99 |
+
$data = false;
|
100 |
+
|
101 |
+
if ($attach_id > 0)
|
102 |
+
{
|
103 |
+
$data = wp_get_attachment_image_src($attach_id, $this->preview_size);
|
104 |
+
$file = get_attached_file($attach_id);
|
105 |
+
Log::addDebug('Attached File ' . $file, $data);
|
106 |
+
|
107 |
+
}
|
108 |
+
|
109 |
+
$mime_type = get_post_mime_type($attach_id);
|
110 |
+
|
111 |
+
if (! is_array($data) || ! file_exists($file) )
|
112 |
+
{
|
113 |
+
// if attachid higher than zero ( exists ) but not the image, fail, that's an error state.
|
114 |
+
$icon = ($attach_id < 0) ? '' : 'dashicons-no';
|
115 |
+
$is_document = false;
|
116 |
+
|
117 |
+
$args = array(
|
118 |
+
'width' => $this->preview_width,
|
119 |
+
'height' => $this->preview_height,
|
120 |
+
'is_image' => false,
|
121 |
+
'is_document' => $is_document,
|
122 |
+
'icon' => $icon,
|
123 |
+
);
|
124 |
+
|
125 |
+
// failed, it might be this server doens't support PDF thumbnails. Fallback to File preview.
|
126 |
+
if ($mime_type == 'application/pdf')
|
127 |
+
{
|
128 |
+
return $this->getPreviewFile($attach_id);
|
129 |
+
}
|
130 |
+
|
131 |
+
return $this->getPlaceHolder($args);
|
132 |
+
}
|
133 |
+
|
134 |
+
$url = $data[0];
|
135 |
+
$width = $data[1];
|
136 |
+
$height = $data[2];
|
137 |
+
// preview width, if source if found, should be set to source.
|
138 |
+
$this->preview_width = $width;
|
139 |
+
$this->preview_height = $height;
|
140 |
+
|
141 |
+
if ($width > $this->preview_max_width)
|
142 |
+
$width = $this->preview_max_width;
|
143 |
+
if ($height > $this->preview_max_height)
|
144 |
+
$height = $this->preview_max_height;
|
145 |
+
|
146 |
+
$image = "<img src='$url' width='$width' height='$height' class='image' style='max-width:100%; max-height: 100%;' />";
|
147 |
+
|
148 |
+
$args = array(
|
149 |
+
'width' => $width,
|
150 |
+
'height' => $height,
|
151 |
+
'image' => $image,
|
152 |
+
'mime_type' => $mime_type,
|
153 |
+
);
|
154 |
+
$output = $this->getPlaceHolder($args);
|
155 |
+
return $output;
|
156 |
+
}
|
157 |
+
|
158 |
+
public function getPreviewError($attach_id)
|
159 |
+
{
|
160 |
+
$args = array(
|
161 |
+
'width' => $this->preview_width,
|
162 |
+
'height' => $this->preview_height,
|
163 |
+
'icon' => 'dashicons-no',
|
164 |
+
'is_image' => false,
|
165 |
+
);
|
166 |
+
$output = $this->getPlaceHolder($args);
|
167 |
+
return $output;
|
168 |
+
}
|
169 |
+
|
170 |
+
public function getPreviewFile($attach_id)
|
171 |
+
{
|
172 |
+
if ($attach_id > 0)
|
173 |
+
{
|
174 |
+
$filepath = get_attached_file($attach_id);
|
175 |
+
$filename = basename($filepath);
|
176 |
+
}
|
177 |
+
else {
|
178 |
+
$filename = false;
|
179 |
+
}
|
180 |
+
|
181 |
+
$mime_type = get_post_mime_type($attach_id);
|
182 |
+
|
183 |
+
$args = array(
|
184 |
+
'width' => 300,
|
185 |
+
'height' => 300,
|
186 |
+
'is_image' => false,
|
187 |
+
'is_document' => true,
|
188 |
+
'layer' => $filename,
|
189 |
+
'mime_type' => $mime_type,
|
190 |
+
);
|
191 |
+
$output = $this->getPlaceHolder($args);
|
192 |
+
return $output;
|
193 |
+
}
|
194 |
+
|
195 |
+
public function findImageSizeByMax($maxwidth)
|
196 |
+
{
|
197 |
+
$image_sizes = $this->get_image_sizes();
|
198 |
+
|
199 |
+
$match_width = 0;
|
200 |
+
$match_height = 0;
|
201 |
+
$match = '';
|
202 |
+
|
203 |
+
foreach($image_sizes as $sizeName => $sizeItem)
|
204 |
+
{
|
205 |
+
|
206 |
+
$width = $sizeItem['width'];
|
207 |
+
if ($width > $match_width && $width <= $maxwidth)
|
208 |
+
{
|
209 |
+
$match = $sizeName;
|
210 |
+
$match_width = $width;
|
211 |
+
$match_height = $sizeItem['height'];
|
212 |
+
}
|
213 |
+
}
|
214 |
+
return array($match, $match_width, $match_height);
|
215 |
+
}
|
216 |
+
|
217 |
+
public function getPlaceHolder($args)
|
218 |
+
{
|
219 |
+
$defaults = array(
|
220 |
+
'width' => 150,
|
221 |
+
'height' => 150,
|
222 |
+
'image' => '',
|
223 |
+
'icon' => 'dashicons-media-document',
|
224 |
+
'layer' => $this->full_width . ' x ' . $this->full_height,
|
225 |
+
'is_image' => true,
|
226 |
+
'is_document' => false,
|
227 |
+
'mime_type' => false,
|
228 |
+
);
|
229 |
+
|
230 |
+
$args = wp_parse_args($args, $defaults);
|
231 |
+
$w = $args['width'];
|
232 |
+
$h = $args['height'];
|
233 |
+
|
234 |
+
if ($w < 150) // minimum
|
235 |
+
$w = 150;
|
236 |
+
if ($h < 150)
|
237 |
+
$h = 150;
|
238 |
+
|
239 |
+
$icon = $args['icon'];
|
240 |
+
|
241 |
+
if ($args['is_image'])
|
242 |
+
{
|
243 |
+
$placeholder_class = 'is_image';
|
244 |
+
}
|
245 |
+
else {
|
246 |
+
$placeholder_class = 'not_image';
|
247 |
+
}
|
248 |
+
|
249 |
+
if ($args['is_document'])
|
250 |
+
{
|
251 |
+
$placeholder_class .= ' is_document';
|
252 |
+
}
|
253 |
+
|
254 |
+
$filetype = '';
|
255 |
+
if ($args['mime_type'])
|
256 |
+
{
|
257 |
+
$filetype = 'data-filetype="' . $args['mime_type'] . '"';
|
258 |
+
}
|
259 |
+
|
260 |
+
|
261 |
+
$output = "<div class='image_placeholder $placeholder_class' $filetype style='width:" . $w . "px; height:". $h ."px'> ";
|
262 |
+
$output .= $args['image'];
|
263 |
+
$output .= "<div class='dashicons $icon'> </div>";
|
264 |
+
$output .= "<span class='textlayer'>" . $args['layer'] . "</span>";
|
265 |
+
$output .= "</div>";
|
266 |
+
|
267 |
+
return $output;
|
268 |
+
}
|
269 |
+
|
270 |
+
/**
|
271 |
+
* Get size information for all currently-registered image sizes.
|
272 |
+
* Directly stolen from - https://codex.wordpress.org/Function_Reference/get_intermediate_image_sizes
|
273 |
+
* @global $_wp_additional_image_sizes
|
274 |
+
* @uses get_intermediate_image_sizes()
|
275 |
+
* @return array $sizes Data for all currently-registered image sizes.
|
276 |
+
*/
|
277 |
+
private function get_image_sizes() {
|
278 |
+
global $_wp_additional_image_sizes;
|
279 |
+
|
280 |
+
$sizes = array();
|
281 |
+
|
282 |
+
foreach ( get_intermediate_image_sizes() as $_size ) {
|
283 |
+
if ( in_array( $_size, array('thumbnail', 'medium', 'medium_large', 'large') ) ) {
|
284 |
+
$sizes[ $_size ]['width'] = get_option( "{$_size}_size_w" );
|
285 |
+
$sizes[ $_size ]['height'] = get_option( "{$_size}_size_h" );
|
286 |
+
} elseif ( isset( $_wp_additional_image_sizes[ $_size ] ) ) {
|
287 |
+
$sizes[ $_size ] = array(
|
288 |
+
'width' => $_wp_additional_image_sizes[ $_size ]['width'],
|
289 |
+
'height' => $_wp_additional_image_sizes[ $_size ]['height'],
|
290 |
+
);
|
291 |
+
}
|
292 |
+
}
|
293 |
+
|
294 |
+
return $sizes;
|
295 |
+
}
|
296 |
+
|
297 |
+
} // class
|
composer.json
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"repositories": [
|
3 |
+
{
|
4 |
+
"packagist.org": false,
|
5 |
+
"type": "path",
|
6 |
+
"url": "../modules/*",
|
7 |
+
"options": {
|
8 |
+
"symlink": true
|
9 |
+
}
|
10 |
+
}
|
11 |
+
],
|
12 |
+
"require": {
|
13 |
+
"shortpixel/notices":"@dev",
|
14 |
+
"shortpixel/build" : "@dev"
|
15 |
+
},
|
16 |
+
|
17 |
+
"scripts": {
|
18 |
+
"post-update-cmd" : "\\ShortPixel\\Build\\Build::BuildIt",
|
19 |
+
"buildSP" : "\\ShortPixel\\Build\\Build::BuildIt"
|
20 |
+
},
|
21 |
+
"extra": {
|
22 |
+
"targetNamespace" : "EnableMediaReplace"
|
23 |
+
}
|
24 |
+
|
25 |
+
}
|
css/admin.css
CHANGED
@@ -772,14 +772,80 @@
|
|
772 |
min-height: 350px; }
|
773 |
.emr_upload_form .image_chooser.wrapper .image_previews {
|
774 |
margin: 15px 0; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
775 |
.emr_upload_form .option-flex-wrapper {
|
776 |
display: flex; }
|
777 |
.emr_upload_form .replace_type.wrapper {
|
778 |
flex: 1;
|
779 |
border: 1px solid #ccc;
|
780 |
margin: 15px 0; }
|
781 |
-
.emr_upload_form .replace_type.wrapper
|
782 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
783 |
.emr_upload_form .options.wrapper {
|
784 |
flex: 1;
|
785 |
border: 1px solid #ccc;
|
772 |
min-height: 350px; }
|
773 |
.emr_upload_form .image_chooser.wrapper .image_previews {
|
774 |
margin: 15px 0; }
|
775 |
+
.emr_upload_form .image_chooser.wrapper .image_previews .image_placeholder {
|
776 |
+
position: relative;
|
777 |
+
display: inline-block;
|
778 |
+
margin-right: 25px;
|
779 |
+
border: 1px solid #ddd;
|
780 |
+
vertical-align: top;
|
781 |
+
max-height: 500px; }
|
782 |
+
.emr_upload_form .image_chooser.wrapper .image_previews .image_placeholder .textlayer {
|
783 |
+
font-size: 25px;
|
784 |
+
line-height: 25px;
|
785 |
+
opacity: 0.7;
|
786 |
+
position: absolute;
|
787 |
+
color: #ccc;
|
788 |
+
left: 48%;
|
789 |
+
top: 50%;
|
790 |
+
transform: translate(-50%, -50%);
|
791 |
+
border: 1px dashed #eee;
|
792 |
+
background-color: #333;
|
793 |
+
padding: 8px; }
|
794 |
+
.emr_upload_form .image_chooser.wrapper .image_previews .image_placeholder .dashicons {
|
795 |
+
font-size: 60px;
|
796 |
+
position: absolute;
|
797 |
+
top: 50%;
|
798 |
+
margin-top: -30px;
|
799 |
+
left: 50%;
|
800 |
+
margin-left: -30px;
|
801 |
+
opacity: 0.5; }
|
802 |
+
.emr_upload_form .image_chooser.wrapper .image_previews .image_placeholder.is_image .dashicons::before, .emr_upload_form .image_chooser.wrapper .image_previews .image_placeholder.is_image .dashicons {
|
803 |
+
display: none; }
|
804 |
+
.emr_upload_form .image_chooser.wrapper .image_previews .image_placeholder.not_image img {
|
805 |
+
display: none; }
|
806 |
+
.emr_upload_form .image_chooser.wrapper .image_previews .image_placeholder.not_image .textlayer {
|
807 |
+
display: none; }
|
808 |
+
.emr_upload_form .image_chooser.wrapper .image_previews .image_placeholder.not_image.is_document .textlayer {
|
809 |
+
font-size: 18px;
|
810 |
+
line-height: 20px;
|
811 |
+
display: block; }
|
812 |
+
.emr_upload_form .form-error, .emr_upload_form .form-warning {
|
813 |
+
background: #fff;
|
814 |
+
padding: 8px;
|
815 |
+
border-left: 4px solid #ff0000;
|
816 |
+
margin: 10px 0;
|
817 |
+
display: none; }
|
818 |
+
.emr_upload_form .form-error p, .emr_upload_form .form-warning p {
|
819 |
+
margin: 0; }
|
820 |
+
.emr_upload_form .form-warning {
|
821 |
+
border-left: 4px solid #ffb900; }
|
822 |
.emr_upload_form .option-flex-wrapper {
|
823 |
display: flex; }
|
824 |
.emr_upload_form .replace_type.wrapper {
|
825 |
flex: 1;
|
826 |
border: 1px solid #ccc;
|
827 |
margin: 15px 0; }
|
828 |
+
.emr_upload_form .replace_type.wrapper .option {
|
829 |
+
position: relative;
|
830 |
+
z-index: 1; }
|
831 |
+
.emr_upload_form .replace_type.wrapper .option label {
|
832 |
+
font-size: 1.2em; }
|
833 |
+
.emr_upload_form .replace_type.wrapper .option .nofeature-notice {
|
834 |
+
border: 1px solid #ccc;
|
835 |
+
padding: 8px;
|
836 |
+
margin: 0;
|
837 |
+
position: absolute;
|
838 |
+
left: 0;
|
839 |
+
right: 0;
|
840 |
+
top: 0;
|
841 |
+
bottom: 0;
|
842 |
+
opacity: 0.8;
|
843 |
+
z-index: 9;
|
844 |
+
background: #444; }
|
845 |
+
.emr_upload_form .replace_type.wrapper .option .nofeature-notice p {
|
846 |
+
text-align: center;
|
847 |
+
color: #fff;
|
848 |
+
margin: 15px 0; }
|
849 |
.emr_upload_form .options.wrapper {
|
850 |
flex: 1;
|
851 |
border: 1px solid #ccc;
|
enable-media-replace.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
Plugin Name: Enable Media Replace
|
4 |
Plugin URI: https://wordpress.org/plugins/enable-media-replace/
|
5 |
Description: Enable replacing media files by uploading a new file in the "Edit Media" section of the WordPress Media Library.
|
6 |
-
Version: 3.3.
|
7 |
Author: ShortPixel
|
8 |
Author URI: https://shortpixel.com
|
9 |
Text Domain: enable-media-replace
|
@@ -24,6 +24,8 @@ http://www.gnu.org/licenses/gpl.html
|
|
24 |
*
|
25 |
*/
|
26 |
|
|
|
|
|
27 |
if ( ! defined( 'ABSPATH' ) ) {
|
28 |
exit; // Exit if accessed directly.
|
29 |
}
|
@@ -40,10 +42,13 @@ if(!defined("SHORTPIXEL_AFFILIATE_CODE")) {
|
|
40 |
define("SHORTPIXEL_AFFILIATE_CODE", 'VKG6LYN28044');
|
41 |
}
|
42 |
|
|
|
43 |
require_once('classes/replacer.php');
|
|
|
44 |
require_once('classes/file.php');
|
45 |
require_once('classes/cache.php');
|
46 |
require_once('classes/emr-plugin.php');
|
|
|
47 |
require_once('thumbnail_updater.php');
|
48 |
|
49 |
-
$emr_plugin =
|
3 |
Plugin Name: Enable Media Replace
|
4 |
Plugin URI: https://wordpress.org/plugins/enable-media-replace/
|
5 |
Description: Enable replacing media files by uploading a new file in the "Edit Media" section of the WordPress Media Library.
|
6 |
+
Version: 3.3.2
|
7 |
Author: ShortPixel
|
8 |
Author URI: https://shortpixel.com
|
9 |
Text Domain: enable-media-replace
|
24 |
*
|
25 |
*/
|
26 |
|
27 |
+
namespace EnableMediaReplace;
|
28 |
+
|
29 |
if ( ! defined( 'ABSPATH' ) ) {
|
30 |
exit; // Exit if accessed directly.
|
31 |
}
|
42 |
define("SHORTPIXEL_AFFILIATE_CODE", 'VKG6LYN28044');
|
43 |
}
|
44 |
|
45 |
+
require_once('build/shortpixel/autoload.php');
|
46 |
require_once('classes/replacer.php');
|
47 |
+
require_once('classes/uihelper.php');
|
48 |
require_once('classes/file.php');
|
49 |
require_once('classes/cache.php');
|
50 |
require_once('classes/emr-plugin.php');
|
51 |
+
require_once('classes/externals.php');
|
52 |
require_once('thumbnail_updater.php');
|
53 |
|
54 |
+
$emr_plugin = EnableMediaReplacePlugin::get();
|
js/emr_admin.js
CHANGED
@@ -3,12 +3,39 @@ jQuery(document).ready(function($)
|
|
3 |
// interface for emr.
|
4 |
var emrIf = new function ()
|
5 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
6 |
|
7 |
this.init = function()
|
8 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
$('input[name="timestamp_replace"]').on('change', $.proxy(this.checkCustomDate, this));
|
|
|
10 |
this.checkCustomDate();
|
11 |
this.loadDatePicker();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
},
|
13 |
this.loadDatePicker = function()
|
14 |
{
|
@@ -28,7 +55,6 @@ jQuery(document).ready(function($)
|
|
28 |
},
|
29 |
this.checkCustomDate = function()
|
30 |
{
|
31 |
-
console.log('check');
|
32 |
if ($('input[name="timestamp_replace"]:checked').val() == 3)
|
33 |
this.showCustomDate();
|
34 |
else
|
@@ -46,26 +72,148 @@ jQuery(document).ready(function($)
|
|
46 |
$('.custom_date').css('visibility', 'hidden');
|
47 |
});
|
48 |
}
|
49 |
-
|
|
|
|
|
|
|
|
|
50 |
|
51 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
52 |
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
58 |
{
|
59 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
60 |
}
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
});
|
67 |
}
|
68 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
69 |
|
70 |
window.enableMediaReplace = emrIf;
|
71 |
window.enableMediaReplace.init();
|
3 |
// interface for emr.
|
4 |
var emrIf = new function ()
|
5 |
{
|
6 |
+
var source_type;
|
7 |
+
var source_is_image;
|
8 |
+
var target_type;
|
9 |
+
var target_is_image;
|
10 |
+
|
11 |
+
var is_debug = false;
|
12 |
|
13 |
this.init = function()
|
14 |
{
|
15 |
+
if ( emr_options.is_debug)
|
16 |
+
{
|
17 |
+
this.is_debug = true;
|
18 |
+
this.debug('EMR Debug is active');
|
19 |
+
}
|
20 |
+
|
21 |
$('input[name="timestamp_replace"]').on('change', $.proxy(this.checkCustomDate, this));
|
22 |
+
$('input[name="userfile"]').on('change', $.proxy(this.handleImage, this));
|
23 |
this.checkCustomDate();
|
24 |
this.loadDatePicker();
|
25 |
+
|
26 |
+
var source = $('.image_placeholder').first();
|
27 |
+
if (typeof( $(source).data('filetype') ) !== 'undefined')
|
28 |
+
{
|
29 |
+
source_type = $(source).data('filetype');
|
30 |
+
this.debug('detected type - ' + source_type);
|
31 |
+
}
|
32 |
+
if (source.hasClass('is_image'))
|
33 |
+
{
|
34 |
+
source_is_image = true;
|
35 |
+
}
|
36 |
+
|
37 |
+
this.updateTextLayer(source, false);
|
38 |
+
|
39 |
},
|
40 |
this.loadDatePicker = function()
|
41 |
{
|
55 |
},
|
56 |
this.checkCustomDate = function()
|
57 |
{
|
|
|
58 |
if ($('input[name="timestamp_replace"]:checked').val() == 3)
|
59 |
this.showCustomDate();
|
60 |
else
|
72 |
$('.custom_date').css('visibility', 'hidden');
|
73 |
});
|
74 |
}
|
75 |
+
this.handleImage = function(e)
|
76 |
+
{
|
77 |
+
this.toggleErrors(false);
|
78 |
+
var target = e.target;
|
79 |
+
var file = target.files[0];
|
80 |
|
81 |
+
if (! target.files || target.files.length <= 0) // FileAPI appears to be not present, handle files on backend.
|
82 |
+
{
|
83 |
+
if ($('input[name="userfile"]').val().length > 0)
|
84 |
+
this.checkSubmit();
|
85 |
+
console.log('FileAPI not detected');
|
86 |
+
return;
|
87 |
+
}
|
88 |
|
89 |
+
var status = this.checkUpload(file);
|
90 |
+
this.debug('check upload status ' + status);
|
91 |
+
|
92 |
+
if (status)
|
93 |
+
{
|
94 |
+
this.updatePreview(file);
|
95 |
+
}
|
96 |
+
else {
|
97 |
+
this.updatePreview(null);
|
98 |
+
}
|
99 |
+
this.checkSubmit();
|
100 |
+
},
|
101 |
+
this.updatePreview = function(file)
|
102 |
+
{
|
103 |
+
var preview = $('.image_placeholder').last();
|
104 |
+
|
105 |
+
$(preview).find('img').remove();
|
106 |
+
$(preview).removeClass('is_image not_image is_document');
|
107 |
+
|
108 |
+
if (file !== null) /// file is null when empty, or error
|
109 |
{
|
110 |
+
target_is_image = (file.type.indexOf('image') >= 0) ? true : false;
|
111 |
+
target_type = file.type;
|
112 |
+
}
|
113 |
+
// If image, load thumbnail and get dimensions.
|
114 |
+
if (file && target_is_image)
|
115 |
+
{
|
116 |
+
var img = new Image();
|
117 |
+
img.src = window.URL.createObjectURL(file);
|
118 |
+
self = this;
|
119 |
+
|
120 |
+
img.setAttribute('style', 'max-width:100%; max-height: 100%;');
|
121 |
+
img.addEventListener("load", function () {
|
122 |
+
// $(preview).find('.textlayer').text(img.naturalWidth + ' x ' + img.naturalHeight );
|
123 |
+
self.updateTextLayer(preview, img.naturalWidth + ' x ' + img.naturalHeight);
|
124 |
+
});
|
125 |
+
|
126 |
+
$(preview).prepend(img);
|
127 |
+
$(preview).addClass('is_image');
|
128 |
+
}
|
129 |
+
else if(file === null)
|
130 |
+
{
|
131 |
+
$(preview).addClass('not_image');
|
132 |
+
$(preview).find('.dashicons').removeClass().addClass('dashicons dashicons-no');
|
133 |
+
//$(preview).find('.textlayer').text('');
|
134 |
+
this.updateTextLayer(preview, '');
|
135 |
+
this.debug('File is null');
|
136 |
+
}
|
137 |
+
else { // not an image
|
138 |
+
$(preview).addClass('not_image is_document');
|
139 |
+
$(preview).find('.dashicons').removeClass().addClass('dashicons dashicons-media-document');
|
140 |
+
//$(preview).find('.textlayer').text(file.name);
|
141 |
+
this.updateTextLayer(preview, file.name);
|
142 |
+
this.debug('Not image, media document');
|
143 |
}
|
144 |
+
|
145 |
+
if (target_type != source_type)
|
146 |
+
{
|
147 |
+
this.debug(target_type + ' not ' + source_type);
|
148 |
+
this.warningFileType();
|
|
|
149 |
}
|
150 |
+
},
|
151 |
+
// replace the text, check if text is there ( or hide ), and fix the layout.
|
152 |
+
this.updateTextLayer = function (preview, newtext)
|
153 |
+
{
|
154 |
+
textlayer = $(preview).find('.textlayer');
|
155 |
+
textlayer.css('opacity', '0');
|
156 |
+
if (newtext !== false)
|
157 |
+
textlayer.text(newtext);
|
158 |
+
|
159 |
+
if (textlayer.text() !== '')
|
160 |
+
{
|
161 |
+
textlayer.css('opacity', '0.7');
|
162 |
+
// textlayer.css('margin-left', '-' + (textlayer.width() / 2 ) + 'px');
|
163 |
+
}
|
164 |
+
|
165 |
+
},
|
166 |
+
this.checkSubmit = function()
|
167 |
+
{
|
168 |
+
var check = ($('input[name="userfile"]').val().length > 0) ? true : false;
|
169 |
+
|
170 |
+
if (check)
|
171 |
+
{
|
172 |
+
$('input[type="submit"]').prop('disabled', false);
|
173 |
+
}
|
174 |
+
else {
|
175 |
+
$('input[type="submit"]').prop('disabled', true);
|
176 |
+
}
|
177 |
+
},
|
178 |
+
this.toggleErrors = function(toggle)
|
179 |
+
{
|
180 |
+
$('.form-error').fadeOut();
|
181 |
+
$('.form-warning').fadeOut();
|
182 |
+
}
|
183 |
+
this.checkUpload = function(fileItem)
|
184 |
+
{
|
185 |
+
var maxsize = emr_options.maxfilesize;
|
186 |
+
|
187 |
+
if ($('input[name="userfile"]').val().length <= 0)
|
188 |
+
{
|
189 |
+
console.info('[EMR] - Upload file value not set in form. Pick a file');
|
190 |
+
$('input[name="userfile"]').val('');
|
191 |
+
return false;
|
192 |
+
}
|
193 |
+
|
194 |
+
if (fileItem.size > maxsize)
|
195 |
+
{
|
196 |
+
console.info('[EMR] - File too big for uploading - exceeds upload limits');
|
197 |
+
this.errorFileSize(fileItem);
|
198 |
+
$('input[name="userfile"]').val('');
|
199 |
+
return false;
|
200 |
+
}
|
201 |
+
return true;
|
202 |
+
},
|
203 |
+
this.errorFileSize = function(fileItem)
|
204 |
+
{
|
205 |
+
$('.form-error.filesize').find('.fn').text(fileItem.name);
|
206 |
+
$('.form-error.filesize').fadeIn();
|
207 |
+
}
|
208 |
+
this.warningFileType = function(fileItem)
|
209 |
+
{
|
210 |
+
$('.form-warning.filetype').fadeIn();
|
211 |
+
}
|
212 |
+
this.debug = function(message)
|
213 |
+
{
|
214 |
+
console.debug(message);
|
215 |
+
}
|
216 |
+
} // emrIf
|
217 |
|
218 |
window.enableMediaReplace = emrIf;
|
219 |
window.enableMediaReplace.init();
|
readme.txt
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
Contributors: ShortPixel
|
3 |
Donate link: https://www.paypal.me/resizeImage
|
4 |
Tags: replace, attachment, media, files, replace image, replace jpg, change media, replace media, image, file
|
5 |
-
Requires at least: 4.
|
6 |
Tested up to: 5.2
|
7 |
Requires PHP: 5.4
|
8 |
Stable tag: trunk
|
@@ -27,16 +27,16 @@ Now you'll be able to replace any uploaded file from the media "edit" view, wher
|
|
27 |
1. Just replace the file. This option requires you to upload a file of the same type as the one you are replacing. The name of the attachment will stay the same no matter what the file you upload is called.
|
28 |
1. Replace the file, use new file name and update all links. 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 will be updated to point to the new file name.
|
29 |
|
30 |
-
This plugin is very powerful and a must-have for any larger sites built with WordPress. It now also comes with preview of the replaced image!
|
31 |
|
32 |
#### Display file modification time
|
33 |
|
34 |
There is a shortcode available which picks up the file modification date and displays it in a post or a page. The code is:
|
35 |
-
`[file_modified id=XX format=XXXX]` where the "id" is required and the "format" is optional and defaults to your current WordPress settings for date and time format.
|
36 |
|
37 |
So `[file_modified id=870]` would display the last time the file with ID 870 was updated on your site. To get the ID for a file, check the URL when editing a file in the media library (see screenshot #4)
|
38 |
|
39 |
-
If you want more control over the format used to display the time, you can use the format option, so `[file_modified id=870 format=Y-m-d]` would display the file modification date but not the time. The format string uses [standard PHP date() formatting tags](http://php.net/manual/en/function.date.php).
|
40 |
|
41 |
|
42 |
#### Compatible and recommended Plugins =
|
@@ -47,6 +47,19 @@ If you want more control over the format used to display the time, you can use t
|
|
47 |
|
48 |
== Changelog ==
|
49 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
50 |
= 3.3.1 =
|
51 |
|
52 |
Release date: 18th June 2019
|
@@ -133,7 +146,7 @@ Release date: 18th June 2019
|
|
133 |
= 3.0.3 =
|
134 |
* Scrapped old method of detecting media screen, button to replace media will now show up in more places, yay!
|
135 |
* Made sure the call to get_attached_file() no longer skips filters, in response to several users wishes.
|
136 |
-
* Suppressed error messages on chmod()
|
137 |
* Added Japanese translation (Thank you, chacomv!)
|
138 |
|
139 |
= 3.0.2 =
|
@@ -169,7 +182,7 @@ Release date: 18th June 2019
|
|
169 |
* Added call to update_attached_file() which should purge changed files for various CDN and cache plugs. Thanks Dylan Barlett for the suggestion! (http://wordpress.org/support/topic/compatibility-with-w3-total-cache)
|
170 |
* Suppressed possible error in new hook added in 2.9.2
|
171 |
|
172 |
-
= 2.9.2 =
|
173 |
* Small bug fix
|
174 |
* Added hook for developers to enable purging possible CDN when updating files - thanks rubious for the suggestion!
|
175 |
|
@@ -185,14 +198,14 @@ Release date: 18th June 2019
|
|
185 |
* After uploading, the plugin now takes you back to edit screen instead of library
|
186 |
|
187 |
= 2.8.2 =
|
188 |
-
* Made another change to the discovery of media context which will hopefully fix a bug in certain cases. Thanks to "Joolee" at the WordPress.org forums!
|
189 |
-
* Added a new, supposedly better Russian translation from "Vlad".
|
190 |
|
191 |
= 2.8.1 =
|
192 |
-
* Fixed a small bug which could create error messages on some systems when deleting old image files.
|
193 |
|
194 |
= 2.8 =
|
195 |
-
* New and safer method for deleting thumbnails when a new image file is uploaded.
|
196 |
* New translations for simplified Chinese (thanks Tunghsiao Liu) and Italian (grazie Marco Chiesi)
|
197 |
* Added method for detecting upload screen to ensure backward compatibility with versions pre 3.5
|
198 |
|
@@ -206,13 +219,13 @@ Release date: 18th June 2019
|
|
206 |
* The "more reliable way" of determining MIME types turned out to be less reliable. Go figure. There seems to be no perfect way of performing a reliable check for MIME-types on an uploaded file that is also truly portable. I have now made checks for the availability of mime_content_type() before using it, using the old method as a fall-back. It is far from beautiful, so if anybody has a better way of doing it, please contact me!
|
207 |
|
208 |
= 2.5.1 =
|
209 |
-
* Bug fix - there is now a more reliable way of determining file type on your upload so you can upload PDF files without seeing that pesky "File type does not meet security guidelines" message.
|
210 |
* New translation to Danish - thanks to Michael Bering Petersen!
|
211 |
|
212 |
= 2.5 =
|
213 |
* Tested with WordPress 3.2.1
|
214 |
* New translation to German - thanks to Martin Lettner!
|
215 |
-
* New translation to French - thanks to François Collette!
|
216 |
|
217 |
= 2.4.1 =
|
218 |
* Bug fix for WordPress 3.1 RC. Now properly tested and should be working with 3.1 whenever it finally comes out. :)
|
@@ -239,7 +252,7 @@ Release date: 18th June 2019
|
|
239 |
* Replaced popup with inline navigation when replacing media
|
240 |
* Added instructions in admin link under Media
|
241 |
|
242 |
-
= 1.4.1 =
|
243 |
* Tested with WordPress 3.0 beta 2
|
244 |
|
245 |
= 1.4 =
|
@@ -269,23 +282,23 @@ Quick and easy installation:
|
|
269 |
|
270 |
= What does this plugin actually do? =
|
271 |
|
272 |
-
This plugin makes it easy to update/replace files that have been uploaded to the WordPress Media Library.
|
273 |
|
274 |
= How does it work? =
|
275 |
|
276 |
-
A new option will be available in the Edit Media view, called "Replace Media". This is where you can upload a new file to replace the old one.
|
277 |
|
278 |
= I replaced a file, but it didn't change! =
|
279 |
|
280 |
There are two main reasons this would happen.
|
281 |
|
282 |
-
First, make sure you are not viewing a cached version of the file, especially if you replaced an image. Press "Refresh" in your browser to make sure.
|
283 |
|
284 |
-
Second, if the file really looks unchanged, make sure WordPress has write permissions to the files in your uploads folder. If you have ever moved your WP installation (maybe when you moved it to a new server), the permissions on your uploaded files are commonly reset so that WordPress no longer has permissions to change the files. If you don't know how to do this, contact your web server operator.
|
285 |
|
286 |
== Screenshots ==
|
287 |
|
288 |
-
1. The new link in the media library.
|
289 |
2. The replace media-button as seen in the "Edit media" view.
|
290 |
3. The upload options.
|
291 |
4. Get the file ID in the edit file URL
|
2 |
Contributors: ShortPixel
|
3 |
Donate link: https://www.paypal.me/resizeImage
|
4 |
Tags: replace, attachment, media, files, replace image, replace jpg, change media, replace media, image, file
|
5 |
+
Requires at least: 4.2
|
6 |
Tested up to: 5.2
|
7 |
Requires PHP: 5.4
|
8 |
Stable tag: trunk
|
27 |
1. Just replace the file. This option requires you to upload a file of the same type as the one you are replacing. The name of the attachment will stay the same no matter what the file you upload is called.
|
28 |
1. Replace the file, use new file name and update all links. 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 will be updated to point to the new file name.
|
29 |
|
30 |
+
This plugin is very powerful and a must-have for any larger sites built with WordPress. It now also comes with preview of the replaced image!
|
31 |
|
32 |
#### Display file modification time
|
33 |
|
34 |
There is a shortcode available which picks up the file modification date and displays it in a post or a page. The code is:
|
35 |
+
`[file_modified id=XX format=XXXX]` where the "id" is required and the "format" is optional and defaults to your current WordPress settings for date and time format.
|
36 |
|
37 |
So `[file_modified id=870]` would display the last time the file with ID 870 was updated on your site. To get the ID for a file, check the URL when editing a file in the media library (see screenshot #4)
|
38 |
|
39 |
+
If you want more control over the format used to display the time, you can use the format option, so `[file_modified id=870 format=Y-m-d]` would display the file modification date but not the time. The format string uses [standard PHP date() formatting tags](http://php.net/manual/en/function.date.php).
|
40 |
|
41 |
|
42 |
#### Compatible and recommended Plugins =
|
47 |
|
48 |
== Changelog ==
|
49 |
|
50 |
+
= 3.3.2 =
|
51 |
+
|
52 |
+
Release date: 17th July 2019
|
53 |
+
* Check if medium size !> 400px, display that one, otherwise smallest.
|
54 |
+
* Fixed: Links not updated when using Advanced Custom Fields
|
55 |
+
* Fixed: Fails silently when file is too big for upload
|
56 |
+
* When source file does not exist, show placeholder instead of failed image load
|
57 |
+
* Fixed: Fatal error when replacing images
|
58 |
+
* Fixed: Not the right time zone on replace
|
59 |
+
* Fixed Beaver Builder incompatibility by not allowing replace with rename.
|
60 |
+
* Fixed: Cannot replace non default Wordpress file types, even those allowed to upload [ Media Library Assistant compat ]
|
61 |
+
* Fixed: error when trying to remove a file that doesn't exist - because the files are actually on another server
|
62 |
+
|
63 |
= 3.3.1 =
|
64 |
|
65 |
Release date: 18th June 2019
|
146 |
= 3.0.3 =
|
147 |
* Scrapped old method of detecting media screen, button to replace media will now show up in more places, yay!
|
148 |
* Made sure the call to get_attached_file() no longer skips filters, in response to several users wishes.
|
149 |
+
* Suppressed error messages on chmod()
|
150 |
* Added Japanese translation (Thank you, chacomv!)
|
151 |
|
152 |
= 3.0.2 =
|
182 |
* Added call to update_attached_file() which should purge changed files for various CDN and cache plugs. Thanks Dylan Barlett for the suggestion! (http://wordpress.org/support/topic/compatibility-with-w3-total-cache)
|
183 |
* Suppressed possible error in new hook added in 2.9.2
|
184 |
|
185 |
+
= 2.9.2 =
|
186 |
* Small bug fix
|
187 |
* Added hook for developers to enable purging possible CDN when updating files - thanks rubious for the suggestion!
|
188 |
|
198 |
* After uploading, the plugin now takes you back to edit screen instead of library
|
199 |
|
200 |
= 2.8.2 =
|
201 |
+
* Made another change to the discovery of media context which will hopefully fix a bug in certain cases. Thanks to "Joolee" at the WordPress.org forums!
|
202 |
+
* Added a new, supposedly better Russian translation from "Vlad".
|
203 |
|
204 |
= 2.8.1 =
|
205 |
+
* Fixed a small bug which could create error messages on some systems when deleting old image files.
|
206 |
|
207 |
= 2.8 =
|
208 |
+
* New and safer method for deleting thumbnails when a new image file is uploaded.
|
209 |
* New translations for simplified Chinese (thanks Tunghsiao Liu) and Italian (grazie Marco Chiesi)
|
210 |
* Added method for detecting upload screen to ensure backward compatibility with versions pre 3.5
|
211 |
|
219 |
* The "more reliable way" of determining MIME types turned out to be less reliable. Go figure. There seems to be no perfect way of performing a reliable check for MIME-types on an uploaded file that is also truly portable. I have now made checks for the availability of mime_content_type() before using it, using the old method as a fall-back. It is far from beautiful, so if anybody has a better way of doing it, please contact me!
|
220 |
|
221 |
= 2.5.1 =
|
222 |
+
* Bug fix - there is now a more reliable way of determining file type on your upload so you can upload PDF files without seeing that pesky "File type does not meet security guidelines" message.
|
223 |
* New translation to Danish - thanks to Michael Bering Petersen!
|
224 |
|
225 |
= 2.5 =
|
226 |
* Tested with WordPress 3.2.1
|
227 |
* New translation to German - thanks to Martin Lettner!
|
228 |
+
* New translation to French - thanks to François Collette!
|
229 |
|
230 |
= 2.4.1 =
|
231 |
* Bug fix for WordPress 3.1 RC. Now properly tested and should be working with 3.1 whenever it finally comes out. :)
|
252 |
* Replaced popup with inline navigation when replacing media
|
253 |
* Added instructions in admin link under Media
|
254 |
|
255 |
+
= 1.4.1 =
|
256 |
* Tested with WordPress 3.0 beta 2
|
257 |
|
258 |
= 1.4 =
|
282 |
|
283 |
= What does this plugin actually do? =
|
284 |
|
285 |
+
This plugin makes it easy to update/replace files that have been uploaded to the WordPress Media Library.
|
286 |
|
287 |
= How does it work? =
|
288 |
|
289 |
+
A new option will be available in the Edit Media view, called "Replace Media". This is where you can upload a new file to replace the old one.
|
290 |
|
291 |
= I replaced a file, but it didn't change! =
|
292 |
|
293 |
There are two main reasons this would happen.
|
294 |
|
295 |
+
First, make sure you are not viewing a cached version of the file, especially if you replaced an image. Press "Refresh" in your browser to make sure.
|
296 |
|
297 |
+
Second, if the file really looks unchanged, make sure WordPress has write permissions to the files in your uploads folder. If you have ever moved your WP installation (maybe when you moved it to a new server), the permissions on your uploaded files are commonly reset so that WordPress no longer has permissions to change the files. If you don't know how to do this, contact your web server operator.
|
298 |
|
299 |
== Screenshots ==
|
300 |
|
301 |
+
1. The new link in the media library.
|
302 |
2. The replace media-button as seen in the "Edit media" view.
|
303 |
3. The upload options.
|
304 |
4. Get the file ID in the edit file URL
|
scss/admin.scss
CHANGED
@@ -24,7 +24,77 @@
|
|
24 |
.image_previews
|
25 |
{
|
26 |
margin: 15px 0;
|
27 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
}
|
29 |
|
30 |
.option-flex-wrapper
|
@@ -37,10 +107,39 @@
|
|
37 |
flex: 1;
|
38 |
border: 1px solid #ccc;
|
39 |
margin: 15px 0;
|
40 |
-
|
41 |
{
|
42 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
}
|
|
|
44 |
}
|
45 |
|
46 |
.options.wrapper
|
@@ -130,4 +229,4 @@
|
|
130 |
line-height: 1.3em; // match size
|
131 |
}
|
132 |
}
|
133 |
-
}
|
24 |
.image_previews
|
25 |
{
|
26 |
margin: 15px 0;
|
27 |
+
.image_placeholder
|
28 |
+
{
|
29 |
+
position: relative;
|
30 |
+
display: inline-block;
|
31 |
+
margin-right: 25px;
|
32 |
+
border: 1px solid #ddd;
|
33 |
+
vertical-align: top;
|
34 |
+
max-height: 500px;
|
35 |
+
.textlayer
|
36 |
+
{
|
37 |
+
font-size: 25px;
|
38 |
+
line-height: 25px;
|
39 |
+
opacity: 0.7;
|
40 |
+
position: absolute;
|
41 |
+
color: #ccc;
|
42 |
+
left: 48%;
|
43 |
+
top: 50%;
|
44 |
+
transform: translate(-50%, -50%);
|
45 |
+
border: 1px dashed #eee;
|
46 |
+
background-color: #333;
|
47 |
+
padding: 8px;
|
48 |
+
//max-width: 100%;
|
49 |
+
}
|
50 |
+
.dashicons
|
51 |
+
{
|
52 |
+
font-size: 60px;
|
53 |
+
position: absolute;
|
54 |
+
top: 50%;
|
55 |
+
margin-top: -30px;
|
56 |
+
left: 50%;
|
57 |
+
margin-left: -30px;
|
58 |
+
opacity: 0.5;
|
59 |
+
|
60 |
+
}
|
61 |
+
&.is_image
|
62 |
+
{
|
63 |
+
.dashicons::before, .dashicons { display: none }
|
64 |
+
|
65 |
+
|
66 |
+
}
|
67 |
+
&.not_image
|
68 |
+
{
|
69 |
+
img { display: none; }
|
70 |
+
.textlayer { display: none; }
|
71 |
+
&.is_document{
|
72 |
+
.textlayer {
|
73 |
+
font-size: 18px;
|
74 |
+
line-height: 20px;
|
75 |
+
display: block;
|
76 |
+
|
77 |
+
}
|
78 |
+
}
|
79 |
+
} // not_image
|
80 |
+
} // image_placeholder
|
81 |
+
} // image_previews
|
82 |
+
} // wrapper
|
83 |
+
|
84 |
+
.form-error, .form-warning
|
85 |
+
{
|
86 |
+
background: #fff;
|
87 |
+
padding: 8px;
|
88 |
+
border-left: 4px solid #ff0000;
|
89 |
+
// display: inline-block;
|
90 |
+
margin: 10px 0;
|
91 |
+
display: none;
|
92 |
+
p { margin: 0; }
|
93 |
+
|
94 |
+
}
|
95 |
+
.form-warning
|
96 |
+
{
|
97 |
+
border-left: 4px solid #ffb900;
|
98 |
}
|
99 |
|
100 |
.option-flex-wrapper
|
107 |
flex: 1;
|
108 |
border: 1px solid #ccc;
|
109 |
margin: 15px 0;
|
110 |
+
.option
|
111 |
{
|
112 |
+
position: relative;
|
113 |
+
z-index: 1;
|
114 |
+
&.disabled
|
115 |
+
{
|
116 |
+
// color: #eee;
|
117 |
+
}
|
118 |
+
label
|
119 |
+
{
|
120 |
+
font-size: 1.2em;
|
121 |
+
}
|
122 |
+
.nofeature-notice
|
123 |
+
{
|
124 |
+
border: 1px solid #ccc;
|
125 |
+
padding: 8px;
|
126 |
+
margin: 0;
|
127 |
+
position: absolute;
|
128 |
+
left: 0;
|
129 |
+
right: 0;
|
130 |
+
top: 0;
|
131 |
+
bottom: 0;
|
132 |
+
opacity: 0.8;
|
133 |
+
z-index: 9;
|
134 |
+
background: #444;
|
135 |
+
p {
|
136 |
+
text-align: center;
|
137 |
+
color: #fff;
|
138 |
+
margin: 15px 0;
|
139 |
+
}
|
140 |
+
}
|
141 |
}
|
142 |
+
|
143 |
}
|
144 |
|
145 |
.options.wrapper
|
229 |
line-height: 1.3em; // match size
|
230 |
}
|
231 |
}
|
232 |
+
} // emr_upload_form
|
thumbnail_updater.php
CHANGED
@@ -2,6 +2,9 @@
|
|
2 |
if ( ! defined( 'ABSPATH' ) )
|
3 |
exit; // Exit if accessed directly.
|
4 |
|
|
|
|
|
|
|
5 |
/* Simple class for updating thumbnails.
|
6 |
*
|
7 |
*
|
@@ -60,7 +63,12 @@ class ThumbnailUpdater
|
|
60 |
if (isset($this->newMeta['sizes'][$sizeName]))
|
61 |
{
|
62 |
|
63 |
-
|
|
|
|
|
|
|
|
|
|
|
64 |
$newFile = $this->newMeta['sizes'][$sizeName]['file'];
|
65 |
|
66 |
// if images are not same size.
|
@@ -84,6 +92,7 @@ class ThumbnailUpdater
|
|
84 |
global $wpdb;
|
85 |
$sql = "UPDATE " . $this->post_table . " set post_content = REPLACE(post_content, %s, %s)";
|
86 |
|
|
|
87 |
foreach($this->convertArray as $convert_item)
|
88 |
{
|
89 |
$from = $convert_item['imageFrom'];
|
@@ -112,13 +121,22 @@ class ThumbnailUpdater
|
|
112 |
|
113 |
if ( $thisdiff < $diff )
|
114 |
{
|
115 |
-
$diff = $thisdiff;
|
116 |
$closest_file = $data['file'];
|
117 |
-
$
|
|
|
|
|
|
|
|
|
118 |
}
|
119 |
}
|
120 |
|
121 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
122 |
|
123 |
}
|
124 |
|
2 |
if ( ! defined( 'ABSPATH' ) )
|
3 |
exit; // Exit if accessed directly.
|
4 |
|
5 |
+
use EnableMediaReplace\ShortPixelLogger\ShortPixelLogger as Log;
|
6 |
+
use EnableMediaReplace\Notices\NoticeController as Notices;
|
7 |
+
|
8 |
/* Simple class for updating thumbnails.
|
9 |
*
|
10 |
*
|
63 |
if (isset($this->newMeta['sizes'][$sizeName]))
|
64 |
{
|
65 |
|
66 |
+
//in some rare cases 'file' is missing
|
67 |
+
$oldFile = isset($data['file']) ? $data['file'] : null;
|
68 |
+
if(is_array($oldFile)) { $oldFile = $oldFile[0];} // HelpScout case 709692915
|
69 |
+
if(empty($oldFile)) {
|
70 |
+
return false; //make sure we don't replace in this case as we will break the URLs for all the images in the folder.
|
71 |
+
}
|
72 |
$newFile = $this->newMeta['sizes'][$sizeName]['file'];
|
73 |
|
74 |
// if images are not same size.
|
92 |
global $wpdb;
|
93 |
$sql = "UPDATE " . $this->post_table . " set post_content = REPLACE(post_content, %s, %s)";
|
94 |
|
95 |
+
Log::addDebug('Thumbnail Updater - Converting Thumbnails for sizes', $this->convertArray);
|
96 |
foreach($this->convertArray as $convert_item)
|
97 |
{
|
98 |
$from = $convert_item['imageFrom'];
|
121 |
|
122 |
if ( $thisdiff < $diff )
|
123 |
{
|
|
|
124 |
$closest_file = $data['file'];
|
125 |
+
if(is_array($closest_file)) { $closest_file = $closest_file[0];} // HelpScout case 709692915
|
126 |
+
if(!empty($closest_file)) {
|
127 |
+
$diff = $thisdiff;
|
128 |
+
$found_metasize = true;
|
129 |
+
}
|
130 |
}
|
131 |
}
|
132 |
|
133 |
+
if(empty($closest_file)) return;
|
134 |
+
$oldFile = $oldData['file'];
|
135 |
+
if(is_array($oldFile)) { $oldFile = $oldFile[0];} // HelpScout case 709692915
|
136 |
+
if(empty($oldFile)) {
|
137 |
+
return; //make sure we don't replace in this case as we will break the URLs for all the images in the folder.
|
138 |
+
}
|
139 |
+
$this->convertArray[] = array('imageFrom' => $this->relPath . $oldFile, 'imageTo' => $this->relPath . $closest_file);
|
140 |
|
141 |
}
|
142 |
|
views/popup.php
CHANGED
@@ -1,4 +1,11 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
/**
|
3 |
* Uploadscreen for selecting and uploading new media file
|
4 |
*
|
@@ -20,6 +27,7 @@ global $wpdb;
|
|
20 |
|
21 |
$table_name = $wpdb->prefix . "posts";
|
22 |
|
|
|
23 |
|
24 |
//$sql = "SELECT guid, post_mime_type FROM $table_name WHERE ID = " . (int) $_GET["attachment_id"];
|
25 |
//list($current_filename, $current_filetype) = $wpdb->get_row($sql, ARRAY_N);
|
@@ -28,10 +36,15 @@ $attachment_id = intval($_GET['attachment_id']);
|
|
28 |
$attachment = get_post($attachment_id);
|
29 |
|
30 |
$filepath = get_attached_file($attachment_id); // fullpath
|
31 |
-
$fileurl = wp_get_attachment_url($attachment_id); //full url
|
32 |
-
|
33 |
$filetype = $attachment->post_mime_type;
|
34 |
$filename = basename($filepath);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
35 |
|
36 |
?>
|
37 |
<style>
|
@@ -49,15 +62,15 @@ $filename = basename($filepath);
|
|
49 |
<h1><?php echo esc_html__("Replace Media Upload", "enable-media-replace"); ?></h1>
|
50 |
|
51 |
<?php
|
52 |
-
$url = admin_url( "upload.php?page=enable-media-replace/enable-media-replace.php&noheader=true&action=media_replace_upload&attachment_id=" . $attachment_id );
|
53 |
|
|
|
54 |
$formurl = wp_nonce_url( $url, "media_replace_upload" );
|
55 |
if (FORCE_SSL_ADMIN) {
|
56 |
$formurl = str_replace("http:", "https:", $formurl);
|
57 |
}
|
58 |
?>
|
59 |
|
60 |
-
<form enctype="multipart/form-data" method="
|
61 |
<section class='image_chooser wrapper'>
|
62 |
<div class='section-header'> <?php _e('Choose Replacement Image', 'enable-replace-media'); ?></div>
|
63 |
|
@@ -95,11 +108,33 @@ $filename = basename($filepath);
|
|
95 |
<?php } ?>
|
96 |
|
97 |
<p><?php echo esc_html__("Choose a file to upload from your computer", "enable-media-replace"); ?></p>
|
|
|
|
|
|
|
98 |
|
99 |
-
|
|
|
|
|
|
|
100 |
<div class='image_previews'>
|
101 |
-
|
102 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
103 |
</div>
|
104 |
|
105 |
</section>
|
@@ -107,30 +142,40 @@ $filename = basename($filepath);
|
|
107 |
<section class='replace_type wrapper'>
|
108 |
<div class='section-header'> <?php _e('Replacement Options', 'enable-replace-media'); ?></div>
|
109 |
|
110 |
-
<?php
|
|
|
|
|
111 |
|
112 |
|
113 |
-
|
114 |
-
|
115 |
-
|
|
|
|
|
|
|
116 |
|
|
|
|
|
|
|
117 |
|
118 |
-
|
119 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
120 |
|
121 |
-
<?php endif; ?>
|
122 |
-
<?php if ( apply_filters( 'emr_enable_replace_and_search', true ) ) : ?>
|
123 |
-
<label for="replace_type_2"><input <?php echo $s3pluginExist ? 'CHECKED' : '' ?> id="replace_type_2" type="radio" name="replace_type" value="replace_and_search"> <?php echo __("Replace the file, use new file name and update all links", "enable-media-replace"); ?></label>
|
124 |
<p class="howto"><?php printf( esc_html__("Note: If you check this option, the name and type of the file you are about to upload will replace the old file. All links pointing to the current file (%s) will be updated to point to the new file name.", "enable-media-replace"), $filename ); ?></p>
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
<input type="hidden" name="replace_type" value="replace_and_search" />
|
132 |
-
<?php endif; ?>
|
133 |
-
<?php endif; ?>
|
134 |
</section>
|
135 |
<section class='options wrapper'>
|
136 |
<div class='section-header'> <?php _e('Date Options', 'enable-media-replace'); ?></div>
|
@@ -138,7 +183,7 @@ $filename = basename($filepath);
|
|
138 |
<?php
|
139 |
$attachment_current_date = date_i18n('d/M/Y H:i', strtotime($attachment->post_date) );
|
140 |
$time = current_time('mysql');
|
141 |
-
$date = new dateTime($time);
|
142 |
?>
|
143 |
<p><?php _e('When replacing the media, do you want to:', 'enable-media-replace'); ?></p>
|
144 |
<ul>
|
@@ -154,7 +199,7 @@ $filename = basename($filepath);
|
|
154 |
|
155 |
@ <input type='text' name="custom_hour" class='emr_hour' value="<?php echo $date->format('H') ?>" />
|
156 |
<input type="text" name="custom_minute" class='emr_minute' value="<?php echo $date->format('i'); ?>" />
|
157 |
-
<input type="hidden" name="custom_date_formatted" value="" />
|
158 |
</div>
|
159 |
</div>
|
160 |
</section>
|
@@ -165,37 +210,3 @@ $filename = basename($filepath);
|
|
165 |
</section>
|
166 |
</form>
|
167 |
</div>
|
168 |
-
<script>
|
169 |
-
function imageHandle(event) {
|
170 |
-
var file = document.getElementById("userfile");
|
171 |
-
var submit = document.getElementById("submit");
|
172 |
-
var preview = document.getElementById("previewImage");
|
173 |
-
|
174 |
-
appendPreview(file, preview, event);
|
175 |
-
enableSubmitButton(file, submit);
|
176 |
-
}
|
177 |
-
|
178 |
-
function appendPreview(fileSource, preview, event) {
|
179 |
-
if (fileSource.value) {
|
180 |
-
var file = fileSource.files[0];
|
181 |
-
if (file.type.match("image/*")) {
|
182 |
-
preview.setAttribute("src", window.URL.createObjectURL(file));
|
183 |
-
preview.setAttribute("style", "object-fit: cover");
|
184 |
-
} else {
|
185 |
-
preview.setAttribute("src", "https://dummyimage.com/150x150/ccc/969696.gif&text=File");
|
186 |
-
preview.removeAttribute("style");
|
187 |
-
}
|
188 |
-
} else {
|
189 |
-
preview.setAttribute("src", "https://via.placeholder.com/150x150");
|
190 |
-
}
|
191 |
-
}
|
192 |
-
function enableSubmitButton(file, submit)
|
193 |
-
{
|
194 |
-
if (file.value) {
|
195 |
-
submit.disabled = false;
|
196 |
-
submit.removeAttribute("disabled");
|
197 |
-
} else {
|
198 |
-
submit.setAttribute("disabled", true);
|
199 |
-
}
|
200 |
-
}
|
201 |
-
</script>
|
1 |
<?php
|
2 |
+
namespace EnableMediaReplace;
|
3 |
+
|
4 |
+
//use \EnableMediaReplace\UIHelper;
|
5 |
+
use EnableMediaReplace\ShortPixelLogger\ShortPixelLogger as Log;
|
6 |
+
use EnableMediaReplace\Notices\NoticeController as Notices;
|
7 |
+
|
8 |
+
|
9 |
/**
|
10 |
* Uploadscreen for selecting and uploading new media file
|
11 |
*
|
27 |
|
28 |
$table_name = $wpdb->prefix . "posts";
|
29 |
|
30 |
+
Log::addDebug('Load Popup Form View');
|
31 |
|
32 |
//$sql = "SELECT guid, post_mime_type FROM $table_name WHERE ID = " . (int) $_GET["attachment_id"];
|
33 |
//list($current_filename, $current_filetype) = $wpdb->get_row($sql, ARRAY_N);
|
36 |
$attachment = get_post($attachment_id);
|
37 |
|
38 |
$filepath = get_attached_file($attachment_id); // fullpath
|
|
|
|
|
39 |
$filetype = $attachment->post_mime_type;
|
40 |
$filename = basename($filepath);
|
41 |
+
$source_mime = get_post_mime_type($attachment_id);
|
42 |
+
|
43 |
+
$uiHelper = new UIHelper();
|
44 |
+
$uiHelper->setPreviewSizes();
|
45 |
+
$uiHelper->setSourceSizes($attachment_id);
|
46 |
+
|
47 |
+
Log::addDebug('Popup view Data', array('id' => $attachment_id, 'source_mime' => $source_mime, 'filepath' => $filepath));
|
48 |
|
49 |
?>
|
50 |
<style>
|
62 |
<h1><?php echo esc_html__("Replace Media Upload", "enable-media-replace"); ?></h1>
|
63 |
|
64 |
<?php
|
|
|
65 |
|
66 |
+
$url = $uiHelper->getFormUrl($attachment_id);
|
67 |
$formurl = wp_nonce_url( $url, "media_replace_upload" );
|
68 |
if (FORCE_SSL_ADMIN) {
|
69 |
$formurl = str_replace("http:", "https:", $formurl);
|
70 |
}
|
71 |
?>
|
72 |
|
73 |
+
<form enctype="multipart/form-data" method="POST" action="<?php echo $formurl; ?>">
|
74 |
<section class='image_chooser wrapper'>
|
75 |
<div class='section-header'> <?php _e('Choose Replacement Image', 'enable-replace-media'); ?></div>
|
76 |
|
108 |
<?php } ?>
|
109 |
|
110 |
<p><?php echo esc_html__("Choose a file to upload from your computer", "enable-media-replace"); ?></p>
|
111 |
+
<p><?php printf(__('Maximum file size: <strong>%s</strong>','enable-media-replace'), size_format(wp_max_upload_size() ) ) ?></p>
|
112 |
+
<div class='form-error filesize'><p><?php printf(__('%s f %s exceeds the maximum upload size for this site.', 'enable-media-replace'), '<span class="fn">', '</span>'); ?></p>
|
113 |
+
</div>
|
114 |
|
115 |
+
<div class='form-warning filetype'><p><?php printf(__('Replacement file is not the same filetype. This might cause unexpected issues')); ?></p></div>
|
116 |
+
|
117 |
+
|
118 |
+
<input type="file" name="userfile" id="userfile" />
|
119 |
<div class='image_previews'>
|
120 |
+
<?php if (wp_attachment_is('image', $attachment_id) || $source_mime == 'application/pdf')
|
121 |
+
{
|
122 |
+
echo $uiHelper->getPreviewImage($attachment_id);
|
123 |
+
echo $uiHelper->getPreviewImage(-1);
|
124 |
+
}
|
125 |
+
else {
|
126 |
+
if (strlen($filepath) == 0) // check if image in error state.
|
127 |
+
{
|
128 |
+
echo $uiHelper->getPreviewError(-1);
|
129 |
+
echo $uiHelper->getPreviewImage(-1);
|
130 |
+
}
|
131 |
+
else {
|
132 |
+
echo $uiHelper->getPreviewFile($attachment_id);
|
133 |
+
echo $uiHelper->getPreviewFile(-1);
|
134 |
+
}
|
135 |
+
|
136 |
+
}
|
137 |
+
?>
|
138 |
</div>
|
139 |
|
140 |
</section>
|
142 |
<section class='replace_type wrapper'>
|
143 |
<div class='section-header'> <?php _e('Replacement Options', 'enable-replace-media'); ?></div>
|
144 |
|
145 |
+
<?php
|
146 |
+
// these are also used in externals, for checks.
|
147 |
+
do_action( 'emr_before_replace_type_options' ); ?>
|
148 |
|
149 |
|
150 |
+
<?php $enabled_search = apply_filters( 'emr_display_replace_type_options', true );
|
151 |
+
$search_disabled = (! $enabled_search) ? 'disabled' : '';
|
152 |
+
?>
|
153 |
+
<div class='option replace <?php echo $search_disabled ?>'>
|
154 |
+
<label for="replace_type_1" ><input CHECKED id="replace_type_1" type="radio" name="replace_type" value="replace" <?php echo $search_disabled ?> > <?php echo esc_html__("Just replace the file", "enable-media-replace"); ?>
|
155 |
+
</label>
|
156 |
|
157 |
+
<p class="howto">
|
158 |
+
<?php printf( esc_html__("Note: This option requires you to upload a file of the same type (%s) as the one you are replacing. The name of the attachment will stay the same (%s) no matter what the file you upload is called.", "enable-media-replace"), $filetype, $filename ); ?>
|
159 |
+
</p>
|
160 |
|
161 |
+
<?php do_action('emr_after_search_type_options'); ?>
|
162 |
+
</div>
|
163 |
+
|
164 |
+
<?php $enabled_replacesearch = apply_filters( 'emr_enable_replace_and_search', true );
|
165 |
+
$searchreplace_disabled = (! $enabled_replacesearch) ? 'disabled' : '';
|
166 |
+
?>
|
167 |
+
|
168 |
+
<div class="option searchreplace <?php echo $searchreplace_disabled ?>">
|
169 |
+
<label for="replace_type_2"><input id="replace_type_2" type="radio" name="replace_type" value="replace_and_search" <?php echo $searchreplace_disabled ?> > <?php echo __("Replace the file, use new file name and update all links", "enable-media-replace"); ?>
|
170 |
+
</label>
|
171 |
|
|
|
|
|
|
|
172 |
<p class="howto"><?php printf( esc_html__("Note: If you check this option, the name and type of the file you are about to upload will replace the old file. All links pointing to the current file (%s) will be updated to point to the new file name.", "enable-media-replace"), $filename ); ?></p>
|
173 |
+
|
174 |
+
<!-- <p class="howto"><?php echo esc_html__("Please note that if you upload a new image, only embeds/links of the original size image will be replaced in your posts.", "enable-media-replace"); ?></p> -->
|
175 |
+
|
176 |
+
<?php do_action('emr_after_replace_type_options'); ?>
|
177 |
+
</div>
|
178 |
+
|
|
|
|
|
|
|
179 |
</section>
|
180 |
<section class='options wrapper'>
|
181 |
<div class='section-header'> <?php _e('Date Options', 'enable-media-replace'); ?></div>
|
183 |
<?php
|
184 |
$attachment_current_date = date_i18n('d/M/Y H:i', strtotime($attachment->post_date) );
|
185 |
$time = current_time('mysql');
|
186 |
+
$date = new \dateTime($time);
|
187 |
?>
|
188 |
<p><?php _e('When replacing the media, do you want to:', 'enable-media-replace'); ?></p>
|
189 |
<ul>
|
199 |
|
200 |
@ <input type='text' name="custom_hour" class='emr_hour' value="<?php echo $date->format('H') ?>" />
|
201 |
<input type="text" name="custom_minute" class='emr_minute' value="<?php echo $date->format('i'); ?>" />
|
202 |
+
<input type="hidden" name="custom_date_formatted" value="<?php echo $date->format('Y-m-d'); ?>" />
|
203 |
</div>
|
204 |
</div>
|
205 |
</section>
|
210 |
</section>
|
211 |
</form>
|
212 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
views/upload.php
CHANGED
@@ -1,7 +1,12 @@
|
|
1 |
<?php
|
|
|
|
|
2 |
if ( ! defined( 'ABSPATH' ) )
|
3 |
exit; // Exit if accessed directly.
|
4 |
|
|
|
|
|
|
|
5 |
if (!current_user_can('upload_files'))
|
6 |
wp_die( esc_html__('You do not have permission to upload files.', 'enable-media-replace') );
|
7 |
|
@@ -22,6 +27,7 @@ $postmeta_table_name = $wpdb->prefix . "postmeta";
|
|
22 |
* @param string $current_file
|
23 |
* @param array|null $metadta
|
24 |
*/
|
|
|
25 |
function emr_delete_current_files( $current_file, $metadta = null ) {
|
26 |
// Delete old file
|
27 |
|
@@ -79,7 +85,7 @@ function emr_delete_current_files( $current_file, $metadta = null ) {
|
|
79 |
//$mask = $prefix . "-*x*" . $suffix;
|
80 |
//array_map( "unlink", glob( $mask ) );
|
81 |
}
|
82 |
-
}
|
83 |
|
84 |
/**
|
85 |
* Maybe remove query string from URL.
|
@@ -207,19 +213,13 @@ function emr_normalize_file_urls( $old, $new ) {
|
|
207 |
}
|
208 |
|
209 |
// Starts processing.
|
|
|
210 |
|
211 |
// Get old guid and filetype from DB
|
212 |
$post_id = intval($_POST['ID']); // sanitize, post_id.
|
213 |
-
|
214 |
$replacer = new replacer($post_id);
|
215 |
|
216 |
-
/*$sql = "SELECT post_mime_type FROM $table_name WHERE ID = '%d'";
|
217 |
-
$sql = $wpdb->prepare($sql, array($post_id) );
|
218 |
-
list($current_filetype) = $wpdb->get_row($sql, ARRAY_N); // seems unused as well.
|
219 |
-
*/
|
220 |
// Massage a bunch of vars
|
221 |
-
//$current_guid = wp_get_attachment_url($post_id); // this is used for search / replace
|
222 |
-
|
223 |
$ID = intval($_POST["ID"]); // legacy
|
224 |
$replace_type = isset($_POST["replace_type"]) ? sanitize_text_field($_POST["replace_type"]) : false;
|
225 |
$timestamp_replace = intval($_POST['timestamp_replace']);
|
@@ -230,6 +230,10 @@ $current_file = preg_replace("|(?<!:)/{2,}|", "/", $current_file); // @todo what
|
|
230 |
$current_filename = wp_basename($current_file);
|
231 |
$current_metadata = wp_get_attachment_metadata( $post_id );
|
232 |
|
|
|
|
|
|
|
|
|
233 |
switch($timestamp_replace)
|
234 |
{
|
235 |
case \EnableMediaReplace\Replacer::TIME_UPDATEALL:
|
@@ -238,17 +242,31 @@ switch($timestamp_replace)
|
|
238 |
break;
|
239 |
case \EnableMediaReplace\Replacer::TIME_CUSTOM:
|
240 |
$custom_date = $_POST['custom_date_formatted'];
|
241 |
-
$custom_hour = $_POST['custom_hour'];
|
242 |
-
$custom_minute = $_POST['custom_minute'];
|
243 |
|
244 |
// create a mysql time representation from what we have.
|
245 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
246 |
$datetime = $custom_date->format("Y-m-d H:i:s");
|
247 |
break;
|
248 |
}
|
249 |
|
250 |
-
|
251 |
-
|
252 |
// We have two types: replace / replace_and_search
|
253 |
if ($replace_type == 'replace')
|
254 |
{
|
@@ -261,22 +279,34 @@ elseif ( 'replace_and_search' == $replace_type && apply_filters( 'emr_enable_rep
|
|
261 |
|
262 |
$replacer->setTimeMode($timestamp_replace, $datetime);
|
263 |
|
264 |
-
|
265 |
-
|
266 |
if (is_uploaded_file($_FILES["userfile"]["tmp_name"])) {
|
267 |
|
|
|
|
|
268 |
// New method for validating that the uploaded file is allowed, using WP:s internal wp_check_filetype_and_ext() function.
|
269 |
$filedata = wp_check_filetype_and_ext($_FILES["userfile"]["tmp_name"], $_FILES["userfile"]["name"]);
|
270 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
271 |
if ($filedata["ext"] == "") {
|
272 |
-
|
273 |
-
|
|
|
|
|
274 |
}
|
275 |
|
276 |
// Here we have the uploaded file
|
277 |
|
278 |
-
|
279 |
-
|
280 |
|
281 |
$new_filename = $_FILES["userfile"]["name"];
|
282 |
//$new_filesize = $_FILES["userfile"]["size"]; // Seems not to be in use.
|
@@ -288,9 +318,15 @@ if (is_uploaded_file($_FILES["userfile"]["tmp_name"])) {
|
|
288 |
// Gather all functions that both options do.
|
289 |
do_action('wp_handle_replace', array('post_id' => $post_id));
|
290 |
|
291 |
-
|
292 |
-
|
293 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
294 |
|
295 |
$returnurl = admin_url("/post.php?post={$_POST["ID"]}&action=edit&message=1");
|
296 |
|
@@ -300,15 +336,17 @@ if (is_uploaded_file($_FILES["userfile"]["tmp_name"])) {
|
|
300 |
} else {
|
301 |
//TODO Better error handling when no file is selected.
|
302 |
//For now just go back to media management
|
303 |
-
|
|
|
|
|
|
|
|
|
304 |
}
|
305 |
|
306 |
-
|
307 |
-
$returnurl = str_replace("http:", "https:", $returnurl);
|
308 |
-
}
|
309 |
|
310 |
// Allow developers to override $returnurl
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
?>
|
1 |
<?php
|
2 |
+
namespace EnableMediaReplace;
|
3 |
+
|
4 |
if ( ! defined( 'ABSPATH' ) )
|
5 |
exit; // Exit if accessed directly.
|
6 |
|
7 |
+
use EnableMediaReplace\ShortPixelLogger\ShortPixelLogger as Log;
|
8 |
+
use EnableMediaReplace\Notices\NoticeController as Notices;
|
9 |
+
|
10 |
if (!current_user_can('upload_files'))
|
11 |
wp_die( esc_html__('You do not have permission to upload files.', 'enable-media-replace') );
|
12 |
|
27 |
* @param string $current_file
|
28 |
* @param array|null $metadta
|
29 |
*/
|
30 |
+
/* Phased-out, marked for delete.
|
31 |
function emr_delete_current_files( $current_file, $metadta = null ) {
|
32 |
// Delete old file
|
33 |
|
85 |
//$mask = $prefix . "-*x*" . $suffix;
|
86 |
//array_map( "unlink", glob( $mask ) );
|
87 |
}
|
88 |
+
} */
|
89 |
|
90 |
/**
|
91 |
* Maybe remove query string from URL.
|
213 |
}
|
214 |
|
215 |
// Starts processing.
|
216 |
+
$uihelper = new UIHelper();
|
217 |
|
218 |
// Get old guid and filetype from DB
|
219 |
$post_id = intval($_POST['ID']); // sanitize, post_id.
|
|
|
220 |
$replacer = new replacer($post_id);
|
221 |
|
|
|
|
|
|
|
|
|
222 |
// Massage a bunch of vars
|
|
|
|
|
223 |
$ID = intval($_POST["ID"]); // legacy
|
224 |
$replace_type = isset($_POST["replace_type"]) ? sanitize_text_field($_POST["replace_type"]) : false;
|
225 |
$timestamp_replace = intval($_POST['timestamp_replace']);
|
230 |
$current_filename = wp_basename($current_file);
|
231 |
$current_metadata = wp_get_attachment_metadata( $post_id );
|
232 |
|
233 |
+
|
234 |
+
$redirect_error = $uihelper->getFailedRedirect($post_id);
|
235 |
+
$redirect_success = $uihelper->getSuccesRedirect($post_id);
|
236 |
+
|
237 |
switch($timestamp_replace)
|
238 |
{
|
239 |
case \EnableMediaReplace\Replacer::TIME_UPDATEALL:
|
242 |
break;
|
243 |
case \EnableMediaReplace\Replacer::TIME_CUSTOM:
|
244 |
$custom_date = $_POST['custom_date_formatted'];
|
245 |
+
$custom_hour = str_pad($_POST['custom_hour'],2,0, STR_PAD_LEFT);
|
246 |
+
$custom_minute = str_pad($_POST['custom_minute'], 2, 0, STR_PAD_LEFT);
|
247 |
|
248 |
// create a mysql time representation from what we have.
|
249 |
+
Log::addDebug($_POST);
|
250 |
+
Log::addDebug('Custom Date - ' . $custom_date . ' ' . $custom_hour . ':' . $custom_minute );
|
251 |
+
$custom_date = \DateTime::createFromFormat('Y-m-d G:i', $custom_date . ' ' . $custom_hour . ':' . $custom_minute );
|
252 |
+
if ($custom_date === false)
|
253 |
+
{
|
254 |
+
|
255 |
+
wp_safe_redirect($redirect_error);
|
256 |
+
$errors = \DateTime::getLastErrors();
|
257 |
+
$error = '';
|
258 |
+
if (isset($errors['errors']))
|
259 |
+
{
|
260 |
+
$error = implode(',', $errors['errors']);
|
261 |
+
}
|
262 |
+
Notices::addError(sprintf(__('Invalid Custom Date. Please custom date values (%s)', 'enable-media-replace'), $error));
|
263 |
+
|
264 |
+
exit();
|
265 |
+
}
|
266 |
$datetime = $custom_date->format("Y-m-d H:i:s");
|
267 |
break;
|
268 |
}
|
269 |
|
|
|
|
|
270 |
// We have two types: replace / replace_and_search
|
271 |
if ($replace_type == 'replace')
|
272 |
{
|
279 |
|
280 |
$replacer->setTimeMode($timestamp_replace, $datetime);
|
281 |
|
282 |
+
/** Check if file is uploaded properly **/
|
|
|
283 |
if (is_uploaded_file($_FILES["userfile"]["tmp_name"])) {
|
284 |
|
285 |
+
Log::addDebug($_FILES['userfile']);
|
286 |
+
|
287 |
// New method for validating that the uploaded file is allowed, using WP:s internal wp_check_filetype_and_ext() function.
|
288 |
$filedata = wp_check_filetype_and_ext($_FILES["userfile"]["tmp_name"], $_FILES["userfile"]["name"]);
|
289 |
|
290 |
+
Log::addDebug('Data after check', $filedata);
|
291 |
+
if (isset($_FILES['userfile']['error']) && $_FILES['userfile']['error'] > 0)
|
292 |
+
{
|
293 |
+
$e = new RunTimeException('File Uploaded Failed');
|
294 |
+
Notices::addError($e->getMessage());
|
295 |
+
wp_safe_redirect($redirect_error);
|
296 |
+
exit();
|
297 |
+
}
|
298 |
+
|
299 |
if ($filedata["ext"] == "") {
|
300 |
+
|
301 |
+
Notices::addError(esc_html__("File type does not meet security guidelines. Try another.", 'enable-media-replace') );
|
302 |
+
wp_safe_redirect($redirect_error);
|
303 |
+
exit();
|
304 |
}
|
305 |
|
306 |
// Here we have the uploaded file
|
307 |
|
308 |
+
//$thumbUpdater = new ThumbnailUpdater($ID);
|
309 |
+
//$thumbUpdater->setOldMetadata($current_metadata);
|
310 |
|
311 |
$new_filename = $_FILES["userfile"]["name"];
|
312 |
//$new_filesize = $_FILES["userfile"]["size"]; // Seems not to be in use.
|
318 |
// Gather all functions that both options do.
|
319 |
do_action('wp_handle_replace', array('post_id' => $post_id));
|
320 |
|
321 |
+
try
|
322 |
+
{
|
323 |
+
$replacer->replaceWith($_FILES["userfile"]["tmp_name"], $new_filename);
|
324 |
+
}
|
325 |
+
catch(\RunTimeException $e)
|
326 |
+
{
|
327 |
+
Log::addError($e->getMessage());
|
328 |
+
exit($e->getMessage());
|
329 |
+
}
|
330 |
|
331 |
$returnurl = admin_url("/post.php?post={$_POST["ID"]}&action=edit&message=1");
|
332 |
|
336 |
} else {
|
337 |
//TODO Better error handling when no file is selected.
|
338 |
//For now just go back to media management
|
339 |
+
//$returnurl = admin_url("upload.php");
|
340 |
+
Log::addInfo('Failed. Redirecting - '. $redirect_error);
|
341 |
+
Notices::addError(__('File Upload seems to have failed. No files were returned by system','enable-media-replace'));
|
342 |
+
wp_safe_redirect($redirect_error);
|
343 |
+
exit();
|
344 |
}
|
345 |
|
346 |
+
Notices::addSuccess(__('File successfully replaced'));
|
|
|
|
|
347 |
|
348 |
// Allow developers to override $returnurl
|
349 |
+
//$returnurl = apply_filters('emr_returnurl', $returnurl);
|
350 |
+
wp_redirect($redirect_success);
|
351 |
+
exit();
|
352 |
?>
|