first commit
@@ -0,0 +1,280 @@
|
||||
.analyst-action-opt {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.analyst-modal {
|
||||
color: #000000;
|
||||
display: none;
|
||||
position: fixed;
|
||||
z-index: 1000;
|
||||
padding-top: 100px;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
background-color: rgb(0,0,0);
|
||||
background-color: rgba(0,0,0,0.4);
|
||||
}
|
||||
|
||||
.analyst-modal-content {
|
||||
font-family: Helvetica, serif;
|
||||
position: relative;
|
||||
background-color: #fefefe;
|
||||
margin: auto;
|
||||
padding: 35px 35px 20px;
|
||||
border: 1px solid #F2F2F2;
|
||||
width: 40%;
|
||||
box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19);
|
||||
-webkit-animation-name: analyst-animatetop;
|
||||
-webkit-animation-duration: 0.4s;
|
||||
animation-name: analyst-animatetop;
|
||||
animation-duration: 0.4s
|
||||
}
|
||||
|
||||
.analyst-btn-success {
|
||||
cursor: pointer;
|
||||
color: #ffffff;
|
||||
background-color: #00AF5E;
|
||||
border: none;
|
||||
width: 100%;
|
||||
font-size: 18px;
|
||||
padding: 8px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.analyst-btn-grey {
|
||||
cursor: pointer;
|
||||
color: #2D2D2D;
|
||||
background-color: #D8D8D8;
|
||||
border: none;
|
||||
width: 100%;
|
||||
font-size: 18px;
|
||||
padding: 8px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.analyst-btn-secondary-ghost {
|
||||
cursor: pointer;
|
||||
background: transparent;
|
||||
border: none;
|
||||
color: #898686;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.analyst-modal-def-top-padding {
|
||||
padding-top: 20px;
|
||||
}
|
||||
|
||||
.analyst-modal-header {
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/*INSTALL STYLES*/
|
||||
.analyst-install-footer {
|
||||
padding-top: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.analyst-install-image-block {
|
||||
width: 140px;
|
||||
}
|
||||
|
||||
.analyst-install-image-block img {
|
||||
width: inherit;
|
||||
}
|
||||
|
||||
.analyst-install-description-block {
|
||||
padding-left: 40px;
|
||||
padding-top: 5px
|
||||
}
|
||||
|
||||
.analyst-install-description-text {
|
||||
font-size: 16px;
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
.analyst-install-permissions-list {
|
||||
list-style: disc inside;
|
||||
}
|
||||
|
||||
.analyst-install-permissions-list li {
|
||||
padding-left: 15px;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.analyst-install-footer span {
|
||||
color: #8a8787;
|
||||
padding-right: 10px;
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
.analyst-install-footer span:not(:last-child) {
|
||||
border-right: 1px solid #8a8787;
|
||||
}
|
||||
|
||||
/*INSTALL STYLES*/
|
||||
|
||||
.reason-answer {
|
||||
padding: 7px;
|
||||
margin-left: 23px;
|
||||
border: 1px solid #F2F2F2;
|
||||
}
|
||||
|
||||
.analyst-link {
|
||||
color: #00AF5E;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.analyst-action-text {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.analyst-action-text:hover {
|
||||
color: #9d9a9a;
|
||||
}
|
||||
|
||||
.analyst-disable-modal-mask {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
opacity: 0.5;
|
||||
position: absolute;
|
||||
background: white;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.analyst-smile-image {
|
||||
vertical-align: middle;
|
||||
padding-bottom: 3px;
|
||||
width: 24px;
|
||||
}
|
||||
|
||||
#analyst-deactivation-reasons li {
|
||||
padding-bottom: 3px;
|
||||
font-size: 16px;
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
@-webkit-keyframes analyst-animatetop {
|
||||
from {top:-300px; opacity:0}
|
||||
to {top:0; opacity:1}
|
||||
}
|
||||
|
||||
@keyframes analyst-animatetop {
|
||||
from {top:-300px; opacity:0}
|
||||
to {top:0; opacity:1}
|
||||
}
|
||||
|
||||
.analyst-modal-close {
|
||||
color: #48036F;
|
||||
font-size: 28px;
|
||||
font-weight: bold;
|
||||
top: 12px;
|
||||
position: absolute;
|
||||
right: 15px;
|
||||
}
|
||||
|
||||
.analyst-modal-close:hover,
|
||||
.analyst-modal-close:focus {
|
||||
color: #000;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.analyst-modal-body {padding: 2px 16px;}
|
||||
|
||||
.analyst-modal-footer {
|
||||
padding: 6px 16px;
|
||||
background-color: #FFE773;
|
||||
color: white;
|
||||
}
|
||||
|
||||
#analyst-deactivate-modal .question-answer input, textarea {
|
||||
margin-top: 5px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.analyst-btn-primary {
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
display:inline-block;
|
||||
padding:0.7em 1.4em;
|
||||
margin:0 0.3em 0.3em 0;
|
||||
border-radius:0.15em;
|
||||
box-sizing: border-box;
|
||||
text-decoration:none;
|
||||
font-family:'Roboto',sans-serif;
|
||||
text-transform:uppercase;
|
||||
font-weight:400;
|
||||
color:#FFFFFF;
|
||||
background-color:#9F3ED5;
|
||||
box-shadow:inset 0 -0.6em 0 -0.35em rgba(0,0,0,0.17);
|
||||
text-align:center;
|
||||
position:relative;
|
||||
}
|
||||
|
||||
.analyst-btn-primary:disabled {
|
||||
background-color: #AD66D5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.analyst-btn-primary:active{
|
||||
top:0.1em;
|
||||
}
|
||||
@media all and (max-width:30em){
|
||||
.analyst-btn-primary {
|
||||
display:block;
|
||||
margin:0.4em auto;
|
||||
}
|
||||
}
|
||||
|
||||
.analyst-btn-secondary {
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
display:inline-block;
|
||||
padding:0.7em 1.4em;
|
||||
margin:0 0.3em 0.3em 0;
|
||||
border-radius:0.15em;
|
||||
box-sizing: border-box;
|
||||
text-decoration:none;
|
||||
font-family:'Roboto',sans-serif;
|
||||
text-transform:uppercase;
|
||||
font-weight:400;
|
||||
color:#FFFFFF;
|
||||
background-color:#6C8CD5;
|
||||
box-shadow:inset 0 -0.6em 0 -0.35em rgba(0,0,0,0.17);
|
||||
text-align:center;
|
||||
position:relative;
|
||||
}
|
||||
|
||||
.analyst-btn-secondary:disabled {
|
||||
background-color: #6C8CD5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.analyst-btn-secondary:active{
|
||||
top:0.1em;
|
||||
}
|
||||
@media all and (max-width:30em){
|
||||
.analyst-btn-secondary {
|
||||
display:block;
|
||||
margin:0.4em auto;
|
||||
}
|
||||
}
|
||||
|
||||
.analyst-notice {
|
||||
padding-right: 38px;
|
||||
position: relative;
|
||||
margin-bottom: 30px !important;
|
||||
}
|
||||
|
||||
.analyst-notice .analyst-plugin-name {
|
||||
background-color: #00000024;
|
||||
padding-left: 7px;
|
||||
padding-right: 7px;
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
border-radius: 0 0 5px 5px;
|
||||
}
|
||||
|
After Width: | Height: | Size: 6.5 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 3.0 KiB |
@@ -0,0 +1,2 @@
|
||||
<?php
|
||||
// Silence is golden.
|
||||
@@ -0,0 +1,33 @@
|
||||
(function ($) {
|
||||
$(document).on('click', '.analyst-notice-dismiss', function () {
|
||||
var id = $(this).attr('analyst-notice-id');
|
||||
var self = this;
|
||||
|
||||
$.post(ajaxurl, {
|
||||
action: 'analyst_notification_dismiss',
|
||||
id: id,
|
||||
nonce: analyst_opt_localize.nonce
|
||||
}).done(function () {
|
||||
$(self).parent().fadeOut()
|
||||
})
|
||||
})
|
||||
|
||||
var url = new URL(window.location.href)
|
||||
|
||||
if (url.searchParams.has('verify')) {
|
||||
var pluginId = url.searchParams.get('plugin_id')
|
||||
|
||||
$.ajax({
|
||||
url: ajaxurl,
|
||||
method: 'POST',
|
||||
data: {
|
||||
action: 'analyst_install_verified_' + pluginId,
|
||||
nonce: analyst_opt_localize.nonce
|
||||
},
|
||||
success: function () {
|
||||
// Refresh page without query params
|
||||
window.location.href = window.location.origin + window.location.pathname
|
||||
}
|
||||
})
|
||||
}
|
||||
})(jQuery)
|
||||
40
wp-content/plugins/copy-delete-posts/analyst/autoload.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/src/helpers.php';
|
||||
|
||||
require_once __DIR__ . '/src/Contracts/HttpClientContract.php';
|
||||
require_once __DIR__ . '/src/Contracts/RequestContract.php';
|
||||
require_once __DIR__ . '/src/Contracts/RequestorContract.php';
|
||||
require_once __DIR__ . '/src/Contracts/TrackerContract.php';
|
||||
require_once __DIR__ . '/src/Contracts/CacheContract.php';
|
||||
|
||||
require_once __DIR__ . '/src/Core/AbstractFactory.php';
|
||||
|
||||
require_once __DIR__ . '/src/Cache/DatabaseCache.php';
|
||||
|
||||
require_once __DIR__ . '/src/Account/Account.php';
|
||||
require_once __DIR__ . '/src/Account/AccountData.php';
|
||||
require_once __DIR__ . '/src/Account/AccountDataFactory.php';
|
||||
require_once __DIR__ . '/src/Contracts/AnalystContract.php';
|
||||
|
||||
require_once __DIR__ . '/src/Http/Requests/AbstractLoggerRequest.php';
|
||||
require_once __DIR__ . '/src/Http/Requests/ActivateRequest.php';
|
||||
require_once __DIR__ . '/src/Http/Requests/DeactivateRequest.php';
|
||||
require_once __DIR__ . '/src/Http/Requests/InstallRequest.php';
|
||||
require_once __DIR__ . '/src/Http/Requests/OptInRequest.php';
|
||||
require_once __DIR__ . '/src/Http/Requests/OptOutRequest.php';
|
||||
require_once __DIR__ . '/src/Http/Requests/UninstallRequest.php';
|
||||
|
||||
require_once __DIR__ . '/src/Http/CurlHttpClient.php';
|
||||
require_once __DIR__ . '/src/Http/DummyHttpClient.php';
|
||||
require_once __DIR__ . '/src/Http/WordPressHttpClient.php';
|
||||
|
||||
require_once __DIR__ . '/src/Notices/Notice.php';
|
||||
require_once __DIR__ . '/src/Notices/NoticeFactory.php';
|
||||
|
||||
require_once __DIR__ . '/src/Analyst.php';
|
||||
require_once __DIR__ . '/src/ApiRequestor.php';
|
||||
require_once __DIR__ . '/src/ApiResponse.php';
|
||||
require_once __DIR__ . '/src/Collector.php';
|
||||
require_once __DIR__ . '/src/Mutator.php';
|
||||
|
||||
2
wp-content/plugins/copy-delete-posts/analyst/index.php
Normal file
@@ -0,0 +1,2 @@
|
||||
<?php
|
||||
// Silence
|
||||
70
wp-content/plugins/copy-delete-posts/analyst/main.php
Normal file
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
require_once 'sdk_resolver.php';
|
||||
|
||||
/**
|
||||
* Initialize analyst "private"
|
||||
*
|
||||
* @param array $options
|
||||
*/
|
||||
if (!function_exists('___analyst_init')) {
|
||||
function ___analyst_init($options) {
|
||||
$capabilities = [
|
||||
'activate_plugins',
|
||||
'edit_plugins',
|
||||
'install_plugins',
|
||||
'update_plugins',
|
||||
'delete_plugins',
|
||||
'manage_network_plugins',
|
||||
'upload_plugins'
|
||||
];
|
||||
|
||||
// Allow if has any of above permissions
|
||||
$hasPerms = false;
|
||||
foreach ($capabilities as $i => $cap) {
|
||||
if (current_user_can($cap)) {
|
||||
$hasPerms = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($hasPerms == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Try resolve latest supported SDK
|
||||
// In case resolving is failed exit the execution
|
||||
try {
|
||||
analyst_resolve_sdk($options['base-dir']);
|
||||
} catch (Exception $exception) {
|
||||
// error_log('[ANALYST] Cannot resolve any supported SDK');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
global /** @var Analyst\Analyst $analyst */
|
||||
$analyst;
|
||||
|
||||
// Set global instance of analyst
|
||||
if (!$analyst) {
|
||||
$analyst = Analyst\Analyst::getInstance();
|
||||
}
|
||||
|
||||
$analyst->registerAccount(new Account\Account($options['client-id'], $options['client-secret'], $options['base-dir']));
|
||||
} catch (Exception $e) {
|
||||
// error_log('Analyst SDK receive an error: [' . $e->getMessage() . '] Please contact our support at support@analyst.com');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!function_exists('analyst_init')) {
|
||||
function analyst_init($__options) {
|
||||
if (did_action('init') > 0 && function_exists('current_user_can')) ___analyst_init($__options);
|
||||
else {
|
||||
add_action('init', function () use ($__options) {
|
||||
___analyst_init($__options);
|
||||
}, -1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
if (!function_exists('analyst_resolve_sdk')) {
|
||||
|
||||
/**
|
||||
* Resolve supported sdk versions and load latest supported one
|
||||
* also bootstrap sdk with autoloader
|
||||
*
|
||||
* @since 1.1.3
|
||||
*
|
||||
* @param null $thisPluginPath
|
||||
* @return void
|
||||
* @throws Exception
|
||||
*/
|
||||
function analyst_resolve_sdk($thisPluginPath = null) {
|
||||
static $loaded = false;
|
||||
|
||||
// Exit if we already resolved SDK
|
||||
if ($loaded) return;
|
||||
|
||||
$plugins = get_option('active_plugins');
|
||||
|
||||
if ($thisPluginPath) {
|
||||
array_push($plugins, plugin_basename($thisPluginPath));
|
||||
}
|
||||
|
||||
$pluginsFolder = WP_PLUGIN_DIR;
|
||||
|
||||
$possibleSDKs = array_map(function ($path) use ($pluginsFolder) {
|
||||
$sdkFolder = sprintf('%s/%s/analyst/', $pluginsFolder, dirname($path));
|
||||
|
||||
$sdkFolder = str_replace('\\', '/', $sdkFolder);
|
||||
|
||||
$versionPath = $sdkFolder . 'version.php';
|
||||
|
||||
if (file_exists($versionPath)) {
|
||||
return require $versionPath;
|
||||
}
|
||||
|
||||
return false;
|
||||
}, $plugins);
|
||||
|
||||
global $wp_version;
|
||||
|
||||
// Filter out plugins which has no SDK
|
||||
$SDKs = array_filter($possibleSDKs, function ($s) {return is_array($s);});
|
||||
|
||||
// Filter SDKs which is supported by PHP and WP
|
||||
$supported = array_values(array_filter($SDKs, function ($sdk) use($wp_version) {
|
||||
$phpSupported = version_compare(PHP_VERSION, $sdk['php']) >= 0;
|
||||
$wpSupported = version_compare($wp_version, $sdk['wp']) >= 0;
|
||||
|
||||
return $phpSupported && $wpSupported;
|
||||
}));
|
||||
|
||||
// Sort SDK by version in descending order
|
||||
uasort($supported, function ($x, $y) {
|
||||
return version_compare($y['sdk'], $x['sdk']);
|
||||
});
|
||||
|
||||
// Reset sorted values keys
|
||||
$supported = array_values($supported);
|
||||
|
||||
if (!isset($supported[0])) {
|
||||
throw new Exception('There is no SDK which is support current PHP version and WP version');
|
||||
}
|
||||
|
||||
// Autoload files for supported SDK
|
||||
$autoloaderPath = str_replace(
|
||||
'\\',
|
||||
'/',
|
||||
sprintf('%s/autoload.php', $supported[0]['path'])
|
||||
);
|
||||
|
||||
require_once $autoloaderPath;
|
||||
|
||||
$loaded = true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,629 @@
|
||||
<?php
|
||||
|
||||
namespace Account;
|
||||
|
||||
use Analyst\Analyst;
|
||||
use Analyst\ApiRequestor;
|
||||
use Analyst\Cache\DatabaseCache;
|
||||
use Analyst\Collector;
|
||||
use Analyst\Http\Requests\ActivateRequest;
|
||||
use Analyst\Http\Requests\DeactivateRequest;
|
||||
use Analyst\Http\Requests\InstallRequest;
|
||||
use Analyst\Http\Requests\OptInRequest;
|
||||
use Analyst\Http\Requests\OptOutRequest;
|
||||
use Analyst\Http\Requests\UninstallRequest;
|
||||
use Analyst\Notices\Notice;
|
||||
use Analyst\Notices\NoticeFactory;
|
||||
use Analyst\Contracts\TrackerContract;
|
||||
use Analyst\Contracts\RequestorContract;
|
||||
|
||||
/**
|
||||
* Class Account
|
||||
*
|
||||
* This is plugin's account object
|
||||
*/
|
||||
class Account implements TrackerContract
|
||||
{
|
||||
/**
|
||||
* Account id
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $id;
|
||||
|
||||
/**
|
||||
* Basename of plugin
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $path;
|
||||
|
||||
/**
|
||||
* Whether plugin is active or not
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $isInstalled = false;
|
||||
|
||||
/**
|
||||
* Is user sign in for data tracking
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $isOptedIn = false;
|
||||
|
||||
/**
|
||||
* Is user accepted permissions grant
|
||||
* for collection site data
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $isSigned = false;
|
||||
|
||||
/**
|
||||
* Is user ever resolved install modal window?
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $isInstallResolved = false;
|
||||
|
||||
/**
|
||||
* Public secret code
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $clientSecret;
|
||||
|
||||
/**
|
||||
* @var AccountData
|
||||
*/
|
||||
protected $data;
|
||||
|
||||
/**
|
||||
* Base plugin path
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $basePluginPath;
|
||||
|
||||
/**
|
||||
* @var RequestorContract
|
||||
*/
|
||||
protected $requestor;
|
||||
|
||||
/**
|
||||
* @var Collector
|
||||
*/
|
||||
protected $collector;
|
||||
|
||||
/**
|
||||
* Account constructor.
|
||||
* @param $id
|
||||
* @param $secret
|
||||
* @param $baseDir
|
||||
*/
|
||||
public function __construct($id, $secret, $baseDir)
|
||||
{
|
||||
$this->id = $id;
|
||||
$this->clientSecret = $secret;
|
||||
|
||||
$this->path = $baseDir;
|
||||
|
||||
$this->basePluginPath = plugin_basename($baseDir);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getPath()
|
||||
{
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
*/
|
||||
public function setPath($path)
|
||||
{
|
||||
$this->data->setPath($path);
|
||||
|
||||
$this->path = $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isOptedIn()
|
||||
{
|
||||
return $this->isOptedIn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $isOptedIn
|
||||
*/
|
||||
public function setIsOptedIn($isOptedIn)
|
||||
{
|
||||
$this->data->setIsOptedIn($isOptedIn);
|
||||
|
||||
$this->isOptedIn = $isOptedIn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether plugin is active
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isActive()
|
||||
{
|
||||
return is_plugin_active($this->path);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $id
|
||||
*/
|
||||
public function setId($id)
|
||||
{
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isInstalled()
|
||||
{
|
||||
return $this->isInstalled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $isInstalled
|
||||
*/
|
||||
public function setIsInstalled($isInstalled)
|
||||
{
|
||||
$this->data->setIsInstalled($isInstalled);
|
||||
|
||||
$this->isInstalled = $isInstalled;
|
||||
}
|
||||
|
||||
protected function verifyNonceAndPerms() {
|
||||
|
||||
$capabilities = [
|
||||
'activate_plugins',
|
||||
'edit_plugins',
|
||||
'install_plugins',
|
||||
'update_plugins',
|
||||
'delete_plugins',
|
||||
'manage_network_plugins',
|
||||
'upload_plugins'
|
||||
];
|
||||
|
||||
// Allow if has any of above permissions
|
||||
$hasPerms = false;
|
||||
foreach ($capabilities as $i => $cap) {
|
||||
if (current_user_can($cap)) {
|
||||
$hasPerms = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($hasPerms == false) {
|
||||
wp_send_json_error(['message' => 'no_permissions']);
|
||||
die;
|
||||
}
|
||||
|
||||
if (!isset($_POST['nonce']) || !wp_verify_nonce(sanitize_text_field($_POST['nonce']), 'analyst_opt_ajax_nonce')) {
|
||||
wp_send_json_error(['message' => 'invalid_nonce']);
|
||||
die;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Should register activation and deactivation
|
||||
* event hooks
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function registerHooks()
|
||||
{
|
||||
register_activation_hook($this->basePluginPath, [&$this, 'onActivePluginListener']);
|
||||
register_uninstall_hook($this->basePluginPath, ['Account\Account', 'onUninstallPluginListener']);
|
||||
|
||||
$this->addFilter('plugin_action_links', [&$this, 'onRenderActionLinksHook']);
|
||||
|
||||
$this->addAjax('analyst_opt_in', [&$this, 'onOptInListener']);
|
||||
$this->addAjax('analyst_opt_out', [&$this, 'onOptOutListener']);
|
||||
$this->addAjax('analyst_plugin_deactivate', [&$this, 'onDeactivatePluginListener']);
|
||||
$this->addAjax('analyst_install', [&$this, 'onInstallListener']);
|
||||
$this->addAjax('analyst_skip_install', [&$this, 'onSkipInstallListener']);
|
||||
$this->addAjax('analyst_install_verified', [&$this, 'onInstallVerifiedListener']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will fire when admin activates plugin
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function onActivePluginListener()
|
||||
{
|
||||
if (!$this->isInstallResolved()) {
|
||||
DatabaseCache::getInstance()->put('plugin_to_install', $this->id);
|
||||
}
|
||||
|
||||
if (!$this->isAllowingLogging()) return;
|
||||
|
||||
ActivateRequest::make($this->collector, $this->id, $this->path)
|
||||
->execute($this->requestor);
|
||||
|
||||
$this->setIsInstalled(true);
|
||||
|
||||
AccountDataFactory::syncData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Will fire when admin deactivates plugin
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function onDeactivatePluginListener()
|
||||
{
|
||||
$this->verifyNonceAndPerms();
|
||||
|
||||
if (!$this->isAllowingLogging()) return;
|
||||
|
||||
$question = isset($_POST['question']) ? sanitize_text_field(stripslashes($_POST['question'])) : null;
|
||||
$reason = isset($_POST['reason']) ? sanitize_text_field(stripslashes($_POST['reason'])) : null;
|
||||
|
||||
DeactivateRequest::make($this->collector, $this->id, $this->path, $question, $reason)
|
||||
->execute($this->requestor);
|
||||
|
||||
$this->setIsInstalled(false);
|
||||
|
||||
AccountDataFactory::syncData();
|
||||
|
||||
wp_send_json_success();
|
||||
}
|
||||
|
||||
/**
|
||||
* Will fire when user opted in
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function onOptInListener()
|
||||
{
|
||||
$this->verifyNonceAndPerms();
|
||||
|
||||
OptInRequest::make($this->collector, $this->id, $this->path)->execute($this->requestor);
|
||||
|
||||
$this->setIsOptedIn(true);
|
||||
|
||||
AccountDataFactory::syncData();
|
||||
|
||||
wp_die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Will fire when user opted out
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function onOptOutListener()
|
||||
{
|
||||
$this->verifyNonceAndPerms();
|
||||
|
||||
OptOutRequest::make($this->collector, $this->id, $this->path)->execute($this->requestor);
|
||||
|
||||
$this->setIsOptedIn(false);
|
||||
|
||||
AccountDataFactory::syncData();
|
||||
|
||||
wp_send_json_success();
|
||||
}
|
||||
|
||||
/**
|
||||
* Will fire when user accept opt-in
|
||||
* at first time
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function onInstallListener()
|
||||
{
|
||||
$this->verifyNonceAndPerms();
|
||||
|
||||
$cache = DatabaseCache::getInstance();
|
||||
|
||||
// Set flag to true which indicates that install is resolved
|
||||
// also remove install plugin id from cache
|
||||
$this->setIsInstallResolved(true);
|
||||
$cache->delete('plugin_to_install');
|
||||
|
||||
InstallRequest::make($this->collector, $this->id, $this->path)->execute($this->requestor);
|
||||
|
||||
$this->setIsSigned(true);
|
||||
|
||||
$this->setIsOptedIn(true);
|
||||
|
||||
$factory = NoticeFactory::instance();
|
||||
|
||||
$message = sprintf('Please confirm your email by clicking on the link we sent to %s. This makes sure you’re not a bot.', $this->collector->getGeneralEmailAddress());
|
||||
|
||||
$notificationId = uniqid();
|
||||
|
||||
$notice = Notice::make(
|
||||
$notificationId,
|
||||
$this->getId(),
|
||||
$message,
|
||||
$this->collector->getPluginName($this->path)
|
||||
);
|
||||
|
||||
$factory->addNotice($notice);
|
||||
|
||||
AccountDataFactory::syncData();
|
||||
|
||||
// Set email confirmation notification id to cache
|
||||
// se we can extract and remove it when user confirmed email
|
||||
$cache->put(
|
||||
sprintf('account_email_confirmation_%s', $this->getId()),
|
||||
$notificationId
|
||||
);
|
||||
|
||||
wp_send_json_success();
|
||||
}
|
||||
|
||||
/**
|
||||
* Will fire when user skipped installation
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function onSkipInstallListener()
|
||||
{
|
||||
$this->verifyNonceAndPerms();
|
||||
|
||||
// Set flag to true which indicates that install is resolved
|
||||
// also remove install plugin id from cache
|
||||
$this->setIsInstallResolved(true);
|
||||
DatabaseCache::getInstance()->delete('plugin_to_install');
|
||||
}
|
||||
|
||||
/**
|
||||
* Will fire when user delete plugin through admin panel.
|
||||
* This action will happen if admin at least once
|
||||
* activated the plugin.
|
||||
*
|
||||
* @return void
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function onUninstallPluginListener()
|
||||
{
|
||||
$factory = AccountDataFactory::instance();
|
||||
|
||||
$pluginFile = substr(current_filter(), strlen( 'uninstall_' ));
|
||||
|
||||
$account = $factory->getAccountDataByBasePath($pluginFile);
|
||||
|
||||
// If account somehow is not found, exit the execution
|
||||
if (!$account) return;
|
||||
|
||||
$analyst = Analyst::getInstance();
|
||||
|
||||
$collector = new Collector($analyst);
|
||||
|
||||
$requestor = new ApiRequestor($account->getId(), $account->getSecret(), $analyst->getApiBase());
|
||||
|
||||
// Just send request to log uninstall event not caring about response
|
||||
UninstallRequest::make($collector, $account->getId(), $account->getPath())->execute($requestor);
|
||||
|
||||
$factory->sync();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires when used verified his account
|
||||
*/
|
||||
public function onInstallVerifiedListener()
|
||||
{
|
||||
$this->verifyNonceAndPerms();
|
||||
|
||||
$factory = NoticeFactory::instance();
|
||||
|
||||
$notice = Notice::make(
|
||||
uniqid(),
|
||||
$this->getId(),
|
||||
'Thank you for confirming your email.',
|
||||
$this->collector->getPluginName($this->path)
|
||||
);
|
||||
|
||||
$factory->addNotice($notice);
|
||||
|
||||
// Remove confirmation notification
|
||||
$confirmationNotificationId = DatabaseCache::getInstance()->pop(sprintf('account_email_confirmation_%s', $this->getId()));
|
||||
$factory->remove($confirmationNotificationId);
|
||||
|
||||
AccountDataFactory::syncData();
|
||||
|
||||
wp_send_json_success();
|
||||
}
|
||||
|
||||
/**
|
||||
* Will fire when wp renders plugin
|
||||
* action buttons
|
||||
*
|
||||
* @param $defaultLinks
|
||||
* @return array
|
||||
*/
|
||||
public function onRenderActionLinksHook($defaultLinks)
|
||||
{
|
||||
$customLinks = [];
|
||||
|
||||
$customLinks[] = $this->isOptedIn()
|
||||
? '<a class="analyst-action-opt analyst-opt-out" analyst-plugin-id="' . $this->getId() . '" analyst-plugin-signed="' . (int) $this->isSigned() . '">Opt Out</a>'
|
||||
: '<a class="analyst-action-opt analyst-opt-in" analyst-plugin-id="' . $this->getId() . '" analyst-plugin-signed="' . (int) $this->isSigned() . '">Opt In</a>';
|
||||
|
||||
// Append anchor to find specific deactivation link
|
||||
if (isset($defaultLinks['deactivate'])) {
|
||||
$defaultLinks['deactivate'] .= '<span analyst-plugin-id="' . $this->getId() . '" analyst-plugin-opted-in="' . (int) $this->isOptedIn() . '"></span>';
|
||||
}
|
||||
|
||||
return array_merge($customLinks, $defaultLinks);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AccountData
|
||||
*/
|
||||
public function getData()
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AccountData $data
|
||||
*/
|
||||
public function setData(AccountData $data)
|
||||
{
|
||||
$this->data = $data;
|
||||
|
||||
$this->setIsOptedIn($data->isOptedIn());
|
||||
$this->setIsInstalled($data->isInstalled());
|
||||
$this->setIsSigned($data->isSigned());
|
||||
$this->setIsInstallResolved($data->isInstallResolved());
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves valid action name
|
||||
* based on client id
|
||||
*
|
||||
* @param $action
|
||||
* @return string
|
||||
*/
|
||||
private function resolveActionName($action)
|
||||
{
|
||||
return sprintf('%s_%s', $action, $this->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register action for current plugin
|
||||
*
|
||||
* @param $action
|
||||
* @param $callback
|
||||
*/
|
||||
private function addFilter($action, $callback)
|
||||
{
|
||||
$validAction = sprintf('%s_%s', $action, $this->basePluginPath);
|
||||
|
||||
add_filter($validAction, $callback, 10);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add ajax action for current plugin
|
||||
*
|
||||
* @param $action
|
||||
* @param $callback
|
||||
* @param bool $raw Format action ??
|
||||
*/
|
||||
private function addAjax($action, $callback, $raw = false)
|
||||
{
|
||||
$validAction = $raw ? $action : sprintf('%s%s', 'wp_ajax_', $this->resolveActionName($action));
|
||||
|
||||
add_action($validAction, $callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isSigned()
|
||||
{
|
||||
return $this->isSigned;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $isSigned
|
||||
*/
|
||||
public function setIsSigned($isSigned)
|
||||
{
|
||||
$this->data->setIsSigned($isSigned);
|
||||
|
||||
$this->isSigned = $isSigned;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return RequestorContract
|
||||
*/
|
||||
public function getRequestor()
|
||||
{
|
||||
return $this->requestor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param RequestorContract $requestor
|
||||
*/
|
||||
public function setRequestor(RequestorContract $requestor)
|
||||
{
|
||||
$this->requestor = $requestor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getClientSecret()
|
||||
{
|
||||
return $this->clientSecret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collector
|
||||
*/
|
||||
public function getCollector()
|
||||
{
|
||||
return $this->collector;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collector $collector
|
||||
*/
|
||||
public function setCollector(Collector $collector)
|
||||
{
|
||||
$this->collector = $collector;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do we allowing logging
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isAllowingLogging()
|
||||
{
|
||||
return $this->isOptedIn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getBasePluginPath()
|
||||
{
|
||||
return $this->basePluginPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isInstallResolved()
|
||||
{
|
||||
return $this->isInstallResolved;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $isInstallResolved
|
||||
*/
|
||||
public function setIsInstallResolved($isInstallResolved)
|
||||
{
|
||||
$this->data->setIsInstallResolved($isInstallResolved);
|
||||
|
||||
$this->isInstallResolved = $isInstallResolved;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
<?php
|
||||
|
||||
namespace Account;
|
||||
|
||||
/**
|
||||
* Class AccountData is the data holder
|
||||
* for Analyst\Account\Account class
|
||||
* which is unserialized from database
|
||||
*/
|
||||
class AccountData
|
||||
{
|
||||
/**
|
||||
* Account id
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $id;
|
||||
|
||||
/**
|
||||
* Account secret key
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $secret;
|
||||
|
||||
/**
|
||||
* Basename of plugin
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $path;
|
||||
|
||||
/**
|
||||
* Whether admin accepted opt in
|
||||
* terms and permissions
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $isInstalled = false;
|
||||
|
||||
/**
|
||||
* Is user sign in for data tracking
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $isOptedIn = false;
|
||||
|
||||
/**
|
||||
* Is user accepted permissions grant
|
||||
* for collection site data
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $isSigned = false;
|
||||
|
||||
/**
|
||||
* Is user ever resolved install modal window?
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $isInstallResolved;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $id
|
||||
*/
|
||||
public function setId($id)
|
||||
{
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @return AccountData
|
||||
*/
|
||||
public function setPath($path)
|
||||
{
|
||||
$this->path = $path;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isInstalled()
|
||||
{
|
||||
return $this->isInstalled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $isInstalled
|
||||
*/
|
||||
public function setIsInstalled($isInstalled)
|
||||
{
|
||||
$this->isInstalled = $isInstalled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isOptedIn()
|
||||
{
|
||||
return $this->isOptedIn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $isOptedIn
|
||||
*/
|
||||
public function setIsOptedIn($isOptedIn)
|
||||
{
|
||||
$this->isOptedIn = $isOptedIn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isSigned()
|
||||
{
|
||||
return $this->isSigned;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $isSigned
|
||||
*/
|
||||
public function setIsSigned($isSigned)
|
||||
{
|
||||
$this->isSigned = $isSigned;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getPath()
|
||||
{
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getSecret()
|
||||
{
|
||||
return $this->secret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $secret
|
||||
*/
|
||||
public function setSecret($secret)
|
||||
{
|
||||
$this->secret = $secret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isInstallResolved()
|
||||
{
|
||||
return $this->isInstallResolved;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $isInstallResolved
|
||||
*/
|
||||
public function setIsInstallResolved($isInstallResolved)
|
||||
{
|
||||
$this->isInstallResolved = $isInstallResolved;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
<?php
|
||||
|
||||
namespace Account;
|
||||
|
||||
|
||||
use Analyst\Core\AbstractFactory;
|
||||
|
||||
/**
|
||||
* Class AccountDataFactory
|
||||
*
|
||||
* Holds information about this
|
||||
* wordpress project plugins accounts
|
||||
*
|
||||
*/
|
||||
class AccountDataFactory extends AbstractFactory
|
||||
{
|
||||
private static $instance;
|
||||
|
||||
CONST OPTIONS_KEY = 'analyst_accounts_data';
|
||||
|
||||
/**
|
||||
* @var AccountData[]
|
||||
*/
|
||||
protected $accounts = [];
|
||||
|
||||
/**
|
||||
* Read factory from options or make fresh instance
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public static function instance()
|
||||
{
|
||||
if (!static::$instance) {
|
||||
$raw = get_option(self::OPTIONS_KEY);
|
||||
|
||||
// In case object is already unserialized
|
||||
// and instance of AccountDataFactory we
|
||||
// return it, in other case deal with
|
||||
// serialized string data
|
||||
if ($raw instanceof self) {
|
||||
static::$instance = $raw;
|
||||
} else {
|
||||
static::$instance = is_string($raw) ? static::unserialize($raw) : new self();
|
||||
}
|
||||
}
|
||||
|
||||
return static::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sync this object data with cache
|
||||
*/
|
||||
public function sync()
|
||||
{
|
||||
update_option(self::OPTIONS_KEY, serialize($this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sync this instance data with cache
|
||||
*/
|
||||
public static function syncData()
|
||||
{
|
||||
static::instance()->sync();
|
||||
}
|
||||
|
||||
/**
|
||||
* Find plugin account data or create fresh one
|
||||
*
|
||||
* @param Account $account
|
||||
* @return AccountData|null
|
||||
*/
|
||||
public function resolvePluginAccountData(Account $account)
|
||||
{
|
||||
$accountData = $this->findAccountDataById($account->getId());
|
||||
|
||||
if (!$accountData) {
|
||||
$accountData = new AccountData();
|
||||
|
||||
// Set proper default values
|
||||
$accountData->setPath($account->getPath());
|
||||
$accountData->setId($account->getId());
|
||||
$accountData->setSecret($account->getClientSecret());
|
||||
|
||||
array_push($this->accounts, $accountData);
|
||||
}
|
||||
|
||||
return $accountData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should return account data by base path
|
||||
*
|
||||
* @param $basePath
|
||||
* @return AccountData
|
||||
*/
|
||||
public function getAccountDataByBasePath($basePath)
|
||||
{
|
||||
foreach ($this->accounts as $iterable) {
|
||||
$iterableBasePath = plugin_basename($iterable->getPath());
|
||||
|
||||
if ($iterableBasePath === $basePath) {
|
||||
return $iterable;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return account by id
|
||||
*
|
||||
* @param $id
|
||||
* @return AccountData|null
|
||||
*/
|
||||
private function findAccountDataById($id)
|
||||
{
|
||||
foreach ($this->accounts as &$iterable) {
|
||||
if ($iterable->getId() === $id) {
|
||||
return $iterable;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
167
wp-content/plugins/copy-delete-posts/analyst/src/Analyst.php
Normal file
@@ -0,0 +1,167 @@
|
||||
<?php
|
||||
namespace Analyst;
|
||||
|
||||
use Account\Account;
|
||||
use Account\AccountDataFactory;
|
||||
use Analyst\Contracts\AnalystContract;
|
||||
use Analyst\Contracts\RequestorContract;
|
||||
|
||||
class Analyst implements AnalystContract
|
||||
{
|
||||
/**
|
||||
* All plugin's accounts
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $accounts = array();
|
||||
|
||||
/**
|
||||
* @var Mutator
|
||||
*/
|
||||
protected $mutator;
|
||||
|
||||
/**
|
||||
* @var AccountDataFactory
|
||||
*/
|
||||
protected $accountDataFactory;
|
||||
|
||||
/**
|
||||
* Base url to api
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $apiBase = 'https://feedback.sellcodes.com/api/v1';
|
||||
|
||||
/**
|
||||
* @var Collector
|
||||
*/
|
||||
protected $collector;
|
||||
|
||||
/**
|
||||
* Singleton instance
|
||||
*
|
||||
* @var static
|
||||
*/
|
||||
protected static $instance;
|
||||
|
||||
/**
|
||||
* Get instance of analyst
|
||||
*
|
||||
* @return Analyst
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function getInstance()
|
||||
{
|
||||
if (!static::$instance) {
|
||||
static::$instance = new Analyst();
|
||||
}
|
||||
|
||||
return static::$instance;
|
||||
}
|
||||
|
||||
protected function __construct()
|
||||
{
|
||||
$this->mutator = new Mutator();
|
||||
|
||||
$this->accountDataFactory = AccountDataFactory::instance();
|
||||
|
||||
$this->mutator->initialize();
|
||||
|
||||
$this->collector = new Collector($this);
|
||||
|
||||
$this->initialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize rest of application
|
||||
*/
|
||||
public function initialize()
|
||||
{
|
||||
add_action('init', function () {
|
||||
$this->collector->loadCurrentUser();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Register new account
|
||||
*
|
||||
* @param Account $account
|
||||
* @return Analyst
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function registerAccount($account)
|
||||
{
|
||||
// Stop propagation when account is already registered
|
||||
if ($this->isAccountRegistered($account)) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
// Resolve account data from factory
|
||||
$accountData = $this->accountDataFactory->resolvePluginAccountData($account);
|
||||
|
||||
$account->setData($accountData);
|
||||
|
||||
$account->setRequestor(
|
||||
$this->resolveRequestorForAccount($account)
|
||||
);
|
||||
|
||||
$account->setCollector($this->collector);
|
||||
|
||||
$account->registerHooks();
|
||||
|
||||
$this->accounts[$account->getId()] = $account;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Must return version of analyst
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function version()
|
||||
{
|
||||
$version = require __DIR__ . '/../version.php';
|
||||
|
||||
return $version['sdk'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this account registered
|
||||
*
|
||||
* @param Account $account
|
||||
* @return bool
|
||||
*/
|
||||
protected function isAccountRegistered($account)
|
||||
{
|
||||
return isset($this->accounts[$account->getId()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves requestor for account
|
||||
*
|
||||
* @param Account $account
|
||||
* @return RequestorContract
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function resolveRequestorForAccount(Account $account)
|
||||
{
|
||||
$requestor = new ApiRequestor($account->getId(), $account->getClientSecret(), $this->apiBase);
|
||||
|
||||
// Set SDK version
|
||||
$requestor->setDefaultHeader(
|
||||
'x-analyst-client-user-agent',
|
||||
sprintf('Analyst/%s', $this->version())
|
||||
);
|
||||
|
||||
return $requestor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getApiBase()
|
||||
{
|
||||
return $this->apiBase;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,257 @@
|
||||
<?php
|
||||
|
||||
namespace Analyst;
|
||||
|
||||
use Exception;
|
||||
use Analyst\Contracts\HttpClientContract;
|
||||
use Analyst\Contracts\RequestorContract;
|
||||
|
||||
class ApiRequestor implements RequestorContract
|
||||
{
|
||||
/**
|
||||
* Supported http client
|
||||
*
|
||||
* @var HttpClientContract
|
||||
*/
|
||||
protected $httpClient;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $clientId;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $clientSecret;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $apiBase;
|
||||
|
||||
/**
|
||||
* Default headers to be sent
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $defaultHeaders = [
|
||||
'accept' => 'application/json',
|
||||
'content-type' => 'application/json'
|
||||
];
|
||||
|
||||
/**
|
||||
* Prioritized http clients
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $availableClients = [
|
||||
'Analyst\Http\WordPressHttpClient',
|
||||
'Analyst\Http\CurlHttpClient',
|
||||
'Analyst\Http\DummyHttpClient',
|
||||
];
|
||||
|
||||
/**
|
||||
* ApiRequestor constructor.
|
||||
* @param $id
|
||||
* @param $secret
|
||||
* @param $apiBase
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function __construct($id, $secret, $apiBase)
|
||||
{
|
||||
$this->clientId = $id;
|
||||
$this->clientSecret = $secret;
|
||||
|
||||
$this->setApiBase($apiBase);
|
||||
|
||||
$this->httpClient = $this->resolveHttpClient();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set api base url
|
||||
*
|
||||
* @param $url
|
||||
*/
|
||||
public function setApiBase($url)
|
||||
{
|
||||
$this->apiBase = $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get request
|
||||
*
|
||||
* @param $url
|
||||
* @param array $headers
|
||||
* @return mixed
|
||||
*/
|
||||
public function get($url, $headers = [])
|
||||
{
|
||||
return $this->request('GET', $url, null, $headers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Post request
|
||||
*
|
||||
* @param $url
|
||||
* @param $body
|
||||
* @param array $headers
|
||||
* @return mixed
|
||||
*/
|
||||
public function post($url, $body = [], $headers = [])
|
||||
{
|
||||
return $this->request('POST', $url, $body, $headers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Put request
|
||||
*
|
||||
* @param $url
|
||||
* @param $body
|
||||
* @param array $headers
|
||||
* @return mixed
|
||||
*/
|
||||
public function put($url, $body = [], $headers = [])
|
||||
{
|
||||
return $this->request('PUT', $url, $body, $headers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete request
|
||||
*
|
||||
* @param $url
|
||||
* @param array $headers
|
||||
* @return mixed
|
||||
*/
|
||||
public function delete($url, $headers = [])
|
||||
{
|
||||
return $this->request('DELETE', $url, null, $headers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make request to api
|
||||
*
|
||||
* @param $method
|
||||
* @param $url
|
||||
* @param array $body
|
||||
* @param array $headers
|
||||
* @return mixed
|
||||
*/
|
||||
protected function request($method, $url, $body = [], $headers = [])
|
||||
{
|
||||
$fullUrl = $this->resolveFullUrl($url);
|
||||
|
||||
$date = date('r', time());
|
||||
|
||||
$headers['date'] = $date;
|
||||
$headers['signature'] = $this->resolveSignature($this->clientSecret, $method, $fullUrl, $body, $date);
|
||||
|
||||
// Lowercase header names
|
||||
$headers = $this->prepareHeaders(
|
||||
array_merge($headers, $this->defaultHeaders)
|
||||
);
|
||||
|
||||
$response = $this->httpClient->request($method, $fullUrl, $body, $headers);
|
||||
|
||||
// TODO: Check response code and take actions
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set one default header
|
||||
*
|
||||
* @param $header
|
||||
* @param $value
|
||||
*/
|
||||
public function setDefaultHeader($header, $value)
|
||||
{
|
||||
$this->defaultHeaders[
|
||||
$this->resolveValidHeaderName($header)
|
||||
] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves supported http client
|
||||
*
|
||||
* @return HttpClientContract
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function resolveHttpClient()
|
||||
{
|
||||
$clients = array_filter($this->availableClients, $this->guessClientSupportEnvironment());
|
||||
|
||||
if (!isset($clients[0])) {
|
||||
throw new Exception('There is no http client which this application can support');
|
||||
}
|
||||
|
||||
// Instantiate first supported http client
|
||||
return new $clients[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* This will filter out clients which is not supported
|
||||
* by the current environment
|
||||
*
|
||||
* @return \Closure
|
||||
*/
|
||||
protected function guessClientSupportEnvironment()
|
||||
{
|
||||
return function ($client) {
|
||||
return forward_static_call([$client, 'hasSupport']);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves valid header name
|
||||
*
|
||||
* @param $headerName
|
||||
* @return string
|
||||
*/
|
||||
private function resolveValidHeaderName($headerName)
|
||||
{
|
||||
return strtolower($headerName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lowercase header names
|
||||
*
|
||||
* @param $headers
|
||||
* @return array
|
||||
*/
|
||||
private function prepareHeaders($headers)
|
||||
{
|
||||
return array_change_key_case($headers, CASE_LOWER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sign request
|
||||
*
|
||||
* @param $key
|
||||
* @param $method
|
||||
* @param $url
|
||||
* @param $body
|
||||
* @param $date
|
||||
*
|
||||
* @return false|string
|
||||
*/
|
||||
private function resolveSignature($key, $method, $url, $body, $date)
|
||||
{
|
||||
$string = implode('\n', [$method, $url, md5(json_encode($body)), $date]);
|
||||
|
||||
$contentSecret = hash_hmac('sha256', $string, $key);
|
||||
|
||||
return sprintf('%s:%s', $this->clientId, $contentSecret);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compose full url
|
||||
*
|
||||
* @param $url
|
||||
* @return string
|
||||
*/
|
||||
private function resolveFullUrl($url)
|
||||
{
|
||||
return sprintf('%s/%s', $this->apiBase, trim($url, '/'));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace Analyst;
|
||||
|
||||
class ApiResponse
|
||||
{
|
||||
/**
|
||||
* Response headers
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $headers;
|
||||
|
||||
/**
|
||||
* Response body
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
public $body;
|
||||
|
||||
/**
|
||||
* Status code
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $code;
|
||||
|
||||
public function __construct($body, $code, $headers)
|
||||
{
|
||||
$this->body = $body;
|
||||
$this->code = $code;
|
||||
$this->headers = $headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether status code is successful
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isSuccess()
|
||||
{
|
||||
return $this->code >= 200 && $this->code < 300;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
<?php
|
||||
|
||||
namespace Analyst\Cache;
|
||||
|
||||
use Analyst\Contracts\CacheContract;
|
||||
|
||||
/**
|
||||
* Class DatabaseCache
|
||||
*
|
||||
* @since 1.1.5
|
||||
*/
|
||||
class DatabaseCache implements CacheContract
|
||||
{
|
||||
const OPTION_KEY = 'analyst_cache';
|
||||
|
||||
protected static $instance;
|
||||
|
||||
/**
|
||||
* Get instance of db cache
|
||||
*
|
||||
* @return DatabaseCache
|
||||
*/
|
||||
public static function getInstance()
|
||||
{
|
||||
if (!self::$instance) {
|
||||
self::$instance = new DatabaseCache();
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Key value pair
|
||||
*
|
||||
* @var array[]
|
||||
*/
|
||||
protected $values = [];
|
||||
|
||||
/**
|
||||
* DatabaseCache constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$raw = get_option(self::OPTION_KEY, serialize([]));
|
||||
|
||||
// Raw data may be an array already
|
||||
$this->values = is_array($raw) ? $raw : @unserialize($raw);
|
||||
|
||||
// In case serialization is failed
|
||||
// make sure values is an array
|
||||
if (!is_array($this->values)) {
|
||||
$this->values = [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save value with given key
|
||||
*
|
||||
* @param string $key
|
||||
* @param string $value
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function put($key, $value)
|
||||
{
|
||||
$this->values[$key] = $value;
|
||||
|
||||
$this->sync();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get value by given key
|
||||
*
|
||||
* @param $key
|
||||
*
|
||||
* @param null $default
|
||||
* @return string
|
||||
*/
|
||||
public function get($key, $default = null)
|
||||
{
|
||||
$value = isset($this->values[$key]) ? $this->values[$key] : $default;
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $key
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function delete($key)
|
||||
{
|
||||
if (isset($this->values[$key])) {
|
||||
unset($this->values[$key]);
|
||||
|
||||
$this->sync();
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update cache in DB
|
||||
*/
|
||||
protected function sync()
|
||||
{
|
||||
update_option(self::OPTION_KEY, serialize($this->values));
|
||||
}
|
||||
|
||||
/**
|
||||
* Should get value and remove it from cache
|
||||
*
|
||||
* @param $key
|
||||
* @param null $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function pop($key, $default = null)
|
||||
{
|
||||
$value = $this->get($key);
|
||||
|
||||
$this->delete($key);
|
||||
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
221
wp-content/plugins/copy-delete-posts/analyst/src/Collector.php
Normal file
@@ -0,0 +1,221 @@
|
||||
<?php
|
||||
|
||||
namespace Analyst;
|
||||
|
||||
use Analyst\Contracts\AnalystContract;
|
||||
|
||||
/**
|
||||
* Class Collector is a set of getters
|
||||
* to retrieve some data from wp site
|
||||
*/
|
||||
class Collector
|
||||
{
|
||||
/**
|
||||
* @var AnalystContract
|
||||
*/
|
||||
protected $sdk;
|
||||
|
||||
/**
|
||||
* @var \WP_User
|
||||
*/
|
||||
protected $user;
|
||||
|
||||
public function __construct(AnalystContract $sdk)
|
||||
{
|
||||
$this->sdk = $sdk;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load current user into memory
|
||||
*/
|
||||
public function loadCurrentUser()
|
||||
{
|
||||
$this->user = wp_get_current_user();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get site url
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSiteUrl()
|
||||
{
|
||||
return get_option('siteurl');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current user email
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getCurrentUserEmail()
|
||||
{
|
||||
return $this->user->user_email;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get's email from general settings
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getGeneralEmailAddress()
|
||||
{
|
||||
return get_option('admin_email');
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this user administrator
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isUserAdministrator()
|
||||
{
|
||||
return in_array('administrator', $this->user->roles);
|
||||
}
|
||||
|
||||
/**
|
||||
* User name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getCurrentUserName()
|
||||
{
|
||||
return $this->user ? $this->user->user_nicename : 'unknown';
|
||||
}
|
||||
|
||||
/**
|
||||
* WP version
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getWordPressVersion()
|
||||
{
|
||||
global $wp_version;
|
||||
|
||||
return $wp_version;
|
||||
}
|
||||
|
||||
/**
|
||||
* PHP version
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPHPVersion()
|
||||
{
|
||||
return phpversion();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves plugin information
|
||||
*
|
||||
* @param string $path Absolute path to plugin
|
||||
* @return array
|
||||
*/
|
||||
public function resolvePluginData($path)
|
||||
{
|
||||
if( !function_exists('get_plugin_data') ){
|
||||
require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
|
||||
}
|
||||
|
||||
return get_plugin_data($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get plugin name by path
|
||||
*
|
||||
* @param $path
|
||||
* @return string
|
||||
*/
|
||||
public function getPluginName($path)
|
||||
{
|
||||
$data = $this->resolvePluginData($path);
|
||||
|
||||
return $data['Name'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get plugin version
|
||||
*
|
||||
* @param $path
|
||||
* @return string
|
||||
*/
|
||||
public function getPluginVersion($path)
|
||||
{
|
||||
$data = $this->resolvePluginData($path);
|
||||
|
||||
return $data['Version'] ? $data['Version'] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get server ip
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getServerIp()
|
||||
{
|
||||
return sanitize_text_field($_SERVER['SERVER_ADDR']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getSDKVersion()
|
||||
{
|
||||
return $this->sdk->version();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getMysqlVersion()
|
||||
{
|
||||
$conn = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
|
||||
|
||||
if ($conn) {
|
||||
$version = mysqli_get_server_info($conn);
|
||||
} else {
|
||||
return 'unknown';
|
||||
}
|
||||
|
||||
return $version ? $version : 'unknown';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getSiteLanguage()
|
||||
{
|
||||
return get_locale();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Current WP theme
|
||||
*
|
||||
* @return false|string
|
||||
*/
|
||||
public function getCurrentThemeName()
|
||||
{
|
||||
return wp_get_theme()->get('Name');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get active plugins list
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getActivePluginsList()
|
||||
{
|
||||
if (!function_exists('get_plugins')) {
|
||||
require_once ABSPATH . 'wp-admin/includes/plugin.php';
|
||||
}
|
||||
|
||||
$allPlugins = get_plugins();
|
||||
|
||||
$activePluginsNames = array_map(function ($path) use ($allPlugins) {
|
||||
return $allPlugins[$path]['Name'];
|
||||
}, get_option('active_plugins'));
|
||||
|
||||
return $activePluginsNames;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
namespace Analyst\Contracts;
|
||||
|
||||
interface AnalystContract
|
||||
{
|
||||
/**
|
||||
* Must return version of analyst
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function version();
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace Analyst\Contracts;
|
||||
|
||||
/**
|
||||
* Interface CacheContract
|
||||
*
|
||||
* @since 1.1.5
|
||||
*/
|
||||
interface CacheContract
|
||||
{
|
||||
/**
|
||||
* Save value with given key
|
||||
*
|
||||
* @param string $key
|
||||
* @param string $value
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function put($key, $value);
|
||||
|
||||
/**
|
||||
* Get value by given key
|
||||
*
|
||||
* @param $key
|
||||
*
|
||||
* @param null $default
|
||||
* @return string
|
||||
*/
|
||||
public function get($key, $default = null);
|
||||
|
||||
/**
|
||||
* @param $key
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function delete($key);
|
||||
|
||||
/**
|
||||
* Should get value and remove it from cache
|
||||
*
|
||||
* @param $key
|
||||
* @param null $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function pop($key, $default = null);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
namespace Analyst\Contracts;
|
||||
|
||||
use Analyst\ApiResponse;
|
||||
|
||||
interface HttpClientContract
|
||||
{
|
||||
/**
|
||||
* Make an http request
|
||||
*
|
||||
* @param $method
|
||||
* @param $url
|
||||
* @param $body
|
||||
* @param $headers
|
||||
* @return ApiResponse
|
||||
*/
|
||||
public function request($method, $url, $body, $headers);
|
||||
|
||||
/**
|
||||
* Must return `true` if client is supported
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function hasSupport();
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace Analyst\Contracts;
|
||||
|
||||
use Analyst\ApiResponse;
|
||||
|
||||
interface RequestContract
|
||||
{
|
||||
/**
|
||||
* Cast request data to array
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray();
|
||||
|
||||
/**
|
||||
* Execute the request
|
||||
* @param RequestorContract $requestor
|
||||
* @return ApiResponse
|
||||
*/
|
||||
public function execute(RequestorContract $requestor);
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace Analyst\Contracts;
|
||||
|
||||
interface RequestorContract
|
||||
{
|
||||
/**
|
||||
* Get request
|
||||
*
|
||||
* @param $url
|
||||
* @param array $headers
|
||||
* @return mixed
|
||||
*/
|
||||
public function get($url, $headers = []);
|
||||
|
||||
/**
|
||||
* Post request
|
||||
*
|
||||
* @param $url
|
||||
* @param $body
|
||||
* @param array $headers
|
||||
* @return mixed
|
||||
*/
|
||||
public function post($url, $body = [], $headers = []);
|
||||
|
||||
/**
|
||||
* Put request
|
||||
*
|
||||
* @param $url
|
||||
* @param $body
|
||||
* @param array $headers
|
||||
* @return mixed
|
||||
*/
|
||||
public function put($url, $body = [], $headers = []);
|
||||
|
||||
/**
|
||||
* Delete request
|
||||
*
|
||||
* @param $url
|
||||
* @param array $headers
|
||||
* @return mixed
|
||||
*/
|
||||
public function delete($url, $headers = []);
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
namespace Analyst\Contracts;
|
||||
|
||||
interface TrackerContract
|
||||
{
|
||||
/**
|
||||
* Should register activation and deactivation
|
||||
* event hooks
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function registerHooks();
|
||||
|
||||
/**
|
||||
* Will fire when admin activates plugin
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function onActivePluginListener();
|
||||
|
||||
/**
|
||||
* Will fire when admin deactivates plugin
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function onDeactivatePluginListener();
|
||||
|
||||
/**
|
||||
* Will fire when user opted in
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function onOptInListener();
|
||||
|
||||
/**
|
||||
* Will fire when user opted out
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function onOptOutListener();
|
||||
|
||||
/**
|
||||
* Will fire when user accept opt/in at first time
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function onInstallListener();
|
||||
|
||||
/**
|
||||
* Will fire when user skipped installation
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function onSkipInstallListener();
|
||||
|
||||
/**
|
||||
* Will fire when user delete plugin through admin panel.
|
||||
* This action will happen if admin at least once
|
||||
* activated the plugin.
|
||||
*
|
||||
* The register_uninstall_hook function accepts only static
|
||||
* function or global function to be executed, so this is
|
||||
* why this method is static
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function onUninstallPluginListener();
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace Analyst\Core;
|
||||
|
||||
abstract class AbstractFactory
|
||||
{
|
||||
/**
|
||||
* Unserialize to static::class instance
|
||||
*
|
||||
* @param $raw
|
||||
* @return static
|
||||
*/
|
||||
protected static function unserialize($raw)
|
||||
{
|
||||
$instance = maybe_unserialize($raw);
|
||||
|
||||
$isProperObject = is_object($instance) && $instance instanceof static;
|
||||
|
||||
// In case for some reason unserialized object is not
|
||||
// static::class we make sure it is static::class
|
||||
if (!$isProperObject) {
|
||||
$instance = new static();
|
||||
}
|
||||
|
||||
return $instance;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
namespace Analyst\Http;
|
||||
|
||||
use Analyst\ApiResponse;
|
||||
use Analyst\Contracts\HttpClientContract;
|
||||
|
||||
class CurlHttpClient implements HttpClientContract
|
||||
{
|
||||
/**
|
||||
* Make an http request
|
||||
*
|
||||
* @param $method
|
||||
* @param $url
|
||||
* @param array $body
|
||||
* @param $headers
|
||||
* @return mixed
|
||||
*/
|
||||
public function request($method, $url, $body, $headers)
|
||||
{
|
||||
$method = strtoupper($method);
|
||||
|
||||
$options = [
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_URL => $url,
|
||||
CURLOPT_HTTPHEADER => $this->prepareRequestHeaders($headers),
|
||||
CURLOPT_CUSTOMREQUEST => $method,
|
||||
CURLOPT_FAILONERROR => true,
|
||||
CURLOPT_HEADER => true,
|
||||
CURLOPT_TIMEOUT => 30,
|
||||
];
|
||||
|
||||
if ($method === 'POST') {
|
||||
$options[CURLOPT_POST] = 1;
|
||||
$options[CURLOPT_POSTFIELDS] = json_encode($body);
|
||||
}
|
||||
|
||||
$curl = curl_init();
|
||||
|
||||
curl_setopt_array($curl, $options);
|
||||
|
||||
$response = curl_exec($curl);
|
||||
|
||||
list($rawHeaders, $rawBody) = explode("\r\n\r\n", $response, 2);
|
||||
|
||||
$info = curl_getinfo($curl);
|
||||
|
||||
curl_close($curl);
|
||||
|
||||
$responseHeaders = $this->resolveResponseHeaders($rawHeaders);
|
||||
$responseBody = json_decode($rawBody, true);
|
||||
|
||||
return new ApiResponse($responseBody, $info['http_code'], $responseHeaders);
|
||||
}
|
||||
|
||||
/**
|
||||
* Must return `true` if client is supported
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function hasSupport()
|
||||
{
|
||||
return function_exists('curl_version');
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify request headers from key value pair
|
||||
* to vector array
|
||||
*
|
||||
* @param array $headers
|
||||
* @return array
|
||||
*/
|
||||
protected function prepareRequestHeaders ($headers)
|
||||
{
|
||||
return array_map(function ($key, $value) {
|
||||
return sprintf('%s:%s', $key, $value);
|
||||
}, array_keys($headers), $headers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve raw response headers as
|
||||
* associative array
|
||||
*
|
||||
* @param $rawHeaders
|
||||
* @return array
|
||||
*/
|
||||
private function resolveResponseHeaders($rawHeaders)
|
||||
{
|
||||
$headers = [];
|
||||
|
||||
foreach (explode("\r\n", $rawHeaders) as $i => $line) {
|
||||
$parts = explode(': ', $line);
|
||||
|
||||
if (count($parts) === 1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$headers[$parts[0]] = $parts[1];
|
||||
}
|
||||
return $headers;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace Analyst\Http;
|
||||
|
||||
use Analyst\ApiResponse;
|
||||
use Analyst\Contracts\HttpClientContract;
|
||||
|
||||
class DummyHttpClient implements HttpClientContract
|
||||
{
|
||||
/**
|
||||
* Make an http request
|
||||
*
|
||||
* @param $method
|
||||
* @param $url
|
||||
* @param $body
|
||||
* @param $headers
|
||||
* @return ApiResponse
|
||||
*/
|
||||
public function request($method, $url, $body, $headers)
|
||||
{
|
||||
return new ApiResponse('Dummy response', 200, []);
|
||||
}
|
||||
|
||||
/**
|
||||
* Must return `true` if client is supported
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function hasSupport()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace Analyst\Http\Requests;
|
||||
|
||||
use Analyst\ApiResponse;
|
||||
use Analyst\Collector;
|
||||
use Analyst\Contracts\RequestContract;
|
||||
use Analyst\Contracts\RequestorContract;
|
||||
|
||||
abstract class AbstractLoggerRequest implements RequestContract
|
||||
{
|
||||
/**
|
||||
* @var Collector
|
||||
*/
|
||||
protected $collector;
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
*/
|
||||
protected $id;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $path;
|
||||
|
||||
public function __construct(Collector $collector, $pluginId, $path)
|
||||
{
|
||||
$this->collector = $collector;
|
||||
$this->id = $pluginId;
|
||||
$this->path = $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cast request data to array
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
return [
|
||||
'plugin_id' => $this->id,
|
||||
'php_version' => $this->collector->getPHPVersion(),
|
||||
'wp_version' => $this->collector->getWordPressVersion(),
|
||||
'plugin_version' => $this->collector->getPluginVersion($this->path),
|
||||
'url' => $this->collector->getSiteUrl(),
|
||||
'sdk_version' => $this->collector->getSDKVersion(),
|
||||
'ip' => $this->collector->getServerIp(),
|
||||
'mysql_version' => $this->collector->getMysqlVersion(),
|
||||
'locale' => $this->collector->getSiteLanguage(),
|
||||
'current_theme' => $this->collector->getCurrentThemeName(),
|
||||
'active_plugins_list' => implode(', ', $this->collector->getActivePluginsList()),
|
||||
'email' => $this->collector->getGeneralEmailAddress(),
|
||||
'name' => $this->collector->getCurrentUserName()
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the request
|
||||
* @param RequestorContract $requestor
|
||||
* @return ApiResponse
|
||||
*/
|
||||
public abstract function execute(RequestorContract $requestor);
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace Analyst\Http\Requests;
|
||||
|
||||
use Analyst\ApiResponse;
|
||||
use Analyst\Collector;
|
||||
use Analyst\Contracts\RequestContract;
|
||||
use Analyst\Contracts\RequestorContract;
|
||||
|
||||
/**
|
||||
* Class ActivateRequest
|
||||
*
|
||||
* Is is very similar to install request
|
||||
* but with different path
|
||||
*
|
||||
* @since 0.9.12
|
||||
*/
|
||||
class ActivateRequest extends AbstractLoggerRequest
|
||||
{
|
||||
/**
|
||||
* Execute the request
|
||||
* @param RequestorContract $requestor
|
||||
* @return ApiResponse
|
||||
*/
|
||||
public function execute(RequestorContract $requestor)
|
||||
{
|
||||
return $requestor->post('logger/activate', $this->toArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Make request instance
|
||||
*
|
||||
* @param Collector $collector
|
||||
* @param $pluginId
|
||||
* @param $path
|
||||
* @return static
|
||||
*/
|
||||
public static function make(Collector $collector, $pluginId, $path)
|
||||
{
|
||||
return new static($collector, $pluginId, $path);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace Analyst\Http\Requests;
|
||||
|
||||
use Analyst\ApiResponse;
|
||||
use Analyst\Collector;
|
||||
use Analyst\Contracts\RequestorContract;
|
||||
|
||||
/**
|
||||
* Class DeactivateRequest
|
||||
*
|
||||
* @since 0.9.10
|
||||
*/
|
||||
class DeactivateRequest extends AbstractLoggerRequest
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $question;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $answer;
|
||||
|
||||
/**
|
||||
* @param Collector $collector
|
||||
* @param $pluginId
|
||||
* @param $path
|
||||
* @param $question
|
||||
* @param $answer
|
||||
* @return static
|
||||
*/
|
||||
public static function make(Collector $collector, $pluginId, $path, $question, $answer)
|
||||
{
|
||||
return new static($collector, $pluginId, $path, $question, $answer);
|
||||
}
|
||||
|
||||
public function __construct(Collector $collector, $pluginId, $path, $question, $answer)
|
||||
{
|
||||
parent::__construct($collector, $pluginId, $path);
|
||||
|
||||
$this->question = $question;
|
||||
$this->answer = $answer;
|
||||
}
|
||||
|
||||
public function toArray()
|
||||
{
|
||||
return array_merge(parent::toArray(), [
|
||||
'question' => $this->question,
|
||||
'answer' => $this->answer,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the request
|
||||
* @param RequestorContract $requestor
|
||||
* @return ApiResponse
|
||||
*/
|
||||
public function execute(RequestorContract $requestor)
|
||||
{
|
||||
return $requestor->post('logger/deactivate', $this->toArray());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace Analyst\Http\Requests;
|
||||
|
||||
use Analyst\ApiResponse;
|
||||
use Analyst\Collector;
|
||||
use Analyst\Contracts\RequestorContract;
|
||||
|
||||
/**
|
||||
* Class InstallRequest
|
||||
*
|
||||
* @since 0.9.4
|
||||
*/
|
||||
class InstallRequest extends AbstractLoggerRequest
|
||||
{
|
||||
/**
|
||||
* Execute the request
|
||||
* @param RequestorContract $requestor
|
||||
* @return ApiResponse
|
||||
*/
|
||||
public function execute(RequestorContract $requestor)
|
||||
{
|
||||
return $requestor->post('logger/install', $this->toArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Make request instance
|
||||
*
|
||||
* @param Collector $collector
|
||||
* @param $pluginId
|
||||
* @param $path
|
||||
* @return static
|
||||
*/
|
||||
public static function make(Collector $collector, $pluginId, $path)
|
||||
{
|
||||
return new static($collector, $pluginId, $path);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace Analyst\Http\Requests;
|
||||
|
||||
use Analyst\ApiResponse;
|
||||
use Analyst\Collector;
|
||||
use Analyst\Contracts\RequestContract;
|
||||
use Analyst\Contracts\RequestorContract;
|
||||
|
||||
/**
|
||||
* Class OptInRequest
|
||||
*
|
||||
* Is is very similar to install request
|
||||
* but with different path
|
||||
*
|
||||
* @since 0.9.5
|
||||
*/
|
||||
class OptInRequest extends AbstractLoggerRequest
|
||||
{
|
||||
/**
|
||||
* Execute the request
|
||||
* @param RequestorContract $requestor
|
||||
* @return ApiResponse
|
||||
*/
|
||||
public function execute(RequestorContract $requestor)
|
||||
{
|
||||
return $requestor->post('logger/opt-in', $this->toArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Make request instance
|
||||
*
|
||||
* @param Collector $collector
|
||||
* @param $pluginId
|
||||
* @param $path
|
||||
* @return static
|
||||
*/
|
||||
public static function make(Collector $collector, $pluginId, $path)
|
||||
{
|
||||
return new static($collector, $pluginId, $path);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace Analyst\Http\Requests;
|
||||
|
||||
use Analyst\ApiResponse;
|
||||
use Analyst\Collector;
|
||||
use Analyst\Contracts\RequestContract;
|
||||
use Analyst\Contracts\RequestorContract;
|
||||
|
||||
/**
|
||||
* Class OptOutRequest
|
||||
*
|
||||
* Is is very similar to install request
|
||||
* but with different path
|
||||
*
|
||||
* @since 0.9.9
|
||||
*/
|
||||
class OptOutRequest extends AbstractLoggerRequest
|
||||
{
|
||||
/**
|
||||
* @param Collector $collector
|
||||
* @param $pluginId
|
||||
* @param $path
|
||||
* @return static
|
||||
*/
|
||||
public static function make(Collector $collector, $pluginId, $path)
|
||||
{
|
||||
return new static($collector, $pluginId, $path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the request
|
||||
* @param RequestorContract $requestor
|
||||
* @return ApiResponse
|
||||
*/
|
||||
public function execute(RequestorContract $requestor)
|
||||
{
|
||||
return $requestor->post('logger/opt-out', $this->toArray());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace Analyst\Http\Requests;
|
||||
|
||||
use Analyst\ApiResponse;
|
||||
use Analyst\Collector;
|
||||
use Analyst\Contracts\RequestorContract;
|
||||
|
||||
/**
|
||||
* Class DeactivateRequest
|
||||
*
|
||||
* @since 0.9.13
|
||||
*/
|
||||
class UninstallRequest extends AbstractLoggerRequest
|
||||
{
|
||||
/**
|
||||
* @param Collector $collector
|
||||
* @param $pluginId
|
||||
* @param $path
|
||||
* @return static
|
||||
*/
|
||||
public static function make(Collector $collector, $pluginId, $path)
|
||||
{
|
||||
return new static($collector, $pluginId, $path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the request
|
||||
* @param RequestorContract $requestor
|
||||
* @return ApiResponse
|
||||
*/
|
||||
public function execute(RequestorContract $requestor)
|
||||
{
|
||||
return $requestor->post('logger/uninstall', $this->toArray());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
namespace Analyst\Http;
|
||||
|
||||
use WP_Error;
|
||||
use Analyst\ApiResponse;
|
||||
use Analyst\Contracts\HttpClientContract;
|
||||
use Requests_Utility_CaseInsensitiveDictionary;
|
||||
|
||||
class WordPressHttpClient implements HttpClientContract
|
||||
{
|
||||
/**
|
||||
* Make an http request
|
||||
*
|
||||
* @param $method
|
||||
* @param $url
|
||||
* @param $body
|
||||
* @param $headers
|
||||
* @return ApiResponse
|
||||
*/
|
||||
public function request($method, $url, $body, $headers)
|
||||
{
|
||||
$options = [
|
||||
'body' => json_encode($body),
|
||||
'headers' => $headers,
|
||||
'method' => $method,
|
||||
'timeout' => 30,
|
||||
];
|
||||
|
||||
$response = wp_remote_request($url, $options);
|
||||
|
||||
$body = [];
|
||||
$responseHeaders = [];
|
||||
|
||||
if ($response instanceof WP_Error) {
|
||||
$code = $response->get_error_code();
|
||||
} else {
|
||||
/** @var Requests_Utility_CaseInsensitiveDictionary $headers */
|
||||
$responseHeaders = $response['headers']->getAll();
|
||||
$body = json_decode($response['body'], true);
|
||||
$code = $response['response']['code'];
|
||||
}
|
||||
|
||||
|
||||
return new ApiResponse(
|
||||
$body,
|
||||
$code,
|
||||
$responseHeaders
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Must return `true` if client is supported
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function hasSupport()
|
||||
{
|
||||
return function_exists('wp_remote_request');
|
||||
}
|
||||
}
|
||||
135
wp-content/plugins/copy-delete-posts/analyst/src/Mutator.php
Normal file
@@ -0,0 +1,135 @@
|
||||
<?php
|
||||
|
||||
namespace Analyst;
|
||||
|
||||
use Analyst\Cache\DatabaseCache;
|
||||
use Analyst\Contracts\CacheContract;
|
||||
use Analyst\Notices\NoticeFactory;
|
||||
|
||||
/**
|
||||
* Class Mutator mutates (modifies) UX with additional
|
||||
* functional
|
||||
*/
|
||||
class Mutator
|
||||
{
|
||||
protected $notices = [];
|
||||
|
||||
/**
|
||||
* @var NoticeFactory
|
||||
*/
|
||||
protected $factory;
|
||||
|
||||
/**
|
||||
* @var CacheContract
|
||||
*/
|
||||
protected $cache;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->factory = NoticeFactory::instance();
|
||||
|
||||
$this->notices = $this->factory->getNotices();
|
||||
|
||||
$this->cache = DatabaseCache::getInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register filters all necessary stuff.
|
||||
* Can be invoked only once.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function initialize()
|
||||
{
|
||||
$this->registerLinks();
|
||||
$this->registerAssets();
|
||||
$this->registerHooks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register all necessary filters and templates
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function registerLinks()
|
||||
{
|
||||
add_action('admin_footer', function () {
|
||||
analyst_require_template('optout.php', [
|
||||
'shieldImage' => analyst_assets_url('img/shield_question.png')
|
||||
]);
|
||||
|
||||
analyst_require_template('optin.php');
|
||||
|
||||
analyst_require_template('forms/deactivate.php', [
|
||||
'pencilImage' => analyst_assets_url('img/pencil.png'),
|
||||
'smileImage' => analyst_assets_url('img/smile.png'),
|
||||
]);
|
||||
|
||||
analyst_require_template('forms/install.php', [
|
||||
'pluginToInstall' => $this->cache->get('plugin_to_install'),
|
||||
'shieldImage' => analyst_assets_url('img/shield_success.png'),
|
||||
]);
|
||||
});
|
||||
|
||||
add_action('admin_notices',function () {
|
||||
foreach ($this->notices as $notice) {
|
||||
analyst_require_template('notice.php', ['notice' => $notice]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Register all assets
|
||||
*/
|
||||
public function registerAssets()
|
||||
{
|
||||
add_action('admin_enqueue_scripts', function () {
|
||||
wp_enqueue_style('analyst_custom', analyst_assets_url('/css/customize.css'));
|
||||
wp_enqueue_script('analyst_custom', analyst_assets_url('/js/customize.js'));
|
||||
wp_localize_script('analyst_custom', 'analyst_opt_localize', array(
|
||||
'nonce' => wp_create_nonce('analyst_opt_ajax_nonce')
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Register action hooks
|
||||
*/
|
||||
public function registerHooks()
|
||||
{
|
||||
add_action('wp_ajax_analyst_notification_dismiss', function () {
|
||||
$capabilities = [
|
||||
'activate_plugins',
|
||||
'edit_plugins',
|
||||
'install_plugins',
|
||||
'update_plugins',
|
||||
'delete_plugins',
|
||||
'manage_network_plugins',
|
||||
'upload_plugins'
|
||||
];
|
||||
|
||||
// Allow if has any of above permissions
|
||||
$hasPerms = false;
|
||||
foreach ($capabilities as $i => $cap) {
|
||||
if (current_user_can($cap)) {
|
||||
$hasPerms = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($hasPerms == false) {
|
||||
wp_send_json_error(['message' => 'no_permissions']);
|
||||
die;
|
||||
}
|
||||
|
||||
if (!isset($_POST['nonce']) || !wp_verify_nonce(sanitize_text_field($_POST['nonce']), 'analyst_opt_ajax_nonce')) {
|
||||
wp_send_json_error(['message' => 'invalid_nonce']);
|
||||
die;
|
||||
}
|
||||
|
||||
$this->factory->remove(sanitize_text_field($_POST['id']));
|
||||
|
||||
$this->factory->sync();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
<?php
|
||||
|
||||
namespace Analyst\Notices;
|
||||
|
||||
class Notice
|
||||
{
|
||||
/**
|
||||
* Id of notice
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $id;
|
||||
|
||||
/**
|
||||
* Body of notice
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $body;
|
||||
|
||||
/**
|
||||
* Account id
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $accountId;
|
||||
|
||||
/**
|
||||
* The plugin name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $pluginName;
|
||||
|
||||
/**
|
||||
* New notice
|
||||
*
|
||||
* @param $id
|
||||
* @param $accountId
|
||||
* @param $body
|
||||
* @param null $pluginName
|
||||
*
|
||||
* @return Notice
|
||||
*/
|
||||
public static function make($id, $accountId, $body, $pluginName = null)
|
||||
{
|
||||
return new Notice($id, $accountId, $body, $pluginName);
|
||||
}
|
||||
|
||||
public function __construct($id, $accountId, $body, $pluginName)
|
||||
{
|
||||
$this->setId($id);
|
||||
$this->setBody($body);
|
||||
$this->setAccountId($accountId);
|
||||
$this->setPluginName($pluginName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $id
|
||||
*/
|
||||
public function setId($id)
|
||||
{
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getBody()
|
||||
{
|
||||
return $this->body;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $body
|
||||
*/
|
||||
public function setBody($body)
|
||||
{
|
||||
$this->body = $body;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getAccountId()
|
||||
{
|
||||
return $this->accountId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $accountId
|
||||
*/
|
||||
public function setAccountId($accountId)
|
||||
{
|
||||
$this->accountId = $accountId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function getPluginName()
|
||||
{
|
||||
return $this->pluginName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $pluginName
|
||||
*/
|
||||
public function setPluginName($pluginName)
|
||||
{
|
||||
$this->pluginName = $pluginName;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
<?php
|
||||
|
||||
namespace Analyst\Notices;
|
||||
|
||||
use Analyst\Core\AbstractFactory;
|
||||
|
||||
class NoticeFactory extends AbstractFactory
|
||||
{
|
||||
private static $instance;
|
||||
|
||||
CONST OPTIONS_KEY = 'analyst_notices';
|
||||
|
||||
/**
|
||||
* Application notifications
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $notices = [];
|
||||
|
||||
/**
|
||||
* Read factory from options or make fresh instance
|
||||
*
|
||||
* @return NoticeFactory
|
||||
*/
|
||||
public static function instance()
|
||||
{
|
||||
if (!static::$instance) {
|
||||
$raw = get_option(self::OPTIONS_KEY);
|
||||
|
||||
// In case object is already unserialized
|
||||
// and instance of AccountDataFactory we
|
||||
// return it, in other case deal with
|
||||
// serialized string data
|
||||
if ($raw instanceof self) {
|
||||
static::$instance = $raw;
|
||||
} else {
|
||||
static::$instance = is_string($raw) ? static::unserialize($raw) : new self();
|
||||
}
|
||||
}
|
||||
|
||||
return static::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sync this object data with cache
|
||||
*/
|
||||
public function sync()
|
||||
{
|
||||
update_option(self::OPTIONS_KEY, serialize($this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sync this instance data with cache
|
||||
*/
|
||||
public static function syncData()
|
||||
{
|
||||
static::instance()->sync();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getNotices()
|
||||
{
|
||||
return $this->notices;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter out notices for certain account
|
||||
*
|
||||
* @param $accountId
|
||||
* @return array
|
||||
*/
|
||||
public function getNoticesForAccount($accountId)
|
||||
{
|
||||
return array_filter($this->notices, function (Notice $notice) use ($accountId) {
|
||||
return $notice->getAccountId() === $accountId;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new notice
|
||||
*
|
||||
* @param $notice
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addNotice($notice)
|
||||
{
|
||||
array_push($this->notices, $notice);
|
||||
|
||||
$this->sync();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find notice by id
|
||||
*
|
||||
* @param $id
|
||||
* @return Notice|null
|
||||
*/
|
||||
public function find($id)
|
||||
{
|
||||
$notices = array_filter($this->notices, function (Notice $notice) use ($id) {
|
||||
return $notice->getId() === $id;
|
||||
});
|
||||
|
||||
return array_pop($notices);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove notice by it's id
|
||||
*
|
||||
* @param $id
|
||||
*/
|
||||
public function remove($id)
|
||||
{
|
||||
// Get key of notice to remove
|
||||
$key = array_search(
|
||||
$this->find($id),
|
||||
$this->notices
|
||||
);
|
||||
|
||||
// Unset notice with key
|
||||
unset($this->notices[$key]);
|
||||
|
||||
$this->sync();
|
||||
}
|
||||
}
|
||||
73
wp-content/plugins/copy-delete-posts/analyst/src/helpers.php
Normal file
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
if (! function_exists('analyst_assets_path')) {
|
||||
/**
|
||||
* Generates path to file in assets folder
|
||||
*
|
||||
* @param $file
|
||||
* @return string
|
||||
*/
|
||||
function analyst_assets_path($file)
|
||||
{
|
||||
$path = sprintf('%s/assets/%s', realpath(__DIR__ . '/..'), trim($file, '/'));
|
||||
|
||||
return wp_normalize_path($path);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (! function_exists('analyst_assets_url')) {
|
||||
/**
|
||||
* Generates url to file in assets folder
|
||||
*
|
||||
* @param $file
|
||||
* @return string
|
||||
*/
|
||||
function analyst_assets_url($file)
|
||||
{
|
||||
$absolutePath = analyst_assets_path($file);
|
||||
|
||||
// We can always rely on WP_PLUGIN_DIR, because that's where
|
||||
// wordpress install it's plugin's. So we remove last segment
|
||||
// of that path to get the content dir AKA directly where
|
||||
// plugins are installed and make the magic...
|
||||
$contentDir = is_link(WP_PLUGIN_DIR) ?
|
||||
dirname(wp_normalize_path(readlink(WP_PLUGIN_DIR))) :
|
||||
dirname(wp_normalize_path(WP_PLUGIN_DIR));
|
||||
|
||||
$relativePath = str_replace( $contentDir, '', $absolutePath);
|
||||
|
||||
return content_url(wp_normalize_path($relativePath));
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('analyst_templates_path')) {
|
||||
/**
|
||||
* Generates path to file in templates folder
|
||||
*
|
||||
* @param $file
|
||||
* @return string
|
||||
*/
|
||||
function analyst_templates_path($file)
|
||||
{
|
||||
$path = sprintf('%s/templates/%s', realpath(__DIR__ . '/..'), trim($file, '/'));
|
||||
|
||||
return wp_normalize_path($path);
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('analyst_require_template')) {
|
||||
/**
|
||||
* Require certain template with data
|
||||
*
|
||||
* @param $file
|
||||
* @param array $data
|
||||
*/
|
||||
function analyst_require_template($file, $data = [])
|
||||
{
|
||||
// Extract data to current scope table
|
||||
extract($data);
|
||||
|
||||
require analyst_templates_path($file);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
<div id="analyst-deactivate-modal" class="analyst-modal" style="display: none">
|
||||
<div class="analyst-modal-content" style="width: 500px">
|
||||
<div class="analyst-disable-modal-mask" id="analyst-disable-deactivate-modal-mask" style="display: none"></div>
|
||||
<div style="display: flex">
|
||||
<div class="analyst-install-image-block" style="width: 80px">
|
||||
<img src="<?php echo $pencilImage; ?>"/>
|
||||
</div>
|
||||
<div class="analyst-install-description-block" style="padding-left: 20px">
|
||||
<strong class="analyst-modal-header">Why do you deactivate?</strong>
|
||||
<div class="analyst-install-description-text" style="padding-top: 2px">
|
||||
Please let us know, so we can improve it! Thank you <img class="analyst-smile-image" src="<?php echo $smileImage; ?>" alt="">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<ul id="analyst-deactivation-reasons">
|
||||
<li>
|
||||
<label>
|
||||
<span>
|
||||
<input type="radio" name="deactivation-reason">
|
||||
</span>
|
||||
<span class="question" data-question="I couldn't understand how to make it work">I couldn't understand how to make it work</span>
|
||||
</label>
|
||||
</li>
|
||||
<li data-input-type="textarea" data-input-placeholder="What should have worked, but didn’t?">
|
||||
<label>
|
||||
<span>
|
||||
<input type="radio" name="deactivation-reason">
|
||||
</span>
|
||||
<span class="question" data-question="The plugin didn't work as expected">The plugin didn't work as expected</span>
|
||||
</label>
|
||||
<div class="question-answer"></div>
|
||||
</li>
|
||||
<li data-input-type="input" data-input-placeholder="What is the plugin name?">
|
||||
<label>
|
||||
<span>
|
||||
<input type="radio" name="deactivation-reason">
|
||||
</span>
|
||||
<span class="question" data-question="I found a better plugin">I found a better plugin</span>
|
||||
</label>
|
||||
<div class="question-answer"></div>
|
||||
</li>
|
||||
<li>
|
||||
<label>
|
||||
<span>
|
||||
<input type="radio" name="deactivation-reason">
|
||||
</span>
|
||||
<span class="question" data-question="It's a temporary deactivation">It's a temporary deactivation</span>
|
||||
</label>
|
||||
<div class="question-answer"></div>
|
||||
</li>
|
||||
<li data-input-type="textarea" data-input-placeholder="Please provide the reason of deactivation">
|
||||
<label>
|
||||
<span>
|
||||
<input type="radio" name="deactivation-reason">
|
||||
</span>
|
||||
<span class="question" data-question="Other">Other</span>
|
||||
</label>
|
||||
<div class="question-answer"></div>
|
||||
</li>
|
||||
</ul>
|
||||
<p id="analyst-deactivation-error" style="color: #dc3232; font-size: 16px; display: none">Please let us know the reason for de-activation. Thank you!</p>
|
||||
</div>
|
||||
<div>
|
||||
<button class="analyst-btn-grey" id="analyst-disabled-plugin-action">Deactivate</button>
|
||||
</div>
|
||||
<div class="" style="text-align: center; font-size: 18px; padding-top: 10px">
|
||||
<button class="analyst-btn-secondary-ghost analyst-deactivate-modal-close" style="color: #cccccc">Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
(function ($) {
|
||||
$('.deactivate').click(function (e) {
|
||||
var anchor = $(this).find('[analyst-plugin-id]')
|
||||
var pluginId = anchor.attr('analyst-plugin-id')
|
||||
var isOptedIn = anchor.attr('analyst-plugin-opted-in') === '1'
|
||||
|
||||
// Do not ask for reason if not opted in
|
||||
if (!isOptedIn) {
|
||||
return
|
||||
}
|
||||
|
||||
e.preventDefault()
|
||||
|
||||
$('#analyst-deactivate-modal')
|
||||
.attr({
|
||||
'analyst-plugin-id': pluginId,
|
||||
'analyst-redirect-url': $(this).find('a').attr('href')
|
||||
})
|
||||
.show()
|
||||
})
|
||||
|
||||
$('.analyst-deactivate-modal-close').click(function () {
|
||||
$('#analyst-deactivate-modal').hide()
|
||||
})
|
||||
|
||||
$('#analyst-deactivation-reasons input[name="deactivation-reason"]').change(function () {
|
||||
$('.question-answer').empty()
|
||||
|
||||
var root = $('#analyst-deactivation-reasons input[name="deactivation-reason"]:checked').parents('li')
|
||||
|
||||
$('#analyst-deactivation-error').hide()
|
||||
|
||||
if (!root.attr('data-input-type')) return
|
||||
|
||||
var reasonInput = $('<' + root.attr('data-input-type') + '/>').attr({placeholder: root.attr('data-input-placeholder'), class: 'reason-answer'})
|
||||
|
||||
root.find('.question-answer').append(reasonInput)
|
||||
})
|
||||
|
||||
$('#analyst-disabled-plugin-action').click(function () {
|
||||
var pluginId = $('#analyst-deactivate-modal').attr('analyst-plugin-id')
|
||||
var pluginDeactivationUrl = $('#analyst-deactivate-modal').attr('analyst-redirect-url')
|
||||
|
||||
var root = $('#analyst-deactivation-reasons input[name="deactivation-reason"]:checked').parents('li');
|
||||
|
||||
var reason = root.find('.question-answer .reason-answer').val();
|
||||
|
||||
var question = root.find('.question').attr('data-question').trim()
|
||||
|
||||
var $errorBlock = $('#analyst-deactivation-error')
|
||||
|
||||
if (!question) {
|
||||
return $errorBlock.show()
|
||||
}
|
||||
|
||||
$errorBlock.hide()
|
||||
|
||||
var data = {
|
||||
action: 'analyst_plugin_deactivate_' + pluginId,
|
||||
question: question,
|
||||
nonce: analyst_opt_localize.nonce
|
||||
}
|
||||
|
||||
if (reason) {
|
||||
data['reason'] = reason.trim();
|
||||
}
|
||||
|
||||
$(this).attr('disabled', true).text('Deactivating...');
|
||||
|
||||
$('#analyst-disable-deactivate-modal-mask').show();
|
||||
|
||||
$.ajax({
|
||||
url: ajaxurl,
|
||||
method: 'POST',
|
||||
data: data
|
||||
}).done(function () {
|
||||
window.location.href = pluginDeactivationUrl
|
||||
|
||||
$('#analyst-disable-deactivate-modal-mask').hide();
|
||||
})
|
||||
})
|
||||
|
||||
})(jQuery)
|
||||
</script>
|
||||
@@ -0,0 +1,117 @@
|
||||
<div id="analyst-install-modal" class="analyst-modal" style="display: none" analyst-plugin-id="<?php echo $pluginToInstall; ?>">
|
||||
<div class="analyst-modal-content" style="width: 450px">
|
||||
<div class="analyst-disable-modal-mask" id="analyst-disable-install-modal-mask" style="display: none"></div>
|
||||
<div style="display: flex">
|
||||
<div class="analyst-install-image-block">
|
||||
<img src="<?php echo $shieldImage; ?>"/>
|
||||
</div>
|
||||
<div class="analyst-install-description-block">
|
||||
<strong class="analyst-modal-header">Stay on the safe side</strong>
|
||||
<p class="analyst-install-description-text">Receive our plugin’s alerts in
|
||||
case of <strong>critical security</strong>, feature & special deal
|
||||
updates and allow non-sensitive
|
||||
diagnostic tracking.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="analyst-modal-def-top-padding">
|
||||
<button class="analyst-btn-success" id="analyst-install-action">Allow & Continue ></button>
|
||||
</div>
|
||||
<div class="analyst-modal-def-top-padding" id="analyst-permissions-block" style="display: none">
|
||||
<span>You’re granting these permissions:</span>
|
||||
<ul class="analyst-install-permissions-list">
|
||||
<li><strong>Your profile information</strong> (name and email) </li>
|
||||
<li><strong>Your site information</strong> (URL, WP version, PHP info, plugins & themes)</li>
|
||||
<li><strong>Plugin notices</strong> (updates, announcements, marketing, no spam)</li>
|
||||
<li><strong>Plugin events</strong> (activation, deactivation and uninstall)</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="analyst-install-footer analyst-modal-def-top-padding">
|
||||
<span class="analyst-action-text" id="analyst-permissions-toggle">Learn more</span>
|
||||
<span id="analyst-powered-by" style="display: none;">Powered by <a href="https://sellcodes.com/blog/wordpress-feedback-system-for-plugin-creators/?utm_source=optin_screen" target="_blank" class="analyst-link">Sellcodes.com</a></span>
|
||||
<span class="analyst-action-text analyst-install-modal-close" id="analyst-install-skip">Skip</span>
|
||||
</div>
|
||||
<div id="analyst-install-error" class="analyst-modal-def-top-padding" style="display: none; text-align: center">
|
||||
<span style="color: #dc3232; font-size: 16px">Service unavailable. Please try again later</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
(function ($) {
|
||||
|
||||
var installPlugin = function (pluginId) {
|
||||
var $error = $('#analyst-install-error')
|
||||
|
||||
$error.hide()
|
||||
|
||||
$.ajax({
|
||||
url: ajaxurl,
|
||||
method: 'POST',
|
||||
data: {
|
||||
action: 'analyst_install_' + pluginId,
|
||||
nonce: analyst_opt_localize.nonce
|
||||
},
|
||||
success: function (data) {
|
||||
if (data && !data.success) {
|
||||
//error
|
||||
$('#analyst-install-modal').hide()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
window.location.reload()
|
||||
},
|
||||
error: function () {
|
||||
$('#analyst-install-modal').hide()
|
||||
}
|
||||
}).done(function () {
|
||||
$('#analyst-disable-install-modal-mask').hide()
|
||||
|
||||
$('#analyst-install-action')
|
||||
.attr('disabled', false)
|
||||
.text('Allow & Continue >')
|
||||
})
|
||||
}
|
||||
|
||||
if ($('#analyst-install-modal').attr('analyst-plugin-id')) {
|
||||
$('#analyst-install-modal').show()
|
||||
}
|
||||
|
||||
|
||||
$('.analyst-install-modal-close').click(function () {
|
||||
$('#analyst-install-modal').hide()
|
||||
})
|
||||
|
||||
$('#analyst-install-action').click(function () {
|
||||
var pluginId = $('#analyst-install-modal').attr('analyst-plugin-id')
|
||||
|
||||
$('#analyst-install-action')
|
||||
.attr('disabled', true)
|
||||
.text('Please wait...')
|
||||
|
||||
$('#analyst-disable-install-modal-mask').show()
|
||||
|
||||
installPlugin(pluginId)
|
||||
})
|
||||
|
||||
$('#analyst-permissions-toggle').click(function () {
|
||||
var isVisible = $('#analyst-permissions-block').toggle().is(':visible')
|
||||
|
||||
isVisible ? $(this).text('Close section') : $(this).text('Learn more')
|
||||
|
||||
var poweredBy = $('#analyst-powered-by')
|
||||
isVisible ? poweredBy.show() : poweredBy.hide()
|
||||
})
|
||||
|
||||
$('#analyst-install-skip').click(function () {
|
||||
var pluginId = $('#analyst-install-modal').attr('analyst-plugin-id')
|
||||
|
||||
$.post(ajaxurl, {
|
||||
action: 'analyst_skip_install_' + pluginId,
|
||||
nonce: analyst_opt_localize.nonce
|
||||
}).done(function () {
|
||||
$('#analyst-install-modal').hide()
|
||||
})
|
||||
})
|
||||
})(jQuery)
|
||||
</script>
|
||||
@@ -0,0 +1,10 @@
|
||||
<div class="notice notice-success analyst-notice">
|
||||
<p>
|
||||
<strong class="analyst-plugin-name"><?php echo $notice->getPluginName(); ?></strong>
|
||||
<?php echo $notice->getBody(); ?>
|
||||
</p>
|
||||
|
||||
<button type="button" class="analyst-notice-dismiss notice-dismiss" analyst-notice-id="<?php echo $notice->getId(); ?>">
|
||||
<span class="screen-reader-text">Dismiss this notice.</span>
|
||||
</button>
|
||||
</div>
|
||||
@@ -0,0 +1,61 @@
|
||||
<script type="text/javascript">
|
||||
|
||||
(function ($) {
|
||||
var isOptingIn = false
|
||||
|
||||
$('#analyst-opt-in-modal').appendTo($('body'))
|
||||
|
||||
var makeOptIn = function (pluginId) {
|
||||
if (isOptingIn) return
|
||||
|
||||
isOptingIn = true
|
||||
|
||||
$.ajax({
|
||||
url: ajaxurl,
|
||||
method: 'POST',
|
||||
data: {
|
||||
action: 'analyst_opt_in_' + pluginId,
|
||||
nonce: analyst_opt_localize.nonce
|
||||
},
|
||||
success: function () {
|
||||
$('#analyst-opt-in-modal').hide()
|
||||
|
||||
isOptingIn = false
|
||||
|
||||
var optOutAction = $('<a />').attr({
|
||||
class: 'analyst-action-opt analyst-opt-out',
|
||||
'analyst-plugin-id': pluginId,
|
||||
'analyst-plugin-signed': '1'
|
||||
})
|
||||
.text('Opt Out')
|
||||
$('.analyst-opt-in[analyst-plugin-id="'+ pluginId +'"').replaceWith(optOutAction)
|
||||
|
||||
$('[analyst-plugin-id="' + pluginId + '"').attr('analyst-plugin-opted-in', 1)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
$(document).on('click', '.analyst-opt-in:not([loading])', function() {
|
||||
var pluginId = $(this).attr('analyst-plugin-id')
|
||||
var isSigned = $(this).attr('analyst-plugin-signed') === '1'
|
||||
|
||||
if (!isSigned) {
|
||||
$('#analyst-install-modal')
|
||||
.attr('analyst-plugin-id', pluginId)
|
||||
.show()
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$('#analyst-install-modal').attr({'analyst-plugin-id': pluginId})
|
||||
|
||||
$(this).attr('loading', true).text('Opting In...')
|
||||
|
||||
makeOptIn(pluginId);
|
||||
})
|
||||
|
||||
$('.opt-in-modal-close').click(function () {
|
||||
$('#analyst-opt-in-modal').hide()
|
||||
})
|
||||
})(jQuery)
|
||||
</script>
|
||||
@@ -0,0 +1,110 @@
|
||||
<div id="analyst-opt-out-modal" class="analyst-modal" style="display: none">
|
||||
<div class="analyst-modal-content" style="width: 600px">
|
||||
<div class="analyst-disable-modal-mask" id="analyst-disable-opt-out-modal-mask" style="display: none"></div>
|
||||
<div style="display: flex">
|
||||
<div class="analyst-install-image-block" style="width: 120px">
|
||||
<img src="<?php echo $shieldImage; ?>"/>
|
||||
</div>
|
||||
<div class="analyst-install-description-block">
|
||||
<strong class="analyst-modal-header">By opting out, we cannot alert you anymore in case of important security updates.</strong>
|
||||
<p class="analyst-install-description-text">
|
||||
In addition, we won’t get pointers how to further improve the plugin based on your integration with our plugin.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="analyst-modal-def-top-padding">
|
||||
<button class="analyst-btn-success opt-out-modal-close">Ok, don't opt out</button>
|
||||
</div>
|
||||
<div class="analyst-modal-def-top-padding" style="text-align: center;">
|
||||
<button class="analyst-btn-secondary-ghost" id="opt-out-action">Opt out</button>
|
||||
</div>
|
||||
<div id="analyst-opt-out-error" class="analyst-modal-def-top-padding" style="display: none;">
|
||||
<span style="color: #dc3232; font-size: 16px">Service unavailable. Please try again later</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
(function ($) {
|
||||
var isOptingOut = false
|
||||
|
||||
$('#analyst-opt-out-modal').appendTo($('body'))
|
||||
|
||||
$(document).on('click', '.analyst-opt-out', function() {
|
||||
var pluginId = $(this).attr('analyst-plugin-id')
|
||||
|
||||
$('#analyst-opt-out-modal')
|
||||
.attr({'analyst-plugin-id': pluginId})
|
||||
.show()
|
||||
})
|
||||
|
||||
$('.opt-out-modal-close').click(function () {
|
||||
$('#analyst-opt-out-modal').hide()
|
||||
})
|
||||
|
||||
$('#opt-out-action').click(function () {
|
||||
if (isOptingOut) return
|
||||
|
||||
var $mask = $('#analyst-disable-opt-out-modal-mask')
|
||||
var $error = $('#analyst-opt-out-error')
|
||||
|
||||
var pluginId = $('#analyst-opt-out-modal').attr('analyst-plugin-id')
|
||||
|
||||
$mask.show()
|
||||
$error.hide()
|
||||
|
||||
var self = this
|
||||
|
||||
isOptingOut = true
|
||||
|
||||
$(self).text('Opting out...')
|
||||
|
||||
$.ajax({
|
||||
url: ajaxurl,
|
||||
method: 'POST',
|
||||
data: {
|
||||
action: 'analyst_opt_out_' + pluginId,
|
||||
nonce: analyst_opt_localize.nonce
|
||||
},
|
||||
success: function (data) {
|
||||
$(self).text('Opt out')
|
||||
|
||||
if (data && !data.success) {
|
||||
$('#analyst-opt-out-modal').hide()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
$error.hide()
|
||||
|
||||
$('#analyst-opt-out-modal').hide()
|
||||
|
||||
isOptingOut = false
|
||||
|
||||
var optInAction = $('<a />').attr({
|
||||
class: 'analyst-action-opt analyst-opt-in',
|
||||
'analyst-plugin-id': pluginId,
|
||||
'analyst-plugin-signed': '1'
|
||||
})
|
||||
.text('Opt In')
|
||||
$('.analyst-opt-out[analyst-plugin-id="'+ pluginId +'"').replaceWith(optInAction)
|
||||
|
||||
$('[analyst-plugin-id="' + pluginId + '"').attr('analyst-plugin-opted-in', 0)
|
||||
|
||||
$mask.hide()
|
||||
},
|
||||
error: function () {
|
||||
$('#analyst-opt-out-error').show()
|
||||
|
||||
$(self).text('Opt out')
|
||||
}
|
||||
}).done(function () {
|
||||
$mask.hide()
|
||||
|
||||
isOptingOut = false
|
||||
})
|
||||
})
|
||||
})(jQuery)
|
||||
</script>
|
||||
15
wp-content/plugins/copy-delete-posts/analyst/version.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
return array(
|
||||
// The sdk version
|
||||
'sdk' => '1.3.30',
|
||||
|
||||
// Minimum supported WordPress version
|
||||
'wp' => '4.7',
|
||||
|
||||
// Supported PHP version
|
||||
'php' => '5.4',
|
||||
|
||||
// Path to current SDK$
|
||||
'path' => __DIR__,
|
||||
);
|
||||
1
wp-content/plugins/copy-delete-posts/assets/css/cdp-editor.min.css
vendored
Normal file
@@ -0,0 +1 @@
|
||||
#delete-action,#publishing-action{float: none!important;line-height: 1.5}#delete-action{width: calc(100% - 121px)!important}#publishing-action{position: absolute!important;right: 10px!important;bottom: 12px!important}@media screen and (max-width: 782px){#delete-action,#publishing-action{line-height: 1.6!important}#publishing-action{bottom: 7px!important}}#duplicate-action{display: none}
|
||||
1
wp-content/plugins/copy-delete-posts/assets/css/cdp-global.min.css
vendored
Normal file
1
wp-content/plugins/copy-delete-posts/assets/css/cdp-gutenberg.min.css
vendored
Normal file
@@ -0,0 +1 @@
|
||||
.editor-post-trash{margin-left: 5px!important}.cdp-editor-gutenberg-copy{margin-right: 5px!important;border: 1px solid blue;border-radius: 3px;color: blue}.cdp-red{color: red!important;font-style: italic!important;pointer-events: none!important}
|
||||
1
wp-content/plugins/copy-delete-posts/assets/css/cdp-select.min.css
vendored
Normal file
1
wp-content/plugins/copy-delete-posts/assets/css/cdp-user.min.css
vendored
Normal file
@@ -0,0 +1 @@
|
||||
.cdp-admin-bar-icon::before{font-family: dashicons;content: '\f105';top: 4px;position: relative;color: rgba(240,245,250,.6);margin-right: 3px;font-size: 18px}.cdp-admin-bar-icon{line-height: 1!important}.cdp-admin-bar-copy{line-height: 1!important}
|
||||
1
wp-content/plugins/copy-delete-posts/assets/css/cdp.min.css
vendored
Normal file
1
wp-content/plugins/copy-delete-posts/assets/css/cdp.tooltip.min.css
vendored
Normal file
BIN
wp-content/plugins/copy-delete-posts/assets/imgs/alert_error.png
Normal file
|
After Width: | Height: | Size: 463 B |
BIN
wp-content/plugins/copy-delete-posts/assets/imgs/alert_info.png
Normal file
|
After Width: | Height: | Size: 507 B |
|
After Width: | Height: | Size: 538 B |
|
After Width: | Height: | Size: 524 B |
BIN
wp-content/plugins/copy-delete-posts/assets/imgs/arrow.png
Normal file
|
After Width: | Height: | Size: 843 B |
BIN
wp-content/plugins/copy-delete-posts/assets/imgs/close.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
wp-content/plugins/copy-delete-posts/assets/imgs/copy.png
Normal file
|
After Width: | Height: | Size: 6.7 KiB |
BIN
wp-content/plugins/copy-delete-posts/assets/imgs/icon.png
Normal file
|
After Width: | Height: | Size: 502 B |
BIN
wp-content/plugins/copy-delete-posts/assets/imgs/info.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
wp-content/plugins/copy-delete-posts/assets/imgs/intro_1.gif
Normal file
|
After Width: | Height: | Size: 2.3 MiB |
BIN
wp-content/plugins/copy-delete-posts/assets/imgs/intro_2.gif
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
wp-content/plugins/copy-delete-posts/assets/imgs/intro_3.gif
Normal file
|
After Width: | Height: | Size: 416 KiB |
BIN
wp-content/plugins/copy-delete-posts/assets/imgs/premium.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 6.2 KiB |
BIN
wp-content/plugins/copy-delete-posts/assets/imgs/search.png
Normal file
|
After Width: | Height: | Size: 485 B |
44
wp-content/plugins/copy-delete-posts/assets/imgs/smile.svg
Normal file
@@ -0,0 +1,44 @@
|
||||
<svg width="171" height="77" viewBox="0 0 171 77" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="86.5658" cy="43.9003" r="33.0263" fill="#77D501"/>
|
||||
<path d="M101.758 48.5241H71.3738C74.0159 53.8083 77.3185 61.0741 86.5659 61.0741C95.8132 61.0741 99.7764 52.9276 101.758 48.5241Z" fill="white"/>
|
||||
<path d="M70.7135 39.9373C70.7135 38.6163 71.5061 35.9742 74.6767 35.9742C77.8472 35.9742 78.6398 38.6163 78.6398 39.9373" stroke="#000500" stroke-width="2.6421" stroke-linecap="round"/>
|
||||
<path d="M93.1713 39.9373C93.1713 38.6163 93.9639 35.9742 97.1344 35.9742C100.305 35.9742 101.098 38.6163 101.098 39.9373" stroke="#000500" stroke-width="2.6421" stroke-linecap="round"/>
|
||||
<path d="M3.43707 29.3057L1.27364 28.7538L2.76858 24.7226L5.92317 23.9845L3.43707 29.3057Z" fill="#9DE8FF"/>
|
||||
<path d="M127.346 0.090332C128.251 1.54276 129.899 1.3648 131.104 0.707937C130.919 0.807383 131.138 2.1342 130.938 2.24149C129.732 2.89836 128.085 3.07631 127.179 1.62388C127 1.33863 127.516 0.365116 127.346 0.090332Z" fill="#78D500"/>
|
||||
<path d="M133.083 39.7929C131.374 39.6973 130.57 41.1467 130.414 42.5101C130.439 42.3013 129.228 41.7165 129.256 41.4911C129.412 40.1276 130.216 38.6782 131.925 38.7738C132.261 38.7917 132.76 39.7742 133.083 39.7929Z" fill="#77D501"/>
|
||||
<path d="M45.8559 60.828C46.9933 61.5943 48.1401 60.9256 48.8069 60.0512C48.7038 60.1846 49.2977 61.0835 49.1864 61.2274C48.5197 62.1018 47.3728 62.7705 46.2354 62.0042C46.0112 61.8541 46.0705 60.9732 45.8559 60.828Z" fill="#76FFA2"/>
|
||||
<path d="M29.4909 2.00425L28.0653 5.37453L26.8488 3.76672L27.8777 0.090332L29.4909 2.00425Z" fill="#FFC887"/>
|
||||
<path d="M71.3705 4.08609L72.0804 1.68428L73.869 0.345451L74.2727 6.11676L71.3705 4.08609Z" fill="url(#paint0_linear_2_882)"/>
|
||||
<path d="M87.4414 26.3795L87.1276 28.3197L84.1297 27.1508L83.4653 24.3801L87.4414 26.3795Z" fill="#E94C93"/>
|
||||
<path d="M169.175 1.3237L170.513 2.76289L167.749 4.4109L165.155 3.23361L169.175 1.3237Z" fill="#E94C93"/>
|
||||
<path d="M32.86 39.0054L31.5857 38.9204L31.7591 35.8406L33.3714 34.8691L32.86 39.0054Z" fill="#E94C93"/>
|
||||
<path d="M113.713 12.3042L112.713 11.5103L114.605 9.07421L116.484 9.19054L113.713 12.3042Z" fill="#E94C4C"/>
|
||||
<path d="M165.773 40.5307L167.5 41.1844L166.123 45.2027L163.537 45.8149L165.773 40.5307Z" fill="#3B4DF0"/>
|
||||
<path d="M36.4262 75.1937L35.9293 77L32.3428 75.5788L31.6922 72.8829L36.4262 75.1937Z" fill="url(#paint1_linear_2_882)"/>
|
||||
<path d="M146.995 71.2653L148.385 71.5018L147.682 74.4758L145.743 75.2284L146.995 71.2653Z" fill="#D886FF"/>
|
||||
<path d="M49.6672 19.4817L48.8837 18.4327L51.0626 17.1708L52.778 18.0055L49.6672 19.4817Z" fill="#FFE68D"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_2_882" x1="140.08" y1="-150.3" x2="-16.8617" y2="203.176" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0.1124" stop-color="#F0C83B"/>
|
||||
<stop offset="0.2416" stop-color="#F1563C"/>
|
||||
<stop offset="0.2688" stop-color="#E65352"/>
|
||||
<stop offset="0.3232" stop-color="#D34F7A"/>
|
||||
<stop offset="0.3666" stop-color="#C74C92"/>
|
||||
<stop offset="0.3933" stop-color="#C34B9B"/>
|
||||
<stop offset="0.7865" stop-color="#00B3C1"/>
|
||||
<stop offset="0.8146" stop-color="#00B36C"/>
|
||||
<stop offset="1" stop-color="#00B3C1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_2_882" x1="-7.63982" y1="174.969" x2="244.551" y2="-448.84" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0.1124" stop-color="#F0C83B"/>
|
||||
<stop offset="0.2416" stop-color="#F1563C"/>
|
||||
<stop offset="0.2688" stop-color="#E65352"/>
|
||||
<stop offset="0.3232" stop-color="#D34F7A"/>
|
||||
<stop offset="0.3666" stop-color="#C74C92"/>
|
||||
<stop offset="0.3933" stop-color="#C34B9B"/>
|
||||
<stop offset="0.7865" stop-color="#00B3C1"/>
|
||||
<stop offset="0.8146" stop-color="#00B36C"/>
|
||||
<stop offset="1" stop-color="#00B3C1"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.6 KiB |
BIN
wp-content/plugins/copy-delete-posts/assets/imgs/stars.gif
Normal file
|
After Width: | Height: | Size: 20 KiB |
1
wp-content/plugins/copy-delete-posts/assets/js/cdp-bulk.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
jQuery(document).ready(function(o){["edit-page","edit-post"].includes(pagenow)||($bulktop=o("#bulk-action-selector-top"),$bulkbot=o("#bulk-action-selector-bottom"),($bulktop.length>0||$bulkbot.length>0)&&(0==$bulktop.find('[value="cdp_bulk_copy"]').length&&$bulktop.append('<option value="cdp_bulk_copy">'+cdpBulkJS.strOptCopy+"</option>"),0==$bulkbot.find('[value="cdp_bulk_copy"]').length&&$bulkbot.append('<option value="cdp_bulk_copy">'+cdpBulkJS.strOptCopy+"</option>"),o("#cdp-current-post-id").remove()))});
|
||||
1
wp-content/plugins/copy-delete-posts/assets/js/cdp-global.min.js
vendored
Normal file
1
wp-content/plugins/copy-delete-posts/assets/js/cdp-gutenberg.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
jQuery(document).ready(function(t){if(t(document).on("readystatechange",function(){e(10)}),e(10),e(100),e(300),$button=t(t(".edit-post-header__settings").find('.components-button.components-icon-button[aria-label="Settings"]')[0]),$button.on("click",e),t(".edit-post-sidebar__panel-tab").on("click",e),t("#cdp-original-post").length>0){let e=t("#cdp-original-post").attr("data-cdp-parent"),n=t("#cdp-original-post").attr("data-cdp-parent-url");t(".edit-post-header-toolbar").append(t(`<div class="cdp-original-info-b">This post is a duplicate of <a href="${n}" target="_blank">${e}</a></div>`))}function e(e=100){"number"!=typeof e&&(e=100),setTimeout(()=>{0==t(".cdp-editor-gutenberg-copy").length&&($parent=t(".editor-post-trash").parents(".components-panel__row"),$html='<button type="button" class="components-button cdp-editor-gutenberg-copy is-button is-default is-large">'+cdpGutenbergJS.cdpCopy+"</button>",t($parent).prepend($html),t($html).insertBefore(".interface-pinned-items"))},e)}setInterval(()=>{t(".cdp-editor-gutenberg-copy").length<=0&&e(10)},3e3),t(window).on("resize",e)});
|
||||
1
wp-content/plugins/copy-delete-posts/assets/js/cdp-icPagination.min.js
vendored
Normal file
1
wp-content/plugins/copy-delete-posts/assets/js/cdp-modal.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
jQuery(document).ready(function(o){o("#cdp-purl").val();let t="default";function e(){o.cdpModal("cdp-copy-modal-global");let t=o("select.cdp-modal-input-profiles-r").val();void 0!==t&&null!=t&&"alloptions"!=t||(t="default"),o('select.cdp-input-dynamic[name="tooltip-which-profile-second-modal"]').val(t),o('select.cdp-input-dynamic[name="tooltip-which-profile-second-modal"]').trigger("change")}function c(){if(o("#cdp-current-post-id").length>0)return[o("#cdp-current-post-id").val()];$rows=o("#the-list").find("tr"),$ids=[];for(var t=0;t<$rows.length;t++){let e=o($rows[t]);e.find('input[name="post[]"]').is(":checked")&&$ids.push(e.find('input[name="post[]"]').attr("value"))}return $ids}function n(t=(()=>{})){window.onbeforeunload=null,$e=o(".cdp-copy-loader-overlay"),$e.is(":hidden")||$e.animate({opacity:0},300,function(){$e.hide(),t(!0)})}o(".cdp-admin-bar-copy").on("click",e),o("body").on("click",".cdp-editor-gutenberg-copy",e),o("body").on("click",".cdp-copy-btn-editor",e),o("body").on("click",".cdp-copy-modal-button",function(){let e=o(this).attr("data-cdp-btn"),i=["copy-quick","copy-custom","copy-custom-link"];if(i.includes(e)){let d={type:e},l=c(),p=o(".cdp-modal-checkboxes").find(".cdp-modal-option-r");if(l.length<=0)return void o.cdpNotification("warning",cdpModalJS.strRowCopyTryAgain);let a=o(".cdp-modal-input-profiles-r").val();d.custom={},d.times=o(".cdp-modal-input-times").val(),d.swap="2"==o(".cdp-swap").val()?"true":"false",d.profile=a,o(".cdp-multiple-sites-selector").is(":hidden")?d.site=o(".cdp-multi-site-at-once-selector select").val():d.site=o('.cdp-input-dynamic[name="tooltip-which-site-second-modal"]').val();let s=["clear","alloptions","custom","custom_named","null","undefined",null,void 0];if(a&&!s.includes(a)&&(t=a),!d.profile){if(!t||s.includes(t))return o.cdpNotification("warning",cdpModalJS.strSettCopyIssue),void n();d.profile=t}for(let t=0;t<p.length;++t)d.custom[o(p[t]).attr("name")]=o(p[t]).is(":checked");d.custom.taxonomy=d.custom.cdp_taxonomy,delete d.custom.cdp_taxonomy,setTimeout(()=>{let t=o.cdptipster.instances();for(instance in t)t[instance].close()},10),function(t=(()=>{})){window.onbeforeunload=(()=>cdpModalJS.strCopyInProgress),$e=o(".cdp-copy-loader-overlay"),$e.is(":hidden")&&($e.show(),$e.animate({opacity:1},300,function(){t(!0)}))}(()=>{o.ajax({type:"POST",url:ajaxurl,data:{action:"cdp_action_handling",token:"cdp",f:"copy_post",nonce:cdpGlobalJS.ajaxNonce,origin:"modal",id:l,data:d},timeout:0}).done(function(t){o.isJsonString(t)&&(t=o.cdpParse(t));"error"==t.status?o.cdpNotification("error",cdpModalJS.strPostCopyIssue):(n(),e==i[2]||t.link&&t.link.length>0?"pConv"==t.link?(o.post(ajaxurl,{action:"cdp_action_handling",nonce:cdpGlobalJS.ajaxNonce,token:"cdp",f:"delete_success_img"}),"-28"==o(".cdp-copy-alert-success").position().top&&o(".cdp-copy-alert-success").animate({top:"32px",opacity:1},300),setTimeout(()=>{"32"==o(".cdp-copy-alert-success").position().top&&o(".cdp-copy-alert-success").animate({top:"-28px",opacity:0},300)},3e3),o.cdpModalClose("cdp-copy-modal-global")):window.location.href=t.link:"undefined"==typeof pagenow||"post"==pagenow||"page"==pagenow?(o.post(ajaxurl,{action:"cdp_action_handling",nonce:cdpGlobalJS.ajaxNonce,token:"cdp",f:"delete_success_img"}),"-28"==o(".cdp-copy-alert-success").position().top&&o(".cdp-copy-alert-success").animate({top:"32px",opacity:1},300),setTimeout(()=>{"32"==o(".cdp-copy-alert-success").position().top&&o(".cdp-copy-alert-success").animate({top:"-28px",opacity:0},300)},3e3),o("#cdp_notice_error_modal").length>0&&(o("#cdp_notice_error_modal").show(),o("#cdp_notice_error_modal").fadeIn(300),o("#cdp_notice_error_modal").animate({opacity:1},500),o("#cdp_notice_error_modal .cdp_notice_content").animate({opacity:1,top:"50%"},500)),o.cdpModalClose("cdp-copy-modal-global")):location.reload())}).fail(function(t){o.cdpNotification("error",cdpModalJS.strPostCopyIssueConsoleInfo),n(),console.log(t),console.log(t.responseText)})})}else o.cdpNotification(cdpModalJS.strRecogBtnIssue)}),o("body").on("click",".cdp-modal-copy-times-content .cdp-multiple-sites-selector",function(){o(".cdp-modal-copy-times-content .cdp-modal-select-2").fadeOut(300),o(".cdp-modal-copy-times-content .cdp-multiple-sites-selector").hide(300),o(".cdp-modal-copy-times-content .cdp-multi-site-at-once-selector").show(300)}),o("body").on("change","select.cdp-modal-input-profiles-r",function(){let e=["clear","alloptions","custom","custom_named","null","undefined",null,void 0];o(this).val()&&!e.includes(o(this).val())&&(t=o(this).val())}),o("#posts-filter").on("submit",function(t){"cdp_bulk_copy"==o("#bulk-action-selector-top").val()&&(t.preventDefault(),$ids=c(),$ids.length<=0?o.cdpNotification("warning",cdpModalJS.strRowCopyIssue):e())})});
|
||||
1
wp-content/plugins/copy-delete-posts/assets/js/cdp-select.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!function(e){e.fn.cdpNiceSelect=function(t){function s(t){t.after(e("<div></div>").addClass("cdp-nice-select").addClass(t.attr("class")||"").addClass(t.attr("disabled")?"disabled":"").attr("tabindex",t.attr("disabled")?null:"0").html('<span class="current"></span><ul class="list"></ul>'));var s=t.next(),c=t.find("option"),n=t.find("option:selected");s.find(".current").html(n.data("display")||n.text()),c.each(function(t){var c=e(this),n=c.data("display");s.find("ul").append(e("<li></li>").attr("data-value",c.val()).attr("data-display",n||null).addClass("option"+(c.is(":selected")?" selected":"")+(c.is(":disabled")?" disabled":"")).html(c.text()))})}if("string"==typeof t)return"update"==t?this.each(function(){var t=e(this),c=e(this).next(".cdp-nice-select"),n=c.hasClass("open");c.length&&(c.remove(),s(t),n&&t.next().trigger("click"))}):"destroy"==t?(this.each(function(){var t=e(this),s=e(this).next(".cdp-nice-select");s.length&&(s.remove(),t.css("display",""))}),0==e(".cdp-nice-select").length&&e(document).off(".cdp_nice_select")):console.log('Method "'+t+'" does not exist.'),this;this.hide(),this.each(function(){var t=e(this);t.next().hasClass("cdp-nice-select")||s(t)}),e(document).off(".cdp_nice_select"),e(document).on("click.cdp_nice_select",".cdp-nice-select",function(t){var s=e(this);e(".cdp-nice-select").not(s).removeClass("open"),s.toggleClass("open"),s.hasClass("open")?(s.find(".option"),s.find(".focus").removeClass("focus"),s.find(".selected").addClass("focus")):s.focus()}),e(document).on("click.cdp_nice_select",function(t){0===e(t.target).closest(".cdp-nice-select").length&&e(".cdp-nice-select").removeClass("open").find(".option")}),e(document).on("click.cdp_nice_select",".cdp-nice-select .option:not(.disabled)",function(t){var s=e(this),c=s.closest(".cdp-nice-select");c.find(".selected").removeClass("selected"),s.addClass("selected");var n=s.data("display")||s.text();c.find(".current").text(n),c.prev("select").val(s.data("value")).trigger("change")}),e(document).on("keydown.cdp_nice_select",".cdp-nice-select",function(t){var s=e(this),c=e(s.find(".focus")||s.find(".list .option.selected"));if(32==t.keyCode||13==t.keyCode)return s.hasClass("open")?c.trigger("click"):s.trigger("click"),!1;if(40==t.keyCode){if(s.hasClass("open")){var n=c.nextAll(".option:not(.disabled)").first();n.length>0&&(s.find(".focus").removeClass("focus"),n.addClass("focus"))}else s.trigger("click");return!1}if(38==t.keyCode){if(s.hasClass("open")){var l=c.prevAll(".option:not(.disabled)").first();l.length>0&&(s.find(".focus").removeClass("focus"),l.addClass("focus"))}else s.trigger("click");return!1}if(27==t.keyCode)s.hasClass("open")&&s.trigger("click");else if(9==t.keyCode&&s.hasClass("open"))return!1});var c=document.createElement("a").style;return c.cssText="pointer-events:auto","auto"!==c.pointerEvents&&e("html").addClass("no-csspointerevents"),this}}(jQuery),jQuery(document).ready(function(e){e("body").on("mousewheel DOMMouseScroll",".cdp-nice-select .list, .cdp-content-with-scroll",function(t){let s=null;"mousewheel"==t.type?s=-1*t.originalEvent.wheelDelta:"DOMMouseScroll"==t.type&&(s=40*t.originalEvent.detail),s&&(t.preventDefault(),e(this).scrollTop(s+e(this).scrollTop()))})});
|
||||
1
wp-content/plugins/copy-delete-posts/assets/js/cdp-user.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
jQuery(document).ready(function(e){});
|
||||
1
wp-content/plugins/copy-delete-posts/assets/js/cdp.min.js
vendored
Normal file
1
wp-content/plugins/copy-delete-posts/assets/js/cdp.tooltip.min.js
vendored
Normal file
1
wp-content/plugins/copy-delete-posts/banner/assets/index.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!function(){let e=[],t={name:null,trigger:null,element:null},n=null,r=null,i=!1;const s=e=>{o(),c(e),l()},c=e=>{t.name&&document.querySelector(".ci-project-content").classList.remove(`ci-${t.name}-visible`),t.name=e.id.replace("-trigger",""),document.querySelector(".ci-project-content").classList.add(`ci-${t.name}-visible`),t.trigger&&t.trigger.classList.remove("ci-selected-project"),t.trigger=e,t.trigger.classList.add("ci-selected-project"),t.element=document.querySelector(`.ci-project-${t.name}`)},l=()=>{n||(n=setInterval(()=>{const n=e.findIndex(e=>e.name===t.name),r=n===e.length-1?0:n+1;c(e[r].trigger)},1e4))},o=()=>{clearInterval(n),n=null},a=()=>{const e=(e=>{const t=e.getBoundingClientRect();return t.top>=0&&t.left>=0&&t.bottom<=(window.innerHeight||document.documentElement.clientHeight)&&t.right<=(window.innerWidth||document.documentElement.clientWidth)})(r);!n&&e?l():n&&!e&&o()},u=e=>{const t=e.target,r=t.dataset.slug,s=t.innerText;!0!==i&&(i=!0,t.innerText="Installing, please wait...",t.classList.add("ci-inisev-prepare"),clearInterval(n),setTimeout(()=>{t.classList.add("ci-inisev-install");let e=new XMLHttpRequest;e.open("POST",ajaxurl,!0),e.setRequestHeader("Content-type","application/x-www-form-urlencoded"),e.onload=(()=>{if(l(),200===e.status||e.status<400)try{let n=e.responseText;g(n)&&(n=v(n)),void 0!==n.success&&!0===n.success?(t.classList.remove("ci-inisev-install"),t.innerText="Plugin installed successfully :)",setTimeout(()=>{window.location.href=n.data.url},300)):d(t,s)}catch(e){d(t,s)}else d(t,s)}),e.send("action=inisev_installation&slug="+r+"&nonce="+inisev_carousel.nonce)},7e3))},d=(e,t)=>{e.innerText="Installation failed...",setTimeout(()=>{e.classList.remove("ci-inisev-install"),setTimeout(()=>{e.classList.remove("ci-inisev-prepare"),e.innerText=t,i=!1})},2e3)},m=e=>{e&&e.addEventListener("click",u)},g=e=>{try{JSON.parse(e)}catch(t){if("string"==typeof e){let t=p(e).indexOf("}");t=0==t?e.length:-t,e=e.slice(e.indexOf("{"),t);try{JSON.parse(e)}catch(e){return!1}return!0}return!1}return!0},p=e=>"string"==typeof e?""===e?"":p(e.substr(1))+e.charAt(0):e,v=e=>{try{JSON.parse(e)}catch(t){if("string"==typeof e){let t=p(e).indexOf("}");t=0==t?e.length:-t,e=e.slice(e.indexOf("{"),t);try{JSON.parse(e)}catch(e){return!1}return JSON.parse(e)}return!1}return JSON.parse(e)};document.addEventListener("DOMContentLoaded",()=>{(()=>{const t=document.querySelectorAll(".ci-project-list-element"),n=document.querySelectorAll(".ci-project");e=Array.from(t).map((e,t)=>({trigger:e,element:n[t],name:e.id.replace("-trigger","")}))})(),c(document.querySelector("#BackupMigration-trigger")),document.querySelectorAll(".ci-project-list-element").forEach(e=>{e.addEventListener("mouseover",t=>(e=>{e.classList.contains("ci-selected-project")?o():s(e)})(e)),e.addEventListener("mouseout",l)}),r=document.querySelector(".ci-carrinis .ci-carousel"),document.addEventListener("scroll",a),document.querySelectorAll(".ci-carrinis .ci-project").forEach(e=>{e.addEventListener("mouseover",o),e.addEventListener("mouseout",l)}),(()=>{const e=document.getElementsByClassName("ci-inisev-install-plugin");for(let t=0;t<e.length;++t)m(e[t])})()})}();
|
||||
15
wp-content/plugins/copy-delete-posts/banner/assets/style.min.css
vendored
Normal file
501
wp-content/plugins/copy-delete-posts/banner/misc.php
Normal file
@@ -0,0 +1,501 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* File for our cool Carousel in the footer
|
||||
*
|
||||
* @category Child Plugin
|
||||
* @version v0.3.1
|
||||
* @since v0.1.0
|
||||
* @author iClyde <kontakt@iclyde.pl>
|
||||
*/
|
||||
|
||||
// Namespace
|
||||
namespace Inisev\Subs;
|
||||
|
||||
// Disallow direct access
|
||||
if (defined('ABSPATH')) {
|
||||
|
||||
/**
|
||||
* Main class for handling the Carousel
|
||||
*/
|
||||
if (!class_exists('Inisev\Subs\Inisev_Carousel')) {
|
||||
class Inisev_Carousel {
|
||||
|
||||
// Should hide it for good i.e. styles may be broken?
|
||||
private $error = 0;
|
||||
|
||||
// Slugs of plugins
|
||||
private $usm_premium = 'usm-premium/usm_premium_icons.php';
|
||||
private $usm_slug = 'ultimate-social-media-icons/ultimate_social_media_icons.php';
|
||||
private $bmi_premium = 'backup-backup-pro/backup-backup-pro.php';
|
||||
private $bmi_slug = 'backup-backup/backup-backup.php';
|
||||
private $cdp_premium = 'copy-delete-posts-premium/copy-delete-posts-premium.php';
|
||||
private $cdp_slug = 'copy-delete-posts/copy-delete-posts.php';
|
||||
private $mpu_slug = 'pop-up-pop-up/pop-up-pop-up.php';
|
||||
private $redi_slug = 'redirect-redirection/redirect-redirection.php';
|
||||
|
||||
// Global variables
|
||||
public $_root_file = null;
|
||||
public $_root_dir = null;
|
||||
public $page = null;
|
||||
public $slug = null;
|
||||
public $root = null;
|
||||
public $slug_low = null;
|
||||
public $hooked = null;
|
||||
public $menu = null;
|
||||
public $url = null;
|
||||
|
||||
/*
|
||||
* Compile some variables for "future us"
|
||||
* Such as slug of current plugin, root dir of plugin
|
||||
*/
|
||||
function __construct($root_file, $root_dir) {
|
||||
|
||||
// This roots
|
||||
$this->_root_file = $root_file;
|
||||
$this->_root_dir = $root_dir;
|
||||
|
||||
// Add handler for Ajax request
|
||||
if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
|
||||
// Check if slug is defined
|
||||
if (isset($_POST['slug']) && !empty($_POST['slug'])) {
|
||||
|
||||
// Handle the request
|
||||
add_action('wp_ajax_inisev_installation', [&$this, 'handle_installation']);
|
||||
add_action('wp_ajax_inisev_installation_widget', [&$this, 'handle_installation']);
|
||||
|
||||
}
|
||||
|
||||
// Stop for POST
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
// WordPress globals
|
||||
global $menu;
|
||||
|
||||
// Make sure WP_PLUGIN_DIR is defined
|
||||
if (!defined('WP_PLUGIN_DIR')) return $this->fail(1);
|
||||
if (!function_exists('trailingslashit')) return $this->fail(2);
|
||||
if (!defined('DIRECTORY_SEPARATOR')) define('DIRECTORY_SEPARATOR', '/');
|
||||
|
||||
// That's in case the developer moved this file somewhere else
|
||||
$tmp_slug = trailingslashit($this->_root_dir);
|
||||
$tmp_root = trailingslashit(WP_PLUGIN_DIR);
|
||||
$tmp_name = explode(DIRECTORY_SEPARATOR, substr($tmp_slug, strlen($tmp_root)));
|
||||
|
||||
// Make the "probably" slug name
|
||||
$this->page = sanitize_text_field($_GET['page']);
|
||||
$this->slug = $tmp_name[0];
|
||||
$this->root = $tmp_root . $this->slug;
|
||||
|
||||
// Make lowercase slug
|
||||
$this->slug_low = $this->makelower($this->slug);
|
||||
|
||||
// We don't need those anymore
|
||||
unset($tmp_slug, $tmp_root, $tmp_name);
|
||||
|
||||
// Check if the guess is correct enough
|
||||
if (!is_dir($this->root)) return $this->fail(3);
|
||||
|
||||
// Check if the script requires to be in hook
|
||||
if (!function_exists('current_action')) return $this->fail(4);
|
||||
$this->hooked = (current_action() == '' ? false : true);
|
||||
|
||||
// Add hook if it's required
|
||||
if (!$this->hooked) {
|
||||
|
||||
// Hook the script to init
|
||||
add_action('admin_menu', [&$this, 'setup'], PHP_INT_MAX);
|
||||
|
||||
} else {
|
||||
|
||||
// The child plugin is already hooked, check if correctly
|
||||
if (current_action() == 'admin_menu' || isset($menu)) {
|
||||
|
||||
// If the hook is correct continue
|
||||
$this->setup();
|
||||
|
||||
} else {
|
||||
|
||||
// Hook the script to init if it's not hooked to it already
|
||||
add_action('admin_menu', [&$this, 'setup'], PHP_INT_MAX);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Main setup of this child plugin
|
||||
*/
|
||||
public function setup() {
|
||||
|
||||
// WordPress Global Variables
|
||||
global $menu;
|
||||
|
||||
// Make sure $menu exists
|
||||
if (!isset($menu) || !is_array($menu)) return $this->fail(5);
|
||||
if (!current_user_can('install_plugins')) return $this->fail(10);
|
||||
|
||||
// Get menu slug name
|
||||
if (!$this->menu_name($menu)) return false;
|
||||
|
||||
if (/*$this->page === $this->menu && */!defined('INISEV_CAROUSEL')) {
|
||||
|
||||
// Initialize Carousel constant
|
||||
define('INISEV_CAROUSEL', true);
|
||||
|
||||
// Root URL for assets
|
||||
$this->url = trailingslashit(plugins_url('', $this->_root_file));
|
||||
|
||||
// Load styles
|
||||
// wp_enqueue_script('inisev-carousel-script', ($this->url . 'assets/index.min.js'), [], filemtime($this->_root_dir . '/assets/index.min.js'), true);
|
||||
// wp_enqueue_style('inisev-carousel-style', ($this->url . 'assets/style.min.css'), [], filemtime($this->_root_dir . '/assets/style.min.css'));
|
||||
|
||||
// Pass nonce to JS
|
||||
// wp_localize_script('inisev-carousel-script', 'inisev_carousel', [
|
||||
// 'nonce' => wp_create_nonce('inisev_carousel'),
|
||||
// ], true);
|
||||
|
||||
// Print the footer
|
||||
if (!has_action('ins_global_print_carrousel')) {
|
||||
add_action('ins_global_print_carrousel', [&$this, '_print'], 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* This function may be used for debugging purposes
|
||||
*/
|
||||
private function fail($code = false) {
|
||||
|
||||
if ($code === false) {
|
||||
|
||||
// Return error code if specified as request ($code === false)
|
||||
return $this->error;
|
||||
|
||||
} else {
|
||||
|
||||
// Set the error code and return
|
||||
// error_log($code);
|
||||
$this->error = $code;
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper function remove _ -/ characters and make lowercase
|
||||
*/
|
||||
private function makelower($str) {
|
||||
|
||||
if (!is_string($str) || empty($str)) $str = '';
|
||||
|
||||
$str = str_replace('_', '', $str);
|
||||
$str = str_replace('-', '', $str);
|
||||
$str = str_replace('/', '', $str);
|
||||
$str = str_replace('\/', '', $str);
|
||||
$str = str_replace(' ', '', $str);
|
||||
$str = strtolower($str);
|
||||
|
||||
return $str;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* This function will find slug of menu page
|
||||
*/
|
||||
private function menu_name(&$menu) {
|
||||
|
||||
// Find the menu slug
|
||||
// IMPORTANT: It requires the plugin to use own icon (own assets)
|
||||
foreach ($menu as $priority => $details) {
|
||||
if (is_array($details) && sizeof($details) >= 6) {
|
||||
foreach ($details as $key => $value) {
|
||||
if (is_object($value) || is_array($value)) continue;
|
||||
if ($this->makelower($value) == $this->slug_low) {
|
||||
$this->menu = $details[2];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isset($this->menu)) break;
|
||||
}
|
||||
}
|
||||
|
||||
// MyPopUps exception
|
||||
if (!isset($this->menu)) {
|
||||
$mpu = ['wpmypopups', 'mypopups', 'popuppopup'];
|
||||
if (in_array($this->slug_low, $mpu)) {
|
||||
$this->menu = 'wp-mypopups';
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($this->menu)) {
|
||||
$bmi = ['backupbackup', 'backup-backup', 'backup-migration', 'backupmigration'];
|
||||
if (in_array($this->slug_low, $bmi)) {
|
||||
$this->menu = 'backup-migration';
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($this->menu)) {
|
||||
$hhr = ['httpsremover', 'httphttpsremover'];
|
||||
if (in_array($this->slug_low, $hhr)) {
|
||||
$this->menu = 'httphttpsRemoval';
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($this->menu)) {
|
||||
$wpc = ['wp-clone', 'wp-clone', 'wpclonebywpacademy'];
|
||||
if (in_array($this->slug_low, $wpc)) {
|
||||
$this->menu = 'wp-clone';
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure it found something
|
||||
if (isset($this->menu)) return true;
|
||||
else return true;
|
||||
// else return $this->fail(6);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper: Include file
|
||||
*/
|
||||
private function _include($path) {
|
||||
|
||||
include_once trailingslashit($this->_root_dir) . 'views/' . $path . '.php';
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper: Get asset URL
|
||||
*/
|
||||
private function get_asset($file) {
|
||||
|
||||
return $this->url . $file;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper: Get asset and print URL
|
||||
*/
|
||||
private function _asset($file) {
|
||||
|
||||
echo $this->get_asset('views/' . $file);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Upgrade plugin, this function probably will never be fired
|
||||
*/
|
||||
private function upgrade_plugin($plugin_slug) {
|
||||
|
||||
// Include upgrader
|
||||
include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
|
||||
wp_cache_flush();
|
||||
|
||||
// Initialize & upgrade the plugin
|
||||
$upgrader = new \Plugin_Upgrader();
|
||||
$upgraded = $upgrader->upgrade($plugin_slug);
|
||||
|
||||
// Return status or WP Error
|
||||
return $upgraded;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if plugin is installed by slug
|
||||
*/
|
||||
private function is_plugin_installed($slug) {
|
||||
|
||||
// Get all plugins
|
||||
$all_plugins = get_plugins();
|
||||
|
||||
// Make sure all slugs are in lowercase.
|
||||
foreach ($all_plugins as $plug => $v) {
|
||||
|
||||
// Once something match return success
|
||||
if (strtolower($plug) == strtolower($slug)) return true;
|
||||
|
||||
}
|
||||
|
||||
// If nothing just fail
|
||||
return false;
|
||||
|
||||
// When I exactly know the letter case...
|
||||
// if (!empty($all_plugins[$slug])) return true;
|
||||
// else return false;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Install the plugin by slug
|
||||
*/
|
||||
private function install_plugin($plugin_zip) {
|
||||
|
||||
// Include upgrader
|
||||
include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
|
||||
wp_cache_flush();
|
||||
|
||||
// Initialize WP upgrader & install the plugin
|
||||
$upgrader = new \Plugin_Upgrader();
|
||||
$installed = $upgrader->install($plugin_zip);
|
||||
|
||||
// Return status or WP Error
|
||||
return $installed;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Install file
|
||||
*/
|
||||
private function install($slug, $directory_slug) {
|
||||
|
||||
// Prepare the URLs and full slug
|
||||
$plugin_slug = $slug;
|
||||
$plugin_zip = 'https://downloads.wordpress.org/plugin/' . $directory_slug . '.latest-stable.zip';
|
||||
|
||||
// Make sure the plugin is not installed
|
||||
if ($this->is_plugin_installed($plugin_slug)) {
|
||||
|
||||
// Upgrade the plugin if it's installed somehow
|
||||
$this->upgrade_plugin($plugin_slug);
|
||||
$installed = true;
|
||||
|
||||
// Install instead
|
||||
} else $installed = $this->install_plugin($plugin_zip);
|
||||
|
||||
// Check if there was any error
|
||||
if (!is_wp_error($installed) && $installed) {
|
||||
$activate = activate_plugin($plugin_slug);
|
||||
|
||||
if (is_null($activate)) {
|
||||
|
||||
$url = admin_url('', 'admin');
|
||||
|
||||
// CDP has special alert when installed with quick-install module
|
||||
if ($_POST['slug'] === 'cdp') {
|
||||
update_option('_cdp_cool_installation', true);
|
||||
update_option('_cdp_redirect', true);
|
||||
$url = admin_url() . 'admin.php?page=copy-delete-posts';
|
||||
}
|
||||
|
||||
// Redirection for MPU
|
||||
if ($_POST['slug'] === 'mpu') {
|
||||
update_option('wp_mypopups_do_activation_redirect', true);
|
||||
$url = admin_url() . 'admin.php?page=wp-mypopups';
|
||||
}
|
||||
|
||||
// Redirection for USM
|
||||
if ($_POST['slug'] === 'usm') {
|
||||
update_option('sfsi_plugin_do_activation_redirect', true);
|
||||
$url = admin_url() . 'admin.php?page=sfsi-options';
|
||||
}
|
||||
|
||||
// Redirection for BMI
|
||||
if ($_POST['slug'] === 'bmi') {
|
||||
update_option('_bmi_redirect', true);
|
||||
$url = admin_url() . 'admin.php?page=backup-migration';
|
||||
}
|
||||
|
||||
// Redirection for RED
|
||||
if ($_POST['slug'] === 'redi') {
|
||||
update_option('irrp_activation_redirect', true);
|
||||
$url = admin_url() . 'admin.php?page=irrp-redirection';
|
||||
}
|
||||
|
||||
// Send success
|
||||
wp_send_json_success([ 'installed' => true, 'url' => $url ]);
|
||||
|
||||
// I don't know what happened here and if it's even possible
|
||||
} else wp_send_json_error();
|
||||
|
||||
// Send fail
|
||||
} else wp_send_json_error();
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Add/print the Carousel
|
||||
*/
|
||||
public function _print() {
|
||||
|
||||
try {
|
||||
|
||||
include_once trailingslashit($this->_root_dir) . 'views/index.php';
|
||||
|
||||
} catch (\Exception $e) {
|
||||
|
||||
return $this->fail(7);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
|
||||
return $this->fail(8);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle ajax request
|
||||
*/
|
||||
public function handle_installation() {
|
||||
|
||||
if (check_ajax_referer('inisev_carousel', 'nonce', false) === false) {
|
||||
return wp_send_json_error();
|
||||
}
|
||||
|
||||
if (!current_user_can('install_plugins')) {
|
||||
return wp_send_json_error();
|
||||
}
|
||||
|
||||
// Handle the slug and install the plugin
|
||||
$slug = sanitize_text_field($_POST['slug']);
|
||||
if ($slug === 'usm') {
|
||||
|
||||
$this->install($this->usm_slug, 'ultimate-social-media-icons');
|
||||
|
||||
} elseif ($slug === 'bmi') {
|
||||
|
||||
$this->install($this->bmi_slug, 'backup-backup');
|
||||
|
||||
} elseif ($slug === 'cdp') {
|
||||
|
||||
$this->install($this->cdp_slug, 'copy-delete-posts');
|
||||
|
||||
} elseif ($slug === 'mpu') {
|
||||
|
||||
$this->install($this->mpu_slug, 'pop-up-pop-up');
|
||||
|
||||
} elseif ($slug == 'redi') {
|
||||
|
||||
$this->install($this->redi_slug, 'redirect-redirection');
|
||||
|
||||
// Anything else error
|
||||
} else wp_send_json_error();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Disallow usage of multiple Carousels + allow only GET requests
|
||||
if (!defined('INISEV_CAROUSEL')) {
|
||||
|
||||
// Make sure settings/menu page slug exsits
|
||||
if (!empty($_GET['page']) || (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] === 'POST')) {
|
||||
|
||||
// Initialize the Carousel
|
||||
$carousel = new Inisev_Carousel(__FILE__, __DIR__);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
152
wp-content/plugins/copy-delete-posts/banner/views/index.php
Normal file
@@ -0,0 +1,152 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Main renderer for the Carousel
|
||||
*
|
||||
* @category Child Plugin
|
||||
* @author iClyde <kontakt@iclyde.pl>
|
||||
*/
|
||||
|
||||
// Namespace
|
||||
namespace Inisev\Subs;
|
||||
|
||||
// Disallow direct access
|
||||
if (!defined('ABSPATH')) exit;
|
||||
|
||||
?>
|
||||
<script type="text/javascript" charset="utf-8">
|
||||
var inisev_carousel = { nonce: `<?php echo wp_create_nonce('inisev_carousel'); ?>` };
|
||||
</script>
|
||||
<script src="<?php echo $this->url . 'assets/index.min.js?v=' . filemtime($this->_root_dir . '/assets/index.min.js'); ?>" type="text/javascript" charset="utf-8" defer></script>
|
||||
<link rel="stylesheet" type="text/css" href="<?php echo $this->url . 'assets/style.min.css?v=' . filemtime($this->_root_dir . '/assets/style.min.css'); ?>">
|
||||
<section class="ci-carrinis-wrapper">
|
||||
<section class="ci-carrinis" id="carrinis">
|
||||
<h1>Like this plugin?</h1>
|
||||
<h1>Then you'll LOVE our others too :)</h1>
|
||||
<div class="ci-carousel">
|
||||
<?php $this->_include('static/tabs'); ?>
|
||||
<div class="ci-project-content">
|
||||
<?php
|
||||
|
||||
$bmi_free = $this->is_plugin_installed($this->bmi_slug);
|
||||
$bmi_pro = $this->is_plugin_installed($this->bmi_premium);
|
||||
$bmi_state = (!$bmi_free || (!$bmi_free && $bmi_pro)) ? 'install' : (($bmi_free && !$bmi_pro) ? 'upgrade' : 'already-installed')
|
||||
|
||||
?>
|
||||
<div class="ci-project ci-project-BackupMigration <?php echo 'ci-'.$bmi_state.'-state-visible'; ?>">
|
||||
<?php
|
||||
|
||||
if (!$bmi_free || (!$bmi_free && $bmi_pro)) {
|
||||
$this->_include('projects/bmi/install');
|
||||
} elseif ($bmi_free && !$bmi_pro) {
|
||||
$this->_include('projects/bmi/upgrade');
|
||||
} elseif ($bmi_free && $bmi_pro) {
|
||||
$this->_include('projects/bmi/installed');
|
||||
}
|
||||
|
||||
?>
|
||||
<div class="ci-right-part">
|
||||
<img src="<?php $this->_asset('/projects/bmi/imgs/background-images.png'); ?>" class="ci-main-image">
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
|
||||
$mpu_plugin = $this->is_plugin_installed($this->mpu_slug);
|
||||
$mpu_state = $mpu_plugin ? 'already-installed' : 'install';
|
||||
|
||||
?>
|
||||
<div class="ci-project ci-project-MyPopups <?php echo 'ci-'.$mpu_state.'-state-visible'; ?>">
|
||||
<?php
|
||||
|
||||
if ($mpu_plugin) {
|
||||
$this->_include('projects/mpu/installed');
|
||||
} else {
|
||||
$this->_include('projects/mpu/install');
|
||||
}
|
||||
|
||||
?>
|
||||
<div class="ci-right-part">
|
||||
<img src="<?php $this->_asset('/projects/mpu/imgs/background-images.png'); ?>" class="ci-main-image">
|
||||
<img src="<?php $this->_asset('/projects/mpu/imgs/background-texture-green.png'); ?>" class="ci-secondary-image">
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
|
||||
$cdp_free = $this->is_plugin_installed($this->cdp_slug);
|
||||
$cdp_pro = $this->is_plugin_installed($this->cdp_premium);
|
||||
$cdp_state = (!$cdp_free || (!$cdp_free && $cdp_pro)) ? 'install' : (($cdp_free && !$cdp_pro) ? 'upgrade' : 'already-installed');
|
||||
|
||||
?>
|
||||
<div class="ci-project ci-project-CopyDeletePosts <?php echo 'ci-'.$cdp_state.'-state-visible'; ?>">
|
||||
<?php
|
||||
|
||||
if (!$cdp_free || (!$cdp_free && $cdp_pro)) {
|
||||
$this->_include('projects/cdp/install');
|
||||
} elseif ($cdp_free && !$cdp_pro) {
|
||||
$this->_include('projects/cdp/upgrade');
|
||||
} elseif ($cdp_free && $cdp_pro) {
|
||||
$this->_include('projects/cdp/installed');
|
||||
}
|
||||
|
||||
?>
|
||||
<div class="ci-right-part">
|
||||
<img src="<?php $this->_asset('/projects/cdp/imgs/secondary-background-image.svg'); ?>" class="ci-secondary-image">
|
||||
<img src="<?php $this->_asset('/projects/cdp/imgs/main-background-image.png'); ?>" class="ci-main-image">
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
|
||||
$redi_plugin = $this->is_plugin_installed($this->redi_slug);
|
||||
$redi_state = $redi_plugin ? 'already-installed' : 'install';
|
||||
|
||||
?>
|
||||
<div class="ci-project ci-project-redRed ci-<?php echo $redi_state; ?>-state-visible">
|
||||
<?php
|
||||
if ($redi_state == 'install') {
|
||||
$this->_include('projects/red/install');
|
||||
} else {
|
||||
$this->_include('projects/red/installed');
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<div class="ci-project ci-project-TasteWP ci-install-state-visible">
|
||||
<?php $this->_include('projects/twp/install'); ?>
|
||||
<div class="ci-right-part">
|
||||
<img src="<?php $this->_asset('/projects/twp/imgs/background-image-1.svg'); ?>">
|
||||
<img src="<?php $this->_asset('/projects/twp/imgs/background-image-2.svg'); ?>">
|
||||
<img src="<?php $this->_asset('/projects/twp/imgs/background-image-3.svg'); ?>">
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
|
||||
$usm_free = $this->is_plugin_installed($this->usm_slug);
|
||||
$usm_pro = $this->is_plugin_installed($this->usm_premium);
|
||||
$usm_state = (!$usm_free || (!$usm_free && $usm_pro)) ? 'install' : (($usm_free && !$usm_pro) ? 'upgrade' : 'already-installed');
|
||||
|
||||
?>
|
||||
<div class="ci-project ci-project-SocialShare <?php echo 'ci-'.$usm_state.'-state-visible'; ?>">
|
||||
<?php
|
||||
|
||||
if (!$usm_free || (!$usm_free && $usm_pro)) {
|
||||
$this->_include('projects/usm/install');
|
||||
$this->_include('projects/usm/part-install');
|
||||
} elseif ($usm_free && !$usm_pro) {
|
||||
$this->_include('projects/usm/upgrade');
|
||||
$this->_include('projects/usm/part-upgrade');
|
||||
} elseif ($usm_free && $usm_pro) {
|
||||
$this->_include('projects/usm/part-install');
|
||||
$this->_include('projects/usm/installed');
|
||||
}
|
||||
|
||||
?>
|
||||
</div>
|
||||
<div class="ci-project ci-project-followIt ci-install-state-visible">
|
||||
<?php $this->_include('projects/fit/install'); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ci-all-projects">
|
||||
<a class="ci-see-all-projects" href="https://inisev.com/?utm_source=plugin_footer&utm_campaign=CDP&utm_medium=carrousel" target="_blank">See all projects</a>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
|
After Width: | Height: | Size: 4.1 KiB |
|
After Width: | Height: | Size: 5.0 KiB |
|
After Width: | Height: | Size: 871 B |
@@ -0,0 +1,4 @@
|
||||
<svg width="27" height="28" viewBox="0 0 27 28" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M13.5991 0.648193C11.8006 0.648193 10.0877 1.00301 8.53385 1.63922V14.9264C8.68067 17.7894 11.0542 20.0651 13.9539 20.0651C15.7035 20.0651 17.2696 19.2331 18.2606 17.9362C18.0159 19.3065 17.3552 20.6156 16.303 21.6801C14.7859 23.1972 12.6081 24.0414 10.467 23.5887C10.1856 23.5276 9.9164 23.4541 9.65946 23.3563C8.05669 22.7812 6.68637 21.5822 5.74428 20.1996C4.6309 18.5602 4.03139 16.6148 4.03139 14.6327C4.03139 14.4982 4.03139 14.3758 4.04362 14.2412V4.67349C1.68228 7.08378 0.226318 10.375 0.226318 14.021C0.226318 21.4109 6.20921 27.3938 13.5991 27.3938C20.989 27.3938 26.9719 21.4109 26.9719 14.021C26.9719 6.63108 20.9768 0.648193 13.5991 0.648193Z" fill="#0F9990"/>
|
||||
<path d="M14.896 24.5186C15.8014 24.1026 16.6456 23.5276 17.3919 22.7812C19.3984 20.7747 20.2304 17.6181 19.79 14.8407C19.3862 12.3326 17.3307 9.17596 14.4678 9.23714C14.4678 9.70207 14.4678 10.1792 14.4678 10.6442C14.4678 10.8399 14.3332 11.8432 14.4678 11.9778C14.3943 11.8921 9.76953 7.26731 9.76953 7.26731L14.4678 2.56909V4.73468C19.7043 5.00385 23.8764 9.34725 23.8764 14.645C23.8764 19.7959 19.9245 24.0414 14.896 24.5186Z" fill="#55BDBD"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
@@ -0,0 +1,4 @@
|
||||
<svg width="27" height="28" viewBox="0 0 27 28" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M13.5991 0.648193C11.8006 0.648193 10.0877 1.00301 8.53385 1.63922V14.9264C8.68067 17.7894 11.0542 20.0651 13.9539 20.0651C15.7035 20.0651 17.2696 19.2331 18.2606 17.9362C18.0159 19.3065 17.3552 20.6156 16.303 21.6801C14.7859 23.1972 12.6081 24.0414 10.467 23.5887C10.1856 23.5276 9.9164 23.4541 9.65946 23.3563C8.05669 22.7812 6.68637 21.5822 5.74428 20.1996C4.6309 18.5602 4.03139 16.6148 4.03139 14.6327C4.03139 14.4982 4.03139 14.3758 4.04362 14.2412V4.67349C1.68228 7.08378 0.226318 10.375 0.226318 14.021C0.226318 21.4109 6.20921 27.3938 13.5991 27.3938C20.989 27.3938 26.9719 21.4109 26.9719 14.021C26.9719 6.63108 20.9768 0.648193 13.5991 0.648193Z" fill="white"/>
|
||||
<path d="M14.896 24.5186C15.8014 24.1026 16.6456 23.5276 17.3919 22.7812C19.3984 20.7747 20.2304 17.6181 19.79 14.8407C19.3862 12.3326 17.3307 9.17596 14.4678 9.23714C14.4678 9.70207 14.4678 10.1792 14.4678 10.6442C14.4678 10.8399 14.3332 11.8432 14.4678 11.9778C14.3943 11.8921 9.76953 7.26731 9.76953 7.26731L14.4678 2.56909V4.73468C19.7043 5.00385 23.8764 9.34725 23.8764 14.645C23.8764 19.7959 19.9245 24.0414 14.896 24.5186Z" fill="#55BDBD"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
// Namespace
|
||||
namespace Inisev\Subs;
|
||||
|
||||
// Disallow direct access
|
||||
if (!defined('ABSPATH')) exit;
|
||||
|
||||
?>
|
||||
|
||||
<div class="ci-left-part ci-install-state">
|
||||
<div class="ci-project-logo">
|
||||
<a href="https://backupbliss.com" target="_blank">
|
||||
<div class="ci-project-logo-element">
|
||||
<img src="<?php $this->_asset('/projects/bmi/imgs/big-colored-logo.png'); ?>">
|
||||
<span><b>Backup</b> &<br>Clone & Migration</span>
|
||||
</div>
|
||||
</a>
|
||||
<img src="<?php $this->_asset('/static/imgs/rating.svg'); ?>" class="ci-rating" >
|
||||
</div>
|
||||
<div class="ci-install-column">
|
||||
<ul class="ci-checkmark-list ci-checkmark-list-type-1">
|
||||
<li>Create backups & migrate your site</li>
|
||||
<li>Don't lose your work / switch to another host with ease</li>
|
||||
<li><b>Free</b> <span class="ci-light-font">(optional upgrade to <a href="https://backupbliss.com" target="_blank">premium</a>)</span></li>
|
||||
</ul>
|
||||
<div class="ci-install-button">
|
||||
<button class="ci-inisev-install-plugin" data-slug="bmi">Install plugin now</button>
|
||||
<span>(from <a href="https://wordpress.org/plugins/backup-backup/" target="_blank">WP directory</a>)</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
// Namespace
|
||||
namespace Inisev\Subs;
|
||||
|
||||
// Disallow direct access
|
||||
if (!defined('ABSPATH')) exit;
|
||||
|
||||
?>
|
||||
|
||||
<div class="ci-left-part ci-already-installed-state">
|
||||
<div class="ci-already-installed-heading">
|
||||
<svg width="42" height="42" viewBox="0 0 42 42" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M40.7975 5.74273C40.1757 5.1268 39.1785 5.1268 38.5567 5.74273L19.5688 24.6779L12.7232 17.24C12.1307 16.5947 11.1276 16.5536 10.4824 17.1461C9.843 17.7385 9.802 18.7416 10.3945 19.381L18.3603 28.0332C18.6478 28.35 19.0584 28.5318 19.4866 28.5436C19.4984 28.5436 19.51 28.5436 19.5218 28.5436C19.9441 28.5436 20.343 28.3793 20.6422 28.0802L40.7916 7.98351C41.4134 7.36759 41.4134 6.36451 40.7975 5.74273ZM40.4162 19.4162C39.5421 19.4162 38.8324 20.126 38.8324 21C38.8324 30.8313 30.8313 38.8324 21 38.8324C11.1687 38.8324 3.16761 30.8313 3.16761 21C3.16761 11.1687 11.1687 3.16758 21 3.16758C21.874 3.16758 22.5838 2.45783 22.5838 1.58381C22.5838 0.709784 21.874 0 21 0C9.42069 0 0 9.42067 0 21C0 32.5793 9.42069 42 21 42C32.5793 42 42 32.5793 42 21C42 20.126 41.2902 19.4162 40.4162 19.4162Z" fill="#6BB4A7"/>
|
||||
</svg>
|
||||
<p><span class="ci-colored-part">Already installed –</span> now <b>earn affiliate commissions!</b></p>
|
||||
</div>
|
||||
<p>If you share this plugin, you’ll earn 40% (!) of every sale you helped to generate!</p>
|
||||
<p>Just go to <a href="https://sellcodes.com/oZxnXtc2" target="_blank">Sellcodes</a>, click on “Share & earn cash” (next to the title) and follow the steps :)</p>
|
||||
<div class="ci-check-it-out-button">
|
||||
<a href="https://sellcodes.com/oZxnXtc2" target="_blank" class="ci-button-link ci-round-button">Check it out</a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
// Namespace
|
||||
namespace Inisev\Subs;
|
||||
|
||||
// Disallow direct access
|
||||
if (!defined('ABSPATH')) exit;
|
||||
|
||||
?>
|
||||
|
||||
<div class="ci-left-part ci-upgrade-state">
|
||||
<h2>Don’t forget to <b>upgrade to premium</b> for the backup plugin :)</h2>
|
||||
<div class="ci-pros-list">
|
||||
<div class="ci-pros-list-column">
|
||||
<ul class="ci-checkmark-list ci-checkmark-list-type-2">
|
||||
<li>Unlimited backup size</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="ci-pros-list-column">
|
||||
<ul class="ci-checkmark-list ci-checkmark-list-type-2">
|
||||
<li>Top support</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<h2><b>Coming soon:</b></h2>
|
||||
<div class="ci-pros-list">
|
||||
<div class="ci-pros-list-column">
|
||||
<ul class="ci-timer-list">
|
||||
<li>External storage</li>
|
||||
<li>Encryption</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="ci-pros-list-column">
|
||||
<ul class="ci-timer-list">
|
||||
<li>Smart exclusion rules</li>
|
||||
<li class="ci-no-clock ci-fancy-signature">...and so <a href="https://backupbliss.com" target="_blank" class="ci-green-text">much more!</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ci-submit-button-row">
|
||||
<div class="ci-submit-button-wrapper">
|
||||
<a href="https://backupbliss.com" target="_blank" class="ci-button-link ci-round-button ci-no-arrow">Upgrade now</a>
|
||||
<div class="ci-learn-more-button">
|
||||
<a href="https://backupbliss.com" target="_blank">Learn more</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
After Width: | Height: | Size: 5.0 KiB |