Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
22a2389
Load the bundled autoload only if no global autoload is present
kasparsd Sep 4, 2025
cd9190b
We’re already in the global namespace, no need for root escaping
kasparsd Sep 4, 2025
9b10c0d
These are classes
kasparsd Sep 4, 2025
8c1aa24
Use the defaults
kasparsd Sep 4, 2025
21b27e2
These are already excluded by /build/ rule above
kasparsd Sep 4, 2025
a6cbe51
Keep a minimal default config
kasparsd Sep 4, 2025
4ddd782
Describe all parameters used
kasparsd Sep 4, 2025
7dccb27
Adjust per linter rules
kasparsd Sep 4, 2025
38ac830
Use tabs per WPCS
kasparsd Sep 4, 2025
1a58d3e
Per WPCS linter
kasparsd Sep 4, 2025
89ca4fc
Rename per WPCS
kasparsd Sep 4, 2025
5ada5c6
No need for this since classes alone don’t do anything when called di…
kasparsd Sep 4, 2025
07a61b2
This is already implied due to the namespace of this class
kasparsd Sep 4, 2025
e2eccae
Introduce a generic module class to enable init() logic
kasparsd Sep 4, 2025
393c4f7
Use classmap to follow WPCS naming
kasparsd Sep 4, 2025
9343443
Showcase dependency injection and make plugin paths reusable
kasparsd Sep 4, 2025
4280d8c
USe npm-run-all for cross-platform scripting
kasparsd Sep 4, 2025
a70385c
Ignore the map files during development
kasparsd Sep 4, 2025
d05fbb7
This already runs things by default
kasparsd Sep 4, 2025
88e9689
Per WPCS
kasparsd Sep 4, 2025
3a5fa7f
Inherit the default rules from wp-scripts instead
kasparsd Sep 4, 2025
3efaf30
Match the class name
kasparsd Sep 4, 2025
49cb89c
Disable notices until we have these placeholders
kasparsd Sep 4, 2025
ad3f9f8
Per linter
kasparsd Sep 4, 2025
a66e926
Document classes
kasparsd Sep 4, 2025
1570a15
Bump WPCS
kasparsd Sep 4, 2025
7ce1f09
Account for adjusted filenames
kasparsd Sep 4, 2025
17be6a9
Turns out the textdomain isn’t detected from the plugin header automa…
kasparsd Sep 4, 2025
3c99e1e
Ensure it is prefixed per our wpcs ruleset
kasparsd Sep 4, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions .eslintignore

This file was deleted.

17 changes: 0 additions & 17 deletions .eslintrc.json

This file was deleted.

2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
/build/**/*.map

# Logs
logs
*.log
Expand Down
3 changes: 0 additions & 3 deletions .prettierignore

This file was deleted.

13 changes: 0 additions & 13 deletions .prettierrc

This file was deleted.

5 changes: 0 additions & 5 deletions .stylelintignore

This file was deleted.

8 changes: 0 additions & 8 deletions .stylelintrc.json

This file was deleted.

46 changes: 0 additions & 46 deletions Functions/Enqueues.php

This file was deleted.

16 changes: 0 additions & 16 deletions Functions/Plugin_Paths.php

This file was deleted.

31 changes: 0 additions & 31 deletions Functions/Register_Blocks.php

This file was deleted.

36 changes: 20 additions & 16 deletions advanced-multi-block.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,25 +13,29 @@
* @package CreateBlock
*/

if (! defined('ABSPATH') ) {
exit;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}

// Include Composer's autoload file.
if ( file_exists( plugin_dir_path( __FILE__ ) . 'vendor/autoload.php' ) ) {
require_once plugin_dir_path( __FILE__ ) . 'vendor/autoload.php';
} else {
wp_trigger_error( 'Advanced Multi Block Plugin: Composer autoload file not found. Please run `composer install`.', E_USER_ERROR );
return;
// Include our bundled autoload if not loaded globally.
if ( ! class_exists( Advanced_Multi_Block\Plugin_Paths::class ) && file_exists( __DIR__ . '/vendor/autoload.php' ) ) {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here we attempt to require the bundled vendor/autoload.php only if the class is not resolved by the global project autoloader. By default, calling class_exists() triggers the autoload logic so that attempts everything that a global Composer autoload has registered (if at all).

require_once __DIR__ . '/vendor/autoload.php';
}

// Instantiate the classes.
$advanced_multi_block_classes = array(
\Advanced_Multi_Block\Plugin_Paths::class,
\Advanced_Multi_Block\Register_Blocks::class,
\Advanced_Multi_Block\Enqueues::class,
if ( ! class_exists( Advanced_Multi_Block\Plugin_Paths::class ) ) {
wp_trigger_error( 'Advanced Multi Block Plugin: Composer autoload file not found. Please run `composer install`.', E_USER_ERROR );
return;
}

// Instantiate our modules.
$advanced_multi_block_modules = array(
new Advanced_Multi_Block\Register_Blocks( __DIR__ . '/build' ),
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This approach now avoid registering WP hooks early so that classes can all be instantiated before their init() logic is called.

new Advanced_Multi_Block\Enqueues( __DIR__ . '/build' ),
);

foreach ( $advanced_multi_block_classes as $advanced_multi_block_class ) {
new $advanced_multi_block_class();
}

foreach ( $advanced_multi_block_modules as $advanced_multi_block_module ) {
if ( is_a( $advanced_multi_block_module, Advanced_Multi_Block\Plugin_Module::class ) ) {
$advanced_multi_block_module->init();
}
}
2 changes: 1 addition & 1 deletion build/blocks/toggle/render.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
'isDark' => false,
'darkText' => esc_html__( 'Switch to Light', 'advanced-multi-block' ),
'lightText' => esc_html__( 'Switch to Dark', 'advanced-multi-block' ),
'themeText' => esc_html__( 'Switch to Dark', 'advanced-multi-block' ),
'themeText' => esc_html__( 'Switch to Dark', 'advanced-multi-block' ),
)
);
?>
Expand Down
71 changes: 71 additions & 0 deletions classes/class-enqueues.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php
/**
* Enqueue assets.
*
* @package Advanced_Multi_Block
*/

namespace Advanced_Multi_Block;

/**
* Enqueues class.
*/
class Enqueues extends Plugin_Module {
/**
* Path resolver for build directory.
*
* @var Plugin_Paths
*/
private Plugin_Paths $build_dir;

/**
* Setup the class.
*
* @param string $build_path Absolute path to the build directory for all assets.
*/
public function __construct( string $build_path ) {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This now receives the path of the build directory via constructor argument. It is now the responsibility of the caller of this class (plugin bootstrap) to define where that directory lives (which also gives us a single place to update it).

$this->build_dir = new Plugin_Paths( $build_path );
}

/**
* Initialize the module.
*/
public function init() {
add_action( 'enqueue_block_editor_assets', array( $this, 'enqueue_block_assets' ) );
add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_frontend_assets' ) );
}

/**
* Enqueues the block assets for the editor.
*/
public function enqueue_block_assets() {
$asset_meta = $this->build_dir->get_asset_meta( 'editor-script.js' );
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Plugin_Paths now has a helper for resolving the *.asset.php meta file and returning the data, if the file is present. Removes a lot of repeated boilerplate.


if ( $asset_meta ) {
wp_enqueue_script(
'editor-script-js',
$this->build_dir->get_url( 'editor-script.js' ),
$asset_meta['dependencies'],
$asset_meta['version'],
false
);
}
}

/**
* Enqueues the block assets for the frontend.
*/
public function enqueue_frontend_assets() {
$asset_meta = $this->build_dir->get_asset_meta( 'frontend-script.js' );

if ( $asset_meta ) {
wp_enqueue_script(
'frontend-script-js',
$this->build_dir->get_url( 'frontend-script.js' ),
$asset_meta['dependencies'],
$asset_meta['version'],
true
);
}
}
}
18 changes: 18 additions & 0 deletions classes/class-plugin-module.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php
/**
* Base class for plugin modules which can be initialized.
*
* @package Advanced_Multi_Block
*/

namespace Advanced_Multi_Block;

/**
* Plugin module extended by other classes.
*/
abstract class Plugin_Module {
/**
* Initialize the module.
*/
abstract public function init();
}
83 changes: 83 additions & 0 deletions classes/class-plugin-paths.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<?php
/**
* Help resolve paths and URLs relative to plugin directories.
*
* @package Advanced_Multi_Block
*/

namespace Advanced_Multi_Block;

/**
* Path resolver class.
*/
class Plugin_Paths {

/**
* Absolute path to a directory inside the plugin.
*
* @var string
*/
private string $plugin_dir;

/**
* Setup the class.
*
* @param string $plugin_dir Absolute path to the plugin directory.
*/
public function __construct( string $plugin_dir ) {
$this->plugin_dir = rtrim( $plugin_dir, '\\/' );
}

/**
* Get a URL for a path relative to the plugin directory.
*
* @param string|null $relative_path Optional. Relative path from the plugin directory.
* Default null for the base plugin URL.
*
* @return string The full URL.
*/
public function get_url( ?string $relative_path = null ): string {
if ( isset( $relative_path ) ) {
return plugins_url( ltrim( $relative_path, '/' ), $this->plugin_dir . '/fake.file' );
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That /fake.file definitely feels like a hack but I'm not aware of a better helper that would accept a directory path as the argument :)

}

return plugins_url( '', $this->plugin_dir . '/fake.file' );
}

/**
* Get the absolute path for a path relative to the plugin directory.
*
* @param string|null $relative_path Optional. Relative path from the plugin directory.
* Default null for the base plugin path.
*
* @return string The full path.
*/
public function get_path( ?string $relative_path = null ): string {
if ( isset( $relative_path ) ) {
return $this->plugin_dir . '/' . ltrim( $relative_path, '/' );
}

return $this->plugin_dir;
}

/**
* Get the asset meta for a built asset file.
*
* @param string $asset_file Asset file name relative to the plugin directory.
*
* @return array|null Array with 'dependencies' and 'version' keys, or null if not found.
*/
public function get_asset_meta( string $asset_file ): ?array {
$asset_path = $this->get_path( dirname( $asset_file ) . '/' . pathinfo( $asset_file, PATHINFO_FILENAME ) . '.asset.php' );
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the new helper that resolves *.asset.php meta data for any JS/CSS file.


if ( file_exists( $asset_path ) ) {
$meta = include $asset_path;

if ( is_array( $meta ) ) {
return $meta;
}
}

return null;
}
}
Loading