- Programatically modify php files with an intuitive top level read/write API
- Read/write on classes, framework- and language constructs using
FileQueryBuilders
andAbstractSyntaxTreeQueryBuilders
composer require ajthinking/archetype
That's it! Check out introduction of concepts below or review the API examples
use Archetype\Facades\PHPFile;
// Create new files
PHPFile::make()->class(\Acme\Product::class)
->use('Shippable')
->public()->property('stock', -1)
->save();
// Modify existing files
PHPFile::load(\App\Models\User::class)
->className('NewClassName')
->save();
use Archetype\Facades\LaravelFile; // extends PHPFile
// Expanding on our User model
LaravelFile::user()
->add()->use(['App\Traits\Dumpable', 'App\Contracts\PlayerInterface'])
->add()->implements('PlayerInterface')
->table('gdpr_users')
->add()->fillable('nickname')
->remove()->hidden()
->empty()->casts()
->hasMany('App\Game')
->belongsTo('App\Guild')
->save()
->render();
Show output
<?php
namespace App\Models;
use App\Contracts\PlayerInterface;
use App\Traits\Dumpable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable implements PlayerInterface
{
use HasApiTokens, HasFactory, Notifiable;
protected $table = 'gdpr_users';
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'name',
'email',
'password',
'nickname',
];
/**
* The attributes that should be cast.
*
* @var array<string, string>
*/
protected $casts = [];
/**
* Get the associated Guild
*/
public function guild()
{
return $this->belongsTo(Guild::class);
}
/**
* Get the associated Games
*/
public function games()
{
return $this->hasMany(Game::class);
}
}
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();
// ...
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
->classMethod()
->where('name->name', 'up')
->staticCall()
->where('class', 'Schema')
->where('name->name', 'create')
->args
->closure()
->stmts
->methodCall()
->where('var->name', 'table')
->args
->value
->value
->get();
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.
- Traverse into nodes by using methods (
method()
,staticCall()
...) - Traverse into node properties by accessing properties (
args
,stmts
...) - Filter results with
where(...)
- Resolving matching paths with
get()
ASTQueryBuilder
also supports removing, replacing and injecting nodes ๐ง
// Replace a node property
$file->astQuery()
->class()
->name
->replaceProperty('name', $newClassName)
->commit() // updates the file's AST
->end() // exit query
->save()
If a file can't be parsed, a FileParseError
will be thrown. This can happen if you try to explicitly load a broken file but also when performing queries matching one or more 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
.
php artisan vendor:publish --provider="Archetype\ServiceProvider"
- UNIX filesystem
- PHP >= 7.4
- Laravel >= 7
PRs and issues are welcome ๐ Feel free to take a stab at an incomplete test.
git clone [email protected]:ajthinking/archetype.git
cd archetype
composer install
./vendor/bin/pest
MIT
- Built with nikic/php-parser
- PSR Printing fixes borrowed from tcopestake/PHP-Parser-PSR-2-pretty-printer
archetype's People
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. ๐๐๐
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google โค๏ธ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.