Tuesday, March 12, 2013

zf2 howto GridFS

GridFS is the mongoDB standard for storing and retrieving files.You can find out more information about GridFS here.

This is how I managed to store and retrieve image using zf2, doctrine-odm and mongoDB.

You can setup a Document,

<?php
namespace Course\Document;

use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;

/** @ODM\Document(collection="course") */
class Course
{
    /** @ODM\Id */
    private $id;

    /** @ODM\File */
    private $thumb;


    public function getId() {
        return $this->id;
    }

    public function getThumb()
    {
        return $this->thumb;
    }

    public function setId($id) {
        $this->id = $id;
    }

     public function setThumb($thumb)
    {
        $this->thumb = $thumb;
    }

    public function exchangeArray($data)
    {
        $this->id               = (isset($data['id']))     ? $data['id']     : null;
        $this->thumb            = (isset($data['thumb'])) ? $data['thumb'] : null;

    }

   public function getArrayCopy()
    {
        return get_object_vars($this);
    }

    public function getObjectAsArray()
    {
        $array = array(
         'thumb' =>$this->thumb,
                      );
        return $array;
    }

}

Then zf2 form with file upload input field, within your function __construct you can add,



$this->setAttribute('method', 'post');
$this->setAttribute('enctype','multipart/form-data');
$this->add(array(
            'name' => 'id',
            'attributes' => array(
                'type'  => 'hidden',
            ),
        ));
$this->add(array(
            'name' => 'thumb',
            'attributes' => array(
                'type'  => 'file',
            ),
            'options' => array(
                'label' => 'Thumbnail',
            ),
        ));

Then create the form,

<?php
$title = 'upload Image';
$this->headTitle($title);
?>
<h1><?php echo $this->escapeHtml($title); ?></h1>
<?php
$form = $this->form;
$form->setAttribute('action', $this->url('image', array('action' => 'add')));
$form->prepare();

echo $this->form()->openTag($form);
echo $this->formRow($form->get('thumb'));
echo $this->formSubmit($form->get('submit'));
echo $this->form()->closeTag();
?>
and finally update your controller with,
$request = $this->getRequest();
        if ($request->isPost()) {

            $data = array_merge_recursive(
            $this->getRequest()->getPost()->toArray(),
            $this->getRequest()->getFiles()->toArray()
             );


     $file_src   = '/tmp/'.$data['thumb']['name'];
         move_uploaded_file($data['thumb']['tmp_name'], $file_src);


    $dm = $this->getServiceLocator()->get('doctrine.documentmanager.odm_default');
    $course = new Course();
    $course->setThumb($file_src);
    $dm->persist($course);
        $dm->flush();

    }

To retrieve image, update controller with
$dm = $this->getServiceLocator()->get('doctrine.documentmanager.odm_default');
        $courses = $dm->createQueryBuilder('Course\Document\Course')
                ->getQuery()
                ->execute();

        return new ViewModel(array(
           'courses' => $courses,
        ));
And your view,
<table class="table">
<tr>
    <th>thumb</th>
    <th>&nbsp;</th>
</tr>
<?php foreach ($courses as $course) : ?>
<tr>
    <td><?php $i= base64_encode($course->getThumb()->getBytes());echo "<img src=\"data:image/jpg;base64,{$i}\">";?></td>
</tr>
<?php endforeach; ?>
</table>

 Make sure you set the correct header image type in order to render the image.

further info :
Storing Files with MongoGridFS
ZF2 form collections

Friday, March 8, 2013

ZF2 skeleton with mongoDB | using doctrine odm

1. git clone the ZF2 Skeleton Application

    git clone git://github.com/zendframework/ZendSkeletonApplication.git

2. cd into the ZendSkeletonApplication directory and open the composer.json in your favourite text editor.

    {
        "name": "zendframework/skeleton-application",
        "description": "Skeleton Application for ZF2",
        "license": "BSD-3-Clause",
        "keywords": [
            "framework",
            "zf2"
        ],
        "homepage": "http://framework.zend.com/",
        "minimum-stability": "dev",
        "require": {
            "php": ">=5.3.3",
            "zendframework/zendframework": "2.*",
            "doctrine/doctrine-mongo-odm-module": "dev-master"
        }
    }

3. Update your composer.json and run

php composer.phar self-update
php composer.phar install


4. If you are success with installing all dependencies using composer follow the official guide here to set up virtual-host and update hosts file.

5. If you are unable to update those dependencies and found something similar to this,

Check your composer.json for any mistakes, or follow my previous blog post.

6. Add the doctrine modules to your config file, config/application.config.php. Update the modules array similar to this, here im adding zend module named course as well.

        'modules' => array(
            'Application',
            'Course',
            'DoctrineModule',
            'DoctrineMongoODMModule',
        ),

7.  Copy the doctrine-odm config file to your config directory, and update according to your environment.This is where you set your server hosts, ports, username, and passwords etc.

    cp vendor/doctrine/doctrine-mongo-odm-module/config/module.doctrine-mongo-odm.local.php.dist config/module.doctrine-mongo-odm.local.php

 and update,

8. You can try the course module I have created here with course add and retrieve course data.

Wednesday, March 6, 2013

Installing doctrine ODM through composer

I tried to install doctrine/doctrine-mongo-odm-module through composer with ZF2, but I keep getting an error stating that PHP mango extension is missing from my computer.This is the require section of my composer.json file,
"require": {
        "php": ">=5.3.3",
        "zendframework/zendframework": "2.*",
        "doctrine/doctrine-mongo-odm-module": "dev-master"
    }
 Im getting this after I run  "php composer.phar install"


Correct version of MongoDB driver shows up in phpinfo() as well.


And THE PROBLEM is, Composer runs on PHP-CLI I do have two php.ini files.

/etc/php5/apache2/php.ini
/etc/php5/cli/php.ini

But I only updated MongoDB extension "extension=mongo.so" in /etc/php5/apache2/php.ini.Composer in the other hand is looking for mongo extension in the php.ini located in the /etc/php5/cli/php.ini directory. So by adding mongo extension in /etc/php5/cli/php.ini  file and apache restart solved my problem.