forked from LiveCarta/LiveCartaWP
Changed source root directory
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Zend
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Zend
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Exception extends Exception
|
||||
{
|
||||
/**
|
||||
* @var null|Exception
|
||||
*/
|
||||
private $_previous = null;
|
||||
|
||||
/**
|
||||
* Construct the exception
|
||||
*
|
||||
* @param string $msg
|
||||
* @param int $code
|
||||
* @param Exception $previous
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($msg = '', $code = 0, ?Exception $previous = null)
|
||||
{
|
||||
if (version_compare(PHP_VERSION, '5.3.0', '<')) {
|
||||
parent::__construct($msg, (int) $code);
|
||||
$this->_previous = $previous;
|
||||
} else {
|
||||
parent::__construct($msg, (int) $code, $previous);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Overloading
|
||||
*
|
||||
* For PHP < 5.3.0, provides access to the getPrevious() method.
|
||||
*
|
||||
* @param string $method
|
||||
* @param array $args
|
||||
* @return mixed
|
||||
*/
|
||||
public function __call($method, array $args)
|
||||
{
|
||||
if ('getprevious' == strtolower($method)) {
|
||||
return $this->_getPrevious();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* String representation of the exception
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
if (version_compare(PHP_VERSION, '5.3.0', '<')) {
|
||||
if (null !== ($e = $this->getPrevious())) {
|
||||
return $e->__toString()
|
||||
. "\n\nNext "
|
||||
. parent::__toString();
|
||||
}
|
||||
}
|
||||
return parent::__toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns previous Exception
|
||||
*
|
||||
* @return Exception|null
|
||||
*/
|
||||
protected function _getPrevious()
|
||||
{
|
||||
return $this->_previous;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,343 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Loader
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* Static methods for loading classes and files.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Loader
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Loader
|
||||
{
|
||||
/**
|
||||
* Loads a class from a PHP file. The filename must be formatted
|
||||
* as "$class.php".
|
||||
*
|
||||
* If $dirs is a string or an array, it will search the directories
|
||||
* in the order supplied, and attempt to load the first matching file.
|
||||
*
|
||||
* If $dirs is null, it will split the class name at underscores to
|
||||
* generate a path hierarchy (e.g., "Postman_Zend_Example_Class" will map
|
||||
* to "Zend/Example/Class.php").
|
||||
*
|
||||
* If the file was not found in the $dirs, or if no $dirs were specified,
|
||||
* it will attempt to load it from PHP's include_path.
|
||||
*
|
||||
* @param string $class - The full class name of a Zend component.
|
||||
* @param string|array $dirs - OPTIONAL Either a path or an array of paths
|
||||
* to search.
|
||||
* @return void
|
||||
* @throws Postman_Zend_Exception
|
||||
*/
|
||||
public static function loadClass($class, $dirs = null)
|
||||
{
|
||||
if (class_exists($class, false) || interface_exists($class, false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((null !== $dirs) && !is_string($dirs) && !is_array($dirs)) {
|
||||
require_once 'Zend/Exception.php';
|
||||
throw new Postman_Zend_Exception('Directory argument must be a string or an array');
|
||||
}
|
||||
|
||||
$file = self::standardiseFile($class);
|
||||
|
||||
if (!empty($dirs)) {
|
||||
// use the autodiscovered path
|
||||
$dirPath = dirname($file);
|
||||
if (is_string($dirs)) {
|
||||
$dirs = explode(PATH_SEPARATOR, $dirs);
|
||||
}
|
||||
foreach ($dirs as $key => $dir) {
|
||||
if ($dir == '.') {
|
||||
$dirs[$key] = $dirPath;
|
||||
} else {
|
||||
$dir = rtrim($dir, '\\/');
|
||||
$dirs[$key] = $dir . DIRECTORY_SEPARATOR . $dirPath;
|
||||
}
|
||||
}
|
||||
$file = basename($file);
|
||||
self::loadFile($file, $dirs, true);
|
||||
} else {
|
||||
self::loadFile($file, null, true);
|
||||
}
|
||||
|
||||
if (!class_exists($class, false) && !interface_exists($class, false)) {
|
||||
require_once 'Zend/Exception.php';
|
||||
throw new Postman_Zend_Exception("File \"$file\" does not exist or class \"$class\" was not found in the file");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a PHP file. This is a wrapper for PHP's include() function.
|
||||
*
|
||||
* $filename must be the complete filename, including any
|
||||
* extension such as ".php". Note that a security check is performed that
|
||||
* does not permit extended characters in the filename. This method is
|
||||
* intended for loading Zend Framework files.
|
||||
*
|
||||
* If $dirs is a string or an array, it will search the directories
|
||||
* in the order supplied, and attempt to load the first matching file.
|
||||
*
|
||||
* If the file was not found in the $dirs, or if no $dirs were specified,
|
||||
* it will attempt to load it from PHP's include_path.
|
||||
*
|
||||
* If $once is TRUE, it will use include_once() instead of include().
|
||||
*
|
||||
* @param string $filename
|
||||
* @param string|array $dirs - OPTIONAL either a path or array of paths
|
||||
* to search.
|
||||
* @param boolean $once
|
||||
* @return boolean
|
||||
* @throws Postman_Zend_Exception
|
||||
*/
|
||||
public static function loadFile($filename, $dirs = null, $once = false)
|
||||
{
|
||||
self::_securityCheck($filename);
|
||||
|
||||
/**
|
||||
* Search in provided directories, as well as include_path
|
||||
*/
|
||||
$incPath = false;
|
||||
if (!empty($dirs) && (is_array($dirs) || is_string($dirs))) {
|
||||
if (is_array($dirs)) {
|
||||
$dirs = implode(PATH_SEPARATOR, $dirs);
|
||||
}
|
||||
$incPath = get_include_path();
|
||||
set_include_path($dirs . PATH_SEPARATOR . $incPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Try finding for the plain filename in the include_path.
|
||||
*/
|
||||
if ($once) {
|
||||
include_once $filename;
|
||||
} else {
|
||||
include $filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* If searching in directories, reset include_path
|
||||
*/
|
||||
if ($incPath) {
|
||||
set_include_path($incPath);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns TRUE if the $filename is readable, or FALSE otherwise.
|
||||
* This function uses the PHP include_path, where PHP's is_readable()
|
||||
* does not.
|
||||
*
|
||||
* Note from ZF-2900:
|
||||
* If you use custom error handler, please check whether return value
|
||||
* from error_reporting() is zero or not.
|
||||
* At mark of fopen() can not suppress warning if the handler is used.
|
||||
*
|
||||
* @param string $filename
|
||||
* @return boolean
|
||||
*/
|
||||
public static function isReadable($filename)
|
||||
{
|
||||
if (is_readable($filename)) {
|
||||
// Return early if the filename is readable without needing the
|
||||
// include_path
|
||||
return true;
|
||||
}
|
||||
|
||||
if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN'
|
||||
&& preg_match('/^[a-z]:/i', $filename)
|
||||
) {
|
||||
// If on windows, and path provided is clearly an absolute path,
|
||||
// return false immediately
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (self::explodeIncludePath() as $path) {
|
||||
if ($path == '.') {
|
||||
if (is_readable($filename)) {
|
||||
return true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
$file = $path . '/' . $filename;
|
||||
if (is_readable($file)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Explode an include path into an array
|
||||
*
|
||||
* If no path provided, uses current include_path. Works around issues that
|
||||
* occur when the path includes stream schemas.
|
||||
*
|
||||
* @param string|null $path
|
||||
* @return array
|
||||
*/
|
||||
public static function explodeIncludePath($path = null)
|
||||
{
|
||||
if (null === $path) {
|
||||
$path = get_include_path();
|
||||
}
|
||||
|
||||
if (PATH_SEPARATOR == ':') {
|
||||
// On *nix systems, include_paths which include paths with a stream
|
||||
// schema cannot be safely explode'd, so we have to be a bit more
|
||||
// intelligent in the approach.
|
||||
$paths = preg_split('#:(?!//)#', $path);
|
||||
} else {
|
||||
$paths = explode(PATH_SEPARATOR, $path);
|
||||
}
|
||||
return $paths;
|
||||
}
|
||||
|
||||
/**
|
||||
* spl_autoload() suitable implementation for supporting class autoloading.
|
||||
*
|
||||
* Attach to spl_autoload() using the following:
|
||||
* <code>
|
||||
* spl_autoload_register(array('Postman_Zend_Loader', 'autoload'));
|
||||
* </code>
|
||||
*
|
||||
* @deprecated Since 1.8.0
|
||||
* @param string $class
|
||||
* @return string|false Class name on success; false on failure
|
||||
*/
|
||||
public static function autoload($class)
|
||||
{
|
||||
trigger_error(__CLASS__ . '::' . __METHOD__ . ' is deprecated as of 1.8.0 and will be removed with 2.0.0; use Postman_Zend_Loader_Autoloader instead', E_USER_NOTICE);
|
||||
try {
|
||||
@self::loadClass($class);
|
||||
return $class;
|
||||
} catch (Exception $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register {@link autoload()} with spl_autoload()
|
||||
*
|
||||
* @deprecated Since 1.8.0
|
||||
* @param string $class (optional)
|
||||
* @param boolean $enabled (optional)
|
||||
* @return void
|
||||
* @throws Postman_Zend_Exception if spl_autoload() is not found
|
||||
* or if the specified class does not have an autoload() method.
|
||||
*/
|
||||
public static function registerAutoload($class = 'Postman_Zend_Loader', $enabled = true)
|
||||
{
|
||||
trigger_error(__CLASS__ . '::' . __METHOD__ . ' is deprecated as of 1.8.0 and will be removed with 2.0.0; use Postman_Zend_Loader_Autoloader instead', E_USER_NOTICE);
|
||||
require_once 'Zend/Loader/Autoloader.php';
|
||||
$autoloader = Postman_Zend_Loader_Autoloader::getInstance();
|
||||
$autoloader->setFallbackAutoloader(true);
|
||||
|
||||
if ('Postman_Zend_Loader' != $class) {
|
||||
self::loadClass($class);
|
||||
$methods = get_class_methods($class);
|
||||
if (!in_array('autoload', (array) $methods)) {
|
||||
require_once 'Zend/Exception.php';
|
||||
throw new Postman_Zend_Exception("The class \"$class\" does not have an autoload() method");
|
||||
}
|
||||
|
||||
$callback = array($class, 'autoload');
|
||||
|
||||
if ($enabled) {
|
||||
$autoloader->pushAutoloader($callback);
|
||||
} else {
|
||||
$autoloader->removeAutoloader($callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that filename does not contain exploits
|
||||
*
|
||||
* @param string $filename
|
||||
* @return void
|
||||
* @throws Postman_Zend_Exception
|
||||
*/
|
||||
protected static function _securityCheck($filename)
|
||||
{
|
||||
/**
|
||||
* Security check
|
||||
*/
|
||||
if (preg_match('/[^a-z0-9\\/\\\\_.:-]/i', $filename)) {
|
||||
require_once 'Zend/Exception.php';
|
||||
throw new Postman_Zend_Exception('Security check: Illegal character in filename');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to include() the file.
|
||||
*
|
||||
* include() is not prefixed with the @ operator because if
|
||||
* the file is loaded and contains a parse error, execution
|
||||
* will halt silently and this is difficult to debug.
|
||||
*
|
||||
* Always set display_errors = Off on production servers!
|
||||
*
|
||||
* @param string $filespec
|
||||
* @param boolean $once
|
||||
* @return boolean
|
||||
* @deprecated Since 1.5.0; use loadFile() instead
|
||||
*/
|
||||
protected static function _includeFile($filespec, $once = false)
|
||||
{
|
||||
if ($once) {
|
||||
return include_once $filespec;
|
||||
} else {
|
||||
return include $filespec ;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Standardise the filename.
|
||||
*
|
||||
* Convert the supplied filename into the namespace-aware standard,
|
||||
* based on the Framework Interop Group reference implementation:
|
||||
* http://groups.google.com/group/php-standards/web/psr-0-final-proposal
|
||||
*
|
||||
* The filename must be formatted as "$file.php".
|
||||
*
|
||||
* @param string $file - The file name to be loaded.
|
||||
* @return string
|
||||
*/
|
||||
public static function standardiseFile($file)
|
||||
{
|
||||
$fileName = ltrim($file, '\\');
|
||||
$file = '';
|
||||
$namespace = '';
|
||||
if ($lastNsPos = strripos($fileName, '\\')) {
|
||||
$namespace = substr($fileName, 0, $lastNsPos);
|
||||
$fileName = substr($fileName, $lastNsPos + 1);
|
||||
$file = str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR;
|
||||
}
|
||||
$file .= str_replace('_', DIRECTORY_SEPARATOR, $fileName) . '.php';
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,589 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Loader
|
||||
* @subpackage Autoloader
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @version $Id$
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
/** Postman_Zend_Loader */
|
||||
require_once 'Zend/Loader.php';
|
||||
|
||||
/**
|
||||
* Autoloader stack and namespace autoloader
|
||||
*
|
||||
* @uses Postman_Zend_Loader_Autoloader
|
||||
* @package Postman_Zend_Loader
|
||||
* @subpackage Autoloader
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Loader_Autoloader
|
||||
{
|
||||
/**
|
||||
* @var Postman_Zend_Loader_Autoloader Singleton instance
|
||||
*/
|
||||
protected static $_instance;
|
||||
|
||||
/**
|
||||
* @var array Concrete autoloader callback implementations
|
||||
*/
|
||||
protected $_autoloaders = array();
|
||||
|
||||
/**
|
||||
* @var array Default autoloader callback
|
||||
*/
|
||||
protected $_defaultAutoloader = array('Postman_Zend_Loader', 'loadClass');
|
||||
|
||||
/**
|
||||
* @var bool Whether or not to act as a fallback autoloader
|
||||
*/
|
||||
protected $_fallbackAutoloader = false;
|
||||
|
||||
/**
|
||||
* @var array Callback for internal autoloader implementation
|
||||
*/
|
||||
protected $_internalAutoloader;
|
||||
|
||||
/**
|
||||
* @var array Supported namespaces 'Zend' and 'ZendX' by default.
|
||||
*/
|
||||
protected $_namespaces = array(
|
||||
'Postman_Zend_' => true,
|
||||
'ZendX_' => true,
|
||||
);
|
||||
|
||||
/**
|
||||
* @var array Namespace-specific autoloaders
|
||||
*/
|
||||
protected $_namespaceAutoloaders = array();
|
||||
|
||||
/**
|
||||
* @var bool Whether or not to suppress file not found warnings
|
||||
*/
|
||||
protected $_suppressNotFoundWarnings = false;
|
||||
|
||||
/**
|
||||
* @var null|string
|
||||
*/
|
||||
protected $_zfPath;
|
||||
|
||||
/**
|
||||
* Retrieve singleton instance
|
||||
*
|
||||
* @return Postman_Zend_Loader_Autoloader
|
||||
*/
|
||||
public static function getInstance()
|
||||
{
|
||||
if (null === self::$_instance) {
|
||||
self::$_instance = new self();
|
||||
}
|
||||
return self::$_instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the singleton instance
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function resetInstance()
|
||||
{
|
||||
self::$_instance = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Autoload a class
|
||||
*
|
||||
* @param string $class
|
||||
* @return bool
|
||||
*/
|
||||
public static function autoload($class)
|
||||
{
|
||||
$self = self::getInstance();
|
||||
|
||||
foreach ($self->getClassAutoloaders($class) as $autoloader) {
|
||||
if ($autoloader instanceof Postman_Zend_Loader_Autoloader_Interface) {
|
||||
if ($autoloader->autoload($class)) {
|
||||
return true;
|
||||
}
|
||||
} elseif (is_array($autoloader)) {
|
||||
if (call_user_func($autoloader, $class)) {
|
||||
return true;
|
||||
}
|
||||
} elseif (is_string($autoloader) || is_callable($autoloader)) {
|
||||
if ($autoloader($class)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default autoloader implementation
|
||||
*
|
||||
* @param string|array $callback PHP callback
|
||||
* @return void
|
||||
*/
|
||||
public function setDefaultAutoloader($callback)
|
||||
{
|
||||
if (!is_callable($callback)) {
|
||||
throw new Postman_Zend_Loader_Exception('Invalid callback specified for default autoloader');
|
||||
}
|
||||
|
||||
$this->_defaultAutoloader = $callback;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the default autoloader callback
|
||||
*
|
||||
* @return string|array PHP Callback
|
||||
*/
|
||||
public function getDefaultAutoloader()
|
||||
{
|
||||
return $this->_defaultAutoloader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set several autoloader callbacks at once
|
||||
*
|
||||
* @param array $autoloaders Array of PHP callbacks (or Postman_Zend_Loader_Autoloader_Interface implementations) to act as autoloaders
|
||||
* @return Postman_Zend_Loader_Autoloader
|
||||
*/
|
||||
public function setAutoloaders(array $autoloaders)
|
||||
{
|
||||
$this->_autoloaders = $autoloaders;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get attached autoloader implementations
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAutoloaders()
|
||||
{
|
||||
return $this->_autoloaders;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all autoloaders for a given namespace
|
||||
*
|
||||
* @param string $namespace
|
||||
* @return array
|
||||
*/
|
||||
public function getNamespaceAutoloaders($namespace)
|
||||
{
|
||||
$namespace = (string) $namespace;
|
||||
if (!array_key_exists($namespace, $this->_namespaceAutoloaders)) {
|
||||
return array();
|
||||
}
|
||||
return $this->_namespaceAutoloaders[$namespace];
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a namespace to autoload
|
||||
*
|
||||
* @param string|array $namespace
|
||||
* @return Postman_Zend_Loader_Autoloader
|
||||
*/
|
||||
public function registerNamespace($namespace)
|
||||
{
|
||||
if (is_string($namespace)) {
|
||||
$namespace = (array) $namespace;
|
||||
} elseif (!is_array($namespace)) {
|
||||
throw new Postman_Zend_Loader_Exception('Invalid namespace provided');
|
||||
}
|
||||
|
||||
foreach ($namespace as $ns) {
|
||||
if (!isset($this->_namespaces[$ns])) {
|
||||
$this->_namespaces[$ns] = true;
|
||||
}
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unload a registered autoload namespace
|
||||
*
|
||||
* @param string|array $namespace
|
||||
* @return Postman_Zend_Loader_Autoloader
|
||||
*/
|
||||
public function unregisterNamespace($namespace)
|
||||
{
|
||||
if (is_string($namespace)) {
|
||||
$namespace = (array) $namespace;
|
||||
} elseif (!is_array($namespace)) {
|
||||
throw new Postman_Zend_Loader_Exception('Invalid namespace provided');
|
||||
}
|
||||
|
||||
foreach ($namespace as $ns) {
|
||||
if (isset($this->_namespaces[$ns])) {
|
||||
unset($this->_namespaces[$ns]);
|
||||
}
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of registered autoload namespaces
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getRegisteredNamespaces()
|
||||
{
|
||||
return array_keys($this->_namespaces);
|
||||
}
|
||||
|
||||
public function setZfPath($spec, $version = 'latest')
|
||||
{
|
||||
$path = $spec;
|
||||
if (is_array($spec)) {
|
||||
if (!isset($spec['path'])) {
|
||||
throw new Postman_Zend_Loader_Exception('No path specified for ZF');
|
||||
}
|
||||
$path = $spec['path'];
|
||||
if (isset($spec['version'])) {
|
||||
$version = $spec['version'];
|
||||
}
|
||||
}
|
||||
|
||||
$this->_zfPath = $this->_getVersionPath($path, $version);
|
||||
set_include_path(implode(PATH_SEPARATOR, array(
|
||||
$this->_zfPath,
|
||||
get_include_path(),
|
||||
)));
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getZfPath()
|
||||
{
|
||||
return $this->_zfPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get or set the value of the "suppress not found warnings" flag
|
||||
*
|
||||
* @param null|bool $flag
|
||||
* @return bool|Postman_Zend_Loader_Autoloader Returns boolean if no argument is passed, object instance otherwise
|
||||
*/
|
||||
public function suppressNotFoundWarnings($flag = null)
|
||||
{
|
||||
if (null === $flag) {
|
||||
return $this->_suppressNotFoundWarnings;
|
||||
}
|
||||
$this->_suppressNotFoundWarnings = (bool) $flag;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate whether or not this autoloader should be a fallback autoloader
|
||||
*
|
||||
* @param bool $flag
|
||||
* @return Postman_Zend_Loader_Autoloader
|
||||
*/
|
||||
public function setFallbackAutoloader($flag)
|
||||
{
|
||||
$this->_fallbackAutoloader = (bool) $flag;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this instance acting as a fallback autoloader?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isFallbackAutoloader()
|
||||
{
|
||||
return $this->_fallbackAutoloader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get autoloaders to use when matching class
|
||||
*
|
||||
* Determines if the class matches a registered namespace, and, if so,
|
||||
* returns only the autoloaders for that namespace. Otherwise, it returns
|
||||
* all non-namespaced autoloaders.
|
||||
*
|
||||
* @param string $class
|
||||
* @return array Array of autoloaders to use
|
||||
*/
|
||||
public function getClassAutoloaders($class)
|
||||
{
|
||||
$namespace = false;
|
||||
$autoloaders = array();
|
||||
|
||||
// Add concrete namespaced autoloaders
|
||||
foreach (array_keys($this->_namespaceAutoloaders) as $ns) {
|
||||
if ('' == $ns) {
|
||||
continue;
|
||||
}
|
||||
if (0 === strpos($class, $ns)) {
|
||||
if ((false === $namespace) || (strlen($ns) > strlen($namespace))) {
|
||||
$namespace = $ns;
|
||||
$autoloaders = $this->getNamespaceAutoloaders($ns);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add internal namespaced autoloader
|
||||
foreach ($this->getRegisteredNamespaces() as $ns) {
|
||||
if (0 === strpos($class, $ns)) {
|
||||
$namespace = $ns;
|
||||
$autoloaders[] = $this->_internalAutoloader;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Add non-namespaced autoloaders
|
||||
$autoloadersNonNamespace = $this->getNamespaceAutoloaders('');
|
||||
if (count($autoloadersNonNamespace)) {
|
||||
foreach ($autoloadersNonNamespace as $ns) {
|
||||
$autoloaders[] = $ns;
|
||||
}
|
||||
unset($autoloadersNonNamespace);
|
||||
}
|
||||
|
||||
// Add fallback autoloader
|
||||
if (!$namespace && $this->isFallbackAutoloader()) {
|
||||
$autoloaders[] = $this->_internalAutoloader;
|
||||
}
|
||||
|
||||
return $autoloaders;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an autoloader to the beginning of the stack
|
||||
*
|
||||
* @param object|array|string $callback PHP callback or Postman_Zend_Loader_Autoloader_Interface implementation
|
||||
* @param string|array $namespace Specific namespace(s) under which to register callback
|
||||
* @return Postman_Zend_Loader_Autoloader
|
||||
*/
|
||||
public function unshiftAutoloader($callback, $namespace = '')
|
||||
{
|
||||
$autoloaders = $this->getAutoloaders();
|
||||
array_unshift($autoloaders, $callback);
|
||||
$this->setAutoloaders($autoloaders);
|
||||
|
||||
$namespace = (array) $namespace;
|
||||
foreach ($namespace as $ns) {
|
||||
$autoloaders = $this->getNamespaceAutoloaders($ns);
|
||||
array_unshift($autoloaders, $callback);
|
||||
$this->_setNamespaceAutoloaders($autoloaders, $ns);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append an autoloader to the autoloader stack
|
||||
*
|
||||
* @param object|array|string $callback PHP callback or Postman_Zend_Loader_Autoloader_Interface implementation
|
||||
* @param string|array $namespace Specific namespace(s) under which to register callback
|
||||
* @return Postman_Zend_Loader_Autoloader
|
||||
*/
|
||||
public function pushAutoloader($callback, $namespace = '')
|
||||
{
|
||||
$autoloaders = $this->getAutoloaders();
|
||||
array_push($autoloaders, $callback);
|
||||
$this->setAutoloaders($autoloaders);
|
||||
|
||||
$namespace = (array) $namespace;
|
||||
foreach ($namespace as $ns) {
|
||||
$autoloaders = $this->getNamespaceAutoloaders($ns);
|
||||
array_push($autoloaders, $callback);
|
||||
$this->_setNamespaceAutoloaders($autoloaders, $ns);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an autoloader from the autoloader stack
|
||||
*
|
||||
* @param object|array|string $callback PHP callback or Postman_Zend_Loader_Autoloader_Interface implementation
|
||||
* @param null|string|array $namespace Specific namespace(s) from which to remove autoloader
|
||||
* @return Postman_Zend_Loader_Autoloader
|
||||
*/
|
||||
public function removeAutoloader($callback, $namespace = null)
|
||||
{
|
||||
if (null === $namespace) {
|
||||
$autoloaders = $this->getAutoloaders();
|
||||
if (false !== ($index = array_search($callback, $autoloaders, true))) {
|
||||
unset($autoloaders[$index]);
|
||||
$this->setAutoloaders($autoloaders);
|
||||
}
|
||||
|
||||
foreach ($this->_namespaceAutoloaders as $ns => $autoloaders) {
|
||||
if (false !== ($index = array_search($callback, $autoloaders, true))) {
|
||||
unset($autoloaders[$index]);
|
||||
$this->_setNamespaceAutoloaders($autoloaders, $ns);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$namespace = (array) $namespace;
|
||||
foreach ($namespace as $ns) {
|
||||
$autoloaders = $this->getNamespaceAutoloaders($ns);
|
||||
if (false !== ($index = array_search($callback, $autoloaders, true))) {
|
||||
unset($autoloaders[$index]);
|
||||
$this->_setNamespaceAutoloaders($autoloaders, $ns);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* Registers instance with spl_autoload stack
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function __construct()
|
||||
{
|
||||
spl_autoload_register(array(__CLASS__, 'autoload'));
|
||||
$this->_internalAutoloader = array($this, '_autoload');
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal autoloader implementation
|
||||
*
|
||||
* @param string $class
|
||||
* @return bool
|
||||
*/
|
||||
protected function _autoload($class)
|
||||
{
|
||||
$callback = $this->getDefaultAutoloader();
|
||||
try {
|
||||
if ($this->suppressNotFoundWarnings()) {
|
||||
@call_user_func($callback, $class);
|
||||
} else {
|
||||
call_user_func($callback, $class);
|
||||
}
|
||||
return $class;
|
||||
} catch (Postman_Zend_Exception $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set autoloaders for a specific namespace
|
||||
*
|
||||
* @param array $autoloaders
|
||||
* @param string $namespace
|
||||
* @return Postman_Zend_Loader_Autoloader
|
||||
*/
|
||||
protected function _setNamespaceAutoloaders(array $autoloaders, $namespace = '')
|
||||
{
|
||||
$namespace = (string) $namespace;
|
||||
$this->_namespaceAutoloaders[$namespace] = $autoloaders;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the filesystem path for the requested ZF version
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $version
|
||||
* @return void
|
||||
*/
|
||||
protected function _getVersionPath($path, $version)
|
||||
{
|
||||
$type = $this->_getVersionType($version);
|
||||
|
||||
if ($type == 'latest') {
|
||||
$version = 'latest';
|
||||
}
|
||||
|
||||
$availableVersions = $this->_getAvailableVersions($path, $version);
|
||||
if (empty($availableVersions)) {
|
||||
throw new Postman_Zend_Loader_Exception('No valid ZF installations discovered');
|
||||
}
|
||||
|
||||
$matchedVersion = array_pop($availableVersions);
|
||||
return $matchedVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the ZF version type
|
||||
*
|
||||
* @param string $version
|
||||
* @return string "latest", "major", "minor", or "specific"
|
||||
* @throws Postman_Zend_Loader_Exception if version string contains too many dots
|
||||
*/
|
||||
protected function _getVersionType($version)
|
||||
{
|
||||
if (strtolower($version) == 'latest') {
|
||||
return 'latest';
|
||||
}
|
||||
|
||||
$parts = explode('.', $version);
|
||||
$count = count($parts);
|
||||
if (1 == $count) {
|
||||
return 'major';
|
||||
}
|
||||
if (2 == $count) {
|
||||
return 'minor';
|
||||
}
|
||||
if (3 < $count) {
|
||||
throw new Postman_Zend_Loader_Exception('Invalid version string provided');
|
||||
}
|
||||
return 'specific';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get available versions for the version type requested
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $version
|
||||
* @return array
|
||||
*/
|
||||
protected function _getAvailableVersions($path, $version)
|
||||
{
|
||||
if (!is_dir($path)) {
|
||||
throw new Postman_Zend_Loader_Exception('Invalid ZF path provided');
|
||||
}
|
||||
|
||||
$path = rtrim($path, '/');
|
||||
$path = rtrim($path, '\\');
|
||||
$versionLen = strlen($version);
|
||||
$versions = array();
|
||||
$dirs = glob("$path/*", GLOB_ONLYDIR);
|
||||
foreach ((array) $dirs as $dir) {
|
||||
$dirName = substr($dir, strlen($path) + 1);
|
||||
if (!preg_match('/^(?:ZendFramework-)?(\d+\.\d+\.\d+((a|b|pl|pr|p|rc)\d+)?)(?:-minimal)?$/i', $dirName, $matches)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$matchedVersion = $matches[1];
|
||||
|
||||
if (('latest' == $version)
|
||||
|| ((strlen($matchedVersion) >= $versionLen)
|
||||
&& (0 === strpos($matchedVersion, $version)))
|
||||
) {
|
||||
$versions[$matchedVersion] = $dir . '/library';
|
||||
}
|
||||
}
|
||||
|
||||
uksort($versions, 'version_compare');
|
||||
return $versions;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Exception
|
||||
*/
|
||||
// require_once 'Zend/Exception.php';
|
||||
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Mail_Exception extends Postman_Zend_Exception
|
||||
{}
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Postman_Zend_Mail_Part
|
||||
*/
|
||||
require_once 'Zend/Mail/Part.php';
|
||||
|
||||
/**
|
||||
* Postman_Zend_Mail_Message_Interface
|
||||
*/
|
||||
require_once 'Zend/Mail/Message/Interface.php';
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Mail_Message extends Postman_Zend_Mail_Part implements Postman_Zend_Mail_Message_Interface
|
||||
{
|
||||
/**
|
||||
* flags for this message
|
||||
* @var array
|
||||
*/
|
||||
protected $_flags = array();
|
||||
|
||||
/**
|
||||
* Public constructor
|
||||
*
|
||||
* In addition to the parameters of Postman_Zend_Mail_Part::__construct() this constructor supports:
|
||||
* - file filename or file handle of a file with raw message content
|
||||
* - flags array with flags for message, keys are ignored, use constants defined in Postman_Zend_Mail_Storage
|
||||
*
|
||||
* @param string $rawMessage full message with or without headers
|
||||
* @throws Postman_Zend_Mail_Exception
|
||||
*/
|
||||
public function __construct(array $params)
|
||||
{
|
||||
if (isset($params['file'])) {
|
||||
if (!is_resource($params['file'])) {
|
||||
$params['raw'] = @file_get_contents($params['file']);
|
||||
if ($params['raw'] === false) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Exception.php';
|
||||
throw new Postman_Zend_Mail_Exception('could not open file');
|
||||
}
|
||||
} else {
|
||||
$params['raw'] = stream_get_contents($params['file']);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($params['flags'])) {
|
||||
// set key and value to the same value for easy lookup
|
||||
$this->_flags = array_merge($this->_flags, array_combine($params['flags'],$params['flags']));
|
||||
}
|
||||
|
||||
parent::__construct($params);
|
||||
}
|
||||
|
||||
/**
|
||||
* return toplines as found after headers
|
||||
*
|
||||
* @return string toplines
|
||||
*/
|
||||
public function getTopLines()
|
||||
{
|
||||
return $this->_topLines;
|
||||
}
|
||||
|
||||
/**
|
||||
* check if flag is set
|
||||
*
|
||||
* @param mixed $flag a flag name, use constants defined in Postman_Zend_Mail_Storage
|
||||
* @return bool true if set, otherwise false
|
||||
*/
|
||||
public function hasFlag($flag)
|
||||
{
|
||||
return isset($this->_flags[$flag]);
|
||||
}
|
||||
|
||||
/**
|
||||
* get all set flags
|
||||
*
|
||||
* @return array array with flags, key and value are the same for easy lookup
|
||||
*/
|
||||
public function getFlags()
|
||||
{
|
||||
return $this->_flags;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Postman_Zend_Mail_Part
|
||||
*/
|
||||
require_once 'Zend/Mail/Part/File.php';
|
||||
|
||||
/**
|
||||
* Postman_Zend_Mail_Message_Interface
|
||||
*/
|
||||
require_once 'Zend/Mail/Message/Interface.php';
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Mail_Message_File extends Postman_Zend_Mail_Part_File implements Postman_Zend_Mail_Message_Interface
|
||||
{
|
||||
/**
|
||||
* flags for this message
|
||||
* @var array
|
||||
*/
|
||||
protected $_flags = array();
|
||||
|
||||
/**
|
||||
* Public constructor
|
||||
*
|
||||
* In addition to the parameters of Postman_Zend_Mail_Part::__construct() this constructor supports:
|
||||
* - flags array with flags for message, keys are ignored, use constants defined in Postman_Zend_Mail_Storage
|
||||
*
|
||||
* @param string $rawMessage full message with or without headers
|
||||
* @throws Postman_Zend_Mail_Exception
|
||||
*/
|
||||
public function __construct(array $params)
|
||||
{
|
||||
if (!empty($params['flags'])) {
|
||||
// set key and value to the same value for easy lookup
|
||||
$this->_flags = array_combine($params['flags'], $params['flags']);
|
||||
}
|
||||
|
||||
parent::__construct($params);
|
||||
}
|
||||
|
||||
/**
|
||||
* return toplines as found after headers
|
||||
*
|
||||
* @return string toplines
|
||||
*/
|
||||
public function getTopLines()
|
||||
{
|
||||
return $this->_topLines;
|
||||
}
|
||||
|
||||
/**
|
||||
* check if flag is set
|
||||
*
|
||||
* @param mixed $flag a flag name, use constants defined in Postman_Zend_Mail_Storage
|
||||
* @return bool true if set, otherwise false
|
||||
*/
|
||||
public function hasFlag($flag)
|
||||
{
|
||||
return isset($this->_flags[$flag]);
|
||||
}
|
||||
|
||||
/**
|
||||
* get all set flags
|
||||
*
|
||||
* @return array array with flags, key and value are the same for easy lookup
|
||||
*/
|
||||
public function getFlags()
|
||||
{
|
||||
return $this->_flags;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @subpackage Storage
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @subpackage Storage
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
interface Postman_Zend_Mail_Message_Interface
|
||||
{
|
||||
/**
|
||||
* return toplines as found after headers
|
||||
*
|
||||
* @return string toplines
|
||||
*/
|
||||
public function getTopLines();
|
||||
|
||||
/**
|
||||
* check if flag is set
|
||||
*
|
||||
* @param mixed $flag a flag name, use constants defined in Postman_Zend_Mail_Storage
|
||||
* @return bool true if set, otherwise false
|
||||
*/
|
||||
public function hasFlag($flag);
|
||||
|
||||
/**
|
||||
* get all set flags
|
||||
*
|
||||
* @return array array with flags, key and value are the same for easy lookup
|
||||
*/
|
||||
public function getFlags();
|
||||
}
|
||||
@@ -0,0 +1,198 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Mime_Decode
|
||||
*/
|
||||
require_once 'Zend/Mime/Decode.php';
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Part
|
||||
*/
|
||||
require_once 'Zend/Mail/Part.php';
|
||||
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Mail_Part_File extends Postman_Zend_Mail_Part
|
||||
{
|
||||
protected $_contentPos = array();
|
||||
protected $_partPos = array();
|
||||
protected $_fh;
|
||||
|
||||
/**
|
||||
* Public constructor
|
||||
*
|
||||
* This handler supports the following params:
|
||||
* - file filename or open file handler with message content (required)
|
||||
* - startPos start position of message or part in file (default: current position)
|
||||
* - endPos end position of message or part in file (default: end of file)
|
||||
*
|
||||
* @param array $params full message with or without headers
|
||||
* @throws Postman_Zend_Mail_Exception
|
||||
*/
|
||||
public function __construct(array $params)
|
||||
{
|
||||
if (empty($params['file'])) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Exception.php';
|
||||
throw new Postman_Zend_Mail_Exception('no file given in params');
|
||||
}
|
||||
|
||||
if (!is_resource($params['file'])) {
|
||||
$this->_fh = fopen($params['file'], 'r');
|
||||
} else {
|
||||
$this->_fh = $params['file'];
|
||||
}
|
||||
if (!$this->_fh) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Exception.php';
|
||||
throw new Postman_Zend_Mail_Exception('could not open file');
|
||||
}
|
||||
if (isset($params['startPos'])) {
|
||||
fseek($this->_fh, $params['startPos']);
|
||||
}
|
||||
$header = '';
|
||||
$endPos = isset($params['endPos']) ? $params['endPos'] : null;
|
||||
while (($endPos === null || ftell($this->_fh) < $endPos) && trim($line = fgets($this->_fh))) {
|
||||
$header .= $line;
|
||||
}
|
||||
|
||||
Postman_Zend_Mime_Decode::splitMessage($header, $this->_headers, $null);
|
||||
|
||||
$this->_contentPos[0] = ftell($this->_fh);
|
||||
if ($endPos !== null) {
|
||||
$this->_contentPos[1] = $endPos;
|
||||
} else {
|
||||
fseek($this->_fh, 0, SEEK_END);
|
||||
$this->_contentPos[1] = ftell($this->_fh);
|
||||
}
|
||||
if (!$this->isMultipart()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$boundary = $this->getHeaderField('content-type', 'boundary');
|
||||
if (!$boundary) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Exception.php';
|
||||
throw new Postman_Zend_Mail_Exception('no boundary found in content type to split message');
|
||||
}
|
||||
|
||||
$part = array();
|
||||
$pos = $this->_contentPos[0];
|
||||
fseek($this->_fh, $pos);
|
||||
while (!feof($this->_fh) && ($endPos === null || $pos < $endPos)) {
|
||||
$line = fgets($this->_fh);
|
||||
if ($line === false) {
|
||||
if (feof($this->_fh)) {
|
||||
break;
|
||||
}
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Exception.php';
|
||||
throw new Postman_Zend_Mail_Exception('error reading file');
|
||||
}
|
||||
|
||||
$lastPos = $pos;
|
||||
$pos = ftell($this->_fh);
|
||||
$line = trim($line);
|
||||
|
||||
if ($line == '--' . $boundary) {
|
||||
if ($part) {
|
||||
// not first part
|
||||
$part[1] = $lastPos;
|
||||
$this->_partPos[] = $part;
|
||||
}
|
||||
$part = array($pos);
|
||||
} else if ($line == '--' . $boundary . '--') {
|
||||
$part[1] = $lastPos;
|
||||
$this->_partPos[] = $part;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$this->_countParts = count($this->_partPos);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Body of part
|
||||
*
|
||||
* If part is multipart the raw content of this part with all sub parts is returned
|
||||
*
|
||||
* @return string body
|
||||
* @throws Postman_Zend_Mail_Exception
|
||||
*/
|
||||
public function getContent($stream = null)
|
||||
{
|
||||
fseek($this->_fh, $this->_contentPos[0]);
|
||||
if ($stream !== null) {
|
||||
return stream_copy_to_stream($this->_fh, $stream, $this->_contentPos[1] - $this->_contentPos[0]);
|
||||
}
|
||||
$length = $this->_contentPos[1] - $this->_contentPos[0];
|
||||
return $length < 1 ? '' : fread($this->_fh, $length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return size of part
|
||||
*
|
||||
* Quite simple implemented currently (not decoding). Handle with care.
|
||||
*
|
||||
* @return int size
|
||||
*/
|
||||
public function getSize() {
|
||||
return $this->_contentPos[1] - $this->_contentPos[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get part of multipart message
|
||||
*
|
||||
* @param int $num number of part starting with 1 for first part
|
||||
* @return Postman_Zend_Mail_Part wanted part
|
||||
* @throws Postman_Zend_Mail_Exception
|
||||
*/
|
||||
public function getPart($num)
|
||||
{
|
||||
--$num;
|
||||
if (!isset($this->_partPos[$num])) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Exception.php';
|
||||
throw new Postman_Zend_Mail_Exception('part not found');
|
||||
}
|
||||
|
||||
return new self(array('file' => $this->_fh, 'startPos' => $this->_partPos[$num][0],
|
||||
'endPos' => $this->_partPos[$num][1]));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @subpackage Storage
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @subpackage Storage
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
interface Postman_Zend_Mail_Part_Interface extends RecursiveIterator
|
||||
{
|
||||
/**
|
||||
* Check if part is a multipart message
|
||||
*
|
||||
* @return bool if part is multipart
|
||||
*/
|
||||
public function isMultipart();
|
||||
|
||||
|
||||
/**
|
||||
* Body of part
|
||||
*
|
||||
* If part is multipart the raw content of this part with all sub parts is returned
|
||||
*
|
||||
* @return string body
|
||||
* @throws Postman_Zend_Mail_Exception
|
||||
*/
|
||||
public function getContent();
|
||||
|
||||
/**
|
||||
* Return size of part
|
||||
*
|
||||
* @return int size
|
||||
*/
|
||||
public function getSize();
|
||||
|
||||
/**
|
||||
* Get part of multipart message
|
||||
*
|
||||
* @param int $num number of part starting with 1 for first part
|
||||
* @return Postman_Zend_Mail_Part wanted part
|
||||
* @throws Postman_Zend_Mail_Exception
|
||||
*/
|
||||
public function getPart($num);
|
||||
|
||||
/**
|
||||
* Count parts of a multipart part
|
||||
*
|
||||
* @return int number of sub-parts
|
||||
*/
|
||||
public function countParts();
|
||||
|
||||
|
||||
/**
|
||||
* Get all headers
|
||||
*
|
||||
* The returned headers are as saved internally. All names are lowercased. The value is a string or an array
|
||||
* if a header with the same name occurs more than once.
|
||||
*
|
||||
* @return array headers as array(name => value)
|
||||
*/
|
||||
public function getHeaders();
|
||||
|
||||
/**
|
||||
* Get a header in specificed format
|
||||
*
|
||||
* Internally headers that occur more than once are saved as array, all other as string. If $format
|
||||
* is set to string implode is used to concat the values (with Postman_Zend_Mime::LINEEND as delim).
|
||||
*
|
||||
* @param string $name name of header, matches case-insensitive, but camel-case is replaced with dashes
|
||||
* @param string $format change type of return value to 'string' or 'array'
|
||||
* @return string|array value of header in wanted or internal format
|
||||
* @throws Postman_Zend_Mail_Exception
|
||||
*/
|
||||
public function getHeader($name, $format = null);
|
||||
|
||||
/**
|
||||
* Get a specific field from a header like content type or all fields as array
|
||||
*
|
||||
* If the header occurs more than once, only the value from the first header
|
||||
* is returned.
|
||||
*
|
||||
* Throws a Postman_Zend_Mail_Exception if the requested header does not exist. If
|
||||
* the specific header field does not exist, returns null.
|
||||
*
|
||||
* @param string $name name of header, like in getHeader()
|
||||
* @param string $wantedPart the wanted part, default is first, if null an array with all parts is returned
|
||||
* @param string $firstName key name for the first part
|
||||
* @return string|array wanted part or all parts as array($firstName => firstPart, partname => value)
|
||||
* @throws Postman_Zend_Exception, Postman_Zend_Mail_Exception
|
||||
*/
|
||||
public function getHeaderField($name, $wantedPart = 0, $firstName = 0);
|
||||
|
||||
|
||||
/**
|
||||
* Getter for mail headers - name is matched in lowercase
|
||||
*
|
||||
* This getter is short for Postman_Zend_Mail_Part::getHeader($name, 'string')
|
||||
*
|
||||
* @see Postman_Zend_Mail_Part::getHeader()
|
||||
*
|
||||
* @param string $name header name
|
||||
* @return string value of header
|
||||
* @throws Postman_Zend_Mail_Exception
|
||||
*/
|
||||
public function __get($name);
|
||||
|
||||
/**
|
||||
* magic method to get content of part
|
||||
*
|
||||
* @return string content
|
||||
*/
|
||||
public function __toString();
|
||||
}
|
||||
@@ -0,0 +1,453 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @subpackage Protocol
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Validate
|
||||
*/
|
||||
// require_once 'Zend/Validate.php';
|
||||
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Validate_Hostname
|
||||
*/
|
||||
// require_once 'Zend/Validate/Hostname.php';
|
||||
|
||||
|
||||
/**
|
||||
* Postman_Zend_Mail_Protocol_Abstract
|
||||
*
|
||||
* Provides low-level methods for concrete adapters to communicate with a remote mail server and track requests and responses.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @subpackage Protocol
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
* @todo Implement proxy settings
|
||||
*/
|
||||
abstract class Postman_Zend_Mail_Protocol_Abstract
|
||||
{
|
||||
/**
|
||||
* Mail default EOL string
|
||||
*/
|
||||
const EOL = "\r\n";
|
||||
|
||||
|
||||
/**
|
||||
* Default timeout in seconds for initiating session
|
||||
*/
|
||||
const TIMEOUT_CONNECTION = 30;
|
||||
|
||||
/**
|
||||
* Maximum of the transaction log
|
||||
* @var integer
|
||||
*/
|
||||
protected $_maximumLog = 64;
|
||||
|
||||
|
||||
/**
|
||||
* Hostname or IP address of remote server
|
||||
* @var string
|
||||
*/
|
||||
protected $_host;
|
||||
|
||||
|
||||
/**
|
||||
* Port number of connection
|
||||
* @var integer
|
||||
*/
|
||||
protected $_port;
|
||||
|
||||
|
||||
/**
|
||||
* Instance of Postman_Zend_Validate to check hostnames
|
||||
* @var Postman_Zend_Validate
|
||||
*/
|
||||
protected $_validHost;
|
||||
|
||||
|
||||
/**
|
||||
* Socket connection resource
|
||||
* @var resource
|
||||
*/
|
||||
protected $_socket;
|
||||
|
||||
|
||||
/**
|
||||
* Last request sent to server
|
||||
* @var string
|
||||
*/
|
||||
protected $_request;
|
||||
|
||||
|
||||
/**
|
||||
* Array of server responses to last request
|
||||
* @var array
|
||||
*/
|
||||
protected $_response;
|
||||
|
||||
|
||||
/**
|
||||
* String template for parsing server responses using sscanf (default: 3 digit code and response string)
|
||||
* @var resource
|
||||
* @deprecated Since 1.10.3
|
||||
*/
|
||||
protected $_template = '%d%s';
|
||||
|
||||
|
||||
/**
|
||||
* Log of mail requests and server responses for a session
|
||||
* @var array
|
||||
*/
|
||||
private $_log = array();
|
||||
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $host OPTIONAL Hostname of remote connection (default: 127.0.0.1)
|
||||
* @param integer $port OPTIONAL Port number (default: null)
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($host = '127.0.0.1', $port = null)
|
||||
{
|
||||
$this->_validHost = new Postman_Zend_Validate();
|
||||
$this->_validHost->addValidator(new Postman_Zend_Validate_Hostname(Postman_Zend_Validate_Hostname::ALLOW_ALL));
|
||||
|
||||
if (!$this->_validHost->isValid($host)) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
// require_once 'Zend/Mail/Protocol/Exception.php';
|
||||
throw new Postman_Zend_Mail_Protocol_Exception(join(', ', $this->_validHost->getMessages()));
|
||||
}
|
||||
|
||||
$this->_host = $host;
|
||||
$this->_port = $port;
|
||||
$this->_maximumLog = PostmanOptions::getInstance()->getTranscriptSize();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Class destructor to cleanup open resources
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
$this->_disconnect();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the maximum log size
|
||||
*
|
||||
* @param integer $maximumLog Maximum log size
|
||||
* @return void
|
||||
*/
|
||||
public function setMaximumLog($maximumLog)
|
||||
{
|
||||
$this->_maximumLog = (int) $maximumLog;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the maximum log size
|
||||
*
|
||||
* @return int the maximum log size
|
||||
*/
|
||||
public function getMaximumLog()
|
||||
{
|
||||
return $this->_maximumLog;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a connection to the remote host
|
||||
*
|
||||
* Concrete adapters for this class will implement their own unique connect scripts, using the _connect() method to create the socket resource.
|
||||
*/
|
||||
abstract public function connect();
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve the last client request
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getRequest()
|
||||
{
|
||||
return $this->_request;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve the last server response
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getResponse()
|
||||
{
|
||||
return $this->_response;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve the transaction log
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLog()
|
||||
{
|
||||
return implode('', $this->_log);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reset the transaction log
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function resetLog()
|
||||
{
|
||||
$this->_log = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the transaction log
|
||||
*
|
||||
* @param string new transaction
|
||||
* @return void
|
||||
*/
|
||||
protected function _addLog($value)
|
||||
{
|
||||
if ($this->_maximumLog >= 0 && count($this->_log) >= $this->_maximumLog) {
|
||||
array_shift($this->_log);
|
||||
}
|
||||
|
||||
$this->_log[] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to the server using the supplied transport and target
|
||||
*
|
||||
* An example $remote string may be 'tcp://mail.example.com:25' or 'ssh://hostname.com:2222'
|
||||
*
|
||||
* @param string $remote Remote
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
* @return boolean
|
||||
*/
|
||||
protected function _connect($remote)
|
||||
{
|
||||
$errorNum = 0;
|
||||
$errorStr = '';
|
||||
|
||||
// open connection
|
||||
$this->_socket = @stream_socket_client($remote, $errorNum, $errorStr, self::TIMEOUT_CONNECTION);
|
||||
|
||||
if ($this->_socket === false) {
|
||||
if ($errorNum == 0) {
|
||||
$errorStr = 'Could not open socket';
|
||||
}
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
// require_once 'Zend/Mail/Protocol/Exception.php';
|
||||
throw new Postman_Zend_Mail_Protocol_Exception($errorStr);
|
||||
}
|
||||
|
||||
if (($result = $this->_setStreamTimeout(self::TIMEOUT_CONNECTION)) === false) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
// require_once 'Zend/Mail/Protocol/Exception.php';
|
||||
throw new Postman_Zend_Mail_Protocol_Exception('Could not set stream timeout');
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Disconnect from remote host and free resource
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function _disconnect()
|
||||
{
|
||||
if (is_resource($this->_socket)) {
|
||||
fclose($this->_socket);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Send the given request followed by a LINEEND to the server.
|
||||
*
|
||||
* @param string $request
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
* @return integer|boolean Number of bytes written to remote host
|
||||
*/
|
||||
protected function _send($request)
|
||||
{
|
||||
if (!is_resource($this->_socket)) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
// require_once 'Zend/Mail/Protocol/Exception.php';
|
||||
throw new Postman_Zend_Mail_Protocol_Exception('No connection has been established to ' . $this->_host);
|
||||
}
|
||||
|
||||
$this->_request = $request;
|
||||
|
||||
$result = fwrite($this->_socket, $request . self::EOL);
|
||||
|
||||
// Save request to internal log
|
||||
$this->_addLog($request . self::EOL);
|
||||
|
||||
if ($result === false) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
// require_once 'Zend/Mail/Protocol/Exception.php';
|
||||
throw new Postman_Zend_Mail_Protocol_Exception('Could not send request to ' . $this->_host);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a line from the stream.
|
||||
*
|
||||
* @var integer $timeout Per-request timeout value if applicable
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
* @return string
|
||||
*/
|
||||
protected function _receive($timeout = null)
|
||||
{
|
||||
if (!is_resource($this->_socket)) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
// require_once 'Zend/Mail/Protocol/Exception.php';
|
||||
throw new Postman_Zend_Mail_Protocol_Exception('No connection has been established to ' . $this->_host);
|
||||
}
|
||||
|
||||
// Adapters may wish to supply per-commend timeouts according to appropriate RFC
|
||||
if ($timeout !== null) {
|
||||
$this->_setStreamTimeout($timeout);
|
||||
}
|
||||
|
||||
// Retrieve response
|
||||
$reponse = fgets($this->_socket, 1024);
|
||||
|
||||
// Save request to internal log
|
||||
$this->_addLog($reponse);
|
||||
|
||||
// Check meta data to ensure connection is still valid
|
||||
$info = stream_get_meta_data($this->_socket);
|
||||
|
||||
if (!empty($info['timed_out'])) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
// require_once 'Zend/Mail/Protocol/Exception.php';
|
||||
throw new Postman_Zend_Mail_Protocol_Exception($this->_host . ' has timed out');
|
||||
}
|
||||
|
||||
if ($reponse === false) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
// require_once 'Zend/Mail/Protocol/Exception.php';
|
||||
throw new Postman_Zend_Mail_Protocol_Exception('Could not read from ' . $this->_host);
|
||||
}
|
||||
|
||||
return $reponse;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse server response for successful codes
|
||||
*
|
||||
* Read the response from the stream and check for expected return code.
|
||||
* Throws a Postman_Zend_Mail_Protocol_Exception if an unexpected code is returned.
|
||||
*
|
||||
* @param string|array $code One or more codes that indicate a successful response
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
* @return string Last line of response string
|
||||
*/
|
||||
protected function _expect($code, $timeout = null)
|
||||
{
|
||||
$userTimeout = PostmanOptions::getInstance()->getReadTimeout();
|
||||
if($timeout > $userTimeout) {
|
||||
$timeout = $userTimeout;
|
||||
}
|
||||
$this->_response = array();
|
||||
$cmd = '';
|
||||
$more = '';
|
||||
$msg = '';
|
||||
$errMsg = '';
|
||||
|
||||
if (!is_array($code)) {
|
||||
$code = array($code);
|
||||
}
|
||||
|
||||
do {
|
||||
$this->_response[] = $result = $this->_receive($timeout);
|
||||
list($cmd, $more, $msg) = preg_split('/([\s-]+)/', $result, 2, PREG_SPLIT_DELIM_CAPTURE);
|
||||
|
||||
if ($errMsg !== '') {
|
||||
$errMsg .= ' ' . $msg;
|
||||
} elseif ($cmd === null || !in_array($cmd, $code)) {
|
||||
$errMsg = $msg;
|
||||
}
|
||||
|
||||
} while (strpos($more, '-') === 0); // The '-' message prefix indicates an information string instead of a response string.
|
||||
|
||||
if ($errMsg !== '') {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
// require_once 'Zend/Mail/Protocol/Exception.php';
|
||||
throw new Postman_Zend_Mail_Protocol_Exception($errMsg, $cmd);
|
||||
}
|
||||
|
||||
return $msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set stream timeout
|
||||
*
|
||||
* @param integer $timeout
|
||||
* @return boolean
|
||||
*/
|
||||
protected function _setStreamTimeout($timeout)
|
||||
{
|
||||
// @jason: added @ to hide PHP warnings if the host has disabled stream_set_timeout
|
||||
return @stream_set_timeout($this->_socket, $timeout);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @subpackage Protocol
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Exception
|
||||
*/
|
||||
// require_once 'Zend/Mail/Exception.php';
|
||||
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @subpackage Protocol
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Mail_Protocol_Exception extends Postman_Zend_Mail_Exception
|
||||
{}
|
||||
|
||||
@@ -0,0 +1,838 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @subpackage Protocol
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @subpackage Protocol
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Mail_Protocol_Imap
|
||||
{
|
||||
/**
|
||||
* Default timeout in seconds for initiating session
|
||||
*/
|
||||
const TIMEOUT_CONNECTION = 30;
|
||||
|
||||
/**
|
||||
* socket to imap server
|
||||
* @var resource|null
|
||||
*/
|
||||
protected $_socket;
|
||||
|
||||
/**
|
||||
* counter for request tag
|
||||
* @var int
|
||||
*/
|
||||
protected $_tagCount = 0;
|
||||
|
||||
/**
|
||||
* Public constructor
|
||||
*
|
||||
* @param string $host hostname or IP address of IMAP server, if given connect() is called
|
||||
* @param int|null $port port of IMAP server, null for default (143 or 993 for ssl)
|
||||
* @param bool $ssl use ssl? 'SSL', 'TLS' or false
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
function __construct($host = '', $port = null, $ssl = false)
|
||||
{
|
||||
if ($host) {
|
||||
$this->connect($host, $port, $ssl);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Public destructor
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
$this->logout();
|
||||
}
|
||||
|
||||
/**
|
||||
* Open connection to IMAP server
|
||||
*
|
||||
* @param string $host hostname or IP address of IMAP server
|
||||
* @param int|null $port of IMAP server, default is 143 (993 for ssl)
|
||||
* @param string|bool $ssl use 'SSL', 'TLS' or false
|
||||
* @return string welcome message
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
public function connect($host, $port = null, $ssl = false)
|
||||
{
|
||||
if ($ssl == 'SSL') {
|
||||
$host = 'ssl://' . $host;
|
||||
}
|
||||
|
||||
if ($port === null) {
|
||||
$port = $ssl === 'SSL' ? 993 : 143;
|
||||
}
|
||||
|
||||
$errno = 0;
|
||||
$errstr = '';
|
||||
$this->_socket = @fsockopen($host, $port, $errno, $errstr, self::TIMEOUT_CONNECTION);
|
||||
if (!$this->_socket) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Protocol/Exception.php';
|
||||
throw new Postman_Zend_Mail_Protocol_Exception('cannot connect to host; error = ' . $errstr .
|
||||
' (errno = ' . $errno . ' )');
|
||||
}
|
||||
|
||||
if (!$this->_assumedNextLine('* OK')) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Protocol/Exception.php';
|
||||
throw new Postman_Zend_Mail_Protocol_Exception('host doesn\'t allow connection');
|
||||
}
|
||||
|
||||
if ($ssl === 'TLS') {
|
||||
$result = $this->requestAndResponse('STARTTLS');
|
||||
$result = $result && stream_socket_enable_crypto($this->_socket, true, STREAM_CRYPTO_METHOD_TLS_CLIENT);
|
||||
if (!$result) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Protocol/Exception.php';
|
||||
throw new Postman_Zend_Mail_Protocol_Exception('cannot enable TLS');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get the next line from socket with error checking, but nothing else
|
||||
*
|
||||
* @return string next line
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
protected function _nextLine()
|
||||
{
|
||||
$line = @fgets($this->_socket);
|
||||
if ($line === false) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Protocol/Exception.php';
|
||||
throw new Postman_Zend_Mail_Protocol_Exception('cannot read - connection closed?');
|
||||
}
|
||||
|
||||
return $line;
|
||||
}
|
||||
|
||||
/**
|
||||
* get next line and assume it starts with $start. some requests give a simple
|
||||
* feedback so we can quickly check if we can go on.
|
||||
*
|
||||
* @param string $start the first bytes we assume to be in the next line
|
||||
* @return bool line starts with $start
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
protected function _assumedNextLine($start)
|
||||
{
|
||||
$line = $this->_nextLine();
|
||||
return strpos($line, $start) === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* get next line and split the tag. that's the normal case for a response line
|
||||
*
|
||||
* @param string $tag tag of line is returned by reference
|
||||
* @return string next line
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
protected function _nextTaggedLine(&$tag)
|
||||
{
|
||||
$line = $this->_nextLine();
|
||||
|
||||
// seperate tag from line
|
||||
list($tag, $line) = explode(' ', $line, 2);
|
||||
|
||||
return $line;
|
||||
}
|
||||
|
||||
/**
|
||||
* split a given line in tokens. a token is literal of any form or a list
|
||||
*
|
||||
* @param string $line line to decode
|
||||
* @return array tokens, literals are returned as string, lists as array
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
protected function _decodeLine($line)
|
||||
{
|
||||
$tokens = array();
|
||||
$stack = array();
|
||||
|
||||
/*
|
||||
We start to decode the response here. The unterstood tokens are:
|
||||
literal
|
||||
"literal" or also "lit\\er\"al"
|
||||
{bytes}<NL>literal
|
||||
(literals*)
|
||||
All tokens are returned in an array. Literals in braces (the last unterstood
|
||||
token in the list) are returned as an array of tokens. I.e. the following response:
|
||||
"foo" baz {3}<NL>bar ("f\\\"oo" bar)
|
||||
would be returned as:
|
||||
array('foo', 'baz', 'bar', array('f\\\"oo', 'bar'));
|
||||
|
||||
// TODO: add handling of '[' and ']' to parser for easier handling of response text
|
||||
*/
|
||||
// replace any trailling <NL> including spaces with a single space
|
||||
$line = rtrim($line) . ' ';
|
||||
while (($pos = strpos($line, ' ')) !== false) {
|
||||
$token = substr($line, 0, $pos);
|
||||
while ($token[0] == '(') {
|
||||
array_push($stack, $tokens);
|
||||
$tokens = array();
|
||||
$token = substr($token, 1);
|
||||
}
|
||||
if ($token[0] == '"') {
|
||||
if (preg_match('%^\(*"((.|\\\\|\\")*?)" *%', $line, $matches)) {
|
||||
$tokens[] = $matches[1];
|
||||
$line = substr($line, strlen($matches[0]));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ($token[0] == '{') {
|
||||
$endPos = strpos($token, '}');
|
||||
$chars = substr($token, 1, $endPos - 1);
|
||||
if (is_numeric($chars)) {
|
||||
$token = '';
|
||||
while (strlen($token) < $chars) {
|
||||
$token .= $this->_nextLine();
|
||||
}
|
||||
$line = '';
|
||||
if (strlen($token) > $chars) {
|
||||
$line = substr($token, $chars);
|
||||
$token = substr($token, 0, $chars);
|
||||
} else {
|
||||
$line .= $this->_nextLine();
|
||||
}
|
||||
$tokens[] = $token;
|
||||
$line = trim($line) . ' ';
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ($stack && $token[strlen($token) - 1] == ')') {
|
||||
// closing braces are not seperated by spaces, so we need to count them
|
||||
$braces = strlen($token);
|
||||
$token = rtrim($token, ')');
|
||||
// only count braces if more than one
|
||||
$braces -= strlen($token) + 1;
|
||||
// only add if token had more than just closing braces
|
||||
if (rtrim($token) != '') {
|
||||
$tokens[] = rtrim($token);
|
||||
}
|
||||
$token = $tokens;
|
||||
$tokens = array_pop($stack);
|
||||
// special handline if more than one closing brace
|
||||
while ($braces-- > 0) {
|
||||
$tokens[] = $token;
|
||||
$token = $tokens;
|
||||
$tokens = array_pop($stack);
|
||||
}
|
||||
}
|
||||
$tokens[] = $token;
|
||||
$line = substr($line, $pos + 1);
|
||||
}
|
||||
|
||||
// maybe the server forgot to send some closing braces
|
||||
while ($stack) {
|
||||
$child = $tokens;
|
||||
$tokens = array_pop($stack);
|
||||
$tokens[] = $child;
|
||||
}
|
||||
|
||||
return $tokens;
|
||||
}
|
||||
|
||||
/**
|
||||
* read a response "line" (could also be more than one real line if response has {..}<NL>)
|
||||
* and do a simple decode
|
||||
*
|
||||
* @param array|string $tokens decoded tokens are returned by reference, if $dontParse
|
||||
* is true the unparsed line is returned here
|
||||
* @param string $wantedTag check for this tag for response code. Default '*' is
|
||||
* continuation tag.
|
||||
* @param bool $dontParse if true only the unparsed line is returned $tokens
|
||||
* @return bool if returned tag matches wanted tag
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
public function readLine(&$tokens = array(), $wantedTag = '*', $dontParse = false)
|
||||
{
|
||||
$line = $this->_nextTaggedLine($tag);
|
||||
if (!$dontParse) {
|
||||
$tokens = $this->_decodeLine($line);
|
||||
} else {
|
||||
$tokens = $line;
|
||||
}
|
||||
|
||||
// if tag is wanted tag we might be at the end of a multiline response
|
||||
return $tag == $wantedTag;
|
||||
}
|
||||
|
||||
/**
|
||||
* read all lines of response until given tag is found (last line of response)
|
||||
*
|
||||
* @param string $tag the tag of your request
|
||||
* @param string|array $filter you can filter the response so you get only the
|
||||
* given response lines
|
||||
* @param bool $dontParse if true every line is returned unparsed instead of
|
||||
* the decoded tokens
|
||||
* @return null|bool|array tokens if success, false if error, null if bad request
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
public function readResponse($tag, $dontParse = false)
|
||||
{
|
||||
$lines = array();
|
||||
while (!$this->readLine($tokens, $tag, $dontParse)) {
|
||||
$lines[] = $tokens;
|
||||
}
|
||||
|
||||
if ($dontParse) {
|
||||
// last to chars are still needed for response code
|
||||
$tokens = array(substr($tokens, 0, 2));
|
||||
}
|
||||
// last line has response code
|
||||
if ($tokens[0] == 'OK') {
|
||||
return $lines ? $lines : true;
|
||||
} else if ($tokens[0] == 'NO'){
|
||||
return false;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* send a request
|
||||
*
|
||||
* @param string $command your request command
|
||||
* @param array $tokens additional parameters to command, use escapeString() to prepare
|
||||
* @param string $tag provide a tag otherwise an autogenerated is returned
|
||||
* @return null
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
public function sendRequest($command, $tokens = array(), &$tag = null)
|
||||
{
|
||||
if (!$tag) {
|
||||
++$this->_tagCount;
|
||||
$tag = 'TAG' . $this->_tagCount;
|
||||
}
|
||||
|
||||
$line = $tag . ' ' . $command;
|
||||
|
||||
foreach ($tokens as $token) {
|
||||
if (is_array($token)) {
|
||||
if (@fputs($this->_socket, $line . ' ' . $token[0] . "\r\n") === false) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Protocol/Exception.php';
|
||||
throw new Postman_Zend_Mail_Protocol_Exception('cannot write - connection closed?');
|
||||
}
|
||||
if (!$this->_assumedNextLine('+ ')) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Protocol/Exception.php';
|
||||
throw new Postman_Zend_Mail_Protocol_Exception('cannot send literal string');
|
||||
}
|
||||
$line = $token[1];
|
||||
} else {
|
||||
$line .= ' ' . $token;
|
||||
}
|
||||
}
|
||||
|
||||
if (@fputs($this->_socket, $line . "\r\n") === false) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Protocol/Exception.php';
|
||||
throw new Postman_Zend_Mail_Protocol_Exception('cannot write - connection closed?');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* send a request and get response at once
|
||||
*
|
||||
* @param string $command command as in sendRequest()
|
||||
* @param array $tokens parameters as in sendRequest()
|
||||
* @param bool $dontParse if true unparsed lines are returned instead of tokens
|
||||
* @return mixed response as in readResponse()
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
public function requestAndResponse($command, $tokens = array(), $dontParse = false)
|
||||
{
|
||||
$this->sendRequest($command, $tokens, $tag);
|
||||
$response = $this->readResponse($tag, $dontParse);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* escape one or more literals i.e. for sendRequest
|
||||
*
|
||||
* @param string|array $string the literal/-s
|
||||
* @return string|array escape literals, literals with newline ar returned
|
||||
* as array('{size}', 'string');
|
||||
*/
|
||||
public function escapeString($string)
|
||||
{
|
||||
if (func_num_args() < 2) {
|
||||
if (strpos($string, "\n") !== false) {
|
||||
return array('{' . strlen($string) . '}', $string);
|
||||
} else {
|
||||
return '"' . str_replace(array('\\', '"'), array('\\\\', '\\"'), $string) . '"';
|
||||
}
|
||||
}
|
||||
$result = array();
|
||||
foreach (func_get_args() as $string) {
|
||||
$result[] = $this->escapeString($string);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* escape a list with literals or lists
|
||||
*
|
||||
* @param array $list list with literals or lists as PHP array
|
||||
* @return string escaped list for imap
|
||||
*/
|
||||
public function escapeList($list)
|
||||
{
|
||||
$result = array();
|
||||
foreach ($list as $k => $v) {
|
||||
if (!is_array($v)) {
|
||||
// $result[] = $this->escapeString($v);
|
||||
$result[] = $v;
|
||||
continue;
|
||||
}
|
||||
$result[] = $this->escapeList($v);
|
||||
}
|
||||
return '(' . implode(' ', $result) . ')';
|
||||
}
|
||||
|
||||
/**
|
||||
* Login to IMAP server.
|
||||
*
|
||||
* @param string $user username
|
||||
* @param string $password password
|
||||
* @return bool success
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
public function login($user, $password)
|
||||
{
|
||||
return $this->requestAndResponse('LOGIN', $this->escapeString($user, $password), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* logout of imap server
|
||||
*
|
||||
* @return bool success
|
||||
*/
|
||||
public function logout()
|
||||
{
|
||||
$result = false;
|
||||
if ($this->_socket) {
|
||||
try {
|
||||
$result = $this->requestAndResponse('LOGOUT', array(), true);
|
||||
} catch (Postman_Zend_Mail_Protocol_Exception $e) {
|
||||
// ignoring exception
|
||||
}
|
||||
fclose($this->_socket);
|
||||
$this->_socket = null;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get capabilities from IMAP server
|
||||
*
|
||||
* @return array list of capabilities
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
public function capability()
|
||||
{
|
||||
$response = $this->requestAndResponse('CAPABILITY');
|
||||
|
||||
if (!$response) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
$capabilities = array();
|
||||
foreach ($response as $line) {
|
||||
$capabilities = array_merge($capabilities, $line);
|
||||
}
|
||||
return $capabilities;
|
||||
}
|
||||
|
||||
/**
|
||||
* Examine and select have the same response. The common code for both
|
||||
* is in this method
|
||||
*
|
||||
* @param string $command can be 'EXAMINE' or 'SELECT' and this is used as command
|
||||
* @param string $box which folder to change to or examine
|
||||
* @return bool|array false if error, array with returned information
|
||||
* otherwise (flags, exists, recent, uidvalidity)
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
public function examineOrSelect($command = 'EXAMINE', $box = 'INBOX')
|
||||
{
|
||||
$this->sendRequest($command, array($this->escapeString($box)), $tag);
|
||||
|
||||
$result = array();
|
||||
while (!$this->readLine($tokens, $tag)) {
|
||||
if ($tokens[0] == 'FLAGS') {
|
||||
array_shift($tokens);
|
||||
$result['flags'] = $tokens;
|
||||
continue;
|
||||
}
|
||||
switch ($tokens[1]) {
|
||||
case 'EXISTS':
|
||||
case 'RECENT':
|
||||
$result[strtolower($tokens[1])] = $tokens[0];
|
||||
break;
|
||||
case '[UIDVALIDITY':
|
||||
$result['uidvalidity'] = (int)$tokens[2];
|
||||
break;
|
||||
default:
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
if ($tokens[0] != 'OK') {
|
||||
return false;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* change folder
|
||||
*
|
||||
* @param string $box change to this folder
|
||||
* @return bool|array see examineOrselect()
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
public function select($box = 'INBOX')
|
||||
{
|
||||
return $this->examineOrSelect('SELECT', $box);
|
||||
}
|
||||
|
||||
/**
|
||||
* examine folder
|
||||
*
|
||||
* @param string $box examine this folder
|
||||
* @return bool|array see examineOrselect()
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
public function examine($box = 'INBOX')
|
||||
{
|
||||
return $this->examineOrSelect('EXAMINE', $box);
|
||||
}
|
||||
|
||||
/**
|
||||
* fetch one or more items of one or more messages
|
||||
*
|
||||
* @param string|array $items items to fetch from message(s) as string (if only one item)
|
||||
* or array of strings
|
||||
* @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 avaible
|
||||
* @return string|array if only one item of one message is fetched it's returned as string
|
||||
* if items of one message are fetched it's returned as (name => value)
|
||||
* if one items of messages are fetched it's returned as (msgno => value)
|
||||
* if items of messages are fetchted it's returned as (msgno => (name => value))
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
public function fetch($items, $from, $to = null)
|
||||
{
|
||||
if (is_array($from)) {
|
||||
$set = implode(',', $from);
|
||||
} else if ($to === null) {
|
||||
$set = (int)$from;
|
||||
} else if ($to === INF) {
|
||||
$set = (int)$from . ':*';
|
||||
} else {
|
||||
$set = (int)$from . ':' . (int)$to;
|
||||
}
|
||||
|
||||
$items = (array)$items;
|
||||
$itemList = $this->escapeList($items);
|
||||
|
||||
$this->sendRequest('FETCH', array($set, $itemList), $tag);
|
||||
|
||||
$result = array();
|
||||
while (!$this->readLine($tokens, $tag)) {
|
||||
// ignore other responses
|
||||
if ($tokens[1] != 'FETCH') {
|
||||
continue;
|
||||
}
|
||||
// ignore other messages
|
||||
if ($to === null && !is_array($from) && $tokens[0] != $from) {
|
||||
continue;
|
||||
}
|
||||
// if we only want one item we return that one directly
|
||||
if (count($items) == 1) {
|
||||
if ($tokens[2][0] == $items[0]) {
|
||||
$data = $tokens[2][1];
|
||||
} else {
|
||||
// maybe the server send an other field we didn't wanted
|
||||
$count = count($tokens[2]);
|
||||
// we start with 2, because 0 was already checked
|
||||
for ($i = 2; $i < $count; $i += 2) {
|
||||
if ($tokens[2][$i] != $items[0]) {
|
||||
continue;
|
||||
}
|
||||
$data = $tokens[2][$i + 1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$data = array();
|
||||
while (key($tokens[2]) !== null) {
|
||||
$data[current($tokens[2])] = next($tokens[2]);
|
||||
next($tokens[2]);
|
||||
}
|
||||
}
|
||||
// if we want only one message we can ignore everything else and just return
|
||||
if ($to === null && !is_array($from) && $tokens[0] == $from) {
|
||||
// we still need to read all lines
|
||||
while (!$this->readLine($tokens, $tag));
|
||||
return $data;
|
||||
}
|
||||
$result[$tokens[0]] = $data;
|
||||
}
|
||||
|
||||
if ($to === null && !is_array($from)) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Protocol/Exception.php';
|
||||
throw new Postman_Zend_Mail_Protocol_Exception('the single id was not found in response');
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* get mailbox list
|
||||
*
|
||||
* this method can't be named after the IMAP command 'LIST', as list is a reserved keyword
|
||||
*
|
||||
* @param string $reference mailbox reference for list
|
||||
* @param string $mailbox mailbox name match with wildcards
|
||||
* @return array mailboxes that matched $mailbox as array(globalName => array('delim' => .., 'flags' => ..))
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
public function listMailbox($reference = '', $mailbox = '*')
|
||||
{
|
||||
$result = array();
|
||||
$list = $this->requestAndResponse('LIST', $this->escapeString($reference, $mailbox));
|
||||
if (!$list || $list === true) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
foreach ($list as $item) {
|
||||
if (count($item) != 4 || $item[0] != 'LIST') {
|
||||
continue;
|
||||
}
|
||||
$result[$item[3]] = array('delim' => $item[2], 'flags' => $item[1]);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* set 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 avaible
|
||||
* @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
|
||||
* @return bool|array new flags if $silent is false, else true or false depending on success
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
public function store(array $flags, $from, $to = null, $mode = null, $silent = true)
|
||||
{
|
||||
$item = 'FLAGS';
|
||||
if ($mode == '+' || $mode == '-') {
|
||||
$item = $mode . $item;
|
||||
}
|
||||
if ($silent) {
|
||||
$item .= '.SILENT';
|
||||
}
|
||||
|
||||
$flags = $this->escapeList($flags);
|
||||
$set = (int)$from;
|
||||
if ($to != null) {
|
||||
$set .= ':' . ($to == INF ? '*' : (int)$to);
|
||||
}
|
||||
|
||||
$result = $this->requestAndResponse('STORE', array($set, $item, $flags), $silent);
|
||||
|
||||
if ($silent) {
|
||||
return $result ? true : false;
|
||||
}
|
||||
|
||||
$tokens = $result;
|
||||
$result = array();
|
||||
foreach ($tokens as $token) {
|
||||
if ($token[1] != 'FETCH' || $token[2][0] != 'FLAGS') {
|
||||
continue;
|
||||
}
|
||||
$result[$token[0]] = $token[2][1];
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* append a new message to given folder
|
||||
*
|
||||
* @param string $folder name of target folder
|
||||
* @param string $message full message content
|
||||
* @param array $flags flags for new message
|
||||
* @param string $date date for new message
|
||||
* @return bool success
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
public function append($folder, $message, $flags = null, $date = null)
|
||||
{
|
||||
$tokens = array();
|
||||
$tokens[] = $this->escapeString($folder);
|
||||
if ($flags !== null) {
|
||||
$tokens[] = $this->escapeList($flags);
|
||||
}
|
||||
if ($date !== null) {
|
||||
$tokens[] = $this->escapeString($date);
|
||||
}
|
||||
$tokens[] = $this->escapeString($message);
|
||||
|
||||
return $this->requestAndResponse('APPEND', $tokens, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* copy message set from current folder to other folder
|
||||
*
|
||||
* @param string $folder destination folder
|
||||
* @param int|null $to if null only one message ($from) is fetched, else it's the
|
||||
* last message, INF means last message avaible
|
||||
* @return bool success
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
public function copy($folder, $from, $to = null)
|
||||
{
|
||||
$set = (int)$from;
|
||||
if ($to != null) {
|
||||
$set .= ':' . ($to == INF ? '*' : (int)$to);
|
||||
}
|
||||
|
||||
return $this->requestAndResponse('COPY', array($set, $this->escapeString($folder)), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* create a new folder (and parent folders if needed)
|
||||
*
|
||||
* @param string $folder folder name
|
||||
* @return bool success
|
||||
*/
|
||||
public function create($folder)
|
||||
{
|
||||
return $this->requestAndResponse('CREATE', array($this->escapeString($folder)), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* rename an existing folder
|
||||
*
|
||||
* @param string $old old name
|
||||
* @param string $new new name
|
||||
* @return bool success
|
||||
*/
|
||||
public function rename($old, $new)
|
||||
{
|
||||
return $this->requestAndResponse('RENAME', $this->escapeString($old, $new), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* remove a folder
|
||||
*
|
||||
* @param string $folder folder name
|
||||
* @return bool success
|
||||
*/
|
||||
public function delete($folder)
|
||||
{
|
||||
return $this->requestAndResponse('DELETE', array($this->escapeString($folder)), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* permanently remove messages
|
||||
*
|
||||
* @return bool success
|
||||
*/
|
||||
public function expunge()
|
||||
{
|
||||
// TODO: parse response?
|
||||
return $this->requestAndResponse('EXPUNGE');
|
||||
}
|
||||
|
||||
/**
|
||||
* send noop
|
||||
*
|
||||
* @return bool success
|
||||
*/
|
||||
public function noop()
|
||||
{
|
||||
// TODO: parse response
|
||||
return $this->requestAndResponse('NOOP');
|
||||
}
|
||||
|
||||
/**
|
||||
* do a search request
|
||||
*
|
||||
* This method is currently marked as internal as the API might change and is not
|
||||
* safe if you don't take precautions.
|
||||
*
|
||||
* @internal
|
||||
* @return array message ids
|
||||
*/
|
||||
public function search(array $params)
|
||||
{
|
||||
$response = $this->requestAndResponse('SEARCH', $params);
|
||||
if (!$response) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
foreach ($response as $ids) {
|
||||
if ($ids[0] == 'SEARCH') {
|
||||
array_shift($ids);
|
||||
return $ids;
|
||||
}
|
||||
}
|
||||
return array();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,472 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @subpackage Protocol
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @subpackage Protocol
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Mail_Protocol_Pop3
|
||||
{
|
||||
/**
|
||||
* Default timeout in seconds for initiating session
|
||||
*/
|
||||
const TIMEOUT_CONNECTION = 30;
|
||||
|
||||
/**
|
||||
* saves if server supports top
|
||||
* @var null|bool
|
||||
*/
|
||||
public $hasTop = null;
|
||||
|
||||
/**
|
||||
* socket to pop3
|
||||
* @var null|resource
|
||||
*/
|
||||
protected $_socket;
|
||||
|
||||
/**
|
||||
* greeting timestamp for apop
|
||||
* @var null|string
|
||||
*/
|
||||
protected $_timestamp;
|
||||
|
||||
|
||||
/**
|
||||
* Public constructor
|
||||
*
|
||||
* @param string $host hostname or IP address of POP3 server, if given connect() is called
|
||||
* @param int|null $port port of POP3 server, null for default (110 or 995 for ssl)
|
||||
* @param bool|string $ssl use ssl? 'SSL', 'TLS' or false
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
public function __construct($host = '', $port = null, $ssl = false)
|
||||
{
|
||||
if ($host) {
|
||||
$this->connect($host, $port, $ssl);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Public destructor
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
$this->logout();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Open connection to POP3 server
|
||||
*
|
||||
* @param string $host hostname or IP address of POP3 server
|
||||
* @param int|null $port of POP3 server, default is 110 (995 for ssl)
|
||||
* @param string|bool $ssl use 'SSL', 'TLS' or false
|
||||
* @return string welcome message
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
public function connect($host, $port = null, $ssl = false)
|
||||
{
|
||||
if ($ssl == 'SSL') {
|
||||
$host = 'ssl://' . $host;
|
||||
}
|
||||
|
||||
if ($port === null) {
|
||||
$port = $ssl == 'SSL' ? 995 : 110;
|
||||
}
|
||||
|
||||
$errno = 0;
|
||||
$errstr = '';
|
||||
$this->_socket = @fsockopen($host, $port, $errno, $errstr, self::TIMEOUT_CONNECTION);
|
||||
if (!$this->_socket) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Protocol/Exception.php';
|
||||
throw new Postman_Zend_Mail_Protocol_Exception('cannot connect to host; error = ' . $errstr .
|
||||
' (errno = ' . $errno . ' )');
|
||||
}
|
||||
|
||||
$welcome = $this->readResponse();
|
||||
|
||||
strtok($welcome, '<');
|
||||
$this->_timestamp = strtok('>');
|
||||
if (!strpos($this->_timestamp, '@')) {
|
||||
$this->_timestamp = null;
|
||||
} else {
|
||||
$this->_timestamp = '<' . $this->_timestamp . '>';
|
||||
}
|
||||
|
||||
if ($ssl === 'TLS') {
|
||||
$this->request('STLS');
|
||||
$result = stream_socket_enable_crypto($this->_socket, true, STREAM_CRYPTO_METHOD_TLS_CLIENT);
|
||||
if (!$result) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Protocol/Exception.php';
|
||||
throw new Postman_Zend_Mail_Protocol_Exception('cannot enable TLS');
|
||||
}
|
||||
}
|
||||
|
||||
return $welcome;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Send a request
|
||||
*
|
||||
* @param string $request your request without newline
|
||||
* @return null
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
public function sendRequest($request)
|
||||
{
|
||||
$result = @fputs($this->_socket, $request . "\r\n");
|
||||
if (!$result) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Protocol/Exception.php';
|
||||
throw new Postman_Zend_Mail_Protocol_Exception('send failed - connection closed?');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* read a response
|
||||
*
|
||||
* @param boolean $multiline response has multiple lines and should be read until "<nl>.<nl>"
|
||||
* @return string response
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
public function readResponse($multiline = false)
|
||||
{
|
||||
$result = @fgets($this->_socket);
|
||||
if (!is_string($result)) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Protocol/Exception.php';
|
||||
throw new Postman_Zend_Mail_Protocol_Exception('read failed - connection closed?');
|
||||
}
|
||||
|
||||
$result = trim($result);
|
||||
if (strpos($result, ' ')) {
|
||||
list($status, $message) = explode(' ', $result, 2);
|
||||
} else {
|
||||
$status = $result;
|
||||
$message = '';
|
||||
}
|
||||
|
||||
if ($status != '+OK') {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Protocol/Exception.php';
|
||||
throw new Postman_Zend_Mail_Protocol_Exception('last request failed');
|
||||
}
|
||||
|
||||
if ($multiline) {
|
||||
$message = '';
|
||||
$line = fgets($this->_socket);
|
||||
while ($line && rtrim($line, "\r\n") != '.') {
|
||||
if ($line[0] == '.') {
|
||||
$line = substr($line, 1);
|
||||
}
|
||||
$message .= $line;
|
||||
$line = fgets($this->_socket);
|
||||
};
|
||||
}
|
||||
|
||||
return $message;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Send request and get resposne
|
||||
*
|
||||
* @see sendRequest(), readResponse()
|
||||
*
|
||||
* @param string $request request
|
||||
* @param bool $multiline multiline response?
|
||||
* @return string result from readResponse()
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
public function request($request, $multiline = false)
|
||||
{
|
||||
$this->sendRequest($request);
|
||||
return $this->readResponse($multiline);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* End communication with POP3 server (also closes socket)
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public function logout()
|
||||
{
|
||||
if (!$this->_socket) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
$this->request('QUIT');
|
||||
} catch (Postman_Zend_Mail_Protocol_Exception $e) {
|
||||
// ignore error - we're closing the socket anyway
|
||||
}
|
||||
|
||||
fclose($this->_socket);
|
||||
$this->_socket = null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get capabilities from POP3 server
|
||||
*
|
||||
* @return array list of capabilities
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
public function capa()
|
||||
{
|
||||
$result = $this->request('CAPA', true);
|
||||
return explode("\n", $result);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Login to POP3 server. Can use APOP
|
||||
*
|
||||
* @param string $user username
|
||||
* @param string $password password
|
||||
* @param bool $try_apop should APOP be tried?
|
||||
* @return void
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
public function login($user, $password, $tryApop = true)
|
||||
{
|
||||
if ($tryApop && $this->_timestamp) {
|
||||
try {
|
||||
$this->request("APOP $user " . md5($this->_timestamp . $password));
|
||||
return;
|
||||
} catch (Postman_Zend_Mail_Protocol_Exception $e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
$result = $this->request("USER $user");
|
||||
$result = $this->request("PASS $password");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Make STAT call for message count and size sum
|
||||
*
|
||||
* @param int $messages out parameter with count of messages
|
||||
* @param int $octets out parameter with size in octects of messages
|
||||
* @return void
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
public function status(&$messages, &$octets)
|
||||
{
|
||||
$messages = 0;
|
||||
$octets = 0;
|
||||
$result = $this->request('STAT');
|
||||
|
||||
list($messages, $octets) = explode(' ', $result);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Make LIST call for size of message(s)
|
||||
*
|
||||
* @param int|null $msgno number of message, null for all
|
||||
* @return int|array size of given message or list with array(num => size)
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
public function getList($msgno = null)
|
||||
{
|
||||
if ($msgno !== null) {
|
||||
$result = $this->request("LIST $msgno");
|
||||
|
||||
list(, $result) = explode(' ', $result);
|
||||
return (int)$result;
|
||||
}
|
||||
|
||||
$result = $this->request('LIST', true);
|
||||
$messages = array();
|
||||
$line = strtok($result, "\n");
|
||||
while ($line) {
|
||||
list($no, $size) = explode(' ', trim($line));
|
||||
$messages[(int)$no] = (int)$size;
|
||||
$line = strtok("\n");
|
||||
}
|
||||
|
||||
return $messages;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Make UIDL call for getting a uniqueid
|
||||
*
|
||||
* @param int|null $msgno number of message, null for all
|
||||
* @return string|array uniqueid of message or list with array(num => uniqueid)
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
public function uniqueid($msgno = null)
|
||||
{
|
||||
if ($msgno !== null) {
|
||||
$result = $this->request("UIDL $msgno");
|
||||
|
||||
list(, $result) = explode(' ', $result);
|
||||
return $result;
|
||||
}
|
||||
|
||||
$result = $this->request('UIDL', true);
|
||||
|
||||
$result = explode("\n", $result);
|
||||
$messages = array();
|
||||
foreach ($result as $line) {
|
||||
if (!$line) {
|
||||
continue;
|
||||
}
|
||||
list($no, $id) = explode(' ', trim($line), 2);
|
||||
$messages[(int)$no] = $id;
|
||||
}
|
||||
|
||||
return $messages;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Make TOP call for getting headers and maybe some body lines
|
||||
* This method also sets hasTop - before it it's not known if top is supported
|
||||
*
|
||||
* The fallback makes normale RETR call, which retrieves the whole message. Additional
|
||||
* lines are not removed.
|
||||
*
|
||||
* @param int $msgno number of message
|
||||
* @param int $lines number of wanted body lines (empty line is inserted after header lines)
|
||||
* @param bool $fallback fallback with full retrieve if top is not supported
|
||||
* @return string message headers with wanted body lines
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
public function top($msgno, $lines = 0, $fallback = false)
|
||||
{
|
||||
if ($this->hasTop === false) {
|
||||
if ($fallback) {
|
||||
return $this->retrieve($msgno);
|
||||
} else {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Protocol/Exception.php';
|
||||
throw new Postman_Zend_Mail_Protocol_Exception('top not supported and no fallback wanted');
|
||||
}
|
||||
}
|
||||
$this->hasTop = true;
|
||||
|
||||
$lines = (!$lines || $lines < 1) ? 0 : (int)$lines;
|
||||
|
||||
try {
|
||||
$result = $this->request("TOP $msgno $lines", true);
|
||||
} catch (Postman_Zend_Mail_Protocol_Exception $e) {
|
||||
$this->hasTop = false;
|
||||
if ($fallback) {
|
||||
$result = $this->retrieve($msgno);
|
||||
} else {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Make a RETR call for retrieving a full message with headers and body
|
||||
*
|
||||
* @deprecated since 1.1.0; this method has a typo - please use retrieve()
|
||||
* @param int $msgno message number
|
||||
* @return string message
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
public function retrive($msgno)
|
||||
{
|
||||
return $this->retrieve($msgno);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Make a RETR call for retrieving a full message with headers and body
|
||||
*
|
||||
* @param int $msgno message number
|
||||
* @return string message
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
public function retrieve($msgno)
|
||||
{
|
||||
$result = $this->request("RETR $msgno", true);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a NOOP call, maybe needed for keeping the server happy
|
||||
*
|
||||
* @return null
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
public function noop()
|
||||
{
|
||||
$this->request('NOOP');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Make a DELE count to remove a message
|
||||
*
|
||||
* @return null
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
public function delete($msgno)
|
||||
{
|
||||
$this->request("DELE $msgno");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Make RSET call, which rollbacks delete requests
|
||||
*
|
||||
* @return null
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
public function undelete()
|
||||
{
|
||||
$this->request('RSET');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,467 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @subpackage Protocol
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Mime
|
||||
*/
|
||||
// require_once 'Zend/Mime.php';
|
||||
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Protocol_Abstract
|
||||
*/
|
||||
// require_once 'Zend/Mail/Protocol/Abstract.php';
|
||||
|
||||
|
||||
/**
|
||||
* Smtp implementation of Postman_Zend_Mail_Protocol_Abstract
|
||||
*
|
||||
* Minimum implementation according to RFC2821: EHLO, MAIL FROM, RCPT TO, DATA, RSET, NOOP, QUIT
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @subpackage Protocol
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Mail_Protocol_Smtp extends Postman_Zend_Mail_Protocol_Abstract
|
||||
{
|
||||
/**
|
||||
* The transport method for the socket
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_transport = 'tcp';
|
||||
|
||||
|
||||
/**
|
||||
* Indicates that a session is requested to be secure
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_secure;
|
||||
|
||||
|
||||
/**
|
||||
* Indicates an smtp session has been started by the HELO command
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
protected $_sess = false;
|
||||
|
||||
|
||||
/**
|
||||
* Indicates the HELO command has been issues
|
||||
*
|
||||
* @var unknown_type
|
||||
*/
|
||||
protected $_helo = false;
|
||||
|
||||
|
||||
/**
|
||||
* Indicates an smtp AUTH has been issued and authenticated
|
||||
*
|
||||
* @var unknown_type
|
||||
*/
|
||||
protected $_auth = false;
|
||||
|
||||
|
||||
/**
|
||||
* Indicates a MAIL command has been issued
|
||||
*
|
||||
* @var unknown_type
|
||||
*/
|
||||
protected $_mail = false;
|
||||
|
||||
|
||||
/**
|
||||
* Indicates one or more RCTP commands have been issued
|
||||
*
|
||||
* @var unknown_type
|
||||
*/
|
||||
protected $_rcpt = false;
|
||||
|
||||
|
||||
/**
|
||||
* Indicates that DATA has been issued and sent
|
||||
*
|
||||
* @var unknown_type
|
||||
*/
|
||||
protected $_data = null;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $host
|
||||
* @param integer $port
|
||||
* @param array $config
|
||||
* @return void
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
public function __construct($host = '127.0.0.1', $port = null, array $config = array())
|
||||
{
|
||||
if (isset($config['ssl'])) {
|
||||
switch (strtolower($config['ssl'])) {
|
||||
case 'tls':
|
||||
$this->_secure = 'tls';
|
||||
break;
|
||||
|
||||
case 'ssl':
|
||||
$this->_transport = 'ssl';
|
||||
$this->_secure = 'ssl';
|
||||
if ($port == null) {
|
||||
$port = 465;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
// require_once 'Zend/Mail/Protocol/Exception.php';
|
||||
throw new Postman_Zend_Mail_Protocol_Exception($config['ssl'] . ' is unsupported SSL type');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If no port has been specified then check the master PHP ini file. Defaults to 25 if the ini setting is null.
|
||||
if ($port == null) {
|
||||
if (($port = ini_get('smtp_port')) == '') {
|
||||
$port = 25;
|
||||
}
|
||||
}
|
||||
|
||||
parent::__construct($host, $port);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Connect to the server with the parameters given in the constructor.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function connect()
|
||||
{
|
||||
return $this->_connect($this->_transport . '://' . $this->_host . ':'. $this->_port);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initiate HELO/EHLO sequence and set flag to indicate valid smtp session
|
||||
*
|
||||
* @param string $host The client hostname or IP address (default: 127.0.0.1)
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
* @return void
|
||||
*/
|
||||
public function helo($host = '127.0.0.1')
|
||||
{
|
||||
// Respect RFC 2821 and disallow HELO attempts if session is already initiated.
|
||||
if ($this->_sess === true) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
// require_once 'Zend/Mail/Protocol/Exception.php';
|
||||
throw new Postman_Zend_Mail_Protocol_Exception('Cannot issue HELO to existing session');
|
||||
}
|
||||
|
||||
// Validate client hostname
|
||||
if (!$this->_validHost->isValid($host)) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
// require_once 'Zend/Mail/Protocol/Exception.php';
|
||||
throw new Postman_Zend_Mail_Protocol_Exception(join(', ', $this->_validHost->getMessages()));
|
||||
}
|
||||
|
||||
// Initiate helo sequence
|
||||
$this->_expect(220, 300); // Timeout set for 5 minutes as per RFC 2821 4.5.3.2
|
||||
$this->_ehlo($host);
|
||||
|
||||
// If a TLS session is required, commence negotiation
|
||||
if ($this->_secure == 'tls') {
|
||||
$this->_send('STARTTLS');
|
||||
$this->_expect(220, 180);
|
||||
|
||||
stream_context_set_option($this->_socket, 'ssl', 'verify_peer', false);
|
||||
stream_context_set_option($this->_socket, 'ssl', 'verify_peer_name', false);
|
||||
stream_context_set_option($this->_socket, 'ssl', 'allow_self_signed', true);
|
||||
|
||||
$crypto_method = STREAM_CRYPTO_METHOD_TLS_CLIENT;
|
||||
|
||||
$curl = curl_version();
|
||||
preg_match('/.*\/(\d*\.\d*\.\d*)[a-z]?/', $curl['ssl_version'], $ver_match );
|
||||
$tlsv1_2_installed = ! empty( $ver_match[1] ) ? $ver_match[1] >= '1.0.1' : true;
|
||||
|
||||
if ( $this->_host == 'smtp.office365.com' && ! $tlsv1_2_installed ) {
|
||||
|
||||
$error = sprintf( 'Office365 SMTP servie require TLS v1.2 and OpenSSL version 1.0.1 or greater, your current OpenSSL version is: %s.
|
||||
You need to contact your web hosting support for help.', $ver_match[1] );
|
||||
|
||||
throw new Postman_Zend_Mail_Protocol_Exception( $error );
|
||||
}
|
||||
|
||||
if ( defined('STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT') ) {
|
||||
$crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT;
|
||||
$crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT;
|
||||
}
|
||||
|
||||
if (!stream_socket_enable_crypto($this->_socket, true, $crypto_method)) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
// require_once 'Zend/Mail/Protocol/Exception.php';
|
||||
throw new Postman_Zend_Mail_Protocol_Exception('Unable to connect via TLS');
|
||||
}
|
||||
$this->_ehlo($host);
|
||||
}
|
||||
|
||||
$this->_startSession();
|
||||
$this->auth();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Send EHLO or HELO depending on capabilities of smtp host
|
||||
*
|
||||
* @param string $host The client hostname or IP address (default: 127.0.0.1)
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
* @return void
|
||||
*/
|
||||
protected function _ehlo($host)
|
||||
{
|
||||
// Support for older, less-compliant remote servers. Tries multiple attempts of EHLO or HELO.
|
||||
try {
|
||||
$this->_send('EHLO ' . $host);
|
||||
$this->_expect(250, 300); // Timeout set for 5 minutes as per RFC 2821 4.5.3.2
|
||||
} catch (Postman_Zend_Mail_Protocol_Exception $e) {
|
||||
$this->_send('HELO ' . $host);
|
||||
$this->_expect(250, 300); // Timeout set for 5 minutes as per RFC 2821 4.5.3.2
|
||||
} catch (Postman_Zend_Mail_Protocol_Exception $e) {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Issues MAIL command
|
||||
*
|
||||
* @param string $from Sender mailbox
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
* @return void
|
||||
*/
|
||||
public function mail($from)
|
||||
{
|
||||
if ($this->_sess !== true) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
// require_once 'Zend/Mail/Protocol/Exception.php';
|
||||
throw new Postman_Zend_Mail_Protocol_Exception('A valid session has not been started');
|
||||
}
|
||||
|
||||
$this->_send('MAIL FROM:<' . $from . '>');
|
||||
$this->_expect(250, 300); // Timeout set for 5 minutes as per RFC 2821 4.5.3.2
|
||||
|
||||
// Set mail to true, clear recipients and any existing data flags as per 4.1.1.2 of RFC 2821
|
||||
$this->_mail = true;
|
||||
$this->_rcpt = false;
|
||||
$this->_data = false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Issues RCPT command
|
||||
*
|
||||
* @param string $to Receiver(s) mailbox
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
* @return void
|
||||
*/
|
||||
public function rcpt($to)
|
||||
{
|
||||
if ($this->_mail !== true) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
// require_once 'Zend/Mail/Protocol/Exception.php';
|
||||
throw new Postman_Zend_Mail_Protocol_Exception('No sender reverse path has been supplied');
|
||||
}
|
||||
|
||||
// Set rcpt to true, as per 4.1.1.3 of RFC 2821
|
||||
$this->_send('RCPT TO:<' . $to . '>');
|
||||
$this->_expect(array(250, 251), 300); // Timeout set for 5 minutes as per RFC 2821 4.5.3.2
|
||||
$this->_rcpt = true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Issues DATA command
|
||||
*
|
||||
* @param string $data
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
* @return void
|
||||
*/
|
||||
public function data($data)
|
||||
{
|
||||
// Ensure recipients have been set
|
||||
if ($this->_rcpt !== true) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
// require_once 'Zend/Mail/Protocol/Exception.php';
|
||||
throw new Postman_Zend_Mail_Protocol_Exception('No recipient forward path has been supplied');
|
||||
}
|
||||
|
||||
$this->_send('DATA');
|
||||
$this->_expect(354, 120); // Timeout set for 2 minutes as per RFC 2821 4.5.3.2
|
||||
|
||||
foreach (explode(Postman_Zend_Mime::LINEEND, $data) as $line) {
|
||||
if (strpos($line, '.') === 0) {
|
||||
// Escape lines prefixed with a '.'
|
||||
$line = '.' . $line;
|
||||
}
|
||||
$this->_send($line);
|
||||
}
|
||||
|
||||
$this->_send('.');
|
||||
$this->_expect(250, 600); // Timeout set for 10 minutes as per RFC 2821 4.5.3.2
|
||||
$this->_data = true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Issues the RSET command and validates answer
|
||||
*
|
||||
* Can be used to restore a clean smtp communication state when a transaction has been cancelled or commencing a new transaction.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function rset()
|
||||
{
|
||||
$this->_send('RSET');
|
||||
// MS ESMTP doesn't follow RFC, see [ZF-1377]
|
||||
$this->_expect(array(250, 220));
|
||||
|
||||
$this->_mail = false;
|
||||
$this->_rcpt = false;
|
||||
$this->_data = false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Issues the NOOP command and validates answer
|
||||
*
|
||||
* Not used by Postman_Zend_Mail, could be used to keep a connection alive or check if it is still open.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function noop()
|
||||
{
|
||||
$this->_send('NOOP');
|
||||
$this->_expect(250, 300); // Timeout set for 5 minutes as per RFC 2821 4.5.3.2
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Issues the VRFY command and validates answer
|
||||
*
|
||||
* Not used by Postman_Zend_Mail.
|
||||
*
|
||||
* @param string $user User Name or eMail to verify
|
||||
* @return void
|
||||
*/
|
||||
public function vrfy($user)
|
||||
{
|
||||
$this->_send('VRFY ' . $user);
|
||||
$this->_expect(array(250, 251, 252), 300); // Timeout set for 5 minutes as per RFC 2821 4.5.3.2
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Issues the QUIT command and clears the current session
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function quit()
|
||||
{
|
||||
if ($this->_sess) {
|
||||
$this->_send('QUIT');
|
||||
$this->_expect(221, 300); // Timeout set for 5 minutes as per RFC 2821 4.5.3.2
|
||||
$this->_stopSession();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Default authentication method
|
||||
*
|
||||
* This default method is implemented by AUTH adapters to properly authenticate to a remote host.
|
||||
*
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
* @return void
|
||||
*/
|
||||
public function auth()
|
||||
{
|
||||
if ($this->_auth === true) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
// require_once 'Zend/Mail/Protocol/Exception.php';
|
||||
throw new Postman_Zend_Mail_Protocol_Exception('Already authenticated for this session');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Closes connection
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function disconnect()
|
||||
{
|
||||
$this->_disconnect();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Start mail session
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function _startSession()
|
||||
{
|
||||
$this->_sess = true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Stop mail session
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function _stopSession()
|
||||
{
|
||||
$this->_sess = false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @subpackage Protocol
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Protocol_Smtp
|
||||
*/
|
||||
// require_once 'Zend/Mail/Protocol/Smtp.php';
|
||||
|
||||
|
||||
/**
|
||||
* Performs CRAM-MD5 authentication
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @subpackage Protocol
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Mail_Protocol_Smtp_Auth_Crammd5 extends Postman_Zend_Mail_Protocol_Smtp
|
||||
{
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $host (Default: 127.0.0.1)
|
||||
* @param int $port (Default: null)
|
||||
* @param array $config Auth-specific parameters
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($host = '127.0.0.1', $port = null, $config = null)
|
||||
{
|
||||
if (is_array($config)) {
|
||||
if (isset($config['username'])) {
|
||||
$this->_username = $config['username'];
|
||||
}
|
||||
if (isset($config['password'])) {
|
||||
$this->_password = $config['password'];
|
||||
}
|
||||
}
|
||||
|
||||
parent::__construct($host, $port, $config);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @todo Perform CRAM-MD5 authentication with supplied credentials
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function auth()
|
||||
{
|
||||
// Ensure AUTH has not already been initiated.
|
||||
parent::auth();
|
||||
|
||||
$this->_send('AUTH CRAM-MD5');
|
||||
$challenge = $this->_expect(334);
|
||||
$challenge = base64_decode($challenge);
|
||||
$digest = $this->_hmacMd5($this->_password, $challenge);
|
||||
$this->_send(base64_encode($this->_username . ' ' . $digest));
|
||||
$this->_expect(235);
|
||||
$this->_auth = true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Prepare CRAM-MD5 response to server's ticket
|
||||
*
|
||||
* @param string $key Challenge key (usually password)
|
||||
* @param string $data Challenge data
|
||||
* @param string $block Length of blocks
|
||||
* @return string
|
||||
*/
|
||||
protected function _hmacMd5($key, $data, $block = 64)
|
||||
{
|
||||
if (strlen($key) > 64) {
|
||||
$key = pack('H32', md5($key));
|
||||
} elseif (strlen($key) < 64) {
|
||||
$key = str_pad($key, $block, "\0");
|
||||
}
|
||||
|
||||
$k_ipad = substr($key, 0, 64) ^ str_repeat(chr(0x36), 64);
|
||||
$k_opad = substr($key, 0, 64) ^ str_repeat(chr(0x5C), 64);
|
||||
|
||||
$inner = pack('H32', md5($k_ipad . $data));
|
||||
$digest = md5($k_opad . $inner);
|
||||
|
||||
return $digest;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @subpackage Protocol
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Protocol_Smtp
|
||||
*/
|
||||
// require_once 'Zend/Mail/Protocol/Smtp.php';
|
||||
|
||||
|
||||
/**
|
||||
* Performs LOGIN authentication
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @subpackage Protocol
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Mail_Protocol_Smtp_Auth_Login extends Postman_Zend_Mail_Protocol_Smtp
|
||||
{
|
||||
/**
|
||||
* LOGIN username
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_username;
|
||||
|
||||
|
||||
/**
|
||||
* LOGIN password
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_password;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $host (Default: 127.0.0.1)
|
||||
* @param int $port (Default: null)
|
||||
* @param array $config Auth-specific parameters
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($host = '127.0.0.1', $port = null, $config = null)
|
||||
{
|
||||
if (is_array($config)) {
|
||||
if (isset($config['username'])) {
|
||||
$this->_username = $config['username'];
|
||||
}
|
||||
if (isset($config['password'])) {
|
||||
$this->_password = $config['password'];
|
||||
}
|
||||
}
|
||||
|
||||
parent::__construct($host, $port, $config);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Perform LOGIN authentication with supplied credentials
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function auth()
|
||||
{
|
||||
// Ensure AUTH has not already been initiated.
|
||||
parent::auth();
|
||||
|
||||
$this->_send('AUTH LOGIN');
|
||||
$this->_expect(334);
|
||||
$this->_send(base64_encode($this->_username));
|
||||
$this->_expect(334);
|
||||
$this->_send(base64_encode($this->_password));
|
||||
$this->_expect(235);
|
||||
$this->_auth = true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @subpackage Protocol
|
||||
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id: Login.php 24593 2012-01-05 20:35:02Z matthew $
|
||||
*/
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Protocol_Smtp
|
||||
*/
|
||||
|
||||
/**
|
||||
* Performs Oauth2 authentication
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @subpackage Protocol
|
||||
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Mail_Protocol_Smtp_Auth_Oauth2 extends Postman_Zend_Mail_Protocol_Smtp
|
||||
{
|
||||
/**
|
||||
* LOGIN xoauth2 request
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_xoauth2_request;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $host (Default: 127.0.0.1)
|
||||
* @param int $port (Default: null)
|
||||
* @param array $config Auth-specific parameters
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($host = '127.0.0.1', $port = null, $config = null)
|
||||
{
|
||||
if (is_array($config)) {
|
||||
if (isset($config['xoauth2_request'])) {
|
||||
$this->_xoauth2_request = $config['xoauth2_request'];
|
||||
}
|
||||
}
|
||||
|
||||
parent::__construct($host, $port, $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform LOGIN authentication with supplied credentials
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function auth()
|
||||
{
|
||||
// Ensure AUTH has not already been initiated.
|
||||
parent::auth();
|
||||
|
||||
$this->_send('AUTH XOAUTH2 '.$this->_xoauth2_request);
|
||||
$this->_expect(235);
|
||||
$this->_auth = true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @subpackage Protocol
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Protocol_Smtp
|
||||
*/
|
||||
// require_once 'Zend/Mail/Protocol/Smtp.php';
|
||||
|
||||
|
||||
/**
|
||||
* Performs PLAIN authentication
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @subpackage Protocol
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Mail_Protocol_Smtp_Auth_Plain extends Postman_Zend_Mail_Protocol_Smtp
|
||||
{
|
||||
/**
|
||||
* PLAIN username
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_username;
|
||||
|
||||
|
||||
/**
|
||||
* PLAIN password
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_password;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $host (Default: 127.0.0.1)
|
||||
* @param int $port (Default: null)
|
||||
* @param array $config Auth-specific parameters
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($host = '127.0.0.1', $port = null, $config = null)
|
||||
{
|
||||
if (is_array($config)) {
|
||||
if (isset($config['username'])) {
|
||||
$this->_username = $config['username'];
|
||||
}
|
||||
if (isset($config['password'])) {
|
||||
$this->_password = $config['password'];
|
||||
}
|
||||
}
|
||||
|
||||
parent::__construct($host, $port, $config);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Perform PLAIN authentication with supplied credentials
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function auth()
|
||||
{
|
||||
// Ensure AUTH has not already been initiated.
|
||||
parent::auth();
|
||||
|
||||
$this->_send('AUTH PLAIN');
|
||||
$this->_expect(334);
|
||||
$this->_send(base64_encode("\0" . $this->_username . "\0" . $this->_password));
|
||||
$this->_expect(235);
|
||||
$this->_auth = true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Mail_Storage
|
||||
{
|
||||
// maildir and IMAP flags, using IMAP names, where possible to be able to distinguish between IMAP
|
||||
// system flags and other flags
|
||||
const FLAG_PASSED = 'Passed';
|
||||
const FLAG_SEEN = '\Seen';
|
||||
const FLAG_ANSWERED = '\Answered';
|
||||
const FLAG_FLAGGED = '\Flagged';
|
||||
const FLAG_DELETED = '\Deleted';
|
||||
const FLAG_DRAFT = '\Draft';
|
||||
const FLAG_RECENT = '\Recent';
|
||||
}
|
||||
@@ -0,0 +1,366 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @subpackage Storage
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @subpackage Storage
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
abstract class Postman_Zend_Mail_Storage_Abstract implements Countable, ArrayAccess, SeekableIterator
|
||||
{
|
||||
/**
|
||||
* class capabilities with default values
|
||||
* @var array
|
||||
*/
|
||||
protected $_has = array('uniqueid' => true,
|
||||
'delete' => false,
|
||||
'create' => false,
|
||||
'top' => false,
|
||||
'fetchPart' => true,
|
||||
'flags' => false);
|
||||
|
||||
/**
|
||||
* current iteration position
|
||||
* @var int
|
||||
*/
|
||||
protected $_iterationPos = 0;
|
||||
|
||||
/**
|
||||
* maximum iteration position (= message count)
|
||||
* @var null|int
|
||||
*/
|
||||
protected $_iterationMax = null;
|
||||
|
||||
/**
|
||||
* used message class, change it in an extened class to extend the returned message class
|
||||
* @var string
|
||||
*/
|
||||
protected $_messageClass = 'Postman_Zend_Mail_Message';
|
||||
|
||||
/**
|
||||
* Getter for has-properties. The standard has properties
|
||||
* are: hasFolder, hasUniqueid, hasDelete, hasCreate, hasTop
|
||||
*
|
||||
* The valid values for the has-properties are:
|
||||
* - true if a feature is supported
|
||||
* - false if a feature is not supported
|
||||
* - null is it's not yet known or it can't be know if a feature is supported
|
||||
*
|
||||
* @param string $var property name
|
||||
* @return bool supported or not
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
public function __get($var)
|
||||
{
|
||||
if (strpos($var, 'has') === 0) {
|
||||
$var = strtolower(substr($var, 3));
|
||||
return isset($this->_has[$var]) ? $this->_has[$var] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception($var . ' not found');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a full list of features supported by the specific mail lib and the server
|
||||
*
|
||||
* @return array list of features as array(featurename => true|false[|null])
|
||||
*/
|
||||
public function getCapabilities()
|
||||
{
|
||||
return $this->_has;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Count messages messages in current box/folder
|
||||
*
|
||||
* @return int number of messages
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
abstract public function countMessages();
|
||||
|
||||
|
||||
/**
|
||||
* Get a list of messages with number and size
|
||||
*
|
||||
* @param int $id number of message
|
||||
* @return int|array size of given message of list with all messages as array(num => size)
|
||||
*/
|
||||
abstract public function getSize($id = 0);
|
||||
|
||||
|
||||
/**
|
||||
* Get a message with headers and body
|
||||
*
|
||||
* @param int $id number of message
|
||||
* @return Postman_Zend_Mail_Message
|
||||
*/
|
||||
abstract public function getMessage($id);
|
||||
|
||||
|
||||
/**
|
||||
* Get raw header of message or part
|
||||
*
|
||||
* @param int $id number of message
|
||||
* @param null|array|string $part path to part or null for messsage header
|
||||
* @param int $topLines include this many lines with header (after an empty line)
|
||||
* @return string raw header
|
||||
*/
|
||||
abstract public function getRawHeader($id, $part = null, $topLines = 0);
|
||||
|
||||
/**
|
||||
* Get raw content of message or part
|
||||
*
|
||||
* @param int $id number of message
|
||||
* @param null|array|string $part path to part or null for messsage content
|
||||
* @return string raw content
|
||||
*/
|
||||
abstract public function getRawContent($id, $part = null);
|
||||
|
||||
/**
|
||||
* Create instance with parameters
|
||||
*
|
||||
* @param array $params mail reader specific parameters
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
abstract public function __construct($params);
|
||||
|
||||
|
||||
/**
|
||||
* Destructor calls close() and therefore closes the resource.
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
$this->close();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Close resource for mail lib. If you need to control, when the resource
|
||||
* is closed. Otherwise the destructor would call this.
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
abstract public function close();
|
||||
|
||||
|
||||
/**
|
||||
* Keep the resource alive.
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
abstract public function noop();
|
||||
|
||||
/**
|
||||
* delete a message from current box/folder
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
abstract public function removeMessage($id);
|
||||
|
||||
/**
|
||||
* get unique id for one or all messages
|
||||
*
|
||||
* if storage does not support unique ids it's the same as the message number
|
||||
*
|
||||
* @param int|null $id message number
|
||||
* @return array|string message number for given message or all messages as array
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
abstract public function getUniqueId($id = null);
|
||||
|
||||
/**
|
||||
* get a message number from a unique id
|
||||
*
|
||||
* I.e. if you have a webmailer that supports deleting messages you should use unique ids
|
||||
* as parameter and use this method to translate it to message number right before calling removeMessage()
|
||||
*
|
||||
* @param string $id unique id
|
||||
* @return int message number
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
abstract public function getNumberByUniqueId($id);
|
||||
|
||||
// interface implementations follows
|
||||
|
||||
/**
|
||||
* Countable::count()
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return $this->countMessages();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ArrayAccess::offsetExists()
|
||||
*
|
||||
* @param int $id
|
||||
* @return boolean
|
||||
*/
|
||||
public function offsetExists($id)
|
||||
{
|
||||
try {
|
||||
if ($this->getMessage($id)) {
|
||||
return true;
|
||||
}
|
||||
} catch(Postman_Zend_Mail_Storage_Exception $e) {}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ArrayAccess::offsetGet()
|
||||
*
|
||||
* @param int $id
|
||||
* @return Postman_Zend_Mail_Message message object
|
||||
*/
|
||||
public function offsetGet($id)
|
||||
{
|
||||
return $this->getMessage($id);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ArrayAccess::offsetSet()
|
||||
*
|
||||
* @param id $id
|
||||
* @param mixed $value
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
* @return void
|
||||
*/
|
||||
public function offsetSet($id, $value)
|
||||
{
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception('cannot write mail messages via array access');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ArrayAccess::offsetUnset()
|
||||
*
|
||||
* @param int $id
|
||||
* @return boolean success
|
||||
*/
|
||||
public function offsetUnset($id)
|
||||
{
|
||||
return $this->removeMessage($id);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Iterator::rewind()
|
||||
*
|
||||
* Rewind always gets the new count from the storage. Thus if you use
|
||||
* the interfaces and your scripts take long you should use reset()
|
||||
* from time to time.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function rewind()
|
||||
{
|
||||
$this->_iterationMax = $this->countMessages();
|
||||
$this->_iterationPos = 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Iterator::current()
|
||||
*
|
||||
* @return Postman_Zend_Mail_Message current message
|
||||
*/
|
||||
public function current()
|
||||
{
|
||||
return $this->getMessage($this->_iterationPos);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Iterator::key()
|
||||
*
|
||||
* @return int id of current position
|
||||
*/
|
||||
public function key()
|
||||
{
|
||||
return $this->_iterationPos;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Iterator::next()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function next()
|
||||
{
|
||||
++$this->_iterationPos;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Iterator::valid()
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function valid()
|
||||
{
|
||||
if ($this->_iterationMax === null) {
|
||||
$this->_iterationMax = $this->countMessages();
|
||||
}
|
||||
return $this->_iterationPos && $this->_iterationPos <= $this->_iterationMax;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* SeekableIterator::seek()
|
||||
*
|
||||
* @param int $pos
|
||||
* @return void
|
||||
* @throws OutOfBoundsException
|
||||
*/
|
||||
public function seek($pos)
|
||||
{
|
||||
if ($this->_iterationMax === null) {
|
||||
$this->_iterationMax = $this->countMessages();
|
||||
}
|
||||
|
||||
if ($pos > $this->_iterationMax) {
|
||||
throw new OutOfBoundsException('this position does not exist');
|
||||
}
|
||||
$this->_iterationPos = $pos;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @subpackage Storage
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Exception.php';
|
||||
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @subpackage Storage
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Mail_Storage_Exception extends Postman_Zend_Mail_Exception
|
||||
{}
|
||||
|
||||
@@ -0,0 +1,236 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @subpackage Storage
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @subpackage Storage
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Mail_Storage_Folder implements RecursiveIterator
|
||||
{
|
||||
/**
|
||||
* subfolders of folder array(localName => Postman_Zend_Mail_Storage_Folder folder)
|
||||
* @var array
|
||||
*/
|
||||
protected $_folders;
|
||||
|
||||
/**
|
||||
* local name (name of folder in parent folder)
|
||||
* @var string
|
||||
*/
|
||||
protected $_localName;
|
||||
|
||||
/**
|
||||
* global name (absolute name of folder)
|
||||
* @var string
|
||||
*/
|
||||
protected $_globalName;
|
||||
|
||||
/**
|
||||
* folder is selectable if folder is able to hold messages, else it's just a parent folder
|
||||
* @var bool
|
||||
*/
|
||||
protected $_selectable = true;
|
||||
|
||||
/**
|
||||
* create a new mail folder instance
|
||||
*
|
||||
* @param string $localName name of folder in current subdirectory
|
||||
* @param string $globalName absolute name of folder
|
||||
* @param bool $selectable if true folder holds messages, if false it's just a parent for subfolders
|
||||
* @param array $folders init with given instances of Postman_Zend_Mail_Storage_Folder as subfolders
|
||||
*/
|
||||
public function __construct($localName, $globalName = '', $selectable = true, array $folders = array())
|
||||
{
|
||||
$this->_localName = $localName;
|
||||
$this->_globalName = $globalName ? $globalName : $localName;
|
||||
$this->_selectable = $selectable;
|
||||
$this->_folders = $folders;
|
||||
}
|
||||
|
||||
/**
|
||||
* implements RecursiveIterator::hasChildren()
|
||||
*
|
||||
* @return bool current element has children
|
||||
*/
|
||||
public function hasChildren()
|
||||
{
|
||||
$current = $this->current();
|
||||
return $current && $current instanceof Postman_Zend_Mail_Storage_Folder && !$current->isLeaf();
|
||||
}
|
||||
|
||||
/**
|
||||
* implements RecursiveIterator::getChildren()
|
||||
*
|
||||
* @return Postman_Zend_Mail_Storage_Folder same as self::current()
|
||||
*/
|
||||
public function getChildren()
|
||||
{
|
||||
return $this->current();
|
||||
}
|
||||
|
||||
/**
|
||||
* implements Iterator::valid()
|
||||
*
|
||||
* @return bool check if there's a current element
|
||||
*/
|
||||
public function valid()
|
||||
{
|
||||
return key($this->_folders) !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* implements Iterator::next()
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public function next()
|
||||
{
|
||||
next($this->_folders);
|
||||
}
|
||||
|
||||
/**
|
||||
* implements Iterator::key()
|
||||
*
|
||||
* @return string key/local name of current element
|
||||
*/
|
||||
public function key()
|
||||
{
|
||||
return key($this->_folders);
|
||||
}
|
||||
|
||||
/**
|
||||
* implements Iterator::current()
|
||||
*
|
||||
* @return Postman_Zend_Mail_Storage_Folder current folder
|
||||
*/
|
||||
public function current()
|
||||
{
|
||||
return current($this->_folders);
|
||||
}
|
||||
|
||||
/**
|
||||
* implements Iterator::rewind()
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public function rewind()
|
||||
{
|
||||
reset($this->_folders);
|
||||
}
|
||||
|
||||
/**
|
||||
* get subfolder named $name
|
||||
*
|
||||
* @param string $name wanted subfolder
|
||||
* @return Postman_Zend_Mail_Storage_Folder folder named $folder
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
if (!isset($this->_folders[$name])) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception("no subfolder named $name");
|
||||
}
|
||||
|
||||
return $this->_folders[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* add or replace subfolder named $name
|
||||
*
|
||||
* @param string $name local name of subfolder
|
||||
* @param Postman_Zend_Mail_Storage_Folder $folder instance for new subfolder
|
||||
* @return null
|
||||
*/
|
||||
public function __set($name, Postman_Zend_Mail_Storage_Folder $folder)
|
||||
{
|
||||
$this->_folders[$name] = $folder;
|
||||
}
|
||||
|
||||
/**
|
||||
* remove subfolder named $name
|
||||
*
|
||||
* @param string $name local name of subfolder
|
||||
* @return null
|
||||
*/
|
||||
public function __unset($name)
|
||||
{
|
||||
unset($this->_folders[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* magic method for easy output of global name
|
||||
*
|
||||
* @return string global name of folder
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return (string)$this->getGlobalName();
|
||||
}
|
||||
|
||||
/**
|
||||
* get local name
|
||||
*
|
||||
* @return string local name
|
||||
*/
|
||||
public function getLocalName()
|
||||
{
|
||||
return $this->_localName;
|
||||
}
|
||||
|
||||
/**
|
||||
* get global name
|
||||
*
|
||||
* @return string global name
|
||||
*/
|
||||
public function getGlobalName()
|
||||
{
|
||||
return $this->_globalName;
|
||||
}
|
||||
|
||||
/**
|
||||
* is this folder selectable?
|
||||
*
|
||||
* @return bool selectable
|
||||
*/
|
||||
public function isSelectable()
|
||||
{
|
||||
return $this->_selectable;
|
||||
}
|
||||
|
||||
/**
|
||||
* check if folder has no subfolder
|
||||
*
|
||||
* @return bool true if no subfolders
|
||||
*/
|
||||
public function isLeaf()
|
||||
{
|
||||
return empty($this->_folders);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @subpackage Storage
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @subpackage Storage
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
interface Postman_Zend_Mail_Storage_Folder_Interface
|
||||
{
|
||||
/**
|
||||
* get root folder or given folder
|
||||
*
|
||||
* @param string $rootFolder get folder structure for given folder, else root
|
||||
* @return Postman_Zend_Mail_Storage_Folder root or wanted folder
|
||||
*/
|
||||
public function getFolders($rootFolder = null);
|
||||
|
||||
/**
|
||||
* select given folder
|
||||
*
|
||||
* folder must be selectable!
|
||||
*
|
||||
* @param Postman_Zend_Mail_Storage_Folder|string $globalName global name of folder or instance for subfolder
|
||||
* @return null
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
public function selectFolder($globalName);
|
||||
|
||||
|
||||
/**
|
||||
* get Postman_Zend_Mail_Storage_Folder instance for current folder
|
||||
*
|
||||
* @return Postman_Zend_Mail_Storage_Folder instance of current folder
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
public function getCurrentFolder();
|
||||
}
|
||||
@@ -0,0 +1,265 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @subpackage Storage
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Folder
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Folder.php';
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Folder_Interface
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Folder/Interface.php';
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Maildir
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Maildir.php';
|
||||
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @subpackage Storage
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Mail_Storage_Folder_Maildir extends Postman_Zend_Mail_Storage_Maildir implements Postman_Zend_Mail_Storage_Folder_Interface
|
||||
{
|
||||
/**
|
||||
* Postman_Zend_Mail_Storage_Folder root folder for folder structure
|
||||
* @var Postman_Zend_Mail_Storage_Folder
|
||||
*/
|
||||
protected $_rootFolder;
|
||||
|
||||
/**
|
||||
* rootdir of folder structure
|
||||
* @var string
|
||||
*/
|
||||
protected $_rootdir;
|
||||
|
||||
/**
|
||||
* name of current folder
|
||||
* @var string
|
||||
*/
|
||||
protected $_currentFolder;
|
||||
|
||||
/**
|
||||
* delim char for subfolders
|
||||
* @var string
|
||||
*/
|
||||
protected $_delim;
|
||||
|
||||
/**
|
||||
* Create instance with parameters
|
||||
* Supported parameters are:
|
||||
* - dirname rootdir of maildir structure
|
||||
* - delim delim char for folder structur, default is '.'
|
||||
* - folder intial selected folder, default is 'INBOX'
|
||||
*
|
||||
* @param array $params mail reader specific parameters
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
public function __construct($params)
|
||||
{
|
||||
if (is_array($params)) {
|
||||
$params = (object)$params;
|
||||
}
|
||||
|
||||
if (!isset($params->dirname) || !is_dir($params->dirname)) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception('no valid dirname given in params');
|
||||
}
|
||||
|
||||
$this->_rootdir = rtrim($params->dirname, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
|
||||
|
||||
$this->_delim = isset($params->delim) ? $params->delim : '.';
|
||||
|
||||
$this->_buildFolderTree();
|
||||
$this->selectFolder(!empty($params->folder) ? $params->folder : 'INBOX');
|
||||
$this->_has['top'] = true;
|
||||
$this->_has['flags'] = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* find all subfolders and mbox files for folder structure
|
||||
*
|
||||
* Result is save in Postman_Zend_Mail_Storage_Folder instances with the root in $this->_rootFolder.
|
||||
* $parentFolder and $parentGlobalName are only used internally for recursion.
|
||||
*
|
||||
* @return null
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
protected function _buildFolderTree()
|
||||
{
|
||||
$this->_rootFolder = new Postman_Zend_Mail_Storage_Folder('/', '/', false);
|
||||
$this->_rootFolder->INBOX = new Postman_Zend_Mail_Storage_Folder('INBOX', 'INBOX', true);
|
||||
|
||||
$dh = @opendir($this->_rootdir);
|
||||
if (!$dh) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception("can't read folders in maildir");
|
||||
}
|
||||
$dirs = array();
|
||||
while (($entry = readdir($dh)) !== false) {
|
||||
// maildir++ defines folders must start with .
|
||||
if ($entry[0] != '.' || $entry == '.' || $entry == '..') {
|
||||
continue;
|
||||
}
|
||||
if ($this->_isMaildir($this->_rootdir . $entry)) {
|
||||
$dirs[] = $entry;
|
||||
}
|
||||
}
|
||||
closedir($dh);
|
||||
|
||||
sort($dirs);
|
||||
$stack = array(null);
|
||||
$folderStack = array(null);
|
||||
$parentFolder = $this->_rootFolder;
|
||||
$parent = '.';
|
||||
|
||||
foreach ($dirs as $dir) {
|
||||
do {
|
||||
if (strpos($dir, $parent) === 0) {
|
||||
$local = substr($dir, strlen($parent));
|
||||
if (strpos($local, $this->_delim) !== false) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception('error while reading maildir');
|
||||
}
|
||||
array_push($stack, $parent);
|
||||
$parent = $dir . $this->_delim;
|
||||
$folder = new Postman_Zend_Mail_Storage_Folder($local, substr($dir, 1), true);
|
||||
$parentFolder->$local = $folder;
|
||||
array_push($folderStack, $parentFolder);
|
||||
$parentFolder = $folder;
|
||||
break;
|
||||
} else if ($stack) {
|
||||
$parent = array_pop($stack);
|
||||
$parentFolder = array_pop($folderStack);
|
||||
}
|
||||
} while ($stack);
|
||||
if (!$stack) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception('error while reading maildir');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get root folder or given folder
|
||||
*
|
||||
* @param string $rootFolder get folder structure for given folder, else root
|
||||
* @return Postman_Zend_Mail_Storage_Folder root or wanted folder
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
public function getFolders($rootFolder = null)
|
||||
{
|
||||
if (!$rootFolder || $rootFolder == 'INBOX') {
|
||||
return $this->_rootFolder;
|
||||
}
|
||||
|
||||
// rootdir is same as INBOX in maildir
|
||||
if (strpos($rootFolder, 'INBOX' . $this->_delim) === 0) {
|
||||
$rootFolder = substr($rootFolder, 6);
|
||||
}
|
||||
$currentFolder = $this->_rootFolder;
|
||||
$subname = trim($rootFolder, $this->_delim);
|
||||
while ($currentFolder) {
|
||||
@list($entry, $subname) = @explode($this->_delim, $subname, 2);
|
||||
$currentFolder = $currentFolder->$entry;
|
||||
if (!$subname) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($currentFolder->getGlobalName() != rtrim($rootFolder, $this->_delim)) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception("folder $rootFolder not found");
|
||||
}
|
||||
return $currentFolder;
|
||||
}
|
||||
|
||||
/**
|
||||
* select given folder
|
||||
*
|
||||
* folder must be selectable!
|
||||
*
|
||||
* @param Postman_Zend_Mail_Storage_Folder|string $globalName global name of folder or instance for subfolder
|
||||
* @return null
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
public function selectFolder($globalName)
|
||||
{
|
||||
$this->_currentFolder = (string)$globalName;
|
||||
|
||||
// getting folder from folder tree for validation
|
||||
$folder = $this->getFolders($this->_currentFolder);
|
||||
|
||||
try {
|
||||
$this->_openMaildir($this->_rootdir . '.' . $folder->getGlobalName());
|
||||
} catch(Postman_Zend_Mail_Storage_Exception $e) {
|
||||
// check what went wrong
|
||||
if (!$folder->isSelectable()) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception("{$this->_currentFolder} is not selectable", 0, $e);
|
||||
}
|
||||
// seems like file has vanished; rebuilding folder tree - but it's still an exception
|
||||
$this->_buildFolderTree($this->_rootdir);
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception('seems like the maildir has vanished, I\'ve rebuild the ' .
|
||||
'folder tree, search for an other folder and try again', 0, $e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get Postman_Zend_Mail_Storage_Folder instance for current folder
|
||||
*
|
||||
* @return Postman_Zend_Mail_Storage_Folder instance of current folder
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
public function getCurrentFolder()
|
||||
{
|
||||
return $this->_currentFolder;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,264 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @subpackage Storage
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Folder
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Folder.php';
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Folder_Interface
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Folder/Interface.php';
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Mbox
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Mbox.php';
|
||||
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @subpackage Storage
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Mail_Storage_Folder_Mbox extends Postman_Zend_Mail_Storage_Mbox implements Postman_Zend_Mail_Storage_Folder_Interface
|
||||
{
|
||||
/**
|
||||
* Postman_Zend_Mail_Storage_Folder root folder for folder structure
|
||||
* @var Postman_Zend_Mail_Storage_Folder
|
||||
*/
|
||||
protected $_rootFolder;
|
||||
|
||||
/**
|
||||
* rootdir of folder structure
|
||||
* @var string
|
||||
*/
|
||||
protected $_rootdir;
|
||||
|
||||
/**
|
||||
* name of current folder
|
||||
* @var string
|
||||
*/
|
||||
protected $_currentFolder;
|
||||
|
||||
/**
|
||||
* Create instance with parameters
|
||||
*
|
||||
* Disallowed parameters are:
|
||||
* - filename use Postman_Zend_Mail_Storage_Mbox for a single file
|
||||
* Supported parameters are:
|
||||
* - dirname rootdir of mbox structure
|
||||
* - folder intial selected folder, default is 'INBOX'
|
||||
*
|
||||
* @param array $params mail reader specific parameters
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
public function __construct($params)
|
||||
{
|
||||
if (is_array($params)) {
|
||||
$params = (object)$params;
|
||||
}
|
||||
|
||||
if (isset($params->filename)) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception('use Postman_Zend_Mail_Storage_Mbox for a single file');
|
||||
}
|
||||
|
||||
if (!isset($params->dirname) || !is_dir($params->dirname)) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception('no valid dirname given in params');
|
||||
}
|
||||
|
||||
$this->_rootdir = rtrim($params->dirname, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
|
||||
|
||||
$this->_buildFolderTree($this->_rootdir);
|
||||
$this->selectFolder(!empty($params->folder) ? $params->folder : 'INBOX');
|
||||
$this->_has['top'] = true;
|
||||
$this->_has['uniqueid'] = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* find all subfolders and mbox files for folder structure
|
||||
*
|
||||
* Result is save in Postman_Zend_Mail_Storage_Folder instances with the root in $this->_rootFolder.
|
||||
* $parentFolder and $parentGlobalName are only used internally for recursion.
|
||||
*
|
||||
* @param string $currentDir call with root dir, also used for recursion.
|
||||
* @param Postman_Zend_Mail_Storage_Folder|null $parentFolder used for recursion
|
||||
* @param string $parentGlobalName used for rescursion
|
||||
* @return null
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
protected function _buildFolderTree($currentDir, $parentFolder = null, $parentGlobalName = '')
|
||||
{
|
||||
if (!$parentFolder) {
|
||||
$this->_rootFolder = new Postman_Zend_Mail_Storage_Folder('/', '/', false);
|
||||
$parentFolder = $this->_rootFolder;
|
||||
}
|
||||
|
||||
$dh = @opendir($currentDir);
|
||||
if (!$dh) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception("can't read dir $currentDir");
|
||||
}
|
||||
while (($entry = readdir($dh)) !== false) {
|
||||
// ignore hidden files for mbox
|
||||
if ($entry[0] == '.') {
|
||||
continue;
|
||||
}
|
||||
$absoluteEntry = $currentDir . $entry;
|
||||
$globalName = $parentGlobalName . DIRECTORY_SEPARATOR . $entry;
|
||||
if (is_file($absoluteEntry) && $this->_isMboxFile($absoluteEntry)) {
|
||||
$parentFolder->$entry = new Postman_Zend_Mail_Storage_Folder($entry, $globalName);
|
||||
continue;
|
||||
}
|
||||
if (!is_dir($absoluteEntry) /* || $entry == '.' || $entry == '..' */) {
|
||||
continue;
|
||||
}
|
||||
$folder = new Postman_Zend_Mail_Storage_Folder($entry, $globalName, false);
|
||||
$parentFolder->$entry = $folder;
|
||||
$this->_buildFolderTree($absoluteEntry . DIRECTORY_SEPARATOR, $folder, $globalName);
|
||||
}
|
||||
|
||||
closedir($dh);
|
||||
}
|
||||
|
||||
/**
|
||||
* get root folder or given folder
|
||||
*
|
||||
* @param string $rootFolder get folder structure for given folder, else root
|
||||
* @return Postman_Zend_Mail_Storage_Folder root or wanted folder
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
public function getFolders($rootFolder = null)
|
||||
{
|
||||
if (!$rootFolder) {
|
||||
return $this->_rootFolder;
|
||||
}
|
||||
|
||||
$currentFolder = $this->_rootFolder;
|
||||
$subname = trim($rootFolder, DIRECTORY_SEPARATOR);
|
||||
while ($currentFolder) {
|
||||
@list($entry, $subname) = @explode(DIRECTORY_SEPARATOR, $subname, 2);
|
||||
$currentFolder = $currentFolder->$entry;
|
||||
if (!$subname) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($currentFolder->getGlobalName() != DIRECTORY_SEPARATOR . trim($rootFolder, DIRECTORY_SEPARATOR)) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception("folder $rootFolder not found");
|
||||
}
|
||||
return $currentFolder;
|
||||
}
|
||||
|
||||
/**
|
||||
* select given folder
|
||||
*
|
||||
* folder must be selectable!
|
||||
*
|
||||
* @param Postman_Zend_Mail_Storage_Folder|string $globalName global name of folder or instance for subfolder
|
||||
* @return null
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
public function selectFolder($globalName)
|
||||
{
|
||||
$this->_currentFolder = (string)$globalName;
|
||||
|
||||
// getting folder from folder tree for validation
|
||||
$folder = $this->getFolders($this->_currentFolder);
|
||||
|
||||
try {
|
||||
$this->_openMboxFile($this->_rootdir . $folder->getGlobalName());
|
||||
} catch(Postman_Zend_Mail_Storage_Exception $e) {
|
||||
// check what went wrong
|
||||
if (!$folder->isSelectable()) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception("{$this->_currentFolder} is not selectable", 0, $e);
|
||||
}
|
||||
// seems like file has vanished; rebuilding folder tree - but it's still an exception
|
||||
$this->_buildFolderTree($this->_rootdir);
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception('seems like the mbox file has vanished, I\'ve rebuild the ' .
|
||||
'folder tree, search for an other folder and try again', 0, $e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get Postman_Zend_Mail_Storage_Folder instance for current folder
|
||||
*
|
||||
* @return Postman_Zend_Mail_Storage_Folder instance of current folder
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
public function getCurrentFolder()
|
||||
{
|
||||
return $this->_currentFolder;
|
||||
}
|
||||
|
||||
/**
|
||||
* magic method for serialize()
|
||||
*
|
||||
* with this method you can cache the mbox class
|
||||
*
|
||||
* @return array name of variables
|
||||
*/
|
||||
public function __sleep()
|
||||
{
|
||||
return array_merge(parent::__sleep(), array('_currentFolder', '_rootFolder', '_rootdir'));
|
||||
}
|
||||
|
||||
/**
|
||||
* magic method for unserialize()
|
||||
*
|
||||
* with this method you can cache the mbox class
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public function __wakeup()
|
||||
{
|
||||
// if cache is stall selectFolder() rebuilds the tree on error
|
||||
parent::__wakeup();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,644 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @subpackage Storage
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Abstract
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Abstract.php';
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Protocol_Imap
|
||||
*/
|
||||
require_once 'Zend/Mail/Protocol/Imap.php';
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Writable_Interface
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Writable/Interface.php';
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Folder_Interface
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Folder/Interface.php';
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Folder
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Folder.php';
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Message
|
||||
*/
|
||||
require_once 'Zend/Mail/Message.php';
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage.php';
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @subpackage Storage
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Mail_Storage_Imap extends Postman_Zend_Mail_Storage_Abstract
|
||||
implements Postman_Zend_Mail_Storage_Folder_Interface, Postman_Zend_Mail_Storage_Writable_Interface
|
||||
{
|
||||
// TODO: with an internal cache we could optimize this class, or create an extra class with
|
||||
// such optimizations. Especially the various fetch calls could be combined to one cache call
|
||||
|
||||
/**
|
||||
* protocol handler
|
||||
* @var null|Postman_Zend_Mail_Protocol_Imap
|
||||
*/
|
||||
protected $_protocol;
|
||||
|
||||
/**
|
||||
* name of current folder
|
||||
* @var string
|
||||
*/
|
||||
protected $_currentFolder = '';
|
||||
|
||||
/**
|
||||
* imap flags to constants translation
|
||||
* @var array
|
||||
*/
|
||||
protected static $_knownFlags = array('\Passed' => Postman_Zend_Mail_Storage::FLAG_PASSED,
|
||||
'\Answered' => Postman_Zend_Mail_Storage::FLAG_ANSWERED,
|
||||
'\Seen' => Postman_Zend_Mail_Storage::FLAG_SEEN,
|
||||
'\Deleted' => Postman_Zend_Mail_Storage::FLAG_DELETED,
|
||||
'\Draft' => Postman_Zend_Mail_Storage::FLAG_DRAFT,
|
||||
'\Flagged' => Postman_Zend_Mail_Storage::FLAG_FLAGGED);
|
||||
|
||||
/**
|
||||
* map flags to search criterias
|
||||
* @var array
|
||||
*/
|
||||
protected static $_searchFlags = array('\Recent' => 'RECENT',
|
||||
'\Answered' => 'ANSWERED',
|
||||
'\Seen' => 'SEEN',
|
||||
'\Deleted' => 'DELETED',
|
||||
'\Draft' => 'DRAFT',
|
||||
'\Flagged' => 'FLAGGED');
|
||||
|
||||
/**
|
||||
* Count messages all messages in current box
|
||||
*
|
||||
* @return int number of messages
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
public function countMessages($flags = null)
|
||||
{
|
||||
if (!$this->_currentFolder) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception('No selected folder to count');
|
||||
}
|
||||
|
||||
if ($flags === null) {
|
||||
return count($this->_protocol->search(array('ALL')));
|
||||
}
|
||||
|
||||
$params = array();
|
||||
foreach ((array)$flags as $flag) {
|
||||
if (isset(self::$_searchFlags[$flag])) {
|
||||
$params[] = self::$_searchFlags[$flag];
|
||||
} else {
|
||||
$params[] = 'KEYWORD';
|
||||
$params[] = $this->_protocol->escapeString($flag);
|
||||
}
|
||||
}
|
||||
return count($this->_protocol->search($params));
|
||||
}
|
||||
|
||||
/**
|
||||
* get a list of messages with number and size
|
||||
*
|
||||
* @param int $id number of message
|
||||
* @return int|array size of given message of list with all messages as array(num => size)
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
public function getSize($id = 0)
|
||||
{
|
||||
if ($id) {
|
||||
return $this->_protocol->fetch('RFC822.SIZE', $id);
|
||||
}
|
||||
return $this->_protocol->fetch('RFC822.SIZE', 1, INF);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch a message
|
||||
*
|
||||
* @param int $id number of message
|
||||
* @return Postman_Zend_Mail_Message
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
public function getMessage($id)
|
||||
{
|
||||
$data = $this->_protocol->fetch(array('FLAGS', 'RFC822.HEADER'), $id);
|
||||
$header = $data['RFC822.HEADER'];
|
||||
|
||||
$flags = array();
|
||||
foreach ($data['FLAGS'] as $flag) {
|
||||
$flags[] = isset(self::$_knownFlags[$flag]) ? self::$_knownFlags[$flag] : $flag;
|
||||
}
|
||||
|
||||
return new $this->_messageClass(array('handler' => $this, 'id' => $id, 'headers' => $header, 'flags' => $flags));
|
||||
}
|
||||
|
||||
/*
|
||||
* Get raw header of message or part
|
||||
*
|
||||
* @param int $id number of message
|
||||
* @param null|array|string $part path to part or null for messsage header
|
||||
* @param int $topLines include this many lines with header (after an empty line)
|
||||
* @param int $topLines include this many lines with header (after an empty line)
|
||||
* @return string raw header
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
public function getRawHeader($id, $part = null, $topLines = 0)
|
||||
{
|
||||
if ($part !== null) {
|
||||
// TODO: implement
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception('not implemented');
|
||||
}
|
||||
|
||||
// TODO: toplines
|
||||
return $this->_protocol->fetch('RFC822.HEADER', $id);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get raw content of message or part
|
||||
*
|
||||
* @param int $id number of message
|
||||
* @param null|array|string $part path to part or null for messsage content
|
||||
* @return string raw content
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
public function getRawContent($id, $part = null)
|
||||
{
|
||||
if ($part !== null) {
|
||||
// TODO: implement
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception('not implemented');
|
||||
}
|
||||
|
||||
return $this->_protocol->fetch('RFC822.TEXT', $id);
|
||||
}
|
||||
|
||||
/**
|
||||
* create instance with parameters
|
||||
* Supported paramters are
|
||||
* - user username
|
||||
* - host hostname or ip address of IMAP server [optional, default = 'localhost']
|
||||
* - password password for user 'username' [optional, default = '']
|
||||
* - port port for IMAP server [optional, default = 110]
|
||||
* - ssl 'SSL' or 'TLS' for secure sockets
|
||||
* - folder select this folder [optional, default = 'INBOX']
|
||||
*
|
||||
* @param array $params mail reader specific parameters
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
public function __construct($params)
|
||||
{
|
||||
if (is_array($params)) {
|
||||
$params = (object)$params;
|
||||
}
|
||||
|
||||
$this->_has['flags'] = true;
|
||||
|
||||
if ($params instanceof Postman_Zend_Mail_Protocol_Imap) {
|
||||
$this->_protocol = $params;
|
||||
try {
|
||||
$this->selectFolder('INBOX');
|
||||
} catch(Postman_Zend_Mail_Storage_Exception $e) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception('cannot select INBOX, is this a valid transport?', 0, $e);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isset($params->user)) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception('need at least user in params');
|
||||
}
|
||||
|
||||
$host = isset($params->host) ? $params->host : 'localhost';
|
||||
$password = isset($params->password) ? $params->password : '';
|
||||
$port = isset($params->port) ? $params->port : null;
|
||||
$ssl = isset($params->ssl) ? $params->ssl : false;
|
||||
|
||||
$this->_protocol = new Postman_Zend_Mail_Protocol_Imap();
|
||||
$this->_protocol->connect($host, $port, $ssl);
|
||||
if (!$this->_protocol->login($params->user, $password)) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception('cannot login, user or password wrong');
|
||||
}
|
||||
$this->selectFolder(isset($params->folder) ? $params->folder : 'INBOX');
|
||||
}
|
||||
|
||||
/**
|
||||
* Close resource for mail lib. If you need to control, when the resource
|
||||
* is closed. Otherwise the destructor would call this.
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
$this->_currentFolder = '';
|
||||
$this->_protocol->logout();
|
||||
}
|
||||
|
||||
/**
|
||||
* Keep the server busy.
|
||||
*
|
||||
* @return null
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
public function noop()
|
||||
{
|
||||
if (!$this->_protocol->noop()) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception('could not do nothing');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a message from server. If you're doing that from a web enviroment
|
||||
* you should be careful and use a uniqueid as parameter if possible to
|
||||
* identify the message.
|
||||
*
|
||||
* @param int $id number of message
|
||||
* @return null
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
public function removeMessage($id)
|
||||
{
|
||||
if (!$this->_protocol->store(array(Postman_Zend_Mail_Storage::FLAG_DELETED), $id, null, '+')) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception('cannot set deleted flag');
|
||||
}
|
||||
// TODO: expunge here or at close? we can handle an error here better and are more fail safe
|
||||
if (!$this->_protocol->expunge()) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception('message marked as deleted, but could not expunge');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get unique id for one or all messages
|
||||
*
|
||||
* if storage does not support unique ids it's the same as the message number
|
||||
*
|
||||
* @param int|null $id message number
|
||||
* @return array|string message number for given message or all messages as array
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
public function getUniqueId($id = null)
|
||||
{
|
||||
if ($id) {
|
||||
return $this->_protocol->fetch('UID', $id);
|
||||
}
|
||||
|
||||
return $this->_protocol->fetch('UID', 1, INF);
|
||||
}
|
||||
|
||||
/**
|
||||
* get a message number from a unique id
|
||||
*
|
||||
* I.e. if you have a webmailer that supports deleting messages you should use unique ids
|
||||
* as parameter and use this method to translate it to message number right before calling removeMessage()
|
||||
*
|
||||
* @param string $id unique id
|
||||
* @return int message number
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
public function getNumberByUniqueId($id)
|
||||
{
|
||||
// TODO: use search to find number directly
|
||||
$ids = $this->getUniqueId();
|
||||
foreach ($ids as $k => $v) {
|
||||
if ($v == $id) {
|
||||
return $k;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception('unique id not found');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* get root folder or given folder
|
||||
*
|
||||
* @param string $rootFolder get folder structure for given folder, else root
|
||||
* @return Postman_Zend_Mail_Storage_Folder root or wanted folder
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
public function getFolders($rootFolder = null)
|
||||
{
|
||||
$folders = $this->_protocol->listMailbox((string)$rootFolder);
|
||||
if (!$folders) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception('folder not found');
|
||||
}
|
||||
|
||||
ksort($folders, SORT_STRING);
|
||||
$root = new Postman_Zend_Mail_Storage_Folder('/', '/', false);
|
||||
$stack = array(null);
|
||||
$folderStack = array(null);
|
||||
$parentFolder = $root;
|
||||
$parent = '';
|
||||
|
||||
foreach ($folders as $globalName => $data) {
|
||||
do {
|
||||
if (!$parent || strpos($globalName, $parent) === 0) {
|
||||
$pos = strrpos($globalName, $data['delim']);
|
||||
if ($pos === false) {
|
||||
$localName = $globalName;
|
||||
} else {
|
||||
$localName = substr($globalName, $pos + 1);
|
||||
}
|
||||
$selectable = !$data['flags'] || !in_array('\\Noselect', $data['flags']);
|
||||
|
||||
array_push($stack, $parent);
|
||||
$parent = $globalName . $data['delim'];
|
||||
$folder = new Postman_Zend_Mail_Storage_Folder($localName, $globalName, $selectable);
|
||||
$parentFolder->$localName = $folder;
|
||||
array_push($folderStack, $parentFolder);
|
||||
$parentFolder = $folder;
|
||||
break;
|
||||
} else if ($stack) {
|
||||
$parent = array_pop($stack);
|
||||
$parentFolder = array_pop($folderStack);
|
||||
}
|
||||
} while ($stack);
|
||||
if (!$stack) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception('error while constructing folder tree');
|
||||
}
|
||||
}
|
||||
|
||||
return $root;
|
||||
}
|
||||
|
||||
/**
|
||||
* select given folder
|
||||
*
|
||||
* folder must be selectable!
|
||||
*
|
||||
* @param Postman_Zend_Mail_Storage_Folder|string $globalName global name of folder or instance for subfolder
|
||||
* @return null
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
public function selectFolder($globalName)
|
||||
{
|
||||
$this->_currentFolder = $globalName;
|
||||
if (!$this->_protocol->select($this->_currentFolder)) {
|
||||
$this->_currentFolder = '';
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception('cannot change folder, maybe it does not exist');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* get Postman_Zend_Mail_Storage_Folder instance for current folder
|
||||
*
|
||||
* @return Postman_Zend_Mail_Storage_Folder instance of current folder
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
public function getCurrentFolder()
|
||||
{
|
||||
return $this->_currentFolder;
|
||||
}
|
||||
|
||||
/**
|
||||
* create a new folder
|
||||
*
|
||||
* This method also creates parent folders if necessary. Some mail storages may restrict, which folder
|
||||
* may be used as parent or which chars may be used in the folder name
|
||||
*
|
||||
* @param string $name global name of folder, local name if $parentFolder is set
|
||||
* @param string|Postman_Zend_Mail_Storage_Folder $parentFolder parent folder for new folder, else root folder is parent
|
||||
* @return null
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
public function createFolder($name, $parentFolder = null)
|
||||
{
|
||||
// TODO: we assume / as the hierarchy delim - need to get that from the folder class!
|
||||
if ($parentFolder instanceof Postman_Zend_Mail_Storage_Folder) {
|
||||
$folder = $parentFolder->getGlobalName() . '/' . $name;
|
||||
} else if ($parentFolder != null) {
|
||||
$folder = $parentFolder . '/' . $name;
|
||||
} else {
|
||||
$folder = $name;
|
||||
}
|
||||
|
||||
if (!$this->_protocol->create($folder)) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception('cannot create folder');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* remove a folder
|
||||
*
|
||||
* @param string|Postman_Zend_Mail_Storage_Folder $name name or instance of folder
|
||||
* @return null
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
public function removeFolder($name)
|
||||
{
|
||||
if ($name instanceof Postman_Zend_Mail_Storage_Folder) {
|
||||
$name = $name->getGlobalName();
|
||||
}
|
||||
|
||||
if (!$this->_protocol->delete($name)) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception('cannot delete folder');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* rename and/or move folder
|
||||
*
|
||||
* The new name has the same restrictions as in createFolder()
|
||||
*
|
||||
* @param string|Postman_Zend_Mail_Storage_Folder $oldName name or instance of folder
|
||||
* @param string $newName new global name of folder
|
||||
* @return null
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
public function renameFolder($oldName, $newName)
|
||||
{
|
||||
if ($oldName instanceof Postman_Zend_Mail_Storage_Folder) {
|
||||
$oldName = $oldName->getGlobalName();
|
||||
}
|
||||
|
||||
if (!$this->_protocol->rename($oldName, $newName)) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception('cannot rename folder');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* append a new message to mail storage
|
||||
*
|
||||
* @param string $message message as string or instance of message class
|
||||
* @param null|string|Postman_Zend_Mail_Storage_Folder $folder folder for new message, else current folder is taken
|
||||
* @param null|array $flags set flags for new message, else a default set is used
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
// not yet * @param string|Postman_Zend_Mail_Message|Postman_Zend_Mime_Message $message message as string or instance of message class
|
||||
public function appendMessage($message, $folder = null, $flags = null)
|
||||
{
|
||||
if ($folder === null) {
|
||||
$folder = $this->_currentFolder;
|
||||
}
|
||||
|
||||
if ($flags === null) {
|
||||
$flags = array(Postman_Zend_Mail_Storage::FLAG_SEEN);
|
||||
}
|
||||
|
||||
// TODO: handle class instances for $message
|
||||
if (!$this->_protocol->append($folder, $message, $flags)) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception('cannot create message, please check if the folder exists and your flags');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* copy an existing message
|
||||
*
|
||||
* @param int $id number of message
|
||||
* @param string|Postman_Zend_Mail_Storage_Folder $folder name or instance of targer folder
|
||||
* @return null
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
public function copyMessage($id, $folder)
|
||||
{
|
||||
if (!$this->_protocol->copy($folder, $id)) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception('cannot copy message, does the folder exist?');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* move an existing message
|
||||
*
|
||||
* NOTE: imap has no native move command, thus it's emulated with copy and delete
|
||||
*
|
||||
* @param int $id number of message
|
||||
* @param string|Postman_Zend_Mail_Storage_Folder $folder name or instance of targer folder
|
||||
* @return null
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
public function moveMessage($id, $folder) {
|
||||
$this->copyMessage($id, $folder);
|
||||
$this->removeMessage($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* set flags for message
|
||||
*
|
||||
* NOTE: this method can't set the recent flag.
|
||||
*
|
||||
* @param int $id number of message
|
||||
* @param array $flags new flags for message
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
public function setFlags($id, $flags)
|
||||
{
|
||||
if (!$this->_protocol->store($flags, $id)) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception('cannot set flags, have you tried to set the recent flag or special chars?');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,475 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @subpackage Storage
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Abstract
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Abstract.php';
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Message_File
|
||||
*/
|
||||
require_once 'Zend/Mail/Message/File.php';
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage.php';
|
||||
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @subpackage Storage
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Mail_Storage_Maildir extends Postman_Zend_Mail_Storage_Abstract
|
||||
{
|
||||
/**
|
||||
* used message class, change it in an extened class to extend the returned message class
|
||||
* @var string
|
||||
*/
|
||||
protected $_messageClass = 'Postman_Zend_Mail_Message_File';
|
||||
|
||||
/**
|
||||
* data of found message files in maildir dir
|
||||
* @var array
|
||||
*/
|
||||
protected $_files = array();
|
||||
|
||||
/**
|
||||
* known flag chars in filenames
|
||||
*
|
||||
* This list has to be in alphabetical order for setFlags()
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $_knownFlags = array('D' => Postman_Zend_Mail_Storage::FLAG_DRAFT,
|
||||
'F' => Postman_Zend_Mail_Storage::FLAG_FLAGGED,
|
||||
'P' => Postman_Zend_Mail_Storage::FLAG_PASSED,
|
||||
'R' => Postman_Zend_Mail_Storage::FLAG_ANSWERED,
|
||||
'S' => Postman_Zend_Mail_Storage::FLAG_SEEN,
|
||||
'T' => Postman_Zend_Mail_Storage::FLAG_DELETED);
|
||||
|
||||
// TODO: getFlags($id) for fast access if headers are not needed (i.e. just setting flags)?
|
||||
|
||||
/**
|
||||
* Count messages all messages in current box
|
||||
*
|
||||
* @return int number of messages
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
public function countMessages($flags = null)
|
||||
{
|
||||
if ($flags === null) {
|
||||
return count($this->_files);
|
||||
}
|
||||
|
||||
$count = 0;
|
||||
if (!is_array($flags)) {
|
||||
foreach ($this->_files as $file) {
|
||||
if (isset($file['flaglookup'][$flags])) {
|
||||
++$count;
|
||||
}
|
||||
}
|
||||
return $count;
|
||||
}
|
||||
|
||||
$flags = array_flip($flags);
|
||||
foreach ($this->_files as $file) {
|
||||
foreach ($flags as $flag => $v) {
|
||||
if (!isset($file['flaglookup'][$flag])) {
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
++$count;
|
||||
}
|
||||
return $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get one or all fields from file structure. Also checks if message is valid
|
||||
*
|
||||
* @param int $id message number
|
||||
* @param string|null $field wanted field
|
||||
* @return string|array wanted field or all fields as array
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
protected function _getFileData($id, $field = null)
|
||||
{
|
||||
if (!isset($this->_files[$id - 1])) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception('id does not exist');
|
||||
}
|
||||
|
||||
if (!$field) {
|
||||
return $this->_files[$id - 1];
|
||||
}
|
||||
|
||||
if (!isset($this->_files[$id - 1][$field])) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception('field does not exist');
|
||||
}
|
||||
|
||||
return $this->_files[$id - 1][$field];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of messages with number and size
|
||||
*
|
||||
* @param int|null $id number of message or null for all messages
|
||||
* @return int|array size of given message of list with all messages as array(num => size)
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
public function getSize($id = null)
|
||||
{
|
||||
if ($id !== null) {
|
||||
$filedata = $this->_getFileData($id);
|
||||
return isset($filedata['size']) ? $filedata['size'] : filesize($filedata['filename']);
|
||||
}
|
||||
|
||||
$result = array();
|
||||
foreach ($this->_files as $num => $data) {
|
||||
$result[$num + 1] = isset($data['size']) ? $data['size'] : filesize($data['filename']);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Fetch a message
|
||||
*
|
||||
* @param int $id number of message
|
||||
* @return Postman_Zend_Mail_Message_File
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
public function getMessage($id)
|
||||
{
|
||||
// TODO that's ugly, would be better to let the message class decide
|
||||
if (strtolower($this->_messageClass) == 'Postman_Zend_mail_message_file' || is_subclass_of($this->_messageClass, 'Postman_Zend_mail_message_file')) {
|
||||
return new $this->_messageClass(array('file' => $this->_getFileData($id, 'filename'),
|
||||
'flags' => $this->_getFileData($id, 'flags')));
|
||||
}
|
||||
|
||||
return new $this->_messageClass(array('handler' => $this, 'id' => $id, 'headers' => $this->getRawHeader($id),
|
||||
'flags' => $this->_getFileData($id, 'flags')));
|
||||
}
|
||||
|
||||
/*
|
||||
* Get raw header of message or part
|
||||
*
|
||||
* @param int $id number of message
|
||||
* @param null|array|string $part path to part or null for messsage header
|
||||
* @param int $topLines include this many lines with header (after an empty line)
|
||||
* @return string raw header
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
public function getRawHeader($id, $part = null, $topLines = 0)
|
||||
{
|
||||
if ($part !== null) {
|
||||
// TODO: implement
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception('not implemented');
|
||||
}
|
||||
|
||||
$fh = fopen($this->_getFileData($id, 'filename'), 'r');
|
||||
|
||||
$content = '';
|
||||
while (!feof($fh)) {
|
||||
$line = fgets($fh);
|
||||
if (!trim($line)) {
|
||||
break;
|
||||
}
|
||||
$content .= $line;
|
||||
}
|
||||
|
||||
fclose($fh);
|
||||
return $content;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get raw content of message or part
|
||||
*
|
||||
* @param int $id number of message
|
||||
* @param null|array|string $part path to part or null for messsage content
|
||||
* @return string raw content
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
public function getRawContent($id, $part = null)
|
||||
{
|
||||
if ($part !== null) {
|
||||
// TODO: implement
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception('not implemented');
|
||||
}
|
||||
|
||||
$fh = fopen($this->_getFileData($id, 'filename'), 'r');
|
||||
|
||||
while (!feof($fh)) {
|
||||
$line = fgets($fh);
|
||||
if (!trim($line)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$content = stream_get_contents($fh);
|
||||
fclose($fh);
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create instance with parameters
|
||||
* Supported parameters are:
|
||||
* - dirname dirname of mbox file
|
||||
*
|
||||
* @param array $params mail reader specific parameters
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
public function __construct($params)
|
||||
{
|
||||
if (is_array($params)) {
|
||||
$params = (object)$params;
|
||||
}
|
||||
|
||||
if (!isset($params->dirname) || !is_dir($params->dirname)) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception('no valid dirname given in params');
|
||||
}
|
||||
|
||||
if (!$this->_isMaildir($params->dirname)) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception('invalid maildir given');
|
||||
}
|
||||
|
||||
$this->_has['top'] = true;
|
||||
$this->_has['flags'] = true;
|
||||
$this->_openMaildir($params->dirname);
|
||||
}
|
||||
|
||||
/**
|
||||
* check if a given dir is a valid maildir
|
||||
*
|
||||
* @param string $dirname name of dir
|
||||
* @return bool dir is valid maildir
|
||||
*/
|
||||
protected function _isMaildir($dirname)
|
||||
{
|
||||
if (file_exists($dirname . '/new') && !is_dir($dirname . '/new')) {
|
||||
return false;
|
||||
}
|
||||
if (file_exists($dirname . '/tmp') && !is_dir($dirname . '/tmp')) {
|
||||
return false;
|
||||
}
|
||||
return is_dir($dirname . '/cur');
|
||||
}
|
||||
|
||||
/**
|
||||
* open given dir as current maildir
|
||||
*
|
||||
* @param string $dirname name of maildir
|
||||
* @return null
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
protected function _openMaildir($dirname)
|
||||
{
|
||||
if ($this->_files) {
|
||||
$this->close();
|
||||
}
|
||||
|
||||
$dh = @opendir($dirname . '/cur/');
|
||||
if (!$dh) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception('cannot open maildir');
|
||||
}
|
||||
$this->_getMaildirFiles($dh, $dirname . '/cur/');
|
||||
closedir($dh);
|
||||
|
||||
$dh = @opendir($dirname . '/new/');
|
||||
if ($dh) {
|
||||
$this->_getMaildirFiles($dh, $dirname . '/new/', array(Postman_Zend_Mail_Storage::FLAG_RECENT));
|
||||
closedir($dh);
|
||||
} else if (file_exists($dirname . '/new/')) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception('cannot read recent mails in maildir');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* find all files in opened dir handle and add to maildir files
|
||||
*
|
||||
* @param resource $dh dir handle used for search
|
||||
* @param string $dirname dirname of dir in $dh
|
||||
* @param array $default_flags default flags for given dir
|
||||
* @return null
|
||||
*/
|
||||
protected function _getMaildirFiles($dh, $dirname, $default_flags = array())
|
||||
{
|
||||
while (($entry = readdir($dh)) !== false) {
|
||||
if ($entry[0] == '.' || !is_file($dirname . $entry)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@list($uniq, $info) = explode(':', $entry, 2);
|
||||
@list(,$size) = explode(',', $uniq, 2);
|
||||
if ($size && $size[0] == 'S' && $size[1] == '=') {
|
||||
$size = substr($size, 2);
|
||||
}
|
||||
if (!ctype_digit($size)) {
|
||||
$size = null;
|
||||
}
|
||||
@list($version, $flags) = explode(',', $info, 2);
|
||||
if ($version != 2) {
|
||||
$flags = '';
|
||||
}
|
||||
|
||||
$named_flags = $default_flags;
|
||||
$length = strlen($flags);
|
||||
for ($i = 0; $i < $length; ++$i) {
|
||||
$flag = $flags[$i];
|
||||
$named_flags[$flag] = isset(self::$_knownFlags[$flag]) ? self::$_knownFlags[$flag] : $flag;
|
||||
}
|
||||
|
||||
$data = array('uniq' => $uniq,
|
||||
'flags' => $named_flags,
|
||||
'flaglookup' => array_flip($named_flags),
|
||||
'filename' => $dirname . $entry);
|
||||
if ($size !== null) {
|
||||
$data['size'] = (int)$size;
|
||||
}
|
||||
$this->_files[] = $data;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Close resource for mail lib. If you need to control, when the resource
|
||||
* is closed. Otherwise the destructor would call this.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
$this->_files = array();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Waste some CPU cycles doing nothing.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function noop()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* stub for not supported message deletion
|
||||
*
|
||||
* @return null
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
public function removeMessage($id)
|
||||
{
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception('maildir is (currently) read-only');
|
||||
}
|
||||
|
||||
/**
|
||||
* get unique id for one or all messages
|
||||
*
|
||||
* if storage does not support unique ids it's the same as the message number
|
||||
*
|
||||
* @param int|null $id message number
|
||||
* @return array|string message number for given message or all messages as array
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
public function getUniqueId($id = null)
|
||||
{
|
||||
if ($id) {
|
||||
return $this->_getFileData($id, 'uniq');
|
||||
}
|
||||
|
||||
$ids = array();
|
||||
foreach ($this->_files as $num => $file) {
|
||||
$ids[$num + 1] = $file['uniq'];
|
||||
}
|
||||
return $ids;
|
||||
}
|
||||
|
||||
/**
|
||||
* get a message number from a unique id
|
||||
*
|
||||
* I.e. if you have a webmailer that supports deleting messages you should use unique ids
|
||||
* as parameter and use this method to translate it to message number right before calling removeMessage()
|
||||
*
|
||||
* @param string $id unique id
|
||||
* @return int message number
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
public function getNumberByUniqueId($id)
|
||||
{
|
||||
foreach ($this->_files as $num => $file) {
|
||||
if ($file['uniq'] == $id) {
|
||||
return $num + 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception('unique id not found');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,447 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @subpackage Storage
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Loader
|
||||
* May be used in constructor, but commented out for now
|
||||
*/
|
||||
// require_once 'Zend/Loader.php';
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Abstract
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Abstract.php';
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Message_File
|
||||
*/
|
||||
require_once 'Zend/Mail/Message/File.php';
|
||||
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @subpackage Storage
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Mail_Storage_Mbox extends Postman_Zend_Mail_Storage_Abstract
|
||||
{
|
||||
/**
|
||||
* file handle to mbox file
|
||||
* @var null|resource
|
||||
*/
|
||||
protected $_fh;
|
||||
|
||||
/**
|
||||
* filename of mbox file for __wakeup
|
||||
* @var string
|
||||
*/
|
||||
protected $_filename;
|
||||
|
||||
/**
|
||||
* modification date of mbox file for __wakeup
|
||||
* @var int
|
||||
*/
|
||||
protected $_filemtime;
|
||||
|
||||
/**
|
||||
* start and end position of messages as array('start' => start, 'seperator' => headersep, 'end' => end)
|
||||
* @var array
|
||||
*/
|
||||
protected $_positions;
|
||||
|
||||
/**
|
||||
* used message class, change it in an extened class to extend the returned message class
|
||||
* @var string
|
||||
*/
|
||||
protected $_messageClass = 'Postman_Zend_Mail_Message_File';
|
||||
|
||||
/**
|
||||
* Count messages all messages in current box
|
||||
*
|
||||
* @return int number of messages
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
public function countMessages()
|
||||
{
|
||||
return count($this->_positions);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a list of messages with number and size
|
||||
*
|
||||
* @param int|null $id number of message or null for all messages
|
||||
* @return int|array size of given message of list with all messages as array(num => size)
|
||||
*/
|
||||
public function getSize($id = 0)
|
||||
{
|
||||
if ($id) {
|
||||
$pos = $this->_positions[$id - 1];
|
||||
return $pos['end'] - $pos['start'];
|
||||
}
|
||||
|
||||
$result = array();
|
||||
foreach ($this->_positions as $num => $pos) {
|
||||
$result[$num + 1] = $pos['end'] - $pos['start'];
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get positions for mail message or throw exeption if id is invalid
|
||||
*
|
||||
* @param int $id number of message
|
||||
* @return array positions as in _positions
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
protected function _getPos($id)
|
||||
{
|
||||
if (!isset($this->_positions[$id - 1])) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception('id does not exist');
|
||||
}
|
||||
|
||||
return $this->_positions[$id - 1];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fetch a message
|
||||
*
|
||||
* @param int $id number of message
|
||||
* @return Postman_Zend_Mail_Message_File
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
public function getMessage($id)
|
||||
{
|
||||
// TODO that's ugly, would be better to let the message class decide
|
||||
if (strtolower($this->_messageClass) == 'Postman_Zend_mail_message_file' || is_subclass_of($this->_messageClass, 'Postman_Zend_mail_message_file')) {
|
||||
// TODO top/body lines
|
||||
$messagePos = $this->_getPos($id);
|
||||
return new $this->_messageClass(array('file' => $this->_fh, 'startPos' => $messagePos['start'],
|
||||
'endPos' => $messagePos['end']));
|
||||
}
|
||||
|
||||
$bodyLines = 0; // TODO: need a way to change that
|
||||
|
||||
$message = $this->getRawHeader($id);
|
||||
// file pointer is after headers now
|
||||
if ($bodyLines) {
|
||||
$message .= "\n";
|
||||
while ($bodyLines-- && ftell($this->_fh) < $this->_positions[$id - 1]['end']) {
|
||||
$message .= fgets($this->_fh);
|
||||
}
|
||||
}
|
||||
|
||||
return new $this->_messageClass(array('handler' => $this, 'id' => $id, 'headers' => $message));
|
||||
}
|
||||
|
||||
/*
|
||||
* Get raw header of message or part
|
||||
*
|
||||
* @param int $id number of message
|
||||
* @param null|array|string $part path to part or null for messsage header
|
||||
* @param int $topLines include this many lines with header (after an empty line)
|
||||
* @return string raw header
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
public function getRawHeader($id, $part = null, $topLines = 0)
|
||||
{
|
||||
if ($part !== null) {
|
||||
// TODO: implement
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception('not implemented');
|
||||
}
|
||||
$messagePos = $this->_getPos($id);
|
||||
// TODO: toplines
|
||||
return stream_get_contents($this->_fh, $messagePos['separator'] - $messagePos['start'], $messagePos['start']);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get raw content of message or part
|
||||
*
|
||||
* @param int $id number of message
|
||||
* @param null|array|string $part path to part or null for messsage content
|
||||
* @return string raw content
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
public function getRawContent($id, $part = null)
|
||||
{
|
||||
if ($part !== null) {
|
||||
// TODO: implement
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception('not implemented');
|
||||
}
|
||||
$messagePos = $this->_getPos($id);
|
||||
return stream_get_contents($this->_fh, $messagePos['end'] - $messagePos['separator'], $messagePos['separator']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create instance with parameters
|
||||
* Supported parameters are:
|
||||
* - filename filename of mbox file
|
||||
*
|
||||
* @param array $params mail reader specific parameters
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
public function __construct($params)
|
||||
{
|
||||
if (is_array($params)) {
|
||||
$params = (object)$params;
|
||||
}
|
||||
|
||||
if (!isset($params->filename) /* || Postman_Zend_Loader::isReadable($params['filename']) */) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception('no valid filename given in params');
|
||||
}
|
||||
|
||||
$this->_openMboxFile($params->filename);
|
||||
$this->_has['top'] = true;
|
||||
$this->_has['uniqueid'] = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* check if given file is a mbox file
|
||||
*
|
||||
* if $file is a resource its file pointer is moved after the first line
|
||||
*
|
||||
* @param resource|string $file stream resource of name of file
|
||||
* @param bool $fileIsString file is string or resource
|
||||
* @return bool file is mbox file
|
||||
*/
|
||||
protected function _isMboxFile($file, $fileIsString = true)
|
||||
{
|
||||
if ($fileIsString) {
|
||||
$file = @fopen($file, 'r');
|
||||
if (!$file) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
fseek($file, 0);
|
||||
}
|
||||
|
||||
$result = false;
|
||||
|
||||
$line = fgets($file);
|
||||
if (strpos($line, 'From ') === 0) {
|
||||
$result = true;
|
||||
}
|
||||
|
||||
if ($fileIsString) {
|
||||
@fclose($file);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* open given file as current mbox file
|
||||
*
|
||||
* @param string $filename filename of mbox file
|
||||
* @return null
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
protected function _openMboxFile($filename)
|
||||
{
|
||||
if ($this->_fh) {
|
||||
$this->close();
|
||||
}
|
||||
|
||||
$this->_fh = @fopen($filename, 'r');
|
||||
if (!$this->_fh) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception('cannot open mbox file');
|
||||
}
|
||||
$this->_filename = $filename;
|
||||
$this->_filemtime = filemtime($this->_filename);
|
||||
|
||||
if (!$this->_isMboxFile($this->_fh, false)) {
|
||||
@fclose($this->_fh);
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception('file is not a valid mbox format');
|
||||
}
|
||||
|
||||
$messagePos = array('start' => ftell($this->_fh), 'separator' => 0, 'end' => 0);
|
||||
while (($line = fgets($this->_fh)) !== false) {
|
||||
if (strpos($line, 'From ') === 0) {
|
||||
$messagePos['end'] = ftell($this->_fh) - strlen($line) - 2; // + newline
|
||||
if (!$messagePos['separator']) {
|
||||
$messagePos['separator'] = $messagePos['end'];
|
||||
}
|
||||
$this->_positions[] = $messagePos;
|
||||
$messagePos = array('start' => ftell($this->_fh), 'separator' => 0, 'end' => 0);
|
||||
}
|
||||
if (!$messagePos['separator'] && !trim($line)) {
|
||||
$messagePos['separator'] = ftell($this->_fh);
|
||||
}
|
||||
}
|
||||
|
||||
$messagePos['end'] = ftell($this->_fh);
|
||||
if (!$messagePos['separator']) {
|
||||
$messagePos['separator'] = $messagePos['end'];
|
||||
}
|
||||
$this->_positions[] = $messagePos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close resource for mail lib. If you need to control, when the resource
|
||||
* is closed. Otherwise the destructor would call this.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
@fclose($this->_fh);
|
||||
$this->_positions = array();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Waste some CPU cycles doing nothing.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function noop()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* stub for not supported message deletion
|
||||
*
|
||||
* @return null
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
public function removeMessage($id)
|
||||
{
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception('mbox is read-only');
|
||||
}
|
||||
|
||||
/**
|
||||
* get unique id for one or all messages
|
||||
*
|
||||
* Mbox does not support unique ids (yet) - it's always the same as the message number.
|
||||
* That shouldn't be a problem, because we can't change mbox files. Therefor the message
|
||||
* number is save enough.
|
||||
*
|
||||
* @param int|null $id message number
|
||||
* @return array|string message number for given message or all messages as array
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
public function getUniqueId($id = null)
|
||||
{
|
||||
if ($id) {
|
||||
// check if id exists
|
||||
$this->_getPos($id);
|
||||
return $id;
|
||||
}
|
||||
|
||||
$range = range(1, $this->countMessages());
|
||||
return array_combine($range, $range);
|
||||
}
|
||||
|
||||
/**
|
||||
* get a message number from a unique id
|
||||
*
|
||||
* I.e. if you have a webmailer that supports deleting messages you should use unique ids
|
||||
* as parameter and use this method to translate it to message number right before calling removeMessage()
|
||||
*
|
||||
* @param string $id unique id
|
||||
* @return int message number
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
public function getNumberByUniqueId($id)
|
||||
{
|
||||
// check if id exists
|
||||
$this->_getPos($id);
|
||||
return $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* magic method for serialize()
|
||||
*
|
||||
* with this method you can cache the mbox class
|
||||
*
|
||||
* @return array name of variables
|
||||
*/
|
||||
public function __sleep()
|
||||
{
|
||||
return array('_filename', '_positions', '_filemtime');
|
||||
}
|
||||
|
||||
/**
|
||||
* magic method for unserialize()
|
||||
*
|
||||
* with this method you can cache the mbox class
|
||||
* for cache validation the mtime of the mbox file is used
|
||||
*
|
||||
* @return null
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
public function __wakeup()
|
||||
{
|
||||
if ($this->_filemtime != @filemtime($this->_filename)) {
|
||||
$this->close();
|
||||
$this->_openMboxFile($this->_filename);
|
||||
} else {
|
||||
$this->_fh = @fopen($this->_filename, 'r');
|
||||
if (!$this->_fh) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception('cannot open mbox file');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,328 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @subpackage Storage
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Abstract
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Abstract.php';
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Protocol_Pop3
|
||||
*/
|
||||
require_once 'Zend/Mail/Protocol/Pop3.php';
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Message
|
||||
*/
|
||||
require_once 'Zend/Mail/Message.php';
|
||||
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @subpackage Storage
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Mail_Storage_Pop3 extends Postman_Zend_Mail_Storage_Abstract
|
||||
{
|
||||
/**
|
||||
* protocol handler
|
||||
* @var null|Postman_Zend_Mail_Protocol_Pop3
|
||||
*/
|
||||
protected $_protocol;
|
||||
|
||||
|
||||
/**
|
||||
* Count messages all messages in current box
|
||||
*
|
||||
* @return int number of messages
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
public function countMessages()
|
||||
{
|
||||
$this->_protocol->status($count, $null);
|
||||
return (int)$count;
|
||||
}
|
||||
|
||||
/**
|
||||
* get a list of messages with number and size
|
||||
*
|
||||
* @param int $id number of message
|
||||
* @return int|array size of given message of list with all messages as array(num => size)
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
public function getSize($id = 0)
|
||||
{
|
||||
$id = $id ? $id : null;
|
||||
return $this->_protocol->getList($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch a message
|
||||
*
|
||||
* @param int $id number of message
|
||||
* @return Postman_Zend_Mail_Message
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
public function getMessage($id)
|
||||
{
|
||||
$bodyLines = 0;
|
||||
$message = $this->_protocol->top($id, $bodyLines, true);
|
||||
|
||||
return new $this->_messageClass(array('handler' => $this, 'id' => $id, 'headers' => $message,
|
||||
'noToplines' => $bodyLines < 1));
|
||||
}
|
||||
|
||||
/*
|
||||
* Get raw header of message or part
|
||||
*
|
||||
* @param int $id number of message
|
||||
* @param null|array|string $part path to part or null for messsage header
|
||||
* @param int $topLines include this many lines with header (after an empty line)
|
||||
* @return string raw header
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
public function getRawHeader($id, $part = null, $topLines = 0)
|
||||
{
|
||||
if ($part !== null) {
|
||||
// TODO: implement
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception('not implemented');
|
||||
}
|
||||
|
||||
return $this->_protocol->top($id, 0, true);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get raw content of message or part
|
||||
*
|
||||
* @param int $id number of message
|
||||
* @param null|array|string $part path to part or null for messsage content
|
||||
* @return string raw content
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
public function getRawContent($id, $part = null)
|
||||
{
|
||||
if ($part !== null) {
|
||||
// TODO: implement
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception('not implemented');
|
||||
}
|
||||
|
||||
$content = $this->_protocol->retrieve($id);
|
||||
// TODO: find a way to avoid decoding the headers
|
||||
Postman_Zend_Mime_Decode::splitMessage($content, $null, $body);
|
||||
return $body;
|
||||
}
|
||||
|
||||
/**
|
||||
* create instance with parameters
|
||||
* Supported paramters are
|
||||
* - host hostname or ip address of POP3 server
|
||||
* - user username
|
||||
* - password password for user 'username' [optional, default = '']
|
||||
* - port port for POP3 server [optional, default = 110]
|
||||
* - ssl 'SSL' or 'TLS' for secure sockets
|
||||
*
|
||||
* @param array $params mail reader specific parameters
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
public function __construct($params)
|
||||
{
|
||||
if (is_array($params)) {
|
||||
$params = (object)$params;
|
||||
}
|
||||
|
||||
$this->_has['fetchPart'] = false;
|
||||
$this->_has['top'] = null;
|
||||
$this->_has['uniqueid'] = null;
|
||||
|
||||
if ($params instanceof Postman_Zend_Mail_Protocol_Pop3) {
|
||||
$this->_protocol = $params;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isset($params->user)) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception('need at least user in params');
|
||||
}
|
||||
|
||||
$host = isset($params->host) ? $params->host : 'localhost';
|
||||
$password = isset($params->password) ? $params->password : '';
|
||||
$port = isset($params->port) ? $params->port : null;
|
||||
$ssl = isset($params->ssl) ? $params->ssl : false;
|
||||
|
||||
$this->_protocol = new Postman_Zend_Mail_Protocol_Pop3();
|
||||
$this->_protocol->connect($host, $port, $ssl);
|
||||
$this->_protocol->login($params->user, $password);
|
||||
}
|
||||
|
||||
/**
|
||||
* Close resource for mail lib. If you need to control, when the resource
|
||||
* is closed. Otherwise the destructor would call this.
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
$this->_protocol->logout();
|
||||
}
|
||||
|
||||
/**
|
||||
* Keep the server busy.
|
||||
*
|
||||
* @return null
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
public function noop()
|
||||
{
|
||||
return $this->_protocol->noop();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a message from server. If you're doing that from a web enviroment
|
||||
* you should be careful and use a uniqueid as parameter if possible to
|
||||
* identify the message.
|
||||
*
|
||||
* @param int $id number of message
|
||||
* @return null
|
||||
* @throws Postman_Zend_Mail_Protocol_Exception
|
||||
*/
|
||||
public function removeMessage($id)
|
||||
{
|
||||
$this->_protocol->delete($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* get unique id for one or all messages
|
||||
*
|
||||
* if storage does not support unique ids it's the same as the message number
|
||||
*
|
||||
* @param int|null $id message number
|
||||
* @return array|string message number for given message or all messages as array
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
public function getUniqueId($id = null)
|
||||
{
|
||||
if (!$this->hasUniqueid) {
|
||||
if ($id) {
|
||||
return $id;
|
||||
}
|
||||
$count = $this->countMessages();
|
||||
if ($count < 1) {
|
||||
return array();
|
||||
}
|
||||
$range = range(1, $count);
|
||||
return array_combine($range, $range);
|
||||
}
|
||||
|
||||
return $this->_protocol->uniqueid($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* get a message number from a unique id
|
||||
*
|
||||
* I.e. if you have a webmailer that supports deleting messages you should use unique ids
|
||||
* as parameter and use this method to translate it to message number right before calling removeMessage()
|
||||
*
|
||||
* @param string $id unique id
|
||||
* @return int message number
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
public function getNumberByUniqueId($id)
|
||||
{
|
||||
if (!$this->hasUniqueid) {
|
||||
return $id;
|
||||
}
|
||||
|
||||
$ids = $this->getUniqueId();
|
||||
foreach ($ids as $k => $v) {
|
||||
if ($v == $id) {
|
||||
return $k;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
require_once 'Zend/Mail/Storage/Exception.php';
|
||||
throw new Postman_Zend_Mail_Storage_Exception('unique id not found');
|
||||
}
|
||||
|
||||
/**
|
||||
* Special handling for hasTop and hasUniqueid. The headers of the first message is
|
||||
* retrieved if Top wasn't needed/tried yet.
|
||||
*
|
||||
* @see Postman_Zend_Mail_Storage_Abstract:__get()
|
||||
* @param string $var
|
||||
* @return string
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
public function __get($var)
|
||||
{
|
||||
$result = parent::__get($var);
|
||||
if ($result !== null) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
if (strtolower($var) == 'hastop') {
|
||||
if ($this->_protocol->hasTop === null) {
|
||||
// need to make a real call, because not all server are honest in their capas
|
||||
try {
|
||||
$this->_protocol->top(1, 0, false);
|
||||
} catch(Postman_Zend_Mail_Exception $e) {
|
||||
// ignoring error
|
||||
}
|
||||
}
|
||||
$this->_has['top'] = $this->_protocol->hasTop;
|
||||
return $this->_protocol->hasTop;
|
||||
}
|
||||
|
||||
if (strtolower($var) == 'hasuniqueid') {
|
||||
$id = null;
|
||||
try {
|
||||
$id = $this->_protocol->uniqueid(1);
|
||||
} catch(Postman_Zend_Mail_Exception $e) {
|
||||
// ignoring error
|
||||
}
|
||||
$this->_has['uniqueid'] = $id ? true : false;
|
||||
return $this->_has['uniqueid'];
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @subpackage Storage
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @subpackage Storage
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
interface Postman_Zend_Mail_Storage_Writable_Interface
|
||||
{
|
||||
/**
|
||||
* create a new folder
|
||||
*
|
||||
* This method also creates parent folders if necessary. Some mail storages may restrict, which folder
|
||||
* may be used as parent or which chars may be used in the folder name
|
||||
*
|
||||
* @param string $name global name of folder, local name if $parentFolder is set
|
||||
* @param string|Postman_Zend_Mail_Storage_Folder $parentFolder parent folder for new folder, else root folder is parent
|
||||
* @return null
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
public function createFolder($name, $parentFolder = null);
|
||||
|
||||
/**
|
||||
* remove a folder
|
||||
*
|
||||
* @param string|Postman_Zend_Mail_Storage_Folder $name name or instance of folder
|
||||
* @return null
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
public function removeFolder($name);
|
||||
|
||||
/**
|
||||
* rename and/or move folder
|
||||
*
|
||||
* The new name has the same restrictions as in createFolder()
|
||||
*
|
||||
* @param string|Postman_Zend_Mail_Storage_Folder $oldName name or instance of folder
|
||||
* @param string $newName new global name of folder
|
||||
* @return null
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
public function renameFolder($oldName, $newName);
|
||||
|
||||
/**
|
||||
* append a new message to mail storage
|
||||
*
|
||||
* @param string|Postman_Zend_Mail_Message|Postman_Zend_Mime_Message $message message as string or instance of message class
|
||||
* @param null|string|Postman_Zend_Mail_Storage_Folder $folder folder for new message, else current folder is taken
|
||||
* @param null|array $flags set flags for new message, else a default set is used
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
public function appendMessage($message, $folder = null, $flags = null);
|
||||
|
||||
/**
|
||||
* copy an existing message
|
||||
*
|
||||
* @param int $id number of message
|
||||
* @param string|Postman_Zend_Mail_Storage_Folder $folder name or instance of targer folder
|
||||
* @return null
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
public function copyMessage($id, $folder);
|
||||
|
||||
/**
|
||||
* move an existing message
|
||||
*
|
||||
* @param int $id number of message
|
||||
* @param string|Postman_Zend_Mail_Storage_Folder $folder name or instance of targer folder
|
||||
* @return null
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
public function moveMessage($id, $folder);
|
||||
|
||||
/**
|
||||
* set flags for message
|
||||
*
|
||||
* NOTE: this method can't set the recent flag.
|
||||
*
|
||||
* @param int $id number of message
|
||||
* @param array $flags new flags for message
|
||||
* @throws Postman_Zend_Mail_Storage_Exception
|
||||
*/
|
||||
public function setFlags($id, $flags);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,366 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @subpackage Transport
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Mime
|
||||
*/
|
||||
// require_once 'Zend/Mime.php';
|
||||
|
||||
|
||||
/**
|
||||
* Abstract for sending eMails through different
|
||||
* ways of transport
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @subpackage Transport
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
abstract class Postman_Zend_Mail_Transport_Abstract
|
||||
{
|
||||
/**
|
||||
* Mail body
|
||||
* @var string
|
||||
* @access public
|
||||
*/
|
||||
public $body = '';
|
||||
|
||||
/**
|
||||
* MIME boundary
|
||||
* @var string
|
||||
* @access public
|
||||
*/
|
||||
public $boundary = '';
|
||||
|
||||
/**
|
||||
* Mail header string
|
||||
* @var string
|
||||
* @access public
|
||||
*/
|
||||
public $header = '';
|
||||
|
||||
/**
|
||||
* Array of message headers
|
||||
* @var array
|
||||
* @access protected
|
||||
*/
|
||||
protected $_headers = array();
|
||||
|
||||
/**
|
||||
* Message is a multipart message
|
||||
* @var boolean
|
||||
* @access protected
|
||||
*/
|
||||
protected $_isMultipart = false;
|
||||
|
||||
/**
|
||||
* Postman_Zend_Mail object
|
||||
* @var false|Postman_Zend_Mail
|
||||
* @access protected
|
||||
*/
|
||||
protected $_mail = false;
|
||||
|
||||
/**
|
||||
* Array of message parts
|
||||
* @var array
|
||||
* @access protected
|
||||
*/
|
||||
protected $_parts = array();
|
||||
|
||||
/**
|
||||
* Recipients string
|
||||
* @var string
|
||||
* @access public
|
||||
*/
|
||||
public $recipients = '';
|
||||
|
||||
/**
|
||||
* EOL character string used by transport
|
||||
* @var string
|
||||
* @access public
|
||||
*/
|
||||
public $EOL = "\r\n";
|
||||
|
||||
/**
|
||||
* Send an email independent from the used transport
|
||||
*
|
||||
* The requisite information for the email will be found in the following
|
||||
* properties:
|
||||
*
|
||||
* - {@link $recipients} - list of recipients (string)
|
||||
* - {@link $header} - message header
|
||||
* - {@link $body} - message body
|
||||
*/
|
||||
abstract protected function _sendMail();
|
||||
|
||||
/**
|
||||
* Return all mail headers as an array
|
||||
*
|
||||
* If a boundary is given, a multipart header is generated with a
|
||||
* Content-Type of either multipart/alternative or multipart/mixed depending
|
||||
* on the mail parts present in the {@link $_mail Postman_Zend_Mail object} present.
|
||||
*
|
||||
* @param string $boundary
|
||||
* @return array
|
||||
*/
|
||||
protected function _getHeaders($boundary)
|
||||
{
|
||||
if (null !== $boundary) {
|
||||
// Build multipart mail
|
||||
$type = $this->_mail->getType();
|
||||
if (!$type) {
|
||||
if ($this->_mail->hasAttachments) {
|
||||
$type = Postman_Zend_Mime::MULTIPART_MIXED;
|
||||
} elseif ($this->_mail->getBodyText() && $this->_mail->getBodyHtml() ) {
|
||||
$type = Postman_Zend_Mime::MULTIPART_ALTERNATIVE;
|
||||
} else {
|
||||
$type = Postman_Zend_Mime::MULTIPART_MIXED;
|
||||
}
|
||||
}
|
||||
|
||||
$this->_headers['Content-Type'] = array(
|
||||
$type . ';'
|
||||
. $this->EOL
|
||||
. " " . 'boundary="' . $boundary . '"'
|
||||
);
|
||||
$this->boundary = $boundary;
|
||||
}
|
||||
|
||||
$this->_headers['MIME-Version'] = array('1.0');
|
||||
|
||||
return $this->_headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepend header name to header value
|
||||
*
|
||||
* @param string $item
|
||||
* @param string $key
|
||||
* @param string $prefix
|
||||
* @static
|
||||
* @access protected
|
||||
* @return void
|
||||
*/
|
||||
protected static function _formatHeader(&$item, $key, $prefix)
|
||||
{
|
||||
$item = $prefix . ': ' . $item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare header string for use in transport
|
||||
*
|
||||
* Prepares and generates {@link $header} based on the headers provided.
|
||||
*
|
||||
* @param mixed $headers
|
||||
* @access protected
|
||||
* @return void
|
||||
* @throws Postman_Zend_Mail_Transport_Exception if any header lines exceed 998
|
||||
* characters
|
||||
*/
|
||||
protected function _prepareHeaders($headers)
|
||||
{
|
||||
if (!$this->_mail) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Transport_Exception
|
||||
*/
|
||||
require_once 'Exception.php';
|
||||
throw new Postman_Zend_Mail_Transport_Exception('Missing Postman_Zend_Mail object in _mail property');
|
||||
}
|
||||
|
||||
if( PostmanOptions::getInstance()->is_php_compatibility_enabled() ) {
|
||||
|
||||
add_filter( 'post_smtp_incompatible_php', '__return_true' );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter to manage \r\n compalibility issues with some PHP versions
|
||||
*
|
||||
* @since 2.4.5
|
||||
* @version 1.0.0
|
||||
*/
|
||||
$incompatible_php = apply_filters( 'post_smtp_incompatible_php', false );
|
||||
|
||||
$this->header = '';
|
||||
|
||||
foreach ($headers as $header => $content) {
|
||||
if (isset($content['append'])) {
|
||||
unset($content['append']);
|
||||
$value = implode(',' . $this->EOL . ' ', $content);
|
||||
$this->header .= $incompatible_php ? $header . ': ' . $value . "\r\n" : $header . ': ' . $value . $this->EOL;
|
||||
} else {
|
||||
|
||||
array_walk($content, array(get_class($this), '_formatHeader'), $header);
|
||||
$this->header .= $incompatible_php ? implode($this->EOL, $content) . "\r\n" : implode($this->EOL, $content) . $this->EOL;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Sanity check on headers -- should not be > 998 characters
|
||||
$sane = true;
|
||||
foreach (explode($this->EOL, $this->header) as $line) {
|
||||
if (strlen(trim($line)) > 998) {
|
||||
$sane = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!$sane) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Transport_Exception
|
||||
*/
|
||||
require_once 'Exception.php';
|
||||
throw new Postman_Zend_Mail_Exception('At least one mail header line is too long');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate MIME compliant message from the current configuration
|
||||
*
|
||||
* If both a text and HTML body are present, generates a
|
||||
* multipart/alternative Postman_Zend_Mime_Part containing the headers and contents
|
||||
* of each. Otherwise, uses whichever of the text or HTML parts present.
|
||||
*
|
||||
* The content part is then prepended to the list of Postman_Zend_Mime_Parts for
|
||||
* this message.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function _buildBody()
|
||||
{
|
||||
if (($text = $this->_mail->getBodyText())
|
||||
&& ($html = $this->_mail->getBodyHtml()))
|
||||
{
|
||||
// Generate unique boundary for multipart/alternative
|
||||
$mime = new Postman_Zend_Mime(null);
|
||||
$boundaryLine = $mime->boundaryLine($this->EOL);
|
||||
$boundaryEnd = $mime->mimeEnd($this->EOL);
|
||||
|
||||
$text->disposition = false;
|
||||
$html->disposition = false;
|
||||
|
||||
$body = $boundaryLine
|
||||
. $text->getHeaders($this->EOL)
|
||||
. $this->EOL
|
||||
. $text->getContent($this->EOL)
|
||||
. $this->EOL
|
||||
. $boundaryLine
|
||||
. $html->getHeaders($this->EOL)
|
||||
. $this->EOL
|
||||
. $html->getContent($this->EOL)
|
||||
. $this->EOL
|
||||
. $boundaryEnd;
|
||||
|
||||
$mp = new Postman_Zend_Mime_Part($body);
|
||||
$mp->type = Postman_Zend_Mime::MULTIPART_ALTERNATIVE;
|
||||
$mp->boundary = $mime->boundary();
|
||||
|
||||
$this->_isMultipart = true;
|
||||
|
||||
// Ensure first part contains text alternatives
|
||||
array_unshift($this->_parts, $mp);
|
||||
|
||||
// Get headers
|
||||
$this->_headers = $this->_mail->getHeaders();
|
||||
return;
|
||||
}
|
||||
|
||||
// If not multipart, then get the body
|
||||
if (false !== ($body = $this->_mail->getBodyHtml())) {
|
||||
array_unshift($this->_parts, $body);
|
||||
} elseif (false !== ($body = $this->_mail->getBodyText())) {
|
||||
array_unshift($this->_parts, $body);
|
||||
}
|
||||
|
||||
if (!$body) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Transport_Exception
|
||||
*/
|
||||
require_once 'Exception.php';
|
||||
throw new Postman_Zend_Mail_Transport_Exception('This email has empty body');
|
||||
}
|
||||
|
||||
// Get headers
|
||||
$this->_headers = $this->_mail->getHeaders();
|
||||
$headers = $body->getHeadersArray($this->EOL);
|
||||
foreach ($headers as $header) {
|
||||
// Headers in Postman_Zend_Mime_Part are kept as arrays with two elements, a
|
||||
// key and a value
|
||||
$this->_headers[$header[0]] = array($header[1]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a mail using this transport
|
||||
*
|
||||
* @param Postman_Zend_Mail $mail
|
||||
* @access public
|
||||
* @return void
|
||||
* @throws Postman_Zend_Mail_Transport_Exception if mail is empty
|
||||
*/
|
||||
public function send(Postman_Zend_Mail $mail)
|
||||
{
|
||||
$this->_isMultipart = false;
|
||||
$this->_mail = $mail;
|
||||
$this->_parts = $mail->getParts();
|
||||
$mime = $mail->getMime();
|
||||
|
||||
// Build body content
|
||||
$this->_buildBody();
|
||||
|
||||
// Determine number of parts and boundary
|
||||
$count = count($this->_parts);
|
||||
$boundary = null;
|
||||
if ($count < 1) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Transport_Exception
|
||||
*/
|
||||
require_once 'Exception.php';
|
||||
throw new Postman_Zend_Mail_Transport_Exception('Empty mail cannot be sent');
|
||||
}
|
||||
|
||||
if ($count > 1) {
|
||||
// Multipart message; create new MIME object and boundary
|
||||
$mime = new Postman_Zend_Mime($this->_mail->getMimeBoundary());
|
||||
$boundary = $mime->boundary();
|
||||
} elseif ($this->_isMultipart) {
|
||||
// multipart/alternative -- grab boundary
|
||||
$boundary = $this->_parts[0]->boundary;
|
||||
}
|
||||
|
||||
// Determine recipients, and prepare headers
|
||||
$this->recipients = implode(',', $mail->getRecipients());
|
||||
$this->_prepareHeaders($this->_getHeaders($boundary));
|
||||
|
||||
// Create message body
|
||||
// This is done so that the same Postman_Zend_Mail object can be used in
|
||||
// multiple transports
|
||||
$message = new Postman_Zend_Mime_Message();
|
||||
$message->setParts($this->_parts);
|
||||
$message->setMime($mime);
|
||||
$this->body = $message->generateMessage($this->EOL);
|
||||
|
||||
// Send to transport!
|
||||
$this->_sendMail();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @subpackage Transport
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Exception
|
||||
*/
|
||||
// require_once 'Zend/Mail/Exception.php';
|
||||
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @subpackage Transport
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Mail_Transport_Exception extends Postman_Zend_Mail_Exception
|
||||
{}
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @subpackage Transport
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Transport_Abstract
|
||||
*/
|
||||
require_once 'Zend/Mail/Transport/Abstract.php';
|
||||
|
||||
|
||||
/**
|
||||
* File transport
|
||||
*
|
||||
* Class for saving outgoing emails in filesystem
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @subpackage Transport
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Mail_Transport_File extends Postman_Zend_Mail_Transport_Abstract
|
||||
{
|
||||
/**
|
||||
* Target directory for saving sent email messages
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_path;
|
||||
|
||||
/**
|
||||
* Callback function generating a file name
|
||||
*
|
||||
* @var string|array
|
||||
*/
|
||||
protected $_callback;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param array|Postman_Zend_Config $options OPTIONAL (Default: null)
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($options = null)
|
||||
{
|
||||
if ($options instanceof Postman_Zend_Config) {
|
||||
$options = $options->toArray();
|
||||
} elseif (!is_array($options)) {
|
||||
$options = array();
|
||||
}
|
||||
|
||||
// Making sure we have some defaults to work with
|
||||
if (!isset($options['path'])) {
|
||||
$options['path'] = sys_get_temp_dir();
|
||||
}
|
||||
if (!isset($options['callback'])) {
|
||||
$options['callback'] = array($this, 'defaultCallback');
|
||||
}
|
||||
|
||||
$this->setOptions($options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets options
|
||||
*
|
||||
* @param array $options
|
||||
* @return void
|
||||
*/
|
||||
public function setOptions(array $options)
|
||||
{
|
||||
if (isset($options['path']) && is_dir($options['path'])) {
|
||||
$this->_path = $options['path'];
|
||||
}
|
||||
if (isset($options['callback']) && is_callable($options['callback'])) {
|
||||
$this->_callback = $options['callback'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves e-mail message to a file
|
||||
*
|
||||
* @return void
|
||||
* @throws Postman_Zend_Mail_Transport_Exception on not writable target directory
|
||||
* @throws Postman_Zend_Mail_Transport_Exception on file_put_contents() failure
|
||||
*/
|
||||
protected function _sendMail()
|
||||
{
|
||||
$file = $this->_path . DIRECTORY_SEPARATOR . call_user_func($this->_callback, $this);
|
||||
|
||||
if (!is_writable(dirname($file))) {
|
||||
require_once 'Zend/Mail/Transport/Exception.php';
|
||||
throw new Postman_Zend_Mail_Transport_Exception(sprintf(
|
||||
'Target directory "%s" does not exist or is not writable',
|
||||
dirname($file)
|
||||
));
|
||||
}
|
||||
|
||||
$email = $this->header . $this->EOL . $this->body;
|
||||
|
||||
if (!file_put_contents($file, $email)) {
|
||||
require_once 'Zend/Mail/Transport/Exception.php';
|
||||
throw new Postman_Zend_Mail_Transport_Exception('Unable to send mail');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Default callback for generating filenames
|
||||
*
|
||||
* @param Postman_Zend_Mail_Transport_File File transport instance
|
||||
* @return string
|
||||
*/
|
||||
public function defaultCallback($transport)
|
||||
{
|
||||
return 'ZendMail_' . $_SERVER['REQUEST_TIME'] . '_' . mt_rand() . '.tmp';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,220 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @subpackage Transport
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Transport_Abstract
|
||||
*/
|
||||
// require_once 'Zend/Mail/Transport/Abstract.php';
|
||||
|
||||
|
||||
/**
|
||||
* Class for sending eMails via the PHP internal mail() function
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @subpackage Transport
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Mail_Transport_Sendmail extends Postman_Zend_Mail_Transport_Abstract
|
||||
{
|
||||
/**
|
||||
* Subject
|
||||
* @var string
|
||||
* @access public
|
||||
*/
|
||||
public $subject = null;
|
||||
|
||||
|
||||
/**
|
||||
* Config options for sendmail parameters
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $parameters;
|
||||
|
||||
/**
|
||||
* EOL character string
|
||||
* @var string
|
||||
* @access public
|
||||
*/
|
||||
public $EOL = PHP_EOL;
|
||||
|
||||
/**
|
||||
* error information
|
||||
* @var string
|
||||
*/
|
||||
protected $_errstr;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string|array|Postman_Zend_Config $parameters OPTIONAL (Default: null)
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($parameters = null)
|
||||
{
|
||||
if ($parameters instanceof Postman_Zend_Config) {
|
||||
$parameters = $parameters->toArray();
|
||||
}
|
||||
|
||||
if (is_array($parameters)) {
|
||||
$parameters = implode(' ', $parameters);
|
||||
}
|
||||
|
||||
$this->parameters = $parameters;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Send mail using PHP native mail()
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
* @throws Postman_Zend_Mail_Transport_Exception if parameters is set
|
||||
* but not a string
|
||||
* @throws Postman_Zend_Mail_Transport_Exception on mail() failure
|
||||
*/
|
||||
public function _sendMail()
|
||||
{
|
||||
if ($this->parameters === null) {
|
||||
set_error_handler(array($this, '_handleMailErrors'));
|
||||
$result = mail(
|
||||
$this->recipients,
|
||||
$this->_mail->getSubject(),
|
||||
$this->body,
|
||||
$this->header);
|
||||
restore_error_handler();
|
||||
} else {
|
||||
if(!is_string($this->parameters)) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Transport_Exception
|
||||
*
|
||||
* Exception is thrown here because
|
||||
* $parameters is a public property
|
||||
*/
|
||||
// require_once 'Zend/Mail/Transport/Exception.php';
|
||||
throw new Postman_Zend_Mail_Transport_Exception(
|
||||
'Parameters were set but are not a string'
|
||||
);
|
||||
}
|
||||
|
||||
set_error_handler(array($this, '_handleMailErrors'));
|
||||
$result = mail(
|
||||
$this->recipients,
|
||||
$this->_mail->getSubject(),
|
||||
$this->body,
|
||||
$this->header,
|
||||
$this->parameters);
|
||||
restore_error_handler();
|
||||
}
|
||||
|
||||
if ($this->_errstr !== null || !$result) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Transport_Exception
|
||||
*/
|
||||
// require_once 'Zend/Mail/Transport/Exception.php';
|
||||
throw new Postman_Zend_Mail_Transport_Exception('Unable to send mail. ' . $this->_errstr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Format and fix headers
|
||||
*
|
||||
* mail() uses its $to and $subject arguments to set the To: and Subject:
|
||||
* headers, respectively. This method strips those out as a sanity check to
|
||||
* prevent duplicate header entries.
|
||||
*
|
||||
* @access protected
|
||||
* @param array $headers
|
||||
* @return void
|
||||
* @throws Postman_Zend_Mail_Transport_Exception
|
||||
*/
|
||||
protected function _prepareHeaders($headers)
|
||||
{
|
||||
if (!$this->_mail) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Transport_Exception
|
||||
*/
|
||||
// require_once 'Zend/Mail/Transport/Exception.php';
|
||||
throw new Postman_Zend_Mail_Transport_Exception('_prepareHeaders requires a registered Postman_Zend_Mail object');
|
||||
}
|
||||
|
||||
// mail() uses its $to parameter to set the To: header, and the $subject
|
||||
// parameter to set the Subject: header. We need to strip them out.
|
||||
if (0 === strpos(PHP_OS, 'WIN')) {
|
||||
// If the current recipients list is empty, throw an error
|
||||
if (empty($this->recipients)) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Transport_Exception
|
||||
*/
|
||||
// require_once 'Zend/Mail/Transport/Exception.php';
|
||||
throw new Postman_Zend_Mail_Transport_Exception('Missing To addresses');
|
||||
}
|
||||
} else {
|
||||
// All others, simply grab the recipients and unset the To: header
|
||||
if (!isset($headers['To'])) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Transport_Exception
|
||||
*/
|
||||
// require_once 'Zend/Mail/Transport/Exception.php';
|
||||
throw new Postman_Zend_Mail_Transport_Exception('Missing To header');
|
||||
}
|
||||
|
||||
unset($headers['To']['append']);
|
||||
$this->recipients = implode(',', $headers['To']);
|
||||
}
|
||||
|
||||
// Remove recipient header
|
||||
unset($headers['To']);
|
||||
|
||||
// Remove subject header, if present
|
||||
if (isset($headers['Subject'])) {
|
||||
unset($headers['Subject']);
|
||||
}
|
||||
|
||||
// Prepare headers
|
||||
parent::_prepareHeaders($headers);
|
||||
|
||||
// Fix issue with empty blank line ontop when using Sendmail Trnasport
|
||||
$this->header = rtrim($this->header);
|
||||
}
|
||||
|
||||
/**
|
||||
* Temporary error handler for PHP native mail().
|
||||
*
|
||||
* @param int $errno
|
||||
* @param string $errstr
|
||||
* @param string $errfile
|
||||
* @param string $errline
|
||||
* @param array $errcontext
|
||||
* @return true
|
||||
*/
|
||||
public function _handleMailErrors($errno, $errstr, $errfile = null, $errline = null, ?array $errcontext = null)
|
||||
{
|
||||
$this->_errstr = $errstr;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,247 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @subpackage Transport
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Mime
|
||||
*/
|
||||
// require_once 'Zend/Mime.php';
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Protocol_Smtp
|
||||
*/
|
||||
// require_once 'Zend/Mail/Protocol/Smtp.php';
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Transport_Abstract
|
||||
*/
|
||||
// require_once 'Zend/Mail/Transport/Abstract.php';
|
||||
|
||||
|
||||
/**
|
||||
* SMTP connection object
|
||||
*
|
||||
* Loads an instance of Postman_Zend_Mail_Protocol_Smtp and forwards smtp transactions
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mail
|
||||
* @subpackage Transport
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Mail_Transport_Smtp extends Postman_Zend_Mail_Transport_Abstract
|
||||
{
|
||||
/**
|
||||
* EOL character string used by transport
|
||||
* @var string
|
||||
* @access public
|
||||
*/
|
||||
public $EOL = "\n";
|
||||
|
||||
/**
|
||||
* Remote smtp hostname or i.p.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_host;
|
||||
|
||||
|
||||
/**
|
||||
* Port number
|
||||
*
|
||||
* @var integer|null
|
||||
*/
|
||||
protected $_port;
|
||||
|
||||
|
||||
/**
|
||||
* Local client hostname or i.p.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_name = 'localhost';
|
||||
|
||||
|
||||
/**
|
||||
* Authentication type OPTIONAL
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_auth;
|
||||
|
||||
|
||||
/**
|
||||
* Config options for authentication
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_config;
|
||||
|
||||
|
||||
/**
|
||||
* Instance of Postman_Zend_Mail_Protocol_Smtp
|
||||
*
|
||||
* @var Postman_Zend_Mail_Protocol_Smtp
|
||||
*/
|
||||
protected $_connection;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $host OPTIONAL (Default: 127.0.0.1)
|
||||
* @param array|null $config OPTIONAL (Default: null)
|
||||
* @return void
|
||||
*
|
||||
* @todo Someone please make this compatible
|
||||
* with the SendMail transport class.
|
||||
*/
|
||||
public function __construct($host = '127.0.0.1', Array $config = array())
|
||||
{
|
||||
if (isset($config['name'])) {
|
||||
$this->_name = $config['name'];
|
||||
} else {
|
||||
$this->_name = PostmanUtils::getServerName();
|
||||
}
|
||||
|
||||
if (isset($config['port'])) {
|
||||
$this->_port = $config['port'];
|
||||
}
|
||||
|
||||
if (isset($config['auth'])) {
|
||||
$this->_auth = $config['auth'];
|
||||
}
|
||||
|
||||
$this->_host = $host;
|
||||
$this->_config = $config;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Class destructor to ensure all open connections are closed
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
if ($this->_connection instanceof Postman_Zend_Mail_Protocol_Smtp) {
|
||||
try {
|
||||
$this->_connection->quit();
|
||||
} catch (Postman_Zend_Mail_Protocol_Exception $e) {
|
||||
// ignore
|
||||
}
|
||||
$this->_connection->disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the connection protocol instance
|
||||
*
|
||||
* @param Postman_Zend_Mail_Protocol_Abstract $client
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setConnection(Postman_Zend_Mail_Protocol_Abstract $connection)
|
||||
{
|
||||
$this->_connection = $connection;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the connection protocol instance
|
||||
*
|
||||
* @return Postman_Zend_Mail_Protocol|null
|
||||
*/
|
||||
public function getConnection()
|
||||
{
|
||||
return $this->_connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an email via the SMTP connection protocol
|
||||
*
|
||||
* The connection via the protocol adapter is made just-in-time to allow a
|
||||
* developer to add a custom adapter if required before mail is sent.
|
||||
*
|
||||
* @return void
|
||||
* @todo Rename this to sendMail, it's a public method...
|
||||
*/
|
||||
public function _sendMail()
|
||||
{
|
||||
// If sending multiple messages per session use existing adapter
|
||||
if (!($this->_connection instanceof Postman_Zend_Mail_Protocol_Smtp)) {
|
||||
// Check if authentication is required and determine required class
|
||||
$connectionClass = 'Postman_Zend_Mail_Protocol_Smtp';
|
||||
if ($this->_auth) {
|
||||
$connectionClass .= '_Auth_' . ucwords($this->_auth);
|
||||
}
|
||||
if (!class_exists($connectionClass)) {
|
||||
// require_once 'Zend/Loader.php';
|
||||
// Postman_Zend_Loader::loadClass($connectionClass);
|
||||
}
|
||||
$this->setConnection(new $connectionClass($this->_host, $this->_port, $this->_config));
|
||||
$this->_connection->connect();
|
||||
$this->_connection->helo($this->_name);
|
||||
} else {
|
||||
// Reset connection to ensure reliable transaction
|
||||
$this->_connection->rset();
|
||||
}
|
||||
|
||||
// Set sender email address
|
||||
$this->_connection->mail($this->_mail->getReturnPath());
|
||||
|
||||
// Set recipient forward paths
|
||||
foreach ($this->_mail->getRecipients() as $recipient) {
|
||||
$this->_connection->rcpt($recipient);
|
||||
}
|
||||
|
||||
// Issue DATA command to client
|
||||
$this->_connection->data($this->header . Postman_Zend_Mime::LINEEND . $this->body);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format and fix headers
|
||||
*
|
||||
* Some SMTP servers do not strip BCC headers. Most clients do it themselves as do we.
|
||||
*
|
||||
* @access protected
|
||||
* @param array $headers
|
||||
* @return void
|
||||
* @throws Postman_Zend_Transport_Exception
|
||||
*/
|
||||
protected function _prepareHeaders($headers)
|
||||
{
|
||||
if (!$this->_mail) {
|
||||
/**
|
||||
* @see Postman_Zend_Mail_Transport_Exception
|
||||
*/
|
||||
// require_once 'Zend/Mail/Transport/Exception.php';
|
||||
throw new Postman_Zend_Mail_Transport_Exception('_prepareHeaders requires a registered Postman_Zend_Mail object');
|
||||
}
|
||||
|
||||
unset($headers['Bcc']);
|
||||
|
||||
// Prepare headers
|
||||
parent::_prepareHeaders($headers);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,670 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mime
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* Support class for MultiPart Mime Messages
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mime
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Mime
|
||||
{
|
||||
const TYPE_OCTETSTREAM = 'application/octet-stream';
|
||||
const TYPE_TEXT = 'text/plain';
|
||||
const TYPE_HTML = 'text/html';
|
||||
const ENCODING_7BIT = '7bit';
|
||||
const ENCODING_8BIT = '8bit';
|
||||
const ENCODING_QUOTEDPRINTABLE = 'quoted-printable';
|
||||
const ENCODING_BASE64 = 'base64';
|
||||
const DISPOSITION_ATTACHMENT = 'attachment';
|
||||
const DISPOSITION_INLINE = 'inline';
|
||||
const LINELENGTH = 72;
|
||||
const LINEEND = "\n";
|
||||
const MULTIPART_ALTERNATIVE = 'multipart/alternative';
|
||||
const MULTIPART_MIXED = 'multipart/mixed';
|
||||
const MULTIPART_RELATED = 'multipart/related';
|
||||
|
||||
/**
|
||||
* Boundary
|
||||
*
|
||||
* @var null|string
|
||||
*/
|
||||
protected $_boundary;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected static $makeUnique = 0;
|
||||
|
||||
/**
|
||||
* Lookup-Tables for QuotedPrintable
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $qpKeys = array(
|
||||
"\x00",
|
||||
"\x01",
|
||||
"\x02",
|
||||
"\x03",
|
||||
"\x04",
|
||||
"\x05",
|
||||
"\x06",
|
||||
"\x07",
|
||||
"\x08",
|
||||
"\x09",
|
||||
"\x0A",
|
||||
"\x0B",
|
||||
"\x0C",
|
||||
"\x0D",
|
||||
"\x0E",
|
||||
"\x0F",
|
||||
"\x10",
|
||||
"\x11",
|
||||
"\x12",
|
||||
"\x13",
|
||||
"\x14",
|
||||
"\x15",
|
||||
"\x16",
|
||||
"\x17",
|
||||
"\x18",
|
||||
"\x19",
|
||||
"\x1A",
|
||||
"\x1B",
|
||||
"\x1C",
|
||||
"\x1D",
|
||||
"\x1E",
|
||||
"\x1F",
|
||||
"\x7F",
|
||||
"\x80",
|
||||
"\x81",
|
||||
"\x82",
|
||||
"\x83",
|
||||
"\x84",
|
||||
"\x85",
|
||||
"\x86",
|
||||
"\x87",
|
||||
"\x88",
|
||||
"\x89",
|
||||
"\x8A",
|
||||
"\x8B",
|
||||
"\x8C",
|
||||
"\x8D",
|
||||
"\x8E",
|
||||
"\x8F",
|
||||
"\x90",
|
||||
"\x91",
|
||||
"\x92",
|
||||
"\x93",
|
||||
"\x94",
|
||||
"\x95",
|
||||
"\x96",
|
||||
"\x97",
|
||||
"\x98",
|
||||
"\x99",
|
||||
"\x9A",
|
||||
"\x9B",
|
||||
"\x9C",
|
||||
"\x9D",
|
||||
"\x9E",
|
||||
"\x9F",
|
||||
"\xA0",
|
||||
"\xA1",
|
||||
"\xA2",
|
||||
"\xA3",
|
||||
"\xA4",
|
||||
"\xA5",
|
||||
"\xA6",
|
||||
"\xA7",
|
||||
"\xA8",
|
||||
"\xA9",
|
||||
"\xAA",
|
||||
"\xAB",
|
||||
"\xAC",
|
||||
"\xAD",
|
||||
"\xAE",
|
||||
"\xAF",
|
||||
"\xB0",
|
||||
"\xB1",
|
||||
"\xB2",
|
||||
"\xB3",
|
||||
"\xB4",
|
||||
"\xB5",
|
||||
"\xB6",
|
||||
"\xB7",
|
||||
"\xB8",
|
||||
"\xB9",
|
||||
"\xBA",
|
||||
"\xBB",
|
||||
"\xBC",
|
||||
"\xBD",
|
||||
"\xBE",
|
||||
"\xBF",
|
||||
"\xC0",
|
||||
"\xC1",
|
||||
"\xC2",
|
||||
"\xC3",
|
||||
"\xC4",
|
||||
"\xC5",
|
||||
"\xC6",
|
||||
"\xC7",
|
||||
"\xC8",
|
||||
"\xC9",
|
||||
"\xCA",
|
||||
"\xCB",
|
||||
"\xCC",
|
||||
"\xCD",
|
||||
"\xCE",
|
||||
"\xCF",
|
||||
"\xD0",
|
||||
"\xD1",
|
||||
"\xD2",
|
||||
"\xD3",
|
||||
"\xD4",
|
||||
"\xD5",
|
||||
"\xD6",
|
||||
"\xD7",
|
||||
"\xD8",
|
||||
"\xD9",
|
||||
"\xDA",
|
||||
"\xDB",
|
||||
"\xDC",
|
||||
"\xDD",
|
||||
"\xDE",
|
||||
"\xDF",
|
||||
"\xE0",
|
||||
"\xE1",
|
||||
"\xE2",
|
||||
"\xE3",
|
||||
"\xE4",
|
||||
"\xE5",
|
||||
"\xE6",
|
||||
"\xE7",
|
||||
"\xE8",
|
||||
"\xE9",
|
||||
"\xEA",
|
||||
"\xEB",
|
||||
"\xEC",
|
||||
"\xED",
|
||||
"\xEE",
|
||||
"\xEF",
|
||||
"\xF0",
|
||||
"\xF1",
|
||||
"\xF2",
|
||||
"\xF3",
|
||||
"\xF4",
|
||||
"\xF5",
|
||||
"\xF6",
|
||||
"\xF7",
|
||||
"\xF8",
|
||||
"\xF9",
|
||||
"\xFA",
|
||||
"\xFB",
|
||||
"\xFC",
|
||||
"\xFD",
|
||||
"\xFE",
|
||||
"\xFF"
|
||||
);
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public static $qpReplaceValues = array(
|
||||
"=00",
|
||||
"=01",
|
||||
"=02",
|
||||
"=03",
|
||||
"=04",
|
||||
"=05",
|
||||
"=06",
|
||||
"=07",
|
||||
"=08",
|
||||
"=09",
|
||||
"=0A",
|
||||
"=0B",
|
||||
"=0C",
|
||||
"=0D",
|
||||
"=0E",
|
||||
"=0F",
|
||||
"=10",
|
||||
"=11",
|
||||
"=12",
|
||||
"=13",
|
||||
"=14",
|
||||
"=15",
|
||||
"=16",
|
||||
"=17",
|
||||
"=18",
|
||||
"=19",
|
||||
"=1A",
|
||||
"=1B",
|
||||
"=1C",
|
||||
"=1D",
|
||||
"=1E",
|
||||
"=1F",
|
||||
"=7F",
|
||||
"=80",
|
||||
"=81",
|
||||
"=82",
|
||||
"=83",
|
||||
"=84",
|
||||
"=85",
|
||||
"=86",
|
||||
"=87",
|
||||
"=88",
|
||||
"=89",
|
||||
"=8A",
|
||||
"=8B",
|
||||
"=8C",
|
||||
"=8D",
|
||||
"=8E",
|
||||
"=8F",
|
||||
"=90",
|
||||
"=91",
|
||||
"=92",
|
||||
"=93",
|
||||
"=94",
|
||||
"=95",
|
||||
"=96",
|
||||
"=97",
|
||||
"=98",
|
||||
"=99",
|
||||
"=9A",
|
||||
"=9B",
|
||||
"=9C",
|
||||
"=9D",
|
||||
"=9E",
|
||||
"=9F",
|
||||
"=A0",
|
||||
"=A1",
|
||||
"=A2",
|
||||
"=A3",
|
||||
"=A4",
|
||||
"=A5",
|
||||
"=A6",
|
||||
"=A7",
|
||||
"=A8",
|
||||
"=A9",
|
||||
"=AA",
|
||||
"=AB",
|
||||
"=AC",
|
||||
"=AD",
|
||||
"=AE",
|
||||
"=AF",
|
||||
"=B0",
|
||||
"=B1",
|
||||
"=B2",
|
||||
"=B3",
|
||||
"=B4",
|
||||
"=B5",
|
||||
"=B6",
|
||||
"=B7",
|
||||
"=B8",
|
||||
"=B9",
|
||||
"=BA",
|
||||
"=BB",
|
||||
"=BC",
|
||||
"=BD",
|
||||
"=BE",
|
||||
"=BF",
|
||||
"=C0",
|
||||
"=C1",
|
||||
"=C2",
|
||||
"=C3",
|
||||
"=C4",
|
||||
"=C5",
|
||||
"=C6",
|
||||
"=C7",
|
||||
"=C8",
|
||||
"=C9",
|
||||
"=CA",
|
||||
"=CB",
|
||||
"=CC",
|
||||
"=CD",
|
||||
"=CE",
|
||||
"=CF",
|
||||
"=D0",
|
||||
"=D1",
|
||||
"=D2",
|
||||
"=D3",
|
||||
"=D4",
|
||||
"=D5",
|
||||
"=D6",
|
||||
"=D7",
|
||||
"=D8",
|
||||
"=D9",
|
||||
"=DA",
|
||||
"=DB",
|
||||
"=DC",
|
||||
"=DD",
|
||||
"=DE",
|
||||
"=DF",
|
||||
"=E0",
|
||||
"=E1",
|
||||
"=E2",
|
||||
"=E3",
|
||||
"=E4",
|
||||
"=E5",
|
||||
"=E6",
|
||||
"=E7",
|
||||
"=E8",
|
||||
"=E9",
|
||||
"=EA",
|
||||
"=EB",
|
||||
"=EC",
|
||||
"=ED",
|
||||
"=EE",
|
||||
"=EF",
|
||||
"=F0",
|
||||
"=F1",
|
||||
"=F2",
|
||||
"=F3",
|
||||
"=F4",
|
||||
"=F5",
|
||||
"=F6",
|
||||
"=F7",
|
||||
"=F8",
|
||||
"=F9",
|
||||
"=FA",
|
||||
"=FB",
|
||||
"=FC",
|
||||
"=FD",
|
||||
"=FE",
|
||||
"=FF"
|
||||
);
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public static $qpKeysString =
|
||||
"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF";
|
||||
|
||||
/**
|
||||
* Check if the given string is "printable"
|
||||
*
|
||||
* Checks that a string contains no unprintable characters. If this returns
|
||||
* false, encode the string for secure delivery.
|
||||
*
|
||||
* @param string $str
|
||||
* @return boolean
|
||||
*/
|
||||
public static function isPrintable($str)
|
||||
{
|
||||
return (strcspn($str, self::$qpKeysString) == strlen($str));
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode a given string with the QUOTED_PRINTABLE mechanism and wrap the lines.
|
||||
*
|
||||
* @param string $str
|
||||
* @param int $lineLength Line length; defaults to {@link LINELENGTH}
|
||||
* @param string $lineEnd Line end; defaults to {@link LINEEND}
|
||||
* @return string
|
||||
*/
|
||||
public static function encodeQuotedPrintable(
|
||||
$str,
|
||||
$lineLength = self::LINELENGTH,
|
||||
$lineEnd = self::LINEEND
|
||||
)
|
||||
{
|
||||
$out = '';
|
||||
$str = self::_encodeQuotedPrintable($str);
|
||||
|
||||
// Split encoded text into separate lines
|
||||
while (strlen($str) > 0) {
|
||||
$ptr = strlen($str);
|
||||
if ($ptr > $lineLength) {
|
||||
$ptr = $lineLength;
|
||||
}
|
||||
|
||||
// Ensure we are not splitting across an encoded character
|
||||
$pos = strrpos(substr($str, 0, $ptr), '=');
|
||||
if ($pos !== false && $pos >= $ptr - 2) {
|
||||
$ptr = $pos;
|
||||
}
|
||||
|
||||
// Check if there is a space at the end of the line and rewind
|
||||
if ($ptr > 0 && $str[$ptr - 1] == ' ') {
|
||||
--$ptr;
|
||||
}
|
||||
|
||||
// Add string and continue
|
||||
$out .= substr($str, 0, $ptr) . '=' . $lineEnd;
|
||||
$str = substr($str, $ptr);
|
||||
}
|
||||
|
||||
$out = rtrim($out, $lineEnd);
|
||||
$out = rtrim($out, '=');
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a string into quoted printable format.
|
||||
*
|
||||
* @param string $str
|
||||
* @return string
|
||||
*/
|
||||
private static function _encodeQuotedPrintable($str)
|
||||
{
|
||||
$str = str_replace('=', '=3D', $str);
|
||||
$str = str_replace(self::$qpKeys, self::$qpReplaceValues, $str);
|
||||
$str = rtrim($str);
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode a given string with the QUOTED_PRINTABLE mechanism for Mail Headers.
|
||||
*
|
||||
* Mail headers depend on an extended quoted printable algorithm otherwise
|
||||
* a range of bugs can occur.
|
||||
*
|
||||
* @param string $str
|
||||
* @param string $charset
|
||||
* @param int $lineLength Line length; defaults to {@link LINELENGTH}
|
||||
* @param string $lineEnd Line end; defaults to {@link LINEEND}
|
||||
* @return string
|
||||
*/
|
||||
public static function encodeQuotedPrintableHeader(
|
||||
$str, $charset, $lineLength = self::LINELENGTH, $lineEnd = self::LINEEND
|
||||
)
|
||||
{
|
||||
// Reduce line-length by the length of the required delimiter, charsets and encoding
|
||||
$prefix = sprintf('=?%s?Q?', $charset);
|
||||
$lineLength = $lineLength - strlen($prefix) - 3;
|
||||
|
||||
$str = self::_encodeQuotedPrintable($str);
|
||||
|
||||
// Mail-Header required chars have to be encoded also:
|
||||
$str = str_replace(
|
||||
array('?', ' ', '_', ','), array('=3F', '=20', '=5F', '=2C'), $str
|
||||
);
|
||||
|
||||
// initialize first line, we need it anyways
|
||||
$lines = array(0 => "");
|
||||
|
||||
// Split encoded text into separate lines
|
||||
$tmp = "";
|
||||
while (strlen($str) > 0) {
|
||||
$currentLine = max(count($lines) - 1, 0);
|
||||
$token = self::getNextQuotedPrintableToken($str);
|
||||
$str = substr($str, strlen($token));
|
||||
|
||||
$tmp .= $token;
|
||||
if ($token == '=20') {
|
||||
// only if we have a single char token or space, we can append the
|
||||
// tempstring it to the current line or start a new line if necessary.
|
||||
if (strlen($lines[$currentLine] . $tmp) > $lineLength) {
|
||||
$lines[$currentLine + 1] = $tmp;
|
||||
} else {
|
||||
$lines[$currentLine] .= $tmp;
|
||||
}
|
||||
$tmp = "";
|
||||
}
|
||||
// don't forget to append the rest to the last line
|
||||
if (strlen($str) == 0) {
|
||||
$lines[$currentLine] .= $tmp;
|
||||
}
|
||||
}
|
||||
|
||||
// assemble the lines together by pre- and appending delimiters, charset, encoding.
|
||||
for ($i = 0; $i < count($lines); $i++) {
|
||||
$lines[$i] = " " . $prefix . $lines[$i] . "?=";
|
||||
}
|
||||
$str = trim(implode($lineEnd, $lines));
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the first token from a quoted printable string.
|
||||
*
|
||||
* @param string $str
|
||||
* @return string
|
||||
*/
|
||||
private static function getNextQuotedPrintableToken($str)
|
||||
{
|
||||
if (substr($str, 0, 1) == "=") {
|
||||
$token = substr($str, 0, 3);
|
||||
} else {
|
||||
$token = substr($str, 0, 1);
|
||||
}
|
||||
|
||||
return $token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode a given string in mail header compatible base64 encoding.
|
||||
*
|
||||
* @param string $str
|
||||
* @param string $charset
|
||||
* @param int $lineLength Line length; defaults to {@link LINELENGTH}
|
||||
* @param string $lineEnd Line end; defaults to {@link LINEEND}
|
||||
* @return string
|
||||
*/
|
||||
public static function encodeBase64Header(
|
||||
$str, $charset, $lineLength = self::LINELENGTH, $lineEnd = self::LINEEND
|
||||
)
|
||||
{
|
||||
$prefix = '=?' . $charset . '?B?';
|
||||
$suffix = '?=';
|
||||
$remainingLength = $lineLength - strlen($prefix) - strlen($suffix);
|
||||
|
||||
$encodedValue = self::encodeBase64($str, $remainingLength, $lineEnd);
|
||||
$encodedValue = str_replace(
|
||||
$lineEnd, $suffix . $lineEnd . ' ' . $prefix, $encodedValue
|
||||
);
|
||||
$encodedValue = $prefix . $encodedValue . $suffix;
|
||||
|
||||
return $encodedValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode a given string in base64 encoding and break lines
|
||||
* according to the maximum linelength.
|
||||
*
|
||||
* @param string $str
|
||||
* @param int $lineLength Line length; defaults to {@link LINELENGTH}
|
||||
* @param string $lineEnd Line end; defaults to {@link LINEEND}
|
||||
* @return string
|
||||
*/
|
||||
public static function encodeBase64(
|
||||
$str, $lineLength = self::LINELENGTH, $lineEnd = self::LINEEND
|
||||
)
|
||||
{
|
||||
return rtrim(chunk_split(base64_encode($str), $lineLength, $lineEnd));
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param null|string $boundary
|
||||
*/
|
||||
public function __construct($boundary = null)
|
||||
{
|
||||
// This string needs to be somewhat unique
|
||||
if ($boundary === null) {
|
||||
$this->_boundary = '=_' . md5(microtime(1) . self::$makeUnique++);
|
||||
} else {
|
||||
$this->_boundary = $boundary;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the given string with the given encoding.
|
||||
*
|
||||
* @param string $str
|
||||
* @param string $encoding
|
||||
* @param string $EOL Line end; defaults to {@link Postman_Zend_Mime::LINEEND}
|
||||
* @return string
|
||||
*/
|
||||
public static function encode($str, $encoding, $EOL = self::LINEEND)
|
||||
{
|
||||
switch ($encoding) {
|
||||
case self::ENCODING_BASE64:
|
||||
return self::encodeBase64($str, self::LINELENGTH, $EOL);
|
||||
|
||||
case self::ENCODING_QUOTEDPRINTABLE:
|
||||
return self::encodeQuotedPrintable($str, self::LINELENGTH, $EOL);
|
||||
|
||||
default:
|
||||
/**
|
||||
* @todo 7Bit and 8Bit is currently handled the same way.
|
||||
*/
|
||||
return $str;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a MIME boundary
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function boundary()
|
||||
{
|
||||
return $this->_boundary;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a MIME boundary line
|
||||
*
|
||||
* @param string $EOL Line end; defaults to {@link LINEEND}
|
||||
* @return string
|
||||
*/
|
||||
public function boundaryLine($EOL = self::LINEEND)
|
||||
{
|
||||
return $EOL . '--' . $this->_boundary . $EOL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return MIME ending
|
||||
*
|
||||
* @param string $EOL Line end; defaults to {@link LINEEND}
|
||||
* @return string
|
||||
*/
|
||||
public function mimeEnd($EOL = self::LINEEND)
|
||||
{
|
||||
return $EOL . '--' . $this->_boundary . '--' . $EOL;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,276 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mime
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Mime
|
||||
*/
|
||||
require_once 'Zend/Mime.php';
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mime
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Mime_Decode
|
||||
{
|
||||
/**
|
||||
* Explode MIME multipart string into seperate parts
|
||||
*
|
||||
* Parts consist of the header and the body of each MIME part.
|
||||
*
|
||||
* @param string $body raw body of message
|
||||
* @param string $boundary boundary as found in content-type
|
||||
* @return array parts with content of each part, empty if no parts found
|
||||
* @throws Postman_Zend_Exception
|
||||
*/
|
||||
public static function splitMime($body, $boundary)
|
||||
{
|
||||
// TODO: we're ignoring \r for now - is this function fast enough and is it safe to asume noone needs \r?
|
||||
$body = str_replace("\r", '', $body);
|
||||
|
||||
$start = 0;
|
||||
$res = array();
|
||||
// find every mime part limiter and cut out the
|
||||
// string before it.
|
||||
// the part before the first boundary string is discarded:
|
||||
$p = strpos($body, '--' . $boundary . "\n", $start);
|
||||
if ($p === false) {
|
||||
// no parts found!
|
||||
return array();
|
||||
}
|
||||
|
||||
// position after first boundary line
|
||||
$start = $p + 3 + strlen($boundary);
|
||||
|
||||
while (($p = strpos($body, '--' . $boundary . "\n", $start)) !== false) {
|
||||
$res[] = substr($body, $start, $p-$start);
|
||||
$start = $p + 3 + strlen($boundary);
|
||||
}
|
||||
|
||||
// no more parts, find end boundary
|
||||
$p = strpos($body, '--' . $boundary . '--', $start);
|
||||
if ($p === false) {
|
||||
throw new Postman_Zend_Exception('Not a valid Mime Message: End Missing');
|
||||
}
|
||||
|
||||
// the remaining part also needs to be parsed:
|
||||
$res[] = substr($body, $start, $p - $start);
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* decodes a mime encoded String and returns a
|
||||
* struct of parts with header and body
|
||||
*
|
||||
* @param string $message raw message content
|
||||
* @param string $boundary boundary as found in content-type
|
||||
* @param string $EOL EOL string; defaults to {@link Postman_Zend_Mime::LINEEND}
|
||||
* @return array|null parts as array('header' => array(name => value), 'body' => content), null if no parts found
|
||||
* @throws Postman_Zend_Exception
|
||||
*/
|
||||
public static function splitMessageStruct(
|
||||
$message, $boundary, $EOL = Postman_Zend_Mime::LINEEND
|
||||
)
|
||||
{
|
||||
$parts = self::splitMime($message, $boundary);
|
||||
if (count($parts) <= 0) {
|
||||
return null;
|
||||
}
|
||||
$result = array();
|
||||
foreach ($parts as $part) {
|
||||
self::splitMessage($part, $headers, $body, $EOL);
|
||||
$result[] = array(
|
||||
'header' => $headers,
|
||||
'body' => $body
|
||||
);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* split a message in header and body part, if no header or an
|
||||
* invalid header is found $headers is empty
|
||||
*
|
||||
* The charset of the returned headers depend on your iconv settings.
|
||||
*
|
||||
* @param string $message raw message with header and optional content
|
||||
* @param array $headers output param, array with headers as array(name => value)
|
||||
* @param string $body output param, content of message
|
||||
* @param string $EOL EOL string; defaults to {@link Postman_Zend_Mime::LINEEND}
|
||||
* @return null
|
||||
*/
|
||||
public static function splitMessage(
|
||||
$message, &$headers, &$body, $EOL = Postman_Zend_Mime::LINEEND
|
||||
)
|
||||
{
|
||||
// check for valid header at first line
|
||||
$firstline = strtok($message, "\n");
|
||||
if (!preg_match('%^[^\s]+[^:]*:%', $firstline)) {
|
||||
$headers = array();
|
||||
// TODO: we're ignoring \r for now - is this function fast enough and is it safe to asume noone needs \r?
|
||||
$body = str_replace(
|
||||
array(
|
||||
"\r",
|
||||
"\n"
|
||||
), array(
|
||||
'',
|
||||
$EOL
|
||||
), $message
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// find an empty line between headers and body
|
||||
// default is set new line
|
||||
if (strpos($message, $EOL . $EOL)) {
|
||||
list($headers, $body) = explode($EOL . $EOL, $message, 2);
|
||||
// next is the standard new line
|
||||
} else {
|
||||
if ($EOL != "\r\n" && strpos($message, "\r\n\r\n")) {
|
||||
list($headers, $body) = explode("\r\n\r\n", $message, 2);
|
||||
// next is the other "standard" new line
|
||||
} else {
|
||||
if ($EOL != "\n" && strpos($message, "\n\n")) {
|
||||
list($headers, $body) = explode("\n\n", $message, 2);
|
||||
// at last resort find anything that looks like a new line
|
||||
} else {
|
||||
@list($headers, $body) =
|
||||
@preg_split("%([\r\n]+)\\1%U", $message, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$headers = iconv_mime_decode_headers(
|
||||
$headers, ICONV_MIME_DECODE_CONTINUE_ON_ERROR
|
||||
);
|
||||
|
||||
if ($headers === false) {
|
||||
// an error occurs during the decoding
|
||||
return;
|
||||
}
|
||||
|
||||
// normalize header names
|
||||
foreach ($headers as $name => $header) {
|
||||
$lower = strtolower($name);
|
||||
if ($lower == $name) {
|
||||
continue;
|
||||
}
|
||||
unset($headers[$name]);
|
||||
if (!isset($headers[$lower])) {
|
||||
$headers[$lower] = $header;
|
||||
continue;
|
||||
}
|
||||
if (is_array($headers[$lower])) {
|
||||
$headers[$lower][] = $header;
|
||||
continue;
|
||||
}
|
||||
$headers[$lower] = array(
|
||||
$headers[$lower],
|
||||
$header
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* split a content type in its different parts
|
||||
*
|
||||
* @param string $type content-type
|
||||
* @param string $wantedPart the wanted part, else an array with all parts is returned
|
||||
* @return string|array wanted part or all parts as array('type' => content-type, partname => value)
|
||||
*/
|
||||
public static function splitContentType($type, $wantedPart = null)
|
||||
{
|
||||
return self::splitHeaderField($type, $wantedPart, 'type');
|
||||
}
|
||||
|
||||
/**
|
||||
* split a header field like content type in its different parts
|
||||
*
|
||||
* @param string $field
|
||||
* @param string $wantedPart the wanted part, else an array with all parts is returned
|
||||
* @param int|string $firstName key name for the first part
|
||||
* @throws Postman_Zend_Exception
|
||||
* @return string|array wanted part or all parts as array($firstName => firstPart, partname => value)
|
||||
*/
|
||||
public static function splitHeaderField(
|
||||
$field, $wantedPart = null, $firstName = 0
|
||||
)
|
||||
{
|
||||
$wantedPart = strtolower($wantedPart);
|
||||
$firstName = strtolower($firstName);
|
||||
|
||||
// special case - a bit optimized
|
||||
if ($firstName === $wantedPart) {
|
||||
$field = strtok($field, ';');
|
||||
|
||||
return $field[0] == '"' ? substr($field, 1, -1) : $field;
|
||||
}
|
||||
|
||||
$field = $firstName . '=' . $field;
|
||||
if (!preg_match_all('%([^=\s]+)\s*=\s*("[^"]+"|[^;]+)(;\s*|$)%', $field, $matches)) {
|
||||
throw new Postman_Zend_Exception('not a valid header field');
|
||||
}
|
||||
|
||||
if ($wantedPart) {
|
||||
foreach ($matches[1] as $key => $name) {
|
||||
if (strcasecmp($name, $wantedPart)) {
|
||||
continue;
|
||||
}
|
||||
if ($matches[2][$key][0] != '"') {
|
||||
return $matches[2][$key];
|
||||
}
|
||||
|
||||
return substr($matches[2][$key], 1, -1);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
$split = array();
|
||||
foreach ($matches[1] as $key => $name) {
|
||||
$name = strtolower($name);
|
||||
if ($matches[2][$key][0] == '"') {
|
||||
$split[$name] = substr($matches[2][$key], 1, -1);
|
||||
} else {
|
||||
$split[$name] = $matches[2][$key];
|
||||
}
|
||||
}
|
||||
|
||||
return $split;
|
||||
}
|
||||
|
||||
/**
|
||||
* decode a quoted printable encoded string
|
||||
*
|
||||
* The charset of the returned string depends on your iconv settings.
|
||||
*
|
||||
* @param string $string Encoded string
|
||||
* @return string Decoded string
|
||||
*/
|
||||
public static function decodeQuotedPrintable($string)
|
||||
{
|
||||
return quoted_printable_decode($string);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mime
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* Postman_Zend_Exception
|
||||
*/
|
||||
require_once 'Zend/Exception.php';
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mime
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Mime_Exception extends Postman_Zend_Exception
|
||||
{
|
||||
}
|
||||
|
||||
@@ -0,0 +1,305 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mime
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* Postman_Zend_Mime
|
||||
*/
|
||||
// require_once 'Zend/Mime.php';
|
||||
|
||||
/**
|
||||
* Postman_Zend_Mime_Part
|
||||
*/
|
||||
// require_once 'Zend/Mime/Part.php';
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mime
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Mime_Message
|
||||
{
|
||||
/**
|
||||
* The Postman_Zend_Mime_Parts of the message
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_parts = array();
|
||||
|
||||
/**
|
||||
* The Postman_Zend_Mime object for the message
|
||||
*
|
||||
* @var Postman_Zend_Mime|null
|
||||
*/
|
||||
protected $_mime = null;
|
||||
|
||||
/**
|
||||
* Returns the list of all Postman_Zend_Mime_Parts in the message
|
||||
*
|
||||
* @return array of Postman_Zend_Mime_Part
|
||||
*/
|
||||
public function getParts()
|
||||
{
|
||||
return $this->_parts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the given array of Postman_Zend_Mime_Parts as the array for the message
|
||||
*
|
||||
* @param array $parts
|
||||
*/
|
||||
public function setParts($parts)
|
||||
{
|
||||
$this->_parts = $parts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append a new Postman_Zend_Mime_Part to the current message
|
||||
*
|
||||
* @param Postman_Zend_Mime_Part $part
|
||||
*/
|
||||
public function addPart(Postman_Zend_Mime_Part $part)
|
||||
{
|
||||
/**
|
||||
* @todo check for duplicate object handle
|
||||
*/
|
||||
$this->_parts[] = $part;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if message needs to be sent as multipart
|
||||
* MIME message or if it has only one part.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isMultiPart()
|
||||
{
|
||||
return (count($this->_parts) > 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Postman_Zend_Mime object for the message
|
||||
*
|
||||
* This can be used to set the boundary specifically or to use a subclass of
|
||||
* Postman_Zend_Mime for generating the boundary.
|
||||
*
|
||||
* @param Postman_Zend_Mime $mime
|
||||
*/
|
||||
public function setMime(Postman_Zend_Mime $mime)
|
||||
{
|
||||
$this->_mime = $mime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Postman_Zend_Mime object in use by the message
|
||||
*
|
||||
* If the object was not present, it is created and returned. Can be used to
|
||||
* determine the boundary used in this message.
|
||||
*
|
||||
* @return Postman_Zend_Mime
|
||||
*/
|
||||
public function getMime()
|
||||
{
|
||||
if ($this->_mime === null) {
|
||||
$this->_mime = new Postman_Zend_Mime();
|
||||
}
|
||||
|
||||
return $this->_mime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate MIME-compliant message from the current configuration
|
||||
*
|
||||
* This can be a multipart message if more than one MIME part was added. If
|
||||
* only one part is present, the content of this part is returned. If no
|
||||
* part had been added, an empty string is returned.
|
||||
*
|
||||
* Parts are seperated by the mime boundary as defined in Postman_Zend_Mime. If
|
||||
* {@link setMime()} has been called before this method, the Postman_Zend_Mime
|
||||
* object set by this call will be used. Otherwise, a new Postman_Zend_Mime object
|
||||
* is generated and used.
|
||||
*
|
||||
* @param string $EOL EOL string; defaults to {@link Postman_Zend_Mime::LINEEND}
|
||||
* @return string
|
||||
*/
|
||||
public function generateMessage($EOL = Postman_Zend_Mime::LINEEND)
|
||||
{
|
||||
if (!$this->isMultiPart()) {
|
||||
$body = array_shift($this->_parts);
|
||||
$body = $body->getContent($EOL);
|
||||
} else {
|
||||
$mime = $this->getMime();
|
||||
|
||||
$boundaryLine = $mime->boundaryLine($EOL);
|
||||
$body = 'This is a message in Mime Format. If you see this, '
|
||||
. "your mail reader does not support this format." . $EOL;
|
||||
|
||||
foreach (array_keys($this->_parts) as $p) {
|
||||
$body .= $boundaryLine
|
||||
. $this->getPartHeaders($p, $EOL)
|
||||
. $EOL
|
||||
. $this->getPartContent($p, $EOL);
|
||||
}
|
||||
|
||||
$body .= $mime->mimeEnd($EOL);
|
||||
}
|
||||
|
||||
return trim($body);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the headers of a given part as an array
|
||||
*
|
||||
* @param int $partnum
|
||||
* @return array
|
||||
*/
|
||||
public function getPartHeadersArray($partnum)
|
||||
{
|
||||
return $this->_parts[$partnum]->getHeadersArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the headers of a given part as a string
|
||||
*
|
||||
* @param int $partnum
|
||||
* @param string $EOL
|
||||
* @return string
|
||||
*/
|
||||
public function getPartHeaders($partnum, $EOL = Postman_Zend_Mime::LINEEND)
|
||||
{
|
||||
return $this->_parts[$partnum]->getHeaders($EOL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the (encoded) content of a given part as a string
|
||||
*
|
||||
* @param int $partnum
|
||||
* @param string $EOL
|
||||
* @return string
|
||||
*/
|
||||
public function getPartContent($partnum, $EOL = Postman_Zend_Mime::LINEEND)
|
||||
{
|
||||
return $this->_parts[$partnum]->getContent($EOL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Explode MIME multipart string into seperate parts
|
||||
*
|
||||
* Parts consist of the header and the body of each MIME part.
|
||||
*
|
||||
* @param string $body
|
||||
* @param string $boundary
|
||||
* @throws Postman_Zend_Exception
|
||||
* @return array
|
||||
*/
|
||||
protected static function _disassembleMime($body, $boundary)
|
||||
{
|
||||
$start = 0;
|
||||
$res = array();
|
||||
// find every mime part limiter and cut out the
|
||||
// string before it.
|
||||
// the part before the first boundary string is discarded:
|
||||
$p = strpos($body, '--' . $boundary . "\n", $start);
|
||||
if ($p === false) {
|
||||
// no parts found!
|
||||
return array();
|
||||
}
|
||||
|
||||
// position after first boundary line
|
||||
$start = $p + 3 + strlen($boundary);
|
||||
|
||||
while (($p = strpos($body, '--' . $boundary . "\n", $start))
|
||||
!== false) {
|
||||
$res[] = substr($body, $start, $p - $start);
|
||||
$start = $p + 3 + strlen($boundary);
|
||||
}
|
||||
|
||||
// no more parts, find end boundary
|
||||
$p = strpos($body, '--' . $boundary . '--', $start);
|
||||
if ($p === false) {
|
||||
throw new Postman_Zend_Exception('Not a valid Mime Message: End Missing');
|
||||
}
|
||||
|
||||
// the remaining part also needs to be parsed:
|
||||
$res[] = substr($body, $start, $p - $start);
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes a MIME encoded string and returns a Postman_Zend_Mime_Message object with
|
||||
* all the MIME parts set according to the given string
|
||||
*
|
||||
* @param string $message
|
||||
* @param string $boundary
|
||||
* @param string $EOL EOL string; defaults to {@link Postman_Zend_Mime::LINEEND}
|
||||
* @throws Postman_Zend_Exception
|
||||
* @return Postman_Zend_Mime_Message
|
||||
*/
|
||||
public static function createFromMessage(
|
||||
$message, $boundary, $EOL = Postman_Zend_Mime::LINEEND
|
||||
)
|
||||
{
|
||||
require_once 'Zend/Mime/Decode.php';
|
||||
$parts = Postman_Zend_Mime_Decode::splitMessageStruct($message, $boundary, $EOL);
|
||||
|
||||
$res = new self();
|
||||
foreach ($parts as $part) {
|
||||
// now we build a new MimePart for the current Message Part:
|
||||
$newPart = new Postman_Zend_Mime_Part($part['body']);
|
||||
foreach ($part['header'] as $key => $value) {
|
||||
/**
|
||||
* @todo check for characterset and filename
|
||||
*/
|
||||
switch (strtolower($key)) {
|
||||
case 'content-type':
|
||||
$newPart->type = $value;
|
||||
break;
|
||||
case 'content-transfer-encoding':
|
||||
$newPart->encoding = $value;
|
||||
break;
|
||||
case 'content-id':
|
||||
$newPart->id = trim($value, '<>');
|
||||
break;
|
||||
case 'content-disposition':
|
||||
$newPart->disposition = $value;
|
||||
break;
|
||||
case 'content-description':
|
||||
$newPart->description = $value;
|
||||
break;
|
||||
case 'content-location':
|
||||
$newPart->location = $value;
|
||||
break;
|
||||
case 'content-language':
|
||||
$newPart->language = $value;
|
||||
break;
|
||||
default:
|
||||
throw new Postman_Zend_Exception(
|
||||
'Unknown header ignored for MimePart:' . $key
|
||||
);
|
||||
}
|
||||
}
|
||||
$res->addPart($newPart);
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,333 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mime
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* Postman_Zend_Mime
|
||||
*/
|
||||
// require_once 'Zend/Mime.php';
|
||||
|
||||
/**
|
||||
* Class representing a MIME part.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Mime
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Mime_Part
|
||||
{
|
||||
|
||||
/**
|
||||
* Type
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $type = Postman_Zend_Mime::TYPE_OCTETSTREAM;
|
||||
|
||||
/**
|
||||
* Encoding
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $encoding = Postman_Zend_Mime::ENCODING_8BIT;
|
||||
|
||||
/**
|
||||
* ID
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $id;
|
||||
|
||||
/**
|
||||
* Disposition
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $disposition;
|
||||
|
||||
/**
|
||||
* Filename
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $filename;
|
||||
|
||||
/**
|
||||
* Description
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $description;
|
||||
|
||||
/**
|
||||
* Character set
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $charset;
|
||||
|
||||
/**
|
||||
* Boundary
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $boundary;
|
||||
|
||||
/**
|
||||
* Location
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $location;
|
||||
|
||||
/**
|
||||
* Language
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $language;
|
||||
|
||||
/**
|
||||
* Content
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
protected $_content;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $_isStream = false;
|
||||
|
||||
/**
|
||||
* create a new Mime Part.
|
||||
* The (unencoded) content of the Part as passed
|
||||
* as a string or stream
|
||||
*
|
||||
* @param mixed $content String or Stream containing the content
|
||||
*/
|
||||
public function __construct($content)
|
||||
{
|
||||
$this->_content = $content;
|
||||
if (is_resource($content)) {
|
||||
$this->_isStream = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo setters/getters
|
||||
* @todo error checking for setting $type
|
||||
* @todo error checking for setting $encoding
|
||||
*/
|
||||
|
||||
/**
|
||||
* check if this part can be read as a stream.
|
||||
* if true, getEncodedStream can be called, otherwise
|
||||
* only getContent can be used to fetch the encoded
|
||||
* content of the part
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isStream()
|
||||
{
|
||||
return $this->_isStream;
|
||||
}
|
||||
|
||||
/**
|
||||
* if this was created with a stream, return a filtered stream for
|
||||
* reading the content. very useful for large file attachments.
|
||||
*
|
||||
* @return mixed Stream
|
||||
* @throws Postman_Zend_Mime_Exception if not a stream or unable to append filter
|
||||
*/
|
||||
public function getEncodedStream()
|
||||
{
|
||||
if (!$this->_isStream) {
|
||||
require_once 'Zend/Mime/Exception.php';
|
||||
throw new Postman_Zend_Mime_Exception(
|
||||
'Attempt to get a stream from a string part'
|
||||
);
|
||||
}
|
||||
|
||||
//stream_filter_remove(); // ??? is that right?
|
||||
switch ($this->encoding) {
|
||||
case Postman_Zend_Mime::ENCODING_QUOTEDPRINTABLE:
|
||||
$filter = stream_filter_append(
|
||||
$this->_content,
|
||||
'convert.quoted-printable-encode',
|
||||
STREAM_FILTER_READ,
|
||||
array(
|
||||
'line-length' => 76,
|
||||
'line-break-chars' => Postman_Zend_Mime::LINEEND
|
||||
)
|
||||
);
|
||||
if (!is_resource($filter)) {
|
||||
require_once 'Zend/Mime/Exception.php';
|
||||
throw new Postman_Zend_Mime_Exception(
|
||||
'Failed to append quoted-printable filter'
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case Postman_Zend_Mime::ENCODING_BASE64:
|
||||
$filter = stream_filter_append(
|
||||
$this->_content,
|
||||
'convert.base64-encode',
|
||||
STREAM_FILTER_READ,
|
||||
array(
|
||||
'line-length' => 76,
|
||||
'line-break-chars' => Postman_Zend_Mime::LINEEND
|
||||
)
|
||||
);
|
||||
if (!is_resource($filter)) {
|
||||
require_once 'Zend/Mime/Exception.php';
|
||||
throw new Postman_Zend_Mime_Exception(
|
||||
'Failed to append base64 filter'
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
}
|
||||
|
||||
return $this->_content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Content of the current Mime Part in the given encoding.
|
||||
*
|
||||
* @param string $EOL Line end; defaults to {@link Postman_Zend_Mime::LINEEND}
|
||||
* @throws Postman_Zend_Mime_Exception
|
||||
* @return string
|
||||
*/
|
||||
public function getContent($EOL = Postman_Zend_Mime::LINEEND)
|
||||
{
|
||||
if ($this->_isStream) {
|
||||
return stream_get_contents($this->getEncodedStream());
|
||||
} else {
|
||||
return Postman_Zend_Mime::encode($this->_content, $this->encoding, $EOL);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the RAW unencoded content from this part
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getRawContent()
|
||||
{
|
||||
if ($this->_isStream) {
|
||||
return stream_get_contents($this->_content);
|
||||
} else {
|
||||
return $this->_content;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and return the array of headers for this MIME part
|
||||
*
|
||||
* @param string $EOL Line end; defaults to {@link Postman_Zend_Mime::LINEEND}
|
||||
* @return array
|
||||
*/
|
||||
public function getHeadersArray($EOL = Postman_Zend_Mime::LINEEND)
|
||||
{
|
||||
$headers = array();
|
||||
|
||||
$contentType = $this->type;
|
||||
if ($this->charset) {
|
||||
$contentType .= '; charset=' . $this->charset;
|
||||
}
|
||||
|
||||
if ($this->boundary) {
|
||||
$contentType .= ';' . $EOL
|
||||
. " boundary=\"" . $this->boundary . '"';
|
||||
}
|
||||
|
||||
$headers[] = array(
|
||||
'Content-Type',
|
||||
$contentType
|
||||
);
|
||||
|
||||
if ($this->encoding) {
|
||||
$headers[] = array(
|
||||
'Content-Transfer-Encoding',
|
||||
$this->encoding
|
||||
);
|
||||
}
|
||||
|
||||
if ($this->id) {
|
||||
$headers[] = array(
|
||||
'Content-ID',
|
||||
'<' . $this->id . '>'
|
||||
);
|
||||
}
|
||||
|
||||
if ($this->disposition) {
|
||||
$disposition = $this->disposition;
|
||||
if ($this->filename) {
|
||||
$disposition .= '; filename="' . $this->filename . '"';
|
||||
}
|
||||
$headers[] = array(
|
||||
'Content-Disposition',
|
||||
$disposition
|
||||
);
|
||||
}
|
||||
|
||||
if ($this->description) {
|
||||
$headers[] = array(
|
||||
'Content-Description',
|
||||
$this->description
|
||||
);
|
||||
}
|
||||
|
||||
if ($this->location) {
|
||||
$headers[] = array(
|
||||
'Content-Location',
|
||||
$this->location
|
||||
);
|
||||
}
|
||||
|
||||
if ($this->language) {
|
||||
$headers[] = array(
|
||||
'Content-Language',
|
||||
$this->language
|
||||
);
|
||||
}
|
||||
|
||||
return $headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the headers for this part as a string
|
||||
*
|
||||
* @param string $EOL Line end; defaults to {@link Postman_Zend_Mime::LINEEND}
|
||||
* @return string
|
||||
*/
|
||||
public function getHeaders($EOL = Postman_Zend_Mime::LINEEND)
|
||||
{
|
||||
$res = '';
|
||||
foreach ($this->getHeadersArray($EOL) as $header) {
|
||||
$res .= $header[0] . ': ' . $header[1] . $EOL;
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,198 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Registry
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* Generic storage class helps to manage global data.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Registry
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Registry extends ArrayObject
|
||||
{
|
||||
/**
|
||||
* Class name of the singleton registry object.
|
||||
* @var string
|
||||
*/
|
||||
private static $_registryClassName = 'Postman_Zend_Registry';
|
||||
|
||||
/**
|
||||
* Registry object provides storage for shared objects.
|
||||
* @var Postman_Zend_Registry
|
||||
*/
|
||||
private static $_registry = null;
|
||||
|
||||
/**
|
||||
* Retrieves the default registry instance.
|
||||
*
|
||||
* @return Postman_Zend_Registry
|
||||
*/
|
||||
public static function getInstance()
|
||||
{
|
||||
if (self::$_registry === null) {
|
||||
self::init();
|
||||
}
|
||||
|
||||
return self::$_registry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default registry instance to a specified instance.
|
||||
*
|
||||
* @param Postman_Zend_Registry $registry An object instance of type Postman_Zend_Registry,
|
||||
* or a subclass.
|
||||
* @return void
|
||||
* @throws Postman_Zend_Exception if registry is already initialized.
|
||||
*/
|
||||
public static function setInstance(Postman_Zend_Registry $registry)
|
||||
{
|
||||
if (self::$_registry !== null) {
|
||||
require_once 'Zend/Exception.php';
|
||||
throw new Postman_Zend_Exception('Registry is already initialized');
|
||||
}
|
||||
|
||||
self::setClassName(get_class($registry));
|
||||
self::$_registry = $registry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the default registry instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected static function init()
|
||||
{
|
||||
self::setInstance(new self::$_registryClassName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the class name to use for the default registry instance.
|
||||
* Does not affect the currently initialized instance, it only applies
|
||||
* for the next time you instantiate.
|
||||
*
|
||||
* @param string $registryClassName
|
||||
* @return void
|
||||
* @throws Postman_Zend_Exception if the registry is initialized or if the
|
||||
* class name is not valid.
|
||||
*/
|
||||
public static function setClassName($registryClassName = 'Postman_Zend_Registry')
|
||||
{
|
||||
if (self::$_registry !== null) {
|
||||
require_once 'Zend/Exception.php';
|
||||
throw new Postman_Zend_Exception('Registry is already initialized');
|
||||
}
|
||||
|
||||
if (!is_string($registryClassName)) {
|
||||
require_once 'Zend/Exception.php';
|
||||
throw new Postman_Zend_Exception("Argument is not a class name");
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Loader
|
||||
*/
|
||||
if (!class_exists($registryClassName)) {
|
||||
require_once 'Zend/Loader.php';
|
||||
Postman_Zend_Loader::loadClass($registryClassName);
|
||||
}
|
||||
|
||||
self::$_registryClassName = $registryClassName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unset the default registry instance.
|
||||
* Primarily used in tearDown() in unit tests.
|
||||
* @returns void
|
||||
*/
|
||||
public static function _unsetInstance()
|
||||
{
|
||||
self::$_registry = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* getter method, basically same as offsetGet().
|
||||
*
|
||||
* This method can be called from an object of type Postman_Zend_Registry, or it
|
||||
* can be called statically. In the latter case, it uses the default
|
||||
* static instance stored in the class.
|
||||
*
|
||||
* @param string $index - get the value associated with $index
|
||||
* @return mixed
|
||||
* @throws Postman_Zend_Exception if no entry is registerd for $index.
|
||||
*/
|
||||
public static function get($index)
|
||||
{
|
||||
$instance = self::getInstance();
|
||||
|
||||
if (!$instance->offsetExists($index)) {
|
||||
require_once 'Zend/Exception.php';
|
||||
throw new Postman_Zend_Exception("No entry is registered for key '$index'");
|
||||
}
|
||||
|
||||
return $instance->offsetGet($index);
|
||||
}
|
||||
|
||||
/**
|
||||
* setter method, basically same as offsetSet().
|
||||
*
|
||||
* This method can be called from an object of type Postman_Zend_Registry, or it
|
||||
* can be called statically. In the latter case, it uses the default
|
||||
* static instance stored in the class.
|
||||
*
|
||||
* @param string $index The location in the ArrayObject in which to store
|
||||
* the value.
|
||||
* @param mixed $value The object to store in the ArrayObject.
|
||||
* @return void
|
||||
*/
|
||||
public static function set($index, $value)
|
||||
{
|
||||
$instance = self::getInstance();
|
||||
$instance->offsetSet($index, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns TRUE if the $index is a named value in the registry,
|
||||
* or FALSE if $index was not found in the registry.
|
||||
*
|
||||
* @param string $index
|
||||
* @return boolean
|
||||
*/
|
||||
public static function isRegistered($index)
|
||||
{
|
||||
if (self::$_registry === null) {
|
||||
return false;
|
||||
}
|
||||
return self::$_registry->offsetExists($index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a parent ArrayObject with default
|
||||
* ARRAY_AS_PROPS to allow acces as an object
|
||||
*
|
||||
* @param array $array data array
|
||||
* @param integer $flags ArrayObject flags
|
||||
*/
|
||||
public function __construct($array = array(), $flags = parent::ARRAY_AS_PROPS)
|
||||
{
|
||||
parent::__construct($array, $flags);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,290 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Validate_Interface
|
||||
*/
|
||||
// require_once 'Zend/Validate/Interface.php';
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Validate implements Postman_Zend_Validate_Interface
|
||||
{
|
||||
/**
|
||||
* Validator chain
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_validators = array();
|
||||
|
||||
/**
|
||||
* Array of validation failure messages
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_messages = array();
|
||||
|
||||
/**
|
||||
* Default Namespaces
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $_defaultNamespaces = array();
|
||||
|
||||
/**
|
||||
* Array of validation failure message codes
|
||||
*
|
||||
* @var array
|
||||
* @deprecated Since 1.5.0
|
||||
*/
|
||||
protected $_errors = array();
|
||||
|
||||
/**
|
||||
* Adds a validator to the end of the chain
|
||||
*
|
||||
* If $breakChainOnFailure is true, then if the validator fails, the next validator in the chain,
|
||||
* if one exists, will not be executed.
|
||||
*
|
||||
* @param Postman_Zend_Validate_Interface $validator
|
||||
* @param boolean $breakChainOnFailure
|
||||
* @return Postman_Zend_Validate Provides a fluent interface
|
||||
*/
|
||||
public function addValidator(Postman_Zend_Validate_Interface $validator, $breakChainOnFailure = false)
|
||||
{
|
||||
$this->_validators[] = array(
|
||||
'instance' => $validator,
|
||||
'breakChainOnFailure' => (boolean) $breakChainOnFailure
|
||||
);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if and only if $value passes all validations in the chain
|
||||
*
|
||||
* Validators are run in the order in which they were added to the chain (FIFO).
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return boolean
|
||||
*/
|
||||
public function isValid($value)
|
||||
{
|
||||
$this->_messages = array();
|
||||
$this->_errors = array();
|
||||
$result = true;
|
||||
foreach ($this->_validators as $element) {
|
||||
$validator = $element['instance'];
|
||||
if ($validator->isValid($value)) {
|
||||
continue;
|
||||
}
|
||||
$result = false;
|
||||
$messages = $validator->getMessages();
|
||||
$this->_messages = array_merge($this->_messages, $messages);
|
||||
$this->_errors = array_merge($this->_errors, array_keys($messages));
|
||||
if ($element['breakChainOnFailure']) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defined by Postman_Zend_Validate_Interface
|
||||
*
|
||||
* Returns array of validation failure messages
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getMessages()
|
||||
{
|
||||
return $this->_messages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defined by Postman_Zend_Validate_Interface
|
||||
*
|
||||
* Returns array of validation failure message codes
|
||||
*
|
||||
* @return array
|
||||
* @deprecated Since 1.5.0
|
||||
*/
|
||||
public function getErrors()
|
||||
{
|
||||
return $this->_errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the set default namespaces
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getDefaultNamespaces()
|
||||
{
|
||||
return self::$_defaultNamespaces;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets new default namespaces
|
||||
*
|
||||
* @param array|string $namespace
|
||||
* @return null
|
||||
*/
|
||||
public static function setDefaultNamespaces($namespace)
|
||||
{
|
||||
if (!is_array($namespace)) {
|
||||
$namespace = array((string) $namespace);
|
||||
}
|
||||
|
||||
self::$_defaultNamespaces = $namespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new default namespace
|
||||
*
|
||||
* @param array|string $namespace
|
||||
* @return null
|
||||
*/
|
||||
public static function addDefaultNamespaces($namespace)
|
||||
{
|
||||
if (!is_array($namespace)) {
|
||||
$namespace = array((string) $namespace);
|
||||
}
|
||||
|
||||
self::$_defaultNamespaces = array_unique(array_merge(self::$_defaultNamespaces, $namespace));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true when defaultNamespaces are set
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static function hasDefaultNamespaces()
|
||||
{
|
||||
return (!empty(self::$_defaultNamespaces));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
* @param string $classBaseName
|
||||
* @param array $args OPTIONAL
|
||||
* @param mixed $namespaces OPTIONAL
|
||||
* @return boolean
|
||||
* @throws Postman_Zend_Validate_Exception
|
||||
*/
|
||||
public static function is($value, $classBaseName, array $args = array(), $namespaces = array())
|
||||
{
|
||||
$namespaces = array_merge((array) $namespaces, self::$_defaultNamespaces, array('Postman_Zend_Validate'));
|
||||
$className = ucfirst($classBaseName);
|
||||
try {
|
||||
if (!class_exists($className, false)) {
|
||||
require_once 'Zend/Loader.php';
|
||||
foreach($namespaces as $namespace) {
|
||||
$class = $namespace . '_' . $className;
|
||||
$file = str_replace('_', DIRECTORY_SEPARATOR, $class) . '.php';
|
||||
if (Postman_Zend_Loader::isReadable($file)) {
|
||||
Postman_Zend_Loader::loadClass($class);
|
||||
$className = $class;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$class = new ReflectionClass($className);
|
||||
if ($class->implementsInterface('Postman_Zend_Validate_Interface')) {
|
||||
if ($class->hasMethod('__construct')) {
|
||||
$keys = array_keys($args);
|
||||
$numeric = false;
|
||||
foreach($keys as $key) {
|
||||
if (is_numeric($key)) {
|
||||
$numeric = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($numeric) {
|
||||
$object = $class->newInstanceArgs($args);
|
||||
} else {
|
||||
$object = $class->newInstance($args);
|
||||
}
|
||||
} else {
|
||||
$object = $class->newInstance();
|
||||
}
|
||||
|
||||
return $object->isValid($value);
|
||||
}
|
||||
} catch (Postman_Zend_Validate_Exception $ze) {
|
||||
// if there is an exception while validating throw it
|
||||
throw $ze;
|
||||
} catch (Exception $e) {
|
||||
// fallthrough and continue for missing validation classes
|
||||
}
|
||||
|
||||
require_once 'Zend/Validate/Exception.php';
|
||||
throw new Postman_Zend_Validate_Exception("Validate class not found from basename '$classBaseName'");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximum allowed message length
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public static function getMessageLength()
|
||||
{
|
||||
require_once 'Zend/Validate/Abstract.php';
|
||||
return Postman_Zend_Validate_Abstract::getMessageLength();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the maximum allowed message length
|
||||
*
|
||||
* @param integer $length
|
||||
*/
|
||||
public static function setMessageLength($length = -1)
|
||||
{
|
||||
require_once 'Zend/Validate/Abstract.php';
|
||||
Postman_Zend_Validate_Abstract::setMessageLength($length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default translation object
|
||||
*
|
||||
* @return Postman_Zend_Translate_Adapter|null
|
||||
*/
|
||||
public static function getDefaultTranslator($translator = null)
|
||||
{
|
||||
require_once 'Zend/Validate/Abstract.php';
|
||||
return Postman_Zend_Validate_Abstract::getDefaultTranslator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a default translation object for all validation objects
|
||||
*
|
||||
* @param Postman_Zend_Translate|Postman_Zend_Translate_Adapter|null $translator
|
||||
*/
|
||||
public static function setDefaultTranslator($translator = null)
|
||||
{
|
||||
require_once 'Zend/Validate/Abstract.php';
|
||||
Postman_Zend_Validate_Abstract::setDefaultTranslator($translator);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,483 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Validate_Interface
|
||||
*/
|
||||
// require_once 'Zend/Validate/Interface.php';
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
abstract class Postman_Zend_Validate_Abstract implements Postman_Zend_Validate_Interface
|
||||
{
|
||||
/**
|
||||
* The value to be validated
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
protected $_value;
|
||||
|
||||
/**
|
||||
* Additional variables available for validation failure messages
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_messageVariables = array();
|
||||
|
||||
/**
|
||||
* Validation failure message template definitions
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_messageTemplates = array();
|
||||
|
||||
/**
|
||||
* Array of validation failure messages
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_messages = array();
|
||||
|
||||
/**
|
||||
* Flag indidcating whether or not value should be obfuscated in error
|
||||
* messages
|
||||
* @var bool
|
||||
*/
|
||||
protected $_obscureValue = false;
|
||||
|
||||
/**
|
||||
* Array of validation failure message codes
|
||||
*
|
||||
* @var array
|
||||
* @deprecated Since 1.5.0
|
||||
*/
|
||||
protected $_errors = array();
|
||||
|
||||
/**
|
||||
* Translation object
|
||||
* @var Postman_Zend_Translate
|
||||
*/
|
||||
protected $_translator;
|
||||
|
||||
/**
|
||||
* Default translation object for all validate objects
|
||||
* @var Postman_Zend_Translate
|
||||
*/
|
||||
protected static $_defaultTranslator;
|
||||
|
||||
/**
|
||||
* Is translation disabled?
|
||||
* @var Boolean
|
||||
*/
|
||||
protected $_translatorDisabled = false;
|
||||
|
||||
/**
|
||||
* Limits the maximum returned length of a error message
|
||||
*
|
||||
* @var Integer
|
||||
*/
|
||||
protected static $_messageLength = -1;
|
||||
|
||||
/**
|
||||
* Returns array of validation failure messages
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getMessages()
|
||||
{
|
||||
return $this->_messages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of the names of variables that are used in constructing validation failure messages
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getMessageVariables()
|
||||
{
|
||||
return array_keys($this->_messageVariables);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the message templates from the validator
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getMessageTemplates()
|
||||
{
|
||||
return $this->_messageTemplates;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the validation failure message template for a particular key
|
||||
*
|
||||
* @param string $messageString
|
||||
* @param string $messageKey OPTIONAL
|
||||
* @return Postman_Zend_Validate_Abstract Provides a fluent interface
|
||||
* @throws Postman_Zend_Validate_Exception
|
||||
*/
|
||||
public function setMessage($messageString, $messageKey = null)
|
||||
{
|
||||
if ($messageKey === null) {
|
||||
$keys = array_keys($this->_messageTemplates);
|
||||
foreach($keys as $key) {
|
||||
$this->setMessage($messageString, $key);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
if (!isset($this->_messageTemplates[$messageKey])) {
|
||||
// require_once 'Zend/Validate/Exception.php';
|
||||
throw new Postman_Zend_Validate_Exception("No message template exists for key '$messageKey'");
|
||||
}
|
||||
|
||||
$this->_messageTemplates[$messageKey] = $messageString;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets validation failure message templates given as an array, where the array keys are the message keys,
|
||||
* and the array values are the message template strings.
|
||||
*
|
||||
* @param array $messages
|
||||
* @return Postman_Zend_Validate_Abstract
|
||||
*/
|
||||
public function setMessages(array $messages)
|
||||
{
|
||||
foreach ($messages as $key => $message) {
|
||||
$this->setMessage($message, $key);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic function returns the value of the requested property, if and only if it is the value or a
|
||||
* message variable.
|
||||
*
|
||||
* @param string $property
|
||||
* @return mixed
|
||||
* @throws Postman_Zend_Validate_Exception
|
||||
*/
|
||||
public function __get($property)
|
||||
{
|
||||
if ($property == 'value') {
|
||||
return $this->_value;
|
||||
}
|
||||
if (array_key_exists($property, $this->_messageVariables)) {
|
||||
return $this->{$this->_messageVariables[$property]};
|
||||
}
|
||||
/**
|
||||
* @see Postman_Zend_Validate_Exception
|
||||
*/
|
||||
// require_once 'Zend/Validate/Exception.php';
|
||||
throw new Postman_Zend_Validate_Exception("No property exists by the name '$property'");
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs and returns a validation failure message with the given message key and value.
|
||||
*
|
||||
* Returns null if and only if $messageKey does not correspond to an existing template.
|
||||
*
|
||||
* If a translator is available and a translation exists for $messageKey,
|
||||
* the translation will be used.
|
||||
*
|
||||
* @param string $messageKey
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
protected function _createMessage($messageKey, $value)
|
||||
{
|
||||
if (!isset($this->_messageTemplates[$messageKey])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$message = $this->_messageTemplates[$messageKey];
|
||||
|
||||
if (null !== ($translator = $this->getTranslator())) {
|
||||
if ($translator->isTranslated($messageKey)) {
|
||||
$message = $translator->translate($messageKey);
|
||||
} else {
|
||||
$message = $translator->translate($message);
|
||||
}
|
||||
}
|
||||
|
||||
if (is_object($value)) {
|
||||
if (!in_array('__toString', get_class_methods($value))) {
|
||||
$value = get_class($value) . ' object';
|
||||
} else {
|
||||
$value = $value->__toString();
|
||||
}
|
||||
} elseif (is_array($value)) {
|
||||
$value = $this->_implodeRecursive($value);
|
||||
} else {
|
||||
$value = implode((array) $value);
|
||||
}
|
||||
|
||||
if ($this->getObscureValue()) {
|
||||
$value = str_repeat('*', strlen($value));
|
||||
}
|
||||
|
||||
$message = str_replace('%value%', $value, $message);
|
||||
foreach ($this->_messageVariables as $ident => $property) {
|
||||
$message = str_replace(
|
||||
"%$ident%",
|
||||
implode(' ', (array) $this->$property),
|
||||
$message
|
||||
);
|
||||
}
|
||||
|
||||
$length = self::getMessageLength();
|
||||
if (($length > -1) && (strlen($message) > $length)) {
|
||||
$message = substr($message, 0, (self::getMessageLength() - 3)) . '...';
|
||||
}
|
||||
|
||||
return $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Joins elements of a multidimensional array
|
||||
*
|
||||
* @param array $pieces
|
||||
* @return string
|
||||
*/
|
||||
protected function _implodeRecursive(array $pieces)
|
||||
{
|
||||
$values = array();
|
||||
foreach ($pieces as $item) {
|
||||
if (is_array($item)) {
|
||||
$values[] = $this->_implodeRecursive($item);
|
||||
} else {
|
||||
$values[] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
return implode(', ', $values);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $messageKey
|
||||
* @param string $value OPTIONAL
|
||||
* @return void
|
||||
*/
|
||||
protected function _error($messageKey, $value = null)
|
||||
{
|
||||
if ($messageKey === null) {
|
||||
$keys = array_keys($this->_messageTemplates);
|
||||
$messageKey = current($keys);
|
||||
}
|
||||
if ($value === null) {
|
||||
$value = $this->_value;
|
||||
}
|
||||
$this->_errors[] = $messageKey;
|
||||
$this->_messages[$messageKey] = $this->_createMessage($messageKey, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value to be validated and clears the messages and errors arrays
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
*/
|
||||
protected function _setValue($value)
|
||||
{
|
||||
$this->_value = $value;
|
||||
$this->_messages = array();
|
||||
$this->_errors = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns array of validation failure message codes
|
||||
*
|
||||
* @return array
|
||||
* @deprecated Since 1.5.0
|
||||
*/
|
||||
public function getErrors()
|
||||
{
|
||||
return $this->_errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set flag indicating whether or not value should be obfuscated in messages
|
||||
*
|
||||
* @param bool $flag
|
||||
* @return Postman_Zend_Validate_Abstract
|
||||
*/
|
||||
public function setObscureValue($flag)
|
||||
{
|
||||
$this->_obscureValue = (bool) $flag;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve flag indicating whether or not value should be obfuscated in
|
||||
* messages
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getObscureValue()
|
||||
{
|
||||
return $this->_obscureValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set translation object
|
||||
*
|
||||
* @param Postman_Zend_Translate|Postman_Zend_Translate_Adapter|null $translator
|
||||
* @throws Postman_Zend_Validate_Exception
|
||||
* @return Postman_Zend_Validate_Abstract
|
||||
*/
|
||||
public function setTranslator($translator = null)
|
||||
{
|
||||
if ((null === $translator) || ($translator instanceof Postman_Zend_Translate_Adapter)) {
|
||||
$this->_translator = $translator;
|
||||
} elseif ($translator instanceof Postman_Zend_Translate) {
|
||||
$this->_translator = $translator->getAdapter();
|
||||
} else {
|
||||
// require_once 'Zend/Validate/Exception.php';
|
||||
throw new Postman_Zend_Validate_Exception('Invalid translator specified');
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return translation object
|
||||
*
|
||||
* @return Postman_Zend_Translate_Adapter|null
|
||||
*/
|
||||
public function getTranslator()
|
||||
{
|
||||
if ($this->translatorIsDisabled()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (null === $this->_translator) {
|
||||
return self::getDefaultTranslator();
|
||||
}
|
||||
|
||||
return $this->_translator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this validator have its own specific translator?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasTranslator()
|
||||
{
|
||||
return (bool)$this->_translator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set default translation object for all validate objects
|
||||
*
|
||||
* @param Postman_Zend_Translate|Postman_Zend_Translate_Adapter|null $translator
|
||||
* @throws Postman_Zend_Validate_Exception
|
||||
*/
|
||||
public static function setDefaultTranslator($translator = null)
|
||||
{
|
||||
if ((null === $translator) || ($translator instanceof Postman_Zend_Translate_Adapter)) {
|
||||
self::$_defaultTranslator = $translator;
|
||||
} elseif ($translator instanceof Postman_Zend_Translate) {
|
||||
self::$_defaultTranslator = $translator->getAdapter();
|
||||
} else {
|
||||
// require_once 'Zend/Validate/Exception.php';
|
||||
throw new Postman_Zend_Validate_Exception('Invalid translator specified');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default translation object for all validate objects
|
||||
*
|
||||
* @return Postman_Zend_Translate_Adapter|null
|
||||
*/
|
||||
public static function getDefaultTranslator()
|
||||
{
|
||||
if (null === self::$_defaultTranslator) {
|
||||
// require_once 'Zend/Registry.php';
|
||||
if (Postman_Zend_Registry::isRegistered('Postman_Zend_Translate')) {
|
||||
$translator = Postman_Zend_Registry::get('Postman_Zend_Translate');
|
||||
if ($translator instanceof Postman_Zend_Translate_Adapter) {
|
||||
return $translator;
|
||||
} elseif ($translator instanceof Postman_Zend_Translate) {
|
||||
return $translator->getAdapter();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return self::$_defaultTranslator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is there a default translation object set?
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static function hasDefaultTranslator()
|
||||
{
|
||||
return (bool)self::$_defaultTranslator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate whether or not translation should be disabled
|
||||
*
|
||||
* @param bool $flag
|
||||
* @return Postman_Zend_Validate_Abstract
|
||||
*/
|
||||
public function setDisableTranslator($flag)
|
||||
{
|
||||
$this->_translatorDisabled = (bool) $flag;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is translation disabled?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function translatorIsDisabled()
|
||||
{
|
||||
return $this->_translatorDisabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximum allowed message length
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public static function getMessageLength()
|
||||
{
|
||||
return self::$_messageLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the maximum allowed message length
|
||||
*
|
||||
* @param integer $length
|
||||
*/
|
||||
public static function setMessageLength($length = -1)
|
||||
{
|
||||
self::$_messageLength = $length;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Validate_Abstract
|
||||
*/
|
||||
require_once 'Zend/Validate/Abstract.php';
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Validate_Alnum extends Postman_Zend_Validate_Abstract
|
||||
{
|
||||
const INVALID = 'alnumInvalid';
|
||||
const NOT_ALNUM = 'notAlnum';
|
||||
const STRING_EMPTY = 'alnumStringEmpty';
|
||||
|
||||
/**
|
||||
* Whether to allow white space characters; off by default
|
||||
*
|
||||
* @var boolean
|
||||
* @deprecated
|
||||
*/
|
||||
public $allowWhiteSpace;
|
||||
|
||||
/**
|
||||
* Alphanumeric filter used for validation
|
||||
*
|
||||
* @var Postman_Zend_Filter_Alnum
|
||||
*/
|
||||
protected static $_filter = null;
|
||||
|
||||
/**
|
||||
* Validation failure message template definitions
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_messageTemplates = array(
|
||||
self::INVALID => "Invalid type given. String, integer or float expected",
|
||||
self::NOT_ALNUM => "'%value%' contains characters which are non alphabetic and no digits",
|
||||
self::STRING_EMPTY => "'%value%' is an empty string",
|
||||
);
|
||||
|
||||
/**
|
||||
* Sets default option values for this instance
|
||||
*
|
||||
* @param boolean|Postman_Zend_Config $allowWhiteSpace
|
||||
*/
|
||||
public function __construct($allowWhiteSpace = false)
|
||||
{
|
||||
if ($allowWhiteSpace instanceof Postman_Zend_Config) {
|
||||
$allowWhiteSpace = $allowWhiteSpace->toArray();
|
||||
}
|
||||
|
||||
if (is_array($allowWhiteSpace)) {
|
||||
if (array_key_exists('allowWhiteSpace', $allowWhiteSpace)) {
|
||||
$allowWhiteSpace = $allowWhiteSpace['allowWhiteSpace'];
|
||||
} else {
|
||||
$allowWhiteSpace = false;
|
||||
}
|
||||
}
|
||||
|
||||
$this->allowWhiteSpace = (boolean) $allowWhiteSpace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the allowWhiteSpace option
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function getAllowWhiteSpace()
|
||||
{
|
||||
return $this->allowWhiteSpace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the allowWhiteSpace option
|
||||
*
|
||||
* @param boolean $allowWhiteSpace
|
||||
* @return Postman_Zend_Filter_Alnum Provides a fluent interface
|
||||
*/
|
||||
public function setAllowWhiteSpace($allowWhiteSpace)
|
||||
{
|
||||
$this->allowWhiteSpace = (boolean) $allowWhiteSpace;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defined by Postman_Zend_Validate_Interface
|
||||
*
|
||||
* Returns true if and only if $value contains only alphabetic and digit characters
|
||||
*
|
||||
* @param string $value
|
||||
* @return boolean
|
||||
*/
|
||||
public function isValid($value)
|
||||
{
|
||||
if (!is_string($value) && !is_int($value) && !is_float($value)) {
|
||||
$this->_error(self::INVALID);
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->_setValue($value);
|
||||
|
||||
if ('' === $value) {
|
||||
$this->_error(self::STRING_EMPTY);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (null === self::$_filter) {
|
||||
/**
|
||||
* @see Postman_Zend_Filter_Alnum
|
||||
*/
|
||||
require_once 'Zend/Filter/Alnum.php';
|
||||
self::$_filter = new Postman_Zend_Filter_Alnum();
|
||||
}
|
||||
|
||||
self::$_filter->allowWhiteSpace = $this->allowWhiteSpace;
|
||||
|
||||
if ($value != self::$_filter->filter($value)) {
|
||||
$this->_error(self::NOT_ALNUM);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Validate_Abstract
|
||||
*/
|
||||
require_once 'Zend/Validate/Abstract.php';
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Validate_Alpha extends Postman_Zend_Validate_Abstract
|
||||
{
|
||||
const INVALID = 'alphaInvalid';
|
||||
const NOT_ALPHA = 'notAlpha';
|
||||
const STRING_EMPTY = 'alphaStringEmpty';
|
||||
|
||||
/**
|
||||
* Whether to allow white space characters; off by default
|
||||
*
|
||||
* @var boolean
|
||||
* @deprecated
|
||||
*/
|
||||
public $allowWhiteSpace;
|
||||
|
||||
/**
|
||||
* Alphabetic filter used for validation
|
||||
*
|
||||
* @var Postman_Zend_Filter_Alpha
|
||||
*/
|
||||
protected static $_filter = null;
|
||||
|
||||
/**
|
||||
* Validation failure message template definitions
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_messageTemplates = array(
|
||||
self::INVALID => "Invalid type given. String expected",
|
||||
self::NOT_ALPHA => "'%value%' contains non alphabetic characters",
|
||||
self::STRING_EMPTY => "'%value%' is an empty string"
|
||||
);
|
||||
|
||||
/**
|
||||
* Sets default option values for this instance
|
||||
*
|
||||
* @param boolean|Postman_Zend_Config $allowWhiteSpace
|
||||
*/
|
||||
public function __construct($allowWhiteSpace = false)
|
||||
{
|
||||
if ($allowWhiteSpace instanceof Postman_Zend_Config) {
|
||||
$allowWhiteSpace = $allowWhiteSpace->toArray();
|
||||
}
|
||||
|
||||
if (is_array($allowWhiteSpace)) {
|
||||
if (array_key_exists('allowWhiteSpace', $allowWhiteSpace)) {
|
||||
$allowWhiteSpace = $allowWhiteSpace['allowWhiteSpace'];
|
||||
} else {
|
||||
$allowWhiteSpace = false;
|
||||
}
|
||||
}
|
||||
|
||||
$this->allowWhiteSpace = (boolean) $allowWhiteSpace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the allowWhiteSpace option
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function getAllowWhiteSpace()
|
||||
{
|
||||
return $this->allowWhiteSpace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the allowWhiteSpace option
|
||||
*
|
||||
* @param boolean $allowWhiteSpace
|
||||
* @return Postman_Zend_Filter_Alpha Provides a fluent interface
|
||||
*/
|
||||
public function setAllowWhiteSpace($allowWhiteSpace)
|
||||
{
|
||||
$this->allowWhiteSpace = (boolean) $allowWhiteSpace;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defined by Postman_Zend_Validate_Interface
|
||||
*
|
||||
* Returns true if and only if $value contains only alphabetic characters
|
||||
*
|
||||
* @param string $value
|
||||
* @return boolean
|
||||
*/
|
||||
public function isValid($value)
|
||||
{
|
||||
if (!is_string($value)) {
|
||||
$this->_error(self::INVALID);
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->_setValue($value);
|
||||
|
||||
if ('' === $value) {
|
||||
$this->_error(self::STRING_EMPTY);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (null === self::$_filter) {
|
||||
/**
|
||||
* @see Postman_Zend_Filter_Alpha
|
||||
*/
|
||||
require_once 'Zend/Filter/Alpha.php';
|
||||
self::$_filter = new Postman_Zend_Filter_Alpha();
|
||||
}
|
||||
|
||||
self::$_filter->allowWhiteSpace = $this->allowWhiteSpace;
|
||||
|
||||
if ($value !== self::$_filter->filter($value)) {
|
||||
$this->_error(self::NOT_ALPHA);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,227 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Validate_Abstract
|
||||
*/
|
||||
require_once 'Zend/Validate/Abstract.php';
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Loader
|
||||
*/
|
||||
require_once 'Zend/Loader.php';
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Validate_Barcode extends Postman_Zend_Validate_Abstract
|
||||
{
|
||||
const INVALID = 'barcodeInvalid';
|
||||
const FAILED = 'barcodeFailed';
|
||||
const INVALID_CHARS = 'barcodeInvalidChars';
|
||||
const INVALID_LENGTH = 'barcodeInvalidLength';
|
||||
|
||||
protected $_messageTemplates = array(
|
||||
self::FAILED => "'%value%' failed checksum validation",
|
||||
self::INVALID_CHARS => "'%value%' contains invalid characters",
|
||||
self::INVALID_LENGTH => "'%value%' should have a length of %length% characters",
|
||||
self::INVALID => "Invalid type given. String expected",
|
||||
);
|
||||
|
||||
/**
|
||||
* Additional variables available for validation failure messages
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_messageVariables = array(
|
||||
'length' => '_length'
|
||||
);
|
||||
|
||||
/**
|
||||
* Length for the set subtype
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $_length;
|
||||
|
||||
/**
|
||||
* Barcode adapter
|
||||
*
|
||||
* @var Postman_Zend_Validate_Barcode_BarcodeAdapter
|
||||
*/
|
||||
protected $_adapter;
|
||||
|
||||
/**
|
||||
* Generates the standard validator object
|
||||
*
|
||||
* @param string|Postman_Zend_Config|
|
||||
* Postman_Zend_Validate_Barcode_BarcodeAdapter $adapter Barcode adapter to use
|
||||
* @throws Postman_Zend_Validate_Exception
|
||||
*/
|
||||
public function __construct($adapter)
|
||||
{
|
||||
if ($adapter instanceof Postman_Zend_Config) {
|
||||
$adapter = $adapter->toArray();
|
||||
}
|
||||
|
||||
$options = null;
|
||||
$checksum = null;
|
||||
if (is_array($adapter)) {
|
||||
if (array_key_exists('options', $adapter)) {
|
||||
$options = $adapter['options'];
|
||||
}
|
||||
|
||||
if (array_key_exists('checksum', $adapter)) {
|
||||
$checksum = $adapter['checksum'];
|
||||
}
|
||||
|
||||
if (array_key_exists('adapter', $adapter)) {
|
||||
$adapter = $adapter['adapter'];
|
||||
} else {
|
||||
require_once 'Zend/Validate/Exception.php';
|
||||
throw new Postman_Zend_Validate_Exception("Missing option 'adapter'");
|
||||
}
|
||||
}
|
||||
|
||||
$this->setAdapter($adapter, $options);
|
||||
if ($checksum !== null) {
|
||||
$this->setChecksum($checksum);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the set adapter
|
||||
*
|
||||
* @return Postman_Zend_Validate_Barcode_BarcodeAdapter
|
||||
*/
|
||||
public function getAdapter()
|
||||
{
|
||||
return $this->_adapter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new barcode adapter
|
||||
*
|
||||
* @param string|Postman_Zend_Validate_Barcode $adapter Barcode adapter to use
|
||||
* @param array $options Options for this adapter
|
||||
* @return $this
|
||||
* @throws Postman_Zend_Validate_Exception
|
||||
*/
|
||||
public function setAdapter($adapter, $options = null)
|
||||
{
|
||||
$adapter = ucfirst(strtolower($adapter));
|
||||
require_once 'Zend/Loader.php';
|
||||
if (Postman_Zend_Loader::isReadable('Zend/Validate/Barcode/' . $adapter. '.php')) {
|
||||
$adapter = 'Postman_Zend_Validate_Barcode_' . $adapter;
|
||||
}
|
||||
|
||||
if (!class_exists($adapter)) {
|
||||
Postman_Zend_Loader::loadClass($adapter);
|
||||
}
|
||||
|
||||
$this->_adapter = new $adapter($options);
|
||||
if (!$this->_adapter instanceof Postman_Zend_Validate_Barcode_AdapterInterface) {
|
||||
require_once 'Zend/Validate/Exception.php';
|
||||
throw new Postman_Zend_Validate_Exception(
|
||||
"Adapter " . $adapter . " does not implement Postman_Zend_Validate_Barcode_AdapterInterface"
|
||||
);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the checksum option
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function getChecksum()
|
||||
{
|
||||
return $this->getAdapter()->getCheck();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the checksum option
|
||||
*
|
||||
* @param boolean $checksum
|
||||
* @return Postman_Zend_Validate_Barcode
|
||||
*/
|
||||
public function setChecksum($checksum)
|
||||
{
|
||||
$this->getAdapter()->setCheck($checksum);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defined by Postman_Zend_Validate_Interface
|
||||
*
|
||||
* Returns true if and only if $value contains a valid barcode
|
||||
*
|
||||
* @param string $value
|
||||
* @return boolean
|
||||
*/
|
||||
public function isValid($value)
|
||||
{
|
||||
if (!is_string($value)) {
|
||||
$this->_error(self::INVALID);
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->_setValue($value);
|
||||
$adapter = $this->getAdapter();
|
||||
$this->_length = $adapter->getLength();
|
||||
$result = $adapter->checkLength($value);
|
||||
if (!$result) {
|
||||
if (is_array($this->_length)) {
|
||||
$temp = $this->_length;
|
||||
$this->_length = "";
|
||||
foreach($temp as $length) {
|
||||
$this->_length .= "/";
|
||||
$this->_length .= $length;
|
||||
}
|
||||
|
||||
$this->_length = substr($this->_length, 1);
|
||||
}
|
||||
|
||||
$this->_error(self::INVALID_LENGTH);
|
||||
return false;
|
||||
}
|
||||
|
||||
$result = $adapter->checkChars($value);
|
||||
if (!$result) {
|
||||
$this->_error(self::INVALID_CHARS);
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->getChecksum()) {
|
||||
$result = $adapter->checksum($value);
|
||||
if (!$result) {
|
||||
$this->_error(self::FAILED);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,224 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Validate_Abstract
|
||||
*/
|
||||
require_once 'Zend/Validate/Abstract.php';
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Validate_Between extends Postman_Zend_Validate_Abstract
|
||||
{
|
||||
/**
|
||||
* Validation failure message key for when the value is not between the min and max, inclusively
|
||||
*/
|
||||
const NOT_BETWEEN = 'notBetween';
|
||||
|
||||
/**
|
||||
* Validation failure message key for when the value is not strictly between the min and max
|
||||
*/
|
||||
const NOT_BETWEEN_STRICT = 'notBetweenStrict';
|
||||
|
||||
/**
|
||||
* Validation failure message template definitions
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_messageTemplates = array(
|
||||
self::NOT_BETWEEN => "'%value%' is not between '%min%' and '%max%', inclusively",
|
||||
self::NOT_BETWEEN_STRICT => "'%value%' is not strictly between '%min%' and '%max%'"
|
||||
);
|
||||
|
||||
/**
|
||||
* Additional variables available for validation failure messages
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_messageVariables = array(
|
||||
'min' => '_min',
|
||||
'max' => '_max'
|
||||
);
|
||||
|
||||
/**
|
||||
* Minimum value
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
protected $_min;
|
||||
|
||||
/**
|
||||
* Maximum value
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
protected $_max;
|
||||
|
||||
/**
|
||||
* Whether to do inclusive comparisons, allowing equivalence to min and/or max
|
||||
*
|
||||
* If false, then strict comparisons are done, and the value may equal neither
|
||||
* the min nor max options
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
protected $_inclusive;
|
||||
|
||||
/**
|
||||
* Sets validator options
|
||||
* Accepts the following option keys:
|
||||
* 'min' => scalar, minimum border
|
||||
* 'max' => scalar, maximum border
|
||||
* 'inclusive' => boolean, inclusive border values
|
||||
*
|
||||
* @param array|Postman_Zend_Config $options
|
||||
* @throws Postman_Zend_Validate_Exception
|
||||
*/
|
||||
public function __construct($options)
|
||||
{
|
||||
if ($options instanceof Postman_Zend_Config) {
|
||||
$options = $options->toArray();
|
||||
} else if (!is_array($options)) {
|
||||
$options = func_get_args();
|
||||
$temp['min'] = array_shift($options);
|
||||
if (!empty($options)) {
|
||||
$temp['max'] = array_shift($options);
|
||||
}
|
||||
|
||||
if (!empty($options)) {
|
||||
$temp['inclusive'] = array_shift($options);
|
||||
}
|
||||
|
||||
$options = $temp;
|
||||
}
|
||||
|
||||
if (!array_key_exists('min', $options) || !array_key_exists('max', $options)) {
|
||||
require_once 'Zend/Validate/Exception.php';
|
||||
throw new Postman_Zend_Validate_Exception("Missing option. 'min' and 'max' has to be given");
|
||||
}
|
||||
|
||||
if (!array_key_exists('inclusive', $options)) {
|
||||
$options['inclusive'] = true;
|
||||
}
|
||||
|
||||
$this->setMin($options['min'])
|
||||
->setMax($options['max'])
|
||||
->setInclusive($options['inclusive']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the min option
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getMin()
|
||||
{
|
||||
return $this->_min;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the min option
|
||||
*
|
||||
* @param mixed $min
|
||||
* @return Postman_Zend_Validate_Between Provides a fluent interface
|
||||
*/
|
||||
public function setMin($min)
|
||||
{
|
||||
$this->_min = $min;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the max option
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getMax()
|
||||
{
|
||||
return $this->_max;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the max option
|
||||
*
|
||||
* @param mixed $max
|
||||
* @return Postman_Zend_Validate_Between Provides a fluent interface
|
||||
*/
|
||||
public function setMax($max)
|
||||
{
|
||||
$this->_max = $max;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the inclusive option
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function getInclusive()
|
||||
{
|
||||
return $this->_inclusive;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the inclusive option
|
||||
*
|
||||
* @param boolean $inclusive
|
||||
* @return Postman_Zend_Validate_Between Provides a fluent interface
|
||||
*/
|
||||
public function setInclusive($inclusive)
|
||||
{
|
||||
$this->_inclusive = $inclusive;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defined by Postman_Zend_Validate_Interface
|
||||
*
|
||||
* Returns true if and only if $value is between min and max options, inclusively
|
||||
* if inclusive option is true.
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return boolean
|
||||
*/
|
||||
public function isValid($value)
|
||||
{
|
||||
$this->_setValue($value);
|
||||
|
||||
if ($this->_inclusive) {
|
||||
if ($this->_min > $value || $value > $this->_max) {
|
||||
$this->_error(self::NOT_BETWEEN);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if ($this->_min >= $value || $value >= $this->_max) {
|
||||
$this->_error(self::NOT_BETWEEN_STRICT);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Validate_Abstract
|
||||
*/
|
||||
require_once 'Zend/Validate/Abstract.php';
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Validate_Callback extends Postman_Zend_Validate_Abstract
|
||||
{
|
||||
/**
|
||||
* Invalid callback
|
||||
*/
|
||||
const INVALID_CALLBACK = 'callbackInvalid';
|
||||
|
||||
/**
|
||||
* Invalid value
|
||||
*/
|
||||
const INVALID_VALUE = 'callbackValue';
|
||||
|
||||
/**
|
||||
* Validation failure message template definitions
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_messageTemplates = array(
|
||||
self::INVALID_VALUE => "'%value%' is not valid",
|
||||
self::INVALID_CALLBACK => "An exception has been raised within the callback",
|
||||
);
|
||||
|
||||
/**
|
||||
* Callback in a call_user_func format
|
||||
*
|
||||
* @var string|array
|
||||
*/
|
||||
protected $_callback = null;
|
||||
|
||||
/**
|
||||
* Default options to set for the filter
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
protected $_options = array();
|
||||
|
||||
/**
|
||||
* Sets validator options
|
||||
*
|
||||
* @param mixed $callback
|
||||
* @throws Postman_Zend_Validate_Exception
|
||||
*/
|
||||
public function __construct($callback = null)
|
||||
{
|
||||
if (is_callable($callback)) {
|
||||
$this->setCallback($callback);
|
||||
} elseif (is_array($callback)) {
|
||||
if (isset($callback['callback'])) {
|
||||
$this->setCallback($callback['callback']);
|
||||
}
|
||||
if (isset($callback['options'])) {
|
||||
$this->setOptions($callback['options']);
|
||||
}
|
||||
}
|
||||
|
||||
if (null === ($initializedCallack = $this->getCallback())) {
|
||||
require_once 'Zend/Validate/Exception.php';
|
||||
throw new Postman_Zend_Validate_Exception('No callback registered');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the set callback
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getCallback()
|
||||
{
|
||||
return $this->_callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the callback
|
||||
*
|
||||
* @param string|array $callback
|
||||
* @throws Postman_Zend_Validate_Exception
|
||||
* @return Postman_Zend_Validate_Callback Provides a fluent interface
|
||||
*/
|
||||
public function setCallback($callback)
|
||||
{
|
||||
if (!is_callable($callback)) {
|
||||
require_once 'Zend/Validate/Exception.php';
|
||||
throw new Postman_Zend_Validate_Exception('Invalid callback given');
|
||||
}
|
||||
$this->_callback = $callback;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the set options for the callback
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getOptions()
|
||||
{
|
||||
return $this->_options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets options for the callback
|
||||
*
|
||||
* @param mixed $options
|
||||
* @return Postman_Zend_Validate_Callback Provides a fluent interface
|
||||
*/
|
||||
public function setOptions($options)
|
||||
{
|
||||
$this->_options = (array) $options;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defined by Postman_Zend_Validate_Interface
|
||||
*
|
||||
* Returns true if and only if the set callback returns
|
||||
* for the provided $value
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return boolean
|
||||
*/
|
||||
public function isValid($value)
|
||||
{
|
||||
$this->_setValue($value);
|
||||
|
||||
$options = $this->getOptions();
|
||||
$callback = $this->getCallback();
|
||||
$args = func_get_args();
|
||||
$options = array_merge($args, $options);
|
||||
|
||||
try {
|
||||
if (!call_user_func_array($callback, $options)) {
|
||||
$this->_error(self::INVALID_VALUE);
|
||||
return false;
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
$this->_error(self::INVALID_CALLBACK);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Validate_Abstract
|
||||
*/
|
||||
require_once 'Zend/Validate/Abstract.php';
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Validate_Ccnum extends Postman_Zend_Validate_Abstract
|
||||
{
|
||||
/**
|
||||
* Validation failure message key for when the value is not of valid length
|
||||
*/
|
||||
const LENGTH = 'ccnumLength';
|
||||
|
||||
/**
|
||||
* Validation failure message key for when the value fails the mod-10 checksum
|
||||
*/
|
||||
const CHECKSUM = 'ccnumChecksum';
|
||||
|
||||
/**
|
||||
* Digits filter for input
|
||||
*
|
||||
* @var Postman_Zend_Filter_Digits
|
||||
*/
|
||||
protected static $_filter = null;
|
||||
|
||||
/**
|
||||
* Validation failure message template definitions
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_messageTemplates = array(
|
||||
self::LENGTH => "'%value%' must contain between 13 and 19 digits",
|
||||
self::CHECKSUM => "Luhn algorithm (mod-10 checksum) failed on '%value%'"
|
||||
);
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
trigger_error('Using the Ccnum validator is deprecated in favor of the CreditCard validator');
|
||||
}
|
||||
|
||||
/**
|
||||
* Defined by Postman_Zend_Validate_Interface
|
||||
*
|
||||
* Returns true if and only if $value follows the Luhn algorithm (mod-10 checksum)
|
||||
*
|
||||
* @param string $value
|
||||
* @return boolean
|
||||
*/
|
||||
public function isValid($value)
|
||||
{
|
||||
$this->_setValue($value);
|
||||
|
||||
if (null === self::$_filter) {
|
||||
/**
|
||||
* @see Postman_Zend_Filter_Digits
|
||||
*/
|
||||
require_once 'Zend/Filter/Digits.php';
|
||||
self::$_filter = new Postman_Zend_Filter_Digits();
|
||||
}
|
||||
|
||||
$valueFiltered = self::$_filter->filter($value);
|
||||
|
||||
$length = strlen($valueFiltered);
|
||||
|
||||
if ($length < 13 || $length > 19) {
|
||||
$this->_error(self::LENGTH);
|
||||
return false;
|
||||
}
|
||||
|
||||
$sum = 0;
|
||||
$weight = 2;
|
||||
|
||||
for ($i = $length - 2; $i >= 0; $i--) {
|
||||
$digit = $weight * $valueFiltered[$i];
|
||||
$sum += floor($digit / 10) + $digit % 10;
|
||||
$weight = $weight % 2 + 1;
|
||||
}
|
||||
|
||||
if ((10 - $sum % 10) % 10 != $valueFiltered[$length - 1]) {
|
||||
$this->_error(self::CHECKSUM, $valueFiltered);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,319 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Validate_Abstract
|
||||
*/
|
||||
require_once 'Zend/Validate/Abstract.php';
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Validate_CreditCard extends Postman_Zend_Validate_Abstract
|
||||
{
|
||||
/**
|
||||
* Detected CCI list
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const ALL = 'All';
|
||||
const AMERICAN_EXPRESS = 'American_Express';
|
||||
const UNIONPAY = 'Unionpay';
|
||||
const DINERS_CLUB = 'Diners_Club';
|
||||
const DINERS_CLUB_US = 'Diners_Club_US';
|
||||
const DISCOVER = 'Discover';
|
||||
const JCB = 'JCB';
|
||||
const LASER = 'Laser';
|
||||
const MAESTRO = 'Maestro';
|
||||
const MASTERCARD = 'Mastercard';
|
||||
const SOLO = 'Solo';
|
||||
const VISA = 'Visa';
|
||||
|
||||
const CHECKSUM = 'creditcardChecksum';
|
||||
const CONTENT = 'creditcardContent';
|
||||
const INVALID = 'creditcardInvalid';
|
||||
const LENGTH = 'creditcardLength';
|
||||
const PREFIX = 'creditcardPrefix';
|
||||
const SERVICE = 'creditcardService';
|
||||
const SERVICEFAILURE = 'creditcardServiceFailure';
|
||||
|
||||
/**
|
||||
* Validation failure message template definitions
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_messageTemplates = array(
|
||||
self::CHECKSUM => "'%value%' seems to contain an invalid checksum",
|
||||
self::CONTENT => "'%value%' must contain only digits",
|
||||
self::INVALID => "Invalid type given. String expected",
|
||||
self::LENGTH => "'%value%' contains an invalid amount of digits",
|
||||
self::PREFIX => "'%value%' is not from an allowed institute",
|
||||
self::SERVICE => "'%value%' seems to be an invalid creditcard number",
|
||||
self::SERVICEFAILURE => "An exception has been raised while validating '%value%'",
|
||||
);
|
||||
|
||||
/**
|
||||
* List of allowed CCV lengths
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_cardLength = array(
|
||||
self::AMERICAN_EXPRESS => array(15),
|
||||
self::DINERS_CLUB => array(14),
|
||||
self::DINERS_CLUB_US => array(16),
|
||||
self::DISCOVER => array(16),
|
||||
self::JCB => array(16),
|
||||
self::LASER => array(16, 17, 18, 19),
|
||||
self::MAESTRO => array(12, 13, 14, 15, 16, 17, 18, 19),
|
||||
self::MASTERCARD => array(16),
|
||||
self::SOLO => array(16, 18, 19),
|
||||
self::UNIONPAY => array(16, 17, 18, 19),
|
||||
self::VISA => array(16),
|
||||
);
|
||||
|
||||
/**
|
||||
* List of accepted CCV provider tags
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_cardType = array(
|
||||
self::AMERICAN_EXPRESS => array('34', '37'),
|
||||
self::DINERS_CLUB => array('300', '301', '302', '303', '304', '305', '36'),
|
||||
self::DINERS_CLUB_US => array('54', '55'),
|
||||
self::DISCOVER => array('6011', '622126', '622127', '622128', '622129', '62213',
|
||||
'62214', '62215', '62216', '62217', '62218', '62219',
|
||||
'6222', '6223', '6224', '6225', '6226', '6227', '6228',
|
||||
'62290', '62291', '622920', '622921', '622922', '622923',
|
||||
'622924', '622925', '644', '645', '646', '647', '648',
|
||||
'649', '65'),
|
||||
self::JCB => array('3528', '3529', '353', '354', '355', '356', '357', '358'),
|
||||
self::LASER => array('6304', '6706', '6771', '6709'),
|
||||
self::MAESTRO => array('5018', '5020', '5038', '6304', '6759', '6761', '6763'),
|
||||
self::MASTERCARD => array('51', '52', '53', '54', '55'),
|
||||
self::SOLO => array('6334', '6767'),
|
||||
self::UNIONPAY => array('622126', '622127', '622128', '622129', '62213', '62214',
|
||||
'62215', '62216', '62217', '62218', '62219', '6222', '6223',
|
||||
'6224', '6225', '6226', '6227', '6228', '62290', '62291',
|
||||
'622920', '622921', '622922', '622923', '622924', '622925'),
|
||||
self::VISA => array('4'),
|
||||
);
|
||||
|
||||
/**
|
||||
* CCIs which are accepted by validation
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_type = array();
|
||||
|
||||
/**
|
||||
* Service callback for additional validation
|
||||
*
|
||||
* @var callback
|
||||
*/
|
||||
protected $_service;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string|array|Postman_Zend_Config $options OPTIONAL Type of CCI to allow
|
||||
*/
|
||||
public function __construct($options = array())
|
||||
{
|
||||
if ($options instanceof Postman_Zend_Config) {
|
||||
$options = $options->toArray();
|
||||
} else if (!is_array($options)) {
|
||||
$options = func_get_args();
|
||||
$temp['type'] = array_shift($options);
|
||||
if (!empty($options)) {
|
||||
$temp['service'] = array_shift($options);
|
||||
}
|
||||
|
||||
$options = $temp;
|
||||
}
|
||||
|
||||
if (!array_key_exists('type', $options)) {
|
||||
$options['type'] = self::ALL;
|
||||
}
|
||||
|
||||
$this->setType($options['type']);
|
||||
if (array_key_exists('service', $options)) {
|
||||
$this->setService($options['service']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of accepted CCIs
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
return $this->_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets CCIs which are accepted by validation
|
||||
*
|
||||
* @param string|array $type Type to allow for validation
|
||||
* @return Postman_Zend_Validate_CreditCard Provides a fluent interface
|
||||
*/
|
||||
public function setType($type)
|
||||
{
|
||||
$this->_type = array();
|
||||
return $this->addType($type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a CCI to be accepted by validation
|
||||
*
|
||||
* @param string|array $type Type to allow for validation
|
||||
* @return Postman_Zend_Validate_CreditCard Provides a fluent interface
|
||||
*/
|
||||
public function addType($type)
|
||||
{
|
||||
if (is_string($type)) {
|
||||
$type = array($type);
|
||||
}
|
||||
|
||||
foreach($type as $typ) {
|
||||
if (defined('self::' . strtoupper($typ)) && !in_array($typ, $this->_type)) {
|
||||
$this->_type[] = $typ;
|
||||
}
|
||||
|
||||
if (($typ == self::ALL)) {
|
||||
$this->_type = array_keys($this->_cardLength);
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the actual set service
|
||||
*
|
||||
* @return callback
|
||||
*/
|
||||
public function getService()
|
||||
{
|
||||
return $this->_service;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new callback for service validation
|
||||
*
|
||||
* @param mixed $service
|
||||
* @throws Postman_Zend_Validate_Exception
|
||||
* @return $this
|
||||
*/
|
||||
public function setService($service)
|
||||
{
|
||||
if (!is_callable($service)) {
|
||||
require_once 'Zend/Validate/Exception.php';
|
||||
throw new Postman_Zend_Validate_Exception('Invalid callback given');
|
||||
}
|
||||
|
||||
$this->_service = $service;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defined by Postman_Zend_Validate_Interface
|
||||
*
|
||||
* Returns true if and only if $value follows the Luhn algorithm (mod-10 checksum)
|
||||
*
|
||||
* @param string $value
|
||||
* @return boolean
|
||||
*/
|
||||
public function isValid($value)
|
||||
{
|
||||
$this->_setValue($value);
|
||||
|
||||
if (!is_string($value)) {
|
||||
$this->_error(self::INVALID, $value);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ctype_digit($value)) {
|
||||
$this->_error(self::CONTENT, $value);
|
||||
return false;
|
||||
}
|
||||
|
||||
$length = strlen($value);
|
||||
$types = $this->getType();
|
||||
$foundp = false;
|
||||
$foundl = false;
|
||||
foreach ($types as $type) {
|
||||
foreach ($this->_cardType[$type] as $prefix) {
|
||||
if (substr($value, 0, strlen($prefix)) == $prefix) {
|
||||
$foundp = true;
|
||||
if (in_array($length, $this->_cardLength[$type])) {
|
||||
$foundl = true;
|
||||
break 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($foundp == false){
|
||||
$this->_error(self::PREFIX, $value);
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($foundl == false) {
|
||||
$this->_error(self::LENGTH, $value);
|
||||
return false;
|
||||
}
|
||||
|
||||
$sum = 0;
|
||||
$weight = 2;
|
||||
|
||||
for ($i = $length - 2; $i >= 0; $i--) {
|
||||
$digit = $weight * $value[$i];
|
||||
$sum += floor($digit / 10) + $digit % 10;
|
||||
$weight = $weight % 2 + 1;
|
||||
}
|
||||
|
||||
if ((10 - $sum % 10) % 10 != $value[$length - 1]) {
|
||||
$this->_error(self::CHECKSUM, $value);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!empty($this->_service)) {
|
||||
try {
|
||||
require_once 'Zend/Validate/Callback.php';
|
||||
$callback = new Postman_Zend_Validate_Callback($this->_service);
|
||||
$callback->setOptions($this->_type);
|
||||
if (!$callback->isValid($value)) {
|
||||
$this->_error(self::SERVICE, $value);
|
||||
return false;
|
||||
}
|
||||
} catch (Postman_Zend_Exception $e) {
|
||||
$this->_error(self::SERVICEFAILURE, $value);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,258 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Validate_Abstract
|
||||
*/
|
||||
require_once 'Zend/Validate/Abstract.php';
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Validate_Date extends Postman_Zend_Validate_Abstract
|
||||
{
|
||||
const INVALID = 'dateInvalid';
|
||||
const INVALID_DATE = 'dateInvalidDate';
|
||||
const FALSEFORMAT = 'dateFalseFormat';
|
||||
|
||||
/**
|
||||
* Validation failure message template definitions
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_messageTemplates = array(
|
||||
self::INVALID => "Invalid type given. String, integer, array or Postman_Zend_Date expected",
|
||||
self::INVALID_DATE => "'%value%' does not appear to be a valid date",
|
||||
self::FALSEFORMAT => "'%value%' does not fit the date format '%format%'",
|
||||
);
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $_messageVariables = array(
|
||||
'format' => '_format'
|
||||
);
|
||||
|
||||
/**
|
||||
* Optional format
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
protected $_format;
|
||||
|
||||
/**
|
||||
* Optional locale
|
||||
*
|
||||
* @var string|Postman_Zend_Locale|null
|
||||
*/
|
||||
protected $_locale;
|
||||
|
||||
/**
|
||||
* Sets validator options
|
||||
*
|
||||
* @param string|array|Postman_Zend_Config $options OPTIONAL
|
||||
*/
|
||||
public function __construct($options = array())
|
||||
{
|
||||
if ($options instanceof Postman_Zend_Config) {
|
||||
$options = $options->toArray();
|
||||
} else if (!is_array($options)) {
|
||||
$options = func_get_args();
|
||||
$temp['format'] = array_shift($options);
|
||||
if (!empty($options)) {
|
||||
$temp['locale'] = array_shift($options);
|
||||
}
|
||||
|
||||
$options = $temp;
|
||||
}
|
||||
|
||||
if (array_key_exists('format', $options)) {
|
||||
$this->setFormat($options['format']);
|
||||
}
|
||||
|
||||
if (!array_key_exists('locale', $options)) {
|
||||
require_once 'Zend/Registry.php';
|
||||
if (Postman_Zend_Registry::isRegistered('Postman_Zend_Locale')) {
|
||||
$options['locale'] = Postman_Zend_Registry::get('Postman_Zend_Locale');
|
||||
}
|
||||
}
|
||||
|
||||
if (array_key_exists('locale', $options)) {
|
||||
$this->setLocale($options['locale']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the locale option
|
||||
*
|
||||
* @return string|Postman_Zend_Locale|null
|
||||
*/
|
||||
public function getLocale()
|
||||
{
|
||||
return $this->_locale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the locale option
|
||||
*
|
||||
* @param string|Postman_Zend_Locale $locale
|
||||
* @return Postman_Zend_Validate_Date provides a fluent interface
|
||||
*/
|
||||
public function setLocale($locale = null)
|
||||
{
|
||||
require_once 'Zend/Locale.php';
|
||||
$this->_locale = Postman_Zend_Locale::findLocale($locale);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the locale option
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getFormat()
|
||||
{
|
||||
return $this->_format;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the format option
|
||||
*
|
||||
* @param string $format
|
||||
* @return Postman_Zend_Validate_Date provides a fluent interface
|
||||
*/
|
||||
public function setFormat($format = null)
|
||||
{
|
||||
$this->_format = $format;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defined by Postman_Zend_Validate_Interface
|
||||
*
|
||||
* Returns true if $value is a valid date of the format YYYY-MM-DD
|
||||
* If optional $format or $locale is set the date format is checked
|
||||
* according to Postman_Zend_Date, see Postman_Zend_Date::isDate()
|
||||
*
|
||||
* @param string|array|Postman_Zend_Date $value
|
||||
* @return boolean
|
||||
*/
|
||||
public function isValid($value)
|
||||
{
|
||||
if (!is_string($value) && !is_int($value) && !is_float($value) &&
|
||||
!is_array($value) && !($value instanceof Postman_Zend_Date)) {
|
||||
$this->_error(self::INVALID);
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->_setValue($value);
|
||||
|
||||
if (($this->_format !== null) || ($this->_locale !== null) || is_array($value) ||
|
||||
$value instanceof Postman_Zend_Date) {
|
||||
require_once 'Zend/Date.php';
|
||||
if (!Postman_Zend_Date::isDate($value, $this->_format, $this->_locale)) {
|
||||
if ($this->_checkFormat($value) === false) {
|
||||
$this->_error(self::FALSEFORMAT);
|
||||
} else {
|
||||
$this->_error(self::INVALID_DATE);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $value)) {
|
||||
$this->_format = 'yyyy-MM-dd';
|
||||
$this->_error(self::FALSEFORMAT);
|
||||
$this->_format = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
list($year, $month, $day) = sscanf($value, '%d-%d-%d');
|
||||
|
||||
if (!checkdate($month, $day, $year)) {
|
||||
$this->_error(self::INVALID_DATE);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given date fits the given format
|
||||
*
|
||||
* @param string $value Date to check
|
||||
* @return boolean False when date does not fit the format
|
||||
*/
|
||||
private function _checkFormat($value)
|
||||
{
|
||||
try {
|
||||
require_once 'Zend/Locale/Format.php';
|
||||
$parsed = Postman_Zend_Locale_Format::getDate($value, array(
|
||||
'date_format' => $this->_format, 'format_type' => 'iso',
|
||||
'fix_date' => false));
|
||||
if (isset($parsed['year']) and ((strpos(strtoupper($this->_format), 'YY') !== false) and
|
||||
(strpos(strtoupper($this->_format), 'YYYY') === false))) {
|
||||
$parsed['year'] = Postman_Zend_Date::getFullYear($parsed['year']);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
// Date can not be parsed
|
||||
return false;
|
||||
}
|
||||
|
||||
if (((strpos($this->_format, 'Y') !== false) or (strpos($this->_format, 'y') !== false)) and
|
||||
(!isset($parsed['year']))) {
|
||||
// Year expected but not found
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((strpos($this->_format, 'M') !== false) and (!isset($parsed['month']))) {
|
||||
// Month expected but not found
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((strpos($this->_format, 'd') !== false) and (!isset($parsed['day']))) {
|
||||
// Day expected but not found
|
||||
return false;
|
||||
}
|
||||
|
||||
if (((strpos($this->_format, 'H') !== false) or (strpos($this->_format, 'h') !== false)) and
|
||||
(!isset($parsed['hour']))) {
|
||||
// Hour expected but not found
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((strpos($this->_format, 'm') !== false) and (!isset($parsed['minute']))) {
|
||||
// Minute expected but not found
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((strpos($this->_format, 's') !== false) and (!isset($parsed['second']))) {
|
||||
// Second expected but not found
|
||||
return false;
|
||||
}
|
||||
|
||||
// Date fits the format
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Validate_Abstract
|
||||
*/
|
||||
require_once 'Zend/Validate/Abstract.php';
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Validate_Digits extends Postman_Zend_Validate_Abstract
|
||||
{
|
||||
const NOT_DIGITS = 'notDigits';
|
||||
const STRING_EMPTY = 'digitsStringEmpty';
|
||||
const INVALID = 'digitsInvalid';
|
||||
|
||||
/**
|
||||
* Digits filter used for validation
|
||||
*
|
||||
* @var Postman_Zend_Filter_Digits
|
||||
*/
|
||||
protected static $_filter = null;
|
||||
|
||||
/**
|
||||
* Validation failure message template definitions
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_messageTemplates = array(
|
||||
self::NOT_DIGITS => "'%value%' must contain only digits",
|
||||
self::STRING_EMPTY => "'%value%' is an empty string",
|
||||
self::INVALID => "Invalid type given. String, integer or float expected",
|
||||
);
|
||||
|
||||
/**
|
||||
* Defined by Postman_Zend_Validate_Interface
|
||||
*
|
||||
* Returns true if and only if $value only contains digit characters
|
||||
*
|
||||
* @param string $value
|
||||
* @return boolean
|
||||
*/
|
||||
public function isValid($value)
|
||||
{
|
||||
if (!is_string($value) && !is_int($value) && !is_float($value)) {
|
||||
$this->_error(self::INVALID);
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->_setValue((string) $value);
|
||||
|
||||
if ('' === $this->_value) {
|
||||
$this->_error(self::STRING_EMPTY);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (null === self::$_filter) {
|
||||
require_once 'Zend/Filter/Digits.php';
|
||||
self::$_filter = new Postman_Zend_Filter_Digits();
|
||||
}
|
||||
|
||||
if ($this->_value !== self::$_filter->filter($this->_value)) {
|
||||
$this->_error(self::NOT_DIGITS);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,574 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Validate_Abstract
|
||||
*/
|
||||
// require_once 'Zend/Validate/Abstract.php';
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Validate_Hostname
|
||||
*/
|
||||
// require_once 'Zend/Validate/Hostname.php';
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Validate_EmailAddress extends Postman_Zend_Validate_Abstract
|
||||
{
|
||||
const INVALID = 'emailAddressInvalid';
|
||||
const INVALID_FORMAT = 'emailAddressInvalidFormat';
|
||||
const INVALID_HOSTNAME = 'emailAddressInvalidHostname';
|
||||
const INVALID_MX_RECORD = 'emailAddressInvalidMxRecord';
|
||||
const INVALID_SEGMENT = 'emailAddressInvalidSegment';
|
||||
const DOT_ATOM = 'emailAddressDotAtom';
|
||||
const QUOTED_STRING = 'emailAddressQuotedString';
|
||||
const INVALID_LOCAL_PART = 'emailAddressInvalidLocalPart';
|
||||
const LENGTH_EXCEEDED = 'emailAddressLengthExceeded';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $_messageTemplates = array(
|
||||
self::INVALID => "Invalid type given. String expected",
|
||||
self::INVALID_FORMAT => "'%value%' is not a valid email address in the basic format local-part@hostname",
|
||||
self::INVALID_HOSTNAME => "'%hostname%' is not a valid hostname for email address '%value%'",
|
||||
self::INVALID_MX_RECORD => "'%hostname%' does not appear to have a valid MX record for the email address '%value%'",
|
||||
self::INVALID_SEGMENT => "'%hostname%' is not in a routable network segment. The email address '%value%' should not be resolved from public network",
|
||||
self::DOT_ATOM => "'%localPart%' can not be matched against dot-atom format",
|
||||
self::QUOTED_STRING => "'%localPart%' can not be matched against quoted-string format",
|
||||
self::INVALID_LOCAL_PART => "'%localPart%' is not a valid local part for email address '%value%'",
|
||||
self::LENGTH_EXCEEDED => "'%value%' exceeds the allowed length",
|
||||
);
|
||||
|
||||
/**
|
||||
* As of RFC5753 (JAN 2010), the following blocks are no logner reserved:
|
||||
* - 128.0.0.0/16
|
||||
* - 191.255.0.0/16
|
||||
* - 223.255.255.0/24
|
||||
* @see http://tools.ietf.org/html/rfc5735#page-6
|
||||
*
|
||||
* As of RFC6598 (APR 2012), the following blocks are now reserved:
|
||||
* - 100.64.0.0/10
|
||||
* @see http://tools.ietf.org/html/rfc6598#section-7
|
||||
*
|
||||
* @see http://en.wikipedia.org/wiki/IPv4
|
||||
* @var array
|
||||
*/
|
||||
protected $_invalidIp = array(
|
||||
'0' => '0.0.0.0/8',
|
||||
'10' => '10.0.0.0/8',
|
||||
'100' => '100.64.0.0/10',
|
||||
'127' => '127.0.0.0/8',
|
||||
'169' => '169.254.0.0/16',
|
||||
'172' => '172.16.0.0/12',
|
||||
'192' => array(
|
||||
'192.0.0.0/24',
|
||||
'192.0.2.0/24',
|
||||
'192.88.99.0/24',
|
||||
'192.168.0.0/16'
|
||||
),
|
||||
'198' => '198.18.0.0/15',
|
||||
'224' => '224.0.0.0/4',
|
||||
'240' => '240.0.0.0/4'
|
||||
);
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $_messageVariables = array(
|
||||
'hostname' => '_hostname',
|
||||
'localPart' => '_localPart'
|
||||
);
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $_hostname;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $_localPart;
|
||||
|
||||
/**
|
||||
* Internal options array
|
||||
*/
|
||||
protected $_options = array(
|
||||
'mx' => false,
|
||||
'deep' => false,
|
||||
'domain' => true,
|
||||
'allow' => Postman_Zend_Validate_Hostname::ALLOW_DNS,
|
||||
'hostname' => null
|
||||
);
|
||||
|
||||
/**
|
||||
* Instantiates hostname validator for local use
|
||||
*
|
||||
* The following option keys are supported:
|
||||
* 'hostname' => A hostname validator, see Postman_Zend_Validate_Hostname
|
||||
* 'allow' => Options for the hostname validator, see Postman_Zend_Validate_Hostname::ALLOW_*
|
||||
* 'mx' => If MX check should be enabled, boolean
|
||||
* 'deep' => If a deep MX check should be done, boolean
|
||||
*
|
||||
* @param array|string|Postman_Zend_Config $options OPTIONAL
|
||||
*/
|
||||
public function __construct($options = array())
|
||||
{
|
||||
if ($options instanceof Postman_Zend_Config) {
|
||||
$options = $options->toArray();
|
||||
} else if (!is_array($options)) {
|
||||
$options = func_get_args();
|
||||
$temp['allow'] = array_shift($options);
|
||||
if (!empty($options)) {
|
||||
$temp['mx'] = array_shift($options);
|
||||
}
|
||||
|
||||
if (!empty($options)) {
|
||||
$temp['hostname'] = array_shift($options);
|
||||
}
|
||||
|
||||
$options = $temp;
|
||||
}
|
||||
|
||||
$options += $this->_options;
|
||||
$this->setOptions($options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all set Options
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getOptions()
|
||||
{
|
||||
return $this->_options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set options for the email validator
|
||||
*
|
||||
* @param array $options
|
||||
* @return Postman_Zend_Validate_EmailAddress Provides a fluent inteface
|
||||
*/
|
||||
public function setOptions(array $options = array())
|
||||
{
|
||||
if (array_key_exists('messages', $options)) {
|
||||
$this->setMessages($options['messages']);
|
||||
}
|
||||
|
||||
if (array_key_exists('hostname', $options)) {
|
||||
if (array_key_exists('allow', $options)) {
|
||||
$this->setHostnameValidator($options['hostname'], $options['allow']);
|
||||
} else {
|
||||
$this->setHostnameValidator($options['hostname']);
|
||||
}
|
||||
} elseif ($this->_options['hostname'] == null) {
|
||||
$this->setHostnameValidator();
|
||||
}
|
||||
|
||||
if (array_key_exists('mx', $options)) {
|
||||
$this->setValidateMx($options['mx']);
|
||||
}
|
||||
|
||||
if (array_key_exists('deep', $options)) {
|
||||
$this->setDeepMxCheck($options['deep']);
|
||||
}
|
||||
|
||||
if (array_key_exists('domain', $options)) {
|
||||
$this->setDomainCheck($options['domain']);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the validation failure message template for a particular key
|
||||
* Adds the ability to set messages to the attached hostname validator
|
||||
*
|
||||
* @param string $messageString
|
||||
* @param string $messageKey OPTIONAL
|
||||
* @return Postman_Zend_Validate_Abstract Provides a fluent interface
|
||||
* @throws Postman_Zend_Validate_Exception
|
||||
*/
|
||||
public function setMessage($messageString, $messageKey = null)
|
||||
{
|
||||
if ($messageKey === null) {
|
||||
$this->_options['hostname']->setMessage($messageString);
|
||||
parent::setMessage($messageString);
|
||||
return $this;
|
||||
}
|
||||
|
||||
if (!isset($this->_messageTemplates[$messageKey])) {
|
||||
$this->_options['hostname']->setMessage($messageString, $messageKey);
|
||||
}
|
||||
|
||||
$this->_messageTemplates[$messageKey] = $messageString;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the set hostname validator
|
||||
*
|
||||
* @return Postman_Zend_Validate_Hostname
|
||||
*/
|
||||
public function getHostnameValidator()
|
||||
{
|
||||
return $this->_options['hostname'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Postman_Zend_Validate_Hostname $hostnameValidator OPTIONAL
|
||||
* @param int $allow OPTIONAL
|
||||
* @return $this
|
||||
*/
|
||||
public function setHostnameValidator(?Postman_Zend_Validate_Hostname $hostnameValidator = null, $allow = Postman_Zend_Validate_Hostname::ALLOW_DNS)
|
||||
{
|
||||
if (!$hostnameValidator) {
|
||||
$hostnameValidator = new Postman_Zend_Validate_Hostname($allow);
|
||||
}
|
||||
|
||||
$this->_options['hostname'] = $hostnameValidator;
|
||||
$this->_options['allow'] = $allow;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether MX checking via getmxrr is supported or not
|
||||
*
|
||||
* This currently only works on UNIX systems
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function validateMxSupported()
|
||||
{
|
||||
return function_exists('getmxrr');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the set validateMx option
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function getValidateMx()
|
||||
{
|
||||
return $this->_options['mx'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether we check for a valid MX record via DNS
|
||||
*
|
||||
* This only applies when DNS hostnames are validated
|
||||
*
|
||||
* @param boolean $mx Set allowed to true to validate for MX records, and false to not validate them
|
||||
* @throws Postman_Zend_Validate_Exception
|
||||
* @return Postman_Zend_Validate_EmailAddress Provides a fluent inteface
|
||||
*/
|
||||
public function setValidateMx($mx)
|
||||
{
|
||||
if ((bool) $mx && !$this->validateMxSupported()) {
|
||||
// require_once 'Zend/Validate/Exception.php';
|
||||
throw new Postman_Zend_Validate_Exception('MX checking not available on this system');
|
||||
}
|
||||
|
||||
$this->_options['mx'] = (bool) $mx;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the set deepMxCheck option
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function getDeepMxCheck()
|
||||
{
|
||||
return $this->_options['deep'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether we check MX record should be a deep validation
|
||||
*
|
||||
* @param boolean $deep Set deep to true to perform a deep validation process for MX records
|
||||
* @return Postman_Zend_Validate_EmailAddress Provides a fluent inteface
|
||||
*/
|
||||
public function setDeepMxCheck($deep)
|
||||
{
|
||||
$this->_options['deep'] = (bool) $deep;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the set domainCheck option
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getDomainCheck()
|
||||
{
|
||||
return $this->_options['domain'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets if the domain should also be checked
|
||||
* or only the local part of the email address
|
||||
*
|
||||
* @param boolean $domain
|
||||
* @return Postman_Zend_Validate_EmailAddress Provides a fluent inteface
|
||||
*/
|
||||
public function setDomainCheck($domain = true)
|
||||
{
|
||||
$this->_options['domain'] = (boolean) $domain;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if the given host is reserved
|
||||
*
|
||||
* @param string $host
|
||||
* @return boolean
|
||||
*/
|
||||
private function _isReserved($host){
|
||||
if (!preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $host)) {
|
||||
$host = gethostbyname($host);
|
||||
}
|
||||
|
||||
$octet = explode('.',$host);
|
||||
if ((int)$octet[0] >= 224) {
|
||||
return true;
|
||||
} else if (array_key_exists($octet[0], $this->_invalidIp)) {
|
||||
foreach ((array)$this->_invalidIp[$octet[0]] as $subnetData) {
|
||||
// we skip the first loop as we already know that octet matches
|
||||
for ($i = 1; $i < 4; $i++) {
|
||||
if (strpos($subnetData, $octet[$i]) !== $i * 4) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$host = explode("/", $subnetData);
|
||||
$binaryHost = "";
|
||||
$tmp = explode(".", $host[0]);
|
||||
for ($i = 0; $i < 4 ; $i++) {
|
||||
$binaryHost .= str_pad(decbin($tmp[$i]), 8, "0", STR_PAD_LEFT);
|
||||
}
|
||||
|
||||
$segmentData = array(
|
||||
'network' => (int)$this->_toIp(str_pad(substr($binaryHost, 0, $host[1]), 32, 0)),
|
||||
'broadcast' => (int)$this->_toIp(str_pad(substr($binaryHost, 0, $host[1]), 32, 1))
|
||||
);
|
||||
|
||||
for ($j = $i; $j < 4; $j++) {
|
||||
if ((int)$octet[$j] < $segmentData['network'][$j] ||
|
||||
(int)$octet[$j] > $segmentData['broadcast'][$j]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a binary string to an IP address
|
||||
*
|
||||
* @param string $binary
|
||||
* @return mixed
|
||||
*/
|
||||
private function _toIp($binary)
|
||||
{
|
||||
$ip = array();
|
||||
$tmp = explode(".", chunk_split($binary, 8, "."));
|
||||
for ($i = 0; $i < 4 ; $i++) {
|
||||
$ip[$i] = bindec($tmp[$i]);
|
||||
}
|
||||
|
||||
return $ip;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method to validate the local part of the email address
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
private function _validateLocalPart()
|
||||
{
|
||||
// First try to match the local part on the common dot-atom format
|
||||
$result = false;
|
||||
|
||||
// Dot-atom characters are: 1*atext *("." 1*atext)
|
||||
// atext: ALPHA / DIGIT / and "!", "#", "$", "%", "&", "'", "*",
|
||||
// "+", "-", "/", "=", "?", "^", "_", "`", "{", "|", "}", "~"
|
||||
$atext = 'a-zA-Z0-9\x21\x23\x24\x25\x26\x27\x2a\x2b\x2d\x2f\x3d\x3f\x5e\x5f\x60\x7b\x7c\x7d\x7e';
|
||||
if (preg_match('/^[' . $atext . ']+(\x2e+[' . $atext . ']+)*$/', $this->_localPart)) {
|
||||
$result = true;
|
||||
} else {
|
||||
// Try quoted string format (RFC 5321 Chapter 4.1.2)
|
||||
|
||||
// Quoted-string characters are: DQUOTE *(qtext/quoted-pair) DQUOTE
|
||||
$qtext = '\x20-\x21\x23-\x5b\x5d-\x7e'; // %d32-33 / %d35-91 / %d93-126
|
||||
$quotedPair = '\x20-\x7e'; // %d92 %d32-126
|
||||
if (preg_match('/^"(['. $qtext .']|\x5c[' . $quotedPair . '])*"$/', $this->localPart)) {
|
||||
$result = true;
|
||||
} else {
|
||||
$this->_error(self::DOT_ATOM);
|
||||
$this->_error(self::QUOTED_STRING);
|
||||
$this->_error(self::INVALID_LOCAL_PART);
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method to validate the servers MX records
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
private function _validateMXRecords()
|
||||
{
|
||||
$mxHosts = array();
|
||||
$hostname = $this->_hostname;
|
||||
|
||||
//decode IDN domain name if possible
|
||||
if (function_exists('idn_to_ascii')) {
|
||||
$hostname = idn_to_ascii($this->_hostname);
|
||||
}
|
||||
|
||||
$result = getmxrr($hostname, $mxHosts);
|
||||
if (!$result) {
|
||||
$this->_error(self::INVALID_MX_RECORD);
|
||||
} else if ($this->_options['deep'] && function_exists('checkdnsrr')) {
|
||||
$validAddress = false;
|
||||
$reserved = true;
|
||||
foreach ($mxHosts as $hostname) {
|
||||
$res = $this->_isReserved($hostname);
|
||||
if (!$res) {
|
||||
$reserved = false;
|
||||
}
|
||||
|
||||
if (!$res
|
||||
&& (checkdnsrr($hostname, "A")
|
||||
|| checkdnsrr($hostname, "AAAA")
|
||||
|| checkdnsrr($hostname, "A6"))) {
|
||||
$validAddress = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$validAddress) {
|
||||
$result = false;
|
||||
if ($reserved) {
|
||||
$this->_error(self::INVALID_SEGMENT);
|
||||
} else {
|
||||
$this->_error(self::INVALID_MX_RECORD);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method to validate the hostname part of the email address
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
private function _validateHostnamePart()
|
||||
{
|
||||
$hostname = $this->_options['hostname']->setTranslator($this->getTranslator())
|
||||
->isValid($this->_hostname);
|
||||
if (!$hostname) {
|
||||
$this->_error(self::INVALID_HOSTNAME);
|
||||
|
||||
// Get messages and errors from hostnameValidator
|
||||
foreach ($this->_options['hostname']->getMessages() as $code => $message) {
|
||||
$this->_messages[$code] = $message;
|
||||
}
|
||||
|
||||
foreach ($this->_options['hostname']->getErrors() as $error) {
|
||||
$this->_errors[] = $error;
|
||||
}
|
||||
} else if ($this->_options['mx']) {
|
||||
// MX check on hostname
|
||||
$hostname = $this->_validateMXRecords();
|
||||
}
|
||||
|
||||
return $hostname;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defined by Postman_Zend_Validate_Interface
|
||||
*
|
||||
* Returns true if and only if $value is a valid email address
|
||||
* according to RFC2822
|
||||
*
|
||||
* @link http://www.ietf.org/rfc/rfc2822.txt RFC2822
|
||||
* @link http://www.columbia.edu/kermit/ascii.html US-ASCII characters
|
||||
* @param string $value
|
||||
* @return boolean
|
||||
*/
|
||||
public function isValid($value)
|
||||
{
|
||||
if (!is_string($value)) {
|
||||
$this->_error(self::INVALID);
|
||||
return false;
|
||||
}
|
||||
|
||||
$matches = array();
|
||||
$length = true;
|
||||
$this->_setValue($value);
|
||||
|
||||
// Split email address up and disallow '..'
|
||||
if ((strpos($value, '..') !== false) or
|
||||
(!preg_match('/^(.+)@([^@]+)$/', $value, $matches))) {
|
||||
$this->_error(self::INVALID_FORMAT);
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->_localPart = $matches[1];
|
||||
$this->_hostname = $matches[2];
|
||||
|
||||
if ((strlen($this->_localPart) > 64) || (strlen($this->_hostname) > 255)) {
|
||||
$length = false;
|
||||
$this->_error(self::LENGTH_EXCEEDED);
|
||||
}
|
||||
|
||||
// Match hostname part
|
||||
if ($this->_options['domain']) {
|
||||
$hostname = $this->_validateHostnamePart();
|
||||
}
|
||||
|
||||
$local = $this->_validateLocalPart();
|
||||
|
||||
// If both parts valid, return true
|
||||
if ($local && $length) {
|
||||
if (($this->_options['domain'] && $hostname) || !$this->_options['domain']) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Exception
|
||||
*/
|
||||
// require_once 'Zend/Exception.php';
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Validate_Exception extends Postman_Zend_Exception
|
||||
{}
|
||||
@@ -0,0 +1,135 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Validate_Abstract
|
||||
*/
|
||||
require_once 'Zend/Validate/Abstract.php';
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Locale_Format
|
||||
*/
|
||||
require_once 'Zend/Locale/Format.php';
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Validate_Float extends Postman_Zend_Validate_Abstract
|
||||
{
|
||||
const INVALID = 'floatInvalid';
|
||||
const NOT_FLOAT = 'notFloat';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $_messageTemplates = array(
|
||||
self::INVALID => "Invalid type given. String, integer or float expected",
|
||||
self::NOT_FLOAT => "'%value%' does not appear to be a float",
|
||||
);
|
||||
|
||||
protected $_locale;
|
||||
|
||||
/**
|
||||
* Constructor for the float validator
|
||||
*
|
||||
* @param string|Postman_Zend_Config|Postman_Zend_Locale $locale
|
||||
*/
|
||||
public function __construct($locale = null)
|
||||
{
|
||||
if ($locale instanceof Postman_Zend_Config) {
|
||||
$locale = $locale->toArray();
|
||||
}
|
||||
|
||||
if (is_array($locale)) {
|
||||
if (array_key_exists('locale', $locale)) {
|
||||
$locale = $locale['locale'];
|
||||
} else {
|
||||
$locale = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($locale)) {
|
||||
require_once 'Zend/Registry.php';
|
||||
if (Postman_Zend_Registry::isRegistered('Postman_Zend_Locale')) {
|
||||
$locale = Postman_Zend_Registry::get('Postman_Zend_Locale');
|
||||
}
|
||||
}
|
||||
|
||||
$this->setLocale($locale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the set locale
|
||||
*/
|
||||
public function getLocale()
|
||||
{
|
||||
return $this->_locale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the locale to use
|
||||
*
|
||||
* @param string|Postman_Zend_Locale $locale
|
||||
* @return $this
|
||||
*/
|
||||
public function setLocale($locale = null)
|
||||
{
|
||||
require_once 'Zend/Locale.php';
|
||||
$this->_locale = Postman_Zend_Locale::findLocale($locale);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defined by Postman_Zend_Validate_Interface
|
||||
*
|
||||
* Returns true if and only if $value is a floating-point value
|
||||
*
|
||||
* @param string $value
|
||||
* @return boolean
|
||||
*/
|
||||
public function isValid($value)
|
||||
{
|
||||
if (!is_string($value) && !is_int($value) && !is_float($value)) {
|
||||
$this->_error(self::INVALID);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_float($value)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$this->_setValue($value);
|
||||
try {
|
||||
if (!Postman_Zend_Locale_Format::isFloat($value, array('locale' => $this->_locale))) {
|
||||
$this->_error(self::NOT_FLOAT);
|
||||
return false;
|
||||
}
|
||||
} catch (Postman_Zend_Locale_Exception $e) {
|
||||
$this->_error(self::NOT_FLOAT);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Validate_Abstract
|
||||
*/
|
||||
require_once 'Zend/Validate/Abstract.php';
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Validate_GreaterThan extends Postman_Zend_Validate_Abstract
|
||||
{
|
||||
|
||||
const NOT_GREATER = 'notGreaterThan';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $_messageTemplates = array(
|
||||
self::NOT_GREATER => "'%value%' is not greater than '%min%'",
|
||||
);
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $_messageVariables = array(
|
||||
'min' => '_min'
|
||||
);
|
||||
|
||||
/**
|
||||
* Minimum value
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
protected $_min;
|
||||
|
||||
/**
|
||||
* Sets validator options
|
||||
*
|
||||
* @param mixed|Postman_Zend_Config $min
|
||||
* @throws Postman_Zend_Validate_Exception
|
||||
*/
|
||||
public function __construct($min)
|
||||
{
|
||||
if ($min instanceof Postman_Zend_Config) {
|
||||
$min = $min->toArray();
|
||||
}
|
||||
|
||||
if (is_array($min)) {
|
||||
if (array_key_exists('min', $min)) {
|
||||
$min = $min['min'];
|
||||
} else {
|
||||
require_once 'Zend/Validate/Exception.php';
|
||||
throw new Postman_Zend_Validate_Exception("Missing option 'min'");
|
||||
}
|
||||
}
|
||||
|
||||
$this->setMin($min);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the min option
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getMin()
|
||||
{
|
||||
return $this->_min;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the min option
|
||||
*
|
||||
* @param mixed $min
|
||||
* @return Postman_Zend_Validate_GreaterThan Provides a fluent interface
|
||||
*/
|
||||
public function setMin($min)
|
||||
{
|
||||
$this->_min = $min;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defined by Postman_Zend_Validate_Interface
|
||||
*
|
||||
* Returns true if and only if $value is greater than min option
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return boolean
|
||||
*/
|
||||
public function isValid($value)
|
||||
{
|
||||
$this->_setValue($value);
|
||||
|
||||
if ($this->_min >= $value) {
|
||||
$this->_error(self::NOT_GREATER);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Validate_Abstract
|
||||
*/
|
||||
require_once 'Zend/Validate/Abstract.php';
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Validate_Hex extends Postman_Zend_Validate_Abstract
|
||||
{
|
||||
const INVALID = 'hexInvalid';
|
||||
const NOT_HEX = 'notHex';
|
||||
|
||||
/**
|
||||
* Validation failure message template definitions
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_messageTemplates = array(
|
||||
self::INVALID => "Invalid type given. String expected",
|
||||
self::NOT_HEX => "'%value%' has not only hexadecimal digit characters",
|
||||
);
|
||||
|
||||
/**
|
||||
* Defined by Postman_Zend_Validate_Interface
|
||||
*
|
||||
* Returns true if and only if $value contains only hexadecimal digit characters
|
||||
*
|
||||
* @param string $value
|
||||
* @return boolean
|
||||
*/
|
||||
public function isValid($value)
|
||||
{
|
||||
if (!is_string($value) && !is_int($value)) {
|
||||
$this->_error(self::INVALID);
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->_setValue($value);
|
||||
if (!ctype_xdigit((string) $value)) {
|
||||
$this->_error(self::NOT_HEX);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,196 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* Ressource file for com and net idn validation
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
return array(
|
||||
1 => '/^[\x{002d}0-9\x{0400}-\x{052f}]{1,63}$/iu',
|
||||
2 => '/^[\x{002d}0-9\x{0370}-\x{03ff}]{1,63}$/iu',
|
||||
3 => '/^[\x{002d}0-9a-z\x{ac00}-\x{d7a3}]{1,17}$/iu',
|
||||
4 => '/^[\x{002d}0-9a-z·à-öø-ÿāăąćĉċčďđēĕėęěĝğġģĥħĩīĭįıĵķĸĺļľłńņňŋōŏőœŕŗřśŝşšţťŧũūŭůűųŵŷźżž]{1,63}$/iu',
|
||||
5 => '/^[\x{002d}0-9A-Za-z\x{3400}-\x{3401}\x{3404}-\x{3406}\x{340C}\x{3416}\x{341C}' .
|
||||
'\x{3421}\x{3424}\x{3428}-\x{3429}\x{342B}-\x{342E}\x{3430}-\x{3434}\x{3436}' .
|
||||
'\x{3438}-\x{343C}\x{343E}\x{3441}-\x{3445}\x{3447}\x{3449}-\x{3451}\x{3453}' .
|
||||
'\x{3457}-\x{345F}\x{3463}-\x{3467}\x{346E}-\x{3471}\x{3473}-\x{3477}\x{3479}-\x{348E}\x{3491}-\x{3497}' .
|
||||
'\x{3499}-\x{34A1}\x{34A4}-\x{34AD}\x{34AF}-\x{34B0}\x{34B2}-\x{34BF}\x{34C2}-\x{34C5}\x{34C7}-\x{34CC}' .
|
||||
'\x{34CE}-\x{34D1}\x{34D3}-\x{34D8}\x{34DA}-\x{34E4}\x{34E7}-\x{34E9}\x{34EC}-\x{34EF}\x{34F1}-\x{34FE}' .
|
||||
'\x{3500}-\x{3507}\x{350A}-\x{3513}\x{3515}\x{3517}-\x{351A}\x{351C}-\x{351E}\x{3520}-\x{352A}' .
|
||||
'\x{352C}-\x{3552}\x{3554}-\x{355C}\x{355E}-\x{3567}\x{3569}-\x{3573}\x{3575}-\x{357C}\x{3580}-\x{3588}' .
|
||||
'\x{358F}-\x{3598}\x{359E}-\x{35AB}\x{35B4}-\x{35CD}\x{35D0}\x{35D3}-\x{35DC}\x{35E2}-\x{35ED}' .
|
||||
'\x{35F0}-\x{35F6}\x{35FB}-\x{3602}\x{3605}-\x{360E}\x{3610}-\x{3611}\x{3613}-\x{3616}\x{3619}-\x{362D}' .
|
||||
'\x{362F}-\x{3634}\x{3636}-\x{363B}\x{363F}-\x{3645}\x{3647}-\x{364B}\x{364D}-\x{3653}\x{3655}' .
|
||||
'\x{3659}-\x{365E}\x{3660}-\x{3665}\x{3667}-\x{367C}\x{367E}\x{3680}-\x{3685}\x{3687}' .
|
||||
'\x{3689}-\x{3690}\x{3692}-\x{3698}\x{369A}\x{369C}-\x{36AE}\x{36B0}-\x{36BF}\x{36C1}-\x{36C5}' .
|
||||
'\x{36C9}-\x{36CA}\x{36CD}-\x{36DE}\x{36E1}-\x{36E2}\x{36E5}-\x{36FE}\x{3701}-\x{3713}\x{3715}-\x{371E}' .
|
||||
'\x{3720}-\x{372C}\x{372E}-\x{3745}\x{3747}-\x{3748}\x{374A}\x{374C}-\x{3759}\x{375B}-\x{3760}' .
|
||||
'\x{3762}-\x{3767}\x{3769}-\x{3772}\x{3774}-\x{378C}\x{378F}-\x{379C}\x{379F}\x{37A1}-\x{37AD}' .
|
||||
'\x{37AF}-\x{37B7}\x{37B9}-\x{37C1}\x{37C3}-\x{37C5}\x{37C7}-\x{37D4}\x{37D6}-\x{37E0}\x{37E2}' .
|
||||
'\x{37E5}-\x{37ED}\x{37EF}-\x{37F6}\x{37F8}-\x{3802}\x{3804}-\x{381D}\x{3820}-\x{3822}\x{3825}-\x{382A}' .
|
||||
'\x{382D}-\x{382F}\x{3831}-\x{3832}\x{3834}-\x{384C}\x{384E}-\x{3860}\x{3862}-\x{3863}\x{3865}-\x{386B}' .
|
||||
'\x{386D}-\x{3886}\x{3888}-\x{38A1}\x{38A3}\x{38A5}-\x{38AA}\x{38AC}\x{38AE}-\x{38B0}' .
|
||||
'\x{38B2}-\x{38B6}\x{38B8}\x{38BA}-\x{38BE}\x{38C0}-\x{38C9}\x{38CB}-\x{38D4}\x{38D8}-\x{38E0}' .
|
||||
'\x{38E2}-\x{38E6}\x{38EB}-\x{38ED}\x{38EF}-\x{38F2}\x{38F5}-\x{38F7}\x{38FA}-\x{38FF}\x{3901}-\x{392A}' .
|
||||
'\x{392C}\x{392E}-\x{393B}\x{393E}-\x{3956}\x{395A}-\x{3969}\x{396B}-\x{397A}\x{397C}-\x{3987}' .
|
||||
'\x{3989}-\x{3998}\x{399A}-\x{39B0}\x{39B2}\x{39B4}-\x{39D0}\x{39D2}-\x{39DA}\x{39DE}-\x{39DF}' .
|
||||
'\x{39E1}-\x{39EF}\x{39F1}-\x{3A17}\x{3A19}-\x{3A2A}\x{3A2D}-\x{3A40}\x{3A43}-\x{3A4E}\x{3A50}' .
|
||||
'\x{3A52}-\x{3A5E}\x{3A60}-\x{3A6D}\x{3A6F}-\x{3A77}\x{3A79}-\x{3A82}\x{3A84}-\x{3A85}\x{3A87}-\x{3A89}' .
|
||||
'\x{3A8B}-\x{3A8F}\x{3A91}-\x{3A93}\x{3A95}-\x{3A96}\x{3A9A}\x{3A9C}-\x{3AA6}\x{3AA8}-\x{3AA9}' .
|
||||
'\x{3AAB}-\x{3AB1}\x{3AB4}-\x{3ABC}\x{3ABE}-\x{3AC5}\x{3ACA}-\x{3ACB}\x{3ACD}-\x{3AD5}\x{3AD7}-\x{3AE1}' .
|
||||
'\x{3AE4}-\x{3AE7}\x{3AE9}-\x{3AEC}\x{3AEE}-\x{3AFD}\x{3B01}-\x{3B10}\x{3B12}-\x{3B15}\x{3B17}-\x{3B1E}' .
|
||||
'\x{3B20}-\x{3B23}\x{3B25}-\x{3B27}\x{3B29}-\x{3B36}\x{3B38}-\x{3B39}\x{3B3B}-\x{3B3C}\x{3B3F}' .
|
||||
'\x{3B41}-\x{3B44}\x{3B47}-\x{3B4C}\x{3B4E}\x{3B51}-\x{3B55}\x{3B58}-\x{3B62}\x{3B68}-\x{3B72}' .
|
||||
'\x{3B78}-\x{3B88}\x{3B8B}-\x{3B9F}\x{3BA1}\x{3BA3}-\x{3BBA}\x{3BBC}\x{3BBF}-\x{3BD0}' .
|
||||
'\x{3BD3}-\x{3BE6}\x{3BEA}-\x{3BFB}\x{3BFE}-\x{3C12}\x{3C14}-\x{3C1B}\x{3C1D}-\x{3C37}\x{3C39}-\x{3C4F}' .
|
||||
'\x{3C52}\x{3C54}-\x{3C5C}\x{3C5E}-\x{3C68}\x{3C6A}-\x{3C76}\x{3C78}-\x{3C8F}\x{3C91}-\x{3CA8}' .
|
||||
'\x{3CAA}-\x{3CAD}\x{3CAF}-\x{3CBE}\x{3CC0}-\x{3CC8}\x{3CCA}-\x{3CD3}\x{3CD6}-\x{3CE0}\x{3CE4}-\x{3CEE}' .
|
||||
'\x{3CF3}-\x{3D0A}\x{3D0E}-\x{3D1E}\x{3D20}-\x{3D21}\x{3D25}-\x{3D38}\x{3D3B}-\x{3D46}\x{3D4A}-\x{3D59}' .
|
||||
'\x{3D5D}-\x{3D7B}\x{3D7D}-\x{3D81}\x{3D84}-\x{3D88}\x{3D8C}-\x{3D8F}\x{3D91}-\x{3D98}\x{3D9A}-\x{3D9C}' .
|
||||
'\x{3D9E}-\x{3DA1}\x{3DA3}-\x{3DB0}\x{3DB2}-\x{3DB5}\x{3DB9}-\x{3DBC}\x{3DBE}-\x{3DCB}\x{3DCD}-\x{3DDB}' .
|
||||
'\x{3DDF}-\x{3DE8}\x{3DEB}-\x{3DF0}\x{3DF3}-\x{3DF9}\x{3DFB}-\x{3DFC}\x{3DFE}-\x{3E05}\x{3E08}-\x{3E33}' .
|
||||
'\x{3E35}-\x{3E3E}\x{3E40}-\x{3E47}\x{3E49}-\x{3E67}\x{3E6B}-\x{3E6F}\x{3E71}-\x{3E85}\x{3E87}-\x{3E8C}' .
|
||||
'\x{3E8E}-\x{3E98}\x{3E9A}-\x{3EA1}\x{3EA3}-\x{3EAE}\x{3EB0}-\x{3EB5}\x{3EB7}-\x{3EBA}\x{3EBD}' .
|
||||
'\x{3EBF}-\x{3EC4}\x{3EC7}-\x{3ECE}\x{3ED1}-\x{3ED7}\x{3ED9}-\x{3EDA}\x{3EDD}-\x{3EE3}\x{3EE7}-\x{3EE8}' .
|
||||
'\x{3EEB}-\x{3EF2}\x{3EF5}-\x{3EFF}\x{3F01}-\x{3F02}\x{3F04}-\x{3F07}\x{3F09}-\x{3F44}\x{3F46}-\x{3F4E}' .
|
||||
'\x{3F50}-\x{3F53}\x{3F55}-\x{3F72}\x{3F74}-\x{3F75}\x{3F77}-\x{3F7B}\x{3F7D}-\x{3FB0}\x{3FB6}-\x{3FBF}' .
|
||||
'\x{3FC1}-\x{3FCF}\x{3FD1}-\x{3FD3}\x{3FD5}-\x{3FDF}\x{3FE1}-\x{400B}\x{400D}-\x{401C}\x{401E}-\x{4024}' .
|
||||
'\x{4027}-\x{403F}\x{4041}-\x{4060}\x{4062}-\x{4069}\x{406B}-\x{408A}\x{408C}-\x{40A7}\x{40A9}-\x{40B4}' .
|
||||
'\x{40B6}-\x{40C2}\x{40C7}-\x{40CF}\x{40D1}-\x{40DE}\x{40E0}-\x{40E7}\x{40E9}-\x{40EE}\x{40F0}-\x{40FB}' .
|
||||
'\x{40FD}-\x{4109}\x{410B}-\x{4115}\x{4118}-\x{411D}\x{411F}-\x{4122}\x{4124}-\x{4133}\x{4136}-\x{4138}' .
|
||||
'\x{413A}-\x{4148}\x{414A}-\x{4169}\x{416C}-\x{4185}\x{4188}-\x{418B}\x{418D}-\x{41AD}\x{41AF}-\x{41B3}' .
|
||||
'\x{41B5}-\x{41C3}\x{41C5}-\x{41C9}\x{41CB}-\x{41F2}\x{41F5}-\x{41FE}\x{4200}-\x{4227}\x{422A}-\x{4246}' .
|
||||
'\x{4248}-\x{4263}\x{4265}-\x{428B}\x{428D}-\x{42A1}\x{42A3}-\x{42C4}\x{42C8}-\x{42DC}\x{42DE}-\x{430A}' .
|
||||
'\x{430C}-\x{4335}\x{4337}\x{4342}-\x{435F}\x{4361}-\x{439A}\x{439C}-\x{439D}\x{439F}-\x{43A4}' .
|
||||
'\x{43A6}-\x{43EC}\x{43EF}-\x{4405}\x{4407}-\x{4429}\x{442B}-\x{4455}\x{4457}-\x{4468}\x{446A}-\x{446D}' .
|
||||
'\x{446F}-\x{4476}\x{4479}-\x{447D}\x{447F}-\x{4486}\x{4488}-\x{4490}\x{4492}-\x{4498}\x{449A}-\x{44AD}' .
|
||||
'\x{44B0}-\x{44BD}\x{44C1}-\x{44D3}\x{44D6}-\x{44E7}\x{44EA}\x{44EC}-\x{44FA}\x{44FC}-\x{4541}' .
|
||||
'\x{4543}-\x{454F}\x{4551}-\x{4562}\x{4564}-\x{4575}\x{4577}-\x{45AB}\x{45AD}-\x{45BD}\x{45BF}-\x{45D5}' .
|
||||
'\x{45D7}-\x{45EC}\x{45EE}-\x{45F2}\x{45F4}-\x{45FA}\x{45FC}-\x{461A}\x{461C}-\x{461D}\x{461F}-\x{4631}' .
|
||||
'\x{4633}-\x{4649}\x{464C}\x{464E}-\x{4652}\x{4654}-\x{466A}\x{466C}-\x{4675}\x{4677}-\x{467A}' .
|
||||
'\x{467C}-\x{4694}\x{4696}-\x{46A3}\x{46A5}-\x{46AB}\x{46AD}-\x{46D2}\x{46D4}-\x{4723}\x{4729}-\x{4732}' .
|
||||
'\x{4734}-\x{4758}\x{475A}\x{475C}-\x{478B}\x{478D}\x{4791}-\x{47B1}\x{47B3}-\x{47F1}' .
|
||||
'\x{47F3}-\x{480B}\x{480D}-\x{4815}\x{4817}-\x{4839}\x{483B}-\x{4870}\x{4872}-\x{487A}\x{487C}-\x{487F}' .
|
||||
'\x{4883}-\x{488E}\x{4890}-\x{4896}\x{4899}-\x{48A2}\x{48A4}-\x{48B9}\x{48BB}-\x{48C8}\x{48CA}-\x{48D1}' .
|
||||
'\x{48D3}-\x{48E5}\x{48E7}-\x{48F2}\x{48F4}-\x{48FF}\x{4901}-\x{4922}\x{4924}-\x{4928}\x{492A}-\x{4931}' .
|
||||
'\x{4933}-\x{495B}\x{495D}-\x{4978}\x{497A}\x{497D}\x{4982}-\x{4983}\x{4985}-\x{49A8}' .
|
||||
'\x{49AA}-\x{49AF}\x{49B1}-\x{49B7}\x{49B9}-\x{49BD}\x{49C1}-\x{49C7}\x{49C9}-\x{49CE}\x{49D0}-\x{49E8}' .
|
||||
'\x{49EA}\x{49EC}\x{49EE}-\x{4A19}\x{4A1B}-\x{4A43}\x{4A45}-\x{4A4D}\x{4A4F}-\x{4A9E}' .
|
||||
'\x{4AA0}-\x{4AA9}\x{4AAB}-\x{4B4E}\x{4B50}-\x{4B5B}\x{4B5D}-\x{4B69}\x{4B6B}-\x{4BC2}\x{4BC6}-\x{4BE8}' .
|
||||
'\x{4BEA}-\x{4BFA}\x{4BFC}-\x{4C06}\x{4C08}-\x{4C2D}\x{4C2F}-\x{4C32}\x{4C34}-\x{4C35}\x{4C37}-\x{4C69}' .
|
||||
'\x{4C6B}-\x{4C73}\x{4C75}-\x{4C86}\x{4C88}-\x{4C97}\x{4C99}-\x{4C9C}\x{4C9F}-\x{4CA3}\x{4CA5}-\x{4CB5}' .
|
||||
'\x{4CB7}-\x{4CF8}\x{4CFA}-\x{4D27}\x{4D29}-\x{4DAC}\x{4DAE}-\x{4DB1}\x{4DB3}-\x{4DB5}\x{4E00}-\x{4E54}' .
|
||||
'\x{4E56}-\x{4E89}\x{4E8B}-\x{4EEC}\x{4EEE}-\x{4FAC}\x{4FAE}-\x{503C}\x{503E}-\x{51E5}\x{51E7}-\x{5270}' .
|
||||
'\x{5272}-\x{56A1}\x{56A3}-\x{5840}\x{5842}-\x{58B5}\x{58B7}-\x{58CB}\x{58CD}-\x{5BC8}\x{5BCA}-\x{5C01}' .
|
||||
'\x{5C03}-\x{5C25}\x{5C27}-\x{5D5B}\x{5D5D}-\x{5F08}\x{5F0A}-\x{61F3}\x{61F5}-\x{63BA}\x{63BC}-\x{6441}' .
|
||||
'\x{6443}-\x{657C}\x{657E}-\x{663E}\x{6640}-\x{66FC}\x{66FE}-\x{6728}\x{672A}-\x{6766}\x{6768}-\x{67A8}' .
|
||||
'\x{67AA}-\x{685B}\x{685D}-\x{685E}\x{6860}-\x{68B9}\x{68BB}-\x{6AC8}\x{6ACA}-\x{6BB0}\x{6BB2}-\x{6C16}' .
|
||||
'\x{6C18}-\x{6D9B}\x{6D9D}-\x{6E12}\x{6E14}-\x{6E8B}\x{6E8D}-\x{704D}\x{704F}-\x{7113}\x{7115}-\x{713B}' .
|
||||
'\x{713D}-\x{7154}\x{7156}-\x{729F}\x{72A1}-\x{731E}\x{7320}-\x{7362}\x{7364}-\x{7533}\x{7535}-\x{7551}' .
|
||||
'\x{7553}-\x{7572}\x{7574}-\x{75E8}\x{75EA}-\x{7679}\x{767B}-\x{783E}\x{7840}-\x{7A62}\x{7A64}-\x{7AC2}' .
|
||||
'\x{7AC4}-\x{7B06}\x{7B08}-\x{7B79}\x{7B7B}-\x{7BCE}\x{7BD0}-\x{7D99}\x{7D9B}-\x{7E49}\x{7E4C}-\x{8132}' .
|
||||
'\x{8134}\x{8136}-\x{81D2}\x{81D4}-\x{8216}\x{8218}-\x{822D}\x{822F}-\x{83B4}\x{83B6}-\x{841F}' .
|
||||
'\x{8421}-\x{86CC}\x{86CE}-\x{874A}\x{874C}-\x{877E}\x{8780}-\x{8A32}\x{8A34}-\x{8B71}\x{8B73}-\x{8B8E}' .
|
||||
'\x{8B90}-\x{8DE4}\x{8DE6}-\x{8E9A}\x{8E9C}-\x{8EE1}\x{8EE4}-\x{8F0B}\x{8F0D}-\x{8FB9}\x{8FBB}-\x{9038}' .
|
||||
'\x{903A}-\x{9196}\x{9198}-\x{91A3}\x{91A5}-\x{91B7}\x{91B9}-\x{91C7}\x{91C9}-\x{91E0}\x{91E2}-\x{91FB}' .
|
||||
'\x{91FD}-\x{922B}\x{922D}-\x{9270}\x{9272}-\x{9420}\x{9422}-\x{9664}\x{9666}-\x{9679}\x{967B}-\x{9770}' .
|
||||
'\x{9772}-\x{982B}\x{982D}-\x{98ED}\x{98EF}-\x{99C4}\x{99C6}-\x{9A11}\x{9A14}-\x{9A27}\x{9A29}-\x{9D0D}' .
|
||||
'\x{9D0F}-\x{9D2B}\x{9D2D}-\x{9D8E}\x{9D90}-\x{9DC5}\x{9DC7}-\x{9E77}\x{9E79}-\x{9EB8}\x{9EBB}-\x{9F20}' .
|
||||
'\x{9F22}-\x{9F61}\x{9F63}-\x{9FA5}\x{FA28}]{1,20}$/iu',
|
||||
6 => '/^[\x{002d}0-9A-Za-z]{1,63}$/iu',
|
||||
7 => '/^[\x{00A1}-\x{00FF}]{1,63}$/iu',
|
||||
8 => '/^[\x{0100}-\x{017f}]{1,63}$/iu',
|
||||
9 => '/^[\x{0180}-\x{024f}]{1,63}$/iu',
|
||||
10 => '/^[\x{0250}-\x{02af}]{1,63}$/iu',
|
||||
11 => '/^[\x{02b0}-\x{02ff}]{1,63}$/iu',
|
||||
12 => '/^[\x{0300}-\x{036f}]{1,63}$/iu',
|
||||
13 => '/^[\x{0370}-\x{03ff}]{1,63}$/iu',
|
||||
14 => '/^[\x{0400}-\x{04ff}]{1,63}$/iu',
|
||||
15 => '/^[\x{0500}-\x{052f}]{1,63}$/iu',
|
||||
16 => '/^[\x{0530}-\x{058F}]{1,63}$/iu',
|
||||
17 => '/^[\x{0590}-\x{05FF}]{1,63}$/iu',
|
||||
18 => '/^[\x{0600}-\x{06FF}]{1,63}$/iu',
|
||||
19 => '/^[\x{0700}-\x{074F}]{1,63}$/iu',
|
||||
20 => '/^[\x{0780}-\x{07BF}]{1,63}$/iu',
|
||||
21 => '/^[\x{0900}-\x{097F}]{1,63}$/iu',
|
||||
22 => '/^[\x{0980}-\x{09FF}]{1,63}$/iu',
|
||||
23 => '/^[\x{0A00}-\x{0A7F}]{1,63}$/iu',
|
||||
24 => '/^[\x{0A80}-\x{0AFF}]{1,63}$/iu',
|
||||
25 => '/^[\x{0B00}-\x{0B7F}]{1,63}$/iu',
|
||||
26 => '/^[\x{0B80}-\x{0BFF}]{1,63}$/iu',
|
||||
27 => '/^[\x{0C00}-\x{0C7F}]{1,63}$/iu',
|
||||
28 => '/^[\x{0C80}-\x{0CFF}]{1,63}$/iu',
|
||||
29 => '/^[\x{0D00}-\x{0D7F}]{1,63}$/iu',
|
||||
30 => '/^[\x{0D80}-\x{0DFF}]{1,63}$/iu',
|
||||
31 => '/^[\x{0E00}-\x{0E7F}]{1,63}$/iu',
|
||||
32 => '/^[\x{0E80}-\x{0EFF}]{1,63}$/iu',
|
||||
33 => '/^[\x{0F00}-\x{0FFF}]{1,63}$/iu',
|
||||
34 => '/^[\x{1000}-\x{109F}]{1,63}$/iu',
|
||||
35 => '/^[\x{10A0}-\x{10FF}]{1,63}$/iu',
|
||||
36 => '/^[\x{1100}-\x{11FF}]{1,63}$/iu',
|
||||
37 => '/^[\x{1200}-\x{137F}]{1,63}$/iu',
|
||||
38 => '/^[\x{13A0}-\x{13FF}]{1,63}$/iu',
|
||||
39 => '/^[\x{1400}-\x{167F}]{1,63}$/iu',
|
||||
40 => '/^[\x{1680}-\x{169F}]{1,63}$/iu',
|
||||
41 => '/^[\x{16A0}-\x{16FF}]{1,63}$/iu',
|
||||
42 => '/^[\x{1700}-\x{171F}]{1,63}$/iu',
|
||||
43 => '/^[\x{1720}-\x{173F}]{1,63}$/iu',
|
||||
44 => '/^[\x{1740}-\x{175F}]{1,63}$/iu',
|
||||
45 => '/^[\x{1760}-\x{177F}]{1,63}$/iu',
|
||||
46 => '/^[\x{1780}-\x{17FF}]{1,63}$/iu',
|
||||
47 => '/^[\x{1800}-\x{18AF}]{1,63}$/iu',
|
||||
48 => '/^[\x{1E00}-\x{1EFF}]{1,63}$/iu',
|
||||
49 => '/^[\x{1F00}-\x{1FFF}]{1,63}$/iu',
|
||||
50 => '/^[\x{2070}-\x{209F}]{1,63}$/iu',
|
||||
51 => '/^[\x{2100}-\x{214F}]{1,63}$/iu',
|
||||
52 => '/^[\x{2150}-\x{218F}]{1,63}$/iu',
|
||||
53 => '/^[\x{2460}-\x{24FF}]{1,63}$/iu',
|
||||
54 => '/^[\x{2E80}-\x{2EFF}]{1,63}$/iu',
|
||||
55 => '/^[\x{2F00}-\x{2FDF}]{1,63}$/iu',
|
||||
56 => '/^[\x{2FF0}-\x{2FFF}]{1,63}$/iu',
|
||||
57 => '/^[\x{3040}-\x{309F}]{1,63}$/iu',
|
||||
58 => '/^[\x{30A0}-\x{30FF}]{1,63}$/iu',
|
||||
59 => '/^[\x{3100}-\x{312F}]{1,63}$/iu',
|
||||
60 => '/^[\x{3130}-\x{318F}]{1,63}$/iu',
|
||||
61 => '/^[\x{3190}-\x{319F}]{1,63}$/iu',
|
||||
62 => '/^[\x{31A0}-\x{31BF}]{1,63}$/iu',
|
||||
63 => '/^[\x{31F0}-\x{31FF}]{1,63}$/iu',
|
||||
64 => '/^[\x{3200}-\x{32FF}]{1,63}$/iu',
|
||||
65 => '/^[\x{3300}-\x{33FF}]{1,63}$/iu',
|
||||
66 => '/^[\x{3400}-\x{4DBF}]{1,63}$/iu',
|
||||
67 => '/^[\x{4E00}-\x{9FFF}]{1,63}$/iu',
|
||||
68 => '/^[\x{A000}-\x{A48F}]{1,63}$/iu',
|
||||
69 => '/^[\x{A490}-\x{A4CF}]{1,63}$/iu',
|
||||
70 => '/^[\x{AC00}-\x{D7AF}]{1,63}$/iu',
|
||||
73 => '/^[\x{F900}-\x{FAFF}]{1,63}$/iu',
|
||||
74 => '/^[\x{FB00}-\x{FB4F}]{1,63}$/iu',
|
||||
75 => '/^[\x{FB50}-\x{FDFF}]{1,63}$/iu',
|
||||
76 => '/^[\x{FE20}-\x{FE2F}]{1,63}$/iu',
|
||||
77 => '/^[\x{FE70}-\x{FEFF}]{1,63}$/iu',
|
||||
78 => '/^[\x{FF00}-\x{FFEF}]{1,63}$/iu',
|
||||
79 => '/^[\x{20000}-\x{2A6DF}]{1,63}$/iu',
|
||||
80 => '/^[\x{2F800}-\x{2FA1F}]{1,63}$/iu'
|
||||
|
||||
);
|
||||
@@ -0,0 +1,739 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* Ressource file for japanese idn validation
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
return array(
|
||||
1 => '/^[\x{002d}0-9a-z\x{3005}-\x{3007}\x{3041}-\x{3093}\x{309D}\x{309E}' .
|
||||
'\x{30A1}-\x{30F6}\x{30FC}' .
|
||||
'\x{30FD}\x{30FE}\x{4E00}\x{4E01}\x{4E03}\x{4E07}\x{4E08}\x{4E09}\x{4E0A}' .
|
||||
'\x{4E0B}\x{4E0D}\x{4E0E}\x{4E10}\x{4E11}\x{4E14}\x{4E15}\x{4E16}\x{4E17}' .
|
||||
'\x{4E18}\x{4E19}\x{4E1E}\x{4E21}\x{4E26}\x{4E2A}\x{4E2D}\x{4E31}\x{4E32}' .
|
||||
'\x{4E36}\x{4E38}\x{4E39}\x{4E3B}\x{4E3C}\x{4E3F}\x{4E42}\x{4E43}\x{4E45}' .
|
||||
'\x{4E4B}\x{4E4D}\x{4E4E}\x{4E4F}\x{4E55}\x{4E56}\x{4E57}\x{4E58}\x{4E59}' .
|
||||
'\x{4E5D}\x{4E5E}\x{4E5F}\x{4E62}\x{4E71}\x{4E73}\x{4E7E}\x{4E80}\x{4E82}' .
|
||||
'\x{4E85}\x{4E86}\x{4E88}\x{4E89}\x{4E8A}\x{4E8B}\x{4E8C}\x{4E8E}\x{4E91}' .
|
||||
'\x{4E92}\x{4E94}\x{4E95}\x{4E98}\x{4E99}\x{4E9B}\x{4E9C}\x{4E9E}\x{4E9F}' .
|
||||
'\x{4EA0}\x{4EA1}\x{4EA2}\x{4EA4}\x{4EA5}\x{4EA6}\x{4EA8}\x{4EAB}\x{4EAC}' .
|
||||
'\x{4EAD}\x{4EAE}\x{4EB0}\x{4EB3}\x{4EB6}\x{4EBA}\x{4EC0}\x{4EC1}\x{4EC2}' .
|
||||
'\x{4EC4}\x{4EC6}\x{4EC7}\x{4ECA}\x{4ECB}\x{4ECD}\x{4ECE}\x{4ECF}\x{4ED4}' .
|
||||
'\x{4ED5}\x{4ED6}\x{4ED7}\x{4ED8}\x{4ED9}\x{4EDD}\x{4EDE}\x{4EDF}\x{4EE3}' .
|
||||
'\x{4EE4}\x{4EE5}\x{4EED}\x{4EEE}\x{4EF0}\x{4EF2}\x{4EF6}\x{4EF7}\x{4EFB}' .
|
||||
'\x{4F01}\x{4F09}\x{4F0A}\x{4F0D}\x{4F0E}\x{4F0F}\x{4F10}\x{4F11}\x{4F1A}' .
|
||||
'\x{4F1C}\x{4F1D}\x{4F2F}\x{4F30}\x{4F34}\x{4F36}\x{4F38}\x{4F3A}\x{4F3C}' .
|
||||
'\x{4F3D}\x{4F43}\x{4F46}\x{4F47}\x{4F4D}\x{4F4E}\x{4F4F}\x{4F50}\x{4F51}' .
|
||||
'\x{4F53}\x{4F55}\x{4F57}\x{4F59}\x{4F5A}\x{4F5B}\x{4F5C}\x{4F5D}\x{4F5E}' .
|
||||
'\x{4F69}\x{4F6F}\x{4F70}\x{4F73}\x{4F75}\x{4F76}\x{4F7B}\x{4F7C}\x{4F7F}' .
|
||||
'\x{4F83}\x{4F86}\x{4F88}\x{4F8B}\x{4F8D}\x{4F8F}\x{4F91}\x{4F96}\x{4F98}' .
|
||||
'\x{4F9B}\x{4F9D}\x{4FA0}\x{4FA1}\x{4FAB}\x{4FAD}\x{4FAE}\x{4FAF}\x{4FB5}' .
|
||||
'\x{4FB6}\x{4FBF}\x{4FC2}\x{4FC3}\x{4FC4}\x{4FCA}\x{4FCE}\x{4FD0}\x{4FD1}' .
|
||||
'\x{4FD4}\x{4FD7}\x{4FD8}\x{4FDA}\x{4FDB}\x{4FDD}\x{4FDF}\x{4FE1}\x{4FE3}' .
|
||||
'\x{4FE4}\x{4FE5}\x{4FEE}\x{4FEF}\x{4FF3}\x{4FF5}\x{4FF6}\x{4FF8}\x{4FFA}' .
|
||||
'\x{4FFE}\x{5005}\x{5006}\x{5009}\x{500B}\x{500D}\x{500F}\x{5011}\x{5012}' .
|
||||
'\x{5014}\x{5016}\x{5019}\x{501A}\x{501F}\x{5021}\x{5023}\x{5024}\x{5025}' .
|
||||
'\x{5026}\x{5028}\x{5029}\x{502A}\x{502B}\x{502C}\x{502D}\x{5036}\x{5039}' .
|
||||
'\x{5043}\x{5047}\x{5048}\x{5049}\x{504F}\x{5050}\x{5055}\x{5056}\x{505A}' .
|
||||
'\x{505C}\x{5065}\x{506C}\x{5072}\x{5074}\x{5075}\x{5076}\x{5078}\x{507D}' .
|
||||
'\x{5080}\x{5085}\x{508D}\x{5091}\x{5098}\x{5099}\x{509A}\x{50AC}\x{50AD}' .
|
||||
'\x{50B2}\x{50B3}\x{50B4}\x{50B5}\x{50B7}\x{50BE}\x{50C2}\x{50C5}\x{50C9}' .
|
||||
'\x{50CA}\x{50CD}\x{50CF}\x{50D1}\x{50D5}\x{50D6}\x{50DA}\x{50DE}\x{50E3}' .
|
||||
'\x{50E5}\x{50E7}\x{50ED}\x{50EE}\x{50F5}\x{50F9}\x{50FB}\x{5100}\x{5101}' .
|
||||
'\x{5102}\x{5104}\x{5109}\x{5112}\x{5114}\x{5115}\x{5116}\x{5118}\x{511A}' .
|
||||
'\x{511F}\x{5121}\x{512A}\x{5132}\x{5137}\x{513A}\x{513B}\x{513C}\x{513F}' .
|
||||
'\x{5140}\x{5141}\x{5143}\x{5144}\x{5145}\x{5146}\x{5147}\x{5148}\x{5149}' .
|
||||
'\x{514B}\x{514C}\x{514D}\x{514E}\x{5150}\x{5152}\x{5154}\x{515A}\x{515C}' .
|
||||
'\x{5162}\x{5165}\x{5168}\x{5169}\x{516A}\x{516B}\x{516C}\x{516D}\x{516E}' .
|
||||
'\x{5171}\x{5175}\x{5176}\x{5177}\x{5178}\x{517C}\x{5180}\x{5182}\x{5185}' .
|
||||
'\x{5186}\x{5189}\x{518A}\x{518C}\x{518D}\x{518F}\x{5190}\x{5191}\x{5192}' .
|
||||
'\x{5193}\x{5195}\x{5196}\x{5197}\x{5199}\x{51A0}\x{51A2}\x{51A4}\x{51A5}' .
|
||||
'\x{51A6}\x{51A8}\x{51A9}\x{51AA}\x{51AB}\x{51AC}\x{51B0}\x{51B1}\x{51B2}' .
|
||||
'\x{51B3}\x{51B4}\x{51B5}\x{51B6}\x{51B7}\x{51BD}\x{51C4}\x{51C5}\x{51C6}' .
|
||||
'\x{51C9}\x{51CB}\x{51CC}\x{51CD}\x{51D6}\x{51DB}\x{51DC}\x{51DD}\x{51E0}' .
|
||||
'\x{51E1}\x{51E6}\x{51E7}\x{51E9}\x{51EA}\x{51ED}\x{51F0}\x{51F1}\x{51F5}' .
|
||||
'\x{51F6}\x{51F8}\x{51F9}\x{51FA}\x{51FD}\x{51FE}\x{5200}\x{5203}\x{5204}' .
|
||||
'\x{5206}\x{5207}\x{5208}\x{520A}\x{520B}\x{520E}\x{5211}\x{5214}\x{5217}' .
|
||||
'\x{521D}\x{5224}\x{5225}\x{5227}\x{5229}\x{522A}\x{522E}\x{5230}\x{5233}' .
|
||||
'\x{5236}\x{5237}\x{5238}\x{5239}\x{523A}\x{523B}\x{5243}\x{5244}\x{5247}' .
|
||||
'\x{524A}\x{524B}\x{524C}\x{524D}\x{524F}\x{5254}\x{5256}\x{525B}\x{525E}' .
|
||||
'\x{5263}\x{5264}\x{5265}\x{5269}\x{526A}\x{526F}\x{5270}\x{5271}\x{5272}' .
|
||||
'\x{5273}\x{5274}\x{5275}\x{527D}\x{527F}\x{5283}\x{5287}\x{5288}\x{5289}' .
|
||||
'\x{528D}\x{5291}\x{5292}\x{5294}\x{529B}\x{529F}\x{52A0}\x{52A3}\x{52A9}' .
|
||||
'\x{52AA}\x{52AB}\x{52AC}\x{52AD}\x{52B1}\x{52B4}\x{52B5}\x{52B9}\x{52BC}' .
|
||||
'\x{52BE}\x{52C1}\x{52C3}\x{52C5}\x{52C7}\x{52C9}\x{52CD}\x{52D2}\x{52D5}' .
|
||||
'\x{52D7}\x{52D8}\x{52D9}\x{52DD}\x{52DE}\x{52DF}\x{52E0}\x{52E2}\x{52E3}' .
|
||||
'\x{52E4}\x{52E6}\x{52E7}\x{52F2}\x{52F3}\x{52F5}\x{52F8}\x{52F9}\x{52FA}' .
|
||||
'\x{52FE}\x{52FF}\x{5301}\x{5302}\x{5305}\x{5306}\x{5308}\x{530D}\x{530F}' .
|
||||
'\x{5310}\x{5315}\x{5316}\x{5317}\x{5319}\x{531A}\x{531D}\x{5320}\x{5321}' .
|
||||
'\x{5323}\x{532A}\x{532F}\x{5331}\x{5333}\x{5338}\x{5339}\x{533A}\x{533B}' .
|
||||
'\x{533F}\x{5340}\x{5341}\x{5343}\x{5345}\x{5346}\x{5347}\x{5348}\x{5349}' .
|
||||
'\x{534A}\x{534D}\x{5351}\x{5352}\x{5353}\x{5354}\x{5357}\x{5358}\x{535A}' .
|
||||
'\x{535C}\x{535E}\x{5360}\x{5366}\x{5369}\x{536E}\x{536F}\x{5370}\x{5371}' .
|
||||
'\x{5373}\x{5374}\x{5375}\x{5377}\x{5378}\x{537B}\x{537F}\x{5382}\x{5384}' .
|
||||
'\x{5396}\x{5398}\x{539A}\x{539F}\x{53A0}\x{53A5}\x{53A6}\x{53A8}\x{53A9}' .
|
||||
'\x{53AD}\x{53AE}\x{53B0}\x{53B3}\x{53B6}\x{53BB}\x{53C2}\x{53C3}\x{53C8}' .
|
||||
'\x{53C9}\x{53CA}\x{53CB}\x{53CC}\x{53CD}\x{53CE}\x{53D4}\x{53D6}\x{53D7}' .
|
||||
'\x{53D9}\x{53DB}\x{53DF}\x{53E1}\x{53E2}\x{53E3}\x{53E4}\x{53E5}\x{53E8}' .
|
||||
'\x{53E9}\x{53EA}\x{53EB}\x{53EC}\x{53ED}\x{53EE}\x{53EF}\x{53F0}\x{53F1}' .
|
||||
'\x{53F2}\x{53F3}\x{53F6}\x{53F7}\x{53F8}\x{53FA}\x{5401}\x{5403}\x{5404}' .
|
||||
'\x{5408}\x{5409}\x{540A}\x{540B}\x{540C}\x{540D}\x{540E}\x{540F}\x{5410}' .
|
||||
'\x{5411}\x{541B}\x{541D}\x{541F}\x{5420}\x{5426}\x{5429}\x{542B}\x{542C}' .
|
||||
'\x{542D}\x{542E}\x{5436}\x{5438}\x{5439}\x{543B}\x{543C}\x{543D}\x{543E}' .
|
||||
'\x{5440}\x{5442}\x{5446}\x{5448}\x{5449}\x{544A}\x{544E}\x{5451}\x{545F}' .
|
||||
'\x{5468}\x{546A}\x{5470}\x{5471}\x{5473}\x{5475}\x{5476}\x{5477}\x{547B}' .
|
||||
'\x{547C}\x{547D}\x{5480}\x{5484}\x{5486}\x{548B}\x{548C}\x{548E}\x{548F}' .
|
||||
'\x{5490}\x{5492}\x{54A2}\x{54A4}\x{54A5}\x{54A8}\x{54AB}\x{54AC}\x{54AF}' .
|
||||
'\x{54B2}\x{54B3}\x{54B8}\x{54BC}\x{54BD}\x{54BE}\x{54C0}\x{54C1}\x{54C2}' .
|
||||
'\x{54C4}\x{54C7}\x{54C8}\x{54C9}\x{54D8}\x{54E1}\x{54E2}\x{54E5}\x{54E6}' .
|
||||
'\x{54E8}\x{54E9}\x{54ED}\x{54EE}\x{54F2}\x{54FA}\x{54FD}\x{5504}\x{5506}' .
|
||||
'\x{5507}\x{550F}\x{5510}\x{5514}\x{5516}\x{552E}\x{552F}\x{5531}\x{5533}' .
|
||||
'\x{5538}\x{5539}\x{553E}\x{5540}\x{5544}\x{5545}\x{5546}\x{554C}\x{554F}' .
|
||||
'\x{5553}\x{5556}\x{5557}\x{555C}\x{555D}\x{5563}\x{557B}\x{557C}\x{557E}' .
|
||||
'\x{5580}\x{5583}\x{5584}\x{5587}\x{5589}\x{558A}\x{558B}\x{5598}\x{5599}' .
|
||||
'\x{559A}\x{559C}\x{559D}\x{559E}\x{559F}\x{55A7}\x{55A8}\x{55A9}\x{55AA}' .
|
||||
'\x{55AB}\x{55AC}\x{55AE}\x{55B0}\x{55B6}\x{55C4}\x{55C5}\x{55C7}\x{55D4}' .
|
||||
'\x{55DA}\x{55DC}\x{55DF}\x{55E3}\x{55E4}\x{55F7}\x{55F9}\x{55FD}\x{55FE}' .
|
||||
'\x{5606}\x{5609}\x{5614}\x{5616}\x{5617}\x{5618}\x{561B}\x{5629}\x{562F}' .
|
||||
'\x{5631}\x{5632}\x{5634}\x{5636}\x{5638}\x{5642}\x{564C}\x{564E}\x{5650}' .
|
||||
'\x{565B}\x{5664}\x{5668}\x{566A}\x{566B}\x{566C}\x{5674}\x{5678}\x{567A}' .
|
||||
'\x{5680}\x{5686}\x{5687}\x{568A}\x{568F}\x{5694}\x{56A0}\x{56A2}\x{56A5}' .
|
||||
'\x{56AE}\x{56B4}\x{56B6}\x{56BC}\x{56C0}\x{56C1}\x{56C2}\x{56C3}\x{56C8}' .
|
||||
'\x{56CE}\x{56D1}\x{56D3}\x{56D7}\x{56D8}\x{56DA}\x{56DB}\x{56DE}\x{56E0}' .
|
||||
'\x{56E3}\x{56EE}\x{56F0}\x{56F2}\x{56F3}\x{56F9}\x{56FA}\x{56FD}\x{56FF}' .
|
||||
'\x{5700}\x{5703}\x{5704}\x{5708}\x{5709}\x{570B}\x{570D}\x{570F}\x{5712}' .
|
||||
'\x{5713}\x{5716}\x{5718}\x{571C}\x{571F}\x{5726}\x{5727}\x{5728}\x{572D}' .
|
||||
'\x{5730}\x{5737}\x{5738}\x{573B}\x{5740}\x{5742}\x{5747}\x{574A}\x{574E}' .
|
||||
'\x{574F}\x{5750}\x{5751}\x{5761}\x{5764}\x{5766}\x{5769}\x{576A}\x{577F}' .
|
||||
'\x{5782}\x{5788}\x{5789}\x{578B}\x{5793}\x{57A0}\x{57A2}\x{57A3}\x{57A4}' .
|
||||
'\x{57AA}\x{57B0}\x{57B3}\x{57C0}\x{57C3}\x{57C6}\x{57CB}\x{57CE}\x{57D2}' .
|
||||
'\x{57D3}\x{57D4}\x{57D6}\x{57DC}\x{57DF}\x{57E0}\x{57E3}\x{57F4}\x{57F7}' .
|
||||
'\x{57F9}\x{57FA}\x{57FC}\x{5800}\x{5802}\x{5805}\x{5806}\x{580A}\x{580B}' .
|
||||
'\x{5815}\x{5819}\x{581D}\x{5821}\x{5824}\x{582A}\x{582F}\x{5830}\x{5831}' .
|
||||
'\x{5834}\x{5835}\x{583A}\x{583D}\x{5840}\x{5841}\x{584A}\x{584B}\x{5851}' .
|
||||
'\x{5852}\x{5854}\x{5857}\x{5858}\x{5859}\x{585A}\x{585E}\x{5862}\x{5869}' .
|
||||
'\x{586B}\x{5870}\x{5872}\x{5875}\x{5879}\x{587E}\x{5883}\x{5885}\x{5893}' .
|
||||
'\x{5897}\x{589C}\x{589F}\x{58A8}\x{58AB}\x{58AE}\x{58B3}\x{58B8}\x{58B9}' .
|
||||
'\x{58BA}\x{58BB}\x{58BE}\x{58C1}\x{58C5}\x{58C7}\x{58CA}\x{58CC}\x{58D1}' .
|
||||
'\x{58D3}\x{58D5}\x{58D7}\x{58D8}\x{58D9}\x{58DC}\x{58DE}\x{58DF}\x{58E4}' .
|
||||
'\x{58E5}\x{58EB}\x{58EC}\x{58EE}\x{58EF}\x{58F0}\x{58F1}\x{58F2}\x{58F7}' .
|
||||
'\x{58F9}\x{58FA}\x{58FB}\x{58FC}\x{58FD}\x{5902}\x{5909}\x{590A}\x{590F}' .
|
||||
'\x{5910}\x{5915}\x{5916}\x{5918}\x{5919}\x{591A}\x{591B}\x{591C}\x{5922}' .
|
||||
'\x{5925}\x{5927}\x{5929}\x{592A}\x{592B}\x{592C}\x{592D}\x{592E}\x{5931}' .
|
||||
'\x{5932}\x{5937}\x{5938}\x{593E}\x{5944}\x{5947}\x{5948}\x{5949}\x{594E}' .
|
||||
'\x{594F}\x{5950}\x{5951}\x{5954}\x{5955}\x{5957}\x{5958}\x{595A}\x{5960}' .
|
||||
'\x{5962}\x{5965}\x{5967}\x{5968}\x{5969}\x{596A}\x{596C}\x{596E}\x{5973}' .
|
||||
'\x{5974}\x{5978}\x{597D}\x{5981}\x{5982}\x{5983}\x{5984}\x{598A}\x{598D}' .
|
||||
'\x{5993}\x{5996}\x{5999}\x{599B}\x{599D}\x{59A3}\x{59A5}\x{59A8}\x{59AC}' .
|
||||
'\x{59B2}\x{59B9}\x{59BB}\x{59BE}\x{59C6}\x{59C9}\x{59CB}\x{59D0}\x{59D1}' .
|
||||
'\x{59D3}\x{59D4}\x{59D9}\x{59DA}\x{59DC}\x{59E5}\x{59E6}\x{59E8}\x{59EA}' .
|
||||
'\x{59EB}\x{59F6}\x{59FB}\x{59FF}\x{5A01}\x{5A03}\x{5A09}\x{5A11}\x{5A18}' .
|
||||
'\x{5A1A}\x{5A1C}\x{5A1F}\x{5A20}\x{5A25}\x{5A29}\x{5A2F}\x{5A35}\x{5A36}' .
|
||||
'\x{5A3C}\x{5A40}\x{5A41}\x{5A46}\x{5A49}\x{5A5A}\x{5A62}\x{5A66}\x{5A6A}' .
|
||||
'\x{5A6C}\x{5A7F}\x{5A92}\x{5A9A}\x{5A9B}\x{5ABC}\x{5ABD}\x{5ABE}\x{5AC1}' .
|
||||
'\x{5AC2}\x{5AC9}\x{5ACB}\x{5ACC}\x{5AD0}\x{5AD6}\x{5AD7}\x{5AE1}\x{5AE3}' .
|
||||
'\x{5AE6}\x{5AE9}\x{5AFA}\x{5AFB}\x{5B09}\x{5B0B}\x{5B0C}\x{5B16}\x{5B22}' .
|
||||
'\x{5B2A}\x{5B2C}\x{5B30}\x{5B32}\x{5B36}\x{5B3E}\x{5B40}\x{5B43}\x{5B45}' .
|
||||
'\x{5B50}\x{5B51}\x{5B54}\x{5B55}\x{5B57}\x{5B58}\x{5B5A}\x{5B5B}\x{5B5C}' .
|
||||
'\x{5B5D}\x{5B5F}\x{5B63}\x{5B64}\x{5B65}\x{5B66}\x{5B69}\x{5B6B}\x{5B70}' .
|
||||
'\x{5B71}\x{5B73}\x{5B75}\x{5B78}\x{5B7A}\x{5B80}\x{5B83}\x{5B85}\x{5B87}' .
|
||||
'\x{5B88}\x{5B89}\x{5B8B}\x{5B8C}\x{5B8D}\x{5B8F}\x{5B95}\x{5B97}\x{5B98}' .
|
||||
'\x{5B99}\x{5B9A}\x{5B9B}\x{5B9C}\x{5B9D}\x{5B9F}\x{5BA2}\x{5BA3}\x{5BA4}' .
|
||||
'\x{5BA5}\x{5BA6}\x{5BAE}\x{5BB0}\x{5BB3}\x{5BB4}\x{5BB5}\x{5BB6}\x{5BB8}' .
|
||||
'\x{5BB9}\x{5BBF}\x{5BC2}\x{5BC3}\x{5BC4}\x{5BC5}\x{5BC6}\x{5BC7}\x{5BC9}' .
|
||||
'\x{5BCC}\x{5BD0}\x{5BD2}\x{5BD3}\x{5BD4}\x{5BDB}\x{5BDD}\x{5BDE}\x{5BDF}' .
|
||||
'\x{5BE1}\x{5BE2}\x{5BE4}\x{5BE5}\x{5BE6}\x{5BE7}\x{5BE8}\x{5BE9}\x{5BEB}' .
|
||||
'\x{5BEE}\x{5BF0}\x{5BF3}\x{5BF5}\x{5BF6}\x{5BF8}\x{5BFA}\x{5BFE}\x{5BFF}' .
|
||||
'\x{5C01}\x{5C02}\x{5C04}\x{5C05}\x{5C06}\x{5C07}\x{5C08}\x{5C09}\x{5C0A}' .
|
||||
'\x{5C0B}\x{5C0D}\x{5C0E}\x{5C0F}\x{5C11}\x{5C13}\x{5C16}\x{5C1A}\x{5C20}' .
|
||||
'\x{5C22}\x{5C24}\x{5C28}\x{5C2D}\x{5C31}\x{5C38}\x{5C39}\x{5C3A}\x{5C3B}' .
|
||||
'\x{5C3C}\x{5C3D}\x{5C3E}\x{5C3F}\x{5C40}\x{5C41}\x{5C45}\x{5C46}\x{5C48}' .
|
||||
'\x{5C4A}\x{5C4B}\x{5C4D}\x{5C4E}\x{5C4F}\x{5C50}\x{5C51}\x{5C53}\x{5C55}' .
|
||||
'\x{5C5E}\x{5C60}\x{5C61}\x{5C64}\x{5C65}\x{5C6C}\x{5C6E}\x{5C6F}\x{5C71}' .
|
||||
'\x{5C76}\x{5C79}\x{5C8C}\x{5C90}\x{5C91}\x{5C94}\x{5CA1}\x{5CA8}\x{5CA9}' .
|
||||
'\x{5CAB}\x{5CAC}\x{5CB1}\x{5CB3}\x{5CB6}\x{5CB7}\x{5CB8}\x{5CBB}\x{5CBC}' .
|
||||
'\x{5CBE}\x{5CC5}\x{5CC7}\x{5CD9}\x{5CE0}\x{5CE1}\x{5CE8}\x{5CE9}\x{5CEA}' .
|
||||
'\x{5CED}\x{5CEF}\x{5CF0}\x{5CF6}\x{5CFA}\x{5CFB}\x{5CFD}\x{5D07}\x{5D0B}' .
|
||||
'\x{5D0E}\x{5D11}\x{5D14}\x{5D15}\x{5D16}\x{5D17}\x{5D18}\x{5D19}\x{5D1A}' .
|
||||
'\x{5D1B}\x{5D1F}\x{5D22}\x{5D29}\x{5D4B}\x{5D4C}\x{5D4E}\x{5D50}\x{5D52}' .
|
||||
'\x{5D5C}\x{5D69}\x{5D6C}\x{5D6F}\x{5D73}\x{5D76}\x{5D82}\x{5D84}\x{5D87}' .
|
||||
'\x{5D8B}\x{5D8C}\x{5D90}\x{5D9D}\x{5DA2}\x{5DAC}\x{5DAE}\x{5DB7}\x{5DBA}' .
|
||||
'\x{5DBC}\x{5DBD}\x{5DC9}\x{5DCC}\x{5DCD}\x{5DD2}\x{5DD3}\x{5DD6}\x{5DDB}' .
|
||||
'\x{5DDD}\x{5DDE}\x{5DE1}\x{5DE3}\x{5DE5}\x{5DE6}\x{5DE7}\x{5DE8}\x{5DEB}' .
|
||||
'\x{5DEE}\x{5DF1}\x{5DF2}\x{5DF3}\x{5DF4}\x{5DF5}\x{5DF7}\x{5DFB}\x{5DFD}' .
|
||||
'\x{5DFE}\x{5E02}\x{5E03}\x{5E06}\x{5E0B}\x{5E0C}\x{5E11}\x{5E16}\x{5E19}' .
|
||||
'\x{5E1A}\x{5E1B}\x{5E1D}\x{5E25}\x{5E2B}\x{5E2D}\x{5E2F}\x{5E30}\x{5E33}' .
|
||||
'\x{5E36}\x{5E37}\x{5E38}\x{5E3D}\x{5E40}\x{5E43}\x{5E44}\x{5E45}\x{5E47}' .
|
||||
'\x{5E4C}\x{5E4E}\x{5E54}\x{5E55}\x{5E57}\x{5E5F}\x{5E61}\x{5E62}\x{5E63}' .
|
||||
'\x{5E64}\x{5E72}\x{5E73}\x{5E74}\x{5E75}\x{5E76}\x{5E78}\x{5E79}\x{5E7A}' .
|
||||
'\x{5E7B}\x{5E7C}\x{5E7D}\x{5E7E}\x{5E7F}\x{5E81}\x{5E83}\x{5E84}\x{5E87}' .
|
||||
'\x{5E8A}\x{5E8F}\x{5E95}\x{5E96}\x{5E97}\x{5E9A}\x{5E9C}\x{5EA0}\x{5EA6}' .
|
||||
'\x{5EA7}\x{5EAB}\x{5EAD}\x{5EB5}\x{5EB6}\x{5EB7}\x{5EB8}\x{5EC1}\x{5EC2}' .
|
||||
'\x{5EC3}\x{5EC8}\x{5EC9}\x{5ECA}\x{5ECF}\x{5ED0}\x{5ED3}\x{5ED6}\x{5EDA}' .
|
||||
'\x{5EDB}\x{5EDD}\x{5EDF}\x{5EE0}\x{5EE1}\x{5EE2}\x{5EE3}\x{5EE8}\x{5EE9}' .
|
||||
'\x{5EEC}\x{5EF0}\x{5EF1}\x{5EF3}\x{5EF4}\x{5EF6}\x{5EF7}\x{5EF8}\x{5EFA}' .
|
||||
'\x{5EFB}\x{5EFC}\x{5EFE}\x{5EFF}\x{5F01}\x{5F03}\x{5F04}\x{5F09}\x{5F0A}' .
|
||||
'\x{5F0B}\x{5F0C}\x{5F0D}\x{5F0F}\x{5F10}\x{5F11}\x{5F13}\x{5F14}\x{5F15}' .
|
||||
'\x{5F16}\x{5F17}\x{5F18}\x{5F1B}\x{5F1F}\x{5F25}\x{5F26}\x{5F27}\x{5F29}' .
|
||||
'\x{5F2D}\x{5F2F}\x{5F31}\x{5F35}\x{5F37}\x{5F38}\x{5F3C}\x{5F3E}\x{5F41}' .
|
||||
'\x{5F48}\x{5F4A}\x{5F4C}\x{5F4E}\x{5F51}\x{5F53}\x{5F56}\x{5F57}\x{5F59}' .
|
||||
'\x{5F5C}\x{5F5D}\x{5F61}\x{5F62}\x{5F66}\x{5F69}\x{5F6A}\x{5F6B}\x{5F6C}' .
|
||||
'\x{5F6D}\x{5F70}\x{5F71}\x{5F73}\x{5F77}\x{5F79}\x{5F7C}\x{5F7F}\x{5F80}' .
|
||||
'\x{5F81}\x{5F82}\x{5F83}\x{5F84}\x{5F85}\x{5F87}\x{5F88}\x{5F8A}\x{5F8B}' .
|
||||
'\x{5F8C}\x{5F90}\x{5F91}\x{5F92}\x{5F93}\x{5F97}\x{5F98}\x{5F99}\x{5F9E}' .
|
||||
'\x{5FA0}\x{5FA1}\x{5FA8}\x{5FA9}\x{5FAA}\x{5FAD}\x{5FAE}\x{5FB3}\x{5FB4}' .
|
||||
'\x{5FB9}\x{5FBC}\x{5FBD}\x{5FC3}\x{5FC5}\x{5FCC}\x{5FCD}\x{5FD6}\x{5FD7}' .
|
||||
'\x{5FD8}\x{5FD9}\x{5FDC}\x{5FDD}\x{5FE0}\x{5FE4}\x{5FEB}\x{5FF0}\x{5FF1}' .
|
||||
'\x{5FF5}\x{5FF8}\x{5FFB}\x{5FFD}\x{5FFF}\x{600E}\x{600F}\x{6010}\x{6012}' .
|
||||
'\x{6015}\x{6016}\x{6019}\x{601B}\x{601C}\x{601D}\x{6020}\x{6021}\x{6025}' .
|
||||
'\x{6026}\x{6027}\x{6028}\x{6029}\x{602A}\x{602B}\x{602F}\x{6031}\x{603A}' .
|
||||
'\x{6041}\x{6042}\x{6043}\x{6046}\x{604A}\x{604B}\x{604D}\x{6050}\x{6052}' .
|
||||
'\x{6055}\x{6059}\x{605A}\x{605F}\x{6060}\x{6062}\x{6063}\x{6064}\x{6065}' .
|
||||
'\x{6068}\x{6069}\x{606A}\x{606B}\x{606C}\x{606D}\x{606F}\x{6070}\x{6075}' .
|
||||
'\x{6077}\x{6081}\x{6083}\x{6084}\x{6089}\x{608B}\x{608C}\x{608D}\x{6092}' .
|
||||
'\x{6094}\x{6096}\x{6097}\x{609A}\x{609B}\x{609F}\x{60A0}\x{60A3}\x{60A6}' .
|
||||
'\x{60A7}\x{60A9}\x{60AA}\x{60B2}\x{60B3}\x{60B4}\x{60B5}\x{60B6}\x{60B8}' .
|
||||
'\x{60BC}\x{60BD}\x{60C5}\x{60C6}\x{60C7}\x{60D1}\x{60D3}\x{60D8}\x{60DA}' .
|
||||
'\x{60DC}\x{60DF}\x{60E0}\x{60E1}\x{60E3}\x{60E7}\x{60E8}\x{60F0}\x{60F1}' .
|
||||
'\x{60F3}\x{60F4}\x{60F6}\x{60F7}\x{60F9}\x{60FA}\x{60FB}\x{6100}\x{6101}' .
|
||||
'\x{6103}\x{6106}\x{6108}\x{6109}\x{610D}\x{610E}\x{610F}\x{6115}\x{611A}' .
|
||||
'\x{611B}\x{611F}\x{6121}\x{6127}\x{6128}\x{612C}\x{6134}\x{613C}\x{613D}' .
|
||||
'\x{613E}\x{613F}\x{6142}\x{6144}\x{6147}\x{6148}\x{614A}\x{614B}\x{614C}' .
|
||||
'\x{614D}\x{614E}\x{6153}\x{6155}\x{6158}\x{6159}\x{615A}\x{615D}\x{615F}' .
|
||||
'\x{6162}\x{6163}\x{6165}\x{6167}\x{6168}\x{616B}\x{616E}\x{616F}\x{6170}' .
|
||||
'\x{6171}\x{6173}\x{6174}\x{6175}\x{6176}\x{6177}\x{617E}\x{6182}\x{6187}' .
|
||||
'\x{618A}\x{618E}\x{6190}\x{6191}\x{6194}\x{6196}\x{6199}\x{619A}\x{61A4}' .
|
||||
'\x{61A7}\x{61A9}\x{61AB}\x{61AC}\x{61AE}\x{61B2}\x{61B6}\x{61BA}\x{61BE}' .
|
||||
'\x{61C3}\x{61C6}\x{61C7}\x{61C8}\x{61C9}\x{61CA}\x{61CB}\x{61CC}\x{61CD}' .
|
||||
'\x{61D0}\x{61E3}\x{61E6}\x{61F2}\x{61F4}\x{61F6}\x{61F7}\x{61F8}\x{61FA}' .
|
||||
'\x{61FC}\x{61FD}\x{61FE}\x{61FF}\x{6200}\x{6208}\x{6209}\x{620A}\x{620C}' .
|
||||
'\x{620D}\x{620E}\x{6210}\x{6211}\x{6212}\x{6214}\x{6216}\x{621A}\x{621B}' .
|
||||
'\x{621D}\x{621E}\x{621F}\x{6221}\x{6226}\x{622A}\x{622E}\x{622F}\x{6230}' .
|
||||
'\x{6232}\x{6233}\x{6234}\x{6238}\x{623B}\x{623F}\x{6240}\x{6241}\x{6247}' .
|
||||
'\x{6248}\x{6249}\x{624B}\x{624D}\x{624E}\x{6253}\x{6255}\x{6258}\x{625B}' .
|
||||
'\x{625E}\x{6260}\x{6263}\x{6268}\x{626E}\x{6271}\x{6276}\x{6279}\x{627C}' .
|
||||
'\x{627E}\x{627F}\x{6280}\x{6282}\x{6283}\x{6284}\x{6289}\x{628A}\x{6291}' .
|
||||
'\x{6292}\x{6293}\x{6294}\x{6295}\x{6296}\x{6297}\x{6298}\x{629B}\x{629C}' .
|
||||
'\x{629E}\x{62AB}\x{62AC}\x{62B1}\x{62B5}\x{62B9}\x{62BB}\x{62BC}\x{62BD}' .
|
||||
'\x{62C2}\x{62C5}\x{62C6}\x{62C7}\x{62C8}\x{62C9}\x{62CA}\x{62CC}\x{62CD}' .
|
||||
'\x{62CF}\x{62D0}\x{62D1}\x{62D2}\x{62D3}\x{62D4}\x{62D7}\x{62D8}\x{62D9}' .
|
||||
'\x{62DB}\x{62DC}\x{62DD}\x{62E0}\x{62E1}\x{62EC}\x{62ED}\x{62EE}\x{62EF}' .
|
||||
'\x{62F1}\x{62F3}\x{62F5}\x{62F6}\x{62F7}\x{62FE}\x{62FF}\x{6301}\x{6302}' .
|
||||
'\x{6307}\x{6308}\x{6309}\x{630C}\x{6311}\x{6319}\x{631F}\x{6327}\x{6328}' .
|
||||
'\x{632B}\x{632F}\x{633A}\x{633D}\x{633E}\x{633F}\x{6349}\x{634C}\x{634D}' .
|
||||
'\x{634F}\x{6350}\x{6355}\x{6357}\x{635C}\x{6367}\x{6368}\x{6369}\x{636B}' .
|
||||
'\x{636E}\x{6372}\x{6376}\x{6377}\x{637A}\x{637B}\x{6380}\x{6383}\x{6388}' .
|
||||
'\x{6389}\x{638C}\x{638E}\x{638F}\x{6392}\x{6396}\x{6398}\x{639B}\x{639F}' .
|
||||
'\x{63A0}\x{63A1}\x{63A2}\x{63A3}\x{63A5}\x{63A7}\x{63A8}\x{63A9}\x{63AA}' .
|
||||
'\x{63AB}\x{63AC}\x{63B2}\x{63B4}\x{63B5}\x{63BB}\x{63BE}\x{63C0}\x{63C3}' .
|
||||
'\x{63C4}\x{63C6}\x{63C9}\x{63CF}\x{63D0}\x{63D2}\x{63D6}\x{63DA}\x{63DB}' .
|
||||
'\x{63E1}\x{63E3}\x{63E9}\x{63EE}\x{63F4}\x{63F6}\x{63FA}\x{6406}\x{640D}' .
|
||||
'\x{640F}\x{6413}\x{6416}\x{6417}\x{641C}\x{6426}\x{6428}\x{642C}\x{642D}' .
|
||||
'\x{6434}\x{6436}\x{643A}\x{643E}\x{6442}\x{644E}\x{6458}\x{6467}\x{6469}' .
|
||||
'\x{646F}\x{6476}\x{6478}\x{647A}\x{6483}\x{6488}\x{6492}\x{6493}\x{6495}' .
|
||||
'\x{649A}\x{649E}\x{64A4}\x{64A5}\x{64A9}\x{64AB}\x{64AD}\x{64AE}\x{64B0}' .
|
||||
'\x{64B2}\x{64B9}\x{64BB}\x{64BC}\x{64C1}\x{64C2}\x{64C5}\x{64C7}\x{64CD}' .
|
||||
'\x{64D2}\x{64D4}\x{64D8}\x{64DA}\x{64E0}\x{64E1}\x{64E2}\x{64E3}\x{64E6}' .
|
||||
'\x{64E7}\x{64EC}\x{64EF}\x{64F1}\x{64F2}\x{64F4}\x{64F6}\x{64FA}\x{64FD}' .
|
||||
'\x{64FE}\x{6500}\x{6505}\x{6518}\x{651C}\x{651D}\x{6523}\x{6524}\x{652A}' .
|
||||
'\x{652B}\x{652C}\x{652F}\x{6534}\x{6535}\x{6536}\x{6537}\x{6538}\x{6539}' .
|
||||
'\x{653B}\x{653E}\x{653F}\x{6545}\x{6548}\x{654D}\x{654F}\x{6551}\x{6555}' .
|
||||
'\x{6556}\x{6557}\x{6558}\x{6559}\x{655D}\x{655E}\x{6562}\x{6563}\x{6566}' .
|
||||
'\x{656C}\x{6570}\x{6572}\x{6574}\x{6575}\x{6577}\x{6578}\x{6582}\x{6583}' .
|
||||
'\x{6587}\x{6588}\x{6589}\x{658C}\x{658E}\x{6590}\x{6591}\x{6597}\x{6599}' .
|
||||
'\x{659B}\x{659C}\x{659F}\x{65A1}\x{65A4}\x{65A5}\x{65A7}\x{65AB}\x{65AC}' .
|
||||
'\x{65AD}\x{65AF}\x{65B0}\x{65B7}\x{65B9}\x{65BC}\x{65BD}\x{65C1}\x{65C3}' .
|
||||
'\x{65C4}\x{65C5}\x{65C6}\x{65CB}\x{65CC}\x{65CF}\x{65D2}\x{65D7}\x{65D9}' .
|
||||
'\x{65DB}\x{65E0}\x{65E1}\x{65E2}\x{65E5}\x{65E6}\x{65E7}\x{65E8}\x{65E9}' .
|
||||
'\x{65EC}\x{65ED}\x{65F1}\x{65FA}\x{65FB}\x{6602}\x{6603}\x{6606}\x{6607}' .
|
||||
'\x{660A}\x{660C}\x{660E}\x{660F}\x{6613}\x{6614}\x{661C}\x{661F}\x{6620}' .
|
||||
'\x{6625}\x{6627}\x{6628}\x{662D}\x{662F}\x{6634}\x{6635}\x{6636}\x{663C}' .
|
||||
'\x{663F}\x{6641}\x{6642}\x{6643}\x{6644}\x{6649}\x{664B}\x{664F}\x{6652}' .
|
||||
'\x{665D}\x{665E}\x{665F}\x{6662}\x{6664}\x{6666}\x{6667}\x{6668}\x{6669}' .
|
||||
'\x{666E}\x{666F}\x{6670}\x{6674}\x{6676}\x{667A}\x{6681}\x{6683}\x{6684}' .
|
||||
'\x{6687}\x{6688}\x{6689}\x{668E}\x{6691}\x{6696}\x{6697}\x{6698}\x{669D}' .
|
||||
'\x{66A2}\x{66A6}\x{66AB}\x{66AE}\x{66B4}\x{66B8}\x{66B9}\x{66BC}\x{66BE}' .
|
||||
'\x{66C1}\x{66C4}\x{66C7}\x{66C9}\x{66D6}\x{66D9}\x{66DA}\x{66DC}\x{66DD}' .
|
||||
'\x{66E0}\x{66E6}\x{66E9}\x{66F0}\x{66F2}\x{66F3}\x{66F4}\x{66F5}\x{66F7}' .
|
||||
'\x{66F8}\x{66F9}\x{66FC}\x{66FD}\x{66FE}\x{66FF}\x{6700}\x{6703}\x{6708}' .
|
||||
'\x{6709}\x{670B}\x{670D}\x{670F}\x{6714}\x{6715}\x{6716}\x{6717}\x{671B}' .
|
||||
'\x{671D}\x{671E}\x{671F}\x{6726}\x{6727}\x{6728}\x{672A}\x{672B}\x{672C}' .
|
||||
'\x{672D}\x{672E}\x{6731}\x{6734}\x{6736}\x{6737}\x{6738}\x{673A}\x{673D}' .
|
||||
'\x{673F}\x{6741}\x{6746}\x{6749}\x{674E}\x{674F}\x{6750}\x{6751}\x{6753}' .
|
||||
'\x{6756}\x{6759}\x{675C}\x{675E}\x{675F}\x{6760}\x{6761}\x{6762}\x{6763}' .
|
||||
'\x{6764}\x{6765}\x{676A}\x{676D}\x{676F}\x{6770}\x{6771}\x{6772}\x{6773}' .
|
||||
'\x{6775}\x{6777}\x{677C}\x{677E}\x{677F}\x{6785}\x{6787}\x{6789}\x{678B}' .
|
||||
'\x{678C}\x{6790}\x{6795}\x{6797}\x{679A}\x{679C}\x{679D}\x{67A0}\x{67A1}' .
|
||||
'\x{67A2}\x{67A6}\x{67A9}\x{67AF}\x{67B3}\x{67B4}\x{67B6}\x{67B7}\x{67B8}' .
|
||||
'\x{67B9}\x{67C1}\x{67C4}\x{67C6}\x{67CA}\x{67CE}\x{67CF}\x{67D0}\x{67D1}' .
|
||||
'\x{67D3}\x{67D4}\x{67D8}\x{67DA}\x{67DD}\x{67DE}\x{67E2}\x{67E4}\x{67E7}' .
|
||||
'\x{67E9}\x{67EC}\x{67EE}\x{67EF}\x{67F1}\x{67F3}\x{67F4}\x{67F5}\x{67FB}' .
|
||||
'\x{67FE}\x{67FF}\x{6802}\x{6803}\x{6804}\x{6813}\x{6816}\x{6817}\x{681E}' .
|
||||
'\x{6821}\x{6822}\x{6829}\x{682A}\x{682B}\x{6832}\x{6834}\x{6838}\x{6839}' .
|
||||
'\x{683C}\x{683D}\x{6840}\x{6841}\x{6842}\x{6843}\x{6846}\x{6848}\x{684D}' .
|
||||
'\x{684E}\x{6850}\x{6851}\x{6853}\x{6854}\x{6859}\x{685C}\x{685D}\x{685F}' .
|
||||
'\x{6863}\x{6867}\x{6874}\x{6876}\x{6877}\x{687E}\x{687F}\x{6881}\x{6883}' .
|
||||
'\x{6885}\x{688D}\x{688F}\x{6893}\x{6894}\x{6897}\x{689B}\x{689D}\x{689F}' .
|
||||
'\x{68A0}\x{68A2}\x{68A6}\x{68A7}\x{68A8}\x{68AD}\x{68AF}\x{68B0}\x{68B1}' .
|
||||
'\x{68B3}\x{68B5}\x{68B6}\x{68B9}\x{68BA}\x{68BC}\x{68C4}\x{68C6}\x{68C9}' .
|
||||
'\x{68CA}\x{68CB}\x{68CD}\x{68D2}\x{68D4}\x{68D5}\x{68D7}\x{68D8}\x{68DA}' .
|
||||
'\x{68DF}\x{68E0}\x{68E1}\x{68E3}\x{68E7}\x{68EE}\x{68EF}\x{68F2}\x{68F9}' .
|
||||
'\x{68FA}\x{6900}\x{6901}\x{6904}\x{6905}\x{6908}\x{690B}\x{690C}\x{690D}' .
|
||||
'\x{690E}\x{690F}\x{6912}\x{6919}\x{691A}\x{691B}\x{691C}\x{6921}\x{6922}' .
|
||||
'\x{6923}\x{6925}\x{6926}\x{6928}\x{692A}\x{6930}\x{6934}\x{6936}\x{6939}' .
|
||||
'\x{693D}\x{693F}\x{694A}\x{6953}\x{6954}\x{6955}\x{6959}\x{695A}\x{695C}' .
|
||||
'\x{695D}\x{695E}\x{6960}\x{6961}\x{6962}\x{696A}\x{696B}\x{696D}\x{696E}' .
|
||||
'\x{696F}\x{6973}\x{6974}\x{6975}\x{6977}\x{6978}\x{6979}\x{697C}\x{697D}' .
|
||||
'\x{697E}\x{6981}\x{6982}\x{698A}\x{698E}\x{6991}\x{6994}\x{6995}\x{699B}' .
|
||||
'\x{699C}\x{69A0}\x{69A7}\x{69AE}\x{69B1}\x{69B2}\x{69B4}\x{69BB}\x{69BE}' .
|
||||
'\x{69BF}\x{69C1}\x{69C3}\x{69C7}\x{69CA}\x{69CB}\x{69CC}\x{69CD}\x{69CE}' .
|
||||
'\x{69D0}\x{69D3}\x{69D8}\x{69D9}\x{69DD}\x{69DE}\x{69E7}\x{69E8}\x{69EB}' .
|
||||
'\x{69ED}\x{69F2}\x{69F9}\x{69FB}\x{69FD}\x{69FF}\x{6A02}\x{6A05}\x{6A0A}' .
|
||||
'\x{6A0B}\x{6A0C}\x{6A12}\x{6A13}\x{6A14}\x{6A17}\x{6A19}\x{6A1B}\x{6A1E}' .
|
||||
'\x{6A1F}\x{6A21}\x{6A22}\x{6A23}\x{6A29}\x{6A2A}\x{6A2B}\x{6A2E}\x{6A35}' .
|
||||
'\x{6A36}\x{6A38}\x{6A39}\x{6A3A}\x{6A3D}\x{6A44}\x{6A47}\x{6A48}\x{6A4B}' .
|
||||
'\x{6A58}\x{6A59}\x{6A5F}\x{6A61}\x{6A62}\x{6A66}\x{6A72}\x{6A78}\x{6A7F}' .
|
||||
'\x{6A80}\x{6A84}\x{6A8D}\x{6A8E}\x{6A90}\x{6A97}\x{6A9C}\x{6AA0}\x{6AA2}' .
|
||||
'\x{6AA3}\x{6AAA}\x{6AAC}\x{6AAE}\x{6AB3}\x{6AB8}\x{6ABB}\x{6AC1}\x{6AC2}' .
|
||||
'\x{6AC3}\x{6AD1}\x{6AD3}\x{6ADA}\x{6ADB}\x{6ADE}\x{6ADF}\x{6AE8}\x{6AEA}' .
|
||||
'\x{6AFA}\x{6AFB}\x{6B04}\x{6B05}\x{6B0A}\x{6B12}\x{6B16}\x{6B1D}\x{6B1F}' .
|
||||
'\x{6B20}\x{6B21}\x{6B23}\x{6B27}\x{6B32}\x{6B37}\x{6B38}\x{6B39}\x{6B3A}' .
|
||||
'\x{6B3D}\x{6B3E}\x{6B43}\x{6B47}\x{6B49}\x{6B4C}\x{6B4E}\x{6B50}\x{6B53}' .
|
||||
'\x{6B54}\x{6B59}\x{6B5B}\x{6B5F}\x{6B61}\x{6B62}\x{6B63}\x{6B64}\x{6B66}' .
|
||||
'\x{6B69}\x{6B6A}\x{6B6F}\x{6B73}\x{6B74}\x{6B78}\x{6B79}\x{6B7B}\x{6B7F}' .
|
||||
'\x{6B80}\x{6B83}\x{6B84}\x{6B86}\x{6B89}\x{6B8A}\x{6B8B}\x{6B8D}\x{6B95}' .
|
||||
'\x{6B96}\x{6B98}\x{6B9E}\x{6BA4}\x{6BAA}\x{6BAB}\x{6BAF}\x{6BB1}\x{6BB2}' .
|
||||
'\x{6BB3}\x{6BB4}\x{6BB5}\x{6BB7}\x{6BBA}\x{6BBB}\x{6BBC}\x{6BBF}\x{6BC0}' .
|
||||
'\x{6BC5}\x{6BC6}\x{6BCB}\x{6BCD}\x{6BCE}\x{6BD2}\x{6BD3}\x{6BD4}\x{6BD8}' .
|
||||
'\x{6BDB}\x{6BDF}\x{6BEB}\x{6BEC}\x{6BEF}\x{6BF3}\x{6C08}\x{6C0F}\x{6C11}' .
|
||||
'\x{6C13}\x{6C14}\x{6C17}\x{6C1B}\x{6C23}\x{6C24}\x{6C34}\x{6C37}\x{6C38}' .
|
||||
'\x{6C3E}\x{6C40}\x{6C41}\x{6C42}\x{6C4E}\x{6C50}\x{6C55}\x{6C57}\x{6C5A}' .
|
||||
'\x{6C5D}\x{6C5E}\x{6C5F}\x{6C60}\x{6C62}\x{6C68}\x{6C6A}\x{6C70}\x{6C72}' .
|
||||
'\x{6C73}\x{6C7A}\x{6C7D}\x{6C7E}\x{6C81}\x{6C82}\x{6C83}\x{6C88}\x{6C8C}' .
|
||||
'\x{6C8D}\x{6C90}\x{6C92}\x{6C93}\x{6C96}\x{6C99}\x{6C9A}\x{6C9B}\x{6CA1}' .
|
||||
'\x{6CA2}\x{6CAB}\x{6CAE}\x{6CB1}\x{6CB3}\x{6CB8}\x{6CB9}\x{6CBA}\x{6CBB}' .
|
||||
'\x{6CBC}\x{6CBD}\x{6CBE}\x{6CBF}\x{6CC1}\x{6CC4}\x{6CC5}\x{6CC9}\x{6CCA}' .
|
||||
'\x{6CCC}\x{6CD3}\x{6CD5}\x{6CD7}\x{6CD9}\x{6CDB}\x{6CDD}\x{6CE1}\x{6CE2}' .
|
||||
'\x{6CE3}\x{6CE5}\x{6CE8}\x{6CEA}\x{6CEF}\x{6CF0}\x{6CF1}\x{6CF3}\x{6D0B}' .
|
||||
'\x{6D0C}\x{6D12}\x{6D17}\x{6D19}\x{6D1B}\x{6D1E}\x{6D1F}\x{6D25}\x{6D29}' .
|
||||
'\x{6D2A}\x{6D2B}\x{6D32}\x{6D33}\x{6D35}\x{6D36}\x{6D38}\x{6D3B}\x{6D3D}' .
|
||||
'\x{6D3E}\x{6D41}\x{6D44}\x{6D45}\x{6D59}\x{6D5A}\x{6D5C}\x{6D63}\x{6D64}' .
|
||||
'\x{6D66}\x{6D69}\x{6D6A}\x{6D6C}\x{6D6E}\x{6D74}\x{6D77}\x{6D78}\x{6D79}' .
|
||||
'\x{6D85}\x{6D88}\x{6D8C}\x{6D8E}\x{6D93}\x{6D95}\x{6D99}\x{6D9B}\x{6D9C}' .
|
||||
'\x{6DAF}\x{6DB2}\x{6DB5}\x{6DB8}\x{6DBC}\x{6DC0}\x{6DC5}\x{6DC6}\x{6DC7}' .
|
||||
'\x{6DCB}\x{6DCC}\x{6DD1}\x{6DD2}\x{6DD5}\x{6DD8}\x{6DD9}\x{6DDE}\x{6DE1}' .
|
||||
'\x{6DE4}\x{6DE6}\x{6DE8}\x{6DEA}\x{6DEB}\x{6DEC}\x{6DEE}\x{6DF1}\x{6DF3}' .
|
||||
'\x{6DF5}\x{6DF7}\x{6DF9}\x{6DFA}\x{6DFB}\x{6E05}\x{6E07}\x{6E08}\x{6E09}' .
|
||||
'\x{6E0A}\x{6E0B}\x{6E13}\x{6E15}\x{6E19}\x{6E1A}\x{6E1B}\x{6E1D}\x{6E1F}' .
|
||||
'\x{6E20}\x{6E21}\x{6E23}\x{6E24}\x{6E25}\x{6E26}\x{6E29}\x{6E2B}\x{6E2C}' .
|
||||
'\x{6E2D}\x{6E2E}\x{6E2F}\x{6E38}\x{6E3A}\x{6E3E}\x{6E43}\x{6E4A}\x{6E4D}' .
|
||||
'\x{6E4E}\x{6E56}\x{6E58}\x{6E5B}\x{6E5F}\x{6E67}\x{6E6B}\x{6E6E}\x{6E6F}' .
|
||||
'\x{6E72}\x{6E76}\x{6E7E}\x{6E7F}\x{6E80}\x{6E82}\x{6E8C}\x{6E8F}\x{6E90}' .
|
||||
'\x{6E96}\x{6E98}\x{6E9C}\x{6E9D}\x{6E9F}\x{6EA2}\x{6EA5}\x{6EAA}\x{6EAF}' .
|
||||
'\x{6EB2}\x{6EB6}\x{6EB7}\x{6EBA}\x{6EBD}\x{6EC2}\x{6EC4}\x{6EC5}\x{6EC9}' .
|
||||
'\x{6ECB}\x{6ECC}\x{6ED1}\x{6ED3}\x{6ED4}\x{6ED5}\x{6EDD}\x{6EDE}\x{6EEC}' .
|
||||
'\x{6EEF}\x{6EF2}\x{6EF4}\x{6EF7}\x{6EF8}\x{6EFE}\x{6EFF}\x{6F01}\x{6F02}' .
|
||||
'\x{6F06}\x{6F09}\x{6F0F}\x{6F11}\x{6F13}\x{6F14}\x{6F15}\x{6F20}\x{6F22}' .
|
||||
'\x{6F23}\x{6F2B}\x{6F2C}\x{6F31}\x{6F32}\x{6F38}\x{6F3E}\x{6F3F}\x{6F41}' .
|
||||
'\x{6F45}\x{6F54}\x{6F58}\x{6F5B}\x{6F5C}\x{6F5F}\x{6F64}\x{6F66}\x{6F6D}' .
|
||||
'\x{6F6E}\x{6F6F}\x{6F70}\x{6F74}\x{6F78}\x{6F7A}\x{6F7C}\x{6F80}\x{6F81}' .
|
||||
'\x{6F82}\x{6F84}\x{6F86}\x{6F8E}\x{6F91}\x{6F97}\x{6FA1}\x{6FA3}\x{6FA4}' .
|
||||
'\x{6FAA}\x{6FB1}\x{6FB3}\x{6FB9}\x{6FC0}\x{6FC1}\x{6FC2}\x{6FC3}\x{6FC6}' .
|
||||
'\x{6FD4}\x{6FD5}\x{6FD8}\x{6FDB}\x{6FDF}\x{6FE0}\x{6FE1}\x{6FE4}\x{6FEB}' .
|
||||
'\x{6FEC}\x{6FEE}\x{6FEF}\x{6FF1}\x{6FF3}\x{6FF6}\x{6FFA}\x{6FFE}\x{7001}' .
|
||||
'\x{7009}\x{700B}\x{700F}\x{7011}\x{7015}\x{7018}\x{701A}\x{701B}\x{701D}' .
|
||||
'\x{701E}\x{701F}\x{7026}\x{7027}\x{702C}\x{7030}\x{7032}\x{703E}\x{704C}' .
|
||||
'\x{7051}\x{7058}\x{7063}\x{706B}\x{706F}\x{7070}\x{7078}\x{707C}\x{707D}' .
|
||||
'\x{7089}\x{708A}\x{708E}\x{7092}\x{7099}\x{70AC}\x{70AD}\x{70AE}\x{70AF}' .
|
||||
'\x{70B3}\x{70B8}\x{70B9}\x{70BA}\x{70C8}\x{70CB}\x{70CF}\x{70D9}\x{70DD}' .
|
||||
'\x{70DF}\x{70F1}\x{70F9}\x{70FD}\x{7109}\x{7114}\x{7119}\x{711A}\x{711C}' .
|
||||
'\x{7121}\x{7126}\x{7136}\x{713C}\x{7149}\x{714C}\x{714E}\x{7155}\x{7156}' .
|
||||
'\x{7159}\x{7162}\x{7164}\x{7165}\x{7166}\x{7167}\x{7169}\x{716C}\x{716E}' .
|
||||
'\x{717D}\x{7184}\x{7188}\x{718A}\x{718F}\x{7194}\x{7195}\x{7199}\x{719F}' .
|
||||
'\x{71A8}\x{71AC}\x{71B1}\x{71B9}\x{71BE}\x{71C3}\x{71C8}\x{71C9}\x{71CE}' .
|
||||
'\x{71D0}\x{71D2}\x{71D4}\x{71D5}\x{71D7}\x{71DF}\x{71E0}\x{71E5}\x{71E6}' .
|
||||
'\x{71E7}\x{71EC}\x{71ED}\x{71EE}\x{71F5}\x{71F9}\x{71FB}\x{71FC}\x{71FF}' .
|
||||
'\x{7206}\x{720D}\x{7210}\x{721B}\x{7228}\x{722A}\x{722C}\x{722D}\x{7230}' .
|
||||
'\x{7232}\x{7235}\x{7236}\x{723A}\x{723B}\x{723C}\x{723D}\x{723E}\x{723F}' .
|
||||
'\x{7240}\x{7246}\x{7247}\x{7248}\x{724B}\x{724C}\x{7252}\x{7258}\x{7259}' .
|
||||
'\x{725B}\x{725D}\x{725F}\x{7261}\x{7262}\x{7267}\x{7269}\x{7272}\x{7274}' .
|
||||
'\x{7279}\x{727D}\x{727E}\x{7280}\x{7281}\x{7282}\x{7287}\x{7292}\x{7296}' .
|
||||
'\x{72A0}\x{72A2}\x{72A7}\x{72AC}\x{72AF}\x{72B2}\x{72B6}\x{72B9}\x{72C2}' .
|
||||
'\x{72C3}\x{72C4}\x{72C6}\x{72CE}\x{72D0}\x{72D2}\x{72D7}\x{72D9}\x{72DB}' .
|
||||
'\x{72E0}\x{72E1}\x{72E2}\x{72E9}\x{72EC}\x{72ED}\x{72F7}\x{72F8}\x{72F9}' .
|
||||
'\x{72FC}\x{72FD}\x{730A}\x{7316}\x{7317}\x{731B}\x{731C}\x{731D}\x{731F}' .
|
||||
'\x{7325}\x{7329}\x{732A}\x{732B}\x{732E}\x{732F}\x{7334}\x{7336}\x{7337}' .
|
||||
'\x{733E}\x{733F}\x{7344}\x{7345}\x{734E}\x{734F}\x{7357}\x{7363}\x{7368}' .
|
||||
'\x{736A}\x{7370}\x{7372}\x{7375}\x{7378}\x{737A}\x{737B}\x{7384}\x{7387}' .
|
||||
'\x{7389}\x{738B}\x{7396}\x{73A9}\x{73B2}\x{73B3}\x{73BB}\x{73C0}\x{73C2}' .
|
||||
'\x{73C8}\x{73CA}\x{73CD}\x{73CE}\x{73DE}\x{73E0}\x{73E5}\x{73EA}\x{73ED}' .
|
||||
'\x{73EE}\x{73F1}\x{73F8}\x{73FE}\x{7403}\x{7405}\x{7406}\x{7409}\x{7422}' .
|
||||
'\x{7425}\x{7432}\x{7433}\x{7434}\x{7435}\x{7436}\x{743A}\x{743F}\x{7441}' .
|
||||
'\x{7455}\x{7459}\x{745A}\x{745B}\x{745C}\x{745E}\x{745F}\x{7460}\x{7463}' .
|
||||
'\x{7464}\x{7469}\x{746A}\x{746F}\x{7470}\x{7473}\x{7476}\x{747E}\x{7483}' .
|
||||
'\x{748B}\x{749E}\x{74A2}\x{74A7}\x{74B0}\x{74BD}\x{74CA}\x{74CF}\x{74D4}' .
|
||||
'\x{74DC}\x{74E0}\x{74E2}\x{74E3}\x{74E6}\x{74E7}\x{74E9}\x{74EE}\x{74F0}' .
|
||||
'\x{74F1}\x{74F2}\x{74F6}\x{74F7}\x{74F8}\x{7503}\x{7504}\x{7505}\x{750C}' .
|
||||
'\x{750D}\x{750E}\x{7511}\x{7513}\x{7515}\x{7518}\x{751A}\x{751C}\x{751E}' .
|
||||
'\x{751F}\x{7523}\x{7525}\x{7526}\x{7528}\x{752B}\x{752C}\x{7530}\x{7531}' .
|
||||
'\x{7532}\x{7533}\x{7537}\x{7538}\x{753A}\x{753B}\x{753C}\x{7544}\x{7546}' .
|
||||
'\x{7549}\x{754A}\x{754B}\x{754C}\x{754D}\x{754F}\x{7551}\x{7554}\x{7559}' .
|
||||
'\x{755A}\x{755B}\x{755C}\x{755D}\x{7560}\x{7562}\x{7564}\x{7565}\x{7566}' .
|
||||
'\x{7567}\x{7569}\x{756A}\x{756B}\x{756D}\x{7570}\x{7573}\x{7574}\x{7576}' .
|
||||
'\x{7577}\x{7578}\x{757F}\x{7582}\x{7586}\x{7587}\x{7589}\x{758A}\x{758B}' .
|
||||
'\x{758E}\x{758F}\x{7591}\x{7594}\x{759A}\x{759D}\x{75A3}\x{75A5}\x{75AB}' .
|
||||
'\x{75B1}\x{75B2}\x{75B3}\x{75B5}\x{75B8}\x{75B9}\x{75BC}\x{75BD}\x{75BE}' .
|
||||
'\x{75C2}\x{75C3}\x{75C5}\x{75C7}\x{75CA}\x{75CD}\x{75D2}\x{75D4}\x{75D5}' .
|
||||
'\x{75D8}\x{75D9}\x{75DB}\x{75DE}\x{75E2}\x{75E3}\x{75E9}\x{75F0}\x{75F2}' .
|
||||
'\x{75F3}\x{75F4}\x{75FA}\x{75FC}\x{75FE}\x{75FF}\x{7601}\x{7609}\x{760B}' .
|
||||
'\x{760D}\x{761F}\x{7620}\x{7621}\x{7622}\x{7624}\x{7627}\x{7630}\x{7634}' .
|
||||
'\x{763B}\x{7642}\x{7646}\x{7647}\x{7648}\x{764C}\x{7652}\x{7656}\x{7658}' .
|
||||
'\x{765C}\x{7661}\x{7662}\x{7667}\x{7668}\x{7669}\x{766A}\x{766C}\x{7670}' .
|
||||
'\x{7672}\x{7676}\x{7678}\x{767A}\x{767B}\x{767C}\x{767D}\x{767E}\x{7680}' .
|
||||
'\x{7683}\x{7684}\x{7686}\x{7687}\x{7688}\x{768B}\x{768E}\x{7690}\x{7693}' .
|
||||
'\x{7696}\x{7699}\x{769A}\x{76AE}\x{76B0}\x{76B4}\x{76B7}\x{76B8}\x{76B9}' .
|
||||
'\x{76BA}\x{76BF}\x{76C2}\x{76C3}\x{76C6}\x{76C8}\x{76CA}\x{76CD}\x{76D2}' .
|
||||
'\x{76D6}\x{76D7}\x{76DB}\x{76DC}\x{76DE}\x{76DF}\x{76E1}\x{76E3}\x{76E4}' .
|
||||
'\x{76E5}\x{76E7}\x{76EA}\x{76EE}\x{76F2}\x{76F4}\x{76F8}\x{76FB}\x{76FE}' .
|
||||
'\x{7701}\x{7704}\x{7707}\x{7708}\x{7709}\x{770B}\x{770C}\x{771B}\x{771E}' .
|
||||
'\x{771F}\x{7720}\x{7724}\x{7725}\x{7726}\x{7729}\x{7737}\x{7738}\x{773A}' .
|
||||
'\x{773C}\x{7740}\x{7747}\x{775A}\x{775B}\x{7761}\x{7763}\x{7765}\x{7766}' .
|
||||
'\x{7768}\x{776B}\x{7779}\x{777E}\x{777F}\x{778B}\x{778E}\x{7791}\x{779E}' .
|
||||
'\x{77A0}\x{77A5}\x{77AC}\x{77AD}\x{77B0}\x{77B3}\x{77B6}\x{77B9}\x{77BB}' .
|
||||
'\x{77BC}\x{77BD}\x{77BF}\x{77C7}\x{77CD}\x{77D7}\x{77DA}\x{77DB}\x{77DC}' .
|
||||
'\x{77E2}\x{77E3}\x{77E5}\x{77E7}\x{77E9}\x{77ED}\x{77EE}\x{77EF}\x{77F3}' .
|
||||
'\x{77FC}\x{7802}\x{780C}\x{7812}\x{7814}\x{7815}\x{7820}\x{7825}\x{7826}' .
|
||||
'\x{7827}\x{7832}\x{7834}\x{783A}\x{783F}\x{7845}\x{785D}\x{786B}\x{786C}' .
|
||||
'\x{786F}\x{7872}\x{7874}\x{787C}\x{7881}\x{7886}\x{7887}\x{788C}\x{788D}' .
|
||||
'\x{788E}\x{7891}\x{7893}\x{7895}\x{7897}\x{789A}\x{78A3}\x{78A7}\x{78A9}' .
|
||||
'\x{78AA}\x{78AF}\x{78B5}\x{78BA}\x{78BC}\x{78BE}\x{78C1}\x{78C5}\x{78C6}' .
|
||||
'\x{78CA}\x{78CB}\x{78D0}\x{78D1}\x{78D4}\x{78DA}\x{78E7}\x{78E8}\x{78EC}' .
|
||||
'\x{78EF}\x{78F4}\x{78FD}\x{7901}\x{7907}\x{790E}\x{7911}\x{7912}\x{7919}' .
|
||||
'\x{7926}\x{792A}\x{792B}\x{792C}\x{793A}\x{793C}\x{793E}\x{7940}\x{7941}' .
|
||||
'\x{7947}\x{7948}\x{7949}\x{7950}\x{7953}\x{7955}\x{7956}\x{7957}\x{795A}' .
|
||||
'\x{795D}\x{795E}\x{795F}\x{7960}\x{7962}\x{7965}\x{7968}\x{796D}\x{7977}' .
|
||||
'\x{797A}\x{797F}\x{7980}\x{7981}\x{7984}\x{7985}\x{798A}\x{798D}\x{798E}' .
|
||||
'\x{798F}\x{799D}\x{79A6}\x{79A7}\x{79AA}\x{79AE}\x{79B0}\x{79B3}\x{79B9}' .
|
||||
'\x{79BA}\x{79BD}\x{79BE}\x{79BF}\x{79C0}\x{79C1}\x{79C9}\x{79CB}\x{79D1}' .
|
||||
'\x{79D2}\x{79D5}\x{79D8}\x{79DF}\x{79E1}\x{79E3}\x{79E4}\x{79E6}\x{79E7}' .
|
||||
'\x{79E9}\x{79EC}\x{79F0}\x{79FB}\x{7A00}\x{7A08}\x{7A0B}\x{7A0D}\x{7A0E}' .
|
||||
'\x{7A14}\x{7A17}\x{7A18}\x{7A19}\x{7A1A}\x{7A1C}\x{7A1F}\x{7A20}\x{7A2E}' .
|
||||
'\x{7A31}\x{7A32}\x{7A37}\x{7A3B}\x{7A3C}\x{7A3D}\x{7A3E}\x{7A3F}\x{7A40}' .
|
||||
'\x{7A42}\x{7A43}\x{7A46}\x{7A49}\x{7A4D}\x{7A4E}\x{7A4F}\x{7A50}\x{7A57}' .
|
||||
'\x{7A61}\x{7A62}\x{7A63}\x{7A69}\x{7A6B}\x{7A70}\x{7A74}\x{7A76}\x{7A79}' .
|
||||
'\x{7A7A}\x{7A7D}\x{7A7F}\x{7A81}\x{7A83}\x{7A84}\x{7A88}\x{7A92}\x{7A93}' .
|
||||
'\x{7A95}\x{7A96}\x{7A97}\x{7A98}\x{7A9F}\x{7AA9}\x{7AAA}\x{7AAE}\x{7AAF}' .
|
||||
'\x{7AB0}\x{7AB6}\x{7ABA}\x{7ABF}\x{7AC3}\x{7AC4}\x{7AC5}\x{7AC7}\x{7AC8}' .
|
||||
'\x{7ACA}\x{7ACB}\x{7ACD}\x{7ACF}\x{7AD2}\x{7AD3}\x{7AD5}\x{7AD9}\x{7ADA}' .
|
||||
'\x{7ADC}\x{7ADD}\x{7ADF}\x{7AE0}\x{7AE1}\x{7AE2}\x{7AE3}\x{7AE5}\x{7AE6}' .
|
||||
'\x{7AEA}\x{7AED}\x{7AEF}\x{7AF0}\x{7AF6}\x{7AF8}\x{7AF9}\x{7AFA}\x{7AFF}' .
|
||||
'\x{7B02}\x{7B04}\x{7B06}\x{7B08}\x{7B0A}\x{7B0B}\x{7B0F}\x{7B11}\x{7B18}' .
|
||||
'\x{7B19}\x{7B1B}\x{7B1E}\x{7B20}\x{7B25}\x{7B26}\x{7B28}\x{7B2C}\x{7B33}' .
|
||||
'\x{7B35}\x{7B36}\x{7B39}\x{7B45}\x{7B46}\x{7B48}\x{7B49}\x{7B4B}\x{7B4C}' .
|
||||
'\x{7B4D}\x{7B4F}\x{7B50}\x{7B51}\x{7B52}\x{7B54}\x{7B56}\x{7B5D}\x{7B65}' .
|
||||
'\x{7B67}\x{7B6C}\x{7B6E}\x{7B70}\x{7B71}\x{7B74}\x{7B75}\x{7B7A}\x{7B86}' .
|
||||
'\x{7B87}\x{7B8B}\x{7B8D}\x{7B8F}\x{7B92}\x{7B94}\x{7B95}\x{7B97}\x{7B98}' .
|
||||
'\x{7B99}\x{7B9A}\x{7B9C}\x{7B9D}\x{7B9F}\x{7BA1}\x{7BAA}\x{7BAD}\x{7BB1}' .
|
||||
'\x{7BB4}\x{7BB8}\x{7BC0}\x{7BC1}\x{7BC4}\x{7BC6}\x{7BC7}\x{7BC9}\x{7BCB}' .
|
||||
'\x{7BCC}\x{7BCF}\x{7BDD}\x{7BE0}\x{7BE4}\x{7BE5}\x{7BE6}\x{7BE9}\x{7BED}' .
|
||||
'\x{7BF3}\x{7BF6}\x{7BF7}\x{7C00}\x{7C07}\x{7C0D}\x{7C11}\x{7C12}\x{7C13}' .
|
||||
'\x{7C14}\x{7C17}\x{7C1F}\x{7C21}\x{7C23}\x{7C27}\x{7C2A}\x{7C2B}\x{7C37}' .
|
||||
'\x{7C38}\x{7C3D}\x{7C3E}\x{7C3F}\x{7C40}\x{7C43}\x{7C4C}\x{7C4D}\x{7C4F}' .
|
||||
'\x{7C50}\x{7C54}\x{7C56}\x{7C58}\x{7C5F}\x{7C60}\x{7C64}\x{7C65}\x{7C6C}' .
|
||||
'\x{7C73}\x{7C75}\x{7C7E}\x{7C81}\x{7C82}\x{7C83}\x{7C89}\x{7C8B}\x{7C8D}' .
|
||||
'\x{7C90}\x{7C92}\x{7C95}\x{7C97}\x{7C98}\x{7C9B}\x{7C9F}\x{7CA1}\x{7CA2}' .
|
||||
'\x{7CA4}\x{7CA5}\x{7CA7}\x{7CA8}\x{7CAB}\x{7CAD}\x{7CAE}\x{7CB1}\x{7CB2}' .
|
||||
'\x{7CB3}\x{7CB9}\x{7CBD}\x{7CBE}\x{7CC0}\x{7CC2}\x{7CC5}\x{7CCA}\x{7CCE}' .
|
||||
'\x{7CD2}\x{7CD6}\x{7CD8}\x{7CDC}\x{7CDE}\x{7CDF}\x{7CE0}\x{7CE2}\x{7CE7}' .
|
||||
'\x{7CEF}\x{7CF2}\x{7CF4}\x{7CF6}\x{7CF8}\x{7CFA}\x{7CFB}\x{7CFE}\x{7D00}' .
|
||||
'\x{7D02}\x{7D04}\x{7D05}\x{7D06}\x{7D0A}\x{7D0B}\x{7D0D}\x{7D10}\x{7D14}' .
|
||||
'\x{7D15}\x{7D17}\x{7D18}\x{7D19}\x{7D1A}\x{7D1B}\x{7D1C}\x{7D20}\x{7D21}' .
|
||||
'\x{7D22}\x{7D2B}\x{7D2C}\x{7D2E}\x{7D2F}\x{7D30}\x{7D32}\x{7D33}\x{7D35}' .
|
||||
'\x{7D39}\x{7D3A}\x{7D3F}\x{7D42}\x{7D43}\x{7D44}\x{7D45}\x{7D46}\x{7D4B}' .
|
||||
'\x{7D4C}\x{7D4E}\x{7D4F}\x{7D50}\x{7D56}\x{7D5B}\x{7D5E}\x{7D61}\x{7D62}' .
|
||||
'\x{7D63}\x{7D66}\x{7D68}\x{7D6E}\x{7D71}\x{7D72}\x{7D73}\x{7D75}\x{7D76}' .
|
||||
'\x{7D79}\x{7D7D}\x{7D89}\x{7D8F}\x{7D93}\x{7D99}\x{7D9A}\x{7D9B}\x{7D9C}' .
|
||||
'\x{7D9F}\x{7DA2}\x{7DA3}\x{7DAB}\x{7DAC}\x{7DAD}\x{7DAE}\x{7DAF}\x{7DB0}' .
|
||||
'\x{7DB1}\x{7DB2}\x{7DB4}\x{7DB5}\x{7DB8}\x{7DBA}\x{7DBB}\x{7DBD}\x{7DBE}' .
|
||||
'\x{7DBF}\x{7DC7}\x{7DCA}\x{7DCB}\x{7DCF}\x{7DD1}\x{7DD2}\x{7DD5}\x{7DD8}' .
|
||||
'\x{7DDA}\x{7DDC}\x{7DDD}\x{7DDE}\x{7DE0}\x{7DE1}\x{7DE4}\x{7DE8}\x{7DE9}' .
|
||||
'\x{7DEC}\x{7DEF}\x{7DF2}\x{7DF4}\x{7DFB}\x{7E01}\x{7E04}\x{7E05}\x{7E09}' .
|
||||
'\x{7E0A}\x{7E0B}\x{7E12}\x{7E1B}\x{7E1E}\x{7E1F}\x{7E21}\x{7E22}\x{7E23}' .
|
||||
'\x{7E26}\x{7E2B}\x{7E2E}\x{7E31}\x{7E32}\x{7E35}\x{7E37}\x{7E39}\x{7E3A}' .
|
||||
'\x{7E3B}\x{7E3D}\x{7E3E}\x{7E41}\x{7E43}\x{7E46}\x{7E4A}\x{7E4B}\x{7E4D}' .
|
||||
'\x{7E54}\x{7E55}\x{7E56}\x{7E59}\x{7E5A}\x{7E5D}\x{7E5E}\x{7E66}\x{7E67}' .
|
||||
'\x{7E69}\x{7E6A}\x{7E6D}\x{7E70}\x{7E79}\x{7E7B}\x{7E7C}\x{7E7D}\x{7E7F}' .
|
||||
'\x{7E82}\x{7E83}\x{7E88}\x{7E89}\x{7E8C}\x{7E8E}\x{7E8F}\x{7E90}\x{7E92}' .
|
||||
'\x{7E93}\x{7E94}\x{7E96}\x{7E9B}\x{7E9C}\x{7F36}\x{7F38}\x{7F3A}\x{7F45}' .
|
||||
'\x{7F4C}\x{7F4D}\x{7F4E}\x{7F50}\x{7F51}\x{7F54}\x{7F55}\x{7F58}\x{7F5F}' .
|
||||
'\x{7F60}\x{7F67}\x{7F68}\x{7F69}\x{7F6A}\x{7F6B}\x{7F6E}\x{7F70}\x{7F72}' .
|
||||
'\x{7F75}\x{7F77}\x{7F78}\x{7F79}\x{7F82}\x{7F83}\x{7F85}\x{7F86}\x{7F87}' .
|
||||
'\x{7F88}\x{7F8A}\x{7F8C}\x{7F8E}\x{7F94}\x{7F9A}\x{7F9D}\x{7F9E}\x{7FA3}' .
|
||||
'\x{7FA4}\x{7FA8}\x{7FA9}\x{7FAE}\x{7FAF}\x{7FB2}\x{7FB6}\x{7FB8}\x{7FB9}' .
|
||||
'\x{7FBD}\x{7FC1}\x{7FC5}\x{7FC6}\x{7FCA}\x{7FCC}\x{7FD2}\x{7FD4}\x{7FD5}' .
|
||||
'\x{7FE0}\x{7FE1}\x{7FE6}\x{7FE9}\x{7FEB}\x{7FF0}\x{7FF3}\x{7FF9}\x{7FFB}' .
|
||||
'\x{7FFC}\x{8000}\x{8001}\x{8003}\x{8004}\x{8005}\x{8006}\x{800B}\x{800C}' .
|
||||
'\x{8010}\x{8012}\x{8015}\x{8017}\x{8018}\x{8019}\x{801C}\x{8021}\x{8028}' .
|
||||
'\x{8033}\x{8036}\x{803B}\x{803D}\x{803F}\x{8046}\x{804A}\x{8052}\x{8056}' .
|
||||
'\x{8058}\x{805A}\x{805E}\x{805F}\x{8061}\x{8062}\x{8068}\x{806F}\x{8070}' .
|
||||
'\x{8072}\x{8073}\x{8074}\x{8076}\x{8077}\x{8079}\x{807D}\x{807E}\x{807F}' .
|
||||
'\x{8084}\x{8085}\x{8086}\x{8087}\x{8089}\x{808B}\x{808C}\x{8093}\x{8096}' .
|
||||
'\x{8098}\x{809A}\x{809B}\x{809D}\x{80A1}\x{80A2}\x{80A5}\x{80A9}\x{80AA}' .
|
||||
'\x{80AC}\x{80AD}\x{80AF}\x{80B1}\x{80B2}\x{80B4}\x{80BA}\x{80C3}\x{80C4}' .
|
||||
'\x{80C6}\x{80CC}\x{80CE}\x{80D6}\x{80D9}\x{80DA}\x{80DB}\x{80DD}\x{80DE}' .
|
||||
'\x{80E1}\x{80E4}\x{80E5}\x{80EF}\x{80F1}\x{80F4}\x{80F8}\x{80FC}\x{80FD}' .
|
||||
'\x{8102}\x{8105}\x{8106}\x{8107}\x{8108}\x{8109}\x{810A}\x{811A}\x{811B}' .
|
||||
'\x{8123}\x{8129}\x{812F}\x{8131}\x{8133}\x{8139}\x{813E}\x{8146}\x{814B}' .
|
||||
'\x{814E}\x{8150}\x{8151}\x{8153}\x{8154}\x{8155}\x{815F}\x{8165}\x{8166}' .
|
||||
'\x{816B}\x{816E}\x{8170}\x{8171}\x{8174}\x{8178}\x{8179}\x{817A}\x{817F}' .
|
||||
'\x{8180}\x{8182}\x{8183}\x{8188}\x{818A}\x{818F}\x{8193}\x{8195}\x{819A}' .
|
||||
'\x{819C}\x{819D}\x{81A0}\x{81A3}\x{81A4}\x{81A8}\x{81A9}\x{81B0}\x{81B3}' .
|
||||
'\x{81B5}\x{81B8}\x{81BA}\x{81BD}\x{81BE}\x{81BF}\x{81C0}\x{81C2}\x{81C6}' .
|
||||
'\x{81C8}\x{81C9}\x{81CD}\x{81D1}\x{81D3}\x{81D8}\x{81D9}\x{81DA}\x{81DF}' .
|
||||
'\x{81E0}\x{81E3}\x{81E5}\x{81E7}\x{81E8}\x{81EA}\x{81ED}\x{81F3}\x{81F4}' .
|
||||
'\x{81FA}\x{81FB}\x{81FC}\x{81FE}\x{8201}\x{8202}\x{8205}\x{8207}\x{8208}' .
|
||||
'\x{8209}\x{820A}\x{820C}\x{820D}\x{820E}\x{8210}\x{8212}\x{8216}\x{8217}' .
|
||||
'\x{8218}\x{821B}\x{821C}\x{821E}\x{821F}\x{8229}\x{822A}\x{822B}\x{822C}' .
|
||||
'\x{822E}\x{8233}\x{8235}\x{8236}\x{8237}\x{8238}\x{8239}\x{8240}\x{8247}' .
|
||||
'\x{8258}\x{8259}\x{825A}\x{825D}\x{825F}\x{8262}\x{8264}\x{8266}\x{8268}' .
|
||||
'\x{826A}\x{826B}\x{826E}\x{826F}\x{8271}\x{8272}\x{8276}\x{8277}\x{8278}' .
|
||||
'\x{827E}\x{828B}\x{828D}\x{8292}\x{8299}\x{829D}\x{829F}\x{82A5}\x{82A6}' .
|
||||
'\x{82AB}\x{82AC}\x{82AD}\x{82AF}\x{82B1}\x{82B3}\x{82B8}\x{82B9}\x{82BB}' .
|
||||
'\x{82BD}\x{82C5}\x{82D1}\x{82D2}\x{82D3}\x{82D4}\x{82D7}\x{82D9}\x{82DB}' .
|
||||
'\x{82DC}\x{82DE}\x{82DF}\x{82E1}\x{82E3}\x{82E5}\x{82E6}\x{82E7}\x{82EB}' .
|
||||
'\x{82F1}\x{82F3}\x{82F4}\x{82F9}\x{82FA}\x{82FB}\x{8302}\x{8303}\x{8304}' .
|
||||
'\x{8305}\x{8306}\x{8309}\x{830E}\x{8316}\x{8317}\x{8318}\x{831C}\x{8323}' .
|
||||
'\x{8328}\x{832B}\x{832F}\x{8331}\x{8332}\x{8334}\x{8335}\x{8336}\x{8338}' .
|
||||
'\x{8339}\x{8340}\x{8345}\x{8349}\x{834A}\x{834F}\x{8350}\x{8352}\x{8358}' .
|
||||
'\x{8373}\x{8375}\x{8377}\x{837B}\x{837C}\x{8385}\x{8387}\x{8389}\x{838A}' .
|
||||
'\x{838E}\x{8393}\x{8396}\x{839A}\x{839E}\x{839F}\x{83A0}\x{83A2}\x{83A8}' .
|
||||
'\x{83AA}\x{83AB}\x{83B1}\x{83B5}\x{83BD}\x{83C1}\x{83C5}\x{83CA}\x{83CC}' .
|
||||
'\x{83CE}\x{83D3}\x{83D6}\x{83D8}\x{83DC}\x{83DF}\x{83E0}\x{83E9}\x{83EB}' .
|
||||
'\x{83EF}\x{83F0}\x{83F1}\x{83F2}\x{83F4}\x{83F7}\x{83FB}\x{83FD}\x{8403}' .
|
||||
'\x{8404}\x{8407}\x{840B}\x{840C}\x{840D}\x{840E}\x{8413}\x{8420}\x{8422}' .
|
||||
'\x{8429}\x{842A}\x{842C}\x{8431}\x{8435}\x{8438}\x{843C}\x{843D}\x{8446}' .
|
||||
'\x{8449}\x{844E}\x{8457}\x{845B}\x{8461}\x{8462}\x{8463}\x{8466}\x{8469}' .
|
||||
'\x{846B}\x{846C}\x{846D}\x{846E}\x{846F}\x{8471}\x{8475}\x{8477}\x{8479}' .
|
||||
'\x{847A}\x{8482}\x{8484}\x{848B}\x{8490}\x{8494}\x{8499}\x{849C}\x{849F}' .
|
||||
'\x{84A1}\x{84AD}\x{84B2}\x{84B8}\x{84B9}\x{84BB}\x{84BC}\x{84BF}\x{84C1}' .
|
||||
'\x{84C4}\x{84C6}\x{84C9}\x{84CA}\x{84CB}\x{84CD}\x{84D0}\x{84D1}\x{84D6}' .
|
||||
'\x{84D9}\x{84DA}\x{84EC}\x{84EE}\x{84F4}\x{84FC}\x{84FF}\x{8500}\x{8506}' .
|
||||
'\x{8511}\x{8513}\x{8514}\x{8515}\x{8517}\x{8518}\x{851A}\x{851F}\x{8521}' .
|
||||
'\x{8526}\x{852C}\x{852D}\x{8535}\x{853D}\x{8540}\x{8541}\x{8543}\x{8548}' .
|
||||
'\x{8549}\x{854A}\x{854B}\x{854E}\x{8555}\x{8557}\x{8558}\x{855A}\x{8563}' .
|
||||
'\x{8568}\x{8569}\x{856A}\x{856D}\x{8577}\x{857E}\x{8580}\x{8584}\x{8587}' .
|
||||
'\x{8588}\x{858A}\x{8590}\x{8591}\x{8594}\x{8597}\x{8599}\x{859B}\x{859C}' .
|
||||
'\x{85A4}\x{85A6}\x{85A8}\x{85A9}\x{85AA}\x{85AB}\x{85AC}\x{85AE}\x{85AF}' .
|
||||
'\x{85B9}\x{85BA}\x{85C1}\x{85C9}\x{85CD}\x{85CF}\x{85D0}\x{85D5}\x{85DC}' .
|
||||
'\x{85DD}\x{85E4}\x{85E5}\x{85E9}\x{85EA}\x{85F7}\x{85F9}\x{85FA}\x{85FB}' .
|
||||
'\x{85FE}\x{8602}\x{8606}\x{8607}\x{860A}\x{860B}\x{8613}\x{8616}\x{8617}' .
|
||||
'\x{861A}\x{8622}\x{862D}\x{862F}\x{8630}\x{863F}\x{864D}\x{864E}\x{8650}' .
|
||||
'\x{8654}\x{8655}\x{865A}\x{865C}\x{865E}\x{865F}\x{8667}\x{866B}\x{8671}' .
|
||||
'\x{8679}\x{867B}\x{868A}\x{868B}\x{868C}\x{8693}\x{8695}\x{86A3}\x{86A4}' .
|
||||
'\x{86A9}\x{86AA}\x{86AB}\x{86AF}\x{86B0}\x{86B6}\x{86C4}\x{86C6}\x{86C7}' .
|
||||
'\x{86C9}\x{86CB}\x{86CD}\x{86CE}\x{86D4}\x{86D9}\x{86DB}\x{86DE}\x{86DF}' .
|
||||
'\x{86E4}\x{86E9}\x{86EC}\x{86ED}\x{86EE}\x{86EF}\x{86F8}\x{86F9}\x{86FB}' .
|
||||
'\x{86FE}\x{8700}\x{8702}\x{8703}\x{8706}\x{8708}\x{8709}\x{870A}\x{870D}' .
|
||||
'\x{8711}\x{8712}\x{8718}\x{871A}\x{871C}\x{8725}\x{8729}\x{8734}\x{8737}' .
|
||||
'\x{873B}\x{873F}\x{8749}\x{874B}\x{874C}\x{874E}\x{8753}\x{8755}\x{8757}' .
|
||||
'\x{8759}\x{875F}\x{8760}\x{8763}\x{8766}\x{8768}\x{876A}\x{876E}\x{8774}' .
|
||||
'\x{8776}\x{8778}\x{877F}\x{8782}\x{878D}\x{879F}\x{87A2}\x{87AB}\x{87AF}' .
|
||||
'\x{87B3}\x{87BA}\x{87BB}\x{87BD}\x{87C0}\x{87C4}\x{87C6}\x{87C7}\x{87CB}' .
|
||||
'\x{87D0}\x{87D2}\x{87E0}\x{87EF}\x{87F2}\x{87F6}\x{87F7}\x{87F9}\x{87FB}' .
|
||||
'\x{87FE}\x{8805}\x{880D}\x{880E}\x{880F}\x{8811}\x{8815}\x{8816}\x{8821}' .
|
||||
'\x{8822}\x{8823}\x{8827}\x{8831}\x{8836}\x{8839}\x{883B}\x{8840}\x{8842}' .
|
||||
'\x{8844}\x{8846}\x{884C}\x{884D}\x{8852}\x{8853}\x{8857}\x{8859}\x{885B}' .
|
||||
'\x{885D}\x{885E}\x{8861}\x{8862}\x{8863}\x{8868}\x{886B}\x{8870}\x{8872}' .
|
||||
'\x{8875}\x{8877}\x{887D}\x{887E}\x{887F}\x{8881}\x{8882}\x{8888}\x{888B}' .
|
||||
'\x{888D}\x{8892}\x{8896}\x{8897}\x{8899}\x{889E}\x{88A2}\x{88A4}\x{88AB}' .
|
||||
'\x{88AE}\x{88B0}\x{88B1}\x{88B4}\x{88B5}\x{88B7}\x{88BF}\x{88C1}\x{88C2}' .
|
||||
'\x{88C3}\x{88C4}\x{88C5}\x{88CF}\x{88D4}\x{88D5}\x{88D8}\x{88D9}\x{88DC}' .
|
||||
'\x{88DD}\x{88DF}\x{88E1}\x{88E8}\x{88F2}\x{88F3}\x{88F4}\x{88F8}\x{88F9}' .
|
||||
'\x{88FC}\x{88FD}\x{88FE}\x{8902}\x{8904}\x{8907}\x{890A}\x{890C}\x{8910}' .
|
||||
'\x{8912}\x{8913}\x{891D}\x{891E}\x{8925}\x{892A}\x{892B}\x{8936}\x{8938}' .
|
||||
'\x{893B}\x{8941}\x{8943}\x{8944}\x{894C}\x{894D}\x{8956}\x{895E}\x{895F}' .
|
||||
'\x{8960}\x{8964}\x{8966}\x{896A}\x{896D}\x{896F}\x{8972}\x{8974}\x{8977}' .
|
||||
'\x{897E}\x{897F}\x{8981}\x{8983}\x{8986}\x{8987}\x{8988}\x{898A}\x{898B}' .
|
||||
'\x{898F}\x{8993}\x{8996}\x{8997}\x{8998}\x{899A}\x{89A1}\x{89A6}\x{89A7}' .
|
||||
'\x{89A9}\x{89AA}\x{89AC}\x{89AF}\x{89B2}\x{89B3}\x{89BA}\x{89BD}\x{89BF}' .
|
||||
'\x{89C0}\x{89D2}\x{89DA}\x{89DC}\x{89DD}\x{89E3}\x{89E6}\x{89E7}\x{89F4}' .
|
||||
'\x{89F8}\x{8A00}\x{8A02}\x{8A03}\x{8A08}\x{8A0A}\x{8A0C}\x{8A0E}\x{8A10}' .
|
||||
'\x{8A13}\x{8A16}\x{8A17}\x{8A18}\x{8A1B}\x{8A1D}\x{8A1F}\x{8A23}\x{8A25}' .
|
||||
'\x{8A2A}\x{8A2D}\x{8A31}\x{8A33}\x{8A34}\x{8A36}\x{8A3A}\x{8A3B}\x{8A3C}' .
|
||||
'\x{8A41}\x{8A46}\x{8A48}\x{8A50}\x{8A51}\x{8A52}\x{8A54}\x{8A55}\x{8A5B}' .
|
||||
'\x{8A5E}\x{8A60}\x{8A62}\x{8A63}\x{8A66}\x{8A69}\x{8A6B}\x{8A6C}\x{8A6D}' .
|
||||
'\x{8A6E}\x{8A70}\x{8A71}\x{8A72}\x{8A73}\x{8A7C}\x{8A82}\x{8A84}\x{8A85}' .
|
||||
'\x{8A87}\x{8A89}\x{8A8C}\x{8A8D}\x{8A91}\x{8A93}\x{8A95}\x{8A98}\x{8A9A}' .
|
||||
'\x{8A9E}\x{8AA0}\x{8AA1}\x{8AA3}\x{8AA4}\x{8AA5}\x{8AA6}\x{8AA8}\x{8AAC}' .
|
||||
'\x{8AAD}\x{8AB0}\x{8AB2}\x{8AB9}\x{8ABC}\x{8ABF}\x{8AC2}\x{8AC4}\x{8AC7}' .
|
||||
'\x{8ACB}\x{8ACC}\x{8ACD}\x{8ACF}\x{8AD2}\x{8AD6}\x{8ADA}\x{8ADB}\x{8ADC}' .
|
||||
'\x{8ADE}\x{8AE0}\x{8AE1}\x{8AE2}\x{8AE4}\x{8AE6}\x{8AE7}\x{8AEB}\x{8AED}' .
|
||||
'\x{8AEE}\x{8AF1}\x{8AF3}\x{8AF7}\x{8AF8}\x{8AFA}\x{8AFE}\x{8B00}\x{8B01}' .
|
||||
'\x{8B02}\x{8B04}\x{8B07}\x{8B0C}\x{8B0E}\x{8B10}\x{8B14}\x{8B16}\x{8B17}' .
|
||||
'\x{8B19}\x{8B1A}\x{8B1B}\x{8B1D}\x{8B20}\x{8B21}\x{8B26}\x{8B28}\x{8B2B}' .
|
||||
'\x{8B2C}\x{8B33}\x{8B39}\x{8B3E}\x{8B41}\x{8B49}\x{8B4C}\x{8B4E}\x{8B4F}' .
|
||||
'\x{8B56}\x{8B58}\x{8B5A}\x{8B5B}\x{8B5C}\x{8B5F}\x{8B66}\x{8B6B}\x{8B6C}' .
|
||||
'\x{8B6F}\x{8B70}\x{8B71}\x{8B72}\x{8B74}\x{8B77}\x{8B7D}\x{8B80}\x{8B83}' .
|
||||
'\x{8B8A}\x{8B8C}\x{8B8E}\x{8B90}\x{8B92}\x{8B93}\x{8B96}\x{8B99}\x{8B9A}' .
|
||||
'\x{8C37}\x{8C3A}\x{8C3F}\x{8C41}\x{8C46}\x{8C48}\x{8C4A}\x{8C4C}\x{8C4E}' .
|
||||
'\x{8C50}\x{8C55}\x{8C5A}\x{8C61}\x{8C62}\x{8C6A}\x{8C6B}\x{8C6C}\x{8C78}' .
|
||||
'\x{8C79}\x{8C7A}\x{8C7C}\x{8C82}\x{8C85}\x{8C89}\x{8C8A}\x{8C8C}\x{8C8D}' .
|
||||
'\x{8C8E}\x{8C94}\x{8C98}\x{8C9D}\x{8C9E}\x{8CA0}\x{8CA1}\x{8CA2}\x{8CA7}' .
|
||||
'\x{8CA8}\x{8CA9}\x{8CAA}\x{8CAB}\x{8CAC}\x{8CAD}\x{8CAE}\x{8CAF}\x{8CB0}' .
|
||||
'\x{8CB2}\x{8CB3}\x{8CB4}\x{8CB6}\x{8CB7}\x{8CB8}\x{8CBB}\x{8CBC}\x{8CBD}' .
|
||||
'\x{8CBF}\x{8CC0}\x{8CC1}\x{8CC2}\x{8CC3}\x{8CC4}\x{8CC7}\x{8CC8}\x{8CCA}' .
|
||||
'\x{8CCD}\x{8CCE}\x{8CD1}\x{8CD3}\x{8CDA}\x{8CDB}\x{8CDC}\x{8CDE}\x{8CE0}' .
|
||||
'\x{8CE2}\x{8CE3}\x{8CE4}\x{8CE6}\x{8CEA}\x{8CED}\x{8CFA}\x{8CFB}\x{8CFC}' .
|
||||
'\x{8CFD}\x{8D04}\x{8D05}\x{8D07}\x{8D08}\x{8D0A}\x{8D0B}\x{8D0D}\x{8D0F}' .
|
||||
'\x{8D10}\x{8D13}\x{8D14}\x{8D16}\x{8D64}\x{8D66}\x{8D67}\x{8D6B}\x{8D6D}' .
|
||||
'\x{8D70}\x{8D71}\x{8D73}\x{8D74}\x{8D77}\x{8D81}\x{8D85}\x{8D8A}\x{8D99}' .
|
||||
'\x{8DA3}\x{8DA8}\x{8DB3}\x{8DBA}\x{8DBE}\x{8DC2}\x{8DCB}\x{8DCC}\x{8DCF}' .
|
||||
'\x{8DD6}\x{8DDA}\x{8DDB}\x{8DDD}\x{8DDF}\x{8DE1}\x{8DE3}\x{8DE8}\x{8DEA}' .
|
||||
'\x{8DEB}\x{8DEF}\x{8DF3}\x{8DF5}\x{8DFC}\x{8DFF}\x{8E08}\x{8E09}\x{8E0A}' .
|
||||
'\x{8E0F}\x{8E10}\x{8E1D}\x{8E1E}\x{8E1F}\x{8E2A}\x{8E30}\x{8E34}\x{8E35}' .
|
||||
'\x{8E42}\x{8E44}\x{8E47}\x{8E48}\x{8E49}\x{8E4A}\x{8E4C}\x{8E50}\x{8E55}' .
|
||||
'\x{8E59}\x{8E5F}\x{8E60}\x{8E63}\x{8E64}\x{8E72}\x{8E74}\x{8E76}\x{8E7C}' .
|
||||
'\x{8E81}\x{8E84}\x{8E85}\x{8E87}\x{8E8A}\x{8E8B}\x{8E8D}\x{8E91}\x{8E93}' .
|
||||
'\x{8E94}\x{8E99}\x{8EA1}\x{8EAA}\x{8EAB}\x{8EAC}\x{8EAF}\x{8EB0}\x{8EB1}' .
|
||||
'\x{8EBE}\x{8EC5}\x{8EC6}\x{8EC8}\x{8ECA}\x{8ECB}\x{8ECC}\x{8ECD}\x{8ED2}' .
|
||||
'\x{8EDB}\x{8EDF}\x{8EE2}\x{8EE3}\x{8EEB}\x{8EF8}\x{8EFB}\x{8EFC}\x{8EFD}' .
|
||||
'\x{8EFE}\x{8F03}\x{8F05}\x{8F09}\x{8F0A}\x{8F0C}\x{8F12}\x{8F13}\x{8F14}' .
|
||||
'\x{8F15}\x{8F19}\x{8F1B}\x{8F1C}\x{8F1D}\x{8F1F}\x{8F26}\x{8F29}\x{8F2A}' .
|
||||
'\x{8F2F}\x{8F33}\x{8F38}\x{8F39}\x{8F3B}\x{8F3E}\x{8F3F}\x{8F42}\x{8F44}' .
|
||||
'\x{8F45}\x{8F46}\x{8F49}\x{8F4C}\x{8F4D}\x{8F4E}\x{8F57}\x{8F5C}\x{8F5F}' .
|
||||
'\x{8F61}\x{8F62}\x{8F63}\x{8F64}\x{8F9B}\x{8F9C}\x{8F9E}\x{8F9F}\x{8FA3}' .
|
||||
'\x{8FA7}\x{8FA8}\x{8FAD}\x{8FAE}\x{8FAF}\x{8FB0}\x{8FB1}\x{8FB2}\x{8FB7}' .
|
||||
'\x{8FBA}\x{8FBB}\x{8FBC}\x{8FBF}\x{8FC2}\x{8FC4}\x{8FC5}\x{8FCE}\x{8FD1}' .
|
||||
'\x{8FD4}\x{8FDA}\x{8FE2}\x{8FE5}\x{8FE6}\x{8FE9}\x{8FEA}\x{8FEB}\x{8FED}' .
|
||||
'\x{8FEF}\x{8FF0}\x{8FF4}\x{8FF7}\x{8FF8}\x{8FF9}\x{8FFA}\x{8FFD}\x{9000}' .
|
||||
'\x{9001}\x{9003}\x{9005}\x{9006}\x{900B}\x{900D}\x{900E}\x{900F}\x{9010}' .
|
||||
'\x{9011}\x{9013}\x{9014}\x{9015}\x{9016}\x{9017}\x{9019}\x{901A}\x{901D}' .
|
||||
'\x{901E}\x{901F}\x{9020}\x{9021}\x{9022}\x{9023}\x{9027}\x{902E}\x{9031}' .
|
||||
'\x{9032}\x{9035}\x{9036}\x{9038}\x{9039}\x{903C}\x{903E}\x{9041}\x{9042}' .
|
||||
'\x{9045}\x{9047}\x{9049}\x{904A}\x{904B}\x{904D}\x{904E}\x{904F}\x{9050}' .
|
||||
'\x{9051}\x{9052}\x{9053}\x{9054}\x{9055}\x{9056}\x{9058}\x{9059}\x{905C}' .
|
||||
'\x{905E}\x{9060}\x{9061}\x{9063}\x{9065}\x{9068}\x{9069}\x{906D}\x{906E}' .
|
||||
'\x{906F}\x{9072}\x{9075}\x{9076}\x{9077}\x{9078}\x{907A}\x{907C}\x{907D}' .
|
||||
'\x{907F}\x{9080}\x{9081}\x{9082}\x{9083}\x{9084}\x{9087}\x{9089}\x{908A}' .
|
||||
'\x{908F}\x{9091}\x{90A3}\x{90A6}\x{90A8}\x{90AA}\x{90AF}\x{90B1}\x{90B5}' .
|
||||
'\x{90B8}\x{90C1}\x{90CA}\x{90CE}\x{90DB}\x{90E1}\x{90E2}\x{90E4}\x{90E8}' .
|
||||
'\x{90ED}\x{90F5}\x{90F7}\x{90FD}\x{9102}\x{9112}\x{9119}\x{912D}\x{9130}' .
|
||||
'\x{9132}\x{9149}\x{914A}\x{914B}\x{914C}\x{914D}\x{914E}\x{9152}\x{9154}' .
|
||||
'\x{9156}\x{9158}\x{9162}\x{9163}\x{9165}\x{9169}\x{916A}\x{916C}\x{9172}' .
|
||||
'\x{9173}\x{9175}\x{9177}\x{9178}\x{9182}\x{9187}\x{9189}\x{918B}\x{918D}' .
|
||||
'\x{9190}\x{9192}\x{9197}\x{919C}\x{91A2}\x{91A4}\x{91AA}\x{91AB}\x{91AF}' .
|
||||
'\x{91B4}\x{91B5}\x{91B8}\x{91BA}\x{91C0}\x{91C1}\x{91C6}\x{91C7}\x{91C8}' .
|
||||
'\x{91C9}\x{91CB}\x{91CC}\x{91CD}\x{91CE}\x{91CF}\x{91D0}\x{91D1}\x{91D6}' .
|
||||
'\x{91D8}\x{91DB}\x{91DC}\x{91DD}\x{91DF}\x{91E1}\x{91E3}\x{91E6}\x{91E7}' .
|
||||
'\x{91F5}\x{91F6}\x{91FC}\x{91FF}\x{920D}\x{920E}\x{9211}\x{9214}\x{9215}' .
|
||||
'\x{921E}\x{9229}\x{922C}\x{9234}\x{9237}\x{923F}\x{9244}\x{9245}\x{9248}' .
|
||||
'\x{9249}\x{924B}\x{9250}\x{9257}\x{925A}\x{925B}\x{925E}\x{9262}\x{9264}' .
|
||||
'\x{9266}\x{9271}\x{927E}\x{9280}\x{9283}\x{9285}\x{9291}\x{9293}\x{9295}' .
|
||||
'\x{9296}\x{9298}\x{929A}\x{929B}\x{929C}\x{92AD}\x{92B7}\x{92B9}\x{92CF}' .
|
||||
'\x{92D2}\x{92E4}\x{92E9}\x{92EA}\x{92ED}\x{92F2}\x{92F3}\x{92F8}\x{92FA}' .
|
||||
'\x{92FC}\x{9306}\x{930F}\x{9310}\x{9318}\x{9319}\x{931A}\x{9320}\x{9322}' .
|
||||
'\x{9323}\x{9326}\x{9328}\x{932B}\x{932C}\x{932E}\x{932F}\x{9332}\x{9335}' .
|
||||
'\x{933A}\x{933B}\x{9344}\x{934B}\x{934D}\x{9354}\x{9356}\x{935B}\x{935C}' .
|
||||
'\x{9360}\x{936C}\x{936E}\x{9375}\x{937C}\x{937E}\x{938C}\x{9394}\x{9396}' .
|
||||
'\x{9397}\x{939A}\x{93A7}\x{93AC}\x{93AD}\x{93AE}\x{93B0}\x{93B9}\x{93C3}' .
|
||||
'\x{93C8}\x{93D0}\x{93D1}\x{93D6}\x{93D7}\x{93D8}\x{93DD}\x{93E1}\x{93E4}' .
|
||||
'\x{93E5}\x{93E8}\x{9403}\x{9407}\x{9410}\x{9413}\x{9414}\x{9418}\x{9419}' .
|
||||
'\x{941A}\x{9421}\x{942B}\x{9435}\x{9436}\x{9438}\x{943A}\x{9441}\x{9444}' .
|
||||
'\x{9451}\x{9452}\x{9453}\x{945A}\x{945B}\x{945E}\x{9460}\x{9462}\x{946A}' .
|
||||
'\x{9470}\x{9475}\x{9477}\x{947C}\x{947D}\x{947E}\x{947F}\x{9481}\x{9577}' .
|
||||
'\x{9580}\x{9582}\x{9583}\x{9587}\x{9589}\x{958A}\x{958B}\x{958F}\x{9591}' .
|
||||
'\x{9593}\x{9594}\x{9596}\x{9598}\x{9599}\x{95A0}\x{95A2}\x{95A3}\x{95A4}' .
|
||||
'\x{95A5}\x{95A7}\x{95A8}\x{95AD}\x{95B2}\x{95B9}\x{95BB}\x{95BC}\x{95BE}' .
|
||||
'\x{95C3}\x{95C7}\x{95CA}\x{95CC}\x{95CD}\x{95D4}\x{95D5}\x{95D6}\x{95D8}' .
|
||||
'\x{95DC}\x{95E1}\x{95E2}\x{95E5}\x{961C}\x{9621}\x{9628}\x{962A}\x{962E}' .
|
||||
'\x{962F}\x{9632}\x{963B}\x{963F}\x{9640}\x{9642}\x{9644}\x{964B}\x{964C}' .
|
||||
'\x{964D}\x{964F}\x{9650}\x{965B}\x{965C}\x{965D}\x{965E}\x{965F}\x{9662}' .
|
||||
'\x{9663}\x{9664}\x{9665}\x{9666}\x{966A}\x{966C}\x{9670}\x{9672}\x{9673}' .
|
||||
'\x{9675}\x{9676}\x{9677}\x{9678}\x{967A}\x{967D}\x{9685}\x{9686}\x{9688}' .
|
||||
'\x{968A}\x{968B}\x{968D}\x{968E}\x{968F}\x{9694}\x{9695}\x{9697}\x{9698}' .
|
||||
'\x{9699}\x{969B}\x{969C}\x{96A0}\x{96A3}\x{96A7}\x{96A8}\x{96AA}\x{96B0}' .
|
||||
'\x{96B1}\x{96B2}\x{96B4}\x{96B6}\x{96B7}\x{96B8}\x{96B9}\x{96BB}\x{96BC}' .
|
||||
'\x{96C0}\x{96C1}\x{96C4}\x{96C5}\x{96C6}\x{96C7}\x{96C9}\x{96CB}\x{96CC}' .
|
||||
'\x{96CD}\x{96CE}\x{96D1}\x{96D5}\x{96D6}\x{96D9}\x{96DB}\x{96DC}\x{96E2}' .
|
||||
'\x{96E3}\x{96E8}\x{96EA}\x{96EB}\x{96F0}\x{96F2}\x{96F6}\x{96F7}\x{96F9}' .
|
||||
'\x{96FB}\x{9700}\x{9704}\x{9706}\x{9707}\x{9708}\x{970A}\x{970D}\x{970E}' .
|
||||
'\x{970F}\x{9711}\x{9713}\x{9716}\x{9719}\x{971C}\x{971E}\x{9724}\x{9727}' .
|
||||
'\x{972A}\x{9730}\x{9732}\x{9738}\x{9739}\x{973D}\x{973E}\x{9742}\x{9744}' .
|
||||
'\x{9746}\x{9748}\x{9749}\x{9752}\x{9756}\x{9759}\x{975C}\x{975E}\x{9760}' .
|
||||
'\x{9761}\x{9762}\x{9764}\x{9766}\x{9768}\x{9769}\x{976B}\x{976D}\x{9771}' .
|
||||
'\x{9774}\x{9779}\x{977A}\x{977C}\x{9781}\x{9784}\x{9785}\x{9786}\x{978B}' .
|
||||
'\x{978D}\x{978F}\x{9790}\x{9798}\x{979C}\x{97A0}\x{97A3}\x{97A6}\x{97A8}' .
|
||||
'\x{97AB}\x{97AD}\x{97B3}\x{97B4}\x{97C3}\x{97C6}\x{97C8}\x{97CB}\x{97D3}' .
|
||||
'\x{97DC}\x{97ED}\x{97EE}\x{97F2}\x{97F3}\x{97F5}\x{97F6}\x{97FB}\x{97FF}' .
|
||||
'\x{9801}\x{9802}\x{9803}\x{9805}\x{9806}\x{9808}\x{980C}\x{980F}\x{9810}' .
|
||||
'\x{9811}\x{9812}\x{9813}\x{9817}\x{9818}\x{981A}\x{9821}\x{9824}\x{982C}' .
|
||||
'\x{982D}\x{9834}\x{9837}\x{9838}\x{983B}\x{983C}\x{983D}\x{9846}\x{984B}' .
|
||||
'\x{984C}\x{984D}\x{984E}\x{984F}\x{9854}\x{9855}\x{9858}\x{985B}\x{985E}' .
|
||||
'\x{9867}\x{986B}\x{986F}\x{9870}\x{9871}\x{9873}\x{9874}\x{98A8}\x{98AA}' .
|
||||
'\x{98AF}\x{98B1}\x{98B6}\x{98C3}\x{98C4}\x{98C6}\x{98DB}\x{98DC}\x{98DF}' .
|
||||
'\x{98E2}\x{98E9}\x{98EB}\x{98ED}\x{98EE}\x{98EF}\x{98F2}\x{98F4}\x{98FC}' .
|
||||
'\x{98FD}\x{98FE}\x{9903}\x{9905}\x{9909}\x{990A}\x{990C}\x{9910}\x{9912}' .
|
||||
'\x{9913}\x{9914}\x{9918}\x{991D}\x{991E}\x{9920}\x{9921}\x{9924}\x{9928}' .
|
||||
'\x{992C}\x{992E}\x{993D}\x{993E}\x{9942}\x{9945}\x{9949}\x{994B}\x{994C}' .
|
||||
'\x{9950}\x{9951}\x{9952}\x{9955}\x{9957}\x{9996}\x{9997}\x{9998}\x{9999}' .
|
||||
'\x{99A5}\x{99A8}\x{99AC}\x{99AD}\x{99AE}\x{99B3}\x{99B4}\x{99BC}\x{99C1}' .
|
||||
'\x{99C4}\x{99C5}\x{99C6}\x{99C8}\x{99D0}\x{99D1}\x{99D2}\x{99D5}\x{99D8}' .
|
||||
'\x{99DB}\x{99DD}\x{99DF}\x{99E2}\x{99ED}\x{99EE}\x{99F1}\x{99F2}\x{99F8}' .
|
||||
'\x{99FB}\x{99FF}\x{9A01}\x{9A05}\x{9A0E}\x{9A0F}\x{9A12}\x{9A13}\x{9A19}' .
|
||||
'\x{9A28}\x{9A2B}\x{9A30}\x{9A37}\x{9A3E}\x{9A40}\x{9A42}\x{9A43}\x{9A45}' .
|
||||
'\x{9A4D}\x{9A55}\x{9A57}\x{9A5A}\x{9A5B}\x{9A5F}\x{9A62}\x{9A64}\x{9A65}' .
|
||||
'\x{9A69}\x{9A6A}\x{9A6B}\x{9AA8}\x{9AAD}\x{9AB0}\x{9AB8}\x{9ABC}\x{9AC0}' .
|
||||
'\x{9AC4}\x{9ACF}\x{9AD1}\x{9AD3}\x{9AD4}\x{9AD8}\x{9ADE}\x{9ADF}\x{9AE2}' .
|
||||
'\x{9AE3}\x{9AE6}\x{9AEA}\x{9AEB}\x{9AED}\x{9AEE}\x{9AEF}\x{9AF1}\x{9AF4}' .
|
||||
'\x{9AF7}\x{9AFB}\x{9B06}\x{9B18}\x{9B1A}\x{9B1F}\x{9B22}\x{9B23}\x{9B25}' .
|
||||
'\x{9B27}\x{9B28}\x{9B29}\x{9B2A}\x{9B2E}\x{9B2F}\x{9B31}\x{9B32}\x{9B3B}' .
|
||||
'\x{9B3C}\x{9B41}\x{9B42}\x{9B43}\x{9B44}\x{9B45}\x{9B4D}\x{9B4E}\x{9B4F}' .
|
||||
'\x{9B51}\x{9B54}\x{9B58}\x{9B5A}\x{9B6F}\x{9B74}\x{9B83}\x{9B8E}\x{9B91}' .
|
||||
'\x{9B92}\x{9B93}\x{9B96}\x{9B97}\x{9B9F}\x{9BA0}\x{9BA8}\x{9BAA}\x{9BAB}' .
|
||||
'\x{9BAD}\x{9BAE}\x{9BB4}\x{9BB9}\x{9BC0}\x{9BC6}\x{9BC9}\x{9BCA}\x{9BCF}' .
|
||||
'\x{9BD1}\x{9BD2}\x{9BD4}\x{9BD6}\x{9BDB}\x{9BE1}\x{9BE2}\x{9BE3}\x{9BE4}' .
|
||||
'\x{9BE8}\x{9BF0}\x{9BF1}\x{9BF2}\x{9BF5}\x{9C04}\x{9C06}\x{9C08}\x{9C09}' .
|
||||
'\x{9C0A}\x{9C0C}\x{9C0D}\x{9C10}\x{9C12}\x{9C13}\x{9C14}\x{9C15}\x{9C1B}' .
|
||||
'\x{9C21}\x{9C24}\x{9C25}\x{9C2D}\x{9C2E}\x{9C2F}\x{9C30}\x{9C32}\x{9C39}' .
|
||||
'\x{9C3A}\x{9C3B}\x{9C3E}\x{9C46}\x{9C47}\x{9C48}\x{9C52}\x{9C57}\x{9C5A}' .
|
||||
'\x{9C60}\x{9C67}\x{9C76}\x{9C78}\x{9CE5}\x{9CE7}\x{9CE9}\x{9CEB}\x{9CEC}' .
|
||||
'\x{9CF0}\x{9CF3}\x{9CF4}\x{9CF6}\x{9D03}\x{9D06}\x{9D07}\x{9D08}\x{9D09}' .
|
||||
'\x{9D0E}\x{9D12}\x{9D15}\x{9D1B}\x{9D1F}\x{9D23}\x{9D26}\x{9D28}\x{9D2A}' .
|
||||
'\x{9D2B}\x{9D2C}\x{9D3B}\x{9D3E}\x{9D3F}\x{9D41}\x{9D44}\x{9D46}\x{9D48}' .
|
||||
'\x{9D50}\x{9D51}\x{9D59}\x{9D5C}\x{9D5D}\x{9D5E}\x{9D60}\x{9D61}\x{9D64}' .
|
||||
'\x{9D6C}\x{9D6F}\x{9D72}\x{9D7A}\x{9D87}\x{9D89}\x{9D8F}\x{9D9A}\x{9DA4}' .
|
||||
'\x{9DA9}\x{9DAB}\x{9DAF}\x{9DB2}\x{9DB4}\x{9DB8}\x{9DBA}\x{9DBB}\x{9DC1}' .
|
||||
'\x{9DC2}\x{9DC4}\x{9DC6}\x{9DCF}\x{9DD3}\x{9DD9}\x{9DE6}\x{9DED}\x{9DEF}' .
|
||||
'\x{9DF2}\x{9DF8}\x{9DF9}\x{9DFA}\x{9DFD}\x{9E1A}\x{9E1B}\x{9E1E}\x{9E75}' .
|
||||
'\x{9E78}\x{9E79}\x{9E7D}\x{9E7F}\x{9E81}\x{9E88}\x{9E8B}\x{9E8C}\x{9E91}' .
|
||||
'\x{9E92}\x{9E93}\x{9E95}\x{9E97}\x{9E9D}\x{9E9F}\x{9EA5}\x{9EA6}\x{9EA9}' .
|
||||
'\x{9EAA}\x{9EAD}\x{9EB8}\x{9EB9}\x{9EBA}\x{9EBB}\x{9EBC}\x{9EBE}\x{9EBF}' .
|
||||
'\x{9EC4}\x{9ECC}\x{9ECD}\x{9ECE}\x{9ECF}\x{9ED0}\x{9ED2}\x{9ED4}\x{9ED8}' .
|
||||
'\x{9ED9}\x{9EDB}\x{9EDC}\x{9EDD}\x{9EDE}\x{9EE0}\x{9EE5}\x{9EE8}\x{9EEF}' .
|
||||
'\x{9EF4}\x{9EF6}\x{9EF7}\x{9EF9}\x{9EFB}\x{9EFC}\x{9EFD}\x{9F07}\x{9F08}' .
|
||||
'\x{9F0E}\x{9F13}\x{9F15}\x{9F20}\x{9F21}\x{9F2C}\x{9F3B}\x{9F3E}\x{9F4A}' .
|
||||
'\x{9F4B}\x{9F4E}\x{9F4F}\x{9F52}\x{9F54}\x{9F5F}\x{9F60}\x{9F61}\x{9F62}' .
|
||||
'\x{9F63}\x{9F66}\x{9F67}\x{9F6A}\x{9F6C}\x{9F72}\x{9F76}\x{9F77}\x{9F8D}' .
|
||||
'\x{9F95}\x{9F9C}\x{9F9D}\x{9FA0}]{1,15}$/iu');
|
||||
@@ -0,0 +1,250 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Validate_Abstract
|
||||
*/
|
||||
require_once 'Zend/Validate/Abstract.php';
|
||||
|
||||
/**
|
||||
* Validates IBAN Numbers (International Bank Account Numbers)
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Validate_Iban extends Postman_Zend_Validate_Abstract
|
||||
{
|
||||
const NOTSUPPORTED = 'ibanNotSupported';
|
||||
const FALSEFORMAT = 'ibanFalseFormat';
|
||||
const CHECKFAILED = 'ibanCheckFailed';
|
||||
|
||||
/**
|
||||
* Validation failure message template definitions
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_messageTemplates = array(
|
||||
self::NOTSUPPORTED => "Unknown country within the IBAN '%value%'",
|
||||
self::FALSEFORMAT => "'%value%' has a false IBAN format",
|
||||
self::CHECKFAILED => "'%value%' has failed the IBAN check",
|
||||
);
|
||||
|
||||
/**
|
||||
* Optional locale
|
||||
*
|
||||
* @var string|Postman_Zend_Locale|null
|
||||
*/
|
||||
protected $_locale;
|
||||
|
||||
/**
|
||||
* IBAN regexes by region
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_ibanregex = array(
|
||||
'AD' => '/^AD[0-9]{2}[0-9]{8}[A-Z0-9]{12}$/',
|
||||
'AE' => '/^AE[0-9]{2}[0-9]{3}[0-9]{16}$/',
|
||||
'AL' => '/^AL[0-9]{2}[0-9]{8}[A-Z0-9]{16}$/',
|
||||
'AT' => '/^AT[0-9]{2}[0-9]{5}[0-9]{11}$/',
|
||||
'AZ' => '/^AZ[0-9]{2}[0-9]{4}[A-Z0-9]{20}$/',
|
||||
'BA' => '/^BA[0-9]{2}[0-9]{6}[0-9]{10}$/',
|
||||
'BE' => '/^BE[0-9]{2}[0-9]{3}[0-9]{9}$/',
|
||||
'BG' => '/^BG[0-9]{2}[A-Z]{4}[0-9]{4}[0-9]{2}[A-Z0-9]{8}$/',
|
||||
'BH' => '/^BH[0-9]{2}[A-Z]{4}[A-Z0-9]{14}$/',
|
||||
'BR' => '/^BR[0-9]{2}[0-9]{8}[0-9]{5}[0-9]{10}[A-Z]{1}[A-Z0-9]{1}$/',
|
||||
'CH' => '/^CH[0-9]{2}[0-9]{5}[A-Z0-9]{12}$/',
|
||||
'CR' => '/^CR[0-9]{2}[0-9]{3}[0-9]{14}$/',
|
||||
'CS' => '/^CS[0-9]{2}[0-9]{3}[0-9]{15}$/',
|
||||
'CY' => '/^CY[0-9]{2}[0-9]{8}[A-Z0-9]{16}$/',
|
||||
'CZ' => '/^CZ[0-9]{2}[0-9]{4}[0-9]{16}$/',
|
||||
'DE' => '/^DE[0-9]{2}[0-9]{8}[0-9]{10}$/',
|
||||
'DK' => '/^DK[0-9]{2}[0-9]{4}[0-9]{10}$/',
|
||||
'DO' => '/^DO[0-9]{2}[A-Z0-9]{4}[0-9]{20}$/',
|
||||
'EE' => '/^EE[0-9]{2}[0-9]{4}[0-9]{12}$/',
|
||||
'ES' => '/^ES[0-9]{2}[0-9]{8}[0-9]{12}$/',
|
||||
'FR' => '/^FR[0-9]{2}[0-9]{10}[A-Z0-9]{11}[0-9]{2}$/',
|
||||
'FI' => '/^FI[0-9]{2}[0-9]{6}[0-9]{8}$/',
|
||||
'FO' => '/^FO[0-9]{2}[0-9]{4}[0-9]{9}[0-9]{1}$/',
|
||||
'GB' => '/^GB[0-9]{2}[A-Z]{4}[0-9]{14}$/',
|
||||
'GE' => '/^GE[0-9]{2}[A-Z]{2}[0-9]{16}$/',
|
||||
'GI' => '/^GI[0-9]{2}[A-Z]{4}[A-Z0-9]{15}$/',
|
||||
'GL' => '/^GL[0-9]{2}[0-9]{4}[0-9]{9}[0-9]{1}$/',
|
||||
'GR' => '/^GR[0-9]{2}[0-9]{7}[A-Z0-9]{16}$/',
|
||||
'GT' => '/^GT[0-9]{2}[A-Z0-9]{4}[A-Z0-9]{20}$/',
|
||||
'HR' => '/^HR[0-9]{2}[0-9]{7}[0-9]{10}$/',
|
||||
'HU' => '/^HU[0-9]{2}[0-9]{7}[0-9]{1}[0-9]{15}[0-9]{1}$/',
|
||||
'IE' => '/^IE[0-9]{2}[A-Z0-9]{4}[0-9]{6}[0-9]{8}$/',
|
||||
'IL' => '/^IL[0-9]{2}[0-9]{3}[0-9]{3}[0-9]{13}$/',
|
||||
'IS' => '/^IS[0-9]{2}[0-9]{4}[0-9]{18}$/',
|
||||
'IT' => '/^IT[0-9]{2}[A-Z]{1}[0-9]{10}[A-Z0-9]{12}$/',
|
||||
'KW' => '/^KW[0-9]{2}[A-Z]{4}[0-9]{3}[0-9]{22}$/',
|
||||
'KZ' => '/^KZ[A-Z]{2}[0-9]{2}[0-9]{3}[A-Z0-9]{13}$/',
|
||||
'LB' => '/^LB[0-9]{2}[0-9]{4}[A-Z0-9]{20}$/',
|
||||
'LI' => '/^LI[0-9]{2}[0-9]{5}[A-Z0-9]{12}$/',
|
||||
'LU' => '/^LU[0-9]{2}[0-9]{3}[A-Z0-9]{13}$/',
|
||||
'LT' => '/^LT[0-9]{2}[0-9]{5}[0-9]{11}$/',
|
||||
'LV' => '/^LV[0-9]{2}[A-Z]{4}[A-Z0-9]{13}$/',
|
||||
'MC' => '/^MC[0-9]{2}[0-9]{5}[0-9]{5}[A-Z0-9]{11}[0-9]{2}$/',
|
||||
'MD' => '/^MD[0-9]{2}[A-Z0-9]{20}$/',
|
||||
'ME' => '/^ME[0-9]{2}[0-9]{3}[0-9]{13}[0-9]{2}$/',
|
||||
'MK' => '/^MK[0-9]{2}[A-Z]{3}[A-Z0-9]{10}[0-9]{2}$/',
|
||||
'MR' => '/^MR13[0-9]{5}[0-9]{5}[0-9]{11}[0-9]{2}$/',
|
||||
'MU' => '/^MU[0-9]{2}[A-Z]{4}[0-9]{2}[0-9]{2}[0-9]{12}[0-9]{3}[A-Z]{2}$/',
|
||||
'MT' => '/^MT[0-9]{2}[A-Z]{4}[0-9]{5}[A-Z0-9]{18}$/',
|
||||
'NL' => '/^NL[0-9]{2}[A-Z]{4}[0-9]{10}$/',
|
||||
'NO' => '/^NO[0-9]{2}[0-9]{4}[0-9]{7}$/',
|
||||
'PK' => '/^PK[0-9]{2}[A-Z]{4}[0-9]{16}$/',
|
||||
'PL' => '/^PL[0-9]{2}[0-9]{8}[0-9]{16}$/',
|
||||
'PS' => '/^PS[0-9]{2}[A-Z]{4}[0-9]{21}$/',
|
||||
'PT' => '/^PT[0-9]{2}[0-9]{8}[0-9]{13}$/',
|
||||
'RO' => '/^RO[0-9]{2}[A-Z]{4}[A-Z0-9]{16}$/',
|
||||
'RS' => '/^RS[0-9]{2}[0-9]{3}[0-9]{13}[0-9]{2}$/',
|
||||
'SA' => '/^SA[0-9]{2}[0-9]{2}[A-Z0-9]{18}$/',
|
||||
'SE' => '/^SE[0-9]{2}[0-9]{3}[0-9]{17}$/',
|
||||
'SI' => '/^SI[0-9]{2}[0-9]{5}[0-9]{8}[0-9]{2}$/',
|
||||
'SK' => '/^SK[0-9]{2}[0-9]{4}[0-9]{16}$/',
|
||||
'SM' => '/^SM[0-9]{2}[A-Z]{1}[0-9]{5}[0-9]{5}[A-Z0-9]{12}$/',
|
||||
'TN' => '/^TN[0-9]{2}[0-9]{5}[0-9]{15}$/',
|
||||
'TR' => '/^TR[0-9]{2}[0-9]{5}[A-Z0-9]{17}$/',
|
||||
'VG' => '/^VG[0-9]{2}[A-Z]{4}[0-9]{16}$/'
|
||||
);
|
||||
|
||||
/**
|
||||
* Sets validator options
|
||||
*
|
||||
* @param string|Postman_Zend_Config|Postman_Zend_Locale $locale OPTIONAL
|
||||
*/
|
||||
public function __construct($locale = null)
|
||||
{
|
||||
if ($locale instanceof Postman_Zend_Config) {
|
||||
$locale = $locale->toArray();
|
||||
}
|
||||
|
||||
if (is_array($locale)) {
|
||||
if (array_key_exists('locale', $locale)) {
|
||||
$locale = $locale['locale'];
|
||||
} else {
|
||||
$locale = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($locale)) {
|
||||
require_once 'Zend/Registry.php';
|
||||
if (Postman_Zend_Registry::isRegistered('Postman_Zend_Locale')) {
|
||||
$locale = Postman_Zend_Registry::get('Postman_Zend_Locale');
|
||||
}
|
||||
}
|
||||
|
||||
if ($locale !== null) {
|
||||
$this->setLocale($locale);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the locale option
|
||||
*
|
||||
* @return string|Postman_Zend_Locale|null
|
||||
*/
|
||||
public function getLocale()
|
||||
{
|
||||
return $this->_locale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the locale option
|
||||
*
|
||||
* @param string|Postman_Zend_Locale $locale
|
||||
* @throws Postman_Zend_Locale_Exception
|
||||
* @throws Postman_Zend_Validate_Exception
|
||||
* @return Postman_Zend_Validate_Date provides a fluent interface
|
||||
*/
|
||||
public function setLocale($locale = null)
|
||||
{
|
||||
if ($locale !== false) {
|
||||
require_once 'Zend/Locale.php';
|
||||
$locale = Postman_Zend_Locale::findLocale($locale);
|
||||
if (strlen($locale) < 4) {
|
||||
require_once 'Zend/Validate/Exception.php';
|
||||
throw new Postman_Zend_Validate_Exception('Region must be given for IBAN validation');
|
||||
}
|
||||
}
|
||||
|
||||
$this->_locale = $locale;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defined by Postman_Zend_Validate_Interface
|
||||
*
|
||||
* Returns true if $value is a valid IBAN
|
||||
*
|
||||
* @param string $value
|
||||
* @return boolean
|
||||
*/
|
||||
public function isValid($value)
|
||||
{
|
||||
$value = strtoupper($value);
|
||||
$this->_setValue($value);
|
||||
|
||||
if (empty($this->_locale)) {
|
||||
$region = substr($value, 0, 2);
|
||||
} else {
|
||||
$region = new Postman_Zend_Locale($this->_locale);
|
||||
$region = $region->getRegion();
|
||||
}
|
||||
|
||||
if (!array_key_exists($region, $this->_ibanregex)) {
|
||||
$this->_setValue($region);
|
||||
$this->_error(self::NOTSUPPORTED);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!preg_match($this->_ibanregex[$region], $value)) {
|
||||
$this->_error(self::FALSEFORMAT);
|
||||
return false;
|
||||
}
|
||||
|
||||
$format = substr($value, 4) . substr($value, 0, 4);
|
||||
$format = str_replace(
|
||||
array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
|
||||
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'),
|
||||
array('10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22',
|
||||
'23', '24', '25', '26', '27', '28', '29', '30', '31', '32', '33', '34', '35'),
|
||||
$format);
|
||||
|
||||
$temp = intval(substr($format, 0, 1));
|
||||
$len = strlen($format);
|
||||
for ($x = 1; $x < $len; ++$x) {
|
||||
$temp *= 10;
|
||||
$temp += intval(substr($format, $x, 1));
|
||||
$temp %= 97;
|
||||
}
|
||||
|
||||
if ($temp != 1) {
|
||||
$this->_error(self::CHECKFAILED);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/** @see Postman_Zend_Validate_Abstract */
|
||||
require_once 'Zend/Validate/Abstract.php';
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Validate_Identical extends Postman_Zend_Validate_Abstract
|
||||
{
|
||||
/**
|
||||
* Error codes
|
||||
* @const string
|
||||
*/
|
||||
const NOT_SAME = 'notSame';
|
||||
const MISSING_TOKEN = 'missingToken';
|
||||
|
||||
/**
|
||||
* Error messages
|
||||
* @var array
|
||||
*/
|
||||
protected $_messageTemplates = array(
|
||||
self::NOT_SAME => "The two given tokens do not match",
|
||||
self::MISSING_TOKEN => 'No token was provided to match against',
|
||||
);
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $_messageVariables = array(
|
||||
'token' => '_tokenString'
|
||||
);
|
||||
|
||||
/**
|
||||
* Original token against which to validate
|
||||
* @var string
|
||||
*/
|
||||
protected $_tokenString;
|
||||
protected $_token;
|
||||
protected $_strict = true;
|
||||
|
||||
/**
|
||||
* Sets validator options
|
||||
*
|
||||
* @param mixed $token
|
||||
*/
|
||||
public function __construct($token = null)
|
||||
{
|
||||
if ($token instanceof Postman_Zend_Config) {
|
||||
$token = $token->toArray();
|
||||
}
|
||||
|
||||
if (is_array($token) && array_key_exists('token', $token)) {
|
||||
if (array_key_exists('strict', $token)) {
|
||||
$this->setStrict($token['strict']);
|
||||
}
|
||||
|
||||
$this->setToken($token['token']);
|
||||
} else if (null !== $token) {
|
||||
$this->setToken($token);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve token
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getToken()
|
||||
{
|
||||
return $this->_token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set token against which to compare
|
||||
*
|
||||
* @param mixed $token
|
||||
* @return Postman_Zend_Validate_Identical
|
||||
*/
|
||||
public function setToken($token)
|
||||
{
|
||||
$this->_tokenString = $token;
|
||||
$this->_token = $token;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the strict parameter
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function getStrict()
|
||||
{
|
||||
return $this->_strict;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the strict parameter
|
||||
*
|
||||
* @param Postman_Zend_Validate_Identical
|
||||
* @return $this
|
||||
*/
|
||||
public function setStrict($strict)
|
||||
{
|
||||
$this->_strict = (boolean) $strict;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defined by Postman_Zend_Validate_Interface
|
||||
*
|
||||
* Returns true if and only if a token has been set and the provided value
|
||||
* matches that token.
|
||||
*
|
||||
* @param mixed $value
|
||||
* @param array $context
|
||||
* @return boolean
|
||||
*/
|
||||
public function isValid($value, $context = null)
|
||||
{
|
||||
$this->_setValue($value);
|
||||
|
||||
if (($context !== null) && isset($context) && array_key_exists($this->getToken(), $context)) {
|
||||
$token = $context[$this->getToken()];
|
||||
} else {
|
||||
$token = $this->getToken();
|
||||
}
|
||||
|
||||
if ($token === null) {
|
||||
$this->_error(self::MISSING_TOKEN);
|
||||
return false;
|
||||
}
|
||||
|
||||
$strict = $this->getStrict();
|
||||
if (($strict && ($value !== $token)) || (!$strict && ($value != $token))) {
|
||||
$this->_error(self::NOT_SAME);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,204 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Validate_Abstract
|
||||
*/
|
||||
require_once 'Zend/Validate/Abstract.php';
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Validate_InArray extends Postman_Zend_Validate_Abstract
|
||||
{
|
||||
const NOT_IN_ARRAY = 'notInArray';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $_messageTemplates = array(
|
||||
self::NOT_IN_ARRAY => "'%value%' was not found in the haystack",
|
||||
);
|
||||
|
||||
/**
|
||||
* Haystack of possible values
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_haystack;
|
||||
|
||||
/**
|
||||
* Whether a strict in_array() invocation is used
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
protected $_strict = false;
|
||||
|
||||
/**
|
||||
* Whether a recursive search should be done
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
protected $_recursive = false;
|
||||
|
||||
/**
|
||||
* Sets validator options
|
||||
*
|
||||
* @param array|Postman_Zend_Config $options Validator options
|
||||
* @throws Postman_Zend_Validate_Exception
|
||||
*/
|
||||
public function __construct($options)
|
||||
{
|
||||
if ($options instanceof Postman_Zend_Config) {
|
||||
$options = $options->toArray();
|
||||
} else if (!is_array($options)) {
|
||||
require_once 'Zend/Validate/Exception.php';
|
||||
throw new Postman_Zend_Validate_Exception('Array expected as parameter');
|
||||
} else {
|
||||
$count = func_num_args();
|
||||
$temp = array();
|
||||
if ($count > 1) {
|
||||
$temp['haystack'] = func_get_arg(0);
|
||||
$temp['strict'] = func_get_arg(1);
|
||||
$options = $temp;
|
||||
} else {
|
||||
$temp = func_get_arg(0);
|
||||
if (!array_key_exists('haystack', $options)) {
|
||||
$options = array();
|
||||
$options['haystack'] = $temp;
|
||||
} else {
|
||||
$options = $temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->setHaystack($options['haystack']);
|
||||
if (array_key_exists('strict', $options)) {
|
||||
$this->setStrict($options['strict']);
|
||||
}
|
||||
|
||||
if (array_key_exists('recursive', $options)) {
|
||||
$this->setRecursive($options['recursive']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the haystack option
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getHaystack()
|
||||
{
|
||||
return $this->_haystack;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the haystack option
|
||||
*
|
||||
* @param mixed $haystack
|
||||
* @return Postman_Zend_Validate_InArray Provides a fluent interface
|
||||
*/
|
||||
public function setHaystack(array $haystack)
|
||||
{
|
||||
$this->_haystack = $haystack;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the strict option
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function getStrict()
|
||||
{
|
||||
return $this->_strict;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the strict option
|
||||
*
|
||||
* @param boolean $strict
|
||||
* @return Postman_Zend_Validate_InArray Provides a fluent interface
|
||||
*/
|
||||
public function setStrict($strict)
|
||||
{
|
||||
$this->_strict = (boolean) $strict;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the recursive option
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function getRecursive()
|
||||
{
|
||||
return $this->_recursive;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the recursive option
|
||||
*
|
||||
* @param boolean $recursive
|
||||
* @return Postman_Zend_Validate_InArray Provides a fluent interface
|
||||
*/
|
||||
public function setRecursive($recursive)
|
||||
{
|
||||
$this->_recursive = (boolean) $recursive;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defined by Postman_Zend_Validate_Interface
|
||||
*
|
||||
* Returns true if and only if $value is contained in the haystack option. If the strict
|
||||
* option is true, then the type of $value is also checked.
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return boolean
|
||||
*/
|
||||
public function isValid($value)
|
||||
{
|
||||
$this->_setValue($value);
|
||||
if ($this->getRecursive()) {
|
||||
$iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($this->_haystack));
|
||||
foreach($iterator as $element) {
|
||||
if ($this->_strict) {
|
||||
if ($element === $value) {
|
||||
return true;
|
||||
}
|
||||
} else if ($element == $value) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (in_array($value, $this->_haystack, $this->_strict)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
$this->_error(self::NOT_IN_ARRAY);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Validate_Abstract
|
||||
*/
|
||||
require_once 'Zend/Validate/Abstract.php';
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Locale_Format
|
||||
*/
|
||||
require_once 'Zend/Locale/Format.php';
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Validate_Int extends Postman_Zend_Validate_Abstract
|
||||
{
|
||||
const INVALID = 'intInvalid';
|
||||
const NOT_INT = 'notInt';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $_messageTemplates = array(
|
||||
self::INVALID => "Invalid type given. String or integer expected",
|
||||
self::NOT_INT => "'%value%' does not appear to be an integer",
|
||||
);
|
||||
|
||||
protected $_locale;
|
||||
|
||||
/**
|
||||
* Constructor for the integer validator
|
||||
*
|
||||
* @param string|Postman_Zend_Config|Postman_Zend_Locale $locale
|
||||
*/
|
||||
public function __construct($locale = null)
|
||||
{
|
||||
if ($locale instanceof Postman_Zend_Config) {
|
||||
$locale = $locale->toArray();
|
||||
}
|
||||
|
||||
if (is_array($locale)) {
|
||||
if (array_key_exists('locale', $locale)) {
|
||||
$locale = $locale['locale'];
|
||||
} else {
|
||||
$locale = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($locale)) {
|
||||
require_once 'Zend/Registry.php';
|
||||
if (Postman_Zend_Registry::isRegistered('Postman_Zend_Locale')) {
|
||||
$locale = Postman_Zend_Registry::get('Postman_Zend_Locale');
|
||||
}
|
||||
}
|
||||
|
||||
if ($locale !== null) {
|
||||
$this->setLocale($locale);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the set locale
|
||||
*/
|
||||
public function getLocale()
|
||||
{
|
||||
return $this->_locale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the locale to use
|
||||
*
|
||||
* @param string|Postman_Zend_Locale $locale
|
||||
* @return $this
|
||||
*/
|
||||
public function setLocale($locale = null)
|
||||
{
|
||||
require_once 'Zend/Locale.php';
|
||||
$this->_locale = Postman_Zend_Locale::findLocale($locale);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defined by Postman_Zend_Validate_Interface
|
||||
*
|
||||
* Returns true if and only if $value is a valid integer
|
||||
*
|
||||
* @param string|integer $value
|
||||
* @return boolean
|
||||
*/
|
||||
public function isValid($value)
|
||||
{
|
||||
if (!is_string($value) && !is_int($value) && !is_float($value)) {
|
||||
$this->_error(self::INVALID);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_int($value)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$this->_setValue($value);
|
||||
if ($this->_locale === null) {
|
||||
$locale = localeconv();
|
||||
$valueFiltered = str_replace($locale['decimal_point'], '.', $value);
|
||||
$valueFiltered = str_replace($locale['thousands_sep'], '', $valueFiltered);
|
||||
|
||||
if (strval(intval($valueFiltered)) != $valueFiltered) {
|
||||
$this->_error(self::NOT_INT);
|
||||
return false;
|
||||
}
|
||||
|
||||
} else {
|
||||
try {
|
||||
if (!Postman_Zend_Locale_Format::isInteger($value, array('locale' => $this->_locale))) {
|
||||
$this->_error(self::NOT_INT);
|
||||
return false;
|
||||
}
|
||||
} catch (Postman_Zend_Locale_Exception $e) {
|
||||
$this->_error(self::NOT_INT);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
interface Postman_Zend_Validate_Interface
|
||||
{
|
||||
/**
|
||||
* Returns true if and only if $value meets the validation requirements
|
||||
*
|
||||
* If $value fails validation, then this method returns false, and
|
||||
* getMessages() will return an array of messages that explain why the
|
||||
* validation failed.
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return boolean
|
||||
* @throws Postman_Zend_Validate_Exception If validation of $value is impossible
|
||||
*/
|
||||
public function isValid($value);
|
||||
|
||||
/**
|
||||
* Returns an array of messages that explain why the most recent isValid()
|
||||
* call returned false. The array keys are validation failure message identifiers,
|
||||
* and the array values are the corresponding human-readable message strings.
|
||||
*
|
||||
* If isValid() was never called or if the most recent isValid() call
|
||||
* returned true, then this method returns an empty array.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getMessages();
|
||||
}
|
||||
@@ -0,0 +1,192 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Validate_Abstract
|
||||
*/
|
||||
// require_once 'Zend/Validate/Abstract.php';
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Validate_Ip extends Postman_Zend_Validate_Abstract
|
||||
{
|
||||
const INVALID = 'ipInvalid';
|
||||
const NOT_IP_ADDRESS = 'notIpAddress';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $_messageTemplates = array(
|
||||
self::INVALID => "Invalid type given. String expected",
|
||||
self::NOT_IP_ADDRESS => "'%value%' does not appear to be a valid IP address",
|
||||
);
|
||||
|
||||
/**
|
||||
* internal options
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_options = array(
|
||||
'allowipv6' => true,
|
||||
'allowipv4' => true
|
||||
);
|
||||
|
||||
/**
|
||||
* Sets validator options
|
||||
*
|
||||
* @param array $options OPTIONAL Options to set, see the manual for all available options
|
||||
*/
|
||||
public function __construct($options = array())
|
||||
{
|
||||
if ($options instanceof Postman_Zend_Config) {
|
||||
$options = $options->toArray();
|
||||
} else if (!is_array($options)) {
|
||||
$options = func_get_args();
|
||||
$temp['allowipv6'] = array_shift($options);
|
||||
if (!empty($options)) {
|
||||
$temp['allowipv4'] = array_shift($options);
|
||||
}
|
||||
|
||||
$options = $temp;
|
||||
}
|
||||
|
||||
$options += $this->_options;
|
||||
$this->setOptions($options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all set options
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getOptions()
|
||||
{
|
||||
return $this->_options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the options for this validator
|
||||
*
|
||||
* @param array $options
|
||||
* @throws Postman_Zend_Validate_Exception
|
||||
* @return Postman_Zend_Validate_Ip
|
||||
*/
|
||||
public function setOptions($options)
|
||||
{
|
||||
if (array_key_exists('allowipv6', $options)) {
|
||||
$this->_options['allowipv6'] = (boolean) $options['allowipv6'];
|
||||
}
|
||||
|
||||
if (array_key_exists('allowipv4', $options)) {
|
||||
$this->_options['allowipv4'] = (boolean) $options['allowipv4'];
|
||||
}
|
||||
|
||||
if (!$this->_options['allowipv4'] && !$this->_options['allowipv6']) {
|
||||
// require_once 'Zend/Validate/Exception.php';
|
||||
throw new Postman_Zend_Validate_Exception('Nothing to validate. Check your options');
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defined by Postman_Zend_Validate_Interface
|
||||
*
|
||||
* Returns true if and only if $value is a valid IP address
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return boolean
|
||||
*/
|
||||
public function isValid($value)
|
||||
{
|
||||
if (!is_string($value)) {
|
||||
$this->_error(self::INVALID);
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->_setValue($value);
|
||||
if (($this->_options['allowipv4'] && !$this->_options['allowipv6'] && !$this->_validateIPv4($value)) ||
|
||||
(!$this->_options['allowipv4'] && $this->_options['allowipv6'] && !$this->_validateIPv6($value)) ||
|
||||
($this->_options['allowipv4'] && $this->_options['allowipv6'] && !$this->_validateIPv4($value) && !$this->_validateIPv6($value))) {
|
||||
$this->_error(self::NOT_IP_ADDRESS);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates an IPv4 address
|
||||
*
|
||||
* @param string $value
|
||||
* @return bool
|
||||
*/
|
||||
protected function _validateIPv4($value) {
|
||||
$ip2long = ip2long($value);
|
||||
if($ip2long === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $value == long2ip($ip2long);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates an IPv6 address
|
||||
*
|
||||
* @param string $value Value to check against
|
||||
* @return boolean True when $value is a valid ipv6 address
|
||||
* False otherwise
|
||||
*/
|
||||
protected function _validateIPv6($value) {
|
||||
if (strlen($value) < 3) {
|
||||
return $value == '::';
|
||||
}
|
||||
|
||||
if (strpos($value, '.')) {
|
||||
$lastcolon = strrpos($value, ':');
|
||||
if (!($lastcolon && $this->_validateIPv4(substr($value, $lastcolon + 1)))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$value = substr($value, 0, $lastcolon) . ':0:0';
|
||||
}
|
||||
|
||||
if (strpos($value, '::') === false) {
|
||||
return preg_match('/\A(?:[a-f0-9]{1,4}:){7}[a-f0-9]{1,4}\z/i', $value);
|
||||
}
|
||||
|
||||
$colonCount = substr_count($value, ':');
|
||||
if ($colonCount < 8) {
|
||||
return preg_match('/\A(?::|(?:[a-f0-9]{1,4}:)+):(?:(?:[a-f0-9]{1,4}:)*[a-f0-9]{1,4})?\z/i', $value);
|
||||
}
|
||||
|
||||
// special case with ending or starting double colon
|
||||
if ($colonCount == 8) {
|
||||
return preg_match('/\A(?:::)?(?:[a-f0-9]{1,4}:){6}[a-f0-9]{1,4}(?:::)?\z/i', $value);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,278 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Validate_Abstract
|
||||
*/
|
||||
require_once 'Zend/Validate/Abstract.php';
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Validate_Isbn extends Postman_Zend_Validate_Abstract
|
||||
{
|
||||
const AUTO = 'auto';
|
||||
const ISBN10 = '10';
|
||||
const ISBN13 = '13';
|
||||
const INVALID = 'isbnInvalid';
|
||||
const NO_ISBN = 'isbnNoIsbn';
|
||||
|
||||
/**
|
||||
* Validation failure message template definitions.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_messageTemplates = array(
|
||||
self::INVALID => "Invalid type given. String or integer expected",
|
||||
self::NO_ISBN => "'%value%' is not a valid ISBN number",
|
||||
);
|
||||
|
||||
/**
|
||||
* Allowed type.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_type = self::AUTO;
|
||||
|
||||
/**
|
||||
* Separator character.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_separator = '';
|
||||
|
||||
/**
|
||||
* Set up options.
|
||||
*
|
||||
* @param Postman_Zend_Config|array $options
|
||||
* @throws Postman_Zend_Validate_Exception When $options is not valid
|
||||
*/
|
||||
public function __construct($options = array())
|
||||
{
|
||||
// prepare options
|
||||
if ($options instanceof Postman_Zend_Config) {
|
||||
$options = $options->toArray();
|
||||
}
|
||||
if (!is_array($options)) {
|
||||
/**
|
||||
* @see Postman_Zend_Validate_Exception
|
||||
*/
|
||||
require_once 'Zend/Validate/Exception.php';
|
||||
throw new Postman_Zend_Validate_Exception('Invalid options provided.');
|
||||
}
|
||||
|
||||
// set type
|
||||
if (array_key_exists('type', $options)) {
|
||||
$this->setType($options['type']);
|
||||
}
|
||||
|
||||
// set separator
|
||||
if (array_key_exists('separator', $options)) {
|
||||
$this->setSeparator($options['separator']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect input format.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function _detectFormat()
|
||||
{
|
||||
// prepare separator and pattern list
|
||||
$sep = quotemeta($this->_separator);
|
||||
$patterns = array();
|
||||
$lengths = array();
|
||||
|
||||
// check for ISBN-10
|
||||
if ($this->_type == self::ISBN10 || $this->_type == self::AUTO) {
|
||||
if (empty($sep)) {
|
||||
$pattern = '/^[0-9]{9}[0-9X]{1}$/';
|
||||
$length = 10;
|
||||
} else {
|
||||
$pattern = "/^[0-9]{1,7}[{$sep}]{1}[0-9]{1,7}[{$sep}]{1}[0-9]{1,7}[{$sep}]{1}[0-9X]{1}$/";
|
||||
$length = 13;
|
||||
}
|
||||
|
||||
$patterns[$pattern] = self::ISBN10;
|
||||
$lengths[$pattern] = $length;
|
||||
}
|
||||
|
||||
// check for ISBN-13
|
||||
if ($this->_type == self::ISBN13 || $this->_type == self::AUTO) {
|
||||
if (empty($sep)) {
|
||||
$pattern = '/^[0-9]{13}$/';
|
||||
$length = 13;
|
||||
} else {
|
||||
$pattern = "/^[0-9]{1,9}[{$sep}]{1}[0-9]{1,5}[{$sep}]{1}[0-9]{1,9}[{$sep}]{1}[0-9]{1,9}[{$sep}]{1}[0-9]{1}$/";
|
||||
$length = 17;
|
||||
}
|
||||
|
||||
$patterns[$pattern] = self::ISBN13;
|
||||
$lengths[$pattern] = $length;
|
||||
}
|
||||
|
||||
// check pattern list
|
||||
foreach ($patterns as $pattern => $type) {
|
||||
if ((strlen($this->_value) == $lengths[$pattern]) && preg_match($pattern, $this->_value)) {
|
||||
return $type;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defined by Postman_Zend_Validate_Interface.
|
||||
*
|
||||
* Returns true if and only if $value is a valid ISBN.
|
||||
*
|
||||
* @param string $value
|
||||
* @return boolean
|
||||
*/
|
||||
public function isValid($value)
|
||||
{
|
||||
if (!is_string($value) && !is_int($value)) {
|
||||
$this->_error(self::INVALID);
|
||||
return false;
|
||||
}
|
||||
|
||||
$value = (string) $value;
|
||||
$this->_setValue($value);
|
||||
|
||||
switch ($this->_detectFormat()) {
|
||||
case self::ISBN10:
|
||||
// sum
|
||||
$isbn10 = str_replace($this->_separator, '', $value);
|
||||
$sum = 0;
|
||||
for ($i = 0; $i < 9; $i++) {
|
||||
$sum += (10 - $i) * $isbn10[$i];
|
||||
}
|
||||
|
||||
// checksum
|
||||
$checksum = 11 - ($sum % 11);
|
||||
if ($checksum == 11) {
|
||||
$checksum = '0';
|
||||
} elseif ($checksum == 10) {
|
||||
$checksum = 'X';
|
||||
}
|
||||
break;
|
||||
|
||||
case self::ISBN13:
|
||||
// sum
|
||||
$isbn13 = str_replace($this->_separator, '', $value);
|
||||
$sum = 0;
|
||||
for ($i = 0; $i < 12; $i++) {
|
||||
if ($i % 2 == 0) {
|
||||
$sum += $isbn13[$i];
|
||||
} else {
|
||||
$sum += 3 * $isbn13[$i];
|
||||
}
|
||||
}
|
||||
// checksum
|
||||
$checksum = 10 - ($sum % 10);
|
||||
if ($checksum == 10) {
|
||||
$checksum = '0';
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
$this->_error(self::NO_ISBN);
|
||||
return false;
|
||||
}
|
||||
|
||||
// validate
|
||||
if (substr($this->_value, -1) != $checksum) {
|
||||
$this->_error(self::NO_ISBN);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set separator characters.
|
||||
*
|
||||
* It is allowed only empty string, hyphen and space.
|
||||
*
|
||||
* @param string $separator
|
||||
* @throws Postman_Zend_Validate_Exception When $separator is not valid
|
||||
* @return Postman_Zend_Validate_Isbn Provides a fluent interface
|
||||
*/
|
||||
public function setSeparator($separator)
|
||||
{
|
||||
// check separator
|
||||
if (!in_array($separator, array('-', ' ', ''))) {
|
||||
/**
|
||||
* @see Postman_Zend_Validate_Exception
|
||||
*/
|
||||
require_once 'Zend/Validate/Exception.php';
|
||||
throw new Postman_Zend_Validate_Exception('Invalid ISBN separator.');
|
||||
}
|
||||
|
||||
$this->_separator = $separator;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get separator characters.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSeparator()
|
||||
{
|
||||
return $this->_separator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set allowed ISBN type.
|
||||
*
|
||||
* @param string $type
|
||||
* @throws Postman_Zend_Validate_Exception When $type is not valid
|
||||
* @return Postman_Zend_Validate_Isbn Provides a fluent interface
|
||||
*/
|
||||
public function setType($type)
|
||||
{
|
||||
// check type
|
||||
if (!in_array($type, array(self::AUTO, self::ISBN10, self::ISBN13))) {
|
||||
/**
|
||||
* @see Postman_Zend_Validate_Exception
|
||||
*/
|
||||
require_once 'Zend/Validate/Exception.php';
|
||||
throw new Postman_Zend_Validate_Exception('Invalid ISBN type');
|
||||
}
|
||||
|
||||
$this->_type = $type;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get allowed ISBN type.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
return $this->_type;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Validate_Abstract
|
||||
*/
|
||||
require_once 'Zend/Validate/Abstract.php';
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Validate_LessThan extends Postman_Zend_Validate_Abstract
|
||||
{
|
||||
const NOT_LESS = 'notLessThan';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $_messageTemplates = array(
|
||||
self::NOT_LESS => "'%value%' is not less than '%max%'"
|
||||
);
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $_messageVariables = array(
|
||||
'max' => '_max'
|
||||
);
|
||||
|
||||
/**
|
||||
* Maximum value
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
protected $_max;
|
||||
|
||||
/**
|
||||
* Sets validator options
|
||||
*
|
||||
* @param mixed|Postman_Zend_Config $max
|
||||
* @throws Postman_Zend_Validate_Exception
|
||||
*/
|
||||
public function __construct($max)
|
||||
{
|
||||
if ($max instanceof Postman_Zend_Config) {
|
||||
$max = $max->toArray();
|
||||
}
|
||||
|
||||
if (is_array($max)) {
|
||||
if (array_key_exists('max', $max)) {
|
||||
$max = $max['max'];
|
||||
} else {
|
||||
require_once 'Zend/Validate/Exception.php';
|
||||
throw new Postman_Zend_Validate_Exception("Missing option 'max'");
|
||||
}
|
||||
}
|
||||
|
||||
$this->setMax($max);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the max option
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getMax()
|
||||
{
|
||||
return $this->_max;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the max option
|
||||
*
|
||||
* @param mixed $max
|
||||
* @return Postman_Zend_Validate_LessThan Provides a fluent interface
|
||||
*/
|
||||
public function setMax($max)
|
||||
{
|
||||
$this->_max = $max;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defined by Postman_Zend_Validate_Interface
|
||||
*
|
||||
* Returns true if and only if $value is less than max option
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return boolean
|
||||
*/
|
||||
public function isValid($value)
|
||||
{
|
||||
$this->_setValue($value);
|
||||
if ($this->_max <= $value) {
|
||||
$this->_error(self::NOT_LESS);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,279 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Validate_Abstract
|
||||
*/
|
||||
require_once 'Zend/Validate/Abstract.php';
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Validate_NotEmpty extends Postman_Zend_Validate_Abstract
|
||||
{
|
||||
const BOOLEAN = 1;
|
||||
const INTEGER = 2;
|
||||
const FLOAT = 4;
|
||||
const STRING = 8;
|
||||
const ZERO = 16;
|
||||
const EMPTY_ARRAY = 32;
|
||||
const NULL = 64;
|
||||
const PHP = 127;
|
||||
const SPACE = 128;
|
||||
const OBJECT = 256;
|
||||
const OBJECT_STRING = 512;
|
||||
const OBJECT_COUNT = 1024;
|
||||
const ALL = 2047;
|
||||
|
||||
const INVALID = 'notEmptyInvalid';
|
||||
const IS_EMPTY = 'isEmpty';
|
||||
|
||||
protected $_constants = array(
|
||||
self::BOOLEAN => 'boolean',
|
||||
self::INTEGER => 'integer',
|
||||
self::FLOAT => 'float',
|
||||
self::STRING => 'string',
|
||||
self::ZERO => 'zero',
|
||||
self::EMPTY_ARRAY => 'array',
|
||||
self::NULL => 'null',
|
||||
self::PHP => 'php',
|
||||
self::SPACE => 'space',
|
||||
self::OBJECT => 'object',
|
||||
self::OBJECT_STRING => 'objectstring',
|
||||
self::OBJECT_COUNT => 'objectcount',
|
||||
self::ALL => 'all',
|
||||
);
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $_messageTemplates = array(
|
||||
self::IS_EMPTY => "Value is required and can't be empty",
|
||||
self::INVALID => "Invalid type given. String, integer, float, boolean or array expected",
|
||||
);
|
||||
|
||||
/**
|
||||
* Internal type to detect
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $_type = 493;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string|array|Postman_Zend_Config $options OPTIONAL
|
||||
*/
|
||||
public function __construct($options = null)
|
||||
{
|
||||
if ($options instanceof Postman_Zend_Config) {
|
||||
$options = $options->toArray();
|
||||
} else if (!is_array($options)) {
|
||||
$options = func_get_args();
|
||||
$temp = array();
|
||||
if (!empty($options)) {
|
||||
$temp['type'] = array_shift($options);
|
||||
}
|
||||
|
||||
$options = $temp;
|
||||
}
|
||||
|
||||
if (is_array($options) && array_key_exists('type', $options)) {
|
||||
$this->setType($options['type']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the set types
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
return $this->_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the types
|
||||
*
|
||||
* @param integer|array $type
|
||||
* @throws Postman_Zend_Validate_Exception
|
||||
* @return Postman_Zend_Validate_NotEmpty
|
||||
*/
|
||||
public function setType($type = null)
|
||||
{
|
||||
if (is_array($type)) {
|
||||
$detected = 0;
|
||||
foreach($type as $value) {
|
||||
if (is_int($value)) {
|
||||
$detected += $value;
|
||||
} else if (in_array($value, $this->_constants)) {
|
||||
$detected += array_search($value, $this->_constants);
|
||||
}
|
||||
}
|
||||
|
||||
$type = $detected;
|
||||
} else if (is_string($type) && in_array($type, $this->_constants)) {
|
||||
$type = array_search($type, $this->_constants);
|
||||
}
|
||||
|
||||
if (!is_int($type) || ($type < 0) || ($type > self::ALL)) {
|
||||
require_once 'Zend/Validate/Exception.php';
|
||||
throw new Postman_Zend_Validate_Exception('Unknown type');
|
||||
}
|
||||
|
||||
$this->_type = $type;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defined by Postman_Zend_Validate_Interface
|
||||
*
|
||||
* Returns true if and only if $value is not an empty value.
|
||||
*
|
||||
* @param string $value
|
||||
* @return boolean
|
||||
*/
|
||||
public function isValid($value)
|
||||
{
|
||||
if ($value !== null && !is_string($value) && !is_int($value) && !is_float($value) &&
|
||||
!is_bool($value) && !is_array($value) && !is_object($value)) {
|
||||
$this->_error(self::INVALID);
|
||||
return false;
|
||||
}
|
||||
|
||||
$type = $this->getType();
|
||||
$this->_setValue($value);
|
||||
$object = false;
|
||||
|
||||
// OBJECT_COUNT (countable object)
|
||||
if ($type >= self::OBJECT_COUNT) {
|
||||
$type -= self::OBJECT_COUNT;
|
||||
$object = true;
|
||||
|
||||
if (is_object($value) && ($value instanceof Countable) && (count($value) == 0)) {
|
||||
$this->_error(self::IS_EMPTY);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// OBJECT_STRING (object's toString)
|
||||
if ($type >= self::OBJECT_STRING) {
|
||||
$type -= self::OBJECT_STRING;
|
||||
$object = true;
|
||||
|
||||
if ((is_object($value) && (!method_exists($value, '__toString'))) ||
|
||||
(is_object($value) && (method_exists($value, '__toString')) && (((string) $value) == ""))) {
|
||||
$this->_error(self::IS_EMPTY);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// OBJECT (object)
|
||||
if ($type >= self::OBJECT) {
|
||||
$type -= self::OBJECT;
|
||||
// fall trough, objects are always not empty
|
||||
} else if ($object === false) {
|
||||
// object not allowed but object given -> return false
|
||||
if (is_object($value)) {
|
||||
$this->_error(self::IS_EMPTY);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// SPACE (' ')
|
||||
if ($type >= self::SPACE) {
|
||||
$type -= self::SPACE;
|
||||
if (is_string($value) && (preg_match('/^\s+$/s', $value))) {
|
||||
$this->_error(self::IS_EMPTY);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// NULL (null)
|
||||
if ($type >= self::NULL) {
|
||||
$type -= self::NULL;
|
||||
if ($value === null) {
|
||||
$this->_error(self::IS_EMPTY);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// EMPTY_ARRAY (array())
|
||||
if ($type >= self::EMPTY_ARRAY) {
|
||||
$type -= self::EMPTY_ARRAY;
|
||||
if (is_array($value) && ($value == array())) {
|
||||
$this->_error(self::IS_EMPTY);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// ZERO ('0')
|
||||
if ($type >= self::ZERO) {
|
||||
$type -= self::ZERO;
|
||||
if (is_string($value) && ($value == '0')) {
|
||||
$this->_error(self::IS_EMPTY);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// STRING ('')
|
||||
if ($type >= self::STRING) {
|
||||
$type -= self::STRING;
|
||||
if (is_string($value) && ($value == '')) {
|
||||
$this->_error(self::IS_EMPTY);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// FLOAT (0.0)
|
||||
if ($type >= self::FLOAT) {
|
||||
$type -= self::FLOAT;
|
||||
if (is_float($value) && ($value == 0.0)) {
|
||||
$this->_error(self::IS_EMPTY);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// INTEGER (0)
|
||||
if ($type >= self::INTEGER) {
|
||||
$type -= self::INTEGER;
|
||||
if (is_int($value) && ($value == 0)) {
|
||||
$this->_error(self::IS_EMPTY);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// BOOLEAN (false)
|
||||
if ($type >= self::BOOLEAN) {
|
||||
$type -= self::BOOLEAN;
|
||||
if (is_bool($value) && ($value == false)) {
|
||||
$this->_error(self::IS_EMPTY);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,210 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Validate_Abstract
|
||||
*/
|
||||
require_once 'Zend/Validate/Abstract.php';
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Locale_Format
|
||||
*/
|
||||
require_once 'Zend/Locale/Format.php';
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Validate_PostCode extends Postman_Zend_Validate_Abstract
|
||||
{
|
||||
const INVALID = 'postcodeInvalid';
|
||||
const NO_MATCH = 'postcodeNoMatch';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $_messageTemplates = array(
|
||||
self::INVALID => "Invalid type given. String or integer expected",
|
||||
self::NO_MATCH => "'%value%' does not appear to be a postal code",
|
||||
);
|
||||
|
||||
/**
|
||||
* Locale to use
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_locale;
|
||||
|
||||
/**
|
||||
* Manual postal code format
|
||||
*
|
||||
* @var unknown_type
|
||||
*/
|
||||
protected $_format;
|
||||
|
||||
/**
|
||||
* Constructor for the integer validator
|
||||
*
|
||||
* Accepts either a string locale, a Postman_Zend_Locale object, or an array or
|
||||
* Postman_Zend_Config object containing the keys "locale" and/or "format".
|
||||
*
|
||||
* @param string|Postman_Zend_Locale|array|Postman_Zend_Config $options
|
||||
* @throws Postman_Zend_Validate_Exception On empty format
|
||||
*/
|
||||
public function __construct($options = null)
|
||||
{
|
||||
if ($options instanceof Postman_Zend_Config) {
|
||||
$options = $options->toArray();
|
||||
}
|
||||
|
||||
if (empty($options)) {
|
||||
require_once 'Zend/Registry.php';
|
||||
if (Postman_Zend_Registry::isRegistered('Postman_Zend_Locale')) {
|
||||
$this->setLocale(Postman_Zend_Registry::get('Postman_Zend_Locale'));
|
||||
}
|
||||
} elseif (is_array($options)) {
|
||||
// Received
|
||||
if (array_key_exists('locale', $options)) {
|
||||
$this->setLocale($options['locale']);
|
||||
}
|
||||
|
||||
if (array_key_exists('format', $options)) {
|
||||
$this->setFormat($options['format']);
|
||||
}
|
||||
} elseif ($options instanceof Postman_Zend_Locale || is_string($options)) {
|
||||
// Received Locale object or string locale
|
||||
$this->setLocale($options);
|
||||
}
|
||||
|
||||
$format = $this->getFormat();
|
||||
if (empty($format)) {
|
||||
require_once 'Zend/Validate/Exception.php';
|
||||
throw new Postman_Zend_Validate_Exception("A postcode-format string has to be given for validation");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the set locale
|
||||
*
|
||||
* @return string|Postman_Zend_Locale The set locale
|
||||
*/
|
||||
public function getLocale()
|
||||
{
|
||||
return $this->_locale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the locale to use
|
||||
*
|
||||
* @param string|Postman_Zend_Locale $locale
|
||||
* @throws Postman_Zend_Validate_Exception On unrecognised region
|
||||
* @throws Postman_Zend_Validate_Exception On not detected format
|
||||
* @return Postman_Zend_Validate_PostCode Provides a fluent interface
|
||||
*/
|
||||
public function setLocale($locale = null)
|
||||
{
|
||||
require_once 'Zend/Locale.php';
|
||||
$this->_locale = Postman_Zend_Locale::findLocale($locale);
|
||||
$locale = new Postman_Zend_Locale($this->_locale);
|
||||
$region = $locale->getRegion();
|
||||
if (empty($region)) {
|
||||
require_once 'Zend/Validate/Exception.php';
|
||||
throw new Postman_Zend_Validate_Exception("Unable to detect a region for the locale '$locale'");
|
||||
}
|
||||
|
||||
$format = Postman_Zend_Locale::getTranslation(
|
||||
$locale->getRegion(),
|
||||
'postaltoterritory',
|
||||
$this->_locale
|
||||
);
|
||||
|
||||
if (empty($format)) {
|
||||
require_once 'Zend/Validate/Exception.php';
|
||||
throw new Postman_Zend_Validate_Exception("Unable to detect a postcode format for the region '{$locale->getRegion()}'");
|
||||
}
|
||||
|
||||
$this->setFormat($format);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the set postal code format
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFormat()
|
||||
{
|
||||
return $this->_format;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a self defined postal format as regex
|
||||
*
|
||||
* @param string $format
|
||||
* @throws Postman_Zend_Validate_Exception On empty format
|
||||
* @return Postman_Zend_Validate_PostCode Provides a fluent interface
|
||||
*/
|
||||
public function setFormat($format)
|
||||
{
|
||||
if (empty($format) || !is_string($format)) {
|
||||
require_once 'Zend/Validate/Exception.php';
|
||||
throw new Postman_Zend_Validate_Exception("A postcode-format string has to be given for validation");
|
||||
}
|
||||
|
||||
if ($format[0] !== '/') {
|
||||
$format = '/^' . $format;
|
||||
}
|
||||
|
||||
if ($format[strlen($format) - 1] !== '/') {
|
||||
$format .= '$/';
|
||||
}
|
||||
|
||||
$this->_format = $format;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defined by Postman_Zend_Validate_Interface
|
||||
*
|
||||
* Returns true if and only if $value is a valid postalcode
|
||||
*
|
||||
* @param string $value
|
||||
* @return boolean
|
||||
*/
|
||||
public function isValid($value)
|
||||
{
|
||||
$this->_setValue($value);
|
||||
if (!is_string($value) && !is_int($value)) {
|
||||
$this->_error(self::INVALID);
|
||||
return false;
|
||||
}
|
||||
|
||||
$format = $this->getFormat();
|
||||
if (!preg_match($format, $value)) {
|
||||
$this->_error(self::NO_MATCH);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Validate_Abstract
|
||||
*/
|
||||
require_once 'Zend/Validate/Abstract.php';
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Validate_Regex extends Postman_Zend_Validate_Abstract
|
||||
{
|
||||
const INVALID = 'regexInvalid';
|
||||
const NOT_MATCH = 'regexNotMatch';
|
||||
const ERROROUS = 'regexErrorous';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $_messageTemplates = array(
|
||||
self::INVALID => "Invalid type given. String, integer or float expected",
|
||||
self::NOT_MATCH => "'%value%' does not match against pattern '%pattern%'",
|
||||
self::ERROROUS => "There was an internal error while using the pattern '%pattern%'",
|
||||
);
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $_messageVariables = array(
|
||||
'pattern' => '_pattern'
|
||||
);
|
||||
|
||||
/**
|
||||
* Regular expression pattern
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_pattern;
|
||||
|
||||
/**
|
||||
* Sets validator options
|
||||
*
|
||||
* @param string|Postman_Zend_Config $pattern
|
||||
* @throws Postman_Zend_Validate_Exception On missing 'pattern' parameter
|
||||
*/
|
||||
public function __construct($pattern)
|
||||
{
|
||||
if ($pattern instanceof Postman_Zend_Config) {
|
||||
$pattern = $pattern->toArray();
|
||||
}
|
||||
|
||||
if (is_array($pattern)) {
|
||||
if (array_key_exists('pattern', $pattern)) {
|
||||
$pattern = $pattern['pattern'];
|
||||
} else {
|
||||
require_once 'Zend/Validate/Exception.php';
|
||||
throw new Postman_Zend_Validate_Exception("Missing option 'pattern'");
|
||||
}
|
||||
}
|
||||
|
||||
$this->setPattern($pattern);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the pattern option
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPattern()
|
||||
{
|
||||
return $this->_pattern;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the pattern option
|
||||
*
|
||||
* @param string $pattern
|
||||
* @throws Postman_Zend_Validate_Exception if there is a fatal error in pattern matching
|
||||
* @return Postman_Zend_Validate_Regex Provides a fluent interface
|
||||
*/
|
||||
public function setPattern($pattern)
|
||||
{
|
||||
$this->_pattern = (string) $pattern;
|
||||
$status = @preg_match($this->_pattern, "Test");
|
||||
|
||||
if (false === $status) {
|
||||
require_once 'Zend/Validate/Exception.php';
|
||||
throw new Postman_Zend_Validate_Exception("Internal error while using the pattern '$this->_pattern'");
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defined by Postman_Zend_Validate_Interface
|
||||
*
|
||||
* Returns true if and only if $value matches against the pattern option
|
||||
*
|
||||
* @param string $value
|
||||
* @return boolean
|
||||
*/
|
||||
public function isValid($value)
|
||||
{
|
||||
if (!is_string($value) && !is_int($value) && !is_float($value)) {
|
||||
$this->_error(self::INVALID);
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->_setValue($value);
|
||||
|
||||
$status = @preg_match($this->_pattern, $value);
|
||||
if (false === $status) {
|
||||
$this->_error(self::ERROROUS);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$status) {
|
||||
$this->_error(self::NOT_MATCH);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,263 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @see Postman_Zend_Validate_Abstract
|
||||
*/
|
||||
require_once 'Zend/Validate/Abstract.php';
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Postman_Zend_Validate
|
||||
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Postman_Zend_Validate_StringLength extends Postman_Zend_Validate_Abstract
|
||||
{
|
||||
const INVALID = 'stringLengthInvalid';
|
||||
const TOO_SHORT = 'stringLengthTooShort';
|
||||
const TOO_LONG = 'stringLengthTooLong';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $_messageTemplates = array(
|
||||
self::INVALID => "Invalid type given. String expected",
|
||||
self::TOO_SHORT => "'%value%' is less than %min% characters long",
|
||||
self::TOO_LONG => "'%value%' is more than %max% characters long",
|
||||
);
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $_messageVariables = array(
|
||||
'min' => '_min',
|
||||
'max' => '_max'
|
||||
);
|
||||
|
||||
/**
|
||||
* Minimum length
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $_min;
|
||||
|
||||
/**
|
||||
* Maximum length
|
||||
*
|
||||
* If null, there is no maximum length
|
||||
*
|
||||
* @var integer|null
|
||||
*/
|
||||
protected $_max;
|
||||
|
||||
/**
|
||||
* Encoding to use
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
protected $_encoding;
|
||||
|
||||
/**
|
||||
* Sets validator options
|
||||
*
|
||||
* @param integer|array|Postman_Zend_Config $options
|
||||
*/
|
||||
public function __construct($options = array())
|
||||
{
|
||||
if ($options instanceof Postman_Zend_Config) {
|
||||
$options = $options->toArray();
|
||||
} else if (!is_array($options)) {
|
||||
$options = func_get_args();
|
||||
$temp['min'] = array_shift($options);
|
||||
if (!empty($options)) {
|
||||
$temp['max'] = array_shift($options);
|
||||
}
|
||||
|
||||
if (!empty($options)) {
|
||||
$temp['encoding'] = array_shift($options);
|
||||
}
|
||||
|
||||
$options = $temp;
|
||||
}
|
||||
|
||||
if (!array_key_exists('min', $options)) {
|
||||
$options['min'] = 0;
|
||||
}
|
||||
|
||||
$this->setMin($options['min']);
|
||||
if (array_key_exists('max', $options)) {
|
||||
$this->setMax($options['max']);
|
||||
}
|
||||
|
||||
if (array_key_exists('encoding', $options)) {
|
||||
$this->setEncoding($options['encoding']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the min option
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getMin()
|
||||
{
|
||||
return $this->_min;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the min option
|
||||
*
|
||||
* @param integer $min
|
||||
* @throws Postman_Zend_Validate_Exception
|
||||
* @return Postman_Zend_Validate_StringLength Provides a fluent interface
|
||||
*/
|
||||
public function setMin($min)
|
||||
{
|
||||
if (null !== $this->_max && $min > $this->_max) {
|
||||
/**
|
||||
* @see Postman_Zend_Validate_Exception
|
||||
*/
|
||||
require_once 'Zend/Validate/Exception.php';
|
||||
throw new Postman_Zend_Validate_Exception("The minimum must be less than or equal to the maximum length, but $min >"
|
||||
. " $this->_max");
|
||||
}
|
||||
$this->_min = max(0, (integer) $min);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the max option
|
||||
*
|
||||
* @return integer|null
|
||||
*/
|
||||
public function getMax()
|
||||
{
|
||||
return $this->_max;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the max option
|
||||
*
|
||||
* @param integer|null $max
|
||||
* @throws Postman_Zend_Validate_Exception
|
||||
* @return Postman_Zend_Validate_StringLength Provides a fluent interface
|
||||
*/
|
||||
public function setMax($max)
|
||||
{
|
||||
if (null === $max) {
|
||||
$this->_max = null;
|
||||
} else if ($max < $this->_min) {
|
||||
/**
|
||||
* @see Postman_Zend_Validate_Exception
|
||||
*/
|
||||
require_once 'Zend/Validate/Exception.php';
|
||||
throw new Postman_Zend_Validate_Exception("The maximum must be greater than or equal to the minimum length, but "
|
||||
. "$max < $this->_min");
|
||||
} else {
|
||||
$this->_max = (integer) $max;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the actual encoding
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getEncoding()
|
||||
{
|
||||
return $this->_encoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new encoding to use
|
||||
*
|
||||
* @param string $encoding
|
||||
* @throws Postman_Zend_Validate_Exception
|
||||
* @return Postman_Zend_Validate_StringLength
|
||||
*/
|
||||
public function setEncoding($encoding = null)
|
||||
{
|
||||
if ($encoding !== null) {
|
||||
$orig = PHP_VERSION_ID < 50600
|
||||
? iconv_get_encoding('internal_encoding')
|
||||
: ini_get('default_charset');
|
||||
if (PHP_VERSION_ID < 50600) {
|
||||
$result = iconv_set_encoding('internal_encoding', $encoding);
|
||||
} else {
|
||||
$result = ini_set('default_charset', $encoding);
|
||||
}
|
||||
if (!$result) {
|
||||
require_once 'Zend/Validate/Exception.php';
|
||||
throw new Postman_Zend_Validate_Exception('Given encoding not supported on this OS!');
|
||||
}
|
||||
|
||||
if (PHP_VERSION_ID < 50600) {
|
||||
iconv_set_encoding('internal_encoding', $orig);
|
||||
} else {
|
||||
ini_set('default_charset', $orig);
|
||||
}
|
||||
}
|
||||
|
||||
$this->_encoding = $encoding;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defined by Postman_Zend_Validate_Interface
|
||||
*
|
||||
* Returns true if and only if the string length of $value is at least the min option and
|
||||
* no greater than the max option (when the max option is not null).
|
||||
*
|
||||
* @param string $value
|
||||
* @return boolean
|
||||
*/
|
||||
public function isValid($value)
|
||||
{
|
||||
if (!is_string($value)) {
|
||||
$this->_error(self::INVALID);
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->_setValue($value);
|
||||
if ($this->_encoding !== null) {
|
||||
$length = iconv_strlen($value, $this->_encoding);
|
||||
} else {
|
||||
$length = iconv_strlen($value);
|
||||
}
|
||||
|
||||
if ($length < $this->_min) {
|
||||
$this->_error(self::TOO_SHORT);
|
||||
}
|
||||
|
||||
if (null !== $this->_max && $this->_max < $length) {
|
||||
$this->_error(self::TOO_LONG);
|
||||
}
|
||||
|
||||
if (count($this->_messages)) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user