Skip to content

Instantly share code, notes, and snippets.

@sebsel
Last active November 5, 2020 09:32
Show Gist options
  • Select an option

  • Save sebsel/3dce47c53ea9785f6ffb07aaa51c35ce to your computer and use it in GitHub Desktop.

Select an option

Save sebsel/3dce47c53ea9785f6ffb07aaa51c35ce to your computer and use it in GitHub Desktop.
Kirby IDE Helper
<?php define('DS', DIRECTORY_SEPARATOR);
// Set this one to your own blueprint root if you changed it.
$blueprint_root = __DIR__ . DS . 'site' . DS . 'blueprints';
// For Kirby 3, see the comment below.
/**
* === Let's build an IDE-helper for Kirby for PHPStorm!
*
* You can create the IDE-helper by putting this file in your project, then run the following command:
* php _ide_helper_generator.php
*
* This will create an _ide_helper_models.php based in your blueprints and an _ide_helper.php based on
* the kirby/extensions/methods.php file (which contains field-methods). TODO: add custom field method-files.
*
* If you change your blueprints, you should run the command again.
*
* You should *NOT* add the resulting php-files to your site with `include` or `require`. They are
* only meant to be analysed by PHPStorm (or any other IDE of your choice).
*
* You could add them to Git, you could add `_ide_helper*` to your .gitignore, up to you!
*
* You can hint your IDE with `/** @var SomeblueprintPage $page * /` in your templates.
*
* Happy IDE-ing!
*/
// Import the Kirby Toolkit to make our life easier
require_once __DIR__ . DS . 'kirby' . DS . 'vendor' . DS . 'getkirby' . DS . 'toolkit' . DS . 'bootstrap.php';
$helperFile = new IDEHelperFile('_ide_helper_models.php');
foreach (dir::read($blueprint_root) as $filename) {
$blueprint = yaml::read($blueprint_root . DS . $filename);
$filename = f::name($filename);
$className = $filename == 'site' ? 'Site' : str::ucfirst($filename) . 'Page extends Page';
if (!isset($blueprint['fields'])) {
$helperFile->addEmpty($className);
continue;
}
foreach (array_keys($blueprint['fields']) as $field) {
$helperFile->add($className, $field, 'Field');
}
}
$helperFile->save();
/**
* Now for Kirby's build in magic methods
*/
$helperFile = new IDEHelperFile('_ide_helper.php');
// Yeah, you can add your Field method-files to this array
$fieldMethodsFiles[] = __DIR__ . DS . 'kirby' . DS . 'extensions' . DS . 'methods.php';
class Field { public static $methods; }
$fieldMethodsReturnTypes = [];
foreach ($fieldMethodsFiles as $methodsFile) {
require_once $methodsFile;
// Just regex them.
preg_match_all(
'/\@return (.*?)\n \*\/\nfield::\$methods\[\'(.*?)\'\]/',
f::read($methodsFile),
$matches,
PREG_SET_ORDER
);
foreach ($matches as $match) {
$return = $match[1];
$method = $match[2];
$fieldMethodsReturnTypes[$method] = $return;
}
}
foreach (field::$methods as $name => $method) {
$func = new ReflectionFunction($method);
$args = array_map(function ($arg) { return $arg->name; }, $func->getParameters());
$return = array_key_exists($name, $fieldMethodsReturnTypes)
? $fieldMethodsReturnTypes[$name] : '';
$helperFile->add('Field', $name, $return, $args);
}
// Also add the v:: validator class
foreach (v::$validators as $name => $validator) {
$func = new ReflectionFunction($validator);
$args = array_map(function ($arg) { return $arg->name; }, $func->getParameters());
$helperFile->add('V', $name, 'boolean', $args, true);
}
$helperFile->save();
/**
* Helpers
*/
class IDEHelperFile {
private $filename;
private $methods = [];
public function __construct($filename)
{
$this->filename = $filename;
}
public function add($class, $method, $return, $args = [], $static = false)
{
$this->methods[$class][$method] = [
'return' => $return,
'static' => $static,
'args' => $args,
];
}
public function addEmpty($class) {
$this->methods[$class] = [];
}
public function save()
{
$helper = "<?php\n";
foreach ($this->methods as $class => $methods) {
$helper .= "\n/**\n";
foreach ($methods as $method => $d) {
$helper .= ' * @method ';
$helper .= $d['static'] ? 'static' : '';
$helper .= $d['return'] . " $method(";
$helper .= $d['args'] ? '$' . implode(', $', $d['args']) : '';
$helper .= ")\n";
}
$helper .= " */\nclass $class {}\n";
}
f::write($this->filename, $helper);
}
}
@Alzy
Copy link

Alzy commented Nov 5, 2020

So if one of my page blueprints was in say site/blueprints/pages/team-member.yml I would say something like:

/** @var $page TeamMemberPage */

<div class="content-wrapper">
    <h1>
        <?= $page->title() ?>
    </h1>

    ...
</div>

I think I'm following.. Just wanna make sure I got a grip on this

@sascha-schieferdecker
Copy link

Only if you really have PHP class named TeamMemberPage. Otherwise use DefaultPage or whatever is listed in _ide_helper_models.php.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment