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

namespace Diskerror\Typed;

use stdClass;

/**
 * Class ScalarAbstract
 *
 * @package Diskerror\Typed\Scalar
 */
abstract class ScalarAbstract implements AtomicInterface
{
	/**
	 * Stores the scalar value.
	 *
	 * @var mixed
	 */
	protected $_value;

	/**
	 * Indicates whether or not the value can also be null.
	 *
	 * @var bool
	 */
	private $_allowNull;

	/**
	 * @var mixed
	 */
	private $_defaultValue;

	/**
	 * ScalarAbstract constructor.
	 *
	 * @param mixed $in A default of an empty string will cast to false or zero as needed.
	 * @param bool  $allowNull
	 */
	public function __construct($in = '', bool $allowNull = false)
	{
		$this->_allowNull = $allowNull;

		if ($allowNull && null === $in) {
			$this->_value        = null;
			$this->_defaultValue = null;
		}
		else {
			$this->set(null === $in ? '' : $in);
			$this->_defaultValue = $this->_value;
		}
	}

	/**
	 * Returns the scalar value.
	 */
	public function get()
	{
		return $this->_value;
	}

	/**
	 * Filters the value before saving.
	 */
	abstract public function set($in);

	/**
	 * Returns true if value is not null.
	 */
	public function isset(): bool
	{
		return isset($this->_value);
	}

	/**
	 * Sets a null or the default value.
	 */
	public function unset()
	{
		$this->_value = $this->_allowNull ? null : $this->_defaultValue;
	}

	/**
	 * @param stdClass $in
	 *
	 * @return mixed
	 */
	protected static function _castObject(stdClass $in)
	{
		if ($in instanceof AtomicInterface) {
			return $in->get();
		}

		if (method_exists($in, '__toString')) {
			return $in->__toString();
		}

		if (method_exists($in, 'format')) {
			return $in->format('c');
		}

		if (method_exists($in, 'toArray')) {
			return $in->toArray();
		}

		return (array)$in;
	}
}


<?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\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Orkestra\Common\Entity\AbstractEntity;
use Orkestra\Common\Type\DateTime;
use Symfony\Component\HttpFoundation\File\Exception\UploadException;
use Symfony\Component\HttpFoundation\File\UploadedFile;

/**
 * File Entity
 *
 * @ORM\Entity
 * @ORM\Table(name="orkestra_files")
 * @ORM\HasLifecycleCallbacks
 */
class File extends AbstractEntity
{
    /**
     * Create From Uploaded File
     *
     * @param \Symfony\Component\HttpFoundation\File\UploadedFile $upload
     * @param string                                              $uploadPath The directory to save the uploaded file to
     * @param string                                              $filename
     *
     * @throws \Symfony\Component\HttpFoundation\File\Exception\UploadException
     * @return \Orkestra\Bundle\ApplicationBundle\Entity\File
     */
    public static function createFromUploadedFile(UploadedFile $upload, $uploadPath, $filename = null)
    {
        if (!$upload->isValid()) {
            throw new UploadException(sprintf('An error occurred during file upload. Error code: %s', $upload->getError()));
        } elseif (($uploadPath = realpath($uploadPath . '/')) === false) {
            throw new UploadException('An error occurred during file upload. The specified upload path is invalid.');
        }

        if (!$filename) {
            $fullPath = sprintf(
                '%s%s%s.%s',
                rtrim($uploadPath, DIRECTORY_SEPARATOR),
                DIRECTORY_SEPARATOR,
                uniqid(),
                ($upload->getExtension() ?: ($upload->guessExtension() ?: 'file'))
            );
        } else {
            $fullPath = rtrim($uploadPath, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . $filename;
        }

        $file = new self($fullPath, $upload->getClientOriginalName(), $upload->getMimeType(), $upload->getClientSize(), md5_file($upload->getRealPath()));
        $file->_uploadedFile = $upload;

        return $file;
    }

    /**
     * @var \Symfony\Component\HttpFoundation\File\UploadedFile
     */
    private $_uploadedFile = null;

    /**
     * @var string $path The full filesystem path to the file
     *
     * @ORM\Column(name="path", type="string", unique=true)
     */
    protected $path;

    /**
     * @var string $filename
     *
     * @ORM\Column(name="filename", type="string")
     */
    protected $filename;

    /**
     * @var string $mimeType
     *
     * @ORM\Column(name="mime_type", type="string")
     */
    protected $mimeType = '';

    /**
     * @ORM\ManyToMany(targetEntity="Orkestra\Bundle\ApplicationBundle\Entity\Group", fetch="EAGER")
     * @ORM\JoinTable(name="orkestra_file_groups",
     *     joinColumns={@ORM\JoinColumn(name="file_id", referencedColumnName="id")},
     *     inverseJoinColumns={@ORM\JoinColumn(name="group_id", referencedColumnName="id")}
     * )
     */
    protected $groups;

    /**
     * @var string $user
     *
     * @ORM\ManyToOne(targetEntity="Orkestra\Bundle\ApplicationBundle\Entity\User")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="user_id", referencedColumnName="id")
     * })
     */
    protected $user;

    /**
     * @var integer $fileSize
     *
     * @ORM\Column(name="file_size", type="integer")
     */
    protected $fileSize = 0;

    /**
     * @var string $md5
     *
     * @ORM\Column(name="md5_hash", type="string")
     */
    protected $md5 = '';

    /**
     * Constructor
     */
    public function __construct($path, $filename, $mimeType = '', $fileSize = 0, $md5 = '')
    {
        $this->path = $path;
        if (!empty($md5)) {
            $this->md5 = $md5;
        } elseif (file_exists($path)) {
            $this->md5 = md5_file($path);
        }

        $this->filename = $filename;
        $this->mimeType = $mimeType ?: '';
        $this->fileSize = $fileSize ?: 0;

        $this->groups = new ArrayCollection();
    }

    /**
     * Set Filename
     *
     * @param string $filename
     */
    public function setFilename($filename)
    {
        $this->filename = $filename;
    }

    /**
     * Get Filename
     *
     * @return string
     */
    public function getFilename()
    {
        return $this->filename;
    }

    /**
     * Get Path
     *
     * @return string
     */
    public function getPath()
    {
        return $this->path;
    }

    /**
     * Get Mime Type
     *
     * @return string
     */
    public function getMimeType()
    {
        return $this->mimeType;
    }

    /**
     * Get File Size
     *
     * @return float
     */
    public function getFileSize()
    {
        return $this->fileSize;
    }

    /**
     * Get MD5 hash of the file
     *
     * @return string
     */
    public function getMd5()
    {
        return $this->md5;
    }

    /**
     * Get Content
     *
     * Returns the content of the file, unaltered
     *
     * @return mixed
     */
    public function getContent()
    {
        return file_get_contents($this->path);
    }

    /**
     * Add Group
     *
     * @param \Orkestra\Bundle\ApplicationBundle\Entity\Group $group
     */
    public function addGroup(Group $group)
    {
        $this->groups[] = $group;
    }

    /**
     * Remove Group
     *
     * @param \Orkestra\Bundle\ApplicationBundle\Entity\Group $group
     */
    public function removeGroup(Group $group)
    {
        foreach ($this->groups as $index => $existingGroup) {
            if ($existingGroup === $group) {
                unset($this->groups[$index]);

                return;
            }
        }
    }

    /**
     * Get Groups
     *
     * @return \Doctrine\Common\Collections\Collection|\Orkestra\Bundle\ApplicationBundle\Entity\Group[]
     */
    public function getGroups()
    {
        return $this->groups;
    }

    /**
     * Set User
     *
     * @param \Orkestra\Bundle\ApplicationBundle\Entity\User
     */
    public function setUser(User $user)
    {
        $this->user = $user;
    }

    /**
     * Get User
     *
     * @return \Orkestra\Bundle\ApplicationBundle\Entity\User
     */
    public function getUser()
    {
        return $this->user;
    }

    /**
     * Move Uploaded File
     *
     * If the file was uploaded, then this method will move the uploaded file from the temporary
     * directory to its new path.
     *
     * This is usually automatically handled as this method is a prePersist lifecycle callback.
     *
     * @ORM\PrePersist
     */
    public function moveUploadedFile()
    {
        $this->dateCreated = new DateTime();

        if (null === $this->_uploadedFile) {
            return;
        }

        $this->_uploadedFile->move(dirname($this->path), basename($this->path));
        $this->_uploadedFile = null;
    }

    /**
     * Delete
     *
     * Unlinks the file. This does not do anything about the database side of things.
     *
     * This is usually automatically handled as this method is a postRemove lifecycle callback.
     *
     * @ORM\PostRemove
     */
    public function delete()
    {
        unlink($this->path);
    }
}


<?php

/*
 * This file is part of questocat/console-color package.
 *
 * (c) questocat <zhengchaopu@gmail.com>
 *
 * This source file is subject to the MIT license that is bundled
 * with this source code in the file LICENSE.
 */

namespace Questocat\ConsoleColor;

use InvalidArgumentException;

/*
 * @method mixed default()
 * @method mixed black()
 * @method mixed red()
 * @method mixed green()
 * @method mixed yellow()
 * @method mixed blue()
 * @method mixed magenta()
 * @method mixed cyan()
 * @method mixed lightGray()
 * @method mixed darkGray()
 * @method mixed lightRed()
 * @method mixed lightGreen()
 * @method mixed lightYellow()
 * @method mixed lightBlue()
 * @method mixed lightMagenta()
 * @method mixed lightCyan()
 * @method mixed white()
 * @method mixed defaultBackground()
 * @method mixed blackBackground()
 * @method mixed redBackground()
 * @method mixed Background()
 * @method mixed greenBackground()
 * @method mixed yellowBackground()
 * @method mixed blueBackground()
 * @method mixed magentaBackground()
 * @method mixed cyanlightGrayBackground()
 * @method mixed darkGrayBackground()
 * @method mixed lightRedBackground()
 * @method mixed lightGreenBackground()
 * @method mixed lightYellowBackground()
 * @method mixed lightBlueBackground()
 * @method mixed lightMagentaBackground()
 * @method mixed lightCyanBackground()
 * @method mixed whiteBackground()
 * @method mixed bold()
 * @method mixed dim()
 * @method mixed undernewline()
 * @method mixed blink()
 * @method mixed invert()
 * @method mixed hidden()
 */

define('FOREGROUND', 38);
define('BACKGROUND', 48);

class ConsoleColor
{
    const COLORS_256_FOREGROUND = 38;

    const COLORS_256_BACKGROUND = 48;

    /**
     * The current style.
     *
     * @var array
     */
    protected $current = [];

    /**
     * The output instance.
     *
     * @var OutputInterface
     */
    protected $output;

    /**
     * The default colors.
     *
     * @var array
     */
    protected $colors = [
        'default' => 39,
        'black' => 30,
        'red' => 31,
        'green' => 32,
        'yellow' => 33,
        'blue' => 34,
        'magenta' => 35,
        'cyan' => 36,
        'light_gray' => 37,
        'dark_gray' => 90,
        'light_red' => 91,
        'light_green' => 92,
        'light_yellow' => 93,
        'light_blue' => 94,
        'light_magenta' => 95,
        'light_cyan' => 96,
        'white' => 97,
        'default_background' => 49,
        'black_background' => 40,
        'red_background' => 41,
        'green_background' => 42,
        'yellow_background' => 43,
        'blue_background' => 44,
        'magenta_background' => 45,
        'cyan_background' => 46,
        'light_gray_background' => 47,
        'dark_gray_background' => 100,
        'light_red_background' => 101,
        'light_green_background' => 102,
        'light_yellow_background' => 103,
        'light_blue_background' => 104,
        'light_magenta_background' => 105,
        'light_cyan_background' => 106,
        'white_background' => 107,
    ];

    /**
     * The default formats.
     *
     * @var array
     */
    protected $defaultFormats = [
        'bold' => 1,
        'dim' => 2,
        'underline' => 4,
        'blink' => 5,
        'invert' => 7,
        'hidden' => 8,
    ];

    /**
     * The default themes.
     *
     * @var array
     */
    protected $defaultThemes = [
        'info' => [38, 5, 8],
        'warning' => [38, 5, 226],
        'error' => [38, 5, 196],
        'success' => [38, 5, 40],
    ];

    /**
     * ConsoleColor construct.
     *
     * @param OutputInterface|null $output
     */
    public function __construct(OutputInterface $output = null)
    {
        $this->output = $output;
    }

    /**
     * @param string $method
     * @param array  $args
     *
     * @return string|$this
     */
    public function __call($method, $args)
    {
        $str = implode('', $args);

        if ($this->styleWasCalled($method) && $str) {
            return $this->render($str);
        }

        return $this;
    }

    /**
     * @param string $name
     *
     * @throws StyleNotFoundException
     *
     * @return bool
     */
    public function styleWasCalled($name)
    {
        $name = $this->snakeCase($name);
        $supportedStyles = $this->getSupportedStyles();

        if ($code = $this->searchStyle($name, $supportedStyles)) {
            $this->mergeToCurrent($code);

            return true;
        }

        throw new StyleNotFoundException("Invalid style {$name}.");
    }

    /**
     * @param int $code
     * @param int $option
     *
     * @throws InvalidArgumentException
     *
     * @return $this
     */
    public function color256($code, $option = self::COLORS_256_FOREGROUND)
    {
        if (!$this->isSupportedColors256()) {
            throw new InvalidArgumentException('No supported colors 256.');
        }

        $attrs = [$option, 5, $code];
        $this->mergeToCurrent($attrs);

        return $this;
    }

    /**
     * Returns colorized string.
     *
     * @param string $str
     * @param bool   $newline
     *
     * @return string
     */
    public function render($str = null, $newline = true)
    {
        return $this->out($str, $newline);
    }

    /**
     * Set the output.
     *
     * @param OutputInterface $output
     *
     * @return $this
     */
    public function setOutput(OutputInterface $output)
    {
        $this->output = $output;

        return $this;
    }

    /**
     * Returns the output instance.
     *
     * @return OutputInterface
     */
    public function getOutput()
    {
        if (is_null($this->output)) {
            $this->output = new StdOut();
        }

        return $this->output;
    }

    /**
     * Add color to the colors.
     *
     * @param string $color
     * @param int    $code
     */
    public function addColor($color, $code = null)
    {
        $newColors = $this->parseColor($color, $code);

        $this->colors = array_merge($this->colors, $newColors);

        return $this;
    }

    /**
     * Get the supported styles.
     *
     * @return array
     */
    protected function getSupportedStyles()
    {
        return array_merge(
            $this->colors,
            $this->defaultFormats,
            $this->defaultThemes
        );
    }

    /**
     * Merge the current style.
     *
     * @param mixed $code
     *
     * @return $this
     */
    protected function mergeToCurrent($code)
    {
        $this->current = array_merge($this->current, (array) $code);

        return $this;
    }

    /**
     * Convert a string to snake case.
     *
     * @param string $value
     * @param string $delimiter
     *
     * @return string
     */
    protected function snakeCase($value, $delimiter = '_')
    {
        if (!ctype_lower($value)) {
            $value = preg_replace('/\s+/u', '', $value);
            $value = strtolower(preg_replace('/(.)(?=[A-Z])/u', '$1'.$delimiter, $value));
        }

        return $value;
    }

    /**
     * @param string $content
     * @param bool   $newline
     *
     * @return string
     */
    protected function out($content, $newline = true)
    {
        $content = $this->applyStyle($content, $this->current);

        return $this->getOutput()->write($content, $newline);
    }

    /**
     * Apply the string.
     *
     * @param string $str
     * @param array  $attrs
     *
     * @return string
     */
    protected function applyStyle($str, array $attrs)
    {
        return $this->resetStyle()->colorize($str, $attrs);
    }

    /**
     * Reset current style.
     *
     * @return $this
     */
    protected function resetStyle()
    {
        $this->current = [];

        return $this;
    }

    /**
     * Colorize the string.
     *
     * @param string $str
     * @param array  $attrs
     *
     * @return string
     */
    protected function colorize($str, $attrs)
    {
        $start = $this->start($attrs);

        return $start.$str.$this->end();
    }

    /**
     * Get the string that begins the style.
     *
     * @param array $attrs
     *
     * @return string
     */
    protected function start(array $attrs)
    {
        $attrs = $this->buildAttrs($attrs);

        return $this->escSequence($attrs);
    }

    /**
     * Get the string that ends the style.
     *
     * @return string
     */
    protected function end()
    {
        return $this->escSequence(0);
    }

    /**
     * @param string $attrs
     *
     * @return string
     */
    protected function escSequence($attrs)
    {
        return sprintf("\e[%sm", $attrs);
    }

    /**
     * Build the style attributes.
     *
     * @param array $attrs
     *
     * @return string
     */
    protected function buildAttrs(array $attrs)
    {
        return implode(';', $attrs);
    }

    /**
     * @param string     $name
     * @param array      $styles
     * @param mixed|null $default
     *
     * @return mixed
     */
    protected function searchStyle($name, $styles, $default = null)
    {
        if (array_key_exists($name, $styles)) {
            return $styles[$name];
        }

        return $default;
    }

    /**
     * Parse the color.
     *
     * @param string|array $color
     * @param int|null     $code
     *
     * @return array
     */
    protected function parseColor($color, $code = null)
    {
        $colors = is_array($color) ? $color : [$color => $code];
        $return = [];

        array_walk($colors, function ($code, $color) use (&$return) {
            $color = $this->snakeCase($color);
            $return[$color] = $code;
        });

        return $return;
    }

    /**
     * @return bool
     */
    protected function isSupportedColors256()
    {
        return false !== strpos(getenv('TERM'), '256color');
    }
}


<?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\Controller;

use JMS\SecurityExtraBundle\Annotation\Secure;
use Orkestra\Bundle\ApplicationBundle\Entity\User;
use Orkestra\Bundle\ApplicationBundle\Form\ChangePasswordType;
use Orkestra\Bundle\ApplicationBundle\Form\UserType;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Component\HttpFoundation\Request;

/**
 * User controller.
 *
 * @Route("/user")
 */
class UserController extends Controller
{
    /**
     * Lists all User entities.
     *
     * @Route("s/", name="orkestra_users")
     * @Template()
     * @Secure(roles="ROLE_USER_READ")
     */
    public function indexAction()
    {
        $em = $this->getDoctrine()->getManager();

        $entities = $em->getRepository('OrkestraApplicationBundle:User')->findAll();

        return array(
            'entities' => $entities,
        );
    }

    /**
     * Finds and displays a User entity.
     *
     * @Route("/{id}/show", name="orkestra_user_show")
     * @Template()
     * @Secure(roles="ROLE_USER_READ")
     */
    public function showAction($id)
    {
        $em = $this->getDoctrine()->getManager();

        $user = $em->getRepository('Orkestra\Bundle\ApplicationBundle\Entity\User')->find($id);

        if (!$user) {
            throw $this->createNotFoundException('Unable to locate User');
        }

        return array(
            'user' => $user,
        );
    }

    /**
     * Displays a form to create a new User entity.
     *
     * @Route("/new", name="orkestra_user_new")
     * @Template()
     * @Secure(roles="ROLE_USER_WRITE")
     */
    public function newAction()
    {
        $user = new User();
        $form = $this->createForm(UserType::class, $user);

        return array(
            'user' => $user,
            'form' => $form->createView()
        );
    }

    /**
     * Creates a new User entity.
     *
     * @Route("/create", name="orkestra_user_create")
     * @Method("post")
     * @Template("OrkestraApplicationBundle:User:new.html.twig")
     * @Secure(roles="ROLE_USER_WRITE")
     */
    public function createAction(Request $request)
    {
        $user = new User();
        $form = $this->createForm(UserType::class, $user);
        $form->bind($request);

        if ($form->isValid()) {
            $factory = $this->get('security.encoder_factory');
            $encoder = $factory->getEncoder($user);
            $user->setPassword($encoder->encodePassword($user->getPassword(), $user->getSalt()));

            $em = $this->getDoctrine()->getManager();
            $em->persist($user);
            $em->flush();

            $this->get('session')->getFlashBag()->set('success', 'The user has been created.');

            return $this->redirect($this->generateUrl('orkestra_user_show', array('id' => $user->getId())));
        }

        return array(
            'user' => $user,
            'form' => $form->createView()
        );
    }

    /**
     * Reset Password Action
     *
     * @Route("/{id}/reset-password", name="orkestra_user_password_reset")
     * @Template()
     * @Secure(roles="ROLE_USER_WRITE")
     */
    public function resetPasswordAction(Request $request, $id)
    {
        $em = $this->getDoctrine()->getManager();
        $user = $em->getRepository('Orkestra\Bundle\ApplicationBundle\Entity\User')->find($id);

        if (!$user) {
            throw $this->createNotFoundException('Unable to locate User');
        }

        $form = $this->createForm(ChangePasswordType::class, null, array('require_current' => false));

        if ($request->isMethod('POST')) {
            $form->bind($request);

            if ($form->isValid()) {
                $data = $form->getData();

                $factory = $this->get('security.encoder_factory');
                $encoder = $factory->getEncoder($user);
                $user->setPassword($encoder->encodePassword($data['password'], $user->getSalt()));

                $em->persist($user);
                $em->flush();

                $this->get('session')->getFlashBag()->set('success', 'The password has been changed.');

                return $this->redirect($this->generateUrl('orkestra_user_show', array('id' => $id)));
            }
        }

        return array(
            'user' => $user,
            'form' => $form->createView(),
        );
    }

    /**
     * Displays a form to edit an existing User entity.
     *
     * @Route("/{id}/edit", name="orkestra_user_edit")
     * @Template()
     * @Secure(roles="ROLE_USER_WRITE")
     */
    public function editAction($id)
    {
        $em = $this->getDoctrine()->getManager();
        $user = $em->getRepository('Orkestra\Bundle\ApplicationBundle\Entity\User')->find($id);

        if (!$user) {
            throw $this->createNotFoundException('Unable to locate User');
        }

        $form = $this->createForm(UserType::class, $user, array('include_password' => false));

        return array(
            'user' => $user,
            'form' => $form->createView(),
        );
    }

    /**
     * Edits an existing User entity.
     *
     * @Route("/{id}/update", name="orkestra_user_update")
     * @Method("post")
     * @Template("OrkestraApplicationBundle:User:edit.html.twig")
     * @Secure(roles="ROLE_USER_WRITE")
     */
    public function updateAction(Request $request, $id)
    {
        $em = $this->getDoctrine()->getManager();
        $user = $em->getRepository('Orkestra\Bundle\ApplicationBundle\Entity\User')->find($id);

        if (!$user) {
            throw $this->createNotFoundException('Unable to locate User');
        }

        $form = $this->createForm(UserType::class, $user, array('include_password' => false));
        $form->bind($request);

        if ($form->isValid()) {
            $em->persist($user);
            $em->flush();

            $this->get('session')->getFlashBag()->set('success', 'Your changes have been saved.');

            return $this->redirect($this->generateUrl('orkestra_user_show', array('id' => $id)));
        }

        return array(
            'user' => $user,
            'form' => $form->createView(),
        );
    }
}


<?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\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;

/**
 * Overrides necessary service definitions.
 */
class ModifyServiceDefinitionsPass implements CompilerPassInterface
{
    /**
     * {@inheritDoc}
     */
    public function process(ContainerBuilder $container)
    {
        $this->overrideAuthenticationServices($container);
        $this->configureEmailHelper($container);
    }

    /**
     * Overrides authentication related services
     *
     * @param ContainerBuilder $container
     */
    private function overrideAuthenticationServices(ContainerBuilder $container)
    {
        $definition = $container->getDefinition('security.authentication.failure_handler');
        $definition->setClass('Orkestra\Bundle\ApplicationBundle\Security\Authentication\AuthenticationFailureHandler');
    }

    /**
     * Configures the EmailHelper
     *
     * @param ContainerBuilder $container
     */
    private function configureEmailHelper(ContainerBuilder $container)
    {
        if (!class_exists('Swift_Mailer')) {
            $definition = $container->getDefinition('orkestra.application.helper.email');
            $definition->setClass('Orkestra\Bundle\ApplicationBundle\Helper\EmailHelper\MisconfiguredEmailHelper');
            $definition->setArguments(array());
        }
    }
}


<?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\Form\EntityChoice;

use Doctrine\Common\Collections\Collection;
use Symfony\Bridge\Doctrine\Form\ChoiceList\EntityLoaderInterface;
use Symfony\Component\Form\Exception\UnexpectedTypeException;
use Symfony\Component\PropertyAccess\PropertyAccess;

class ArbitrarySetLoader implements EntityLoaderInterface
{
    protected $entities;

    /**
     * @param \Closure $setClosure
     */
    public function __construct($setClosure)
    {
        if ($setClosure instanceof \Closure) {
            $this->entities = $setClosure();
        } elseif (is_array($setClosure) || $setClosure instanceof Collection) {
            $this->entities = $setClosure;
        } else {
            throw new UnexpectedTypeException($setClosure, '\Closure');
        }
    }

    /**
     * Returns an array of entities that are valid choices in the corresponding choice list.
     *
     * @return array The entities.
     */
    public function getEntities()
    {
        return $this->entities;
    }

    /**
     * Returns an array of entities matching the given identifiers.
     *
     * @param string $identifier The identifier field of the object. This method
     *                           is not applicable for fields with multiple
     *                           identifiers.
     * @param array $values The values of the identifiers.
     *
     * @return array The entities.
     */
    public function getEntitiesByIds($identifier, array $values)
    {
        $accessor = PropertyAccess::createPropertyAccessor();
        return array_filter(is_array($this->entities) ? $this->entities : $this->entities->toArray(), function ($entity) use ($identifier, $values, $accessor) {
            return in_array($accessor->getValue($entity, $identifier), $values);
        });
    }
}


<?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\Controller;

use JMS\SecurityExtraBundle\Annotation\Secure;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

/**
 * File controller
 *
 * @Route("/file")
 */
class FileController extends Controller
{
    /**
     * Outputs a file
     *
     * @Route("/{id}/view", name="view_file")
     * @Secure(roles="ROLE_USER")
     */
    public function viewAction(Request $request, $id)
    {
        $em = $this->getDoctrine()->getManager();

        /** @var $file \Orkestra\Bundle\ApplicationBundle\Entity\File */
        $file = $em->find('Orkestra\Bundle\ApplicationBundle\Entity\File', $id);

        if (!$file || !file_exists($file->getPath())) {
            throw $this->createNotFoundException('Unable to locate File');
        }

        $securityContext = $this->get('security.authorization_checker');

        foreach ($file->getGroups() as $group) {
            if (!$securityContext->isGranted($group->getRole())) {
                throw $this->createNotFoundException('Unable to locate File');
            }
        }

        $response = new Response();
        $response->setLastModified(new \DateTime('@' . filemtime($file->getPath())));
        $response->setPublic();
        if (($hash = $file->getMd5()) !== '') {
            $response->setEtag($hash);
        }

        if ($response->isNotModified($request)) {
            return $response;
        }

        $response->setContent($file->getContent());
        $response->headers->add(array(
            'Content-Type' => $file->getMimeType(),
        ));

        return $response;
    }

    /**
     * Outputs a file for the user to download
     *
     * @Route("/{id}/download", name="download_file")
     * @Secure(roles="ROLE_USER")
     */
    public function downloadAction($id)
    {
        $em = $this->getDoctrine()->getManager();

        /** @var $file \Orkestra\Bundle\ApplicationBundle\Entity\File */
        $file = $em->find('Orkestra\Bundle\ApplicationBundle\Entity\File', $id);

        if (!$file) {
            throw $this->createNotFoundException('Unable to locate File');
        }

        $securityContext = $this->get('security.authorization_checker');

        foreach ($file->getGroups() as $group) {
            if (!$securityContext->isGranted($group->getRole())) {
                throw $this->createNotFoundException('Unable to locate File');
            }
        }

        return new Response($file->getContent(), 200, array(
            'Content-Type' => $file->getMimeType(),
            'Content-Disposition' => sprintf('attachment; filename="%s"', $file->getFilename())
        ));
    }
}


<?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\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller as BaseController;

/**
 * Base class for any controller
 */
abstract class Controller extends BaseController
{
    /**
     * @var \Orkestra\Bundle\ApplicationBundle\Helper\FormHelper
     */
    protected $_formHelper;

    /**
     * Get Form Type
     *
     * @param object      $entity
     * @param string|null $className If the object being passed is a subclass,
     *    specify the superclass that should be used to find the form type.
     * @param array $options
     *
     * @throws \RuntimeException
     * @return \Symfony\Component\Form\AbstractType
     */
    public function getFormFor($entity, $className = null, array $options = array())
    {
        if (empty($this->_formHelper) && ($this->_formHelper = $this->get('orkestra.application.helper.form')) == null) {
            throw new \RuntimeException('Orkestra FormHelper is not registered as a service');
        }

        $type = $this->container->get('orkestra.application.helper.form')->getType($entity, $className);

        return $this->createForm($type, $entity, $options);
    }

    /**
     * Gets the session container
     *
     * @return \Symfony\Component\HttpFoundation\Session\SessionInterface|\Symfony\Component\HttpFoundation\Session\Session
     */
    public function getSession()
    {
        return $this->get('session');
    }

    /**
     * Gets the repository for the given class
     *
     * @param string $className
     *
     * @return \Doctrine\Common\Persistence\ObjectRepository
     */
    public function getRepository($className)
    {
        return $this->getDoctrine()->getManagerForClass($className)->getRepository($className);
    }
}


<?php //-->
/**
 * This file is part of the Eden PHP Library.
 * (c) 2014-2016 Openovate Labs
 *
 * Copyright and license information can be found at LICENSE.txt
 * distributed with this package.
 */

namespace Eden\File;

/**
 * General available methods for common file
 * manipulations and information per file
 *
 * @vendor   Eden
 * @package  File
 * @author   Christian Blanquera <cblanquera@openovate.com>
 * @standard PSR-2
 */
class Index extends Base
{
    /**
     * @const string ERROR_PATH_IS_NOT_FILE Error template
     */
    const ERROR_PATH_IS_NOT_FILE = 'Path %s is not a file in the system.';

    /**
     * @var string|null $path memory cache of instances saved
     */
    protected $path = null;

    /**
     * Checks to see if this
     * path is a real file
     *
     * @return bool
     */
    public function isFile()
    {
        return file_exists($this->data);
    }

    /**
     * Returns the base file name with out the extension
     *
     * @return string
     */
    public function getBase()
    {
        $pathInfo = pathinfo($this->data);
        return $pathInfo['filename'];
    }

    /**
     * Returns the contents of a file given the path
     *
     * @return string
     */
    public function getContent()
    {
        $this->absolute();

        //if the pat is not a real file
        if (!is_file($this->data)) {
            //throw an exception
            Exception::i()
                ->setMessage(self::ERROR_PATH_IS_NOT_FILE)
                ->addVariable($this->data)
                ->trigger();
        }

        return file_get_contents($this->data);
    }

    /**
     * Returns the executes the specified file and returns the final value
     *
     * @return bool
     */
    public function getData()
    {
        $this->absolute();

        return include($this->data);
    }

    /**
     * Returns the base file name extension
     *
     * @return string|null
     */
    public function getExtension()
    {
        $pathInfo = pathinfo($this->data);

        if (!isset($pathInfo['extension'])) {
            return null;
        }

        return $pathInfo['extension'];
    }

    /**
     * Returns the file path
     *
     * @return string
     */
    public function getFolder()
    {
        return dirname($this->data);
    }

    /**
     * Returns the mime type of a file
     *
     * @return string
     */
    public function getMime()
    {
        $this->absolute();

        //mime_content_type seems to be deprecated in some versions of PHP
        //if it does exist then lets use it
        if (function_exists('mime_content_type')) {
            return mime_content_type($this->data);
        }

        //if not then use the replacement funciton fileinfo
        //see: http://www.php.net/manual/en/function.finfo-file.php
        if (function_exists('finfo_open')) {
            $resource = finfo_open(FILEINFO_MIME_TYPE);
            $mime = finfo_file($resource, $this->data);
            finfo_close($finfo);

            return $mime;
        }

        //ok we have to do this manually
        //get this file extension
        $extension = strtolower($this->getExtension());

        //get the list of mimetypes stored locally
        $types = self::$mimeTypes;
        //if this extension exissts in the types
        if (isset($types[$extension])) {
            //return the mimetype
            return $types[$extension];
        }

        //return text/plain by default
        return $types['class'];
    }

    /**
     * Returns the file name
     *
     * @return string
     */
    public function getName()
    {
        return basename($this->data);
    }

    /**
     * Returns the size of a file in bytes
     *
     * @return string
     */
    public function getSize()
    {
        $this->absolute();

        return filesize($this->data);
    }

    /**
     * Returns the last time file was modified in UNIX time
     *
     * @return int
     */
    public function getTime()
    {
        $this->absolute();

        return filemtime($this->data);
    }

    /**
     * Creates a file and puts specified content into that file
     *
     * @param *string $content The raw content to save
     *
     * @return Eden\File\Index
     */
    public function setContent($content)
    {
        //argument 1 must be string
        Argument::i()->test(1, 'string');

        try {
            $this->absolute();
        } catch (\Eden\Path\Exception $e) {
            $this->touch();
        }

        file_put_contents($this->data, $content);

        return $this;
    }

    /**
     * Creates a php file and puts specified variable into that file
     *
     * @param *mixed $variable Whatever data to save
     *
     * @return Eden\File\Index
     */
    public function setData($variable)
    {
        return $this->setContent("<?php //-->\nreturn ".var_export($variable, true).";");
    }

    /**
     * Removes a file
     *
     * @return Eden\File\Index
     */
    public function remove()
    {
        $this->absolute();

        //if it's a file
        if (is_file($this->data)) {
            //remove it
            unlink($this->data);

            return $this;
        }

        return $this;
    }

    /**
     * Touches a file (effectively creates the file if
     * it doesn't exist and updates the date if it does)
     *
     * @return Eden\File\Index
     */
    public function touch()
    {
        touch($this->data);

        return $this;
    }

    /**
     * @var array $mimeTypes list of mimetypes when php methods fail
     */
    protected static $mimeTypes = array(
        'ai' => 'application/postscript',
        'aif' => 'audio/x-aiff',
        'aifc' => 'audio/x-aiff',
        'aiff' => 'audio/x-aiff',
        'asc' => 'text/plain',
        'atom' => 'application/atom+xml',
        'au' => 'audio/basic',
        'avi' => 'video/x-msvideo',
        'bcpio' => 'application/x-bcpio',
        'bin' => 'application/octet-stream',
        'bmp' => 'image/bmp',
        'cdf' => 'application/x-netcdf',
        'cgm' => 'image/cgm',
        'class' => 'application/octet-stream',
        'cpio' => 'application/x-cpio',
        'cpt' => 'application/mac-compactpro',
        'csh' => 'application/x-csh',
        'css' => 'text/css',
        'dcr' => 'application/x-director',
        'dif' => 'video/x-dv',
        'dir' => 'application/x-director',
        'djv' => 'image/vnd.djvu',
        'djvu' => 'image/vnd.djvu',
        'dll' => 'application/octet-stream',
        'dmg' => 'application/octet-stream',
        'dms' => 'application/octet-stream',
        'doc' => 'application/msword',
        'dtd' => 'application/xml-dtd',
        'dv' => 'video/x-dv',
        'dvi' => 'application/x-dvi',
        'dxr' => 'application/x-director',
        'eps' => 'application/postscript',
        'etx' => 'text/x-setext',
        'exe' => 'application/octet-stream',
        'ez' => 'application/andrew-inset',
        'gif' => 'image/gif',
        'gram' => 'application/srgs',
        'grxml' => 'application/srgs+xml',
        'gtar' => 'application/x-gtar',
        'hdf' => 'application/x-hdf',
        'hqx' => 'application/mac-binhex40',
        'htm' => 'text/html',
        'html' => 'text/html',
        'ice' => 'x-conference/x-cooltalk',
        'ico' => 'image/x-icon',
        'ics' => 'text/calendar',
        'ief' => 'image/ief',
        'ifb' => 'text/calendar',
        'iges' => 'model/iges',
        'igs' => 'model/iges',
        'jnlp' => 'application/x-java-jnlp-file',
        'jp2' => 'image/jp2',
        'jpe' => 'image/jpeg',
        'jpeg' => 'image/jpeg',
        'jpg' => 'image/jpeg',
        'js' => 'application/x-javascript',
        'kar' => 'audio/midi',
        'latex' => 'application/x-latex',
        'lha' => 'application/octet-stream',
        'lzh' => 'application/octet-stream',
        'm3u' => 'audio/x-mpegurl',
        'm4a' => 'audio/mp4a-latm',
        'm4b' => 'audio/mp4a-latm',
        'm4p' => 'audio/mp4a-latm',
        'm4u' => 'video/vnd.mpegurl',
        'm4v' => 'video/x-m4v',
        'mac' => 'image/x-macpaint',
        'man' => 'application/x-troff-man',
        'mathml' => 'application/mathml+xml',
        'me' => 'application/x-troff-me',
        'mesh' => 'model/mesh',
        'mid' => 'audio/midi',
        'midi' => 'audio/midi',
        'mif' => 'application/vnd.mif',
        'mov' => 'video/quicktime',
        'movie' => 'video/x-sgi-movie',
        'mp2' => 'audio/mpeg',
        'mp3' => 'audio/mpeg',
        'mp4' => 'video/mp4',
        'mpe' => 'video/mpeg',
        'mpeg' => 'video/mpeg',
        'mpg' => 'video/mpeg',
        'mpga' => 'audio/mpeg',
        'ms' => 'application/x-troff-ms',
        'msh' => 'model/mesh',
        'mxu' => 'video/vnd.mpegurl',
        'nc' => 'application/x-netcdf',
        'oda' => 'application/oda',
        'ogg' => 'application/ogg',
        'pbm' => 'image/x-portable-bitmap',
        'pct' => 'image/pict',
        'pdb' => 'chemical/x-pdb',
        'pdf' => 'application/pdf',
        'pgm' => 'image/x-portable-graymap',
        'pgn' => 'application/x-chess-pgn',
        'pic' => 'image/pict',
        'pict' => 'image/pict',
        'png' => 'image/png',
        'pnm' => 'image/x-portable-anymap',
        'pnt' => 'image/x-macpaint',
        'pntg' => 'image/x-macpaint',
        'ppm' => 'image/x-portable-pixmap',
        'ppt' => 'application/vnd.ms-powerpoint',
        'ps' => 'application/postscript',
        'qt' => 'video/quicktime',
        'qti' => 'image/x-quicktime',
        'qtif' => 'image/x-quicktime',
        'ra' => 'audio/x-pn-realaudio',
        'ram' => 'audio/x-pn-realaudio',
        'ras' => 'image/x-cmu-raster',
        'rdf' => 'application/rdf+xml',
        'rgb' => 'image/x-rgb',
        'rm' => 'application/vnd.rn-realmedia',
        'roff' => 'application/x-troff',
        'rtf' => 'text/rtf',
        'rtx' => 'text/richtext',
        'sgm' => 'text/sgml',
        'sgml' => 'text/sgml',
        'sh' => 'application/x-sh',
        'shar' => 'application/x-shar',
        'silo' => 'model/mesh',
        'sit' => 'application/x-stuffit',
        'skd' => 'application/x-koan',
        'skm' => 'application/x-koan',
        'skp' => 'application/x-koan',
        'skt' => 'application/x-koan',
        'smi' => 'application/smil',
        'smil' => 'application/smil',
        'snd' => 'audio/basic',
        'so' => 'application/octet-stream',
        'spl' => 'application/x-futuresplash',
        'src' => 'application/x-wais-source',
        'sv4cpio' => 'application/x-sv4cpio',
        'sv4crc' => 'application/x-sv4crc',
        'svg' => 'image/svg+xml',
        'swf' => 'application/x-shockwave-flash',
        't' => 'application/x-troff',
        'tar' => 'application/x-tar',
        'tcl' => 'application/x-tcl',
        'tex' => 'application/x-tex',
        'texi' => 'application/x-texinfo',
        'texinfo' => 'application/x-texinfo',
        'tif' => 'image/tiff',
        'tiff' => 'image/tiff',
        'tr' => 'application/x-troff',
        'tsv' => 'text/tab-separated-values',
        'txt' => 'text/plain',
        'ustar' => 'application/x-ustar',
        'vcd' => 'application/x-cdlink',
        'vrml' => 'model/vrml',
        'vxml' => 'application/voicexml+xml',
        'wav' => 'audio/x-wav',
        'wbmp' => 'image/vnd.wap.wbmp',
        'wbmxl' => 'application/vnd.wap.wbxml',
        'wml' => 'text/vnd.wap.wml',
        'wmlc' => 'application/vnd.wap.wmlc',
        'wmls' => 'text/vnd.wap.wmlscript',
        'wmlsc' => 'application/vnd.wap.wmlscriptc',
        'wrl' => 'model/vrml',
        'xbm' => 'image/x-xbitmap',
        'xht' => 'application/xhtml+xml',
        'xhtml' => 'application/xhtml+xml',
        'xls' => 'application/vnd.ms-excel',
        'xml' => 'application/xml',
        'xpm' => 'image/x-xpixmap',
        'xsl' => 'application/xml',
        'xslt' => 'application/xslt+xml',
        'xul' => 'application/vnd.mozilla.xul+xml',
        'xwd' => 'image/x-xwindowdump',
        'xyz' => 'chemical/x-xyz',
        'zip' => 'application/zip',
        'woff' => 'application/x-font-woff',
        'eot' => 'application/vnd.ms-fontobject',
        'ttf' => 'font/truetype',
        'otf' => 'font/opentype');
}


<?php

namespace Slion\Http;

use Slim\App;
use Slim\Http\Request as RawRequest;
use Slim\Http\Response as RawResponse;
use Slion\Abort;
use Slion\Debugger;

/**
 * Description of Dispatcher
 *
 * @author andares
 */
class Dispatcher {
    /**
     *
     * @var App
     */
    protected $app;

    /**
     *
     * @param App $app
     */
    public function __construct(App $app) {
        $this->app = $app;
    }

    /**
     *
     * @param string $module
     * @param string $pattern
     * @param array $methods
     * @return self
     */
    public function json(string $module, string $pattern,
        array $methods = ['GET', 'POST', 'PUT', 'PATCH',
            'DELETE', 'OPTIONS']): self {

        $dispatcher = $this;
        $this->app->map($methods, "/$module/{controller}[/{action}[/{more:.*}]]",
            function (RawRequest $request, RawResponse $response, array $args)
            use ($pattern, $dispatcher) {
                $response = $dispatcher($pattern, $args['controller'],
                    $args['action'] ?? 'index',
                    $request, $response);
                /* @var $response Response */

                $this->get('hook')->take(\Slion\HOOK_REGRESS_RESPONSE, $response);
                return $response->regress()->withJson($response);
            })->setName($module);
        return $this;
    }

    /**
     *
     * @todo 有待加入错误页面处理
     *
     * @param string $module
     * @param string $pattern
     * @param array $methods
     * @return self
     */
    public function html(string $module, string $pattern,
        array $methods = ['GET', 'POST', 'PUT', 'PATCH',
            'DELETE', 'OPTIONS']): self {

        $dispatcher = $this;
        $this->app->map($methods, "/$module/{controller}[/{action}[/{more:.*}]]",
            function (RawRequest $request, RawResponse $response, array $args)
            use ($pattern, $dispatcher) {
                $response = $dispatcher($pattern, $args['controller'],
                    $args['action'] ?? 'index',
                    $request, $response);
                /* @var $response Response */

                $this->get('hook')->take(\Slion\HOOK_REGRESS_RESPONSE, $response);
                return $this->renderer->render($response->regress(),
                    $response->getTemplate(), $response->toArray());
            })->setName($module);
        return $this;
    }

    /**
     *
     * @param string $pattern
     * @param string $controller_name
     * @param string $action
     * @param RawRequest $raw_request
     * @param RawResponse $raw_response
     * @return \Slion\Http\Response
     */
    public function __invoke(string $pattern, string $controller_name, string $action,
        RawRequest $raw_request, RawResponse $raw_response): Response {

        try {
            $controller = $this->makeController($pattern, $controller_name,
                $raw_request, $raw_response);
            $response   = $controller->$action();

        } catch (Abort $abort) {
            $response = $this->raiseError($raw_response, $raw_request, $abort());

            // 触发hook
            $this->app->getContainer()->get('hook')
                ->take(\Slion\HOOK_ABORT_CATCHED, $abort, $response);

        } catch (\BadMethodCallException $e) {
            // 处理未定义的接口
            $response = $this->raiseError($raw_response, $raw_request,
                new \BadMethodCallException(
                    "action [$action@$controller_name] is not exists", 0, $e));
            $response->setHttpCode(404);

        } catch (\Throwable $e) {
            $response = $this->raiseError($raw_response, $raw_request, $e);
        }

        // 错误记录与触发debugger handle
        if ($response instanceof ErrorResponse) {
            lg($response->confirm()->toLog());
            $this->app->getContainer()->get('hook')
                ->take(\Slion\HOOK_TAKE_ERRORRESPONSE, $response);
        }
        return $response;
    }

    /**
     *
     * @param string $pattern
     * @param string $name
     * @return \Slion\Http\Controller
     * @throws \BadMethodCallException
     */
    protected function makeController(string $pattern, string $name,
        RawRequest $raw_request, RawResponse $raw_response): Controller {
        $class = $this->getControllerClass($pattern, $name);
        if (!class_exists($class)) {
            throw new \BadMethodCallException(
                "controller [$name] is not exists($class)");
        }
        $controller = new $class($this->app->getContainer(),
            $raw_request, $raw_response);
        return $controller;
    }

    /**
     *
     * @param string $pattern
     * @param string $name
     * @return string
     */
    protected function getControllerClass(string $pattern, string $name): string {
        return str_replace('%c%', ucfirst($name), $pattern);
    }

    /**
     * @todo 未对原response（如果有的话）中的channel项做继承
     *
     * @param RawResponse $raw
     * @param \Throwable $e
     * @return \Slion\Http\ErrorResponse
     */
    protected function raiseError(RawResponse $raw, RawRequest $request, \Throwable $e): ErrorResponse {
        $response = new ErrorResponse($raw, $request, $e);
        return $response;
    }

}


<?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\Command\Worker;

use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

/**
 * Lists all registered workers
 */
class ListCommand extends ContainerAwareCommand
{
    /**
     * Configures the current command
     */
    protected function configure()
    {
        $this->setName('orkestra:worker:list')
            ->setDescription('Lists all configured workers');
    }

    /**
     * Executes the current command
     *
     * @param \Symfony\Component\Console\Input\InputInterface $input
     * @param \Symfony\Component\Console\Output\OutputInterface $output
     */
    protected function execute(InputInterface $input, OutputInterface $output)
    {
        /** @var $factory \Orkestra\Bundle\ApplicationBundle\Worker\WorkerFactoryInterface */
        $factory = $this->getContainer()->get('orkestra.worker_factory');
        $workers = $factory->getWorkers();

        $output->writeln('');

        if (count($workers) > 0) {
            $output->writeln(sprintf('<info>%-40s</info><comment>%s</comment>', 'Name', 'Internal Name'));

            foreach ($workers as $worker) {
                $output->writeln(sprintf('%-40s%s', $worker->getName(), $worker->getInternalName()));
            }
        } else {
            $output->writeln('<comment>No workers configured.</comment>');
        }
        $output->writeln('');
    }
}


<?php

/**
 * This file is part of bit3/string-builder.
 *
 * (c) Tristan Lins <tristan@lins.io>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * This project is provided in good faith and hope to be usable by anyone.
 *
 * @package    bit3/string-builder
 * @author     Tristan Lins <tristan@lins.io>
 * @copyright  2013,2014 Tristan Lins
 * @link       https://github.com/bit3/string-builder
 * @license    https://github.com/bit3/string-builder/blob/master/LICENSE MIT
 * @filesource
 */

namespace Bit3\StringBuilder;

/**
 * StringBuilder for PHP provide string manipulation logic in an object.
 */
class StringBuilder
{
    /**
     * The current sequence.
     *
     * @var string
     */
    protected $string;

    /**
     * The current sequence encoding.
     *
     * @var string
     */
    protected $encoding;

    /**
     * Create a new string builder object.
     *
     * @param string|null $string   The initial sequence.
     * @param string|null $encoding The encoding of the sequence.
     */
    public function __construct($string = null, $encoding = 'UTF-8')
    {
        $this->string   = static::convertString($string, $encoding);
        $this->encoding = (string) $encoding;
    }

    /**
     * Set the encoding of this sequence.
     *
     * Warning: This will not convert an existing sequence!
     *
     * @param string $encoding The new encoding.
     *
     * @return StringBuilder
     */
    public function setEncoding($encoding)
    {
        $this->encoding = (string) $encoding;

        return $this;
    }

    /**
     * Convert this sequence into another encoding.
     *
     * @param string $encoding The new encoding.
     *
     * @return StringBuilder
     */
    public function changeEncoding($encoding)
    {
        $encoding       = (string) $encoding;
        $this->string   = iconv($this->encoding, $encoding, $this->string);
        $this->encoding = $encoding;

        return $this;
    }

    /**
     * Get the encoding of this sequence.
     *
     * @return string
     */
    public function getEncoding()
    {
        return $this->encoding;
    }

    /**
     * Check if this sequence starts with a given string.
     *
     * @param string $string The sequence to search for.
     *
     * @return bool
     */
    public function startsWith($string)
    {
        $string = static::convertString($string, $this->encoding);

        return $string === $this->substring(0, (mb_strlen($string, $this->encoding) - 1))->__toString();
    }

    /**
     * Check if this sequence ends with a given string.
     *
     * @param string $string The sequence to search for.
     *
     * @return bool
     */
    public function endsWith($string)
    {
        $string = static::convertString($string, $this->encoding);

        return $string === $this->substring($this->length() - mb_strlen($string, $this->encoding))->__toString();
    }

    /**
     * Return the character at the given position in the sequence.
     *
     * @param int $index The character index.
     *
     * @return string
     * @throws \OutOfBoundsException If the index is out of bounds.
     */
    public function charAt($index)
    {
        $index = (int) $index;

        if ($index < 0 || $index >= $this->length()) {
            throw new \OutOfBoundsException();
        }

        return mb_substr($this->string, $index, 1, $this->encoding);
    }

    /**
     * Return the first occurrence of a string in the sequence.
     *
     * @param string   $string The sequence to search for.
     * @param int|null $offset The offset index to search from.
     *
     * @return int
     * @throws \OutOfBoundsException If the index is out of bounds.
     */
    public function indexOf($string, $offset = null)
    {
        $string = static::convertString($string, $this->encoding);
        $offset = $offset !== null ? (int) $offset : null;

        if ($offset !== null && ($offset < 0 || $offset >= $this->length())) {
            throw new \OutOfBoundsException();
        }

        return mb_strpos($this->string, $string, $offset, $this->encoding);
    }

    /**
     * Return the last occurrence of a string in the sequence.
     *
     * @param string   $string The sequence to search for.
     * @param int|null $offset The offset index to search from.
     *
     * @return int
     * @throws \OutOfBoundsException If the index is out of bounds.
     */
    public function lastIndexOf($string, $offset = null)
    {
        $string = static::convertString($string, $this->encoding);
        $offset = $offset !== null ? (int) $offset : null;

        if ($offset !== null && ($offset < 0 || $offset >= $this->length())) {
            throw new \OutOfBoundsException();
        }

        return mb_strrpos($this->string, $string, $offset, $this->encoding);
    }

    /**
     * Check if this sequence contains the given string.
     *
     * @param string $string The sequence to search for.
     *
     * @return bool
     */
    public function contains($string)
    {
        return $this->indexOf($string) !== false;
    }

    /**
     * Return a substring of this sequence.
     *
     * @param int $start The start index.
     * @param int $end   The end index.
     *
     * @return StringBuilder
     * @throws \OutOfBoundsException If the start or end index is out of bounds.
     */
    public function substring($start, $end = null)
    {
        $start = (int) $start;
        $end   = $end !== null ? (int) $end : null;

        if ($start < 0 || $start >= $this->length() || $end !== null && ($end < 0 || $end >= $this->length())) {
            throw new \OutOfBoundsException();
        }

        $string        =
            mb_substr($this->string, $start, $end !== null ? ($end + 1) : $this->length(), $this->encoding);
        $stringBuilder = new StringBuilder($string);
        $stringBuilder->setEncoding($this->encoding);

        return $stringBuilder;
    }

    /**
     * Return the length of this sequence.
     *
     * @return int
     */
    public function length()
    {
        return mb_strlen($this->string, $this->encoding);
    }

    /**
     * Return the byte count of this sequence.
     *
     * @return int
     */
    public function byteCount()
    {
        return strlen($this->string);
    }

    /**
     * Append a string to the sequence.
     *
     * @param string $string The sequence to append.
     *
     * @return StringBuilder
     */
    public function append($string)
    {
        $string = static::convertString($string, $this->encoding);

        $this->string .= $string;

        return $this;
    }

    /**
     * Insert a string into the sequence.
     *
     * @param int    $offset The offset index.
     * @param string $string The sequence to insert.
     *
     * @return StringBuilder
     *
     * @throws \OutOfBoundsException If the index is out of bounds.
     */
    public function insert($offset, $string)
    {
        $offset = (int) $offset;
        $string = static::convertString($string, $this->encoding);

        if ($offset < 0 || $offset >= $this->length()) {
            throw new \OutOfBoundsException();
        }

        $this->string = mb_substr($this->string, 0, $offset, $this->encoding) .
            $string .
            mb_substr($this->string, $offset, $this->length(), $this->encoding);
        return $this;
    }

    /**
     * Replace a substring by another string in this sequence.
     *
     * @param int    $start  The start index.
     * @param int    $end    The end index.
     * @param string $string The sequence to place.
     *
     * @return StringBuilder
     *
     * @throws \OutOfBoundsException If the start or end index is out of bounds.
     */
    public function replace($start, $end, $string)
    {
        $start  = (int) $start;
        $end    = (int) $end;
        $string = static::convertString($string, $this->encoding);

        if ($start < 0 || $start >= $this->length() || $end < 0 || $end >= $this->length()) {
            throw new \OutOfBoundsException();
        }

        $this->string = mb_substr($this->string, 0, $start, $this->encoding) .
            $string .
            mb_substr($this->string, ($end + 1), $this->length(), $this->encoding);
        return $this;
    }

    /**
     * Remove the characters in a substring of this sequence.
     *
     * @param int $start Start of substring.
     * @param int $end   End of substring.
     *
     * @return StringBuilder
     *
     * @throws \OutOfBoundsException If the index is out of bounds.
     */
    public function delete($start, $end)
    {
        $start = (int) $start;
        $end   = (int) $end;

        if ($start < 0 || $start >= $this->length() || $end < 0 || $end >= $this->length()) {
            throw new \OutOfBoundsException();
        }

        $this->string = mb_substr($this->string, 0, $start, $this->encoding) .
            mb_substr($this->string, ($end + 1), $this->length(), $this->encoding);
        return $this;
    }

    /**
     * Delete the character at the index, the sequence will be shorten by one.
     *
     * @param int $index The character position, starting at 0.
     *
     * @return StringBuilder
     *
     * @throws \OutOfBoundsException If the index is out of bounds.
     */
    public function deleteCharAt($index)
    {
        $index = (int) $index;
        if ($index < 0 || $index >= $this->length()) {
            throw new \OutOfBoundsException();
        }

        $this->string = mb_substr($this->string, 0, $index, $this->encoding) .
            mb_substr($this->string, ($index + 1), $this->length(), $this->encoding);
        return $this;
    }

    /**
     * Reverse the sequence.
     *
     * @return StringBuilder
     */
    public function reverse()
    {
        $length   = $this->length();
        $reversed = '';
        while ($length-- > 0) {
            $reversed .= mb_substr($this->string, $length, 1, $this->encoding);
        }

        $this->string = $reversed;
        return $this;
    }

    /**
     * Set the length of this sequence.
     *
     * If the sequence is shorter, than it will be pad with spaces.
     *
     * @param int    $newLength The new length.
     * @param string $padding   The padding sequence.
     *
     * @return StringBuilder
     */
    public function setLength($newLength, $padding = ' ')
    {
        $newLength     = (int) $newLength;
        $currentLength = $this->length();

        if ($newLength != $currentLength) {
            while ($newLength > $this->length()) {
                $this->string .= $padding;
            }
            if ($newLength < $this->length()) {
                $this->string = mb_substr($this->string, 0, $newLength, $this->encoding);
            }
        }

        return $this;
    }

    /**
     * Trim characters from the left and right side of this sequence.
     *
     * @param string|null $characters The characters to trim. Leave empty for whitespaces.
     *
     * @return StringBuilder
     */
    public function trim($characters = null)
    {
        $this->string = trim($this->string, $characters);
        return $this;
    }

    /**
     * Trim characters from the left side of this sequence.
     *
     * @param string|null $characters The characters to trim. Leave empty for whitespaces.
     *
     * @return StringBuilder
     */
    public function trimLeft($characters = null)
    {
        $this->string = ltrim($this->string, $characters);
        return $this;
    }

    /**
     * Trim characters from the right side of this sequence.
     *
     * @param string|null $characters The characters to trim. Leave empty for whitespaces.
     *
     * @return StringBuilder
     */
    public function trimRight($characters = null)
    {
        $this->string = rtrim($this->string, $characters);
        return $this;
    }

    /**
     * Return the string representation.
     *
     * @return string
     */
    public function __toString()
    {
        return $this->string;
    }

    /**
     * Internal helper function to convert string encodings.
     *
     * @param string|StringBuilder $string         The input string.
     * @param string               $outputEncoding The output encoding.
     *
     * @return string
     */
    private static function convertString($string, $outputEncoding)
    {
        if ($string instanceof StringBuilder) {
            $inputEncoding = $string->getEncoding();
        } else {
            $inputEncoding = mb_detect_encoding((string) $string);
        }
        $string = (string) $string;
        if ($inputEncoding != $outputEncoding) {
            $string = iconv($inputEncoding, $outputEncoding, $string);
        }
        return $string;
    }
}


<?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 Monolog\Logger;
use Orkestra\Bundle\ApplicationBundle\Entity\EmailTemplate;
use Symfony\Component\DependencyInjection\ContainerInterface;

use Symfony\Component\Templating\EngineInterface;

/**
 * Provides additional functionality to Swift_Mailer
 */
class EmailHelper implements EmailHelperInterface
{
    /**
     * @var \Symfony\Component\Templating\EngineInterface
     */
    protected $templating;

    /**
     * @var \Twig_Environment
     */
    protected $environment;

    /**
     * @var \Swift_Mailer
     */
    protected $mailer;

    /**
     * @var string
     */
    protected $defaultSender;

    /**
     * Constructor
     *
     * @param \Symfony\Component\Templating\EngineInterface $engine
     * @param \Twig_Environment                             $environment
     * @param \Swift_Mailer                                 $mailer
     * @param string                                        $defaultSender
     */
    public function __construct(EngineInterface $engine, \Twig_Environment $environment, \Swift_Mailer $mailer, $defaultSender)
    {
        $this->templating = $engine;
        $this->environment = $environment;
        $this->mailer = $mailer;
        $this->defaultSender = $defaultSender;
    }

    /**
     * Create Message from an EmailTemplate entity
     *
     * @param \Orkestra\Bundle\ApplicationBundle\Entity\EmailTemplate $template
     * @param array $parameters An array of parameters to pass to the the templating engine
     * @return \Swift_Message
     */
    public function createMessageFromTemplateEntity(EmailTemplate $template, array $parameters = array())
    {
        $subject = $this->renderStringTemplate($template->getSubject(), $parameters);
        $recipient = $this->renderStringTemplate($template->getRecipient(), $parameters);
        $body = $this->renderStringTemplate($template->getBody(), $parameters);
        $sender = $template->getSender() ?: $this->defaultSender;

        $message = new \Swift_Message($subject, $body, $template->getMimeType());
        $message->setFrom($sender)
                ->setSender($sender)
                ->setTo($recipient);

        if ($template->hasCc()) {
            $message->setCc($template->getCc());
        }

        if ($template->hasAltBody()) {
            $altBody = $this->renderStringTemplate($template->getAltBody(), $parameters);
            $message->addPart($altBody, $template->getAltMimeType());
        }

        return $message;
    }

    /**
     * Create Message from a file-based template
     *
     * @param string      $template
     * @param string      $params
     * @param string      $subject
     * @param string      $recipient
     * @param string|null $sender
     *
     * @return \Swift_Message
     */
    public function createMessageFromTemplateFile($template, $params, $subject, $recipient, $sender = null)
    {
        $body = $this->templating->render($template, $params);

        if (!$sender) {
            $sender = $this->defaultSender;
        }

        $message = new \Swift_Message();
        $message->setFrom($sender)
            ->setReplyTo($sender)
            ->setTo($recipient)
            ->setSubject($subject)
            ->setBody($body, 'text/html');
        return $message;
    }

    /**
     * This method creates and sends an email message using the given template
     *
     * One of two signatures:
     *
     * function(EmailTemplate $template, array $parameters = array())
     * function($template, $params, $subject, $recipient, $sender = null)
     *
     * @return bool
     * @throws \RuntimeException
     */
    public function createAndSendMessageFromTemplate()
    {
        $args = func_get_args();
        if (empty($args[0])) {
            throw new \RuntimeException('First parameter must be a template filename or EmailTemplate entity');

        } elseif ($args[0] instanceof EmailTemplate) {
            $method = 'createMessageFromTemplateEntity';

        } else {
            $method = 'createMessageFromTemplateFile';
        }

        $message = call_user_func_array(array($this, $method), $args);
        $this->mailer->send($message);

        return true;
    }

    /**
     * Renders a string template
     *
     * @param       $template
     * @param array $parameters
     *
     * @return string
     */
    protected function renderStringTemplate($template, $parameters = array())
    {
        $template = $this->environment->createTemplate($template);

        return $template->render($parameters);
    }
}


<?php
/**
 * This file is part of Vegas package
 *
 * @author Slawomir Zytko <slawomir.zytko@gmail.com>
 * @copyright Amsterdam Standard Sp. Z o.o.
 * @homepage https://bitbucket.org/amsdard/vegas-phalcon
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Vegas\Media\Db\Mapping;

use Vegas\Db\MappingInterface;
use Vegas\Media\Db\FileInterface;
use Vegas\Media\File\Decorator;

/**
 * Class File
 *
 * Usage
 *
 * Add somewhere in \Bootstrap class
 *
 * $mappingManager = new MappingManager();
 * $mappingManager->add(new \Vegas\Media\Db\Mapping\File());
 *
 *
 * Add mappings definition to model
 *
 * class Foo extends CollectionAbstract
 * {
 *  ....
 *  protected $mappings = array('image' => 'file');
 *  ....
 * }
 *
 *
 * Read mapped values
 *
 * $foo = Foo::findFirst();
 * echo $foo->readMapped('image')->offsetGet(0)->getPath();
 * echo $foo->readMapped('image')[0]->getUrl();
 *
 *
 * @package Vegas\Media\Db\Mapping
 */
class File implements MappingInterface
{
    /**
     * Class represents model
     *
     * @var FileInterface
     */
    private $fileModel;

    /**
     * Constructor
     * Sets model
     *
     * @param FileInterface $fileModel
     */
    public function __construct(FileInterface $fileModel)
    {
        $this->fileModel = $fileModel;
    }

    /**
     * {@inheritdoc}
     */
    public function getName()
    {
        return 'file';
    }

    /**
     * {@inheritdoc}
     */
    public function resolve(& $value)
    {
        $extraData = array();
        $files = array();
        if (is_array($value)) {
            if (!empty($value['file_id'])) {
                $extraDataTmp = array();
                foreach ($value as $extraDataKey => $extraDataValue) {
                    if ($extraDataKey !== 'file_id') {
                        $extraDataTmp[$extraDataKey] = $extraDataValue;
                    }
                }

                $extraData = $extraDataTmp;
                $files[] = call_user_func(array($this->fileModel, 'findById'), $value['file_id']);
            } else {
                foreach ($value as $index => $file) {
                    if (!empty($file['file_id'])) {
                        $modelFile = call_user_func(array($this->fileModel, 'findById'), $file['file_id']);

                        $extraDataTmp = array();
                        foreach ($file as $extraDataKey => $extraDataValue) {
                            if ($extraDataKey !== 'file_id') {
                                $extraDataTmp[$extraDataKey] = $extraDataValue;
                            }
                        }

                        $extraData[$index] = $extraDataTmp;
                        $files[] = $modelFile;
                    }
                }
            }
        }

        $decoratedFiles = new \ArrayObject();
        foreach ($files as $index => $file) {
            if (!$file instanceof $this->fileModel) {
                continue;
            }

            $decoratedFiles->append(new Decorator($file, $extraData[$index]));
        }
        $value = $decoratedFiles;

        return $value;
    }
}


<?php
namespace  keenly\session;
/**
 * 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
 */
use keenly\common;
use keenly\config;
use database;

class sessionHandler  extends \SessionHandler {

    use common;

    private $key;

    public $name;

    public function __construct()
    {
        $session = config::reload('session')->Get();
        if($session['save_state']){
            ini_set("session.save_handler", $session['save_handler']);
            ini_set("session.save_path", $session['save_path']);
        }

        $this->key = isset($session['key'])?$session['key']:'studious_key';
        $this->name = $session['session_n'];
        $this->setSession($session);
    }

    /* public function read($id)
    {
        return $data = parent::read($id);
        if (!$data) {
            return "";
        } else {
            return $this->decrypt($data, $this->key);
        }
    }

    public function write($id, $data)
    {
        //$data = $this->encrypt($data, $this->key);
        return parent::write($id, $data);
    } */

    private function setSession($C){
        session_set_cookie_params(
            $C['session_indate'],
            $C['session_path'],
            empty($C['session_domain'])?$_SERVER['HTTP_HOST']:$C['session_domain'],
            $C['http_session_secure'],
            $C['session_httponly']
        );
    }

}


<?php
namespace Pondol\Curl;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;

use Response;
use Pondol\Curl\CurlResponse;

/*
GET, POST, HEAD, PUT, DELETE Enable

$curl = new \Pondol\Curl('GET', 'http://www.shop-wiz.com/');
$curl = new \Pondol\Curl('POST', 'http://www.shop-wiz.com/', $params);

## options

$params['headers'][] = 'Accept: image/gif, image/x-bitmap, image/jpeg, image/pjpeg, application/json';
$params['headers'][] = 'Connection: Keep-Alive';
$params['headers'][] = 'Content-type: application/x-www-form-urlencoded;charset=UTF-8';

$params['proxy'] = 'tcp://localhost:1111',

$params['body'] = string or array

$params['encoding'] = 'gzip'// "identity", "deflate", and "gzip

// 'json' => ['foo' => 'bar'], 'timeout' => 3.14]);

$params['agent'] = 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.0.3705; .NET CLR 1.1.4322; Media Center PC 4.0)';

$params['cookies'] = [filepath=''] , if [cookies=>[]] path willbe /tmp/filename

*/

class CurlService
{
    private $ch;
    private $response;

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

    public function request($method, $url, $options=array()){

        $url = $this->url_change($url);

        $this->ch = curl_init();

        curl_setopt($this->ch, CURLOPT_AUTOREFERER, true);//TRUE to automatically set the Referer: field in requests where it follows a Location: redirect.
        curl_setopt($this->ch, CURLOPT_HEADER, true);//TRUE to include the header in the output.
        curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, true);//TRUE to return the raw output when CURLOPT_RETURNTRANSFER is used.
        curl_setopt($this->ch, CURLOPT_FOLLOWLOCATION, true);

        //curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, true);
        //curl_setopt($this->ch, CURLOPT_VERBOSE, true);

        //echo "url:".$url.PHP_EOL;

        isset($options['headers']) ?  $this->set_header($options['headers']):null;
        isset($options['agent']) ?  $this->set_agent($options['agent']):null;
        isset($options['cookies']) ?  $this->set_cookies($options['cookies']):null;
        isset($options['encoding']) ?  $this->set_encoding($options['encoding']):null;
        isset($options['timeout']) ?  $this->set_timeout($options['timeout']):null;
        isset($options['proxy']) ?  $this->set_proxy($options['proxy']):null;

      //

        switch(strtoupper($method)){
            case "POST":

                curl_setopt($this->ch, CURLOPT_URL, $url);
                curl_setopt($this->ch, CURLOPT_POST, true);
                isset($options['body']) ?  $this->set_body($options['body']):null;
                break;
            case "GET":
                curl_setopt($this->ch, CURLOPT_URL, $this->build_http_get_url($url, $options));
                break;
            case "HEAD":
                curl_setopt($this->ch, CURLOPT_URL, $url);
                curl_setopt( $this->ch, CURLOPT_NOBODY, true );
                curl_setopt($this->ch, CURLOPT_CUSTOMREQUEST, $method);//PUT, DELETE, HEAD
                break;
            default:
                curl_setopt($this->ch, CURLOPT_URL, $url);
                curl_setopt($this->ch, CURLOPT_CUSTOMREQUEST, $method);//PUT, DELETE, HEAD
                break;
        }

        $this->response->set_response(curl_exec($this->ch));

        if (!curl_errno($this->ch)) {
          $this->response->set_info(curl_getinfo($this->ch));
        }else{
            $this->response->err_code = curl_errno($this->ch);
        }

        curl_close($this->ch);
    }

    /**
     * request as body data is json
     * if you want to request Json, set Content-Type and Length;
     */
    public function requestJson($method, $url, $options=array()){
        $options['headers'][] = 'Content-Type: application/json';
        $options['headers'][] = 'Content-Length: ' . strlen($options['body']);
        $this->request($method, $url, $options);
    }

    private function build_query($body){
        return is_array($body) ? http_build_query($body):null;
    }

    private function url_change($url){
        $search = array(" ");
        $replace   = array("%20");

        return str_replace($search, $replace, $url);
    }

    private function build_http_get_url($url, $options=[]){
        if(isset($options['body'])){
            $query = $this->build_query($options['body']);
            return $url.'?'.$query;
        }else
            return $url;
    }

    private function set_header($headers){
        curl_setopt($this->ch, CURLOPT_HTTPHEADER, $headers);
    }

    private function set_body($body){
        if(is_array($body))
            curl_setopt($this->ch, CURLOPT_POSTFIELDS, http_build_query($body));
        else
            curl_setopt($this->ch, CURLOPT_POSTFIELDS, $body);
    }

    private function set_agent($agent){
        //echo "set_agent:".$agent.PHP_EOL;
        curl_setopt($this->ch, CURLOPT_USERAGENT, $agent);
    }

     /**
      * @param Array cookies = [filepath='']
      */
     private function set_cookies($cookies=null){
        $filepath = isset($cookies['filepath']) ? $cookies['filepath']:$this->get_cookie_path();

        curl_setopt($this->ch, CURLOPT_COOKIEJAR, $filepath);//(write) makes curl to store the cookies in a file at the end of the curl session
        curl_setopt($this->ch, CURLOPT_COOKIEFILE, $filepath);//(read) makes curl to use the given file as source for the cookies to send to the server.

    }

    private function get_cookie_path(){
      // return tempnam( "/tmp", 'cookie_');
       return '/tmp/cookie_pondol_curl';
    }
     /**
      * The contents of the "Accept-Encoding: " header. This enables decoding of the response.
      * Supported encodings are "identity", "deflate", br, and "gzip". If an empty string, "", is set, a header containing all supported encoding types is sent.
      */
    private function set_encoding($encoding){
        curl_setopt($this->ch,CURLOPT_ENCODING , $encoding);
    }

    /**
     * The maximum number of seconds to allow cURL functions to execute.
     */
    private function set_timeout($timeout){
        curl_setopt($this->ch, CURLOPT_TIMEOUT, $timeout);
    }

    /**
     * The HTTP proxy to tunnel requests through.
     */
    private function set_proxy($proxy){
        curl_setopt($this->ch, CURLOPT_PROXY, $proxy);
    }

    // return
    public function get_response(){
        return $this->response;
    }

    public function info(){
        return $this->response->info();
    }

     public function http_code(){
        return $this->response->http_code();
    }

    public function header_size(){
        return $this->response->header_size();
    }

    public function header(){
        return $this->response->header();
    }

    public function body(){
        return $this->response->body();
    }

    public function err_message(){
        return $this->response->err_message();
    }

}


<?php
namespace dbtext\storage;

use n2n\l10n\N2nLocale;
use n2n\reflection\ObjectAdapter;

class GroupData extends ObjectAdapter {
	const TEXTS_KEY = 'texts';
	const PLACEHOLDER_JSON_KEY = 'placeholderJsons';

	/**
	 * @var string $namespace
	 */
	private $namespace;
	/**
	 * @var string[][] $texts
	 */
	private $data;
	/**
	 * @var GroupDataListener[]
	 */
	private $listeners = array();

	/**
	 * @param string $namespace
	 * @param string[][] $data
	 */
	public function __construct($namespace, array $data = array()) {
		$this->namespace = $namespace;
		$this->data = $data;

		if (!isset($this->data[self::TEXTS_KEY])) {
			$this->data[self::TEXTS_KEY] = array();
		}

		if (!isset($this->data[self::PLACEHOLDER_JSON_KEY])) {
			$this->data[self::PLACEHOLDER_JSON_KEY] = array();
		}

	}

	/**
	 * Finds {@see TextT::$str} for given n2nLocales.
	 * null returned if no fitting {@see TextT::$str} found.
	 *
	 * @param string $key
	 * @param N2nLocale[] ...$n2nLocales
	 * @return string|null
	 */
	public function find(string $key, N2nLocale ...$n2nLocales): ?string {
		if (!isset($this->data[self::TEXTS_KEY][$key])) {
			return null;
		}

		array_push($n2nLocales, N2nLocale::getFallback());

		foreach ($n2nLocales as $n2nLocale) {
			$n2nLocaleId = $n2nLocale->getId();
			if (isset($this->data[self::TEXTS_KEY][$key][$n2nLocaleId])) {
				return $this->data[self::TEXTS_KEY][$key][$n2nLocaleId];
			}

			// if no region id than locale id and language id are the same.
			if (null === $n2nLocale->getRegionId()) {
				continue;
			}

			$langId = $n2nLocale->getLanguageId();
			if (isset($this->data[self::TEXTS_KEY][$key][$langId])) {
				return $this->data[self::TEXTS_KEY][$key][$langId];
			}
		}

		return null;
	}

	/**
	 * Use to check key available in {@see Group}.
	 *
	 * @param string $key
	 * @return bool
	 */
	public function has(string $key) {
		return isset($this->data[self::TEXTS_KEY][$key]);
	}

	/**
	 * Method adds key to {@see GroupData::$data} and triggers {@see GroupDataListener::keyAdded() listeners}.
	 *
	 * @param string $key
	 */
	public function add(string $key, array $args = []) {
		$this->data[self::TEXTS_KEY][$key] = array();
		$this->data[self::PLACEHOLDER_JSON_KEY][$key] = $args;

		foreach ($this->listeners as $listener) {
			$listener->keyAdded($key, $this);
		}
	}

	public function changePlaceholders(string $key, array $placeholders) {
		$this->data[self::PLACEHOLDER_JSON_KEY][$key] = $placeholders;

		foreach ($this->listeners as $listener) {
			$listener->placeholdersChanged($key, $this->getNamespace(), $placeholders);
		}
	}

	/**
	 * @param GroupDataListener $listener
	 */
	public function registerListener(GroupDataListener $listener) {
		$this->listeners[] = $listener;
	}

	/**
	 * @param GroupDataListener $listener
	 */
	public function unregisterListener(GroupDataListener $listener) {
		$this->listeners = array_filter($this->listeners, function($a) use($listener) {
			return $a !== $listener;
		});
	}

	/**
	 * @return string
	 */
	public function getNamespace(): string {
		return $this->namespace;
	}

	/**
	 * @param string $namespace
	 */
	public function setNamespace(string $namespace) {
		$this->namespace = $namespace;
	}

	/**
	 * @return string[][]
	 */
	public function getData(): array {
		return $this->data;
	}

	/**
	 * @param string[][] $data
	 */
	public function setData(array $data) {
		$this->data = $data;
	}

	/**
	 * @return string[]
	 */
	public function getKeys() {
		return array_keys($this->data[self::TEXTS_KEY]);
	}

	/**
	 * @return GroupDataListener[]
	 */
	public function getListeners() {
		return $this->listeners;
	}

	public function equalsPlaceholders(string $key, array $args) {
		if (!isset($this->data[self::PLACEHOLDER_JSON_KEY]) || !isset($this->data[self::PLACEHOLDER_JSON_KEY][$key])) {
			return false;
		}

		return array_keys($args) == array_keys((array) $this->data[self::PLACEHOLDER_JSON_KEY][$key]);
	}
}


<?php
namespace dbtext\storage;

use dbtext\config\DbtextConfig;
use n2n\context\RequestScoped;
use n2n\core\container\N2nContext;
use n2n\core\N2N;
use n2n\util\cache\CacheStore;
use n2n\util\cache\CorruptedCacheStoreException;

/**
 * Manages data for dbtext module.
 */
class DbtextCollectionManager implements RequestScoped, GroupDataListener {
	const NS = 'dbtext';
	const APP_CACHE_PREFIX = DbtextCollectionManager::class . '_';

	/**
	 * @var GroupData[] $groupDatas
	 */
	private $groupDatas;
	/**
	 * @var DbtextDao $dbtextDao
	 */
	private $dbtextDao;
	/**
	 * @var DbtextConfig $moduleConfig
	 */
	private $moduleConfig;
	/**
	 * @var CacheStore $cacheStore
	 */
	private $cacheStore;

	private function _init(DbtextDao $dbtextDao, N2nContext $n2nContext) {
		$this->dbtextDao = $dbtextDao;
		$this->moduleConfig = $n2nContext->getModuleConfig(self::NS);
		$this->cacheStore = $n2nContext->getAppCache()->lookupCacheStore(DbtextCollectionManager::class);
	}

	/**
	 * {@see GroupData} stored in cache or database can be found.
	 *
	 * @param string $namespace
	 * @return GroupData
	 */
	public function getGroupData(string $namespace) {
		if (isset($this->groupDatas[$namespace])) {
			return $this->groupDatas[$namespace];
		}

		$this->groupDatas[$namespace] = $this->readCachedGroupData($namespace);
		if ($this->groupDatas[$namespace] === null) {
			$this->groupDatas[$namespace] = $this->dbtextDao->getGroupData($namespace);
			$this->writeToAppCache($this->groupDatas[$namespace]);
		}

		if ($this->moduleConfig->isModifyOnRequest()) {
			$this->groupDatas[$namespace]->registerListener($this);
		}

		return $this->groupDatas[$namespace];
	}

	/**
	 * If no namespace is provided, the whole dbtext cache is cleared.
	 *
	 * @param string $namespace
	 */
	public function clearCache(string $namespace = null) {
		if (null !== $namespace) {
			$this->cacheStore->remove(self::APP_CACHE_PREFIX . $namespace, array());
			return;
		}

		$this->cacheStore->clear();
	}

	/**
	 * Adds a {@see Text} to {@see Group} then clears cache for {@see Group::$groupdata::namespace}.
	 *
	 * @param string $key
	 * @param GroupData $groupData
	 */
	public function keyAdded(string $key, GroupData $groupData, array $args = null) {
		$this->dbtextDao->insertKey($groupData->getNamespace(), $key, $args);
		$this->clearCache($groupData->getNamespace());
	}

	public function placeholdersChanged(string $key, string $ns, array $args = null) {
		$this->dbtextDao->changePlaceholders($key, $ns, $args);
	}

	/**
	 * Finds cached {@see GroupData} by given namespace.
	 * If dbtext cache of namespace is corrupt it is cleared.
	 *
	 * @param string $namespace
	 * @return GroupData|mixed|null
	 */
	private function readCachedGroupData(string $namespace) {
		// Due to confusion, no cached items are returned during development
		if (N2N::isDevelopmentModeOn()) return null;

		$groupData = null;
		try {
			$cacheItem = $this->cacheStore->get(self::APP_CACHE_PREFIX . $namespace, array());
			if ($cacheItem === null) return null;

			if ($cacheItem->data instanceof GroupData) {
				return $cacheItem->data;
			}
		} catch (CorruptedCacheStoreException $e) {
		}

		$this->clearCache($namespace);
		return null;
	}

	/**
	 * @param GroupData $groupData
	 */
	private function writeToAppCache(GroupData $groupData) {
		if (!empty($groupData->getListeners())) {
			throw new \InvalidArgumentException('GroupData cannot have registered listeners while caching');
		}
		$this->cacheStore->store(self::APP_CACHE_PREFIX . $groupData->getNamespace(), array(), $groupData);
	}
}


<?php
namespace dbtext\model;

use n2n\l10n\N2nLocale;

class GroupedDbtextCollection implements DbtextCollection {
	private $dbtextCollections;
	private $n2nLocales;

	/**
	 * @param DbtextCollection[] $dbtextCollections
	 * @param N2nLocale[] $n2nLocales
	 */
	public function __construct(array $dbtextCollections, array $n2nLocales) {
		$this->dbtextCollections = $dbtextCollections;
		$this->n2nLocales = $n2nLocales;
	}

	/**
	 * Finds most fitting {@see TextT} by locales provided and returns modified {@see TextT::$str}.
	 * {@see TextT::$str} args are replaced by {@see TextCollection::fillArgs()}.
	 *
	 * @param string $key
	 * @param array $args
	 * @param N2nLocale[] ...$n2nLocales
	 * @return string
	 */
	public function t(string $key, array $args = null, N2nLocale ...$n2nLocales): string {
		$passedN2nLocales = $n2nLocales ?? $this->n2nLocales;
		$passedN2nLocales[] = N2nLocale::getFallback();

		if (empty($this->dbtextCollections)) {
			return $key;
		}

		$n2nLocales = [];
		foreach ($passedN2nLocales as $passedN2nLocale) {
			$n2nLocales[] = $passedN2nLocale;

			if (null !== $passedN2nLocale->getRegionId()) {
				$n2nLocales[] = new N2nLocale($passedN2nLocale->getLanguageId());
			}
		}

		foreach ($this->dbtextCollections as $dbtextCollection) {
			if ($dbtextCollection->has($key)) {
				return $dbtextCollection->t($key, $args, ...$n2nLocales);
			}
		}

		if (reset($this->dbtextCollections)) {
			return reset($this->dbtextCollections)->t($key);
		}

		return $key;
	}

	/**
	 * Finds most fitting {@see TextT} by locales provided and returns modified {@see TextT::$str}.
	 * {@see TextT::$str} args are replaced by the printf method.
	 *
	 * @param string $key
	 * @param array $args
	 * @param N2nLocale[] ...$n2nLocales
	 * @return string
	 */
	public function tf(string $key, array $args = null, N2nLocale ...$n2nLocales): string {
		foreach ($this->dbtextCollections as $dbtextCollection) {
			if ($dbtextCollection->has($key)) {
				return $dbtextCollection->tf($key, $args, ...$this->n2nLocales);
			}
		}

		if (reset($this->dbtextCollections)) {
			return reset($this->dbtextCollections)->t($key);
		}

		return $key;
	}

	/**
	 * {@inheritDoc}
	 * @see \dbtext\model\DbtextCollection::has()
	 */
	public function has(string $key): bool {
		foreach ($this->dbtextCollections as $dbtextCollection) {
			if ($dbtextCollection->has($key)) {
				return true;
			}
		}

		return false;
	}

	/**
	 * {@inheritDoc}
	 * @see \dbtext\model\DbtextCollection::getKeys()
	 */
	public function getKeys(): array {
		if (1 == count($this->dbtextCollections)) {
			return reset($this->dbtextCollections)->getKeys();
		}

		$keys = array();

		foreach ($this->dbtextCollections as $dbtextCollection) {
			array_push($keys, ...$dbtextCollection->getKeys());
		}

		return array_unique($keys);;
	}
}


<?php
namespace dbtext\model;

use dbtext\storage\DbtextCollectionManager;
use n2n\context\RequestScoped;
use n2n\l10n\N2nLocale;
use n2n\core\container\N2nContext;

class DbtextService implements RequestScoped {
	/**
	 * @var DbtextCollection[]
	 */
	private $dbtextCollections;
	/**
	 * @var DbtextCollectionManager $tcm
	 */
	private $tcm;
	/**
	 *
	 * @var N2nContext
	 */
	private $n2nContext;

	private function _init(DbtextCollectionManager $tcm, N2nContext $n2nContext) {
		$this->tcm = $tcm;
		$this->n2nContext = $n2nContext;
	}

	/**
	 * Uses {@see DbtextCollection dbtextCollections} to translate a textblock.
	 *
	 * @see DbtextCollection::t()
	 * @param string|string[] $ns
	 * @param string $key
	 * @param array|null $args
	 * @param N2nLocale[] ...$n2nLocales
	 * @return string
	 */
	public function t($ns, string $key, array $args = null, N2nLocale ...$n2nLocales): string {
		if (empty($n2nLocales)) {
			$n2nLocales[] = $this->n2nContext->getN2nLocale();
		}

		if (!is_array($ns) && $this->dbtextCollections[$ns]) {
			return $this->dbtextCollections[$ns]->t($key, $args, ...$n2nLocales);
		}

		return $this->tc($ns, ...$n2nLocales)->t($key, $args, ...$n2nLocales);
	}

	/**
	 * Uses {@see DbtextCollection dbtextCollections} to translate a textblock.
	 *
	 * @see DbtextCollection::tf()
	 * @param string|string[] $ns
	 * @param string $key
	 * @param array|null $args
	 * @param N2nLocale[] ...$n2nLocale
	 * @return string
	 */
	public function tf($ns, string $key, array $args = null, N2nLocale ...$n2nLocales): string {
		$namespaces = array();
		if (!is_array($ns)) {
			$namespaces[] = $ns;
		}

		if (!is_array($ns) && $this->dbtextCollections[$ns]) {
			return $this->dbtextCollections[$ns]->tf($key, $args, ...$n2nLocales);
		}

		return $this->tc($ns, ...$n2nLocales)->tf($key, $args, ...$n2nLocales);
	}

	/**
	 * Returns fitting {@see TextCollection}
	 *
	 * @param string|string[] $ns
	 * @return DbtextCollection
	 */
	public function tc($ns, N2nLocale ...$n2nLocales): DbtextCollection {
		if (empty($n2nLocales)) {
			$n2nLocales[] = $this->n2nContext->getN2nLocale();
		}

		if (!is_array($ns)) {
			return $this->getOrCreateBasicDbCollection($ns, ...$n2nLocales);
		} elseif (count($ns) === 1) {
			return $this->getOrCreateBasicDbCollection(reset($ns), ...$n2nLocales);
		}

		$dbtextCollections = array();
		foreach ($ns as $namespace) {
			$dbtextCollections[] = $this->getOrCreateBasicDbCollection($namespace, ...$n2nLocales);
		}

		return new GroupedDbtextCollection($dbtextCollections, $n2nLocales);
	}

	/**
	 * Clears dbtext cache
	 *
	 * @param string $namespace Clears whole cache if no namespace provided.
	 */
	public function clearCache(string $namespace = null) {
		$this->tcm->clearCache($namespace);
	}

	private function getOrCreateBasicDbCollection(string $namespace, N2nLocale ...$n2nLocale) {
		if (!isset($this->dbtextCollections[$namespace])) {
			$this->dbtextCollections[$namespace] = new BasicDbtextCollection($this->tcm->getGroupData($namespace), ...$n2nLocale);
		}

		return $this->dbtextCollections[$namespace];
	}
}


<?php
namespace dbtext\model;

use dbtext\storage\GroupData;
use n2n\l10n\N2nLocale;
use n2n\l10n\TextCollection;
use n2n\util\StringUtils;

/**
 * Manages {@see GroupData}.
 */
class BasicDbtextCollection implements DbtextCollection {
	/**
	 * @var GroupData $groupData
	 */
	private $groupData;
	/**
	 * @var N2nLocale[] $n2nLocale
	 */
	private $n2nLocales;

	/**
	 * @param GroupData $groupData
	 */
	public function __construct(GroupData $groupData, N2nLocale ...$n2nLocales) {
		$this->groupData = $groupData;
		$this->n2nLocales = $n2nLocales;
	}

	/**
	 * {@inheritDoc}
	 */
	public function t(string $key, array $args = null, N2nLocale ...$n2nLocales): string {
		$n2nLocales = array_merge($n2nLocales, $this->n2nLocales);
		$n2nLocales[] = N2nLocale::getFallback();
		$args = (array) $args;

		if (!$this->has($key)) {
			$this->groupData->add($key, $args);
		} else if (!$this->groupData->equalsPlaceholders($key, $args)) {
			$this->groupData->changePlaceholders($key, $args);
		}

		$text = $this->groupData->find($key, ...$n2nLocales);
		if ($text === null) {
			return StringUtils::pretty(TextCollection::implode($key, $args));
		}

		return TextCollection::fillArgs($text, $args);
	}

	/**
	 * {@inheritDoc}
	 */
	public function tf(string $key, array $args = null, N2nLocale ...$n2nLocales): string {
		$n2nLocales = array_merge($n2nLocales, $this->n2nLocales);
		$n2nLocales[] = N2nLocale::getFallback();

		if (!$this->has($key)) {
			$this->groupData->add($key, $args);
		}

		$text = $this->groupData->find($key, ...$n2nLocales);
		if ($text === null) {
			return StringUtils::pretty(TextCollection::implode($key, $args));
		}

		$text = @sprintf($text, ...$args);

		if (!!$text) {
			return $text;
		}

		return $key;
	}

	/**
	 * {@inheritDoc}
	 */
	public function has(string $key): bool {
		return $this->groupData->has($key);
	}

	public function getKeys(): array {
		return $this->groupData->getKeys();
	}
}