{"id":15578533,"url":"https://github.com/cathedralcode/builder","last_synced_at":"2025-04-24T02:22:44.935Z","repository":{"id":17353188,"uuid":"20124754","full_name":"CathedralCode/Builder","owner":"CathedralCode","description":"Database layer builder for laminas-db with easy web \u0026 console interfaces","archived":false,"fork":false,"pushed_at":"2023-05-25T20:22:20.000Z","size":725,"stargazers_count":6,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-18T10:23:24.770Z","etag":null,"topics":["laminas","laminas-cli","laminas-code-generator","laminas-db","laminas-mvc","php","php-library","php8"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/CathedralCode.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2014-05-24T07:48:25.000Z","updated_at":"2022-02-23T17:18:44.000Z","dependencies_parsed_at":"2025-04-17T21:55:14.383Z","dependency_job_id":"2021cf23-abfb-4d80-808e-14ed9944020d","html_url":"https://github.com/CathedralCode/Builder","commit_stats":null,"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CathedralCode%2FBuilder","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CathedralCode%2FBuilder/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CathedralCode%2FBuilder/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CathedralCode%2FBuilder/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/CathedralCode","download_url":"https://codeload.github.com/CathedralCode/Builder/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250546453,"owners_count":21448335,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["laminas","laminas-cli","laminas-code-generator","laminas-db","laminas-mvc","php","php-library","php8"],"created_at":"2024-10-02T19:11:21.295Z","updated_at":"2025-04-24T02:22:44.920Z","avatar_url":"https://github.com/CathedralCode.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Cathedral Builder\n\n## Quick Start\n\nThe three steps needed to get up and run assuming you already have laminas running with a database.\n\n### Step 1: Register Static Adapter:\n\nLaminas let's us register the database connection statically for easy reference.\n\nEdit the `bootstrap` method in `Application\\Module.php`:\n\n```php\n/**\n * Bootstrap\n *\n * If you don't have a bootstrap method this one will do.\n *\n * @param MvcEvent $e\n */\npublic function onBootstrap(\\Laminas\\Mvc\\MvcEvent $e): void {\n    // Add this line to register the static method\n    \\Laminas\\Db\\TableGateway\\Feature\\GlobalAdapterFeature::setStaticAdapter($e-\u003egetApplication()-\u003egetServiceManager()-\u003eget('Laminas\\Db\\Adapter\\Adapter'));\n}\n```\n\n### Step 2: Register Builder Module:\n\nTo register Builder is even easier, it just needs to be added to the module array. This enables ui for console and web.\n\nEdit `config/development.config.php`:\n```php\n    // Additional modules to include when in development mode\n    'modules' =\u003e [\n        'Cathedral\\Builder',\n    ],\n\n```\n\nThat's it!\n\nOpen the web interface by using `/builder` as the route.\n\nE.g.: `http://localhost/builder`\n\nOr use it from the command line:\n\n```shell\n# list tables and file status\n$ ./vendor/bin/laminas builder:list\n# build command\n$ ./vendor/bin/laminas builder:build\n```\n\n---\n\n## CURRENTLY SPLITTING\n\nLaminas 3 database layer builder with a simple Web \u0026 Console UI with many great features.\n\nFor a quick list of fixes and changes see [CHANGELOG.md](CHANGELOG.md)\n\nCreates classes based on:\n\n\u003chttp://framework.zend.com/manual/current/en/user-guide/database-and-models.html\u003e\n\n## Requirements\n\n- PHP \\\u003e= 8\n- Laminas 3 (latest master)\n\n## Installing\n\nI’m sure most of you can do this, but those that need a little help.\n\n### With composer\n\nCommand line:\n\n```shell\ncomposer require --dev cathedral/builder\n```\n\nOR edit composer.json manually:\n\nAdd builder to composer.json require:\n\n```json\n    \"require-dev\": {\n        \"cathedral/builder\": \"dev-master\"\n    }\n```\n\nThen update composer:\n\n```\n    $ php composer.phar update\n```\n\n### Post installation (Optional)\n\nEnabling Builder GUI in your `development.config.php` file:\n\n```php\n    return [\n        'modules' =\u003e [\n            // ...\n            'Cathedral\\Builder',\n        ],\n        // ...\n    ];\n```\n\nBuilder GUI has some options to allow you to quickly customise the basic functionality. After Enabling Builder GUI:\n\n1. copy `./vendor/cathedral/builder/config/cathedral-builder.global.php.dist` to `./config/autoload/cathedral-builder.global.php.php`\n2. change settings as desired.\n    - **namespace** - Module where files will be created and the namespace of the\n    created files. Default is `Application`.\n    - **entity_singular** - On/Off switch for this feature.\n    - **singular_ignore** - A | (pipe) delimited list of tables to ignore for EntitySingular.\n\n## Build Your Data Layer\n\nBuilder is only used to generate the classes, after that the classes are only dependent on laminas, so no need to have builder on your production machine as a dependency.\n\n### First things first\n\n* Make sure any custom module is 100% functional before running builder or it will revert back to Application.\n* Using WebUI: check web user has write access to modules `src/{Model,Entity}` folders\n* Using Console: check you have write access to `src/{Model,Entity}` folders\n\n### WebUI\n\n`Open http://yoursite/builder`\n\nIf you want builder to save files to disk the directories for Namespace/Entity\nand Namespace/Model must be writeable by php.\nAnd enjoy.\n\n### Console\n\nAnd just for kicks there is even console support.\nThe console UI uses the same config as the Web UI.\nIn the root of your project run `php index.php` and see the Cathedral options:\n\nGet info with: `php index.php table list`\n\n```\n    Listing of tables\n    basics\n        DataTable     :Ok\n        EntityAbstract:Outdated\n        Entity        :None\n```\n\nGenerate with `build (datatable|abstract|entity|ALL) \u003ctable|ALL\u003e [--write|-w]`\nYou can redirect to a file ` \u003e path/to/file.php`\nOr simple use the -w option and builder does it for you.\n\njust use `build ALL ALL -w`\nand everything's done.\n\n#### Quick console tips\n\n* `builder build -w` # this creates all the files for all the tables\n* `builder build ALL logs -w` # build all files for logs table\n* `builder build datatable ALL -w` # builds the datatable file for all tables\n\n### Custom Builder\n\nUse builder in your own way.\n\n#### Single Table\n\nFigure out what module will house your db code e.g. DBLayer\n\ncreate the Entity \u0026 Model namespace dirs\n(module/DBLayer/src/DBLayer/{Entity|Model}\n\nUse BuilderManager:\n\n    use Cathedral\\Builder\\BuilderManager;\n\nCreate a BuilderManager:\n\n    $buildManager = new BuilderManager('DBLayer', ’mytable');\n\nIf you don’t leave off the table argument you can use the nextTable method to\nloop through all the tables. Handy for batch runs. And probably the most common\nuse.\n\nWith either a table specified or loaded via nextTable, write the files to disk\nor display to screen.\n\n```php\n    //Echo to screen\n    echo $buildManager-\u003egetDataTableCode();\n    echo $buildManager-\u003egetEntityAbstractCode();\n    echo $buildManager-\u003egetEntityCode();\n\n    //Write to file\n    $buildManager-\u003ewriteDataTable();\n    $buildManager-\u003ewriteEntityAbstract();\n    $buildManager-\u003ewriteEntity();\n```\n\nThat's it for the table :)\n\n#### Loop through Tables\n\nHandy for updating classes to new version etc… And for many tables a lot less\npainful then 3 lines of code per tables :)\n\nUse BuilderManager:\n\n    use Cathedral\\Builder\\BuilderManager;\n\nCreate a BuilderManager NO table specified:\n\n    $buildManager = new BuilderManager('DBLayer');\n\nWrite while loop overwriting current DataTable And EntityAbstract, only create\nEntity if not found:\n\n    while ($buildManager-\u003enextTable()) {\n        $buildManager-\u003ewriteDataTable();\n        $buildManager-\u003ewriteEntityAbstract();\n        $buildManager-\u003ewriteEntity();\n    }\n\nThat's it for all tables :)\n\n### Restful\n\nBuilder now has some a simple Restful interface to tables.\n\nSupported so far:\n\n- getList (List tables \u0026 list rows in table)\n- get (individual row from table)\n\nTo get a list of tables use:\n\n    get http://yoursite/builder/rest\n\nresult:\n\n    {\n        \"code\": 401,\n        \"message\": \"Tabels\",\n        \"data\": [\n            \"cities\",\n            \"countries\",\n            \"currencies\",\n            \"settings\",\n            \"users\"\n        ]\n    }\n\nTo list rows in table showing primary key field and value\n\n    get http://yoursite/builder/rest/settings\n\nresult:\n\n    {\n        \"code\": 0,\n        \"message\": \"SettingsTable List\",\n        \"data\": [\n            {\n                \"name\": \"currency\"\n            },\n            {\n                \"name\": \"db_version\"\n            }\n        ]\n    }\n\nList a row:\n\n    get http://yoursite/builder/rest/settings/db_version\n\nresult:\n\n    {\n        \"code\": 0,\n        \"message\": \"Setting\",\n        \"data\": {\n            \"name\": \"db_version\",\n            \"value\": \"1\",\n            \"created\": \"2014-11-08 05:28:31\",\n            \"modified\": null\n        }\n    }\n\n## Features/Conventions (Assumptions)\n\n### EntitySingular\n\nIf a table name is plural, builder will try create the entity as the singular\nversion.\n\nMost **common** plural/singular conventions are supported.\n\nE.g.\n\n    Table countries\n    DataTable: CountriesTable\n    Entity: Country\n\n    Table catches\n    DataTable: CatchesTable\n    Entity: Catch\n\n    Table users\n    DataTable: UsersTable\n    Entity: User\n\n#### Disable\n\nBut if you want you can also disable it totally.\n\n    // First we create a NameManger\n    $nm = new NameManager('Dossier');\n\n    // EntitySingular is enabled by default\n    // To check the status use:\n    if ($nm-\u003eentitySingular()) {\n        // If enabled\n        // To disable it:\n        $nm-\u003eentitySingular(false);\n    } else {\n        // If disabled\n        // To enable it:\n        $nm-\u003eentitySingular(true);\n    }\n\n    // Lets keep it enabled\n    $nm-\u003eentitySingular(true);\n\n#### Ignore List\n\nOr add tables to an ignore list to skip a table or two.\n\n    // But lets tell it that a few tables ending in a plural should be ignored\n    // To reset the ignore list pass FALSE\n    $nm-\u003esetEntitySingularIgnores(false);\n\n    // Now lets add our ignore tables\n    // adding table1s\n    $nm-\u003esetEntitySingularIgnores('table1s');\n\n    // you can add them as an array or | (pipe) delimited string as well\n    $nm-\u003esetEntitySingularIgnores('table1s|table2s');\n    // OR\n    $nm-\u003esetEntitySingularIgnores(['table1s','table2s']);\n\n### Relations\n\nBuilder checks the MySQL info tables to relate tables to one another.\n\nTo get related records either use the table name in plural for referenced tables or the singular for a referenced table.\n\nE.g.: Get the User related to a Group\n\n    ...\n    Table groups which contains users\n    Method: $group-\u003eUser()\n    Entity: User\n    ...\n\nE.g.: Get all Groups related to a User\n\n    ...\n    Method: $user-\u003eGroups()\n    Entities: Group\n    OR\n    Method: $user-\u003eGroups(['active' =\u003e 1])\n    Entities: Group that also have active set to 1\n    ...\n\n### Events\n\nSee Laminas Events: [Laminas-db](https://docs.laminas.dev/laminas-db/table-gateway/)\n\n#### TableGateway LifeCycle Events\n\nWhen the EventFeature is enabled on the TableGateway instance, you may attach to any of the following events, which provide access to the parameters listed.\n\n* **preInitialize** (no parameters)\n* **postInitialize** (no parameters)\n* **preSelect**, with the following parameters:\n  * *select*, with type Laminas\\Db\\Sql\\Select\n* **postSelect**, with the following parameters:\n  * *statement*, with type Laminas\\Db\\Adapter\\Driver\\StatementInterface\n  * *result*, with type Laminas\\Db\\Adapter\\Driver\\ResultInterface\n  * *resultSet*, with type Laminas\\Db\\ResultSet\\ResultSetInterface\n* **preInsert**, with the following parameters:\n  * *insert*, with type Laminas\\Db\\Sql\\Insert\n* **postInsert**, with the following parameters:\n  * *statement* with type Laminas\\Db\\Adapter\\Driver\\StatementInterface\n  * *result* with type Laminas\\Db\\Adapter\\Driver\\ResultInterface\n* **preUpdate**, with the following parameters:\n  * *update*, with type Laminas\\Db\\Sql\\Update\n* **postUpdate**, with the following parameters:\n  * *statement*, with type Laminas\\Db\\Adapter\\Driver\\StatementInterface\n  * *result*, with type Laminas\\Db\\Adapter\\Driver\\ResultInterface\n* **preDelete**, with the following parameters:\n  * *delete*, with type Laminas\\Db\\Sql\\Delete\n* **postDelete**, with the following parameters:\n  * *statement*, with type Laminas\\Db\\Adapter\\Driver\\StatementInterface\n  * *result*, with type Laminas\\Db\\Adapter\\Driver\\ResultInterface\n\nListeners receive a Laminas\\Db\\TableGateway\\Feature\\EventFeature\\TableGatewayEvent instance as an argument. Within the listener, you can retrieve a parameter by name from the event using the following syntax:\n\n#### Examples:\n\nA Quick Example:\n\n```php\n// Create Settings \u0026 User table objects\n$settingaTable = new SettingsTable();\n$usersTable = new UsersTable();\n\n// Two simple select events to see it in action\n$settingaTable-\u003egetEventManager()-\u003eattach('postSelect', function(TableGatewayEvent $event) {\n    Logger::dump($event-\u003egetParam('result')-\u003ecurrent(), 'TableGatewayEvent::Setting', false);\n});\n\n$usersTable-\u003egetEventManager()-\u003eattach('postSelect', function(TableGatewayEvent $event) {\n    Logger::dump($event-\u003egetParam('result')-\u003ecurrent(), 'TableGatewayEvent::User', false);\n});\n\n// More useful, if a user is added we can run some init setup tasks\n$usersTable-\u003egetEventManager()-\u003eattach('postInsert', function (TableGatewayEvent $event) {\n    /** @var ResultInterface $result */\n    $result = $event-\u003egetParam('result');\n    $generatedId = $result-\u003egetGeneratedValue();\n\n    // do something with the generated identifier...\n});\n\n// More useful, if a setting is updated rebuild cache or ...\n$settingaTable-\u003egetEventManager()-\u003eattach('postUpdate', function (TableGatewayEvent $event) {\n    /** @var ResultInterface $result */\n    $result = $event-\u003egetParam('result');\n    $generatedId = $result-\u003egetGeneratedValue();\n\n    // do something with the generated identifier...\n});\n\n$user = $usersTable-\u003egetUser(1);\n$pagination = $settingaTable-\u003egetSetting('pagination');\n$dbVersion = (new Setting())-\u003eget('dbVersion');\n```\n\n## The Generated Files\n\n### Entity\n\nThis files is created for you to add any custom stuff you may want for that table.\nOn a users table it might be a function that formats the full name to some crazy standard.\nSo this file is **NEVER** replaced by the builder.\nSo use it for what ever you need and rest assured the code will not disappear.\n\n### EntityAbstract\n\nThis is the basic Entity file.\nIf newer version of Builder may replace this with fixes/features/etc\nDon't edit this file, your changes will be lost!\n\n### DataTable\n\nBasically this is a TableGateway, it does the database lifting and returns the Entities.\nAgain, Builder checks the version of this and it will be replaced with newer versions.\nDon't edit.\n\n## Requirements: Runtime\n\n### Module \u0026 Directories (Only if you want to write to file)\n\nThe namespace passed to a manger needs to be an existing module.\nIt also needs to have the directories Entity and Model in the `src/{ModuleName}/directory`\n\nThese 2 dirs need to be writeable by your web server\n\nE.G.\n\n    $buildManager = new BuilderManager(‘DBLayer');\n\nWill try create the files in:\n\n`module/DBLayer/src/DBLayer/Entity`\n\n`module/DBLayer/src/DBLayer/Model`\n\n### Global Adapter\n\nBuilder uses the Global Adapter feature\n\nSimplest way to get set it (I'm my opinion) is to modify the Module.php in the\nmodule where the Data object will be created.\n\n`module/DBLayer/Module.php`\n\n    public function onBootstrap(MvcEvent $e) {\n    ...\n      $adapter = $e-\u003egetApplication()\n        -\u003egetServiceManager()\n        -\u003eget('Laminas\\Db\\Adapter\\Adapter');\n\n      \\Laminas\\Db\\TableGateway\\Feature\\GlobalAdapterFeature::setStaticAdapter($adapter);\n    ...\n    }\n\nA make sure that this Module is before any other in the list the use the\nDBLayer.\n\n\n## Tips\n\n### Write Permission Error\n\nTry shell line bellow (replace DBLayer with your data module)\n\n```shell\nsudo chmod -R a+rwX module/DBLayer/src/{Entity,Model}\n```\n\n### Quick console tips\n\n* `builder build -w` # this creates all the files for all the tables\n* `builder build ALL logs -w` # build all files for logs table\n* `builder build datatable ALL -w` # builds the datatable file for all tables\n\n## Feedback\n\nHey, got any ideas or suggestions to help improve this generator let me.\nEmail me \u003ccode@cathedral.co.za\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcathedralcode%2Fbuilder","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcathedralcode%2Fbuilder","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcathedralcode%2Fbuilder/lists"}