Skip to content

Commit

Permalink
🎉 initial version
Browse files Browse the repository at this point in the history
  • Loading branch information
bnomei committed Aug 31, 2021
1 parent 5192e37 commit 3989108
Show file tree
Hide file tree
Showing 75 changed files with 9,026 additions and 7 deletions.
25 changes: 25 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
[*.{css,scss,less,js,json,ts,sass,html,hbs,mustache,phtml,html.twig,md,yml}]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
insert_final_newline = true

[*.md, *.txt]
indent_size = 4
trim_trailing_whitespace = false

[site/templates/**.php]
indent_size = 2

[site/snippets/**.php]
indent_size = 2

[package.json,.{babelrc,editorconfig,eslintrc,lintstagedrc,stylelintrc}]
indent_style = space
indent_size = 2

[composer.json]
indent_size = 4
12 changes: 12 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Auto detect text files and perform LF normalization
* text=auto

/docs export-ignore
/tests export-ignore
/.github export-ignore
/.gitattributes export-ignore
/.coveralls.yml export-ignore
/.php-cs-fixer.dist.php export-ignore
/.gitignore export-ignore
/.travis.yml export-ignore
/phpunit.xml export-ignore
40 changes: 35 additions & 5 deletions .gitignore
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,6 +1,36 @@
composer.phar
/vendor/
# OS files
.DS_Store
.idea
*.cache

node_modules

/tests/kirby
/tests/logs
/tests/media
/tests/site/accounts
/tests/site/cache
/tests/site/sessions
/tests/janitor-*.php

# files of Composer dependencies that are not needed for the plugin
/vendor/**/.*
/vendor/**/*.json
/vendor/**/*.txt
/vendor/**/*.md
/vendor/**/*.yml
/vendor/**/*.yaml
/vendor/**/*.xml
/vendor/**/*.dist
/vendor/**/readme.php
/vendor/**/LICENSE
/vendor/**/COPYING
/vendor/**/VERSION
/vendor/**/docs/*
/vendor/**/example/*
/vendor/**/examples/*
/vendor/**/test/*
/vendor/**/tests/*
/vendor/**/php4/*
/vendor/getkirby/composer-installer

# Commit your application's lock file https://getcomposer.org/doc/01-basic-usage.md#commit-your-composer-lock-file-to-version-control
# You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file
# composer.lock
19 changes: 19 additions & 0 deletions .php-cs-fixer.dist.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php


$finder = PhpCsFixer\Finder::create()
->exclude('content')
->exclude('kirby')
->exclude('node_modules')
//->exclude('site/plugins')
->exclude('src')
->exclude('vendor')
->in(__DIR__)
;

return (new PhpCsFixer\Config())
->setRules([
'@PSR2' => true,
])
->setFinder($finder)
;
14 changes: 14 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
language: php
php: 7.3
matrix:
fast_finish: true
install: composer install --no-interaction
script: composer test
after_success: travis_retry php vendor/bin/php-coveralls -v
notifications:
webhooks:
on_success: change
on_failure: always
on_start: never
urls:
- https://webhooks.gitter.im/e/77d9949056dc0462d25d
70 changes: 68 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,68 @@
# autoloader-for-kirby
Helper Class to automatically load various Kirby extension in a plugin
# Autoloader for Kirby

![Release](https://flat.badgen.net/packagist/v/bnomei/autoloader-for-kirby?color=ae81ff)
![Downloads](https://flat.badgen.net/packagist/dt/bnomei/autoloader-for-kirby?color=272822)
[![Twitter](https://flat.badgen.net/badge/twitter/bnomei?color=66d9ef)](https://twitter.com/bnomei)

Helper Class to automatically load various Kirby extensions in a plugin

## Commerical Usage

This package is free but if you use it in a commercial project please consider to

- [make a donation 🍻](https://www.paypal.me/bnomei/5) or
- [buy me ☕](https://buymeacoff.ee/bnomei) or
- [buy a Kirby license using this affiliate link](https://a.paddle.com/v2/click/1129/35731?link=1170)

## Installation

```bash
composer require bnomei/kirby3-autoloader-for-kirby
```

> This is NOT a kirby plugin. This is a composer package because that actually makes it easier to setup and does not mess with the loading order of extensions.
### Autoloading of extensions

Add the autoloader for each extension type you want once and it will register all files in subfolders correctly. The following extensions can be autoloaded:

#### Supported Extensions

- [x] blueprints
- [x] collections
- [x] controllers
- [x] models (with registering the class)
- [x] snippets
- [x] templates

#### Roadmap

- [ ] translastions

**/site/plugins/example/index.php**
```php
<?php

Kirby::plugin('bnomei/example', [
'options' => [
// options
],
'blueprints' => autoloader(__DIR__)->blueprints(),
'collections' => autoloader(__DIR__)->collections(),
'controllers' => autoloader(__DIR__)->controllers(),
'models' => autoloader(__DIR__)->models(),
'snippets' => autoloader(__DIR__)->snippets(),
'templates' => autoloader(__DIR__)->templates(),
// other extensions
]);
```

## Disclaimer

This package is provided "as is" with no guarantee. Use it at your own risk and always test it yourself before using it in a production environment. If you find any issues, please [create a new issue](https://github.com/bnomei/autoloader-for-kirby/issues/new).

## License

[MIT](https://opensource.org/licenses/MIT)

It is discouraged to use this package in any project that promotes racism, sexism, homophobia, animal abuse, violence or any other form of hate speech.
207 changes: 207 additions & 0 deletions classes/Autoloader.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
<?php

declare(strict_types=1);

namespace Bnomei;

use Symfony\Component\Finder\Finder;

final class Autoloader
{
// exclude files like filename.config.(php|yml)
public const PHP = '/^[\w\d\-\_]+\.php$/';
public const YML = '/^[\w\d\-\_]+\.yml$/';
public const PHP_OR_YML = '/^[\w\d\-\_]+\.(php|yml)$/';

/** @var self */
private static $singleton;

/** @var array */
private $options;

/** @var array */
private $registry;

public function __construct(array $options = [])
{
$this->options = array_merge_recursive([
'blueprints' => [
'folder' => 'blueprints',
'name' => static::PHP_OR_YML,
'key' => 'relativepath',
'require' => false,
],
'collections' => [
'folder' => 'collections',
'name' => static::PHP,
'key' => 'relativepath',
'require' => true,
],
'controllers' => [
'folder' => 'controllers',
'name' => static::PHP,
'key' => 'filename',
'require' => true,
],
'models' => [
'folder' => 'models',
'name' => static::PHP,
'key' => 'classname',
'require' => false,
],
'snippets' => [
'folder' => 'snippets',
'name' => static::PHP,
'key' => 'relativepath',
'require' => false,
],
'templates' => [
'folder' => 'templates',
'name' => static::PHP,
'key' => 'filename',
'require' => false,
],
/* TODO: translations
'translations' => [
'folder' => 'translations',
'name' => static::PHP,
'key' => 'relativepath',
'require' => true,
],
*/
], $options);

if (!array_key_exists('dir', $this->options)) {
throw new \Exception("Autoloader needs a directory to start scanning at.");
}

$this->registry = [];
}

private function registry(string $type): array
{
// only register once
if (array_key_exists($type, $this->registry)) {
return $this->registry[$type];
}

$options = $this->options[$type];

$this->registry[$type] = [];
$finder = (new Finder())->files()
->name($options['name'])
->in($this->options['dir'] . '/' . $options['folder']);

foreach ($finder as $file) {
$key = '';
$class = '';
$split = explode('.', $file->getPathname());
$extension = array_pop($split);
if ($options['key'] === 'relativepath') {
$key = $file->getRelativePathname();
$key = strtolower(str_replace('.' . $extension, '', $key));
} elseif ($options['key'] === 'filename') {
$key = basename($file->getRelativePathname());
$key = strtolower(str_replace('.' . $extension, '', $key));
} elseif ($options['key'] === 'classname') {
$key = basename($file->getRelativePathname());
$key = str_replace('.' . $extension, '', $key);
$class = $key;
$key = strtolower($key);
if ($classFile = file_get_contents($file->getPathname())) {
if (preg_match('/^namespace (.*);$/im', $classFile, $matches) === 1) {
$class = $matches[1] . '\\' . $class;
}
$this->load([
$class => $file->getRelativePathname(),
], $this->options['dir'] . '/' . $options['folder']);
}
$pageAt = strpos('Page', $key);
if ($pageAt === strlen($key) - 4) {
$key = substr($key, 0, -4);
}
}
if (empty($key)) {
continue;
}

if ($options['key'] === 'classname') {
$this->registry[$type][$key] = $class;
} elseif ($options['require'] && $extension && strtolower($extension) === 'php') {
$path = $file->getPathname();
$this->registry[$type][$key] = require_once $path;
} else {
$this->registry[$type][$key] = $file->getRealPath();
}
}

return $this->registry[$type];
}

public function blueprints(): array
{
return $this->registry('blueprints');
}

public function collections(): array
{
return $this->registry('collections');
}

public function controllers(): array
{
return $this->registry('controllers');
}

public function models(): array
{
return $this->registry('models');
}

public function snippets(): array
{
return $this->registry('snippets');
}

public function templates(): array
{
return $this->registry('templates');
}

public static function singleton(array $options = []): self
{
if (self::$singleton) {
return self::$singleton;
}
self::$singleton = new self($options);
return self::$singleton;
}

// https://github.com/getkirby/kirby/blob/c77ccb82944b5fa0e3a453b4e203bd697e96330d/config/helpers.php#L505
/**
* A super simple class autoloader
*
* @param array $classmap
* @param string $base
* @return void
*/
private function load(array $classmap, string $base = null)
{
// convert all classnames to lowercase
$classmap = array_change_key_case($classmap);

spl_autoload_register(function ($class) use ($classmap, $base) {
$class = strtolower($class);

if (!isset($classmap[$class])) {
return false;
}

if ($base) {
include $base . '/' . $classmap[$class];
} else {
include $classmap[$class];
}
});
}
}
Loading

0 comments on commit 3989108

Please sign in to comment.