<?php
namespace OTGS\Installer\Recommendations;
class RecommendationsManager {
/**
* @var \OTGS_Installer_Repositories
*/
private $repositories;
/**
* @var array
*/
private $settings;
/**
* @var array
*/
private $repositoriesForRecommendation = [ 'wpml' ];
/**
* @var Storage
*/
private $noticesStorage;
/**
* RecommendationsManager constructor.
*
* @param \OTGS_Installer_Repositories $repositories
* @param array $settings
* @param Storage $settings
*/
public function __construct( \OTGS_Installer_Repositories $repositories, $settings, Storage $noticesStorage ) {
$this->repositories = $repositories;
$this->settings = $settings;
$this->noticesStorage = $noticesStorage;
}
public function addHooks() {
add_action( 'activated_plugin', [ $this, 'activatedPluginRecommendation' ] );
add_action( 'deactivated_plugin', [ $this, 'deactivatedPluginRecommendation' ] );
add_action( 'wp_ajax_installer_recommendation_success', [ $this, 'recommendationSuccess' ] );
}
public function activatedPluginRecommendation( $plugin ) {
$activatedPluginSlug = dirname( $plugin );
$gluePluginData = $this->getActivatedPluginGlue( $activatedPluginSlug );
if ( $gluePluginData && ! $this->isGluePluginActive( $gluePluginData['glue_plugin_slug'] ) ) {
$this->noticesStorage->save( $activatedPluginSlug, $gluePluginData );
}
}
private function isGluePluginActive( $gluePluginSlug ) {
$pluginData = isset( $this->getInstalledPlugins()[ $gluePluginSlug ] ) ? $this->getInstalledPlugins()[ $gluePluginSlug ] : null;
return $pluginData && $pluginData['is_active'];
}
public function deactivatedPluginRecommendation( $plugin ) {
$deactivatedPluginSlug = dirname( $plugin );
$gluePluginData = $this->getActivatedPluginGlue( $deactivatedPluginSlug );
if ( $gluePluginData ) {
$this->noticesStorage->delete( $deactivatedPluginSlug, $gluePluginData['repository_id'] );
}
}
public function recommendationSuccess() {
if ( array_key_exists( 'nonce', $_POST )
&& array_key_exists( 'pluginData', $_POST )
&& wp_verify_nonce( $_POST['nonce'], 'recommendation_success_nonce' ) ) {
$data = json_decode( base64_decode( sanitize_text_field( $_POST['pluginData'] ) ), true );
$this->noticesStorage->delete( $data['slug'], $data['repository_id'] );
}
}
/**
* @param string $activatedPluginSlug
*
* @return array|null
*/
private function getActivatedPluginGlue( $activatedPluginSlug ) {
$language = $this->getCurrentLanguage();
foreach ( $this->repositoriesForRecommendation as $repositoryId ) {
$downloads = isset( $this->settings[ $repositoryId ]['data']['downloads']['plugins'] )
? $this->settings[ $repositoryId ]['data']['downloads']['plugins'] : [];
foreach ( $downloads as $pluginData ) {
$gluePluginSlug = isset( $pluginData['glue_check_slug'] ) ? $pluginData['glue_check_slug'] : false;
if ( $gluePluginSlug && $activatedPluginSlug === $pluginData['glue_check_slug'] ) {
$repository = $this->repositories->get( $repositoryId );
$subscription = $repository->get_subscription();
if ( ! $subscription ) {
return null;
}
$url = $this->appendSiteKeyToDownloadUrl(
$pluginData['url'],
$subscription->get_site_key(),
$subscription->get_site_url() );
$downloadData = [
'url' => $url,
'slug' => $pluginData['slug'],
'nonce' => wp_create_nonce( 'install_plugin_' . $url ),
'repository_id' => $repositoryId,
];
return [
'repository_id' => $repositoryId,
'glue_check_slug' => $pluginData['glue_check_slug'],
'glue_check_name' => $pluginData['glue_check_name'],
'glue_plugin_name' => $pluginData['name'],
'glue_plugin_slug' => $pluginData['slug'],
'recommendation_notification' => $this->getNotificationForLanguage( $pluginData, $language ),
'download_data' => $downloadData,
];
}
}
}
return null;
}
private function getNotificationForLanguage( $pluginData, $language ) {
$default = isset( $pluginData['recommendation_notification'][ 'en' ] ) ? $pluginData['recommendation_notification'][ 'en' ] : '';
return isset( $pluginData['recommendation_notification'][ $language ] )
? $pluginData['recommendation_notification'][ $language ]
: $default;
}
/**
* @return array
*/
public function getRepositoryPluginsRecommendations() {
$pluginsRecommendations = [];
$language = $this->getCurrentLanguage();
foreach ( $this->repositoriesForRecommendation as $repositoryId ) {
$repository = $this->repositories->get( $repositoryId );
if ( $this->settings[ $repositoryId ]['data']['downloads']['plugins']
&& $this->settings[ $repositoryId ]['data']['recommendation_sections'] ) {
$downloads = $this->settings[ $repositoryId ]['data']['downloads']['plugins'];
$sections = $this->settings[ $repositoryId ]['data']['recommendation_sections'];
} else {
continue;
}
$subscription = $repository->get_subscription();
if ( ! $subscription ) {
continue;
}
$available_plugins_list = $this->getAvailablePluginsForSubscription( $repository );
$installedPlugins = $this->getInstalledPlugins();
foreach ( $downloads as $pluginData ) {
if ( $pluginData['recommended']
&& in_array( $pluginData['slug'], $available_plugins_list, true )
&& $this->shouldBeDisplayed( $pluginData )
) {
$isInstalled = isset( $installedPlugins[ $pluginData['slug'] ] );
$isActive = $isInstalled && $installedPlugins[ $pluginData['slug'] ]['is_active'];
if ( ! $isInstalled || ! $isActive ) {
$recommendation = $this->preparePluginData(
$language,
$pluginData,
$subscription->get_site_key(),
$repositoryId,
$subscription->get_site_url(),
$isInstalled,
$isActive
);
if ($pluginData['download_recommendation_section']) {
$pluginsRecommendations[ $pluginData['download_recommendation_section'] ]['plugins'][ $pluginData['slug'] ] = $recommendation;
}
}
}
}
foreach ( $pluginsRecommendations as $section => $plugins_recommendation ) {
$pluginsRecommendations[$section]['title'] = $sections[$section][$language]['name'];
$pluginsRecommendations[$section]['order'] = $sections[$section][$language]['order'];
}
}
return $pluginsRecommendations;
}
private function getCurrentLanguage() {
global $sitepress;
return $sitepress ? $sitepress->get_admin_language() : 'en';
}
/**
* @param \OTGS_Installer_Repository $repository
*
* @return array
*/
private function getAvailablePluginsForSubscription( \OTGS_Installer_Repository $repository ) {
$product = $repository->get_product_by_subscription_type();
if ( ! $product ) {
$product = $repository->get_product_by_subscription_type_equivalent();
}
return $product->get_plugins();
}
/**
* @return array
*/
private function getInstalledPlugins() {
$installed_plugins = [];
foreach ( get_plugins() as $plugin_id => $plugin_data ) {
$installed_plugins[ dirname( $plugin_id ) ] = [
'is_active' => is_plugin_active( $plugin_id ),
];
}
return $installed_plugins;
}
/**
* @param string $language
* @param array $pluginData
* @param string $siteKey
* @param string $repositoryId
* @param string $siteUrl
* @param bool $isInstalled
* @param bool $isActive
*
* @return array
*/
private function preparePluginData( $language, $pluginData, $siteKey, $repositoryId, $siteUrl, $isInstalled, $isActive ) {
$url = $this->appendSiteKeyToDownloadUrl( $pluginData['url'], $siteKey, $siteUrl );
$downloadData = [
'url' => $url,
'slug' => $pluginData['slug'],
'nonce' => wp_create_nonce( 'install_plugin_' . $url ),
'repository_id' => $repositoryId,
];
return [
'name' => $pluginData['name'],
'short_description' => isset( $pluginData['short_description'][ $language ] ) ? $pluginData['short_description'][ $language ] : '',
'is_installed' => $isInstalled,
'is_active' => $isActive,
'download_data' => $downloadData,
];
}
/**
* @param array $pluginData
*
* @return bool
*/
private function shouldBeDisplayed( $pluginData ) {
$glueCheckType = isset( $pluginData['glue_check_type'] ) ? $pluginData['glue_check_type'] : null;
$glueCheckValue = isset( $pluginData['glue_check_value'] ) ? $pluginData['glue_check_value'] : null;
if ( $glueCheckType && $glueCheckValue ) {
switch ( $glueCheckType ) {
case 'class':
return class_exists( $glueCheckValue );
case 'constant':
return defined( $glueCheckValue );
case 'function':
return function_exists( $glueCheckValue );
default:
return false;
}
}
return true;
}
/**
* @param string $url
* @param string $siteKey
* @param string $siteUrl
*
* @return string
*/
private function appendSiteKeyToDownloadUrl( $url, $siteKey, $siteUrl ) {
return add_query_arg(
[
'site_key' => $siteKey,
'site_url' => $siteUrl,
],
$url
);
}
}