Include composer dependencies in repo
This commit is contained in:
21
vendor/fguillot/json-rpc/LICENSE
vendored
Normal file
21
vendor/fguillot/json-rpc/LICENSE
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Frederic Guillot
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
194
vendor/fguillot/json-rpc/src/JsonRPC/Client.php
vendored
Normal file
194
vendor/fguillot/json-rpc/src/JsonRPC/Client.php
vendored
Normal file
@@ -0,0 +1,194 @@
|
||||
<?php
|
||||
|
||||
namespace JsonRPC;
|
||||
|
||||
use Exception;
|
||||
use JsonRPC\Request\RequestBuilder;
|
||||
use JsonRPC\Response\ResponseParser;
|
||||
|
||||
/**
|
||||
* JsonRPC client class
|
||||
*
|
||||
* @package JsonRPC
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class Client
|
||||
{
|
||||
/**
|
||||
* If the only argument passed to a function is an array
|
||||
* assume it contains named arguments
|
||||
*
|
||||
* @access private
|
||||
* @var boolean
|
||||
*/
|
||||
private $isNamedArguments = true;
|
||||
|
||||
/**
|
||||
* Do not immediately throw an exception on error. Return it instead.
|
||||
*
|
||||
* @access public
|
||||
* @var boolean
|
||||
*/
|
||||
private $returnException = false;
|
||||
|
||||
/**
|
||||
* True for a batch request
|
||||
*
|
||||
* @access private
|
||||
* @var boolean
|
||||
*/
|
||||
private $isBatch = false;
|
||||
|
||||
/**
|
||||
* Batch payload
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
private $batch = array();
|
||||
|
||||
/**
|
||||
* Http Client
|
||||
*
|
||||
* @access private
|
||||
* @var HttpClient
|
||||
*/
|
||||
private $httpClient;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @access public
|
||||
* @param string $url Server URL
|
||||
* @param bool $returnException Return exceptions
|
||||
* @param HttpClient $httpClient HTTP client object
|
||||
*/
|
||||
public function __construct($url = '', $returnException = false, HttpClient $httpClient = null)
|
||||
{
|
||||
$this->httpClient = $httpClient ?: new HttpClient($url);
|
||||
$this->returnException = $returnException;
|
||||
}
|
||||
|
||||
/**
|
||||
* Arguments passed are always positional
|
||||
*
|
||||
* @access public
|
||||
* @return $this
|
||||
*/
|
||||
public function withPositionalArguments()
|
||||
{
|
||||
$this->isNamedArguments = false;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get HTTP Client
|
||||
*
|
||||
* @access public
|
||||
* @return HttpClient
|
||||
*/
|
||||
public function getHttpClient()
|
||||
{
|
||||
return $this->httpClient;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set username and password
|
||||
*
|
||||
* @access public
|
||||
* @param string $username
|
||||
* @param string $password
|
||||
* @return $this
|
||||
*/
|
||||
public function authentication($username, $password)
|
||||
{
|
||||
$this->httpClient
|
||||
->withUsername($username)
|
||||
->withPassword($password);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Automatic mapping of procedures
|
||||
*
|
||||
* @access public
|
||||
* @param string $method Procedure name
|
||||
* @param array $params Procedure arguments
|
||||
* @return mixed
|
||||
*/
|
||||
public function __call($method, array $params)
|
||||
{
|
||||
if ($this->isNamedArguments && count($params) === 1 && is_array($params[0])) {
|
||||
$params = $params[0];
|
||||
}
|
||||
|
||||
return $this->execute($method, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a batch request
|
||||
*
|
||||
* @access public
|
||||
* @return Client
|
||||
*/
|
||||
public function batch()
|
||||
{
|
||||
$this->isBatch = true;
|
||||
$this->batch = array();
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a batch request
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function send()
|
||||
{
|
||||
$this->isBatch = false;
|
||||
return $this->sendPayload('['.implode(', ', $this->batch).']');
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a procedure
|
||||
*
|
||||
* @access public
|
||||
* @param string $procedure Procedure name
|
||||
* @param array $params Procedure arguments
|
||||
* @param array $reqattrs
|
||||
* @return mixed
|
||||
*/
|
||||
public function execute($procedure, array $params = array(), array $reqattrs = array())
|
||||
{
|
||||
$payload = RequestBuilder::create()
|
||||
->withProcedure($procedure)
|
||||
->withParams($params)
|
||||
->withRequestAttributes($reqattrs)
|
||||
->build();
|
||||
|
||||
if ($this->isBatch) {
|
||||
$this->batch[] = $payload;
|
||||
return $this;
|
||||
}
|
||||
|
||||
return $this->sendPayload($payload);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send payload
|
||||
*
|
||||
* @access private
|
||||
* @throws Exception
|
||||
* @param string $payload
|
||||
* @return Exception|Client
|
||||
*/
|
||||
private function sendPayload($payload)
|
||||
{
|
||||
return ResponseParser::create()
|
||||
->withReturnException($this->returnException)
|
||||
->withPayload($this->httpClient->execute($payload))
|
||||
->parse();
|
||||
}
|
||||
}
|
||||
15
vendor/fguillot/json-rpc/src/JsonRPC/Exception/AccessDeniedException.php
vendored
Normal file
15
vendor/fguillot/json-rpc/src/JsonRPC/Exception/AccessDeniedException.php
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace JsonRPC\Exception;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Class AccessDeniedException
|
||||
*
|
||||
* @package JsonRPC\Exception
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class AccessDeniedException extends Exception
|
||||
{
|
||||
}
|
||||
15
vendor/fguillot/json-rpc/src/JsonRPC/Exception/AuthenticationFailureException.php
vendored
Normal file
15
vendor/fguillot/json-rpc/src/JsonRPC/Exception/AuthenticationFailureException.php
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace JsonRPC\Exception;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Class AuthenticationFailureException
|
||||
*
|
||||
* @package JsonRPC\Exception
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class AuthenticationFailureException extends Exception
|
||||
{
|
||||
}
|
||||
15
vendor/fguillot/json-rpc/src/JsonRPC/Exception/ConnectionFailureException.php
vendored
Normal file
15
vendor/fguillot/json-rpc/src/JsonRPC/Exception/ConnectionFailureException.php
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace JsonRPC\Exception;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Class ConnectionFailureException
|
||||
*
|
||||
* @package JsonRPC\Exception
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class ConnectionFailureException extends Exception
|
||||
{
|
||||
}
|
||||
15
vendor/fguillot/json-rpc/src/JsonRPC/Exception/InvalidJsonFormatException.php
vendored
Normal file
15
vendor/fguillot/json-rpc/src/JsonRPC/Exception/InvalidJsonFormatException.php
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace JsonRPC\Exception;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Class InvalidJsonFormatException
|
||||
*
|
||||
* @package JsonRPC\Exception
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class InvalidJsonFormatException extends Exception
|
||||
{
|
||||
}
|
||||
15
vendor/fguillot/json-rpc/src/JsonRPC/Exception/InvalidJsonRpcFormatException.php
vendored
Normal file
15
vendor/fguillot/json-rpc/src/JsonRPC/Exception/InvalidJsonRpcFormatException.php
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace JsonRPC\Exception;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Class InvalidJsonRpcFormatException
|
||||
*
|
||||
* @package JsonRPC\Exception
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class InvalidJsonRpcFormatException extends Exception
|
||||
{
|
||||
}
|
||||
15
vendor/fguillot/json-rpc/src/JsonRPC/Exception/ResponseEncodingFailureException.php
vendored
Normal file
15
vendor/fguillot/json-rpc/src/JsonRPC/Exception/ResponseEncodingFailureException.php
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace JsonRPC\Exception;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Class ResponseEncodingFailureException
|
||||
*
|
||||
* @package JsonRPC\Exception
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class ResponseEncodingFailureException extends Exception
|
||||
{
|
||||
}
|
||||
62
vendor/fguillot/json-rpc/src/JsonRPC/Exception/ResponseException.php
vendored
Normal file
62
vendor/fguillot/json-rpc/src/JsonRPC/Exception/ResponseException.php
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace JsonRPC\Exception;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Class ResponseException
|
||||
*
|
||||
* @package JsonRPC\Exception
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class ResponseException extends Exception
|
||||
{
|
||||
/**
|
||||
* A value that contains additional information about the error.
|
||||
*
|
||||
* @access protected
|
||||
* @link http://www.jsonrpc.org/specification#error_object
|
||||
* @var mixed
|
||||
*/
|
||||
protected $data;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @access public
|
||||
* @param string $message [optional] The Exception message to throw.
|
||||
* @param int $code [optional] The Exception code.
|
||||
* @param Exception $previous [optional] The previous exception used for the exception chaining. Since 5.3.0
|
||||
* @param mixed $data [optional] A value that contains additional information about the error.
|
||||
*/
|
||||
public function __construct($message = '', $code = 0, Exception $previous = null, $data = null)
|
||||
{
|
||||
parent::__construct($message, $code, $previous);
|
||||
$this->setData($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attach additional information
|
||||
*
|
||||
* @access public
|
||||
* @param mixed $data [optional] A value that contains additional information about the error.
|
||||
* @return \JsonRPC\Exception\ResponseException
|
||||
*/
|
||||
public function setData($data = null)
|
||||
{
|
||||
$this->data = $data;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get additional information
|
||||
*
|
||||
* @access public
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function getData()
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
}
|
||||
15
vendor/fguillot/json-rpc/src/JsonRPC/Exception/ServerErrorException.php
vendored
Normal file
15
vendor/fguillot/json-rpc/src/JsonRPC/Exception/ServerErrorException.php
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace JsonRPC\Exception;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Class ServerErrorException
|
||||
*
|
||||
* @package JsonRPC\Exception
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class ServerErrorException extends Exception
|
||||
{
|
||||
}
|
||||
365
vendor/fguillot/json-rpc/src/JsonRPC/HttpClient.php
vendored
Normal file
365
vendor/fguillot/json-rpc/src/JsonRPC/HttpClient.php
vendored
Normal file
@@ -0,0 +1,365 @@
|
||||
<?php
|
||||
|
||||
namespace JsonRPC;
|
||||
|
||||
use Closure;
|
||||
use JsonRPC\Exception\AccessDeniedException;
|
||||
use JsonRPC\Exception\ConnectionFailureException;
|
||||
use JsonRPC\Exception\ServerErrorException;
|
||||
|
||||
/**
|
||||
* Class HttpClient
|
||||
*
|
||||
* @package JsonRPC
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class HttpClient
|
||||
{
|
||||
/**
|
||||
* URL of the server
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
private $url;
|
||||
|
||||
/**
|
||||
* HTTP client timeout
|
||||
*
|
||||
* @access private
|
||||
* @var integer
|
||||
*/
|
||||
private $timeout = 5;
|
||||
|
||||
/**
|
||||
* Default HTTP headers to send to the server
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
private $headers = array(
|
||||
'User-Agent: JSON-RPC PHP Client <https://github.com/fguillot/JsonRPC>',
|
||||
'Content-Type: application/json',
|
||||
'Accept: application/json',
|
||||
'Connection: close',
|
||||
);
|
||||
|
||||
/**
|
||||
* Username for authentication
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
private $username;
|
||||
|
||||
/**
|
||||
* Password for authentication
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
private $password;
|
||||
|
||||
/**
|
||||
* Enable debug output to the php error log
|
||||
*
|
||||
* @access private
|
||||
* @var boolean
|
||||
*/
|
||||
private $debug = false;
|
||||
|
||||
/**
|
||||
* Cookies
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
private $cookies = array();
|
||||
|
||||
/**
|
||||
* SSL certificates verification
|
||||
*
|
||||
* @access private
|
||||
* @var boolean
|
||||
*/
|
||||
private $verifySslCertificate = true;
|
||||
|
||||
/**
|
||||
* Callback called before the doing the request
|
||||
*
|
||||
* @access private
|
||||
* @var Closure
|
||||
*/
|
||||
private $beforeRequest;
|
||||
|
||||
/**
|
||||
* HttpClient constructor
|
||||
*
|
||||
* @access public
|
||||
* @param string $url
|
||||
*/
|
||||
public function __construct($url = '')
|
||||
{
|
||||
$this->url = $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set URL
|
||||
*
|
||||
* @access public
|
||||
* @param string $url
|
||||
* @return $this
|
||||
*/
|
||||
public function withUrl($url)
|
||||
{
|
||||
$this->url = $url;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set username
|
||||
*
|
||||
* @access public
|
||||
* @param string $username
|
||||
* @return $this
|
||||
*/
|
||||
public function withUsername($username)
|
||||
{
|
||||
$this->username = $username;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set password
|
||||
*
|
||||
* @access public
|
||||
* @param string $password
|
||||
* @return $this
|
||||
*/
|
||||
public function withPassword($password)
|
||||
{
|
||||
$this->password = $password;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set timeout
|
||||
*
|
||||
* @access public
|
||||
* @param integer $timeout
|
||||
* @return $this
|
||||
*/
|
||||
public function withTimeout($timeout)
|
||||
{
|
||||
$this->timeout = $timeout;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set timeout
|
||||
*
|
||||
* @access public
|
||||
* @param array $headers
|
||||
* @return $this
|
||||
*/
|
||||
public function withHeaders(array $headers)
|
||||
{
|
||||
$this->headers = array_merge($this->headers, $headers);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set cookies
|
||||
*
|
||||
* @access public
|
||||
* @param array $cookies
|
||||
* @param boolean $replace
|
||||
*/
|
||||
public function withCookies(array $cookies, $replace = false)
|
||||
{
|
||||
if ($replace) {
|
||||
$this->cookies = $cookies;
|
||||
} else {
|
||||
$this->cookies = array_merge($this->cookies, $cookies);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable debug mode
|
||||
*
|
||||
* @access public
|
||||
* @return $this
|
||||
*/
|
||||
public function withDebug()
|
||||
{
|
||||
$this->debug = true;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable SSL verification
|
||||
*
|
||||
* @access public
|
||||
* @return $this
|
||||
*/
|
||||
public function withoutSslVerification()
|
||||
{
|
||||
$this->verifySslCertificate = false;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign a callback before the request
|
||||
*
|
||||
* @access public
|
||||
* @param Closure $closure
|
||||
* @return $this
|
||||
*/
|
||||
public function withBeforeRequestCallback(Closure $closure)
|
||||
{
|
||||
$this->beforeRequest = $closure;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cookies
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getCookies()
|
||||
{
|
||||
return $this->cookies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do the HTTP request
|
||||
*
|
||||
* @access public
|
||||
* @throws ConnectionFailureException
|
||||
* @param string $payload
|
||||
* @return array
|
||||
*/
|
||||
public function execute($payload)
|
||||
{
|
||||
if (is_callable($this->beforeRequest)) {
|
||||
call_user_func_array($this->beforeRequest, array($this, $payload));
|
||||
}
|
||||
|
||||
$stream = fopen(trim($this->url), 'r', false, $this->buildContext($payload));
|
||||
|
||||
if (! is_resource($stream)) {
|
||||
throw new ConnectionFailureException('Unable to establish a connection');
|
||||
}
|
||||
|
||||
$metadata = stream_get_meta_data($stream);
|
||||
$headers = $metadata['wrapper_data'];
|
||||
$response = json_decode(stream_get_contents($stream), true);
|
||||
|
||||
if ($this->debug) {
|
||||
error_log('==> Request: '.PHP_EOL.(is_string($payload) ? $payload : json_encode($payload, JSON_PRETTY_PRINT)));
|
||||
error_log('==> Headers: '.PHP_EOL.var_export($headers, true));
|
||||
error_log('==> Response: '.PHP_EOL.json_encode($response, JSON_PRETTY_PRINT));
|
||||
}
|
||||
|
||||
$this->handleExceptions($headers);
|
||||
$this->parseCookies($headers);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare stream context
|
||||
*
|
||||
* @access private
|
||||
* @param string $payload
|
||||
* @return resource
|
||||
*/
|
||||
private function buildContext($payload)
|
||||
{
|
||||
$headers = $this->headers;
|
||||
|
||||
if (! empty($this->username) && ! empty($this->password)) {
|
||||
$headers[] = 'Authorization: Basic '.base64_encode($this->username.':'.$this->password);
|
||||
}
|
||||
|
||||
if (! empty($this->cookies)){
|
||||
$cookies = array();
|
||||
|
||||
foreach ($this->cookies as $key => $value) {
|
||||
$cookies[] = $key.'='.$value;
|
||||
}
|
||||
|
||||
$headers[] = 'Cookie: '.implode('; ', $cookies);
|
||||
}
|
||||
|
||||
return stream_context_create(array(
|
||||
'http' => array(
|
||||
'method' => 'POST',
|
||||
'protocol_version' => 1.1,
|
||||
'timeout' => $this->timeout,
|
||||
'max_redirects' => 2,
|
||||
'header' => implode("\r\n", $headers),
|
||||
'content' => $payload,
|
||||
'ignore_errors' => true,
|
||||
),
|
||||
'ssl' => array(
|
||||
'verify_peer' => $this->verifySslCertificate,
|
||||
'verify_peer_name' => $this->verifySslCertificate,
|
||||
)
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse cookies from response
|
||||
*
|
||||
* @access private
|
||||
* @param array $headers
|
||||
*/
|
||||
private function parseCookies(array $headers)
|
||||
{
|
||||
foreach ($headers as $header) {
|
||||
$pos = stripos($header, 'Set-Cookie:');
|
||||
|
||||
if ($pos !== false) {
|
||||
$cookies = explode(';', substr($header, $pos + 11));
|
||||
|
||||
foreach ($cookies as $cookie) {
|
||||
$item = explode('=', $cookie);
|
||||
|
||||
if (count($item) === 2) {
|
||||
$name = trim($item[0]);
|
||||
$value = $item[1];
|
||||
$this->cookies[$name] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Throw an exception according the HTTP response
|
||||
*
|
||||
* @access public
|
||||
* @param array $headers
|
||||
* @throws AccessDeniedException
|
||||
* @throws ServerErrorException
|
||||
*/
|
||||
public function handleExceptions(array $headers)
|
||||
{
|
||||
$exceptions = array(
|
||||
'401' => '\JsonRPC\Exception\AccessDeniedException',
|
||||
'403' => '\JsonRPC\Exception\AccessDeniedException',
|
||||
'404' => '\JsonRPC\Exception\ConnectionFailureException',
|
||||
'500' => '\JsonRPC\Exception\ServerErrorException',
|
||||
);
|
||||
|
||||
foreach ($headers as $header) {
|
||||
foreach ($exceptions as $code => $exception) {
|
||||
if (strpos($header, 'HTTP/1.0 '.$code) !== false || strpos($header, 'HTTP/1.1 '.$code) !== false) {
|
||||
throw new $exception('Response: '.$header);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
114
vendor/fguillot/json-rpc/src/JsonRPC/MiddlewareHandler.php
vendored
Normal file
114
vendor/fguillot/json-rpc/src/JsonRPC/MiddlewareHandler.php
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
|
||||
namespace JsonRPC;
|
||||
|
||||
/**
|
||||
* Class MiddlewareHandler
|
||||
*
|
||||
* @package JsonRPC
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class MiddlewareHandler
|
||||
{
|
||||
/**
|
||||
* Procedure Name
|
||||
*
|
||||
* @access protected
|
||||
* @var string
|
||||
*/
|
||||
protected $procedureName = '';
|
||||
|
||||
/**
|
||||
* Username
|
||||
*
|
||||
* @access protected
|
||||
* @var string
|
||||
*/
|
||||
protected $username = '';
|
||||
|
||||
/**
|
||||
* Password
|
||||
*
|
||||
* @access protected
|
||||
* @var string
|
||||
*/
|
||||
protected $password = '';
|
||||
|
||||
/**
|
||||
* List of middleware to execute before to call the method
|
||||
*
|
||||
* @access protected
|
||||
* @var MiddlewareInterface[]
|
||||
*/
|
||||
protected $middleware = array();
|
||||
|
||||
/**
|
||||
* Set username
|
||||
*
|
||||
* @access public
|
||||
* @param string $username
|
||||
* @return $this
|
||||
*/
|
||||
public function withUsername($username)
|
||||
{
|
||||
if (! empty($username)) {
|
||||
$this->username = $username;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set password
|
||||
*
|
||||
* @access public
|
||||
* @param string $password
|
||||
* @return $this
|
||||
*/
|
||||
public function withPassword($password)
|
||||
{
|
||||
if (! empty($password)) {
|
||||
$this->password = $password;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set procedure name
|
||||
*
|
||||
* @access public
|
||||
* @param string $procedureName
|
||||
* @return $this
|
||||
*/
|
||||
public function withProcedure($procedureName)
|
||||
{
|
||||
$this->procedureName = $procedureName;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new middleware
|
||||
*
|
||||
* @access public
|
||||
* @param MiddlewareInterface $middleware
|
||||
* @return MiddlewareHandler
|
||||
*/
|
||||
public function withMiddleware(MiddlewareInterface $middleware)
|
||||
{
|
||||
$this->middleware[] = $middleware;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute all middleware
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
foreach ($this->middleware as $middleware) {
|
||||
$middleware->execute($this->username, $this->password, $this->procedureName);
|
||||
}
|
||||
}
|
||||
}
|
||||
27
vendor/fguillot/json-rpc/src/JsonRPC/MiddlewareInterface.php
vendored
Normal file
27
vendor/fguillot/json-rpc/src/JsonRPC/MiddlewareInterface.php
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace JsonRPC;
|
||||
|
||||
use JsonRPC\Exception\AccessDeniedException;
|
||||
use JsonRPC\Exception\AuthenticationFailureException;
|
||||
|
||||
/**
|
||||
* Interface MiddlewareInterface
|
||||
*
|
||||
* @package JsonRPC
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
interface MiddlewareInterface
|
||||
{
|
||||
/**
|
||||
* Execute Middleware
|
||||
*
|
||||
* @access public
|
||||
* @param string $username
|
||||
* @param string $password
|
||||
* @param string $procedureName
|
||||
* @throws AccessDeniedException
|
||||
* @throws AuthenticationFailureException
|
||||
*/
|
||||
public function execute($username, $password, $procedureName);
|
||||
}
|
||||
264
vendor/fguillot/json-rpc/src/JsonRPC/ProcedureHandler.php
vendored
Normal file
264
vendor/fguillot/json-rpc/src/JsonRPC/ProcedureHandler.php
vendored
Normal file
@@ -0,0 +1,264 @@
|
||||
<?php
|
||||
|
||||
namespace JsonRPC;
|
||||
|
||||
use BadFunctionCallException;
|
||||
use Closure;
|
||||
use InvalidArgumentException;
|
||||
use ReflectionFunction;
|
||||
use ReflectionMethod;
|
||||
|
||||
/**
|
||||
* Class ProcedureHandler
|
||||
*
|
||||
* @package JsonRPC
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class ProcedureHandler
|
||||
{
|
||||
/**
|
||||
* List of procedures
|
||||
*
|
||||
* @access protected
|
||||
* @var array
|
||||
*/
|
||||
protected $callbacks = array();
|
||||
|
||||
/**
|
||||
* List of classes
|
||||
*
|
||||
* @access protected
|
||||
* @var array
|
||||
*/
|
||||
protected $classes = array();
|
||||
|
||||
/**
|
||||
* List of instances
|
||||
*
|
||||
* @access protected
|
||||
* @var array
|
||||
*/
|
||||
protected $instances = array();
|
||||
|
||||
/**
|
||||
* Before method name to call
|
||||
*
|
||||
* @access protected
|
||||
* @var string
|
||||
*/
|
||||
protected $beforeMethodName = '';
|
||||
|
||||
/**
|
||||
* Register a new procedure
|
||||
*
|
||||
* @access public
|
||||
* @param string $procedure Procedure name
|
||||
* @param closure $callback Callback
|
||||
* @return $this
|
||||
*/
|
||||
public function withCallback($procedure, Closure $callback)
|
||||
{
|
||||
$this->callbacks[$procedure] = $callback;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bind a procedure to a class
|
||||
*
|
||||
* @access public
|
||||
* @param string $procedure Procedure name
|
||||
* @param mixed $class Class name or instance
|
||||
* @param string $method Procedure name
|
||||
* @return $this
|
||||
*/
|
||||
public function withClassAndMethod($procedure, $class, $method = '')
|
||||
{
|
||||
if ($method === '') {
|
||||
$method = $procedure;
|
||||
}
|
||||
|
||||
$this->classes[$procedure] = array($class, $method);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bind a class instance
|
||||
*
|
||||
* @access public
|
||||
* @param mixed $instance
|
||||
* @return $this
|
||||
*/
|
||||
public function withObject($instance)
|
||||
{
|
||||
$this->instances[] = $instance;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a before method to call
|
||||
*
|
||||
* @access public
|
||||
* @param string $methodName
|
||||
* @return $this
|
||||
*/
|
||||
public function withBeforeMethod($methodName)
|
||||
{
|
||||
$this->beforeMethodName = $methodName;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the procedure
|
||||
*
|
||||
* @access public
|
||||
* @param string $procedure Procedure name
|
||||
* @param array $params Procedure params
|
||||
* @return mixed
|
||||
*/
|
||||
public function executeProcedure($procedure, array $params = array())
|
||||
{
|
||||
if (isset($this->callbacks[$procedure])) {
|
||||
return $this->executeCallback($this->callbacks[$procedure], $params);
|
||||
} elseif (isset($this->classes[$procedure]) && method_exists($this->classes[$procedure][0], $this->classes[$procedure][1])) {
|
||||
return $this->executeMethod($this->classes[$procedure][0], $this->classes[$procedure][1], $params);
|
||||
}
|
||||
|
||||
foreach ($this->instances as $instance) {
|
||||
if (method_exists($instance, $procedure)) {
|
||||
return $this->executeMethod($instance, $procedure, $params);
|
||||
}
|
||||
}
|
||||
|
||||
throw new BadFunctionCallException('Unable to find the procedure');
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a callback
|
||||
*
|
||||
* @access public
|
||||
* @param Closure $callback Callback
|
||||
* @param array $params Procedure params
|
||||
* @return mixed
|
||||
*/
|
||||
public function executeCallback(Closure $callback, $params)
|
||||
{
|
||||
$reflection = new ReflectionFunction($callback);
|
||||
|
||||
$arguments = $this->getArguments(
|
||||
$params,
|
||||
$reflection->getParameters(),
|
||||
$reflection->getNumberOfRequiredParameters(),
|
||||
$reflection->getNumberOfParameters()
|
||||
);
|
||||
|
||||
return $reflection->invokeArgs($arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a method
|
||||
*
|
||||
* @access public
|
||||
* @param mixed $class Class name or instance
|
||||
* @param string $method Method name
|
||||
* @param array $params Procedure params
|
||||
* @return mixed
|
||||
*/
|
||||
public function executeMethod($class, $method, $params)
|
||||
{
|
||||
$instance = is_string($class) ? new $class : $class;
|
||||
$reflection = new ReflectionMethod($class, $method);
|
||||
|
||||
$this->executeBeforeMethod($instance, $method);
|
||||
|
||||
$arguments = $this->getArguments(
|
||||
$params,
|
||||
$reflection->getParameters(),
|
||||
$reflection->getNumberOfRequiredParameters(),
|
||||
$reflection->getNumberOfParameters()
|
||||
);
|
||||
|
||||
return $reflection->invokeArgs($instance, $arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute before method if defined
|
||||
*
|
||||
* @access public
|
||||
* @param mixed $object
|
||||
* @param string $method
|
||||
*/
|
||||
public function executeBeforeMethod($object, $method)
|
||||
{
|
||||
if ($this->beforeMethodName !== '' && method_exists($object, $this->beforeMethodName)) {
|
||||
call_user_func_array(array($object, $this->beforeMethodName), array($method));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get procedure arguments
|
||||
*
|
||||
* @access public
|
||||
* @param array $requestParams Incoming arguments
|
||||
* @param array $methodParams Procedure arguments
|
||||
* @param integer $nbRequiredParams Number of required parameters
|
||||
* @param integer $nbMaxParams Maximum number of parameters
|
||||
* @return array
|
||||
*/
|
||||
public function getArguments(array $requestParams, array $methodParams, $nbRequiredParams, $nbMaxParams)
|
||||
{
|
||||
$nbParams = count($requestParams);
|
||||
|
||||
if ($nbParams < $nbRequiredParams) {
|
||||
throw new InvalidArgumentException('Wrong number of arguments');
|
||||
}
|
||||
|
||||
if ($nbParams > $nbMaxParams) {
|
||||
throw new InvalidArgumentException('Too many arguments');
|
||||
}
|
||||
|
||||
if ($this->isPositionalArguments($requestParams)) {
|
||||
return $requestParams;
|
||||
}
|
||||
|
||||
return $this->getNamedArguments($requestParams, $methodParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if we have positional parameters
|
||||
*
|
||||
* @access public
|
||||
* @param array $request_params Incoming arguments
|
||||
* @return bool
|
||||
*/
|
||||
public function isPositionalArguments(array $request_params)
|
||||
{
|
||||
return array_keys($request_params) === range(0, count($request_params) - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get named arguments
|
||||
*
|
||||
* @access public
|
||||
* @param array $requestParams Incoming arguments
|
||||
* @param array $methodParams Procedure arguments
|
||||
* @return array
|
||||
*/
|
||||
public function getNamedArguments(array $requestParams, array $methodParams)
|
||||
{
|
||||
$params = array();
|
||||
|
||||
foreach ($methodParams as $p) {
|
||||
$name = $p->getName();
|
||||
|
||||
if (isset($requestParams[$name])) {
|
||||
$params[$name] = $requestParams[$name];
|
||||
} elseif ($p->isDefaultValueAvailable()) {
|
||||
$params[$name] = $p->getDefaultValue();
|
||||
} else {
|
||||
throw new InvalidArgumentException('Missing argument: '.$name);
|
||||
}
|
||||
}
|
||||
|
||||
return $params;
|
||||
}
|
||||
}
|
||||
55
vendor/fguillot/json-rpc/src/JsonRPC/Request/BatchRequestParser.php
vendored
Normal file
55
vendor/fguillot/json-rpc/src/JsonRPC/Request/BatchRequestParser.php
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace JsonRPC\Request;
|
||||
|
||||
/**
|
||||
* Class BatchRequestParser
|
||||
*
|
||||
* @package JsonRPC\Request
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class BatchRequestParser extends RequestParser
|
||||
{
|
||||
/**
|
||||
* Parse incoming request
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function parse()
|
||||
{
|
||||
$responses = array();
|
||||
|
||||
foreach ($this->payload as $payload) {
|
||||
$responses[] = RequestParser::create()
|
||||
->withPayload($payload)
|
||||
->withProcedureHandler($this->procedureHandler)
|
||||
->withMiddlewareHandler($this->middlewareHandler)
|
||||
->withLocalException($this->localExceptions)
|
||||
->parse();
|
||||
}
|
||||
|
||||
$responses = array_filter($responses);
|
||||
return empty($responses) ? '' : '['.implode(',', $responses).']';
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if we have a batch request
|
||||
*
|
||||
* ex : [
|
||||
* 0 => '...',
|
||||
* 1 => '...',
|
||||
* 2 => '...',
|
||||
* 3 => '...',
|
||||
* ]
|
||||
*
|
||||
* @static
|
||||
* @access public
|
||||
* @param array $payload
|
||||
* @return bool
|
||||
*/
|
||||
public static function isBatchRequest(array $payload)
|
||||
{
|
||||
return array_keys($payload) === range(0, count($payload) - 1);
|
||||
}
|
||||
}
|
||||
129
vendor/fguillot/json-rpc/src/JsonRPC/Request/RequestBuilder.php
vendored
Normal file
129
vendor/fguillot/json-rpc/src/JsonRPC/Request/RequestBuilder.php
vendored
Normal file
@@ -0,0 +1,129 @@
|
||||
<?php
|
||||
|
||||
namespace JsonRPC\Request;
|
||||
|
||||
/**
|
||||
* Class RequestBuilder
|
||||
*
|
||||
* @package JsonRPC\Request
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class RequestBuilder
|
||||
{
|
||||
/**
|
||||
* Request ID
|
||||
*
|
||||
* @access private
|
||||
* @var mixed
|
||||
*/
|
||||
private $id = null;
|
||||
|
||||
/**
|
||||
* Method name
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
private $procedure = '';
|
||||
|
||||
/**
|
||||
* Method arguments
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
private $params = array();
|
||||
|
||||
/**
|
||||
* Additional request attributes
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
private $reqattrs = array();
|
||||
|
||||
/**
|
||||
* Get new object instance
|
||||
*
|
||||
* @static
|
||||
* @access public
|
||||
* @return RequestBuilder
|
||||
*/
|
||||
public static function create()
|
||||
{
|
||||
return new static();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set id
|
||||
*
|
||||
* @access public
|
||||
* @param null $id
|
||||
* @return RequestBuilder
|
||||
*/
|
||||
public function withId($id)
|
||||
{
|
||||
$this->id = $id;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set method
|
||||
*
|
||||
* @access public
|
||||
* @param string $procedure
|
||||
* @return RequestBuilder
|
||||
*/
|
||||
public function withProcedure($procedure)
|
||||
{
|
||||
$this->procedure = $procedure;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set parameters
|
||||
*
|
||||
* @access public
|
||||
* @param array $params
|
||||
* @return RequestBuilder
|
||||
*/
|
||||
public function withParams(array $params)
|
||||
{
|
||||
$this->params = $params;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set additional request attributes
|
||||
*
|
||||
* @access public
|
||||
* @param array $reqattrs
|
||||
* @return RequestBuilder
|
||||
*/
|
||||
public function withRequestAttributes(array $reqattrs)
|
||||
{
|
||||
$this->reqattrs = $reqattrs;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the payload
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function build()
|
||||
{
|
||||
$payload = array_merge_recursive($this->reqattrs, array(
|
||||
'jsonrpc' => '2.0',
|
||||
'method' => $this->procedure,
|
||||
'id' => $this->id ?: mt_rand(),
|
||||
));
|
||||
|
||||
if (! empty($this->params)) {
|
||||
$payload['params'] = $this->params;
|
||||
}
|
||||
|
||||
return json_encode($payload);
|
||||
}
|
||||
}
|
||||
200
vendor/fguillot/json-rpc/src/JsonRPC/Request/RequestParser.php
vendored
Normal file
200
vendor/fguillot/json-rpc/src/JsonRPC/Request/RequestParser.php
vendored
Normal file
@@ -0,0 +1,200 @@
|
||||
<?php
|
||||
|
||||
namespace JsonRPC\Request;
|
||||
|
||||
use Exception;
|
||||
use JsonRPC\Exception\AccessDeniedException;
|
||||
use JsonRPC\Exception\AuthenticationFailureException;
|
||||
use JsonRPC\Exception\InvalidJsonRpcFormatException;
|
||||
use JsonRPC\MiddlewareHandler;
|
||||
use JsonRPC\ProcedureHandler;
|
||||
use JsonRPC\Response\ResponseBuilder;
|
||||
use JsonRPC\Validator\JsonFormatValidator;
|
||||
use JsonRPC\Validator\RpcFormatValidator;
|
||||
|
||||
/**
|
||||
* Class RequestParser
|
||||
*
|
||||
* @package JsonRPC
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class RequestParser
|
||||
{
|
||||
/**
|
||||
* Request payload
|
||||
*
|
||||
* @access protected
|
||||
* @var mixed
|
||||
*/
|
||||
protected $payload;
|
||||
|
||||
/**
|
||||
* List of exceptions that should not be relayed to the client
|
||||
*
|
||||
* @access protected
|
||||
* @var array()
|
||||
*/
|
||||
protected $localExceptions = array(
|
||||
'JsonRPC\Exception\AuthenticationFailureException',
|
||||
'JsonRPC\Exception\AccessDeniedException',
|
||||
);
|
||||
|
||||
/**
|
||||
* ProcedureHandler
|
||||
*
|
||||
* @access protected
|
||||
* @var ProcedureHandler
|
||||
*/
|
||||
protected $procedureHandler;
|
||||
|
||||
/**
|
||||
* MiddlewareHandler
|
||||
*
|
||||
* @access protected
|
||||
* @var MiddlewareHandler
|
||||
*/
|
||||
protected $middlewareHandler;
|
||||
|
||||
/**
|
||||
* Get new object instance
|
||||
*
|
||||
* @static
|
||||
* @access public
|
||||
* @return RequestParser
|
||||
*/
|
||||
public static function create()
|
||||
{
|
||||
return new static();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set payload
|
||||
*
|
||||
* @access public
|
||||
* @param mixed $payload
|
||||
* @return $this
|
||||
*/
|
||||
public function withPayload($payload)
|
||||
{
|
||||
$this->payload = $payload;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Exception classes that should not be relayed to the client
|
||||
*
|
||||
* @access public
|
||||
* @param mixed $exception
|
||||
* @return $this
|
||||
*/
|
||||
public function withLocalException($exception)
|
||||
{
|
||||
if (is_array($exception)) {
|
||||
$this->localExceptions = array_merge($this->localExceptions, $exception);
|
||||
} else {
|
||||
$this->localExceptions[] = $exception;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set procedure handler
|
||||
*
|
||||
* @access public
|
||||
* @param ProcedureHandler $procedureHandler
|
||||
* @return $this
|
||||
*/
|
||||
public function withProcedureHandler(ProcedureHandler $procedureHandler)
|
||||
{
|
||||
$this->procedureHandler = $procedureHandler;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set middleware handler
|
||||
*
|
||||
* @access public
|
||||
* @param MiddlewareHandler $middlewareHandler
|
||||
* @return $this
|
||||
*/
|
||||
public function withMiddlewareHandler(MiddlewareHandler $middlewareHandler)
|
||||
{
|
||||
$this->middlewareHandler = $middlewareHandler;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse incoming request
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
* @throws AccessDeniedException
|
||||
* @throws AuthenticationFailureException
|
||||
*/
|
||||
public function parse()
|
||||
{
|
||||
try {
|
||||
|
||||
JsonFormatValidator::validate($this->payload);
|
||||
RpcFormatValidator::validate($this->payload);
|
||||
|
||||
$this->middlewareHandler
|
||||
->withProcedure($this->payload['method'])
|
||||
->execute();
|
||||
|
||||
$result = $this->procedureHandler->executeProcedure(
|
||||
$this->payload['method'],
|
||||
empty($this->payload['params']) ? array() : $this->payload['params']
|
||||
);
|
||||
|
||||
if (! $this->isNotification()) {
|
||||
return ResponseBuilder::create()
|
||||
->withId($this->payload['id'])
|
||||
->withResult($result)
|
||||
->build();
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
return $this->handleExceptions($e);
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle exceptions
|
||||
*
|
||||
* @access protected
|
||||
* @param Exception $e
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function handleExceptions(Exception $e)
|
||||
{
|
||||
foreach ($this->localExceptions as $exception) {
|
||||
if ($e instanceof $exception) {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
if ($e instanceof InvalidJsonRpcFormatException || ! $this->isNotification()) {
|
||||
return ResponseBuilder::create()
|
||||
->withId(isset($this->payload['id']) ? $this->payload['id'] : null)
|
||||
->withException($e)
|
||||
->build();
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the message is a notification
|
||||
*
|
||||
* @access protected
|
||||
* @return bool
|
||||
*/
|
||||
protected function isNotification()
|
||||
{
|
||||
return is_array($this->payload) && !isset($this->payload['id']);
|
||||
}
|
||||
}
|
||||
324
vendor/fguillot/json-rpc/src/JsonRPC/Response/ResponseBuilder.php
vendored
Normal file
324
vendor/fguillot/json-rpc/src/JsonRPC/Response/ResponseBuilder.php
vendored
Normal file
@@ -0,0 +1,324 @@
|
||||
<?php
|
||||
|
||||
namespace JsonRPC\Response;
|
||||
|
||||
use BadFunctionCallException;
|
||||
use Exception;
|
||||
use InvalidArgumentException;
|
||||
use JsonRPC\Exception\AccessDeniedException;
|
||||
use JsonRPC\Exception\AuthenticationFailureException;
|
||||
use JsonRPC\Exception\InvalidJsonFormatException;
|
||||
use JsonRPC\Exception\InvalidJsonRpcFormatException;
|
||||
use JsonRPC\Exception\ResponseEncodingFailureException;
|
||||
use JsonRPC\Exception\ResponseException;
|
||||
use JsonRPC\Validator\JsonEncodingValidator;
|
||||
|
||||
/**
|
||||
* Class ResponseBuilder
|
||||
*
|
||||
* @package JsonRPC
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class ResponseBuilder
|
||||
{
|
||||
/**
|
||||
* Payload ID
|
||||
*
|
||||
* @access private
|
||||
* @var mixed
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* Payload ID
|
||||
*
|
||||
* @access private
|
||||
* @var mixed
|
||||
*/
|
||||
private $result;
|
||||
|
||||
/**
|
||||
* Payload error code
|
||||
*
|
||||
* @access private
|
||||
* @var integer
|
||||
*/
|
||||
private $errorCode;
|
||||
|
||||
/**
|
||||
* Payload error message
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
private $errorMessage;
|
||||
|
||||
/**
|
||||
* Payload error data
|
||||
*
|
||||
* @access private
|
||||
* @var mixed
|
||||
*/
|
||||
private $errorData;
|
||||
|
||||
/**
|
||||
* HTTP Headers
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
private $headers = array(
|
||||
'Content-Type' => 'application/json',
|
||||
);
|
||||
|
||||
/**
|
||||
* HTTP status
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
private $status;
|
||||
|
||||
/**
|
||||
* Exception
|
||||
*
|
||||
* @access private
|
||||
* @var ResponseException
|
||||
*/
|
||||
private $exception;
|
||||
|
||||
/**
|
||||
* Get new object instance
|
||||
*
|
||||
* @static
|
||||
* @access public
|
||||
* @return ResponseBuilder
|
||||
*/
|
||||
public static function create()
|
||||
{
|
||||
return new static();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set id
|
||||
*
|
||||
* @access public
|
||||
* @param mixed $id
|
||||
* @return $this
|
||||
*/
|
||||
public function withId($id)
|
||||
{
|
||||
$this->id = $id;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set result
|
||||
*
|
||||
* @access public
|
||||
* @param mixed $result
|
||||
* @return $this
|
||||
*/
|
||||
public function withResult($result)
|
||||
{
|
||||
$this->result = $result;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set error
|
||||
*
|
||||
* @access public
|
||||
* @param integer $code
|
||||
* @param string $message
|
||||
* @param string $data
|
||||
* @return $this
|
||||
*/
|
||||
public function withError($code, $message, $data = '')
|
||||
{
|
||||
$this->errorCode = $code;
|
||||
$this->errorMessage = $message;
|
||||
$this->errorData = $data;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set exception
|
||||
*
|
||||
* @access public
|
||||
* @param Exception $exception
|
||||
* @return $this
|
||||
*/
|
||||
public function withException(Exception $exception)
|
||||
{
|
||||
$this->exception = $exception;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add HTTP header
|
||||
*
|
||||
* @access public
|
||||
* @param string $name
|
||||
* @param string $value
|
||||
* @return $this
|
||||
*/
|
||||
public function withHeader($name, $value)
|
||||
{
|
||||
$this->headers[$name] = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add HTTP Status
|
||||
*
|
||||
* @access public
|
||||
* @param string $status
|
||||
* @return $this
|
||||
*/
|
||||
public function withStatus($status)
|
||||
{
|
||||
$this->status = $status;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get status
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getStatus()
|
||||
{
|
||||
return $this->status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get headers
|
||||
*
|
||||
* @access public
|
||||
* @return string[]
|
||||
*/
|
||||
public function getHeaders()
|
||||
{
|
||||
return $this->headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build response
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function build()
|
||||
{
|
||||
$encodedResponse = json_encode($this->buildResponse());
|
||||
JsonEncodingValidator::validate();
|
||||
|
||||
return $encodedResponse;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send HTTP headers
|
||||
*
|
||||
* @access public
|
||||
* @return $this
|
||||
*/
|
||||
public function sendHeaders()
|
||||
{
|
||||
if (! empty($this->status)) {
|
||||
header($this->status);
|
||||
}
|
||||
|
||||
foreach ($this->headers as $name => $value) {
|
||||
header($name.': '.$value);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build response payload
|
||||
*
|
||||
* @access private
|
||||
* @return array
|
||||
*/
|
||||
private function buildResponse()
|
||||
{
|
||||
$response = array('jsonrpc' => '2.0');
|
||||
$this->handleExceptions();
|
||||
|
||||
if (! empty($this->errorMessage)) {
|
||||
$response['error'] = $this->buildErrorResponse();
|
||||
} else {
|
||||
$response['result'] = $this->result;
|
||||
}
|
||||
|
||||
$response['id'] = $this->id;
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build response error payload
|
||||
*
|
||||
* @access private
|
||||
* @return array
|
||||
*/
|
||||
private function buildErrorResponse()
|
||||
{
|
||||
$response = array(
|
||||
'code' => $this->errorCode,
|
||||
'message' => $this->errorMessage,
|
||||
);
|
||||
|
||||
if (! empty($this->errorData)) {
|
||||
$response['data'] = $this->errorData;
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform exceptions to JSON-RPC errors
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
private function handleExceptions()
|
||||
{
|
||||
if ($this->exception instanceof InvalidJsonFormatException) {
|
||||
$this->errorCode = -32700;
|
||||
$this->errorMessage = 'Parse error';
|
||||
$this->id = null;
|
||||
} elseif ($this->exception instanceof InvalidJsonRpcFormatException) {
|
||||
$this->errorCode = -32600;
|
||||
$this->errorMessage = 'Invalid Request';
|
||||
$this->id = null;
|
||||
} elseif ($this->exception instanceof BadFunctionCallException) {
|
||||
$this->errorCode = -32601;
|
||||
$this->errorMessage = 'Method not found';
|
||||
} elseif ($this->exception instanceof InvalidArgumentException) {
|
||||
$this->errorCode = -32602;
|
||||
$this->errorMessage = 'Invalid params';
|
||||
} elseif ($this->exception instanceof ResponseEncodingFailureException) {
|
||||
$this->errorCode = -32603;
|
||||
$this->errorMessage = 'Internal error';
|
||||
$this->errorData = $this->exception->getMessage();
|
||||
} elseif ($this->exception instanceof AuthenticationFailureException) {
|
||||
$this->errorCode = 401;
|
||||
$this->errorMessage = 'Unauthorized';
|
||||
$this->status = 'HTTP/1.0 401 Unauthorized';
|
||||
$this->withHeader('WWW-Authenticate', 'Basic realm="JsonRPC"');
|
||||
} elseif ($this->exception instanceof AccessDeniedException) {
|
||||
$this->errorCode = 403;
|
||||
$this->errorMessage = 'Forbidden';
|
||||
$this->status = 'HTTP/1.0 403 Forbidden';
|
||||
} elseif ($this->exception instanceof ResponseException) {
|
||||
$this->errorCode = $this->exception->getCode();
|
||||
$this->errorMessage = $this->exception->getMessage();
|
||||
$this->errorData = $this->exception->getData();
|
||||
} elseif ($this->exception instanceof Exception) {
|
||||
$this->errorCode = $this->exception->getCode();
|
||||
$this->errorMessage = $this->exception->getMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
154
vendor/fguillot/json-rpc/src/JsonRPC/Response/ResponseParser.php
vendored
Normal file
154
vendor/fguillot/json-rpc/src/JsonRPC/Response/ResponseParser.php
vendored
Normal file
@@ -0,0 +1,154 @@
|
||||
<?php
|
||||
|
||||
namespace JsonRPC\Response;
|
||||
|
||||
use BadFunctionCallException;
|
||||
use InvalidArgumentException;
|
||||
use Exception;
|
||||
use JsonRPC\Exception\InvalidJsonFormatException;
|
||||
use JsonRPC\Exception\InvalidJsonRpcFormatException;
|
||||
use JsonRPC\Exception\ResponseException;
|
||||
use JsonRPC\Validator\JsonFormatValidator;
|
||||
|
||||
/**
|
||||
* Class ResponseParser
|
||||
*
|
||||
* @package JsonRPC\Request
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class ResponseParser
|
||||
{
|
||||
/**
|
||||
* Payload
|
||||
*
|
||||
* @access private
|
||||
* @var mixed
|
||||
*/
|
||||
private $payload;
|
||||
|
||||
/**
|
||||
* Do not immediately throw an exception on error. Return it instead.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $returnException = false;
|
||||
|
||||
/**
|
||||
* Get new object instance
|
||||
*
|
||||
* @static
|
||||
* @access public
|
||||
* @return ResponseParser
|
||||
*/
|
||||
public static function create()
|
||||
{
|
||||
return new static();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Return Exception Or Throw It
|
||||
*
|
||||
* @param $returnException
|
||||
* @return ResponseParser
|
||||
*/
|
||||
public function withReturnException($returnException)
|
||||
{
|
||||
$this->returnException = $returnException;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set payload
|
||||
*
|
||||
* @access public
|
||||
* @param mixed $payload
|
||||
* @return $this
|
||||
*/
|
||||
public function withPayload($payload)
|
||||
{
|
||||
$this->payload = $payload;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse response
|
||||
*
|
||||
* @return array|Exception|null
|
||||
* @throws InvalidJsonFormatException
|
||||
* @throws BadFunctionCallException
|
||||
* @throws InvalidJsonRpcFormatException
|
||||
* @throws InvalidArgumentException
|
||||
* @throws Exception
|
||||
* @throws ResponseException
|
||||
*/
|
||||
public function parse()
|
||||
{
|
||||
JsonFormatValidator::validate($this->payload);
|
||||
|
||||
if ($this->isBatchResponse()) {
|
||||
$results = array();
|
||||
|
||||
foreach ($this->payload as $response) {
|
||||
$results[] = self::create()
|
||||
->withReturnException($this->returnException)
|
||||
->withPayload($response)
|
||||
->parse();
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
if (isset($this->payload['error']['code'])) {
|
||||
try {
|
||||
$this->handleExceptions();
|
||||
} catch (Exception $e) {
|
||||
if ($this->returnException) {
|
||||
return $e;
|
||||
}
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
return isset($this->payload['result']) ? $this->payload['result'] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle exceptions
|
||||
*
|
||||
* @access private
|
||||
* @throws InvalidJsonFormatException
|
||||
* @throws InvalidJsonRpcFormatException
|
||||
* @throws ResponseException
|
||||
*/
|
||||
private function handleExceptions()
|
||||
{
|
||||
switch ($this->payload['error']['code']) {
|
||||
case -32700:
|
||||
throw new InvalidJsonFormatException('Parse error: '.$this->payload['error']['message']);
|
||||
case -32600:
|
||||
throw new InvalidJsonRpcFormatException('Invalid Request: '.$this->payload['error']['message']);
|
||||
case -32601:
|
||||
throw new BadFunctionCallException('Procedure not found: '.$this->payload['error']['message']);
|
||||
case -32602:
|
||||
throw new InvalidArgumentException('Invalid arguments: '.$this->payload['error']['message']);
|
||||
default:
|
||||
throw new ResponseException(
|
||||
$this->payload['error']['message'],
|
||||
$this->payload['error']['code'],
|
||||
null,
|
||||
isset($this->payload['error']['data']) ? $this->payload['error']['data'] : null
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if we have a batch response
|
||||
*
|
||||
* @access private
|
||||
* @return boolean
|
||||
*/
|
||||
private function isBatchResponse()
|
||||
{
|
||||
return array_keys($this->payload) === range(0, count($this->payload) - 1);
|
||||
}
|
||||
}
|
||||
386
vendor/fguillot/json-rpc/src/JsonRPC/Server.php
vendored
Normal file
386
vendor/fguillot/json-rpc/src/JsonRPC/Server.php
vendored
Normal file
@@ -0,0 +1,386 @@
|
||||
<?php
|
||||
|
||||
namespace JsonRPC;
|
||||
|
||||
use Closure;
|
||||
use Exception;
|
||||
use JsonRPC\Request\BatchRequestParser;
|
||||
use JsonRPC\Request\RequestParser;
|
||||
use JsonRPC\Response\ResponseBuilder;
|
||||
use JsonRPC\Validator\HostValidator;
|
||||
use JsonRPC\Validator\JsonFormatValidator;
|
||||
use JsonRPC\Validator\UserValidator;
|
||||
|
||||
/**
|
||||
* JsonRPC server class
|
||||
*
|
||||
* @package JsonRPC
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class Server
|
||||
{
|
||||
/**
|
||||
* Allowed hosts
|
||||
*
|
||||
* @access protected
|
||||
* @var array
|
||||
*/
|
||||
protected $hosts = array();
|
||||
|
||||
/**
|
||||
* Data received from the client
|
||||
*
|
||||
* @access protected
|
||||
* @var array
|
||||
*/
|
||||
protected $payload = array();
|
||||
|
||||
/**
|
||||
* List of exceptions that should not be relayed to the client
|
||||
*
|
||||
* @access protected
|
||||
* @var array()
|
||||
*/
|
||||
protected $localExceptions = array();
|
||||
|
||||
/**
|
||||
* Username
|
||||
*
|
||||
* @access protected
|
||||
* @var string
|
||||
*/
|
||||
protected $username = '';
|
||||
|
||||
/**
|
||||
* Password
|
||||
*
|
||||
* @access protected
|
||||
* @var string
|
||||
*/
|
||||
protected $password = '';
|
||||
|
||||
/**
|
||||
* Allowed users
|
||||
*
|
||||
* @access protected
|
||||
* @var array
|
||||
*/
|
||||
protected $users = array();
|
||||
|
||||
/**
|
||||
* $_SERVER
|
||||
*
|
||||
* @access protected
|
||||
* @var array
|
||||
*/
|
||||
protected $serverVariable;
|
||||
|
||||
/**
|
||||
* ProcedureHandler object
|
||||
*
|
||||
* @access protected
|
||||
* @var ProcedureHandler
|
||||
*/
|
||||
protected $procedureHandler;
|
||||
|
||||
/**
|
||||
* MiddlewareHandler object
|
||||
*
|
||||
* @access protected
|
||||
* @var MiddlewareHandler
|
||||
*/
|
||||
protected $middlewareHandler;
|
||||
|
||||
/**
|
||||
* Response builder
|
||||
*
|
||||
* @access protected
|
||||
* @var ResponseBuilder
|
||||
*/
|
||||
protected $responseBuilder;
|
||||
|
||||
/**
|
||||
* Response builder
|
||||
*
|
||||
* @access protected
|
||||
* @var RequestParser
|
||||
*/
|
||||
protected $requestParser;
|
||||
|
||||
/**
|
||||
*
|
||||
* Batch request parser
|
||||
*
|
||||
* @access protected
|
||||
* @var BatchRequestParser
|
||||
*/
|
||||
protected $batchRequestParser;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @access public
|
||||
* @param string $request
|
||||
* @param array $server
|
||||
* @param ResponseBuilder $responseBuilder
|
||||
* @param RequestParser $requestParser
|
||||
* @param BatchRequestParser $batchRequestParser
|
||||
* @param ProcedureHandler $procedureHandler
|
||||
* @param MiddlewareHandler $middlewareHandler
|
||||
*/
|
||||
public function __construct(
|
||||
$request = '',
|
||||
array $server = array(),
|
||||
ResponseBuilder $responseBuilder = null,
|
||||
RequestParser $requestParser = null,
|
||||
BatchRequestParser $batchRequestParser = null,
|
||||
ProcedureHandler $procedureHandler = null,
|
||||
MiddlewareHandler $middlewareHandler = null
|
||||
) {
|
||||
if ($request !== '') {
|
||||
$this->payload = json_decode($request, true);
|
||||
} else {
|
||||
$this->payload = json_decode(file_get_contents('php://input'), true);
|
||||
}
|
||||
|
||||
$this->serverVariable = $server ?: $_SERVER;
|
||||
$this->responseBuilder = $responseBuilder ?: ResponseBuilder::create();
|
||||
$this->requestParser = $requestParser ?: RequestParser::create();
|
||||
$this->batchRequestParser = $batchRequestParser ?: BatchRequestParser::create();
|
||||
$this->procedureHandler = $procedureHandler ?: new ProcedureHandler();
|
||||
$this->middlewareHandler = $middlewareHandler ?: new MiddlewareHandler();
|
||||
}
|
||||
|
||||
/**
|
||||
* Define alternative authentication header
|
||||
*
|
||||
* @access public
|
||||
* @param string $header Header name
|
||||
* @return $this
|
||||
*/
|
||||
public function setAuthenticationHeader($header)
|
||||
{
|
||||
if (! empty($header)) {
|
||||
$header = 'HTTP_'.str_replace('-', '_', strtoupper($header));
|
||||
$value = $this->getServerVariable($header);
|
||||
|
||||
if (! empty($value)) {
|
||||
list($this->username, $this->password) = explode(':', base64_decode($value));
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ProcedureHandler
|
||||
*
|
||||
* @access public
|
||||
* @return ProcedureHandler
|
||||
*/
|
||||
public function getProcedureHandler()
|
||||
{
|
||||
return $this->procedureHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get MiddlewareHandler
|
||||
*
|
||||
* @access public
|
||||
* @return MiddlewareHandler
|
||||
*/
|
||||
public function getMiddlewareHandler()
|
||||
{
|
||||
return $this->middlewareHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get username
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getUsername()
|
||||
{
|
||||
return $this->username ?: $this->getServerVariable('PHP_AUTH_USER');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get password
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getPassword()
|
||||
{
|
||||
return $this->password ?: $this->getServerVariable('PHP_AUTH_PW');
|
||||
}
|
||||
|
||||
/**
|
||||
* IP based client restrictions
|
||||
*
|
||||
* @access public
|
||||
* @param array $hosts List of hosts
|
||||
* @return $this
|
||||
*/
|
||||
public function allowHosts(array $hosts)
|
||||
{
|
||||
$this->hosts = $hosts;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* HTTP Basic authentication
|
||||
*
|
||||
* @access public
|
||||
* @param array $users Dictionary of username/password
|
||||
* @return $this
|
||||
*/
|
||||
public function authentication(array $users)
|
||||
{
|
||||
$this->users = $users;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a new procedure
|
||||
*
|
||||
* @access public
|
||||
* @deprecated Use $server->getProcedureHandler()->withCallback($procedure, $callback)
|
||||
* @param string $procedure Procedure name
|
||||
* @param closure $callback Callback
|
||||
* @return $this
|
||||
*/
|
||||
public function register($procedure, Closure $callback)
|
||||
{
|
||||
$this->procedureHandler->withCallback($procedure, $callback);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bind a procedure to a class
|
||||
*
|
||||
* @access public
|
||||
* @deprecated Use $server->getProcedureHandler()->withClassAndMethod($procedure, $class, $method);
|
||||
* @param string $procedure Procedure name
|
||||
* @param mixed $class Class name or instance
|
||||
* @param string $method Procedure name
|
||||
* @return $this
|
||||
*/
|
||||
public function bind($procedure, $class, $method = '')
|
||||
{
|
||||
$this->procedureHandler->withClassAndMethod($procedure, $class, $method);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bind a class instance
|
||||
*
|
||||
* @access public
|
||||
* @deprecated Use $server->getProcedureHandler()->withObject($instance);
|
||||
* @param mixed $instance Instance name
|
||||
* @return $this
|
||||
*/
|
||||
public function attach($instance)
|
||||
{
|
||||
$this->procedureHandler->withObject($instance);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Exception classes that should not be relayed to the client
|
||||
*
|
||||
* @access public
|
||||
* @param Exception|string $exception
|
||||
* @return $this
|
||||
*/
|
||||
public function withLocalException($exception)
|
||||
{
|
||||
$this->localExceptions[] = $exception;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse incoming requests
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
try {
|
||||
JsonFormatValidator::validate($this->payload);
|
||||
HostValidator::validate($this->hosts, $this->getServerVariable('REMOTE_ADDR'));
|
||||
UserValidator::validate($this->users, $this->getUsername(), $this->getPassword());
|
||||
|
||||
$this->middlewareHandler
|
||||
->withUsername($this->getUsername())
|
||||
->withPassword($this->getPassword())
|
||||
;
|
||||
|
||||
$response = $this->parseRequest();
|
||||
|
||||
} catch (Exception $e) {
|
||||
$response = $this->handleExceptions($e);
|
||||
}
|
||||
|
||||
$this->responseBuilder->sendHeaders();
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle exceptions
|
||||
*
|
||||
* @access protected
|
||||
* @param Exception $e
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function handleExceptions(Exception $e)
|
||||
{
|
||||
foreach ($this->localExceptions as $exception) {
|
||||
if ($e instanceof $exception) {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->responseBuilder->withException($e)->build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse incoming request
|
||||
*
|
||||
* @access protected
|
||||
* @return string
|
||||
*/
|
||||
protected function parseRequest()
|
||||
{
|
||||
if (BatchRequestParser::isBatchRequest($this->payload)) {
|
||||
return $this->batchRequestParser
|
||||
->withPayload($this->payload)
|
||||
->withProcedureHandler($this->procedureHandler)
|
||||
->withMiddlewareHandler($this->middlewareHandler)
|
||||
->withLocalException($this->localExceptions)
|
||||
->parse();
|
||||
}
|
||||
|
||||
return $this->requestParser
|
||||
->withPayload($this->payload)
|
||||
->withProcedureHandler($this->procedureHandler)
|
||||
->withMiddlewareHandler($this->middlewareHandler)
|
||||
->withLocalException($this->localExceptions)
|
||||
->parse();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check existence and get value of server variable
|
||||
*
|
||||
* @access protected
|
||||
* @param string $variable
|
||||
* @return string|null
|
||||
*/
|
||||
protected function getServerVariable($variable)
|
||||
{
|
||||
return isset($this->serverVariable[$variable]) ? $this->serverVariable[$variable] : null;
|
||||
}
|
||||
}
|
||||
30
vendor/fguillot/json-rpc/src/JsonRPC/Validator/HostValidator.php
vendored
Normal file
30
vendor/fguillot/json-rpc/src/JsonRPC/Validator/HostValidator.php
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace JsonRPC\Validator;
|
||||
|
||||
use JsonRPC\Exception\AccessDeniedException;
|
||||
|
||||
/**
|
||||
* Class HostValidator
|
||||
*
|
||||
* @package JsonRPC\Validator
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class HostValidator
|
||||
{
|
||||
/**
|
||||
* Validate
|
||||
*
|
||||
* @static
|
||||
* @access public
|
||||
* @param array $hosts
|
||||
* @param string $remoteAddress
|
||||
* @throws AccessDeniedException
|
||||
*/
|
||||
public static function validate(array $hosts, $remoteAddress)
|
||||
{
|
||||
if (! empty($hosts) && ! in_array($remoteAddress, $hosts)) {
|
||||
throw new AccessDeniedException('Access Forbidden');
|
||||
}
|
||||
}
|
||||
}
|
||||
44
vendor/fguillot/json-rpc/src/JsonRPC/Validator/JsonEncodingValidator.php
vendored
Normal file
44
vendor/fguillot/json-rpc/src/JsonRPC/Validator/JsonEncodingValidator.php
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace JsonRPC\Validator;
|
||||
|
||||
use JsonRPC\Exception\ResponseEncodingFailureException;
|
||||
|
||||
/**
|
||||
* Class JsonEncodingValidator
|
||||
*
|
||||
* @package JsonRPC\Validator
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class JsonEncodingValidator
|
||||
{
|
||||
public static function validate()
|
||||
{
|
||||
$jsonError = json_last_error();
|
||||
|
||||
if ($jsonError !== JSON_ERROR_NONE) {
|
||||
switch ($jsonError) {
|
||||
case JSON_ERROR_DEPTH:
|
||||
$errorMessage = 'Maximum stack depth exceeded';
|
||||
break;
|
||||
case JSON_ERROR_STATE_MISMATCH:
|
||||
$errorMessage = 'Underflow or the modes mismatch';
|
||||
break;
|
||||
case JSON_ERROR_CTRL_CHAR:
|
||||
$errorMessage = 'Unexpected control character found';
|
||||
break;
|
||||
case JSON_ERROR_SYNTAX:
|
||||
$errorMessage = 'Syntax error, malformed JSON';
|
||||
break;
|
||||
case JSON_ERROR_UTF8:
|
||||
$errorMessage = 'Malformed UTF-8 characters, possibly incorrectly encoded';
|
||||
break;
|
||||
default:
|
||||
$errorMessage = 'Unknown error';
|
||||
break;
|
||||
}
|
||||
|
||||
throw new ResponseEncodingFailureException($errorMessage, $jsonError);
|
||||
}
|
||||
}
|
||||
}
|
||||
30
vendor/fguillot/json-rpc/src/JsonRPC/Validator/JsonFormatValidator.php
vendored
Normal file
30
vendor/fguillot/json-rpc/src/JsonRPC/Validator/JsonFormatValidator.php
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace JsonRPC\Validator;
|
||||
|
||||
use JsonRPC\Exception\InvalidJsonFormatException;
|
||||
|
||||
/**
|
||||
* Class JsonFormatValidator
|
||||
*
|
||||
* @package JsonRPC\Validator
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class JsonFormatValidator
|
||||
{
|
||||
/**
|
||||
* Validate
|
||||
*
|
||||
* @static
|
||||
* @access public
|
||||
* @param mixed $payload
|
||||
* @throws InvalidJsonFormatException
|
||||
*/
|
||||
public static function validate($payload)
|
||||
{
|
||||
if (! is_array($payload)) {
|
||||
throw new InvalidJsonFormatException('Malformed payload');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
35
vendor/fguillot/json-rpc/src/JsonRPC/Validator/RpcFormatValidator.php
vendored
Normal file
35
vendor/fguillot/json-rpc/src/JsonRPC/Validator/RpcFormatValidator.php
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace JsonRPC\Validator;
|
||||
|
||||
use JsonRPC\Exception\InvalidJsonRpcFormatException;
|
||||
|
||||
/**
|
||||
* Class RpcFormatValidator
|
||||
*
|
||||
* @package JsonRPC\Validator
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class RpcFormatValidator
|
||||
{
|
||||
/**
|
||||
* Validate
|
||||
*
|
||||
* @static
|
||||
* @access public
|
||||
* @param array $payload
|
||||
* @throws InvalidJsonRpcFormatException
|
||||
*/
|
||||
public static function validate(array $payload)
|
||||
{
|
||||
if (! isset($payload['jsonrpc']) ||
|
||||
! isset($payload['method']) ||
|
||||
! is_string($payload['method']) ||
|
||||
$payload['jsonrpc'] !== '2.0' ||
|
||||
(isset($payload['params']) && ! is_array($payload['params']))) {
|
||||
|
||||
throw new InvalidJsonRpcFormatException('Invalid JSON RPC payload');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
21
vendor/fguillot/json-rpc/src/JsonRPC/Validator/UserValidator.php
vendored
Normal file
21
vendor/fguillot/json-rpc/src/JsonRPC/Validator/UserValidator.php
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace JsonRPC\Validator;
|
||||
|
||||
use JsonRPC\Exception\AuthenticationFailureException;
|
||||
|
||||
/**
|
||||
* Class UserValidator
|
||||
*
|
||||
* @package JsonRPC\Validator
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class UserValidator
|
||||
{
|
||||
public static function validate(array $users, $username, $password)
|
||||
{
|
||||
if (! empty($users) && (! isset($users[$username]) || $users[$username] !== $password)) {
|
||||
throw new AuthenticationFailureException('Access not allowed');
|
||||
}
|
||||
}
|
||||
}
|
||||
21
vendor/fguillot/picodb/LICENSE
vendored
Normal file
21
vendor/fguillot/picodb/LICENSE
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Frederic Guillot
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
86
vendor/fguillot/picodb/lib/PicoDb/Builder/BaseBuilder.php
vendored
Normal file
86
vendor/fguillot/picodb/lib/PicoDb/Builder/BaseBuilder.php
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
namespace PicoDb\Builder;
|
||||
|
||||
use PicoDb\Database;
|
||||
|
||||
/**
|
||||
* Class InsertBuilder
|
||||
*
|
||||
* @package PicoDb\Builder
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
abstract class BaseBuilder
|
||||
{
|
||||
/**
|
||||
* @var Database
|
||||
*/
|
||||
protected $db;
|
||||
|
||||
/**
|
||||
* @var ConditionBuilder
|
||||
*/
|
||||
protected $conditionBuilder;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $table = '';
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
protected $columns = array();
|
||||
|
||||
/**
|
||||
* InsertBuilder constructor
|
||||
*
|
||||
* @param Database $db
|
||||
* @param ConditionBuilder $condition
|
||||
*/
|
||||
public function __construct(Database $db, ConditionBuilder $condition)
|
||||
{
|
||||
$this->db = $db;
|
||||
$this->conditionBuilder = $condition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get object instance
|
||||
*
|
||||
* @static
|
||||
* @access public
|
||||
* @param Database $db
|
||||
* @param ConditionBuilder $condition
|
||||
* @return static
|
||||
*/
|
||||
public static function getInstance(Database $db, ConditionBuilder $condition)
|
||||
{
|
||||
return new static($db, $condition);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set table name
|
||||
*
|
||||
* @access public
|
||||
* @param string $table
|
||||
* @return $this
|
||||
*/
|
||||
public function withTable($table)
|
||||
{
|
||||
$this->table = $table;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set columns name
|
||||
*
|
||||
* @access public
|
||||
* @param string[] $columns
|
||||
* @return $this
|
||||
*/
|
||||
public function withColumns(array $columns)
|
||||
{
|
||||
$this->columns = $columns;
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
377
vendor/fguillot/picodb/lib/PicoDb/Builder/ConditionBuilder.php
vendored
Normal file
377
vendor/fguillot/picodb/lib/PicoDb/Builder/ConditionBuilder.php
vendored
Normal file
@@ -0,0 +1,377 @@
|
||||
<?php
|
||||
|
||||
namespace PicoDb\Builder;
|
||||
|
||||
use PicoDb\Database;
|
||||
use PicoDb\Table;
|
||||
|
||||
/**
|
||||
* Handle SQL conditions
|
||||
*
|
||||
* @package PicoDb\Builder
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class ConditionBuilder
|
||||
{
|
||||
/**
|
||||
* Database instance
|
||||
*
|
||||
* @access private
|
||||
* @var Database
|
||||
*/
|
||||
private $db;
|
||||
|
||||
/**
|
||||
* Condition values
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
private $values = array();
|
||||
|
||||
/**
|
||||
* SQL AND conditions
|
||||
*
|
||||
* @access private
|
||||
* @var string[]
|
||||
*/
|
||||
private $conditions = array();
|
||||
|
||||
/**
|
||||
* SQL OR conditions
|
||||
*
|
||||
* @access private
|
||||
* @var OrConditionBuilder[]
|
||||
*/
|
||||
private $orConditions = array();
|
||||
|
||||
/**
|
||||
* SQL condition offset
|
||||
*
|
||||
* @access private
|
||||
* @var int
|
||||
*/
|
||||
private $orConditionOffset = 0;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @access public
|
||||
* @param Database $db
|
||||
*/
|
||||
public function __construct(Database $db)
|
||||
{
|
||||
$this->db = $db;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the SQL condition
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function build()
|
||||
{
|
||||
return empty($this->conditions) ? '' : ' WHERE '.implode(' AND ', $this->conditions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get condition values
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getValues()
|
||||
{
|
||||
return $this->values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if there is some conditions
|
||||
*
|
||||
* @access public
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasCondition()
|
||||
{
|
||||
return ! empty($this->conditions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add custom condition
|
||||
*
|
||||
* @access public
|
||||
* @param string $sql
|
||||
*/
|
||||
public function addCondition($sql)
|
||||
{
|
||||
if ($this->orConditionOffset > 0) {
|
||||
$this->orConditions[$this->orConditionOffset]->withCondition($sql);
|
||||
}
|
||||
else {
|
||||
$this->conditions[] = $sql;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Start OR condition
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function beginOr()
|
||||
{
|
||||
$this->orConditionOffset++;
|
||||
$this->orConditions[$this->orConditionOffset] = new OrConditionBuilder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Close OR condition
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function closeOr()
|
||||
{
|
||||
$condition = $this->orConditions[$this->orConditionOffset]->build();
|
||||
$this->orConditionOffset--;
|
||||
|
||||
if ($this->orConditionOffset > 0) {
|
||||
$this->orConditions[$this->orConditionOffset]->withCondition($condition);
|
||||
} else {
|
||||
$this->conditions[] = $condition;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Equal condition
|
||||
*
|
||||
* @access public
|
||||
* @param string $column
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function eq($column, $value)
|
||||
{
|
||||
$this->addCondition($this->db->escapeIdentifier($column).' = ?');
|
||||
$this->values[] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Not equal condition
|
||||
*
|
||||
* @access public
|
||||
* @param string $column
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function neq($column, $value)
|
||||
{
|
||||
$this->addCondition($this->db->escapeIdentifier($column).' != ?');
|
||||
$this->values[] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* IN condition
|
||||
*
|
||||
* @access public
|
||||
* @param string $column
|
||||
* @param array $values
|
||||
*/
|
||||
public function in($column, array $values)
|
||||
{
|
||||
if (! empty($values)) {
|
||||
$this->addCondition($this->db->escapeIdentifier($column).' IN ('.implode(', ', array_fill(0, count($values), '?')).')');
|
||||
$this->values = array_merge($this->values, $values);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* IN condition with a subquery
|
||||
*
|
||||
* @access public
|
||||
* @param string $column
|
||||
* @param Table $subquery
|
||||
*/
|
||||
public function inSubquery($column, Table $subquery)
|
||||
{
|
||||
$this->addCondition($this->db->escapeIdentifier($column).' IN ('.$subquery->buildSelectQuery().')');
|
||||
$this->values = array_merge($this->values, $subquery->getConditionBuilder()->getValues());
|
||||
}
|
||||
|
||||
/**
|
||||
* NOT IN condition
|
||||
*
|
||||
* @access public
|
||||
* @param string $column
|
||||
* @param array $values
|
||||
*/
|
||||
public function notIn($column, array $values)
|
||||
{
|
||||
if (! empty($values)) {
|
||||
$this->addCondition($this->db->escapeIdentifier($column).' NOT IN ('.implode(', ', array_fill(0, count($values), '?')).')');
|
||||
$this->values = array_merge($this->values, $values);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* NOT IN condition with a subquery
|
||||
*
|
||||
* @access public
|
||||
* @param string $column
|
||||
* @param Table $subquery
|
||||
*/
|
||||
public function notInSubquery($column, Table $subquery)
|
||||
{
|
||||
$this->addCondition($this->db->escapeIdentifier($column).' NOT IN ('.$subquery->buildSelectQuery().')');
|
||||
$this->values = array_merge($this->values, $subquery->getConditionBuilder()->getValues());
|
||||
}
|
||||
|
||||
/**
|
||||
* LIKE condition
|
||||
*
|
||||
* @access public
|
||||
* @param string $column
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function like($column, $value)
|
||||
{
|
||||
$this->addCondition($this->db->escapeIdentifier($column).' '.$this->db->getDriver()->getOperator('LIKE').' ?');
|
||||
$this->values[] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* ILIKE condition
|
||||
*
|
||||
* @access public
|
||||
* @param string $column
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function ilike($column, $value)
|
||||
{
|
||||
$this->addCondition($this->db->escapeIdentifier($column).' '.$this->db->getDriver()->getOperator('ILIKE').' ?');
|
||||
$this->values[] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Greater than condition
|
||||
*
|
||||
* @access public
|
||||
* @param string $column
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function gt($column, $value)
|
||||
{
|
||||
$this->addCondition($this->db->escapeIdentifier($column).' > ?');
|
||||
$this->values[] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Greater than condition with subquery
|
||||
*
|
||||
* @access public
|
||||
* @param string $column
|
||||
* @param Table $subquery
|
||||
*/
|
||||
public function gtSubquery($column, Table $subquery)
|
||||
{
|
||||
$this->addCondition($this->db->escapeIdentifier($column).' > ('.$subquery->buildSelectQuery().')');
|
||||
$this->values = array_merge($this->values, $subquery->getConditionBuilder()->getValues());
|
||||
}
|
||||
|
||||
/**
|
||||
* Lower than condition
|
||||
*
|
||||
* @access public
|
||||
* @param string $column
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function lt($column, $value)
|
||||
{
|
||||
$this->addCondition($this->db->escapeIdentifier($column).' < ?');
|
||||
$this->values[] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lower than condition with subquery
|
||||
*
|
||||
* @access public
|
||||
* @param string $column
|
||||
* @param Table $subquery
|
||||
*/
|
||||
public function ltSubquery($column, Table $subquery)
|
||||
{
|
||||
$this->addCondition($this->db->escapeIdentifier($column).' < ('.$subquery->buildSelectQuery().')');
|
||||
$this->values = array_merge($this->values, $subquery->getConditionBuilder()->getValues());
|
||||
}
|
||||
|
||||
/**
|
||||
* Greater than or equals condition
|
||||
*
|
||||
* @access public
|
||||
* @param string $column
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function gte($column, $value)
|
||||
{
|
||||
$this->addCondition($this->db->escapeIdentifier($column).' >= ?');
|
||||
$this->values[] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Greater than or equal condition with subquery
|
||||
*
|
||||
* @access public
|
||||
* @param string $column
|
||||
* @param Table $subquery
|
||||
*/
|
||||
public function gteSubquery($column, Table $subquery)
|
||||
{
|
||||
$this->addCondition($this->db->escapeIdentifier($column).' >= ('.$subquery->buildSelectQuery().')');
|
||||
$this->values = array_merge($this->values, $subquery->getConditionBuilder()->getValues());
|
||||
}
|
||||
|
||||
/**
|
||||
* Lower than or equals condition
|
||||
*
|
||||
* @access public
|
||||
* @param string $column
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function lte($column, $value)
|
||||
{
|
||||
$this->addCondition($this->db->escapeIdentifier($column).' <= ?');
|
||||
$this->values[] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lower than or equal condition with subquery
|
||||
*
|
||||
* @access public
|
||||
* @param string $column
|
||||
* @param Table $subquery
|
||||
*/
|
||||
public function lteSubquery($column, Table $subquery)
|
||||
{
|
||||
$this->addCondition($this->db->escapeIdentifier($column).' <= ('.$subquery->buildSelectQuery().')');
|
||||
$this->values = array_merge($this->values, $subquery->getConditionBuilder()->getValues());
|
||||
}
|
||||
|
||||
/**
|
||||
* IS NULL condition
|
||||
*
|
||||
* @access public
|
||||
* @param string $column
|
||||
*/
|
||||
public function isNull($column)
|
||||
{
|
||||
$this->addCondition($this->db->escapeIdentifier($column).' IS NULL');
|
||||
}
|
||||
|
||||
/**
|
||||
* IS NOT NULL condition
|
||||
*
|
||||
* @access public
|
||||
* @param string $column
|
||||
*/
|
||||
public function notNull($column)
|
||||
{
|
||||
$this->addCondition($this->db->escapeIdentifier($column).' IS NOT NULL');
|
||||
}
|
||||
}
|
||||
36
vendor/fguillot/picodb/lib/PicoDb/Builder/InsertBuilder.php
vendored
Normal file
36
vendor/fguillot/picodb/lib/PicoDb/Builder/InsertBuilder.php
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace PicoDb\Builder;
|
||||
|
||||
/**
|
||||
* Class InsertBuilder
|
||||
*
|
||||
* @package PicoDb\Builder
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class InsertBuilder extends BaseBuilder
|
||||
{
|
||||
/**
|
||||
* Build SQL
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function build()
|
||||
{
|
||||
$columns = array();
|
||||
$placeholders = array();
|
||||
|
||||
foreach ($this->columns as $column) {
|
||||
$columns[] = $this->db->escapeIdentifier($column);
|
||||
$placeholders[] = ':'.$column;
|
||||
}
|
||||
|
||||
return sprintf(
|
||||
'INSERT INTO %s (%s) VALUES (%s)',
|
||||
$this->db->escapeIdentifier($this->table),
|
||||
implode(', ', $columns),
|
||||
implode(', ', $placeholders)
|
||||
);
|
||||
}
|
||||
}
|
||||
43
vendor/fguillot/picodb/lib/PicoDb/Builder/OrConditionBuilder.php
vendored
Normal file
43
vendor/fguillot/picodb/lib/PicoDb/Builder/OrConditionBuilder.php
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace PicoDb\Builder;
|
||||
|
||||
/**
|
||||
* Class OrConditionBuilder
|
||||
*
|
||||
* @package PicoDb\Builder
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class OrConditionBuilder
|
||||
{
|
||||
/**
|
||||
* List of SQL conditions
|
||||
*
|
||||
* @access protected
|
||||
* @var string[]
|
||||
*/
|
||||
protected $conditions = array();
|
||||
|
||||
/**
|
||||
* Add new condition
|
||||
*
|
||||
* @access public
|
||||
* @param string $condition
|
||||
* @return $this
|
||||
*/
|
||||
public function withCondition($condition) {
|
||||
$this->conditions[] = $condition;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build SQL
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function build()
|
||||
{
|
||||
return '('.implode(' OR ', $this->conditions).')';
|
||||
}
|
||||
}
|
||||
56
vendor/fguillot/picodb/lib/PicoDb/Builder/UpdateBuilder.php
vendored
Normal file
56
vendor/fguillot/picodb/lib/PicoDb/Builder/UpdateBuilder.php
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace PicoDb\Builder;
|
||||
|
||||
/**
|
||||
* Class UpdateBuilder
|
||||
*
|
||||
* @package PicoDb\Builder
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class UpdateBuilder extends BaseBuilder
|
||||
{
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
protected $sumColumns = array();
|
||||
|
||||
/**
|
||||
* Set columns name
|
||||
*
|
||||
* @access public
|
||||
* @param string[] $columns
|
||||
* @return $this
|
||||
*/
|
||||
public function withSumColumns(array $columns)
|
||||
{
|
||||
$this->sumColumns = $columns;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build SQL
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function build()
|
||||
{
|
||||
$columns = array();
|
||||
|
||||
foreach ($this->columns as $column) {
|
||||
$columns[] = $this->db->escapeIdentifier($column).'=?';
|
||||
}
|
||||
|
||||
foreach ($this->sumColumns as $column) {
|
||||
$columns[] = $this->db->escapeIdentifier($column).'='.$this->db->escapeIdentifier($column).' + ?';
|
||||
}
|
||||
|
||||
return sprintf(
|
||||
'UPDATE %s SET %s %s',
|
||||
$this->db->escapeIdentifier($this->table),
|
||||
implode(', ', $columns),
|
||||
$this->conditionBuilder->build()
|
||||
);
|
||||
}
|
||||
}
|
||||
370
vendor/fguillot/picodb/lib/PicoDb/Database.php
vendored
Normal file
370
vendor/fguillot/picodb/lib/PicoDb/Database.php
vendored
Normal file
@@ -0,0 +1,370 @@
|
||||
<?php
|
||||
|
||||
namespace PicoDb;
|
||||
|
||||
use Closure;
|
||||
use PDOException;
|
||||
use LogicException;
|
||||
use PicoDb\Driver\Mssql;
|
||||
use PicoDb\Driver\Sqlite;
|
||||
use PicoDb\Driver\Mysql;
|
||||
use PicoDb\Driver\Postgres;
|
||||
|
||||
/**
|
||||
* Database
|
||||
*
|
||||
* @package PicoDb
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class Database
|
||||
{
|
||||
/**
|
||||
* Database instances
|
||||
*
|
||||
* @static
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
private static $instances = array();
|
||||
|
||||
/**
|
||||
* Statement object
|
||||
*
|
||||
* @access protected
|
||||
* @var StatementHandler
|
||||
*/
|
||||
protected $statementHandler;
|
||||
|
||||
/**
|
||||
* Queries logs
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
private $logs = array();
|
||||
|
||||
/**
|
||||
* Driver instance
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
private $driver;
|
||||
|
||||
/**
|
||||
* Initialize the driver
|
||||
*
|
||||
* @access public
|
||||
* @param array $settings
|
||||
*/
|
||||
public function __construct(array $settings = array())
|
||||
{
|
||||
$this->driver = DriverFactory::getDriver($settings);
|
||||
$this->statementHandler = new StatementHandler($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
$this->closeConnection();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a new database instance
|
||||
*
|
||||
* @static
|
||||
* @access public
|
||||
* @param string $name Instance name
|
||||
* @param Closure $callback Callback
|
||||
*/
|
||||
public static function setInstance($name, Closure $callback)
|
||||
{
|
||||
self::$instances[$name] = $callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a database instance
|
||||
*
|
||||
* @static
|
||||
* @access public
|
||||
* @param string $name Instance name
|
||||
* @return Database
|
||||
*/
|
||||
public static function getInstance($name)
|
||||
{
|
||||
if (! isset(self::$instances[$name])) {
|
||||
throw new LogicException('No database instance created with that name');
|
||||
}
|
||||
|
||||
if (is_callable(self::$instances[$name])) {
|
||||
self::$instances[$name] = call_user_func(self::$instances[$name]);
|
||||
}
|
||||
|
||||
return self::$instances[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a log message
|
||||
*
|
||||
* @access public
|
||||
* @param mixed $message
|
||||
* @return Database
|
||||
*/
|
||||
public function setLogMessage($message)
|
||||
{
|
||||
$this->logs[] = is_array($message) ? var_export($message, true) : $message;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add many log messages
|
||||
*
|
||||
* @access public
|
||||
* @param array $messages
|
||||
* @return Database
|
||||
*/
|
||||
public function setLogMessages(array $messages)
|
||||
{
|
||||
foreach ($messages as $message) {
|
||||
$this->setLogMessage($message);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all queries logs
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getLogMessages()
|
||||
{
|
||||
return $this->logs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the PDO connection
|
||||
*
|
||||
* @access public
|
||||
* @return \PDO
|
||||
*/
|
||||
public function getConnection()
|
||||
{
|
||||
return $this->driver->getConnection();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Driver instance
|
||||
*
|
||||
* @access public
|
||||
* @return Mssql|Sqlite|Postgres|Mysql
|
||||
*/
|
||||
public function getDriver()
|
||||
{
|
||||
return $this->driver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the last inserted id
|
||||
*
|
||||
* @access public
|
||||
* @return integer
|
||||
*/
|
||||
public function getLastId()
|
||||
{
|
||||
return (int) $this->driver->getLastId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get statement object
|
||||
*
|
||||
* @access public
|
||||
* @return StatementHandler
|
||||
*/
|
||||
public function getStatementHandler()
|
||||
{
|
||||
return $this->statementHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Release the PDO connection
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function closeConnection()
|
||||
{
|
||||
$this->driver->closeConnection();
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape an identifier (column, table name...)
|
||||
*
|
||||
* @access public
|
||||
* @param string $value Value
|
||||
* @param string $table Table name
|
||||
* @return string
|
||||
*/
|
||||
public function escapeIdentifier($value, $table = '')
|
||||
{
|
||||
// Do not escape custom query
|
||||
if (strpos($value, '.') !== false || strpos($value, ' ') !== false) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
if (! empty($table)) {
|
||||
return $this->driver->escape($table).'.'.$this->driver->escape($value);
|
||||
}
|
||||
|
||||
return $this->driver->escape($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape an identifier list
|
||||
*
|
||||
* @access public
|
||||
* @param array $identifiers List of identifiers
|
||||
* @param string $table Table name
|
||||
* @return string[]
|
||||
*/
|
||||
public function escapeIdentifierList(array $identifiers, $table = '')
|
||||
{
|
||||
foreach ($identifiers as $key => $value) {
|
||||
$identifiers[$key] = $this->escapeIdentifier($value, $table);
|
||||
}
|
||||
|
||||
return $identifiers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a prepared statement
|
||||
*
|
||||
* Note: returns false on duplicate keys instead of SQLException
|
||||
*
|
||||
* @access public
|
||||
* @param string $sql SQL query
|
||||
* @param array $values Values
|
||||
* @return \PDOStatement|false
|
||||
*/
|
||||
public function execute($sql, array $values = array())
|
||||
{
|
||||
return $this->statementHandler
|
||||
->withSql($sql)
|
||||
->withPositionalParams($values)
|
||||
->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Run a transaction
|
||||
*
|
||||
* @access public
|
||||
* @param Closure $callback Callback
|
||||
* @return mixed
|
||||
*/
|
||||
public function transaction(Closure $callback)
|
||||
{
|
||||
try {
|
||||
|
||||
$this->startTransaction();
|
||||
$result = $callback($this);
|
||||
$this->closeTransaction();
|
||||
|
||||
return $result === null ? true : $result;
|
||||
} catch (PDOException $e) {
|
||||
return $this->statementHandler->handleSqlError($e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Begin a transaction
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function startTransaction()
|
||||
{
|
||||
if (! $this->getConnection()->inTransaction()) {
|
||||
$this->getConnection()->beginTransaction();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Commit a transaction
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function closeTransaction()
|
||||
{
|
||||
if ($this->getConnection()->inTransaction()) {
|
||||
$this->getConnection()->commit();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Rollback a transaction
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function cancelTransaction()
|
||||
{
|
||||
if ($this->getConnection()->inTransaction()) {
|
||||
$this->getConnection()->rollBack();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a table object
|
||||
*
|
||||
* @access public
|
||||
* @param string $table
|
||||
* @return Table
|
||||
*/
|
||||
public function table($table)
|
||||
{
|
||||
return new Table($this, $table);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a hashtable object
|
||||
*
|
||||
* @access public
|
||||
* @param string $table
|
||||
* @return Hashtable
|
||||
*/
|
||||
public function hashtable($table)
|
||||
{
|
||||
return new Hashtable($this, $table);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a LOB object
|
||||
*
|
||||
* @access public
|
||||
* @param string $table
|
||||
* @return LargeObject
|
||||
*/
|
||||
public function largeObject($table)
|
||||
{
|
||||
return new LargeObject($this, $table);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a schema object
|
||||
*
|
||||
* @access public
|
||||
* @param string $namespace
|
||||
* @return Schema
|
||||
*/
|
||||
public function schema($namespace = null)
|
||||
{
|
||||
$schema = new Schema($this);
|
||||
|
||||
if ($namespace !== null) {
|
||||
$schema->setNamespace($namespace);
|
||||
}
|
||||
|
||||
return $schema;
|
||||
}
|
||||
}
|
||||
234
vendor/fguillot/picodb/lib/PicoDb/Driver/Base.php
vendored
Normal file
234
vendor/fguillot/picodb/lib/PicoDb/Driver/Base.php
vendored
Normal file
@@ -0,0 +1,234 @@
|
||||
<?php
|
||||
|
||||
namespace PicoDb\Driver;
|
||||
|
||||
use PDO;
|
||||
use LogicException;
|
||||
use PDOException;
|
||||
|
||||
/**
|
||||
* Base Driver class
|
||||
*
|
||||
* @package PicoDb\Driver
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
abstract class Base
|
||||
{
|
||||
/**
|
||||
* List of required settings options
|
||||
*
|
||||
* @access protected
|
||||
* @var array
|
||||
*/
|
||||
protected $requiredAttributes = array();
|
||||
|
||||
/**
|
||||
* PDO connection
|
||||
*
|
||||
* @access protected
|
||||
* @var PDO
|
||||
*/
|
||||
protected $pdo = null;
|
||||
|
||||
/**
|
||||
* Create a new PDO connection
|
||||
*
|
||||
* @abstract
|
||||
* @access public
|
||||
* @param array $settings
|
||||
*/
|
||||
abstract public function createConnection(array $settings);
|
||||
|
||||
/**
|
||||
* Enable foreign keys
|
||||
*
|
||||
* @abstract
|
||||
* @access public
|
||||
*/
|
||||
abstract public function enableForeignKeys();
|
||||
|
||||
/**
|
||||
* Disable foreign keys
|
||||
*
|
||||
* @abstract
|
||||
* @access public
|
||||
*/
|
||||
abstract public function disableForeignKeys();
|
||||
|
||||
/**
|
||||
* Return true if the error code is a duplicate key
|
||||
*
|
||||
* @abstract
|
||||
* @access public
|
||||
* @param integer $code
|
||||
* @return boolean
|
||||
*/
|
||||
abstract public function isDuplicateKeyError($code);
|
||||
|
||||
/**
|
||||
* Escape identifier
|
||||
*
|
||||
* @abstract
|
||||
* @access public
|
||||
* @param string $identifier
|
||||
* @return string
|
||||
*/
|
||||
abstract public function escape($identifier);
|
||||
|
||||
/**
|
||||
* Get non standard operator
|
||||
*
|
||||
* @abstract
|
||||
* @access public
|
||||
* @param string $operator
|
||||
* @return string
|
||||
*/
|
||||
abstract public function getOperator($operator);
|
||||
|
||||
/**
|
||||
* Get last inserted id
|
||||
*
|
||||
* @abstract
|
||||
* @access public
|
||||
* @return integer
|
||||
*/
|
||||
abstract public function getLastId();
|
||||
|
||||
/**
|
||||
* Get current schema version
|
||||
*
|
||||
* @abstract
|
||||
* @access public
|
||||
* @return integer
|
||||
*/
|
||||
abstract public function getSchemaVersion();
|
||||
|
||||
/**
|
||||
* Set current schema version
|
||||
*
|
||||
* @abstract
|
||||
* @access public
|
||||
* @param integer $version
|
||||
*/
|
||||
abstract public function setSchemaVersion($version);
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @access public
|
||||
* @param array $settings
|
||||
*/
|
||||
public function __construct(array $settings)
|
||||
{
|
||||
foreach ($this->requiredAttributes as $attribute) {
|
||||
if (! isset($settings[$attribute])) {
|
||||
throw new LogicException('This configuration parameter is missing: "'.$attribute.'"');
|
||||
}
|
||||
}
|
||||
|
||||
$this->createConnection($settings);
|
||||
$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the PDO connection
|
||||
*
|
||||
* @access public
|
||||
* @return PDO
|
||||
*/
|
||||
public function getConnection()
|
||||
{
|
||||
return $this->pdo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Release the PDO connection
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function closeConnection()
|
||||
{
|
||||
$this->pdo = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Upsert for a key/value variable
|
||||
*
|
||||
* @access public
|
||||
* @param string $table
|
||||
* @param string $keyColumn
|
||||
* @param string $valueColumn
|
||||
* @param array $dictionary
|
||||
* @return bool False on failure
|
||||
*/
|
||||
public function upsert($table, $keyColumn, $valueColumn, array $dictionary)
|
||||
{
|
||||
try {
|
||||
$this->pdo->beginTransaction();
|
||||
|
||||
foreach ($dictionary as $key => $value) {
|
||||
|
||||
$rq = $this->pdo->prepare('SELECT 1 FROM '.$this->escape($table).' WHERE '.$this->escape($keyColumn).'=?');
|
||||
$rq->execute(array($key));
|
||||
|
||||
if ($rq->fetchColumn()) {
|
||||
$rq = $this->pdo->prepare('UPDATE '.$this->escape($table).' SET '.$this->escape($valueColumn).'=? WHERE '.$this->escape($keyColumn).'=?');
|
||||
$rq->execute(array($value, $key));
|
||||
}
|
||||
else {
|
||||
$rq = $this->pdo->prepare('INSERT INTO '.$this->escape($table).' ('.$this->escape($keyColumn).', '.$this->escape($valueColumn).') VALUES (?, ?)');
|
||||
$rq->execute(array($key, $value));
|
||||
}
|
||||
}
|
||||
|
||||
$this->pdo->commit();
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (PDOException $e) {
|
||||
$this->pdo->rollBack();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run EXPLAIN command
|
||||
*
|
||||
* @access public
|
||||
* @param string $sql
|
||||
* @param array $values
|
||||
* @return array
|
||||
*/
|
||||
public function explain($sql, array $values)
|
||||
{
|
||||
return $this->getConnection()->query('EXPLAIN '.$this->getSqlFromPreparedStatement($sql, $values))->fetchAll(PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace placeholder with values in prepared statement
|
||||
*
|
||||
* @access protected
|
||||
* @param string $sql
|
||||
* @param array $values
|
||||
* @return string
|
||||
*/
|
||||
protected function getSqlFromPreparedStatement($sql, array $values)
|
||||
{
|
||||
foreach ($values as $value) {
|
||||
$sql = substr_replace($sql, "'$value'", strpos($sql, '?'), 1);
|
||||
}
|
||||
|
||||
return $sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get database version
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getDatabaseVersion()
|
||||
{
|
||||
return $this->getConnection()->query('SELECT VERSION()')->fetchColumn();
|
||||
}
|
||||
}
|
||||
178
vendor/fguillot/picodb/lib/PicoDb/Driver/Mssql.php
vendored
Normal file
178
vendor/fguillot/picodb/lib/PicoDb/Driver/Mssql.php
vendored
Normal file
@@ -0,0 +1,178 @@
|
||||
<?php
|
||||
|
||||
namespace PicoDb\Driver;
|
||||
|
||||
use PDO;
|
||||
|
||||
/**
|
||||
* Microsoft SQL Server Driver
|
||||
*
|
||||
* @package PicoDb\Driver
|
||||
* @author Algy Taylor <thomas.taylor@cmft.nhs.uk>
|
||||
*/
|
||||
class Mssql extends Base
|
||||
{
|
||||
/**
|
||||
* List of required settings options
|
||||
*
|
||||
* @access protected
|
||||
* @var array
|
||||
*/
|
||||
protected $requiredAttributes = array(
|
||||
'hostname',
|
||||
'username',
|
||||
'password',
|
||||
'database',
|
||||
);
|
||||
|
||||
/**
|
||||
* Table to store the schema version
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
private $schemaTable = 'schema_version';
|
||||
|
||||
/**
|
||||
* Create a new PDO connection
|
||||
*
|
||||
* @access public
|
||||
* @param array $settings
|
||||
*/
|
||||
public function createConnection(array $settings)
|
||||
{
|
||||
$dsn = 'sqlsrv:Server=' . $settings['hostname'] . ';Database=' . $settings['database'];
|
||||
|
||||
if (! empty($settings['port'])) {
|
||||
$dsn .= ';port=' . $settings['port'];
|
||||
}
|
||||
|
||||
$this->pdo = new PDO($dsn, $settings['username'], $settings['password']);
|
||||
|
||||
if (isset($settings['schema_table'])) {
|
||||
$this->schemaTable = $settings['schema_table'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable foreign keys
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function enableForeignKeys()
|
||||
{
|
||||
$this->pdo->exec('EXEC sp_MSforeachtable @command1="ALTER TABLE ? CHECK CONSTRAINT ALL"; GO;');
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable foreign keys
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function disableForeignKeys()
|
||||
{
|
||||
$this->pdo->exec('EXEC sp_MSforeachtable @command1="ALTER TABLE ? NOCHECK CONSTRAINT ALL"; GO;');
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the error code is a duplicate key
|
||||
*
|
||||
* @access public
|
||||
* @param integer $code
|
||||
* @return boolean
|
||||
*/
|
||||
public function isDuplicateKeyError($code)
|
||||
{
|
||||
return $code == 2601;
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape identifier
|
||||
*
|
||||
* https://msdn.microsoft.com/en-us/library/ms175874.aspx
|
||||
*
|
||||
* @access public
|
||||
* @param string $identifier
|
||||
* @return string
|
||||
*/
|
||||
public function escape($identifier)
|
||||
{
|
||||
return '['.$identifier.']';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get non standard operator
|
||||
*
|
||||
* @access public
|
||||
* @param string $operator
|
||||
* @return string
|
||||
*/
|
||||
public function getOperator($operator)
|
||||
{
|
||||
if ($operator === 'LIKE' || $operator === 'ILIKE') {
|
||||
return 'LIKE';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get last inserted id
|
||||
*
|
||||
* @access public
|
||||
* @return integer
|
||||
*/
|
||||
public function getLastId()
|
||||
{
|
||||
return $this->pdo->lastInsertId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current schema version
|
||||
*
|
||||
* @access public
|
||||
* @return integer
|
||||
*/
|
||||
public function getSchemaVersion()
|
||||
{
|
||||
$this->pdo->exec("CREATE TABLE IF NOT EXISTS [".$this->schemaTable."] ([version] INT DEFAULT '0')");
|
||||
|
||||
$rq = $this->pdo->prepare('SELECT [version] FROM ['.$this->schemaTable.']');
|
||||
$rq->execute();
|
||||
$result = $rq->fetchColumn();
|
||||
|
||||
if ($result !== false) {
|
||||
return (int) $result;
|
||||
}
|
||||
else {
|
||||
$this->pdo->exec('INSERT INTO ['.$this->schemaTable.'] VALUES(0)');
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set current schema version
|
||||
*
|
||||
* @access public
|
||||
* @param integer $version
|
||||
*/
|
||||
public function setSchemaVersion($version)
|
||||
{
|
||||
$rq = $this->pdo->prepare('UPDATE ['.$this->schemaTable.'] SET [version]=?');
|
||||
$rq->execute(array($version));
|
||||
}
|
||||
|
||||
/**
|
||||
* Run EXPLAIN command
|
||||
*
|
||||
* @param string $sql
|
||||
* @param array $values
|
||||
* @return array
|
||||
*/
|
||||
public function explain($sql, array $values)
|
||||
{
|
||||
$this->getConnection()->exec('SET SHOWPLAN_ALL ON');
|
||||
return $this->getConnection()->query($this->getSqlFromPreparedStatement($sql, $values))->fetchAll(PDO::FETCH_ASSOC);
|
||||
}
|
||||
}
|
||||
252
vendor/fguillot/picodb/lib/PicoDb/Driver/Mysql.php
vendored
Normal file
252
vendor/fguillot/picodb/lib/PicoDb/Driver/Mysql.php
vendored
Normal file
@@ -0,0 +1,252 @@
|
||||
<?php
|
||||
|
||||
namespace PicoDb\Driver;
|
||||
|
||||
use PDO;
|
||||
use PDOException;
|
||||
|
||||
/**
|
||||
* Mysql Driver
|
||||
*
|
||||
* @package PicoDb\Driver
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class Mysql extends Base
|
||||
{
|
||||
/**
|
||||
* List of required settings options
|
||||
*
|
||||
* @access protected
|
||||
* @var array
|
||||
*/
|
||||
protected $requiredAttributes = array(
|
||||
'hostname',
|
||||
'username',
|
||||
'password',
|
||||
'database',
|
||||
);
|
||||
|
||||
/**
|
||||
* Table to store the schema version
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
private $schemaTable = 'schema_version';
|
||||
|
||||
/**
|
||||
* Create a new PDO connection
|
||||
*
|
||||
* @access public
|
||||
* @param array $settings
|
||||
*/
|
||||
public function createConnection(array $settings)
|
||||
{
|
||||
$this->pdo = new PDO(
|
||||
$this->buildDsn($settings),
|
||||
$settings['username'],
|
||||
$settings['password'],
|
||||
$this->buildOptions($settings)
|
||||
);
|
||||
|
||||
if (isset($settings['schema_table'])) {
|
||||
$this->schemaTable = $settings['schema_table'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build connection DSN
|
||||
*
|
||||
* @access protected
|
||||
* @param array $settings
|
||||
* @return string
|
||||
*/
|
||||
protected function buildDsn(array $settings)
|
||||
{
|
||||
$charset = empty($settings['charset']) ? 'utf8' : $settings['charset'];
|
||||
$dsn = 'mysql:host='.$settings['hostname'].';dbname='.$settings['database'].';charset='.$charset;
|
||||
|
||||
if (! empty($settings['port'])) {
|
||||
$dsn .= ';port='.$settings['port'];
|
||||
}
|
||||
|
||||
return $dsn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build connection options
|
||||
*
|
||||
* @access protected
|
||||
* @param array $settings
|
||||
* @return array
|
||||
*/
|
||||
protected function buildOptions(array $settings)
|
||||
{
|
||||
$options = array(
|
||||
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET sql_mode = STRICT_ALL_TABLES',
|
||||
);
|
||||
|
||||
if (! empty($settings['ssl_key'])) {
|
||||
$options[PDO::MYSQL_ATTR_SSL_KEY] = $settings['ssl_key'];
|
||||
}
|
||||
|
||||
if (! empty($settings['ssl_cert'])) {
|
||||
$options[PDO::MYSQL_ATTR_SSL_CERT] = $settings['ssl_cert'];
|
||||
}
|
||||
|
||||
if (! empty($settings['ssl_ca'])) {
|
||||
$options[PDO::MYSQL_ATTR_SSL_CA] = $settings['ssl_ca'];
|
||||
}
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable foreign keys
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function enableForeignKeys()
|
||||
{
|
||||
$this->pdo->exec('SET FOREIGN_KEY_CHECKS=1');
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable foreign keys
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function disableForeignKeys()
|
||||
{
|
||||
$this->pdo->exec('SET FOREIGN_KEY_CHECKS=0');
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the error code is a duplicate key
|
||||
*
|
||||
* @access public
|
||||
* @param integer $code
|
||||
* @return boolean
|
||||
*/
|
||||
public function isDuplicateKeyError($code)
|
||||
{
|
||||
return $code == 23000;
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape identifier
|
||||
*
|
||||
* @access public
|
||||
* @param string $identifier
|
||||
* @return string
|
||||
*/
|
||||
public function escape($identifier)
|
||||
{
|
||||
return '`'.$identifier.'`';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get non standard operator
|
||||
*
|
||||
* @access public
|
||||
* @param string $operator
|
||||
* @return string
|
||||
*/
|
||||
public function getOperator($operator)
|
||||
{
|
||||
if ($operator === 'LIKE') {
|
||||
return 'LIKE BINARY';
|
||||
}
|
||||
else if ($operator === 'ILIKE') {
|
||||
return 'LIKE';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get last inserted id
|
||||
*
|
||||
* @access public
|
||||
* @return integer
|
||||
*/
|
||||
public function getLastId()
|
||||
{
|
||||
return $this->pdo->lastInsertId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current schema version
|
||||
*
|
||||
* @access public
|
||||
* @return integer
|
||||
*/
|
||||
public function getSchemaVersion()
|
||||
{
|
||||
$this->pdo->exec("CREATE TABLE IF NOT EXISTS `".$this->schemaTable."` (`version` INT DEFAULT '0') ENGINE=InnoDB CHARSET=utf8");
|
||||
|
||||
$rq = $this->pdo->prepare('SELECT `version` FROM `'.$this->schemaTable.'`');
|
||||
$rq->execute();
|
||||
$result = $rq->fetchColumn();
|
||||
|
||||
if ($result !== false) {
|
||||
return (int) $result;
|
||||
}
|
||||
else {
|
||||
$this->pdo->exec('INSERT INTO `'.$this->schemaTable.'` VALUES(0)');
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set current schema version
|
||||
*
|
||||
* @access public
|
||||
* @param integer $version
|
||||
*/
|
||||
public function setSchemaVersion($version)
|
||||
{
|
||||
$rq = $this->pdo->prepare('UPDATE `'.$this->schemaTable.'` SET `version`=?');
|
||||
$rq->execute(array($version));
|
||||
}
|
||||
|
||||
/**
|
||||
* Upsert for a key/value variable
|
||||
*
|
||||
* @access public
|
||||
* @param string $table
|
||||
* @param string $keyColumn
|
||||
* @param string $valueColumn
|
||||
* @param array $dictionary
|
||||
* @return bool False on failure
|
||||
*/
|
||||
public function upsert($table, $keyColumn, $valueColumn, array $dictionary)
|
||||
{
|
||||
try {
|
||||
|
||||
$sql = sprintf(
|
||||
'REPLACE INTO %s (%s, %s) VALUES %s',
|
||||
$this->escape($table),
|
||||
$this->escape($keyColumn),
|
||||
$this->escape($valueColumn),
|
||||
implode(', ', array_fill(0, count($dictionary), '(?, ?)'))
|
||||
);
|
||||
|
||||
$values = array();
|
||||
|
||||
foreach ($dictionary as $key => $value) {
|
||||
$values[] = $key;
|
||||
$values[] = $value;
|
||||
}
|
||||
|
||||
$rq = $this->pdo->prepare($sql);
|
||||
$rq->execute($values);
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (PDOException $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
196
vendor/fguillot/picodb/lib/PicoDb/Driver/Postgres.php
vendored
Normal file
196
vendor/fguillot/picodb/lib/PicoDb/Driver/Postgres.php
vendored
Normal file
@@ -0,0 +1,196 @@
|
||||
<?php
|
||||
|
||||
namespace PicoDb\Driver;
|
||||
|
||||
use PDO;
|
||||
use PDOException;
|
||||
|
||||
/**
|
||||
* Postgres Driver
|
||||
*
|
||||
* @package PicoDb\Driver
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class Postgres extends Base
|
||||
{
|
||||
/**
|
||||
* List of required settings options
|
||||
*
|
||||
* @access protected
|
||||
* @var array
|
||||
*/
|
||||
protected $requiredAttributes = array(
|
||||
'hostname',
|
||||
'username',
|
||||
'password',
|
||||
'database',
|
||||
);
|
||||
|
||||
/**
|
||||
* Table to store the schema version
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
private $schemaTable = 'schema_version';
|
||||
|
||||
/**
|
||||
* Create a new PDO connection
|
||||
*
|
||||
* @access public
|
||||
* @param array $settings
|
||||
*/
|
||||
public function createConnection(array $settings)
|
||||
{
|
||||
$dsn = 'pgsql:host='.$settings['hostname'].';dbname='.$settings['database'];
|
||||
|
||||
if (! empty($settings['port'])) {
|
||||
$dsn .= ';port='.$settings['port'];
|
||||
}
|
||||
|
||||
$this->pdo = new PDO($dsn, $settings['username'], $settings['password']);
|
||||
|
||||
if (isset($settings['schema_table'])) {
|
||||
$this->schemaTable = $settings['schema_table'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable foreign keys
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function enableForeignKeys()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable foreign keys
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function disableForeignKeys()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the error code is a duplicate key
|
||||
*
|
||||
* @access public
|
||||
* @param integer $code
|
||||
* @return boolean
|
||||
*/
|
||||
public function isDuplicateKeyError($code)
|
||||
{
|
||||
return $code == 23505 || $code == 23503;
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape identifier
|
||||
*
|
||||
* @access public
|
||||
* @param string $identifier
|
||||
* @return string
|
||||
*/
|
||||
public function escape($identifier)
|
||||
{
|
||||
return '"'.$identifier.'"';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get non standard operator
|
||||
*
|
||||
* @access public
|
||||
* @param string $operator
|
||||
* @return string
|
||||
*/
|
||||
public function getOperator($operator)
|
||||
{
|
||||
if ($operator === 'LIKE') {
|
||||
return 'LIKE';
|
||||
}
|
||||
else if ($operator === 'ILIKE') {
|
||||
return 'ILIKE';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get last inserted id
|
||||
*
|
||||
* @access public
|
||||
* @return integer
|
||||
*/
|
||||
public function getLastId()
|
||||
{
|
||||
try {
|
||||
$rq = $this->pdo->prepare('SELECT LASTVAL()');
|
||||
$rq->execute();
|
||||
|
||||
return $rq->fetchColumn();
|
||||
}
|
||||
catch (PDOException $e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current schema version
|
||||
*
|
||||
* @access public
|
||||
* @return integer
|
||||
*/
|
||||
public function getSchemaVersion()
|
||||
{
|
||||
$this->pdo->exec("CREATE TABLE IF NOT EXISTS ".$this->schemaTable." (version INTEGER DEFAULT 0)");
|
||||
|
||||
$rq = $this->pdo->prepare('SELECT "version" FROM "'.$this->schemaTable.'"');
|
||||
$rq->execute();
|
||||
$result = $rq->fetchColumn();
|
||||
|
||||
if ($result !== false) {
|
||||
return (int) $result;
|
||||
}
|
||||
else {
|
||||
$this->pdo->exec('INSERT INTO '.$this->schemaTable.' VALUES(0)');
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set current schema version
|
||||
*
|
||||
* @access public
|
||||
* @param integer $version
|
||||
*/
|
||||
public function setSchemaVersion($version)
|
||||
{
|
||||
$rq = $this->pdo->prepare('UPDATE '.$this->schemaTable.' SET version=?');
|
||||
$rq->execute(array($version));
|
||||
}
|
||||
|
||||
/**
|
||||
* Run EXPLAIN command
|
||||
*
|
||||
* @param string $sql
|
||||
* @param array $values
|
||||
* @return array
|
||||
*/
|
||||
public function explain($sql, array $values)
|
||||
{
|
||||
return $this->getConnection()->query('EXPLAIN (FORMAT YAML) '.$this->getSqlFromPreparedStatement($sql, $values))->fetchAll(PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get database version
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getDatabaseVersion()
|
||||
{
|
||||
return $this->getConnection()->query('SHOW server_version')->fetchColumn();
|
||||
}
|
||||
}
|
||||
193
vendor/fguillot/picodb/lib/PicoDb/Driver/Sqlite.php
vendored
Normal file
193
vendor/fguillot/picodb/lib/PicoDb/Driver/Sqlite.php
vendored
Normal file
@@ -0,0 +1,193 @@
|
||||
<?php
|
||||
|
||||
namespace PicoDb\Driver;
|
||||
|
||||
use PDO;
|
||||
use PDOException;
|
||||
|
||||
/**
|
||||
* Sqlite Driver
|
||||
*
|
||||
* @package PicoDb\Driver
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class Sqlite extends Base
|
||||
{
|
||||
/**
|
||||
* List of required settings options
|
||||
*
|
||||
* @access protected
|
||||
* @var array
|
||||
*/
|
||||
protected $requiredAttributes = array('filename');
|
||||
|
||||
/**
|
||||
* Create a new PDO connection
|
||||
*
|
||||
* @access public
|
||||
* @param array $settings
|
||||
*/
|
||||
public function createConnection(array $settings)
|
||||
{
|
||||
$this->pdo = new PDO('sqlite:'.$settings['filename']);
|
||||
$this->enableForeignKeys();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable foreign keys
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function enableForeignKeys()
|
||||
{
|
||||
$this->pdo->exec('PRAGMA foreign_keys = ON');
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable foreign keys
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function disableForeignKeys()
|
||||
{
|
||||
$this->pdo->exec('PRAGMA foreign_keys = OFF');
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the error code is a duplicate key
|
||||
*
|
||||
* @access public
|
||||
* @param integer $code
|
||||
* @return boolean
|
||||
*/
|
||||
public function isDuplicateKeyError($code)
|
||||
{
|
||||
return $code == 23000;
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape identifier
|
||||
*
|
||||
* @access public
|
||||
* @param string $identifier
|
||||
* @return string
|
||||
*/
|
||||
public function escape($identifier)
|
||||
{
|
||||
return '"'.$identifier.'"';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get non standard operator
|
||||
*
|
||||
* @access public
|
||||
* @param string $operator
|
||||
* @return string
|
||||
*/
|
||||
public function getOperator($operator)
|
||||
{
|
||||
if ($operator === 'LIKE' || $operator === 'ILIKE') {
|
||||
return 'LIKE';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get last inserted id
|
||||
*
|
||||
* @access public
|
||||
* @return integer
|
||||
*/
|
||||
public function getLastId()
|
||||
{
|
||||
return $this->pdo->lastInsertId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current schema version
|
||||
*
|
||||
* @access public
|
||||
* @return integer
|
||||
*/
|
||||
public function getSchemaVersion()
|
||||
{
|
||||
$rq = $this->pdo->prepare('PRAGMA user_version');
|
||||
$rq->execute();
|
||||
|
||||
return (int) $rq->fetchColumn();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set current schema version
|
||||
*
|
||||
* @access public
|
||||
* @param integer $version
|
||||
*/
|
||||
public function setSchemaVersion($version)
|
||||
{
|
||||
$this->pdo->exec('PRAGMA user_version='.$version);
|
||||
}
|
||||
|
||||
/**
|
||||
* Upsert for a key/value variable
|
||||
*
|
||||
* @access public
|
||||
* @param string $table
|
||||
* @param string $keyColumn
|
||||
* @param string $valueColumn
|
||||
* @param array $dictionary
|
||||
* @return bool False on failure
|
||||
*/
|
||||
public function upsert($table, $keyColumn, $valueColumn, array $dictionary)
|
||||
{
|
||||
try {
|
||||
$this->pdo->beginTransaction();
|
||||
|
||||
foreach ($dictionary as $key => $value) {
|
||||
|
||||
$sql = sprintf(
|
||||
'INSERT OR REPLACE INTO %s (%s, %s) VALUES (?, ?)',
|
||||
$this->escape($table),
|
||||
$this->escape($keyColumn),
|
||||
$this->escape($valueColumn)
|
||||
);
|
||||
|
||||
$rq = $this->pdo->prepare($sql);
|
||||
$rq->execute(array($key, $value));
|
||||
}
|
||||
|
||||
$this->pdo->commit();
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (PDOException $e) {
|
||||
$this->pdo->rollBack();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run EXPLAIN command
|
||||
*
|
||||
* @access public
|
||||
* @param string $sql
|
||||
* @param array $values
|
||||
* @return array
|
||||
*/
|
||||
public function explain($sql, array $values)
|
||||
{
|
||||
return $this->getConnection()->query('EXPLAIN QUERY PLAN '.$this->getSqlFromPreparedStatement($sql, $values))->fetchAll(PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get database version
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getDatabaseVersion()
|
||||
{
|
||||
return $this->getConnection()->query('SELECT sqlite_version()')->fetchColumn();
|
||||
}
|
||||
}
|
||||
45
vendor/fguillot/picodb/lib/PicoDb/DriverFactory.php
vendored
Normal file
45
vendor/fguillot/picodb/lib/PicoDb/DriverFactory.php
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace PicoDb;
|
||||
|
||||
use LogicException;
|
||||
use PicoDb\Driver\Mssql;
|
||||
use PicoDb\Driver\Mysql;
|
||||
use PicoDb\Driver\Postgres;
|
||||
use PicoDb\Driver\Sqlite;
|
||||
|
||||
/**
|
||||
* Class DriverFactory
|
||||
*
|
||||
* @package PicoDb
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class DriverFactory
|
||||
{
|
||||
/**
|
||||
* Get database driver from settings or environment URL
|
||||
*
|
||||
* @access public
|
||||
* @param array $settings
|
||||
* @return Mssql|Mysql|Postgres|Sqlite
|
||||
*/
|
||||
public static function getDriver(array $settings)
|
||||
{
|
||||
if (! isset($settings['driver'])) {
|
||||
throw new LogicException('You must define a database driver');
|
||||
}
|
||||
|
||||
switch ($settings['driver']) {
|
||||
case 'sqlite':
|
||||
return new Sqlite($settings);
|
||||
case 'mssql':
|
||||
return new Mssql($settings);
|
||||
case 'mysql':
|
||||
return new Mysql($settings);
|
||||
case 'postgres':
|
||||
return new Postgres($settings);
|
||||
default:
|
||||
throw new LogicException('This database driver is not supported');
|
||||
}
|
||||
}
|
||||
}
|
||||
112
vendor/fguillot/picodb/lib/PicoDb/Hashtable.php
vendored
Normal file
112
vendor/fguillot/picodb/lib/PicoDb/Hashtable.php
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
namespace PicoDb;
|
||||
|
||||
use PDO;
|
||||
|
||||
/**
|
||||
* HashTable (key/value)
|
||||
*
|
||||
* @package PicoDb
|
||||
* @author Frederic Guillot
|
||||
* @author Mathias Kresin
|
||||
*/
|
||||
class Hashtable extends Table
|
||||
{
|
||||
/**
|
||||
* Column for the key
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
private $keyColumn = 'key';
|
||||
|
||||
/**
|
||||
* Column for the value
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
private $valueColumn = 'value';
|
||||
|
||||
/**
|
||||
* Set the key column
|
||||
*
|
||||
* @access public
|
||||
* @param string $column
|
||||
* @return $this
|
||||
*/
|
||||
public function columnKey($column)
|
||||
{
|
||||
$this->keyColumn = $column;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value column
|
||||
*
|
||||
* @access public
|
||||
* @param string $column
|
||||
* @return $this
|
||||
*/
|
||||
public function columnValue($column)
|
||||
{
|
||||
$this->valueColumn = $column;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert or update
|
||||
*
|
||||
* @access public
|
||||
* @param array $hashmap
|
||||
* @return boolean
|
||||
*/
|
||||
public function put(array $hashmap)
|
||||
{
|
||||
return $this->db->getDriver()->upsert($this->getName(), $this->keyColumn, $this->valueColumn, $hashmap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hashmap result [ [column1 => column2], [], ...]
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
$hashmap = array();
|
||||
|
||||
// setup where condition
|
||||
if (func_num_args() > 0) {
|
||||
$this->in($this->keyColumn, func_get_args());
|
||||
}
|
||||
|
||||
// setup to select columns in case that there are more than two
|
||||
$this->columns($this->keyColumn, $this->valueColumn);
|
||||
|
||||
$rq = $this->db->execute($this->buildSelectQuery(), $this->conditionBuilder->getValues());
|
||||
$rows = $rq->fetchAll(PDO::FETCH_NUM);
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$hashmap[$row[0]] = $row[1];
|
||||
}
|
||||
|
||||
return $hashmap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shortcut method to get a hashmap result
|
||||
*
|
||||
* @access public
|
||||
* @param string $key Key column
|
||||
* @param string $value Value column
|
||||
* @return array
|
||||
*/
|
||||
public function getAll($key, $value)
|
||||
{
|
||||
$this->keyColumn = $key;
|
||||
$this->valueColumn = $value;
|
||||
return $this->get();
|
||||
}
|
||||
}
|
||||
167
vendor/fguillot/picodb/lib/PicoDb/LargeObject.php
vendored
Normal file
167
vendor/fguillot/picodb/lib/PicoDb/LargeObject.php
vendored
Normal file
@@ -0,0 +1,167 @@
|
||||
<?php
|
||||
|
||||
namespace PicoDb;
|
||||
|
||||
use PDO;
|
||||
use PicoDb\Builder\InsertBuilder;
|
||||
use PicoDb\Builder\UpdateBuilder;
|
||||
|
||||
/**
|
||||
* Handle Large Objects (LOBs)
|
||||
*
|
||||
* @package PicoDb
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class LargeObject extends Table
|
||||
{
|
||||
/**
|
||||
* Fetch large object as file descriptor
|
||||
*
|
||||
* This method is not compatible with Sqlite and Mysql (return a string instead of resource)
|
||||
*
|
||||
* @access public
|
||||
* @param string $column
|
||||
* @return resource
|
||||
*/
|
||||
public function findOneColumnAsStream($column)
|
||||
{
|
||||
$this->limit(1);
|
||||
$this->columns($column);
|
||||
|
||||
$rq = $this->db->getStatementHandler()
|
||||
->withSql($this->buildSelectQuery())
|
||||
->withPositionalParams($this->conditionBuilder->getValues())
|
||||
->execute();
|
||||
|
||||
$rq->bindColumn($column, $fd, PDO::PARAM_LOB);
|
||||
$rq->fetch(PDO::FETCH_BOUND);
|
||||
|
||||
return $fd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch large object as string
|
||||
*
|
||||
* @access public
|
||||
* @param string $column
|
||||
* @return string
|
||||
*/
|
||||
public function findOneColumnAsString($column)
|
||||
{
|
||||
$fd = $this->findOneColumnAsStream($column);
|
||||
|
||||
if (is_string($fd)) {
|
||||
return $fd;
|
||||
}
|
||||
|
||||
return stream_get_contents($fd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert large object from stream
|
||||
*
|
||||
* @access public
|
||||
* @param string $blobColumn
|
||||
* @param resource|string $blobDescriptor
|
||||
* @param array $data
|
||||
* @return bool
|
||||
*/
|
||||
public function insertFromStream($blobColumn, &$blobDescriptor, array $data = array())
|
||||
{
|
||||
$columns = array_merge(array($blobColumn), array_keys($data));
|
||||
$this->db->startTransaction();
|
||||
|
||||
$result = $this->db->getStatementHandler()
|
||||
->withSql(InsertBuilder::getInstance($this->db, $this->conditionBuilder)
|
||||
->withTable($this->name)
|
||||
->withColumns($columns)
|
||||
->build()
|
||||
)
|
||||
->withNamedParams($data)
|
||||
->withLobParam($blobColumn, $blobDescriptor)
|
||||
->execute();
|
||||
|
||||
$this->db->closeTransaction();
|
||||
|
||||
return $result !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert large object from file
|
||||
*
|
||||
* @access public
|
||||
* @param string $blobColumn
|
||||
* @param string $filename
|
||||
* @param array $data
|
||||
* @return bool
|
||||
*/
|
||||
public function insertFromFile($blobColumn, $filename, array $data = array())
|
||||
{
|
||||
$fp = fopen($filename, 'rb');
|
||||
$result = $this->insertFromStream($blobColumn, $fp, $data);
|
||||
fclose($fp);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert large object from string
|
||||
*
|
||||
* @access public
|
||||
* @param string $blobColumn
|
||||
* @param string $blobData
|
||||
* @param array $data
|
||||
* @return bool
|
||||
*/
|
||||
public function insertFromString($blobColumn, &$blobData, array $data = array())
|
||||
{
|
||||
return $this->insertFromStream($blobColumn, $blobData, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update large object from stream
|
||||
*
|
||||
* @access public
|
||||
* @param string $blobColumn
|
||||
* @param resource $blobDescriptor
|
||||
* @param array $data
|
||||
* @return bool
|
||||
*/
|
||||
public function updateFromStream($blobColumn, &$blobDescriptor, array $data = array())
|
||||
{
|
||||
$values = array_merge(array_values($data), $this->conditionBuilder->getValues());
|
||||
$columns = array_merge(array($blobColumn), array_keys($data));
|
||||
|
||||
$this->db->startTransaction();
|
||||
|
||||
$result = $this->db->getStatementHandler()
|
||||
->withSql(UpdateBuilder::getInstance($this->db, $this->conditionBuilder)
|
||||
->withTable($this->name)
|
||||
->withColumns($columns)
|
||||
->build()
|
||||
)
|
||||
->withPositionalParams($values)
|
||||
->withLobParam($blobColumn, $blobDescriptor)
|
||||
->execute();
|
||||
|
||||
$this->db->closeTransaction();
|
||||
|
||||
return $result !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update large object from file
|
||||
*
|
||||
* @access public
|
||||
* @param string $blobColumn
|
||||
* @param string $filename
|
||||
* @param array $data
|
||||
* @return bool
|
||||
*/
|
||||
public function updateFromFile($blobColumn, $filename, array $data = array())
|
||||
{
|
||||
$fp = fopen($filename, 'r');
|
||||
$result = $this->updateFromStream($blobColumn, $fp, $data);
|
||||
fclose($fp);
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
15
vendor/fguillot/picodb/lib/PicoDb/SQLException.php
vendored
Normal file
15
vendor/fguillot/picodb/lib/PicoDb/SQLException.php
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace PicoDb;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* SQLException
|
||||
*
|
||||
* @package PicoDb
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class SQLException extends Exception
|
||||
{
|
||||
}
|
||||
119
vendor/fguillot/picodb/lib/PicoDb/Schema.php
vendored
Normal file
119
vendor/fguillot/picodb/lib/PicoDb/Schema.php
vendored
Normal file
@@ -0,0 +1,119 @@
|
||||
<?php
|
||||
|
||||
namespace PicoDb;
|
||||
|
||||
use PDOException;
|
||||
|
||||
/**
|
||||
* Schema migration class
|
||||
*
|
||||
* @package PicoDb
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class Schema
|
||||
{
|
||||
/**
|
||||
* Database instance
|
||||
*
|
||||
* @access protected
|
||||
* @var Database
|
||||
*/
|
||||
protected $db = null;
|
||||
|
||||
/**
|
||||
* Schema namespace
|
||||
*
|
||||
* @access protected
|
||||
* @var string
|
||||
*/
|
||||
protected $namespace = '\Schema';
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @access public
|
||||
* @param Database $db
|
||||
*/
|
||||
public function __construct(Database $db)
|
||||
{
|
||||
$this->db = $db;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set another namespace
|
||||
*
|
||||
* @access public
|
||||
* @param string $namespace
|
||||
* @return Schema
|
||||
*/
|
||||
public function setNamespace($namespace)
|
||||
{
|
||||
$this->namespace = $namespace;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get schema namespace
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getNamespace()
|
||||
{
|
||||
return $this->namespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the schema version and run the migrations
|
||||
*
|
||||
* @access public
|
||||
* @param integer $last_version
|
||||
* @return boolean
|
||||
*/
|
||||
public function check($last_version = 1)
|
||||
{
|
||||
$current_version = $this->db->getDriver()->getSchemaVersion();
|
||||
|
||||
if ($current_version < $last_version) {
|
||||
return $this->migrateTo($current_version, $last_version);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrate the schema to one version to another
|
||||
*
|
||||
* @access public
|
||||
* @param integer $current_version
|
||||
* @param integer $next_version
|
||||
* @return boolean
|
||||
*/
|
||||
public function migrateTo($current_version, $next_version)
|
||||
{
|
||||
try {
|
||||
for ($i = $current_version + 1; $i <= $next_version; $i++) {
|
||||
$this->db->startTransaction();
|
||||
$this->db->getDriver()->disableForeignKeys();
|
||||
|
||||
$function_name = $this->getNamespace().'\version_'.$i;
|
||||
|
||||
if (function_exists($function_name)) {
|
||||
$this->db->setLogMessage('Running migration '.$function_name);
|
||||
call_user_func($function_name, $this->db->getConnection());
|
||||
}
|
||||
|
||||
$this->db->getDriver()->setSchemaVersion($i);
|
||||
$this->db->getDriver()->enableForeignKeys();
|
||||
$this->db->closeTransaction();
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
$this->db->setLogMessage($e->getMessage());
|
||||
$this->db->cancelTransaction();
|
||||
$this->db->getDriver()->enableForeignKeys();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
353
vendor/fguillot/picodb/lib/PicoDb/StatementHandler.php
vendored
Normal file
353
vendor/fguillot/picodb/lib/PicoDb/StatementHandler.php
vendored
Normal file
@@ -0,0 +1,353 @@
|
||||
<?php
|
||||
|
||||
namespace PicoDb;
|
||||
|
||||
use PDO;
|
||||
use PDOException;
|
||||
use PDOStatement;
|
||||
|
||||
/**
|
||||
* Statement Handler
|
||||
*
|
||||
* @package PicoDb
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class StatementHandler
|
||||
{
|
||||
/**
|
||||
* Database instance
|
||||
*
|
||||
* @access protected
|
||||
* @var Database
|
||||
*/
|
||||
protected $db = null;
|
||||
|
||||
/**
|
||||
* Flag to calculate query time
|
||||
*
|
||||
* @access protected
|
||||
* @var boolean
|
||||
*/
|
||||
protected $stopwatch = false;
|
||||
|
||||
/**
|
||||
* Start time
|
||||
*
|
||||
* @access protected
|
||||
* @var float
|
||||
*/
|
||||
protected $startTime = 0;
|
||||
|
||||
/**
|
||||
* Execution time of all queries
|
||||
*
|
||||
* @access protected
|
||||
* @var float
|
||||
*/
|
||||
protected $executionTime = 0;
|
||||
|
||||
/**
|
||||
* Flag to log generated SQL queries
|
||||
*
|
||||
* @access protected
|
||||
* @var boolean
|
||||
*/
|
||||
protected $logQueries = false;
|
||||
|
||||
/**
|
||||
* Run explain command on each query
|
||||
*
|
||||
* @access protected
|
||||
* @var boolean
|
||||
*/
|
||||
protected $explain = false;
|
||||
|
||||
/**
|
||||
* Number of SQL queries executed
|
||||
*
|
||||
* @access protected
|
||||
* @var integer
|
||||
*/
|
||||
protected $nbQueries = 0;
|
||||
|
||||
/**
|
||||
* SQL query
|
||||
*
|
||||
* @access protected
|
||||
* @var string
|
||||
*/
|
||||
protected $sql = '';
|
||||
|
||||
/**
|
||||
* Positional SQL parameters
|
||||
*
|
||||
* @access protected
|
||||
* @var array
|
||||
*/
|
||||
protected $positionalParams = array();
|
||||
|
||||
/**
|
||||
* Named SQL parameters
|
||||
*
|
||||
* @access protected
|
||||
* @var array
|
||||
*/
|
||||
protected $namedParams = array();
|
||||
|
||||
/**
|
||||
* Flag to use named params
|
||||
*
|
||||
* @access protected
|
||||
* @var boolean
|
||||
*/
|
||||
protected $useNamedParams = false;
|
||||
|
||||
/**
|
||||
* LOB params
|
||||
*
|
||||
* @access protected
|
||||
* @var array
|
||||
*/
|
||||
protected $lobParams = array();
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @access public
|
||||
* @param Database $db
|
||||
*/
|
||||
public function __construct(Database $db)
|
||||
{
|
||||
$this->db = $db;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable query logging
|
||||
*
|
||||
* @access public
|
||||
* @return $this
|
||||
*/
|
||||
public function withLogging()
|
||||
{
|
||||
$this->logQueries = true;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Record query execution time
|
||||
*
|
||||
* @access public
|
||||
* @return $this
|
||||
*/
|
||||
public function withStopWatch()
|
||||
{
|
||||
$this->stopwatch = true;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute explain command on query
|
||||
*
|
||||
* @access public
|
||||
* @return $this
|
||||
*/
|
||||
public function withExplain()
|
||||
{
|
||||
$this->explain = true;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set SQL query
|
||||
*
|
||||
* @access public
|
||||
* @param string $sql
|
||||
* @return $this
|
||||
*/
|
||||
public function withSql($sql)
|
||||
{
|
||||
$this->sql = $sql;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set positional parameters
|
||||
*
|
||||
* @access public
|
||||
* @param array $params
|
||||
* @return $this
|
||||
*/
|
||||
public function withPositionalParams(array $params)
|
||||
{
|
||||
$this->positionalParams = $params;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set named parameters
|
||||
*
|
||||
* @access public
|
||||
* @param array $params
|
||||
* @return $this
|
||||
*/
|
||||
public function withNamedParams(array $params)
|
||||
{
|
||||
$this->namedParams = $params;
|
||||
$this->useNamedParams = true;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bind large object parameter
|
||||
*
|
||||
* @access public
|
||||
* @param $name
|
||||
* @param $fp
|
||||
* @return $this
|
||||
*/
|
||||
public function withLobParam($name, &$fp)
|
||||
{
|
||||
$this->lobParams[$name] =& $fp;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get number of queries executed
|
||||
*
|
||||
* @access public
|
||||
* @return int
|
||||
*/
|
||||
public function getNbQueries()
|
||||
{
|
||||
return $this->nbQueries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a prepared statement
|
||||
*
|
||||
* Note: returns false on duplicate keys instead of SQLException
|
||||
*
|
||||
* @access public
|
||||
* @return PDOStatement|false
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
try {
|
||||
$this->beforeExecute();
|
||||
|
||||
$pdoStatement = $this->db->getConnection()->prepare($this->sql);
|
||||
$this->bindParams($pdoStatement);
|
||||
$pdoStatement->execute();
|
||||
|
||||
$this->afterExecute();
|
||||
return $pdoStatement;
|
||||
} catch (PDOException $e) {
|
||||
return $this->handleSqlError($e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Bind parameters to PDOStatement
|
||||
*
|
||||
* @access protected
|
||||
* @param PDOStatement $pdoStatement
|
||||
*/
|
||||
protected function bindParams(PDOStatement $pdoStatement)
|
||||
{
|
||||
$i = 1;
|
||||
|
||||
foreach ($this->lobParams as $name => $variable) {
|
||||
if (! $this->useNamedParams) {
|
||||
$parameter = $i;
|
||||
$i++;
|
||||
} else {
|
||||
$parameter = $name;
|
||||
}
|
||||
|
||||
$pdoStatement->bindParam($parameter, $variable, PDO::PARAM_LOB);
|
||||
}
|
||||
|
||||
foreach ($this->positionalParams as $value) {
|
||||
$pdoStatement->bindValue($i, $value, PDO::PARAM_STR);
|
||||
$i++;
|
||||
}
|
||||
|
||||
foreach ($this->namedParams as $name => $value) {
|
||||
$pdoStatement->bindValue($name, $value, PDO::PARAM_STR);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method executed before query execution
|
||||
*
|
||||
* @access protected
|
||||
*/
|
||||
protected function beforeExecute()
|
||||
{
|
||||
if ($this->logQueries) {
|
||||
$this->db->setLogMessage($this->sql);
|
||||
}
|
||||
|
||||
if ($this->stopwatch) {
|
||||
$this->startTime = microtime(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method executed after query execution
|
||||
*
|
||||
* @access protected
|
||||
*/
|
||||
protected function afterExecute()
|
||||
{
|
||||
if ($this->stopwatch) {
|
||||
$duration = microtime(true) - $this->startTime;
|
||||
$this->executionTime += $duration;
|
||||
$this->db->setLogMessage('query_duration='.$duration);
|
||||
$this->db->setLogMessage('total_execution_time='.$this->executionTime);
|
||||
}
|
||||
|
||||
if ($this->explain) {
|
||||
$this->db->setLogMessages($this->db->getDriver()->explain($this->sql, $this->positionalParams));
|
||||
}
|
||||
|
||||
$this->nbQueries++;
|
||||
$this->cleanup();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset internal properties after execution
|
||||
* The same object instance is used
|
||||
*
|
||||
* @access protected
|
||||
*/
|
||||
protected function cleanup()
|
||||
{
|
||||
$this->sql = '';
|
||||
$this->useNamedParams = false;
|
||||
$this->positionalParams = array();
|
||||
$this->namedParams = array();
|
||||
$this->lobParams = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle PDOException
|
||||
*
|
||||
* @access public
|
||||
* @param PDOException $e
|
||||
* @return bool
|
||||
* @throws SQLException
|
||||
*/
|
||||
public function handleSqlError(PDOException $e)
|
||||
{
|
||||
$this->cleanup();
|
||||
$this->db->cancelTransaction();
|
||||
$this->db->setLogMessage($e->getMessage());
|
||||
|
||||
if ($this->db->getDriver()->isDuplicateKeyError($e->getCode())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
throw new SQLException('SQL error'.($this->logQueries ? ': '.$e->getMessage() : ''));
|
||||
}
|
||||
}
|
||||
721
vendor/fguillot/picodb/lib/PicoDb/Table.php
vendored
Normal file
721
vendor/fguillot/picodb/lib/PicoDb/Table.php
vendored
Normal file
@@ -0,0 +1,721 @@
|
||||
<?php
|
||||
|
||||
namespace PicoDb;
|
||||
|
||||
use PDO;
|
||||
use Closure;
|
||||
use PicoDb\Builder\ConditionBuilder;
|
||||
use PicoDb\Builder\InsertBuilder;
|
||||
use PicoDb\Builder\UpdateBuilder;
|
||||
|
||||
/**
|
||||
* Table
|
||||
*
|
||||
* @package PicoDb
|
||||
* @author Frederic Guillot
|
||||
*
|
||||
* @method $this addCondition($sql)
|
||||
* @method $this beginOr()
|
||||
* @method $this closeOr()
|
||||
* @method $this eq($column, $value)
|
||||
* @method $this neq($column, $value)
|
||||
* @method $this in($column, array $values)
|
||||
* @method $this inSubquery($column, Table $subquery)
|
||||
* @method $this notIn($column, array $values)
|
||||
* @method $this notInSubquery($column, Table $subquery)
|
||||
* @method $this like($column, $value)
|
||||
* @method $this ilike($column, $value)
|
||||
* @method $this gt($column, $value)
|
||||
* @method $this gtSubquery($column, Table $subquery)
|
||||
* @method $this lt($column, $value)
|
||||
* @method $this ltSubquery($column, Table $subquery)
|
||||
* @method $this gte($column, $value)
|
||||
* @method $this gteSubquery($column, Table $subquery)
|
||||
* @method $this lte($column, $value)
|
||||
* @method $this lteSubquery($column, Table $subquery)
|
||||
* @method $this isNull($column)
|
||||
* @method $this notNull($column)
|
||||
*/
|
||||
class Table
|
||||
{
|
||||
/**
|
||||
* Sorting direction
|
||||
*
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
const SORT_ASC = 'ASC';
|
||||
const SORT_DESC = 'DESC';
|
||||
|
||||
/**
|
||||
* Condition instance
|
||||
*
|
||||
* @access protected
|
||||
* @var ConditionBuilder
|
||||
*/
|
||||
protected $conditionBuilder;
|
||||
|
||||
/**
|
||||
* Database instance
|
||||
*
|
||||
* @access protected
|
||||
* @var Database
|
||||
*/
|
||||
protected $db;
|
||||
|
||||
/**
|
||||
* Table name
|
||||
*
|
||||
* @access protected
|
||||
* @var string
|
||||
*/
|
||||
protected $name = '';
|
||||
|
||||
/**
|
||||
* Columns list for SELECT query
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
private $columns = array();
|
||||
|
||||
/**
|
||||
* Columns to sum during update
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
private $sumColumns = array();
|
||||
|
||||
/**
|
||||
* SQL limit
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
private $sqlLimit = '';
|
||||
|
||||
/**
|
||||
* SQL offset
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
private $sqlOffset = '';
|
||||
|
||||
/**
|
||||
* SQL order
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
private $sqlOrder = '';
|
||||
|
||||
/**
|
||||
* SQL custom SELECT value
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
private $sqlSelect = '';
|
||||
|
||||
/**
|
||||
* SQL joins
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
private $joins = array();
|
||||
|
||||
/**
|
||||
* Use DISTINCT or not?
|
||||
*
|
||||
* @access private
|
||||
* @var boolean
|
||||
*/
|
||||
private $distinct = false;
|
||||
|
||||
/**
|
||||
* Group by those columns
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
private $groupBy = array();
|
||||
|
||||
/**
|
||||
* Callback for result filtering
|
||||
*
|
||||
* @access private
|
||||
* @var Closure
|
||||
*/
|
||||
private $callback = null;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @access public
|
||||
* @param Database $db
|
||||
* @param string $name
|
||||
*/
|
||||
public function __construct(Database $db, $name)
|
||||
{
|
||||
$this->db = $db;
|
||||
$this->name = $name;
|
||||
$this->conditionBuilder = new ConditionBuilder($db);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the table name
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return ConditionBuilder object
|
||||
*
|
||||
* @access public
|
||||
* @return ConditionBuilder
|
||||
*/
|
||||
public function getConditionBuilder()
|
||||
{
|
||||
return $this->conditionBuilder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert or update
|
||||
*
|
||||
* @access public
|
||||
* @param array $data
|
||||
* @return boolean
|
||||
*/
|
||||
public function save(array $data)
|
||||
{
|
||||
return $this->conditionBuilder->hasCondition() ? $this->update($data) : $this->insert($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update
|
||||
*
|
||||
* @access public
|
||||
* @param array $data
|
||||
* @return boolean
|
||||
*/
|
||||
public function update(array $data = array())
|
||||
{
|
||||
$values = array_merge(array_values($data), array_values($this->sumColumns), $this->conditionBuilder->getValues());
|
||||
$sql = UpdateBuilder::getInstance($this->db, $this->conditionBuilder)
|
||||
->withTable($this->name)
|
||||
->withColumns(array_keys($data))
|
||||
->withSumColumns(array_keys($this->sumColumns))
|
||||
->build();
|
||||
|
||||
return $this->db->execute($sql, $values) !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert
|
||||
*
|
||||
* @access public
|
||||
* @param array $data
|
||||
* @return boolean
|
||||
*/
|
||||
public function insert(array $data)
|
||||
{
|
||||
return $this->db->getStatementHandler()
|
||||
->withSql(InsertBuilder::getInstance($this->db, $this->conditionBuilder)
|
||||
->withTable($this->name)
|
||||
->withColumns(array_keys($data))
|
||||
->build()
|
||||
)
|
||||
->withNamedParams($data)
|
||||
->execute() !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert a new row and return the ID of the primary key
|
||||
*
|
||||
* @access public
|
||||
* @param array $data
|
||||
* @return bool|int
|
||||
*/
|
||||
public function persist(array $data)
|
||||
{
|
||||
if ($this->insert($data)) {
|
||||
return $this->db->getLastId();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove
|
||||
*
|
||||
* @access public
|
||||
* @return boolean
|
||||
*/
|
||||
public function remove()
|
||||
{
|
||||
$sql = sprintf(
|
||||
'DELETE FROM %s %s',
|
||||
$this->db->escapeIdentifier($this->name),
|
||||
$this->conditionBuilder->build()
|
||||
);
|
||||
|
||||
$result = $this->db->execute($sql, $this->conditionBuilder->getValues());
|
||||
return $result->rowCount() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch all rows
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function findAll()
|
||||
{
|
||||
$rq = $this->db->execute($this->buildSelectQuery(), $this->conditionBuilder->getValues());
|
||||
$results = $rq->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
if (is_callable($this->callback) && ! empty($results)) {
|
||||
return call_user_func($this->callback, $results);
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find all with a single column
|
||||
*
|
||||
* @access public
|
||||
* @param string $column
|
||||
* @return mixed
|
||||
*/
|
||||
public function findAllByColumn($column)
|
||||
{
|
||||
$this->columns = array($column);
|
||||
$rq = $this->db->execute($this->buildSelectQuery(), $this->conditionBuilder->getValues());
|
||||
|
||||
return $rq->fetchAll(PDO::FETCH_COLUMN, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch one row
|
||||
*
|
||||
* @access public
|
||||
* @return array|null
|
||||
*/
|
||||
public function findOne()
|
||||
{
|
||||
$this->limit(1);
|
||||
$result = $this->findAll();
|
||||
|
||||
return isset($result[0]) ? $result[0] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch one column, first row
|
||||
*
|
||||
* @access public
|
||||
* @param string $column
|
||||
* @return string
|
||||
*/
|
||||
public function findOneColumn($column)
|
||||
{
|
||||
$this->limit(1);
|
||||
$this->columns = array($column);
|
||||
|
||||
return $this->db->execute($this->buildSelectQuery(), $this->conditionBuilder->getValues())->fetchColumn();
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a subquery with an alias
|
||||
*
|
||||
* @access public
|
||||
* @param string $sql
|
||||
* @param string $alias
|
||||
* @return $this
|
||||
*/
|
||||
public function subquery($sql, $alias)
|
||||
{
|
||||
$this->columns[] = '('.$sql.') AS '.$this->db->escapeIdentifier($alias);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Exists
|
||||
*
|
||||
* @access public
|
||||
* @return integer
|
||||
*/
|
||||
public function exists()
|
||||
{
|
||||
$sql = sprintf(
|
||||
'SELECT 1 FROM %s '.implode(' ', $this->joins).$this->conditionBuilder->build(),
|
||||
$this->db->escapeIdentifier($this->name)
|
||||
);
|
||||
|
||||
$rq = $this->db->execute($sql, $this->conditionBuilder->getValues());
|
||||
$result = $rq->fetchColumn();
|
||||
|
||||
return $result ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Count
|
||||
*
|
||||
* @access public
|
||||
* @return integer
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
$sql = sprintf(
|
||||
'SELECT COUNT(*) FROM %s '.implode(' ', $this->joins).$this->conditionBuilder->build().$this->sqlOrder.$this->sqlLimit.$this->sqlOffset,
|
||||
$this->db->escapeIdentifier($this->name)
|
||||
);
|
||||
|
||||
$rq = $this->db->execute($sql, $this->conditionBuilder->getValues());
|
||||
$result = $rq->fetchColumn();
|
||||
|
||||
return $result ? (int) $result : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sum
|
||||
*
|
||||
* @access public
|
||||
* @param string $column
|
||||
* @return float
|
||||
*/
|
||||
public function sum($column)
|
||||
{
|
||||
$sql = sprintf(
|
||||
'SELECT SUM(%s) FROM %s '.implode(' ', $this->joins).$this->conditionBuilder->build().$this->sqlOrder.$this->sqlLimit.$this->sqlOffset,
|
||||
$this->db->escapeIdentifier($column),
|
||||
$this->db->escapeIdentifier($this->name)
|
||||
);
|
||||
|
||||
$rq = $this->db->execute($sql, $this->conditionBuilder->getValues());
|
||||
$result = $rq->fetchColumn();
|
||||
|
||||
return $result ? (float) $result : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment column value
|
||||
*
|
||||
* @access public
|
||||
* @param string $column
|
||||
* @param string $value
|
||||
* @return boolean
|
||||
*/
|
||||
public function increment($column, $value)
|
||||
{
|
||||
$sql = sprintf(
|
||||
'UPDATE %s SET %s=%s+%d '.$this->conditionBuilder->build(),
|
||||
$this->db->escapeIdentifier($this->name),
|
||||
$this->db->escapeIdentifier($column),
|
||||
$this->db->escapeIdentifier($column),
|
||||
$value
|
||||
);
|
||||
|
||||
return $this->db->execute($sql, $this->conditionBuilder->getValues()) !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrement column value
|
||||
*
|
||||
* @access public
|
||||
* @param string $column
|
||||
* @param string $value
|
||||
* @return boolean
|
||||
*/
|
||||
public function decrement($column, $value)
|
||||
{
|
||||
$sql = sprintf(
|
||||
'UPDATE %s SET %s=%s-%d '.$this->conditionBuilder->build(),
|
||||
$this->db->escapeIdentifier($this->name),
|
||||
$this->db->escapeIdentifier($column),
|
||||
$this->db->escapeIdentifier($column),
|
||||
$value
|
||||
);
|
||||
|
||||
return $this->db->execute($sql, $this->conditionBuilder->getValues()) !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Left join
|
||||
*
|
||||
* @access public
|
||||
* @param string $table Join table
|
||||
* @param string $foreign_column Foreign key on the join table
|
||||
* @param string $local_column Local column
|
||||
* @param string $local_table Local table
|
||||
* @param string $alias Join table alias
|
||||
* @return $this
|
||||
*/
|
||||
public function join($table, $foreign_column, $local_column, $local_table = '', $alias = '')
|
||||
{
|
||||
$this->joins[] = sprintf(
|
||||
'LEFT JOIN %s ON %s=%s',
|
||||
$this->db->escapeIdentifier($table),
|
||||
$this->db->escapeIdentifier($alias ?: $table).'.'.$this->db->escapeIdentifier($foreign_column),
|
||||
$this->db->escapeIdentifier($local_table ?: $this->name).'.'.$this->db->escapeIdentifier($local_column)
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Left join
|
||||
*
|
||||
* @access public
|
||||
* @param string $table1
|
||||
* @param string $alias1
|
||||
* @param string $column1
|
||||
* @param string $table2
|
||||
* @param string $column2
|
||||
* @return $this
|
||||
*/
|
||||
public function left($table1, $alias1, $column1, $table2, $column2)
|
||||
{
|
||||
$this->joins[] = sprintf(
|
||||
'LEFT JOIN %s AS %s ON %s=%s',
|
||||
$this->db->escapeIdentifier($table1),
|
||||
$this->db->escapeIdentifier($alias1),
|
||||
$this->db->escapeIdentifier($alias1).'.'.$this->db->escapeIdentifier($column1),
|
||||
$this->db->escapeIdentifier($table2).'.'.$this->db->escapeIdentifier($column2)
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inner join
|
||||
*
|
||||
* @access public
|
||||
* @param string $table1
|
||||
* @param string $alias1
|
||||
* @param string $column1
|
||||
* @param string $table2
|
||||
* @param string $column2
|
||||
* @return $this
|
||||
*/
|
||||
public function inner($table1, $alias1, $column1, $table2, $column2)
|
||||
{
|
||||
$this->joins[] = sprintf(
|
||||
'JOIN %s AS %s ON %s=%s',
|
||||
$this->db->escapeIdentifier($table1),
|
||||
$this->db->escapeIdentifier($alias1),
|
||||
$this->db->escapeIdentifier($alias1).'.'.$this->db->escapeIdentifier($column1),
|
||||
$this->db->escapeIdentifier($table2).'.'.$this->db->escapeIdentifier($column2)
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Order by
|
||||
*
|
||||
* @access public
|
||||
* @param string $column Column name
|
||||
* @param string $order Direction ASC or DESC
|
||||
* @return $this
|
||||
*/
|
||||
public function orderBy($column, $order = self::SORT_ASC)
|
||||
{
|
||||
$order = strtoupper($order);
|
||||
$order = $order === self::SORT_ASC || $order === self::SORT_DESC ? $order : self::SORT_ASC;
|
||||
|
||||
if ($this->sqlOrder === '') {
|
||||
$this->sqlOrder = ' ORDER BY '.$this->db->escapeIdentifier($column).' '.$order;
|
||||
}
|
||||
else {
|
||||
$this->sqlOrder .= ', '.$this->db->escapeIdentifier($column).' '.$order;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ascending sort
|
||||
*
|
||||
* @access public
|
||||
* @param string $column
|
||||
* @return $this
|
||||
*/
|
||||
public function asc($column)
|
||||
{
|
||||
$this->orderBy($column, self::SORT_ASC);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Descending sort
|
||||
*
|
||||
* @access public
|
||||
* @param string $column
|
||||
* @return $this
|
||||
*/
|
||||
public function desc($column)
|
||||
{
|
||||
$this->orderBy($column, self::SORT_DESC);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Limit
|
||||
*
|
||||
* @access public
|
||||
* @param integer $value
|
||||
* @return $this
|
||||
*/
|
||||
public function limit($value)
|
||||
{
|
||||
if (! is_null($value)) {
|
||||
$this->sqlLimit = ' LIMIT '.(int) $value;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Offset
|
||||
*
|
||||
* @access public
|
||||
* @param integer $value
|
||||
* @return $this
|
||||
*/
|
||||
public function offset($value)
|
||||
{
|
||||
if (! is_null($value)) {
|
||||
$this->sqlOffset = ' OFFSET '.(int) $value;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Group by
|
||||
*
|
||||
* @access public
|
||||
* @return $this
|
||||
*/
|
||||
public function groupBy()
|
||||
{
|
||||
$this->groupBy = func_get_args();
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom select
|
||||
*
|
||||
* @access public
|
||||
* @param string $select
|
||||
* @return $this
|
||||
*/
|
||||
public function select($select)
|
||||
{
|
||||
$this->sqlSelect = $select;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the columns for the select
|
||||
*
|
||||
* @access public
|
||||
* @return $this
|
||||
*/
|
||||
public function columns()
|
||||
{
|
||||
$this->columns = func_get_args();
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sum column
|
||||
*
|
||||
* @access public
|
||||
* @param string $column
|
||||
* @param mixed $value
|
||||
* @return $this
|
||||
*/
|
||||
public function sumColumn($column, $value)
|
||||
{
|
||||
$this->sumColumns[$column] = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Distinct
|
||||
*
|
||||
* @access public
|
||||
* @return $this
|
||||
*/
|
||||
public function distinct()
|
||||
{
|
||||
$this->columns = func_get_args();
|
||||
$this->distinct = true;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add callback to alter the resultset
|
||||
*
|
||||
* @access public
|
||||
* @param Closure|array $callback
|
||||
* @return $this
|
||||
*/
|
||||
public function callback($callback)
|
||||
{
|
||||
$this->callback = $callback;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a select query
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function buildSelectQuery()
|
||||
{
|
||||
if (empty($this->sqlSelect)) {
|
||||
$this->columns = $this->db->escapeIdentifierList($this->columns);
|
||||
$this->sqlSelect = ($this->distinct ? 'DISTINCT ' : '').(empty($this->columns) ? '*' : implode(', ', $this->columns));
|
||||
}
|
||||
|
||||
$this->groupBy = $this->db->escapeIdentifierList($this->groupBy);
|
||||
|
||||
return trim(sprintf(
|
||||
'SELECT %s FROM %s %s %s %s %s %s %s',
|
||||
$this->sqlSelect,
|
||||
$this->db->escapeIdentifier($this->name),
|
||||
implode(' ', $this->joins),
|
||||
$this->conditionBuilder->build(),
|
||||
empty($this->groupBy) ? '' : 'GROUP BY '.implode(', ', $this->groupBy),
|
||||
$this->sqlOrder,
|
||||
$this->sqlLimit,
|
||||
$this->sqlOffset
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic method for sql conditions
|
||||
*
|
||||
* @access public
|
||||
* @param string $name
|
||||
* @param array $arguments
|
||||
* @return $this
|
||||
*/
|
||||
public function __call($name, array $arguments)
|
||||
{
|
||||
call_user_func_array(array($this->conditionBuilder, $name), $arguments);
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
93
vendor/fguillot/picodb/lib/PicoDb/UrlParser.php
vendored
Normal file
93
vendor/fguillot/picodb/lib/PicoDb/UrlParser.php
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
namespace PicoDb;
|
||||
|
||||
/**
|
||||
* Class UrlParser
|
||||
*
|
||||
* @package PicoDb
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class UrlParser
|
||||
{
|
||||
/**
|
||||
* URL
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
private $url;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @access public
|
||||
* @param string $environmentVariable
|
||||
*/
|
||||
public function __construct($environmentVariable = 'DATABASE_URL')
|
||||
{
|
||||
$this->url = getenv($environmentVariable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get object instance
|
||||
*
|
||||
* @access public
|
||||
* @param string $environmentVariable
|
||||
* @return static
|
||||
*/
|
||||
public static function getInstance($environmentVariable = 'DATABASE_URL')
|
||||
{
|
||||
return new static($environmentVariable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the variable is defined
|
||||
*
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function isEnvironmentVariableDefined()
|
||||
{
|
||||
return ! empty($this->url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get settings from URL
|
||||
*
|
||||
* @access public
|
||||
* @param string $url
|
||||
* @return array
|
||||
*/
|
||||
public function getSettings($url = '')
|
||||
{
|
||||
$url = $url ?: $this->url;
|
||||
$components = parse_url($url);
|
||||
|
||||
if ($components === false) {
|
||||
return array();
|
||||
}
|
||||
|
||||
return array(
|
||||
'driver' => $this->getUrlComponent($components, 'scheme'),
|
||||
'username' => $this->getUrlComponent($components, 'user'),
|
||||
'password' => $this->getUrlComponent($components, 'pass'),
|
||||
'hostname' => $this->getUrlComponent($components, 'host'),
|
||||
'port' => $this->getUrlComponent($components, 'port'),
|
||||
'database' => ltrim($this->getUrlComponent($components, 'path'), '/'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get URL component
|
||||
*
|
||||
* @access private
|
||||
* @param array $components
|
||||
* @param string $component
|
||||
* @return mixed|null
|
||||
*/
|
||||
private function getUrlComponent(array $components, $component)
|
||||
{
|
||||
return ! empty($components[$component]) ? $components[$component] : null;
|
||||
}
|
||||
}
|
||||
21
vendor/fguillot/simple-queue/LICENSE
vendored
Normal file
21
vendor/fguillot/simple-queue/LICENSE
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Frédéric Guillot
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
138
vendor/fguillot/simple-queue/src/Adapter/AmqpQueueAdapter.php
vendored
Normal file
138
vendor/fguillot/simple-queue/src/Adapter/AmqpQueueAdapter.php
vendored
Normal file
@@ -0,0 +1,138 @@
|
||||
<?php
|
||||
|
||||
namespace SimpleQueue\Adapter;
|
||||
|
||||
use DateTime;
|
||||
use PhpAmqpLib\Channel\AMQPChannel;
|
||||
use PhpAmqpLib\Message\AMQPMessage;
|
||||
use PhpAmqpLib\Wire\AMQPTable;
|
||||
use SimpleQueue\Job;
|
||||
use SimpleQueue\QueueAdapterInterface;
|
||||
|
||||
/**
|
||||
* Class AmqpQueueAdapter
|
||||
*
|
||||
* @package SimpleQueue\Adapter
|
||||
*/
|
||||
class AmqpQueueAdapter implements QueueAdapterInterface
|
||||
{
|
||||
/**
|
||||
* @var AMQPChannel
|
||||
*/
|
||||
protected $channel;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $exchange = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $queue = '';
|
||||
|
||||
/**
|
||||
* AmqpQueueAdapter constructor.
|
||||
*
|
||||
* @param AMQPChannel $channel
|
||||
* @param string $queue
|
||||
* @param string $exchange
|
||||
*/
|
||||
public function __construct(AMQPChannel $channel, $queue, $exchange)
|
||||
{
|
||||
$this->channel = $channel;
|
||||
$this->exchange = $exchange;
|
||||
$this->queue = $queue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a job
|
||||
*
|
||||
* @access public
|
||||
* @param Job $job
|
||||
* @return $this
|
||||
*/
|
||||
public function push(Job $job)
|
||||
{
|
||||
$message = new AMQPMessage($job->serialize(), array('content_type' => 'text/plain'));
|
||||
$this->channel->basic_publish($message, $this->exchange);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule a job in the future
|
||||
*
|
||||
* @access public
|
||||
* @param Job $job
|
||||
* @param DateTime $dateTime
|
||||
* @return $this
|
||||
*/
|
||||
public function schedule(Job $job, DateTime $dateTime)
|
||||
{
|
||||
$now = new DateTime();
|
||||
$when = clone($dateTime);
|
||||
$delay = $when->getTimestamp() - $now->getTimestamp();
|
||||
|
||||
$message = new AMQPMessage($job->serialize(), array('delivery_mode' => 2));
|
||||
$message->set('application_headers', new AMQPTable(array('x-delay' => $delay)));
|
||||
|
||||
$this->channel->basic_publish($message, $this->exchange);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait and get job from a queue
|
||||
*
|
||||
* @access public
|
||||
* @return Job|null
|
||||
*/
|
||||
public function pull()
|
||||
{
|
||||
$message = null;
|
||||
|
||||
$this->channel->basic_consume($this->queue, 'test', false, false, false, false, function ($msg) use (&$message) {
|
||||
$message = $msg;
|
||||
$message->delivery_info['channel']->basic_cancel($message->delivery_info['consumer_tag']);
|
||||
});
|
||||
|
||||
while (count($this->channel->callbacks)) {
|
||||
$this->channel->wait();
|
||||
}
|
||||
|
||||
if ($message === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$job = new Job();
|
||||
$job->setId($message->get('delivery_tag'));
|
||||
$job->unserialize($message->getBody());
|
||||
|
||||
return $job;
|
||||
}
|
||||
|
||||
/**
|
||||
* Acknowledge a job
|
||||
*
|
||||
* @access public
|
||||
* @param Job $job
|
||||
* @return $this
|
||||
*/
|
||||
public function completed(Job $job)
|
||||
{
|
||||
$this->channel->basic_ack($job->getId());
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark a job as failed
|
||||
*
|
||||
* @access public
|
||||
* @param Job $job
|
||||
* @return $this
|
||||
*/
|
||||
public function failed(Job $job)
|
||||
{
|
||||
$this->channel->basic_nack($job->getId());
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
150
vendor/fguillot/simple-queue/src/Adapter/AwsSqsQueueAdapter.php
vendored
Normal file
150
vendor/fguillot/simple-queue/src/Adapter/AwsSqsQueueAdapter.php
vendored
Normal file
@@ -0,0 +1,150 @@
|
||||
<?php
|
||||
|
||||
namespace SimpleQueue\Adapter;
|
||||
|
||||
use Aws\Sqs\SqsClient;
|
||||
use SimpleQueue\Job;
|
||||
use SimpleQueue\QueueAdapterInterface;
|
||||
use DateTime;
|
||||
|
||||
/**
|
||||
* Class AwsSqsQueueAdapter
|
||||
*
|
||||
* @package SimpleQueue\Adapter
|
||||
* @author George Webb <george@webb.uno>
|
||||
*/
|
||||
class AwsSqsQueueAdapter implements QueueAdapterInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $queueName;
|
||||
|
||||
/**
|
||||
* @var SqsClient
|
||||
*/
|
||||
private $sqsClient;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sqsUrl;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $config;
|
||||
|
||||
/**
|
||||
* AwsSqsQueueAdapter constructor.
|
||||
*
|
||||
* @param string $queueName The name of the SQS queue
|
||||
* @param SqsClient $sqsClient An SQS client
|
||||
* @param array $config Array of config values
|
||||
*/
|
||||
public function __construct($queueName, SqsClient $sqsClient, $config = array())
|
||||
{
|
||||
$this->queueName = $queueName;
|
||||
$this->sqsClient = $sqsClient;
|
||||
$this->sqsUrl = $this->sqsClient->getQueueUrl(array('QueueName' => $this->queueName))->get('QueueUrl');
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a job
|
||||
*
|
||||
* @access public
|
||||
* @param Job $job
|
||||
* @return $this
|
||||
*/
|
||||
public function push(Job $job)
|
||||
{
|
||||
$this->sqsClient->sendMessage(array(
|
||||
'QueueUrl' => $this->sqsUrl,
|
||||
'MessageBody' => $job->serialize()
|
||||
));
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule a job in the future
|
||||
*
|
||||
* @access public
|
||||
* @param Job $job
|
||||
* @param DateTime $dateTime
|
||||
* @return $this
|
||||
*/
|
||||
public function schedule(Job $job, DateTime $dateTime)
|
||||
{
|
||||
$now = new DateTime();
|
||||
$when = clone($dateTime);
|
||||
$delay = $when->getTimestamp() - $now->getTimestamp();
|
||||
|
||||
$this->sqsClient->sendMessage(array(
|
||||
'QueueUrl' => $this->sqsUrl,
|
||||
'MessageBody' => $job->serialize(),
|
||||
'VisibilityTimeout' => $delay
|
||||
));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait and get job from a queue
|
||||
*
|
||||
* @access public
|
||||
* @return Job|null
|
||||
*/
|
||||
public function pull()
|
||||
{
|
||||
$result = $this->sqsClient->receiveMessage(array(
|
||||
'QueueUrl' => $this->sqsUrl,
|
||||
'WaitTimeSeconds' => empty($this->config['LongPollingTime']) ? 0 : (int) $this->config['LongPollingTime']
|
||||
));
|
||||
|
||||
if ($result['Messages'] == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$resultMessage = array_pop($result['Messages']);
|
||||
|
||||
$job = new Job();
|
||||
$job->setId($resultMessage['ReceiptHandle']);
|
||||
$job->unserialize($resultMessage['Body']);
|
||||
|
||||
return $job;
|
||||
}
|
||||
|
||||
/**
|
||||
* Acknowledge a job
|
||||
*
|
||||
* @access public
|
||||
* @param Job $job
|
||||
* @return $this
|
||||
*/
|
||||
public function completed(Job $job)
|
||||
{
|
||||
$this->sqsClient->deleteMessage(array(
|
||||
'QueueUrl' => $this->sqsUrl,
|
||||
'ReceiptHandle' => $job->getId()
|
||||
));
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark a job as failed
|
||||
*
|
||||
* @access public
|
||||
* @param Job $job
|
||||
* @return $this
|
||||
*/
|
||||
public function failed(Job $job)
|
||||
{
|
||||
$this->sqsClient->changeMessageVisibility(array(
|
||||
'QueueUrl' => $this->sqsUrl,
|
||||
'ReceiptHandle' => $job->getId(),
|
||||
'VisibilityTimeout' => 0
|
||||
));
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
120
vendor/fguillot/simple-queue/src/Adapter/BeanstalkQueueAdapter.php
vendored
Normal file
120
vendor/fguillot/simple-queue/src/Adapter/BeanstalkQueueAdapter.php
vendored
Normal file
@@ -0,0 +1,120 @@
|
||||
<?php
|
||||
|
||||
namespace SimpleQueue\Adapter;
|
||||
|
||||
use DateTime;
|
||||
use Pheanstalk\Job as BeanstalkJob;
|
||||
use Pheanstalk\Pheanstalk;
|
||||
use Pheanstalk\PheanstalkInterface;
|
||||
use SimpleQueue\Job;
|
||||
use SimpleQueue\QueueAdapterInterface;
|
||||
|
||||
/**
|
||||
* Class BeanstalkQueueAdapter
|
||||
*
|
||||
* @package SimpleQueue\Adapter
|
||||
*/
|
||||
class BeanstalkQueueAdapter implements QueueAdapterInterface
|
||||
{
|
||||
/**
|
||||
* @var PheanstalkInterface
|
||||
*/
|
||||
protected $beanstalk;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $queueName = '';
|
||||
|
||||
/**
|
||||
* BeanstalkQueueAdapter constructor.
|
||||
*
|
||||
* @param PheanstalkInterface $beanstalk
|
||||
* @param string $queueName
|
||||
*/
|
||||
public function __construct(PheanstalkInterface $beanstalk, $queueName)
|
||||
{
|
||||
$this->beanstalk = $beanstalk;
|
||||
$this->queueName = $queueName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a job
|
||||
*
|
||||
* @access public
|
||||
* @param Job $job
|
||||
* @return $this
|
||||
*/
|
||||
public function push(Job $job)
|
||||
{
|
||||
$this->beanstalk->putInTube($this->queueName, $job->serialize());
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule a job in the future
|
||||
*
|
||||
* @access public
|
||||
* @param Job $job
|
||||
* @param DateTime $dateTime
|
||||
* @return $this
|
||||
*/
|
||||
public function schedule(Job $job, DateTime $dateTime)
|
||||
{
|
||||
$now = new DateTime();
|
||||
$when = clone($dateTime);
|
||||
$delay = $when->getTimestamp() - $now->getTimestamp();
|
||||
|
||||
$this->beanstalk->putInTube($this->queueName, $job->serialize(), Pheanstalk::DEFAULT_PRIORITY, $delay);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait and get job from a queue
|
||||
*
|
||||
* @access public
|
||||
* @return Job|null
|
||||
*/
|
||||
public function pull()
|
||||
{
|
||||
$beanstalkJob = $this->beanstalk->reserveFromTube($this->queueName);
|
||||
|
||||
if ($beanstalkJob === false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$job = new Job();
|
||||
$job->setId($beanstalkJob->getId());
|
||||
$job->unserialize($beanstalkJob->getData());
|
||||
|
||||
return $job;
|
||||
}
|
||||
|
||||
/**
|
||||
* Acknowledge a job
|
||||
*
|
||||
* @access public
|
||||
* @param Job $job
|
||||
* @return $this
|
||||
*/
|
||||
public function completed(Job $job)
|
||||
{
|
||||
$beanstalkJob = new BeanstalkJob($job->getId(), $job->serialize());
|
||||
$this->beanstalk->delete($beanstalkJob);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark a job as failed
|
||||
*
|
||||
* @access public
|
||||
* @param Job $job
|
||||
* @return $this
|
||||
*/
|
||||
public function failed(Job $job)
|
||||
{
|
||||
$beanstalkJob = new BeanstalkJob($job->getId(), $job->serialize());
|
||||
$this->beanstalk->bury($beanstalkJob);
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
109
vendor/fguillot/simple-queue/src/Adapter/DisqueQueueAdapter.php
vendored
Normal file
109
vendor/fguillot/simple-queue/src/Adapter/DisqueQueueAdapter.php
vendored
Normal file
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
|
||||
namespace SimpleQueue\Adapter;
|
||||
|
||||
use DateTime;
|
||||
use Disque\Client as DisqueClient;
|
||||
use Disque\Queue\Job as DisqueJob;
|
||||
use SimpleQueue\Job;
|
||||
use SimpleQueue\QueueAdapterInterface;
|
||||
|
||||
/**
|
||||
* Class DisqueQueueAdapter
|
||||
*
|
||||
* @package SimpleQueue\Adapter
|
||||
*/
|
||||
class DisqueQueueAdapter implements QueueAdapterInterface
|
||||
{
|
||||
/**
|
||||
* @var DisqueClient
|
||||
*/
|
||||
protected $disque;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $queueName;
|
||||
|
||||
/**
|
||||
* DisqueQueueAdapter constructor.
|
||||
*
|
||||
* @param DisqueClient $disque
|
||||
* @param string $queueName
|
||||
*/
|
||||
public function __construct(DisqueClient $disque, $queueName)
|
||||
{
|
||||
$this->disque = $disque;
|
||||
$this->queueName = $queueName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a job
|
||||
*
|
||||
* @access public
|
||||
* @param Job $job
|
||||
* @return $this
|
||||
*/
|
||||
public function push(Job $job)
|
||||
{
|
||||
$this->disque->queue($this->queueName)->push(new DisqueJob($job->getBody()));
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule a job in the future
|
||||
*
|
||||
* @access public
|
||||
* @param Job $job
|
||||
* @param DateTime $dateTime
|
||||
* @return $this
|
||||
*/
|
||||
public function schedule(Job $job, DateTime $dateTime)
|
||||
{
|
||||
$this->disque->queue($this->queueName)->schedule(new DisqueJob($job->serialize()), $dateTime);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait and get job from a queue
|
||||
*
|
||||
* @access public
|
||||
* @return Job|null
|
||||
*/
|
||||
public function pull()
|
||||
{
|
||||
$disqueJob = $this->disque->queue($this->queueName)->pull();
|
||||
|
||||
if ($disqueJob === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Job($disqueJob->getBody(), $disqueJob->getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Acknowledge a job
|
||||
*
|
||||
* @access public
|
||||
* @param Job $job
|
||||
* @return $this
|
||||
*/
|
||||
public function completed(Job $job)
|
||||
{
|
||||
$this->disque->queue($this->queueName)->processed(new DisqueJob($job->getBody(), $job->getId()));
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark a job as failed
|
||||
*
|
||||
* @access public
|
||||
* @param Job $job
|
||||
* @return $this
|
||||
*/
|
||||
public function failed(Job $job)
|
||||
{
|
||||
$this->disque->queue($this->queueName)->failed(new DisqueJob($job->getBody(), $job->getId()));
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
100
vendor/fguillot/simple-queue/src/Adapter/MemoryQueueAdapter.php
vendored
Normal file
100
vendor/fguillot/simple-queue/src/Adapter/MemoryQueueAdapter.php
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
namespace SimpleQueue\Adapter;
|
||||
|
||||
use DateTime;
|
||||
use Exception;
|
||||
use SimpleQueue\Exception\NotSupportedException;
|
||||
use SimpleQueue\QueueAdapterInterface;
|
||||
use SimpleQueue\Job;
|
||||
use SplQueue;
|
||||
|
||||
/**
|
||||
* Class MemoryAdapter
|
||||
*
|
||||
* @package SimpleQueue\Adapter
|
||||
*/
|
||||
class MemoryQueueAdapter implements QueueAdapterInterface
|
||||
{
|
||||
/**
|
||||
* @var SplQueue
|
||||
*/
|
||||
protected $queue;
|
||||
|
||||
/**
|
||||
* MemoryAdapter constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->queue = new SplQueue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a job
|
||||
*
|
||||
* @access public
|
||||
* @param Job $job
|
||||
* @return $this
|
||||
*/
|
||||
public function push(Job $job)
|
||||
{
|
||||
$this->queue->enqueue($job->serialize());
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule a job in the future
|
||||
*
|
||||
* @access public
|
||||
* @param Job $job
|
||||
* @param DateTime $dateTime
|
||||
* @return bool
|
||||
* @throws NotSupportedException
|
||||
*/
|
||||
public function schedule(Job $job, DateTime $dateTime)
|
||||
{
|
||||
throw new NotSupportedException('Job delay is not supported by MemoryQueue');
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait and get job from a queue
|
||||
*
|
||||
* @access public
|
||||
* @return Job|null
|
||||
*/
|
||||
public function pull()
|
||||
{
|
||||
try {
|
||||
$job = new Job();
|
||||
$payload = $this->queue->dequeue();
|
||||
return $job->unserialize($payload);
|
||||
} catch (Exception $e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Acknowledge a job
|
||||
*
|
||||
* @access public
|
||||
* @param Job $job
|
||||
* @return $this
|
||||
*/
|
||||
public function completed(Job $job)
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark a job as failed
|
||||
*
|
||||
* @access public
|
||||
* @param Job $job
|
||||
* @return $this
|
||||
*/
|
||||
public function failed(Job $job)
|
||||
{
|
||||
$this->queue->enqueue($job->serialize());
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
14
vendor/fguillot/simple-queue/src/Exception/NotSupportedException.php
vendored
Normal file
14
vendor/fguillot/simple-queue/src/Exception/NotSupportedException.php
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace SimpleQueue\Exception;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Class NotSupportedException
|
||||
*
|
||||
* @package SimpleQueue\Exception
|
||||
*/
|
||||
class NotSupportedException extends Exception
|
||||
{
|
||||
}
|
||||
98
vendor/fguillot/simple-queue/src/Job.php
vendored
Normal file
98
vendor/fguillot/simple-queue/src/Job.php
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
namespace SimpleQueue;
|
||||
|
||||
/**
|
||||
* Class Job
|
||||
*
|
||||
* @package SimpleQueue
|
||||
*/
|
||||
class Job
|
||||
{
|
||||
protected $id;
|
||||
protected $body;
|
||||
|
||||
/**
|
||||
* Job constructor.
|
||||
*
|
||||
* @param null $body
|
||||
* @param null $id
|
||||
*/
|
||||
public function __construct($body = null, $id = null)
|
||||
{
|
||||
$this->body = $body;
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unserialize a payload
|
||||
*
|
||||
* @param string $payload
|
||||
* @return $this
|
||||
*/
|
||||
public function unserialize($payload)
|
||||
{
|
||||
$this->body = json_decode($payload, true);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize the body
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function serialize()
|
||||
{
|
||||
return json_encode($this->body);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set body
|
||||
*
|
||||
* @param mixed $body
|
||||
* @return Job
|
||||
*/
|
||||
public function setBody($body)
|
||||
{
|
||||
$this->body = $body;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get body
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getBody()
|
||||
{
|
||||
return $this->body;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set job ID
|
||||
*
|
||||
* @param mixed $jobId
|
||||
* @return Job
|
||||
*/
|
||||
public function setId($jobId)
|
||||
{
|
||||
$this->id = $jobId;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get job ID
|
||||
* @return mixed
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute job
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
}
|
||||
}
|
||||
92
vendor/fguillot/simple-queue/src/Queue.php
vendored
Normal file
92
vendor/fguillot/simple-queue/src/Queue.php
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
namespace SimpleQueue;
|
||||
|
||||
use DateTime;
|
||||
|
||||
/**
|
||||
* Class Queue
|
||||
*
|
||||
* @package SimpleQueue
|
||||
*/
|
||||
class Queue implements QueueAdapterInterface
|
||||
{
|
||||
/**
|
||||
* @var QueueAdapterInterface
|
||||
*/
|
||||
protected $queueAdapter;
|
||||
|
||||
/**
|
||||
* Queue constructor.
|
||||
*
|
||||
* @param QueueAdapterInterface $queueAdapter
|
||||
*/
|
||||
public function __construct(QueueAdapterInterface $queueAdapter)
|
||||
{
|
||||
$this->queueAdapter = $queueAdapter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a job
|
||||
*
|
||||
* @access public
|
||||
* @param Job $job
|
||||
* @return $this
|
||||
*/
|
||||
public function push(Job $job)
|
||||
{
|
||||
$this->queueAdapter->push($job);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule a job in the future
|
||||
*
|
||||
* @access public
|
||||
* @param Job $job
|
||||
* @param DateTime $dateTime
|
||||
* @return $this
|
||||
*/
|
||||
public function schedule(Job $job, DateTime $dateTime)
|
||||
{
|
||||
$this->queueAdapter->schedule($job, $dateTime);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait and get job from a queue
|
||||
*
|
||||
* @access public
|
||||
* @return Job|null
|
||||
*/
|
||||
public function pull()
|
||||
{
|
||||
return $this->queueAdapter->pull();
|
||||
}
|
||||
|
||||
/**
|
||||
* Acknowledge a job
|
||||
*
|
||||
* @access public
|
||||
* @param Job $job
|
||||
* @return $this
|
||||
*/
|
||||
public function completed(Job $job)
|
||||
{
|
||||
$this->queueAdapter->completed($job);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark a job as failed
|
||||
*
|
||||
* @access public
|
||||
* @param Job $job
|
||||
* @return $this
|
||||
*/
|
||||
public function failed(Job $job)
|
||||
{
|
||||
$this->queueAdapter->failed($job);
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
58
vendor/fguillot/simple-queue/src/QueueAdapterInterface.php
vendored
Normal file
58
vendor/fguillot/simple-queue/src/QueueAdapterInterface.php
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
namespace SimpleQueue;
|
||||
|
||||
use DateTime;
|
||||
|
||||
/**
|
||||
* Interface AdapterInterface
|
||||
*
|
||||
* @package SimpleQueue\Adapter
|
||||
*/
|
||||
interface QueueAdapterInterface
|
||||
{
|
||||
/**
|
||||
* Send a job
|
||||
*
|
||||
* @access public
|
||||
* @param Job $job
|
||||
* @return $this
|
||||
*/
|
||||
public function push(Job $job);
|
||||
|
||||
/**
|
||||
* Schedule a job in the future
|
||||
*
|
||||
* @access public
|
||||
* @param Job $job
|
||||
* @param DateTime $dateTime
|
||||
* @return $this
|
||||
*/
|
||||
public function schedule(Job $job, DateTime $dateTime);
|
||||
|
||||
/**
|
||||
* Wait and get job from a queue
|
||||
*
|
||||
* @access public
|
||||
* @return Job|null
|
||||
*/
|
||||
public function pull();
|
||||
|
||||
/**
|
||||
* Acknowledge a job
|
||||
*
|
||||
* @access public
|
||||
* @param Job $job
|
||||
* @return $this
|
||||
*/
|
||||
public function completed(Job $job);
|
||||
|
||||
/**
|
||||
* Mark a job as failed
|
||||
*
|
||||
* @access public
|
||||
* @param Job $job
|
||||
* @return $this
|
||||
*/
|
||||
public function failed(Job $job);
|
||||
}
|
||||
21
vendor/fguillot/simple-validator/LICENSE
vendored
Normal file
21
vendor/fguillot/simple-validator/LICENSE
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Frederic Guillot
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
44
vendor/fguillot/simple-validator/src/SimpleValidator/Validator.php
vendored
Normal file
44
vendor/fguillot/simple-validator/src/SimpleValidator/Validator.php
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace SimpleValidator;
|
||||
|
||||
class Validator
|
||||
{
|
||||
private $data = array();
|
||||
private $errors = array();
|
||||
private $validators = array();
|
||||
|
||||
public function __construct(array $data, array $validators)
|
||||
{
|
||||
$this->data = $data;
|
||||
$this->validators = $validators;
|
||||
}
|
||||
|
||||
public function execute()
|
||||
{
|
||||
$result = true;
|
||||
|
||||
foreach ($this->validators as $validator) {
|
||||
if (! $validator->execute($this->data)) {
|
||||
$this->addError($validator->getField(), $validator->getErrorMessage());
|
||||
$result = false;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function addError($field, $message)
|
||||
{
|
||||
if (! isset($this->errors[$field])) {
|
||||
$this->errors[$field] = array();
|
||||
}
|
||||
|
||||
$this->errors[$field][] = $message;
|
||||
}
|
||||
|
||||
public function getErrors()
|
||||
{
|
||||
return $this->errors;
|
||||
}
|
||||
}
|
||||
15
vendor/fguillot/simple-validator/src/SimpleValidator/Validators/Alpha.php
vendored
Normal file
15
vendor/fguillot/simple-validator/src/SimpleValidator/Validators/Alpha.php
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace SimpleValidator\Validators;
|
||||
|
||||
class Alpha extends Base
|
||||
{
|
||||
public function execute(array $data)
|
||||
{
|
||||
if ($this->isFieldNotEmpty($data)) {
|
||||
return ctype_alpha($data[$this->field]);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
15
vendor/fguillot/simple-validator/src/SimpleValidator/Validators/AlphaNumeric.php
vendored
Normal file
15
vendor/fguillot/simple-validator/src/SimpleValidator/Validators/AlphaNumeric.php
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace SimpleValidator\Validators;
|
||||
|
||||
class AlphaNumeric extends Base
|
||||
{
|
||||
public function execute(array $data)
|
||||
{
|
||||
if ($this->isFieldNotEmpty($data)) {
|
||||
return ctype_alnum($data[$this->field]);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
37
vendor/fguillot/simple-validator/src/SimpleValidator/Validators/Base.php
vendored
Normal file
37
vendor/fguillot/simple-validator/src/SimpleValidator/Validators/Base.php
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace SimpleValidator\Validators;
|
||||
|
||||
abstract class Base
|
||||
{
|
||||
protected $field = '';
|
||||
protected $error_message = '';
|
||||
protected $data = array();
|
||||
|
||||
abstract public function execute(array $data);
|
||||
|
||||
public function __construct($field, $error_message)
|
||||
{
|
||||
$this->field = $field;
|
||||
$this->error_message = $error_message;
|
||||
}
|
||||
|
||||
public function getErrorMessage()
|
||||
{
|
||||
return $this->error_message;
|
||||
}
|
||||
|
||||
public function getField()
|
||||
{
|
||||
if (is_array($this->field)) {
|
||||
return $this->field[0];
|
||||
}
|
||||
|
||||
return $this->field;
|
||||
}
|
||||
|
||||
public function isFieldNotEmpty(array $data)
|
||||
{
|
||||
return isset($data[$this->field]) && $data[$this->field] !== '';
|
||||
}
|
||||
}
|
||||
45
vendor/fguillot/simple-validator/src/SimpleValidator/Validators/Date.php
vendored
Normal file
45
vendor/fguillot/simple-validator/src/SimpleValidator/Validators/Date.php
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace SimpleValidator\Validators;
|
||||
|
||||
use DateTime;
|
||||
|
||||
class Date extends Base
|
||||
{
|
||||
private $formats = array();
|
||||
|
||||
public function __construct($field, $error_message, array $formats)
|
||||
{
|
||||
parent::__construct($field, $error_message);
|
||||
$this->formats = $formats;
|
||||
}
|
||||
|
||||
public function execute(array $data)
|
||||
{
|
||||
if ($this->isFieldNotEmpty($data)) {
|
||||
foreach ($this->formats as $format) {
|
||||
if ($this->isValidDate($data[$this->field], $format)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function isValidDate($value, $format)
|
||||
{
|
||||
$date = DateTime::createFromFormat($format, $value);
|
||||
|
||||
if ($date !== false) {
|
||||
$errors = DateTime::getLastErrors();
|
||||
if ($errors['error_count'] === 0 && $errors['warning_count'] === 0) {
|
||||
return $date->getTimestamp() > 0;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
67
vendor/fguillot/simple-validator/src/SimpleValidator/Validators/Email.php
vendored
Normal file
67
vendor/fguillot/simple-validator/src/SimpleValidator/Validators/Email.php
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
namespace SimpleValidator\Validators;
|
||||
|
||||
class Email extends Base
|
||||
{
|
||||
public function execute(array $data)
|
||||
{
|
||||
if ($this->isFieldNotEmpty($data)) {
|
||||
|
||||
// I use the same validation method as Firefox
|
||||
// http://hg.mozilla.org/mozilla-central/file/cf5da681d577/content/html/content/src/nsHTMLInputElement.cpp#l3967
|
||||
|
||||
$value = $data[$this->field];
|
||||
$length = strlen($value);
|
||||
|
||||
// If the email address begins with a '@' or ends with a '.',
|
||||
// we know it's invalid.
|
||||
if ($value[0] === '@' || $value[$length - 1] === '.') {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check the username
|
||||
for ($i = 0; $i < $length && $value[$i] !== '@'; ++$i) {
|
||||
|
||||
$c = $value[$i];
|
||||
|
||||
if (! (ctype_alnum($c) || $c === '.' || $c === '!' || $c === '#' || $c === '$' ||
|
||||
$c === '%' || $c === '&' || $c === '\'' || $c === '*' || $c === '+' ||
|
||||
$c === '-' || $c === '/' || $c === '=' || $c === '?' || $c === '^' ||
|
||||
$c === '_' || $c === '`' || $c === '{' || $c === '|' || $c === '}' ||
|
||||
$c === '~')) {
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// There is no domain name (or it's one-character long),
|
||||
// that's not a valid email address.
|
||||
if (++$i >= $length) return false;
|
||||
if (($i + 1) === $length) return false;
|
||||
|
||||
// The domain name can't begin with a dot.
|
||||
if ($value[$i] === '.') return false;
|
||||
|
||||
// Parsing the domain name.
|
||||
for (; $i < $length; ++$i) {
|
||||
|
||||
$c = $value[$i];
|
||||
|
||||
if ($c === '.') {
|
||||
|
||||
// A dot can't follow a dot.
|
||||
if ($value[$i - 1] === '.') return false;
|
||||
}
|
||||
elseif (! (ctype_alnum($c) || $c === '-')) {
|
||||
|
||||
// The domain characters have to be in this list to be valid.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
27
vendor/fguillot/simple-validator/src/SimpleValidator/Validators/Equals.php
vendored
Normal file
27
vendor/fguillot/simple-validator/src/SimpleValidator/Validators/Equals.php
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace SimpleValidator\Validators;
|
||||
|
||||
class Equals extends Base
|
||||
{
|
||||
private $field2;
|
||||
|
||||
public function __construct($field1, $field2, $error_message)
|
||||
{
|
||||
parent::__construct($field1, $error_message);
|
||||
$this->field2 = $field2;
|
||||
}
|
||||
|
||||
public function execute(array $data)
|
||||
{
|
||||
if ($this->isFieldNotEmpty($data)) {
|
||||
if (! isset($data[$this->field2])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $data[$this->field] === $data[$this->field2];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
38
vendor/fguillot/simple-validator/src/SimpleValidator/Validators/Exists.php
vendored
Normal file
38
vendor/fguillot/simple-validator/src/SimpleValidator/Validators/Exists.php
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace SimpleValidator\Validators;
|
||||
|
||||
use PDO;
|
||||
|
||||
class Exists extends Base
|
||||
{
|
||||
private $pdo;
|
||||
private $key;
|
||||
private $table;
|
||||
|
||||
public function __construct($field, $error_message, PDO $pdo, $table, $key = '')
|
||||
{
|
||||
parent::__construct($field, $error_message);
|
||||
|
||||
$this->pdo = $pdo;
|
||||
$this->table = $table;
|
||||
$this->key = $key;
|
||||
}
|
||||
|
||||
|
||||
public function execute(array $data)
|
||||
{
|
||||
if (! $this->isFieldNotEmpty($data)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($this->key === '') {
|
||||
$this->key = $this->field;
|
||||
}
|
||||
|
||||
$rq = $this->pdo->prepare('SELECT 1 FROM '.$this->table.' WHERE '.$this->key.'=?');
|
||||
$rq->execute(array($data[$this->field]));
|
||||
|
||||
return $rq->fetchColumn() == 1;
|
||||
}
|
||||
}
|
||||
23
vendor/fguillot/simple-validator/src/SimpleValidator/Validators/GreaterThan.php
vendored
Normal file
23
vendor/fguillot/simple-validator/src/SimpleValidator/Validators/GreaterThan.php
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace SimpleValidator\Validators;
|
||||
|
||||
class GreaterThan extends Base
|
||||
{
|
||||
private $min;
|
||||
|
||||
public function __construct($field, $error_message, $min)
|
||||
{
|
||||
parent::__construct($field, $error_message);
|
||||
$this->min = $min;
|
||||
}
|
||||
|
||||
public function execute(array $data)
|
||||
{
|
||||
if ($this->isFieldNotEmpty($data)) {
|
||||
return $data[$this->field] > $this->min;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
23
vendor/fguillot/simple-validator/src/SimpleValidator/Validators/InArray.php
vendored
Normal file
23
vendor/fguillot/simple-validator/src/SimpleValidator/Validators/InArray.php
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace SimpleValidator\Validators;
|
||||
|
||||
class InArray extends Base
|
||||
{
|
||||
protected $array;
|
||||
|
||||
public function __construct($field, array $array, $error_message)
|
||||
{
|
||||
parent::__construct($field, $error_message);
|
||||
$this->array = $array;
|
||||
}
|
||||
|
||||
public function execute(array $data)
|
||||
{
|
||||
if ($this->isFieldNotEmpty($data)) {
|
||||
return in_array($data[$this->field], $this->array);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
25
vendor/fguillot/simple-validator/src/SimpleValidator/Validators/Integer.php
vendored
Normal file
25
vendor/fguillot/simple-validator/src/SimpleValidator/Validators/Integer.php
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace SimpleValidator\Validators;
|
||||
|
||||
class Integer extends Base
|
||||
{
|
||||
public function execute(array $data)
|
||||
{
|
||||
if ($this->isFieldNotEmpty($data)) {
|
||||
if (is_string($data[$this->field])) {
|
||||
|
||||
if ($data[$this->field][0] === '-') {
|
||||
return ctype_digit(substr($data[$this->field], 1));
|
||||
}
|
||||
|
||||
return ctype_digit($data[$this->field]);
|
||||
}
|
||||
else {
|
||||
return is_int($data[$this->field]);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
15
vendor/fguillot/simple-validator/src/SimpleValidator/Validators/Ip.php
vendored
Normal file
15
vendor/fguillot/simple-validator/src/SimpleValidator/Validators/Ip.php
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace SimpleValidator\Validators;
|
||||
|
||||
class Ip extends Base
|
||||
{
|
||||
public function execute(array $data)
|
||||
{
|
||||
if ($this->isFieldNotEmpty($data)) {
|
||||
return filter_var($data[$this->field], FILTER_VALIDATE_IP) !== false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
26
vendor/fguillot/simple-validator/src/SimpleValidator/Validators/Length.php
vendored
Normal file
26
vendor/fguillot/simple-validator/src/SimpleValidator/Validators/Length.php
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace SimpleValidator\Validators;
|
||||
|
||||
class Length extends Base
|
||||
{
|
||||
private $min;
|
||||
private $max;
|
||||
|
||||
public function __construct($field, $error_message, $min, $max)
|
||||
{
|
||||
parent::__construct($field, $error_message);
|
||||
$this->min = $min;
|
||||
$this->max = $max;
|
||||
}
|
||||
|
||||
public function execute(array $data)
|
||||
{
|
||||
if ($this->isFieldNotEmpty($data)) {
|
||||
$length = mb_strlen($data[$this->field], 'UTF-8');
|
||||
return $length >= $this->min && $length <= $this->max;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
24
vendor/fguillot/simple-validator/src/SimpleValidator/Validators/MaxLength.php
vendored
Normal file
24
vendor/fguillot/simple-validator/src/SimpleValidator/Validators/MaxLength.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace SimpleValidator\Validators;
|
||||
|
||||
class MaxLength extends Base
|
||||
{
|
||||
private $max;
|
||||
|
||||
public function __construct($field, $error_message, $max)
|
||||
{
|
||||
parent::__construct($field, $error_message);
|
||||
$this->max = $max;
|
||||
}
|
||||
|
||||
public function execute(array $data)
|
||||
{
|
||||
if ($this->isFieldNotEmpty($data)) {
|
||||
$length = mb_strlen($data[$this->field], 'UTF-8');
|
||||
return $length <= $this->max;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
24
vendor/fguillot/simple-validator/src/SimpleValidator/Validators/MinLength.php
vendored
Normal file
24
vendor/fguillot/simple-validator/src/SimpleValidator/Validators/MinLength.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace SimpleValidator\Validators;
|
||||
|
||||
class MinLength extends Base
|
||||
{
|
||||
private $min;
|
||||
|
||||
public function __construct($field, $error_message, $min)
|
||||
{
|
||||
parent::__construct($field, $error_message);
|
||||
$this->min = $min;
|
||||
}
|
||||
|
||||
public function execute(array $data)
|
||||
{
|
||||
if ($this->isFieldNotEmpty($data)) {
|
||||
$length = mb_strlen($data[$this->field], 'UTF-8');
|
||||
return $length >= $this->min;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
15
vendor/fguillot/simple-validator/src/SimpleValidator/Validators/NotEmpty.php
vendored
Normal file
15
vendor/fguillot/simple-validator/src/SimpleValidator/Validators/NotEmpty.php
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace SimpleValidator\Validators;
|
||||
|
||||
class NotEmpty extends Base
|
||||
{
|
||||
public function execute(array $data)
|
||||
{
|
||||
if (array_key_exists($this->field, $data)) {
|
||||
return $data[$this->field] !== null && $data[$this->field] !== '';
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
28
vendor/fguillot/simple-validator/src/SimpleValidator/Validators/NotEquals.php
vendored
Normal file
28
vendor/fguillot/simple-validator/src/SimpleValidator/Validators/NotEquals.php
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace SimpleValidator\Validators;
|
||||
|
||||
class NotEquals extends Base
|
||||
{
|
||||
private $field2;
|
||||
|
||||
public function __construct($field1, $field2, $error_message)
|
||||
{
|
||||
parent::__construct($field1, $error_message);
|
||||
$this->field2 = $field2;
|
||||
}
|
||||
|
||||
public function execute(array $data)
|
||||
{
|
||||
if ($this->isFieldNotEmpty($data)) {
|
||||
|
||||
if (! isset($data[$this->field2])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $data[$this->field] !== $data[$this->field2];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
15
vendor/fguillot/simple-validator/src/SimpleValidator/Validators/NotInArray.php
vendored
Normal file
15
vendor/fguillot/simple-validator/src/SimpleValidator/Validators/NotInArray.php
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace SimpleValidator\Validators;
|
||||
|
||||
class NotInArray extends InArray
|
||||
{
|
||||
public function execute(array $data)
|
||||
{
|
||||
if ($this->isFieldNotEmpty($data)) {
|
||||
return ! in_array($data[$this->field], $this->array);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
15
vendor/fguillot/simple-validator/src/SimpleValidator/Validators/Numeric.php
vendored
Normal file
15
vendor/fguillot/simple-validator/src/SimpleValidator/Validators/Numeric.php
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace SimpleValidator\Validators;
|
||||
|
||||
class Numeric extends Base
|
||||
{
|
||||
public function execute(array $data)
|
||||
{
|
||||
if ($this->isFieldNotEmpty($data)) {
|
||||
return is_numeric($data[$this->field]);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
33
vendor/fguillot/simple-validator/src/SimpleValidator/Validators/Range.php
vendored
Normal file
33
vendor/fguillot/simple-validator/src/SimpleValidator/Validators/Range.php
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace SimpleValidator\Validators;
|
||||
|
||||
class Range extends Base
|
||||
{
|
||||
private $min;
|
||||
private $max;
|
||||
|
||||
public function __construct($field, $error_message, $min, $max)
|
||||
{
|
||||
parent::__construct($field, $error_message);
|
||||
|
||||
$this->min = $min;
|
||||
$this->max = $max;
|
||||
}
|
||||
|
||||
public function execute(array $data)
|
||||
{
|
||||
if ($this->isFieldNotEmpty($data)) {
|
||||
|
||||
if (! is_numeric($data[$this->field])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($data[$this->field] < $this->min || $data[$this->field] > $this->max) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
11
vendor/fguillot/simple-validator/src/SimpleValidator/Validators/Required.php
vendored
Normal file
11
vendor/fguillot/simple-validator/src/SimpleValidator/Validators/Required.php
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace SimpleValidator\Validators;
|
||||
|
||||
class Required extends Base
|
||||
{
|
||||
public function execute(array $data)
|
||||
{
|
||||
return $this->isFieldNotEmpty($data);
|
||||
}
|
||||
}
|
||||
48
vendor/fguillot/simple-validator/src/SimpleValidator/Validators/Unique.php
vendored
Normal file
48
vendor/fguillot/simple-validator/src/SimpleValidator/Validators/Unique.php
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace SimpleValidator\Validators;
|
||||
|
||||
use PDO;
|
||||
|
||||
class Unique extends Base
|
||||
{
|
||||
private $pdo;
|
||||
private $primary_key;
|
||||
private $table;
|
||||
|
||||
public function __construct($field, $error_message, PDO $pdo, $table, $primary_key = 'id')
|
||||
{
|
||||
parent::__construct($field, $error_message);
|
||||
|
||||
$this->pdo = $pdo;
|
||||
$this->primary_key = $primary_key;
|
||||
$this->table = $table;
|
||||
}
|
||||
|
||||
public function execute(array $data)
|
||||
{
|
||||
if ($this->isFieldNotEmpty($data)) {
|
||||
if (! isset($data[$this->primary_key])) {
|
||||
$rq = $this->pdo->prepare('SELECT 1 FROM '.$this->table.' WHERE '.$this->field.'=?');
|
||||
$rq->execute(array($data[$this->field]));
|
||||
}
|
||||
else {
|
||||
|
||||
$rq = $this->pdo->prepare(
|
||||
'SELECT 1 FROM '.$this->table.'
|
||||
WHERE '.$this->field.'=? AND '.$this->primary_key.' != ?'
|
||||
);
|
||||
|
||||
$rq->execute(array($data[$this->field], $data[$this->primary_key]));
|
||||
}
|
||||
|
||||
$result = $rq->fetchColumn();
|
||||
|
||||
if ($result == 1) { // Postgresql returns an integer but other database returns a string '1'
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
21
vendor/fguillot/simpleLogger/LICENSE
vendored
Normal file
21
vendor/fguillot/simpleLogger/LICENSE
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Frederic Guillot
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
89
vendor/fguillot/simpleLogger/src/SimpleLogger/Base.php
vendored
Normal file
89
vendor/fguillot/simpleLogger/src/SimpleLogger/Base.php
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
namespace SimpleLogger;
|
||||
|
||||
use Psr\Log\AbstractLogger;
|
||||
use Psr\Log\LogLevel;
|
||||
|
||||
/**
|
||||
* Base class for loggers
|
||||
*
|
||||
* @package SimpleLogger
|
||||
* @author Frédéric Guillot
|
||||
*/
|
||||
abstract class Base extends AbstractLogger
|
||||
{
|
||||
/**
|
||||
* Minimum log level for the logger
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
private $level = LogLevel::DEBUG;
|
||||
|
||||
/**
|
||||
* Set minimum log level
|
||||
*
|
||||
* @access public
|
||||
* @param string $level
|
||||
*/
|
||||
public function setLevel($level)
|
||||
{
|
||||
$this->level = $level;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get minimum log level
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getLevel()
|
||||
{
|
||||
return $this->level;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dump to log a variable (by example an array)
|
||||
*
|
||||
* @param mixed $variable
|
||||
*/
|
||||
public function dump($variable)
|
||||
{
|
||||
$this->log(LogLevel::DEBUG, var_export($variable, true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Interpolates context values into the message placeholders.
|
||||
*
|
||||
* @access protected
|
||||
* @param string $message
|
||||
* @param array $context
|
||||
* @return string
|
||||
*/
|
||||
protected function interpolate($message, array $context = array())
|
||||
{
|
||||
// build a replacement array with braces around the context keys
|
||||
$replace = array();
|
||||
|
||||
foreach ($context as $key => $val) {
|
||||
$replace['{' . $key . '}'] = $val;
|
||||
}
|
||||
|
||||
// interpolate replacement values into the message and return
|
||||
return strtr($message, $replace);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format log message
|
||||
*
|
||||
* @param mixed $level
|
||||
* @param string $message
|
||||
* @param array $context
|
||||
* @return string
|
||||
*/
|
||||
protected function formatMessage($level, $message, array $context = array())
|
||||
{
|
||||
return '['.date('Y-m-d H:i:s').'] ['.$level.'] '.$this->interpolate($message, $context).PHP_EOL;
|
||||
}
|
||||
}
|
||||
48
vendor/fguillot/simpleLogger/src/SimpleLogger/File.php
vendored
Normal file
48
vendor/fguillot/simpleLogger/src/SimpleLogger/File.php
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace SimpleLogger;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
/**
|
||||
* File logger
|
||||
*
|
||||
* @package SimpleLogger
|
||||
* @author Frédéric Guillot
|
||||
*/
|
||||
class File extends Base
|
||||
{
|
||||
/**
|
||||
* Filename
|
||||
*
|
||||
* @access protected
|
||||
* @var string
|
||||
*/
|
||||
protected $filename = '';
|
||||
|
||||
/**
|
||||
* Setup logger configuration
|
||||
*
|
||||
* @param string $filename Output file
|
||||
*/
|
||||
public function __construct($filename)
|
||||
{
|
||||
$this->filename = $filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs with an arbitrary level.
|
||||
*
|
||||
* @param mixed $level
|
||||
* @param string $message
|
||||
* @param array $context
|
||||
*/
|
||||
public function log($level, $message, array $context = array())
|
||||
{
|
||||
$line = $this->formatMessage($level, $message, $context);
|
||||
|
||||
if (file_put_contents($this->filename, $line, FILE_APPEND | LOCK_EX) === false) {
|
||||
throw new RuntimeException('Unable to write to the log file.');
|
||||
}
|
||||
}
|
||||
}
|
||||
94
vendor/fguillot/simpleLogger/src/SimpleLogger/Logger.php
vendored
Normal file
94
vendor/fguillot/simpleLogger/src/SimpleLogger/Logger.php
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
namespace SimpleLogger;
|
||||
|
||||
use Psr\Log\AbstractLogger;
|
||||
use Psr\Log\LoggerAwareInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Psr\Log\LogLevel;
|
||||
|
||||
/**
|
||||
* Handler for multiple loggers
|
||||
*
|
||||
* @package SimpleLogger
|
||||
* @author Frédéric Guillot
|
||||
*/
|
||||
class Logger extends AbstractLogger implements LoggerAwareInterface
|
||||
{
|
||||
/**
|
||||
* Logger instances
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
private $loggers = array();
|
||||
|
||||
/**
|
||||
* Get level priority
|
||||
*
|
||||
* @param mixed $level
|
||||
* @return integer
|
||||
*/
|
||||
public function getLevelPriority($level)
|
||||
{
|
||||
switch ($level) {
|
||||
case LogLevel::EMERGENCY:
|
||||
return 600;
|
||||
case LogLevel::ALERT:
|
||||
return 550;
|
||||
case LogLevel::CRITICAL:
|
||||
return 500;
|
||||
case LogLevel::ERROR:
|
||||
return 400;
|
||||
case LogLevel::WARNING:
|
||||
return 300;
|
||||
case LogLevel::NOTICE:
|
||||
return 250;
|
||||
case LogLevel::INFO:
|
||||
return 200;
|
||||
}
|
||||
|
||||
return 100;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a logger instance on the object
|
||||
*
|
||||
* @param LoggerInterface $logger
|
||||
* @return null
|
||||
*/
|
||||
public function setLogger(LoggerInterface $logger)
|
||||
{
|
||||
$this->loggers[] = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Proxy method to the real loggers
|
||||
*
|
||||
* @param mixed $level
|
||||
* @param string $message
|
||||
* @param array $context
|
||||
* @return null
|
||||
*/
|
||||
public function log($level, $message, array $context = array())
|
||||
{
|
||||
foreach ($this->loggers as $logger) {
|
||||
if ($this->getLevelPriority($level) >= $this->getLevelPriority($logger->getLevel())) {
|
||||
$logger->log($level, $message, $context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dump variables for debugging
|
||||
*
|
||||
* @param mixed $variable
|
||||
*/
|
||||
public function dump($variable)
|
||||
{
|
||||
foreach ($this->loggers as $logger) {
|
||||
if ($this->getLevelPriority(LogLevel::DEBUG) >= $this->getLevelPriority($logger->getLevel())) {
|
||||
$logger->dump($variable);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
25
vendor/fguillot/simpleLogger/src/SimpleLogger/Stderr.php
vendored
Normal file
25
vendor/fguillot/simpleLogger/src/SimpleLogger/Stderr.php
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace SimpleLogger;
|
||||
|
||||
/**
|
||||
* Stderr logger
|
||||
*
|
||||
* @package SimpleLogger
|
||||
* @author Frédéric Guillot
|
||||
*/
|
||||
class Stderr extends Base
|
||||
{
|
||||
/**
|
||||
* Logs with an arbitrary level.
|
||||
*
|
||||
* @param mixed $level
|
||||
* @param string $message
|
||||
* @param array $context
|
||||
* @return null
|
||||
*/
|
||||
public function log($level, $message, array $context = array())
|
||||
{
|
||||
file_put_contents('php://stderr', $this->formatMessage($level, $message, $context), FILE_APPEND);
|
||||
}
|
||||
}
|
||||
25
vendor/fguillot/simpleLogger/src/SimpleLogger/Stdout.php
vendored
Normal file
25
vendor/fguillot/simpleLogger/src/SimpleLogger/Stdout.php
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace SimpleLogger;
|
||||
|
||||
/**
|
||||
* Stdout logger
|
||||
*
|
||||
* @package SimpleLogger
|
||||
* @author Frédéric Guillot
|
||||
*/
|
||||
class Stdout extends Base
|
||||
{
|
||||
/**
|
||||
* Logs with an arbitrary level.
|
||||
*
|
||||
* @param mixed $level
|
||||
* @param string $message
|
||||
* @param array $context
|
||||
* @return null
|
||||
*/
|
||||
public function log($level, $message, array $context = array())
|
||||
{
|
||||
file_put_contents('php://stdout', $this->formatMessage($level, $message, $context), FILE_APPEND);
|
||||
}
|
||||
}
|
||||
72
vendor/fguillot/simpleLogger/src/SimpleLogger/Syslog.php
vendored
Normal file
72
vendor/fguillot/simpleLogger/src/SimpleLogger/Syslog.php
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
namespace SimpleLogger;
|
||||
|
||||
use RuntimeException;
|
||||
use Psr\Log\LogLevel;
|
||||
|
||||
/**
|
||||
* Syslog Logger
|
||||
*
|
||||
* @package SimpleLogger
|
||||
* @author Frédéric Guillot
|
||||
*/
|
||||
class Syslog extends Base
|
||||
{
|
||||
/**
|
||||
* Setup Syslog configuration
|
||||
*
|
||||
* @param string $ident Application name
|
||||
* @param int $facility See http://php.net/manual/en/function.openlog.php
|
||||
*/
|
||||
public function __construct($ident = 'PHP', $facility = LOG_USER)
|
||||
{
|
||||
if (! openlog($ident, LOG_ODELAY | LOG_PID, $facility)) {
|
||||
throw new RuntimeException('Unable to connect to syslog.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get syslog priority according to Psr\LogLevel
|
||||
*
|
||||
* @param mixed $level
|
||||
* @return integer
|
||||
*/
|
||||
public function getSyslogPriority($level)
|
||||
{
|
||||
switch ($level) {
|
||||
case LogLevel::EMERGENCY:
|
||||
return LOG_EMERG;
|
||||
case LogLevel::ALERT:
|
||||
return LOG_ALERT;
|
||||
case LogLevel::CRITICAL:
|
||||
return LOG_CRIT;
|
||||
case LogLevel::ERROR:
|
||||
return LOG_ERR;
|
||||
case LogLevel::WARNING:
|
||||
return LOG_WARNING;
|
||||
case LogLevel::NOTICE:
|
||||
return LOG_NOTICE;
|
||||
case LogLevel::INFO:
|
||||
return LOG_INFO;
|
||||
}
|
||||
|
||||
return LOG_DEBUG;
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs with an arbitrary level.
|
||||
*
|
||||
* @param mixed $level
|
||||
* @param string $message
|
||||
* @param array $context
|
||||
* @return null
|
||||
*/
|
||||
public function log($level, $message, array $context = array())
|
||||
{
|
||||
$syslogPriority = $this->getSyslogPriority($level);
|
||||
$syslogMessage = $this->interpolate($message, $context);
|
||||
|
||||
syslog($syslogPriority, $syslogMessage);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user