353 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			353 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						|
 | 
						|
namespace Sphere\Debloat;
 | 
						|
 | 
						|
use Sphere\Debloat\Admin\Cache;
 | 
						|
use Sphere\Debloat\Admin\OptionsData;
 | 
						|
 | 
						|
/**
 | 
						|
 * Admin initialization.
 | 
						|
 * 
 | 
						|
 * @author  asadkn
 | 
						|
 * @since   1.0.0
 | 
						|
 */
 | 
						|
class Admin
 | 
						|
{
 | 
						|
	/**
 | 
						|
	 * @var Sphere\Debloat\Admin\Cache
 | 
						|
	 */
 | 
						|
	protected $cache;
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Setup hooks
 | 
						|
	 */
 | 
						|
	public function init()
 | 
						|
	{
 | 
						|
		$this->cache = new Cache;
 | 
						|
		$this->cache->init();
 | 
						|
 | 
						|
		add_action('cmb2_admin_init',  [$this, 'setup_options']);
 | 
						|
 | 
						|
		// Enqueue at a lower priority to be after CMB2.
 | 
						|
		add_action('admin_enqueue_scripts', [$this, 'register_assets'], 99);
 | 
						|
 | 
						|
		// Page to delete cache.
 | 
						|
		add_action('admin_menu', function() {
 | 
						|
			add_submenu_page(
 | 
						|
				'', 
 | 
						|
				'Delete Cache', 
 | 
						|
				'Delete Cache', 
 | 
						|
				'manage_options', 
 | 
						|
				'debloat-delete-cache', 
 | 
						|
				[$this, 'delete_cache']
 | 
						|
			);
 | 
						|
		});
 | 
						|
 | 
						|
		// Empty cache on save.
 | 
						|
		add_action('cmb2_save_options-page_fields', [$this, '_delete_cache']);
 | 
						|
 | 
						|
		/**
 | 
						|
		 * Fix: CMB2 doesn't save unchecked making default => true impossible.
 | 
						|
		 */
 | 
						|
		add_filter('cmb2_sanitize_checkbox', function($override, $value) {
 | 
						|
			return is_null($value) ? '0' : $value;
 | 
						|
		}, 20, 2);
 | 
						|
 | 
						|
		// Custom CMB2 field for manual callback
 | 
						|
		add_action('cmb2_render_manual', function($field) {
 | 
						|
 | 
						|
			// Add attributes to an empty span for cmb2-conditional
 | 
						|
			if (!empty($field->args['attributes'])) {
 | 
						|
				printf('<meta name="%s" %s />', 
 | 
						|
					$field->args('id'),
 | 
						|
					\CMB2_Utils::concat_attrs($field->args('attributes'))
 | 
						|
				);
 | 
						|
			}
 | 
						|
 | 
						|
			if (!empty($field->args['render_html']) && is_callable($field->args['render_html'])) {
 | 
						|
				call_user_func($field->args['render_html'], $field);
 | 
						|
			}
 | 
						|
 | 
						|
			if (!empty($field->args['desc'])) {
 | 
						|
				echo '<p class="cmb2-metabox-description">' . esc_html($field->args['desc']) . '</p>';
 | 
						|
			}
 | 
						|
		});
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Register admin assets
 | 
						|
	 */
 | 
						|
	public function register_assets()
 | 
						|
	{
 | 
						|
		// Specific assets for option pages only
 | 
						|
		if (!empty($_GET['page']) && strpos($_GET['page'], 'debloat_options') !== false) {
 | 
						|
 | 
						|
			wp_enqueue_script(
 | 
						|
				'debloat-cmb2-conditionals', 
 | 
						|
				Plugin::get_instance()->dir_url . 'js/admin/cmb2-conditionals.js', 
 | 
						|
				['jquery'],
 | 
						|
				Plugin::VERSION
 | 
						|
			);
 | 
						|
 | 
						|
			wp_enqueue_script(
 | 
						|
				'debloat-options', 
 | 
						|
				Plugin::get_instance()->dir_url . 'js/admin/options.js', 
 | 
						|
				['jquery', 'debloat-cmb2-conditionals'],
 | 
						|
				Plugin::VERSION
 | 
						|
			);
 | 
						|
 | 
						|
			wp_enqueue_style(
 | 
						|
				'debloat-admin-cmb2',
 | 
						|
				Plugin::get_instance()->dir_url . 'css/admin/cmb2.css',
 | 
						|
				['cmb2-styles'],
 | 
						|
				Plugin::VERSION
 | 
						|
			);
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Delete Cache page.
 | 
						|
	 */
 | 
						|
	public function delete_cache()
 | 
						|
	{
 | 
						|
		check_admin_referer('debloat_delete_cache');
 | 
						|
		$this->_delete_cache();
 | 
						|
 | 
						|
		echo '
 | 
						|
			<h2>Clearing Cache</h2>
 | 
						|
			<p>Caches cleared. You may also have to clear your cache plugins.</p>
 | 
						|
			<a href="' . esc_url(admin_url('admin.php?page=debloat_options')) . '">Back to Options</a>';
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Callback: Delete the cache.
 | 
						|
	 *
 | 
						|
	 * @access private
 | 
						|
	 */
 | 
						|
	public function _delete_cache()
 | 
						|
	{
 | 
						|
		$this->cache->empty();
 | 
						|
 | 
						|
		/**
 | 
						|
		 * Hook after deleting cache.
 | 
						|
		 */
 | 
						|
		do_action('debloat/after_delete_cache');
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Setup admin options with CMB2
 | 
						|
	 */
 | 
						|
	public function setup_options()
 | 
						|
	{
 | 
						|
		// Configure admin options
 | 
						|
		$options = new_cmb2_box([
 | 
						|
			'id'           => 'debloat_options',
 | 
						|
			'title'        => esc_html__('Debloat Plugin Settings', 'debloat'),
 | 
						|
			'object_types' => ['options-page'],
 | 
						|
			'option_key'   => 'debloat_options',
 | 
						|
			'parent_slug'  => 'options-general.php',
 | 
						|
			'menu_title'   => esc_html__('Debloat: Optimize', 'debloat'),
 | 
						|
			'tab_group'    => 'debloat_options',
 | 
						|
			'tab_title'    => esc_html__('Optimize CSS', 'debloat'),
 | 
						|
			'classes'      => 'sphere-cmb2-wrap',
 | 
						|
			'display_cb'   => [$this, 'render_options_page'],
 | 
						|
		]);
 | 
						|
 | 
						|
		$this->add_options(
 | 
						|
			OptionsData::get_css(),
 | 
						|
			$options
 | 
						|
		);
 | 
						|
 | 
						|
		// Configure admin options
 | 
						|
		$js_options = new_cmb2_box([
 | 
						|
			'id'           => 'debloat_options_js',
 | 
						|
			'title'        => esc_html__('Optimize JS', 'debloat'),
 | 
						|
			'object_types' => ['options-page'],
 | 
						|
			'option_key'   => 'debloat_options_js',
 | 
						|
			'parent_slug'  => 'debloat_options',
 | 
						|
			'menu_title'   => esc_html__('Optimize JS', 'debloat'),
 | 
						|
			'tab_group'    => 'debloat_options',
 | 
						|
			'tab_title'    => esc_html__('Optimize JS', 'debloat'),
 | 
						|
			'classes'      => 'sphere-cmb2-wrap',
 | 
						|
			'display_cb'   => [$this, 'render_options_page'],
 | 
						|
		]);
 | 
						|
 | 
						|
		$this->add_options(
 | 
						|
			OptionsData::get_js(),
 | 
						|
			$js_options
 | 
						|
		);
 | 
						|
 | 
						|
		// Configure admin options
 | 
						|
		$general_options = new_cmb2_box([
 | 
						|
			'id'           => 'debloat_options_general',
 | 
						|
			'title'        => esc_html__('General Settings', 'debloat'),
 | 
						|
			'object_types' => ['options-page'],
 | 
						|
			'option_key'   => 'debloat_options_general',
 | 
						|
			'parent_slug'  => 'debloat_options',
 | 
						|
			'menu_title'   => esc_html__('General Settings', 'debloat'),
 | 
						|
			'tab_group'    => 'debloat_options',
 | 
						|
			'tab_title'    => esc_html__('General Settings', 'debloat'),
 | 
						|
			'display_cb'   => [$this, 'render_options_page'],
 | 
						|
			'classes'      => 'sphere-cmb2-wrap'
 | 
						|
		]);
 | 
						|
 | 
						|
		$this->add_options(
 | 
						|
			OptionsData::get_general(),
 | 
						|
			$general_options
 | 
						|
		);
 | 
						|
 | 
						|
		do_action('debloat/admin/after_options', $options);
 | 
						|
 | 
						|
	}
 | 
						|
	
 | 
						|
	/**
 | 
						|
	 * Add options to CMB2 array.
 | 
						|
	 *
 | 
						|
	 * @param array $options
 | 
						|
	 * @param \CMB2 $object
 | 
						|
	 * @return void
 | 
						|
	 */
 | 
						|
	protected function add_options($options, $object)
 | 
						|
	{
 | 
						|
		return array_map(
 | 
						|
			function($option) use ($object) {
 | 
						|
				if (isset($option['attributes']['data-conditional-id'])) {
 | 
						|
					$condition = &$option['attributes']['data-conditional-id'];
 | 
						|
					if (is_array($condition)) {
 | 
						|
						$condition = json_encode($condition);
 | 
						|
					}
 | 
						|
				}
 | 
						|
 | 
						|
				$field_id = $object->add_field($option);
 | 
						|
				
 | 
						|
                if ($option['type'] === 'group') {
 | 
						|
                    $this->add_option_group($option, $field_id, $object);
 | 
						|
                }
 | 
						|
 | 
						|
			}, 
 | 
						|
			$options
 | 
						|
		);
 | 
						|
	}
 | 
						|
 | 
						|
	protected function add_option_group($option, $group_id, $object)
 | 
						|
	{
 | 
						|
		if ($option['id'] === 'allow_conditionals_data') {
 | 
						|
			$object->add_group_field($group_id, [
 | 
						|
				'id'      => 'type',
 | 
						|
				'name'    => esc_html__('Condition Type', 'debloat'),
 | 
						|
				'type'    => 'radio',
 | 
						|
				'default' => 'class',
 | 
						|
				'options' => [
 | 
						|
					'class'  => esc_html__('Class - If a class (in "condition match") exists in HTML, keep classes matching "selector match".', 'debloat'),
 | 
						|
					'prefix' => esc_html__('Prefix - Condition matches the first class and keeps all the used child classes. Example: .s-dark will keep .s-dark .site-header.', 'debloat'),
 | 
						|
				],
 | 
						|
			]);
 | 
						|
 | 
						|
			$object->add_group_field($group_id, [
 | 
						|
				'id'      => 'match',
 | 
						|
				'name'    => esc_html__('Condition Match', 'debloat'),
 | 
						|
				'desc'    => esc_html__('Required. Usually a single class, example:', 'debloat') . '<code>.my-class</code>',
 | 
						|
				'type'    => 'text',
 | 
						|
				'default' => '',
 | 
						|
			]);
 | 
						|
 | 
						|
			$object->add_group_field($group_id, [
 | 
						|
				'id'      => 'search',
 | 
						|
				'name'    => esc_html__('Selectors Match', 'debloat'),
 | 
						|
				'desc'    => esc_html__('Enter one per line. See example matchings in "Always Keep Selectors" above.', 'debloat'),
 | 
						|
				'type'    => 'textarea_small',
 | 
						|
				'default' => '',
 | 
						|
				'attributes' => [
 | 
						|
					'data-conditional-id' => json_encode([$group_id, 'type']),
 | 
						|
					'data-conditional-value' => 'class'
 | 
						|
				]
 | 
						|
			]);
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	public function render_options_page($hookup)
 | 
						|
	{
 | 
						|
		?>
 | 
						|
		<div class="cmb2-options-page debloat-options option-<?php echo esc_attr( sanitize_html_class( $hookup->option_key ) ); ?>">
 | 
						|
			<div class="wrap">
 | 
						|
				<?php if ( $hookup->cmb->prop( 'title' ) ) : ?>
 | 
						|
					<h2><?php echo wp_kses_post( $hookup->cmb->prop( 'title' ) ); ?></h2>
 | 
						|
				<?php endif; ?>
 | 
						|
			</div>
 | 
						|
			
 | 
						|
			<div class="wrap"><?php $hookup->options_page_tab_nav_output(); ?></div>
 | 
						|
 | 
						|
			<div class="debloat-inner-wrap">
 | 
						|
				<form class="cmb-form debloat-options-form" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" method="POST" id="<?php echo esc_attr($hookup->cmb->cmb_id); ?>" enctype="multipart/form-data" encoding="multipart/form-data">
 | 
						|
					<input type="hidden" name="action" value="<?php echo esc_attr( $hookup->option_key ); ?>">
 | 
						|
 | 
						|
					<div class="sphere-cmb2-wrap debloat-intro-info">
 | 
						|
						<div class="cmb2-wrap cmb2-metabox">
 | 
						|
						<div class="cmb-row">
 | 
						|
							<h3>Important: Debloat Plugin</h3>
 | 
						|
							<p>
 | 
						|
								This plugin is for advanced users. The features "Remove Unused CSS" and "Delay JS" are especially for advanced users only.
 | 
						|
							</p>
 | 
						|
							<ol>
 | 
						|
								<li>Use a cache plugin like W3 Total Cache, WP Super Cache, etc. <strong>Required</strong> for Remove Unused CSS feature.</li>
 | 
						|
								<li>Do <strong>NOT</strong> enable minification, CSS, or JS optimization via another plugin.</li>
 | 
						|
								<li>If your theme doesn't have it built-in, use a Lazyload plugin for images.</li>
 | 
						|
							</ol>
 | 
						|
						</div>
 | 
						|
						</div>
 | 
						|
					</div>
 | 
						|
 | 
						|
					<?php $hookup->options_page_metabox(); ?>
 | 
						|
					<?php submit_button( esc_attr( $hookup->cmb->prop( 'save_button' ) ), 'primary', 'submit-cmb' ); ?>
 | 
						|
				</form>
 | 
						|
				<div class="debloat-sidebar">
 | 
						|
					<?php $this->cache_info(); ?>
 | 
						|
				</div>
 | 
						|
			</div>
 | 
						|
 | 
						|
		</div>
 | 
						|
		<?php
 | 
						|
	}
 | 
						|
 | 
						|
	public function cache_info()
 | 
						|
	{
 | 
						|
		$js_cache   = Plugin::file_cache()->get_stats('js');
 | 
						|
		$css_cache  = Plugin::file_cache()->get_stats('css');
 | 
						|
 | 
						|
		// Number of css sheets in cache.
 | 
						|
		$css_sheets = count($this->cache->get_transients());
 | 
						|
		?>
 | 
						|
 | 
						|
		<div class="sphere-cmb2-wrap debloat-cache-info">
 | 
						|
		<div class="cmb2-wrap cmb2-metabox">
 | 
						|
			<div class="cmb-row cmb-type-title">
 | 
						|
				<div class="cmb-td">
 | 
						|
					<h3 class="cmb2-metabox-title">
 | 
						|
						<?php esc_html_e('Cache Stats', 'debloat'); ?>
 | 
						|
					</h3>
 | 
						|
				</div>
 | 
						|
			</div>
 | 
						|
 | 
						|
			<div class="cmb-row">
 | 
						|
				<?php if (defined('SCRIPT_DEBUG') && SCRIPT_DEBUG): ?>
 | 
						|
					<p><strong>Minification Disabled</strong>: SCRIPT_DEBUG is enabled (likely in wp-config.php).</p>
 | 
						|
				<?php endif; ?>
 | 
						|
				
 | 
						|
				<div class="cache-stats">
 | 
						|
					<p><?php printf(esc_html__('Minified CSS files: %d', 'debloat'), $css_cache); ?></p>
 | 
						|
					<p><?php printf(esc_html__('Minified JS files: %d', 'debloat'), $js_cache); ?></p>
 | 
						|
					<p><?php printf(esc_html__('Processed CSS Sheets: %d', 'debloat'), $css_sheets); ?></p>
 | 
						|
				</div>
 | 
						|
 | 
						|
				<a href="<?php echo wp_nonce_url(admin_url('admin.php?page=debloat-delete-cache'), 'debloat_delete_cache'); ?>" 
 | 
						|
					class="button button-secondary" style="margin-top: 10px;">
 | 
						|
					<?php echo esc_html('Empty All Cache', 'debloat'); ?>
 | 
						|
				</a>
 | 
						|
				</p>
 | 
						|
			</div>
 | 
						|
		</div>
 | 
						|
		</div>
 | 
						|
 | 
						|
		<?php
 | 
						|
	}
 | 
						|
}
 |