diff --git a/.gitignore b/.gitignore index dadd0895e..7ed06261c 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,6 @@ # # https://help.github.com/articles/ignoring-files/#create-a-global-gitignore -composer.lock /vendor/ codeception.yml tests/aerospike.suite.yml diff --git a/Library/Phalcon/Acl/Adapter/Database.php b/Library/Phalcon/Acl/Adapter/Database.php deleted file mode 100644 index 1eab8a038..000000000 --- a/Library/Phalcon/Acl/Adapter/Database.php +++ /dev/null @@ -1,697 +0,0 @@ - | - | Eduar Carvajal | - +------------------------------------------------------------------------+ -*/ - -namespace Phalcon\Acl\Adapter; - -use Phalcon\Db; -use Phalcon\Db\AdapterInterface as DbAdapter; -use Phalcon\Acl\Adapter; -use Phalcon\Acl\Exception; -use Phalcon\Acl\Resource; -use Phalcon\Acl; -use Phalcon\Acl\Role; -use Phalcon\Acl\RoleInterface; - -/** - * Phalcon\Acl\Adapter\Database - * Manages ACL lists in database tables - */ -class Database extends Adapter -{ - /** - * @var DbAdapter - */ - protected $connection; - - /** - * Roles table - * @var string - */ - protected $roles; - - /** - * Resources table - * @var string - */ - protected $resources; - - /** - * Resources Accesses table - * @var string - */ - protected $resourcesAccesses; - - /** - * Access List table - * @var string - */ - protected $accessList; - - /** - * Roles Inherits table - * @var string - */ - protected $rolesInherits; - - /** - * Default action for no arguments is allow - * @var int - */ - protected $noArgumentsDefaultAction = Acl::ALLOW; - - /** - * Class constructor. - * - * @param array $options Adapter config - * @throws Exception - */ - public function __construct(array $options) - { - if (!isset($options['db']) || !$options['db'] instanceof DbAdapter) { - throw new Exception( - 'Parameter "db" is required and it must be an instance of Phalcon\Acl\AdapterInterface' - ); - } - - $this->connection = $options['db']; - - $tables = [ - 'roles', - 'resources', - 'resourcesAccesses', - 'accessList', - 'rolesInherits', - ]; - - foreach ($tables as $table) { - if (!isset($options[$table]) || empty($options[$table]) || !is_string($options[$table])) { - throw new Exception( - "Parameter '{$table}' is required and it must be a non empty string" - ); - } - - $this->{$table} = $this->connection->escapeIdentifier( - $options[$table] - ); - } - } - - /** - * {@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 - * @throws \Phalcon\Acl\Exception - */ - public function addRole($role, $accessInherits = null) - { - if (is_string($role)) { - $role = new Role( - $role, - ucwords($role) . ' Role' - ); - } - - if (!$role instanceof RoleInterface) { - throw new Exception( - 'Role must be either an string or implement RoleInterface' - ); - } - - $exists = $this->connection->fetchOne( - "SELECT COUNT(*) FROM {$this->roles} WHERE name = ?", - null, - [ - $role->getName(), - ] - ); - - if (!$exists[0]) { - $this->connection->execute( - "INSERT INTO {$this->roles} VALUES (?, ?)", - [ - $role->getName(), - $role->getDescription(), - ] - ); - - $this->connection->execute( - "INSERT INTO {$this->accessList} VALUES (?, ?, ?, ?)", - [ - $role->getName(), - '*', - '*', - $this->_defaultAccess, - ] - ); - } - - if ($accessInherits) { - return $this->addInherit( - $role->getName(), - $accessInherits - ); - } - - return true; - } - - /** - * {@inheritdoc} - * - * @param string $roleName - * @param string $roleToInherit - * @throws \Phalcon\Acl\Exception - */ - public function addInherit($roleName, $roleToInherit) - { - $sql = "SELECT COUNT(*) FROM {$this->roles} WHERE name = ?"; - - $exists = $this->connection->fetchOne( - $sql, - null, - [ - $roleName, - ] - ); - - if (!$exists[0]) { - throw new Exception( - "Role '{$roleName}' does not exist in the role list" - ); - } - - $exists = $this->connection->fetchOne( - "SELECT COUNT(*) FROM {$this->rolesInherits} WHERE roles_name = ? AND roles_inherit = ?", - null, - [ - $roleName, - $roleToInherit, - ] - ); - - if (!$exists[0]) { - $this->connection->execute( - "INSERT INTO {$this->rolesInherits} VALUES (?, ?)", - [ - $roleName, - $roleToInherit, - ] - ); - } - } - - /** - * {@inheritdoc} - * - * @param string $roleName - * @return boolean - */ - public function isRole($roleName) - { - $exists = $this->connection->fetchOne( - "SELECT COUNT(*) FROM {$this->roles} WHERE name = ?", - null, - [ - $roleName, - ] - ); - - return (bool) $exists[0]; - } - - /** - * {@inheritdoc} - * - * @param string $resourceName - * @return boolean - */ - public function isResource($resourceName) - { - $exists = $this->connection->fetchOne( - "SELECT COUNT(*) FROM {$this->resources} WHERE name = ?", - null, - [ - $resourceName, - ] - ); - - return (bool) $exists[0]; - } - - /** - * {@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'), ['create', 'search']); - * $acl->addResource('customers', ['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); - } - - $exists = $this->connection->fetchOne( - "SELECT COUNT(*) FROM {$this->resources} WHERE name = ?", - null, - [ - $resource->getName(), - ] - ); - - if (!$exists[0]) { - $this->connection->execute( - "INSERT INTO {$this->resources} VALUES (?, ?)", - [ - $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" - ); - } - - $sql = "SELECT COUNT(*) FROM {$this->resourcesAccesses} WHERE resources_name = ? AND access_name = ?"; - - if (!is_array($accessList)) { - $accessList = [$accessList]; - } - - foreach ($accessList as $accessName) { - $exists = $this->connection->fetchOne( - $sql, - null, - [ - $resourceName, - $accessName, - ] - ); - - if (!$exists[0]) { - $this->connection->execute( - 'INSERT INTO ' . $this->resourcesAccesses . ' VALUES (?, ?)', - [ - $resourceName, - $accessName, - ] - ); - } - } - - return true; - } - - /** - * {@inheritdoc} - * - * @return \Phalcon\Acl\Resource[] - */ - public function getResources() - { - $resources = []; - - $sql = "SELECT * FROM {$this->resources}"; - - $rows = $this->connection->fetchAll( - $sql, - Db::FETCH_ASSOC - ); - - foreach ($rows as $row) { - $resources[] = new Resource( - $row['name'], - $row['description'] - ); - } - - return $resources; - } - - /** - * {@inheritdoc} - * - * @return RoleInterface[] - */ - public function getRoles() - { - $roles = []; - $sql = "SELECT * FROM {$this->roles}"; - - $rows = $this->connection->fetchAll( - $sql, - Db::FETCH_ASSOC - ); - - foreach ($rows as $row) { - $roles[] = new Role( - $row['name'], - $row['description'] - ); - } - - return $roles; - } - - /** - * {@inheritdoc} - * - * @param string $resourceName - * @param array|string $accessList - */ - public function dropResourceAccess($resourceName, $accessList) - { - throw new \BadMethodCallException('Not implemented yet.'); - } - - /** - * {@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', ['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 $roleName - * @param string $resourceName - * @param array|string $access - * @param mixed $func - */ - public function allow($roleName, $resourceName, $access, $func = null) - { - $this->allowOrDeny($roleName, $resourceName, $access, Acl::ALLOW); - } - - /** - * {@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', ['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 - * @param mixed $func - * @return boolean - */ - public function deny($roleName, $resourceName, $access, $func = null) - { - $this->allowOrDeny($roleName, $resourceName, $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 - * @param array $parameters - * @return bool - */ - public function isAllowed($role, $resource, $access, array $parameters = null) - { - $sql = implode( - ' ', - [ - "SELECT " . $this->connection->escapeIdentifier('allowed') . " FROM {$this->accessList} AS a", - // role_name in: - 'WHERE roles_name IN (', - // given 'role'-parameter - 'SELECT ? ', - // inherited role_names - "UNION SELECT roles_inherit FROM {$this->rolesInherits} WHERE roles_name = ?", - // or 'any' - "UNION SELECT '*'", - ')', - // resources_name should be given one or 'any' - "AND resources_name IN (?, '*')", - // access_name should be given one or 'any' - "AND access_name IN (?, '*')", - // order be the sum of bools for 'literals' before 'any' - "ORDER BY " . $this->connection->escapeIdentifier('allowed') . " DESC", - // get only one... - 'LIMIT 1', - ] - ); - - // fetch one entry... - $allowed = $this->connection->fetchOne( - $sql, - Db::FETCH_NUM, - [ - $role, - $role, - $resource, - $access, - ] - ); - - if (is_array($allowed)) { - return (bool) $allowed[0]; - } - - /** - * Return the default access action - */ - return $this->_defaultAccess; - } - - /** - * Returns the default ACL access level for no arguments provided - * in isAllowed action if there exists func for accessKey - * - * @return int - */ - public function getNoArgumentsDefaultAction() - { - return $this->noArgumentsDefaultAction; - } - - /** - * Sets the default access level for no arguments provided - * in isAllowed action if there exists func for accessKey - * - * @param int $defaultAccess Phalcon\Acl::ALLOW or Phalcon\Acl::DENY - */ - public function setNoArgumentsDefaultAction($defaultAccess) - { - $this->noArgumentsDefaultAction = intval($defaultAccess); - } - - /** - * Inserts/Updates a permission in the access list - * - * @param string $roleName - * @param string $resourceName - * @param string $accessName - * @param integer $action - * @return boolean - * @throws \Phalcon\Acl\Exception - */ - protected function insertOrUpdateAccess($roleName, $resourceName, $accessName, $action) - { - /** - * Check if the access is valid in the resource unless wildcard - */ - if ($resourceName !== '*' && $accessName !== '*') { - $sql = "SELECT COUNT(*) FROM {$this->resourcesAccesses} WHERE resources_name = ? AND access_name = ?"; - - $exists = $this->connection->fetchOne( - $sql, - null, - [ - $resourceName, - $accessName, - ] - ); - - if (!$exists[0]) { - throw new Exception( - "Access '{$accessName}' does not exist in resource '{$resourceName}' in ACL" - ); - } - } - - /** - * Update the access in access_list - */ - $sql = "SELECT COUNT(*) FROM {$this->accessList} " - . " WHERE roles_name = ? AND resources_name = ? AND access_name = ?"; - - $exists = $this->connection->fetchOne( - $sql, - null, - [ - $roleName, - $resourceName, - $accessName, - ] - ); - - if (!$exists[0]) { - $sql = "INSERT INTO {$this->accessList} VALUES (?, ?, ?, ?)"; - - $params = [ - $roleName, - $resourceName, - $accessName, - $action, - ]; - } else { - $sql = "UPDATE {$this->accessList} SET allowed = ? " . - "WHERE roles_name = ? AND resources_name = ? AND access_name = ?"; - - $params = [ - $action, - $roleName, - $resourceName, - $accessName, - ]; - } - - $this->connection->execute($sql, $params); - - /** - * Update the access '*' in access_list - */ - $sql = "SELECT COUNT(*) FROM {$this->accessList} " . - "WHERE roles_name = ? AND resources_name = ? AND access_name = ?"; - - $exists = $this->connection->fetchOne( - $sql, - null, - [ - $roleName, - $resourceName, - '*', - ] - ); - - if (!$exists[0]) { - $sql = "INSERT INTO {$this->accessList} VALUES (?, ?, ?, ?)"; - - $this->connection->execute( - $sql, - [ - $roleName, - $resourceName, - '*', - $this->_defaultAccess, - ] - ); - } - - 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 (!is_array($access)) { - $access = [$access]; - } - - foreach ($access as $accessName) { - $this->insertOrUpdateAccess( - $roleName, - $resourceName, - $accessName, - $action - ); - } - } -} diff --git a/Library/Phalcon/Acl/Adapter/Mongo.php b/Library/Phalcon/Acl/Adapter/Mongo.php deleted file mode 100644 index de991db8b..000000000 --- a/Library/Phalcon/Acl/Adapter/Mongo.php +++ /dev/null @@ -1,568 +0,0 @@ - | - | Eduar Carvajal | - +------------------------------------------------------------------------+ -*/ - -namespace Phalcon\Acl\Adapter; - -use Phalcon\Acl\Adapter; -use Phalcon\Acl\Exception; -use Phalcon\Acl\Resource; -use Phalcon\Acl; -use Phalcon\Acl\Role; -use Phalcon\Acl\RoleInterface; - -/** - * Phalcon\Acl\Adapter\Mongo - * Manages ACL lists using Mongo Collections - */ -class Mongo extends Adapter -{ - /** - * @var array - */ - protected $options; - - /** - * Default action for no arguments is allow - * @var int - */ - protected $noArgumentsDefaultAction = Acl::ALLOW; - - /** - * Class constructor. - * - * @param array $options - * @throws \Phalcon\Acl\Exception - */ - public function __construct($options) - { - if (!is_array($options)) { - throw new Exception("Acl options must be an array"); - } - - if (!isset($options['db'])) { - throw new Exception("Parameter 'db' is required"); - } - - if (!isset($options['roles'])) { - throw new Exception("Parameter 'roles' is required"); - } - - if (!isset($options['resources'])) { - throw new Exception("Parameter 'resources' is required"); - } - - if (!isset($options['resourcesAccesses'])) { - throw new Exception("Parameter 'resourcesAccesses' is required"); - } - - if (!isset($options['accessList'])) { - throw new Exception("Parameter 'accessList' is required"); - } - - $this->options = $options; - } - - /** - * {@inheritdoc} - * - * Example: - * $acl->addRole(new Phalcon\Acl\Role('administrator'), 'consultor'); - * $acl->addRole('administrator', 'consultor'); - * - * @param string $role - * @param array $accessInherits - * @return boolean - * @throws \Phalcon\Acl\Exception - */ - public function addRole($role, $accessInherits = null) - { - if (is_string($role)) { - $role = new Role( - $role, - ucwords($role) . ' Role' - ); - } - - if (!$role instanceof RoleInterface) { - throw new Exception( - 'Role must be either an string or implement RoleInterface' - ); - } - - $roles = $this->getCollection('roles'); - - $exists = $roles->count( - [ - 'name' => $role->getName(), - ] - ); - - if (!$exists) { - $roles->insert( - [ - 'name' => $role->getName(), - 'description' => $role->getDescription(), - ] - ); - - $this->getCollection('accessList')->insert( - [ - 'roles_name' => $role->getName(), - 'resources_name' => '*', - 'access_name' => '*', - 'allowed' => $this->_defaultAccess, - ] - ); - } - - if ($accessInherits) { - return $this->addInherit( - $role->getName(), - $accessInherits - ); - } - - return true; - } - - /** - * {@inheritdoc} - * - * @param string $roleName - * @param string $roleToInherit - * @throws \BadMethodCallException - */ - public function addInherit($roleName, $roleToInherit) - { - throw new \BadMethodCallException('Not implemented yet.'); - } - - /** - * {@inheritdoc} - * - * @param string $roleName - * @return boolean - */ - public function isRole($roleName) - { - return $this->getCollection('roles')->count(['name' => $roleName]) > 0; - } - - /** - * {@inheritdoc} - * - * @param string $resourceName - * @return boolean - */ - public function isResource($resourceName) - { - return $this->getCollection('resources')->count(['name' => $resourceName]) > 0; - } - - /** - * {@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'), ['create', 'search']); - * $acl->addResource('customers', ['create', 'search']); - * - * - * @param \Phalcon\Acl\Resource $resource - * @param array|string $accessList - * @return boolean - */ - public function addResource($resource, $accessList = null) - { - if (!is_object($resource)) { - $resource = new Resource($resource); - } - - $resources = $this->getCollection('resources'); - - $exists = $resources->count( - [ - 'name' => $resource->getName(), - ] - ); - - if (!$exists) { - $resources->insert( - [ - 'name' => $resource->getName(), - 'description' => $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" - ); - } - - $resourcesAccesses = $this->getCollection('resourcesAccesses'); - - if (!is_array($accessList)) { - $accessList = [$accessList]; - } - - foreach ($accessList as $accessName) { - $exists = $resourcesAccesses->count( - [ - 'resources_name' => $resourceName, - 'access_name' => $accessName, - ] - ); - - if (!$exists) { - $resourcesAccesses->insert( - [ - 'resources_name' => $resourceName, - 'access_name' => $accessName, - ] - ); - } - } - - return true; - } - - /** - * {@inheritdoc} - * - * @return \Phalcon\Acl\Resource[] - */ - public function getResources() - { - $resources = []; - - foreach ($this->getCollection('resources')->find() as $row) { - $resources[] = new Resource( - $row['name'], - $row['description'] - ); - } - - return $resources; - } - - /** - * {@inheritdoc} - * - * @return RoleInterface[] - */ - public function getRoles() - { - $roles = []; - - foreach ($this->getCollection('roles')->find() as $row) { - $roles[] = new Role( - $row['name'], - $row['description'] - ); - } - - return $roles; - } - - /** - * {@inheritdoc} - * - * @param string $resourceName - * @param array|string $accessList - */ - public function dropResourceAccess($resourceName, $accessList) - { - throw new \BadMethodCallException('Not implemented yet.'); - } - - /** - * {@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', ['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 $roleName - * @param string $resourceName - * @param mixed $access - * @param mixed $func - */ - public function allow($roleName, $resourceName, $access, $func = null) - { - $this->allowOrDeny($roleName, $resourceName, $access, Acl::ALLOW); - } - - /** - * {@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', ['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 mixed $access - * @param mixed $func - * @return boolean - */ - public function deny($roleName, $resourceName, $access, $func = null) - { - $this->allowOrDeny($roleName, $resourceName, $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 - * @param array $parameters - * @return boolean - */ - public function isAllowed($role, $resource, $access, array $parameters = null) - { - $accessList = $this->getCollection('accessList'); - - $access = $accessList->findOne( - [ - 'roles_name' => $role, - 'resources_name' => $resource, - 'access_name' => $access, - ] - ); - - if (is_array($access)) { - return (bool) $access['allowed']; - } - - /** - * Check if there is an common rule for that resource - */ - $access = $accessList->findOne( - [ - 'roles_name' => $role, - 'resources_name' => $resource, - 'access_name' => '*', - ] - ); - - if (is_array($access)) { - return (bool) $access['allowed']; - } - - return $this->_defaultAccess; - } - - /** - * Returns the default ACL access level for no arguments provided - * in isAllowed action if there exists func for accessKey - * - * @return int - */ - public function getNoArgumentsDefaultAction() - { - return $this->noArgumentsDefaultAction; - } - - /** - * Sets the default access level for no arguments provided - * in isAllowed action if there exists func for accessKey - * - * @param int $defaultAccess Phalcon\Acl::ALLOW or Phalcon\Acl::DENY - */ - public function setNoArgumentsDefaultAction($defaultAccess) - { - $this->noArgumentsDefaultAction = intval($defaultAccess); - } - - /** - * Returns a mongo collection - * - * @param string $name - * @return \MongoCollection - */ - protected function getCollection($name) - { - return $this->options['db']->selectCollection($this->options[$name]); - } - - /** - * Inserts/Updates a permission in the access list - * - * @param string $roleName - * @param string $resourceName - * @param string $accessName - * @param integer $action - * @return boolean - * @throws \Phalcon\Acl\Exception - */ - protected function insertOrUpdateAccess($roleName, $resourceName, $accessName, $action) - { - /** - * Check if the access is valid in the resource - */ - $exists = $this->getCollection('resourcesAccesses')->count( - [ - 'resources_name' => $resourceName, - 'access_name' => $accessName, - ] - ); - - if (!$exists) { - throw new Exception( - "Access '" . $accessName . "' does not exist in resource '" . $resourceName . "' in ACL" - ); - } - - $accessList = $this->getCollection('accessList'); - - $access = $accessList->findOne( - [ - 'roles_name' => $roleName, - 'resources_name' => $resourceName, - 'access_name' => $accessName, - ] - ); - - if (!$access) { - $accessList->insert( - [ - 'roles_name' => $roleName, - 'resources_name' => $resourceName, - 'access_name' => $accessName, - 'allowed' => $action, - ] - ); - } else { - $access['allowed'] = $action; - - $accessList->save($access); - } - - /** - * Update the access '*' in access_list - */ - $exists = $accessList->count( - [ - 'roles_name' => $roleName, - 'resources_name' => $resourceName, - 'access_name' => '*', - ] - ); - - if (!$exists) { - $accessList->insert( - [ - 'roles_name' => $roleName, - 'resources_name' => $resourceName, - 'access_name' => '*', - 'allowed' => $this->_defaultAccess, - ] - ); - } - - return true; - } - - /** - * Inserts/Updates a permission in the access list - * - * @param string $roleName - * @param string $resourceName - * @param 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 (!is_array($access)) { - $access = [ - $access, - ]; - } - - foreach ($access as $accessName) { - $this->insertOrUpdateAccess( - $roleName, - $resourceName, - $accessName, - $action - ); - } - } -} diff --git a/Library/Phalcon/Acl/Adapter/README.md b/Library/Phalcon/Acl/Adapter/README.md deleted file mode 100644 index 2e66f7298..000000000 --- a/Library/Phalcon/Acl/Adapter/README.md +++ /dev/null @@ -1,100 +0,0 @@ -# Phalcon\Acl\Adapter - -Usage examples of the adapters available here: - -## Database - -This adapter uses a database to store the ACL list: - -```php -use Phalcon\Acl\Adapter\Database as AclDb; -use Phalcon\Db\Adapter\Pdo\Sqlite; - -$connection = new Sqlite( - [ - 'dbname' => 'sample.db', - ] -); - -$acl = AclDb( - [ - 'db' => $connection, - 'roles' => 'roles', - 'rolesInherits' => 'roles_inherits', - 'resources' => 'resources', - 'resourcesAccesses' => 'resources_accesses', - 'accessList' => 'access_list', - ] -); - -``` - -This adapter uses the following table to store the data: - -```sql -CREATE TABLE `roles` ( - `name` VARCHAR(32) NOT NULL, - `description` TEXT, - PRIMARY KEY(`name`) -); - -CREATE TABLE `access_list` ( - `roles_name` VARCHAR(32) NOT NULL, - `resources_name` VARCHAR(32) NOT NULL, - `access_name` VARCHAR(32) NOT NULL, - `allowed` INT(3) NOT NULL, - PRIMARY KEY(`roles_name`, `resources_name`, `access_name`) -); - -CREATE TABLE `resources` ( - `name` VARCHAR(32) NOT NULL, - `description` TEXT, - PRIMARY KEY(`name`) -); - -CREATE TABLE `resources_accesses` ( - `resources_name` VARCHAR(32) NOT NULL, - `access_name` VARCHAR(32) NOT NULL, - PRIMARY KEY(`resources_name`, `access_name`) -); - -CREATE TABLE `roles_inherits` ( - `roles_name` VARCHAR(32) NOT NULL, - `roles_inherit` VARCHAR(32) NOT NULL, - PRIMARY KEY(roles_name, roles_inherit) -); -``` - -Using the cache adapter: - -```php -// By default the action is deny access -$acl->setDefaultAction( - \Phalcon\Acl::DENY -); - -// You can add roles/resources/accesses to list or insert them directly in the tables - -// Add roles -$acl->addRole( - new \Phalcon\Acl\Role('Admins') -); - -// Create the resource with its accesses -$acl->addResource( - 'Products', - [ - 'insert', - 'update', - 'delete', - ] -); - -// Allow Admins to insert products -$acl->allow('Admin', 'Products', 'insert'); - -// Do Admins are allowed to insert Products? -var_dump( - $acl->isAllowed('Admins', 'Products', 'update') -); -``` diff --git a/Library/Phalcon/Acl/Adapter/Redis.php b/Library/Phalcon/Acl/Adapter/Redis.php deleted file mode 100644 index cf57cb1d8..000000000 --- a/Library/Phalcon/Acl/Adapter/Redis.php +++ /dev/null @@ -1,613 +0,0 @@ - | - | Eduar Carvajal | - +------------------------------------------------------------------------+ -*/ - -namespace Phalcon\Acl\Adapter; - -use Phalcon\Acl; -use Phalcon\Acl\Role; -use Phalcon\Acl\Adapter; -use Phalcon\Acl\Exception; -use Phalcon\Acl\Resource; -use Phalcon\Acl\RoleInterface; - -/** - * \Phalcon\Acl\Adapter\Redis - * - * Manages ACL lists in Redis Database - */ -class Redis extends Adapter -{ - /** - * @var bool - */ - protected $setNXAccess = true; - - /** - * @var \Redis - */ - protected $redis; - - /** - * Default action for no arguments is allow - * @var int - */ - protected $noArgumentsDefaultAction = Acl::ALLOW; - - public function __construct($redis = null) - { - $this->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 - * @throws \Phalcon\Acl\Exception - */ - public function addRole($role, $accessInherits = null) - { - if (is_string($role)) { - $role = new Role( - $role, - ucwords($role) . ' Role' - ); - } - - if (!$role instanceof RoleInterface) { - throw new Exception( - 'Role must be either an string or implement RoleInterface' - ); - } - - $this->redis->hMset( - 'roles', - [ - $role->getName() => $role->getDescription(), - ] - ); - - $this->redis->sAdd( - "accessList:$role:*:{$this->getDefaultAction()}}", - "*" - ); - - if ($accessInherits) { - $this->addInherit( - $role->getName(), - $accessInherits - ); - } - - return true; - } - - /** - * {@inheritdoc} - * - * Example: - * //Administrator implicitly inherits all descendants of 'consultor' unless explicity set in an Array - * $acl->addInherit('administrator', new Phalcon\Acl\Role('consultor')); - * $acl->addInherit('administrator', 'consultor'); - * $acl->addInherit('administrator', ['consultor', 'poweruser']); - * - * @param string $roleName - * @param \Phalcon\Acl\Role|string $roleToInherit - * @throws \Phalcon\Acl\Exception - */ - public function addInherit($roleName, $roleToInherit) - { - $exists = $this->redis->hGet('roles', $roleName); - - if (!$exists) { - throw new Exception( - sprintf("Role '%s' does not exist in the role list", $roleName) - ); - } - - if ($roleToInherit instanceof Role) { - $roleToInherit = $roleToInherit->getName(); - } - - /** - * Deep inherits Explicit tests array, Implicit recurs through inheritance chain - */ - if (is_array($roleToInherit)) { - foreach ($roleToInherit as $roleToInherit) { - $this->redis->sAdd("rolesInherits:$roleName", $roleToInherit); - } - - return true; - } - - if ($this->redis->exists("rolesInherits:$roleToInherit")) { - $deeperInherits = $this->redis->sGetMembers("rolesInherits:$roleToInherit"); - - foreach ($deeperInherits as $deeperInherit) { - $this->addInherit($roleName, $deeperInherit); - } - } - - $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'), ['create', 'search']); - * $acl->addResource('customers', ['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", - [ - $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 = []; - - foreach ($this->redis->hGetAll("resources") as $name => $desc) { - $resources[] = new Resource($name, $desc); - } - - return $resources; - } - - /** - * {@inheritdoc} - * - * @return RoleInterface[] - */ - public function getRoles() - { - $roles = []; - - 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( - [ - $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', ['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 - * @param mixed $func - */ - public function allow($role, $resource, $access, $func = null) - { - 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', ['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 - * @param mixed $func - */ - public function deny($role, $resource, $access, $func = null) - { - 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 - * @param array $parameters - * @return bool - */ - public function isAllowed($role, $resource, $access, array $parameters = null) - { - 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(); - } - - /** - * Returns the default ACL access level for no arguments provided - * in isAllowed action if there exists func for accessKey - * - * @return int - */ - public function getNoArgumentsDefaultAction() - { - return $this->noArgumentsDefaultAction; - } - - /** - * Sets the default access level for no arguments provided - * in isAllowed action if there exists func for accessKey - * - * @param int $defaultAccess Phalcon\Acl::ALLOW or Phalcon\Acl::DENY - */ - public function setNoArgumentsDefaultAction($defaultAccess) - { - $this->noArgumentsDefaultAction = intval($defaultAccess); - } - - /** - * @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 ([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/Acl/Factory/Memory.php b/Library/Phalcon/Acl/Factory/Memory.php deleted file mode 100644 index acf669a86..000000000 --- a/Library/Phalcon/Acl/Factory/Memory.php +++ /dev/null @@ -1,270 +0,0 @@ - | - +------------------------------------------------------------------------+ -*/ - -namespace Phalcon\Acl\Factory; - -use Phalcon\Config; -use Phalcon\Acl\Adapter\Memory as MemoryAdapter; -use Phalcon\Acl\Exception; -use Phalcon\Acl\Resource; -use Phalcon\Acl\Role; - -/** - * Class Memory - * - * This factory is intended to be used to ease setup of \Phalcon\Acl\Adapter\Memory - * in case \Phalcon\Config is used for configuration. - * - * @package Phalcon\Acl\Factory - */ -class Memory -{ - /** - * @var Config - */ - private $config; - - /** - * @var MemoryAdapter - */ - private $acl; - - /** - * Array of defined role objects. - * - * @var Role[] - */ - private $roles = []; - - /** - * Creates configured instance of acl. - * - * @param Config $config config - * @return MemoryAdapter acl - * @throws Exception If configuration is wrong - */ - public function create(Config $config) - { - $this->acl = new MemoryAdapter(); - $this->config = $config; - $defaultAction = $this->config->get('defaultAction'); - - if (!is_int($defaultAction) && !ctype_digit($defaultAction)) { - throw new Exception( - 'Key "defaultAction" must exist and must be of numeric value.' - ); - } - - $this->acl->setDefaultAction( - (int) $defaultAction - ); - - $this->addResources(); - $this->addRoles(); - - return $this->acl; - } - - /** - * Adds resources from config to acl object. - * - * @return $this - * @throws Exception - */ - protected function addResources() - { - if (!(array)$this->config->get('resource')) { - throw new Exception( - 'Key "resource" must exist and must be traversable.' - ); - } - - // resources - foreach ($this->config->get('resource') as $name => $resource) { - $actions = (array) $resource->get('actions'); - - if (!$actions) { - $actions = null; - } - - $this->acl->addResource( - $this->makeResource($name, $resource->description), - $actions - ); - } - - return $this; - } - - /** - * Adds role from config to acl object. - * - * @return $this - * @throws Exception - */ - protected function addRoles() - { - if (!(array) $this->config->get('role')) { - throw new Exception( - 'Key "role" must exist and must be traversable.' - ); - } - - foreach ($this->config->get('role') as $role => $rules) { - $this->roles[$role] = $this->makeRole( - $role, - $rules->get('description') - ); - - $this->addRole($role, $rules); - - $this->addAccessRulesToRole($role, $rules); - } - - return $this; - } - - /** - * Adds access rules to role. - * - * @param string $role role - * @param Config $rules rules - * - * @return $this - * - * @throws Exception - */ - protected function addAccessRulesToRole($role, Config $rules) - { - foreach ($rules as $method => $rules) { - // skip not wanted rules - if (in_array($method, ['inherit', 'description'])) { - continue; - } - - foreach ($rules as $controller => $actionRules) { - $actions = $this->castAction( - $actionRules->get('actions') - ); - - if (!in_array($method, ['allow', 'deny'])) { - throw new Exception( - sprintf( - 'Wrong access method given. Expected "allow" or "deny" but "%s" was set.', - $method - ) - ); - } - - $this->acl->{$method}($role, $controller, $actions); - } - } - - return $this; - } - - /** - * Cast actions - * - * @param mixed $actions Actions - * @return array|null - * @throws Exception - */ - protected function castAction($actions) - { - if ($actions instanceof Config) { - $actions = $actions->toArray(); - } elseif (is_string($actions)) { - $actions = [$actions]; - } - - if (!is_array($actions)) { - throw new Exception( - 'Key "actions" must exist and must be traversable.' - ); - } - - return $actions; - } - - /** - * Add role to acl. - * - * @param string $role role - * @param Config $rules rules - * - * @return $this - * - * @throws Exception - */ - protected function addRole($role, Config $rules) - { - // role has inheritance ? - if ($rules->get('inherit')) { - // role exists? - if (!array_key_exists($rules->inherit, $this->roles)) { - throw new Exception( - sprintf( - 'Role "%s" cannot inherit non-existent role "%s". - Either such role does not exist or it is set to be inherited before it is actually defined.', - $role, - $rules->inherit - ) - ); - } - - $this->acl->addRole( - $this->roles[$role], - $this->roles[$rules->inherit] - ); - } else { - $this->acl->addRole( - $this->roles[$role] - ); - } - - return $this; - } - - /** - * Creates acl resource. - * - * @param string $name Resource name - * @param string|null $description Resource description [Optional] - * - * @return Resource - */ - protected function makeResource($name, $description = null) - { - return new Resource($name, $description); - } - - /** - * Creates acl role. - * - * @param string $role Role name - * @param string|null $description Description [Optional] - * - * @return Role - */ - protected function makeRole($role, $description = null) - { - return new Role($role, $description); - } -} diff --git a/Library/Phalcon/Acl/Factory/README.md b/Library/Phalcon/Acl/Factory/README.md deleted file mode 100644 index 81f014dce..000000000 --- a/Library/Phalcon/Acl/Factory/README.md +++ /dev/null @@ -1,47 +0,0 @@ -# Phalcon\Acl\Factory - -## Phalcon\Acl\Factory\Memory - -This factory is intended to be used to ease setup of `\Phalcon\Acl\Adapter\Memory` -in case `\Phalcon\Config` or one of its adapters is used for configuration. - -To setup `acl` service in DI `service.php` file using `acl.ini` file: -(example of structure and options in ini file can be found in [tests/_fixtures/Acl/acl.ini](tests/_fixtures/Acl/acl.ini) - -```php -use Phalcon\Config\Adapter\Ini as ConfigIni; -use Phalcon\Acl\Factory\Memory as AclMemory; - -$di->setShared( - 'acl' - function () { - $config = new ConfigIni(APP_PATH . '/config/acl.ini'); - $factory = new AclMemory(); - - // returns instance of \Phalcon\Acl\Adapter\Memory - // note the [acl] section in ini file - return $factory->create( - $config->get('acl') - ); - } -); -``` - -To setup `acl` service in DI `service.php` file using `acl.php` (array) file: -(example of structure and options in ini file can be found in [tests/_fixtures/Acl/acl.php](tests/_fixtures/Acl/acl.php) - -```php -use Phalcon\Config; -use Phalcon\Acl\Factory\Memory as AclMemory; - -$di->setShared( - 'acl' - function () { - $config = new Config(APP_PATH . '/config/acl.php'); - $factory = new AclMemory(); - - // returns instance of \Phalcon\Acl\Adapter\Memory - return $factory->create($config); - } -); -``` diff --git a/composer.json b/composer.json index fd6040263..ea08e5f77 100644 --- a/composer.json +++ b/composer.json @@ -30,8 +30,9 @@ "email": "support@phalconphp.com" }, "require": { - "php": ">=5.5", - "ext-phalcon": "~3.3" + "php": ">=7.2", + "ext-phalcon": "^4.0", + "phalcon/incubator-acl": "^1.0.0-alpha.1" }, "require-dev": { "phpdocumentor/reflection-docblock": "2.0.4", diff --git a/composer.lock b/composer.lock new file mode 100644 index 000000000..b45f31723 --- /dev/null +++ b/composer.lock @@ -0,0 +1,2887 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "b6f69e31917ad3420c1f304cf35f1bf9", + "packages": [ + { + "name": "phalcon/incubator-acl", + "version": "v1.0.0-alpha.1", + "source": { + "type": "git", + "url": "https://github.com/phalcon/incubator-acl.git", + "reference": "33b4e184ef9c99d355c20eb983e85621015c6d3f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phalcon/incubator-acl/zipball/33b4e184ef9c99d355c20eb983e85621015c6d3f", + "reference": "33b4e184ef9c99d355c20eb983e85621015c6d3f", + "shasum": "" + }, + "require": { + "ext-phalcon": "^4.0", + "php": ">=7.2" + }, + "require-dev": { + "codeception/codeception": "^4.1", + "codeception/module-asserts": "^1.0.0", + "mongodb/mongodb": "^1.6", + "phalcon/ide-stubs": "^4.0", + "phpstan/phpstan": "^0.12.18", + "squizlabs/php_codesniffer": "3.5.1", + "vimeo/psalm": "3.6.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Phalcon\\Incubator\\Acl\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Phalcon Team", + "email": "team@phalcon.io", + "homepage": "https://phalcon.io/en/team" + }, + { + "name": "Contributors", + "homepage": "https://github.com/phalcon/incubator-acl/graphs/contributors" + } + ], + "description": "Phalcon Incubator Access Control List", + "homepage": "https://phalcon.io", + "keywords": [ + "acl", + "framework", + "incubator", + "phalcon" + ], + "time": "2020-04-13T22:00:37+00:00" + } + ], + "packages-dev": [ + { + "name": "behat/gherkin", + "version": "v4.6.2", + "source": { + "type": "git", + "url": "https://github.com/Behat/Gherkin.git", + "reference": "51ac4500c4dc30cbaaabcd2f25694299df666a31" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Behat/Gherkin/zipball/51ac4500c4dc30cbaaabcd2f25694299df666a31", + "reference": "51ac4500c4dc30cbaaabcd2f25694299df666a31", + "shasum": "" + }, + "require": { + "php": ">=5.3.1" + }, + "require-dev": { + "phpunit/phpunit": "~4.5|~5", + "symfony/phpunit-bridge": "~2.7|~3|~4", + "symfony/yaml": "~2.3|~3|~4" + }, + "suggest": { + "symfony/yaml": "If you want to parse features, represented in YAML files" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.4-dev" + } + }, + "autoload": { + "psr-0": { + "Behat\\Gherkin": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + } + ], + "description": "Gherkin DSL parser for PHP 5.3", + "homepage": "http://behat.org/", + "keywords": [ + "BDD", + "Behat", + "Cucumber", + "DSL", + "gherkin", + "parser" + ], + "time": "2020-03-17T14:03:26+00:00" + }, + { + "name": "codeception/aerospike-module", + "version": "v1.0.3", + "source": { + "type": "git", + "url": "https://github.com/Codeception/Aerospike-module.git", + "reference": "2c13bd3f981ecfa7486855546e3bfdea414bc5d6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Codeception/Aerospike-module/zipball/2c13bd3f981ecfa7486855546e3bfdea414bc5d6", + "reference": "2c13bd3f981ecfa7486855546e3bfdea414bc5d6", + "shasum": "" + }, + "require": { + "codeception/codeception": "^2 || ^3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Codeception\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Bodnarchuk", + "email": "davert@codeception.com" + }, + { + "name": "Serghei Iakovlev", + "email": "serghei@codeception.com" + } + ], + "description": "Aerospike Module for Codeception. Integrates Aerospike into Codeception tests.", + "homepage": "https://github.com/Codeception/Aerospike-module/releases", + "keywords": [ + "aerospike", + "codeception", + "nosql", + "testing" + ], + "time": "2019-07-25T16:10:30+00:00" + }, + { + "name": "codeception/codeception", + "version": "2.5.6", + "source": { + "type": "git", + "url": "https://github.com/Codeception/Codeception.git", + "reference": "b83a9338296e706fab2ceb49de8a352fbca3dc98" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Codeception/Codeception/zipball/b83a9338296e706fab2ceb49de8a352fbca3dc98", + "reference": "b83a9338296e706fab2ceb49de8a352fbca3dc98", + "shasum": "" + }, + "require": { + "behat/gherkin": "^4.4.0", + "codeception/phpunit-wrapper": "^6.0.9|^7.0.6", + "codeception/stub": "^2.0", + "ext-curl": "*", + "ext-json": "*", + "ext-mbstring": "*", + "facebook/webdriver": ">=1.1.3 <2.0", + "guzzlehttp/guzzle": ">=4.1.4 <7.0", + "guzzlehttp/psr7": "~1.0", + "php": ">=5.6.0 <8.0", + "symfony/browser-kit": ">=2.7 <5.0", + "symfony/console": ">=2.7 <5.0", + "symfony/css-selector": ">=2.7 <5.0", + "symfony/dom-crawler": ">=2.7 <5.0", + "symfony/event-dispatcher": ">=2.7 <5.0", + "symfony/finder": ">=2.7 <5.0", + "symfony/yaml": ">=2.7 <5.0" + }, + "require-dev": { + "codeception/specify": "~0.3", + "facebook/graph-sdk": "~5.3", + "flow/jsonpath": "~0.2", + "monolog/monolog": "~1.8", + "pda/pheanstalk": "~3.0", + "php-amqplib/php-amqplib": "~2.4", + "predis/predis": "^1.0", + "squizlabs/php_codesniffer": "~2.0", + "symfony/process": ">=2.7 <5.0", + "vlucas/phpdotenv": "^3.0" + }, + "suggest": { + "aws/aws-sdk-php": "For using AWS Auth in REST module and Queue module", + "codeception/phpbuiltinserver": "Start and stop PHP built-in web server for your tests", + "codeception/specify": "BDD-style code blocks", + "codeception/verify": "BDD-style assertions", + "flow/jsonpath": "For using JSONPath in REST module", + "league/factory-muffin": "For DataFactory module", + "league/factory-muffin-faker": "For Faker support in DataFactory module", + "phpseclib/phpseclib": "for SFTP option in FTP Module", + "stecman/symfony-console-completion": "For BASH autocompletion", + "symfony/phpunit-bridge": "For phpunit-bridge support" + }, + "bin": [ + "codecept" + ], + "type": "library", + "extra": { + "branch-alias": [] + }, + "autoload": { + "psr-4": { + "Codeception\\": "src/Codeception", + "Codeception\\Extension\\": "ext" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Bodnarchuk", + "email": "davert@mail.ua", + "homepage": "http://codegyre.com" + } + ], + "description": "BDD-style testing framework", + "homepage": "http://codeception.com/", + "keywords": [ + "BDD", + "TDD", + "acceptance testing", + "functional testing", + "unit testing" + ], + "time": "2019-04-24T11:28:19+00:00" + }, + { + "name": "codeception/mockery-module", + "version": "0.2.2", + "source": { + "type": "git", + "url": "https://github.com/Codeception/MockeryModule.git", + "reference": "ab1c965290f8ac78507c4da0a78b1111d3aebab2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Codeception/MockeryModule/zipball/ab1c965290f8ac78507c4da0a78b1111d3aebab2", + "reference": "ab1c965290f8ac78507c4da0a78b1111d3aebab2", + "shasum": "" + }, + "require": { + "mockery/mockery": "~0.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "Codeception\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Bodnarchuk", + "email": "davert.php@mailican.com" + }, + { + "name": "Jáchym Toušek", + "email": "enumag@gmail.com" + } + ], + "description": "Mockery Module for Codeception", + "time": "2015-09-24T19:28:29+00:00" + }, + { + "name": "codeception/phpunit-wrapper", + "version": "6.0.10", + "source": { + "type": "git", + "url": "https://github.com/Codeception/phpunit-wrapper.git", + "reference": "7057e599d97b02b4efb009681a43b327dbce138a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Codeception/phpunit-wrapper/zipball/7057e599d97b02b4efb009681a43b327dbce138a", + "reference": "7057e599d97b02b4efb009681a43b327dbce138a", + "shasum": "" + }, + "require": { + "phpunit/php-code-coverage": ">=2.2.4 <6.0", + "phpunit/phpunit": ">=4.8.28 <5.0.0 || >=5.6.3 <7.0", + "sebastian/comparator": ">1.1 <3.0", + "sebastian/diff": ">=1.4 <4.0" + }, + "replace": { + "codeception/phpunit-wrapper": "*" + }, + "require-dev": { + "codeception/specify": "*", + "vlucas/phpdotenv": "^2.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Codeception\\PHPUnit\\": "src\\" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Davert", + "email": "davert.php@resend.cc" + } + ], + "description": "PHPUnit classes used by Codeception", + "time": "2018-06-20T20:08:14+00:00" + }, + { + "name": "codeception/specify", + "version": "0.4.6", + "source": { + "type": "git", + "url": "https://github.com/Codeception/Specify.git", + "reference": "21b586f503ca444aa519dd9cafb32f113a05f286" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Codeception/Specify/zipball/21b586f503ca444aa519dd9cafb32f113a05f286", + "reference": "21b586f503ca444aa519dd9cafb32f113a05f286", + "shasum": "" + }, + "require": { + "myclabs/deep-copy": "~1.1", + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "autoload": { + "psr-0": { + "Codeception\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Bodnarchuk", + "email": "davert.php@mailican.com" + } + ], + "description": "BDD code blocks for PHPUnit and Codeception", + "time": "2016-10-21T09:42:00+00:00" + }, + { + "name": "codeception/stub", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/Codeception/Stub.git", + "reference": "f50bc271f392a2836ff80690ce0c058efe1ae03e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Codeception/Stub/zipball/f50bc271f392a2836ff80690ce0c058efe1ae03e", + "reference": "f50bc271f392a2836ff80690ce0c058efe1ae03e", + "shasum": "" + }, + "require": { + "phpunit/phpunit": ">=4.8 <8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Codeception\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Flexible Stub wrapper for PHPUnit's Mock Builder", + "time": "2018-07-26T11:55:37+00:00" + }, + { + "name": "codeception/verify", + "version": "0.3.3", + "source": { + "type": "git", + "url": "https://github.com/Codeception/Verify.git", + "reference": "5d649dda453cd814dadc4bb053060cd2c6bb4b4c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Codeception/Verify/zipball/5d649dda453cd814dadc4bb053060cd2c6bb4b4c", + "reference": "5d649dda453cd814dadc4bb053060cd2c6bb4b4c", + "shasum": "" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "autoload": { + "files": [ + "src/Codeception/function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Bodnarchuk", + "email": "davert.php@mailican.com" + } + ], + "description": "BDD assertion library for PHPUnit", + "time": "2017-01-09T10:58:51+00:00" + }, + { + "name": "doctrine/instantiator", + "version": "1.0.5", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", + "shasum": "" + }, + "require": { + "php": ">=5.3,<8.0-DEV" + }, + "require-dev": { + "athletic/athletic": "~0.1.8", + "ext-pdo": "*", + "ext-phar": "*", + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "~2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://github.com/doctrine/instantiator", + "keywords": [ + "constructor", + "instantiate" + ], + "time": "2015-06-14T21:17:01+00:00" + }, + { + "name": "facebook/webdriver", + "version": "1.7.1", + "source": { + "type": "git", + "url": "https://github.com/php-webdriver/php-webdriver-archive.git", + "reference": "e43de70f3c7166169d0f14a374505392734160e5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-webdriver/php-webdriver-archive/zipball/e43de70f3c7166169d0f14a374505392734160e5", + "reference": "e43de70f3c7166169d0f14a374505392734160e5", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "ext-json": "*", + "ext-mbstring": "*", + "ext-zip": "*", + "php": "^5.6 || ~7.0", + "symfony/process": "^2.8 || ^3.1 || ^4.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.0", + "jakub-onderka/php-parallel-lint": "^0.9.2", + "php-coveralls/php-coveralls": "^2.0", + "php-mock/php-mock-phpunit": "^1.1", + "phpunit/phpunit": "^5.7", + "sebastian/environment": "^1.3.4 || ^2.0 || ^3.0", + "squizlabs/php_codesniffer": "^2.6", + "symfony/var-dumper": "^3.3 || ^4.0" + }, + "suggest": { + "ext-SimpleXML": "For Firefox profile creation" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-community": "1.5-dev" + } + }, + "autoload": { + "psr-4": { + "Facebook\\WebDriver\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "description": "A PHP client for Selenium WebDriver", + "homepage": "https://github.com/facebook/php-webdriver", + "keywords": [ + "facebook", + "php", + "selenium", + "webdriver" + ], + "abandoned": "php-webdriver/webdriver", + "time": "2019-06-13T08:02:18+00:00" + }, + { + "name": "guzzlehttp/guzzle", + "version": "6.5.2", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "43ece0e75098b7ecd8d13918293029e555a50f82" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/43ece0e75098b7ecd8d13918293029e555a50f82", + "reference": "43ece0e75098b7ecd8d13918293029e555a50f82", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/promises": "^1.0", + "guzzlehttp/psr7": "^1.6.1", + "php": ">=5.5" + }, + "require-dev": { + "ext-curl": "*", + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0", + "psr/log": "^1.1" + }, + "suggest": { + "ext-intl": "Required for Internationalized Domain Name (IDN) support", + "psr/log": "Required for using the Log middleware" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.5-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle is a PHP HTTP client library", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "rest", + "web service" + ], + "time": "2019-12-23T11:57:10+00:00" + }, + { + "name": "guzzlehttp/promises", + "version": "v1.3.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646", + "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646", + "shasum": "" + }, + "require": { + "php": ">=5.5.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "time": "2016-12-20T10:07:11+00:00" + }, + { + "name": "guzzlehttp/psr7", + "version": "1.6.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "239400de7a173fe9901b9ac7c06497751f00727a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/239400de7a173fe9901b9ac7c06497751f00727a", + "reference": "239400de7a173fe9901b9ac7c06497751f00727a", + "shasum": "" + }, + "require": { + "php": ">=5.4.0", + "psr/http-message": "~1.0", + "ralouphie/getallheaders": "^2.0.5 || ^3.0.0" + }, + "provide": { + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "ext-zlib": "*", + "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.8" + }, + "suggest": { + "zendframework/zend-httphandlerrunner": "Emit PSR-7 responses" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.6-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Schultze", + "homepage": "https://github.com/Tobion" + } + ], + "description": "PSR-7 message implementation that also provides common utility methods", + "keywords": [ + "http", + "message", + "psr-7", + "request", + "response", + "stream", + "uri", + "url" + ], + "time": "2019-07-01T23:21:34+00:00" + }, + { + "name": "hamcrest/hamcrest-php", + "version": "v1.2.2", + "source": { + "type": "git", + "url": "https://github.com/hamcrest/hamcrest-php.git", + "reference": "b37020aa976fa52d3de9aa904aa2522dc518f79c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/b37020aa976fa52d3de9aa904aa2522dc518f79c", + "reference": "b37020aa976fa52d3de9aa904aa2522dc518f79c", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "replace": { + "cordoval/hamcrest-php": "*", + "davedevelopment/hamcrest-php": "*", + "kodova/hamcrest-php": "*" + }, + "require-dev": { + "phpunit/php-file-iterator": "1.3.3", + "satooshi/php-coveralls": "dev-master" + }, + "type": "library", + "autoload": { + "classmap": [ + "hamcrest" + ], + "files": [ + "hamcrest/Hamcrest.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD" + ], + "description": "This is the PHP port of Hamcrest Matchers", + "keywords": [ + "test" + ], + "time": "2015-05-11T14:41:42+00:00" + }, + { + "name": "mockery/mockery", + "version": "0.9.11", + "source": { + "type": "git", + "url": "https://github.com/mockery/mockery.git", + "reference": "be9bf28d8e57d67883cba9fcadfcff8caab667f8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mockery/mockery/zipball/be9bf28d8e57d67883cba9fcadfcff8caab667f8", + "reference": "be9bf28d8e57d67883cba9fcadfcff8caab667f8", + "shasum": "" + }, + "require": { + "hamcrest/hamcrest-php": "~1.1", + "lib-pcre": ">=7.0", + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.9.x-dev" + } + }, + "autoload": { + "psr-0": { + "Mockery": "library/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Pádraic Brady", + "email": "padraic.brady@gmail.com", + "homepage": "http://blog.astrumfutura.com" + }, + { + "name": "Dave Marshall", + "email": "dave.marshall@atstsolutions.co.uk", + "homepage": "http://davedevelopment.co.uk" + } + ], + "description": "Mockery is a simple yet flexible PHP mock object framework for use in unit testing with PHPUnit, PHPSpec or any other testing framework. Its core goal is to offer a test double framework with a succinct API capable of clearly defining all possible object operations and interactions using a human readable Domain Specific Language (DSL). Designed as a drop in alternative to PHPUnit's phpunit-mock-objects library, Mockery is easy to integrate with PHPUnit and can operate alongside phpunit-mock-objects without the World ending.", + "homepage": "http://github.com/padraic/mockery", + "keywords": [ + "BDD", + "TDD", + "library", + "mock", + "mock objects", + "mockery", + "stub", + "test", + "test double", + "testing" + ], + "time": "2019-02-12T16:07:13+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.9.5", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "b2c28789e80a97badd14145fda39b545d83ca3ef" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/b2c28789e80a97badd14145fda39b545d83ca3ef", + "reference": "b2c28789e80a97badd14145fda39b545d83ca3ef", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "replace": { + "myclabs/deep-copy": "self.version" + }, + "require-dev": { + "doctrine/collections": "^1.0", + "doctrine/common": "^2.6", + "phpunit/phpunit": "^7.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + }, + "files": [ + "src/DeepCopy/deep_copy.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "time": "2020-01-17T21:11:47+00:00" + }, + { + "name": "phalcon/dd", + "version": "v1.1.3", + "source": { + "type": "git", + "url": "https://github.com/phalcon/dd.git", + "reference": "71a05c4f8d4b4216638f61d0c0be312799b0ab08" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phalcon/dd/zipball/71a05c4f8d4b4216638f61d0c0be312799b0ab08", + "reference": "71a05c4f8d4b4216638f61d0c0be312799b0ab08", + "shasum": "" + }, + "require": { + "ext-phalcon": "^3.0 || ^4.0", + "php": "^5.4 || ^7.0" + }, + "type": "library", + "autoload": { + "files": [ + "src/helper.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Phalcon Team", + "email": "team@phalconphp.com", + "homepage": "http://phalconphp.com/en/team" + }, + { + "name": "Contributors", + "homepage": "https://github.com/phalcon/dd/graphs/contributors" + } + ], + "description": "This package will add the `dd` and `dump` helpers to your Phalcon application.", + "homepage": "https://github.com/phalcon/dd", + "keywords": [ + "VarDumper", + "dd", + "debug", + "dump", + "phalcon", + "utils" + ], + "time": "2019-07-26T05:29:31+00:00" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d68dbdc53dc358a816f00b300704702b2eaff7b8", + "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "suggest": { + "dflydev/markdown": "~1.0", + "erusev/parsedown": "~1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "phpDocumentor": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "mike.vanriel@naenius.com" + } + ], + "time": "2015-02-03T12:10:50+00:00" + }, + { + "name": "phpspec/prophecy", + "version": "v1.10.3", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "451c3cd1418cf640de218914901e51b064abb093" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/451c3cd1418cf640de218914901e51b064abb093", + "reference": "451c3cd1418cf640de218914901e51b064abb093", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "php": "^5.3|^7.0", + "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0|^5.0", + "sebastian/comparator": "^1.2.3|^2.0|^3.0|^4.0", + "sebastian/recursion-context": "^1.0|^2.0|^3.0|^4.0" + }, + "require-dev": { + "phpspec/phpspec": "^2.5 || ^3.2", + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.10.x-dev" + } + }, + "autoload": { + "psr-4": { + "Prophecy\\": "src/Prophecy" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "https://github.com/phpspec/prophecy", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ], + "time": "2020-03-05T15:02:03+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "2.2.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979", + "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "phpunit/php-file-iterator": "~1.3", + "phpunit/php-text-template": "~1.2", + "phpunit/php-token-stream": "~1.3", + "sebastian/environment": "^1.3.2", + "sebastian/version": "~1.0" + }, + "require-dev": { + "ext-xdebug": ">=2.1.4", + "phpunit/phpunit": "~4" + }, + "suggest": { + "ext-dom": "*", + "ext-xdebug": ">=2.2.1", + "ext-xmlwriter": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "time": "2015-10-06T15:47:00+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "1.4.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4", + "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "time": "2017-11-27T13:52:08+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "time": "2015-06-21T13:50:34+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "1.0.9", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", + "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "time": "2017-02-26T11:10:40+00:00" + }, + { + "name": "phpunit/php-token-stream", + "version": "1.4.12", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "1ce90ba27c42e4e44e6d8458241466380b51fa16" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/1ce90ba27c42e4e44e6d8458241466380b51fa16", + "reference": "1ce90ba27c42e4e44e6d8458241466380b51fa16", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Wrapper around PHP's tokenizer extension.", + "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "keywords": [ + "tokenizer" + ], + "time": "2017-12-04T08:55:13+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "4.8.36", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "46023de9a91eec7dfb06cc56cb4e260017298517" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/46023de9a91eec7dfb06cc56cb4e260017298517", + "reference": "46023de9a91eec7dfb06cc56cb4e260017298517", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-pcre": "*", + "ext-reflection": "*", + "ext-spl": "*", + "php": ">=5.3.3", + "phpspec/prophecy": "^1.3.1", + "phpunit/php-code-coverage": "~2.1", + "phpunit/php-file-iterator": "~1.4", + "phpunit/php-text-template": "~1.2", + "phpunit/php-timer": "^1.0.6", + "phpunit/phpunit-mock-objects": "~2.3", + "sebastian/comparator": "~1.2.2", + "sebastian/diff": "~1.2", + "sebastian/environment": "~1.3", + "sebastian/exporter": "~1.2", + "sebastian/global-state": "~1.0", + "sebastian/version": "~1.0", + "symfony/yaml": "~2.1|~3.0" + }, + "suggest": { + "phpunit/php-invoker": "~1.1" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.8.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "time": "2017-06-21T08:07:12+00:00" + }, + { + "name": "phpunit/phpunit-mock-objects", + "version": "2.3.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", + "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983", + "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "php": ">=5.3.3", + "phpunit/php-text-template": "~1.2", + "sebastian/exporter": "~1.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "suggest": { + "ext-soap": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.3.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Mock Object library for PHPUnit", + "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", + "keywords": [ + "mock", + "xunit" + ], + "abandoned": true, + "time": "2015-10-02T06:51:40+00:00" + }, + { + "name": "psr/container", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "time": "2017-02-14T16:28:37+00:00" + }, + { + "name": "psr/http-message", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "time": "2016-08-06T14:39:51+00:00" + }, + { + "name": "ralouphie/getallheaders", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "120b605dfeb996808c31b6477290a714d356e822" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", + "reference": "120b605dfeb996808c31b6477290a714d356e822", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^5 || ^6.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/getallheaders.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" + } + ], + "description": "A polyfill for getallheaders.", + "time": "2019-03-08T08:55:37+00:00" + }, + { + "name": "sebastian/comparator", + "version": "1.2.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", + "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "sebastian/diff": "~1.2", + "sebastian/exporter": "~1.2 || ~2.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "http://www.github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "time": "2017-01-29T09:50:25+00:00" + }, + { + "name": "sebastian/diff", + "version": "1.4.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7f066a26a962dbe58ddea9f72a4e82874a3975a4", + "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff" + ], + "time": "2017-05-22T07:24:03+00:00" + }, + { + "name": "sebastian/environment", + "version": "1.3.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/be2c607e43ce4c89ecd60e75c6a85c126e754aea", + "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8 || ^5.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "time": "2016-08-18T05:49:44+00:00" + }, + { + "name": "sebastian/exporter", + "version": "1.2.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/42c4c2eec485ee3e159ec9884f95b431287edde4", + "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "sebastian/recursion-context": "~1.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "http://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "time": "2016-06-17T09:04:28+00:00" + }, + { + "name": "sebastian/global-state", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4", + "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "time": "2015-10-12T03:26:01+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "1.0.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/b19cc3298482a335a95f3016d2f8a6950f0fbcd7", + "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "time": "2016-10-03T07:41:43+00:00" + }, + { + "name": "sebastian/version", + "version": "1.0.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", + "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", + "shasum": "" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "time": "2015-06-21T13:59:46+00:00" + }, + { + "name": "squizlabs/php_codesniffer", + "version": "2.9.2", + "source": { + "type": "git", + "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", + "reference": "2acf168de78487db620ab4bc524135a13cfe6745" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/2acf168de78487db620ab4bc524135a13cfe6745", + "reference": "2acf168de78487db620ab4bc524135a13cfe6745", + "shasum": "" + }, + "require": { + "ext-simplexml": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": ">=5.1.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "bin": [ + "scripts/phpcs", + "scripts/phpcbf" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "classmap": [ + "CodeSniffer.php", + "CodeSniffer/CLI.php", + "CodeSniffer/Exception.php", + "CodeSniffer/File.php", + "CodeSniffer/Fixer.php", + "CodeSniffer/Report.php", + "CodeSniffer/Reporting.php", + "CodeSniffer/Sniff.php", + "CodeSniffer/Tokens.php", + "CodeSniffer/Reports/", + "CodeSniffer/Tokenizers/", + "CodeSniffer/DocGenerators/", + "CodeSniffer/Standards/AbstractPatternSniff.php", + "CodeSniffer/Standards/AbstractScopeSniff.php", + "CodeSniffer/Standards/AbstractVariableSniff.php", + "CodeSniffer/Standards/IncorrectPatternException.php", + "CodeSniffer/Standards/Generic/Sniffs/", + "CodeSniffer/Standards/MySource/Sniffs/", + "CodeSniffer/Standards/PEAR/Sniffs/", + "CodeSniffer/Standards/PSR1/Sniffs/", + "CodeSniffer/Standards/PSR2/Sniffs/", + "CodeSniffer/Standards/Squiz/Sniffs/", + "CodeSniffer/Standards/Zend/Sniffs/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Greg Sherwood", + "role": "lead" + } + ], + "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", + "homepage": "http://www.squizlabs.com/php-codesniffer", + "keywords": [ + "phpcs", + "standards" + ], + "time": "2018-11-07T22:31:41+00:00" + }, + { + "name": "symfony/browser-kit", + "version": "v4.4.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/browser-kit.git", + "reference": "e4b0dc1b100bf75b5717c5b451397f230a618a42" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/browser-kit/zipball/e4b0dc1b100bf75b5717c5b451397f230a618a42", + "reference": "e4b0dc1b100bf75b5717c5b451397f230a618a42", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "symfony/dom-crawler": "^3.4|^4.0|^5.0" + }, + "require-dev": { + "symfony/css-selector": "^3.4|^4.0|^5.0", + "symfony/http-client": "^4.3|^5.0", + "symfony/mime": "^4.3|^5.0", + "symfony/process": "^3.4|^4.0|^5.0" + }, + "suggest": { + "symfony/process": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\BrowserKit\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony BrowserKit Component", + "homepage": "https://symfony.com", + "time": "2020-03-28T10:15:50+00:00" + }, + { + "name": "symfony/console", + "version": "v4.4.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "10bb3ee3c97308869d53b3e3d03f6ac23ff985f7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/10bb3ee3c97308869d53b3e3d03f6ac23ff985f7", + "reference": "10bb3ee3c97308869d53b3e3d03f6ac23ff985f7", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/polyfill-php73": "^1.8", + "symfony/service-contracts": "^1.1|^2" + }, + "conflict": { + "symfony/dependency-injection": "<3.4", + "symfony/event-dispatcher": "<4.3|>=5", + "symfony/lock": "<4.4", + "symfony/process": "<3.3" + }, + "provide": { + "psr/log-implementation": "1.0" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "^3.4|^4.0|^5.0", + "symfony/dependency-injection": "^3.4|^4.0|^5.0", + "symfony/event-dispatcher": "^4.3", + "symfony/lock": "^4.4|^5.0", + "symfony/process": "^3.4|^4.0|^5.0", + "symfony/var-dumper": "^4.3|^5.0" + }, + "suggest": { + "psr/log": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/lock": "", + "symfony/process": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Console Component", + "homepage": "https://symfony.com", + "time": "2020-03-30T11:41:10+00:00" + }, + { + "name": "symfony/css-selector", + "version": "v4.4.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/css-selector.git", + "reference": "afc26133a6fbdd4f8842e38893e0ee4685c7c94b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/afc26133a6fbdd4f8842e38893e0ee4685c7c94b", + "reference": "afc26133a6fbdd4f8842e38893e0ee4685c7c94b", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\CssSelector\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Jean-François Simon", + "email": "jeanfrancois.simon@sensiolabs.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony CssSelector Component", + "homepage": "https://symfony.com", + "time": "2020-03-27T16:54:36+00:00" + }, + { + "name": "symfony/dom-crawler", + "version": "v4.4.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/dom-crawler.git", + "reference": "4d0fb3374324071ecdd94898367a3fa4b5563162" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/4d0fb3374324071ecdd94898367a3fa4b5563162", + "reference": "4d0fb3374324071ecdd94898367a3fa4b5563162", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "masterminds/html5": "<2.6" + }, + "require-dev": { + "masterminds/html5": "^2.6", + "symfony/css-selector": "^3.4|^4.0|^5.0" + }, + "suggest": { + "symfony/css-selector": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\DomCrawler\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony DomCrawler Component", + "homepage": "https://symfony.com", + "time": "2020-03-29T19:12:22+00:00" + }, + { + "name": "symfony/event-dispatcher", + "version": "v4.4.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "abc8e3618bfdb55e44c8c6a00abd333f831bbfed" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/abc8e3618bfdb55e44c8c6a00abd333f831bbfed", + "reference": "abc8e3618bfdb55e44c8c6a00abd333f831bbfed", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "symfony/event-dispatcher-contracts": "^1.1" + }, + "conflict": { + "symfony/dependency-injection": "<3.4" + }, + "provide": { + "psr/event-dispatcher-implementation": "1.0", + "symfony/event-dispatcher-implementation": "1.1" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "^3.4|^4.0|^5.0", + "symfony/dependency-injection": "^3.4|^4.0|^5.0", + "symfony/expression-language": "^3.4|^4.0|^5.0", + "symfony/http-foundation": "^3.4|^4.0|^5.0", + "symfony/service-contracts": "^1.1|^2", + "symfony/stopwatch": "^3.4|^4.0|^5.0" + }, + "suggest": { + "symfony/dependency-injection": "", + "symfony/http-kernel": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony EventDispatcher Component", + "homepage": "https://symfony.com", + "time": "2020-03-27T16:54:36+00:00" + }, + { + "name": "symfony/event-dispatcher-contracts", + "version": "v1.1.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher-contracts.git", + "reference": "c43ab685673fb6c8d84220c77897b1d6cdbe1d18" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/c43ab685673fb6c8d84220c77897b1d6cdbe1d18", + "reference": "c43ab685673fb6c8d84220c77897b1d6cdbe1d18", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "suggest": { + "psr/event-dispatcher": "", + "symfony/event-dispatcher-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\EventDispatcher\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to dispatching event", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "time": "2019-09-17T09:54:03+00:00" + }, + { + "name": "symfony/finder", + "version": "v4.4.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "5729f943f9854c5781984ed4907bbb817735776b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/5729f943f9854c5781984ed4907bbb817735776b", + "reference": "5729f943f9854c5781984ed4907bbb817735776b", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Finder Component", + "homepage": "https://symfony.com", + "time": "2020-03-27T16:54:36+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.15.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "4719fa9c18b0464d399f1a63bf624b42b6fa8d14" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/4719fa9c18b0464d399f1a63bf624b42b6fa8d14", + "reference": "4719fa9c18b0464d399f1a63bf624b42b6fa8d14", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.15-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "time": "2020-02-27T09:26:54+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.15.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "81ffd3a9c6d707be22e3012b827de1c9775fc5ac" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/81ffd3a9c6d707be22e3012b827de1c9775fc5ac", + "reference": "81ffd3a9c6d707be22e3012b827de1c9775fc5ac", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.15-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "time": "2020-03-09T19:04:49+00:00" + }, + { + "name": "symfony/polyfill-php73", + "version": "v1.15.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php73.git", + "reference": "0f27e9f464ea3da33cbe7ca3bdf4eb66def9d0f7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/0f27e9f464ea3da33cbe7ca3bdf4eb66def9d0f7", + "reference": "0f27e9f464ea3da33cbe7ca3bdf4eb66def9d0f7", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.15-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php73\\": "" + }, + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "time": "2020-02-27T09:26:54+00:00" + }, + { + "name": "symfony/process", + "version": "v4.4.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "3e40e87a20eaf83a1db825e1fa5097ae89042db3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/3e40e87a20eaf83a1db825e1fa5097ae89042db3", + "reference": "3e40e87a20eaf83a1db825e1fa5097ae89042db3", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Process Component", + "homepage": "https://symfony.com", + "time": "2020-03-27T16:54:36+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "v2.0.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "144c5e51266b281231e947b51223ba14acf1a749" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/144c5e51266b281231e947b51223ba14acf1a749", + "reference": "144c5e51266b281231e947b51223ba14acf1a749", + "shasum": "" + }, + "require": { + "php": "^7.2.5", + "psr/container": "^1.0" + }, + "suggest": { + "symfony/service-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "time": "2019-11-18T17:27:11+00:00" + }, + { + "name": "symfony/yaml", + "version": "v3.4.39", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "e701b47e11749970f63803879c4febb520f07b6c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/e701b47e11749970f63803879c4febb520f07b6c", + "reference": "e701b47e11749970f63803879c4febb520f07b6c", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "symfony/polyfill-ctype": "~1.8" + }, + "conflict": { + "symfony/console": "<3.4" + }, + "require-dev": { + "symfony/console": "~3.4|~4.0" + }, + "suggest": { + "symfony/console": "For validating YAML files using the lint command" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Yaml Component", + "homepage": "https://symfony.com", + "time": "2020-03-25T12:02:26+00:00" + }, + { + "name": "vlucas/phpdotenv", + "version": "v2.6.3", + "source": { + "type": "git", + "url": "https://github.com/vlucas/phpdotenv.git", + "reference": "df4c4d08a639be4ef5d6d1322868f9e477553679" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/df4c4d08a639be4ef5d6d1322868f9e477553679", + "reference": "df4c4d08a639be4ef5d6d1322868f9e477553679", + "shasum": "" + }, + "require": { + "php": ">=5.3.9", + "symfony/polyfill-ctype": "^1.9" + }, + "require-dev": { + "ext-filter": "*", + "ext-pcre": "*", + "phpunit/phpunit": "^4.8.35 || ^5.0" + }, + "suggest": { + "ext-filter": "Required to use the boolean validator.", + "ext-pcre": "Required to use most of the library." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.6-dev" + } + }, + "autoload": { + "psr-4": { + "Dotenv\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Vance Lucas", + "email": "vance@vancelucas.com", + "homepage": "http://www.vancelucas.com" + } + ], + "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.", + "keywords": [ + "dotenv", + "env", + "environment" + ], + "time": "2020-04-12T15:11:38+00:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": { + "phalcon/incubator-acl": 15 + }, + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": ">=7.2", + "ext-phalcon": "^4.0" + }, + "platform-dev": [] +} diff --git a/tests/unit/Acl/Adapter/DatabaseTest.php b/tests/unit/Acl/Adapter/DatabaseTest.php deleted file mode 100644 index 1f28a883b..000000000 --- a/tests/unit/Acl/Adapter/DatabaseTest.php +++ /dev/null @@ -1,159 +0,0 @@ - - * @package Phalcon\Test\Acl\Adapter - * @group Acl - * - * The contents of this file are subject to the New BSD License that is - * bundled with this package in the file docs/LICENSE.txt - * - * If you did not receive a copy of the license and are unable to obtain it - * through the world-wide-web, please send an email to license@phalconphp.com - * so that we can send you a copy immediately. - */ -class DatabaseTest extends Test -{ - const ADAPTER_CLASS = Database::class; - - protected function getConnection() - { - return new Sqlite( - [ - 'dbname' => 'tests/_output/sample.db', - ] - ); - } - - protected function assertProtectedPropertyEquals($propertyName, $tableName, DbAdapter $connection, Database $adapter) - { - $property = new ReflectionProperty( - self::ADAPTER_CLASS, - $propertyName - ); - - $property->setAccessible(true); - - $this->assertEquals( - $connection->escapeIdentifier($tableName), - $property->getValue($adapter) - ); - } - - /** - * @param array $options - * - * @dataProvider incorrectDbProvider - * @expectedException \Phalcon\Acl\Exception - * @expectedExceptionMessage Parameter "db" is required and it must be an instance of Phalcon\Acl\AdapterInterface - */ - public function testShouldThrowExceptionIfDbIsMissingOrInvalid($options) - { - new Database($options); - } - - public function incorrectDbProvider() - { - return [ - [['abc' => '']], - [['db' => null]], - [['db' => true]], - [['db' => __CLASS__]], - [['db' => new \stdClass()]], - [['db' => []]], - [['db' => microtime(true)]], - [['db' => PHP_INT_MAX]], - ]; - } - - /** - * @param string $expected - * @param array $options - * - * @dataProvider incorrectOptionsProvider - */ - public function testShouldThrowExceptionWhenOptionsIsInvalid($expected, $options) - { - $this->tester->setExpectedException( - '\Phalcon\Acl\Exception', - "Parameter '{$expected}' is required and it must be a non empty string" - ); - - new Database($options); - } - - public function incorrectOptionsProvider() - { - return [ - ['roles', ['db' => $this->getConnection()]], - ['roles', ['db' => $this->getConnection(), 'roles' => '']], - ['roles', ['db' => $this->getConnection(), 'roles' => true]], - ['roles', ['db' => $this->getConnection(), 'roles' => []]], - - ['resources', ['db' => $this->getConnection(), 'roles' => 'roles']], - ['resources', ['db' => $this->getConnection(), 'roles' => 'roles', 'resources' => '']], - ['resources', ['db' => $this->getConnection(), 'roles' => 'roles', 'resources' => true]], - ['resources', ['db' => $this->getConnection(), 'roles' => 'roles', 'resources' => []]], - - ['resourcesAccesses', ['db' => $this->getConnection(), 'roles' => 'roles', 'resources' => 'resources']], - ['resourcesAccesses', ['db' => $this->getConnection(), 'roles' => 'roles', 'resources' => 'resources', 'resourcesAccesses' => '']], - ['resourcesAccesses', ['db' => $this->getConnection(), 'roles' => 'roles', 'resources' => 'resources', 'resourcesAccesses' => true]], - ['resourcesAccesses', ['db' => $this->getConnection(), 'roles' => 'roles', 'resources' => 'resources', 'resourcesAccesses' => []]], - - ['accessList', ['db' => $this->getConnection(), 'roles' => 'roles', 'resources' => 'resources', 'resourcesAccesses' => 'resources_accesses']], - ['accessList', ['db' => $this->getConnection(), 'roles' => 'roles', 'resources' => 'resources', 'resourcesAccesses' => 'resources_accesses', 'accessList' => '']], - ['accessList', ['db' => $this->getConnection(), 'roles' => 'roles', 'resources' => 'resources', 'resourcesAccesses' => 'resources_accesses', 'accessList' => true]], - ['accessList', ['db' => $this->getConnection(), 'roles' => 'roles', 'resources' => 'resources', 'resourcesAccesses' => 'resources_accesses', 'accessList' => []]], - - ['rolesInherits', ['db' => $this->getConnection(), 'roles' => 'roles', 'resources' => 'resources', 'resourcesAccesses' => 'resources_accesses', 'accessList' => 'access_list']], - ['rolesInherits', ['db' => $this->getConnection(), 'roles' => 'roles', 'resources' => 'resources', 'resourcesAccesses' => 'resources_accesses', 'accessList' => 'access_list', 'rolesInherits' => '']], - ['rolesInherits', ['db' => $this->getConnection(), 'roles' => 'roles', 'resources' => 'resources', 'resourcesAccesses' => 'resources_accesses', 'accessList' => 'access_list', 'rolesInherits' => true]], - ['rolesInherits', ['db' => $this->getConnection(), 'roles' => 'roles', 'resources' => 'resources', 'resourcesAccesses' => 'resources_accesses', 'accessList' => 'access_list', 'rolesInherits' => []]], - ]; - } - - public function testShouldCreateAdapterInstance() - { - $connection = $this->getConnection(); - - $options = [ - 'db' => $connection, - 'roles' => 'roles', - 'rolesInherits' => 'roles_inherits', - 'resources' => 'resources', - 'resourcesAccesses' => 'resources_accesses', - 'accessList' => 'access_list', - ]; - - $adapter = new Database($options); - - $this->assertInstanceOf( - self::ADAPTER_CLASS, - $adapter - ); - - unset($options['db']); - - foreach ($options as $property => $tableName) { - $this->assertProtectedPropertyEquals( - $property, - $tableName, - $connection, - $adapter - ); - } - } -} diff --git a/tests/unit/Acl/Factory/MemoryTest.php b/tests/unit/Acl/Factory/MemoryTest.php deleted file mode 100644 index 048b84b96..000000000 --- a/tests/unit/Acl/Factory/MemoryTest.php +++ /dev/null @@ -1,338 +0,0 @@ - - * @package Phalcon\Test\Acl\Factory - * @group Acl - * - * The contents of this file are subject to the New BSD License that is - * bundled with this package in the file docs/LICENSE.txt - * - * If you did not receive a copy of the license and are unable to obtain it - * through the world-wide-web, please send an email to license@phalconphp.com - * so that we can send you a copy immediately. - */ -class MemoryTest extends Test -{ - public function testFactoryShouldCreateMemoryAclObjectFromAclConfigurationWithAllOptions() - { - $config = new Ini( - INCUBATOR_FIXTURES . 'Acl/acl.ini' - ); - - $factory = new MemoryFactory(); - - $acl = $factory->create( - $config->get('acl') - ); - - $this->assertInstanceOf( - MemoryAdapter::class, - $acl - ); - - $this->assertAclIsConfiguredAsExpected($acl, $config); - } - - public function testFactoryShouldWorkIfCreatedFromConfigPHPArray() - { - $config = new Config( - include INCUBATOR_FIXTURES . 'Acl/acl.php' - ); - - $factory = new MemoryFactory(); - - $acl = $factory->create( - $config->get('acl') - ); - - $this->assertInstanceOf( - MemoryAdapter::class, - $acl - ); - - $this->assertAclIsConfiguredAsExpected($acl, $config); - } - - /** - * @expectedException \Phalcon\Acl\Exception - * @expectedExceptionMessage Key "defaultAction" must exist and must be of numeric value. - */ - public function testFactoryShouldThrowExceptionIfDefaultActionIsMissing() - { - $config = new Ini( - INCUBATOR_FIXTURES . 'Acl/acl.ini' - ); - - unset($config->acl->defaultAction); - - $factory = new MemoryFactory(); - - $factory->create( - $config->get('acl') - ); - } - - /** - * @expectedException \Phalcon\Acl\Exception - * @expectedExceptionMessage Key "resource" must exist and must be traversable. - */ - public function testFactoryShouldThrowExceptionIfResourceOptionIsMissing() - { - $config = new Ini( - INCUBATOR_FIXTURES . 'Acl/acl.ini' - ); - - unset($config->acl->resource); - - $factory = new MemoryFactory(); - - $factory->create( - $config->get('acl') - ); - } - - /** - * @expectedException \Phalcon\Acl\Exception - * @expectedExceptionMessage Invalid value for accessList - */ - public function testFactoryShouldThrowExceptionIfActionsKeyIsMissing() - { - $config = new Ini( - INCUBATOR_FIXTURES . 'Acl/acl.ini' - ); - - unset( - $config->acl->resource->index->actions - ); - - unset( - $config->acl->role->guest->allow->index->actions[0] - ); - - $factory = new MemoryFactory(); - - $factory->create( - $config->get('acl') - ); - } - - /** - * @expectedException \Phalcon\Acl\Exception - * @expectedExceptionMessage Key "role" must exist and must be traversable. - */ - public function testFactoryShouldThrowExceptionIfRoleKeyIsMissing() - { - $config = new Ini( - INCUBATOR_FIXTURES . 'Acl/acl.ini' - ); - - unset($config->acl->role); - - $factory = new MemoryFactory(); - - $factory->create( - $config->get('acl') - ); - } - - /** - * @expectedException \Phalcon\Acl\Exception - * @expectedExceptionMessage Wrong access method given. Expected "allow" or "deny" but "wrongmethod" was set. - */ - public function testFactoryShouldThrowExceptionIfWrongMethodIsSet() - { - $config = new Ini( - INCUBATOR_FIXTURES . 'Acl/acl.ini' - ); - - $config->acl->role->user->wrongmethod = new Config( - [ - 'test' => [ - 'actions' => [ - 'test', - ], - ], - ] - ); - - $factory = new MemoryFactory(); - - $factory->create( - $config->get('acl') - ); - } - - /** - * @dataProvider invalidActionProvider - * - * @expectedException \Phalcon\Acl\Exception - * @expectedExceptionMessage Key "actions" must exist and must be traversable. - * - * @param mixed $action - */ - public function testFactoryShouldThrowExceptionIfWrongNoActionIsSet($action) - { - $config = new Ini( - INCUBATOR_FIXTURES . 'Acl/acl.ini' - ); - - $config->acl->role->user->wrongmethod = new Config( - [ - 'test' => [ - 'actions' => $action, - ], - ] - ); - - $factory = new MemoryFactory(); - - $factory->create( - $config->get('acl') - ); - } - - public function invalidActionProvider() - { - return [ - 'int' => [PHP_INT_MAX], - 'float' => [microtime(true)], - 'null' => [null], - 'bool' => [false], - 'object' => [new \stdClass], - 'callable' => [ - function () { - }, - ], - ]; - } - - /** - * @expectedException \Phalcon\Acl\Exception - * @expectedExceptionMessage Role "user" cannot inherit non-existent role "nonexistentrole". - * Either such role does not exist or it is set to be inherited before it is actually defined. - */ - public function testFactoryShouldThrowExceptionIfNonExistentInheritRoleIsSet() - { - $config = new Ini( - INCUBATOR_FIXTURES . 'Acl/acl.ini' - ); - - $config->acl->role->user->inherit = 'nonexistentrole'; - - $factory = new MemoryFactory(); - - $factory->create( - $config->get('acl') - ); - } - - protected function assertAclIsConfiguredAsExpected(MemoryAdapter $acl, Config $config) - { - // assert default action - $this->assertEquals( - Acl::DENY, - $acl->getDefaultAction() - ); - - - - // assert resources - $resources = $acl->getResources(); - - $this->assertInternalType('array', $resources); - - $indexResource = $resources[0]; - $testResource = $resources[1]; - - $this->assertEquals( - 'index', - $indexResource->getName() - ); - - $this->assertEquals( - 'test', - $testResource->getName() - ); - - $this->assertEquals( - $config->acl->resource->index->description, - $indexResource->getDescription() - ); - - $this->assertEquals( - $config->acl->resource->test->description, - $testResource->getDescription() - ); - - - - // assert roles - $roles = $acl->getRoles(); - - $this->assertInternalType( - 'array', - $roles - ); - - $guestRole = $roles[0]; - $userRole = $roles[1]; - - $this->assertEquals( - 'guest', - $guestRole->getName() - ); - - $this->assertEquals( - 'user', - $userRole->getName() - ); - - $this->assertEquals( - $config->acl->role->guest->description, - $guestRole->getDescription() - ); - - $this->assertEquals( - $config->acl->role->user->description, - $userRole->getDescription() - ); - - - - // assert guest rules - $this->assertTrue( - $acl->isAllowed('guest', 'index', 'index') - ); - - $this->assertFalse( - $acl->isAllowed('guest', 'test', 'index') - ); - - - - // assert user rules - // inherited from guest - $this->assertTrue( - $acl->isAllowed('user', 'index', 'index') - ); - - $this->assertTrue( - $acl->isAllowed('user', 'test', 'index') - ); - } -}