Skip to content

Commit

Permalink
2.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
luizbills committed Sep 26, 2023
1 parent dae1277 commit 7853442
Show file tree
Hide file tree
Showing 20 changed files with 297 additions and 52 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/vendor/
/node_modules/
/wp-build/
*.zip
*.log
File renamed without changes.
2 changes: 1 addition & 1 deletion .bin/install.php → .installer/install.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,10 @@
// list of files and folders
$all_files = rscandir( $src_dir );
$ignores = [
'/.installer/',
'/.git/',
'/.github/',
'/vendor/',
'/.bin/',
'/.snippets/',
'/README.md',
'/CHANGELOG.md',
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.

This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## 2.0.0 - 2023-09-26

- Break: Now the core classes throws `Exception` instead of `Error`.
- Feat: Now all core classes has PHPDoc comments.
- Feat: Added `h::str_contains( $string, $search )` helper

## 1.10.1 - 2023-09-25

- Fix text domain in `core/Dependencies.php`
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Open your terminal and execute the script below in your `wp-content/plugins` to
wp_plugin_base_clone_dir=".wp_plugin_base_$(date +%s)" \
&& git clone --branch main --single-branch --no-tags --quiet \
https://github.com/luizbills/wp-plugin-base.git $wp_plugin_base_clone_dir \
&& cd $wp_plugin_base_clone_dir && php .bin/install.php && sleep .1 \
&& cd $wp_plugin_base_clone_dir && php .installer/install.php && sleep .1 \
&& cd $(cat install.log) \
&& chmod -R +x ./scripts \
&& rm -rf "../$wp_plugin_base_clone_dir"
Expand Down
2 changes: 1 addition & 1 deletion classes/Sample_Class.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public function sample_notice () {
$plugin_name = h::config_get( 'NAME' );

// see /templates/sample-notice.php file
echo h::get_template( 'sample-notice', [
echo h::get_template( 'notice-info', [
'text' => sprintf( 'Hello world from "%s" plugin', $plugin_name ),
] );
}
Expand Down
41 changes: 34 additions & 7 deletions core/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,25 @@

namespace Your_Namespace\Core;

abstract class Config {
final class Config {
/** @var array */
protected static $values = [];

/**
* @param string $main_file The file that contains the plugin headers
* @return void
* @throws \Exception
*/
public static function init ( $main_file ) {
if ( self::get_size() > 0 ) {
throw new \Error( __CLASS__ . ' already initialized' );
throw new \Exception( __CLASS__ . ' already initialized' );
}

$root = dirname( $main_file );
$config = require $root . '/config.php';

if ( ! is_array( $config ) ) {
throw new \Error( $root . '/config.php must return an Array' );
throw new \Exception( $root . '/config.php must return an Array' );
}

if (
Expand All @@ -36,12 +42,12 @@ function_exists( 'wp_get_environment_type' )

$slug = isset( self::$values[ 'SLUG' ] ) ? self::$values[ 'SLUG' ] : false;
if ( ! $slug || ! is_string( $slug ) ) {
throw new \Error( $root . '/config.php must define a string SLUG (Recommended: only alphanumeric and dashes)' );
throw new \Exception( $root . '/config.php must define a string SLUG (Recommended: only alphanumeric and dashes)' );
}

$prefix = isset( self::$values[ 'PREFIX' ] ) ? self::$values[ 'PREFIX' ] : false;
if ( ! $prefix || ! is_string( $prefix ) ) {
throw new \Error( $root . '/config.php must define a string PREFIX (only alphanumeric and underscores)' );
throw new \Exception( $root . '/config.php must define a string PREFIX (only alphanumeric and underscores)' );
}

self::$values[ 'FILE'] = $main_file;
Expand All @@ -50,30 +56,51 @@ function_exists( 'wp_get_environment_type' )
$data = \get_file_data( $main_file, [ 'Plugin Name', 'Version' ] );
self::$values[ 'NAME' ] = __( $data[0], 'your_text_domain' );
self::$values[ 'VERSION' ] = $data[1] ? $data[1] : '0.0.0';
self::$values[ 'VERSION' ] = $data[2] ? $data[1] : '0.0.0';
}

/**
* @param string $key
* @param mixed $value
* @return mixed The value
* @throws \Exception
*/
public static function set ( $key, $value ) {
$key = mb_strtoupper( $key );
if ( isset( self::$values[ $key ] ) ) {
throw new \Error( __METHOD__ . ": Key \"$key\" has already been assigned. No key can be assigned more than once." );
throw new \Exception( __METHOD__ . ": Key \"$key\" has already been assigned. No key can be assigned more than once." );
}
self::$values[ $key ] = $value;
return $value;
}

/**
* @param string $key
* @param mixed $default
* @return mixed
* @throws \Exception
*/
public static function get ( $key, $default = null ) {
$key = \mb_strtoupper( $key );
$value = isset( self::$values[ $key ] ) ? self::$values[ $key ] : $default;
if ( null === $value ) {
throw new \Error( __METHOD__ . ": Undefined key $key" );
throw new \Exception( __METHOD__ . ": Undefined key $key" );
}
return $value;
}

/**
* @return positive-int
*/
public static function get_size () {
return count( self::$values );
}

/**
* @param string $string
* @param string $sep
* @return string
*/
public static function sanitize_slug ( $string, $sep = '-' ) {
$slug = \strtolower( \remove_accents( $string ) ); // Convert to ASCII
// Standard replacements
Expand Down
35 changes: 29 additions & 6 deletions core/Dependencies.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,36 @@

namespace Your_Namespace\Core;

abstract class Dependencies {
final class Dependencies {
/** @var array */
protected static $dependencies;

/** @var bool */
protected static $initialized = false;

/**
* @return void
* @throws \Exception
*/
public static function init () {
if ( self::$initialized ) {
throw new \Error( __CLASS__ . ' already initialized' );
throw new \Exception( __CLASS__ . ' already initialized' );
}

$root = Config::get( 'DIR' );
self::$dependencies = include_once $root . '/dependencies.php';
if ( ! is_array( self::$dependencies ) ) {
throw new \Error( $root . '/dependencies.php must return an Array' );
throw new \Exception( $root . '/dependencies.php must return an Array' );
}

\add_action( 'plugins_loaded', [ __CLASS__, 'maybe_start_plugin' ], 0 );

self::$initialized = true;
}

/**
* @return void
*/
public static function maybe_start_plugin () {
$result = self::check_dependencies();

Expand All @@ -32,6 +42,10 @@ public static function maybe_start_plugin () {
}
}

/**
* @return array{success: bool, messages: string[]} The result
* @throws \Exception
*/
public static function check_dependencies () {
$result = [
'success' => null,
Expand All @@ -47,7 +61,7 @@ public static function check_dependencies () {
// check the message
if ( ! is_string( $message ) || '' === trim( $message ) ) {
$id = is_integer( $key ) ? '#' . ( 1 + $key ) : $key;
throw new \Error( "Dependency $id has an invalid 'message': its must be a string and and it cannot be empty." );
throw new \Exception( "Dependency $id has an invalid 'message': its must be a string and and it cannot be empty." );
}

// check the requirement
Expand All @@ -71,12 +85,17 @@ public static function check_dependencies () {
return $result;
}

/**
* @param string $shortcut
* @return bool
* @throws \Exception
*/
protected static function handle_shortcut ( $shortcut ) {
$parts = explode( ':', $shortcut );
$value = trim( implode( ':', array_slice( $parts, 1 ) ) );
$type = trim( $parts[0] );
if ( ! $value || ! $type ) {
throw new \Error( "Invalid shortcut syntax: $shortcut" );
throw new \Exception( "Invalid shortcut syntax: $shortcut" );
}
switch ( $type ) {
case 'class':
Expand All @@ -101,9 +120,13 @@ protected static function handle_shortcut ( $shortcut ) {
break;
}

throw new \Error( "Unexpected shortcut: $shortcut" );
throw new \Exception( "Unexpected shortcut: $shortcut" );
}

/**
* @param string[] $messages
* @return void
*/
protected static function display_notice_missing_deps ( $messages ) {
if ( ! \is_admin() ) return;
if ( ! \current_user_can( 'install_plugins' ) ) return;
Expand Down
24 changes: 19 additions & 5 deletions core/Loader.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,20 @@

namespace Your_Namespace\Core;

abstract class Loader {
final class Loader {
/** @var bool */
protected static $initialized = false;

/** @var string */
protected static $main_file;

/**
* @return void
* @throws \Exception
*/
public static function init () {
if ( self::$initialized ) {
throw new \Error( __CLASS__ . ' already initialized' );
throw new \Exception( __CLASS__ . ' already initialized' );
}

self::$main_file = Config::get( 'FILE' );
Expand All @@ -17,16 +24,23 @@ public static function init () {
self::$initialized = true;
}

/**
* @return string
*/
public static function get_hook_start_plugin () {
return 'start_plugin_' . self::$main_file;
}

/**
* @return void
* @throws \Exception
*/
public static function load_classes () {
$root = Config::get( 'DIR' );
$loader = include_once $root . '/loader.php';

if ( ! is_array( $loader ) ) {
throw new \Error( $root . '/loader.php must return an Array' );
throw new \Exception( $root . '/loader.php must return an Array' );
}

$classes = [];
Expand All @@ -53,7 +67,7 @@ public static function load_classes () {
$loaded = false;

if ( is_string( $class_name ) && ! \class_exists( $class_name ) ) {
throw new \Error( 'class ' . $class_name . ' does not exist' );
throw new \Exception( 'class ' . $class_name . ' does not exist' );
}

$instance = is_string( $class_name ) ? new $class_name() : $class_name;
Expand All @@ -75,7 +89,7 @@ public static function load_classes () {
}

if ( ! $loaded ) {
throw new \Error( "class $class_name must have at least one of the following methods: __start, __activation (static) or __deactivation (static)" );
throw new \Exception( "class $class_name must have at least one of the following methods: __start, __activation (static) or __deactivation (static)" );
}
}
}
Expand Down
28 changes: 19 additions & 9 deletions core/Main.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@

namespace Your_Namespace\Core;

abstract class Main {
protected static $classes_to_load = [];
protected static $dependencies = [];
final class Main {

/**
* @param string $main_file The file that contains the plugin headers
* @return void
*/
public static function start_plugin ( $main_file ) {
if ( ! file_exists( $main_file ) ) {
throw new \Error( 'Invalid plugin main file path in ' . __CLASS__ );
throw new \Exception( 'Invalid plugin main file path in ' . __CLASS__ );
}

Config::init( $main_file );
Expand All @@ -18,11 +20,19 @@ public static function start_plugin ( $main_file ) {
add_action( 'init', [ __CLASS__, 'load_textdomain' ], 0 );
}

/**
* Loads the plugin translations
* @return void
*/
public static function load_textdomain () {
\load_plugin_textdomain(
'your_text_domain',
false,
dirname( plugin_basename( Config::get( 'FILE' ) ) ) . '/languages/'
);
$languages_dir = Config::get( 'DOMAIN_PATH', 'languages' );
$path = Config::get( 'DIR' ) . "/$languages_dir";
if ( file_exists( $path ) && is_dir( $path ) ) {
\load_plugin_textdomain(
'your_text_domain',
false,
dirname( plugin_basename( Config::get( 'FILE' ) ) ) . "/$languages_dir/"
);
}
}
}
Loading

0 comments on commit 7853442

Please sign in to comment.