Skip to content

Instantly share code, notes, and snippets.

@shov
Forked from holisticnetworking/autoload.php
Last active February 13, 2019 06:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shov/c9e64750402f29d64ffe98e512861d62 to your computer and use it in GitHub Desktop.
Save shov/c9e64750402f29d64ffe98e512861d62 to your computer and use it in GitHub Desktop.
Autoloading for both WordPress classes and PSR-4
<?php
/**
* Autoload PSR-4 and Wordpress compatible named classes,
* Require it in very begin of your functions.php or plugin
*
* @author Alexandr Shevchenko <ls.shov@gmail.com>
* @author Thomas J Belknap <tbelknap@holisticnetworking.net>
*/
namespace App; //Change it
/** @var string : autoload root $rootDir */
$rootDir = __DIR__ . '/inc';
(new class
{
public function __invoke(string $rootDir)
{
$rootDir = ($rootDir[-1] === '/') ? $rootDir : $rootDir . '/';
spl_autoload_register(function ($class) use ($rootDir) {
array_map(function ($filePath) use ($rootDir) {
if (false === $filePath) {
return;
}
if (is_readable("${rootDir}${filePath}.php")) {
require_once "${rootDir}${filePath}.php";
}
}, [
$this->wpClassPath($class),
$this->psr4ClassPath($class),
]);
});
}
/**
* Format the incoming class name to the PSR-4 file naming standard.
* @param string $class
* @return bool|string
*/
private function psr4ClassPath(string $class)
{
$parts = $this->splitNameSpace($class);
if (is_null($parts)) {
return false;
}
$classPath = implode('/', $parts);
return $classPath;
}
/**
* Format the incoming class name to the WordPress file naming standard.
* @param string $class
* @return bool|string
*/
private function wpClassPath(string $class)
{
$parts = $this->splitNameSpace($class);
if (is_null($parts)) {
return false;
}
$lastPartIndex = count($parts)-1;
$parts[$lastPartIndex] = 'class-' . $this->wpClassToFile($parts[$lastPartIndex]);
$classPath = implode('/', $parts);
return $classPath;
}
/**
* Split and prepare namespace parts
* @param string $class
* @return null|array
*/
private function splitNameSpace(string $class): ?array
{
$parts = explode('\\', $class);
if (__NAMESPACE__ !== $parts[0]) {
return null;
}
//Remove root namespace (like App, or your project name)
unset($parts[0]);
if (empty($parts)) {
return null;
}
return array_values($parts);
}
/**
* Translates a WordPress-valid class name to a WordPress-valid file name (e.g. Class_Name - class-name)
* @param string $name String in camel case format
* @return string Translated into dashed format
*/
private function wpClassToFile(string $name): string
{
return implode(
'-',
explode(
'_',
preg_replace_callback(
'/[A-Z]*?/',
function ($matches) {
return strtolower($matches[0]);
},
$name
)
)
);
}
})($rootDir);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment