<?php
/**
 * Provides support for class members/properties maintain their initial types.
 *
 * @name           \Diskerror\Typed\TypedClass
 * @copyright      Copyright (c) 2012 Reid Woodbury Jr
 * @license        http://www.apache.org/licenses/LICENSE-2.0.html Apache License, Version 2.0
 */

namespace Diskerror\Typed;

use DateTimeInterface;
use InvalidArgumentException;
use Traversable;

/**
 * Create a child of this class with your named properties with a visibility of
 *      protected or private, and default values of the desired type. Property
 *      names CANNOT begin with an underscore. This maintains the Zend Framework
 *      convention that protected and private property names should begin with an
 *      underscore. This abstract class will expose all members whose name don't
 *      begin with an underscore, but filter access to those class members or
 *      properties that have a visibility of protected or private.
 *
 * Input to the constructor or assign methods must be an array or object. Only the
 *      values in the matching names will be filtered and copied into the object.
 *      All input will be copied by value, not referenced.
 *
 * This class will adds simple casting of input values to be the same type as the
 *      named property or member. This includes scalar values, built-in PHP classes,
 *      and other classes, especially those derived from this class.
 *
 * Only properties in the original child class are allowed. This prevents erroneously
 *      adding properties on the fly.
 *
 * More elaborate filtering can be done by creating methods with this naming
 *      convention: If property is called "personName" then create a method called
 *      "_set_personName($in)". That is, prepend "_set_" to the property name.
 *
 * The ideal usage of this abstract class is as the parent class of a data set
 *      where the input to the constructor (or assign) method is an HTTP request
 *      object. It will help with filtering and insuring the existence of default
 *      values for missing input parameters.
 */
abstract class TypedClass extends TypedAbstract
{
	/**
	 * Holds the name pairs for when different/bad key names need to point to the same data.
	 *
	 * @var array
	 */
	protected $_map = [];

	/**
	 * Holds the name of the name of the child class for method_exists and property_exists.
	 *
	 * @var string
	 */
	private $_calledClass;

	/**
	 * Holds the default values of the called class to-be-public properties in associative array.
	 *
	 * @var array
	 */
	private $_defaultValues;

	/**
	 * Holds the names of the called class' to-be-public properties in an indexed array.
	 *
	 * @var array
	 */
	private $_publicNames;

	/**
	 * Holds the count of the to-be-public properties.
	 *
	 * @var int
	 */
	private $_count;

	/**
	 * Constructor.
	 * Accepts an object, array, or JSON string.
	 *
	 * @param mixed $in -OPTIONAL
	 */
	public function __construct($in = null)
	{
		switch (gettype($in)) {
			case 'string':
			case 'array':
			case 'object':
				break;

			case 'NULL':
			case 'null':
				break;

			case 'bool':
			case 'boolean':
				if (!$in) {
					break;
				}
			//	"True" falls through and triggers exception.
			//	We allow "false" because some DB frameworks return "false" for empty result sets.

			default:
				throw new InvalidArgumentException('bad value to constructor');
		}

		$this->_initArrayOptions();
		$this->_initMetaData();
		$this->_initProperties();
		$this->replace($in);
	}

	private function _initMetaData()
	{
		$this->_calledClass = get_called_class();

		//	Build array of default values with converted types.
		//	First get all class properties then remove elements with names starting with underscore, except "_id".
		$this->_defaultValues = get_class_vars($this->_calledClass);
		foreach ($this->_defaultValues as $k => &$v) {
			if ($k[0] === '_' && $k !== '_id') {
				unset($this->_defaultValues[$k]);
				continue;
			}

			switch (gettype($v)) {
				case 'null':
				case 'NULL':
					$v = new SAAnything($v);
					break;

				case 'bool':
				case 'boolean':
					$v = new SABoolean($v);
					break;

				case 'int':
				case 'integer':
					$v = new SAInteger($v);
					break;

				case 'float':
				case 'double':
				case 'real':
					$v = new SAFloat($v);
					break;

				case 'string':
					$v = new SAString($v);
					break;

				case 'array':
					if (!empty($v) && array_values($v) === $v && is_string($v[0]) && class_exists($v[0])) {
						$class = array_shift($v);
						$v     = new $class(...$v);
					}
					else {
						$v = new TypedArray('', $v);
					}
					break;

				default:
					//	Do nothing. Don't try to cast.
			}
		}

		$this->_publicNames = array_keys($this->_defaultValues);
		$this->_count       = count($this->_defaultValues);
	}

	/**
	 * Should be called after _initMetaData().
	 */
	private function _initProperties()
	{
		foreach ($this->_defaultValues as $k => &$v) {
			/**
			 * All properties, except resources, are now objects.
			 * Clone the default/original value back to the original property.
			 */
			if (is_object($v)) {
				$this->{$k} = clone $v;
			}
		}
	}

	/**
	 * Return array of sudo public property names.
	 *
	 * @return array
	 */
	protected function _getPublicNames()
	{
		return $this->_publicNames;
	}

	/**
	 * Assign matching values to local keys resetting unmatched local keys.
	 *
	 * Copies all matching property names while maintaining original types and
	 *     doing a deep copy where appropriate.
	 * This method silently ignores extra properties in $input,
	 *     resets unmatched local properties, and
	 *     skips names starting with an underscore.
	 *
	 * Input can be an object, or an indexed or associative array.
	 *
	 * @param object|array|string|bool|null $in -OPTIONAL
	 */
	public function assign($in)
	{
		$this->_massageBlockInput($in);

		if (empty($in)) {
			foreach ($this->_publicNames as $publicName) {
				$this->__unset($publicName);
			}
		}
		elseif (is_object($in)) {
			foreach ($this->_publicNames as $publicName) {
				if (isset($in->{$publicName})) {
					$this->_setByName($publicName, $in->{$publicName});
				}
				else {
					$this->__unset($publicName);
				}
			}
		}
		else {
			foreach ($this->_publicNames as $publicName) {
				if (isset($in[$publicName])) {
					$this->_setByName($publicName, $in[$publicName]);
				}
				else {
					$this->__unset($publicName);
				}
			}
		}

		$this->_checkRelatedProperties();
	}

	/**
	 * Required method for Countable.
	 *
	 * @return int
	 */
	final public function count(): int
	{
		return $this->_count;
	}

	/**
	 * Required by the IteratorAggregate interface.
	 * Every value is checked for change during iteration.
	 *
	 * @return \Traversable
	 */
	public function getIterator(): Traversable
	{
		return (function &() {
			foreach ($this->_defaultValues as $k => &$vDefault) {
				if ($vDefault instanceof AtomicInterface) {
					$v     = $this->{$k}->get();
					$vOrig = $v;

					yield $k => $v;

					if ($v !== $vOrig) {
						$this->{$k}->set($v);
					}
				}
				else {
					yield $k => $this->{$k};

					//	Cast if not the same type.
					if (!is_object($this->{$k}) || get_class($this->{$k}) !== get_class($vDefault)) {
						$this->_setByName($k, $this->{$k});
					}
					//	Null property types don't get checked.
				}
			}
		})();
	}

	/**
	 * String representation of PHP object.
	 *
	 * This serialization, as opposed to JSON or BSON, does not unwrap the
	 * structured data. It only omits data that is part of the class definition.
	 *
	 * @link  https://php.net/manual/en/serializable.serialize.php
	 * @return string the string representation of the object or null
	 */
	public function serialize(): string
	{
		$toSerialize = [
			'_arrayOptions' => $this->_arrayOptions,
			'_jsonOptions'  => $this->_jsonOptions,
		];
		foreach ($this->_publicNames as $k) {
			$toSerialize[$k] = $this->{$k};
		}

		return serialize($toSerialize);
	}

	/**
	 * Constructs the object.
	 *
	 * This uses a faster but unsafe restore technique. It assumes that the
	 * serialized data was created by the local serialize method and was
	 * safely stored locally. No type checking is performed on restore. All
	 * data structure members have been serialized so no initialization of
	 * empty need be done.
	 *
	 * @link  https://php.net/manual/en/serializable.unserialize.php
	 *
	 * @param string $serialized The string representation of the object.
	 *
	 * @return void
	 */
	public function unserialize($serialized): void
	{
		$this->_initMetaData();

		$data = unserialize($serialized);

		foreach ($data as $k => $v) {
			$this->{$k} = $v;
		}
	}

	/**
	 * Deep replace local values with matches from input.
	 *
	 * Copies all matching property names while maintaining original types and
	 *     doing a deep copy where appropriate.
	 * This method silently ignores extra properties in $input,
	 *     leaves unmatched properties in this class untouched, and
	 *     skips names starting with an underscore.
	 *
	 * Input can be an object, or an indexed or associative array.
	 *
	 * @param object|array|string|bool|null $in
	 *
	 * @return void
	 */
	public function replace($in): void
	{
		$this->_massageBlockInput($in);

		if (empty($in)) {
			return;
		}

		foreach ($in as $k => $v) {
			if ($this->_keyExists($k)) {
				if ($this->{$k} instanceof TypedAbstract) {
					$this->{$k}->replace($v);
				}
				else {
					$this->_setByName($k, $v);
				}
			}
		}

		$this->_checkRelatedProperties();
	}

	/**
	 * Clone local values and replace matching values with input.
	 *
	 * This method clones $this then replaces matching keys from $in
	 *     and returns the new object.
	 *
	 * @param object|array|string|bool|null $in
	 *
	 * @return TypedClass
	 */
	public function merge($in)
	{
		$ret = clone $this;
		$ret->replace($in);

		return $ret;
	}

	/**
	 * @return array
	 */
	protected function _toArray(ArrayOptions $arrayOptions): array
	{
		$keepJsonExpr = $arrayOptions->has(ArrayOptions::KEEP_JSON_EXPR);
		$ZJE_STRING   = '\\Zend\\Json\\Expr';

		$arr = [];
		foreach ($this->_publicNames as $k) {
			$v = $this->_getByName($k);    //	AtomicInterface objects are returned as scalars.

			switch (gettype($v)) {
				case 'resource':
					if (!$arrayOptions->has(ArrayOptions::OMIT_RESOURCE)) {
						$arr[$k] = $v;
					}
					break;

				case 'object':
					if ($this->{$k} instanceof TypedAbstract) {
						$arr[$k] = $v->_toArray($arrayOptions);
					}
					elseif ($this->{$k} instanceof DateTimeInterface) {
						$arr[$k] = $v;    // maintain the type
					}
					elseif (($this->{$k} instanceof $ZJE_STRING) && $keepJsonExpr) {
						$arr[$k] = $v;    // maintain the type
					}
					elseif (method_exists($v, 'toArray')) {
						$arr[$k] = $v->toArray();
					}
					elseif (method_exists($v, '__toString')) {
						$arr[$k] = $v->__toString();
					}
					else {
						$arr[$k] = $v;
					}
					break;

				//	nulls, bools, ints, floats, strings, and arrays
				default:
					$arr[$k] = $v;
			}
		}

		if ($arrayOptions->has(ArrayOptions::OMIT_EMPTY)) {
			foreach ($arr as $k => &$v) {
				if (empty($v) || (is_object($v) && empty((array)$v))) {
					unset($arr[$k]);
				}
			}
		}

		return $arr;
	}

	/**
	 * Check if the input data is good or needs to be massaged.
	 *
	 * Indexed arrays ARE COPIED BY POSITION starting with the first sudo-public
	 * property (property names not starting with an underscore). Extra values
	 * are ignored. Unused properties are unchanged.
	 *
	 * @param $in
	 *
	 * @return object|array
	 * @throws InvalidArgumentException
	 */
	protected function _massageBlockInput(&$in)
	{
		if (is_string($in)) {
			$in          = json_decode($in);
			$jsonLastErr = json_last_error();
			if ($jsonLastErr !== JSON_ERROR_NONE) {
				throw new InvalidArgumentException(
					'invalid input type (string); tried as JSON: ' . json_last_error_msg(),
					$jsonLastErr
				);
			}
		}

		switch (gettype($in)) {
			case 'object':
				break;

			case 'array':
				//	Test to see if it's an indexed or an associative array.
				//	Leave associative array as is.
				//	Copy indexed array by position to a named array
				if (!empty($in) && array_values($in) === $in) {
					$newArr   = [];
					$minCount = min(count($in), $this->_count);
					for ($i = 0; $i < $minCount; ++$i) {
						$newArr[$this->_publicNames[$i]] = $in[$i];
					}

					$in = $newArr;
				}
				break;

			case 'null':
			case 'NULL':
				$in = [];
				break;

			case 'bool':
			case 'boolean':
				/** A 'false' is returned by MySQL:PDO for "no results" */
				if (false === $in) {
					/** Change false to empty array. */
					$in = [];
					break;
				}
			//	A boolean 'true' falls through.

			default:
				throw new InvalidArgumentException('invalid input type: ' . gettype($in));
		}
	}

	/**
	 * Sets a variable to it's default value rather than unsetting it.
	 *
	 * @param string $k
	 */
	public function __unset($k)
	{
		$this->{$k} = clone $this->_defaultValues[$k];
	}

	/**
	 * All member objects will be deep cloned.
	 */
	public function __clone()
	{
		foreach ($this->_publicNames as $k) {
			if (is_object($this->{$k})) {
				$this->{$k} = clone $this->{$k};
			}
		}
	}

	/**
	 * Get variable.
	 *
	 * @param string $k
	 *
	 * @return mixed
	 */
	public function __get($k)
	{
		$this->_assertPropName($k);
		return $this->_getByName($k);
	}

	/**
	 * Set variable
	 * Casts the incoming data ($v) to the same type as the named ($k) property.
	 *
	 * @param string $k
	 * @param mixed  $v
	 */
	public function __set($k, $v)
	{
		$this->_assertPropName($k);
		$this->_setByName($k, $v);
		$this->_checkRelatedProperties();
	}

	/**
	 * Is a variable set?
	 *
	 * Behavior for "isset()" expects the variable (property) to exist and not be null.
	 *
	 * @param string $k
	 *
	 * @return bool
	 */
	public function __isset($k): bool
	{
		return $this->_keyExists($k) && ($this->{$k} !== null);
	}

	/**
	 * Set data to named variable.
	 * Casts the incoming data ($v) to the same type as the named ($k) property.
	 *
	 * @param string $propName
	 * @param mixed  $in
	 *
	 * @throws InvalidArgumentException
	 */
	protected function _setByName($propName, $in)
	{
		if (array_key_exists($propName, $this->_map)) {
			$propName = $this->_map[$propName];
		}

		$setter = '_set_' . $propName;
		if (method_exists($this->_calledClass, $setter)) {
			$this->{$setter}($in);
			return;
		}

		/** All properties are now handled as objects. */
		$propertyDefaultValue = $this->_defaultValues[$propName];

		//	Handle our atomic types.
		if ($propertyDefaultValue instanceof AtomicInterface) {
			$this->{$propName}->set($in);
			return;
		}

		//	Handle our two special object types.
		if ($propertyDefaultValue instanceof TypedAbstract) {
			$this->{$propName}->assign($in);
			return;
		}

		//	Handler for other types of objects.
		$propertyClassType = get_class($propertyDefaultValue);

		//	Treat DateTime related objects as atomic.
		if ($propertyDefaultValue instanceof DateTime) {
			$this->{$propName} = new $propertyClassType($in);
			return;
		}

		switch (gettype($in)) {
			case 'object':
				//	if identical types then reference the original object
				if ($propertyClassType === get_class($in)) {
					$this->{$propName} = $in;
				}

				//	Else give up.
				else {
					throw new InvalidArgumentException('cannot coerce object types');
				}
				break;

			case 'null':
			case 'NULL':
				$this->{$propName} = clone $propertyDefaultValue;
				break;

			case 'array':
				if ($propertyClassType === 'stdClass') {
					$this->{$propName} = (object)$in;
					break;
				}
			//	fall through

			default:
				//	Other classes might be able to absorb/convert other input,
				//		like «DateTime::__construct("now")» accepts a string.
				$this->{$propName} = new $propertyClassType($in);
		}
	}

	/**
	 * Override this method for additional checking such as when a start-date
	 * is required to be earlier than an end-date, any range of values like
	 * minimum and maximum, or any custom filtering dependent on more than a single property.
	 */
	protected function _checkRelatedProperties()
	{
	}

	/**
	 * Throws exception if named property does not exist.
	 *
	 * @param string $k
	 *
	 * @throws InvalidArgumentException
	 */
	protected function _assertPropName($k)
	{
		if (!$this->_keyExists($k)) {
			throw new InvalidArgumentException();
		}
	}

	/**
	 * Get variable by name.
	 *
	 * @param string $propName
	 *
	 * @return mixed
	 */
	protected function _getByName($propName)
	{
		if (array_key_exists($propName, $this->_map)) {
			$propName = $this->_map[$propName];
		}

		if ($this->{$propName} instanceof AtomicInterface) {
			return $this->{$propName}->get();
		}

		$getter = '_get_' . $propName;
		if (method_exists($this->_calledClass, $getter)) {
			return $this->{$getter}();
		}

		return $this->{$propName};
	}

	/**
	 * Returns true if key/prop name exists or is mappable.
	 *
	 * @param string $propName
	 *
	 * @return bool
	 */
	private function _keyExists($propName): bool
	{
		if (array_key_exists($propName, $this->_map)) {
			$propName = $this->_map[$propName];
		}

		return in_array($propName, $this->_publicNames);
	}
}


<?php

/*
 * This file is part of the OrkestraApplicationBundle package.
 *
 * Copyright (c) Orkestra Community
 *
 * For the full copyright and license information, please view the LICENSE file
 * that was distributed with this source code.
 */

namespace Orkestra\Bundle\ApplicationBundle\Worker;

use Doctrine\ORM\EntityManager;
use Guzzle\Http\ClientInterface;
use Orkestra\Bundle\ApplicationBundle\Entity\Contact\Address;
use Orkestra\Common\Kernel\HttpKernel;
use Symfony\Component\HttpFoundation\Request;

/**
 * Populates latitude and longitude in addresses
 */
class LatitudeLongitudeWorker implements WorkerInterface
{
    const MILLISECONDS_PAUSE_BETWEEN_QUERIES = 0;

    /**
     * @var \Doctrine\ORM\EntityManager
     */
    protected $entityManager;

    /**
     * @var \Doctrine\ORM\EntityRepository
     */
    protected $addressRepository;

    /**
     * @var \Guzzle\Http\ClientInterface
     */
    private $client;

    /**
     * Constructor
     *
     * @param \Doctrine\ORM\EntityManager $entityManager
     * @param \Guzzle\Http\ClientInterface $client
     */
    public function __construct(EntityManager $entityManager, ClientInterface $client)
    {
        $this->entityManager = $entityManager;
        $this->addressRepository = $entityManager->getRepository('OrkestraApplicationBundle:Contact\Address');
        $this->client = $client;
    }

    /**
     * Gets the user-friendly name of the worker
     *
     * @return string
     */
    public function getName()
    {
        return 'Latitude and Longitude Worker';
    }

    /**
     * Gets the internally used name of the worker
     *
     * @return string
     */
    public function getInternalName()
    {
        return 'orkestra.address.latitude_longitude';
    }

    /**
     * Execute the work
     *
     * @return void
     */
    public function execute()
    {
        $addresses = $this->addressRepository->createQueryBuilder('a')
            ->where('a.latitude IS NULL')
            ->orWhere('a.longitude IS NULL')
            ->setMaxResults(500)
            ->getQuery()
            ->getResult();

        foreach ($addresses as $address) {
            try {
                $this->updateLatLong($address);
            } catch (\RuntimeException $e) {
                echo "Stopping work -- over the API query limit.\n";

                break;
            }

            $this->entityManager->persist($address);

            usleep(self::MILLISECONDS_PAUSE_BETWEEN_QUERIES);
        }

        $this->entityManager->flush();
    }

    private function updateLatLong(Address $address)
    {
        $request = $this->client->get('https://maps.googleapis.com/maps/api/geocode/json');
        $request->getQuery()
            ->set('address', $address->__toString())
            ->set('sensor', 'false');

        $response = $request->send();

        $data = json_decode($response->getBody(true));

        if (isset($data->status)) {
            if ('OK' === $data->status && isset($data->results[0]->geometry->location)) {
                $address->setLatitude((float)$data->results[0]->geometry->location->lat);
                $address->setLongitude((float)$data->results[0]->geometry->location->lng);

            }  elseif ('OVER_QUERY_LIMIT' === $data->status) {
                throw new \RuntimeException('Over the query limit');
            }
        }
    }
}


<?php
/**
 * @license MIT
 */
namespace Pivasic\Core;

/**
 * Represents a HTTP response.
 *
 * Class Response
 * @package Pivasic\Core
 */
class Response
{
    /**
     * Response constructor.
     */
    public function __construct()
    {
        $this->content = '';
        $this->is404 = true;
    }

    /**
     * False if response body was set.
     * @return bool
     */
    public function is404(): bool
    {
        return $this->is404;
    }

    /**
     * Send response.
     */
    public function send()
    {
        echo $this->content;

        if (function_exists('fastcgi_finish_request')) {
            fastcgi_finish_request();
        } elseif ('cli' !== php_sapi_name()) {
            $level = ob_get_level();
            if (0 < $level) {
                $status = ob_get_status(true);
                // PHP_OUTPUT_HANDLER_* are not defined on HHVM 3.3
                $flags = defined('PHP_OUTPUT_HANDLER_REMOVABLE') ? PHP_OUTPUT_HANDLER_REMOVABLE | PHP_OUTPUT_HANDLER_FLUSHABLE : -1;
                while ($level-- > 0 && ($s = $status[$level]) && (!isset($s['del']) ? !isset($s['flags']) || $flags === ($s['flags'] & $flags) : $s['del'])) {
                    ob_end_flush();
                }
            }
        }
    }

    /**
     * Set response body.
     *
     * @param string $content
     */
    public function setContent(string $content)
    {
        $this->is404 = false;
        $this->content = $content;
    }

    /**
     * Set response header.
     *
     * @param string $name
     * @param string $value
     * @return bool
     */
    public function header(string $name, string $value): bool
    {
        if (!empty($name) && !empty($value) && !headers_sent()) {
            header($name . ': ' . $value);
            return true;
        }
        return false;
    }

    /**
     * @return bool
     */
    public function setContentTypeJson(): bool
    {
        return $this->header('Content-Type', 'application/json; charset=utf-8');
    }

    /**
     * @return bool
     */
    public function setContentTypeXml(): bool
    {
        return $this->header('Content-Type', 'text/xml; charset=utf-8');
    }

    /**
     * Set response status.
     *
     * @param int $statusCode           - status
     * @param string $version           - HTTP version
     * @param string $statusText   - status text
     * @return bool
     */
    public function setStatusCode(int $statusCode, string $version = '1.1', string $statusText = ''): bool
    {
        if (!headers_sent()) {
            $statusCode = intval($statusCode);

            if ('' == $statusText) {
                $statusTexts = [
                    100 => 'Continue',
                    101 => 'Switching Protocols',
                    102 => 'Processing',            // RFC2518
                    200 => 'OK',
                    201 => 'Created',
                    202 => 'Accepted',
                    203 => 'Non-Authoritative Information',
                    204 => 'No Content',
                    205 => 'Reset Content',
                    206 => 'Partial Content',
                    207 => 'Multi-Status',          // RFC4918
                    208 => 'Already Reported',      // RFC5842
                    226 => 'IM Used',               // RFC3229
                    300 => 'Multiple Choices',
                    301 => 'Moved Permanently',
                    302 => 'Found',
                    303 => 'See Other',
                    304 => 'Not Modified',
                    305 => 'Use Proxy',
                    307 => 'Temporary Redirect',
                    308 => 'Permanent Redirect',    // RFC7238
                    400 => 'Bad Request',
                    401 => 'Unauthorized',
                    402 => 'Payment Required',
                    403 => 'Forbidden',
                    404 => 'Not Found',
                    405 => 'Method Not Allowed',
                    406 => 'Not Acceptable',
                    407 => 'Proxy Authentication Required',
                    408 => 'Request Timeout',
                    409 => 'Conflict',
                    410 => 'Gone',
                    411 => 'Length Required',
                    412 => 'Precondition Failed',
                    413 => 'Payload Too Large',
                    414 => 'URI Too Long',
                    415 => 'Unsupported Media Type',
                    416 => 'Range Not Satisfiable',
                    417 => 'Expectation Failed',
                    418 => 'I\'m a teapot',                                               // RFC2324
                    422 => 'Unprocessable Entity',                                        // RFC4918
                    423 => 'Locked',                                                      // RFC4918
                    424 => 'Failed Dependency',                                           // RFC4918
                    425 => 'Reserved for WebDAV advanced collections expired proposal',   // RFC2817
                    426 => 'Upgrade Required',                                            // RFC2817
                    428 => 'Precondition Required',                                       // RFC6585
                    429 => 'Too Many Requests',                                           // RFC6585
                    431 => 'Request Header Fields Too Large',                             // RFC6585
                    500 => 'Internal Server Error',
                    501 => 'Not Implemented',
                    502 => 'Bad Gateway',
                    503 => 'Service Unavailable',
                    504 => 'Gateway Timeout',
                    505 => 'HTTP Version Not Supported',
                    506 => 'Variant Also Negotiates (Experimental)',                      // RFC2295
                    507 => 'Insufficient Storage',                                        // RFC4918
                    508 => 'Loop Detected',                                               // RFC5842
                    510 => 'Not Extended',                                                // RFC2774
                    511 => 'Network Authentication Required',                             // RFC6585
                ];
                $statusText = $statusTexts[$statusCode];
            }

            header(sprintf('HTTP/%s %s %s', $version, $statusCode, $statusText), true, $statusCode);
            return true;
        }

        return false;
    }

    /**
     * Redirect to url with statusCode and terminate.
     *
     * @param string $url
     * @param int $statusCode
     */
    public function redirect(string $url = '', int $statusCode = 302)
    {
        $this->is404 = false;
        $server = filter_input_array(INPUT_SERVER);
        if ('' == $url && isset($server['REQUEST_URI'])) {
            $url = '/' . trim($server['REQUEST_URI'], '/');
            preg_match('/^[\\a-zA-Z0-9-\._~:\/\?\#\[\]\@\!\$\&\'\(\)\*\+\,\;\=%]*$/iD', $url, $match);
            $url = $match[1] ?? '';
        }

        if (!headers_sent()) {
            header('Location: ' . $url, true, $statusCode);
        }

        echo sprintf('<!DOCTYPE html>

        <meta charset="UTF-8" />
        <meta http-equiv="refresh" content="0;url=%1$s" />
        <title>Redirecting to %1$s</title>

        Redirecting to %1$s.

', htmlspecialchars($url, ENT_QUOTES, 'UTF-8'));

    }

    private $content;
    private $is404;
}


<?php

/*
 * This file is part of the OrkestraApplicationBundle package.
 *
 * Copyright (c) Orkestra Community
 *
 * For the full copyright and license information, please view the LICENSE file
 * that was distributed with this source code.
 */

namespace Orkestra\Bundle\ApplicationBundle\Http;

use Symfony\Component\Form\Form;
use Symfony\Component\Form\FormError;
use Symfony\Component\HttpFoundation\JsonResponse;

/**
 * A JsonSuccessResponse containing error information tailored to the Orkestra client side library
 */
class JsonErrorResponse extends JsonResponse
{
    /**
     * Constructor
     *
     * If $message is an instance of Form, the appropriate message will be
     * fetched from the form errors and the validation updates will be sent
     * to the browser.
     *
     * @param \Symfony\Component\Form\Form|string $message
     */
    public function __construct($message = null)
    {
        if ($message instanceof Form) {
            $data = $this->getFormErrorData($message);
        } else {
            $data = $this->getResponseData($message ?: 'An error occurred. Please try again later.');
        }

        parent::__construct($data);
    }

    /**
     * Iterates over the given Form returning error information contained within
     *
     * @todo Handle validation updates -- probably needs a FormView instead of a Form to get field IDs
     *
     * @param \Symfony\Component\Form\Form $form
     *
     * @return array
     */
    private function getFormErrorData(Form $form)
    {
        if ($form->isValid()) {
            // A JsonErrorResponse was created with a valid form-- no errors will be found
            return $this->getResponseData('An error occurred while processing the submitted information');
        }

        $errors = $this->getErrors($form);
        $message = $this->getMainErrorMessage($form);

        return $this->getResponseData($message, $errors);
    }

    private function getMainErrorMessage(Form $form)
    {
        $message = 'An error occurred. ';

        $errors = $form->getErrors();
        if (!empty($errors)) {
            $message .= implode('. ', array_map(function(FormError $error) {
                return rtrim($error->getMessage(), '.');
            }, $errors instanceof \Iterator ? iterator_to_array($errors) : $errors));

        } else {
            $message .= 'The form contains invalid values.';
        }

        return $message;
    }

    /**
     * Gets error message recursively through a form and all its children
     *
     * @param \Symfony\Component\Form\Form $form
     *
     * @return array
     */
    private function getErrors(Form $form)
    {
        $errors = array();

        if ($form->isSubmitted() && $form->isValid()) {
            return $errors;
        }

        $id = $form->createView()->vars['id'];

        foreach ($form->getErrors() as $error) {

            if (!isset($errors[$id])) {
                $errors[$id] = array();
            }

            $errors[$id][] = $error->getMessage();
        }

        foreach ($form->all() as $child) {
            $errors = array_merge($this->getErrors($child), $errors);
        }

        return $errors;
    }

    /**
     * Returns an array of data ready to be consumed by the Orkestra client-side javascript
     *
     * @param $message
     *
     * @return array
     */
    private function getResponseData($message, array $fieldErrors = array())
    {
        return array(
            'type'         => 'error',
            'message'      => $message,
            'field_errors' => $fieldErrors
        );
    }
}


<?php
namespace keenly;
/**
 * This file is part of keenly from.
 * @author brain_yang<qiaopi520@qq.com>
 * (c) brain_yang
 * github: https://github.com/keenlysoft/
 * @time 2018年6月27日
 * For the full copyright and license information, please view the LICENSE
 */
class config {

    private static $rangePath = '../config/';

    private static $format = 'php';

    private static $name;

    protected static $config;

    private static $instance;

    private static $defule = 'database';

    //const CLIPATH = ;

    public function Get($name = null,$value = null,...$param){
        if(!isset($name)) return  self::$config;
        return  isset($value)?
        self::$config[$name][$value]
        :(isset(self::$config[$name])?self::$config[$name]:null);
    }

    /**
     * This file is part of keenly from.
     * @author brain_yang<qiaopi520@qq.com>
     * (c) brain_yang
     * github: https://github.com/keenlysoft/
     * @time 2018年8月27日
     * @param $file 文件名称
     * @param $rangePath 文件路径
     * For the full copyright and license information, please view the LICENSE
     */
    public static function reload($file,$rangePath = null){
        if(!empty($rangePath)){
            self::$rangePath = $rangePath;
        }
        if (PHP_SAPI === 'cli'){
            $cilpath = realpath(dirname(dirname(dirname(dirname(__FILE__))))).'/config/';
            $file = $cilpath.$file.'.'.self::$format;
        }else{
            $file = self::$rangePath.$file.'.'.self::$format;
        }
        $name = strtolower($file);
        $type = pathinfo($file, PATHINFO_EXTENSION);

        if(self::$format == $type)
            return self::set(include $file);
    }

   private static function set($config){
        self::$config = $config;
        if(!isset(self::$instance)){
            self::$instance = new static();
        }
        return self::$instance;
    }

}


<?php

/**
 * TechDivision\Import\Product\Media\Ee\Repositories\ProductMediaGalleryValueToEntityRepository
 *
 * NOTICE OF LICENSE
 *
 * This source file is subject to the Open Software License (OSL 3.0)
 * that is available through the world-wide-web at this URL:
 * http://opensource.org/licenses/osl-3.0.php
 *
 * PHP version 5
 *
 * @author    Tim Wagner <t.wagner@techdivision.com>
 * @copyright 2016 TechDivision GmbH <info@techdivision.com>
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
 * @link      https://github.com/techdivision/import-product-media-ee
 * @link      http://www.techdivision.com
 */

namespace TechDivision\Import\Product\Media\Ee\Repositories;

use TechDivision\Import\Product\Media\Ee\Utils\MemberNames;
use TechDivision\Import\Product\Media\Ee\Utils\SqlStatementKeys;

/**
 * Interface for repository implementations to load product media gallery value to entity data.
 *
 * @author    Tim Wagner <t.wagner@techdivision.com>
 * @copyright 2016 TechDivision GmbH <info@techdivision.com>
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
 * @link      https://github.com/techdivision/import-product-media-ee
 * @link      http://www.techdivision.com
 */
class ProductMediaGalleryValueToEntityRepository extends \TechDivision\Import\Product\Media\Repositories\ProductMediaGalleryValueToEntityRepository implements ProductMediaGalleryValueToEntityRepositoryInterface
{

    /**
     * The prepared statement to load an existing product media gallery value to entity entity.
     *
     * @var \PDOStatement
     */
    protected $productMediaGalleryValueToEntityStmt;

    /**
     * Initializes the repository's prepared statements.
     *
     * @return void
     */
    public function init()
    {

        // initialize the prepared statements
        $this->productMediaGalleryValueToEntityStmt =
            $this->getConnection()->prepare($this->loadStatement(SqlStatementKeys::PRODUCT_MEDIA_GALLERY_VALUE_TO_ENTITY));
    }

    /**
     * Load's the product media gallery with the passed value/row ID.
     *
     * @param integer $valueId The value ID of the product media gallery value to entity to load
     * @param integer $rowId   The row ID of the product media gallery value to entity to load
     *
     * @return array The product media gallery
     */
    public function findOneByValueIdAndRowId($valueId, $rowId)
    {

        // initialize the params
        $params = array(
            MemberNames::VALUE_ID  => $valueId,
            MemberNames::ROW_ID    => $rowId
        );

        // load and return the prodcut media gallery value to entity with the passed value/entity ID
        $this->productMediaGalleryValueToEntityStmt->execute($params);
        return $this->productMediaGalleryValueToEntityStmt->fetch(\PDO::FETCH_ASSOC);
    }
}


<?php
/**
 * @license MIT
 */
namespace Pivasic\Bundle\Common\File;

/**
 * Class FileBag
 * @package Pivasic\Bundle\Common\File
 */
class FileBag
{
    /**
     * Initialize bag from $_FILES.
     *
     * @throws \InvalidArgumentException
     */
    public function __construct()
    {
        $this->bag = [];

        foreach ($_FILES as $key => $file) {
            if (!is_array($file) && !$file instanceof FileUpload) {
                throw new \InvalidArgumentException('An uploaded file must be an array or an instance of FileUpload.');
            }
            $this->bag[$key] = $this->convertFileInformation($file);
        }
    }

    /**
     * Returns true if the FILE parameter is defined.
     *
     * @param string $key
     * @return bool
     */
    public function has(string $key): bool
    {
        return array_key_exists($key, $this->bag);
    }

    /**
     * An array of parameter names.
     *
     * @return array
     */
    public function keys(): array
    {
        return array_keys($this->bag);
    }

    /**
     * Get value by parameter name.
     *
     * @param string $key
     * @param mixed|null $default The default value if parameter does not exist
     * @return FileUpload|array|null
     */
    public function fetch(string $key, $default = null)
    {
        return $this->bag[$key] ?? $default;
    }

    /**
     * Converts uploaded files to FileUpload instances.
     *
     * @param array|FileUpload $file A (multi-dimensional) array of uploaded file information
     * @return array A (multi-dimensional) array of FileUpload instances
     */
    private function convertFileInformation($file)
    {
        if ($file instanceof FileUpload) {
            return $file;
        }

        $file = $this->fixPhpFilesArray($file);
        if (is_array($file)) {
            $keys = array_keys($file);
            sort($keys);

            if ($keys == ['error', 'name', 'size', 'tmp_name', 'type']) {
                if (UPLOAD_ERR_NO_FILE == $file['error']) {
                    $file = null;
                } else {
                    $file = new FileUpload($file['tmp_name'], $file['name'], $file['size'], $file['type'], $file['error']);
                }
            } else {
                $file = array_map([$this, 'convertFileInformation'], $file);
            }
        }

        return $file;
    }

    /**
     * Fixes a malformed PHP $_FILES array.
     *
     * PHP has a bug that the format of the $_FILES array differs, depending on
     * whether the uploaded file fields had normal field names or array-like
     * field names ("normal" vs. "parent[child]").
     *
     * This method fixes the array to look like the "normal" $_FILES array.
     *
     * It's safe to pass an already converted array, in which case this method
     * just returns the original array unmodified.
     *
     * @param array $data
     * @return array
     */
    private function fixPhpFilesArray(array $data): array
    {
        if (!is_array($data)) {
            return $data;
        }

        $keys = array_keys($data);
        sort($keys);

        if (['error', 'name', 'size', 'tmp_name', 'type'] != $keys || !isset($data['name']) || !is_array($data['name'])) {
            return $data;
        }

        $files = $data;
        foreach (['error', 'name', 'size', 'tmp_name', 'type'] as $k) {
            unset($files[$k]);
        }

        foreach ($data['name'] as $key => $name) {
            $files[$key] = $this->fixPhpFilesArray(array(
                'error' => $data['error'][$key],
                'name' => $name,
                'type' => $data['type'][$key],
                'tmp_name' => $data['tmp_name'][$key],
                'size' => $data['size'][$key],
            ));
        }

        return $files;
    }

    private $bag;
}


<?php
namespace keenly\component\swoole;
use swoole_process;
use keenly\base\Singleton;
use models\User;
use keenly\component\Box;
/**
 * This file is part of keenly from.
 * @author brain_yang<qiaopi520@qq.com>
 * (c) brain_yang
 * github: https://github.com/keenlysoft/
 * @time 2018年8月27日
 * For the full copyright and license information, please view the LICENSE
 */
class process {

    use Singleton;

    private $process;

    public  $works = [];

    private $pro = [];

    private $index = 0;
    /**
     * @name 添加进程
     * 进程检测和自动回收僵尸进程
     * @param 进程名称 $name
     * @param 唯一标识 $key
     * @param callb $fun
     * @param 执行参数 ...$arg
     * @author brain_yang <qiaopi520@qq.com>
     * @time 2018年10月6日 15:52:04
     * This file is part of keenly from.
     */
    public function addprocess($name,$key,callable $fun,...$arg){
        Box::I()->add($key, $fun,...$arg);
        $this->setName($name);
        $this->process = new \swoole_process(function(swoole_process $worker)use($key){
            $this->pro[$this->index]['obj'] = $worker;
            $this->pro[$this->index]['key'] = $key;
            $this->index++;
            Box::I()->call($key);
        }, true, false);
        return $this;
    }

    private function setName($name){
        return \swoole_set_process_name($name);
    }

    /**
     * @name 开启进程
     * @param 为true表示不要切换当前目录到根目录              $nochdir
     * @param 为true表示不要关闭标准输入输出文件描述符   $noclose
     * @desc
     * 此函数在1.7.5版本后可用
     * 1.9.1或更高版本修改了默认值，现在默认nochir和noclose均为true
     * 蜕变为守护进程时，该进程的PID将发生变化，可以使用getmypid()来获取当前的PID
     *
     */

    public function start($nochdir = TRUE,$noclose = TRUE){
        //\swoole_process::daemon($nochdir,$noclose);
        $this->works[$this->index] = $this->process->start();
        $this->processWait();
    }

    /**
     * 获取Index
     * 也是表示进程次数;
     * 进程和worke对象属性中
     * $this->pro[$this->getIndex()]['obj']->exec() 执行进程 或者 进程写 write(string $data) or read();
     *  or $this->works;
     * @author brain_yang <qiaopi520@qq.com>
     * @return number
     */
    public function getIndex(){
        return $this->index;
    }

    public function processWait(){
        while(1) {
            if(count($this->works)){
                $ret = \swoole_process::wait();
                var_dump($this->works);
                sleep(1);
                if ($ret) {
                    $this->rebootProcess($ret);
                }
            }else{
                break;
            }
        }
    }

    public function rebootProcess($ret){
        $pid = $ret['pid'];
        var_dump($this->works);
        $index = array_search($pid, $this->works);
        if($index !== false){
            $index = intval($index);
            $new_pid = $this->CreateProcess($index);
            return;
        }
        throw new \Exception('rebootProcess Error: no pid');
    }

    public function CreateProcess($index = null){
        $process = new \swoole_process(function(swoole_process $worker)use($index){
            if(is_null($index)){
                $index = $this->index;
                $this->index++;
            }
            \swoole_set_process_name(sprintf('keenly:%s',$index));
            var_dump($this->pro);
            if(isset($this->pro[$index])){
                Box::I()->call($this->pro[$index]['key']);
            }
        }, false, false);
        $pid = $process->start();
        $this->works[$index] = $pid;
        return $pid;
    }

    /**
     * $pid 进程ID
     * 默认的信号为SIGTERM，表示终止进程
     * $signo=0，可以检测进程是否存在，不会发送信号
     */
    public static function kill($pid, $signo = SIGTERM){
        return parent::kill($pid, $signo);
   }

}


<?php
/**
 * Create an array where members must be the same type.
 *
 * @name        \Diskerror\Typed\TypedArray
 * @copyright   Copyright (c) 2012 Reid Woodbury Jr
 * @license     http://www.apache.org/licenses/LICENSE-2.0.html Apache License, Version 2.0
 */

namespace Diskerror\Typed;

use ArrayAccess;
use DateTimeInterface;
use InvalidArgumentException;
use LengthException;
use Traversable;

/**
 * Provides support for an array's elements to all have the same type.
 * If type is defined as null then any element can have any type but
 *      deep copying of objects is always available.
 */
class TypedArray extends TypedAbstract implements ArrayAccess
{
	/**
	 * A string that specifies the type of values in the container.
	 * A child class can override _type rather than it being set with the constructor.
	 *
	 * @var string|null
	 */
	protected $_type;

	/**
	 * An array that contains the items of interest.
	 *
	 * @var array
	 */
	protected $_container;

	/**
	 * Constructor.
	 *
	 * This allows for initial values to be passed in the first parameter.
	 * This is only works for children of this class where the type has already
	 * been set.
	 *
	 * @param mixed             $type   OPTIONAL ''
	 * @param array|object|null $values OPTIONAL null
	 */
	public function __construct($type = '', $values = null)
	{
		if (get_called_class() !== self::class) {
			if (!isset($this->_type)) {
				throw new InvalidArgumentException('$this->_type must be set in child class.');
			}

			if (null !== $values) {
				throw new InvalidArgumentException('Only the first parameter can be set when using an inherited class.');
			}

			// Assume the first parameter holds the values and the second is unset.
			$values = $type;
		}
		else {
			$this->_type = $type;
		}

		$this->_initArrayOptions();

		switch (strtolower($this->_type)) {
			case '':
			case 'null':
			case 'anything':
				$this->_type = SAAnything::class;
				break;

			case 'scalar':
				$this->_type = SAScalar::class;
				break;

			case 'bool':
			case 'boolean':
				$this->_type = SABoolean::class;
				break;

			case 'int':
			case 'integer':
				$this->_type = SAInteger::class;
				break;

			case 'float':
			case 'double':
			case 'real':
				$this->_type = SAFloat::class;
				break;

			case 'string':
				$this->_type = SAString::class;
				break;

			case 'array':
				$this->_type = TypedArray::class;
				break;

			case 'date':
				$this->_type = Date::class;
				break;

			case 'datetime':
				$this->_type = DateTime::class;
				break;
		}

		$this->assign($values);
	}

	/**
	 * Check if the input data is good or needs to be massaged.
	 *
	 * Indexed arrays ARE COPIED BY POSITION starting with the first sudo-public
	 * property (property names not starting with an underscore). Extra values
	 * are ignored. Unused properties are unchanged.
	 *
	 * @param $in
	 *
	 * @throws InvalidArgumentException
	 */
	protected function _massageBlockInput(&$in)
	{
		if (is_string($in)) {
			$in          = json_decode($in);
			$jsonLastErr = json_last_error();
			if ($jsonLastErr !== JSON_ERROR_NONE) {
				throw new InvalidArgumentException(
					'invalid input type (string); tried as JSON: ' . json_last_error_msg(),
					$jsonLastErr
				);
			}
		}

		switch (gettype($in)) {
			case 'object':
			case 'array':
				break;

			case 'null':
			case 'NULL':
				$in = [];
				break;

			case 'bool':
			case 'boolean':
				// A 'false' is returned by MySQL:PDO for "no results".
				if (true !== $in) {
					/** Change false to empty array. */
					$in = [];
				}
			//	A boolean 'true' falls through.

			default:
				throw new InvalidArgumentException('bad input type ' . gettype($in) . ', value: "' . $in . '"');
		}
	}

	/**
	 * Copies all members into this class, removing all existing values.
	 *
	 * Null clears the entire contents of the typed array but not it's type.
	 *
	 * @param object|array|string|null $in
	 *
	 * @throws \InvalidArgumentException
	 */
	public function assign($in)
	{
		$this->_massageBlockInput($in);

		$this->_container = [];    //	initialize array or remove all current values

		foreach ($in as $k => $v) {
			$this->offsetSet($k, $v);
		}
	}

	/**
	 * Copies all members into this class. Indexed keys will be re-indexed.
	 *
	 * @param object|array|string|null $in
	 *
	 * @throws \InvalidArgumentException
	 */
	public function replace($in)
	{
		$this->_massageBlockInput($in);

		foreach ($in as $k => $v) {
			$this->offsetSet($k, $v);
		}
	}

	/**
	 * Required by the Countable interface.
	 *
	 * @return int
	 */
	public function count(): int
	{
		return count($this->_container);
	}

	/**
	 * Return an integer representing the toArray conversion options.
	 *
	 * @return int
	 */
	public function getArrayOptions(): int
	{
		return $this->_arrayOptions->get();
	}

	/**
	 * Takes an integer representing the toArray conversion options.
	 *
	 * @param int $opts
	 */
	public function setArrayOptions(int $opts)
	{
		$this->_arrayOptions->set($opts);
	}

	/**
	 * Required by the IteratorAggregate interface.
	 * Every value is checked for change during iteration.
	 *
	 * The _type or gettype() can return different names for the same type,
	 * ie. "bool" or "boolean", so we're only going to check the first 3 characters.
	 *
	 * @return Traversable
	 */
	public function getIterator(): Traversable
	{
		if (is_a($this->_type, AtomicInterface::class, true)) {
			return (function &() {
				foreach ($this->_container as $k => $v) {
					$v     = $v->get();
					$vOrig = $v;
					yield $k => $v;
					if ($v !== $vOrig) {
						$this->_container[$k]->set($v);
					}
				}
			})();
		}
		else {
			return (function &() {
				foreach ($this->_container as $k => &$v) {
					yield $k => $v;

					//	Compare whole class names.
					if (get_class($v) !== $this->_type) {
						$this->offsetSet($k, $v);
					}
				}
			})();
		}
	}

	/**
	 * String representation of object.
	 *
	 * @link  https://php.net/manual/en/serializable.serialize.php
	 * @return string the string representation of the object or null
	 */
	public function serialize(): string
	{
		return serialize([
			'_type'         => $this->_type,
			'_arrayOptions' => $this->_arrayOptions,
			'_jsonOptions'  => $this->_jsonOptions,
			'_container'    => $this->_container,
		]);
	}

	/**
	 * Constructs the object
	 *
	 * @link  https://php.net/manual/en/serializable.unserialize.php
	 *
	 * @param string $serialized The string representation of the object.
	 *
	 * @return void
	 */
	public function unserialize($serialized)
	{
		$data = unserialize($serialized);

		$this->_type         = $data['_type'];
		$this->_arrayOptions = $data['_arrayOptions'];
		$this->_jsonOptions  = $data['_jsonOptions'];
		$this->_container    = $data['_container'];
	}

	/**
	 * Returns an array with all members checked for a "toArray" method so
	 * that any member of type "Typed" will also be returned.
	 * Use "__get" and "__set", or $var[$member] to access individual names.
	 *
	 * @return array
	 */
	protected function _toArray(ArrayOptions $arrayOptions): array
	{
		$omitEmpty = $arrayOptions->has(ArrayOptions::OMIT_EMPTY);
		$output    = [];

		//	At this point all items are some type of object.
		if (is_a($this->_type, AtomicInterface::class, true)) {
			foreach ($this->_container as $k => $v) {
				$output[$k] = $v->get();
			}
		}
		elseif (is_a($this->_type, TypedAbstract::class, true)) {
			foreach ($this->_container as $k => $v) {
				$output[$k] = $v->_toArray($arrayOptions);
			}
		}
		elseif (is_a($this->_type, DateTimeInterface::class, true)) {
			foreach ($this->_container as $k => $v) {
				$output[$k] = $v;
			}
		}
		elseif (method_exists($this->_type, 'toArray')) {
			foreach ($this->_container as $k => $v) {
				$output[$k] = $v->toArray();
			}
		}
		elseif (method_exists($this->_type, '__toString')) {
			foreach ($this->_container as $k => $v) {
				$output[$k] = $v->__toString();
			}
		}
		else {
			//	else this is an array of some generic objects
			foreach ($this->_container as $k => $v) {
				$output[$k] = $v;
			}
		}

		if ($omitEmpty) {
			//	Is this an indexed array (not associative)?
			$isIndexed = (array_values($output) === $output);

			//	Remove empty items.
			foreach ($output as $k => $v) {
				if (empty($v) || (is_object($v) && empty((array)$v))) {
					unset($output[$k]);
				}
			}

			//	If it's an indexed array then fix the indexes.
			if ($isIndexed) {
				$output = array_values($output);
			}
		}

		return $output;
	}

	/**
	 * Merge input with clone of this and return new TypedArray.
	 *
	 * Similar to the function array_merge().
	 *
	 * @param Traversable|array $ta
	 *
	 * @return \Diskerror\Typed\TypedArray
	 */
	public function merge($ta): self
	{
		$this->_massageBlockInput($in);

		$ret = clone $this;

		foreach ($ta as $k => $v) {
			if (is_int($k)) {
				$ret[] = $v;
			}
			else {
				$ret[$k] = $v;
			}
		}

		return $ret;
	}

	/**
	 * Required by the ArrayAccess interface.
	 *
	 * @param string|int $offset
	 *
	 * @return bool
	 */
	public function offsetExists($offset): bool
	{
		return isset($this->_container[$offset]);
	}

	/**
	 * Required by the ArrayAccess interface.
	 * Returns reference to offset.
	 *
	 * http://stackoverflow.com/questions/20053269/indirect-modification-of-overloaded-element-of-splfixedarray-has-no-effect
	 *
	 * @param string|int $offset
	 *
	 * @return mixed
	 */
	public function &offsetGet($offset)
	{
		if (!$this->offsetExists($offset)) {
			//	Be sure offset exists before accessing it.
			$this->offsetSet($offset, null);

			//	Returns new offset created by ::offsetSet().
			if (null === $offset) {
				end($this->_container);
				$offset = key($this->_container);
			}
		}

		return $this->_container[$offset];
	}

	/**
	 * Required by the ArrayAccess interface
	 * Coerces input values to be the required type.
	 *
	 * There are 5 basic conditions for $this->_type:
	 * # $this->_type is null (accept any type and value, like a standard array);
	 * # $this->_type is a scalar [bool, int, float, string];
	 * # $this->_type is an array (check if input value is an object and has toArray);
	 * # $this->_type is an object of type TypedAbstract (call replace());
	 * # $this->_type is any other object.
	 *
	 * There are 3 conditions involving $offset:
	 * # $offset is null;
	 * # $offset is set and does not exist (null);
	 * # $offset is set and exists;
	 *
	 * There are 4 conditions for handling $value:
	 * # $value is null (replace current scalar values with null, reset non-scalars);
	 * # $value is a scalar (cast);
	 * # $value is a an array (check for toArray, or cast);
	 * # $value is a an object (clone if the same as _type, otherwise new _type(value) );
	 *
	 * @param string|int $k
	 * @param mixed      $v
	 */
	public function offsetSet($k, $v)
	{
		if (null === $k || !array_key_exists($k, $this->_container)) {
			$v = (is_object($v) && get_class($v) === $this->_type) ? $v : new $this->_type($v);

			if (null === $k) {
				$this->_container[] = $v;
			}
			else {
				$this->_container[$k] = $v;
			}

			return;
		}

		if (is_a($this->_type, AtomicInterface::class, true)) {
			$this->_container[$k]->set($v);
			return;
		}

		if (is_a($this->_type, TypedAbstract::class, true)) {
			$this->_container[$k]->replace($v);
			return;
		}

		$this->_container[$k] = new $this->_type($v);
	}

	/**
	 * Required by the ArrayAccess interface.
	 *
	 * @param string|int $offset
	 */
	public function offsetUnset($offset)
	{
		unset($this->_container[$offset]);
	}

	/**
	 * Make sure object is deep copied.
	 */
	public function __clone()
	{
		foreach ($this->_container as $k => $v) {
			if (is_object($v)) {
				$this->_container[$k] = clone $v;
			}
		}
	}

	/**
	 * Returns array keys.
	 *
	 * @return array
	 */
	public function keys(): array
	{
		return array_keys($this->_container);
	}

	/**
	 * Apply new names from input array values.
	 *
	 * @param array $keys
	 *
	 * @return TypedArray
	 * @throws LengthException
	 */
	public function combine(array $keys): self
	{
		if (count($keys) !== count($this->_container)) {
			throw new LengthException('array counts do not match');
		}

		$this->_container = array_combine($keys, $this->_container);

		return $this;
	}

	/**
	 * Behave like array_shift.
	 *
	 * @return mixed
	 */
	public function shift()
	{
		return array_shift($this->_container);
	}

	/**
	 * @return array
	 */
	public function getValues()
	{
		return array_values($this->_container);
	}
}


<?php
/**
 * This file is part of keenly from.
 * @author brain_yang<qiaopi520@qq.com>
 * (c) brain_yang
 * github: https://github.com/keenlysoft/
 * @time 2019年3月25日 20:54:42
 * For the full copyright and license information, please view the LICENSE
 */
namespace keenly\base;

use keenly\session\session;

class security{

    protected $session;

    protected $fontsize = 6;

    protected $number = 5;

    protected $captcha_code;

    public $image;

    public function __construct()
    {
        $this->session =  new session();
    }

    private function createImage(){
        $this->image = imagecreate(120, 40);
        return $this;
    }

    /**
     * @name 设置数字
     *
     */
    private function createCode()
    {
        $fontsize = 140;
        for($i=0;$i < $this->number;$i++){
            //设置字体大小
            //设置字体颜色，随机颜色
            $fontcolor = imagecolorallocate($this->image, rand(0,120),rand(0,120), rand(0,120));      //0-120深颜色
            //设置数字
            $fontcontent = $this->createNumber();
            //10>.=连续定义变量
            $this->captcha_code .= $fontcontent;
            //设置坐标
            $x = ($i*100/4)+rand(5,10);
            $y = rand(5,10);
            imagestring($this->image,$fontsize,$x,$y,$fontcontent,$fontcolor);
        }
        $this->setSession()->disturb();
    }

    /**
     * @name 生成数字保留Session
     * @author brain_yang
     * @time 2019年3月25日 21:08:18
     *
     */
    private function setSession()
    {

        $this->session['authcode'] = $this->captcha_code;
        return $this;
    }

    /**
     * @name 设置数字或者字母
     * @author brain_yang
     * @todo 增加字母
     * @return number
     */
    private function createNumber()
    {
        return rand(0,9);

    }

    /**
     * @name 扰乱正常字符串
     * @author brain_yang
     * @time 2019年3月25日 21:44:18
     * @desc 对验证码渲染干扰像素
     */
    private function disturb()
    {

        for($i=0;$i < $this->number;$i++)
        {
            //设置线的颜色
            $linecolor = imagecolorallocate($this->image,rand(80,220), rand(80,220),rand(80,220));
            //设置线，两点一线
            imageline($this->image,rand(10,99), rand(10,29),rand(10,99), rand(10,29),$linecolor);
        }
    }

    public function image()
    {
        // 建立一幅 100X30 的图像
        $im = imagecreate(200, 300);

        // 白色背景和蓝色文本
        $bg = imagecolorallocate($im, 255, 255, 255);
        $textcolor = imagecolorallocate($im, 0, 0, 255);

        // 把字符串写在图像左上角
        imagestring($im, 40, 30, 150, "Hello world!", $textcolor);

        // 输出图像
        header("Content-type: image/png");
        imagepng($im);
        exit;
        header('Content-Type: image/png');
        $this->createImage()->createCode();
        imagepng($this->image);
        imagedestroy($this->image);
        $this->image;
    }

}


<?php
/**
 * @license MIT
 */
namespace Pivasic\Bundle\Common\File;

use Pivasic\Bundle\Common\File\Exception\FileException;
use Pivasic\Bundle\Common\File\Exception\FileNotFoundException;
use Pivasic\Bundle\Common\File\Extension\Extension;
use Pivasic\Bundle\Common\File\MimeType\MimeType;

/**
 * Class File
 * @package Pivasic\Bundle\Common\File
 */
class File extends \SplFileInfo
{
    /**
     * @param string $path      The path to the file
     * @param bool   $checkPath Whether to check the path or not
     * @throws FileNotFoundException
     */
    public function __construct(string $path, bool $checkPath = true)
    {
        if ($checkPath && !is_file($path)) {
            throw new FileNotFoundException($path);
        }

        parent::__construct($path);
    }

    /**
     * @return string
     */
    public function guessExtension(): string
    {
        return Extension::getInstance()->guess($this->guessMimeType());
    }

    /**
     * @return string
     */
    public function guessMimeType(): string
    {
        return MimeType::getInstance()->guess($this->getPathname());
    }

    /**
     * Moves the file to a new location.
     *
     * @param string $directory   Destination folder
     * @param string $name   New file name
     * @return File
     * @throws FileException
     */
    public function move(string $directory, string $name = ''): File
    {
        $target = $this->getTargetFile($directory, $name);

        if (!@rename($this->getPathname(), $target)) {
            $error = error_get_last();
            throw new FileException(sprintf('Could not rename the file "%s" (%s)', $this->getPathname(), strip_tags($error['message'])));
        }

        $this->customChmod($target);

        return $target;
    }

    /**
     * @param string $directory
     * @param string $name
     * @return File
     * @throws FileException
     */
    protected function getTargetFile(string $directory, string $name = ''): File
    {
        if (!is_dir($directory)) {
            if (false === @mkdir($directory, 0777, true) && !is_dir($directory)) {
                throw new FileException(sprintf('Unable to create the "%s" directory', $directory));
            }
        } elseif (!is_writable($directory)) {
            throw new FileException(sprintf('Unable to write in the "%s" directory', $directory));
        }

        $target = rtrim($directory, '/\\') . DIRECTORY_SEPARATOR . ('' == $name ? $this->getBasename() : $this->getName($name));

        return new self($target, false);
    }

    /**
     * Chmod function with exception
     *
     * @param $target
     * @param $mode
     * @throws FileException
     */
    protected function customChmod(string $target, $mode = 0666)
    {
        if (false === @chmod($target, $mode & ~umask())) {
            throw new FileException(sprintf('Unable to change mode of the "%s"', $target));
        }
    }

    /**
     * Returns locale independent base name of the given path.
     *
     * @param string $name The new file name
     * @return string containing
     */
    protected function getName(string $name): string
    {
        $originalName = str_replace('\\', '/', $name);
        $pos = strrpos($originalName, '/');
        $originalName = false === $pos ? $originalName : substr($originalName, $pos + 1);

        return $originalName;
    }
}


<?php
/**
 * @license MIT
 */
namespace Pivasic\Core;

use Pivasic\Core\Exception\RouteException;

/**
 * Base routing.
 *
 * Class DefaultRoute
 * @package Pivasic\Core
 */
class DefaultRoute implements IRoute
{
    /**
     * Find and call controller, get Response object.
     *
     * @param string $packageRoot
     * @param Request $request
     * @return Response
     * @throws RouteException
     */
    public function getResponse(string &$packageRoot, Request &$request): Response
    {
        $packageRoot = rtrim($packageRoot, '/');
        $route = preg_replace('/\/\d+/u', '/D', $request->route());
        $path = $packageRoot . '/Route/' . $route . '/' . $request->method() . '.php';
        if (file_exists($path)) {
            require $path;
            $controllerClass = $request->package() . '\\Route_' . str_replace('/', '_', $route) . '\\' . $request->method();
            /**
             * @var BaseController $controller
             */
            if (class_exists($controllerClass)) {
                $controller = new $controllerClass($packageRoot, $request);
            } else {
                throw new RouteException(sprintf('Route: the class "%s" does not exist', $controllerClass));
            }

            /**
             * Call handler.
             */
            $handler = filter_input_array(INPUT_POST)['handler'] ?? filter_input_array(INPUT_GET)['handler'] ?? 'index';
            if (method_exists($controllerClass, $handler)) {
                $controller->invoke($handler);
                return $controller->getResponse();
            } else {
                throw new RouteException(sprintf('Route: the method "%s" does not exist', $handler));
            }
        } else {
            throw new RouteException(sprintf('Route: path "%s" does not exist', $request->package() . '/Route/' . $route . '/' . $request->method() . '.php'));
        }
    }
}


<?php
/**
 * @license MIT
 */
namespace Pivasic\Bundle\Common\File;

use Pivasic\Bundle\Common\File\Exception\FileException;

/**
 * Class FileUpload
 * @package Pivasic\Bundle\Common\File
 */
class FileUpload extends File
{
    /**
     * @param string $path
     * @param string $name
     * @param int $size
     * @param string $mimeType
     * @param null $error
     */
    public function __construct(string $path, string $name, int $size = 0, string $mimeType = '', $error = null)
    {
        $this->name = $this->getName($name);
        $this->size = $size;
        $this->mimeType = $mimeType ?: 'application/octet-stream';
        $this->error = $error ?: UPLOAD_ERR_OK;

        parent::__construct($path, UPLOAD_ERR_OK == $this->error);
    }

    /**
     * Get file content.
     *
     * @return string|mixed
     */
    public function read()
    {
        $data = '';
        $fileObj = $this->openFile();
        while (!$fileObj->eof()) {
            $data .= $fileObj->fread(4096);
        }
        $fileObj = null;
        return $data;
    }

    /**
     * Returns the original file name.
     *
     * It is extracted from the request from which the file has been uploaded.
     * Then it should not be considered as a safe value.
     *
     * @return string The original name
     */
    public function nameUnsafe(): string
    {
        return $this->name;
    }

    /**
     * Returns the file size.
     *
     * It is extracted from the request from which the file has been uploaded.
     * Then it should not be considered as a safe value.
     *
     * @return int The file size
     */
    public function sizeUnsafe(): int
    {
        return $this->size;
    }

    /**
     * Returns the file mime type.
     *
     * The client mime type is extracted from the request from which the file
     * was uploaded, so it should not be considered as a safe value.
     *
     * @return string The mime type
     */
    public function mimeTypeUnsafe(): string
    {
        return $this->mimeType;
    }

    /**
     * Returns the upload error.
     *
     * If the upload was successful, the constant UPLOAD_ERR_OK is returned.
     * Otherwise one of the other UPLOAD_ERR_XXX constants is returned.
     *
     * @return int The upload error
     */
    public function error()
    {
        return $this->error;
    }

    /**
     * Returns an informative upload error message.
     *
     * @return string The error message regarding the specified error code
     */
    public function errorMessage(): string
    {
        static $errors = array(
            UPLOAD_ERR_INI_SIZE => 'The file "%s" exceeds your upload_max_filesize ini directive (limit is %d KiB).',
            UPLOAD_ERR_FORM_SIZE => 'The file "%s" exceeds the upload limit defined in your form.',
            UPLOAD_ERR_PARTIAL => 'The file "%s" was only partially uploaded.',
            UPLOAD_ERR_NO_FILE => 'No file was uploaded.',
            UPLOAD_ERR_CANT_WRITE => 'The file "%s" could not be written on disk.',
            UPLOAD_ERR_NO_TMP_DIR => 'File could not be uploaded: missing temporary directory.',
            UPLOAD_ERR_EXTENSION => 'File upload was stopped by a PHP extension.',
        );

        $errorCode = $this->error;
        $maxFileSize = $errorCode === UPLOAD_ERR_INI_SIZE ? $this->getMaxFileSize() / 1024 : 0;
        $message = isset($errors[$errorCode]) ? $errors[$errorCode] : 'The file "%s" was not uploaded due to an unknown error.';

        return sprintf($message, $this->name, $maxFileSize);
    }

    /**
     * Returns the original file extension.
     *
     * It is extracted from the original file name that was uploaded.
     * Then it should not be considered as a safe value.
     *
     * @return string The extension
     */
    public function extensionUnsafe(): string
    {
        return pathinfo($this->name, PATHINFO_EXTENSION);
    }

    /**
     * Returns whether the file was uploaded successfully.
     *
     * @return bool True if the file has been uploaded with HTTP and no error occurred.
     */
    public function isValid(): bool
    {
        return $this->error === UPLOAD_ERR_OK && is_uploaded_file($this->getPathname());
    }

    /**
     * Returns the maximum size of an uploaded file as configured in php.ini.
     *
     * @return int The maximum size of an uploaded file in bytes
     */
    public function getMaxFileSize(): int
    {
        $iniMax = strtolower(ini_get('upload_max_filesize'));

        if ('' === $iniMax) {
            return PHP_INT_MAX;
        }

        $max = ltrim($iniMax, '+');
        if (0 === strpos($max, '0x')) {
            $max = intval($max, 16);
        } elseif (0 === strpos($max, '0')) {
            $max = intval($max, 8);
        } else {
            $max = (int) $max;
        }

        switch (substr($iniMax, -1)) {
            case 't':
                $max *= 1024;
            // no break
            case 'g':
                $max *= 1024;
            // no break
            case 'm':
                $max *= 1024;
            // no break
            case 'k':
                $max *= 1024;
            // no break
        }

        return $max;
    }

    /**
     * Moves the file to a new location.
     *
     * @param string $directory Destination folder
     * @param string $name      New file name
     * @return File A File object representing the new file
     * @throws FileException
     */
    public function move(string $directory, string $name = ''): File
    {
        if ($this->isValid()) {
            $target = $this->getTargetFile($directory, $name);

            if (!@move_uploaded_file($this->getPathname(), $target)) {
                $error = error_get_last();
                throw new FileException(sprintf('Could not move the file "%s" to "%s" (%s)', $this->getPathname(), $target, strip_tags($error['message'])));
            }

            $this->customChmod($target);

            return $target;
        }

        throw new FileException($this->errorMessage());
    }

    private $name;
    private $size;
    private $mimeType;
    private $error;
}


<?php
/**
 * @license MIT
 */
namespace Pivasic\Core;

use Pivasic\Bundle\Debug\Wrap;
use Pivasic\Bundle\Template\Native;

/**
 * Base functions to service request.
 *
 * Class BaseController
 * @package Pivasic\Core
 */
class BaseController
{
    /**
     * @param string $packageRoot
     * @param Request $request
     */
    public function __construct(string &$packageRoot, Request &$request)
    {
        $this->packageRoot =& $packageRoot;
        $this->request =& $request;
        $this->response = new Response();
        $this->data['request'] =& $this->request;
        $this->deleteJsonKeys = true;
    }

    /**
     * @param string $handler
     */
    public function invoke(string $handler)
    {
        $this->$handler();
    }

    /**
     * @return Response
     */
    public function getResponse(): Response
    {
        return $this->response;
    }

    /**
     * @param bool $delete
     */
    protected function deleteJsonKeys(bool $delete)
    {
        $this->deleteJsonKeys = $delete;
    }

    /**
     * @param Response $response
     */
    protected function setResponse(Response &$response)
    {
        $this->response =& $response;
    }

    /**
     * Add items to the template data array.
     *
     * @param array $data
     */
    protected function addData(array $data)
    {
        $this->data = array_replace($this->data, $data);
    }

    /**
     * Create Response from template.
     *
     * @param string $name
     * @param array $data
     */
    protected function setView(string $name = '', array $data = [])
    {
        if (!empty($data)) {
            $this->data = array_replace($this->data, $data);
        }
        $content = (new Native($this->packageRoot, $this->request->language(), !Wrap::isEnabled()))->getContent($name, $this->data);
        $this->response->setContent($content);
    }

    /**
     * Create Response from content.
     *
     * @param string $content
     */
    protected function setContent(string $content)
    {
        $this->response->setContent($content);
    }

    /**
     * Create Response from content.
     *
     * @param array $content
     */
    protected function setJSONContent(array $content)
    {
        if ($this->deleteJsonKeys) {
            $content = $this->deleteArrayKeys($content);
        }
        $content = json_encode($content, JSON_UNESCAPED_UNICODE);
        $this->response->setContentTypeJson();
        $this->response->setContent($content);
    }

    /**
     * Redirect to the URL with statusCode.
     *
     * @param string $url
     * @param int $statusCode
     */
    protected function setRedirect(string $url = '', int $statusCode = 303)
    {
        $this->response->redirect($url, $statusCode);
    }

    /**
     * Get route digit's.
     *
     * @return array
     */
    protected function getNumList(): array
    {
        preg_match_all('/\/\d+/u', $this->request->route(), $numList);
        $numList = $numList[0];
        $numList = array_map(function($val) {
            return intval(ltrim($val, '/'));
        }, $numList);
        return $numList;
    }

    /**
     * @param $arr
     * @return array
     */
    private function deleteArrayKeys(&$arr): array
    {
        $lst = [];
        foreach($arr as $k => $v){
            if (is_array($v)) {
                $lst[] = $this->deleteArrayKeys($v);
            } else {
                $lst[] = $v;
            }
        }
        return $lst;
    }

    protected $request;
    protected $response;
    protected $data;
    protected $deleteJsonKeys;

    private $packageRoot;
}


<?php

/*
 * This file is part of the OrkestraApplicationBundle package.
 *
 * Copyright (c) Orkestra Community
 *
 * For the full copyright and license information, please view the LICENSE file
 * that was distributed with this source code.
 */

namespace Orkestra\Bundle\ApplicationBundle\Helper;

use Symfony\Component\DependencyInjection\ContainerInterface,
    Symfony\Component\Form\AbstractType;
use Symfony\Component\PropertyAccess\Exception\UnexpectedTypeException;
use Symfony\Component\PropertyAccess\PropertyAccess;

class FormHelper
{
    private $_container;

    private $_types = array();

    public function __construct(ContainerInterface $container)
    {
        $this->_container = $container;
    }

    public function addType($className, AbstractType $type, $property, $value)
    {
        if (empty($property)) {
            $this->_types['defaults'][$className] = $type;
        }
        else {
            $this->_types[$className][$property][$value] = $type;
        }
    }

    public function getTypes()
    {
        return $this->_types;
    }

    public function getDefaultType($entity)
    {
        $className = is_object($entity) ? get_class($entity) : $entity;

        if (!empty($this->_types['defaults'][$className])) {
            return $this->_types['defaults'][$className];
        }

        throw new \RuntimeException(sprintf('Unable to locate FormType for %s: %s', $className, $entity));
    }

    public function getType($entity, $className = null)
    {
        if (!$className) {
            $className = is_object($entity) ? get_class($entity) : $entity;
        }

        if (!empty($this->_types[$className])) {
            foreach ($this->_types[$className] as $property => $values) {
                $value = $this->_parseValue($entity, $property);

                if (is_object($value)) {
                    $value = "{$value}";
                }

                if (!empty($values[$value])) {
                    return $values[$value];
                }
            }
        }

        if (!empty($this->_types['defaults'][$className])) {
            return $this->_types['defaults'][$className];
        }

        throw new \RuntimeException(sprintf('Unable to locate FormType for %s: %s', $className, $entity));
    }

    /**
     * Parse Value
     *
     * Given a starting object, this will split $content into parts and
     * iterate through each part, effectively creating a chained method
     * call.
     *
     * @param object $item
     * @param string $content
     * @return mixed
     */
    protected function _parseValue($item, $content)
    {
        $value = null;
        try {
            $value = PropertyAccess::createPropertyAccessor()->getValue($item, $content);
        } catch (UnexpectedTypeException $e) {
            // Suppress potentially null values
        }

        return $value;
    }
}


<?php

/**
 * TechDivision\Import\Product\Media\Ee\Observers\EeMediaGalleryUpdateObserver
 *
 * NOTICE OF LICENSE
 *
 * This source file is subject to the Open Software License (OSL 3.0)
 * that is available through the world-wide-web at this URL:
 * http://opensource.org/licenses/osl-3.0.php
 *
 * PHP version 5
 *
 * @author    Tim Wagner <t.wagner@techdivision.com>
 * @copyright 2016 TechDivision GmbH <info@techdivision.com>
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
 * @link      https://github.com/techdivision/import-product-media-ee
 * @link      http://www.techdivision.com
 */

namespace TechDivision\Import\Product\Media\Ee\Observers;

use TechDivision\Import\Product\Media\Ee\Utils\MemberNames;

/**
 * Observer that provides extended mapping functionality to map a SKU to a row ID (EE Feature).
 *
 * @author    Tim Wagner <t.wagner@techdivision.com>
 * @copyright 2016 TechDivision GmbH <info@techdivision.com>
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
 * @link      https://github.com/techdivision/import-product-media-ee
 * @link      http://www.techdivision.com
 */
class EeMediaGalleryUpdateObserver extends EeMediaGalleryObserver
{

    /**
     * Initialize the product media gallery value to entity with the passed attributes and returns an instance.
     *
     * @param array $attr The product media gallery value to entity attributes
     *
     * @return array|null The initialized product media gallery value to entity, or NULL if the product media gallery value to entity already exists
     */
    protected function initializeProductMediaGalleryValueToEntity(array $attr)
    {

        // load the row/value ID
        $rowId = $attr[MemberNames::ROW_ID];
        $valueId = $attr[MemberNames::VALUE_ID];

        // query whether the product media gallery value to entity entity already exists or not
        if ($this->loadProductMediaGalleryValueToEntityByValueIdAndRowId($valueId, $rowId)) {
            return;
        }

        // simply return the attributes
        return $attr;
    }

    /**
     * Load's the product media gallery with the passed value/entity ID.
     *
     * @param integer $valueId The value ID of the product media gallery value to entity to load
     * @param integer $rowId   The row ID of the product media gallery value to entity to load
     *
     * @return array The product media gallery
     */
    protected function loadProductMediaGalleryValueToEntityByValueIdAndRowId($valueId, $rowId)
    {
        return $this->getProductMediaProcessor()->loadProductMediaGalleryValueToEntityByValueIdAndRowId($valueId, $rowId);
    }
}


<?php

namespace Orchid\Defender\Middleware;

use Closure;

class Firewall
{
    /**
     * Handle an incoming request.
     *
     * @param \Illuminate\Http\Request $request
     * @param \Closure                 $next
     *
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $listIp = config('defender');

        if (count($listIp['whitelist']) && !in_array($request->ip(), $listIp['whitelist'])) {
            abort(105);
        }

        if (count($listIp['blacklist']) && !in_array($request->ip(), $listIp['blacklist'])) {
            abort(105);
        }

        return $next($request);
    }
}


<?php
/**
 * Created by PhpStorm.
 * User: execut
 * Date: 12/26/17
 * Time: 3:37 PM
 */

namespace execut\actions\widgets;

use execut\loadingOverlay\LoadingOverlay;
use execut\yii\jui\WidgetTrait;
use yii\helpers\ArrayHelper;
use yii\helpers\Html;
use yii\helpers\Url;
use kartik\alert\Alert;

class DetailView extends \kartik\detail\DetailView
{
    use WidgetTrait;
    const DEFAULT_BUTTONS_TEMPLATE = '{save}  {apply}  {cancel}';
    const All_BUTTONS_TEMPLATE = '{check}  {save}  {apply}  {cancel}';
    public $uniqueId = null;
    public $action = null;
    public $buttonsTemplate = self::DEFAULT_BUTTONS_TEMPLATE;
    public $saveButton = self::BUTTON_SAVE;
    public $checkButton = self::BUTTON_CHECK;
    public $applyButton = self::BUTTON_APPLY;
    public $cancelButton = self::BUTTON_CANCEL;
    public $backUrl = null;
    public $alertBlockAddon = null;

    const BUTTON_CANCEL = '<input type="submit" name="cancel" value="Отмена" class="btn btn-default" title="Отменить" onclick="$(this).parents(\'form\').data(\'yiiActiveForm\').validated = true">';
    const BUTTON_APPLY = '<input type="submit" name="apply" value="Применить" class="btn btn-primary" href="" title="Сохранить изменения">';
    const BUTTON_CHECK = '<input type="submit" name="check" value="Проверить" class="btn btn-info" href="" title="Проверить">';
    const BUTTON_SAVE = '<input type="submit" name="save" value="Отправить" class="btn btn-primary" href="" title="Сохранить и вернуться">';

    public function __construct($config = [])
    {
        $config = ArrayHelper::merge([
            'panel'=> false,
//            [
//                'heading'=> '',
//                'footer' => ' {buttons}',
////                'type'=>\kartik\detail\DetailView::TYPE_PRIMARY,
//                'headingOptions' => [
//                    'template' => ''
//                ],
//                'footerOptions' => [
//                    'style' => 'height: 31px',
//                ],
//            ],
            'buttons1' => '',
            'buttonContainer' => [
                'class' => 'buttons-container',
            ],
            'bordered' => true,
            'striped' => true,
            'condensed' => true,
            'responsive' => false,
            'hideIfEmpty' => true,
            'hover' => true,
//                        'hAlign'=> true,
//                        'vAlign'=> true,
//                        'fadeDelay'=> 2000,
//                        'container' => ['id'=>'kv-demo'],
            'formOptions' => [
                'enableAjaxValidation' => false,
                'validateOnChange' => false,
                'validateOnSubmit' => false,
                'validateOnBlur' => false,
                'options' => [
                    'enctype'=>'multipart/form-data',
                ],
            ],
        ], $config);

        parent::__construct($config);
    }

    public function run() {
        echo LoadingOverlay::widget();
        $this->mainTemplate = $this->renderAlertBlock() . ((!empty($this->attributes) && count($this->attributes) > 8) ? '{buttons}' : '') . '{detail}{buttons}';

        $this->_registerBundle();
        parent::registerPlugin('DetailView');
        echo $this->_beginContainer();
        $r = parent::run();
        echo $this->_endContainer();

        return $r;
    }

    public function init()
    {
        $this->attributes = $this->model->getFormFields();
        $this->formOptions['action'] = $this->getAction();
        $this->deleteOptions = [
            'url' => Url::to([
                $this->uniqueId . '/delete',
                'id' => $this->model->primaryKey,
            ]),
            'kvdelete' => true
        ];
        $this->formOptions['validationUrl'] = $this->getAction();

        parent::init();
    }

    protected function getAction() {
        if ($this->action !== null) {
            return $this->action;
        }

        return Url::to([
            $this->uniqueId . '/update',
            'id' => $this->model->primaryKey,
        ]);
    }

    public function runWidget()
    {
//        $this->buttons1 = $this->renderSubmitButtons();
        $this->buttons1 = $this->renderSubmitButtons();
        $this->buttons2 = $this->renderSubmitButtons();
        parent::runWidget(); // TODO: Change the autogenerated stub
    }

    /**
     * Initializes and renders alert container block
     */
    protected function renderAlertBlock()
    {
        $session = \Yii::$app->session;
        $flashes = $session->getAllFlashes();
        $alertContainerOptions = [
            'style' => 'max-width:400px'
        ];
        if (count($flashes) === 0) {
            Html::addCssStyle($alertContainerOptions, 'display:none;');
        }
        $out = Html::beginTag('div', $alertContainerOptions);
        foreach ($flashes as $type => $message) {
            if (is_array($message)) {
                $message = implode('
', $message);
            }

            $alertWidgetOptions = [];
            $alertWidgetOptions['body'] = $message;
            $alertWidgetOptions['options'] = [
                'class' => ['alert', 'alert-success'],
                'style' => 'padding-left:10px;padding-right:10px;'
            ];
            $out .= "\n" . Alert::widget($alertWidgetOptions);
            $session->removeFlash($type);
        }

        $out .= "\n
";

        return $this->alertBlockAddon . $out;
    }

    /**
     * @param $cancelUrl
     * @return string
     */
    public function renderSubmitButtons()
    {
        $cancelButton = $this->cancelButton;
        $backUrl = $this->backUrl;
        if ($backUrl === null) {
            $backUrlParts = explode('/', $this->uniqueId);
            unset($backUrlParts[count($backUrlParts) - 1]);
            $backUrl = [implode('/', $backUrlParts)];
        }
        if (is_array($backUrl)) {
            $backUrl = Url::to($backUrl);
        }

        $cancelButton = strtr($cancelButton, [
            '{backUrl}' => $backUrl,
        ]);

        $buttonsTemplate = $this->buttonsTemplate;
        if (is_callable($buttonsTemplate)) {
            $buttonsTemplate = call_user_func($buttonsTemplate, $this->model);
        }

        return strtr($buttonsTemplate, [
            '{check}' => $this->checkButton,
            '{save}' => $this->saveButton,
            '{apply}' => $this->applyButton,
            '{cancel}' => $cancelButton,
        ]);
    }
}


<?php
/**
 * Created by PhpStorm.
 * User: execut
 * Date: 2/21/18
 * Time: 2:44 PM
 */

namespace execut\actions\widgets;

use execut\yii\jui\WidgetTrait;
use kartik\alert\Alert;
use yii\helpers\ArrayHelper;
use yii\helpers\Html;
use yii\helpers\Inflector;
use yii\helpers\Json;
use yii\helpers\Url;
use kartik\base\Config;

class GridView extends \kartik\grid\GridView
{
    use WidgetTrait;
    public $addButtonUrl = null;
    public $updateUrl = null;
    public $title = null;
    public $isAjaxCrud = false;
    public $formModel = null;
    public $uniqueId = null;
    public $hover = true;
    public $responsiveWrap = false;
    public function init()
    {
        $this->toolbar = $this->getToolbarConfig();
        $rowOptions = function ($row) {
            if ($this->isAjaxCrud) {
                $attributes = Json::encode($row->attributes);
            } else {
                $attributes = [];
            }

            $rowPrimaryKey = $row->primaryKey;
            if (is_array($rowPrimaryKey)) {
                $dataId = $rowPrimaryKey;
                $rowPrimaryKeyString = implode('-', $rowPrimaryKey);
            } else {
                $dataId = [
                    'id' => $rowPrimaryKey,
                ];
                $rowPrimaryKeyString = $rowPrimaryKey;
            }

            return [
                'class' => 'link-row',
                'id' => $row->formName() . '-' . $rowPrimaryKeyString,
                'data-id' => http_build_query($dataId),
                'attributes' => $attributes,
            ];
        };

        if (is_callable($this->rowOptions)) {
            $oldRowOptions = $this->rowOptions;
            $this->rowOptions = function ($row) use ($oldRowOptions, $rowOptions) {
                $oldData = $oldRowOptions($row);
                if ($oldData === null) {
                    $oldData = [];
                }

                return ArrayHelper::merge($rowOptions($row), $oldData);
            };
        } else if (is_array($this->rowOptions)) {
            $oldRowOptions = $this->rowOptions;
            $this->rowOptions = function ($row) use ($oldRowOptions, $rowOptions) {
                return ArrayHelper::merge($rowOptions($row), $oldRowOptions);
            };
        } else {
            $this->rowOptions = $rowOptions;
        }

        return parent::init();
    }

    protected function getUpdateUrl() {
        if ($this->updateUrl !== null) {
            return $this->updateUrl;
        }

        return $this->addButtonUrl;
    }

    /**
     * Registers a specific jQuery UI widget options
     * @param string $name the name of the jQuery UI widget
     * @param string $id the ID of the widget
     */
    protected function registerWidget($name = null, $id = null)
    {
        if ($name === null) {
            $name = $this->getDefaultJsWidgetName();
        }

        $this->_registerBundle();

        if (!$this->isAjaxCrud && $this->getUpdateUrl()) {
            if ($id === null) {
                $id = $this->options['id'];
            }

            $options = empty($this->clientOptions) ? '' : Json::htmlEncode([
                'updateUrl' => Url::to($this->getUpdateUrl())
            ]);
            $js = "jQuery('#$id').$name($options);";
            $this->getView()->registerJs($js);
        }
    }

    public function run()
    {
        $this->registerWidget();
        parent::run();
    }

    /**
     * @param $refreshUrlParams
     * @return array
     */
    public function getToolbarConfig(): array
    {
        if ($this->toolbar === false) {
            return [];
        }
//        $refreshUrlParams = [
//            $this->adapter->uniqueId,
//        ];
//
//        foreach ($this->refreshAttributes as $key) {
//            if (!empty($this->adapter->actionParams->get[$key])) {
//                $refreshUrlParams[$key] = $this->adapter->actionParams->get[$key];
//            }
//        }
        if (!is_array($this->toolbar)) {
            if (empty($this->toolbar)) {
                $this->toolbar = [];
            } else {
                $this->toolbar = [$this->toolbar];
            }
        }

        return ArrayHelper::merge([
//            'massEdit' => ['content' => $this->renderMassEditButton()],
//            'massVisible' => ['content' => $this->renderVisibleButtons()],
            'add' => ['content' => $this->renderAddButton()],
            'alert' => ['content' => $this->renderAlertBlock()],
//            'refresh' => [
//                'content' => Html::a('', $refreshUrlParams, ['data-pjax' => 0, 'class' => 'btn btn-default', 'title' => 'Reset Grid']),
//            ],
//            'dynaParams' => ['content' => '{dynagridFilter}{dynagridSort}{dynagrid}'],
//            'toggleData' => '{toggleData}',
//            'export' => '{export}',
        ], $this->toolbar);
    }

    public function beginPjax() {
        parent::beginPjax();
        if ($this->isAjaxCrud) {
            $model = $this->getFormModel();

            if ($this->pjax) {
                $gridId = $this->id . '-pjax';
            } else {
                $gridId = null;
            }

            echo EditDialog::widget([
                'id' => $this->id . '-edit',
                'model' => $model,
                'uniqueId' => $this->uniqueId,
                'alertId' => $this->id . '-alert',
                'clientOptions' => [
                    'inputsPrefix' => str_replace('-', '', Inflector::camel2id($model->formName())),
                    'editButtons' => 'tr[data-key]',
                    'gridId' => $gridId,
                ],
                'toggleButtonOptions' => false,
            ]);
        }
    }

    public function renderAlertBlock() {
        $alertWidgetOptions = [
            'id' => $this->id . '-alert',
        ];

        $alertWidgetOptions['body'] = '';
        $alertWidgetOptions['options'] = [
            'class' => ['alert', 'alert-success'],
            'style' => 'padding-left:10px;padding-right:10px;display:none;'
        ];

        return Alert::widget($alertWidgetOptions);
    }

    /**
     * @return string
     */
    protected function renderAddButton()
    {
        $title = \yii::t('execut.actions', 'Add') . ' ' . $this->title;
        $url = $this->addButtonUrl;
        if (!is_array($url)) {
            $url = [$url];
        }

        return Html::a($title, Url::to($url), [
                'id' => $this->id . '-edit-add-button',
                'type' => 'button',
                'data-pjax' => 0,
                'title' => $title,
                'class' => 'btn btn-success'
            ]);
    }

    /**
     * @return null
     */
    protected function getFormModel()
    {
        $model = $this->formModel;
        if (is_callable($model)) {
            $model = $model();
        }
        return $model;
    }
}


<?php

/*
 * This file is part of the OrkestraApplicationBundle package.
 *
 * Copyright (c) Orkestra Community
 *
 * For the full copyright and license information, please view the LICENSE file
 * that was distributed with this source code.
 */

namespace Orkestra\Bundle\ApplicationBundle\Helper;

use Doctrine\Common\Persistence\Proxy;
use Doctrine\ORM\EntityManager;
use Orkestra\Bundle\ApplicationBundle\Entity\HashedEntity;
use Orkestra\Bundle\ApplicationBundle\Model\PersistentModelInterface;

class HashedEntityHelper
{
    /**
     * @var EntityManager
     */
    private $entityManager;

    /**
     * Constructor
     *
     * @param EntityManager $entityManager
     */
    public function __construct(EntityManager $entityManager)
    {
        $this->entityManager = $entityManager;
    }

    /**
     * @param  PersistentModelInterface $entity
     * @param  \DateTime                $expiration
     * @return HashedEntity
     */
    public function create(PersistentModelInterface $entity, \DateTime $expiration = null)
    {
        $entityClass = get_class($entity);
        if ($entity instanceof Proxy) {
            $reflClass = new \ReflectionClass($entity);
            $entityClass = $reflClass->getParentClass()->getName();
        }

        $hash = $this->entityManager->getRepository('OrkestraApplicationBundle:HashedEntity')
            ->createQueryBuilder('h')
            ->where('h.referenceId = :refId')
            ->andWhere('h.className = :className')
            ->andWhere('h.dateExpires >= :curDate')
            ->andWhere('h.active = true')
            ->setParameters(array(
                'refId' => $entity->getId(),
                'className' => $entityClass,
                'curDate' => new \DateTime()
            ))
            ->getQuery()->getOneOrNullResult();

        if (!$hash) {
            $hash = new HashedEntity();
            $hash->setClassName($entityClass);
            $hash->setReferenceId($entity->getId());
        }

        $hash->setDateExpires($expiration);
        $hash->setReferencedObject($entity);
        $hash->setHash(sha1(uniqid(mt_rand(), true)));

        return $hash;
    }

    /**
     * @param string $hash
     * @param string $class
     *
     * @return HashedEntity
     */
    public function lookup($hash, $class)
    {
        $qb = $this->entityManager->getRepository('OrkestraApplicationBundle:HashedEntity')
            ->createQueryBuilder('h');

        $result = $qb->where('h.hash = :hash')
            ->andWhere('h.className = :className')
            ->andWhere($qb->expr()->orX(
                $qb->expr()->gte('h.dateExpires', ':curDate'),
                $qb->expr()->isNull('h.dateExpires')
            ))
            ->andWhere('h.active = true')
            ->setParameters(array(
                'hash' => $hash,
                'className' => $class,
                'curDate' => new \DateTime()
            ))
            ->getQuery()->getOneOrNullResult();

        if ($result) {
            $referencedObject = $this->entityManager->getRepository($class)
                ->createQueryBuilder('x')
                ->where('x.id = :refId')
                ->setParameter('refId', $result->getReferenceId())
                ->getQuery()->getOneOrNullResult();

            if ($referencedObject) {
                $result->setReferencedObject($referencedObject);
            } else {
                throw new \RuntimeException('Unable to find referenced object.');
            }
        }

        return $result;
    }

    /**
     * @param HashedEntity $hashedEntity
     */
    public function invalidate($hashedEntity)
    {
        $hashedEntity->setActive(false);
    }
}


<?php
namespace KayStrobach\Menu\ViewHelpers\Widget;

/*                                                                        *
 * This script belongs to the TYPO3 Flow package "Fluid".                 *
 *                                                                        *
 * It is free software; you can redistribute it and/or modify it under    *
 * the terms of the GNU Lesser General Public License, either version 3   *
 * of the License, or (at your option) any later version.                 *
 *                                                                        *
 * The TYPO3 project - inspiring people to share!                         *
 *                                                                        */

use Neos\Flow\Annotations as Flow;

class MenuViewHelper extends \Neos\FluidAdaptor\Core\Widget\AbstractWidgetViewHelper {

	/**
	 * @Flow\Inject
	 * @var \KayStrobach\Menu\ViewHelpers\Widget\Controller\MenuController
	 */
	protected $controller;

    /**
     * Render this view helper
     *
     * @param string $menu
     * @param bool $debug
     * @param string $class
     * @return string
     * @throws \Neos\Flow\Mvc\Exception\InfiniteLoopException
     * @throws \Neos\Flow\Mvc\Exception\StopActionException
     * @throws \Neos\FluidAdaptor\Core\Widget\Exception\InvalidControllerException
     * @throws \Neos\FluidAdaptor\Core\Widget\Exception\MissingControllerException
     */
	public function render($menu = 'Default', $debug = false, $class = null) {
		$response = $this->initiateSubRequest();
		return $response->getContent();
	}
}