<?php
/**
 * Error Stack Implementation
 *
 * This is an incredibly simple implementation of a very complex error handling
 * facility.  It contains the ability
 * to track multiple errors from multiple packages simultaneously.  In addition,
 * it can track errors of many levels, save data along with the error, context
 * information such as the exact file, line number, class and function that
 * generated the error, and if necessary, it can raise a traditional PEAR_Error.
 * It has built-in support for PEAR::Log, to log errors as they occur
 *
 * Since version 0.2alpha, it is also possible to selectively ignore errors,
 * through the use of an error callback, see {@link pushCallback()}
 *
 * Since version 0.3alpha, it is possible to specify the exception class
 * returned from {@link push()}
 *
 * Since version PEAR1.3.2, ErrorStack no longer instantiates an exception class.  This can
 * still be done quite handily in an error callback or by manipulating the returned array
 * @category   Debugging
 * @package    PEAR_ErrorStack
 * @author     Greg Beaver <cellog@php.net>
 * @copyright  2004-2008 Greg Beaver
 * @license    http://opensource.org/licenses/bsd-license.php New BSD License
 * @version    CVS: $Id: ErrorStack.php 313023 2011-07-06 19:17:11Z dufuz $
 * @link       http://pear.php.net/package/PEAR_ErrorStack
 */

/**
 * Singleton storage
 *
 * Format:
 *

 * array(
 *  'package1' => PEAR_ErrorStack object,
 *  'package2' => PEAR_ErrorStack object,
 *  ...
 * )
 *

 * @access private
 * @global array $GLOBALS['_PEAR_ERRORSTACK_SINGLETON']
 */
$GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] = array();

/**
 * Global error callback (default)
 *
 * This is only used if set to non-false.  * is the default callback for
 * all packages, whereas specific packages may set a default callback
 * for all instances, regardless of whether they are a singleton or not.
 *
 * To exclude non-singletons, only set the local callback for the singleton
 * @see PEAR_ErrorStack::setDefaultCallback()
 * @access private
 * @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK']
 */
$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'] = array(
    '*' => false,
);

/**
 * Global Log object (default)
 *
 * This is only used if set to non-false.  Use to set a default log object for
 * all stacks, regardless of instantiation order or location
 * @see PEAR_ErrorStack::setDefaultLogger()
 * @access private
 * @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER']
 */
$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = false;

/**
 * Global Overriding Callback
 *
 * This callback will override any error callbacks that specific loggers have set.
 * Use with EXTREME caution
 * @see PEAR_ErrorStack::staticPushCallback()
 * @access private
 * @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER']
 */
$GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'] = array();

/**#@+
 * One of four possible return values from the error Callback
 * @see PEAR_ErrorStack::_errorCallback()
 */
/**
 * If this is returned, then the error will be both pushed onto the stack
 * and logged.
 */
define('PEAR_ERRORSTACK_PUSHANDLOG', 1);
/**
 * If this is returned, then the error will only be pushed onto the stack,
 * and not logged.
 */
define('PEAR_ERRORSTACK_PUSH', 2);
/**
 * If this is returned, then the error will only be logged, but not pushed
 * onto the error stack.
 */
define('PEAR_ERRORSTACK_LOG', 3);
/**
 * If this is returned, then the error is completely ignored.
 */
define('PEAR_ERRORSTACK_IGNORE', 4);
/**
 * If this is returned, then the error is logged and die() is called.
 */
define('PEAR_ERRORSTACK_DIE', 5);
/**#@-*/

/**
 * Error code for an attempt to instantiate a non-class as a PEAR_ErrorStack in
 * the singleton method.
 */
define('PEAR_ERRORSTACK_ERR_NONCLASS', 1);

/**
 * Error code for an attempt to pass an object into {@link PEAR_ErrorStack::getMessage()}
 * that has no __toString() method
 */
define('PEAR_ERRORSTACK_ERR_OBJTOSTRING', 2);
/**
 * Error Stack Implementation
 *
 * Usage:
 *
 * // global error stack
 * $global_stack = &PEAR_ErrorStack::singleton('MyPackage');
 * // local error stack
 * $local_stack = new PEAR_ErrorStack('MyPackage');
 *
 * @author     Greg Beaver <cellog@php.net>
 * @version    1.9.4
 * @package    PEAR_ErrorStack
 * @category   Debugging
 * @copyright  2004-2008 Greg Beaver
 * @license    http://opensource.org/licenses/bsd-license.php New BSD License
 * @version    CVS: $Id: ErrorStack.php 313023 2011-07-06 19:17:11Z dufuz $
 * @link       http://pear.php.net/package/PEAR_ErrorStack
 */
class PEAR_ErrorStack {
    /**
     * Errors are stored in the order that they are pushed on the stack.
     * @since 0.4alpha Errors are no longer organized by error level.
     * This renders pop() nearly unusable, and levels could be more easily
     * handled in a callback anyway
     * @var array
     * @access private
     */
    var $_errors = array();

    /**
     * Storage of errors by level.
     *
     * Allows easy retrieval and deletion of only errors from a particular level
     * @since PEAR 1.4.0dev
     * @var array
     * @access private
     */
    var $_errorsByLevel = array();

    /**
     * Package name this error stack represents
     * @var string
     * @access protected
     */
    var $_package;

    /**
     * Determines whether a PEAR_Error is thrown upon every error addition
     * @var boolean
     * @access private
     */
    var $_compat = false;

    /**
     * If set to a valid callback, this will be used to generate the error
     * message from the error code, otherwise the message passed in will be
     * used
     * @var false|string|array
     * @access private
     */
    var $_msgCallback = false;

    /**
     * If set to a valid callback, this will be used to generate the error
     * context for an error.  For PHP-related errors, this will be a file
     * and line number as retrieved from debug_backtrace(), but can be
     * customized for other purposes.  The error might actually be in a separate
     * configuration file, or in a database query.
     * @var false|string|array
     * @access protected
     */
    var $_contextCallback = false;

    /**
     * If set to a valid callback, this will be called every time an error
     * is pushed onto the stack.  The return value will be used to determine
     * whether to allow an error to be pushed or logged.
     *
     * The return value must be one an PEAR_ERRORSTACK_* constant
     * @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG
     * @var false|string|array
     * @access protected
     */
    var $_errorCallback = array();

    /**
     * PEAR::Log object for logging errors
     * @var false|Log
     * @access protected
     */
    var $_logger = false;

    /**
     * Error messages - designed to be overridden
     * @var array
     * @abstract
     */
    var $_errorMsgs = array();

    /**
     * Set up a new error stack
     *
     * @param string   $package name of the package this error stack represents
     * @param callback $msgCallback callback used for error message generation
     * @param callback $contextCallback callback used for context generation,
     *                 defaults to {@link getFileLine()}
     * @param boolean  $throwPEAR_Error
     */
    function PEAR_ErrorStack($package, $msgCallback = false, $contextCallback = false,
                         $throwPEAR_Error = false)
    {
        $this->_package = $package;
        $this->setMessageCallback($msgCallback);
        $this->setContextCallback($contextCallback);
        $this->_compat = $throwPEAR_Error;
    }

    /**
     * Return a single error stack for this package.
     *
     * Note that all parameters are ignored if the stack for package $package
     * has already been instantiated
     * @param string   $package name of the package this error stack represents
     * @param callback $msgCallback callback used for error message generation
     * @param callback $contextCallback callback used for context generation,
     *                 defaults to {@link getFileLine()}
     * @param boolean  $throwPEAR_Error
     * @param string   $stackClass class to instantiate
     * @static
     * @return PEAR_ErrorStack
     */
    function &singleton($package, $msgCallback = false, $contextCallback = false,
                         $throwPEAR_Error = false, $stackClass = 'PEAR_ErrorStack')
    {
        if (isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) {
            return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package];
        }
        if (!class_exists($stackClass)) {
            if (function_exists('debug_backtrace')) {
                $trace = debug_backtrace();
            }
            PEAR_ErrorStack::staticPush('PEAR_ErrorStack', PEAR_ERRORSTACK_ERR_NONCLASS,
                'exception', array('stackclass' => $stackClass),
                'stack class "%stackclass%" is not a valid class name (should be like PEAR_ErrorStack)',
                false, $trace);
        }
        $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package] =
            new $stackClass($package, $msgCallback, $contextCallback, $throwPEAR_Error);

        return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package];
    }

    /**
     * Internal error handler for PEAR_ErrorStack class
     *
     * Dies if the error is an exception (and would have died anyway)
     * @access private
     */
    function _handleError($err)
    {
        if ($err['level'] == 'exception') {
            $message = $err['message'];
            if (isset($_SERVER['REQUEST_URI'])) {
                echo '
';
            } else {
                echo "\n";
            }
            var_dump($err['context']);
            die($message);
        }
    }

    /**
     * Set up a PEAR::Log object for all error stacks that don't have one
     * @param Log $log
     * @static
     */
    function setDefaultLogger(&$log)
    {
        if (is_object($log) && method_exists($log, 'log') ) {
            $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = &$log;
        } elseif (is_callable($log)) {
            $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = &$log;
	}
    }

    /**
     * Set up a PEAR::Log object for this error stack
     * @param Log $log
     */
    function setLogger(&$log)
    {
        if (is_object($log) && method_exists($log, 'log') ) {
            $this->_logger = &$log;
        } elseif (is_callable($log)) {
            $this->_logger = &$log;
        }
    }

    /**
     * Set an error code => error message mapping callback
     *
     * This method sets the callback that can be used to generate error
     * messages for any instance
     * @param array|string Callback function/method
     */
    function setMessageCallback($msgCallback)
    {
        if (!$msgCallback) {
            $this->_msgCallback = array(&$this, 'getErrorMessage');
        } else {
            if (is_callable($msgCallback)) {
                $this->_msgCallback = $msgCallback;
            }
        }
    }

    /**
     * Get an error code => error message mapping callback
     *
     * This method returns the current callback that can be used to generate error
     * messages
     * @return array|string|false Callback function/method or false if none
     */
    function getMessageCallback()
    {
        return $this->_msgCallback;
    }

    /**
     * Sets a default callback to be used by all error stacks
     *
     * This method sets the callback that can be used to generate error
     * messages for a singleton
     * @param array|string Callback function/method
     * @param string Package name, or false for all packages
     * @static
     */
    function setDefaultCallback($callback = false, $package = false)
    {
        if (!is_callable($callback)) {
            $callback = false;
        }
        $package = $package ? $package : '*';
        $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$package] = $callback;
    }

    /**
     * Set a callback that generates context information (location of error) for an error stack
     *
     * This method sets the callback that can be used to generate context
     * information for an error.  Passing in NULL will disable context generation
     * and remove the expensive call to debug_backtrace()
     * @param array|string|null Callback function/method
     */
    function setContextCallback($contextCallback)
    {
        if ($contextCallback === null) {
            return $this->_contextCallback = false;
        }
        if (!$contextCallback) {
            $this->_contextCallback = array(&$this, 'getFileLine');
        } else {
            if (is_callable($contextCallback)) {
                $this->_contextCallback = $contextCallback;
            }
        }
    }

    /**
     * Set an error Callback
     * If set to a valid callback, this will be called every time an error
     * is pushed onto the stack.  The return value will be used to determine
     * whether to allow an error to be pushed or logged.
     *
     * The return value must be one of the ERRORSTACK_* constants.
     *
     * This functionality can be used to emulate PEAR's pushErrorHandling, and
     * the PEAR_ERROR_CALLBACK mode, without affecting the integrity of
     * the error stack or logging
     * @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG
     * @see popCallback()
     * @param string|array $cb
     */
    function pushCallback($cb)
    {
        array_push($this->_errorCallback, $cb);
    }

    /**
     * Remove a callback from the error callback stack
     * @see pushCallback()
     * @return array|string|false
     */
    function popCallback()
    {
        if (!count($this->_errorCallback)) {
            return false;
        }
        return array_pop($this->_errorCallback);
    }

    /**
     * Set a temporary overriding error callback for every package error stack
     *
     * Use this to temporarily disable all existing callbacks (can be used
     * to emulate the @ operator, for instance)
     * @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG
     * @see staticPopCallback(), pushCallback()
     * @param string|array $cb
     * @static
     */
    function staticPushCallback($cb)
    {
        array_push($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'], $cb);
    }

    /**
     * Remove a temporary overriding error callback
     * @see staticPushCallback()
     * @return array|string|false
     * @static
     */
    function staticPopCallback()
    {
        $ret = array_pop($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK']);
        if (!is_array($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'])) {
            $GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'] = array();
        }
        return $ret;
    }

    /**
     * Add an error to the stack
     *
     * If the message generator exists, it is called with 2 parameters.
     *  - the current Error Stack object
     *  - an array that is in the same format as an error.  Available indices
     *    are 'code', 'package', 'time', 'params', 'level', and 'context'
     *
     * Next, if the error should contain context information, this is
     * handled by the context grabbing method.
     * Finally, the error is pushed onto the proper error stack
     * @param int    $code      Package-specific error code
     * @param string $level     Error level.  This is NOT spell-checked
     * @param array  $params    associative array of error parameters
     * @param string $msg       Error message, or a portion of it if the message
     *                          is to be generated
     * @param array  $repackage If this error re-packages an error pushed by
     *                          another package, place the array returned from
     *                          {@link pop()} in this parameter
     * @param array  $backtrace Protected parameter: use this to pass in the
     *                          {@link debug_backtrace()} that should be used
     *                          to find error context
     * @return PEAR_Error|array if compatibility mode is on, a PEAR_Error is also
     * thrown.  If a PEAR_Error is returned, the userinfo
     * property is set to the following array:
     *
     *
     * array(
     *    'code' => $code,
     *    'params' => $params,
     *    'package' => $this->_package,
     *    'level' => $level,
     *    'time' => time(),
     *    'context' => $context,
     *    'message' => $msg,
     * //['repackage' => $err] repackaged error array/Exception class
     * );
     *
     *
     * Normally, the previous array is returned.
     */
    function push($code, $level = 'error', $params = array(), $msg = false,
                  $repackage = false, $backtrace = false)
    {
        $context = false;
        // grab error context
        if ($this->_contextCallback) {
            if (!$backtrace) {
                $backtrace = debug_backtrace();
            }
            $context = call_user_func($this->_contextCallback, $code, $params, $backtrace);
        }

        // save error
        $time = explode(' ', microtime());
        $time = $time[1] + $time[0];
        $err = array(
                'code' => $code,
                'params' => $params,
                'package' => $this->_package,
                'level' => $level,
                'time' => $time,
                'context' => $context,
                'message' => $msg,
               );

        if ($repackage) {
            $err['repackage'] = $repackage;
        }

        // set up the error message, if necessary
        if ($this->_msgCallback) {
            $msg = call_user_func_array($this->_msgCallback,
                                        array(&$this, $err));
            $err['message'] = $msg;
        }
        $push = $log = true;
        $die = false;
        // try the overriding callback first
        $callback = $this->staticPopCallback();
        if ($callback) {
            $this->staticPushCallback($callback);
        }
        if (!is_callable($callback)) {
            // try the local callback next
            $callback = $this->popCallback();
            if (is_callable($callback)) {
                $this->pushCallback($callback);
            } else {
                // try the default callback
                $callback = isset($GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$this->_package]) ?
                    $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$this->_package] :
                    $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK']['*'];
            }
        }
        if (is_callable($callback)) {
            switch(call_user_func($callback, $err)){
            	case PEAR_ERRORSTACK_IGNORE:
            		return $err;
        		break;
            	case PEAR_ERRORSTACK_PUSH:
            		$log = false;
        		break;
            	case PEAR_ERRORSTACK_LOG:
            		$push = false;
        		break;
            	case PEAR_ERRORSTACK_DIE:
            		$die = true;
        		break;
                // anything else returned has the same effect as pushandlog
            }
        }
        if ($push) {
            array_unshift($this->_errors, $err);
            if (!isset($this->_errorsByLevel[$err['level']])) {
                $this->_errorsByLevel[$err['level']] = array();
            }
            $this->_errorsByLevel[$err['level']][] = &$this->_errors[0];
        }
        if ($log) {
            if ($this->_logger || $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER']) {
                $this->_log($err);
            }
        }
        if ($die) {
            die();
        }
        if ($this->_compat && $push) {
            return $this->raiseError($msg, $code, null, null, $err);
        }
        return $err;
    }

    /**
     * Static version of {@link push()}
     *
     * @param string $package   Package name this error belongs to
     * @param int    $code      Package-specific error code
     * @param string $level     Error level.  This is NOT spell-checked
     * @param array  $params    associative array of error parameters
     * @param string $msg       Error message, or a portion of it if the message
     *                          is to be generated
     * @param array  $repackage If this error re-packages an error pushed by
     *                          another package, place the array returned from
     *                          {@link pop()} in this parameter
     * @param array  $backtrace Protected parameter: use this to pass in the
     *                          {@link debug_backtrace()} that should be used
     *                          to find error context
     * @return PEAR_Error|array if compatibility mode is on, a PEAR_Error is also
     *                          thrown.  see docs for {@link push()}
     * @static
     */
    function staticPush($package, $code, $level = 'error', $params = array(),
                        $msg = false, $repackage = false, $backtrace = false)
    {
        $s = &PEAR_ErrorStack::singleton($package);
        if ($s->_contextCallback) {
            if (!$backtrace) {
                if (function_exists('debug_backtrace')) {
                    $backtrace = debug_backtrace();
                }
            }
        }
        return $s->push($code, $level, $params, $msg, $repackage, $backtrace);
    }

    /**
     * Log an error using PEAR::Log
     * @param array $err Error array
     * @param array $levels Error level => Log constant map
     * @access protected
     */
    function _log($err)
    {
        if ($this->_logger) {
            $logger = &$this->_logger;
        } else {
            $logger = &$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'];
        }
        if (is_a($logger, 'Log')) {
            $levels = array(
                'exception' => PEAR_LOG_CRIT,
                'alert' => PEAR_LOG_ALERT,
                'critical' => PEAR_LOG_CRIT,
                'error' => PEAR_LOG_ERR,
                'warning' => PEAR_LOG_WARNING,
                'notice' => PEAR_LOG_NOTICE,
                'info' => PEAR_LOG_INFO,
                'debug' => PEAR_LOG_DEBUG);
            if (isset($levels[$err['level']])) {
                $level = $levels[$err['level']];
            } else {
                $level = PEAR_LOG_INFO;
            }
            $logger->log($err['message'], $level, $err);
        } else { // support non-standard logs
            call_user_func($logger, $err);
        }
    }

    /**
     * Pop an error off of the error stack
     *
     * @return false|array
     * @since 0.4alpha it is no longer possible to specify a specific error
     * level to return - the last error pushed will be returned, instead
     */
    function pop()
    {
        $err = @array_shift($this->_errors);
        if (!is_null($err)) {
            @array_pop($this->_errorsByLevel[$err['level']]);
            if (!count($this->_errorsByLevel[$err['level']])) {
                unset($this->_errorsByLevel[$err['level']]);
            }
        }
        return $err;
    }

    /**
     * Pop an error off of the error stack, static method
     *
     * @param string package name
     * @return boolean
     * @since PEAR1.5.0a1
     */
    function staticPop($package)
    {
        if ($package) {
            if (!isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) {
                return false;
            }
            return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->pop();
        }
    }

    /**
     * Determine whether there are any errors on the stack
     * @param string|array Level name.  Use to determine if any errors
     * of level (string), or levels (array) have been pushed
     * @return boolean
     */
    function hasErrors($level = false)
    {
        if ($level) {
            return isset($this->_errorsByLevel[$level]);
        }
        return count($this->_errors);
    }

    /**
     * Retrieve all errors since last purge
     *
     * @param boolean set in order to empty the error stack
     * @param string level name, to return only errors of a particular severity
     * @return array
     */
    function getErrors($purge = false, $level = false)
    {
        if (!$purge) {
            if ($level) {
                if (!isset($this->_errorsByLevel[$level])) {
                    return array();
                } else {
                    return $this->_errorsByLevel[$level];
                }
            } else {
                return $this->_errors;
            }
        }
        if ($level) {
            $ret = $this->_errorsByLevel[$level];
            foreach ($this->_errorsByLevel[$level] as $i => $unused) {
                // entries are references to the $_errors array
                $this->_errorsByLevel[$level][$i] = false;
            }
            // array_filter removes all entries === false
            $this->_errors = array_filter($this->_errors);
            unset($this->_errorsByLevel[$level]);
            return $ret;
        }
        $ret = $this->_errors;
        $this->_errors = array();
        $this->_errorsByLevel = array();
        return $ret;
    }

    /**
     * Determine whether there are any errors on a single error stack, or on any error stack
     *
     * The optional parameter can be used to test the existence of any errors without the need of
     * singleton instantiation
     * @param string|false Package name to check for errors
     * @param string Level name to check for a particular severity
     * @return boolean
     * @static
     */
    function staticHasErrors($package = false, $level = false)
    {
        if ($package) {
            if (!isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) {
                return false;
            }
            return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->hasErrors($level);
        }
        foreach ($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] as $package => $obj) {
            if ($obj->hasErrors($level)) {
                return true;
            }
        }
        return false;
    }

    /**
     * Get a list of all errors since last purge, organized by package
     * @since PEAR 1.4.0dev BC break! $level is now in the place $merge used to be
     * @param boolean $purge Set to purge the error stack of existing errors
     * @param string  $level Set to a level name in order to retrieve only errors of a particular level
     * @param boolean $merge Set to return a flat array, not organized by package
     * @param array   $sortfunc Function used to sort a merged array - default
     *        sorts by time, and should be good for most cases
     * @static
     * @return array
     */
    function staticGetErrors($purge = false, $level = false, $merge = false,
                             $sortfunc = array('PEAR_ErrorStack', '_sortErrors'))
    {
        $ret = array();
        if (!is_callable($sortfunc)) {
            $sortfunc = array('PEAR_ErrorStack', '_sortErrors');
        }
        foreach ($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] as $package => $obj) {
            $test = $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->getErrors($purge, $level);
            if ($test) {
                if ($merge) {
                    $ret = array_merge($ret, $test);
                } else {
                    $ret[$package] = $test;
                }
            }
        }
        if ($merge) {
            usort($ret, $sortfunc);
        }
        return $ret;
    }

    /**
     * Error sorting function, sorts by time
     * @access private
     */
    function _sortErrors($a, $b)
    {
        if ($a['time'] == $b['time']) {
            return 0;
        }
        if ($a['time'] < $b['time']) {
            return 1;
        }
        return -1;
    }

    /**
     * Standard file/line number/function/class context callback
     *
     * This function uses a backtrace generated from {@link debug_backtrace()}
     * and so will not work at all in PHP < 4.3.0.  The frame should
     * reference the frame that contains the source of the error.
     * @return array|false either array('file' => file, 'line' => line,
     *         'function' => function name, 'class' => class name) or
     *         if this doesn't work, then false
     * @param unused
     * @param integer backtrace frame.
     * @param array Results of debug_backtrace()
     * @static
     */
    function getFileLine($code, $params, $backtrace = null)
    {
        if ($backtrace === null) {
            return false;
        }
        $frame = 0;
        $functionframe = 1;
        if (!isset($backtrace[1])) {
            $functionframe = 0;
        } else {
            while (isset($backtrace[$functionframe]['function']) &&
                  $backtrace[$functionframe]['function'] == 'eval' &&
                  isset($backtrace[$functionframe + 1])) {
                $functionframe++;
            }
        }
        if (isset($backtrace[$frame])) {
            if (!isset($backtrace[$frame]['file'])) {
                $frame++;
            }
            $funcbacktrace = $backtrace[$functionframe];
            $filebacktrace = $backtrace[$frame];
            $ret = array('file' => $filebacktrace['file'],
                         'line' => $filebacktrace['line']);
            // rearrange for eval'd code or create function errors
            if (strpos($filebacktrace['file'], '(') &&
            	  preg_match(';^(.*?)\((\d+)\) : (.*?)\\z;', $filebacktrace['file'],
                  $matches)) {
                $ret['file'] = $matches[1];
                $ret['line'] = $matches[2] + 0;
            }
            if (isset($funcbacktrace['function']) && isset($backtrace[1])) {
                if ($funcbacktrace['function'] != 'eval') {
                    if ($funcbacktrace['function'] == '__lambda_func') {
                        $ret['function'] = 'create_function() code';
                    } else {
                        $ret['function'] = $funcbacktrace['function'];
                    }
                }
            }
            if (isset($funcbacktrace['class']) && isset($backtrace[1])) {
                $ret['class'] = $funcbacktrace['class'];
            }
            return $ret;
        }
        return false;
    }

    /**
     * Standard error message generation callback
     *
     * This method may also be called by a custom error message generator
     * to fill in template values from the params array, simply
     * set the third parameter to the error message template string to use
     *
     * The special variable %__msg% is reserved: use it only to specify
     * where a message passed in by the user should be placed in the template,
     * like so:
     *
     * Error message: %msg% - internal error
     *
     * If the message passed like so:
     *
     *
     * $stack->push(ERROR_CODE, 'error', array(), 'server error 500');
     *
     *
     * The returned error message will be "Error message: server error 500 -
     * internal error"
     * @param PEAR_ErrorStack
     * @param array
     * @param string|false Pre-generated error message template
     * @static
     * @return string
     */
    function getErrorMessage(&$stack, $err, $template = false)
    {
        if ($template) {
            $mainmsg = $template;
        } else {
            $mainmsg = $stack->getErrorMessageTemplate($err['code']);
        }
        $mainmsg = str_replace('%__msg%', $err['message'], $mainmsg);
        if (is_array($err['params']) && count($err['params'])) {
            foreach ($err['params'] as $name => $val) {
                if (is_array($val)) {
                    // @ is needed in case $val is a multi-dimensional array
                    $val = @implode(', ', $val);
                }
                if (is_object($val)) {
                    if (method_exists($val, '__toString')) {
                        $val = $val->__toString();
                    } else {
                        PEAR_ErrorStack::staticPush('PEAR_ErrorStack', PEAR_ERRORSTACK_ERR_OBJTOSTRING,
                            'warning', array('obj' => get_class($val)),
                            'object %obj% passed into getErrorMessage, but has no __toString() method');
                        $val = 'Object';
                    }
                }
                $mainmsg = str_replace('%' . $name . '%', $val, $mainmsg);
            }
        }
        return $mainmsg;
    }

    /**
     * Standard Error Message Template generator from code
     * @return string
     */
    function getErrorMessageTemplate($code)
    {
        if (!isset($this->_errorMsgs[$code])) {
            return '%__msg%';
        }
        return $this->_errorMsgs[$code];
    }

    /**
     * Set the Error Message Template array
     *
     * The array format must be:
     *

     * array(error code => 'message template',...)
     *

     *
     * Error message parameters passed into {@link push()} will be used as input
     * for the error message.  If the template is 'message %foo% was %bar%', and the
     * parameters are array('foo' => 'one', 'bar' => 'six'), the error message returned will
     * be 'message one was six'
     * @return string
     */
    function setErrorMessageTemplate($template)
    {
        $this->_errorMsgs = $template;
    }

    /**
     * emulate PEAR::raiseError()
     *
     * @return PEAR_Error
     */
    function raiseError()
    {
        require_once 'PEAR.php';
        $args = func_get_args();
        return call_user_func_array(array('PEAR', 'raiseError'), $args);
    }
}
$stack = &PEAR_ErrorStack::singleton('PEAR_ErrorStack');
$stack->pushCallback(array('PEAR_ErrorStack', '_handleError'));
?>


<?php

namespace Simply\Container;

use Simply\Container\Entry\CallableEntry;
use Simply\Container\Entry\MixedEntry;
use Simply\Container\Entry\ProviderEntry;
use Simply\Container\Entry\WiredEntry;
use Simply\Container\Exception\ContainerException;

/**
 * Class that provides convenience functionality for setting up containers.
 *
 * @author Riikka Kalliomäki <riikka.kalliomaki@gmail.com>
 * @copyright Copyright (c) 2018 Riikka Kalliomäki
 * @license http://opensource.org/licenses/mit-license.php MIT License
 */
class ContainerBuilder
{
    /** @var Container The container that is being built */
    private $container;

    /**
     * ContainerBuilder constructor.
     */
    public function __construct()
    {
        $this->container = new Container();
    }

    /**
     * Returns the container that is being built.
     * @return Container The container that is being built
     */
    public function getContainer(): Container
    {
        return $this->container;
    }

    /**
     * Registers an array with identifier value pairs to the container as mixed entries.
     * @param array $configuration The configuration array to register
     * @throws ContainerException If trying to register values that already exist
     */
    public function registerConfiguration(array $configuration): void
    {
        foreach ($configuration as $identifier => $value) {
            $this->container->addEntry($identifier, new MixedEntry($value));
        }
    }

    /**
     * Registers the given provider as a callable and applicable methods as provider methods.
     * @param EntryProvider $provider The entry provider to register
     * @throws ContainerException If the provider tries to provide something that has already been registered
     */
    public function registerProvider(EntryProvider $provider): void
    {
        $class = \get_class($provider);

        $this->container->addEntry($class, new CallableEntry([\get_class($provider), 'initialize']));

        foreach ($provider->getMethods() as $identifier => $method) {
            $this->container->addEntry($identifier, new ProviderEntry([$provider, $method]));
        }
    }

    /**
     * Registers classes that can be wired automatically based on constructor arguments.
     * @param string[] $classes List of classes to register for autowiring
     * @param string[] $overrides Override identifiers for constructor parameters
     * @throws ContainerException If trying to register classes that have already been registered
     */
    public function registerAutowiredClasses(array $classes, array $overrides = []): void
    {
        foreach ($classes as $class) {
            $reflection = new \ReflectionClass($class);
            $name = $reflection->getName();
            $parameters = $this->getWiredParameters($reflection, $overrides);

            $this->container->addEntry($name, new WiredEntry($name, $parameters));
        }
    }

    /**
     * Loads the parameter identifiers based on the constructor arguments and provided overrides.
     * @param \ReflectionClass $reflection The class reflection to inspect
     * @param string[] $overrides Override identifiers for constructor parameters
     * @return string[] Identifiers for constructor parameters
     */
    private function getWiredParameters(\ReflectionClass $reflection, array $overrides): array
    {
        $constructor = $reflection->getConstructor();

        if (!$constructor instanceof \ReflectionMethod) {
            return [];
        }

        $parameters = [];

        foreach ($constructor->getParameters() as $parameter) {
            $name = '$' . $parameter->getName();

            if (isset($overrides[$name])) {
                $parameters[] = $overrides[$name];
                continue;
            }

            $type = $parameter->getType();

            if (!$type instanceof \ReflectionType || $type->isBuiltin()) {
                throw new \InvalidArgumentException(
                    sprintf("Missing autowired parameter '%s' for '%s'", $name, $reflection->getName())
                );
            }

            $parameters[] = $type->getName();
        }

        return $parameters;
    }
}


<?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_Filter
 * @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: Tar.php 24593 2012-01-05 20:35:02Z matthew $
 */

/**
 * @see Zend_Filter_Compress_CompressAbstract
 */

/**
 * Compression adapter for Tar
 *
 * @category   Zend
 * @package    Zend_Filter
 * @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 Zend_Filter_Compress_Tar extends Zend_Filter_Compress_CompressAbstract
{
    /**
     * Compression Options
     * array(
     *     'archive'  => Archive to use
     *     'target'   => Target to write the files to
     * )
     *
     * @var array
     */
    protected $_options = array(
        'archive'  => null,
        'target'   => '.',
        'mode'     => null,
    );

    /**
     * Class constructor
     *
     * @param array $options (Optional) Options to set
     */
    public function __construct($options = null)
    {
        if (!class_exists('Archive_Tar')) {

            try {
                Zend_Loader::loadClass('Archive_Tar');
            } catch (Zend_Exception $e) {

                throw new Zend_Filter_Exception('This filter needs PEARs Archive_Tar', 0, $e);
            }
        }

        parent::__construct($options);
    }

    /**
     * Returns the set archive
     *
     * @return string
     */
    public function getArchive()
    {
        return $this->_options['archive'];
    }

    /**
     * Sets the archive to use for de-/compression
     *
     * @param string $archive Archive to use
     * @return Zend_Filter_Compress_Tar
     */
    public function setArchive($archive)
    {
        $archive = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $archive);
        $this->_options['archive'] = (string) $archive;

        return $this;
    }

    /**
     * Returns the set targetpath
     *
     * @return string
     */
    public function getTarget()
    {
        return $this->_options['target'];
    }

    /**
     * Sets the targetpath to use
     *
     * @param string $target
     * @return Zend_Filter_Compress_Tar
     */
    public function setTarget($target)
    {
        if (!file_exists(dirname($target))) {

            throw new Zend_Filter_Exception("The directory '$target' does not exist");
        }

        $target = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $target);
        $this->_options['target'] = (string) $target;
        return $this;
    }

    /**
     * Returns the set compression mode
     */
    public function getMode()
    {
        return $this->_options['mode'];
    }

    /**
     * Compression mode to use
     * Eighter Gz or Bz2
     *
     * @param string $mode
     */
    public function setMode($mode)
    {
        $mode = ucfirst(strtolower($mode));
        if (($mode != 'Bz2') && ($mode != 'Gz')) {

            throw new Zend_Filter_Exception("The mode '$mode' is unknown");
        }

        if (($mode == 'Bz2') && (!extension_loaded('bz2'))) {

            throw new Zend_Filter_Exception('This mode needs the bz2 extension');
        }

        if (($mode == 'Gz') && (!extension_loaded('zlib'))) {

            throw new Zend_Filter_Exception('This mode needs the zlib extension');
        }
    }

    /**
     * Compresses the given content
     *
     * @param  string $content
     * @return string
     */
    public function compress($content)
    {
        $archive = new Archive_Tar($this->getArchive(), $this->getMode());
        if (!file_exists($content)) {
            $file = $this->getTarget();
            if (is_dir($file)) {
                $file .= DIRECTORY_SEPARATOR . "tar.tmp";
            }

            $result = file_put_contents($file, $content);
            if ($result === false) {

                throw new Zend_Filter_Exception('Error creating the temporary file');
            }

            $content = $file;
        }

        if (is_dir($content)) {
            // collect all file infos
            foreach (new RecursiveIteratorIterator(
                        new RecursiveDirectoryIterator($content, RecursiveDirectoryIterator::KEY_AS_PATHNAME),
                        RecursiveIteratorIterator::SELF_FIRST
                    ) as $directory => $info
            ) {
                if ($info->isFile()) {
                    $file[] = $directory;
                }
            }

            $content = $file;
        }

        $result  = $archive->create($content);
        if ($result === false) {

            throw new Zend_Filter_Exception('Error creating the Tar archive');
        }

        return $this->getArchive();
    }

    /**
     * Decompresses the given content
     *
     * @param  string $content
     * @return boolean
     */
    public function decompress($content)
    {
        $archive = $this->getArchive();
        if (file_exists($content)) {
            $archive = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, realpath($content));
        } elseif (empty($archive) || !file_exists($archive)) {

            throw new Zend_Filter_Exception('Tar Archive not found');
        }

        $archive = new Archive_Tar($archive, $this->getMode());
        $target  = $this->getTarget();
        if (!is_dir($target)) {
            $target = dirname($target);
        }

        $result = $archive->extract($target);
        if ($result === false) {

            throw new Zend_Filter_Exception('Error while extracting the Tar archive');
        }

        return true;
    }

    /**
     * Returns the adapter name
     *
     * @return string
     */
    public function toString()
    {
        return 'Tar';
    }
}


<?php

namespace Think;

/**
 * 视图类
 * Class View
 * @package Think
 */
final class View
{
    /**
     * 模板输出变量
     * @var $tVar
     */
    protected $tVar = [];

    /**
     * 模板主题
     * @var $theme

     */
    protected $theme = '';

    /**
     * 模板变量赋值
     *
     * @param mixed $name
     * @param mixed $value
     */
    public function assign($name, $value = '')
    {
        if (is_array($name)) {
            $this->tVar = array_merge($this->tVar, $name);
        } else {
            $this->tVar[$name] = $value;
        }
    }

    /**
     * 取得模板变量的值
     *
     * @param string $name
     *
     * @return mixed
     */
    public function get($name = '')
    {
        if ('' === $name) {
            return $this->tVar;
        }

        return isset($this->tVar[$name]) ? $this->tVar[$name] : false;
    }

    /**
     * 加载模板和页面输出 可以返回输出内容
     *
     * @param string $templateFile 模板文件名
     * @param string $charset 模板输出字符集
     * @param string $contentType 输出类型
     * @param string $content 模板输出内容
     * @param string $prefix 模板缓存前缀
     *
     * @return void
     * @throws BaseException
     */
    public function display($templateFile = '', $charset = '', $contentType = '', $content = '', $prefix = '')
    {
        G('viewStartTime');
        // 视图开始标签
        Hook::listen('view_begin', $templateFile);
        // 解析并获取模板内容
        $content = $this->fetch($templateFile, $content, $prefix);
        // 输出模板内容
        $this->render($content, $charset, $contentType);
        // 视图结束标签
        Hook::listen('view_end');
    }

    /**
     * 输出内容文本可以包括Html
     *
     * @param string $content 输出内容
     * @param string $charset 模板输出字符集
     * @param string $contentType 输出类型
     *
     * @return void
     */
    private function render($content, $charset = '', $contentType = '')
    {
        if (empty($charset)) {
            $charset = C('DEFAULT_CHARSET');
        }
        if (empty($contentType)) {
            $contentType = C('TMPL_CONTENT_TYPE');
        }
        if (!headers_sent()) {
            // 网页字符编码
            header('Content-Type:'.$contentType.'; charset='.$charset);
            // 页面缓存控制
            header('Cache-control: '.C('HTTP_CACHE_CONTROL'));
            header('X-Powered-By:CheukPang');
        }
        // 输出模板文件
        echo $content;
    }

    /**
     * 解析和获取模板内容 用于输出
     *
     * @param string $templateFile 模板文件名
     * @param string $content 模板输出内容
     * @param string $prefix 模板缓存前缀
     * @return string
     * @throws BaseException
     */
    public function fetch($templateFile = '', $content = '', $prefix = '')
    {
        if (empty($content)) {
            $templateFile = $this->parseTemplate($templateFile);
            // 模板文件不存在直接返回
            if (!is_file($templateFile)) {
                throw new BaseException(L('_TEMPLATE_NOT_EXIST_').':'.$templateFile);
            }
        } else {
            defined('THEME_PATH') || define('THEME_PATH', $this->getThemePath());
        }
        // 页面缓存
        ob_start();
        ob_implicit_flush(0);
        // 使用PHP原生模板
        if ('php' == strtolower(C('TMPL_ENGINE_TYPE'))) {
            $_content = $content;
            // 模板阵列变量分解成为独立变量
            extract($this->tVar, EXTR_OVERWRITE);
            // 直接载入PHP模板
            /** @noinspection PhpIncludeInspection */
            empty($_content) ? include $templateFile : eval('?>'.$_content);
        } else {
            // 视图解析标签
            $params = ['var' => $this->tVar, 'file' => $templateFile, 'content' => $content, 'prefix' => $prefix];
            Hook::listen('view_parse', $params);
        }
        // 获取并清空缓存
        $content = ob_get_clean();
        // 内容过滤标签
        Hook::listen('view_filter', $content);

        // 输出模板文件
        return $content;
    }

    /**
     * 自动定位模板文件
     *
     * @param string $template 模板文件规则
     *
     * @return string
     */
    public function parseTemplate($template = '')
    {
        if (is_file($template)) {
            return $template;
        }
        $depr = C('TMPL_FILE_DEPR');
        $template = str_replace(':', $depr, $template);

        // 获取当前模块
        $module = MODULE_NAME;
        // 跨模块调用模版文件
        if (strpos($template, '@')) {
            list($module, $template) = explode('@', $template);
        }
        // 获取当前主题的模版路径
        defined('THEME_PATH') || define('THEME_PATH', $this->getThemePath($module));

        // 分析模板文件规则
        if ('' == $template) {
            // 如果模板文件名为空 按照默认规则定位
            $template = CONTROLLER_NAME.$depr.ACTION_NAME;
        } elseif (false === strpos($template, $depr)) {
            $template = CONTROLLER_NAME.$depr.$template;
        }
        $file = THEME_PATH.$template.C('TMPL_TEMPLATE_SUFFIX');
        if (C('TMPL_LOAD_DEFAULTTHEME') && THEME_NAME != C('DEFAULT_THEME') && !is_file($file)) {
            // 找不到当前主题模板的时候定位默认主题中的模板
            $file = dirname(THEME_PATH).'/'.C('DEFAULT_THEME').'/'.$template.C('TMPL_TEMPLATE_SUFFIX');
        }

        return $file;
    }

    /**
     * 获取当前的模板路径
     *
     * @param mixed|string $module 模块名
     *
     * @return string
     */
    protected function getThemePath($module = MODULE_NAME)
    {
        // 获取当前主题名称
        $_theme = $this->getTemplateTheme();
        // 获取当前主题的模版路径
        // 模块设置独立的视图目录
        $tmplPath = C('VIEW_PATH');
        if (!$tmplPath) {
            // 定义TMPL_PATH 则改变全局的视图目录到模块之外
            $tmplPath = defined('TMPL_PATH') ? TMPL_PATH.$module.'/' : APP_PATH.$module.'/'.C(
                    'DEFAULT_V_LAYER'
                ).'/';
        }

        return $tmplPath.$_theme;
    }

    /**
     * 设置当前输出的模板主题
     *
     * @param  mixed $theme 主题名称
     *
     * @return $this
     */
    public function theme($theme)
    {
        $this->theme = $theme;

        return $this;
    }

    /**
     * 获取当前的模板主题
     * @return string
     */
    private function getTemplateTheme()
    {
        // 指定模板主题
        if ($this->theme) {
            $_theme = $this->theme;
        } else {
            /* 获取模板主题名称 */
            $_theme = C('DEFAULT_THEME');
            // 自动侦测模板主题
            if (C('TMPL_DETECT_THEME')) {
                $t = C('VAR_TEMPLATE');
                if (isset($_GET[$t])) {
                    $_theme = $_GET[$t];
                } elseif (cookie('think_template')) {
                    $_theme = cookie('think_template');
                }
                if (!in_array($_theme, explode(',', C('THEME_LIST')))) {
                    $_theme = C('DEFAULT_THEME');
                }
                cookie('think_template', $_theme, 864000);
            }
        }
        // 当前模板主题名称
        defined('THEME_NAME') || define('THEME_NAME', $_theme);

        return $_theme ? $_theme.'/' : '';
    }

}


<?php

namespace Ekyna\Bundle\CoreBundle\Validator\Constraints;

use Ekyna\Bundle\CoreBundle\Model\AddressInterface;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Symfony\Component\Validator\Exception\UnexpectedTypeException;

/**
 * Class AddressValidator
 * @package Ekyna\Bundle\CoreBundle\Validator\Constraints
 * @author Étienne Dauvergne <contact@ekyna.com>
 */
class AddressValidator extends ConstraintValidator
{
    /**
     * @var array
     * @see http://unicode.org/cldr/trac/browser/trunk/common/supplemental/postalCodeData.xml
     */
    private $zipRegex = [
        'GB' => 'GIR[ ]?0AA|((AB|AL|B|BA|BB|BD|BH|BL|BN|BR|BS|BT|CA|CB|CF|CH|CM|CO|CR|CT|CV|CW|DA|DD|DE|DG|DH|DL|DN|DT|DY|E|EC|EH|EN|EX|FK|FY|G|GL|GY|GU|HA|HD|HG|HP|HR|HS|HU|HX|IG|IM|IP|IV|JE|KA|KT|KW|KY|L|LA|LD|LE|LL|LN|LS|LU|M|ME|MK|ML|N|NE|NG|NN|NP|NR|NW|OL|OX|PA|PE|PH|PL|PO|PR|RG|RH|RM|S|SA|SE|SG|SK|SL|SM|SN|SO|SP|SR|SS|ST|SW|SY|TA|TD|TF|TN|TQ|TR|TS|TW|UB|W|WA|WC|WD|WF|WN|WR|WS|WV|YO|ZE)(\d[\dA-Z]?[ ]?\d[ABD-HJLN-UW-Z]{2}))|BFPO[ ]?\d{1,4}',
        'JE' => 'JE\d[\dA-Z]?[ ]?\d[ABD-HJLN-UW-Z]{2}',
        'GG' => 'GY\d[\dA-Z]?[ ]?\d[ABD-HJLN-UW-Z]{2}',
        'IM' => 'IM\d[\dA-Z]?[ ]?\d[ABD-HJLN-UW-Z]{2}',
        'US' => '\d{5}([ \-]\d{4})?',
        'CA' => '[ABCEGHJKLMNPRSTVXY]\d[ABCEGHJ-NPRSTV-Z][ ]?\d[ABCEGHJ-NPRSTV-Z]\d',
        'DE' => '\d{5}',
        'JP' => '\d{3}-\d{4}',
        'FR' => '((0[1-9])|([1-8][0-9])|(9[0-8])|(2A)|(2B))[0-9]{3}', // improved
        'AU' => '\d{4}',
        'IT' => '\d{5}',
        'CH' => '\d{4}',
        'AT' => '\d{4}',
        'ES' => '\d{5}',
        'NL' => '\d{4}[ ]?[A-Z]{2}',
        'BE' => '\d{4}',
        'DK' => '\d{4}',
        'SE' => '\d{3}[ ]?\d{2}',
        'NO' => '\d{4}',
        'BR' => '\d{5}[\-]?\d{3}',
        'PT' => '\d{4}([\-]\d{3})?',
        'FI' => '\d{5}',
        'AX' => '22\d{3}',
        'KR' => '\d{3}[\-]\d{3}',
        'CN' => '\d{6}',
        'TW' => '\d{3}(\d{2})?',
        'SG' => '\d{6}',
        'DZ' => '\d{5}',
        'AD' => 'AD\d{3}',
        'AR' => '([A-HJ-NP-Z])?\d{4}([A-Z]{3})?',
        'AM' => '(37)?\d{4}',
        'AZ' => '\d{4}',
        'BH' => '((1[0-2]|[2-9])\d{2})?',
        'BD' => '\d{4}',
        'BB' => '(BB\d{5})?',
        'BY' => '\d{6}',
        'BM' => '[A-Z]{2}[ ]?[A-Z0-9]{2}',
        'BA' => '\d{5}',
        'IO' => 'BBND 1ZZ',
        'BN' => '[A-Z]{2}[ ]?\d{4}',
        'BG' => '\d{4}',
        'KH' => '\d{5}',
        'CV' => '\d{4}',
        'CL' => '\d{7}',
        'CR' => '\d{4,5}|\d{3}-\d{4}',
        'HR' => '\d{5}',
        'CY' => '\d{4}',
        'CZ' => '\d{3}[ ]?\d{2}',
        'DO' => '\d{5}',
        'EC' => '([A-Z]\d{4}[A-Z]|(?:[A-Z]{2})?\d{6})?',
        'EG' => '\d{5}',
        'EE' => '\d{5}',
        'FO' => '\d{3}',
        'GE' => '\d{4}',
        'GR' => '\d{3}[ ]?\d{2}',
        'GL' => '39\d{2}',
        'GT' => '\d{5}',
        'HT' => '\d{4}',
        'HN' => '(?:\d{5})?',
        'HU' => '\d{4}',
        'IS' => '\d{3}',
        'IN' => '\d{6}',
        'ID' => '\d{5}',
        'IL' => '\d{5}',
        'JO' => '\d{5}',
        'KZ' => '\d{6}',
        'KE' => '\d{5}',
        'KW' => '\d{5}',
        'LA' => '\d{5}',
        'LV' => '\d{4}',
        'LB' => '(\d{4}([ ]?\d{4})?)?',
        'LI' => '(948[5-9])|(949[0-7])',
        'LT' => '\d{5}',
        'LU' => '\d{4}',
        'MK' => '\d{4}',
        'MY' => '\d{5}',
        'MV' => '\d{5}',
        'MT' => '[A-Z]{3}[ ]?\d{2,4}',
        'MU' => '(\d{3}[A-Z]{2}\d{3})?',
        'MX' => '\d{5}',
        'MD' => '\d{4}',
        'MC' => '980\d{2}',
        'MA' => '\d{5}',
        'NP' => '\d{5}',
        'NZ' => '\d{4}',
        'NI' => '((\d{4}-)?\d{3}-\d{3}(-\d{1})?)?',
        'NG' => '(\d{6})?',
        'OM' => '(PC )?\d{3}',
        'PK' => '\d{5}',
        'PY' => '\d{4}',
        'PH' => '\d{4}',
        'PL' => '\d{2}-\d{3}',
        'PR' => '00[679]\d{2}([ \-]\d{4})?',
        'RO' => '\d{6}',
        'RU' => '\d{6}',
        'SM' => '4789\d',
        'SA' => '\d{5}',
        'SN' => '\d{5}',
        'SK' => '\d{3}[ ]?\d{2}',
        'SI' => '\d{4}',
        'ZA' => '\d{4}',
        'LK' => '\d{5}',
        'TJ' => '\d{6}',
        'TH' => '\d{5}',
        'TN' => '\d{4}',
        'TR' => '\d{5}',
        'TM' => '\d{6}',
        'UA' => '\d{5}',
        'UY' => '\d{5}',
        'UZ' => '\d{6}',
        'VA' => '00120',
        'VE' => '\d{4}',
        'ZM' => '\d{5}',
        'AS' => '96799',
        'CC' => '6799',
        'CK' => '\d{4}',
        'RS' => '\d{6}',
        'ME' => '8\d{4}',
        'CS' => '\d{5}',
        'YU' => '\d{5}',
        'CX' => '6798',
        'ET' => '\d{4}',
        'FK' => 'FIQQ 1ZZ',
        'NF' => '2899',
        'FM' => '(9694[1-4])([ \-]\d{4})?',
        'GF' => '9[78]3\d{2}',
        'GN' => '\d{3}',
        'GP' => '9[78][01]\d{2}',
        'GS' => 'SIQQ 1ZZ',
        'GU' => '969[123]\d([ \-]\d{4})?',
        'GW' => '\d{4}',
        'HM' => '\d{4}',
        'IQ' => '\d{5}',
        'KG' => '\d{6}',
        'LR' => '\d{4}',
        'LS' => '\d{3}',
        'MG' => '\d{3}',
        'MH' => '969[67]\d([ \-]\d{4})?',
        'MN' => '\d{6}',
        'MP' => '9695[012]([ \-]\d{4})?',
        'MQ' => '9[78]2\d{2}',
        'NC' => '988\d{2}',
        'NE' => '\d{4}',
        'VI' => '008(([0-4]\d)|(5[01]))([ \-]\d{4})?',
        'PF' => '987\d{2}',
        'PG' => '\d{3}',
        'PM' => '9[78]5\d{2}',
        'PN' => 'PCRN 1ZZ',
        'PW' => '96940',
        'RE' => '9[78]4\d{2}',
        'SH' => '(ASCN|STHL) 1ZZ',
        'SJ' => '\d{4}',
        'SO' => '\d{5}',
        'SZ' => '[HLMS]\d{3}',
        'TC' => 'TKCA 1ZZ',
        'WF' => '986\d{2}',
        'XK' => '\d{5}',
        'YT' => '976\d{2}',
    ];

    /**
     * {@inheritdoc}
     */
    public function validate($address, Constraint $constraint)
    {
        if (!$address instanceof AddressInterface) {
            throw new UnexpectedTypeException($address, '\Ekyna\Bundle\CoreBundle\Model\AddressInterface');
        }
        if (!$constraint instanceof Address) {
            throw new UnexpectedTypeException($constraint, __NAMESPACE__ . '\Address');
        }

        /**
         * @var AddressInterface $address
         * @var Address $constraint
         */
        if (array_key_exists($address->getCountry(), $this->zipRegex)) {
            if (!preg_match("~^" . $this->zipRegex[$address->getCountry()] . "$~i", $address->getPostalCode())) {
                $this->context->addViolationAt('postalCode', $constraint->invalidPostalCode);
            }
        }
    }
}


<?php

namespace Tecnocreaciones\Vzla\GovernmentBundle\DependencyInjection;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\Loader;

/**
 * This is the class that loads and manages your bundle configuration
 *
 * To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html}
 */
class TecnocreacionesVzlaGovernmentExtension extends Extension
{
    /**
     * {@inheritDoc}
     */
    public function load(array $configs, ContainerBuilder $container)
    {
        $configuration = new Configuration();
        $config = $this->processConfiguration($configuration, $configs);

        $loader = new Loader\XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
        $loader->load('services.xml');
        $classMenuBuilder = $config['template']['developer']['menu'];

        $container->setParameter('tecnocreaciones_vzla_government.menu_builder.developer.class', $classMenuBuilder);

        $templatesConfig = array();
        $templatesConfig['developer']= $config['template']['developer'];
        $globalConfig = $container->getDefinition('tecnocreaciones_vzla_government.global_config');

        $globalConfig->addMethodCall('setTemplates',array($templatesConfig));
        $globalConfig->addMethodCall('setOptions',array($config['config']));

    }
}


<?php
namespace keeko\auth\action;

use keeko\framework\foundation\AbstractAction;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use keeko\framework\domain\payload\Found;

/**
 * Users Profile
 *
 * This code is automatically created. Modifications will probably be overwritten.
 */
class ProfileReadAction extends AbstractAction {

	/**
	 * Automatically generated run method
	 *
	 * @param Request $request
	 * @return Response
	 */
	public function run(Request $request) {
		$user = $this->getServiceContainer()->getAuthManager()->getUser();
		$payload = new Found(['model' => $user]);
		// note: $session must be not null for this action!
		return $this->responder->run($request, $payload);
	}
}


<?php

namespace Potherca\Katwizy\Immutable;

class Command
{
    ////////////////////////////// CLASS PROPERTIES \\\\\\\\\\\\\\\\\\\\\\\\\\\\
    /*/ const COMMAND_TYPE_COMPOSER = 'composer';/*/// Not yet implemented
    const COMMAND_TYPE_PHP = 'php'; // PHP static call = "Namespace\Class::method"
    const COMMAND_TYPE_SHELL = 'shell'; // <- normal command line calls
    const COMMAND_TYPE_SYMFONY = 'symfony'; // the command after `console`

    const ERROR_UNSUPPORTED_TYPE = 'Type must be one of "%s", "%s" given';

    /** @var string */
    private $callable;
    /** @var string */
    private $arguments;
    /** @var string */
    private $type;

    //////////////////////////// SETTERS AND GETTERS \\\\\\\\\\\\\\\\\\\\\\\\\\\
    /** @return string */
    public function getCallable()
    {
        return $this->callable;
    }

    /** @return string */
    public function getArguments()
    {
        return $this->arguments;
    }

    /** @return string */
    public function getType()
    {
        return $this->type;
    }

    //////////////////////////////// PUBLIC API \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
    /**
     * Command constructor.
     *
     * @param string $type
     * @param string $callable
     * @param array $arguments
     *
     * @throws \InvalidArgumentException
     */
    final public function __construct($type, $callable, array $arguments = [])
    {
        $this->validateType($type);

        $this->callable = $callable;
        $this->arguments = $arguments;
        $this->type = $type;
    }

    /**
     * @param string $type
     *
     * @throws \InvalidArgumentException
     */
    final public function validateType($type)
    {
        $class = new \ReflectionObject($this);
        $constants = $class->getConstants();

        if ($type !== null && in_array($type, $constants, true) === false) {
            throw new \InvalidArgumentException(
                sprintf(
                    self::ERROR_UNSUPPORTED_TYPE,
                    implode('", "', $constants),
                    $type
                )
            );
        }
    }
}

/*EOF*/


<?php

/*
 * This file is part of the Valkyrja framework.
 *
 * (c) Melech Mizrachi
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Valkyrja\Routing\Annotations;

use Valkyrja\Annotations\AnnotationsParser;
use Valkyrja\Annotations\NativeAnnotations;
use Valkyrja\Application;
use Valkyrja\Routing\Exceptions\InvalidRoutePath;
use Valkyrja\Routing\Route as RouterRoute;
use Valkyrja\Support\Providers\Provides;

/**
 * Class RouteAnnotations.
 *
 * @author Melech Mizrachi
 */
class NativeRouteAnnotations extends NativeAnnotations implements RouteAnnotations
{
    use Provides;

    /**
     * The route annotation type.
     *
     * @var string
     */
    protected $routeAnnotationType = 'Route';

    /**
     * Get routes.
     *
     * @param string[] $classes The classes
     *
     * @throws \InvalidArgumentException
     * @throws \ReflectionException
     * @throws \Valkyrja\Routing\Exceptions\InvalidRoutePath
     *
     * @return \Valkyrja\Routing\Route[]
     */
    public function getRoutes(string ...$classes): array
    {
        $routes = $this->getClassRoutes($classes);
        /** @var \Valkyrja\Routing\Route[] $finalRoutes */
        $finalRoutes = [];

        // Iterate through all the routes
        foreach ($routes as $route) {
            // Set the route's properties
            $this->setRouteProperties($route);

            $classAnnotations = $this->classAnnotationsType(
                $this->routeAnnotationType,
                $route->getClass()
            );

            // If this route's class has annotations
            if ($classAnnotations) {
                /** @var Route $annotation */
                // Iterate through all the annotations
                foreach ($classAnnotations as $annotation) {
                    // And set a new route with the controller defined annotation additions
                    $finalRoutes[] =
                        $this->getRouteFromAnnotation(
                            $this->getControllerBuiltRoute($annotation, $route)
                        );
                }
            } else {
                // Validate the path before setting the route
                $route->setPath($this->validatePath($route->getPath()));

                // Otherwise just set the route in the final array
                $finalRoutes[] = $this->getRouteFromAnnotation($route);
            }
        }

        return $finalRoutes;
    }

    /**
     * Set the route properties from arguments.
     *
     * @param Route $route
     *
     * @throws \ReflectionException
     * @throws \Valkyrja\Routing\Exceptions\InvalidRoutePath
     *
     * @return void
     */
    protected function setRouteProperties(Route $route): void
    {
        if (null === $route->getProperty()) {
            $methodReflection = $this->getMethodReflection(
                $route->getClass(),
                $route->getMethod() ?? '__construct'
            );

            // Set the dependencies
            $route->setDependencies(
                $this->getDependencies(...$methodReflection->getParameters())
            );
        }

        // Avoid having large arrays in cached routes file
        $route->setMatches();

        if (null === $route->getPath()) {
            throw new InvalidRoutePath(
                'Invalid route name for route : '
                . $route->getClass()
                . '@' . $route->getMethod()
            );
        }
    }

    /**
     * Get all classes' routes.
     *
     * @param array $classes The classes
     *
     * @throws \ReflectionException
     *
     * @return \Valkyrja\Routing\Route[]
     */
    protected function getClassRoutes(array $classes): array
    {
        /** @var \Valkyrja\Routing\Route[] $routes */
        $routes = [];

        // Iterate through all the classes
        foreach ($classes as $class) {
            $annotations = $this->classMembersAnnotationsType(
                $this->routeAnnotationType,
                $class
            );

            // Get all the routes for each class and iterate through them
            foreach ($annotations as $annotation) {
                // Set the annotation in the routes list
                $routes[] = $annotation;
            }
        }

        return $routes;
    }

    /**
     * Get a new route with controller route additions.
     *
     * @param Route $controllerRoute
     * @param Route $route
     *
     * @return \Valkyrja\Routing\Annotations\Route
     */
    protected function getControllerBuiltRoute(Route $controllerRoute, Route $route): Route
    {
        $newRoute = clone $route;

        // If there is a base path for this controller
        if (null !== $controllerRoute->getPath()) {
            // Get the route's path
            $path           = $this->validatePath($route->getPath());
            $controllerPath = $this->validatePath($controllerRoute->getPath());

            // Set the path to the base path and route path
            $newRoute->setPath($this->validatePath($controllerPath . $path));
        }

        // If there is a base name for this controller
        if (null !== $controllerRoute->getName()) {
            // Set the name to the base name and route name
            $newRoute->setName(
                $controllerRoute->getName() . '.' . $route->getName()
            );
        }

        // If the base is dynamic
        if (false !== $controllerRoute->isDynamic()) {
            // Set the route to dynamic
            $newRoute->setDynamic(true);
        }

        // If the base is secure
        if (false !== $controllerRoute->isSecure()) {
            // Set the route to dynamic
            $newRoute->setSecure(true);
        }

        // If there is a base middleware collection for this controller
        if (null !== $controllerRoute->getMiddleware()) {
            // Merge the route's middleware and the controller's middleware
            // keeping the controller's middleware first
            $middleware = array_merge(
                $controllerRoute->getMiddleware(),
                $route->getMiddleware() ?? []
            );

            // Set the middleware in the route
            $newRoute->setMiddleware($middleware);
        }

        return $newRoute;
    }

    /**
     * Validate a path.
     *
     * @param string $path The path
     *
     * @return string
     */
    protected function validatePath(string $path): string
    {
        // Trim slashes from the beginning and end of the path
        $path = trim($path, '/');

        // If the path only had a slash
        if (! $path) {
            // Return as just slash
            return '/';
        }

        // If the route doesn't begin with an optional or required group
        if ($path[0] !== '[' && $path[0] !== '<') {
            // Append a slash
            return '/' . $path;
        }

        return $path;
    }

    /**
     * Get a route from a route annotation.
     *
     * @param Route $route The route annotation
     *
     * @throws \InvalidArgumentException
     *
     * @return \Valkyrja\Routing\Route
     */
    protected function getRouteFromAnnotation(Route $route): RouterRoute
    {
        $routerRoute = new RouterRoute();

        $routerRoute
            ->setPath($route->getPath())
            ->setRegex($route->getRegex())
            ->setParams($route->getParams())
            ->setSegments($route->getSegments())
            ->setRequestMethods($route->getRequestMethods())
            ->setSecure($route->isSecure())
            ->setDynamic($route->isDynamic())
            ->setId($route->getId())
            ->setName($route->getName())
            ->setClass($route->getClass())
            ->setProperty($route->getProperty())
            ->setMethod($route->getMethod())
            ->setStatic($route->isStatic())
            ->setFunction($route->getFunction())
            ->setMatches($route->getMatches())
            ->setDependencies($route->getDependencies())
            ->setMiddleware($route->getMiddleware())
            ->setArguments($route->getArguments());

        return $routerRoute;
    }

    /**
     * The items provided by this provider.
     *
     * @return array
     */
    public static function provides(): array
    {
        return [
            RouteAnnotations::class,
        ];
    }

    /**
     * Bind the route annotations.
     *
     * @param Application $app The application
     *
     * @return void
     */
    public static function publish(Application $app): void
    {
        $app->container()->singleton(
            RouteAnnotations::class,
            new static(
                $app->container()->getSingleton(AnnotationsParser::class)
            )
        );
    }
}


<?php

namespace Reaction\Web\Formatters;

use Reaction;
use Reaction\Base\Component;
use Reaction\Helpers\Json;
use Reaction\Web\ResponseBuilderInterface;
use Reaction\Web\ResponseFormatterInterface;

/**
 * JsonResponseFormatter formats the given data into a JSON or JSONP response content.
 *
 * It is used by [[Response]] to format response data.
 *
 * To configure properties like [[encodeOptions]] or [[prettyPrint]], you can configure the `response`
 * application component like the following:
 *
 * ```php
 * 'response' => [
 *     // ...
 *     'formatters' => [
 *         \Reaction\Web\Response::FORMAT_JSON => [
 *              'class' => 'Reaction\Web\Formatters\JsonResponseFormatter',
 *              'prettyPrint' => Reaction::isDev(), // use "pretty" output in debug mode
 *              // ...
 *         ],
 *     ],
 * ],
 * ```
 */
class JsonResponseFormatter extends Component implements ResponseFormatterInterface
{
    /**
     * JSON Content Type
     */
    const CONTENT_TYPE_JSONP = 'application/javascript; charset=UTF-8';
    /**
     * JSONP Content Type
     */
    const CONTENT_TYPE_JSON = 'application/json; charset=UTF-8';
    /**
     * HAL JSON Content Type
     */
    const CONTENT_TYPE_HAL_JSON = 'application/hal+json; charset=UTF-8';

    /**
     * @var string|null custom value of the `Content-Type` header of the response.
     * When equals `null` default content type will be used based on the `useJsonp` property.
     * @since 2.0.14
     */
    public $contentType;
    /**
     * @var bool whether to use JSONP response format. When this is true, the [[Response::data|response data]]
     * must be an array consisting of `data` and `callback` members. The latter should be a JavaScript
     * function name while the former will be passed to this function as a parameter.
     */
    public $useJsonp = false;
    /**
     * @var int the encoding options passed to [[Json::encode()]]. For more details please refer to
     * <http://www.php.net/manual/en/function.json-encode.php>.
     * Default is `JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE`.
     * This property has no effect, when [[useJsonp]] is `true`.
     */
    public $encodeOptions = 320;
    /**
     * @var bool whether to format the output in a readable "pretty" format. This can be useful for debugging purpose.
     * If this is true, `JSON_PRETTY_PRINT` will be added to [[encodeOptions]].
     * Defaults to `false`.
     * This property has no effect, when [[useJsonp]] is `true`.
     */
    public $prettyPrint = false;

    /**
     * Formats the specified response.
     * @param ResponseBuilderInterface $response the response to be formatted.
     * @return string
     */
    public function format($response)
    {
        if ($this->contentType === null) {
            $this->contentType = $this->useJsonp
                ? self::CONTENT_TYPE_JSONP
                : self::CONTENT_TYPE_JSON;
        } elseif (strpos($this->contentType, 'charset') === false) {
            $this->contentType .= '; charset=UTF-8';
        }
        $response->getHeaders()->set('Content-Type', $this->contentType);

        if ($this->useJsonp) {
            return $this->formatJsonp($response);
        } else {
            return $this->formatJson($response);
        }
    }

    /**
     * Formats response data in JSON format.
     * @param ResponseBuilderInterface $response
     * @return string
     */
    protected function formatJson($response)
    {
        $bodyRaw = $response->getRawBody();
        if ($bodyRaw !== null) {
            $options = $this->encodeOptions;
            if ($this->prettyPrint) {
                $options |= JSON_PRETTY_PRINT;
            }
            return $response->app instanceof Reaction\RequestApplicationInterface
                ? $response->app->helpers->json->encode($bodyRaw, $options)
                : Json::encode($bodyRaw, $options);
        }
        return '';
    }

    /**
     * Formats response data in JSONP format.
     * @param ResponseBuilderInterface $response
     * @return string
     */
    protected function formatJsonp($response)
    {
        $bodyRaw = $response->getRawBody();
        if (is_array($bodyRaw)
            && isset($bodyRaw['data'], $bodyRaw['callback'])
        ) {
            $data = $response->app instanceof Reaction\RequestApplicationInterface
                ? $response->app->helpers->json->htmlEncode($bodyRaw['data'])
                : Json::htmlEncode($bodyRaw['data']);
            return sprintf('%s(%s);', $bodyRaw['callback'], $data);
        } elseif ($bodyRaw !== null) {
            Reaction::warning(
                "The 'jsonp' response requires that the data be an array consisting of both 'data' and 'callback' elements."
            );
        }
        return '';
    }
}


<?php

/*
 * This file is part of madewithlove/service-providers
 *
 * (c) madewithlove <heroes@madewithlove.be>
 *
 * For the full copyright and license information, please view the LICENSE
 */

namespace Madewithlove\ServiceProviders\Filesystem;

use Interop\Container\ServiceProviderInterface;
use League\Flysystem\AdapterInterface;
use League\Flysystem\Filesystem;
use League\Flysystem\FilesystemInterface;
use League\Flysystem\MountManager;
use Psr\Container\ContainerInterface;

class FlysystemServiceProvider implements ServiceProviderInterface
{
    /**
     * The default adapter to use.
     *
     * @var string
     */
    protected $default;

    /**
     * @var AdapterInterface[]
     */
    protected $adapters = [];

    /**
     * @param string $default
     * @param array  $adapters
     */
    public function __construct($default, array $adapters)
    {
        $this->default = $default;
        $this->adapters = $adapters;
    }

    /**
     * {@inheritdoc}
     */
    public function getServices()
    {
        return [
            MountManager::class => [$this, 'getMountManager'],
            FilesystemInterface::class => [$this, 'getFilesystem'],
        ];
    }

    /**
     * @return MountManager
     */
    public function getMountManager()
    {
        $adapters = array_map(function (AdapterInterface $adapter) {
            return new Filesystem($adapter);
        }, $this->adapters);

        return new MountManager($adapters);
    }

    /**
     * @param ContainerInterface $container
     *
     * @return FilesystemInterface
     */
    public function getFilesystem(ContainerInterface $container)
    {
        /** @var MountManager $mountManager */
        $mountManager = $container->get(MountManager::class);

        return $mountManager->getFilesystem($this->default);
    }
}