diff --git a/.travis.yml b/.travis.yml
index c27f36326..684b2b774 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,10 +1,8 @@
language: php
env:
- - PHALCON_VERSION="1.3.5"
- - PHALCON_VERSION="1.3.4"
- - PHALCON_VERSION="1.3.3"
- - PHALCON_VERSION="1.3.2"
+ - PHALCON_VERSION="2.0.x"
+ - PHALCON_VERSION="2.0.0"
install:
- tests/memcached.sh
@@ -30,4 +28,4 @@ after_script:
- php ocular.phar code-coverage:upload --format=php-clover coverage.clover
services:
- - memcached
\ No newline at end of file
+ - memcached
diff --git a/Library/Phalcon/Acl/Adapter/Redis.php b/Library/Phalcon/Acl/Adapter/Redis.php
new file mode 100644
index 000000000..110aa9058
--- /dev/null
+++ b/Library/Phalcon/Acl/Adapter/Redis.php
@@ -0,0 +1,424 @@
+redis = $redis;
+ }
+
+ public function setRedis($redis, $chainRedis = false)
+ {
+ $this->redis = $redis;
+ return $chainRedis ? $redis : $this;
+ }
+
+ public function getRedis()
+ {
+ return $this->redis;
+ }
+
+ /**
+ * {@inheritdoc}
+ * Example:
+ * $acl->addRole(new Phalcon\Acl\Role('administrator'), 'consultor');
+ * $acl->addRole('administrator', 'consultor');
+ *
+ * @param \Phalcon\Acl\Role|string $role
+ * @param string $accessInherits
+ * @return boolean
+ */
+ public function addRole($role, $accessInherits = null)
+ {
+ if (!is_object($role)) {
+ $role = new Role($role, ucwords($role) . " Role");
+ }
+
+ $this->redis->hMset("roles", array($role->getName() => $role->getDescription()));
+ $this->redis->sAdd("accessList:$role:*:{$this->getDefaultAction()}}", "*");
+
+ if ($accessInherits) {
+ $this->addInherit($role->getName(), $accessInherits);
+ }
+
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @param string $roleName
+ * @param string $roleToInherit
+ * @throws \Phalcon\Acl\Exception
+ */
+ public function addInherit($roleName, $roleToInherit)
+ {
+ $exists = $this->redis->hGet("roles", $roleName);
+ if (!$exists) {
+ throw new Exception("Role '" . $roleName . "' does not exist in the role list");
+ }
+
+ $this->redis->sAdd("rolesInherits:$roleName", $roleToInherit);
+ }
+
+ /**
+ * {@inheritdoc}
+ * Example:
+ *
+ * //Add a resource to the the list allowing access to an action
+ * $acl->addResource(new Phalcon\Acl\Resource('customers'), 'search');
+ * $acl->addResource('customers', 'search');
+ * //Add a resource with an access list
+ * $acl->addResource(new Phalcon\Acl\Resource('customers'), array('create', 'search'));
+ * $acl->addResource('customers', array('create', 'search'));
+ *
+ *
+ * @param \Phalcon\Acl\Resource|string $resource
+ * @param array|string $accessList
+ * @return boolean
+ */
+ public function addResource($resource, $accessList = null)
+ {
+ if (!is_object($resource)) {
+ $resource = new Resource($resource, ucwords($resource) . " Resource");
+ }
+ $this->redis->hMset("resources", array($resource->getName() => $resource->getDescription()));
+
+ if ($accessList) {
+ return $this->addResourceAccess($resource->getName(), $accessList);
+ }
+
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @param string $resourceName
+ * @param array|string $accessList
+ * @return boolean
+ * @throws \Phalcon\Acl\Exception
+ */
+ public function addResourceAccess($resourceName, $accessList)
+ {
+ if (!$this->isResource($resourceName)) {
+ throw new Exception("Resource '" . $resourceName . "' does not exist in ACL");
+ }
+
+ $accessList = (is_string($accessList)) ? explode(' ', $accessList) : $accessList;
+ foreach ($accessList as $accessName) {
+ $this->redis->sAdd("resourcesAccesses:$resourceName", $accessName);
+ }
+
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @param string $roleName
+ * @return boolean
+ */
+ public function isRole($roleName)
+ {
+ return $this->redis->hExists("roles", $roleName);
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @param string $resourceName
+ * @return boolean
+ */
+ public function isResource($resourceName)
+ {
+ return $this->redis->hExists("resources", $resourceName);
+ }
+
+ public function isResourceAccess($resource, $access)
+ {
+ return $this->redis->sIsMember("resourcesAccesses:$resource", $access);
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @return \Phalcon\Acl\Resource[]
+ */
+ public function getResources()
+ {
+ $resources = array();
+
+ foreach ($this->redis->hGetAll("resources") as $name => $desc) {
+ $resources[] = new Resource($name, $desc);
+ }
+
+ return $resources;
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @return \Phalcon\Acl\Role[]
+ */
+ public function getRoles()
+ {
+ $roles = array();
+
+ foreach ($this->redis->hGetAll("roles") as $name => $desc) {
+ $roles[] = new Role($name, $desc);
+ }
+
+ return $roles;
+ }
+
+ /**
+ * @param $role
+ * @return array
+ */
+ public function getRoleInherits($role)
+ {
+ return $this->redis->sMembers("rolesInherits:$role");
+ }
+
+ public function getResourceAccess($resource)
+ {
+ return $this->redis->sMembers("resourcesAccesses:$resource");
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @param string $resource
+ * @param array|string $accessList
+ */
+ public function dropResourceAccess($resource, $accessList)
+ {
+ if (!is_array($accessList)) {
+ $accessList = (array)$accessList;
+ }
+ array_unshift($accessList, "resourcesAccesses:$resource");
+ call_user_func_array(array($this->redis, 'sRem'), $accessList);
+ }
+
+ /**
+ * {@inheritdoc}
+ * You can use '*' as wildcard
+ * Example:
+ *
+ * //Allow access to guests to search on customers
+ * $acl->allow('guests', 'customers', 'search');
+ * //Allow access to guests to search or create on customers
+ * $acl->allow('guests', 'customers', array('search', 'create'));
+ * //Allow access to any role to browse on products
+ * $acl->allow('*', 'products', 'browse');
+ * //Allow access to any role to browse on any resource
+ * $acl->allow('*', '*', 'browse');
+ *
+ *
+ * @param string $role
+ * @param string $resource
+ * @param array|string $access
+ */
+ public function allow($role, $resource, $access)
+ {
+ if ($role !== '*' && $resource !== '*') {
+ $this->allowOrDeny($role, $resource, $access, Acl::ALLOW);
+ }
+ if ($role === '*' || empty($role)) {
+ $this->rolePermission($resource, $access, Acl::ALLOW);
+ }
+ if ($resource === '*' || empty($resource)) {
+ $this->resourcePermission($role, $access, Acl::ALLOW);
+ }
+ }
+
+ /**
+ * @param $role
+ * @param $access
+ * @param $allowOrDeny
+ * @throws Exception
+ */
+ protected function resourcePermission($role, $access, $allowOrDeny)
+ {
+ foreach ($this->getResources() as $resource) {
+ if ($role === '*' || empty($role)) {
+ $this->rolePermission($resource, $access, $allowOrDeny);
+ } else {
+ $this->allowOrDeny($role, $resource, $access, $allowOrDeny);
+ }
+ }
+ }
+
+ /**
+ * @param $resource
+ * @param $access
+ * @param $allowOrDeny
+ * @throws Exception
+ */
+ protected function rolePermission($resource, $access, $allowOrDeny)
+ {
+ foreach ($this->getRoles() as $role) {
+ if ($resource === '*' || empty($resource)) {
+ $this->resourcePermission($role, $access, $allowOrDeny);
+ } else {
+ $this->allowOrDeny($role, $resource, $access, $allowOrDeny);
+ }
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ * You can use '*' as wildcard
+ * Example:
+ *
+ * //Deny access to guests to search on customers
+ * $acl->deny('guests', 'customers', 'search');
+ * //Deny access to guests to search or create on customers
+ * $acl->deny('guests', 'customers', array('search', 'create'));
+ * //Deny access to any role to browse on products
+ * $acl->deny('*', 'products', 'browse');
+ * //Deny access to any role to browse on any resource
+ * $acl->deny('*', '*', 'browse');
+ *
+ *
+ * @param string $roleName
+ * @param string $resourceName
+ * @param array|string $access
+ * @return boolean
+ */
+ public function deny($role, $resource, $access)
+ {
+ if ($role === '*' || empty($role)) {
+ $this->rolePermission($resource, $access, Acl::DENY);
+ } elseif ($resource === '*' || empty($resource)) {
+ $this->resourcePermission($role, $access, Acl::DENY);
+ } else {
+ $this->allowOrDeny($role, $resource, $access, Acl::DENY);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ * Example:
+ *
+ * //Does Andres have access to the customers resource to create?
+ * $acl->isAllowed('Andres', 'Products', 'create');
+ * //Do guests have access to any resource to edit?
+ * $acl->isAllowed('guests', '*', 'edit');
+ *
+ *
+ * @param string $role
+ * @param string $resource
+ * @param string $access
+ *
+ * @return bool
+ */
+ public function isAllowed($role, $resource, $access)
+ {
+ if ($this->redis->sIsMember("accessList:$role:$resource:" . Acl::ALLOW, $access)) {
+ return Acl::ALLOW;
+ }
+
+ if ($this->redis->exists("rolesInherits:$role")) {
+ $rolesInherits = $this->redis->sMembers("rolesInherits:$role");
+ foreach ($rolesInherits as $role) {
+ if ($this->redis->sIsMember("accessList:$role:$resource:" . Acl::ALLOW, $access)) {
+ return Acl::ALLOW;
+ }
+ }
+ }
+
+ /**
+ * Return the default access action
+ */
+
+ return $this->getDefaultAction();
+ }
+
+ /**
+ * @param $roleName
+ * @param $resourceName
+ * @param $accessName
+ * @param $action
+ * @return bool
+ * @throws Exception
+ */
+ protected function setAccess($roleName, $resourceName, $accessName, $action)
+ {
+ /**
+ * Check if the access is valid in the resource
+ */
+ if ($this->isResourceAccess($resourceName, $accessName)) {
+ if (!$this->setNXAccess) {
+ throw new Exception(
+ "Access '" . $accessName . "' does not exist in resource '" . $resourceName . "' in ACL"
+ );
+ }
+ $this->addResourceAccess($resourceName, $accessName);
+ }
+ $this->redis->sAdd("accessList:$roleName:$resourceName:$action", $accessName);
+ $accessList = "accessList:$roleName:$resourceName";
+
+ // remove first if exists
+ foreach (array(1, 2) as $act) {
+ $this->redis->sRem("$accessList:$act", $accessName);
+ $this->redis->sRem("$accessList:$act", "*");
+ }
+
+ $this->redis->sAdd("$accessList:$action", $accessName);
+
+ $this->redis->sAdd("$accessList:{$this->getDefaultAction()}", "*");
+
+ return true;
+ }
+
+ /**
+ * Inserts/Updates a permission in the access list
+ *
+ * @param string $roleName
+ * @param string $resourceName
+ * @param array|string $access
+ * @param integer $action
+ * @throws \Phalcon\Acl\Exception
+ */
+ protected function allowOrDeny($roleName, $resourceName, $access, $action)
+ {
+ if (!$this->isRole($roleName)) {
+ throw new Exception('Role "' . $roleName . '" does not exist in the list');
+ }
+ if (!$this->isResource($resourceName)) {
+ throw new Exception('Resource "' . $resourceName . '" does not exist in the list');
+ }
+ $access = ($access === '*' || empty($access)) ? $this->getResourceAccess($resourceName) : $access;
+ if (is_array($access)) {
+ foreach ($access as $accessName) {
+ $this->setAccess($roleName, $resourceName, $accessName, $action);
+ }
+ } else {
+ $this->setAccess($roleName, $resourceName, $access, $action);
+ }
+ }
+}
diff --git a/Library/Phalcon/Config/Adapter/Json.php b/Library/Phalcon/Config/Adapter/Json.php
deleted file mode 100644
index 113863e1a..000000000
--- a/Library/Phalcon/Config/Adapter/Json.php
+++ /dev/null
@@ -1,32 +0,0 @@
-phalcon->controllersDir;
echo $config->database->username;
echo $config->database->password;
-```
-
-Json
-----
-Reads Json markup files and converts it to Phalcon\Config objects. For the following configuration file:
-
-```
-
-{
- "database": {
- "adapter": "Mysql",
- "host": "localhost",
- "username": "scott",
- "password": "dbpassword",
- "dbname": "test_db"
- },
-
- "phalcon": {
- "controllersDir": "../app/controllers/",
- "modelsDir": "../app/models/",
- "viewsDir": "../app/views/"
- }
-}
-
-```
-
-You can read it as follows:
-
-```php
-
-$config = new Phalcon\Config\Adapter\Json('path/config.json');
-
-echo $config->phalcon->controllersDir;
-echo $config->database->username;
-echo $config->database->password;
-
-```
+```
\ No newline at end of file
diff --git a/Library/Phalcon/Debug/Dump.php b/Library/Phalcon/Debug/Dump.php
deleted file mode 100644
index 7809f6163..000000000
--- a/Library/Phalcon/Debug/Dump.php
+++ /dev/null
@@ -1,149 +0,0 @@
-flushBuffer = $flushBuffer;
- }
-
- /**
- * Get the current value of the debug output environment.
- * This defaults to the value of PHP_SAPI.
- *
- * @return string;
- */
- public static function getSapi()
- {
- if (static::$sapi === null) {
- static::$sapi = PHP_SAPI;
- }
-
- return static::$sapi;
- }
-
- /**
- * Sets sapi value
- *
- * @param string $sapi
- */
- public static function setSapi($sapi)
- {
- static::$sapi = $sapi;
- }
-
- /**
- * Sets output flag.
- *
- * @param boolean $flag
- */
- public static function setOutput($flag)
- {
- static::$output = $flag;
- }
-
- /**
- * Gets current value of output flag.
- *
- * @return boolean
- */
- public static function getOutput()
- {
- return static::$output;
- }
-
- /**
- * Debug helper function. This is a wrapper for var_dump|xdebug_var_dump that adds
- * the
' - . $label - . $output - . ''; - } - - $echo = self::$output; - if (is_bool($outputDump)) { - $echo = $outputDump; - } - - if ($echo) { - echo $output; - if ($this->flushBuffer) { - ob_flush(); - } - } - - return $output; - } - - /** - * Checks if xdebug_var_dump function is available - * - * @return bool - */ - protected function xdebugDumpExists() - { - return function_exists('xdebug_var_dump'); - } -} diff --git a/Library/Phalcon/Debug/README.md b/Library/Phalcon/Debug/README.md deleted file mode 100644 index 6a96cb4f4..000000000 --- a/Library/Phalcon/Debug/README.md +++ /dev/null @@ -1,95 +0,0 @@ -Phalcon\Debug -=================== - -Debug help - -Dump --------- -This utility class is meant to be used for dumping variables, heavily inspired by [Zend Framework's \Zend\Debug\Debug class](http://framework.zend.com/apidoc/2.1/classes/Zend.Debug.Debug.html). -Outputs var using var_dump() or xdebug_var_dump() and, if outputted, flushes Phalcons default output buffer. -Also, writes name of file and line from which it was called. - -Basic usage: - -```php - -(new \Phalcon\Debug\Dump())->dump($varToDump); - -``` - -Can be set to return output instead of echoing it using \Phalcon\Debug\Dump::setOutput() method - -```php - -if (ENVIRONMENT === 'production') { - \Phalcon\Debug\Dump::setOutput(false); -} - -// will return dump instead of echoing it -(new \Phalcon\Debug\Dump())->dump($varToDump); - -``` - -If, for any reason, there is need to override \Phalcon\Debug\Dump::$output value, -behavior can be overriden by setting second argument of \Phalcon\Debug\Dump::dump method to true or false - -```php - -\Phalcon\Debug\Dump::setOutput(false); - -// will return dump instead of echoing it -(new \Phalcon\Debug\Dump())->dump($varToDump); - -// this will echo dump -(new \Phalcon\Debug\Dump())->dump($varToDump, true); - -``` - -and - -```php - -\Phalcon\Debug\Dump::setOutput(true); - -// this will echo dump -(new \Phalcon\Debug\Dump())->dump($varToDump); - -// will return dump instead of echoing it -(new \Phalcon\Debug\Dump())->dump($varToDump, false); - -``` - -Convenient way of setting dump application wide (instead of making instance every time its called) can be using Phalcons DI: - -```php - -$this->getDI()->setShared('dump', function() { - return new \Phalcon\Debug\Dump(); -}); - -// ... later in application ... -$this->getDI()->getShared('dump')->dump($varToDump); // echoes dump - -``` - -... or set \Phalcon\Debug\Dump as a service to be able to easily consume it within controller ... - -```php - -// services.php -$di['debug'] = new \Phalcon\Debug\Dump(); - -// later in controller ... -$this->debug->dump($varToDump); - -``` - -If calling ob_flush() every time after var is dumped is not wanted behaviour it can be changed by setting false in object constructor: -(WARNING: if dump is echoed anywhere in Phalcon application, except in view, and ob_flush() is not called, it will not be seen due to Phalcons output buffering) - -```php - -// ob_flush() will not be called -(new \Phalcon\Debug\Dump(false))->dump($varToDump); - -``` diff --git a/Library/Phalcon/Logger/README.md b/Library/Phalcon/Logger/README.md index 4ff6994ae..e7f243582 100644 --- a/Library/Phalcon/Logger/README.md +++ b/Library/Phalcon/Logger/README.md @@ -41,20 +41,6 @@ CREATE TABLE `logs` ( ) ``` -Firephp -------- -Adapter to send messages to [Firebug](https://getfirebug.com/). You need -the [Firephp](http://www.firephp.org/) extension installed in your browser. - -```php -$logger = new Phalcon\Logger\Adapter\Firephp('debug', null); - -$logger->log('Plain Message'); -$logger->info('Info Message'); -$logger->warning('Warn Message'); -$logger->error('Error Message'); -``` - Firelogger ---------- Adapter to send messages to the [Firelogger](http://firelogger.binaryage.com/) console inside the [Firebug](https://getfirebug.com/) in your browser. diff --git a/Library/Phalcon/Mvc/Model/Behavior/NestedSet.php b/Library/Phalcon/Mvc/Model/Behavior/NestedSet.php index 84c2f8e39..cd0f186f0 100644 --- a/Library/Phalcon/Mvc/Model/Behavior/NestedSet.php +++ b/Library/Phalcon/Mvc/Model/Behavior/NestedSet.php @@ -5,6 +5,7 @@ use Phalcon\Mvc\Model\Behavior; use Phalcon\Mvc\Model\BehaviorInterface; use Phalcon\Mvc\Model; +use Phalcon\Mvc\ModelInterface; class NestedSet extends Behavior implements BehaviorInterface { @@ -19,7 +20,7 @@ class NestedSet extends Behavior implements BehaviorInterface private $deleted = false; - public function __construct($options) + public function __construct($options = null) { if (isset($options['hasManyRoots'])) { $this->hasManyRoots = (bool) $options['hasManyRoots']; @@ -46,7 +47,7 @@ public function __construct($options) } } - public function notify($eventType, $model) + public function notify($eventType, ModelInterface $model) { $message = 'You should not use this method when NestedSetBehavior attached. Use the methods of behavior.'; switch ($eventType) { @@ -60,7 +61,7 @@ public function notify($eventType, $model) } } - public function missingMethod($model, $method, $arguments = null) + public function missingMethod(ModelInterface $model, $method, $arguments = null) { if (!method_exists($this, $method)) { return null; diff --git a/Library/Phalcon/Mvc/Model/Validator/Between.php b/Library/Phalcon/Mvc/Model/Validator/Between.php index ada6f7e38..ec4dcf217 100644 --- a/Library/Phalcon/Mvc/Model/Validator/Between.php +++ b/Library/Phalcon/Mvc/Model/Validator/Between.php @@ -1,7 +1,7 @@ */ -class Between extends ModelValidator implements ValidatorInterface +class Between extends Validator implements ValidatorInterface { /** * {@inheritdoc} @@ -44,12 +44,8 @@ class Between extends ModelValidator implements ValidatorInterface * @return boolean * @throws Exception */ - public function validate($record) + public function validate(ModelInterface $record) { - if (false === is_object($record) || false === $record instanceof ModelInterface) { - throw new Exception('Invalid parameter type.'); - } - $field = $this->getOption('field'); if (false === is_string($field)) { diff --git a/Library/Phalcon/Mvc/Model/Validator/CardNumber.php b/Library/Phalcon/Mvc/Model/Validator/CardNumber.php index aeaef4202..f7d89dad8 100644 --- a/Library/Phalcon/Mvc/Model/Validator/CardNumber.php +++ b/Library/Phalcon/Mvc/Model/Validator/CardNumber.php @@ -1,9 +1,10 @@ */ -class CardNumber extends \Phalcon\Mvc\Model\Validator +class CardNumber extends Validator implements ValidatorInterface { const AMERICAN_EXPRESS = 0; // 34, 37 const MASTERCARD = 1; // 51-55 const VISA = 2; // 4 - public function validate($record) + public function validate(ModelInterface $record) { - if (false === $record instanceof ModelInterface && false === $record instanceof CollectionInterface) { - throw new Exception('Invalid parameter type.'); - } - $field = $this->getOption('field'); if (false === is_string($field)) { diff --git a/Library/Phalcon/Mvc/Model/Validator/ConfirmationOf.php b/Library/Phalcon/Mvc/Model/Validator/ConfirmationOf.php index 3e78e1551..1b6d4627f 100644 --- a/Library/Phalcon/Mvc/Model/Validator/ConfirmationOf.php +++ b/Library/Phalcon/Mvc/Model/Validator/ConfirmationOf.php @@ -1,13 +1,16 @@ getOption('field'); $fieldConfirmation = $this->getOption('field_confirmation'); diff --git a/Library/Phalcon/Mvc/Model/Validator/Decimal.php b/Library/Phalcon/Mvc/Model/Validator/Decimal.php index b7c270a70..1c846b04f 100644 --- a/Library/Phalcon/Mvc/Model/Validator/Decimal.php +++ b/Library/Phalcon/Mvc/Model/Validator/Decimal.php @@ -1,7 +1,7 @@ */ -class Decimal extends ModelValidator implements ValidatorInterface +class Decimal extends Validator implements ValidatorInterface { /** * {@inheritdoc} @@ -50,10 +50,6 @@ class Decimal extends ModelValidator implements ValidatorInterface */ public function validate(ModelInterface $record) { - if (false === is_object($record) || false === $record instanceof ModelInterface) { - throw new Exception('Invalid parameter type.'); - } - $field = $this->getOption('field'); if (false === is_string($field)) { diff --git a/Library/Phalcon/Mvc/Model/Validator/IP.php b/Library/Phalcon/Mvc/Model/Validator/IP.php index f55de556e..769df3d9a 100644 --- a/Library/Phalcon/Mvc/Model/Validator/IP.php +++ b/Library/Phalcon/Mvc/Model/Validator/IP.php @@ -1,9 +1,10 @@ */ -class IP extends \Phalcon\Mvc\Model\Validator +class IP extends Validator implements ValidatorInterface { const VERSION_4 = FILTER_FLAG_IPV4; const VERSION_6 = FILTER_FLAG_IPV6; - public function validate($record) + public function validate(ModelInterface $record) { - if (false === is_object($record)) { - throw new Exception('Invalid parameter type.'); - } - - if (false === ($record instanceof ModelInterface || $record instanceof CollectionInterface)) { - throw new Exception('Invalid parameter type.'); - } - $field = $this->getOption('field'); if (false === is_string($field)) { diff --git a/Library/Phalcon/Paginator/Pager.php b/Library/Phalcon/Paginator/Pager.php index e142efdbc..8950296fd 100644 --- a/Library/Phalcon/Paginator/Pager.php +++ b/Library/Phalcon/Paginator/Pager.php @@ -11,8 +11,6 @@ */ namespace Phalcon\Paginator; -use Phalcon\Paginator\AdapterInterface; - /** * \Phalcon\Paginator\Pager * Pager object is a navigation menu renderer based on doctrine1 pager object. @@ -29,13 +27,6 @@ class Pager implements \IteratorAggregate, \Countable */ protected $paginateResult = null; - /** - * Object that detects pages range. - * - * @var \Phalcon\Paginator\Range - */ - protected $range = null; - /** * Array with options. * @@ -46,18 +37,24 @@ class Pager implements \IteratorAggregate, \Countable /** * Current rows limit (if provided) * - * @var int|null + * @var integer|null */ protected $limit = null; /** * Class constructor. * - * @param \Phalcon\Paginator\AdapterInterface $adapter - * @param array $options { - * @type string $rangeType How to make the range: Jumping or Sliding - * @type integer $rangeChunkLength Range window size - * } + * Consumes Phalcon paginator adapter and options array. + * Option keys: + * - rangeClass: Class name which determines scrolling style type (e.g. Phalcon\Paginator\Pager\Range\Sliding). + * Defaults to "Phalcon\Paginator\Pager\Range\Sliding". + * - rangeLength: Size of range to be used. Default size is 10. + * - layoutClass: Used with getLayout() method. Defaults to "Phalcon\Paginator\Pager\Layout". + * - urlMask: Required with getLayout() method. + * + * @param \Phalcon\Paginator\AdapterInterface $adapter Phalcon paginator adapter + * @param array $options options array + * */ public function __construct(AdapterInterface $adapter, array $options = array()) { @@ -73,7 +70,7 @@ public function __construct(AdapterInterface $adapter, array $options = array()) /** * Get current rows limit (if provided) * - * @return int|null + * @return integer|null */ public function getLimit() { @@ -143,19 +140,11 @@ public function getLastPage() /** * Returns the layout object. * - * @return \Phalcon\Paginator\Layout - * @throws \RuntimeException + * @return \Phalcon\Paginator\Pager\Layout + * @throws \RuntimeException in case options are not properly set */ public function getLayout() { - if (!array_key_exists('rangeClass', $this->options)) { - $this->options['rangeClass'] = 'Phalcon\Paginator\Pager\Range\Sliding'; - } - - if (!array_key_exists('rangeLength', $this->options)) { - $this->options['rangeLength'] = 10; - } - if (!array_key_exists('layoutClass', $this->options)) { $this->options['layoutClass'] = 'Phalcon\Paginator\Pager\Layout'; } @@ -164,22 +153,37 @@ public function getLayout() throw new \RuntimeException('You must provide option "urlMask"'); } - $range = null; - try { - $range = new $this->options['rangeClass']($this, $this->options['rangeLength']); - } catch (\Exception $e) { - throw new \RuntimeException(sprintf('Unable to find range class "%s"', $this->options['rangeClass'])); - } + $range = null; + $rangeClass = $this->getRangeClass(); + $rangeLength = $this->getRangeLength(); - $layout = null; + if (!class_exists($rangeClass)) { + throw new \RuntimeException(sprintf('Unable to find range class "%s"', $rangeClass)); + } - try { - $layout = new $this->options['layoutClass']($this, $range, $this->options['urlMask']); - } catch (\Exception $e) { + if (!class_exists($this->options['layoutClass'])) { throw new \RuntimeException(sprintf('Unable to find layout "%s"', $this->options['layoutClass'])); } - return $layout; + return new $this->options['layoutClass']( + $this, + new $rangeClass($this, $rangeLength), + $this->options['urlMask'] + ); + } + + /** + * Returns array of page numbers that are in range of slider. + * + * @return array array of page numbers + */ + public function getPagesInRange() + { + /** @var \Phalcon\Paginator\Pager\Range $range */ + $rangeClass = $this->getRangeClass(); + $range = new $rangeClass($this, $this->getRangeLength()); + + return $range->getRange(); } /** @@ -205,4 +209,32 @@ public function count() { return intval($this->paginateResult->total_items); } + + /** + * RangeClass option getter. + * + * @return string range class name + */ + protected function getRangeClass() + { + if (!array_key_exists('rangeClass', $this->options)) { + $this->options['rangeClass'] = 'Phalcon\Paginator\Pager\Range\Sliding'; + } + + return $this->options['rangeClass']; + } + + /** + * RangeLength option getter. + * + * @return integer range length + */ + protected function getRangeLength() + { + if (!array_key_exists('rangeLength', $this->options)) { + $this->options['rangeLength'] = 10; + } + + return (int) $this->options['rangeLength']; + } } diff --git a/Library/Phalcon/Paginator/Pager/Layout.php b/Library/Phalcon/Paginator/Pager/Layout.php index 874fe9a33..d4f471222 100644 --- a/Library/Phalcon/Paginator/Pager/Layout.php +++ b/Library/Phalcon/Paginator/Pager/Layout.php @@ -12,7 +12,6 @@ namespace Phalcon\Paginator\Pager; use Phalcon\Paginator\Pager; -use Phalcon\Paginator\Pager\Range; /** * \Phalcon\Paginator\Pager\Layout @@ -31,7 +30,7 @@ class Layout /** * Ranges generator. * - * @var \Phalcon\Paginator\Range + * @var \Phalcon\Paginator\Pager\Range */ protected $range = null; diff --git a/Library/Phalcon/Paginator/Pager/Range/Sliding.php b/Library/Phalcon/Paginator/Pager/Range/Sliding.php index 6e4834404..2f43bd79a 100644 --- a/Library/Phalcon/Paginator/Pager/Range/Sliding.php +++ b/Library/Phalcon/Paginator/Pager/Range/Sliding.php @@ -39,8 +39,8 @@ public function getRange() $chunk = $pages; } - $chunkStart = $page - (floor($chunk / 2)); - $chunkEnd = $page + (ceil($chunk / 2) - 1); + $chunkStart = (int) ($page - (floor($chunk / 2))); + $chunkEnd = (int) ($page + (ceil($chunk / 2) - 1)); if ($chunkStart < 1) { $adjust = 1 - $chunkStart; diff --git a/Library/Phalcon/Session/Adapter/Memcache.php b/Library/Phalcon/Session/Adapter/Memcache.php deleted file mode 100755 index 2a202fabf..000000000 --- a/Library/Phalcon/Session/Adapter/Memcache.php +++ /dev/null @@ -1,226 +0,0 @@ - - */ -namespace Phalcon\Session\Adapter; - -use Phalcon; - -/** - * Memcache session adapter for Phalcon framework - * - * @category Phalcon - * @package Phalcon_Session_Adapter_Memcache - */ -class Memcache extends Phalcon\Session\Adapter implements Phalcon\Session\AdapterInterface -{ - /** - * Default option for memcache port - * - * @var integer - */ - const DEFAULT_OPTION_PORT = 11211; - - /** - * Default option for session lifetime - * - * @var integer - */ - const DEFAULT_OPTION_LIFETIME = 8600; - - /** - * Default option for persistent session - * - * @var boolean - */ - const DEFAULT_OPTION_PERSISTENT = false; - - /** - * Default option for prefix of sessionId's - * - * @var string - */ - const DEFAULT_OPTION_PREFIX = ''; - - /** - * Contains the memcache instance - * - * @var \Phalcon\Cache\Backend\Memcache - */ - protected $memcacheInstance = null; - - /** - * Class constructor. - * - * @param null|array $options - * @throws Phalcon\Session\Exception - */ - public function __construct($options = null) - { - if (!is_array($options)) { - throw new Phalcon\Session\Exception("No configuration given"); - } - - if (!isset($options["host"])) { - throw new Phalcon\Session\Exception("No session host given in options"); - } - - if (!isset($options["port"])) { - $options["port"] = self::DEFAULT_OPTION_PORT; - } - - if (!isset($options["lifetime"])) { - $options["lifetime"] = self::DEFAULT_OPTION_LIFETIME; - } - - if (!isset($options["persistent"])) { - $options["persistent"] = self::DEFAULT_OPTION_PERSISTENT; - } - - if (!isset($options["prefix"])) { - $options["prefix"] = self::DEFAULT_OPTION_PREFIX; - } - - session_set_save_handler( - array($this, 'open'), - array($this, 'close'), - array($this, 'read'), - array($this, 'write'), - array($this, 'destroy'), - array($this, 'gc') - ); - - parent::__construct($options); - } - - /** - * {@inheritdoc} - * - * @return boolean - */ - public function open() - { - return true; - } - - /** - * {@inheritdoc} - * - * @return boolean - */ - public function close() - { - return true; - } - - /** - * {@inheritdoc} - * - * @param string $sessionId - * @return mixed - */ - public function read($sessionId) - { - return $this->getMemcacheInstance()->get( - $this->getSessionId($sessionId), - $this->getOption('lifetime') - ); - } - - /** - * {@inheritdoc} - * - * @param string $sessionId - * @param string $data - */ - public function write($sessionId, $data) - { - $this->getMemcacheInstance()->save( - $this->getSessionId($sessionId), - $data, - $this->getOption('lifetime') - ); - } - - /** - * {@inheritdoc} - * - * @param string $sessionId - * @return boolean - */ - public function destroy($session_id = null) - { - if (is_null($session_id)) { - $session_id = $this->getId(); - } - - return $this->getMemcacheInstance()->delete($this->getSessionId($session_id)); - } - - /** - * {@inheritdoc} - */ - public function gc() - { - } - - /** - * {@inheritdoc} - * - * @param string $key - * @return mixed - */ - public function getOption($key) - { - $options = $this->getOptions(); - if (!isset($options[$key])) { - return null; - } - - return $options[$key]; - } - - /** - * Returns the memcache instance. - * - * @return \Phalcon\Cache\Backend\Memcache - */ - protected function getMemcacheInstance() - { - if ($this->memcacheInstance === null) { - $this->memcacheInstance = new Phalcon\Cache\Backend\Memcache( - new Phalcon\Cache\Frontend\Data(array("lifetime" => $this->getOption("lifetime"))), - array( - 'host' => $this->getOption('host'), - 'port' => $this->getOption('port'), - 'persistent' => $this->getOption('persistent') - ) - ); - } - - return $this->memcacheInstance; - } - - /** - * Returns the sessionId with prefix - * - * @param string $sessionId - * @return string - */ - protected function getSessionId($sessionId) - { - return (strlen($this->getOption('prefix')) > 0) - ? $this->getOption('prefix') . '_' . $sessionId - : $sessionId; - } -} diff --git a/Library/Phalcon/Session/Adapter/README.md b/Library/Phalcon/Session/Adapter/README.md index 73bb5c279..fdf6e2fd5 100644 --- a/Library/Phalcon/Session/Adapter/README.md +++ b/Library/Phalcon/Session/Adapter/README.md @@ -43,29 +43,6 @@ This adapter uses the following table to store the data: ) ``` - -Memcache ---------- -This adapter uses a Memcache backend to store session data: - -```php - -$di->set('session', function(){ - - $memcache = new Phalcon\Session\Adapter\Memcache(array( - 'host' => '127.0.0.1', // mandatory - 'port' => 11211, // optional (standard: 11211) - 'lifetime' => 8600, // optional (standard: 8600) - 'prefix' => 'my-app' // optional (standard: [empty_string]), means memcache key is my-app_31231jkfsdfdsfds3 - 'persistent' => false // optional (standard: false) - )); - $memcache->start(); - return $memcache; -}); - -``` - - Mongo ----- This adapter uses a Mongo database backend to store session data: diff --git a/Library/Phalcon/Translate/Adapter/Csv.php b/Library/Phalcon/Translate/Adapter/Csv.php deleted file mode 100644 index f6d1a57f3..000000000 --- a/Library/Phalcon/Translate/Adapter/Csv.php +++ /dev/null @@ -1,75 +0,0 @@ - ';', - 'length' => 0, - 'enclosure' => '"', - ); - - $options = array_merge($default, $options); - if (false === ($file = @fopen($options['file'], 'rb'))) { - throw new \Exception('Error opening translation file "' . $options['file'] . '".'); - } - - while (false !== ($data = fgetcsv($file, $options['length'], $options['delimiter'], $options['enclosure']))) { - if (substr($data[0], 0, 1) === '#' || !isset($data[1])) { - continue; - } - - $this->translate[$data[0]] = $data[1]; - } - - @fclose($file); - } - - /** - * {@inheritdoc} - * - * @param string $index - * @param array $placeholders - * @return string - */ - public function query($index, $placeholders = null) - { - if (!$this->exists($index)) { - return $index; - } - - return self::setPlaceholders($this->translate[$index], $placeholders); - } - - /** - * {@inheritdoc} - * - * @param string $index - * @return boolean - */ - public function exists($index) - { - return isset($this->translate[$index]); - } -} diff --git a/Library/Phalcon/Translate/Adapter/Gettext.php b/Library/Phalcon/Translate/Adapter/Gettext.php deleted file mode 100644 index 99b0f0515..000000000 --- a/Library/Phalcon/Translate/Adapter/Gettext.php +++ /dev/null @@ -1,380 +0,0 @@ - | - | Eduar Carvajal
test
', - ); - - // set for testing purposes - protected $flushBuffer = false; - - public function testDumpingHtmlStringVarByDefaultShouldEchoNonEscapedDump() - { - ob_start(); - $dump = new \Phalcon\Debug\Dump($this->flushBuffer); - $dump->dump($this->fixtures['htmlString']); - $output = ob_get_clean(); - $this->assertBacktraceExists($output); - // assert string was not converted - $this->assertContains($this->fixtures['htmlString'], $output); - // assert correct sapi set - $this->assertEquals(PHP_SAPI, \Phalcon\Debug\Dump::getSapi()); - } - - public function testDumpingHtmlStringVarWithNonCliSapiShouldEchoEscapedDump() - { - // non cli sapi - \Phalcon\Debug\Dump::setSapi('apache'); - - ob_start(); - $dump = new \Phalcon\Debug\Dump($this->flushBuffer); - $dump->dump($this->fixtures['htmlString']); - $output = ob_get_clean(); - $this->assertBacktraceExists($output); - // assert string was converted - $this->assertContains(htmlentities($this->fixtures['htmlString'], ENT_QUOTES, 'UTF-8'), $output); - // assert correct sapi set - $this->assertEquals('apache', \Phalcon\Debug\Dump::getSapi()); - } - - public function testDumpingHtmlStringVarWithSupressedOutputShouldReturnValue() - { - // supress output - \Phalcon\Debug\Dump::setOutput(false); - - ob_start(); - $dump = new \Phalcon\Debug\Dump($this->flushBuffer); - $return = $dump->dump($this->fixtures['htmlString']); - $output = ob_get_clean(); - $this->assertBacktraceNotExists($output); - // assert no output - $this->assertEmpty($output); - // assert returned value has backtrace - $this->assertBacktraceExists($return); - // assert dump was returned - $this->assertContains($this->fixtures['htmlString'], $return); - // assert right output flag was set - $this->assertFalse(\Phalcon\Debug\Dump::getOutput()); - } - - public function testSecondDumpParamShouldOverrideGlobalOutputSetting() - { - ob_start(); - $dump = new \Phalcon\Debug\Dump($this->flushBuffer); - $return = $dump->dump($this->fixtures['htmlString'], false); - $output = ob_get_clean(); - // no backtrace - $this->assertBacktraceNotExists($output); - // assert no output - $this->assertEmpty($output); - // assert dump was returned - $this->assertContains($this->fixtures['htmlString'], $return); - } - - public function testIfNoXdebugVarDumpObjectShouldFallback() - { - /* @var $mockDumpStub \Phalcon\Debug\Dump */ - $mockDumpStub = $this->getMock('\Phalcon\Debug\Dump', array('xdebugDumpExists'), - array($this->flushBuffer)); - - $mockDumpStub->expects($this->once()) - ->method('xdebugDumpExists') - ->will($this->returnValue(false)); - - ob_start(); - $mockDumpStub->dump($this->fixtures['htmlString']); - $output = ob_get_clean(); - $this->assertBacktraceExists($output); - // assert string was not converted - $this->assertContains($this->fixtures['htmlString'], $output); - - } - - public function testObGetCleanShouldReturnEmptyIfFlushBufferNotSet() - { - ob_start(); - $dump = new \Phalcon\Debug\Dump(); - $return = $dump->dump($this->fixtures['htmlString']); - $output = ob_get_clean(); - - // assert output empty - $this->assertEmpty($output); - $this->assertBacktraceExists($return); - $this->assertContains($this->fixtures['htmlString'], $return); - - } - - protected function assertBacktraceExists($output) - { - // assert backtrace exists - $this->assertContains('Line:', $output); - $this->assertContains('DumpTest.php', $output); - } - - protected function assertBacktraceNotExists($output) - { - // assert backtrace doesnt exist - $this->assertNotContains('Line:', $output); - $this->assertNotContains('DumpTest.php', $output); - } - - protected function tearDown() - { - parent::tearDown(); - // reset output flag to default - \Phalcon\Debug\Dump::setOutput(true); - // reset PHP_SAPI - \Phalcon\Debug\Dump::setSapi(PHP_SAPI); - - } -} diff --git a/tests/Phalcon/Mvc/Model/Validator/BetweenTest.php b/tests/Phalcon/Mvc/Model/Validator/BetweenTest.php index 9a2b5ac2b..f9208f25e 100644 --- a/tests/Phalcon/Mvc/Model/Validator/BetweenTest.php +++ b/tests/Phalcon/Mvc/Model/Validator/BetweenTest.php @@ -62,17 +62,6 @@ public function testValidate($min, $max, $position, $willReturn) } - /** - * @expectedException \Phalcon\Mvc\Model\Exception - * @expectedExceptionMessage Invalid parameter type. - */ - public function testExceptionNotObject() - { - $obj = new Between(array('min' => 1, 'max' => 2, 'field' => 'position')); - - $obj->validate(1); - } - public function testValidateInstanceOf() { require_once(__DIR__ . '/resources/TestBetweenModel.php'); @@ -81,24 +70,6 @@ public function testValidateInstanceOf() $this->assertInstanceOf('Phalcon\Mvc\ModelInterface', $obj); } - /** - * @expectedException \Phalcon\Mvc\Model\Exception - * @expectedExceptionMessage Invalid parameter type. - */ - public function testValidateOtherInstance() - { - require_once(__DIR__ . '/resources/TestBetweenFail.php'); - - $obj = new \TestBetweenFail(); - - $obj->min = 1; - $obj->max = 3; - $obj->position = 4; - - $this->assertNotInstanceOf('Phalcon\Mvc\ModelInterface', $obj); - $obj->validation(); - } - /** * @expectedException \Phalcon\Mvc\Model\Exception * @expectedExceptionMessage Field name must be a string diff --git a/tests/Phalcon/Mvc/Model/Validator/CardNumberTest.php b/tests/Phalcon/Mvc/Model/Validator/CardNumberTest.php index 25c9c9b41..2db721ff6 100644 --- a/tests/Phalcon/Mvc/Model/Validator/CardNumberTest.php +++ b/tests/Phalcon/Mvc/Model/Validator/CardNumberTest.php @@ -141,46 +141,9 @@ public function testValidateInstanceOfModel() $obj = new \TestCardNumberModel(); $this->assertInstanceOf('Phalcon\Mvc\ModelInterface', $obj); - $this->assertNotInstanceOf('Phalcon\Mvc\CollectionInterface', $obj); } - public function testValidateInstanceOfCollection() - { - $di = New DI(); - $di->set('collectionManager', function () { - return new \Phalcon\Mvc\Collection\Manager(); - }); - - require_once(__DIR__ . '/resources/TestCardNumberCollection.php'); - - $obj = new \TestCardNumberCollection($di); - - $obj->type = CardNumber::MASTERCARD; - $obj->cardnumber = 1270338206812535; - - $this->assertInstanceOf('Phalcon\Mvc\CollectionInterface', $obj); - $this->assertNotInstanceOf('Phalcon\Mvc\ModelInterface', $obj); - $obj->validation(); - } - - /** - * @expectedException \Phalcon\Mvc\Model\Exception - * @expectedExceptionMessage Invalid parameter type. - */ - public function testValidateOtherInstance() - { - require_once(__DIR__ . '/resources/TestCardNumberFail.php'); - - $obj = new \TestCardNumberFail(); - - $obj->type = CardNumber::MASTERCARD; - $obj->cardnumber = 1270338206812535; - - $this->assertNotInstanceOf('Phalcon\Mvc\CollectionInterface', $obj); - $this->assertNotInstanceOf('Phalcon\Mvc\ModelInterface', $obj); - $obj->validation(); - } /** * @expectedException \Phalcon\Mvc\Model\Exception diff --git a/tests/Phalcon/Paginator/PagerTest.php b/tests/Phalcon/Paginator/PagerTest.php new file mode 100644 index 000000000..09624bee0 --- /dev/null +++ b/tests/Phalcon/Paginator/PagerTest.php @@ -0,0 +1,262 @@ +getMockBuilder('Phalcon\Paginator\Adapter\QueryBuilder') + ->disableOriginalConstructor() + ->getMock(); + + $pager = new \Phalcon\Paginator\Pager($adapter); + $this->assertInstanceOf('Phalcon\Paginator\Pager', $pager); + } + + public function testCallingGetPagesInRangeMethodWithDefaultOptionsShouldReturnExpectedArray() + { + // stub paginate + $paginate = new \stdClass(); + $paginate->total_pages = 20; + $paginate->current = 5; + $paginate->last = 20; + + $adapter = $this->getMockBuilder('Phalcon\Paginator\Adapter\QueryBuilder') + ->disableOriginalConstructor() + ->setMethods(array('getPaginate')) + ->getMock(); + $adapter->expects($this->once()) + ->method('getPaginate') + ->will($this->returnValue($paginate)); + + $pager = new \Phalcon\Paginator\Pager($adapter); + $this->assertEquals( + array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), + $pager->getPagesInRange() + ); + } + + public function testCallingGetPagesInRangeMethodWithSliderOnEndShouldReturnExpectedArray() + { + // stub paginate + $paginate = new \stdClass(); + $paginate->total_pages = 20; + $paginate->current = 20; + $paginate->last = 20; + + $adapter = $this->getMockBuilder('Phalcon\Paginator\Adapter\QueryBuilder') + ->disableOriginalConstructor() + ->setMethods(array('getPaginate')) + ->getMock(); + $adapter->expects($this->once()) + ->method('getPaginate') + ->will($this->returnValue($paginate)); + + $pager = new \Phalcon\Paginator\Pager($adapter, array('rangeLength' => 5)); + $this->assertEquals( + array(16, 17, 18, 19, 20), + $pager->getPagesInRange() + ); + } + + public function testCallingGetPagesInRangeMethodWithSliderOnStartShouldReturnExpectedArray() + { + // stub paginate + $paginate = new \stdClass(); + $paginate->total_pages = 20; + $paginate->current = 1; + $paginate->last = 20; + + $adapter = $this->getMockBuilder('Phalcon\Paginator\Adapter\QueryBuilder') + ->disableOriginalConstructor() + ->setMethods(array('getPaginate')) + ->getMock(); + $adapter->expects($this->once()) + ->method('getPaginate') + ->will($this->returnValue($paginate)); + + $pager = new \Phalcon\Paginator\Pager($adapter, array('rangeLength' => 5)); + $this->assertEquals( + array(1, 2, 3, 4, 5), + $pager->getPagesInRange() + ); + } + + public function testGetLayoutMethodShouldReturnObjectOfLayoutType() + { + // stub paginate + $paginate = new \stdClass(); + $paginate->total_pages = 20; + $paginate->current = 1; + $paginate->last = 20; + + $adapter = $this->getMockBuilder('Phalcon\Paginator\Adapter\QueryBuilder') + ->disableOriginalConstructor() + ->setMethods(array('getPaginate')) + ->getMock(); + $adapter->expects($this->once()) + ->method('getPaginate') + ->will($this->returnValue($paginate)); + + $pager = new \Phalcon\Paginator\Pager( + $adapter, + array( + 'rangeLength' => 5, + 'urlMask' => 'xxx', + ) + ); + $this->assertInstanceOf('Phalcon\Paginator\Pager\Layout', $pager->getLayout()); + } + + public function testPagerGetterMethodsShouldReturnExpectedValues() + { + // stub paginate + $paginate = new \stdClass(); + $paginate->total_pages = 20; + $paginate->current = 10; + $paginate->last = 20; + $paginate->total_items = 100; + $paginate->first = 1; + $paginate->before = $paginate->current - 1; + $paginate->next = $paginate->current + 1; + $paginate->items = new \ArrayIterator(array(1, 2, 4, 5)); + + $adapter = $this->getMockBuilder('Phalcon\Paginator\Adapter\QueryBuilder') + ->disableOriginalConstructor() + ->setMethods(array('getPaginate')) + ->getMock(); + $adapter->expects($this->once()) + ->method('getPaginate') + ->will($this->returnValue($paginate)); + + $pager = new \Phalcon\Paginator\Pager( + $adapter, + array( + 'rangeLength' => 5, + 'urlMask' => 'xxx', + ) + ); + $this->assertEquals($paginate->current, $pager->getCurrentPage()); + $this->assertEquals($paginate->total_items, $pager->count()); + $this->assertEquals(1, $pager->getFirstPage()); + $this->assertTrue($pager->haveToPaginate()); + $this->assertEquals($paginate->before, $pager->getPreviousPage()); + $this->assertEquals($paginate->next, $pager->getNextPage()); + $this->assertInstanceOf('Iterator', $pager->getIterator()); + } + + public function testPagerGetIteratorMethodWillCreateIteratorIfArrayIsPassed() + { + // stub paginate + $paginate = new \stdClass(); + $paginate->total_pages = 20; + $paginate->current = 10; + $paginate->items = array(1, 2, 4, 5); + + $adapter = $this->getMockBuilder('Phalcon\Paginator\Adapter\QueryBuilder') + ->disableOriginalConstructor() + ->setMethods(array('getPaginate')) + ->getMock(); + $adapter->expects($this->once()) + ->method('getPaginate') + ->will($this->returnValue($paginate)); + + $pager = new \Phalcon\Paginator\Pager( + $adapter, + array( + 'rangeLength' => 5, + 'urlMask' => 'xxx', + ) + ); + $this->assertInstanceOf('Iterator', $pager->getIterator()); + } + + /** + * @expectedException \RuntimeException + * @expectedExceptionMessage You must provide option "urlMask" + */ + public function testGetLayoutMethodWithoutUrlMaskOptionShouldThrowException() + { + // stub paginate + $paginate = new \stdClass(); + $paginate->total_pages = 20; + $paginate->current = 1; + + $adapter = $this->getMockBuilder('Phalcon\Paginator\Adapter\QueryBuilder') + ->disableOriginalConstructor() + ->setMethods(array('getPaginate')) + ->getMock(); + $adapter->expects($this->once()) + ->method('getPaginate') + ->will($this->returnValue($paginate)); + + $pager = new \Phalcon\Paginator\Pager( + $adapter, + array( + 'rangeLength' => 5, + ) + ); + $pager->getLayout(); + } + + /** + * @expectedException \RuntimeException + * @expectedExceptionMessage Unable to find range class "UnknownRangeClass" + */ + public function testGetLayoutMethodShouldWithInvalidRangeClassShouldThrowException() + { + // stub paginate + $paginate = new \stdClass(); + $paginate->total_pages = 20; + $paginate->current = 1; + + $adapter = $this->getMockBuilder('Phalcon\Paginator\Adapter\QueryBuilder') + ->disableOriginalConstructor() + ->setMethods(array('getPaginate')) + ->getMock(); + $adapter->expects($this->once()) + ->method('getPaginate') + ->will($this->returnValue($paginate)); + + $pager = new \Phalcon\Paginator\Pager( + $adapter, + array( + 'rangeLength' => 5, + 'rangeClass' => 'UnknownRangeClass', + 'urlMask' => 'xxx', + ) + ); + $pager->getLayout(); + } + + /** + * @expectedException \RuntimeException + * @expectedExceptionMessage Unable to find layout "UnknownLayoutClass" + */ + public function testGetLayoutMethodShouldWithInvalidLayoutClassShouldThrowException() + { + // stub paginate + $paginate = new \stdClass(); + $paginate->total_pages = 20; + $paginate->current = 1; + + + $adapter = $this->getMockBuilder('Phalcon\Paginator\Adapter\QueryBuilder') + ->disableOriginalConstructor() + ->setMethods(array('getPaginate')) + ->getMock(); + $adapter->expects($this->once()) + ->method('getPaginate') + ->will($this->returnValue($paginate)); + + $pager = new \Phalcon\Paginator\Pager( + $adapter, + array( + 'rangeLength' => 5, + 'layoutClass' => 'UnknownLayoutClass', + 'urlMask' => 'xxx', + ) + ); + $pager->getLayout(); + } +}