* @copyright Copyright (c) 2020 Samuel Marshall / JCH Optimize * @license GNU/GPLv3, or later. See LICENSE file * * If LICENSE file missing, see . */ namespace JchOptimize\WordPress\Plugin; use _JchOptimizeVendor\V91\Joomla\DI\ContainerAwareInterface; use _JchOptimizeVendor\V91\Joomla\DI\ContainerAwareTrait; use _JchOptimizeVendor\V91\Joomla\Input\Input; use _JchOptimizeVendor\V91\Psr\Log\LoggerAwareInterface; use _JchOptimizeVendor\V91\Psr\Log\LoggerAwareTrait; use Exception; use JchOptimize\Core\Admin\Ajax\Ajax; use JchOptimize\Core\Mvc\Controller; use JchOptimize\Core\Platform\PathsInterface; use JchOptimize\Core\Registry; use JchOptimize\WordPress\Container\ContainerFactory; use JchOptimize\WordPress\Contracts\WillEnqueueAssets; use JchOptimize\WordPress\Controller\PageCache; use JchOptimize\WordPress\ControllerResolver; use JchOptimize\WordPress\Admin\Settings\ControlRenderer; use JchOptimize\WordPress\Admin\Settings\SectionCallbacks; use JchOptimize\WordPress\Admin\Settings\FieldCallbacks; use JchOptimize\WordPress\Admin\Settings\ConfigurationSchema; use JetBrains\PhpStorm\NoReturn; use function __; use function add_action; use function add_options_page; use function add_settings_field; use function add_settings_section; use function add_submenu_page; use function admin_url; use function check_admin_referer; use function current_user_can; use function delete_transient; use function esc_url_raw; use function get_transient; use function plugin_basename; use function register_setting; use function wp_add_inline_script; use function wp_create_nonce; use function wp_enqueue_script; use function wp_enqueue_style; use function wp_register_script; use function wp_register_style; use const JCH_PRO; use const JCH_VERSION; class Admin implements LoggerAwareInterface, ContainerAwareInterface { use LoggerAwareTrait; use ContainerAwareTrait; private string $hookSuffix = ''; private ?Controller $resolvedController = null; public function __construct( private Registry $params, private ControllerResolver $controllerResolver, private PathsInterface $paths, ) { } public static function publishAdminNotices(): void { try { if ($messages = get_transient('jch-optimize_notices')) { foreach ($messages as $message) { echo <<

{$message['message']}

HTML; } delete_transient('jch-optimize_notices'); } } catch (Exception $e) { } } public function addAdminMenu(): void { $menuTitle = JCH_PRO ? 'JCH Optimize Pro' : 'JCH Optimize'; $this->hookSuffix = (string)add_options_page( __('JCH Optimize Settings', 'jch-optimize'), $menuTitle, 'manage_options', 'jch_optimize', [$this, 'loadAdminPage'] ); add_action('admin_enqueue_scripts', [$this, 'loadResourceFiles']); if ($this->hookSuffix !== '') { add_action("load-{$this->hookSuffix}", [$this, 'initializeSettings']); } add_action('admin_init', [$this, 'checkMessages']); } public function addPageCacheMenu(): void { if (current_user_can('manage_options')) { return; } $this->hookSuffix = (string)add_submenu_page( 'tools.php', // parent __('JCH Optimize Page Cache', 'jch-optimize'), // page title __('Page Cache', 'jch-optimize'), // menu title 'jch_clear_page_cache', // capability 'jch_optimize_page_cache', // slug [$this, 'renderPageCacheOnly'] ); if ($this->hookSuffix !== '') { add_action("load-{$this->hookSuffix}", [$this, 'initializeSettings']); add_action("load-{$this->hookSuffix}", [ $this->getContainer()->get(PageCache::class), 'enqueueAssets' ]); } // Show a card on Tools → Available Tools add_action('tool_box', function () { if (!current_user_can('jch_clear_page_cache')) { return; } $url = menu_page_url('jch_optimize_page_cache', false); ?>

resolvedController?->execute() ?? $this->controllerResolver->resolve(); } catch (Exception $e) { $class = get_class($e); echo <<Application Error

Please submit the following error message and trace in a support request:

{$class} — {$e->getMessage()}
 {$e->getTraceAsString()} 
HTML; } } public function renderPageCacheOnly(): void { $this->getContainer()->get(PageCache::class) ->setRedirect('tools.php?page=jch_optimize_page_cache') ->setLayout('page_cache_only.php') ->execute(); } public function registerOptions(): void { //Buffer output to allow for redirection ob_start(); register_setting('jchOptimizeOptionsPage', 'jch-optimize_settings', ['type' => 'array']); } /** * @param string $hookSuffix The current admin page * * @return void */ public function loadResourceFiles(string $hookSuffix): void { if ($this->hookSuffix !== $hookSuffix) { return; } $this->enqueueGlobalAssets(); if ($this->resolvedController instanceof WillEnqueueAssets) { $this->resolvedController->enqueueAssets(); } } private function enqueueGlobalAssets(): void { wp_enqueue_style('jch-bootstrap'); wp_enqueue_style('jch-admin'); wp_enqueue_style('jch-fonts'); //wp_enqueue_style('jch-choices-base'); wp_enqueue_style('jch-dashicons-wordpress'); wp_enqueue_style('jch-dashicons'); wp_enqueue_style('jch-wordpress'); wp_enqueue_script('jch-platform-wordpress'); wp_enqueue_script('jch-bootstrap'); wp_enqueue_script('jch-admin-utility'); wp_enqueue_script('jch-collapsible-js'); } public function initializeSettings(): void { //Css files wp_register_style( 'jch-bootstrap', JCH_PLUGIN_URL . 'media/bootstrap/css/bootstrap.min.css', [], JCH_VERSION ); wp_register_style('jch-admin', JCH_PLUGIN_URL . 'media/core/css/admin.css', [], JCH_VERSION); wp_register_style('jch-fonts', 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css'); //wp_register_style('jch-choices-base', JCH_PLUGIN_URL . 'media/choices.js/styles/base.css', [], JCH_VERSION); wp_register_style('jch-wordpress', JCH_PLUGIN_URL . 'media/css/wordpress.css', ['jch-dashicons'], JCH_VERSION); wp_register_style( 'jch-dashicons-wordpress', JCH_PLUGIN_URL . 'media/css/dashicons-wordpress.css', [], JCH_VERSION ); wp_register_style( 'jch-dashicons', JCH_PLUGIN_URL . 'media/core/css/dashicons.css', ['jch-dashicons-wordpress'], JCH_VERSION ); //JavaScript files wp_register_script( 'jch-bootstrap', JCH_PLUGIN_URL . 'media/bootstrap/js/bootstrap.bundle.min.js', ['jquery'], JCH_VERSION, true ); wp_register_script( 'jch-platform-wordpress', JCH_PLUGIN_URL . 'media/js/platform-wordpress.js', ['jquery'], JCH_VERSION, true ); wp_register_script( 'jch-admin-utility', JCH_PLUGIN_URL . 'media/core/js/admin-utility.js', ['jquery'], JCH_VERSION, true ); $this->resolvedController = $this->controllerResolver->getController(); $loader_image = $this->paths->mediaUrl() . '/core/images/loader.gif'; $multiselect_nonce = wp_create_nonce('jch_optimize_multiselect'); $optimize_image_nonce = wp_create_nonce('jch_optimize_image'); $imageLoaderJs = <<> $aSettingsArray */ $aSettingsArray = ConfigurationSchema::getSettingsArray(); foreach ($aSettingsArray as $section => $aSettings) { add_settings_section('jch-optimize_' . $section . '_section', '', [ SectionCallbacks::class, $section ], 'jchOptimizeOptionsPage'); foreach ($aSettings as $setting => $args) { list($title, $description, $new, $class) = array_pad($args, 4, false); $id = 'jch-optimize_' . $setting; $title = ControlRenderer::description($title, $description, $new); $args = []; if ($class !== false) { $args['class'] = $class; } add_settings_field($id, $title, [ FieldCallbacks::class, $setting ], 'jchOptimizeOptionsPage', 'jch-optimize_' . $section . '_section', $args); } } } public function getCurrentAdminUri(): string { $uri = isset($_SERVER['REQUEST_URI']) ? esc_url_raw(wp_unslash($_SERVER['REQUEST_URI'])) : ''; $uri = preg_replace('|^.*/wp-admin/|i', '', $uri); if (!$uri) { return ''; } return $uri; } public function checkMessages(): void { if (get_transient('jch-optimize_notices')) { add_action('admin_notices', [__CLASS__, 'publishAdminNotices']); } } /** * @param string[] $actionLinks An array of plugin action links. By default, this can include 'activate', 'deactivate', and 'delete'. * With Multisite active this can also include 'network_active' and 'network_only' items. * @param string $pluginFile Path to the plugin file relative to the plugins directory * * @return array */ public function loadActionLinks(array $actionLinks, string $pluginFile): array { static $this_plugin; if (!$this_plugin) { $this_plugin = plugin_basename(JCH_PLUGIN_FILE); } if ($pluginFile == $this_plugin) { $settingsLink = '' . __( 'Settings' ) . ''; array_unshift($actionLinks, $settingsLink); } return $actionLinks; } #[NoReturn] public function doAjaxFileTree(): void { check_admin_referer('jch_optimize_filetree'); if (current_user_can('manage_options')) { echo Ajax::getInstance('FileTree')->run(); } die(); } #[NoReturn] public function doAjaxMultiSelect(): void { check_admin_referer('jch_optimize_multiselect'); $_POST = wp_unslash($_POST); $_REQUEST = wp_unslash($_REQUEST); if (current_user_can('manage_options')) { echo Ajax::getInstance('MultiSelect')->run(); } die(); } #[NoReturn] public function doAjaxOptimizeImages(): void { check_admin_referer('jch_optimize_image'); if (current_user_can('manage_options')) { Ajax::getInstance('OptimizeImage')->run(); } die(); } #[NoReturn] public function doAjaxConfigureSettings(): void { if (current_user_can('manage_options')) { $container = ContainerFactory::getInstance(); $container->get(ControllerResolver::class)->resolve(); } die(); } #[NoReturn] public function doAjaxOnClickIcon(): void { if (current_user_can('manage_options')) { $container = ContainerFactory::getInstance(); check_admin_referer($container->get(Input::class)->get('task')); $container->get(ControllerResolver::class)->resolve(); } die(); } #[NoReturn] public function doAjaxGetCacheInfo(): void { $container = ContainerFactory::getInstance(); $container->get('getcacheinfo')->execute(); die(); } #[NoReturn] public function doAjaxJchConfigureJsTableBody(): void { $container = ContainerFactory::getInstance(); $container->get('criticaljstablebody')->execute(); die(); } #[NoReturn] public function doAjaxJchConfigureJsAutoSave(): void { $container = ContainerFactory::getInstance(); $container->get('criticaljsautosave')->execute(); die(); } #[NoReturn] public function doAjaxJchCfVerify(): void { check_admin_referer('jch_optimize_verify_cf_token'); if (current_user_can('manage_options')) { $container = ContainerFactory::getInstance(); $container->get(Input::class)->def('task', 'CfVerifyToken'); $container->get(ControllerResolver::class)->resolve(); } die(); } }