added php download of membershipments
This commit is contained in:
90
vendor/webklex/php-imap/src/Address.php
vendored
Normal file
90
vendor/webklex/php-imap/src/Address.php
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
/*
|
||||
* File: Address.php
|
||||
* Category: -
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 01.01.21 21:17
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP;
|
||||
|
||||
/**
|
||||
* Class Address
|
||||
*
|
||||
* @package Webklex\PHPIMAP
|
||||
*/
|
||||
class Address {
|
||||
|
||||
/**
|
||||
* Address attributes
|
||||
* @var string $personal
|
||||
* @var string $mailbox
|
||||
* @var string $host
|
||||
* @var string $mail
|
||||
* @var string $full
|
||||
*/
|
||||
public $personal = "";
|
||||
public $mailbox = "";
|
||||
public $host = "";
|
||||
public $mail = "";
|
||||
public $full = "";
|
||||
|
||||
/**
|
||||
* Address constructor.
|
||||
* @param object $object
|
||||
*/
|
||||
public function __construct($object) {
|
||||
if (property_exists($object, "personal")){ $this->personal = $object->personal; }
|
||||
if (property_exists($object, "mailbox")){ $this->mailbox = $object->mailbox; }
|
||||
if (property_exists($object, "host")){ $this->host = $object->host; }
|
||||
if (property_exists($object, "mail")){ $this->mail = $object->mail; }
|
||||
if (property_exists($object, "full")){ $this->full = $object->full; }
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the stringified address
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString() {
|
||||
return $this->full ?: "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the serialized address
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function __serialize(){
|
||||
return [
|
||||
"personal" => $this->personal,
|
||||
"mailbox" => $this->mailbox,
|
||||
"host" => $this->host,
|
||||
"mail" => $this->mail,
|
||||
"full" => $this->full,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert instance to array
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray(): array {
|
||||
return $this->__serialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the stringified attribute
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function toString(): string {
|
||||
return $this->__toString();
|
||||
}
|
||||
}
|
||||
353
vendor/webklex/php-imap/src/Attachment.php
vendored
Executable file
353
vendor/webklex/php-imap/src/Attachment.php
vendored
Executable file
@@ -0,0 +1,353 @@
|
||||
<?php
|
||||
/*
|
||||
* File: Attachment.php
|
||||
* Category: -
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 16.03.18 19:37
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP;
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
use Webklex\PHPIMAP\Exceptions\MaskNotFoundException;
|
||||
use Webklex\PHPIMAP\Exceptions\MethodNotFoundException;
|
||||
use Webklex\PHPIMAP\Support\Masks\AttachmentMask;
|
||||
|
||||
/**
|
||||
* Class Attachment
|
||||
*
|
||||
* @package Webklex\PHPIMAP
|
||||
*
|
||||
* @property integer part_number
|
||||
* @property integer size
|
||||
* @property string content
|
||||
* @property string type
|
||||
* @property string content_type
|
||||
* @property string id
|
||||
* @property string name
|
||||
* @property string disposition
|
||||
* @property string img_src
|
||||
*
|
||||
* @method integer getPartNumber()
|
||||
* @method integer setPartNumber(integer $part_number)
|
||||
* @method string getContent()
|
||||
* @method string setContent(string $content)
|
||||
* @method string getType()
|
||||
* @method string setType(string $type)
|
||||
* @method string getContentType()
|
||||
* @method string setContentType(string $content_type)
|
||||
* @method string getId()
|
||||
* @method string setId(string $id)
|
||||
* @method string getSize()
|
||||
* @method string setSize(integer $size)
|
||||
* @method string getName()
|
||||
* @method string getDisposition()
|
||||
* @method string setDisposition(string $disposition)
|
||||
* @method string setImgSrc(string $img_src)
|
||||
*/
|
||||
class Attachment {
|
||||
|
||||
/**
|
||||
* @var Message $oMessage
|
||||
*/
|
||||
protected $oMessage;
|
||||
|
||||
/**
|
||||
* Used config
|
||||
*
|
||||
* @var array $config
|
||||
*/
|
||||
protected $config = [];
|
||||
|
||||
/** @var Part $part */
|
||||
protected $part;
|
||||
|
||||
/**
|
||||
* Attribute holder
|
||||
*
|
||||
* @var array $attributes
|
||||
*/
|
||||
protected $attributes = [
|
||||
'content' => null,
|
||||
'type' => null,
|
||||
'part_number' => 0,
|
||||
'content_type' => null,
|
||||
'id' => null,
|
||||
'name' => null,
|
||||
'disposition' => null,
|
||||
'img_src' => null,
|
||||
'size' => null,
|
||||
];
|
||||
|
||||
/**
|
||||
* Default mask
|
||||
*
|
||||
* @var string $mask
|
||||
*/
|
||||
protected $mask = AttachmentMask::class;
|
||||
|
||||
/**
|
||||
* Attachment constructor.
|
||||
* @param Message $oMessage
|
||||
* @param Part $part
|
||||
*/
|
||||
public function __construct(Message $oMessage, Part $part) {
|
||||
$this->config = ClientManager::get('options');
|
||||
|
||||
$this->oMessage = $oMessage;
|
||||
$this->part = $part;
|
||||
$this->part_number = $part->part_number;
|
||||
|
||||
$default_mask = $this->oMessage->getClient()->getDefaultAttachmentMask();
|
||||
if($default_mask != null) {
|
||||
$this->mask = $default_mask;
|
||||
}
|
||||
|
||||
$this->findType();
|
||||
$this->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* Call dynamic attribute setter and getter methods
|
||||
* @param string $method
|
||||
* @param array $arguments
|
||||
*
|
||||
* @return mixed
|
||||
* @throws MethodNotFoundException
|
||||
*/
|
||||
public function __call(string $method, array $arguments) {
|
||||
if(strtolower(substr($method, 0, 3)) === 'get') {
|
||||
$name = Str::snake(substr($method, 3));
|
||||
|
||||
if(isset($this->attributes[$name])) {
|
||||
return $this->attributes[$name];
|
||||
}
|
||||
|
||||
return null;
|
||||
}elseif (strtolower(substr($method, 0, 3)) === 'set') {
|
||||
$name = Str::snake(substr($method, 3));
|
||||
|
||||
$this->attributes[$name] = array_pop($arguments);
|
||||
|
||||
return $this->attributes[$name];
|
||||
}
|
||||
|
||||
throw new MethodNotFoundException("Method ".self::class.'::'.$method.'() is not supported');
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic setter
|
||||
* @param $name
|
||||
* @param $value
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function __set($name, $value) {
|
||||
$this->attributes[$name] = $value;
|
||||
|
||||
return $this->attributes[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* magic getter
|
||||
* @param $name
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function __get($name) {
|
||||
if(isset($this->attributes[$name])) {
|
||||
return $this->attributes[$name];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the structure type
|
||||
*/
|
||||
protected function findType() {
|
||||
switch ($this->part->type) {
|
||||
case IMAP::ATTACHMENT_TYPE_MESSAGE:
|
||||
$this->type = 'message';
|
||||
break;
|
||||
case IMAP::ATTACHMENT_TYPE_APPLICATION:
|
||||
$this->type = 'application';
|
||||
break;
|
||||
case IMAP::ATTACHMENT_TYPE_AUDIO:
|
||||
$this->type = 'audio';
|
||||
break;
|
||||
case IMAP::ATTACHMENT_TYPE_IMAGE:
|
||||
$this->type = 'image';
|
||||
break;
|
||||
case IMAP::ATTACHMENT_TYPE_VIDEO:
|
||||
$this->type = 'video';
|
||||
break;
|
||||
case IMAP::ATTACHMENT_TYPE_MODEL:
|
||||
$this->type = 'model';
|
||||
break;
|
||||
case IMAP::ATTACHMENT_TYPE_TEXT:
|
||||
$this->type = 'text';
|
||||
break;
|
||||
case IMAP::ATTACHMENT_TYPE_MULTIPART:
|
||||
$this->type = 'multipart';
|
||||
break;
|
||||
default:
|
||||
$this->type = 'other';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the given attachment
|
||||
*/
|
||||
protected function fetch() {
|
||||
|
||||
$content = $this->part->content;
|
||||
|
||||
$this->content_type = $this->part->content_type;
|
||||
$this->content = $this->oMessage->decodeString($content, $this->part->encoding);
|
||||
|
||||
if (($id = $this->part->id) !== null) {
|
||||
$this->id = str_replace(['<', '>'], '', $id);
|
||||
}else{
|
||||
$this->id = hash("sha256", (string)microtime(true));
|
||||
}
|
||||
|
||||
$this->size = $this->part->bytes;
|
||||
$this->disposition = $this->part->disposition;
|
||||
|
||||
if (($filename = $this->part->filename) !== null) {
|
||||
$this->setName($filename);
|
||||
} elseif (($name = $this->part->name) !== null) {
|
||||
$this->setName($name);
|
||||
}else {
|
||||
$this->setName("undefined");
|
||||
}
|
||||
|
||||
if (IMAP::ATTACHMENT_TYPE_MESSAGE == $this->part->type) {
|
||||
if ($this->part->ifdescription) {
|
||||
$this->setName($this->part->description);
|
||||
} else {
|
||||
$this->setName($this->part->subtype);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the attachment content to your filesystem
|
||||
* @param string $path
|
||||
* @param string|null $filename
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function save(string $path, $filename = null): bool {
|
||||
$filename = $filename ?: $this->getName();
|
||||
|
||||
return file_put_contents($path.$filename, $this->getContent()) !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the attachment name and try to decode it
|
||||
* @param $name
|
||||
*/
|
||||
public function setName($name) {
|
||||
$decoder = $this->config['decoder']['attachment'];
|
||||
if ($name !== null) {
|
||||
if($decoder === 'utf-8' && extension_loaded('imap')) {
|
||||
$this->name = \imap_utf8($name);
|
||||
}else{
|
||||
$this->name = mb_decode_mimeheader($name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attachment mime type
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getMimeType(){
|
||||
return (new \finfo())->buffer($this->getContent(), FILEINFO_MIME_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to guess the attachment file extension
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getExtension(){
|
||||
$guesser = "\Symfony\Component\Mime\MimeTypes";
|
||||
if (class_exists($guesser) !== false) {
|
||||
/** @var Symfony\Component\Mime\MimeTypes $guesser */
|
||||
$extensions = $guesser::getDefault()->getExtensions($this->getMimeType());
|
||||
return $extensions[0] ?? null;
|
||||
}
|
||||
|
||||
$deprecated_guesser = "\Symfony\Component\HttpFoundation\File\MimeType\ExtensionGuesser";
|
||||
if (class_exists($deprecated_guesser) !== false){
|
||||
/** @var \Symfony\Component\HttpFoundation\File\MimeType\ExtensionGuesser $deprecated_guesser */
|
||||
return $deprecated_guesser::getInstance()->guess($this->getMimeType());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all attributes
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAttributes(): array {
|
||||
return $this->attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Message
|
||||
*/
|
||||
public function getMessage(): Message {
|
||||
return $this->oMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default mask
|
||||
* @param $mask
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setMask($mask): Attachment {
|
||||
if(class_exists($mask)){
|
||||
$this->mask = $mask;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the used default mask
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getMask(): string {
|
||||
return $this->mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a masked instance by providing a mask name
|
||||
* @param string|null $mask
|
||||
*
|
||||
* @return mixed
|
||||
* @throws MaskNotFoundException
|
||||
*/
|
||||
public function mask($mask = null){
|
||||
$mask = $mask !== null ? $mask : $this->mask;
|
||||
if(class_exists($mask)){
|
||||
return new $mask($this);
|
||||
}
|
||||
|
||||
throw new MaskNotFoundException("Unknown mask provided: ".$mask);
|
||||
}
|
||||
}
|
||||
262
vendor/webklex/php-imap/src/Attribute.php
vendored
Normal file
262
vendor/webklex/php-imap/src/Attribute.php
vendored
Normal file
@@ -0,0 +1,262 @@
|
||||
<?php
|
||||
/*
|
||||
* File: Attribute.php
|
||||
* Category: -
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 01.01.21 20:17
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP;
|
||||
|
||||
use ArrayAccess;
|
||||
use Carbon\Carbon;
|
||||
use ReturnTypeWillChange;
|
||||
|
||||
/**
|
||||
* Class Attribute
|
||||
*
|
||||
* @package Webklex\PHPIMAP
|
||||
*/
|
||||
class Attribute implements ArrayAccess {
|
||||
|
||||
/** @var string $name */
|
||||
protected $name;
|
||||
|
||||
/**
|
||||
* Value holder
|
||||
*
|
||||
* @var array $values
|
||||
*/
|
||||
protected $values = [];
|
||||
|
||||
/**
|
||||
* Attribute constructor.
|
||||
* @param string $name
|
||||
* @param array|mixed $value
|
||||
*/
|
||||
public function __construct(string $name, $value = null) {
|
||||
$this->setName($name);
|
||||
$this->add($value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the stringified attribute
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString() {
|
||||
return implode(", ", $this->values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the stringified attribute
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function toString(): string {
|
||||
return $this->__toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert instance to array
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray(): array {
|
||||
return $this->values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert first value to a date object
|
||||
*
|
||||
* @return Carbon
|
||||
*/
|
||||
public function toDate(): Carbon {
|
||||
$date = $this->first();
|
||||
if ($date instanceof Carbon) return $date;
|
||||
|
||||
return Carbon::parse($date);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a value exists at an offset.
|
||||
*
|
||||
* @param mixed $offset
|
||||
* @return bool
|
||||
*/
|
||||
public function offsetExists($offset): bool {
|
||||
return array_key_exists($offset, $this->values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a value at a given offset.
|
||||
*
|
||||
* @param mixed $offset
|
||||
* @return mixed
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function offsetGet($offset) {
|
||||
return $this->values[$offset];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value at a given offset.
|
||||
*
|
||||
* @param mixed $offset
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function offsetSet($offset, $value) {
|
||||
if (is_null($offset)) {
|
||||
$this->values[] = $value;
|
||||
} else {
|
||||
$this->values[$offset] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unset the value at a given offset.
|
||||
*
|
||||
* @param string $offset
|
||||
* @return void
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function offsetUnset($offset) {
|
||||
unset($this->values[$offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add one or more values to the attribute
|
||||
* @param array|mixed $value
|
||||
* @param boolean $strict
|
||||
*
|
||||
* @return Attribute
|
||||
*/
|
||||
public function add($value, bool $strict = false): Attribute {
|
||||
if (is_array($value)) {
|
||||
return $this->merge($value, $strict);
|
||||
}elseif ($value !== null) {
|
||||
$this->attach($value, $strict);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge a given array of values with the current values array
|
||||
* @param array $values
|
||||
* @param boolean $strict
|
||||
*
|
||||
* @return Attribute
|
||||
*/
|
||||
public function merge(array $values, bool $strict = false): Attribute {
|
||||
foreach ($values as $value) {
|
||||
$this->attach($value, $strict);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the attribute contains the given value
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function contains($value): bool {
|
||||
return in_array($value, $this->values, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attach a given value to the current value array
|
||||
* @param $value
|
||||
* @param bool $strict
|
||||
*/
|
||||
public function attach($value, bool $strict = false) {
|
||||
if ($strict === true) {
|
||||
if ($this->contains($value) === false) {
|
||||
$this->values[] = $value;
|
||||
}
|
||||
}else{
|
||||
$this->values[] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the attribute name
|
||||
* @param $name
|
||||
*
|
||||
* @return Attribute
|
||||
*/
|
||||
public function setName($name): Attribute {
|
||||
$this->name = $name;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attribute name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName(): string {
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all values
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get(): array {
|
||||
return $this->values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias method for self::get()
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function all(): array {
|
||||
return $this->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the first value if possible
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function first(){
|
||||
if ($this->offsetExists(0)) {
|
||||
return $this->values[0];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the last value if possible
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function last(){
|
||||
if (($cnt = $this->count()) > 0) {
|
||||
return $this->values[$cnt - 1];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of values
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function count(): int {
|
||||
return count($this->values);
|
||||
}
|
||||
}
|
||||
746
vendor/webklex/php-imap/src/Client.php
vendored
Executable file
746
vendor/webklex/php-imap/src/Client.php
vendored
Executable file
@@ -0,0 +1,746 @@
|
||||
<?php
|
||||
/*
|
||||
* File: Client.php
|
||||
* Category: -
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 19.01.17 22:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP;
|
||||
|
||||
use ErrorException;
|
||||
use Webklex\PHPIMAP\Connection\Protocols\ImapProtocol;
|
||||
use Webklex\PHPIMAP\Connection\Protocols\LegacyProtocol;
|
||||
use Webklex\PHPIMAP\Connection\Protocols\Protocol;
|
||||
use Webklex\PHPIMAP\Connection\Protocols\ProtocolInterface;
|
||||
use Webklex\PHPIMAP\Exceptions\AuthFailedException;
|
||||
use Webklex\PHPIMAP\Exceptions\ConnectionFailedException;
|
||||
use Webklex\PHPIMAP\Exceptions\FolderFetchingException;
|
||||
use Webklex\PHPIMAP\Exceptions\MaskNotFoundException;
|
||||
use Webklex\PHPIMAP\Exceptions\ProtocolNotSupportedException;
|
||||
use Webklex\PHPIMAP\Support\FolderCollection;
|
||||
use Webklex\PHPIMAP\Support\Masks\AttachmentMask;
|
||||
use Webklex\PHPIMAP\Support\Masks\MessageMask;
|
||||
use Webklex\PHPIMAP\Traits\HasEvents;
|
||||
|
||||
/**
|
||||
* Class Client
|
||||
*
|
||||
* @package Webklex\PHPIMAP
|
||||
*/
|
||||
class Client {
|
||||
use HasEvents;
|
||||
|
||||
/**
|
||||
* Connection resource
|
||||
*
|
||||
* @var boolean|Protocol|ProtocolInterface
|
||||
*/
|
||||
public $connection = false;
|
||||
|
||||
/**
|
||||
* Server hostname.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $host;
|
||||
|
||||
/**
|
||||
* Server port.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $port;
|
||||
|
||||
/**
|
||||
* Service protocol.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $protocol;
|
||||
|
||||
/**
|
||||
* Server encryption.
|
||||
* Supported: none, ssl, tls, starttls or notls.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $encryption;
|
||||
|
||||
/**
|
||||
* If server has to validate cert.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $validate_cert = true;
|
||||
|
||||
/**
|
||||
* Proxy settings
|
||||
* @var array
|
||||
*/
|
||||
protected $proxy = [
|
||||
'socket' => null,
|
||||
'request_fulluri' => false,
|
||||
'username' => null,
|
||||
'password' => null,
|
||||
];
|
||||
|
||||
/**
|
||||
* Connection timeout
|
||||
* @var int $timeout
|
||||
*/
|
||||
public $timeout;
|
||||
|
||||
/**
|
||||
* Account username/
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
public $username;
|
||||
|
||||
/**
|
||||
* Account password.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $password;
|
||||
|
||||
/**
|
||||
* Additional data fetched from the server.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $extensions;
|
||||
|
||||
/**
|
||||
* Account authentication method.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $authentication;
|
||||
|
||||
/**
|
||||
* Active folder path.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $active_folder = null;
|
||||
|
||||
/**
|
||||
* Default message mask
|
||||
*
|
||||
* @var string $default_message_mask
|
||||
*/
|
||||
protected $default_message_mask = MessageMask::class;
|
||||
|
||||
/**
|
||||
* Default attachment mask
|
||||
*
|
||||
* @var string $default_attachment_mask
|
||||
*/
|
||||
protected $default_attachment_mask = AttachmentMask::class;
|
||||
|
||||
/**
|
||||
* Used default account values
|
||||
*
|
||||
* @var array $default_account_config
|
||||
*/
|
||||
protected $default_account_config = [
|
||||
'host' => 'localhost',
|
||||
'port' => 993,
|
||||
'protocol' => 'imap',
|
||||
'encryption' => 'ssl',
|
||||
'validate_cert' => true,
|
||||
'username' => '',
|
||||
'password' => '',
|
||||
'authentication' => null,
|
||||
"extensions" => [],
|
||||
'proxy' => [
|
||||
'socket' => null,
|
||||
'request_fulluri' => false,
|
||||
'username' => null,
|
||||
'password' => null,
|
||||
],
|
||||
"timeout" => 30
|
||||
];
|
||||
|
||||
/**
|
||||
* Client constructor.
|
||||
* @param array $config
|
||||
*
|
||||
* @throws MaskNotFoundException
|
||||
*/
|
||||
public function __construct(array $config = []) {
|
||||
$this->setConfig($config);
|
||||
$this->setMaskFromConfig($config);
|
||||
$this->setEventsFromConfig($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Client destructor
|
||||
*/
|
||||
public function __destruct() {
|
||||
$this->disconnect();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Client configuration
|
||||
* @param array $config
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setConfig(array $config): Client {
|
||||
$default_account = ClientManager::get('default');
|
||||
$default_config = ClientManager::get("accounts.$default_account");
|
||||
|
||||
foreach ($this->default_account_config as $key => $value) {
|
||||
$this->setAccountConfig($key, $config, $default_config);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a specific account config
|
||||
* @param string $key
|
||||
* @param array $config
|
||||
* @param array $default_config
|
||||
*/
|
||||
private function setAccountConfig(string $key, array $config, array $default_config){
|
||||
$value = $this->default_account_config[$key];
|
||||
if(isset($config[$key])) {
|
||||
$value = $config[$key];
|
||||
}elseif(isset($default_config[$key])) {
|
||||
$value = $default_config[$key];
|
||||
}
|
||||
$this->$key = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Look for a possible events in any available config
|
||||
* @param $config
|
||||
*/
|
||||
protected function setEventsFromConfig($config) {
|
||||
$this->events = ClientManager::get("events");
|
||||
if(isset($config['events'])){
|
||||
foreach($config['events'] as $section => $events) {
|
||||
$this->events[$section] = array_merge($this->events[$section], $events);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Look for a possible mask in any available config
|
||||
* @param $config
|
||||
*
|
||||
* @throws MaskNotFoundException
|
||||
*/
|
||||
protected function setMaskFromConfig($config) {
|
||||
$default_config = ClientManager::get("masks");
|
||||
|
||||
if(isset($config['masks'])){
|
||||
if(isset($config['masks']['message'])) {
|
||||
if(class_exists($config['masks']['message'])) {
|
||||
$this->default_message_mask = $config['masks']['message'];
|
||||
}else{
|
||||
throw new MaskNotFoundException("Unknown mask provided: ".$config['masks']['message']);
|
||||
}
|
||||
}else{
|
||||
if(class_exists($default_config['message'])) {
|
||||
$this->default_message_mask = $default_config['message'];
|
||||
}else{
|
||||
throw new MaskNotFoundException("Unknown mask provided: ".$default_config['message']);
|
||||
}
|
||||
}
|
||||
if(isset($config['masks']['attachment'])) {
|
||||
if(class_exists($config['masks']['attachment'])) {
|
||||
$this->default_attachment_mask = $config['masks']['attachment'];
|
||||
}else{
|
||||
throw new MaskNotFoundException("Unknown mask provided: ".$config['masks']['attachment']);
|
||||
}
|
||||
}else{
|
||||
if(class_exists($default_config['attachment'])) {
|
||||
$this->default_attachment_mask = $default_config['attachment'];
|
||||
}else{
|
||||
throw new MaskNotFoundException("Unknown mask provided: ".$default_config['attachment']);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
if(class_exists($default_config['message'])) {
|
||||
$this->default_message_mask = $default_config['message'];
|
||||
}else{
|
||||
throw new MaskNotFoundException("Unknown mask provided: ".$default_config['message']);
|
||||
}
|
||||
|
||||
if(class_exists($default_config['attachment'])) {
|
||||
$this->default_attachment_mask = $default_config['attachment'];
|
||||
}else{
|
||||
throw new MaskNotFoundException("Unknown mask provided: ".$default_config['attachment']);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current imap resource
|
||||
*
|
||||
* @return bool|Protocol|ProtocolInterface
|
||||
* @throws ConnectionFailedException
|
||||
*/
|
||||
public function getConnection() {
|
||||
$this->checkConnection();
|
||||
return $this->connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if connection was established.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isConnected(): bool {
|
||||
return $this->connection && $this->connection->connected();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if connection was established and connect if not.
|
||||
*
|
||||
* @throws ConnectionFailedException
|
||||
*/
|
||||
public function checkConnection() {
|
||||
if (!$this->isConnected()) {
|
||||
$this->connect();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Force the connection to reconnect
|
||||
*
|
||||
* @throws ConnectionFailedException
|
||||
*/
|
||||
public function reconnect() {
|
||||
if ($this->isConnected()) {
|
||||
$this->disconnect();
|
||||
}
|
||||
$this->connect();
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to server.
|
||||
*
|
||||
* @return $this
|
||||
* @throws ConnectionFailedException
|
||||
*/
|
||||
public function connect(): Client {
|
||||
$this->disconnect();
|
||||
$protocol = strtolower($this->protocol);
|
||||
|
||||
if (in_array($protocol, ['imap', 'imap4', 'imap4rev1'])) {
|
||||
$this->connection = new ImapProtocol($this->validate_cert, $this->encryption);
|
||||
$this->connection->setConnectionTimeout($this->timeout);
|
||||
$this->connection->setProxy($this->proxy);
|
||||
}else{
|
||||
if (extension_loaded('imap') === false) {
|
||||
throw new ConnectionFailedException("connection setup failed", 0, new ProtocolNotSupportedException($protocol." is an unsupported protocol"));
|
||||
}
|
||||
$this->connection = new LegacyProtocol($this->validate_cert, $this->encryption);
|
||||
if (strpos($protocol, "legacy-") === 0) {
|
||||
$protocol = substr($protocol, 7);
|
||||
}
|
||||
$this->connection->setProtocol($protocol);
|
||||
}
|
||||
|
||||
if (ClientManager::get('options.debug')) {
|
||||
$this->connection->enableDebug();
|
||||
}
|
||||
|
||||
if (!ClientManager::get('options.uid_cache')) {
|
||||
$this->connection->disableUidCache();
|
||||
}
|
||||
|
||||
try {
|
||||
$this->connection->connect($this->host, $this->port);
|
||||
} catch (ErrorException $e) {
|
||||
throw new ConnectionFailedException("connection setup failed", 0, $e);
|
||||
} catch (Exceptions\RuntimeException $e) {
|
||||
throw new ConnectionFailedException("connection setup failed", 0, $e);
|
||||
}
|
||||
$this->authenticate();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Authenticate the current session
|
||||
*
|
||||
* @throws ConnectionFailedException
|
||||
*/
|
||||
protected function authenticate() {
|
||||
try {
|
||||
if ($this->authentication == "oauth") {
|
||||
if (!$this->connection->authenticate($this->username, $this->password)) {
|
||||
throw new AuthFailedException();
|
||||
}
|
||||
} elseif (!$this->connection->login($this->username, $this->password)) {
|
||||
throw new AuthFailedException();
|
||||
}
|
||||
} catch (AuthFailedException $e) {
|
||||
throw new ConnectionFailedException("connection setup failed", 0, $e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnect from server.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function disconnect(): Client {
|
||||
if ($this->isConnected() && $this->connection !== false) {
|
||||
$this->connection->logout();
|
||||
}
|
||||
$this->active_folder = null;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a folder instance by a folder name
|
||||
* @param string $folder_name
|
||||
* @param string|bool|null $delimiter
|
||||
*
|
||||
* @return Folder|null
|
||||
* @throws ConnectionFailedException
|
||||
* @throws FolderFetchingException
|
||||
* @throws Exceptions\RuntimeException
|
||||
*/
|
||||
public function getFolder(string $folder_name, $delimiter = null) {
|
||||
if ($delimiter !== false && $delimiter !== null) {
|
||||
return $this->getFolderByPath($folder_name);
|
||||
}
|
||||
|
||||
// Set delimiter to false to force selection via getFolderByName (maybe useful for uncommon folder names)
|
||||
$delimiter = is_null($delimiter) ? ClientManager::get('options.delimiter', "/") : $delimiter;
|
||||
if (strpos($folder_name, (string)$delimiter) !== false) {
|
||||
return $this->getFolderByPath($folder_name);
|
||||
}
|
||||
|
||||
return $this->getFolderByName($folder_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a folder instance by a folder name
|
||||
* @param $folder_name
|
||||
*
|
||||
* @return Folder|null
|
||||
* @throws ConnectionFailedException
|
||||
* @throws FolderFetchingException
|
||||
* @throws Exceptions\RuntimeException
|
||||
*/
|
||||
public function getFolderByName($folder_name) {
|
||||
return $this->getFolders(false)->where("name", $folder_name)->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a folder instance by a folder path
|
||||
* @param $folder_path
|
||||
*
|
||||
* @return Folder|null
|
||||
* @throws ConnectionFailedException
|
||||
* @throws FolderFetchingException
|
||||
* @throws Exceptions\RuntimeException
|
||||
*/
|
||||
public function getFolderByPath($folder_path) {
|
||||
return $this->getFolders(false)->where("path", $folder_path)->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get folders list.
|
||||
* If hierarchical order is set to true, it will make a tree of folders, otherwise it will return flat array.
|
||||
*
|
||||
* @param boolean $hierarchical
|
||||
* @param string|null $parent_folder
|
||||
*
|
||||
* @return FolderCollection
|
||||
* @throws ConnectionFailedException
|
||||
* @throws FolderFetchingException
|
||||
* @throws Exceptions\RuntimeException
|
||||
*/
|
||||
public function getFolders(bool $hierarchical = true, string $parent_folder = null): FolderCollection {
|
||||
$this->checkConnection();
|
||||
$folders = FolderCollection::make([]);
|
||||
|
||||
$pattern = $parent_folder.($hierarchical ? '%' : '*');
|
||||
$items = $this->connection->folders('', $pattern);
|
||||
|
||||
if(is_array($items)){
|
||||
foreach ($items as $folder_name => $item) {
|
||||
$folder = new Folder($this, $folder_name, $item["delimiter"], $item["flags"]);
|
||||
|
||||
if ($hierarchical && $folder->hasChildren()) {
|
||||
$pattern = $folder->full_name.$folder->delimiter.'%';
|
||||
|
||||
$children = $this->getFolders(true, $pattern);
|
||||
$folder->setChildren($children);
|
||||
}
|
||||
|
||||
$folders->push($folder);
|
||||
}
|
||||
|
||||
return $folders;
|
||||
}else{
|
||||
throw new FolderFetchingException("failed to fetch any folders");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get folders list.
|
||||
* If hierarchical order is set to true, it will make a tree of folders, otherwise it will return flat array.
|
||||
*
|
||||
* @param boolean $hierarchical
|
||||
* @param string|null $parent_folder
|
||||
*
|
||||
* @return FolderCollection
|
||||
* @throws ConnectionFailedException
|
||||
* @throws FolderFetchingException
|
||||
* @throws Exceptions\RuntimeException
|
||||
*/
|
||||
public function getFoldersWithStatus(bool $hierarchical = true, string $parent_folder = null): FolderCollection {
|
||||
$this->checkConnection();
|
||||
$folders = FolderCollection::make([]);
|
||||
|
||||
$pattern = $parent_folder.($hierarchical ? '%' : '*');
|
||||
$items = $this->connection->folders('', $pattern);
|
||||
|
||||
if(is_array($items)){
|
||||
foreach ($items as $folder_name => $item) {
|
||||
$folder = new Folder($this, $folder_name, $item["delimiter"], $item["flags"]);
|
||||
|
||||
if ($hierarchical && $folder->hasChildren()) {
|
||||
$pattern = $folder->full_name.$folder->delimiter.'%';
|
||||
|
||||
$children = $this->getFoldersWithStatus(true, $pattern);
|
||||
$folder->setChildren($children);
|
||||
}
|
||||
|
||||
$folder->loadStatus();
|
||||
$folders->push($folder);
|
||||
}
|
||||
|
||||
return $folders;
|
||||
}else{
|
||||
throw new FolderFetchingException("failed to fetch any folders");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Open a given folder.
|
||||
* @param string $folder_path
|
||||
* @param boolean $force_select
|
||||
*
|
||||
* @return array|bool
|
||||
* @throws ConnectionFailedException
|
||||
* @throws Exceptions\RuntimeException
|
||||
*/
|
||||
public function openFolder(string $folder_path, bool $force_select = false) {
|
||||
if ($this->active_folder == $folder_path && $this->isConnected() && $force_select === false) {
|
||||
return true;
|
||||
}
|
||||
$this->checkConnection();
|
||||
$this->active_folder = $folder_path;
|
||||
return $this->connection->selectFolder($folder_path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new Folder
|
||||
* @param string $folder
|
||||
* @param boolean $expunge
|
||||
*
|
||||
* @return Folder
|
||||
* @throws ConnectionFailedException
|
||||
* @throws FolderFetchingException
|
||||
* @throws Exceptions\EventNotFoundException
|
||||
* @throws Exceptions\RuntimeException
|
||||
*/
|
||||
public function createFolder(string $folder, bool $expunge = true): Folder {
|
||||
$this->checkConnection();
|
||||
$status = $this->connection->createFolder($folder);
|
||||
|
||||
if($expunge) $this->expunge();
|
||||
|
||||
$folder = $this->getFolderByPath($folder);
|
||||
if($status && $folder) {
|
||||
$event = $this->getEvent("folder", "new");
|
||||
$event::dispatch($folder);
|
||||
}
|
||||
|
||||
return $folder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check a given folder
|
||||
* @param $folder
|
||||
*
|
||||
* @return array|bool
|
||||
* @throws ConnectionFailedException
|
||||
* @throws Exceptions\RuntimeException
|
||||
*/
|
||||
public function checkFolder($folder) {
|
||||
$this->checkConnection();
|
||||
return $this->connection->examineFolder($folder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current active folder
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFolderPath(){
|
||||
return $this->active_folder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Exchange identification information
|
||||
* Ref.: https://datatracker.ietf.org/doc/html/rfc2971
|
||||
*
|
||||
* @param array|null $ids
|
||||
* @return array|bool|void|null
|
||||
*
|
||||
* @throws ConnectionFailedException
|
||||
* @throws Exceptions\RuntimeException
|
||||
*/
|
||||
public function Id(array $ids = null) {
|
||||
$this->checkConnection();
|
||||
return $this->connection->ID($ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the quota level settings, and usage statics per mailbox
|
||||
*
|
||||
* @return array
|
||||
* @throws ConnectionFailedException
|
||||
* @throws Exceptions\RuntimeException
|
||||
*/
|
||||
public function getQuota(): array {
|
||||
$this->checkConnection();
|
||||
return $this->connection->getQuota($this->username);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the quota settings per user
|
||||
* @param string $quota_root
|
||||
*
|
||||
* @return array
|
||||
* @throws ConnectionFailedException
|
||||
*/
|
||||
public function getQuotaRoot(string $quota_root = 'INBOX'): array {
|
||||
$this->checkConnection();
|
||||
return $this->connection->getQuotaRoot($quota_root);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all messages marked for deletion
|
||||
*
|
||||
* @return bool
|
||||
* @throws ConnectionFailedException
|
||||
* @throws Exceptions\RuntimeException
|
||||
*/
|
||||
public function expunge(): bool {
|
||||
$this->checkConnection();
|
||||
return $this->connection->expunge();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the connection timeout
|
||||
* @param integer $timeout
|
||||
*
|
||||
* @return Protocol
|
||||
* @throws ConnectionFailedException
|
||||
*/
|
||||
public function setTimeout(int $timeout): Protocol {
|
||||
$this->timeout = $timeout;
|
||||
if ($this->isConnected()) {
|
||||
$this->connection->setConnectionTimeout($timeout);
|
||||
$this->reconnect();
|
||||
}
|
||||
return $this->connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the connection timeout
|
||||
*
|
||||
* @return int
|
||||
* @throws ConnectionFailedException
|
||||
*/
|
||||
public function getTimeout(): int {
|
||||
$this->checkConnection();
|
||||
return $this->connection->getConnectionTimeout();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default message mask
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDefaultMessageMask(): string {
|
||||
return $this->default_message_mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default events for a given section
|
||||
* @param $section
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getDefaultEvents($section): array {
|
||||
if (isset($this->events[$section])) {
|
||||
return is_array($this->events[$section]) ? $this->events[$section] : [];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default message mask
|
||||
* @param string $mask
|
||||
*
|
||||
* @return $this
|
||||
* @throws MaskNotFoundException
|
||||
*/
|
||||
public function setDefaultMessageMask(string $mask): Client {
|
||||
if(class_exists($mask)) {
|
||||
$this->default_message_mask = $mask;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
throw new MaskNotFoundException("Unknown mask provided: ".$mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default attachment mask
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDefaultAttachmentMask(): string {
|
||||
return $this->default_attachment_mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default attachment mask
|
||||
* @param string $mask
|
||||
*
|
||||
* @return $this
|
||||
* @throws MaskNotFoundException
|
||||
*/
|
||||
public function setDefaultAttachmentMask(string $mask): Client {
|
||||
if(class_exists($mask)) {
|
||||
$this->default_attachment_mask = $mask;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
throw new MaskNotFoundException("Unknown mask provided: ".$mask);
|
||||
}
|
||||
}
|
||||
276
vendor/webklex/php-imap/src/ClientManager.php
vendored
Normal file
276
vendor/webklex/php-imap/src/ClientManager.php
vendored
Normal file
@@ -0,0 +1,276 @@
|
||||
<?php
|
||||
/*
|
||||
* File: ClientManager.php
|
||||
* Category: -
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 19.01.17 22:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP;
|
||||
|
||||
/**
|
||||
* Class ClientManager
|
||||
*
|
||||
* @package Webklex\IMAP
|
||||
*
|
||||
* @mixin Client
|
||||
*/
|
||||
class ClientManager {
|
||||
|
||||
/**
|
||||
* All library config
|
||||
*
|
||||
* @var array $config
|
||||
*/
|
||||
public static $config = [];
|
||||
|
||||
/**
|
||||
* @var array $accounts
|
||||
*/
|
||||
protected $accounts = [];
|
||||
|
||||
/**
|
||||
* ClientManager constructor.
|
||||
* @param array|string $config
|
||||
*/
|
||||
public function __construct($config = []) {
|
||||
$this->setConfig($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dynamically pass calls to the default account.
|
||||
* @param string $method
|
||||
* @param array $parameters
|
||||
*
|
||||
* @return mixed
|
||||
* @throws Exceptions\MaskNotFoundException
|
||||
*/
|
||||
public function __call(string $method, array $parameters) {
|
||||
$callable = [$this->account(), $method];
|
||||
|
||||
return call_user_func_array($callable, $parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Safely create a new client instance which is not listed in accounts
|
||||
* @param array $config
|
||||
*
|
||||
* @return Client
|
||||
* @throws Exceptions\MaskNotFoundException
|
||||
*/
|
||||
public function make(array $config): Client {
|
||||
return new Client($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a dotted config parameter
|
||||
* @param string $key
|
||||
* @param null $default
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
public static function get(string $key, $default = null) {
|
||||
$parts = explode('.', $key);
|
||||
$value = null;
|
||||
foreach($parts as $part) {
|
||||
if($value === null) {
|
||||
if(isset(self::$config[$part])) {
|
||||
$value = self::$config[$part];
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
}else{
|
||||
if(isset($value[$part])) {
|
||||
$value = $value[$part];
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $value === null ? $default : $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve a account instance.
|
||||
* @param string|null $name
|
||||
*
|
||||
* @return Client
|
||||
* @throws Exceptions\MaskNotFoundException
|
||||
*/
|
||||
public function account(string $name = null): Client {
|
||||
$name = $name ?: $this->getDefaultAccount();
|
||||
|
||||
// If the connection has not been resolved we will resolve it now as all
|
||||
// the connections are resolved when they are actually needed, so we do
|
||||
// not make any unnecessary connection to the various queue end-points.
|
||||
if (!isset($this->accounts[$name])) {
|
||||
$this->accounts[$name] = $this->resolve($name);
|
||||
}
|
||||
|
||||
return $this->accounts[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve an account.
|
||||
* @param string $name
|
||||
*
|
||||
* @return Client
|
||||
* @throws Exceptions\MaskNotFoundException
|
||||
*/
|
||||
protected function resolve(string $name): Client {
|
||||
$config = $this->getClientConfig($name);
|
||||
|
||||
return new Client($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the account configuration.
|
||||
* @param string|null $name
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getClientConfig($name): array {
|
||||
if ($name === null || $name === 'null') {
|
||||
return ['driver' => 'null'];
|
||||
}
|
||||
|
||||
return is_array(self::$config["accounts"][$name]) ? self::$config["accounts"][$name] : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the default account.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDefaultAccount(): string {
|
||||
return self::$config['default'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the name of the default account.
|
||||
* @param string $name
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setDefaultAccount(string $name) {
|
||||
self::$config['default'] = $name;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Merge the vendor settings with the local config
|
||||
*
|
||||
* The default account identifier will be used as default for any missing account parameters.
|
||||
* If however the default account is missing a parameter the package default account parameter will be used.
|
||||
* This can be disabled by setting imap.default in your config file to 'false'
|
||||
*
|
||||
* @param array|string $config
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setConfig($config): ClientManager {
|
||||
|
||||
if(is_array($config) === false) {
|
||||
$config = require $config;
|
||||
}
|
||||
|
||||
$config_key = 'imap';
|
||||
$path = __DIR__.'/config/'.$config_key.'.php';
|
||||
|
||||
$vendor_config = require $path;
|
||||
$config = $this->array_merge_recursive_distinct($vendor_config, $config);
|
||||
|
||||
if(is_array($config)){
|
||||
if(isset($config['default'])){
|
||||
if(isset($config['accounts']) && $config['default']){
|
||||
|
||||
$default_config = $vendor_config['accounts']['default'];
|
||||
if(isset($config['accounts'][$config['default']])){
|
||||
$default_config = array_merge($default_config, $config['accounts'][$config['default']]);
|
||||
}
|
||||
|
||||
if(is_array($config['accounts'])){
|
||||
foreach($config['accounts'] as $account_key => $account){
|
||||
$config['accounts'][$account_key] = array_merge($default_config, $account);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self::$config = $config;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Marge arrays recursively and distinct
|
||||
*
|
||||
* Merges any number of arrays / parameters recursively, replacing
|
||||
* entries with string keys with values from latter arrays.
|
||||
* If the entry or the next value to be assigned is an array, then it
|
||||
* automatically treats both arguments as an array.
|
||||
* Numeric entries are appended, not replaced, but only if they are
|
||||
* unique
|
||||
*
|
||||
* @return array|mixed
|
||||
*
|
||||
* @link http://www.php.net/manual/en/function.array-merge-recursive.php#96201
|
||||
* @author Mark Roduner <mark.roduner@gmail.com>
|
||||
*/
|
||||
private function array_merge_recursive_distinct() {
|
||||
|
||||
$arrays = func_get_args();
|
||||
$base = array_shift($arrays);
|
||||
|
||||
// From https://stackoverflow.com/a/173479
|
||||
$isAssoc = function(array $arr) {
|
||||
if (array() === $arr) return false;
|
||||
return array_keys($arr) !== range(0, count($arr) - 1);
|
||||
};
|
||||
|
||||
if(!is_array($base)) $base = empty($base) ? array() : array($base);
|
||||
|
||||
foreach($arrays as $append) {
|
||||
|
||||
if(!is_array($append)) $append = array($append);
|
||||
|
||||
foreach($append as $key => $value) {
|
||||
|
||||
if(!array_key_exists($key, $base) and !is_numeric($key)) {
|
||||
$base[$key] = $value;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(
|
||||
(
|
||||
is_array($value)
|
||||
&& $isAssoc($value)
|
||||
)
|
||||
|| (
|
||||
is_array($base[$key])
|
||||
&& $isAssoc($base[$key])
|
||||
)
|
||||
) {
|
||||
// If the arrays are not associates we don't want to array_merge_recursive_distinct
|
||||
// else merging $baseConfig['dispositions'] = ['attachment', 'inline'] with $customConfig['dispositions'] = ['attachment']
|
||||
// results in $resultConfig['dispositions'] = ['attachment', 'inline']
|
||||
$base[$key] = $this->array_merge_recursive_distinct($base[$key], $value);
|
||||
} else if(is_numeric($key)) {
|
||||
if(!in_array($value, $base)) $base[] = $value;
|
||||
} else {
|
||||
$base[$key] = $value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $base;
|
||||
}
|
||||
}
|
||||
1160
vendor/webklex/php-imap/src/Connection/Protocols/ImapProtocol.php
vendored
Normal file
1160
vendor/webklex/php-imap/src/Connection/Protocols/ImapProtocol.php
vendored
Normal file
File diff suppressed because it is too large
Load Diff
643
vendor/webklex/php-imap/src/Connection/Protocols/LegacyProtocol.php
vendored
Normal file
643
vendor/webklex/php-imap/src/Connection/Protocols/LegacyProtocol.php
vendored
Normal file
@@ -0,0 +1,643 @@
|
||||
<?php
|
||||
/*
|
||||
* File: LegacyProtocol.php
|
||||
* Category: Protocol
|
||||
* Author: M.Goldenbaum
|
||||
* Created: 16.09.20 18:27
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Connection\Protocols;
|
||||
|
||||
use Webklex\PHPIMAP\ClientManager;
|
||||
use Webklex\PHPIMAP\Exceptions\AuthFailedException;
|
||||
use Webklex\PHPIMAP\Exceptions\MethodNotSupportedException;
|
||||
use Webklex\PHPIMAP\Exceptions\RuntimeException;
|
||||
use Webklex\PHPIMAP\IMAP;
|
||||
|
||||
/**
|
||||
* Class LegacyProtocol
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Connection\Protocols
|
||||
*/
|
||||
class LegacyProtocol extends Protocol {
|
||||
|
||||
protected $protocol = "imap";
|
||||
protected $host = null;
|
||||
protected $port = null;
|
||||
protected $encryption = null;
|
||||
|
||||
/**
|
||||
* Imap constructor.
|
||||
* @param bool $cert_validation set to false to skip SSL certificate validation
|
||||
* @param mixed $encryption Connection encryption method
|
||||
*/
|
||||
public function __construct(bool $cert_validation = true, $encryption = false) {
|
||||
$this->setCertValidation($cert_validation);
|
||||
$this->encryption = $encryption;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public destructor
|
||||
*/
|
||||
public function __destruct() {
|
||||
$this->logout();
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the information for a nw connection
|
||||
* @param string $host
|
||||
* @param null $port
|
||||
*/
|
||||
public function connect(string $host, $port = null) {
|
||||
if ($this->encryption) {
|
||||
$encryption = strtolower($this->encryption);
|
||||
if ($encryption == "ssl") {
|
||||
$port = $port === null ? 993 : $port;
|
||||
}
|
||||
}
|
||||
$port = $port === null ? 143 : $port;
|
||||
$this->host = $host;
|
||||
$this->port = $port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Login to a new session.
|
||||
* @param string $user username
|
||||
* @param string $password password
|
||||
*
|
||||
* @return bool
|
||||
* @throws AuthFailedException
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function login(string $user, string $password): bool {
|
||||
try {
|
||||
$this->stream = \imap_open(
|
||||
$this->getAddress(),
|
||||
$user,
|
||||
$password,
|
||||
0,
|
||||
$attempts = 3,
|
||||
ClientManager::get('options.open')
|
||||
);
|
||||
} catch (\ErrorException $e) {
|
||||
$errors = \imap_errors();
|
||||
$message = $e->getMessage().'. '.implode("; ", (is_array($errors) ? $errors : array()));
|
||||
throw new AuthFailedException($message);
|
||||
}
|
||||
|
||||
if(!$this->stream) {
|
||||
$errors = \imap_errors();
|
||||
$message = implode("; ", (is_array($errors) ? $errors : array()));
|
||||
throw new AuthFailedException($message);
|
||||
}
|
||||
|
||||
$errors = \imap_errors();
|
||||
if(is_array($errors)) {
|
||||
$status = $this->examineFolder();
|
||||
if($status['exists'] !== 0) {
|
||||
$message = implode("; ", (is_array($errors) ? $errors : array()));
|
||||
throw new RuntimeException($message);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->stream !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Authenticate your current session.
|
||||
* @param string $user username
|
||||
* @param string $token access token
|
||||
*
|
||||
* @return bool|resource
|
||||
* @throws AuthFailedException|RuntimeException
|
||||
*/
|
||||
public function authenticate(string $user, string $token): bool {
|
||||
return $this->login($user, $token);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get full address of mailbox.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getAddress(): string {
|
||||
$address = "{".$this->host.":".$this->port."/".$this->protocol;
|
||||
if (!$this->cert_validation) {
|
||||
$address .= '/novalidate-cert';
|
||||
}
|
||||
if (in_array($this->encryption,['tls', 'notls', 'ssl'])) {
|
||||
$address .= '/'.$this->encryption;
|
||||
} elseif ($this->encryption === "starttls") {
|
||||
$address .= '/tls';
|
||||
}
|
||||
|
||||
$address .= '}';
|
||||
|
||||
return $address;
|
||||
}
|
||||
|
||||
/**
|
||||
* Logout of the current session
|
||||
*
|
||||
* @return bool success
|
||||
*/
|
||||
public function logout(): bool {
|
||||
if ($this->stream) {
|
||||
$result = \imap_close($this->stream, IMAP::CL_EXPUNGE);
|
||||
$this->stream = false;
|
||||
$this->uid_cache = null;
|
||||
return $result;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the current session is connected
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function connected(): bool {
|
||||
return boolval($this->stream);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of available capabilities
|
||||
*
|
||||
* @throws MethodNotSupportedException
|
||||
*/
|
||||
public function getCapabilities(): array {
|
||||
throw new MethodNotSupportedException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the current folder
|
||||
* @param string $folder change to this folder
|
||||
*
|
||||
* @return bool|array see examineOrselect()
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function selectFolder(string $folder = 'INBOX') {
|
||||
$flags = IMAP::OP_READONLY;
|
||||
if (in_array($this->protocol, ["pop3", "nntp"])) {
|
||||
$flags = IMAP::NIL;
|
||||
}
|
||||
if ($this->stream === false) {
|
||||
throw new RuntimeException("failed to reopen stream.");
|
||||
}
|
||||
|
||||
\imap_reopen($this->stream, $this->getAddress().$folder, $flags, 3);
|
||||
$this->uid_cache = null;
|
||||
return $this->examineFolder($folder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Examine a given folder
|
||||
* @param string $folder examine this folder
|
||||
*
|
||||
* @return bool|array
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function examineFolder(string $folder = 'INBOX') {
|
||||
if (strpos($folder, ".") === 0) {
|
||||
throw new RuntimeException("Segmentation fault prevented. Folders starts with an illegal char '.'.");
|
||||
}
|
||||
$folder = $this->getAddress().$folder;
|
||||
$status = \imap_status($this->stream, $folder, IMAP::SA_ALL);
|
||||
return [
|
||||
"flags" => [],
|
||||
"exists" => $status->messages,
|
||||
"recent" => $status->recent,
|
||||
"unseen" => $status->unseen,
|
||||
"uidnext" => $status->uidnext,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch message content
|
||||
* @param array|int $uids
|
||||
* @param string $rfc
|
||||
* @param int $uid set to IMAP::ST_UID if you pass message unique identifiers instead of numbers.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function content($uids, string $rfc = "RFC822", $uid = IMAP::ST_UID): array {
|
||||
$result = [];
|
||||
$uids = is_array($uids) ? $uids : [$uids];
|
||||
foreach ($uids as $id) {
|
||||
$result[$id] = \imap_fetchbody($this->stream, $id, "", $uid ? IMAP::ST_UID : IMAP::NIL);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch message headers
|
||||
* @param array|int $uids
|
||||
* @param string $rfc
|
||||
* @param int $uid set to IMAP::ST_UID if you pass message unique identifiers instead of numbers.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function headers($uids, string $rfc = "RFC822", $uid = IMAP::ST_UID): array {
|
||||
$result = [];
|
||||
$uids = is_array($uids) ? $uids : [$uids];
|
||||
foreach ($uids as $id) {
|
||||
$result[$id] = \imap_fetchheader($this->stream, $id, $uid ? IMAP::ST_UID : IMAP::NIL);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch message flags
|
||||
* @param array|int $uids
|
||||
* @param int $uid set to IMAP::ST_UID if you pass message unique identifiers instead of numbers.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function flags($uids, $uid = IMAP::ST_UID): array {
|
||||
$result = [];
|
||||
$uids = is_array($uids) ? $uids : [$uids];
|
||||
foreach ($uids as $id) {
|
||||
$raw_flags = \imap_fetch_overview($this->stream, $id, $uid ? IMAP::ST_UID : IMAP::NIL);
|
||||
$flags = [];
|
||||
if (is_array($raw_flags) && isset($raw_flags[0])) {
|
||||
$raw_flags = (array) $raw_flags[0];
|
||||
foreach($raw_flags as $flag => $value) {
|
||||
if ($value === 1 && in_array($flag, ["size", "uid", "msgno", "update"]) === false){
|
||||
$flags[] = "\\".ucfirst($flag);
|
||||
}
|
||||
}
|
||||
}
|
||||
$result[$uid] = $flags;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get uid for a given id
|
||||
* @param int|null $id message number
|
||||
*
|
||||
* @return array|string message number for given message or all messages as array
|
||||
*/
|
||||
public function getUid($id = null) {
|
||||
if ($id === null) {
|
||||
if ($this->enable_uid_cache && $this->uid_cache) {
|
||||
return $this->uid_cache;
|
||||
}
|
||||
|
||||
$overview = $this->overview("1:*");
|
||||
$uids = [];
|
||||
foreach($overview as $set){
|
||||
$uids[$set->msgno] = $set->uid;
|
||||
}
|
||||
|
||||
$this->setUidCache($uids);
|
||||
return $uids;
|
||||
}
|
||||
|
||||
return \imap_uid($this->stream, $id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a message number for a uid
|
||||
* @param string $id uid
|
||||
*
|
||||
* @return int message number
|
||||
*/
|
||||
public function getMessageNumber(string $id): int {
|
||||
return \imap_msgno($this->stream, $id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a message overview
|
||||
* @param string $sequence uid sequence
|
||||
* @param int $uid set to IMAP::ST_UID if you pass message unique identifiers instead of numbers.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function overview(string $sequence, $uid = IMAP::ST_UID): array {
|
||||
return \imap_fetch_overview($this->stream, $sequence,$uid ? IMAP::ST_UID : IMAP::NIL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of available folders
|
||||
* @param string $reference mailbox reference for list
|
||||
* @param string $folder mailbox name match with wildcards
|
||||
*
|
||||
* @return array folders that matched $folder as array(name => array('delimiter' => .., 'flags' => ..))
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function folders(string $reference = '', string $folder = '*'): array {
|
||||
$result = [];
|
||||
|
||||
$items = \imap_getmailboxes($this->stream, $this->getAddress(), $reference.$folder);
|
||||
if(is_array($items)){
|
||||
foreach ($items as $item) {
|
||||
$name = $this->decodeFolderName($item->name);
|
||||
$result[$name] = ['delimiter' => $item->delimiter, 'flags' => []];
|
||||
}
|
||||
}else{
|
||||
throw new RuntimeException(\imap_last_error());
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Manage flags
|
||||
* @param array $flags flags to set, add or remove - see $mode
|
||||
* @param int $from message for items or start message if $to !== null
|
||||
* @param int|null $to if null only one message ($from) is fetched, else it's the
|
||||
* last message, INF means last message available
|
||||
* @param string|null $mode '+' to add flags, '-' to remove flags, everything else sets the flags as given
|
||||
* @param bool $silent if false the return values are the new flags for the wanted messages
|
||||
* @param int $uid set to IMAP::ST_UID if you pass message unique identifiers instead of numbers.
|
||||
* @param null $item unused attribute
|
||||
*
|
||||
* @return bool|array new flags if $silent is false, else true or false depending on success
|
||||
*/
|
||||
public function store(array $flags, int $from, $to = null, $mode = null, bool $silent = true, $uid = IMAP::ST_UID, $item = null) {
|
||||
$flag = trim(is_array($flags) ? implode(" ", $flags) : $flags);
|
||||
|
||||
if ($mode == "+"){
|
||||
$status = \imap_setflag_full($this->stream, $from, $flag, $uid ? IMAP::ST_UID : IMAP::NIL);
|
||||
}else{
|
||||
$status = \imap_clearflag_full($this->stream, $from, $flag, $uid ? IMAP::ST_UID : IMAP::NIL);
|
||||
}
|
||||
|
||||
if ($silent === true) {
|
||||
return $status;
|
||||
}
|
||||
|
||||
return $this->flags($from);
|
||||
}
|
||||
|
||||
/**
|
||||
* Append a new message to given folder
|
||||
* @param string $folder name of target folder
|
||||
* @param string $message full message content
|
||||
* @param array|null $flags flags for new message
|
||||
* @param string $date date for new message
|
||||
*
|
||||
* @return bool success
|
||||
*/
|
||||
public function appendMessage(string $folder, string $message, $flags = null, $date = null): bool {
|
||||
if ($date != null) {
|
||||
if ($date instanceof \Carbon\Carbon){
|
||||
$date = $date->format('d-M-Y H:i:s O');
|
||||
}
|
||||
return \imap_append($this->stream, $folder, $message, $flags, $date);
|
||||
}
|
||||
|
||||
return \imap_append($this->stream, $folder, $message, $flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy message set from current folder to other folder
|
||||
* @param string $folder destination folder
|
||||
* @param $from
|
||||
* @param int|null $to if null only one message ($from) is fetched, else it's the
|
||||
* last message, INF means last message available
|
||||
* @param int $uid set to IMAP::ST_UID if you pass message unique identifiers instead of numbers.
|
||||
*
|
||||
* @return bool success
|
||||
*/
|
||||
public function copyMessage(string $folder, $from, $to = null, $uid = IMAP::ST_UID): bool {
|
||||
return \imap_mail_copy($this->stream, $from, $folder, $uid ? IMAP::ST_UID : IMAP::NIL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy multiple messages to the target folder
|
||||
* @param array $messages List of message identifiers
|
||||
* @param string $folder Destination folder
|
||||
* @param int $uid set to IMAP::ST_UID if you pass message unique identifiers instead of numbers.
|
||||
*
|
||||
* @return array|bool Tokens if operation successful, false if an error occurred
|
||||
*/
|
||||
public function copyManyMessages(array $messages, string $folder, $uid = IMAP::ST_UID) {
|
||||
foreach($messages as $msg) {
|
||||
if (!$this->copyMessage($folder, $msg, null, $uid)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return $messages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move a message set from current folder to another folder
|
||||
* @param string $folder destination folder
|
||||
* @param $from
|
||||
* @param int|null $to if null only one message ($from) is fetched, else it's the
|
||||
* last message, INF means last message available
|
||||
* @param int $uid set to IMAP::ST_UID if you pass message unique identifiers instead of numbers.
|
||||
*
|
||||
* @return bool success
|
||||
*/
|
||||
public function moveMessage(string $folder, $from, $to = null, $uid = IMAP::ST_UID): bool {
|
||||
return \imap_mail_move($this->stream, $from, $folder, $uid ? IMAP::ST_UID : IMAP::NIL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Move multiple messages to the target folder
|
||||
* @param array $messages List of message identifiers
|
||||
* @param string $folder Destination folder
|
||||
* @param int $uid set to IMAP::ST_UID if you pass message unique identifiers instead of numbers.
|
||||
*
|
||||
* @return array|bool Tokens if operation successful, false if an error occurred
|
||||
*/
|
||||
public function moveManyMessages(array $messages, string $folder, $uid = IMAP::ST_UID) {
|
||||
foreach($messages as $msg) {
|
||||
if (!$this->moveMessage($folder, $msg, null, $uid)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return $messages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Exchange identification information
|
||||
* Ref.: https://datatracker.ietf.org/doc/html/rfc2971
|
||||
*
|
||||
* @param null $ids
|
||||
* @return array|bool|void|null
|
||||
*
|
||||
* @throws MethodNotSupportedException
|
||||
*/
|
||||
public function ID($ids = null) {
|
||||
throw new MethodNotSupportedException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new folder (and parent folders if needed)
|
||||
* @param string $folder folder name
|
||||
*
|
||||
* @return bool success
|
||||
*/
|
||||
public function createFolder(string $folder): bool {
|
||||
return \imap_createmailbox($this->stream, $folder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename an existing folder
|
||||
* @param string $old old name
|
||||
* @param string $new new name
|
||||
*
|
||||
* @return bool success
|
||||
*/
|
||||
public function renameFolder(string $old, string $new): bool {
|
||||
return \imap_renamemailbox($this->stream, $old, $new);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a folder
|
||||
* @param string $folder folder name
|
||||
*
|
||||
* @return bool success
|
||||
*/
|
||||
public function deleteFolder(string $folder): bool {
|
||||
return \imap_deletemailbox($this->stream, $folder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscribe to a folder
|
||||
* @param string $folder folder name
|
||||
*
|
||||
* @throws MethodNotSupportedException
|
||||
*/
|
||||
public function subscribeFolder(string $folder): bool {
|
||||
throw new MethodNotSupportedException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsubscribe from a folder
|
||||
* @param string $folder folder name
|
||||
*
|
||||
* @throws MethodNotSupportedException
|
||||
*/
|
||||
public function unsubscribeFolder(string $folder): bool {
|
||||
throw new MethodNotSupportedException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply session saved changes to the server
|
||||
*
|
||||
* @return bool success
|
||||
*/
|
||||
public function expunge(): bool {
|
||||
return \imap_expunge($this->stream);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send noop command
|
||||
*
|
||||
* @throws MethodNotSupportedException
|
||||
*/
|
||||
public function noop(): bool {
|
||||
throw new MethodNotSupportedException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send idle command
|
||||
*
|
||||
* @throws MethodNotSupportedException
|
||||
*/
|
||||
public function idle() {
|
||||
throw new MethodNotSupportedException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send done command
|
||||
*
|
||||
* @throws MethodNotSupportedException
|
||||
*/
|
||||
public function done() {
|
||||
throw new MethodNotSupportedException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for matching messages
|
||||
* @param array $params
|
||||
* @param int $uid set to IMAP::ST_UID if you pass message unique identifiers instead of numbers.
|
||||
*
|
||||
* @return array message ids
|
||||
*/
|
||||
public function search(array $params, $uid = IMAP::ST_UID): array {
|
||||
$result = \imap_search($this->stream, $params[0], $uid ? IMAP::ST_UID : IMAP::NIL);
|
||||
if ($result === false) {
|
||||
return [];
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable the debug mode
|
||||
*/
|
||||
public function enableDebug(){
|
||||
$this->debug = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable the debug mode
|
||||
*/
|
||||
public function disableDebug(){
|
||||
$this->debug = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode name.
|
||||
* It converts UTF7-IMAP encoding to UTF-8.
|
||||
*
|
||||
* @param $name
|
||||
*
|
||||
* @return array|false|string|string[]|null
|
||||
*/
|
||||
protected function decodeFolderName($name) {
|
||||
preg_match('#\{(.*)\}(.*)#', $name, $preg);
|
||||
return mb_convert_encoding($preg[2], "UTF-8", "UTF7-IMAP");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getProtocol(): string {
|
||||
return $this->protocol;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the quota level settings, and usage statics per mailbox
|
||||
* @param $username
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getQuota($username): array {
|
||||
return \imap_get_quota($this->stream, 'user.'.$username);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the quota settings per user
|
||||
* @param string $quota_root
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getQuotaRoot(string $quota_root = 'INBOX'): array {
|
||||
return \imap_get_quotaroot($this->stream, $quota_root);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $protocol
|
||||
* @return LegacyProtocol
|
||||
*/
|
||||
public function setProtocol(string $protocol): LegacyProtocol {
|
||||
if (($pos = strpos($protocol, "legacy")) > 0) {
|
||||
$protocol = substr($protocol, 0, ($pos + 2) * -1);
|
||||
}
|
||||
$this->protocol = $protocol;
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
285
vendor/webklex/php-imap/src/Connection/Protocols/Protocol.php
vendored
Normal file
285
vendor/webklex/php-imap/src/Connection/Protocols/Protocol.php
vendored
Normal file
@@ -0,0 +1,285 @@
|
||||
<?php
|
||||
/*
|
||||
* File: ImapProtocol.php
|
||||
* Category: Protocol
|
||||
* Author: M.Goldenbaum
|
||||
* Created: 16.09.20 18:27
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Connection\Protocols;
|
||||
|
||||
use Webklex\PHPIMAP\Exceptions\ConnectionFailedException;
|
||||
use Webklex\PHPIMAP\IMAP;
|
||||
|
||||
/**
|
||||
* Class Protocol
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Connection\Protocols
|
||||
*/
|
||||
abstract class Protocol implements ProtocolInterface {
|
||||
|
||||
/**
|
||||
* Default connection timeout in seconds
|
||||
*/
|
||||
protected $connection_timeout = 30;
|
||||
|
||||
/**
|
||||
* @var boolean
|
||||
*/
|
||||
protected $debug = false;
|
||||
|
||||
/**
|
||||
* @var boolean
|
||||
*/
|
||||
protected $enable_uid_cache = true;
|
||||
|
||||
/**
|
||||
* @var false|\IMAP\Connection|resource
|
||||
*/
|
||||
public $stream = false;
|
||||
|
||||
/**
|
||||
* Connection encryption method
|
||||
* @var mixed $encryption
|
||||
*/
|
||||
protected $encryption = false;
|
||||
|
||||
/**
|
||||
* Set to false to ignore SSL certificate validation
|
||||
* @var bool
|
||||
*/
|
||||
protected $cert_validation = true;
|
||||
|
||||
/**
|
||||
* Proxy settings
|
||||
* @var array
|
||||
*/
|
||||
protected $proxy = [
|
||||
'socket' => null,
|
||||
'request_fulluri' => false,
|
||||
'username' => null,
|
||||
'password' => null,
|
||||
];
|
||||
|
||||
/**
|
||||
* Cache for uid of active folder.
|
||||
*
|
||||
* @var null|array
|
||||
*/
|
||||
protected $uid_cache = null;
|
||||
|
||||
/**
|
||||
* Get an available cryptographic method
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getCryptoMethod() {
|
||||
// Allow the best TLS version(s) we can
|
||||
$cryptoMethod = STREAM_CRYPTO_METHOD_TLS_CLIENT;
|
||||
|
||||
// PHP 5.6.7 dropped inclusion of TLS 1.1 and 1.2 in STREAM_CRYPTO_METHOD_TLS_CLIENT
|
||||
// so add them back in manually if we can
|
||||
if (defined('STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT')) {
|
||||
$cryptoMethod = STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT;
|
||||
}elseif (defined('STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT')) {
|
||||
$cryptoMethod = STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT;
|
||||
}
|
||||
|
||||
return $cryptoMethod;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable SSL certificate validation
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function enableCertValidation() {
|
||||
$this->cert_validation = true;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable SSL certificate validation
|
||||
* @return $this
|
||||
*/
|
||||
public function disableCertValidation() {
|
||||
$this->cert_validation = false;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set SSL certificate validation
|
||||
* @var int $cert_validation
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setCertValidation($cert_validation) {
|
||||
$this->cert_validation = $cert_validation;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should we validate SSL certificate?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getCertValidation() {
|
||||
return $this->cert_validation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set connection proxy settings
|
||||
* @var array $options
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setProxy($options) {
|
||||
foreach ($this->proxy as $key => $val) {
|
||||
if (isset($options[$key])) {
|
||||
$this->proxy[$key] = $options[$key];
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current proxy settings
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getProxy() {
|
||||
return $this->proxy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare socket options
|
||||
* @var string $transport
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function defaultSocketOptions($transport) {
|
||||
$options = [];
|
||||
if ($this->encryption != false) {
|
||||
$options["ssl"] = [
|
||||
'verify_peer_name' => $this->getCertValidation(),
|
||||
'verify_peer' => $this->getCertValidation(),
|
||||
];
|
||||
}
|
||||
|
||||
if ($this->proxy["socket"] != null) {
|
||||
$options[$transport]["proxy"] = $this->proxy["socket"];
|
||||
$options[$transport]["request_fulluri"] = $this->proxy["request_fulluri"];
|
||||
|
||||
if ($this->proxy["username"] != null) {
|
||||
$auth = base64_encode($this->proxy["username"].':'.$this->proxy["password"]);
|
||||
|
||||
$options[$transport]["header"] = [
|
||||
"Proxy-Authorization: Basic $auth"
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new resource stream
|
||||
* @param $transport
|
||||
* @param string $host hostname or IP address of IMAP server
|
||||
* @param int $port of IMAP server, default is 143 (993 for ssl)
|
||||
* @param int $timeout timeout in seconds for initiating session
|
||||
*
|
||||
* @return resource|boolean The socket created.
|
||||
* @throws ConnectionFailedException
|
||||
*/
|
||||
protected function createStream($transport, $host, $port, $timeout) {
|
||||
$socket = "$transport://$host:$port";
|
||||
$stream = stream_socket_client($socket, $errno, $errstr, $timeout,
|
||||
STREAM_CLIENT_CONNECT,
|
||||
stream_context_create($this->defaultSocketOptions($transport))
|
||||
);
|
||||
|
||||
if (!$stream) {
|
||||
throw new ConnectionFailedException($errstr, $errno);
|
||||
}
|
||||
|
||||
if (false === stream_set_timeout($stream, $timeout)) {
|
||||
throw new ConnectionFailedException('Failed to set stream timeout');
|
||||
}
|
||||
|
||||
return $stream;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getConnectionTimeout() {
|
||||
return $this->connection_timeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $connection_timeout
|
||||
* @return Protocol
|
||||
*/
|
||||
public function setConnectionTimeout($connection_timeout) {
|
||||
if ($connection_timeout !== null) {
|
||||
$this->connection_timeout = $connection_timeout;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the UID key string
|
||||
* @param int|string $uid
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getUIDKey($uid) {
|
||||
if ($uid == IMAP::ST_UID || $uid == IMAP::FT_UID) {
|
||||
return "UID";
|
||||
}
|
||||
if (strlen($uid) > 0 && !is_numeric($uid)) {
|
||||
return (string)$uid;
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
public function buildUIDCommand($command, $uid) {
|
||||
return trim($this->getUIDKey($uid)." ".$command);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the uid cache of current active folder
|
||||
*
|
||||
* @param array|null $uids
|
||||
*/
|
||||
public function setUidCache($uids) {
|
||||
if (is_null($uids)) {
|
||||
$this->uid_cache = null;
|
||||
return;
|
||||
}
|
||||
|
||||
$messageNumber = 1;
|
||||
|
||||
$uid_cache = [];
|
||||
foreach ($uids as $uid) {
|
||||
$uid_cache[$messageNumber++] = $uid;
|
||||
}
|
||||
|
||||
$this->uid_cache = $uid_cache;
|
||||
}
|
||||
|
||||
public function enableUidCache() {
|
||||
$this->enable_uid_cache = true;
|
||||
}
|
||||
|
||||
public function disableUidCache() {
|
||||
$this->enable_uid_cache = false;
|
||||
}
|
||||
}
|
||||
408
vendor/webklex/php-imap/src/Connection/Protocols/ProtocolInterface.php
vendored
Normal file
408
vendor/webklex/php-imap/src/Connection/Protocols/ProtocolInterface.php
vendored
Normal file
@@ -0,0 +1,408 @@
|
||||
<?php
|
||||
/*
|
||||
* File: ImapProtocol.php
|
||||
* Category: Protocol
|
||||
* Author: M.Goldenbaum
|
||||
* Created: 16.09.20 18:27
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Connection\Protocols;
|
||||
|
||||
use ErrorException;
|
||||
use Webklex\PHPIMAP\Client;
|
||||
use Webklex\PHPIMAP\Exceptions\AuthFailedException;
|
||||
use Webklex\PHPIMAP\Exceptions\ConnectionFailedException;
|
||||
use Webklex\PHPIMAP\Exceptions\InvalidMessageDateException;
|
||||
use Webklex\PHPIMAP\Exceptions\MessageNotFoundException;
|
||||
use Webklex\PHPIMAP\Exceptions\RuntimeException;
|
||||
use Webklex\PHPIMAP\IMAP;
|
||||
|
||||
/**
|
||||
* Interface ProtocolInterface
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Connection\Protocols
|
||||
*/
|
||||
interface ProtocolInterface {
|
||||
|
||||
/**
|
||||
* Public destructor
|
||||
*/
|
||||
public function __destruct();
|
||||
|
||||
/**
|
||||
* Open a new connection / session
|
||||
* @param string $host hostname or IP address of IMAP server
|
||||
* @param int|null $port of service server
|
||||
*
|
||||
* @throws ErrorException
|
||||
* @throws ConnectionFailedException
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function connect(string $host, $port = null);
|
||||
|
||||
/**
|
||||
* Login to a new session.
|
||||
*
|
||||
* @param string $user username
|
||||
* @param string $password password
|
||||
* @return bool success
|
||||
* @throws AuthFailedException
|
||||
*/
|
||||
public function login(string $user, string $password): bool;
|
||||
|
||||
/**
|
||||
* Authenticate your current session.
|
||||
* @param string $user username
|
||||
* @param string $token access token
|
||||
*
|
||||
* @return bool|mixed
|
||||
* @throws AuthFailedException
|
||||
*/
|
||||
public function authenticate(string $user, string $token);
|
||||
|
||||
/**
|
||||
* Logout of the current server session
|
||||
*
|
||||
* @return bool success
|
||||
*/
|
||||
public function logout(): bool;
|
||||
|
||||
/**
|
||||
* Check if the current session is connected
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function connected(): bool;
|
||||
|
||||
/**
|
||||
* Get an array of available capabilities
|
||||
*
|
||||
* @return array list of capabilities
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function getCapabilities(): array;
|
||||
|
||||
/**
|
||||
* Change the current folder
|
||||
*
|
||||
* @param string $folder change to this folder
|
||||
* @return bool|array see examineOrSelect()
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function selectFolder(string $folder = 'INBOX');
|
||||
|
||||
/**
|
||||
* Examine a given folder
|
||||
*
|
||||
* @param string $folder
|
||||
* @return bool|array
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function examineFolder(string $folder = 'INBOX');
|
||||
|
||||
/**
|
||||
* Fetch message headers
|
||||
* @param array|int $uids
|
||||
* @param string $rfc
|
||||
* @param int|string $uid set to IMAP::ST_UID or any string representing the UID - set to IMAP::ST_MSGN to use
|
||||
* message numbers instead.
|
||||
*
|
||||
* @return array
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function content($uids, string $rfc = "RFC822", $uid = IMAP::ST_UID): array;
|
||||
|
||||
/**
|
||||
* Fetch message headers
|
||||
* @param array|int $uids
|
||||
* @param string $rfc
|
||||
* @param int|string $uid set to IMAP::ST_UID or any string representing the UID - set to IMAP::ST_MSGN to use
|
||||
* message numbers instead.
|
||||
*
|
||||
* @return array
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function headers($uids, string $rfc = "RFC822", $uid = IMAP::ST_UID): array;
|
||||
|
||||
/**
|
||||
* Fetch message flags
|
||||
* @param array|int $uids
|
||||
* @param int|string $uid set to IMAP::ST_UID or any string representing the UID - set to IMAP::ST_MSGN to use
|
||||
* message numbers instead.
|
||||
*
|
||||
* @return array
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function flags($uids, $uid = IMAP::ST_UID): array;
|
||||
|
||||
/**
|
||||
* Get uid for a given id
|
||||
* @param int|null $id message number
|
||||
*
|
||||
* @return array|string message number for given message or all messages as array
|
||||
* @throws MessageNotFoundException
|
||||
*/
|
||||
public function getUid($id = null);
|
||||
|
||||
/**
|
||||
* Get a message number for a uid
|
||||
* @param string $id uid
|
||||
*
|
||||
* @return int message number
|
||||
* @throws MessageNotFoundException
|
||||
*/
|
||||
public function getMessageNumber(string $id): int;
|
||||
|
||||
/**
|
||||
* Get a list of available folders
|
||||
* @param string $reference mailbox reference for list
|
||||
* @param string $folder mailbox / folder name match with wildcards
|
||||
*
|
||||
* @return array mailboxes that matched $folder as array(globalName => array('delim' => .., 'flags' => ..))
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function folders(string $reference = '', string $folder = '*'): array;
|
||||
|
||||
/**
|
||||
* Set message flags
|
||||
* @param array $flags flags to set, add or remove
|
||||
* @param int $from message for items or start message if $to !== null
|
||||
* @param int|null $to if null only one message ($from) is fetched, else it's the
|
||||
* last message, INF means last message available
|
||||
* @param string|null $mode '+' to add flags, '-' to remove flags, everything else sets the flags as given
|
||||
* @param bool $silent if false the return values are the new flags for the wanted messages
|
||||
* @param int|string $uid set to IMAP::ST_UID or any string representing the UID - set to IMAP::ST_MSGN to use
|
||||
* message numbers instead.
|
||||
* @param null|string $item command used to store a flag
|
||||
*
|
||||
* @return bool|array new flags if $silent is false, else true or false depending on success
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function store(array $flags, int $from, $to = null, $mode = null, bool $silent = true, $uid = IMAP::ST_UID, $item = null);
|
||||
|
||||
/**
|
||||
* Append a new message to given folder
|
||||
* @param string $folder name of target folder
|
||||
* @param string $message full message content
|
||||
* @param array|null $flags flags for new message
|
||||
* @param string|null $date date for new message
|
||||
*
|
||||
* @return bool success
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function appendMessage(string $folder, string $message, $flags = null, $date = null): bool;
|
||||
|
||||
/**
|
||||
* Copy message set from current folder to other folder
|
||||
*
|
||||
* @param string $folder destination folder
|
||||
* @param $from
|
||||
* @param int|null $to if null only one message ($from) is fetched, else it's the
|
||||
* last message, INF means last message available
|
||||
* @param int|string $uid set to IMAP::ST_UID or any string representing the UID - set to IMAP::ST_MSGN to use
|
||||
* message numbers instead.
|
||||
*
|
||||
* @return bool success
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function copyMessage(string $folder, $from, $to = null, $uid = IMAP::ST_UID): bool;
|
||||
|
||||
/**
|
||||
* Copy multiple messages to the target folder
|
||||
* @param array<string> $messages List of message identifiers
|
||||
* @param string $folder Destination folder
|
||||
* @param int|string $uid set to IMAP::ST_UID or any string representing the UID - set to IMAP::ST_MSGN to use
|
||||
* message numbers instead.
|
||||
*
|
||||
* @return array|bool Tokens if operation successful, false if an error occurred
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function copyManyMessages(array $messages, string $folder, $uid = IMAP::ST_UID);
|
||||
|
||||
/**
|
||||
* Move a message set from current folder to another folder
|
||||
* @param string $folder destination folder
|
||||
* @param $from
|
||||
* @param int|null $to if null only one message ($from) is fetched, else it's the
|
||||
* last message, INF means last message available
|
||||
* @param int|string $uid set to IMAP::ST_UID or any string representing the UID - set to IMAP::ST_MSGN to use
|
||||
* message numbers instead.
|
||||
*
|
||||
* @return bool success
|
||||
*/
|
||||
public function moveMessage(string $folder, $from, $to = null, $uid = IMAP::ST_UID): bool;
|
||||
|
||||
/**
|
||||
* Move multiple messages to the target folder
|
||||
*
|
||||
* @param array<string> $messages List of message identifiers
|
||||
* @param string $folder Destination folder
|
||||
* @param int|string $uid set to IMAP::ST_UID or any string representing the UID - set to IMAP::ST_MSGN to use
|
||||
* message numbers instead.
|
||||
*
|
||||
* @return array|bool Tokens if operation successful, false if an error occurred
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function moveManyMessages(array $messages, string $folder, $uid = IMAP::ST_UID);
|
||||
|
||||
/**
|
||||
* Exchange identification information
|
||||
* Ref.: https://datatracker.ietf.org/doc/html/rfc2971
|
||||
*
|
||||
* @param null $ids
|
||||
* @return array|bool|void|null
|
||||
*
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function ID($ids = null);
|
||||
|
||||
/**
|
||||
* Create a new folder
|
||||
*
|
||||
* @param string $folder folder name
|
||||
* @return bool success
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function createFolder(string $folder): bool;
|
||||
|
||||
/**
|
||||
* Rename an existing folder
|
||||
*
|
||||
* @param string $old old name
|
||||
* @param string $new new name
|
||||
* @return bool success
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function renameFolder(string $old, string $new): bool;
|
||||
|
||||
/**
|
||||
* Delete a folder
|
||||
*
|
||||
* @param string $folder folder name
|
||||
* @return bool success
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function deleteFolder(string $folder): bool;
|
||||
|
||||
/**
|
||||
* Subscribe to a folder
|
||||
*
|
||||
* @param string $folder folder name
|
||||
* @return bool success
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function subscribeFolder(string $folder): bool;
|
||||
|
||||
/**
|
||||
* Unsubscribe from a folder
|
||||
* @param string $folder folder name
|
||||
*
|
||||
* @return bool success
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function unsubscribeFolder(string $folder): bool;
|
||||
|
||||
/**
|
||||
* Send idle command
|
||||
*
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function idle();
|
||||
|
||||
/**
|
||||
* Send done command
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function done();
|
||||
|
||||
/**
|
||||
* Apply session saved changes to the server
|
||||
*
|
||||
* @return bool success
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function expunge(): bool;
|
||||
|
||||
/**
|
||||
* Retrieve the quota level settings, and usage statics per mailbox
|
||||
* @param $username
|
||||
*
|
||||
* @return array
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function getQuota($username): array;
|
||||
|
||||
/**
|
||||
* Retrieve the quota settings per user
|
||||
*
|
||||
* @param string $quota_root
|
||||
*
|
||||
* @return array
|
||||
* @throws ConnectionFailedException
|
||||
*/
|
||||
public function getQuotaRoot(string $quota_root = 'INBOX'): array;
|
||||
|
||||
/**
|
||||
* Send noop command
|
||||
*
|
||||
* @return bool success
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function noop(): bool;
|
||||
|
||||
/**
|
||||
* Do a search request
|
||||
*
|
||||
* @param array $params
|
||||
* @param int|string $uid set to IMAP::ST_UID or any string representing the UID - set to IMAP::ST_MSGN to use
|
||||
* message numbers instead.
|
||||
*
|
||||
* @return array message ids
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function search(array $params, $uid = IMAP::ST_UID): array;
|
||||
|
||||
/**
|
||||
* Get a message overview
|
||||
* @param string $sequence uid sequence
|
||||
* @param int|string $uid set to IMAP::ST_UID or any string representing the UID - set to IMAP::ST_MSGN to use
|
||||
* message numbers instead.
|
||||
*
|
||||
* @return array
|
||||
* @throws RuntimeException
|
||||
* @throws MessageNotFoundException
|
||||
* @throws InvalidMessageDateException
|
||||
*/
|
||||
public function overview(string $sequence, $uid = IMAP::ST_UID): array;
|
||||
|
||||
/**
|
||||
* Enable the debug mode
|
||||
*/
|
||||
public function enableDebug();
|
||||
|
||||
/**
|
||||
* Disable the debug mode
|
||||
*/
|
||||
public function disableDebug();
|
||||
|
||||
/**
|
||||
* Enable uid caching
|
||||
*/
|
||||
public function enableUidCache();
|
||||
|
||||
/**
|
||||
* Disable uid caching
|
||||
*/
|
||||
public function disableUidCache();
|
||||
|
||||
/**
|
||||
* Set the uid cache of current active folder
|
||||
*
|
||||
* @param array|null $uids
|
||||
*/
|
||||
public function setUidCache($uids);
|
||||
}
|
||||
482
vendor/webklex/php-imap/src/EncodingAliases.php
vendored
Normal file
482
vendor/webklex/php-imap/src/EncodingAliases.php
vendored
Normal file
@@ -0,0 +1,482 @@
|
||||
<?php
|
||||
/*
|
||||
* File: EncodingAliases.php
|
||||
* Category: -
|
||||
* Author: S. Todorov (https://github.com/todorowww)
|
||||
* Created: 23.04.18 14:16
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* Contains email encoding aliases, thta can occur when fetching emails. These sometimes can break icvon()
|
||||
* This file attempts to correct this by using a list of aliases and their mappings to supported iconv() encodings
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP;
|
||||
|
||||
/**
|
||||
* Class EncodingAliases
|
||||
*
|
||||
* @package Webklex\PHPIMAP
|
||||
*/
|
||||
class EncodingAliases {
|
||||
|
||||
/**
|
||||
* Contains email encoding mappings
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $aliases = [
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Email encoding aliases
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Email encoding aliases used to convert to iconv supported charsets
|
||||
|
|
||||
|
|
||||
| This Source Code Form is subject to the terms of the Mozilla Public
|
||||
| License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
| file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
|
||||
| This Original Code has been modified by IBM Corporation.
|
||||
| Modifications made by IBM described herein are
|
||||
| Copyright (c) International Business Machines
|
||||
| Corporation, 1999
|
||||
|
|
||||
| Modifications to Mozilla code or documentation
|
||||
| identified per MPL Section 3.3
|
||||
|
|
||||
| Date Modified by Description of modification
|
||||
| 12/09/1999 IBM Corp. Support for IBM codepages - 850,852,855,857,862,864
|
||||
|
|
||||
| Rule of this file:
|
||||
| 1. key should always be in lower case ascii so we can do case insensitive
|
||||
| comparison in the code faster.
|
||||
| 2. value should be the one used in unicode converter
|
||||
|
|
||||
| 3. If the charset is not used for document charset, but font charset
|
||||
| (e.g. XLFD charset- such as JIS x0201, JIS x0208), don't put here
|
||||
|
|
||||
*/
|
||||
"ascii" => "us-ascii",
|
||||
"us-ascii" => "us-ascii",
|
||||
"ansi_x3.4-1968" => "us-ascii",
|
||||
"646" => "us-ascii",
|
||||
"iso-8859-1" => "ISO-8859-1",
|
||||
"iso-8859-2" => "ISO-8859-2",
|
||||
"iso-8859-3" => "ISO-8859-3",
|
||||
"iso-8859-4" => "ISO-8859-4",
|
||||
"iso-8859-5" => "ISO-8859-5",
|
||||
"iso-8859-6" => "ISO-8859-6",
|
||||
"iso-8859-6-i" => "ISO-8859-6-I",
|
||||
"iso-8859-6-e" => "ISO-8859-6-E",
|
||||
"iso-8859-7" => "ISO-8859-7",
|
||||
"iso-8859-8" => "ISO-8859-8",
|
||||
"iso-8859-8-i" => "ISO-8859-8-I",
|
||||
"iso-8859-8-e" => "ISO-8859-8-E",
|
||||
"iso-8859-9" => "ISO-8859-9",
|
||||
"iso-8859-10" => "ISO-8859-10",
|
||||
"iso-8859-11" => "ISO-8859-11",
|
||||
"iso-8859-13" => "ISO-8859-13",
|
||||
"iso-8859-14" => "ISO-8859-14",
|
||||
"iso-8859-15" => "ISO-8859-15",
|
||||
"iso-8859-16" => "ISO-8859-16",
|
||||
"iso-ir-111" => "ISO-IR-111",
|
||||
"iso-2022-cn" => "ISO-2022-CN",
|
||||
"iso-2022-cn-ext" => "ISO-2022-CN",
|
||||
"iso-2022-kr" => "ISO-2022-KR",
|
||||
"iso-2022-jp" => "ISO-2022-JP",
|
||||
"utf-16be" => "UTF-16BE",
|
||||
"utf-16le" => "UTF-16LE",
|
||||
"utf-16" => "UTF-16",
|
||||
"windows-1250" => "windows-1250",
|
||||
"windows-1251" => "windows-1251",
|
||||
"windows-1252" => "windows-1252",
|
||||
"windows-1253" => "windows-1253",
|
||||
"windows-1254" => "windows-1254",
|
||||
"windows-1255" => "windows-1255",
|
||||
"windows-1256" => "windows-1256",
|
||||
"windows-1257" => "windows-1257",
|
||||
"windows-1258" => "windows-1258",
|
||||
"ibm866" => "IBM866",
|
||||
"ibm850" => "IBM850",
|
||||
"ibm852" => "IBM852",
|
||||
"ibm855" => "IBM855",
|
||||
"ibm857" => "IBM857",
|
||||
"ibm862" => "IBM862",
|
||||
"ibm864" => "IBM864",
|
||||
"utf-8" => "UTF-8",
|
||||
"utf-7" => "UTF-7",
|
||||
"shift_jis" => "Shift_JIS",
|
||||
"big5" => "Big5",
|
||||
"euc-jp" => "EUC-JP",
|
||||
"euc-kr" => "EUC-KR",
|
||||
"gb2312" => "GB2312",
|
||||
"gb18030" => "gb18030",
|
||||
"viscii" => "VISCII",
|
||||
"koi8-r" => "KOI8-R",
|
||||
"koi8_r" => "KOI8-R",
|
||||
"cskoi8r" => "KOI8-R",
|
||||
"koi" => "KOI8-R",
|
||||
"koi8" => "KOI8-R",
|
||||
"koi8-u" => "KOI8-U",
|
||||
"tis-620" => "TIS-620",
|
||||
"t.61-8bit" => "T.61-8bit",
|
||||
"hz-gb-2312" => "HZ-GB-2312",
|
||||
"big5-hkscs" => "Big5-HKSCS",
|
||||
"gbk" => "gbk",
|
||||
"cns11643" => "x-euc-tw",
|
||||
//
|
||||
// Aliases for ISO-8859-1
|
||||
//
|
||||
"latin1" => "ISO-8859-1",
|
||||
"iso_8859-1" => "ISO-8859-1",
|
||||
"iso8859-1" => "ISO-8859-1",
|
||||
"iso8859-2" => "ISO-8859-2",
|
||||
"iso8859-3" => "ISO-8859-3",
|
||||
"iso8859-4" => "ISO-8859-4",
|
||||
"iso8859-5" => "ISO-8859-5",
|
||||
"iso8859-6" => "ISO-8859-6",
|
||||
"iso8859-7" => "ISO-8859-7",
|
||||
"iso8859-8" => "ISO-8859-8",
|
||||
"iso8859-9" => "ISO-8859-9",
|
||||
"iso8859-10" => "ISO-8859-10",
|
||||
"iso8859-11" => "ISO-8859-11",
|
||||
"iso8859-13" => "ISO-8859-13",
|
||||
"iso8859-14" => "ISO-8859-14",
|
||||
"iso8859-15" => "ISO-8859-15",
|
||||
"iso_8859-1:1987" => "ISO-8859-1",
|
||||
"iso-ir-100" => "ISO-8859-1",
|
||||
"l1" => "ISO-8859-1",
|
||||
"ibm819" => "ISO-8859-1",
|
||||
"cp819" => "ISO-8859-1",
|
||||
"csisolatin1" => "ISO-8859-1",
|
||||
//
|
||||
// Aliases for ISO-8859-2
|
||||
//
|
||||
"latin2" => "ISO-8859-2",
|
||||
"iso_8859-2" => "ISO-8859-2",
|
||||
"iso_8859-2:1987" => "ISO-8859-2",
|
||||
"iso-ir-101" => "ISO-8859-2",
|
||||
"l2" => "ISO-8859-2",
|
||||
"csisolatin2" => "ISO-8859-2",
|
||||
//
|
||||
// Aliases for ISO-8859-3
|
||||
//
|
||||
"latin3" => "ISO-8859-3",
|
||||
"iso_8859-3" => "ISO-8859-3",
|
||||
"iso_8859-3:1988" => "ISO-8859-3",
|
||||
"iso-ir-109" => "ISO-8859-3",
|
||||
"l3" => "ISO-8859-3",
|
||||
"csisolatin3" => "ISO-8859-3",
|
||||
//
|
||||
// Aliases for ISO-8859-4
|
||||
//
|
||||
"latin4" => "ISO-8859-4",
|
||||
"iso_8859-4" => "ISO-8859-4",
|
||||
"iso_8859-4:1988" => "ISO-8859-4",
|
||||
"iso-ir-110" => "ISO-8859-4",
|
||||
"l4" => "ISO-8859-4",
|
||||
"csisolatin4" => "ISO-8859-4",
|
||||
//
|
||||
// Aliases for ISO-8859-5
|
||||
//
|
||||
"cyrillic" => "ISO-8859-5",
|
||||
"iso_8859-5" => "ISO-8859-5",
|
||||
"iso_8859-5:1988" => "ISO-8859-5",
|
||||
"iso-ir-144" => "ISO-8859-5",
|
||||
"csisolatincyrillic" => "ISO-8859-5",
|
||||
//
|
||||
// Aliases for ISO-8859-6
|
||||
//
|
||||
"arabic" => "ISO-8859-6",
|
||||
"iso_8859-6" => "ISO-8859-6",
|
||||
"iso_8859-6:1987" => "ISO-8859-6",
|
||||
"iso-ir-127" => "ISO-8859-6",
|
||||
"ecma-114" => "ISO-8859-6",
|
||||
"asmo-708" => "ISO-8859-6",
|
||||
"csisolatinarabic" => "ISO-8859-6",
|
||||
//
|
||||
// Aliases for ISO-8859-6-I
|
||||
//
|
||||
"csiso88596i" => "ISO-8859-6-I",
|
||||
//
|
||||
// Aliases for ISO-8859-6-E",
|
||||
//
|
||||
"csiso88596e" => "ISO-8859-6-E",
|
||||
//
|
||||
// Aliases for ISO-8859-7",
|
||||
//
|
||||
"greek" => "ISO-8859-7",
|
||||
"greek8" => "ISO-8859-7",
|
||||
"sun_eu_greek" => "ISO-8859-7",
|
||||
"iso_8859-7" => "ISO-8859-7",
|
||||
"iso_8859-7:1987" => "ISO-8859-7",
|
||||
"iso-ir-126" => "ISO-8859-7",
|
||||
"elot_928" => "ISO-8859-7",
|
||||
"ecma-118" => "ISO-8859-7",
|
||||
"csisolatingreek" => "ISO-8859-7",
|
||||
//
|
||||
// Aliases for ISO-8859-8",
|
||||
//
|
||||
"hebrew" => "ISO-8859-8",
|
||||
"iso_8859-8" => "ISO-8859-8",
|
||||
"visual" => "ISO-8859-8",
|
||||
"iso_8859-8:1988" => "ISO-8859-8",
|
||||
"iso-ir-138" => "ISO-8859-8",
|
||||
"csisolatinhebrew" => "ISO-8859-8",
|
||||
//
|
||||
// Aliases for ISO-8859-8-I",
|
||||
//
|
||||
"csiso88598i" => "ISO-8859-8-I",
|
||||
"iso-8859-8i" => "ISO-8859-8-I",
|
||||
"logical" => "ISO-8859-8-I",
|
||||
//
|
||||
// Aliases for ISO-8859-8-E",
|
||||
//
|
||||
"csiso88598e" => "ISO-8859-8-E",
|
||||
//
|
||||
// Aliases for ISO-8859-9",
|
||||
//
|
||||
"latin5" => "ISO-8859-9",
|
||||
"iso_8859-9" => "ISO-8859-9",
|
||||
"iso_8859-9:1989" => "ISO-8859-9",
|
||||
"iso-ir-148" => "ISO-8859-9",
|
||||
"l5" => "ISO-8859-9",
|
||||
"csisolatin5" => "ISO-8859-9",
|
||||
//
|
||||
// Aliases for UTF-8",
|
||||
//
|
||||
"unicode-1-1-utf-8" => "UTF-8",
|
||||
// nl_langinfo(CODESET) in HP/UX returns 'utf8' under UTF-8 locales",
|
||||
"utf8" => "UTF-8",
|
||||
//
|
||||
// Aliases for Shift_JIS",
|
||||
//
|
||||
"x-sjis" => "Shift_JIS",
|
||||
"shift-jis" => "Shift_JIS",
|
||||
"ms_kanji" => "Shift_JIS",
|
||||
"csshiftjis" => "Shift_JIS",
|
||||
"windows-31j" => "Shift_JIS",
|
||||
"cp932" => "Shift_JIS",
|
||||
"sjis" => "Shift_JIS",
|
||||
//
|
||||
// Aliases for EUC_JP",
|
||||
//
|
||||
"cseucpkdfmtjapanese" => "EUC-JP",
|
||||
"x-euc-jp" => "EUC-JP",
|
||||
//
|
||||
// Aliases for ISO-2022-JP",
|
||||
//
|
||||
"csiso2022jp" => "ISO-2022-JP",
|
||||
// The following are really not aliases ISO-2022-JP, but sharing the same decoder",
|
||||
"iso-2022-jp-2" => "ISO-2022-JP",
|
||||
"csiso2022jp2" => "ISO-2022-JP",
|
||||
//
|
||||
// Aliases for Big5",
|
||||
//
|
||||
"csbig5" => "Big5",
|
||||
"cn-big5" => "Big5",
|
||||
// x-x-big5 is not really a alias for Big5, add it only for MS FrontPage",
|
||||
"x-x-big5" => "Big5",
|
||||
// Sun Solaris",
|
||||
"zh_tw-big5" => "Big5",
|
||||
//
|
||||
// Aliases for EUC-KR",
|
||||
//
|
||||
"cseuckr" => "EUC-KR",
|
||||
"ks_c_5601-1987" => "EUC-KR",
|
||||
"iso-ir-149" => "EUC-KR",
|
||||
"ks_c_5601-1989" => "EUC-KR",
|
||||
"ksc_5601" => "EUC-KR",
|
||||
"ksc5601" => "EUC-KR",
|
||||
"korean" => "EUC-KR",
|
||||
"csksc56011987" => "EUC-KR",
|
||||
"5601" => "EUC-KR",
|
||||
"windows-949" => "EUC-KR",
|
||||
//
|
||||
// Aliases for GB2312",
|
||||
//
|
||||
// The following are really not aliases GB2312, add them only for MS FrontPage",
|
||||
"gb_2312-80" => "GB2312",
|
||||
"iso-ir-58" => "GB2312",
|
||||
"chinese" => "GB2312",
|
||||
"csiso58gb231280" => "GB2312",
|
||||
"csgb2312" => "GB2312",
|
||||
"zh_cn.euc" => "GB2312",
|
||||
// Sun Solaris",
|
||||
"gb_2312" => "GB2312",
|
||||
//
|
||||
// Aliases for windows-125x ",
|
||||
//
|
||||
"x-cp1250" => "windows-1250",
|
||||
"x-cp1251" => "windows-1251",
|
||||
"x-cp1252" => "windows-1252",
|
||||
"x-cp1253" => "windows-1253",
|
||||
"x-cp1254" => "windows-1254",
|
||||
"x-cp1255" => "windows-1255",
|
||||
"x-cp1256" => "windows-1256",
|
||||
"x-cp1257" => "windows-1257",
|
||||
"x-cp1258" => "windows-1258",
|
||||
//
|
||||
// Aliases for windows-874 ",
|
||||
//
|
||||
"windows-874" => "windows-874",
|
||||
"ibm874" => "windows-874",
|
||||
"dos-874" => "windows-874",
|
||||
//
|
||||
// Aliases for macintosh",
|
||||
//
|
||||
"macintosh" => "macintosh",
|
||||
"x-mac-roman" => "macintosh",
|
||||
"mac" => "macintosh",
|
||||
"csmacintosh" => "macintosh",
|
||||
//
|
||||
// Aliases for IBM866",
|
||||
//
|
||||
"cp866" => "IBM866",
|
||||
"cp-866" => "IBM866",
|
||||
"866" => "IBM866",
|
||||
"csibm866" => "IBM866",
|
||||
//
|
||||
// Aliases for IBM850",
|
||||
//
|
||||
"cp850" => "IBM850",
|
||||
"850" => "IBM850",
|
||||
"csibm850" => "IBM850",
|
||||
//
|
||||
// Aliases for IBM852",
|
||||
//
|
||||
"cp852" => "IBM852",
|
||||
"852" => "IBM852",
|
||||
"csibm852" => "IBM852",
|
||||
//
|
||||
// Aliases for IBM855",
|
||||
//
|
||||
"cp855" => "IBM855",
|
||||
"855" => "IBM855",
|
||||
"csibm855" => "IBM855",
|
||||
//
|
||||
// Aliases for IBM857",
|
||||
//
|
||||
"cp857" => "IBM857",
|
||||
"857" => "IBM857",
|
||||
"csibm857" => "IBM857",
|
||||
//
|
||||
// Aliases for IBM862",
|
||||
//
|
||||
"cp862" => "IBM862",
|
||||
"862" => "IBM862",
|
||||
"csibm862" => "IBM862",
|
||||
//
|
||||
// Aliases for IBM864",
|
||||
//
|
||||
"cp864" => "IBM864",
|
||||
"864" => "IBM864",
|
||||
"csibm864" => "IBM864",
|
||||
"ibm-864" => "IBM864",
|
||||
//
|
||||
// Aliases for T.61-8bit",
|
||||
//
|
||||
"t.61" => "T.61-8bit",
|
||||
"iso-ir-103" => "T.61-8bit",
|
||||
"csiso103t618bit" => "T.61-8bit",
|
||||
//
|
||||
// Aliases for UTF-7",
|
||||
//
|
||||
"x-unicode-2-0-utf-7" => "UTF-7",
|
||||
"unicode-2-0-utf-7" => "UTF-7",
|
||||
"unicode-1-1-utf-7" => "UTF-7",
|
||||
"csunicode11utf7" => "UTF-7",
|
||||
//
|
||||
// Aliases for ISO-10646-UCS-2",
|
||||
//
|
||||
"csunicode" => "UTF-16BE",
|
||||
"csunicode11" => "UTF-16BE",
|
||||
"iso-10646-ucs-basic" => "UTF-16BE",
|
||||
"csunicodeascii" => "UTF-16BE",
|
||||
"iso-10646-unicode-latin1" => "UTF-16BE",
|
||||
"csunicodelatin1" => "UTF-16BE",
|
||||
"iso-10646" => "UTF-16BE",
|
||||
"iso-10646-j-1" => "UTF-16BE",
|
||||
//
|
||||
// Aliases for ISO-8859-10",
|
||||
//
|
||||
"latin6" => "ISO-8859-10",
|
||||
"iso-ir-157" => "ISO-8859-10",
|
||||
"l6" => "ISO-8859-10",
|
||||
// Currently .properties cannot handle : in key",
|
||||
//iso_8859-10:1992" => "ISO-8859-10",
|
||||
"csisolatin6" => "ISO-8859-10",
|
||||
//
|
||||
// Aliases for ISO-8859-15",
|
||||
//
|
||||
"iso_8859-15" => "ISO-8859-15",
|
||||
"csisolatin9" => "ISO-8859-15",
|
||||
"l9" => "ISO-8859-15",
|
||||
//
|
||||
// Aliases for ISO-IR-111",
|
||||
//
|
||||
"ecma-cyrillic" => "ISO-IR-111",
|
||||
"csiso111ecmacyrillic" => "ISO-IR-111",
|
||||
//
|
||||
// Aliases for ISO-2022-KR",
|
||||
//
|
||||
"csiso2022kr" => "ISO-2022-KR",
|
||||
//
|
||||
// Aliases for VISCII",
|
||||
//
|
||||
"csviscii" => "VISCII",
|
||||
//
|
||||
// Aliases for x-euc-tw",
|
||||
//
|
||||
"zh_tw-euc" => "x-euc-tw",
|
||||
//
|
||||
// Following names appears in unix nl_langinfo(CODESET)",
|
||||
// They can be compiled as platform specific if necessary",
|
||||
// DONT put things here if it does not look generic enough (like hp15CN)",
|
||||
//
|
||||
"iso88591" => "ISO-8859-1",
|
||||
"iso88592" => "ISO-8859-2",
|
||||
"iso88593" => "ISO-8859-3",
|
||||
"iso88594" => "ISO-8859-4",
|
||||
"iso88595" => "ISO-8859-5",
|
||||
"iso88596" => "ISO-8859-6",
|
||||
"iso88597" => "ISO-8859-7",
|
||||
"iso88598" => "ISO-8859-8",
|
||||
"iso88599" => "ISO-8859-9",
|
||||
"iso885910" => "ISO-8859-10",
|
||||
"iso885911" => "ISO-8859-11",
|
||||
"iso885912" => "ISO-8859-12",
|
||||
"iso885913" => "ISO-8859-13",
|
||||
"iso885914" => "ISO-8859-14",
|
||||
"iso885915" => "ISO-8859-15",
|
||||
"cp1250" => "windows-1250",
|
||||
"cp1251" => "windows-1251",
|
||||
"cp1252" => "windows-1252",
|
||||
"cp1253" => "windows-1253",
|
||||
"cp1254" => "windows-1254",
|
||||
"cp1255" => "windows-1255",
|
||||
"cp1256" => "windows-1256",
|
||||
"cp1257" => "windows-1257",
|
||||
"cp1258" => "windows-1258",
|
||||
"x-gbk" => "gbk",
|
||||
"windows-936" => "gbk",
|
||||
"ansi-1251" => "windows-1251",
|
||||
];
|
||||
|
||||
/**
|
||||
* Returns proper encoding mapping, if exsists. If it doesn't, return unchanged $encoding
|
||||
* @param string|null $encoding
|
||||
* @param string|null $fallback
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get($encoding, string $fallback = null): string {
|
||||
if (isset(self::$aliases[strtolower($encoding ?? '')])) {
|
||||
return self::$aliases[strtolower($encoding ?? '')];
|
||||
}
|
||||
return $fallback !== null ? $fallback : $encoding;
|
||||
}
|
||||
|
||||
}
|
||||
28
vendor/webklex/php-imap/src/Events/Event.php
vendored
Normal file
28
vendor/webklex/php-imap/src/Events/Event.php
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
/*
|
||||
* File: Event.php
|
||||
* Category: Event
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 25.11.20 22:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Events;
|
||||
|
||||
/**
|
||||
* Class Event
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Events
|
||||
*/
|
||||
abstract class Event {
|
||||
|
||||
/**
|
||||
* Dispatch the event with the given arguments.
|
||||
*/
|
||||
public static function dispatch(): Event {
|
||||
return new static(func_get_args());
|
||||
}
|
||||
}
|
||||
22
vendor/webklex/php-imap/src/Events/FlagDeletedEvent.php
vendored
Normal file
22
vendor/webklex/php-imap/src/Events/FlagDeletedEvent.php
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
/*
|
||||
* File: FlagDeletedEvent.php
|
||||
* Category: Event
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 25.11.20 22:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Events;
|
||||
|
||||
/**
|
||||
* Class FlagDeletedEvent
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Events
|
||||
*/
|
||||
class FlagDeletedEvent extends FlagNewEvent {
|
||||
|
||||
}
|
||||
39
vendor/webklex/php-imap/src/Events/FlagNewEvent.php
vendored
Normal file
39
vendor/webklex/php-imap/src/Events/FlagNewEvent.php
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
/*
|
||||
* File: FlagNewEvent.php
|
||||
* Category: Event
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 25.11.20 22:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Events;
|
||||
|
||||
use Webklex\PHPIMAP\Message;
|
||||
|
||||
/**
|
||||
* Class FlagNewEvent
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Events
|
||||
*/
|
||||
class FlagNewEvent extends Event {
|
||||
|
||||
/** @var Message $message */
|
||||
public $message;
|
||||
|
||||
/** @var string $flag */
|
||||
public $flag;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
* @var mixed[] $arguments
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($arguments) {
|
||||
$this->message = $arguments[0];
|
||||
$this->flag = $arguments[1];
|
||||
}
|
||||
}
|
||||
22
vendor/webklex/php-imap/src/Events/FolderDeletedEvent.php
vendored
Normal file
22
vendor/webklex/php-imap/src/Events/FolderDeletedEvent.php
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
/*
|
||||
* File: FolderDeletedEvent.php
|
||||
* Category: Event
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 25.11.20 22:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Events;
|
||||
|
||||
/**
|
||||
* Class FolderDeletedEvent
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Events
|
||||
*/
|
||||
class FolderDeletedEvent extends FolderNewEvent {
|
||||
|
||||
}
|
||||
38
vendor/webklex/php-imap/src/Events/FolderMovedEvent.php
vendored
Normal file
38
vendor/webklex/php-imap/src/Events/FolderMovedEvent.php
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
/*
|
||||
* File: FolderMovedEvent.php
|
||||
* Category: Event
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 25.11.20 22:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Events;
|
||||
|
||||
use Webklex\PHPIMAP\Folder;
|
||||
|
||||
/**
|
||||
* Class FolderMovedEvent
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Events
|
||||
*/
|
||||
class FolderMovedEvent extends Event {
|
||||
|
||||
/** @var Folder $old_folder */
|
||||
public $old_folder;
|
||||
/** @var Folder $new_folder */
|
||||
public $new_folder;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
* @var Folder[] $folders
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($folders) {
|
||||
$this->old_folder = $folders[0];
|
||||
$this->new_folder = $folders[1];
|
||||
}
|
||||
}
|
||||
35
vendor/webklex/php-imap/src/Events/FolderNewEvent.php
vendored
Normal file
35
vendor/webklex/php-imap/src/Events/FolderNewEvent.php
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
/*
|
||||
* File: FolderNewEvent.php
|
||||
* Category: Event
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 25.11.20 22:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Events;
|
||||
|
||||
use Webklex\PHPIMAP\Folder;
|
||||
|
||||
/**
|
||||
* Class FolderNewEvent
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Events
|
||||
*/
|
||||
class FolderNewEvent extends Event {
|
||||
|
||||
/** @var Folder $folder */
|
||||
public $folder;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
* @var Folder[] $folders
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($folders) {
|
||||
$this->folder = $folders[0];
|
||||
}
|
||||
}
|
||||
22
vendor/webklex/php-imap/src/Events/MessageCopiedEvent.php
vendored
Normal file
22
vendor/webklex/php-imap/src/Events/MessageCopiedEvent.php
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
/*
|
||||
* File: MessageCopiedEvent.php
|
||||
* Category: Event
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 25.11.20 22:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Events;
|
||||
|
||||
/**
|
||||
* Class MessageCopiedEvent
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Events
|
||||
*/
|
||||
class MessageCopiedEvent extends MessageMovedEvent {
|
||||
|
||||
}
|
||||
22
vendor/webklex/php-imap/src/Events/MessageDeletedEvent.php
vendored
Normal file
22
vendor/webklex/php-imap/src/Events/MessageDeletedEvent.php
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
/*
|
||||
* File: MessageDeletedEvent.php
|
||||
* Category: Event
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 25.11.20 22:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Events;
|
||||
|
||||
/**
|
||||
* Class MessageDeletedEvent
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Events
|
||||
*/
|
||||
class MessageDeletedEvent extends MessageNewEvent {
|
||||
|
||||
}
|
||||
38
vendor/webklex/php-imap/src/Events/MessageMovedEvent.php
vendored
Normal file
38
vendor/webklex/php-imap/src/Events/MessageMovedEvent.php
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
/*
|
||||
* File: MessageMovedEvent.php
|
||||
* Category: Event
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 25.11.20 22:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Events;
|
||||
|
||||
use Webklex\PHPIMAP\Message;
|
||||
|
||||
/**
|
||||
* Class MessageMovedEvent
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Events
|
||||
*/
|
||||
class MessageMovedEvent extends Event {
|
||||
|
||||
/** @var Message $old_message */
|
||||
public $old_message;
|
||||
/** @var Message $new_message */
|
||||
public $new_message;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
* @var Message[] $messages
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($messages) {
|
||||
$this->old_message = $messages[0];
|
||||
$this->new_message = $messages[1];
|
||||
}
|
||||
}
|
||||
35
vendor/webklex/php-imap/src/Events/MessageNewEvent.php
vendored
Normal file
35
vendor/webklex/php-imap/src/Events/MessageNewEvent.php
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
/*
|
||||
* File: MessageNewEvent.php
|
||||
* Category: Event
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 25.11.20 22:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Events;
|
||||
|
||||
use Webklex\PHPIMAP\Message;
|
||||
|
||||
/**
|
||||
* Class MessageNewEvent
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Events
|
||||
*/
|
||||
class MessageNewEvent extends Event {
|
||||
|
||||
/** @var Message $message */
|
||||
public $message;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
* @var Message[] $messages
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($messages) {
|
||||
$this->message = $messages[0];
|
||||
}
|
||||
}
|
||||
22
vendor/webklex/php-imap/src/Events/MessageRestoredEvent.php
vendored
Normal file
22
vendor/webklex/php-imap/src/Events/MessageRestoredEvent.php
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
/*
|
||||
* File: MessageRestoredEvent.php
|
||||
* Category: Event
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 25.11.20 22:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Events;
|
||||
|
||||
/**
|
||||
* Class MessageRestoredEvent
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Events
|
||||
*/
|
||||
class MessageRestoredEvent extends MessageNewEvent {
|
||||
|
||||
}
|
||||
24
vendor/webklex/php-imap/src/Exceptions/AuthFailedException.php
vendored
Normal file
24
vendor/webklex/php-imap/src/Exceptions/AuthFailedException.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/*
|
||||
* File: AuthFailedException.php
|
||||
* Category: Exception
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 19.01.17 22:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Exceptions;
|
||||
|
||||
use \Exception;
|
||||
|
||||
/**
|
||||
* Class AuthFailedException
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Exceptions
|
||||
*/
|
||||
class AuthFailedException extends Exception {
|
||||
|
||||
}
|
||||
24
vendor/webklex/php-imap/src/Exceptions/ConnectionFailedException.php
vendored
Normal file
24
vendor/webklex/php-imap/src/Exceptions/ConnectionFailedException.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/*
|
||||
* File: ConnectionFailedException.php
|
||||
* Category: Exception
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 19.01.17 22:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Exceptions;
|
||||
|
||||
use \Exception;
|
||||
|
||||
/**
|
||||
* Class ConnectionFailedException
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Exceptions
|
||||
*/
|
||||
class ConnectionFailedException extends Exception {
|
||||
|
||||
}
|
||||
24
vendor/webklex/php-imap/src/Exceptions/EventNotFoundException.php
vendored
Normal file
24
vendor/webklex/php-imap/src/Exceptions/EventNotFoundException.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/*
|
||||
* File: EventNotFoundException.php
|
||||
* Category: Exception
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 05.03.18 23:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Exceptions;
|
||||
|
||||
use \Exception;
|
||||
|
||||
/**
|
||||
* Class EventNotFoundException
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Exceptions
|
||||
*/
|
||||
class EventNotFoundException extends Exception {
|
||||
|
||||
}
|
||||
24
vendor/webklex/php-imap/src/Exceptions/FolderFetchingException.php
vendored
Normal file
24
vendor/webklex/php-imap/src/Exceptions/FolderFetchingException.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/*
|
||||
* File: FolderFetchingException.php
|
||||
* Category: Exception
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 05.03.18 23:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Exceptions;
|
||||
|
||||
use \Exception;
|
||||
|
||||
/**
|
||||
* Class FolderFetchingException
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Exceptions
|
||||
*/
|
||||
class FolderFetchingException extends Exception {
|
||||
|
||||
}
|
||||
24
vendor/webklex/php-imap/src/Exceptions/GetMessagesFailedException.php
vendored
Normal file
24
vendor/webklex/php-imap/src/Exceptions/GetMessagesFailedException.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/*
|
||||
* File: GetMessagesFailedException.php
|
||||
* Category: Exception
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 19.01.17 22:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Exceptions;
|
||||
|
||||
use \Exception;
|
||||
|
||||
/**
|
||||
* Class GetMessagesFailedException
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Exceptions
|
||||
*/
|
||||
class GetMessagesFailedException extends Exception {
|
||||
|
||||
}
|
||||
24
vendor/webklex/php-imap/src/Exceptions/InvalidMessageDateException.php
vendored
Normal file
24
vendor/webklex/php-imap/src/Exceptions/InvalidMessageDateException.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/*
|
||||
* File: InvalidMessageDateException.php
|
||||
* Category: Exception
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 10.03.19 04:31
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Exceptions;
|
||||
|
||||
use \Exception;
|
||||
|
||||
/**
|
||||
* Class InvalidMessageDateException
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Exceptions
|
||||
*/
|
||||
class InvalidMessageDateException extends Exception {
|
||||
|
||||
}
|
||||
24
vendor/webklex/php-imap/src/Exceptions/InvalidWhereQueryCriteriaException.php
vendored
Normal file
24
vendor/webklex/php-imap/src/Exceptions/InvalidWhereQueryCriteriaException.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/*
|
||||
* File: InvalidWhereQueryCriteriaException.php
|
||||
* Category: Exception
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 21.07.18 19:04
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Exceptions;
|
||||
|
||||
use \Exception;
|
||||
|
||||
/**
|
||||
* Class InvalidWhereQueryCriteriaException
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Exceptions
|
||||
*/
|
||||
class InvalidWhereQueryCriteriaException extends Exception {
|
||||
|
||||
}
|
||||
24
vendor/webklex/php-imap/src/Exceptions/MaskNotFoundException.php
vendored
Normal file
24
vendor/webklex/php-imap/src/Exceptions/MaskNotFoundException.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/*
|
||||
* File: MaskNotFoundException.php
|
||||
* Category: Exception
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 05.03.18 23:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Exceptions;
|
||||
|
||||
use \Exception;
|
||||
|
||||
/**
|
||||
* Class MaskNotFoundException
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Exceptions
|
||||
*/
|
||||
class MaskNotFoundException extends Exception {
|
||||
|
||||
}
|
||||
24
vendor/webklex/php-imap/src/Exceptions/MessageContentFetchingException.php
vendored
Normal file
24
vendor/webklex/php-imap/src/Exceptions/MessageContentFetchingException.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/*
|
||||
* File: MessageContentFetchingException.php
|
||||
* Category: Exception
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 05.03.18 23:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Exceptions;
|
||||
|
||||
use \Exception;
|
||||
|
||||
/**
|
||||
* Class MessageContentFetchingException
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Exceptions
|
||||
*/
|
||||
class MessageContentFetchingException extends Exception {
|
||||
|
||||
}
|
||||
24
vendor/webklex/php-imap/src/Exceptions/MessageFlagException.php
vendored
Normal file
24
vendor/webklex/php-imap/src/Exceptions/MessageFlagException.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/*
|
||||
* File: MessageFlagException.php
|
||||
* Category: Exception
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 02.01.21 02:47
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Exceptions;
|
||||
|
||||
use \Exception;
|
||||
|
||||
/**
|
||||
* Class MessageFlagException
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Exceptions
|
||||
*/
|
||||
class MessageFlagException extends Exception {
|
||||
|
||||
}
|
||||
24
vendor/webklex/php-imap/src/Exceptions/MessageHeaderFetchingException.php
vendored
Normal file
24
vendor/webklex/php-imap/src/Exceptions/MessageHeaderFetchingException.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/*
|
||||
* File: MessageHeaderFetchingException.php
|
||||
* Category: Exception
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 05.03.18 23:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Exceptions;
|
||||
|
||||
use \Exception;
|
||||
|
||||
/**
|
||||
* Class MessageHeaderFetchingException
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Exceptions
|
||||
*/
|
||||
class MessageHeaderFetchingException extends Exception {
|
||||
|
||||
}
|
||||
24
vendor/webklex/php-imap/src/Exceptions/MessageNotFoundException.php
vendored
Normal file
24
vendor/webklex/php-imap/src/Exceptions/MessageNotFoundException.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/*
|
||||
* File: MessageNotFoundException.php
|
||||
* Category: Exception
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 25.01.21 18:19
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Exceptions;
|
||||
|
||||
use \Exception;
|
||||
|
||||
/**
|
||||
* Class MessageNotFoundException
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Exceptions
|
||||
*/
|
||||
class MessageNotFoundException extends Exception {
|
||||
|
||||
}
|
||||
24
vendor/webklex/php-imap/src/Exceptions/MessageSearchValidationException.php
vendored
Normal file
24
vendor/webklex/php-imap/src/Exceptions/MessageSearchValidationException.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/*
|
||||
* File: MessageSearchValidationException.php
|
||||
* Category: Exception
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 05.03.18 23:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Exceptions;
|
||||
|
||||
use \Exception;
|
||||
|
||||
/**
|
||||
* Class MessageSearchValidationException
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Exceptions
|
||||
*/
|
||||
class MessageSearchValidationException extends Exception {
|
||||
|
||||
}
|
||||
24
vendor/webklex/php-imap/src/Exceptions/MethodNotFoundException.php
vendored
Normal file
24
vendor/webklex/php-imap/src/Exceptions/MethodNotFoundException.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/*
|
||||
* File: MethodNotFoundException.php
|
||||
* Category: Exception
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 05.03.18 23:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Exceptions;
|
||||
|
||||
use \Exception;
|
||||
|
||||
/**
|
||||
* Class MethodNotFoundException
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Exceptions
|
||||
*/
|
||||
class MethodNotFoundException extends Exception {
|
||||
|
||||
}
|
||||
24
vendor/webklex/php-imap/src/Exceptions/MethodNotSupportedException.php
vendored
Normal file
24
vendor/webklex/php-imap/src/Exceptions/MethodNotSupportedException.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/*
|
||||
* File: MethodNotSupportedException.php
|
||||
* Category: Exception
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 05.03.18 23:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Exceptions;
|
||||
|
||||
use \Exception;
|
||||
|
||||
/**
|
||||
* Class MethodNotSupportedException
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Exceptions
|
||||
*/
|
||||
class MethodNotSupportedException extends Exception {
|
||||
|
||||
}
|
||||
24
vendor/webklex/php-imap/src/Exceptions/NotSupportedCapabilityException.php
vendored
Normal file
24
vendor/webklex/php-imap/src/Exceptions/NotSupportedCapabilityException.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/*
|
||||
* File: RuntimeException.php
|
||||
* Category: Exception
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 19.01.17 22:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Exceptions;
|
||||
|
||||
use \Exception;
|
||||
|
||||
/**
|
||||
* Class NotSupportedCapabilityException
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Exceptions
|
||||
*/
|
||||
class NotSupportedCapabilityException extends Exception {
|
||||
|
||||
}
|
||||
24
vendor/webklex/php-imap/src/Exceptions/ProtocolNotSupportedException.php
vendored
Normal file
24
vendor/webklex/php-imap/src/Exceptions/ProtocolNotSupportedException.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/*
|
||||
* File: ProtocolNotSupportedException.php
|
||||
* Category: Exception
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 19.01.17 22:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Exceptions;
|
||||
|
||||
use \Exception;
|
||||
|
||||
/**
|
||||
* Class ProtocolNotSupportedException
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Exceptions
|
||||
*/
|
||||
class ProtocolNotSupportedException extends Exception {
|
||||
|
||||
}
|
||||
24
vendor/webklex/php-imap/src/Exceptions/RuntimeException.php
vendored
Normal file
24
vendor/webklex/php-imap/src/Exceptions/RuntimeException.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/*
|
||||
* File: RuntimeException.php
|
||||
* Category: Exception
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 19.01.17 22:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Exceptions;
|
||||
|
||||
use \Exception;
|
||||
|
||||
/**
|
||||
* Class RuntimeException
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Exceptions
|
||||
*/
|
||||
class RuntimeException extends Exception {
|
||||
|
||||
}
|
||||
475
vendor/webklex/php-imap/src/Folder.php
vendored
Executable file
475
vendor/webklex/php-imap/src/Folder.php
vendored
Executable file
@@ -0,0 +1,475 @@
|
||||
<?php
|
||||
/*
|
||||
* File: Folder.php
|
||||
* Category: -
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 19.01.17 22:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Webklex\PHPIMAP\Exceptions\ConnectionFailedException;
|
||||
use Webklex\PHPIMAP\Exceptions\NotSupportedCapabilityException;
|
||||
use Webklex\PHPIMAP\Exceptions\RuntimeException;
|
||||
use Webklex\PHPIMAP\Query\WhereQuery;
|
||||
use Webklex\PHPIMAP\Support\FolderCollection;
|
||||
use Webklex\PHPIMAP\Traits\HasEvents;
|
||||
|
||||
/**
|
||||
* Class Folder
|
||||
*
|
||||
* @package Webklex\PHPIMAP
|
||||
*/
|
||||
class Folder {
|
||||
use HasEvents;
|
||||
|
||||
/**
|
||||
* Client instance
|
||||
*
|
||||
* @var Client
|
||||
*/
|
||||
protected $client;
|
||||
|
||||
/**
|
||||
* Folder full path
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $path;
|
||||
|
||||
/**
|
||||
* Folder name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $name;
|
||||
|
||||
/**
|
||||
* Folder fullname
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $full_name;
|
||||
|
||||
/**
|
||||
* Children folders
|
||||
*
|
||||
* @var FolderCollection|array
|
||||
*/
|
||||
public $children = [];
|
||||
|
||||
/**
|
||||
* Delimiter for folder
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $delimiter;
|
||||
|
||||
/**
|
||||
* Indicates if folder can't containg any "children".
|
||||
* CreateFolder won't work on this folder.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
public $no_inferiors;
|
||||
|
||||
/**
|
||||
* Indicates if folder is only container, not a mailbox - you can't open it.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
public $no_select;
|
||||
|
||||
/**
|
||||
* Indicates if folder is marked. This means that it may contain new messages since the last time it was checked.
|
||||
* Not provided by all IMAP servers.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
public $marked;
|
||||
|
||||
/**
|
||||
* Indicates if folder containg any "children".
|
||||
* Not provided by all IMAP servers.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
public $has_children;
|
||||
|
||||
/**
|
||||
* Indicates if folder refers to other.
|
||||
* Not provided by all IMAP servers.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
public $referral;
|
||||
|
||||
/** @var array */
|
||||
public $status;
|
||||
|
||||
/**
|
||||
* Folder constructor.
|
||||
* @param Client $client
|
||||
* @param string $folder_name
|
||||
* @param string $delimiter
|
||||
* @param string[] $attributes
|
||||
*/
|
||||
public function __construct(Client $client, string $folder_name, string $delimiter, array $attributes) {
|
||||
$this->client = $client;
|
||||
|
||||
$this->events["message"] = $client->getDefaultEvents("message");
|
||||
$this->events["folder"] = $client->getDefaultEvents("folder");
|
||||
|
||||
$this->setDelimiter($delimiter);
|
||||
$this->path = $folder_name;
|
||||
$this->full_name = $this->decodeName($folder_name);
|
||||
$this->name = $this->getSimpleName($this->delimiter, $this->full_name);
|
||||
|
||||
$this->parseAttributes($attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a new search query instance
|
||||
* @param string[] $extensions
|
||||
*
|
||||
* @return WhereQuery
|
||||
* @throws Exceptions\ConnectionFailedException
|
||||
* @throws Exceptions\RuntimeException
|
||||
*/
|
||||
public function query(array $extensions = []): WhereQuery {
|
||||
$this->getClient()->checkConnection();
|
||||
$this->getClient()->openFolder($this->path);
|
||||
$extensions = count($extensions) > 0 ? $extensions : $this->getClient()->extensions;
|
||||
|
||||
return new WhereQuery($this->getClient(), $extensions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a new search query instance
|
||||
* @param string[] $extensions
|
||||
*
|
||||
* @return WhereQuery
|
||||
* @throws Exceptions\ConnectionFailedException
|
||||
* @throws Exceptions\RuntimeException
|
||||
*/
|
||||
public function search(array $extensions = []): WhereQuery {
|
||||
return $this->query($extensions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a new search query instance
|
||||
* @param string[] $extensions
|
||||
*
|
||||
* @return WhereQuery
|
||||
* @throws Exceptions\ConnectionFailedException
|
||||
* @throws Exceptions\RuntimeException
|
||||
*/
|
||||
public function messages(array $extensions = []): WhereQuery {
|
||||
return $this->query($extensions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if folder has children.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasChildren(): bool {
|
||||
return $this->has_children;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set children.
|
||||
* @param FolderCollection|array $children
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setChildren($children = []): Folder {
|
||||
$this->children = $children;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode name.
|
||||
* It converts UTF7-IMAP encoding to UTF-8.
|
||||
* @param $name
|
||||
*
|
||||
* @return array|false|string|string[]|null
|
||||
*/
|
||||
protected function decodeName($name) {
|
||||
return mb_convert_encoding($name, "UTF-8", "UTF7-IMAP");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get simple name (without parent folders).
|
||||
* @param $delimiter
|
||||
* @param $full_name
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
protected function getSimpleName($delimiter, $full_name) {
|
||||
$arr = explode($delimiter, $full_name);
|
||||
|
||||
return end($arr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse attributes and set it to object properties.
|
||||
* @param $attributes
|
||||
*/
|
||||
protected function parseAttributes($attributes) {
|
||||
$this->no_inferiors = in_array('\NoInferiors', $attributes);
|
||||
$this->no_select = in_array('\NoSelect', $attributes);
|
||||
$this->marked = in_array('\Marked', $attributes);
|
||||
$this->referral = in_array('\Referral', $attributes);
|
||||
$this->has_children = in_array('\HasChildren', $attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Move or rename the current folder
|
||||
* @param string $new_name
|
||||
* @param boolean $expunge
|
||||
*
|
||||
* @return bool
|
||||
* @throws ConnectionFailedException
|
||||
* @throws Exceptions\EventNotFoundException
|
||||
* @throws Exceptions\FolderFetchingException
|
||||
* @throws Exceptions\RuntimeException
|
||||
*/
|
||||
public function move(string $new_name, bool $expunge = true): bool {
|
||||
$this->client->checkConnection();
|
||||
$status = $this->client->getConnection()->renameFolder($this->full_name, $new_name);
|
||||
if($expunge) $this->client->expunge();
|
||||
|
||||
$folder = $this->client->getFolder($new_name);
|
||||
$event = $this->getEvent("folder", "moved");
|
||||
$event::dispatch($this, $folder);
|
||||
|
||||
return $status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a message overview
|
||||
* @param string|null $sequence uid sequence
|
||||
*
|
||||
* @return array
|
||||
* @throws ConnectionFailedException
|
||||
* @throws Exceptions\InvalidMessageDateException
|
||||
* @throws Exceptions\MessageNotFoundException
|
||||
* @throws Exceptions\RuntimeException
|
||||
*/
|
||||
public function overview(string $sequence = null): array {
|
||||
$this->client->openFolder($this->path);
|
||||
$sequence = $sequence === null ? "1:*" : $sequence;
|
||||
$uid = ClientManager::get('options.sequence', IMAP::ST_MSGN) == IMAP::ST_UID;
|
||||
return $this->client->getConnection()->overview($sequence, $uid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Append a string message to the current mailbox
|
||||
* @param string $message
|
||||
* @param array|null $options
|
||||
* @param string|null|Carbon $internal_date
|
||||
*
|
||||
* @return bool
|
||||
* @throws Exceptions\ConnectionFailedException
|
||||
* @throws Exceptions\RuntimeException
|
||||
*/
|
||||
public function appendMessage(string $message, array $options = null, $internal_date = null): bool {
|
||||
/**
|
||||
* Check if $internal_date is parsed. If it is null it should not be set. Otherwise, the message can't be stored.
|
||||
* If this parameter is set, it will set the INTERNALDATE on the appended message. The parameter should be a
|
||||
* date string that conforms to the rfc2060 specifications for a date_time value or be a Carbon object.
|
||||
*/
|
||||
|
||||
if ($internal_date instanceof Carbon){
|
||||
$internal_date = $internal_date->format('d-M-Y H:i:s O');
|
||||
}
|
||||
|
||||
return $this->client->getConnection()->appendMessage($this->path, $message, $options, $internal_date);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename the current folder
|
||||
* @param string $new_name
|
||||
* @param boolean $expunge
|
||||
*
|
||||
* @return bool
|
||||
* @throws ConnectionFailedException
|
||||
* @throws Exceptions\EventNotFoundException
|
||||
* @throws Exceptions\FolderFetchingException
|
||||
* @throws Exceptions\RuntimeException
|
||||
*/
|
||||
public function rename(string $new_name, bool $expunge = true): bool {
|
||||
return $this->move($new_name, $expunge);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the current folder
|
||||
* @param boolean $expunge
|
||||
*
|
||||
* @return bool
|
||||
* @throws Exceptions\ConnectionFailedException
|
||||
* @throws Exceptions\RuntimeException
|
||||
* @throws Exceptions\EventNotFoundException
|
||||
*/
|
||||
public function delete(bool $expunge = true): bool {
|
||||
$status = $this->client->getConnection()->deleteFolder($this->path);
|
||||
if($expunge) $this->client->expunge();
|
||||
|
||||
$event = $this->getEvent("folder", "deleted");
|
||||
$event::dispatch($this);
|
||||
|
||||
return $status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscribe the current folder
|
||||
*
|
||||
* @return bool
|
||||
* @throws Exceptions\ConnectionFailedException
|
||||
* @throws Exceptions\RuntimeException
|
||||
*/
|
||||
public function subscribe(): bool {
|
||||
$this->client->openFolder($this->path);
|
||||
return $this->client->getConnection()->subscribeFolder($this->path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsubscribe the current folder
|
||||
*
|
||||
* @return bool
|
||||
* @throws Exceptions\ConnectionFailedException
|
||||
* @throws Exceptions\RuntimeException
|
||||
*/
|
||||
public function unsubscribe(): bool {
|
||||
$this->client->openFolder($this->path);
|
||||
return $this->client->getConnection()->unsubscribeFolder($this->path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Idle the current connection
|
||||
* @param callable $callback
|
||||
* @param integer $timeout max 1740 seconds - recommended by rfc2177 §3. Should not be lower than the servers "* OK Still here" message interval
|
||||
* @param boolean $auto_reconnect try to reconnect on connection close (@deprecated is no longer required)
|
||||
*
|
||||
* @throws ConnectionFailedException
|
||||
* @throws Exceptions\InvalidMessageDateException
|
||||
* @throws Exceptions\MessageContentFetchingException
|
||||
* @throws Exceptions\MessageHeaderFetchingException
|
||||
* @throws Exceptions\RuntimeException
|
||||
* @throws Exceptions\EventNotFoundException
|
||||
* @throws Exceptions\MessageFlagException
|
||||
* @throws Exceptions\MessageNotFoundException
|
||||
* @throws Exceptions\NotSupportedCapabilityException
|
||||
*/
|
||||
public function idle(callable $callback, int $timeout = 300, bool $auto_reconnect = false) {
|
||||
$this->client->setTimeout($timeout);
|
||||
if (!in_array("IDLE", $this->client->getConnection()->getCapabilities())) {
|
||||
throw new NotSupportedCapabilityException("IMAP server does not support IDLE");
|
||||
}
|
||||
$this->client->openFolder($this->path, true);
|
||||
$connection = $this->client->getConnection();
|
||||
$connection->idle();
|
||||
|
||||
$sequence = ClientManager::get('options.sequence', IMAP::ST_MSGN);
|
||||
|
||||
while (true) {
|
||||
try {
|
||||
// This polymorphic call is fine - Protocol::idle() will throw an exception beforehand
|
||||
$line = $connection->nextLine();
|
||||
|
||||
if (($pos = strpos($line, "EXISTS")) !== false) {
|
||||
$connection->done();
|
||||
$msgn = (int) substr($line, 2, $pos -2);
|
||||
|
||||
$this->client->openFolder($this->path, true);
|
||||
$message = $this->query()->getMessageByMsgn($msgn);
|
||||
$message->setSequence($sequence);
|
||||
$callback($message);
|
||||
|
||||
$event = $this->getEvent("message", "new");
|
||||
$event::dispatch($message);
|
||||
$connection->idle();
|
||||
} elseif (strpos($line, "OK") === false) {
|
||||
$connection->done();
|
||||
$connection->idle();
|
||||
}
|
||||
}catch (Exceptions\RuntimeException $e) {
|
||||
if(strpos($e->getMessage(), "empty response") >= 0 && $connection->connected()) {
|
||||
$connection->done();
|
||||
$connection->idle();
|
||||
continue;
|
||||
}
|
||||
if(strpos($e->getMessage(), "connection closed") === false) {
|
||||
throw $e;
|
||||
}
|
||||
|
||||
$this->client->reconnect();
|
||||
$this->client->openFolder($this->path, true);
|
||||
|
||||
$connection = $this->client->getConnection();
|
||||
$connection->idle();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get folder status information
|
||||
*
|
||||
* @return array
|
||||
* @throws Exceptions\ConnectionFailedException
|
||||
* @throws Exceptions\RuntimeException
|
||||
*/
|
||||
public function getStatus(): array {
|
||||
return $this->examine();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws RuntimeException
|
||||
* @throws ConnectionFailedException
|
||||
*/
|
||||
public function loadStatus(): Folder
|
||||
{
|
||||
$this->status = $this->getStatus();
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Examine the current folder
|
||||
*
|
||||
* @return array
|
||||
* @throws Exceptions\ConnectionFailedException
|
||||
* @throws Exceptions\RuntimeException
|
||||
*/
|
||||
public function examine(): array {
|
||||
$result = $this->client->getConnection()->examineFolder($this->path);
|
||||
return is_array($result) ? $result : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current Client instance
|
||||
*
|
||||
* @return Client
|
||||
*/
|
||||
public function getClient(): Client {
|
||||
return $this->client;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the delimiter
|
||||
* @param $delimiter
|
||||
*/
|
||||
public function setDelimiter($delimiter){
|
||||
if(in_array($delimiter, [null, '', ' ', false]) === true) {
|
||||
$delimiter = ClientManager::get('options.delimiter', '/');
|
||||
}
|
||||
|
||||
$this->delimiter = $delimiter;
|
||||
}
|
||||
}
|
||||
756
vendor/webklex/php-imap/src/Header.php
vendored
Normal file
756
vendor/webklex/php-imap/src/Header.php
vendored
Normal file
@@ -0,0 +1,756 @@
|
||||
<?php
|
||||
/*
|
||||
* File: Header.php
|
||||
* Category: -
|
||||
* Author: M.Goldenbaum
|
||||
* Created: 17.09.20 20:38
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP;
|
||||
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Webklex\PHPIMAP\Exceptions\InvalidMessageDateException;
|
||||
use Webklex\PHPIMAP\Exceptions\MethodNotFoundException;
|
||||
|
||||
/**
|
||||
* Class Header
|
||||
*
|
||||
* @package Webklex\PHPIMAP
|
||||
*/
|
||||
class Header {
|
||||
|
||||
/**
|
||||
* Raw header
|
||||
*
|
||||
* @var string $raw
|
||||
*/
|
||||
public $raw = "";
|
||||
|
||||
/**
|
||||
* Attribute holder
|
||||
*
|
||||
* @var Attribute[]|array $attributes
|
||||
*/
|
||||
protected $attributes = [];
|
||||
|
||||
/**
|
||||
* Config holder
|
||||
*
|
||||
* @var array $config
|
||||
*/
|
||||
protected $config = [];
|
||||
|
||||
/**
|
||||
* Fallback Encoding
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $fallback_encoding = 'UTF-8';
|
||||
|
||||
/**
|
||||
* Convert parsed values to attributes
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $attributize = false;
|
||||
|
||||
/**
|
||||
* Header constructor.
|
||||
* @param string $raw_header
|
||||
* @param boolean $attributize
|
||||
*
|
||||
* @throws InvalidMessageDateException
|
||||
*/
|
||||
public function __construct(string $raw_header, bool $attributize = true) {
|
||||
$this->raw = $raw_header;
|
||||
$this->config = ClientManager::get('options');
|
||||
$this->attributize = $attributize;
|
||||
$this->parse();
|
||||
}
|
||||
|
||||
/**
|
||||
* Call dynamic attribute setter and getter methods
|
||||
* @param string $method
|
||||
* @param array $arguments
|
||||
*
|
||||
* @return Attribute|mixed
|
||||
* @throws MethodNotFoundException
|
||||
*/
|
||||
public function __call(string $method, array $arguments) {
|
||||
if (strtolower(substr($method, 0, 3)) === 'get') {
|
||||
$name = preg_replace('/(.)(?=[A-Z])/u', '$1_', substr(strtolower($method), 3));
|
||||
|
||||
if (in_array($name, array_keys($this->attributes))) {
|
||||
return $this->attributes[$name];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
throw new MethodNotFoundException("Method " . self::class . '::' . $method . '() is not supported');
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic getter
|
||||
* @param $name
|
||||
*
|
||||
* @return Attribute|null
|
||||
*/
|
||||
public function __get($name) {
|
||||
return $this->get($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a specific header attribute
|
||||
* @param $name
|
||||
*
|
||||
* @return Attribute|mixed
|
||||
*/
|
||||
public function get($name) {
|
||||
if (isset($this->attributes[$name])) {
|
||||
return $this->attributes[$name];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a specific attribute
|
||||
* @param string $name
|
||||
* @param array|mixed $value
|
||||
* @param boolean $strict
|
||||
*
|
||||
* @return Attribute
|
||||
*/
|
||||
public function set(string $name, $value, bool $strict = false) {
|
||||
if (isset($this->attributes[$name]) && $strict === false) {
|
||||
if ($this->attributize) {
|
||||
$this->attributes[$name]->add($value, true);
|
||||
} else {
|
||||
if (isset($this->attributes[$name])) {
|
||||
if (!is_array($this->attributes[$name])) {
|
||||
$this->attributes[$name] = [$this->attributes[$name], $value];
|
||||
} else {
|
||||
$this->attributes[$name][] = $value;
|
||||
}
|
||||
} else {
|
||||
$this->attributes[$name] = $value;
|
||||
}
|
||||
}
|
||||
} elseif (!$this->attributize) {
|
||||
$this->attributes[$name] = $value;
|
||||
} else {
|
||||
$this->attributes[$name] = new Attribute($name, $value);
|
||||
}
|
||||
|
||||
return $this->attributes[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a regex match all on the raw header and return the first result
|
||||
* @param $pattern
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function find($pattern) {
|
||||
if (preg_match_all($pattern, $this->raw, $matches)) {
|
||||
if (isset($matches[1])) {
|
||||
if (count($matches[1]) > 0) {
|
||||
return $matches[1][0];
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to find a boundary if possible
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getBoundary() {
|
||||
$regex = $this->config["boundary"] ?? "/boundary=(.*?(?=;)|(.*))/i";
|
||||
$boundary = $this->find($regex);
|
||||
|
||||
if ($boundary === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->clearBoundaryString($boundary);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all unwanted chars from a given boundary
|
||||
* @param string $str
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function clearBoundaryString(string $str): string {
|
||||
return str_replace(['"', '\r', '\n', "\n", "\r", ";", "\s"], "", $str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the raw headers
|
||||
*
|
||||
* @throws InvalidMessageDateException
|
||||
*/
|
||||
protected function parse() {
|
||||
$header = $this->rfc822_parse_headers($this->raw);
|
||||
$this->extractAddresses($header);
|
||||
|
||||
if (property_exists($header, 'subject')) {
|
||||
$sub = $this->decode($header->subject);
|
||||
$this->set("subject", $sub);
|
||||
}
|
||||
if (property_exists($header, 'references')) {
|
||||
$this->set("references", $this->decode($header->references));
|
||||
}
|
||||
if (property_exists($header, 'message_id')) {
|
||||
$this->set("message_id", str_replace(['<', '>'], '', $header->message_id));
|
||||
}
|
||||
|
||||
$this->parseDate($header);
|
||||
foreach ($header as $key => $value) {
|
||||
$key = trim(rtrim(strtolower($key)));
|
||||
if (!isset($this->attributes[$key])) {
|
||||
$this->set($key, $value);
|
||||
}
|
||||
}
|
||||
|
||||
$this->extractHeaderExtensions();
|
||||
$this->findPriority();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse mail headers from a string
|
||||
* @link https://php.net/manual/en/function.imap-rfc822-parse-headers.php
|
||||
* @param $raw_headers
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function rfc822_parse_headers($raw_headers) {
|
||||
$headers = [];
|
||||
$imap_headers = [];
|
||||
if (extension_loaded('imap') && $this->config["rfc822"]) {
|
||||
$raw_imap_headers = (array)\imap_rfc822_parse_headers($this->raw);
|
||||
foreach ($raw_imap_headers as $key => $values) {
|
||||
$key = str_replace("-", "_", $key);
|
||||
$imap_headers[$key] = $values;
|
||||
}
|
||||
}
|
||||
$lines = explode("\r\n", preg_replace("/\r\n\s/", ' ', $raw_headers));
|
||||
$prev_header = null;
|
||||
foreach ($lines as $line) {
|
||||
if (substr($line, 0, 1) === "\n") {
|
||||
$line = substr($line, 1);
|
||||
}
|
||||
|
||||
if (substr($line, 0, 1) === "\t") {
|
||||
$line = substr($line, 1);
|
||||
$line = trim(rtrim($line));
|
||||
if ($prev_header !== null) {
|
||||
$headers[$prev_header][] = $line;
|
||||
}
|
||||
} elseif (substr($line, 0, 1) === " ") {
|
||||
$line = substr($line, 1);
|
||||
$line = trim(rtrim($line));
|
||||
if ($prev_header !== null) {
|
||||
if (!isset($headers[$prev_header])) {
|
||||
$headers[$prev_header] = "";
|
||||
}
|
||||
if (is_array($headers[$prev_header])) {
|
||||
$headers[$prev_header][] = $line;
|
||||
} else {
|
||||
$headers[$prev_header] .= $line;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (($pos = strpos($line, ":")) > 0) {
|
||||
$key = trim(rtrim(strtolower(substr($line, 0, $pos))));
|
||||
$key = str_replace("-", "_", $key);
|
||||
|
||||
$value = trim(rtrim(substr($line, $pos + 1)));
|
||||
if (isset($headers[$key])) {
|
||||
$headers[$key][] = $value;
|
||||
} else {
|
||||
$headers[$key] = [$value];
|
||||
}
|
||||
$prev_header = $key;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($headers as $key => $values) {
|
||||
if (isset($imap_headers[$key])) continue;
|
||||
$value = null;
|
||||
switch ($key) {
|
||||
case 'from':
|
||||
case 'to':
|
||||
case 'cc':
|
||||
case 'bcc':
|
||||
case 'reply_to':
|
||||
case 'sender':
|
||||
$value = $this->decodeAddresses($values);
|
||||
$headers[$key . "address"] = implode(", ", $values);
|
||||
break;
|
||||
case 'subject':
|
||||
$value = implode(" ", $values);
|
||||
break;
|
||||
default:
|
||||
if (is_array($values)) {
|
||||
foreach ($values as $k => $v) {
|
||||
if ($v == "") {
|
||||
unset($values[$k]);
|
||||
}
|
||||
}
|
||||
$available_values = count($values);
|
||||
if ($available_values === 1) {
|
||||
$value = array_pop($values);
|
||||
} elseif ($available_values === 2) {
|
||||
$value = implode(" ", $values);
|
||||
} elseif ($available_values > 2) {
|
||||
$value = array_values($values);
|
||||
} else {
|
||||
$value = "";
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
$headers[$key] = $value;
|
||||
}
|
||||
|
||||
return (object)array_merge($headers, $imap_headers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode MIME header elements
|
||||
* @link https://php.net/manual/en/function.imap-mime-header-decode.php
|
||||
* @param string $text The MIME text
|
||||
*
|
||||
* @return array The decoded elements are returned in an array of objects, where each
|
||||
* object has two properties, charset and text.
|
||||
*/
|
||||
public function mime_header_decode(string $text): array {
|
||||
if (extension_loaded('imap')) {
|
||||
$result = \imap_mime_header_decode($text);
|
||||
return is_array($result) ? $result : [];
|
||||
}
|
||||
$charset = $this->getEncoding($text);
|
||||
return [(object)[
|
||||
"charset" => $charset,
|
||||
"text" => $this->convertEncoding($text, $charset)
|
||||
]];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a given pair of strings has been decoded
|
||||
* @param $encoded
|
||||
* @param $decoded
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function notDecoded($encoded, $decoded): bool {
|
||||
return 0 === strpos($decoded, '=?')
|
||||
&& strlen($decoded) - 2 === strpos($decoded, '?=')
|
||||
&& false !== strpos($encoded, $decoded);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the encoding
|
||||
* @param $str
|
||||
* @param string $from
|
||||
* @param string $to
|
||||
*
|
||||
* @return mixed|string
|
||||
*/
|
||||
public function convertEncoding($str, $from = "ISO-8859-2", $to = "UTF-8") {
|
||||
|
||||
$from = EncodingAliases::get($from, $this->fallback_encoding);
|
||||
$to = EncodingAliases::get($to, $this->fallback_encoding);
|
||||
|
||||
if ($from === $to) {
|
||||
return $str;
|
||||
}
|
||||
|
||||
// We don't need to do convertEncoding() if charset is ASCII (us-ascii):
|
||||
// ASCII is a subset of UTF-8, so all ASCII files are already UTF-8 encoded
|
||||
// https://stackoverflow.com/a/11303410
|
||||
//
|
||||
// us-ascii is the same as ASCII:
|
||||
// ASCII is the traditional name for the encoding system; the Internet Assigned Numbers Authority (IANA)
|
||||
// prefers the updated name US-ASCII, which clarifies that this system was developed in the US and
|
||||
// based on the typographical symbols predominantly in use there.
|
||||
// https://en.wikipedia.org/wiki/ASCII
|
||||
//
|
||||
// convertEncoding() function basically means convertToUtf8(), so when we convert ASCII string into UTF-8 it gets broken.
|
||||
if (strtolower($from) == 'us-ascii' && $to == 'UTF-8') {
|
||||
return $str;
|
||||
}
|
||||
|
||||
try {
|
||||
if (function_exists('iconv') && $from != 'UTF-7' && $to != 'UTF-7') {
|
||||
return iconv($from, $to, $str);
|
||||
} else {
|
||||
if (!$from) {
|
||||
return mb_convert_encoding($str, $to);
|
||||
}
|
||||
return mb_convert_encoding($str, $to, $from);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
if (strstr($from, '-')) {
|
||||
$from = str_replace('-', '', $from);
|
||||
return $this->convertEncoding($str, $from, $to);
|
||||
} else {
|
||||
return $str;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the encoding of a given abject
|
||||
* @param object|string $structure
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getEncoding($structure): string {
|
||||
if (property_exists($structure, 'parameters')) {
|
||||
foreach ($structure->parameters as $parameter) {
|
||||
if (strtolower($parameter->attribute) == "charset") {
|
||||
return EncodingAliases::get($parameter->value, $this->fallback_encoding);
|
||||
}
|
||||
}
|
||||
} elseif (property_exists($structure, 'charset')) {
|
||||
return EncodingAliases::get($structure->charset, $this->fallback_encoding);
|
||||
} elseif (is_string($structure) === true) {
|
||||
$result = mb_detect_encoding($structure);
|
||||
return $result === false ? $this->fallback_encoding : $result;
|
||||
}
|
||||
|
||||
return $this->fallback_encoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if a given value is utf-8 encoded
|
||||
* @param $value
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function is_uft8($value): bool {
|
||||
return strpos(strtolower($value), '=?utf-8?') === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to decode a specific header
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function decode($value) {
|
||||
// Check if the input contains any encoding
|
||||
if (!preg_match('/=\?([^?]+)\?([QB])\?([^?]+)\?=/i', $value)) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
preg_match_all('/=\?([^?]+)\?([QB])\?([^?]+)\?=/i', $value, $matches, PREG_SET_ORDER);
|
||||
|
||||
$decoded = '';
|
||||
foreach ($matches as $match) {
|
||||
$encoding = $match[1];
|
||||
$type = $match[2];
|
||||
$encoded_string = $match[3];
|
||||
|
||||
// Decode based on encoding type
|
||||
if (strtolower($type) == 'q') {
|
||||
$decoded_part = quoted_printable_decode($encoded_string);
|
||||
} elseif (strtolower($type) == 'b') {
|
||||
$decoded_part = base64_decode($encoded_string);
|
||||
}
|
||||
|
||||
if (strtolower($encoding) != 'utf-8') {
|
||||
$decoded_part = iconv($encoding, 'UTF-8', $decoded_part);
|
||||
}
|
||||
|
||||
$decoded .= str_replace('_', ' ', $decoded_part);
|
||||
}
|
||||
|
||||
return $decoded;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a given array
|
||||
* @param array $values
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function decodeArray(array $values): array {
|
||||
foreach ($values as $key => $value) {
|
||||
$values[$key] = $this->decode($value);
|
||||
}
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to extract the priority from a given raw header string
|
||||
*/
|
||||
private function findPriority() {
|
||||
if (($priority = $this->get("x_priority")) === null) return;
|
||||
switch ((int)"$priority") {
|
||||
case IMAP::MESSAGE_PRIORITY_HIGHEST;
|
||||
$priority = IMAP::MESSAGE_PRIORITY_HIGHEST;
|
||||
break;
|
||||
case IMAP::MESSAGE_PRIORITY_HIGH;
|
||||
$priority = IMAP::MESSAGE_PRIORITY_HIGH;
|
||||
break;
|
||||
case IMAP::MESSAGE_PRIORITY_NORMAL;
|
||||
$priority = IMAP::MESSAGE_PRIORITY_NORMAL;
|
||||
break;
|
||||
case IMAP::MESSAGE_PRIORITY_LOW;
|
||||
$priority = IMAP::MESSAGE_PRIORITY_LOW;
|
||||
break;
|
||||
case IMAP::MESSAGE_PRIORITY_LOWEST;
|
||||
$priority = IMAP::MESSAGE_PRIORITY_LOWEST;
|
||||
break;
|
||||
default:
|
||||
$priority = IMAP::MESSAGE_PRIORITY_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
|
||||
$this->set("priority", $priority);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract a given part as address array from a given header
|
||||
* @param $values
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function decodeAddresses($values): array {
|
||||
$addresses = [];
|
||||
|
||||
if (extension_loaded('mailparse') && $this->config["rfc822"]) {
|
||||
foreach ($values as $address) {
|
||||
foreach (\mailparse_rfc822_parse_addresses($address) as $parsed_address) {
|
||||
if (isset($parsed_address['address'])) {
|
||||
$mail_address = explode('@', $parsed_address['address']);
|
||||
if (count($mail_address) == 2) {
|
||||
$addresses[] = (object)[
|
||||
"personal" => $parsed_address['display'] ?? '',
|
||||
"mailbox" => $mail_address[0],
|
||||
"host" => $mail_address[1],
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $addresses;
|
||||
}
|
||||
|
||||
foreach ($values as $address) {
|
||||
foreach (preg_split('/, (?=(?:[^"]*"[^"]*")*[^"]*$)/', $address) as $split_address) {
|
||||
$split_address = trim(rtrim($split_address));
|
||||
|
||||
if (strpos($split_address, ",") == strlen($split_address) - 1) {
|
||||
$split_address = substr($split_address, 0, -1);
|
||||
}
|
||||
if (preg_match(
|
||||
'/^(?:(?P<name>.+)\s)?(?(name)<|<?)(?P<email>[^\s]+?)(?(name)>|>?)$/',
|
||||
$split_address,
|
||||
$matches
|
||||
)) {
|
||||
$name = trim(rtrim($matches["name"]));
|
||||
$email = trim(rtrim($matches["email"]));
|
||||
list($mailbox, $host) = array_pad(explode("@", $email), 2, null);
|
||||
$addresses[] = (object)[
|
||||
"personal" => $name,
|
||||
"mailbox" => $mailbox,
|
||||
"host" => $host,
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $addresses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract a given part as address array from a given header
|
||||
* @param object $header
|
||||
*/
|
||||
private function extractAddresses($header) {
|
||||
foreach (['from', 'to', 'cc', 'bcc', 'reply_to', 'sender'] as $key) {
|
||||
if (property_exists($header, $key)) {
|
||||
$this->set($key, $this->parseAddresses($header->$key));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse Addresses
|
||||
* @param $list
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function parseAddresses($list): array {
|
||||
$addresses = [];
|
||||
|
||||
if (is_array($list) === false) {
|
||||
return $addresses;
|
||||
}
|
||||
|
||||
foreach ($list as $item) {
|
||||
$address = (object)$item;
|
||||
|
||||
if (!property_exists($address, 'mailbox')) {
|
||||
$address->mailbox = false;
|
||||
}
|
||||
if (!property_exists($address, 'host')) {
|
||||
$address->host = false;
|
||||
}
|
||||
if (!property_exists($address, 'personal')) {
|
||||
$address->personal = false;
|
||||
} else {
|
||||
$personalParts = $this->mime_header_decode($address->personal);
|
||||
|
||||
if (is_array($personalParts)) {
|
||||
$address->personal = '';
|
||||
foreach ($personalParts as $p) {
|
||||
$address->personal .= $this->convertEncoding($p->text, $this->getEncoding($p));
|
||||
}
|
||||
}
|
||||
|
||||
if (strpos($address->personal, "'") === 0) {
|
||||
$address->personal = str_replace("'", "", $address->personal);
|
||||
}
|
||||
}
|
||||
|
||||
$address->mail = ($address->mailbox && $address->host) ? $address->mailbox . '@' . $address->host : false;
|
||||
$address->full = ($address->personal) ? $address->personal . ' <' . $address->mail . '>' : $address->mail;
|
||||
|
||||
$addresses[] = new Address($address);
|
||||
}
|
||||
|
||||
return $addresses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search and extract potential header extensions
|
||||
*/
|
||||
private function extractHeaderExtensions() {
|
||||
foreach ($this->attributes as $key => $value) {
|
||||
if (is_array($value)) {
|
||||
$value = implode(", ", $value);
|
||||
} else {
|
||||
$value = (string)$value;
|
||||
}
|
||||
// Only parse strings and don't parse any attributes like the user-agent
|
||||
if (($key == "user_agent") === false) {
|
||||
if (($pos = strpos($value, ";")) !== false) {
|
||||
$original = substr($value, 0, $pos);
|
||||
$this->set($key, trim(rtrim($original)), true);
|
||||
|
||||
// Get all potential extensions
|
||||
$extensions = explode(";", substr($value, $pos + 1));
|
||||
foreach ($extensions as $extension) {
|
||||
if (($pos = strpos($extension, "=")) !== false) {
|
||||
$key = substr($extension, 0, $pos);
|
||||
$key = trim(rtrim(strtolower($key)));
|
||||
|
||||
if (isset($this->attributes[$key]) === false) {
|
||||
$value = substr($extension, $pos + 1);
|
||||
$value = str_replace('"', "", $value);
|
||||
$value = trim(rtrim($value));
|
||||
|
||||
$this->set($key, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Exception handling for invalid dates
|
||||
*
|
||||
* Currently known invalid formats:
|
||||
* ^ Datetime ^ Problem ^ Cause
|
||||
* | Mon, 20 Nov 2017 20:31:31 +0800 (GMT+8:00) | Double timezone specification | A Windows feature
|
||||
* | Thu, 8 Nov 2018 08:54:58 -0200 (-02) |
|
||||
* | | and invalid timezone (max 6 char) |
|
||||
* | 04 Jan 2018 10:12:47 UT | Missing letter "C" | Unknown
|
||||
* | Thu, 31 May 2018 18:15:00 +0800 (added by) | Non-standard details added by the | Unknown
|
||||
* | | mail server |
|
||||
* | Sat, 31 Aug 2013 20:08:23 +0580 | Invalid timezone | PHPMailer bug https://sourceforge.net/p/phpmailer/mailman/message/6132703/
|
||||
*
|
||||
* Please report any new invalid timestamps to [#45](https://github.com/Webklex/php-imap/issues)
|
||||
*
|
||||
* @param object $header
|
||||
*
|
||||
* @throws InvalidMessageDateException
|
||||
*/
|
||||
private function parseDate($header) {
|
||||
|
||||
if (property_exists($header, 'date')) {
|
||||
$date = $header->date;
|
||||
|
||||
if (preg_match('/\+0580/', $date)) {
|
||||
$date = str_replace('+0580', '+0530', $date);
|
||||
}
|
||||
|
||||
$date = trim(rtrim($date));
|
||||
try {
|
||||
if(strpos($date, ' ') !== false){
|
||||
$date = str_replace(' ', ' ', $date);
|
||||
}
|
||||
$parsed_date = Carbon::parse($date);
|
||||
} catch (\Exception $e) {
|
||||
switch (true) {
|
||||
case preg_match('/([0-9]{4}\.[0-9]{1,2}\.[0-9]{1,2}\-[0-9]{1,2}\.[0-9]{1,2}.[0-9]{1,2})+$/i', $date) > 0:
|
||||
$date = Carbon::createFromFormat("Y.m.d-H.i.s", $date);
|
||||
break;
|
||||
case preg_match('/([0-9]{1,2}\ [A-Z]{2,3}\ [0-9]{4}\ [0-9]{1,2}\:[0-9]{1,2}\:[0-9]{1,2}\ UT)+$/i', $date) > 0:
|
||||
case preg_match('/([A-Z]{2,3}\,\ [0-9]{1,2}\ [A-Z]{2,3}\ [0-9]{4}\ [0-9]{1,2}\:[0-9]{1,2}\:[0-9]{1,2}\ UT)+$/i', $date) > 0:
|
||||
$date .= 'C';
|
||||
break;
|
||||
case preg_match('/([A-Z]{2,3}\,\ [0-9]{1,2}[\,]\ [A-Z]{2,3}\ [0-9]{4}\ [0-9]{1,2}\:[0-9]{1,2}\:[0-9]{1,2}\ [\-|\+][0-9]{4})+$/i', $date) > 0:
|
||||
$date = str_replace(',', '', $date);
|
||||
case preg_match('/([A-Z]{2,3}\,\ [0-9]{1,2}\ [A-Z]{2,3}\ [0-9]{4}\ [0-9]{1,2}\:[0-9]{1,2}\:[0-9]{1,2}\ \+[0-9]{2,4}\ \(\+[0-9]{1,2}\))+$/i', $date) > 0:
|
||||
case preg_match('/([A-Z]{2,3}[\,|\ \,]\ [0-9]{1,2}\ [A-Z]{2,3}\ [0-9]{4}\ [0-9]{1,2}\:[0-9]{1,2}\:[0-9]{1,2}.*)+$/i', $date) > 0:
|
||||
case preg_match('/([A-Z]{2,3}\,\ [0-9]{1,2}\ [A-Z]{2,3}\ [0-9]{4}\ [0-9]{1,2}\:[0-9]{1,2}\:[0-9]{1,2}\ [\-|\+][0-9]{4}\ \(.*)\)+$/i', $date) > 0:
|
||||
case preg_match('/([A-Z]{2,3}\, \ [0-9]{1,2}\ [A-Z]{2,3}\ [0-9]{4}\ [0-9]{1,2}\:[0-9]{1,2}\:[0-9]{1,2}\ [\-|\+][0-9]{4}\ \(.*)\)+$/i', $date) > 0:
|
||||
case preg_match('/([0-9]{1,2}\ [A-Z]{2,3}\ [0-9]{2,4}\ [0-9]{2}\:[0-9]{2}\:[0-9]{2}\ [A-Z]{2}\ \-[0-9]{2}\:[0-9]{2}\ \([A-Z]{2,3}\ \-[0-9]{2}:[0-9]{2}\))+$/i', $date) > 0:
|
||||
$array = explode('(', $date);
|
||||
$array = array_reverse($array);
|
||||
$date = trim(array_pop($array));
|
||||
break;
|
||||
}
|
||||
try {
|
||||
$parsed_date = Carbon::parse($date);
|
||||
} catch (\Exception $_e) {
|
||||
if (!isset($this->config["fallback_date"])) {
|
||||
throw new InvalidMessageDateException("Invalid message date. ID:" . $this->get("message_id") . " Date:" . $header->date . "/" . $date, 1100, $e);
|
||||
} else {
|
||||
$parsed_date = Carbon::parse($this->config["fallback_date"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->set("date", $parsed_date);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all available attributes
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAttributes(): array {
|
||||
return $this->attributes;
|
||||
}
|
||||
|
||||
}
|
||||
375
vendor/webklex/php-imap/src/IMAP.php
vendored
Normal file
375
vendor/webklex/php-imap/src/IMAP.php
vendored
Normal file
@@ -0,0 +1,375 @@
|
||||
<?php
|
||||
/*
|
||||
* File: IMAP.php
|
||||
* Category: -
|
||||
* Author: M.Goldenbaum
|
||||
* Created: 14.03.19 18:22
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP;
|
||||
|
||||
/**
|
||||
* Class IMAP
|
||||
*
|
||||
* Independent imap const holder
|
||||
*/
|
||||
class IMAP {
|
||||
|
||||
/**
|
||||
* Message const
|
||||
*
|
||||
* @const integer TYPE_TEXT
|
||||
* @const integer TYPE_MULTIPART
|
||||
*
|
||||
* @const integer ENC_7BIT
|
||||
* @const integer ENC_8BIT
|
||||
* @const integer ENC_BINARY
|
||||
* @const integer ENC_BASE64
|
||||
* @const integer ENC_QUOTED_PRINTABLE
|
||||
* @const integer ENC_OTHER
|
||||
*/
|
||||
const MESSAGE_TYPE_TEXT = 0;
|
||||
const MESSAGE_TYPE_MULTIPART = 1;
|
||||
|
||||
const MESSAGE_ENC_7BIT = 0;
|
||||
const MESSAGE_ENC_8BIT = 1;
|
||||
const MESSAGE_ENC_BINARY = 2;
|
||||
const MESSAGE_ENC_BASE64 = 3;
|
||||
const MESSAGE_ENC_QUOTED_PRINTABLE = 4;
|
||||
const MESSAGE_ENC_OTHER = 5;
|
||||
|
||||
const MESSAGE_PRIORITY_UNKNOWN = 0;
|
||||
const MESSAGE_PRIORITY_HIGHEST = 1;
|
||||
const MESSAGE_PRIORITY_HIGH = 2;
|
||||
const MESSAGE_PRIORITY_NORMAL = 3;
|
||||
const MESSAGE_PRIORITY_LOW = 4;
|
||||
const MESSAGE_PRIORITY_LOWEST = 5;
|
||||
|
||||
/**
|
||||
* Attachment const
|
||||
*
|
||||
* @const integer TYPE_TEXT
|
||||
* @const integer TYPE_MULTIPART
|
||||
* @const integer TYPE_MESSAGE
|
||||
* @const integer TYPE_APPLICATION
|
||||
* @const integer TYPE_AUDIO
|
||||
* @const integer TYPE_IMAGE
|
||||
* @const integer TYPE_VIDEO
|
||||
* @const integer TYPE_MODEL
|
||||
* @const integer TYPE_OTHER
|
||||
*/
|
||||
const ATTACHMENT_TYPE_TEXT = 0;
|
||||
const ATTACHMENT_TYPE_MULTIPART = 1;
|
||||
const ATTACHMENT_TYPE_MESSAGE = 2;
|
||||
const ATTACHMENT_TYPE_APPLICATION = 3;
|
||||
const ATTACHMENT_TYPE_AUDIO = 4;
|
||||
const ATTACHMENT_TYPE_IMAGE = 5;
|
||||
const ATTACHMENT_TYPE_VIDEO = 6;
|
||||
const ATTACHMENT_TYPE_MODEL = 7;
|
||||
const ATTACHMENT_TYPE_OTHER = 8;
|
||||
|
||||
/**
|
||||
* Client const
|
||||
*
|
||||
* @const integer CLIENT_OPENTIMEOUT
|
||||
* @const integer CLIENT_READTIMEOUT
|
||||
* @const integer CLIENT_WRITETIMEOUT
|
||||
* @const integer CLIENT_CLOSETIMEOUT
|
||||
*/
|
||||
const CLIENT_OPENTIMEOUT = 1;
|
||||
const CLIENT_READTIMEOUT = 2;
|
||||
const CLIENT_WRITETIMEOUT = 3;
|
||||
const CLIENT_CLOSETIMEOUT = 4;
|
||||
|
||||
/**
|
||||
* Generic imap const
|
||||
*
|
||||
* @const integer NIL
|
||||
* @const integer IMAP_OPENTIMEOUT
|
||||
* @const integer IMAP_READTIMEOUT
|
||||
* @const integer IMAP_WRITETIMEOUT
|
||||
* @const integer IMAP_CLOSETIMEOUT
|
||||
* @const integer OP_DEBUG
|
||||
* @const integer OP_READONLY
|
||||
* @const integer OP_ANONYMOUS
|
||||
* @const integer OP_SHORTCACHE
|
||||
* @const integer OP_SILENT
|
||||
* @const integer OP_PROTOTYPE
|
||||
* @const integer OP_HALFOPEN
|
||||
* @const integer OP_EXPUNGE
|
||||
* @const integer OP_SECURE
|
||||
* @const integer CL_EXPUNGE
|
||||
* @const integer FT_UID
|
||||
* @const integer FT_PEEK
|
||||
* @const integer FT_NOT
|
||||
* @const integer FT_INTERNAL
|
||||
* @const integer FT_PREFETCHTEXT
|
||||
* @const integer ST_UID
|
||||
* @const integer ST_SILENT
|
||||
* @const integer ST_SET
|
||||
* @const integer CP_UID
|
||||
* @const integer CP_MOVE
|
||||
* @const integer SE_UID
|
||||
* @const integer SE_FREE
|
||||
* @const integer SE_NOPREFETCH
|
||||
* @const integer SO_FREE
|
||||
* @const integer SO_NOSERVER
|
||||
* @const integer SA_MESSAGES
|
||||
* @const integer SA_RECENT
|
||||
* @const integer SA_UNSEEN
|
||||
* @const integer SA_UIDNEXT
|
||||
* @const integer SA_UIDVALIDITY
|
||||
* @const integer SA_ALL
|
||||
* @const integer LATT_NOINFERIORS
|
||||
* @const integer LATT_NOSELECT
|
||||
* @const integer LATT_MARKED
|
||||
* @const integer LATT_UNMARKED
|
||||
* @const integer LATT_REFERRAL
|
||||
* @const integer LATT_HASCHILDREN
|
||||
* @const integer LATT_HASNOCHILDREN
|
||||
* @const integer SORTDATE
|
||||
* @const integer SORTARRIVAL
|
||||
* @const integer SORTFROM
|
||||
* @const integer SORTSUBJECT
|
||||
* @const integer SORTTO
|
||||
* @const integer SORTCC
|
||||
* @const integer SORTSIZE
|
||||
* @const integer TYPETEXT
|
||||
* @const integer TYPEMULTIPART
|
||||
* @const integer TYPEMESSAGE
|
||||
* @const integer TYPEAPPLICATION
|
||||
* @const integer TYPEAUDIO
|
||||
* @const integer TYPEIMAGE
|
||||
* @const integer TYPEVIDEO
|
||||
* @const integer TYPEMODEL
|
||||
* @const integer TYPEOTHER
|
||||
* @const integer ENC7BIT
|
||||
* @const integer ENC8BIT
|
||||
* @const integer ENCBINARY
|
||||
* @const integer ENCBASE64
|
||||
* @const integer ENCQUOTEDPRINTABLE
|
||||
* @const integer ENCOTHER
|
||||
* @const integer IMAP_GC_ELT
|
||||
* @const integer IMAP_GC_ENV
|
||||
* @const integer IMAP_GC_TEXTS
|
||||
*/
|
||||
|
||||
const NIL = 0;
|
||||
const IMAP_OPENTIMEOUT = 1;
|
||||
const IMAP_READTIMEOUT = 2;
|
||||
const IMAP_WRITETIMEOUT = 3;
|
||||
const IMAP_CLOSETIMEOUT = 4;
|
||||
const OP_DEBUG = 1;
|
||||
|
||||
/**
|
||||
* Open mailbox read-only
|
||||
* @link http://php.net/manual/en/imap.constants.php
|
||||
*/
|
||||
const OP_READONLY = 2;
|
||||
|
||||
/**
|
||||
* Don't use or update a .newsrc for news
|
||||
* (NNTP only)
|
||||
* @link http://php.net/manual/en/imap.constants.php
|
||||
*/
|
||||
const OP_ANONYMOUS = 4;
|
||||
const OP_SHORTCACHE = 8;
|
||||
const OP_SILENT = 16;
|
||||
const OP_PROTOTYPE = 32;
|
||||
|
||||
/**
|
||||
* For IMAP and NNTP
|
||||
* names, open a connection but don't open a mailbox.
|
||||
* @link http://php.net/manual/en/imap.constants.php
|
||||
*/
|
||||
const OP_HALFOPEN = 64;
|
||||
const OP_EXPUNGE = 128;
|
||||
const OP_SECURE = 256;
|
||||
|
||||
/**
|
||||
* silently expunge the mailbox before closing when
|
||||
* calling <b>imap_close</b>
|
||||
* @link http://php.net/manual/en/imap.constants.php
|
||||
*/
|
||||
const CL_EXPUNGE = 32768;
|
||||
|
||||
/**
|
||||
* The parameter is a UID
|
||||
* @link http://php.net/manual/en/imap.constants.php
|
||||
*/
|
||||
const FT_UID = 1;
|
||||
|
||||
/**
|
||||
* Do not set the \Seen flag if not already set
|
||||
* @link http://php.net/manual/en/imap.constants.php
|
||||
*/
|
||||
const FT_PEEK = 2;
|
||||
const FT_NOT = 4;
|
||||
|
||||
/**
|
||||
* The return string is in internal format, will not canonicalize to CRLF.
|
||||
* @link http://php.net/manual/en/imap.constants.php
|
||||
*/
|
||||
const FT_INTERNAL = 8;
|
||||
const FT_PREFETCHTEXT = 32;
|
||||
|
||||
/**
|
||||
* The sequence argument contains UIDs instead of sequence numbers
|
||||
* @link http://php.net/manual/en/imap.constants.php
|
||||
*/
|
||||
const ST_UID = 1;
|
||||
const ST_SILENT = 2;
|
||||
const ST_MSGN = 3;
|
||||
const ST_SET = 4;
|
||||
|
||||
/**
|
||||
* the sequence numbers contain UIDS
|
||||
* @link http://php.net/manual/en/imap.constants.php
|
||||
*/
|
||||
const CP_UID = 1;
|
||||
|
||||
/**
|
||||
* Delete the messages from the current mailbox after copying
|
||||
* with <b>imap_mail_copy</b>
|
||||
* @link http://php.net/manual/en/imap.constants.php
|
||||
*/
|
||||
const CP_MOVE = 2;
|
||||
|
||||
/**
|
||||
* Return UIDs instead of sequence numbers
|
||||
* @link http://php.net/manual/en/imap.constants.php
|
||||
*/
|
||||
const SE_UID = 1;
|
||||
const SE_FREE = 2;
|
||||
|
||||
/**
|
||||
* Don't prefetch searched messages
|
||||
* @link http://php.net/manual/en/imap.constants.php
|
||||
*/
|
||||
const SE_NOPREFETCH = 4;
|
||||
const SO_FREE = 8;
|
||||
const SO_NOSERVER = 16;
|
||||
const SA_MESSAGES = 1;
|
||||
const SA_RECENT = 2;
|
||||
const SA_UNSEEN = 4;
|
||||
const SA_UIDNEXT = 8;
|
||||
const SA_UIDVALIDITY = 16;
|
||||
const SA_ALL = 31;
|
||||
|
||||
/**
|
||||
* This mailbox has no "children" (there are no
|
||||
* mailboxes below this one).
|
||||
* @link http://php.net/manual/en/imap.constants.php
|
||||
*/
|
||||
const LATT_NOINFERIORS = 1;
|
||||
|
||||
/**
|
||||
* This is only a container, not a mailbox - you
|
||||
* cannot open it.
|
||||
* @link http://php.net/manual/en/imap.constants.php
|
||||
*/
|
||||
const LATT_NOSELECT = 2;
|
||||
|
||||
/**
|
||||
* This mailbox is marked. Only used by UW-IMAPD.
|
||||
* @link http://php.net/manual/en/imap.constants.php
|
||||
*/
|
||||
const LATT_MARKED = 4;
|
||||
|
||||
/**
|
||||
* This mailbox is not marked. Only used by
|
||||
* UW-IMAPD.
|
||||
* @link http://php.net/manual/en/imap.constants.php
|
||||
*/
|
||||
const LATT_UNMARKED = 8;
|
||||
const LATT_REFERRAL = 16;
|
||||
const LATT_HASCHILDREN = 32;
|
||||
const LATT_HASNOCHILDREN = 64;
|
||||
|
||||
/**
|
||||
* Sort criteria for <b>imap_sort</b>:
|
||||
* message Date
|
||||
* @link http://php.net/manual/en/imap.constants.php
|
||||
*/
|
||||
const SORTDATE = 0;
|
||||
|
||||
/**
|
||||
* Sort criteria for <b>imap_sort</b>:
|
||||
* arrival date
|
||||
* @link http://php.net/manual/en/imap.constants.php
|
||||
*/
|
||||
const SORTARRIVAL = 1;
|
||||
|
||||
/**
|
||||
* Sort criteria for <b>imap_sort</b>:
|
||||
* mailbox in first From address
|
||||
* @link http://php.net/manual/en/imap.constants.php
|
||||
*/
|
||||
const SORTFROM = 2;
|
||||
|
||||
/**
|
||||
* Sort criteria for <b>imap_sort</b>:
|
||||
* message subject
|
||||
* @link http://php.net/manual/en/imap.constants.php
|
||||
*/
|
||||
const SORTSUBJECT = 3;
|
||||
|
||||
/**
|
||||
* Sort criteria for <b>imap_sort</b>:
|
||||
* mailbox in first To address
|
||||
* @link http://php.net/manual/en/imap.constants.php
|
||||
*/
|
||||
const SORTTO = 4;
|
||||
|
||||
/**
|
||||
* Sort criteria for <b>imap_sort</b>:
|
||||
* mailbox in first cc address
|
||||
* @link http://php.net/manual/en/imap.constants.php
|
||||
*/
|
||||
const SORTCC = 5;
|
||||
|
||||
/**
|
||||
* Sort criteria for <b>imap_sort</b>:
|
||||
* size of message in octets
|
||||
* @link http://php.net/manual/en/imap.constants.php
|
||||
*/
|
||||
const SORTSIZE = 6;
|
||||
const TYPETEXT = 0;
|
||||
const TYPEMULTIPART = 1;
|
||||
const TYPEMESSAGE = 2;
|
||||
const TYPEAPPLICATION = 3;
|
||||
const TYPEAUDIO = 4;
|
||||
const TYPEIMAGE = 5;
|
||||
const TYPEVIDEO = 6;
|
||||
const TYPEMODEL = 7;
|
||||
const TYPEOTHER = 8;
|
||||
const ENC7BIT = 0;
|
||||
const ENC8BIT = 1;
|
||||
const ENCBINARY = 2;
|
||||
const ENCBASE64 = 3;
|
||||
const ENCQUOTEDPRINTABLE = 4;
|
||||
const ENCOTHER = 5;
|
||||
|
||||
/**
|
||||
* Garbage collector, clear message cache elements.
|
||||
* @link http://php.net/manual/en/imap.constants.php
|
||||
*/
|
||||
const IMAP_GC_ELT = 1;
|
||||
|
||||
/**
|
||||
* Garbage collector, clear envelopes and bodies.
|
||||
* @link http://php.net/manual/en/imap.constants.php
|
||||
*/
|
||||
const IMAP_GC_ENV = 2;
|
||||
|
||||
/**
|
||||
* Garbage collector, clear texts.
|
||||
* @link http://php.net/manual/en/imap.constants.php
|
||||
*/
|
||||
const IMAP_GC_TEXTS = 4;
|
||||
|
||||
}
|
||||
1432
vendor/webklex/php-imap/src/Message.php
vendored
Executable file
1432
vendor/webklex/php-imap/src/Message.php
vendored
Executable file
File diff suppressed because it is too large
Load Diff
312
vendor/webklex/php-imap/src/Part.php
vendored
Normal file
312
vendor/webklex/php-imap/src/Part.php
vendored
Normal file
@@ -0,0 +1,312 @@
|
||||
<?php
|
||||
/*
|
||||
* File: Part.php
|
||||
* Category: -
|
||||
* Author: M.Goldenbaum
|
||||
* Created: 17.09.20 20:38
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP;
|
||||
|
||||
|
||||
use Webklex\PHPIMAP\Exceptions\InvalidMessageDateException;
|
||||
|
||||
/**
|
||||
* Class Part
|
||||
*
|
||||
* @package Webklex\PHPIMAP
|
||||
*/
|
||||
class Part {
|
||||
|
||||
/**
|
||||
* Raw part
|
||||
*
|
||||
* @var string $raw
|
||||
*/
|
||||
public $raw = "";
|
||||
|
||||
/**
|
||||
* Part type
|
||||
*
|
||||
* @var int $type
|
||||
*/
|
||||
public $type = IMAP::MESSAGE_TYPE_TEXT;
|
||||
|
||||
/**
|
||||
* Part content
|
||||
*
|
||||
* @var string $content
|
||||
*/
|
||||
public $content = "";
|
||||
|
||||
/**
|
||||
* Part subtype
|
||||
*
|
||||
* @var string $subtype
|
||||
*/
|
||||
public $subtype = null;
|
||||
|
||||
/**
|
||||
* Part charset - if available
|
||||
*
|
||||
* @var string $charset
|
||||
*/
|
||||
public $charset = "utf-8";
|
||||
|
||||
/**
|
||||
* Part encoding method
|
||||
*
|
||||
* @var int $encoding
|
||||
*/
|
||||
public $encoding = IMAP::MESSAGE_ENC_OTHER;
|
||||
|
||||
/**
|
||||
* Alias to check if the part is an attachment
|
||||
*
|
||||
* @var boolean $ifdisposition
|
||||
*/
|
||||
public $ifdisposition = false;
|
||||
|
||||
/**
|
||||
* Indicates if the part is an attachment
|
||||
*
|
||||
* @var string $disposition
|
||||
*/
|
||||
public $disposition = null;
|
||||
|
||||
/**
|
||||
* Alias to check if the part has a description
|
||||
*
|
||||
* @var boolean $ifdescription
|
||||
*/
|
||||
public $ifdescription = false;
|
||||
|
||||
/**
|
||||
* Part description if available
|
||||
*
|
||||
* @var string $description
|
||||
*/
|
||||
public $description = null;
|
||||
|
||||
/**
|
||||
* Part filename if available
|
||||
*
|
||||
* @var string $filename
|
||||
*/
|
||||
public $filename = null;
|
||||
|
||||
/**
|
||||
* Part name if available
|
||||
*
|
||||
* @var string $name
|
||||
*/
|
||||
public $name = null;
|
||||
|
||||
/**
|
||||
* Part id if available
|
||||
*
|
||||
* @var string $id
|
||||
*/
|
||||
public $id = null;
|
||||
|
||||
/**
|
||||
* The part number of the current part
|
||||
*
|
||||
* @var integer $part_number
|
||||
*/
|
||||
public $part_number = 0;
|
||||
|
||||
/**
|
||||
* Part length in bytes
|
||||
*
|
||||
* @var integer $bytes
|
||||
*/
|
||||
public $bytes = null;
|
||||
|
||||
/**
|
||||
* Part content type
|
||||
*
|
||||
* @var string|null $content_type
|
||||
*/
|
||||
public $content_type = null;
|
||||
|
||||
/**
|
||||
* @var Header $header
|
||||
*/
|
||||
private $header = null;
|
||||
|
||||
/**
|
||||
* Part constructor.
|
||||
* @param $raw_part
|
||||
* @param Header|null $header
|
||||
* @param integer $part_number
|
||||
*
|
||||
* @throws InvalidMessageDateException
|
||||
*/
|
||||
public function __construct($raw_part, Header $header = null, int $part_number = 0) {
|
||||
$this->raw = $raw_part;
|
||||
$this->header = $header;
|
||||
$this->part_number = $part_number;
|
||||
$this->parse();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the raw parts
|
||||
*
|
||||
* @throws InvalidMessageDateException
|
||||
*/
|
||||
protected function parse(){
|
||||
if ($this->header === null) {
|
||||
$body = $this->findHeaders();
|
||||
}else{
|
||||
$body = $this->raw;
|
||||
}
|
||||
|
||||
$this->parseDisposition();
|
||||
$this->parseDescription();
|
||||
$this->parseEncoding();
|
||||
|
||||
$this->charset = $this->header->get("charset");
|
||||
$this->name = $this->header->get("name");
|
||||
$this->filename = $this->header->get("filename");
|
||||
|
||||
if(!empty($this->header->get("id"))) {
|
||||
$this->id = $this->header->get("id");
|
||||
} else if(!empty($this->header->get("x_attachment_id"))){
|
||||
$this->id = $this->header->get("x_attachment_id");
|
||||
} else if(!empty($this->header->get("content_id"))){
|
||||
$this->id = strtr($this->header->get("content_id"), [
|
||||
'<' => '',
|
||||
'>' => ''
|
||||
]);
|
||||
}
|
||||
|
||||
$content_types = $this->header->get("content_type");
|
||||
if(!empty($content_types)){
|
||||
$this->subtype = $this->parseSubtype($content_types);
|
||||
$content_type = $content_types;
|
||||
if (is_array($content_types)) {
|
||||
$content_type = $content_types[0];
|
||||
}
|
||||
$parts = explode(';', $content_type);
|
||||
$this->content_type = trim($parts[0]);
|
||||
}
|
||||
|
||||
|
||||
$this->content = trim(rtrim($body));
|
||||
$this->bytes = strlen($this->content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find all available headers and return the leftover body segment
|
||||
*
|
||||
* @return string
|
||||
* @throws InvalidMessageDateException
|
||||
*/
|
||||
private function findHeaders(): string {
|
||||
$body = $this->raw;
|
||||
while (($pos = strpos($body, "\r\n")) > 0) {
|
||||
$body = substr($body, $pos + 2);
|
||||
}
|
||||
$headers = substr($this->raw, 0, strlen($body) * -1);
|
||||
$body = substr($body, 0, -2);
|
||||
|
||||
$this->header = new Header($headers);
|
||||
|
||||
return $body;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to parse the subtype if any is present
|
||||
* @param $content_type
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function parseSubtype($content_type){
|
||||
if (is_array($content_type)) {
|
||||
foreach ($content_type as $part){
|
||||
if ((strpos($part, "/")) !== false){
|
||||
return $this->parseSubtype($part);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if (($pos = strpos($content_type, "/")) !== false){
|
||||
return substr($content_type, $pos + 1);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to parse the disposition if any is present
|
||||
*/
|
||||
private function parseDisposition(){
|
||||
$content_disposition = $this->header->get("content_disposition");
|
||||
if($content_disposition !== null) {
|
||||
$this->ifdisposition = true;
|
||||
$this->disposition = (is_array($content_disposition)) ? implode(' ', $content_disposition) : $content_disposition;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to parse the description if any is present
|
||||
*/
|
||||
private function parseDescription(){
|
||||
$content_description = $this->header->get("content_description");
|
||||
if($content_description !== null) {
|
||||
$this->ifdescription = true;
|
||||
$this->description = $content_description;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to parse the encoding if any is present
|
||||
*/
|
||||
private function parseEncoding(){
|
||||
$encoding = $this->header->get("content_transfer_encoding");
|
||||
if($encoding !== null) {
|
||||
switch (strtolower($encoding)) {
|
||||
case "quoted-printable":
|
||||
$this->encoding = IMAP::MESSAGE_ENC_QUOTED_PRINTABLE;
|
||||
break;
|
||||
case "base64":
|
||||
$this->encoding = IMAP::MESSAGE_ENC_BASE64;
|
||||
break;
|
||||
case "7bit":
|
||||
$this->encoding = IMAP::MESSAGE_ENC_7BIT;
|
||||
break;
|
||||
case "8bit":
|
||||
$this->encoding = IMAP::MESSAGE_ENC_8BIT;
|
||||
break;
|
||||
case "binary":
|
||||
$this->encoding = IMAP::MESSAGE_ENC_BINARY;
|
||||
break;
|
||||
default:
|
||||
$this->encoding = IMAP::MESSAGE_ENC_OTHER;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the current part represents an attachment
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isAttachment(): bool {
|
||||
$valid_disposition = in_array(strtolower($this->disposition ?? ''), ClientManager::get('options.dispositions'));
|
||||
|
||||
if ($this->type == IMAP::MESSAGE_TYPE_TEXT && ($this->ifdisposition == 0 || empty($this->disposition) || !$valid_disposition)) {
|
||||
if (($this->subtype == null || in_array((strtolower($this->subtype)), ["plain", "html"])) && $this->filename == null && $this->name == null) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
979
vendor/webklex/php-imap/src/Query/Query.php
vendored
Normal file
979
vendor/webklex/php-imap/src/Query/Query.php
vendored
Normal file
@@ -0,0 +1,979 @@
|
||||
<?php
|
||||
/*
|
||||
* File: Query.php
|
||||
* Category: -
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 21.07.18 18:54
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Query;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Exception;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Support\Collection;
|
||||
use ReflectionException;
|
||||
use Webklex\PHPIMAP\Client;
|
||||
use Webklex\PHPIMAP\ClientManager;
|
||||
use Webklex\PHPIMAP\Exceptions\ConnectionFailedException;
|
||||
use Webklex\PHPIMAP\Exceptions\EventNotFoundException;
|
||||
use Webklex\PHPIMAP\Exceptions\GetMessagesFailedException;
|
||||
use Webklex\PHPIMAP\Exceptions\InvalidMessageDateException;
|
||||
use Webklex\PHPIMAP\Exceptions\MessageContentFetchingException;
|
||||
use Webklex\PHPIMAP\Exceptions\MessageFlagException;
|
||||
use Webklex\PHPIMAP\Exceptions\MessageHeaderFetchingException;
|
||||
use Webklex\PHPIMAP\Exceptions\MessageNotFoundException;
|
||||
use Webklex\PHPIMAP\Exceptions\MessageSearchValidationException;
|
||||
use Webklex\PHPIMAP\Exceptions\RuntimeException;
|
||||
use Webklex\PHPIMAP\IMAP;
|
||||
use Webklex\PHPIMAP\Message;
|
||||
use Webklex\PHPIMAP\Support\MessageCollection;
|
||||
|
||||
/**
|
||||
* Class Query
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Query
|
||||
*/
|
||||
class Query {
|
||||
|
||||
/** @var Collection $query */
|
||||
protected $query;
|
||||
|
||||
/** @var string $raw_query */
|
||||
protected $raw_query;
|
||||
|
||||
/** @var string[] $extensions */
|
||||
protected $extensions;
|
||||
|
||||
/** @var Client $client */
|
||||
protected $client;
|
||||
|
||||
/** @var int $limit */
|
||||
protected $limit = null;
|
||||
|
||||
/** @var int $page */
|
||||
protected $page = 1;
|
||||
|
||||
/** @var int $fetch_options */
|
||||
protected $fetch_options = null;
|
||||
|
||||
/** @var int $fetch_body */
|
||||
protected $fetch_body = true;
|
||||
|
||||
/** @var int $fetch_flags */
|
||||
protected $fetch_flags = true;
|
||||
|
||||
/** @var int|string $sequence */
|
||||
protected $sequence = IMAP::NIL;
|
||||
|
||||
/** @var string $fetch_order */
|
||||
protected $fetch_order;
|
||||
|
||||
/** @var string $date_format */
|
||||
protected $date_format;
|
||||
|
||||
/** @var bool $soft_fail */
|
||||
protected $soft_fail = false;
|
||||
|
||||
/** @var array $errors */
|
||||
protected $errors = [];
|
||||
|
||||
/**
|
||||
* Query constructor.
|
||||
* @param Client $client
|
||||
* @param string[] $extensions
|
||||
*/
|
||||
public function __construct(Client $client, array $extensions = []) {
|
||||
$this->setClient($client);
|
||||
|
||||
$this->sequence = ClientManager::get('options.sequence', IMAP::ST_MSGN);
|
||||
if (ClientManager::get('options.fetch') === IMAP::FT_PEEK) $this->leaveUnread();
|
||||
|
||||
if (ClientManager::get('options.fetch_order') === 'desc') {
|
||||
$this->fetch_order = 'desc';
|
||||
} else {
|
||||
$this->fetch_order = 'asc';
|
||||
}
|
||||
|
||||
$this->date_format = ClientManager::get('date_format', 'd M y');
|
||||
$this->soft_fail = ClientManager::get('options.soft_fail', false);
|
||||
|
||||
$this->setExtensions($extensions);
|
||||
$this->query = new Collection();
|
||||
$this->boot();
|
||||
}
|
||||
|
||||
/**
|
||||
* Instance boot method for additional functionality
|
||||
*/
|
||||
protected function boot() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a given value
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function parse_value($value): string {
|
||||
if ($value instanceof Carbon) {
|
||||
$value = $value->format($this->date_format);
|
||||
}
|
||||
|
||||
return (string)$value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a given date is a valid carbon object and if not try to convert it
|
||||
* @param string|Carbon $date
|
||||
*
|
||||
* @return Carbon
|
||||
* @throws MessageSearchValidationException
|
||||
*/
|
||||
protected function parse_date($date): Carbon {
|
||||
if ($date instanceof Carbon) return $date;
|
||||
|
||||
try {
|
||||
$date = Carbon::parse($date);
|
||||
} catch (Exception $e) {
|
||||
throw new MessageSearchValidationException();
|
||||
}
|
||||
|
||||
return $date;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the raw IMAP search query
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function generate_query(): string {
|
||||
$query = '';
|
||||
$this->query->each(function($statement) use (&$query) {
|
||||
if (count($statement) == 1) {
|
||||
$query .= $statement[0];
|
||||
} else {
|
||||
if ($statement[1] === null) {
|
||||
$query .= $statement[0];
|
||||
} else {
|
||||
if (is_numeric($statement[1])) {
|
||||
$query .= $statement[0] . ' ' . $statement[1];
|
||||
} else {
|
||||
$query .= $statement[0] . ' "' . $statement[1] . '"';
|
||||
}
|
||||
}
|
||||
}
|
||||
$query .= ' ';
|
||||
|
||||
});
|
||||
|
||||
$this->raw_query = trim($query);
|
||||
|
||||
return $this->raw_query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform an imap search request
|
||||
*
|
||||
* @return Collection
|
||||
* @throws GetMessagesFailedException
|
||||
*/
|
||||
protected function search(): Collection {
|
||||
$this->generate_query();
|
||||
|
||||
try {
|
||||
$available_messages = $this->client->getConnection()->search([$this->getRawQuery()], $this->sequence);
|
||||
return new Collection($available_messages);
|
||||
} catch (RuntimeException $e) {
|
||||
throw new GetMessagesFailedException("failed to fetch messages", 0, $e);
|
||||
} catch (ConnectionFailedException $e) {
|
||||
throw new GetMessagesFailedException("failed to fetch messages", 0, $e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Count all available messages matching the current search criteria
|
||||
*
|
||||
* @return int
|
||||
* @throws GetMessagesFailedException
|
||||
*/
|
||||
public function count(): int {
|
||||
return $this->search()->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch a given id collection
|
||||
* @param Collection $available_messages
|
||||
*
|
||||
* @return array
|
||||
* @throws ConnectionFailedException
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
protected function fetch(Collection $available_messages): array {
|
||||
if ($this->fetch_order === 'desc') {
|
||||
$available_messages = $available_messages->reverse();
|
||||
}
|
||||
|
||||
$uids = $available_messages->forPage($this->page, $this->limit)->toArray();
|
||||
$extensions = $this->getExtensions();
|
||||
if (empty($extensions) === false && method_exists($this->client->getConnection(), "fetch")) {
|
||||
$extensions = $this->client->getConnection()->fetch($extensions, $uids, null, $this->sequence);
|
||||
}
|
||||
$flags = $this->client->getConnection()->flags($uids, $this->sequence);
|
||||
$headers = $this->client->getConnection()->headers($uids, "RFC822", $this->sequence);
|
||||
|
||||
$contents = [];
|
||||
if ($this->getFetchBody()) {
|
||||
$contents = $this->client->getConnection()->content($uids, "RFC822", $this->sequence);
|
||||
}
|
||||
|
||||
return [
|
||||
"uids" => $uids,
|
||||
"flags" => $flags,
|
||||
"headers" => $headers,
|
||||
"contents" => $contents,
|
||||
"extensions" => $extensions,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a new message from given raw components
|
||||
* @param integer $uid
|
||||
* @param integer $msglist
|
||||
* @param string $header
|
||||
* @param string $content
|
||||
* @param array $flags
|
||||
*
|
||||
* @return Message|null
|
||||
* @throws ConnectionFailedException
|
||||
* @throws EventNotFoundException
|
||||
* @throws GetMessagesFailedException
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
protected function make(int $uid, int $msglist, string $header, string $content, array $flags) {
|
||||
try {
|
||||
return Message::make($uid, $msglist, $this->getClient(), $header, $content, $flags, $this->getFetchOptions(), $this->sequence);
|
||||
} catch (MessageNotFoundException $e) {
|
||||
$this->setError($uid, $e);
|
||||
} catch (RuntimeException $e) {
|
||||
$this->setError($uid, $e);
|
||||
} catch (MessageFlagException $e) {
|
||||
$this->setError($uid, $e);
|
||||
} catch (InvalidMessageDateException $e) {
|
||||
$this->setError($uid, $e);
|
||||
} catch (MessageContentFetchingException $e) {
|
||||
$this->setError($uid, $e);
|
||||
}
|
||||
|
||||
$this->handleException($uid);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the message key for a given message
|
||||
* @param string $message_key
|
||||
* @param integer $msglist
|
||||
* @param Message $message
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getMessageKey(string $message_key, int $msglist, Message $message): string {
|
||||
switch ($message_key) {
|
||||
case 'number':
|
||||
$key = $message->getMessageNo();
|
||||
break;
|
||||
case 'list':
|
||||
$key = $msglist;
|
||||
break;
|
||||
case 'uid':
|
||||
$key = $message->getUid();
|
||||
break;
|
||||
default:
|
||||
$key = $message->getMessageId();
|
||||
break;
|
||||
}
|
||||
return (string)$key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Curates a given collection aof messages
|
||||
* @param Collection $available_messages
|
||||
*
|
||||
* @return MessageCollection
|
||||
* @throws GetMessagesFailedException
|
||||
*/
|
||||
public function curate_messages(Collection $available_messages): MessageCollection {
|
||||
try {
|
||||
if ($available_messages->count() > 0) {
|
||||
return $this->populate($available_messages);
|
||||
}
|
||||
return MessageCollection::make([]);
|
||||
} catch (Exception $e) {
|
||||
throw new GetMessagesFailedException($e->getMessage(), 0, $e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate a given id collection and receive a fully fetched message collection
|
||||
* @param Collection $available_messages
|
||||
*
|
||||
* @return MessageCollection
|
||||
* @throws ConnectionFailedException
|
||||
* @throws EventNotFoundException
|
||||
* @throws GetMessagesFailedException
|
||||
* @throws ReflectionException
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
protected function populate(Collection $available_messages): MessageCollection {
|
||||
$messages = MessageCollection::make([]);
|
||||
|
||||
$messages->total($available_messages->count());
|
||||
|
||||
$message_key = ClientManager::get('options.message_key');
|
||||
|
||||
$raw_messages = $this->fetch($available_messages);
|
||||
|
||||
$msglist = 0;
|
||||
foreach ($raw_messages["headers"] as $uid => $header) {
|
||||
$content = $raw_messages["contents"][$uid] ?? "";
|
||||
$flag = $raw_messages["flags"][$uid] ?? [];
|
||||
$extensions = $raw_messages["extensions"][$uid] ?? [];
|
||||
|
||||
$message = $this->make($uid, $msglist, $header, $content, $flag);
|
||||
foreach($extensions as $key => $extension) {
|
||||
$message->getHeader()->set($key, $extension);
|
||||
}
|
||||
if ($message !== null) {
|
||||
$key = $this->getMessageKey($message_key, $msglist, $message);
|
||||
$messages->put("$key", $message);
|
||||
}
|
||||
$msglist++;
|
||||
}
|
||||
|
||||
return $messages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the current query and return all found messages
|
||||
*
|
||||
* @return MessageCollection
|
||||
* @throws GetMessagesFailedException
|
||||
*/
|
||||
public function get(): MessageCollection {
|
||||
return $this->curate_messages($this->search());
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the current query as chunked requests
|
||||
* @param callable $callback
|
||||
* @param int $chunk_size
|
||||
* @param int $start_chunk
|
||||
*
|
||||
* @throws ConnectionFailedException
|
||||
* @throws EventNotFoundException
|
||||
* @throws GetMessagesFailedException
|
||||
* @throws ReflectionException
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function chunked(callable $callback, int $chunk_size = 10, int $start_chunk = 1) {
|
||||
$available_messages = $this->search();
|
||||
if (($available_messages_count = $available_messages->count()) > 0) {
|
||||
$old_limit = $this->limit;
|
||||
$old_page = $this->page;
|
||||
|
||||
$this->limit = $chunk_size;
|
||||
$this->page = $start_chunk;
|
||||
$handled_messages_count = 0;
|
||||
do {
|
||||
$messages = $this->populate($available_messages);
|
||||
$handled_messages_count += $messages->count();
|
||||
$callback($messages, $this->page);
|
||||
$this->page++;
|
||||
} while ($handled_messages_count < $available_messages_count);
|
||||
$this->limit = $old_limit;
|
||||
$this->page = $old_page;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Paginate the current query
|
||||
* @param int $per_page Results you which to receive per page
|
||||
* @param int|null $page The current page you are on (e.g. 0, 1, 2, ...) use `null` to enable auto mode
|
||||
* @param string $page_name The page name / uri parameter used for the generated links and the auto mode
|
||||
*
|
||||
* @return LengthAwarePaginator
|
||||
* @throws GetMessagesFailedException
|
||||
*/
|
||||
public function paginate(int $per_page = 5, $page = null, string $page_name = 'imap_page'): LengthAwarePaginator {
|
||||
if (
|
||||
$page === null
|
||||
&& isset($_GET[$page_name])
|
||||
&& $_GET[$page_name] > 0
|
||||
) {
|
||||
$this->page = intval($_GET[$page_name]);
|
||||
} elseif ($page > 0) {
|
||||
$this->page = $page;
|
||||
}
|
||||
|
||||
$this->limit = $per_page;
|
||||
|
||||
return $this->get()->paginate($per_page, $this->page, $page_name, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a new Message instance
|
||||
* @param int $uid
|
||||
* @param int|null $msglist
|
||||
* @param int|string|null $sequence
|
||||
*
|
||||
* @return Message
|
||||
* @throws ConnectionFailedException
|
||||
* @throws RuntimeException
|
||||
* @throws InvalidMessageDateException
|
||||
* @throws MessageContentFetchingException
|
||||
* @throws MessageHeaderFetchingException
|
||||
* @throws EventNotFoundException
|
||||
* @throws MessageFlagException
|
||||
* @throws MessageNotFoundException
|
||||
*/
|
||||
public function getMessage(int $uid, $msglist = null, $sequence = null): Message {
|
||||
return new Message($uid, $msglist, $this->getClient(), $this->getFetchOptions(), $this->getFetchBody(), $this->getFetchFlags(), $sequence ? $sequence : $this->sequence);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a message by its message number
|
||||
* @param $msgn
|
||||
* @param int|null $msglist
|
||||
*
|
||||
* @return Message
|
||||
* @throws ConnectionFailedException
|
||||
* @throws InvalidMessageDateException
|
||||
* @throws MessageContentFetchingException
|
||||
* @throws MessageHeaderFetchingException
|
||||
* @throws RuntimeException
|
||||
* @throws EventNotFoundException
|
||||
* @throws MessageFlagException
|
||||
* @throws MessageNotFoundException
|
||||
*/
|
||||
public function getMessageByMsgn($msgn, $msglist = null): Message {
|
||||
return $this->getMessage($msgn, $msglist, IMAP::ST_MSGN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a message by its uid
|
||||
* @param $uid
|
||||
*
|
||||
* @return Message
|
||||
* @throws ConnectionFailedException
|
||||
* @throws InvalidMessageDateException
|
||||
* @throws MessageContentFetchingException
|
||||
* @throws MessageHeaderFetchingException
|
||||
* @throws RuntimeException
|
||||
* @throws EventNotFoundException
|
||||
* @throws MessageFlagException
|
||||
* @throws MessageNotFoundException
|
||||
*/
|
||||
public function getMessageByUid($uid): Message {
|
||||
return $this->getMessage($uid, null, IMAP::ST_UID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter all available uids by a given closure and get a curated list of messages
|
||||
* @param callable $closure
|
||||
*
|
||||
* @return MessageCollection
|
||||
* @throws ConnectionFailedException
|
||||
* @throws GetMessagesFailedException
|
||||
* @throws MessageNotFoundException
|
||||
*/
|
||||
public function filter(callable $closure): MessageCollection {
|
||||
$connection = $this->getClient()->getConnection();
|
||||
|
||||
$uids = $connection->getUid();
|
||||
$available_messages = new Collection();
|
||||
if (is_array($uids)) {
|
||||
foreach ($uids as $id){
|
||||
if ($closure($id)) {
|
||||
$available_messages->push($id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->curate_messages($available_messages);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all messages with an uid greater or equal to a given UID
|
||||
* @param int $uid
|
||||
*
|
||||
* @return MessageCollection
|
||||
* @throws ConnectionFailedException
|
||||
* @throws GetMessagesFailedException
|
||||
* @throws MessageNotFoundException
|
||||
*/
|
||||
public function getByUidGreaterOrEqual(int $uid): MessageCollection {
|
||||
return $this->filter(function($id) use($uid){
|
||||
return $id >= $uid;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all messages with an uid greater than a given UID
|
||||
* @param int $uid
|
||||
*
|
||||
* @return MessageCollection
|
||||
* @throws ConnectionFailedException
|
||||
* @throws GetMessagesFailedException
|
||||
* @throws MessageNotFoundException
|
||||
*/
|
||||
public function getByUidGreater(int $uid): MessageCollection {
|
||||
return $this->filter(function($id) use($uid){
|
||||
return $id > $uid;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all messages with an uid lower than a given UID
|
||||
* @param int $uid
|
||||
*
|
||||
* @return MessageCollection
|
||||
* @throws ConnectionFailedException
|
||||
* @throws GetMessagesFailedException
|
||||
* @throws MessageNotFoundException
|
||||
*/
|
||||
public function getByUidLower(int $uid): MessageCollection {
|
||||
return $this->filter(function($id) use($uid){
|
||||
return $id < $uid;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all messages with an uid lower or equal to a given UID
|
||||
* @param int $uid
|
||||
*
|
||||
* @return MessageCollection
|
||||
* @throws ConnectionFailedException
|
||||
* @throws GetMessagesFailedException
|
||||
* @throws MessageNotFoundException
|
||||
*/
|
||||
public function getByUidLowerOrEqual(int $uid): MessageCollection {
|
||||
return $this->filter(function($id) use($uid){
|
||||
return $id <= $uid;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all messages with an uid greater than a given UID
|
||||
* @param int $uid
|
||||
*
|
||||
* @return MessageCollection
|
||||
* @throws ConnectionFailedException
|
||||
* @throws GetMessagesFailedException
|
||||
* @throws MessageNotFoundException
|
||||
*/
|
||||
public function getByUidLowerThan(int $uid): MessageCollection {
|
||||
return $this->filter(function($id) use($uid){
|
||||
return $id < $uid;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Don't mark messages as read when fetching
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function leaveUnread(): Query {
|
||||
$this->setFetchOptions(IMAP::FT_PEEK);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark all messages as read when fetching
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function markAsRead(): Query {
|
||||
$this->setFetchOptions(IMAP::FT_UID);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the sequence type
|
||||
* @param int $sequence
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setSequence(int $sequence): Query {
|
||||
$this->sequence = $sequence;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the sequence type
|
||||
*
|
||||
* @return int|string
|
||||
*/
|
||||
public function getSequence() {
|
||||
return $this->sequence;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Client
|
||||
* @throws ConnectionFailedException
|
||||
*/
|
||||
public function getClient(): Client {
|
||||
$this->client->checkConnection();
|
||||
return $this->client;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the limit and page for the current query
|
||||
* @param int $limit
|
||||
* @param int $page
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function limit(int $limit, int $page = 1): Query {
|
||||
if ($page >= 1) $this->page = $page;
|
||||
$this->limit = $limit;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
public function getQuery(): Collection {
|
||||
return $this->query;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $query
|
||||
* @return Query
|
||||
*/
|
||||
public function setQuery(array $query): Query {
|
||||
$this->query = new Collection($query);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getRawQuery(): string {
|
||||
return $this->raw_query;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $raw_query
|
||||
* @return Query
|
||||
*/
|
||||
public function setRawQuery(string $raw_query): Query {
|
||||
$this->raw_query = $raw_query;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getExtensions(): array {
|
||||
return $this->extensions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $extensions
|
||||
* @return Query
|
||||
*/
|
||||
public function setExtensions(array $extensions): Query {
|
||||
$this->extensions = $extensions;
|
||||
if (count($this->extensions) > 0) {
|
||||
if (in_array("UID", $this->extensions) === false) {
|
||||
$this->extensions[] = "UID";
|
||||
}
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Client $client
|
||||
* @return Query
|
||||
*/
|
||||
public function setClient(Client $client): Query {
|
||||
$this->client = $client;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the set fetch limit
|
||||
* @return int
|
||||
*/
|
||||
public function getLimit() {
|
||||
return $this->limit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $limit
|
||||
* @return Query
|
||||
*/
|
||||
public function setLimit(int $limit): Query {
|
||||
$this->limit = $limit <= 0 ? null : $limit;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getPage(): int {
|
||||
return $this->page;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $page
|
||||
* @return Query
|
||||
*/
|
||||
public function setPage(int $page): Query {
|
||||
$this->page = $page;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $fetch_options
|
||||
* @return Query
|
||||
*/
|
||||
public function setFetchOptions(int $fetch_options): Query {
|
||||
$this->fetch_options = $fetch_options;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $fetch_options
|
||||
* @return Query
|
||||
*/
|
||||
public function fetchOptions(int $fetch_options): Query {
|
||||
return $this->setFetchOptions($fetch_options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getFetchOptions() {
|
||||
return $this->fetch_options;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
public function getFetchBody() {
|
||||
return $this->fetch_body;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param boolean $fetch_body
|
||||
* @return Query
|
||||
*/
|
||||
public function setFetchBody(bool $fetch_body): Query {
|
||||
$this->fetch_body = $fetch_body;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param boolean $fetch_body
|
||||
* @return Query
|
||||
*/
|
||||
public function fetchBody(bool $fetch_body): Query {
|
||||
return $this->setFetchBody($fetch_body);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getFetchFlags() {
|
||||
return $this->fetch_flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $fetch_flags
|
||||
* @return Query
|
||||
*/
|
||||
public function setFetchFlags(int $fetch_flags): Query {
|
||||
$this->fetch_flags = $fetch_flags;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $fetch_order
|
||||
* @return Query
|
||||
*/
|
||||
public function setFetchOrder(string $fetch_order): Query {
|
||||
$fetch_order = strtolower($fetch_order);
|
||||
|
||||
if (in_array($fetch_order, ['asc', 'desc'])) {
|
||||
$this->fetch_order = $fetch_order;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $fetch_order
|
||||
* @return Query
|
||||
*/
|
||||
public function fetchOrder(string $fetch_order): Query {
|
||||
return $this->setFetchOrder($fetch_order);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getFetchOrder(): string {
|
||||
return $this->fetch_order;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Query
|
||||
*/
|
||||
public function setFetchOrderAsc(): Query {
|
||||
return $this->setFetchOrder('asc');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Query
|
||||
*/
|
||||
public function fetchOrderAsc(): Query {
|
||||
return $this->setFetchOrderAsc();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Query
|
||||
*/
|
||||
public function setFetchOrderDesc(): Query {
|
||||
return $this->setFetchOrder('desc');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Query
|
||||
*/
|
||||
public function fetchOrderDesc(): Query {
|
||||
return $this->setFetchOrderDesc();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Query
|
||||
* @var boolean $state
|
||||
*
|
||||
*/
|
||||
public function softFail(bool $state = true): Query {
|
||||
return $this->setSoftFail($state);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Query
|
||||
* @var boolean $state
|
||||
*
|
||||
*/
|
||||
public function setSoftFail(bool $state = true): Query {
|
||||
$this->soft_fail = $state;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
public function getSoftFail(): bool {
|
||||
return $this->soft_fail;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the exception for a given uid
|
||||
* @param integer $uid
|
||||
*
|
||||
* @throws GetMessagesFailedException
|
||||
*/
|
||||
protected function handleException(int $uid) {
|
||||
if ($this->soft_fail === false && $this->hasError($uid)) {
|
||||
$error = $this->getError($uid);
|
||||
throw new GetMessagesFailedException($error->getMessage(), 0, $error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new error to the error holder
|
||||
* @param integer $uid
|
||||
* @param Exception $error
|
||||
*/
|
||||
protected function setError(int $uid, Exception $error) {
|
||||
$this->errors[$uid] = $error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if there are any errors / exceptions present
|
||||
* @return boolean
|
||||
* @var integer|null $uid
|
||||
*
|
||||
*/
|
||||
public function hasErrors($uid = null): bool {
|
||||
if ($uid !== null) {
|
||||
return $this->hasError($uid);
|
||||
}
|
||||
return count($this->errors) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if there is an error / exception present
|
||||
* @return boolean
|
||||
* @var integer $uid
|
||||
*
|
||||
*/
|
||||
public function hasError(int $uid): bool {
|
||||
return isset($this->errors[$uid]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all available errors / exceptions
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function errors(): array {
|
||||
return $this->getErrors();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all available errors / exceptions
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getErrors(): array {
|
||||
return $this->errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a specific error / exception
|
||||
* @return Exception|null
|
||||
* @var integer $uid
|
||||
*
|
||||
*/
|
||||
public function error(int $uid) {
|
||||
return $this->getError($uid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a specific error / exception
|
||||
* @return Exception|null
|
||||
* @var integer $uid
|
||||
*
|
||||
*/
|
||||
public function getError(int $uid) {
|
||||
if ($this->hasError($uid)) {
|
||||
return $this->errors[$uid];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
546
vendor/webklex/php-imap/src/Query/WhereQuery.php
vendored
Executable file
546
vendor/webklex/php-imap/src/Query/WhereQuery.php
vendored
Executable file
@@ -0,0 +1,546 @@
|
||||
<?php
|
||||
/*
|
||||
* File: Query.php
|
||||
* Category: -
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 21.07.18 18:54
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Query;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Support\Str;
|
||||
use Webklex\PHPIMAP\Exceptions\InvalidWhereQueryCriteriaException;
|
||||
use Webklex\PHPIMAP\Exceptions\MethodNotFoundException;
|
||||
use Webklex\PHPIMAP\Exceptions\MessageSearchValidationException;
|
||||
|
||||
/**
|
||||
* Class WhereQuery
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Query
|
||||
*
|
||||
* @method WhereQuery all()
|
||||
* @method WhereQuery answered()
|
||||
* @method WhereQuery deleted()
|
||||
* @method WhereQuery new()
|
||||
* @method WhereQuery old()
|
||||
* @method WhereQuery recent()
|
||||
* @method WhereQuery seen()
|
||||
* @method WhereQuery unanswered()
|
||||
* @method WhereQuery undeleted()
|
||||
* @method WhereQuery unflagged()
|
||||
* @method WhereQuery unseen()
|
||||
* @method WhereQuery not()
|
||||
* @method WhereQuery unkeyword($value)
|
||||
* @method WhereQuery to($value)
|
||||
* @method WhereQuery text($value)
|
||||
* @method WhereQuery subject($value)
|
||||
* @method WhereQuery since($date)
|
||||
* @method WhereQuery on($date)
|
||||
* @method WhereQuery keyword($value)
|
||||
* @method WhereQuery from($value)
|
||||
* @method WhereQuery flagged()
|
||||
* @method WhereQuery cc($value)
|
||||
* @method WhereQuery body($value)
|
||||
* @method WhereQuery before($date)
|
||||
* @method WhereQuery bcc($value)
|
||||
* @method WhereQuery inReplyTo($value)
|
||||
* @method WhereQuery messageId($value)
|
||||
*
|
||||
* @mixin Query
|
||||
*/
|
||||
class WhereQuery extends Query {
|
||||
|
||||
/**
|
||||
* @var array $available_criteria
|
||||
*/
|
||||
protected $available_criteria = [
|
||||
'OR', 'AND',
|
||||
'ALL', 'ANSWERED', 'BCC', 'BEFORE', 'BODY', 'CC', 'DELETED', 'FLAGGED', 'FROM', 'KEYWORD',
|
||||
'NEW', 'NOT', 'OLD', 'ON', 'RECENT', 'SEEN', 'SINCE', 'SUBJECT', 'TEXT', 'TO',
|
||||
'UNANSWERED', 'UNDELETED', 'UNFLAGGED', 'UNKEYWORD', 'UNSEEN', 'UID'
|
||||
];
|
||||
|
||||
/**
|
||||
* Magic method in order to allow alias usage of all "where" methods in an optional connection with "NOT"
|
||||
* @param string $name
|
||||
* @param array|null $arguments
|
||||
*
|
||||
* @return mixed
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
* @throws MethodNotFoundException
|
||||
*/
|
||||
public function __call(string $name, $arguments) {
|
||||
$that = $this;
|
||||
|
||||
$name = Str::camel($name);
|
||||
|
||||
if (strtolower(substr($name, 0, 3)) === 'not') {
|
||||
$that = $that->whereNot();
|
||||
$name = substr($name, 3);
|
||||
}
|
||||
|
||||
if (strpos(strtolower($name), "where") === false) {
|
||||
$method = 'where' . ucfirst($name);
|
||||
} else {
|
||||
$method = lcfirst($name);
|
||||
}
|
||||
|
||||
if (method_exists($this, $method) === true) {
|
||||
return call_user_func_array([$that, $method], $arguments);
|
||||
}
|
||||
|
||||
throw new MethodNotFoundException("Method " . self::class . '::' . $method . '() is not supported');
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate a given criteria
|
||||
* @param $criteria
|
||||
*
|
||||
* @return string
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
protected function validate_criteria($criteria): string {
|
||||
$command = strtoupper($criteria);
|
||||
if (substr($command, 0, 7) === "CUSTOM ") {
|
||||
return substr($criteria, 7);
|
||||
}
|
||||
if (in_array($command, $this->available_criteria) === false) {
|
||||
throw new InvalidWhereQueryCriteriaException("Invalid imap search criteria: $command");
|
||||
}
|
||||
|
||||
return $criteria;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register search parameters
|
||||
* @param mixed $criteria
|
||||
* @param null $value
|
||||
*
|
||||
* @return $this
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*
|
||||
* Examples:
|
||||
* $query->from("someone@email.tld")->seen();
|
||||
* $query->whereFrom("someone@email.tld")->whereSeen();
|
||||
* $query->where([["FROM" => "someone@email.tld"], ["SEEN"]]);
|
||||
* $query->where(["FROM" => "someone@email.tld"])->where(["SEEN"]);
|
||||
* $query->where(["FROM" => "someone@email.tld", "SEEN"]);
|
||||
* $query->where("FROM", "someone@email.tld")->where("SEEN");
|
||||
*/
|
||||
public function where($criteria, $value = null): WhereQuery {
|
||||
if (is_array($criteria)) {
|
||||
foreach ($criteria as $key => $value) {
|
||||
if (is_numeric($key)) {
|
||||
$this->where($value);
|
||||
}else{
|
||||
$this->where($key, $value);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$this->push_search_criteria($criteria, $value);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Push a given search criteria and value pair to the search query
|
||||
* @param $criteria string
|
||||
* @param $value mixed
|
||||
*
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
protected function push_search_criteria(string $criteria, $value){
|
||||
$criteria = $this->validate_criteria($criteria);
|
||||
$value = $this->parse_value($value);
|
||||
|
||||
if ($value === null || $value === '') {
|
||||
$this->query->push([$criteria]);
|
||||
} else {
|
||||
$this->query->push([$criteria, $value]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Closure $closure
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function orWhere(Closure $closure = null): WhereQuery {
|
||||
$this->query->push(['OR']);
|
||||
if ($closure !== null) $closure($this);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Closure $closure
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function andWhere(Closure $closure = null): WhereQuery {
|
||||
$this->query->push(['AND']);
|
||||
if ($closure !== null) $closure($this);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereAll(): WhereQuery {
|
||||
return $this->where('ALL');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereAnswered(): WhereQuery {
|
||||
return $this->where('ANSWERED');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
*
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereBcc(string $value): WhereQuery {
|
||||
return $this->where('BCC', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
* @throws MessageSearchValidationException
|
||||
*/
|
||||
public function whereBefore($value): WhereQuery {
|
||||
$date = $this->parse_date($value);
|
||||
return $this->where('BEFORE', $date);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
*
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereBody(string $value): WhereQuery {
|
||||
return $this->where('BODY', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
*
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereCc(string $value): WhereQuery {
|
||||
return $this->where('CC', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereDeleted(): WhereQuery {
|
||||
return $this->where('DELETED');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
*
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereFlagged(string $value): WhereQuery {
|
||||
return $this->where('FLAGGED', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
*
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereFrom(string $value): WhereQuery {
|
||||
return $this->where('FROM', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
*
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereKeyword(string $value): WhereQuery {
|
||||
return $this->where('KEYWORD', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereNew(): WhereQuery {
|
||||
return $this->where('NEW');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereNot(): WhereQuery {
|
||||
return $this->where('NOT');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereOld(): WhereQuery {
|
||||
return $this->where('OLD');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return WhereQuery
|
||||
* @throws MessageSearchValidationException
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereOn($value): WhereQuery {
|
||||
$date = $this->parse_date($value);
|
||||
return $this->where('ON', $date);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereRecent(): WhereQuery {
|
||||
return $this->where('RECENT');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereSeen(): WhereQuery {
|
||||
return $this->where('SEEN');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return WhereQuery
|
||||
* @throws MessageSearchValidationException
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereSince($value): WhereQuery {
|
||||
$date = $this->parse_date($value);
|
||||
return $this->where('SINCE', $date);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
*
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereSubject(string $value): WhereQuery {
|
||||
return $this->where('SUBJECT', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
*
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereText(string $value): WhereQuery {
|
||||
return $this->where('TEXT', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
*
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereTo(string $value): WhereQuery {
|
||||
return $this->where('TO', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
*
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereUnkeyword(string $value): WhereQuery {
|
||||
return $this->where('UNKEYWORD', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereUnanswered(): WhereQuery {
|
||||
return $this->where('UNANSWERED');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereUndeleted(): WhereQuery {
|
||||
return $this->where('UNDELETED');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereUnflagged(): WhereQuery {
|
||||
return $this->where('UNFLAGGED');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereUnseen(): WhereQuery {
|
||||
return $this->where('UNSEEN');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereNoXSpam(): WhereQuery {
|
||||
return $this->where("CUSTOM X-Spam-Flag NO");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereIsXSpam(): WhereQuery {
|
||||
return $this->where("CUSTOM X-Spam-Flag YES");
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for a specific header value
|
||||
* @param $header
|
||||
* @param $value
|
||||
*
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereHeader($header, $value): WhereQuery {
|
||||
return $this->where("CUSTOM HEADER $header $value");
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for a specific message id
|
||||
* @param $messageId
|
||||
*
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereMessageId($messageId): WhereQuery {
|
||||
return $this->whereHeader("Message-ID", $messageId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for a specific message id
|
||||
* @param $messageId
|
||||
*
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereInReplyTo($messageId): WhereQuery {
|
||||
return $this->whereHeader("In-Reply-To", $messageId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $country_code
|
||||
*
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereLanguage($country_code): WhereQuery {
|
||||
return $this->where("Content-Language $country_code");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get message be it UID.
|
||||
*
|
||||
* @param int|string $uid
|
||||
*
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereUid($uid): WhereQuery {
|
||||
return $this->where('UID', $uid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get messages by their UIDs.
|
||||
*
|
||||
* @param array<int, int> $uids
|
||||
*
|
||||
* @return WhereQuery
|
||||
* @throws InvalidWhereQueryCriteriaException
|
||||
*/
|
||||
public function whereUidIn(array $uids): WhereQuery {
|
||||
$uids = implode(',', $uids);
|
||||
return $this->where('UID', $uids);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the callback if the given "value" is truthy.
|
||||
* copied from @url https://github.com/laravel/framework/blob/8.x/src/Illuminate/Support/Traits/Conditionable.php
|
||||
*
|
||||
* @param mixed $value
|
||||
* @param callable $callback
|
||||
* @param callable|null $default
|
||||
* @return $this|mixed
|
||||
*/
|
||||
public function when($value, callable $callback, $default = null) {
|
||||
if ($value) {
|
||||
return $callback($this, $value) ?: $this;
|
||||
} elseif ($default) {
|
||||
return $default($this, $value) ?: $this;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the callback if the given "value" is falsy.
|
||||
* copied from @url https://github.com/laravel/framework/blob/8.x/src/Illuminate/Support/Traits/Conditionable.php
|
||||
*
|
||||
* @param mixed $value
|
||||
* @param callable $callback
|
||||
* @param callable|null $default
|
||||
* @return $this|mixed
|
||||
*/
|
||||
public function unless($value, callable $callback, $default = null) {
|
||||
if (!$value) {
|
||||
return $callback($this, $value) ?: $this;
|
||||
} elseif ($default) {
|
||||
return $default($this, $value) ?: $this;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
174
vendor/webklex/php-imap/src/Structure.php
vendored
Normal file
174
vendor/webklex/php-imap/src/Structure.php
vendored
Normal file
@@ -0,0 +1,174 @@
|
||||
<?php
|
||||
/*
|
||||
* File: Structure.php
|
||||
* Category: -
|
||||
* Author: M.Goldenbaum
|
||||
* Created: 17.09.20 20:38
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP;
|
||||
|
||||
|
||||
use Webklex\PHPIMAP\Exceptions\InvalidMessageDateException;
|
||||
use Webklex\PHPIMAP\Exceptions\MessageContentFetchingException;
|
||||
|
||||
/**
|
||||
* Class Structure
|
||||
*
|
||||
* @package Webklex\PHPIMAP
|
||||
*/
|
||||
class Structure {
|
||||
|
||||
/**
|
||||
* Raw structure
|
||||
*
|
||||
* @var string $raw
|
||||
*/
|
||||
public $raw = "";
|
||||
|
||||
/**
|
||||
* @var Header $header
|
||||
*/
|
||||
private $header = null;
|
||||
|
||||
/**
|
||||
* Message type (if multipart or not)
|
||||
*
|
||||
* @var int $type
|
||||
*/
|
||||
public $type = IMAP::MESSAGE_TYPE_TEXT;
|
||||
|
||||
/**
|
||||
* All available parts
|
||||
*
|
||||
* @var Part[] $parts
|
||||
*/
|
||||
public $parts = [];
|
||||
|
||||
/**
|
||||
* Config holder
|
||||
*
|
||||
* @var array $config
|
||||
*/
|
||||
protected $config = [];
|
||||
|
||||
/**
|
||||
* Structure constructor.
|
||||
* @param $raw_structure
|
||||
* @param Header $header
|
||||
*
|
||||
* @throws MessageContentFetchingException
|
||||
* @throws InvalidMessageDateException
|
||||
*/
|
||||
public function __construct($raw_structure, Header $header) {
|
||||
$this->raw = $raw_structure;
|
||||
$this->header = $header;
|
||||
$this->config = ClientManager::get('options');
|
||||
$this->parse();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the given raw structure
|
||||
*
|
||||
* @throws MessageContentFetchingException
|
||||
* @throws InvalidMessageDateException
|
||||
*/
|
||||
protected function parse(){
|
||||
$this->findContentType();
|
||||
$this->parts = $this->find_parts();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the message content type
|
||||
*/
|
||||
public function findContentType(){
|
||||
$content_type = $this->header->get("content_type");
|
||||
$content_type = (is_array($content_type)) ? implode(' ', $content_type) : $content_type;
|
||||
if($content_type && stripos($content_type, 'multipart') === 0) {
|
||||
$this->type = IMAP::MESSAGE_TYPE_MULTIPART;
|
||||
}else{
|
||||
$this->type = IMAP::MESSAGE_TYPE_TEXT;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find all available headers and return the left over body segment
|
||||
* @var string $context
|
||||
* @var integer $part_number
|
||||
*
|
||||
* @return Part[]
|
||||
* @throws InvalidMessageDateException
|
||||
*/
|
||||
private function parsePart(string $context, int $part_number = 0): array {
|
||||
$body = $context;
|
||||
while (($pos = strpos($body, "\r\n")) > 0) {
|
||||
$body = substr($body, $pos + 2);
|
||||
}
|
||||
$headers = substr($context, 0, strlen($body) * -1);
|
||||
$body = substr($body, 0, -2);
|
||||
|
||||
$headers = new Header($headers);
|
||||
if (($boundary = $headers->getBoundary()) !== null) {
|
||||
return $this->detectParts($boundary, $body, $part_number);
|
||||
}
|
||||
return [new Part($body, $headers, $part_number)];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $boundary
|
||||
* @param string $context
|
||||
* @param int $part_number
|
||||
*
|
||||
* @return array
|
||||
* @throws InvalidMessageDateException
|
||||
*/
|
||||
private function detectParts(string $boundary, string $context, int $part_number = 0): array {
|
||||
$base_parts = explode( $boundary, $context);
|
||||
$final_parts = [];
|
||||
foreach($base_parts as $ctx) {
|
||||
$ctx = substr($ctx, 2);
|
||||
if ($ctx !== "--" && $ctx != "") {
|
||||
$parts = $this->parsePart($ctx, $part_number);
|
||||
foreach ($parts as $part) {
|
||||
$final_parts[] = $part;
|
||||
$part_number = $part->part_number;
|
||||
}
|
||||
$part_number++;
|
||||
}
|
||||
}
|
||||
return $final_parts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find all available parts
|
||||
*
|
||||
* @return array
|
||||
* @throws MessageContentFetchingException
|
||||
* @throws InvalidMessageDateException
|
||||
*/
|
||||
public function find_parts(): array {
|
||||
if($this->type === IMAP::MESSAGE_TYPE_MULTIPART) {
|
||||
if (($boundary = $this->header->getBoundary()) === null) {
|
||||
throw new MessageContentFetchingException("no content found", 0);
|
||||
}
|
||||
|
||||
return $this->detectParts($boundary, $this->raw);
|
||||
}
|
||||
|
||||
return [new Part($this->raw, $this->header)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to find a boundary if possible
|
||||
*
|
||||
* @return string|null
|
||||
* @Depricated since version 2.4.4
|
||||
*/
|
||||
public function getBoundary(){
|
||||
return $this->header->getBoundary();
|
||||
}
|
||||
}
|
||||
22
vendor/webklex/php-imap/src/Support/AttachmentCollection.php
vendored
Normal file
22
vendor/webklex/php-imap/src/Support/AttachmentCollection.php
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
/*
|
||||
* File: AttachmentCollection.php
|
||||
* Category: Collection
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 16.03.18 03:13
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Support;
|
||||
|
||||
/**
|
||||
* Class AttachmentCollection
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Support
|
||||
*/
|
||||
class AttachmentCollection extends PaginatedCollection {
|
||||
|
||||
}
|
||||
22
vendor/webklex/php-imap/src/Support/FlagCollection.php
vendored
Normal file
22
vendor/webklex/php-imap/src/Support/FlagCollection.php
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
/*
|
||||
* File: FlagCollection.php
|
||||
* Category: Collection
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 21.07.18 23:10
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Support;
|
||||
|
||||
/**
|
||||
* Class FlagCollection
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Support
|
||||
*/
|
||||
class FlagCollection extends PaginatedCollection {
|
||||
|
||||
}
|
||||
22
vendor/webklex/php-imap/src/Support/FolderCollection.php
vendored
Normal file
22
vendor/webklex/php-imap/src/Support/FolderCollection.php
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
/*
|
||||
* File: FolderCollection.php
|
||||
* Category: Collection
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 18.03.18 02:21
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Support;
|
||||
|
||||
/**
|
||||
* Class FolderCollection
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Support
|
||||
*/
|
||||
class FolderCollection extends PaginatedCollection {
|
||||
|
||||
}
|
||||
44
vendor/webklex/php-imap/src/Support/Masks/AttachmentMask.php
vendored
Normal file
44
vendor/webklex/php-imap/src/Support/Masks/AttachmentMask.php
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
/*
|
||||
* File: AttachmentMask.php
|
||||
* Category: Mask
|
||||
* Author: M.Goldenbaum
|
||||
* Created: 14.03.19 20:49
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Support\Masks;
|
||||
|
||||
use Webklex\PHPIMAP\Attachment;
|
||||
|
||||
/**
|
||||
* Class AttachmentMask
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Support\Masks
|
||||
*/
|
||||
class AttachmentMask extends Mask {
|
||||
|
||||
/** @var Attachment $parent */
|
||||
protected $parent;
|
||||
|
||||
/**
|
||||
* Get the attachment content base64 encoded
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getContentBase64Encoded() {
|
||||
return base64_encode($this->parent->content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a base64 image src string
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getImageSrc() {
|
||||
return 'data:'.$this->parent->content_type.';base64,'.$this->getContentBase64Encoded();
|
||||
}
|
||||
}
|
||||
137
vendor/webklex/php-imap/src/Support/Masks/Mask.php
vendored
Executable file
137
vendor/webklex/php-imap/src/Support/Masks/Mask.php
vendored
Executable file
@@ -0,0 +1,137 @@
|
||||
<?php
|
||||
/*
|
||||
* File: Mask.php
|
||||
* Category: Mask
|
||||
* Author: M.Goldenbaum
|
||||
* Created: 14.03.19 20:49
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Support\Masks;
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
use Webklex\PHPIMAP\Exceptions\MethodNotFoundException;
|
||||
|
||||
/**
|
||||
* Class Mask
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Support\Masks
|
||||
*/
|
||||
class Mask {
|
||||
|
||||
/**
|
||||
* Available attributes
|
||||
*
|
||||
* @var array $attributes
|
||||
*/
|
||||
protected $attributes = [];
|
||||
|
||||
/**
|
||||
* Parent instance
|
||||
*
|
||||
* @var object $parent
|
||||
*/
|
||||
protected $parent;
|
||||
|
||||
/**
|
||||
* Mask constructor.
|
||||
* @param $parent
|
||||
*/
|
||||
public function __construct($parent) {
|
||||
$this->parent = $parent;
|
||||
|
||||
if(method_exists($this->parent, 'getAttributes')){
|
||||
$this->attributes = array_merge($this->attributes, $this->parent->getAttributes());
|
||||
}
|
||||
|
||||
$this->boot();
|
||||
}
|
||||
|
||||
/**
|
||||
* Boot method made to be used by any custom mask
|
||||
*/
|
||||
protected function boot(){}
|
||||
|
||||
/**
|
||||
* Call dynamic attribute setter and getter methods and inherit the parent calls
|
||||
* @param string $method
|
||||
* @param array $arguments
|
||||
*
|
||||
* @return mixed
|
||||
* @throws MethodNotFoundException
|
||||
*/
|
||||
public function __call(string $method, array $arguments) {
|
||||
if(strtolower(substr($method, 0, 3)) === 'get') {
|
||||
$name = Str::snake(substr($method, 3));
|
||||
|
||||
if(isset($this->attributes[$name])) {
|
||||
return $this->attributes[$name];
|
||||
}
|
||||
|
||||
}elseif (strtolower(substr($method, 0, 3)) === 'set') {
|
||||
$name = Str::snake(substr($method, 3));
|
||||
|
||||
if(isset($this->attributes[$name])) {
|
||||
$this->attributes[$name] = array_pop($arguments);
|
||||
|
||||
return $this->attributes[$name];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(method_exists($this->parent, $method) === true){
|
||||
return call_user_func_array([$this->parent, $method], $arguments);
|
||||
}
|
||||
|
||||
throw new MethodNotFoundException("Method ".self::class.'::'.$method.'() is not supported');
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic setter
|
||||
* @param $name
|
||||
* @param $value
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function __set($name, $value) {
|
||||
$this->attributes[$name] = $value;
|
||||
|
||||
return $this->attributes[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic getter
|
||||
* @param $name
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function __get($name) {
|
||||
if(isset($this->attributes[$name])) {
|
||||
return $this->attributes[$name];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the parent instance
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function getParent(){
|
||||
return $this->parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all available attributes
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAttributes(): array {
|
||||
return $this->attributes;
|
||||
}
|
||||
|
||||
}
|
||||
86
vendor/webklex/php-imap/src/Support/Masks/MessageMask.php
vendored
Normal file
86
vendor/webklex/php-imap/src/Support/Masks/MessageMask.php
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
/*
|
||||
* File: MessageMask.php
|
||||
* Category: Mask
|
||||
* Author: M.Goldenbaum
|
||||
* Created: 14.03.19 20:49
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Support\Masks;
|
||||
|
||||
use Webklex\PHPIMAP\Attachment;
|
||||
use Webklex\PHPIMAP\Message;
|
||||
|
||||
/**
|
||||
* Class MessageMask
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Support\Masks
|
||||
*/
|
||||
class MessageMask extends Mask {
|
||||
|
||||
/** @var Message $parent */
|
||||
protected $parent;
|
||||
|
||||
/**
|
||||
* Get the message html body
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public function getHtmlBody(){
|
||||
$bodies = $this->parent->getBodies();
|
||||
if (!isset($bodies['html'])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if(is_object($bodies['html']) && property_exists($bodies['html'], 'content')) {
|
||||
return $bodies['html']->content;
|
||||
}
|
||||
return $bodies['html'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Message html body filtered by an optional callback
|
||||
* @param callable|bool $callback
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getCustomHTMLBody($callback = false) {
|
||||
$body = $this->getHtmlBody();
|
||||
if($body === null) return null;
|
||||
|
||||
if ($callback !== false) {
|
||||
$aAttachment = $this->parent->getAttachments();
|
||||
$aAttachment->each(function($oAttachment) use(&$body, $callback) {
|
||||
/** @var Attachment $oAttachment */
|
||||
if(is_callable($callback)) {
|
||||
$body = $callback($body, $oAttachment);
|
||||
}elseif(is_string($callback)) {
|
||||
call_user_func($callback, [$body, $oAttachment]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return $body;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Message html body with embedded base64 images
|
||||
* the resulting $body.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getHTMLBodyWithEmbeddedBase64Images() {
|
||||
return $this->getCustomHTMLBody(function($body, $oAttachment){
|
||||
/** @var Attachment $oAttachment */
|
||||
if ($oAttachment->id) {
|
||||
$body = str_replace('cid:'.$oAttachment->id, 'data:'.$oAttachment->getContentType().';base64, '.base64_encode($oAttachment->getContent()), $body);
|
||||
}
|
||||
|
||||
return $body;
|
||||
});
|
||||
}
|
||||
}
|
||||
22
vendor/webklex/php-imap/src/Support/MessageCollection.php
vendored
Normal file
22
vendor/webklex/php-imap/src/Support/MessageCollection.php
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
/*
|
||||
* File: MessageCollection.php
|
||||
* Category: Collection
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 16.03.18 03:13
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Support;
|
||||
|
||||
/**
|
||||
* Class MessageCollection
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Support
|
||||
*/
|
||||
class MessageCollection extends PaginatedCollection {
|
||||
|
||||
}
|
||||
82
vendor/webklex/php-imap/src/Support/PaginatedCollection.php
vendored
Normal file
82
vendor/webklex/php-imap/src/Support/PaginatedCollection.php
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
/*
|
||||
* File: PaginatedCollection.php
|
||||
* Category: Collection
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 16.03.18 03:13
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Support;
|
||||
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Pagination\Paginator;
|
||||
|
||||
/**
|
||||
* Class PaginatedCollection
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Support
|
||||
*/
|
||||
class PaginatedCollection extends Collection {
|
||||
|
||||
/**
|
||||
* Number of total entries
|
||||
*
|
||||
* @var int $total
|
||||
*/
|
||||
protected $total;
|
||||
|
||||
/**
|
||||
* Paginate the current collection.
|
||||
* @param int $per_page
|
||||
* @param int|null $page
|
||||
* @param string $page_name
|
||||
* @param boolean $prepaginated
|
||||
*
|
||||
* @return LengthAwarePaginator
|
||||
*/
|
||||
public function paginate(int $per_page = 15, $page = null, string $page_name = 'page', bool $prepaginated = false): LengthAwarePaginator {
|
||||
$page = $page ?: Paginator::resolveCurrentPage($page_name);
|
||||
|
||||
$total = $this->total ?: $this->count();
|
||||
|
||||
$results = !$prepaginated && $total ? $this->forPage($page, $per_page)->toArray() : $this->all();
|
||||
|
||||
return $this->paginator($results, $total, $per_page, $page, [
|
||||
'path' => Paginator::resolveCurrentPath(),
|
||||
'pageName' => $page_name,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new length-aware paginator instance.
|
||||
* @param array $items
|
||||
* @param int $total
|
||||
* @param int $per_page
|
||||
* @param int|null $current_page
|
||||
* @param array $options
|
||||
*
|
||||
* @return LengthAwarePaginator
|
||||
*/
|
||||
protected function paginator(array $items, int $total, int $per_page, $current_page, array $options): LengthAwarePaginator {
|
||||
return new LengthAwarePaginator($items, $total, $per_page, $current_page, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get and set the total amount
|
||||
* @param null $total
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public function total($total = null) {
|
||||
if($total === null) {
|
||||
return $this->total;
|
||||
}
|
||||
|
||||
return $this->total = $total;
|
||||
}
|
||||
}
|
||||
77
vendor/webklex/php-imap/src/Traits/HasEvents.php
vendored
Normal file
77
vendor/webklex/php-imap/src/Traits/HasEvents.php
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
/*
|
||||
* File: HasEvents.php
|
||||
* Category: -
|
||||
* Author: M.Goldenbaum
|
||||
* Created: 21.09.20 22:46
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
namespace Webklex\PHPIMAP\Traits;
|
||||
|
||||
|
||||
use Webklex\PHPIMAP\Events\Event;
|
||||
use Webklex\PHPIMAP\Exceptions\EventNotFoundException;
|
||||
|
||||
/**
|
||||
* Trait HasEvents
|
||||
*
|
||||
* @package Webklex\PHPIMAP\Traits
|
||||
*/
|
||||
trait HasEvents {
|
||||
|
||||
/**
|
||||
* Event holder
|
||||
*
|
||||
* @var array $events
|
||||
*/
|
||||
protected $events = [];
|
||||
|
||||
/**
|
||||
* Set a specific event
|
||||
* @param $section
|
||||
* @param $event
|
||||
* @param $class
|
||||
*/
|
||||
public function setEvent($section, $event, $class) {
|
||||
if (isset($this->events[$section])) {
|
||||
$this->events[$section][$event] = $class;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set all events
|
||||
* @param $events
|
||||
*/
|
||||
public function setEvents($events) {
|
||||
$this->events = $events;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a specific event callback
|
||||
* @param $section
|
||||
* @param $event
|
||||
*
|
||||
* @return Event|string
|
||||
* @throws EventNotFoundException
|
||||
*/
|
||||
public function getEvent($section, $event) {
|
||||
if (isset($this->events[$section])) {
|
||||
return $this->events[$section][$event];
|
||||
}
|
||||
throw new EventNotFoundException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all events
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getEvents(): array {
|
||||
return $this->events;
|
||||
}
|
||||
|
||||
}
|
||||
226
vendor/webklex/php-imap/src/config/imap.php
vendored
Normal file
226
vendor/webklex/php-imap/src/config/imap.php
vendored
Normal file
@@ -0,0 +1,226 @@
|
||||
<?php
|
||||
/*
|
||||
* File: imap.php
|
||||
* Category: config
|
||||
* Author: M. Goldenbaum
|
||||
* Created: 24.09.16 22:36
|
||||
* Updated: -
|
||||
*
|
||||
* Description:
|
||||
* -
|
||||
*/
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Default date format
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The default date format is used to convert any given Carbon::class object into a valid date string.
|
||||
| These are currently known working formats: "d-M-Y", "d-M-y", "d M y"
|
||||
|
|
||||
*/
|
||||
'date_format' => 'd-M-Y',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Default account
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The default account identifier. It will be used as default for any missing account parameters.
|
||||
| If however the default account is missing a parameter the package default will be used.
|
||||
| Set to 'false' [boolean] to disable this functionality.
|
||||
|
|
||||
*/
|
||||
'default' => 'default',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Available accounts
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Please list all IMAP accounts which you are planning to use within the
|
||||
| array below.
|
||||
|
|
||||
*/
|
||||
'accounts' => [
|
||||
|
||||
'default' => [// account identifier
|
||||
'host' => 'localhost',
|
||||
'port' => 993,
|
||||
'protocol' => 'imap', //might also use imap, [pop3 or nntp (untested)]
|
||||
'encryption' => 'ssl', // Supported: false, 'ssl', 'tls'
|
||||
'validate_cert' => true,
|
||||
'username' => 'root@example.com',
|
||||
'password' => '',
|
||||
'authentication' => null,
|
||||
'proxy' => [
|
||||
'socket' => null,
|
||||
'request_fulluri' => false,
|
||||
'username' => null,
|
||||
'password' => null,
|
||||
],
|
||||
"timeout" => 30,
|
||||
"extensions" => []
|
||||
],
|
||||
|
||||
/*
|
||||
'gmail' => [ // account identifier
|
||||
'host' => 'imap.gmail.com',
|
||||
'port' => 993,
|
||||
'encryption' => 'ssl',
|
||||
'validate_cert' => true,
|
||||
'username' => 'example@gmail.com',
|
||||
'password' => 'PASSWORD',
|
||||
'authentication' => 'oauth',
|
||||
],
|
||||
|
||||
'another' => [ // account identifier
|
||||
'host' => '',
|
||||
'port' => 993,
|
||||
'encryption' => false,
|
||||
'validate_cert' => true,
|
||||
'username' => '',
|
||||
'password' => '',
|
||||
'authentication' => null,
|
||||
]
|
||||
*/
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Available IMAP options
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Available php imap config parameters are listed below
|
||||
| -Delimiter (optional):
|
||||
| This option is only used when calling $oClient->
|
||||
| You can use any supported char such as ".", "/", (...)
|
||||
| -Fetch option:
|
||||
| IMAP::FT_UID - Message marked as read by fetching the body message
|
||||
| IMAP::FT_PEEK - Fetch the message without setting the "seen" flag
|
||||
| -Fetch sequence id:
|
||||
| IMAP::ST_UID - Fetch message components using the message uid
|
||||
| IMAP::ST_MSGN - Fetch message components using the message number
|
||||
| -Body download option
|
||||
| Default TRUE
|
||||
| -Flag download option
|
||||
| Default TRUE
|
||||
| -Soft fail
|
||||
| Default FALSE - Set to TRUE if you want to ignore certain exception while fetching bulk messages
|
||||
| -RFC822
|
||||
| Default TRUE - Set to FALSE to prevent the usage of \imap_rfc822_parse_headers().
|
||||
| See https://github.com/Webklex/php-imap/issues/115 for more information.
|
||||
| -Debug enable to trace communication traffic
|
||||
| -UID cache enable the UID cache
|
||||
| -Fallback date is used if the given message date could not be parsed
|
||||
| -Boundary regex used to detect message boundaries. If you are having problems with empty messages, missing
|
||||
| attachments or anything like this. Be advised that it likes to break which causes new problems..
|
||||
| -Message key identifier option
|
||||
| You can choose between the following:
|
||||
| 'id' - Use the MessageID as array key (default, might cause hickups with yahoo mail)
|
||||
| 'number' - Use the message number as array key (isn't always unique and can cause some interesting behavior)
|
||||
| 'list' - Use the message list number as array key (incrementing integer (does not always start at 0 or 1)
|
||||
| 'uid' - Use the message uid as array key (isn't always unique and can cause some interesting behavior)
|
||||
| -Fetch order
|
||||
| 'asc' - Order all messages ascending (probably results in oldest first)
|
||||
| 'desc' - Order all messages descending (probably results in newest first)
|
||||
| -Disposition types potentially considered an attachment
|
||||
| Default ['attachment', 'inline']
|
||||
| -Common folders
|
||||
| Default folder locations and paths assumed if none is provided
|
||||
| -Open IMAP options:
|
||||
| DISABLE_AUTHENTICATOR - Disable authentication properties.
|
||||
| Use 'GSSAPI' if you encounter the following
|
||||
| error: "Kerberos error: No credentials cache
|
||||
| file found (try running kinit) (...)"
|
||||
| or ['GSSAPI','PLAIN'] if you are using outlook mail
|
||||
| -Decoder options (currently only the message subject and attachment name decoder can be set)
|
||||
| 'utf-8' - Uses imap_utf8($string) to decode a string
|
||||
| 'mimeheader' - Uses mb_decode_mimeheader($string) to decode a string
|
||||
|
|
||||
*/
|
||||
'options' => [
|
||||
'delimiter' => '/',
|
||||
'fetch' => \Webklex\PHPIMAP\IMAP::FT_PEEK,
|
||||
'sequence' => \Webklex\PHPIMAP\IMAP::ST_UID,
|
||||
'fetch_body' => true,
|
||||
'fetch_flags' => true,
|
||||
'soft_fail' => false,
|
||||
'rfc822' => true,
|
||||
'debug' => false,
|
||||
'uid_cache' => true,
|
||||
// 'fallback_date' => "01.01.1970 00:00:00",
|
||||
'boundary' => '/boundary=(.*?(?=;)|(.*))/i',
|
||||
'message_key' => 'list',
|
||||
'fetch_order' => 'asc',
|
||||
'dispositions' => ['attachment', 'inline'],
|
||||
'common_folders' => [
|
||||
"root" => "INBOX",
|
||||
"junk" => "INBOX/Junk",
|
||||
"draft" => "INBOX/Drafts",
|
||||
"sent" => "INBOX/Sent",
|
||||
"trash" => "INBOX/Trash",
|
||||
],
|
||||
'decoder' => [
|
||||
'message' => 'utf-8', // mimeheader
|
||||
'attachment' => 'utf-8' // mimeheader
|
||||
],
|
||||
'open' => [
|
||||
// 'DISABLE_AUTHENTICATOR' => 'GSSAPI'
|
||||
]
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Available flags
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| List all available / supported flags. Set to null to accept all given flags.
|
||||
*/
|
||||
'flags' => ['recent', 'flagged', 'answered', 'deleted', 'seen', 'draft'],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Available events
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
*/
|
||||
'events' => [
|
||||
"message" => [
|
||||
'new' => \Webklex\PHPIMAP\Events\MessageNewEvent::class,
|
||||
'moved' => \Webklex\PHPIMAP\Events\MessageMovedEvent::class,
|
||||
'copied' => \Webklex\PHPIMAP\Events\MessageCopiedEvent::class,
|
||||
'deleted' => \Webklex\PHPIMAP\Events\MessageDeletedEvent::class,
|
||||
'restored' => \Webklex\PHPIMAP\Events\MessageRestoredEvent::class,
|
||||
],
|
||||
"folder" => [
|
||||
'new' => \Webklex\PHPIMAP\Events\FolderNewEvent::class,
|
||||
'moved' => \Webklex\PHPIMAP\Events\FolderMovedEvent::class,
|
||||
'deleted' => \Webklex\PHPIMAP\Events\FolderDeletedEvent::class,
|
||||
],
|
||||
"flag" => [
|
||||
'new' => \Webklex\PHPIMAP\Events\FlagNewEvent::class,
|
||||
'deleted' => \Webklex\PHPIMAP\Events\FlagDeletedEvent::class,
|
||||
],
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Available masking options
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| By using your own custom masks you can implement your own methods for
|
||||
| a better and faster access and less code to write.
|
||||
|
|
||||
| Checkout the two examples custom_attachment_mask and custom_message_mask
|
||||
| for a quick start.
|
||||
|
|
||||
| The provided masks below are used as the default masks.
|
||||
*/
|
||||
'masks' => [
|
||||
'message' => \Webklex\PHPIMAP\Support\Masks\MessageMask::class,
|
||||
'attachment' => \Webklex\PHPIMAP\Support\Masks\AttachmentMask::class
|
||||
]
|
||||
];
|
||||
Reference in New Issue
Block a user