From: vincent@cubedesigners.com Date: Wed, 6 Jun 2018 10:47:32 +0000 (+0000) Subject: wip #2083 @4 X-Git-Url: http://git.cubedesigners.com/?a=commitdiff_plain;h=89fc3fe6fac202769394686a61cbfd01f4205ce3;p=cubeextranet.git wip #2083 @4 --- diff --git a/composer.json b/composer.json new file mode 100644 index 000000000..024757558 --- /dev/null +++ b/composer.json @@ -0,0 +1,5 @@ +{ + "require": { + "php-mime-mail-parser/php-mime-mail-parser": "2.11.1" + } +} diff --git a/composer.phar b/composer.phar new file mode 100644 index 000000000..c6353cab1 Binary files /dev/null and b/composer.phar differ diff --git a/inc/commons/class.common.core.php b/inc/commons/class.common.core.php index bd8563063..b8b28490e 100644 --- a/inc/commons/class.common.core.php +++ b/inc/commons/class.common.core.php @@ -532,6 +532,13 @@ class commonCore extends cubeCore $db->google_search_api->date('integer', 0, false); $db->google_search_api->primary('pk_google_search_api', 'request'); + // Table Bourbon + $db->bourbon_suggestions->from('varchar', 256, false); + $db->bourbon_suggestions->date('integer', 0, false); + $db->bourbon_suggestions->type('varchar', 256, false); + $db->bourbon_suggestions->suggestion('text', 0, false); + $db->bourbon_suggestions->page('varchar', 256, false); + try { $dbi = new CubeDbStruct($this->con); $dbi->synchronize($db); diff --git a/inc/ws/Controlleur/class.ws.services.php b/inc/ws/Controlleur/class.ws.services.php index 5746d4a3a..543c9b9e9 100644 --- a/inc/ws/Controlleur/class.ws.services.php +++ b/inc/ws/Controlleur/class.ws.services.php @@ -1096,6 +1096,7 @@ class wsServices extends cubeFlashGateway public function getFluidbookPage($id, $page) { global $core; + $this->outputXML = false; $id = $this->callArgs[0]; $page = $this->callArgs[1]; @@ -1170,4 +1171,102 @@ class wsServices extends cubeFlashGateway } } + + public function bourbonSuggestion() + { + global $core; + try { + $mail = new PhpMimeMailParser\Parser(); + $mail->setText(base64_decode($_POST['email'])); + $from = $mail->getAddresses('from'); + $from = $from[0]['address']; + + + $attachments = $mail->getAttachments(); + foreach ($attachments as $k => $attachment) { + if ($attachment->getFilename() !== 'suggestion.txt') { + continue; + } + $suggestion = $attachment->getContent(); + $parts = explode('/|!/', $suggestion); + $c = $core->con->openCursor('bourbon_suggestions'); + $c->type = $parts[2]; + $c->suggestion = $parts[3]; + $c->date = round($parts[1]/1000); + $c->from = $from; + $c->page = $parts[0]; + $c->insert(); + + break; + } + file_put_contents('/tmp/bourbonSuggestion', print_r($mail, true)); + file_put_contents('/tmp/bourbonSuggestionAttach', print_r($attachments, true)); + } catch (Exception $e) { + file_put_contents('/tmp/bourbonSuggestion', print_r($e, true)); + } + + $body = "Hello,\r\nThis automatic message confirm that your suggestion has been received.\r\nPlease do not reply to this e-mail,\r\nThank you"; + + $ack = new Zend_Mail(); + $ack->setFrom('no-reply@bourbonoffshore.com'); + $ack->setSubject('Suggestion ackknowledge'); + $ack->setBodyText($body); + + $ack->addTo($from); + $ack->send(); + } + + public function downloadBourbonSuggestions58412() + { + global $core; + $this->outputXML = false; + $r = $core->con->select('SELECT * FROM bourbon_suggestions ORDER BY date DESC'); + $excel = new PHPExcel(); + $excel->setActiveSheetIndex(0); + $defaultStyle = $excel->getDefaultStyle(); + $defaultStyle->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_CENTER); + $defaultStyle->getAlignment()->setWrapText(true); + $s = $excel->getActiveSheet(); + $s->setTitle('Suggestions'); + $s->setCellValueByColumnAndRow(0, 1, 'Sender'); + $s->setCellValueByColumnAndRow(1, 1, 'Date'); + $s->setCellValueByColumnAndRow(2, 1, 'Type'); + $s->setCellValueByColumnAndRow(3, 1, 'Page'); + $s->setCellValueByColumnAndRow(4, 1, 'Suggestion content'); + + $line = 2; + while ($r->fetch()) { + $date = date('Y-m-d H:i:s', round($r->date)); + + $s->setCellValueByColumnAndRow(0, $line, $r->from); + $s->setCellValueByColumnAndRow(1, $line, $date); + $s->setCellValueByColumnAndRow(2, $line, $r->type); + $s->setCellValueByColumnAndRow(3, $line, $r->page); + $s->setCellValueByColumnAndRow(4, $line, $r->suggestion); + + $line++; + } + + for ($i = 0; $i <= 4; $i++) { + $s->getColumnDimensionByColumn($i)->setAutoSize(true); + } + + + header('Content-type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'); + header('Content-Disposition: attachment;filename="fluidbook-suggestions.xlsx"'); + header('Cache-Control: max-age=0'); + // If you're serving to IE 9, then the following may be needed + header('Cache-Control: max-age=1'); + // If you're serving to IE over SSL, then the following may be needed + header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past + header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); // always modified + header('Cache-Control: cache, must-revalidate'); // HTTP/1.1 + header('Pragma: public'); // HTTP/1.0 + + $writer = PHPExcel_IOFactory::createWriter($excel, 'Excel2007'); + ob_end_clean(); + $writer->save('php://output'); + exit; + + } } diff --git a/index.php b/index.php index f23ea3c0d..e82a607f9 100644 --- a/index.php +++ b/index.php @@ -1,5 +1,7 @@ + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Autoload; + +/** + * ClassLoader implements a PSR-0, PSR-4 and classmap class loader. + * + * $loader = new \Composer\Autoload\ClassLoader(); + * + * // register classes with namespaces + * $loader->add('Symfony\Component', __DIR__.'/component'); + * $loader->add('Symfony', __DIR__.'/framework'); + * + * // activate the autoloader + * $loader->register(); + * + * // to enable searching the include path (eg. for PEAR packages) + * $loader->setUseIncludePath(true); + * + * In this example, if you try to use a class in the Symfony\Component + * namespace or one of its children (Symfony\Component\Console for instance), + * the autoloader will first look for the class under the component/ + * directory, and it will then fallback to the framework/ directory if not + * found before giving up. + * + * This class is loosely based on the Symfony UniversalClassLoader. + * + * @author Fabien Potencier + * @author Jordi Boggiano + * @see http://www.php-fig.org/psr/psr-0/ + * @see http://www.php-fig.org/psr/psr-4/ + */ +class ClassLoader +{ + // PSR-4 + private $prefixLengthsPsr4 = array(); + private $prefixDirsPsr4 = array(); + private $fallbackDirsPsr4 = array(); + + // PSR-0 + private $prefixesPsr0 = array(); + private $fallbackDirsPsr0 = array(); + + private $useIncludePath = false; + private $classMap = array(); + private $classMapAuthoritative = false; + private $missingClasses = array(); + private $apcuPrefix; + + public function getPrefixes() + { + if (!empty($this->prefixesPsr0)) { + return call_user_func_array('array_merge', $this->prefixesPsr0); + } + + return array(); + } + + public function getPrefixesPsr4() + { + return $this->prefixDirsPsr4; + } + + public function getFallbackDirs() + { + return $this->fallbackDirsPsr0; + } + + public function getFallbackDirsPsr4() + { + return $this->fallbackDirsPsr4; + } + + public function getClassMap() + { + return $this->classMap; + } + + /** + * @param array $classMap Class to filename map + */ + public function addClassMap(array $classMap) + { + if ($this->classMap) { + $this->classMap = array_merge($this->classMap, $classMap); + } else { + $this->classMap = $classMap; + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, either + * appending or prepending to the ones previously set for this prefix. + * + * @param string $prefix The prefix + * @param array|string $paths The PSR-0 root directories + * @param bool $prepend Whether to prepend the directories + */ + public function add($prefix, $paths, $prepend = false) + { + if (!$prefix) { + if ($prepend) { + $this->fallbackDirsPsr0 = array_merge( + (array) $paths, + $this->fallbackDirsPsr0 + ); + } else { + $this->fallbackDirsPsr0 = array_merge( + $this->fallbackDirsPsr0, + (array) $paths + ); + } + + return; + } + + $first = $prefix[0]; + if (!isset($this->prefixesPsr0[$first][$prefix])) { + $this->prefixesPsr0[$first][$prefix] = (array) $paths; + + return; + } + if ($prepend) { + $this->prefixesPsr0[$first][$prefix] = array_merge( + (array) $paths, + $this->prefixesPsr0[$first][$prefix] + ); + } else { + $this->prefixesPsr0[$first][$prefix] = array_merge( + $this->prefixesPsr0[$first][$prefix], + (array) $paths + ); + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, either + * appending or prepending to the ones previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param array|string $paths The PSR-4 base directories + * @param bool $prepend Whether to prepend the directories + * + * @throws \InvalidArgumentException + */ + public function addPsr4($prefix, $paths, $prepend = false) + { + if (!$prefix) { + // Register directories for the root namespace. + if ($prepend) { + $this->fallbackDirsPsr4 = array_merge( + (array) $paths, + $this->fallbackDirsPsr4 + ); + } else { + $this->fallbackDirsPsr4 = array_merge( + $this->fallbackDirsPsr4, + (array) $paths + ); + } + } elseif (!isset($this->prefixDirsPsr4[$prefix])) { + // Register directories for a new namespace. + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } elseif ($prepend) { + // Prepend directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + (array) $paths, + $this->prefixDirsPsr4[$prefix] + ); + } else { + // Append directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + $this->prefixDirsPsr4[$prefix], + (array) $paths + ); + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, + * replacing any others previously set for this prefix. + * + * @param string $prefix The prefix + * @param array|string $paths The PSR-0 base directories + */ + public function set($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr0 = (array) $paths; + } else { + $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, + * replacing any others previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param array|string $paths The PSR-4 base directories + * + * @throws \InvalidArgumentException + */ + public function setPsr4($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr4 = (array) $paths; + } else { + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } + } + + /** + * Turns on searching the include path for class files. + * + * @param bool $useIncludePath + */ + public function setUseIncludePath($useIncludePath) + { + $this->useIncludePath = $useIncludePath; + } + + /** + * Can be used to check if the autoloader uses the include path to check + * for classes. + * + * @return bool + */ + public function getUseIncludePath() + { + return $this->useIncludePath; + } + + /** + * Turns off searching the prefix and fallback directories for classes + * that have not been registered with the class map. + * + * @param bool $classMapAuthoritative + */ + public function setClassMapAuthoritative($classMapAuthoritative) + { + $this->classMapAuthoritative = $classMapAuthoritative; + } + + /** + * Should class lookup fail if not found in the current class map? + * + * @return bool + */ + public function isClassMapAuthoritative() + { + return $this->classMapAuthoritative; + } + + /** + * APCu prefix to use to cache found/not-found classes, if the extension is enabled. + * + * @param string|null $apcuPrefix + */ + public function setApcuPrefix($apcuPrefix) + { + $this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null; + } + + /** + * The APCu prefix in use, or null if APCu caching is not enabled. + * + * @return string|null + */ + public function getApcuPrefix() + { + return $this->apcuPrefix; + } + + /** + * Registers this instance as an autoloader. + * + * @param bool $prepend Whether to prepend the autoloader or not + */ + public function register($prepend = false) + { + spl_autoload_register(array($this, 'loadClass'), true, $prepend); + } + + /** + * Unregisters this instance as an autoloader. + */ + public function unregister() + { + spl_autoload_unregister(array($this, 'loadClass')); + } + + /** + * Loads the given class or interface. + * + * @param string $class The name of the class + * @return bool|null True if loaded, null otherwise + */ + public function loadClass($class) + { + if ($file = $this->findFile($class)) { + includeFile($file); + + return true; + } + } + + /** + * Finds the path to the file where the class is defined. + * + * @param string $class The name of the class + * + * @return string|false The path if found, false otherwise + */ + public function findFile($class) + { + // class map lookup + if (isset($this->classMap[$class])) { + return $this->classMap[$class]; + } + if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { + return false; + } + if (null !== $this->apcuPrefix) { + $file = apcu_fetch($this->apcuPrefix.$class, $hit); + if ($hit) { + return $file; + } + } + + $file = $this->findFileWithExtension($class, '.php'); + + // Search for Hack files if we are running on HHVM + if (false === $file && defined('HHVM_VERSION')) { + $file = $this->findFileWithExtension($class, '.hh'); + } + + if (null !== $this->apcuPrefix) { + apcu_add($this->apcuPrefix.$class, $file); + } + + if (false === $file) { + // Remember that this class does not exist. + $this->missingClasses[$class] = true; + } + + return $file; + } + + private function findFileWithExtension($class, $ext) + { + // PSR-4 lookup + $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; + + $first = $class[0]; + if (isset($this->prefixLengthsPsr4[$first])) { + $subPath = $class; + while (false !== $lastPos = strrpos($subPath, '\\')) { + $subPath = substr($subPath, 0, $lastPos); + $search = $subPath . '\\'; + if (isset($this->prefixDirsPsr4[$search])) { + $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); + foreach ($this->prefixDirsPsr4[$search] as $dir) { + if (file_exists($file = $dir . $pathEnd)) { + return $file; + } + } + } + } + } + + // PSR-4 fallback dirs + foreach ($this->fallbackDirsPsr4 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { + return $file; + } + } + + // PSR-0 lookup + if (false !== $pos = strrpos($class, '\\')) { + // namespaced class name + $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) + . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); + } else { + // PEAR-like class name + $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; + } + + if (isset($this->prefixesPsr0[$first])) { + foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { + if (0 === strpos($class, $prefix)) { + foreach ($dirs as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + } + } + } + + // PSR-0 fallback dirs + foreach ($this->fallbackDirsPsr0 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + + // PSR-0 include paths. + if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { + return $file; + } + + return false; + } +} + +/** + * Scope isolated include. + * + * Prevents access to $this/self from included files. + */ +function includeFile($file) +{ + include $file; +} diff --git a/vendor/composer/LICENSE b/vendor/composer/LICENSE new file mode 100644 index 000000000..f27399a04 --- /dev/null +++ b/vendor/composer/LICENSE @@ -0,0 +1,21 @@ + +Copyright (c) Nils Adermann, Jordi Boggiano + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php new file mode 100644 index 000000000..7a91153b0 --- /dev/null +++ b/vendor/composer/autoload_classmap.php @@ -0,0 +1,9 @@ + array($vendorDir . '/php-mime-mail-parser/php-mime-mail-parser/src'), +); diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php new file mode 100644 index 000000000..679b0d57a --- /dev/null +++ b/vendor/composer/autoload_real.php @@ -0,0 +1,52 @@ += 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); + if ($useStaticLoader) { + require_once __DIR__ . '/autoload_static.php'; + + call_user_func(\Composer\Autoload\ComposerStaticInit920111649f7e87249f1f2fbc0fd23976::getInitializer($loader)); + } else { + $map = require __DIR__ . '/autoload_namespaces.php'; + foreach ($map as $namespace => $path) { + $loader->set($namespace, $path); + } + + $map = require __DIR__ . '/autoload_psr4.php'; + foreach ($map as $namespace => $path) { + $loader->setPsr4($namespace, $path); + } + + $classMap = require __DIR__ . '/autoload_classmap.php'; + if ($classMap) { + $loader->addClassMap($classMap); + } + } + + $loader->register(true); + + return $loader; + } +} diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php new file mode 100644 index 000000000..62403a9eb --- /dev/null +++ b/vendor/composer/autoload_static.php @@ -0,0 +1,31 @@ + + array ( + 'PhpMimeMailParser\\' => 18, + ), + ); + + public static $prefixDirsPsr4 = array ( + 'PhpMimeMailParser\\' => + array ( + 0 => __DIR__ . '/..' . '/php-mime-mail-parser/php-mime-mail-parser/src', + ), + ); + + public static function getInitializer(ClassLoader $loader) + { + return \Closure::bind(function () use ($loader) { + $loader->prefixLengthsPsr4 = ComposerStaticInit920111649f7e87249f1f2fbc0fd23976::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInit920111649f7e87249f1f2fbc0fd23976::$prefixDirsPsr4; + + }, null, ClassLoader::class); + } +} diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json new file mode 100644 index 000000000..037daaa55 --- /dev/null +++ b/vendor/composer/installed.json @@ -0,0 +1,84 @@ +[ + { + "name": "php-mime-mail-parser/php-mime-mail-parser", + "version": "2.11.1", + "version_normalized": "2.11.1.0", + "source": { + "type": "git", + "url": "https://github.com/php-mime-mail-parser/php-mime-mail-parser.git", + "reference": "4769e942ed0dbbdd7882fc390b119d625463c8af" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-mime-mail-parser/php-mime-mail-parser/zipball/4769e942ed0dbbdd7882fc390b119d625463c8af", + "reference": "4769e942ed0dbbdd7882fc390b119d625463c8af", + "shasum": "" + }, + "require": { + "ext-mailparse": "*", + "php": "^5.4.0 || ^7.0" + }, + "replace": { + "exorus/php-mime-mail-parser": "*", + "messaged/php-mime-mail-parser": "*" + }, + "require-dev": { + "phpunit/php-token-stream": "^1.3.0", + "phpunit/phpunit": "^4.0 || ^5.0", + "satooshi/php-coveralls": "0.*", + "squizlabs/php_codesniffer": "2.*" + }, + "time": "2018-04-30T05:55:59+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "PhpMimeMailParser\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "bucabay", + "email": "gabe@fijiwebdesign.com", + "homepage": "http://www.fijiwebdesign.com", + "role": "Developer" + }, + { + "name": "eXorus", + "email": "exorus.spam@gmail.com", + "homepage": "https://github.com/eXorus/", + "role": "Developer" + }, + { + "name": "M.Valinskis", + "email": "M.Valins@gmail.com", + "homepage": "https://code.google.com/p/php-mime-mail-parser", + "role": "Developer" + }, + { + "name": "eugene.emmett.wood", + "email": "gene_w@cementhorizon.com", + "homepage": "https://code.google.com/p/php-mime-mail-parser", + "role": "Developer" + }, + { + "name": "alknetso", + "email": "alkne@gmail.com", + "homepage": "https://code.google.com/p/php-mime-mail-parser", + "role": "Developer" + } + ], + "description": "Fully Tested Mailparse Extension Wrapper for PHP 5.4+", + "homepage": "https://github.com/php-mime-mail-parser/php-mime-mail-parser", + "keywords": [ + "MimeMailParser", + "mail", + "mailparse", + "mime" + ] + } +] diff --git a/vendor/php-mime-mail-parser/php-mime-mail-parser/LICENSE b/vendor/php-mime-mail-parser/php-mime-mail-parser/LICENSE new file mode 100644 index 000000000..ab85686e0 --- /dev/null +++ b/vendor/php-mime-mail-parser/php-mime-mail-parser/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Vincent Dauce + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/php-mime-mail-parser/php-mime-mail-parser/README.md b/vendor/php-mime-mail-parser/php-mime-mail-parser/README.md new file mode 100644 index 000000000..0b0502fc4 --- /dev/null +++ b/vendor/php-mime-mail-parser/php-mime-mail-parser/README.md @@ -0,0 +1,167 @@ +# php-mime-mail-parser + +A fully tested mailparse extension wrapper for PHP 5.4+ + +[![Latest Version](https://img.shields.io/packagist/v/php-mime-mail-parser/php-mime-mail-parser.svg?style=flat-square)](https://github.com/php-mime-mail-parser/php-mime-mail-parser/releases) +[![Total Downloads](https://img.shields.io/packagist/dt/php-mime-mail-parser/php-mime-mail-parser.svg?style=flat-square)](https://packagist.org/packages/php-mime-mail-parser/php-mime-mail-parser) +[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE) + +## Why? + +This extension can be used to... + * Parse and read email from Postfix + * Create webmail + * Store email information such a subject, HTML body, attachments, and etc. into a database + +## Is it reliable? + +Yes. All known issues have been reproduced, fixed and tested. + +We use Travis CI to help ensure code quality. You can see real-time statistics below: + +[![Build Status](https://img.shields.io/travis/php-mime-mail-parser/php-mime-mail-parser/master.svg?style=flat-square)](https://travis-ci.org/php-mime-mail-parser/php-mime-mail-parser) +[![Coverage](https://img.shields.io/coveralls/php-mime-mail-parser/php-mime-mail-parser.svg?style=flat-square)](https://coveralls.io/r/php-mime-mail-parser/php-mime-mail-parser) +[![Quality Score](https://img.shields.io/scrutinizer/g/php-mime-mail-parser/php-mime-mail-parser.svg?style=flat-square)](https://scrutinizer-ci.com/g/php-mime-mail-parser/php-mime-mail-parser) + +## How do I install it? + +The easiest way is via [Composer](https://getcomposer.org/). + +To install the latest version of PHP MIME Mail Parser, run the command below: + + composer require php-mime-mail-parser/php-mime-mail-parser + +## Requirements + +The following versions of PHP are supported: + +* PHP 5.4 +* PHP 5.5 +* PHP 5.6 +* PHP 7 +* HHVM + +``` +sudo apt install php-cli php-pear php-dev php-mbstring +``` + +Make sure you have the mailparse extension (http://php.net/manual/en/book.mailparse.php) properly installed. The command line `php -m | grep mailparse` need to return "mailparse" else install it: +* PHP version > 7.0: mailparse +* PHP version < 7.0: mailparse 2.1.6 + +Follow this steps to install mailparse: + +* Compile in the temp folder the extension mailparse or mailparse-2.1.6 (workaround because pecl install doesn't work yet) +``` +cd +pecl download mailparse +tar -xvf mailparse-3.0.2.tgz +cd mailparse-3.0.2/ +phpize +./configure +sed -i 's/#if\s!HAVE_MBSTRING/#ifndef MBFL_MBFILTER_H/' ./mailparse.c +make +sudo mv modules/mailparse.so /usr/lib/php/20160303/ +``` +* Add the extension mailparse and activate it +``` +echo "extension=mailparse.so" | sudo tee /etc/php/7.1/mods-available/mailparse.ini +sudo phpenmod mailparse +``` + +On Windows, you need to download mailparse DLL from http://pecl.php.net/package/mailparse and add the line "extension=php_mailparse.dll" to php.ini accordingly. + +## How do I use it? + +```php +setPath($path); + +// 2. Specify a php file resource (stream) to the mime mail. +$Parser->setStream(fopen($path, "r")); + +// 3. Specify the raw mime mail text. +$Parser->setText(file_get_contents($path)); + +// 4. Specify a stream to work with mail server +$Parser->setStream(fopen("php://stdin", "r")); + +// Once we've indicated where to find the mail, we can parse out the data +$to = $Parser->getHeader('to'); // "test" , "test2" +$addressesTo = $Parser->getAddresses('to'); //Return an array : [["display"=>"test", "address"=>"test@example.com", false],["display"=>"test2", "address"=>"test2@example.com", false]] + +$from = $Parser->getHeader('from'); // "test" +$addressesFrom = $Parser->getAddresses('from'); //Return an array : [["display"=>"test", "address"=>"test@example.com", "is_group"=>false]] + +$subject = $Parser->getHeader('subject'); + +$text = $Parser->getMessageBody('text'); + +$html = $Parser->getMessageBody('html'); +$htmlEmbedded = $Parser->getMessageBody('htmlEmbedded'); //HTML Body included data + +$stringHeaders = $Parser->getHeadersRaw(); // Get all headers as a string, no charset conversion +$arrayHeaders = $Parser->getHeaders(); // Get all headers as an array, with charset conversion + +// Pass in a writeable path to save attachments +$attach_dir = '/path/to/save/attachments/'; // Be sure to include the trailing slash +$include_inline = true; // Optional argument to include inline attachments (default: true) +$Parser->saveAttachments($attach_dir [,$include_inline]); + +// Get an array of Attachment items from $Parser +$attachments = $Parser->getAttachments([$include_inline]); + +// Loop through all the Attachments +if (count($attachments) > 0) { + foreach ($attachments as $attachment) { + echo 'Filename : '.$attachment->getFilename().'
'; // logo.jpg + echo 'Filesize : '.filesize($attach_dir.$attachment->getFilename()).'
'; // 1000 + echo 'Filetype : '.$attachment->getContentType().'
'; // image/jpeg + echo 'MIME part string : '.$attachment->getMimePartStr().'
'; // (the whole MIME part of the attachment) + } +} + +?> +``` + +Next you need to forward emails to this script above. For that I'm using [Postfix](http://www.postfix.org/) like a mail server, you need to configure /etc/postfix/master.cf + +Add this line at the end of the file (specify myhook to send all emails to the script test.php) +``` +myhook unix - n n - - pipe + flags=F user=www-data argv=php -c /etc/php5/apache2/php.ini -f /var/www/test.php ${sender} ${size} ${recipient} +``` + +Edit this line (register myhook) +``` +smtp inet n - - - - smtpd + -o content_filter=myhook:dummy +``` + +The php script must use the fourth method to work with this configuration. + + +## Can I contribute? + +Feel free to contribute! + + git clone https://github.com/php-mime-mail-parser/php-mime-mail-parser + cd php-mime-mail-parser + composer install + ./vendor/bin/phpunit + +If you report an issue, please provide the raw email that triggered it. This helps us reproduce the issue and fix it more quickly. + +### License + +The php-mime-mail-parser/php-mime-mail-parser is open-sourced software licensed under the [MIT license](http://opensource.org/licenses/MIT) diff --git a/vendor/php-mime-mail-parser/php-mime-mail-parser/composer.json b/vendor/php-mime-mail-parser/php-mime-mail-parser/composer.json new file mode 100644 index 000000000..320d08d24 --- /dev/null +++ b/vendor/php-mime-mail-parser/php-mime-mail-parser/composer.json @@ -0,0 +1,61 @@ +{ + "name": "php-mime-mail-parser/php-mime-mail-parser", + "type": "library", + "description": "Fully Tested Mailparse Extension Wrapper for PHP 5.4+", + "keywords": ["mime", "mail", "mailparse", "MimeMailParser"], + "homepage": "https://github.com/php-mime-mail-parser/php-mime-mail-parser", + "license": "MIT", + "authors": [ + { + "name":"eXorus", + "email":"exorus.spam@gmail.com", + "homepage":"https://github.com/eXorus/", + "role":"Developer" + }, + { + "name":"M.Valinskis", + "email":"M.Valins@gmail.com", + "homepage":"https://code.google.com/p/php-mime-mail-parser", + "role":"Developer" + }, + { + "name":"eugene.emmett.wood", + "email":"gene_w@cementhorizon.com", + "homepage":"https://code.google.com/p/php-mime-mail-parser", + "role":"Developer" + }, + { + "name":"alknetso", + "email":"alkne@gmail.com", + "homepage":"https://code.google.com/p/php-mime-mail-parser", + "role":"Developer" + }, + { + "name":"bucabay", + "email":"gabe@fijiwebdesign.com", + "homepage":"http://www.fijiwebdesign.com", + "role":"Developer" + } + ], + "repository":{ + "type":"git", + "url":"https://github.com/php-mime-mail-parser/php-mime-mail-parser.git" + }, + "require": { + "php": "^5.4.0 || ^7.0", + "ext-mailparse": "*" + }, + "require-dev": { + "phpunit/phpunit": "^4.0 || ^5.0", + "phpunit/php-token-stream": "^1.3.0", + "satooshi/php-coveralls": "0.*", + "squizlabs/PHP_CodeSniffer": "2.*" + }, + "replace": { + "exorus/php-mime-mail-parser": "*", + "messaged/php-mime-mail-parser": "*" + }, + "autoload": { + "psr-4": { "PhpMimeMailParser\\": "src/" } + } +} diff --git a/vendor/php-mime-mail-parser/php-mime-mail-parser/mailparse-stubs.php b/vendor/php-mime-mail-parser/php-mime-mail-parser/mailparse-stubs.php new file mode 100644 index 000000000..743033efe --- /dev/null +++ b/vendor/php-mime-mail-parser/php-mime-mail-parser/mailparse-stubs.php @@ -0,0 +1,303 @@ + + + + tests + + diff --git a/vendor/php-mime-mail-parser/php-mime-mail-parser/src/Attachment.php b/vendor/php-mime-mail-parser/php-mime-mail-parser/src/Attachment.php new file mode 100644 index 000000000..520126229 --- /dev/null +++ b/vendor/php-mime-mail-parser/php-mime-mail-parser/src/Attachment.php @@ -0,0 +1,183 @@ +filename = $filename; + $this->contentType = $contentType; + $this->stream = $stream; + $this->content = null; + $this->contentDisposition = $contentDisposition; + $this->contentId = $contentId; + $this->headers = $headers; + $this->mimePartStr = $mimePartStr; + } + + /** + * retrieve the attachment filename + * + * @return string + */ + public function getFilename() + { + return $this->filename; + } + + /** + * Retrieve the Attachment Content-Type + * + * @return string + */ + public function getContentType() + { + return $this->contentType; + } + + /** + * Retrieve the Attachment Content-Disposition + * + * @return string + */ + public function getContentDisposition() + { + return $this->contentDisposition; + } + + /** + * Retrieve the Attachment Content-ID + * + * @return string + */ + public function getContentID() + { + return $this->contentId; + } + + /** + * Retrieve the Attachment Headers + * + * @return array + */ + public function getHeaders() + { + return $this->headers; + } + + /** + * Get a handle to the stream + * + * @return stream + */ + public function getStream() + { + return $this->stream; + } + + /** + * Read the contents a few bytes at a time until completed + * Once read to completion, it always returns false + * + * @param int $bytes (default: 2082) + * + * @return string|bool + */ + public function read($bytes = 2082) + { + return feof($this->stream) ? false : fread($this->stream, $bytes); + } + + /** + * Retrieve the file content in one go + * Once you retrieve the content you cannot use MimeMailParser_attachment::read() + * + * @return string + */ + public function getContent() + { + if ($this->content === null) { + fseek($this->stream, 0); + while (($buf = $this->read()) !== false) { + $this->content .= $buf; + } + } + + return $this->content; + } + + /** + * Get mime part string for this attachment + * + * @return string + */ + public function getMimePartStr() + { + return $this->mimePartStr; + } +} diff --git a/vendor/php-mime-mail-parser/php-mime-mail-parser/src/Charset.php b/vendor/php-mime-mail-parser/php-mime-mail-parser/src/Charset.php new file mode 100644 index 000000000..04315c1e7 --- /dev/null +++ b/vendor/php-mime-mail-parser/php-mime-mail-parser/src/Charset.php @@ -0,0 +1,338 @@ + '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', + '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', + 'x-imap4-modified-utf7' => 'x-imap4-modified-utf7', + 'x-euc-tw' => 'x-euc-tw', + 'x-mac-ce' => 'x-mac-ce', + 'x-mac-turkish' => 'x-mac-turkish', + 'x-mac-greek' => 'x-mac-greek', + 'x-mac-icelandic' => 'x-mac-icelandic', + 'x-mac-croatian' => 'x-mac-croatian', + 'x-mac-romanian' => 'x-mac-romanian', + 'x-mac-cyrillic' => 'x-mac-cyrillic', + 'x-mac-ukrainian' => 'x-mac-cyrillic', + 'x-mac-hebrew' => 'x-mac-hebrew', + 'x-mac-arabic' => 'x-mac-arabic', + 'x-mac-farsi' => 'x-mac-farsi', + 'x-mac-devanagari' => 'x-mac-devanagari', + 'x-mac-gujarati' => 'x-mac-gujarati', + 'x-mac-gurmukhi' => 'x-mac-gurmukhi', + 'armscii-8' => 'armscii-8', + 'x-viet-tcvn5712' => 'x-viet-tcvn5712', + 'x-viet-vps' => 'x-viet-vps', + 'iso-10646-ucs-2' => 'UTF-16BE', + 'x-iso-10646-ucs-2-be' => 'UTF-16BE', + 'x-iso-10646-ucs-2-le' => 'UTF-16LE', + 'x-user-defined' => 'x-user-defined', + 'x-johab' => 'x-johab', + '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', + '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', + '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', + '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', + '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', + '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', + 'csiso88596i' => 'ISO-8859-6-I', + 'csiso88596e' => 'ISO-8859-6-E', + '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', + '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', + 'csiso88598i' => 'ISO-8859-8', + 'iso-8859-8i' => 'ISO-8859-8', + 'logical' => 'ISO-8859-8', + 'csiso88598e' => 'ISO-8859-8-E', + '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', + 'unicode-1-1-utf-8' => 'UTF-8', + 'utf8' => 'UTF-8', + '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', + 'cseucpkdfmtjapanese' => 'EUC-JP', + 'x-euc-jp' => 'EUC-JP', + 'csiso2022jp' => 'ISO-2022-JP', + 'iso-2022-jp-2' => 'ISO-2022-JP', + 'csiso2022jp2' => 'ISO-2022-JP', + 'csbig5' => 'Big5', + 'cn-big5' => 'Big5', + 'x-x-big5' => 'Big5', + 'zh_tw-big5' => 'Big5', + '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', + 'gb_2312-80' => 'GB2312', + 'iso-ir-58' => 'GB2312', + 'chinese' => 'GB2312', + 'csiso58gb231280' => 'GB2312', + 'csgb2312' => 'GB2312', + 'zh_cn.euc' => 'GB2312', + 'gb_2312' => 'GB2312', + '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', + 'windows-874' => 'windows-874', + 'ibm874' => 'windows-874', + 'dos-874' => 'windows-874', + 'macintosh' => 'macintosh', + 'x-mac-roman' => 'macintosh', + 'mac' => 'macintosh', + 'csmacintosh' => 'macintosh', + 'cp866' => 'IBM866', + 'cp-866' => 'IBM866', + '866' => 'IBM866', + 'csibm866' => 'IBM866', + 'cp850' => 'IBM850', + '850' => 'IBM850', + 'csibm850' => 'IBM850', + 'cp852' => 'IBM852', + '852' => 'IBM852', + 'csibm852' => 'IBM852', + 'cp855' => 'IBM855', + '855' => 'IBM855', + 'csibm855' => 'IBM855', + 'cp857' => 'IBM857', + '857' => 'IBM857', + 'csibm857' => 'IBM857', + 'cp862' => 'IBM862', + '862' => 'IBM862', + 'csibm862' => 'IBM862', + 'cp864' => 'IBM864', + '864' => 'IBM864', + 'csibm864' => 'IBM864', + 'ibm-864' => 'IBM864', + 't.61' => 'T.61-8bit', + 'iso-ir-103' => 'T.61-8bit', + 'csiso103t618bit' => 'T.61-8bit', + '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', + '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', + 'latin6' => 'ISO-8859-10', + 'iso-ir-157' => 'ISO-8859-10', + 'l6' => 'ISO-8859-10', + 'csisolatin6' => 'ISO-8859-10', + 'iso_8859-15' => 'ISO-8859-15', + 'csisolatin9' => 'ISO-8859-15', + 'l9' => 'ISO-8859-15', + 'ecma-cyrillic' => 'ISO-IR-111', + 'csiso111ecmacyrillic' => 'ISO-IR-111', + 'csiso2022kr' => 'ISO-2022-KR', + 'csviscii' => 'VISCII', + 'zh_tw-euc' => 'x-euc-tw', + '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', + 'tis620' => 'TIS-620', + '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', + ]; + + /** + * {@inheritdoc} + */ + public function decodeCharset($encodedString, $charset) + { + if (strtolower($charset) == 'utf-8' || strtolower($charset) == 'us-ascii') { + return $encodedString; + } else { + return iconv($this->getCharsetAlias($charset), 'UTF-8//TRANSLIT//IGNORE', $encodedString); + } + } + + /** + * {@inheritdoc} + */ + public function getCharsetAlias($charset) + { + $charset = strtolower($charset); + + if (array_key_exists($charset, $this->charsetAlias)) { + return $this->charsetAlias[$charset]; + } else { + return null; + } + } +} diff --git a/vendor/php-mime-mail-parser/php-mime-mail-parser/src/Contracts/CharsetManager.php b/vendor/php-mime-mail-parser/php-mime-mail-parser/src/Contracts/CharsetManager.php new file mode 100644 index 000000000..660ec00cb --- /dev/null +++ b/vendor/php-mime-mail-parser/php-mime-mail-parser/src/Contracts/CharsetManager.php @@ -0,0 +1,24 @@ +parser = $fn; + } + + /** + * Process a mime part, optionally delegating parsing to the $next MiddlewareStack + */ + public function parse(MimePart $part, MiddlewareStack $next) + { + return call_user_func($this->parser, $part, $next); + } +} diff --git a/vendor/php-mime-mail-parser/php-mime-mail-parser/src/MiddlewareStack.php b/vendor/php-mime-mail-parser/php-mime-mail-parser/src/MiddlewareStack.php new file mode 100644 index 000000000..967783a48 --- /dev/null +++ b/vendor/php-mime-mail-parser/php-mime-mail-parser/src/MiddlewareStack.php @@ -0,0 +1,89 @@ +add($Middleware) + * + * @param Middleware $middleware + */ + public function __construct(Middleware $middleware = null) + { + $this->middleware = $middleware; + } + + /** + * Creates a chained middleware in MiddlewareStack + * + * @param Middleware $middleware + * @return MiddlewareStack Immutable MiddlewareStack + */ + public function add(Middleware $middleware) + { + $stack = new static($middleware); + $stack->next = $this; + return $stack; + } + + /** + * Parses the MimePart by passing it through the Middleware + * @param MimePart $part + * @return MimePart + */ + public function parse(MimePart $part) + { + if (!$this->middleware) { + return $part; + } + $part = call_user_func(array($this->middleware, 'parse'), $part, $this->next); + return $part; + } + + /** + * Creates a MiddlewareStack based on an array of middleware + * + * @param Middleware[] $middlewares + * @return MiddlewareStack + */ + public static function factory(array $middlewares = array()) + { + $stack = new static; + foreach ($middlewares as $middleware) { + $stack = $stack->add($middleware); + } + return $stack; + } + + /** + * Allow calling MiddlewareStack instance directly to invoke parse() + * + * @param MimePart $part + * @return MimePart + */ + public function __invoke(MimePart $part) + { + return $this->parse($part); + } +} diff --git a/vendor/php-mime-mail-parser/php-mime-mail-parser/src/MimePart.php b/vendor/php-mime-mail-parser/php-mime-mail-parser/src/MimePart.php new file mode 100644 index 000000000..a42728fbe --- /dev/null +++ b/vendor/php-mime-mail-parser/php-mime-mail-parser/src/MimePart.php @@ -0,0 +1,115 @@ +getPart(); + * $part['headers']['from'] = 'modified@example.com'; + * $MimePart->setPart($part); + */ +class MimePart implements \ArrayAccess +{ + /** + * Internal mime part + * + * @var array + */ + protected $part = array(); + + /** + * Immutable Part Id + * + * @var string + */ + private $id; + + /** + * Create a mime part + * + * @param array $part + * @param string $id + */ + public function __construct($id, array $part) + { + $this->part = $part; + $this->id = $id; + } + + /** + * Retrieve the part Id + * + * @return string + */ + public function getId() + { + return $this->id; + } + + /** + * Retrieve the part data + * + * @return array + */ + public function getPart() + { + return $this->part; + } + + /** + * Set the mime part data + * + * @param array $part + * @return void + */ + public function setPart(array $part) + { + $this->part = $part; + } + + /** + * ArrayAccess + */ + public function offsetSet($offset, $value) + { + if (is_null($offset)) { + $this->part[] = $value; + } else { + $this->part[$offset] = $value; + } + } + + /** + * ArrayAccess + */ + public function offsetExists($offset) + { + return isset($this->part[$offset]); + } + + /** + * ArrayAccess + */ + public function offsetUnset($offset) + { + unset($this->part[$offset]); + } + + /** + * ArrayAccess + */ + public function offsetGet($offset) + { + return isset($this->part[$offset]) ? $this->part[$offset] : null; + } +} diff --git a/vendor/php-mime-mail-parser/php-mime-mail-parser/src/Parser.php b/vendor/php-mime-mail-parser/php-mime-mail-parser/src/Parser.php new file mode 100644 index 000000000..3a641d485 --- /dev/null +++ b/vendor/php-mime-mail-parser/php-mime-mail-parser/src/Parser.php @@ -0,0 +1,944 @@ +saveAttachments(). + */ + const ATTACHMENT_DUPLICATE_THROW = 'DuplicateThrow'; + const ATTACHMENT_DUPLICATE_SUFFIX = 'DuplicateSuffix'; + const ATTACHMENT_RANDOM_FILENAME = 'RandomFilename'; + + /** + * PHP MimeParser Resource ID + * + * @var resource $resource + */ + protected $resource; + + /** + * A file pointer to email + * + * @var resource $stream + */ + protected $stream; + + /** + * A text of an email + * + * @var string $data + */ + protected $data; + + /** + * Parts of an email + * + * @var array $parts + */ + protected $parts; + + /** + * @var CharsetManager object + */ + protected $charset; + + /** + * Valid stream modes for reading + * + * @var array + */ + protected static $readableModes = [ + 'r', 'r+', 'w+', 'a+', 'x+', 'c+', 'rb', 'r+b', 'w+b', 'a+b', + 'x+b', 'c+b', 'rt', 'r+t', 'w+t', 'a+t', 'x+t', 'c+t' + ]; + + /** + * Stack of middleware registered to process data + * + * @var MiddlewareStack + */ + protected $middlewareStack; + + /** + * Parser constructor. + * + * @param CharsetManager|null $charset + */ + public function __construct(CharsetManager $charset = null) + { + if ($charset == null) { + $charset = new Charset(); + } + + $this->charset = $charset; + $this->middlewareStack = new MiddlewareStack(); + } + + /** + * Free the held resources + * + * @return void + */ + public function __destruct() + { + // clear the email file resource + if (is_resource($this->stream)) { + fclose($this->stream); + } + // clear the MailParse resource + if (is_resource($this->resource)) { + mailparse_msg_free($this->resource); + } + } + + /** + * Set the file path we use to get the email text + * + * @param string $path File path to the MIME mail + * + * @return Parser MimeMailParser Instance + */ + public function setPath($path) + { + // should parse message incrementally from file + $this->resource = mailparse_msg_parse_file($path); + $this->stream = fopen($path, 'r'); + $this->parse(); + + return $this; + } + + /** + * Set the Stream resource we use to get the email text + * + * @param resource $stream + * + * @return Parser MimeMailParser Instance + * @throws Exception + */ + public function setStream($stream) + { + // streams have to be cached to file first + $meta = @stream_get_meta_data($stream); + if (!$meta || !$meta['mode'] || !in_array($meta['mode'], self::$readableModes, true) || $meta['eof']) { + throw new Exception( + 'setStream() expects parameter stream to be readable stream resource.' + ); + } + + /** @var resource $tmp_fp */ + $tmp_fp = tmpfile(); + if ($tmp_fp) { + while (!feof($stream)) { + fwrite($tmp_fp, fread($stream, 2028)); + } + fseek($tmp_fp, 0); + $this->stream = &$tmp_fp; + } else { + throw new Exception( + 'Could not create temporary files for attachments. Your tmp directory may be unwritable by PHP.' + ); + } + fclose($stream); + + $this->resource = mailparse_msg_create(); + // parses the message incrementally (low memory usage but slower) + while (!feof($this->stream)) { + mailparse_msg_parse($this->resource, fread($this->stream, 2082)); + } + $this->parse(); + + return $this; + } + + /** + * Set the email text + * + * @param string $data + * + * @return Parser MimeMailParser Instance + */ + public function setText($data) + { + if (!$data) { + throw new Exception('You must not call MimeMailParser::setText with an empty string parameter'); + } + $this->resource = mailparse_msg_create(); + // does not parse incrementally, fast memory hog might explode + mailparse_msg_parse($this->resource, $data); + $this->data = $data; + $this->parse(); + + return $this; + } + + /** + * Parse the Message into parts + * + * @return void + */ + protected function parse() + { + $structure = mailparse_msg_get_structure($this->resource); + $this->parts = []; + foreach ($structure as $part_id) { + $part = mailparse_msg_get_part($this->resource, $part_id); + $part_data = mailparse_msg_get_part_data($part); + $mimePart = new MimePart($part_id, $part_data); + // let each middleware parse the part before saving + $this->parts[$part_id] = $this->middlewareStack->parse($mimePart)->getPart(); + } + } + + /** + * Retrieve a specific Email Header, without charset conversion. + * + * @param string $name Header name (case-insensitive) + * + * @return string + * @throws Exception + */ + public function getRawHeader($name) + { + $name = strtolower($name); + if (isset($this->parts[1])) { + $headers = $this->getPart('headers', $this->parts[1]); + + return (isset($headers[$name])) ? $headers[$name] : false; + } else { + throw new Exception( + 'setPath() or setText() or setStream() must be called before retrieving email headers.' + ); + } + } + + /** + * Retrieve a specific Email Header + * + * @param string $name Header name (case-insensitive) + * + * @return string + */ + public function getHeader($name) + { + $rawHeader = $this->getRawHeader($name); + if ($rawHeader === false) { + return false; + } + + return $this->decodeHeader($rawHeader); + } + + /** + * Retrieve all mail headers + * + * @return array + * @throws Exception + */ + public function getHeaders() + { + if (isset($this->parts[1])) { + $headers = $this->getPart('headers', $this->parts[1]); + foreach ($headers as $name => &$value) { + if (is_array($value)) { + foreach ($value as &$v) { + $v = $this->decodeSingleHeader($v); + } + } else { + $value = $this->decodeSingleHeader($value); + } + } + + return $headers; + } else { + throw new Exception( + 'setPath() or setText() or setStream() must be called before retrieving email headers.' + ); + } + } + + /** + * Retrieve the raw mail headers as a string + * + * @return string + * @throws Exception + */ + public function getHeadersRaw() + { + if (isset($this->parts[1])) { + return $this->getPartHeader($this->parts[1]); + } else { + throw new Exception( + 'setPath() or setText() or setStream() must be called before retrieving email headers.' + ); + } + } + + /** + * Retrieve the raw Header of a MIME part + * + * @return String + * @param $part Object + * @throws Exception + */ + protected function getPartHeader(&$part) + { + $header = ''; + if ($this->stream) { + $header = $this->getPartHeaderFromFile($part); + } elseif ($this->data) { + $header = $this->getPartHeaderFromText($part); + } + return $header; + } + + /** + * Retrieve the Header from a MIME part from file + * + * @return String Mime Header Part + * @param $part Array + */ + protected function getPartHeaderFromFile(&$part) + { + $start = $part['starting-pos']; + $end = $part['starting-pos-body']; + fseek($this->stream, $start, SEEK_SET); + $header = fread($this->stream, $end - $start); + return $header; + } + + /** + * Retrieve the Header from a MIME part from text + * + * @return String Mime Header Part + * @param $part Array + */ + protected function getPartHeaderFromText(&$part) + { + $start = $part['starting-pos']; + $end = $part['starting-pos-body']; + $header = substr($this->data, $start, $end - $start); + return $header; + } + + /** + * Checks whether a given part ID is a child of another part + * eg. an RFC822 attachment may have one or more text parts + * + * @param string $partId + * @param string $parentPartId + * @return bool + */ + protected function partIdIsChildOfPart($partId, $parentPartId) + { + $parentPartId = $parentPartId.'.'; + return substr($partId, 0, strlen($parentPartId)) == $parentPartId; + } + + /** + * Whether the given part ID is a child of any attachment part in the message. + * + * @param string $checkPartId + * @return bool + */ + protected function partIdIsChildOfAnAttachment($checkPartId) + { + foreach ($this->parts as $partId => $part) { + if ($this->getPart('content-disposition', $part) == 'attachment') { + if ($this->partIdIsChildOfPart($checkPartId, $partId)) { + return true; + } + } + } + return false; + } + + /** + * Returns the email message body in the specified format + * + * @param string $type text, html or htmlEmbedded + * + * @return string Body + * @throws Exception + */ + public function getMessageBody($type = 'text') + { + $mime_types = [ + 'text' => 'text/plain', + 'html' => 'text/html', + 'htmlEmbedded' => 'text/html', + ]; + + if (in_array($type, array_keys($mime_types))) { + $part_type = $type === 'htmlEmbedded' ? 'html' : $type; + $inline_parts = $this->getInlineParts($part_type); + $body = empty($inline_parts) ? '' : $inline_parts[0]; + } else { + throw new Exception( + 'Invalid type specified for getMessageBody(). Expected: text, html or htmlEmbeded.' + ); + } + + if ($type == 'htmlEmbedded') { + $attachments = $this->getAttachments(); + foreach ($attachments as $attachment) { + if ($attachment->getContentID() != '') { + $body = str_replace( + '"cid:'.$attachment->getContentID().'"', + '"'.$this->getEmbeddedData($attachment->getContentID()).'"', + $body + ); + } + } + } + + return $body; + } + + /** + * Returns the embedded data structure + * + * @param string $contentId Content-Id + * + * @return string + */ + protected function getEmbeddedData($contentId) + { + foreach ($this->parts as $part) { + if ($this->getPart('content-id', $part) == $contentId) { + $embeddedData = 'data:'; + $embeddedData .= $this->getPart('content-type', $part); + $embeddedData .= ';'.$this->getPart('transfer-encoding', $part); + $embeddedData .= ','.$this->getPartBody($part); + return $embeddedData; + } + } + return ''; + } + + /** + * Return an array with the following keys display, address, is_group + * + * @param string $name Header name (case-insensitive) + * + * @return array + */ + public function getAddresses($name) + { + $value = $this->getRawHeader($name); + $value = (is_array($value)) ? $value[0] : $value; + $addresses = mailparse_rfc822_parse_addresses($value); + foreach ($addresses as $i => $item) { + $addresses[$i]['display'] = $this->decodeHeader($item['display']); + } + return $addresses; + } + + /** + * Returns the attachments contents in order of appearance + * + * @return Attachment[] + */ + public function getInlineParts($type = 'text') + { + $inline_parts = []; + $mime_types = [ + 'text' => 'text/plain', + 'html' => 'text/html', + ]; + + if (!in_array($type, array_keys($mime_types))) { + throw new Exception('Invalid type specified for getInlineParts(). "type" can either be text or html.'); + } + + foreach ($this->parts as $partId => $part) { + if ($this->getPart('content-type', $part) == $mime_types[$type] + && $this->getPart('content-disposition', $part) != 'attachment' + && !$this->partIdIsChildOfAnAttachment($partId) + ) { + $headers = $this->getPart('headers', $part); + $encodingType = array_key_exists('content-transfer-encoding', $headers) ? + $headers['content-transfer-encoding'] : ''; + $undecoded_body = $this->decodeContentTransfer($this->getPartBody($part), $encodingType); + $inline_parts[] = $this->charset->decodeCharset($undecoded_body, $this->getPartCharset($part)); + } + } + + return $inline_parts; + } + + /** + * Returns the attachments contents in order of appearance + * + * @return Attachment[] + */ + public function getAttachments($include_inline = true) + { + $attachments = []; + $dispositions = $include_inline ? ['attachment', 'inline'] : ['attachment']; + $non_attachment_types = ['text/plain', 'text/html']; + $nonameIter = 0; + + foreach ($this->parts as $part) { + $disposition = $this->getPart('content-disposition', $part); + $filename = 'noname'; + + if (isset($part['disposition-filename'])) { + $filename = $this->decodeHeader($part['disposition-filename']); + // Escape all potentially unsafe characters from the filename + $filename = preg_replace('((^\.)|\/|(\.$))', '_', $filename); + } elseif (isset($part['content-name'])) { + // if we have no disposition but we have a content-name, it's a valid attachment. + // we simulate the presence of an attachment disposition with a disposition filename + $filename = $this->decodeHeader($part['content-name']); + // Escape all potentially unsafe characters from the filename + $filename = preg_replace('((^\.)|\/|(\.$))', '_', $filename); + $disposition = 'attachment'; + } elseif (in_array($part['content-type'], $non_attachment_types, true) + && $disposition !== 'attachment') { + // it is a message body, no attachment + continue; + } elseif (substr($part['content-type'], 0, 10) !== 'multipart/') { + // if we cannot get it by getMessageBody(), we assume it is an attachment + $disposition = 'attachment'; + } + if (in_array($disposition, ['attachment', 'inline']) === false && !empty($disposition)) { + $disposition = 'attachment'; + } + + if (in_array($disposition, $dispositions) === true) { + if ($filename == 'noname') { + $nonameIter++; + $filename = 'noname'.$nonameIter; + } + + $headersAttachments = $this->getPart('headers', $part); + $contentidAttachments = $this->getPart('content-id', $part); + + $attachmentStream = $this->getAttachmentStream($part); + $mimePartStr = $this->getPartComplete($part); + + $attachments[] = new Attachment( + $filename, + $this->getPart('content-type', $part), + $attachmentStream, + $disposition, + $contentidAttachments, + $headersAttachments, + $mimePartStr + ); + } + } + + return $attachments; + } + + /** + * Save attachments in a folder + * + * @param string $attach_dir directory + * @param bool $include_inline + * @param string $filenameStrategy How to generate attachment filenames + * + * @return array Saved attachments paths + * @throws Exception + */ + public function saveAttachments( + $attach_dir, + $include_inline = true, + $filenameStrategy = self::ATTACHMENT_DUPLICATE_SUFFIX + ) { + $attachments = $this->getAttachments($include_inline); + if (empty($attachments)) { + return false; + } + + if (!is_dir($attach_dir)) { + mkdir($attach_dir); + } + + $attachments_paths = []; + foreach ($attachments as $attachment) { + // Determine filename + switch ($filenameStrategy) { + case self::ATTACHMENT_RANDOM_FILENAME: + $attachment_path = tempnam($attach_dir, ''); + break; + case self::ATTACHMENT_DUPLICATE_THROW: + case self::ATTACHMENT_DUPLICATE_SUFFIX: + $attachment_path = $attach_dir.$attachment->getFilename(); + break; + default: + throw new Exception('Invalid filename strategy argument provided.'); + } + + // Handle duplicate filename + if (file_exists($attachment_path)) { + switch ($filenameStrategy) { + case self::ATTACHMENT_DUPLICATE_THROW: + throw new Exception('Could not create file for attachment: duplicate filename.'); + case self::ATTACHMENT_DUPLICATE_SUFFIX: + $attachment_path = tempnam($attach_dir, $attachment->getFilename()); + break; + } + } + + /** @var resource $fp */ + if ($fp = fopen($attachment_path, 'w')) { + while ($bytes = $attachment->read()) { + fwrite($fp, $bytes); + } + fclose($fp); + $attachments_paths[] = realpath($attachment_path); + } else { + throw new Exception('Could not write attachments. Your directory may be unwritable by PHP.'); + } + } + + return $attachments_paths; + } + + /** + * Read the attachment Body and save temporary file resource + * + * @param array $part + * + * @return resource Mime Body Part + * @throws Exception + */ + protected function getAttachmentStream(&$part) + { + /** @var resource $temp_fp */ + $temp_fp = tmpfile(); + + $headers = $this->getPart('headers', $part); + $encodingType = array_key_exists('content-transfer-encoding', $headers) ? + $headers['content-transfer-encoding'] : ''; + + if ($temp_fp) { + if ($this->stream) { + $start = $part['starting-pos-body']; + $end = $part['ending-pos-body']; + fseek($this->stream, $start, SEEK_SET); + $len = $end - $start; + $written = 0; + while ($written < $len) { + $write = $len; + $data = fread($this->stream, $write); + fwrite($temp_fp, $this->decodeContentTransfer($data, $encodingType)); + $written += $write; + } + } elseif ($this->data) { + $attachment = $this->decodeContentTransfer($this->getPartBodyFromText($part), $encodingType); + fwrite($temp_fp, $attachment, strlen($attachment)); + } + fseek($temp_fp, 0, SEEK_SET); + } else { + throw new Exception( + 'Could not create temporary files for attachments. Your tmp directory may be unwritable by PHP.' + ); + } + + return $temp_fp; + } + + /** + * Decode the string from Content-Transfer-Encoding + * + * @param string $encodedString The string in its original encoded state + * @param string $encodingType The encoding type from the Content-Transfer-Encoding header of the part. + * + * @return string The decoded string + */ + protected function decodeContentTransfer($encodedString, $encodingType) + { + if (is_array($encodingType)) { + $encodingType = $encodingType[0]; + } + + $encodingType = strtolower($encodingType); + if ($encodingType == 'base64') { + return base64_decode($encodedString); + } elseif ($encodingType == 'quoted-printable') { + return quoted_printable_decode($encodedString); + } else { + return $encodedString; + } + } + + /** + * $input can be a string or array + * + * @param string|array $input + * + * @return string + */ + protected function decodeHeader($input) + { + //Sometimes we have 2 label From so we take only the first + if (is_array($input)) { + return $this->decodeSingleHeader($input[0]); + } + + return $this->decodeSingleHeader($input); + } + + /** + * Decodes a single header (= string) + * + * @param string $input + * + * @return string + */ + protected function decodeSingleHeader($input) + { + // For each encoded-word... + while (preg_match('/(=\?([^?]+)\?(q|b)\?([^?]*)\?=)((\s+)=\?)?/i', $input, $matches)) { + $encoded = $matches[1]; + $charset = $matches[2]; + $encoding = $matches[3]; + $text = $matches[4]; + $space = isset($matches[6]) ? $matches[6] : ''; + + switch (strtolower($encoding)) { + case 'b': + $text = $this->decodeContentTransfer($text, 'base64'); + break; + + case 'q': + $text = str_replace('_', ' ', $text); + preg_match_all('/=([a-f0-9]{2})/i', $text, $matches); + foreach ($matches[1] as $value) { + $text = str_replace('='.$value, chr(hexdec($value)), $text); + } + break; + } + + $text = $this->charset->decodeCharset($text, $this->charset->getCharsetAlias($charset)); + $input = str_replace($encoded.$space, $text, $input); + } + + return $input; + } + + /** + * Return the charset of the MIME part + * + * @param array $part + * + * @return string + */ + protected function getPartCharset($part) + { + if (isset($part['charset'])) { + return $this->charset->getCharsetAlias($part['charset']); + } else { + return 'us-ascii'; + } + } + + /** + * Retrieve a specified MIME part + * + * @param string $type + * @param array $parts + * + * @return string|array + */ + protected function getPart($type, $parts) + { + return (isset($parts[$type])) ? $parts[$type] : false; + } + + /** + * Retrieve the Body of a MIME part + * + * @param array $part + * + * @return string + */ + protected function getPartBody(&$part) + { + $body = ''; + if ($this->stream) { + $body = $this->getPartBodyFromFile($part); + } elseif ($this->data) { + $body = $this->getPartBodyFromText($part); + } + + return $body; + } + + /** + * Retrieve the Body from a MIME part from file + * + * @param array $part + * + * @return string Mime Body Part + */ + protected function getPartBodyFromFile(&$part) + { + $start = $part['starting-pos-body']; + $end = $part['ending-pos-body']; + $body = ''; + if ($end - $start > 0) { + fseek($this->stream, $start, SEEK_SET); + $body = fread($this->stream, $end - $start); + } + + return $body; + } + + /** + * Retrieve the Body from a MIME part from text + * + * @param array $part + * + * @return string Mime Body Part + */ + protected function getPartBodyFromText(&$part) + { + $start = $part['starting-pos-body']; + $end = $part['ending-pos-body']; + + return substr($this->data, $start, $end - $start); + } + + /** + * Retrieve the content of a MIME part + * + * @param array $part + * + * @return string + */ + protected function getPartComplete(&$part) + { + $body = ''; + if ($this->stream) { + $body = $this->getPartFromFile($part); + } elseif ($this->data) { + $body = $this->getPartFromText($part); + } + + return $body; + } + + /** + * Retrieve the content from a MIME part from file + * + * @param array $part + * + * @return string Mime Content + */ + protected function getPartFromFile(&$part) + { + $start = $part['starting-pos']; + $end = $part['ending-pos']; + $body = ''; + if ($end - $start > 0) { + fseek($this->stream, $start, SEEK_SET); + $body = fread($this->stream, $end - $start); + } + + return $body; + } + + /** + * Retrieve the content from a MIME part from text + * + * @param array $part + * + * @return string Mime Content + */ + protected function getPartFromText(&$part) + { + $start = $part['starting-pos']; + $end = $part['ending-pos']; + + return substr($this->data, $start, $end - $start); + } + + /** + * Retrieve the resource + * + * @return resource resource + */ + public function getResource() + { + return $this->resource; + } + + /** + * Retrieve the file pointer to email + * + * @return resource stream + */ + public function getStream() + { + return $this->stream; + } + + /** + * Retrieve the text of an email + * + * @return string data + */ + public function getData() + { + return $this->data; + } + + /** + * Retrieve the parts of an email + * + * @return array parts + */ + public function getParts() + { + return $this->parts; + } + + /** + * Retrieve the charset manager object + * + * @return CharsetManager charset + */ + public function getCharset() + { + return $this->charset; + } + + /** + * Add a middleware to the parser MiddlewareStack + * Each middleware is invoked when: + * a MimePart is retrieved by mailparse_msg_get_part_data() during $this->parse() + * The middleware will receive MimePart $part and the next MiddlewareStack $next + * + * Eg: + * + * $Parser->addMiddleware(function(MimePart $part, MiddlewareStack $next) { + * // do something with the $part + * return $next($part); + * }); + * + * @param callable $middleware Plain Function or Middleware Instance to execute + * @return void + */ + public function addMiddleware(callable $middleware) + { + if (!$middleware instanceof Middleware) { + $middleware = new Middleware($middleware); + } + $this->middlewareStack = $this->middlewareStack->add($middleware); + } +}