Smutty

MVC Framework

ClassSmutty_Model

Models are your interface to the database. They allow you to create, find, update and delete data, so are very, very useful.

Creating a Model

You can use smut to easily create new models with the following command:

./smut model Model

Where "Model" is the name of your model. This name should be the singular version of the actual table name in your database, underscores included. So for example a table called entry_types would have a model called EntryType. Smutty does this conversion for you automatically, but if your tables need to be called something else then you can specify their name, see the section called Table Names below.

You can then easily create models in your application just like instantiating a class.

function indexFunction( $data, &$session ) {
    $entryType = new EntryType();
    // more code...
}

This will create a brand new, empty EntryType object. You can then add data to this object and save it to the database with the models save() method.

Model Web-Interface

As soon as you've created a model is will be available for edit via the management interface. This provides an instant, easy way for dealing with your models.

Manipulating Models

Smutty models come with a number of functions to make dealing with them easy. Allowing you to search, edit and save data in your application.

save()

  • return: true if save ok, false otherwise

This is obviously a very important method. It will take any changes that have been made to your model and try to apply them to the database (after running any validation checks you've defined - see below).

function testAction( $data, &$session ) {
    // create a new model
    $post = new Post();
    $post->title = 'Title';
    $post->body = 'Body';
    $post->save();
    // edit the data
    $post->title = 'New Title';
    $post->save();
}

The function returns true if the save went ahead fine, false otherwise.

find( id )

  • id: the id of the row to find (column assumed to be called id)
  • return: Smutty_Model object if found, false otherwise

A very useful static method of your models is the find() method. This method can be used for searching for entries matching a specific id.

function showAction( $data, &$session) {
    $entry = Entry::find( $data->int('id') );
    // ...
}

fetchAll( order, fields, limit )

  • order: the name of the column to order by. can also specify the direction like "column:desc".
  • fields: a hash of fields to match on and their values, can also specify match type like "column:!=" => $value.
  • limit: the number of rows to return
  • return: array of Smutty_Model objects

This method can be used for searching for many results.

function indexAction( $data, &$session ) {
    $this->set( 'entries', Entry::fetchAll() );
    // ...
}

NOTE: These functions are kind of reserved by Smutty, but you can override them if you like. If you do so though make sure to check the spec of the Model function, it differs slightly (Smutty does some internal trickery to make this static syntax possible).

Filling Models

A very common action is to populate a model based on input from a form the user has filled in. Smutty tries to make this as easy as possible if you follow a few naming conventions. When creating your fields you should name them after the model they're for using dot notation. So for a Bug model, use names like this...

{field name="bug.name" label="Bug Name:"}
{textarea name="bug.body" label="Description:"}

You can then use the fill method of the model which'll try and populate as many of the fields in the model as it can.

function saveBugAction( $data, &$session ) {
    $bug = new Bug();
    $bug->fill();
}

Date Fields

Smutty will also look for any date fields in your model that haven't been filled by data from the form. If found they'll be filled with the current date.

Current User

Additionally, if there is a current user logged in ($session->user) then Smutty will set this value to any field found named user_id if it doesn't already have a value form data.

Table Names

By default Smutty will try to guess the correct table name using the name of your Model class. So for example if you have a model named Post, then Smutty will assume that the table behind it is called posts. But if it is infact something different then you can specify this using the $tableName variable, like so...

class Post extends Smutty_Model {

    var $tableName = 'wierd_posts_table';

}

Related Data

It's pretty likely that your models will be related to other models. For example when writing a blog you'll probably have a posts table, and an associated comments table. To tell Smutty about this you just use the $hasMany, $hasOne and $hasRelation variables in your model. This should be a string of space seperated model names.

class Post extends Smutty_Model {

    var $hasMany = 'Comment';

    var $hasOne = 'User';

    var $hasRelation = 'Something';

}

The comments will then be available in your template as $post->comments, and the user will be $post->user.

Column Names

The related field is assumed to be model_id, but you can specify this if it's something different using the dot notation shown below. So if you have a comments table for some posts, then Smutty will assume there is a field called comments.post_id. But if it is something else you can specify this as follows.

class Post extends Smutty_Model {

    var $hasMany = "Comment.post_id_field_name";

}

Property Names

The property name is assumed to be the name of the class that is being referred to. So, if you have a class Post, with a field for the user who made that post referring to a class called User, then you will specify the relation as follows. (Remember, Smutty will assume this field to be named user_id so we don't need to specify it)

$hasOne = 'User';

And this will then be available as...

$post->user;

But if you have more than one field that refers to users (eg. a User may have a current Location, and a home Location), you can specify this as a third argument as follows...

$hasOne = 'Location.curr_location.current Location.home_location.home';

Which will then expose these two properties as...

$post->current;
$post->home;

Custom Property Handlers

The $hasOne and $hasMany variables can be very useful, but sometimes they just don't provide enough lexibility. Smutty also allows you to define custom methods for properties of your models.

So for example, if I have a Post model with related comments, I could write the following method in my model.

function commentsProperty() {
    return Comment::fetchAll( false, array(
        thread => $this->id
    ));
}

This method will then be called when you access $post->comments. This is a simple example but enough to see you could use it to allow very flexible property access.

Data Validation

Smutty provides an easy method for you to specify how data should be validated as it passes through your models. There is a single variable called $validate which should be assigned an array of name/value pairs. The name is the field to be validated, and the value is the validation rules. The easiest way to use this is just to specify one of the builtin Smutty data types, but a much more powerful array is to assign an array of rules (all of which are optional).

class My_Model extends Smutty_Model {

    var $validate = array(

        fieldName => STR_REQUIRED, // a required string field,

        intField  => INT_REQUIRED, // an integer, required
        anInt     => INT_OPTIONAL, // an integer, but optional

        // assign array of validation rules for field
        another => array(
            type => STR_OPTIONAL, // a string, but it's optional
            regexp => '/w+/',
            maxlength => 50,
            minlength => 10
        )
    );

}

Models are checked for validity before they are saved, but you can also do this any time you want by using the isValid() method. This method returns true if the model is valid, false otherwise. If the model is invalid then the error messages describing what failed will be stored internally and can be accessed through the getErrors() method.

function saveAction( $data, &$session ) {
    $post = new Post();
    $post->title = $data->string( 'title' );
    if ( !$post->isValid() )
        $errors = $post->getErrors();
    // etc...
}

Validation Methods

You can also write your own methods to handle validation for individual fields. You do this by naming the method validateMYFIELD, where MYFIELD is the name of the field to validate with the first letter capitalized. So if you have a field called user_name...

function validateUser_name( $value, $data, $session ) {
    // validate code
}

This function should returm the empty string if the value is valid, o a description of the problem if it's not. The data and session objects are the usual.

NOTE: This function will be used in addition to using any validation information you provided via the $validate property.

Model Transactions

It will often be the case where you'll want to save/validate multiple models at the same time. In these cases you'll find the Smutty_Model_Transaction class very useful.

Links: Post a comment

Useful Pages

Links