Package Data | |
---|---|
Maintainer Username: | ajthinking |
Maintainer Contact: | jurisoo@hotmail.com (Anders Jürisoo) |
Package Create Date: | 2020-01-03 |
Package Last Update: | 2024-05-11 |
Home Page: | |
Language: | PHP |
License: | MIT |
Last Refreshed: | 2024-11-17 03:08:28 |
Package Statistics | |
---|---|
Total Downloads: | 1,842,354 |
Monthly Downloads: | 56,916 |
Daily Downloads: | 918 |
Total Stars: | 256 |
Total Watchers: | 4 |
Total Forks: | 19 |
Total Open Issues: | 2 |
php::archetype
(:fire::fire::fire:);
PHPFile
s and LaravelFile
s with an intuiutive top level read/write APIFileQueryBuilders
and AbstractSyntaxTreeQueryBuilders
Snippet
s with an inline PHP Template enginecomposer require ajthinking/archetype
Requires UNIX filesystem, PHP >= 7 and Laravel >= 7
PHPFile
read/write APIuse PHPFile;
// Create new files
PHPFile::make()->class('acme/Product.php')
->use('Shippable')
->add()->trait('Acme\Traits\Shippable')
->public()->property('stock', -1)
->save();
// Modify existing files
PHPFile::load('app/Models/User.php')
->className('NewClassName')
->save();
LaravelFile
read/write APIuse LaravelFile; // extends PHPFile
// Expanding on our User model
LaravelFile::user()
->add()->use(['App\Traits\Dumpable', 'App\Contracts\PlayerInterface'])
->add()->implements('PlayerInterface')
->add()->trait('Dumpable')
->table('gdpr_users')
->add()->fillable('nickname')
->remove()->hidden()
->empty()->casts()
->hasMany('App\Game')
->belongsTo('App\Guild')
->save();
Result:
Review full API documentation here :point_left:
Filter and retrieve a set of files to interact with.
// find files with the query builder
PHPFile::in('database/migrations')
->where('extends', 'Migration')
->andWhere('className', 'like', 'Create')
->get() // returns Collection of PHPFiles
// Quickly find the Laravel User file
$file = LaravelFile::user();
// Quickly find Laravel specific files
LaravelFile::models()->get();
LaravelFile::controllers()->get();
LaravelFile::serviceProviders()->get();
// ...
See a few more QueryBuilder examples in the tests :point_left:
As seen in the previous examples we can query and manipulate nodes with simple or primitive values, such as strings and arrays. However, if we want to perform custom or more in dept queries we must use the ASTQueryBuilder
.
Example: how can we fetch explicit column names in a migration file?
LaravelFile::load('database/migrations/2014_10_12_000000_create_users_table.php')
->astQuery() // get a ASTQueryBuilder
->method()
->where('name->name', 'up')
->staticCall()
->where('class', 'Schema')
->where('name->name', 'create')
->args
->closure()
->stmts
->methodCall()
->where('var->name', 'table')
->args
->value
->value
->get(); // exit ASTQueryBuilder, get a Collection
The ASTQueryBuilder examines all possible paths and automatically terminates those that cant complete the query:
The ASTQueryBuilder relies entirely on nikic/php-parser. Available query methods mirror the PhpParser
types and properties. To understand this syntax better you may want to tinker with dd($file->ast())
while building your queries. Basic conventions are listed below.
method()
,staticCall()
...)args
,stmts
...)where(...)
get()
ASTQueryBuilder
also supports removing, replacing and injecting nodes :wrench:
// Replace a node property
$file->astQuery()
->class()
->name
->replaceProperty('name', $newClassName)
->commit() // updates the file's AST
->end() // exit query
->save()
More ASTQueryBuilder examples here :point_left:
Use the LaravelSchema
class to get an app schema.
use Archetype\Schema\LaravelSchema;
LaravelSchema::get();
{
"entities": [
{
"model": "App\\User",
"table": "users",
"columns": {
"id": {
"name": "id",
"type": {},
"default": null,
"notnull": true,
"length": null,
"precision": 10,
"scale": 0,
"fixed": false,
"unsigned": false,
"autoincrement": true,
"columnDefinition": null,
"comment": null
},
"name": {
"name": "name",
"type": {},
"default": null,
"notnull": true,
"length": null,
"precision": 10,
"scale": 0,
"fixed": false,
"unsigned": false,
"autoincrement": false,
"columnDefinition": null,
"comment": null,
"collation": "BINARY"
}
}
}
],
"strategy_used": "Archetype\\Schema\\Strategies\\FromDatabase",
"log": []
}
Schema feature is under construction ⚠
Let's make a snippet for a method we want to insert. Start by creating a file storage/archetype/snippets/my-stuff.php
like shown below. In the file, we put our template code including any encapsuling constructs (in our case we will have to put a class since methods only exists inside classes). Name anything you want to be configurable with a handle for instance '___TARGET_CLASS___'
. Even your snippet name itself may be a handle as long as it is unique.
<?php
/**
* Optionally use FAKE names to silence IDE warnings
*/
use Archetype\Support\FakeName;
use Archetype\Support\FakeName as ANY;
use Archetype\Support\FakeName as ___TARGET_CLASS___;
/**
* This is just a placeholder class where we can add our snippets
*/
class _ extends FakeName
{
/**
* ___DOC_BLOCK___
*/
public function mySpecialMethod($arg)
{
$want = abs($arg);
return $this->doSomethingWith(___TARGET_CLASS___::class, 'my template')
->use(ANY::thing(new static('you' . $want)));
}
}
Your snippet is then instantly available anywhere in your code:
use Archetype\Support\Snippet;
// Get the snippet
Snippet::mySpecialMethod()
// Pass an array of replacement pairs to replace any handles:
Snippet::mySpecialMethod([
'___DOC_BLOCK___' => 'Inserted with archetype :)',
'___TARGET_CLASS___' => 'App\Rocket'
]);
// Integrated example
PHPFile::load('app/Models/User.php')
->addMethod(
Snippet::mySpecialMethod([
// replacement pairs ...
])
)->save();
:information_source: The
Snippet
class currently only supports templates on class methods.
You may use either of the following
// Using class
(new \Archetype\PHPFile)->load('...');
// Using facade
PHPFile::load('...');
// Using facade explicitly
use Archetype\Facades\PHPFile;
PHPFile::load('...'); // Using facade explicitly
If a file can't be parsed, a FileParseError
will be thrown. This can happen if you try to explicitly load the file but also when performing queries matching problematic files.
To see all offending files run php artisan archetype:errors
. To ignore files with problems, put them in config/archetype.php
-> ignored_paths
.
In general this package assumes code to be parsed follows guidellines and conventions from PSR and Laravel. Some examples are listed below.
Requires UNIX based file system - no windows support
Can't use group use syntax (use Something\{X, Y};
)
Assumes one class per file
Assumes no multiple/grouped property declarations (protected $a, $b = 1;
)
php artisan vendor:publish --provider="Archetype\ServiceProvider"
git clone git@github.com:ajthinking/archetype.git
cd archetype
composer install
./vendor/bin/phpunit tests
MIT
Star it :star: