class-redux-extension-abstract.php (6429B)
1 <?php 2 /** 3 * Redux Extension Abstract 4 * 5 * @class Redux_Extension_Abstract 6 * @version 4.0.0 7 * @package Redux Framework/Classes 8 */ 9 10 defined( 'ABSPATH' ) || exit; 11 12 /** 13 * Class Redux_Extension_Abstract 14 * An abstract class to make the writing of redux extensions easier by allowing users to extend this class 15 * 16 * @see the samples directory to find a usage example 17 */ 18 abstract class Redux_Extension_Abstract { 19 /** 20 * The version of the extension (This is a default value you may want to override it) 21 * 22 * @var string 23 */ 24 public static $version = '1.0.0'; 25 26 /** 27 * The extension URL. 28 * 29 * @var string 30 */ 31 protected $extension_url; 32 33 /** 34 * The extension dir. 35 * 36 * @var string 37 */ 38 protected $extension_dir; 39 40 /** 41 * The instance of the extension 42 * 43 * @var static 44 */ 45 protected static $instance; 46 47 /** 48 * The extension's file 49 * 50 * @var string 51 */ 52 protected $file; 53 54 /** 55 * The redux framework instance that spawned the extension. 56 * 57 * @var ReduxFramework 58 */ 59 public $parent; 60 61 /** 62 * The ReflectionClass of the extension 63 * 64 * @var ReflectionClass 65 */ 66 protected $reflection_class; 67 68 /** 69 * Redux_Extension_Abstract constructor. 70 * 71 * @param object $parent ReduxFramework pointer. 72 * @param string $file Extension file. 73 */ 74 public function __construct( $parent, string $file = '' ) { 75 $this->parent = $parent; 76 77 // If the file is not given make sure we have one. 78 if ( empty( $file ) ) { 79 $file = $this->get_reflection()->getFileName(); 80 } 81 82 $this->file = $file; 83 84 $this->extension_dir = trailingslashit( str_replace( '\\', '/', dirname( $file ) ) ); 85 86 $plugin_info = Redux_Functions_Ex::is_inside_plugin( $this->file ); 87 88 if ( false !== $plugin_info ) { 89 $this->extension_url = trailingslashit( dirname( $plugin_info['url'] ) ); 90 } else { 91 $theme_info = Redux_Functions_Ex::is_inside_theme( $this->file ); 92 if ( false !== $theme_info ) { 93 $this->extension_url = trailingslashit( dirname( $theme_info['url'] ) ); 94 } 95 } 96 97 static::$instance = $this; 98 } 99 100 /** 101 * Get the reflection class of the extension. 102 * 103 * @return ReflectionClass 104 */ 105 protected function get_reflection(): ReflectionClass { 106 if ( ! isset( $this->reflection_class ) ) { 107 try { 108 $this->reflection_class = new ReflectionClass( $this ); 109 } catch ( ReflectionException $e ) { // phpcs:ignore 110 error_log( $e->getMessage() ); // phpcs:ignore 111 } 112 } 113 114 return $this->reflection_class; 115 } 116 117 /** 118 * Return extension version. 119 * 120 * @return string 121 */ 122 public static function get_version(): string { 123 return static::$version; 124 } 125 126 /** 127 * Returns extension instance. 128 * 129 * @return Redux_Extension_Abstract 130 */ 131 public static function get_instance(): Redux_Extension_Abstract { 132 return static::$instance; 133 } 134 135 /** 136 * Return extension dir. 137 * 138 * @return string 139 */ 140 public function get_dir(): string { 141 return $this->extension_dir; 142 } 143 144 /** 145 * Returns extension URL 146 * 147 * @return string 148 */ 149 public function get_url(): string { 150 return $this->extension_url; 151 } 152 153 /** 154 * Adds the local field. (The use of add_field is recommended). 155 * 156 * @param string $field_name Name of field. 157 */ 158 protected function add_overload_field_filter( string $field_name ) { 159 // phpcs:ignore WordPress.NamingConventions.ValidHookName 160 add_filter( 161 'redux/' . $this->parent->args['opt_name'] . '/field/class/' . $field_name, 162 array( 163 &$this, 164 'overload_field_path', 165 ), 166 10, 167 2 168 ); 169 } 170 171 /** 172 * Adds the local field to the extension and register it in the builder. 173 * 174 * @param string $field_name Name of field. 175 */ 176 protected function add_field( string $field_name ) { 177 $class = $this->get_reflection()->getName(); 178 179 // phpcs:ignore WordPress.NamingConventions.ValidHookName 180 add_filter( 181 'redux/fields', 182 function ( $classes ) use ( $field_name, $class ) { 183 $classes[ $field_name ] = $class; 184 return $classes; 185 } 186 ); 187 188 $this->add_overload_field_filter( $field_name ); 189 } 190 191 /** 192 * Overload field path. 193 * 194 * @param string $file Extension file. 195 * @param array $field Field array. 196 * 197 * @return string 198 */ 199 public function overload_field_path( string $file, array $field ): string { 200 $filename_fix = str_replace( '_', '-', $field['type'] ); 201 202 $files = array( 203 trailingslashit( dirname( $this->file ) ) . $field['type'] . DIRECTORY_SEPARATOR . 'field_' . $field['type'] . '.php', 204 trailingslashit( dirname( $this->file ) ) . $field['type'] . DIRECTORY_SEPARATOR . 'class-redux-' . $filename_fix . '.php', 205 ); 206 207 return Redux_Functions::file_exists_ex( $files ); 208 } 209 210 /** 211 * Sets the minimum version of Redux to use. Displays a notice if requirments not met. 212 * 213 * @param string $min_version Minimum version to evaluate. 214 * @param string $extension_version Extension version number. 215 * @param string $friendly_name Friend extension name for notice display. 216 * 217 * @return bool 218 */ 219 public function is_minimum_version( string $min_version = '', string $extension_version = '', string $friendly_name = '' ): bool { 220 $redux_ver = Redux_Core::$version; 221 222 if ( '' !== $min_version ) { 223 if ( version_compare( $redux_ver, $min_version ) < 0 ) { 224 // translators: %1$s Extension friendly name. %2$s: minimum Redux version. 225 $msg = '<strong>' . sprintf( esc_html__( 'The %1$s extension requires Redux Framework version %2$s or higher.', 'redux-framework' ), $friendly_name, $min_version ) . '</strong> ' . esc_html__( 'You are currently running Redux Framework version ', 'redux-framework' ) . ' ' . $redux_ver . '.<br/><br/>' . esc_html__( 'This field will not render in your option panel, and featuress of this extension will not be available until the latest version of Redux Framework has been installed.', 'redux-framework' ); 226 227 $data = array( 228 'parent' => $this->parent, 229 'type' => 'error', 230 'msg' => $msg, 231 'id' => $this->ext_name . '_notice_' . $extension_version, 232 'dismiss' => false, 233 ); 234 235 if ( method_exists( 'Redux_Admin_Notices', 'set_notice' ) ) { 236 Redux_Admin_Notices::set_notice( $data ); 237 } else { 238 echo '<div class="error">'; 239 echo '<p>'; 240 echo $msg; // phpcs:ignore WordPress.Security.EscapeOutput 241 echo '</p>'; 242 echo '</div>'; 243 } 244 245 return false; 246 } 247 } 248 249 return true; 250 } 251 } 252 253 if ( ! class_exists( 'Redux_Abstract_Extension' ) ) { 254 class_alias( 'Redux_Extension_Abstract', 'Redux_Abstract_Extension' ); 255 }