ajthinking/archetype
Archetype is a Laravel code generation package that lets you define models, migrations, controllers and more through a fluent PHP API, then scaffolds the files instantly—speeding up new features and project setup.
Maintenance only. No API changes — nothing here can break existing usage.
v2.0.0 shipped the php-parser 5 port in May 2024 having never been tested against any PHP or Laravel version currently in use: the CI matrix still targeted PHP 7.4/8.0 with Laravel 6/7/8, and hadn't run since. The package worked; there was just no evidence of it. This release supplies the evidence and fixes what turned up along the way.
| Archetype | PHP | Laravel | php-parser |
|---|---|---|---|
| 2.x | 8.1–8.4 | 10, 11, 12, 13 | ^5.0 |
| 1.x | 7.4–8.1 | 6–9 | ^4.11 |
Verified across twelve PHP × Laravel combinations in CI, plus macOS and PHPStan. Laravel 13 is included because statamic/cms 6 already allows it, so people were running Archetype there untested.
->throw() had matched nothing since 2.0.0. php-parser 5 removed Stmt\Throw_ and the class map still pointed at it. Now maps to Expr\Throw_, with a regression test.getReflection() caught Exception instead of Throwable. A file whose parent class or trait can't be autoloaded raises an Error, which escaped and killed the whole query rather than skipping that one file. Affects LaravelFile::models(), controllers() and serviceProviders().commands_root and controllers_root in the shipped config both pointed at app/HTTP/Controllers.Declares a php requirement for the first time (^8.1). The upper bound is deliberate: PHP 9 removes dynamic properties, which the AST node-identity mechanism still relies on, so Composer declining the install beats handing you a package that fatals.
Also adds the missing LICENSE.md, a changelog, and a Dependabot config.
From 2.0.0 — drop-in, provided you're on PHP 8.1+.
From 1.x — worth doing. 1.x pins nikic/php-parser to ^4.11, which can't coexist with anything needing php-parser 5, Pest 3 and newer included. If Composer refuses to resolve ajthinking/archetype, that's why. No changes to your own code are required.
statamic/cms is the largest consumer, and this release was checked against it specifically. Real installs of Statamic 5 (Laravel 12) and Statamic 6 (Laravel 13) both resolve 2.0.1 and produce byte-identical output to 2.0.0 across every code path Statamic exercises. Statamic 4 and 3.4 pin ^1.0.3 and are unaffected.
Full details in CHANGELOG.md and #87.
Thanks to @jasonvarga ✨
Please see #77 for details.
This feature provides a BuilderFactory instance when passing a closure to insertStmt.
PHPFile::make()->class(\App\Dummy::class)
->astQuery()
->class()
->insertStmt(function(BuilderFactory $builder) {
return $builder->property('someProperty')->getNode();
})
->commit()
->end()
->preview();
When astQuery()->insertStmt(.....) had no matches to operate on, it added the node to the end of the file. This was fixed by adding a guard clause.
withEach methodPHPFile::make() now return a Maker instance. Makers allows creating files from a template, for instance:
PHPFile::make()->file('scripts.php')
PHPFile::make()->class(\App\Car::class)
We can implement a custom maker and attaching it to the property "maker" on the File instance.
File methods no longer rely on obscure __call magic, instead minimal stubs are implemented to explicitly forward calls to the corresponding endpoint class.
Avoid Str macros which may cause segmentation fault in statamic/cms
Fixes bug when creating classes.
Now we can create classes like so:
namespace App;
PHPFile::make()->class(Models\Car::class);
PHPFile::make()->class(\App\Models\Car::class);
PHPFile::make()->class('App\Models\Car');
PHPFile::make()->class('\App\Models\Car');
PHPFile::make()->class('app/Models/Car.php');
all of these will write two app/Models/Car.php.
$astQuery->classMethod('name->name')
$this->file->astQuery()
->class()
->property()
->where->propertyProperty('name->name')->is($key)->get()
->replace(function() {
...
};
get(). Results are evaluated to see if they have results (considered thruty) or empty (falsy).Dumpable proxies on astQueryBuilder for ->dd->something() and ->dump->anotherfromString can allow pseudo phpPHPFile::addMissingTags()->fromString('$hey = 1337')
In order to tighten this package up and consolidate around primary features, we will drop the following incomplete/broken functionality:
Furthermore,
TestablePHPFile facade.TestableAstQueryBuilder facade.remove() ability for class constants.In order to tighten this package up and consolidate around primary features, we will drop the following:
Most of these feature were incomplete or otherwise broken. A side effect of this is we will no longer be depending on doctrine/dbal.
All tests are moved to pest and many uses an internal TestablePHPFile facade.
Better array formatting 🎉 🎉 🎉 Works for newly created, loaded or modified code.
class Finally
{
protected $empty = [];
protected $one = [
'one',
];
protected $moreThanOne = [
'one',
'two',
];
}
Thanks for spotting this @jackmcdade
Fixes an issue with doctrine/dbal
:bug: Fix bug in notInOperator by @ordago
🔒 Allow doctrine/dbal ^2.10 by @WorldSeso7
:white_check_mark: Bump dependecies, typos and test updates
Include nikic/php-parser as a dependency, don't assume it is included elsewhere.
Rename mismatching class name/file name. Fixes #15
Don't use facade aliases which might be unavailable.
Fix class resolving when using archetype schema in remote context
Archetype v0.1.0 :rocket:In the astQuery(), you can now access general classes/objects/structures with ->methodCall() or similar. To enter a property, simply use ->stmts without ()
How can I help you explore Laravel packages today?