Move into nested docroot
This commit is contained in:
parent
83a0d3a149
commit
c8b70abde9
13405 changed files with 0 additions and 0 deletions
web/vendor/symfony/http-kernel/Profiler
315
web/vendor/symfony/http-kernel/Profiler/BaseMemcacheProfilerStorage.php
vendored
Normal file
315
web/vendor/symfony/http-kernel/Profiler/BaseMemcacheProfilerStorage.php
vendored
Normal file
|
@ -0,0 +1,315 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Profiler;
|
||||
|
||||
@trigger_error('The '.__NAMESPACE__.'\BaseMemcacheProfilerStorage class is deprecated since Symfony 2.8 and will be removed in 3.0. Use FileProfilerStorage instead.', E_USER_DEPRECATED);
|
||||
|
||||
/**
|
||||
* Base Memcache storage for profiling information in a Memcache.
|
||||
*
|
||||
* @author Andrej Hudec <pulzarraider@gmail.com>
|
||||
*
|
||||
* @deprecated Deprecated since Symfony 2.8, to be removed in Symfony 3.0.
|
||||
* Use {@link FileProfilerStorage} instead.
|
||||
*/
|
||||
abstract class BaseMemcacheProfilerStorage implements ProfilerStorageInterface
|
||||
{
|
||||
const TOKEN_PREFIX = 'sf_profiler_';
|
||||
|
||||
protected $dsn;
|
||||
protected $lifetime;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $dsn A data source name
|
||||
* @param string $username
|
||||
* @param string $password
|
||||
* @param int $lifetime The lifetime to use for the purge
|
||||
*/
|
||||
public function __construct($dsn, $username = '', $password = '', $lifetime = 86400)
|
||||
{
|
||||
$this->dsn = $dsn;
|
||||
$this->lifetime = (int) $lifetime;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function find($ip, $url, $limit, $method, $start = null, $end = null)
|
||||
{
|
||||
$indexName = $this->getIndexName();
|
||||
|
||||
$indexContent = $this->getValue($indexName);
|
||||
if (!$indexContent) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$profileList = explode("\n", $indexContent);
|
||||
$result = array();
|
||||
|
||||
foreach ($profileList as $item) {
|
||||
if ($limit === 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ($item == '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$values = explode("\t", $item, 7);
|
||||
list($itemToken, $itemIp, $itemMethod, $itemUrl, $itemTime, $itemParent) = $values;
|
||||
$statusCode = isset($values[6]) ? $values[6] : null;
|
||||
|
||||
$itemTime = (int) $itemTime;
|
||||
|
||||
if ($ip && false === strpos($itemIp, $ip) || $url && false === strpos($itemUrl, $url) || $method && false === strpos($itemMethod, $method)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!empty($start) && $itemTime < $start) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!empty($end) && $itemTime > $end) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$result[$itemToken] = array(
|
||||
'token' => $itemToken,
|
||||
'ip' => $itemIp,
|
||||
'method' => $itemMethod,
|
||||
'url' => $itemUrl,
|
||||
'time' => $itemTime,
|
||||
'parent' => $itemParent,
|
||||
'status_code' => $statusCode,
|
||||
);
|
||||
--$limit;
|
||||
}
|
||||
|
||||
usort($result, function ($a, $b) {
|
||||
if ($a['time'] === $b['time']) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return $a['time'] > $b['time'] ? -1 : 1;
|
||||
});
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function purge()
|
||||
{
|
||||
// delete only items from index
|
||||
$indexName = $this->getIndexName();
|
||||
|
||||
$indexContent = $this->getValue($indexName);
|
||||
|
||||
if (!$indexContent) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$profileList = explode("\n", $indexContent);
|
||||
|
||||
foreach ($profileList as $item) {
|
||||
if ($item == '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (false !== $pos = strpos($item, "\t")) {
|
||||
$this->delete($this->getItemName(substr($item, 0, $pos)));
|
||||
}
|
||||
}
|
||||
|
||||
return $this->delete($indexName);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function read($token)
|
||||
{
|
||||
if (empty($token)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$profile = $this->getValue($this->getItemName($token));
|
||||
|
||||
if (false !== $profile) {
|
||||
$profile = $this->createProfileFromData($token, $profile);
|
||||
}
|
||||
|
||||
return $profile;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function write(Profile $profile)
|
||||
{
|
||||
$data = array(
|
||||
'token' => $profile->getToken(),
|
||||
'parent' => $profile->getParentToken(),
|
||||
'children' => array_map(function ($p) { return $p->getToken(); }, $profile->getChildren()),
|
||||
'data' => $profile->getCollectors(),
|
||||
'ip' => $profile->getIp(),
|
||||
'method' => $profile->getMethod(),
|
||||
'url' => $profile->getUrl(),
|
||||
'time' => $profile->getTime(),
|
||||
);
|
||||
|
||||
$profileIndexed = false !== $this->getValue($this->getItemName($profile->getToken()));
|
||||
|
||||
if ($this->setValue($this->getItemName($profile->getToken()), $data, $this->lifetime)) {
|
||||
if (!$profileIndexed) {
|
||||
// Add to index
|
||||
$indexName = $this->getIndexName();
|
||||
|
||||
$indexRow = implode("\t", array(
|
||||
$profile->getToken(),
|
||||
$profile->getIp(),
|
||||
$profile->getMethod(),
|
||||
$profile->getUrl(),
|
||||
$profile->getTime(),
|
||||
$profile->getParentToken(),
|
||||
$profile->getStatusCode(),
|
||||
))."\n";
|
||||
|
||||
return $this->appendValue($indexName, $indexRow, $this->lifetime);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve item from the memcache server.
|
||||
*
|
||||
* @param string $key
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
abstract protected function getValue($key);
|
||||
|
||||
/**
|
||||
* Store an item on the memcache server under the specified key.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param int $expiration
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
abstract protected function setValue($key, $value, $expiration = 0);
|
||||
|
||||
/**
|
||||
* Delete item from the memcache server.
|
||||
*
|
||||
* @param string $key
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
abstract protected function delete($key);
|
||||
|
||||
/**
|
||||
* Append data to an existing item on the memcache server.
|
||||
*
|
||||
* @param string $key
|
||||
* @param string $value
|
||||
* @param int $expiration
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
abstract protected function appendValue($key, $value, $expiration = 0);
|
||||
|
||||
private function createProfileFromData($token, $data, $parent = null)
|
||||
{
|
||||
$profile = new Profile($token);
|
||||
$profile->setIp($data['ip']);
|
||||
$profile->setMethod($data['method']);
|
||||
$profile->setUrl($data['url']);
|
||||
$profile->setTime($data['time']);
|
||||
$profile->setCollectors($data['data']);
|
||||
|
||||
if (!$parent && $data['parent']) {
|
||||
$parent = $this->read($data['parent']);
|
||||
}
|
||||
|
||||
if ($parent) {
|
||||
$profile->setParent($parent);
|
||||
}
|
||||
|
||||
foreach ($data['children'] as $token) {
|
||||
if (!$token) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!$childProfileData = $this->getValue($this->getItemName($token))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$profile->addChild($this->createProfileFromData($token, $childProfileData, $profile));
|
||||
}
|
||||
|
||||
return $profile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get item name.
|
||||
*
|
||||
* @param string $token
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getItemName($token)
|
||||
{
|
||||
$name = self::TOKEN_PREFIX.$token;
|
||||
|
||||
if ($this->isItemNameValid($name)) {
|
||||
return $name;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name of index.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getIndexName()
|
||||
{
|
||||
$name = self::TOKEN_PREFIX.'index';
|
||||
|
||||
if ($this->isItemNameValid($name)) {
|
||||
return $name;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function isItemNameValid($name)
|
||||
{
|
||||
$length = strlen($name);
|
||||
|
||||
if ($length > 250) {
|
||||
throw new \RuntimeException(sprintf('The memcache item key "%s" is too long (%s bytes). Allowed maximum size is 250 bytes.', $name, $length));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
284
web/vendor/symfony/http-kernel/Profiler/FileProfilerStorage.php
vendored
Normal file
284
web/vendor/symfony/http-kernel/Profiler/FileProfilerStorage.php
vendored
Normal file
|
@ -0,0 +1,284 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Profiler;
|
||||
|
||||
/**
|
||||
* Storage for profiler using files.
|
||||
*
|
||||
* @author Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
*/
|
||||
class FileProfilerStorage implements ProfilerStorageInterface
|
||||
{
|
||||
/**
|
||||
* Folder where profiler data are stored.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $folder;
|
||||
|
||||
/**
|
||||
* Constructs the file storage using a "dsn-like" path.
|
||||
*
|
||||
* Example : "file:/path/to/the/storage/folder"
|
||||
*
|
||||
* @param string $dsn The DSN
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function __construct($dsn)
|
||||
{
|
||||
if (0 !== strpos($dsn, 'file:')) {
|
||||
throw new \RuntimeException(sprintf('Please check your configuration. You are trying to use FileStorage with an invalid dsn "%s". The expected format is "file:/path/to/the/storage/folder".', $dsn));
|
||||
}
|
||||
$this->folder = substr($dsn, 5);
|
||||
|
||||
if (!is_dir($this->folder) && false === @mkdir($this->folder, 0777, true) && !is_dir($this->folder)) {
|
||||
throw new \RuntimeException(sprintf('Unable to create the storage directory (%s).', $this->folder));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function find($ip, $url, $limit, $method, $start = null, $end = null)
|
||||
{
|
||||
$file = $this->getIndexFilename();
|
||||
|
||||
if (!file_exists($file)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$file = fopen($file, 'r');
|
||||
fseek($file, 0, SEEK_END);
|
||||
|
||||
$result = array();
|
||||
while (count($result) < $limit && $line = $this->readLineFromFile($file)) {
|
||||
$values = str_getcsv($line);
|
||||
list($csvToken, $csvIp, $csvMethod, $csvUrl, $csvTime, $csvParent) = $values;
|
||||
$csvStatusCode = isset($values[6]) ? $values[6] : null;
|
||||
|
||||
$csvTime = (int) $csvTime;
|
||||
|
||||
if ($ip && false === strpos($csvIp, $ip) || $url && false === strpos($csvUrl, $url) || $method && false === strpos($csvMethod, $method)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!empty($start) && $csvTime < $start) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!empty($end) && $csvTime > $end) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$result[$csvToken] = array(
|
||||
'token' => $csvToken,
|
||||
'ip' => $csvIp,
|
||||
'method' => $csvMethod,
|
||||
'url' => $csvUrl,
|
||||
'time' => $csvTime,
|
||||
'parent' => $csvParent,
|
||||
'status_code' => $csvStatusCode,
|
||||
);
|
||||
}
|
||||
|
||||
fclose($file);
|
||||
|
||||
return array_values($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function purge()
|
||||
{
|
||||
$flags = \FilesystemIterator::SKIP_DOTS;
|
||||
$iterator = new \RecursiveDirectoryIterator($this->folder, $flags);
|
||||
$iterator = new \RecursiveIteratorIterator($iterator, \RecursiveIteratorIterator::CHILD_FIRST);
|
||||
|
||||
foreach ($iterator as $file) {
|
||||
if (is_file($file)) {
|
||||
unlink($file);
|
||||
} else {
|
||||
rmdir($file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function read($token)
|
||||
{
|
||||
if (!$token || !file_exists($file = $this->getFilename($token))) {
|
||||
return;
|
||||
}
|
||||
|
||||
return $this->createProfileFromData($token, unserialize(file_get_contents($file)));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function write(Profile $profile)
|
||||
{
|
||||
$file = $this->getFilename($profile->getToken());
|
||||
|
||||
$profileIndexed = is_file($file);
|
||||
if (!$profileIndexed) {
|
||||
// Create directory
|
||||
$dir = dirname($file);
|
||||
if (!is_dir($dir) && false === @mkdir($dir, 0777, true) && !is_dir($dir)) {
|
||||
throw new \RuntimeException(sprintf('Unable to create the storage directory (%s).', $dir));
|
||||
}
|
||||
}
|
||||
|
||||
// Store profile
|
||||
$data = array(
|
||||
'token' => $profile->getToken(),
|
||||
'parent' => $profile->getParentToken(),
|
||||
'children' => array_map(function ($p) { return $p->getToken(); }, $profile->getChildren()),
|
||||
'data' => $profile->getCollectors(),
|
||||
'ip' => $profile->getIp(),
|
||||
'method' => $profile->getMethod(),
|
||||
'url' => $profile->getUrl(),
|
||||
'time' => $profile->getTime(),
|
||||
);
|
||||
|
||||
if (false === file_put_contents($file, serialize($data))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$profileIndexed) {
|
||||
// Add to index
|
||||
if (false === $file = fopen($this->getIndexFilename(), 'a')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
fputcsv($file, array(
|
||||
$profile->getToken(),
|
||||
$profile->getIp(),
|
||||
$profile->getMethod(),
|
||||
$profile->getUrl(),
|
||||
$profile->getTime(),
|
||||
$profile->getParentToken(),
|
||||
$profile->getStatusCode(),
|
||||
));
|
||||
fclose($file);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets filename to store data, associated to the token.
|
||||
*
|
||||
* @param string $token
|
||||
*
|
||||
* @return string The profile filename
|
||||
*/
|
||||
protected function getFilename($token)
|
||||
{
|
||||
// Uses 4 last characters, because first are mostly the same.
|
||||
$folderA = substr($token, -2, 2);
|
||||
$folderB = substr($token, -4, 2);
|
||||
|
||||
return $this->folder.'/'.$folderA.'/'.$folderB.'/'.$token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the index filename.
|
||||
*
|
||||
* @return string The index filename
|
||||
*/
|
||||
protected function getIndexFilename()
|
||||
{
|
||||
return $this->folder.'/index.csv';
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a line in the file, backward.
|
||||
*
|
||||
* This function automatically skips the empty lines and do not include the line return in result value.
|
||||
*
|
||||
* @param resource $file The file resource, with the pointer placed at the end of the line to read
|
||||
*
|
||||
* @return mixed A string representing the line or null if beginning of file is reached
|
||||
*/
|
||||
protected function readLineFromFile($file)
|
||||
{
|
||||
$line = '';
|
||||
$position = ftell($file);
|
||||
|
||||
if (0 === $position) {
|
||||
return;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
$chunkSize = min($position, 1024);
|
||||
$position -= $chunkSize;
|
||||
fseek($file, $position);
|
||||
|
||||
if (0 === $chunkSize) {
|
||||
// bof reached
|
||||
break;
|
||||
}
|
||||
|
||||
$buffer = fread($file, $chunkSize);
|
||||
|
||||
if (false === ($upTo = strrpos($buffer, "\n"))) {
|
||||
$line = $buffer.$line;
|
||||
continue;
|
||||
}
|
||||
|
||||
$position += $upTo;
|
||||
$line = substr($buffer, $upTo + 1).$line;
|
||||
fseek($file, max(0, $position), SEEK_SET);
|
||||
|
||||
if ('' !== $line) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return '' === $line ? null : $line;
|
||||
}
|
||||
|
||||
protected function createProfileFromData($token, $data, $parent = null)
|
||||
{
|
||||
$profile = new Profile($token);
|
||||
$profile->setIp($data['ip']);
|
||||
$profile->setMethod($data['method']);
|
||||
$profile->setUrl($data['url']);
|
||||
$profile->setTime($data['time']);
|
||||
$profile->setCollectors($data['data']);
|
||||
|
||||
if (!$parent && $data['parent']) {
|
||||
$parent = $this->read($data['parent']);
|
||||
}
|
||||
|
||||
if ($parent) {
|
||||
$profile->setParent($parent);
|
||||
}
|
||||
|
||||
foreach ($data['children'] as $token) {
|
||||
if (!$token || !file_exists($file = $this->getFilename($token))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$profile->addChild($this->createProfileFromData($token, unserialize(file_get_contents($file)), $profile));
|
||||
}
|
||||
|
||||
return $profile;
|
||||
}
|
||||
}
|
112
web/vendor/symfony/http-kernel/Profiler/MemcacheProfilerStorage.php
vendored
Normal file
112
web/vendor/symfony/http-kernel/Profiler/MemcacheProfilerStorage.php
vendored
Normal file
|
@ -0,0 +1,112 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Profiler;
|
||||
|
||||
@trigger_error('The '.__NAMESPACE__.'\MemcacheProfilerStorage class is deprecated since Symfony 2.8 and will be removed in 3.0. Use FileProfilerStorage instead.', E_USER_DEPRECATED);
|
||||
|
||||
/**
|
||||
* Memcache Profiler Storage.
|
||||
*
|
||||
* @author Andrej Hudec <pulzarraider@gmail.com>
|
||||
*
|
||||
* @deprecated Deprecated since Symfony 2.8, to be removed in Symfony 3.0.
|
||||
* Use {@link FileProfilerStorage} instead.
|
||||
*/
|
||||
class MemcacheProfilerStorage extends BaseMemcacheProfilerStorage
|
||||
{
|
||||
/**
|
||||
* @var \Memcache
|
||||
*/
|
||||
private $memcache;
|
||||
|
||||
/**
|
||||
* Internal convenience method that returns the instance of the Memcache.
|
||||
*
|
||||
* @return \Memcache
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
protected function getMemcache()
|
||||
{
|
||||
if (null === $this->memcache) {
|
||||
if (!preg_match('#^memcache://(?(?=\[.*\])\[(.*)\]|(.*)):(.*)$#', $this->dsn, $matches)) {
|
||||
throw new \RuntimeException(sprintf('Please check your configuration. You are trying to use Memcache with an invalid dsn "%s". The expected format is "memcache://[host]:port".', $this->dsn));
|
||||
}
|
||||
|
||||
$host = $matches[1] ?: $matches[2];
|
||||
$port = $matches[3];
|
||||
|
||||
$memcache = new \Memcache();
|
||||
$memcache->addserver($host, $port);
|
||||
|
||||
$this->memcache = $memcache;
|
||||
}
|
||||
|
||||
return $this->memcache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set instance of the Memcache.
|
||||
*
|
||||
* @param \Memcache $memcache
|
||||
*/
|
||||
public function setMemcache($memcache)
|
||||
{
|
||||
$this->memcache = $memcache;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getValue($key)
|
||||
{
|
||||
return $this->getMemcache()->get($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setValue($key, $value, $expiration = 0)
|
||||
{
|
||||
return $this->getMemcache()->set($key, $value, false, time() + $expiration);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function delete($key)
|
||||
{
|
||||
return $this->getMemcache()->delete($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function appendValue($key, $value, $expiration = 0)
|
||||
{
|
||||
$memcache = $this->getMemcache();
|
||||
|
||||
if (method_exists($memcache, 'append')) {
|
||||
// Memcache v3.0
|
||||
if (!$result = $memcache->append($key, $value, false, $expiration)) {
|
||||
return $memcache->set($key, $value, false, $expiration);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
// simulate append in Memcache <3.0
|
||||
$content = $memcache->get($key);
|
||||
|
||||
return $memcache->set($key, $content.$value, false, $expiration);
|
||||
}
|
||||
}
|
108
web/vendor/symfony/http-kernel/Profiler/MemcachedProfilerStorage.php
vendored
Normal file
108
web/vendor/symfony/http-kernel/Profiler/MemcachedProfilerStorage.php
vendored
Normal file
|
@ -0,0 +1,108 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Profiler;
|
||||
|
||||
@trigger_error('The '.__NAMESPACE__.'\MemcachedProfilerStorage class is deprecated since Symfony 2.8 and will be removed in 3.0. Use FileProfilerStorage instead.', E_USER_DEPRECATED);
|
||||
|
||||
/**
|
||||
* Memcached Profiler Storage.
|
||||
*
|
||||
* @author Andrej Hudec <pulzarraider@gmail.com>
|
||||
*
|
||||
* @deprecated Deprecated since Symfony 2.8, to be removed in Symfony 3.0.
|
||||
* Use {@link FileProfilerStorage} instead.
|
||||
*/
|
||||
class MemcachedProfilerStorage extends BaseMemcacheProfilerStorage
|
||||
{
|
||||
/**
|
||||
* @var \Memcached
|
||||
*/
|
||||
private $memcached;
|
||||
|
||||
/**
|
||||
* Internal convenience method that returns the instance of the Memcached.
|
||||
*
|
||||
* @return \Memcached
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
protected function getMemcached()
|
||||
{
|
||||
if (null === $this->memcached) {
|
||||
if (!preg_match('#^memcached://(?(?=\[.*\])\[(.*)\]|(.*)):(.*)$#', $this->dsn, $matches)) {
|
||||
throw new \RuntimeException(sprintf('Please check your configuration. You are trying to use Memcached with an invalid dsn "%s". The expected format is "memcached://[host]:port".', $this->dsn));
|
||||
}
|
||||
|
||||
$host = $matches[1] ?: $matches[2];
|
||||
$port = $matches[3];
|
||||
|
||||
$memcached = new \Memcached();
|
||||
|
||||
// disable compression to allow appending
|
||||
$memcached->setOption(\Memcached::OPT_COMPRESSION, false);
|
||||
|
||||
$memcached->addServer($host, $port);
|
||||
|
||||
$this->memcached = $memcached;
|
||||
}
|
||||
|
||||
return $this->memcached;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set instance of the Memcached.
|
||||
*
|
||||
* @param \Memcached $memcached
|
||||
*/
|
||||
public function setMemcached($memcached)
|
||||
{
|
||||
$this->memcached = $memcached;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getValue($key)
|
||||
{
|
||||
return $this->getMemcached()->get($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setValue($key, $value, $expiration = 0)
|
||||
{
|
||||
return $this->getMemcached()->set($key, $value, time() + $expiration);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function delete($key)
|
||||
{
|
||||
return $this->getMemcached()->delete($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function appendValue($key, $value, $expiration = 0)
|
||||
{
|
||||
$memcached = $this->getMemcached();
|
||||
|
||||
if (!$result = $memcached->append($key, $value)) {
|
||||
return $memcached->set($key, $value, $expiration);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
265
web/vendor/symfony/http-kernel/Profiler/MongoDbProfilerStorage.php
vendored
Normal file
265
web/vendor/symfony/http-kernel/Profiler/MongoDbProfilerStorage.php
vendored
Normal file
|
@ -0,0 +1,265 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Profiler;
|
||||
|
||||
@trigger_error('The '.__NAMESPACE__.'\MongoDbProfilerStorage class is deprecated since Symfony 2.8 and will be removed in 3.0. Use FileProfilerStorage instead.', E_USER_DEPRECATED);
|
||||
|
||||
/**
|
||||
* @deprecated Deprecated since Symfony 2.8, to be removed in Symfony 3.0.
|
||||
* Use {@link FileProfilerStorage} instead.
|
||||
*/
|
||||
class MongoDbProfilerStorage implements ProfilerStorageInterface
|
||||
{
|
||||
protected $dsn;
|
||||
protected $lifetime;
|
||||
private $mongo;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $dsn A data source name
|
||||
* @param string $username Not used
|
||||
* @param string $password Not used
|
||||
* @param int $lifetime The lifetime to use for the purge
|
||||
*/
|
||||
public function __construct($dsn, $username = '', $password = '', $lifetime = 86400)
|
||||
{
|
||||
$this->dsn = $dsn;
|
||||
$this->lifetime = (int) $lifetime;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function find($ip, $url, $limit, $method, $start = null, $end = null)
|
||||
{
|
||||
$cursor = $this->getMongo()->find($this->buildQuery($ip, $url, $method, $start, $end), array('_id', 'parent', 'ip', 'method', 'url', 'time', 'status_code'))->sort(array('time' => -1))->limit($limit);
|
||||
|
||||
$tokens = array();
|
||||
foreach ($cursor as $profile) {
|
||||
$tokens[] = $this->getData($profile);
|
||||
}
|
||||
|
||||
return $tokens;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function purge()
|
||||
{
|
||||
$this->getMongo()->remove(array());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function read($token)
|
||||
{
|
||||
$profile = $this->getMongo()->findOne(array('_id' => $token, 'data' => array('$exists' => true)));
|
||||
|
||||
if (null !== $profile) {
|
||||
$profile = $this->createProfileFromData($this->getData($profile));
|
||||
}
|
||||
|
||||
return $profile;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function write(Profile $profile)
|
||||
{
|
||||
$this->cleanup();
|
||||
|
||||
$record = array(
|
||||
'_id' => $profile->getToken(),
|
||||
'parent' => $profile->getParentToken(),
|
||||
'data' => base64_encode(serialize($profile->getCollectors())),
|
||||
'ip' => $profile->getIp(),
|
||||
'method' => $profile->getMethod(),
|
||||
'url' => $profile->getUrl(),
|
||||
'time' => $profile->getTime(),
|
||||
'status_code' => $profile->getStatusCode(),
|
||||
);
|
||||
|
||||
$result = $this->getMongo()->update(array('_id' => $profile->getToken()), array_filter($record, function ($v) { return !empty($v); }), array('upsert' => true));
|
||||
|
||||
return (bool) (isset($result['ok']) ? $result['ok'] : $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal convenience method that returns the instance of the MongoDB Collection.
|
||||
*
|
||||
* @return \MongoCollection
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
protected function getMongo()
|
||||
{
|
||||
if (null !== $this->mongo) {
|
||||
return $this->mongo;
|
||||
}
|
||||
|
||||
if (!$parsedDsn = $this->parseDsn($this->dsn)) {
|
||||
throw new \RuntimeException(sprintf('Please check your configuration. You are trying to use MongoDB with an invalid dsn "%s". The expected format is "mongodb://[user:pass@]host/database/collection"', $this->dsn));
|
||||
}
|
||||
|
||||
list($server, $database, $collection) = $parsedDsn;
|
||||
$mongoClass = version_compare(phpversion('mongo'), '1.3.0', '<') ? '\Mongo' : '\MongoClient';
|
||||
$mongo = new $mongoClass($server);
|
||||
|
||||
return $this->mongo = $mongo->selectCollection($database, $collection);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return Profile
|
||||
*/
|
||||
protected function createProfileFromData(array $data)
|
||||
{
|
||||
$profile = $this->getProfile($data);
|
||||
|
||||
if ($data['parent']) {
|
||||
$parent = $this->getMongo()->findOne(array('_id' => $data['parent'], 'data' => array('$exists' => true)));
|
||||
if ($parent) {
|
||||
$profile->setParent($this->getProfile($this->getData($parent)));
|
||||
}
|
||||
}
|
||||
|
||||
$profile->setChildren($this->readChildren($data['token']));
|
||||
|
||||
return $profile;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $token
|
||||
*
|
||||
* @return Profile[] An array of Profile instances
|
||||
*/
|
||||
protected function readChildren($token)
|
||||
{
|
||||
$profiles = array();
|
||||
|
||||
$cursor = $this->getMongo()->find(array('parent' => $token, 'data' => array('$exists' => true)));
|
||||
foreach ($cursor as $d) {
|
||||
$profiles[] = $this->getProfile($this->getData($d));
|
||||
}
|
||||
|
||||
return $profiles;
|
||||
}
|
||||
|
||||
protected function cleanup()
|
||||
{
|
||||
$this->getMongo()->remove(array('time' => array('$lt' => time() - $this->lifetime)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $ip
|
||||
* @param string $url
|
||||
* @param string $method
|
||||
* @param int $start
|
||||
* @param int $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function buildQuery($ip, $url, $method, $start, $end)
|
||||
{
|
||||
$query = array();
|
||||
|
||||
if (!empty($ip)) {
|
||||
$query['ip'] = $ip;
|
||||
}
|
||||
|
||||
if (!empty($url)) {
|
||||
$query['url'] = $url;
|
||||
}
|
||||
|
||||
if (!empty($method)) {
|
||||
$query['method'] = $method;
|
||||
}
|
||||
|
||||
if (!empty($start) || !empty($end)) {
|
||||
$query['time'] = array();
|
||||
}
|
||||
|
||||
if (!empty($start)) {
|
||||
$query['time']['$gte'] = $start;
|
||||
}
|
||||
|
||||
if (!empty($end)) {
|
||||
$query['time']['$lte'] = $end;
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getData(array $data)
|
||||
{
|
||||
return array(
|
||||
'token' => $data['_id'],
|
||||
'parent' => isset($data['parent']) ? $data['parent'] : null,
|
||||
'ip' => isset($data['ip']) ? $data['ip'] : null,
|
||||
'method' => isset($data['method']) ? $data['method'] : null,
|
||||
'url' => isset($data['url']) ? $data['url'] : null,
|
||||
'time' => isset($data['time']) ? $data['time'] : null,
|
||||
'data' => isset($data['data']) ? $data['data'] : null,
|
||||
'status_code' => isset($data['status_code']) ? $data['status_code'] : null,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return Profile
|
||||
*/
|
||||
private function getProfile(array $data)
|
||||
{
|
||||
$profile = new Profile($data['token']);
|
||||
$profile->setIp($data['ip']);
|
||||
$profile->setMethod($data['method']);
|
||||
$profile->setUrl($data['url']);
|
||||
$profile->setTime($data['time']);
|
||||
$profile->setCollectors(unserialize(base64_decode($data['data'])));
|
||||
|
||||
return $profile;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $dsn
|
||||
*
|
||||
* @return null|array Array($server, $database, $collection)
|
||||
*/
|
||||
private function parseDsn($dsn)
|
||||
{
|
||||
if (!preg_match('#^(mongodb://.*)/(.*)/(.*)$#', $dsn, $matches)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$server = $matches[1];
|
||||
$database = $matches[2];
|
||||
$collection = $matches[3];
|
||||
preg_match('#^mongodb://(([^:]+):?(.*)(?=@))?@?([^/]*)(.*)$#', $server, $matchesServer);
|
||||
|
||||
if ('' == $matchesServer[5] && '' != $matches[2]) {
|
||||
$server .= '/'.$matches[2];
|
||||
}
|
||||
|
||||
return array($server, $database, $collection);
|
||||
}
|
||||
}
|
84
web/vendor/symfony/http-kernel/Profiler/MysqlProfilerStorage.php
vendored
Normal file
84
web/vendor/symfony/http-kernel/Profiler/MysqlProfilerStorage.php
vendored
Normal file
|
@ -0,0 +1,84 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Profiler;
|
||||
|
||||
@trigger_error('The '.__NAMESPACE__.'\MysqlProfilerStorage class is deprecated since Symfony 2.8 and will be removed in 3.0. Use FileProfilerStorage instead.', E_USER_DEPRECATED);
|
||||
|
||||
/**
|
||||
* A ProfilerStorage for Mysql.
|
||||
*
|
||||
* @author Jan Schumann <js@schumann-it.com>
|
||||
*
|
||||
* @deprecated Deprecated since Symfony 2.8, to be removed in Symfony 3.0.
|
||||
* Use {@link FileProfilerStorage} instead.
|
||||
*/
|
||||
class MysqlProfilerStorage extends PdoProfilerStorage
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function initDb()
|
||||
{
|
||||
if (null === $this->db) {
|
||||
if (0 !== strpos($this->dsn, 'mysql')) {
|
||||
throw new \RuntimeException(sprintf('Please check your configuration. You are trying to use Mysql with an invalid dsn "%s". The expected format is "mysql:dbname=database_name;host=host_name".', $this->dsn));
|
||||
}
|
||||
|
||||
if (!class_exists('PDO') || !in_array('mysql', \PDO::getAvailableDrivers(), true)) {
|
||||
throw new \RuntimeException('You need to enable PDO_Mysql extension for the profiler to run properly.');
|
||||
}
|
||||
|
||||
$db = new \PDO($this->dsn, $this->username, $this->password);
|
||||
$db->exec('CREATE TABLE IF NOT EXISTS sf_profiler_data (token VARCHAR(255) PRIMARY KEY, data LONGTEXT, ip VARCHAR(64), method VARCHAR(6), url VARCHAR(255), time INTEGER UNSIGNED, parent VARCHAR(255), created_at INTEGER UNSIGNED, status_code SMALLINT UNSIGNED, KEY (created_at), KEY (ip), KEY (method), KEY (url), KEY (parent))');
|
||||
|
||||
$this->db = $db;
|
||||
}
|
||||
|
||||
return $this->db;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function buildCriteria($ip, $url, $start, $end, $limit, $method)
|
||||
{
|
||||
$criteria = array();
|
||||
$args = array();
|
||||
|
||||
if ($ip = preg_replace('/[^\d\.]/', '', $ip)) {
|
||||
$criteria[] = 'ip LIKE :ip';
|
||||
$args[':ip'] = '%'.$ip.'%';
|
||||
}
|
||||
|
||||
if ($url) {
|
||||
$criteria[] = 'url LIKE :url';
|
||||
$args[':url'] = '%'.addcslashes($url, '%_\\').'%';
|
||||
}
|
||||
|
||||
if ($method) {
|
||||
$criteria[] = 'method = :method';
|
||||
$args[':method'] = $method;
|
||||
}
|
||||
|
||||
if (!empty($start)) {
|
||||
$criteria[] = 'time >= :start';
|
||||
$args[':start'] = $start;
|
||||
}
|
||||
|
||||
if (!empty($end)) {
|
||||
$criteria[] = 'time <= :end';
|
||||
$args[':end'] = $end;
|
||||
}
|
||||
|
||||
return array($criteria, $args);
|
||||
}
|
||||
}
|
267
web/vendor/symfony/http-kernel/Profiler/PdoProfilerStorage.php
vendored
Normal file
267
web/vendor/symfony/http-kernel/Profiler/PdoProfilerStorage.php
vendored
Normal file
|
@ -0,0 +1,267 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Profiler;
|
||||
|
||||
@trigger_error('The '.__NAMESPACE__.'\PdoProfilerStorage class is deprecated since Symfony 2.8 and will be removed in 3.0. Use FileProfilerStorage instead.', E_USER_DEPRECATED);
|
||||
|
||||
/**
|
||||
* Base PDO storage for profiling information in a PDO database.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Jan Schumann <js@schumann-it.com>
|
||||
*
|
||||
* @deprecated Deprecated since Symfony 2.8, to be removed in Symfony 3.0.
|
||||
* Use {@link FileProfilerStorage} instead.
|
||||
*/
|
||||
abstract class PdoProfilerStorage implements ProfilerStorageInterface
|
||||
{
|
||||
protected $dsn;
|
||||
protected $username;
|
||||
protected $password;
|
||||
protected $lifetime;
|
||||
protected $db;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $dsn A data source name
|
||||
* @param string $username The username for the database
|
||||
* @param string $password The password for the database
|
||||
* @param int $lifetime The lifetime to use for the purge
|
||||
*/
|
||||
public function __construct($dsn, $username = '', $password = '', $lifetime = 86400)
|
||||
{
|
||||
$this->dsn = $dsn;
|
||||
$this->username = $username;
|
||||
$this->password = $password;
|
||||
$this->lifetime = (int) $lifetime;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function find($ip, $url, $limit, $method, $start = null, $end = null)
|
||||
{
|
||||
if (null === $start) {
|
||||
$start = 0;
|
||||
}
|
||||
|
||||
if (null === $end) {
|
||||
$end = time();
|
||||
}
|
||||
|
||||
list($criteria, $args) = $this->buildCriteria($ip, $url, $start, $end, $limit, $method);
|
||||
|
||||
$criteria = $criteria ? 'WHERE '.implode(' AND ', $criteria) : '';
|
||||
|
||||
$db = $this->initDb();
|
||||
$tokens = $this->fetch($db, 'SELECT token, ip, method, url, time, parent, status_code FROM sf_profiler_data '.$criteria.' ORDER BY time DESC LIMIT '.((int) $limit), $args);
|
||||
$this->close($db);
|
||||
|
||||
return $tokens;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function read($token)
|
||||
{
|
||||
$db = $this->initDb();
|
||||
$args = array(':token' => $token);
|
||||
$data = $this->fetch($db, 'SELECT data, parent, ip, method, url, time FROM sf_profiler_data WHERE token = :token LIMIT 1', $args);
|
||||
$this->close($db);
|
||||
if (isset($data[0]['data'])) {
|
||||
return $this->createProfileFromData($token, $data[0]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function write(Profile $profile)
|
||||
{
|
||||
$db = $this->initDb();
|
||||
$args = array(
|
||||
':token' => $profile->getToken(),
|
||||
':parent' => $profile->getParentToken(),
|
||||
':data' => base64_encode(serialize($profile->getCollectors())),
|
||||
':ip' => $profile->getIp(),
|
||||
':method' => $profile->getMethod(),
|
||||
':url' => $profile->getUrl(),
|
||||
':time' => $profile->getTime(),
|
||||
':created_at' => time(),
|
||||
':status_code' => $profile->getStatusCode(),
|
||||
);
|
||||
|
||||
try {
|
||||
if ($this->has($profile->getToken())) {
|
||||
$this->exec($db, 'UPDATE sf_profiler_data SET parent = :parent, data = :data, ip = :ip, method = :method, url = :url, time = :time, created_at = :created_at, status_code = :status_code WHERE token = :token', $args);
|
||||
} else {
|
||||
$this->exec($db, 'INSERT INTO sf_profiler_data (token, parent, data, ip, method, url, time, created_at, status_code) VALUES (:token, :parent, :data, :ip, :method, :url, :time, :created_at, :status_code)', $args);
|
||||
}
|
||||
$this->cleanup();
|
||||
$status = true;
|
||||
} catch (\Exception $e) {
|
||||
$status = false;
|
||||
}
|
||||
|
||||
$this->close($db);
|
||||
|
||||
return $status;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function purge()
|
||||
{
|
||||
$db = $this->initDb();
|
||||
$this->exec($db, 'DELETE FROM sf_profiler_data');
|
||||
$this->close($db);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build SQL criteria to fetch records by ip and url.
|
||||
*
|
||||
* @param string $ip The IP
|
||||
* @param string $url The URL
|
||||
* @param string $start The start period to search from
|
||||
* @param string $end The end period to search to
|
||||
* @param string $limit The maximum number of tokens to return
|
||||
* @param string $method The request method
|
||||
*
|
||||
* @return array An array with (criteria, args)
|
||||
*/
|
||||
abstract protected function buildCriteria($ip, $url, $start, $end, $limit, $method);
|
||||
|
||||
/**
|
||||
* Initializes the database.
|
||||
*
|
||||
* @throws \RuntimeException When the requested database driver is not installed
|
||||
*/
|
||||
abstract protected function initDb();
|
||||
|
||||
protected function cleanup()
|
||||
{
|
||||
$db = $this->initDb();
|
||||
$this->exec($db, 'DELETE FROM sf_profiler_data WHERE created_at < :time', array(':time' => time() - $this->lifetime));
|
||||
$this->close($db);
|
||||
}
|
||||
|
||||
protected function exec($db, $query, array $args = array())
|
||||
{
|
||||
$stmt = $this->prepareStatement($db, $query);
|
||||
|
||||
foreach ($args as $arg => $val) {
|
||||
$stmt->bindValue($arg, $val, is_int($val) ? \PDO::PARAM_INT : \PDO::PARAM_STR);
|
||||
}
|
||||
$success = $stmt->execute();
|
||||
if (!$success) {
|
||||
throw new \RuntimeException(sprintf('Error executing query "%s"', $query));
|
||||
}
|
||||
}
|
||||
|
||||
protected function prepareStatement($db, $query)
|
||||
{
|
||||
try {
|
||||
$stmt = $db->prepare($query);
|
||||
} catch (\Exception $e) {
|
||||
$stmt = false;
|
||||
}
|
||||
|
||||
if (false === $stmt) {
|
||||
throw new \RuntimeException('The database cannot successfully prepare the statement');
|
||||
}
|
||||
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
protected function fetch($db, $query, array $args = array())
|
||||
{
|
||||
$stmt = $this->prepareStatement($db, $query);
|
||||
|
||||
foreach ($args as $arg => $val) {
|
||||
$stmt->bindValue($arg, $val, is_int($val) ? \PDO::PARAM_INT : \PDO::PARAM_STR);
|
||||
}
|
||||
$stmt->execute();
|
||||
|
||||
return $stmt->fetchAll(\PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
protected function close($db)
|
||||
{
|
||||
}
|
||||
|
||||
protected function createProfileFromData($token, $data, $parent = null)
|
||||
{
|
||||
$profile = new Profile($token);
|
||||
$profile->setIp($data['ip']);
|
||||
$profile->setMethod($data['method']);
|
||||
$profile->setUrl($data['url']);
|
||||
$profile->setTime($data['time']);
|
||||
$profile->setCollectors(unserialize(base64_decode($data['data'])));
|
||||
|
||||
if (!$parent && !empty($data['parent'])) {
|
||||
$parent = $this->read($data['parent']);
|
||||
}
|
||||
|
||||
if ($parent) {
|
||||
$profile->setParent($parent);
|
||||
}
|
||||
|
||||
$profile->setChildren($this->readChildren($token, $profile));
|
||||
|
||||
return $profile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the child profiles for the given token.
|
||||
*
|
||||
* @param string $token The parent token
|
||||
* @param string $parent The parent instance
|
||||
*
|
||||
* @return Profile[] An array of Profile instance
|
||||
*/
|
||||
protected function readChildren($token, $parent)
|
||||
{
|
||||
$db = $this->initDb();
|
||||
$data = $this->fetch($db, 'SELECT token, data, ip, method, url, time FROM sf_profiler_data WHERE parent = :token', array(':token' => $token));
|
||||
$this->close($db);
|
||||
|
||||
if (!$data) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$profiles = array();
|
||||
foreach ($data as $d) {
|
||||
$profiles[] = $this->createProfileFromData($d['token'], $d, $parent);
|
||||
}
|
||||
|
||||
return $profiles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether data for the given token already exists in storage.
|
||||
*
|
||||
* @param string $token The profile token
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function has($token)
|
||||
{
|
||||
$db = $this->initDb();
|
||||
$tokenExists = $this->fetch($db, 'SELECT 1 FROM sf_profiler_data WHERE token = :token LIMIT 1', array(':token' => $token));
|
||||
$this->close($db);
|
||||
|
||||
return !empty($tokenExists);
|
||||
}
|
||||
}
|
292
web/vendor/symfony/http-kernel/Profiler/Profile.php
vendored
Normal file
292
web/vendor/symfony/http-kernel/Profiler/Profile.php
vendored
Normal file
|
@ -0,0 +1,292 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Profiler;
|
||||
|
||||
use Symfony\Component\HttpKernel\DataCollector\DataCollectorInterface;
|
||||
|
||||
/**
|
||||
* Profile.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class Profile
|
||||
{
|
||||
private $token;
|
||||
|
||||
/**
|
||||
* @var DataCollectorInterface[]
|
||||
*/
|
||||
private $collectors = array();
|
||||
|
||||
private $ip;
|
||||
private $method;
|
||||
private $url;
|
||||
private $time;
|
||||
private $statusCode;
|
||||
|
||||
/**
|
||||
* @var Profile
|
||||
*/
|
||||
private $parent;
|
||||
|
||||
/**
|
||||
* @var Profile[]
|
||||
*/
|
||||
private $children = array();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $token The token
|
||||
*/
|
||||
public function __construct($token)
|
||||
{
|
||||
$this->token = $token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the token.
|
||||
*
|
||||
* @param string $token The token
|
||||
*/
|
||||
public function setToken($token)
|
||||
{
|
||||
$this->token = $token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the token.
|
||||
*
|
||||
* @return string The token
|
||||
*/
|
||||
public function getToken()
|
||||
{
|
||||
return $this->token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the parent token.
|
||||
*
|
||||
* @param Profile $parent
|
||||
*/
|
||||
public function setParent(Profile $parent)
|
||||
{
|
||||
$this->parent = $parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the parent profile.
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function getParent()
|
||||
{
|
||||
return $this->parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the parent token.
|
||||
*
|
||||
* @return null|string The parent token
|
||||
*/
|
||||
public function getParentToken()
|
||||
{
|
||||
return $this->parent ? $this->parent->getToken() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the IP.
|
||||
*
|
||||
* @return string The IP
|
||||
*/
|
||||
public function getIp()
|
||||
{
|
||||
return $this->ip;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the IP.
|
||||
*
|
||||
* @param string $ip
|
||||
*/
|
||||
public function setIp($ip)
|
||||
{
|
||||
$this->ip = $ip;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the request method.
|
||||
*
|
||||
* @return string The request method
|
||||
*/
|
||||
public function getMethod()
|
||||
{
|
||||
return $this->method;
|
||||
}
|
||||
|
||||
public function setMethod($method)
|
||||
{
|
||||
$this->method = $method;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URL.
|
||||
*
|
||||
* @return string The URL
|
||||
*/
|
||||
public function getUrl()
|
||||
{
|
||||
return $this->url;
|
||||
}
|
||||
|
||||
public function setUrl($url)
|
||||
{
|
||||
$this->url = $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the time.
|
||||
*
|
||||
* @return string The time
|
||||
*/
|
||||
public function getTime()
|
||||
{
|
||||
if (null === $this->time) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return $this->time;
|
||||
}
|
||||
|
||||
public function setTime($time)
|
||||
{
|
||||
$this->time = $time;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $statusCode
|
||||
*/
|
||||
public function setStatusCode($statusCode)
|
||||
{
|
||||
$this->statusCode = $statusCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getStatusCode()
|
||||
{
|
||||
return $this->statusCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds children profilers.
|
||||
*
|
||||
* @return self[]
|
||||
*/
|
||||
public function getChildren()
|
||||
{
|
||||
return $this->children;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets children profiler.
|
||||
*
|
||||
* @param Profile[] $children
|
||||
*/
|
||||
public function setChildren(array $children)
|
||||
{
|
||||
$this->children = array();
|
||||
foreach ($children as $child) {
|
||||
$this->addChild($child);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the child token.
|
||||
*
|
||||
* @param Profile $child
|
||||
*/
|
||||
public function addChild(Profile $child)
|
||||
{
|
||||
$this->children[] = $child;
|
||||
$child->setParent($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a Collector by name.
|
||||
*
|
||||
* @param string $name A collector name
|
||||
*
|
||||
* @return DataCollectorInterface A DataCollectorInterface instance
|
||||
*
|
||||
* @throws \InvalidArgumentException if the collector does not exist
|
||||
*/
|
||||
public function getCollector($name)
|
||||
{
|
||||
if (!isset($this->collectors[$name])) {
|
||||
throw new \InvalidArgumentException(sprintf('Collector "%s" does not exist.', $name));
|
||||
}
|
||||
|
||||
return $this->collectors[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Collectors associated with this profile.
|
||||
*
|
||||
* @return DataCollectorInterface[]
|
||||
*/
|
||||
public function getCollectors()
|
||||
{
|
||||
return $this->collectors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Collectors associated with this profile.
|
||||
*
|
||||
* @param DataCollectorInterface[] $collectors
|
||||
*/
|
||||
public function setCollectors(array $collectors)
|
||||
{
|
||||
$this->collectors = array();
|
||||
foreach ($collectors as $collector) {
|
||||
$this->addCollector($collector);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a Collector.
|
||||
*
|
||||
* @param DataCollectorInterface $collector A DataCollectorInterface instance
|
||||
*/
|
||||
public function addCollector(DataCollectorInterface $collector)
|
||||
{
|
||||
$this->collectors[$collector->getName()] = $collector;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if a Collector for the given name exists.
|
||||
*
|
||||
* @param string $name A collector name
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasCollector($name)
|
||||
{
|
||||
return isset($this->collectors[$name]);
|
||||
}
|
||||
|
||||
public function __sleep()
|
||||
{
|
||||
return array('token', 'parent', 'children', 'collectors', 'ip', 'method', 'url', 'time');
|
||||
}
|
||||
}
|
309
web/vendor/symfony/http-kernel/Profiler/Profiler.php
vendored
Normal file
309
web/vendor/symfony/http-kernel/Profiler/Profiler.php
vendored
Normal file
|
@ -0,0 +1,309 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Profiler;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Exception\ConflictingHeadersException;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\DataCollector\DataCollectorInterface;
|
||||
use Symfony\Component\HttpKernel\DataCollector\LateDataCollectorInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
* Profiler.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class Profiler
|
||||
{
|
||||
/**
|
||||
* @var ProfilerStorageInterface
|
||||
*/
|
||||
private $storage;
|
||||
|
||||
/**
|
||||
* @var DataCollectorInterface[]
|
||||
*/
|
||||
private $collectors = array();
|
||||
|
||||
/**
|
||||
* @var LoggerInterface
|
||||
*/
|
||||
private $logger;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $enabled = true;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param ProfilerStorageInterface $storage A ProfilerStorageInterface instance
|
||||
* @param LoggerInterface $logger A LoggerInterface instance
|
||||
*/
|
||||
public function __construct(ProfilerStorageInterface $storage, LoggerInterface $logger = null)
|
||||
{
|
||||
$this->storage = $storage;
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables the profiler.
|
||||
*/
|
||||
public function disable()
|
||||
{
|
||||
$this->enabled = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables the profiler.
|
||||
*/
|
||||
public function enable()
|
||||
{
|
||||
$this->enabled = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the Profile for the given Response.
|
||||
*
|
||||
* @param Response $response A Response instance
|
||||
*
|
||||
* @return Profile|false A Profile instance
|
||||
*/
|
||||
public function loadProfileFromResponse(Response $response)
|
||||
{
|
||||
if (!$token = $response->headers->get('X-Debug-Token')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->loadProfile($token);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the Profile for the given token.
|
||||
*
|
||||
* @param string $token A token
|
||||
*
|
||||
* @return Profile A Profile instance
|
||||
*/
|
||||
public function loadProfile($token)
|
||||
{
|
||||
return $this->storage->read($token);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves a Profile.
|
||||
*
|
||||
* @param Profile $profile A Profile instance
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function saveProfile(Profile $profile)
|
||||
{
|
||||
// late collect
|
||||
foreach ($profile->getCollectors() as $collector) {
|
||||
if ($collector instanceof LateDataCollectorInterface) {
|
||||
$collector->lateCollect();
|
||||
}
|
||||
}
|
||||
|
||||
if (!($ret = $this->storage->write($profile)) && null !== $this->logger) {
|
||||
$this->logger->warning('Unable to store the profiler information.', array('configured_storage' => get_class($this->storage)));
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Purges all data from the storage.
|
||||
*/
|
||||
public function purge()
|
||||
{
|
||||
$this->storage->purge();
|
||||
}
|
||||
|
||||
/**
|
||||
* Exports the current profiler data.
|
||||
*
|
||||
* @param Profile $profile A Profile instance
|
||||
*
|
||||
* @return string The exported data
|
||||
*
|
||||
* @deprecated since Symfony 2.8, to be removed in 3.0.
|
||||
*/
|
||||
public function export(Profile $profile)
|
||||
{
|
||||
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
|
||||
|
||||
return base64_encode(serialize($profile));
|
||||
}
|
||||
|
||||
/**
|
||||
* Imports data into the profiler storage.
|
||||
*
|
||||
* @param string $data A data string as exported by the export() method
|
||||
*
|
||||
* @return Profile|false A Profile instance
|
||||
*
|
||||
* @deprecated since Symfony 2.8, to be removed in 3.0.
|
||||
*/
|
||||
public function import($data)
|
||||
{
|
||||
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
|
||||
|
||||
$profile = unserialize(base64_decode($data));
|
||||
|
||||
if ($this->storage->read($profile->getToken())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->saveProfile($profile);
|
||||
|
||||
return $profile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds profiler tokens for the given criteria.
|
||||
*
|
||||
* @param string $ip The IP
|
||||
* @param string $url The URL
|
||||
* @param string $limit The maximum number of tokens to return
|
||||
* @param string $method The request method
|
||||
* @param string $start The start date to search from
|
||||
* @param string $end The end date to search to
|
||||
*
|
||||
* @return array An array of tokens
|
||||
*
|
||||
* @see http://php.net/manual/en/datetime.formats.php for the supported date/time formats
|
||||
*/
|
||||
public function find($ip, $url, $limit, $method, $start, $end)
|
||||
{
|
||||
return $this->storage->find($ip, $url, $limit, $method, $this->getTimestamp($start), $this->getTimestamp($end));
|
||||
}
|
||||
|
||||
/**
|
||||
* Collects data for the given Response.
|
||||
*
|
||||
* @param Request $request A Request instance
|
||||
* @param Response $response A Response instance
|
||||
* @param \Exception $exception An exception instance if the request threw one
|
||||
*
|
||||
* @return Profile|null A Profile instance or null if the profiler is disabled
|
||||
*/
|
||||
public function collect(Request $request, Response $response, \Exception $exception = null)
|
||||
{
|
||||
if (false === $this->enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
$profile = new Profile(substr(hash('sha256', uniqid(mt_rand(), true)), 0, 6));
|
||||
$profile->setTime(time());
|
||||
$profile->setUrl($request->getUri());
|
||||
$profile->setMethod($request->getMethod());
|
||||
$profile->setStatusCode($response->getStatusCode());
|
||||
try {
|
||||
$profile->setIp($request->getClientIp());
|
||||
} catch (ConflictingHeadersException $e) {
|
||||
$profile->setIp('Unknown');
|
||||
}
|
||||
|
||||
$response->headers->set('X-Debug-Token', $profile->getToken());
|
||||
|
||||
foreach ($this->collectors as $collector) {
|
||||
$collector->collect($request, $response, $exception);
|
||||
|
||||
// we need to clone for sub-requests
|
||||
$profile->addCollector(clone $collector);
|
||||
}
|
||||
|
||||
return $profile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Collectors associated with this profiler.
|
||||
*
|
||||
* @return array An array of collectors
|
||||
*/
|
||||
public function all()
|
||||
{
|
||||
return $this->collectors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Collectors associated with this profiler.
|
||||
*
|
||||
* @param DataCollectorInterface[] $collectors An array of collectors
|
||||
*/
|
||||
public function set(array $collectors = array())
|
||||
{
|
||||
$this->collectors = array();
|
||||
foreach ($collectors as $collector) {
|
||||
$this->add($collector);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a Collector.
|
||||
*
|
||||
* @param DataCollectorInterface $collector A DataCollectorInterface instance
|
||||
*/
|
||||
public function add(DataCollectorInterface $collector)
|
||||
{
|
||||
$this->collectors[$collector->getName()] = $collector;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if a Collector for the given name exists.
|
||||
*
|
||||
* @param string $name A collector name
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has($name)
|
||||
{
|
||||
return isset($this->collectors[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a Collector by name.
|
||||
*
|
||||
* @param string $name A collector name
|
||||
*
|
||||
* @return DataCollectorInterface A DataCollectorInterface instance
|
||||
*
|
||||
* @throws \InvalidArgumentException if the collector does not exist
|
||||
*/
|
||||
public function get($name)
|
||||
{
|
||||
if (!isset($this->collectors[$name])) {
|
||||
throw new \InvalidArgumentException(sprintf('Collector "%s" does not exist.', $name));
|
||||
}
|
||||
|
||||
return $this->collectors[$name];
|
||||
}
|
||||
|
||||
private function getTimestamp($value)
|
||||
{
|
||||
if (null === $value || '' == $value) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
$value = new \DateTime(is_numeric($value) ? '@'.$value : $value);
|
||||
} catch (\Exception $e) {
|
||||
return;
|
||||
}
|
||||
|
||||
return $value->getTimestamp();
|
||||
}
|
||||
}
|
59
web/vendor/symfony/http-kernel/Profiler/ProfilerStorageInterface.php
vendored
Normal file
59
web/vendor/symfony/http-kernel/Profiler/ProfilerStorageInterface.php
vendored
Normal file
|
@ -0,0 +1,59 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Profiler;
|
||||
|
||||
/**
|
||||
* ProfilerStorageInterface.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
interface ProfilerStorageInterface
|
||||
{
|
||||
/**
|
||||
* Finds profiler tokens for the given criteria.
|
||||
*
|
||||
* @param string $ip The IP
|
||||
* @param string $url The URL
|
||||
* @param string $limit The maximum number of tokens to return
|
||||
* @param string $method The request method
|
||||
* @param int|null $start The start date to search from
|
||||
* @param int|null $end The end date to search to
|
||||
*
|
||||
* @return array An array of tokens
|
||||
*/
|
||||
public function find($ip, $url, $limit, $method, $start = null, $end = null);
|
||||
|
||||
/**
|
||||
* Reads data associated with the given token.
|
||||
*
|
||||
* The method returns false if the token does not exist in the storage.
|
||||
*
|
||||
* @param string $token A token
|
||||
*
|
||||
* @return Profile The profile associated with token
|
||||
*/
|
||||
public function read($token);
|
||||
|
||||
/**
|
||||
* Saves a Profile.
|
||||
*
|
||||
* @param Profile $profile A Profile instance
|
||||
*
|
||||
* @return bool Write operation successful
|
||||
*/
|
||||
public function write(Profile $profile);
|
||||
|
||||
/**
|
||||
* Purges all data from the database.
|
||||
*/
|
||||
public function purge();
|
||||
}
|
399
web/vendor/symfony/http-kernel/Profiler/RedisProfilerStorage.php
vendored
Normal file
399
web/vendor/symfony/http-kernel/Profiler/RedisProfilerStorage.php
vendored
Normal file
|
@ -0,0 +1,399 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Profiler;
|
||||
|
||||
@trigger_error('The '.__NAMESPACE__.'\RedisProfilerStorage class is deprecated since Symfony 2.8 and will be removed in 3.0. Use FileProfilerStorage instead.', E_USER_DEPRECATED);
|
||||
|
||||
/**
|
||||
* RedisProfilerStorage stores profiling information in Redis.
|
||||
*
|
||||
* @author Andrej Hudec <pulzarraider@gmail.com>
|
||||
* @author Stephane PY <py.stephane1@gmail.com>
|
||||
*
|
||||
* @deprecated Deprecated since Symfony 2.8, to be removed in Symfony 3.0.
|
||||
* Use {@link FileProfilerStorage} instead.
|
||||
*/
|
||||
class RedisProfilerStorage implements ProfilerStorageInterface
|
||||
{
|
||||
const TOKEN_PREFIX = 'sf_profiler_';
|
||||
|
||||
const REDIS_OPT_SERIALIZER = 1;
|
||||
const REDIS_OPT_PREFIX = 2;
|
||||
const REDIS_SERIALIZER_NONE = 0;
|
||||
const REDIS_SERIALIZER_PHP = 1;
|
||||
|
||||
protected $dsn;
|
||||
protected $lifetime;
|
||||
|
||||
/**
|
||||
* @var \Redis
|
||||
*/
|
||||
private $redis;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $dsn A data source name
|
||||
* @param string $username Not used
|
||||
* @param string $password Not used
|
||||
* @param int $lifetime The lifetime to use for the purge
|
||||
*/
|
||||
public function __construct($dsn, $username = '', $password = '', $lifetime = 86400)
|
||||
{
|
||||
$this->dsn = $dsn;
|
||||
$this->lifetime = (int) $lifetime;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function find($ip, $url, $limit, $method, $start = null, $end = null)
|
||||
{
|
||||
$indexName = $this->getIndexName();
|
||||
|
||||
if (!$indexContent = $this->getValue($indexName, self::REDIS_SERIALIZER_NONE)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$profileList = array_reverse(explode("\n", $indexContent));
|
||||
$result = array();
|
||||
|
||||
foreach ($profileList as $item) {
|
||||
if ($limit === 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ($item == '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$values = explode("\t", $item, 7);
|
||||
list($itemToken, $itemIp, $itemMethod, $itemUrl, $itemTime, $itemParent) = $values;
|
||||
$statusCode = isset($values[6]) ? $values[6] : null;
|
||||
|
||||
$itemTime = (int) $itemTime;
|
||||
|
||||
if ($ip && false === strpos($itemIp, $ip) || $url && false === strpos($itemUrl, $url) || $method && false === strpos($itemMethod, $method)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!empty($start) && $itemTime < $start) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!empty($end) && $itemTime > $end) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$result[] = array(
|
||||
'token' => $itemToken,
|
||||
'ip' => $itemIp,
|
||||
'method' => $itemMethod,
|
||||
'url' => $itemUrl,
|
||||
'time' => $itemTime,
|
||||
'parent' => $itemParent,
|
||||
'status_code' => $statusCode,
|
||||
);
|
||||
--$limit;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function purge()
|
||||
{
|
||||
// delete only items from index
|
||||
$indexName = $this->getIndexName();
|
||||
|
||||
$indexContent = $this->getValue($indexName, self::REDIS_SERIALIZER_NONE);
|
||||
|
||||
if (!$indexContent) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$profileList = explode("\n", $indexContent);
|
||||
|
||||
$result = array();
|
||||
|
||||
foreach ($profileList as $item) {
|
||||
if ($item == '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (false !== $pos = strpos($item, "\t")) {
|
||||
$result[] = $this->getItemName(substr($item, 0, $pos));
|
||||
}
|
||||
}
|
||||
|
||||
$result[] = $indexName;
|
||||
|
||||
return $this->delete($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function read($token)
|
||||
{
|
||||
if (empty($token)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$profile = $this->getValue($this->getItemName($token), self::REDIS_SERIALIZER_PHP);
|
||||
|
||||
if (false !== $profile) {
|
||||
$profile = $this->createProfileFromData($token, $profile);
|
||||
}
|
||||
|
||||
return $profile;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function write(Profile $profile)
|
||||
{
|
||||
$data = array(
|
||||
'token' => $profile->getToken(),
|
||||
'parent' => $profile->getParentToken(),
|
||||
'children' => array_map(function ($p) { return $p->getToken(); }, $profile->getChildren()),
|
||||
'data' => $profile->getCollectors(),
|
||||
'ip' => $profile->getIp(),
|
||||
'method' => $profile->getMethod(),
|
||||
'url' => $profile->getUrl(),
|
||||
'time' => $profile->getTime(),
|
||||
);
|
||||
|
||||
$profileIndexed = false !== $this->getValue($this->getItemName($profile->getToken()));
|
||||
|
||||
if ($this->setValue($this->getItemName($profile->getToken()), $data, $this->lifetime, self::REDIS_SERIALIZER_PHP)) {
|
||||
if (!$profileIndexed) {
|
||||
// Add to index
|
||||
$indexName = $this->getIndexName();
|
||||
|
||||
$indexRow = implode("\t", array(
|
||||
$profile->getToken(),
|
||||
$profile->getIp(),
|
||||
$profile->getMethod(),
|
||||
$profile->getUrl(),
|
||||
$profile->getTime(),
|
||||
$profile->getParentToken(),
|
||||
$profile->getStatusCode(),
|
||||
))."\n";
|
||||
|
||||
return $this->appendValue($indexName, $indexRow, $this->lifetime);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal convenience method that returns the instance of Redis.
|
||||
*
|
||||
* @return \Redis
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
protected function getRedis()
|
||||
{
|
||||
if (null === $this->redis) {
|
||||
$data = parse_url($this->dsn);
|
||||
|
||||
if (false === $data || !isset($data['scheme']) || $data['scheme'] !== 'redis' || !isset($data['host']) || !isset($data['port'])) {
|
||||
throw new \RuntimeException(sprintf('Please check your configuration. You are trying to use Redis with an invalid dsn "%s". The minimal expected format is "redis://[host]:port".', $this->dsn));
|
||||
}
|
||||
|
||||
if (!extension_loaded('redis')) {
|
||||
throw new \RuntimeException('RedisProfilerStorage requires that the redis extension is loaded.');
|
||||
}
|
||||
|
||||
$redis = new \Redis();
|
||||
$redis->connect($data['host'], $data['port']);
|
||||
|
||||
if (isset($data['path'])) {
|
||||
$redis->select(substr($data['path'], 1));
|
||||
}
|
||||
|
||||
if (isset($data['pass'])) {
|
||||
$redis->auth($data['pass']);
|
||||
}
|
||||
|
||||
$redis->setOption(self::REDIS_OPT_PREFIX, self::TOKEN_PREFIX);
|
||||
|
||||
$this->redis = $redis;
|
||||
}
|
||||
|
||||
return $this->redis;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set instance of the Redis.
|
||||
*
|
||||
* @param \Redis $redis
|
||||
*/
|
||||
public function setRedis($redis)
|
||||
{
|
||||
$this->redis = $redis;
|
||||
}
|
||||
|
||||
private function createProfileFromData($token, $data, $parent = null)
|
||||
{
|
||||
$profile = new Profile($token);
|
||||
$profile->setIp($data['ip']);
|
||||
$profile->setMethod($data['method']);
|
||||
$profile->setUrl($data['url']);
|
||||
$profile->setTime($data['time']);
|
||||
$profile->setCollectors($data['data']);
|
||||
|
||||
if (!$parent && $data['parent']) {
|
||||
$parent = $this->read($data['parent']);
|
||||
}
|
||||
|
||||
if ($parent) {
|
||||
$profile->setParent($parent);
|
||||
}
|
||||
|
||||
foreach ($data['children'] as $token) {
|
||||
if (!$token) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!$childProfileData = $this->getValue($this->getItemName($token), self::REDIS_SERIALIZER_PHP)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$profile->addChild($this->createProfileFromData($token, $childProfileData, $profile));
|
||||
}
|
||||
|
||||
return $profile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the item name.
|
||||
*
|
||||
* @param string $token
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getItemName($token)
|
||||
{
|
||||
$name = $token;
|
||||
|
||||
if ($this->isItemNameValid($name)) {
|
||||
return $name;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the index.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getIndexName()
|
||||
{
|
||||
$name = 'index';
|
||||
|
||||
if ($this->isItemNameValid($name)) {
|
||||
return $name;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function isItemNameValid($name)
|
||||
{
|
||||
$length = strlen($name);
|
||||
|
||||
if ($length > 2147483648) {
|
||||
throw new \RuntimeException(sprintf('The Redis item key "%s" is too long (%s bytes). Allowed maximum size is 2^31 bytes.', $name, $length));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves an item from the Redis server.
|
||||
*
|
||||
* @param string $key
|
||||
* @param int $serializer
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private function getValue($key, $serializer = self::REDIS_SERIALIZER_NONE)
|
||||
{
|
||||
$redis = $this->getRedis();
|
||||
$redis->setOption(self::REDIS_OPT_SERIALIZER, $serializer);
|
||||
|
||||
return $redis->get($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores an item on the Redis server under the specified key.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param int $expiration
|
||||
* @param int $serializer
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function setValue($key, $value, $expiration = 0, $serializer = self::REDIS_SERIALIZER_NONE)
|
||||
{
|
||||
$redis = $this->getRedis();
|
||||
$redis->setOption(self::REDIS_OPT_SERIALIZER, $serializer);
|
||||
|
||||
return $redis->setex($key, $expiration, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends data to an existing item on the Redis server.
|
||||
*
|
||||
* @param string $key
|
||||
* @param string $value
|
||||
* @param int $expiration
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function appendValue($key, $value, $expiration = 0)
|
||||
{
|
||||
$redis = $this->getRedis();
|
||||
$redis->setOption(self::REDIS_OPT_SERIALIZER, self::REDIS_SERIALIZER_NONE);
|
||||
|
||||
if ($redis->exists($key)) {
|
||||
$redis->append($key, $value);
|
||||
|
||||
return $redis->setTimeout($key, $expiration);
|
||||
}
|
||||
|
||||
return $redis->setex($key, $expiration, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the specified keys.
|
||||
*
|
||||
* @param array $keys
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function delete(array $keys)
|
||||
{
|
||||
return (bool) $this->getRedis()->delete($keys);
|
||||
}
|
||||
}
|
144
web/vendor/symfony/http-kernel/Profiler/SqliteProfilerStorage.php
vendored
Normal file
144
web/vendor/symfony/http-kernel/Profiler/SqliteProfilerStorage.php
vendored
Normal file
|
@ -0,0 +1,144 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Profiler;
|
||||
|
||||
@trigger_error('The '.__NAMESPACE__.'\SqliteProfilerStorage class is deprecated since Symfony 2.8 and will be removed in 3.0. Use FileProfilerStorage instead.', E_USER_DEPRECATED);
|
||||
|
||||
/**
|
||||
* SqliteProfilerStorage stores profiling information in a SQLite database.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @deprecated Deprecated since Symfony 2.8, to be removed in Symfony 3.0.
|
||||
* Use {@link FileProfilerStorage} instead.
|
||||
*/
|
||||
class SqliteProfilerStorage extends PdoProfilerStorage
|
||||
{
|
||||
/**
|
||||
* @throws \RuntimeException When neither of SQLite3 or PDO_SQLite extension is enabled
|
||||
*/
|
||||
protected function initDb()
|
||||
{
|
||||
if (null === $this->db || $this->db instanceof \SQLite3) {
|
||||
if (0 !== strpos($this->dsn, 'sqlite')) {
|
||||
throw new \RuntimeException(sprintf('Please check your configuration. You are trying to use Sqlite with an invalid dsn "%s". The expected format is "sqlite:/path/to/the/db/file".', $this->dsn));
|
||||
}
|
||||
if (class_exists('SQLite3')) {
|
||||
$db = new \SQLite3(substr($this->dsn, 7, strlen($this->dsn)), \SQLITE3_OPEN_READWRITE | \SQLITE3_OPEN_CREATE);
|
||||
if (method_exists($db, 'busyTimeout')) {
|
||||
// busyTimeout only exists for PHP >= 5.3.3
|
||||
$db->busyTimeout(1000);
|
||||
}
|
||||
} elseif (class_exists('PDO') && in_array('sqlite', \PDO::getAvailableDrivers(), true)) {
|
||||
$db = new \PDO($this->dsn);
|
||||
} else {
|
||||
throw new \RuntimeException('You need to enable either the SQLite3 or PDO_SQLite extension for the profiler to run properly.');
|
||||
}
|
||||
|
||||
$db->exec('PRAGMA temp_store=MEMORY; PRAGMA journal_mode=MEMORY;');
|
||||
$db->exec('CREATE TABLE IF NOT EXISTS sf_profiler_data (token STRING, data STRING, ip STRING, method STRING, url STRING, time INTEGER, parent STRING, created_at INTEGER, status_code INTEGER)');
|
||||
$db->exec('CREATE INDEX IF NOT EXISTS data_created_at ON sf_profiler_data (created_at)');
|
||||
$db->exec('CREATE INDEX IF NOT EXISTS data_ip ON sf_profiler_data (ip)');
|
||||
$db->exec('CREATE INDEX IF NOT EXISTS data_method ON sf_profiler_data (method)');
|
||||
$db->exec('CREATE INDEX IF NOT EXISTS data_url ON sf_profiler_data (url)');
|
||||
$db->exec('CREATE INDEX IF NOT EXISTS data_parent ON sf_profiler_data (parent)');
|
||||
$db->exec('CREATE UNIQUE INDEX IF NOT EXISTS data_token ON sf_profiler_data (token)');
|
||||
|
||||
$this->db = $db;
|
||||
}
|
||||
|
||||
return $this->db;
|
||||
}
|
||||
|
||||
protected function exec($db, $query, array $args = array())
|
||||
{
|
||||
if ($db instanceof \SQLite3) {
|
||||
$stmt = $this->prepareStatement($db, $query);
|
||||
foreach ($args as $arg => $val) {
|
||||
$stmt->bindValue($arg, $val, is_int($val) ? \SQLITE3_INTEGER : \SQLITE3_TEXT);
|
||||
}
|
||||
|
||||
$res = $stmt->execute();
|
||||
if (false === $res) {
|
||||
throw new \RuntimeException(sprintf('Error executing SQLite query "%s"', $query));
|
||||
}
|
||||
$res->finalize();
|
||||
} else {
|
||||
parent::exec($db, $query, $args);
|
||||
}
|
||||
}
|
||||
|
||||
protected function fetch($db, $query, array $args = array())
|
||||
{
|
||||
$return = array();
|
||||
|
||||
if ($db instanceof \SQLite3) {
|
||||
$stmt = $this->prepareStatement($db, $query);
|
||||
foreach ($args as $arg => $val) {
|
||||
$stmt->bindValue($arg, $val, is_int($val) ? \SQLITE3_INTEGER : \SQLITE3_TEXT);
|
||||
}
|
||||
$res = $stmt->execute();
|
||||
while ($row = $res->fetchArray(\SQLITE3_ASSOC)) {
|
||||
$return[] = $row;
|
||||
}
|
||||
$res->finalize();
|
||||
$stmt->close();
|
||||
} else {
|
||||
$return = parent::fetch($db, $query, $args);
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function buildCriteria($ip, $url, $start, $end, $limit, $method)
|
||||
{
|
||||
$criteria = array();
|
||||
$args = array();
|
||||
|
||||
if ($ip = preg_replace('/[^\d\.]/', '', $ip)) {
|
||||
$criteria[] = 'ip LIKE :ip';
|
||||
$args[':ip'] = '%'.$ip.'%';
|
||||
}
|
||||
|
||||
if ($url) {
|
||||
$criteria[] = 'url LIKE :url ESCAPE "\"';
|
||||
$args[':url'] = '%'.addcslashes($url, '%_\\').'%';
|
||||
}
|
||||
|
||||
if ($method) {
|
||||
$criteria[] = 'method = :method';
|
||||
$args[':method'] = $method;
|
||||
}
|
||||
|
||||
if (!empty($start)) {
|
||||
$criteria[] = 'time >= :start';
|
||||
$args[':start'] = $start;
|
||||
}
|
||||
|
||||
if (!empty($end)) {
|
||||
$criteria[] = 'time <= :end';
|
||||
$args[':end'] = $end;
|
||||
}
|
||||
|
||||
return array($criteria, $args);
|
||||
}
|
||||
|
||||
protected function close($db)
|
||||
{
|
||||
if ($db instanceof \SQLite3) {
|
||||
$db->close();
|
||||
}
|
||||
}
|
||||
}
|
Reference in a new issue