Seditio Source
Root |
./othercms/croogo-4.0.7/vendor/cakephp/acl/src/Adapter/CachedDbAcl.php
<?php
/**
 * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
 * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
 *
 * Licensed under The MIT License
 * For full copyright and license information, please see the LICENSE.txt
 * Redistributions of files must retain the above copyright notice.
 *
 * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
 * @link          http://cakephp.org CakePHP(tm) Project
 * @license       http://www.opensource.org/licenses/mit-license.php MIT License
 */
namespace Acl\Adapter;

use
Acl\AclInterface;
use
Cake\Cache\Cache;
use
Cake\Controller\Component;
use
Cake\Core\Configure;
use
Cake\ORM\Entity;
use
Cake\ORM\TableRegistry;
use
Cake\Utility\Text;

/**
 * CachedDbAcl extends DbAcl to add caching of permissions.
 *
 * Its usage is identical to that of DbAcl, however it supports a `Acl.cacheConfig` configuration value
 * This configuration value tells CachedDbAcl what cache config should be used.
 */
class CachedDbAcl extends DbAcl implements AclInterface
{

    protected
$_cacheConfig = 'default';

   
/**
     * Constructor
     *
     */
   
public function __construct()
    {
       
parent::__construct();

        if (
Configure::check('Acl.cacheConfig')) {
           
$this->_cacheConfig = Configure::read('Acl.cacheConfig');
        }
    }

   
/**
     * {{@inheritDoc}}
     */
   
public function check($aro, $aco, $action = "*")
    {
       
$key = $this->_getCacheKey($aro, $aco, $action);

       
$permission = Cache::remember($key, function () use ($aro, $aco, $action) {
            return
$this->Permission->check($aro, $aco, $action) === true ? 'true' : 'false';
        },
$this->_cacheConfig);

        return
$permission === 'true';
    }

   
/**
     * {{@inheritDoc}}
     */
   
public function allow($aro, $aco, $actions = "*", $value = 1)
    {
       
Cache::clear(false, $this->_cacheConfig);

        return
parent::allow($aro, $aco, $actions, $value);
    }

   
/**
     * Generates a string cache key for the ARO, ACO pair
     *
     * @param string|array|Entity $aro The requesting object identifier.
     * @param string|array|Entity $aco The controlled object identifier.
     * @param string $action Action
     * @return string
     */
   
protected function _getCacheKey($aro, $aco, $action = '*')
    {
        return
strtolower($this->_getNodeCacheKey($aro) . '_' . $this->_getNodeCacheKey($aco) . ($action == '*' ? '' : '_' . $action));
    }

   
/**
     * Generates a key string to use for the cache
     *
     * @param string|array|Entity $ref Array with 'model' and 'foreign_key', model object, or string value
     * @return string
     */
   
protected function _getNodeCacheKey($ref)
    {
        if (empty(
$ref)) {
            return
'';
        } elseif (
is_string($ref)) {
            return
Text::slug($ref, '_');
        } elseif (
is_object($ref) && $ref instanceof Entity) {
            return
$ref->getSource() . '_' . $ref->id;
        } elseif (
is_array($ref) && !(isset($ref['model']) && isset($ref['foreign_key']))) {
           
$name = key($ref);
            list(,
$alias) = pluginSplit($name);

           
$bindTable = TableRegistry::getTableLocator()->get($name);
           
$entityClass = $bindTable->getEntityClass();

            if (
$entityClass) {
               
$entity = new $entityClass();
            }

            if (empty(
$entity)) {
                throw new
Exception\Exception(
                   
__d(
                       
'cake_dev',
                       
"Entity class {0} not found in CachedDbAcl::_getNodeCacheKey() when trying to bind {1} object",
                        [
$type, $this->alias()]
                    )
                );
            }

           
$tmpRef = null;
            if (
method_exists($entity, 'bindNode')) {
               
$tmpRef = $entity->bindNode($ref);
            }

            if (empty(
$tmpRef)) {
               
$ref = [
                   
'model' => $alias,
                   
'foreign_key' => $ref[$name][$bindTable->getPrimaryKey()]
                ];
            } else {
               
$ref = $tmpRef;
            }

            return
$ref['model'] . '_' . $ref['foreign_key'];
        } elseif (
is_array($ref)) {
            return
$ref['model'] . '_' . $ref['foreign_key'];
        }

        return
'';
    }
}