I have already introduced you to this application, and i already told you about the porting process to Zend Framework 2 but that's not all. Since i finished the first version which only worked for Greek documents, i always wanted to add support for the English language and extend it further more.

So after a few weeks of work and research here it is with a brand new name, Sum+my, which stands for Summarization Methodology Yardstick.

summy_home.png summy_admin_documents.png summy_admin_terms.png  

 

Changelog v2.0

  • Brand New Appearance based on Twitter Bootstrap
  • Ported Application to Zend Framework 2.0
  • Added Support for English Language
  • Added Stemmer Test Page
  • Fixed typos in the Greek Stemmer, improved accuracy a lot!
  • Summaries are now cached, to avoid double posting, the links are by no means permanent!

 summy_admin_home.png summy_stemmer_en.png summy_changelog.png

It's probably the work i am most proud because it's so out of my element, so give it a try you might  actually find it a great tool for everyday tasks and let me know if you have any ideas to improve it further or why not start adding support for more languages. For that you might also want to check the docs of the Sum+my

 

I finished yesterday porting Sum+my to zf2, it will be online after some new features and further development. The process wasn't very hard and you don't have to master zf2 before you begin or even to finish the task. There are already a lot of resources about zf2 and to be able to see code from real life applications from the modules.zendframework.com is a huge bonus. In my case it was a very small application with only 5-6 controllers with a few extra controller plugins, acl + auth + the 15 classes based on Zend\Filter, and it took about 5 hours of work, mostly reading and copy/paste.

First of all performance impressions, out of the box with zero optimization, zf2 is a little friendlier on memory but a little worse on speed. The differences are small but noticeable, i can't give you excact numbers cause i couldn't bother with extensive tests so take my opinion or leave it.

Secondly some tips:

  1. If you are building multi-modular applications avoid doublicate configurations, otherwise you will often be stuck wondering why some changes don't take effect.
  2. The code hasn't changed that much, zf2 hasn't been rewritten from scratch with a few exceptions, so you will often end up wondering what's up with all the fuss about zf2 being hard to start with 
    $error = false;
    $return = $this->params()->fromQuery('return');
    if($this->getRequest()->isPost())
    {
    	$username = $this->params()->fromPost('username');
    	$password = $this->params()->fromPost('password');
    	$return = $this->params()->fromPost('return');
    
    	if($username != '' AND $password != '')
    	{
    		$adapter = $auth->getAdapter();
    		$adapter->setIdentity($username)
    				->setCredential(hash('SHA256', $password));
    
    		$result = $adapter->authenticate();
    		if($result->isValid())
    		{
    			$auth->getStorage()->write($adapter->getResultRowObject(null, 'password'));
    			if($return)
    			{
    				return $this->redirect()->toUrl(base64_decode($return));
    			}
    			return $this->redirect()->toRoute('default', array('controller' => 'index', 'action' => 'index'));
    		}
    	}
    	$error = true;
    }
    

    zf2 vs zf1

    if($this->getRequest()->isPost())
    {
    	$username = $this->_request->getParam('username');
    	$password = $this->_request->getParam('password');
    
    	if($username != '' AND $password != '')
    	{
    		$adapter = new Zend_Auth_Adapter_DbTable(Zend_Db_Table::getDefaultAdapter());
    		$adapter->setTableName('user')
    				->setIdentityColumn('username')
    				->setCredentialColumn('password')
    				->setIdentity($username)
    				->setCredential(hash('SHA256', $password));
    
    		$auth = Zend_Auth::getInstance();
    		$result = $auth->authenticate($adapter);
    		if($result->isValid())
    		{
    			$auth->getStorage()->write($adapter->getResultRowObject(null, 'password'));
    			$returnUri = $this->_getParam('returnUri');
    			$this->_helper->redirector->gotoUrlAndExit($returnUri);
    		}
    	}
    	$this->view->loginFailed = true;
    	$this->view->returnUri = $this->_getParam('returnUri');
    }
  3. The default route you will find in the skeleton app is very basic, so to at least achieve the main function of zf1 default route /controller/action/id use the bellow route, it also supports extra query params, if you call the url helper with route name 'default/query'
    'default' => array(
    	'type' => 'Segment',
    	'options' => array(
    		'route' => '/[:controller[/:action]][/:id]',
    		'constraints' => array(
    			'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
    			'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
    			'id' => '([0-9]+)?'
    		),
    		'defaults' => array(
    			'__NAMESPACE__' => 'Application\Controller',
    			'controller' => 'Application\Controller\Index',
    			'action' => 'index',
    			'id' => false
    		),
    	),
    	'may_terminate' => true,
    	'child_routes' => array(
    		'query' => array(
    			'type' => 'Query',
    		),
    	),
    ),
  4. If you stepped on a bug there is a good possibility you are not the first one to discover it, check the zf2 github as much as possible.
  5. Use the zf2 classmap generator to make autoloading a hell of a lot faster.

 

That's all for now, i will continue posting about ZF2, my opinion about it has improved a lot since i started porting one of my old zf1 applications and check back maybe i will start posting some very interesting tutorials about Zend Framework 2

 

Day number two of porting this application to zend framework 2. I only had a couple of hours today but still i have a couple of things i actually want to talk about. I keep encountering things that are not that much different from ZF1 like Zend\Navigation or Zend\Paginator. I was quite surprised i got them working in seconds.

In the app i have a paginated list of documents, and below is how the code changed:

Zend Framework 1

$db = Zend_Db_Table_Abstract::getDefaultAdapter();
$select = $db->select()->from('document', $orders)->order(array("$order $way"));
$paginator = Zend_Paginator::factory($select);
$paginator->setDefaultItemCountPerPage($perpage);
$paginator->setCurrentPageNumber($this->_getParam('page'));

Zend Framework 2

$db = $this->getServiceLocator()->get('db');
$select = new Select('document');
$select->columns($orders)->order("$order $way");
$paginator = new Paginator(new DbSelect($select, $db));
$paginator->setDefaultItemCountPerPage($perpage);
$paginator->setCurrentPageNumber($page);

 

 Which if you exclude all the Use Statements you have to add on top it's not bad, i actually think it pretty much the same. It would be nice to be able to get the Select object from the adapter but it's not a big deal. The second thing of the day was how actively the ZF2 is developed. I found a couple bugs today working with v2.0.3. The most important was with the Zend\Mvc\Router\Http\Query which was adding the controller, action and namespace parameters to the query string, instead of only adding the extra parameters it was receiving. But guess what download the latest version from github and voila bugs are gone. (Lithium are you there... ;p). That really made my day, i make it a habit not following popular trends or rooting for the underdogs, see my history. I started learning php with LDU cms probably the most unkown cms of all and now choosing Lithium for Komposta Core instead of one of the most popular frameworks like Zend or Symphone or CakePHP for pete sake. So it felt great to go from the disappointing moment  of finding a bug to see that i was fixed in a minute. People are whining how much ZF2 changed and that it got a bit Java-ish but today at least, in my mind ZF2 will succeed because of the active developers and contributors.

zf2.pngI 've been following zf2 from the very first beta versions mainly reading presentations, tutorials and occasionally i browsed the code especially the skeleton application to see how the project progressed. So far i wasn't very impressed with it, the common view as i understand it is that it's not quite there yet and that it needs to be refined more before people really start to jump in and port their old applications to the new framework.

Today thought i started porting my BA thesis application from ZF1 to ZF2 as i plan to extend it  and add new features. The application consists of 5 controllers, a few plugins/helpers and the main engine that produces automatic summarization for Greek language which is a bunch of filters also written in ZF1. Beside that there are Users and Administration systems in place to easily manage the internal data.

I actually managed to accomplice more than i thought for day one. I got the front-end controllers and the summarization engine working with ZF2 quite easily. But still some things really bothered me. The most annoying thing of the day is the new Zend\Db it's obvious that they tried to enforce the Model part of the new MVC concept and it's not there not by a mile not when you have to inject every custom model with the TableGetAway which has to also be injected with the Db\Adapter.  

class Module
{
    // getAutoloaderConfig() and getConfig() methods here

    // Add this method:
    public function getServiceConfig()
    {
        return array(
            'factories' => array(
                'Album\Model\AlbumTable' =>  function($sm) {
                    $tableGateway = $sm->get('AlbumTableGateway');
                    $table = new AlbumTable($tableGateway);
                    return $table;
                },
                'AlbumTableGateway' => function ($sm) {
                    $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
                    $resultSetPrototype = new ResultSet();
                    $resultSetPrototype->setArrayObjectPrototype(new Album());
                    return new TableGateway('album', $dbAdapter, null, $resultSetPrototype);
                },
            ),
        );
    }
}

I am pretty sure there is a smarter way to go that people already use in their modules but that official example is a joke. In my case there are about 4 mysql tables and in the current code base so i didn't bother with models since the system is quite predictable about future features and queries so i prefered the direct approach, here is an example of ZF1 vs ZF2 for running raw queries.

 Zend Framework 1.11

$db = Zend_Db_Table::getDefaultAdapter();
$docu = $db->fetchOne("SELECT COUNT(*) as unprocessed FROM document WHERE processed = 0");

Zend Framework 2.0.3

$db = $this->getServiceLocator()->get('db');
list($docu) = $db->query("SELECT COUNT(*) as total FROM document WHERE processed = 0")->execute()->current();

So my first day wasn't very positive. It was easy to port basic stuff and start working but on the other hand i am not seeing many advantages so far. Keep in touch as i will post daily about my experience with zf2.