mirror of
https://github.com/YunoHost-Apps/rainloop_ynh.git
synced 2024-09-03 20:16:18 +02:00
Merge branch 'master' of https://github.com/polytan02/rainloop_ynh
This commit is contained in:
commit
dc09591995
918 changed files with 0 additions and 236307 deletions
|
@ -1,124 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Exception;
|
||||
|
||||
use GuzzleHttp\Message\RequestInterface;
|
||||
use GuzzleHttp\Message\ResponseInterface;
|
||||
|
||||
/**
|
||||
* HTTP Request exception
|
||||
*/
|
||||
class RequestException extends TransferException
|
||||
{
|
||||
/** @var bool */
|
||||
private $emittedErrorEvent = false;
|
||||
|
||||
/** @var RequestInterface */
|
||||
private $request;
|
||||
|
||||
/** @var ResponseInterface */
|
||||
private $response;
|
||||
|
||||
public function __construct(
|
||||
$message = '',
|
||||
RequestInterface $request,
|
||||
ResponseInterface $response = null,
|
||||
\Exception $previous = null
|
||||
) {
|
||||
$code = $response ? $response->getStatusCode() : 0;
|
||||
parent::__construct($message, $code, $previous);
|
||||
$this->request = $request;
|
||||
$this->response = $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method to create a new exception with a normalized error message
|
||||
*
|
||||
* @param RequestInterface $request Request
|
||||
* @param ResponseInterface $response Response received
|
||||
* @param \Exception $previous Previous exception
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public static function create(
|
||||
RequestInterface $request,
|
||||
ResponseInterface $response = null,
|
||||
\Exception $previous = null
|
||||
) {
|
||||
if (!$response) {
|
||||
return new self('Error completing request', $request, null, $previous);
|
||||
}
|
||||
|
||||
$level = $response->getStatusCode()[0];
|
||||
if ($level == '4') {
|
||||
$label = 'Client error response';
|
||||
$className = __NAMESPACE__ . '\\ClientException';
|
||||
} elseif ($level == '5') {
|
||||
$label = 'Server error response';
|
||||
$className = __NAMESPACE__ . '\\ServerException';
|
||||
} else {
|
||||
$label = 'Unsuccessful response';
|
||||
$className = __CLASS__;
|
||||
}
|
||||
|
||||
$message = $label . ' [url] ' . $request->getUrl()
|
||||
. ' [status code] ' . $response->getStatusCode()
|
||||
. ' [reason phrase] ' . $response->getReasonPhrase();
|
||||
|
||||
return new $className($message, $request, $response, $previous);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the request that caused the exception
|
||||
*
|
||||
* @return RequestInterface
|
||||
*/
|
||||
public function getRequest()
|
||||
{
|
||||
return $this->request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the associated response
|
||||
*
|
||||
* @return ResponseInterface|null
|
||||
*/
|
||||
public function getResponse()
|
||||
{
|
||||
return $this->response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a response was received
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasResponse()
|
||||
{
|
||||
return $this->response !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check or set if the exception was emitted in an error event.
|
||||
*
|
||||
* This value is used in the RequestEvents::emitBefore() method to check
|
||||
* to see if an exception has already been emitted in an error event.
|
||||
*
|
||||
* @param bool|null Set to true to set the exception as having emitted an
|
||||
* error. Leave null to retrieve the current setting.
|
||||
*
|
||||
* @return null|bool
|
||||
* @throws \InvalidArgumentException if you attempt to set the value to false
|
||||
*/
|
||||
public function emittedError($value = null)
|
||||
{
|
||||
if ($value === null) {
|
||||
return $this->emittedErrorEvent;
|
||||
} elseif ($value === true) {
|
||||
return $this->emittedErrorEvent = true;
|
||||
} else {
|
||||
throw new \InvalidArgumentException('You cannot set the emitted '
|
||||
. 'error value to false.');
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Exception;
|
||||
|
||||
/**
|
||||
* Exception when a server error is encountered (5xx codes)
|
||||
*/
|
||||
class ServerException extends BadResponseException {}
|
|
@ -1,5 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Exception;
|
||||
|
||||
class TooManyRedirectsException extends RequestException {}
|
|
@ -1,5 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Exception;
|
||||
|
||||
class TransferException extends \RuntimeException {}
|
|
@ -1,76 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp;
|
||||
|
||||
/**
|
||||
* Trait implementing ToArrayInterface, \ArrayAccess, \Countable,
|
||||
* \IteratorAggregate, and some path style methods.
|
||||
*/
|
||||
trait HasDataTrait
|
||||
{
|
||||
/** @var array */
|
||||
protected $data = [];
|
||||
|
||||
public function getIterator()
|
||||
{
|
||||
return new \ArrayIterator($this->data);
|
||||
}
|
||||
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
return isset($this->data[$offset]) ? $this->data[$offset] : null;
|
||||
}
|
||||
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
$this->data[$offset] = $value;
|
||||
}
|
||||
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return isset($this->data[$offset]);
|
||||
}
|
||||
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
unset($this->data[$offset]);
|
||||
}
|
||||
|
||||
public function toArray()
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
public function count()
|
||||
{
|
||||
return count($this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a value from the collection using a path syntax to retrieve nested
|
||||
* data.
|
||||
*
|
||||
* @param string $path Path to traverse and retrieve a value from
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function getPath($path)
|
||||
{
|
||||
return \GuzzleHttp\get_path($this->data, $path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a value into a nested array key. Keys will be created as needed to
|
||||
* set the value.
|
||||
*
|
||||
* @param string $path Path to set
|
||||
* @param mixed $value Value to set at the key
|
||||
*
|
||||
* @throws \RuntimeException when trying to setPath using a nested path
|
||||
* that travels through a scalar value
|
||||
*/
|
||||
public function setPath($path, $value)
|
||||
{
|
||||
\GuzzleHttp\set_path($this->data, $path, $value);
|
||||
}
|
||||
}
|
|
@ -1,237 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Message;
|
||||
|
||||
use GuzzleHttp\Stream\StreamInterface;
|
||||
|
||||
abstract class AbstractMessage implements MessageInterface
|
||||
{
|
||||
/** @var array HTTP header collection */
|
||||
private $headers = [];
|
||||
|
||||
/** @var array mapping a lowercase header name to its name over the wire */
|
||||
private $headerNames = [];
|
||||
|
||||
/** @var StreamInterface Message body */
|
||||
private $body;
|
||||
|
||||
/** @var string HTTP protocol version of the message */
|
||||
private $protocolVersion = '1.1';
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
$result = $this->getStartLine();
|
||||
foreach ($this->getHeaders() as $name => $values) {
|
||||
$result .= "\r\n{$name}: " . implode(', ', $values);
|
||||
}
|
||||
|
||||
return $result . "\r\n\r\n" . $this->body;
|
||||
}
|
||||
|
||||
public function getProtocolVersion()
|
||||
{
|
||||
return $this->protocolVersion;
|
||||
}
|
||||
|
||||
public function getBody()
|
||||
{
|
||||
return $this->body;
|
||||
}
|
||||
|
||||
public function setBody(StreamInterface $body = null)
|
||||
{
|
||||
if ($body === null) {
|
||||
// Setting a null body will remove the body of the request
|
||||
$this->removeHeader('Content-Length')
|
||||
->removeHeader('Transfer-Encoding');
|
||||
}
|
||||
|
||||
$this->body = $body;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addHeader($header, $value)
|
||||
{
|
||||
static $valid = ['string' => true, 'integer' => true,
|
||||
'double' => true, 'array' => true];
|
||||
|
||||
$type = gettype($value);
|
||||
if (!isset($valid[$type])) {
|
||||
throw new \InvalidArgumentException('Invalid header value');
|
||||
}
|
||||
|
||||
if ($type == 'array') {
|
||||
$current = array_merge($this->getHeader($header, true), $value);
|
||||
} else {
|
||||
$current = $this->getHeader($header, true);
|
||||
$current[] = $value;
|
||||
}
|
||||
|
||||
return $this->setHeader($header, $current);
|
||||
}
|
||||
|
||||
public function addHeaders(array $headers)
|
||||
{
|
||||
foreach ($headers as $name => $header) {
|
||||
$this->addHeader($name, $header);
|
||||
}
|
||||
}
|
||||
|
||||
public function getHeader($header, $asArray = false)
|
||||
{
|
||||
$name = strtolower($header);
|
||||
|
||||
if (!isset($this->headers[$name])) {
|
||||
return $asArray ? [] : '';
|
||||
}
|
||||
|
||||
return $asArray
|
||||
? $this->headers[$name]
|
||||
: implode(', ', $this->headers[$name]);
|
||||
}
|
||||
|
||||
public function getHeaders()
|
||||
{
|
||||
$headers = [];
|
||||
foreach ($this->headers as $name => $values) {
|
||||
$headers[$this->headerNames[$name]] = $values;
|
||||
}
|
||||
|
||||
return $headers;
|
||||
}
|
||||
|
||||
public function setHeader($header, $value)
|
||||
{
|
||||
$header = trim($header);
|
||||
$name = strtolower($header);
|
||||
$this->headerNames[$name] = $header;
|
||||
|
||||
switch (gettype($value)) {
|
||||
case 'string':
|
||||
$this->headers[$name] = [trim($value)];
|
||||
break;
|
||||
case 'integer':
|
||||
case 'double':
|
||||
$this->headers[$name] = [(string) $value];
|
||||
break;
|
||||
case 'array':
|
||||
foreach ($value as &$v) {
|
||||
$v = trim($v);
|
||||
}
|
||||
$this->headers[$name] = $value;
|
||||
break;
|
||||
default:
|
||||
throw new \InvalidArgumentException('Invalid header value '
|
||||
. 'provided: ' . var_export($value, true));
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setHeaders(array $headers)
|
||||
{
|
||||
$this->headers = $this->headerNames = [];
|
||||
foreach ($headers as $key => $value) {
|
||||
$this->setHeader($key, $value);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function hasHeader($header)
|
||||
{
|
||||
return isset($this->headers[strtolower($header)]);
|
||||
}
|
||||
|
||||
public function removeHeader($header)
|
||||
{
|
||||
$name = strtolower($header);
|
||||
unset($this->headers[$name], $this->headerNames[$name]);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse an array of header values containing ";" separated data into an
|
||||
* array of associative arrays representing the header key value pair
|
||||
* data of the header. When a parameter does not contain a value, but just
|
||||
* contains a key, this function will inject a key with a '' string value.
|
||||
*
|
||||
* @param MessageInterface $message That contains the header
|
||||
* @param string $header Header to retrieve from the message
|
||||
*
|
||||
* @return array Returns the parsed header values.
|
||||
*/
|
||||
public static function parseHeader(MessageInterface $message, $header)
|
||||
{
|
||||
static $trimmed = "\"' \n\t\r";
|
||||
$params = $matches = [];
|
||||
|
||||
foreach (self::normalizeHeader($message, $header) as $val) {
|
||||
$part = [];
|
||||
foreach (preg_split('/;(?=([^"]*"[^"]*")*[^"]*$)/', $val) as $kvp) {
|
||||
if (preg_match_all('/<[^>]+>|[^=]+/', $kvp, $matches)) {
|
||||
$m = $matches[0];
|
||||
if (isset($m[1])) {
|
||||
$part[trim($m[0], $trimmed)] = trim($m[1], $trimmed);
|
||||
} else {
|
||||
$part[] = trim($m[0], $trimmed);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($part) {
|
||||
$params[] = $part;
|
||||
}
|
||||
}
|
||||
|
||||
return $params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an array of header values that may contain comma separated
|
||||
* headers into an array of headers with no comma separated values.
|
||||
*
|
||||
* @param MessageInterface $message That contains the header
|
||||
* @param string $header Header to retrieve from the message
|
||||
*
|
||||
* @return array Returns the normalized header field values.
|
||||
*/
|
||||
public static function normalizeHeader(MessageInterface $message, $header)
|
||||
{
|
||||
$h = $message->getHeader($header, true);
|
||||
for ($i = 0, $total = count($h); $i < $total; $i++) {
|
||||
if (strpos($h[$i], ',') === false) {
|
||||
continue;
|
||||
}
|
||||
foreach (preg_split('/,(?=([^"]*"[^"]*")*[^"]*$)/', $h[$i]) as $v) {
|
||||
$h[] = trim($v);
|
||||
}
|
||||
unset($h[$i]);
|
||||
}
|
||||
|
||||
return $h;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the start line of a message.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
abstract protected function getStartLine();
|
||||
|
||||
/**
|
||||
* Accepts and modifies the options provided to the message in the
|
||||
* constructor.
|
||||
*
|
||||
* Can be overridden in subclasses as necessary.
|
||||
*
|
||||
* @param array $options Options array passed by reference.
|
||||
*/
|
||||
protected function handleOptions(array &$options)
|
||||
{
|
||||
if (isset($options['protocol_version'])) {
|
||||
$this->protocolVersion = $options['protocol_version'];
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,345 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Message;
|
||||
|
||||
use GuzzleHttp\Event\ListenerAttacherTrait;
|
||||
use GuzzleHttp\Post\PostFileInterface;
|
||||
use GuzzleHttp\Subscriber\Cookie;
|
||||
use GuzzleHttp\Cookie\CookieJar;
|
||||
use GuzzleHttp\Cookie\CookieJarInterface;
|
||||
use GuzzleHttp\Subscriber\HttpError;
|
||||
use GuzzleHttp\Post\PostBody;
|
||||
use GuzzleHttp\Post\PostFile;
|
||||
use GuzzleHttp\Subscriber\Redirect;
|
||||
use GuzzleHttp\Stream;
|
||||
use GuzzleHttp\Query;
|
||||
use GuzzleHttp\Url;
|
||||
|
||||
/**
|
||||
* Default HTTP request factory used to create Request and Response objects.
|
||||
*/
|
||||
class MessageFactory implements MessageFactoryInterface
|
||||
{
|
||||
use ListenerAttacherTrait;
|
||||
|
||||
/** @var HttpError */
|
||||
private $errorPlugin;
|
||||
|
||||
/** @var Redirect */
|
||||
private $redirectPlugin;
|
||||
|
||||
/** @var array */
|
||||
protected static $classMethods = [];
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->errorPlugin = new HttpError();
|
||||
$this->redirectPlugin = new Redirect();
|
||||
}
|
||||
|
||||
public function createResponse(
|
||||
$statusCode,
|
||||
array $headers = [],
|
||||
$body = null,
|
||||
array $options = []
|
||||
) {
|
||||
if (null !== $body) {
|
||||
$body = Stream\create($body);
|
||||
}
|
||||
|
||||
return new Response($statusCode, $headers, $body, $options);
|
||||
}
|
||||
|
||||
public function createRequest($method, $url, array $options = [])
|
||||
{
|
||||
// Handle the request protocol version option that needs to be
|
||||
// specified in the request constructor.
|
||||
if (isset($options['version'])) {
|
||||
$options['config']['protocol_version'] = $options['version'];
|
||||
unset($options['version']);
|
||||
}
|
||||
|
||||
$request = new Request($method, $url, [], null,
|
||||
isset($options['config']) ? $options['config'] : []);
|
||||
|
||||
unset($options['config']);
|
||||
|
||||
// Use a POST body by default
|
||||
if ($method == 'POST' &&
|
||||
!isset($options['body']) &&
|
||||
!isset($options['json'])
|
||||
) {
|
||||
$options['body'] = [];
|
||||
}
|
||||
|
||||
if ($options) {
|
||||
$this->applyOptions($request, $options);
|
||||
}
|
||||
|
||||
return $request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a request or response object from an HTTP message string
|
||||
*
|
||||
* @param string $message Message to parse
|
||||
*
|
||||
* @return RequestInterface|ResponseInterface
|
||||
* @throws \InvalidArgumentException if unable to parse a message
|
||||
*/
|
||||
public function fromMessage($message)
|
||||
{
|
||||
static $parser;
|
||||
if (!$parser) {
|
||||
$parser = new MessageParser();
|
||||
}
|
||||
|
||||
// Parse a response
|
||||
if (strtoupper(substr($message, 0, 4)) == 'HTTP') {
|
||||
$data = $parser->parseResponse($message);
|
||||
return $this->createResponse(
|
||||
$data['code'],
|
||||
$data['headers'],
|
||||
$data['body'] === '' ? null : $data['body'],
|
||||
$data
|
||||
);
|
||||
}
|
||||
|
||||
// Parse a request
|
||||
if (!($data = ($parser->parseRequest($message)))) {
|
||||
throw new \InvalidArgumentException('Unable to parse request');
|
||||
}
|
||||
|
||||
return $this->createRequest(
|
||||
$data['method'],
|
||||
Url::buildUrl($data['request_url']),
|
||||
[
|
||||
'headers' => $data['headers'],
|
||||
'body' => $data['body'] === '' ? null : $data['body'],
|
||||
'config' => [
|
||||
'protocol_version' => $data['protocol_version']
|
||||
]
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply POST fields and files to a request to attempt to give an accurate
|
||||
* representation.
|
||||
*
|
||||
* @param RequestInterface $request Request to update
|
||||
* @param array $body Body to apply
|
||||
*/
|
||||
protected function addPostData(RequestInterface $request, array $body)
|
||||
{
|
||||
static $fields = ['string' => true, 'array' => true, 'NULL' => true,
|
||||
'boolean' => true, 'double' => true, 'integer' => true];
|
||||
|
||||
$post = new PostBody();
|
||||
foreach ($body as $key => $value) {
|
||||
if (isset($fields[gettype($value)])) {
|
||||
$post->setField($key, $value);
|
||||
} elseif ($value instanceof PostFileInterface) {
|
||||
$post->addFile($value);
|
||||
} else {
|
||||
$post->addFile(new PostFile($key, $value));
|
||||
}
|
||||
}
|
||||
|
||||
$request->setBody($post);
|
||||
$post->applyRequestHeaders($request);
|
||||
}
|
||||
|
||||
protected function applyOptions(
|
||||
RequestInterface $request,
|
||||
array $options = []
|
||||
) {
|
||||
// Values specified in the config map are passed to request options
|
||||
static $configMap = ['connect_timeout' => 1, 'timeout' => 1,
|
||||
'verify' => 1, 'ssl_key' => 1, 'cert' => 1, 'proxy' => 1,
|
||||
'debug' => 1, 'save_to' => 1, 'stream' => 1, 'expect' => 1];
|
||||
|
||||
// Take the class of the instance, not the parent
|
||||
$selfClass = get_class($this);
|
||||
|
||||
// Check if we already took it's class methods and had them saved
|
||||
if (!isset(self::$classMethods[$selfClass])) {
|
||||
self::$classMethods[$selfClass] = array_flip(get_class_methods($this));
|
||||
}
|
||||
|
||||
// Take class methods of this particular instance
|
||||
$methods = self::$classMethods[$selfClass];
|
||||
|
||||
// Iterate over each key value pair and attempt to apply a config using
|
||||
// double dispatch.
|
||||
$config = $request->getConfig();
|
||||
foreach ($options as $key => $value) {
|
||||
$method = "add_{$key}";
|
||||
if (isset($methods[$method])) {
|
||||
$this->{$method}($request, $value);
|
||||
} elseif (isset($configMap[$key])) {
|
||||
$config[$key] = $value;
|
||||
} else {
|
||||
throw new \InvalidArgumentException("No method is configured "
|
||||
. "to handle the {$key} config key");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function add_body(RequestInterface $request, $value)
|
||||
{
|
||||
if ($value !== null) {
|
||||
if (is_array($value)) {
|
||||
$this->addPostData($request, $value);
|
||||
} else {
|
||||
$request->setBody(Stream\create($value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function add_allow_redirects(RequestInterface $request, $value)
|
||||
{
|
||||
static $defaultRedirect = [
|
||||
'max' => 5,
|
||||
'strict' => false,
|
||||
'referer' => false
|
||||
];
|
||||
|
||||
if ($value === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($value === true) {
|
||||
$value = $defaultRedirect;
|
||||
} elseif (!isset($value['max'])) {
|
||||
throw new \InvalidArgumentException('allow_redirects must be '
|
||||
. 'true, false, or an array that contains the \'max\' key');
|
||||
} else {
|
||||
// Merge the default settings with the provided settings
|
||||
$value += $defaultRedirect;
|
||||
}
|
||||
|
||||
$request->getConfig()['redirect'] = $value;
|
||||
$request->getEmitter()->attach($this->redirectPlugin);
|
||||
}
|
||||
|
||||
private function add_exceptions(RequestInterface $request, $value)
|
||||
{
|
||||
if ($value === true) {
|
||||
$request->getEmitter()->attach($this->errorPlugin);
|
||||
}
|
||||
}
|
||||
|
||||
private function add_auth(RequestInterface $request, $value)
|
||||
{
|
||||
if (!$value) {
|
||||
return;
|
||||
} elseif (is_array($value)) {
|
||||
$authType = isset($value[2]) ? strtolower($value[2]) : 'basic';
|
||||
} else {
|
||||
$authType = strtolower($value);
|
||||
}
|
||||
|
||||
$request->getConfig()->set('auth', $value);
|
||||
|
||||
if ($authType == 'basic') {
|
||||
$request->setHeader(
|
||||
'Authorization',
|
||||
'Basic ' . base64_encode("$value[0]:$value[1]")
|
||||
);
|
||||
} elseif ($authType == 'digest') {
|
||||
// Currently only implemented by the cURL adapter.
|
||||
// @todo: Need an event listener solution that does not rely on cURL
|
||||
$config = $request->getConfig();
|
||||
$config->setPath('curl/' . CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
|
||||
$config->setPath('curl/' . CURLOPT_USERPWD, "$value[0]:$value[1]");
|
||||
}
|
||||
}
|
||||
|
||||
private function add_query(RequestInterface $request, $value)
|
||||
{
|
||||
if ($value instanceof Query) {
|
||||
$original = $request->getQuery();
|
||||
// Do not overwrite existing query string variables by overwriting
|
||||
// the object with the query string data passed in the URL
|
||||
$request->setQuery($value->overwriteWith($original->toArray()));
|
||||
} elseif (is_array($value)) {
|
||||
// Do not overwrite existing query string variables
|
||||
$query = $request->getQuery();
|
||||
foreach ($value as $k => $v) {
|
||||
if (!isset($query[$k])) {
|
||||
$query[$k] = $v;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new \InvalidArgumentException('query value must be an array '
|
||||
. 'or Query object');
|
||||
}
|
||||
}
|
||||
|
||||
private function add_headers(RequestInterface $request, $value)
|
||||
{
|
||||
if (!is_array($value)) {
|
||||
throw new \InvalidArgumentException('header value must be an array');
|
||||
}
|
||||
|
||||
// Do not overwrite existing headers
|
||||
foreach ($value as $k => $v) {
|
||||
if (!$request->hasHeader($k)) {
|
||||
$request->setHeader($k, $v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function add_cookies(RequestInterface $request, $value)
|
||||
{
|
||||
if ($value === true) {
|
||||
static $cookie = null;
|
||||
if (!$cookie) {
|
||||
$cookie = new Cookie();
|
||||
}
|
||||
$request->getEmitter()->attach($cookie);
|
||||
} elseif (is_array($value)) {
|
||||
$request->getEmitter()->attach(
|
||||
new Cookie(CookieJar::fromArray($value, $request->getHost()))
|
||||
);
|
||||
} elseif ($value instanceof CookieJarInterface) {
|
||||
$request->getEmitter()->attach(new Cookie($value));
|
||||
} elseif ($value !== false) {
|
||||
throw new \InvalidArgumentException('cookies must be an array, '
|
||||
. 'true, or a CookieJarInterface object');
|
||||
}
|
||||
}
|
||||
|
||||
private function add_events(RequestInterface $request, $value)
|
||||
{
|
||||
if (!is_array($value)) {
|
||||
throw new \InvalidArgumentException('events value must be an array');
|
||||
}
|
||||
|
||||
$this->attachListeners($request, $this->prepareListeners($value,
|
||||
['before', 'complete', 'error', 'headers']
|
||||
));
|
||||
}
|
||||
|
||||
private function add_subscribers(RequestInterface $request, $value)
|
||||
{
|
||||
if (!is_array($value)) {
|
||||
throw new \InvalidArgumentException('subscribers must be an array');
|
||||
}
|
||||
|
||||
$emitter = $request->getEmitter();
|
||||
foreach ($value as $subscribers) {
|
||||
$emitter->attach($subscribers);
|
||||
}
|
||||
}
|
||||
|
||||
private function add_json(RequestInterface $request, $value)
|
||||
{
|
||||
if (!$request->hasHeader('Content-Type')) {
|
||||
$request->setHeader('Content-Type', 'application/json');
|
||||
}
|
||||
|
||||
$request->setBody(Stream\create(json_encode($value)));
|
||||
}
|
||||
}
|
|
@ -1,71 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Message;
|
||||
|
||||
use GuzzleHttp\Url;
|
||||
|
||||
/**
|
||||
* Request and response factory
|
||||
*/
|
||||
interface MessageFactoryInterface
|
||||
{
|
||||
/**
|
||||
* Creates a response
|
||||
*
|
||||
* @param string $statusCode HTTP status code
|
||||
* @param array $headers Response headers
|
||||
* @param mixed $body Response body
|
||||
* @param array $options Response options
|
||||
* - protocol_version: HTTP protocol version
|
||||
* - header_factory: Factory used to create headers
|
||||
* - And any other options used by a concrete message implementation
|
||||
*
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
public function createResponse(
|
||||
$statusCode,
|
||||
array $headers = [],
|
||||
$body = null,
|
||||
array $options = []
|
||||
);
|
||||
|
||||
/**
|
||||
* Create a new request based on the HTTP method.
|
||||
*
|
||||
* This method accepts an associative array of request options. Below is a
|
||||
* brief description of each parameter. See
|
||||
* http://docs.guzzlephp.org/clients.html#request-options for a much more
|
||||
* in-depth description of each parameter.
|
||||
*
|
||||
* - headers: Associative array of headers to add to the request
|
||||
* - body: string|resource|array|StreamInterface request body to send
|
||||
* - json: mixed Uploads JSON encoded data using an application/json Content-Type header.
|
||||
* - query: Associative array of query string values to add to the request
|
||||
* - auth: array|string HTTP auth settings (user, pass[, type="basic"])
|
||||
* - version: The HTTP protocol version to use with the request
|
||||
* - cookies: true|false|CookieJarInterface To enable or disable cookies
|
||||
* - allow_redirects: true|false|array Controls HTTP redirects
|
||||
* - save_to: string|resource|StreamInterface Where the response is saved
|
||||
* - events: Associative array of event names to callables or arrays
|
||||
* - subscribers: Array of event subscribers to add to the request
|
||||
* - exceptions: Specifies whether or not exceptions are thrown for HTTP protocol errors
|
||||
* - timeout: Timeout of the request in seconds. Use 0 to wait indefinitely
|
||||
* - connect_timeout: Number of seconds to wait while trying to connect. (0 to wait indefinitely)
|
||||
* - verify: SSL validation. True/False or the path to a PEM file
|
||||
* - cert: Path a SSL cert or array of (path, pwd)
|
||||
* - ssl_key: Path to a private SSL key or array of (path, pwd)
|
||||
* - proxy: Specify an HTTP proxy or hash of protocols to proxies
|
||||
* - debug: Set to true or a resource to view adapter specific debug info
|
||||
* - stream: Set to true to stream a response body rather than download it all up front
|
||||
* - expect: true/false/integer Controls the "Expect: 100-Continue" header
|
||||
* - config: Associative array of request config collection options
|
||||
*
|
||||
* @param string $method HTTP method (GET, POST, PUT, etc.)
|
||||
* @param string|Url $url HTTP URL to connect to
|
||||
* @param array $options Array of options to apply to the request
|
||||
*
|
||||
* @return RequestInterface
|
||||
* @link http://docs.guzzlephp.org/clients.html#request-options
|
||||
*/
|
||||
public function createRequest($method, $url, array $options = []);
|
||||
}
|
|
@ -1,148 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Message;
|
||||
|
||||
use GuzzleHttp\Stream\StreamInterface;
|
||||
|
||||
/**
|
||||
* Request and response message interface
|
||||
*/
|
||||
interface MessageInterface
|
||||
{
|
||||
/**
|
||||
* Get a string representation of the message
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString();
|
||||
|
||||
/**
|
||||
* Get the HTTP protocol version of the message
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getProtocolVersion();
|
||||
|
||||
/**
|
||||
* Sets the body of the message.
|
||||
*
|
||||
* The body MUST be a StreamInterface object. Setting the body to null MUST
|
||||
* remove the existing body.
|
||||
*
|
||||
* @param StreamInterface|null $body Body.
|
||||
*
|
||||
* @return self Returns the message.
|
||||
*/
|
||||
public function setBody(StreamInterface $body = null);
|
||||
|
||||
/**
|
||||
* Get the body of the message
|
||||
*
|
||||
* @return StreamInterface|null
|
||||
*/
|
||||
public function getBody();
|
||||
|
||||
/**
|
||||
* Gets all message headers.
|
||||
*
|
||||
* The keys represent the header name as it will be sent over the wire, and
|
||||
* each value is an array of strings associated with the header.
|
||||
*
|
||||
* // Represent the headers as a string
|
||||
* foreach ($message->getHeaders() as $name => $values) {
|
||||
* echo $name . ": " . implode(", ", $values);
|
||||
* }
|
||||
*
|
||||
* @return array Returns an associative array of the message's headers.
|
||||
*/
|
||||
public function getHeaders();
|
||||
|
||||
/**
|
||||
* Retrieve a header by the given case-insensitive name.
|
||||
*
|
||||
* By default, this method returns all of the header values of the given
|
||||
* case-insensitive header name as a string concatenated together using
|
||||
* a comma. Because some header should not be concatenated together using a
|
||||
* comma, this method provides a Boolean argument that can be used to
|
||||
* retrieve the associated header values as an array of strings.
|
||||
*
|
||||
* @param string $header Case-insensitive header name.
|
||||
* @param bool $asArray Set to true to retrieve the header value as an
|
||||
* array of strings.
|
||||
*
|
||||
* @return array|string
|
||||
*/
|
||||
public function getHeader($header, $asArray = false);
|
||||
|
||||
/**
|
||||
* Checks if a header exists by the given case-insensitive name.
|
||||
*
|
||||
* @param string $header Case-insensitive header name.
|
||||
*
|
||||
* @return bool Returns true if any header names match the given header
|
||||
* name using a case-insensitive string comparison. Returns false if
|
||||
* no matching header name is found in the message.
|
||||
*/
|
||||
public function hasHeader($header);
|
||||
|
||||
/**
|
||||
* Remove a specific header by case-insensitive name.
|
||||
*
|
||||
* @param string $header Case-insensitive header name.
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function removeHeader($header);
|
||||
|
||||
/**
|
||||
* Appends a header value to any existing values associated with the
|
||||
* given header name.
|
||||
*
|
||||
* @param string $header Header name to add
|
||||
* @param string $value Value of the header
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function addHeader($header, $value);
|
||||
|
||||
/**
|
||||
* Merges in an associative array of headers.
|
||||
*
|
||||
* Each array key MUST be a string representing the case-insensitive name
|
||||
* of a header. Each value MUST be either a string or an array of strings.
|
||||
* For each value, the value is appended to any existing header of the same
|
||||
* name, or, if a header does not already exist by the given name, then the
|
||||
* header is added.
|
||||
*
|
||||
* @param array $headers Associative array of headers to add to the message
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function addHeaders(array $headers);
|
||||
|
||||
/**
|
||||
* Sets a header, replacing any existing values of any headers with the
|
||||
* same case-insensitive name.
|
||||
*
|
||||
* The header values MUST be a string or an array of strings.
|
||||
*
|
||||
* @param string $header Header name
|
||||
* @param string|array $value Header value(s)
|
||||
*
|
||||
* @return self Returns the message.
|
||||
*/
|
||||
public function setHeader($header, $value);
|
||||
|
||||
/**
|
||||
* Sets headers, replacing any headers that have already been set on the
|
||||
* message.
|
||||
*
|
||||
* The array keys MUST be a string. The array values must be either a
|
||||
* string or an array of strings.
|
||||
*
|
||||
* @param array $headers Headers to set.
|
||||
*
|
||||
* @return self Returns the message.
|
||||
*/
|
||||
public function setHeaders(array $headers);
|
||||
}
|
|
@ -1,172 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Message;
|
||||
|
||||
/**
|
||||
* Request and response parser used by Guzzle
|
||||
*/
|
||||
class MessageParser
|
||||
{
|
||||
/**
|
||||
* Parse an HTTP request message into an associative array of parts.
|
||||
*
|
||||
* @param string $message HTTP request to parse
|
||||
*
|
||||
* @return array|bool Returns false if the message is invalid
|
||||
*/
|
||||
public function parseRequest($message)
|
||||
{
|
||||
if (!($parts = $this->parseMessage($message))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Parse the protocol and protocol version
|
||||
if (isset($parts['start_line'][2])) {
|
||||
$startParts = explode('/', $parts['start_line'][2]);
|
||||
$protocol = strtoupper($startParts[0]);
|
||||
$version = isset($startParts[1]) ? $startParts[1] : '1.1';
|
||||
} else {
|
||||
$protocol = 'HTTP';
|
||||
$version = '1.1';
|
||||
}
|
||||
|
||||
$parsed = [
|
||||
'method' => strtoupper($parts['start_line'][0]),
|
||||
'protocol' => $protocol,
|
||||
'protocol_version' => $version,
|
||||
'headers' => $parts['headers'],
|
||||
'body' => $parts['body']
|
||||
];
|
||||
|
||||
$parsed['request_url'] = $this->getUrlPartsFromMessage(
|
||||
(isset($parts['start_line'][1]) ? $parts['start_line'][1] : ''), $parsed);
|
||||
|
||||
return $parsed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse an HTTP response message into an associative array of parts.
|
||||
*
|
||||
* @param string $message HTTP response to parse
|
||||
*
|
||||
* @return array|bool Returns false if the message is invalid
|
||||
*/
|
||||
public function parseResponse($message)
|
||||
{
|
||||
if (!($parts = $this->parseMessage($message))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
list($protocol, $version) = explode('/', trim($parts['start_line'][0]));
|
||||
|
||||
return [
|
||||
'protocol' => $protocol,
|
||||
'protocol_version' => $version,
|
||||
'code' => $parts['start_line'][1],
|
||||
'reason_phrase' => isset($parts['start_line'][2]) ? $parts['start_line'][2] : '',
|
||||
'headers' => $parts['headers'],
|
||||
'body' => $parts['body']
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a message into parts
|
||||
*
|
||||
* @param string $message Message to parse
|
||||
*
|
||||
* @return array|bool
|
||||
*/
|
||||
private function parseMessage($message)
|
||||
{
|
||||
if (!$message) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$startLine = null;
|
||||
$headers = [];
|
||||
$body = '';
|
||||
|
||||
// Iterate over each line in the message, accounting for line endings
|
||||
$lines = preg_split('/(\\r?\\n)/', $message, -1, PREG_SPLIT_DELIM_CAPTURE);
|
||||
for ($i = 0, $totalLines = count($lines); $i < $totalLines; $i += 2) {
|
||||
|
||||
$line = $lines[$i];
|
||||
|
||||
// If two line breaks were encountered, then this is the end of body
|
||||
if (empty($line)) {
|
||||
if ($i < $totalLines - 1) {
|
||||
$body = implode('', array_slice($lines, $i + 2));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Parse message headers
|
||||
if (!$startLine) {
|
||||
$startLine = explode(' ', $line, 3);
|
||||
} elseif (strpos($line, ':')) {
|
||||
$parts = explode(':', $line, 2);
|
||||
$key = trim($parts[0]);
|
||||
$value = isset($parts[1]) ? trim($parts[1]) : '';
|
||||
if (!isset($headers[$key])) {
|
||||
$headers[$key] = $value;
|
||||
} elseif (!is_array($headers[$key])) {
|
||||
$headers[$key] = [$headers[$key], $value];
|
||||
} else {
|
||||
$headers[$key][] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'start_line' => $startLine,
|
||||
'headers' => $headers,
|
||||
'body' => $body
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create URL parts from HTTP message parts
|
||||
*
|
||||
* @param string $requestUrl Associated URL
|
||||
* @param array $parts HTTP message parts
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getUrlPartsFromMessage($requestUrl, array $parts)
|
||||
{
|
||||
// Parse the URL information from the message
|
||||
$urlParts = ['path' => $requestUrl, 'scheme' => 'http'];
|
||||
|
||||
// Check for the Host header
|
||||
if (isset($parts['headers']['Host'])) {
|
||||
$urlParts['host'] = $parts['headers']['Host'];
|
||||
} elseif (isset($parts['headers']['host'])) {
|
||||
$urlParts['host'] = $parts['headers']['host'];
|
||||
} else {
|
||||
$urlParts['host'] = null;
|
||||
}
|
||||
|
||||
if (false === strpos($urlParts['host'], ':')) {
|
||||
$urlParts['port'] = '';
|
||||
} else {
|
||||
$hostParts = explode(':', $urlParts['host']);
|
||||
$urlParts['host'] = trim($hostParts[0]);
|
||||
$urlParts['port'] = (int) trim($hostParts[1]);
|
||||
if ($urlParts['port'] == 443) {
|
||||
$urlParts['scheme'] = 'https';
|
||||
}
|
||||
}
|
||||
|
||||
// Check if a query is present
|
||||
$path = $urlParts['path'];
|
||||
$qpos = strpos($path, '?');
|
||||
if ($qpos) {
|
||||
$urlParts['query'] = substr($path, $qpos + 1);
|
||||
$urlParts['path'] = substr($path, 0, $qpos);
|
||||
} else {
|
||||
$urlParts['query'] = '';
|
||||
}
|
||||
|
||||
return $urlParts;
|
||||
}
|
||||
}
|
|
@ -1,216 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Message;
|
||||
|
||||
use GuzzleHttp\Event\HasEmitterTrait;
|
||||
use GuzzleHttp\Collection;
|
||||
use GuzzleHttp\Subscriber\Prepare;
|
||||
use GuzzleHttp\Url;
|
||||
|
||||
/**
|
||||
* HTTP request class to send requests
|
||||
*/
|
||||
class Request extends AbstractMessage implements RequestInterface
|
||||
{
|
||||
use HasEmitterTrait;
|
||||
|
||||
/** @var Url HTTP Url */
|
||||
private $url;
|
||||
|
||||
/** @var string HTTP method */
|
||||
private $method;
|
||||
|
||||
/** @var Collection Transfer options */
|
||||
private $transferOptions;
|
||||
|
||||
/**
|
||||
* @param string $method HTTP method
|
||||
* @param string|Url $url HTTP URL to connect to. The URI scheme,
|
||||
* host header, and URI are parsed from the full URL. If query string
|
||||
* parameters are present they will be parsed as well.
|
||||
* @param array|Collection $headers HTTP headers
|
||||
* @param mixed $body Body to send with the request
|
||||
* @param array $options Array of options to use with the request
|
||||
* - emitter: Event emitter to use with the request
|
||||
*/
|
||||
public function __construct(
|
||||
$method,
|
||||
$url,
|
||||
$headers = [],
|
||||
$body = null,
|
||||
array $options = []
|
||||
) {
|
||||
$this->setUrl($url);
|
||||
$this->method = strtoupper($method);
|
||||
$this->handleOptions($options);
|
||||
$this->transferOptions = new Collection($options);
|
||||
$this->addPrepareEvent();
|
||||
|
||||
if ($body !== null) {
|
||||
$this->setBody($body);
|
||||
}
|
||||
|
||||
if ($headers) {
|
||||
foreach ($headers as $key => $value) {
|
||||
$this->setHeader($key, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function __clone()
|
||||
{
|
||||
if ($this->emitter) {
|
||||
$this->emitter = clone $this->emitter;
|
||||
}
|
||||
$this->transferOptions = clone $this->transferOptions;
|
||||
$this->url = clone $this->url;
|
||||
}
|
||||
|
||||
public function setUrl($url)
|
||||
{
|
||||
$this->url = $url instanceof Url ? $url : Url::fromString($url);
|
||||
$this->updateHostHeaderFromUrl();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getUrl()
|
||||
{
|
||||
return (string) $this->url;
|
||||
}
|
||||
|
||||
public function setQuery($query)
|
||||
{
|
||||
$this->url->setQuery($query);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getQuery()
|
||||
{
|
||||
return $this->url->getQuery();
|
||||
}
|
||||
|
||||
public function setMethod($method)
|
||||
{
|
||||
$this->method = strtoupper($method);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getMethod()
|
||||
{
|
||||
return $this->method;
|
||||
}
|
||||
|
||||
public function getScheme()
|
||||
{
|
||||
return $this->url->getScheme();
|
||||
}
|
||||
|
||||
public function setScheme($scheme)
|
||||
{
|
||||
$this->url->setScheme($scheme);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getPort()
|
||||
{
|
||||
return $this->url->getPort();
|
||||
}
|
||||
|
||||
public function setPort($port)
|
||||
{
|
||||
$this->url->setPort($port);
|
||||
$this->updateHostHeaderFromUrl();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getHost()
|
||||
{
|
||||
return $this->url->getHost();
|
||||
}
|
||||
|
||||
public function setHost($host)
|
||||
{
|
||||
$this->url->setHost($host);
|
||||
$this->updateHostHeaderFromUrl();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getPath()
|
||||
{
|
||||
return '/' . ltrim($this->url->getPath(), '/');
|
||||
}
|
||||
|
||||
public function setPath($path)
|
||||
{
|
||||
$this->url->setPath($path);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getResource()
|
||||
{
|
||||
$resource = $this->getPath();
|
||||
if ($query = (string) $this->url->getQuery()) {
|
||||
$resource .= '?' . $query;
|
||||
}
|
||||
|
||||
return $resource;
|
||||
}
|
||||
|
||||
public function getConfig()
|
||||
{
|
||||
return $this->transferOptions;
|
||||
}
|
||||
|
||||
protected function handleOptions(array &$options)
|
||||
{
|
||||
parent::handleOptions($options);
|
||||
// Use a custom emitter if one is specified, and remove it from
|
||||
// options that are exposed through getConfig()
|
||||
if (isset($options['emitter'])) {
|
||||
$this->emitter = $options['emitter'];
|
||||
unset($options['emitter']);
|
||||
}
|
||||
}
|
||||
|
||||
protected function getStartLine()
|
||||
{
|
||||
return trim($this->method . ' ' . $this->getResource())
|
||||
. ' HTTP/' . $this->getProtocolVersion();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a subscriber that ensures a request's body is prepared before
|
||||
* sending.
|
||||
*/
|
||||
private function addPrepareEvent()
|
||||
{
|
||||
static $subscriber;
|
||||
if (!$subscriber) {
|
||||
$subscriber = new Prepare();
|
||||
}
|
||||
|
||||
$this->getEmitter()->attach($subscriber);
|
||||
}
|
||||
|
||||
private function updateHostHeaderFromUrl()
|
||||
{
|
||||
$port = $this->url->getPort();
|
||||
$scheme = $this->url->getScheme();
|
||||
if ($host = $this->url->getHost()) {
|
||||
if (($port == 80 && $scheme == 'http') ||
|
||||
($port == 443 && $scheme == 'https')
|
||||
) {
|
||||
$this->setHeader('Host', $host);
|
||||
} else {
|
||||
$this->setHeader('Host', "{$host}:{$port}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,150 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Message;
|
||||
|
||||
use GuzzleHttp\Event\HasEmitterInterface;
|
||||
use GuzzleHttp\Query;
|
||||
|
||||
/**
|
||||
* Generic HTTP request interface
|
||||
*/
|
||||
interface RequestInterface extends MessageInterface, HasEmitterInterface
|
||||
{
|
||||
/**
|
||||
* Sets the request URL.
|
||||
*
|
||||
* The URL MUST be a string, or an object that implements the
|
||||
* `__toString()` method.
|
||||
*
|
||||
* @param string $url Request URL.
|
||||
*
|
||||
* @return self Reference to the request.
|
||||
* @throws \InvalidArgumentException If the URL is invalid.
|
||||
*/
|
||||
public function setUrl($url);
|
||||
|
||||
/**
|
||||
* Gets the request URL as a string.
|
||||
*
|
||||
* @return string Returns the URL as a string.
|
||||
*/
|
||||
public function getUrl();
|
||||
|
||||
/**
|
||||
* Get the resource part of the the request, including the path, query
|
||||
* string, and fragment.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getResource();
|
||||
|
||||
/**
|
||||
* Get the collection of key value pairs that will be used as the query
|
||||
* string in the request.
|
||||
*
|
||||
* @return Query
|
||||
*/
|
||||
public function getQuery();
|
||||
|
||||
/**
|
||||
* Set the query string used by the request
|
||||
*
|
||||
* @param array|Query $query Query to set
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setQuery($query);
|
||||
|
||||
/**
|
||||
* Get the HTTP method of the request.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getMethod();
|
||||
|
||||
/**
|
||||
* Set the HTTP method of the request.
|
||||
*
|
||||
* @param string $method HTTP method
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setMethod($method);
|
||||
|
||||
/**
|
||||
* Get the URI scheme of the request (http, https, etc.).
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getScheme();
|
||||
|
||||
/**
|
||||
* Set the URI scheme of the request (http, https, etc.).
|
||||
*
|
||||
* @param string $scheme Scheme to set
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setScheme($scheme);
|
||||
|
||||
/**
|
||||
* Get the port scheme of the request (e.g., 80, 443, etc.).
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getPort();
|
||||
|
||||
/**
|
||||
* Set the port of the request.
|
||||
*
|
||||
* Setting a port modifies the Host header of a request as necessary.
|
||||
*
|
||||
* @param int $port Port to set
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setPort($port);
|
||||
|
||||
/**
|
||||
* Get the host of the request.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getHost();
|
||||
|
||||
/**
|
||||
* Set the host of the request including an optional port.
|
||||
*
|
||||
* Including a port in the host argument will explicitly change the port of
|
||||
* the request. If no port is found, the default port of the current
|
||||
* request scheme will be utilized.
|
||||
*
|
||||
* @param string $host Host to set (e.g. www.yahoo.com, www.yahoo.com:80)
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setHost($host);
|
||||
|
||||
/**
|
||||
* Get the path of the request (e.g. '/', '/index.html').
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPath();
|
||||
|
||||
/**
|
||||
* Set the path of the request (e.g. '/', '/index.html').
|
||||
*
|
||||
* @param string|array $path Path to set or array of segments to implode
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setPath($path);
|
||||
|
||||
/**
|
||||
* Get the request's configuration options.
|
||||
*
|
||||
* @return \GuzzleHttp\Collection
|
||||
*/
|
||||
public function getConfig();
|
||||
}
|
|
@ -1,202 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Message;
|
||||
|
||||
use GuzzleHttp\Exception\ParseException;
|
||||
use GuzzleHttp\Stream\StreamInterface;
|
||||
|
||||
/**
|
||||
* Guzzle HTTP response object
|
||||
*/
|
||||
class Response extends AbstractMessage implements ResponseInterface
|
||||
{
|
||||
/** @var array Mapping of status codes to reason phrases */
|
||||
private static $statusTexts = array(
|
||||
100 => 'Continue',
|
||||
101 => 'Switching Protocols',
|
||||
102 => 'Processing',
|
||||
200 => 'OK',
|
||||
201 => 'Created',
|
||||
202 => 'Accepted',
|
||||
203 => 'Non-Authoritative Information',
|
||||
204 => 'No Content',
|
||||
205 => 'Reset Content',
|
||||
206 => 'Partial Content',
|
||||
207 => 'Multi-Status',
|
||||
208 => 'Already Reported',
|
||||
226 => 'IM Used',
|
||||
300 => 'Multiple Choices',
|
||||
301 => 'Moved Permanently',
|
||||
302 => 'Found',
|
||||
303 => 'See Other',
|
||||
304 => 'Not Modified',
|
||||
305 => 'Use Proxy',
|
||||
307 => 'Temporary Redirect',
|
||||
308 => 'Permanent Redirect',
|
||||
400 => 'Bad Request',
|
||||
401 => 'Unauthorized',
|
||||
402 => 'Payment Required',
|
||||
403 => 'Forbidden',
|
||||
404 => 'Not Found',
|
||||
405 => 'Method Not Allowed',
|
||||
406 => 'Not Acceptable',
|
||||
407 => 'Proxy Authentication Required',
|
||||
408 => 'Request Timeout',
|
||||
409 => 'Conflict',
|
||||
410 => 'Gone',
|
||||
411 => 'Length Required',
|
||||
412 => 'Precondition Failed',
|
||||
413 => 'Request Entity Too Large',
|
||||
414 => 'Request-URI Too Long',
|
||||
415 => 'Unsupported Media Type',
|
||||
416 => 'Requested Range Not Satisfiable',
|
||||
417 => 'Expectation Failed',
|
||||
422 => 'Unprocessable Entity',
|
||||
423 => 'Locked',
|
||||
424 => 'Failed Dependency',
|
||||
425 => 'Reserved for WebDAV advanced collections expired proposal',
|
||||
426 => 'Upgrade required',
|
||||
428 => 'Precondition Required',
|
||||
429 => 'Too Many Requests',
|
||||
431 => 'Request Header Fields Too Large',
|
||||
500 => 'Internal Server Error',
|
||||
501 => 'Not Implemented',
|
||||
502 => 'Bad Gateway',
|
||||
503 => 'Service Unavailable',
|
||||
504 => 'Gateway Timeout',
|
||||
505 => 'HTTP Version Not Supported',
|
||||
506 => 'Variant Also Negotiates (Experimental)',
|
||||
507 => 'Insufficient Storage',
|
||||
508 => 'Loop Detected',
|
||||
510 => 'Not Extended',
|
||||
511 => 'Network Authentication Required',
|
||||
);
|
||||
|
||||
/** @var string The reason phrase of the response (human readable code) */
|
||||
private $reasonPhrase;
|
||||
|
||||
/** @var string The status code of the response */
|
||||
private $statusCode;
|
||||
|
||||
/** @var string The effective URL that returned this response */
|
||||
private $effectiveUrl;
|
||||
|
||||
/**
|
||||
* @param string $statusCode The response status code (e.g. 200)
|
||||
* @param array $headers The response headers
|
||||
* @param StreamInterface $body The body of the response
|
||||
* @param array $options Response message options
|
||||
* - reason_phrase: Set a custom reason phrase
|
||||
* - protocol_version: Set a custom protocol version
|
||||
*/
|
||||
public function __construct(
|
||||
$statusCode,
|
||||
array $headers = [],
|
||||
StreamInterface $body = null,
|
||||
array $options = []
|
||||
) {
|
||||
$this->statusCode = (string) $statusCode;
|
||||
$this->handleOptions($options);
|
||||
|
||||
// Assume a reason phrase if one was not applied as an option
|
||||
if (!$this->reasonPhrase &&
|
||||
isset(self::$statusTexts[$this->statusCode])
|
||||
) {
|
||||
$this->reasonPhrase = self::$statusTexts[$this->statusCode];
|
||||
}
|
||||
|
||||
if ($headers) {
|
||||
$this->setHeaders($headers);
|
||||
}
|
||||
|
||||
if ($body) {
|
||||
$this->setBody($body);
|
||||
}
|
||||
}
|
||||
|
||||
public function getStatusCode()
|
||||
{
|
||||
return $this->statusCode;
|
||||
}
|
||||
|
||||
public function getReasonPhrase()
|
||||
{
|
||||
return $this->reasonPhrase;
|
||||
}
|
||||
|
||||
public function json(array $config = [])
|
||||
{
|
||||
try {
|
||||
return \GuzzleHttp\json_decode(
|
||||
(string) $this->getBody(),
|
||||
isset($config['object']) ? !$config['object'] : true,
|
||||
512,
|
||||
isset($config['big_int_strings']) ? JSON_BIGINT_AS_STRING : 0
|
||||
);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
throw new ParseException(
|
||||
$e->getMessage(),
|
||||
$this
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public function xml(array $config = [])
|
||||
{
|
||||
$disableEntities = libxml_disable_entity_loader(true);
|
||||
$internalErrors = libxml_use_internal_errors(true);
|
||||
|
||||
try {
|
||||
// Allow XML to be retrieved even if there is no response body
|
||||
$xml = new \SimpleXMLElement(
|
||||
(string) $this->getBody() ?: '<root />',
|
||||
LIBXML_NONET,
|
||||
isset($config['ns']) ? $config['ns'] : '',
|
||||
isset($config['ns_is_prefix']) ? $config['ns_is_prefix'] : false
|
||||
);
|
||||
libxml_disable_entity_loader($disableEntities);
|
||||
libxml_use_internal_errors($internalErrors);
|
||||
} catch (\Exception $e) {
|
||||
libxml_disable_entity_loader($disableEntities);
|
||||
libxml_use_internal_errors($internalErrors);
|
||||
throw new ParseException(
|
||||
'Unable to parse response body into XML: ' . $e->getMessage(),
|
||||
$this
|
||||
);
|
||||
}
|
||||
|
||||
return $xml;
|
||||
}
|
||||
|
||||
public function getEffectiveUrl()
|
||||
{
|
||||
return $this->effectiveUrl;
|
||||
}
|
||||
|
||||
public function setEffectiveUrl($url)
|
||||
{
|
||||
$this->effectiveUrl = $url;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accepts and modifies the options provided to the response in the
|
||||
* constructor.
|
||||
*
|
||||
* @param array $options Options array passed by reference.
|
||||
*/
|
||||
protected function handleOptions(array &$options = [])
|
||||
{
|
||||
parent::handleOptions($options);
|
||||
if (isset($options['reason_phrase'])) {
|
||||
$this->reasonPhrase = $options['reason_phrase'];
|
||||
}
|
||||
}
|
||||
|
||||
protected function getStartLine()
|
||||
{
|
||||
return 'HTTP/' . $this->getProtocolVersion()
|
||||
. " {$this->statusCode} {$this->reasonPhrase}";
|
||||
}
|
||||
}
|
|
@ -1,86 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Message;
|
||||
|
||||
/**
|
||||
* Represents an HTTP response message.
|
||||
*/
|
||||
interface ResponseInterface extends MessageInterface
|
||||
{
|
||||
/**
|
||||
* Get the response status code (e.g. "200", "404", etc.)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getStatusCode();
|
||||
|
||||
/**
|
||||
* Get the response reason phrase- a human readable version of the numeric
|
||||
* status code
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getReasonPhrase();
|
||||
|
||||
/**
|
||||
* Get the effective URL that resulted in this response (e.g. the last
|
||||
* redirect URL).
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getEffectiveUrl();
|
||||
|
||||
/**
|
||||
* Set the effective URL that resulted in this response (e.g. the last
|
||||
* redirect URL).
|
||||
*
|
||||
* @param string $url Effective URL
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setEffectiveUrl($url);
|
||||
|
||||
/**
|
||||
* Parse the JSON response body and return the JSON decoded data.
|
||||
*
|
||||
* @param array $config Associative array of configuration settings used
|
||||
* to control how the JSON data is parsed. Concrete implementations MAY
|
||||
* add further configuration settings as needed, but they MUST implement
|
||||
* functionality for the following options:
|
||||
*
|
||||
* - object: Set to true to parse JSON objects as PHP objects rather
|
||||
* than associative arrays. Defaults to false.
|
||||
* - big_int_strings: When set to true, large integers are converted to
|
||||
* strings rather than floats. Defaults to false.
|
||||
*
|
||||
* Implementations are free to add further configuration settings as
|
||||
* needed.
|
||||
*
|
||||
* @return mixed Returns the JSON decoded data based on the provided
|
||||
* parse settings.
|
||||
* @throws \RuntimeException if the response body is not in JSON format
|
||||
*/
|
||||
public function json(array $config = []);
|
||||
|
||||
/**
|
||||
* Parse the XML response body and return a \SimpleXMLElement.
|
||||
*
|
||||
* In order to prevent XXE attacks, this method disables loading external
|
||||
* entities. If you rely on external entities, then you must parse the
|
||||
* XML response manually by accessing the response body directly.
|
||||
*
|
||||
* @param array $config Associative array of configuration settings used
|
||||
* to control how the XML is parsed. Concrete implementations MAY add
|
||||
* further configuration settings as needed, but they MUST implement
|
||||
* functionality for the following options:
|
||||
*
|
||||
* - ns: Set to a string to represent the namespace prefix or URI
|
||||
* - ns_is_prefix: Set to true to specify that the NS is a prefix rather
|
||||
* than a URI (defaults to false).
|
||||
*
|
||||
* @return \SimpleXMLElement
|
||||
* @throws \RuntimeException if the response body is not in XML format
|
||||
* @link http://websec.io/2012/08/27/Preventing-XXE-in-PHP.html
|
||||
*/
|
||||
public function xml(array $config = []);
|
||||
}
|
|
@ -1,964 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp;
|
||||
|
||||
/**
|
||||
* Provides mappings of file extensions to mimetypes
|
||||
* @link http://svn.apache.org/repos/asf/httpd/httpd/branches/1.3.x/conf/mime.types
|
||||
*/
|
||||
class Mimetypes
|
||||
{
|
||||
/** @var self */
|
||||
protected static $instance;
|
||||
|
||||
/** @var array Mapping of extension to mimetype */
|
||||
protected $mimetypes = array(
|
||||
'3dml' => 'text/vnd.in3d.3dml',
|
||||
'3g2' => 'video/3gpp2',
|
||||
'3gp' => 'video/3gpp',
|
||||
'7z' => 'application/x-7z-compressed',
|
||||
'aab' => 'application/x-authorware-bin',
|
||||
'aac' => 'audio/x-aac',
|
||||
'aam' => 'application/x-authorware-map',
|
||||
'aas' => 'application/x-authorware-seg',
|
||||
'abw' => 'application/x-abiword',
|
||||
'ac' => 'application/pkix-attr-cert',
|
||||
'acc' => 'application/vnd.americandynamics.acc',
|
||||
'ace' => 'application/x-ace-compressed',
|
||||
'acu' => 'application/vnd.acucobol',
|
||||
'acutc' => 'application/vnd.acucorp',
|
||||
'adp' => 'audio/adpcm',
|
||||
'aep' => 'application/vnd.audiograph',
|
||||
'afm' => 'application/x-font-type1',
|
||||
'afp' => 'application/vnd.ibm.modcap',
|
||||
'ahead' => 'application/vnd.ahead.space',
|
||||
'ai' => 'application/postscript',
|
||||
'aif' => 'audio/x-aiff',
|
||||
'aifc' => 'audio/x-aiff',
|
||||
'aiff' => 'audio/x-aiff',
|
||||
'air' => 'application/vnd.adobe.air-application-installer-package+zip',
|
||||
'ait' => 'application/vnd.dvb.ait',
|
||||
'ami' => 'application/vnd.amiga.ami',
|
||||
'apk' => 'application/vnd.android.package-archive',
|
||||
'application' => 'application/x-ms-application',
|
||||
'apr' => 'application/vnd.lotus-approach',
|
||||
'asa' => 'text/plain',
|
||||
'asax' => 'application/octet-stream',
|
||||
'asc' => 'application/pgp-signature',
|
||||
'ascx' => 'text/plain',
|
||||
'asf' => 'video/x-ms-asf',
|
||||
'ashx' => 'text/plain',
|
||||
'asm' => 'text/x-asm',
|
||||
'asmx' => 'text/plain',
|
||||
'aso' => 'application/vnd.accpac.simply.aso',
|
||||
'asp' => 'text/plain',
|
||||
'aspx' => 'text/plain',
|
||||
'asx' => 'video/x-ms-asf',
|
||||
'atc' => 'application/vnd.acucorp',
|
||||
'atom' => 'application/atom+xml',
|
||||
'atomcat' => 'application/atomcat+xml',
|
||||
'atomsvc' => 'application/atomsvc+xml',
|
||||
'atx' => 'application/vnd.antix.game-component',
|
||||
'au' => 'audio/basic',
|
||||
'avi' => 'video/x-msvideo',
|
||||
'aw' => 'application/applixware',
|
||||
'axd' => 'text/plain',
|
||||
'azf' => 'application/vnd.airzip.filesecure.azf',
|
||||
'azs' => 'application/vnd.airzip.filesecure.azs',
|
||||
'azw' => 'application/vnd.amazon.ebook',
|
||||
'bat' => 'application/x-msdownload',
|
||||
'bcpio' => 'application/x-bcpio',
|
||||
'bdf' => 'application/x-font-bdf',
|
||||
'bdm' => 'application/vnd.syncml.dm+wbxml',
|
||||
'bed' => 'application/vnd.realvnc.bed',
|
||||
'bh2' => 'application/vnd.fujitsu.oasysprs',
|
||||
'bin' => 'application/octet-stream',
|
||||
'bmi' => 'application/vnd.bmi',
|
||||
'bmp' => 'image/bmp',
|
||||
'book' => 'application/vnd.framemaker',
|
||||
'box' => 'application/vnd.previewsystems.box',
|
||||
'boz' => 'application/x-bzip2',
|
||||
'bpk' => 'application/octet-stream',
|
||||
'btif' => 'image/prs.btif',
|
||||
'bz' => 'application/x-bzip',
|
||||
'bz2' => 'application/x-bzip2',
|
||||
'c' => 'text/x-c',
|
||||
'c11amc' => 'application/vnd.cluetrust.cartomobile-config',
|
||||
'c11amz' => 'application/vnd.cluetrust.cartomobile-config-pkg',
|
||||
'c4d' => 'application/vnd.clonk.c4group',
|
||||
'c4f' => 'application/vnd.clonk.c4group',
|
||||
'c4g' => 'application/vnd.clonk.c4group',
|
||||
'c4p' => 'application/vnd.clonk.c4group',
|
||||
'c4u' => 'application/vnd.clonk.c4group',
|
||||
'cab' => 'application/vnd.ms-cab-compressed',
|
||||
'car' => 'application/vnd.curl.car',
|
||||
'cat' => 'application/vnd.ms-pki.seccat',
|
||||
'cc' => 'text/x-c',
|
||||
'cct' => 'application/x-director',
|
||||
'ccxml' => 'application/ccxml+xml',
|
||||
'cdbcmsg' => 'application/vnd.contact.cmsg',
|
||||
'cdf' => 'application/x-netcdf',
|
||||
'cdkey' => 'application/vnd.mediastation.cdkey',
|
||||
'cdmia' => 'application/cdmi-capability',
|
||||
'cdmic' => 'application/cdmi-container',
|
||||
'cdmid' => 'application/cdmi-domain',
|
||||
'cdmio' => 'application/cdmi-object',
|
||||
'cdmiq' => 'application/cdmi-queue',
|
||||
'cdx' => 'chemical/x-cdx',
|
||||
'cdxml' => 'application/vnd.chemdraw+xml',
|
||||
'cdy' => 'application/vnd.cinderella',
|
||||
'cer' => 'application/pkix-cert',
|
||||
'cfc' => 'application/x-coldfusion',
|
||||
'cfm' => 'application/x-coldfusion',
|
||||
'cgm' => 'image/cgm',
|
||||
'chat' => 'application/x-chat',
|
||||
'chm' => 'application/vnd.ms-htmlhelp',
|
||||
'chrt' => 'application/vnd.kde.kchart',
|
||||
'cif' => 'chemical/x-cif',
|
||||
'cii' => 'application/vnd.anser-web-certificate-issue-initiation',
|
||||
'cil' => 'application/vnd.ms-artgalry',
|
||||
'cla' => 'application/vnd.claymore',
|
||||
'class' => 'application/java-vm',
|
||||
'clkk' => 'application/vnd.crick.clicker.keyboard',
|
||||
'clkp' => 'application/vnd.crick.clicker.palette',
|
||||
'clkt' => 'application/vnd.crick.clicker.template',
|
||||
'clkw' => 'application/vnd.crick.clicker.wordbank',
|
||||
'clkx' => 'application/vnd.crick.clicker',
|
||||
'clp' => 'application/x-msclip',
|
||||
'cmc' => 'application/vnd.cosmocaller',
|
||||
'cmdf' => 'chemical/x-cmdf',
|
||||
'cml' => 'chemical/x-cml',
|
||||
'cmp' => 'application/vnd.yellowriver-custom-menu',
|
||||
'cmx' => 'image/x-cmx',
|
||||
'cod' => 'application/vnd.rim.cod',
|
||||
'com' => 'application/x-msdownload',
|
||||
'conf' => 'text/plain',
|
||||
'cpio' => 'application/x-cpio',
|
||||
'cpp' => 'text/x-c',
|
||||
'cpt' => 'application/mac-compactpro',
|
||||
'crd' => 'application/x-mscardfile',
|
||||
'crl' => 'application/pkix-crl',
|
||||
'crt' => 'application/x-x509-ca-cert',
|
||||
'cryptonote' => 'application/vnd.rig.cryptonote',
|
||||
'cs' => 'text/plain',
|
||||
'csh' => 'application/x-csh',
|
||||
'csml' => 'chemical/x-csml',
|
||||
'csp' => 'application/vnd.commonspace',
|
||||
'css' => 'text/css',
|
||||
'cst' => 'application/x-director',
|
||||
'csv' => 'text/csv',
|
||||
'cu' => 'application/cu-seeme',
|
||||
'curl' => 'text/vnd.curl',
|
||||
'cww' => 'application/prs.cww',
|
||||
'cxt' => 'application/x-director',
|
||||
'cxx' => 'text/x-c',
|
||||
'dae' => 'model/vnd.collada+xml',
|
||||
'daf' => 'application/vnd.mobius.daf',
|
||||
'dataless' => 'application/vnd.fdsn.seed',
|
||||
'davmount' => 'application/davmount+xml',
|
||||
'dcr' => 'application/x-director',
|
||||
'dcurl' => 'text/vnd.curl.dcurl',
|
||||
'dd2' => 'application/vnd.oma.dd2+xml',
|
||||
'ddd' => 'application/vnd.fujixerox.ddd',
|
||||
'deb' => 'application/x-debian-package',
|
||||
'def' => 'text/plain',
|
||||
'deploy' => 'application/octet-stream',
|
||||
'der' => 'application/x-x509-ca-cert',
|
||||
'dfac' => 'application/vnd.dreamfactory',
|
||||
'dic' => 'text/x-c',
|
||||
'dir' => 'application/x-director',
|
||||
'dis' => 'application/vnd.mobius.dis',
|
||||
'dist' => 'application/octet-stream',
|
||||
'distz' => 'application/octet-stream',
|
||||
'djv' => 'image/vnd.djvu',
|
||||
'djvu' => 'image/vnd.djvu',
|
||||
'dll' => 'application/x-msdownload',
|
||||
'dmg' => 'application/octet-stream',
|
||||
'dms' => 'application/octet-stream',
|
||||
'dna' => 'application/vnd.dna',
|
||||
'doc' => 'application/msword',
|
||||
'docm' => 'application/vnd.ms-word.document.macroenabled.12',
|
||||
'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
||||
'dot' => 'application/msword',
|
||||
'dotm' => 'application/vnd.ms-word.template.macroenabled.12',
|
||||
'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
|
||||
'dp' => 'application/vnd.osgi.dp',
|
||||
'dpg' => 'application/vnd.dpgraph',
|
||||
'dra' => 'audio/vnd.dra',
|
||||
'dsc' => 'text/prs.lines.tag',
|
||||
'dssc' => 'application/dssc+der',
|
||||
'dtb' => 'application/x-dtbook+xml',
|
||||
'dtd' => 'application/xml-dtd',
|
||||
'dts' => 'audio/vnd.dts',
|
||||
'dtshd' => 'audio/vnd.dts.hd',
|
||||
'dump' => 'application/octet-stream',
|
||||
'dvi' => 'application/x-dvi',
|
||||
'dwf' => 'model/vnd.dwf',
|
||||
'dwg' => 'image/vnd.dwg',
|
||||
'dxf' => 'image/vnd.dxf',
|
||||
'dxp' => 'application/vnd.spotfire.dxp',
|
||||
'dxr' => 'application/x-director',
|
||||
'ecelp4800' => 'audio/vnd.nuera.ecelp4800',
|
||||
'ecelp7470' => 'audio/vnd.nuera.ecelp7470',
|
||||
'ecelp9600' => 'audio/vnd.nuera.ecelp9600',
|
||||
'ecma' => 'application/ecmascript',
|
||||
'edm' => 'application/vnd.novadigm.edm',
|
||||
'edx' => 'application/vnd.novadigm.edx',
|
||||
'efif' => 'application/vnd.picsel',
|
||||
'ei6' => 'application/vnd.pg.osasli',
|
||||
'elc' => 'application/octet-stream',
|
||||
'eml' => 'message/rfc822',
|
||||
'emma' => 'application/emma+xml',
|
||||
'eol' => 'audio/vnd.digital-winds',
|
||||
'eot' => 'application/vnd.ms-fontobject',
|
||||
'eps' => 'application/postscript',
|
||||
'epub' => 'application/epub+zip',
|
||||
'es3' => 'application/vnd.eszigno3+xml',
|
||||
'esf' => 'application/vnd.epson.esf',
|
||||
'et3' => 'application/vnd.eszigno3+xml',
|
||||
'etx' => 'text/x-setext',
|
||||
'exe' => 'application/x-msdownload',
|
||||
'exi' => 'application/exi',
|
||||
'ext' => 'application/vnd.novadigm.ext',
|
||||
'ez' => 'application/andrew-inset',
|
||||
'ez2' => 'application/vnd.ezpix-album',
|
||||
'ez3' => 'application/vnd.ezpix-package',
|
||||
'f' => 'text/x-fortran',
|
||||
'f4v' => 'video/x-f4v',
|
||||
'f77' => 'text/x-fortran',
|
||||
'f90' => 'text/x-fortran',
|
||||
'fbs' => 'image/vnd.fastbidsheet',
|
||||
'fcs' => 'application/vnd.isac.fcs',
|
||||
'fdf' => 'application/vnd.fdf',
|
||||
'fe_launch' => 'application/vnd.denovo.fcselayout-link',
|
||||
'fg5' => 'application/vnd.fujitsu.oasysgp',
|
||||
'fgd' => 'application/x-director',
|
||||
'fh' => 'image/x-freehand',
|
||||
'fh4' => 'image/x-freehand',
|
||||
'fh5' => 'image/x-freehand',
|
||||
'fh7' => 'image/x-freehand',
|
||||
'fhc' => 'image/x-freehand',
|
||||
'fig' => 'application/x-xfig',
|
||||
'fli' => 'video/x-fli',
|
||||
'flo' => 'application/vnd.micrografx.flo',
|
||||
'flv' => 'video/x-flv',
|
||||
'flw' => 'application/vnd.kde.kivio',
|
||||
'flx' => 'text/vnd.fmi.flexstor',
|
||||
'fly' => 'text/vnd.fly',
|
||||
'fm' => 'application/vnd.framemaker',
|
||||
'fnc' => 'application/vnd.frogans.fnc',
|
||||
'for' => 'text/x-fortran',
|
||||
'fpx' => 'image/vnd.fpx',
|
||||
'frame' => 'application/vnd.framemaker',
|
||||
'fsc' => 'application/vnd.fsc.weblaunch',
|
||||
'fst' => 'image/vnd.fst',
|
||||
'ftc' => 'application/vnd.fluxtime.clip',
|
||||
'fti' => 'application/vnd.anser-web-funds-transfer-initiation',
|
||||
'fvt' => 'video/vnd.fvt',
|
||||
'fxp' => 'application/vnd.adobe.fxp',
|
||||
'fxpl' => 'application/vnd.adobe.fxp',
|
||||
'fzs' => 'application/vnd.fuzzysheet',
|
||||
'g2w' => 'application/vnd.geoplan',
|
||||
'g3' => 'image/g3fax',
|
||||
'g3w' => 'application/vnd.geospace',
|
||||
'gac' => 'application/vnd.groove-account',
|
||||
'gdl' => 'model/vnd.gdl',
|
||||
'geo' => 'application/vnd.dynageo',
|
||||
'gex' => 'application/vnd.geometry-explorer',
|
||||
'ggb' => 'application/vnd.geogebra.file',
|
||||
'ggt' => 'application/vnd.geogebra.tool',
|
||||
'ghf' => 'application/vnd.groove-help',
|
||||
'gif' => 'image/gif',
|
||||
'gim' => 'application/vnd.groove-identity-message',
|
||||
'gmx' => 'application/vnd.gmx',
|
||||
'gnumeric' => 'application/x-gnumeric',
|
||||
'gph' => 'application/vnd.flographit',
|
||||
'gqf' => 'application/vnd.grafeq',
|
||||
'gqs' => 'application/vnd.grafeq',
|
||||
'gram' => 'application/srgs',
|
||||
'gre' => 'application/vnd.geometry-explorer',
|
||||
'grv' => 'application/vnd.groove-injector',
|
||||
'grxml' => 'application/srgs+xml',
|
||||
'gsf' => 'application/x-font-ghostscript',
|
||||
'gtar' => 'application/x-gtar',
|
||||
'gtm' => 'application/vnd.groove-tool-message',
|
||||
'gtw' => 'model/vnd.gtw',
|
||||
'gv' => 'text/vnd.graphviz',
|
||||
'gxt' => 'application/vnd.geonext',
|
||||
'h' => 'text/x-c',
|
||||
'h261' => 'video/h261',
|
||||
'h263' => 'video/h263',
|
||||
'h264' => 'video/h264',
|
||||
'hal' => 'application/vnd.hal+xml',
|
||||
'hbci' => 'application/vnd.hbci',
|
||||
'hdf' => 'application/x-hdf',
|
||||
'hh' => 'text/x-c',
|
||||
'hlp' => 'application/winhlp',
|
||||
'hpgl' => 'application/vnd.hp-hpgl',
|
||||
'hpid' => 'application/vnd.hp-hpid',
|
||||
'hps' => 'application/vnd.hp-hps',
|
||||
'hqx' => 'application/mac-binhex40',
|
||||
'hta' => 'application/octet-stream',
|
||||
'htc' => 'text/html',
|
||||
'htke' => 'application/vnd.kenameaapp',
|
||||
'htm' => 'text/html',
|
||||
'html' => 'text/html',
|
||||
'hvd' => 'application/vnd.yamaha.hv-dic',
|
||||
'hvp' => 'application/vnd.yamaha.hv-voice',
|
||||
'hvs' => 'application/vnd.yamaha.hv-script',
|
||||
'i2g' => 'application/vnd.intergeo',
|
||||
'icc' => 'application/vnd.iccprofile',
|
||||
'ice' => 'x-conference/x-cooltalk',
|
||||
'icm' => 'application/vnd.iccprofile',
|
||||
'ico' => 'image/x-icon',
|
||||
'ics' => 'text/calendar',
|
||||
'ief' => 'image/ief',
|
||||
'ifb' => 'text/calendar',
|
||||
'ifm' => 'application/vnd.shana.informed.formdata',
|
||||
'iges' => 'model/iges',
|
||||
'igl' => 'application/vnd.igloader',
|
||||
'igm' => 'application/vnd.insors.igm',
|
||||
'igs' => 'model/iges',
|
||||
'igx' => 'application/vnd.micrografx.igx',
|
||||
'iif' => 'application/vnd.shana.informed.interchange',
|
||||
'imp' => 'application/vnd.accpac.simply.imp',
|
||||
'ims' => 'application/vnd.ms-ims',
|
||||
'in' => 'text/plain',
|
||||
'ini' => 'text/plain',
|
||||
'ipfix' => 'application/ipfix',
|
||||
'ipk' => 'application/vnd.shana.informed.package',
|
||||
'irm' => 'application/vnd.ibm.rights-management',
|
||||
'irp' => 'application/vnd.irepository.package+xml',
|
||||
'iso' => 'application/octet-stream',
|
||||
'itp' => 'application/vnd.shana.informed.formtemplate',
|
||||
'ivp' => 'application/vnd.immervision-ivp',
|
||||
'ivu' => 'application/vnd.immervision-ivu',
|
||||
'jad' => 'text/vnd.sun.j2me.app-descriptor',
|
||||
'jam' => 'application/vnd.jam',
|
||||
'jar' => 'application/java-archive',
|
||||
'java' => 'text/x-java-source',
|
||||
'jisp' => 'application/vnd.jisp',
|
||||
'jlt' => 'application/vnd.hp-jlyt',
|
||||
'jnlp' => 'application/x-java-jnlp-file',
|
||||
'joda' => 'application/vnd.joost.joda-archive',
|
||||
'jpe' => 'image/jpeg',
|
||||
'jpeg' => 'image/jpeg',
|
||||
'jpg' => 'image/jpeg',
|
||||
'jpgm' => 'video/jpm',
|
||||
'jpgv' => 'video/jpeg',
|
||||
'jpm' => 'video/jpm',
|
||||
'js' => 'text/javascript',
|
||||
'json' => 'application/json',
|
||||
'kar' => 'audio/midi',
|
||||
'karbon' => 'application/vnd.kde.karbon',
|
||||
'kfo' => 'application/vnd.kde.kformula',
|
||||
'kia' => 'application/vnd.kidspiration',
|
||||
'kml' => 'application/vnd.google-earth.kml+xml',
|
||||
'kmz' => 'application/vnd.google-earth.kmz',
|
||||
'kne' => 'application/vnd.kinar',
|
||||
'knp' => 'application/vnd.kinar',
|
||||
'kon' => 'application/vnd.kde.kontour',
|
||||
'kpr' => 'application/vnd.kde.kpresenter',
|
||||
'kpt' => 'application/vnd.kde.kpresenter',
|
||||
'ksp' => 'application/vnd.kde.kspread',
|
||||
'ktr' => 'application/vnd.kahootz',
|
||||
'ktx' => 'image/ktx',
|
||||
'ktz' => 'application/vnd.kahootz',
|
||||
'kwd' => 'application/vnd.kde.kword',
|
||||
'kwt' => 'application/vnd.kde.kword',
|
||||
'lasxml' => 'application/vnd.las.las+xml',
|
||||
'latex' => 'application/x-latex',
|
||||
'lbd' => 'application/vnd.llamagraphics.life-balance.desktop',
|
||||
'lbe' => 'application/vnd.llamagraphics.life-balance.exchange+xml',
|
||||
'les' => 'application/vnd.hhe.lesson-player',
|
||||
'lha' => 'application/octet-stream',
|
||||
'link66' => 'application/vnd.route66.link66+xml',
|
||||
'list' => 'text/plain',
|
||||
'list3820' => 'application/vnd.ibm.modcap',
|
||||
'listafp' => 'application/vnd.ibm.modcap',
|
||||
'log' => 'text/plain',
|
||||
'lostxml' => 'application/lost+xml',
|
||||
'lrf' => 'application/octet-stream',
|
||||
'lrm' => 'application/vnd.ms-lrm',
|
||||
'ltf' => 'application/vnd.frogans.ltf',
|
||||
'lvp' => 'audio/vnd.lucent.voice',
|
||||
'lwp' => 'application/vnd.lotus-wordpro',
|
||||
'lzh' => 'application/octet-stream',
|
||||
'm13' => 'application/x-msmediaview',
|
||||
'm14' => 'application/x-msmediaview',
|
||||
'm1v' => 'video/mpeg',
|
||||
'm21' => 'application/mp21',
|
||||
'm2a' => 'audio/mpeg',
|
||||
'm2v' => 'video/mpeg',
|
||||
'm3a' => 'audio/mpeg',
|
||||
'm3u' => 'audio/x-mpegurl',
|
||||
'm3u8' => 'application/vnd.apple.mpegurl',
|
||||
'm4a' => 'audio/mp4',
|
||||
'm4u' => 'video/vnd.mpegurl',
|
||||
'm4v' => 'video/mp4',
|
||||
'ma' => 'application/mathematica',
|
||||
'mads' => 'application/mads+xml',
|
||||
'mag' => 'application/vnd.ecowin.chart',
|
||||
'maker' => 'application/vnd.framemaker',
|
||||
'man' => 'text/troff',
|
||||
'mathml' => 'application/mathml+xml',
|
||||
'mb' => 'application/mathematica',
|
||||
'mbk' => 'application/vnd.mobius.mbk',
|
||||
'mbox' => 'application/mbox',
|
||||
'mc1' => 'application/vnd.medcalcdata',
|
||||
'mcd' => 'application/vnd.mcd',
|
||||
'mcurl' => 'text/vnd.curl.mcurl',
|
||||
'mdb' => 'application/x-msaccess',
|
||||
'mdi' => 'image/vnd.ms-modi',
|
||||
'me' => 'text/troff',
|
||||
'mesh' => 'model/mesh',
|
||||
'meta4' => 'application/metalink4+xml',
|
||||
'mets' => 'application/mets+xml',
|
||||
'mfm' => 'application/vnd.mfmp',
|
||||
'mgp' => 'application/vnd.osgeo.mapguide.package',
|
||||
'mgz' => 'application/vnd.proteus.magazine',
|
||||
'mid' => 'audio/midi',
|
||||
'midi' => 'audio/midi',
|
||||
'mif' => 'application/vnd.mif',
|
||||
'mime' => 'message/rfc822',
|
||||
'mj2' => 'video/mj2',
|
||||
'mjp2' => 'video/mj2',
|
||||
'mlp' => 'application/vnd.dolby.mlp',
|
||||
'mmd' => 'application/vnd.chipnuts.karaoke-mmd',
|
||||
'mmf' => 'application/vnd.smaf',
|
||||
'mmr' => 'image/vnd.fujixerox.edmics-mmr',
|
||||
'mny' => 'application/x-msmoney',
|
||||
'mobi' => 'application/x-mobipocket-ebook',
|
||||
'mods' => 'application/mods+xml',
|
||||
'mov' => 'video/quicktime',
|
||||
'movie' => 'video/x-sgi-movie',
|
||||
'mp2' => 'audio/mpeg',
|
||||
'mp21' => 'application/mp21',
|
||||
'mp2a' => 'audio/mpeg',
|
||||
'mp3' => 'audio/mpeg',
|
||||
'mp4' => 'video/mp4',
|
||||
'mp4a' => 'audio/mp4',
|
||||
'mp4s' => 'application/mp4',
|
||||
'mp4v' => 'video/mp4',
|
||||
'mpc' => 'application/vnd.mophun.certificate',
|
||||
'mpe' => 'video/mpeg',
|
||||
'mpeg' => 'video/mpeg',
|
||||
'mpg' => 'video/mpeg',
|
||||
'mpg4' => 'video/mp4',
|
||||
'mpga' => 'audio/mpeg',
|
||||
'mpkg' => 'application/vnd.apple.installer+xml',
|
||||
'mpm' => 'application/vnd.blueice.multipass',
|
||||
'mpn' => 'application/vnd.mophun.application',
|
||||
'mpp' => 'application/vnd.ms-project',
|
||||
'mpt' => 'application/vnd.ms-project',
|
||||
'mpy' => 'application/vnd.ibm.minipay',
|
||||
'mqy' => 'application/vnd.mobius.mqy',
|
||||
'mrc' => 'application/marc',
|
||||
'mrcx' => 'application/marcxml+xml',
|
||||
'ms' => 'text/troff',
|
||||
'mscml' => 'application/mediaservercontrol+xml',
|
||||
'mseed' => 'application/vnd.fdsn.mseed',
|
||||
'mseq' => 'application/vnd.mseq',
|
||||
'msf' => 'application/vnd.epson.msf',
|
||||
'msh' => 'model/mesh',
|
||||
'msi' => 'application/x-msdownload',
|
||||
'msl' => 'application/vnd.mobius.msl',
|
||||
'msty' => 'application/vnd.muvee.style',
|
||||
'mts' => 'model/vnd.mts',
|
||||
'mus' => 'application/vnd.musician',
|
||||
'musicxml' => 'application/vnd.recordare.musicxml+xml',
|
||||
'mvb' => 'application/x-msmediaview',
|
||||
'mwf' => 'application/vnd.mfer',
|
||||
'mxf' => 'application/mxf',
|
||||
'mxl' => 'application/vnd.recordare.musicxml',
|
||||
'mxml' => 'application/xv+xml',
|
||||
'mxs' => 'application/vnd.triscape.mxs',
|
||||
'mxu' => 'video/vnd.mpegurl',
|
||||
'n-gage' => 'application/vnd.nokia.n-gage.symbian.install',
|
||||
'n3' => 'text/n3',
|
||||
'nb' => 'application/mathematica',
|
||||
'nbp' => 'application/vnd.wolfram.player',
|
||||
'nc' => 'application/x-netcdf',
|
||||
'ncx' => 'application/x-dtbncx+xml',
|
||||
'ngdat' => 'application/vnd.nokia.n-gage.data',
|
||||
'nlu' => 'application/vnd.neurolanguage.nlu',
|
||||
'nml' => 'application/vnd.enliven',
|
||||
'nnd' => 'application/vnd.noblenet-directory',
|
||||
'nns' => 'application/vnd.noblenet-sealer',
|
||||
'nnw' => 'application/vnd.noblenet-web',
|
||||
'npx' => 'image/vnd.net-fpx',
|
||||
'nsf' => 'application/vnd.lotus-notes',
|
||||
'oa2' => 'application/vnd.fujitsu.oasys2',
|
||||
'oa3' => 'application/vnd.fujitsu.oasys3',
|
||||
'oas' => 'application/vnd.fujitsu.oasys',
|
||||
'obd' => 'application/x-msbinder',
|
||||
'oda' => 'application/oda',
|
||||
'odb' => 'application/vnd.oasis.opendocument.database',
|
||||
'odc' => 'application/vnd.oasis.opendocument.chart',
|
||||
'odf' => 'application/vnd.oasis.opendocument.formula',
|
||||
'odft' => 'application/vnd.oasis.opendocument.formula-template',
|
||||
'odg' => 'application/vnd.oasis.opendocument.graphics',
|
||||
'odi' => 'application/vnd.oasis.opendocument.image',
|
||||
'odm' => 'application/vnd.oasis.opendocument.text-master',
|
||||
'odp' => 'application/vnd.oasis.opendocument.presentation',
|
||||
'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
|
||||
'odt' => 'application/vnd.oasis.opendocument.text',
|
||||
'oga' => 'audio/ogg',
|
||||
'ogg' => 'audio/ogg',
|
||||
'ogv' => 'video/ogg',
|
||||
'ogx' => 'application/ogg',
|
||||
'onepkg' => 'application/onenote',
|
||||
'onetmp' => 'application/onenote',
|
||||
'onetoc' => 'application/onenote',
|
||||
'onetoc2' => 'application/onenote',
|
||||
'opf' => 'application/oebps-package+xml',
|
||||
'oprc' => 'application/vnd.palm',
|
||||
'org' => 'application/vnd.lotus-organizer',
|
||||
'osf' => 'application/vnd.yamaha.openscoreformat',
|
||||
'osfpvg' => 'application/vnd.yamaha.openscoreformat.osfpvg+xml',
|
||||
'otc' => 'application/vnd.oasis.opendocument.chart-template',
|
||||
'otf' => 'application/x-font-otf',
|
||||
'otg' => 'application/vnd.oasis.opendocument.graphics-template',
|
||||
'oth' => 'application/vnd.oasis.opendocument.text-web',
|
||||
'oti' => 'application/vnd.oasis.opendocument.image-template',
|
||||
'otp' => 'application/vnd.oasis.opendocument.presentation-template',
|
||||
'ots' => 'application/vnd.oasis.opendocument.spreadsheet-template',
|
||||
'ott' => 'application/vnd.oasis.opendocument.text-template',
|
||||
'oxt' => 'application/vnd.openofficeorg.extension',
|
||||
'p' => 'text/x-pascal',
|
||||
'p10' => 'application/pkcs10',
|
||||
'p12' => 'application/x-pkcs12',
|
||||
'p7b' => 'application/x-pkcs7-certificates',
|
||||
'p7c' => 'application/pkcs7-mime',
|
||||
'p7m' => 'application/pkcs7-mime',
|
||||
'p7r' => 'application/x-pkcs7-certreqresp',
|
||||
'p7s' => 'application/pkcs7-signature',
|
||||
'p8' => 'application/pkcs8',
|
||||
'pas' => 'text/x-pascal',
|
||||
'paw' => 'application/vnd.pawaafile',
|
||||
'pbd' => 'application/vnd.powerbuilder6',
|
||||
'pbm' => 'image/x-portable-bitmap',
|
||||
'pcf' => 'application/x-font-pcf',
|
||||
'pcl' => 'application/vnd.hp-pcl',
|
||||
'pclxl' => 'application/vnd.hp-pclxl',
|
||||
'pct' => 'image/x-pict',
|
||||
'pcurl' => 'application/vnd.curl.pcurl',
|
||||
'pcx' => 'image/x-pcx',
|
||||
'pdb' => 'application/vnd.palm',
|
||||
'pdf' => 'application/pdf',
|
||||
'pfa' => 'application/x-font-type1',
|
||||
'pfb' => 'application/x-font-type1',
|
||||
'pfm' => 'application/x-font-type1',
|
||||
'pfr' => 'application/font-tdpfr',
|
||||
'pfx' => 'application/x-pkcs12',
|
||||
'pgm' => 'image/x-portable-graymap',
|
||||
'pgn' => 'application/x-chess-pgn',
|
||||
'pgp' => 'application/pgp-encrypted',
|
||||
'php' => 'text/x-php',
|
||||
'phps' => 'application/x-httpd-phps',
|
||||
'pic' => 'image/x-pict',
|
||||
'pkg' => 'application/octet-stream',
|
||||
'pki' => 'application/pkixcmp',
|
||||
'pkipath' => 'application/pkix-pkipath',
|
||||
'plb' => 'application/vnd.3gpp.pic-bw-large',
|
||||
'plc' => 'application/vnd.mobius.plc',
|
||||
'plf' => 'application/vnd.pocketlearn',
|
||||
'pls' => 'application/pls+xml',
|
||||
'pml' => 'application/vnd.ctc-posml',
|
||||
'png' => 'image/png',
|
||||
'pnm' => 'image/x-portable-anymap',
|
||||
'portpkg' => 'application/vnd.macports.portpkg',
|
||||
'pot' => 'application/vnd.ms-powerpoint',
|
||||
'potm' => 'application/vnd.ms-powerpoint.template.macroenabled.12',
|
||||
'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template',
|
||||
'ppam' => 'application/vnd.ms-powerpoint.addin.macroenabled.12',
|
||||
'ppd' => 'application/vnd.cups-ppd',
|
||||
'ppm' => 'image/x-portable-pixmap',
|
||||
'pps' => 'application/vnd.ms-powerpoint',
|
||||
'ppsm' => 'application/vnd.ms-powerpoint.slideshow.macroenabled.12',
|
||||
'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow',
|
||||
'ppt' => 'application/vnd.ms-powerpoint',
|
||||
'pptm' => 'application/vnd.ms-powerpoint.presentation.macroenabled.12',
|
||||
'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
|
||||
'pqa' => 'application/vnd.palm',
|
||||
'prc' => 'application/x-mobipocket-ebook',
|
||||
'pre' => 'application/vnd.lotus-freelance',
|
||||
'prf' => 'application/pics-rules',
|
||||
'ps' => 'application/postscript',
|
||||
'psb' => 'application/vnd.3gpp.pic-bw-small',
|
||||
'psd' => 'image/vnd.adobe.photoshop',
|
||||
'psf' => 'application/x-font-linux-psf',
|
||||
'pskcxml' => 'application/pskc+xml',
|
||||
'ptid' => 'application/vnd.pvi.ptid1',
|
||||
'pub' => 'application/x-mspublisher',
|
||||
'pvb' => 'application/vnd.3gpp.pic-bw-var',
|
||||
'pwn' => 'application/vnd.3m.post-it-notes',
|
||||
'pya' => 'audio/vnd.ms-playready.media.pya',
|
||||
'pyv' => 'video/vnd.ms-playready.media.pyv',
|
||||
'qam' => 'application/vnd.epson.quickanime',
|
||||
'qbo' => 'application/vnd.intu.qbo',
|
||||
'qfx' => 'application/vnd.intu.qfx',
|
||||
'qps' => 'application/vnd.publishare-delta-tree',
|
||||
'qt' => 'video/quicktime',
|
||||
'qwd' => 'application/vnd.quark.quarkxpress',
|
||||
'qwt' => 'application/vnd.quark.quarkxpress',
|
||||
'qxb' => 'application/vnd.quark.quarkxpress',
|
||||
'qxd' => 'application/vnd.quark.quarkxpress',
|
||||
'qxl' => 'application/vnd.quark.quarkxpress',
|
||||
'qxt' => 'application/vnd.quark.quarkxpress',
|
||||
'ra' => 'audio/x-pn-realaudio',
|
||||
'ram' => 'audio/x-pn-realaudio',
|
||||
'rar' => 'application/x-rar-compressed',
|
||||
'ras' => 'image/x-cmu-raster',
|
||||
'rb' => 'text/plain',
|
||||
'rcprofile' => 'application/vnd.ipunplugged.rcprofile',
|
||||
'rdf' => 'application/rdf+xml',
|
||||
'rdz' => 'application/vnd.data-vision.rdz',
|
||||
'rep' => 'application/vnd.businessobjects',
|
||||
'res' => 'application/x-dtbresource+xml',
|
||||
'resx' => 'text/xml',
|
||||
'rgb' => 'image/x-rgb',
|
||||
'rif' => 'application/reginfo+xml',
|
||||
'rip' => 'audio/vnd.rip',
|
||||
'rl' => 'application/resource-lists+xml',
|
||||
'rlc' => 'image/vnd.fujixerox.edmics-rlc',
|
||||
'rld' => 'application/resource-lists-diff+xml',
|
||||
'rm' => 'application/vnd.rn-realmedia',
|
||||
'rmi' => 'audio/midi',
|
||||
'rmp' => 'audio/x-pn-realaudio-plugin',
|
||||
'rms' => 'application/vnd.jcp.javame.midlet-rms',
|
||||
'rnc' => 'application/relax-ng-compact-syntax',
|
||||
'roff' => 'text/troff',
|
||||
'rp9' => 'application/vnd.cloanto.rp9',
|
||||
'rpss' => 'application/vnd.nokia.radio-presets',
|
||||
'rpst' => 'application/vnd.nokia.radio-preset',
|
||||
'rq' => 'application/sparql-query',
|
||||
'rs' => 'application/rls-services+xml',
|
||||
'rsd' => 'application/rsd+xml',
|
||||
'rss' => 'application/rss+xml',
|
||||
'rtf' => 'application/rtf',
|
||||
'rtx' => 'text/richtext',
|
||||
's' => 'text/x-asm',
|
||||
'saf' => 'application/vnd.yamaha.smaf-audio',
|
||||
'sbml' => 'application/sbml+xml',
|
||||
'sc' => 'application/vnd.ibm.secure-container',
|
||||
'scd' => 'application/x-msschedule',
|
||||
'scm' => 'application/vnd.lotus-screencam',
|
||||
'scq' => 'application/scvp-cv-request',
|
||||
'scs' => 'application/scvp-cv-response',
|
||||
'scurl' => 'text/vnd.curl.scurl',
|
||||
'sda' => 'application/vnd.stardivision.draw',
|
||||
'sdc' => 'application/vnd.stardivision.calc',
|
||||
'sdd' => 'application/vnd.stardivision.impress',
|
||||
'sdkd' => 'application/vnd.solent.sdkm+xml',
|
||||
'sdkm' => 'application/vnd.solent.sdkm+xml',
|
||||
'sdp' => 'application/sdp',
|
||||
'sdw' => 'application/vnd.stardivision.writer',
|
||||
'see' => 'application/vnd.seemail',
|
||||
'seed' => 'application/vnd.fdsn.seed',
|
||||
'sema' => 'application/vnd.sema',
|
||||
'semd' => 'application/vnd.semd',
|
||||
'semf' => 'application/vnd.semf',
|
||||
'ser' => 'application/java-serialized-object',
|
||||
'setpay' => 'application/set-payment-initiation',
|
||||
'setreg' => 'application/set-registration-initiation',
|
||||
'sfd-hdstx' => 'application/vnd.hydrostatix.sof-data',
|
||||
'sfs' => 'application/vnd.spotfire.sfs',
|
||||
'sgl' => 'application/vnd.stardivision.writer-global',
|
||||
'sgm' => 'text/sgml',
|
||||
'sgml' => 'text/sgml',
|
||||
'sh' => 'application/x-sh',
|
||||
'shar' => 'application/x-shar',
|
||||
'shf' => 'application/shf+xml',
|
||||
'sig' => 'application/pgp-signature',
|
||||
'silo' => 'model/mesh',
|
||||
'sis' => 'application/vnd.symbian.install',
|
||||
'sisx' => 'application/vnd.symbian.install',
|
||||
'sit' => 'application/x-stuffit',
|
||||
'sitx' => 'application/x-stuffitx',
|
||||
'skd' => 'application/vnd.koan',
|
||||
'skm' => 'application/vnd.koan',
|
||||
'skp' => 'application/vnd.koan',
|
||||
'skt' => 'application/vnd.koan',
|
||||
'sldm' => 'application/vnd.ms-powerpoint.slide.macroenabled.12',
|
||||
'sldx' => 'application/vnd.openxmlformats-officedocument.presentationml.slide',
|
||||
'slt' => 'application/vnd.epson.salt',
|
||||
'sm' => 'application/vnd.stepmania.stepchart',
|
||||
'smf' => 'application/vnd.stardivision.math',
|
||||
'smi' => 'application/smil+xml',
|
||||
'smil' => 'application/smil+xml',
|
||||
'snd' => 'audio/basic',
|
||||
'snf' => 'application/x-font-snf',
|
||||
'so' => 'application/octet-stream',
|
||||
'spc' => 'application/x-pkcs7-certificates',
|
||||
'spf' => 'application/vnd.yamaha.smaf-phrase',
|
||||
'spl' => 'application/x-futuresplash',
|
||||
'spot' => 'text/vnd.in3d.spot',
|
||||
'spp' => 'application/scvp-vp-response',
|
||||
'spq' => 'application/scvp-vp-request',
|
||||
'spx' => 'audio/ogg',
|
||||
'src' => 'application/x-wais-source',
|
||||
'sru' => 'application/sru+xml',
|
||||
'srx' => 'application/sparql-results+xml',
|
||||
'sse' => 'application/vnd.kodak-descriptor',
|
||||
'ssf' => 'application/vnd.epson.ssf',
|
||||
'ssml' => 'application/ssml+xml',
|
||||
'st' => 'application/vnd.sailingtracker.track',
|
||||
'stc' => 'application/vnd.sun.xml.calc.template',
|
||||
'std' => 'application/vnd.sun.xml.draw.template',
|
||||
'stf' => 'application/vnd.wt.stf',
|
||||
'sti' => 'application/vnd.sun.xml.impress.template',
|
||||
'stk' => 'application/hyperstudio',
|
||||
'stl' => 'application/vnd.ms-pki.stl',
|
||||
'str' => 'application/vnd.pg.format',
|
||||
'stw' => 'application/vnd.sun.xml.writer.template',
|
||||
'sub' => 'image/vnd.dvb.subtitle',
|
||||
'sus' => 'application/vnd.sus-calendar',
|
||||
'susp' => 'application/vnd.sus-calendar',
|
||||
'sv4cpio' => 'application/x-sv4cpio',
|
||||
'sv4crc' => 'application/x-sv4crc',
|
||||
'svc' => 'application/vnd.dvb.service',
|
||||
'svd' => 'application/vnd.svd',
|
||||
'svg' => 'image/svg+xml',
|
||||
'svgz' => 'image/svg+xml',
|
||||
'swa' => 'application/x-director',
|
||||
'swf' => 'application/x-shockwave-flash',
|
||||
'swi' => 'application/vnd.aristanetworks.swi',
|
||||
'sxc' => 'application/vnd.sun.xml.calc',
|
||||
'sxd' => 'application/vnd.sun.xml.draw',
|
||||
'sxg' => 'application/vnd.sun.xml.writer.global',
|
||||
'sxi' => 'application/vnd.sun.xml.impress',
|
||||
'sxm' => 'application/vnd.sun.xml.math',
|
||||
'sxw' => 'application/vnd.sun.xml.writer',
|
||||
't' => 'text/troff',
|
||||
'tao' => 'application/vnd.tao.intent-module-archive',
|
||||
'tar' => 'application/x-tar',
|
||||
'tcap' => 'application/vnd.3gpp2.tcap',
|
||||
'tcl' => 'application/x-tcl',
|
||||
'teacher' => 'application/vnd.smart.teacher',
|
||||
'tei' => 'application/tei+xml',
|
||||
'teicorpus' => 'application/tei+xml',
|
||||
'tex' => 'application/x-tex',
|
||||
'texi' => 'application/x-texinfo',
|
||||
'texinfo' => 'application/x-texinfo',
|
||||
'text' => 'text/plain',
|
||||
'tfi' => 'application/thraud+xml',
|
||||
'tfm' => 'application/x-tex-tfm',
|
||||
'thmx' => 'application/vnd.ms-officetheme',
|
||||
'tif' => 'image/tiff',
|
||||
'tiff' => 'image/tiff',
|
||||
'tmo' => 'application/vnd.tmobile-livetv',
|
||||
'torrent' => 'application/x-bittorrent',
|
||||
'tpl' => 'application/vnd.groove-tool-template',
|
||||
'tpt' => 'application/vnd.trid.tpt',
|
||||
'tr' => 'text/troff',
|
||||
'tra' => 'application/vnd.trueapp',
|
||||
'trm' => 'application/x-msterminal',
|
||||
'tsd' => 'application/timestamped-data',
|
||||
'tsv' => 'text/tab-separated-values',
|
||||
'ttc' => 'application/x-font-ttf',
|
||||
'ttf' => 'application/x-font-ttf',
|
||||
'ttl' => 'text/turtle',
|
||||
'twd' => 'application/vnd.simtech-mindmapper',
|
||||
'twds' => 'application/vnd.simtech-mindmapper',
|
||||
'txd' => 'application/vnd.genomatix.tuxedo',
|
||||
'txf' => 'application/vnd.mobius.txf',
|
||||
'txt' => 'text/plain',
|
||||
'u32' => 'application/x-authorware-bin',
|
||||
'udeb' => 'application/x-debian-package',
|
||||
'ufd' => 'application/vnd.ufdl',
|
||||
'ufdl' => 'application/vnd.ufdl',
|
||||
'umj' => 'application/vnd.umajin',
|
||||
'unityweb' => 'application/vnd.unity',
|
||||
'uoml' => 'application/vnd.uoml+xml',
|
||||
'uri' => 'text/uri-list',
|
||||
'uris' => 'text/uri-list',
|
||||
'urls' => 'text/uri-list',
|
||||
'ustar' => 'application/x-ustar',
|
||||
'utz' => 'application/vnd.uiq.theme',
|
||||
'uu' => 'text/x-uuencode',
|
||||
'uva' => 'audio/vnd.dece.audio',
|
||||
'uvd' => 'application/vnd.dece.data',
|
||||
'uvf' => 'application/vnd.dece.data',
|
||||
'uvg' => 'image/vnd.dece.graphic',
|
||||
'uvh' => 'video/vnd.dece.hd',
|
||||
'uvi' => 'image/vnd.dece.graphic',
|
||||
'uvm' => 'video/vnd.dece.mobile',
|
||||
'uvp' => 'video/vnd.dece.pd',
|
||||
'uvs' => 'video/vnd.dece.sd',
|
||||
'uvt' => 'application/vnd.dece.ttml+xml',
|
||||
'uvu' => 'video/vnd.uvvu.mp4',
|
||||
'uvv' => 'video/vnd.dece.video',
|
||||
'uvva' => 'audio/vnd.dece.audio',
|
||||
'uvvd' => 'application/vnd.dece.data',
|
||||
'uvvf' => 'application/vnd.dece.data',
|
||||
'uvvg' => 'image/vnd.dece.graphic',
|
||||
'uvvh' => 'video/vnd.dece.hd',
|
||||
'uvvi' => 'image/vnd.dece.graphic',
|
||||
'uvvm' => 'video/vnd.dece.mobile',
|
||||
'uvvp' => 'video/vnd.dece.pd',
|
||||
'uvvs' => 'video/vnd.dece.sd',
|
||||
'uvvt' => 'application/vnd.dece.ttml+xml',
|
||||
'uvvu' => 'video/vnd.uvvu.mp4',
|
||||
'uvvv' => 'video/vnd.dece.video',
|
||||
'uvvx' => 'application/vnd.dece.unspecified',
|
||||
'uvx' => 'application/vnd.dece.unspecified',
|
||||
'vcd' => 'application/x-cdlink',
|
||||
'vcf' => 'text/x-vcard',
|
||||
'vcg' => 'application/vnd.groove-vcard',
|
||||
'vcs' => 'text/x-vcalendar',
|
||||
'vcx' => 'application/vnd.vcx',
|
||||
'vis' => 'application/vnd.visionary',
|
||||
'viv' => 'video/vnd.vivo',
|
||||
'vor' => 'application/vnd.stardivision.writer',
|
||||
'vox' => 'application/x-authorware-bin',
|
||||
'vrml' => 'model/vrml',
|
||||
'vsd' => 'application/vnd.visio',
|
||||
'vsf' => 'application/vnd.vsf',
|
||||
'vss' => 'application/vnd.visio',
|
||||
'vst' => 'application/vnd.visio',
|
||||
'vsw' => 'application/vnd.visio',
|
||||
'vtu' => 'model/vnd.vtu',
|
||||
'vxml' => 'application/voicexml+xml',
|
||||
'w3d' => 'application/x-director',
|
||||
'wad' => 'application/x-doom',
|
||||
'wav' => 'audio/x-wav',
|
||||
'wax' => 'audio/x-ms-wax',
|
||||
'wbmp' => 'image/vnd.wap.wbmp',
|
||||
'wbs' => 'application/vnd.criticaltools.wbs+xml',
|
||||
'wbxml' => 'application/vnd.wap.wbxml',
|
||||
'wcm' => 'application/vnd.ms-works',
|
||||
'wdb' => 'application/vnd.ms-works',
|
||||
'weba' => 'audio/webm',
|
||||
'webm' => 'video/webm',
|
||||
'webp' => 'image/webp',
|
||||
'wg' => 'application/vnd.pmi.widget',
|
||||
'wgt' => 'application/widget',
|
||||
'wks' => 'application/vnd.ms-works',
|
||||
'wm' => 'video/x-ms-wm',
|
||||
'wma' => 'audio/x-ms-wma',
|
||||
'wmd' => 'application/x-ms-wmd',
|
||||
'wmf' => 'application/x-msmetafile',
|
||||
'wml' => 'text/vnd.wap.wml',
|
||||
'wmlc' => 'application/vnd.wap.wmlc',
|
||||
'wmls' => 'text/vnd.wap.wmlscript',
|
||||
'wmlsc' => 'application/vnd.wap.wmlscriptc',
|
||||
'wmv' => 'video/x-ms-wmv',
|
||||
'wmx' => 'video/x-ms-wmx',
|
||||
'wmz' => 'application/x-ms-wmz',
|
||||
'woff' => 'application/x-font-woff',
|
||||
'wpd' => 'application/vnd.wordperfect',
|
||||
'wpl' => 'application/vnd.ms-wpl',
|
||||
'wps' => 'application/vnd.ms-works',
|
||||
'wqd' => 'application/vnd.wqd',
|
||||
'wri' => 'application/x-mswrite',
|
||||
'wrl' => 'model/vrml',
|
||||
'wsdl' => 'application/wsdl+xml',
|
||||
'wspolicy' => 'application/wspolicy+xml',
|
||||
'wtb' => 'application/vnd.webturbo',
|
||||
'wvx' => 'video/x-ms-wvx',
|
||||
'x32' => 'application/x-authorware-bin',
|
||||
'x3d' => 'application/vnd.hzn-3d-crossword',
|
||||
'xap' => 'application/x-silverlight-app',
|
||||
'xar' => 'application/vnd.xara',
|
||||
'xbap' => 'application/x-ms-xbap',
|
||||
'xbd' => 'application/vnd.fujixerox.docuworks.binder',
|
||||
'xbm' => 'image/x-xbitmap',
|
||||
'xdf' => 'application/xcap-diff+xml',
|
||||
'xdm' => 'application/vnd.syncml.dm+xml',
|
||||
'xdp' => 'application/vnd.adobe.xdp+xml',
|
||||
'xdssc' => 'application/dssc+xml',
|
||||
'xdw' => 'application/vnd.fujixerox.docuworks',
|
||||
'xenc' => 'application/xenc+xml',
|
||||
'xer' => 'application/patch-ops-error+xml',
|
||||
'xfdf' => 'application/vnd.adobe.xfdf',
|
||||
'xfdl' => 'application/vnd.xfdl',
|
||||
'xht' => 'application/xhtml+xml',
|
||||
'xhtml' => 'application/xhtml+xml',
|
||||
'xhvml' => 'application/xv+xml',
|
||||
'xif' => 'image/vnd.xiff',
|
||||
'xla' => 'application/vnd.ms-excel',
|
||||
'xlam' => 'application/vnd.ms-excel.addin.macroenabled.12',
|
||||
'xlc' => 'application/vnd.ms-excel',
|
||||
'xlm' => 'application/vnd.ms-excel',
|
||||
'xls' => 'application/vnd.ms-excel',
|
||||
'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroenabled.12',
|
||||
'xlsm' => 'application/vnd.ms-excel.sheet.macroenabled.12',
|
||||
'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
'xlt' => 'application/vnd.ms-excel',
|
||||
'xltm' => 'application/vnd.ms-excel.template.macroenabled.12',
|
||||
'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template',
|
||||
'xlw' => 'application/vnd.ms-excel',
|
||||
'xml' => 'application/xml',
|
||||
'xo' => 'application/vnd.olpc-sugar',
|
||||
'xop' => 'application/xop+xml',
|
||||
'xpi' => 'application/x-xpinstall',
|
||||
'xpm' => 'image/x-xpixmap',
|
||||
'xpr' => 'application/vnd.is-xpr',
|
||||
'xps' => 'application/vnd.ms-xpsdocument',
|
||||
'xpw' => 'application/vnd.intercon.formnet',
|
||||
'xpx' => 'application/vnd.intercon.formnet',
|
||||
'xsl' => 'application/xml',
|
||||
'xslt' => 'application/xslt+xml',
|
||||
'xsm' => 'application/vnd.syncml+xml',
|
||||
'xspf' => 'application/xspf+xml',
|
||||
'xul' => 'application/vnd.mozilla.xul+xml',
|
||||
'xvm' => 'application/xv+xml',
|
||||
'xvml' => 'application/xv+xml',
|
||||
'xwd' => 'image/x-xwindowdump',
|
||||
'xyz' => 'chemical/x-xyz',
|
||||
'yaml' => 'text/yaml',
|
||||
'yang' => 'application/yang',
|
||||
'yin' => 'application/yin+xml',
|
||||
'yml' => 'text/yaml',
|
||||
'zaz' => 'application/vnd.zzazz.deck+xml',
|
||||
'zip' => 'application/zip',
|
||||
'zir' => 'application/vnd.zul',
|
||||
'zirz' => 'application/vnd.zul',
|
||||
'zmm' => 'application/vnd.handheld-entertainment+xml'
|
||||
);
|
||||
|
||||
/**
|
||||
* Get a singleton instance of the class
|
||||
*
|
||||
* @return self
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public static function getInstance()
|
||||
{
|
||||
if (!self::$instance) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a mimetype value from a file extension
|
||||
*
|
||||
* @param string $extension File extension
|
||||
*
|
||||
* @return string|null
|
||||
*
|
||||
*/
|
||||
public function fromExtension($extension)
|
||||
{
|
||||
$extension = strtolower($extension);
|
||||
|
||||
return isset($this->mimetypes[$extension])
|
||||
? $this->mimetypes[$extension]
|
||||
: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a mimetype from a filename
|
||||
*
|
||||
* @param string $filename Filename to generate a mimetype from
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function fromFilename($filename)
|
||||
{
|
||||
return $this->fromExtension(pathinfo($filename, PATHINFO_EXTENSION));
|
||||
}
|
||||
}
|
|
@ -1,292 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Post;
|
||||
|
||||
use GuzzleHttp\Stream;
|
||||
|
||||
/**
|
||||
* Stream that when read returns bytes for a streaming multipart/form-data body
|
||||
*/
|
||||
class MultipartBody implements Stream\StreamInterface
|
||||
{
|
||||
/** @var Stream\StreamInterface */
|
||||
private $files;
|
||||
private $fields;
|
||||
private $size;
|
||||
private $buffer;
|
||||
private $bufferedHeaders = [];
|
||||
private $pos = 0;
|
||||
private $currentFile = 0;
|
||||
private $currentField = 0;
|
||||
private $sentLast;
|
||||
private $boundary;
|
||||
|
||||
/**
|
||||
* @param array $fields Associative array of field names to values where
|
||||
* each value is a string.
|
||||
* @param array $files Associative array of PostFileInterface objects
|
||||
* @param string $boundary You can optionally provide a specific boundary
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct(
|
||||
array $fields = [],
|
||||
array $files = [],
|
||||
$boundary = null
|
||||
) {
|
||||
$this->boundary = $boundary ?: uniqid();
|
||||
$this->fields = $fields;
|
||||
$this->files = $files;
|
||||
|
||||
// Ensure each file is a PostFileInterface
|
||||
foreach ($this->files as $file) {
|
||||
if (!$file instanceof PostFileInterface) {
|
||||
throw new \InvalidArgumentException('All POST fields must '
|
||||
. 'implement PostFieldInterface');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
$this->seek(0);
|
||||
|
||||
return $this->getContents();
|
||||
}
|
||||
|
||||
public function getContents($maxLength = -1)
|
||||
{
|
||||
$buffer = '';
|
||||
|
||||
while (!$this->eof()) {
|
||||
if ($maxLength === -1) {
|
||||
$read = 1048576;
|
||||
} else {
|
||||
$len = strlen($buffer);
|
||||
if ($len == $maxLength) {
|
||||
break;
|
||||
}
|
||||
$read = min(1048576, $maxLength - $len);
|
||||
}
|
||||
$buffer .= $this->read($read);
|
||||
}
|
||||
|
||||
return $buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the boundary
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getBoundary()
|
||||
{
|
||||
return $this->boundary;
|
||||
}
|
||||
|
||||
public function close()
|
||||
{
|
||||
$this->detach();
|
||||
}
|
||||
|
||||
public function detach()
|
||||
{
|
||||
$this->fields = $this->files = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* The stream has reached an EOF when all of the fields and files have been
|
||||
* read.
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function eof()
|
||||
{
|
||||
return $this->currentField == count($this->fields) &&
|
||||
$this->currentFile == count($this->files);
|
||||
}
|
||||
|
||||
public function tell()
|
||||
{
|
||||
return $this->pos;
|
||||
}
|
||||
|
||||
public function isReadable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function isWritable()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* The steam is seekable by default, but all attached files must be
|
||||
* seekable too.
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isSeekable()
|
||||
{
|
||||
foreach ($this->files as $file) {
|
||||
if (!$file->getContent()->isSeekable()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getSize()
|
||||
{
|
||||
if ($this->size === null) {
|
||||
foreach ($this->files as $file) {
|
||||
// We must be able to ascertain the size of each attached file
|
||||
if (null === ($size = $file->getContent()->getSize())) {
|
||||
return null;
|
||||
}
|
||||
$this->size += strlen($this->getFileHeaders($file)) + $size;
|
||||
}
|
||||
foreach (array_keys($this->fields) as $key) {
|
||||
$this->size += strlen($this->getFieldString($key));
|
||||
}
|
||||
$this->size += strlen("\r\n--{$this->boundary}--");
|
||||
}
|
||||
|
||||
return $this->size;
|
||||
}
|
||||
|
||||
public function read($length)
|
||||
{
|
||||
$content = '';
|
||||
if ($this->buffer && !$this->buffer->eof()) {
|
||||
$content .= $this->buffer->read($length);
|
||||
}
|
||||
if ($delta = $length - strlen($content)) {
|
||||
$content .= $this->readData($delta);
|
||||
}
|
||||
|
||||
if ($content === '' && !$this->sentLast) {
|
||||
$this->sentLast = true;
|
||||
$content = "\r\n--{$this->boundary}--";
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
public function seek($offset, $whence = SEEK_SET)
|
||||
{
|
||||
if ($offset != 0 || $whence != SEEK_SET || !$this->isSeekable()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ($this->files as $file) {
|
||||
if (!$file->getContent()->seek(0)) {
|
||||
throw new \RuntimeException('Rewind on multipart file failed '
|
||||
. 'even though it shouldn\'t have');
|
||||
}
|
||||
}
|
||||
|
||||
$this->buffer = $this->sentLast = null;
|
||||
$this->pos = $this->currentField = $this->currentFile = 0;
|
||||
$this->bufferedHeaders = [];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function write($string)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* No data is in the read buffer, so more needs to be pulled in from fields
|
||||
* and files.
|
||||
*
|
||||
* @param int $length Amount of data to read
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function readData($length)
|
||||
{
|
||||
$result = '';
|
||||
|
||||
if ($this->currentField < count($this->fields)) {
|
||||
$result = $this->readField($length);
|
||||
}
|
||||
|
||||
if ($result === '' && $this->currentFile < count($this->files)) {
|
||||
$result = $this->readFile($length);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new stream buffer and inject form-data
|
||||
*
|
||||
* @param int $length Amount of data to read from the stream buffer
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function readField($length)
|
||||
{
|
||||
$name = array_keys($this->fields)[++$this->currentField - 1];
|
||||
$this->buffer = Stream\create($this->getFieldString($name));
|
||||
|
||||
return $this->buffer->read($length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read data from a POST file, fill the read buffer with any overflow
|
||||
*
|
||||
* @param int $length Amount of data to read from the file
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function readFile($length)
|
||||
{
|
||||
$current = $this->files[$this->currentFile];
|
||||
|
||||
// Got to the next file and recursively return the read value, or bail
|
||||
// if no more data can be read.
|
||||
if ($current->getContent()->eof()) {
|
||||
return ++$this->currentFile == count($this->files)
|
||||
? ''
|
||||
: $this->readFile($length);
|
||||
}
|
||||
|
||||
// If this is the start of a file, then send the headers to the read
|
||||
// buffer.
|
||||
if (!isset($this->bufferedHeaders[$this->currentFile])) {
|
||||
$this->buffer = Stream\create($this->getFileHeaders($current));
|
||||
$this->bufferedHeaders[$this->currentFile] = true;
|
||||
}
|
||||
|
||||
// More data needs to be read to meet the limit, so pull from the file
|
||||
$content = $this->buffer ? $this->buffer->read($length) : '';
|
||||
if (($remaining = $length - strlen($content)) > 0) {
|
||||
$content .= $current->getContent()->read($remaining);
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
private function getFieldString($key)
|
||||
{
|
||||
return sprintf(
|
||||
"--%s\r\nContent-Disposition: form-data; name=\"%s\"\r\n\r\n%s\r\n",
|
||||
$this->boundary,
|
||||
$key,
|
||||
$this->fields[$key]
|
||||
);
|
||||
}
|
||||
|
||||
private function getFileHeaders(PostFileInterface $file)
|
||||
{
|
||||
$headers = '';
|
||||
foreach ($file->getHeaders() as $key => $value) {
|
||||
$headers .= "{$key}: {$value}\r\n";
|
||||
}
|
||||
|
||||
return "--{$this->boundary}\r\n" . trim($headers) . "\r\n\r\n";
|
||||
}
|
||||
}
|
|
@ -1,282 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Post;
|
||||
|
||||
use GuzzleHttp\Message\RequestInterface;
|
||||
use GuzzleHttp\Stream;
|
||||
use GuzzleHttp\Query;
|
||||
|
||||
/**
|
||||
* Holds POST fields and files and creates a streaming body when read methods
|
||||
* are called on the object.
|
||||
*/
|
||||
class PostBody implements PostBodyInterface
|
||||
{
|
||||
/** @var Stream\StreamInterface */
|
||||
private $body;
|
||||
|
||||
/** @var callable */
|
||||
private $aggregator;
|
||||
|
||||
private $fields = [];
|
||||
|
||||
/** @var PostFileInterface[] */
|
||||
private $files = [];
|
||||
private $forceMultipart = false;
|
||||
|
||||
/**
|
||||
* Applies request headers to a request based on the POST state
|
||||
*
|
||||
* @param RequestInterface $request Request to update
|
||||
*/
|
||||
public function applyRequestHeaders(RequestInterface $request)
|
||||
{
|
||||
if ($this->files || $this->forceMultipart) {
|
||||
$request->setHeader(
|
||||
'Content-Type',
|
||||
'multipart/form-data; boundary=' . $this->getBody()->getBoundary()
|
||||
);
|
||||
} elseif ($this->fields) {
|
||||
$request->setHeader('Content-Type', 'application/x-www-form-urlencoded');
|
||||
}
|
||||
|
||||
if ($size = $this->getSize()) {
|
||||
$request->setHeader('Content-Length', $size);
|
||||
}
|
||||
}
|
||||
|
||||
public function forceMultipartUpload($force)
|
||||
{
|
||||
$this->forceMultipart = $force;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setAggregator(callable $aggregator)
|
||||
{
|
||||
$this->aggregator = $aggregator;
|
||||
}
|
||||
|
||||
public function setField($name, $value)
|
||||
{
|
||||
$this->fields[$name] = $value;
|
||||
$this->mutate();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function replaceFields(array $fields)
|
||||
{
|
||||
$this->fields = $fields;
|
||||
$this->mutate();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getField($name)
|
||||
{
|
||||
return isset($this->fields[$name]) ? $this->fields[$name] : null;
|
||||
}
|
||||
|
||||
public function removeField($name)
|
||||
{
|
||||
unset($this->fields[$name]);
|
||||
$this->mutate();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getFields($asString = false)
|
||||
{
|
||||
if (!$asString) {
|
||||
return $this->fields;
|
||||
}
|
||||
|
||||
return (string) (new Query($this->fields))
|
||||
->setEncodingType(Query::RFC1738)
|
||||
->setAggregator($this->getAggregator());
|
||||
}
|
||||
|
||||
public function hasField($name)
|
||||
{
|
||||
return isset($this->fields[$name]);
|
||||
}
|
||||
|
||||
public function getFile($name)
|
||||
{
|
||||
foreach ($this->files as $file) {
|
||||
if ($file->getName() == $name) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getFiles()
|
||||
{
|
||||
return $this->files;
|
||||
}
|
||||
|
||||
public function addFile(PostFileInterface $file)
|
||||
{
|
||||
$this->files[] = $file;
|
||||
$this->mutate();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function clearFiles()
|
||||
{
|
||||
$this->files = [];
|
||||
$this->mutate();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the numbers of fields + files
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return count($this->files) + count($this->fields);
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return (string) $this->getBody();
|
||||
}
|
||||
|
||||
public function getContents($maxLength = -1)
|
||||
{
|
||||
return $this->getBody()->getContents();
|
||||
}
|
||||
|
||||
public function close()
|
||||
{
|
||||
return $this->body ? $this->body->close() : true;
|
||||
}
|
||||
|
||||
public function detach()
|
||||
{
|
||||
$this->body = null;
|
||||
$this->fields = $this->files = [];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function eof()
|
||||
{
|
||||
return $this->getBody()->eof();
|
||||
}
|
||||
|
||||
public function tell()
|
||||
{
|
||||
return $this->body ? $this->body->tell() : 0;
|
||||
}
|
||||
|
||||
public function isSeekable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function isReadable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function isWritable()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getSize()
|
||||
{
|
||||
return $this->getBody()->getSize();
|
||||
}
|
||||
|
||||
public function seek($offset, $whence = SEEK_SET)
|
||||
{
|
||||
return $this->getBody()->seek($offset, $whence);
|
||||
}
|
||||
|
||||
public function read($length)
|
||||
{
|
||||
return $this->getBody()->read($length);
|
||||
}
|
||||
|
||||
public function write($string)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a stream object that is built from the POST fields and files.
|
||||
*
|
||||
* If one has already been created, the previously created stream will be
|
||||
* returned.
|
||||
*/
|
||||
private function getBody()
|
||||
{
|
||||
if ($this->body) {
|
||||
return $this->body;
|
||||
} elseif ($this->files || $this->forceMultipart) {
|
||||
return $this->body = $this->createMultipart();
|
||||
} elseif ($this->fields) {
|
||||
return $this->body = $this->createUrlEncoded();
|
||||
} else {
|
||||
return $this->body = Stream\create();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the aggregator used to join multi-valued field parameters
|
||||
*
|
||||
* @return callable
|
||||
*/
|
||||
final protected function getAggregator()
|
||||
{
|
||||
if (!$this->aggregator) {
|
||||
$this->aggregator = Query::phpAggregator();
|
||||
}
|
||||
|
||||
return $this->aggregator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a multipart/form-data body stream
|
||||
*
|
||||
* @return MultipartBody
|
||||
*/
|
||||
private function createMultipart()
|
||||
{
|
||||
// Flatten the nested query string values using the correct aggregator
|
||||
$query = (string) (new Query($this->fields))
|
||||
->setEncodingType(false)
|
||||
->setAggregator($this->getAggregator());
|
||||
// Convert the flattened query string back into an array
|
||||
$fields = Query::fromString($query)->toArray();
|
||||
|
||||
return new MultipartBody($fields, $this->files);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an application/x-www-form-urlencoded stream body
|
||||
*
|
||||
* @return Stream\StreamInterface
|
||||
*/
|
||||
private function createUrlEncoded()
|
||||
{
|
||||
return Stream\create($this->getFields(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get rid of any cached data
|
||||
*/
|
||||
private function mutate()
|
||||
{
|
||||
$this->body = null;
|
||||
}
|
||||
}
|
|
@ -1,129 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Post;
|
||||
|
||||
use GuzzleHttp\Message\RequestInterface;
|
||||
use GuzzleHttp\Stream\StreamInterface;
|
||||
|
||||
/**
|
||||
* Represents a POST body that is sent as either a multipart/form-data stream
|
||||
* or application/x-www-urlencoded stream.
|
||||
*/
|
||||
interface PostBodyInterface extends StreamInterface, \Countable
|
||||
{
|
||||
/**
|
||||
* Apply headers to the request appropriate for the current state of the object
|
||||
*
|
||||
* @param RequestInterface $request Request
|
||||
*/
|
||||
public function applyRequestHeaders(RequestInterface $request);
|
||||
|
||||
/**
|
||||
* Set a specific field
|
||||
*
|
||||
* @param string $name Name of the field to set
|
||||
* @param string|array $value Value to set
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setField($name, $value);
|
||||
|
||||
/**
|
||||
* Set the aggregation strategy that will be used to turn multi-valued
|
||||
* fields into a string.
|
||||
*
|
||||
* The aggregation function accepts a deeply nested array of query string
|
||||
* values and returns a flattened associative array of key value pairs.
|
||||
*
|
||||
* @param callable $aggregator
|
||||
*/
|
||||
public function setAggregator(callable $aggregator);
|
||||
|
||||
/**
|
||||
* Set to true to force a multipart upload even if there are no files.
|
||||
*
|
||||
* @param bool $force Set to true to force multipart uploads or false to
|
||||
* remove this flag.
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function forceMultipartUpload($force);
|
||||
|
||||
/**
|
||||
* Replace all existing form fields with an array of fields
|
||||
*
|
||||
* @param array $fields Associative array of fields to set
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function replaceFields(array $fields);
|
||||
|
||||
/**
|
||||
* Get a specific field by name
|
||||
*
|
||||
* @param string $name Name of the POST field to retrieve
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getField($name);
|
||||
|
||||
/**
|
||||
* Remove a field by name
|
||||
*
|
||||
* @param string $name Name of the field to remove
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function removeField($name);
|
||||
|
||||
/**
|
||||
* Returns an associative array of names to values or a query string.
|
||||
*
|
||||
* @param bool $asString Set to true to retrieve the fields as a query
|
||||
* string.
|
||||
*
|
||||
* @return array|string
|
||||
*/
|
||||
public function getFields($asString = false);
|
||||
|
||||
/**
|
||||
* Returns true if a field is set
|
||||
*
|
||||
* @param string $name Name of the field to set
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasField($name);
|
||||
|
||||
/**
|
||||
* Get all of the files
|
||||
*
|
||||
* @return array Returns an array of PostFileInterface objects
|
||||
*/
|
||||
public function getFiles();
|
||||
|
||||
/**
|
||||
* Get a POST file by name.
|
||||
*
|
||||
* @param string $name Name of the POST file to retrieve
|
||||
*
|
||||
* @return PostFileInterface|null
|
||||
*/
|
||||
public function getFile($name);
|
||||
|
||||
/**
|
||||
* Add a file to the POST
|
||||
*
|
||||
* @param PostFileInterface $file File to add
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addFile(PostFileInterface $file);
|
||||
|
||||
/**
|
||||
* Remove all files from the collection
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function clearFiles();
|
||||
}
|
|
@ -1,138 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Post;
|
||||
|
||||
use GuzzleHttp\Mimetypes;
|
||||
use GuzzleHttp\Stream\MetadataStreamInterface;
|
||||
use GuzzleHttp\Stream\StreamInterface;
|
||||
|
||||
/**
|
||||
* Post file upload
|
||||
*/
|
||||
class PostFile implements PostFileInterface
|
||||
{
|
||||
private $name;
|
||||
private $filename;
|
||||
private $content;
|
||||
private $headers = [];
|
||||
|
||||
/**
|
||||
* @param null $name Name of the form field
|
||||
* @param mixed $content Data to send
|
||||
* @param null $filename Filename content-disposition attribute
|
||||
* @param array $headers Array of headers to set on the file
|
||||
* (can override any default headers)
|
||||
* @throws \RuntimeException when filename is not passed or can't be determined
|
||||
*/
|
||||
public function __construct(
|
||||
$name,
|
||||
$content,
|
||||
$filename = null,
|
||||
array $headers = []
|
||||
) {
|
||||
$this->headers = $headers;
|
||||
$this->name = $name;
|
||||
$this->prepareContent($content);
|
||||
$this->prepareFilename($filename);
|
||||
$this->prepareDefaultHeaders();
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function getFilename()
|
||||
{
|
||||
return $this->filename;
|
||||
}
|
||||
|
||||
public function getContent()
|
||||
{
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
public function getHeaders()
|
||||
{
|
||||
return $this->headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares the contents of a POST file.
|
||||
*
|
||||
* @param mixed $content Content of the POST file
|
||||
*/
|
||||
private function prepareContent($content)
|
||||
{
|
||||
$this->content = $content;
|
||||
|
||||
if (!($this->content instanceof StreamInterface)) {
|
||||
$this->content = \GuzzleHttp\Stream\create($this->content);
|
||||
} elseif ($this->content instanceof MultipartBody) {
|
||||
if (!$this->hasHeader('Content-Disposition')) {
|
||||
$disposition = 'form-data; name="' . $this->name .'"';
|
||||
$this->headers['Content-Disposition'] = $disposition;
|
||||
}
|
||||
|
||||
if (!$this->hasHeader('Content-Type')) {
|
||||
$this->headers['Content-Type'] = sprintf(
|
||||
"multipart/form-data; boundary=%s",
|
||||
$this->content->getBoundary()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies a file name to the POST file based on various checks.
|
||||
*
|
||||
* @param string|null $filename Filename to apply (or null to guess)
|
||||
*/
|
||||
private function prepareFilename($filename)
|
||||
{
|
||||
$this->filename = $filename;
|
||||
|
||||
if (!$this->filename &&
|
||||
$this->content instanceof MetadataStreamInterface
|
||||
) {
|
||||
$this->filename = $this->content->getMetadata('uri');
|
||||
}
|
||||
|
||||
if (!$this->filename || substr($this->filename, 0, 6) === 'php://') {
|
||||
$this->filename = $this->name;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies default Content-Disposition and Content-Type headers if needed.
|
||||
*/
|
||||
private function prepareDefaultHeaders()
|
||||
{
|
||||
// Set a default content-disposition header if one was no provided
|
||||
if (!$this->hasHeader('Content-Disposition')) {
|
||||
$this->headers['Content-Disposition'] = sprintf(
|
||||
'form-data; filename="%s"; name="%s"',
|
||||
basename($this->filename),
|
||||
$this->name
|
||||
);
|
||||
}
|
||||
|
||||
// Set a default Content-Type if one was not supplied
|
||||
if (!$this->hasHeader('Content-Type')) {
|
||||
$this->headers['Content-Type'] = Mimetypes::getInstance()
|
||||
->fromFilename($this->filename) ?: 'text/plain';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a specific header exists on the POST file by name.
|
||||
*
|
||||
* @param string $name Case-insensitive header to check
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function hasHeader($name)
|
||||
{
|
||||
return isset(array_change_key_case($this->headers)[strtolower($name)]);
|
||||
}
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Post;
|
||||
|
||||
use GuzzleHttp\Stream\StreamInterface;
|
||||
|
||||
/**
|
||||
* Post file upload interface
|
||||
*/
|
||||
interface PostFileInterface
|
||||
{
|
||||
/**
|
||||
* Get the name of the form field
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName();
|
||||
|
||||
/**
|
||||
* Get the full path to the file
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFilename();
|
||||
|
||||
/**
|
||||
* Get the content
|
||||
*
|
||||
* @return StreamInterface
|
||||
*/
|
||||
public function getContent();
|
||||
|
||||
/**
|
||||
* Gets all POST file headers.
|
||||
*
|
||||
* The keys represent the header name as it will be sent over the wire, and
|
||||
* each value is a string.
|
||||
*
|
||||
* @return array Returns an associative array of the file's headers.
|
||||
*/
|
||||
public function getHeaders();
|
||||
}
|
|
@ -1,226 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp;
|
||||
|
||||
/**
|
||||
* Manages query string variables and can aggregate them into a string
|
||||
*/
|
||||
class Query extends Collection
|
||||
{
|
||||
const RFC3986 = 'RFC3986';
|
||||
const RFC1738 = 'RFC1738';
|
||||
|
||||
/** @var bool URL encode fields and values */
|
||||
private $encoding = self::RFC3986;
|
||||
|
||||
/** @var callable */
|
||||
private $aggregator;
|
||||
|
||||
/**
|
||||
* Parse a query string into a Query object
|
||||
*
|
||||
* @param string $query Query string to parse
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public static function fromString($query)
|
||||
{
|
||||
$q = new static();
|
||||
if ($query === '') {
|
||||
return $q;
|
||||
}
|
||||
|
||||
$foundDuplicates = $foundPhpStyle = false;
|
||||
|
||||
foreach (explode('&', $query) as $kvp) {
|
||||
$parts = explode('=', $kvp, 2);
|
||||
$key = rawurldecode($parts[0]);
|
||||
if ($paramIsPhpStyleArray = substr($key, -2) == '[]') {
|
||||
$foundPhpStyle = true;
|
||||
$key = substr($key, 0, -2);
|
||||
}
|
||||
if (isset($parts[1])) {
|
||||
$value = rawurldecode(str_replace('+', '%20', $parts[1]));
|
||||
if (isset($q[$key])) {
|
||||
$q->add($key, $value);
|
||||
$foundDuplicates = true;
|
||||
} elseif ($paramIsPhpStyleArray) {
|
||||
$q[$key] = array($value);
|
||||
} else {
|
||||
$q[$key] = $value;
|
||||
}
|
||||
} else {
|
||||
$q->add($key, null);
|
||||
}
|
||||
}
|
||||
|
||||
// Use the duplicate aggregator if duplicates were found and not using
|
||||
// PHP style arrays.
|
||||
if ($foundDuplicates && !$foundPhpStyle) {
|
||||
$q->setAggregator(self::duplicateAggregator());
|
||||
}
|
||||
|
||||
return $q;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the query string parameters to a query string string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
if (!$this->data) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// The default aggregator is statically cached
|
||||
static $defaultAggregator;
|
||||
|
||||
if (!$this->aggregator) {
|
||||
if (!$defaultAggregator) {
|
||||
$defaultAggregator = self::phpAggregator();
|
||||
}
|
||||
$this->aggregator = $defaultAggregator;
|
||||
}
|
||||
|
||||
$result = '';
|
||||
$aggregator = $this->aggregator;
|
||||
|
||||
foreach ($aggregator($this->data) as $key => $values) {
|
||||
foreach ($values as $value) {
|
||||
if ($result) {
|
||||
$result .= '&';
|
||||
}
|
||||
if ($this->encoding == self::RFC1738) {
|
||||
$result .= urlencode($key);
|
||||
if ($value !== null) {
|
||||
$result .= '=' . urlencode($value);
|
||||
}
|
||||
} elseif ($this->encoding == self::RFC3986) {
|
||||
$result .= rawurlencode($key);
|
||||
if ($value !== null) {
|
||||
$result .= '=' . rawurlencode($value);
|
||||
}
|
||||
} else {
|
||||
$result .= $key;
|
||||
if ($value !== null) {
|
||||
$result .= '=' . $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Controls how multi-valued query string parameters are aggregated into a
|
||||
* string.
|
||||
*
|
||||
* $query->setAggregator($query::duplicateAggregator());
|
||||
*
|
||||
* @param callable $aggregator Callable used to convert a deeply nested
|
||||
* array of query string variables into a flattened array of key value
|
||||
* pairs. The callable accepts an array of query data and returns a
|
||||
* flattened array of key value pairs where each value is an array of
|
||||
* strings.
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setAggregator(callable $aggregator)
|
||||
{
|
||||
$this->aggregator = $aggregator;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify how values are URL encoded
|
||||
*
|
||||
* @param string|bool $type One of 'RFC1738', 'RFC3986', or false to disable encoding
|
||||
*
|
||||
* @return self
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function setEncodingType($type)
|
||||
{
|
||||
if ($type === false || $type === self::RFC1738 || $type === self::RFC3986) {
|
||||
$this->encoding = $type;
|
||||
} else {
|
||||
throw new \InvalidArgumentException('Invalid URL encoding type');
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Query string aggregator that does not aggregate nested query string
|
||||
* values and allows duplicates in the resulting array.
|
||||
*
|
||||
* Example: http://test.com?q=1&q=2
|
||||
*
|
||||
* @return callable
|
||||
*/
|
||||
public static function duplicateAggregator()
|
||||
{
|
||||
return function (array $data) {
|
||||
return self::walkQuery($data, '', function ($key, $prefix) {
|
||||
return is_int($key) ? $prefix : "{$prefix}[{$key}]";
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Aggregates nested query string variables using the same technique as
|
||||
* ``http_build_query()``.
|
||||
*
|
||||
* @param bool $numericIndices Pass false to not include numeric indices
|
||||
* when multi-values query string parameters are present.
|
||||
*
|
||||
* @return callable
|
||||
*/
|
||||
public static function phpAggregator($numericIndices = true)
|
||||
{
|
||||
return function (array $data) use ($numericIndices) {
|
||||
return self::walkQuery(
|
||||
$data,
|
||||
'',
|
||||
function ($key, $prefix) use ($numericIndices) {
|
||||
return !$numericIndices && is_int($key)
|
||||
? "{$prefix}[]"
|
||||
: "{$prefix}[{$key}]";
|
||||
}
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Easily create query aggregation functions by providing a key prefix
|
||||
* function to this query string array walker.
|
||||
*
|
||||
* @param array $query Query string to walk
|
||||
* @param string $keyPrefix Key prefix (start with '')
|
||||
* @param callable $prefixer Function used to create a key prefix
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function walkQuery(array $query, $keyPrefix, callable $prefixer)
|
||||
{
|
||||
$result = [];
|
||||
foreach ($query as $key => $value) {
|
||||
if ($keyPrefix) {
|
||||
$key = $prefixer($key, $keyPrefix);
|
||||
}
|
||||
if (is_array($value)) {
|
||||
$result += self::walkQuery($value, $key, $prefixer);
|
||||
} elseif (isset($result[$key])) {
|
||||
$result[$key][] = $value;
|
||||
} else {
|
||||
$result[$key] = array($value);
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Subscriber;
|
||||
|
||||
use GuzzleHttp\Event\RequestEvents;
|
||||
use GuzzleHttp\Event\SubscriberInterface;
|
||||
use GuzzleHttp\Event\CompleteEvent;
|
||||
use GuzzleHttp\Event\BeforeEvent;
|
||||
use GuzzleHttp\Cookie\CookieJar;
|
||||
use GuzzleHttp\Cookie\CookieJarInterface;
|
||||
|
||||
/**
|
||||
* Adds, extracts, and persists cookies between HTTP requests
|
||||
*/
|
||||
class Cookie implements SubscriberInterface
|
||||
{
|
||||
/** @var CookieJarInterface */
|
||||
private $cookieJar;
|
||||
|
||||
/**
|
||||
* @param CookieJarInterface $cookieJar Cookie jar used to hold cookies
|
||||
*/
|
||||
public function __construct(CookieJarInterface $cookieJar = null)
|
||||
{
|
||||
$this->cookieJar = $cookieJar ?: new CookieJar();
|
||||
}
|
||||
|
||||
public function getEvents()
|
||||
{
|
||||
// Fire the cookie plugin complete event before redirecting
|
||||
return [
|
||||
'before' => ['onBefore'],
|
||||
'complete' => ['onComplete', RequestEvents::REDIRECT_RESPONSE + 10]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the cookie cookieJar
|
||||
*
|
||||
* @return CookieJarInterface
|
||||
*/
|
||||
public function getCookieJar()
|
||||
{
|
||||
return $this->cookieJar;
|
||||
}
|
||||
|
||||
public function onBefore(BeforeEvent $event)
|
||||
{
|
||||
$this->cookieJar->addCookieHeader($event->getRequest());
|
||||
}
|
||||
|
||||
public function onComplete(CompleteEvent $event)
|
||||
{
|
||||
$this->cookieJar->extractCookies(
|
||||
$event->getRequest(),
|
||||
$event->getResponse()
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,138 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Subscriber;
|
||||
|
||||
use GuzzleHttp\Event\RequestEvents;
|
||||
use GuzzleHttp\Event\SubscriberInterface;
|
||||
use GuzzleHttp\Event\CompleteEvent;
|
||||
use GuzzleHttp\Event\ErrorEvent;
|
||||
use GuzzleHttp\Message\RequestInterface;
|
||||
use GuzzleHttp\Message\ResponseInterface;
|
||||
|
||||
/**
|
||||
* Maintains a list of requests and responses sent using a request or client
|
||||
*/
|
||||
class History implements SubscriberInterface, \IteratorAggregate, \Countable
|
||||
{
|
||||
/** @var int The maximum number of requests to maintain in the history */
|
||||
private $limit;
|
||||
|
||||
/** @var array Requests and responses that have passed through the plugin */
|
||||
private $transactions = [];
|
||||
|
||||
public function __construct($limit = 10)
|
||||
{
|
||||
$this->limit = $limit;
|
||||
}
|
||||
|
||||
public function getEvents()
|
||||
{
|
||||
return [
|
||||
'complete' => ['onComplete', RequestEvents::EARLY],
|
||||
'error' => ['onError', RequestEvents::EARLY],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert to a string that contains all request and response headers
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
$lines = array();
|
||||
foreach ($this->transactions as $entry) {
|
||||
$response = isset($entry['response']) ? $entry['response'] : '';
|
||||
$lines[] = '> ' . trim($entry['request']) . "\n\n< " . trim($response) . "\n";
|
||||
}
|
||||
|
||||
return implode("\n", $lines);
|
||||
}
|
||||
|
||||
public function onComplete(CompleteEvent $event)
|
||||
{
|
||||
$this->add($event->getRequest(), $event->getResponse());
|
||||
}
|
||||
|
||||
public function onError(ErrorEvent $event)
|
||||
{
|
||||
$this->add($event->getRequest(), $event->getResponse());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an Iterator that yields associative array values where each
|
||||
* associative array contains a 'request' and 'response' key.
|
||||
*
|
||||
* @return \Iterator
|
||||
*/
|
||||
public function getIterator()
|
||||
{
|
||||
return new \ArrayIterator($this->transactions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all of the requests sent through the plugin
|
||||
*
|
||||
* @return RequestInterface[]
|
||||
*/
|
||||
public function getRequests()
|
||||
{
|
||||
return array_map(function ($t) {
|
||||
return $t['request'];
|
||||
}, $this->transactions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of requests in the history
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return count($this->transactions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the last request sent
|
||||
*
|
||||
* @return RequestInterface
|
||||
*/
|
||||
public function getLastRequest()
|
||||
{
|
||||
return end($this->transactions)['request'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the last response in the history
|
||||
*
|
||||
* @return ResponseInterface|null
|
||||
*/
|
||||
public function getLastResponse()
|
||||
{
|
||||
return end($this->transactions)['response'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the history
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
$this->transactions = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a request to the history
|
||||
*
|
||||
* @param RequestInterface $request Request to add
|
||||
* @param ResponseInterface $response Response of the request
|
||||
*/
|
||||
private function add(
|
||||
RequestInterface $request,
|
||||
ResponseInterface $response = null
|
||||
) {
|
||||
$this->transactions[] = ['request' => $request, 'response' => $response];
|
||||
if (count($this->transactions) > $this->limit) {
|
||||
array_shift($this->transactions);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Subscriber;
|
||||
|
||||
use GuzzleHttp\Event\RequestEvents;
|
||||
use GuzzleHttp\Event\SubscriberInterface;
|
||||
use GuzzleHttp\Event\CompleteEvent;
|
||||
use GuzzleHttp\Exception\RequestException;
|
||||
|
||||
/**
|
||||
* Throws exceptions when a 4xx or 5xx response is received
|
||||
*/
|
||||
class HttpError implements SubscriberInterface
|
||||
{
|
||||
public function getEvents()
|
||||
{
|
||||
return ['complete' => ['onComplete', RequestEvents::VERIFY_RESPONSE]];
|
||||
}
|
||||
|
||||
/**
|
||||
* Throw a RequestException on an HTTP protocol error
|
||||
*
|
||||
* @param CompleteEvent $event Emitted event
|
||||
* @throws RequestException
|
||||
*/
|
||||
public function onComplete(CompleteEvent $event)
|
||||
{
|
||||
$code = (string) $event->getResponse()->getStatusCode();
|
||||
// Throw an exception for an unsuccessful response
|
||||
if ($code[0] === '4' || $code[0] === '5') {
|
||||
throw RequestException::create($event->getRequest(), $event->getResponse());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,143 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Subscriber;
|
||||
|
||||
use GuzzleHttp\Event\RequestEvents;
|
||||
use GuzzleHttp\Event\SubscriberInterface;
|
||||
use GuzzleHttp\Adapter\Transaction;
|
||||
use GuzzleHttp\Event\BeforeEvent;
|
||||
use GuzzleHttp\Event\HeadersEvent;
|
||||
use GuzzleHttp\Exception\RequestException;
|
||||
use GuzzleHttp\Message\MessageFactory;
|
||||
use GuzzleHttp\Message\ResponseInterface;
|
||||
|
||||
/**
|
||||
* Queues mock responses or exceptions and delivers mock responses or
|
||||
* exceptions in a fifo order.
|
||||
*/
|
||||
class Mock implements SubscriberInterface, \Countable
|
||||
{
|
||||
/** @var array Array of mock responses / exceptions */
|
||||
private $queue = [];
|
||||
|
||||
/** @var bool Whether or not to consume an entity body when mocking */
|
||||
private $readBodies;
|
||||
|
||||
/** @var MessageFactory */
|
||||
private $factory;
|
||||
|
||||
/**
|
||||
* @param array $items Array of responses or exceptions to queue
|
||||
* @param bool $readBodies Set to false to not consume the entity body of
|
||||
* a request when a mock is served.
|
||||
*/
|
||||
public function __construct(array $items = [], $readBodies = true)
|
||||
{
|
||||
$this->factory = new MessageFactory();
|
||||
$this->readBodies = $readBodies;
|
||||
$this->addMultiple($items);
|
||||
}
|
||||
|
||||
public function getEvents()
|
||||
{
|
||||
// Fire the event last, after signing
|
||||
return ['before' => ['onBefore', RequestEvents::SIGN_REQUEST - 10]];
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \OutOfBoundsException|\Exception
|
||||
*/
|
||||
public function onBefore(BeforeEvent $event)
|
||||
{
|
||||
if (!$item = array_shift($this->queue)) {
|
||||
throw new \OutOfBoundsException('Mock queue is empty');
|
||||
} elseif ($item instanceof RequestException) {
|
||||
throw $item;
|
||||
}
|
||||
|
||||
// Emulate the receiving of the response headers
|
||||
$request = $event->getRequest();
|
||||
$transaction = new Transaction($event->getClient(), $request);
|
||||
$transaction->setResponse($item);
|
||||
$request->getEmitter()->emit(
|
||||
'headers',
|
||||
new HeadersEvent($transaction)
|
||||
);
|
||||
|
||||
// Emulate reading a response body
|
||||
if ($this->readBodies && $request->getBody()) {
|
||||
while (!$request->getBody()->eof()) {
|
||||
$request->getBody()->read(8096);
|
||||
}
|
||||
}
|
||||
|
||||
$event->intercept($item);
|
||||
}
|
||||
|
||||
public function count()
|
||||
{
|
||||
return count($this->queue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a response to the end of the queue
|
||||
*
|
||||
* @param string|ResponseInterface $response Response or path to response file
|
||||
*
|
||||
* @return self
|
||||
* @throws \InvalidArgumentException if a string or Response is not passed
|
||||
*/
|
||||
public function addResponse($response)
|
||||
{
|
||||
if (is_string($response)) {
|
||||
$response = file_exists($response)
|
||||
? $this->factory->fromMessage(file_get_contents($response))
|
||||
: $this->factory->fromMessage($response);
|
||||
} elseif (!($response instanceof ResponseInterface)) {
|
||||
throw new \InvalidArgumentException('Response must a message '
|
||||
. 'string, response object, or path to a file');
|
||||
}
|
||||
|
||||
$this->queue[] = $response;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an exception to the end of the queue
|
||||
*
|
||||
* @param RequestException $e Exception to throw when the request is executed
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function addException(RequestException $e)
|
||||
{
|
||||
$this->queue[] = $e;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add multiple items to the queue
|
||||
*
|
||||
* @param array $items Items to add
|
||||
*/
|
||||
public function addMultiple(array $items)
|
||||
{
|
||||
foreach ($items as $item) {
|
||||
if ($item instanceof RequestException) {
|
||||
$this->addException($item);
|
||||
} else {
|
||||
$this->addResponse($item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the queue
|
||||
*/
|
||||
public function clearQueue()
|
||||
{
|
||||
$this->queue = [];
|
||||
}
|
||||
}
|
|
@ -1,136 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Subscriber;
|
||||
|
||||
use GuzzleHttp\Event\RequestEvents;
|
||||
use GuzzleHttp\Event\SubscriberInterface;
|
||||
use GuzzleHttp\Message\RequestInterface;
|
||||
use GuzzleHttp\Event\BeforeEvent;
|
||||
use GuzzleHttp\Post\PostBodyInterface;
|
||||
use GuzzleHttp\Stream\StreamInterface;
|
||||
use GuzzleHttp\Stream\MetadataStreamInterface;
|
||||
use GuzzleHttp\Mimetypes;
|
||||
|
||||
/**
|
||||
* Prepares requests with a body before sending
|
||||
*
|
||||
* **Request Options**
|
||||
*
|
||||
* - expect: Set to true to enable the "Expect: 100-Continue" header for a
|
||||
* request that send a body. Set to false to disable "Expect: 100-Continue".
|
||||
* Set to a number so that the size of the payload must be greater than the
|
||||
* number in order to send the Expect header. Setting to a number will send
|
||||
* the Expect header for all requests in which the size of the payload cannot
|
||||
* be determined or where the body is not rewindable.
|
||||
*/
|
||||
class Prepare implements SubscriberInterface
|
||||
{
|
||||
public function getEvents()
|
||||
{
|
||||
return ['before' => ['onBefore', RequestEvents::PREPARE_REQUEST]];
|
||||
}
|
||||
|
||||
public function onBefore(BeforeEvent $event)
|
||||
{
|
||||
$request = $event->getRequest();
|
||||
|
||||
// Set the appropriate Content-Type for a request if one is not set and
|
||||
// there are form fields
|
||||
if (!($body = $request->getBody())) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->addContentLength($request, $body);
|
||||
|
||||
if ($body instanceof PostBodyInterface) {
|
||||
// Synchronize the POST body with the request's headers
|
||||
$body->applyRequestHeaders($request);
|
||||
} elseif (!$request->hasHeader('Content-Type')) {
|
||||
$this->addContentType($request, $body);
|
||||
}
|
||||
|
||||
$this->addExpectHeader($request, $body);
|
||||
}
|
||||
|
||||
private function addContentType(
|
||||
RequestInterface $request,
|
||||
StreamInterface $body
|
||||
) {
|
||||
if (!($body instanceof MetadataStreamInterface)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!($uri = $body->getMetadata('uri'))) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Guess the content-type based on the stream's "uri" metadata value.
|
||||
// The file extension is used to determine the appropriate mime-type.
|
||||
if ($contentType = Mimetypes::getInstance()->fromFilename($uri)) {
|
||||
$request->setHeader('Content-Type', $contentType);
|
||||
}
|
||||
}
|
||||
|
||||
private function addContentLength(
|
||||
RequestInterface $request,
|
||||
StreamInterface $body
|
||||
) {
|
||||
// Set the Content-Length header if it can be determined, and never
|
||||
// send a Transfer-Encoding: chunked and Content-Length header in
|
||||
// the same request.
|
||||
if ($request->hasHeader('Content-Length')) {
|
||||
// Remove transfer-encoding if content-length is set.
|
||||
$request->removeHeader('Transfer-Encoding');
|
||||
return;
|
||||
}
|
||||
|
||||
if ($request->hasHeader('Transfer-Encoding')) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (null !== ($size = $body->getSize())) {
|
||||
$request->setHeader('Content-Length', $size)
|
||||
->removeHeader('Transfer-Encoding');
|
||||
} elseif ('1.1' == $request->getProtocolVersion()) {
|
||||
// Use chunked Transfer-Encoding if there is no determinable
|
||||
// content-length header and we're using HTTP/1.1.
|
||||
$request->setHeader('Transfer-Encoding', 'chunked')
|
||||
->removeHeader('Content-Length');
|
||||
}
|
||||
}
|
||||
|
||||
private function addExpectHeader(
|
||||
RequestInterface $request,
|
||||
StreamInterface $body
|
||||
) {
|
||||
// Determine if the Expect header should be used
|
||||
if ($request->hasHeader('Expect')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$expect = $request->getConfig()['expect'];
|
||||
|
||||
// Return if disabled or if you're not using HTTP/1.1
|
||||
if ($expect === false || $request->getProtocolVersion() !== '1.1') {
|
||||
return;
|
||||
}
|
||||
|
||||
// The expect header is unconditionally enabled
|
||||
if ($expect === true) {
|
||||
$request->setHeader('Expect', '100-Continue');
|
||||
return;
|
||||
}
|
||||
|
||||
// By default, send the expect header when the payload is > 1mb
|
||||
if ($expect === null) {
|
||||
$expect = 1048576;
|
||||
}
|
||||
|
||||
// Always add if the body cannot be rewound, the size cannot be
|
||||
// determined, or the size is greater than the cutoff threshold
|
||||
$size = $body->getSize();
|
||||
if ($size === null || $size >= (int) $expect || !$body->isSeekable()) {
|
||||
$request->setHeader('Expect', '100-Continue');
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,172 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Subscriber;
|
||||
|
||||
use GuzzleHttp\Event\RequestEvents;
|
||||
use GuzzleHttp\Event\SubscriberInterface;
|
||||
use GuzzleHttp\Event\CompleteEvent;
|
||||
use GuzzleHttp\Exception\TooManyRedirectsException;
|
||||
use GuzzleHttp\Exception\CouldNotRewindStreamException;
|
||||
use GuzzleHttp\Message\RequestInterface;
|
||||
use GuzzleHttp\Message\ResponseInterface;
|
||||
use GuzzleHttp\Url;
|
||||
|
||||
/**
|
||||
* Subscriber used to implement HTTP redirects.
|
||||
*
|
||||
* **Request options**
|
||||
*
|
||||
* - redirect: Associative array containing the 'max', 'strict', and 'referer'
|
||||
* keys.
|
||||
*
|
||||
* - max: Maximum number of redirects allowed per-request
|
||||
* - strict: You can use strict redirects by setting this value to ``true``.
|
||||
* Strict redirects adhere to strict RFC compliant redirection (e.g.,
|
||||
* redirect POST with POST) vs doing what most clients do (e.g., redirect
|
||||
* POST request with a GET request).
|
||||
* - referer: Set to true to automatically add the "Referer" header when a
|
||||
* redirect request is sent.
|
||||
*/
|
||||
class Redirect implements SubscriberInterface
|
||||
{
|
||||
public function getEvents()
|
||||
{
|
||||
return ['complete' => ['onComplete', RequestEvents::REDIRECT_RESPONSE]];
|
||||
}
|
||||
|
||||
/**
|
||||
* Rewind the entity body of the request if needed
|
||||
*
|
||||
* @param RequestInterface $redirectRequest
|
||||
* @throws CouldNotRewindStreamException
|
||||
*/
|
||||
public static function rewindEntityBody(RequestInterface $redirectRequest)
|
||||
{
|
||||
// Rewind the entity body of the request if needed
|
||||
if ($redirectRequest->getBody()) {
|
||||
$body = $redirectRequest->getBody();
|
||||
// Only rewind the body if some of it has been read already, and
|
||||
// throw an exception if the rewind fails
|
||||
if ($body->tell() && !$body->seek(0)) {
|
||||
throw new CouldNotRewindStreamException(
|
||||
'Unable to rewind the non-seekable request body after redirecting',
|
||||
$redirectRequest
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a request receives a redirect response
|
||||
*
|
||||
* @param CompleteEvent $event Event emitted
|
||||
* @throws TooManyRedirectsException
|
||||
*/
|
||||
public function onComplete(CompleteEvent $event)
|
||||
{
|
||||
$response = $event->getResponse();
|
||||
|
||||
if (substr($response->getStatusCode(), 0, 1) != '3' ||
|
||||
!$response->hasHeader('Location')
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
$redirectCount = 0;
|
||||
$request = $event->getRequest();
|
||||
$redirectResponse = $response;
|
||||
$max = $request->getConfig()->getPath('redirect/max') ?: 5;
|
||||
|
||||
do {
|
||||
if (++$redirectCount > $max) {
|
||||
throw new TooManyRedirectsException(
|
||||
"Will not follow more than {$redirectCount} redirects",
|
||||
$request
|
||||
);
|
||||
}
|
||||
$redirectRequest = $this->createRedirectRequest($request, $redirectResponse);
|
||||
$redirectResponse = $event->getClient()->send($redirectRequest);
|
||||
} while (substr($redirectResponse->getStatusCode(), 0, 1) == '3' &&
|
||||
$redirectResponse->hasHeader('Location')
|
||||
);
|
||||
|
||||
if ($redirectResponse !== $response) {
|
||||
$event->intercept($redirectResponse);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a redirect request for a specific request object
|
||||
*
|
||||
* Takes into account strict RFC compliant redirection (e.g. redirect POST
|
||||
* with POST) vs doing what most clients do (e.g. redirect POST with GET).
|
||||
*
|
||||
* @param RequestInterface $request
|
||||
* @param ResponseInterface $response
|
||||
*
|
||||
* @return RequestInterface Returns a new redirect request
|
||||
* @throws CouldNotRewindStreamException If the body cannot be rewound.
|
||||
*/
|
||||
private function createRedirectRequest(
|
||||
RequestInterface $request,
|
||||
ResponseInterface $response
|
||||
) {
|
||||
$config = $request->getConfig();
|
||||
|
||||
// Use a GET request if this is an entity enclosing request and we are
|
||||
// not forcing RFC compliance, but rather emulating what all browsers
|
||||
// would do. Be sure to disable redirects on the clone.
|
||||
$redirectRequest = clone $request;
|
||||
$redirectRequest->getEmitter()->detach($this);
|
||||
$statusCode = $response->getStatusCode();
|
||||
|
||||
if ($statusCode == 303 ||
|
||||
($statusCode <= 302 && $request->getBody() &&
|
||||
!$config->getPath('redirect/strict'))
|
||||
) {
|
||||
$redirectRequest->setMethod('GET');
|
||||
$redirectRequest->setBody(null);
|
||||
}
|
||||
|
||||
$this->setRedirectUrl($redirectRequest, $response);
|
||||
$this->rewindEntityBody($redirectRequest);
|
||||
|
||||
// Add the Referer header if it is told to do so and only
|
||||
// add the header if we are not redirecting from https to http.
|
||||
if ($config->getPath('redirect/referer') && (
|
||||
$redirectRequest->getScheme() == 'https' ||
|
||||
$redirectRequest->getScheme() == $request->getScheme()
|
||||
)) {
|
||||
$url = Url::fromString($request->getUrl());
|
||||
$url->setUsername(null)->setPassword(null);
|
||||
$redirectRequest->setHeader('Referer', (string) $url);
|
||||
}
|
||||
|
||||
return $redirectRequest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the appropriate URL on the request based on the location header
|
||||
*
|
||||
* @param RequestInterface $redirectRequest
|
||||
* @param ResponseInterface $response
|
||||
*/
|
||||
private function setRedirectUrl(
|
||||
RequestInterface $redirectRequest,
|
||||
ResponseInterface $response
|
||||
) {
|
||||
$location = $response->getHeader('Location');
|
||||
$location = Url::fromString($location);
|
||||
|
||||
// Combine location with the original URL if it is not absolute.
|
||||
if (!$location->isAbsolute()) {
|
||||
$originalUrl = Url::fromString($redirectRequest->getUrl());
|
||||
// Remove query string parameters and just take what is present on
|
||||
// the redirect Location header
|
||||
$originalUrl->getQuery()->clear();
|
||||
$location = $originalUrl->combine($location);
|
||||
}
|
||||
|
||||
$redirectRequest->setUrl($location);
|
||||
}
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp;
|
||||
|
||||
/**
|
||||
* An object that can be represented as an array
|
||||
*/
|
||||
interface ToArrayInterface
|
||||
{
|
||||
/**
|
||||
* Get the array representation of an object
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray();
|
||||
}
|
|
@ -1,242 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp;
|
||||
|
||||
/**
|
||||
* Expands URI templates. Userland implementation of PECL uri_template.
|
||||
*
|
||||
* @link http://tools.ietf.org/html/rfc6570
|
||||
*/
|
||||
class UriTemplate
|
||||
{
|
||||
/** @var string URI template */
|
||||
private $template;
|
||||
|
||||
/** @var array Variables to use in the template expansion */
|
||||
private $variables;
|
||||
|
||||
/** @var array Hash for quick operator lookups */
|
||||
private static $operatorHash = array(
|
||||
'' => array('prefix' => '', 'joiner' => ',', 'query' => false),
|
||||
'+' => array('prefix' => '', 'joiner' => ',', 'query' => false),
|
||||
'#' => array('prefix' => '#', 'joiner' => ',', 'query' => false),
|
||||
'.' => array('prefix' => '.', 'joiner' => '.', 'query' => false),
|
||||
'/' => array('prefix' => '/', 'joiner' => '/', 'query' => false),
|
||||
';' => array('prefix' => ';', 'joiner' => ';', 'query' => true),
|
||||
'?' => array('prefix' => '?', 'joiner' => '&', 'query' => true),
|
||||
'&' => array('prefix' => '&', 'joiner' => '&', 'query' => true)
|
||||
);
|
||||
|
||||
/** @var array Delimiters */
|
||||
private static $delims = array(':', '/', '?', '#', '[', ']', '@', '!', '$',
|
||||
'&', '\'', '(', ')', '*', '+', ',', ';', '=');
|
||||
|
||||
/** @var array Percent encoded delimiters */
|
||||
private static $delimsPct = array('%3A', '%2F', '%3F', '%23', '%5B', '%5D',
|
||||
'%40', '%21', '%24', '%26', '%27', '%28', '%29', '%2A', '%2B', '%2C',
|
||||
'%3B', '%3D');
|
||||
|
||||
public function expand($template, array $variables)
|
||||
{
|
||||
if (false === strpos($template, '{')) {
|
||||
return $template;
|
||||
}
|
||||
|
||||
$this->template = $template;
|
||||
$this->variables = $variables;
|
||||
|
||||
return preg_replace_callback(
|
||||
'/\{([^\}]+)\}/',
|
||||
[$this, 'expandMatch'],
|
||||
$this->template
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse an expression into parts
|
||||
*
|
||||
* @param string $expression Expression to parse
|
||||
*
|
||||
* @return array Returns an associative array of parts
|
||||
*/
|
||||
private function parseExpression($expression)
|
||||
{
|
||||
$result = array();
|
||||
|
||||
if (isset(self::$operatorHash[$expression[0]])) {
|
||||
$result['operator'] = $expression[0];
|
||||
$expression = substr($expression, 1);
|
||||
} else {
|
||||
$result['operator'] = '';
|
||||
}
|
||||
|
||||
foreach (explode(',', $expression) as $value) {
|
||||
$value = trim($value);
|
||||
$varspec = array();
|
||||
if ($colonPos = strpos($value, ':')) {
|
||||
$varspec['value'] = substr($value, 0, $colonPos);
|
||||
$varspec['modifier'] = ':';
|
||||
$varspec['position'] = (int) substr($value, $colonPos + 1);
|
||||
} elseif (substr($value, -1) == '*') {
|
||||
$varspec['modifier'] = '*';
|
||||
$varspec['value'] = substr($value, 0, -1);
|
||||
} else {
|
||||
$varspec['value'] = (string) $value;
|
||||
$varspec['modifier'] = '';
|
||||
}
|
||||
$result['values'][] = $varspec;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process an expansion
|
||||
*
|
||||
* @param array $matches Matches met in the preg_replace_callback
|
||||
*
|
||||
* @return string Returns the replacement string
|
||||
*/
|
||||
private function expandMatch(array $matches)
|
||||
{
|
||||
static $rfc1738to3986 = array('+' => '%20', '%7e' => '~');
|
||||
|
||||
$replacements = array();
|
||||
$parsed = self::parseExpression($matches[1]);
|
||||
$prefix = self::$operatorHash[$parsed['operator']]['prefix'];
|
||||
$joiner = self::$operatorHash[$parsed['operator']]['joiner'];
|
||||
$useQuery = self::$operatorHash[$parsed['operator']]['query'];
|
||||
|
||||
foreach ($parsed['values'] as $value) {
|
||||
|
||||
if (!isset($this->variables[$value['value']])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$variable = $this->variables[$value['value']];
|
||||
$actuallyUseQuery = $useQuery;
|
||||
$expanded = '';
|
||||
|
||||
if (is_array($variable)) {
|
||||
|
||||
$isAssoc = $this->isAssoc($variable);
|
||||
$kvp = array();
|
||||
foreach ($variable as $key => $var) {
|
||||
|
||||
if ($isAssoc) {
|
||||
$key = rawurlencode($key);
|
||||
$isNestedArray = is_array($var);
|
||||
} else {
|
||||
$isNestedArray = false;
|
||||
}
|
||||
|
||||
if (!$isNestedArray) {
|
||||
$var = rawurlencode($var);
|
||||
if ($parsed['operator'] == '+' ||
|
||||
$parsed['operator'] == '#'
|
||||
) {
|
||||
$var = $this->decodeReserved($var);
|
||||
}
|
||||
}
|
||||
|
||||
if ($value['modifier'] == '*') {
|
||||
if ($isAssoc) {
|
||||
if ($isNestedArray) {
|
||||
// Nested arrays must allow for deeply nested
|
||||
// structures.
|
||||
$var = strtr(
|
||||
http_build_query([$key => $var]),
|
||||
$rfc1738to3986
|
||||
);
|
||||
} else {
|
||||
$var = $key . '=' . $var;
|
||||
}
|
||||
} elseif ($key > 0 && $actuallyUseQuery) {
|
||||
$var = $value['value'] . '=' . $var;
|
||||
}
|
||||
}
|
||||
|
||||
$kvp[$key] = $var;
|
||||
}
|
||||
|
||||
if (empty($variable)) {
|
||||
$actuallyUseQuery = false;
|
||||
} elseif ($value['modifier'] == '*') {
|
||||
$expanded = implode($joiner, $kvp);
|
||||
if ($isAssoc) {
|
||||
// Don't prepend the value name when using the explode
|
||||
// modifier with an associative array.
|
||||
$actuallyUseQuery = false;
|
||||
}
|
||||
} else {
|
||||
if ($isAssoc) {
|
||||
// When an associative array is encountered and the
|
||||
// explode modifier is not set, then the result must be
|
||||
// a comma separated list of keys followed by their
|
||||
// respective values.
|
||||
foreach ($kvp as $k => &$v) {
|
||||
$v = $k . ',' . $v;
|
||||
}
|
||||
}
|
||||
$expanded = implode(',', $kvp);
|
||||
}
|
||||
|
||||
} else {
|
||||
if ($value['modifier'] == ':') {
|
||||
$variable = substr($variable, 0, $value['position']);
|
||||
}
|
||||
$expanded = rawurlencode($variable);
|
||||
if ($parsed['operator'] == '+' || $parsed['operator'] == '#') {
|
||||
$expanded = $this->decodeReserved($expanded);
|
||||
}
|
||||
}
|
||||
|
||||
if ($actuallyUseQuery) {
|
||||
if (!$expanded && $joiner != '&') {
|
||||
$expanded = $value['value'];
|
||||
} else {
|
||||
$expanded = $value['value'] . '=' . $expanded;
|
||||
}
|
||||
}
|
||||
|
||||
$replacements[] = $expanded;
|
||||
}
|
||||
|
||||
$ret = implode($joiner, $replacements);
|
||||
if ($ret && $prefix) {
|
||||
return $prefix . $ret;
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if an array is associative.
|
||||
*
|
||||
* This makes the assumption that input arrays are sequences or hashes.
|
||||
* This assumption is a tradeoff for accuracy in favor of speed, but it
|
||||
* should work in almost every case where input is supplied for a URI
|
||||
* template.
|
||||
*
|
||||
* @param array $array Array to check
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function isAssoc(array $array)
|
||||
{
|
||||
return $array && array_keys($array)[0] !== 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes percent encoding on reserved characters (used with + and #
|
||||
* modifiers).
|
||||
*
|
||||
* @param string $string String to fix
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function decodeReserved($string)
|
||||
{
|
||||
return str_replace(self::$delimsPct, self::$delims, $string);
|
||||
}
|
||||
}
|
|
@ -1,585 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp;
|
||||
|
||||
/**
|
||||
* Parses and generates URLs based on URL parts
|
||||
*/
|
||||
class Url
|
||||
{
|
||||
private $scheme;
|
||||
private $host;
|
||||
private $port;
|
||||
private $username;
|
||||
private $password;
|
||||
private $path = '';
|
||||
private $fragment;
|
||||
private static $defaultPorts = ['http' => 80, 'https' => 443, 'ftp' => 21];
|
||||
|
||||
/** @var Query Query part of the URL */
|
||||
private $query;
|
||||
|
||||
/**
|
||||
* Factory method to create a new URL from a URL string
|
||||
*
|
||||
* @param string $url Full URL used to create a Url object
|
||||
*
|
||||
* @return Url
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public static function fromString($url)
|
||||
{
|
||||
static $defaults = array('scheme' => null, 'host' => null,
|
||||
'path' => null, 'port' => null, 'query' => null,
|
||||
'user' => null, 'pass' => null, 'fragment' => null);
|
||||
|
||||
if (false === ($parts = parse_url($url))) {
|
||||
throw new \InvalidArgumentException('Unable to parse malformed '
|
||||
. 'url: ' . $url);
|
||||
}
|
||||
|
||||
$parts += $defaults;
|
||||
|
||||
// Convert the query string into a Query object
|
||||
if ($parts['query'] || 0 !== strlen($parts['query'])) {
|
||||
$parts['query'] = Query::fromString($parts['query']);
|
||||
}
|
||||
|
||||
return new static($parts['scheme'], $parts['host'], $parts['user'],
|
||||
$parts['pass'], $parts['port'], $parts['path'], $parts['query'],
|
||||
$parts['fragment']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a URL from parse_url parts. The generated URL will be a relative
|
||||
* URL if a scheme or host are not provided.
|
||||
*
|
||||
* @param array $parts Array of parse_url parts
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function buildUrl(array $parts)
|
||||
{
|
||||
$url = $scheme = '';
|
||||
|
||||
if (!empty($parts['scheme'])) {
|
||||
$scheme = $parts['scheme'];
|
||||
$url .= $scheme . ':';
|
||||
}
|
||||
|
||||
if (!empty($parts['host'])) {
|
||||
$url .= '//';
|
||||
if (isset($parts['user'])) {
|
||||
$url .= $parts['user'];
|
||||
if (isset($parts['pass'])) {
|
||||
$url .= ':' . $parts['pass'];
|
||||
}
|
||||
$url .= '@';
|
||||
}
|
||||
|
||||
$url .= $parts['host'];
|
||||
|
||||
// Only include the port if it is not the default port of the scheme
|
||||
if (isset($parts['port']) &&
|
||||
(!isset(self::$defaultPorts[$scheme]) ||
|
||||
$parts['port'] != self::$defaultPorts[$scheme])
|
||||
) {
|
||||
$url .= ':' . $parts['port'];
|
||||
}
|
||||
}
|
||||
|
||||
// Add the path component if present
|
||||
if (isset($parts['path']) && strlen($parts['path'])) {
|
||||
// Always ensure that the path begins with '/' if set and something
|
||||
// is before the path
|
||||
if (isset($parts['host']) && $parts['path'][0] != '/') {
|
||||
$url .= '/';
|
||||
}
|
||||
$url .= $parts['path'];
|
||||
}
|
||||
|
||||
// Add the query string if present
|
||||
if (isset($parts['query'])) {
|
||||
$queryStr = (string) $parts['query'];
|
||||
if ($queryStr || $queryStr === '0') {
|
||||
$url .= '?' . $queryStr;
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that # is only added to the url if fragment contains anything.
|
||||
if (isset($parts['fragment'])) {
|
||||
$url .= '#' . $parts['fragment'];
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new URL from URL parts
|
||||
*
|
||||
* @param string $scheme Scheme of the URL
|
||||
* @param string $host Host of the URL
|
||||
* @param string $username Username of the URL
|
||||
* @param string $password Password of the URL
|
||||
* @param int $port Port of the URL
|
||||
* @param string $path Path of the URL
|
||||
* @param Query|array|string $query Query string of the URL
|
||||
* @param string $fragment Fragment of the URL
|
||||
*/
|
||||
public function __construct(
|
||||
$scheme,
|
||||
$host,
|
||||
$username = null,
|
||||
$password = null,
|
||||
$port = null,
|
||||
$path = null,
|
||||
Query $query = null,
|
||||
$fragment = null
|
||||
) {
|
||||
$this->scheme = $scheme;
|
||||
$this->host = $host;
|
||||
$this->port = $port;
|
||||
$this->username = $username;
|
||||
$this->password = $password;
|
||||
$this->fragment = $fragment;
|
||||
if (!$query) {
|
||||
$this->query = new Query();
|
||||
} else {
|
||||
$this->setQuery($query);
|
||||
}
|
||||
$this->setPath($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clone the URL
|
||||
*/
|
||||
public function __clone()
|
||||
{
|
||||
$this->query = clone $this->query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URL as a URL string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return static::buildUrl($this->getParts());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the parts of the URL as an array
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getParts()
|
||||
{
|
||||
return array(
|
||||
'scheme' => $this->scheme,
|
||||
'user' => $this->username,
|
||||
'pass' => $this->password,
|
||||
'host' => $this->host,
|
||||
'port' => $this->port,
|
||||
'path' => $this->path,
|
||||
'query' => $this->query,
|
||||
'fragment' => $this->fragment,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the host of the request.
|
||||
*
|
||||
* @param string $host Host to set (e.g. www.yahoo.com, yahoo.com)
|
||||
*
|
||||
* @return Url
|
||||
*/
|
||||
public function setHost($host)
|
||||
{
|
||||
if (strpos($host, ':') === false) {
|
||||
$this->host = $host;
|
||||
} else {
|
||||
list($host, $port) = explode(':', $host);
|
||||
$this->host = $host;
|
||||
$this->setPort($port);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the host part of the URL
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getHost()
|
||||
{
|
||||
return $this->host;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the scheme part of the URL (http, https, ftp, etc.)
|
||||
*
|
||||
* @param string $scheme Scheme to set
|
||||
*
|
||||
* @return Url
|
||||
*/
|
||||
public function setScheme($scheme)
|
||||
{
|
||||
// Remove the default port if one is specified
|
||||
if ($this->port && isset(self::$defaultPorts[$this->scheme]) &&
|
||||
self::$defaultPorts[$this->scheme] == $this->port
|
||||
) {
|
||||
$this->port = null;
|
||||
}
|
||||
|
||||
$this->scheme = $scheme;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the scheme part of the URL
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getScheme()
|
||||
{
|
||||
return $this->scheme;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the port part of the URL
|
||||
*
|
||||
* @param int $port Port to set
|
||||
*
|
||||
* @return Url
|
||||
*/
|
||||
public function setPort($port)
|
||||
{
|
||||
$this->port = $port;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the port part of the URl.
|
||||
*
|
||||
* If no port was set, this method will return the default port for the
|
||||
* scheme of the URI.
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public function getPort()
|
||||
{
|
||||
if ($this->port) {
|
||||
return $this->port;
|
||||
} elseif (isset(self::$defaultPorts[$this->scheme])) {
|
||||
return self::$defaultPorts[$this->scheme];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the path part of the URL
|
||||
*
|
||||
* @param string $path Path string to set
|
||||
*
|
||||
* @return Url
|
||||
*/
|
||||
public function setPath($path)
|
||||
{
|
||||
static $search = [' ', '?'];
|
||||
static $replace = ['%20', '%3F'];
|
||||
$this->path = str_replace($search, $replace, $path);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes dot segments from a URL
|
||||
*
|
||||
* @return Url
|
||||
* @link http://tools.ietf.org/html/rfc3986#section-5.2.4
|
||||
*/
|
||||
public function removeDotSegments()
|
||||
{
|
||||
static $noopPaths = ['' => true, '/' => true, '*' => true];
|
||||
static $ignoreSegments = ['' => true, '.' => true, '..' => true];
|
||||
|
||||
if (isset($noopPaths[$this->path])) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$results = [];
|
||||
$segments = $this->getPathSegments();
|
||||
foreach ($segments as $segment) {
|
||||
if ($segment == '..') {
|
||||
array_pop($results);
|
||||
} elseif (!isset($ignoreSegments[$segment])) {
|
||||
$results[] = $segment;
|
||||
}
|
||||
}
|
||||
|
||||
// Combine the normalized parts and add the leading slash if needed
|
||||
if ($this->path[0] == '/') {
|
||||
$this->path = '/' . implode('/', $results);
|
||||
} else {
|
||||
$this->path = implode('/', $results);
|
||||
}
|
||||
|
||||
// Add the trailing slash if necessary
|
||||
if ($this->path != '/' && isset($ignoreSegments[end($segments)])) {
|
||||
$this->path .= '/';
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a relative path to the currently set path.
|
||||
*
|
||||
* @param string $relativePath Relative path to add
|
||||
*
|
||||
* @return Url
|
||||
*/
|
||||
public function addPath($relativePath)
|
||||
{
|
||||
if ($relativePath != '/' &&
|
||||
is_string($relativePath) &&
|
||||
strlen($relativePath) > 0
|
||||
) {
|
||||
// Add a leading slash if needed
|
||||
if ($relativePath[0] != '/') {
|
||||
$relativePath = '/' . $relativePath;
|
||||
}
|
||||
$this->setPath(str_replace('//', '/', $this->path . $relativePath));
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the path part of the URL
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPath()
|
||||
{
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the path segments of the URL as an array
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getPathSegments()
|
||||
{
|
||||
return explode('/', $this->path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the password part of the URL
|
||||
*
|
||||
* @param string $password Password to set
|
||||
*
|
||||
* @return Url
|
||||
*/
|
||||
public function setPassword($password)
|
||||
{
|
||||
$this->password = $password;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the password part of the URL
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getPassword()
|
||||
{
|
||||
return $this->password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the username part of the URL
|
||||
*
|
||||
* @param string $username Username to set
|
||||
*
|
||||
* @return Url
|
||||
*/
|
||||
public function setUsername($username)
|
||||
{
|
||||
$this->username = $username;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the username part of the URl
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getUsername()
|
||||
{
|
||||
return $this->username;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the query part of the URL as a Query object
|
||||
*
|
||||
* @return Query
|
||||
*/
|
||||
public function getQuery()
|
||||
{
|
||||
return $this->query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the query part of the URL
|
||||
*
|
||||
* @param Query|string|array $query Query string value to set. Can
|
||||
* be a string that will be parsed into a Query object, an array
|
||||
* of key value pairs, or a Query object.
|
||||
*
|
||||
* @return Url
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function setQuery($query)
|
||||
{
|
||||
if ($query instanceof Query) {
|
||||
$this->query = $query;
|
||||
} elseif (is_string($query)) {
|
||||
$this->query = Query::fromString($query);
|
||||
} elseif (is_array($query)) {
|
||||
$this->query = new Query($query);
|
||||
} else {
|
||||
throw new \InvalidArgumentException('Query must be a '
|
||||
. 'QueryInterface, array, or string');
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the fragment part of the URL
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getFragment()
|
||||
{
|
||||
return $this->fragment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the fragment part of the URL
|
||||
*
|
||||
* @param string $fragment Fragment to set
|
||||
*
|
||||
* @return Url
|
||||
*/
|
||||
public function setFragment($fragment)
|
||||
{
|
||||
$this->fragment = $fragment;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this is an absolute URL
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isAbsolute()
|
||||
{
|
||||
return $this->scheme && $this->host;
|
||||
}
|
||||
|
||||
/**
|
||||
* Combine the URL with another URL and return a new URL instance.
|
||||
*
|
||||
* Follows the rules specific in RFC 3986 section 5.4.
|
||||
*
|
||||
* @param string $url Relative URL to combine with
|
||||
*
|
||||
* @return Url
|
||||
* @throws \InvalidArgumentException
|
||||
* @link http://tools.ietf.org/html/rfc3986#section-5.4
|
||||
*/
|
||||
public function combine($url)
|
||||
{
|
||||
$url = static::fromString($url);
|
||||
|
||||
// Use the more absolute URL as the base URL
|
||||
if (!$this->isAbsolute() && $url->isAbsolute()) {
|
||||
$url = $url->combine($this);
|
||||
}
|
||||
|
||||
$parts = $url->getParts();
|
||||
|
||||
// Passing a URL with a scheme overrides everything
|
||||
if ($parts['scheme']) {
|
||||
return new static(
|
||||
$parts['scheme'],
|
||||
$parts['host'],
|
||||
$parts['user'],
|
||||
$parts['pass'],
|
||||
$parts['port'],
|
||||
$parts['path'],
|
||||
clone $parts['query'],
|
||||
$parts['fragment']
|
||||
);
|
||||
}
|
||||
|
||||
// Setting a host overrides the entire rest of the URL
|
||||
if ($parts['host']) {
|
||||
return new static(
|
||||
$this->scheme,
|
||||
$parts['host'],
|
||||
$parts['user'],
|
||||
$parts['pass'],
|
||||
$parts['port'],
|
||||
$parts['path'],
|
||||
clone $parts['query'],
|
||||
$parts['fragment']
|
||||
);
|
||||
}
|
||||
|
||||
if (!$parts['path']) {
|
||||
// The relative URL has no path, so check if it is just a query
|
||||
$path = $this->path ?: '';
|
||||
$query = count($parts['query']) ? $parts['query'] : $this->query;
|
||||
} else {
|
||||
$query = $parts['query'];
|
||||
if ($parts['path'][0] == '/' || !$this->path) {
|
||||
// Overwrite the existing path if the rel path starts with "/"
|
||||
$path = $parts['path'];
|
||||
} else {
|
||||
// If the relative URL does not have a path or the base URL
|
||||
// path does not end in a "/" then overwrite the existing path
|
||||
// up to the last "/"
|
||||
$path = substr($this->path, 0, strrpos($this->path, '/') + 1) . $parts['path'];
|
||||
}
|
||||
}
|
||||
|
||||
$result = new self(
|
||||
$this->scheme,
|
||||
$this->host,
|
||||
$this->username,
|
||||
$this->password,
|
||||
$this->port,
|
||||
$path,
|
||||
clone $query,
|
||||
$parts['fragment']
|
||||
);
|
||||
|
||||
if ($path) {
|
||||
$result->removeDotSegments();
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -1,325 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp;
|
||||
|
||||
use GuzzleHttp\Event\CompleteEvent;
|
||||
use GuzzleHttp\Event\ErrorEvent;
|
||||
use GuzzleHttp\Event\RequestEvents;
|
||||
use GuzzleHttp\Message\ResponseInterface;
|
||||
use GuzzleHttp\UriTemplate;
|
||||
|
||||
/**
|
||||
* Send a custom request
|
||||
*
|
||||
* @param string $method HTTP request method
|
||||
* @param string $url URL of the request
|
||||
* @param array $options Options to use with the request.
|
||||
*
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
function request($method, $url, array $options = [])
|
||||
{
|
||||
static $client;
|
||||
if (!$client) {
|
||||
$client = new Client();
|
||||
}
|
||||
|
||||
return $client->send($client->createRequest($method, $url, $options));
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a GET request
|
||||
*
|
||||
* @param string $url URL of the request
|
||||
* @param array $options Array of request options
|
||||
*
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
function get($url, array $options = [])
|
||||
{
|
||||
return request('GET', $url, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a HEAD request
|
||||
*
|
||||
* @param string $url URL of the request
|
||||
* @param array $options Array of request options
|
||||
*
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
function head($url, array $options = [])
|
||||
{
|
||||
return request('HEAD', $url, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a DELETE request
|
||||
*
|
||||
* @param string $url URL of the request
|
||||
* @param array $options Array of request options
|
||||
*
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
function delete($url, array $options = [])
|
||||
{
|
||||
return request('DELETE', $url, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a POST request
|
||||
*
|
||||
* @param string $url URL of the request
|
||||
* @param array $options Array of request options
|
||||
*
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
function post($url, array $options = [])
|
||||
{
|
||||
return request('POST', $url, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a PUT request
|
||||
*
|
||||
* @param string $url URL of the request
|
||||
* @param array $options Array of request options
|
||||
*
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
function put($url, array $options = [])
|
||||
{
|
||||
return request('PUT', $url, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a PATCH request
|
||||
*
|
||||
* @param string $url URL of the request
|
||||
* @param array $options Array of request options
|
||||
*
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
function patch($url, array $options = [])
|
||||
{
|
||||
return request('PATCH', $url, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an OPTIONS request
|
||||
*
|
||||
* @param string $url URL of the request
|
||||
* @param array $options Array of request options
|
||||
*
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
function options($url, array $options = [])
|
||||
{
|
||||
return request('OPTIONS', $url, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method for sending multiple requests in parallel and retrieving
|
||||
* a hash map of requests to response objects or RequestException objects.
|
||||
*
|
||||
* Note: This method keeps every request and response in memory, and as such is
|
||||
* NOT recommended when sending a large number or an indeterminable number of
|
||||
* requests in parallel.
|
||||
*
|
||||
* @param ClientInterface $client Client used to send the requests
|
||||
* @param array|\Iterator $requests Requests to send in parallel
|
||||
* @param array $options Passes through the options available in
|
||||
* {@see GuzzleHttp\ClientInterface::sendAll()}
|
||||
* @return \SplObjectStorage Requests are the key and each value is a
|
||||
* {@see GuzzleHttp\Message\ResponseInterface} if the request succeeded or
|
||||
* a {@see GuzzleHttp\Exception\RequestException} if it failed.
|
||||
* @throws \InvalidArgumentException if the event format is incorrect.
|
||||
*/
|
||||
function batch(ClientInterface $client, $requests, array $options = [])
|
||||
{
|
||||
$hash = new \SplObjectStorage();
|
||||
foreach ($requests as $request) {
|
||||
$hash->attach($request);
|
||||
}
|
||||
|
||||
// Merge the necessary complete and error events to the event listeners so
|
||||
// that as each request succeeds or fails, it is added to the result hash.
|
||||
$options = RequestEvents::convertEventArray(
|
||||
$options,
|
||||
['complete', 'error'],
|
||||
[
|
||||
'priority' => RequestEvents::EARLY,
|
||||
'once' => true,
|
||||
'fn' => function ($e) use ($hash) { $hash[$e->getRequest()] = $e; }
|
||||
]
|
||||
);
|
||||
|
||||
// Send the requests in parallel and aggregate the results.
|
||||
$client->sendAll($requests, $options);
|
||||
|
||||
// Update the received value for any of the intercepted requests.
|
||||
foreach ($hash as $request) {
|
||||
if ($hash[$request] instanceof CompleteEvent) {
|
||||
$hash[$request] = $hash[$request]->getResponse();
|
||||
} elseif ($hash[$request] instanceof ErrorEvent) {
|
||||
$hash[$request] = $hash[$request]->getException();
|
||||
}
|
||||
}
|
||||
|
||||
return $hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a value from an array using a path syntax to retrieve nested data.
|
||||
*
|
||||
* This method does not allow for keys that contain "/". You must traverse
|
||||
* the array manually or using something more advanced like JMESPath to
|
||||
* work with keys that contain "/".
|
||||
*
|
||||
* // Get the bar key of a set of nested arrays.
|
||||
* // This is equivalent to $collection['foo']['baz']['bar'] but won't
|
||||
* // throw warnings for missing keys.
|
||||
* GuzzleHttp\get_path($data, 'foo/baz/bar');
|
||||
*
|
||||
* @param array $data Data to retrieve values from
|
||||
* @param string $path Path to traverse and retrieve a value from
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
function get_path($data, $path)
|
||||
{
|
||||
$path = explode('/', $path);
|
||||
|
||||
while (null !== ($part = array_shift($path))) {
|
||||
if (!is_array($data) || !isset($data[$part])) {
|
||||
return null;
|
||||
}
|
||||
$data = $data[$part];
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a value in a nested array key. Keys will be created as needed to set the
|
||||
* value.
|
||||
*
|
||||
* This function does not support keys that contain "/" or "[]" characters
|
||||
* because these are special tokens used when traversing the data structure.
|
||||
* A value may be prepended to an existing array by using "[]" as the final
|
||||
* key of a path.
|
||||
*
|
||||
* GuzzleHttp\get_path($data, 'foo/baz'); // null
|
||||
* GuzzleHttp\set_path($data, 'foo/baz/[]', 'a');
|
||||
* GuzzleHttp\set_path($data, 'foo/baz/[]', 'b');
|
||||
* GuzzleHttp\get_path($data, 'foo/baz');
|
||||
* // Returns ['a', 'b']
|
||||
*
|
||||
* @param array $data Data to modify by reference
|
||||
* @param string $path Path to set
|
||||
* @param mixed $value Value to set at the key
|
||||
* @throws \RuntimeException when trying to setPath using a nested path that
|
||||
* travels through a scalar value.
|
||||
*/
|
||||
function set_path(&$data, $path, $value)
|
||||
{
|
||||
$current =& $data;
|
||||
$queue = explode('/', $path);
|
||||
while (null !== ($key = array_shift($queue))) {
|
||||
if (!is_array($current)) {
|
||||
throw new \RuntimeException("Trying to setPath {$path}, but "
|
||||
. "{$key} is set and is not an array");
|
||||
} elseif (!$queue) {
|
||||
if ($key == '[]') {
|
||||
$current[] = $value;
|
||||
} else {
|
||||
$current[$key] = $value;
|
||||
}
|
||||
} elseif (isset($current[$key])) {
|
||||
$current =& $current[$key];
|
||||
} else {
|
||||
$current[$key] = [];
|
||||
$current =& $current[$key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Expands a URI template
|
||||
*
|
||||
* @param string $template URI template
|
||||
* @param array $variables Template variables
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function uri_template($template, array $variables)
|
||||
{
|
||||
if (function_exists('\\uri_template')) {
|
||||
return \uri_template($template, $variables);
|
||||
}
|
||||
|
||||
static $uriTemplate;
|
||||
if (!$uriTemplate) {
|
||||
$uriTemplate = new UriTemplate();
|
||||
}
|
||||
|
||||
return $uriTemplate->expand($template, $variables);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for JSON decode that implements error detection with helpful error
|
||||
* messages.
|
||||
*
|
||||
* @param string $json JSON data to parse
|
||||
* @param bool $assoc When true, returned objects will be converted into
|
||||
* associative arrays.
|
||||
* @param int $depth User specified recursion depth.
|
||||
* @param int $options Bitmask of JSON decode options.
|
||||
*
|
||||
* @return mixed
|
||||
* @throws \InvalidArgumentException if the JSON cannot be parsed.
|
||||
* @link http://www.php.net/manual/en/function.json-decode.php
|
||||
*/
|
||||
function json_decode($json, $assoc = false, $depth = 512, $options = 0)
|
||||
{
|
||||
static $jsonErrors = [
|
||||
JSON_ERROR_DEPTH => 'JSON_ERROR_DEPTH - Maximum stack depth exceeded',
|
||||
JSON_ERROR_STATE_MISMATCH => 'JSON_ERROR_STATE_MISMATCH - Underflow or the modes mismatch',
|
||||
JSON_ERROR_CTRL_CHAR => 'JSON_ERROR_CTRL_CHAR - Unexpected control character found',
|
||||
JSON_ERROR_SYNTAX => 'JSON_ERROR_SYNTAX - Syntax error, malformed JSON',
|
||||
JSON_ERROR_UTF8 => 'JSON_ERROR_UTF8 - Malformed UTF-8 characters, possibly incorrectly encoded'
|
||||
];
|
||||
|
||||
$data = \json_decode($json, $assoc, $depth, $options);
|
||||
|
||||
if (JSON_ERROR_NONE !== json_last_error()) {
|
||||
$last = json_last_error();
|
||||
throw new \InvalidArgumentException(
|
||||
'Unable to parse JSON data: '
|
||||
. (isset($jsonErrors[$last]) ? $jsonErrors[$last] : 'Unknown error')
|
||||
);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
function deprecation_proxy($object, $name, $arguments, $map)
|
||||
{
|
||||
if (!isset($map[$name])) {
|
||||
throw new \BadMethodCallException('Unknown method, ' . $name);
|
||||
}
|
||||
|
||||
$message = sprintf('%s is deprecated and will be removed in a future '
|
||||
. 'version. Update your code to use the equivalent %s method '
|
||||
. 'instead to avoid breaking changes when this shim is removed.',
|
||||
get_class($object) . '::' . $name . '()',
|
||||
get_class($object) . '::' . $map[$name] . '()'
|
||||
);
|
||||
|
||||
trigger_error($message, E_USER_DEPRECATED);
|
||||
|
||||
return call_user_func_array([$object, $map[$name]], $arguments);
|
||||
}
|
|
@ -1,192 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Base;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Base
|
||||
*/
|
||||
abstract class Collection
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $aItems;
|
||||
|
||||
/**
|
||||
* @access protected
|
||||
*/
|
||||
protected function __construct()
|
||||
{
|
||||
$this->aItems = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $mItem
|
||||
* @param bool $bToTop = false
|
||||
* @return self
|
||||
*/
|
||||
public function Add($mItem, $bToTop = false)
|
||||
{
|
||||
if ($bToTop)
|
||||
{
|
||||
\array_unshift($this->aItems, $mItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
\array_push($this->aItems, $mItem);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $aItems
|
||||
* @return self
|
||||
*
|
||||
* @throws \MailSo\Base\Exceptions\InvalidArgumentException
|
||||
*/
|
||||
public function AddArray($aItems)
|
||||
{
|
||||
if (!\is_array($aItems))
|
||||
{
|
||||
throw new \MailSo\Base\Exceptions\InvalidArgumentException();
|
||||
}
|
||||
|
||||
foreach ($aItems as $mItem)
|
||||
{
|
||||
$this->Add($mItem);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return self
|
||||
*/
|
||||
public function Clear()
|
||||
{
|
||||
$this->aItems = array();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function CloneAsArray()
|
||||
{
|
||||
return $this->aItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function Count()
|
||||
{
|
||||
return \count($this->aItems);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function &GetAsArray()
|
||||
{
|
||||
return $this->aItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $mCallback
|
||||
*/
|
||||
public function MapList($mCallback)
|
||||
{
|
||||
$aResult = array();
|
||||
if (\is_callable($mCallback))
|
||||
{
|
||||
foreach ($this->aItems as $oItem)
|
||||
{
|
||||
$aResult[] = \call_user_func($mCallback, $oItem);
|
||||
}
|
||||
}
|
||||
|
||||
return $aResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $mCallback
|
||||
* @return array
|
||||
*/
|
||||
public function FilterList($mCallback)
|
||||
{
|
||||
$aResult = array();
|
||||
if (\is_callable($mCallback))
|
||||
{
|
||||
foreach ($this->aItems as $oItem)
|
||||
{
|
||||
if (\call_user_func($mCallback, $oItem))
|
||||
{
|
||||
$aResult[] = $oItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $aResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $mCallback
|
||||
* @return void
|
||||
*/
|
||||
public function ForeachList($mCallback)
|
||||
{
|
||||
if (\is_callable($mCallback))
|
||||
{
|
||||
foreach ($this->aItems as $oItem)
|
||||
{
|
||||
\call_user_func($mCallback, $oItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed | null
|
||||
* @return mixed
|
||||
*/
|
||||
public function &GetByIndex($iIndex)
|
||||
{
|
||||
$mResult = null;
|
||||
if (\key_exists($iIndex, $this->aItems))
|
||||
{
|
||||
$mResult = $this->aItems[$iIndex];
|
||||
}
|
||||
|
||||
return $mResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $aItems
|
||||
* @return self
|
||||
*
|
||||
* @throws \MailSo\Base\Exceptions\InvalidArgumentException
|
||||
*/
|
||||
public function SetAsArray($aItems)
|
||||
{
|
||||
if (!\is_array($aItems))
|
||||
{
|
||||
throw new \MailSo\Base\Exceptions\InvalidArgumentException();
|
||||
}
|
||||
|
||||
$this->aItems = $aItems;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
|
@ -1,189 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Base;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Base
|
||||
*/
|
||||
class Crypt
|
||||
{
|
||||
/**
|
||||
*
|
||||
* @param string $sString
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function XxteaEncrypt($sString, $sKey)
|
||||
{
|
||||
if (0 === \strlen($sString))
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
$aV = self::str2long($sString, true);
|
||||
$aK = self::str2long($sKey, false);
|
||||
if (\count($aK) < 4)
|
||||
{
|
||||
for ($iIndex = \count($aK); $iIndex < 4; $iIndex++)
|
||||
{
|
||||
$aK[$iIndex] = 0;
|
||||
}
|
||||
}
|
||||
$iN = \count($aV) - 1;
|
||||
|
||||
$iZ = $aV[$iN];
|
||||
$iY = $aV[0];
|
||||
$iDelta = 0x9E3779B9;
|
||||
$iQ = \floor(6 + 52 / ($iN + 1));
|
||||
$iSum = 0;
|
||||
while (0 < $iQ--)
|
||||
{
|
||||
$iSum = self::int32($iSum + $iDelta);
|
||||
$iE = $iSum >> 2 & 3;
|
||||
for ($iPIndex = 0; $iPIndex < $iN; $iPIndex++)
|
||||
{
|
||||
$iY = $aV[$iPIndex + 1];
|
||||
$iMx = self::int32((($iZ >> 5 & 0x07ffffff) ^ $iY << 2) +
|
||||
(($iY >> 3 & 0x1fffffff) ^ $iZ << 4)) ^ self::int32(($iSum ^ $iY) + ($aK[$iPIndex & 3 ^ $iE] ^ $iZ));
|
||||
$iZ = $aV[$iPIndex] = self::int32($aV[$iPIndex] + $iMx);
|
||||
}
|
||||
$iY = $aV[0];
|
||||
$iMx = self::int32((($iZ >> 5 & 0x07ffffff) ^ $iY << 2) +
|
||||
(($iY >> 3 & 0x1fffffff) ^ $iZ << 4)) ^ self::int32(($iSum ^ $iY) + ($aK[$iPIndex & 3 ^ $iE] ^ $iZ));
|
||||
$iZ = $aV[$iN] = self::int32($aV[$iN] + $iMx);
|
||||
}
|
||||
|
||||
return self::long2str($aV, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sEncriptedString
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function XxteaDecrypt($sEncriptedString, $sKey)
|
||||
{
|
||||
if (0 === \strlen($sEncriptedString))
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
$aV = self::str2long($sEncriptedString, false);
|
||||
$aK = self::str2long($sKey, false);
|
||||
|
||||
if (\count($aK) < 4)
|
||||
{
|
||||
for ($iIndex = \count($aK); $iIndex < 4; $iIndex++)
|
||||
{
|
||||
$aK[$iIndex] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
$iN = \count($aV) - 1;
|
||||
|
||||
$iZ = $aV[$iN];
|
||||
$iY = $aV[0];
|
||||
$iDelta = 0x9E3779B9;
|
||||
$iQ = \floor(6 + 52 / ($iN + 1));
|
||||
$iSum = self::int32($iQ * $iDelta);
|
||||
while ($iSum != 0)
|
||||
{
|
||||
$iE = $iSum >> 2 & 3;
|
||||
for ($iPIndex = $iN; $iPIndex > 0; $iPIndex--)
|
||||
{
|
||||
$iZ = $aV[$iPIndex - 1];
|
||||
$iMx = self::int32((($iZ >> 5 & 0x07ffffff) ^ $iY << 2) +
|
||||
(($iY >> 3 & 0x1fffffff) ^ $iZ << 4)) ^ self::int32(($iSum ^ $iY) + ($aK[$iPIndex & 3 ^ $iE] ^ $iZ));
|
||||
$iY = $aV[$iPIndex] = self::int32($aV[$iPIndex] - $iMx);
|
||||
}
|
||||
$iZ = $aV[$iN];
|
||||
$iMx = self::int32((($iZ >> 5 & 0x07ffffff) ^ $iY << 2) +
|
||||
(($iY >> 3 & 0x1fffffff) ^ $iZ << 4)) ^ self::int32(($iSum ^ $iY) + ($aK[$iPIndex & 3 ^ $iE] ^ $iZ));
|
||||
$iY = $aV[0] = self::int32($aV[0] - $iMx);
|
||||
$iSum = self::int32($iSum - $iDelta);
|
||||
}
|
||||
|
||||
return self::long2str($aV, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $aV
|
||||
* @param array $aW
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function long2str($aV, $aW)
|
||||
{
|
||||
$iLen = \count($aV);
|
||||
$iN = ($iLen - 1) << 2;
|
||||
if ($aW)
|
||||
{
|
||||
$iM = $aV[$iLen - 1];
|
||||
if (($iM < $iN - 3) || ($iM > $iN))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
$iN = $iM;
|
||||
}
|
||||
$aS = array();
|
||||
for ($iIndex = 0; $iIndex < $iLen; $iIndex++)
|
||||
{
|
||||
$aS[$iIndex] = \pack('V', $aV[$iIndex]);
|
||||
}
|
||||
if ($aW)
|
||||
{
|
||||
return \substr(\join('', $aS), 0, $iN);
|
||||
}
|
||||
else
|
||||
{
|
||||
return \join('', $aS);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sS
|
||||
* @param string $sW
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private static function str2long($sS, $sW)
|
||||
{
|
||||
$aV = \unpack('V*', $sS . \str_repeat("\0", (4 - \strlen($sS) % 4) & 3));
|
||||
$aV = \array_values($aV);
|
||||
if ($sW)
|
||||
{
|
||||
$aV[\count($aV)] = \strlen($sS);
|
||||
}
|
||||
return $aV;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iN
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private static function int32($iN)
|
||||
{
|
||||
while ($iN >= 2147483648)
|
||||
{
|
||||
$iN -= 4294967296;
|
||||
}
|
||||
while ($iN <= -2147483649)
|
||||
{
|
||||
$iN += 4294967296;
|
||||
}
|
||||
return (int) $iN;
|
||||
}
|
||||
}
|
|
@ -1,89 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Base;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Base
|
||||
*/
|
||||
class DateTimeHelper
|
||||
{
|
||||
/**
|
||||
* @access private
|
||||
*/
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @staticvar \DateTimeZone $oDateTimeZone
|
||||
*
|
||||
* @return \DateTimeZone
|
||||
*/
|
||||
public static function GetUtcTimeZoneObject()
|
||||
{
|
||||
static $oDateTimeZone = null;
|
||||
if (null === $oDateTimeZone)
|
||||
{
|
||||
$oDateTimeZone = new \DateTimeZone('UTC');
|
||||
}
|
||||
return $oDateTimeZone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse date string formated as "Thu, 10 Jun 2010 08:58:33 -0700 (PDT)"
|
||||
* RFC2822
|
||||
*
|
||||
* @param string $sDateTime
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function ParseRFC2822DateString($sDateTime)
|
||||
{
|
||||
$sDateTime = \trim(\preg_replace('/ \([a-zA-Z0-9]+\)$/', '', \trim($sDateTime)));
|
||||
$oDateTime = \DateTime::createFromFormat('D, d M Y H:i:s O', $sDateTime, \MailSo\Base\DateTimeHelper::GetUtcTimeZoneObject());
|
||||
return $oDateTime ? $oDateTime->getTimestamp() : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse date string formated as "10-Jan-2012 01:58:17 -0800"
|
||||
* IMAP INTERNALDATE Format
|
||||
*
|
||||
* @param string $sDateTime
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function ParseInternalDateString($sDateTime)
|
||||
{
|
||||
$sDateTime = \trim($sDateTime);
|
||||
if (\preg_match('/^[a-z]{2,4}, /i', $sDateTime)) // RFC2822
|
||||
{
|
||||
return \MailSo\Base\DateTimeHelper::ParseRFC2822DateString($sDateTime);
|
||||
}
|
||||
|
||||
$oDateTime = \DateTime::createFromFormat('d-M-Y H:i:s O', $sDateTime, \MailSo\Base\DateTimeHelper::GetUtcTimeZoneObject());
|
||||
return $oDateTime ? $oDateTime->getTimestamp() : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse date string formated as "2011-06-14 23:59:59 +0400"
|
||||
*
|
||||
* @param string $sDateTime
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function ParseDateStringType1($sDateTime)
|
||||
{
|
||||
$oDateTime = \DateTime::createFromFormat('Y-m-d H:i:s O', \trim($sDateTime), \MailSo\Base\DateTimeHelper::GetUtcTimeZoneObject());
|
||||
return $oDateTime ? $oDateTime->getTimestamp() : 0;
|
||||
}
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Base\Enumerations;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Base
|
||||
* @subpackage Enumerations
|
||||
*/
|
||||
class Charset
|
||||
{
|
||||
const UTF_8 = 'utf-8';
|
||||
const UTF_7 = 'utf-7';
|
||||
const UTF_7_IMAP = 'utf7-imap';
|
||||
const WIN_1250 = 'windows-1250';
|
||||
const WIN_1251 = 'windows-1251';
|
||||
const WIN_1252 = 'windows-1252';
|
||||
const WIN_1253 = 'windows-1253';
|
||||
const WIN_1254 = 'windows-1254';
|
||||
const WIN_1255 = 'windows-1255';
|
||||
const WIN_1256 = 'windows-1256';
|
||||
const WIN_1257 = 'windows-1257';
|
||||
const WIN_1258 = 'windows-1258';
|
||||
const ISO_8859_1 = 'iso-8859-1';
|
||||
const ISO_8859_8 = 'iso-8859-8';
|
||||
const ISO_8859_8_I = 'iso-8859-8-i';
|
||||
const ISO_2022_JP = 'iso-2022-jp';
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Base\Enumerations;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Base
|
||||
* @subpackage Enumerations
|
||||
*/
|
||||
class Encoding
|
||||
{
|
||||
const QUOTED_PRINTABLE = 'Quoted-Printable';
|
||||
const QUOTED_PRINTABLE_LOWER = 'quoted-printable';
|
||||
const QUOTED_PRINTABLE_SHORT = 'Q';
|
||||
|
||||
const BASE64 = 'Base64';
|
||||
const BASE64_LOWER = 'base64';
|
||||
const BASE64_SHORT = 'B';
|
||||
|
||||
const SEVEN_BIT = '7bit';
|
||||
const _7_BIT = '7bit';
|
||||
const EIGHT_BIT = '8bit';
|
||||
const _8_BIT = '8bit';
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Base\Exceptions;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Base
|
||||
* @subpackage Exceptions
|
||||
*/
|
||||
class Exception extends \Exception
|
||||
{
|
||||
/**
|
||||
* @param string $sMessage
|
||||
* @param int $iCode
|
||||
* @param \Exception|null $oPrevious
|
||||
*/
|
||||
public function __construct($sMessage = '', $iCode = 0, $oPrevious = null)
|
||||
{
|
||||
$sMessage = 0 === strlen($sMessage) ? str_replace('\\', '-', get_class($this)).' ('.
|
||||
basename($this->getFile()).' ~ '.$this->getLine().')' : $sMessage;
|
||||
|
||||
parent::__construct($sMessage, $iCode, $oPrevious);
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Base\Exceptions;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Base
|
||||
* @subpackage Exceptions
|
||||
*/
|
||||
class InvalidArgumentException extends \MailSo\Base\Exceptions\Exception {}
|
File diff suppressed because it is too large
Load diff
|
@ -1,780 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Base;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Base
|
||||
*/
|
||||
class Http
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $bIsMagicQuotesOn;
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*/
|
||||
private function __construct()
|
||||
{
|
||||
$this->bIsMagicQuotesOn = (bool) @\ini_get('magic_quotes_gpc');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \MailSo\Base\Http
|
||||
*/
|
||||
public static function NewInstance()
|
||||
{
|
||||
return new self();
|
||||
}
|
||||
|
||||
/**
|
||||
* @staticvar \MailSo\Base\Http $oInstance;
|
||||
*
|
||||
* @return \MailSo\Base\Http
|
||||
*/
|
||||
public static function SingletonInstance()
|
||||
{
|
||||
static $oInstance = null;
|
||||
if (null === $oInstance)
|
||||
{
|
||||
$oInstance = self::NewInstance();
|
||||
}
|
||||
|
||||
return $oInstance;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function HasQuery($sKey)
|
||||
{
|
||||
return isset($_GET[$sKey]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sKey
|
||||
* @param mixed $mDefault = null
|
||||
* @param bool $bClearPercZeroZero = true
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function GetQuery($sKey, $mDefault = null, $bClearPercZeroZero = true)
|
||||
{
|
||||
return isset($_GET[$sKey]) ? \MailSo\Base\Utils::StripSlashesValue($_GET[$sKey], $bClearPercZeroZero) : $mDefault;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|null
|
||||
*/
|
||||
public function GetQueryAsArray()
|
||||
{
|
||||
return isset($_GET) && \is_array($_GET) ? \MailSo\Base\Utils::StripSlashesValue($_GET, true) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function HasPost($sKey)
|
||||
{
|
||||
return isset($_POST[$sKey]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sKey
|
||||
* @param mixed $mDefault = null
|
||||
* @param bool $bClearPercZeroZero = false
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function GetPost($sKey, $mDefault = null, $bClearPercZeroZero = false)
|
||||
{
|
||||
return isset($_POST[$sKey]) ? \MailSo\Base\Utils::StripSlashesValue($_POST[$sKey], $bClearPercZeroZero) : $mDefault;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|null
|
||||
*/
|
||||
public function GetPostAsArray()
|
||||
{
|
||||
return isset($_POST) && \is_array($_POST) ? \MailSo\Base\Utils::StripSlashesValue($_POST, false) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function HasRequest($sKey)
|
||||
{
|
||||
return isset($_REQUEST[$sKey]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sKey
|
||||
* @param mixed $mDefault = null
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function GetRequest($sKey, $mDefault = null)
|
||||
{
|
||||
return isset($_REQUEST[$sKey]) ? \MailSo\Base\Utils::StripSlashesValue($_REQUEST[$sKey]) : $mDefault;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function HasServer($sKey)
|
||||
{
|
||||
return isset($_SERVER[$sKey]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sKey
|
||||
* @param mixed $mDefault = null
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function GetServer($sKey, $mDefault = null)
|
||||
{
|
||||
return isset($_SERVER[$sKey]) ? $_SERVER[$sKey] : $mDefault;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function HasEnv($sKey)
|
||||
{
|
||||
return isset($_ENV[$sKey]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sKey
|
||||
* @param mixed $mDefault = null
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function GetEnv($sKey, $mDefault = null)
|
||||
{
|
||||
return isset($_ENV[$sKey]) ? $_ENV[$sKey] : $mDefault;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function ServerProtocol()
|
||||
{
|
||||
return $this->GetServer('SERVER_PROTOCOL', 'HTTP/1.0');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function GetMethod()
|
||||
{
|
||||
return $this->GetServer('REQUEST_METHOD', '');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsPost()
|
||||
{
|
||||
return ('POST' === $this->GetMethod());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsGet()
|
||||
{
|
||||
return ('GET' === $this->GetMethod());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function GetQueryString()
|
||||
{
|
||||
return $this->GetServer('QUERY_STRING', '');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function CheckLocalhost($sServer)
|
||||
{
|
||||
return \in_array(\strtolower(\trim($sServer)), array(
|
||||
'localhost', '127.0.0.1', '::1', '::1/128', '0:0:0:0:0:0:0:1'
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sValueToCheck = ''
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function IsLocalhost($sValueToCheck = '')
|
||||
{
|
||||
if (empty($sValueToCheck))
|
||||
{
|
||||
$sValueToCheck = $this->GetServer('REMOTE_ADDR', '');
|
||||
}
|
||||
|
||||
return $this->CheckLocalhost($sValueToCheck);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function GetRawBody()
|
||||
{
|
||||
static $sRawBody = null;
|
||||
if (null === $sRawBody)
|
||||
{
|
||||
$sBody = @\file_get_contents('php://input');
|
||||
$sRawBody = (false !== $sBody) ? $sBody : '';
|
||||
}
|
||||
return $sRawBody;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sHeader
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function GetHeader($sHeader)
|
||||
{
|
||||
$sResultHeader = '';
|
||||
$sServerKey = 'HTTP_'.\strtoupper(\str_replace('-', '_', $sHeader));
|
||||
$sResultHeader = $this->GetServer($sServerKey, '');
|
||||
|
||||
if (0 === \strlen($sResultHeader) &&
|
||||
\MailSo\Base\Utils::FunctionExistsAndEnabled('apache_request_headers'))
|
||||
{
|
||||
$sHeaders = \apache_request_headers();
|
||||
if (isset($sHeaders[$sHeader]))
|
||||
{
|
||||
$sResultHeader = $sHeaders[$sHeader];
|
||||
}
|
||||
}
|
||||
|
||||
return $sResultHeader;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function GetScheme()
|
||||
{
|
||||
$sHttps = \strtolower($this->GetServer('HTTPS', ''));
|
||||
return ('on' === $sHttps || ('' === $sHttps && '443' === (string) $this->GetServer('SERVER_PORT', ''))) ? 'https' : 'http';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsSecure()
|
||||
{
|
||||
return ('https' === $this->GetScheme());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $bWithRemoteUserData = false
|
||||
* @param bool $bWithoutWWW = true
|
||||
* @param bool $bWithoutPort = false
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function GetHost($bWithRemoteUserData = false, $bWithoutWWW = true, $bWithoutPort = false)
|
||||
{
|
||||
$sHost = $this->GetServer('HTTP_HOST', '');
|
||||
if (0 === \strlen($sHost))
|
||||
{
|
||||
$sScheme = $this->GetScheme();
|
||||
$sName = $this->GetServer('SERVER_NAME');
|
||||
$iPort = (int) $this->GetServer('SERVER_PORT');
|
||||
|
||||
$sHost = (('http' === $sScheme && 80 === $iPort) || ('https' === $sScheme && 443 === $iPort))
|
||||
? $sName : $sName.':'.$iPort;
|
||||
}
|
||||
|
||||
if ($bWithoutWWW)
|
||||
{
|
||||
$sHost = 'www.' === \substr(\strtolower($sHost), 0, 4) ? \substr($sHost, 4) : $sHost;
|
||||
}
|
||||
|
||||
if ($bWithRemoteUserData)
|
||||
{
|
||||
$sUser = \trim($this->HasServer('REMOTE_USER') ? $this->GetServer('REMOTE_USER', '') : '');
|
||||
$sHost = (0 < \strlen($sUser) ? $sUser.'@' : '').$sHost;
|
||||
}
|
||||
|
||||
if ($bWithoutPort)
|
||||
{
|
||||
$sHost = \preg_replace('/:[\d]+$/', '', $sHost);
|
||||
}
|
||||
|
||||
return $sHost;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $bCheckProxy = false
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function GetClientIp($bCheckProxy = false)
|
||||
{
|
||||
$sIp = '';
|
||||
if ($bCheckProxy && null !== $this->GetServer('HTTP_CLIENT_IP', null))
|
||||
{
|
||||
$sIp = $this->GetServer('HTTP_CLIENT_IP', '');
|
||||
}
|
||||
else if ($bCheckProxy && null !== $this->GetServer('HTTP_X_FORWARDED_FOR', null))
|
||||
{
|
||||
$sIp = $this->GetServer('HTTP_X_FORWARDED_FOR', '');
|
||||
}
|
||||
else
|
||||
{
|
||||
$sIp = $this->GetServer('REMOTE_ADDR', '');
|
||||
}
|
||||
|
||||
return $sIp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sUrl
|
||||
* @param array $aPost = array()
|
||||
* @param string $sCustomUserAgent = 'MailSo Http User Agent (v1)'
|
||||
* @param int $iCode = 0
|
||||
* @param \MailSo\Log\Logger $oLogger = null
|
||||
* @param int $iTimeout = 20
|
||||
* @param string $sProxy = ''
|
||||
* @param string $sProxyAuth = ''
|
||||
*
|
||||
* @return string|bool
|
||||
*/
|
||||
public function SendPostRequest($sUrl, $aPost = array(), $sCustomUserAgent = 'MailSo Http User Agent (v1)', &$iCode = 0,
|
||||
$oLogger = null, $iTimeout = 20, $sProxy = '', $sProxyAuth = '')
|
||||
{
|
||||
$aOptions = array(
|
||||
CURLOPT_URL => $sUrl,
|
||||
CURLOPT_HEADER => false,
|
||||
CURLOPT_FAILONERROR => true,
|
||||
CURLOPT_SSL_VERIFYPEER => false,
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_POST => true,
|
||||
CURLOPT_POSTFIELDS => \http_build_query($aPost, '', '&'),
|
||||
CURLOPT_TIMEOUT => (int) $iTimeout
|
||||
);
|
||||
|
||||
if (0 < \strlen($sCustomUserAgent))
|
||||
{
|
||||
$aOptions[CURLOPT_USERAGENT] = $sCustomUserAgent;
|
||||
}
|
||||
|
||||
if (0 < \strlen($sProxy))
|
||||
{
|
||||
$aOptions[CURLOPT_PROXY] = $sProxy;
|
||||
if (0 < \strlen($sProxyAuth))
|
||||
{
|
||||
$aOptions[CURLOPT_PROXYUSERPWD] = $sProxyAuth;
|
||||
}
|
||||
}
|
||||
|
||||
$oCurl = \curl_init();
|
||||
\curl_setopt_array($oCurl, $aOptions);
|
||||
|
||||
if ($oLogger)
|
||||
{
|
||||
$oLogger->Write('cURL: Send post request: '.$sUrl);
|
||||
}
|
||||
|
||||
$mResult = \curl_exec($oCurl);
|
||||
|
||||
$iCode = (int) \curl_getinfo($oCurl, CURLINFO_HTTP_CODE);
|
||||
$sContentType = (string) \curl_getinfo($oCurl, CURLINFO_CONTENT_TYPE);
|
||||
|
||||
if ($oLogger)
|
||||
{
|
||||
$oLogger->Write('cURL: Post request result: (Status: '.$iCode.', ContentType: '.$sContentType.')');
|
||||
if (false === $mResult || 200 !== $iCode)
|
||||
{
|
||||
$oLogger->Write('cURL: Error: '.\curl_error($oCurl), \MailSo\Log\Enumerations\Type::WARNING);
|
||||
}
|
||||
}
|
||||
|
||||
if (\is_resource($oCurl))
|
||||
{
|
||||
\curl_close($oCurl);
|
||||
}
|
||||
|
||||
return $mResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sUrl
|
||||
* @param array $aOptions
|
||||
* @param \MailSo\Log\Logger $oLogger = null
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static public function DetectAndHackFollowLocationUrl($sUrl, &$aOptions, $oLogger = null)
|
||||
{
|
||||
$sSafeMode = \strtolower(\trim(@\ini_get('safe_mode')));
|
||||
$bSafeMode = 'on' === $sSafeMode || '1' === $sSafeMode;
|
||||
|
||||
$sNewUrl = null;
|
||||
$sUrl = isset($aOptions[CURLOPT_URL]) ? $aOptions[CURLOPT_URL] : $sUrl;
|
||||
|
||||
if (isset($aOptions[CURLOPT_FOLLOWLOCATION]) && $aOptions[CURLOPT_FOLLOWLOCATION] && 0 < \strlen($sUrl) &&
|
||||
($bSafeMode || \ini_get('open_basedir') !== ''))
|
||||
{
|
||||
$aOptions[CURLOPT_FOLLOWLOCATION] = false;
|
||||
|
||||
$iMaxRedirects = isset($aOptions[CURLOPT_MAXREDIRS]) ? $aOptions[CURLOPT_MAXREDIRS] : 5;
|
||||
$iRedirectLimit = $iMaxRedirects;
|
||||
|
||||
if ($iRedirectLimit > 0)
|
||||
{
|
||||
$sNewUrl = $sUrl;
|
||||
|
||||
$oCurl = \curl_init($sUrl);
|
||||
|
||||
$aAddOptions = array(
|
||||
CURLOPT_URL => $sUrl,
|
||||
CURLOPT_HEADER => true,
|
||||
CURLOPT_NOBODY => true,
|
||||
CURLOPT_FAILONERROR => false,
|
||||
CURLOPT_SSL_VERIFYPEER => false,
|
||||
CURLOPT_FOLLOWLOCATION => false,
|
||||
CURLOPT_FORBID_REUSE => false,
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_TIMEOUT => 5
|
||||
);
|
||||
|
||||
if (isset($aOptions[CURLOPT_HTTPHEADER]) && \is_array($aOptions[CURLOPT_HTTPHEADER]) && 0 < \count($aOptions[CURLOPT_HTTPHEADER]))
|
||||
{
|
||||
$aAddOptions[CURLOPT_HTTPHEADER] = $aOptions[CURLOPT_HTTPHEADER];
|
||||
}
|
||||
|
||||
\curl_setopt_array($oCurl, $aAddOptions);
|
||||
|
||||
do
|
||||
{
|
||||
\curl_setopt($oCurl, CURLOPT_URL, $sNewUrl);
|
||||
|
||||
$sHeader = \curl_exec($oCurl);
|
||||
if (\curl_errno($oCurl))
|
||||
{
|
||||
$iCode = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
$iCode = \curl_getinfo($oCurl, CURLINFO_HTTP_CODE);
|
||||
if ($iCode === 301 || $iCode === 302)
|
||||
{
|
||||
$aMatches = array();
|
||||
\preg_match('/Location:(.*?)\n/', $sHeader, $aMatches);
|
||||
$sNewUrl = \trim(\array_pop($aMatches));
|
||||
|
||||
if ($oLogger)
|
||||
{
|
||||
$oLogger->Write('cUrl: Location URL: '.$sNewUrl);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$iCode = 0;
|
||||
}
|
||||
}
|
||||
|
||||
} while ($iCode && --$iRedirectLimit);
|
||||
|
||||
\curl_close($oCurl);
|
||||
if ($iRedirectLimit > 0 && 0 < \strlen($sNewUrl))
|
||||
{
|
||||
$aOptions[CURLOPT_URL] = $sNewUrl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null === $sNewUrl ? $sUrl : $sNewUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sUrl
|
||||
* @param resource $rFile
|
||||
* @param string $sCustomUserAgent = 'MailSo Http User Agent (v1)'
|
||||
* @param string $sContentType = ''
|
||||
* @param int $iCode = 0
|
||||
* @param \MailSo\Log\Logger $oLogger = null
|
||||
* @param int $iTimeout = 10
|
||||
* @param string $sProxy = ''
|
||||
* @param string $sProxyAuth = ''
|
||||
* @param array $aHttpHeaders = array()
|
||||
* @param bool $bFollowLocation = true
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function SaveUrlToFile($sUrl, $rFile, $sCustomUserAgent = 'MailSo Http User Agent (v1)', &$sContentType = '', &$iCode = 0,
|
||||
$oLogger = null, $iTimeout = 10, $sProxy = '', $sProxyAuth = '', $aHttpHeaders = array(), $bFollowLocation = true)
|
||||
{
|
||||
if (null === $sCustomUserAgent)
|
||||
{
|
||||
$sCustomUserAgent = 'MailSo Http User Agent (v1)';
|
||||
}
|
||||
|
||||
if (!is_resource($rFile))
|
||||
{
|
||||
if ($oLogger)
|
||||
{
|
||||
$oLogger->Write('cURL: input resource invalid.', \MailSo\Log\Enumerations\Type::WARNING);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$aOptions = array(
|
||||
CURLOPT_URL => $sUrl,
|
||||
CURLOPT_HEADER => false,
|
||||
CURLOPT_FAILONERROR => true,
|
||||
CURLOPT_SSL_VERIFYPEER => false,
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_FOLLOWLOCATION => !!$bFollowLocation,
|
||||
CURLOPT_MAXREDIRS => 7,
|
||||
CURLOPT_FILE => $rFile,
|
||||
CURLOPT_TIMEOUT => (int) $iTimeout
|
||||
);
|
||||
|
||||
if (0 < \strlen($sCustomUserAgent))
|
||||
{
|
||||
$aOptions[CURLOPT_USERAGENT] = $sCustomUserAgent;
|
||||
}
|
||||
|
||||
if (0 < \strlen($sProxy))
|
||||
{
|
||||
$aOptions[CURLOPT_PROXY] = $sProxy;
|
||||
if (0 < \strlen($sProxyAuth))
|
||||
{
|
||||
$aOptions[CURLOPT_PROXYUSERPWD] = $sProxyAuth;
|
||||
}
|
||||
}
|
||||
|
||||
if (\is_array($aHttpHeaders) && 0 < \count($aHttpHeaders))
|
||||
{
|
||||
$aOptions[CURLOPT_HTTPHEADER] = $aHttpHeaders;
|
||||
}
|
||||
|
||||
if ($oLogger)
|
||||
{
|
||||
$oLogger->Write('cUrl: URL: '.$sUrl);
|
||||
// if (isset($aOptions[CURLOPT_HTTPHEADER]) && \is_array($aOptions[CURLOPT_HTTPHEADER]) && 0 < \count($aOptions[CURLOPT_HTTPHEADER]))
|
||||
// {
|
||||
// $oLogger->Write('cUrl: Headers: '.\print_r($aOptions[CURLOPT_HTTPHEADER], true));
|
||||
// }
|
||||
}
|
||||
|
||||
\MailSo\Base\Http::DetectAndHackFollowLocationUrl($sUrl, $aOptions, $oLogger);
|
||||
|
||||
$oCurl = \curl_init();
|
||||
\curl_setopt_array($oCurl, $aOptions);
|
||||
|
||||
$bResult = \curl_exec($oCurl);
|
||||
|
||||
$iCode = (int) \curl_getinfo($oCurl, CURLINFO_HTTP_CODE);
|
||||
$sContentType = (string) \curl_getinfo($oCurl, CURLINFO_CONTENT_TYPE);
|
||||
|
||||
if ($oLogger)
|
||||
{
|
||||
$oLogger->Write('cUrl: Request result: '.($bResult ? 'true' : 'false').' (Status: '.$iCode.', ContentType: '.$sContentType.')');
|
||||
if (!$bResult || 200 !== $iCode)
|
||||
{
|
||||
$oLogger->Write('cUrl: Error: '.\curl_error($oCurl), \MailSo\Log\Enumerations\Type::WARNING);
|
||||
}
|
||||
}
|
||||
|
||||
if (\is_resource($oCurl))
|
||||
{
|
||||
\curl_close($oCurl);
|
||||
}
|
||||
|
||||
return $bResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sUrl
|
||||
* @param string $sCustomUserAgent = 'MailSo Http User Agent (v1)'
|
||||
* @param string $sContentType = ''
|
||||
* @param int $iCode = 0
|
||||
* @param \MailSo\Log\Logger $oLogger = null
|
||||
* @param int $iTimeout = 10
|
||||
* @param string $sProxy = ''
|
||||
* @param string $sProxyAuth = ''
|
||||
* @param array $aHttpHeaders = array()
|
||||
* @param bool $bFollowLocation = true
|
||||
*
|
||||
* @return string|bool
|
||||
*/
|
||||
public function GetUrlAsString($sUrl, $sCustomUserAgent = 'MailSo Http User Agent (v1)', &$sContentType = '', &$iCode = 0,
|
||||
$oLogger = null, $iTimeout = 10, $sProxy = '', $sProxyAuth = '', $aHttpHeaders = array(), $bFollowLocation = true)
|
||||
{
|
||||
$rMemFile = \MailSo\Base\ResourceRegistry::CreateMemoryResource();
|
||||
if ($this->SaveUrlToFile($sUrl, $rMemFile, $sCustomUserAgent, $sContentType, $iCode, $oLogger, $iTimeout, $sProxy, $sProxyAuth, $aHttpHeaders, $bFollowLocation) && \is_resource($rMemFile))
|
||||
{
|
||||
\rewind($rMemFile);
|
||||
return \stream_get_contents($rMemFile);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iExpireTime
|
||||
* @param bool $bSetCacheHeader = true
|
||||
* @param string $sEtag = ''
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function ServerNotModifiedCache($iExpireTime, $bSetCacheHeader = true, $sEtag = '')
|
||||
{
|
||||
$bResult = false;
|
||||
if (0 < $iExpireTime)
|
||||
{
|
||||
$iUtcTimeStamp = \time();
|
||||
$sIfModifiedSince = $this->GetHeader('If-Modified-Since', '');
|
||||
if (0 === \strlen($sIfModifiedSince))
|
||||
{
|
||||
if ($bSetCacheHeader)
|
||||
{
|
||||
\header('Cache-Control: public', true);
|
||||
\header('Pragma: public', true);
|
||||
\header('Last-Modified: '.\gmdate('D, d M Y H:i:s', $iUtcTimeStamp - $iExpireTime).' UTC', true);
|
||||
\header('Expires: '.\gmdate('D, j M Y H:i:s', $iUtcTimeStamp + $iExpireTime).' UTC', true);
|
||||
|
||||
if (0 < strlen($sEtag))
|
||||
{
|
||||
\header('Etag: '.$sEtag, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->StatusHeader(304);
|
||||
$bResult = true;
|
||||
}
|
||||
}
|
||||
|
||||
return $bResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @staticvar bool $bCache
|
||||
*/
|
||||
public function ServerNoCache()
|
||||
{
|
||||
static $bCache = false;
|
||||
if (false === $bCache)
|
||||
{
|
||||
$bCache = true;
|
||||
@\header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
|
||||
@\header('Last-Modified: '.\gmdate('D, d M Y H:i:s').' GMT');
|
||||
@\header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
|
||||
@\header('Cache-Control: post-check=0, pre-check=0', false);
|
||||
@\header('Pragma: no-cache');
|
||||
@\header('X-RainLoop-Cache: no');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @staticvar bool $bCache
|
||||
* @param string $sEtag
|
||||
* @param int $iLastModified
|
||||
* @param int $iExpires
|
||||
*/
|
||||
public function ServerUseCache($sEtag, $iLastModified, $iExpires)
|
||||
{
|
||||
static $bCache = false;
|
||||
if (false === $bCache)
|
||||
{
|
||||
$bCache = true;
|
||||
@\header('Cache-Control: private', true);
|
||||
@\header('ETag: '.$sEtag, true);
|
||||
@\header('Last-Modified: '.\gmdate('D, d M Y H:i:s', $iLastModified).' UTC', true);
|
||||
@\header('Expires: '.\gmdate('D, j M Y H:i:s', $iExpires).' UTC', true);
|
||||
@\header('X-RainLoop-Cache: yes');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iStatus
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function StatusHeader($iStatus, $sCustomStatusText = '')
|
||||
{
|
||||
$iStatus = (int) $iStatus;
|
||||
if (99 < $iStatus)
|
||||
{
|
||||
$aStatus = array(
|
||||
301 => 'Moved Permanently',
|
||||
304 => 'Not Modified',
|
||||
200 => 'OK',
|
||||
400 => 'Bad Request',
|
||||
401 => 'Unauthorized',
|
||||
403 => 'Forbidden',
|
||||
404 => 'Not Found',
|
||||
405 => 'Method Not Allowed'
|
||||
);
|
||||
|
||||
$sCustomStatusText = \trim($sCustomStatusText);
|
||||
$sHeaderHead = \ini_get('cgi.rfc2616_headers') && false !== \strpos(\strtolower(\php_sapi_name()), 'cgi') ? 'Status:' : $this->ServerProtocol();
|
||||
$sHeaderText = (0 === \strlen($sCustomStatusText) && isset($aStatus[$iStatus]) ? $aStatus[$iStatus] : $sCustomStatusText);
|
||||
|
||||
\header(\trim($sHeaderHead.' '.$iStatus.' '.$sHeaderText), true, $iStatus);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function GetPath()
|
||||
{
|
||||
$sUrl = \ltrim(\substr($this->GetServer('SCRIPT_NAME', ''), 0, \strrpos($this->GetServer('SCRIPT_NAME', ''), '/')), '/');
|
||||
return '' === $sUrl ? '/' : '/'.$sUrl.'/';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function GetUrl()
|
||||
{
|
||||
return $this->GetServer('REQUEST_URI', '');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function GetFullUrl()
|
||||
{
|
||||
return $this->GetScheme().'://'.$this->GetHost(true, false).$this->GetPath();
|
||||
}
|
||||
}
|
|
@ -1,298 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Base;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Base
|
||||
*/
|
||||
class LinkFinder
|
||||
{
|
||||
/**
|
||||
* @const
|
||||
*/
|
||||
const OPEN_LINK = '@#@link{';
|
||||
const CLOSE_LINK = '}link@#@';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $aPrepearPlainStringUrls;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sText;
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
private $fLinkWrapper;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $iHtmlSpecialCharsFlags;
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
private $fMailWrapper;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $iOptimizationLimit;
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*/
|
||||
private function __construct()
|
||||
{
|
||||
$this->iHtmlSpecialCharsFlags = (\defined('ENT_QUOTES') && \defined('ENT_SUBSTITUTE') && \defined('ENT_HTML401'))
|
||||
? ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401 : ENT_QUOTES;
|
||||
|
||||
if (\defined('ENT_IGNORE'))
|
||||
{
|
||||
$this->iHtmlSpecialCharsFlags |= ENT_IGNORE;
|
||||
}
|
||||
|
||||
$this->iOptimizationLimit = 300000;
|
||||
|
||||
$this->Clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \MailSo\Base\LinkFinder
|
||||
*/
|
||||
public static function NewInstance()
|
||||
{
|
||||
return new self();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \MailSo\Base\LinkFinder
|
||||
*/
|
||||
public function Clear()
|
||||
{
|
||||
$this->aPrepearPlainStringUrls = array();
|
||||
$this->fLinkWrapper = null;
|
||||
$this->fMailWrapper = null;
|
||||
$this->sText = '';
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sText
|
||||
*
|
||||
* @return \MailSo\Base\LinkFinder
|
||||
*/
|
||||
public function Text($sText)
|
||||
{
|
||||
$this->sText = $sText;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $fLinkWrapper
|
||||
*
|
||||
* @return \MailSo\Base\LinkFinder
|
||||
*/
|
||||
public function LinkWrapper($fLinkWrapper)
|
||||
{
|
||||
$this->fLinkWrapper = $fLinkWrapper;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $fMailWrapper
|
||||
*
|
||||
* @return \MailSo\Base\LinkFinder
|
||||
*/
|
||||
public function MailWrapper($fMailWrapper)
|
||||
{
|
||||
$this->fMailWrapper = $fMailWrapper;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $bAddTargetBlank = false
|
||||
*
|
||||
* @return \MailSo\Base\LinkFinder
|
||||
*/
|
||||
public function UseDefaultWrappers($bAddTargetBlank = false)
|
||||
{
|
||||
$this->fLinkWrapper = function ($sLink) use ($bAddTargetBlank) {
|
||||
|
||||
$sNameLink = $sLink;
|
||||
if (!\preg_match('/^[a-z]{3,5}\:\/\//i', \ltrim($sLink)))
|
||||
{
|
||||
$sLink = 'http://'.\ltrim($sLink);
|
||||
}
|
||||
|
||||
return '<a '.($bAddTargetBlank ? 'target="_blank" ': '').'href="'.$sLink.'">'.$sNameLink.'</a>';
|
||||
};
|
||||
|
||||
$this->fMailWrapper = function ($sEmail) use ($bAddTargetBlank) {
|
||||
return '<a '.($bAddTargetBlank ? 'target="_blank" ': '').'href="mailto:'.$sEmail.'">'.$sEmail.'</a>';
|
||||
};
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $bUseHtmlSpecialChars = true
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function CompileText($bUseHtmlSpecialChars = true)
|
||||
{
|
||||
$sText = \substr($this->sText, 0, $this->iOptimizationLimit);
|
||||
$sSubText = \substr($this->sText, $this->iOptimizationLimit);
|
||||
|
||||
$this->aPrepearPlainStringUrls = array();
|
||||
if (null !== $this->fLinkWrapper && \is_callable($this->fLinkWrapper))
|
||||
{
|
||||
$sText = $this->findLinks($sText, $this->fLinkWrapper);
|
||||
}
|
||||
|
||||
if (null !== $this->fMailWrapper && \is_callable($this->fMailWrapper))
|
||||
{
|
||||
$sText = $this->findMails($sText, $this->fMailWrapper);
|
||||
}
|
||||
|
||||
$sResult = '';
|
||||
if ($bUseHtmlSpecialChars)
|
||||
{
|
||||
$sResult = @\htmlentities($sText.$sSubText, $this->iHtmlSpecialCharsFlags, 'UTF-8');
|
||||
}
|
||||
else
|
||||
{
|
||||
$sResult = $sText.$sSubText;
|
||||
}
|
||||
|
||||
unset($sText, $sSubText);
|
||||
|
||||
if (0 < \count($this->aPrepearPlainStringUrls))
|
||||
{
|
||||
$aPrepearPlainStringUrls = $this->aPrepearPlainStringUrls;
|
||||
$sResult = \preg_replace_callback('/'.\preg_quote(\MailSo\Base\LinkFinder::OPEN_LINK, '/').
|
||||
'([\d]+)'.\preg_quote(\MailSo\Base\LinkFinder::CLOSE_LINK, '/').'/',
|
||||
function ($aMatches) use ($aPrepearPlainStringUrls) {
|
||||
$iIndex = (int) $aMatches[1];
|
||||
return isset($aPrepearPlainStringUrls[$iIndex]) ? $aPrepearPlainStringUrls[$iIndex] : '';
|
||||
}, $sResult);
|
||||
|
||||
$this->aPrepearPlainStringUrls = array();
|
||||
}
|
||||
|
||||
return $sResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sText
|
||||
* @param mixed $fWrapper
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function findLinks($sText, $fWrapper)
|
||||
{
|
||||
$sPattern = '/([\W]|^)((?:https?:\/\/)|(?:svn:\/\/)|(?:git:\/\/)|(?:s?ftps?:\/\/)|(?:www\.))'.
|
||||
'((\S+?)(\\/)?)((?:>)?|[^\w\=\\/;\(\)\[\]]*?)(?=<|\s|$)/imu';
|
||||
|
||||
$aPrepearPlainStringUrls = $this->aPrepearPlainStringUrls;
|
||||
$sText = \preg_replace_callback($sPattern, function ($aMatch) use ($fWrapper, &$aPrepearPlainStringUrls) {
|
||||
|
||||
if (\is_array($aMatch) && 6 < \count($aMatch))
|
||||
{
|
||||
while (\in_array($sChar = \substr($aMatch[3], -1), array(']', ')')))
|
||||
{
|
||||
if (\substr_count($aMatch[3], ']' === $sChar ? '[': '(') - \substr_count($aMatch[3], $sChar) < 0)
|
||||
{
|
||||
$aMatch[3] = \substr($aMatch[3], 0, -1);
|
||||
$aMatch[6] = (']' === $sChar ? ']': ')').$aMatch[6];
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$sLinkWithWrap = \call_user_func($fWrapper, $aMatch[2].$aMatch[3]);
|
||||
if (\is_string($sLinkWithWrap) && 0 < \strlen($sLinkWithWrap))
|
||||
{
|
||||
$aPrepearPlainStringUrls[] = \stripslashes($sLinkWithWrap);
|
||||
return $aMatch[1].
|
||||
\MailSo\Base\LinkFinder::OPEN_LINK.
|
||||
(\count($aPrepearPlainStringUrls) - 1).
|
||||
\MailSo\Base\LinkFinder::CLOSE_LINK.
|
||||
$aMatch[6];
|
||||
}
|
||||
|
||||
return $aMatch[0];
|
||||
}
|
||||
|
||||
return '';
|
||||
|
||||
}, $sText);
|
||||
|
||||
if (0 < \count($aPrepearPlainStringUrls))
|
||||
{
|
||||
$this->aPrepearPlainStringUrls = $aPrepearPlainStringUrls;
|
||||
}
|
||||
|
||||
return $sText;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sText
|
||||
* @param mixed $fWrapper
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function findMails($sText, $fWrapper)
|
||||
{
|
||||
$sPattern = '/([\w\.!#\$%\-+.]+@[A-Za-z0-9\-]+(\.[A-Za-z0-9\-]+)+)/';
|
||||
|
||||
$aPrepearPlainStringUrls = $this->aPrepearPlainStringUrls;
|
||||
$sText = \preg_replace_callback($sPattern, function ($aMatch) use ($fWrapper, &$aPrepearPlainStringUrls) {
|
||||
|
||||
if (\is_array($aMatch) && isset($aMatch[1]))
|
||||
{
|
||||
$sMailWithWrap = \call_user_func($fWrapper, $aMatch[1]);
|
||||
if (\is_string($sMailWithWrap) && 0 < \strlen($sMailWithWrap))
|
||||
{
|
||||
$aPrepearPlainStringUrls[] = \stripslashes($sMailWithWrap);
|
||||
return \MailSo\Base\LinkFinder::OPEN_LINK.
|
||||
(\count($aPrepearPlainStringUrls) - 1).
|
||||
\MailSo\Base\LinkFinder::CLOSE_LINK;
|
||||
}
|
||||
|
||||
return $aMatch[1];
|
||||
}
|
||||
|
||||
return '';
|
||||
|
||||
}, $sText);
|
||||
|
||||
if (0 < \count($aPrepearPlainStringUrls))
|
||||
{
|
||||
$this->aPrepearPlainStringUrls = $aPrepearPlainStringUrls;
|
||||
}
|
||||
|
||||
return $sText;
|
||||
}
|
||||
}
|
|
@ -1,123 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Base;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Base
|
||||
*/
|
||||
class Loader
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public static $StoreStatistic = true;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private static $aIncStatistic = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private static $aSetStatistic = array();
|
||||
|
||||
/**
|
||||
* @staticvar bool $bIsInited
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function Init()
|
||||
{
|
||||
static $bIsInited = false;
|
||||
if (!$bIsInited)
|
||||
{
|
||||
$bIsInited = true;
|
||||
self::SetStatistic('Inited', \microtime(true));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param int $iIncSize = 1
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function IncStatistic($sName, $iIncSize = 1)
|
||||
{
|
||||
if (self::$StoreStatistic)
|
||||
{
|
||||
self::$aIncStatistic[$sName] = isset(self::$aIncStatistic[$sName])
|
||||
? self::$aIncStatistic[$sName] + $iIncSize : $iIncSize;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param mixed $mValue
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function SetStatistic($sName, $mValue)
|
||||
{
|
||||
if (self::$StoreStatistic)
|
||||
{
|
||||
self::$aSetStatistic[$sName] = $mValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function GetStatistic($sName)
|
||||
{
|
||||
return self::$StoreStatistic && isset(self::$aSetStatistic[$sName]) ? self::$aSetStatistic[$sName] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|null
|
||||
*/
|
||||
public static function Statistic()
|
||||
{
|
||||
$aResult = null;
|
||||
if (self::$StoreStatistic)
|
||||
{
|
||||
$aResult = array(
|
||||
'php' => array(
|
||||
'phpversion' => PHP_VERSION,
|
||||
'ssl' => (int) \function_exists('openssl_open'),
|
||||
'iconv' => (int) \function_exists('iconv')
|
||||
));
|
||||
|
||||
if (\MailSo\Base\Utils::FunctionExistsAndEnabled('memory_get_usage') &&
|
||||
\MailSo\Base\Utils::FunctionExistsAndEnabled('memory_get_peak_usage'))
|
||||
{
|
||||
$aResult['php']['memory_get_usage'] =
|
||||
Utils::FormatFileSize(\memory_get_usage(true), 2);
|
||||
$aResult['php']['memory_get_peak_usage'] =
|
||||
Utils::FormatFileSize(\memory_get_peak_usage(true), 2);
|
||||
}
|
||||
|
||||
$iTimeDelta = \microtime(true) - self::GetStatistic('Inited');
|
||||
self::SetStatistic('TimeDelta', $iTimeDelta);
|
||||
|
||||
$aResult['statistic'] = self::$aSetStatistic;
|
||||
$aResult['counts'] = self::$aIncStatistic;
|
||||
$aResult['time'] = $iTimeDelta;
|
||||
}
|
||||
|
||||
return $aResult;
|
||||
}
|
||||
}
|
|
@ -1,125 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Base;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Base
|
||||
*/
|
||||
class ResourceRegistry
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public static $Resources = array();
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*/
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @staticvar bool $bInited
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private static function regResourcesShutdownFunc()
|
||||
{
|
||||
static $bInited = false;
|
||||
if (!$bInited)
|
||||
{
|
||||
$bInited = true;
|
||||
\register_shutdown_function(function () {
|
||||
if (\is_array(\MailSo\Base\ResourceRegistry::$Resources))
|
||||
{
|
||||
foreach (\array_keys(\MailSo\Base\ResourceRegistry::$Resources) as $sKey)
|
||||
{
|
||||
if (\is_resource(\MailSo\Base\ResourceRegistry::$Resources[$sKey]))
|
||||
{
|
||||
\MailSo\Base\Loader::IncStatistic('CloseMemoryResource');
|
||||
\fclose(\MailSo\Base\ResourceRegistry::$Resources[$sKey]);
|
||||
}
|
||||
\MailSo\Base\ResourceRegistry::$Resources[$sKey] = null;
|
||||
}
|
||||
}
|
||||
|
||||
\MailSo\Base\ResourceRegistry::$Resources = array();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iMemoryMaxInMb = 5
|
||||
*
|
||||
* @return resource | bool
|
||||
*/
|
||||
public static function CreateMemoryResource($iMemoryMaxInMb = 5)
|
||||
{
|
||||
self::regResourcesShutdownFunc();
|
||||
|
||||
$oResult = @\fopen('php://temp/maxmemory:'.($iMemoryMaxInMb * 1024 * 1024), 'r+b');
|
||||
if (\is_resource($oResult))
|
||||
{
|
||||
\MailSo\Base\Loader::IncStatistic('CreateMemoryResource');
|
||||
\MailSo\Base\ResourceRegistry::$Resources[(string) $oResult] = $oResult;
|
||||
return $oResult;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sString
|
||||
*
|
||||
* @return resource | bool
|
||||
*/
|
||||
public static function CreateMemoryResourceFromString($sString)
|
||||
{
|
||||
$oResult = self::CreateMemoryResource();
|
||||
if (\is_resource($oResult))
|
||||
{
|
||||
\fwrite($oResult, $sString);
|
||||
\rewind($oResult);
|
||||
}
|
||||
|
||||
return $oResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param resource $rResource
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function CloseMemoryResource(&$rResource)
|
||||
{
|
||||
if (\is_resource($rResource))
|
||||
{
|
||||
$sKey = (string) $rResource;
|
||||
if (isset(\MailSo\Base\ResourceRegistry::$Resources[$sKey]))
|
||||
{
|
||||
\fclose(\MailSo\Base\ResourceRegistry::$Resources[$sKey]);
|
||||
\MailSo\Base\ResourceRegistry::$Resources[$sKey] = null;
|
||||
unset(\MailSo\Base\ResourceRegistry::$Resources[$sKey]);
|
||||
\MailSo\Base\Loader::IncStatistic('CloseMemoryResource');
|
||||
}
|
||||
|
||||
if (\is_resource($rResource))
|
||||
{
|
||||
\fclose($rResource);
|
||||
}
|
||||
|
||||
$rResource = null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,411 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Base\StreamWrappers;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Base
|
||||
* @subpackage StreamWrappers
|
||||
*/
|
||||
class Binary
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
const STREAM_NAME = 'mailsobinary';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private static $aStreams = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private static $aRememberStreams = array();
|
||||
|
||||
/**
|
||||
* @var resource
|
||||
*/
|
||||
private $rStream;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sFromEncoding;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sToEncoding;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sFunctionName;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $iPos;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sBuffer;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sReadEndBuffer;
|
||||
|
||||
/**
|
||||
* @param string $sContentTransferEncoding
|
||||
* @param bool $bDecode = true
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function GetInlineDecodeOrEncodeFunctionName($sContentTransferEncoding, $bDecode = true)
|
||||
{
|
||||
$sFunctionName = '';
|
||||
switch (strtolower($sContentTransferEncoding))
|
||||
{
|
||||
case \MailSo\Base\Enumerations\Encoding::BASE64_LOWER:
|
||||
// InlineBase64Decode
|
||||
$sFunctionName = $bDecode ? 'InlineBase64Decode' : 'convert.base64-encode';
|
||||
break;
|
||||
case \MailSo\Base\Enumerations\Encoding::QUOTED_PRINTABLE_LOWER:
|
||||
// InlineQuotedPrintableDecode
|
||||
$sFunctionName = $bDecode ? 'convert.quoted-printable-decode' : 'convert.quoted-printable-encode';
|
||||
break;
|
||||
}
|
||||
|
||||
return $sFunctionName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sBodyString
|
||||
* @param string $sEndBuffer
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function InlineNullDecode($sBodyString, &$sEndBuffer)
|
||||
{
|
||||
$sEndBuffer = '';
|
||||
return $sBodyString;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sBaseString
|
||||
* @param string $sEndBuffer
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function InlineBase64Decode($sBaseString, &$sEndBuffer)
|
||||
{
|
||||
$sEndBuffer = '';
|
||||
$sBaseString = str_replace(array("\r", "\n", "\t"), '', $sBaseString);
|
||||
$iBaseStringLen = strlen($sBaseString);
|
||||
$iBaseStringNormFloorLen = floor($iBaseStringLen / 4) * 4;
|
||||
if ($iBaseStringNormFloorLen < $iBaseStringLen)
|
||||
{
|
||||
$sEndBuffer = substr($sBaseString, $iBaseStringNormFloorLen);
|
||||
$sBaseString = substr($sBaseString, 0, $iBaseStringNormFloorLen);
|
||||
}
|
||||
return \MailSo\Base\Utils::Base64Decode($sBaseString);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sQuotedPrintableString
|
||||
* @param string $sEndBuffer
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function InlineQuotedPrintableDecode($sQuotedPrintableString, &$sEndBuffer)
|
||||
{
|
||||
$sEndBuffer = '';
|
||||
$sQuotedPrintableLen = strlen($sQuotedPrintableString);
|
||||
$iLastSpace = strrpos($sQuotedPrintableString, ' ');
|
||||
if (false !== $iLastSpace && $iLastSpace + 1 < $sQuotedPrintableLen)
|
||||
{
|
||||
$sEndBuffer = substr($sQuotedPrintableString, $iLastSpace + 1);
|
||||
$sQuotedPrintableString = substr($sQuotedPrintableString, 0, $iLastSpace + 1);
|
||||
}
|
||||
return quoted_printable_decode($sQuotedPrintableString);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sEncodedString
|
||||
* @param string $sEndBuffer
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function InlineConvertDecode($sEncodedString, &$sEndBuffer, $sFromEncoding, $sToEncoding)
|
||||
{
|
||||
$sEndBuffer = '';
|
||||
$sQuotedPrintableLen = strlen($sEncodedString);
|
||||
$iLastSpace = strrpos($sEncodedString, ' ');
|
||||
if (false !== $iLastSpace && $iLastSpace + 1 < $sQuotedPrintableLen)
|
||||
{
|
||||
$sEndBuffer = substr($sEncodedString, $iLastSpace + 1);
|
||||
$sEncodedString = substr($sEncodedString, 0, $iLastSpace + 1);
|
||||
}
|
||||
return \MailSo\Base\Utils::ConvertEncoding($sEncodedString, $sFromEncoding, $sToEncoding);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param resource $rStream
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function IsStreamRemembed($rStream)
|
||||
{
|
||||
foreach (self::$aRememberStreams as $rRem)
|
||||
{
|
||||
if ($rStream === $rRem)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param resource $rStream
|
||||
*/
|
||||
public static function RememberStream($rStream)
|
||||
{
|
||||
if (!self::IsStreamRemembed($rStream))
|
||||
{
|
||||
self::$aRememberStreams[] = $rStream;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param resource $rStream
|
||||
* @param string $sUtilsDecodeOrEncodeFunctionName = null
|
||||
* @param string $sFromEncoding = null
|
||||
* @param string $sToEncoding = null
|
||||
*
|
||||
* @return resource|bool
|
||||
*/
|
||||
public static function CreateStream($rStream,
|
||||
$sUtilsDecodeOrEncodeFunctionName = null, $sFromEncoding = null, $sToEncoding = null)
|
||||
{
|
||||
if (!in_array(self::STREAM_NAME, stream_get_wrappers()))
|
||||
{
|
||||
stream_wrapper_register(self::STREAM_NAME, '\MailSo\Base\StreamWrappers\Binary');
|
||||
}
|
||||
|
||||
if (null === $sUtilsDecodeOrEncodeFunctionName || 0 === strlen($sUtilsDecodeOrEncodeFunctionName))
|
||||
{
|
||||
$sUtilsDecodeOrEncodeFunctionName = 'InlineNullDecode';
|
||||
}
|
||||
|
||||
$sHashName = md5(microtime(true).rand(1000, 9999));
|
||||
|
||||
if (null !== $sFromEncoding && null !== $sToEncoding && $sFromEncoding !== $sToEncoding)
|
||||
{
|
||||
$rStream = self::CreateStream($rStream, $sUtilsDecodeOrEncodeFunctionName);
|
||||
$sUtilsDecodeOrEncodeFunctionName = 'InlineConvertDecode';
|
||||
}
|
||||
|
||||
if (in_array($sUtilsDecodeOrEncodeFunctionName, array(
|
||||
'convert.base64-decode', 'convert.base64-encode',
|
||||
'convert.quoted-printable-decode', 'convert.quoted-printable-encode'
|
||||
)))
|
||||
{
|
||||
$rFilter = \stream_filter_append($rStream, $sUtilsDecodeOrEncodeFunctionName,
|
||||
STREAM_FILTER_READ, array(
|
||||
'line-length' => \MailSo\Mime\Enumerations\Constants::LINE_LENGTH,
|
||||
'line-break-chars' => \MailSo\Mime\Enumerations\Constants::CRLF
|
||||
));
|
||||
|
||||
return \is_resource($rFilter) ? $rStream : false;
|
||||
}
|
||||
|
||||
self::$aStreams[$sHashName] =
|
||||
array($rStream, $sUtilsDecodeOrEncodeFunctionName, $sFromEncoding, $sToEncoding);
|
||||
|
||||
\MailSo\Base\Loader::IncStatistic('CreateStream/Binary');
|
||||
|
||||
return \fopen(self::STREAM_NAME.'://'.$sHashName, 'rb');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sPath
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function stream_open($sPath)
|
||||
{
|
||||
$this->iPos = 0;
|
||||
$this->sBuffer = '';
|
||||
$this->sReadEndBuffer = '';
|
||||
$this->rStream = false;
|
||||
$this->sFromEncoding = null;
|
||||
$this->sToEncoding = null;
|
||||
$this->sFunctionName = null;
|
||||
|
||||
$bResult = false;
|
||||
$aPath = parse_url($sPath);
|
||||
|
||||
if (isset($aPath['host']) && isset($aPath['scheme']) &&
|
||||
0 < strlen($aPath['host']) && 0 < strlen($aPath['scheme']) &&
|
||||
self::STREAM_NAME === $aPath['scheme'])
|
||||
{
|
||||
$sHashName = $aPath['host'];
|
||||
if (isset(self::$aStreams[$sHashName]) &&
|
||||
is_array(self::$aStreams[$sHashName]) &&
|
||||
4 === count(self::$aStreams[$sHashName]))
|
||||
{
|
||||
$this->rStream = self::$aStreams[$sHashName][0];
|
||||
$this->sFunctionName = self::$aStreams[$sHashName][1];
|
||||
$this->sFromEncoding = self::$aStreams[$sHashName][2];
|
||||
$this->sToEncoding = self::$aStreams[$sHashName][3];
|
||||
}
|
||||
|
||||
$bResult = is_resource($this->rStream);
|
||||
}
|
||||
|
||||
return $bResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iCount
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function stream_read($iCount)
|
||||
{
|
||||
$sReturn = '';
|
||||
$sFunctionName = $this->sFunctionName;
|
||||
|
||||
if ($iCount > 0)
|
||||
{
|
||||
if ($iCount < strlen($this->sBuffer))
|
||||
{
|
||||
$sReturn = substr($this->sBuffer, 0, $iCount);
|
||||
$this->sBuffer = substr($this->sBuffer, $iCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
$sReturn = $this->sBuffer;
|
||||
while ($iCount > 0)
|
||||
{
|
||||
if (feof($this->rStream))
|
||||
{
|
||||
if (0 === strlen($this->sBuffer.$sReturn))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (0 < strlen($this->sReadEndBuffer))
|
||||
{
|
||||
$sReturn .= self::$sFunctionName($this->sReadEndBuffer,
|
||||
$this->sReadEndBuffer, $this->sFromEncoding, $this->sToEncoding);
|
||||
|
||||
$iDecodeLen = strlen($sReturn);
|
||||
}
|
||||
|
||||
$iCount = 0;
|
||||
$this->sBuffer = '';
|
||||
}
|
||||
else
|
||||
{
|
||||
$sReadResult = fread($this->rStream, 8192);
|
||||
if (false === $sReadResult)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$sReturn .= self::$sFunctionName($this->sReadEndBuffer.$sReadResult,
|
||||
$this->sReadEndBuffer, $this->sFromEncoding, $this->sToEncoding);
|
||||
|
||||
$iDecodeLen = strlen($sReturn);
|
||||
if ($iCount < $iDecodeLen)
|
||||
{
|
||||
$this->sBuffer = substr($sReturn, $iCount);
|
||||
$sReturn = substr($sReturn, 0, $iCount);
|
||||
$iCount = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
$iCount -= $iDecodeLen;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->iPos += strlen($sReturn);
|
||||
return $sReturn;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function stream_write()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function stream_tell()
|
||||
{
|
||||
return $this->iPos;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function stream_eof()
|
||||
{
|
||||
return 0 === strlen($this->sBuffer) && feof($this->rStream);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function stream_stat()
|
||||
{
|
||||
return array(
|
||||
'dev' => 2,
|
||||
'ino' => 0,
|
||||
'mode' => 33206,
|
||||
'nlink' => 1,
|
||||
'uid' => 0,
|
||||
'gid' => 0,
|
||||
'rdev' => 2,
|
||||
'size' => 0,
|
||||
'atime' => 1061067181,
|
||||
'mtime' => 1056136526,
|
||||
'ctime' => 1056136526,
|
||||
'blksize' => -1,
|
||||
'blocks' => -1
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function stream_seek()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -1,194 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Base\StreamWrappers;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Base
|
||||
* @subpackage StreamWrappers
|
||||
*/
|
||||
class Literal
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
const STREAM_NAME = 'mailsoliteral';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private static $aStreams = array();
|
||||
|
||||
/**
|
||||
* @var resource
|
||||
*/
|
||||
private $rStream;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $iSize;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $iPos;
|
||||
|
||||
/**
|
||||
* @param resource $rStream
|
||||
* @param int $iLiteralLen
|
||||
*
|
||||
* @return resource|bool
|
||||
*/
|
||||
public static function CreateStream($rStream, $iLiteralLen)
|
||||
{
|
||||
if (!in_array(self::STREAM_NAME, stream_get_wrappers()))
|
||||
{
|
||||
stream_wrapper_register(self::STREAM_NAME, '\MailSo\Base\StreamWrappers\Literal');
|
||||
}
|
||||
|
||||
$sHashName = md5(microtime(true).rand(1000, 9999));
|
||||
|
||||
self::$aStreams[$sHashName] = array($rStream, $iLiteralLen);
|
||||
|
||||
\MailSo\Base\Loader::IncStatistic('CreateStream/Literal');
|
||||
|
||||
return fopen(self::STREAM_NAME.'://'.$sHashName, 'rb');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sPath
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function stream_open($sPath)
|
||||
{
|
||||
$this->iPos = 0;
|
||||
$this->iSize = 0;
|
||||
$this->rStream = false;
|
||||
|
||||
$bResult = false;
|
||||
$aPath = parse_url($sPath);
|
||||
|
||||
if (isset($aPath['host']) && isset($aPath['scheme']) &&
|
||||
0 < strlen($aPath['host']) && 0 < strlen($aPath['scheme']) &&
|
||||
self::STREAM_NAME === $aPath['scheme'])
|
||||
{
|
||||
$sHashName = $aPath['host'];
|
||||
if (isset(self::$aStreams[$sHashName]) &&
|
||||
is_array(self::$aStreams[$sHashName]) &&
|
||||
2 === count(self::$aStreams[$sHashName]))
|
||||
{
|
||||
$this->rStream = self::$aStreams[$sHashName][0];
|
||||
$this->iSize = self::$aStreams[$sHashName][1];
|
||||
}
|
||||
|
||||
$bResult = is_resource($this->rStream);
|
||||
}
|
||||
|
||||
return $bResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iCount
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function stream_read($iCount)
|
||||
{
|
||||
$sResult = false;
|
||||
if ($this->iSize < $this->iPos + $iCount)
|
||||
{
|
||||
$iCount = $this->iSize - $this->iPos;
|
||||
}
|
||||
|
||||
if ($iCount > 0)
|
||||
{
|
||||
$sReadResult = '';
|
||||
$iRead = $iCount;
|
||||
while (0 < $iRead)
|
||||
{
|
||||
$sAddRead = @fread($this->rStream, $iRead);
|
||||
if (false === $sAddRead)
|
||||
{
|
||||
$sReadResult = false;
|
||||
break;
|
||||
}
|
||||
|
||||
$sReadResult .= $sAddRead;
|
||||
$iRead -= strlen($sAddRead);
|
||||
$this->iPos += strlen($sAddRead);
|
||||
}
|
||||
|
||||
if (false !== $sReadResult)
|
||||
{
|
||||
$sResult = $sReadResult;
|
||||
}
|
||||
}
|
||||
|
||||
return $sResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function stream_write()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function stream_tell()
|
||||
{
|
||||
return $this->iPos;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function stream_eof()
|
||||
{
|
||||
return $this->iPos >= $this->iSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function stream_stat()
|
||||
{
|
||||
return array(
|
||||
'dev' => 2,
|
||||
'ino' => 0,
|
||||
'mode' => 33206,
|
||||
'nlink' => 1,
|
||||
'uid' => 0,
|
||||
'gid' => 0,
|
||||
'rdev' => 2,
|
||||
'size' => $this->iSize,
|
||||
'atime' => 1061067181,
|
||||
'mtime' => 1056136526,
|
||||
'ctime' => 1056136526,
|
||||
'blksize' => -1,
|
||||
'blocks' => -1
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function stream_seek()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -1,267 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Base\StreamWrappers;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Base
|
||||
* @subpackage StreamWrappers
|
||||
*/
|
||||
class SubStreams
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
const STREAM_NAME = 'mailsosubstreams';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private static $aStreams = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $aSubStreams;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $iIndex;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sBuffer;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $bIsEnd;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $iPos;
|
||||
|
||||
/**
|
||||
* @param array $aSubStreams
|
||||
*
|
||||
* @return resource|bool
|
||||
*/
|
||||
public static function CreateStream($aSubStreams)
|
||||
{
|
||||
if (!\in_array(self::STREAM_NAME, \stream_get_wrappers()))
|
||||
{
|
||||
\stream_wrapper_register(self::STREAM_NAME, '\MailSo\Base\StreamWrappers\SubStreams');
|
||||
}
|
||||
|
||||
$sHashName = \md5(\microtime(true).\rand(1000, 9999));
|
||||
|
||||
self::$aStreams[$sHashName] = $aSubStreams;
|
||||
|
||||
\MailSo\Base\Loader::IncStatistic('CreateStream/SubStreams');
|
||||
|
||||
return \fopen(self::STREAM_NAME.'://'.$sHashName, 'rb');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return resource|null
|
||||
*/
|
||||
protected function &getPart()
|
||||
{
|
||||
$nNull = null;
|
||||
if (isset($this->aSubStreams[$this->iIndex]))
|
||||
{
|
||||
return $this->aSubStreams[$this->iIndex];
|
||||
}
|
||||
|
||||
return $nNull;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sPath
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function stream_open($sPath)
|
||||
{
|
||||
$this->aSubStreams = array();
|
||||
|
||||
$bResult = false;
|
||||
$aPath = \parse_url($sPath);
|
||||
|
||||
if (isset($aPath['host'], $aPath['scheme']) &&
|
||||
0 < \strlen($aPath['host']) && 0 < \strlen($aPath['scheme']) &&
|
||||
self::STREAM_NAME === $aPath['scheme'])
|
||||
{
|
||||
$sHashName = $aPath['host'];
|
||||
if (isset(self::$aStreams[$sHashName]) &&
|
||||
\is_array(self::$aStreams[$sHashName]) &&
|
||||
0 < \count(self::$aStreams[$sHashName]))
|
||||
{
|
||||
$this->iIndex = 0;
|
||||
$this->iPos = 0;
|
||||
$this->bIsEnd = false;
|
||||
$this->sBuffer = '';
|
||||
$this->aSubStreams = self::$aStreams[$sHashName];
|
||||
}
|
||||
|
||||
$bResult = 0 < \count($this->aSubStreams);
|
||||
}
|
||||
|
||||
return $bResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iCount
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function stream_read($iCount)
|
||||
{
|
||||
$sReturn = '';
|
||||
$mCurrentPart = null;
|
||||
if ($iCount > 0)
|
||||
{
|
||||
if ($iCount < \strlen($this->sBuffer))
|
||||
{
|
||||
$sReturn = \substr($this->sBuffer, 0, $iCount);
|
||||
$this->sBuffer = \substr($this->sBuffer, $iCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
$sReturn = $this->sBuffer;
|
||||
while ($iCount > 0)
|
||||
{
|
||||
$mCurrentPart =& $this->getPart();
|
||||
if (null === $mCurrentPart)
|
||||
{
|
||||
$this->bIsEnd = true;
|
||||
$this->sBuffer = '';
|
||||
$iCount = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (\is_resource($mCurrentPart))
|
||||
{
|
||||
if (!\feof($mCurrentPart))
|
||||
{
|
||||
$sReadResult = @\fread($mCurrentPart, 8192);
|
||||
if (false === $sReadResult)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$sReturn .= $sReadResult;
|
||||
|
||||
$iLen = \strlen($sReturn);
|
||||
if ($iCount < $iLen)
|
||||
{
|
||||
$this->sBuffer = \substr($sReturn, $iCount);
|
||||
$sReturn = \substr($sReturn, 0, $iCount);
|
||||
$iCount = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
$iCount -= $iLen;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->iIndex++;
|
||||
}
|
||||
}
|
||||
else if (\is_string($mCurrentPart))
|
||||
{
|
||||
$sReadResult = \substr($mCurrentPart, 0, $iCount);
|
||||
|
||||
$sReturn .= $sReadResult;
|
||||
|
||||
$iLen = \strlen($sReadResult);
|
||||
if ($iCount < $iLen)
|
||||
{
|
||||
$this->sBuffer = \substr($sReturn, $iCount);
|
||||
$sReturn = \substr($sReturn, 0, $iCount);
|
||||
$iCount = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
$iCount -= $iLen;
|
||||
}
|
||||
|
||||
$this->iIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->iPos += \strlen($sReturn);
|
||||
return $sReturn;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function stream_write()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function stream_tell()
|
||||
{
|
||||
return $this->iPos;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function stream_eof()
|
||||
{
|
||||
return $this->bIsEnd;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function stream_stat()
|
||||
{
|
||||
return array(
|
||||
'dev' => 2,
|
||||
'ino' => 0,
|
||||
'mode' => 33206,
|
||||
'nlink' => 1,
|
||||
'uid' => 0,
|
||||
'gid' => 0,
|
||||
'rdev' => 2,
|
||||
'size' => 0,
|
||||
'atime' => 1061067181,
|
||||
'mtime' => 1056136526,
|
||||
'ctime' => 1056136526,
|
||||
'blksize' => -1,
|
||||
'blocks' => -1
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function stream_seek()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -1,161 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Base\StreamWrappers;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Base
|
||||
* @subpackage StreamWrappers
|
||||
*/
|
||||
class TempFile
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
const STREAM_NAME = 'mailsotempfile';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private static $aStreams = array();
|
||||
|
||||
/**
|
||||
* @var resource
|
||||
*/
|
||||
private $rSream;
|
||||
|
||||
public static function Reg()
|
||||
{
|
||||
if (!in_array(self::STREAM_NAME, stream_get_wrappers()))
|
||||
{
|
||||
stream_wrapper_register(self::STREAM_NAME, '\MailSo\Base\StreamWrappers\TempFile');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sHash
|
||||
*
|
||||
* @return resource|bool
|
||||
*/
|
||||
public static function CreateStream($sHash)
|
||||
{
|
||||
self::Reg();
|
||||
|
||||
return fopen(self::STREAM_NAME.'://'.$sHash, 'r+b');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sPath
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function stream_open($sPath)
|
||||
{
|
||||
$bResult = false;
|
||||
$aPath = parse_url($sPath);
|
||||
|
||||
if (isset($aPath['host']) && isset($aPath['scheme']) &&
|
||||
0 < strlen($aPath['host']) && 0 < strlen($aPath['scheme']) &&
|
||||
self::STREAM_NAME === $aPath['scheme'])
|
||||
{
|
||||
$sHashName = $aPath['host'];
|
||||
if (isset(self::$aStreams[$sHashName]) &&
|
||||
is_resource(self::$aStreams[$sHashName]))
|
||||
{
|
||||
$this->rSream = self::$aStreams[$sHashName];
|
||||
$bResult = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->rSream = fopen('php://memory', 'r+b');
|
||||
self::$aStreams[$sHashName] = $this->rSream;
|
||||
|
||||
$bResult = true;
|
||||
|
||||
\MailSo\Base\Loader::IncStatistic('CreateStream/TempFile');
|
||||
}
|
||||
}
|
||||
|
||||
return $bResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function stream_close()
|
||||
{
|
||||
return -1 !== fseek($this->rSream, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function stream_flush()
|
||||
{
|
||||
return fflush($this->rSream);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iLen
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function stream_read($iLen)
|
||||
{
|
||||
return fread($this->rSream, $iLen);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sInputString
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function stream_write($sInputString)
|
||||
{
|
||||
return fwrite($this->rSream, $sInputString);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function stream_tell()
|
||||
{
|
||||
return ftell($this->rSream);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function stream_eof()
|
||||
{
|
||||
return feof($this->rSream);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function stream_stat()
|
||||
{
|
||||
return fstat($this->rSream);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iOffset
|
||||
* @param int $iWhence = SEEK_SET
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function stream_seek($iOffset, $iWhence = SEEK_SET)
|
||||
{
|
||||
return fseek($this->rSream, $iOffset, $iWhence);
|
||||
}
|
||||
}
|
|
@ -1,138 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Base\StreamWrappers;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Base
|
||||
* @subpackage StreamWrappers
|
||||
*/
|
||||
class Test
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
const STREAM_NAME = 'mailsotest';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private static $aStreams = array();
|
||||
|
||||
/**
|
||||
* @var resource
|
||||
*/
|
||||
private $rReadSream;
|
||||
|
||||
/**
|
||||
* @param string $sRawResponse
|
||||
*
|
||||
* @return resource|bool
|
||||
*/
|
||||
public static function CreateStream($sRawResponse)
|
||||
{
|
||||
if (!in_array(self::STREAM_NAME, stream_get_wrappers()))
|
||||
{
|
||||
stream_wrapper_register(self::STREAM_NAME, '\MailSo\Base\StreamWrappers\Test');
|
||||
}
|
||||
|
||||
$sHashName = md5(microtime(true).rand(1000, 9999));
|
||||
|
||||
$rConnect = fopen('php://memory', 'r+b');
|
||||
fwrite($rConnect, $sRawResponse);
|
||||
fseek($rConnect, 0);
|
||||
|
||||
self::$aStreams[$sHashName] = $rConnect;
|
||||
|
||||
\MailSo\Base\Loader::IncStatistic('CreateStream/Test');
|
||||
|
||||
return fopen(self::STREAM_NAME.'://'.$sHashName, 'r+b');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sPath
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function stream_open($sPath)
|
||||
{
|
||||
$bResult = false;
|
||||
$aPath = parse_url($sPath);
|
||||
|
||||
if (isset($aPath['host']) && isset($aPath['scheme']) &&
|
||||
0 < strlen($aPath['host']) && 0 < strlen($aPath['scheme']) &&
|
||||
self::STREAM_NAME === $aPath['scheme'])
|
||||
{
|
||||
$sHashName = $aPath['host'];
|
||||
if (isset(self::$aStreams[$sHashName]) &&
|
||||
is_resource(self::$aStreams[$sHashName]))
|
||||
{
|
||||
$this->rReadSream = self::$aStreams[$sHashName];
|
||||
$bResult = true;
|
||||
}
|
||||
}
|
||||
|
||||
return $bResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iCount
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function stream_read($iCount)
|
||||
{
|
||||
return fread($this->rReadSream, $iCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sInputString
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function stream_write($sInputString)
|
||||
{
|
||||
return strlen($sInputString);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function stream_tell()
|
||||
{
|
||||
return ftell($this->rReadSream);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function stream_eof()
|
||||
{
|
||||
return feof($this->rReadSream);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function stream_stat()
|
||||
{
|
||||
return fstat($this->rReadSream);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function stream_seek()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -1,100 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Base;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Base
|
||||
*/
|
||||
class Validator
|
||||
{
|
||||
/**
|
||||
* @param string $sEmail
|
||||
* @param array $aAllowedInternalDomains = array('localhost')
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function EmailString($sEmail, $aAllowedInternalDomains = array('localhost'))
|
||||
{
|
||||
$bResult = false;
|
||||
if (\MailSo\Base\Validator::NotEmptyString($sEmail, true))
|
||||
{
|
||||
$bResult = false !== \filter_var($sEmail, FILTER_VALIDATE_EMAIL);
|
||||
if (!$bResult)
|
||||
{
|
||||
$aSplit = \explode("@", $sEmail);
|
||||
$bResult = 2 === \count($aSplit) &&
|
||||
\in_array($aSplit[1], $aAllowedInternalDomains) &&
|
||||
false !== \filter_var(($aSplit[0].'@example.com'), FILTER_VALIDATE_EMAIL);
|
||||
}
|
||||
}
|
||||
|
||||
return $bResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sEmail
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function SimpleEmailString($sEmail)
|
||||
{
|
||||
return \MailSo\Base\Validator::NotEmptyString($sEmail, true) &&
|
||||
!!\preg_match('/^[a-zA-Z0-9][a-zA-Z0-9\.\+\-_]*@[a-zA-Z0-9][a-zA-Z0-9\.\+\-_]*$/', $sEmail);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sString
|
||||
* @param bool $bTrim = false
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function NotEmptyString($sString, $bTrim = false)
|
||||
{
|
||||
return \is_string($sString) &&
|
||||
(0 < \strlen($bTrim ? \trim($sString) : $sString));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $aList
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function NotEmptyArray($aList)
|
||||
{
|
||||
return \is_array($aList) && 0 < \count($aList);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iNumber
|
||||
* @param int $iMin = null
|
||||
* @param int $iMax = null
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function RangeInt($iNumber, $iMin = null, $iMax = null)
|
||||
{
|
||||
return \is_int($iNumber) &&
|
||||
(null !== $iMin && $iNumber >= $iMin || null === $iMin) &&
|
||||
(null !== $iMax && $iNumber <= $iMax || null === $iMax);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iPort
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function PortInt($iPort)
|
||||
{
|
||||
return \MailSo\Base\Validator::RangeInt($iPort, 0, 65535);
|
||||
}
|
||||
}
|
|
@ -1,194 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Cache;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Cache
|
||||
*/
|
||||
class CacheClient
|
||||
{
|
||||
/**
|
||||
* @var \MailSo\Cache\DriverInterface
|
||||
*/
|
||||
private $oDriver;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sCacheIndex;
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*/
|
||||
private function __construct()
|
||||
{
|
||||
$this->oDriver = null;
|
||||
$this->sCacheIndex = '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \MailSo\Cache\CacheClient
|
||||
*/
|
||||
public static function NewInstance()
|
||||
{
|
||||
return new self();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sKey
|
||||
* @param string $sValue
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Set($sKey, $sValue)
|
||||
{
|
||||
return $this->oDriver ? $this->oDriver->Set($sKey.$this->sCacheIndex, $sValue) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function SetTimer($sKey)
|
||||
{
|
||||
return $this->Set($sKey.'/TIMER', time());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function SetLock($sKey)
|
||||
{
|
||||
return $this->Set($sKey.'/LOCK', '1');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function RemoveLock($sKey)
|
||||
{
|
||||
return $this->Set($sKey.'/LOCK', '0');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function GetLock($sKey)
|
||||
{
|
||||
return '1' === $this->Get($sKey.'/LOCK');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sKey
|
||||
* @param string $bClearAfterGet = false
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function Get($sKey, $bClearAfterGet = false)
|
||||
{
|
||||
$sValue = '';
|
||||
|
||||
if ($this->oDriver)
|
||||
{
|
||||
$sValue = $this->oDriver->Get($sKey.$this->sCacheIndex);
|
||||
}
|
||||
|
||||
if ($bClearAfterGet)
|
||||
{
|
||||
$this->Delete($sKey);
|
||||
}
|
||||
|
||||
return $sValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function GetTimer($sKey)
|
||||
{
|
||||
$iTimer = 0;
|
||||
$sValue = $this->Get($sKey.'/TIMER');
|
||||
if (0 < strlen($sValue) && is_numeric($sValue))
|
||||
{
|
||||
$iTimer = (int) $sValue;
|
||||
}
|
||||
|
||||
return $iTimer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return \MailSo\Cache\CacheClient
|
||||
*/
|
||||
public function Delete($sKey)
|
||||
{
|
||||
if ($this->oDriver)
|
||||
{
|
||||
$this->oDriver->Delete($sKey.$this->sCacheIndex);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \MailSo\Cache\DriverInterface $oDriver
|
||||
*
|
||||
* @return \MailSo\Cache\CacheClient
|
||||
*/
|
||||
public function SetDriver(\MailSo\Cache\DriverInterface $oDriver)
|
||||
{
|
||||
$this->oDriver = $oDriver;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iTimeToClearInHours = 24
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function GC($iTimeToClearInHours = 24)
|
||||
{
|
||||
return $this->oDriver ? $this->oDriver->GC($iTimeToClearInHours) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsInited()
|
||||
{
|
||||
return $this->oDriver instanceof \MailSo\Cache\DriverInterface;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sCacheIndex
|
||||
*
|
||||
* @return \MailSo\Cache\CacheClient
|
||||
*/
|
||||
public function SetCacheIndex($sCacheIndex)
|
||||
{
|
||||
$this->sCacheIndex = 0 < \strlen($sCacheIndex) ? "\x0".$sCacheIndex : '';
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Cache;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Cache
|
||||
*/
|
||||
interface DriverInterface
|
||||
{
|
||||
/**
|
||||
* @param string $sKey
|
||||
* @param string $sValue
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Set($sKey, $sValue);
|
||||
|
||||
/**
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function Get($sKey);
|
||||
|
||||
/**
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function Delete($sKey);
|
||||
|
||||
/**
|
||||
* @param int $iTimeToClearInHours = 24
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function GC($iTimeToClearInHours = 24);
|
||||
}
|
|
@ -1,85 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Cache\Drivers;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Cache
|
||||
* @subpackage Drivers
|
||||
*/
|
||||
class APC implements \MailSo\Cache\DriverInterface
|
||||
{
|
||||
/**
|
||||
* @return \MailSo\Cache\Drivers\APC
|
||||
*/
|
||||
public static function NewInstance()
|
||||
{
|
||||
return new self();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sKey
|
||||
* @param string $sValue
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Set($sKey, $sValue)
|
||||
{
|
||||
return \apc_store($this->generateCachedKey($sKey), (string) $sValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function Get($sKey)
|
||||
{
|
||||
$sValue = \apc_fetch($this->generateCachedKey($sKey));
|
||||
return \is_string($sValue) ? $sValue : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function Delete($sKey)
|
||||
{
|
||||
\apc_delete($this->generateCachedKey($sKey));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iTimeToClearInHours = 24
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function GC($iTimeToClearInHours = 24)
|
||||
{
|
||||
if (0 === $iTimeToClearInHours)
|
||||
{
|
||||
return \apc_clear_cache('user');
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function generateCachedKey($sKey)
|
||||
{
|
||||
return \sha1($sKey);
|
||||
}
|
||||
}
|
|
@ -1,135 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Cache\Drivers;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Cache
|
||||
* @subpackage Drivers
|
||||
*/
|
||||
class File implements \MailSo\Cache\DriverInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sCacheFolder;
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*
|
||||
* @param string $sCacheFolder
|
||||
*/
|
||||
private function __construct($sCacheFolder)
|
||||
{
|
||||
$this->sCacheFolder = $sCacheFolder;
|
||||
$this->sCacheFolder = rtrim(trim($this->sCacheFolder), '\\/').'/';
|
||||
if (!\is_dir($this->sCacheFolder))
|
||||
{
|
||||
@\mkdir($this->sCacheFolder, 0755);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sCacheFolder
|
||||
*
|
||||
* @return \MailSo\Cache\Drivers\File
|
||||
*/
|
||||
public static function NewInstance($sCacheFolder)
|
||||
{
|
||||
return new self($sCacheFolder);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sKey
|
||||
* @param string $sValue
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Set($sKey, $sValue)
|
||||
{
|
||||
return false !== \file_put_contents($sPath = $this->generateCachedFileName($sKey, true), $sValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function Get($sKey)
|
||||
{
|
||||
$sValue = '';
|
||||
$sPath = $this->generateCachedFileName($sKey);
|
||||
if (\file_exists($sPath))
|
||||
{
|
||||
$sValue = \file_get_contents($sPath);
|
||||
}
|
||||
|
||||
return \is_string($sValue) ? $sValue : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function Delete($sKey)
|
||||
{
|
||||
$sPath = $this->generateCachedFileName($sKey);
|
||||
if (\file_exists($sPath))
|
||||
{
|
||||
\unlink($sPath);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iTimeToClearInHours = 24
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function GC($iTimeToClearInHours = 24)
|
||||
{
|
||||
if (0 < $iTimeToClearInHours)
|
||||
{
|
||||
\MailSo\Base\Utils::RecTimeDirRemove($this->sCacheFolder, 60 * 60 * $iTimeToClearInHours, \time());
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sKey
|
||||
* @param bool $bMkDir = false
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function generateCachedFileName($sKey, $bMkDir = false)
|
||||
{
|
||||
$sFilePath = '';
|
||||
if (3 < \strlen($sKey))
|
||||
{
|
||||
$sKeyPath = \sha1($sKey);
|
||||
$sKeyPath = \substr($sKeyPath, 0, 2).'/'.\substr($sKeyPath, 2, 2).'/'.$sKeyPath;
|
||||
|
||||
$sFilePath = $this->sCacheFolder.'/'.$sKeyPath;
|
||||
if ($bMkDir && !\is_dir(\dirname($sFilePath)))
|
||||
{
|
||||
if (!\mkdir(\dirname($sFilePath), 0755, true))
|
||||
{
|
||||
$sFilePath = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $sFilePath;
|
||||
}
|
||||
}
|
|
@ -1,129 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Cache\Drivers;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Cache
|
||||
* @subpackage Drivers
|
||||
*/
|
||||
class Memcache implements \MailSo\Cache\DriverInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sHost;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $iPost;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $iExpire;
|
||||
|
||||
/**
|
||||
* @var \Memcache|null
|
||||
*/
|
||||
private $oMem;
|
||||
|
||||
/**
|
||||
* @param string $sHost = '127.0.0.1'
|
||||
* @param int $iPost = 11211
|
||||
* @param int $iExpire = 43200
|
||||
*/
|
||||
private function __construct($sHost = '127.0.0.1', $iPost = 11211, $iExpire = 43200)
|
||||
{
|
||||
$this->sHost = $sHost;
|
||||
$this->iPost = $iPost;
|
||||
$this->iExpire = 0 < $iExpire ? $iExpire : 43200;
|
||||
|
||||
$this->oMem = new \Memcache();
|
||||
if (!$this->oMem->connect($this->sHost, $this->iPost))
|
||||
{
|
||||
$this->oMem = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sHost = '127.0.0.1'
|
||||
* @param int $iPost = 11211
|
||||
*
|
||||
* @return \MailSo\Cache\Drivers\APC
|
||||
*/
|
||||
public static function NewInstance($sHost = '127.0.0.1', $iPost = 11211)
|
||||
{
|
||||
return new self($sHost, $iPost);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sKey
|
||||
* @param string $sValue
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Set($sKey, $sValue)
|
||||
{
|
||||
return $this->oMem ? $this->oMem->set($this->generateCachedKey($sKey), $sValue, 0, $this->iExpire) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function Get($sKey)
|
||||
{
|
||||
$sValue = $this->oMem ? $this->oMem->get($this->generateCachedKey($sKey)) : '';
|
||||
return \is_string($sValue) ? $sValue : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function Delete($sKey)
|
||||
{
|
||||
if ($this->oMem)
|
||||
{
|
||||
$this->oMem->delete($this->generateCachedKey($sKey));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iTimeToClearInHours = 24
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function GC($iTimeToClearInHours = 24)
|
||||
{
|
||||
if (0 === $iTimeToClearInHours && $this->oMem)
|
||||
{
|
||||
return $this->oMem->flush();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function generateCachedKey($sKey)
|
||||
{
|
||||
return \sha1($sKey);
|
||||
}
|
||||
}
|
|
@ -1,68 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
*/
|
||||
class Config
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public static $ICONV = true;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public static $MBSTRING = true;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public static $FixIconvByMbstring = true;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public static $MessageListFastSimpleSearch = true;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public static $MessageListCountLimitTrigger = 0;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public static $MessageListDateFilter = 0;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public static $LargeThreadLimit = 100;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public static $LogSimpleLiterals = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public static $PreferStartTlsIfAutoDetect = true;
|
||||
|
||||
/**
|
||||
* @var \MailSo\Log\Logger|null
|
||||
*/
|
||||
public static $SystemLogger = null;
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
*/
|
||||
class Hooks
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
static $aCallbacks = array();
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param array $aArg
|
||||
*/
|
||||
static public function Run($sName, $aArg = array())
|
||||
{
|
||||
if (isset(\MailSo\Hooks::$aCallbacks[$sName]))
|
||||
{
|
||||
foreach (\MailSo\Hooks::$aCallbacks[$sName] as $mCallback)
|
||||
{
|
||||
\call_user_func_array($mCallback, $aArg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param mixed $mCallback
|
||||
*/
|
||||
static public function Add($sName, $mCallback)
|
||||
{
|
||||
if (\is_callable($mCallback))
|
||||
{
|
||||
if (!isset(\MailSo\Hooks::$aCallbacks[$sName]))
|
||||
{
|
||||
\MailSo\Hooks::$aCallbacks[$sName] = array();
|
||||
}
|
||||
|
||||
\MailSo\Hooks::$aCallbacks[$sName][] = $mCallback;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,918 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Imap;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Imap
|
||||
*/
|
||||
class BodyStructure
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sContentType;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sCharset;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $aBodyParams;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sContentID;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sDescription;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sMailEncodingName;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sDisposition;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $aDispositionParams;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sFileName;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sLanguage;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sLocation;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $iSize;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $iTextLineCount;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sPartID;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $aSubParts;
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*
|
||||
* @param string $sContentType
|
||||
* @param string $sCharset
|
||||
* @param array $aBodyParams
|
||||
* @param string $sContentID
|
||||
* @param string $sDescription
|
||||
* @param string $sMailEncodingName
|
||||
* @param string $sDisposition
|
||||
* @param array $aDispositionParams
|
||||
* @param string $sFileName
|
||||
* @param string $sLanguage
|
||||
* @param string $sLocation
|
||||
* @param int $iSize
|
||||
* @param int $iTextLineCount
|
||||
* @param string $sPartID
|
||||
* @param array $aSubParts
|
||||
*/
|
||||
private function __construct($sContentType, $sCharset, $aBodyParams, $sContentID,
|
||||
$sDescription, $sMailEncodingName, $sDisposition, $aDispositionParams, $sFileName,
|
||||
$sLanguage, $sLocation, $iSize, $iTextLineCount, $sPartID, $aSubParts)
|
||||
{
|
||||
$this->sContentType = $sContentType;
|
||||
$this->sCharset = $sCharset;
|
||||
$this->aBodyParams = $aBodyParams;
|
||||
$this->sContentID = $sContentID;
|
||||
$this->sDescription = $sDescription;
|
||||
$this->sMailEncodingName = $sMailEncodingName;
|
||||
$this->sDisposition = $sDisposition;
|
||||
$this->aDispositionParams = $aDispositionParams;
|
||||
$this->sFileName = $sFileName;
|
||||
$this->sLanguage = $sLanguage;
|
||||
$this->sLocation = $sLocation;
|
||||
$this->iSize = $iSize;
|
||||
$this->iTextLineCount = $iTextLineCount;
|
||||
$this->sPartID = $sPartID;
|
||||
$this->aSubParts = $aSubParts;
|
||||
}
|
||||
|
||||
/**
|
||||
* return string
|
||||
*/
|
||||
public function MailEncodingName()
|
||||
{
|
||||
return $this->sMailEncodingName;
|
||||
}
|
||||
|
||||
/**
|
||||
* return string
|
||||
*/
|
||||
public function PartID()
|
||||
{
|
||||
return (string) $this->sPartID;
|
||||
}
|
||||
|
||||
/**
|
||||
* return string
|
||||
*/
|
||||
public function FileName()
|
||||
{
|
||||
return $this->sFileName;
|
||||
}
|
||||
|
||||
/**
|
||||
* return string
|
||||
*/
|
||||
public function ContentType()
|
||||
{
|
||||
return $this->sContentType;
|
||||
}
|
||||
|
||||
/**
|
||||
* return int
|
||||
*/
|
||||
public function Size()
|
||||
{
|
||||
return (int) $this->iSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* return int
|
||||
*/
|
||||
public function EstimatedSize()
|
||||
{
|
||||
$fCoefficient = 1;
|
||||
switch (\strtolower($this->MailEncodingName()))
|
||||
{
|
||||
case 'base64':
|
||||
$fCoefficient = 0.75;
|
||||
break;
|
||||
case 'quoted-printable':
|
||||
$fCoefficient = 0.44;
|
||||
break;
|
||||
}
|
||||
|
||||
return (int) ($this->Size() * $fCoefficient);
|
||||
}
|
||||
|
||||
/**
|
||||
* return string
|
||||
*/
|
||||
public function Charset()
|
||||
{
|
||||
return $this->sCharset;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* return string
|
||||
*/
|
||||
public function ContentID()
|
||||
{
|
||||
return (null === $this->sContentID) ? '' : $this->sContentID;
|
||||
}
|
||||
|
||||
/**
|
||||
* return string
|
||||
*/
|
||||
public function ContentLocation()
|
||||
{
|
||||
return (null === $this->sLocation) ? '' : $this->sLocation;
|
||||
}
|
||||
|
||||
/**
|
||||
* return bool
|
||||
*/
|
||||
public function IsInline()
|
||||
{
|
||||
return (null === $this->sDisposition) ?
|
||||
(0 < \strlen($this->ContentID())) : ('inline' === strtolower($this->sDisposition));
|
||||
}
|
||||
|
||||
/**
|
||||
* return bool
|
||||
*/
|
||||
public function IsImage()
|
||||
{
|
||||
return 'image' === \MailSo\Base\Utils::ContentTypeType($this->ContentType(), $this->FileName());
|
||||
}
|
||||
|
||||
/**
|
||||
* return bool
|
||||
*/
|
||||
public function IsArchive()
|
||||
{
|
||||
return 'archive' === \MailSo\Base\Utils::ContentTypeType($this->ContentType(), $this->FileName());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsPdf()
|
||||
{
|
||||
return 'pdf' === \MailSo\Base\Utils::ContentTypeType($this->ContentType(), $this->FileName());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsDoc()
|
||||
{
|
||||
return 'doc' === \MailSo\Base\Utils::ContentTypeType($this->ContentType(), $this->FileName());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsPgpSignature()
|
||||
{
|
||||
return \in_array(\strtolower($this->ContentType()),
|
||||
array('application/pgp-signature', 'application/pkcs7-signature'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsAttachBodyPart()
|
||||
{
|
||||
$bResult = (
|
||||
(null !== $this->sDisposition && 'attachment' === \strtolower($this->sDisposition))
|
||||
);
|
||||
|
||||
if (!$bResult && null !== $this->sContentType)
|
||||
{
|
||||
$sContentType = \strtolower($this->sContentType);
|
||||
$bResult = false === \strpos($sContentType, 'multipart/') &&
|
||||
'text/html' !== $sContentType && 'text/plain' !== $sContentType;
|
||||
}
|
||||
|
||||
return $bResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|null
|
||||
*/
|
||||
public function SearchPlainParts()
|
||||
{
|
||||
$aReturn = array();
|
||||
$aParts = $this->SearchByContentType('text/plain');
|
||||
foreach ($aParts as $oPart)
|
||||
{
|
||||
if (!$oPart->IsAttachBodyPart())
|
||||
{
|
||||
$aReturn[] = $oPart;
|
||||
}
|
||||
}
|
||||
return $aReturn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|null
|
||||
*/
|
||||
public function SearchHtmlParts()
|
||||
{
|
||||
$aReturn = array();
|
||||
$aParts = $this->SearchByContentType('text/html');
|
||||
|
||||
foreach ($aParts as $oPart)
|
||||
{
|
||||
if (!$oPart->IsAttachBodyPart())
|
||||
{
|
||||
$aReturn[] = $oPart;
|
||||
}
|
||||
}
|
||||
|
||||
return $aReturn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|null
|
||||
*/
|
||||
public function SearchHtmlOrPlainParts()
|
||||
{
|
||||
$mResult = $this->SearchHtmlParts();
|
||||
if (null === $mResult || (\is_array($mResult) && 0 === count($mResult)))
|
||||
{
|
||||
$mResult = $this->SearchPlainParts();
|
||||
}
|
||||
|
||||
return $mResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function SearchCharset()
|
||||
{
|
||||
$sResult = '';
|
||||
$mParts = array();
|
||||
|
||||
$mHtmlParts = $this->SearchHtmlParts();
|
||||
$mPlainParts = $this->SearchPlainParts();
|
||||
|
||||
if (\is_array($mHtmlParts) && 0 < \count($mHtmlParts))
|
||||
{
|
||||
$mParts = \array_merge($mParts, $mHtmlParts);
|
||||
}
|
||||
|
||||
if (\is_array($mPlainParts) && 0 < \count($mPlainParts))
|
||||
{
|
||||
$mParts = \array_merge($mParts, $mPlainParts);
|
||||
}
|
||||
|
||||
foreach ($mParts as $oPart)
|
||||
{
|
||||
$sResult = $oPart ? $oPart->Charset() : '';
|
||||
if (!empty($sResult))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (0 === strlen($sResult))
|
||||
{
|
||||
$aParts = $this->SearchAttachmentsParts();
|
||||
foreach ($aParts as $oPart)
|
||||
{
|
||||
if (0 === \strlen($sResult))
|
||||
{
|
||||
$sResult = $oPart ? $oPart->Charset() : '';
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $sResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $fCallback
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function SearchByCallback($fCallback)
|
||||
{
|
||||
$aReturn = array();
|
||||
if (\call_user_func($fCallback, $this))
|
||||
{
|
||||
$aReturn[] = $this;
|
||||
}
|
||||
|
||||
if (\is_array($this->aSubParts) && 0 < \count($this->aSubParts))
|
||||
{
|
||||
foreach ($this->aSubParts as /* @var $oSubPart \MailSo\Imap\BodyStructure */ &$oSubPart)
|
||||
{
|
||||
$aReturn = \array_merge($aReturn, $oSubPart->SearchByCallback($fCallback));
|
||||
}
|
||||
}
|
||||
|
||||
return $aReturn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function SearchAttachmentsParts()
|
||||
{
|
||||
return $this->SearchByCallback(function ($oItem) {
|
||||
return $oItem->IsAttachBodyPart();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sContentType
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function SearchByContentType($sContentType)
|
||||
{
|
||||
$sContentType = \strtolower($sContentType);
|
||||
return $this->SearchByCallback(function ($oItem) use ($sContentType) {
|
||||
return $sContentType === $oItem->ContentType();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sMimeIndex
|
||||
*
|
||||
* @return \MailSo\Imap\BodyStructure
|
||||
*/
|
||||
public function GetPartByMimeIndex($sMimeIndex)
|
||||
{
|
||||
$oPart = null;
|
||||
if (0 < \strlen($sMimeIndex))
|
||||
{
|
||||
if ($sMimeIndex === $this->sPartID)
|
||||
{
|
||||
$oPart = $this;
|
||||
}
|
||||
|
||||
if (null === $oPart && is_array($this->aSubParts) && 0 < count($this->aSubParts))
|
||||
{
|
||||
foreach ($this->aSubParts as /* @var $oSubPart \MailSo\Imap\BodyStructure */ &$oSubPart)
|
||||
{
|
||||
$oPart = $oSubPart->GetPartByMimeIndex($sMimeIndex);
|
||||
if (null !== $oPart)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $oPart;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $aParams
|
||||
* @param string $sParamName
|
||||
* @param string $sCharset = \MailSo\Base\Enumerations\Charset::UTF_8
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function decodeAttrParamenter($aParams, $sParamName, $sCharset = \MailSo\Base\Enumerations\Charset::UTF_8)
|
||||
{
|
||||
$sResult = '';
|
||||
if (isset($aParams[$sParamName]))
|
||||
{
|
||||
$sResult = \MailSo\Base\Utils::DecodeHeaderValue($aParams[$sParamName], $sCharset);
|
||||
}
|
||||
else if (isset($aParams[$sParamName.'*']))
|
||||
{
|
||||
$aValueParts = \explode("''", $aParams[$sParamName.'*'], 2);
|
||||
if (\is_array($aValueParts) && 2 === \count($aValueParts))
|
||||
{
|
||||
$sCharset = isset($aValueParts[0]) ? $aValueParts[0] : \MailSo\Base\Enumerations\Charset::UTF_8;
|
||||
|
||||
$sResult = \MailSo\Base\Utils::ConvertEncoding(
|
||||
\urldecode($aValueParts[1]), $sCharset, \MailSo\Base\Enumerations\Charset::UTF_8);
|
||||
}
|
||||
else
|
||||
{
|
||||
$sResult = \urldecode($aParams[$sParamName.'*']);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$sCharset = '';
|
||||
$sCharsetIndex = -1;
|
||||
|
||||
$aFileNames = array();
|
||||
foreach ($aParams as $sName => $sValue)
|
||||
{
|
||||
$aMatches = array();
|
||||
if (\preg_match('/^'.\preg_quote($sParamName, '/').'\*([0-9]+)\*$/i', $sName, $aMatches))
|
||||
{
|
||||
$iIndex = (int) $aMatches[1];
|
||||
if ($sCharsetIndex < $iIndex && false !== \strpos($sValue, "''"))
|
||||
{
|
||||
$aValueParts = \explode("''", $sValue, 2);
|
||||
if (\is_array($aValueParts) && 2 === \count($aValueParts) && 0 < \strlen($aValueParts[0]))
|
||||
{
|
||||
$sCharsetIndex = $iIndex;
|
||||
$sCharset = $aValueParts[0];
|
||||
$sValue = $aValueParts[1];
|
||||
}
|
||||
}
|
||||
|
||||
$aFileNames[$iIndex] = $sValue;
|
||||
}
|
||||
}
|
||||
|
||||
if (0 < \count($aFileNames))
|
||||
{
|
||||
\ksort($aFileNames, SORT_NUMERIC);
|
||||
$sResult = \implode(\array_values($aFileNames));
|
||||
$sResult = \urldecode($sResult);
|
||||
|
||||
if (0 < \strlen($sCharset))
|
||||
{
|
||||
$sResult = \MailSo\Base\Utils::ConvertEncoding($sResult,
|
||||
$sCharset, \MailSo\Base\Enumerations\Charset::UTF_8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $sResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $aBodyStructure
|
||||
* @param string $sPartID = ''
|
||||
*
|
||||
* @return \MailSo\Imap\BodyStructure
|
||||
*/
|
||||
public static function NewInstance(array $aBodyStructure, $sPartID = '')
|
||||
{
|
||||
if (!\is_array($aBodyStructure) || 2 > \count($aBodyStructure))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
$sBodyMainType = null;
|
||||
if (\is_string($aBodyStructure[0]) && 'NIL' !== $aBodyStructure[0])
|
||||
{
|
||||
$sBodyMainType = $aBodyStructure[0];
|
||||
}
|
||||
|
||||
$sBodySubType = null;
|
||||
$sContentType = '';
|
||||
$aSubParts = null;
|
||||
$aBodyParams = array();
|
||||
$sName = null;
|
||||
$sCharset = null;
|
||||
$sContentID = null;
|
||||
$sDescription = null;
|
||||
$sMailEncodingName = null;
|
||||
$iSize = 0;
|
||||
$iTextLineCount = 0; // valid for rfc822/message and text parts
|
||||
$iExtraItemPos = 0; // list index of items which have no well-established position (such as 0, 1, 5, etc).
|
||||
|
||||
if (null === $sBodyMainType)
|
||||
{
|
||||
// Process multipart body structure
|
||||
if (!\is_array($aBodyStructure[0]))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
$sBodyMainType = 'multipart';
|
||||
$sSubPartIDPrefix = '';
|
||||
if (0 === \strlen($sPartID) || '.' === $sPartID[\strlen($sPartID) - 1])
|
||||
{
|
||||
// This multi-part is root part of message.
|
||||
$sSubPartIDPrefix = $sPartID;
|
||||
$sPartID .= 'TEXT';
|
||||
}
|
||||
else if (0 < \strlen($sPartID))
|
||||
{
|
||||
// This multi-part is a part of another multi-part.
|
||||
$sSubPartIDPrefix = $sPartID.'.';
|
||||
}
|
||||
|
||||
$aSubParts = array();
|
||||
$iIndex = 1;
|
||||
|
||||
while ($iExtraItemPos < \count($aBodyStructure) && \is_array($aBodyStructure[$iExtraItemPos]))
|
||||
{
|
||||
$oPart = self::NewInstance($aBodyStructure[$iExtraItemPos], $sSubPartIDPrefix.$iIndex);
|
||||
if (null === $oPart)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
// For multipart, we have no charset info in the part itself. Thus,
|
||||
// obtain charset from nested parts.
|
||||
if ($sCharset == null)
|
||||
{
|
||||
$sCharset = $oPart->Charset();
|
||||
}
|
||||
|
||||
$aSubParts[] = $oPart;
|
||||
$iExtraItemPos++;
|
||||
$iIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($iExtraItemPos < \count($aBodyStructure))
|
||||
{
|
||||
if (!\is_string($aBodyStructure[$iExtraItemPos]) || 'NIL' === $aBodyStructure[$iExtraItemPos])
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
$sBodySubType = \strtolower($aBodyStructure[$iExtraItemPos]);
|
||||
$iExtraItemPos++;
|
||||
}
|
||||
|
||||
if ($iExtraItemPos < \count($aBodyStructure))
|
||||
{
|
||||
$sBodyParamList = $aBodyStructure[$iExtraItemPos];
|
||||
if (\is_array($sBodyParamList))
|
||||
{
|
||||
$aBodyParams = self::getKeyValueListFromArrayList($sBodyParamList);
|
||||
}
|
||||
}
|
||||
|
||||
$iExtraItemPos++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Process simple (singlepart) body structure
|
||||
if (7 > \count($aBodyStructure))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
$sBodyMainType = \strtolower($sBodyMainType);
|
||||
if (!\is_string($aBodyStructure[1]) || 'NIL' === $aBodyStructure[1])
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
$sBodySubType = \strtolower($aBodyStructure[1]);
|
||||
|
||||
$aBodyParamList = $aBodyStructure[2];
|
||||
if (\is_array($aBodyParamList))
|
||||
{
|
||||
$aBodyParams = self::getKeyValueListFromArrayList($aBodyParamList);
|
||||
if (isset($aBodyParams['charset']))
|
||||
{
|
||||
$sCharset = $aBodyParams['charset'];
|
||||
}
|
||||
|
||||
if (\is_array($aBodyParams))
|
||||
{
|
||||
$sName = self::decodeAttrParamenter($aBodyParams, 'name', $sContentType);
|
||||
}
|
||||
}
|
||||
|
||||
if (null !== $aBodyStructure[3] && 'NIL' !== $aBodyStructure[3])
|
||||
{
|
||||
if (!\is_string($aBodyStructure[3]))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
$sContentID = $aBodyStructure[3];
|
||||
}
|
||||
|
||||
if (null !== $aBodyStructure[4] && 'NIL' !== $aBodyStructure[4])
|
||||
{
|
||||
if (!\is_string($aBodyStructure[4]))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
$sDescription = $aBodyStructure[4];
|
||||
}
|
||||
|
||||
if (null !== $aBodyStructure[5] && 'NIL' !== $aBodyStructure[5])
|
||||
{
|
||||
if (!\is_string($aBodyStructure[5]))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
$sMailEncodingName = $aBodyStructure[5];
|
||||
}
|
||||
|
||||
if (\is_numeric($aBodyStructure[6]))
|
||||
{
|
||||
$iSize = (int) $aBodyStructure[6];
|
||||
}
|
||||
else
|
||||
{
|
||||
$iSize = -1;
|
||||
}
|
||||
|
||||
if (0 === \strlen($sPartID) || '.' === $sPartID[\strlen($sPartID) - 1])
|
||||
{
|
||||
// This is the only sub-part of the message (otherwise, it would be
|
||||
// one of sub-parts of a multi-part, and partID would already be fully set up).
|
||||
$sPartID .= '1';
|
||||
}
|
||||
|
||||
$iExtraItemPos = 7;
|
||||
if ('text' === $sBodyMainType)
|
||||
{
|
||||
if ($iExtraItemPos < \count($aBodyStructure))
|
||||
{
|
||||
if (\is_numeric($aBodyStructure[$iExtraItemPos]))
|
||||
{
|
||||
$iTextLineCount = (int) $aBodyStructure[$iExtraItemPos];
|
||||
}
|
||||
else
|
||||
{
|
||||
$iTextLineCount = -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$iTextLineCount = -1;
|
||||
}
|
||||
|
||||
$iExtraItemPos++;
|
||||
}
|
||||
else if ('message' === $sBodyMainType && 'rfc822' === $sBodySubType)
|
||||
{
|
||||
if ($iExtraItemPos + 2 < \count($aBodyStructure))
|
||||
{
|
||||
if (\is_numeric($aBodyStructure[$iExtraItemPos + 2]))
|
||||
{
|
||||
$iTextLineCount = (int) $aBodyStructure[$iExtraItemPos + 2];
|
||||
}
|
||||
else
|
||||
{
|
||||
$iTextLineCount = -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$iTextLineCount = -1;
|
||||
}
|
||||
|
||||
$iExtraItemPos += 3;
|
||||
}
|
||||
|
||||
$iExtraItemPos++; // skip MD5 digest of the body because most mail servers leave it NIL anyway
|
||||
}
|
||||
|
||||
$sContentType = $sBodyMainType.'/'.$sBodySubType;
|
||||
|
||||
$sDisposition = null;
|
||||
$aDispositionParams = null;
|
||||
$sFileName = null;
|
||||
|
||||
if ($iExtraItemPos < \count($aBodyStructure))
|
||||
{
|
||||
$aDispList = $aBodyStructure[$iExtraItemPos];
|
||||
if (\is_array($aDispList) && 1 < \count($aDispList))
|
||||
{
|
||||
if (null !== $aDispList[0])
|
||||
{
|
||||
if (\is_string($aDispList[0]) && 'NIL' !== $aDispList[0])
|
||||
{
|
||||
$sDisposition = $aDispList[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$aDispParamList = $aDispList[1];
|
||||
if (\is_array($aDispParamList))
|
||||
{
|
||||
$aDispositionParams = self::getKeyValueListFromArrayList($aDispParamList);
|
||||
if (\is_array($aDispositionParams))
|
||||
{
|
||||
$sFileName = self::decodeAttrParamenter($aDispositionParams, 'filename', $sCharset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$iExtraItemPos++;
|
||||
|
||||
$sLanguage = null;
|
||||
if ($iExtraItemPos < count($aBodyStructure))
|
||||
{
|
||||
if (null !== $aBodyStructure[$iExtraItemPos] && 'NIL' !== $aBodyStructure[$iExtraItemPos])
|
||||
{
|
||||
if (\is_array($aBodyStructure[$iExtraItemPos]))
|
||||
{
|
||||
$sLanguage = \implode(',', $aBodyStructure[$iExtraItemPos]);
|
||||
}
|
||||
else if (\is_string($aBodyStructure[$iExtraItemPos]))
|
||||
{
|
||||
$sLanguage = $aBodyStructure[$iExtraItemPos];
|
||||
}
|
||||
}
|
||||
$iExtraItemPos++;
|
||||
}
|
||||
|
||||
$sLocation = null;
|
||||
if ($iExtraItemPos < \count($aBodyStructure))
|
||||
{
|
||||
if (null !== $aBodyStructure[$iExtraItemPos] && 'NIL' !== $aBodyStructure[$iExtraItemPos])
|
||||
{
|
||||
if (\is_string($aBodyStructure[$iExtraItemPos]))
|
||||
{
|
||||
$sLocation = $aBodyStructure[$iExtraItemPos];
|
||||
}
|
||||
}
|
||||
$iExtraItemPos++;
|
||||
}
|
||||
|
||||
return new self(
|
||||
$sContentType,
|
||||
$sCharset,
|
||||
$aBodyParams,
|
||||
$sContentID,
|
||||
$sDescription,
|
||||
$sMailEncodingName,
|
||||
$sDisposition,
|
||||
$aDispositionParams,
|
||||
\MailSo\Base\Utils::Utf8Clear((null === $sFileName || 0 === \strlen($sFileName)) ? $sName : $sFileName),
|
||||
$sLanguage,
|
||||
$sLocation,
|
||||
$iSize,
|
||||
$iTextLineCount,
|
||||
$sPartID,
|
||||
$aSubParts
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $aBodyStructure
|
||||
* @param string $sSubPartID
|
||||
*
|
||||
* @return \MailSo\Imap\BodyStructure|null
|
||||
*/
|
||||
public static function NewInstanceFromRfc822SubPart(array $aBodyStructure, $sSubPartID)
|
||||
{
|
||||
$oBody = null;
|
||||
$aBodySubStructure = self::findPartByIndexInArray($aBodyStructure, $sSubPartID);
|
||||
if ($aBodySubStructure && \is_array($aBodySubStructure) && isset($aBodySubStructure[8]))
|
||||
{
|
||||
$oBody = self::NewInstance($aBodySubStructure[8], $sSubPartID);
|
||||
}
|
||||
|
||||
return $oBody;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $aList
|
||||
* @param string $sPartID
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
private static function findPartByIndexInArray(array $aList, $sPartID)
|
||||
{
|
||||
$bFind = false;
|
||||
$aPath = \explode('.', ''.$sPartID);
|
||||
$aCurrentPart = $aList;
|
||||
|
||||
foreach ($aPath as $iPos => $iNum)
|
||||
{
|
||||
$iIndex = \intval($iNum) - 1;
|
||||
if (0 <= $iIndex && 0 < $iPos ? isset($aCurrentPart[8][$iIndex]) : isset($aCurrentPart[$iIndex]))
|
||||
{
|
||||
$aCurrentPart = 0 < $iPos ? $aCurrentPart[8][$iIndex] : $aCurrentPart[$iIndex];
|
||||
$bFind = true;
|
||||
}
|
||||
}
|
||||
|
||||
return $bFind ? $aCurrentPart : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns dict with key="charset" and value="US-ASCII" for array ("CHARSET" "US-ASCII").
|
||||
* Keys are lowercased (StringDictionary itself does this), values are not altered.
|
||||
*
|
||||
* @param array $aList
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private static function getKeyValueListFromArrayList(array $aList)
|
||||
{
|
||||
$aDict = null;
|
||||
if (0 === \count($aList) % 2)
|
||||
{
|
||||
$aDict = array();
|
||||
for ($iIndex = 0, $iLen = \count($aList); $iIndex < $iLen; $iIndex += 2)
|
||||
{
|
||||
if (\is_string($aList[$iIndex]) && isset($aList[$iIndex + 1]) && \is_string($aList[$iIndex + 1]))
|
||||
{
|
||||
$aDict[\strtolower($aList[$iIndex])] = $aList[$iIndex + 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $aDict;
|
||||
}
|
||||
}
|
|
@ -1,127 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Imap\Enumerations;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Imap
|
||||
* @subpackage Enumerations
|
||||
*/
|
||||
class FetchType
|
||||
{
|
||||
const ALL = 'ALL';
|
||||
const FAST = 'FAST';
|
||||
const FULL = 'FULL';
|
||||
const BODY = 'BODY';
|
||||
const BODY_PEEK = 'BODY.PEEK';
|
||||
const BODY_HEADER = 'BODY[HEADER]';
|
||||
const BODY_HEADER_PEEK = 'BODY.PEEK[HEADER]';
|
||||
const BODYSTRUCTURE = 'BODYSTRUCTURE';
|
||||
const ENVELOPE = 'ENVELOPE';
|
||||
const FLAGS = 'FLAGS';
|
||||
const INTERNALDATE = 'INTERNALDATE';
|
||||
const RFC822 = 'RFC822';
|
||||
const RFC822_HEADER = 'RFC822.HEADER';
|
||||
const RFC822_SIZE = 'RFC822.SIZE';
|
||||
const RFC822_TEXT = 'RFC822.TEXT';
|
||||
const UID = 'UID';
|
||||
const INDEX = 'INDEX';
|
||||
|
||||
const GMAIL_MSGID = 'X-GM-MSGID';
|
||||
const GMAIL_THRID = 'X-GM-THRID';
|
||||
const GMAIL_LABELS = 'X-GM-LABELS';
|
||||
|
||||
/**
|
||||
* @param array $aReturn
|
||||
*
|
||||
* @param string|array $mType
|
||||
*/
|
||||
private static function addHelper(&$aReturn, $mType)
|
||||
{
|
||||
if (\is_string($mType))
|
||||
{
|
||||
$aReturn[$mType] = '';
|
||||
}
|
||||
else if (\is_array($mType) && 2 === count($mType) && \is_string($mType[0]) &&
|
||||
is_callable($mType[1]))
|
||||
{
|
||||
$aReturn[$mType[0]] = $mType[1];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $aHeaders
|
||||
* @param bool $bPeek = true
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function BuildBodyCustomHeaderRequest(array $aHeaders, $bPeek = true)
|
||||
{
|
||||
$sResult = '';
|
||||
if (0 < \count($aHeaders))
|
||||
{
|
||||
$aHeaders = \array_map('trim', $aHeaders);
|
||||
$aHeaders = \array_map('strtoupper', $aHeaders);
|
||||
|
||||
$sResult = $bPeek ? self::BODY_PEEK : self::BODY;
|
||||
$sResult .= '[HEADER.FIELDS ('.\implode(' ', $aHeaders).')]';
|
||||
}
|
||||
|
||||
return $sResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $aFetchItems
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function ChangeFetchItemsBefourRequest(array $aFetchItems)
|
||||
{
|
||||
$aReturn = array();
|
||||
self::addHelper($aReturn, self::UID);
|
||||
self::addHelper($aReturn, self::RFC822_SIZE);
|
||||
|
||||
foreach ($aFetchItems as $mFetchKey)
|
||||
{
|
||||
switch ($mFetchKey)
|
||||
{
|
||||
default:
|
||||
if (is_string($mFetchKey) || is_array($mFetchKey))
|
||||
{
|
||||
self::addHelper($aReturn, $mFetchKey);
|
||||
}
|
||||
break;
|
||||
case self::INDEX:
|
||||
case self::UID:
|
||||
case self::RFC822_SIZE:
|
||||
break;
|
||||
case self::ALL:
|
||||
self::addHelper($aReturn, self::FLAGS);
|
||||
self::addHelper($aReturn, self::INTERNALDATE);
|
||||
self::addHelper($aReturn, self::ENVELOPE);
|
||||
break;
|
||||
case self::FAST:
|
||||
self::addHelper($aReturn, self::FLAGS);
|
||||
self::addHelper($aReturn, self::INTERNALDATE);
|
||||
break;
|
||||
case self::FULL:
|
||||
self::addHelper($aReturn, self::FLAGS);
|
||||
self::addHelper($aReturn, self::INTERNALDATE);
|
||||
self::addHelper($aReturn, self::ENVELOPE);
|
||||
self::addHelper($aReturn, self::BODY);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $aReturn;
|
||||
}
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Imap\Enumerations;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Imap
|
||||
* @subpackage Enumerations
|
||||
*/
|
||||
class FolderResponseStatus
|
||||
{
|
||||
const MESSAGES = 'MESSAGES';
|
||||
const RECENT = 'RECENT';
|
||||
const UNSEEN = 'UNSEEN';
|
||||
const UIDNEXT = 'UIDNEXT';
|
||||
const UIDVALIDITY = 'UIDVALIDITY';
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Imap\Enumerations;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Imap
|
||||
* @subpackage Enumerations
|
||||
*/
|
||||
class FolderStatus
|
||||
{
|
||||
const MESSAGES = 'MESSAGES';
|
||||
const RECENT = 'RECENT';
|
||||
const UNSEEN = 'UNSEEN';
|
||||
const UIDNEXT = 'UIDNEXT';
|
||||
const UIDVALIDITY = 'UIDVALIDITY';
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Imap\Enumerations;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Imap
|
||||
* @subpackage Enumerations
|
||||
*/
|
||||
class FolderType
|
||||
{
|
||||
const USER = 0;
|
||||
const INBOX = 1;
|
||||
const SENT = 2;
|
||||
const DRAFTS = 3;
|
||||
const JUNK = 4;
|
||||
const TRASH = 5;
|
||||
const IMPORTANT = 10;
|
||||
const FLAGGED = 11;
|
||||
const ALL = 12;
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Imap\Enumerations;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Imap
|
||||
* @subpackage Enumerations
|
||||
*/
|
||||
class MessageFlag
|
||||
{
|
||||
const RECENT = '\Recent';
|
||||
const SEEN = '\Seen';
|
||||
const DELETED = '\Deleted';
|
||||
const FLAGGED = '\Flagged';
|
||||
const ANSWERED = '\Answered';
|
||||
const DRAFT = '\Draft';
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Imap\Enumerations;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Imap
|
||||
* @subpackage Enumerations
|
||||
*/
|
||||
class ResponseStatus
|
||||
{
|
||||
const OK = 'OK';
|
||||
const NO = 'NO';
|
||||
const BAD = 'BAD';
|
||||
const BYE = 'BYE';
|
||||
const PREAUTH = 'PREAUTH';
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Imap\Enumerations;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Imap
|
||||
* @subpackage Enumerations
|
||||
*/
|
||||
class ResponseType
|
||||
{
|
||||
const UNKNOWN = 0;
|
||||
const TAGGED = 1;
|
||||
const UNTAGGED = 2;
|
||||
const CONTINUATION = 3;
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Imap\Enumerations;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Imap
|
||||
* @subpackage Enumerations
|
||||
*/
|
||||
class StoreAction
|
||||
{
|
||||
const SET_FLAGS = 'FLAGS';
|
||||
const SET_FLAGS_SILENT = 'FLAGS.SILENT';
|
||||
const ADD_FLAGS = '+FLAGS';
|
||||
const ADD_FLAGS_SILENT = '+FLAGS.SILENT';
|
||||
const REMOVE_FLAGS = '-FLAGS';
|
||||
const REMOVE_FLAGS_SILENT = '-FLAGS.SILENT';
|
||||
|
||||
const SET_GMAIL_LABELS = 'X-GM-LABELS';
|
||||
const SET_GMAIL_LABELS_SILENT = 'X-GM-LABELS.SILENT';
|
||||
const ADD_GMAIL_LABELS = '+X-GM-LABELS';
|
||||
const ADD_GMAIL_LABELS_SILENT = '+X-GM-LABELS.SILENT';
|
||||
const REMOVE_GMAIL_LABELS = '-X-GM-LABELS';
|
||||
const REMOVE_GMAIL_LABELS_SILENT = '-X-GM-LABELS.SILENT';
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Imap\Exceptions;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Imap
|
||||
* @subpackage Exceptions
|
||||
*/
|
||||
class Exception extends \MailSo\Base\Exceptions\Exception {}
|
|
@ -1,19 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Imap\Exceptions;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Imap
|
||||
* @subpackage Exceptions
|
||||
*/
|
||||
class InvalidResponseException extends \MailSo\Imap\Exceptions\ResponseException {}
|
|
@ -1,19 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Imap\Exceptions;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Imap
|
||||
* @subpackage Exceptions
|
||||
*/
|
||||
class LoginBadCredentialsException extends \MailSo\Imap\Exceptions\LoginException {}
|
|
@ -1,19 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Imap\Exceptions;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Imap
|
||||
* @subpackage Exceptions
|
||||
*/
|
||||
class LoginBadMethodException extends \MailSo\Imap\Exceptions\LoginException {}
|
|
@ -1,19 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Imap\Exceptions;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Imap
|
||||
* @subpackage Exceptions
|
||||
*/
|
||||
class LoginException extends \MailSo\Imap\Exceptions\NegativeResponseException {}
|
|
@ -1,37 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Imap\Exceptions;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Imap
|
||||
* @subpackage Exceptions
|
||||
*/
|
||||
class NegativeResponseException extends \MailSo\Imap\Exceptions\ResponseException
|
||||
{
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getAlertFromStatus()
|
||||
{
|
||||
$sResult = '';
|
||||
|
||||
$oResponse = $this->GetLastResponse();
|
||||
if ($oResponse && $oResponse->IsStatusResponse && !empty($oResponse->HumanReadable) &&
|
||||
isset($oResponse->OptionalResponse[0]) && 'ALERT' === $oResponse->OptionalResponse[0])
|
||||
{
|
||||
$sResult = $oResponse->HumanReadable;
|
||||
}
|
||||
|
||||
return $sResult;
|
||||
}
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Imap\Exceptions;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Imap
|
||||
* @subpackage Exceptions
|
||||
*/
|
||||
class ResponseException extends \MailSo\Imap\Exceptions\Exception
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $aResponses;
|
||||
|
||||
/**
|
||||
* @param array $aResponses = array
|
||||
* @param string $sMessage = ''
|
||||
* @param int $iCode = 0
|
||||
* @param \Exception $oPrevious = null
|
||||
*/
|
||||
public function __construct($aResponses = array(), $sMessage = '', $iCode = 0, $oPrevious = null)
|
||||
{
|
||||
parent::__construct($sMessage, $iCode, $oPrevious);
|
||||
|
||||
if (is_array($aResponses))
|
||||
{
|
||||
$this->aResponses = $aResponses;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function GetResponses()
|
||||
{
|
||||
return $this->aResponses;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \MailSo\Imap\Response|null
|
||||
*/
|
||||
public function GetLastResponse()
|
||||
{
|
||||
return 0 < count($this->aResponses) ? $this->aResponses[count($this->aResponses) - 1] : null;
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Imap\Exceptions;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Imap
|
||||
* @subpackage Exceptions
|
||||
*/
|
||||
class ResponseNotFoundException extends \MailSo\Imap\Exceptions\Exception {}
|
|
@ -1,19 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Imap\Exceptions;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Imap
|
||||
* @subpackage Exceptions
|
||||
*/
|
||||
class RuntimeException extends \MailSo\Imap\Exceptions\Exception {}
|
|
@ -1,274 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Imap;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Imap
|
||||
*/
|
||||
class FetchResponse
|
||||
{
|
||||
/**
|
||||
* @var \MailSo\Imap\Response
|
||||
*/
|
||||
private $oImapResponse;
|
||||
|
||||
/**
|
||||
* @var array|null
|
||||
*/
|
||||
private $aEnvelopeCache;
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*
|
||||
* @param \MailSo\Imap\Response $oImapResponse
|
||||
*/
|
||||
private function __construct($oImapResponse)
|
||||
{
|
||||
$this->oImapResponse = $oImapResponse;
|
||||
$this->aEnvelopeCache = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \MailSo\Imap\Response $oImapResponse
|
||||
* @return \MailSo\Imap\FetchResponse
|
||||
*/
|
||||
public static function NewInstance($oImapResponse)
|
||||
{
|
||||
return new self($oImapResponse);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $bForce = false
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
public function GetEnvelope($bForce = false)
|
||||
{
|
||||
if (null === $this->aEnvelopeCache || $bForce)
|
||||
{
|
||||
$this->aEnvelopeCache = $this->GetFetchValue(Enumerations\FetchType::ENVELOPE);
|
||||
}
|
||||
return $this->aEnvelopeCache;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iIndex
|
||||
* @param mixed $mNullResult = null
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function GetFetchEnvelopeValue($iIndex, $mNullResult)
|
||||
{
|
||||
return self::findEnvelopeIndex($this->GetEnvelope(), $iIndex, $mNullResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iIndex
|
||||
* @param string $sParentCharset = \MailSo\Base\Enumerations\Charset::ISO_8859_1
|
||||
*
|
||||
* @return \MailSo\Mime\EmailCollection|null
|
||||
*/
|
||||
public function GetFetchEnvelopeEmailCollection($iIndex, $sParentCharset = \MailSo\Base\Enumerations\Charset::ISO_8859_1)
|
||||
{
|
||||
$oResult = null;
|
||||
$aEmails = $this->GetFetchEnvelopeValue($iIndex, null);
|
||||
if (is_array($aEmails) && 0 < count($aEmails))
|
||||
{
|
||||
$oResult = \MailSo\Mime\EmailCollection::NewInstance();
|
||||
foreach ($aEmails as $aEmailItem)
|
||||
{
|
||||
if (is_array($aEmailItem) && 4 === count($aEmailItem))
|
||||
{
|
||||
$sDisplayName = \MailSo\Base\Utils::DecodeHeaderValue(
|
||||
self::findEnvelopeIndex($aEmailItem, 0, ''), $sParentCharset);
|
||||
|
||||
$sRemark = \MailSo\Base\Utils::DecodeHeaderValue(
|
||||
self::findEnvelopeIndex($aEmailItem, 1, ''), $sParentCharset);
|
||||
|
||||
$sLocalPart = self::findEnvelopeIndex($aEmailItem, 2, '');
|
||||
$sDomainPart = self::findEnvelopeIndex($aEmailItem, 3, '');
|
||||
|
||||
if (0 < strlen($sLocalPart) && 0 < strlen($sDomainPart))
|
||||
{
|
||||
$oResult->Add(
|
||||
\MailSo\Mime\Email::NewInstance(
|
||||
$sLocalPart.'@'.$sDomainPart, $sDisplayName, $sRemark)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $oResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sRfc822SubMimeIndex = ''
|
||||
*
|
||||
* @return \MailSo\Imap\BodyStructure|null
|
||||
*/
|
||||
public function GetFetchBodyStructure($sRfc822SubMimeIndex = '')
|
||||
{
|
||||
$oBodyStructure = null;
|
||||
$aBodyStructureArray = $this->GetFetchValue(Enumerations\FetchType::BODYSTRUCTURE);
|
||||
|
||||
if (is_array($aBodyStructureArray))
|
||||
{
|
||||
if (0 < strlen($sRfc822SubMimeIndex))
|
||||
{
|
||||
$oBodyStructure = BodyStructure::NewInstanceFromRfc822SubPart($aBodyStructureArray, $sRfc822SubMimeIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
$oBodyStructure = BodyStructure::NewInstance($aBodyStructureArray);
|
||||
}
|
||||
}
|
||||
|
||||
return $oBodyStructure;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sFetchItemName
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function GetFetchValue($sFetchItemName)
|
||||
{
|
||||
$mReturn = null;
|
||||
$bNextIsValue = false;
|
||||
|
||||
if (Enumerations\FetchType::INDEX === $sFetchItemName)
|
||||
{
|
||||
$mReturn = $this->oImapResponse->ResponseList[1];
|
||||
}
|
||||
else if (isset($this->oImapResponse->ResponseList[3]) && \is_array($this->oImapResponse->ResponseList[3]))
|
||||
{
|
||||
foreach ($this->oImapResponse->ResponseList[3] as $mItem)
|
||||
{
|
||||
if ($bNextIsValue)
|
||||
{
|
||||
$mReturn = $mItem;
|
||||
break;
|
||||
}
|
||||
|
||||
if ($sFetchItemName === $mItem)
|
||||
{
|
||||
$bNextIsValue = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $mReturn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sRfc822SubMimeIndex = ''
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function GetHeaderFieldsValue($sRfc822SubMimeIndex = '')
|
||||
{
|
||||
$sReturn = '';
|
||||
$bNextIsValue = false;
|
||||
|
||||
$sRfc822SubMimeIndex = 0 < \strlen($sRfc822SubMimeIndex) ? ''.$sRfc822SubMimeIndex.'.' : '';
|
||||
|
||||
if (isset($this->oImapResponse->ResponseList[3]) && \is_array($this->oImapResponse->ResponseList[3]))
|
||||
{
|
||||
foreach ($this->oImapResponse->ResponseList[3] as $mItem)
|
||||
{
|
||||
if ($bNextIsValue)
|
||||
{
|
||||
$sReturn = (string) $mItem;
|
||||
break;
|
||||
}
|
||||
|
||||
if (\is_string($mItem) && (
|
||||
$mItem === 'BODY['.$sRfc822SubMimeIndex.'HEADER]' ||
|
||||
0 === \strpos($mItem, 'BODY['.$sRfc822SubMimeIndex.'HEADER.FIELDS') ||
|
||||
$mItem === 'BODY['.$sRfc822SubMimeIndex.'MIME]'))
|
||||
{
|
||||
$bNextIsValue = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $sReturn;
|
||||
}
|
||||
|
||||
private static function findFetchUidAndSize($aList)
|
||||
{
|
||||
$bUid = false;
|
||||
$bSize = false;
|
||||
if (is_array($aList))
|
||||
{
|
||||
foreach ($aList as $mItem)
|
||||
{
|
||||
if (\MailSo\Imap\Enumerations\FetchType::UID === $mItem)
|
||||
{
|
||||
$bUid = true;
|
||||
}
|
||||
else if (\MailSo\Imap\Enumerations\FetchType::RFC822_SIZE === $mItem)
|
||||
{
|
||||
$bSize = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $bUid && $bSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \MailSo\Imap\Response $oImapResponse
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function IsValidFetchImapResponse($oImapResponse)
|
||||
{
|
||||
return (
|
||||
$oImapResponse
|
||||
&& true !== $oImapResponse->IsStatusResponse
|
||||
&& \MailSo\Imap\Enumerations\ResponseType::UNTAGGED === $oImapResponse->ResponseType
|
||||
&& 3 < count($oImapResponse->ResponseList) && 'FETCH' === $oImapResponse->ResponseList[2]
|
||||
&& is_array($oImapResponse->ResponseList[3])
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \MailSo\Imap\Response $oImapResponse
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function IsNotEmptyFetchImapResponse($oImapResponse)
|
||||
{
|
||||
return (
|
||||
$oImapResponse
|
||||
&& self::IsValidFetchImapResponse($oImapResponse)
|
||||
&& isset($oImapResponse->ResponseList[3])
|
||||
&& self::findFetchUidAndSize($oImapResponse->ResponseList[3])
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $aEnvelope
|
||||
* @param int $iIndex
|
||||
* @param mixed $mNullResult = null
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private static function findEnvelopeIndex($aEnvelope, $iIndex, $mNullResult)
|
||||
{
|
||||
return (isset($aEnvelope[$iIndex]) && 'NIL' !== $aEnvelope[$iIndex] && '' !== $aEnvelope[$iIndex])
|
||||
? $aEnvelope[$iIndex] : $mNullResult;
|
||||
}
|
||||
}
|
|
@ -1,188 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Imap;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Imap
|
||||
*/
|
||||
class Folder
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sNameRaw;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sFullNameRaw;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sDelimiter;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $aFlags;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $aFlagsLowerCase;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $aExtended;
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*
|
||||
* @param string $sFullNameRaw
|
||||
* @param string $sDelimiter
|
||||
* @param array $aFlags
|
||||
*
|
||||
* @throws \MailSo\Base\Exceptions\InvalidArgumentException
|
||||
*/
|
||||
private function __construct($sFullNameRaw, $sDelimiter, array $aFlags)
|
||||
{
|
||||
$this->sNameRaw = '';
|
||||
$this->sFullNameRaw = '';
|
||||
$this->sDelimiter = '';
|
||||
$this->aFlags = array();
|
||||
$this->aExtended = array();
|
||||
|
||||
$sDelimiter = 'NIL' === \strtoupper($sDelimiter) ? '' : $sDelimiter;
|
||||
if (empty($sDelimiter))
|
||||
{
|
||||
$sDelimiter = '.'; // default delimiter
|
||||
}
|
||||
|
||||
if (!\is_array($aFlags) ||
|
||||
!\is_string($sDelimiter) || 1 < \strlen($sDelimiter) ||
|
||||
!\is_string($sFullNameRaw) || 0 === \strlen($sFullNameRaw))
|
||||
{
|
||||
throw new \MailSo\Base\Exceptions\InvalidArgumentException();
|
||||
}
|
||||
|
||||
$this->sFullNameRaw = $sFullNameRaw;
|
||||
$this->sDelimiter = $sDelimiter;
|
||||
$this->aFlags = $aFlags;
|
||||
$this->aFlagsLowerCase = \array_map('strtolower', $this->aFlags);
|
||||
|
||||
$this->sFullNameRaw = 'INBOX'.$this->sDelimiter === \substr(\strtoupper($this->sFullNameRaw), 0, 5 + \strlen($this->sDelimiter)) ?
|
||||
'INBOX'.\substr($this->sFullNameRaw, 5) : $this->sFullNameRaw;
|
||||
|
||||
if ($this->IsInbox())
|
||||
{
|
||||
$this->sFullNameRaw = 'INBOX';
|
||||
}
|
||||
|
||||
$this->sNameRaw = $this->sFullNameRaw;
|
||||
if (0 < \strlen($this->sDelimiter))
|
||||
{
|
||||
$aNames = \explode($this->sDelimiter, $this->sFullNameRaw);
|
||||
$this->sNameRaw = \end($aNames);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sFullNameRaw
|
||||
* @param string $sDelimiter = '.'
|
||||
* @param array $aFlags = array()
|
||||
*
|
||||
* @return \MailSo\Imap\Folder
|
||||
*
|
||||
* @throws \MailSo\Base\Exceptions\InvalidArgumentException
|
||||
*/
|
||||
public static function NewInstance($sFullNameRaw, $sDelimiter = '.', $aFlags = array())
|
||||
{
|
||||
return new self($sFullNameRaw, $sDelimiter, $aFlags);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function NameRaw()
|
||||
{
|
||||
return $this->sNameRaw;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function FullNameRaw()
|
||||
{
|
||||
return $this->sFullNameRaw;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string | null
|
||||
*/
|
||||
public function Delimiter()
|
||||
{
|
||||
return $this->sDelimiter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function Flags()
|
||||
{
|
||||
return $this->aFlags;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function FlagsLowerCase()
|
||||
{
|
||||
return $this->aFlagsLowerCase;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsSelectable()
|
||||
{
|
||||
return !\in_array('\noselect', $this->aFlagsLowerCase);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsInbox()
|
||||
{
|
||||
return 'INBOX' === \strtoupper($this->sFullNameRaw) || \in_array('\inbox', $this->aFlagsLowerCase);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param mixed $mData
|
||||
*/
|
||||
public function SetExtended($sName, $mData)
|
||||
{
|
||||
$this->aExtended[$sName] = $mData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @return mixed
|
||||
*/
|
||||
public function GetExtended($sName)
|
||||
{
|
||||
return isset($this->aExtended[$sName]) ? $this->aExtended[$sName] : null;
|
||||
}
|
||||
}
|
|
@ -1,104 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Imap;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Imap
|
||||
*/
|
||||
class FolderInformation
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $FolderName;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $IsWritable;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $Flags;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $PermanentFlags;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $Exists;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $Recent;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $Uidvalidity;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $Unread;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $Uidnext;
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*
|
||||
* @param string $sFolderName
|
||||
* @param bool $bIsWritable
|
||||
*/
|
||||
private function __construct($sFolderName, $bIsWritable)
|
||||
{
|
||||
$this->FolderName = $sFolderName;
|
||||
$this->IsWritable = $bIsWritable;
|
||||
$this->Exists = null;
|
||||
$this->Recent = null;
|
||||
$this->Flags = array();
|
||||
$this->PermanentFlags = array();
|
||||
|
||||
$this->Unread = null;
|
||||
$this->Uidnext = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sFolderName
|
||||
* @param bool $bIsWritable
|
||||
*
|
||||
* @return \MailSo\Imap\FolderInformation
|
||||
*/
|
||||
public static function NewInstance($sFolderName, $bIsWritable)
|
||||
{
|
||||
return new self($sFolderName, $bIsWritable);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sFlag
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function IsFlagSupported($sFlag)
|
||||
{
|
||||
return \in_array('\\*', $this->PermanentFlags) || \in_array($sFlag, $this->PermanentFlags);
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -1,132 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Imap;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Imap
|
||||
*/
|
||||
class NamespaceResult
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sPersonal;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sPersonalDelimiter;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sOtherUser;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sOtherUserDelimiter;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sShared;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sSharedDelimiter;
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*/
|
||||
private function __construct()
|
||||
{
|
||||
$this->sPersonal = '';
|
||||
$this->sPersonalDelimiter = '';
|
||||
$this->sOtherUser = '';
|
||||
$this->sOtherUserDelimiter = '';
|
||||
$this->sShared = '';
|
||||
$this->sSharedDelimiter = '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \MailSo\Imap\NamespaceResult
|
||||
*/
|
||||
public static function NewInstance()
|
||||
{
|
||||
return new self();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \MailSo\Imap\Response $oImapResponse
|
||||
*
|
||||
* @return \MailSo\Imap\NamespaceResult
|
||||
*/
|
||||
public function InitByImapResponse($oImapResponse)
|
||||
{
|
||||
if ($oImapResponse && $oImapResponse instanceof \MailSo\Imap\Response)
|
||||
{
|
||||
if (isset($oImapResponse->ResponseList[2][0]) &&
|
||||
\is_array($oImapResponse->ResponseList[2][0]) &&
|
||||
2 <= \count($oImapResponse->ResponseList[2][0]))
|
||||
{
|
||||
$this->sPersonal = $oImapResponse->ResponseList[2][0][0];
|
||||
$this->sPersonalDelimiter = $oImapResponse->ResponseList[2][0][1];
|
||||
|
||||
$this->sPersonal = 'INBOX'.$this->sPersonalDelimiter === \substr(\strtoupper($this->sPersonal), 0, 6) ?
|
||||
'INBOX'.$this->sPersonalDelimiter.\substr($this->sPersonal, 6) : $this->sPersonal;
|
||||
}
|
||||
|
||||
if (isset($oImapResponse->ResponseList[3][0]) &&
|
||||
\is_array($oImapResponse->ResponseList[3][0]) &&
|
||||
2 <= \count($oImapResponse->ResponseList[3][0]))
|
||||
{
|
||||
$this->sOtherUser = $oImapResponse->ResponseList[3][0][0];
|
||||
$this->sOtherUserDelimiter = $oImapResponse->ResponseList[3][0][1];
|
||||
|
||||
$this->sOtherUser = 'INBOX'.$this->sOtherUserDelimiter === \substr(\strtoupper($this->sOtherUser), 0, 6) ?
|
||||
'INBOX'.$this->sOtherUserDelimiter.\substr($this->sOtherUser, 6) : $this->sOtherUser;
|
||||
}
|
||||
|
||||
if (isset($oImapResponse->ResponseList[4][0]) &&
|
||||
\is_array($oImapResponse->ResponseList[4][0]) &&
|
||||
2 <= \count($oImapResponse->ResponseList[4][0]))
|
||||
{
|
||||
$this->sShared = $oImapResponse->ResponseList[4][0][0];
|
||||
$this->sSharedDelimiter = $oImapResponse->ResponseList[4][0][1];
|
||||
|
||||
$this->sShared = 'INBOX'.$this->sSharedDelimiter === \substr(\strtoupper($this->sShared), 0, 6) ?
|
||||
'INBOX'.$this->sSharedDelimiter.\substr($this->sShared, 6) : $this->sShared;
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function GetPersonalNamespace()
|
||||
{
|
||||
return $this->sPersonal;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function GetPersonalNamespaceDelimiter()
|
||||
{
|
||||
return $this->sPersonalDelimiter;
|
||||
}
|
||||
}
|
|
@ -1,104 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Imap;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Imap
|
||||
*/
|
||||
class Response
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $ResponseList;
|
||||
|
||||
/**
|
||||
* @var array | null
|
||||
*/
|
||||
public $OptionalResponse;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $StatusOrIndex;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $HumanReadable;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $IsStatusResponse;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $ResponseType;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $Tag;
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*/
|
||||
private function __construct()
|
||||
{
|
||||
$this->ResponseList = array();
|
||||
$this->OptionalResponse = null;
|
||||
$this->StatusOrIndex = '';
|
||||
$this->HumanReadable = '';
|
||||
$this->IsStatusResponse = false;
|
||||
$this->ResponseType = \MailSo\Imap\Enumerations\ResponseType::UNKNOWN;
|
||||
$this->Tag = '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \MailSo\Imap\Response
|
||||
*/
|
||||
public static function NewInstance()
|
||||
{
|
||||
return new self();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $aList
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function recToLine($aList)
|
||||
{
|
||||
$aResult = array();
|
||||
if (\is_array($aList))
|
||||
{
|
||||
foreach ($aList as $mItem)
|
||||
{
|
||||
$aResult[] = \is_array($mItem) ? '('.$this->recToLine($mItem).')' : (string) $mItem;
|
||||
}
|
||||
}
|
||||
|
||||
return \implode(' ', $aResult);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function ToLine()
|
||||
{
|
||||
return $this->recToLine($this->ResponseList);
|
||||
}
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Usenko Timur
|
||||
|
||||
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.
|
|
@ -1,347 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Log;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Log
|
||||
*/
|
||||
abstract class Driver
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $sDatePattern;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $sName;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $aPrefixes;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $bGuidPrefix;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $bTimePrefix;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $bTypedPrefix;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $iWriteOnTimeoutOnly;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $bWriteOnErrorOnly;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $bWriteOnPhpErrorOnly;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $bFlushCache;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $aCache;
|
||||
|
||||
/**
|
||||
* @access protected
|
||||
*/
|
||||
protected function __construct()
|
||||
{
|
||||
$this->sDatePattern = 'H:i:s';
|
||||
$this->sName = 'INFO';
|
||||
$this->bTimePrefix = true;
|
||||
$this->bTypedPrefix = true;
|
||||
$this->bGuidPrefix = true;
|
||||
|
||||
$this->iWriteOnTimeoutOnly = 0;
|
||||
$this->bWriteOnErrorOnly = false;
|
||||
$this->bWriteOnPhpErrorOnly = false;
|
||||
$this->bFlushCache = false;
|
||||
$this->aCache = array();
|
||||
|
||||
$this->aPrefixes = array(
|
||||
\MailSo\Log\Enumerations\Type::INFO => '[DATA]',
|
||||
\MailSo\Log\Enumerations\Type::SECURE => '[SECURE]',
|
||||
\MailSo\Log\Enumerations\Type::NOTE => '[NOTE]',
|
||||
\MailSo\Log\Enumerations\Type::TIME => '[TIME]',
|
||||
\MailSo\Log\Enumerations\Type::TIME_DELTA => '[TIME]',
|
||||
\MailSo\Log\Enumerations\Type::MEMORY => '[MEMORY]',
|
||||
\MailSo\Log\Enumerations\Type::NOTICE => '[NOTICE]',
|
||||
\MailSo\Log\Enumerations\Type::WARNING => '[WARNING]',
|
||||
\MailSo\Log\Enumerations\Type::ERROR => '[ERROR]',
|
||||
|
||||
\MailSo\Log\Enumerations\Type::NOTICE_PHP => '[NOTICE]',
|
||||
\MailSo\Log\Enumerations\Type::WARNING_PHP => '[WARNING]',
|
||||
\MailSo\Log\Enumerations\Type::ERROR_PHP => '[ERROR]',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \MailSo\Log\Driver
|
||||
*/
|
||||
public function DisableGuidPrefix()
|
||||
{
|
||||
$this->bGuidPrefix = false;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \MailSo\Log\Driver
|
||||
*/
|
||||
public function DisableTimePrefix()
|
||||
{
|
||||
$this->bTimePrefix = false;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $bValue
|
||||
*
|
||||
* @return \MailSo\Log\Driver
|
||||
*/
|
||||
public function WriteOnErrorOnly($bValue)
|
||||
{
|
||||
$this->bWriteOnErrorOnly = !!$bValue;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $bValue
|
||||
*
|
||||
* @return \MailSo\Log\Driver
|
||||
*/
|
||||
public function WriteOnPhpErrorOnly($bValue)
|
||||
{
|
||||
$this->bWriteOnPhpErrorOnly = !!$bValue;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iTimeout
|
||||
*
|
||||
* @return \MailSo\Log\Driver
|
||||
*/
|
||||
public function WriteOnTimeoutOnly($iTimeout)
|
||||
{
|
||||
$this->iWriteOnTimeoutOnly = (int) $iTimeout;
|
||||
if (0 > $this->iWriteOnTimeoutOnly)
|
||||
{
|
||||
$this->iWriteOnTimeoutOnly = 0;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \MailSo\Log\Driver
|
||||
*/
|
||||
public function DisableTypedPrefix()
|
||||
{
|
||||
$this->bTypedPrefix = false;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|array $mDesc
|
||||
* @return bool
|
||||
*/
|
||||
abstract protected function writeImplementation($mDesc);
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
protected function writeEmptyLineImplementation()
|
||||
{
|
||||
return $this->writeImplementation('');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sTimePrefix
|
||||
* @param string $sDesc
|
||||
* @param int $iType = \MailSo\Log\Enumerations\Type::INFO
|
||||
* @param array $sName = ''
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function loggerLineImplementation($sTimePrefix, $sDesc,
|
||||
$iType = \MailSo\Log\Enumerations\Type::INFO, $sName = '')
|
||||
{
|
||||
return \ltrim(
|
||||
($this->bTimePrefix ? '['.$sTimePrefix.']' : '').
|
||||
($this->bGuidPrefix ? '['.\MailSo\Log\Logger::Guid().']' : '').
|
||||
($this->bTypedPrefix ? ' '.$this->getTypedPrefix($iType, $sName) : '')
|
||||
).$sDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
protected function clearImplementation()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function getTimeWithMicroSec()
|
||||
{
|
||||
$aMicroTimeItems = \explode(' ', \microtime());
|
||||
return \gmdate($this->sDatePattern, $aMicroTimeItems[1]).'.'.
|
||||
\str_pad((int) ($aMicroTimeItems[0] * 1000), 3, '0', STR_PAD_LEFT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iType
|
||||
* @param string $sName = ''
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getTypedPrefix($iType, $sName = '')
|
||||
{
|
||||
$sName = 0 < \strlen($sName) ? $sName : $this->sName;
|
||||
return isset($this->aPrefixes[$iType]) ? $sName.$this->aPrefixes[$iType].': ' : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @final
|
||||
* @param string $sDesc
|
||||
* @param int $iType = \MailSo\Log\Enumerations\Type::INFO
|
||||
* @param string $sName = ''
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
final public function Write($sDesc, $iType = \MailSo\Log\Enumerations\Type::INFO, $sName = '')
|
||||
{
|
||||
$bResult = true;
|
||||
if (!$this->bFlushCache && ($this->bWriteOnErrorOnly || $this->bWriteOnPhpErrorOnly || 0 < $this->iWriteOnTimeoutOnly))
|
||||
{
|
||||
$bErrorPhp = false;
|
||||
|
||||
$bError = $this->bWriteOnErrorOnly && \in_array($iType, array(
|
||||
\MailSo\Log\Enumerations\Type::NOTICE,
|
||||
\MailSo\Log\Enumerations\Type::NOTICE_PHP,
|
||||
\MailSo\Log\Enumerations\Type::WARNING,
|
||||
\MailSo\Log\Enumerations\Type::WARNING_PHP,
|
||||
\MailSo\Log\Enumerations\Type::ERROR,
|
||||
\MailSo\Log\Enumerations\Type::ERROR_PHP
|
||||
));
|
||||
|
||||
if (!$bError)
|
||||
{
|
||||
$bErrorPhp = $this->bWriteOnPhpErrorOnly && \in_array($iType, array(
|
||||
\MailSo\Log\Enumerations\Type::NOTICE_PHP,
|
||||
\MailSo\Log\Enumerations\Type::WARNING_PHP,
|
||||
\MailSo\Log\Enumerations\Type::ERROR_PHP
|
||||
));
|
||||
}
|
||||
|
||||
if ($bError || $bErrorPhp)
|
||||
{
|
||||
$sFlush = '--- FlushLogCache: '.($bError ? 'WriteOnErrorOnly' : 'WriteOnPhpErrorOnly');
|
||||
if (isset($this->aCache[0]) && empty($this->aCache[0]))
|
||||
{
|
||||
$this->aCache[0] = $sFlush;
|
||||
array_unshift($this->aCache, '');
|
||||
}
|
||||
else
|
||||
{
|
||||
array_unshift($this->aCache, $sFlush);
|
||||
}
|
||||
|
||||
$this->aCache[] = '--- FlushLogCache: Trigger';
|
||||
$this->aCache[] = $this->loggerLineImplementation($this->getTimeWithMicroSec(), $sDesc, $iType, $sName);
|
||||
|
||||
$this->bFlushCache = true;
|
||||
$bResult = $this->writeImplementation($this->aCache);
|
||||
$this->aCache = array();
|
||||
}
|
||||
else if (0 < $this->iWriteOnTimeoutOnly && \time() - APP_START_TIME > $this->iWriteOnTimeoutOnly)
|
||||
{
|
||||
$sFlush = '--- FlushLogCache: WriteOnTimeoutOnly ['.(\time() - APP_START_TIME).'sec]';
|
||||
if (isset($this->aCache[0]) && empty($this->aCache[0]))
|
||||
{
|
||||
$this->aCache[0] = $sFlush;
|
||||
array_unshift($this->aCache, '');
|
||||
}
|
||||
else
|
||||
{
|
||||
array_unshift($this->aCache, $sFlush);
|
||||
}
|
||||
|
||||
$this->aCache[] = '--- FlushLogCache: Trigger';
|
||||
$this->aCache[] = $this->loggerLineImplementation($this->getTimeWithMicroSec(), $sDesc, $iType, $sName);
|
||||
|
||||
$this->bFlushCache = true;
|
||||
$bResult = $this->writeImplementation($this->aCache);
|
||||
$this->aCache = array();
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->aCache[] = $this->loggerLineImplementation($this->getTimeWithMicroSec(), $sDesc, $iType, $sName);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$bResult = $this->writeImplementation(
|
||||
$this->loggerLineImplementation($this->getTimeWithMicroSec(), $sDesc, $iType, $sName));
|
||||
}
|
||||
|
||||
return $bResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @final
|
||||
* @return bool
|
||||
*/
|
||||
final public function Clear()
|
||||
{
|
||||
return $this->clearImplementation();
|
||||
}
|
||||
|
||||
/**
|
||||
* @final
|
||||
* @return void
|
||||
*/
|
||||
final public function WriteEmptyLine()
|
||||
{
|
||||
if (!$this->bFlushCache && ($this->bWriteOnErrorOnly || $this->bWriteOnPhpErrorOnly || 0 < $this->iWriteOnTimeoutOnly))
|
||||
{
|
||||
$this->aCache[] = '';
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->writeEmptyLineImplementation();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,83 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Log\Drivers;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Log
|
||||
* @subpackage Drivers
|
||||
*/
|
||||
class Callback extends \MailSo\Log\Driver
|
||||
{
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
private $fWriteCallback;
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
private $fClearCallback;
|
||||
|
||||
/**
|
||||
* @access protected
|
||||
*
|
||||
* @param mixed $fWriteCallback
|
||||
* @param mixed $fClearCallback
|
||||
*/
|
||||
protected function __construct($fWriteCallback, $fClearCallback)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->fWriteCallback = \is_callable($fWriteCallback) ? $fWriteCallback : null;
|
||||
$this->fClearCallback = \is_callable($fClearCallback) ? $fClearCallback : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $fWriteCallback
|
||||
* @param mixed $fClearCallback = null
|
||||
*
|
||||
* @return \MailSo\Log\Drivers\Callback
|
||||
*/
|
||||
public static function NewInstance($fWriteCallback, $fClearCallback = null)
|
||||
{
|
||||
return new self($fWriteCallback, $fClearCallback);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|array $mDesc
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function writeImplementation($mDesc)
|
||||
{
|
||||
if ($this->fWriteCallback)
|
||||
{
|
||||
\call_user_func_array($this->fWriteCallback, array($mDesc));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
protected function clearImplementation()
|
||||
{
|
||||
if ($this->fClearCallback)
|
||||
{
|
||||
\call_user_func($this->fClearCallback);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -1,96 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Log\Drivers;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Log
|
||||
* @subpackage Drivers
|
||||
*/
|
||||
class File extends \MailSo\Log\Driver
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sLoggerFileName;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sCrLf;
|
||||
|
||||
/**
|
||||
* @access protected
|
||||
*
|
||||
* @param string $sLoggerFileName
|
||||
* @param string $sCrLf = "\r\n"
|
||||
*/
|
||||
protected function __construct($sLoggerFileName, $sCrLf = "\r\n")
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->sLoggerFileName = $sLoggerFileName;
|
||||
$this->sCrLf = $sCrLf;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sLoggerFileName
|
||||
*/
|
||||
public function SetLoggerFileName($sLoggerFileName)
|
||||
{
|
||||
$this->sLoggerFileName = $sLoggerFileName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sLoggerFileName
|
||||
* @param string $sCrLf = "\r\n"
|
||||
*
|
||||
* @return \MailSo\Log\Drivers\File
|
||||
*/
|
||||
public static function NewInstance($sLoggerFileName, $sCrLf = "\r\n")
|
||||
{
|
||||
return new self($sLoggerFileName, $sCrLf);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|array $mDesc
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function writeImplementation($mDesc)
|
||||
{
|
||||
return $this->writeToLogFile($mDesc);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
protected function clearImplementation()
|
||||
{
|
||||
return \unlink($this->sLoggerFileName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|array $mDesc
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function writeToLogFile($mDesc)
|
||||
{
|
||||
if (is_array($mDesc))
|
||||
{
|
||||
$mDesc = \implode($this->sCrLf, $mDesc);
|
||||
}
|
||||
|
||||
return \error_log($mDesc.$this->sCrLf, 3, $this->sLoggerFileName);
|
||||
}
|
||||
}
|
|
@ -1,94 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Log\Drivers;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Log
|
||||
* @subpackage Drivers
|
||||
*/
|
||||
class Inline extends \MailSo\Log\Driver
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sNewLine;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $bHtmlEncodeSpecialChars;
|
||||
|
||||
/**
|
||||
* @access protected
|
||||
*
|
||||
* @param string $sNewLine = "\r\n"
|
||||
* @param bool $bHtmlEncodeSpecialChars = false
|
||||
*/
|
||||
protected function __construct($sNewLine = "\r\n", $bHtmlEncodeSpecialChars = false)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->sNewLine = $sNewLine;
|
||||
$this->bHtmlEncodeSpecialChars = $bHtmlEncodeSpecialChars;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sNewLine = "\r\n"
|
||||
* @param bool $bHtmlEncodeSpecialChars = false
|
||||
*
|
||||
* @return \MailSo\Log\Drivers\Inline
|
||||
*/
|
||||
public static function NewInstance($sNewLine = "\r\n", $bHtmlEncodeSpecialChars = false)
|
||||
{
|
||||
return new self($sNewLine, $bHtmlEncodeSpecialChars);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $mDesc
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function writeImplementation($mDesc)
|
||||
{
|
||||
if (\is_array($mDesc))
|
||||
{
|
||||
if ($this->bHtmlEncodeSpecialChars)
|
||||
{
|
||||
$mDesc = \array_map(function ($sItem) {
|
||||
return \htmlspecialchars($sItem);
|
||||
}, $mDesc);
|
||||
}
|
||||
|
||||
$mDesc = \implode($this->sNewLine, $mDesc);
|
||||
}
|
||||
else
|
||||
{
|
||||
echo ($this->bHtmlEncodeSpecialChars) ? \htmlspecialchars($mDesc).$this->sNewLine : $mDesc.$this->sNewLine;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
protected function clearImplementation()
|
||||
{
|
||||
if (\defined('PHP_SAPI') && 'cli' === PHP_SAPI && \MailSo\Base\Utils::FunctionExistsAndEnabled('system'))
|
||||
{
|
||||
\system('clear');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Log\Enumerations;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Log
|
||||
* @subpackage Enumerations
|
||||
*/
|
||||
class Type
|
||||
{
|
||||
const INFO = 0;
|
||||
const NOTICE = 1;
|
||||
const WARNING = 2;
|
||||
const ERROR = 3;
|
||||
const SECURE = 4;
|
||||
const NOTE = 5;
|
||||
const TIME = 6;
|
||||
const MEMORY = 7;
|
||||
const TIME_DELTA = 8;
|
||||
|
||||
const NOTICE_PHP = 11;
|
||||
const WARNING_PHP = 12;
|
||||
const ERROR_PHP = 13;
|
||||
}
|
|
@ -1,383 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Log;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Log
|
||||
*/
|
||||
class Logger extends \MailSo\Base\Collection
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $bUsed;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $aForbiddenTypes;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $aSecretWords;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $bShowSecter;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $bHideErrorNotices;
|
||||
|
||||
/**
|
||||
* @access protected
|
||||
*
|
||||
* @param bool $bRegPhpErrorHandler = false
|
||||
*/
|
||||
protected function __construct($bRegPhpErrorHandler = true)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->bUsed = false;
|
||||
$this->aForbiddenTypes = array();
|
||||
$this->aSecretWords = array();
|
||||
$this->bShowSecter = false;
|
||||
$this->bHideErrorNotices = false;
|
||||
|
||||
if ($bRegPhpErrorHandler)
|
||||
{
|
||||
\set_error_handler(array(&$this, '__phpErrorHandler'));
|
||||
}
|
||||
|
||||
\register_shutdown_function(array(&$this, '__loggerShutDown'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $bRegPhpErrorHandler = false
|
||||
*
|
||||
* @return \MailSo\Log\Logger
|
||||
*/
|
||||
public static function NewInstance($bRegPhpErrorHandler = false)
|
||||
{
|
||||
return new self($bRegPhpErrorHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* @staticvar \MailSo\Log\Logger $oInstance;
|
||||
*
|
||||
* @return \MailSo\Log\Logger
|
||||
*/
|
||||
public static function SingletonInstance()
|
||||
{
|
||||
static $oInstance = null;
|
||||
if (null === $oInstance)
|
||||
{
|
||||
$oInstance = self::NewInstance();
|
||||
}
|
||||
|
||||
return $oInstance;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public static function IsSystemEnabled()
|
||||
{
|
||||
return !!(\MailSo\Config::$SystemLogger instanceof \MailSo\Log\Logger);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $mData
|
||||
* @param int $iType = \MailSo\Log\Enumerations\Type::INFO
|
||||
*/
|
||||
public static function SystemLog($mData, $iType = \MailSo\Log\Enumerations\Type::INFO)
|
||||
{
|
||||
if (\MailSo\Config::$SystemLogger instanceof \MailSo\Log\Logger)
|
||||
{
|
||||
\MailSo\Config::$SystemLogger->WriteMixed($mData, $iType);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @staticvar string $sCache;
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function Guid()
|
||||
{
|
||||
static $sCache = null;
|
||||
if (null === $sCache)
|
||||
{
|
||||
$sCache = \substr(\md5(\microtime(true).\rand(10000, 99999)), -8);
|
||||
}
|
||||
|
||||
return $sCache;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function Ping()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsEnabled()
|
||||
{
|
||||
return 0 < $this->Count();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sWord
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function AddSecret($sWord)
|
||||
{
|
||||
if (0 < \strlen(\trim($sWord)))
|
||||
{
|
||||
$this->aSecretWords[] = $sWord;
|
||||
$this->aSecretWords = \array_unique($this->aSecretWords);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $bShow
|
||||
*
|
||||
* @return \MailSo\Log\Logger
|
||||
*/
|
||||
public function SetShowSecter($bShow)
|
||||
{
|
||||
$this->bShowSecter = !!$bShow;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $bValue
|
||||
*
|
||||
* @return \MailSo\Log\Logger
|
||||
*/
|
||||
public function HideErrorNotices($bValue)
|
||||
{
|
||||
$this->bHideErrorNotices = !!$bValue;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsShowSecter()
|
||||
{
|
||||
return $this->bShowSecter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iType
|
||||
*
|
||||
* @return \MailSo\Log\Logger
|
||||
*/
|
||||
public function AddForbiddenType($iType)
|
||||
{
|
||||
$this->aForbiddenTypes[$iType] = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iType
|
||||
*
|
||||
* @return \MailSo\Log\Logger
|
||||
*/
|
||||
public function RemoveForbiddenType($iType)
|
||||
{
|
||||
$this->aForbiddenTypes[$iType] = false;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iErrNo
|
||||
* @param string $sErrStr
|
||||
* @param string $sErrFile
|
||||
* @param int $iErrLine
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function __phpErrorHandler($iErrNo, $sErrStr, $sErrFile, $iErrLine)
|
||||
{
|
||||
$iType = \MailSo\Log\Enumerations\Type::NOTICE_PHP;
|
||||
switch ($iErrNo)
|
||||
{
|
||||
case E_USER_ERROR:
|
||||
$iType = \MailSo\Log\Enumerations\Type::ERROR_PHP;
|
||||
break;
|
||||
case E_USER_WARNING:
|
||||
$iType = \MailSo\Log\Enumerations\Type::WARNING_PHP;
|
||||
break;
|
||||
}
|
||||
|
||||
$this->Write($sErrFile.' [line:'.$iErrLine.', code:'.$iErrNo.']', $iType, 'PHP');
|
||||
$this->Write('Error: '.$sErrStr, $iType, 'PHP');
|
||||
|
||||
return !!(\MailSo\Log\Enumerations\Type::NOTICE === $iType && $this->bHideErrorNotices);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function __loggerShutDown()
|
||||
{
|
||||
if ($this->bUsed)
|
||||
{
|
||||
$aStatistic = \MailSo\Base\Loader::Statistic();
|
||||
if (\is_array($aStatistic))
|
||||
{
|
||||
if (isset($aStatistic['php']['memory_get_peak_usage']))
|
||||
{
|
||||
$this->Write('Memory peak usage: '.$aStatistic['php']['memory_get_peak_usage'],
|
||||
\MailSo\Log\Enumerations\Type::MEMORY);
|
||||
}
|
||||
|
||||
if (isset($aStatistic['time']))
|
||||
{
|
||||
$this->Write('Time delta: '.$aStatistic['time'], \MailSo\Log\Enumerations\Type::TIME_DELTA);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function WriteEmptyLine()
|
||||
{
|
||||
$iResult = 1;
|
||||
|
||||
$aLoggers =& $this->GetAsArray();
|
||||
foreach ($aLoggers as /* @var $oLogger \MailSo\Log\Driver */ &$oLogger)
|
||||
{
|
||||
$iResult &= $oLogger->WriteEmptyLine();
|
||||
}
|
||||
|
||||
return (bool) $iResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sDesc
|
||||
* @param int $iType = \MailSo\Log\Enumerations\Type::INFO
|
||||
* @param string $sName = ''
|
||||
* @param bool $bSearchWords = false
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Write($sDesc, $iType = \MailSo\Log\Enumerations\Type::INFO, $sName = '', $bSearchWords = false)
|
||||
{
|
||||
if (isset($this->aForbiddenTypes[$iType]) && true === $this->aForbiddenTypes[$iType])
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
$this->bUsed = true;
|
||||
|
||||
$oLogger = null;
|
||||
$aLoggers = array();
|
||||
$iResult = 1;
|
||||
|
||||
if ($bSearchWords && !$this->bShowSecter && 0 < \count($this->aSecretWords))
|
||||
{
|
||||
$sDesc = \str_replace($this->aSecretWords, '*******', $sDesc);
|
||||
}
|
||||
|
||||
$aLoggers =& $this->GetAsArray();
|
||||
foreach ($aLoggers as /* @var $oLogger \MailSo\Log\Driver */ $oLogger)
|
||||
{
|
||||
$iResult &= $oLogger->Write($sDesc, $iType, $sName);
|
||||
}
|
||||
|
||||
return (bool) $iResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $oValue
|
||||
* @param int $iType = \MailSo\Log\Enumerations\Type::INFO
|
||||
* @param string $sName = ''
|
||||
* @param bool $bSearchSecretWords = false
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function WriteDump($oValue, $iType = \MailSo\Log\Enumerations\Type::INFO, $sName = '', $bSearchSecretWords = false)
|
||||
{
|
||||
return $this->Write(\print_r($oValue, true), $iType, $sName, $bSearchSecretWords);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Exception $oException
|
||||
* @param int $iType = \MailSo\Log\Enumerations\Type::NOTICE
|
||||
* @param string $sName = ''
|
||||
* @param bool $bSearchSecretWords = true
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function WriteException($oException, $iType = \MailSo\Log\Enumerations\Type::NOTICE, $sName = '', $bSearchSecretWords = true)
|
||||
{
|
||||
if ($oException instanceof \Exception)
|
||||
{
|
||||
if (isset($oException->__LOGINNED__))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
$oException->__LOGINNED__ = true;
|
||||
|
||||
return $this->Write((string) $oException, $iType, $sName, $bSearchSecretWords);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $mData
|
||||
* @param int $iType = \MailSo\Log\Enumerations\Type::NOTICE
|
||||
* @param string $sName = ''
|
||||
* @param bool $bSearchSecretWords = true
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function WriteMixed($mData, $iType = null, $sName = '', $bSearchSecretWords = true)
|
||||
{
|
||||
$iType = null === $iType ? \MailSo\Log\Enumerations\Type::INFO : $iType;
|
||||
if (\is_array($mData) || \is_object($mData))
|
||||
{
|
||||
if ($mData instanceof \Exception)
|
||||
{
|
||||
$iType = null === $iType ? \MailSo\Log\Enumerations\Type::NOTICE : $iType;
|
||||
return $this->WriteException($mData, $iType, $sName, $bSearchSecretWords);
|
||||
}
|
||||
else
|
||||
{
|
||||
return $this->WriteDump($mData, $iType, $sName, $bSearchSecretWords);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return $this->Write($mData, $iType, $sName, $bSearchSecretWords);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -1,239 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Mail;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Mail
|
||||
*/
|
||||
class Attachment
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sFolder;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $iUid;
|
||||
|
||||
/**
|
||||
* @var \MailSo\Imap\BodyStructure
|
||||
*/
|
||||
private $oBodyStructure;
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*/
|
||||
private function __construct()
|
||||
{
|
||||
$this->Clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \MailSo\Mail\Attachment
|
||||
*/
|
||||
public function Clear()
|
||||
{
|
||||
$this->sFolder = '';
|
||||
$this->iUid = 0;
|
||||
$this->oBodyStructure = null;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Folder()
|
||||
{
|
||||
return $this->sFolder;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function Uid()
|
||||
{
|
||||
return $this->iUid;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function MimeIndex()
|
||||
{
|
||||
return $this->oBodyStructure ? $this->oBodyStructure->PartID() : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $bCalculateOnEmpty = false
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function FileName($bCalculateOnEmpty = false)
|
||||
{
|
||||
$sFileName = '';
|
||||
if ($this->oBodyStructure)
|
||||
{
|
||||
$sFileName = $this->oBodyStructure->FileName();
|
||||
if ($bCalculateOnEmpty && 0 === \strlen(trim($sFileName)))
|
||||
{
|
||||
$sMimeType = \strtolower(\trim($this->MimeType()));
|
||||
if ('message/rfc822' === $sMimeType)
|
||||
{
|
||||
$sFileName = 'message'.$this->MimeIndex().'.eml';
|
||||
}
|
||||
else if ('text/calendar' === $sMimeType)
|
||||
{
|
||||
$sFileName = 'calendar'.$this->MimeIndex().'.ics';
|
||||
}
|
||||
else if (0 < \strlen($sMimeType))
|
||||
{
|
||||
$sFileName = \str_replace('/', $this->MimeIndex().'.', $sMimeType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $sFileName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function MimeType()
|
||||
{
|
||||
return $this->oBodyStructure ? $this->oBodyStructure->ContentType() : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function ContentTransferEncoding()
|
||||
{
|
||||
return $this->oBodyStructure ? $this->oBodyStructure->MailEncodingName() : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function EncodedSize()
|
||||
{
|
||||
return $this->oBodyStructure ? $this->oBodyStructure->Size() : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function EstimatedSize()
|
||||
{
|
||||
return $this->oBodyStructure ? $this->oBodyStructure->EstimatedSize() : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Cid()
|
||||
{
|
||||
return $this->oBodyStructure ? $this->oBodyStructure->ContentID() : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function ContentLocation()
|
||||
{
|
||||
return $this->oBodyStructure ? $this->oBodyStructure->ContentLocation() : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsInline()
|
||||
{
|
||||
return $this->oBodyStructure ? $this->oBodyStructure->IsInline() : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsImage()
|
||||
{
|
||||
return $this->oBodyStructure ? $this->oBodyStructure->IsImage() : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsArchive()
|
||||
{
|
||||
return $this->oBodyStructure ? $this->oBodyStructure->IsArchive() : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsPdf()
|
||||
{
|
||||
return $this->oBodyStructure ? $this->oBodyStructure->IsPdf() : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsDoc()
|
||||
{
|
||||
return $this->oBodyStructure ? $this->oBodyStructure->IsDoc() : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsPgpSignature()
|
||||
{
|
||||
return $this->oBodyStructure ? $this->oBodyStructure->IsPgpSignature() : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \MailSo\Mail\Attachment
|
||||
*/
|
||||
public static function NewInstance()
|
||||
{
|
||||
return new self();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sFolder
|
||||
* @param int $iUid
|
||||
* @param \MailSo\Imap\BodyStructure $oBodyStructure
|
||||
* @return \MailSo\Mail\Attachment
|
||||
*/
|
||||
public static function NewBodyStructureInstance($sFolder, $iUid, $oBodyStructure)
|
||||
{
|
||||
return self::NewInstance()->InitByBodyStructure($sFolder, $iUid, $oBodyStructure);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sFolder
|
||||
* @param int $iUid
|
||||
* @param \MailSo\Imap\BodyStructure $oBodyStructure
|
||||
* @return \MailSo\Mail\Attachment
|
||||
*/
|
||||
public function InitByBodyStructure($sFolder, $iUid, $oBodyStructure)
|
||||
{
|
||||
$this->sFolder = $sFolder;
|
||||
$this->iUid = $iUid;
|
||||
$this->oBodyStructure = $oBodyStructure;
|
||||
return $this;
|
||||
}
|
||||
}
|
|
@ -1,119 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Mail;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Mail
|
||||
*/
|
||||
class AttachmentCollection extends \MailSo\Base\Collection
|
||||
{
|
||||
/**
|
||||
* @access protected
|
||||
*/
|
||||
protected function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \MailSo\Mail\AttachmentCollection
|
||||
*/
|
||||
public static function NewInstance()
|
||||
{
|
||||
return new self();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function InlineCount()
|
||||
{
|
||||
$aList = $this->FilterList(function ($oAttachment) {
|
||||
return $oAttachment && $oAttachment->IsInline();
|
||||
});
|
||||
|
||||
return \is_array($aList) ? \count($aList) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function NonInlineCount()
|
||||
{
|
||||
$aList = $this->FilterList(function ($oAttachment) {
|
||||
return $oAttachment && !$oAttachment->IsInline();
|
||||
});
|
||||
|
||||
return \is_array($aList) ? \count($aList) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function ImageCount()
|
||||
{
|
||||
$aList = $this->FilterList(function ($oAttachment) {
|
||||
return $oAttachment && $oAttachment->IsImage();
|
||||
});
|
||||
|
||||
return \is_array($aList) ? \count($aList) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function ArchiveCount()
|
||||
{
|
||||
$aList = $this->FilterList(function ($oAttachment) {
|
||||
return $oAttachment && $oAttachment->IsArchive();
|
||||
});
|
||||
|
||||
return \is_array($aList) ? \count($aList) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function PdfCount()
|
||||
{
|
||||
$aList = $this->FilterList(function ($oAttachment) {
|
||||
return $oAttachment && $oAttachment->IsPdf();
|
||||
});
|
||||
|
||||
return \is_array($aList) ? \count($aList) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function DocCount()
|
||||
{
|
||||
$aList = $this->FilterList(function ($oAttachment) {
|
||||
return $oAttachment && $oAttachment->IsDoc();
|
||||
});
|
||||
|
||||
return \is_array($aList) ? \count($aList) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function CertificateCount()
|
||||
{
|
||||
$aList = $this->FilterList(function ($oAttachment) {
|
||||
return $oAttachment && $oAttachment->IsPgpSignature();
|
||||
});
|
||||
|
||||
return \is_array($aList) ? \count($aList) : 0;
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Mail\Exceptions;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Mail
|
||||
* @subpackage Exceptions
|
||||
*/
|
||||
class Exception extends \MailSo\Base\Exceptions\Exception {}
|
|
@ -1,19 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Mail\Exceptions;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Mail
|
||||
* @subpackage Exceptions
|
||||
*/
|
||||
class NonEmptyFolder extends \MailSo\Mail\Exceptions\RuntimeException {}
|
|
@ -1,19 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Mail\Exceptions;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Mail
|
||||
* @subpackage Exceptions
|
||||
*/
|
||||
class RuntimeException extends \MailSo\Mail\Exceptions\Exception {}
|
|
@ -1,317 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Mail;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Mail
|
||||
*/
|
||||
class Folder
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sParentFullNameRaw;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $iNestingLevel;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $bExisten;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $bSubscribed;
|
||||
|
||||
/**
|
||||
* @var \MailSo\Imap\Folder
|
||||
*/
|
||||
private $oImapFolder;
|
||||
|
||||
/**
|
||||
* @var \MailSo\Mail\FolderCollection
|
||||
*/
|
||||
private $oSubFolders;
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*
|
||||
* @param \MailSo\Imap\Folder $oImapFolder
|
||||
* @param bool $bSubscribed = true
|
||||
* @param bool $bExisten = true
|
||||
*
|
||||
* @throws \MailSo\Base\Exceptions\InvalidArgumentException
|
||||
*/
|
||||
private function __construct($oImapFolder, $bSubscribed = true, $bExisten = true)
|
||||
{
|
||||
if ($oImapFolder instanceof \MailSo\Imap\Folder)
|
||||
{
|
||||
$this->oImapFolder = $oImapFolder;
|
||||
$this->oSubFolders = null;
|
||||
|
||||
$aNames = \explode($this->oImapFolder->Delimiter(), $this->oImapFolder->FullNameRaw());
|
||||
$this->iNestingLevel = \count($aNames);
|
||||
|
||||
$this->sParentFullNameRaw = '';
|
||||
if (1 < $this->iNestingLevel)
|
||||
{
|
||||
\array_pop($aNames);
|
||||
$this->sParentFullNameRaw = \implode($this->oImapFolder->Delimiter(), $aNames);
|
||||
}
|
||||
|
||||
$this->bSubscribed = $bSubscribed;
|
||||
$this->bExisten = $bExisten;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new \MailSo\Base\Exceptions\InvalidArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \MailSo\Imap\Folder $oImapFolder
|
||||
* @param bool $bSubscribed = true
|
||||
* @param bool $bExisten = true
|
||||
*
|
||||
* @return \MailSo\Mail\Folder
|
||||
*
|
||||
* @throws \MailSo\Base\Exceptions\InvalidArgumentException
|
||||
*/
|
||||
public static function NewInstance($oImapFolder, $bSubscribed = true, $bExisten = true)
|
||||
{
|
||||
return new self($oImapFolder, $bSubscribed, $bExisten);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sFullNameRaw
|
||||
* @param string $sDelimiter
|
||||
*
|
||||
* @return \MailSo\Mail\Folder
|
||||
*
|
||||
* @throws \MailSo\Base\Exceptions\InvalidArgumentException
|
||||
* @throws \MailSo\Base\Exceptions\InvalidArgumentException
|
||||
*/
|
||||
public static function NewNonExistenInstance($sFullNameRaw, $sDelimiter)
|
||||
{
|
||||
return self::NewInstance(
|
||||
\MailSo\Imap\Folder::NewInstance($sFullNameRaw, $sDelimiter, array('\NoSelect')), true, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Name()
|
||||
{
|
||||
return \MailSo\Base\Utils::ConvertEncoding($this->NameRaw(),
|
||||
\MailSo\Base\Enumerations\Charset::UTF_7_IMAP,
|
||||
\MailSo\Base\Enumerations\Charset::UTF_8);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function FullName()
|
||||
{
|
||||
return \MailSo\Base\Utils::ConvertEncoding($this->FullNameRaw(),
|
||||
\MailSo\Base\Enumerations\Charset::UTF_7_IMAP,
|
||||
\MailSo\Base\Enumerations\Charset::UTF_8);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function NameRaw()
|
||||
{
|
||||
return $this->oImapFolder->NameRaw();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function FullNameRaw()
|
||||
{
|
||||
return $this->oImapFolder->FullNameRaw();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function ParentFullName()
|
||||
{
|
||||
return \MailSo\Base\Utils::ConvertEncoding($this->sParentFullNameRaw,
|
||||
\MailSo\Base\Enumerations\Charset::UTF_7_IMAP,
|
||||
\MailSo\Base\Enumerations\Charset::UTF_8);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function ParentFullNameRaw()
|
||||
{
|
||||
return $this->sParentFullNameRaw;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Delimiter()
|
||||
{
|
||||
return $this->oImapFolder->Delimiter();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function Flags()
|
||||
{
|
||||
return $this->oImapFolder->Flags();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function FlagsLowerCase()
|
||||
{
|
||||
return $this->oImapFolder->FlagsLowerCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $bCreateIfNull = false
|
||||
* @return \MailSo\Mail\FolderCollection
|
||||
*/
|
||||
public function SubFolders($bCreateIfNull = false)
|
||||
{
|
||||
if ($bCreateIfNull && !$this->oSubFolders)
|
||||
{
|
||||
$this->oSubFolders = FolderCollection::NewInstance();
|
||||
}
|
||||
|
||||
return $this->oSubFolders;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function HasSubFolders()
|
||||
{
|
||||
return $this->oSubFolders && 0 < $this->oSubFolders->Count();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function HasVisibleSubFolders()
|
||||
{
|
||||
$sList = array();
|
||||
if ($this->oSubFolders)
|
||||
{
|
||||
$sList = $this->oSubFolders->FilterList(function (\MailSo\Mail\Folder $oFolder) {
|
||||
return $oFolder->IsSubscribed();
|
||||
});
|
||||
}
|
||||
|
||||
return 0 < \count($sList);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsSubscribed()
|
||||
{
|
||||
return $this->bSubscribed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsExists()
|
||||
{
|
||||
return $this->bExisten;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsSelectable()
|
||||
{
|
||||
return $this->IsExists() && $this->oImapFolder->IsSelectable();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function Status()
|
||||
{
|
||||
return $this->oImapFolder->GetExtended('STATUS');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsInbox()
|
||||
{
|
||||
return $this->oImapFolder->IsInbox();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function GetFolderListType()
|
||||
{
|
||||
$aFlags = $this->oImapFolder->FlagsLowerCase();
|
||||
$iListType = \MailSo\Imap\Enumerations\FolderType::USER;
|
||||
|
||||
if (\is_array($aFlags))
|
||||
{
|
||||
switch (true)
|
||||
{
|
||||
case \in_array('\inbox', $aFlags) || 'INBOX' === \strtoupper($this->FullNameRaw()):
|
||||
$iListType = \MailSo\Imap\Enumerations\FolderType::INBOX;
|
||||
break;
|
||||
case \in_array('\sent', $aFlags):
|
||||
case \in_array('\sentmail', $aFlags):
|
||||
$iListType = \MailSo\Imap\Enumerations\FolderType::SENT;
|
||||
break;
|
||||
case \in_array('\drafts', $aFlags):
|
||||
$iListType = \MailSo\Imap\Enumerations\FolderType::DRAFTS;
|
||||
break;
|
||||
case \in_array('\junk', $aFlags):
|
||||
case \in_array('\spam', $aFlags):
|
||||
$iListType = \MailSo\Imap\Enumerations\FolderType::JUNK;
|
||||
break;
|
||||
case \in_array('\trash', $aFlags):
|
||||
case \in_array('\bin', $aFlags):
|
||||
$iListType = \MailSo\Imap\Enumerations\FolderType::TRASH;
|
||||
break;
|
||||
case \in_array('\important', $aFlags):
|
||||
$iListType = \MailSo\Imap\Enumerations\FolderType::IMPORTANT;
|
||||
break;
|
||||
case \in_array('\flagged', $aFlags):
|
||||
case \in_array('\starred', $aFlags):
|
||||
$iListType = \MailSo\Imap\Enumerations\FolderType::FLAGGED;
|
||||
break;
|
||||
case \in_array('\all', $aFlags):
|
||||
case \in_array('\allmail', $aFlags):
|
||||
case \in_array('\archive', $aFlags):
|
||||
$iListType = \MailSo\Imap\Enumerations\FolderType::ALL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $iListType;
|
||||
}
|
||||
}
|
|
@ -1,233 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Mail;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Mail
|
||||
*/
|
||||
class FolderCollection extends \MailSo\Base\Collection
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sNamespace;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $FoldersHash;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $IsThreadsSupported;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $Optimized;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $SystemFolders;
|
||||
|
||||
/**
|
||||
* @access protected
|
||||
*/
|
||||
protected function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->sNamespace = '';
|
||||
$this->FoldersHash = '';
|
||||
$this->SystemFolders = array();
|
||||
$this->IsThreadsSupported = false;
|
||||
$this->Optimized = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \MailSo\Mail\FolderCollection
|
||||
*/
|
||||
public static function NewInstance()
|
||||
{
|
||||
return new self();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sFullNameRaw
|
||||
*
|
||||
* @return \MailSo\Mail\Folder|null
|
||||
*/
|
||||
public function GetByFullNameRaw($sFullNameRaw)
|
||||
{
|
||||
$mResult = null;
|
||||
foreach ($this->aItems as /* @var $oFolder \MailSo\Mail\Folder */ $oFolder)
|
||||
{
|
||||
if ($oFolder->FullNameRaw() === $sFullNameRaw)
|
||||
{
|
||||
$mResult = $oFolder;
|
||||
break;
|
||||
}
|
||||
else if ($oFolder->HasSubFolders())
|
||||
{
|
||||
$mResult = $oFolder->SubFolders(true)->GetByFullNameRaw($sFullNameRaw);
|
||||
if ($mResult)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
$mResult = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $mResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function GetNamespace()
|
||||
{
|
||||
return $this->sNamespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sNamespace
|
||||
*
|
||||
* @return \MailSo\Mail\FolderCollection
|
||||
*/
|
||||
public function SetNamespace($sNamespace)
|
||||
{
|
||||
$this->sNamespace = $sNamespace;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $aUnsortedMailFolders
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function InitByUnsortedMailFolderArray($aUnsortedMailFolders)
|
||||
{
|
||||
$this->Clear();
|
||||
|
||||
$aSortedByLenImapFolders = array();
|
||||
foreach ($aUnsortedMailFolders as /* @var $oMailFolder \MailSo\Mail\Folder */ &$oMailFolder)
|
||||
{
|
||||
$aSortedByLenImapFolders[$oMailFolder->FullNameRaw()] =& $oMailFolder;
|
||||
unset($oMailFolder);
|
||||
}
|
||||
unset($aUnsortedMailFolders);
|
||||
|
||||
$aAddedFolders = array();
|
||||
foreach ($aSortedByLenImapFolders as /* @var $oMailFolder \MailSo\Mail\Folder */ $oMailFolder)
|
||||
{
|
||||
$sDelimiter = $oMailFolder->Delimiter();
|
||||
$aFolderExplode = \explode($sDelimiter, $oMailFolder->FullNameRaw());
|
||||
|
||||
if (1 < \count($aFolderExplode))
|
||||
{
|
||||
\array_pop($aFolderExplode);
|
||||
|
||||
$sNonExistenFolderFullNameRaw = '';
|
||||
foreach ($aFolderExplode as $sFolderExplodeItem)
|
||||
{
|
||||
$sNonExistenFolderFullNameRaw .= (0 < \strlen($sNonExistenFolderFullNameRaw))
|
||||
? $sDelimiter.$sFolderExplodeItem : $sFolderExplodeItem;
|
||||
|
||||
if (!isset($aSortedByLenImapFolders[$sNonExistenFolderFullNameRaw]))
|
||||
{
|
||||
$aAddedFolders[$sNonExistenFolderFullNameRaw] =
|
||||
Folder::NewNonExistenInstance($sNonExistenFolderFullNameRaw, $sDelimiter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$aSortedByLenImapFolders = \array_merge($aSortedByLenImapFolders, $aAddedFolders);
|
||||
unset($aAddedFolders);
|
||||
|
||||
\uasort($aSortedByLenImapFolders, function ($oFolderA, $oFolderB) {
|
||||
return \strnatcmp($oFolderA->FullNameRaw(), $oFolderB->FullNameRaw());
|
||||
});
|
||||
|
||||
foreach ($aSortedByLenImapFolders as /* @var $oMailFolder \MailSo\Mail\Folder */ &$oMailFolder)
|
||||
{
|
||||
$this->AddWithPositionSearch($oMailFolder);
|
||||
unset($oMailFolder);
|
||||
}
|
||||
|
||||
unset($aSortedByLenImapFolders);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \MailSo\Mail\Folder $oMailFolder
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function AddWithPositionSearch($oMailFolder)
|
||||
{
|
||||
$oItemFolder = null;
|
||||
$bIsAdded = false;
|
||||
$aList =& $this->GetAsArray();
|
||||
|
||||
foreach ($aList as /* @var $oItemFolder \MailSo\Mail\Folder */ $oItemFolder)
|
||||
{
|
||||
if ($oMailFolder instanceof \MailSo\Mail\Folder &&
|
||||
0 === \strpos($oMailFolder->FullNameRaw(), $oItemFolder->FullNameRaw().$oItemFolder->Delimiter()))
|
||||
{
|
||||
if ($oItemFolder->SubFolders(true)->AddWithPositionSearch($oMailFolder))
|
||||
{
|
||||
$bIsAdded = true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$bIsAdded && $oMailFolder instanceof \MailSo\Mail\Folder)
|
||||
{
|
||||
$bIsAdded = true;
|
||||
$this->Add($oMailFolder);
|
||||
}
|
||||
|
||||
return $bIsAdded;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param callable $fCallback
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function SortByCallback($fCallback)
|
||||
{
|
||||
if (\is_callable($fCallback))
|
||||
{
|
||||
$aList =& $this->GetAsArray();
|
||||
|
||||
\usort($aList, $fCallback);
|
||||
|
||||
foreach ($aList as &$oItemFolder)
|
||||
{
|
||||
if ($oItemFolder->HasSubFolders())
|
||||
{
|
||||
$oItemFolder->SubFolders()->SortByCallback($fCallback);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -1,897 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Mail;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Mail
|
||||
*/
|
||||
class Message
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sFolder;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $iUid;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sSubject;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sMessageId;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sContentType;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $iSize;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $iInternalTimeStampInUTC;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $iHeaderTimeStampInUTC;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sHeaderDate;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $aFlags;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $aFlagsLowerCase;
|
||||
|
||||
/**
|
||||
* @var \MailSo\Mime\EmailCollection
|
||||
*/
|
||||
private $oFrom;
|
||||
|
||||
/**
|
||||
* @var \MailSo\Mime\EmailCollection
|
||||
*/
|
||||
private $oSender;
|
||||
|
||||
/**
|
||||
* @var \MailSo\Mime\EmailCollection
|
||||
*/
|
||||
private $oReplyTo;
|
||||
|
||||
/**
|
||||
* @var \MailSo\Mime\EmailCollection
|
||||
*/
|
||||
private $oDeliveredTo;
|
||||
|
||||
/**
|
||||
* @var \MailSo\Mime\EmailCollection
|
||||
*/
|
||||
private $oTo;
|
||||
|
||||
/**
|
||||
* @var \MailSo\Mime\EmailCollection
|
||||
*/
|
||||
private $oCc;
|
||||
|
||||
/**
|
||||
* @var \MailSo\Mime\EmailCollection
|
||||
*/
|
||||
private $oBcc;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sInReplyTo;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sPlain;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sHtml;
|
||||
|
||||
/**
|
||||
* @var \MailSo\Mail\AttachmentCollection
|
||||
*/
|
||||
private $oAttachments;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $aDraftInfo;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sReferences;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $iSensitivity;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $iPriority;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sDeliveryReceipt;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sReadReceipt;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $aThreads;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $iParentThread;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $iThreadsLen;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $bTextPartIsTrimmed;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sPgpSignature;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $bPgpSigned;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $bPgpEncrypted;
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*/
|
||||
private function __construct()
|
||||
{
|
||||
$this->Clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \MailSo\Mail\Message
|
||||
*/
|
||||
public function Clear()
|
||||
{
|
||||
$this->sFolder = '';
|
||||
$this->iUid = 0;
|
||||
$this->sSubject = '';
|
||||
$this->sMessageId = '';
|
||||
$this->sContentType = '';
|
||||
$this->iSize = 0;
|
||||
$this->iInternalTimeStampInUTC = 0;
|
||||
$this->iHeaderTimeStampInUTC = 0;
|
||||
$this->sHeaderDate = '';
|
||||
$this->aFlags = array();
|
||||
$this->aFlagsLowerCase = array();
|
||||
|
||||
$this->oFrom = null;
|
||||
$this->oSender = null;
|
||||
$this->oReplyTo = null;
|
||||
$this->oDeliveredTo = null;
|
||||
$this->oTo = null;
|
||||
$this->oCc = null;
|
||||
$this->oBcc = null;
|
||||
|
||||
$this->sPlain = '';
|
||||
$this->sHtml = '';
|
||||
|
||||
$this->oAttachments = null;
|
||||
$this->aDraftInfo = null;
|
||||
|
||||
$this->sInReplyTo = '';
|
||||
$this->sReferences = '';
|
||||
|
||||
$this->iSensitivity = \MailSo\Mime\Enumerations\Sensitivity::NOTHING;
|
||||
$this->iPriority = \MailSo\Mime\Enumerations\MessagePriority::NORMAL;
|
||||
$this->sDeliveryReceipt = '';
|
||||
$this->sReadReceipt = '';
|
||||
|
||||
$this->aThreads = array();
|
||||
$this->iThreadsLen = 0;
|
||||
$this->iParentThread = 0;
|
||||
|
||||
$this->bTextPartIsTrimmed = false;
|
||||
|
||||
$this->sPgpSignature = '';
|
||||
$this->bPgpSigned = false;
|
||||
$this->bPgpEncrypted = false;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \MailSo\Mail\Message
|
||||
*/
|
||||
public static function NewInstance()
|
||||
{
|
||||
return new self();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Plain()
|
||||
{
|
||||
return $this->sPlain;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Html()
|
||||
{
|
||||
return $this->sHtml;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function PgpSignature()
|
||||
{
|
||||
return $this->sPgpSignature;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function PgpSigned()
|
||||
{
|
||||
return $this->bPgpSigned;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function PgpEncrypted()
|
||||
{
|
||||
return $this->bPgpEncrypted;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sHtml
|
||||
*
|
||||
* @retun void
|
||||
*/
|
||||
public function SetHtml($sHtml)
|
||||
{
|
||||
$this->sHtml = $sHtml;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Folder()
|
||||
{
|
||||
return $this->sFolder;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function Uid()
|
||||
{
|
||||
return $this->iUid;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function MessageId()
|
||||
{
|
||||
return $this->sMessageId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Subject()
|
||||
{
|
||||
return $this->sSubject;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function ContentType()
|
||||
{
|
||||
return $this->sContentType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function Size()
|
||||
{
|
||||
return $this->iSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function InternalTimeStampInUTC()
|
||||
{
|
||||
return $this->iInternalTimeStampInUTC;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function HeaderTimeStampInUTC()
|
||||
{
|
||||
return $this->iHeaderTimeStampInUTC;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function HeaderDate()
|
||||
{
|
||||
return $this->sHeaderDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function Flags()
|
||||
{
|
||||
return $this->aFlags;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function FlagsLowerCase()
|
||||
{
|
||||
return $this->aFlagsLowerCase;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \MailSo\Mime\EmailCollection
|
||||
*/
|
||||
public function From()
|
||||
{
|
||||
return $this->oFrom;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function Sensitivity()
|
||||
{
|
||||
return $this->iSensitivity;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function Priority()
|
||||
{
|
||||
return $this->iPriority;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \MailSo\Mime\EmailCollection
|
||||
*/
|
||||
public function Sender()
|
||||
{
|
||||
return $this->oSender;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \MailSo\Mime\EmailCollection
|
||||
*/
|
||||
public function ReplyTo()
|
||||
{
|
||||
return $this->oReplyTo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \MailSo\Mime\EmailCollection
|
||||
*/
|
||||
public function DeliveredTo()
|
||||
{
|
||||
return $this->oDeliveredTo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \MailSo\Mime\EmailCollection
|
||||
*/
|
||||
public function To()
|
||||
{
|
||||
return $this->oTo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \MailSo\Mime\EmailCollection
|
||||
*/
|
||||
public function Cc()
|
||||
{
|
||||
return $this->oCc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \MailSo\Mime\EmailCollection
|
||||
*/
|
||||
public function Bcc()
|
||||
{
|
||||
return $this->oBcc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \MailSo\Mail\AttachmentCollection
|
||||
*/
|
||||
public function Attachments()
|
||||
{
|
||||
return $this->oAttachments;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function InReplyTo()
|
||||
{
|
||||
return $this->sInReplyTo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function References()
|
||||
{
|
||||
return $this->sReferences;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function DeliveryReceipt()
|
||||
{
|
||||
return $this->sDeliveryReceipt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function ReadReceipt()
|
||||
{
|
||||
return $this->sReadReceipt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function ReadingConfirmation()
|
||||
{
|
||||
return $this->ReadReceipt();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array | null
|
||||
*/
|
||||
public function DraftInfo()
|
||||
{
|
||||
return $this->aDraftInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function Threads()
|
||||
{
|
||||
return $this->aThreads;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $aThreads
|
||||
*/
|
||||
public function SetThreads($aThreads)
|
||||
{
|
||||
$this->aThreads = \is_array($aThreads) ? $aThreads : array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function ThreadsLen()
|
||||
{
|
||||
return $this->iThreadsLen;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iThreadsLen
|
||||
*/
|
||||
public function SetThreadsLen($iThreadsLen)
|
||||
{
|
||||
$this->iThreadsLen = $iThreadsLen;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function ParentThread()
|
||||
{
|
||||
return $this->iParentThread;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iParentThread
|
||||
*/
|
||||
public function SetParentThread($iParentThread)
|
||||
{
|
||||
$this->iParentThread = $iParentThread;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boole
|
||||
*/
|
||||
public function TextPartIsTrimmed()
|
||||
{
|
||||
return $this->bTextPartIsTrimmed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sFolder
|
||||
* @param \MailSo\Imap\FetchResponse $oFetchResponse
|
||||
* @param \MailSo\Imap\BodyStructure $oBodyStructure = null
|
||||
*
|
||||
* @return \MailSo\Mail\Message
|
||||
*/
|
||||
public static function NewFetchResponseInstance($sFolder, $oFetchResponse, $oBodyStructure = null)
|
||||
{
|
||||
return self::NewInstance()->InitByFetchResponse($sFolder, $oFetchResponse, $oBodyStructure);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sFolder
|
||||
* @param \MailSo\Imap\FetchResponse $oFetchResponse
|
||||
* @param \MailSo\Imap\BodyStructure $oBodyStructure = null
|
||||
*
|
||||
* @return \MailSo\Mail\Message
|
||||
*/
|
||||
public function InitByFetchResponse($sFolder, $oFetchResponse, $oBodyStructure = null)
|
||||
{
|
||||
if (!$oBodyStructure)
|
||||
{
|
||||
$oBodyStructure = $oFetchResponse->GetFetchBodyStructure();
|
||||
}
|
||||
|
||||
$sUid = $oFetchResponse->GetFetchValue(\MailSo\Imap\Enumerations\FetchType::UID);
|
||||
$sSize = $oFetchResponse->GetFetchValue(\MailSo\Imap\Enumerations\FetchType::RFC822_SIZE);
|
||||
$sInternalDate = $oFetchResponse->GetFetchValue(\MailSo\Imap\Enumerations\FetchType::INTERNALDATE);
|
||||
$aFlags = $oFetchResponse->GetFetchValue(\MailSo\Imap\Enumerations\FetchType::FLAGS);
|
||||
|
||||
$this->sFolder = $sFolder;
|
||||
$this->iUid = \is_numeric($sUid) ? (int) $sUid : 0;
|
||||
$this->iSize = \is_numeric($sSize) ? (int) $sSize : 0;
|
||||
$this->aFlags = \is_array($aFlags) ? $aFlags : array();
|
||||
$this->aFlagsLowerCase = \array_map('strtolower', $this->aFlags);
|
||||
|
||||
$this->iInternalTimeStampInUTC =
|
||||
\MailSo\Base\DateTimeHelper::ParseInternalDateString($sInternalDate);
|
||||
|
||||
$sCharset = $oBodyStructure ? $oBodyStructure->SearchCharset() : '';
|
||||
$sCharset = \MailSo\Base\Utils::NormalizeCharset($sCharset);
|
||||
|
||||
$sHeaders = $oFetchResponse->GetHeaderFieldsValue();
|
||||
if (0 < \strlen($sHeaders))
|
||||
{
|
||||
$oHeaders = \MailSo\Mime\HeaderCollection::NewInstance()->Parse($sHeaders, false, $sCharset);
|
||||
|
||||
$sContentTypeCharset = $oHeaders->ParameterValue(
|
||||
\MailSo\Mime\Enumerations\Header::CONTENT_TYPE,
|
||||
\MailSo\Mime\Enumerations\Parameter::CHARSET
|
||||
);
|
||||
|
||||
if (0 < \strlen($sContentTypeCharset))
|
||||
{
|
||||
$sCharset = $sContentTypeCharset;
|
||||
$sCharset = \MailSo\Base\Utils::NormalizeCharset($sCharset);
|
||||
}
|
||||
|
||||
if (0 < \strlen($sCharset))
|
||||
{
|
||||
$oHeaders->SetParentCharset($sCharset);
|
||||
}
|
||||
|
||||
$bCharsetAutoDetect = 0 === \strlen($sCharset);
|
||||
|
||||
$this->sSubject = $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::SUBJECT, $bCharsetAutoDetect);
|
||||
$this->sMessageId = $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::MESSAGE_ID);
|
||||
$this->sContentType = $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::CONTENT_TYPE);
|
||||
|
||||
$this->oFrom = $oHeaders->GetAsEmailCollection(\MailSo\Mime\Enumerations\Header::FROM_, $bCharsetAutoDetect);
|
||||
$this->oTo = $oHeaders->GetAsEmailCollection(\MailSo\Mime\Enumerations\Header::TO_, $bCharsetAutoDetect);
|
||||
$this->oCc = $oHeaders->GetAsEmailCollection(\MailSo\Mime\Enumerations\Header::CC, $bCharsetAutoDetect);
|
||||
$this->oBcc = $oHeaders->GetAsEmailCollection(\MailSo\Mime\Enumerations\Header::BCC, $bCharsetAutoDetect);
|
||||
|
||||
$oHeaders->PopulateEmailColectionByDkim($this->oFrom);
|
||||
|
||||
$this->oSender = $oHeaders->GetAsEmailCollection(\MailSo\Mime\Enumerations\Header::SENDER, $bCharsetAutoDetect);
|
||||
$this->oReplyTo = $oHeaders->GetAsEmailCollection(\MailSo\Mime\Enumerations\Header::REPLY_TO, $bCharsetAutoDetect);
|
||||
$this->oDeliveredTo = $oHeaders->GetAsEmailCollection(\MailSo\Mime\Enumerations\Header::DELIVERED_TO, $bCharsetAutoDetect);
|
||||
|
||||
$this->sInReplyTo = $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::IN_REPLY_TO);
|
||||
$this->sReferences = $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::REFERENCES);
|
||||
|
||||
$sHeaderDate = $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::DATE);
|
||||
$this->sHeaderDate = $sHeaderDate;
|
||||
$this->iHeaderTimeStampInUTC = \MailSo\Base\DateTimeHelper::ParseRFC2822DateString($sHeaderDate);
|
||||
|
||||
// Sensitivity
|
||||
$this->iSensitivity = \MailSo\Mime\Enumerations\Sensitivity::NOTHING;
|
||||
$sSensitivity = $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::SENSITIVITY);
|
||||
switch (\strtolower($sSensitivity))
|
||||
{
|
||||
case 'personal':
|
||||
$this->iSensitivity = \MailSo\Mime\Enumerations\Sensitivity::PERSONAL;
|
||||
break;
|
||||
case 'private':
|
||||
$this->iSensitivity = \MailSo\Mime\Enumerations\Sensitivity::PRIVATE_;
|
||||
break;
|
||||
case 'company-confidential':
|
||||
$this->iSensitivity = \MailSo\Mime\Enumerations\Sensitivity::CONFIDENTIAL;
|
||||
break;
|
||||
}
|
||||
|
||||
// Priority
|
||||
$this->iPriority = \MailSo\Mime\Enumerations\MessagePriority::NORMAL;
|
||||
$sPriority = $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::X_MSMAIL_PRIORITY);
|
||||
if (0 === \strlen($sPriority))
|
||||
{
|
||||
$sPriority = $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::IMPORTANCE);
|
||||
}
|
||||
if (0 === \strlen($sPriority))
|
||||
{
|
||||
$sPriority = $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::X_PRIORITY);
|
||||
}
|
||||
if (0 < \strlen($sPriority))
|
||||
{
|
||||
switch (\str_replace(' ', '', \strtolower($sPriority)))
|
||||
{
|
||||
case 'high':
|
||||
case '1(highest)':
|
||||
case '2(high)':
|
||||
case '1':
|
||||
case '2':
|
||||
$this->iPriority = \MailSo\Mime\Enumerations\MessagePriority::HIGH;
|
||||
break;
|
||||
|
||||
case 'low':
|
||||
case '4(low)':
|
||||
case '5(lowest)':
|
||||
case '4':
|
||||
case '5':
|
||||
$this->iPriority = \MailSo\Mime\Enumerations\MessagePriority::LOW;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Delivery Receipt
|
||||
$this->sDeliveryReceipt = \trim($oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::RETURN_RECEIPT_TO));
|
||||
|
||||
// Read Receipt
|
||||
$this->sReadReceipt = \trim($oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::DISPOSITION_NOTIFICATION_TO));
|
||||
if (empty($this->sReadReceipt))
|
||||
{
|
||||
$this->sReadReceipt = \trim($oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::X_CONFIRM_READING_TO));
|
||||
}
|
||||
|
||||
$sDraftInfo = $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::X_DRAFT_INFO);
|
||||
if (0 < \strlen($sDraftInfo))
|
||||
{
|
||||
$sType = '';
|
||||
$sFolder = '';
|
||||
$sUid = '';
|
||||
|
||||
\MailSo\Mime\ParameterCollection::NewInstance($sDraftInfo)
|
||||
->ForeachList(function ($oParameter) use (&$sType, &$sFolder, &$sUid) {
|
||||
|
||||
switch (\strtolower($oParameter->Name()))
|
||||
{
|
||||
case 'type':
|
||||
$sType = $oParameter->Value();
|
||||
break;
|
||||
case 'uid':
|
||||
$sUid = $oParameter->Value();
|
||||
break;
|
||||
case 'folder':
|
||||
$sFolder = \base64_decode($oParameter->Value());
|
||||
break;
|
||||
}
|
||||
})
|
||||
;
|
||||
|
||||
if (0 < \strlen($sType) && 0 < \strlen($sFolder) && 0 < \strlen($sUid))
|
||||
{
|
||||
$this->aDraftInfo = array($sType, $sUid, $sFolder);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ($oFetchResponse->GetEnvelope())
|
||||
{
|
||||
if (0 === \strlen($sCharset) && $oBodyStructure)
|
||||
{
|
||||
$sCharset = $oBodyStructure->SearchCharset();
|
||||
$sCharset = \MailSo\Base\Utils::NormalizeCharset($sCharset);
|
||||
}
|
||||
|
||||
if (0 === \strlen($sCharset))
|
||||
{
|
||||
$sCharset = \MailSo\Base\Enumerations\Charset::ISO_8859_1;
|
||||
}
|
||||
|
||||
// date, subject, from, sender, reply-to, to, cc, bcc, in-reply-to, message-id
|
||||
$this->sMessageId = $oFetchResponse->GetFetchEnvelopeValue(9, '');
|
||||
$this->sSubject = \MailSo\Base\Utils::DecodeHeaderValue($oFetchResponse->GetFetchEnvelopeValue(1, ''), $sCharset);
|
||||
|
||||
$this->oFrom = $oFetchResponse->GetFetchEnvelopeEmailCollection(2, $sCharset);
|
||||
$this->oSender = $oFetchResponse->GetFetchEnvelopeEmailCollection(3, $sCharset);
|
||||
$this->oReplyTo = $oFetchResponse->GetFetchEnvelopeEmailCollection(4, $sCharset);
|
||||
$this->oTo = $oFetchResponse->GetFetchEnvelopeEmailCollection(5, $sCharset);
|
||||
$this->oCc = $oFetchResponse->GetFetchEnvelopeEmailCollection(6, $sCharset);
|
||||
$this->oBcc = $oFetchResponse->GetFetchEnvelopeEmailCollection(7, $sCharset);
|
||||
$this->sInReplyTo = $oFetchResponse->GetFetchEnvelopeValue(8, '');
|
||||
}
|
||||
|
||||
$aTextParts = $oBodyStructure ? $oBodyStructure->SearchHtmlOrPlainParts() : null;
|
||||
if (\is_array($aTextParts) && 0 < \count($aTextParts))
|
||||
{
|
||||
if (0 === \strlen($sCharset))
|
||||
{
|
||||
$sCharset = \MailSo\Base\Enumerations\Charset::UTF_8;
|
||||
}
|
||||
|
||||
$sHtmlParts = array();
|
||||
$sPlainParts = array();
|
||||
|
||||
foreach ($aTextParts as $oPart)
|
||||
{
|
||||
$sText = $oFetchResponse->GetFetchValue(\MailSo\Imap\Enumerations\FetchType::BODY.'['.$oPart->PartID().']');
|
||||
if (null === $sText)
|
||||
{
|
||||
$sText = $oFetchResponse->GetFetchValue(\MailSo\Imap\Enumerations\FetchType::BODY.'['.$oPart->PartID().']<0>');
|
||||
if (\is_string($sText) && 0 < \strlen($sText))
|
||||
{
|
||||
$this->bTextPartIsTrimmed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (\is_string($sText) && 0 < \strlen($sText))
|
||||
{
|
||||
$sTextCharset = $oPart->Charset();
|
||||
if (empty($sTextCharset))
|
||||
{
|
||||
$sTextCharset = $sCharset;
|
||||
}
|
||||
|
||||
$sTextCharset = \MailSo\Base\Utils::NormalizeCharset($sTextCharset, true);
|
||||
|
||||
$sText = \MailSo\Base\Utils::DecodeEncodingValue($sText, $oPart->MailEncodingName());
|
||||
$sText = \MailSo\Base\Utils::ConvertEncoding($sText, $sTextCharset, \MailSo\Base\Enumerations\Charset::UTF_8);
|
||||
$sText = \MailSo\Base\Utils::Utf8Clear($sText);
|
||||
|
||||
if ('text/html' === $oPart->ContentType())
|
||||
{
|
||||
$sHtmlParts[] = $sText;
|
||||
}
|
||||
else
|
||||
{
|
||||
$sPlainParts[] = $sText;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (0 < \count($sHtmlParts))
|
||||
{
|
||||
$this->sHtml = \implode('<br />', $sHtmlParts);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->sPlain = \trim(\implode("\n", $sPlainParts));
|
||||
}
|
||||
|
||||
$aMatch = array();
|
||||
if (\preg_match('/-----BEGIN PGP SIGNATURE-----(.+)-----END PGP SIGNATURE-----/ism', $this->sPlain, $aMatch) && !empty($aMatch[0]))
|
||||
{
|
||||
$this->sPgpSignature = \trim($aMatch[0]);
|
||||
$this->bPgpSigned = true;
|
||||
}
|
||||
|
||||
$aMatch = array();
|
||||
if (\preg_match('/-----BEGIN PGP MESSAGE-----/ism', $this->sPlain, $aMatch) && !empty($aMatch[0]))
|
||||
{
|
||||
$this->bPgpEncrypted = true;
|
||||
}
|
||||
|
||||
unset($sHtmlParts, $sPlainParts, $aMatch);
|
||||
}
|
||||
|
||||
// if (empty($this->sPgpSignature) && 'multipart/signed' === \strtolower($this->sContentType) &&
|
||||
// 'application/pgp-signature' === \strtolower($oHeaders->ParameterValue(
|
||||
// \MailSo\Mime\Enumerations\Header::CONTENT_TYPE,
|
||||
// \MailSo\Mime\Enumerations\Parameter::PROTOCOL
|
||||
// )))
|
||||
// {
|
||||
// $aPgpSignatureParts = $oBodyStructure ? $oBodyStructure->SearchByContentType('application/pgp-signature') : null;
|
||||
// if (\is_array($aPgpSignatureParts) && 0 < \count($aPgpSignatureParts) && isset($aPgpSignatureParts[0]))
|
||||
// {
|
||||
// $sPgpSignatureText = $oFetchResponse->GetFetchValue(\MailSo\Imap\Enumerations\FetchType::BODY.'['.$aPgpSignatureParts[0]->PartID().']');
|
||||
// if (\is_string($sPgpSignatureText) && 0 < \strlen($sPgpSignatureText) && 0 < \strpos($sPgpSignatureText, 'BEGIN PGP SIGNATURE'))
|
||||
// {
|
||||
// $this->sPgpSignature = \trim($sPgpSignatureText);
|
||||
// $this->bPgpSigned = true;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
if ($oBodyStructure)
|
||||
{
|
||||
$aAttachmentsParts = $oBodyStructure->SearchAttachmentsParts();
|
||||
if ($aAttachmentsParts && 0 < count($aAttachmentsParts))
|
||||
{
|
||||
$this->oAttachments = AttachmentCollection::NewInstance();
|
||||
foreach ($aAttachmentsParts as /* @var $oAttachmentItem \MailSo\Imap\BodyStructure */ $oAttachmentItem)
|
||||
{
|
||||
$this->oAttachments->Add(
|
||||
\MailSo\Mail\Attachment::NewBodyStructureInstance($this->sFolder, $this->iUid, $oAttachmentItem)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
|
@ -1,117 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Mail;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Mail
|
||||
*/
|
||||
class MessageCollection extends \MailSo\Base\Collection
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $FolderHash;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $MessageCount;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $MessageUnseenCount;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $MessageResultCount;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $FolderName;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $Offset;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $Limit;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $Search;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $UidNext;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $NewMessages;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $LastCollapsedThreadUids;
|
||||
|
||||
/**
|
||||
* @access protected
|
||||
*/
|
||||
protected function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->Clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \MailSo\Mail\MessageCollection
|
||||
*/
|
||||
public static function NewInstance()
|
||||
{
|
||||
return new self();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \MailSo\Mail\MessageCollection
|
||||
*/
|
||||
public function Clear()
|
||||
{
|
||||
parent::Clear();
|
||||
|
||||
$this->FolderHash = '';
|
||||
|
||||
$this->MessageCount = 0;
|
||||
$this->MessageUnseenCount = 0;
|
||||
$this->MessageResultCount = 0;
|
||||
|
||||
$this->FolderName = '';
|
||||
$this->Offset = 0;
|
||||
$this->Limit = 0;
|
||||
$this->Search = '';
|
||||
$this->UidNext = '';
|
||||
$this->NewMessages = array();
|
||||
|
||||
$this->LastCollapsedThreadUids = array();
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo;
|
||||
|
||||
if (!\defined('MAILSO_LIBRARY_ROOT_PATH'))
|
||||
{
|
||||
\define('MAILSO_LIBRARY_ROOT_PATH', \defined('MAILSO_LIBRARY_USE_PHAR')
|
||||
? 'phar://mailso.phar/' : \rtrim(\realpath(__DIR__), '\\/').'/');
|
||||
|
||||
/**
|
||||
* @param string $sClassName
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
function MailSoSplAutoloadRegisterFunction($sClassName)
|
||||
{
|
||||
return (0 === \strpos($sClassName, 'MailSo') && false !== \strpos($sClassName, '\\')) ?
|
||||
include MAILSO_LIBRARY_ROOT_PATH.\str_replace('\\', '/', \substr($sClassName, 7)).'.php' : false;
|
||||
}
|
||||
|
||||
\spl_autoload_register('MailSo\MailSoSplAutoloadRegisterFunction', false);
|
||||
|
||||
if (\class_exists('MailSo\Base\Loader'))
|
||||
{
|
||||
\MailSo\Base\Loader::Init();
|
||||
}
|
||||
else
|
||||
{
|
||||
\spl_autoload_unregister('MailSo\MailSoSplAutoloadRegisterFunction');
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue