This is the documentation for LemonStand V1, which has been discontinued. You can learn more and upgrade your store here.

LemonStand Version 1 Has Been Discontinued

This documentation is for LemonStand Version 1. LemonStand is now offered as a cloud-based eCommerce platform.
You can try the new LemonStand and learn about upgrading here.

Lists

In this section we will continue extending a simple blog module which we started in the Developing a simple module article. We already have the AbcBlog_Posts controller, which will manage blog post records. In the controller we have defined the index() action, which will display a list of blog posts. Below is a code of the AbcBlog_Posts controller class:

<?
  class AbcBlog_Posts extends Backend_Controller
  {
    public function __construct()
    {
      parent::__construct();
      $this->app_module_name = 'Blog';
      $this->app_tab = 'abcblog';
      $this->app_page = 'posts';
    }

    public function index()
    {
      $this->app_page_title = 'Posts';
    }
  }
?>

Defining model columns

In order to display a post list on the /abcblog/posts page, we first need to define list columns in the AbcBlog_Post model class, which we created in the Working with the database article. The Db_ActiveRecord class (a parent class of the AbcBlog_Post class) has the define_columns() method. In this method we can define model columns. By defining columns we just inform the programming framework which fields from the database table we are going to use in lists and forms, and what titles these fields should have. We need to override this method in the AbcBlog_Post class declaration. Inside the method we will call the define_column() method for defining individual columns.

public function define_columns($context = null)
{
  $this->define_column('id', '#');
  $this->define_column('title', 'Title');
  $this->define_column('description', 'Description');
}

In the code above we declared 3 list columns. The define_column() method of the Db_ActiveRecord class has 2 parameters - the column name in the database table, and the column title in the list.

Extending the controller

After defining the model columns, we need to extend the controller class, in order to add list features. The Db_ListBehavior behavior implements everything we need for displaying a list. To extend our posts controller, we need to define the $implement field in the controller class declaration. This field should have a string-type value, containing a list of behaviors, separated with a comma. In our case we want to add only a single behavior:

class AbcBlog_Posts extends Backend_Controller
{
  public $implement = 'Db_ListBehavior';
  ...

All behaviors in LemonStand have a number of configuration parameters. The list behavior requires at least one parameter to be specified - the model class name, which represents items we are going to display in the list. This parameter should be added using the $list_model_class controller field. In our case the model class name is AbcBlog_Post:

class AbcBlog_Posts extends Backend_Controller
{
  public $implement = 'Db_ListBehavior';
  public $list_model_class = 'AbcBlog_Post';
  ...

Displaying a list in the view document

The list behavior adds several methods to the controller. The most important method is the listRender(). This method outputs a list on a page. In the view document (the index.htm file, in our case) we need to add the following line of code:

<?= $this->listRender() ?>

If you go to the Blog/Posts page in the Administration Area, you will see a page with a list of posts on it:

As you can see the list behavior not only displays the record table, but also supports pagination, sorting and provides the standard list setup interface (the icon on the right side of the page, above the list).

The list behavior has many configuration options. Some of them will be described below. But first we will demonstrate how you can add links to list records. In our case we need each record in the post list to refer to the Edit Post page (we will create this page later). The list behavior has the $list_record_url for specifying an URL for list records. We need to add this field to the controller class declaration:

class AbcBlog_Posts extends Backend_Controller
{
  public $implement = 'Db_ListBehavior, Db_FormBehavior';
  public $list_model_class = 'AbcBlog_Post';
  public $list_record_url = null;
  ...

As you can see we declared the field, but assigned the NULL value to it. This is because URLs of pages in the Administration Area are not static. They depend on the Administration Area URL key specified during the application installation. The problem and the solution are explained in the Adding a back-end user interface article. To obtain an actual URL of the Edit Post page we need to use the url() function. But we cannot call functions in class declaration code in PHP. The solution is to define the field in the class declaration and assign a value to it in the class constructor:

public function __construct()
{
  ...
  $this->list_record_url = url('/abcblog/posts/edit/');
  ...
}

This code adds a link to all list record. The link refers to the Edit Post page, which we will add to the controller in the Forms article.

Adding the search functions

The list behavior has many useful features, which are described in the Db_ListBehavior.

article. In this section we want to demonstrate how you can add the search feature to the post list. To enable the search function, we need to define 3 fields in the controller declaration: $list_search_enabled, $list_search_fields and $list_search_prompt:

class AbcBlog_Posts extends Backend_Controller
{
  public $implement = 'Db_ListBehavior, Db_FormBehavior';
  public $list_model_class = 'AbcBlog_Post';
  public $list_record_url = null;

  public $list_search_enabled = true;
  public $list_search_fields = array('@title', '@description', '@content');
  public $list_search_prompt = 'find posts by title or content';
  ...

The $list_search_enabled field just tells the list behavior that the search feature should be enabled. The $list_search_fields field contains a list of database fields you want to search in. The @ symbol is used for indicating that a field belongs to a main table the model (AbcBlog_Post) refers to. In some cases models can have a number of linked tables. In the next section we will add the Categories column to the blog post list. Then the SQL query for fetching data from the database, generated by the list behavior, will contain more than one table reference. If there will be more than one table containing the "title" column, the SQL error will occur, because MySQL server will not known what specific table we mean in the query. The @ symbol helps the behavior to bind a field to the main model table.

The $list_search_prompt specifies a message which will be displayed in the search field.

After declaring all necessary fields and refreshing the blog post list page, you will find a search field above the record table:

The search feature tries to find ALL words specified in the search box in ANY field specified in the $list_search_fields controller field. We recommend you to create database indexes for all fields you are going to make searchable.

Displaying record modification information and data from related tables

Earlier we defined 4 special fields in our blog posts table: created_at, updated_at, created_user_id, updated_user_id. You can add these service fields to the blog post list with two line of code in the AbcBlog_Post model class declaration:

class AbcBlog_Post extends Db_ActiveRecord
{
  public $table_name = 'abcblog_posts';

  public $implement = 'Db_AutoFootprints';
  public $auto_footprints_visible = true;
  ...

The $implement filed tells the Active Record engine that the AbcBlog_Post model should be extended with the Db_AutoFootprints class. This class is an extension for the Db_ActiveRecord class, which automatically defines all update information columns. You can define all columns manually, in the same way as we defined the id, title and description columns, but with the Db_AutoFootprints extension you can save some time. Now our blog post list has 4 new columns:

In the Creating data relations article we created a blog categories model - the AbcBlog_Category class. It is possible to display data from related tables in LemonStand lists. In our blog implementation we can display a list of categories each post belongs to.

We already have the has_and_belongs_to_many relation definition in the AbcBlog_Post model class:

class AbcBlog_Post extends Db_ActiveRecord
{
  ...
  public $has_and_belongs_to_many = array(
    'categories'=>array(
      'class_name'=>'AbcBlog_Category', 
      'join_table'=>'abcblog_posts_categories', 
      'primary_key'=>'post_id', 
      'foreign_key'=>'category_id')
  );
  ...

Now we can define a column for the Categories relation in the model's define_columns() method. But this time we will use the define_multi_relation_column() method instead of the define_column():

public function define_columns($context = null)
{
  $this->define_column('id', '#');
  $this->define_column('title', 'Title');
  $this->define_column('description', 'Description');
  
  $this->define_multi_relation_column('categories', 'categories', 'Categories', "@name");
}

The define_multi_relation_column() method is designed for defining columns for Has Many and Has and Belongs To Many relations. The method has the following parameters:

  • Column name - a name of a column to add to the model. The name should be compatible with SQL table column names.
  • Relation name - a reference to a relation to be presented by the column. It should refer to an existing relation defined in the model class using the $has_many or $has_and_belongs_to_many fields. In our case the relation name is categories.
  • Column title - a title text for the column.
  • Value SQL expression - an SQL expression for fetching the column value. You can use a name of a column from the related table. In our case the related table is abcblog_categories, which have the name column, representing a category name. Also it is possible to use SQL functions here, for example CONCAT. The @ symbol is used to indicate that the column belongs to the related table (abcblog_categories). In this case it is not necessary. But if our blog posts table contained the name column, the @ symbol would be required in order to distinguish the columns from the abcblog_categories and abcblog_posts tables.

After adding the Categories column, you can refresh the post list. Now it contains the Categories column. In our database the single post belongs to 2 categories. LemonStand outputs both categories in the Categories column, separating them with the comma symbol:

The last method for defining columns which we need to describe is the define_relation_column(). Use this method when you need to define a column for the Belongs To or Has One data relation. For example, in the LemonStand Shop_Order model class we defined a column for the shipping method in the following way:

$this->define_relation_column('shipping_method', 'shipping_method', 'Shipping Method', db_varchar, '@name');

The first 3 parameters of this method match first 3 parameters of the define_multi_relation_column() method described above. The shipping_method relation is defined in the Shop_Order class as a Belongs To relation. The fourth method parameter is a column type. Column types are described in the Db_ActiveRecord class description. Active Record engine uses the column type information for formatting columns in list and forms. For example, values of date and numeric columns are right aligned. The last parameter of the method specifies a name of a column from a related table, which value should be displayed in the column.

Conclusion

In this article we demonstrated the power of behaviors in the LemonStand programming framework. You can download the updated Blog module archive here.

Next: List Filters
Previous: Lists and Forms in the Administration Area
Return to Lists and Forms in the Administration Area