andy87 / yii2-file-crafter
PHP library for Yii2 - developed by and_y87
Requires
- php: >=8.0
- ext-json: *
Requires (Dev)
- phpunit/phpunit: ^10.5
- symfony/browser-kit: ^6.0
- symfony/dom-crawler: ^6.0
- yiisoft/yii2: ~2.0.45
- yiisoft/yii2-gii: ~2.2.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
- dev-master
- 1.2.1
- 1.0.0
- dev-fix/empty-command
- dev-fix/migration-identifiers
- dev-fix/regression-ci
- dev-fix/database-portability
- dev-fix/migration-php-literals
- dev-fix/event-payloads
- dev-fix/command-results
- dev-fix/schema-rename-data-loss
- dev-fix/panel-html-encoding
- dev-fix/csrf-before-write
- dev-fix/cache-deletion-security
- dev-fix/migration-data-loss
- dev-examples
- dev-unitTests
This package is auto-updated.
Last update: 2026-10-29 13:52:43 UTC
README
Languages / Языки: English | Русский | 简体中文 | Português (Brasil) | Español | 日本語 | Қазақша | Français | Deutsch
Code examples and interface labels remain in English in all translations.
Yii2 File Crafter is a Gii generator for creating files from reusable templates and named schemas.
Contents
Setup
Requirements: PHP 8.0 or newer, a Yii 2 application, and yiisoft/yii2-gii.
Install File Crafter and Gii as development dependencies in the application:
composer require --dev andy87/yii2-file-crafter:dev-master "yiisoft/yii2-gii:^2.2.7"
For a local Composer installation, replace composer with php composer.phar.
Alternatively, merge these entries into the application's existing composer.json:
{
"require-dev": {
"andy87/yii2-file-crafter": "dev-master",
"yiisoft/yii2-gii": "^2.2.7"
}
}
Then run:
composer update andy87/yii2-file-crafter yiisoft/yii2-gii
Gii must be installed in the application: Composer does not install the
require-dev dependencies of dependency packages. See the
Composer documentation and
Gii installation guide.
Config and Quick Start
The examples use $config for the application's configuration array. In a Basic
application, add the minimum configuration inside the existing if (YII_ENV_DEV)
block in config/web.php, before return $config. In an Advanced application,
merge the same entries into the development configuration of the application
that serves Gii, for example backend/config/main-local.php.
Keep Gii in bootstrap only once if the application already enables it.
Minimum configuration (generates a service file without a migration):
$config['bootstrap'][] = 'gii'; $config['modules']['gii'] = [ 'class' => yii\gii\Module::class, 'generators' => [ 'fileCrafter' => [ 'class' => andy87\yii2\file_crafter\Crafter::class, 'options' => [ 'source' => ['dir' => '@app/templates/file-crafter', 'ext' => '.tpl'], 'migration' => false, 'templates' => [ 'default' => [ 'service' => '@app/services/{{PascalCase}}Service.php', ], ], ], ], ], ];
Create templates/file-crafter/service.tpl under the application's base directory:
<?php
namespace app\services;
/** Service for {{PascalCase}} records. */
class {{PascalCase}}Service
{
}
- Open
http://localhost/index.php?r=gii/fileCrafter, adjusting the host and entry-script path for the application. - Enter
Product Itemsin Schema name and click Create. Database attributes can be left empty for this template. - Select the
defaulttemplate group and the saved schema, then click Preview. - Check the proposed
services/ProductItemsService.php, keep it selected, and click Generate.
The resulting file contains:
<?php namespace app\services; /** Service for ProductItems records. */ class ProductItemsService { }
@app refers to the selected application's base directory. Aliases such as
@backend and @frontend require an Advanced application or explicit alias
configuration; the Quick Start does not depend on them.
The following alternative configuration shows every File Crafter option. Create
the referenced templates before selecting their group. The commands and
eventHandler options are explained below.
$config['bootstrap'][] = 'gii'; $config['modules']['gii'] = [ 'class' => yii\gii\Module::class, 'generators' => [ 'fileCrafter' => [ 'class' => andy87\yii2\file_crafter\Crafter::class, 'options' => [ 'cache' => ['dir' => '@app/runtime/yii2-file-crafter/cache', 'ext' => '.json'], 'source' => ['dir' => '@app/templates/file-crafter', 'ext' => '.tpl'], 'custom_fields' => ['singular' => 'Singular name', 'plural' => 'Plural name'], 'commands' => [], 'eventHandler' => null, 'autoCompleteStatus' => true, 'autoCompleteList' => ['Product Items', 'Category Group'], 'previewStatus' => true, 'canDelete' => true, 'parseDataBase' => ['autocomplete', 'fakeCache'], 'migration' => [ 'root' => '@app/migrations', 'fileName' => '_file_crafter_migration_%s', 'template' => '@vendor/andy87/yii2-file-crafter/src/components/templates/migration.php', ], 'templates' => [ 'default' => ['service' => '@app/services/{{PascalCase}}Service.php'], 'views' => ['view.php' => '@app/views/{{snake_case}}/index.php'], 'all' => [ 'service' => '@app/services/{{PascalCase}}Service.php', 'view.php' => '@app/views/{{snake_case}}/index.php', ], ], ], ], ], ];
Migrations
Unless migration is false, a create-table migration is generated for each
selected schema. Applying it to an existing table raises an error. The existing
table and its data are preserved. Changes to existing tables require an explicit migration
using Yii's column and index operations. Generated migrations are not applied
automatically.
The migration settings shown in the full configuration are the defaults:
root: output directory, resolved through Yii aliases.fileName: suffix pattern;%sis replaced with the schema's table name. A migration timestamp prefix and.phpextension are added automatically.template: PHP template used to render the migration.
All option examples below modify the minimum configuration above. To disable migrations:
$config['modules']['gii']['generators']['fileCrafter']['options']['migration'] = false;
Options and templates
Working with schemas
Create a schema with Create. Select the edit icon to change or rename a
saved schema, and use the delete button to remove it when canDelete is enabled.
The schema name is converted to a lowercase table name: spaces become
underscores and characters other than ASCII letters, digits, underscores and
whitespace are removed. Saved schemas are JSON files in the configured cache
directory; retain those files when moving the application or clearing its runtime.
The panel supports selecting multiple schemas and selecting all at once. An empty schema selection causes the generator to process all available schemas. Preview shows the proposed files; Generate writes the selected files. A missing source template is skipped, so verify the source path if an expected file is absent.
Database fields and imports
Add, remove and reorder fields in the schema editor. Each field has a name,
comment, type, size and FK, UN and NN flags. UN means unique and NN
means not null. The FK flag alone does not define a foreign-key constraint;
the referenced table and columns must be present in the schema's foreign-key
metadata. Field names can suggest a type and flags, which should be reviewed.
The field type selector offers string, int, boolean, text, timestamp, datetime,
date, time, json, float, double, decimal, jsonb, binary, money, smallint, bigint,
char, varchar, tinyint, enum and set. Database support varies by type and driver.
The regression suite exercises SQLite and MySQL; it does not establish support
for every type on every database.
parseDataBase can add table names to autocomplete or show database-derived
schemas with fakeCache. The latter are displayed without creating JSON cache
files and cannot be deleted through the panel. Database autocomplete requires
autoCompleteStatus to be enabled.
Applying and customising migrations
Generated migrations must be reviewed and applied through the application's Yii
migration commands. The generated safeDown() drops the created table; review
the data-loss impact before rolling a migration back. A custom migration template
can use {{migrationClass}} and {{tableName}} along with the schema and generator
objects. Imported primary keys, foreign keys and indexes are stored in schema
metadata; individual field flags do not supply a referenced table or columns.
The command result includes output and resultCode. A non-zero command exit code
is reported but does not by itself stop generation of configured templates.
- Marks
- Cache
- Source
- Templates
- Custom fields
- Autocomplete status
- Autocomplete list
- Preview status
- Can delete
- Parse database
- Commands
- Events
Marks
Marks are replaced in template contents, paths and commands. Use double braces
with the exact spelling shown below. For a schema named Product Items:
| Mark | Result |
|---|---|
{{PascalCase}} |
ProductItems |
{{camelCase}} |
productItems |
{{snake_case}} |
product_items |
{{kebab-case}} |
product-items |
{{UPPERCASE}} |
PRODUCT_ITEMS |
{{lowercase}} |
product_items |
Uppercase and lowercase use the normalized table name, including underscores.
Custom fields use the same syntax, for example {{singular}}; see
Custom fields.
Unknown marks are left unchanged, so check filenames in Preview.
Cache
Schemas are stored as JSON files. Default cache settings:
$config['modules']['gii']['generators']['fileCrafter']['options']['cache'] = [ 'dir' => '@app/runtime/yii2-file-crafter/cache', 'ext' => '.json', ];
Source
Default source settings (the Quick Start overrides dir):
$config['modules']['gii']['generators']['fileCrafter']['options']['source'] = [ 'dir' => '@app/runtime/yii2-file-crafter/templates/source', 'ext' => '.tpl', ];
Templates
templates maps group names to arrays of source-template paths and output paths:
$config['modules']['gii']['generators']['fileCrafter']['options']['templates'] = [ 'group1' => [ 'service' => '@app/services/{{PascalCase}}Service.php', ], 'group2' => [ 'view.php' => '@app/views/{{snake_case}}/index.php', '@app/templates/file-crafter/service.tpl' => 'services/{{PascalCase}}Service.php', ], ];
Select the required group in Gii before Preview.
- Relative source paths start at
source['dir']; paths beginning with a Yii alias use that alias. A source path without an extension receivessource['ext'], which defaults to.tpl. - Relative output paths start at
@app. Specify the desired extension explicitly; no extension is added to ordinary template output paths. - Both paths may contain marks.
A regular .tpl file is read as text and then its marks are replaced. PHP inside
it is copied into the output, as in the Quick Start. PHP templates are rendered
with yii\web\View::renderFile and receive $schema and $generator; mark
replacement follows rendering. The current implementation selects PHP rendering
when the source path contains .php, so keep text templates outside directories
whose names contain .php.
For example, templates/file-crafter/view.php can contain:
<?php /** @var andy87\yii2\file_crafter\components\models\Schema $schema Schema being generated. */ /** @var andy87\yii2\file_crafter\Crafter $generator Active generator. */ echo $schema->getName() . ' from ' . $generator->getName();
For Product Items, the output is:
Product Items from File Crafter
Custom fields
The keys define custom marks; the values define labels in the schema editor:
$config['modules']['gii']['generators']['fileCrafter']['options']['custom_fields'] = [ 'singular' => 'Singular name', 'plural' => 'Plural name', ];
For schema Product Items, enter product in Singular name and products
in Plural name. A text template can use these values:
Item: {{singular}}
List: {{plural}}
Result:
Item: product
List: products
Autocomplete status
autoCompleteStatus enables built-in, custom and database suggestions for Schema name. Default: false.
$config['modules']['gii']['generators']['fileCrafter']['options']['autoCompleteStatus'] = true;
Autocomplete list
autoCompleteList supplies custom schema-name suggestions when autoCompleteStatus is true. Default: an empty array.
$config['modules']['gii']['generators']['fileCrafter']['options']['autoCompleteList'] = [ 'Product Items', 'Category Group', 'User Profile', ];
Preview status
previewStatus enables the schema-content preview shown on icon hover. Default: true.
$config['modules']['gii']['generators']['fileCrafter']['options']['previewStatus'] = true;
Can delete
canDelete controls schema deletion from the panel. Default: true.
$config['modules']['gii']['generators']['fileCrafter']['options']['canDelete'] = true;
Parse database
parseDataBase imports table names into suggestions (autocomplete) and/or
database-derived schemas into the panel (fakeCache). Default: an empty array.
These options require a configured db application component.
$config['modules']['gii']['generators']['fileCrafter']['options']['parseDataBase'] = ['autocomplete', 'fakeCache'];
Commands
commands is a list of CLI commands with mark
replacement. Default: an empty array. Commands run for each selected schema on
an explicit Generate submission with selected files, before rendering its
configured templates. Preview never executes them.
For an application with the Gii console module configured, an existing table
and a common\models namespace, this command generates its ActiveRecord model:
$config['modules']['gii']['generators']['fileCrafter']['options']['commands'] = [ 'php yii gii/model --tableName={{snake_case}} --modelClass={{PascalCase}} --ns="common\models" --interactive=0', ];
Commands run in the PHP process's working directory. Adjust the PHP executable, console entry-script path and namespace for the application. Commands can modify files independently of the files selected in Gii.
Events
eventHandler attaches a Yii behavior to the generator. Default: null.
Create components/behaviors/FileCrafterBehavior.php in the application:
<?php namespace app\components\behaviors; use Yii; use yii\base\Behavior; use andy87\yii2\file_crafter\components\events\{CrafterEvent, CrafterEventCommand, CrafterEventGenerate, CrafterEventRender}; /** Records generator events without changing generated files or commands. */ class FileCrafterBehavior extends Behavior { /** @return array Event names mapped to their handlers. */ public function events(): array { return [ CrafterEvent::BEFORE_INIT => 'onInit', CrafterEvent::AFTER_INIT => 'onInit', CrafterEventGenerate::BEFORE => 'onGenerate', CrafterEventGenerate::AFTER => 'onGenerate', CrafterEventCommand::BEFORE => 'onCommand', CrafterEventCommand::AFTER => 'onCommand', CrafterEventRender::BEFORE => 'onRender', CrafterEventRender::AFTER => 'onRender', ]; } /** * Record generator initialization. * @param CrafterEvent $event Initialization event with the active options. * @return void */ public function onInit(CrafterEvent $event): void { Yii::info($event->name, __METHOD__); } /** * Record the input schemas before generation and the output files afterwards. * @param CrafterEventGenerate $event Generation event and its current payload. * @return void */ public function onGenerate(CrafterEventGenerate $event): void { Yii::info([$event->name, $event->listSchemaDto, $event->files], __METHOD__); } /** * Record the command before execution and its output afterwards. * @param CrafterEventCommand $event Command event containing a Cmd object. * @return void */ public function onCommand(CrafterEventCommand $event): void { Yii::info([$event->name, $event->cmd->exec, $event->cmd->output, $event->cmd->replaceList], __METHOD__); } /** * Record template paths before rendering and the generated content afterwards. * @param CrafterEventRender $event Render event for one schema and template. * @return void */ public function onRender(CrafterEventRender $event): void { Yii::info([$event->name, $event->schema, $event->sourcePath, $event->generatePath, $event->replaceList, $event->content], __METHOD__); } }
Enable the behavior in the minimum configuration:
$config['modules']['gii']['generators']['fileCrafter']['options']['eventHandler'] = app\components\behaviors\FileCrafterBehavior::class;
In an Advanced application, adjust the behavior's namespace and configuration
to match its location, for example backend\components\behaviors.
The events() map is required: handler method names alone do not subscribe to events.
All events expose options. Before generation, the event contains listSchemaDto
and the resolved generateList; handlers can change the selected table names.
After generation, the event contains files (yii\gii\CodeFile[]).
Render events expose schema, sourcePath, generatePath, replaceList and
content; content is populated after rendering.
Command events expose cmd, an instance of
andy87\yii2\file_crafter\components\models\dto\Cmd:
exec(string): command after mark replacement.output(?string):nullbefore execution, command output afterwards.replaceList(array): mark replacement map for the schema.
Schema editing and generation
The schema editor accepts enum/set values as a JSON array of strings, for example
["draft", "published", "owner's"]. Invalid lists are reported before saving the
schema. Legacy invalid schemas are reported in Preview instead of causing an exception.
Preview never runs configured CLI commands. Commands run only for an explicit Generate submission with selected files. Migration filenames retain the timestamp submitted by the preview form, including when Generate happens in a later minute.
Database imports retain primary and foreign keys, referential actions, indexes, decimal scale, auto-increment, unsigned flags and column defaults in the cached schema. Foreign keys are created with the table; referenced tables must already exist. As with all generated migrations, review the result before applying it.
Tests
The PHPUnit development dependencies require PHP 8.1 or newer and the dom, mbstring and pdo_sqlite extensions.
Run these commands from a clone of this repository:
composer update --prefer-stable --prefer-dist
composer test
To check only the README:
composer test:docs
The documentation tests read examples directly from this file. They check PHP syntax, generator configuration, the Quick Start's Preview/Generate flow, template rendering, marks, event subscriptions, unique section anchors and internal links. They do not execute the documented application-specific CLI commands or request external websites.
The default suite uses temporary files and an in-memory SQLite database. To enable the MySQL regression test, provide a disposable test database and the pdo_mysql extension:
FILE_CRAFTER_TEST_MYSQL_DSN='mysql:host=127.0.0.1;port=3306;dbname=file_crafter_test' \
FILE_CRAFTER_TEST_MYSQL_USER=root \
FILE_CRAFTER_TEST_MYSQL_PASSWORD=test-password \
vendor/bin/phpunit --fail-on-warning --fail-on-risky --fail-on-incomplete --fail-on-skipped
The MySQL tests create and remove only their own randomly named tables. They check imported keys, decimal values, defaults and constraint enforcement. Gii controller tests cover isolated generator mutations, repeated Preview, migration selection across a minute boundary, and enum/set form validation. CI runs the suite, including the README checks, on PHP 8.1, 8.2, 8.4 and 8.5 with MySQL 8.4, and checks PHP 8.0 syntax separately.