EditorPlus.php (7780B)
1 <?php 2 /** 3 * Handles editor related changes. 4 * Loaded (or not) in /bootstrap.php 5 */ 6 7 if (!class_exists('edpl__EditorPlus')) { 8 // phpcs:ignore Squiz.Classes.ClassFileName.NoMatch,Squiz.Commenting.ClassComment.Missing,PEAR.Commenting.ClassComment.Missing 9 final class ExtendifySdkEditorPlus 10 { 11 12 /** 13 * A reference to an instance of this class. 14 * 15 * @var $instance 16 */ 17 public static $instance; 18 19 /** 20 * The array of templates that this plugin tracks. 21 * 22 * @var array $templates 23 */ 24 protected $templates; 25 26 /** 27 * Returns an instance of this class. 28 * 29 * @return self 30 */ 31 public static function getInstance() 32 { 33 if (!current_user_can('install_plugins')) { 34 return; 35 } 36 37 if (is_null(self::$instance)) { 38 self::$instance = new ExtendifySdkEditorPlus(); 39 } 40 41 return self::$instance; 42 } 43 44 /** 45 * Initializes the plugin by setting filters and administration functions. 46 */ 47 public function __construct() 48 { 49 if ($this->isSupported()) { 50 $this->templates = []; 51 52 \add_action( 53 'admin_enqueue_scripts', 54 function () { 55 // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.NoExplicitVersion 56 \wp_enqueue_script( 57 'extendifysdk-editorplus-scripts', 58 EXTENDIFYSDK_BASE_URL . 'public/editorplus/editorplus.min.js', 59 [], 60 false, 61 true 62 ); 63 } 64 ); 65 66 add_action('wp_head', [$this, 'enqueueStylesheet']); 67 68 add_filter( 69 'theme_page_templates', 70 [ 71 $this, 72 'addNewTemplate', 73 ] 74 ); 75 76 // Add a filter to the save post to inject out template into the page cache. 77 add_filter( 78 'wp_insert_post_data', 79 [ 80 $this, 81 'registerProjectTemplates', 82 ] 83 ); 84 // Add a filter to the template include to determine if the page has our template assigned and return it's path. 85 add_filter( 86 'template_include', 87 [ 88 $this, 89 'viewProjectTemplate', 90 ] 91 ); 92 93 $this->templates = ['editorplus-template.php' => 'Extendify Template']; 94 add_filter( 95 'body_class', 96 function ($classes) { 97 $classes[] = 'eplus_styles'; 98 return $classes; 99 } 100 ); 101 102 // Registering meta data to store editorplus generated stylesheet of template. 103 $postTypes = get_post_types(['_builtin' => false], 'names', 'and'); 104 $postTypes['post'] = 'post'; 105 foreach ($postTypes as $postType) { 106 register_meta( 107 $postType, 108 'extendify_custom_stylesheet', 109 [ 110 'show_in_rest' => true, 111 'single' => true, 112 'type' => 'string', 113 'default' => '', 114 ] 115 ); 116 } 117 }//end if 118 } 119 120 /** 121 * Used to echo out page template stylesheet if the page template is not active. 122 * 123 * @return void 124 */ 125 public function enqueueStylesheet() 126 { 127 if (!isset($GLOBALS['post']) || !$GLOBALS['post']) { 128 return; 129 } 130 131 $post = $GLOBALS['post']; 132 $cssContent = apply_filters( 133 'extendifysdk_template_css', 134 get_post_meta($post->ID, 'extendify_custom_stylesheet', true), 135 $post 136 ); 137 138 // Note that esc_html() cannot be used because `div > span` is not interpreted properly. 139 // See: https://github.com/WordPress/WordPress/blob/ccdb1766aead26d4cef79badb015bb2727fefd59/wp-includes/theme.php#L1824-L1833 for reference. 140 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped 141 echo "<style id='extendify-custom-stylesheet' type='text/css'>" . wp_strip_all_tags($cssContent) . '</style>'; 142 } 143 144 /** 145 * Will check if page templates are supported in the installed wp version. 146 * 147 * @return bool 148 */ 149 public function isSupported() 150 { 151 return version_compare(floatval(get_bloginfo('version')), '4.7', '>'); 152 } 153 154 /** 155 * Adds our template to the page dropdown for v4.7+ 156 * 157 * @param array $postsTemplates - Array of page templates. 158 * @return array 159 */ 160 public function addNewTemplate($postsTemplates) 161 { 162 return array_merge($postsTemplates, $this->templates); 163 } 164 165 /** 166 * Adds our template to the pages cache in order to trick WordPress, 167 * into thinking the template file exists where it doens't really exist. 168 * 169 * @param array $attributes - The attributes. 170 * @return array 171 */ 172 public function registerProjectTemplates($attributes) 173 { 174 // Create the key used for the themes cache. 175 $cacheKey = 'page_templates-' . \wp_hash(get_theme_root() . '/' . get_stylesheet()); 176 // Retrieve the cache list. 177 // If it doesn't exist, or it's empty prepare an array. 178 $templates = wp_get_theme()->get_page_templates(); 179 if (empty($templates)) { 180 $templates = []; 181 } 182 183 // New cache, therefore remove the old one. 184 wp_cache_delete($cacheKey, 'themes'); 185 // Now add our template to the list of templates by merging our templates. 186 // with the existing templates array from the cache. 187 $templates = array_merge($templates, $this->templates); 188 // Add the modified cache to allow WordPress to pick it up for listing available templates. 189 wp_cache_add($cacheKey, $templates, 'themes', 1800); 190 return $attributes; 191 } 192 193 /** 194 * Checks if the template is assigned to the page. 195 * 196 * @param string $template - The template. 197 * @return string 198 */ 199 public function viewProjectTemplate($template) 200 { 201 $post = $GLOBALS['post']; 202 if (!$post) { 203 return $template; 204 } 205 206 $currentTemplate = get_post_meta($post->ID, '_wp_page_template', true); 207 208 // Check that the set template is one we have defined. 209 if (!is_string($currentTemplate) || !array_key_exists($currentTemplate, $this->templates)) { 210 return $template; 211 } 212 213 $file = plugin_dir_path(__FILE__) . $currentTemplate; 214 if (!file_exists($file)) { 215 return $template; 216 } 217 218 return $file; 219 } 220 // phpcs:ignore Squiz.Classes.ClassDeclaration.SpaceBeforeCloseBrace 221 } 222 223 add_action('after_setup_theme', ['ExtendifySdkEditorPlus', 'getInstance']); 224 }//end if