Share » Learn » eZ Publish » Creating Datatypes in eZ Publish 4

Creating Datatypes in eZ Publish 4

Wednesday 21 May 2008 9:14:00 am

  • Currently 5 out of 5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

The filter extension gives you a powerful API to block or sanitize submitted input. The UserInput component builds an object-oriented API on top of the extension. This helps us to put the form parsing code in a separate class and thereby makes the rest of the code much more readable.

Forms are objects too!

Do you also dislike PHP code where form parsing and business logic are mixed together? Why not give forms the appreciation they deserve and put them in their own PHP classes? All code that is necessary to answer the question “Can we process this data?” should be put in a form class. Code that answers the question “What went wrong with the input?” should be put in the form class too, resulting in elegant controllers in your MVC.

The UserInput component helps by providing a predefined structure to declare the input you are expecting. Consider the following screenshot of a more complicated datatype:

Enhanced edit form for a datatype

The indicated input fields were used as an example to write a valid form definition for the UserInput component:

$formDef = array(
  'isnodeplacement_value' => new ezcInputFormDefinitionElement(
      ezcInputFormDefinitionElement::OPTIONAL, 'boolean' ),
  'option_name_array' => new ezcInputFormDefinitionElement(
      ezcInputFormDefinitionElement::OPTIONAL, 'string', NULL, FILTER_REQUIRE_ARRAY ),
  'move_option_up' => new ezcInputFormDefinitionElement(
      ezcInputFormDefinitionElement::OPTIONAL, 'string', NULL, FILTER_REQUIRE_ARRAY ),
  'newoption_button' => new ezcInputFormDefinitionElement(
      ezcInputFormDefinitionElement::OPTIONAL, 'string' ));

Such an array can then be placed in a class representing the form object. One major benefit of this approach is that all possible input variables are defined in one place.

Another method I put in my form objects is isValid(). Since you have all the validation logic in the form class, you could even check the validity of a form in one line:

if  ( MyFormClass::getInstance()->isValid()) ....

Now let's see how this approach can be applied for our datatype.

UserInput and the ymcDateTime datatype

If you had a simple website with one form containing fields like “firstname”, “surname” and “email” then you can easily put these field names in the array keys of the form definition. The form declaration method described in the previous section is a bit more difficult to deal with when it comes to datatypes.

Remember that a content class in eZ Publish is not represented by a simple form hard-coded in your PHP script. In fact, the form of a content class (or object) is dynamically created based on the included datatypes. Recall that our example content class contains two attributes of the same datatype. If you were to hard-code the field names, there would be no way to determine whether an input field named “day” belonged to the “from” or the “to” attribute.

You need to add another piece of information to the input field names to indicate the attribute to which an input field belongs. This information is provided by a suffix consisting of the field name and the ID of the attribute to which it belongs. To be completely safe, another string is prefixed to the field name, indicating that it belongs to an attribute of a content class and further specifying the datatype. Therefore, your final field name could be “ContentClass_mydatatype_myfield_123”.

Normally, for every field name you want to access, you would need to write code similar to this:

$dataName = $http->postVariable($base . "_mydatatype_myfield_" . $contentObjectAttribute->attribute("id"));

The abstract ymcDatatypeForm class makes this a lot more readable by building the real field name in the background. Let's look at the fetchClassAttributeHTTPInput method in ymcDatatypeDateTimeType for a better understanding. Remember that this method should read the input from the Default Value dropdown list from the Class Edit Interface and store it in the attribute:

public function fetchClassAttributeHTTPInput( $http, $base, $attribute)
    {
        $form = ymcDatatypeForm::getInstance(
            'ymcDatatypeDateTimeClassForm',
            $attribute->attribute( 'id' )
        );

This gives us a singleton instance of the class ymcDatatypeDateTimeClassForm for the specified ID. Next is the input validation code, which consists of one simple statement:

if( !$form->isValid() )
        {
            return;
        }

If the input is valid, we can continue to the last line of code:

$attribute->setAttribute(
            self::CLASSATTRIBUTE_DEFAULT,
            $form->default
        );
    }

Note that I did not have to write “ContentClassAttribute_default_123” to access the field “default”. The mapping to the concrete field name has been done in the background by the ymcDatatypeForm class.

For more detailed information, please refer to the source code of the ymcDatatypeForm class, to the documentation of the UserInput component and to the documentation of the PHP filter extension.

36 542 Users on board!

Tutorial menu

Printable

Printer Friendly version of the full article on one page with plain styles

Author(s)