Permalink
Browse files

Merge branch 'feature/paginator-factory' into develop

Close #2316
  • Loading branch information...
2 parents 5d473f2 + f3a8a34 commit b3c40ad7a972a94ff3e23ad2b5a8f32f1f8f5c28 @weierophinney weierophinney committed Oct 30, 2012
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @package Zend_Mvc
+ */
+
+namespace Zend\Mvc\Service;
+
+use Zend\ServiceManager\ServiceLocatorInterface;
+
+/**
+ * @category Zend
+ * @package Zend_Mvc
+ * @subpackage Service
+ */
+class PaginatorPluginManagerFactory extends AbstractPluginManagerFactory
+{
+ const PLUGIN_MANAGER_CLASS = 'Zend\Paginator\AdapterPluginManager';
+
+ /**
+ * Create and return the MVC controller plugin manager
+ *
+ * @param ServiceLocatorInterface $serviceLocator
+ * @return ControllerPluginManager
+ */
+ public function createService(ServiceLocatorInterface $serviceLocator)
+ {
+ $plugins = parent::createService($serviceLocator);
+ return $plugins;
+ }
+}
@@ -52,11 +52,12 @@ class ServiceListenerFactory implements FactoryInterface
'ConsoleAdapter' => 'Zend\Mvc\Service\ConsoleAdapterFactory',
'ConsoleRouter' => 'Zend\Mvc\Service\RouterFactory',
'DependencyInjector' => 'Zend\Mvc\Service\DiFactory',
- 'DiStrictAbstractServiceFactory' => 'Zend\Mvc\Service\DiStrictAbstractServiceFactoryFactory',
'DiAbstractServiceFactory' => 'Zend\Mvc\Service\DiAbstractServiceFactoryFactory',
'DiServiceInitializer' => 'Zend\Mvc\Service\DiServiceInitializerFactory',
+ 'DiStrictAbstractServiceFactory' => 'Zend\Mvc\Service\DiStrictAbstractServiceFactoryFactory',
'FilterManager' => 'Zend\Mvc\Service\FilterManagerFactory',
'HttpRouter' => 'Zend\Mvc\Service\RouterFactory',
+ 'PaginatorPluginManager' => 'Zend\Mvc\Service\PaginatorPluginManagerFactory',
'Request' => 'Zend\Mvc\Service\RequestFactory',
'Response' => 'Zend\Mvc\Service\ResponseFactory',
'Router' => 'Zend\Mvc\Service\RouterFactory',
@@ -0,0 +1,46 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @package Zend_Paginator
+ */
+
+namespace Zend\Paginator\Adapter\Service;
+
+use Zend\ServiceManager\FactoryInterface;
+use Zend\ServiceManager\ServiceLocatorInterface;
+
+/**
+ * @category Zend
+ * @package Paginator
+ */
+class DbSelectFactory implements FactoryInterface
+{
+ /**
+ * Adapter options
+ * @var array
+ */
+ protected $creationOptions;
+
+ /**
+ * Construct with adapter options
+ * @param array $creationOptions
+ */
+ public function __construct(array $creationOptions)
+ {
+ $this->creationOptions = $creationOptions;
+ }
+
+ /**
+ * @param ServiceLocatorInterface $serviceLocator
+ * @return \Zend\Navigation\Navigation
+ */
+ public function createService(ServiceLocatorInterface $serviceLocator)
+ {
+ $class = new \ReflectionClass('Zend\Paginator\Adapter\DbSelect');
+ return $class->newInstanceArgs($this->creationOptions);
+ }
+}
@@ -0,0 +1,88 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @package Zend_Paginator
+ */
+
+namespace Zend\Paginator;
+
+use Zend\ServiceManager\AbstractPluginManager;
+
+/**
+ * Plugin manager implementation for paginator adapters.
+ *
+ * Enforces that adapters retrieved are instances of
+ * Adapter\AdapterInterface. Additionally, it registers a number of default
+ * adapters available.
+ *
+ * @category Zend
+ * @package Zend_Paginator
+ */
+class AdapterPluginManager extends AbstractPluginManager
+{
+ /**
+ * Default set of adapters
+ *
+ * @var array
+ */
+ protected $invokableClasses = array(
+ 'array' => 'Zend\Paginator\Adapter\ArrayAdapter',
+ 'iterator' => 'Zend\Paginator\Adapter\Iterator',
+ 'null' => 'Zend\Paginator\Adapter\Null',
+ );
+
+ /**
+ * Default set of adapter factories
+ *
+ * @var array
+ */
+ protected $factories = array(
+ 'dbselect' => 'Zend\Paginator\Adapter\Service\DbSelectFactory'
+ );
+
+ /**
+ * Attempt to create an instance via a factory
+ *
+ * @param string $canonicalName
+ * @param string $requestedName
+ * @return mixed
+ * @throws Exception\ServiceNotCreatedException If factory is not callable
+ */
+ protected function createFromFactory($canonicalName, $requestedName)
+ {
+ $factory = $this->factories[$canonicalName];
+ if (is_string($factory) && class_exists($factory, true)) {
+ $factory = new $factory($this->creationOptions);
+ $this->factories[$canonicalName] = $factory;
+ }
+ return parent::createFromFactory($canonicalName, $requestedName);
+ }
+
+ /**
+ * Validate the plugin
+ *
+ * Checks that the adapter loaded is an instance
+ * of Adapter\AdapterInterface.
+ *
+ * @param mixed $plugin
+ * @return void
+ * @throws Exception\RuntimeException if invalid
+ */
+ public function validatePlugin($plugin)
+ {
+ if ($plugin instanceof Adapter\AdapterInterface) {
+ // we're okay
+ return;
+ }
+
+ throw new Exception\RuntimeException(sprintf(
+ 'Plugin of type %s is invalid; must implement %s\Adapter\AdapterInterface',
+ (is_object($plugin) ? get_class($plugin) : gettype($plugin)),
+ __NAMESPACE__
+ ));
+ }
+}
@@ -0,0 +1,114 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @package Zend_Paginator
+ */
+
+namespace Zend\Paginator;
+
+use Traversable;
+use Zend\Paginator\Adapter\AdapterInterface;
+use Zend\Stdlib\ArrayUtils;
+
+/**
+ * @category Zend
+ * @package Zend_Paginator
+ */
+abstract class Factory
+{
+ /**
+ * Adapter plugin manager
+ * @var AdapterPluginManager
+ */
+ protected static $adapters;
+
+ /**
+ * Create adapter from items if necessary, and return paginator
+ * @param Traversable/array $items
+ * @return Paginator
+ */
+ protected static function createAdapterFromItems($items)
+ {
+ if ($items instanceof Traversable) {
+ $items = ArrayUtils::iteratorToArray($items);
+ }
+ if (!is_array($items)) {
+ throw new Exception\InvalidArgumentException(
+ 'The factory needs an associative array '
+ . 'or a Traversable object as an argument when '
+ . "it's used with one parameter"
+ );
+ }
+ if (!isset($items['adapter']) && !isset($items['items'])) {
+ throw new Exception\InvalidArgumentException(
+ 'The factory needs an associative array '
+ . 'or a Traversable object with keys '
+ . '"adapter" and "items"'
+ );
+ }
+ $adapter = $items['adapter'];
+ $items = $items['items'];
+
+ $paginator = static::getAdapterFromManager($items, $adapter);
+ return $paginator;
+ }
+
+ /**
+ * Get adapter from manager if necessary, and return paginator
+ * @param mixed $items
+ * @param mixed $adapter
+ * @return Paginator
+ */
+ protected static function getAdapterFromManager($items, $adapter)
+ {
+ if ($adapter instanceof AdapterInterface || $adapter instanceof AdapterAggregateInterface) {
+ return new Paginator($adapter);
+ }
+ $adapter = static::getAdapterPluginManager()->get($adapter, $items);
+ return new Paginator($adapter);
+ }
+
+ /**
+ * Create paginator with items and adapter
+ * @param mixed $items
+ * @param mixed $adapter
+ * @return Paginator
+ */
+ public static function factory($items, $adapter = null)
+ {
+ if (null === $adapter) {
+ $paginator = static::createAdapterFromItems($items);
+ return $paginator;
+ }
+ $paginator = static::getAdapterFromManager($items, $adapter);
+ return $paginator;
+ }
+
+ /**
+ * Change the adapter plugin manager
+ *
+ * @param AdapterPluginManager $adapters
+ * @return void
+ */
+ public static function setAdapterPluginManager(AdapterPluginManager $adapters)
+ {
+ static::$adapters = $adapters;
+ }
+
+ /**
+ * Get the adapter plugin manager
+ *
+ * @return AdapterPluginManager
+ */
+ public static function getAdapterPluginManager()
+ {
+ if (static::$adapters === null) {
+ static::$adapters = new AdapterPluginManager();
+ }
+ return static::$adapters;
+ }
+}
@@ -287,7 +287,7 @@ public function __construct($adapter)
$this->adapter = $adapter->getPaginatorAdapter();
} else {
throw new Exception\InvalidArgumentException(
- 'Zend_Paginator only accepts instances of the type ' .
+ 'Zend\Paginator only accepts instances of the type ' .
'Zend\Paginator\Adapter\AdapterInterface or Zend\Paginator\AdapterAggregateInterface.'
);
}
@@ -0,0 +1,77 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @package Zend_Paginator
+ */
+
+namespace ZendTest\Paginator;
+
+use Zend\Paginator\AdapterPluginManager;
+use Zend\ServiceManager\ServiceManager;
+use Zend\Mvc\Service\ServiceManagerConfig;
+
+/**
+ * @category Zend
+ * @package Zend_Paginator
+ * @subpackage UnitTests
+ * @group Zend_Paginator
+ */
+class AdapterPluginManagerTest extends \PHPUnit_Framework_TestCase
+{
+ protected $adapaterPluginManager;
+
+ /** @var \PHPUnit_Framework_MockObject_MockObject */
+ protected $mockSelect;
+
+ protected $mockAdapter;
+
+ protected function setUp()
+ {
+ $this->adapaterPluginManager = new AdapterPluginManager();
+ $this->mockSelect = $this->getMock('Zend\Db\Sql\Select');
+
+ $mockStatement = $this->getMock('Zend\Db\Adapter\Driver\StatementInterface');
+ $mockResult = $this->getMock('Zend\Db\Adapter\Driver\ResultInterface');
+
+ $mockDriver = $this->getMock('Zend\Db\Adapter\Driver\DriverInterface');
+ $mockDriver->expects($this->any())->method('createStatement')->will($this->returnValue($mockStatement));
+ $mockStatement->expects($this->any())->method('execute')->will($this->returnValue($mockResult));
+ $mockPlatform = $this->getMock('Zend\Db\Adapter\Platform\PlatformInterface');
+ $mockPlatform->expects($this->any())->method('getName')->will($this->returnValue('platform'));
+
+ $this->mockAdapter = $this->getMockForAbstractClass(
+ 'Zend\Db\Adapter\Adapter',
+ array($mockDriver, $mockPlatform)
+ );
+ }
+
+ public function testCanRetrieveAdapterPlugin()
+ {
+ $plugin = $this->adapaterPluginManager->get('array', array(1, 2, 3));
+ $this->assertInstanceOf('Zend\Paginator\Adapter\ArrayAdapter', $plugin);
+ $plugin = $this->adapaterPluginManager->get('iterator', new \ArrayIterator(range(1, 101)));
+ $this->assertInstanceOf('Zend\Paginator\Adapter\Iterator', $plugin);
+ $plugin = $this->adapaterPluginManager->get('dbselect', array($this->mockSelect, $this->mockAdapter));
+ $this->assertInstanceOf('Zend\Paginator\Adapter\DbSelect', $plugin);
+ $plugin = $this->adapaterPluginManager->get('null', 101);
+ $this->assertInstanceOf('Zend\Paginator\Adapter\Null', $plugin);
+ }
+
+ public function testCanRetrievePluginManagerWithServiceManager()
+ {
+ $sm = $this->serviceManager = new ServiceManager(
+ new ServiceManagerConfig(array(
+ 'factories' => array(
+ 'PaginatorPluginManager' => 'Zend\Mvc\Service\PaginatorPluginManagerFactory',
+ ),
+ ))
+ );
+ $sm->setService('Config', array());
+ $adapterPluginManager = $sm->get('PaginatorPluginManager');
+ $this->assertInstanceOf('Zend\Paginator\AdapterPluginManager', $adapterPluginManager);
+ }
+}
Oops, something went wrong. Retry.

0 comments on commit b3c40ad

Please sign in to comment.