Overview Zend_CodeGenerator

As you may already know Zend_CodeGenerator appeared in beta 1.8 Zend_Framework
I wanted to wait until the release of version 1.8, but could not resist and decided to still poprobuite "by heart".
We will generate a form class based on a mysql table.
It's really very convenient and saves us from the sometimes routine work.

First you need to consider the classes that will use.

To create a php file situated class
Zend_CodeGenerator_Php_File();
Its constructor accepts an array which lists the classes in the file. For example you can do this:

$file = new Zend_CodeGenerator_Php_File(array('classes' => array($class)));


Where $class is an instance of class
Zend_CodeGenerator_Php_Class()

May be a few classes to generate several classes is to specify them in an array.

But in coding standards for Zend_Framework said:
“Only one class is permitted per PHP file.
Placing additional code in class files is permitted but discouraged. In such files, two blank lines must separate the class from any additional PHP code.”

This business is subjective and I would still have generated one file for each class,
So more clearly the structure of the application.

So let's create a new class:
$class = new Zend_CodeGenerator_Php_Class();


the first method we need is setName()
the input parameter for it will be a string with the name of the class.
$class -> setName('MyClass')
In order to specify which class will be nasledovat generated class using the method

$class ->setExtendedClass('Myclass2')


Then we may need Doc block

$docblock = new Zend_CodeGenerator_Php_Docblock(array(
'shortDescription' => 'Simple' generated class'
'longDescription' => 'This class generated Zend_CodeGenerator'
'tags' => array(
array(
'name' => 'version'
);


* This source code was highlighted with Source Code Highlighter.

In the array that is the input parameter, we specify
‘shortDescription' – brief description of class
'longDescription' a full description of class

In a nested array of tags, we can specify the tags for docblock
‘name’ – the name of the
tag ‘description’ is the text following after it

Then we need to declare variables used in this class
It is the setProperties() method the incoming day the parameter is an array of variables, each new variable will be described in the new array.
in which of the following to specify the properties of a variable
Or they can be described via the class Zend_CodeGenerator_Php_Parameter

Suppose that we need 2 variables:

$vars = array(
array(
'name' => ‘name,
'visibility' => 'public'
'defaultValue' => ‘0’
)
array(
'name' => ‘_table’,
'visibility' => 'protected'
'defaultValue' => ‘1’
)
);



Or
$var1 = Zend_CodeGenerator_Php_Parameter(
array(
'name' => ‘var
'visibility' => 'public'
'defaultValue' => ‘0’
)
);
$var2 = Zend_CodeGenerator_Php_Parameter(
array(
'name' => ‘var2’,
'visibility' => 'protected'
'defaultValue' => ‘1’
);
$vars = array($var1, var2);



Name is the name of the variable
Visibility – the access modifier
Default value – znacznie default, if you do not specify this parameter then the variable will be null

Now our class can look like this:
$class = new Zend_CodeGenerator_Php_Class();
$class -> setName('MyClass extends MyClass2') -> setProperties($vars) - > setDocblock($docblock);



Of course, we need to describe the methods of this class
For the installation method is the method
setMethod() or
setMethods()
The only difference in the number of methods which we want to set, setMethod() accepts either a class Zend_CodeGenerator_Php_Method instance or an array which describes the method setMethods() takes an array containing method objects, or a set of arrays.

If you chose the first way it can it will look like this:
$method = Zend_CodeGenerator_Php_Method(array(
'name' => 'myMethod'
'body' => 'echo "hello CodeGenerator"'
'docblock' => new Zend_CodeGenerator_Php_Docblock(array(
'shortDescription' => 'unit documentation'
'tags' => array(
new Zend_CodeGenerator_Php_Docblock_tag_return(array(
'datatype' => 'string|null'
))
)
))
))
));

$class ->setMethod($method);



If the second it is possible so:

$class -> setMethods(array(
array(
'name' => 'myMethod'
'parameters' => array(
array('name' => 'myVar)
)
'
body' => '$var = 'hello world';' . "\n" . 'return $var'
'
docblock' = > new Zend_CodeGenerator_Php_Docblock(array(
'
shortDescription' => 'block documentation'
'
tags the' => array(
new Zend_CodeGenerator_Php_Docblock_tag_param(array(
'
paramName' => 'bar'
'
datatype,' => 'string'
))
new Zend_CodeGenerator_Php_Docblock_tag_return(array(
'
datatype,' => 'string'
))
)
))
)



here 'name' is the name of the method
‘parameters' is the incoming parameters, each new parameter is described by a new array, it's exactly the same as for variables inside a class and you can use the class Zend_CodeGenerator_Php_Parameter()
‘body’ is the body of the method where we place code to be executed inside the method at the bottom of the case, that, '$var = 'hello world';'. "\n". 'return $var', it is worth noting that the code is not formatted automatically because you have to use "\n" and "\t"
Docblock in the methods listed do the same as well as for classes.

In the end, all that remains to do is generate a code and write it to a file
$code = $file->generate();
file_put_contents('file.php', $code);



For this we use the standard php function — file_put_contents and the method generate();
Which is present in all of the above-described classes in Zend_CodeGenerator
If you would prefer we can generate each element of the parts and separately write to the file.

Next, I give a rather vivid example of class which generates forms.

<?php
class FormGenerator
{
/**
* the Array in which the key data type in mysql
* value - the input type in the form
* */
protected $_values = array(
'int' => 'Text'
'varchar' => 'Text'
'tinyint' => 'CheckBox'
'date' => 'Text'
'float' => 'Text'
'mediumint' => 'Text'
);
/**
* the Method generates the form class
* the incoming parameter is an instance of a Zend_Db_Table class
* */
public function generateForm(Zend_Db_Table $table)
{
//get informaciju on the table
$tableInfo = $table->info();

//Get the name of class
$className = 'Form_' . ucfirst($tableInfo['name']);

//Directory where are stored the classes of forms
$folder = $_SERVER['DOCUMENT_ROOT'] . '/application/models/Form/';

//Declare a new class, set its name, and which he must inherit the
$formClass = new Zend_CodeGenerator_Php_Class();
$formClass- > setName($className);
$formClass- > setExtendedClass('Zend_Form');

//Body of method init
$initMethodBody = 'parent::init();
$helper = new Zend_View_Helper_Url();
'
. "\n\t\t";

// written in the body of the method elements using the method generateElement()
foreach ($tableInfo['metadata'] as $field){
Zend_Debug::dump($field);
$initMethodBody .= $this->generateElement($field['COLUMN_NAME'], $field['DATA_TYPE']);
}

// generated separately submit button
$initMethodBody .= $this->generateSumitElement($tableInfo['name']);
$initMethod = new Zend_CodeGenerator_Php_Method(
array(
'name' => 'init'
'body' =>$initMethodBody
));

// set method in the class
$formClass- > setMethod($initMethod);

// set class into a file
$file = new Zend_CodeGenerator_Php_File(array(
'classes' => array($formClass)
));

//generium code
$code = $file->generate();

// if no path then create it
if(!file_exists($folder)) {
mkdir($folder);
}
// and write the code in the file
file_put_contents($folder.ucfirst($tableInfo['name']) . '.php', $code);
}

/**
* Method generowania form element
* incoming settings - the name and type fields in mysql
* returns the code element
* */
public function generateElement($name, $type)
{
$element = '$' . $name . ' = new Zend_Form_Element_' . $this->_values[$type]. "(\n\t\t"
. "'$name'," . " \n\t\t"
. "array("
. "'label' => '$name')); \n\t\t";
// here if it is numeric then use the Digits validator
if($type == 'int' || $type == 'tinyint' || $type == 'mediumint') {
$element .= '$' . $name . '->addValidator("Digits", true);' . "\n\t\t";
}

// but if srokowo then the filter StripTags
if($this->_values[$type] == 'Textarea' || $this->_values[$type] == 'Text'){
$element .= '$' . $name . '->addFilter("StripTags");' . "\n\t\t";
}
// in any case we will need the StringTrim filter
$element .= '$' . $name . '->addFilter("StringTrim");' . "\n\t\t"
return $element;
}

/**
* generate the submit buttons nothing complicated
*/
public function generateSumitElement($name)
{
$element = '$submit_' . $name . ' = new Zend_Form_Element_Submit('
. "'submit_$name'" . "); \n\t\t"
. '$this->addElement($submit_' . $name . ');';
return $element;
}
}

* This source code was highlighted with Source Code Highlighter.


Even here there is much Razgulyai, for example if the data type in mysql is DATE then you can bind that this, issued as a decorator, or make different validators for each data type. Flight of fancy is unlimited.

In the past, you can sheronovich almost anything — kontrollery, model, thereby freeing yourself from unnecessary work.
Or use Zend_Tool + Zend_Application to generate the site structure and some of its classes from the console of your operating system.
Of course, the code generated in this way requires elaboration file, but still it will take less time than writing it from the beginning.
Hard waiting for the release of 1.8 version, but for now deal with the amendments. It seems to me that the developers of the Zend Framework in the release version, will do FormGenerator and all sorts of Goodies.

P. S: the Author is Gibbzy.
Article based on information from habrahabr.ru

Комментарии

Популярные сообщения из этого блога

Car navigation in detail

PostgreSQL: Analytics for DBA

Google has launched an online training course advanced search