<?php

namespace Flowcode\DashboardBundle\Controller;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Flowcode\DashboardBundle\Entity\Job;
use Flowcode\DashboardBundle\Form\Type\JobType;
use Doctrine\ORM\QueryBuilder;

/**
 * Job controller.
 *
 * @Route("/admin/amulen/job")
 */
class JobController extends Controller
{
    /**
     * Lists all Job entities.
     *
     * @Route("/", name="admin_amulen_job")
     * @Method("GET")
     * @Template()
     */
    public function indexAction(Request $request)
    {
        $em = $this->getDoctrine()->getManager();

        $page = $request->get("page", 1);
        $em = $this->getDoctrine()->getManager();
        $dql = "SELECT j FROM FlowcodeDashboardBundle:Job j ORDER BY j.updated DESC";
        $query = $em->createQuery($dql);

        $paginator = $this->get('knp_paginator');
        $pagination = $paginator->paginate(
            $query, $this->get('request')->query->get('page', $page), 50);

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

    /**
     * Finds and displays a Job entity.
     *
     * @Route("/{id}/show", name="admin_amulen_job_show", requirements={"id"="\d+"})
     * @Method("GET")
     * @Template()
     */
    public function showAction(Job $job)
    {
        $editForm = $this->createForm(new JobType(), $job, array(
            'action' => $this->generateUrl('admin_amulen_job_update', array('id' => $job->getid())),
            'method' => 'PUT',
        ));
        $deleteForm = $this->createDeleteForm($job->getId(), 'admin_amulen_job_delete');

        return array(

            'job' => $job, 'edit_form' => $editForm->createView(),
            'delete_form' => $deleteForm->createView(),

        );
    }

    /**
     * Displays a form to create a new Job entity.
     *
     * @Route("/new", name="admin_amulen_job_new")
     * @Method("GET")
     * @Template()
     */
    public function newAction()
    {
        $job = new Job();
        $form = $this->createForm(new JobType(), $job);

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

    /**
     * Creates a new Job entity.
     *
     * @Route("/create", name="admin_amulen_job_create")
     * @Method("POST")
     * @Template("FlowcodeDashboardBundle:Job:new.html.twig")
     */
    public function createAction(Request $request)
    {
        $job = new Job();
        $form = $this->createForm(new JobType(), $job);
        if ($form->handleRequest($request)->isValid()) {
            $em = $this->getDoctrine()->getManager();
            $em->persist($job);
            $em->flush();

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

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

    /**
     * Edits an existing Job entity.
     *
     * @Route("/{id}/update", name="admin_amulen_job_update", requirements={"id"="\d+"})
     * @Method("PUT")
     * @Template("FlowcodeDashboardBundle:Job:edit.html.twig")
     */
    public function updateAction(Job $job, Request $request)
    {
        $editForm = $this->createForm(new JobType(), $job, array(
            'action' => $this->generateUrl('admin_amulen_job_update', array('id' => $job->getid())),
            'method' => 'PUT',
        ));
        if ($editForm->handleRequest($request)->isValid()) {
            $this->getDoctrine()->getManager()->flush();

            return $this->redirect($this->generateUrl('admin_amulen_job_show', array('id' => $job->getId())));
        }
        $deleteForm = $this->createDeleteForm($job->getId(), 'admin_amulen_job_delete');

        return array(
            'job' => $job,
            'edit_form' => $editForm->createView(),
            'delete_form' => $deleteForm->createView(),
        );
    }

    /**
     * Deletes a Job entity.
     *
     * @Route("/{id}/delete", name="admin_amulen_job_delete", requirements={"id"="\d+"})
     * @Method("DELETE")
     */
    public function deleteAction(Job $job, Request $request)
    {
        $form = $this->createDeleteForm($job->getId(), 'admin_amulen_job_delete');
        if ($form->handleRequest($request)->isValid()) {
            $em = $this->getDoctrine()->getManager();
            $em->remove($job);
            $em->flush();
        }

        return $this->redirect($this->generateUrl('admin_amulen_job'));
    }

    /**
     * Create Delete form
     *
     * @param integer $id
     * @param string $route
     * @return \Symfony\Component\Form\Form
     */
    protected function createDeleteForm($id, $route)
    {
        return $this->createFormBuilder(null, array('attr' => array('id' => 'delete')))
            ->setAction($this->generateUrl($route, array('id' => $id)))
            ->setMethod('DELETE')
            ->getForm();
    }

}


<?php
namespace gossi\trixionary\client\action;

use keeko\framework\foundation\AbstractAction;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use gossi\trixionary\model\SportQuery;
use Symfony\Component\OptionsResolver\OptionsResolver;

/**
 * Make a sport the default one
 *
 * This code is automatically created. Modifications will probably be overwritten.
 *
 * @author Thomas Gossmann
 */
class ManageDefaultAction extends AbstractAction {

	protected function configureParams(OptionsResolver $resolver) {
		$resolver->setRequired(['id']);
	}

	/**
	 * Automatically generated run method
	 *
	 * @param Request $request
	 * @return Response
	 */
	public function run(Request $request) {
		$sport = SportQuery::create()->findOneById($this->getParam('id'));

		if ($sport !== null) {
			$default = SportQuery::create()->findOneByIsDefault(true);
			$default->setIsDefault(false);
			$default->save();

			if ($sport->getId() != $default->getId()) {
				$sport->setIsDefault(true);
				$sport->save();
			}
		}

		return $this->responder->run($request);
	}
}


<?php
/**
 * This file is part of the CarteBlanche PHP framework.
 *
 * (c) Pierre Cassat <me@e-piwi.fr> and contributors
 *
 * License Apache-2.0 <http://github.com/php-carteblanche/carteblanche/blob/master/LICENSE>
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace CarteBlanche\Library;

use \CarteBlanche\CarteBlanche;
use \CarteBlanche\Exception\InvalidArgumentException;
use \Library\Helper\Directory as DirectoryHelper;

/**
 * File object extending PHP SplFileInfo
 *
 * @author  Piero Wbmstr <me@e-piwi.fr>
 */
class File
    extends \SplFileInfo
{

    protected $client_file_name;

// -----------------
// Constructor
// -----------------

    public function __construct( $file_name, $client_file_name=null )
    {
        parent::__construct( $file_name );
        if (!is_null($client_file_name)) $this->setClientFilename( $client_file_name );
    }

// -----------------
// Getters / Setters
// -----------------

    /**
     * Set the client filename
     *
     * @param   string  $file_name  The client filename for the file
     * @return  void
     * @throws   \CarteBlanche\Exception\InvalidArgumentException if the file name is not a string
     */
    public function setClientFilename($file_name)
    {
        if (is_string($file_name)) {
            $this->client_file_name = $file_name;
            $_ext = $this->guessExtension();
            if (!empty($_ext) && !strstr($file_name, $_ext))
                $this->client_file_name .= '.'.$_ext;
        } else {
            throw new InvalidArgumentException(
                sprintf('Client name of a file must be a string (got "%s")!', gettype($file_name))
            );
        }
    }

    /**
     * Get the client filename if so, the filename if not
     *
     * @return  string  The client filename
     */
    public function getClientFilename()
    {
        return !empty($this->client_file_name) ? $this->client_file_name : $this->getFilename();
    }

    /**
     * Get the filename without extension
     *
     * @return  string  The isolated filename
     * @see     \SplFileInfo::getBasename()
     */
    public function getFilenameWithoutExtension()
    {
        return $this->getBasename( '.'.$this->getExtension() );
    }

    /**
     * Get the file extension or guess it from MIME type if so ...
     *
     * @return  string  The guessed extension
     * @see     \SplFileInfo::getExtension()
     */
    public function guessExtension()
    {
        $_ext = $this->getExtension();
        if (empty($_ext) && $this->getRealPath()) {
            $finfo = new \finfo();
            $mime = $finfo->file( $this->getRealPath(), FILEINFO_MIME_TYPE );
            $_ext = str_replace('image/', '', $mime);
        }
        return $_ext;
    }

    /**
     * Get the file path (web accessible)
     *
     * @return  string  The target filepath
     */
    public function getWebPath()
    {
        return str_replace(CarteBlanche::getPath('web_dir'), '', $this->getRealPath());
    }

    /**
     * Get the file miem string if possible
     *
     * @return  string  The mime type info
     */
    public function getMime()
    {
        if ($this->getRealPath()) {
            $finfo = new \finfo();
            return $finfo->file( $this->getRealPath(), FILEINFO_MIME_TYPE );
        }
        return null;
    }

    /**
     * Get the file size in human readable string
     *
     * @param   int     $decimals   The decimals number to use in calculated file size
     * @return  string  A human readable string describing a file size
     */
    public function getHumanSize( $decimals=2 )
    {
        $sz = array('B', 'KB', 'MB', 'GB', 'TB', 'PB');
        $factor = floor((strlen($this->getSize()) - 1) / 3);
        if ($factor >= count($sz)) $factor = count($sz)-1;
        return sprintf("%.{$decimals}f", $this->getSize() / pow(1024, $factor)) . $sz[$factor];
    }

    /**
     * Get the stat infos of the file
     *
     * @return  array   The stat infos array about the file
     */
    public function getStat()
    {
        return $this->openFile()->fstat();
    }

    /**
     * Get the last access time on the file and return it as a DateTime object
     *
     * @return  null|object     The datetime object if so
     */
    public function getATimeAsDatetime()
    {
        $_date = $this->getATime();
        if (!empty($_date))
            return \DateTime::createFromFormat( 'U', $_date );
        return null;
    }

    /**
     * Get the creation time on the file and return it as a DateTime object
     *
     * @return  null|object     The datetime object if so
     */
    public function getCTimeAsDatetime()
    {
        $_date = $this->getCTime();
        if (!empty($_date))
            return \DateTime::createFromFormat( 'U', $_date );
        return null;
    }

    /**
     * Get the last modification time on the file and return it as a DateTime object
     *
     * @return  null|object     The datetime object if so
     */
    public function getMTimeAsDatetime()
    {
        $_date = $this->getMTime();
        if (!empty($_date))
            return \DateTime::createFromFormat( 'U', $_date );
        return null;
    }

    /**
     * Check if a file seems to be an image, based on its mime type signature
     *
     * @return  bool    True if the file seems to be an image, false otherwise
     */
    public function isImage()
    {
        $finfo = new \finfo();
        return (0!=preg_match('#^image/(.*)$#', $finfo->file( $this->getRealPath(), FILEINFO_MIME_TYPE )));
    }

// ---------------------
// Create a file from a content string
// ---------------------

    /**
     * Create a file with a content string and returns the created filename
     *
     * @param   string  $file_content   The source file content
     * @param   string  $filename       The target filename (optional - automatic if not set)
     * @return  \CarteBlanche\Library\File
     */
    public static function createFromContent( $file_content, $filename=null, $client_file_name=null )
    {
        $finfo = new \finfo();
        $mime = $finfo->buffer( $file_content, FILEINFO_MIME_TYPE );
        $extension = end(explode('/', $mime));
        if (is_null($filename)) {
            $_tmp_filename = md5( $file_content ).'.'.$extension;
            $filename = CarteBlanche::getFullPath('web_tmp_dir').$_tmp_filename;
            if (file_exists($filename)) {
                return new File( $filename, $client_file_name );
            }
        } elseif (end(explode('.', $filename))!=$extension) {
            $filename .= '.'.$extension;
        }

        $_tf = fopen($filename, 'a+');
        if ($_tf) {
            fwrite($_tf, $file_content);
            fclose($_tf);
            return new File( $filename, $client_file_name );
        }
        return null;
    }

}

/*
$test_img = 'tmp/test_img.png';
$test_noext = 'tmp/10504-F1';

echo '
';
foreach( array($test_img, $test_noext) as $_f)
{
  $a = new \CarteBlanche\Library\File( $_f );
  echo '
object : '.var_export($a,1);
  echo '
filename : '.$a->getFilename();
  echo '
file basename : '.$a->getBasename();
  echo '
file extension : '.$a->getExtension();
  echo '
file guess extension : '.$a->guessExtension();
  echo '
file basename without extension : '.$a->getFilenameWithoutExtension();
  echo '
file real path : '.$a->getRealPath();
  echo '
file size : '.$a->getSize();
  echo '
file size human readable : '.$a->getHumanSize();
  echo '
file stats : '.var_export($a->getStat(),1);
  echo '
file aTime as DateTime : '.var_export($a->getATimeAsDatetime(),1);
  echo '
file cTime as DateTime : '.var_export($a->getCTimeAsDatetime(),1);
  echo '
file mTime as DateTime : '.var_export($a->getMTimeAsDatetime(),1);
  echo '
file is image ? : '.var_export($a->isImage(),1);
  echo '
file mime type ? : '.$a->getMime();
  echo '
';
}
echo '
';
//exit('yo');
*/
// Endfile


<?php

/*
 * This file is part of the SmarTwig (Twig Extension).
 *
 * (c) Omar Yepez <omar.yepez@yepsua.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Yepsua\SmarTwig\Twig\Node;

use \Twig_Node;
use \Twig_Compiler;
use \Twig_Node_Expression;
use \Twig_Node_Expression_Constant;
use \Twig_Node_Expression_Name;

use \Yepsua\SmarTwig\Util\HTMLUtil;

class CommonNode extends Twig_Node {

  private static $LOOP_VAR = 'loop';

  protected $content;
  protected $indexVar;
  protected $id;
  protected $selector;
  protected $varName;
  protected $htmlProperties;
  protected $execute;
  protected $loop;
  protected $optionsVarName;
  protected $callableMethods;
  protected $iterable;
  protected $iteratorValue;
  protected $iteratorVarName;
  protected $validateEmpty;
  protected $emptyMessage;
  protected $isRenderizable;
  protected $onlyJsS;
  protected $onlyHTML;
  protected $inSelector;
  protected $isExec;
  protected $isBuiltByListener;
  protected $isPlugin;

  public function __construct(array $nodes = array(), array $attributes = array(), $lineno = 0, $tag = null) {
    parent::__construct($nodes, $attributes, $lineno, $tag);
    $this->setOnlyHTML(false);
    $this->setOnlyJsS($this->getNode('values')->hasNode('builtIn'));
    $this->setInSelector(true);
    $this->setExec(true);
    $this->setBuiltByListener($this->getNode('values')->hasNode('builtBy'));
  }

  /**
   *
   * @return type
   */
  public function getId() {
    return $this->id . $this->getSuffixId();
  }

  /**
   *
   * @param type $id
   */
  public function setId($id) {
    $this->id = $id;
  }

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

  /**
   *
   * @param type $selector
   */
  public function setSelector($selector) {
    $this->selector = $selector;
  }

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

  /**
   *
   * @param type $varName
   */
  public function setVarName($varName) {
    $this->varName = $varName;
  }

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

  /**
   *
   * @param type $htmlProperties
   */
  public function setHtmlProperties($htmlProperties) {
    $this->htmlProperties = $htmlProperties;
  }

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

  /**
   *
   * @param type $execute
   */
  public function setExecuteSintax($execute) {
    $this->execute = $execute;
  }

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

  /**
   *
   * @param type $loop
   */
  public function setLoop($loop) {
    $this->loop = $loop;
  }

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

  /**
   *
   * @param type $optionsVarName
   */
  public function setOptionsVarName($optionsVarName) {
    $this->optionsVarName = $optionsVarName;
  }

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

  /**
   *
   * @param type $iterable
   */
  public function setIterable($iterable) {
    $this->iterable = $iterable;
  }

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

  /**
   *
   * @param type $iteratorValue
   */
  public function setIteratorValue($iteratorValue) {
    $this->iteratorValue = $iteratorValue;
  }

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

  /**
   *
   * @param type $iteratorVarName
   */
  public function setIteratorVarName($iteratorVarName) {
    $this->iteratorVarName = $iteratorVarName;
  }

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

  /**
   *
   * @param type $indexVar
   */
  public function setIndexVar($indexVar) {
    $this->indexVar = $indexVar;
  }

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

  /**
   *
   * @param type $validateEmpty
   */
  public function setValidateEmpty($validateEmpty) {
    $this->validateEmpty = $validateEmpty;
  }

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

  /**
   *
   * @param type $emptyMessage
   */
  public function setEmptyMessage($emptyMessage) {
    $this->emptyMessage = $emptyMessage;
  }

  /**
   *
   * @return type
   */
  public function getValues(){
    return $this->getNode('values');
  }

  /**
   *
   * @return type
   */
  public function getNames(){
    return $this->getAttribute('names');
  }

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

  /**
   *
   * @param type $isRederizable
   */
  public function setRenderizable($isRederizable) {
    $this->isRederizable = $isRederizable;
  }

  /**
   *
   * @return type
   */
  public function isIterableNode() {
    return false;
  }

  public function isOnlyJsS() {
    return $this->onlyJsS;
  }

  public function setOnlyJsS($onlyJsS) {
    $this->onlyJsS = $onlyJsS;
  }

  public function isOnlyHTML() {
    return $this->onlyHTML;
  }

  public function setOnlyHTML($onlyHTML) {
    $this->onlyHTML = $onlyHTML;
  }

  public function isInSelector() {
    return $this->inSelector;
  }

  public function setInSelector($inSelector) {
    $this->inSelector = $inSelector;
  }

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

  public function setExec($isExec) {
    $this->isExec = $isExec;
  }

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

  public function setBuiltByListener($isBuiltByListener) {
    $this->isBuiltByListener = $isBuiltByListener;
  }

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

  public function setIsPlugin($isPlugin) {
    $this->isPlugin = $isPlugin;
  }

  public function getRenderizableConditionNode($node = null){
    $rNode = null;
    if($node === null){
      $rNode = $this->getNode('values')->getNode('rendered');
    }else{
      $rNode = $node->getNode('rendered');
    }
    return $rNode;
  }

  public function getCommonsCallableMethods(){
    return array(
      'widgetVar' => array('method' => 'assignToVar',
                           'args' => array(false)
      ),
      'timeout' => array('method' => 'timeout'),
      'confirmation' => array('method' => 'confirmation'),
      'condition' => array('method' => 'condition'),
      'interval' => array('method' => 'setInterval'),
      'options' => array('method' => 'addOptions'),
    );
  }

  public function init(){
    $this->defineId();
    $this->defineVarName();
    $this->defineIsRenderizable();
    //$this->buildWidgetVar();
    $this->defineOptionsVarName();
    $this->buildSintaxConfiguration();
    if($this->isIterableNode()){
      $this->buildIterableSintax();
    }
    $this->setEmptyMessage("No Data Found");
  }

  /**
   * Compiles the node to PHP.
   *
   * @param Twig_Compiler A Twig_Compiler instance
   */
  public function compile(Twig_Compiler $compiler){
    $this->init();
    if($this->isRenderizable()){
      $this->compileIfRendered($compiler, $this->getRenderizableConditionNode());
    }
    $this->preCompileWidget($compiler);
    $this->compileWidget($compiler);
    $this->postCompileWidget($compiler);
    if($this->isRenderizable()){
      $this->compileEndIf($compiler);
    }
  }

  /**
   * Compiles the widgetn-ode to PHP.
   *
   * @param Twig_Compiler A Twig_Compiler instance
   */
  public function compileWidget(Twig_Compiler $compiler){
    return false;
  }

  /**
   * Compiles the widgetn-ode to PHP.
   *
   * @param Twig_Compiler A Twig_Compiler instance
   */
  public function preCompileWidget(Twig_Compiler $compiler){
    return false;
  }

    /**
   * Compiles the widgetn-ode to PHP.
   *
   * @param Twig_Compiler A Twig_Compiler instance
   */
  public function postCompileWidget(Twig_Compiler $compiler){
    return false;
  }

  /**
   *
   * @param type $name
   */
  public function removePropertie($name){
    if(!in_array($name, $this->noRemovableProperties())){
      $names = $this->getAttribute('names');
      unset ($names[$name]);
      $this->setAttribute('names', $names);
      $this->getNode('values')->removeNode($name);
    }
  }

  public function noRemovableProperties(){
    return array();
  }

  /**
   *
   * @param array $names
   */
  public function removeProperties(array $names){
    foreach($names as $name){
      $this->removePropertie($name);
    }
  }

  /**
   *
   * @param type $nodeName
   * @return type
   */
  public function getNodeValue($nodeName, $twigNode = null){
    if($twigNode === null){
      $node = $this->getNode('values')->getNode($nodeName);
    }else{
      $node = $twigNode->getNode($nodeName);
    }
    return $node->getAttribute('value');
  }

  /**
   *
   * @param type $nodeName
   * @param type $appendValue
   * @param type $parentNode
   */
  public function appendValueInNode($nodeName, $appendValue, $parentNode = 'values'){
    $node = $this->getNode($parentNode)->getNode($nodeName);
    $node->setAttribute('value',sprintf('%s%s',$node->getAttribute('value'),$appendValue));
    $this->getNode($parentNode)->setNode($nodeName, $node);
  }

  /**
   *
   * @param type $nodeName
   * @param type $appendValue
   * @param type $parentNode
   */
  public function appendValueInNode2($twigNode, $appendValue){
    $twigNode->setAttribute('value',sprintf('%s%s',$twigNode->getAttribute('value'),$appendValue));
  }

  /**
   *
   * @param type $nodeName
   * @param type $prependValue
   * @param type $parentNode
   */
  public function prependValueInNode($nodeName, $prependValue,$parentNode = 'values'){
    $node = $this->getNode($parentNode)->getNode($nodeName);
    $node->setAttribute('value',sprintf('%s%s',$prependValue,$node->getAttribute('value')));
    $this->getNode($parentNode)->setNode($nodeName, $node);
  }

  public function addNode($key,Twig_Node_Expression $newNode, Twig_Node_Expression $newName, $node = null, $attribute = null){
    if($node === null){
      $this->getNode('values')->setNode($key, $newNode);
    }else{
      $node->setNode($key, $newNode);
    }
    if($attribute === null){
      $names = $this->getAttribute('names');
      $names[$key] = $newName;
      $this->setAttribute('names', $names);
    }else{
      $names = $attribute;
      $names[$key] = $newName;
    }
    return array('node' => $node, 'attribute' => $attribute);
  }

  public function addExpressionConstantNode($key,$nodeValue,$lineno){
    $node = new Twig_Node_Expression_Constant($nodeValue, $lineno);
    $name = new Twig_Node_Expression_Name($key, $lineno);
    return $this->addNode($key,$node, $name);
  }

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

  /**
   *
   * @param type $content
   */
  public function setContent($content) {
    $this->content = $content;
  }

  /**
   *
   * @return type
   */
  public function buildId() {
    $id = null;
    if ($this->getNode('values')->hasNode('id')
        && $this->getNode('values')->getNode('id') instanceof Twig_Node_Expression_Constant ) {
      $id = $this->getNode('values')->getNode('id')->getAttribute('value');
    } else {
      $id = sprintf('%s%s',$this->getWidgetName(),rand(1, 1000));
    }
    //$this->removePropertie('id');
    return $id;
  }

  public function defineId() {
    $this->setId($this->buildId());
  }

  public function buildOptionsVarName(){
    return sprintf('%s%s',$this->getVarName(),'Options');
  }

  public function defineOptionsVarName (){
    $this->setOptionsVarName($this->buildOptionsVarName());
  }

  public function buildVarName() {
    $suffix = ($this->getId() instanceof Twig_Node) ? rand(1,1000) :  $this->getId();
    $suffix = str_replace(array('-','.'),'_', $suffix);
    return sprintf('$%s%s', $this->getWidgetName(), $suffix);
  }

  public function defineVarName() {
    $this->setVarName($this->buildVarName());
  }

  public function defineIsRenderizable(){
    if($this->hasNode('values')){
      $this->setRenderizable($this->getNode('values')->hasNode('rendered'));
    }else{
      $this->setRenderizable(false);
    }
  }

  public function buildHtmlProperties(){
    $htmlProperties = ($this->getNode('values')->hasNode('htmlProperties'))
      ? $this->getNodeValue('htmlProperties')
      : null;
    $this->removePropertie('htmlProperties');
    $this->setHtmlProperties($htmlProperties);
  }

  public function compileStandardHtmlProperties(Twig_Compiler $compiler, $node = null){
    $node = ($node === null) ? $this->getNode('values') : $node;
    $attrs = $this->getStandardHtmlProperties();
    $compiler->raw('preg_replace(\'/\w=""/\'," ",""');
    foreach($attrs as $attr){
      if($node->hasNode($attr)){
        $compiler->raw(' . sprintf(\'');
        $compiler->raw(sprintf('%s="', $attr), true);
        $compiler->raw('%s"\',');
        $compiler->subcompile($node->getNode($attr));
        $compiler->raw(')');
        if($attr !== 'id'){
          $this->removePropertie($attr);
        }
      }
    }
    $compiler->raw(')');
  }

  public function getStandardHtmlProperties(){
    return array_merge(HTMLUtil::getStandardHtmlProperties(), $this->configureHTMLProperties());
  }

  public function configureHTMLProperties(){
    return $this->getHTMLAttrs('div');
  }

  public function compileHtmlProperties(Twig_Compiler $compiler, $args = array()){
    $this->compileStandardHtmlProperties($compiler);
    $compiler->write(');');
    $compiler->raw("\n");
  }

  public function buildWidgetVar(){
    if($this->getNode('values')->hasNode('widgetVar')){
      $this->prependValueInNode('widgetVar', 'var ');
    }
  }

  public function buildSintaxConfiguration(){
    $execute = ($this->getNode('values')->hasNode('executeOnReady')
            && $this->getNodeValue('executeOnReady'))
            ? '->executeOnReady()'
            : '->execute()';
    $this->removePropertie('executeOnReady');
    $execute = ($this->getNode('values')->hasNode('showSintax')
            && $this->getNodeValue('showSintax'))
            ? ''
            : '->execute()';
    $this->removePropertie('showSintax');
    $this->setExecuteSintax($execute);
  }

  public function buildIterableSintax(){
      $this->setIndexVar(self::$LOOP_VAR);

      $this->setLoop(false);
      $this->isIterable(false);
      $this->setValidateEmpty(false);

      if($this->getNode('values')->hasNode('indexVar')){
         $this->setLoop(true);
         $this->setIndexVar($this->getNodeValue('indexVar'));
         $this->removePropertie('indexVar');
      }

      if($this->getNode('values')->hasNode('values')){
        $this->setIterable(true);
        $this->setIteratorValue($this->getNodeValue('values'));
        $this->removePropertie('values');
      }

      if($this->getNode('values')->hasNode('var')){
         $this->setIterable(true);
         $this->setIteratorVarName($this->getNodeValue('var'));
         $this->removePropertie('var');
      }

      if($this->getNode('values')->hasNode('emptyMessage')){
         $this->setValidateEmpty(true);
         $this->setEmptyMessage($this->getNodeValue('emptyMessage'));
         $this->removePropertie('emptyMessage');
      }

  }

  /**
   *
   * @param \Twig_Compiler $compiler
   */
  public function compileOptions(Twig_Compiler $compiler) {
    $i = 0;
    $compiler->write(sprintf('%s = array(', $this->getOptionsVarName()));
    $compiler->raw("\n");
    $compiler->indent();
      foreach ($this->getNames() as $name) {
        if(!in_array($name->getAttribute('name'), $this->getAllOptionsToSkip())){
          $names[$name->getAttribute('name')] = sprintf('"%s" =>', $name->getAttribute('name'));
        }
      }
      foreach ($this->getValues() as $key => $node) {
        if (isset($names[$key])) {
          $conpile = true;
          if($this->getAllCallableMethods() !== null){
            foreach($this->getAllCallableMethods() as $keyC => $valueC){
              if($keyC === $key){
                $conpile = false;
                break;
              }
            }
          }
          if($conpile){
            $compiler->write($names[$key]);
            $compiler->subcompile($node);
            $compiler->raw(",");
            $compiler->raw("\n");
          }
        }
      }
    $compiler->outdent();
    $compiler->write(");\n");
  }

  /**
   *
   * @param \Twig_Compiler $compiler
   */
  public function compileCallableMethods(Twig_Compiler $compiler){
    $callableMethods = $this->getAllCallableMethods();
    foreach($callableMethods as $name => $data){
      if($this->getNode('values')->hasNode($name)){
        $compiler->write(sprintf('->%s(',$data['method']));
        $compiler->subcompile($this->getNode('values')->getNode($name));
        if(isset($data['args'])){
          foreach($data['args'] as $arg){
            $compiler->raw(",");
            $compiler->subcompile(new Twig_Node_Expression_Constant($arg, 0));
          }
        }
        $this->removePropertie($name);
        $compiler->raw(")\n");
      }
    }
  }

  public function configureCallableMethods(){
    return array();
  }

  public function getAllCallableMethods(){
    $methods = array_merge($this->getCommonsCallableMethods(),$this->configureCallableMethods());

    return $methods;
  }

  public function getAllOptionsToSkip(){
    return array_merge($this->getStandardHtmlProperties(),$this->getOptionsToSkip());
  }

  public function getOptionsToSkip(){
    return array();
  }

  public function replaceIndexVar($string){
    if(is_array($string)){
      $replacedValues = array();
      foreach($string as $val){
        $replacedValues[] = str_replace("%INDEX_VAR%",$this->getIndexVar(), $val);
      }
    }
    return str_replace("%INDEX_VAR%",$this->getIndexVar(), $string);
  }

  public function compileIteratorInitSintax(Twig_Compiler $compiler){
      foreach($this->getIteratorInitSintax() as $sintax){
        $compiler->write($sintax);
        $compiler->raw("\n");
      }
    }

  public function compileIteratorEndSintax(Twig_Compiler $compiler, $validateEmpty = false){
    foreach($this->getIteratorEndSintax($validateEmpty) as $sintax){
      $compiler->write($sintax);
      $compiler->raw("\n");
    }
  }

  public function compileIfRendered(Twig_Compiler $compiler, $rendered, $isForIterableSection = false){
    $compiler->write('if(');
    $compiler->indent();
      $compiler->subcompile($rendered);
    $compiler->raw("){\n");
    if($isForIterableSection){
      $compiler->write('$context[\'_hasContent\'] = true;');
      $compiler->raw("\n");
      $compiler->write($this->replaceIndexVar('if(isset($context[\'%INDEX_VAR%\'][\'renderedIndex\']))$context[\'%INDEX_VAR%\'][\'renderedIndex\']++;'));
    }
    $compiler->raw("\n");
  }

  public function compileEndIf(Twig_Compiler $compiler){
    $compiler->outdent();
    $compiler->write('}');
    $compiler->raw("\n");
  }

  public function compileWidgetId(Twig_Compiler $compiler){
    if ($this->getNode('values')->hasNode('id')
        && !$this->getNode('values')->getNode('id') instanceof Twig_Node_Expression_Constant) {
      $compiler->subcompile($this->getNode('values')->getNode('id'));
    } else {
      $compiler->raw(sprintf('"%s"',$this->getId()));
    }
  }

  public function compileSelector(Twig_Compiler $compiler, $selector = '#'){
    if($this->getNode('values')->hasNode('builtIn')){
      $compiler->subcompile($this->getNode('values')->getNode('builtIn'));
    }else{
      if ($this->getNode('values')->hasNode('id')
        && !$this->getNode('values')->getNode('id') instanceof Twig_Node_Expression_Constant) {
        $compiler->raw(sprintf('"%s" . ', $selector));
        $compiler->subcompile($this->getNode('values')->getNode('id'));
      } else {
        $compiler->raw(sprintf('"%s%s"', $selector, $this->getId()));
      }
    }
  }

  public function compileExtension(Twig_Compiler $compiler){
    if($this->isPlugin()){
      $compiler->write(sprintf('$this->env->getExtension(\'ui.core\')->getWidget(\'ui.jqueryCore\')->usePlugin(\'%s\');',$this->getPluginName()));
      $compiler->raw("\n");
    }
    $compiler->write(sprintf('%s = $this->env->getExtension(\'%s\')->getWidget(\'ui.%s\');',$this->getVarName(),$this->getExtensionIndex(),$this->getWidgetName()));
    $compiler->raw("\n");
  }

  public function getExtensionIndex(){
    return ($this->isPlugin()) ? 'ui.addons' :'ui.core';
  }

  public function compileInitWidget(Twig_Compiler $compiler){
    $compiler->write(sprintf('echo %s->initWidget(',$this->getVarName()));
    $this->compileWidgetId($compiler);
    $compiler->raw(',');
  }

  public function compileEndWidget(Twig_Compiler $compiler){
    $compiler->write(sprintf('echo %s->endWidget();',$this->getVarName()));
    $compiler->raw("\n");
  }

  public function compileBuilder(Twig_Compiler $compiler){
    if($this->isBuiltByListener()){
      $compiler->raw(sprintf('%s',$this->getVarName()));
    }else{
      $compiler->write(sprintf('echo %s',$this->getVarName()));
    }
    $this->compileBuilderFuntcionName($compiler);
    if($this->isExec()){
      $compiler->indent();
      $compiler->indent();
      if($this->isBuiltByListener()){
        $compiler->indent();
      }
      if($this->isInSelector()){
        $compiler->write("\n");
        $compiler->write('->in(');
        $this->compileSelector($compiler);
        $compiler->raw(')');
      }
      $compiler->write("\n");
      $compiler->write(sprintf("->addOptions(%s)\n",$this->getOptionsVarName()));
    }else{
      $compiler->write(';');
    }
  }

  public function compileListener(Twig_Compiler $compiler){
    $compiler->write('$jQuery = $this->env->getExtension(\'ui.core\')->getWidget(\'ui.jqueryCore\');');
    $compiler->raw("\n");
    $compiler->write('echo $jQuery');
    $compiler->indent();
    $compiler->indent();
    if($this->getNode('values')->hasNode('builtByEvent')){
      $compiler->raw('->setEvent(');
      $compiler->subcompile($this->getNode('values')->getNode('builtByEvent'));
      $compiler->raw(")\n");
    }
    if($this->getNode('values')->hasNode('builtByEvent')){
      $compiler->write('->in(');
      $compiler->subcompile($this->getNode('values')->getNode('builtBy'));
      $compiler->raw(")\n");
    }
    $compiler->write('->execute(');
  }

  public function compileBuilderFuntcionName(Twig_Compiler $compiler){
    $compiler->raw('->build()');
  }

  public function compileExecute(Twig_Compiler $compiler){
    if($this->isBuiltByListener()){
      $compiler->write(')');
    }else{
      $compiler->write(sprintf('%s;',$this->getExecuteSintax()));
    }
    $compiler->outdent();
    $compiler->outdent();
    if($this->isBuiltByListener()){
      $compiler->outdent();
      $compiler->raw("\n");
      $compiler->write('->setPreSintax("$(document).ready(function(){")');
      $compiler->raw("\n");
      $compiler->write('->setPostSintax("})")');
      $compiler->raw("\n");
      $compiler->write('->execute();');
      $compiler->raw("\n");
      $compiler->outdent();
      $compiler->outdent();
    }
    $compiler->write("\n");
  }

  public function getIteratorInitSintax(){
    $sintax = array(
      '$context[\'_parent\'] = (array) $context;',
      sprintf('$context[\'_seq\'] = twig_ensure_traversable($this->getContext($context, "%s"));', $this->getIteratorValue()),
      '$context[\'_iterated\'] = false;',
    );

    if($this->hasLoop()){
      $loop = $this->replaceIndexVar(array('$context[\'%INDEX_VAR%\'] = array(',
        '  \'parent\' => $context[\'_parent\'],',
        '  \'index0\' => 0,',
        '  \'index\'  => 1,',
        '  \'renderedIndex\'  => 0,',
        '  \'first\'  => true,',
      ');',
      'if (is_array($context[\'_seq\']) || (is_object($context[\'_seq\']) && $context[\'_seq\'] instanceof Countable)) {',
      '  $length = count($context[\'_seq\']);',
      '  $context[\'%INDEX_VAR%\'][\'revindex0\'] = $length - 1;',
      '  $context[\'%INDEX_VAR%\'][\'revindex\'] = $length;',
      '  $context[\'%INDEX_VAR%\'][\'length\'] = $length;',
      '  $context[\'%INDEX_VAR%\'][\'last\'] = 1 === $length;',
      '}',));
      $sintax = array_merge($sintax, $loop);
    }

    $sintax[] = sprintf('foreach ($context[\'_seq\'] as $context["_key"] => $context["%s"]) {', $this->getIteratorVarName());
    $sintax[] = str_replace("%ITERATOR_VARNAME%",$this->getIteratorVarName(),'if (isset($context["%ITERATOR_VARNAME%"])) { $_%ITERATOR_VARNAME%_ = $context["%ITERATOR_VARNAME%"]; } else { $_%ITERATOR_VARNAME%_ = null; }');
    return $sintax;
  }

  public function getIteratorEndSintax($validateEmpty = false){
    $sintax = array(
      '    $context[\'_iterated\'] = true;',
    );

    if($this->hasLoop()){
      $loop = $this->replaceIndexVar(array('    ++$context[\'%INDEX_VAR%\'][\'index0\'];',
          '    ++$context[\'%INDEX_VAR%\'][\'index\'];',
          '    $context[\'%INDEX_VAR%\'][\'first\'] = false;',
          '    if (isset($context[\'%INDEX_VAR%\'][\'length\'])) {',
              '    --$context[\'%INDEX_VAR%\'][\'revindex0\'];',
              '    --$context[\'%INDEX_VAR%\'][\'revindex\'];',
              '    $context[\'%INDEX_VAR%\'][\'last\'] = 0 === $context[\'%INDEX_VAR%\'][\'revindex0\'];',
          '    }'));
      $sintax = array_merge($sintax, $loop);
    }

    $sintax[] = '}';

    if($validateEmpty){
      $sintax = array_merge($sintax,array(
          'if (!$context[\'_iterated\'] || !isset($context[\'_hasContent\'])) {',
          sprintf('  echo "%s";', $this->getEmptyMessage()),
          '}',
      ));
    }

    $sintax = array_merge($sintax,array(
        '$_parent = $context[\'_parent\'];',
        $this->replaceIndexVar('unset($context[\'_seq\'], $context[\'_hasContent\'], $context[\'_iterated\'], $context[\'_key\'], $context[\'user\'], $context[\'_parent\'], $context[\'%INDEX_VAR%\']);'),
        '$context = array_merge($_parent, array_intersect_key($context, $_parent));',
    ));
    return $sintax;
  }

  /**
   *
   * @return type
   */
  public function getWidgetName(){
    return 'widget';
  }

  public function getSuffixId(){
    return false;
  }

  public function getHTMLAttrs($args){
    return HTMLUtil::getHTMLAttrs(func_get_args());
  }

  public function getPluginName() {
    return 'plugin';
  }

}


<?php namespace Ordercloud\Support\Reflection;

use ErrorException;
use Ordercloud\Support\Reflection\Exceptions\ArgumentNotProvidedException;
use Ordercloud\Support\Reflection\Exceptions\EntityParseException;
use Ordercloud\Support\Reflection\Exceptions\EntityReflectionException;
use Ordercloud\Support\Reflection\Exceptions\NullRequiredArgumentException;
use ReflectionClass;
use ReflectionParameter;

class EntityReflector extends ReflectionClass
{
    /** @var array */
    private $arguments;

    /**
     * @param string $className
     * @param array  $arguments
     */
    public function __construct($className, array $arguments)
    {
        parent::__construct($className);
        $this->arguments = $arguments;
    }

    /**
     * @param string $className
     * @param array  $arguments
     *
     * @return array
     *
     * @throws EntityParseException
     */
    public static function parseAll($className, $arguments)
    {
        $results = [];

        if (!is_array($arguments)) {
            throw new EntityParseException($className, $arguments);
        }

        foreach ($arguments as $objectArguments) {
            $results[] = static::parse($className, $objectArguments);
        }

        return $results;
    }

    /**
     * @param string $className
     * @param array  $arguments
     *
     * @return mixed
     *
     * @throws EntityParseException
     */
    public static function parse($className, $arguments)
    {
        try {
            $reflector = new static($className, $arguments);
            $reflection = $reflector->reflect();
        }
        catch (EntityReflectionException $e) {
            throw new EntityParseException($className, $arguments, $e);
        }
        catch (ErrorException $e) {
            throw new EntityParseException($className, $arguments);
        }

        return $reflection;
    }

    /**
     * @param $url
     *
     * @return int
     *
     * @throws EntityReflectionException
     */
    public static function parseResourceIDFromURL($url)
    {
        if (is_null($url)) {
            throw new EntityReflectionException("Resource ID can't be parsed, null url");
        }

        $resourceLocationParts = explode('/', $url);

        if ( ! is_array($resourceLocationParts)) {
            throw new EntityReflectionException("Resource ID not found in request, location: {$url}");
        }

        $id = intval(end($resourceLocationParts));

        if ($id === 0) {
            throw new EntityReflectionException("Invalid resource ID found in request, location: {$url}");
        }

        return $id;
    }

    /**
     * @return object
     */
    public function reflect()
    {
        if (is_null($this->arguments)) {
            return null;
        }

        $parameters = $this->getConstructor()->getParameters();

        $preparedArguments = $this->prepareArguments($parameters);

        return $this->newInstanceArgs($preparedArguments);
    }

    /**
     * @param array|ReflectionParameter[] $parameters
     *
     * @return array
     */
    private function prepareArguments(array $parameters)
    {
        $preparedArguments = [];

        foreach ($parameters as $parameter) {
            $preparedArguments[] = $this->prepareArgument($parameter);
        }

        return $preparedArguments;
    }

    /**
     * @param ReflectionParameter $parameter
     *
     * @return mixed
     *
     * @throws \Ordercloud\Support\Reflection\Exceptions\ArgumentNotProvidedException
     * @throws NullRequiredArgumentException
     */
    private function prepareArgument(ReflectionParameter $parameter)
    {
        $parameterName = $parameter->getName();
        $argument = $this->getArgument($parameterName);

        if ($parameter->isArray()) {
            return $this->prepareArrayArgument($parameter, $argument);
        }

        if (is_null($argument) && ! $parameter->allowsNull()) {
            throw NullRequiredArgumentException::create($parameterName, $this->getName());
        }

        if ( ! is_null($argument) && $parameterClass = $parameter->getClass()) {
            return (new static($parameterClass->getName(), $argument))->reflect();
        }

        return $argument;
    }

    /**
     * @param string $parameterName
     *
     * @return array
     *
     * @throws \Ordercloud\Support\Reflection\Exceptions\ArgumentNotProvidedException
     */
    private function getArgument($parameterName)
    {
        $parameterAlias = $this->getParameterAlias($parameterName);

        if (array_key_exists($parameterAlias, $this->arguments)) {
            return $this->arguments[$parameterAlias];
        }

        throw new ArgumentNotProvidedException($this->getName(), $this->arguments, $parameterName, $parameterAlias);
    }

    /**
     * @param $parameterName
     *
     * @return mixed
     */
    private function getParameterAlias($parameterName)
    {
        if ( ! $this->hasProperty($parameterName)) {
            return $parameterName;
        }

        $property = $this->getProperty($parameterName);

        $docBlock = new DocBlock($property->getDocComment());

        if ( ! $docBlock->hasTag('reflectName')) {
            return $parameterName;
        }

        return $docBlock->getTag('reflectName');
    }

    public function prepareArrayArgument(ReflectionParameter $parameter, array $argument = null)
    {
        if (is_null($argument)) {
            return [];
        }

        if ($className = $this->getArrayClass($parameter->getName())) {
            $results = [];

            foreach ($argument as $objectArguments) {
                try {
                    $results[] = (new static($className, $objectArguments))->reflect();
                }
                catch (ErrorException $e) {
                    throw new EntityParseException($className, $objectArguments);
                }
            }

            return $results;
        }

        return $argument;
    }

    public function getArrayClass($parameterName)
    {
        $property = $this->getProperty($parameterName);

        $docBlock = new DocBlock($property->getDocComment());

        if ( ! $docBlock->hasTag('reflectType')) {
            return null;
        }

        return $docBlock->getTag('reflectType');
    }
}


<?php

/*
 * This file is part of the Snide monitoring package.
 *
 * (c) Pascal DENIS <pascal.denis.75@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Snide\Monitoring\Repository\Yaml;

use Snide\Monitoring\Model\Application;
use Snide\Monitoring\Repository\ApplicationRepositoryInterface;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Yaml\Yaml;

/**
 * Class ApplicationRepository
 *
 * @author Pascal DENIS <pascal.denis.75@gmail.com>
 */
class ApplicationRepository implements ApplicationRepositoryInterface
{
    /**
     * Save filename
     *
     * @var string
     */
    protected $filename;
    /**
     * Application class
     *
     * @var string
     */
    protected $class;

    /**
     * Constructor
     *
     * @param string $class Application class
     * @param string $filename save file
     */
    public function __construct($class, $filename)
    {
        $this->class = $class;
        $this->filename = $filename;

        $fs = new Filesystem();
        $fs->touch($this->filename);
    }

    /**
     * Retrieve all applications
     *
     * @return array
     */
    public function findAll()
    {
        $applications = array();

        foreach ($this->getRows() as $row) {
            $application = $this->createNew();
            $application->setId($row['id']);
            $application->setName($row['name']);
            $application->setUrl($row['url']);

            $applications[] = $application;
        }

        return $applications;
    }

    /**
     * Find application by ID
     *
     * @param $id App ID
     * @return Application|null
     */
    public function find($id)
    {
        foreach ($this->findAll() as $application) {
            if ($id == $application->getId()) {
                return $application;
            }
        }

        return null;
    }

    /**
     * Create an application
     *
     * @param Application $application
     * @return mixed
     */
    public function create(Application $application)
    {
        $rows = $this->getRows();
        $id = sizeof($rows) + 1;

        $rows[] = array(
            'id' => $id,
            'name' => $application->getName(),
            'url' => $application->getUrl()
        );

        file_put_contents($this->filename, Yaml::dump($rows));
    }

    /**
     * Delete an application
     *
     * @param Application $application
     * @return mixed
     */
    public function delete(Application $application)
    {
        $rows = array();

        foreach ($this->getRows() as $row) {
            if ($row['id'] == $application->getId()) {
                continue;
            }
            $rows[] = $row;
        }

        file_put_contents($this->filename, Yaml::dump($rows));
    }

    /**
     * Update an application
     *
     * @param Application $application
     * @return mixex
     */
    public function update(Application $application)
    {
        $rows = array();

        foreach ($this->getRows() as $row) {
            if ($row['id'] == $application->getId()) {
                $row = array(
                    'id'   => $application->getId(),
                    'name' => $application->getName(),
                    'url'  => $application->getUrl()
                );
            }
            $rows[] = $row;
        }

        file_put_contents($this->filename, Yaml::dump($rows));
    }

    /**
     * Get List of applications rows
     * @return array
     */
    private function getRows()
    {
        return Yaml::parse($this->filename) ? : array();
    }

    /**
     * Create new instance
     *
     * @return Application
     */
    public function createNew()
    {
        $class = $this->class;

        return new $class;
    }
}


<?php

/**
 * This file is part of Business-hours.
 * Copyright (c) 2015 - 2016 original code: Florian Voutzinos <florian@voutzinos.com
 * Copyright (c) 2015 - 2017 additions and changes: Speicher 210 GmbH
 * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code.
 */

declare(strict_types = 1);

namespace Speicher210\BusinessHours;

use Speicher210\BusinessHours\Day\DayInterface;
use Speicher210\BusinessHours\Day\Time\TimeBuilder;
use Speicher210\BusinessHours\Day\Time\TimeIntervalInterface;

/**
 * Default implementation of BusinessHoursInterface.
 */
class BusinessHours implements BusinessHoursInterface
{
    /**
     * The days.
     *
     * @var DayInterface[]
     */
    protected $days;

    /**
     * The time zone.
     *
     * @var \DateTimeZone
     */
    protected $timezone;

    /**
     * @param DayInterface[] $days
     * @param \DateTimeZone|null $timezone
     */
    public function __construct(array $days, \DateTimeZone $timezone = null)
    {
        $this->setDays($days);
        $this->timezone = $timezone ?: new \DateTimeZone(\date_default_timezone_get());
    }

    /**
     * {@inheritdoc}
     */
    public function getTimezone(): \DateTimeZone
    {
        return $this->timezone;
    }

    /**
     * Get the days.
     *
     * @return DayInterface[]
     */
    public function getDays(): array
    {
        return \array_values($this->days);
    }

    /**
     * Add a set of days.
     *
     * @param DayInterface[] $days The days.
     * @throws \InvalidArgumentException If no days are passed.
     */
    protected function setDays(array $days): void
    {
        if (empty($days)) {
            throw new \InvalidArgumentException('At least one day must be added.');
        }

        $this->days = [];

        foreach ($days as $day) {
            $this->addDay($day);
        }
    }

    /**
     * {@inheritdoc}
     */
    public function within(\DateTime $date): bool
    {
        $tmpDate = clone $date;
        $tmpDate->setTimezone($this->timezone);

        if (null !== $day = $this->getDay((int)$tmpDate->format('N'))) {
            return $day->isWithinOpeningHours(TimeBuilder::fromDate($tmpDate));
        }

        return false;
    }

    /**
     * {@inheritdoc}
     */
    public function getNextChangeDateTime(\DateTime $date): \DateTime
    {
        $tmpDate = clone $date;
        $tmpDate->setTimezone($this->timezone);
        $dateInterval = $this->getNextClosestInterval($tmpDate);

        if ($this->within($date)) {
            return ($date == $dateInterval->getStart()) ? $dateInterval->getStart() : $dateInterval->getEnd();
        }

        return $dateInterval->getStart();
    }

    /**
     * {@inheritdoc}
     */
    public function getPreviousChangeDateTime(\DateTime $date): \DateTime
    {
        $tmpDate = clone $date;
        $tmpDate->setTimezone($this->timezone);
        $dateInterval = $this->getPreviousClosestInterval($tmpDate);

        if ($this->within($date)) {
            return ($date == $dateInterval->getEnd()) ? $dateInterval->getEnd() : $dateInterval->getStart();
        }

        return $dateInterval->getEnd();
    }

    /**
     * {@inheritdoc}
     */
    public function jsonSerialize()
    {
        return [
            'days' => $this->days,
            'timezone' => $this->timezone->getName(),
        ];
    }

    /**
     * Get the closest business hours date interval before the given date.
     *
     * @param \DateTime $date The given date.
     * @return DateTimeInterval
     */
    private function getClosestDateIntervalBefore(\DateTime $date): DateTimeInterval
    {
        $tmpDate = clone $date;
        $dayOfWeek = (int)$tmpDate->format('N');
        $time = TimeBuilder::fromDate($tmpDate);

        if (null !== $day = $this->getDay($dayOfWeek)) {
            if (null !== $closestTime = $day->getClosestPreviousOpeningHoursInterval($time)) {
                return $this->buildDateTimeInterval($tmpDate, $closestTime);
            }
        }

        $tmpDate = $this->getDateBefore($tmpDate);

        $closestDay = $this->getClosestDayBefore((int)$tmpDate->format('N'));

        $closingTime = $closestDay->getClosingTime();
        $closestTime = $closestDay->getClosestPreviousOpeningHoursInterval($closingTime);

        return $this->buildDateTimeInterval($tmpDate, $closestTime);
    }

    /**
     * Get the closest business hours date interval after the given date.
     *
     * @param \DateTime $date The given date.
     * @return DateTimeInterval
     */
    private function getClosestDateIntervalAfter(\DateTime $date): DateTimeInterval
    {
        $tmpDate = clone $date;
        $dayOfWeek = (int)$tmpDate->format('N');
        $time = TimeBuilder::fromDate($tmpDate);

        if (null !== $day = $this->getDay($dayOfWeek)) {
            if (null !== $closestTime = $day->getClosestNextOpeningHoursInterval($time)) {
                return $this->buildDateTimeInterval($tmpDate, $closestTime);
            }
        }

        $tmpDate = $this->getDateAfter($tmpDate);

        $closestDay = $this->getClosestDayBefore((int)$tmpDate->format('N'));

        $openingTime = $closestDay->getOpeningTime();
        $closestTime = $closestDay->getClosestNextOpeningHoursInterval($openingTime);

        return $this->buildDateTimeInterval($tmpDate, $closestTime);
    }

    /**
     * Build a new date time interval for a date.
     *
     * @param \DateTime $date The date.
     * @param TimeIntervalInterface $timeInterval
     * @return DateTimeInterval
     */
    private function buildDateTimeInterval(\DateTime $date, TimeIntervalInterface $timeInterval): DateTimeInterval
    {
        $intervalStart = clone $date;
        $intervalEnd = clone $date;

        $intervalStart->setTime(
            $timeInterval->getStart()->getHours(),
            $timeInterval->getStart()->getMinutes(),
            $timeInterval->getStart()->getSeconds()
        );
        $intervalEnd->setTime(
            $timeInterval->getEnd()->getHours(),
            $timeInterval->getEnd()->getMinutes(),
            $timeInterval->getEnd()->getSeconds()
        );

        return new DateTimeInterval($intervalStart, $intervalEnd);
    }

    /**
     * Get the business hours date before the given date.
     *
     * @param \DateTime $date
     * @return \DateTime
     */
    private function getDateBefore(\DateTime $date): \DateTime
    {
        $tmpDate = clone $date;
        $tmpDate->modify('-1 day');

        $dayOfWeek = (int)$tmpDate->format('N');
        $closestDay = $this->getClosestDayBefore($dayOfWeek);
        if ($closestDay->getDayOfWeek() !== $dayOfWeek) {
            $tmpDate->modify(\sprintf('last %s', $closestDay->getDayOfWeekName()));
        }
        return $tmpDate;
    }

    /**
     * Get the business hours date after the given date.
     *
     * @param \DateTime $date
     * @return \DateTime
     */
    private function getDateAfter(\DateTime $date): \DateTime
    {
        $tmpDate = clone $date;
        $tmpDate->modify('+1 day');

        $dayOfWeek = (int)$tmpDate->format('N');
        $closestDay = $this->getClosestDayAfter($dayOfWeek);

        if ($closestDay->getDayOfWeek() !== $dayOfWeek) {
            $tmpDate->modify(\sprintf('next %s', $closestDay->getDayOfWeekName()));
        }

        return $tmpDate;
    }

    /**
     * Get the closest interval endpoint after the given date.
     *
     * @param \DateTime $date
     * @return DateTimeInterval
     */
    private function getPreviousClosestInterval(\DateTime $date): DateTimeInterval
    {
        $tmpDate = clone $date;
        $dayOfWeek = (int)$tmpDate->format('N');
        $time = TimeBuilder::fromDate($tmpDate);

        if (null !== $day = $this->getDay($dayOfWeek)) {
            if (null !== $closestTime = $day->getClosestPreviousOpeningHoursInterval($time)) {
                return $this->buildDateTimeInterval($tmpDate, $closestTime);
            }
        }

        return $this->getClosestDateIntervalBefore($date);
    }

    /**
     * Get the closest interval endpoint after the given date.
     *
     * @param \DateTime $date
     * @return DateTimeInterval
     */
    private function getNextClosestInterval(\DateTime $date): DateTimeInterval
    {
        $tmpDate = clone $date;
        $dayOfWeek = (int)$tmpDate->format('N');
        $time = TimeBuilder::fromDate($tmpDate);

        if (null !== $day = $this->getDay($dayOfWeek)) {
            if (null !== $closestTime = $day->getClosestNextOpeningHoursInterval($time)) {
                return $this->buildDateTimeInterval($tmpDate, $closestTime);
            }
        }

        return $this->getClosestDateIntervalAfter($date);
    }

    /**
     * Get the closest business hours day before a given day number (including it).
     *
     * @param integer $dayNumber
     * @return DayInterface|null
     */
    private function getClosestDayBefore(int $dayNumber)
    {
        if (null !== $day = $this->getDay($dayNumber)) {
            return $day;
        }

        return $this->getDayBefore($dayNumber);
    }

    /**
     * Get the closest business hours day after a given day number (including it).
     *
     * @param integer $dayNumber
     * @return DayInterface|null
     */
    private function getClosestDayAfter($dayNumber)
    {
        if (null !== $day = $this->getDay($dayNumber)) {
            return $day;
        }

        return $this->getDayAfter($dayNumber);
    }

    /**
     * Get the business hours day before the day number.
     *
     * @param integer $dayNumber
     * @return DayInterface|null
     */
    private function getDayBefore(int $dayNumber)
    {
        $tmpDayNumber = $dayNumber;

        for ($i = 0; $i < 6; $i++) {
            $tmpDayNumber = (DayInterface::WEEK_DAY_MONDAY === $tmpDayNumber) ? DayInterface::WEEK_DAY_SUNDAY : --$tmpDayNumber;

            if (null !== $day = $this->getDay($tmpDayNumber)) {
                return $day;
            }
        }

        return $this->getDay($dayNumber);
    }

    /**
     * Get the business hours day after the day number.
     *
     * @param integer $dayNumber
     * @return DayInterface|null
     */
    private function getDayAfter($dayNumber)
    {
        $tmpDayNumber = $dayNumber;

        for ($i = 0; $i < 6; $i++) {
            $tmpDayNumber = (DayInterface::WEEK_DAY_SUNDAY === $tmpDayNumber) ? DayInterface::WEEK_DAY_MONDAY : ++$tmpDayNumber;

            if (null !== $day = $this->getDay($tmpDayNumber)) {
                return $day;
            }
        }

        return $this->getDay($dayNumber);
    }

    /**
     * Get the day corresponding to the day of the week.
     *
     * @param integer $dayOfWeek The day of the week.
     * @return DayInterface|null
     */
    private function getDay($dayOfWeek): ?DayInterface
    {
        return $this->days[$dayOfWeek] ?? null;
    }

    /**
     * Add a day.
     *
     * @param DayInterface $day The day.
     */
    private function addDay(DayInterface $day): void
    {
        $this->days[$day->getDayOfWeek()] = $day;
    }

    public function __clone()
    {
        $days = [];
        foreach ($this->days as $key => $day) {
            $days[$key] = clone $day;
        }

        $this->days = $days;
    }
}


<?php

namespace Think;

/**
 * 控制器基类
 * Class Controller
 * @package Think
 */
abstract class Controller
{

    /**
     * 视图实例对象
     * @var View $view

     */
    protected $view = null;

    /**
     * 取得模板对象实例

     */
    public function __construct()
    {
        //实例化视图类
        $this->view = new View;
        //控制器初始化
        if (method_exists($this, '__init')) {
            $this->__init();
        }
    }

    /**
     * 控制器初始化附加方法
     */
    protected function __init()
    {
    }

    /**
     * 模板显示 调用内置的模板引擎显示方法，

     *
     * @param string $templateFile 指定要调用的模板文件
     *                             默认为空 由系统自动定位模板文件
     * @param string $charset 输出编码
     * @param string $contentType 输出类型
     * @param string $content 输出内容
     * @param string $prefix 模板缓存前缀
     *
     * @return void
     */
    protected function display($templateFile = '', $charset = '', $contentType = '', $content = '', $prefix = '')
    {
        $this->view->display($templateFile, $charset, $contentType, $content, $prefix);
    }

    /**
     * 输出内容文本可以包括Html 并支持内容解析

     *
     * @param string $content 输出内容
     * @param string $charset 模板输出字符集
     * @param string $contentType 输出类型
     * @param string $prefix 模板缓存前缀
     *
     * @return void
     */
    protected function show($content, $charset = '', $contentType = '', $prefix = '')
    {
        $this->view->display('', $charset, $contentType, $content, $prefix);
    }

    /**
     *  获取输出页面内容
     * 调用内置的模板引擎fetch方法，

     *
     * @param string $templateFile 指定要调用的模板文件
     *                             默认为空 由系统自动定位模板文件
     * @param string $content 模板输出内容
     * @param string $prefix 模板缓存前缀
     *
     * @return string
     */
    protected function fetch($templateFile = '', $content = '', $prefix = '')
    {
        return $this->view->fetch($templateFile, $content, $prefix);
    }

    /**
     *  创建静态页面
     *
     * @param string $htmlFile 生成的静态文件名称
     * @param string $htmlPath 生成的静态文件路径
     * @param string $templateFile 指定要调用的模板文件
     *                             默认为空 由系统自动定位模板文件
     *
     * @return string
     */
    protected function buildHtml($htmlFile = '', $htmlPath = '', $templateFile = '')
    {
        $content = $this->fetch($templateFile);
        $htmlPath = !empty($htmlPath) ? $htmlPath : HTML_PATH;
        $htmlFile = $htmlPath.$htmlFile.C('HTML_FILE_SUFFIX');
        Storage::put($htmlFile, $content);

        return $content;
    }

    /**
     * 模板主题设置

     *
     * @param string $theme 模版主题
     *
     * @return $this
     */
    protected function theme($theme)
    {
        $this->view->theme($theme);

        return $this;
    }

    /**
     * 模板变量赋值

     *
     * @param mixed $name 要显示的模板变量
     * @param mixed $value 变量的值
     *
     * @return $this
     */
    protected function assign($name, $value = '')
    {
        $this->view->assign($name, $value);

        return $this;
    }

    /**
     * @param $name
     * @param $value
     */
    public function __set($name, $value)
    {
        $this->assign($name, $value);
    }

    /**
     * 取得模板显示变量的值

     *
     * @param string $name 模板显示变量
     *
     * @return mixed
     */
    public function get($name = '')
    {
        return $this->view->get($name);
    }

    /**
     * @param $name
     *
     * @return mixed
     */
    public function __get($name)
    {
        return $this->get($name);
    }

    /**
     * 检测模板变量的值

     *
     * @param string $name 名称
     *
     * @return bool
     */
    public function __isset($name)
    {
        return $this->get($name);
    }

    /**
     * 魔术方法 有不存在的操作的时候执行
     *
     * @param string $method 方法名
     * @param array $args 参数
     * @return void
     * @throws BaseException
     */
    public function __call($method, $args)
    {
        if (0 === strcasecmp($method, ACTION_NAME)) {
            if (method_exists($this, '_empty')) {
                // 如果定义了_empty操作 则调用
                $this->_empty($method, $args);
            } else {
                throw new BaseException(L('_ERROR_ACTION_').':'.ACTION_NAME);
            }
        } else {
            throw new BaseException(__CLASS__.':'.$method.L('_METHOD_NOT_EXIST_'));

            return;
        }
    }

    /**
     * 操作错误跳转的快捷方法
     *
     * @param string $message 错误信息
     * @param string $jumpUrl 页面跳转地址
     * @param mixed $ajax 是否为Ajax方式 当数字时指定跳转时间
     *
     * @return void
     */
    protected function error($message = '', $jumpUrl = '', $ajax = false)
    {
        $this->dispatchJump($message, 0, $jumpUrl, $ajax);
    }

    /**
     * 操作成功跳转的快捷方法
     *
     * @param string $message 提示信息
     * @param string $jumpUrl 页面跳转地址
     * @param mixed $ajax 是否为Ajax方式 当数字时指定跳转时间
     *
     * @return void
     */
    protected function success($message = '', $jumpUrl = '', $ajax = false)
    {
        $this->dispatchJump($message, 1, $jumpUrl, $ajax);
    }

    /**
     * Ajax方式返回数据到客户端
     *
     * @param mixed $data 要返回的数据
     * @param String $type AJAX返回数据格式
     * @param int $json_option 传递给json_encode的option参数
     *
     * @return void
     */
    protected function ajaxReturn($data, $type = '', $json_option = 0)
    {
        //禁止trace以免影响输出
        C('SHOW_PAGE_TRACE',false);
        if (empty($type)) {
            $type = C('DEFAULT_AJAX_RETURN');
        }
        switch (strtoupper($type)) {
            case 'JSON' :
                // 返回JSON数据格式到客户端 包含状态信息
                header('Content-Type:application/json; charset=utf-8');
                echo json_encode($data, $json_option);
                break;
            case 'XML'  :
                // 返回xml格式数据
                header('Content-Type:text/xml; charset=utf-8');
                echo xml_encode($data);
                break;
            case 'JSONP':
                // 返回JSON数据格式到客户端 包含状态信息
                header('Content-Type:text/javascript; charset=utf-8');
                $handler = isset($_GET[C('VAR_JSONP_HANDLER')]) ? $_GET[C('VAR_JSONP_HANDLER')] : C(
                    'DEFAULT_JSONP_HANDLER'
                );
                echo $handler.'('.json_encode($data, $json_option).');';
                break;
            case 'EVAL' :
                // 返回可执行的js脚本
                header('Content-Type:text/javascript; charset=utf-8');
                echo $data;
                break;
            default     :
                break;
            // 用于扩展其他返回格式数据
//                    Hook::listen('ajax_return', $data);
        }
    }

    /**
     * Action跳转(URL重定向） 支持指定模块和延时跳转
     *
     * @param string $url 跳转的URL表达式
     * @param array $params 其它URL参数
     * @param int $delay 延时跳转的时间 单位为秒
     * @param string $msg 跳转提示信息
     *
     * @return void
     */
    protected function redirect($url, $params = [], $delay = 0, $msg = '')
    {
        $url = U($url, $params);
        redirect($url, $delay, $msg);
    }

    /**
     * 默认跳转操作 支持错误导向和正确跳转
     * 调用模板显示 默认为public目录下面的success页面
     * 提示页面为可配置 支持模板标签
     *
     * @param string $message 提示信息
     * @param bool|int $status 状态
     * @param string $jumpUrl 页面跳转地址
     * @param mixed $ajax 是否为Ajax方式 当数字时指定跳转时间
     *
     * @return void

     */
    private function dispatchJump($message, $status = 1, $jumpUrl = '', $ajax = false)
    {
        // AJAX提交
        if (true === $ajax || IS_AJAX) {
            $data = is_array($ajax) ? $ajax : [];
            $data['info'] = $message;
            $data['status'] = $status;
            $data['url'] = $jumpUrl;
            $this->ajaxReturn($data);
            return;
        }
        if (is_int($ajax)) {
            $this->assign('waitSecond', $ajax);
        }
        if (!empty($jumpUrl)) {
            $this->assign('jumpUrl', $jumpUrl);
        }
        // 提示标题
        $this->assign('msgTitle', $status ? L('_OPERATION_SUCCESS_') : L('_OPERATION_FAIL_'));
        //如果设置了关闭窗口，则提示完毕后自动关闭窗口
        if ($this->get('closeWin')) {
            $this->assign('jumpUrl', 'javascript:window.close();');
        }
        // 状态
        $this->assign('status', $status);
        //保证输出不受静态缓存影响
        C('HTML_CACHE_ON', false);
        //发送成功信息
        if ($status) {
            // 提示信息
            $this->assign('message', $message);
            // 成功操作后默认停留1秒
            if (!isset($this->waitSecond)) {
                $this->assign('waitSecond', '1');
            }
            // 默认操作成功自动返回操作前页面
            if (!isset($this->jumpUrl)) {
                $this->assign('jumpUrl', $_SERVER["HTTP_REFERER"]);
            }
            $this->display(C('TMPL_ACTION_SUCCESS'));
        } else {
            // 提示信息
            $this->assign('error', $message);
            //发生错误时候默认停留3秒
            if (!isset($this->waitSecond)) {
                $this->assign('waitSecond', '3');
            }
            // 默认发生错误的话自动返回上页
            if (!isset($this->jumpUrl)) {
                $this->assign('jumpUrl', 'javascript:history.back(-1);');
            }
            $this->display(C('TMPL_ACTION_ERROR'));
            // 中止执行  避免出错后继续执行
            return;
        }
    }

    /**
     * 析构方法
     */
    public function __destruct()
    {
    }

    public function __debugInfo()
    {
        return [
            'ControllerName' => static::class,
            'view'           => $this->view,
        ];
    }

    public function __toString()
    {
        return static::class;
    }

}


<?php
/**
 * Base class for all installation roles.
 *
 * PHP versions 4 and 5
 *
 * @category   pear
 * @package    PEAR
 * @author     Greg Beaver <cellog@php.net>
 * @copyright  1997-2006 The PHP Group
 * @license    http://opensource.org/licenses/bsd-license.php New BSD License
 * @version    CVS: $Id: Common.php 313023 2011-07-06 19:17:11Z dufuz $
 * @link       http://pear.php.net/package/PEAR
 * @since      File available since Release 1.4.0a1
 */
/**
 * Base class for all installation roles.
 *
 * This class allows extensibility of file roles.  Packages with complex
 * customization can now provide custom file roles along with the possibility of
 * adding configuration values to match.
 * @category   pear
 * @package    PEAR
 * @author     Greg Beaver <cellog@php.net>
 * @copyright  1997-2006 The PHP Group
 * @license    http://opensource.org/licenses/bsd-license.php New BSD License
 * @version    Release: 1.9.4
 * @link       http://pear.php.net/package/PEAR
 * @since      Class available since Release 1.4.0a1
 */
class PEAR_Installer_Role_Common
{
    /**
     * @var PEAR_Config
     * @access protected
     */
    var $config;

    /**
     * @param PEAR_Config
     */
    function PEAR_Installer_Role_Common(&$config)
    {
        $this->config = $config;
    }

    /**
     * Retrieve configuration information about a file role from its XML info
     *
     * @param string $role Role Classname, as in "PEAR_Installer_Role_Data"
     * @return array
     */
    function getInfo($role)
    {
        if (empty($GLOBALS['_PEAR_INSTALLER_ROLES'][$role])) {
            return PEAR::raiseError('Unknown Role class: "' . $role . '"');
        }
        return $GLOBALS['_PEAR_INSTALLER_ROLES'][$role];
    }

    /**
     * This is called for each file to set up the directories and files
     * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
     * @param array attributes from the <file> tag
     * @param string file name
     * @return array an array consisting of:
     *
     *    1 the original, pre-baseinstalldir installation directory
     *    2 the final installation directory
     *    3 the full path to the final location of the file
     *    4 the location of the pre-installation file
     */
    function processInstallation($pkg, $atts, $file, $tmp_path, $layer = null)
    {
        $roleInfo = PEAR_Installer_Role_Common::getInfo('PEAR_Installer_Role_' .
            ucfirst(str_replace('pear_installer_role_', '', strtolower(get_class($this)))));
        if (PEAR::isError($roleInfo)) {
            return $roleInfo;
        }
        if (!$roleInfo['locationconfig']) {
            return false;
        }
        if ($roleInfo['honorsbaseinstall']) {
            $dest_dir = $save_destdir = $this->config->get($roleInfo['locationconfig'], $layer,
                $pkg->getChannel());
            if (!empty($atts['baseinstalldir'])) {
                $dest_dir .= DIRECTORY_SEPARATOR . $atts['baseinstalldir'];
            }
        } elseif ($roleInfo['unusualbaseinstall']) {
            $dest_dir = $save_destdir = $this->config->get($roleInfo['locationconfig'],
                    $layer, $pkg->getChannel()) . DIRECTORY_SEPARATOR . $pkg->getPackage();
            if (!empty($atts['baseinstalldir'])) {
                $dest_dir .= DIRECTORY_SEPARATOR . $atts['baseinstalldir'];
            }
        } else {
            $dest_dir = $save_destdir = $this->config->get($roleInfo['locationconfig'],
                    $layer, $pkg->getChannel()) . DIRECTORY_SEPARATOR . $pkg->getPackage();
        }
        if (dirname($file) != '.' && empty($atts['install-as'])) {
            $dest_dir .= DIRECTORY_SEPARATOR . dirname($file);
        }
        if (empty($atts['install-as'])) {
            $dest_file = $dest_dir . DIRECTORY_SEPARATOR . basename($file);
        } else {
            $dest_file = $dest_dir . DIRECTORY_SEPARATOR . $atts['install-as'];
        }
        $orig_file = $tmp_path . DIRECTORY_SEPARATOR . $file;

        // Clean up the DIRECTORY_SEPARATOR mess
        $ds2 = DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR;

        list($dest_dir, $dest_file, $orig_file) = preg_replace(array('!\\\\+!', '!/!', "!$ds2+!"),
                                                    array(DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR,
                                                          DIRECTORY_SEPARATOR),
                                                    array($dest_dir, $dest_file, $orig_file));
        return array($save_destdir, $dest_dir, $dest_file, $orig_file);
    }

    /**
     * Get the name of the configuration variable that specifies the location of this file
     * @return string|false
     */
    function getLocationConfig()
    {
        $roleInfo = PEAR_Installer_Role_Common::getInfo('PEAR_Installer_Role_' .
            ucfirst(str_replace('pear_installer_role_', '', strtolower(get_class($this)))));
        if (PEAR::isError($roleInfo)) {
            return $roleInfo;
        }
        return $roleInfo['locationconfig'];
    }

    /**
     * Do any unusual setup here
     * @param PEAR_Installer
     * @param PEAR_PackageFile_v2
     * @param array file attributes
     * @param string file name
     */
    function setup(&$installer, $pkg, $atts, $file)
    {
    }

    function isExecutable()
    {
        $roleInfo = PEAR_Installer_Role_Common::getInfo('PEAR_Installer_Role_' .
            ucfirst(str_replace('pear_installer_role_', '', strtolower(get_class($this)))));
        if (PEAR::isError($roleInfo)) {
            return $roleInfo;
        }
        return $roleInfo['executable'];
    }

    function isInstallable()
    {
        $roleInfo = PEAR_Installer_Role_Common::getInfo('PEAR_Installer_Role_' .
            ucfirst(str_replace('pear_installer_role_', '', strtolower(get_class($this)))));
        if (PEAR::isError($roleInfo)) {
            return $roleInfo;
        }
        return $roleInfo['installable'];
    }

    function isExtension()
    {
        $roleInfo = PEAR_Installer_Role_Common::getInfo('PEAR_Installer_Role_' .
            ucfirst(str_replace('pear_installer_role_', '', strtolower(get_class($this)))));
        if (PEAR::isError($roleInfo)) {
            return $roleInfo;
        }
        return $roleInfo['phpextension'];
    }
}
?>


<?php

namespace Reaction\Db;

use Reaction;
use Reaction\Base\BaseObject;
use Reaction\Exceptions\Exception;
use Reaction\Exceptions\InvalidConfigException;
use Reaction\Promise\ExtendedPromiseInterface;
use Reaction\Promise\LazyPromiseInterface;

/**
 * Transaction represents a DB transaction.
 *
 * It is usually created by calling [[Connection::beginTransaction()]].
 *
 * The following code is a typical example of using transactions (note that some
 * DBMS may not support transactions):
 *
 * ```php
 * $transaction = $connection->beginTransaction();
 * try {
 *     $connection->createCommand($sql1)->execute();
 *     $connection->createCommand($sql2)->execute();
 *     //.... other SQL executions
 *     $transaction->commit();
 * } catch (\Exception $e) {
 *     $transaction->rollBack();
 *     throw $e;
 * } catch (\Throwable $e) {
 *     $transaction->rollBack();
 *     throw $e;
 * }
 * ```
 *
 * > Note: in the above code we have two catch-blocks for compatibility
 * > with PHP 5.x and PHP 7.x. `\Exception` implements the [`\Throwable` interface](http://php.net/manual/en/class.throwable.php)
 * > since PHP 7.0, so you can skip the part with `\Exception` if your app uses only PHP 7.0 and higher.
 *
 * @property bool $isActive Whether this transaction is active. Only an active transaction can [[commit()]] or
 * [[rollBack()]]. This property is read-only.
 * @property string $isolationLevel The transaction isolation level to use for this transaction. This can be
 * one of [[READ_UNCOMMITTED]], [[READ_COMMITTED]], [[REPEATABLE_READ]] and [[SERIALIZABLE]] but also a string
 * containing DBMS specific syntax to be used after `SET TRANSACTION ISOLATION LEVEL`. This property is
 * write-only.
 * @property int $level The current nesting level of the transaction. This property is read-only.
 */
class Transaction extends BaseObject implements TransactionInterface, DbConnectionGetterInterface
{
    /**
     * @var DatabaseInterface the database connection that this transaction is associated with.
     */
    public $db;

    /**
     * @var ConnectionInterface Dedicated DB connection for transaction
     */
    protected $connection;

    /**
     * @var int the nesting level of the transaction. 0 means the outermost level.
     */
    private $_level = 0;

    /**
     * Returns a value indicating whether this transaction is active.
     * @return bool whether this transaction is active. Only an active transaction
     * can [[commit()]] or [[rollBack()]].
     */
    public function getIsActive()
    {
        return $this->_level > 0 && $this->db;
    }

    /**
     * Begins a transaction.
     * @param string|null $isolationLevel The [isolation level][] to use for this transaction.
     * This can be one of [[READ_UNCOMMITTED]], [[READ_COMMITTED]], [[REPEATABLE_READ]] and [[SERIALIZABLE]] but
     * also a string containing DBMS specific syntax to be used after `SET TRANSACTION ISOLATION LEVEL`.
     * If not specified (`null`) the isolation level will not be set explicitly and the DBMS default will be used.
     *
     * > Note: This setting does not work for PostgreSQL, where setting the isolation level before the transaction
     * has no effect. You have to call [[setIsolationLevel()]] in this case after the transaction has started.
     *
     * > Note: Some DBMS allow setting of the isolation level only for the whole connection so subsequent transactions
     * may get the same isolation level even if you did not specify any. When using this feature
     * you may need to set the isolation level for all transactions explicitly to avoid conflicting settings.
     * At the time of this writing affected DBMS are MSSQL and SQLite.
     *
     * [isolation level]: http://en.wikipedia.org/wiki/Isolation_%28database_systems%29#Isolation_levels
     * @return ExtendedPromiseInterface|LazyPromiseInterface
     */
    public function begin($isolationLevel = null)
    {
        if ($this->db === null) {
            $exception = new InvalidConfigException('Transaction::db must be set.');
            return Reaction\Promise\reject($exception);
        }

        $connection = $this->getConnection();

        if ($this->_level === 0) {
            $isolationLevel = isset($isolationLevel) ? $isolationLevel : self::READ_COMMITTED;
            Reaction::debug('Begin transaction' . ($isolationLevel ? ' with isolation level ' . $isolationLevel : ''));
            $this->_level = 1;
            $promise = $connection->beginTransaction($isolationLevel);
        } else {
            $schema = $this->db->getSchema();
            if ($schema->supportsSavepoint()) {
                Reaction::debug('Set savepoint ' . $this->_level);
                $promise = $connection->createSavepoint('LEVEL' . $this->_level);
            } else {
                Reaction::info('Transaction not started: nested transaction not supported');
            }
            $this->_level++;
        }

        if (!isset($promise)) {
            return Reaction\Promise\rejectLazy(null);
        }

        $callback = function() { return $this->getConnection(); };

        return $promise instanceof LazyPromiseInterface ? $promise->thenLazy($callback) : $promise->then($callback);
    }

    /**
     * Commits a transaction.
     * @throws Exception if the transaction is not active
     * @return ExtendedPromiseInterface|LazyPromiseInterface
     */
    public function commit()
    {
        if (!$this->getIsActive()) {
            throw new Exception('Failed to commit transaction: transaction was inactive.');
        }

        $connection = $this->getConnection();
        $this->_level--;
        if ($this->_level === 0) {
            Reaction::debug('Commit transaction');
            return $connection->commitTransaction()
                ->thenLazy(function() { $this->closeConnection(); });
        }

        $schema = $this->db->getSchema();
        if ($schema->supportsSavepoint()) {
            Reaction::debug('Release savepoint ' . $this->_level);
            return $connection->releaseSavepoint('LEVEL' . $this->_level);
        } else {
            Reaction::info('Transaction not committed: nested transaction not supported');
        }
        return Reaction\Promise\rejectLazy(null);
    }

    /**
     * Rolls back a transaction.
     * @param bool $final
     * @return ExtendedPromiseInterface
     */
    public function rollBack($final = false)
    {
        if (!$this->getIsActive()) {
            // do nothing if transaction is not active: this could be the transaction is committed
            // but the event handler to "commitTransaction" throw an exception
            return Reaction\Promise\reject(new Exception("There is no active transactions"));
        }

        //Roll back all transaction with save points
        if ($final && $this->_level > 1) {
            $promises = [];
            while ($this->_level > 0) {
                $promises[] = $this->rollBack(false);
            }
            return !empty($promises)
                ? Reaction\Promise\allInOrder($promises)->then(function() { return true; })
                : Reaction\Promise\resolve(true);
        }

        $connection = $this->getConnection();
        $this->_level--;
        if ($this->_level === 0) {
            Reaction::debug('Roll back transaction');
            return $connection->rollBackTransaction()
                ->thenLazy(function() { $this->closeConnection(); });
        }

        $schema = $this->db->getSchema();
        if ($schema->supportsSavepoint()) {
            Reaction::debug('Roll back to savepoint ' . $this->_level);
            return $connection->rollBackSavepoint('LEVEL' . $this->_level);
        } else {
            Reaction::info('Transaction not rolled back: nested transaction not supported');
            // throw an exception to fail the outer transaction
            return Reaction\Promise\reject(new Exception('Roll back failed: nested transaction not supported.'));
        }
    }

    /**
     * Sets the transaction isolation level for this transaction.
     *
     * This method can be used to set the isolation level while the transaction is already active.
     * However this is not supported by all DBMS so you might rather specify the isolation level directly
     * when calling [[begin()]].
     * @param string $level The transaction isolation level to use for this transaction.
     * This can be one of [[READ_UNCOMMITTED]], [[READ_COMMITTED]], [[REPEATABLE_READ]] and [[SERIALIZABLE]] but
     * also a string containing DBMS specific syntax to be used after `SET TRANSACTION ISOLATION LEVEL`.
     * @return ExtendedPromiseInterface|LazyPromiseInterface
     * @throws Exception if the transaction is not active
     * @see http://en.wikipedia.org/wiki/Isolation_%28database_systems%29#Isolation_levels
     */
    public function setIsolationLevel($level)
    {
        if (!$this->getIsActive()) {
            throw new Exception('Failed to set isolation level: transaction was inactive.');
        }
        Reaction::debug('Setting transaction isolation level to ' . $level);
        return $this->getConnection()->setTransactionIsolationLevel($level);
    }

    /**
     * @return int The current nesting level of the transaction.
     */
    public function getLevel()
    {
        return $this->_level;
    }

    /**
     * Get DB connection
     * @return ConnectionInterface
     */
    public function getConnection() {
        if (!isset($this->connection)) {
            $this->connection = $this->db->getDedicatedConnection();
        }
        return $this->connection;
    }

    /**
     * Close connection at transaction end
     */
    protected function closeConnection()
    {
        $this->connection->close();
        $this->connection = null;
    }

    /**
     * Get Database if applicable
     * @see DbConnectionGetterInterface
     * @return DatabaseInterface|null
     */
    public function getDb()
    {
        return $this->db;
    }
}


<?php

namespace Soluble\Media\Converter;

use Soluble\Media\BoxDimension;
use Imagine\Imagick\Imagine as ImagickImagine;
use Imagine\Gd\Imagine as GdImagine;
use Imagine\Image\ImageInterface;
use Imagine\Image\Box;
use Zend\Cache\Storage\StorageInterface;

class ImageConverter implements ConverterInterface
{
    protected $default_backend = 'gd';
    protected $supported_backends = ['gd', 'imagick'];
    protected $backend;

    protected $default_quality = 90;

    /**
     *
     * @var boolean
     */
    protected $cacheEnabled = false;

    /**
     *
     * @var StorageInterface
     */
    protected $cacheStorage;

    /**
     *
     * @param array $params
     */
    public function __construct(array $params = [])
    {
        if (array_key_exists('backend', $params)) {
            $this->setBackend($params['backend']);
        } else {
            $this->setBackend($this->default_backend);
        }
    }

    /**
     * Set the backend gd of imagick to use
     *
     * @param string $backend (gd/imagick)
     *
     * @throws Exception\UnsupportedBackendException
     * @return \Soluble\Media\Converter\ImageConverter
     */
    public function setBackend($backend)
    {
        if (!is_string($backend)) {
            throw new Exception\InvalidArgumentException(__METHOD__ . " backend parameter must be a valid string.");
        }

        if (!in_array($backend, $this->supported_backends)) {
            $valid_backends = implode(',', $this->supported_backends);
            throw new Exception\UnsupportedBackendException(__METHOD__ . " Backend '$backend' is not supported, supported backends are '$valid_backends'''");
        }
        $this->backend = $backend;
        return $this;
    }

    /**
     *
     * @param string $filename
     * @param \Soluble\Media\BoxDimension $box
     * @param string $format
     * @param int $quality
     * @throws \Soluble\Media\Converter\Exception
     * @throws \Exception
     */
    public function getThumbnail($filename, BoxDimension $box, $format = null, $quality = null)
    {
        $width    = $box->getWidth();
        $height   = $box->getHeight();

        if ($quality === null) {
            $quality = $this->default_quality;
        }

        $cache_key = md5("$filename/$width/$height/$quality/$format");

        if ($this->cacheEnabled && $this->cacheStorage->hasItem($cache_key)) {
            $cacheMd = $this->cacheStorage->getMetadata($cache_key);
            if ($cacheMd['mtime'] < filemtime($filename)) {
                // invalid cache

                $binaryContent = $this->generateThumbnail($filename, $box, $format, $quality);
                $this->cacheStorage->setItem($cache_key, $binaryContent);
            } else {
                $binaryContent = $this->cacheStorage->getItem($cache_key);
            }
        } else {
            $binaryContent = $this->generateThumbnail($filename, $box, $format, $quality);
            $this->cacheStorage->setItem($cache_key, $binaryContent);
        }

        switch ($format) {
            case 'jpg':
                $content_type = 'image/jpeg';
                break;
            case 'png':
                $content_type = 'image/png';
                break;
            case 'gif':
                $content_type = 'image/gif';
                break;
            default:
                throw new \Exception("Unsupported format '$format'");
        }

        header("Content-type: $content_type", true);
        header("Accept-Ranges: bytes", true);
        header("Cache-control: max-age=2592000, public", true);
        header("Content-Disposition: inline; filename=\"$filename\";", true);
        header('Last-Modified: '. gmdate('D, d M Y H:i:s', filemtime($filename)).' GMT', true);
        header('Expires: ' . gmdate('D, d M Y H:i:s', strtotime('+1 years')) . ' GMT', true);
        //header('Content-Disposition: attachment; filename="downloaded.pdf"');
        header('Pragma: cache', true);
        echo $binaryContent;
        die();
    }

    protected function generateThumbnail($filename, BoxDimension $box, $format = null, $quality = null, $strip = true)
    {
        $width    = $box->getWidth();
        $height   = $box->getHeight();

        try {
            $imagine = $this->getImagine();

            if ($imagine instanceof ImagickImagine) {
                $filter = ImageInterface::FILTER_LANCZOS;
                /**
                 * BESSEL : 53k
                 * LANCZOS: 54.5k
                 * GAUSSIAN: 52k
                 * MITCHELL: 53k
                 jpegtran -optimize 14610.jpg > 14610_test.jpg
                 */
            } else {
                $filter = ImageInterface::FILTER_UNDEFINED;
            }

            $image = $imagine->open($filename);

                // Get dimension by keeping proportions
            $size = $image->getSize();
            $ratio_x = $size->getWidth() / $width;
            $ratio_y = $size->getHeight() / $height;
            $max_ratio = max($ratio_x, $ratio_y);
            $new_width  = (int) ($size->getWidth() / $max_ratio);
            $new_height = (int) ($size->getHeight() / $max_ratio);

            $newSize = new Box($new_width, $new_height);

            if ($strip) {
                $image->strip();
            }

            //$image->interlace(ImageInterface::INTERLACE_LINE);

            $image->resize($newSize, $filter);
            $options = [
                'quality' => $quality,
                'flatten' => true,
                //'resolution-units' => ImageInterface::RESOLUTION_PIXELSPERINCH,
                //'resolution-y' => 72,
                //'resolution-x' => 72,
            ];

            //var_dump(get_class($image));die();
            $content = $image->get($format, $options);
        } catch (\Exception $e) {
            // ERROR 403 ?
            //var_dump($e);
            //die();
            throw $e;
        }
        return $content;
    }

    /**
     *
     * @param string $backend
     * @return
     */
    protected function getImagine($backend = null)
    {
        if ($backend === null) {
            $backend = $this->backend;
        }
        switch (strtolower($backend)) {
            case 'imagick':
                $imagine = new ImagickImagine();
                break;
            case 'gd':
                $imagine = new GdImagine();
                break;
            default:
                throw new \Exception("Library '$backend' not supported");

        }
        return $imagine;
    }

    /**
     *
     * @param StorageInterface $storage
     * @return \Soluble\Media\Converter\ImageConverter
     */
    public function setCache(StorageInterface $storage)
    {
        $this->cacheStorage = $storage;
        $this->cacheEnabled = true;
        return $this;
    }

    /**
     * Unset cache (primarly for unit testing)
     * @return \Soluble\Media\Converter\ImageConverter
     */
    public function unsetCache()
    {
        $this->cacheEnabled = false;
        $this->cacheStorage = null;
        return $this;
    }
}


<?php

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

namespace Valkyrja\Logger;

use Psr\Log\LoggerInterface;

/**
 * Class Logger.
 *
 * @author Melech Mizrachi
 */
class MonologLogger implements Logger
{
    /**
     * The logger.
     *
     * @var \Psr\Log\LoggerInterface
     */
    protected $logger;

    /**
     * Logger constructor.
     *
     * @param \Psr\Log\LoggerInterface $logger The logger
     */
    public function __construct(LoggerInterface $logger)
    {
        $this->logger = $logger;
    }

    /**
     * Log a debug message.
     *
     * @param string $message The message
     * @param array  $context [optional] The context
     *
     * @return \Valkyrja\Logger\Logger
     */
    public function debug(string $message, array $context = []): Logger
    {
        $this->logger->{LogLevel::DEBUG}($message, $context);

        return $this;
    }

    /**
     * Log an info message.
     *
     * @param string $message The message
     * @param array  $context [optional] The context
     *
     * @return \Valkyrja\Logger\Logger
     */
    public function info(string $message, array $context = []): Logger
    {
        $this->logger->{LogLevel::INFO}($message, $context);

        return $this;
    }

    /**
     * Log a notice message.
     *
     * @param string $message The message
     * @param array  $context [optional] The context
     *
     * @return \Valkyrja\Logger\Logger
     */
    public function notice(string $message, array $context = []): Logger
    {
        $this->logger->{LogLevel::NOTICE}($message, $context);

        return $this;
    }

    /**
     * Log a warning message.
     *
     * @param string $message The message
     * @param array  $context [optional] The context
     *
     * @return \Valkyrja\Logger\Logger
     */
    public function warning(string $message, array $context = []): Logger
    {
        $this->logger->{LogLevel::WARNING}($message, $context);

        return $this;
    }

    /**
     * Log a error message.
     *
     * @param string $message The message
     * @param array  $context [optional] The context
     *
     * @return \Valkyrja\Logger\Logger
     */
    public function error(string $message, array $context = []): Logger
    {
        $this->logger->{LogLevel::ERROR}($message, $context);

        return $this;
    }

    /**
     * Log a critical message.
     *
     * @param string $message The message
     * @param array  $context [optional] The context
     *
     * @return \Valkyrja\Logger\Logger
     */
    public function critical(string $message, array $context = []): Logger
    {
        $this->logger->{LogLevel::CRITICAL}($message, $context);

        return $this;
    }

    /**
     * Log a alert message.
     *
     * @param string $message The message
     * @param array  $context [optional] The context
     *
     * @return \Valkyrja\Logger\Logger
     */
    public function alert(string $message, array $context = []): Logger
    {
        $this->logger->{LogLevel::ALERT}($message, $context);

        return $this;
    }

    /**
     * Log a emergency message.
     *
     * @param string $message The message
     * @param array  $context [optional] The context
     *
     * @return \Valkyrja\Logger\Logger
     */
    public function emergency(string $message, array $context = []): Logger
    {
        $this->logger->{LogLevel::EMERGENCY}($message, $context);

        return $this;
    }

    /**
     * Log a message.
     *
     * @param LogLevel $level   The log level
     * @param string   $message The message
     * @param array    $context [optional] The context
     *
     * @return \Valkyrja\Logger\Logger
     */
    public function log(LogLevel $level, string $message, array $context = []): Logger
    {
        $this->logger->{$level->getValue()}($message, $context);

        return $this;
    }

    /**
     * Get the logger.
     *
     * @return \Psr\Log\LoggerInterface
     */
    public function getLogger(): LoggerInterface
    {
        return $this->logger;
    }

    /**
     * Set the logger.
     *
     * @param \Psr\Log\LoggerInterface $logger The logger
     *
     * @return \Valkyrja\Logger\Logger
     */
    public function setLogger(LoggerInterface $logger): Logger
    {
        $this->logger = $logger;

        return $this;
    }
}