My contemplations and diurnal novelties are publicized here

Archive for the ‘Zend’ Category

Step by step guide for Zend


Sorry for inconvenience; article is in raw state not yet finalized.

   
 

Introduction (Work in progress no to be published)

Using any framework is easy but applying that to real world application can be hard and time consuming task. People do get bits and pieces of the framework from google and other search engines but will not be able to find a concrete example that can help them lay out the ground they need for their start-up in practical application of that framework.

Background

When I started working in Zend framework I find the documentation is more inclined towards getting familiarity with different classes and other aspect of the framework but not a single concrete development example was presented that can bridge the gap between hello world example and real practical example. So I started to work on this article that will not only help you get familiar with Zend framework but will also help you create a web application from scratch to end.

Some good reference    

There are some worth mentioning reference that people can look into, to enhance their knowledge and understanding

http://www.zend.com/en/webinar/Framework/webinar-ZF-Layout-20080319.flv

Some Nice working examples:-

Pr-requisites

  Off-course you should have some familiarity with PHP. I am going to use ZendFramework-1.11.10 so I have uploaded the source as well to avoid any conflicts with future releases. You can also download the latest version here at http://www.zend.com/en/downloads/. You can also download Zend server and Studio for ease of use. Setting up Zend framework is easy so i am letting it up to you. In case I receive any queries related to setup I will surely add some clarification. I also consider that you are familiar with MVC model as well.

So what you have set up till now 

You have Zend studio + Zend server and able to create a new project using Zend studio.  Now I will discuss the directory structure.

 

  1. application.ini purpose of this file is to contain all information related to configurations
    1. (Explained line by line

[production] //// All setting will related to production

phpSettings.display_startup_errors = 0 //// Startup error :setting it to 1 will display errors

phpSettings.display_errors = 0 //// display error :setting it to 1 will display errors

includePaths.library = APPLICATION_PATH “/../library” // Path for library

bootstrap.path = APPLICATION_PATH “/Bootstrap.php” // path for bootstrap file

bootstrap.class = “Bootstrap” // Class name for boot strap

appnamespace = “Application” // name space for application

resources.frontController.controllerDirectory = APPLICATION_PATH “/controllers” // directory for controllers

resources.frontController.params.displayExceptions = 0 // front controller is among one of the core things that a person need to understand

 
 

[staging : production] // having a colon “:” mean all the above configurations are inherited so you don’t need to explicitly set it here too.

 
 

[testing : production]

phpSettings.display_startup_errors = 1

phpSettings.display_errors = 1

 
 

[development : production]

phpSettings.display_startup_errors = 1

phpSettings.display_errors = 1

resources.frontController.params.displayExceptions = 1

 
 

  1. Controller act as a bridge between Model and view. Zend claim that a “Zend_Controller_Front ” act as a main controller that calls other controller on different request.

    Note:- I am still unable to find this zend controller front so it vague for me as of now.

    1. Model:-

      Will help you create some model classed to perform CRUD (Create Read update delete) options. We will look into details as we proceed.

    2. View

      Section contains different view that can be rendered on demand. I always wonder how different views can be merged together to create a full fledge web page.

    3. BootStrap.php

      Will help you put any boot time setting here.

    4. Index.php

      Index.php is the main file that will server all the request. Application environment is setup here and different paths are setup. Then a new “Zend_Applicationobject is created

      <?php

       
       

      // Define path to application directory

      defined(‘APPLICATION_PATH’)

      || define(‘APPLICATION_PATH’, realpath(dirname(__FILE__) . ‘/../application’));

       
       

      // Define application environment

      defined(‘APPLICATION_ENV’)

      || define(‘APPLICATION_ENV’, (getenv(‘APPLICATION_ENV’) ? getenv(‘APPLICATION_ENV’) : ‘production’)); // Production here will tell to use production section in application.ini

       
       

      // Ensure library/ is on include_path

      set_include_path(implode(PATH_SEPARATOR, array(

      realpath(APPLICATION_PATH . ‘/../library’),

      get_include_path(),

      )));

       
       

      /** Zend_Application */

      require_once ‘Zend/Application.php’;

       
       

      // Create application, bootstrap, and run

      $application = new Zend_Application(

      APPLICATION_ENV,

      APPLICATION_PATH . ‘/configs/application.ini’

      );

      $application->bootstrap()->run();

      Ok if you run the following url http://localhost/ZendStepByStep/public/index.php you will be able to use the application.

       
       

    Real work start now:-l

        It seem really cool that now the app is running an you are able to access the URL but now you have accommodate it as per you needs and this is where you have to mold the things as per you need.

    Let have a database configuration now:-

    db.adapter = PDO_MYSQL (Php data objects)

    db.config.host = localhost

    db.config.username = root

    db.config.password =

    db.config.dbname = zsbs

     
     

     
     

 

Consuming dotnet based web service ( returing dataset ) in PHP (Zend).


Consuming a dotnet web service that return dataset can be a nightmare to consume. I tried to consume it and Google several time to find a solution due to inappropriate/incomplete  solution i am writing one.

Here is a subset list of my useful search which you can use as a per-requisite:-

  1. http://stackoverflow.com/questions/279220/how-to-invoke-a-c-sharp-web-service-through-php
  2. http://php.net/manual/en/soapclient.soapcall.php
  3. http://superdotnet.codeplex.com/
  4. http://stackoverflow.com/questions/2749954/asmx-web-service-returning-xml-instead-of-json-in-net-4-0
  5. http://metrix.fcny.org/wiki/display/tips/How+to+Create+a+PHP+Client+for+a+.NET+and+SOAP-based+Web+Service+API
  6. http://stackoverflow.com/questions/5282930/consuming-net-web-services-with-complex-types-in-php

And here comes my solution:-

require_once(‘Zend/Soap/Client.php’);

$url = ‘http://mywebservice/Service.asmx?wsdl&#8217;;
$options = array
(    “soap_version” => SOAP_1_1,
“encoding” => “UTF-8”,
);
$client = new Zend_Soap_Client($url,$options);

$response = $client->GetBalanceSummary(
array(
“AccessKey”=>”13264”,
“AccountNo”=>”4546”,
“CustomerId”=>”4654”,
“Channel”=>”acb”,
“FundCode”=>”aadd”,
)
)->GetBalanceSummaryResult;

$xml = simplexml_load_string($response->any);
$testArray = $xml->xpath(“NewDataSet”);

$testArray2 = $testArray[0];
var_dump($testArray2[0]->Table1);


Client-side validation with Zend_Form

Zend_Form is Zend Framework’s brand new tool for simplifying form creation, parsing, validation and filtering.

There’s one big thing I want from any kind of form generation tool: The ability to let me combine my server-side validators with JavaScript validation on the client, or other such features.

And here’s the thing: Zend_Form is easily extendable to automatically generate JavaScript for validating fields on the client!

 

Decorators, go

The key to this is the ability to give the form decorators. They can be easily used to perform tasks based on the fields in the form, such as seeing what validators they have and generating some JS.

We can easily do this with two decorators:

  • A modified Form decorator to add an onsubmit event
  • Another decorator for looping through each form field and generating the JS code needed. Let’s call this JsValidation decorator.

We will also need to write a bit of JavaScript that will be used for processing the code generated by the second decorator.

The form decorator

The form decorator is very simple. It only needs to set the onsubmit event and add our JavaScript file which will contain the helper code needed.

Download this from CodeUtopia’s SVN repo

<?php
class CU_Form_Decorator_Form extends Zend_Form_Decorator_Form 
{
    public function getOptions()
    {
        $this->setOption('onsubmit','return App.validate(this)');

        $baseUrl = Zend_Controller_Front::getInstance()->getBaseUrl();
        $this->getElement()->getView()->headScript()->appendFile($baseUrl . '/js/Validator.js');

        return parent::getOptions();
    }
}

So that’s it. I will show how to use it later in the post.

The JsValidation decorator

The JsValidation decorator can simply generate a JavaScript object which contains arrays for each of the fields. The arrays will then contain objects which contain the validator’s name and parameters.

//For example, our form has a field called "firstname" with validators NotEmpty and Alnum:
var MyForm = {
    firstname: [{
        name: 'NotEmpty',
        parameters: { }
    }, {
        name: 'Alnum',
        parameters: { allowWhiteSpace: true }
    }]
};

So how do we go about generating such code?

Download this from CodeUtopia’s SVN repo

<?php
/**
 * Generates JS validation rules for form fields
 */
class CU_Form_Decorator_JsValidation extends Zend_Form_Decorator_Abstract 
{
	/**
	 * The name of the form
	 * @var string
	 */
	protected $_formName;

	public function render($content)
	{
		$form = $this->getElement();
		$view = $form->getView();
		$this->_formName = $form->getName();

		if(!$this->_formName)
			$this->_formName = 'form';

		$script = "var Forms = Forms || { };\r\n"
				. "Forms." . $this->_formName . " = { };\r\n";

		foreach($form as $element)
		{
			$validators = $element->getValidators();

			if(count($validators) > 0)
				$script .= $this->_buildValidationRules($element);	
		}

		$view->inlineScript()->captureStart();
		echo $script;
		$view->inlineScript()->captureEnd();

		return $content;
	}

	/**
	 * Generate the JavaScript code for the validation rules
	 * @param Zend_Form_Element $element
	 * @return string
	 */
	protected function _buildValidationRules(Zend_Form_Element $element)
	{
		$name = $element->getName();
		$formName = $this->_formName;
		$validators = $element->getValidators();

		$rules = array();
		foreach($validators as $validator)
		{
			$class = get_class($validator);
			$params = $this->_buildValidatorParameters($class, $validator);
			$rules[] = "{ name: '$class', parameters: $params }";
		}

		if(count($rules) > 0)
			$script = "Forms." . $this->_formName . ".$name = [ " . implode(', ', $rules) . " ];\r\n";

		return $script;
	}

	/**
	 * Generate parameters for a validator rule
	 * @param string $class The name of the validator class
	 * @param Zend_Validate_Interface $validator the validator
	 * @return string
	 */
	protected function _buildValidatorParameters($class, Zend_Validate_Interface $validator)
	{
		$params = '{}';
		switch($class)
		{
			case 'Zend_Validate_Alnum':
			case 'Zend_Validate_Alpha':
				$params = '{ allowWhitespace: ' . (($validator->allowWhiteSpace) ? 'true' : 'false') . ' } ';
				break;

			case 'Zend_Validate_Between':
				$params = '{ min: ' . $validator->getMin() . ', max: ' . $validator->getMax() . ' } ';
				break;
		}

		return $params;
	}
}

Let’s look at each method. Starting from the top, the render method is called when the form is rendered, so we just use this to do our thing. First we grab some variables and define the JS Forms variable that will act as a namespace for our form rules.

In case we have multiple forms, we use the Forms || { } to create it based on the old one if it exists. We also use the form’s name to store the actual rules, so be sure to give your form a name if you have more than one per page – otherwise their rules may collide etc.

Then it’s simply looping over each form field, generating code if necessary.

the _buildValidationRules method generates JS code for each validator in an element. It pretty much just loops over each validator and returns the code.

Finally, the _buildValidatorParameters method is used to generate the parameters for each validator. Since Zend_Validate does not specify a way to get all the parameters a validator may have, we’re just using a switch and looking at each validator class type on its own. This switch can be easily extended by adding more validators. You can also easily create a custom class based on this one and then override this method to do the same.

If you look at the switch, you’ll notice both Alnum and Alpha have the same code. This is because they both share the same parameters. You can actually do this with some validators, and many validators don’t even have any special parameters, so you won’t need a case for them.

The JavaScript code

Of course, we will also need that Validator.js file mentioned in the Form helper. Without that, our rule definitions would just sit in our page doing nothing.

Download this from CodeUtopia’s SVN repo

var App = App || { };

App.validate = function(form)
{
	var formName = (form.name)
	             ? form.name
	             : 'form';

	var rules = Forms[formName];

	var formValidates = true;

	for(var key in rules)
	{
		var element = form[key];
		var ruleset = rules[key];

		var value = (element.nodeName == 'INPUT') 
		          ? element.value
		          : element.innerHTML;

		for(var i in ruleset)
		{
			var validatorName = ruleset[i].name;
			var elementValidates = App.Validator[validatorName](value, ruleset[i].parameters);

			if(elementValidates)
			{
				//You can replace this with whatever you want to happen to invalid fields.
				YAHOO.util.Dom.removeClass(element, 'invalid');
			}
			else 
			{
				//Again, replace if you aren't using YUI.
				YAHOO.util.Dom.addClass(element, 'invalid');

				//but not this
				formValidates = false;
				break;
			}
		}
	}

	return formValidates;
}

App.Validator = {
	Zend_Validate_NotEmpty: function(value, parameters)
	{
		if(value != '')
			return true;

		return false;
	},

	Zend_Validate_Alnum: function(value, parameters)
	{
		if(parameters.allowWhiteSpace)
			return value.match(/^[a-z0-9\s]*$/i);
		else
			return value.match(/^[a-z0-9]*$/i);
	}
};

Again, let’s go through the code step by step.

First, we’re defining the App namespace. Similar to how the Forms variable was defined, we’re making sure that if it exists, we’ll just use the existing one. It’s good practice to namespace your JS code so that it does not interfere with others.

Next, we define the validate function. It looks at the validation rules created by the JsValidation decorator and loops through them. It takes each field and their value and calls each validator defined for the element. I have left some Yahoo UI library specific code there, which you can replace with your own if you aren’t using YUI. It’s nothing major, simply adding a CSS class “invalid” to fields which fail validation.

In the end the function returns if the form validates or not. This is so that if the validation fails, the form will not get submitted.

Next, in the App.Validator namespace we define our JS versions of Zend_Validate classes. I have added two examples, Zend_Validate_NotEmpty and Zend_Validate_Alnum. NotEmpty simply looks if the value was empty and Alnum uses regular expressions to see if the value only contains alphanumeric characters, and if the allowWhiteSpace parameter is set, it also allows that.

Based on those two you should be able to implement your own validators, but as always, feel free to ask if anything is unclear.

Using the decorators

Finally we have all the code we need to actually create an example!

I’m not going to deal with creating forms with Zend_Form here. If you need help with that, there’s some good information in the Zend_Form Webinar slides you can find at Zend Framework Webinars site, and there’s also a good introductionary article to Zend_Form at Rob Allen’s blog.

To use the new decorators, you will need to replace the old Form decorator and add the JsValidation decorator, like this:

//Replace Form decorator with our own
$form->removeDecorator('Form');
$form->addDecorator(new CU_Form_Decorator_Form());

//Add JsValidation
$form->addDecorator(new CU_Form_Decorator_JsValidation());

And that’s it! You now have client-side validation in your form. Do note that you will need to have both HeadScript and InlineScript view helpers’ contents echoed in your view. Otherwise the JavaScript code will not be shown.

You will probably have to define some more validators in JS and to the switch in the PHP code, but other than that, this is a working solution.

I have tested this code myself and it worked, but if you encounter any issues, please post a comment. Also, if you create any JS code for validators, I encourage you to share your code in the comments so that everyone can benefit.

Copied from http://codeutopia.net/blog/2008/04/04/client-side-validation-with-zend_form/

%d bloggers like this: