c1b76676 by Jeff Balicki

media replace

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