balmet.com

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

class-redux-panel.php (14482B)


      1 <?php
      2 /**
      3  * Redux Panel Class
      4  *
      5  * @class Redux_Panel
      6  * @version 3.0.0
      7  * @package Redux Framework/Classes
      8  */
      9 
     10 defined( 'ABSPATH' ) || exit;
     11 
     12 if ( ! class_exists( 'Redux_Panel', false ) ) {
     13 
     14 	/**
     15 	 * Class Redux_Panel
     16 	 */
     17 	class Redux_Panel {
     18 
     19 		/**
     20 		 * ReduxFramwrok object pointer.
     21 		 *
     22 		 * @var object
     23 		 */
     24 		public $parent = null;
     25 
     26 		/**
     27 		 * Path to templates dir.
     28 		 *
     29 		 * @var null|string
     30 		 */
     31 		public $template_path = null;
     32 
     33 		/**
     34 		 * Original template path.
     35 		 *
     36 		 * @var null
     37 		 */
     38 		public $original_path = null;
     39 
     40 		/**
     41 		 * Sets the path from the arg or via filter. Also calls the panel template function.
     42 		 *
     43 		 * @param object $parent ReduxFramework pointer.
     44 		 */
     45 		public function __construct( $parent ) {
     46 			$this->parent        = $parent;
     47 			$this->template_path = Redux_Core::$dir . 'templates/panel/';
     48 			$this->original_path = Redux_Core::$dir . 'templates/panel/';
     49 
     50 			if ( ! empty( $this->parent->args['templates_path'] ) ) {
     51 				$this->template_path = trailingslashit( $this->parent->args['templates_path'] );
     52 			}
     53 
     54 			// phpcs:ignore WordPress.NamingConventions.ValidHookName
     55 			$this->template_path = trailingslashit( apply_filters( "redux/{$this->parent->args['opt_name']}/panel/templates_path", $this->template_path ) );
     56 		}
     57 
     58 		/**
     59 		 * Class init.
     60 		 */
     61 		public function init() {
     62 			$this->panel_template();
     63 		}
     64 
     65 		/**
     66 		 * Loads the panel templates where needed and provides the container for Redux
     67 		 */
     68 		private function panel_template() {
     69 			if ( $this->parent->args['dev_mode'] ) {
     70 				$this->template_file_check_notice();
     71 			}
     72 
     73 			/**
     74 			 * Action 'redux/{opt_name}/panel/before'
     75 			 */
     76 
     77 			// phpcs:ignore WordPress.NamingConventions.ValidHookName
     78 			do_action( "redux/{$this->parent->args['opt_name']}/panel/before" );
     79 
     80 			echo '<div class="wrap"><h2></h2></div>'; // Stupid hack for WordPress alerts and warnings.
     81 
     82 			echo '<div class="clear"></div>';
     83 			echo '<div class="wrap redux-wrap-div" data-opt-name="' . esc_attr( $this->parent->args['opt_name'] ) . '">';
     84 
     85 			// Do we support JS?
     86 			echo '<noscript><div class="no-js">' . esc_html__( 'Warning- This options panel will not work properly without javascript!', 'redux-framework' ) . '</div></noscript>';
     87 
     88 			// Security is vital!
     89 			echo '<input type="hidden" class="redux-ajax-security" data-opt-name="' . esc_attr( $this->parent->args['opt_name'] ) . '" id="ajaxsecurity" name="security" value="' . esc_attr( wp_create_nonce( 'redux_ajax_nonce' . $this->parent->args['opt_name'] ) ) . '" />';
     90 
     91 			/**
     92 			 * Action 'redux/page/{opt_name}/form/before'
     93 			 *
     94 			 * @param object $this ReduxFramework
     95 			 */
     96 
     97 			// phpcs:ignore WordPress.NamingConventions.ValidHookName
     98 			do_action( "redux/page/{$this->parent->args['opt_name']}/form/before", $this );
     99 
    100 			if ( is_rtl() ) {
    101 				$this->parent->args['class'] = ' redux-rtl';
    102 			}
    103 
    104 			echo '<div id="redux-dialog-confirm" title="' . esc_html__( 'Submit Support Information?', 'redux-framework' ) . '" data-nonce="' . esc_attr( wp_create_nonce( 'redux_sumbit_support' ) ) . '">';
    105 			// translators: %s = WP Site Health Screen URL.
    106 			echo '<p><span class="ui-icon ui-icon-alert" style="float:left; margin:12px 12px 20px 0;"></span>' . sprintf( esc_html__( 'Redux will send the debug information found on the %s and your Redux config to our secure server.  Are you ready to proceed?', 'redux-framework' ), '<a href="' . esc_url( admin_url( 'site-health.php?tab=debug' ) ) . '" target="_blank">' . esc_html__( 'WordPress Site Health screen', 'redux-framework' ) . '</a>' ) . '</p>';
    107 			echo '</div>';
    108 
    109 			echo '<div id="redux-dialog-message" title="Working...">';
    110 			echo '<p class="redux-message-p">';
    111 			echo '<span class="spinner" style="float:left; margin:0 7px 50px 0;" ></span>Transmitting data...';
    112 			echo '</p>';
    113 			echo '</div>';
    114 
    115 			$this->get_template( 'container.tpl.php' );
    116 
    117 			/**
    118 			 * Action 'redux/page/{opt_name}/form/after'
    119 			 *
    120 			 * @param object $this ReduxFramework
    121 			 */
    122 
    123 			// phpcs:ignore WordPress.NamingConventions.ValidHookName
    124 			do_action( "redux/page/{$this->parent->args['opt_name']}/form/after", $this );
    125 
    126 			echo '<div class="clear"></div>';
    127 			echo '</div>';
    128 
    129 			if ( true === $this->parent->args['dev_mode'] ) {
    130 				echo '<br /><div class="redux-timer">' . esc_html( get_num_queries() ) . ' queries in ' . esc_html( timer_stop() ) . ' seconds<br/>Redux is currently set to developer mode.</div>';
    131 			}
    132 
    133 			/**
    134 			 * Action 'redux/{opt_name}/panel/after'
    135 			 */
    136 
    137 			// phpcs:ignore WordPress.NamingConventions.ValidHookName
    138 			do_action( "redux/{$this->parent->args['opt_name']}/panel/after" );
    139 		}
    140 
    141 		/**
    142 		 * Calls the various notification bars and sets the appropriate templates.
    143 		 */
    144 		public function notification_bar() {
    145 			if ( isset( $this->parent->transients['last_save_mode'] ) ) {
    146 
    147 				if ( 'import' === $this->parent->transients['last_save_mode'] ) {
    148 					/**
    149 					 * Action 'redux/options/{opt_name}/import'
    150 					 *
    151 					 * @param object $this ReduxFramework
    152 					 */
    153 
    154 					// phpcs:ignore WordPress.NamingConventions.ValidHookName
    155 					do_action( "redux/options/{$this->parent->args['opt_name']}/import", $this, $this->parent->transients['changed_values'] );
    156 
    157 					echo '<div class="admin-notice notice-blue saved_notice">';
    158 
    159 					/**
    160 					 * Filter 'redux-imported-text-{opt_name}'
    161 					 *
    162 					 * @param string  translated "settings imported" text
    163 					 */
    164 
    165 					// phpcs:ignore WordPress.NamingConventions.ValidHookName
    166 					echo '<strong>' . esc_html( apply_filters( "redux-imported-text-{$this->parent->args['opt_name']}", esc_html__( 'Settings Imported!', 'redux-framework' ) ) ) . '</strong>';
    167 					echo '</div>';
    168 				} elseif ( 'defaults' === $this->parent->transients['last_save_mode'] ) {
    169 					/**
    170 					 * Action 'redux/options/{opt_name}/reset'
    171 					 *
    172 					 * @param object $this ReduxFramework
    173 					 */
    174 
    175 					// phpcs:ignore WordPress.NamingConventions.ValidHookName
    176 					do_action( "redux/options/{$this->parent->args['opt_name']}/reset", $this );
    177 
    178 					echo '<div class="saved_notice admin-notice notice-yellow">';
    179 
    180 					/**
    181 					 * Filter 'redux-defaults-text-{opt_name}'
    182 					 *
    183 					 * @param string  translated "settings imported" text
    184 					 */
    185 
    186 					// phpcs:ignore WordPress.NamingConventions.ValidHookName
    187 					echo '<strong>' . esc_html( apply_filters( "redux-defaults-text-{$this->parent->args['opt_name']}", esc_html__( 'All Defaults Restored!', 'redux-framework' ) ) ) . '</strong>';
    188 					echo '</div>';
    189 				} elseif ( 'defaults_section' === $this->parent->transients['last_save_mode'] ) {
    190 					/**
    191 					 * Action 'redux/options/{opt_name}/section/reset'
    192 					 *
    193 					 * @param object $this ReduxFramework
    194 					 */
    195 
    196 					// phpcs:ignore WordPress.NamingConventions.ValidHookName
    197 					do_action( "redux/options/{$this->parent->args['opt_name']}/section/reset", $this );
    198 
    199 					echo '<div class="saved_notice admin-notice notice-yellow">';
    200 
    201 					/**
    202 					 * Filter 'redux-defaults-section-text-{opt_name}'
    203 					 *
    204 					 * @param string  translated "settings imported" text
    205 					 */
    206 
    207 					// phpcs:ignore WordPress.NamingConventions.ValidHookName
    208 					echo '<strong>' . esc_html( apply_filters( "redux-defaults-section-text-{$this->parent->args['opt_name']}", esc_html__( 'Section Defaults Restored!', 'redux-framework' ) ) ) . '</strong>';
    209 					echo '</div>';
    210 				} elseif ( 'normal' === $this->parent->transients['last_save_mode'] ) {
    211 					/**
    212 					 * Action 'redux/options/{opt_name}/saved'
    213 					 *
    214 					 * @param mixed $value set/saved option value
    215 					 */
    216 
    217 					// phpcs:ignore WordPress.NamingConventions.ValidHookName
    218 					do_action( "redux/options/{$this->parent->args['opt_name']}/saved", $this->parent->options, $this->parent->transients['changed_values'] );
    219 
    220 					echo '<div class="saved_notice admin-notice notice-green">';
    221 
    222 					/**
    223 					 * Filter 'redux-saved-text-{opt_name}'
    224 					 *
    225 					 * @param string translated "settings saved" text
    226 					 */
    227 
    228 					// phpcs:ignore WordPress.NamingConventions.ValidHookName
    229 					echo '<strong>' . esc_html( apply_filters( "redux-saved-text-{$this->parent->args['opt_name']}", esc_html__( 'Settings Saved!', 'redux-framework' ) ) ) . '</strong>';
    230 					echo '</div>';
    231 				}
    232 
    233 				unset( $this->parent->transients['last_save_mode'] );
    234 
    235 				$this->parent->transient_class->set();
    236 			}
    237 
    238 			/**
    239 			 * Action 'redux/options/{opt_name}/settings/changes'
    240 			 *
    241 			 * @param mixed $value set/saved option value
    242 			 */
    243 
    244 			// phpcs:ignore WordPress.NamingConventions.ValidHookName
    245 			do_action( "redux/options/{$this->parent->args['opt_name']}/settings/change", $this->parent->options, $this->parent->transients['changed_values'] );
    246 
    247 			echo '<div class="redux-save-warn notice-yellow">';
    248 
    249 			/**
    250 			 * Filter 'redux-changed-text-{opt_name}'
    251 			 *
    252 			 * @param string translated "settings have changed" text
    253 			 */
    254 
    255 			// phpcs:ignore WordPress.NamingConventions.ValidHookName
    256 			echo '<strong>' . esc_html( apply_filters( "redux-changed-text-{$this->parent->args['opt_name']}", esc_html__( 'Settings have changed, you should save them!', 'redux-framework' ) ) ) . '</strong>';
    257 			echo '</div>';
    258 
    259 			/**
    260 			 * Action 'redux/options/{opt_name}/errors'
    261 			 *
    262 			 * @param array $this ->errors error information
    263 			 */
    264 
    265 			// phpcs:ignore WordPress.NamingConventions.ValidHookName
    266 			do_action( "redux/options/{$this->parent->args['opt_name']}/errors", $this->parent->errors );
    267 
    268 			echo '<div class="redux-field-errors notice-red">';
    269 			echo '<strong>';
    270 			echo '<span></span> ' . esc_html__( 'error(s) were found!', 'redux-framework' );
    271 			echo '</strong>';
    272 			echo '</div>';
    273 
    274 			/**
    275 			 * Action 'redux/options/{opt_name}/warnings'
    276 			 *
    277 			 * @param array $this ->warnings warning information
    278 			 */
    279 
    280 			// phpcs:ignore WordPress.NamingConventions.ValidHookName
    281 			do_action( "redux/options/{$this->parent->args['opt_name']}/warnings", $this->parent->warnings );
    282 
    283 			echo '<div class="redux-field-warnings notice-yellow">';
    284 			echo '<strong>';
    285 			echo '<span></span> ' . esc_html__( 'warning(s) were found!', 'redux-framework' );
    286 			echo '</strong>';
    287 			echo '</div>';
    288 		}
    289 
    290 		/**
    291 		 * Used to intitialize the settings fields for this panel. Required for saving and redirect.
    292 		 */
    293 		private function init_settings_fields() {
    294 			// Must run or the page won't redirect properly.
    295 			settings_fields( "{$this->parent->args['opt_name']}_group" );
    296 		}
    297 
    298 		/**
    299 		 * Enable file deprecate warning from core.  This is necessary because the function is considered private.
    300 		 *
    301 		 * @return bool
    302 		 */
    303 		public function tick_file_deprecate_warning(): bool {
    304 			return true;
    305 		}
    306 
    307 		/**
    308 		 * Used to select the proper template. If it doesn't exist in the path, then the original template file is used.
    309 		 *
    310 		 * @param string $file Path to template file.
    311 		 */
    312 		public function get_template( string $file ) {
    313 			if ( empty( $file ) ) {
    314 				return;
    315 			}
    316 
    317 			if ( file_exists( $this->template_path . $file ) ) {
    318 				$path = $this->template_path . $file;
    319 			} else {
    320 				$path = $this->original_path . $file;
    321 			}
    322 
    323 			// Shim for v3 templates.
    324 			if ( ! file_exists( $path ) ) {
    325 				$old_file = $file;
    326 
    327 				add_filter( 'deprecated_file_trigger_error', array( $this, 'tick_file_deprecate_warning' ) );
    328 
    329 				$file = str_replace( '-', '_', $file );
    330 
    331 				_deprecated_file( esc_html( $file ), '4.0', esc_html( $old_file ), 'Please replace this outdated template with the current one from the Redux core.' );
    332 
    333 				if ( file_exists( $this->template_path . $file ) ) {
    334 					$path = $this->template_path . $file;
    335 				} else {
    336 					$path = $this->original_path . $file;
    337 				}
    338 			}
    339 
    340 			// phpcs:ignore WordPress.NamingConventions.ValidHookName
    341 			do_action( "redux/{$this->parent->args['opt_name']}/panel/template/" . $file . '/before' );
    342 
    343 			// phpcs:ignore WordPress.NamingConventions.ValidHookName
    344 			$path = apply_filters( "redux/{$this->parent->args['opt_name']}/panel/template/" . $file, $path );
    345 
    346 			// phpcs:ignore WordPress.NamingConventions.ValidHookName
    347 			do_action( "redux/{$this->parent->args['opt_name']}/panel/template/" . $file . '/after' );
    348 
    349 			require $path;
    350 		}
    351 
    352 		/**
    353 		 * Scan the template files.
    354 		 *
    355 		 * @param string $template_path Path to template file.
    356 		 *
    357 		 * @return array
    358 		 */
    359 		public function scan_template_files( string $template_path ): array {
    360 			$files  = scandir( $template_path );
    361 			$result = array();
    362 			if ( $files ) {
    363 				foreach ( $files as $key => $value ) {
    364 					if ( ! in_array( $value, array( '.', '..' ), true ) ) {
    365 						if ( is_dir( $template_path . DIRECTORY_SEPARATOR . $value ) ) {
    366 							$sub_files = self::scan_template_files( $template_path . DIRECTORY_SEPARATOR . $value );
    367 							foreach ( $sub_files as $sub_file ) {
    368 								$result[] = $value . DIRECTORY_SEPARATOR . $sub_file;
    369 							}
    370 						} else {
    371 							$result[] = $value;
    372 						}
    373 					}
    374 				}
    375 			}
    376 
    377 			return $result;
    378 		}
    379 
    380 		/**
    381 		 * Show a notice highlighting bad template files
    382 		 */
    383 		public function template_file_check_notice() {
    384 			if ( $this->original_path === $this->template_path ) {
    385 				return;
    386 			}
    387 
    388 			$core_templates = $this->scan_template_files( $this->original_path );
    389 
    390 			foreach ( $core_templates as $file ) {
    391 				$developer_theme_file = false;
    392 
    393 				if ( file_exists( $this->template_path . $file ) ) {
    394 					$developer_theme_file = $this->template_path . $file;
    395 				}
    396 
    397 				if ( $developer_theme_file ) {
    398 					$core_version      = Redux_Helpers::get_template_version( $this->original_path . $file );
    399 					$developer_version = Redux_Helpers::get_template_version( $developer_theme_file );
    400 
    401 					if ( $core_version && $developer_version && version_compare( $developer_version, $core_version, '<' ) && isset( $this->parent->args['dev_mode'] ) && ! empty( $this->parent->args['dev_mode'] ) ) {
    402 						?>
    403 						<div id="message" class="error redux-message">
    404 							<p>
    405 								<strong><?php esc_html_e( 'Your panel has bundled copies of Redux Framework template files that are outdated!', 'redux-framework' ); ?></strong>&nbsp;&nbsp;<?php esc_html_e( 'Please update them now as functionality issues could arise.', 'redux-framework' ); ?>
    406 							</p>
    407 						</div>
    408 						<?php
    409 
    410 						return;
    411 					}
    412 				}
    413 			}
    414 		}
    415 
    416 		/**
    417 		 * Outputs the HTML for a given section using the WordPress settings API.
    418 		 *
    419 		 * @param mixed $k Section number of settings panel to display.
    420 		 */
    421 		private function output_section( $k ) {
    422 			do_settings_sections( $this->parent->args['opt_name'] . $k . '_section_group' );
    423 		}
    424 	}
    425 }
    426 
    427 if ( ! class_exists( 'reduxCorePanel' ) ) {
    428 	class_alias( 'Redux_Panel', 'reduxCorePanel' );
    429 }
    430 
    431