Add php files
This commit is contained in:
53
include/ECM/EcmGoogleServices/src/Google/Cache/Abstract.php
Executable file
53
include/ECM/EcmGoogleServices/src/Google/Cache/Abstract.php
Executable file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright 2008 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Abstract storage class
|
||||
*
|
||||
* @author Chris Chabot <chabotc@google.com>
|
||||
*/
|
||||
abstract class Google_Cache_Abstract
|
||||
{
|
||||
|
||||
abstract public function __construct(Google_Client $client);
|
||||
|
||||
/**
|
||||
* Retrieves the data for the given key, or false if they
|
||||
* key is unknown or expired
|
||||
*
|
||||
* @param String $key The key who's data to retrieve
|
||||
* @param boolean|int $expiration Expiration time in seconds
|
||||
*
|
||||
*/
|
||||
abstract public function get($key, $expiration = false);
|
||||
|
||||
/**
|
||||
* Store the key => $value set. The $value is serialized
|
||||
* by this function so can be of any type
|
||||
*
|
||||
* @param string $key Key of the data
|
||||
* @param string $value data
|
||||
*/
|
||||
abstract public function set($key, $value);
|
||||
|
||||
/**
|
||||
* Removes the key/data pair for the given $key
|
||||
*
|
||||
* @param String $key
|
||||
*/
|
||||
abstract public function delete($key);
|
||||
}
|
||||
113
include/ECM/EcmGoogleServices/src/Google/Cache/Apc.php
Executable file
113
include/ECM/EcmGoogleServices/src/Google/Cache/Apc.php
Executable file
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright 2010 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
if (!class_exists('Google_Client')) {
|
||||
require_once dirname(__FILE__) . '/../autoload.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* A persistent storage class based on the APC cache, which is not
|
||||
* really very persistent, as soon as you restart your web server
|
||||
* the storage will be wiped, however for debugging and/or speed
|
||||
* it can be useful, and cache is a lot cheaper then storage.
|
||||
*
|
||||
* @author Chris Chabot <chabotc@google.com>
|
||||
*/
|
||||
class Google_Cache_Apc extends Google_Cache_Abstract
|
||||
{
|
||||
/**
|
||||
* @var Google_Client the current client
|
||||
*/
|
||||
private $client;
|
||||
|
||||
public function __construct(Google_Client $client)
|
||||
{
|
||||
if (! function_exists('apc_add') ) {
|
||||
$error = "Apc functions not available";
|
||||
|
||||
$client->getLogger()->error($error);
|
||||
throw new Google_Cache_Exception($error);
|
||||
}
|
||||
|
||||
$this->client = $client;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get($key, $expiration = false)
|
||||
{
|
||||
$ret = apc_fetch($key);
|
||||
if ($ret === false) {
|
||||
$this->client->getLogger()->debug(
|
||||
'APC cache miss',
|
||||
array('key' => $key)
|
||||
);
|
||||
return false;
|
||||
}
|
||||
if (is_numeric($expiration) && (time() - $ret['time'] > $expiration)) {
|
||||
$this->client->getLogger()->debug(
|
||||
'APC cache miss (expired)',
|
||||
array('key' => $key, 'var' => $ret)
|
||||
);
|
||||
$this->delete($key);
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->client->getLogger()->debug(
|
||||
'APC cache hit',
|
||||
array('key' => $key, 'var' => $ret)
|
||||
);
|
||||
|
||||
return $ret['data'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function set($key, $value)
|
||||
{
|
||||
$var = array('time' => time(), 'data' => $value);
|
||||
$rc = apc_store($key, $var);
|
||||
|
||||
if ($rc == false) {
|
||||
$this->client->getLogger()->error(
|
||||
'APC cache set failed',
|
||||
array('key' => $key, 'var' => $var)
|
||||
);
|
||||
throw new Google_Cache_Exception("Couldn't store data");
|
||||
}
|
||||
|
||||
$this->client->getLogger()->debug(
|
||||
'APC cache set',
|
||||
array('key' => $key, 'var' => $var)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @param String $key
|
||||
*/
|
||||
public function delete($key)
|
||||
{
|
||||
$this->client->getLogger()->debug(
|
||||
'APC cache delete',
|
||||
array('key' => $key)
|
||||
);
|
||||
apc_delete($key);
|
||||
}
|
||||
}
|
||||
24
include/ECM/EcmGoogleServices/src/Google/Cache/Exception.php
Executable file
24
include/ECM/EcmGoogleServices/src/Google/Cache/Exception.php
Executable file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright 2013 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
if (!class_exists('Google_Client')) {
|
||||
require_once dirname(__FILE__) . '/../autoload.php';
|
||||
}
|
||||
|
||||
class Google_Cache_Exception extends Google_Exception
|
||||
{
|
||||
}
|
||||
206
include/ECM/EcmGoogleServices/src/Google/Cache/File.php
Executable file
206
include/ECM/EcmGoogleServices/src/Google/Cache/File.php
Executable file
@@ -0,0 +1,206 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright 2008 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
if (!class_exists('Google_Client')) {
|
||||
require_once dirname(__FILE__) . '/../autoload.php';
|
||||
}
|
||||
|
||||
/*
|
||||
* This class implements a basic on disk storage. While that does
|
||||
* work quite well it's not the most elegant and scalable solution.
|
||||
* It will also get you into a heap of trouble when you try to run
|
||||
* this in a clustered environment.
|
||||
*
|
||||
* @author Chris Chabot <chabotc@google.com>
|
||||
*/
|
||||
class Google_Cache_File extends Google_Cache_Abstract
|
||||
{
|
||||
const MAX_LOCK_RETRIES = 10;
|
||||
private $path;
|
||||
private $fh;
|
||||
|
||||
/**
|
||||
* @var Google_Client the current client
|
||||
*/
|
||||
private $client;
|
||||
|
||||
public function __construct(Google_Client $client)
|
||||
{
|
||||
$this->client = $client;
|
||||
$this->path = $this->client->getClassConfig($this, 'directory');
|
||||
}
|
||||
|
||||
public function get($key, $expiration = false)
|
||||
{
|
||||
$storageFile = $this->getCacheFile($key);
|
||||
$data = false;
|
||||
|
||||
if (!file_exists($storageFile)) {
|
||||
$this->client->getLogger()->debug(
|
||||
'File cache miss',
|
||||
array('key' => $key, 'file' => $storageFile)
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($expiration) {
|
||||
$mtime = filemtime($storageFile);
|
||||
if ((time() - $mtime) >= $expiration) {
|
||||
$this->client->getLogger()->debug(
|
||||
'File cache miss (expired)',
|
||||
array('key' => $key, 'file' => $storageFile)
|
||||
);
|
||||
$this->delete($key);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->acquireReadLock($storageFile)) {
|
||||
if (filesize($storageFile) > 0) {
|
||||
$data = fread($this->fh, filesize($storageFile));
|
||||
$data = unserialize($data);
|
||||
} else {
|
||||
$this->client->getLogger()->debug(
|
||||
'Cache file was empty',
|
||||
array('file' => $storageFile)
|
||||
);
|
||||
}
|
||||
$this->unlock($storageFile);
|
||||
}
|
||||
|
||||
$this->client->getLogger()->debug(
|
||||
'File cache hit',
|
||||
array('key' => $key, 'file' => $storageFile, 'var' => $data)
|
||||
);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function set($key, $value)
|
||||
{
|
||||
$storageFile = $this->getWriteableCacheFile($key);
|
||||
if ($this->acquireWriteLock($storageFile)) {
|
||||
// We serialize the whole request object, since we don't only want the
|
||||
// responseContent but also the postBody used, headers, size, etc.
|
||||
$data = serialize($value);
|
||||
$result = fwrite($this->fh, $data);
|
||||
$this->unlock($storageFile);
|
||||
|
||||
$this->client->getLogger()->debug(
|
||||
'File cache set',
|
||||
array('key' => $key, 'file' => $storageFile, 'var' => $value)
|
||||
);
|
||||
} else {
|
||||
$this->client->getLogger()->notice(
|
||||
'File cache set failed',
|
||||
array('key' => $key, 'file' => $storageFile)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public function delete($key)
|
||||
{
|
||||
$file = $this->getCacheFile($key);
|
||||
if (file_exists($file) && !unlink($file)) {
|
||||
$this->client->getLogger()->error(
|
||||
'File cache delete failed',
|
||||
array('key' => $key, 'file' => $file)
|
||||
);
|
||||
throw new Google_Cache_Exception("Cache file could not be deleted");
|
||||
}
|
||||
|
||||
$this->client->getLogger()->debug(
|
||||
'File cache delete',
|
||||
array('key' => $key, 'file' => $file)
|
||||
);
|
||||
}
|
||||
|
||||
private function getWriteableCacheFile($file)
|
||||
{
|
||||
return $this->getCacheFile($file, true);
|
||||
}
|
||||
|
||||
private function getCacheFile($file, $forWrite = false)
|
||||
{
|
||||
return $this->getCacheDir($file, $forWrite) . '/' . md5($file);
|
||||
}
|
||||
|
||||
private function getCacheDir($file, $forWrite)
|
||||
{
|
||||
// use the first 2 characters of the hash as a directory prefix
|
||||
// this should prevent slowdowns due to huge directory listings
|
||||
// and thus give some basic amount of scalability
|
||||
$storageDir = $this->path . '/' . substr(md5($file), 0, 2);
|
||||
if ($forWrite && ! is_dir($storageDir)) {
|
||||
if (! mkdir($storageDir, 0755, true)) {
|
||||
$this->client->getLogger()->error(
|
||||
'File cache creation failed',
|
||||
array('dir' => $storageDir)
|
||||
);
|
||||
throw new Google_Cache_Exception("Could not create storage directory: $storageDir");
|
||||
}
|
||||
}
|
||||
return $storageDir;
|
||||
}
|
||||
|
||||
private function acquireReadLock($storageFile)
|
||||
{
|
||||
return $this->acquireLock(LOCK_SH, $storageFile);
|
||||
}
|
||||
|
||||
private function acquireWriteLock($storageFile)
|
||||
{
|
||||
$rc = $this->acquireLock(LOCK_EX, $storageFile);
|
||||
if (!$rc) {
|
||||
$this->client->getLogger()->notice(
|
||||
'File cache write lock failed',
|
||||
array('file' => $storageFile)
|
||||
);
|
||||
$this->delete($storageFile);
|
||||
}
|
||||
return $rc;
|
||||
}
|
||||
|
||||
private function acquireLock($type, $storageFile)
|
||||
{
|
||||
$mode = $type == LOCK_EX ? "w" : "r";
|
||||
$this->fh = fopen($storageFile, $mode);
|
||||
if (!$this->fh) {
|
||||
$this->client->getLogger()->error(
|
||||
'Failed to open file during lock acquisition',
|
||||
array('file' => $storageFile)
|
||||
);
|
||||
return false;
|
||||
}
|
||||
$count = 0;
|
||||
while (!flock($this->fh, $type | LOCK_NB)) {
|
||||
// Sleep for 10ms.
|
||||
usleep(10000);
|
||||
if (++$count < self::MAX_LOCK_RETRIES) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function unlock($storageFile)
|
||||
{
|
||||
if ($this->fh) {
|
||||
flock($this->fh, LOCK_UN);
|
||||
}
|
||||
}
|
||||
}
|
||||
184
include/ECM/EcmGoogleServices/src/Google/Cache/Memcache.php
Executable file
184
include/ECM/EcmGoogleServices/src/Google/Cache/Memcache.php
Executable file
@@ -0,0 +1,184 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright 2008 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
if (!class_exists('Google_Client')) {
|
||||
require_once dirname(__FILE__) . '/../autoload.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* A persistent storage class based on the memcache, which is not
|
||||
* really very persistent, as soon as you restart your memcache daemon
|
||||
* the storage will be wiped.
|
||||
*
|
||||
* Will use either the memcache or memcached extensions, preferring
|
||||
* memcached.
|
||||
*
|
||||
* @author Chris Chabot <chabotc@google.com>
|
||||
*/
|
||||
class Google_Cache_Memcache extends Google_Cache_Abstract
|
||||
{
|
||||
private $connection = false;
|
||||
private $mc = false;
|
||||
private $host;
|
||||
private $port;
|
||||
|
||||
/**
|
||||
* @var Google_Client the current client
|
||||
*/
|
||||
private $client;
|
||||
|
||||
public function __construct(Google_Client $client)
|
||||
{
|
||||
if (!function_exists('memcache_connect') && !class_exists("Memcached")) {
|
||||
$error = "Memcache functions not available";
|
||||
|
||||
$client->getLogger()->error($error);
|
||||
throw new Google_Cache_Exception($error);
|
||||
}
|
||||
|
||||
$this->client = $client;
|
||||
|
||||
if ($client->isAppEngine()) {
|
||||
// No credentials needed for GAE.
|
||||
$this->mc = new Memcached();
|
||||
$this->connection = true;
|
||||
} else {
|
||||
$this->host = $client->getClassConfig($this, 'host');
|
||||
$this->port = $client->getClassConfig($this, 'port');
|
||||
if (empty($this->host) || (empty($this->port) && (string) $this->port != "0")) {
|
||||
$error = "You need to supply a valid memcache host and port";
|
||||
|
||||
$client->getLogger()->error($error);
|
||||
throw new Google_Cache_Exception($error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get($key, $expiration = false)
|
||||
{
|
||||
$this->connect();
|
||||
$ret = false;
|
||||
if ($this->mc) {
|
||||
$ret = $this->mc->get($key);
|
||||
} else {
|
||||
$ret = memcache_get($this->connection, $key);
|
||||
}
|
||||
if ($ret === false) {
|
||||
$this->client->getLogger()->debug(
|
||||
'Memcache cache miss',
|
||||
array('key' => $key)
|
||||
);
|
||||
return false;
|
||||
}
|
||||
if (is_numeric($expiration) && (time() - $ret['time'] > $expiration)) {
|
||||
$this->client->getLogger()->debug(
|
||||
'Memcache cache miss (expired)',
|
||||
array('key' => $key, 'var' => $ret)
|
||||
);
|
||||
$this->delete($key);
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->client->getLogger()->debug(
|
||||
'Memcache cache hit',
|
||||
array('key' => $key, 'var' => $ret)
|
||||
);
|
||||
|
||||
return $ret['data'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @param string $key
|
||||
* @param string $value
|
||||
* @throws Google_Cache_Exception
|
||||
*/
|
||||
public function set($key, $value)
|
||||
{
|
||||
$this->connect();
|
||||
// we store it with the cache_time default expiration so objects will at
|
||||
// least get cleaned eventually.
|
||||
$data = array('time' => time(), 'data' => $value);
|
||||
$rc = false;
|
||||
if ($this->mc) {
|
||||
$rc = $this->mc->set($key, $data);
|
||||
} else {
|
||||
$rc = memcache_set($this->connection, $key, $data, false);
|
||||
}
|
||||
if ($rc == false) {
|
||||
$this->client->getLogger()->error(
|
||||
'Memcache cache set failed',
|
||||
array('key' => $key, 'var' => $data)
|
||||
);
|
||||
|
||||
throw new Google_Cache_Exception("Couldn't store data in cache");
|
||||
}
|
||||
|
||||
$this->client->getLogger()->debug(
|
||||
'Memcache cache set',
|
||||
array('key' => $key, 'var' => $data)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @param String $key
|
||||
*/
|
||||
public function delete($key)
|
||||
{
|
||||
$this->connect();
|
||||
if ($this->mc) {
|
||||
$this->mc->delete($key, 0);
|
||||
} else {
|
||||
memcache_delete($this->connection, $key, 0);
|
||||
}
|
||||
|
||||
$this->client->getLogger()->debug(
|
||||
'Memcache cache delete',
|
||||
array('key' => $key)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazy initialiser for memcache connection. Uses pconnect for to take
|
||||
* advantage of the persistence pool where possible.
|
||||
*/
|
||||
private function connect()
|
||||
{
|
||||
if ($this->connection) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (class_exists("Memcached")) {
|
||||
$this->mc = new Memcached();
|
||||
$this->mc->addServer($this->host, $this->port);
|
||||
$this->connection = true;
|
||||
} else {
|
||||
$this->connection = memcache_pconnect($this->host, $this->port);
|
||||
}
|
||||
|
||||
if (! $this->connection) {
|
||||
$error = "Couldn't connect to memcache server";
|
||||
|
||||
$this->client->getLogger()->error($error);
|
||||
throw new Google_Cache_Exception($error);
|
||||
}
|
||||
}
|
||||
}
|
||||
57
include/ECM/EcmGoogleServices/src/Google/Cache/Null.php
Executable file
57
include/ECM/EcmGoogleServices/src/Google/Cache/Null.php
Executable file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright 2014 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
if (!class_exists('Google_Client')) {
|
||||
require_once dirname(__FILE__) . '/../autoload.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* A blank storage class, for cases where caching is not
|
||||
* required.
|
||||
*/
|
||||
class Google_Cache_Null extends Google_Cache_Abstract
|
||||
{
|
||||
public function __construct(Google_Client $client)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get($key, $expiration = false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function set($key, $value)
|
||||
{
|
||||
// Nop.
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @param String $key
|
||||
*/
|
||||
public function delete($key)
|
||||
{
|
||||
// Nop.
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user