Confessions of an apprentice: How to create and use custom fetch functions in eZ Publish

by Tomislav Buljević -
Confessions of an apprentice

In this article, you will learn how to create your custom fetch functions which will help you in further development of your module. Also, this is a natural continuation of the last article because we will use the examples from the custom database table we created earlier to set up the new fetch functions.

If you need to brush up on your knowledge, I recommend reading the last Confessions of an Apprentice. If not, read on!

Last time we have created a new database table, linked it to a new class we created specifically for this purpose, and learned how to extend the eZPersistentObject class which is used for all the data manipulation.

This time, we will learn how to actually create fetch functions for use in the templates. Of course, as always, I’ll create a simple example which will use as a foundation for all of your work in eZ Publish, as you progress to truly being a wizard. 

Setting up fetch functions

Creating custom fetch functions

The first thing you need to create are two PHP files for your module: function_definition.php and mymodulefunctioncollection.php. As you can see from the names of the files, mymodulefunctioncollection.php is a collection of all the functions that our fetch functions will use in the PHP side of the module, and function_definition.php is the PHP script which defines the names and parameters of our fetch functions.

First off, create the mymodulefunctioncollection.php in the modules/mymodule folder of your extension. This is actually a PHP class which will have a few of the functions we need in the templates. Let’s fill it up with some code, shall we?

<?php

class myModuleFunctionCollection
{
    public static function fetchDiscountCodes( $offset=false, $limit = false )
    {
        $limits = null;
        if ( is_numeric( $offset ) || is_numeric( $limit ) )
        {
            $limits = array();
            $limits['offset'] = is_numeric( $offset ) ? (int) $offset : 0;
            $limits['length'] = is_numeric( $limit ) ? (int) $limit : 15;
        }

        $fetchResult = myDiscountCode::fetchList( null, $limits );

        if ( is_array( $fetchResult ) && !empty( $fetchResult ) )
            return array( 'result' => $fetchResult );

        return array( 'result' => false );
    }

    public static function fetchDiscountCodesCount()
    {
        $fetchResult = myDiscountCode::fetchCount();
        if ( is_numeric( $fetchResult ) )
            return array( 'result' => (int) $fetchResult );

        return array( 'result' => 0 );
    }
}

?>

As you can see, we have defined two methods here: fetchDiscountCodes(), and fetchDiscountCodesCount(). The fetchDiscountCodes() method will take two parameters, $offset and $limit which will serve as parameters for one of the fetch functions. With those, we can define how much of the codes we want to fetch at once, and where in the table to begin fetching results, assuming we have a bunch of codes in our table. Since we already have a fetchList() method defined in the myDiscountCode class, we will just return a result according to those parameters. Therefore, we check if $offset and $limit are numeric values, and if either of them is a numeric value, we will set an offset value or a limit value to our $limits array accordingly. If none of them is a numeric value, we set them to some default values. In this case, I have chosen these values to be 0 for offset and 15 for limit, but you can set them to whichever values you’d like. After that, we just call the fetchList() method from the myDiscountCode class and apply those limits to it. When this function is called from a template, it will return either a false result, in case no data is in the table or if offset and limit are invalid or out of range, or a list of the myDiscountCode objects within specified limits.
The second function we have created is the fetchDiscountCodesCount() function which we’ll use to count all of the rows in the database table. And if there is data in the table, we will get a number of all the rows in it, otherwise, we will get a zero count.

The next step is to modify the function_definition.php file we’ve created. This file is the place where we create definitions for our fetch functions. As you will see in a moment, the structure of this file is very similar to the actual module.php file itself. We’ll start coding it like so:

<?php

$FunctionList = array();

$FunctionList['discount_codes'] = array( 
    'name' => 'discount_codes',
    'call_method' => array(
        'class' => 'myModuleFunctionCollection',
        'method' => 'fetchDiscountCodes'
    ),
    'parameter_type' => 'standard',
    'parameters' => array(
        array(
            'name' => 'offset',
            'type' => 'integer',
            'required' => false,
            'default' => 0
        ),
        array(
            'name' => 'limit',
            'type' => 'integer',
            'required' => false,
            'default' => 15
        )
    )
);

$FunctionList['discount_codes_count'] = array(
    'name' => 'discount_codes_count',
    'call_method' => array(
        'class' => 'myModuleFunctionCollection',
        'method' => 'fetchDiscountCodesCount'
    ),
    'parameter_type' => 'standard',
    'parameters' => array()
);

?>

OK, so what do we see here? We have defined a $FunctionList array and put in it two keys called discount_codes and discount_codes_count. Each of these keys is an array which contains the following keys: name, call_method, parameter_type, and parameters.

The name key speaks for itself, it’s the name of the function we need to call. The call_method key is the key in which we define an array of the class and method this particular function uses, therefore, we’ll use our function collection and a method from it which matches the function we’d like to perform. The parameter_type key is a deprecated feature which is here because of backwards compatibility with the previous versions. And the last key is parameters. Its value is an array which consists of inner arrays which define the parameters we want to pass onto a function one by one. In the case of the discount_codes function, we have determined two integer parameters, ‘offset’ and ‘limit’, both of which are optional, and have default values of 0 and 15 respectively.

At the end of the day, when you test your code, if everything is set up properly, you’ll be able to write something like this:

{def $discount_codes_fetch = fetch('mymodule', 'discount_codes')}

and get a list of discount codes.

Using fetch functions in the templates

Let’s say that you want to set up a template which will have a main purpose of editing discount codes in the database table. We will use both fetch functions we created to demonstrate their use. This is just a fragment of a larger code involving a form which submits the changes:

{def $codes = fetch(mymodule, discount_codes, hash( offset, first_set( $view_parameters.offset, 0 ) ) )}
{def $codes_count = fetch(mymodule, discount_codes_count)}

{if $codes_count|gt( 0 )}
    {foreach $codes as $code}
        <tr>
            <td><input type="checkbox" value="{$code.id}" name="CodeIDArray[]" /></td>
            <td>{$code.discount_code|wash}</td>
            <td>{$code.valid_from|datetime('custom', '%Y-%m-%d %H:%i')}</td>
            <td>{$code.valid_to|datetime('custom', '%Y-%m-%d %H:%i')}</td>
            <td><a href={concat('mymodule/editdiscountcode/', $code.id)|ezurl}><img src={'edit.gif'|ezimage} alt="Edit discount code" /></a></td>
        </tr>
    {/foreach}
{/if}

As you can see, after we fetched the codes count and the codes themselves, we created an HTML table inside the template which displays all of the relevant information regarding our discount codes. Also, at the end of each row in the table, we added an Edit link which will enable us to add new codes, and edit the existing ones.
In the next article, we will deal with the necessary views for our discount codes to be fully functional.
Until next time, I wish you happy coding,
Tomislav

Comments

This site uses cookies. Some of these cookies are essential, while others help us improve your experience by providing insights into how the site is being used.

For more detailed information on the cookies we use, please check our Privacy Policy.

  • Necessary cookies enable core functionality. The website cannot function properly without these cookies, and can only be disabled by changing your browser preferences.