first commit
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace OTGS\Installer\AdminNotices;
|
||||
|
||||
class Config {
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $config;
|
||||
|
||||
public function __construct( array $config ) {
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $messages
|
||||
* @param string $item
|
||||
* @param string $type
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function hasItem( array $messages, $item, $type ) {
|
||||
foreach ( $messages['repo'] as $repo => $ids ) {
|
||||
foreach ( $ids as $id => $noticeType ) {
|
||||
$index = is_array( $noticeType ) ? $id : $noticeType;
|
||||
|
||||
if ( isset( $this->config['repo'][ $repo ][ $index ][ $type ] )
|
||||
&& in_array( $item, $this->config['repo'][ $repo ][ $index ][ $type ], true ) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
namespace OTGS\Installer\AdminNotices;
|
||||
|
||||
class Dismissed {
|
||||
const STORE_KEY = 'dismissed';
|
||||
|
||||
/**
|
||||
* @param array $dismissedNotices
|
||||
* @param string $repo
|
||||
* @param string $id
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function isDismissed( array $dismissedNotices, $repo, $id ) {
|
||||
return isset( $dismissedNotices['repo'][ $repo ][ $id ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $dismissedNotices
|
||||
* @param callable $timeOut - int -> string -> string -> bool
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function clearExpired( array $dismissedNotices, callable $timeOut ) {
|
||||
if ( isset( $dismissedNotices['repo'] ) ) {
|
||||
|
||||
foreach ( $dismissedNotices['repo'] as $repo => $ids ) {
|
||||
foreach ( $ids as $id => $dismissedTimeStamp ) {
|
||||
if ( $timeOut( $dismissedTimeStamp, $repo, $id ) ) {
|
||||
unset ( $dismissedNotices['repo'][ $repo ][ $id ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $dismissedNotices;
|
||||
}
|
||||
|
||||
public static function dismissNotice() {
|
||||
$data = filter_var_array( $_POST, [
|
||||
'repository' => FILTER_SANITIZE_FULL_SPECIAL_CHARS,
|
||||
'noticeType' => FILTER_SANITIZE_FULL_SPECIAL_CHARS,
|
||||
'noticePluginSlug' => FILTER_SANITIZE_FULL_SPECIAL_CHARS,
|
||||
] );
|
||||
|
||||
$dismissions = apply_filters( 'otgs_installer_admin_notices_dismissions', [] );
|
||||
|
||||
$store = new Store();
|
||||
|
||||
$dismissed = $store->get( self::STORE_KEY, [] );
|
||||
|
||||
$dismissed = $dismissions[ $data['noticeType'] ]( $dismissed, $data );
|
||||
|
||||
$store->save( self::STORE_KEY, $dismissed );
|
||||
|
||||
wp_send_json_success( [] );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
namespace OTGS\Installer\AdminNotices;
|
||||
|
||||
class Display {
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $currentNotices;
|
||||
/**
|
||||
* @var PageConfig
|
||||
*/
|
||||
private $pageConfig;
|
||||
/**
|
||||
* @var MessageTexts
|
||||
*/
|
||||
private $messageTexts;
|
||||
/**
|
||||
* @var callable - string -> string -> bool
|
||||
*/
|
||||
private $isDismissed;
|
||||
/**
|
||||
* @var ScreenConfig
|
||||
*/
|
||||
private $screenConfig;
|
||||
|
||||
public function __construct(
|
||||
array $currentNotices,
|
||||
array $config,
|
||||
MessageTexts $messageTexts,
|
||||
callable $isDismissed
|
||||
) {
|
||||
$this->currentNotices = $currentNotices;
|
||||
$this->pageConfig = new PageConfig( $config );
|
||||
$this->screenConfig = new ScreenConfig( $config );
|
||||
$this->messageTexts = $messageTexts;
|
||||
$this->isDismissed = $isDismissed;
|
||||
}
|
||||
|
||||
public function addHooks() {
|
||||
if ( ! empty( $this->currentNotices ) && $this->isRelevantOnPage() ) {
|
||||
add_action( 'admin_notices', [ $this, 'addNotices' ] );
|
||||
add_action( 'admin_enqueue_scripts', [ $this, 'addScripts' ] );
|
||||
}
|
||||
}
|
||||
|
||||
public function addNotices() {
|
||||
foreach ( $this->currentNotices['repo'] as $repo => $ids ) {
|
||||
foreach ( $ids as $id => $type ) {
|
||||
if ( is_array( $type ) ) {
|
||||
$index = $id;
|
||||
$noticesData = $type;
|
||||
} else {
|
||||
$index = $type;
|
||||
$noticesData = [ $type ];
|
||||
}
|
||||
|
||||
if ( $this->pageConfig->shouldShowMessage( $repo, $index ) || $this->screenConfig->shouldShowMessage( $repo, $index ) ) {
|
||||
foreach ( $noticesData as $noticeData ) {
|
||||
$this->displayNotice( $repo, $index, $noticeData );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function isRelevantOnPage() {
|
||||
return $this->pageConfig->isAnyMessageOnPage( $this->currentNotices ) ||
|
||||
$this->screenConfig->isAnyMessageOnPage( $this->currentNotices );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $repo
|
||||
* @param string $ids
|
||||
*/
|
||||
private function displayNotice( $repo, $id, $notice_params = [] ) {
|
||||
$noticeId = $id;
|
||||
if ( isset( $notice_params['noticeId'] ) ) {
|
||||
$noticeId = $notice_params['noticeId'];
|
||||
}
|
||||
if ( ! call_user_func( $this->isDismissed, $repo, $noticeId ) ) {
|
||||
$html = $this->messageTexts->get( $repo, $id, $notice_params );
|
||||
if ( $html ) {
|
||||
echo $html;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function addScripts() {
|
||||
$installer = OTGS_Installer();
|
||||
wp_enqueue_style(
|
||||
'installer-admin-notices',
|
||||
$installer->res_url() . '/res/css/admin-notices.css',
|
||||
[],
|
||||
$installer->version()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
|
||||
namespace OTGS\Installer\AdminNotices;
|
||||
|
||||
use function OTGS\Installer\FP\partial;
|
||||
|
||||
class Loader {
|
||||
|
||||
/**
|
||||
* @param bool $isAjax
|
||||
*/
|
||||
public static function addHooks( $isAjax ) {
|
||||
add_action( 'current_screen', self::class . '::initDisplay' );
|
||||
if ( $isAjax ) {
|
||||
add_action( 'wp_ajax_installer_dismiss_nag', Dismissed::class . '::dismissNotice' );
|
||||
}
|
||||
}
|
||||
|
||||
public static function initDisplay() {
|
||||
|
||||
remove_action( 'current_screen', self::class . '::initDisplay' );
|
||||
|
||||
/**
|
||||
* Filter and return installer admin notices
|
||||
*
|
||||
* @param array - an associative array of messages keyed by repository
|
||||
* eg.
|
||||
* [ 'repo' => [ 'wpml' = [ 'message_id_1', 'message_id_2' ... ] ] ]
|
||||
*/
|
||||
$messages = apply_filters( 'otgs_installer_admin_notices', [] );
|
||||
|
||||
if ( ! empty( $messages ) ) {
|
||||
|
||||
/**
|
||||
* Filter and return configuration of where messages should be displayed
|
||||
*
|
||||
* @param array - an associative array keyed by repository
|
||||
* eg.
|
||||
* [ 'repo' => [ 'wpml' => [
|
||||
* 'message_id_1' => [
|
||||
* 'screens' => [ 'plugins', 'dashboard', ... ],
|
||||
* 'pages' => [ 'sitepress-multilingual-cms/menu/languages.php', ... ]
|
||||
* ],
|
||||
* ...
|
||||
* ] ] ]
|
||||
*/
|
||||
$config = apply_filters( 'otgs_installer_admin_notices_config', [] );
|
||||
|
||||
/**
|
||||
* Filter and return callback functions for retrieving the text for each message
|
||||
* The message id is passed to the callback function
|
||||
*
|
||||
* @param array - an associative array keyed by repository
|
||||
* eg.
|
||||
* [ 'repo' => [ 'wpml' => [
|
||||
* 'message_id_1' => some_callback_function,
|
||||
* 'message_id_2' => some_callback_function,
|
||||
* ] ] ]
|
||||
*
|
||||
*/
|
||||
$texts = apply_filters( 'otgs_installer_admin_notices_texts', [] );
|
||||
|
||||
$dismissedNotices = self::refreshDismissed();
|
||||
|
||||
( new Display(
|
||||
$messages,
|
||||
$config,
|
||||
new MessageTexts( $texts ),
|
||||
partial( Dismissed::class . '::isDismissed', $dismissedNotices )
|
||||
) )->addHooks();
|
||||
}
|
||||
}
|
||||
|
||||
public static function isDismissed( $repository_id, $notice_id ) {
|
||||
$remainigNotices = static::refreshDismissed();
|
||||
return Dismissed::isDismissed( $remainigNotices, $repository_id, $notice_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private static function refreshDismissed() {
|
||||
$store = new Store();
|
||||
|
||||
$dismissedMessages = $store->get( Dismissed::STORE_KEY, [] );
|
||||
$remainingMessages = Dismissed::clearExpired(
|
||||
$dismissedMessages,
|
||||
[ self::class, 'timeOut' ]
|
||||
);
|
||||
|
||||
if ( $dismissedMessages !== $remainingMessages ) {
|
||||
$store->save( Dismissed::STORE_KEY, $remainingMessages );
|
||||
}
|
||||
|
||||
return $remainingMessages;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $start
|
||||
* @param string $repo
|
||||
* @param string $id
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function timeOut( $start, $repo, $id ) {
|
||||
/**
|
||||
* Filters the default time that a notice stays dismissed for. The default is 2 months
|
||||
*
|
||||
* @param int $timeout
|
||||
* @param string $repo
|
||||
* @param string id - message id
|
||||
* return a timestamp in seconds. eg WEEK_IN_SECONDS, etc
|
||||
*/
|
||||
$timeout = apply_filters(
|
||||
'otgs_installer_admin_notices_dismissed_time',
|
||||
2 * MONTH_IN_SECONDS,
|
||||
$repo,
|
||||
$id
|
||||
);
|
||||
|
||||
return time() - $start > $timeout;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace OTGS\Installer\AdminNotices;
|
||||
|
||||
class MessageTexts {
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $messages;
|
||||
|
||||
/**
|
||||
* MessageTexts constructor.
|
||||
*
|
||||
* @param array $messages
|
||||
*/
|
||||
public function __construct( array $messages ) {
|
||||
$this->messages = $messages;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $repo
|
||||
* @param string $messageId
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function get( $repo, $messageId, $parameters = [] ) {
|
||||
if ( isset( $this->messages['repo'][ $repo ][ $messageId ] ) ) {
|
||||
if ( ! empty( $parameters ) ) {
|
||||
return call_user_func(
|
||||
$this->messages['repo'][ $repo ][ $messageId ],
|
||||
$parameters
|
||||
);
|
||||
} else {
|
||||
return call_user_func( $this->messages['repo'][ $repo ][ $messageId ], $messageId );
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace OTGS\Installer\AdminNotices;
|
||||
|
||||
class PageConfig extends Config {
|
||||
|
||||
/**
|
||||
* @param array $messages
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isAnyMessageOnPage( array $messages ) {
|
||||
if ( ! isset( $_GET['page'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->hasItem( $messages, $_GET['page'], 'pages' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $repo
|
||||
* @param string $id
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function shouldShowMessage( $repo, $id ) {
|
||||
if ( ! isset( $_GET['page'] ) ) {
|
||||
return false;
|
||||
}
|
||||
if ( isset( $this->config['repo'][ $repo ][ $id ]['pages'] ) ) {
|
||||
return in_array( $_GET['page'], $this->config['repo'][ $repo ][ $id ]['pages'] );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace OTGS\Installer\AdminNotices;
|
||||
|
||||
class ScreenConfig extends Config {
|
||||
|
||||
/**
|
||||
* @param array $messages
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isAnyMessageOnPage( array $messages ) {
|
||||
$currentScreen = get_current_screen();
|
||||
|
||||
if ( ! $currentScreen instanceof \WP_Screen ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->hasItem( $messages, $currentScreen->id, 'screens' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $repo
|
||||
* @param string $id
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function shouldShowMessage( $repo, $id ) {
|
||||
$currentScreen = get_current_screen();
|
||||
|
||||
if ( $currentScreen instanceof \WP_Screen ) {
|
||||
if ( isset( $this->config['repo'][ $repo ][ $id ]['screens'] ) ) {
|
||||
return in_array( $currentScreen->id, $this->config['repo'][ $repo ][ $id ]['screens'] );
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace OTGS\Installer\AdminNotices;
|
||||
|
||||
class Store {
|
||||
const ADMIN_NOTICES_OPTION = 'otgs_installer_admin_notices';
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param $data
|
||||
*/
|
||||
public function save( $key, $data ) {
|
||||
$current = get_option( self::ADMIN_NOTICES_OPTION, [] );
|
||||
$current[ $key ] = $data;
|
||||
update_option( self::ADMIN_NOTICES_OPTION, $current, 'no' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function get( $key, $default ) {
|
||||
$current = get_option( self::ADMIN_NOTICES_OPTION, [] );
|
||||
return isset( $current[$key] ) ? $current[$key] : $default;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace OTGS\Installer\AdminNotices;
|
||||
|
||||
class TMConfig {
|
||||
public static function pages() {
|
||||
if ( ! defined( 'WPML_TM_FOLDER' ) ) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return [
|
||||
WPML_TM_FOLDER . '/menu/settings',
|
||||
WPML_TM_FOLDER . '/menu/main.php',
|
||||
WPML_TM_FOLDER . '/menu/translations-queue.php',
|
||||
WPML_TM_FOLDER . '/menu/string-translation.php',
|
||||
WPML_TM_FOLDER . '/menu/settings.php',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace OTGS\Installer\AdminNotices;
|
||||
|
||||
class ToolsetConfig {
|
||||
|
||||
public static function pages() {
|
||||
return [
|
||||
'toolset-dashboard',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace OTGS\Installer\AdminNotices;
|
||||
|
||||
class WPMLConfig {
|
||||
|
||||
public static function pages() {
|
||||
if ( ! defined( 'WPML_PLUGIN_FOLDER' ) ) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return [
|
||||
WPML_PLUGIN_FOLDER . '/menu/languages.php',
|
||||
WPML_PLUGIN_FOLDER . '/menu/theme-localization.php',
|
||||
WPML_PLUGIN_FOLDER . '/menu/settings.php',
|
||||
WPML_PLUGIN_FOLDER . '/menu/support.php',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,210 @@
|
||||
<?php
|
||||
|
||||
namespace OTGS\Installer\AdminNotices\Notices;
|
||||
|
||||
use OTGS\Installer\AdminNotices\Loader;
|
||||
use OTGS\Installer\AdminNotices\Store;
|
||||
use OTGS\Installer\AdminNotices\ToolsetConfig;
|
||||
use OTGS\Installer\AdminNotices\WPMLConfig;
|
||||
use OTGS\Installer\Collection;
|
||||
use function OTGS\Installer\FP\partial;
|
||||
|
||||
class Account {
|
||||
|
||||
const NOT_REGISTERED = 'not-registered';
|
||||
const EXPIRED = 'expired';
|
||||
const REFUNDED = 'refunded';
|
||||
const GET_FIRST_INSTALL_TIME = 'get_first_install_time';
|
||||
const DEVELOPMENT_MODE = 'development_mode';
|
||||
|
||||
/**
|
||||
* @param \WP_Installer $installer
|
||||
* @param array $initialNotices
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getCurrentNotices( \WP_Installer $installer, array $initialNotices ) {
|
||||
|
||||
$config = $installer->get_site_key_nags_config();
|
||||
|
||||
$noticeTypes = [
|
||||
self::NOT_REGISTERED => [ Account::class, 'shouldShowNotRegistered' ],
|
||||
self::EXPIRED => [ Account::class, 'shouldShowExpired' ],
|
||||
self::REFUNDED => [ Account::class, 'shouldShowRefunded' ],
|
||||
self::DEVELOPMENT_MODE => [ Account::class, 'shouldShowDevelopmentBanner' ],
|
||||
];
|
||||
|
||||
return collection::of( $noticeTypes )
|
||||
->entities()
|
||||
->reduce( Notice::addNoticesForType( $installer, $config ), Collection::of( $initialNotices ) )
|
||||
->get();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \WP_Installer $installer
|
||||
* @param array $nag
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function shouldShowNotRegistered( \WP_Installer $installer, array $nag ) {
|
||||
$shouldShow = ! self::isDevelopmentSite( $installer->get_installer_site_url( $nag['repository_id'] ) ) &&
|
||||
! $installer->repository_has_subscription( $nag['repository_id'] ) &&
|
||||
( isset( $nag['condition_cb'] ) ? $nag['condition_cb']() : true );
|
||||
|
||||
if ( $shouldShow ) {
|
||||
$shouldShow = ! self::maybeDelayOneWeekOnNewInstalls( $nag['repository_id'] );
|
||||
}
|
||||
|
||||
return $shouldShow;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \WP_Installer $installer
|
||||
* @param array $nag
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function shouldShowExpired( \WP_Installer $installer, array $nag ) {
|
||||
return $installer->repository_has_expired_subscription( $nag['repository_id'], 30 * DAY_IN_SECONDS );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \WP_Installer $installer
|
||||
* @param array $nag
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function shouldShowDevelopmentBanner( \WP_Installer $installer, array $nag ) {
|
||||
$showDevelopmentBanner = $installer->repository_has_development_site_key( $nag['repository_id'] );
|
||||
$isDismissed = Loader::isDismissed( $nag[ 'repository_id' ], Account::DEVELOPMENT_MODE );
|
||||
if ( $showDevelopmentBanner && $isDismissed && $nag['repository_id'] === 'wpml' ) {
|
||||
wp_enqueue_style( 'installer-admin-notices', $installer->res_url() . '/res/css/admin-notices.css', array(), $installer->version() );
|
||||
add_action( 'wp_before_admin_bar_render', [ static::class, 'addWpmlDevelopmentAdminBar' ], 100);
|
||||
}
|
||||
return $showDevelopmentBanner;
|
||||
}
|
||||
|
||||
public static function addWpmlDevelopmentAdminBar() {
|
||||
/** @var \WP_Admin_Bar $wp_admin_bar */
|
||||
global $wp_admin_bar;
|
||||
|
||||
$helpText = __( 'This site is registered on wpml.org as a development site.', 'installer' );
|
||||
$text = __( 'Development Site', 'installer' );
|
||||
|
||||
$wp_admin_bar->add_menu(
|
||||
array(
|
||||
'parent' => false,
|
||||
'id' => 'otgs-wpml-development',
|
||||
'title' => '<i class="otgs-ico-sitepress-multilingual-cms js-otgs-popover-tooltip" data-tippy-zIndex="999999" title="' . $helpText . '" > ' . $text . '</i>',
|
||||
'href' => false,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \WP_Installer $installer
|
||||
* @param array $nag
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function shouldShowRefunded( \WP_Installer $installer, array $nag ) {
|
||||
return $installer->repository_has_refunded_subscription( $nag['repository_id'] );
|
||||
}
|
||||
|
||||
public static function config( array $initialConfig ) {
|
||||
return self::pages( self::screens( $initialConfig ) );
|
||||
}
|
||||
|
||||
public static function pages( array $initialPages ) {
|
||||
$wpmlPages = [ 'pages' => WPMLConfig::pages() ];
|
||||
$toolsetPages = [ 'pages' => ToolsetConfig::pages() ];
|
||||
|
||||
return array_merge_recursive( $initialPages, [
|
||||
'repo' => [
|
||||
'wpml' => [
|
||||
Account::NOT_REGISTERED => $wpmlPages,
|
||||
Account::EXPIRED => $wpmlPages,
|
||||
Account::REFUNDED => $wpmlPages,
|
||||
Account::DEVELOPMENT_MODE => $wpmlPages,
|
||||
],
|
||||
'toolset' => [
|
||||
Account::NOT_REGISTERED => $toolsetPages,
|
||||
Account::EXPIRED => $toolsetPages,
|
||||
Account::REFUNDED => $toolsetPages,
|
||||
Account::DEVELOPMENT_MODE => $toolsetPages,
|
||||
],
|
||||
],
|
||||
] );
|
||||
}
|
||||
|
||||
public static function screens( array $screens ) {
|
||||
$config = [
|
||||
Account::NOT_REGISTERED => [ 'screens' => [ 'plugins' ] ],
|
||||
Account::EXPIRED => [ 'screens' => [ 'plugins' ] ],
|
||||
Account::REFUNDED => [ 'screens' => [ 'plugins', 'dashboard' ] ],
|
||||
Account::DEVELOPMENT_MODE => [ 'screens' => [ 'plugins', 'dashboard', 'plugin-install' ] ],
|
||||
];
|
||||
|
||||
return array_merge_recursive( $screens, [
|
||||
'repo' => [
|
||||
'wpml' => $config,
|
||||
'toolset' => $config,
|
||||
],
|
||||
] );
|
||||
}
|
||||
|
||||
public static function texts( array $initialTexts ) {
|
||||
return array_merge_recursive( $initialTexts, [
|
||||
'repo' => [
|
||||
'wpml' => [
|
||||
Account::NOT_REGISTERED => WPMLTexts::class . '::notRegistered',
|
||||
Account::EXPIRED => WPMLTexts::class . '::expired',
|
||||
Account::REFUNDED => WPMLTexts::class . '::refunded',
|
||||
Account::DEVELOPMENT_MODE => WPMLTexts::class . '::developmentBanner',
|
||||
],
|
||||
'toolset' => [
|
||||
Account::NOT_REGISTERED => ToolsetTexts::class . '::notRegistered',
|
||||
Account::EXPIRED => ToolsetTexts::class . '::expired',
|
||||
Account::REFUNDED => ToolsetTexts::class . '::refunded',
|
||||
Account::DEVELOPMENT_MODE => ToolsetTexts::class . '::developmentBanner',
|
||||
],
|
||||
],
|
||||
] );
|
||||
}
|
||||
|
||||
public static function dismissions( array $initialDismissions ) {
|
||||
return array_merge_recursive(
|
||||
$initialDismissions,
|
||||
[
|
||||
Account::NOT_REGISTERED => Dismissions::class . '::dismissAccountNotice',
|
||||
Account::DEVELOPMENT_MODE => Dismissions::class . '::dismissAccountNotice',
|
||||
Account::EXPIRED => Dismissions::class . '::dismissAccountNotice',
|
||||
Account::REFUNDED => Dismissions::class . '::dismissAccountNotice',
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
private static function isDevelopmentSite( $url ) {
|
||||
$endsWith = function ( $haystack, $needle ) {
|
||||
return substr_compare( $haystack, $needle, - strlen( $needle ) ) === 0;
|
||||
};
|
||||
|
||||
$host = parse_url( $url, PHP_URL_HOST );
|
||||
|
||||
return $endsWith( $host, '.dev' ) ||
|
||||
$endsWith( $host, '.local' ) ||
|
||||
$endsWith( $host, '.test' );
|
||||
}
|
||||
|
||||
private static function maybeDelayOneWeekOnNewInstalls( $repo ) {
|
||||
$store = new Store();
|
||||
$installTime = $store->get( self::GET_FIRST_INSTALL_TIME, [] );
|
||||
if ( ! isset( $installTime[ $repo ] ) ) {
|
||||
$installTime[ $repo ] = time();
|
||||
$store->save( self::GET_FIRST_INSTALL_TIME, $installTime );
|
||||
}
|
||||
|
||||
return time() - $installTime[ $repo ] < WEEK_IN_SECONDS;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
namespace OTGS\Installer\AdminNotices\Notices;
|
||||
|
||||
use OTGS\Installer\AdminNotices\ToolsetConfig;
|
||||
use OTGS\Installer\AdminNotices\WPMLConfig;
|
||||
use OTGS\Installer\Collection;
|
||||
|
||||
class ApiConnection {
|
||||
const CONNECTION_ISSUES = 'connection-issues';
|
||||
|
||||
/**
|
||||
* @param \WP_Installer $installer
|
||||
* @param array $initialNotices
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getCurrentNotices( \WP_Installer $installer, array $initialNotices ) {
|
||||
$config = $installer->getRepositories();
|
||||
|
||||
$noticeTypes = [
|
||||
self::CONNECTION_ISSUES => [ApiConnection::class, 'shouldShowConnectionIssues'],
|
||||
];
|
||||
|
||||
return collection::of( $noticeTypes )
|
||||
->entities()
|
||||
->reduce( Notice::addNoticesForType($installer, $config), Collection::of( $initialNotices ) )
|
||||
->get();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \WP_Installer $installer
|
||||
* @param array $nag
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function shouldShowConnectionIssues( \WP_Installer $installer, array $nag ) {
|
||||
return $installer->shouldDisplayConnectionIssueMessage( $nag['repository_id'] );
|
||||
}
|
||||
|
||||
public static function config( array $initialConfig ) {
|
||||
return self::pages( self::screens( $initialConfig ) );
|
||||
}
|
||||
|
||||
public static function pages( array $initialPages ) {
|
||||
$wpmlPages = [ 'pages' => WPMLConfig::pages() ];
|
||||
$toolsetPages = [ 'pages' => ToolsetConfig::pages() ];
|
||||
|
||||
return array_merge_recursive( $initialPages, [
|
||||
'repo' => [
|
||||
'wpml' => [
|
||||
ApiConnection::CONNECTION_ISSUES => $wpmlPages,
|
||||
],
|
||||
'toolset' => [
|
||||
ApiConnection::CONNECTION_ISSUES => $toolsetPages,
|
||||
],
|
||||
],
|
||||
] );
|
||||
}
|
||||
|
||||
public static function screens( array $screens ) {
|
||||
$config = [
|
||||
ApiConnection::CONNECTION_ISSUES => [ 'screens' => [ 'plugins', 'plugin-install' ] ],
|
||||
];
|
||||
|
||||
return array_merge_recursive( $screens, [
|
||||
'repo' => [
|
||||
'wpml' => $config,
|
||||
'toolset' => $config,
|
||||
],
|
||||
] );
|
||||
}
|
||||
|
||||
public static function texts( array $initialTexts ) {
|
||||
return array_merge_recursive( $initialTexts, [
|
||||
'repo' => [
|
||||
'wpml' => [
|
||||
ApiConnection::CONNECTION_ISSUES => WPMLTexts::class . '::connectionIssues',
|
||||
],
|
||||
'toolset' => [
|
||||
ApiConnection::CONNECTION_ISSUES => ToolsetTexts::class . '::connectionIssues',
|
||||
],
|
||||
],
|
||||
] );
|
||||
}
|
||||
|
||||
public static function dismissions( array $initialDismissions ) {
|
||||
return $initialDismissions;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace OTGS\Installer\AdminNotices\Notices;
|
||||
|
||||
use OTGS\Installer\Recommendations\Storage;
|
||||
|
||||
class Dismissions {
|
||||
/**
|
||||
* @param array $dismissed already dismissed notices.
|
||||
* @param array $data dismissed notice parameters.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function dismissAccountNotice( $dismissed, $data ) {
|
||||
$dismissed['repo'][ $data['repository'] ][ $data['noticeType'] ] = time();
|
||||
|
||||
return $dismissed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $dismissed already dismissed notices.
|
||||
* @param array $data dismissed notice parameters.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function dismissRecommendationNotice( $dismissed, $data ) {
|
||||
Storage::delete( $data['noticePluginSlug'], $data['repository'] );
|
||||
|
||||
return $dismissed;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace OTGS\Installer\AdminNotices\Notices;
|
||||
|
||||
|
||||
use function OTGS\Installer\FP\partial;
|
||||
|
||||
class Hooks {
|
||||
public static function addHooks( $class, \WP_Installer $installer ) {
|
||||
add_filter( 'otgs_installer_admin_notices_config', [$class, 'config'] );
|
||||
add_filter( 'otgs_installer_admin_notices_texts', [$class, 'texts'] );
|
||||
add_filter( 'otgs_installer_admin_notices_dismissions', [$class, 'dismissions'] );
|
||||
add_filter(
|
||||
'otgs_installer_admin_notices',
|
||||
partial( [$class, 'getCurrentNotices'], $installer )
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace OTGS\Installer\AdminNotices\Notices;
|
||||
|
||||
use OTGS\Installer\Collection;
|
||||
use function OTGS\Installer\FP\partial;
|
||||
|
||||
class Notice {
|
||||
/**
|
||||
* @param \WP_Installer $installer
|
||||
* @param array $config
|
||||
*
|
||||
* @return \Closure
|
||||
*/
|
||||
public static function addNoticesForType( $installer, $config ) {
|
||||
return function ( Collection $notices, array $data ) use ( $installer, $config ) {
|
||||
list( $type, $fn ) = $data;
|
||||
$addNotice = partial( self::class . '::addNotice', $type );
|
||||
$shouldShow = partial( $fn, $installer );
|
||||
|
||||
return $notices->mergeRecursive( Collection::of( $config )
|
||||
->filter( $shouldShow )
|
||||
->pluck( 'repository_id' )
|
||||
->reduce( $addNotice, [] ) );
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $noticeId
|
||||
* @param array $notices
|
||||
* @param string $repoId
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function addNotice( $noticeId, array $notices, $repoId ) {
|
||||
return array_merge_recursive( $notices, [ 'repo' => [ $repoId => [ $noticeId ] ] ] );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
|
||||
namespace OTGS\Installer\AdminNotices\Notices;
|
||||
|
||||
use OTGS\Installer\Collection;
|
||||
use OTGS\Installer\Recommendations\RecommendationsManager;
|
||||
use OTGS\Installer\Recommendations\Storage;
|
||||
use function OTGS\Installer\FP\partial;
|
||||
|
||||
class Recommendation {
|
||||
|
||||
const PLUGIN_ACTIVATED = 'plugin-activated';
|
||||
|
||||
public static function addHooks() {
|
||||
add_filter( 'otgs_installer_admin_notices_config', self::class . '::config' );
|
||||
add_filter( 'otgs_installer_admin_notices_texts', self::class . '::texts' );
|
||||
add_filter( 'otgs_installer_admin_notices_dismissions', self::class . '::dismissions' );
|
||||
add_filter(
|
||||
'otgs_installer_admin_notices',
|
||||
self::class . '::getCurrentNotices'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param callable $getActivatedPlugins
|
||||
* @param array $initialNotices
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getCurrentNotices( array $initialNotices ) {
|
||||
$activatedPluginsConfig = apply_filters('wpml_installer_get_stored_recommendation_notices', []);
|
||||
$addNoticeIdField = function ( $item ) {
|
||||
$item['noticeId'] = self::PLUGIN_ACTIVATED . '-' . $item['glue_check_slug'];
|
||||
|
||||
return $item;
|
||||
};
|
||||
|
||||
$updatedConfig = Collection::of( $activatedPluginsConfig )
|
||||
->map( function ( $items ) use ( $addNoticeIdField ) {
|
||||
$items = Collection::of( $items )->map( $addNoticeIdField )->get();
|
||||
|
||||
return [ self::PLUGIN_ACTIVATED => $items ];
|
||||
} );
|
||||
|
||||
if ( ! empty( $updatedConfig->get() ) ) {
|
||||
$activatedPluginsConfig = [ 'repo' => $updatedConfig->get() ];
|
||||
} else {
|
||||
$activatedPluginsConfig = [];
|
||||
}
|
||||
|
||||
return array_merge_recursive( $initialNotices, $activatedPluginsConfig );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $initialConfig
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function config( array $initialConfig ) {
|
||||
return self::screens( $initialConfig );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $screens
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function screens( array $screens ) {
|
||||
$config = [
|
||||
self::PLUGIN_ACTIVATED => [ 'screens' => [ 'plugins' ] ],
|
||||
];
|
||||
|
||||
return array_merge_recursive( $screens, [
|
||||
'repo' => [
|
||||
'wpml' => $config,
|
||||
],
|
||||
] );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $initialTexts
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function texts( array $initialTexts ) {
|
||||
return array_merge_recursive(
|
||||
$initialTexts,
|
||||
[
|
||||
'repo' => [
|
||||
'wpml' => [
|
||||
self::PLUGIN_ACTIVATED => WPMLTexts::class . '::pluginActivatedRecommendation',
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $initialDismissions
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function dismissions( array $initialDismissions ) {
|
||||
return array_merge_recursive(
|
||||
$initialDismissions,
|
||||
[
|
||||
self::PLUGIN_ACTIVATED => Dismissions::class . '::dismissRecommendationNotice',
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,345 @@
|
||||
<?php
|
||||
|
||||
namespace OTGS\Installer\AdminNotices\Notices;
|
||||
|
||||
class Texts {
|
||||
|
||||
protected static $repo;
|
||||
protected static $product;
|
||||
protected static $productURL;
|
||||
protected static $apiHost;
|
||||
protected static $communicationDetailsLink;
|
||||
protected static $supportLink;
|
||||
protected static $publishLink;
|
||||
protected static $learnMoreDevKeysLink;
|
||||
|
||||
public static function notRegistered() {
|
||||
// translators: %s Product name
|
||||
$headingHTML = self::getHeadingHTML( __( 'You are using an unregistered version of %s and are not receiving compatibility and security updates', 'installer' ) );
|
||||
// translators: %s Product name
|
||||
$bodyHTML = self::getBodyHTML( __( '%s plugin must be registered in order to receive stability and security updates. Without these updates, the plugin may become incompatible with new versions of WordPress, which include security patches.', 'installer' ) ) .
|
||||
self::inButtonAreaHTML( self::getNotRegisteredButtons() ) .
|
||||
self::getDismissHTML( Account::NOT_REGISTERED );
|
||||
|
||||
return self::insideDiv( 'register', $headingHTML . $bodyHTML );
|
||||
}
|
||||
|
||||
public static function expired() {
|
||||
// translators: %s Product name
|
||||
$headingHTML = self::getHeadingHTML( __( 'You are using an expired %s account.', 'installer' ) );
|
||||
// translators: %s Product name
|
||||
$bodyHTML = self::getBodyHTML( __( "Your site is using an expired %s account, which means you won't receive updates. This can lead to stability and security issues.", 'installer' ) ) .
|
||||
self::inButtonAreaHTML( self::getExpiredButtons() ) .
|
||||
self::getDismissHTML( Account::EXPIRED );
|
||||
|
||||
return self::insideDiv( 'expire', $headingHTML . $bodyHTML );
|
||||
}
|
||||
|
||||
public static function developmentBanner() {
|
||||
// translators: %s Product url
|
||||
$dismissHTML = self::getDismissHTML( Account::DEVELOPMENT_MODE );
|
||||
$headingHTML = '<h2>' . esc_html( sprintf( __( 'This site is registered on %s as a development site.', 'installer' ), static::$productURL ) ) . '</h2>';
|
||||
// translators: %1$s is the text "update the site key" inside a link and %2$s is the text "Learn more" inside a link
|
||||
$bodyText = esc_html__( 'When this site goes live, remember to %1$s from "development" to "production" to remove this message. %2$s', 'installer' );
|
||||
$bodyHTML = '<p>' . sprintf(
|
||||
$bodyText,
|
||||
self::getPublishLinkHTML( __( 'update the site key', 'installer' ) ),
|
||||
self::getLearnMoveDevKeysLinkHTML( __( 'Learn more', 'installer' ) )
|
||||
) . '</p>';
|
||||
|
||||
return self::insideDiv( 'notice', $dismissHTML . $headingHTML . $bodyHTML );
|
||||
}
|
||||
|
||||
public static function refunded() {
|
||||
// translators: %s Product name
|
||||
$headingHTML = self::getHeadingHTML( __( 'Remember to remove %s from this website', 'installer' ) );
|
||||
// translators: %s Product name
|
||||
$body = self::getBodyHTML( __( 'This site is using the %s plugin, which has not been paid for. After receiving a refund, you should remove this plugin from your sites. Using unregistered plugins means you are not receiving stability and security updates and will ultimately lead to problems running the site.', 'installer' ) ) .
|
||||
self::inButtonAreaHTML( self::getRefundedButtons() );
|
||||
|
||||
return self::insideDiv( 'refund', $headingHTML . $body );
|
||||
}
|
||||
|
||||
public static function connectionIssues() {
|
||||
// translators: %1$s Product name %2$s host name (ex. wpml.org)
|
||||
$headingHTML = self::getConnectionIssueHeadingHTML( __( '%1$s plugin cannot connect to %2$s', 'installer' ) );
|
||||
|
||||
// translators: %1$s Product name %2$s host name (ex. wpml.org)
|
||||
$body = self::getConnectionIssueBodyHTML( __( '%1$s needs to connect to its server to check for new releases and security updates. Something in the network or security settings is preventing this. Please allow outgoing communication to %2$s to remove this notice.', 'installer' ) ) .
|
||||
self::inLinksAreaHTML(
|
||||
__( 'Need help?', 'installer' ),
|
||||
// translators: %1$s is `communication error details` %2$s is ex. wpml.org technical support
|
||||
__( 'See the %1$s and let us know in %2$s.', 'installer' ),
|
||||
self::getCommunicationDetailsLinkHTML( __( 'communication error details', 'installer' ) ),
|
||||
// translators: %s is host name (ex. wpml.org)
|
||||
self::getSupportLinkHTML( __( '%s technical support', 'installer' ) )
|
||||
);
|
||||
|
||||
return self::insideDiv( 'connection-issues', $headingHTML . $body );
|
||||
}
|
||||
|
||||
public static function pluginActivatedRecommendation( $parameters ) {
|
||||
$heading_html = self::getHeadingHTML( $parameters['recommendation_notification'] );
|
||||
|
||||
$body_text = sprintf(
|
||||
__( 'Please install %s to allow translating %s.', 'installer' ),
|
||||
strip_tags( $parameters['glue_plugin_name'] ),
|
||||
$parameters['glue_check_name']
|
||||
);
|
||||
|
||||
$body_html = self::getBodyHTML( $body_text ) .
|
||||
self::inButtonAreaHTML( self::getRecommendationButtons( $parameters ) );
|
||||
|
||||
return self::insideDiv( 'plugin-recommendation', $heading_html . $body_html );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $type The type is used as a suffix of the `otgs-installer-notice-` CSS class.
|
||||
* @param string $html An unescaped HTML string but with escaped data (e.g. attributes, URLs, or strings in the HTML produced from any input).
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function insideDiv( $type, $html ) {
|
||||
$classes = [
|
||||
'notice',
|
||||
'otgs-installer-notice',
|
||||
'otgs-installer-notice-' . esc_attr( static::$repo ),
|
||||
'otgs-installer-notice-' . esc_attr( $type ),
|
||||
];
|
||||
|
||||
$notDismissable = [ 'refund', 'connection-issues', 'development' ];
|
||||
if ( ! in_array( $type, $notDismissable ) ) {
|
||||
$classes[] = 'otgs-is-dismissible';
|
||||
}
|
||||
|
||||
return '<div class="' . implode( ' ', $classes ) . '">' .
|
||||
'<div class="otgs-installer-notice-content">' .
|
||||
$html .
|
||||
'</div>' .
|
||||
'</div>';
|
||||
}
|
||||
|
||||
private static function getRecommendationButtons( $parameters ) {
|
||||
|
||||
$installButton = __( "Install and activate", 'installer' );
|
||||
$dismiss = __( "Ignore and don't ask me again", 'installer' );
|
||||
|
||||
return self::getRecommendationInstallButtonHTML( $installButton, $parameters ) .
|
||||
self::getRecommendationDismissHTML( $dismiss, $parameters );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected static function getNotRegisteredButtons() {
|
||||
$registerUrl = \WP_Installer::menu_url();
|
||||
$register = __( 'Register', 'installer' );
|
||||
$stagingSite = __( 'This is a development / staging site', 'installer' );
|
||||
|
||||
return self::getPrimaryButtonHTML( $registerUrl, $register ) .
|
||||
self::getStagingButtonHTML( $stagingSite );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected static function getExpiredButtons() {
|
||||
$checkOrderStatusUrl = \WP_Installer::menu_url() . '&validate_repository=' . static::$repo;
|
||||
$accountButton = __( 'Extend your subscription', 'installer' );
|
||||
$checkButton = __( 'Check my order status', 'installer' );
|
||||
$statusText = __( 'Got renewal already?', 'installer' );
|
||||
$productUrl = \WP_Installer::instance()->get_product_data( static::$repo, 'url' );
|
||||
|
||||
return self::getPrimaryButtonHTML( $productUrl . '/account', $accountButton ) .
|
||||
self::getStatusHTML( $statusText ) .
|
||||
self::getRefreshButtonHTML( $checkOrderStatusUrl, $checkButton );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private static function getRefundedButtons() {
|
||||
$checkOrderStatusUrl = \WP_Installer::menu_url() . '&validate_repository=' . static::$repo;
|
||||
$checkButton = __( 'Check my order status', 'installer' );
|
||||
$status = __( 'Bought again?', 'installer' );
|
||||
|
||||
return self::getStatusHTML( $status ) .
|
||||
self::getPrimaryButtonHTML( $checkOrderStatusUrl, $checkButton );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $notice_type The method takes care of escaping the string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function getDismissHTML( $notice_type ) {
|
||||
return '<span class="installer-dismiss-nag notice-dismiss" ' . self::getDismissedAttributes( $notice_type ) . '>'
|
||||
. '<span class="screen-reader-text">' . esc_html__( 'Dismiss', 'installer' ) . '</span></span>';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $notice_type The method takes care of escaping the string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function getDismissedAttributes( $notice_type, $noticeId = null ) {
|
||||
$dismissedAttributes = 'data-repository="' . esc_attr( static::$repo ) . '" data-notice-type="' . esc_attr( $notice_type ) . '"';
|
||||
if ( $noticeId ) {
|
||||
$dismissedAttributes .= '" data-notice-plugin-slug="' . esc_attr( $noticeId ) . '"';
|
||||
}
|
||||
|
||||
return $dismissedAttributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url The method takes care of escaping the string.
|
||||
* @param string $text The method takes care of escaping the string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function getPrimaryButtonHTML( $url, $text ) {
|
||||
return '<a class="otgs-installer-notice-status-item otgs-installer-notice-status-item-btn" href="' . esc_url( $url ) . '">' . esc_html( $text ) . '</a>';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url The method takes care of escaping the string.
|
||||
* @param string $text The method takes care of escaping the string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function getRecommendationInstallButtonHTML( $text, $parameters ) {
|
||||
return
|
||||
wp_nonce_field( 'recommendation_success_nonce', 'recommendation_success_nonce' ) .
|
||||
'<input type="hidden" id="originalPluginData" value="' . base64_encode( json_encode( [
|
||||
'slug' => $parameters['glue_check_slug'],
|
||||
'repository_id' => $parameters['repository_id'],
|
||||
] ) ) . '">' .
|
||||
'<button class="js-install-recommended otgs-installer-notice-status-item otgs-installer-notice-status-item-btn" value="' . base64_encode( json_encode( $parameters['download_data'] ) ) . '">' . esc_html( $text ) . '</button><span class="spinner"></span>';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url The method takes care of escaping the string.
|
||||
* @param string $text The method takes care of escaping the string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function getRefreshButtonHTML( $url, $text ) {
|
||||
return '<a class="otgs-installer-notice-status-item otgs-installer-notice-status-item-link otgs-installer-notice-status-item-link-refresh" href="' . esc_url( $url ) . '">' . esc_html( $text ) . '</a>';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $text The method takes care of escaping the string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function getStatusHTML( $text ) {
|
||||
return '<p class="otgs-installer-notice-status-item">' . esc_html( $text ) . '</p>';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $text The method takes care of escaping the string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function getRecommendationDismissHTML( $text, $parameters ) {
|
||||
return '<a class="installer-dismiss-nag otgs-installer-notice-status-item-link" ' . self::getDismissedAttributes( Recommendation::PLUGIN_ACTIVATED, $parameters['glue_check_slug'] ) . ' href="#">'
|
||||
. esc_html( $text ) . '</a>';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $html An unescaped HTML string but with escaped data (e.g. attributes, URLs, or strings in the HTML produced from any input).
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function inButtonAreaHTML( $html ) {
|
||||
return '<div class="otgs-installer-notice-status">' . $html . '</div>';
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $text
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function inLinksAreaHTML( $title, $text, $communicationDetails, $supportLink ) {
|
||||
return '<div class="otgs-installer-notice-status">
|
||||
<p class="otgs-installer-notice-status-item">' . esc_html( $title ) . '</p>
|
||||
<p class="otgs-installer-notice-status-item">' . sprintf( esc_html( $text ), $communicationDetails, $supportLink ) . '</p>
|
||||
</div>';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $text The method takes care of escaping the string.
|
||||
* If the string contains a placeholder, it will be replaced with the value of `static::$product`.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function getHeadingHTML( $text ) {
|
||||
return '<h2>' . esc_html( sprintf( $text, static::$product ) ) . '</h2>';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $text
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function getConnectionIssueHeadingHTML( $text ) {
|
||||
return '<h2>' . esc_html( sprintf( $text, static::$product, static::$apiHost ) ) . '</h2>';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $text The method takes care of escaping the string.
|
||||
* If the string contains a placeholder, it will be replaced with the value of `static::$product`.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function getBodyHTML( $text ) {
|
||||
return '<p>' . esc_html( sprintf( $text, static::$product ) ) . '</p>';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $text The method takes care of escaping the string.
|
||||
* If the string contains a placeholder, it will be replaced with the value of `static::$product`.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function getConnectionIssueBodyHTML( $text ) {
|
||||
return '<p>' . esc_html( sprintf( $text, static::$product, static::$apiHost ) ) . '</p>';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $text The method takes care of escaping the string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function getStagingButtonHTML( $text ) {
|
||||
return '<a class="otgs-installer-notice-status-item otgs-installer-notice-status-item-link installer-dismiss-nag" ' . self::getDismissedAttributes( Account::NOT_REGISTERED ) . '>' . esc_html( $text ) . '</a>';
|
||||
}
|
||||
|
||||
private static function getCommunicationDetailsLinkHTML( $text ) {
|
||||
return '<a href="' . esc_url( admin_url( static::$communicationDetailsLink ) ) . '">' . esc_html( $text ) . '</a>';
|
||||
}
|
||||
|
||||
private static function getSupportLinkHTML( $text ) {
|
||||
return '<a href="' . esc_url( static::$supportLink ) . '">' . esc_html( sprintf( $text, static::$product ) ) . '</a>';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $text
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function getPublishLinkHTML( $text ) {
|
||||
$publishLink = static::$publishLink . \WP_Installer::instance()->get_site_key( static::$repo );
|
||||
|
||||
return self::makeLink( $publishLink, $text );
|
||||
}
|
||||
|
||||
private static function getLearnMoveDevKeysLinkHTML( $text ) {
|
||||
return self::makeLink( static::$learnMoreDevKeysLink, $text );
|
||||
}
|
||||
|
||||
private static function makeLink( $url, $text ) {
|
||||
return '<a href="' . esc_url( $url ) . '" target="_blank">' . esc_html( $text ) . '</a>';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace OTGS\Installer\AdminNotices\Notices;
|
||||
|
||||
class ToolsetTexts extends Texts {
|
||||
|
||||
protected static $repo = 'toolset';
|
||||
protected static $product = 'Toolset';
|
||||
protected static $productURL = 'Toolset.com';
|
||||
protected static $apiHost = 'toolset.com';
|
||||
protected static $communicationDetailsLink = '/admin.php?page=otgs-installer-support';
|
||||
protected static $supportLink = 'https://toolset.com/forums/forum/professional-support/';
|
||||
protected static $publishLink = 'https://toolset.com/account/sites/?publish=';
|
||||
protected static $learnMoreDevKeysLink = 'https://toolset.com/faq/how-to-install-and-register-toolset/?utm_source=plugin&utm_medium=gui&utm_campaign=types#registering-toolset-in-a-development-environment';
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace OTGS\Installer\AdminNotices\Notices;
|
||||
|
||||
class WPMLTexts extends Texts {
|
||||
|
||||
protected static $repo = 'wpml';
|
||||
protected static $product = 'WPML';
|
||||
protected static $productURL = 'WPML.org';
|
||||
protected static $apiHost = 'wpml.org';
|
||||
protected static $communicationDetailsLink = '/admin.php?page=otgs-installer-support';
|
||||
protected static $supportLink = 'https://wpml.org/forums/';
|
||||
protected static $publishLink = 'https://wpml.org/account/sites/?publish=';
|
||||
protected static $learnMoreDevKeysLink = 'https://wpml.org/faq/install-wpml/?utm_source=plugin&utm_medium=gui&utm_campaign=wpmlcore/#register-development-sites';
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Installer_Buy_URL_Hooks {
|
||||
|
||||
private $embedded_at;
|
||||
|
||||
public function __construct( $embedded_at ) {
|
||||
$this->embedded_at = $embedded_at;
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
add_filter( 'wp_installer_buy_url', array( $this, 'append_installer_source' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function append_installer_source( $url ) {
|
||||
$url = add_query_arg( 'embedded_at', $this->embedded_at, $url );
|
||||
|
||||
return $url;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,312 @@
|
||||
<?php
|
||||
|
||||
class Installer_Dependencies {
|
||||
|
||||
private $uploading_allowed = null;
|
||||
private $is_win_paths_exception = array();
|
||||
|
||||
private $missing_php_libraries = array();
|
||||
|
||||
function __construct() {
|
||||
|
||||
add_action( 'admin_init', array( $this, 'prevent_plugins_update_on_plugins_page' ), 100 );
|
||||
|
||||
|
||||
global $pagenow;
|
||||
if ( $pagenow == 'update.php' ) {
|
||||
if ( isset( $_GET['action'] ) && $_GET['action'] == 'update-selected' ) {
|
||||
add_action( 'admin_head', array(
|
||||
$this,
|
||||
'prevent_plugins_update_on_updates_screen'
|
||||
) ); //iframe/bulk
|
||||
} else {
|
||||
add_action( 'all_admin_notices', array(
|
||||
$this,
|
||||
'prevent_plugins_update_on_updates_screen'
|
||||
) ); //regular/singular
|
||||
}
|
||||
}
|
||||
add_action( 'wp_ajax_update-plugin', array(
|
||||
$this,
|
||||
'prevent_plugins_update_on_updates_screen'
|
||||
), 0 ); // high priority, before WP
|
||||
|
||||
}
|
||||
|
||||
public function is_win_paths_exception( $repository_id ) {
|
||||
if ( ! isset( $this->is_win_paths_exception[ $repository_id ] ) ) {
|
||||
$this->is_win_paths_exception[ $repository_id ] = false;
|
||||
if ( strtoupper( substr( constant('PHP_OS'), 0, 3 ) ) === 'WIN' ) {
|
||||
|
||||
$windows_max_path_length = 256;
|
||||
$longest_path['wpml'] = 109;
|
||||
$longest_path['toolset'] = 99;
|
||||
|
||||
$margin = 15;
|
||||
|
||||
$upgrade_path_length = strlen( WP_CONTENT_DIR . '/upgrade' );
|
||||
|
||||
$installer_settings = WP_Installer()->settings;
|
||||
if ( isset( $installer_settings['repositories'][ $repository_id ]['data']['downloads']['plugins'] ) ) {
|
||||
$a_plugin = current( $installer_settings['repositories'][ $repository_id ]['data']['downloads']['plugins'] );
|
||||
$url = WP_Installer()->append_site_key_to_download_url( $a_plugin['url'], 'xxxxxx', $repository_id );
|
||||
$tmpfname = wp_tempnam( $url );
|
||||
$tmpname_length = strlen( basename( $tmpfname ) ) - 4; // -.tmp
|
||||
wp_delete_file( $tmpfname );
|
||||
|
||||
if ( $upgrade_path_length + $tmpname_length + $longest_path[ $repository_id ] + $margin > $windows_max_path_length ) {
|
||||
$this->is_win_paths_exception[ $repository_id ] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->is_win_paths_exception[ $repository_id ];
|
||||
}
|
||||
|
||||
public function is_uploading_allowed() {
|
||||
|
||||
if ( ! isset( $this->uploading_allowed ) ) {
|
||||
require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
|
||||
require_once WP_Installer()->plugin_path() . '/includes/class-installer-upgrader-skins.php';
|
||||
|
||||
$upgrader_skins = new Installer_Upgrader_Skins(); //use our custom (mute) Skin
|
||||
$upgrader = new Plugin_Upgrader( $upgrader_skins );
|
||||
|
||||
ob_start();
|
||||
$res = $upgrader->fs_connect( array( WP_CONTENT_DIR, WP_PLUGIN_DIR ) );
|
||||
ob_end_clean();
|
||||
|
||||
if ( ! $res || is_wp_error( $res ) ) {
|
||||
$this->uploading_allowed = false;
|
||||
} else {
|
||||
$this->uploading_allowed = true;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->uploading_allowed;
|
||||
|
||||
}
|
||||
|
||||
public function cant_download( $repository_id ) {
|
||||
|
||||
return ! $this->is_uploading_allowed() || $this->is_win_paths_exception( $repository_id );
|
||||
|
||||
}
|
||||
|
||||
public function win_paths_exception_message() {
|
||||
return __( 'Downloading is not possible. WordPress cannot create required folders because of the
|
||||
256 characters limitation of the current Windows environment.', 'installer' );
|
||||
}
|
||||
|
||||
public function prevent_plugins_update_on_plugins_page() {
|
||||
|
||||
$plugins = get_site_transient( 'update_plugins' );
|
||||
if ( isset( $plugins->response ) && is_array( $plugins->response ) ) {
|
||||
$plugins_with_updates = array_keys( $plugins->response );
|
||||
}
|
||||
|
||||
if ( ! empty( $plugins_with_updates ) ) {
|
||||
|
||||
$plugins = get_plugins();
|
||||
|
||||
$installer_settings = WP_Installer()->settings;
|
||||
if ( isset( $installer_settings['repositories'] ) ) {
|
||||
foreach ( $installer_settings['repositories'] as $repository_id => $repository ) {
|
||||
|
||||
if ( $this->is_win_paths_exception( $repository_id ) ) {
|
||||
|
||||
$repositories_plugins = array();
|
||||
foreach ( $repository['data']['packages'] as $package ) {
|
||||
foreach ( $package['products'] as $product ) {
|
||||
foreach ( $product['plugins'] as $plugin_slug ) {
|
||||
$download = $installer_settings['repositories'][ $repository_id ]['data']['downloads']['plugins'][ $plugin_slug ];
|
||||
if ( empty( $download['free-on-wporg'] ) ) {
|
||||
$repositories_plugins[ $download['slug'] ] = $download['name'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ( $plugins as $plugin_id => $plugin ) {
|
||||
|
||||
if ( in_array( $plugin_id, $plugins_with_updates ) ) {
|
||||
|
||||
$wp_plugin_slug = dirname( $plugin_id );
|
||||
if ( empty( $wp_plugin_slug ) ) {
|
||||
$wp_plugin_slug = basename( $plugin_id, '.php' );
|
||||
}
|
||||
|
||||
foreach ( $repositories_plugins as $slug => $name ) {
|
||||
if ( $wp_plugin_slug == $slug || $name == $plugin['Name'] || $name == $plugin['Title'] ) { //match order: slug, name, title
|
||||
|
||||
remove_action( "after_plugin_row_$plugin_id", 'wp_plugin_update_row', 10, 2 );
|
||||
add_action( "after_plugin_row_$plugin_id", array(
|
||||
$this,
|
||||
'wp_plugin_update_row_win_exception',
|
||||
), 10, 2 );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function wp_plugin_update_row_win_exception() {
|
||||
$wp_list_table = _get_list_table( 'WP_Plugins_List_Table' );
|
||||
echo '<tr class="plugin-update-tr">';
|
||||
echo '<td class="plugin-update colspanchange" colspan="' . esc_attr( $wp_list_table->get_column_count() ) .
|
||||
'"><div class="update-message">' . $this->win_paths_exception_message() . '</div></td>';
|
||||
echo '</tr>';
|
||||
}
|
||||
|
||||
public function prevent_plugins_update_on_updates_screen() {
|
||||
|
||||
if ( isset( $_REQUEST['action'] ) ) {
|
||||
|
||||
$action = isset( $_REQUEST['action'] ) ? sanitize_text_field( $_REQUEST['action'] ) : '';
|
||||
|
||||
$installer_settings = WP_Installer()->settings;
|
||||
|
||||
//bulk mode
|
||||
if ( 'update-selected' == $action ) {
|
||||
|
||||
global $plugins;
|
||||
|
||||
if ( isset( $plugins ) && is_array( $plugins ) ) {
|
||||
|
||||
foreach ( $plugins as $k => $plugin ) {
|
||||
|
||||
$wp_plugin_slug = dirname( $plugin );
|
||||
|
||||
foreach ( $installer_settings['repositories'] as $repository_id => $repository ) {
|
||||
|
||||
if ( $this->is_win_paths_exception( $repository_id ) ) {
|
||||
|
||||
foreach ( $repository['data']['packages'] as $package ) {
|
||||
|
||||
foreach ( $package['products'] as $product ) {
|
||||
|
||||
foreach ( $product['plugins'] as $plugin_slug ) {
|
||||
|
||||
$download = $installer_settings['repositories'][ $repository_id ]['data']['downloads']['plugins'][ $plugin_slug ];
|
||||
|
||||
if ( $download['slug'] == $wp_plugin_slug && empty( $download['free-on-wporg'] ) ) {
|
||||
|
||||
echo '<div class="updated error"><p>' . $this->win_paths_exception_message() .
|
||||
' <strong>(' . $download['name'] . ')</strong>' . '</p></div>';
|
||||
unset( $plugins[ $k ] );
|
||||
|
||||
break( 3 );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if ( 'upgrade-plugin' == $action || 'update-plugin' == $action ) {
|
||||
|
||||
$plugin = isset( $_REQUEST['plugin'] ) ? trim( sanitize_text_field( $_REQUEST['plugin'] ) ) : '';
|
||||
|
||||
$wp_plugin_slug = dirname( $plugin );
|
||||
|
||||
foreach ( $installer_settings['repositories'] as $repository_id => $repository ) {
|
||||
|
||||
if ( $this->is_win_paths_exception( $repository_id ) ) {
|
||||
foreach ( $repository['data']['packages'] as $package ) {
|
||||
|
||||
foreach ( $package['products'] as $product ) {
|
||||
|
||||
foreach ( $product['plugins'] as $plugin_slug ) {
|
||||
$download = $installer_settings['repositories'][ $repository_id ]['data']['downloads']['plugins'][ $plugin_slug ];
|
||||
|
||||
//match by folder, will change to match by name and folder
|
||||
if ( $download['slug'] == $wp_plugin_slug && empty ( $download['free-on-wporg'] ) ) {
|
||||
|
||||
echo '<div class="updated error"><p>' . $this->win_paths_exception_message() . '</p></div>';
|
||||
|
||||
echo '<div class="wrap">';
|
||||
echo '<h2>' . __( 'Update Plugin' ) . '</h2>';
|
||||
echo '<a href="' . admin_url( 'update-core.php' ) . '">' . __( 'Return to the updates page', 'installer' ) . '</a>';
|
||||
echo '</div>';
|
||||
require_once( ABSPATH . 'wp-admin/admin-footer.php' );
|
||||
exit;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function php_libraries_missing() {
|
||||
$requirements = new OTGS_Installer_Requirements();
|
||||
|
||||
foreach ( $requirements->get() as $requirement ) {
|
||||
if ( ! $requirement['active'] ) {
|
||||
$this->missing_php_libraries[] = $requirement['name'];
|
||||
}
|
||||
}
|
||||
if ( $this->missing_php_libraries ) {
|
||||
add_action( 'admin_notices', array( $this, 'missing_php_functions_notice' ) );
|
||||
}
|
||||
}
|
||||
|
||||
public function missing_php_functions_notice() {
|
||||
$installer_doc_url = 'https://wpml.org/?p=72674#automated-updates';
|
||||
$installer_doc_link = '<a href="' . $installer_doc_url . '">' . __( 'OTGS Installer', 'installer' ) . '</a>';
|
||||
|
||||
echo '<div class="updated error">';
|
||||
echo '<p>';
|
||||
echo sprintf(
|
||||
__( '%s, responsible for receiving automated updates for WPML and Toolset, requires the following PHP component(s) in order to function:', 'installer' ),
|
||||
$installer_doc_link
|
||||
);
|
||||
echo '<code>' . join( ', ', $this->missing_php_libraries ) . '</code>';
|
||||
echo '</p>';
|
||||
|
||||
$minimum_requirements_link = '<a href="https://wpml.org/?page_id=716">' . __( 'Minimum WPML requirements' ) . '</a>';
|
||||
echo '<p>' . sprintf( __( 'Learn more: %s', 'installer' ), $minimum_requirements_link ) . '</p>';
|
||||
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,995 @@
|
||||
<?php
|
||||
/**
|
||||
* Installer Class for Theme Support
|
||||
*
|
||||
* Supports automatic updates and installation of Toolset/WPML Themes
|
||||
*
|
||||
* @class Installer_Theme_Class
|
||||
* @version 1.6
|
||||
* @category Class
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
|
||||
if ( !defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Installer_Theme_Class
|
||||
*/
|
||||
class Installer_Theme_Class {
|
||||
|
||||
/** Theme Repository */
|
||||
private $theme_repo;
|
||||
|
||||
/** Repository API */
|
||||
private $repository_api;
|
||||
|
||||
/** Repository Theme Products */
|
||||
private $repository_theme_products;
|
||||
|
||||
/** Site URL */
|
||||
private $installer_site_url;
|
||||
|
||||
/** Site Key */
|
||||
private $installer_site_key;
|
||||
|
||||
/** The Themes Option */
|
||||
protected $installer_themes_option;
|
||||
|
||||
/** Update settings */
|
||||
protected $installer_themes_available_updates;
|
||||
|
||||
/** The Themes */
|
||||
protected $installer_themes = array();
|
||||
|
||||
/** Repository with themes */
|
||||
protected $installer_repo_with_themes;
|
||||
|
||||
/** Active tab */
|
||||
protected $installer_theme_active_tab;
|
||||
|
||||
/** Theme user registration */
|
||||
protected $theme_user_registration;
|
||||
|
||||
/** Client active subscription */
|
||||
protected $installer_theme_subscription_type;
|
||||
|
||||
public function __construct() {
|
||||
|
||||
/** Properties */
|
||||
|
||||
//Get installer repositories
|
||||
$installer_repositories = WP_Installer()->get_repositories();
|
||||
|
||||
//Get repos with themes
|
||||
$repos_with_themes = $this->installer_theme_reposities_that_has_themes( $installer_repositories );
|
||||
|
||||
if ( is_array( $repos_with_themes ) ) {
|
||||
//Assign to property
|
||||
$this->installer_repo_with_themes = $repos_with_themes;
|
||||
|
||||
//Let's looped through repos with themes
|
||||
foreach ( $repos_with_themes as $k => $repo ) {
|
||||
|
||||
//$repo could be 'toolset' or 'wpml'
|
||||
//Assign each repo with theme to property
|
||||
$this->theme_repo[] = $repo;
|
||||
|
||||
if ( isset( $installer_repositories[ $repo ]['api-url'] ) ) {
|
||||
$products_manager = WP_Installer()->get_products_manager();
|
||||
//Define the rest of the properties based on the given repo
|
||||
$this->repository_api[$repo] = $installer_repositories[$repo]['api-url'];
|
||||
$this->installer_site_url[$repo] = WP_Installer()->get_installer_site_url( $repo );
|
||||
$this->installer_site_key[$repo] = WP_Installer()->get_site_key( $repo );
|
||||
$this->repository_theme_products[ $repo ] = $products_manager->get_products_url(
|
||||
$repo,
|
||||
$this->installer_site_key[ $repo ],
|
||||
$this->installer_site_url[ $repo ],
|
||||
false
|
||||
);
|
||||
|
||||
|
||||
$this->theme_user_registration[$repo] = false;
|
||||
|
||||
if ( WP_Installer()->repository_has_valid_subscription( $repo ) ) {
|
||||
|
||||
$this->installer_theme_subscription_type = WP_Installer()->get_subscription_type_for_repository( $repo );
|
||||
$this->installer_themes_option[$repo] = 'wp_installer_' . $repo . '_themes';
|
||||
$this->installer_themes_available_updates[$repo] = 'wp_installer_' . $repo . '_updated_themes';
|
||||
$this->installer_theme_active_tab = '';
|
||||
|
||||
//We only set themes available to this validated subscription
|
||||
$this->installer_theme_available( $repo, $this->installer_theme_subscription_type );
|
||||
|
||||
add_action( 'installer_themes_support_set_up', array($this, 'installer_theme_sets_active_tab_on_init'), 10 );
|
||||
$this->theme_user_registration[$repo] = true;
|
||||
}
|
||||
|
||||
/** We are ready.. let's initialize .... */
|
||||
$this->init();
|
||||
}
|
||||
}
|
||||
add_action( 'installer_themes_support_set_up', array($this, 'installer_theme_loaded_hooks') );
|
||||
}
|
||||
}
|
||||
|
||||
/** Init */
|
||||
public function init() {
|
||||
add_action( 'admin_enqueue_scripts', array($this, 'installer_theme_enqueue_scripts') );
|
||||
add_filter( 'themes_api', array($this, 'installer_theme_api_override'), 10, 3 );
|
||||
add_filter( 'themes_api_result', array($this, 'installer_theme_api_override_response'), 10, 3 );
|
||||
add_filter( 'site_transient_update_themes', array($this, 'installer_theme_upgrade_check'), 10, 1 );
|
||||
add_action( 'http_api_debug', array($this, 'installer_theme_sync_native_wp_api'), 10, 5 );
|
||||
add_filter( 'installer_theme_hook_response_theme', array($this, 'installer_theme_add_num_ratings'), 10, 1 );
|
||||
add_filter( 'themes_update_check_locales', array($this, 'installer_theme_sync_call_wp_theme_api'), 10, 1 );
|
||||
add_filter( 'admin_url', array($this, 'installer_theme_add_query_arg_tab'), 10, 3 );
|
||||
add_filter( 'network_admin_url', array($this, 'installer_theme_add_query_arg_tab'), 10, 2 );
|
||||
add_action( 'wp_ajax_installer_theme_frontend_selected_tab', array($this, 'installer_theme_frontend_selected_tab'), 0 );
|
||||
add_action( 'wp_loaded', array($this, 'installer_themes_support_set_up_func') );
|
||||
}
|
||||
|
||||
/** Enqueue scripts */
|
||||
public function installer_theme_enqueue_scripts() {
|
||||
$current_screen = $this->installer_theme_current_screen();
|
||||
$commercial_plugin_screen = $this->installer_theme_is_commercial_plugin_screen( $current_screen );
|
||||
if ( ('theme-install' == $current_screen) || ($commercial_plugin_screen) || ('theme-install-network' == $current_screen) ) {
|
||||
$repo_with_themes = $this->installer_repo_with_themes;
|
||||
$js_array = array();
|
||||
if ( is_array( $repo_with_themes ) ) {
|
||||
foreach ( $repo_with_themes as $k => $v ) {
|
||||
|
||||
//Hyperlink text
|
||||
$theme_repo_name = $this->installer_theme_get_repo_product_name( $v );
|
||||
$the_hyperlink_text = esc_js( $theme_repo_name );
|
||||
|
||||
if ( is_multisite() ) {
|
||||
$admin_url_passed = network_admin_url();
|
||||
} else {
|
||||
$admin_url_passed = admin_url();
|
||||
}
|
||||
|
||||
//Define
|
||||
$js_array[$v] = array(
|
||||
'the_hyperlink_text' => $the_hyperlink_text,
|
||||
'registration_status' => $this->theme_user_registration[$v],
|
||||
'is_commercial_plugin_tab' => $commercial_plugin_screen,
|
||||
'registration_url' => $admin_url_passed . 'plugin-install.php?tab=commercial#installer_repo_' . $v
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if ( !(empty($js_array)) ) {
|
||||
wp_register_script( 'otgs-purify', WP_Installer()->res_url() . '/dist/js/domPurify/app.js', [], WP_Installer()->version() );
|
||||
wp_enqueue_script( 'installer-theme-install', WP_Installer()->res_url() . '/res/js/installer_theme_install.js', [
|
||||
'jquery',
|
||||
'otgs-purify'
|
||||
], WP_Installer()->version() );
|
||||
$installer_ajax_url = admin_url( 'admin-ajax.php' );
|
||||
|
||||
if ( is_ssl() ) {
|
||||
$installer_ajax_url = str_replace( 'http://', 'https://', $installer_ajax_url );
|
||||
} else {
|
||||
$installer_ajax_url = str_replace( 'https://', 'http://', $installer_ajax_url );
|
||||
}
|
||||
|
||||
//Case where user is subscribed to a subscription that does not have themes
|
||||
$subscription_js_check = $this->installer_theme_subscription_does_not_have_theme( $js_array );
|
||||
|
||||
wp_localize_script( 'installer-theme-install', 'installer_theme_install_localize',
|
||||
array(
|
||||
'js_array_installer' => $js_array,
|
||||
'ajaxurl' => $installer_ajax_url,
|
||||
'no_associated_themes' => $subscription_js_check,
|
||||
'installer_theme_frontend_selected_tab_nonce' => wp_create_nonce( 'installer_theme_frontend_selected_tab' )
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Case where user is subscribed to a subscription that does not have themes */
|
||||
protected function installer_theme_subscription_does_not_have_theme( $js_array ) {
|
||||
|
||||
$any_subscription_has_theme = array();
|
||||
$number_of_registrations = array();
|
||||
|
||||
//Step1, we looped through JS array
|
||||
foreach ( $js_array as $repo_slug => $js_details ) {
|
||||
|
||||
//Step2, checked if user is registered
|
||||
if ( isset($this->theme_user_registration[$repo_slug]) ) {
|
||||
$registration_status = $this->theme_user_registration[$repo_slug];
|
||||
if ( $registration_status ) {
|
||||
|
||||
//Registered
|
||||
$number_of_registrations[] = $repo_slug;
|
||||
|
||||
//Step3, we checked if the $repo_slug has available theme
|
||||
$themes_available = false;
|
||||
if ( isset($this->installer_themes[$repo_slug]) ) {
|
||||
$themes_available = $this->installer_themes[$repo_slug];
|
||||
if ( !(empty($themes_available)) ) {
|
||||
//This subscription has theme
|
||||
$themes_available = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $themes_available ) {
|
||||
$any_subscription_has_theme[] = $repo_slug;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//Step4, we are done looping, check if there are any repos that have themes
|
||||
if ( empty($registration_status) ) {
|
||||
|
||||
//No registration on any repos
|
||||
return FALSE;
|
||||
|
||||
} elseif ( !(empty($registration_status)) ) {
|
||||
|
||||
//Has some registration on some repos
|
||||
//We then checked if this user has any active subscriptions
|
||||
if ( empty($any_subscription_has_theme) ) {
|
||||
//No subscription
|
||||
return TRUE;
|
||||
} else {
|
||||
//Has subscription found
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Check if its the commercial plugin screen */
|
||||
private function installer_theme_is_commercial_plugin_screen( $current_screen ) {
|
||||
$commercial = false;
|
||||
if ( ('plugin-install' == $current_screen) || ('plugin-install-network' == $current_screen) ) {
|
||||
if ( isset($_GET['tab']) ) {
|
||||
$tab = sanitize_text_field( $_GET['tab'] );
|
||||
if ( 'commercial' == $tab ) {
|
||||
$commercial = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $commercial;
|
||||
}
|
||||
|
||||
/** Current screen */
|
||||
private function installer_theme_current_screen() {
|
||||
|
||||
$current_screen_loaded = false;
|
||||
|
||||
if ( function_exists( 'get_current_screen' ) ) {
|
||||
|
||||
$screen_output = get_current_screen();
|
||||
$current_screen_loaded = $screen_output->id;
|
||||
|
||||
}
|
||||
|
||||
return $current_screen_loaded;
|
||||
|
||||
}
|
||||
|
||||
/** Override WordPress Themes API */
|
||||
public function installer_theme_api_override( $api_boolean, $action, $args ) {
|
||||
|
||||
//Let's checked if user is browsing our themes
|
||||
if ( isset($args->browse) ) {
|
||||
$browse = $args->browse;
|
||||
if ( in_array( $browse, $this->theme_repo ) ) {
|
||||
//Uniquely validated for our Themes
|
||||
if ( 'query_themes' == $action ) {
|
||||
//User is querying or asking information about our themes, let's override
|
||||
$api_boolean = true;
|
||||
}
|
||||
}
|
||||
} elseif ( isset($args->slug) ) {
|
||||
//We are installing our themes
|
||||
$theme_to_install = $args->slug;
|
||||
|
||||
//Lets uniquely validate if this belongs to us
|
||||
//Check if this is OTGS theme
|
||||
$validate_check = $this->installer_themes_belong_to_us( $theme_to_install );
|
||||
if ( $validate_check ) {
|
||||
//Belongs to us
|
||||
if ( !(empty($theme_to_install)) ) {
|
||||
$api_boolean = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $api_boolean;
|
||||
}
|
||||
|
||||
/** Override WordPress Themes API response with our own themes API*/
|
||||
public function installer_theme_api_override_response( $res, $action, $args ) {
|
||||
if ( true === $res ) {
|
||||
if ( isset($args->browse) ) {
|
||||
$browse = $args->browse;
|
||||
if ( in_array( $browse, $this->theme_repo ) ) {
|
||||
//Uniquely validated for our themes
|
||||
if ( 'query_themes' == $action ) {
|
||||
//Client querying OTGS themes
|
||||
//Check for registration status
|
||||
if ( isset($this->theme_user_registration[$browse]) ) {
|
||||
//Set
|
||||
if ( !($this->theme_user_registration[$browse]) ) {
|
||||
//Not registered yet
|
||||
$res = new stdClass();
|
||||
$res->info = array();
|
||||
$res->themes = array();
|
||||
return $res;
|
||||
} else {
|
||||
//Registered
|
||||
$themes = $this->installer_theme_get_themes( '', $browse );
|
||||
$res = $this->installer_theme_format_response( $themes, $action );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} elseif ( isset($args->slug) ) {
|
||||
//We are installing theme
|
||||
//Lets uniquely validate if this belongs to our theme
|
||||
$theme_to_install = $args->slug;
|
||||
|
||||
//Lets uniquely validate if this belongs to us
|
||||
//Check if this is OTGS theme
|
||||
$validate_check = $this->installer_themes_belong_to_us( $theme_to_install );
|
||||
if ( $validate_check ) {
|
||||
//Belongs to us
|
||||
if ( ($res) && ('theme_information' == $action) ) {
|
||||
$themes = $this->installer_theme_get_themes( '', $this->installer_theme_active_tab );
|
||||
$res = $this->installer_theme_format_response( $themes, $action, $args->slug );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
/** Get Themes */
|
||||
private function installer_theme_get_themes( $product_url = '', $repository_id = '' ) {
|
||||
|
||||
//Query API
|
||||
if ( empty($product_url) ) {
|
||||
//Not set
|
||||
if ( isset($this->repository_theme_products[$this->installer_theme_active_tab]) ) {
|
||||
$query_remote_url = $this->repository_theme_products[$this->installer_theme_active_tab];
|
||||
}
|
||||
|
||||
} else {
|
||||
$query_remote_url = $product_url;
|
||||
}
|
||||
|
||||
//Let's retrieved current installer settings so we won't be querying all the time
|
||||
$current_installer_settings = WP_Installer()->get_settings();
|
||||
|
||||
//Set $themes to FALSE by default
|
||||
$themes = false;
|
||||
|
||||
if ( (is_array( $current_installer_settings )) && (!(empty($current_installer_settings))) ) {
|
||||
|
||||
//Set and already defined, retrieved $products
|
||||
if ( isset($current_installer_settings['repositories'][$repository_id]['data']) ) {
|
||||
$products = $current_installer_settings['repositories'][$repository_id]['data'];
|
||||
if ( isset($products['downloads']['themes']) ) {
|
||||
$themes = $products['downloads']['themes'];
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
//Call API
|
||||
$response = wp_remote_get( $query_remote_url );
|
||||
|
||||
if ( is_wp_error( $response ) ) {
|
||||
//Error detected: http fallback
|
||||
$query_remote_url = preg_replace( "@^https://@", 'http://', $query_remote_url );
|
||||
$response = wp_remote_get( $query_remote_url );
|
||||
}
|
||||
|
||||
if ( !(is_wp_error( $response )) ) {
|
||||
//Not WP error
|
||||
//Evaluate response
|
||||
if ( $response && isset($response['response']['code']) && $response['response']['code'] == 200 ) {
|
||||
//In this case, response is set and defined, proceed...
|
||||
$body = wp_remote_retrieve_body( $response );
|
||||
if ( $body ) {
|
||||
$products = json_decode( $body, true );
|
||||
if ( isset($products['downloads']['themes']) ) {
|
||||
$themes = $products['downloads']['themes'];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Return themes, can be filtered by user subscription type
|
||||
return apply_filters( 'installer_theme_get_themes', $themes, $this->installer_theme_active_tab );
|
||||
}
|
||||
|
||||
/** Format response in compatibility with WordPress Theme API response */
|
||||
private function installer_theme_format_response( $themes, $action, $slug = '' ) {
|
||||
|
||||
//Let's append download link only when retrieving theme information for installation
|
||||
if ( ('theme_information' == $action) && (!(empty($slug))) ) {
|
||||
|
||||
//Only return one result -> the theme to be installed
|
||||
foreach ( $themes as $k => $theme ) {
|
||||
if ( $slug == $theme['basename'] ) {
|
||||
$theme['download_link'] = WP_Installer()->append_site_key_to_download_url( $theme['url'], $this->installer_site_key[$this->installer_theme_active_tab], $this->installer_theme_active_tab );
|
||||
$theme = json_decode( json_encode( $theme ), FALSE );
|
||||
return $theme;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
$res = new stdClass();
|
||||
$res->info = array();
|
||||
$res->themes = array();
|
||||
|
||||
//Define info
|
||||
$res->info['page'] = 1;
|
||||
$res->info['pages'] = 10;
|
||||
|
||||
//Let's count available themes ;
|
||||
$res->info['results'] = count( $themes );
|
||||
|
||||
//Let's saved themes for easy access later on
|
||||
$this->installer_theme_savethemes_by_slug( $themes );
|
||||
|
||||
//Let's defined available themes
|
||||
if ( isset($this->installer_theme_subscription_type) ) {
|
||||
//Has subscription type defined, let's saved what is associated with this subscription
|
||||
$this->installer_theme_available( $this->installer_theme_active_tab, $this->installer_theme_subscription_type );
|
||||
} else {
|
||||
$this->installer_theme_available( $this->installer_theme_active_tab );
|
||||
}
|
||||
|
||||
//Let's add themes to the overriden WordPress API Theme response
|
||||
/** Installer 1.7.6: Update to compatible data format response from WP Theme API */
|
||||
$theme_compatible_array=array();
|
||||
if ((is_array($themes))) {
|
||||
foreach ($themes as $k=>$v) {
|
||||
$theme_compatible_array[]=(object)($v);
|
||||
}
|
||||
}
|
||||
$res->themes = $theme_compatible_array;
|
||||
$res->themes = apply_filters( 'installer_theme_hook_response_theme', $res->themes );
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
|
||||
/** Let's save all available themes by its slug after any latest API query */
|
||||
private function installer_theme_savethemes_by_slug( $themes, $doing_query = false ) {
|
||||
|
||||
if ( !($doing_query) ) {
|
||||
$this->installer_themes[$this->installer_theme_active_tab] = array();
|
||||
}
|
||||
|
||||
if ( !(empty($themes)) ) {
|
||||
$themes_for_saving = array();
|
||||
foreach ( $themes as $k => $theme ) {
|
||||
if ( !($doing_query) ) {
|
||||
if ( isset($theme['slug']) ) {
|
||||
$theme_slug = $theme['slug'];
|
||||
if ( !(empty($theme_slug)) ) {
|
||||
$themes_for_saving[] = $theme_slug;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
if ( ((isset($theme['slug'])) && (isset($theme['version'])) &&
|
||||
(isset($theme['theme_page_url']))) && (isset($theme['url']))
|
||||
) {
|
||||
$theme_slug = $theme['slug'];
|
||||
$theme_version = $theme['version'];
|
||||
$theme_page_url = $theme['theme_page_url'];
|
||||
$theme_url = $theme['url'];
|
||||
if ( (!(empty($theme_slug))) && (!(empty($theme_version))) &&
|
||||
(!(empty($theme_page_url))) && (!(empty($theme_url)))
|
||||
) {
|
||||
//$theme_slug is unique for every theme
|
||||
$themes_for_saving[$theme_slug] = array(
|
||||
'version' => $theme_version,
|
||||
'theme_page_url' => $theme_page_url,
|
||||
'url' => $theme_url
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( !(empty($themes_for_saving)) ) {
|
||||
//Has themes for saving
|
||||
if ( !($doing_query) ) {
|
||||
//Not doing query
|
||||
$existing_themes = get_option( $this->installer_themes_option[$this->installer_theme_active_tab] );
|
||||
if ( !($existing_themes) ) {
|
||||
//Does not yet exists
|
||||
delete_option( $this->installer_themes_option[$this->installer_theme_active_tab] );
|
||||
update_option( $this->installer_themes_option[$this->installer_theme_active_tab], $themes_for_saving );
|
||||
} else {
|
||||
//exists, check if we need to update
|
||||
if ( $existing_themes == $themes_for_saving ) {
|
||||
//Equal, no need to update here
|
||||
} else {
|
||||
//Update
|
||||
delete_option( $this->installer_themes_option[$this->installer_theme_active_tab] );
|
||||
update_option( $this->installer_themes_option[$this->installer_theme_active_tab], $themes_for_saving );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//Used for query purposes only, don't save anything
|
||||
return $themes_for_saving;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Available themes */
|
||||
private function installer_theme_available( $repo, $subscription_type = '' ) {
|
||||
|
||||
$subscription_type = intval( $subscription_type );
|
||||
if ( $subscription_type > 0 ) {
|
||||
|
||||
//Here we have a case of validated subscription
|
||||
//We need to set themes that is available to this subscription
|
||||
$themes_associated_with_subscription = $this->installer_themes[$repo] = $this->installer_theme_get_themes_by_subscription( $subscription_type, $repo );
|
||||
if ( !(empty($themes_associated_with_subscription)) ) {
|
||||
//Has themes
|
||||
$this->installer_themes[$repo] = $themes_associated_with_subscription;
|
||||
}
|
||||
} else {
|
||||
|
||||
//Get themes
|
||||
$this->installer_themes[$repo] = get_option( $this->installer_themes_option[$repo] );
|
||||
}
|
||||
}
|
||||
|
||||
/** Theme upgrade check */
|
||||
public function installer_theme_upgrade_check( $the_value ) {
|
||||
|
||||
//Step1: Let's looped through repos with themes and check if we have updates available for them.
|
||||
if ( (is_array( $this->installer_repo_with_themes )) && (!(empty($this->installer_repo_with_themes))) ) {
|
||||
foreach ( $this->installer_repo_with_themes as $k => $repo_slug ) {
|
||||
//Step2: Let's checked if we have update for this theme
|
||||
if ( is_array( $this->installer_themes_available_updates ) && isset( $this->installer_themes_available_updates[ $repo_slug ] ) ) {
|
||||
$update_available = get_option( $this->installer_themes_available_updates[ $repo_slug ] );
|
||||
} else {
|
||||
$update_available = false;
|
||||
}
|
||||
|
||||
if ( $update_available ) {
|
||||
if ( (is_array( $update_available )) && (!(empty($update_available))) ) {
|
||||
//Has updates available coming from this specific theme repo
|
||||
//Let's loop through the themes that needs update
|
||||
foreach ( $update_available as $theme_slug => $v ) {
|
||||
//Add to response API
|
||||
$the_value->response [$theme_slug] = array(
|
||||
'theme' => $theme_slug,
|
||||
'new_version' => $v['new_version'],
|
||||
'url' => $v['url'],
|
||||
'package' => $v['package']
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//Return
|
||||
return $the_value;
|
||||
}
|
||||
|
||||
/** Return repositories that has themes */
|
||||
private function installer_theme_reposities_that_has_themes( $repositories, $ret_value = true, $doing_api_query = false ) {
|
||||
|
||||
$repositories_with_themes = array();
|
||||
|
||||
if ( (is_array( $repositories )) && (!(empty($repositories))) ) {
|
||||
|
||||
//Let's checked if we have something before
|
||||
$themes = get_option( 'installer_repositories_with_theme' );
|
||||
|
||||
if ( (!($themes)) || ($doing_api_query) ) {
|
||||
//Not yet defined
|
||||
//Loop through each repositories and check whether they have themes
|
||||
foreach ( $repositories as $repository_id => $repository_data ) {
|
||||
$products_manager = WP_Installer()->get_products_manager();
|
||||
$product_url = $products_manager->get_products_url(
|
||||
$repository_id,
|
||||
WP_Installer()->get_site_key( $repository_id ),
|
||||
WP_Installer()->get_installer_site_url( $repository_id ),
|
||||
false
|
||||
);
|
||||
if ( $product_url ) {
|
||||
$themes = $this->installer_theme_get_themes( $product_url, $repository_id );
|
||||
if ( ( is_array( $themes ) ) && ( ! ( empty( $themes ) ) ) ) {
|
||||
//Repo has themes
|
||||
$repositories_with_themes[] = $repository_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//Already set
|
||||
$repositories_with_themes = $themes;
|
||||
}
|
||||
|
||||
if ( (((is_array( $repositories_with_themes )) && (!(empty($repositories_with_themes)))) && (!($themes))) || ($doing_api_query) ) {
|
||||
//Save to db
|
||||
update_option( 'installer_repositories_with_theme', $repositories_with_themes );
|
||||
}
|
||||
}
|
||||
|
||||
if ( $ret_value ) {
|
||||
return $repositories_with_themes;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** When WordPress queries its own Themes API, we sync with our own */
|
||||
public function installer_theme_sync_native_wp_api( $response, $responsetext, $class, $args, $url ) {
|
||||
|
||||
$api_native_string = 'api.wordpress.org/themes/';
|
||||
if ( (strpos( $url, $api_native_string ) !== false) ) {
|
||||
//WordPress is querying its own themes API
|
||||
$installer_repositories = WP_Installer()->get_repositories();
|
||||
|
||||
//Query our own API and update repository values too
|
||||
$this->installer_theme_reposities_that_has_themes( $installer_repositories, false, true );
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns product name by theme repo slug */
|
||||
private function installer_theme_get_repo_product_name( $theme_repo ) {
|
||||
|
||||
$theme_repo_name = false;
|
||||
|
||||
if ( isset(WP_Installer()->settings['repositories'][$theme_repo]['data']['product-name']) ) {
|
||||
//Set
|
||||
$prod_name = WP_Installer()->settings['repositories'][$theme_repo]['data']['product-name'];
|
||||
if ( !(empty($prod_name)) ) {
|
||||
$theme_repo_name = $prod_name;
|
||||
}
|
||||
} else {
|
||||
//Not yet
|
||||
if ( $theme_repo == $this->theme_repo ) {
|
||||
$result = $this->installer_theme_general_api_query();
|
||||
if ( isset($result['product-name']) ) {
|
||||
$product_name = $result['product-name'];
|
||||
if ( !(empty($product_name)) ) {
|
||||
$theme_repo_name = $product_name;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $theme_repo_name;
|
||||
}
|
||||
|
||||
/** General query API method, returns $products */
|
||||
private function installer_theme_general_api_query() {
|
||||
$products = false;
|
||||
$response = wp_remote_get( $this->repository_theme_products );
|
||||
if ( !(is_wp_error( $response )) ) {
|
||||
//Not WP error
|
||||
//Evaluate response
|
||||
if ( $response && isset($response['response']['code']) && $response['response']['code'] == 200 ) {
|
||||
//In this case, response is set and defined, proceed...
|
||||
$body = wp_remote_retrieve_body( $response );
|
||||
if ( $body ) {
|
||||
$result = json_decode( $body, true );
|
||||
if ( (is_array( $result )) && (!(empty($result))) ) {
|
||||
$products = $result;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return $products;
|
||||
}
|
||||
|
||||
/** General method to check if themes are OTGS themes based on its slug*/
|
||||
private function installer_themes_belong_to_us( $theme_slug ) {
|
||||
|
||||
$found = false;
|
||||
$theme_slug = trim( $theme_slug );
|
||||
|
||||
foreach ( $this->installer_themes as $repo_with_theme => $themes ) {
|
||||
foreach ( $themes as $k => $otgs_theme_slug ) {
|
||||
if ( $theme_slug == $otgs_theme_slug ) {
|
||||
//match found! Theme belongs to otgs
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $found;
|
||||
|
||||
}
|
||||
|
||||
/** Sets active tab on init */
|
||||
public function installer_theme_sets_active_tab_on_init() {
|
||||
|
||||
if ( isset ($_SERVER ['REQUEST_URI']) ) {
|
||||
$request_uri = $_SERVER ['REQUEST_URI'];
|
||||
if ( isset ($_GET ['browse']) ) {
|
||||
$active_tab = sanitize_text_field( $_GET['browse'] );
|
||||
$this->installer_theme_active_tab = $active_tab;
|
||||
} elseif ( isset ($_POST ['request'] ['browse']) ) {
|
||||
$active_tab = sanitize_text_field ( $_POST['request']['browse'] );
|
||||
$this->installer_theme_active_tab = $active_tab;
|
||||
} elseif ( (isset ($_GET ['theme_repo'])) && (isset ($_GET ['action'])) ) {
|
||||
$theme_repo = sanitize_text_field( $_GET['theme_repo'] );
|
||||
$the_action = sanitize_text_field( $_GET['action'] );
|
||||
if ( ('install-theme' == $the_action) && (!(empty($theme_repo))) ) {
|
||||
$this->installer_theme_active_tab = $theme_repo;
|
||||
}
|
||||
} elseif ( wp_get_referer() ) {
|
||||
$referer = wp_get_referer();
|
||||
$parts = parse_url( $referer );
|
||||
if ( isset($parts['query']) ) {
|
||||
parse_str( $parts['query'], $query );
|
||||
if ( isset($query['browse']) ) {
|
||||
$this->installer_theme_active_tab = $query['browse'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** WP Theme API compatibility- added num ratings */
|
||||
/** Installer 1.7.6+ Added updated 'rating' field */
|
||||
public function installer_theme_add_num_ratings( $themes ) {
|
||||
|
||||
if ( (is_array( $themes )) && (!(empty($themes))) ) {
|
||||
foreach ( $themes as $k => $v ) {
|
||||
if ( !(isset($v->num_ratings)) ) {
|
||||
$themes[$k]->num_ratings = 100;
|
||||
}
|
||||
if ( !(isset($v->rating)) ) {
|
||||
$themes[$k]->rating = 100;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $themes;
|
||||
}
|
||||
|
||||
/** When WordPress.org makes a call to its repository, let's run our own upgrade checks too */
|
||||
public function installer_theme_sync_call_wp_theme_api( $locales ) {
|
||||
|
||||
$this->installer_theme_upgrade_theme_check();
|
||||
|
||||
return $locales;
|
||||
}
|
||||
|
||||
/** Upgrade theme check */
|
||||
private function installer_theme_upgrade_theme_check() {
|
||||
|
||||
// Step1-> we get all installed themes in clients local themes directory
|
||||
$installed_themes = wp_get_themes();
|
||||
|
||||
// Step2: We need to loop through each repository with themes
|
||||
foreach ( $this->installer_repo_with_themes as $k => $repo_slug ) {
|
||||
|
||||
// We then need to retrieved the products URL for each of this repo
|
||||
$products_url = $this->repository_theme_products [$repo_slug];
|
||||
|
||||
// Step3-> we get all available themes in our repository via API based on this URL
|
||||
$available_themes = $this->installer_theme_get_themes( $products_url, $repo_slug );
|
||||
|
||||
if ( !($available_themes) ) {
|
||||
|
||||
// API is not available as of the moment, return..
|
||||
return;
|
||||
} else {
|
||||
|
||||
// We have available themes here...
|
||||
// Step4->let's simplify available themes data by slugs
|
||||
$simplified_available_themes = $this->installer_theme_savethemes_by_slug( $available_themes, true );
|
||||
|
||||
// Step5->Let's loop through installed themes
|
||||
if ( (is_array( $installed_themes )) && (!(empty ($installed_themes))) ) {
|
||||
$otgs_theme_updates_available = array();
|
||||
foreach ( $installed_themes as $theme_slug => $theme_object ) {
|
||||
if ( array_key_exists( $theme_slug, $simplified_available_themes ) ) {
|
||||
|
||||
// This is our theme
|
||||
// Step6->Let's get version of the local theme installed
|
||||
$local_version = $theme_object->get( 'Version' );
|
||||
|
||||
// Step7->Let's get the latest version of this theme, page URL and download URL from our repository
|
||||
$repository_version = $simplified_available_themes [$theme_slug] ['version'];
|
||||
$theme_page_url = $simplified_available_themes [$theme_slug] ['theme_page_url'];
|
||||
$theme_download_url = $simplified_available_themes [$theme_slug] ['url'];
|
||||
|
||||
// Step8->Let's compare the version
|
||||
if ( version_compare( $repository_version, $local_version, '>' ) ) {
|
||||
|
||||
// Update available for this theme
|
||||
// Step9-> Define download URL with site key
|
||||
$package_url = WP_Installer()->append_site_key_to_download_url( $theme_download_url, $this->installer_site_key [$repo_slug], $repo_slug );
|
||||
|
||||
//Step10-> Assign to updates array for later accessing.
|
||||
$otgs_theme_updates_available[$theme_slug] = array(
|
||||
'theme' => $theme_slug,
|
||||
'new_version' => $repository_version,
|
||||
'url' => $theme_page_url,
|
||||
'package' => $package_url
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
//Exited the upgrade loop for this specific theme repository
|
||||
if ( !empty($otgs_theme_updates_available) ) {
|
||||
//Has updates
|
||||
if ( is_array( $this->installer_themes_available_updates ) && isset( $this->installer_themes_available_updates[ $repo_slug ] ) ) {
|
||||
update_option( $this->installer_themes_available_updates[ $repo_slug ], $otgs_theme_updates_available );
|
||||
}
|
||||
} else {
|
||||
//No updates
|
||||
if ( is_array( $this->installer_themes_available_updates ) && isset( $this->installer_themes_available_updates[ $repo_slug ] ) ) {
|
||||
//No updates
|
||||
delete_option( $this->installer_themes_available_updates[ $repo_slug ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** When the user is on Themes install page OTG themes repository, let's the currently selected tab */
|
||||
public function installer_theme_add_query_arg_tab( $url, $path, $blog_id = null ) {
|
||||
|
||||
$wp_install_string = 'update.php?action=install-theme';
|
||||
if ( $path == $wp_install_string ) {
|
||||
if ( isset($this->installer_theme_active_tab) ) {
|
||||
if ( !(empty($this->installer_theme_active_tab)) ) {
|
||||
$url = add_query_arg( array(
|
||||
'theme_repo' => $this->installer_theme_active_tab
|
||||
), $url );
|
||||
}
|
||||
}
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
|
||||
/** Save frontend theme tab selected */
|
||||
public function installer_theme_frontend_selected_tab() {
|
||||
if ( isset($_POST["frontend_tab_selected"]) ) {
|
||||
check_ajax_referer( 'installer_theme_frontend_selected_tab', 'installer_theme_frontend_selected_tab_nonce' );
|
||||
|
||||
//Client_side_active_tab
|
||||
$frontend_tab_selected = sanitize_text_field( $_POST['frontend_tab_selected'] );
|
||||
if ( !(empty($frontend_tab_selected)) ) {
|
||||
//Front end tab selected
|
||||
update_option( 'wp_installer_clientside_active_tab', $frontend_tab_selected, false );
|
||||
|
||||
//Check for registration status
|
||||
if ( isset($this->theme_user_registration[$frontend_tab_selected]) ) {
|
||||
//Set
|
||||
if ( !($this->theme_user_registration[$frontend_tab_selected]) ) {
|
||||
//Not registered yet
|
||||
|
||||
if ( is_multisite() ) {
|
||||
$admin_url_passed = network_admin_url();
|
||||
} else {
|
||||
$admin_url_passed = admin_url();
|
||||
}
|
||||
|
||||
$registration_url = $admin_url_passed . 'plugin-install.php?tab=commercial#installer_repo_' . $frontend_tab_selected;
|
||||
|
||||
//Message and link
|
||||
$theme_repo_name = $this->installer_theme_get_repo_product_name( $frontend_tab_selected );;
|
||||
$response['unregistered_messages'] = sprintf( __( 'To install and update %s, please %sregister%s %s for this site.', 'installer' ),
|
||||
$theme_repo_name, '<a href="' . $registration_url . '">', '</a>', $theme_repo_name );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
$response['output'] = $frontend_tab_selected;
|
||||
echo json_encode( $response );
|
||||
}
|
||||
die();
|
||||
}
|
||||
die();
|
||||
}
|
||||
|
||||
/** Installer loaded aux hooks */
|
||||
public function installer_theme_loaded_hooks() {
|
||||
|
||||
if ( isset($this->installer_theme_subscription_type) ) {
|
||||
$subscription_type = intval( $this->installer_theme_subscription_type );
|
||||
if ( $subscription_type > 0 ) {
|
||||
//Client is subscribed
|
||||
add_filter( 'installer_theme_get_themes', array($this, 'installer_theme_filter_themes_by_subscription'), 10, 2 );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** Get themes by subscription type */
|
||||
protected function installer_theme_get_themes_by_subscription( $subscription_type, $repo ) {
|
||||
|
||||
$themes_associated_with_subscription = array();
|
||||
if ( isset(WP_Installer()->settings['repositories'][$repo]['data']['packages']) ) {
|
||||
//Set
|
||||
$packages = WP_Installer()->settings['repositories'][$repo]['data']['packages'];
|
||||
$available_themes_subscription = array();
|
||||
foreach ( $packages as $package_id => $package_details ) {
|
||||
if ( isset($package_details['products']) ) {
|
||||
$the_products = $package_details['products'];
|
||||
foreach ( $the_products as $product_slug => $product_details ) {
|
||||
if ( isset($product_details['subscription_type']) ) {
|
||||
$subscription_type_from_settings = intval( $product_details['subscription_type'] );
|
||||
if ( $subscription_type_from_settings == $subscription_type ) {
|
||||
//We found the subscription
|
||||
if ( isset($product_details['themes']) ) {
|
||||
$themes_associated_with_subscription = $product_details['themes'];
|
||||
return $themes_associated_with_subscription;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $themes_associated_with_subscription;
|
||||
}
|
||||
|
||||
/** Filter API theme response according to user subscription */
|
||||
public function installer_theme_filter_themes_by_subscription( $themes, $active_tab ) {
|
||||
|
||||
//Step1, we only filter OTGS themes
|
||||
$orig = is_array( $themes ) ? count( $themes ) : 0;
|
||||
if ( in_array( $active_tab, $this->theme_repo ) ) {
|
||||
//OTGS Theme
|
||||
//Step2, we retrieved the available themes based on client subscription
|
||||
if ( isset($this->installer_themes[$active_tab]) ) {
|
||||
$available_themes = $this->installer_themes[$active_tab];
|
||||
//Step3, we filter $themes based on this info
|
||||
if ( (is_array( $themes )) && (!(empty($themes))) ) {
|
||||
foreach ( $themes as $k => $theme ) {
|
||||
//Step4, get theme slug
|
||||
if ( isset($theme['slug']) ) {
|
||||
$theme_slug = $theme['slug'];
|
||||
if ( !(empty($theme_slug)) ) {
|
||||
if ( !(in_array( $theme_slug, $available_themes )) ) {
|
||||
//This theme is not in available themes
|
||||
unset($themes[$k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$new = is_array( $themes ) ? count( $themes ) : 0;
|
||||
if ( $orig != $new ) {
|
||||
//It is filtered
|
||||
$themes = array_values( $themes );
|
||||
}
|
||||
|
||||
return $themes;
|
||||
}
|
||||
|
||||
/** Hook to wp_loaded, fires when all Installer theme class is ready */
|
||||
public function installer_themes_support_set_up_func() {
|
||||
do_action( 'installer_themes_support_set_up' );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** Instantiate Installer Theme Class */
|
||||
new Installer_Theme_Class;
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
class Installer_Upgrader_Skins extends WP_Upgrader_Skin {
|
||||
|
||||
function __construct( $args = array() ) {
|
||||
$defaults = array( 'url' => '', 'nonce' => '', 'title' => '', 'context' => false );
|
||||
$this->options = wp_parse_args( $args, $defaults );
|
||||
}
|
||||
|
||||
function header() {
|
||||
|
||||
}
|
||||
|
||||
function footer() {
|
||||
|
||||
}
|
||||
|
||||
function error( $error ) {
|
||||
$this->installer_error = $error;
|
||||
}
|
||||
|
||||
function add_strings() {
|
||||
|
||||
}
|
||||
|
||||
function feedback( $string, ...$args ) {
|
||||
|
||||
}
|
||||
|
||||
function before() {
|
||||
|
||||
}
|
||||
|
||||
function after() {
|
||||
|
||||
}
|
||||
|
||||
public function request_filesystem_credentials( $error = false, $context = '', $allow_relaxed_file_ownership = false ) {
|
||||
ob_start();
|
||||
$credentials = parent::request_filesystem_credentials( $error, $context, $allow_relaxed_file_ownership );
|
||||
ob_end_clean();
|
||||
|
||||
if ( ! $credentials ) {
|
||||
$message = __( 'We were not able to copy some plugin files. This is usually due to issues with permissions for WordPress content or plugins folder.', 'installer' );
|
||||
$this->error( new WP_Error( 'files_not_writable', $message, $context ) );
|
||||
}
|
||||
return $credentials;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Installer_Autoloader {
|
||||
|
||||
private $classMap = [];
|
||||
|
||||
public function initialize() {
|
||||
include_once dirname( __FILE__ ) . '/functions-core.php';
|
||||
include_once dirname( __FILE__ ) . '/functions-templates.php';
|
||||
include_once dirname( __FILE__ ) . '/utilities/FP/functions.php';
|
||||
|
||||
spl_autoload_register( [ $this, 'autoload' ] );
|
||||
}
|
||||
|
||||
public function autoload( $class_name ) {
|
||||
if ( array_key_exists( $class_name, $this->getClassMap() ) ) {
|
||||
$file = $this->classMap[ $class_name ];
|
||||
include $file;
|
||||
}
|
||||
}
|
||||
|
||||
private function getClassMap() {
|
||||
if ( ! $this->classMap ) {
|
||||
$this->classMap = require dirname( __FILE__ ) . '/otgs-installer-autoload-classmap.php';
|
||||
}
|
||||
|
||||
return $this->classMap;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Installer_Debug_Info {
|
||||
private $installer;
|
||||
|
||||
/**
|
||||
* @var OTGS_Products_Config_Db_Storage
|
||||
*/
|
||||
private $products_config_storage;
|
||||
|
||||
public function __construct( WP_Installer $installer, OTGS_Products_Config_Db_Storage $products_config_storage ) {
|
||||
$this->installer = $installer;
|
||||
$this->products_config_storage = $products_config_storage;
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
add_filter( 'icl_get_extra_debug_info', array( $this, 'add_installer_config_in_debug_information' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function add_installer_config_in_debug_information( $data ) {
|
||||
global $wp_installer_instances;
|
||||
|
||||
$repositories_data = array();
|
||||
$repositories = $this->installer->get_repositories();
|
||||
$repository_settings = $this->installer->get_settings();
|
||||
$repository_settings = $repository_settings['repositories'];
|
||||
|
||||
foreach ( $repositories as $repo_id => $repository ) {
|
||||
$repositories_data[ $repo_id ] = [
|
||||
'api-url' => $repository['api-url'],
|
||||
'bucket-url' => $this->prepare_bucket_url( $repo_id ),
|
||||
'subscription' => isset( $repository_settings[ $repo_id ]['subscription'] ) ? $repository_settings[ $repo_id ]['subscription'] : '',
|
||||
'last-successful-subscription-fetch' => $this->prepare_last_subscription_fetch( $repository_settings, $repo_id ),
|
||||
];
|
||||
}
|
||||
|
||||
$data['installer'] = array(
|
||||
'version' => $this->installer->version(),
|
||||
'repositories' => $repositories_data,
|
||||
'instances' => $wp_installer_instances,
|
||||
);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
private function prepare_bucket_url( $repo_id ) {
|
||||
$bucket_url = $this->products_config_storage->get_repository_products_url( $repo_id );
|
||||
return $bucket_url ? $bucket_url : 'not assigned';
|
||||
}
|
||||
|
||||
private function prepare_last_subscription_fetch( $repository_settings, $repo_id ) {
|
||||
return isset( $repository_settings[ $repo_id ]['last_successful_subscription_fetch'] ) ?
|
||||
date( 'Y-m-d h:i:s', $repository_settings[ $repo_id ]['last_successful_subscription_fetch'] ) : 'none';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,379 @@
|
||||
<?php
|
||||
|
||||
use OTGS\Installer\AdminNotices\Loader;
|
||||
use OTGS\Installer\AdminNotices\Notices\Account;
|
||||
use OTGS\Installer\AdminNotices\Notices\ApiConnection;
|
||||
use OTGS\Installer\AdminNotices\Notices\SiteKey;
|
||||
use OTGS\Installer\AdminNotices\Notices\Hooks;
|
||||
use OTGS\Installer\AdminNotices\Notices\Recommendation;
|
||||
use OTGS\Installer\Upgrade\AutoUpgrade;
|
||||
use OTGS\Installer\Upgrade\InstallerPlugins;
|
||||
|
||||
class OTGS_Installer_Factory {
|
||||
|
||||
private $installer;
|
||||
private $filename_hooks;
|
||||
private $icons;
|
||||
private $installer_php_functions;
|
||||
private $local_components_ajax_setting;
|
||||
private $settings;
|
||||
|
||||
/**
|
||||
* @var OTGS_Template_Service
|
||||
*/
|
||||
private $template_service;
|
||||
private $wp_components_hooks;
|
||||
private $wp_components_sender;
|
||||
private $wp_components_storage;
|
||||
private $upgrade_response;
|
||||
private $plugin_finder;
|
||||
private $plugin_factory;
|
||||
private $repositories;
|
||||
|
||||
public function __construct( WP_Installer $installer ) {
|
||||
$this->installer = $installer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return OTGS_Installer_Filename_Hooks
|
||||
*/
|
||||
public function create_filename_hooks() {
|
||||
if ( ! $this->filename_hooks ) {
|
||||
$this->filename_hooks = new OTGS_Installer_Filename_Hooks( $this->create_installer_php_functions() );
|
||||
}
|
||||
|
||||
return $this->filename_hooks;
|
||||
}
|
||||
|
||||
public function load_filename_hooks() {
|
||||
$filename_hooks = $this->create_filename_hooks();
|
||||
$filename_hooks->add_hooks();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return OTGS_Installer_Icons
|
||||
*/
|
||||
public function create_icons() {
|
||||
if ( ! $this->icons ) {
|
||||
$this->icons = new OTGS_Installer_Icons( $this->get_installer() );
|
||||
}
|
||||
|
||||
return $this->icons;
|
||||
}
|
||||
|
||||
public function load_icons() {
|
||||
$icons = $this->create_icons();
|
||||
$icons->add_hooks();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return OTGS_Installer_WP_Components_Setting_Ajax
|
||||
*/
|
||||
public function create_local_components_ajax_setting() {
|
||||
if ( ! $this->local_components_ajax_setting ) {
|
||||
$this->local_components_ajax_setting = new OTGS_Installer_WP_Components_Setting_Ajax( $this->create_settings(),
|
||||
$this->get_installer() );
|
||||
}
|
||||
|
||||
return $this->local_components_ajax_setting;
|
||||
}
|
||||
|
||||
public function load_local_components_ajax_settings() {
|
||||
$settings = $this->create_local_components_ajax_setting();
|
||||
$settings->add_hooks();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return OTGS_Installer_WP_Components_Setting_Resources
|
||||
*/
|
||||
public function create_resources() {
|
||||
return new OTGS_Installer_WP_Components_Setting_Resources( $this->get_installer() );
|
||||
}
|
||||
|
||||
public function load_resources() {
|
||||
$resources = $this->create_resources();
|
||||
$resources->add_hooks();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return OTGS_Installer_WP_Share_Local_Components_Setting_Hooks
|
||||
*/
|
||||
public function create_settings_hooks() {
|
||||
return new OTGS_Installer_WP_Share_Local_Components_Setting_Hooks(
|
||||
$this->create_template_service(),
|
||||
$this->create_settings() );
|
||||
}
|
||||
|
||||
public function load_settings_hooks() {
|
||||
$settings_hooks = $this->create_settings_hooks();
|
||||
$settings_hooks->add_hooks();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return OTGS_Template_Service
|
||||
*/
|
||||
private function create_template_service() {
|
||||
if ( ! $this->template_service ) {
|
||||
$this->template_service = OTGS_Template_Service_Factory::create(
|
||||
$this->get_installer()
|
||||
->plugin_path()
|
||||
. '/templates/php/components-setting/'
|
||||
);
|
||||
}
|
||||
|
||||
return $this->template_service;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return OTGS_Installer_WP_Share_Local_Components_Setting
|
||||
*/
|
||||
private function create_settings() {
|
||||
if ( ! $this->settings ) {
|
||||
$this->settings = new OTGS_Installer_WP_Share_Local_Components_Setting();
|
||||
}
|
||||
|
||||
return $this->settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return OTGS_Installer_WP_Components_Hooks
|
||||
*/
|
||||
public function create_wp_components_hooks() {
|
||||
if ( ! $this->wp_components_hooks ) {
|
||||
$this->wp_components_hooks = new OTGS_Installer_WP_Components_Hooks( $this->create_wp_components_storage(),
|
||||
$this->create_wp_components_sender(),
|
||||
$this->create_settings(),
|
||||
$this->create_installer_php_functions() );
|
||||
}
|
||||
|
||||
return $this->wp_components_hooks;
|
||||
}
|
||||
|
||||
public function load_wp_components_hooks() {
|
||||
$wp_components_hooks = $this->create_wp_components_hooks();
|
||||
$wp_components_hooks->add_hooks();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return OTGS_Installer_WP_Components_Storage
|
||||
*/
|
||||
public function create_wp_components_storage() {
|
||||
if ( ! $this->wp_components_storage ) {
|
||||
$this->wp_components_storage = new OTGS_Installer_WP_Components_Storage();
|
||||
}
|
||||
|
||||
return $this->wp_components_storage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return OTGS_Installer_WP_Components_Sender
|
||||
*/
|
||||
public function create_wp_components_sender() {
|
||||
if ( ! $this->wp_components_sender ) {
|
||||
$this->wp_components_sender = new OTGS_Installer_WP_Components_Sender( $this->get_installer(),
|
||||
$this->create_settings() );
|
||||
}
|
||||
|
||||
return $this->wp_components_sender;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return OTGS_Installer_PHP_Functions
|
||||
*/
|
||||
public function create_installer_php_functions() {
|
||||
if ( ! $this->installer_php_functions ) {
|
||||
$this->installer_php_functions = new OTGS_Installer_PHP_Functions();
|
||||
}
|
||||
|
||||
return $this->installer_php_functions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return OTGS_Installer_Debug_Info
|
||||
*/
|
||||
public function create_debug_info_hook() {
|
||||
return new OTGS_Installer_Debug_Info( $this->get_installer(), new OTGS_Products_Config_Db_Storage() );
|
||||
}
|
||||
|
||||
public function load_debug_info_hooks() {
|
||||
$debug_info = $this->create_debug_info_hook();
|
||||
$debug_info->add_hooks();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return OTGS_Installer_Plugin_Factory
|
||||
*/
|
||||
public function get_plugin_factory() {
|
||||
if ( ! $this->plugin_factory ) {
|
||||
$this->plugin_factory = new OTGS_Installer_Plugin_Factory();
|
||||
}
|
||||
|
||||
return $this->plugin_factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return OTGS_Installer_Plugin_Finder
|
||||
*/
|
||||
public function get_plugin_finder() {
|
||||
if ( ! $this->plugin_finder ) {
|
||||
$settings = $this->get_installer()->get_settings();
|
||||
$this->plugin_finder = new OTGS_Installer_Plugin_Finder( $this->get_plugin_factory(), $settings['repositories'] );
|
||||
}
|
||||
|
||||
return $this->plugin_finder;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return OTGS_Installer_Upgrade_Response
|
||||
*/
|
||||
public function create_upgrade_response() {
|
||||
if ( ! $this->upgrade_response ) {
|
||||
$this->upgrade_response = new OTGS_Installer_Upgrade_Response(
|
||||
$this->get_plugin_finder()->get_all(),
|
||||
$this->get_repositories(),
|
||||
new OTGS_Installer_Source_Factory(),
|
||||
new OTGS_Installer_Package_Product_Finder()
|
||||
);
|
||||
}
|
||||
|
||||
return $this->upgrade_response;
|
||||
}
|
||||
|
||||
public function load_upgrade_response() {
|
||||
$upgrade_response = $this->create_upgrade_response();
|
||||
$upgrade_response->add_hooks();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return OTGS_Installer_Site_Key_Ajax
|
||||
*/
|
||||
public function create_site_key_ajax_handler() {
|
||||
$logger = new OTGS_Installer_Logger(
|
||||
$this->installer,
|
||||
new OTGS_Installer_Logger_Storage( new OTGS_Installer_Log_Factory() )
|
||||
);
|
||||
|
||||
$fetch_subscription = new OTGS_Installer_Fetch_Subscription(
|
||||
new OTGS_Installer_Source_Factory(),
|
||||
$this->get_plugin_finder(),
|
||||
$this->get_repositories(),
|
||||
$logger,
|
||||
new OTGS_Installer_Log_Factory()
|
||||
);
|
||||
|
||||
return new OTGS_Installer_Site_Key_Ajax(
|
||||
$fetch_subscription,
|
||||
$logger,
|
||||
$this->get_repositories(),
|
||||
new OTGS_Installer_Subscription_Factory()
|
||||
);
|
||||
}
|
||||
|
||||
public function load_site_key_ajax_handler() {
|
||||
$site_key_ajax_handler = $this->create_site_key_ajax_handler();
|
||||
$site_key_ajax_handler->add_hooks();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function load_installer_support_hooks() {
|
||||
$support_hooks = new OTGS_Installer_Support_Hooks( new OTGS_Installer_Support_Template_Factory( $this->get_installer()->plugin_path() ) );
|
||||
$support_hooks->add_hooks();
|
||||
|
||||
if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
|
||||
$support_ajax = new OTGS_Installer_Connection_Test_Ajax(
|
||||
new OTGS_Installer_Connection_Test(
|
||||
$this->get_repositories(),
|
||||
$this->create_upgrade_response(),
|
||||
new OTGS_Installer_Logger_Storage( new OTGS_Installer_Log_Factory() ),
|
||||
new OTGS_Installer_Log_Factory()
|
||||
)
|
||||
);
|
||||
|
||||
$support_ajax->add_hooks();
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function load_translation_service_info_hooks() {
|
||||
$translation_services = new Translation_Service_Info();
|
||||
$translation_services->add_hooks();
|
||||
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
* @return OTGS_Installer_Repositories
|
||||
*/
|
||||
private function get_repositories() {
|
||||
if ( ! $this->repositories ) {
|
||||
$repositories_factory = new OTGS_Installer_Repositories_Factory( $this->get_installer() );
|
||||
$this->repositories = $repositories_factory->create( $this->installer );
|
||||
}
|
||||
|
||||
return $this->repositories;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function load_plugins_update_cache_cleaner() {
|
||||
$plugins_update_cache_cleaner = new OTGS_Installer_Plugins_Update_Cache_Cleaner();
|
||||
$plugins_update_cache_cleaner->add_hooks();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function load_buy_url_hooks() {
|
||||
$buy_url = new OTGS_Installer_Buy_URL_Hooks( $this->installer->get_embedded_at() );
|
||||
$buy_url->add_hooks();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function load_admin_notice_hooks() {
|
||||
Hooks::addHooks( Account::class, $this->installer );
|
||||
Hooks::addHooks( ApiConnection::class, $this->installer );
|
||||
Recommendation::addHooks();
|
||||
|
||||
Loader::addHooks( defined( 'DOING_AJAX' ) );
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function load_auto_upgrade_hooks() {
|
||||
$pluginFinder = $this->get_plugin_finder();
|
||||
$autoUpgrade = new AutoUpgrade(
|
||||
$this->installer,
|
||||
$pluginFinder,
|
||||
new InstallerPlugins($this->installer, $pluginFinder)
|
||||
);
|
||||
|
||||
$autoUpgrade->addHooks();
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WP_Installer
|
||||
*/
|
||||
private function get_installer() {
|
||||
return $this->installer;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Installer_Filename_Hooks {
|
||||
|
||||
/**
|
||||
* @var OTGS_Installer_PHP_Functions
|
||||
*/
|
||||
private $built_in_functions;
|
||||
|
||||
public function __construct( OTGS_Installer_PHP_Functions $built_in_functions ) {
|
||||
$this->built_in_functions = $built_in_functions;
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
if ( in_array( $this->built_in_functions->constant( 'PHP_OS' ), array( 'WIN32', 'WINNT', 'Windows' ), true ) ) {
|
||||
add_filter( 'wp_unique_filename', array( $this, 'fix_filename_for_win' ), 10, 3 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $filename
|
||||
* @param string $ext
|
||||
* @param string $dir
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function fix_filename_for_win( $filename, $ext, $dir ) {
|
||||
if ( $dir === get_temp_dir() ) {
|
||||
return md5( $filename . $this->built_in_functions->time() ) . 'tmp';
|
||||
}
|
||||
return $filename;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Installer_Icons {
|
||||
|
||||
/**
|
||||
* @var WP_Installer
|
||||
*/
|
||||
private $installer;
|
||||
|
||||
public function __construct( WP_Installer $installer ) {
|
||||
$this->installer = $installer;
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
add_filter( 'otgs_installer_upgrade_check_response', array( $this, 'add_icons_on_response' ), 10, 2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param stdClass $response
|
||||
* @param string $name
|
||||
*
|
||||
* @return stdClass
|
||||
*/
|
||||
public function add_icons_on_response( $response, $name ) {
|
||||
$repositories = array_keys( $this->installer->get_repositories() );
|
||||
$product = '';
|
||||
$repository = '';
|
||||
|
||||
foreach( $repositories as $repository_id ) {
|
||||
if ( isset( $this->installer->settings['repositories'][ $repository_id ]['data']['products-map'][ $response->plugin ] ) ) {
|
||||
$product = $this->installer->settings['repositories'][ $repository_id ]['data']['products-map'][ $response->plugin ];
|
||||
$repository = $repository_id;
|
||||
break;
|
||||
} elseif ( isset( $this->installer->settings['repositories'][ $repository_id ]['data']['products-map'][ $name ] ) ) {
|
||||
$product = $this->installer->settings['repositories'][ $repository_id ]['data']['products-map'][ $name ];
|
||||
$repository = $repository_id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $product && $repository ) {
|
||||
$base = $this->installer->plugin_url() . '/../icons/plugin-icons/' . $repository . '/' . $product . '/icon';
|
||||
$response->icons = array(
|
||||
'svg' => $base . '.svg',
|
||||
'1x' => $base . '-128x128.png',
|
||||
'2x' => $base . '-256x256.png',
|
||||
);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Installer_Loader {
|
||||
|
||||
private $installer_factory;
|
||||
|
||||
public function __construct( OTGS_Installer_Factory $installer_factory ) {
|
||||
$this->installer_factory = $installer_factory;
|
||||
}
|
||||
|
||||
public function init() {
|
||||
$this->installer_factory->load_wp_components_hooks();
|
||||
|
||||
add_action( 'otgs_installer_initialized', array( $this, 'load_actions_after_installer_init' ) );
|
||||
}
|
||||
|
||||
public function load_actions_after_installer_init() {
|
||||
$this->installer_factory
|
||||
->load_resources()
|
||||
->load_settings_hooks()
|
||||
->load_local_components_ajax_settings()
|
||||
->load_filename_hooks()
|
||||
->load_icons()
|
||||
->load_debug_info_hooks()
|
||||
->load_upgrade_response()
|
||||
->load_site_key_ajax_handler()
|
||||
->load_installer_support_hooks()
|
||||
->load_translation_service_info_hooks()
|
||||
->load_plugins_update_cache_cleaner()
|
||||
->load_buy_url_hooks()
|
||||
->load_admin_notice_hooks()
|
||||
->load_auto_upgrade_hooks();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Installer_Package_Product_Finder {
|
||||
|
||||
/**
|
||||
* @param OTGS_Installer_Repository $repository
|
||||
* @param OTGS_Installer_Subscription $subscription
|
||||
*
|
||||
* @return null|OTGS_Installer_Package_Product
|
||||
*/
|
||||
public function get_product_in_repository_by_subscription( OTGS_Installer_Repository $repository, OTGS_Installer_Subscription $subscription = null ) {
|
||||
$product = null;
|
||||
|
||||
if ( ! $subscription ) {
|
||||
$subscription = $repository->get_subscription();
|
||||
}
|
||||
if ( $subscription ) {
|
||||
$type = $subscription->get_type();
|
||||
$product = $repository->get_product_by_subscription_type( $type );
|
||||
|
||||
if ( ! $product ) {
|
||||
$product = $repository->get_product_by_subscription_type_equivalent( $type );
|
||||
|
||||
if ( ! $product ) {
|
||||
$product = $repository->get_product_by_subscription_type_on_upgrades( $type );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $product;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Installer_Package_Product {
|
||||
|
||||
private $id;
|
||||
private $name;
|
||||
private $description;
|
||||
private $price;
|
||||
private $subscription_type;
|
||||
private $subscription_type_text;
|
||||
private $subscription_info;
|
||||
private $subscription_type_equivalent;
|
||||
private $url;
|
||||
private $renewals;
|
||||
private $upgrades;
|
||||
private $plugins;
|
||||
private $downloads;
|
||||
|
||||
public function __construct( array $params = array() ) {
|
||||
foreach ( get_object_vars( $this ) as $property => $value ) {
|
||||
if ( array_key_exists( $property, $params ) ) {
|
||||
$this->$property = $params[ $property ];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function get_id() {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function get_name() {
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function get_description() {
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
public function get_price() {
|
||||
return $this->price;
|
||||
}
|
||||
|
||||
public function get_subscription_type() {
|
||||
return $this->subscription_type;
|
||||
}
|
||||
|
||||
public function get_subscription_type_text() {
|
||||
return $this->subscription_type_text;
|
||||
}
|
||||
|
||||
public function get_subscription_info() {
|
||||
return $this->subscription_info;
|
||||
}
|
||||
|
||||
public function get_subscription_type_equivalent() {
|
||||
return (int) $this->subscription_type_equivalent;
|
||||
}
|
||||
|
||||
public function get_url() {
|
||||
return $this->url;
|
||||
}
|
||||
|
||||
public function get_renewals() {
|
||||
return $this->renewals;
|
||||
}
|
||||
|
||||
public function get_upgrades() {
|
||||
return $this->upgrades;
|
||||
}
|
||||
|
||||
public function get_plugins() {
|
||||
return $this->plugins;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $slug
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_plugin_registered( $slug ) {
|
||||
foreach ( $this->plugins as $plugin ) {
|
||||
if ( $slug === $plugin ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function get_downloads() {
|
||||
return $this->downloads;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Installer_Package {
|
||||
|
||||
private $key;
|
||||
private $id;
|
||||
private $name;
|
||||
private $description;
|
||||
private $image_url;
|
||||
private $order;
|
||||
private $parent;
|
||||
private $products = array();
|
||||
|
||||
public function __construct( array $params = array() ) {
|
||||
foreach ( get_object_vars( $this ) as $property => $value ) {
|
||||
if ( array_key_exists( $property, $params ) ) {
|
||||
$this->$property = $params[ $property ];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function get_key() {
|
||||
return $this->key;
|
||||
}
|
||||
|
||||
public function get_products() {
|
||||
return $this->products;
|
||||
}
|
||||
|
||||
public function get_product_by_subscription_type( $type ) {
|
||||
return $this->get_product_by( 'get_subscription_type', $type );
|
||||
}
|
||||
|
||||
public function get_product_by_subscription_type_equivalent( $type ) {
|
||||
return $this->get_product_by( 'get_subscription_type_equivalent', $type );
|
||||
}
|
||||
|
||||
public function get_product_by( $function, $type ) {
|
||||
foreach ( $this->products as $product ) {
|
||||
if ( $type === $product->$function() ) {
|
||||
return $product;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function get_product_by_subscription_type_on_upgrades( $type ) {
|
||||
foreach ( $this->products as $product ) {
|
||||
foreach ( $product->get_upgrades() as $upgrade ) {
|
||||
if ( $type === $upgrade['subscription_type'] ) {
|
||||
return $product;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function get_id() {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function get_name() {
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function get_description() {
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
public function get_image_url() {
|
||||
return $this->image_url;
|
||||
}
|
||||
|
||||
public function get_order() {
|
||||
return $this->order;
|
||||
}
|
||||
|
||||
public function get_parent() {
|
||||
return $this->parent;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Installer_PHP_Functions {
|
||||
|
||||
/**
|
||||
* @param string $constant_name
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function defined( $constant_name ) {
|
||||
return defined( $constant_name );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $constant_name
|
||||
*
|
||||
* @return string|int|null
|
||||
*/
|
||||
public function constant( $constant_name ) {
|
||||
return $this->defined( $constant_name ) ? constant( $constant_name ) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function time() {
|
||||
return time();
|
||||
}
|
||||
|
||||
public function phpversion() {
|
||||
return phpversion();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Installer_Plugin_Factory {
|
||||
|
||||
/**
|
||||
* @param array $params
|
||||
*
|
||||
* @return OTGS_Installer_Plugin
|
||||
*/
|
||||
public function create( array $params = array() ) {
|
||||
return new OTGS_Installer_Plugin( $params );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Installer_Plugin_Finder {
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $plugins = array();
|
||||
private $plugin_factory;
|
||||
private $repositories;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $installed_plugins;
|
||||
|
||||
public function __construct( OTGS_Installer_Plugin_Factory $plugin_factory, array $repositories ) {
|
||||
$this->plugin_factory = $plugin_factory;
|
||||
$this->repositories = $repositories;
|
||||
$this->load();
|
||||
}
|
||||
|
||||
private function load() {
|
||||
if ( ! $this->plugins ) {
|
||||
foreach ( $this->repositories as $repo_key => $repository ) {
|
||||
foreach ( $repository['data']['downloads']['plugins'] as $slug => $plugin ) {
|
||||
$plugin_id = $this->get_installed_plugin_id_by_slug( $plugin['slug'] );
|
||||
|
||||
if ( ! $plugin_id ) {
|
||||
$plugin_id = $this->get_installed_plugin_id_by_name( $plugin['name'] );
|
||||
}
|
||||
|
||||
$this->plugins[] = $this->plugin_factory->create( array(
|
||||
'name' => $plugin['name'],
|
||||
'slug' => $plugin['slug'],
|
||||
'description' => $plugin['description'],
|
||||
'changelog' => $plugin['changelog'],
|
||||
'version' => $plugin['version'],
|
||||
'installed_version' => isset( $this->installed_plugins[ $plugin_id ]['Version'] ) ? $this->installed_plugins[ $plugin_id ]['Version'] : null ,
|
||||
'date' => $plugin['date'],
|
||||
'url' => $plugin['url'],
|
||||
'free_on_wporg' => isset( $plugin['free-on-wporg'] ) ? $plugin['free-on-wporg'] : '',
|
||||
'fallback_on_wporg' => isset( $plugin['fallback-free-on-wporg'] ) ? $plugin['fallback-free-on-wporg'] : '',
|
||||
'basename' => $plugin['basename'],
|
||||
'external_repo' => isset( $plugin['external-repo'] ) ? $plugin['external-repo'] : '',
|
||||
'is_lite' => isset( $plugin['is-lite'] ) ? $plugin['is-lite'] : '',
|
||||
'repo' => $repo_key,
|
||||
'id' => $plugin_id,
|
||||
'channel' => $plugin['channel'],
|
||||
'tested' => isset( $plugin['tested'] ) ? $plugin['tested'] : null,
|
||||
) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return OTGS_Installer_Plugin[]
|
||||
*/
|
||||
public function get_all() {
|
||||
return $this->plugins;
|
||||
}
|
||||
|
||||
public function get_otgs_installed_plugins() {
|
||||
$installed_plugins = array();
|
||||
|
||||
foreach ( $this->plugins as $plugin ) {
|
||||
if ( $plugin->get_installed_version() ) {
|
||||
$installed_plugins[] = $plugin;
|
||||
}
|
||||
}
|
||||
|
||||
return $installed_plugins;
|
||||
}
|
||||
|
||||
public function get_otgs_installed_plugins_by_repository() {
|
||||
$installed_plugins = [];
|
||||
|
||||
/** @var OTGS_Installer_Plugin $plugin */
|
||||
foreach ( $this->plugins as $plugin ) {
|
||||
if ( $plugin->get_installed_version() ) {
|
||||
$installed_plugins[ $plugin->get_repo() ][] = [
|
||||
'id' => $plugin->get_id(),
|
||||
'slug' => $plugin->get_slug(),
|
||||
'name' => $plugin->get_name(),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $installed_plugins;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $slug
|
||||
* @param string $repo
|
||||
*
|
||||
* @return null|OTGS_Installer_Plugin
|
||||
*/
|
||||
public function get_plugin( $slug, $repo = '' ) {
|
||||
foreach ( $this->plugins as $plugin ) {
|
||||
if ( $slug === $plugin->get_slug() ) {
|
||||
|
||||
if ( ! $repo || $plugin->get_repo() === $repo ) {
|
||||
return $plugin;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return null|OTGS_Installer_Plugin
|
||||
*/
|
||||
public function get_plugin_by_name( $name ) {
|
||||
foreach ( $this->plugins as $plugin ) {
|
||||
if ( $name === strip_tags( $plugin->get_name() ) ) {
|
||||
return $plugin;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $slug
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
private function get_installed_plugin_id_by_slug( $slug ) {
|
||||
foreach ( $this->get_installed_plugins() as $plugin_id => $plugin ) {
|
||||
$plugin_slug = explode( '/', $plugin_id );
|
||||
|
||||
if ( $slug === $plugin_slug[0] ) {
|
||||
return $plugin_id;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private function get_installed_plugins() {
|
||||
if ( ! $this->installed_plugins ) {
|
||||
$this->installed_plugins = get_plugins();
|
||||
}
|
||||
|
||||
return $this->installed_plugins;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
private function get_installed_plugin_id_by_name( $name ) {
|
||||
$plugin_id = array_keys( wp_list_filter( $this->get_installed_plugins(), array( 'Name' => $name ) ) );
|
||||
|
||||
return current( $plugin_id );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Installer_Plugin {
|
||||
|
||||
private $name;
|
||||
private $slug;
|
||||
private $description;
|
||||
private $changelog;
|
||||
private $version;
|
||||
private $date;
|
||||
private $url;
|
||||
private $free_on_wporg;
|
||||
private $fallback_on_wporg;
|
||||
private $basename;
|
||||
private $external_repo;
|
||||
private $is_lite;
|
||||
private $repo;
|
||||
private $id;
|
||||
private $installed_version;
|
||||
private $channel;
|
||||
private $tested;
|
||||
|
||||
public function __construct( array $params = array() ) {
|
||||
foreach ( get_object_vars( $this ) as $property => $value ) {
|
||||
if ( array_key_exists( $property, $params ) ) {
|
||||
$this->$property = $params[ $property ];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_name() {
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_slug() {
|
||||
return $this->slug;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_description() {
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_changelog() {
|
||||
return $this->changelog;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_version() {
|
||||
return $this->version;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_date() {
|
||||
return $this->date;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_url() {
|
||||
return $this->url;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_repo() {
|
||||
return $this->repo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function is_free_on_wporg() {
|
||||
return (bool) $this->free_on_wporg;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function has_fallback_on_wporg() {
|
||||
return (bool) $this->fallback_on_wporg;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_basename() {
|
||||
return $this->basename;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_external_repo() {
|
||||
return $this->external_repo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_id() {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_installed_version() {
|
||||
return $this->installed_version;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_channel() {
|
||||
return $this->channel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_tested() {
|
||||
return $this->tested;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function is_lite() {
|
||||
return $this->is_lite;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Installer_Plugins_Page_Notice {
|
||||
|
||||
const TEMPLATE = 'plugins-page';
|
||||
const DISPLAY_SUBSCRIPTION_NOTICE_KEY = 'display_subscription_notice';
|
||||
const DISPLAY_SETTING_NOTICE_KEY = 'display_setting_notice';
|
||||
|
||||
private $plugins = array();
|
||||
|
||||
/**
|
||||
* @var OTGS_Template_Service
|
||||
*/
|
||||
private $template_service;
|
||||
|
||||
private $plugin_finder;
|
||||
|
||||
public function __construct( OTGS_Template_Service $template_service, OTGS_Installer_Plugin_Finder $plugin_finder ) {
|
||||
$this->template_service = $template_service;
|
||||
$this->plugin_finder = $plugin_finder;
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
foreach ( $this->get_plugins() as $plugin_id => $plugin_data ) {
|
||||
add_action( 'after_plugin_row_' . $plugin_id, array(
|
||||
$this,
|
||||
'show_purchase_notice_under_plugin'
|
||||
), 10, 2 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function get_plugins() {
|
||||
return $this->plugins;
|
||||
}
|
||||
|
||||
public function add_plugin( $plugin_id, $plugin_data ) {
|
||||
$this->plugins[ $plugin_id ] = $plugin_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $plugin_file
|
||||
*/
|
||||
public function show_purchase_notice_under_plugin( $plugin_file, $plugin_data ) {
|
||||
$display_subscription_notice = isset( $this->plugins[ $plugin_file ][ self::DISPLAY_SUBSCRIPTION_NOTICE_KEY ] )
|
||||
? $this->plugins[ $plugin_file ][ self::DISPLAY_SUBSCRIPTION_NOTICE_KEY ]
|
||||
: false;
|
||||
|
||||
$plugin = $this->plugin_finder->get_plugin_by_name( $plugin_data['Name'] );
|
||||
|
||||
if ( $display_subscription_notice ) {
|
||||
if ( $plugin && 'toolset' === $plugin->get_external_repo() && $plugin->is_lite() ) {
|
||||
echo $this->template_service->show(
|
||||
$this->get_toolset_lite_notice_model( $plugin->get_name() ),
|
||||
self::TEMPLATE
|
||||
);
|
||||
} else {
|
||||
echo $this->template_service->show(
|
||||
$this->get_model( $display_subscription_notice ),
|
||||
self::TEMPLATE
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function get_model( $notice ) {
|
||||
$wp_list_table = _get_list_table( 'WP_Plugins_List_Table' );
|
||||
|
||||
list( $tr_classes, $notice_classes ) = $this->get_classes();
|
||||
|
||||
if ( is_multisite() ) {
|
||||
if ( is_network_admin() ) {
|
||||
$menu_url = network_admin_url( 'plugin-install.php?tab=commercial' );
|
||||
} else {
|
||||
$menu_url = admin_url( 'options-general.php?page=installer' );
|
||||
}
|
||||
} else {
|
||||
$menu_url = admin_url( 'plugin-install.php?tab=commercial' );
|
||||
}
|
||||
|
||||
$menu_url .= '&repository=' . $notice['repo'];
|
||||
$menu_url_with_action = $menu_url . '&action=' . $notice['type'];
|
||||
|
||||
switch ( $notice['type'] ) {
|
||||
case 'expired':
|
||||
$message = $this->prepareMessage(
|
||||
__( 'You are using an expired account of %s. %sExtend your subscription%s', 'installer' ),
|
||||
$notice['product'],
|
||||
$menu_url_with_action
|
||||
);
|
||||
break;
|
||||
|
||||
case 'refunded':
|
||||
$message = $this->prepareMessage(
|
||||
__( 'Remember to remove %s from this website. %sCheck my order status%s', 'installer' ),
|
||||
$notice['product'],
|
||||
$menu_url_with_action
|
||||
);
|
||||
|
||||
$notice_classes .= ' notice-otgs-refund';
|
||||
break;
|
||||
|
||||
case 'legacy_free':
|
||||
$message = sprintf(
|
||||
__( 'You have an old Types-free subscription, which doesn\'t provide automatic updates. %sUpgrade your account%s', 'installer' ),
|
||||
'<a href="' . $menu_url . '">',
|
||||
'</a>'
|
||||
);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
$message = $this->prepareMessage(
|
||||
__( 'You are using an unregistered version of %s and are not receiving compatibility and security updates. %sRegister now%s', 'installer' ),
|
||||
$notice['product'],
|
||||
$menu_url_with_action
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
return array(
|
||||
'strings' => array(
|
||||
'valid_subscription' => $this->prepareMessage($message, $notice['product'], $menu_url_with_action),
|
||||
),
|
||||
'css' => array(
|
||||
'tr_classes' => $tr_classes,
|
||||
'notice_classes' => $notice_classes,
|
||||
),
|
||||
'col_count' => $wp_list_table->get_column_count(),
|
||||
);
|
||||
}
|
||||
|
||||
private function get_toolset_lite_notice_model( $plugin_name ) {
|
||||
$wp_list_table = _get_list_table( 'WP_Plugins_List_Table' );
|
||||
|
||||
list( $tr_classes, $notice_classes ) = $this->get_classes();
|
||||
|
||||
return array(
|
||||
'strings' => array(
|
||||
'valid_subscription' => sprintf( __( 'You are using the complementary %1$s. For the %2$s, %3$s.', 'installer' ),
|
||||
$plugin_name, '<a href="https://wpml.org/documentation/developing-custom-multilingual-sites/types-and-views-lite/?utm_source=viewsplugin&utm_campaign=wpml-toolset-lite&utm_medium=plugins-page&utm_term=features-link">' . __( 'complete set of features', 'installer' ) . '</a>', '<a href="https://toolset.com/?add-to-cart=631305&buy_now=1&apply_coupon=eyJjb3Vwb25fbmFtZSI6IndwbWwgY291cG9uIGJhc2ljIiwiY291cG9uX2lkIjoiODAyMDE2In0=">' . __( 'upgrade to Toolset', 'installer' ) . '</a>' ),
|
||||
),
|
||||
'css' => array(
|
||||
'tr_classes' => $tr_classes,
|
||||
'notice_classes' => $notice_classes,
|
||||
),
|
||||
'col_count' => $wp_list_table->get_column_count(),
|
||||
);
|
||||
}
|
||||
|
||||
private function get_classes() {
|
||||
$tr_classes = 'plugin-update-tr';
|
||||
$notice_classes = 'update-message installer-q-icon';
|
||||
|
||||
if ( version_compare( get_bloginfo( 'version' ), '4.6', '>=' ) ) {
|
||||
$tr_classes = 'plugin-update-tr installer-plugin-update-tr js-otgs-plugin-tr';
|
||||
$notice_classes = 'update-message notice inline notice-otgs';
|
||||
}
|
||||
|
||||
return array( $tr_classes, $notice_classes );
|
||||
}
|
||||
|
||||
private function prepareMessage($message, $notice, $menu_url) {
|
||||
return sprintf($message, $notice, '<a href="' . $menu_url . '">', '</a>');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Installer_Plugins_Update_Cache_Cleaner {
|
||||
|
||||
public function add_hooks() {
|
||||
add_action( 'otgs_installer_clean_plugins_update_cache', array( $this, 'clean_plugins_update_cache' ) );
|
||||
}
|
||||
|
||||
public function clean_plugins_update_cache() {
|
||||
delete_site_transient( 'update_plugins' );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace OTGS\Installer;
|
||||
|
||||
class Settings {
|
||||
|
||||
public static function load() {
|
||||
$settings = get_option( 'wp_installer_settings' );
|
||||
|
||||
if ( is_array( $settings ) || empty( $settings ) ) { //backward compatibility 1.1
|
||||
return $settings;
|
||||
} else {
|
||||
$settings = base64_decode( $settings );
|
||||
if ( self::is_gz_on() ) {
|
||||
$settings = gzuncompress( $settings );
|
||||
}
|
||||
return unserialize( $settings );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static function save( $settings ) {
|
||||
$settings = serialize( $settings );
|
||||
if ( self::is_gz_on() ) {
|
||||
$settings = gzcompress( $settings );
|
||||
}
|
||||
$settings = base64_encode( $settings );
|
||||
|
||||
update_option( 'wp_installer_settings', $settings, 'no' );
|
||||
}
|
||||
|
||||
public static function is_gz_on() {
|
||||
return function_exists( 'gzuncompress' ) && function_exists( 'gzcompress' );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Installer_Source_Factory {
|
||||
|
||||
public function create() {
|
||||
WP_Filesystem();
|
||||
|
||||
global $wp_filesystem;
|
||||
|
||||
return new OTGS_Installer_Source( WP_Installer(), $wp_filesystem );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Installer_Source {
|
||||
|
||||
private $installer;
|
||||
private $file_system;
|
||||
|
||||
public function __construct( WP_Installer $installer, WP_Filesystem_Base $file_system ) {
|
||||
$this->installer = $installer;
|
||||
$this->file_system = $file_system;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|null
|
||||
*/
|
||||
public function get() {
|
||||
return file_exists( $this->installer->plugin_path() ) ? json_decode( $this->file_system->get_contents( $this->installer->plugin_path() ) ) : null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Installer_Subscription_Factory {
|
||||
|
||||
public function create( $params = array() ) {
|
||||
return new OTGS_Installer_Subscription( $params );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
namespace OTGS\Installer;
|
||||
|
||||
use OTGS\Installer\FP\Obj;
|
||||
use OTGS\Installer\FP\Str;
|
||||
use OTGS_Installer_Subscription;
|
||||
|
||||
use function OTGS\Installer\FP\pipe;
|
||||
|
||||
class Subscription_Warning_Message {
|
||||
|
||||
private $wpInstaller;
|
||||
private $settings;
|
||||
private $menuURL;
|
||||
|
||||
public function __construct( \WP_Installer $wpInstaller ) {
|
||||
$this->wpInstaller = $wpInstaller;
|
||||
$this->settings = $wpInstaller->settings;
|
||||
$this->menuURL = $wpInstaller::menu_url();
|
||||
}
|
||||
|
||||
public function get( $repositoryId, $subscriptionId ) {
|
||||
$subscription = Obj::path( [ 'repositories', $repositoryId, 'subscription' ], $this->settings );
|
||||
$subscriptionData = Obj::prop( 'data', $subscription );
|
||||
$repositoryData = Obj::path( [ 'repositories', $repositoryId, 'data' ], $this->settings );
|
||||
$repositoryURL = Obj::prop( 'url', $repositoryData ) . '/account/?utm_source=plugin&utm_medium=gui&utm_campaign=wpmlinstaller';
|
||||
|
||||
$subscriptionId = $subscriptionId ?: Obj::propOr( 'subscription_type', $subscriptionData );
|
||||
$expires = Obj::prop( 'expires', $subscriptionData );
|
||||
$doesntHaveAutoRenewal = isset( $subscriptionData ) && Obj::has( 'hasAutoRenewal', $subscriptionData ) && Obj::prop( 'hasAutoRenewal', $subscriptionData ) === false;
|
||||
|
||||
$neverExpires = isset( $subscription ) && isset( $subscriptionData ) && ! isset( $expires )
|
||||
&& (
|
||||
(int) $subscriptionData->status === OTGS_Installer_Subscription::SUBSCRIPTION_STATUS_ACTIVE_NO_EXPIRATION ||
|
||||
(int) $subscriptionData->status === OTGS_Installer_Subscription::SUBSCRIPTION_STATUS_ACTIVE
|
||||
);
|
||||
if ( $this->wpInstaller->repository_has_valid_subscription( $repositoryId ) && ! $neverExpires ) {
|
||||
$subscriptionExpirationPath = [ 'subscriptions_meta', 'expiration', $subscriptionId ];
|
||||
|
||||
// Returns true if warning property length > 0 and false otherwise
|
||||
$warningPropertyLength = function ( $propertyName ) use ( $repositoryData, $subscriptionExpirationPath ) {
|
||||
if ( Obj::hasPath( $subscriptionExpirationPath, $repositoryData ) ) {
|
||||
$warningPropertyPath = array_merge( $subscriptionExpirationPath, [ $propertyName ] );
|
||||
|
||||
$warningPropertyPathLength = pipe( Obj::path( $warningPropertyPath ), Str::len() );
|
||||
|
||||
return $warningPropertyPathLength( $repositoryData ) > 0;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
$warningDaysSet = $warningPropertyLength( 'days_warning' );
|
||||
$warningMessageSet = $warningPropertyLength( 'warning_message' );
|
||||
|
||||
if ( $warningDaysSet && $warningMessageSet ) {
|
||||
$daysWarning = Obj::path( array_merge( $subscriptionExpirationPath, [ 'days_warning' ] ), $repositoryData );
|
||||
$customMessage = Obj::path( array_merge( $subscriptionExpirationPath, [ 'warning_message' ] ), $repositoryData );
|
||||
} else {
|
||||
// defaults
|
||||
$daysWarning = 30;
|
||||
|
||||
$customMessage = "<a style='margin-left:0px;' href='{$repositoryURL}' target='_blank'>" . __( 'Renew now or signup for automatic renewals', 'installer' ) . '</a>' . ' ' . __( 'to continue receiving support and updates and never risk losing your renewal discount.', 'installer' ) . '<br>';
|
||||
}
|
||||
|
||||
if ( strtotime( $expires ) < strtotime( sprintf( '+%d day', $daysWarning ) ) ) {
|
||||
if ( $doesntHaveAutoRenewal || ! Obj::has( 'hasAutoRenewal', $subscriptionData ) ) {
|
||||
$daysToExpiration = ceil( ( strtotime( $expires ) - time() ) / 86400 );
|
||||
|
||||
$message = sprintf( _n( 'Your subscription expires in %d day.', 'Your subscription expires in %d days.', $daysToExpiration, 'installer' ), $daysToExpiration );
|
||||
|
||||
return $message . ' ' . $customMessage;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Installer_Subscription {
|
||||
|
||||
const SUBSCRIPTION_STATUS_INACTIVE = 0;
|
||||
const SUBSCRIPTION_STATUS_ACTIVE = 1;
|
||||
const SUBSCRIPTION_STATUS_EXPIRED = 2;
|
||||
const SUBSCRIPTION_STATUS_INACTIVE_UPGRADED = 3;
|
||||
const SUBSCRIPTION_STATUS_ACTIVE_NO_EXPIRATION = 4;
|
||||
|
||||
const SITE_KEY_TYPE_PRODUCTION = 0;
|
||||
const SITE_KEY_TYPE_DEVELOPMENT = 1;
|
||||
|
||||
const SUBSCRIPTION_STATUS_TEXT_EXPIRED = 'expired';
|
||||
const SUBSCRIPTION_STATUS_TEXT_VALID = 'valid';
|
||||
const SUBSCRIPTION_STATUS_TEXT_REFUNDED = 'refunded';
|
||||
const SUBSCRIPTION_STATUS_TEXT_MISSING = 'missing';
|
||||
|
||||
private $status;
|
||||
private $expires;
|
||||
private $site_key;
|
||||
private $site_key_type;
|
||||
private $site_url;
|
||||
private $type;
|
||||
private $registered_by;
|
||||
private $data;
|
||||
private $notes;
|
||||
|
||||
/**
|
||||
* WPML_Installer_Subscription constructor.
|
||||
*
|
||||
* @param array|null $subscription
|
||||
*/
|
||||
public function __construct( $subscription = array() ) {
|
||||
if ( $subscription ) {
|
||||
|
||||
if ( isset( $subscription['data'] ) ) {
|
||||
$this->data = $subscription['data'];
|
||||
}
|
||||
|
||||
if ( isset( $subscription['data']->status ) ) {
|
||||
$this->status = (int) $subscription['data']->status;
|
||||
}
|
||||
|
||||
if ( isset( $subscription['data']->expires ) ) {
|
||||
$this->expires = $subscription['data']->expires;
|
||||
}
|
||||
|
||||
if ( isset( $subscription['data']->notes ) ) {
|
||||
$this->notes = $subscription['data']->notes;
|
||||
}
|
||||
|
||||
if ( isset( $subscription['key'] ) ) {
|
||||
$this->site_key = $subscription['key'];
|
||||
}
|
||||
|
||||
if ( isset( $subscription['site_url'] ) ) {
|
||||
$this->site_url = $subscription['site_url'];
|
||||
}
|
||||
|
||||
if ( isset( $subscription['registered_by'] ) ) {
|
||||
$this->registered_by = $subscription['registered_by'];
|
||||
}
|
||||
|
||||
if ( isset( $subscription['data']->subscription_type ) ) {
|
||||
$this->type = $subscription['data']->subscription_type;
|
||||
}
|
||||
|
||||
$this->site_key_type = isset($subscription['key_type'])
|
||||
? $subscription['key_type'] : self::SITE_KEY_TYPE_PRODUCTION;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_subscription_status_text() {
|
||||
if ( $this->is_expired() ) {
|
||||
return self::SUBSCRIPTION_STATUS_TEXT_EXPIRED;
|
||||
}
|
||||
|
||||
if ( $this->is_valid() ) {
|
||||
return self::SUBSCRIPTION_STATUS_TEXT_VALID;
|
||||
}
|
||||
|
||||
if ( $this->is_refunded() ) {
|
||||
return self::SUBSCRIPTION_STATUS_TEXT_REFUNDED;
|
||||
}
|
||||
|
||||
return self::SUBSCRIPTION_STATUS_TEXT_MISSING;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $expiredForPeriod
|
||||
* @return bool
|
||||
*/
|
||||
private function is_expired( $expiredForPeriod = 0 ) {
|
||||
return ! $this->is_lifetime()
|
||||
&& (
|
||||
self::SUBSCRIPTION_STATUS_EXPIRED === $this->get_status()
|
||||
|| ( $this->get_expiration() && strtotime( $this->get_expiration() ) <= time() - $expiredForPeriod )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function is_lifetime() {
|
||||
return $this->get_status() === self::SUBSCRIPTION_STATUS_ACTIVE_NO_EXPIRATION;
|
||||
}
|
||||
|
||||
private function get_status() {
|
||||
return $this->status;
|
||||
}
|
||||
|
||||
private function get_expiration() {
|
||||
return $this->expires;
|
||||
}
|
||||
|
||||
public function get_site_key() {
|
||||
return $this->site_key;
|
||||
}
|
||||
|
||||
public function get_site_url() {
|
||||
return $this->site_url;
|
||||
}
|
||||
|
||||
public function get_type() {
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
public function get_site_key_type() {
|
||||
return $this->site_key_type;
|
||||
}
|
||||
|
||||
public function get_registered_by() {
|
||||
return $this->registered_by;
|
||||
}
|
||||
|
||||
public function get_data() {
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $expiredForPeriod
|
||||
* @return bool
|
||||
*/
|
||||
public function is_valid( $expiredForPeriod = 0 ) {
|
||||
return ( $this->is_lifetime()
|
||||
|| ( $this->get_status() === self::SUBSCRIPTION_STATUS_ACTIVE && ! $this->is_expired( $expiredForPeriod ) ) );
|
||||
}
|
||||
|
||||
public function is_refunded() {
|
||||
return ! $this->is_lifetime() &&
|
||||
$this->get_status() === self::SUBSCRIPTION_STATUS_INACTIVE &&
|
||||
$this->notes === 'Payment refunded to user';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Installer_WP_Components_Hooks {
|
||||
|
||||
const EVENT_SEND_COMPONENTS_MONTHLY = 'otgs_send_components_data';
|
||||
const EVENT_SEND_COMPONENTS_AFTER_REGISTRATION = 'otgs_send_components_data_on_product_registration';
|
||||
const REPORT_SCHEDULING_PERIOD = '+1 month';
|
||||
|
||||
/**
|
||||
* @var OTGS_Installer_WP_Components_Storage
|
||||
*/
|
||||
private $storage;
|
||||
|
||||
/**
|
||||
* @var OTGS_Installer_WP_Components_Sender
|
||||
*/
|
||||
private $sender;
|
||||
|
||||
/**
|
||||
* @var OTGS_Installer_WP_Share_Local_Components_Setting
|
||||
*/
|
||||
private $setting;
|
||||
|
||||
/**
|
||||
* @var OTGS_Installer_PHP_Functions
|
||||
*/
|
||||
private $php_functions;
|
||||
|
||||
public function __construct(
|
||||
OTGS_Installer_WP_Components_Storage $storage,
|
||||
OTGS_Installer_WP_Components_Sender $sender,
|
||||
OTGS_Installer_WP_Share_Local_Components_Setting $setting,
|
||||
OTGS_Installer_PHP_Functions $php_functions
|
||||
) {
|
||||
$this->storage = $storage;
|
||||
$this->sender = $sender;
|
||||
$this->setting = $setting;
|
||||
$this->php_functions = $php_functions;
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
add_action( 'wp_ajax_end_user_get_info', array( $this, 'process_report_instantly' ) );
|
||||
add_action( 'wp_ajax_' . OTGS_Installer_WP_Components_Setting_Ajax::AJAX_ACTION, array( $this, 'force_send_components_data' ), OTGS_Installer_WP_Components_Setting_Ajax::SAVE_SETTING_PRIORITY + 1 );
|
||||
add_action( self::EVENT_SEND_COMPONENTS_MONTHLY, array( $this, 'send_components_data' ) );
|
||||
add_action( self::EVENT_SEND_COMPONENTS_AFTER_REGISTRATION, array( $this, 'send_components_data' ) );
|
||||
add_action( 'init', array( $this, 'schedule_components_report' ) );
|
||||
add_action( 'wp_ajax_save_site_key', array( $this, 'schedule_components_report_when_product_is_registered' ) );
|
||||
}
|
||||
|
||||
public function schedule_components_report() {
|
||||
if ( ! wp_next_scheduled( self::EVENT_SEND_COMPONENTS_MONTHLY ) ) {
|
||||
wp_schedule_single_event( strtotime( self::REPORT_SCHEDULING_PERIOD ), self::EVENT_SEND_COMPONENTS_MONTHLY );
|
||||
}
|
||||
}
|
||||
|
||||
public function schedule_components_report_when_product_is_registered() {
|
||||
if ( ! wp_next_scheduled( self::EVENT_SEND_COMPONENTS_AFTER_REGISTRATION ) ) {
|
||||
wp_schedule_single_event( time() + 60, self::EVENT_SEND_COMPONENTS_AFTER_REGISTRATION );
|
||||
}
|
||||
}
|
||||
|
||||
public function process_report_instantly() {
|
||||
$this->storage->refresh_cache();
|
||||
$this->sender->send( $this->storage->get(), true );
|
||||
}
|
||||
|
||||
public function force_send_components_data() {
|
||||
$this->storage->refresh_cache();
|
||||
$this->sender->send( $this->storage->get() );
|
||||
}
|
||||
|
||||
public function send_components_data() {
|
||||
if ( $this->storage->is_outdated() ) {
|
||||
$this->storage->refresh_cache();
|
||||
$this->sender->send( $this->storage->get() );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Installer_WP_Components_Sender {
|
||||
|
||||
/**
|
||||
* @var WP_Installer
|
||||
*/
|
||||
private $installer;
|
||||
|
||||
/**
|
||||
* @var OTGS_Installer_WP_Share_Local_Components_Setting
|
||||
*/
|
||||
private $settings;
|
||||
|
||||
public function __construct( WP_Installer $installer, OTGS_Installer_WP_Share_Local_Components_Setting $settings ) {
|
||||
$this->installer = $installer;
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
public function send( array $components, $force = false ) {
|
||||
|
||||
if ( ! $this->installer->get_repositories() ) {
|
||||
$this->installer->load_repositories_list();
|
||||
}
|
||||
|
||||
if ( ! $this->installer->get_settings() ) {
|
||||
$this->installer->save_settings();
|
||||
}
|
||||
|
||||
foreach ( $this->installer->get_repositories() as $key => $repository ) {
|
||||
$site_key = $this->installer->get_site_key( $key );
|
||||
if ( $site_key && $this->settings->is_repo_allowed( $key ) ) {
|
||||
wp_remote_post(
|
||||
$repository['api-url'] . '?action=update_site_components',
|
||||
apply_filters( 'installer_fetch_components_data_request', array(
|
||||
'body' => array(
|
||||
'action' => 'update_site_components',
|
||||
'site_key' => $site_key,
|
||||
'site_url' => get_site_url(),
|
||||
'components' => $components,
|
||||
'phpversion' => phpversion(),
|
||||
'wp_version' => get_bloginfo( 'version' ),
|
||||
'force' => $force,
|
||||
),
|
||||
) )
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Installer_WP_Components_Setting_Ajax {
|
||||
|
||||
const AJAX_ACTION = 'otgs_save_setting_share_local_components';
|
||||
const SAVE_SETTING_PRIORITY = 1;
|
||||
|
||||
/**
|
||||
* @var OTGS_Installer_WP_Share_Local_Components_Setting
|
||||
*/
|
||||
private $setting;
|
||||
|
||||
/**
|
||||
* @var WP_Installer
|
||||
*/
|
||||
private $installer;
|
||||
|
||||
public function __construct( OTGS_Installer_WP_Share_Local_Components_Setting $setting, WP_Installer $installer ) {
|
||||
$this->setting = $setting;
|
||||
$this->installer = $installer;
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
add_action( 'wp_ajax_' . self::AJAX_ACTION, array( $this, 'save' ), self::SAVE_SETTING_PRIORITY );
|
||||
}
|
||||
|
||||
public function save() {
|
||||
if ( $this->is_valid_request() ) {
|
||||
$user_agree = (int) filter_var( $_POST['agree'], FILTER_SANITIZE_FULL_SPECIAL_CHARS );
|
||||
$repo_request = filter_var( $_POST['repo'], FILTER_SANITIZE_FULL_SPECIAL_CHARS );
|
||||
if ( $repo_request ) {
|
||||
$repos = array();
|
||||
foreach ( $this->installer->get_repositories() as $repo_id => $repository ) {
|
||||
if ( $repo_id === $repo_request ) {
|
||||
$repos[ $repo_id ] = $user_agree;
|
||||
}
|
||||
}
|
||||
$this->setting->save( $repos );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function is_valid_request() {
|
||||
return isset( $_POST['nonce'] ) && wp_verify_nonce( $_POST['nonce'], self::AJAX_ACTION );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Installer_WP_Components_Setting_Resources {
|
||||
|
||||
/**
|
||||
* @var WP_Installer
|
||||
*/
|
||||
private $installer;
|
||||
|
||||
const HANDLES_OTGS_INSTALLER_UI = 'otgs-installer-ui';
|
||||
|
||||
public function __construct( WP_Installer $installer ) {
|
||||
$this->installer = $installer;
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_resources' ) );
|
||||
}
|
||||
|
||||
public function enqueue_resources() {
|
||||
$resources_url = $this->installer->res_url();
|
||||
|
||||
wp_register_style(
|
||||
self::HANDLES_OTGS_INSTALLER_UI,
|
||||
$resources_url . '/dist/css/component-settings-reports/styles.css',
|
||||
array(),
|
||||
WP_INSTALLER_VERSION
|
||||
);
|
||||
|
||||
wp_enqueue_script(
|
||||
'otgs-installer-components-save-setting',
|
||||
$resources_url . '/res/js/save-components-setting.js',
|
||||
array(),
|
||||
WP_INSTALLER_VERSION
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Installer_WP_Components_Storage {
|
||||
|
||||
const COMPONENTS_CACHE_OPTION_KEY = 'otgs_active_components';
|
||||
|
||||
public function refresh_cache() {
|
||||
$active_theme = wp_get_theme();
|
||||
$installed_plugins = $this->get_plugins();
|
||||
$components = array();
|
||||
|
||||
foreach ( $installed_plugins as $file => $plugin ) {
|
||||
if ( is_plugin_active( $file ) ) {
|
||||
$components['plugin'][] = array(
|
||||
'File' => $file,
|
||||
'Name' => $plugin['Name'],
|
||||
'Version' => $plugin['Version'],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$components['theme'][] = array(
|
||||
'Template' => $active_theme->get_template(),
|
||||
'Name' => $active_theme->get( 'Name' ),
|
||||
'Version' => $active_theme->get( 'Version' ),
|
||||
);
|
||||
|
||||
update_option( self::COMPONENTS_CACHE_OPTION_KEY, $components );
|
||||
}
|
||||
|
||||
public function is_outdated() {
|
||||
$components = $this->get();
|
||||
|
||||
if ( ! $components ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$current_theme = wp_get_theme();
|
||||
$active_plugins = get_option( 'active_plugins' );
|
||||
|
||||
if ( ! function_exists( 'get_plugins' ) ) {
|
||||
require_once ABSPATH . 'wp-admin/includes/plugin.php';
|
||||
}
|
||||
|
||||
$installed_plugins = $this->get_plugins();
|
||||
|
||||
if ( isset( $components['theme'] ) ) {
|
||||
if ( $components['theme'][0]['Template'] !== $current_theme->get_template() ||
|
||||
$components['theme'][0]['Version'] !== $current_theme->get( 'Version' )
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( array_key_exists( 'plugin', $components ) ) {
|
||||
$cached_activated_plugins = wp_list_pluck( $components['plugin'], 'File' );
|
||||
sort( $cached_activated_plugins );
|
||||
sort( $active_plugins );
|
||||
|
||||
if ( $cached_activated_plugins !== $active_plugins ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
foreach ( $components['plugin'] as $plugin ) {
|
||||
if ( $plugin['Version'] !== $installed_plugins[ $plugin['File'] ]['Version'] ||
|
||||
! is_plugin_active( $plugin['File'] )
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function get() {
|
||||
return get_option( self::COMPONENTS_CACHE_OPTION_KEY );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function get_plugins() {
|
||||
if ( ! function_exists( 'get_plugins' ) ) {
|
||||
require_once ABSPATH . 'wp-admin/includes/plugin.php';
|
||||
}
|
||||
|
||||
return get_plugins();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Installer_WP_Share_Local_Components_Setting_Hooks {
|
||||
|
||||
const TEMPLATE_CHECKBOX = 'share-local-data-setting';
|
||||
const TEMPLATE_RADIO = 'share-local-data-setting-radio';
|
||||
|
||||
/**
|
||||
* @var OTGS_Template_Service
|
||||
*/
|
||||
private $template_service;
|
||||
|
||||
/**
|
||||
* @var OTGS_Installer_WP_Share_Local_Components_Setting
|
||||
*/
|
||||
private $setting;
|
||||
|
||||
public function __construct(
|
||||
OTGS_Template_Service $template_service,
|
||||
OTGS_Installer_WP_Share_Local_Components_Setting $setting
|
||||
) {
|
||||
$this->template_service = $template_service;
|
||||
$this->setting = $setting;
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
add_action( 'otgs_installer_render_local_components_setting',
|
||||
array(
|
||||
$this,
|
||||
'render_local_components_setting',
|
||||
),
|
||||
10,
|
||||
5 );
|
||||
add_filter( 'otgs_installer_has_local_components_setting',
|
||||
array( $this, 'has_local_components_setting_filter' ),
|
||||
10,
|
||||
2 );
|
||||
add_filter( 'otgs_installer_repository_subscription_status',
|
||||
array( $this, 'get_installer_repository_subscription_status' ),
|
||||
10,
|
||||
2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function render_local_components_setting( array $args ) {
|
||||
$params = $this->validate_arguments( $args );
|
||||
|
||||
$template = self::TEMPLATE_CHECKBOX;
|
||||
if ( (bool) $params['use_radio'] ) {
|
||||
$template = self::TEMPLATE_RADIO;
|
||||
}
|
||||
|
||||
if ( (bool) $params['use_styles'] ) {
|
||||
wp_enqueue_style( OTGS_Installer_WP_Components_Setting_Resources::HANDLES_OTGS_INSTALLER_UI );
|
||||
|
||||
if(!(bool) $params['use_radio']) {
|
||||
wp_enqueue_style('otgsSwitcher');
|
||||
}
|
||||
}
|
||||
|
||||
echo $this->template_service->show( $this->get_model( $params ), $template );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $ignore
|
||||
* @param string $repo (wpml|toolset)
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has_local_components_setting_filter( $ignore, $repo ) {
|
||||
return $this->setting->has_setting( $repo );
|
||||
}
|
||||
|
||||
public function get_installer_repository_subscription_status( $ignore, $repo ) {
|
||||
$subscription = WP_Installer()->get_subscription( $repo );
|
||||
|
||||
return $subscription->get_subscription_status_text();
|
||||
}
|
||||
|
||||
private function get_model( $params ) {
|
||||
$plugin_name = $params['plugin_name'];
|
||||
$plugin_uri = $params['plugin_uri'];
|
||||
$plugin_site = $params['plugin_site'];
|
||||
$custom_heading = $params['custom_heading'];
|
||||
$custom_label = $params['custom_label'];
|
||||
$privacy_policy_url = $params['privacy_policy_url'];
|
||||
$privacy_policy_text = $params['privacy_policy_text'];
|
||||
$custom_privacy_policy_text = $params['custom_privacy_policy_text'];
|
||||
$repo = isset( $params['plugin_repository'] ) ? $params['plugin_repository'] : strtolower( $plugin_name );
|
||||
|
||||
return array(
|
||||
'strings' => array(
|
||||
'heading' => __( 'Reporting to', 'installer' ),
|
||||
'report_to' => __( 'Report to', 'installer' ),
|
||||
'radio_report_yes' => __( 'Send theme and plugins information, in order to get faster support and compatibility alerts',
|
||||
'installer' ),
|
||||
'radio_report_no' => __( "Don't send this information and skip compatibility alerts",
|
||||
'installer' ),
|
||||
'which_theme_and_plugins' => __( 'which theme and plugins you are using.', 'installer' ),
|
||||
),
|
||||
'custom_raw_heading' => $custom_heading,
|
||||
'custom_raw_label' => $custom_label,
|
||||
'custom_privacy_policy_text' => $custom_privacy_policy_text,
|
||||
'privacy_policy_url' => $privacy_policy_url,
|
||||
'privacy_policy_text' => $privacy_policy_text,
|
||||
'component_name' => $plugin_name,
|
||||
'company_url' => $plugin_uri,
|
||||
'company_site' => $plugin_site,
|
||||
'nonce' => array(
|
||||
'action' => OTGS_Installer_WP_Components_Setting_Ajax::AJAX_ACTION,
|
||||
'value' => wp_create_nonce( OTGS_Installer_WP_Components_Setting_Ajax::AJAX_ACTION ),
|
||||
),
|
||||
'repo' => $repo,
|
||||
'is_repo_allowed' => $this->setting->is_repo_allowed( $repo ),
|
||||
'has_setting' => (int) $this->setting->has_setting( $repo ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*
|
||||
* @return array
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
private function validate_arguments( array $args ) {
|
||||
if ( ! $args ) {
|
||||
throw new InvalidArgumentException( 'Arguments are missing' );
|
||||
}
|
||||
|
||||
$defaults = array(
|
||||
'custom_heading' => null,
|
||||
'custom_label' => null,
|
||||
'custom_radio_label_yes' => null,
|
||||
'custom_radio_label_no' => null,
|
||||
'custom_privacy_policy_text' => null,
|
||||
'use_styles' => false,
|
||||
'use_radio' => false,
|
||||
'privacy_policy_text' => __( 'Privacy and data usage policy', 'installer' ),
|
||||
'plugin_site' => null,
|
||||
'plugin_uri' => null,
|
||||
);
|
||||
|
||||
$required_arguments = array( 'plugin_name', 'privacy_policy_url' );
|
||||
|
||||
if ( ! $this->must_use_radios( $args ) ) {
|
||||
$required_arguments = array( 'plugin_uri', 'plugin_site' );
|
||||
}
|
||||
|
||||
foreach ( $required_arguments as $required_argument ) {
|
||||
if ( ! $this->has_required_argument( $args, $required_argument ) ) {
|
||||
throw new InvalidArgumentException( $required_argument . ' is missing' );
|
||||
}
|
||||
}
|
||||
|
||||
return array_merge( $defaults, $args );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function must_use_radios( array $args ) {
|
||||
return array_key_exists( 'use_radio', $args ) && $args['use_radio'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
* @param string $required_argument
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function has_required_argument( array $args, $required_argument ) {
|
||||
return array_key_exists( $required_argument, $args ) && $args[ $required_argument ];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Installer_WP_Share_Local_Components_Setting {
|
||||
|
||||
const OPTION_KEY = 'otgs_share_local_components';
|
||||
|
||||
public function save( array $repos ) {
|
||||
$settings = array_merge( $this->get(), $repos );
|
||||
update_option( self::OPTION_KEY, $settings );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $repo
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_repo_allowed( $repo ) {
|
||||
$allowed_repos = $this->get();
|
||||
|
||||
return isset( $allowed_repos[ $repo ] ) && $allowed_repos[ $repo ];
|
||||
}
|
||||
|
||||
public function has_setting( $repo ) {
|
||||
$current_value = self::get();
|
||||
|
||||
return $current_value
|
||||
&& array_key_exists( $repo, $current_value );
|
||||
}
|
||||
|
||||
public static function get_setting ( $repo) {
|
||||
$current_value = self::get();
|
||||
return array_key_exists( $repo, $current_value ) ? $current_value[$repo] : null;
|
||||
}
|
||||
|
||||
private static function get() {
|
||||
$setting = get_option( self::OPTION_KEY );
|
||||
return $setting ? $setting : array();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
class Translation_Service_Info {
|
||||
|
||||
public function add_hooks() {
|
||||
|
||||
add_action( 'installer_fetched_subscription_data', array( $this, 'save_info' ), 10, 2 );
|
||||
|
||||
}
|
||||
|
||||
public function save_info( $data, $repository_id ) {
|
||||
|
||||
$ts_info = isset( WP_Installer()->settings['repositories'][ $repository_id ]['ts_info'] ) ?
|
||||
WP_Installer()->settings['repositories'][ $repository_id ]['ts_info'] : false;
|
||||
|
||||
$save_settings = false;
|
||||
if ( isset( $data->ts_info['preferred'] ) && empty( $ts_info['preferred'] ) ) {
|
||||
WP_Installer()->settings['repositories'][ $repository_id ]['ts_info']['preferred'] = $data->ts_info['preferred'];
|
||||
$save_settings = true;
|
||||
}
|
||||
|
||||
if ( isset( $data->ts_info['referal'] ) && empty( $ts_info['referal'] ) ) {
|
||||
WP_Installer()->settings['repositories'][ $repository_id ]['ts_info']['referal'] = $data->ts_info['referal'];
|
||||
$save_settings = true;
|
||||
}
|
||||
|
||||
if ( ! empty( $data->ts_info['client_id'] ) ) { // can be updated
|
||||
WP_Installer()->settings['repositories'][ $repository_id ]['ts_info']['client_id'] = $data->ts_info['client_id'];
|
||||
$save_settings = true;
|
||||
}
|
||||
|
||||
if ( $save_settings ) {
|
||||
WP_Installer()->save_settings();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
|
||||
class WP_Installer_API{
|
||||
|
||||
public static function get_product_installer_link($repository_id, $package_id = false){
|
||||
|
||||
$menu_url = WP_Installer()->menu_url();
|
||||
|
||||
$url = $menu_url . '#' . $repository_id;
|
||||
if($package_id){
|
||||
$url .= '/' . $package_id;
|
||||
}
|
||||
|
||||
return $url;
|
||||
|
||||
}
|
||||
|
||||
public static function get_product_price($repository_id, $package_id, $product_id, $incl_discount = false){
|
||||
|
||||
$price = WP_Installer()->get_product_price($repository_id, $package_id, $product_id, $incl_discount);
|
||||
|
||||
return $price;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the preferred translation service.
|
||||
*
|
||||
* @since 1.6.5
|
||||
*
|
||||
* @param string The repository id (e.g. wpml)
|
||||
* @return string The translation service id
|
||||
*/
|
||||
public static function get_preferred_ts($repository_id = 'wpml'){
|
||||
|
||||
if(isset(WP_Installer()->settings['repositories'][$repository_id]['ts_info']['preferred'])){
|
||||
return WP_Installer()->settings['repositories'][$repository_id]['ts_info']['preferred'];
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the preferred translation service.
|
||||
*
|
||||
* @since 1.6.5
|
||||
*
|
||||
* @param string The translation service id
|
||||
* @param string The repository id (e.g. wpml)
|
||||
*/
|
||||
public static function set_preferred_ts( $value, $repository_id = 'wpml' ){
|
||||
|
||||
if( isset( WP_Installer()->settings['repositories'][$repository_id]['ts_info']['preferred'] ) ){
|
||||
|
||||
WP_Installer()->settings['repositories'][$repository_id]['ts_info']['preferred'] = $value;
|
||||
|
||||
WP_Installer()->save_settings();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the referring translation service (if any)
|
||||
*
|
||||
* @since 1.6.5
|
||||
*
|
||||
* @param string The repository id (e.g. wpml)
|
||||
* @return string The translation service id or false
|
||||
*/
|
||||
public static function get_ts_referal($repository_id = 'wpml'){
|
||||
|
||||
if(isset(WP_Installer()->settings['repositories'][$repository_id]['ts_info']['referal'])){
|
||||
return WP_Installer()->settings['repositories'][$repository_id]['ts_info']['referal'];
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the translation services client id for a specific repository (if any)
|
||||
*
|
||||
* @since 1.7.9
|
||||
*
|
||||
* @param string The repository id (e.g. wpml)
|
||||
* @return string The client id or false
|
||||
*/
|
||||
public static function get_ts_client_id( $repository_id = 'wpml' ){
|
||||
|
||||
if(isset(WP_Installer()->settings['repositories'][$repository_id]['ts_info']['client_id'])){
|
||||
return WP_Installer()->settings['repositories'][$repository_id]['ts_info']['client_id'];
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the site key corresponding to a repository.
|
||||
* This is a wrapper of WP_Installer::get_site_key()
|
||||
* @see WP_Installer::get_site_key()
|
||||
*
|
||||
* @since 1.7.9
|
||||
*
|
||||
* @param string The repository id (e.g. wpml)
|
||||
* @return string The site key (or false)
|
||||
*/
|
||||
public static function get_site_key( $repository_id = 'wpml' ){
|
||||
|
||||
return WP_Installer()->get_site_key( $repository_id );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the ID of the last user who registered a repository.
|
||||
*
|
||||
* @since 1.7.16
|
||||
*
|
||||
* @param string The repository id (e.g. wpml)
|
||||
* @return int The user id (or zero)
|
||||
*/
|
||||
public static function get_registering_user_id( $repository_id = 'wpml' ){
|
||||
|
||||
$user_id = 0;
|
||||
if( isset( WP_Installer()->settings['repositories'][$repository_id]['subscription']['registered_by'] ) ){
|
||||
$user_id = WP_Installer()->settings['repositories'][$repository_id]['subscription']['registered_by'];
|
||||
}
|
||||
|
||||
return $user_id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,281 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WP_Installer_Channels
|
||||
* @since 1.8
|
||||
*/
|
||||
class WP_Installer_Channels{
|
||||
|
||||
const CHANNEL_PRODUCTION = 'production';
|
||||
const CHANNEL_BETA = 'beta';
|
||||
const CHANNEL_DEVELOPMENT = 'development';
|
||||
|
||||
protected static $_instance = null;
|
||||
|
||||
function __construct() {
|
||||
add_action( 'init', array( $this, 'init' ), 20 ); // after Installer
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|WP_Installer_Channels
|
||||
*/
|
||||
public static function instance() {
|
||||
|
||||
if ( is_null( self::$_instance ) ) {
|
||||
self::$_instance = new self();
|
||||
}
|
||||
|
||||
return self::$_instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the channel literal id based on the numeric id
|
||||
*
|
||||
* @param mixed $id
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function channel_name_by_id( $id ) {
|
||||
if ( self::CHANNEL_DEVELOPMENT === $id ) {
|
||||
$channel = __( 'Development', 'installer' );
|
||||
} elseif ( self::CHANNEL_BETA === $id ) {
|
||||
$channel = __( 'Beta', 'installer' );
|
||||
} else {
|
||||
$channel = __( 'Production', 'installer' );
|
||||
}
|
||||
|
||||
return $channel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialization
|
||||
*/
|
||||
public function init(){
|
||||
global $pagenow;
|
||||
|
||||
if ( defined( 'DOING_AJAX' ) ) {
|
||||
add_action( 'wp_ajax_installer_set_channel', array( $this, 'set_channel' ) );
|
||||
}
|
||||
|
||||
if ( $pagenow === 'plugin-install.php' && isset( $_GET['tab'] ) && $_GET['tab'] === 'commercial' ) {
|
||||
wp_enqueue_script( 'installer-channels', WP_Installer()->res_url() . '/res/js/channels.js', array( 'jquery' ), WP_Installer()->version() );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajax handler for channel switching
|
||||
*/
|
||||
public function set_channel(){
|
||||
$repository_id = sanitize_text_field( $_POST['repository_id'] );
|
||||
$channel = sanitize_text_field( $_POST['channel'] );
|
||||
|
||||
$response = array();
|
||||
if ( wp_verify_nonce( $_POST['nonce'], 'installer_set_channel:' . $repository_id ) ) {
|
||||
if( isset( WP_Installer()->settings['repositories'][$repository_id] ) ){
|
||||
WP_Installer()->settings['repositories'][$repository_id]['channel'] = $channel;
|
||||
WP_Installer()->settings['repositories'][$repository_id]['no-prompt'] = $_POST['noprompt'] === 'true';
|
||||
WP_Installer()->save_settings();
|
||||
}
|
||||
|
||||
WP_Installer()->refresh_repositories_data();
|
||||
|
||||
$response['status'] = 'OK';
|
||||
}
|
||||
|
||||
echo json_encode( $response );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $repository_id
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function get_channel( $repository_id ){
|
||||
$channel = self::CHANNEL_PRODUCTION;
|
||||
if( isset( WP_Installer()->settings['repositories'][$repository_id]['channel'] ) ){
|
||||
$channel = WP_Installer()->settings['repositories'][$repository_id]['channel'];
|
||||
}
|
||||
return $channel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $repository_id
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function get_no_prompt( $repository_id ) {
|
||||
$settings = WP_Installer()->settings;
|
||||
|
||||
return ! empty( $settings['repositories'][ $repository_id ]['no-prompt'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $repository_id
|
||||
* @param array $downloads
|
||||
*/
|
||||
public function load_channel_selector( $repository_id, $downloads ) {
|
||||
|
||||
$available_channels = $this->get_available_channels( $repository_id );
|
||||
|
||||
if ( $available_channels ) {
|
||||
$args = array(
|
||||
'can_switch' => $this->can_use_unstable_channels( $downloads )
|
||||
|| $this->get_channel( $repository_id ) != self::CHANNEL_PRODUCTION,
|
||||
'channels' => $available_channels,
|
||||
'repository_id' => $repository_id,
|
||||
'current_channel' => $this->get_channel( $repository_id ),
|
||||
'no_prompt' => $this->get_no_prompt( $repository_id ),
|
||||
'nonce' => wp_create_nonce( 'installer_set_channel:' . $repository_id )
|
||||
);
|
||||
extract( $args );
|
||||
include WP_Installer()->plugin_path() . '/templates/channel-selector.php';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The beta and development channels can be used only when already using the most up to date versions
|
||||
* @param array $downloads
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function can_use_unstable_channels( $downloads ){
|
||||
|
||||
$can = true;
|
||||
foreach( $downloads as $download ){
|
||||
$available_version = $download['version'];
|
||||
$installed_version = WP_Installer()->plugin_is_installed( $download['name'], $download['slug'] );
|
||||
if( $installed_version !== false && version_compare( $available_version, $installed_version, '>' ) ){
|
||||
$can = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $can;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get available updates channels. Only include channels with actual downloads available.
|
||||
*
|
||||
* @param string $repository_id
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_available_channels( $repository_id ) {
|
||||
|
||||
$beta = false;
|
||||
$dev = false;
|
||||
|
||||
$downloads = WP_Installer()->settings['repositories'][ $repository_id ]['data']['downloads'];
|
||||
foreach ( $downloads as $type => $download_types ) {
|
||||
foreach ( $download_types as $download ) {
|
||||
$extra_channels = isset( $download['extra_channels'] ) ? array_keys( $download['extra_channels'] ) : array();
|
||||
if ( ! $beta && in_array( self::CHANNEL_BETA, $extra_channels ) ) {
|
||||
$beta = true;
|
||||
}
|
||||
if ( ! $dev && in_array( self::CHANNEL_DEVELOPMENT, $extra_channels ) ) {
|
||||
$dev = true;
|
||||
}
|
||||
if ( $beta && $dev ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$channels = array();
|
||||
if ( $beta || $dev ) {
|
||||
$channels[ self::CHANNEL_PRODUCTION ] = self::channel_name_by_id( self::CHANNEL_PRODUCTION );
|
||||
if ( $beta ) {
|
||||
$channels[ self::CHANNEL_BETA ] = self::channel_name_by_id( self::CHANNEL_BETA );
|
||||
}
|
||||
if ( $dev ) {
|
||||
$channels[ self::CHANNEL_DEVELOPMENT ] = self::channel_name_by_id( self::CHANNEL_DEVELOPMENT );
|
||||
}
|
||||
}
|
||||
|
||||
return $channels;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $repository_id
|
||||
* @param array $downloads
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function filter_downloads_by_channel( $repository_id, $downloads ) {
|
||||
|
||||
$current_channel = $this->get_channel( $repository_id );
|
||||
|
||||
foreach ( $downloads as $type => $type_downloads ) {
|
||||
foreach ( $type_downloads as $slug => $download ) {
|
||||
|
||||
$override_download = array();
|
||||
if ( $current_channel === self::CHANNEL_DEVELOPMENT ) {
|
||||
if( ! empty( $download['channels']['development'] ) ){
|
||||
$override_download = $download['channels']['development'];
|
||||
$override_download['channel'] = self::CHANNEL_DEVELOPMENT;
|
||||
}elseif( ! empty( $download['channels']['beta'] ) ){
|
||||
$override_download = $download['channels']['beta'];
|
||||
$override_download['channel'] = self::CHANNEL_BETA;
|
||||
}
|
||||
}elseif ( $current_channel === self::CHANNEL_BETA && ! empty( $download['channels']['beta'] ) ) {
|
||||
$override_download = $download['channels']['beta'];
|
||||
$override_download['channel'] = self::CHANNEL_BETA;
|
||||
}
|
||||
|
||||
if ( $override_download ) {
|
||||
foreach ( $override_download as $key => $value ) {
|
||||
$downloads[ $type ][ $slug ][ $key ] = $value;
|
||||
}
|
||||
} else {
|
||||
$downloads[ $type ][ $slug ]['channel'] = self::CHANNEL_PRODUCTION;
|
||||
}
|
||||
unset ( $downloads[ $type ][ $slug ]['channels'] );
|
||||
|
||||
$downloads[ $type ][ $slug ]['extra_channels'] = array();
|
||||
if( isset( $download['channels'] ) ) {
|
||||
foreach( $download['channels'] as $channel_id => $channel ){
|
||||
$downloads[ $type ][ $slug ]['extra_channels'][$channel_id] = array(
|
||||
'version' => $channel['version']
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return $downloads;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the source channel for the installed version when on the Beta or Development channel
|
||||
* @param string $version
|
||||
* @param string $repository_id
|
||||
* @param string $download_id
|
||||
* @param string $download_kind
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_download_source_channel( $version, $repository_id, $download_id, $download_kind ) {
|
||||
|
||||
$version_channel = '';
|
||||
$installer_settings = WP_Installer()->get_settings();
|
||||
if ( isset( $installer_settings['repositories'][ $repository_id ] ) ) {
|
||||
$repository_data = $installer_settings['repositories'][ $repository_id ]['data'];
|
||||
if ( isset( $repository_data['downloads'][ $download_kind ][ $download_id ]['extra_channels'] ) ) {
|
||||
|
||||
foreach ( $repository_data['downloads'][ $download_kind ][ $download_id ]['extra_channels'] as $channel_id => $channel_data ) {
|
||||
if ( $version === $channel_data['version'] ) {
|
||||
$version_channel = self::channel_name_by_id( $channel_id );
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $version_channel;
|
||||
}
|
||||
}
|
||||
3207
wp-content/plugins/sitepress-multilingual-cms/vendor/otgs/installer/includes/class-wp-installer.php
vendored
Normal file
3207
wp-content/plugins/sitepress-multilingual-cms/vendor/otgs/installer/includes/class-wp-installer.php
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Installer_Log_Factory {
|
||||
|
||||
/**
|
||||
* @return OTGS_Installer_Log
|
||||
*/
|
||||
public function create() {
|
||||
return new OTGS_Installer_Log();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Installer_Log {
|
||||
|
||||
private $time;
|
||||
private $request_url;
|
||||
private $request_args;
|
||||
private $response;
|
||||
private $component;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_time() {
|
||||
return $this->time;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $time
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function set_time( $time ) {
|
||||
$this->time = $time;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_request_url() {
|
||||
return $this->request_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $request_url
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function set_request_url( $request_url ) {
|
||||
$this->request_url = $request_url;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function get_request_args() {
|
||||
return $this->request_args;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $request_args
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function set_request_args( $request_args ) {
|
||||
$this->request_args = $request_args;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_response() {
|
||||
return $this->response;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $response
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function set_response( $response ) {
|
||||
$this->response = $response;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_component() {
|
||||
return $this->component;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $component
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function set_component( $component ) {
|
||||
$this->component = $component;
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Installer_Logger_Storage {
|
||||
|
||||
const MAX_SIZE = 50;
|
||||
|
||||
const OPTION_KEY = 'otgs-installer-log';
|
||||
|
||||
const COMPONENT_SUBSCRIPTION = 'subscription-fetching';
|
||||
const COMPONENT_PRODUCTS_URL = 'products-url-fetching';
|
||||
const COMPONENT_DOWNLOAD = 'download';
|
||||
const COMPONENT_REPOSITORIES = 'repositories-fetching';
|
||||
const COMPONENT_PRODUCTS_PARSING = 'products-parsing';
|
||||
const API_CONNECTION_TEST = 'api-connection-test';
|
||||
const PRODUCTS_FILE_CONNECTION_TEST = 'products-connection-test';
|
||||
|
||||
private $log_entries;
|
||||
private $log_factory;
|
||||
private $max_size;
|
||||
|
||||
public function __construct( OTGS_Installer_Log_Factory $log_factory, $max_size = self::MAX_SIZE ) {
|
||||
$this->max_size = $max_size;
|
||||
$this->log_factory = $log_factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|OTGS_Installer_Log[]
|
||||
*/
|
||||
public function get() {
|
||||
if ( ! $this->log_entries ) {
|
||||
$this->log_entries = get_option( self::OPTION_KEY );
|
||||
}
|
||||
|
||||
return $this->convert_to_object( $this->log_entries ? $this->log_entries : array() );
|
||||
}
|
||||
|
||||
public function add( OTGS_Installer_Log $log ) {
|
||||
$log->set_time( date( 'Y-d-m h:m:s' ) );
|
||||
$log_entries = $this->get();
|
||||
array_unshift( $log_entries, $log );
|
||||
$log_entries = array_slice( $log_entries, 0, $this->max_size );
|
||||
$log_entries_arr = $this->convert_to_array( $log_entries );
|
||||
update_option( self::OPTION_KEY, $log_entries_arr );
|
||||
$this->log_entries = $log_entries_arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $log_entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function convert_to_object( $log_entries ) {
|
||||
$log_converted = array();
|
||||
|
||||
foreach ( $log_entries as $log_data ) {
|
||||
$log = $this->log_factory->create();
|
||||
$log->set_request_args( $log_data['request_args'] )
|
||||
->set_request_url( $log_data['request_url'] )
|
||||
->set_response( $log_data['response'] )
|
||||
->set_time( $log_data['time'] )
|
||||
->set_component( $log_data['component'] );
|
||||
$log_converted[] = $log;
|
||||
}
|
||||
|
||||
return $log_converted;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param OTGS_Installer_Log[] $log_entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function convert_to_array( $log_entries ) {
|
||||
$log_converted = array();
|
||||
|
||||
foreach ( $log_entries as $log_data ) {
|
||||
$log_converted[] = array(
|
||||
'request_args' => $log_data->get_request_args(),
|
||||
'request_url' => $log_data->get_request_url(),
|
||||
'response' => $log_data->get_response(),
|
||||
'component' => $log_data->get_component(),
|
||||
'time' => $log_data->get_time(),
|
||||
);
|
||||
}
|
||||
|
||||
return $log_converted;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Installer_Logger {
|
||||
|
||||
private $installer;
|
||||
private $storage;
|
||||
private $logger_factory;
|
||||
|
||||
public function __construct( WP_Installer $installer, OTGS_Installer_Logger_Storage $storage ) {
|
||||
$this->installer = $installer;
|
||||
$this->storage = $storage;
|
||||
}
|
||||
|
||||
public function get_api_log() {
|
||||
return $this->installer->get_api_debug();
|
||||
}
|
||||
|
||||
public function add_api_log( $log ) {
|
||||
$this->installer->api_debug_log( $log );
|
||||
}
|
||||
|
||||
public function save_log( OTGS_Installer_Log $log ) {
|
||||
$this->storage->add( $log );
|
||||
}
|
||||
|
||||
public function add_log( $log ) {
|
||||
$this->installer->log( $log );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Installer_Products_Parsing_Exception extends Exception {
|
||||
const RESPONSE_PARSING_ERROR_MESSAGE = 'Error in response parsing from %s.';
|
||||
|
||||
public static function createForResponse( $products_url ) {
|
||||
return new OTGS_Installer_Products_Parsing_Exception(
|
||||
sprintf(
|
||||
self::RESPONSE_PARSING_ERROR_MESSAGE,
|
||||
$products_url
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Installer_Fetch_Subscription_Exception extends Exception {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Installer_Site_Key_Exception extends Exception {
|
||||
}
|
||||
34
wp-content/plugins/sitepress-multilingual-cms/vendor/otgs/installer/includes/functions-core.php
vendored
Normal file
34
wp-content/plugins/sitepress-multilingual-cms/vendor/otgs/installer/includes/functions-core.php
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
function WP_Installer(){
|
||||
return WP_Installer::instance();
|
||||
}
|
||||
|
||||
function OTGS_Installer(){
|
||||
return WP_Installer::instance();
|
||||
}
|
||||
|
||||
function WP_Installer_Channels(){
|
||||
return WP_Installer_Channels::instance();
|
||||
}
|
||||
|
||||
function otgs_installer_get_logger_storage() {
|
||||
static $logger_storage;
|
||||
if ( ! $logger_storage ) {
|
||||
$logger_storage = new OTGS_Installer_Logger_Storage( new OTGS_Installer_Log_Factory() );
|
||||
}
|
||||
|
||||
return $logger_storage;
|
||||
}
|
||||
|
||||
function get_OTGS_Installer_Factory() {
|
||||
static $installer_factory;
|
||||
|
||||
if ( ! $installer_factory ) {
|
||||
$installer_factory = new OTGS_Installer_Factory( WP_Installer() );
|
||||
}
|
||||
|
||||
return $installer_factory;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
// Ext function
|
||||
function WP_Installer_Show_Products($args = array()){
|
||||
WP_Installer()->show_products($args);
|
||||
}
|
||||
|
||||
function WP_Installer_get_local_components_setting_ui( $args ) {
|
||||
$installer_factory = get_OTGS_Installer_Factory();
|
||||
|
||||
ob_start();
|
||||
$installer_factory->create_settings_hooks()
|
||||
->render_local_components_setting( $args );
|
||||
|
||||
return ob_get_clean();
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Installer_Instance {
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $bootfile;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $version;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $high_priority;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $delegated;
|
||||
|
||||
/**
|
||||
* @param string $bootfile
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function set_bootfile( $bootfile ) {
|
||||
$this->bootfile = $bootfile;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $high_priority
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function set_high_priority( $high_priority ) {
|
||||
$this->high_priority = $high_priority;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $version
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function set_version( $version ) {
|
||||
$this->version = $version;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $delegated
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function set_delegated( $delegated ) {
|
||||
$this->delegated = (bool) $delegated;
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Installer_Instances_Factory {
|
||||
|
||||
public function create() {
|
||||
global $wp_installer_instances;
|
||||
|
||||
return new OTGS_Installer_Instances( $wp_installer_instances );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Installer_Instances {
|
||||
|
||||
private $instances;
|
||||
|
||||
/**
|
||||
* @var OTGS_Installer_Instance[]
|
||||
*/
|
||||
private $instances_obj = array();
|
||||
|
||||
public function __construct( $instances ) {
|
||||
$this->instances = $instances;
|
||||
}
|
||||
|
||||
public function get() {
|
||||
if ( ! $this->instances_obj ) {
|
||||
foreach( $this->instances as $instance ) {
|
||||
$instance_obj = new OTGS_Installer_Instance();
|
||||
$instance_obj->set_bootfile( $instance['bootfile'] )
|
||||
->set_high_priority( isset( $instance['high_priority'] ) && $instance['high_priority'] )
|
||||
->set_version( $instance['version'] )
|
||||
->set_delegated( isset( $instance['delegated'] ) && $instance['delegated'] );
|
||||
|
||||
$this->instances_obj[] = $instance_obj;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return $this->instances_obj;
|
||||
}
|
||||
}
|
||||
25
wp-content/plugins/sitepress-multilingual-cms/vendor/otgs/installer/includes/loader/Config.php
vendored
Normal file
25
wp-content/plugins/sitepress-multilingual-cms/vendor/otgs/installer/includes/loader/Config.php
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace OTGS\Installer\Loader;
|
||||
|
||||
class Config {
|
||||
|
||||
public static function merge( array $delegate, array $wpInstallerInstances ) {
|
||||
$args_to_merge = [ 'site_key_nags' ];
|
||||
foreach ( $wpInstallerInstances as $instance ) {
|
||||
if ( $instance['bootfile'] !== $delegate['bootfile'] ) {
|
||||
foreach ( $args_to_merge as $arg ) {
|
||||
if ( isset( $instance['args'][ $arg ] ) && is_array( $instance['args'][ $arg ] ) ) {
|
||||
if ( isset( $delegate['args'][ $arg ] ) ) {
|
||||
$delegate['args'][ $arg ] = array_merge_recursive( $delegate['args'][ $arg ], $instance['args'][ $arg ] );
|
||||
} else {
|
||||
$delegate['args'][ $arg ] = $instance['args'][ $arg ];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $delegate;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
<?php
|
||||
$baseDir = dirname( __DIR__ );
|
||||
|
||||
return [
|
||||
'Installer_Dependencies' => $baseDir . '/includes/class-installer-dependencies.php',
|
||||
'Installer_Theme_Class' => $baseDir . '/includes/class-installer-theme.php',
|
||||
'Installer_Upgrader_Skins' => $baseDir . '/includes/class-installer-upgrader-skins.php',
|
||||
'OTGS_Installer_Autoloader' => $baseDir . '/includes/class-otgs-installer-autoloader.php',
|
||||
'OTGS_Installer_Factory' => $baseDir . '/includes/class-otgs-installer-factory.php',
|
||||
'OTGS_Installer_Fetch_Subscription' => $baseDir . '/includes/site-key/class-otgs-installer-fetch-subscription.php',
|
||||
'OTGS_Installer_Fetch_Subscription_Exception' => $baseDir . '/includes/exceptions/class-otgs-installer-fetch-subscription-exception.php',
|
||||
'OTGS_Installer_Filename_Hooks' => $baseDir . '/includes/class-otgs-installer-filename-hooks.php',
|
||||
'OTGS_Installer_Icons' => $baseDir . '/includes/class-otgs-installer-icons.php',
|
||||
'OTGS_Installer_Logger' => $baseDir . '/includes/debug/class-otgs-installer-logger.php',
|
||||
'OTGS_Installer_PHP_Functions' => $baseDir . '/includes/class-otgs-installer-php-functions.php',
|
||||
'OTGS_Installer_Package' => $baseDir . '/includes/class-otgs-installer-package.php',
|
||||
'OTGS_Installer_Package_Product' => $baseDir . '/includes/class-otgs-installer-package-product.php',
|
||||
'OTGS_Installer_Package_Product_Finder' => $baseDir . '/includes/class-otgs-installer-package-product-finder.php',
|
||||
'OTGS_Installer_Plugin' => $baseDir . '/includes/class-otgs-installer-plugin.php',
|
||||
'OTGS_Installer_Plugin_Factory' => $baseDir . '/includes/class-otgs-installer-plugin-factory.php',
|
||||
'OTGS_Installer_Plugin_Finder' => $baseDir . '/includes/class-otgs-installer-plugin-finder.php',
|
||||
'OTGS_Installer_Plugins_Page_Notice' => $baseDir . '/includes/class-otgs-installer-plugins-page-notice.php',
|
||||
'OTGS_Installer_Repositories' => $baseDir . '/includes/repository/class-otgs-installer-repositories.php',
|
||||
'OTGS_Installer_Repositories_Factory' => $baseDir . '/includes/repository/class-otgs-installer-repositories-factory.php',
|
||||
'OTGS_Installer_Repository' => $baseDir . '/includes/repository/class-otgs-installer-repository.php',
|
||||
'OTGS_Installer_Repository_Factory' => $baseDir . '/includes/repository/class-otgs-installer-repository-factory.php',
|
||||
'OTGS_Installer_Site_Key_Ajax' => $baseDir . '/includes/site-key/class-otgs-installer-site-key-ajax.php',
|
||||
'OTGS_Installer_Site_Key_Exception' => $baseDir . '/includes/exceptions/class-otgs-installer-site-key-exception.php',
|
||||
'OTGS_Installer_Source' => $baseDir . '/includes/class-otgs-installer-source.php',
|
||||
'OTGS_Installer_Source_Factory' => $baseDir . '/includes/class-otgs-installer-source-factory.php',
|
||||
'OTGS_Installer_Subscription' => $baseDir . '/includes/class-otgs-installer-subscription.php',
|
||||
'OTGS_Php_Template_Service_Loader' => $baseDir . '/includes/template-service/class-otgs-php-template-service-loader.php',
|
||||
'OTGS_Template_Service_Factory' => $baseDir . '/includes/template-service/class-otgs-template-service-factory.php',
|
||||
'OTGS_Php_Template_Service' => $baseDir . '/includes/template-service/class-otgs-php-template-service.php',
|
||||
'OTGS_Template_Service' => $baseDir . '/includes/template-service/interface-otgs-template-service.php',
|
||||
'OTGS_Template_Service_Loader' => $baseDir . '/includes/template-service/interface-otgs-template-service-loader.php',
|
||||
'OTGS_Template_Service_Php_Model' => $baseDir . '/includes/template-service/class-otgs-template-service-php-model.php',
|
||||
'OTGS_Installer_Upgrade_Response' => $baseDir . '/includes/upgrade/class-otgs-installer-upgrade-response.php',
|
||||
'OTGS_Installer_WP_Components_Hooks' => $baseDir . '/includes/class-otgs-installer-wp-components-hooks.php',
|
||||
'OTGS_Installer_WP_Components_Sender' => $baseDir . '/includes/class-otgs-installer-wp-components-sender.php',
|
||||
'OTGS_Installer_WP_Components_Setting_Ajax' => $baseDir . '/includes/class-otgs-installer-wp-components-setting-ajax.php',
|
||||
'OTGS_Installer_WP_Components_Setting_Resources' => $baseDir . '/includes/class-otgs-installer-wp-components-setting-resources.php',
|
||||
'OTGS_Installer_WP_Components_Storage' => $baseDir . '/includes/class-otgs-installer-wp-components-storage.php',
|
||||
'OTGS_Installer_WP_Share_Local_Components_Setting' => $baseDir . '/includes/class-otgs-installer-wp-share-local-components-setting.php',
|
||||
'OTGS_Installer_WP_Share_Local_Components_Setting_Hooks' => $baseDir . '/includes/class-otgs-installer-wp-share-local-components-setting-hooks.php',
|
||||
'OTGS_Installer_Subscription_Factory' => $baseDir . '/includes/class-otgs-installer-subscription-factory.php',
|
||||
'Translation_Service_Info' => $baseDir . '/includes/class-translation-service-info.php',
|
||||
'WP_Installer' => $baseDir . '/includes/class-wp-installer.php',
|
||||
'WP_Installer_API' => $baseDir . '/includes/class-wp-installer-api.php',
|
||||
'WP_Installer_Channels' => $baseDir . '/includes/class-wp-installer-channels.php',
|
||||
'OTGS_Installer_Debug_Info' => $baseDir . '/includes/class-otgs-installer-debug-info.php',
|
||||
'OTGS_Installer_Loader' => $baseDir . '/includes/class-otgs-installer-loader.php',
|
||||
'OTGS_Installer_Logger_Storage' => $baseDir . '/includes/debug/class-otgs-installer-logger-storage.php',
|
||||
'OTGS_Installer_Log' => $baseDir . '/includes/debug/class-otgs-installer-log.php',
|
||||
'OTGS_Installer_Log_Factory' => $baseDir . '/includes/debug/class-otgs-installer-log-factory.php',
|
||||
'OTGS_Installer_Support_Hooks' => $baseDir . '/includes/support/class-otgs-installer-support-hooks.php',
|
||||
'OTGS_Installer_Support_Template' => $baseDir . '/includes/support/class-otgs-installer-support-template.php',
|
||||
'OTGS_Installer_Support_Template_Factory' => $baseDir . '/includes/support/class-otgs-installer-support-template-factory.php',
|
||||
'OTGS_Installer_Connection_Test' => $baseDir . '/includes/support/class-otgs-installer-connection-test.php',
|
||||
'OTGS_Installer_Connection_Test_Exception' => $baseDir . '/includes/support/class-otgs-installer-connection-test-exception.php',
|
||||
'OTGS_Installer_Connection_Test_Ajax' => $baseDir . '/includes/support/class-otgs-installer-connection-test-ajax.php',
|
||||
'OTGS_Installer_Requirements' => $baseDir . '/includes/support/class-otgs-installer-requirements.php',
|
||||
'OTGS_Installer_Instance' => $baseDir . '/includes/instances/class-otgs-installer-instance.php',
|
||||
'OTGS_Installer_Instances' => $baseDir . '/includes/instances/class-otgs-installer-instances.php',
|
||||
'OTGS_Installer_Instances_Factory' => $baseDir . '/includes/instances/class-otgs-installer-instances-factory.php',
|
||||
'OTGS_Installer_Plugins_Update_Cache_Cleaner' => $baseDir . '/includes/class-otgs-installer-plugins-update-cache-cleaner.php',
|
||||
'OTGS_Installer_Buy_URL_Hooks' => $baseDir . '/includes/buy-url/class-otgs-installer-buy-url-hooks.php',
|
||||
'OTGS_Products_Bucket_Repository' => $baseDir . '/includes/products/repository/OTGS_Products_Bucket_Repository.php',
|
||||
'OTGS_Products_Bucket_Repository_Factory' => $baseDir . '/includes/products/repository/OTGS_Products_Bucket_Repository_Factory.php',
|
||||
'OTGS_Products_Manager' => $baseDir . '/includes/products/OTGS_Products_Manager.php',
|
||||
'OTGS_Products_Manager_Factory' => $baseDir . '/includes/products/OTGS_Products_Manager_Factory.php',
|
||||
'OTGS_Products_Config_Db_Storage' => $baseDir . '/includes/products/OTGS_Products_Config_Db_Storage.php',
|
||||
'OTGS_Products_Config_Xml' => $baseDir . '/includes/products/OTGS_Products_Config_Xml.php',
|
||||
'OTGS\Installer\Collection' => $baseDir . '/includes/utilities/Collection.php',
|
||||
'OTGS_Installer_Products_Parser' => $baseDir . '/includes/products/OTGS_Installer_Products_Parser.php',
|
||||
'OTGS_Installer_Products_Parsing_Exception' => $baseDir . '/includes/exceptions/OTGS_Installer_Products_Parsing_Exception.php',
|
||||
'OTGS\Installer\AdminNotices\Display' => $baseDir . '/includes/admin-notices/Display.php',
|
||||
'OTGS\Installer\AdminNotices\Config' => $baseDir . '/includes/admin-notices/Config.php',
|
||||
'OTGS\Installer\AdminNotices\PageConfig' => $baseDir . '/includes/admin-notices/PageConfig.php',
|
||||
'OTGS\Installer\AdminNotices\ScreenConfig' => $baseDir . '/includes/admin-notices/ScreenConfig.php',
|
||||
'OTGS\Installer\AdminNotices\MessageTexts' => $baseDir . '/includes/admin-notices/MessageTexts.php',
|
||||
'OTGS\Installer\AdminNotices\Dismissed' => $baseDir . '/includes/admin-notices/Dismissed.php',
|
||||
'OTGS\Installer\AdminNotices\Loader' => $baseDir . '/includes/admin-notices/Loader.php',
|
||||
'OTGS\Installer\AdminNotices\Store' => $baseDir . '/includes/admin-notices/Store.php',
|
||||
'OTGS\Installer\AdminNotices\WPMLConfig' => $baseDir . '/includes/admin-notices/config/WPMLConfig.php',
|
||||
'OTGS\Installer\AdminNotices\TMConfig' => $baseDir . '/includes/admin-notices/config/TMConfig.php',
|
||||
'OTGS\Installer\AdminNotices\ToolsetConfig' => $baseDir . '/includes/admin-notices/config/ToolsetConfig.php',
|
||||
'OTGS\Installer\AdminNotices\Notices\Account' => $baseDir . '/includes/admin-notices/notices/Account.php',
|
||||
'OTGS\Installer\AdminNotices\Notices\Texts' => $baseDir . '/includes/admin-notices/notices/Texts.php',
|
||||
'OTGS\Installer\AdminNotices\Notices\WPMLTexts' => $baseDir . '/includes/admin-notices/notices/WPMLTexts.php',
|
||||
'OTGS\Installer\AdminNotices\Notices\ToolsetTexts' => $baseDir . '/includes/admin-notices/notices/ToolsetTexts.php',
|
||||
'OTGS\Installer\AdminNotices\Notices\ApiConnection' => $baseDir . '/includes/admin-notices/notices/ApiConnection.php',
|
||||
'OTGS\Installer\AdminNotices\Notices\Notice' => $baseDir . '/includes/admin-notices/notices/Notice.php',
|
||||
'OTGS\Installer\AdminNotices\Notices\Hooks' => $baseDir . '/includes/admin-notices/notices/Hooks.php',
|
||||
'OTGS\Installer\Templates\Repository\Register' => $baseDir . '/templates/repository-register.php',
|
||||
'OTGS\Installer\Templates\Repository\Expired' => $baseDir . '/templates/repository-expired.php',
|
||||
'OTGS\Installer\Templates\Repository\Refunded' => $baseDir . '/templates/repository-refunded.php',
|
||||
'OTGS\Installer\Templates\Repository\EndUsers' => $baseDir . '/templates/repository-end-users.php',
|
||||
'OTGS\Installer\Templates\Repository\Registered' => $baseDir . '/templates/repository-registered.php',
|
||||
'OTGS\Installer\Templates\Repository\LegacyFree' => $baseDir . '/templates/repository-legacy-free.php',
|
||||
'OTGS\Installer\Templates\Repository\RegisteredButtons' => $baseDir . '/templates/repository-registered-buttons.php',
|
||||
'OTGS\Installer\Rest\Push' => $baseDir . '/includes/rest/Push.php',
|
||||
'OTGS\Installer\Recommendations\RecommendationsManager' => $baseDir . '/src/Recommendations/RecommendationsManager.php',
|
||||
'OTGS\Installer\Recommendations\RecommendationsManagerFactory' => $baseDir . '/src/Recommendations/RecommendationsManagerFactory.php',
|
||||
'OTGS\Installer\Recommendations\Storage' => $baseDir . '/src/Recommendations/Storage.php',
|
||||
'OTGS\Installer\AdminNotices\Notices\Recommendation' => $baseDir . '/includes/admin-notices/notices/Recommendation.php',
|
||||
'OTGS\Installer\AdminNotices\Notices\Dismissions' => $baseDir . '/includes/admin-notices/notices/Dismissions.php',
|
||||
'OTGS\Installer\Loader\Config' => $baseDir . '/includes/loader/Config.php',
|
||||
'OTGS\Installer\Settings' => $baseDir . '/includes/class-otgs-installer-settings.php',
|
||||
'OTGS\Installer\CommercialTab\SectionsManager' => $baseDir . '/includes/products/commercial-tab/SectionsManager.php',
|
||||
'OTGS\Installer\CommercialTab\DownloadsList' => $baseDir . '/includes/products/commercial-tab/DownloadsList.php',
|
||||
'OTGS\Installer\CommercialTab\DownloadFilter' => $baseDir . '/includes/products/commercial-tab/DownloadFilter.php',
|
||||
'OTGS\Installer\Upgrade\AutoUpgrade' => $baseDir . '/includes/upgrade/AutoUpgrade.php',
|
||||
'OTGS\Installer\Upgrade\InstallerPlugins' => $baseDir . '/includes/upgrade/InstallerPlugins.php',
|
||||
'OTGS\Installer\FP\Obj' => $baseDir . '/includes/utilities/FP/Obj.php',
|
||||
'OTGS\Installer\FP\Str' => $baseDir . '/includes/utilities/FP/Str.php',
|
||||
'OTGS\Installer\FP\Either' => $baseDir . '/includes/utilities/FP/Either.php',
|
||||
'OTGS\Installer\FP\Fns' => $baseDir . '/includes/utilities/FP/Fns.php',
|
||||
'OTGS\Installer\FP\Invoker' => $baseDir . '/includes/utilities/FP/Invoker.php',
|
||||
'OTGS\Installer\FP\Logic' => $baseDir . '/includes/utilities/FP/Logic.php',
|
||||
'OTGS\Installer\FP\Relation' => $baseDir . '/includes/utilities/FP/Relation.php',
|
||||
'OTGS\Installer\FP\Undefined' => $baseDir . '/includes/utilities/FP/Undefined.php',
|
||||
'OTGS\Installer\FP\Traits\Applicative' => $baseDir . '/includes/utilities/FP/Traits/Applicative.php',
|
||||
'OTGS\Installer\FP\Traits\ConstApplicative' => $baseDir . '/includes/utilities/FP/Traits/ConstApplicative.php',
|
||||
'OTGS\Installer\FP\Traits\Functor' => $baseDir . '/includes/utilities/FP/Traits/Functor.php',
|
||||
'OTGS\Installer\FP\Traits\Pointed' => $baseDir . '/includes/utilities/FP/Traits/Pointed.php',
|
||||
'OTGS\Installer\Subscription_Warning_Message' => $baseDir . '/includes/class-otgs-installer-subscription-warning-message.php',
|
||||
'OTGS\Installer\Collect\Support\Macroable' => $baseDir . '/includes/utilities/Collect/Support/Macroable.php'
|
||||
];
|
||||
@@ -0,0 +1,163 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Installer_Products_Parser {
|
||||
|
||||
/**
|
||||
* @var OTGS_Installer_Logger_Storage
|
||||
*/
|
||||
private $logger;
|
||||
|
||||
/**
|
||||
* @var WP_Installer_Channels
|
||||
*/
|
||||
private $installerChannels;
|
||||
|
||||
private $product_notices = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $defaultProducts;
|
||||
|
||||
public function __construct(
|
||||
WP_Installer_Channels $installerChannels,
|
||||
OTGS_Products_Config_Xml $productsConfigXml,
|
||||
OTGS_Installer_Logger_Storage $logger
|
||||
) {
|
||||
$this->logger = $logger;
|
||||
$this->installerChannels = $installerChannels;
|
||||
$this->defaultProducts = $productsConfigXml->get_repository_products_default_data();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $products_url
|
||||
* @param string $repository_id
|
||||
* @param string $response
|
||||
*
|
||||
* @return array
|
||||
* @throws OTGS_Installer_Products_Parsing_Exception
|
||||
*/
|
||||
public function get_products_from_response( $products_url, $repository_id, $response ) {
|
||||
$products = $this->parse_products_response( $products_url, $response );
|
||||
$products = $this->validate_products_plugins( $products_url, $products );
|
||||
$products['downloads'] = $this->prepare_products_downloads( $repository_id, $products );
|
||||
|
||||
return $products;
|
||||
}
|
||||
|
||||
public function get_default_products( $repository_id ) {
|
||||
return isset( $this->defaultProducts[ $repository_id ] ) ? $this->defaultProducts[ $repository_id ] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $products_url
|
||||
* @param string $response
|
||||
*
|
||||
* @return array
|
||||
* @throws OTGS_Installer_Products_Parsing_Exception
|
||||
*/
|
||||
private function parse_products_response( $products_url, $response ) {
|
||||
$body = wp_remote_retrieve_body( $response );
|
||||
if ( $body ) {
|
||||
$json = json_decode( $body, true );
|
||||
|
||||
if ( $json ) {
|
||||
return $json;
|
||||
}
|
||||
}
|
||||
|
||||
throw OTGS_Installer_Products_Parsing_Exception::createForResponse( $products_url );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $products_url
|
||||
* @param array $products
|
||||
*
|
||||
* @throws OTGS_Installer_Products_Parsing_Exception
|
||||
*/
|
||||
private function validate_products_plugins( $products_url, $products ) {
|
||||
if ( is_array( $products ) ) {
|
||||
foreach ( $products['downloads']['plugins'] as $product_id => $product ) {
|
||||
if ( empty( $product['slug'] )
|
||||
|| empty( $product['name'] )
|
||||
|| empty( $product['version'] )
|
||||
|| empty( $product['date'] )
|
||||
|| empty( $product['url'] )
|
||||
|| empty( $product['basename'] )
|
||||
) {
|
||||
$this->handle_product_parsing_error( $products_url, $product_id );
|
||||
throw OTGS_Installer_Products_Parsing_Exception::createForResponse( $products_url );
|
||||
}
|
||||
}
|
||||
}
|
||||
return $products;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $products_url
|
||||
* @param string $product_id
|
||||
*/
|
||||
private function handle_product_parsing_error( $products_url, $product_id ) {
|
||||
$error = sprintf( __( 'Information about versions of %s are invalid. It may be a temporary communication problem, please check for updates again.', 'installer' ), $product_id );
|
||||
$this->store_log( $products_url, $error );
|
||||
$this->product_notices[] = $error;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
* @param string $response
|
||||
*/
|
||||
private function store_log( $url, $response ) {
|
||||
$log = new OTGS_Installer_Log();
|
||||
$log->set_request_url( $url )
|
||||
->set_component( OTGS_Installer_Logger_Storage::COMPONENT_PRODUCTS_PARSING )
|
||||
->set_response( $response );
|
||||
|
||||
$this->logger->add( $log );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $repository_id
|
||||
* @param array $products
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function prepare_products_downloads( $repository_id, $products ) {
|
||||
$downloads = $this->installerChannels->filter_downloads_by_channel( $repository_id, $products['downloads'] );
|
||||
$downloads = $this->add_release_notes( $downloads );
|
||||
|
||||
return $downloads;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $products_downloads
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function add_release_notes( $products_downloads ) {
|
||||
foreach ( $products_downloads as $kind => $downloads ) {
|
||||
foreach ( $downloads as $slug => $download ) {
|
||||
$start = strpos( $download['changelog'], '<h4>' . $download['version'] . '</h4>' );
|
||||
if ( $start !== false ) {
|
||||
$start += strlen( $download['version'] ) + 9;
|
||||
$end = strpos( $download['changelog'], '<h4>', 4 );
|
||||
if ( $end ) {
|
||||
$release_notes = substr( $download['changelog'], $start, $end - $start );
|
||||
} else {
|
||||
$release_notes = substr( $download['changelog'], $start );
|
||||
}
|
||||
}
|
||||
$products_downloads[ $kind ][ $slug ]['release-notes'] = ! empty( $release_notes ) ? $release_notes : '';
|
||||
}
|
||||
}
|
||||
|
||||
return $products_downloads;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function get_product_notices() {
|
||||
return $this->product_notices;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Products_Config_Db_Storage {
|
||||
const PRODUCTS_CONFIG_KEY = 'otgs_installer_products_urls';
|
||||
|
||||
/**
|
||||
* @param string $repository_id
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function get_repository_products_url( $repository_id ) {
|
||||
$products = get_option( self::PRODUCTS_CONFIG_KEY, [] );
|
||||
return isset( $products[ $repository_id ] ) ? $products[$repository_id] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $repository_id
|
||||
* @param string $repository_products_url
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function store_repository_products_url( $repository_id, $repository_products_url ) {
|
||||
$products_config = get_option( self::PRODUCTS_CONFIG_KEY, [] );
|
||||
$products_config[ $repository_id ] = $repository_products_url;
|
||||
|
||||
return update_option( self::PRODUCTS_CONFIG_KEY, $products_config, 'yes');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $repository_id
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function clear_repository_products_url( $repository_id ) {
|
||||
$products_config = get_option( self::PRODUCTS_CONFIG_KEY, [] );
|
||||
unset( $products_config[ $repository_id ] );
|
||||
|
||||
return update_option( self::PRODUCTS_CONFIG_KEY, $products_config, 'yes');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Products_Config_Xml {
|
||||
|
||||
/**
|
||||
* @var SimpleXMLElement
|
||||
*/
|
||||
private $repositories_config;
|
||||
|
||||
/**
|
||||
* @param string $xml_file
|
||||
*/
|
||||
public function __construct( $xml_file ) {
|
||||
$this->repositories_config = $this->load_configuration( $xml_file );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $xml_file
|
||||
*
|
||||
* @return SimpleXMLElement|null
|
||||
*/
|
||||
private function load_configuration( $xml_file ) {
|
||||
if( ! file_exists( $xml_file )) {
|
||||
return null;
|
||||
}
|
||||
return simplexml_load_file( $xml_file );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $repository_id
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function get_repository_products_url( $repository_id ) {
|
||||
foreach ( $this->repositories_config as $repository_config ) {
|
||||
if ( isset( $repository_config->id ) && strval( $repository_config->id ) == $repository_id ) {
|
||||
return isset( $repository_config->products) ? strval( $repository_config->products ) : null;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function get_repository_products_default_data() {
|
||||
$productDefaults = [];
|
||||
foreach ( $this->repositories_config as $repository_config ) {
|
||||
$productDefaults[ strval( $repository_config->id ) ] = isset( $repository_config->default_products )
|
||||
? json_decode( strval( $repository_config->default_products ), true ) : null;
|
||||
}
|
||||
|
||||
return $productDefaults;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function get_products_api_urls() {
|
||||
$urls = [];
|
||||
|
||||
foreach ( $this->repositories_config as $repository_config ) {
|
||||
if ( isset( $repository_config->apiurl ) ) {
|
||||
$urls[strval( $repository_config->id )] = strval( $repository_config->apiurl );
|
||||
}
|
||||
}
|
||||
|
||||
return $urls;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Products_Manager {
|
||||
|
||||
/**
|
||||
* @var OTGS_Products_Bucket_Repository
|
||||
*/
|
||||
private $products_bucket_repository;
|
||||
|
||||
/**
|
||||
* @var OTGS_Products_Config_Db_Storage
|
||||
*/
|
||||
private $products_config_storage;
|
||||
|
||||
/**
|
||||
* @var OTGS_Products_Config_Xml
|
||||
*/
|
||||
private $products_config_xml;
|
||||
|
||||
/**
|
||||
* @var WP_Installer_Channels
|
||||
*/
|
||||
private $installer_channels;
|
||||
|
||||
/**
|
||||
* @var OTGS_Installer_Logger_Storage
|
||||
*/
|
||||
private $logger_storage;
|
||||
|
||||
/**
|
||||
* @param OTGS_Products_Config_Db_Storage $products_config_storage
|
||||
* @param OTGS_Products_Bucket_Repository $products_bucket_repository
|
||||
* @param OTGS_Products_Config_Xml $products_config_xml
|
||||
* @param WP_Installer_Channels $installer_channels
|
||||
* @param OTGS_Installer_Logger_Storage $logger_storage
|
||||
*/
|
||||
public function __construct(
|
||||
OTGS_Products_Config_Db_Storage $products_config_storage,
|
||||
OTGS_Products_Bucket_Repository $products_bucket_repository,
|
||||
OTGS_Products_Config_Xml $products_config_xml,
|
||||
WP_Installer_Channels $installer_channels,
|
||||
OTGS_Installer_Logger_Storage $logger_storage
|
||||
) {
|
||||
$this->products_config_storage = $products_config_storage;
|
||||
$this->products_bucket_repository = $products_bucket_repository;
|
||||
$this->products_config_xml = $products_config_xml;
|
||||
$this->installer_channels = $installer_channels;
|
||||
$this->logger_storage = $logger_storage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $repository_id
|
||||
* @param string $site_key
|
||||
* @param string $site_url
|
||||
* @param bool $bypass_buckets
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function get_products_url( $repository_id, $site_key, $site_url, $bypass_buckets ) {
|
||||
$repo_id_upper = strtoupper( $repository_id );
|
||||
if ( defined( "OTGS_INSTALLER_{$repo_id_upper}_PRODUCTS" ) ) {
|
||||
return constant( "OTGS_INSTALLER_{$repo_id_upper}_PRODUCTS" );
|
||||
}
|
||||
|
||||
if ( ! $bypass_buckets && $this->is_on_production_channel( $repository_id ) ) {
|
||||
$products_url = $this->get_products_url_from_local_config( $repository_id, $site_key );
|
||||
if ( $products_url ) {
|
||||
return $products_url;
|
||||
}
|
||||
|
||||
if ( $site_key ) {
|
||||
$products_url = $this->get_products_url_from_otgs( $repository_id, $site_key, $site_url );
|
||||
if ( $products_url ) {
|
||||
return $products_url;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $this->products_config_xml->get_repository_products_url( $repository_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $repository_id
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function is_on_production_channel( $repository_id ) {
|
||||
return $this->installer_channels->get_channel( $repository_id ) === WP_Installer_Channels::CHANNEL_PRODUCTION;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $repository_id
|
||||
* @param string $site_key
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
private function get_products_url_from_local_config( $repository_id, $site_key ) {
|
||||
$products_url = $this->products_config_storage->get_repository_products_url( $repository_id );
|
||||
|
||||
if ( $products_url && !$site_key ) {
|
||||
$this->products_config_storage->clear_repository_products_url( $repository_id );
|
||||
return null;
|
||||
}
|
||||
|
||||
return $products_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $repository_id
|
||||
* @param string $site_key
|
||||
* @param string $site_url
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function get_products_url_from_otgs( $repository_id, $site_key, $site_url ) {
|
||||
$products_url = null;
|
||||
try {
|
||||
$products_url = $this->products_bucket_repository->get_products_bucket_url( $repository_id, $site_key, $site_url );
|
||||
if ($products_url) {
|
||||
$this->products_config_storage->store_repository_products_url( $repository_id, $products_url);
|
||||
}
|
||||
} catch (Exception $exception) {
|
||||
$this->logger_storage->add( $this->prepare_log( $repository_id, $exception->getMessage() ) );
|
||||
}
|
||||
|
||||
return $products_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $repository_id
|
||||
* @param string $message
|
||||
*
|
||||
* @return OTGS_Installer_Log
|
||||
*/
|
||||
private function prepare_log( $repository_id, $message ) {
|
||||
$message = sprintf(
|
||||
"Installer cannot contact our updates server to get information about the available products of %s and check for new versions. Error message: %s",
|
||||
$repository_id,
|
||||
$message
|
||||
);
|
||||
|
||||
$log = new OTGS_Installer_Log();
|
||||
$log->set_component(OTGS_Installer_Logger_Storage::COMPONENT_PRODUCTS_URL);
|
||||
$log->set_response( $message );
|
||||
|
||||
return $log;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Products_Manager_Factory {
|
||||
|
||||
/**
|
||||
* @param OTGS_Products_Config_Xml $repositories_config
|
||||
* @param OTGS_Installer_Logger_Storage $logger_storage
|
||||
*
|
||||
* @return OTGS_Products_Manager
|
||||
*/
|
||||
public static function create( OTGS_Products_Config_Xml $repositories_config, OTGS_Installer_Logger_Storage $logger_storage ) {
|
||||
return new OTGS_Products_Manager(
|
||||
new OTGS_Products_Config_Db_Storage(),
|
||||
OTGS_Products_Bucket_Repository_Factory::create( $repositories_config->get_products_api_urls() ),
|
||||
$repositories_config,
|
||||
WP_Installer_Channels(),
|
||||
$logger_storage
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace OTGS\Installer\CommercialTab;
|
||||
|
||||
class DownloadFilter {
|
||||
public static function shouldDisplayRecord( $productSlug ) {
|
||||
return $productSlug !== 'wpml-translation-management'
|
||||
|| defined( 'ICL_SITEPRESS_VERSION' )
|
||||
&& version_compare( ICL_SITEPRESS_VERSION, '4.5', '<' );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
namespace OTGS\Installer\CommercialTab;
|
||||
|
||||
class DownloadsList {
|
||||
public static function getDownloadRow( $download_id, $download, $site_key, $repository_id ) {
|
||||
$url = OTGS_Installer()->append_site_key_to_download_url( $download['url'], $site_key, $repository_id );
|
||||
|
||||
$download_data = base64_encode( json_encode( [
|
||||
'url' => $url,
|
||||
'slug' => $download['slug'],
|
||||
'nonce' => wp_create_nonce( 'install_plugin_' . $url ),
|
||||
'repository_id' => $repository_id
|
||||
] ) );
|
||||
|
||||
$disabled = ( OTGS_Installer()->plugin_is_installed( $download['name'], $download['slug'], $download['version'] )
|
||||
&& ! OTGS_Installer()->plugin_is_embedded_version( $download['name'], $download['slug'] )
|
||||
|| OTGS_Installer()->dependencies->cant_download( $repository_id ) ) ? 'disabled="disabled"' : '';
|
||||
|
||||
$upToDateClass = '';
|
||||
if ( $v = OTGS_Installer()->plugin_is_installed( $download['name'], $download['slug'] ) ) {
|
||||
|
||||
$class = version_compare( $v, $download['version'], '>=' ) ? 'installer-green-text' : 'installer-red-text';
|
||||
$class .= version_compare( $v, $download['version'], '>' ) ? ' unstable' : '';
|
||||
|
||||
$upToDateClass = '<span class="' . $class . '">' . $v . '</span>';
|
||||
|
||||
if ( OTGS_Installer()->plugin_is_embedded_version( $download['name'], $download['slug'] ) ) {
|
||||
$upToDateClass .= ' ' . __( '(embedded)', 'installer' );
|
||||
}
|
||||
|
||||
if (
|
||||
\WP_Installer_Channels()->get_channel( $repository_id ) !== \WP_Installer_Channels::CHANNEL_PRODUCTION &&
|
||||
$non_stable = \WP_Installer_Channels()->get_download_source_channel( $v, $repository_id, $download_id, 'plugins' )
|
||||
) {
|
||||
$upToDateClass .= '(' . $non_stable . ')';
|
||||
}
|
||||
}
|
||||
|
||||
$releaseNotes = '';
|
||||
$installerReleaseNotes = '';
|
||||
if ( ! empty( $download['release-notes'] ) ) {
|
||||
$releaseNotes = '<a class="js-release-notes handle" href="#">' . esc_html__( 'Release notes', 'installer' ) . '</a>';
|
||||
|
||||
$installerReleaseNotes = '<tr class="installer-release-notes">
|
||||
<td colspan="9">
|
||||
<div class="arrow_box">
|
||||
<div>' . force_balance_tags( $download['release-notes'] ) . '</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>';
|
||||
}
|
||||
|
||||
return '<tr>
|
||||
<td class="installer_checkbox">
|
||||
<label>
|
||||
<input type="checkbox" name="downloads[]" value="' . $download_data . '" data-slug="' . $download['slug'] . '" ' . $disabled . ' />
|
||||
</label>
|
||||
</td>
|
||||
<td class="installer_plugin_name">' . $download['name'] . '</td>
|
||||
<td class="installer_version_installed">' . $upToDateClass . '</td>
|
||||
<td class="installer_version">' . $download['version'] . '</td>
|
||||
<td class="installer_release_date">' . date_i18n( 'F j, Y', strtotime( $download['date'] ) ) . '</td>
|
||||
<td>' . $releaseNotes . '</td>
|
||||
<td>
|
||||
<span class="installer-status-installing">' . __( 'installing...', 'installer' ) . '</span>
|
||||
<span class="installer-status-updating">' . __( 'updating...', 'installer' ) . '</span>
|
||||
<span class="installer-status-installed" data-fail="' . __( 'failed!', 'installer' ) . '">' . __( 'installed', 'installer' ) . '</span>
|
||||
<span class="installer-status-updated" data-fail="' . __( 'failed!', 'installer' ) . '">' . __( 'updated', 'installer' ) . '</span>
|
||||
</td>
|
||||
<td>
|
||||
<span class="installer-status-activating">' . __( 'activating', 'installer' ) . '</span>
|
||||
<span class="installer-status-activated">' . __( 'activated', 'installer' ) . '</span>
|
||||
</td>
|
||||
<td class="for_spinner_js"><span class="spinner"></span></td>
|
||||
</tr>' .
|
||||
$installerReleaseNotes;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
<?php
|
||||
|
||||
namespace OTGS\Installer\CommercialTab;
|
||||
|
||||
class SectionsManager {
|
||||
|
||||
const SECTION_GENERAL = 'general';
|
||||
const SECTION_LEGACY = 'legacy';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $settings;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $installedPlugins;
|
||||
|
||||
/**
|
||||
* @param array $settings
|
||||
*/
|
||||
public function __construct( $settings ) {
|
||||
$this->settings = $settings;
|
||||
$this->installedPlugins = $this->getInstalledPlugins();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $repositoryId
|
||||
* @param array $downloads
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getPluginsSections( $repositoryId, $downloads ) {
|
||||
return $this->addDownloadsToSections(
|
||||
$this->getSections( $repositoryId ),
|
||||
$downloads
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $repositoryId
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getSections( $repositoryId ) {
|
||||
$language = $this->getCurrentLanguage();
|
||||
$sections = [];
|
||||
|
||||
if ( ! empty( $this->settings[ $repositoryId ]['data']['commecial_tab_sections'] ) ) {
|
||||
foreach (
|
||||
$this->settings[ $repositoryId ]['data']['commecial_tab_sections'] as $sectionName => $sectionData
|
||||
) {
|
||||
$sections[ $sectionName ]['name'] = isset( $sectionData[ $language ] )
|
||||
? $sectionData[ $language ]['name'] : $sectionData['en']['name'];
|
||||
$sections[ $sectionName ]['order'] = isset( $sectionData[ $language ] )
|
||||
? $sectionData[ $language ]['order'] : $sectionData['en']['order'];
|
||||
$sections[ $sectionName ]['downloads'] = [];
|
||||
}
|
||||
}
|
||||
|
||||
uasort( $sections, function ( $a, $b ) {
|
||||
return (int) $a['order'] - (int) $b['order'];
|
||||
} );
|
||||
|
||||
return $sections;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $sections
|
||||
* @param array $downloads
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function addDownloadsToSections( $sections, $downloads ) {
|
||||
foreach ( $downloads as $downloadSlug => $download ) {
|
||||
if ( empty( $download['download_commercial_tab_section'] ) ) {
|
||||
$download['download_commercial_tab_section'] = self::SECTION_GENERAL;
|
||||
}
|
||||
if ( $this->shouldDisplayOnCommercialTab( $download ) ) {
|
||||
$sections[ $download['download_commercial_tab_section'] ]['downloads'][ $downloadSlug ]
|
||||
= $download;
|
||||
}
|
||||
}
|
||||
|
||||
return $sections;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $download
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function shouldDisplayOnCommercialTab( $download ) {
|
||||
if ( $download['download_commercial_tab_section'] === self::SECTION_LEGACY ) {
|
||||
return $this->isPluginInstalled( $download['slug'] );
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $slug
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function isPluginInstalled( $slug ) {
|
||||
return isset( $this->installedPlugins[ $slug ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function getInstalledPlugins() {
|
||||
$installed_plugins = [];
|
||||
|
||||
foreach ( get_plugins() as $plugin_id => $plugin_data ) {
|
||||
$installed_plugins[ dirname( $plugin_id ) ] = true;
|
||||
}
|
||||
|
||||
return $installed_plugins;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private function getCurrentLanguage() {
|
||||
global $sitepress;
|
||||
|
||||
return $sitepress ? $sitepress->get_admin_language() : 'en';
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Products_Bucket_Repository {
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $api_urls;
|
||||
|
||||
/**
|
||||
* @param array $api_urls
|
||||
*/
|
||||
public function __construct( $api_urls ) {
|
||||
$this->api_urls = $api_urls;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $repository_id
|
||||
* @param string $site_key
|
||||
* @param string $site_url
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function get_products_bucket_url( $repository_id, $site_key, $site_url ) {
|
||||
$args['body'] = [
|
||||
'action' => 'product_bucket_url',
|
||||
'site_key' => $site_key,
|
||||
'site_url' => $site_url
|
||||
];
|
||||
|
||||
$response = wp_remote_post( $this->api_urls[ $repository_id ], $args );
|
||||
|
||||
$response_data = $this->get_response_data( $response );
|
||||
if ( isset( $response_data->success ) && $response_data->success === true ) {
|
||||
return $response_data->bucket->url;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|WP_Error $response
|
||||
*
|
||||
* @return object|null
|
||||
*/
|
||||
private function get_response_data( $response ) {
|
||||
if (
|
||||
$response &&
|
||||
! is_wp_error( $response ) &&
|
||||
isset( $response['response']['code'] ) &&
|
||||
$response['response']['code'] == 200
|
||||
) {
|
||||
$body = wp_remote_retrieve_body( $response );
|
||||
if ( $body ) {
|
||||
return json_decode( $body );
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Products_Bucket_Repository_Factory {
|
||||
|
||||
/**
|
||||
* @return OTGS_Products_Bucket_Repository
|
||||
*/
|
||||
public static function create( $api_urls ) {
|
||||
return new OTGS_Products_Bucket_Repository(
|
||||
$api_urls
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Installer_Repositories_Factory {
|
||||
public function create( WP_Installer $installer ) {
|
||||
return new OTGS_Installer_Repositories(
|
||||
$installer,
|
||||
new OTGS_Installer_Repository_Factory(),
|
||||
new OTGS_Installer_Subscription_Factory()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Installer_Repositories {
|
||||
|
||||
private $installer;
|
||||
private $repositories;
|
||||
private $repository_factory;
|
||||
private $subscription_factory;
|
||||
|
||||
public function __construct(
|
||||
WP_Installer $installer,
|
||||
OTGS_Installer_Repository_Factory $repository_factory,
|
||||
OTGS_Installer_Subscription_Factory $subscription_factory
|
||||
) {
|
||||
$this->repository_factory = $repository_factory;
|
||||
$this->subscription_factory = $subscription_factory;
|
||||
$this->installer = $installer;
|
||||
$settings = $this->installer->get_settings();
|
||||
$this->repositories = $this->get_repositories( $settings['repositories'] );
|
||||
}
|
||||
|
||||
public function get_all() {
|
||||
return $this->repositories;
|
||||
}
|
||||
|
||||
private function get_repositories( $setting_repositories ) {
|
||||
$repositories = array();
|
||||
|
||||
foreach ( $setting_repositories as $id => $repository ) {
|
||||
$subscription = isset( $repository['subscription']['data'] )
|
||||
? $this->subscription_factory->create( $repository['subscription'] )
|
||||
: null;
|
||||
|
||||
$setting_repositories = $this->installer->get_repositories();
|
||||
|
||||
$api_url = isset($setting_repositories[ $id ]['api-url']) ? $setting_repositories[ $id ]['api-url'] : null;
|
||||
$packages = $this->get_packages( $repository );
|
||||
$repositories[] = $this->repository_factory->create_repository( array(
|
||||
'id' => $id,
|
||||
'subscription' => $subscription,
|
||||
'packages' => $packages,
|
||||
'product_name' => $repository['data']['product-name'],
|
||||
'api_url' => $api_url
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return $repositories;
|
||||
}
|
||||
|
||||
private function get_packages( $repository ) {
|
||||
$packages = array();
|
||||
|
||||
foreach ( $repository['data']['packages'] as $package_key => $package ) {
|
||||
$products = $this->get_products( $package );
|
||||
|
||||
$packages[] = $this->repository_factory->create_package( array(
|
||||
'key' => $package_key,
|
||||
'id' => $package['id'],
|
||||
'name' => $package['name'],
|
||||
'description' => $package['description'],
|
||||
'image_url' => $package['image_url'],
|
||||
'order' => $package['order'],
|
||||
'parent' => $package['parent'],
|
||||
'products' => $products,
|
||||
) );
|
||||
}
|
||||
|
||||
return $packages;
|
||||
}
|
||||
|
||||
private function get_products( $package ) {
|
||||
$products = [];
|
||||
|
||||
foreach ( $package['products'] as $product_key => $product ) {
|
||||
$products[] = $this->repository_factory->create_product( [
|
||||
'id' => $product_key,
|
||||
'name' => $product['name'],
|
||||
'description' => $product['description'],
|
||||
'price' => $product['price'],
|
||||
'subscription_type' => $product['subscription_type'],
|
||||
'subscription_type_text' => $product['subscription_type_text'],
|
||||
'subscription_info' => $product['subscription_info'],
|
||||
'subscription_type_equivalent' => $product['subscription_type_equivalent'],
|
||||
'url' => $product['url'],
|
||||
'renewals' => $product['renewals'],
|
||||
'upgrades' => $product['upgrades'],
|
||||
'plugins' => $product['plugins'],
|
||||
'downloads' => $product['downloads'],
|
||||
] );
|
||||
}
|
||||
|
||||
return $products;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $id
|
||||
*
|
||||
* @return null|OTGS_Installer_Repository
|
||||
*/
|
||||
public function get( $id ) {
|
||||
foreach ( $this->repositories as $repository ) {
|
||||
if ( $id === $repository->get_id() ) {
|
||||
return $repository;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function refresh( $bypass_bucket = false ) {
|
||||
return $this->installer->refresh_repositories_data( $bypass_bucket );
|
||||
}
|
||||
|
||||
public function save_subscription( OTGS_Installer_Repository $repository ) {
|
||||
$subscription = $repository->get_subscription();
|
||||
unset( $this->installer->settings['repositories'][ $repository->get_id() ]['subscription'] );
|
||||
|
||||
if ( $subscription ) {
|
||||
$this->installer->settings['repositories'][ $repository->get_id() ]['subscription'] = array(
|
||||
'key' => $subscription->get_site_key(),
|
||||
'key_type' => $subscription->get_site_key_type(),
|
||||
'data' => $subscription->get_data(),
|
||||
'registered_by' => $subscription->get_registered_by(),
|
||||
'site_url' => $subscription->get_site_url(),
|
||||
);
|
||||
}
|
||||
$actualSiteUrl = $this->installer->get_installer_site_url( $repository->get_id() );
|
||||
$this->installer->settings['repositories'][ $repository->get_id() ]['site_key_url'] = $actualSiteUrl;
|
||||
|
||||
$this->installer->save_settings();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Installer_Repository_Factory {
|
||||
|
||||
public function create_repository( $params ) {
|
||||
return new OTGS_Installer_Repository( $params );
|
||||
}
|
||||
|
||||
public function create_package( $params ) {
|
||||
return new OTGS_Installer_Package( $params );
|
||||
}
|
||||
|
||||
public function create_product( $params ) {
|
||||
return new OTGS_Installer_Package_Product( $params );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Installer_Repository {
|
||||
|
||||
private $id;
|
||||
private $subscription;
|
||||
private $packages;
|
||||
private $product_name;
|
||||
private $api_url;
|
||||
|
||||
public function __construct( array $params = array() ) {
|
||||
foreach ( get_object_vars( $this ) as $property => $value ) {
|
||||
if ( array_key_exists( $property, $params ) ) {
|
||||
$this->$property = $params[ $property ];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_id() {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_product_name() {
|
||||
return $this->product_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $ssl
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_api_url( $ssl = true ) {
|
||||
$api_url = $this->api_url;
|
||||
|
||||
if ( ! $ssl ) {
|
||||
$api_url = wp_parse_url( $api_url );
|
||||
$api_url['scheme'] = 'http';
|
||||
$api_url = http_build_url( $api_url );
|
||||
}
|
||||
|
||||
return $api_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return OTGS_Installer_Subscription
|
||||
*/
|
||||
public function get_subscription() {
|
||||
return $this->subscription;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function get_packages() {
|
||||
return $this->packages;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|OTGS_Installer_Package_Product
|
||||
*/
|
||||
public function get_product_by_subscription_type() {
|
||||
return $this->get_product_by( 'get_product_by_subscription_type' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|OTGS_Installer_Package_Product
|
||||
*/
|
||||
public function get_product_by_subscription_type_equivalent() {
|
||||
return $this->get_product_by( 'get_product_by_subscription_type_equivalent' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|OTGS_Installer_Package_Product
|
||||
*/
|
||||
public function get_product_by_subscription_type_on_upgrades() {
|
||||
return $this->get_product_by( 'get_product_by_subscription_type_on_upgrades' );
|
||||
}
|
||||
|
||||
public function set_subscription( OTGS_Installer_Subscription $subscription = null ) {
|
||||
$this->subscription = $subscription;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $function_name
|
||||
*
|
||||
* @return null|OTGS_Installer_Package_Product
|
||||
*/
|
||||
private function get_product_by( $function_name ) {
|
||||
$subscription_type = $this->subscription->get_type();
|
||||
foreach ( $this->packages as $package ) {
|
||||
$product = $package->$function_name( $subscription_type );
|
||||
if ( $product ) {
|
||||
return $product;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
43
wp-content/plugins/sitepress-multilingual-cms/vendor/otgs/installer/includes/rest/Push.php
vendored
Normal file
43
wp-content/plugins/sitepress-multilingual-cms/vendor/otgs/installer/includes/rest/Push.php
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace OTGS\Installer\Rest;
|
||||
|
||||
use \WP_REST_Response;
|
||||
|
||||
class Push {
|
||||
|
||||
const REFRESH_INTERVAL = 7200; //2 hours
|
||||
|
||||
const REST_NAMESPACE = 'otgs/installer/v1';
|
||||
|
||||
public static function register_routes() {
|
||||
register_rest_route(
|
||||
self::REST_NAMESPACE,
|
||||
'push/fetch-subscription',
|
||||
[
|
||||
'methods' => 'GET',
|
||||
'callback' => self::class . '::fetch_subscription',
|
||||
'permission_callback' => '__return_true',
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
public static function fetch_subscription() {
|
||||
$installer = OTGS_Installer();
|
||||
$last_refresh = $installer->get_last_subscriptions_refresh();
|
||||
|
||||
if ( defined( 'OTGS_INSTALLER_OVERRIDE_SUB_LAST_REFRESH' ) ) {
|
||||
$last_refresh = constant( 'OTGS_INSTALLER_OVERRIDE_SUB_LAST_REFRESH' );
|
||||
}
|
||||
|
||||
if ( time() - $last_refresh > self::REFRESH_INTERVAL ) {
|
||||
$installer->refresh_subscriptions_data();
|
||||
|
||||
do_action( 'otgs_installer_subscription_refreshed' );
|
||||
|
||||
return new WP_REST_Response( [ 'message' => 'OK' ], 200 );
|
||||
}
|
||||
|
||||
return new WP_REST_Response( [ 'message' => 'OK' ], 403 );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,209 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Installer_Fetch_Subscription {
|
||||
|
||||
private $package_source_factory;
|
||||
private $plugin_finder;
|
||||
private $repositories;
|
||||
private $logger;
|
||||
private $log_factory;
|
||||
|
||||
public function __construct(
|
||||
OTGS_Installer_Source_Factory $package_source_factory,
|
||||
OTGS_Installer_Plugin_Finder $plugin_finder,
|
||||
OTGS_Installer_Repositories $repositories,
|
||||
OTGS_Installer_Logger $logger,
|
||||
OTGS_Installer_Log_Factory $log_factory
|
||||
) {
|
||||
$this->package_source_factory = $package_source_factory;
|
||||
$this->plugin_finder = $plugin_finder;
|
||||
$this->repositories = $repositories;
|
||||
$this->logger = $logger;
|
||||
$this->log_factory = $log_factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $repository_id
|
||||
* @param string $site_key
|
||||
* @param string $source
|
||||
*
|
||||
* @return array
|
||||
* @throws OTGS_Installer_Fetch_Subscription_Exception
|
||||
*/
|
||||
public function get( $repository_id, $site_key, $source ) {
|
||||
if ( ! $repository_id || ! $site_key || ! $source ) {
|
||||
throw new OTGS_Installer_Fetch_Subscription_Exception( 'Repository, site key and source are required fields.' );
|
||||
}
|
||||
|
||||
$subscription_data = false;
|
||||
$site_key_data = false;
|
||||
|
||||
$args['body'] = array(
|
||||
'action' => 'site_key_validation',
|
||||
'site_key' => $site_key,
|
||||
'site_url' => $this->get_installer_site_url( $repository_id ),
|
||||
'source' => $source
|
||||
);
|
||||
|
||||
if ( $repository_id === 'wpml' ) {
|
||||
$args['body']['using_icl'] = function_exists( 'wpml_site_uses_icl' ) && wpml_site_uses_icl();
|
||||
$args['body']['wpml_version'] = defined( 'ICL_SITEPRESS_VERSION' ) ? ICL_SITEPRESS_VERSION : '';
|
||||
}
|
||||
|
||||
$args['body']['installer_version'] = WP_INSTALLER_VERSION;
|
||||
$args['body']['theme'] = wp_get_theme()->get( 'Name' );
|
||||
$args['body']['site_name'] = get_bloginfo( 'name' );
|
||||
$args['body']['repository_id'] = $repository_id;
|
||||
$args['body']['versions'] = $this->get_local_product_versions();
|
||||
$args['timeout'] = 45;
|
||||
|
||||
$package_source = $this->package_source_factory->create()->get();
|
||||
|
||||
// Add extra parameters for custom Installer packages
|
||||
if ( $package_source ) {
|
||||
$extra = $this->get_extra_url_parameters( $package_source );
|
||||
if ( ! empty( $extra['repository'] ) && $extra['repository'] == $repository_id ) {
|
||||
unset( $extra['repository'] );
|
||||
foreach ( $extra as $key => $val ) {
|
||||
$args['body'][ $key ] = $val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$repository = $this->repositories->get( $repository_id );
|
||||
|
||||
$valid_response = null;
|
||||
$valid_body = null;
|
||||
$api_url = null;
|
||||
|
||||
foreach ( array( $repository->get_api_url(), $repository->get_api_url( false ) ) as $api_url ) {
|
||||
$valid_response = false;
|
||||
$valid_body = false;
|
||||
|
||||
$response = wp_remote_post(
|
||||
$api_url,
|
||||
apply_filters( 'installer_fetch_subscription_data_request', $args )
|
||||
);
|
||||
|
||||
if ( is_wp_error( $response ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$valid_response = true;
|
||||
|
||||
$body = trim( wp_remote_retrieve_body( $response ) );
|
||||
|
||||
if ( ! $body || ! is_serialized( $body ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$valid_body = true;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
$this->logger->add_api_log( "POST {$api_url}" );
|
||||
$this->logger->add_api_log( $args );
|
||||
|
||||
$this->logger->add_log( "POST {$api_url} - fetch subscription data" );
|
||||
|
||||
if ( $valid_response ) {
|
||||
if ( $valid_body ) {
|
||||
$data = unserialize( $body );
|
||||
$this->logger->add_api_log( $data );
|
||||
|
||||
if ( isset( $data->subscription_data ) && $data->subscription_data ) {
|
||||
$subscription_data = $data->subscription_data;
|
||||
} else {
|
||||
$this->store_log( $args, $api_url, isset( $data->error ) ? $data->error : '' );
|
||||
}
|
||||
|
||||
if ( isset( $data->site_key ) && $data->site_key ) {
|
||||
$site_key_data = $data->site_key;
|
||||
}
|
||||
|
||||
do_action( 'installer_fetched_subscription_data', $data, $repository_id );
|
||||
} else {
|
||||
if ( is_wp_error( $response ) ) {
|
||||
$response_message = $response->get_error_message();
|
||||
} else {
|
||||
$response_message = wp_remote_retrieve_response_message( $response );
|
||||
}
|
||||
$this->store_log( $args, $api_url, $response_message );
|
||||
$this->logger->add_api_log( $body );
|
||||
}
|
||||
|
||||
} else {
|
||||
$this->store_log( $args, $api_url, $response->get_error_message() );
|
||||
$this->logger->add_api_log( $response );
|
||||
throw new OTGS_Installer_Fetch_Subscription_Exception( $response->get_error_message() );
|
||||
}
|
||||
|
||||
return [$subscription_data, $site_key_data];
|
||||
}
|
||||
|
||||
private function store_log( $args, $request_url, $response ) {
|
||||
$log = $this->log_factory->create();
|
||||
$log->set_request_args( $args )
|
||||
->set_request_url( $request_url )
|
||||
->set_response( $response )
|
||||
->set_component( OTGS_Installer_Logger_Storage::COMPONENT_SUBSCRIPTION );
|
||||
|
||||
$this->logger->save_log( $log );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function get_local_product_versions() {
|
||||
$installed_plugins = $this->plugin_finder->get_otgs_installed_plugins();
|
||||
$versions = array();
|
||||
|
||||
foreach ( $installed_plugins as $plugin ) {
|
||||
$versions[ $plugin->get_slug() ] = $plugin->get_installed_version();
|
||||
}
|
||||
|
||||
return $versions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $source
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_extra_url_parameters( $source ) {
|
||||
if ( $source ) {
|
||||
$parameters = $source;
|
||||
}
|
||||
|
||||
$parameters['installer_version'] = WP_INSTALLER_VERSION;
|
||||
$parameters['theme'] = wp_get_theme()->get( 'Name' );
|
||||
$parameters['site_name'] = get_bloginfo( 'name' );
|
||||
|
||||
return $parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $repository_id
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_installer_site_url( $repository_id = false ) {
|
||||
global $current_site;
|
||||
|
||||
$site_url = get_site_url();
|
||||
|
||||
if ( $repository_id && is_multisite() && $this->repositories->get_all() ) {
|
||||
$network_settings = maybe_unserialize( get_site_option( 'wp_installer_network' ) );
|
||||
|
||||
if ( isset( $network_settings[ $repository_id ] ) ) {
|
||||
$site_url = get_site_url( $current_site->blog_id );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$filtered_site_url = filter_var( apply_filters( 'otgs_installer_site_url', $site_url ), FILTER_SANITIZE_URL );
|
||||
|
||||
return $filtered_site_url ? $filtered_site_url : $site_url;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,189 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Installer_Site_Key_Ajax {
|
||||
|
||||
private $subscription_fetch;
|
||||
private $logger;
|
||||
private $repositories;
|
||||
private $subscription_factory;
|
||||
|
||||
public function __construct(
|
||||
OTGS_Installer_Fetch_Subscription $subscription_fetch,
|
||||
OTGS_Installer_Logger $logger,
|
||||
OTGS_Installer_Repositories $repositories,
|
||||
OTGS_Installer_Subscription_Factory $subscription_factory
|
||||
) {
|
||||
$this->subscription_fetch = $subscription_fetch;
|
||||
$this->logger = $logger;
|
||||
$this->repositories = $repositories;
|
||||
$this->subscription_factory = $subscription_factory;
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
add_action( 'wp_ajax_save_site_key', array( $this, 'save' ) );
|
||||
add_action( 'wp_ajax_remove_site_key', array( $this, 'remove' ) );
|
||||
add_action( 'wp_ajax_update_site_key', array( $this, 'update' ) );
|
||||
add_action( 'wp_ajax_find_account', [ $this, 'find' ] );
|
||||
}
|
||||
|
||||
public function save() {
|
||||
$repository = isset( $_POST['repository_id'] ) && $_POST['repository_id'] ? sanitize_text_field( $_POST['repository_id'] ) : null;
|
||||
$nonce = isset( $_POST['nonce'] ) && $_POST['nonce'] ? sanitize_text_field( $_POST['nonce'] ) : null;
|
||||
$site_key = isset( $_POST[ 'site_key_' . $repository ] ) && $_POST[ 'site_key_' . $repository ] ? sanitize_text_field( $_POST[ 'site_key_' . $repository ] ) : null;
|
||||
$site_key = preg_replace( '/[^A-Za-z0-9]/', '', $site_key );
|
||||
$error = '';
|
||||
|
||||
if ( ! $site_key ) {
|
||||
wp_send_json_success( [ 'error' => esc_html__( 'Empty site key!', 'installer' ) ] );
|
||||
return;
|
||||
}
|
||||
if ( ! $repository || ! $nonce || ! wp_verify_nonce( $nonce, 'save_site_key_' . $repository ) ) {
|
||||
wp_send_json_success( [ 'error' => esc_html__( 'Invalid request!', 'installer' ) ] );
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
list ($subscription, $site_key_data) = $this->subscription_fetch->get( $repository, $site_key, WP_Installer::SITE_KEY_VALIDATION_SOURCE_REGISTRATION );
|
||||
if ( $subscription ) {
|
||||
$subscription_data = $this->subscription_factory->create( array(
|
||||
'data' => $subscription,
|
||||
'key' => $site_key,
|
||||
'key_type' => isset($site_key_data['type'])
|
||||
? (int) $site_key_data['type'] : OTGS_Installer_Subscription::SITE_KEY_TYPE_PRODUCTION,
|
||||
'site_url' => get_site_url(),
|
||||
'registered_by' => get_current_user_id()
|
||||
) );
|
||||
|
||||
$repository = $this->repositories->get( $repository );
|
||||
$repository->set_subscription( $subscription_data );
|
||||
$this->repositories->save_subscription( $repository );
|
||||
$this->repositories->refresh();
|
||||
$this->clean_plugins_update_cache();
|
||||
do_action( 'otgs_installer_site_key_update', $repository->get_id() );
|
||||
} else {
|
||||
$error = __( 'Invalid site key for the current site.', 'installer' ) . '<br /><div class="installer-footnote">' . __( 'Please note that the site key is case sensitive.', 'installer' ) . '</div>';
|
||||
}
|
||||
} catch ( Exception $e ) {
|
||||
$repository_data = $this->repositories->get( $repository );
|
||||
$error = $this->get_error_message( $e, $repository_data );
|
||||
}
|
||||
|
||||
$response = array( 'error' => $error );
|
||||
|
||||
if ( $this->logger->get_api_log() ) {
|
||||
$response['debug'] = $this->logger->get_api_log();
|
||||
}
|
||||
|
||||
wp_send_json_success( $response );
|
||||
}
|
||||
|
||||
public function remove() {
|
||||
$repository = isset( $_POST['repository_id'] ) ? sanitize_text_field( $_POST['repository_id'] ) : null;
|
||||
$nonce = isset( $_POST['nonce'] ) ? sanitize_text_field( $_POST['nonce'] ) : null;
|
||||
$nonce_action = 'remove_site_key_' . $repository;
|
||||
|
||||
if ( wp_verify_nonce( $nonce, $nonce_action ) ) {
|
||||
$repository = $this->repositories->get( $repository );
|
||||
$repository->set_subscription( null );
|
||||
$this->repositories->save_subscription( $repository );
|
||||
|
||||
$this->clean_plugins_update_cache();
|
||||
do_action( 'otgs_installer_site_key_update', $repository->get_id() );
|
||||
}
|
||||
|
||||
$this->repositories->refresh();
|
||||
wp_send_json_success();
|
||||
}
|
||||
|
||||
public function update() {
|
||||
$error = '';
|
||||
$nonce = isset( $_POST['nonce'] ) ? $_POST['nonce'] : null;
|
||||
$repository = isset( $_POST['repository_id'] ) ? sanitize_text_field( $_POST['repository_id'] ) : null;
|
||||
|
||||
if ( $nonce && $repository && wp_verify_nonce( $nonce, 'update_site_key_' . $repository ) ) {
|
||||
$repository_data = $this->repositories->get( $repository );
|
||||
$site_key = $repository_data->get_subscription()->get_site_key();
|
||||
|
||||
if ( $site_key ) {
|
||||
try {
|
||||
list ($subscription, $site_key_data) = $this->subscription_fetch->get( $repository, $site_key, WP_Installer::SITE_KEY_VALIDATION_SOURCE_REGISTRATION );
|
||||
|
||||
if ( $subscription ) {
|
||||
$subscription_data = $this->subscription_factory->create( array(
|
||||
'data' => $subscription,
|
||||
'key' => $site_key,
|
||||
'key_type' => isset($site_key_data['type'])
|
||||
? (int) $site_key_data['type'] : OTGS_Installer_Subscription::SITE_KEY_TYPE_PRODUCTION,
|
||||
'site_url' => get_site_url(),
|
||||
'registered_by' => get_current_user_id(),
|
||||
) );
|
||||
$repository_data->set_subscription( $subscription_data );
|
||||
} else {
|
||||
$repository_data->set_subscription( null );
|
||||
$error = __( 'Invalid site key for the current site. If the error persists, try to un-register first and then register again with the same site key.', 'installer' );
|
||||
}
|
||||
|
||||
$this->repositories->save_subscription( $repository_data );
|
||||
$messages = $this->repositories->refresh( true );
|
||||
|
||||
if ( is_array( $messages ) ) {
|
||||
$error .= implode( '', $messages );
|
||||
}
|
||||
|
||||
|
||||
$this->clean_plugins_update_cache();
|
||||
} catch ( Exception $e ) {
|
||||
$error = $this->get_error_message( $e, $repository_data );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
wp_send_json_success( array( 'error' => $error ) );
|
||||
}
|
||||
|
||||
public function find() {
|
||||
$repository = isset( $_POST['repository_id'] ) ? sanitize_text_field( $_POST['repository_id'] ) : null;
|
||||
$nonce = isset( $_POST['nonce'] ) ? $_POST['nonce'] : null;
|
||||
$email = isset( $_POST['email'] ) ? sanitize_text_field( $_POST['email'] ) : null;
|
||||
$success = false;
|
||||
|
||||
if ( $nonce && $repository && $email && wp_verify_nonce( $nonce, 'find_account_' . $repository ) ) {
|
||||
$repository_data = $this->repositories->get( $repository );
|
||||
$siteKey = $repository_data->get_subscription()->get_site_key();
|
||||
|
||||
$args['body'] = [
|
||||
'action' => 'user_email_exists',
|
||||
'umail' => MD5( $email . $siteKey ),
|
||||
'site_key' => $siteKey,
|
||||
'site_url' => get_site_url()
|
||||
];
|
||||
|
||||
$response = wp_remote_post( $repository_data->get_api_url(), $args );
|
||||
if ( $response ) {
|
||||
$body = json_decode( wp_remote_retrieve_body( $response ) );
|
||||
$success = isset( $body->success ) ? 'Success' === $body->success : false;
|
||||
}
|
||||
}
|
||||
|
||||
wp_send_json_success( [ 'found' => $success ] );
|
||||
|
||||
}
|
||||
|
||||
|
||||
private function get_error_message( Exception $e, OTGS_Installer_Repository $repository_data ) {
|
||||
$error = $e->getMessage();
|
||||
if ( preg_match( '#Could not resolve host: (.*)#', $error, $matches ) || preg_match( '#Couldn\'t resolve host \'(.*)\'#', $error, $matches ) ) {
|
||||
$error = sprintf( __( "%s cannot access %s to register. Try again to see if it's a temporary problem. If the problem continues, make sure that this site has access to the Internet. You can still use the plugin without registration, but you will not receive automated updates.", 'installer' ),
|
||||
'<strong><i>' . $repository_data->get_product_name() . '</i></strong>',
|
||||
'<strong><i>' . $matches[1] . '</i></strong>'
|
||||
);
|
||||
}
|
||||
|
||||
return $error;
|
||||
}
|
||||
|
||||
private function clean_plugins_update_cache() {
|
||||
do_action( 'otgs_installer_clean_plugins_update_cache' );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Installer_Connection_Test_Ajax {
|
||||
|
||||
const ACTION = 'otgs_installer_test_connection';
|
||||
|
||||
private $connection_test;
|
||||
|
||||
public function __construct( OTGS_Installer_Connection_Test $connection_test ) {
|
||||
$this->connection_test = $connection_test;
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
add_action( 'wp_ajax_' . self::ACTION, array( $this, 'test_connection' ) );
|
||||
}
|
||||
|
||||
public function test_connection() {
|
||||
if ( $this->is_valid_request() ) {
|
||||
$type = filter_var( $_POST['type'], FILTER_SANITIZE_FULL_SPECIAL_CHARS );
|
||||
$repository = filter_var( $_POST['repository'], FILTER_SANITIZE_FULL_SPECIAL_CHARS );
|
||||
$method = 'get_' . $type . '_status';
|
||||
|
||||
if ( $this->connection_test->{$method}( $repository ) ) {
|
||||
wp_send_json_success();
|
||||
}
|
||||
}
|
||||
|
||||
wp_send_json_error();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function is_valid_request() {
|
||||
return isset( $_POST['nonce'], $_POST['type'] ) && wp_verify_nonce( $_POST['nonce'], self::ACTION );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Installer_Connection_Test_Exception extends Exception {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Installer_Connection_Test {
|
||||
|
||||
private $repositories;
|
||||
private $upgrade_response;
|
||||
private $logger_storage;
|
||||
private $log_factory;
|
||||
|
||||
public function __construct(
|
||||
OTGS_Installer_Repositories $repositories,
|
||||
OTGS_Installer_Upgrade_Response $upgrade_response,
|
||||
OTGS_Installer_Logger_Storage $logger_storage,
|
||||
OTGS_Installer_Log_Factory $log_factory
|
||||
) {
|
||||
$this->repositories = $repositories;
|
||||
$this->upgrade_response = $upgrade_response;
|
||||
$this->logger_storage = $logger_storage;
|
||||
$this->log_factory = $log_factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $repo_id
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function get_api_status( $repo_id ) {
|
||||
return $this->get_url_status( $this->repositories->get( $repo_id )->get_api_url() );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $plugin_id
|
||||
*
|
||||
* @return bool|string
|
||||
*/
|
||||
public function get_download_status( $plugin_id ) {
|
||||
$plugins_updates = get_site_transient( 'update_plugins' );
|
||||
$update_response = $this->upgrade_response->modify_upgrade_response( $plugins_updates );
|
||||
$response = false;
|
||||
$error_message = '';
|
||||
|
||||
if ( isset( $update_response->response[ $plugin_id ] ) ) {
|
||||
$request_response = wp_remote_head( $update_response->response[ $plugin_id ]->package );
|
||||
$parsed_download_url = wp_parse_url( $update_response->response[ $plugin_id ]->package );
|
||||
parse_str( $parsed_download_url['query'], $download_args );
|
||||
|
||||
if ( is_wp_error( $request_response ) ) {
|
||||
$error_message = $request_response->get_error_message();
|
||||
} elseif ( ! $this->is_response_successful( $request_response ) ) {
|
||||
$error_message = 'Invalid response';
|
||||
}
|
||||
|
||||
if ( $error_message ) {
|
||||
$this->log(
|
||||
sprintf(
|
||||
'%s: an error occurred while trying to get information of this download URL. Error: %s, download: %s, version: %s.',
|
||||
$plugin_id,
|
||||
$error_message,
|
||||
$download_args['download'],
|
||||
$download_args['version']
|
||||
),
|
||||
$update_response->response[ $plugin_id ]->package
|
||||
);
|
||||
} else {
|
||||
$response = true;
|
||||
}
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $response
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function is_response_successful( $response ) {
|
||||
return in_array( $response['response']['code'], $this->get_success_codes(), true );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function get_url_status( $url ) {
|
||||
$response = false;
|
||||
$res = wp_remote_get( $url );
|
||||
$error_message = '';
|
||||
|
||||
if ( is_wp_error( $res ) ) {
|
||||
$error_message = sprintf( "Your site can't communicate with %s. Code %d: %s.", $url, $res->get_error_code(), $res->get_error_message() );
|
||||
} elseif ( ! $this->is_response_successful( $res ) ) {
|
||||
$error_message = sprintf( "Your site can't communicate with %s. Code %d.", $url, $res['response']['code'] );
|
||||
}
|
||||
|
||||
if ( $error_message ) {
|
||||
$this->log(
|
||||
$error_message,
|
||||
$url
|
||||
);
|
||||
} else {
|
||||
$response = true;
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
private function log( $msg, $url ) {
|
||||
$this->logger_storage->add(
|
||||
$this->log_factory
|
||||
->create()
|
||||
->set_request_url( $url )
|
||||
->set_component( OTGS_Installer_Logger_Storage::PRODUCTS_FILE_CONNECTION_TEST )
|
||||
->set_response( $msg )
|
||||
);
|
||||
}
|
||||
|
||||
private function get_success_codes() {
|
||||
return array( 302, 200 );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Installer_Requirements {
|
||||
|
||||
private $requirements;
|
||||
|
||||
public function get() {
|
||||
if ( ! $this->requirements ) {
|
||||
$this->requirements = $this->get_requirements();
|
||||
}
|
||||
|
||||
return $this->requirements;
|
||||
}
|
||||
|
||||
private function get_requirements() {
|
||||
return array(
|
||||
array(
|
||||
'name' => 'cURL',
|
||||
'active' => function_exists( 'curl_version' ),
|
||||
),
|
||||
array(
|
||||
'name' => 'simpleXML',
|
||||
'active' => extension_loaded( 'simplexml' ),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Installer_Support_Hooks {
|
||||
|
||||
private $template_factory;
|
||||
|
||||
public function __construct( OTGS_Installer_Support_Template_Factory $template_factory ) {
|
||||
$this->template_factory = $template_factory;
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
add_action( 'admin_menu', array( $this, 'add_support_page' ) );
|
||||
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
|
||||
add_action( 'otgs_render_installer_support_link', array( $this, 'render_link' ) );
|
||||
}
|
||||
|
||||
public function add_support_page() {
|
||||
add_submenu_page(
|
||||
'commercial',
|
||||
__( 'Installer Support', 'installer' ),
|
||||
'Installer Support',
|
||||
'manage_options',
|
||||
'otgs-installer-support',
|
||||
array( $this, 'render_support_page' )
|
||||
);
|
||||
}
|
||||
|
||||
public function render_support_page() {
|
||||
$this->template_factory->create()->show();
|
||||
}
|
||||
|
||||
public function enqueue_scripts( $hook ) {
|
||||
if ( 'admin_page_otgs-installer-support' === $hook ) {
|
||||
wp_enqueue_style( 'otgs-installer-support-style', WP_Installer()->plugin_url() . '/dist/css/otgs-installer-support/styles.css', array(), WP_Installer()->version() );
|
||||
wp_enqueue_script( 'otgs-installer-support-script', WP_Installer()->plugin_url() . '/dist/js/otgs-installer-support/app.js', array(), WP_Installer()->version() );
|
||||
}
|
||||
}
|
||||
|
||||
public function render_link( $args = array() ) {
|
||||
$this->template_factory->create()->render_support_link( $args );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Installer_Support_Template_Factory {
|
||||
|
||||
private $installer_path;
|
||||
|
||||
public function __construct( $installer_path ) {
|
||||
$this->installer_path = $installer_path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return OTGS_Installer_Support_Template
|
||||
*/
|
||||
public function create() {
|
||||
$template_service = OTGS_Template_Service_Factory::create(
|
||||
$this->installer_path . '/templates/php/support/'
|
||||
);
|
||||
$instances_factory = new OTGS_Installer_Instances_Factory();
|
||||
|
||||
return new OTGS_Installer_Support_Template(
|
||||
$template_service,
|
||||
new OTGS_Installer_Logger_Storage( new OTGS_Installer_Log_Factory() ),
|
||||
new OTGS_Installer_Requirements(),
|
||||
$instances_factory->create()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Installer_Support_Template {
|
||||
|
||||
const TEMPLATE_FILE = 'installer-support';
|
||||
const SUPPORT_LINK = 'support-link';
|
||||
|
||||
private $template_service;
|
||||
private $logger_storage;
|
||||
private $requirements;
|
||||
|
||||
/**
|
||||
* @var OTGS_Installer_Instance[]
|
||||
*/
|
||||
private $instances;
|
||||
|
||||
public function __construct(
|
||||
OTGS_Template_Service $template_service,
|
||||
OTGS_Installer_Logger_Storage $logger_storage,
|
||||
OTGS_Installer_Requirements $requirements,
|
||||
OTGS_Installer_Instances $instances
|
||||
) {
|
||||
$this->template_service = $template_service;
|
||||
$this->logger_storage = $logger_storage;
|
||||
$this->requirements = $requirements;
|
||||
$this->instances = $instances;
|
||||
}
|
||||
|
||||
public function show() {
|
||||
echo $this->template_service->show( $this->get_model(), self::TEMPLATE_FILE );
|
||||
}
|
||||
|
||||
public function render_support_link( $args = array() ) {
|
||||
echo $this->template_service->show( $this->get_support_link_model( $args ), self::SUPPORT_LINK );
|
||||
}
|
||||
|
||||
private function get_support_link_model( $args = array() ) {
|
||||
return array(
|
||||
'title' => __( 'Installer Support', 'installer' ),
|
||||
'content' => __( 'For retrieving Installer debug information use the %s page.', 'installer' ),
|
||||
'link' => array(
|
||||
'url' => admin_url( 'admin.php?page=otgs-installer-support' ),
|
||||
'text' => __( 'Installer Support', 'installer' ),
|
||||
),
|
||||
'hide_title' => isset( $args['hide_title'] ) && $args['hide_title'],
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function get_model() {
|
||||
$model = array(
|
||||
'log_entries' => $this->get_log_entries(),
|
||||
'strings' => array(
|
||||
'page_title' => __( 'Installer Support', 'installer' ),
|
||||
'log' => array(
|
||||
'title' => __( 'Installer Log', 'installer' ),
|
||||
'request_url' => __( 'Request URL', 'installer' ),
|
||||
'request_arguments' => __( 'Request Arguments', 'installer' ),
|
||||
'response' => __( 'Response', 'installer' ),
|
||||
'component' => __( 'Component', 'installer' ),
|
||||
'time' => __( 'Time', 'installer' ),
|
||||
'empty_log' => __( 'Log is empty', 'installer' ),
|
||||
),
|
||||
'tester' => array(
|
||||
'title' => __( 'Installer System Status', 'installer' ),
|
||||
'button_label' => __( 'Check Now', 'installer' ),
|
||||
),
|
||||
'requirements' => array(
|
||||
'title' => __( 'Required PHP Libraries', 'installer' ),
|
||||
),
|
||||
'instances' => array(
|
||||
'title' => __( 'All Installer Instances', 'installer' ),
|
||||
'path' => __( 'Path', 'installer' ),
|
||||
'version' => __( 'Version', 'installer' ),
|
||||
'high_priority' => __( 'High priority', 'installer' ),
|
||||
'delegated' => __( 'Delegated', 'installer' ),
|
||||
),
|
||||
),
|
||||
'tester' => array(
|
||||
'endpoints' => array(
|
||||
array(
|
||||
'repository' => 'wpml',
|
||||
'type' => 'api',
|
||||
'description' => __( 'WPML API server', 'installer' )
|
||||
),
|
||||
array(
|
||||
'repository' => 'toolset',
|
||||
'type' => 'api',
|
||||
'description' => __( 'Toolset API server', 'installer' )
|
||||
),
|
||||
),
|
||||
'nonce' => wp_nonce_field( OTGS_Installer_Connection_Test_Ajax::ACTION, OTGS_Installer_Connection_Test_Ajax::ACTION, false ),
|
||||
),
|
||||
'requirements' => $this->requirements->get(),
|
||||
'instances' => $this->instances->get(),
|
||||
);
|
||||
|
||||
return $model;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function get_log_entries() {
|
||||
$log_entries = array();
|
||||
|
||||
foreach ( $this->logger_storage->get() as $log ) {
|
||||
$log_entries[] = array(
|
||||
'request_url' => $log->get_request_url(),
|
||||
'request_arguments' => $log->get_request_args(),
|
||||
'response' => $log->get_response(),
|
||||
'component' => $log->get_component(),
|
||||
'time' => $log->get_time(),
|
||||
);
|
||||
}
|
||||
|
||||
return $log_entries;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Php_Template_Service_Loader implements OTGS_Template_Service_Loader {
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $template_dir;
|
||||
|
||||
/**
|
||||
* @param string $template_dir
|
||||
*/
|
||||
public function __construct( $template_dir ) {
|
||||
$this->template_dir = $template_dir;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return OTGS_Php_Template_Service
|
||||
*/
|
||||
public function get_service() {
|
||||
return new OTGS_Php_Template_Service( $this->template_dir );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Php_Template_Service implements OTGS_Template_Service {
|
||||
|
||||
const FILE_EXTENSION = '.php';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $template_dir;
|
||||
|
||||
/**
|
||||
* @param string $template_dir
|
||||
*/
|
||||
public function __construct( $template_dir ) {
|
||||
$this->template_dir = $template_dir;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $model_params
|
||||
* @param string $template
|
||||
*/
|
||||
public function show( $model_params, $template ) {
|
||||
$model = new OTGS_Template_Service_Php_Model( $model_params );
|
||||
include $this->getTemplatePath($template);
|
||||
}
|
||||
|
||||
private function getTemplatePath( $template ) {
|
||||
return sprintf('%s/%s%s', $this->template_dir, $template, self::FILE_EXTENSION);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Template_Service_Factory
|
||||
{
|
||||
/**
|
||||
* @param string $template_dir
|
||||
* @return OTGS_Php_Template_Service
|
||||
*/
|
||||
public static function create( $template_dir ) {
|
||||
return (new OTGS_Php_Template_Service_Loader( $template_dir ))->get_service();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
|
||||
class OTGS_Template_Service_Php_Model {
|
||||
/**
|
||||
* @var OTGS_Template_Service_Php_Model[]|mixed[]
|
||||
*/
|
||||
private $attributes = [];
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*/
|
||||
public function __construct( $data = [] ) {
|
||||
foreach ( $data as $key => $value ) {
|
||||
$this->__set( $key, $value );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If a property does not exist, the method will create it as an "empty" instance of `Model`
|
||||
* so that children properties can be called without throwing errors.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return mixed|null
|
||||
* @see OTGS_Template_Service_Php_Model::__toString
|
||||
*/
|
||||
public function __get( $name ) {
|
||||
if ( ! array_key_exists( $name, $this->attributes ) ) {
|
||||
$this->attributes[ $name ] = new OTGS_Template_Service_Php_Model();
|
||||
}
|
||||
|
||||
return $this->attributes[ $name ];
|
||||
}
|
||||
|
||||
/**
|
||||
* It ensures that $value is always either an array or a primitive type.
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function __set( $name, $value ) {
|
||||
if ( is_object( $value ) ) {
|
||||
$value = get_object_vars( $value );
|
||||
}
|
||||
if ( is_array( $value ) ) {
|
||||
if( $this->isAssoc( $value ) ) {
|
||||
$value = new OTGS_Template_Service_Php_Model( $value );
|
||||
} else {
|
||||
foreach ($value as $id => $element) {
|
||||
$value[$id] = $this->isAssoc( $element ) ? new OTGS_Template_Service_Php_Model( $element ) : $element;
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->attributes[ $name ] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function isAssoc( $value ) {
|
||||
return is_array( $value ) && count( array_filter( array_keys( $value ), 'is_string' ) ) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasValue( $name ) {
|
||||
return ! $this->isNull( $name ) && ! $this->isEmpty( $name );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isNull( $name ) {
|
||||
return $this->__get( $name ) === null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isEmpty( $name ) {
|
||||
return $this->__get( $name ) === ''
|
||||
|| ( ( $this->__get( $name ) instanceof OTGS_Template_Service_Php_Model )
|
||||
&& ! $this->__get( $name )->getAttributes()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed[]|OTGS_Template_Service_Php_Model[]
|
||||
*/
|
||||
public function getAttributes() {
|
||||
return $this->attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* This logic allows using the model in a template even when referring to properties which do no exist.
|
||||
*
|
||||
* Example:
|
||||
* `<h1><?php echo esc_html( $model->non_existing_property->title ); ?></h1>` Will output an empty string instead of throwing an error
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString() {
|
||||
if ( count( $this->attributes ) === 0 ) {
|
||||
return '';
|
||||
}
|
||||
if ( count( $this->attributes ) === 1 ) {
|
||||
return array_values( $this->attributes )[0];
|
||||
}
|
||||
|
||||
return wp_json_encode( $this->attributes );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
interface OTGS_Template_Service_Loader {
|
||||
/**
|
||||
* @return OTGS_Template_Service
|
||||
*/
|
||||
public function get_service();
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
interface OTGS_Template_Service {
|
||||
public function show( $model, $template );
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user