Skip to content

Commit

Permalink
Merge pull request #25 from nomad-mystic/kpm-update-bootstrap-list
Browse files Browse the repository at this point in the history
Kpm update bootstrap list
  • Loading branch information
nomad-mystic authored Feb 14, 2024
2 parents 99516ef + 46a2c4d commit 215bbc3
Show file tree
Hide file tree
Showing 32 changed files with 321 additions and 270 deletions.
214 changes: 132 additions & 82 deletions scaffolding/theme/classes/BootstrapClasses.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@
*/
class BootstrapClasses
{
private array $no_instantiate = [
'BootstrapClasses',
];

/**
* @description Auto initialize classes from composer namespaces
* @author Keith Murphy | nomadmystics@gmail.com
Expand Down Expand Up @@ -106,29 +110,32 @@ private function perform_bootstrap(array $composer_classes): void
{
// Get our classes and namespaces from the composer extraction
for ($namespace = 0; $namespace < count($composer_classes); $namespace++) {

// Sanity check
if (!empty($composer_classes[$namespace])) {
// For each of the classes check if we have hooks and build
if (isset($composer_classes[$namespace]->namespace) &&
!empty($composer_classes[$namespace]->namespace) &&
isset($composer_classes[$namespace]->classes) &&
!empty($composer_classes[$namespace]->classes)
) {
for ($class = 0; $class < count($composer_classes[$namespace]->classes); $class++) {
// Store our current needed variables
$class_filename = basename($composer_classes[$namespace]->classes[$class], '.php');
$current_namespace = $composer_classes[$namespace]->namespace;

// Name sure things don't blow up here
if (class_exists($current_namespace . "\\" . $class_filename)) {
// Don't call this over and over again, no need to create an infinite loop here
if ($class_filename !== 'BootstrapClasses') {
$this->instantiate_class($current_namespace . "\\" . $class_filename);
}
}
} // End for
} // End if
} // End if
if (empty($composer_classes[$namespace]) ||
!isset($composer_classes[$namespace]->namespace) ||
empty($composer_classes[$namespace]->namespace) ||
!isset($composer_classes[$namespace]->classes) ||
empty($composer_classes[$namespace]->classes)
) {
continue;
}

// For each of the classes check if we have hooks and build
for ($class = 0; $class < count($composer_classes[$namespace]->classes); $class++) {
// Store our current needed variables
$class_filename = basename($composer_classes[$namespace]->classes[$class], '.php');
$current_namespace = $composer_classes[$namespace]->namespace;

// Name sure things don't blow up here
if (class_exists($current_namespace . "\\" . $class_filename)) {

// Don't call this over and over again, no need to create an infinite loop here
if (in_array($class_filename, $this->no_instantiate)) {
$this->instantiate_class($current_namespace . "\\" . $class_filename);
}
}
} // End for
} // End for
}

Expand All @@ -143,73 +150,42 @@ private function perform_bootstrap(array $composer_classes): void
*/
private function instantiate_class(string $namespace_and_class): void
{
//Instantiate the reflection object
$reflector = new ReflectionClass($namespace_and_class);

// If the object is not instantiationable exit
if (!$reflector->isInstantiable()) {
return;
}

// Instantiate the object
$classname_string = $namespace_and_class;
$class = new $classname_string();

//Instantiate the reflection object
$reflector = new ReflectionClass($namespace_and_class);

$methods = $reflector->getMethods();

// Sanity check and bail early if there aren't any methods
if (!empty($methods)) {
foreach ($methods as $method) {
if (!empty($method)) {
$method_name = $method->getName();

// Get method docBlocks string
$doc_blocks = $reflector->getMethod($method_name)->getdoccomment();

// Define the regular expression pattern to use for string matching (Checking for @ in docBlock)
$pattern = "#(@[a-zA-Z]+\s*[a-zA-Z0-9].*)#im";
$matches = null;

// Perform the regular expression on the string provided
preg_match_all($pattern, $doc_blocks, $matches, PREG_PATTERN_ORDER);

// Make sure we have match with @ in the docBlock
if (!empty($matches[0]) && is_array($matches[0])) {
// We need to check for priority in the doc blocks first then apply theme to the action or filter
$priority = 10;
$priority_value = $this->check_for_property('@priority', $matches[0]);

if (!empty($priority_value)) {
$priority_level = preg_split("/[\s,]+/", $priority_value);

$priority = (int) $priority_level[1];
}

// Check for our desired properties
foreach ($matches[0] as $block_property) {
if (!empty($block_property)) {
// Check for filter or action
preg_match('/@add_action*(.*)$/im', $block_property, $action_found);
preg_match('/@add_filter*(.*)$/im', $block_property, $filter_found);

// Here we go
if (!empty($action_found)) {
// Grab the hook name
$action = trim($action_found[1]);

// Do the action
add_action($action, [$class, $method_name], $priority);
}

// Here we go
if (!empty($filter_found)) {
// Grab the hook name
$filter = trim($filter_found[1]);

// Do the filter
add_filter($filter, [$class, $method_name], $priority);
}
} // End sanity $block_property
} // End foreach $block_property
} // End sanity check
} // End sanity check
} // End foreach $methods
} // End $methods
if (empty($methods)) {
return;
}

foreach ($methods as $method) {
// Bail early
if (empty($method)) {
continue;
}

$method_name = $method->getName();

$matches = $this->check_for_matches($reflector, $method_name);

// Make sure we have match with @ in the docBlock
if (!empty($matches[0]) && is_array($matches[0])) {

$this->build_hooks($class, $method_name, $matches[0]);

} // End sanity check
} // End foreach $methods
} // End Method

/**
Expand All @@ -231,6 +207,80 @@ private function check_for_property(string $needle, $haystack): bool | string

return false;
}

/**
* @description Check for DocBlock properties i.e. @
* @private
* @author Keith Murphy | nomadmystics@gmail.com
*
* @param object $reflector
* @param string $method_name
* @return array
*/
private function check_for_matches(object $reflector, string $method_name): array
{
// Get method docBlocks string
$doc_blocks = $reflector->getMethod($method_name)->getdoccomment();

// Define the regular expression pattern to use for string matching (Checking for @ in docBlock)
$pattern = "#(@[a-zA-Z]+\s*[a-zA-Z0-9].*)#im";
$matches = [];

// Perform the regular expression on the string provided
preg_match_all($pattern, $doc_blocks, $matches, PREG_PATTERN_ORDER);

return $matches;
}

/**
* @description Pass this the class information we need and hook into WordPress if DocBlock has hook information
* @private
* @author Keith Murphy | nomadmystics@gmail.com
*
* @param object $class
* @param string $method_name
* @param array $matches
* @return void
*/
private function build_hooks(object $class, string $method_name, array $matches): void
{
// We need to check for priority in the doc blocks first then apply theme to the action or filter
$priority = 10;
$priority_value = $this->check_for_property('@priority', $matches);

if (!empty($priority_value)) {
$priority_level = preg_split("/[\s,]+/", $priority_value);

$priority = (int) $priority_level[1];
}

// Check for our desired properties
foreach ($matches as $block_property) {
if (!empty($block_property)) {
// Check for filter or action
preg_match('/@add_action*(.*)$/im', $block_property, $action_found);
preg_match('/@add_filter*(.*)$/im', $block_property, $filter_found);

// Here we go
if (!empty($action_found)) {
// Grab the hook name
$action = trim($action_found[1]);

// Do the action
add_action($action, [$class, $method_name], $priority);
}

// Here we go
if (!empty($filter_found)) {
// Grab the hook name
$filter = trim($filter_found[1]);

// Do the filter
add_filter($filter, [$class, $method_name], $priority);
}
} // End sanity $block_property
} // End foreach $block_property
}
}

if (class_exists('PASCAL_NAME\BootstrapClasses')) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Interfaces
import ThemeAnswers from '../interfaces/theme/interface-theme-answers.js';
import InterfaceThemeAnswers from '../interfaces/theme/interface-theme-answers.js';
import InitAnswers from '../interfaces/project/interface-init-answers.js';
import PluginAnswers from '../interfaces/plugin/interface-plugin-anwsers.js';
import InterfacePluginAnswers from '../interfaces/plugin/interface-plugin-anwsers.js';

/**
* @classdesc Use this a base for creating the scaffolding for each type of CLI action
Expand All @@ -23,8 +23,8 @@ export default abstract class AbstractScaffold {
* @protected
* @author Keith Murphy | nomadmystics@gmail.com
*
* @param {InitAnswers | ThemeAnswers | PluginAnswers | any} answers
* @param {InitAnswers | InterfaceThemeAnswers | InterfacePluginAnswers | any} answers
* @return Promise<void>
*/
protected static scaffoldFiles = async (answers: InitAnswers | ThemeAnswers | PluginAnswers | any): Promise<void> => {};
protected static scaffoldFiles = async (answers: InitAnswers | InterfaceThemeAnswers | InterfacePluginAnswers | any): Promise<void> => {};
}
Loading

0 comments on commit 215bbc3

Please sign in to comment.