Seditio Source
Root |
./othercms/xenForo 2.2.8/src/XF/DataRegistry.php
<?php

namespace XF;

use
Doctrine\Common\Cache\CacheProvider;
use
XF\Db\AbstractAdapter;

use function
array_key_exists, is_array;

class
DataRegistry implements \ArrayAccess
{
   
/**
     * @var AbstractAdapter
     */
   
protected $db;

   
/**
     * @var CacheProvider|null
     */
   
protected $cache;

    protected
$cacheIdPrefix = 'data_';
    protected
$cacheLifeTime = 3600;

    protected
$localData = [];

    public function
__construct(AbstractAdapter $db, CacheProvider $cache = null)
    {
       
$this->db = $db;
       
$this->cache = $cache;
    }

    public function
getCacheIdPrefix()
    {
        return
$this->cacheIdPrefix;
    }

    public function
setCacheIdPrefix($prefix)
    {
       
$this->cacheIdPrefix = $prefix;
    }

    public function
getCacheLifeTime()
    {
        return
$this->cacheLifeTime;
    }

    public function
setCacheLifeTime($lifeTime)
    {
       
$this->cacheLifeTime = $lifeTime;
    }

    public function
get($keys)
    {
        if (!
is_array($keys))
        {
           
$keys = [$keys];
           
$isMulti = false;
        }
        else
        {
            if (!
$keys)
            {
                return [];
            }

           
$isMulti = true;
        }

       
$data = [];
       
$originalKeys = $keys;
        foreach (
$keys AS $i => $key)
        {
            if (
array_key_exists($key, $this->localData))
            {
               
$data[$key] = $this->localData[$key];
                unset(
$keys[$i]);
            }
        }

        if (
$keys)
        {
           
$remainingKeys = $this->readFromCache($keys, $data);
           
$this->readFromDb($remainingKeys, $data);
        }

        if (
$isMulti)
        {
            return
$data;
        }
        else
        {
            return
$data[reset($originalKeys)];
        }
    }

    public function
exists($key)
    {
        return (
$this->get($key) !== null);
    }

    protected function
readFromCache(array $keys, array &$data)
    {
        if (!
$this->cache || !$keys)
        {
            return
$keys;
        }

       
$lookups = [];
        foreach (
$keys AS $i => $key)
        {
           
$lookups[$this->getCacheId($key)] = [$i, $key];
        }

       
$results = $this->cache->fetchMultiple(array_keys($lookups));
        foreach (
$results AS $cacheKey => $value)
        {
           
$keyId = $lookups[$cacheKey][0];
           
$keyName = $lookups[$cacheKey][1];
            unset(
$keys[$keyId]); // don't need to read from the DB

           
$data[$keyName] = $value;
           
$this->localData[$keyName] = $data[$keyName];
        }

        return
$keys;
    }

    protected function
readFromDb(array $keys, array &$data)
    {
        if (!
$keys)
        {
            return;
        }

       
$pairs = $this->db->fetchPairs("
            SELECT data_key, data_value
            FROM xf_data_registry
            WHERE data_key IN ("
. $this->db->quote($keys) . ")
        "
);
        foreach (
$keys AS $key)
        {
           
$exists = false;

            if (isset(
$pairs[$key]))
            {
               
$value = @unserialize($pairs[$key]);
                if (
$value !== false || $pairs[$key] === 'b:0;')
                {
                   
$data[$key] = $value;
                   
$exists = true;
                }
            }

            if (
$exists)
            {
               
// populate the cache on demand
               
$this->setInCache($key, $data[$key]);
            }
            else
            {
               
$data[$key] = null;
            }

           
$this->localData[$key] = $data[$key];
        }
    }

    public function
set($key, $value)
    {
       
$this->db->query("
            INSERT INTO xf_data_registry
                (data_key, data_value)
            VALUES
                (?, ?)
            ON DUPLICATE KEY UPDATE
                data_value = VALUES(data_value)
        "
, [$key, serialize($value)]);

       
$this->setInCache($key, $value);

       
$this->localData[$key] = $value;
    }

    protected function
setInCache($key, $value)
    {
        if (
$this->cache)
        {
           
$this->cache->save($this->getCacheId($key), $value, $this->cacheLifeTime);
        }
    }

    public function
delete($keys)
    {
        if (!
is_array($keys))
        {
           
$keys = [$keys];
        }
        else if (!
$keys)
        {
            return;
        }

       
$this->db->delete('xf_data_registry', 'data_key IN (' . $this->db->quote($keys) . ')');

        if (
$this->cache)
        {
            foreach (
$keys AS $key)
            {
               
$this->cache->delete($this->getCacheId($key));
            }
        }

        foreach (
$keys AS $key)
        {
           
$this->localData[$key] = null;
        }
    }

    protected function
getCacheId($key)
    {
        return
$this->cacheIdPrefix . $key;
    }

   
#[\ReturnTypeWillChange]
   
public function offsetGet($key)
    {
        return
$this->get($key);
    }

   
#[\ReturnTypeWillChange]
   
public function offsetSet($key, $value)
    {
       
$this->set($key, $value);
    }

   
#[\ReturnTypeWillChange]
   
public function offsetUnset($key)
    {
       
$this->delete($key);
    }

   
#[\ReturnTypeWillChange]
   
public function offsetExists($key)
    {
        return
$this->exists($key);
    }
}