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';
|
||||
}
|
||||
Reference in New Issue
Block a user