| 1 |
<?php |
| 2 |
|
| 3 |
/** |
| 4 |
* Plugin Name: Accordion Toggle |
| 5 |
* Plugin URI: https://essential-blocks.com |
| 6 |
* Description: Display Your FAQs & Improve User Experience with Accordion/Toggle block. |
| 7 |
* Version: 1.3.0 |
| 8 |
* Author: WPDeveloper |
| 9 |
* Author URI: https://wpdeveloper.net |
| 10 |
* License: GPL-3.0-or-later |
| 11 |
* License URI: https://www.gnu.org/licenses/gpl-3.0.html |
| 12 |
* Text Domain: accordion-toggle |
| 13 |
* Requires at least: 5.6 |
| 14 |
* Requires PHP: 7.2 |
| 15 |
* Tested up to: 7.1 |
| 16 |
* |
| 17 |
* @package accordion-toggle |
| 18 |
*/ |
| 19 |
|
| 20 |
/** |
| 21 |
* Registers all block assets so that they can be enqueued through the block editor |
| 22 |
* in the corresponding context. |
| 23 |
* |
| 24 |
* @see https://developer.wordpress.org/block-editor/tutorials/block-tutorial/applying-styles-with-stylesheets/ |
| 25 |
*/ |
| 26 |
|
| 27 |
// Exit if accessed directly. |
| 28 |
if ( ! defined( 'ABSPATH' ) ) { |
| 29 |
exit; |
| 30 |
} |
| 31 |
|
| 32 |
define( 'ACCORDION_BLOCK_VERSION', "1.3.0" ); |
| 33 |
define( 'ACCORDION_BLOCK_ADMIN_URL', plugin_dir_url( __FILE__ ) ); |
| 34 |
define( 'ACCORDION_BLOCK_ADMIN_PATH', dirname( __FILE__ ) ); |
| 35 |
|
| 36 |
class EBAccordionToggle { |
| 37 |
|
| 38 |
protected static $_instance = null; |
| 39 |
|
| 40 |
public static function get_instance() { |
| 41 |
if ( is_null( self::$_instance ) ) { |
| 42 |
self::$_instance = new self(); |
| 43 |
} |
| 44 |
return self::$_instance; |
| 45 |
} |
| 46 |
|
| 47 |
private function __construct() { |
| 48 |
|
| 49 |
// enqueue script and |
| 50 |
add_action( 'enqueue_block_editor_assets', [$this, 'enqueue_block_assets'], 100 ); |
| 51 |
add_action( 'enqueue_block_editor_assets', [$this, 'frontend_backend_assets'], 100 ); |
| 52 |
add_action( 'wp_enqueue_scripts', [$this, 'frontend_backend_assets'], 100 ); |
| 53 |
add_action( 'enqueue_block_assets', [$this, 'block_canvas_assets'] ); |
| 54 |
|
| 55 |
// Load All Block Files |
| 56 |
$this->load_block_dependencies(); |
| 57 |
} |
| 58 |
|
| 59 |
public function enqueue_block_assets() { |
| 60 |
global $pagenow; |
| 61 |
/** |
| 62 |
* Scripts |
| 63 |
*/ |
| 64 |
$controls_dependencies = Accordion_Helper::get_asset_file( '/dist/modules.asset.php' ); |
| 65 |
wp_register_script( |
| 66 |
"eb-accordion-toggle-controls-util", |
| 67 |
ACCORDION_BLOCK_ADMIN_URL . '/dist/modules.js', |
| 68 |
$controls_dependencies['dependencies'], |
| 69 |
$controls_dependencies['version'], |
| 70 |
true |
| 71 |
); |
| 72 |
|
| 73 |
wp_localize_script( 'eb-accordion-toggle-controls-util', 'EssentialBlocksLocalize', [ |
| 74 |
'eb_wp_version' => (float) get_bloginfo( 'version' ), |
| 75 |
'rest_rootURL' => get_rest_url(), |
| 76 |
'fontAwesome' => "true", |
| 77 |
/** |
| 78 |
* StyleComponent builds the editor preview's media queries from this. |
| 79 |
* Without it the editor emitted `@media all and (max-width: undefinedpx)` |
| 80 |
* and silently discarded every tablet/mobile rule, so responsive settings |
| 81 |
* showed no effect in the editor while working on the front end. |
| 82 |
*/ |
| 83 |
'responsiveBreakpoints' => Accordion_Helper::get_responsive_breakpoints(), |
| 84 |
] ); |
| 85 |
|
| 86 |
if ( $pagenow == 'post-new.php' || $pagenow == 'post.php' ) { |
| 87 |
wp_localize_script( 'eb-accordion-toggle-controls-util', 'eb_conditional_localize', [ |
| 88 |
'editor_type' => 'edit-post' |
| 89 |
] ); |
| 90 |
} else if ( $pagenow == 'site-editor.php' || $pagenow == 'themes.php' ) { |
| 91 |
wp_localize_script( 'eb-accordion-toggle-controls-util', 'eb_conditional_localize', [ |
| 92 |
'editor_type' => 'edit-site' |
| 93 |
] ); |
| 94 |
} |
| 95 |
|
| 96 |
wp_enqueue_style( |
| 97 |
'accordion-toggle-editor-css', |
| 98 |
ACCORDION_BLOCK_ADMIN_URL . '/dist/modules.css', |
| 99 |
[ |
| 100 |
'essential-blocks-fontawesome', |
| 101 |
'essential-blocks-iconpicker-css' |
| 102 |
], |
| 103 |
ACCORDION_BLOCK_VERSION, |
| 104 |
'all' |
| 105 |
); |
| 106 |
|
| 107 |
$script_asset = Accordion_Helper::get_asset_file( '/dist/index.asset.php' ); |
| 108 |
$all_dependencies = array_merge( $script_asset['dependencies'], [ |
| 109 |
'wp-blocks', |
| 110 |
'wp-i18n', |
| 111 |
'wp-element', |
| 112 |
'wp-block-editor', |
| 113 |
'eb-accordion-toggle-controls-util', |
| 114 |
'essential-blocks-eb-animation' |
| 115 |
] ); |
| 116 |
|
| 117 |
wp_enqueue_script( |
| 118 |
'eb-accordion-toggle-editor', |
| 119 |
ACCORDION_BLOCK_ADMIN_URL . 'dist/index.js', |
| 120 |
$all_dependencies, |
| 121 |
ACCORDION_BLOCK_VERSION, |
| 122 |
true |
| 123 |
); |
| 124 |
} |
| 125 |
|
| 126 |
/** |
| 127 |
* Assets for the block editor canvas. |
| 128 |
* |
| 129 |
* Since WP 6.3 the post editor renders block content inside an iframe. |
| 130 |
* `_wp_get_iframed_editor_assets()` (wp-includes/block-editor.php) builds that |
| 131 |
* iframe's stylesheet list by replaying the `enqueue_block_assets` action only — |
| 132 |
* anything enqueued on `enqueue_block_editor_assets` stays in the outer admin |
| 133 |
* document and never reaches the canvas. |
| 134 |
* |
| 135 |
* EBDisplayIcon renders the dashicon set as <span class="dashicons dashicons-x">, |
| 136 |
* which needs core's `dashicons` stylesheet for the @font-face and the :before |
| 137 |
* glyph. wp-admin loads dashicons for the outer document as part of the |
| 138 |
* concatenated load-styles.php admin bundle, which the canvas does not inherit, |
| 139 |
* so a selected dashicon rendered as a 0x0 span with no glyph. Font Awesome was |
| 140 |
* unaffected because it is a plugin stylesheet that does reach the canvas. |
| 141 |
* |
| 142 |
* The front end enqueues dashicons from the accordion block's render_callback in |
| 143 |
* blocks/accordion.php, so it is only needed here for the editor. |
| 144 |
*/ |
| 145 |
public function block_canvas_assets() { |
| 146 |
if ( ! is_admin() ) { |
| 147 |
return; |
| 148 |
} |
| 149 |
|
| 150 |
wp_enqueue_style( 'dashicons' ); |
| 151 |
|
| 152 |
/** |
| 153 |
* dist/style.css carries `display:flex` for .eb-accordion-title-content-wrap, |
| 154 |
* the row that holds the title prefix, the title and the suffix. It was |
| 155 |
* registered below but never enqueued anywhere, so the row fell back to |
| 156 |
* `display:block` and every flex property generated for it — justify-content |
| 157 |
* from "Title Align", gap from "Prefix Suffix Spacing", and the |
| 158 |
* flex-direction / align-items from "Prefix & Title Layout" — had no effect. |
| 159 |
* |
| 160 |
* Passing $src here as well makes this independent of hook order: the canvas |
| 161 |
* pass runs before frontend_backend_assets() has registered the handle, and |
| 162 |
* wp_enqueue_style() ignores $src when the handle already exists. |
| 163 |
*/ |
| 164 |
wp_enqueue_style( |
| 165 |
'eb-accordion-toggle-frontend-style', |
| 166 |
ACCORDION_BLOCK_ADMIN_URL . 'dist/style.css', |
| 167 |
[], |
| 168 |
ACCORDION_BLOCK_VERSION, |
| 169 |
'all' |
| 170 |
); |
| 171 |
|
| 172 |
/** |
| 173 |
* Icon fonts for the canvas. |
| 174 |
* |
| 175 |
* These two are declared as dependencies of `accordion-toggle-editor-css` |
| 176 |
* (dist/modules.css) further up, which is enough for the outer admin document. |
| 177 |
* The iframed canvas resolves its own asset list from this hook, and a |
| 178 |
* dependency of a handle that was never enqueued in this pass is not pulled |
| 179 |
* in, so Font Awesome never reached the canvas: the accordion's dropdown |
| 180 |
* arrow, `<i class="fas fa-angle-right eb-accordion-icon">`, fell back to the |
| 181 |
* theme font with `::before { content: none }` and collapsed to zero height. |
| 182 |
* |
| 183 |
* Enqueued with $src for the same reason as the stylesheet above -- this pass |
| 184 |
* runs before frontend_backend_assets() has registered the handles, and |
| 185 |
* wp_enqueue_style() ignores $src for a handle that already exists. |
| 186 |
*/ |
| 187 |
wp_enqueue_style( |
| 188 |
'essential-blocks-fontawesome', |
| 189 |
ACCORDION_BLOCK_ADMIN_URL . 'assets/css/fontawesome/css/all.min.css', |
| 190 |
[], |
| 191 |
ACCORDION_BLOCK_VERSION, |
| 192 |
'all' |
| 193 |
); |
| 194 |
|
| 195 |
wp_enqueue_style( |
| 196 |
'essential-blocks-iconpicker-css', |
| 197 |
ACCORDION_BLOCK_ADMIN_URL . 'dist/style-modules.css', |
| 198 |
[], |
| 199 |
ACCORDION_BLOCK_VERSION, |
| 200 |
'all' |
| 201 |
); |
| 202 |
} |
| 203 |
|
| 204 |
public function frontend_backend_assets() { |
| 205 |
/** |
| 206 |
* Enqueue resources for Animation ||Start|| |
| 207 |
*/ |
| 208 |
wp_register_script( |
| 209 |
'essential-blocks-controls-frontend', |
| 210 |
ACCORDION_BLOCK_ADMIN_URL . 'dist/frontend.js', |
| 211 |
[], |
| 212 |
ACCORDION_BLOCK_VERSION, |
| 213 |
true |
| 214 |
); |
| 215 |
//Animate JS |
| 216 |
wp_enqueue_script( |
| 217 |
'essential-blocks-eb-animation', |
| 218 |
ACCORDION_BLOCK_ADMIN_URL . 'assets/js/eb-animation-load.js', |
| 219 |
[], |
| 220 |
ACCORDION_BLOCK_VERSION, |
| 221 |
true |
| 222 |
); |
| 223 |
|
| 224 |
//Animate CSS |
| 225 |
wp_enqueue_style( |
| 226 |
'essential-blocks-animation', |
| 227 |
ACCORDION_BLOCK_ADMIN_URL . 'assets/css/animate.min.css', |
| 228 |
[], |
| 229 |
ACCORDION_BLOCK_VERSION, |
| 230 |
'all' |
| 231 |
); |
| 232 |
/** |
| 233 |
* Enqueue resources for Animation ||End|| |
| 234 |
*/ |
| 235 |
|
| 236 |
//Blocks Common Style from Dist |
| 237 |
wp_register_style( |
| 238 |
'eb-accordion-toggle-frontend-style', |
| 239 |
ACCORDION_BLOCK_ADMIN_URL . 'dist/style.css', |
| 240 |
[], |
| 241 |
ACCORDION_BLOCK_VERSION, |
| 242 |
'all' |
| 243 |
); |
| 244 |
|
| 245 |
wp_register_style( |
| 246 |
'essential-blocks-fontawesome', |
| 247 |
ACCORDION_BLOCK_ADMIN_URL . 'assets/css/fontawesome/css/all.min.css', |
| 248 |
[], |
| 249 |
ACCORDION_BLOCK_VERSION, |
| 250 |
'all' |
| 251 |
); |
| 252 |
|
| 253 |
wp_register_style( |
| 254 |
'fontpicker-default-theme', |
| 255 |
ACCORDION_BLOCK_ADMIN_URL . 'assets/css/fonticonpicker.base-theme.react.css', |
| 256 |
[], |
| 257 |
ACCORDION_BLOCK_VERSION, |
| 258 |
'all' |
| 259 |
); |
| 260 |
|
| 261 |
wp_register_style( |
| 262 |
'fontpicker-material-theme', |
| 263 |
ACCORDION_BLOCK_ADMIN_URL . 'assets/css/fonticonpicker.material-theme.react.css', |
| 264 |
[], |
| 265 |
ACCORDION_BLOCK_VERSION, |
| 266 |
'all' |
| 267 |
); |
| 268 |
|
| 269 |
wp_register_style( |
| 270 |
'essential-blocks-iconpicker-css', |
| 271 |
ACCORDION_BLOCK_ADMIN_URL . 'dist/style-modules.css', |
| 272 |
[], |
| 273 |
ACCORDION_BLOCK_VERSION, |
| 274 |
'all' |
| 275 |
); |
| 276 |
|
| 277 |
wp_register_style( |
| 278 |
'essential-blocks-hover-css', |
| 279 |
ACCORDION_BLOCK_ADMIN_URL . 'assets/css/hover-min.css', |
| 280 |
[], |
| 281 |
ACCORDION_BLOCK_VERSION, |
| 282 |
'all' |
| 283 |
); |
| 284 |
|
| 285 |
wp_register_style( |
| 286 |
'hover-effects-style', |
| 287 |
ACCORDION_BLOCK_ADMIN_URL . 'assets/css/hover-effects.css', |
| 288 |
[], |
| 289 |
ACCORDION_BLOCK_VERSION, |
| 290 |
'all' |
| 291 |
); |
| 292 |
} |
| 293 |
|
| 294 |
/** |
| 295 |
* Warn an administrator when the style-handler submodule is absent. |
| 296 |
* |
| 297 |
* Runs on `admin_notices`, so the translation calls happen well after |
| 298 |
* `init` (loading them earlier triggers a _doing_it_wrong notice on WP 6.7+). |
| 299 |
*/ |
| 300 |
public function style_handler_missing_notice() { |
| 301 |
if ( ! current_user_can( 'activate_plugins' ) ) { |
| 302 |
return; |
| 303 |
} |
| 304 |
|
| 305 |
printf( |
| 306 |
'<div class="notice notice-error"><p><strong>%s</strong> %s</p><p><code>git submodule update --init --recursive</code></p></div>', |
| 307 |
esc_html__( 'Accordion Toggle:', 'accordion-toggle' ), |
| 308 |
esc_html__( 'the bundled style-handler library is missing, so block styles will not be generated and the front end will render unstyled. If this is a development checkout, initialise the git submodules:', 'accordion-toggle' ) |
| 309 |
); |
| 310 |
} |
| 311 |
|
| 312 |
private function load_block_dependencies() { |
| 313 |
require_once ACCORDION_BLOCK_ADMIN_PATH . '/includes/font-loader.php'; |
| 314 |
require_once ACCORDION_BLOCK_ADMIN_PATH . '/includes/post-meta.php'; |
| 315 |
|
| 316 |
// `lib/style-handler` is a git submodule; guard so an uninitialised |
| 317 |
// submodule degrades instead of fataling the whole site. |
| 318 |
// |
| 319 |
// It is NOT optional: it turns each block's `blockMeta` attribute into |
| 320 |
// the generated stylesheet under uploads/eb-style/. Without it the |
| 321 |
// editor still looks right (it computes styles in JS) but the front end |
| 322 |
// renders completely unstyled. Surface a notice rather than failing |
| 323 |
// silently — a silent skip here is very hard to diagnose. |
| 324 |
$style_handler = ACCORDION_BLOCK_ADMIN_PATH . '/lib/style-handler/style-handler.php'; |
| 325 |
if ( file_exists( $style_handler ) ) { |
| 326 |
require_once $style_handler; |
| 327 |
} else { |
| 328 |
add_action( 'admin_notices', [$this, 'style_handler_missing_notice'] ); |
| 329 |
} |
| 330 |
|
| 331 |
require_once ACCORDION_BLOCK_ADMIN_PATH . '/includes/helpers.php'; |
| 332 |
require_once ACCORDION_BLOCK_ADMIN_PATH . '/includes/class-faq-schema.php'; |
| 333 |
if ( ! WP_Block_Type_Registry::get_instance()->is_registered( 'essential-blocks/accordion' ) ) { |
| 334 |
require_once ACCORDION_BLOCK_ADMIN_PATH . '/blocks/accordion.php'; |
| 335 |
require_once ACCORDION_BLOCK_ADMIN_PATH . '/blocks/accordion-item.php'; |
| 336 |
} |
| 337 |
} |
| 338 |
} |
| 339 |
EBAccordionToggle::get_instance(); |
| 340 |
|