PHPackages                             granadaorm/builder - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. granadaorm/builder

ActiveLibrary[Database &amp; ORM](/categories/database)

granadaorm/builder
==================

Class autogeneration for Granada ORM models

1.4.11(2y ago)0129↓100%11MITPHPPHP &gt;=7.2

Since Sep 13Pushed 2y ago1 watchersCompare

[ Source](https://github.com/GranadaORM/Builder)[ Packagist](https://packagist.org/packages/granadaorm/builder)[ Docs](https://github.com/GranadaORM/Builder)[ RSS](/packages/granadaorm-builder/feed)WikiDiscussions master Synced today

READMEChangelog (10)Dependencies (5)Versions (28)Used By (1)

Builder
=======

[](#builder)

[![Latest Stable Version](https://camo.githubusercontent.com/02cfc2e7b870a757b0dac6b079047068f759eee689b98cd0e2c52947995a591e/68747470733a2f2f706f7365722e707567782e6f72672f6772616e6164616f726d2f6275696c6465722f762f737461626c652e706e67)](https://packagist.org/packages/granadaorm/builder)[![Build Status](https://github.com/GranadaORM/Builder/actions/workflows/ci.yml/badge.svg)](https://github.com/GranadaORM/Builder/actions/workflows/ci.yml/badge.svg)

Class builder for models and controllers for the Granada ORM

Installation
------------

[](#installation)

Install easily with composer:

`composer require granadaorm/builder`

I highly recommend getting the form component instead, which also pulls builder:

`composer require granadaorm/form`

Introduction
------------

[](#introduction)

GranadaORM is a fantastic ORM but creating and managing the classes for each table in a large system can get tedious. Builder addresses this problem using a script that analyses the (MySQL only for now) database structure and automatically builds the required classes for models and controllers.

An added bonus is that a modern IDE will get autocomplete for the elements and functions available in the models.

Overview
--------

[](#overview)

When working with GranadaORM there are two main modes of interaction with the models: Building a query, and working with results of a query.

The builder creates a level of classes extending \\Granada\\Model to add functionality and split these two modes of operation:

- The *Query* classes contain functions to help filter the database to get a desired set of results
- The *Base* classes contain data elements and functions to work on the data for a record or set of records

### Hierarchy

[](#hierarchy)

Let's use an example of a table of People. It has the fields:

myapp\_personidfirst\_namelast\_namecreated\_atdeleted\_atThe *\\Myapp\\Person* class is created that extends *\\Myapp\\BasePerson* which extends a class you define in your configuration, to allow for system-wide additions. That class needs to extend *\\Granada\\Builder\\ExtendedModel* which extends *\\Granada\\Model*

### Added functionality

[](#added-functionality)

To make Granada models more useful, the following functions and features have been added for all models created and managed by Builder:

- **Before / After Save** - functions are called just before and just after every save operation
- **Before / After SaveNew** - functions are called just before and just after when the record is being inserted into the table. Only happens the first time that item is saved. The above before / after save functions are also called.
- **Before / After Delete** - functions are called just before and just after the record is deleted from the database
- **Representation** - define a field or fields and a display function (defaults to the first not-null field in the table) to use as a representation of the row. For example the Person record above may combine first\_name and last\_name fields to create a full name representation of the row.
- **find\_pairs\_representation()** - pulls the data from the database and returns an array with the id of the row as key and the representation of the model as the value.
- **Date and DateTime** fields are represented by the fabulous Chronos library by CakePHP. The database fields are all stored using the same timezone (default and recommended UTC) but can be optionally configured on a per-field basis to have a timezone or not. The interface is automatic and timezone headaches are a thing of the past!
- **Sort Order** automation by using an integer sort\_order field that defaults to "0" the order is automatically set to the end of the list when created
- **Reload** or **refresh** functions to fetch fresh contents from the database. This happens automatically on save to ensure any related data is not stale
- **Typed data** is properly returned, so an integer field returns an integer and a boolean (tinyint(1)) returns boolean. This makes outputting json for REST interfaces much cleaner.
- **Pluralized and Singularized** versions of the model name. Use `humanName()` to get "Person" and `humanNames()` to get "People"

Usage
-----

[](#usage)

Here's some examples of how you can use the classes to interact with the database through Granada even easier.

### Querying

[](#querying)

Using the example above, let's get the list of the 50 people who were most recently updated:

```
$people = \Myapp\Person::q()
          ->order_by_updated_at_desc()
          ->limit(50)
          ->find_many();

foreach ($people as $person) {
    echo $person->representation();
}

```

Now let's get the list of all the people with the surname "Smith"

```
$people = \Myapp\Person::q()
          ->where_last_name('Smith')
          ->order_by_first_name()
          ->find_many();

foreach ($people as $person) {
  echo $person->first_name;
  echo $person->created_at_chronos->toDateString();
}

```

For more functions available, see the list at the top of the `BasePerson.php` and `QueryPerson.php` files.

Set up for building
-------------------

[](#set-up-for-building)

The build system needs to know where to put the files, how to access the database and what to namespace to use if you haven't named your table names with the namespace prefix.

### Create the config file

[](#create-the-config-file)

Create a json config file with contents similar to the following:

```
{
  "db_host": "database",
  "db_name": "db_name",
  "db_username": "db_user",
  "db_password": "db_pass",
  "models_output_dir": "Auto",
  "model_to_extend": "\\MyAppCore\\ORMBaseClass",
  "controller_model_to_extend": "\\MyAppCore\\Controller",
  "use_namespaces": false, // If set to true, you don't need the next two and it splits the namespace from the prefix of the table name
  "default_namespace": "MyAppTest",
  "namespace_prefixes": [
    'blog', // Blog namespace has table names starting with "blog_"
  ]
}

```

That config file should be put somewhere that your script can run it. You can see that in the example the output dir is the same directory as the config file.

### Add the directory to the autobuilder

[](#add-the-directory-to-the-autobuilder)

In your system index.php or wherever your main entrypoint / config include, add an autoloader for these created classes to be loaded on access. For example you could use something like this - adjust your folders appropriately

```

$base_autoload_folder = __DIR__ . '/models';

spl_autoload_register(function ($classname) {
    $nsmodel = explode('\\', $classname);
    if (count($nsmodel) > 1) {
        $filename = $base_autoload_folder . "/" . $nsmodel[0] . '/' . $nsmodel[1] . ".php";
        if (file_exists($filename)) {
            include($filename);
        }

        $filename = $base_autoload_folder . "/cms/" . $nsmodel[0] . '/Models/' . $nsmodel[1] . ".php";
        if (file_exists($filename)) {
            include($filename);
        }

        $filename = $base_autoload_folder . "/cms/" . $nsmodel[0] . '/Models/_base/' . $nsmodel[1] . ".php";
        if (file_exists($filename)) {
            include($filename);
        }

        $filename = $base_autoload_folder . "/cms/" . $nsmodel[0] . '/Controllers/' . $nsmodel[1] . ".php";
        if (file_exists($filename)) {
            include($filename);
        }
    }
});

```

In the example above, we have a structure where the model and controller classes to extend sit in the `$base_autoload_folder` and under that is the `cms` folder which is where the config file sits, and all the classes are created.

Doing the actual build
----------------------

[](#doing-the-actual-build)

Run `./vendor/bin/granadabuild /path/to/config/file`

It may take a minute if your database has a large number of tables.

Note that the builder creates four files for each table. For the `myapp_person` table above, the builder will create:

- /cms/Myapp/Models/Person.php
- /cms/Myapp/Models/\_base/BasePerson.php
- /cms/Myapp/Models/\_base/QueryPerson.php
- /cms/Myapp/Controllers/PersonController.php

Only the files in \_base are managed automatically - the other two are meant for you to modify the class specific to the data in that table and should be managed by your version control system. You should ignore the \_base folders and auto-generate those on the server with each system update.

More details
------------

[](#more-details)

Look in the generated source code, and in the Builder ExtendedModel and the tests to see how you can use the system.

###  Health Score

28

—

LowBetter than 57% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity12

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity59

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~47 days

Recently: every ~22 days

Total

27

Last Release

785d ago

PHP version history (2 changes)1.0.0PHP &gt;=5.6.0

1.3.2PHP &gt;=7.2

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/4043827?v=4)[Josh Marshall](/maintainers/joshbmarshall)[@joshbmarshall](https://github.com/joshbmarshall)

---

Top Contributors

[![joshbmarshall](https://avatars.githubusercontent.com/u/4043827?v=4)](https://github.com/joshbmarshall "joshbmarshall (80 commits)")

---

Tags

ormphpdatabaseormactive-recordeager-loadingidiormparisclass autogeneration

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/granadaorm-builder/health.svg)

```
[![Health](https://phpackages.com/badges/granadaorm-builder/health.svg)](https://phpackages.com/packages/granadaorm-builder)
```

###  Alternatives

[propel/propel1

Propel is an open-source Object-Relational Mapping (ORM) for PHP5.

8391.6M81](/packages/propel-propel1)[granadaorm/granada

Active Record / ORM with eager loading, lazy loading and more

178.8k1](/packages/granadaorm-granada)[flightphp/active-record

Micro Active Record library in PHP, support chain calls, events, and relations.

152.9k](/packages/flightphp-active-record)[perplorm/perpl

Perpl is an improved and still maintained fork of Propel2, an open-source Object-Relational Mapping (ORM) for PHP.

161.9k](/packages/perplorm-perpl)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
