parent
df500bdfb1
commit
91b07afbb3
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,8 @@ |
||||
language: php |
||||
|
||||
php: |
||||
- 5.3 |
||||
- 5.4 |
||||
|
||||
before_script: |
||||
- composer --prefer-source --dev install |
@ -0,0 +1,19 @@ |
||||
Copyright (c) 2006-2012 Doctrine Project |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of |
||||
this software and associated documentation files (the "Software"), to deal in |
||||
the Software without restriction, including without limitation the rights to |
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies |
||||
of the Software, and to permit persons to whom the Software is furnished to do |
||||
so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included in all |
||||
copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||||
SOFTWARE. |
@ -0,0 +1,3 @@ |
||||
# Doctrine Cache |
||||
|
||||
Cache component extracted from the Doctrine Common project. |
@ -0,0 +1,21 @@ |
||||
{ |
||||
"name": "doctrine/cache", |
||||
"type": "library", |
||||
"description": "Caching library offering an object-oriented API for many cache backends", |
||||
"keywords": ["cache", "caching"], |
||||
"homepage": "http://www.doctrine-project.org", |
||||
"license": "MIT", |
||||
"authors": [ |
||||
{"name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com"}, |
||||
{"name": "Roman Borschel", "email": "roman@code-factory.org"}, |
||||
{"name": "Benjamin Eberlei", "email": "kontakt@beberlei.de"}, |
||||
{"name": "Jonathan Wage", "email": "jonwage@gmail.com"}, |
||||
{"name": "Johannes Schmitt", "email": "schmittjoh@gmail.com"} |
||||
], |
||||
"require": { |
||||
"php": ">=5.3.2" |
||||
}, |
||||
"autoload": { |
||||
"psr-0": { "Doctrine\\Common\\Cache\\": "lib/" } |
||||
} |
||||
} |
@ -0,0 +1,93 @@ |
||||
<?php |
||||
|
||||
/* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
* This software consists of voluntary contributions made by many individuals |
||||
* and is licensed under the MIT license. For more information, see |
||||
* <http://www.doctrine-project.org>. |
||||
*/ |
||||
|
||||
namespace Doctrine\Common\Cache; |
||||
|
||||
/** |
||||
* APC cache provider. |
||||
* |
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL |
||||
* @link www.doctrine-project.org |
||||
* @since 2.0 |
||||
* @author Benjamin Eberlei <kontakt@beberlei.de> |
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com> |
||||
* @author Jonathan Wage <jonwage@gmail.com> |
||||
* @author Roman Borschel <roman@code-factory.org> |
||||
* @author David Abdemoulaie <dave@hobodave.com> |
||||
*/ |
||||
class ApcCache extends CacheProvider |
||||
{ |
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doFetch($id) |
||||
{ |
||||
return apc_fetch($id); |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doContains($id) |
||||
{ |
||||
return apc_exists($id); |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doSave($id, $data, $lifeTime = 0) |
||||
{ |
||||
return (bool) apc_store($id, $data, (int) $lifeTime); |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doDelete($id) |
||||
{ |
||||
return apc_delete($id); |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doFlush() |
||||
{ |
||||
return apc_clear_cache() && apc_clear_cache('user'); |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doGetStats() |
||||
{ |
||||
$info = apc_cache_info(); |
||||
$sma = apc_sma_info(); |
||||
|
||||
return array( |
||||
Cache::STATS_HITS => $info['num_hits'], |
||||
Cache::STATS_MISSES => $info['num_misses'], |
||||
Cache::STATS_UPTIME => $info['start_time'], |
||||
Cache::STATS_MEMORY_USAGE => $info['mem_size'], |
||||
Cache::STATS_MEMORY_AVAILIABLE => $sma['avail_mem'], |
||||
); |
||||
} |
||||
} |
@ -0,0 +1,96 @@ |
||||
<?php |
||||
/* |
||||
* $Id$ |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
* This software consists of voluntary contributions made by many individuals |
||||
* and is licensed under the MIT license. For more information, see |
||||
* <http://www.doctrine-project.org>. |
||||
*/ |
||||
|
||||
namespace Doctrine\Common\Cache; |
||||
|
||||
/** |
||||
* Array cache driver. |
||||
* |
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL |
||||
* @link www.doctrine-project.org |
||||
* @since 2.0 |
||||
* @author Benjamin Eberlei <kontakt@beberlei.de> |
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com> |
||||
* @author Jonathan Wage <jonwage@gmail.com> |
||||
* @author Roman Borschel <roman@code-factory.org> |
||||
* @author David Abdemoulaie <dave@hobodave.com> |
||||
*/ |
||||
class ArrayCache extends CacheProvider |
||||
{ |
||||
/** |
||||
* @var array $data |
||||
*/ |
||||
private $data = array(); |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doFetch($id) |
||||
{ |
||||
return (isset($this->data[$id])) ? $this->data[$id] : false; |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doContains($id) |
||||
{ |
||||
return isset($this->data[$id]); |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doSave($id, $data, $lifeTime = 0) |
||||
{ |
||||
$this->data[$id] = $data; |
||||
|
||||
return true; |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doDelete($id) |
||||
{ |
||||
unset($this->data[$id]); |
||||
|
||||
return true; |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doFlush() |
||||
{ |
||||
$this->data = array(); |
||||
|
||||
return true; |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doGetStats() |
||||
{ |
||||
return null; |
||||
} |
||||
} |
@ -0,0 +1,102 @@ |
||||
<?php |
||||
/* |
||||
* $Id$ |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
* This software consists of voluntary contributions made by many individuals |
||||
* and is licensed under the MIT license. For more information, see |
||||
* <http://www.doctrine-project.org>. |
||||
*/ |
||||
|
||||
namespace Doctrine\Common\Cache; |
||||
|
||||
/** |
||||
* Interface for cache drivers. |
||||
* |
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL |
||||
* @link www.doctrine-project.org |
||||
* @since 2.0 |
||||
* @author Benjamin Eberlei <kontakt@beberlei.de> |
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com> |
||||
* @author Jonathan Wage <jonwage@gmail.com> |
||||
* @author Roman Borschel <roman@code-factory.org> |
||||
* @author Fabio B. Silva <fabio.bat.silva@gmail.com> |
||||
*/ |
||||
interface Cache |
||||
{ |
||||
const STATS_HITS = 'hits'; |
||||
const STATS_MISSES = 'misses'; |
||||
const STATS_UPTIME = 'uptime'; |
||||
const STATS_MEMORY_USAGE = 'memory_usage'; |
||||
const STATS_MEMORY_AVAILIABLE = 'memory_available'; |
||||
|
||||
/** |
||||
* Fetches an entry from the cache. |
||||
* |
||||
* @param string $id cache id The id of the cache entry to fetch. |
||||
* @return mixed The cached data or FALSE, if no cache entry exists for the given id. |
||||
*/ |
||||
function fetch($id); |
||||
|
||||
/** |
||||
* Test if an entry exists in the cache. |
||||
* |
||||
* @param string $id cache id The cache id of the entry to check for. |
||||
* @return boolean TRUE if a cache entry exists for the given cache id, FALSE otherwise. |
||||
*/ |
||||
function contains($id); |
||||
|
||||
/** |
||||
* Puts data into the cache. |
||||
* |
||||
* @param string $id The cache id. |
||||
* @param mixed $data The cache entry/data. |
||||
* @param int $lifeTime The lifetime. If != 0, sets a specific lifetime for this cache entry (0 => infinite lifeTime). |
||||
* @return boolean TRUE if the entry was successfully stored in the cache, FALSE otherwise. |
||||
*/ |
||||
function save($id, $data, $lifeTime = 0); |
||||
|
||||
/** |
||||
* Deletes a cache entry. |
||||
* |
||||
* @param string $id cache id |
||||
* @return boolean TRUE if the cache entry was successfully deleted, FALSE otherwise. |
||||
*/ |
||||
function delete($id); |
||||
|
||||
/** |
||||
* Retrieves cached information from data store |
||||
* |
||||
* The server's statistics array has the following values: |
||||
* |
||||
* - <b>hits</b> |
||||
* Number of keys that have been requested and found present. |
||||
* |
||||
* - <b>misses</b> |
||||
* Number of items that have been requested and not found. |
||||
* |
||||
* - <b>uptime</b> |
||||
* Time that the server is running. |
||||
* |
||||
* - <b>memory_usage</b> |
||||
* Memory used by this server to store items. |
||||
* |
||||
* - <b>memory_available</b> |
||||
* Memory allowed to use for storage. |
||||
* |
||||
* @since 2.2 |
||||
* @return array Associative array with server's statistics if available, NULL otherwise. |
||||
*/ |
||||
function getStats(); |
||||
} |
@ -0,0 +1,231 @@ |
||||
<?php |
||||
|
||||
/* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
* This software consists of voluntary contributions made by many individuals |
||||
* and is licensed under the MIT license. For more information, see |
||||
* <http://www.doctrine-project.org>. |
||||
*/ |
||||
|
||||
namespace Doctrine\Common\Cache; |
||||
|
||||
/** |
||||
* Base class for cache provider implementations. |
||||
* |
||||
* @since 2.2 |
||||
* @author Benjamin Eberlei <kontakt@beberlei.de> |
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com> |
||||
* @author Jonathan Wage <jonwage@gmail.com> |
||||
* @author Roman Borschel <roman@code-factory.org> |
||||
* @author Fabio B. Silva <fabio.bat.silva@gmail.com> |
||||
*/ |
||||
abstract class CacheProvider implements Cache |
||||
{ |
||||
const DOCTRINE_NAMESPACE_CACHEKEY = 'DoctrineNamespaceCacheKey[%s]'; |
||||
|
||||
/** |
||||
* @var string The namespace to prefix all cache ids with |
||||
*/ |
||||
private $namespace = ''; |
||||
|
||||
/** |
||||
* @var string The namespace version |
||||
*/ |
||||
private $namespaceVersion; |
||||
|
||||
/** |
||||
* Set the namespace to prefix all cache ids with. |
||||
* |
||||
* @param string $namespace |
||||
* @return void |
||||
*/ |
||||
public function setNamespace($namespace) |
||||
{ |
||||
$this->namespace = (string) $namespace; |
||||
} |
||||
|
||||
/** |
||||
* Retrieve the namespace that prefixes all cache ids. |
||||
* |
||||
* @return string |
||||
*/ |
||||
public function getNamespace() |
||||
{ |
||||
return $this->namespace; |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
public function fetch($id) |
||||
{ |
||||
return $this->doFetch($this->getNamespacedId($id)); |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
public function contains($id) |
||||
{ |
||||
return $this->doContains($this->getNamespacedId($id)); |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
public function save($id, $data, $lifeTime = 0) |
||||
{ |
||||
return $this->doSave($this->getNamespacedId($id), $data, $lifeTime); |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
public function delete($id) |
||||
{ |
||||
return $this->doDelete($this->getNamespacedId($id)); |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
public function getStats() |
||||
{ |
||||
return $this->doGetStats(); |
||||
} |
||||
|
||||
/** |
||||
* Deletes all cache entries. |
||||
* |
||||
* @return boolean TRUE if the cache entries were successfully flushed, FALSE otherwise. |
||||
*/ |
||||
public function flushAll() |
||||
{ |
||||
return $this->doFlush(); |
||||
} |
||||
|
||||
/** |
||||
* Delete all cache entries. |
||||
* |
||||
* @return boolean TRUE if the cache entries were successfully deleted, FALSE otherwise. |
||||
*/ |
||||
public function deleteAll() |
||||
{ |
||||
$namespaceCacheKey = $this->getNamespaceCacheKey(); |
||||
$namespaceVersion = $this->getNamespaceVersion() + 1; |
||||
|
||||
$this->namespaceVersion = $namespaceVersion; |
||||
|
||||
return $this->doSave($namespaceCacheKey, $namespaceVersion); |
||||
} |
||||
|
||||
/** |
||||
* Prefix the passed id with the configured namespace value |
||||
* |
||||
* @param string $id The id to namespace |
||||
* @return string $id The namespaced id |
||||
*/ |
||||
private function getNamespacedId($id) |
||||
{ |
||||
$namespaceVersion = $this->getNamespaceVersion(); |
||||
|
||||
return sprintf('%s[%s][%s]', $this->namespace, $id, $namespaceVersion); |
||||
} |
||||
|
||||
/** |
||||
* Namespace cache key |
||||
* |
||||
* @return string $namespaceCacheKey |
||||
*/ |
||||
private function getNamespaceCacheKey() |
||||
{ |
||||
return sprintf(self::DOCTRINE_NAMESPACE_CACHEKEY, $this->namespace); |
||||
} |
||||
|
||||
/** |
||||
* Namespace version |
||||
* |
||||
* @return string $namespaceVersion |
||||
*/ |
||||
private function getNamespaceVersion() |
||||
{ |
||||
if (null !== $this->namespaceVersion) { |
||||
return $this->namespaceVersion; |
||||
} |
||||
|
||||
$namespaceCacheKey = $this->getNamespaceCacheKey(); |
||||
$namespaceVersion = $this->doFetch($namespaceCacheKey); |
||||
|
||||
if (false === $namespaceVersion) { |
||||
$namespaceVersion = 1; |
||||
|
||||
$this->doSave($namespaceCacheKey, $namespaceVersion); |
||||
} |
||||
|
||||
$this->namespaceVersion = $namespaceVersion; |
||||
|
||||
return $this->namespaceVersion; |
||||
} |
||||
|
||||
/** |
||||
* Fetches an entry from the cache. |
||||
* |
||||
* @param string $id cache id The id of the cache entry to fetch. |
||||
* @return string The cached data or FALSE, if no cache entry exists for the given id. |
||||
*/ |
||||
abstract protected function doFetch($id); |
||||
|
||||
/** |
||||
* Test if an entry exists in the cache. |
||||
* |
||||
* @param string $id cache id The cache id of the entry to check for. |
||||
* @return boolean TRUE if a cache entry exists for the given cache id, FALSE otherwise. |
||||
*/ |
||||
abstract protected function doContains($id); |
||||
|
||||
/** |
||||
* Puts data into the cache. |
||||
* |
||||
* @param string $id The cache id. |
||||
* @param string $data The cache entry/data. |
||||
* @param bool|int $lifeTime The lifetime. If != false, sets a specific lifetime for this |
||||
* cache entry (null => infinite lifeTime). |
||||
* |
||||
* @return boolean TRUE if the entry was successfully stored in the cache, FALSE otherwise. |
||||
*/ |
||||
abstract protected function doSave($id, $data, $lifeTime = false); |
||||
|
||||
/** |
||||
* Deletes a cache entry. |
||||
* |
||||
* @param string $id cache id |
||||
* @return boolean TRUE if the cache entry was successfully deleted, FALSE otherwise. |
||||
*/ |
||||
abstract protected function doDelete($id); |
||||
|
||||
/** |
||||
* Deletes all cache entries. |
||||
* |
||||
* @return boolean TRUE if the cache entry was successfully deleted, FALSE otherwise. |
||||
*/ |
||||
abstract protected function doFlush(); |
||||
|
||||
/** |
||||
* Retrieves cached information from data store |
||||
* |
||||
* @since 2.2 |
||||
* @return array An associative array with server's statistics if available, NULL otherwise. |
||||
*/ |
||||
abstract protected function doGetStats(); |
||||
} |
@ -0,0 +1,123 @@ |
||||
<?php |
||||
|
||||
/* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
* This software consists of voluntary contributions made by many individuals |
||||
* and is licensed under the MIT license. For more information, see |
||||
* <http://www.doctrine-project.org>. |
||||
*/ |
||||
|
||||
namespace Doctrine\Common\Cache; |
||||
|
||||
use \Couchbase; |
||||
|
||||
/** |
||||
* Couchbase cache provider. |
||||
* |
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL |
||||
* @link www.doctrine-project.org |
||||
* @since 2.4 |
||||
* @author Michael Nitschinger <michael@nitschinger.at> |
||||
*/ |
||||
class CouchbaseCache extends CacheProvider |
||||
{ |
||||
|
||||
/** |
||||
* @var Couchbase |
||||
*/ |
||||
private $couchbase; |
||||
|
||||
/** |
||||
* Sets the Couchbase instance to use. |
||||
* |
||||
* @param Couchbase $couchbase |
||||
*/ |
||||
public function setCouchbase(Couchbase $couchbase) |
||||
{ |
||||
$this->couchbase = $couchbase; |
||||
} |
||||
|
||||
/** |
||||
* Gets the Couchbase instance used by the cache. |
||||
* |
||||
* @return Couchbase |
||||
*/ |
||||
public function getCouchbase() |
||||
{ |
||||
return $this->couchbase; |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doFetch($id) |
||||
{ |
||||
return $this->couchbase->get($id) ?: false; |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doContains($id) |
||||
{ |
||||
return (null !== $this->couchbase->get($id)); |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doSave($id, $data, $lifeTime = 0) |
||||
{ |
||||
if ($lifeTime > 30 * 24 * 3600) { |
||||
$lifeTime = time() + $lifeTime; |
||||
} |
||||
return $this->couchbase->set($id, $data, (int) $lifeTime); |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doDelete($id) |
||||
{ |
||||
return $this->couchbase->delete($id); |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doFlush() |
||||
{ |
||||
return $this->couchbase->flush(); |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doGetStats() |
||||
{ |
||||
$stats = $this->couchbase->getStats(); |
||||
$servers = $this->couchbase->getServers(); |
||||
$server = explode(":", $servers[0]); |
||||
$key = $server[0] . ":" . "11210"; |
||||
$stats = $stats[$key]; |
||||
return array( |
||||
Cache::STATS_HITS => $stats['get_hits'], |
||||
Cache::STATS_MISSES => $stats['get_misses'], |
||||
Cache::STATS_UPTIME => $stats['uptime'], |
||||
Cache::STATS_MEMORY_USAGE => $stats['bytes'], |
||||
Cache::STATS_MEMORY_AVAILIABLE => $stats['limit_maxbytes'], |
||||
); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,132 @@ |
||||
<?php |
||||
|
||||
/* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
* This software consists of voluntary contributions made by many individuals |
||||
* and is licensed under the MIT license. For more information, see |
||||
* <http://www.doctrine-project.org>. |
||||
*/ |
||||
|
||||
namespace Doctrine\Common\Cache; |
||||
|
||||
/** |
||||
* Base file cache driver. |
||||
* |
||||
* @since 2.3 |
||||
* @author Fabio B. Silva <fabio.bat.silva@gmail.com> |
||||
*/ |
||||
abstract class FileCache extends CacheProvider |
||||
{ |
||||
/** |
||||
* @var string Cache directory. |
||||
*/ |
||||
protected $directory; |
||||
|
||||
/** |
||||
* @var string Cache file extension. |
||||
*/ |
||||
protected $extension; |
||||
|
||||
/** |
||||
* Constructor |
||||
* |
||||
* @param string $directory Cache directory. |
||||
* @param string $directory Cache file extension. |
||||
* |
||||
* @throws \InvalidArgumentException |
||||
*/ |
||||
public function __construct($directory, $extension = null) |
||||
{ |
||||
if ( ! is_dir($directory) && ! @mkdir($directory, 0777, true)) { |
||||
throw new \InvalidArgumentException(sprintf( |
||||
'The directory "%s" does not exist and could not be created.', |
||||
$directory |
||||
)); |
||||
} |
||||
|
||||
if ( ! is_writable($directory)) { |
||||
throw new \InvalidArgumentException(sprintf( |
||||
'The directory "%s" is not writable.', |
||||
$directory |
||||
)); |
||||
} |
||||
|
||||
$this->directory = realpath($directory); |
||||
$this->extension = $extension ?: $this->extension; |
||||
} |
||||
|
||||
/** |
||||
* Gets the cache directory. |
||||
* |
||||
* @return string |
||||
*/ |
||||
public function getDirectory() |
||||
{ |
||||
return $this->directory; |
||||
} |
||||
|
||||
/** |
||||
* Gets the cache file extension. |
||||
* |
||||
* @return string |
||||
*/ |
||||
public function getExtension() |
||||
{ |
||||
return $this->extension; |
||||
} |
||||
|
||||
/** |
||||
* @return string |
||||
*/ |
||||
protected function getFilename($id) |
||||
{ |
||||
$path = implode(str_split(md5($id), 12), DIRECTORY_SEPARATOR); |
||||
$path = $this->directory . DIRECTORY_SEPARATOR . $path; |
||||
|
||||
return $path . DIRECTORY_SEPARATOR . $id . $this->extension; |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doDelete($id) |
||||
{ |
||||
return @unlink($this->getFilename($id)); |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doFlush() |
||||
{ |
||||
$pattern = '/^.+\\' . $this->extension . '$/i'; |
||||
$iterator = new \RecursiveDirectoryIterator($this->directory); |
||||
$iterator = new \RecursiveIteratorIterator($iterator); |
||||
$iterator = new \RegexIterator($iterator, $pattern); |
||||
|
||||
foreach ($iterator as $name => $file) { |
||||
@unlink($name); |
||||
} |
||||
|
||||
return true; |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doGetStats() |
||||
{ |
||||
return null; |
||||
} |
||||
} |
@ -0,0 +1,114 @@ |
||||
<?php |
||||
|
||||
/* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
* This software consists of voluntary contributions made by many individuals |
||||
* and is licensed under the MIT license. For more information, see |
||||
* <http://www.doctrine-project.org>. |
||||
*/ |
||||
|
||||
namespace Doctrine\Common\Cache; |
||||
|
||||
/** |
||||
* Filesystem cache driver. |
||||
* |
||||
* @since 2.3 |
||||
* @author Fabio B. Silva <fabio.bat.silva@gmail.com> |
||||
*/ |
||||
class FilesystemCache extends FileCache |
||||
{ |
||||
const EXTENSION = '.doctrinecache.data'; |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected $extension = self::EXTENSION; |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doFetch($id) |
||||
{ |
||||
$data = ''; |
||||
$lifetime = -1; |
||||
$filename = $this->getFilename($id); |
||||
|
||||
if ( ! is_file($filename)) { |
||||
return false; |
||||
} |
||||
|
||||
$resource = fopen($filename, "r"); |
||||
|
||||
if (false !== ($line = fgets($resource))) { |
||||
$lifetime = (integer) $line; |
||||
} |
||||
|
||||
if ($lifetime !== 0 && $lifetime < time()) { |
||||
fclose($resource); |
||||
|
||||
return false; |
||||
} |
||||
|
||||
while (false !== ($line = fgets($resource))) { |
||||
$data .= $line; |
||||
} |
||||
|
||||
fclose($resource); |
||||
|
||||
return unserialize($data); |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doContains($id) |
||||
{ |
||||
$lifetime = -1; |
||||
$filename = $this->getFilename($id); |
||||
|
||||
if ( ! is_file($filename)) { |
||||
return false; |
||||
} |
||||
|
||||
$resource = fopen($filename, "r"); |
||||
|
||||
if (false !== ($line = fgets($resource))) { |
||||
$lifetime = (integer) $line; |
||||
} |
||||
|
||||
fclose($resource); |
||||
|
||||
return $lifetime === 0 || $lifetime > time(); |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doSave($id, $data, $lifeTime = 0) |
||||
{ |
||||
if ($lifeTime > 0) { |
||||
$lifeTime = time() + $lifeTime; |
||||
} |
||||
|
||||
$data = serialize($data); |
||||
$filename = $this->getFilename($id); |
||||
$filepath = pathinfo($filename, PATHINFO_DIRNAME); |
||||
|
||||
if ( ! is_dir($filepath)) { |
||||
mkdir($filepath, 0777, true); |
||||
} |
||||
|
||||
return file_put_contents($filename, $lifeTime . PHP_EOL . $data); |
||||
} |
||||
} |
@ -0,0 +1,121 @@ |
||||
<?php |
||||
|
||||
/* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
* This software consists of voluntary contributions made by many individuals |
||||
* and is licensed under the MIT license. For more information, see |
||||
* <http://www.doctrine-project.org>. |
||||
*/ |
||||
|
||||
namespace Doctrine\Common\Cache; |
||||
|
||||
use \Memcache; |
||||
|
||||
/** |
||||
* Memcache cache provider. |
||||
* |
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL |
||||
* @link www.doctrine-project.org |
||||
* @since 2.0 |
||||
* @author Benjamin Eberlei <kontakt@beberlei.de> |
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com> |
||||
* @author Jonathan Wage <jonwage@gmail.com> |
||||
* @author Roman Borschel <roman@code-factory.org> |
||||
* @author David Abdemoulaie <dave@hobodave.com> |
||||
*/ |
||||
class MemcacheCache extends CacheProvider |
||||
{ |
||||
/** |
||||
* @var Memcache |
||||
*/ |
||||
private $memcache; |
||||
|
||||
/** |
||||
* Sets the memcache instance to use. |
||||
* |
||||
* @param Memcache $memcache |
||||
*/ |
||||
public function setMemcache(Memcache $memcache) |
||||
{ |
||||
$this->memcache = $memcache; |
||||
} |
||||
|
||||
/** |
||||
* Gets the memcache instance used by the cache. |
||||
* |
||||
* @return Memcache |
||||
*/ |
||||
public function getMemcache() |
||||
{ |
||||
return $this->memcache; |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doFetch($id) |
||||
{ |
||||
return $this->memcache->get($id); |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doContains($id) |
||||
{ |
||||
return (bool) $this->memcache->get($id); |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doSave($id, $data, $lifeTime = 0) |
||||
{ |
||||
if ($lifeTime > 30 * 24 * 3600) { |
||||
$lifeTime = time() + $lifeTime; |
||||
} |
||||
return $this->memcache->set($id, $data, 0, (int) $lifeTime); |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doDelete($id) |
||||
{ |
||||
return $this->memcache->delete($id); |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doFlush() |
||||
{ |
||||
return $this->memcache->flush(); |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doGetStats() |
||||
{ |
||||
$stats = $this->memcache->getStats(); |
||||
return array( |
||||
Cache::STATS_HITS => $stats['get_hits'], |
||||
Cache::STATS_MISSES => $stats['get_misses'], |
||||
Cache::STATS_UPTIME => $stats['uptime'], |
||||
Cache::STATS_MEMORY_USAGE => $stats['bytes'], |
||||
Cache::STATS_MEMORY_AVAILIABLE => $stats['limit_maxbytes'], |
||||
); |
||||
} |
||||
} |
@ -0,0 +1,124 @@ |
||||
<?php |
||||
|
||||
/* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
* This software consists of voluntary contributions made by many individuals |
||||
* and is licensed under the MIT license. For more information, see |
||||
* <http://www.doctrine-project.org>. |
||||
*/ |
||||
|
||||
namespace Doctrine\Common\Cache; |
||||
|
||||
use \Memcached; |
||||
|
||||
/** |
||||
* Memcached cache provider. |
||||
* |
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL |
||||
* @link www.doctrine-project.org |
||||
* @since 2.2 |
||||
* @author Benjamin Eberlei <kontakt@beberlei.de> |
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com> |
||||
* @author Jonathan Wage <jonwage@gmail.com> |
||||
* @author Roman Borschel <roman@code-factory.org> |
||||
* @author David Abdemoulaie <dave@hobodave.com> |
||||
*/ |
||||
class MemcachedCache extends CacheProvider |
||||
{ |
||||
/** |
||||
* @var Memcached |
||||
*/ |
||||
private $memcached; |
||||
|
||||
/** |
||||
* Sets the memcache instance to use. |
||||
* |
||||
* @param Memcached $memcached |
||||
*/ |
||||
public function setMemcached(Memcached $memcached) |
||||
{ |
||||
$this->memcached = $memcached; |
||||
} |
||||
|
||||
/** |
||||
* Gets the memcached instance used by the cache. |
||||
* |
||||
* @return Memcached |
||||
*/ |
||||
public function getMemcached() |
||||
{ |
||||
return $this->memcached; |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doFetch($id) |
||||
{ |
||||
return $this->memcached->get($id); |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doContains($id) |
||||
{ |
||||
return (false !== $this->memcached->get($id)); |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doSave($id, $data, $lifeTime = 0) |
||||
{ |
||||
if ($lifeTime > 30 * 24 * 3600) { |
||||
$lifeTime = time() + $lifeTime; |
||||
} |
||||
return $this->memcached->set($id, $data, (int) $lifeTime); |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doDelete($id) |
||||
{ |
||||
return $this->memcached->delete($id); |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doFlush() |
||||
{ |
||||
return $this->memcached->flush(); |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doGetStats() |
||||
{ |
||||
$stats = $this->memcached->getStats(); |
||||
$servers = $this->memcached->getServerList(); |
||||
$key = $servers[0]['host'] . ':' . $servers[0]['port']; |
||||
$stats = $stats[$key]; |
||||
return array( |
||||
Cache::STATS_HITS => $stats['get_hits'], |
||||
Cache::STATS_MISSES => $stats['get_misses'], |
||||
Cache::STATS_UPTIME => $stats['uptime'], |
||||
Cache::STATS_MEMORY_USAGE => $stats['bytes'], |
||||
Cache::STATS_MEMORY_AVAILIABLE => $stats['limit_maxbytes'], |
||||
); |
||||
} |
||||
} |
@ -0,0 +1,108 @@ |
||||
<?php |
||||
|
||||
/* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
* This software consists of voluntary contributions made by many individuals |
||||
* and is licensed under the MIT license. For more information, see |
||||
* <http://www.doctrine-project.org>. |
||||
*/ |
||||
|
||||
namespace Doctrine\Common\Cache; |
||||
|
||||
/** |
||||
* Php file cache driver. |
||||
* |
||||
* @since 2.3 |
||||
* @author Fabio B. Silva <fabio.bat.silva@gmail.com> |
||||
*/ |
||||
class PhpFileCache extends FileCache |
||||
{ |
||||
const EXTENSION = '.doctrinecache.php'; |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected $extension = self::EXTENSION; |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doFetch($id) |
||||
{ |
||||
$filename = $this->getFilename($id); |
||||
|
||||
if ( ! is_file($filename)) { |
||||
return false; |
||||
} |
||||
|
||||
$value = include $filename; |
||||
|
||||
if ($value['lifetime'] !== 0 && $value['lifetime'] < time()) { |
||||
return false; |
||||
} |
||||
|
||||
return $value['data']; |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doContains($id) |
||||
{ |
||||
$filename = $this->getFilename($id); |
||||
|
||||
if ( ! is_file($filename)) { |
||||
return false; |
||||
} |
||||
|
||||
$value = include $filename; |
||||
|
||||
return $value['lifetime'] === 0 || $value['lifetime'] > time(); |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doSave($id, $data, $lifeTime = 0) |
||||
{ |
||||
if ($lifeTime > 0) { |
||||
$lifeTime = time() + $lifeTime; |
||||
} |
||||
|
||||
if (is_object($data) && ! method_exists($data, '__set_state')) { |
||||
throw new \InvalidArgumentException( |
||||
"Invalid argument given, PhpFileCache only allows objects that implement __set_state() " . |
||||
"and fully support var_export(). You can use the FilesystemCache to save arbitrary object " . |
||||
"graphs using serialize()/deserialize()." |
||||
); |
||||
} |
||||
|
||||
$filename = $this->getFilename($id); |
||||
$filepath = pathinfo($filename, PATHINFO_DIRNAME); |
||||
|
||||
if ( ! is_dir($filepath)) { |
||||
mkdir($filepath, 0777, true); |
||||
} |
||||
|
||||
$value = array( |
||||
'lifetime' => $lifeTime, |
||||
'data' => $data |
||||
); |
||||
|
||||
$value = var_export($value, true); |
||||
$code = sprintf('<?php return %s;', $value); |
||||
|
||||
return file_put_contents($filename, $code); |
||||
} |
||||
} |
@ -0,0 +1,119 @@ |
||||
<?php |
||||
|
||||
/* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
* This software consists of voluntary contributions made by many individuals |
||||
* and is licensed under the MIT license. For more information, see |
||||
* <http://www.doctrine-project.org>. |
||||
*/ |
||||
|
||||
namespace Doctrine\Common\Cache; |
||||
|
||||
use Redis; |
||||
|
||||
/** |
||||
* Redis cache provider. |
||||
* |
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL |
||||
* @link www.doctrine-project.org |
||||
* @since 2.2 |
||||
* @author Osman Ungur <osmanungur@gmail.com> |
||||
*/ |
||||
class RedisCache extends CacheProvider |
||||
{ |
||||
/** |
||||
* @var Redis |
||||
*/ |
||||
private $redis; |
||||
|
||||
/** |
||||
* Sets the redis instance to use. |
||||
* |
||||
* @param Redis $redis |
||||
*/ |
||||
public function setRedis(Redis $redis) |
||||
{ |
||||
$redis->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_IGBINARY); |
||||
$this->redis = $redis; |
||||
} |
||||
|
||||
/** |
||||
* Gets the redis instance used by the cache. |
||||
* |
||||
* @return Redis |
||||
*/ |
||||
public function getRedis() |
||||
{ |
||||
return $this->redis; |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doFetch($id) |
||||
{ |
||||
return $this->redis->get($id); |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doContains($id) |
||||
{ |
||||
return $this->redis->exists($id); |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doSave($id, $data, $lifeTime = 0) |
||||
{ |
||||
$result = $this->redis->set($id, $data); |
||||
if ($lifeTime > 0) { |
||||
$this->redis->expire($id, $lifeTime); |
||||
} |
||||
return $result; |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doDelete($id) |
||||
{ |
||||
return $this->redis->delete($id); |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doFlush() |
||||
{ |
||||
return $this->redis->flushDB(); |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doGetStats() |
||||
{ |
||||
$info = $this->redis->info(); |
||||
return array( |
||||
Cache::STATS_HITS => false, |
||||
Cache::STATS_MISSES => false, |
||||
Cache::STATS_UPTIME => $info['uptime_in_seconds'], |
||||
Cache::STATS_MEMORY_USAGE => $info['used_memory'], |
||||
Cache::STATS_MEMORY_AVAILIABLE => false |
||||
); |
||||
} |
||||
} |
@ -0,0 +1,93 @@ |
||||
<?php |
||||
|
||||
/* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
* This software consists of voluntary contributions made by many individuals |
||||
* and is licensed under the MIT license. For more information, see |
||||
* <http://www.doctrine-project.org>. |
||||
*/ |
||||
|
||||
namespace Doctrine\Common\Cache; |
||||
|
||||
/** |
||||
* WinCache cache provider. |
||||
* |
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL |
||||
* @link www.doctrine-project.org |
||||
* @since 2.2 |
||||
* @author Benjamin Eberlei <kontakt@beberlei.de> |
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com> |
||||
* @author Jonathan Wage <jonwage@gmail.com> |
||||
* @author Roman Borschel <roman@code-factory.org> |
||||
* @author David Abdemoulaie <dave@hobodave.com> |
||||
*/ |
||||
class WinCacheCache extends CacheProvider |
||||
{ |
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doFetch($id) |
||||
{ |
||||
return wincache_ucache_get($id); |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doContains($id) |
||||
{ |
||||
return wincache_ucache_exists($id); |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doSave($id, $data, $lifeTime = 0) |
||||
{ |
||||
return (bool) wincache_ucache_set($id, $data, (int) $lifeTime); |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doDelete($id) |
||||
{ |
||||
return wincache_ucache_delete($id); |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doFlush() |
||||
{ |
||||
return wincache_ucache_clear(); |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doGetStats() |
||||
{ |
||||
$info = wincache_ucache_info(); |
||||
$meminfo = wincache_ucache_meminfo(); |
||||
|
||||
return array( |
||||
Cache::STATS_HITS => $info['total_hit_count'], |
||||
Cache::STATS_MISSES => $info['total_miss_count'], |
||||
Cache::STATS_UPTIME => $info['total_cache_uptime'], |
||||
Cache::STATS_MEMORY_USAGE => $meminfo['memory_total'], |
||||
Cache::STATS_MEMORY_AVAILIABLE => $meminfo['memory_free'], |
||||
); |
||||
} |
||||
} |
@ -0,0 +1,110 @@ |
||||
<?php |
||||
|
||||
/* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
* This software consists of voluntary contributions made by many individuals |
||||
* and is licensed under the MIT license. For more information, see |
||||
* <http://www.doctrine-project.org>. |
||||
*/ |
||||
|
||||
namespace Doctrine\Common\Cache; |
||||
|
||||
/** |
||||
* Xcache cache driver. |
||||
* |
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL |
||||
* @link www.doctrine-project.org |
||||
* @since 2.0 |
||||
* @author Benjamin Eberlei <kontakt@beberlei.de> |
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com> |
||||
* @author Jonathan Wage <jonwage@gmail.com> |
||||
* @author Roman Borschel <roman@code-factory.org> |
||||
* @author David Abdemoulaie <dave@hobodave.com> |
||||
*/ |
||||
class XcacheCache extends CacheProvider |
||||
{ |
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doFetch($id) |
||||
{ |
||||
return $this->doContains($id) ? unserialize(xcache_get($id)) : false; |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doContains($id) |
||||
{ |
||||
return xcache_isset($id); |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doSave($id, $data, $lifeTime = 0) |
||||
{ |
||||
return xcache_set($id, serialize($data), (int) $lifeTime); |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doDelete($id) |
||||
{ |
||||
return xcache_unset($id); |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doFlush() |
||||
{ |
||||
$this->checkAuthorization(); |
||||
|
||||
xcache_clear_cache(XC_TYPE_VAR, 0); |
||||
|
||||
return true; |
||||
} |
||||
|
||||
/** |
||||
* Checks that xcache.admin.enable_auth is Off |
||||
* |
||||
* @throws \BadMethodCallException When xcache.admin.enable_auth is On |
||||
* @return void |
||||
*/ |
||||
protected function checkAuthorization() |
||||
{ |
||||
if (ini_get('xcache.admin.enable_auth')) { |
||||
throw new \BadMethodCallException('To use all features of \Doctrine\Common\Cache\XcacheCache, you must set "xcache.admin.enable_auth" to "Off" in your php.ini.'); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doGetStats() |
||||
{ |
||||
$this->checkAuthorization(); |
||||
|
||||
$info = xcache_info(XC_TYPE_VAR, 0); |
||||
return array( |
||||
Cache::STATS_HITS => $info['hits'], |
||||
Cache::STATS_MISSES => $info['misses'], |
||||
Cache::STATS_UPTIME => null, |
||||
Cache::STATS_MEMORY_USAGE => $info['size'], |
||||
Cache::STATS_MEMORY_AVAILIABLE => $info['avail'], |
||||
); |
||||
} |
||||
} |
@ -0,0 +1,84 @@ |
||||
<?php |
||||
/* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
* This software consists of voluntary contributions made by many individuals |
||||
* and is licensed under the MIT license. For more information, see |
||||
* <http://www.doctrine-project.org>. |
||||
*/ |
||||
|
||||
namespace Doctrine\Common\Cache; |
||||
|
||||
/** |
||||
* Zend Data Cache cache driver. |
||||
* |
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL |
||||
* @link www.doctrine-project.org |
||||
* @since 2.0 |
||||
* @author Ralph Schindler <ralph.schindler@zend.com> |
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com> |
||||
*/ |
||||
class ZendDataCache extends CacheProvider |
||||
{ |
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doFetch($id) |
||||
{ |
||||
return zend_shm_cache_fetch($id); |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doContains($id) |
||||
{ |
||||
return (false !== zend_shm_cache_fetch($id)); |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doSave($id, $data, $lifeTime = 0) |
||||
{ |
||||
return zend_shm_cache_store($id, $data, $lifeTime); |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doDelete($id) |
||||
{ |
||||
return zend_shm_cache_delete($id); |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doFlush() |
||||
{ |
||||
$namespace = $this->getNamespace(); |
||||
if (empty($namespace)) { |
||||
return zend_shm_cache_clear(); |
||||
} |
||||
return zend_shm_cache_clear($namespace); |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function doGetStats() |
||||
{ |
||||
return null; |
||||
} |
||||
} |
@ -0,0 +1,31 @@ |
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
||||
<phpunit backupGlobals="false" |
||||
backupStaticAttributes="false" |
||||
colors="true" |
||||
convertErrorsToExceptions="true" |
||||
convertNoticesToExceptions="true" |
||||
convertWarningsToExceptions="true" |
||||
processIsolation="false" |
||||
stopOnFailure="false" |
||||
syntaxCheck="false" |
||||
bootstrap="./tests/Doctrine/Tests/TestInit.php" |
||||
> |
||||
<testsuites> |
||||
<testsuite name="Doctrine Cache Test Suite"> |
||||
<directory>./tests/Doctrine/</directory> |
||||
</testsuite> |
||||
</testsuites> |
||||
|
||||
<filter> |
||||
<whitelist> |
||||
<directory>./lib/Doctrine/</directory> |
||||
</whitelist> |
||||
</filter> |
||||
|
||||
<groups> |
||||
<exclude> |
||||
<group>performance</group> |
||||
</exclude> |
||||
</groups> |
||||
</phpunit> |
@ -0,0 +1,20 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Cache; |
||||
|
||||
use Doctrine\Common\Cache\ApcCache; |
||||
|
||||
class ApcCacheTest extends CacheTest |
||||
{ |
||||
public function setUp() |
||||
{ |
||||
if ( ! extension_loaded('apc') || false === @apc_cache_info()) { |
||||
$this->markTestSkipped('The ' . __CLASS__ .' requires the use of APC'); |
||||
} |
||||
} |
||||
|
||||
protected function _getCacheDriver() |
||||
{ |
||||
return new ApcCache(); |
||||
} |
||||
} |
@ -0,0 +1,21 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Cache; |
||||
|
||||
use Doctrine\Common\Cache\ArrayCache; |
||||
|
||||
class ArrayCacheTest extends CacheTest |
||||
{ |
||||
protected function _getCacheDriver() |
||||
{ |
||||
return new ArrayCache(); |
||||
} |
||||
|
||||
public function testGetStats() |
||||
{ |
||||
$cache = $this->_getCacheDriver(); |
||||
$stats = $cache->getStats(); |
||||
|
||||
$this->assertNull($stats); |
||||
} |
||||
} |
@ -0,0 +1,103 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Cache; |
||||
|
||||
use Doctrine\Common\Cache\Cache; |
||||
|
||||
abstract class CacheTest extends \Doctrine\Tests\DoctrineTestCase |
||||
{ |
||||
public function testBasics() |
||||
{ |
||||
$cache = $this->_getCacheDriver(); |
||||
|
||||
// Test save |
||||
$cache->save('test_key', 'testing this out'); |
||||
|
||||
// Test contains to test that save() worked |
||||
$this->assertTrue($cache->contains('test_key')); |
||||
|
||||
// Test fetch |
||||
$this->assertEquals('testing this out', $cache->fetch('test_key')); |
||||
|
||||
// Test delete |
||||
$cache->save('test_key2', 'test2'); |
||||
$cache->delete('test_key2'); |
||||
$this->assertFalse($cache->contains('test_key2')); |
||||
} |
||||
|
||||
public function testObjects() |
||||
{ |
||||
$cache = $this->_getCacheDriver(); |
||||
|
||||
// Fetch/save test with objects (Is cache driver serializes/unserializes objects correctly ?) |
||||
$cache->save('test_object_key', new \ArrayObject()); |
||||
$this->assertTrue($cache->fetch('test_object_key') instanceof \ArrayObject); |
||||
} |
||||
|
||||
public function testDeleteAll() |
||||
{ |
||||
$cache = $this->_getCacheDriver(); |
||||
$cache->save('test_key1', '1'); |
||||
$cache->save('test_key2', '2'); |
||||
$cache->deleteAll(); |
||||
|
||||
$this->assertFalse($cache->contains('test_key1')); |
||||
$this->assertFalse($cache->contains('test_key2')); |
||||
} |
||||
|
||||
public function testFlushAll() |
||||
{ |
||||
$cache = $this->_getCacheDriver(); |
||||
$cache->save('test_key1', '1'); |
||||
$cache->save('test_key2', '2'); |
||||
$cache->flushAll(); |
||||
|
||||
$this->assertFalse($cache->contains('test_key1')); |
||||
$this->assertFalse($cache->contains('test_key2')); |
||||
} |
||||
|
||||
public function testNamespace() |
||||
{ |
||||
$cache = $this->_getCacheDriver(); |
||||
$cache->setNamespace('test_'); |
||||
$cache->save('key1', 'test'); |
||||
|
||||
$this->assertTrue($cache->contains('key1')); |
||||
|
||||
$cache->setNamespace('test2_'); |
||||
|
||||
$this->assertFalse($cache->contains('key1')); |
||||
} |
||||
|
||||
/** |
||||
* @group DCOM-43 |
||||
*/ |
||||
public function testGetStats() |
||||
{ |
||||
$cache = $this->_getCacheDriver(); |
||||
$stats = $cache->getStats(); |
||||
|
||||
$this->assertArrayHasKey(Cache::STATS_HITS, $stats); |
||||
$this->assertArrayHasKey(Cache::STATS_MISSES, $stats); |
||||
$this->assertArrayHasKey(Cache::STATS_UPTIME, $stats); |
||||
$this->assertArrayHasKey(Cache::STATS_MEMORY_USAGE, $stats); |
||||
$this->assertArrayHasKey(Cache::STATS_MEMORY_AVAILIABLE, $stats); |
||||
} |
||||
|
||||
/** |
||||
* Make sure that all supported caches return "false" instead of "null" to be compatible |
||||
* with ORM integration. |
||||
*/ |
||||
public function testFalseOnFailedFetch() |
||||
{ |
||||
$cache = $this->_getCacheDriver(); |
||||
$result = $cache->fetch('nonexistent_key'); |
||||
$this->assertFalse($result); |
||||
$this->assertNotNull($result); |
||||
} |
||||
|
||||
/** |
||||
* @return \Doctrine\Common\Cache\CacheProvider |
||||
*/ |
||||
abstract protected function _getCacheDriver(); |
||||
} |
@ -0,0 +1,47 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Cache; |
||||
|
||||
use Couchbase; |
||||
use Doctrine\Common\Cache\CouchbaseCache; |
||||
|
||||
class CouchbaseCacheTest extends CacheTest |
||||
{ |
||||
private $couchbase; |
||||
|
||||
public function setUp() |
||||
{ |
||||
if (extension_loaded('couchbase')) { |
||||
try { |
||||
$this->couchbase = new Couchbase('127.0.0.1', 'Administrator', 'password', 'default'); |
||||
} catch(Exception $ex) { |
||||
$this->markTestSkipped('Could not instantiate the Couchbase cache because of: ' . $ex); |
||||
} |
||||
} else { |
||||
$this->markTestSkipped('The ' . __CLASS__ .' requires the use of the couchbase extension'); |
||||
} |
||||
} |
||||
|
||||
public function testNoExpire() |
||||
{ |
||||
$cache = $this->_getCacheDriver(); |
||||
$cache->save('noexpire', 'value', 0); |
||||
sleep(1); |
||||
$this->assertTrue($cache->contains('noexpire'), 'Couchbase provider should support no-expire'); |
||||
} |
||||
|
||||
public function testLongLifetime() |
||||
{ |
||||
$cache = $this->_getCacheDriver(); |
||||
$cache->save('key', 'value', 30 * 24 * 3600 + 1); |
||||
|
||||
$this->assertTrue($cache->contains('key'), 'Couchbase provider should support TTL > 30 days'); |
||||
} |
||||
|
||||
protected function _getCacheDriver() |
||||
{ |
||||
$driver = new CouchbaseCache(); |
||||
$driver->setCouchbase($this->couchbase); |
||||
return $driver; |
||||
} |
||||
} |
@ -0,0 +1,97 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Cache; |
||||
|
||||
use Doctrine\Common\Cache\FilesystemCache; |
||||
|
||||
/** |
||||
* @group DCOM-101 |
||||
*/ |
||||
class FilesystemCacheTest extends CacheTest |
||||
{ |
||||
/** |
||||
* @var \Doctrine\Common\Cache\FilesystemCache |
||||
*/ |
||||
private $driver; |
||||
|
||||
protected function _getCacheDriver() |
||||
{ |
||||
$dir = sys_get_temp_dir() . "/doctrine_cache_". uniqid(); |
||||
$this->assertFalse(is_dir($dir)); |
||||
|
||||
$this->driver = new FilesystemCache($dir); |
||||
$this->assertTrue(is_dir($dir)); |
||||
|
||||
return $this->driver; |
||||
} |
||||
|
||||
public function testLifetime() |
||||
{ |
||||
$cache = $this->_getCacheDriver(); |
||||
|
||||
// Test save |
||||
$cache->save('test_key', 'testing this out', 10); |
||||
|
||||
// Test contains to test that save() worked |
||||
$this->assertTrue($cache->contains('test_key')); |
||||
|
||||
// Test fetch |
||||
$this->assertEquals('testing this out', $cache->fetch('test_key')); |
||||
|
||||
// access private methods |
||||
$getFilename = new \ReflectionMethod($cache, 'getFilename'); |
||||
$getNamespacedId = new \ReflectionMethod($cache, 'getNamespacedId'); |
||||
|
||||
$getFilename->setAccessible(true); |
||||
$getNamespacedId->setAccessible(true); |
||||
|
||||
$id = $getNamespacedId->invoke($cache, 'test_key'); |
||||
$filename = $getFilename->invoke($cache, $id); |
||||
|
||||
$data = ''; |
||||
$lifetime = 0; |
||||
$resource = fopen($filename, "r"); |
||||
|
||||
if (false !== ($line = fgets($resource))) { |
||||
$lifetime = (integer) $line; |
||||
} |
||||
|
||||
while (false !== ($line = fgets($resource))) { |
||||
$data .= $line; |
||||
} |
||||
|
||||
$this->assertNotEquals(0, $lifetime, "previous lifetime could not be loaded"); |
||||
|
||||
// update lifetime |
||||
$lifetime = $lifetime - 20; |
||||
file_put_contents($filename, $lifetime . PHP_EOL . $data); |
||||
|
||||
// test expired data |
||||
$this->assertFalse($cache->contains('test_key')); |
||||
$this->assertFalse($cache->fetch('test_key')); |
||||
} |
||||
|
||||
public function testGetStats() |
||||
{ |
||||
$cache = $this->_getCacheDriver(); |
||||
$stats = $cache->getStats(); |
||||
|
||||
$this->assertNull($stats); |
||||
} |
||||
|
||||
public function tearDown() |
||||
{ |
||||
$dir = $this->driver->getDirectory(); |
||||
$ext = $this->driver->getExtension(); |
||||
$iterator = new \RecursiveDirectoryIterator($dir); |
||||
|
||||
foreach (new \RecursiveIteratorIterator($iterator, \RecursiveIteratorIterator::CHILD_FIRST) as $file) { |
||||
if ($file->isFile()) { |
||||
@unlink($file->getRealPath()); |
||||
} else { |
||||
@rmdir($file->getRealPath()); |
||||
} |
||||
} |
||||
} |
||||
|
||||
} |
@ -0,0 +1,45 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Cache; |
||||
|
||||
use Doctrine\Common\Cache\MemcacheCache; |
||||
|
||||
class MemcacheCacheTest extends CacheTest |
||||
{ |
||||
private $_memcache; |
||||
|
||||
public function setUp() |
||||
{ |
||||
if (extension_loaded('memcache')) { |
||||
$this->_memcache = new \Memcache; |
||||
$ok = @$this->_memcache->connect('localhost', 11211); |
||||
if (!$ok) { |
||||
$this->markTestSkipped('The ' . __CLASS__ .' requires the use of memcache'); |
||||
} |
||||
} else { |
||||
$this->markTestSkipped('The ' . __CLASS__ .' requires the use of memcache'); |
||||
} |
||||
} |
||||
|
||||
public function testNoExpire() { |
||||
$cache = $this->_getCacheDriver(); |
||||
$cache->save('noexpire', 'value', 0); |
||||
sleep(1); |
||||
$this->assertTrue($cache->contains('noexpire'), 'Memcache provider should support no-expire'); |
||||
} |
||||
|
||||
public function testLongLifetime() |
||||
{ |
||||
$cache = $this->_getCacheDriver(); |
||||
$cache->save('key', 'value', 30 * 24 * 3600 + 1); |
||||
$this->assertTrue($cache->contains('key'), 'Memcache provider should support TTL > 30 days'); |
||||
} |
||||
|
||||
protected function _getCacheDriver() |
||||
{ |
||||
$driver = new MemcacheCache(); |
||||
$driver->setMemcache($this->_memcache); |
||||
return $driver; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,48 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Cache; |
||||
|
||||
use Doctrine\Common\Cache\MemcachedCache; |
||||
|
||||
class MemcachedCacheTest extends CacheTest |
||||
{ |
||||
private $memcached; |
||||
|
||||
public function setUp() |
||||
{ |
||||
if (extension_loaded('memcached')) { |
||||
$this->memcached = new \Memcached(); |
||||
$this->memcached->setOption(\Memcached::OPT_COMPRESSION, false); |
||||
$this->memcached->addServer('127.0.0.1', 11211); |
||||
|
||||
$fh = @fsockopen('127.0.0.1', 11211); |
||||
if (!$fh) { |
||||
$this->markTestSkipped('The ' . __CLASS__ .' requires the use of memcache'); |
||||
} |
||||
} else { |
||||
$this->markTestSkipped('The ' . __CLASS__ .' requires the use of memcache'); |
||||
} |
||||
} |
||||
|
||||
public function testNoExpire() { |
||||
$cache = $this->_getCacheDriver(); |
||||
$cache->save('noexpire', 'value', 0); |
||||
sleep(1); |
||||
$this->assertTrue($cache->contains('noexpire'), 'Memcache provider should support no-expire'); |
||||
} |
||||
|
||||
public function testLongLifetime() |
||||
{ |
||||
$cache = $this->_getCacheDriver(); |
||||
$cache->save('key', 'value', 30 * 24 * 3600 + 1); |
||||
|
||||
$this->assertTrue($cache->contains('key'), 'Memcached provider should support TTL > 30 days'); |
||||
} |
||||
|
||||
protected function _getCacheDriver() |
||||
{ |
||||
$driver = new MemcachedCache(); |
||||
$driver->setMemcached($this->memcached); |
||||
return $driver; |
||||
} |
||||
} |
@ -0,0 +1,149 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Cache; |
||||
|
||||
use Doctrine\Common\Cache\PhpFileCache; |
||||
|
||||
/** |
||||
* @group DCOM-101 |
||||
*/ |
||||
class PhpFileCacheTest extends CacheTest |
||||
{ |
||||
/** |
||||
* @var \Doctrine\Common\Cache\PhpFileCache |
||||
*/ |
||||
private $driver; |
||||
|
||||
protected function _getCacheDriver() |
||||
{ |
||||
$dir = sys_get_temp_dir() . "/doctrine_cache_". uniqid(); |
||||
$this->assertFalse(is_dir($dir)); |
||||
|
||||
$this->driver = new PhpFileCache($dir); |
||||
$this->assertTrue(is_dir($dir)); |
||||
|
||||
return $this->driver; |
||||
} |
||||
|
||||
public function testObjects() |
||||
{ |
||||
$this->markTestSkipped('PhpFileCache does not support saving objects that dont implement __set_state()'); |
||||
} |
||||
|
||||
public function testLifetime() |
||||
{ |
||||
$cache = $this->_getCacheDriver(); |
||||
|
||||
// Test save |
||||
$cache->save('test_key', 'testing this out', 10); |
||||
|
||||
// Test contains to test that save() worked |
||||
$this->assertTrue($cache->contains('test_key')); |
||||
|
||||
// Test fetch |
||||
$this->assertEquals('testing this out', $cache->fetch('test_key')); |
||||
|
||||
// access private methods |
||||
$getFilename = new \ReflectionMethod($cache, 'getFilename'); |
||||
$getNamespacedId = new \ReflectionMethod($cache, 'getNamespacedId'); |
||||
|
||||
$getFilename->setAccessible(true); |
||||
$getNamespacedId->setAccessible(true); |
||||
|
||||
$id = $getNamespacedId->invoke($cache, 'test_key'); |
||||
$path = $getFilename->invoke($cache, $id); |
||||
$value = include $path; |
||||
|
||||
// update lifetime |
||||
$value['lifetime'] = $value['lifetime'] - 20; |
||||
file_put_contents($path, '<?php return unserialize(' . var_export(serialize($value), true) . ');'); |
||||
|
||||
// test expired data |
||||
$this->assertFalse($cache->contains('test_key')); |
||||
$this->assertFalse($cache->fetch('test_key')); |
||||
} |
||||
|
||||
public function testImplementsSetState() |
||||
{ |
||||
$cache = $this->_getCacheDriver(); |
||||
|
||||
// Test save |
||||
$cache->save('test_set_state', new SetStateClass(array(1,2,3))); |
||||
|
||||
//Test __set_state call |
||||
$this->assertCount(0, SetStateClass::$values); |
||||
|
||||
// Test fetch |
||||
$value = $cache->fetch('test_set_state'); |
||||
$this->assertInstanceOf('Doctrine\Tests\Common\Cache\SetStateClass', $value); |
||||
$this->assertEquals(array(1,2,3), $value->getValue()); |
||||
|
||||
//Test __set_state call |
||||
$this->assertCount(1, SetStateClass::$values); |
||||
|
||||
// Test contains |
||||
$this->assertTrue($cache->contains('test_set_state')); |
||||
} |
||||
|
||||
public function testNotImplementsSetState() |
||||
{ |
||||
$cache = $this->_getCacheDriver(); |
||||
|
||||
$this->setExpectedException('InvalidArgumentException'); |
||||
$cache->save('test_not_set_state', new NotSetStateClass(array(1,2,3))); |
||||
} |
||||
|
||||
public function testGetStats() |
||||
{ |
||||
$cache = $this->_getCacheDriver(); |
||||
$stats = $cache->getStats(); |
||||
|
||||
$this->assertNull($stats); |
||||
} |
||||
|
||||
public function tearDown() |
||||
{ |
||||
if (!$this->driver) { |
||||
return; |
||||
} |
||||
|
||||
$dir = $this->driver->getDirectory(); |
||||
$ext = $this->driver->getExtension(); |
||||
$iterator = new \RecursiveDirectoryIterator($dir); |
||||
|
||||
foreach (new \RecursiveIteratorIterator($iterator, \RecursiveIteratorIterator::CHILD_FIRST) as $file) { |
||||
if ($file->isFile()) { |
||||
@unlink($file->getRealPath()); |
||||
} else { |
||||
@rmdir($file->getRealPath()); |
||||
} |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
class NotSetStateClass |
||||
{ |
||||
private $value; |
||||
|
||||
public function __construct($value) |
||||
{ |
||||
$this->value = $value; |
||||
} |
||||
|
||||
public function getValue() |
||||
{ |
||||
return $this->value; |
||||
} |
||||
} |
||||
|
||||
class SetStateClass extends NotSetStateClass |
||||
{ |
||||
public static $values = array(); |
||||
|
||||
public static function __set_state($data) |
||||
{ |
||||
self::$values = $data; |
||||
return new self($data['value']); |
||||
} |
||||
} |
@ -0,0 +1,30 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Cache; |
||||
|
||||
use Doctrine\Common\Cache\RedisCache; |
||||
|
||||
class RedisCacheTest extends CacheTest |
||||
{ |
||||
private $_redis; |
||||
|
||||
public function setUp() |
||||
{ |
||||
if (extension_loaded('redis')) { |
||||
$this->_redis = new \Redis(); |
||||
$ok = @$this->_redis->connect('127.0.0.1'); |
||||
if (!$ok) { |
||||
$this->markTestSkipped('The ' . __CLASS__ .' requires the use of redis'); |
||||
} |
||||
} else { |
||||
$this->markTestSkipped('The ' . __CLASS__ .' requires the use of redis'); |
||||
} |
||||
} |
||||
|
||||
protected function _getCacheDriver() |
||||
{ |
||||
$driver = new RedisCache(); |
||||
$driver->setRedis($this->_redis); |
||||
return $driver; |
||||
} |
||||
} |
@ -0,0 +1,20 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Cache; |
||||
|
||||
use Doctrine\Common\Cache\WincacheCache; |
||||
|
||||
class WincacheCacheTest extends CacheTest |
||||
{ |
||||
public function setUp() |
||||
{ |
||||
if ( ! extension_loaded('wincache') || ! function_exists('wincache_ucache_info')) { |
||||
$this->markTestSkipped('The ' . __CLASS__ .' requires the use of Wincache'); |
||||
} |
||||
} |
||||
|
||||
protected function _getCacheDriver() |
||||
{ |
||||
return new WincacheCache(); |
||||
} |
||||
} |
@ -0,0 +1,20 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Cache; |
||||
|
||||
use Doctrine\Common\Cache\XcacheCache; |
||||
|
||||
class XcacheCacheTest extends CacheTest |
||||
{ |
||||
public function setUp() |
||||
{ |
||||
if ( ! extension_loaded('xcache')) { |
||||
$this->markTestSkipped('The ' . __CLASS__ .' requires the use of xcache'); |
||||
} |
||||
} |
||||
|
||||
protected function _getCacheDriver() |
||||
{ |
||||
return new XcacheCache(); |
||||
} |
||||
} |
@ -0,0 +1,28 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Cache; |
||||
|
||||
use Doctrine\Common\Cache\ZendDataCache; |
||||
|
||||
class ZendDataCacheTest extends CacheTest |
||||
{ |
||||
public function setUp() |
||||
{ |
||||
if (!function_exists('zend_shm_cache_fetch') || (php_sapi_name() != 'apache2handler')) { |
||||
$this->markTestSkipped('The ' . __CLASS__ .' requires the use of Zend Data Cache which only works in apache2handler SAPI'); |
||||
} |
||||
} |
||||
|
||||
public function testGetStats() |
||||
{ |
||||
$cache = $this->_getCacheDriver(); |
||||
$stats = $cache->getStats(); |
||||
|
||||
$this->assertNull($stats); |
||||
} |
||||
|
||||
protected function _getCacheDriver() |
||||
{ |
||||
return new ZendDataCache(); |
||||
} |
||||
} |
@ -0,0 +1,10 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests; |
||||
|
||||
/** |
||||
* Base testcase class for all Doctrine testcases. |
||||
*/ |
||||
abstract class DoctrineTestCase extends \PHPUnit_Framework_TestCase |
||||
{ |
||||
} |
@ -0,0 +1,23 @@ |
||||
<?php |
||||
/* |
||||
* This file bootstraps the test environment. |
||||
*/ |
||||
namespace Doctrine\Tests; |
||||
|
||||
error_reporting(E_ALL | E_STRICT); |
||||
|
||||
// register silently failing autoloader |
||||
spl_autoload_register(function($class) |
||||
{ |
||||
if (0 === strpos($class, 'Doctrine\Tests\\')) { |
||||
$path = __DIR__.'/../../'.strtr($class, '\\', '/').'.php'; |
||||
if (is_file($path) && is_readable($path)) { |
||||
require_once $path; |
||||
|
||||
return true; |
||||
} |
||||
} |
||||
}); |
||||
|
||||
require_once __DIR__ . "/../../../vendor/autoload.php"; |
||||
|
@ -0,0 +1,4 @@ |
||||
# Doctrine Inflector |
||||
|
||||
Doctrine Inflector is a small library that can perform string manipulations |
||||
with regard to upper-/lowercase and singular/plural forms of words. |
@ -0,0 +1,21 @@ |
||||
{ |
||||
"name": "doctrine/inflector", |
||||
"type": "library", |
||||
"description": "Common String Manipulations with regard to casing and singular/plural rules.", |
||||
"keywords": ["string", "inflection", "singuarlize", "pluarlize"], |
||||
"homepage": "http://www.doctrine-project.org", |
||||
"license": "MIT", |
||||
"authors": [ |
||||
{"name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com"}, |
||||
{"name": "Roman Borschel", "email": "roman@code-factory.org"}, |
||||
{"name": "Benjamin Eberlei", "email": "kontakt@beberlei.de"}, |
||||
{"name": "Jonathan Wage", "email": "jonwage@gmail.com"}, |
||||
{"name": "Johannes Schmitt", "email": "schmittjoh@gmail.com"} |
||||
], |
||||
"require": { |
||||
"php": ">=5.3.2" |
||||
}, |
||||
"autoload": { |
||||
"psr-0": { "Doctrine\\Common\\Inflector\\": "lib/" } |
||||
} |
||||
} |
@ -0,0 +1,385 @@ |
||||
<?php |
||||
/* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
* This software consists of voluntary contributions made by many individuals |
||||
* and is licensed under the MIT license. For more information, see |
||||
* <http://www.doctrine-project.org>. |
||||
*/ |
||||
|
||||
namespace Doctrine\Common\Inflector; |
||||
|
||||
/** |
||||
* Doctrine inflector has static methods for inflecting text |
||||
* |
||||
* The methods in these classes are from several different sources collected |
||||
* across several different php projects and several different authors. The |
||||
* original author names and emails are not known. |
||||
* |
||||
* Plurialize & Singularize implementation are borrowed from CakePHP with some modifications. |
||||
* |
||||
* @link www.doctrine-project.org |
||||
* @since 1.0 |
||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi> |
||||
* @author Jonathan H. Wage <jonwage@gmail.com> |
||||
*/ |
||||
class Inflector |
||||
{ |
||||
/** |
||||
* Plural inflector rules |
||||
* |
||||
* @var array |
||||
*/ |
||||
private static $plural = array( |
||||
'rules' => array( |
||||
'/(s)tatus$/i' => '\1\2tatuses', |
||||
'/(quiz)$/i' => '\1zes', |
||||
'/^(ox)$/i' => '\1\2en', |
||||
'/([m|l])ouse$/i' => '\1ice', |
||||
'/(matr|vert|ind)(ix|ex)$/i' => '\1ices', |
||||
'/(x|ch|ss|sh)$/i' => '\1es', |
||||
'/([^aeiouy]|qu)y$/i' => '\1ies', |
||||
'/(hive)$/i' => '\1s', |
||||
'/(?:([^f])fe|([lr])f)$/i' => '\1\2ves', |
||||
'/sis$/i' => 'ses', |
||||
'/([ti])um$/i' => '\1a', |
||||
'/(p)erson$/i' => '\1eople', |
||||
'/(m)an$/i' => '\1en', |
||||
'/(c)hild$/i' => '\1hildren', |
||||
'/(buffal|tomat)o$/i' => '\1\2oes', |
||||
'/(alumn|bacill|cact|foc|fung|nucle|radi|stimul|syllab|termin|vir)us$/i' => '\1i', |
||||
'/us$/i' => 'uses', |
||||
'/(alias)$/i' => '\1es', |
||||
'/(ax|cris|test)is$/i' => '\1es', |
||||
'/s$/' => 's', |
||||
'/^$/' => '', |
||||
'/$/' => 's', |
||||
), |
||||
'uninflected' => array( |
||||
'.*[nrlm]ese', '.*deer', '.*fish', '.*measles', '.*ois', '.*pox', '.*sheep', 'people', 'cookie' |
||||
), |
||||
'irregular' => array( |
||||
'atlas' => 'atlases', |
||||
'beef' => 'beefs', |
||||
'brother' => 'brothers', |
||||
'cafe' => 'cafes', |
||||
'child' => 'children', |
||||
'cookie' => 'cookies', |
||||
'corpus' => 'corpuses', |
||||
'cow' => 'cows', |
||||
'ganglion' => 'ganglions', |
||||
'genie' => 'genies', |
||||
'genus' => 'genera', |
||||
'graffito' => 'graffiti', |
||||
'hoof' => 'hoofs', |
||||
'loaf' => 'loaves', |
||||
'man' => 'men', |
||||
'money' => 'monies', |
||||
'mongoose' => 'mongooses', |
||||
'move' => 'moves', |
||||
'mythos' => 'mythoi', |
||||
'niche' => 'niches', |
||||
'numen' => 'numina', |
||||
'occiput' => 'occiputs', |
||||
'octopus' => 'octopuses', |
||||
'opus' => 'opuses', |
||||
'ox' => 'oxen', |
||||
'penis' => 'penises', |
||||
'person' => 'people', |
||||
'sex' => 'sexes', |
||||
'soliloquy' => 'soliloquies', |
||||
'testis' => 'testes', |
||||
'trilby' => 'trilbys', |
||||
'turf' => 'turfs' |
||||
) |
||||
); |
||||
|
||||
/** |
||||
* Singular inflector rules |
||||
* |
||||
* @var array |
||||
*/ |
||||
private static $singular = array( |
||||
'rules' => array( |
||||
'/(s)tatuses$/i' => '\1\2tatus', |
||||
'/^(.*)(menu)s$/i' => '\1\2', |
||||
'/(quiz)zes$/i' => '\\1', |
||||
'/(matr)ices$/i' => '\1ix', |
||||
'/(vert|ind)ices$/i' => '\1ex', |
||||
'/^(ox)en/i' => '\1', |
||||
'/(alias)(es)*$/i' => '\1', |
||||
'/(alumn|bacill|cact|foc|fung|nucle|radi|stimul|syllab|termin|viri?)i$/i' => '\1us', |
||||
'/([ftw]ax)es/i' => '\1', |
||||
'/(cris|ax|test)es$/i' => '\1is', |
||||
'/(shoe|slave)s$/i' => '\1', |
||||
'/(o)es$/i' => '\1', |
||||
'/ouses$/' => 'ouse', |
||||
'/([^a])uses$/' => '\1us', |
||||
'/([m|l])ice$/i' => '\1ouse', |
||||
'/(x|ch|ss|sh)es$/i' => '\1', |
||||
'/(m)ovies$/i' => '\1\2ovie', |
||||
'/(s)eries$/i' => '\1\2eries', |
||||
'/([^aeiouy]|qu)ies$/i' => '\1y', |
||||
'/([lr])ves$/i' => '\1f', |
||||
'/(tive)s$/i' => '\1', |
||||
'/(hive)s$/i' => '\1', |
||||
'/(drive)s$/i' => '\1', |
||||
'/([^fo])ves$/i' => '\1fe', |
||||
'/(^analy)ses$/i' => '\1sis', |
||||
'/(analy|diagno|^ba|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i' => '\1\2sis', |
||||
'/([ti])a$/i' => '\1um', |
||||
'/(p)eople$/i' => '\1\2erson', |
||||
'/(m)en$/i' => '\1an', |
||||
'/(c)hildren$/i' => '\1\2hild', |
||||
'/(n)ews$/i' => '\1\2ews', |
||||
'/eaus$/' => 'eau', |
||||
'/^(.*us)$/' => '\\1', |
||||
'/s$/i' => '' |
||||
), |
||||
'uninflected' => array( |
||||
'.*[nrlm]ese', '.*deer', '.*fish', '.*measles', '.*ois', '.*pox', '.*sheep', '.*ss' |
||||
), |
||||
'irregular' => array( |
||||
'foes' => 'foe', |
||||
'waves' => 'wave', |
||||
'curves' => 'curve' |
||||
) |
||||
); |
||||
|
||||
/** |
||||
* Words that should not be inflected |
||||
* |
||||
* @var array |
||||
*/ |
||||
private static $uninflected = array( |
||||
'Amoyese', 'bison', 'Borghese', 'bream', 'breeches', 'britches', 'buffalo', 'cantus', |
||||
'carp', 'chassis', 'clippers', 'cod', 'coitus', 'Congoese', 'contretemps', 'corps', |
||||
'debris', 'diabetes', 'djinn', 'eland', 'elk', 'equipment', 'Faroese', 'flounder', |
||||
'Foochowese', 'gallows', 'Genevese', 'Genoese', 'Gilbertese', 'graffiti', |
||||
'headquarters', 'herpes', 'hijinks', 'Hottentotese', 'information', 'innings', |
||||
'jackanapes', 'Kiplingese', 'Kongoese', 'Lucchese', 'mackerel', 'Maltese', '.*?media', |
||||
'mews', 'moose', 'mumps', 'Nankingese', 'news', 'nexus', 'Niasese', |
||||
'Pekingese', 'Piedmontese', 'pincers', 'Pistoiese', 'pliers', 'Portuguese', |
||||
'proceedings', 'rabies', 'rice', 'rhinoceros', 'salmon', 'Sarawakese', 'scissors', |
||||
'sea[- ]bass', 'series', 'Shavese', 'shears', 'siemens', 'species', 'swine', 'testes', |
||||
'trousers', 'trout', 'tuna', 'Vermontese', 'Wenchowese', 'whiting', 'wildebeest', |
||||
'Yengeese' |
||||
); |
||||
|
||||
/** |
||||
* Method cache array. |
||||
* |
||||
* @var array |
||||
*/ |
||||
private static $cache = array(); |
||||
|
||||
/** |
||||
* The initial state of Inflector so reset() works. |
||||
* |
||||
* @var array |
||||
*/ |
||||
private static $initialState = array(); |
||||
|
||||
/** |
||||
* Convert word in to the format for a Doctrine table name. Converts 'ModelName' to 'model_name' |
||||
* |
||||
* @param string $word Word to tableize |
||||
* @return string $word Tableized word |
||||
*/ |
||||
public static function tableize($word) |
||||
{ |
||||
return strtolower(preg_replace('~(?<=\\w)([A-Z])~', '_$1', $word)); |
||||
} |
||||
|
||||
/** |
||||
* Convert a word in to the format for a Doctrine class name. Converts 'table_name' to 'TableName' |
||||
* |
||||
* @param string $word Word to classify |
||||
* @return string $word Classified word |
||||
*/ |
||||
public static function classify($word) |
||||
{ |
||||
return str_replace(" ", "", ucwords(strtr($word, "_-", " "))); |
||||
} |
||||
|
||||
/** |
||||
* Camelize a word. This uses the classify() method and turns the first character to lowercase |
||||
* |
||||
* @param string $word |
||||
* @return string $word |
||||
*/ |
||||
public static function camelize($word) |
||||
{ |
||||
return lcfirst(self::classify($word)); |
||||
} |
||||
|
||||
/** |
||||
* Clears Inflectors inflected value caches. And resets the inflection |
||||
* rules to the initial values. |
||||
* |
||||
* @return void |
||||
*/ |
||||
public static function reset() |
||||
{ |
||||
if (empty(self::$initialState)) { |
||||
self::$initialState = get_class_vars('Inflector'); |
||||
return; |
||||
} |
||||
foreach (self::$initialState as $key => $val) { |
||||
if ($key != 'initialState') { |
||||
self::${$key} = $val; |
||||
} |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Adds custom inflection $rules, of either 'plural' or 'singular' $type. |
||||
* |
||||
* ### Usage: |
||||
* |
||||
* {{{ |
||||
* Inflector::rules('plural', array('/^(inflect)or$/i' => '\1ables')); |
||||
* Inflector::rules('plural', array( |
||||
* 'rules' => array('/^(inflect)ors$/i' => '\1ables'), |
||||
* 'uninflected' => array('dontinflectme'), |
||||
* 'irregular' => array('red' => 'redlings') |
||||
* )); |
||||
* }}} |
||||
* |
||||
* @param string $type The type of inflection, either 'plural' or 'singular' |
||||
* @param array $rules Array of rules to be added. |
||||
* @param boolean $reset If true, will unset default inflections for all |
||||
* new rules that are being defined in $rules. |
||||
* @return void |
||||
*/ |
||||
public static function rules($type, $rules, $reset = false) |
||||
{ |
||||
foreach ($rules as $rule => $pattern) { |
||||
if (is_array($pattern)) { |
||||
if ($reset) { |
||||
self::${$type}[$rule] = $pattern; |
||||
} else { |
||||
if ($rule === 'uninflected') { |
||||
self::${$type}[$rule] = array_merge($pattern, self::${$type}[$rule]); |
||||
} else { |
||||
self::${$type}[$rule] = $pattern + self::${$type}[$rule]; |
||||
} |
||||
} |
||||
unset($rules[$rule], self::${$type}['cache' . ucfirst($rule)]); |
||||
if (isset(self::${$type}['merged'][$rule])) { |
||||
unset(self::${$type}['merged'][$rule]); |
||||
} |
||||
if ($type === 'plural') { |
||||
self::$cache['pluralize'] = self::$cache['tableize'] = array(); |
||||
} elseif ($type === 'singular') { |
||||
self::$cache['singularize'] = array(); |
||||
} |
||||
} |
||||
} |
||||
self::${$type}['rules'] = $rules + self::${$type}['rules']; |
||||
} |
||||
|
||||
/** |
||||
* Return $word in plural form. |
||||
* |
||||
* @param string $word Word in singular |
||||
* @return string Word in plural |
||||
*/ |
||||
public static function pluralize($word) |
||||
{ |
||||
if (isset(self::$cache['pluralize'][$word])) { |
||||
return self::$cache['pluralize'][$word]; |
||||
} |
||||
|
||||
if (!isset(self::$plural['merged']['irregular'])) { |
||||
self::$plural['merged']['irregular'] = self::$plural['irregular']; |
||||
} |
||||
|
||||
if (!isset(self::$plural['merged']['uninflected'])) { |
||||
self::$plural['merged']['uninflected'] = array_merge(self::$plural['uninflected'], self::$uninflected); |
||||
} |
||||
|
||||
if (!isset(self::$plural['cacheUninflected']) || !isset(self::$plural['cacheIrregular'])) { |
||||
self::$plural['cacheUninflected'] = '(?:' . implode('|', self::$plural['merged']['uninflected']) . ')'; |
||||
self::$plural['cacheIrregular'] = '(?:' . implode('|', array_keys(self::$plural['merged']['irregular'])) . ')'; |
||||
} |
||||
|
||||
if (preg_match('/(.*)\\b(' . self::$plural['cacheIrregular'] . ')$/i', $word, $regs)) { |
||||
self::$cache['pluralize'][$word] = $regs[1] . substr($word, 0, 1) . substr(self::$plural['merged']['irregular'][strtolower($regs[2])], 1); |
||||
return self::$cache['pluralize'][$word]; |
||||
} |
||||
|
||||
if (preg_match('/^(' . self::$plural['cacheUninflected'] . ')$/i', $word, $regs)) { |
||||
self::$cache['pluralize'][$word] = $word; |
||||
return $word; |
||||
} |
||||
|
||||
foreach (self::$plural['rules'] as $rule => $replacement) { |
||||
if (preg_match($rule, $word)) { |
||||
self::$cache['pluralize'][$word] = preg_replace($rule, $replacement, $word); |
||||
return self::$cache['pluralize'][$word]; |
||||
} |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Return $word in singular form. |
||||
* |
||||
* @param string $word Word in plural |
||||
* @return string Word in singular |
||||
*/ |
||||
public static function singularize($word) |
||||
{ |
||||
if (isset(self::$cache['singularize'][$word])) { |
||||
return self::$cache['singularize'][$word]; |
||||
} |
||||
|
||||
if (!isset(self::$singular['merged']['uninflected'])) { |
||||
self::$singular['merged']['uninflected'] = array_merge( |
||||
self::$singular['uninflected'], |
||||
self::$uninflected |
||||
); |
||||
} |
||||
|
||||
if (!isset(self::$singular['merged']['irregular'])) { |
||||
self::$singular['merged']['irregular'] = array_merge( |
||||
self::$singular['irregular'], |
||||
array_flip(self::$plural['irregular']) |
||||
); |
||||
} |
||||
|
||||
if (!isset(self::$singular['cacheUninflected']) || !isset(self::$singular['cacheIrregular'])) { |
||||
self::$singular['cacheUninflected'] = '(?:' . join('|', self::$singular['merged']['uninflected']) . ')'; |
||||
self::$singular['cacheIrregular'] = '(?:' . join('|', array_keys(self::$singular['merged']['irregular'])) . ')'; |
||||
} |
||||
|
||||
if (preg_match('/(.*)\\b(' . self::$singular['cacheIrregular'] . ')$/i', $word, $regs)) { |
||||
self::$cache['singularize'][$word] = $regs[1] . substr($word, 0, 1) . substr(self::$singular['merged']['irregular'][strtolower($regs[2])], 1); |
||||
return self::$cache['singularize'][$word]; |
||||
} |
||||
|
||||
if (preg_match('/^(' . self::$singular['cacheUninflected'] . ')$/i', $word, $regs)) { |
||||
self::$cache['singularize'][$word] = $word; |
||||
return $word; |
||||
} |
||||
|
||||
foreach (self::$singular['rules'] as $rule => $replacement) { |
||||
if (preg_match($rule, $word)) { |
||||
self::$cache['singularize'][$word] = preg_replace($rule, $replacement, $word); |
||||
return self::$cache['singularize'][$word]; |
||||
} |
||||
} |
||||
self::$cache['singularize'][$word] = $word; |
||||
return $word; |
||||
} |
||||
} |
@ -0,0 +1,31 @@ |
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
||||
<phpunit backupGlobals="false" |
||||
backupStaticAttributes="false" |
||||
colors="true" |
||||
convertErrorsToExceptions="true" |
||||
convertNoticesToExceptions="true" |
||||
convertWarningsToExceptions="true" |
||||
processIsolation="false" |
||||
stopOnFailure="false" |
||||
syntaxCheck="false" |
||||
bootstrap="./tests/Doctrine/Tests/TestInit.php" |
||||
> |
||||
<testsuites> |
||||
<testsuite name="Doctrine Inflector Test Suite"> |
||||
<directory>./tests/Doctrine/</directory> |
||||
</testsuite> |
||||
</testsuites> |
||||
|
||||
<filter> |
||||
<whitelist> |
||||
<directory>./lib/Doctrine/</directory> |
||||
</whitelist> |
||||
</filter> |
||||
|
||||
<groups> |
||||
<exclude> |
||||
<group>performance</group> |
||||
</exclude> |
||||
</groups> |
||||
</phpunit> |
@ -0,0 +1,185 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Inflector; |
||||
|
||||
use Doctrine\Tests\DoctrineTestCase; |
||||
use Doctrine\Common\Inflector\Inflector; |
||||
|
||||
class InflectorTest extends DoctrineTestCase |
||||
{ |
||||
|
||||
/** |
||||
* Singular & Plural test data. Returns an array of sample words. |
||||
* |
||||
* @return array |
||||
*/ |
||||
public function dataSampleWords() { |
||||
Inflector::reset(); |
||||
// in the format array('singular', 'plural') |
||||
return array( |
||||
array('categoria', 'categorias'), |
||||
array('house', 'houses'), |
||||
array('powerhouse', 'powerhouses'), |
||||
array('Bus', 'Buses'), |
||||
array('bus', 'buses'), |
||||
array('menu', 'menus'), |
||||
array('news', 'news'), |
||||
array('food_menu', 'food_menus'), |
||||
array('Menu', 'Menus'), |
||||
array('FoodMenu', 'FoodMenus'), |
||||
array('quiz', 'quizzes'), |
||||
array('matrix_row', 'matrix_rows'), |
||||
array('matrix', 'matrices'), |
||||
array('vertex', 'vertices'), |
||||
array('index', 'indices'), |
||||
array('Alias', 'Aliases'), |
||||
array('Media', 'Media'), |
||||
array('NodeMedia', 'NodeMedia'), |
||||
array('alumnus', 'alumni'), |
||||
array('bacillus', 'bacilli'), |
||||
array('cactus', 'cacti'), |
||||
array('focus', 'foci'), |
||||
array('fungus', 'fungi'), |
||||
array('nucleus', 'nuclei'), |
||||
array('octopus', 'octopuses'), |
||||
array('radius', 'radii'), |
||||
array('stimulus', 'stimuli'), |
||||
array('syllabus', 'syllabi'), |
||||
array('terminus', 'termini'), |
||||
array('virus', 'viri'), |
||||
array('person', 'people'), |
||||
array('glove', 'gloves'), |
||||
array('crisis', 'crises'), |
||||
array('tax', 'taxes'), |
||||
array('wave', 'waves'), |
||||
array('bureau', 'bureaus'), |
||||
array('cafe', 'cafes'), |
||||
array('roof', 'roofs'), |
||||
array('foe', 'foes'), |
||||
array('cookie', 'cookies'), |
||||
array('', ''), |
||||
); |
||||
} |
||||
|
||||
/** |
||||
* testInflectingSingulars method |
||||
* |
||||
* @dataProvider dataSampleWords |
||||
* @return void |
||||
*/ |
||||
public function testInflectingSingulars($singular, $plural) { |
||||
$this->assertEquals($singular, Inflector::singularize($plural), "'$plural' should be singularized to '$singular'"); |
||||
} |
||||
|
||||
/** |
||||
* testInflectingPlurals method |
||||
* |
||||
* @dataProvider dataSampleWords |
||||
* @return void |
||||
*/ |
||||
public function testInflectingPlurals($singular, $plural) { |
||||
$this->assertEquals($plural, Inflector::pluralize($singular), "'$singular' should be pluralized to '$plural'"); |
||||
} |
||||
|
||||
/** |
||||
* testCustomPluralRule method |
||||
* |
||||
* @return void |
||||
*/ |
||||
public function testCustomPluralRule() { |
||||
Inflector::reset(); |
||||
Inflector::rules('plural', array('/^(custom)$/i' => '\1izables')); |
||||
$this->assertEquals(Inflector::pluralize('custom'), 'customizables'); |
||||
|
||||
Inflector::rules('plural', array('uninflected' => array('uninflectable'))); |
||||
$this->assertEquals(Inflector::pluralize('uninflectable'), 'uninflectable'); |
||||
|
||||
Inflector::rules('plural', array( |
||||
'rules' => array('/^(alert)$/i' => '\1ables'), |
||||
'uninflected' => array('noflect', 'abtuse'), |
||||
'irregular' => array('amaze' => 'amazable', 'phone' => 'phonezes') |
||||
)); |
||||
$this->assertEquals(Inflector::pluralize('noflect'), 'noflect'); |
||||
$this->assertEquals(Inflector::pluralize('abtuse'), 'abtuse'); |
||||
$this->assertEquals(Inflector::pluralize('alert'), 'alertables'); |
||||
$this->assertEquals(Inflector::pluralize('amaze'), 'amazable'); |
||||
$this->assertEquals(Inflector::pluralize('phone'), 'phonezes'); |
||||
} |
||||
|
||||
/** |
||||
* testCustomSingularRule method |
||||
* |
||||
* @return void |
||||
*/ |
||||
public function testCustomSingularRule() { |
||||
Inflector::reset(); |
||||
Inflector::rules('singular', array('/(eple)r$/i' => '\1', '/(jente)r$/i' => '\1')); |
||||
|
||||
$this->assertEquals(Inflector::singularize('epler'), 'eple'); |
||||
$this->assertEquals(Inflector::singularize('jenter'), 'jente'); |
||||
|
||||
Inflector::rules('singular', array( |
||||
'rules' => array('/^(bil)er$/i' => '\1', '/^(inflec|contribu)tors$/i' => '\1ta'), |
||||
'uninflected' => array('singulars'), |
||||
'irregular' => array('spins' => 'spinor') |
||||
)); |
||||
|
||||
$this->assertEquals(Inflector::singularize('inflectors'), 'inflecta'); |
||||
$this->assertEquals(Inflector::singularize('contributors'), 'contributa'); |
||||
$this->assertEquals(Inflector::singularize('spins'), 'spinor'); |
||||
$this->assertEquals(Inflector::singularize('singulars'), 'singulars'); |
||||
} |
||||
|
||||
/** |
||||
* test that setting new rules clears the inflector caches. |
||||
* |
||||
* @return void |
||||
*/ |
||||
public function testRulesClearsCaches() { |
||||
Inflector::reset(); |
||||
$this->assertEquals(Inflector::singularize('Bananas'), 'Banana'); |
||||
$this->assertEquals(Inflector::pluralize('Banana'), 'Bananas'); |
||||
|
||||
Inflector::rules('singular', array( |
||||
'rules' => array('/(.*)nas$/i' => '\1zzz') |
||||
)); |
||||
$this->assertEquals('Banazzz', Inflector::singularize('Bananas'), 'Was inflected with old rules.'); |
||||
|
||||
Inflector::rules('plural', array( |
||||
'rules' => array('/(.*)na$/i' => '\1zzz'), |
||||
'irregular' => array('corpus' => 'corpora') |
||||
)); |
||||
$this->assertEquals(Inflector::pluralize('Banana'), 'Banazzz', 'Was inflected with old rules.'); |
||||
$this->assertEquals(Inflector::pluralize('corpus'), 'corpora', 'Was inflected with old irregular form.'); |
||||
} |
||||
|
||||
/** |
||||
* Test resetting inflection rules. |
||||
* |
||||
* @return void |
||||
*/ |
||||
public function testCustomRuleWithReset() { |
||||
Inflector::reset(); |
||||
$uninflected = array('atlas', 'lapis', 'onibus', 'pires', 'virus', '.*x'); |
||||
$pluralIrregular = array('as' => 'ases'); |
||||
|
||||
Inflector::rules('singular', array( |
||||
'rules' => array('/^(.*)(a|e|o|u)is$/i' => '\1\2l'), |
||||
'uninflected' => $uninflected, |
||||
), true); |
||||
|
||||
Inflector::rules('plural', array( |
||||
'rules' => array( |
||||
'/^(.*)(a|e|o|u)l$/i' => '\1\2is', |
||||
), |
||||
'uninflected' => $uninflected, |
||||
'irregular' => $pluralIrregular |
||||
), true); |
||||
|
||||
$this->assertEquals(Inflector::pluralize('Alcool'), 'Alcoois'); |
||||
$this->assertEquals(Inflector::pluralize('Atlas'), 'Atlas'); |
||||
$this->assertEquals(Inflector::singularize('Alcoois'), 'Alcool'); |
||||
$this->assertEquals(Inflector::singularize('Atlas'), 'Atlas'); |
||||
} |
||||
} |
||||
|
@ -0,0 +1,10 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests; |
||||
|
||||
/** |
||||
* Base testcase class for all Doctrine testcases. |
||||
*/ |
||||
abstract class DoctrineTestCase extends \PHPUnit_Framework_TestCase |
||||
{ |
||||
} |
@ -0,0 +1,27 @@ |
||||
<?php |
||||
/* |
||||
* This file bootstraps the test environment. |
||||
*/ |
||||
namespace Doctrine\Tests; |
||||
|
||||
error_reporting(E_ALL | E_STRICT); |
||||
|
||||
// register silently failing autoloader |
||||
spl_autoload_register(function($class) |
||||
{ |
||||
if (0 === strpos($class, 'Doctrine\Tests\\')) { |
||||
$path = __DIR__.'/../../'.strtr($class, '\\', '/').'.php'; |
||||
if (is_file($path) && is_readable($path)) { |
||||
require_once $path; |
||||
|
||||
return true; |
||||
} |
||||
} else if (0 === strpos($class, 'Doctrine\Common\\')) { |
||||
$path = __DIR__.'/../../../lib/'.($class = strtr($class, '\\', '/')).'.php'; |
||||
if (is_file($path) && is_readable($path)) { |
||||
require_once $path; |
||||
|
||||
return true; |
||||
} |
||||
} |
||||
}); |
@ -0,0 +1,19 @@ |
||||
Copyright (c) 2012 PHP Framework Interoperability Group |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
of this software and associated documentation files (the "Software"), to deal |
||||
in the Software without restriction, including without limitation the rights |
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
copies of the Software, and to permit persons to whom the Software is |
||||
furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included in |
||||
all copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
||||
THE SOFTWARE. |
@ -0,0 +1,120 @@ |
||||
<?php |
||||
|
||||
namespace Psr\Log; |
||||
|
||||
/** |
||||
* This is a simple Logger implementation that other Loggers can inherit from. |
||||
* |
||||
* It simply delegates all log-level-specific methods to the `log` method to |
||||
* reduce boilerplate code that a simple Logger that does the same thing with |
||||
* messages regardless of the error level has to implement. |
||||
*/ |
||||
abstract class AbstractLogger implements LoggerInterface |
||||
{ |
||||
/** |
||||
* System is unusable. |
||||
* |
||||
* @param string $message |
||||
* @param array $context |
||||
* @return null |
||||
*/ |
||||
public function emergency($message, array $context = array()) |
||||
{ |
||||
$this->log(LogLevel::EMERGENCY, $message, $context); |
||||
} |
||||
|
||||
/** |
||||
* Action must be taken immediately. |
||||
* |
||||
* Example: Entire website down, database unavailable, etc. This should |
||||
* trigger the SMS alerts and wake you up. |
||||
* |
||||
* @param string $message |
||||
* @param array $context |
||||
* @return null |
||||
*/ |
||||
public function alert($message, array $context = array()) |
||||
{ |
||||
$this->log(LogLevel::ALERT, $message, $context); |
||||
} |
||||
|
||||
/** |
||||
* Critical conditions. |
||||
* |
||||
* Example: Application component unavailable, unexpected exception. |
||||
* |
||||
* @param string $message |
||||
* @param array $context |
||||
* @return null |
||||
*/ |
||||
public function critical($message, array $context = array()) |
||||
{ |
||||
$this->log(LogLevel::CRITICAL, $message, $context); |
||||
} |
||||
|
||||
/** |
||||
* Runtime errors that do not require immediate action but should typically |
||||
* be logged and monitored. |
||||
* |
||||
* @param string $message |
||||
* @param array $context |
||||
* @return null |
||||
*/ |
||||
public function error($message, array $context = array()) |
||||
{ |
||||
$this->log(LogLevel::ERROR, $message, $context); |
||||
} |
||||
|
||||
/** |
||||
* Exceptional occurrences that are not errors. |
||||
* |
||||
* Example: Use of deprecated APIs, poor use of an API, undesirable things |
||||
* that are not necessarily wrong. |
||||
* |
||||
* @param string $message |
||||
* @param array $context |
||||
* @return null |
||||
*/ |
||||
public function warning($message, array $context = array()) |
||||
{ |
||||
$this->log(LogLevel::WARNING, $message, $context); |
||||
} |
||||
|
||||
/** |
||||
* Normal but significant events. |
||||
* |
||||
* @param string $message |
||||
* @param array $context |
||||
* @return null |
||||
*/ |
||||
public function notice($message, array $context = array()) |
||||
{ |
||||
$this->log(LogLevel::NOTICE, $message, $context); |
||||
} |
||||
|
||||
/** |
||||
* Interesting events. |
||||
* |
||||
* Example: User logs in, SQL logs. |
||||
* |
||||
* @param string $message |
||||
* @param array $context |
||||
* @return null |
||||
*/ |
||||
public function info($message, array $context = array()) |
||||
{ |
||||
$this->log(LogLevel::INFO, $message, $context); |
||||
} |
||||
|
||||
/** |
||||
* Detailed debug information. |
||||
* |
||||
* @param string $message |
||||
* @param array $context |
||||
* @return null |
||||
*/ |
||||
public function debug($message, array $context = array()) |
||||
{ |
||||
$this->log(LogLevel::DEBUG, $message, $context); |
||||
} |
||||
} |
@ -0,0 +1,7 @@ |
||||
<?php |
||||
|
||||
namespace Psr\Log; |
||||
|
||||
class InvalidArgumentException extends \InvalidArgumentException |
||||
{ |
||||
} |
@ -0,0 +1,18 @@ |
||||
<?php |
||||
|
||||
namespace Psr\Log; |
||||
|
||||
/** |
||||
* Describes log levels |
||||
*/ |
||||
class LogLevel |
||||
{ |
||||
const EMERGENCY = 'emergency'; |
||||
const ALERT = 'alert'; |
||||
const CRITICAL = 'critical'; |
||||
const ERROR = 'error'; |
||||
const WARNING = 'warning'; |
||||
const NOTICE = 'notice'; |
||||
const INFO = 'info'; |
||||
const DEBUG = 'debug'; |
||||
} |
@ -0,0 +1,17 @@ |
||||
<?php |
||||
|
||||
namespace Psr\Log; |
||||
|
||||
/** |
||||
* Describes a logger-aware instance |
||||
*/ |
||||
interface LoggerAwareInterface |
||||
{ |
||||
/** |
||||
* Sets a logger instance on the object |
||||
* |
||||
* @param LoggerInterface $logger |
||||
* @return null |
||||
*/ |
||||
public function setLogger(LoggerInterface $logger); |
||||
} |
@ -0,0 +1,22 @@ |
||||
<?php |
||||
|
||||
namespace Psr\Log; |
||||
|
||||
/** |
||||
* Basic Implementation of LoggerAwareInterface. |
||||
*/ |
||||
trait LoggerAwareTrait |
||||
{ |
||||
/** @var LoggerInterface */ |
||||
protected $logger; |
||||
|
||||
/** |
||||
* Sets a logger. |
||||
* |
||||
* @param LoggerInterface $logger |
||||
*/ |
||||
public function setLogger(LoggerInterface $logger) |
||||
{ |
||||
$this->logger = $logger; |
||||
} |
||||
} |
@ -0,0 +1,114 @@ |
||||
<?php |
||||
|
||||
namespace Psr\Log; |
||||
|
||||
/** |
||||
* Describes a logger instance |
||||
* |
||||
* The message MUST be a string or object implementing __toString(). |
||||
* |
||||
* The message MAY contain placeholders in the form: {foo} where foo |
||||
* will be replaced by the context data in key "foo". |
||||
* |
||||
* The context array can contain arbitrary data, the only assumption that |
||||
* can be made by implementors is that if an Exception instance is given |
||||
* to produce a stack trace, it MUST be in a key named "exception". |
||||
* |
||||
* See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md |
||||
* for the full interface specification. |
||||
*/ |
||||
interface LoggerInterface |
||||
{ |
||||
/** |
||||
* System is unusable. |
||||
* |
||||
* @param string $message |
||||
* @param array $context |
||||
* @return null |
||||
*/ |
||||
public function emergency($message, array $context = array()); |
||||
|
||||
/** |
||||
* Action must be taken immediately. |
||||
* |
||||
* Example: Entire website down, database unavailable, etc. This should |
||||
* trigger the SMS alerts and wake you up. |
||||
* |
||||
* @param string $message |
||||
* @param array $context |
||||
* @return null |
||||
*/ |
||||
public function alert($message, array $context = array()); |
||||
|
||||
/** |
||||
* Critical conditions. |
||||
* |
||||
* Example: Application component unavailable, unexpected exception. |
||||
* |
||||
* @param string $message |
||||
* @param array $context |
||||
* @return null |
||||
*/ |
||||
public function critical($message, array $context = array()); |
||||
|
||||
/** |
||||
* Runtime errors that do not require immediate action but should typically |
||||
* be logged and monitored. |
||||
* |
||||
* @param string $message |
||||
* @param array $context |
||||
* @return null |
||||
*/ |
||||
public function error($message, array $context = array()); |
||||
|
||||
/** |
||||
* Exceptional occurrences that are not errors. |
||||
* |
||||
* Example: Use of deprecated APIs, poor use of an API, undesirable things |
||||
* that are not necessarily wrong. |
||||
* |
||||
* @param string $message |
||||
* @param array $context |
||||
* @return null |
||||
*/ |
||||
public function warning($message, array $context = array()); |
||||
|
||||
/** |
||||
* Normal but significant events. |
||||
* |
||||
* @param string $message |
||||
* @param array $context |
||||
* @return null |
||||
*/ |
||||
public function notice($message, array $context = array()); |
||||
|
||||
/** |
||||
* Interesting events. |
||||
* |
||||
* Example: User logs in, SQL logs. |
||||
* |
||||
* @param string $message |
||||
* @param array $context |
||||
* @return null |
||||
*/ |
||||
public function info($message, array $context = array()); |
||||
|
||||
/** |
||||
* Detailed debug information. |
||||
* |
||||
* @param string $message |
||||
* @param array $context |
||||
* @return null |
||||
*/ |
||||
public function debug($message, array $context = array()); |
||||
|
||||
/** |
||||
* Logs with an arbitrary level. |
||||
* |
||||
* @param mixed $level |
||||
* @param string $message |
||||
* @param array $context |
||||
* @return null |
||||
*/ |
||||
public function log($level, $message, array $context = array()); |
||||
} |
@ -0,0 +1,131 @@ |
||||
<?php |
||||
|
||||
namespace Psr\Log; |
||||
|
||||
/** |
||||
* This is a simple Logger trait that classes unable to extend AbstractLogger |
||||
* (because they extend another class, etc) can include. |
||||
* |
||||
* It simply delegates all log-level-specific methods to the `log` method to |
||||
* reduce boilerplate code that a simple Logger that does the same thing with |
||||
* messages regardless of the error level has to implement. |
||||
*/ |
||||
trait LoggerTrait |
||||
{ |
||||
/** |
||||
* System is unusable. |
||||
* |
||||
* @param string $message |
||||
* @param array $context |
||||
* @return null |
||||
*/ |
||||
public function emergency($message, array $context = array()) |
||||
{ |
||||
$this->log(LogLevel::EMERGENCY, $message, $context); |
||||
} |
||||
|
||||
/** |
||||
* Action must be taken immediately. |
||||
* |
||||
* Example: Entire website down, database unavailable, etc. This should |
||||
* trigger the SMS alerts and wake you up. |
||||
* |
||||
* @param string $message |
||||
* @param array $context |
||||
* @return null |
||||
*/ |
||||
public function alert($message, array $context = array()) |
||||
{ |
||||
$this->log(LogLevel::ALERT, $message, $context); |
||||
} |
||||
|
||||
/** |
||||
* Critical conditions. |
||||
* |
||||
* Example: Application component unavailable, unexpected exception. |
||||
* |
||||
* @param string $message |
||||
* @param array $context |
||||
* @return null |
||||
*/ |
||||
public function critical($message, array $context = array()) |
||||
{ |
||||
$this->log(LogLevel::CRITICAL, $message, $context); |
||||
} |
||||
|
||||
/** |
||||
* Runtime errors that do not require immediate action but should typically |
||||
* be logged and monitored. |
||||
* |
||||
* @param string $message |
||||
* @param array $context |
||||
* @return null |
||||
*/ |
||||
public function error($message, array $context = array()) |
||||
{ |
||||
$this->log(LogLevel::ERROR, $message, $context); |
||||
} |
||||
|
||||
/** |
||||
* Exceptional occurrences that are not errors. |
||||
* |
||||
* Example: Use of deprecated APIs, poor use of an API, undesirable things |
||||
* that are not necessarily wrong. |
||||
* |
||||
* @param string $message |
||||
* @param array $context |
||||
* @return null |
||||
*/ |
||||
public function warning($message, array $context = array()) |
||||
{ |
||||
$this->log(LogLevel::WARNING, $message, $context); |
||||
} |
||||
|
||||
/** |
||||
* Normal but significant events. |
||||
* |
||||
* @param string $message |
||||
* @param array $context |
||||
* @return null |
||||
*/ |
||||
public function notice($message, array $context = array()) |
||||
{ |
||||
$this->log(LogLevel::NOTICE, $message, $context); |
||||
} |
||||
|
||||
/** |
||||
* Interesting events. |
||||
* |
||||
* Example: User logs in, SQL logs. |
||||
* |
||||
* @param string $message |
||||
* @param array $context |
||||
* @return null |
||||
*/ |
||||
public function info($message, array $context = array()) |
||||
{ |
||||
$this->log(LogLevel::INFO, $message, $context); |
||||
} |
||||
|
||||
/** |
||||
* Detailed debug information. |
||||
* |
||||
* @param string $message |
||||
* @param array $context |
||||
* @return null |
||||
*/ |
||||
public function debug($message, array $context = array()) |
||||
{ |
||||
$this->log(LogLevel::DEBUG, $message, $context); |
||||
} |
||||
|
||||
/** |
||||
* Logs with an arbitrary level. |
||||
* |
||||
* @param mixed $level |
||||
* @param string $message |
||||
* @param array $context |
||||
* @return null |
||||
*/ |
||||
abstract public function log($level, $message, array $context = array()); |
||||
} |
@ -0,0 +1,27 @@ |
||||
<?php |
||||
|
||||
namespace Psr\Log; |
||||
|
||||
/** |
||||
* This Logger can be used to avoid conditional log calls |
||||
* |
||||
* Logging should always be optional, and if no logger is provided to your |
||||
* library creating a NullLogger instance to have something to throw logs at |
||||
* is a good way to avoid littering your code with `if ($this->logger) { }` |
||||
* blocks. |
||||
*/ |
||||
class NullLogger extends AbstractLogger |
||||
{ |
||||
/** |
||||
* Logs with an arbitrary level. |
||||
* |
||||
* @param mixed $level |
||||
* @param string $message |
||||
* @param array $context |
||||
* @return null |
||||
*/ |
||||
public function log($level, $message, array $context = array()) |
||||
{ |
||||
// noop |
||||
} |
||||
} |
@ -0,0 +1,116 @@ |
||||
<?php |
||||
|
||||
namespace Psr\Log\Test; |
||||
|
||||
use Psr\Log\LogLevel; |
||||
|
||||
/** |
||||
* Provides a base test class for ensuring compliance with the LoggerInterface |
||||
* |
||||
* Implementors can extend the class and implement abstract methods to run this as part of their test suite |
||||
*/ |
||||
abstract class LoggerInterfaceTest extends \PHPUnit_Framework_TestCase |
||||
{ |
||||
/** |
||||
* @return LoggerInterface |
||||
*/ |
||||
abstract function getLogger(); |
||||
|
||||
/** |
||||
* This must return the log messages in order with a simple formatting: "<LOG LEVEL> <MESSAGE>" |
||||
* |
||||
* Example ->error('Foo') would yield "error Foo" |
||||
* |
||||
* @return string[] |
||||
*/ |
||||
abstract function getLogs(); |
||||
|
||||
public function testImplements() |
||||
{ |
||||
$this->assertInstanceOf('Psr\Log\LoggerInterface', $this->getLogger()); |
||||
} |
||||
|
||||
/** |
||||
* @dataProvider provideLevelsAndMessages |
||||
*/ |
||||
public function testLogsAtAllLevels($level, $message) |
||||
{ |
||||
$logger = $this->getLogger(); |
||||
$logger->{$level}($message, array('user' => 'Bob')); |
||||
$logger->log($level, $message, array('user' => 'Bob')); |
||||
|
||||
$expected = array( |
||||
$level.' message of level '.$level.' with context: Bob', |
||||
$level.' message of level '.$level.' with context: Bob', |
||||
); |
||||
$this->assertEquals($expected, $this->getLogs()); |
||||
} |
||||
|
||||
public function provideLevelsAndMessages() |
||||
{ |
||||
return array( |
||||
LogLevel::EMERGENCY => array(LogLevel::EMERGENCY, 'message of level emergency with context: {user}'), |
||||
LogLevel::ALERT => array(LogLevel::ALERT, 'message of level alert with context: {user}'), |
||||
LogLevel::CRITICAL => array(LogLevel::CRITICAL, 'message of level critical with context: {user}'), |
||||
LogLevel::ERROR => array(LogLevel::ERROR, 'message of level error with context: {user}'), |
||||
LogLevel::WARNING => array(LogLevel::WARNING, 'message of level warning with context: {user}'), |
||||
LogLevel::NOTICE => array(LogLevel::NOTICE, 'message of level notice with context: {user}'), |
||||
LogLevel::INFO => array(LogLevel::INFO, 'message of level info with context: {user}'), |
||||
LogLevel::DEBUG => array(LogLevel::DEBUG, 'message of level debug with context: {user}'), |
||||
); |
||||
} |
||||
|
||||
/** |
||||
* @expectedException Psr\Log\InvalidArgumentException |
||||
*/ |
||||
public function testThrowsOnInvalidLevel() |
||||
{ |
||||
$logger = $this->getLogger(); |
||||
$logger->log('invalid level', 'Foo'); |
||||
} |
||||
|
||||
public function testContextReplacement() |
||||
{ |
||||
$logger = $this->getLogger(); |
||||
$logger->info('{Message {nothing} {user} {foo.bar} a}', array('user' => 'Bob', 'foo.bar' => 'Bar')); |
||||
|
||||
$expected = array('info {Message {nothing} Bob Bar a}'); |
||||
$this->assertEquals($expected, $this->getLogs()); |
||||
} |
||||
|
||||
public function testObjectCastToString() |
||||
{ |
||||
$dummy = $this->getMock('Psr\Log\Test\DummyTest', array('__toString')); |
||||
$dummy->expects($this->once()) |
||||
->method('__toString') |
||||
->will($this->returnValue('DUMMY')); |
||||
|
||||
$this->getLogger()->warning($dummy); |
||||
} |
||||
|
||||
public function testContextCanContainAnything() |
||||
{ |
||||
$context = array( |
||||
'bool' => true, |
||||
'null' => null, |
||||
'string' => 'Foo', |
||||
'int' => 0, |
||||
'float' => 0.5, |
||||
'nested' => array('with object' => new DummyTest), |
||||
'object' => new \DateTime, |
||||
'resource' => fopen('php://memory', 'r'), |
||||
); |
||||
|
||||
$this->getLogger()->warning('Crazy context data', $context); |
||||
} |
||||
|
||||
public function testContextExceptionKeyCanBeExceptionOrOtherValues() |
||||
{ |
||||
$this->getLogger()->warning('Random message', array('exception' => 'oops')); |
||||
$this->getLogger()->critical('Uncaught Exception!', array('exception' => new \LogicException('Fail'))); |
||||
} |
||||
} |
||||
|
||||
class DummyTest |
||||
{ |
||||
} |
@ -0,0 +1,45 @@ |
||||
PSR Log |
||||
======= |
||||
|
||||
This repository holds all interfaces/classes/traits related to |
||||
[PSR-3](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md). |
||||
|
||||
Note that this is not a logger of its own. It is merely an interface that |
||||
describes a logger. See the specification for more details. |
||||
|
||||
Usage |
||||
----- |
||||
|
||||
If you need a logger, you can use the interface like this: |
||||
|
||||
```php |
||||
<?php |
||||
|
||||
use Psr\Log\LoggerInterface; |
||||
|
||||
class Foo |
||||
{ |
||||
private $logger; |
||||
|
||||
public function __construct(LoggerInterface $logger = null) |
||||
{ |
||||
$this->logger = $logger; |
||||
} |
||||
|
||||
public function doSomething() |
||||
{ |
||||
if ($this->logger) { |
||||
$this->logger->info('Doing work'); |
||||
} |
||||
|
||||
// do something useful |
||||
} |
||||
} |
||||
``` |
||||
|
||||
You can then pick one of the implementations of the interface to get a logger. |
||||
|
||||
If you want to implement the interface, you can require this package and |
||||
implement `Psr\Log\LoggerInterface` in your code. Please read the |
||||
[specification text](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md) |
||||
for details. |
@ -0,0 +1,17 @@ |
||||
{ |
||||
"name": "psr/log", |
||||
"description": "Common interface for logging libraries", |
||||
"keywords": ["psr", "psr-3", "log"], |
||||
"license": "MIT", |
||||
"authors": [ |
||||
{ |
||||
"name": "PHP-FIG", |
||||
"homepage": "http://www.php-fig.org/" |
||||
} |
||||
], |
||||
"autoload": { |
||||
"psr-0": { |
||||
"Psr\\Log\\": "" |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue