The DATA Module

The Data module is responsible for handling data storage and retrieval, using the structure of 'models' which are classes that exist to structure data into objects.

Default Data Implementation

The default Data module uses a query builder with some accompanying business logic to convert data in the database into usable PHP objects that are returned to the client as JSON

The default way data is retrieved from the database and structured is through Models. Each model is designed to represent one table in a database, with properties representing table columns.

When using the standard implementation, each Model must extend FW\Data\Standard\Model. When creating Models, there are a few things that need to be defined. First, you need to define your table columns as instance variables. For example, if you had a User table in my database with columns 'userID', 'name', and 'password', your User model would look similar to this:

// When using the standard App Kit, this file would
// go in api/src/Model/User.php

namespace MyApp\Model; //inside the Models namespace

class User extends \FW\Data\Standard\Model {

    protected $userID;
    protected $name;
    protected $password;
    //…
}

The next thing you would need to do is declare some static properties, so that the Adapter knows where to load the data from.

// User.php

class User extends …{
    protected static $table; // database table name
    protected static $id; // database primary key column name
    protected static $searchable; // array of searchable columns

    // If your model needs other models, for example, if you had   
    // an Order model and each User has several Orders, you
    // would specify that 'orders' is an allowed join to the
    // users table.
    protected static $allowedJoins = array();

    // aliases if the data on the front-end expects something
    // other than what the column name is. For example, if the
    // client expects the username column to be 'id' instead
    // of 'userID', you would put a row in this array that looks
    // like this: 'id' => 'userID'
    protected static $aliases = array();

    // array of required fields when creating/updating a row
    protected static $required = array();
}

Once those properties are specified, there are a few static methods on the model that can be used to retrieve records from the database:

    // this function finds one row in the database based
    // on particular search values
    public static function findOne(array $searchValues, array $includes);

    // this function finds all rows in the database based on
    // particular search values
    public static function findAll(array $searchValues, array $includes);

    // this function adds a new row
    public static function add(array $values, array $includes);

    // this function edits an existing row
    public static function edit($id, array $values, array $includes);

Now, when you are calling these methods, you don't do it directly on the model class. Instead, you go through the FW Adapter, a simple class that looks up the models based on a string name. For example, to get access to my user model, I would call the 'model' method of the FW Adapter class;

// some controller class
// $adapter is an instance of FWAdapter

$model = $this->adapter->model('User');
$model::findOne(array('userID' => 'john'));

Alternatively, the FW Adapter class provides a shorthand method call that removes the intermediate step of getting the model name back. You also can directly call each method on the adapter if you want an even shorter version. Using the example above, the same task with two shorthand methods look like this:

//fuller adapter call version
$this->adapter->call('User', 'findOne', array('userID' => 'john'));
//even shorter adapter call of same method
$this->adapter->findOne('User', ['userID' => 'john'])

Any of these should work, but it is advised that you use the final option when calling Models from your Controller. For more advanced usage of Models, look at the API documentation for FW, both for Model and Adapter.

Connection to the Database

Because a majority of FW Apps are designed to handle retrieval of data from a data source, it is necessary to have some sort of handle for database connections. In old implementations of the FW API, there was a whole other module called connection, which handled this connection, but now it is done through the Data module, where it belongs. By default, the database connection parameters are loaded from the configuration data. Because this used to be a separate module, and also because this is something that you will set up once and likely not use again (when you are using the rest of the Data Module with the adapter and models), connecting to the database will be discussed separately.

Default Database Connection Implementation

The default implementation of the database portion of the Data module uses the Pixie Query Builder. While the default implementation is designed to work well with the default Data module, it can be used for other things in the application.

The default implementation looks for certain variables in the config file. While this can be located anywhere within the global, app, or local config files, it is recommended to put the database connection information into the application local.php file (since it contains very sensitive information). Here's an example format:

// local.php

return array(
    'database' => array( // database params MUST go in this array with this key
        'driver' => 'mysql',
        'host' => '127.0.0.1',
        'database' => 'exampleDatabase',
        'username' => 'someUserName',
        'password' => 'SECRET_PASSWORD'
    )
);

For more information about the config structure, look at the Pixie documentation.