September 27th, 2012 | Tags:

Today I had a little problemn with two checkboxes. Well I wanted to add some functionality depending on the status of two checkboxes.

Basically there where four situations:

1. Both chekcboxes are checked

2. Both checkboxes are not checked

3. Only checkbox 1 is checked

3. Only checkbox 2 is checked

So i started with thome basic html and jquery:

1
2

And then the jQuery

$('#checkbox-1, #checkbox-2').bind('change', function() {

if($('#checkbox-1').is(":checked") && $('#checkbox-2').is(":checked")){

sValue = 'both checkboxes are checked';

}

if($('#checkbox-1').is(":checked") && $('#checkbox-2').not(":checked")){

sValue = 'checkbox-1 is checked';

}

if($('#checkbox-2').is(":checked") && $('#checkbox-1').not(":checked")){

sValue = 'checkbox-2 is checked';

}

if($('#checkbox-1').not(":checked") && $('#checkbox-2').not(":checked")){

sValue = 'both checkboxes are checked';

}

alert(sValue);

});

After running this code, you will soon find out that this code is not working well. For example in many of the cases you will get the message “‘both checkboxes are checked”.

 

The reason for this incorrect behaviour is the misleading usage of the .is and .not selectors. At first you might think that you’re doing some action when one checkbox is checked and the other one is not checked.  But this is not true. Lets for example take a short look at one of the if statements:

 

if($('#checkbox-1').not(":checked") && $('#checkbox-2').is(":checked"))

Lets say checkbox 1 is not checked and checkbox 2 is checked.

 

$('#checkbox-1').not(":checked")

will return true  and

$('#checkbox-2').is(":checked") 

will also return true and thus you will get unwanted behaviour.

The solution is to do it like this:

$('#checkbox-1, #checkbox-2').bind('change', function() {

if($('#checkbox-1').is(":checked") && $('#checkbox-2').is(":checked")){

sValue = 'both checkboxes are checked';

}

if($('#checkbox-1').is(":checked") && !$('#checkbox-2').is(":checked")){

sValue = 'checkbox-1 is checked';

}

if($('#checkbox-2').is(":checked") && !$('#checkbox-1').is(":checked")){

sValue = 'checkbox-2 is checked';

}

if(!$('#checkbox-1').is(":checked") && !$('#checkbox-2').is(":checked")){

sValue = 'both checkboxes are checked';

}

alert(sValue);

});

So change

:not

for

:is

And put an “!” before the “$”-sign

Comments Off
July 21st, 2011 | Tags: , ,

About one and a half year ago I remember that I had a look at Doctrine 1. It was pretty easy to install and use. The functions where pretty intuitive and it looked very cool. Even when i wanted to implement it to the Zend Framework.

I hadn’t been using Doctrine for a while and decided to pick it up two weeks ago, as we wanted to see if we can implement it for our CMS at our office. So I setup a clean installation of the zend framework (1.11.9) and tried tried to implement Doctrine.

The main goal was to see if we can reverse engineer existing databases and then start doing some queries.

Finding 1:
It was quite hard to get it going. I was confronted to numerous terminologies which I didn’t understand. What are Proxies, why do we need them? What are annotations? What is the entityManager for?  And so on.

Finding 2:
It was hard to get directions to get the Doctrine classes working with the Zend Framework. We had a hard time getting all autoloaders functioning correct. It also plays a role that Doctrine 2.1 uses Namespaces and the Zend Framework doesn’t yet.

protected function _initDoctrine()
    {
        // Get the configuration options from the application.ini file
        $options = $this->getOption('doctrine');               

        // Get the Zend Autoloader
        $zendAutoloader = Zend_Loader_Autoloader::getInstance();

        // Autoload the doctrine objects
        $autoloader = array(new \Doctrine\Common\ClassLoader('Doctrine'), 'loadClass');
        $zendAutoloader->pushAutoloader($autoloader, 'Doctrine');

        // Autoload the models
        $autoloader = array(new \Doctrine\Common\ClassLoader('Entities', $options['entitiesPath']), 'loadClass');
        $zendAutoloader->pushAutoloader($autoloader, 'Entities');

        // Now configure doctrine
        if ('development' == APPLICATION_ENV) {
            $cacheClass = isset($options['cacheClass']) ? $options['cacheClass'] : 'Doctrine\Common\Cache\ArrayCache';
        } else {
            $cacheClass = isset($options['cacheClass']) ? $options['cacheClass'] : 'Doctrine\Common\Cache\ApcCache';
        }
        $cache = new $cacheClass();

        // Setup the Doctrine configuration
        $config = new Configuration();
        $config -> setMetadataCacheImpl($cache);
        $config -> setMetadataDriverImpl(Doctrine\ORM\Mapping\Driver\AnnotationDriver::create(array($options['entitiesPath'])));
        $config -> setQueryCacheImpl($cache);
        $config -> setProxyDir($options['proxiesPath']);
        $config -> setProxyNamespace('Proxies');
        $config -> setEntityNamespaces(array('Entities'));
        $config->setAutoGenerateProxyClasses(true);
        $em = EntityManager::create(
            $options['connection'],
            $config
        );

        // Register the default ORM annotations for Doctrine. This has all the commonly
        // used annotations for the entities.
        AnnotationRegistry::registerFile('Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php');

        // Once we have the EntityManager ready, add it to the registry
        Zend_Registry::set('em', $em);

        // end
        return $em;
    }

I created a resource in my bootstrap file in order to setup, load and configure Doctrine.
Then in my index controller I created a function to generate my entities. When generating my entities based on an existing mysql database i had the following problems

  • All tables need to have a primary key, without a primary key Doctrine 2 will not generate the entities.
  • We had some tables with geometry fields. Doctrine 2 cannot handle these field types yet. I had to change them to doubles or bynaries

Here is the code I used to generate my Entities.

 
public function generateFromDb()
    {
        try {
            $this->_em->getConfiguration()->setMetadataDriverImpl(
                new \Doctrine\ORM\Mapping\Driver\DatabaseDriver(
                    $this->_em->getConnection()->getSchemaManager()
                )
            );
            $cme = new Doctrine\ORM\Tools\Export\ClassMetadataExporter;
            $cme = new \Doctrine\ORM\Tools\Export\ClassMetadataExporter();
            $cmf = new Doctrine\ORM\Tools\DisconnectedClassMetadataFactory;
            $cmf>setEntityManager($this->_em);

            $generator = new \Doctrine\ORM\Tools\EntityGenerator();
            $generator->setUpdateEntityIfExists(true);	// only update if class already exists
            $generator->setGenerateStubMethods(true);
            $generator->setGenerateAnnotations(true);
            $result = $generator->generate($metadata, APPLICATION_PATH . '/models/');

        }
        catch(Exception $e) {
            Zend_Debug::dump($e->getMessage());
        }
    }

After I generated my entities I wasn’t yet able to start my queries. This because I had errors that it couldn’t find my classes `Entities\User`.  Further investigation learned that each Entity class was missing the line `namespace Entities;`. I thought it was just a setting to get this working. But I ended up debugging the `\Doctrine\ORM\Tools\EntityGenerator();`.

Bug?

What happens behind the scenes is that Doctrine creates an metadata array with objects of each database table. Each object has a `name` property which is by default set to have the name of the table. Doctrine scans this name to find a `\\` if it finds the two shlashes it will create a namespace else it will skip and not create a namespace. Huh?? Yes that’s also what I thought.

The easiest solution to solve this was to loop through the objects and and change the name property to something like: `Entities\\User`. When i did this, I was able to create entities having the namespace declaration. And now I am able to start working with queries.

 
  public function generateFromDb()
    {
        try {
            $this->_em->getConfiguration()->setMetadataDriverImpl(
                new \Doctrine\ORM\Mapping\Driver\DatabaseDriver(
                    $this->_em->getConnection()->getSchemaManager()
                )
            );
            $cme = new Doctrine\ORM\Tools\Export\ClassMetadataExporter;
            $cme = new \Doctrine\ORM\Tools\Export\ClassMetadataExporter();
            $cmf = new Doctrine\ORM\Tools\DisconnectedClassMetadataFactory;
            $cmf->setEntityManager($this->_em);
            $metadata = $cmf->getAllMetadata();
            foreach($metadata as $k => $v){
                $bla = $v->name;
                $v->name  = 'Entities\\'. $bla;
            }

            $generator = new \Doctrine\ORM\Tools\EntityGenerator();
            $generator->setUpdateEntityIfExists(true);	// only update if class already exists
            $generator->setGenerateStubMethods(true);
            $generator->setGenerateAnnotations(true);
            $result = $generator->generate($metadata, APPLICATION_PATH . '/models/');

        }
        catch(Exception $e) {
            Zend_Debug::dump($e->getMessage());
        }
    }

}

I think this is a bug, maybe someone in the community has a different solution to this. I would be glad to hear about it.

First thoughts on Doctrine 2.1

The only thing what keeps me going with doctrine 2.1 at the moment is that Doctrine ‘s query’s are easier and faster. The problem is that I haven’t seen much of this yet as it took me a lot of time to get the basic configuration up and running. I also have a lot of question’s which i hope to become clear in the next few days as I continue to work on my little Zend Framework 1.11.x and Doctrine integration 2 project.

There are already a lot of resources available on the Internet. I have looked at various configurations, like for example the `bisna` project from Guilhere Blanco.  But I keep saying that it’s really difficult and has a steep learning curve. Doctrine 1.2 was really simple. Doctrine 2.x is a lot more difficult to get into.

July 10th, 2011 | Tags:

This week me and my colleague were working on a new project. We downloaded the newest version of the Zend Framework (1.11.7) and wanted it to work with NetBeans 7.0. on Wamp and Windows 7. Here is a video tutorial from NetBeans how to register the Zend Framework within NetBeans: (http://netbeans.org/kb/docs/php/zend-framework-screencast.html)

1. We added the ZF.bat in the same folder as php.exe

2. Then we added the folder to the Zend Library to our include_path in php.ini:

include_path = ".;K:\xampp\php\PEAR;K:\xampp\php\;K:\xampp\htdocs\shared\Zend\1.11.7\"

But we still got this error when we wanted to register the provider within NetBeans:

***************************** ZF ERROR ********************************
In order to run the zf command, you need to ensure that Zend Framework
is inside your include_path. There are a variety of ways that you can
ensure that this zf command line tool knows where the Zend Framework
library is on your system, but not all of them can be described here.

The easiest way to get the zf command running is to give it the include
path via an environment variable ZEND_TOOL_INCLUDE_PATH or
ZEND_TOOL_INCLUDE_PATH_PREPEND with the proper include path to use,
then run the command “zf –setup”. This command is designed to create
a storage location for your user, as well as create the zf.ini file
that the zf command will consult in order to run properly on your
system.

Example you would run:

$ ZEND_TOOL_INCLUDE_PATH=/path/to/library zf –setup

Your are encourged to read more in the link that follows.
Zend_Tool & CLI Setup Information
(available via the command line “zf –info”)
* Home directory found in environment variable HOMEPATH with value \Documents and Settings\Jigal
* Storage directory assumed in home directory at location \Documents and Settings\Jigal/.zf/
* Storage directory does not exist at \Documents and Settings\Jigal/.zf/
* Config file assumed in home directory at location \Documents and Settings\Jigal/.zf.ini
* Config file does not exist at \Documents and Settings\Jigal/.zf.ini

To change the setup of this tool, run: “zf –setup”

The reason you get this error is because the files and directories which are needed for the zf tool to run are not created.
The solution to these problems are to run these two commands:

 zf --setup storage-directory
 zf --setup config-file

After we did this we where able to run the ZF tools properly with NetBeans 7.0

Comments Off
March 27th, 2011 | Tags: , ,

Just a quick tip about from descriptions. I wanted to show my form description on the screen.

class My_Form
{
    function(init){
        $this->setDescription("This is a description");
    }
}

However when you echo the form in the view your description will not be visible. In order to do this you have to do some more work. Add the following lines at the beginning of the init function.

$this->setDecorators(array(
            'Description',
            'FormElements',
            'Form'
        ));

This is why it is important to understand decorators in the zend framework.
Comments Off
March 22nd, 2011 | Tags:

This week I had another challenge. I was wrestling with an error which is quite common. I am trying to build an application and at the same time I am also trying to write test scripts in order to test the application. Now my application runs beautiful, with no errors at all.

Then I tried to run my tests. And soon I had my first error:

PHPUnit 3.5.13 by Sebastian Bergmann.
FFF..EPHP
Fatal error:  Class 'EventManager_Service_Authentication' not found in K:\xampp\htdocs\nrka2\tests\application\modules\eventManager\application\services\AuthenticationTest.php on line 23                                                                                                                            Fatal error: Class 'EventManager_Service_Authentication' not found in K:\xampp\htdocs\nrka2\tests\application\modules\eventManager\application\services\AuthenticationTest.php on line 23

Of course I was wondering what was going wrong. So I started investigating my TestHelpers which I had written, I started including paths, even the exact files where my EventManager_Service_Authentication class is in but nothing seemed to work.

Here is my TestHelper class which I have written:

define('BASE_PATH', realpath(dirname(__FILE__) . '/../'));
define('APPLICATION_PATH',BASE_PATH.'/application');
define('TEST_PATH',BASE_PATH . '/tests');
define('APPLICATION_ENV','testing');

// Ensure library/ is on include_path
set_include_path(implode(PATH_SEPARATOR, array(
    realpath(BASE_PATH . '/library/'),
    get_include_path()
)));

date_default_timezone_set('Europe/Amsterdam');

require_once 'Zend/Loader/Autoloader.php';
Zend_Loader_Autoloader::getInstance();

/**
 * Get PHPUnit
 */
require_once ('Zend/Application.php');
require_once ('Zend/Test/PHPUnit/ControllerTestCase.php');

class TestHelper extends Zend_Test_PHPUnit_ControllerTestCase
{

    public function setUp()
    {
        $this->bootstrap = new Zend_Application(
                'testing',
                APPLICATION_PATH . '/configs/events.ini'
        );
        $this->bootstrap->bootstrap();
        return parent::setUp();
    }

    public function tearDown()
    {
        $this->resetRequest();
        $thi->resetResponse();
        parent::tearDown();
    }
}

Every test class is extending this simple helper class. Then I started investigating my bootstrap. Because I thought maybe something is wrong with my autoloading of the service directory. But I saw in my bootstrap class that my service directory was loaded.

protected function _initDefaultModuleAutoloader(){
	$this->_logger->info('Bootstrap '. __METHOD__);

	$this->_resourceLoader = new Zend_Application_Module_Autoloader(array(
		'namespace' =>	'EventManager',
		'basePath'	=>	APPLICATION_PATH . '/modules/eventManager',
	));

	$this->_resourceLoader->addResourceTypes(array(
			'modelResource'	=>	array(
			'path'			=>	'models/resources',
			'namespace'		=>	'Resource',
	),
			'service'	=> array(
			'path'		=>	'services',
			'namespace'	=>	'Service'
			),
	));
}

To cut it short, everything seemed right, but even though it was not working. Then i started writing debug lines in my bootstrap file, and soon i figured that my bootstrap file wasn’t executing.

And i figured out that I forgot to call the parent setup method within my setup method.

public function setUp()
    {
        parent::setUp();
        $this->_service = new EventManager_Service_Authentication();
        (...)        
}

And this is how I got it working. So the lesson of today is: never forget your ancestors!

Comments Off