Pagination is one of most common tasks we developers know. Almost every system/website I know has some kind of pagination.

Luckly, Zend Framework 2 comes with several paginator adapters out of the box allowing iteration through Arrays, Zend\Db\Sql\Select objects and Iterators. It also allows us to create custom adapters and that’s what we need to do in order to use Zend\Paginator with Doctrine 2.

In this post we are going to go over the required steps to create a Doctrine adapter for Zend\Paginator.

Step 1: Creating the adapter

What a surprise. Assuming the you are working on the Application Module create a file called Adapter.php on module/Application/src/Application/Paginator

module/Application/src/Application/Paginator/Adapter.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
<?php

namespace Application\Paginator;

use Zend\Paginator\Adapter\AdapterInterface;

class Adapter implements AdapterInterface
{
  protected $repository;

    /**
     * Construct
     *
     * @param \Doctrine\ORM\EntityRepository $repository Repository class
     */
    public function __construct($repository)
    {
      $this->repository = $repository;
    }

    /**
     * Returns an collection of items for a page.
     *
     * @param int $offset           Page offset
     * @param int $itemCountPerPage Number of items per page
     *
     * @return array
     */
    public function getItems($offset, $itemCountPerPage)
    {
      return $this->repository->getItems($offset, $itemCountPerPage);
    }

    /**
     * Count results
     *
     * @return int
     */
    public function count()
    {
      return $this->repository->count();
    }

}

Our adapter implements the Zend\Paginator\Adapter\AdapterInterface interface, so we need to implement the methods getItems() and count()

Notice the we are injecting the repository class in the adapter’s contructor. We are going to take care of this dependency in the next steps.

Step 2: Using Service Manager to create the Paginator Service

On ‘module/Application/Module.php’ we are going to use the getServiceConfig() to setup our Paginator Service and injecting the required dependencies. It looks like this:

module/Application/Module.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
public function getServiceConfig()
{
  return array(
      'factories' => array(
          'Application\Paginator\User'        => function ($serviceManager) {

              $entityManager  = $serviceManager->get(
                  'Doctrine\ORM\EntityManager'
                  );

              $userRepository = $entityManager
              ->getRepository('Application\Entity\User');

              $adapter        = new PaginatorAdapter($userRepository);

              $page           = $serviceManager
              ->get('application')
              ->getMvcEvent()
              ->getRouteMatch()
              ->getParam('page');

              $paginator      = new Paginator($adapter);
              $paginator->setCurrentPageNumber($page)
                        ->setItemCountPerPage(5); // how many items per page

                        return $paginator;
                }
            )
  );
}

Step 3: Create your Entity and Repository class

In this tutorial we are using a User Entity that looks like this. It is located on ‘module/Application/src/Application/Entity’:

module/Application/src/Appllication/Entity/User.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
<?php
namespace Application\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="Application\Entity\Repository\User")
 * @ORM\Table(name="user")
 */
class User
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     * @ORM\Column(type="integer")
     */
    protected $id;

    /**
     * @ORM\Column(type="string", length=200)
     */
    protected $name;

    /**
     * @ORM\Column(type="string", length=200)
     */
    protected $email;

    /**
     * @return mixed
     */
    public function getId()
    {
        return $this->id;
    }

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

        return $this;
    }

    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * @return mixed
     */
    public function getName()
    {
        return $this->name;
    }

    public function setEmail($email)
    {
        $this->email = $email;

        return $this;
    }

    /**
     * @return mixed
     */
    public function getEmail()
    {
        return $this->email;
    }
}

Observe this line: @ORM\Entity(repositoryClass="Application\Entity\Repository\User"). It will be in this class that we are going to implements the methods used by our custom adapter.

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
<?php

namespace Application\Entity\Repository;

use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\Query;

class User extends EntityRepository
{
    /**
     * Counts how many users there are in the database
     *
     * @return int
     */
    public function count()
    {
        $query = $this->getEntityManager()->createQueryBuilder();
        $query->select(array('u.id'))
            ->from('Application\Entity\User', 'u');

        $result = $query->getQuery()->getResult();

        return count($result);
    }

    /**
     * Returns a list of users
     *
     * @param int $offset           Offset
     * @param int $itemCountPerPage Max results
     *
     * @return array
     */
    public function getItems($offset, $itemCountPerPage)
    {
        $query = $this->getEntityManager()->createQueryBuilder();
        $query->select(array('u.id', 'u.name', 'u.email'))
            ->from('Application\Entity\User', 'u')
            ->setFirstResult($offset)
            ->setMaxResults($itemCountPerPage);

        $result = $query->getQuery()->getResult(Query::HYDRATE_ARRAY);

        return $result;
    }
}

We now have all set to start using the adapter.

Step 4: Using the paginator adapter on your controller

Using our adapter is pretty straight foward. All we need to do is call the service and pass it to the views,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php

namespace Application\Controller;

use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;

class IndexController extends AbstractActionController
{
    public function indexAction()
    {
        $users = $this->getServiceLocator()->get('Application\Paginator\User');

        return new ViewModel(
            array(
                'users' => $users
            )
        );

    }
}

This is how our view should look like.

module/Application/view/application/index/index.phtml

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
<div class="row">

    <div class="col-md-12">
        <div class="panel panel-default">
            <div class="panel-heading">
                <h3 class="panel-title">Users</h3>
            </div>
            <div class="panel-body">
                <div class=" table-responsive">

                    <table class="table table-striped table-hover table-condensed">
                        <thead>

                            <tr>
                                <th>#</th>
                                <th>Name</th>
                                <th>Email</th>
                            </tr>
                        </thead>
                        <tbody>
                            <?php foreach ($this->users as $user): ?>
                                <tr>
                                    <td><?php echo $user['id'] ?></td>
                                    <td><?php echo $user['name'] ?></td>
                                    <td><?php echo $user['email'] ?></td>
                                </tr>
                            <?php endforeach; ?>
                        </tbody>
                    </table>
                </div>

                <?php echo $this->paginationControl($this->users, 'Sliding', 'paginator.phtml'); ?>
            </div>
        </div>
    </div>

</div>

And the partial paginator file:

module/Application/view/application/partials/paginator.phtml

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
<div class="row paginator">
    <div class="col-sm-6 col-xs-12 col-md-12 margin-bottom-20">
        Showing <?php echo $this->firstItemNumber ?>
        to <?php echo $this->lastItemNumber ?>
        of <?php echo $this->totalItemCount ?> entries
    </div>
    <?php if ($this->pageCount > 1): ?>
        <div class="col-sm-6 col-xs-12 col-md-12">
            <div class="pull-right">
                <ul class="pagination">
                    <!-- Previous page link -->
                    <?php if (isset($this->previous)): ?>
                        <li>
                            <a href="<?php echo $this->url('application/pagination', array('page' => $this->previous)); ?>">
                                <<
                            </a>
                        </li>
                    <?php else: ?>
                        <li class="disabled">
                            <a>
                                <<
                            </a>
                        </li>
                    <?php endif; ?>
                    <!-- Numbered page links -->
                    <?php foreach ($this->pagesInRange as $page): ?>
                        <?php if ($page != $this->current): ?>
                            <li>
                                <a href="<?php echo $this->url('application/pagination', array('page' => $page)); ?>">
                                    <?php echo $page; ?>
                                </a>
                            </li>
                        <?php else: ?>
                            <li class="active">
                                <a><?php echo $page; ?></a>
                            </li>
                        <?php endif; ?>
                    <?php endforeach; ?>

                    <!-- Next page link -->
                    <?php if (isset($this->next)): ?>
                        <li>
                            <a href="<?php echo $this->url('application/pagination', array('page' => $this->next)); ?>">
                                >>
                            </a>
                        </li>
                    <?php else: ?>
                        <li class="disabled">
                            <a>
                                >>
                            </a>
                        </li>
                    <?php endif; ?>
                </ul>
            </div>
        </div>
    <?php endif; ?>
</div>

This partial file, however, requires a little configuration. You need to tell your application to look for view files on partials folder:

module/Application/config/module.config.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
'view_manager'    => array(
    'display_not_found_reason' => true,
    'display_exceptions'       => true,
    'doctype'                  => 'HTML5',
    'not_found_template'       => 'error/404',
    'exception_template'       => 'error/index',
    'template_map'             => array(
        'layout/layout'           => __DIR__ . '/../view/layout/layout.phtml',
        'application/index/index' => __DIR__ . '/../view/application/index/index.phtml',
        'error/404'               => __DIR__ . '/../view/error/404.phtml',
        'error/index'             => __DIR__ . '/../view/error/index.phtml',
    ),
    'template_path_stack'      => array(
        __DIR__ . '/../view',
        __DIR__ . '/../view/application/partials', // Add this line
    ),
),

And finally, we need to add the route application/pagination that we are using on paginator.phtml

module/Application/config/module.config.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'pagination' => array(
    'type'    => 'Segment',
        'options' => array(
                            'route'       => '[/:controller]/page[/:page]',
                            'constraints' => array(
                                'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
                                'page'       => '[0-9]+',
                            ),
                            'defaults'    => array(
                                'controller' => 'Application\Controller\Index',
                                'action'     => 'index',
                            ),
                        ),
                    ),

That’s it.

Checkout out this project’s source code on github:

https://github.com/rosantoz/zf2-paginator-doctrine

TV Credits is a jQuery plugin that works as a vertical and horizontal scroll. Vertical for a TV Credits like scroll and also works as a horizontal ticker.

Download

https://github.com/rosantoz/tvcredits

Usage

Just include the plugin in our site:

1
<script src="tvcredits.jquery.js"></script>

or

1
<script src="tvcredits.jquery.min.js"</script>

Your HTML code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<div id="credits">
  <ul>
      <li>Lorene Nichols</li>
      <li>Ed Figueroa</li>
      <li>Sue Klein</li>
      <li>Sharon Warren</li>
      <li>Marta Maldonado</li>
      <li>Manuel Flowers</li>
      <li>Lila Chambers</li>
      <li>Yolanda Haynes</li>
      <li>Alfonso Lynch</li>
      <li>Janie Reese</li>
  </ul>
</div> 

And then:

1
$("#credits").tvCredits();

Options

1
2
3
4
5
6
$("#credtis").tvCredits({
    direction: 'up', // 'up' or 'left'. Default: 'up'
    complete : function () {}, // Callback function called at the end of each loop
    speed    : 25000, // Animation speed in miliseconds. Default: 25000
    height   : 350, // Container height. Default: 350px
});

Demo

http://jsfiddle.net/rosantoz/h57G2/1/

At the moment I’m working on a responsive web application that requires lots of testing on mobile devices such as iPhones and iPads.

Besides using chrome plug-in called Viewport Resizer that can help previewing our application on lot of different screen sizes, sometimes we need to test is on the actual device.

But how to we do that without having to deploy the application on a public server?

Well, if you are using Vagrant and Mac, there is a quick way to do that.

In your Mac just go to System Preferences –> Sharing as showed bellow:

Select the box File Sharing and give your computer a name. I named mine rod, so it can be accessed by rod.local.

After doing that, you will need to create a virtual host with your computer name in both your Vagrant VM and your local machine and you are done.

On your mobile device just type http://rod.local or, if you use and specific port http://rod.local:8000

I notice that this only work with apple devices. Somehow it doesn’t work with android phones or tablets (why?). I’m still trying to figure that out.

Let me know in the comments if you have a solution for this.

Here is how you can use a custom view helper inside another custom view helper in Zend Framework 1 applications.

All you need to do is to create this method in your view helper

1
2
3
4
public function setView(Zend_View_Interface $view)
{
    $this->_view = $view;
}

Here is a full example on how to use this.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Zend_View_Helper_MyFirstViewHelper extends Zend_View_Helper_Abstract
{
  protected $view;

    public function MyFirstViewHelper()
    {
      // Calling another view helper
      $this->_view->AnotherViewHelper();
    }

    public function setView(Zend_View_Interface $view)
  {
      $this->_view = $view;
  }
}

Flash messages can be really useful when you want to display a message to your user.

That is basically what flash messages do. They store some text in session to be available only in the next request. After that the message is deleted.

Zend Framework 2 has a view helper that makes using flash messages a walk in the park. Let’s see how to use it.

First of all we need a place to show the messages. Usually I place it in my layout file so I can use it from any controller in my application.

1
2
3
4
5
6
7
8
9
10
11
12
<?php
$flash = $this->flashMessenger();
$flash->setMessageOpenFormat('<div%s>
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">
    &times;
</button>
<div>')->setMessageCloseString('</div></div>');

echo $flash->render('error', array('alert', 'alert-dismissable', 'alert-danger'));
echo $flash->render('info', array('alert', 'alert-dismissable', 'alert-info'));
echo $flash->render('default', array('alert', 'alert-dismissable', 'alert-warning'));
echo $flash->render('success', array('alert', 'alert-dismissable', 'alert-success'));

In the code above I’m wrapping the message with the standard Bootstrap CSS classes to generate nice alert boxes.

Now, from your controller, all you have to do is this:

1
2
3
$this->flashMessenger()
     ->setNamespace('error')
     ->addMessage('User not found');

Or for a success message:

1
2
3
$this->flashMessenger()
   ->setNamespace('success')
   ->addMessage('Congratulations. You won the Lottery!')

That’s all folks.

If you want to use a different layout in the same module using Zend Framework 2, just use the example bellow inside your action:

1
2
3
$layout = $this->layout();
$layout->setTemplate('layout/new_layout');
return new ViewModel();

This is going to use “new_layout.phtml” file as the layout file, ignoring the default layout of the module.

This is a quick tip to speed up your unit tests when using DbUnit with a MySQL database connection.

You’ll need to edit your my.cnf file, that is usually located in /etc/ or /etc/mysql folder, and simply add this:

1
innodb_flush_log_at_trx_commit = 2

Let me know if it worked for you.

Cheers.

The idea behind the plugin is really simple. Suppose I have an unsorted list and want to show just a X number of items. Then I fade out this items and fade in the next ones, as it was a slideshow.

Download

https://github.com/rosantoz/jquery-fadelist

Usage

Just include the plugin in our site:

1
<script src="fadelist.jquery.js"></script>

or

1
<script src="fadelist.jquery.min.js"</script>

Your HTML code:

1
2
3
4
5
6
7
8
<ul id="gallery">
      <li>1</li>
      <li>2</li>
      <li>3</li>
      <li>4</li>
      <li>5</li>
      <li>6</li>
</ul>  

And then:

1
$("#gallery").fadelist();

Options

1
2
3
4
$("#gallery").fadelist({
    show: 5 // how many items per page
    fade: 15000 // fade speed in miliseconds
});

Demo

http://jsfiddle.net/rosantoz/wS2R2/2/