Thursday, August 28, 2014

PHPUnit in Zend Framework 2

Hi,

Process of setup PHPUnit testing in Zend Framework-2:

NOTE: Before starting to describe the process of PHPUnit i assuming that readers are aware of Zend Framework-2.

Step 1: PHPUnit Installation with the help of "Pear"
# pear config-set auto_discover 1
# pear install pear.phpunit.de/PHPUnit

Step 2: Create "test" directory inside your module.

Step 3: create phpunit.xml, TestConfig.php and Bootstrap.php file inside the "test" directory.

phpunit.xml File
<?xml version="1.0" encoding="UTF-8"?> 
<phpunit bootstrap="Bootstrap.php">
 <php>
  <!--server name="SERVER_PORT" value="80"/ -->
   </php>
    <testsuites>
        <testsuite name="Demo PHPUnit">
            <directory>./ApplicationTest</directory>
        </testsuite>
    </testsuites>
</phpunit>

TestConfig.php

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
<?php
return array(
    'modules' => array(
        // Other modules needed
        'Application',
    ),
    'module_listener_options'   => array(
        'config_glob_paths' => array(
            '../../../config/autoload/{,*.}{global,local}.php',
        ),
        'module_paths'      => array(
            'module',
            'vendor',
        ),
    ),
);


Bootstrap.php

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
<?php
namespace ApplicationTest; // our namespace
 
use Zend\Loader\AutoloaderFactory;
use Zend\Mvc\Service\ServiceManagerConfig;
use Zend\ServiceManager\ServiceManager;
use Zend\Stdlib\ArrayUtils;
use RuntimeException;
use Zend\Session\Container;
 
error_reporting(E_ALL | E_STRICT);
chdir(__DIR__);
 
class Bootstrap
{
    protected static $serviceManager;
    protected static $config;
    protected static $bootstrap;
 
    public static function init()
    {
        // Load the user-defined test configuration file, if it exists; otherwise, load
        if (is_readable(__DIR__ . '/TestConfig.php')) {
            $testConfig = include __DIR__ . '/TestConfig.php';
        } else {
            $testConfig = include __DIR__ . '/TestConfig.php.dist';
        }
 
        $zf2ModulePaths = array();
 
        if (isset($testConfig['module_listener_options']['module_paths'])) {
            $modulePaths = $testConfig['module_listener_options']['module_paths'];
            foreach ($modulePaths as $modulePath) {
                if (($path = static::findParentPath($modulePath)) ) {
                    $zf2ModulePaths[] = $path;
                }
            }
        }
         
        $zf2ModulePaths  = implode(PATH_SEPARATOR, $zf2ModulePaths) . PATH_SEPARATOR;
        $zf2ModulePaths .= getenv('ZF2_MODULES_TEST_PATHS') ?: (defined('ZF2_MODULES_TEST_PATHS') ? ZF2_MODULES_TEST_PATHS : '');
 
        static::initAutoloader();
 
        // use ModuleManager to load this module and it's dependencies
        $baseConfig = array(
            'module_listener_options' => array(
                'module_paths' => explode(PATH_SEPARATOR, $zf2ModulePaths),
            ),
        );
 
        $config = ArrayUtils::merge($baseConfig, $testConfig);
 
        $serviceManager = new ServiceManager(new ServiceManagerConfig());
        $serviceManager->setService('ApplicationConfig', $config);
        $serviceManager->get('ModuleManager')->loadModules();
 
        static::$serviceManager = $serviceManager;
        static::$config = $config;
    }
 
    public static function getServiceManager()
    {      
        return static::$serviceManager;
    }
 
    public static function getConfig()
    {
        
        return static::$config;
    }
 
    protected static function initAutoloader()
    {
        $vendorPath = static::findParentPath('vendor');
 
        if (is_readable($vendorPath . '/autoload.php')) {
            $loader = include $vendorPath . '/autoload.php';
        } else {
            $zf2Path = getenv('ZF2_PATH') ?: (defined('ZF2_PATH') ? ZF2_PATH : (is_dir($vendorPath . '/ZF2/library') ? $vendorPath . '/ZF2/library' : false));
 
            if (!$zf2Path) {
                throw new RuntimeException('Unable to load ZF2. Run `php composer.phar install` or define a ZF2_PATH environment variable.');
            }
 
            include $zf2Path . '/Zend/Loader/AutoloaderFactory.php';
 
        }
        
        AutoloaderFactory::factory(array(
            'Zend\Loader\StandardAutoloader' => array(
                'autoregister_zf' => true,
                'namespaces' => array(
                    __NAMESPACE__ => __DIR__ . '/' . __NAMESPACE__,
                ),
            ),
        ));
    }
 
    protected static function findParentPath($path)
    {
        $dir = __DIR__;
        $previousDir = '.';
        while (!is_dir($dir . '/' . $path)) {
            $dir = dirname($dir);
            if ($previousDir === $dir) return false;
            $previousDir = $dir;
        }
        return $dir . '/' . $path;
    }
}
 
Bootstrap::init();



Step 4: Create directory for module testing inside the "test" directory. Name should be same as the module name.
EX: if your module name is "Report" then your testing module-name would be "ReportTest"

Step 5: Create Controller directory whose name would be "Controller" inside the Test module i.e. "ReportTest"

Step 6: Create controller class file inside your controller dir, named as your main module controller file-name.
ex: your module controller name as "IndexController" then test-module controller file name should be "IndexControllerTest".

IndexControllerTest.php

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
<?php
 
namespace ApplicationTest\Controller;
use ApplicationTest\Bootstrap;
use Zend\Mvc\Router\Http\TreeRouteStack as HttpRouter;
use Application\Controller\IndexController;
use Zend\Http\Request;
use Zend\Http\Response;
use Zend\Mvc\MvcEvent;
use Zend\Mvc\Router\RouteMatch;
use Zend\Test\PHPUnit\Controller\AbstractControllerTestCase;
// use Zend\Test\PHPUnit\Controller\AbstractHttpControllerTestCase;
class IndexControllerTest extends AbstractControllerTestCase
{
    protected $controller;
    protected $request;
    protected $response;
    protected $routeMatch;
    protected $event;
    protected $userMockObj;
    protected $serviceManager;
    
    public function setUp()
    {
        $this->serviceManager = Bootstrap::getServiceManager();
        $this->controller = new IndexController();
        $this->request    = new Request();
        $this->routeMatch = new RouteMatch(array('controller' => 'index'));
        $this->event      = new MvcEvent();
        $config = $this->serviceManager->get('Config');
        $routerConfig = isset($config['router']) ? $config['router'] : array();
        $router = HttpRouter::factory($routerConfig);
         
        $this->event->setRouter($router);
        $this->event->setRouteMatch($this->routeMatch);
        $this->controller->setEvent($this->event);
        $this->controller->setServiceLocator($this->serviceManager);
        $this->userMockObj = $this->getMockBuilder('Application\Model\TestModel')
                                    ->disableOriginalConstructor()
                                    ->getMock();
        $this->setApplicationConfig(
                include __DIR__.'/../../TestConfig.php'
        );
        parent::setUp();
    }
    
    public function testWorkAction() 
    {
        $this->serviceManager->setAllowOverride(true);
        $this->serviceManager->setService('Application\Model\TestModel', $this->userMockObj);
        
        $this->routeMatch->setParam('action', 'work');
        $response = $this->controller->getResponse();
        $result   = $this->controller->dispatch($this->request, $response);
        
        $this->assertEquals(200, $response->getStatusCode());
        
        // Check a ViewModel has been returned
        $this->assertInstanceOf('Zend\View\Model\ViewModel', $result);
        
        // Test against the test data
        $variables = $result->getVariables();
        $this->assertArrayHasKey('name', $variables);
        // Very lazy validation of data ;-)
        $this->assertEquals('OSSCube1', $variables["name"]);

        $this->dispatch('/index');
        $this->assertModuleName('Application');
        $this->assertControllerClass('IndexController');
        $this->assertMatchedRouteName('xyz');
        $this->assertControllerName('Application\Controller\Index');
    }

    public function testMemory() {
        $this->assertGreaterThanOrEqual(699328, memory_get_usage());
    }
}
?>


Now your directory structure would look like as:


Step 7: Run the phpunit inside of the "test" directory. then you will see some output if your test run successfully like as :

#phpunit
PHPUnit 4.1.3 by Sebastian Bergmann.
..
Time: 00:00
OK (2 tests)

Step 8: Some time you will get error, then there would be some code return that has some significant role like as:
. Printed when the test succeeds.
F Printed when an assertion fails while running the test method.
E Printed when an error occurs while running the test method.
S Printed when the test has been skipped.
I  Printed when the test is marked as being incomplete or not yet implemented.
Step 9: To get the html report for the code coverage analysis of your code, it's a 
feature of the phpunit to get the beautiful html formatted dashboard and reports.
To get this feature you have to install the PHP xDebug module.
# sudo pecl install xdebug 
Now, You can create the report by the below command:
# phpunit --coverage-html dir-name
Here, dir-name is the directory where you will put the report content. It will take bit of time to generate the html report. Once your report generated then just open the index.html file in your browser....










To see the code coverage for the tested code:



















In similar way you can get the dashboard on click of dashboard link that contain nice graph(s):
















I hope it will help you to run PHPUnit in Zend Framework-2. If anybody got issue during setup, Please put your comment, i highly appreciate that.. :)


Monday, June 30, 2014

Zend Server Deployment : With the help of ZPK File

Deployment of ZPK file of your application is pretty simple as compared to ZPK file creation.

Minimum requirement of the ZPK file deployment is installed Zend-Server version 6.2 on your system.

Once Zend-Server installed, just logged-in into zend-server, where you will see the home screen like as :


Here, You will see the Application tab where you can deploy the zpk file of your application.

click on the "Application -> Apps" tab, then you will see the below screen as:



Here, you will see the number of application deployed in "Name" column.
Now click on "Deploy Application" then select your ZPK file to deploy.


























Here, you will see option to upload the zpk file, upload your ZPK file and click next:



























Fill the "Display Name" which will appear in the "Name" column after deploy. Here, you can add your virtual host name where your application will resolve. Path field is optional, if you add path then Url would be like as:
"http://cmdpglock.in:80/path"

After fill the all detail, click "Next". after that you will see the Licence agreement screen as:


























Just accept the agreement of Licence, then click "Next".

Here, you will see all the Prerequisites for the application deploy, If all are okey, then click "Next" :

Fill "Host" as your Hosting server address, Database credentials etc. then click "Next" for the final deployment:
Click on Deploy, you will see the updated screen with your deploy name in "Name" column.

Now open the host URL of your site in your browser, your will see that your site is working.

Its Easy and simple :)

Here, now question is where is your virtual hosting occur at server level?

Virtual-host is setup at zend-server installation via creating a new .conf file at "/usr/local/zend/etc/site.d/" location and your application content stored at "/usr/local/zend/var/apps/http/" location.

Cool...

I hope above content would be helpful for the deploy process.






 

Thursday, June 26, 2014

Creating an Application Package(.ZPK) for Deployment on Zend Server

Hi,

This article is aimed to help you better understand how to better deal with deployments in your development workflow and provide some best practices for deployments. Sometimes a bad production deployment can ruin all the effort you invested in a development process. Having a solid deployment workflow can become one of the greatest advantages of your team.

So what actually is deployment means ?

Deploying an application is the process of copying, configuring and enabling a specific application to a specific base URL on Zend Server or on a cluster. Once the deployment process has finished, the application becomes publicly accessible on the base URL. The server carries out this two step process by first staging the application, and then activating it after successful staging.



The deployment mechanism in Zend Server uses a ZPK file, which contains the source code, assets and the deployment descriptor.

Application Package(.zpk) file for the deployment on Zend Server can be created via a Zend-Studio GUI OR Linux console.Both are ease to implement.

Via Zend-Studio IDE: This is for GUI lover :)

Step 1: 
From Zend IDE, select your application for which you want to create the zpk file.

Step 2: 
Right click on the application, then selecting “Add Application Deployment Support”

 
It will create deployment.xml file in your aplication and opens it on your IDE.

Step 3: 
Screen that you will get on your IDE is:



Most of the fields are self explanatory but a few might require a few words.
  • Document Root – This is the document root which is relative to the base directory of the deployment. 
  • License – This is the relative path to a text file in the project directory structure that contains the EULA for the project.  During the deployment work-flow in the UI the end user will be presented with this if the file is available and will be required to agree to it before proceeding.
  • Persistent Resources – These are items that you don’t want to have overwritten during an upgrade.  For example, cache directories.

Dependencies

There are several different types of dependencies you can specify for your application.
These dependencies will be checked prior to deploying the application.  If they are not satisfied then the application will not deploy.

Triggers

There are several triggers that can be hooked into during the deployment process, each of which has a Pre and Post stage
  • Activate
  • Deactivate
  • Stage
  • Unstage
To set up a trigger simply double click on the stage that you would like to edit and a new file will be created for you.  In that file will be documentation on information on how to retrieve variables and parameters for your deployment scripts.
Speaking of variables and parameters, what is the difference?  There are two differences.
  1. Variables you cannot change during the deployment process.  What the value is in the deployment file is the value that you will get in the deployment script.  Parameters need to be specified during the deployment work-flow and also have some validation that you can do on the entered values whereas with variables you do not.
  2. Both are accessible via getenv() during deployment but variables are retrieved with their names “as is” but parameters are upper cased and prepended with “ZS_”.  So if you have a parameter named “ugly_Duckling” it would be accessed via getenv(‘ZS_UGLY_DUCKLING’)

Package

There may be files in your application that you want to include or exclude.  You can specify those in the Package panel.
 
Exporting
The last step is to export your project.  Right click on the project and select Export and choose “Deployment Package”.  This will output the project into a ZPK file that you can then upload to your Zend Server instance or Zend Application Fabric installation where it will be deployed to your website. 







=================================================
 Via Linux Console : This is for Command line lovers :)
=================================================

Here, i am using Zend's Deployment Tool that allows you to create a skeleton package, and pack the contents into a .zpk package.

Tool location - The tool is located in:
  • Linux - '/usr/local/zend/bin/zdpack'
  • Windows - 'C:Program Files\Zend\ZendServer\bin\zdpack' -OR- as a 
  • standalone (if downloaded separately from the product).

Usage - Run the help command (Linux: '<install_dir>/bin/zdpack --help'; Windows: 'zdpack.exe --help') from the bin directory to see the usage.

The command line actions are:
Step 1
Select a directory and use the create command (Linux: '<install_dir>/bin/zdpack create <application-name>'; Windows: zdpack.exe create <application-name>'
where is your application's name) to create the skeleton of your .zpk package. This includes the XML descriptor file, the data folder and the hook scripts (templates).
Go to the directory to see the resources that have been created:
  • Data folder - The folder that will contain your application files.
  • Scripts folder - The hook script skeletons available for you to edit as needed. 
  • deployment.xml file - The template of the XML descriptor for you to edit as needed.

Step 2:
Perform the following actions:
  • Place your application files in the data folder. 
  • Edit the hook scripts according to your needs. 
  • Edit the XML file as needed. The XML template is made up of example elements.  
  • Validate the package by using the validate command (Linux: '<install_dir>/bin/zdpack validate [--schema=<xsd-file>] <package-xml-descriptor-file>'; Windows: 'zdpack.exe validate [--schema=<xsd-file>] <package-xml-descriptor-file>'). 

For example:
# /usr/local/zend/bin/zdpack validate --schema="/usr/local/zend/share/deployment.xsd" deployment.xml


NOTE: For ZF2 application zpk file creation, I edit the deployement.xml file for the document root settings i.e.
<docroot>data</docroot> 
TO 
<docroot>data/public</docroot>

Step 3:
Use the pack command (Linux: '<install_dir>/bin/zdpack pack <application-name>'; Windows: 'zdpack.exe pack <application-name>') to pack the contents into a .zpk package. By default, the Deployment Tool will create the package in the working directory.
For Example:
# /usr/local/zend/bin/zdpack pack my_application_dir


Once you have a .zpk application package ready and packed, you can deploy your application OR update an existing application.


--
Bye Buddy

Monday, June 23, 2014

OOP : When to prefer an Abstract Class and Interface

Hi,

Abstract classes allow you to provide default functionality for the subclasses.

Why is this extremely important though?
If you plan on updating this base class throughout the life of your program, it is best to allow that base class to be an abstract class.

Why?
Because you can make a change to it and all of the inheriting classes will now have this new functionality.

If the base class keep on changing and an interface was used instead of an abstract class, we are going to run into problems. Once an interface is changed, any class that implements that will be broken. Now if it's just you working on the project, that’s no big deal. However, once your interface is published to the client, that interface needs to be locked down. At that point, you will be breaking the clients code.

As per my personal experiences, frameworks is a good place to show when and where to use both an abstract class and an interface.

Another general rule is if you are creating something that provides common functionality to unrelated classes, use an interface. If you are creating something for objects that are closely related in a hierarchy, use an abstract class.

An Example of this would be something like a business rules engine. This engine would take in multiple BusinessRules as classes perhaps? Each one of these classes will have an analyze function on it.

public interface BusinessRule{
     Boolean analyze(Object o);
}

This can be used ANYWHERE. It can be used to verify the state of your application. Verify data is correct. Verify that the user is logged in. Each one of these classes just needs to implement the analyze function, which will be different for each rule.

Where as if we were creating a generic List object, the use of abstract classes would be better. Every single List object is going to display the data in a list in some form or another. The base functionality would be to have it go through its data provider and build that list. If we want to change that List object, we just extend it, override our build list function, change what we want and call super.buildList();

In Brief: interfaces means you are just defining a list of functions and that abstract classes has the option of providing default functionality.

Tuesday, May 27, 2014

WebSite Page Locking

Hi Everybody,

Today, Again i shared my next module "Page-Lock" in Zend-Framework 2.

Basically page locking is important when you want your site should be more secure in terms of transactions and updation happening across the site.


This module contain the following feature:
1. If one user open let's say the home page, then the same user can not open it on the other browser.

2. If your application handling the login mechanism then this module also handle the locking on logged-in user accordingly.

3. It has the feature where you can set the time period of locking. Its adjustable from flat file.

4. It's lightweight, simple and shower.


You can download the page-lock module from  the Zend-Framework 2 module sites i.e.

URL : https://github.com/tarun-singhal/page-lock

Here, you can find the installation process i.e. how to implement it in your application.


I will be more thankful to you, if i got some feedback from your side :)





Bye...


Thursday, May 22, 2014

Zend Framework 2: JobQueue Module

Hi,

Today i share my first module "JobQueue" on Zend-Framework 2 module site :)

URL : http://modules.zendframework.com/

JobQueue is a Feature of the Zend-Server and i use this feature in Zend-Framework2.

JobQueue Module is basically use to handle heavy background process. It helps to increase the Web App performance.  JobQueue service can be used for the following scenarios :
  1. Preparing data for the next request (pre-calculating)
  2. Pre-caching data
  3. Generating periodical reports 
  4. Sending e-mails 
  5. Cleaning temporary data or files 
  6. Communicating with external systems.

    Job Queue module is useful with Zend Server 5 (though not as part of the Community Edition).
You can download the JobQueue Module from Git-hub i.e
URL : https://github.com/tarun-singhal/JobQueue

NOTE: Please make sure your zend-server service should be running.

Below screen-shot that shows, once you run the module in your application then you can view your application job status send via JobQueue module on zend-server.
 


Wednesday, March 26, 2014

GIT Tag

Hi,

Create GIT Tag on your project is useful to keep track of your project release.

Step to create the Tag in GIT are:

1.  # git tag -a V2 -m "tag 2"

2. # git push origin V2

Where, V2 : relate the tag name

If you want to switch into previous tag

# git checkout tag-name

where tag-name, is the tag no where you want switch back/fro to the release.


To get list GIT tag
# git tag


To cloning the branch or tag
# git clone --branch tag_name repo_url

Where,
tag_name : GIT tag no.
repo_url : GIT URL


To get the checkout from the Tag
# git checkout tags/tag-name

I hope above GIT tag command is useful to manage tag.