<?php

namespace Skillberto\SonataPageMenuBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Menu
 */
class Menu
{
    /**
     * @var integer
     */
    protected $id;

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

    /**
     * @var boolean
     */
    protected $clickable;

    /**
     * @var integer
     */
    protected $lft;

    /**
     * @var integer
     */
    protected $rgt;

    /**
     * @var integer
     */
    protected $root;

    /**
     * @var integer
     */
    protected $lvl;

    /**
     * @var \Doctrine\Common\Collections\Collection
     */
    protected $children;

    /**
     * @var \Application\Sonata\PageBundle\Entity\Page
     */
    protected $page;

    /**
     * @var \Application\Sonata\PageBundle\Entity\Site
     */
    protected $site;

    /**
     * @var \Skillberto\SonataPageMenuBundle\Entity\Menu
     */
    protected $parent;

    /**
     * @var array
     */
    protected $attribute;

    /**
     * @var boolean
     */
    protected $active;

    /**
     * @var \DateTime
     */
    protected $createdAt;

    /**
     * @var \DateTime
     */
    protected $updatedAt;

    /**
     * Constructor
     */
    public function __construct()
    {
        $this->children = new \Doctrine\Common\Collections\ArrayCollection();
    }

    public function __toString()
    {
        return (string) $this->getName();
    }

    /**
     * Get id
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set name
     *
     * @param string $name
     * @return Menu
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Set clickable
     *
     * @param boolean $clickable
     * @return Menu
     */
    public function setClickable($clickable)
    {
        $this->clickable = $clickable;

        return $this;
    }

    /**
     * Get clickable
     *
     * @return boolean
     */
    public function getClickable()
    {
        return $this->clickable;
    }

    /**
     * Set lft
     *
     * @param integer $lft
     * @return Menu
     */
    public function setLft($lft)
    {
        $this->lft = $lft;

        return $this;
    }

    /**
     * Get lft
     *
     * @return integer
     */
    public function getLft()
    {
        return $this->lft;
    }

    /**
     * Set rgt
     *
     * @param integer $rgt
     * @return Menu
     */
    public function setRgt($rgt)
    {
        $this->rgt = $rgt;

        return $this;
    }

    /**
     * Get rgt
     *
     * @return integer
     */
    public function getRgt()
    {
        return $this->rgt;
    }

    /**
     * Set root
     *
     * @param integer $root
     * @return Menu
     */
    public function setRoot($root)
    {
        $this->root = $root;

        return $this;
    }

    /**
     * Get root
     *
     * @return integer
     */
    public function getRoot()
    {
        return $this->root;
    }

    /**
     * Set lvl
     *
     * @param integer $lvl
     * @return Menu
     */
    public function setLvl($lvl)
    {
        $this->lvl = $lvl;

        return $this;
    }

    /**
     * Get lvl
     *
     * @return integer
     */
    public function getLvl()
    {
        return $this->lvl;
    }

    /**
     * Add children
     *
     * @param \Skillberto\SonataPageMenuBundle\Entity\Menu $children
     * @return Menu
     */
    public function addChild(\Skillberto\SonataPageMenuBundle\Entity\Menu $children)
    {
        $this->children[] = $children;

        return $this;
    }

    /**
     * Remove children
     *
     * @param \Skillberto\SonataPageMenuBundle\Entity\Menu $children
     */
    public function removeChild(\Skillberto\SonataPageMenuBundle\Entity\Menu $children)
    {
        $this->children->removeElement($children);
    }

    /**
     * Get children
     *
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getChildren()
    {
        return $this->children;
    }

    /**
     * Set page
     *
     * @param \Application\Sonata\PageBundle\Entity\Page $page
     * @return Menu
     */
    public function setPage(\Application\Sonata\PageBundle\Entity\Page $page = null)
    {
        $this->page = $page;

        return $this;
    }

    /**
     * Get page
     *
     * @return \Application\Sonata\PageBundle\Entity\Page
     */
    public function getPage()
    {
        return $this->page;
    }

    /**
     * Set site
     *
     * @param \Application\Sonata\PageBundle\Entity\Site $site
     * @return Menu
     */
    public function setSite(\Application\Sonata\PageBundle\Entity\Site $site = null)
    {
        $this->site = $site;

        return $this;
    }

    /**
     * Get site
     *
     * @return \Application\Sonata\PageBundle\Entity\Site
     */
    public function getSite()
    {
        return $this->site;
    }

    /**
     * Set parent
     *
     * @param \Skillberto\SonataPageMenuBundle\Entity\Menu $parent
     * @return Menu
     */
    public function setParent(\Skillberto\SonataPageMenuBundle\Entity\Menu $parent = null)
    {
        $this->parent = $parent;

        return $this;
    }

    /**
     * Get parent
     *
     * @return \Skillberto\SonataPageMenuBundle\Entity\Menu
     */
    public function getParent()
    {
        return $this->parent;
    }

    /**
     * Set attribute
     *
     * @param array $attribute
     * @return Menu
     */
    public function setAttribute($attribute)
    {
        $this->attribute = $attribute;

        return $this;
    }

    /**
     * Get attribute
     *
     * @return array
     */
    public function getAttribute()
    {
        return $this->attribute;
    }

    /**
     * Set active
     *
     * @param boolean $active
     * @return Menu        // Add your code here

     */
    public function setActive($active)
    {
        $this->active = $active;

        return $this;
    }

    /**
     * Get active
     *
     * @return boolean
     */
    public function getActive()
    {
        return $this->active;
    }

    /**
     * Set createdAt
     *
     * @param \DateTime $createdAt
     * @return Menu
     */
    public function setCreatedAt($createdAt)
    {
        $this->createdAt = $createdAt;

        return $this;
    }

    /**
     * Get createdAt
     *
     * @return \DateTime
     */
    public function getCreatedAt()
    {
        return $this->createdAt;
    }

    /**
     * Set updatedAt
     *
     * @param \DateTime $updatedAt
     * @return Menu
     */
    public function setUpdatedAt($updatedAt)
    {
        $this->updatedAt = $updatedAt;

        return $this;
    }

    /**
     * Get updatedAt
     *
     * @return \DateTime
     */
    public function getUpdatedAt()
    {
        return $this->updatedAt;
    }

    /**
     * @ORM\PrePersist
     */
    public function createdAt()
    {
        $this->setCreatedAt( new \DateTime("now") );
        $this->setUpdatedAt( new \DateTime("now") );
    }

    /**
     * @ORM\PostPersist
     */
    public function updateAt()
    {
        $this->setUpdatedAt( new \DateTime("now") );
    }
}


<?php

namespace Addons\Core\Models;

use Addons\Core\Models\TreeTrait;
use Addons\Core\Models\CacheTrait;
use Addons\Core\Models\BuilderTrait;
use Addons\Core\Models\PolyfillTrait;
use Illuminate\Database\Eloquent\Model;

class Tree extends Model {

	use CacheTrait, BuilderTrait, PolyfillTrait;
	use TreeTrait;

	//不能批量赋值
	protected $guarded = ['id', 'level', 'path', 'order']; //这些字段禁止维护

	public $parentKey = 'pid'; //必要字段                MySQL需加索引
	public $orderKey = 'order'; //无需此字段请设置NULL   MySQL需加索引
	public $pathKey = 'path'; //无需此字段请设置NULL     MySQL需加索引
	public $levelKey = 'level'; //无需此字段请设置NULL   MySQL需加索引

	//relation
	public function children()
	{
		$builder = $this->hasMany(get_class($this), $this->parentKey, $this->getKeyName());
		!empty($this->orderKey) && $builder->orderBy($this->orderKey, 'ASC');
		return $builder;
	}

	public function parent()
	{
		return $this->hasOne(get_class($this), $this->getKeyName(), $this->parentKey);
	}

	/**
	 * 获取指定ID的Node
	 *
	 * @param  integer $cid 输入ID
	 * @return mixed      输出查询结果
	 */
	public function getNode($id, $columns = ['*'])
	{
		$columns = $this->formatColumns($columns);
		return empty($id) ? (new static)->newFromBuilder([
				$this->getKeyName() => 0,
				$this->parentKey => NULL,
				$this->pathKey => '/0/',
				$this->orderKey => 0,
				$this->levelKey => 0,
			]) : static::find($id, $columns);
	}

	/**
	 * 获取所匹配的根节点Node
	 *
	 * @return mixed      得到root
	 */
	public function getRoot($columns = ['*'])
	{
		$columns = $this->formatColumns($columns);
		$node = $this;
		if (empty($this->pathKey))
		{
			while(!empty($node->getParentKey()))
				$node = $this->getNode($node->getParentKey(), $columns);
			return $node;
		} else {
			list(,,$rootid) = explode('/', $node->getPathKey()); // [/0/1/2/3/] => 1
			return $this->getNode($rootid, $columns);
		}
	}

	/**
	 * 获取父级的Node
	 *
	 * @return mixed      得到父级元素
	 */
	public function getParent($columns = ['*'])
	{
		$columns = $this->formatColumns($columns);
		return $this->getNode($this->getParentKey(), $columns);
	}

	/**
	 * 获取所匹配的祖先Nodes
	 *
	 * @return array     返回祖先
	 */
	public function getParents($columns = ['*'])
	{
		$columns = $this->formatColumns($columns);
		$result = $this->newCollection();
		$node = $this;
		while(!empty($node->getParentKey()))
		{
			$node = $this->getNode($node->getParentKey(), $columns);
			$result[] = $node;
		}
		return $result;
	}

	/**
	 * 获得子集，返回一个Collection
	 *
	 * @return array 返回数据
	 */
	public function getChildren($columns = ['*'])
	{
		$columns = $this->formatColumns($columns);
		$builder = static::where($this->parentKey, $this->getKey());
		!empty($this->orderKey) && $builder->orderBy($this->orderKey);
		return $builder->get();
	}

	/**
	 * 获得所有子(孙)集，不包含自己，返回一个Collection
	 *
	 * @return array 返回数据
	 */
	public function getLeaves($columns = ['*'])
	{
		$columns = $this->formatColumns($columns);
		$node = $this;
		if (!empty($this->pathKey)) //使用Path搜索出来的节点，无法通过order进行良好的排序
		{
			$builder = static::where($this->pathKey, 'LIKE', $node->getPathKey().'%')->where($node->getKeyName(), '!=', $node->getKey());
			!empty($this->orderKey) && $builder->orderBy($this->orderKey);
			!empty($this->pathKey) && $builder->orderBy($this->pathKey);

			return $builder->get($columns);
		}
		else
		{
			$result = $this->newCollection();
			$children = $this->getChildren($columns);
			foreach($children as $v)
			{
				$result[] = $v;
				$result = $result->merge($v->getLeaves($columns));
			}
			return $result;
		}
	}

	/**
	 * 获得一颗树，返回一个Tree的数组
	 *
	 * @param array $columns 需要取出的字段名
	 * @param bool 返回的children中，是否以ID为Key
	 * @return array 返回数据
	 */
	public function getTree(array $columns = ['*'], bool $idAsKey = true)
	{
		$nodes = $this->getLeaves($columns)->prepend($this)->keyBy($this->getKeyName())->toArray();

		return static::datasetToTree($nodes, $idAsKey);
	}

	private function formatColumns(array $columns)
	{
		if (in_array('*', $columns)) return $columns;

		!in_array($this->getKeyName(), $columns) && $columns[] = $this->getKeyName();
		!in_array($this->parentKey, $columns) && $columns[] = $this->parentKey;
		!in_array($this->pathKey, $columns) && $columns[] = $this->pathKey;

		return $columns;
	}

	public function newOrder()
	{
		if (empty($this->orderKey)) return null;

		$node = static::where($this->parentKey, $this->getParentKey())->where($this->getKeyName(), '!=', $this->getKey() ?: 0)->orderBy($this->orderKey, 'DESC')->first([$this->orderKey]);
		return empty($node) ? 1 : intval($node->getOrderKey()) + 1;
	}

	public function moveToLast()
	{
		if (empty($this->orderKey)) return null;

		return static::where($this->getKeyName(), $this->getKey())->update([$this->orderKey => $this->newOrder()]);
	}

	public function movePrev($target_id)
	{
		return $this->move($target_id, 'prev');
	}

	public function moveNext($target_id)
	{
		return $this->move($target_id, 'next');
	}

	public function moveInner($target_id)
	{
		return $this->move($target_id, 'inner');
	}

	/**
	 * 移动节点
	 * @param  integer $target_id   目标CID
	 * @param  string $move_type     [inner, prev, next]分别表示：子集、前一位、后一位
	 * @return boolean
	 */
	public function move($target_id, $move_type)
	{
		$targetNode = $this->getNode($target_id);
		if (empty($target_id) || empty($targetNode)) return NULL;

		if ($move_type == 'inner') //成为别人子集，则直接调用,放入子集
			return $this->update([$this->parentKey => $target_id]); //自动调取changeParent

		if ($targetNode->getParentKey() != $this->getParentKey()) //父级不相同
			$this->update([$this->parentKey => $targetNode->getParentKey()]); //自动调取changeParent
		if (!empty($this->orderKey))
		{
			$order = intval($targetNode->getOrderKey()) + ($move_type == 'prev' ? 0 : 1);
			//更新同父级下所有的顺序
			static::where($this->parentKey, $targetNode->getParentKey())->where($this->orderKey, '>=', $order)->increment($this->orderKey);
			$this->update([$this->orderKey => $order]); //更新自己的顺序
		}

		return $this;
	}

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

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

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

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

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

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

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

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

}


<?php
namespace Owl\Service\DB;

class Statement
{
    use \Owl\Traits\Decorator;

    protected $statement;

    public function __construct(\PDOStatement $statement)
    {
        $this->statement = $this->reference = $statement;
    }

    /**
     * 返回用于执行的sql语句.
     *
     * @return string
     */
    public function __toString()
    {
        return $this->statement->queryString;
    }

    /**
     * 从查询结果提取下一行.
     *
     * @return array
     */
    public function getRow()
    {
        return $this->statement->fetch();
    }

    /**
     * 从下一行行中获取指定列的数据.
     *
     * @param int $col_number 列序号
     *
     * @return mixed
     */
    public function getCol($col_number = 0)
    {
        return $this->statement->fetch(\PDO::FETCH_COLUMN, $col_number);
    }

    /**
     * 获取查询结果内指定列的所有结果.
     *
     * @param int $col_number 列序号
     *
     * @return array
     */
    public function getCols($col_number = 0)
    {
        return $this->statement->fetchAll(\PDO::FETCH_COLUMN, $col_number);
    }

    /**
     * 返回所有的查询结果，允许以指定的字段内容为返回数组的key.
     *
     * @param string $col
     *
     * @return array
     */
    public function getAll($column = null)
    {
        if (!$column) {
            return $this->fetchAll();
        }

        $rowset = [];
        while ($row = $this->fetch()) {
            $rowset[$row[$column]] = $row;
        }

        return $rowset;
    }

    public static function factory($statement): Statement
    {
        if ($statement instanceof self) {
            return $statement;
        }

        if ($statement instanceof \PDOStatement) {
            return new static($statement);
        }

        throw new \InvalidArgumentException('Invalid statement');
    }
}


<?php
/**
 * Created by PhpStorm.
 * User: janhuang
 * Date: 16/5/27
 * Time: 下午10:41
 * Github: https://www.github.com/janhuang
 * Coding: https://www.coding.net/janhuang
 * SegmentFault: http://segmentfault.com/u/janhuang
 * Blog: http://segmentfault.com/blog/janhuang
 * Gmail: bboyjanhuang@gmail.com
 * WebSite: http://www.janhuang.me
 */

namespace Uniondrug\Packet;

use Uniondrug\Packet\Exceptions\PacketException;

/**
 * Class Json
 *
 * @package FastD\Packet
 */
class Json implements PacketInterface
{
    const SALT_START = 5;
    const SALT_LENGTH = 10;

    /**
     * @param     $data
     *
     * @param int $options
     * @param int $depth
     *
     * @return string
     * @throws \Uniondrug\Packet\Exceptions\PacketException
     */
    public static function encode($data, $options = 0, $depth = 512)
    {
        if (!is_array($data)) {
            throw new PacketException('The packet data is invalid. Must be a array.');
        }

        return json_encode($data, $options, $depth);
    }

    /**
     * @param      $data
     * @param bool $assoc
     *
     * @return array
     * @throws \Uniondrug\Packet\Exceptions\PacketException
     */
    public static function decode($data, $assoc = false)
    {
        $json = json_decode($data, $assoc);
        if (json_last_error()) {
            throw new PacketException(json_last_error_msg());
        }

        return $json;
    }
}


<?php
namespace Addons\Core;

use Closure, Schema, DB;
use Illuminate\Support\Arr;
use Illuminate\Http\Request;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;

trait ApiTrait {

	public function _getColumns(Builder $builder)
	{
		static $table_columns;

		$query = $builder->getQuery();
		$tables = [$query->from];
		if (!empty($query->joins))
			foreach ($query->joins as $v)
				$tables[] = $v->table;

		$_columns = [];
		foreach ($tables as &$v)
		{
			list($table, $alias) = strpos(strtolower($v), ' as ') !== false ? explode(' as ', $v) : [$v, $v];

			if (!isset($table_columns[$table]))
				$table_columns[$table] = Schema::getColumnListing($table);
				//$table_columns[$table] = $query->getConnection()->getDoctrineSchemaManager()->listTableColumns($table);

			foreach ($table_columns[$table] as $key/* => $value*/)
				$_columns[$key] = isset($_columns[$key]) ? $_columns[$key] : $alias.'.'.$key;
		}
		return $_columns;
	}

	/**
	 * 给Builder绑定where条件
	 * 注意：参数的值为空字符串，则会忽略该条件
	 *
	 * @param  Request $request
	 * @param  Builder $builder
	 * @return array           返回筛选(搜索)的参数
	 */
	private function _doFilters(Request $request, Builder $builder, $columns = [])
	{
		$filters = $this->_getFilters($request);
		$operators = [
			'in' => 'in', 'nin' => 'not in', 'is' => 'is',
			'min' => '>=', 'gte' => '>=', 'max' => '<=', 'lte' => '<=', 'btw' => 'between', 'nbtw' => 'not between', 'gt' => '>', 'lt' => '<',
			'neq' => '<>', 'ne' => '<>', 'eq' => '=', 'equal' => '=',
			'lk' => 'like', 'like' => 'like', 'lkb' => 'like binary',
			'nlk' => 'not like', 'nlkb' => 'not like binary',
			'rlk' => 'rlike', 'ilk' => 'ilike',
			'and' => '&', 'or' => '|', 'xor' => '^', 'left_shift' => '<<', 'right_shift' => '>>', 'bitwise_not' => '~', 'bitwise_not_any' => '~*', 'not_bitwise_not' => '!~', 'not_bitwise_not_any' => '!~*',
			'regexp' => 'regexp', 'not_regexp' => 'not regexp', 'similar_to' => 'similar to', 'not_similar_to' => 'not similar to',
		];
		foreach ($filters as $key => $filter)
		{
			$key = !empty($columns[$key]) ? $columns[$key] : $key;
			foreach ($filter as $method => $value)
			{
				$operator = $operators[$method];
				if (empty($value) && $value !== '0') continue; //''不做匹配
				else if (in_array($operator, ['like', 'like binary', 'not like', 'not like binary']))
					$value = trim($value, '%') != $value ? $value : '%'.$value.'%'; //如果开头结尾有 % 则以用户的为准

				if ($operator == 'in')
					$builder->whereIn($key, $value);
				else if ($operator == 'not in')
					$builder->whereNotIn($key, $value);
				else
					$builder->where($key, $operator ?: '=' , $value);
			}
		}
		return $filters;
	}

	private function _doQueries(Request $request, Builder $builder)
	{
		$queries = $this->_getQueries($request);
		foreach ($queries as $key => $value)
		{
			if (($value === '0' || !empty($value)) && method_exists($builder->getModel(), 'scope'.ucfirst($key)))
				call_user_func_array([$builder, $key], array_wrap($value));
		}
		return $queries;
	}

	private function _doOrders(Request $request, Builder $builder, $columns = [])
	{
		$orders = $this->_getOrders($request, $builder);
		foreach ($orders as $k => $v)
			$builder->orderBy(isset($columns[$k]) ? $columns[$k] : $k, $v);
		return $orders;
	}
	/**
	 * 获取筛选(搜索)的参数
	 * &f[username][lk]=abc&f[gender][eq]=1
	 *
	 * @param  Request $request
	 * @param  Builder $builder
	 * @return array           返回参数列表
	 */
	public function _getFilters(Request $request)
	{
		$filters = [];
		$inputs = $request->input('f', []);
		if (!empty($inputs))
			foreach ($inputs as $k => $v)
				$filters[$k] = is_array($v) ? array_change_key_case($v) : ['eq' => $v];

		return $filters;
	}
	/**
	 * 获取全文搜索的参数
	 * &q[ofPinyin]=abc
	 *
	 * @param  Request $request
	 * @param  Builder $builder
	 * @return array           返回参数列表
	 */
	public function _getQueries(Request $request)
	{
		$inputs = $request->input('q', []);

		return empty($inputs) ? [] : $inputs;
	}
	/**
	 * 获取排序的参数
	 * 1. datatable 的方式
	 * 2. order[id]=desc&order[created_at]=asc 类似这种方式
	 * 默认是按主键倒序
	 *
	 * @param  Request $request
	 * @param  Builder $builder
	 * @return array           返回参数列表
	 */
	public function _getOrders(Request $request, Builder $builder)
	{
		$orders = $request->input('o', []);
		//默认按照主键的倒序
		return empty($orders) ? [$builder->getModel()->getKeyName() => 'desc'] : $orders;
	}

	public function _getPaginate(Request $request, Builder $builder, array $columns = ['*'], array $extra_query = [])
	{
		$size = $request->input('size') ?: config('size.models.'.$builder->getModel()->getTable(), config('size.common'));
		$page = $request->input('page', 1);
		if ($request->input('all') == 'true') $size = 10000;//$builder->count(); //为统一使用paginate输出数据格式,这里需要将size设置为整表数量

		$tables_columns = $this->_getColumns($builder);
		$filters = $this->_doFilters($request, $builder, $tables_columns);
		$queries = $this->_doQueries($request, $builder);
		$orders = $this->_doOrders($request, $builder, $tables_columns);

		$paginate = $builder->paginate($size, $columns, 'page', $page);

		$query_strings = array_merge_recursive(['f' => $filters, 'q' => $queries], $extra_query);
		$paginate->appends($query_strings);

		$paginate->filters = $filters;
		$paginate->queries = $queries;
		$paginate->orders = $orders;
		return $paginate;
	}

	public function _getData(Request $request, Builder $builder, Closure $callback = null, array $columns = ['*'])
	{
		$paginate = $this->_getPaginate($request, $builder, $columns);

		if (!empty($callback) && is_callable($callback))
			call_user_func_array($callback, [$paginate]); //reference Objecy

		return $paginate->toArray() + ['filters' => $paginate->filters, 'queries' => $paginate->queries, 'orders' => $paginate->orders];
	}

	public function _getCount(Request $request, Builder $builder, $enable_filters = true)
	{
		$_b = clone $builder;
		if ($enable_filters)
		{
			$tables_columns = $this->_getColumns($builder);
			$this->_doFilters($request, $_b, $tables_columns);
			$this->_doQueries($request, $_b);
		}
		$query = $_b->getQuery();
		if (!empty($query->groups)) //group by
		{
			return $query->getCountForPagination($query->groups);
			// or
			$query->columns = $query->groups;
			return DB::table( DB::raw("({$_b->toSql()}) as sub") )
				->mergeBindings($_b->getQuery()) // you need to get underlying Query Builder
				->count();
		} else
			return $_b->count();
	}

	public function _getExport(Request $request, Builder $builder, Closure $callback = null, array $columns = ['*']) {
		set_time_limit(600); //10min

		$size = $request->input('size') ?: config('size.export', 1000);
		$tables_columns = $this->_getColumns($builder);
		$this->_doFilters($request, $builder, $tables_columns);
		$this->_doQueries($request, $builder);
		$paginate = $builder->orderBy($builder->getModel()->getKeyName(),'DESC')->paginate($size, $columns);
		if (!empty($callback) && is_callable($callback))
			call_user_func_array($callback, [&$paginate]);
		$data = $paginate->toArray();
		!empty($data['data']) && Arr::isAssoc($data['data'][0]) && array_unshift($data['data'], array_keys($data['data'][0]));
		array_unshift($data['data'], [$builder->getModel()->getTable(), $data['from']. '-'. $data['to'].'/'. $data['total'], date('Y-m-d h:i:s')]);
		return $data['data'];
	}
}


<?php
/**
 * class pxcmd
 *
 * Pickles 2 のコアオブジェクトの1つ `$pxcmd` のオブジェクトクラスを定義します。
 *
 * @author Tomoya Koyanagi <tomk79@gmail.com>
 */
namespace picklesFramework2;

/**
 * PX Commands
 *
 * Pickles 2 のコアオブジェクトの1つ `$pxcmd` のオブジェクトクラスです。
 * このオブジェクトは、Pickles 2 の初期化処理の中で自動的に生成され、`$px` の内部に格納されます。
 *
 * メソッド `$px->pxcmd()` を通じてアクセスします。
 *
 * @author Tomoya Koyanagi <tomk79@gmail.com>
 */
class pxcmd{

	/**
	 * オブジェクト
	 * @access private
	 */
	private $px, $bowl;

	/**
	 * PXコマンド
	 * @access private
	 */
	private $pxcommands = array();

	/**
	 * Constructor
	 *
	 * @param object $px Picklesオブジェクト
	 */
	public function __construct($px){
		$this->px = $px;
		$this->pxcommands = array();

		// make instance $bowl
		$this->bowl = new bowl();

	}

	/**
	 * PXコマンドを登録する。
	 *
	 * @param string $cmd PXコマンド名
	 * @param function $fnc 実行するコマンド
	 * @return bool 成功時 `true`、失敗時 `false`
	 */
	public function register( $cmd, $fnc ){
		if( !is_string($cmd) ){
			return false;
		}
		if( array_key_exists($cmd, $this->pxcommands) ){
			trigger_error('PX Command "'.$cmd.'" is already registered.');
			return false;
		}
		$this->pxcommands[$cmd] = array(
			'cmd' => $cmd ,
			'name' => $cmd ,
			'fnc' => $fnc ,
		);

		$pxcmd = $this->px->get_px_command();
		if( is_array($pxcmd) && count($pxcmd) && $pxcmd[0] == $cmd ){
			$fnc($this->px);
		}
		return true;
	}

	/**
	 * `$bowl` オブジェクトを取得する。
	 *
	 * @return object $bowlオブジェクト
	 */
	public function bowl(){
		return $this->bowl;
	}

	/**
	 * CLI header を生成する。
	 * @return string Header
	 */
	public function get_cli_header(){
		$pxcmd = $this->px->get_px_command();
		@header('Content-type: text/plain');
		ob_start();
		print '------------'."\n";
		print 'Pickles '.$this->px->get_version().' -> '.$pxcmd[0]."\n";
		print 'PHP '.phpversion()."\n";
		print @date('Y-m-d H:i:s')."\n";
		print '------------'."\n";
		return ob_get_clean();
	}

	/**
	 * CLI footer を生成する。
	 * @return string Footer
	 */
	public function get_cli_footer(){
		ob_start();
		print '------------'."\n";
		print @date('Y-m-d H:i:s')."\n";
		print 'PX Command END;'."\n";
		print "\n";
		return ob_get_clean();
	}

	/**
	 * wrap GUI frame
	 *
	 * @param string $content コンテンツ領域のHTMLソースコード
	 * @return string HTML全体のHTMLソースコード
	 */
	public function wrap_gui_frame( $content ){
		$this->bowl()->send($content);
		unset($content);

		@header( 'Content-type: text/html; charset="UTF-8"' );

		// リソースをキャッシュ領域にコピー
		$path_pxcache = $this->px->fs()->get_realpath( $this->px->get_path_controot().$this->px->conf()->public_cache_dir.'/px/' );
		$realpath_pxcache = $this->px->fs()->get_realpath( $this->px->get_realpath_docroot().$path_pxcache );
		$this->px->fs()->mkdir( $realpath_pxcache );
		$this->px->fs()->copy_r( __DIR__.'/files/', $realpath_pxcache );

		$pxcmd = $this->px->get_px_command();
		ob_start();?>
<!DOCTYPE html>

		<meta charset="UTF-8" />
		<title><?= htmlspecialchars( $this->px->conf()->name ) ?></title>

		<link rel="stylesheet" href="<?= htmlspecialchars( $path_pxcache.'styles/bootstrap/css/bootstrap.min.css' ); ?>">

		<link rel="stylesheet" href="<?= htmlspecialchars( $path_pxcache.'styles/contents.css' ); ?>" type="text/css" />

		<link rel="stylesheet" href="<?= htmlspecialchars( $path_pxcache.'styles/layout.css' ); ?>" type="text/css" />

<?= $this->bowl()->pull('head') ?>

<?= $this->px->get_pickles_logo_svg() ?> Pickles 2 (version: <?= htmlspecialchars( $this->px->get_version() ) ?>)

<?php
	// $pxcommands = $this->pxcommands;
	// if( count($pxcommands) ){
	// 	print '<select onchange="window.location.href=\'?PX=\'+this.options[this.selectedIndex].value;">';
	// 	foreach( $pxcommands as $row ){
	// 		print '<option value="'.htmlspecialchars($row['cmd']).'"'.($row['cmd']==$pxcmd[0]?' selected="selected"':'').'>'.htmlspecialchars($row['name']).'</option>';
	// 	}
	// 	print '</select>';
	// }
?>

<?= htmlspecialchars( @$this->px->conf()->name ) ?>

<?php
		$command_title = $pxcmd[0].(@strlen($pxcmd[1])?'.'.$pxcmd[1]:'');
		$page_title = null;
?>

		<?php if(strlen($page_title)){ ?>

<a href="?PX=<?= htmlspecialchars( $command_title ) ?>" style="color:inherit; text-decoration:none;"><?= htmlspecialchars($command_title) ?>

<?= htmlspecialchars( $page_title ) ?>

		<?php }else{ ?>

<a href="?PX=<?= htmlspecialchars( $command_title ) ?>" style="color:inherit; text-decoration:none;"><?= htmlspecialchars( $command_title ) ?>

		<?php } ?>

<?= $this->bowl()->pull() ?>

PX Commands を終了する

PHP <?= htmlspecialchars(phpversion()) ?>

<?= htmlspecialchars(@date('Y-m-d H:i:s')) ?>

Pickles Framework (C)Tomoya Koyanagi.

<?php
		return ob_get_clean();
	}

}


<?php

namespace Skillberto\SonataPageMenuBundle\Admin;

use Skillberto\SonataPageMenuBundle\Util\PositionHandler;
use Skillberto\SonataPageMenuBundle\Entity\Menu;
use Skillberto\SonataPageMenuBundle\Site\OptionalSiteInterface;
use Sonata\CoreBundle\Validator\ErrorElement;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Show\ShowMapper;
use Sonata\AdminBundle\Route\RouteCollection;
use Sonata\PageBundle\Model\PageManagerInterface;
use Symfony\Component\Validator\Constraints as Assert;
use Sonata\PageBundle\Form\Type\PageSelectorType;

class MenuAdmin extends AbstractAdmin
{
    protected $managerRegistry;
    protected $pageManagerInterface;
    protected $optionalSiteInterface;
    protected $formAttribute = array();
    protected $pageInstance;
    protected $siteInstance;
    protected $positionHandler
    ;

    public function __construct($code, $class, $baseControllerName, PageManagerInterface $pageManagerInterface, OptionalSiteInterface $optionalSiteInterface)
    {
        $this->pageManagerInterface  = $pageManagerInterface;
        $this->optionalSiteInterface = $optionalSiteInterface;
        $this->positionHandler       = new PositionHandler();

        parent::__construct($code, $class, $baseControllerName);
    }

    /**
     * @return array
     */
    public function getPersistentParameters()
    {
        return array(
            'provider'  => $this->getRequest()->get('provider'),
            'site'      => $this->getRequest()->get('site'),
        );
    }

    /**
     * @return Menu
     */
    public function getNewInstance()
    {
        $site = $this->getCurrentSite();

        $instance = parent::getNewInstance();
        $instance->setSite($site);

        return $instance;
    }

    /**
     * @param   string $context
     *
     * @return \Sonata\AdminBundle\Datagrid\ProxyQueryInterface
     */
    public function createQuery($context = 'list')
    {
        $query = parent::createQuery($context);

        $query->andWhere(
            $query->expr()->eq($query->getRootAlias() . '.site', ':my_param')
        );

        $query->addOrderBy($query->getRootAlias() .'.root', 'ASC');
        $query->addOrderBy($query->getRootAlias() .'.lft', 'ASC');
        $query->setParameter('my_param', $this->getCurrentSite());

        return $query;
    }

    /**
     * @param ErrorElement $errorElement
     * @param mixed $object
     */
    public function validate(ErrorElement $errorElement, $object)
    {
        $errorElement
            ->with('parent')
            ->addConstraint(
                new Assert\NotEqualTo(
                    array('value' => $object)
                )
            )
            ->end();
    }

    /**
     * @param  $positionHandler
     * @return $this
     */
    public function setPositionHandler($positionHandler)
    {
        $this->positionHandler = $positionHandler;

        return $this;
    }

    /**
     * @return PositionHandler
     */
    public function getPositionHandler()
    {
        return $this->positionHandler;
    }

    /**
     * @return \Sonata\PageBundle\Model\Site
     */
    public function getCurrentSite()
    {
        return $this->optionalSiteInterface->getChosenSite();
    }

    /**
     * @return mixed
     */
    public function getSites()
    {
        return $this->optionalSiteInterface->getSiteManager()->findBy(array());
    }

    protected function configureRoutes(RouteCollection $collection)
    {
        $collection->add('move', $this->getRouterIdParameter().'/move/{position}');
        $collection->add('activate', $this->getRouterIdParameter().'/activate');
    }

    /**
     * @param \Sonata\AdminBundle\Show\ShowMapper $showMapper
     *
     * @return void
     */
    protected function configureShowField(ShowMapper $showMapper)
    {
        $showMapper
            ->add('name')
            ->add('page')
            ->add('parent')
            ->add('active')
        ;
    }

    /**
     * @param \Sonata\AdminBundle\Form\FormMapper $formMapper
     *
     * @return void
     */
    protected function configureFormFields(FormMapper $formMapper)
    {
        if ($this->getSubject() && $this->getSubject()->getId()) {
            $this->initializeEditForm();
        } else {
            $this->initializeCreateForm();
        }

        $formMapper
             ->add('name', 'text')
             ->add('page', PageSelectorType::class, array(
                        'site'          => $this->siteInstance,
                        'model_manager' => $this->getModelManager(),
                        'class'         => 'Application\Sonata\PageBundle\Entity\Page',
                        'required'      => true
             ), array(
                        'admin_code' => 'sonata.page.admin.page',
                        'link_parameters' => array(
                            'siteId' => $this->getSubject() ? $this->getSubject()->getSite()->getId() : null
                        )
                    ))
             ->add('parent', 'sonata_type_model', array('required' => false))
             ->add('active', 'checkbox', array('required' => false, 'attr' => $this->formAttribute))
             ->add('clickable', 'checkbox', array('required' => false, 'attr' => $this->formAttribute))
            ;
    }

    /**
     * @param \Sonata\AdminBundle\Datagrid\ListMapper $listMapper
     *
     * @return void
     */
    protected function configureListFields(ListMapper $listMapper)
    {
        $this->positionHandler->setLastPositions($this->getLastPositionsFromDb());

        $listMapper
            ->addIdentifier('id')
            ->add('name', 'string', array('template' => 'SkillbertoSonataPageMenuBundle:Admin:base_list_field.html.twig'))
            ->add('page')
            ->add('parent')
            ->add('active')
            ->add('clickable')
            ->add(
                '_action',
                'actions',
                array(
                'actions' => array(
                    'edit'      => array(),
                    'delete'    => array(),
                    'activate'  => array('template' => 'SkillbertoSonataPageMenuBundle:Admin:list__action_activate.html.twig'),
                    'move'      => array('template' => 'SkillbertoSonataPageMenuBundle:Admin:list__action_sort.html.twig')
                    )
                )
            )
        ;
    }

    /**
     * @param \Sonata\AdminBundle\Datagrid\DatagridMapper $datagridMapper
     *
     * @return void
     */
    protected function configureDatagridFilters(DatagridMapper $datagridMapper)
    {
        $datagridMapper
            ->add('name')
            ->add('page')
            ->add('parent')
        ;
    }

    protected function initializeEditForm()
    {
        $page = $this->getSubject()->getPage();
        $site = $this->getSubject()->getSite();

        $this->formAttribute = array();
        $this->pageInstance  = $page;
        $this->siteInstance  = $site;
    }

    protected function initializeCreateForm()
    {
        $this->formAttribute = array('checked' => 'checked');
        $this->pageInstance  = null;
        $this->siteInstance  = $this->getCurrentSite();
    }

    /**
     * @return array
     */
    protected function getAllPages()
    {
        $currentSite = $this->getCurrentSite();

        if ($currentSite) {
            $pages = $this->pageManagerInterface->loadPages($currentSite);
        } else {
            $pages = array();
        }

        return $pages;
    }

    /**
     * @return array
     */
    protected function getLastPositionsFromDb()
    {
        $repo = $this->getConfigurationPool()->getContainer()->get('doctrine')->getRepository($this->getClass());

        $count = array();

        foreach ($repo->getParentChildNumber() as $data) {
            if ($data['parent'] == null) {
                $data['parent'] = 0;
            }

            $count[$data['parent']] = $data['size'];
        }

        return $count;
    }
}


<?php
namespace Addons\Core\Console;

use Illuminate\Foundation\Console\Kernel as BaseKernel;

class Kernel extends BaseKernel {

	/**
     * Run an Artisan console command by name.
     *
     * @param  string  $command
     * @param  array  $parameters
     * @return int
     */
    public function run($commandline)
    {
        $this->bootstrap();

        $artisan = $this->getArtisan();
		$artisan->setCatchExceptions(false);
		$artisan->run($input = new \Symfony\Component\Console\Input\StringInput(trim(str_replace('php artisan', '', $commandline))), $out = new \Symfony\Component\Console\Output\BufferedOutput);
		$artisan->setCatchExceptions(true);
        return $out;
    }

    public function setCommands($commands)
    {
        $this->commands = $commands;
    }

    public function getCommands()
    {
        return $commands;
    }

    public function addCommand($command)
    {
        $this->commands[] = $command;
    }
}


<?php

/*
 * This file is part of the FSi Component package.
 *
 * (c) Lukasz Cybula <lukasz@fsi.pl>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace FSi\Component\Reflection;

class ReflectionMethod extends \ReflectionMethod
{
    protected static $methods = array();

    /**
     * Constructs a new ReflectionMethod object.
     *
     * @param string|object $class
     * @param string $name
     * @throws ReflectionException
     * @return ReflectionMethod
     */
    final public function __construct($class, $name)
    {
        $bt = debug_backtrace();
        if (!isset($bt[1]['class']) || ($bt[1]['class'] !== __CLASS__))
            throw new ReflectionException('ReflectionClass\' constructor cannot be called from outside the class');
        parent::__construct($class, $name);
    }

    /**
     * Constructs a new ReflectionMethod object from method and class name.
     * If object already exists in cache it will taken from there instead of creating
     * new object
     *
     * @param string|object $class
     * @param string $property
     * @return ReflectionMethod
     */
    public static function factory($class, $method = null)
    {
        if (is_object($class))
            $class = get_class($class);
        $class = (string)$class;
        if (!isset(self::$methods[$class])) {
            $classReflection = new \ReflectionClass($class);
            $methods = $classReflection->getMethods();
            self::$methods[$class] = array();
            foreach ($methods as $methodReflection) {
                if ($methodReflection->class != $class) {
                    self::$methods[$class][$methodReflection->name] = self::factory($methodReflection->class, $methodReflection->name);
                } else {
                    self::$methods[$class][$methodReflection->name] = new self($class, $methodReflection->name);
                    self::$methods[$class][$methodReflection->name]->setAccessible(true);
                }
            }
        }
        if (isset($method)) {
            if (!isset(self::$methods[$class][$method])) {
                self::$methods[$class][$method] = new self($class, $method);
                self::$methods[$class][$method]->setAccessible(true);
            }
            return self::$methods[$class][$method];
        } else
            return array_values(self::$methods[$class]);
    }

    /**
     * Get class ReflectionObject using ReflectionClass::factory method.
     *
     * @return ReflectionClass
     */
    public function getDeclaringClass()
    {
        return ReflectionClass::factory($this->class);
    }

}


<?php

namespace ASM\Redis;

use ASM\AsmException;
use ASM\ConcurrentDriver;
use ASM\IdGenerator;
use ASM\Serializer;
use ASM\SessionManager;
use ASM\LostLockException;
use ASM\FailedToAcquireLockException;
use ASM\SessionConfig;
use ASM\Session;
use Predis\Client as RedisClient;

/**
 *
 *
 * SessionDataKey - if this exists the session exists
 *
 * ZombieKey - if this exists, the value it contains is the session ID that replaced
 * the session ID that was destroyed.
 *
 * LockKey - Used to hold implement a lock for the session.
 *
 * Profile key - stores a list of the allowed user-profile strings that can access
 *               this session.
 *
 */

/**
 * @param $sessionID
 * @return string
 *
 */
function generateSessionDataKey($sessionID)
{
    return 'session:'.$sessionID;
}

function generateZombieKey($dyingSessionID)
{
    return 'zombie:'.$dyingSessionID;
}

function generateLockKey($sessionID)
{
    return 'session:'.$sessionID.':lock';
}

function generateProfileKey($sessionID)
{
    return 'session:'.$sessionID.':profile';
}

/**
 * @param $sessionID
 * @return string
 */
function generateAsyncKey($sessionID)
{
    $key = 'session:'.$sessionID.':async';

    return $key;
}

class RedisDriver implements ConcurrentDriver
{
    /**
     * @var \Predis\Client
     */
    private $redisClient;

    /**
     * @var string The lock key, this is consistent per sessionID.
     */
    protected $lockKey;

    /**
     * @var Serializer
     */
    private $serializer;

    /**
     * @var IdGenerator
     */
    private $idGenerator;

    /**
     * Redis lua script for releasing a lock. Returns int(1) when the lock was
     * released correctly, otherwise returns 0
     *
     * Todo - upgrade to a fault tolerant distributed version of this.
     * https://github.com/ronnylt/redlock-php/blob/master/src/RedLock.php
     * http://redis.io/topics/distlock
     *
     */
    const unlockScript = <<< END
if redis.call("get",KEYS[1]) == ARGV[1]
then
    return redis.call("del",KEYS[1])
else
    return 0
end
END;

    /**
     * KEYS[1] == lock key
     * ARGV[1] == lock token
     * ARGV[2] == lock time in milliseconds.
     *
     * If the token is correct - renew the session
     * If there is no lock current - renewing the lock is fine
     * Otherwise return error message.
     */
    const renewLockScript = <<< END
local token = redis.call("get",KEYS[1])
if (token == ARGV[1])
then
    return redis.call("PSETEX",KEYS[1],ARGV[2],ARGV[1])
elseif not token
then
    return "Lock token not found"
else
    return "Lock token not found"
end
END;

    function __construct(
        RedisClient $redisClient,
        Serializer $serializer = null,
        IdGenerator $idGenerator = null)
    {
        $this->redisClient = $redisClient;

        if ($serializer) {
            $this->serializer = $serializer;
        }
        else {
            $this->serializer = new \ASM\Serializer\PHPSerializer();
        }

        if ($idGenerator) {
            $this->idGenerator = $idGenerator;
        }
        else {
            $this->idGenerator = new \ASM\IdGenerator\RandomLibIdGenerator();
        }
    }

    /**
     * Open an existing session. Returns either the session data or null if
     * the session could not be found.
     * @param $sessionId
     * @param SessionManager $sessionManager
     * @param null $userProfile
     * @throws AsmException
     * @return null|string
     */
    function openSessionByID($sessionId, SessionManager $sessionManager, $userProfile = null)
    {
        $sessionId = (string)$sessionId;

        $lockToken = $this->acquireLockIfRequired($sessionId, $sessionManager);

        $dataKey = generateSessionDataKey($sessionId);
        $dataString = $this->redisClient->get($dataKey);
        if ($dataString == null) {
            if ($lockToken !== null) {
                $this->releaseLock($sessionId, $lockToken);
            }
            return null;
        }

        $fullData = $this->serializer->unserialize($dataString);
        $currentProfiles = [];
        $data = [];

        if (isset($fullData['profiles'])) {
            $currentProfiles = $fullData['profiles'];
        }

        if (isset($fullData['data'])) {
            $data = $fullData['data'];
            //Data was not found?
        }

        $currentProfiles = $sessionManager->performProfileSecurityCheck(
            $userProfile,
            $currentProfiles
        );

        return new RedisSession(
            $sessionId,
            $this,
            $sessionManager,
            $data,
            $currentProfiles,
            true,
            $lockToken
        );
    }

    private function acquireLockIfRequired($sessionId, SessionManager $sessionManager)
    {
        $lockToken = null;
        if ($sessionManager->getLockMode() == SessionConfig::LOCK_ON_OPEN) {
            $lockToken = $this->acquireLock(
                $sessionId,
                $sessionManager->getSessionConfig()->getLockMilliSeconds(),
                $sessionManager->getSessionConfig()->getMaxLockWaitTimeMilliseconds()
            );
        }

        return $lockToken;
    }

    /**
     * Create a new session
     * @return RedisSession
     * @param SessionManager $sessionManager
     * @param null $userProfile
     * @throws AsmException
     */
    function createSession(SessionManager $sessionManager, $userProfile = null)
    {
        $sessionLifeTime = $sessionManager->getSessionConfig()->getLifetime();
        $initialData = [];
        $profiles = [];
        if ($userProfile) {
            $profiles = [$userProfile];
        }
        $initialData['profiles'] = $profiles;
        $initialData['data'] = [];
        $dataString = $this->serializer->serialize($initialData);

        $lockToken = null;

        for ($count = 0; $count < 10; $count++) {
            $sessionId = $this->idGenerator->generateSessionID();
            $lockToken = $this->acquireLockIfRequired($sessionId, $sessionManager);
            $dataKey = generateSessionDataKey($sessionId);
            $set = $this->redisClient->set(
                $dataKey,
                $dataString,
                'EX',
                $sessionLifeTime,
                'NX'
            );

            if ($set) {
                return new RedisSession(
                    $sessionId,
                    $this,
                    $sessionManager,
                    [],
                    $profiles,
                    false,
                    $lockToken
                );
            }

            if ($lockToken !== null) {
                $this->releaseLock($sessionId, $lockToken);
            }
        }

        throw new AsmException(
            "Failed to createSession.",
            AsmException::ID_CLASH
        );
    }

    /**
     * @param $sessionID
     * @return mixed|void
     */
    function deleteSessionByID($sessionID)
    {
        $dataKey = generateSessionDataKey($sessionID);
        $this->redisClient->del($dataKey);
    }

    /**
     * @param $sessionID
     * @param $saveData
     * @param $existingProfiles
     */
    function save(Session $session, $saveData, $existingProfiles)
    {
        $sessionID = $session->getSessionId();
        $sessionLifeTime = 3600; // 1 hour

        $data = [];
        $data['data'] = $saveData;
        $data['profiles'] = $existingProfiles;

        $dataKey = generateSessionDataKey($sessionID);
        $dataString = $this->serializer->serialize($data);
        $written = $this->redisClient->set(
            $dataKey,
            $dataString,
            'EX',
            $sessionLifeTime
        );

        if (!$written) {
            throw new AsmException("Failed to save data", AsmException::IO_ERROR);
        }
    }

//
//    /**
//     * Destroy expired sessions.
//     */
//    function destroyExpiredSessions() {
//        // Nothing to do for redis driver as redis automatically clears dead keys
//    }

    /**
     * @param $sessionID
     * @return bool
     */
    function validateLock($sessionID, $lockToken) {
        if (!$lockToken) {
            return false;
        }

        $lockKey = generateLockKey($sessionID);
        $storedLockNumber = $this->redisClient->get($lockKey);

        if ($storedLockNumber === $lockToken) {
            return true;
        }

        return false;
    }

    /**
     * @param $sessionID
     * @param $lockTimeMS
     * @param $acquireTimeoutMS
     * @return string LockToken
     * @throws FailedToAcquireLockException
     */
    function acquireLock($sessionID, $lockTimeMS, $acquireTimeoutMS)
    {
        $lockKey = generateLockKey($sessionID);
        $lockToken = $this->idGenerator->generateSessionID();
        $finished = false;

        $giveUpTime = ((int)(microtime(true) * 1000)) + $acquireTimeoutMS;

        do {
            $set = $this->redisClient->set(
                $lockKey,
                $lockToken,
                'PX',
                $lockTimeMS,
                'NX'
            );
            /** @var $set \Predis\Response\Status */

            if ($set == "OK") {
                $finished = true;
            } else if ($giveUpTime < ((int)(microtime(true) * 1000))) {
                throw new FailedToAcquireLockException(
                    "Failed to acquire lock for session $sessionID"
                );
            }
        } while ($finished === false);

        return $lockToken;
    }

    /**
     * @param $sessionId
     * @param $lockToken
     * @return mixed
     * @throws LostLockException
     */
    function releaseLock($sessionId, $lockToken)
    {
        $lockKey = generateLockKey($sessionId);
        $result = $this->redisClient->eval(self::unlockScript, 1, $lockKey, $lockToken);

        // TODO - should
//        if ($result !== 1) {
//            throw new LostLockException(
//                "Releasing lock revealed lock had been lost."
//            );
//        }

        return $result;
    }

    /**
     * @param $sessionID
     * @return mixed|void
     */
    function forceReleaseLockByID($sessionID)
    {
        $lockKey = generateLockKey($sessionID);
        $this->redisClient->del($lockKey);
    }

    /**
     * @param $sessionID
     * @param $lockToken
     * @param $lockTimeMS
     * @return mixed
     * @throws LostLockException
     */
    function renewLock($sessionID, $lockToken, $lockTimeMS)
    {
        $lockKey = generateLockKey($sessionID);
        $result = $this->redisClient->eval(
            self::renewLockScript,
            1,
            $lockKey,
            $lockToken,
            $lockTimeMS
        );

        if ($result != "OK") {
            throw new LostLockException("Failed to renew lock.");
        }

        return $result;
    }

//
//    /**
//     * @param $sessionID
//     * @return string
//     */
//    function findSessionIDFromZombieID($sessionID) {
//        $zombieKeyName = generateZombieKey($sessionID);
//        $regeneratedSessionID = $this->redisClient->get($zombieKeyName);
//
//        return $regeneratedSessionID;
//    }
//
//
//    /**
//     * @param $dyingSessionID
//     * @param $newSessionID
//     * @param $zombieTimeMilliseconds
//     * @return mixed|void
//     */
//    function setupZombieID($dyingSessionID,  $zombieTimeMilliseconds) {
//        $newSessionID = $sessionID = $this->idGenerator->generateSessionID();;
//        $zombieKey = generateZombieKey($dyingSessionID);
//        $this->redisClient->set(
//            $zombieKey,
//            $newSessionID,
//            'EX',
//            $zombieTimeMilliseconds
//        );
//
//        //TODO - combine this operation with the setting of the zombie key to avoid
//        //any possibility for a race condition.
//
//        //TODO - need to rename all the metadata keys.
//        // or maybe use RENAMENX ?
//        $this->redisClient->rename(
//            generateSessionDataKey($dyingSessionID),
//            generateSessionDataKey($newSessionID)
//        );
//
//        return $newSessionID;
//    }

    /**
     * @param $sessionID
     * @param $index
     * @return int
     */
    function get($sessionID, $index) {
        $key = generateAsyncKey($sessionID, $index);

        return $this->redisClient->hget($key, $index);
    }

    /**
     * @param $sessionID
     * @param $index
     * @param $value
     * @return int
     */
    function set($sessionID, $index, $value) {
        $key = generateAsyncKey($sessionID, $index);

        return $this->redisClient->hset($key, $index, $value);
    }

    /**
     * @param $sessionID
     * @param $index
     * @param $increment
     * @return int
     */
    function increment($sessionID, $index, $increment) {
        $key = generateAsyncKey($sessionID, $index);

        return $this->redisClient->hincrby($key, $index, $increment);
    }

    /**
     * @param $sessionID
     * @param $index
     * @return array
     */
    function getList($sessionID, $index) {
        $key = generateAsyncKey($sessionID, $index);

        return $this->redisClient->lrange($key, 0, -1);
    }

    /**
     * @param $sessionID
     * @param $index
     * @param $value
     * @return int
     */
    function appendToList($sessionID, $index, $value) {

        $key = generateAsyncKey($sessionID, $index);

        if (is_array($value)) {
            return $this->redisClient->rpush($key, $value);
        }
        else {
            return $this->redisClient->rpush($key, [$value]);
        }
    }

    /**
     * @param $sessionID
     * @param $index
     * @return int
     */
    function clearList($sessionID, $index) {
        $key = generateAsyncKey($sessionID, $index);
        return $this->redisClient->del($key);
    }
}


<?php

namespace Addons\Core\Http\Response;

use Addons\Core\File\Mimes;
use Addons\Core\Tools\Office;
use Addons\Core\Http\Response\TextResponse;
use Symfony\Component\HttpFoundation\Request;

class OfficeResponse extends TextResponse {

	//protected $type = 'office';

	public function getFormatter()
	{
		if ($this->formatter == 'auto')
		{
			$request = app('request');
			$of = $request->input('of', null);
			if (!in_array($of, ['csv', 'xls', 'xlsx']))
				$of = 'xlsx';
			return $of;
		}
		return $this->formatter;
	}

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

	public function prepare(Request $request)
	{
		$data = $this->getOutputData();
		$of = $this->getFormatter();
		$response = null;
		switch ($of) {
			case 'csv':
			case 'xls':
			case 'xlsx':
				$filename = Office::$of($data);
				$response = response()->download($filename, date('YmdHis').'.'.$of, ['Content-Type' =>  Mimes::getInstance()->mime_by_ext($of)])->deleteFileAfterSend(true)->setStatusCode($this->getStatusCode());
				break;
		}
		return $response;
	}

}


<?php
/**
 * Inventory
 *
 * PHP Version 5.3 -> 5.4
 * SugarCRM Versions 6.5 - 7.6
 *
 * @author Rémi Sauvat
 * @copyright 2005-2015 iNet Process
 *
 * @package inetprocess/inventory
 *
 * @license GNU General Public License v2.0
 *
 * @link http://www.inetprocess.com
 */

namespace Inet\Inventory;

use Guzzle\Service\Client as GClient;
use Guzzle\Service\Description\ServiceDescription;
use Guzzle\Http\Exception\ClientErrorResponseException;
use Psr\Log\LoggerInterface;
use Inet\Inventory\Facter\FacterInterface;

/**
 * Send gathered facts to Inventory server.
 */
class Agent
{
    protected $facters;
    protected $logger;
    protected $client;
    protected $account_name;

    const SYSTEM = 0;
    const SUGARCRM = 1;

    public function __construct(LoggerInterface $logger, GClient $client, $account_name = '')
    {
        $this->facters = array();
        $this->logger = $logger;
        $this->account_name = $account_name;

        $this->client = $client;
        $this->client->setDescription(
            ServiceDescription::factory(__DIR__ . '/InventoryService.json')
        );
    }

    public function setFacter(FacterInterface $facter, $type)
    {
        $this->facters[$type] = $facter;
    }

    public function getFacter($type)
    {
        if (!isset($this->facters[$type])) {
            throw new \RuntimeException('No facter found for this type. Please set the facter object first.');
        }

        return $this->facters[$type];
    }

    public function getFacts($type)
    {
        return $this->getFacter($type)->getFacts();
    }

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

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

    public function getServerFqdn()
    {
        $facts = $this->getFacts(self::SYSTEM);

        return $facts['fqdn'];
    }

    public function getAccountId($account_name)
    {
        return $this->getEntityId('Account', 'name', $account_name);
    }

    public function getServerId($server_fqdn)
    {
        return $this->getEntityId('Server', 'fqdn', $server_fqdn);
    }

    private function getEntityId($entity_name, $key_id, $search)
    {
        $client = $this->getClient();
        try {
            $cmd = $client->getCommand('get' . $entity_name, array($key_id => $search));
            $entity = $cmd->execute();
            $id = $entity->get('id');
        } catch (ClientErrorResponseException $e) {
            if ($e->getResponse()->getStatusCode() === 404) {
                $id = null;
            } else {
                throw $e;
            }
        }

        return $id;
    }

    public function sendServer()
    {
        $this->getLogger()->info('Fetching system facts.');
        $facts = $this->getFacts(self::SYSTEM);
        $fqdn = $facts['fqdn'];
        $server_data = array(
            'fqdn' => $fqdn,
            'facts' => $facts,
        );
        $this->sendEntity('Server', $server_data, 'fqdn');
    }

    public function sendAccount()
    {
        $this->sendEntity(
            'Account',
            array('name' => $this->account_name),
            'name'
        );
    }

    public function sendSugarInstance($server_id = null, $account_id = null)
    {
        $this->getLogger()->info('Fetch sugarcrm facts.');
        $facts = $this->getFacts(self::SUGARCRM);
        $sugar_data = array(
            'instance_id' => $facts['instance_id'],
            'facts' => $facts,
        );
        if (!is_null($server_id)) {
            $sugar_data['server'] = $server_id;
        }
        if (!is_null($account_id)) {
            $sugar_data['account'] = $account_id;
        }
        $this->sendEntity('SugarInstance', $sugar_data, 'instance_id');
    }

    /**
     * Send an entity.
     * Try put first if 404 create it with POST.
     *
     * @param string $entity_name Entity name in CamelCase
     * @param array  $data        Entity data to send.
     * @param string $key_id      Key of data to use as an id for the request.
     */
    private function sendEntity($entity_name, array $data, $key_id)
    {
        $client = $this->getClient();
        $this->getLogger()->info('Sending new ' . $entity_name . '.');
        try {
            $this->getLogger()->info('Try to PUT data to existing ' . $entity_name . ' record.');
            $data[$key_id . '_uri'] = $data[$key_id];
            $client->getCommand('put' . $entity_name, $data)
                ->execute();
        } catch (ClientErrorResponseException $e) {
            if ($e->getResponse()->getStatusCode() === 404) {
                // The server doesn't exist yet. We need to POST it.
                $this->getLogger()->info($entity_name . ' was not found on PUT request. Doing POST to create it.');
                $client->getCommand('post' . $entity_name, $data)
                    ->execute();
            } else {
                // This is not a 404 error, throw the exception.
                throw $e;
            }
        }
        $this->getLogger()->info('The ' . $entity_name . ' information has been successfully sent.');
    }

    public function sendAll()
    {
        $this->sendServer();
        $server_id = $this->getServerId($this->getServerFqdn());
        $this->sendAccount();
        $account_id = $this->getAccountId($this->account_name);
        $this->sendSugarInstance($server_id, $account_id);
    }
}


<?php
/**
 * Inventory
 *
 * PHP Version 5.3 -> 5.4
 * SugarCRM Versions 6.5 - 7.6
 *
 * @author Rémi Sauvat
 * @copyright 2005-2015 iNet Process
 *
 * @package inetprocess/inventory
 *
 * @license GNU General Public License v2.0
 *
 * @link http://www.inetprocess.com
 */

namespace Inet\Inventory\Facter;

use Symfony\Component\Finder\Finder;

class ProviderFacter implements FacterInterface
{
    /**
     * Directory where providers can be found
     *
     * @var
     */
    protected $providers_dir;
    /**
     * Namespace for the providers in the directory
     *
     * @var
     */
    protected $providers_namespace;

    /**
     * Array of provider objects
     */
    protected $providers;

    /**
     * Array of resulting facts
     */
    protected $facts;

    public function __construct($providers_dir, $providers_namespace)
    {
        $this->facts = null;

        $this->providers_dir = $providers_dir;
        $this->providers_namespace = $providers_namespace;

        $this->providers = array();
        $this->registerProviders();
    }

    /**
     * List the files in the providers dir to create new objects.
     */
    public function registerProviders()
    {
        $finder = new Finder();
        $finder->files()
            ->ignoreUnreadableDirs()
            ->in($this->providers_dir)
            ->sortByName()
            ->name('*.php');
        foreach ($finder as $provider) {
            $this->registerProviderFromFile($provider);
        }
    }

    /**
     * Factory method to create provider classes.
     * Usefull to override this method in child classes to inject into provider classes
     */
    public function factory($class_name)
    {
        return new $class_name();
    }

    /**
     * Instantiate a provider from a file
     */
    public function registerProviderFromFile(\SplFileInfo $provider_file)
    {
        $class_name = $this->providers_namespace . '\\' . $provider_file->getBasename('.php');
        $this->addProvider($this->factory($class_name));
    }

    /**
     * Add a provider object directly
     */
    public function addProvider(FacterInterface $provider)
    {
        $this->providers[] = $provider;
    }

    /**
     * Fetch the facts from the providers
     */
    public function getFacts($cached = true)
    {
        if (is_null($this->facts)) {
            $this->populateFacts();
        }

        return $this->facts;
    }

    /**
     * Fill from facts from providers for caching.
     */
    public function populateFacts()
    {
        $this->facts = array();
        foreach ($this->providers as $provider) {
            $this->facts = array_replace_recursive($this->facts, $provider->getFacts());
        }
    }
}


<?php
/**
 * PX Commands "api"
 */
namespace picklesFramework2\commands;

/**
 * PX Commands "api"
 *
 * ## [API] api.get.*
 *
 *

 *
PX=api.get.version

 *
Pickles Framework のバージョン番号を取得します。

 *
PX=api.get.config

 *
設定オブジェクトを取得します。

 *
 *
PX=api.get.sitemap

 *
サイトマップ全体の配列を取得します。$px->site()が利用できない場合、falseを返します。

 *
PX=api.get.page_info&path={$path}

 *
$px->site()->get_page_info({$path}) の返却値を取得します。$pathを省略した場合は、カレントページの情報を取得します。$px->site()が利用できない場合、falseを返します。

 *
PX=api.get.page_originated_csv&path={$path}

 *
$px->site()->get_page_originated_csv({$path}) の返却値を取得します。$pathを省略した場合は、カレントページの情報を取得します。$px->site()が利用できない場合、falseを返します。

 *
PX=api.get.parent

 *
$px->site()->get_parent() の返却値を取得します。$px->site()が利用できない場合、falseを返します。

 *
PX=api.get.actors

 *
$px->site()->get_actors() の返却値を取得します。$px->site()が利用できない場合、falseを返します。

 *
PX=api.get.role

 *
$px->site()->get_role() の返却値を取得します。$px->site()が利用できない場合、falseを返します。

 *
PX=api.get.children&filter={$filter}

 *
$px->site()->get_children() の返却値を取得します。$px->site()が利用できない場合、falseを返します。

 *
PX=api.get.bros&filter={$filter}

 *
$px->site()->get_bros() の返却値を取得します。$px->site()が利用できない場合、falseを返します。

 *
PX=api.get.bros_next&filter={$filter}

 *
$px->site()->get_bros_next() の返却値を取得します。$px->site()が利用できない場合、falseを返します。

 *
PX=api.get.bros_prev&filter={$filter}

 *
$px->site()->get_bros_prev() の返却値を取得します。$px->site()が利用できない場合、falseを返します。

 *
PX=api.get.next&filter={$filter}

 *
$px->site()->get_next() の返却値を取得します。$px->site()が利用できない場合、falseを返します。

 *
PX=api.get.prev&filter={$filter}

 *
$px->site()->get_prev() の返却値を取得します。$px->site()が利用できない場合、falseを返します。

 *
PX=api.get.breadcrumb_array

 *
$px->site()->get_breadcrumb_array() の返却値を取得します。$px->site()が利用できない場合、falseを返します。

 *
PX=api.get.dynamic_path_info&path={$path}

 *
$px->site()->get_dynamic_path_info({$path}) の返却値を取得します。$px->site()が利用できない場合、falseを返します。

 *
PX=api.get.bind_dynamic_path_param&path={$path}&param={$param}

 *
$px->site()->bind_dynamic_path_param({$path}, {$param}) の返却値を取得します。{$param} には、パラメータのキーと値の組を必要分格納したオブジェクトをJSON形式の文字列で指定します。$px->site()が利用できない場合、falseを返します。

 *
 *
PX=api.get.path_homedir

 *
*[非推奨]* このAPIは PX=api.get.realpath_homedir に改名されました。 古い名前も残されていますが、使用は推奨されません。

 *
PX=api.get.realpath_homedir

 *
$px->get_realpath_homedir() の返却値を取得します。

 *
PX=api.get.path_controot

 *
$px->get_path_controot() の返却値を取得します。

 *
PX=api.get.path_docroot

 *
*[非推奨]* このAPIは PX=api.get.realpath_docroot に改名されました。 古い名前も残されていますが、使用は推奨されません。

 *
PX=api.get.realpath_docroot

 *
$px->get_realpath_docroot() の返却値を取得します。

 *
PX=api.get.path_content

 *
$px->get_path_content() の返却値を取得します。

 *
PX=api.get.path_files&path_resource={$path}

 *
$px->path_files({$path}) の返却値を取得します。$px->site()が利用できない場合、falseを返します。

 *
PX=api.get.realpath_files&path_resource={$path}

 *
$px->realpath_files({$path}) の返却値を取得します。$px->site()が利用できない場合、falseを返します。

 *
PX=api.get.path_files_cache&path_resource={$path}

 *
$px->path_files_cache({$path}) の返却値を取得します。$px->site()が利用できない場合、falseを返します。

 *
PX=api.get.realpath_files_cache&path_resource={$path}

 *
$px->realpath_files_cache({$path}) の返却値を取得します。$px->site()が利用できない場合、falseを返します。

 *
PX=api.get.realpath_files_private_cache&path_resource={$path}

 *
$px->realpath_files_private_cache({$path}) の返却値を取得します。$px->site()が利用できない場合、falseを返します。

 *
PX=api.get.domain

 *
$px->get_domain() の返却値を取得します。

 *
PX=api.get.directory_index

 *
$px->get_directory_index() の返却値を取得します。

 *
PX=api.get.directory_index_primary

 *
$px->get_directory_index_primary() の返却値を取得します。

 *
PX=api.get.path_proc_type

 *
$px->get_path_proc_type() の返却値を取得します。

 *
PX=api.get.href&linkto={$path_linkto}

 *
$px->href({$path_linkto}) の返却値を取得します。$px->site()が利用できない場合、falseを返します。

 *
PX=api.get.canonical&linkto={$path_linkto}

 *
$px->canonical({$path_linkto}) の返却値を取得します。$px->site()が利用できない場合、falseを返します。

 *

 *
 * ## [API] api.is.*
 *
 *

 *
PX=api.is.match_dynamic_path&path={$path}

 *
$px->site()->is_match_dynamic_path({$path}) の返却値を取得します。

 *
PX=api.is.page_in_breadcrumb&path={$path}

 *
$px->site()->is_page_in_breadcrumb({$path}) の返却値を取得します。

 *
PX=api.is.ignore_path&path={$path}

 *
$px->is_ignore_path({$path}) の返却値を取得します。

 *

 */
class api{

	/**
	 * Picklesオブジェクト
	 */
	private $px;

	/**
	 * PXコマンド名
	 */
	private $command = array();

	/**
	 * Starting function
	 * @param object $px Picklesオブジェクト
	 */
	public static function register( $px ){
		$px->pxcmd()->register('api', function($px){
			(new self( $px ))->kick();
			exit;
		});
	}

	/**
	 * constructor
	 *
	 * @param object $px Picklesオブジェクト
	 */
	public function __construct( $px ){
		$this->px = $px;
	}

	/**
	 * kick
	 */
	private function kick(){

		$this->command = $this->px->get_px_command();

		switch( @$this->command[1] ){
			case 'get':
				//各種情報の取得
				$this->api_get();
				break;
			case 'is':
				//各種情報の評価
				$this->api_is();
				break;
			// case 'dlfile':
			// 	//ファイルダウンロード
			// 	$this->api_dlfile();
			// 	break;
			// case 'ulfile':
			// 	//ファイルアップロード
			// 	$this->api_ulfile();
			// 	break;
			// case 'ls':
			// 	//ファイルの一覧を取得
			// 	$this->api_ls();
			// 	break;
			// case 'delete':
			// 	//ファイル削除
			// 	$this->api_delete();
			// 	break;
			// case 'hash':
			// 	//ハッシュ値を取得
			// 	$this->api_hash();
			// 	break;
		}

		if( !strlen( @$this->command[1] ) ){
			$this->homepage();
		}
		$this->error();
		exit;
	}

	/**
	 * ホームページを表示する。
	 *
	 * HTMLを標準出力した後、`exit()` を発行してスクリプトを終了します。
	 *
	 * @return void
	 */
	private function homepage(){
		$this->user_message('このコマンドは、外部アプリケーションへのAPIを提供します。');
		exit;
	}

	/**
	 * エラーメッセージを表示する。
	 *
	 * HTMLを標準出力した後、`exit()` を発行してスクリプトを終了します。
	 *
	 * @return void
	 */
	private function error(){
		$this->user_message('未定義のコマンドを受け付けました。');
		exit;
	}

	/**
	 * ユーザーへのメッセージを表示して終了する
	 * @param string $msg メッセージテキスト
	 */
	private function user_message($msg){
		if( $this->px->req()->is_cmd() ){
			header('Content-type: text/plain;');
			print $this->px->pxcmd()->get_cli_header();
			print $msg."\n";
			print $this->px->pxcmd()->get_cli_footer();
		}else{
			$html = '';
			ob_start(); ?>

<?= htmlspecialchars($msg) ?>

<?php
			$html .= ob_get_clean();
			print $this->px->pxcmd()->wrap_gui_frame($html);
		}
		exit;
	}

	/**
	 * [API] api.get.*
	 *
	 * 結果を標準出力した後、`exit()` を発行してスクリプトを終了します。
	 *
	 * @return void
	 */
	private function api_get(){
		$sitemap_filter_options = function($px, $cmd=null){
			$options = array();
			$options['filter'] = $px->req()->get_param('filter');
			if( strlen($options['filter']) ){
				switch( $options['filter'] ){
					case 'true':
					case '1':
						$options['filter'] = true;
						break;
					case 'false':
					case '0':
						$options['filter'] = false;
						break;
				}
			}
			return $options;
		};

		switch( $this->command[2] ){
			case 'version':
				$val = $this->px->get_version();
				print $this->data_convert( $val );
				break;
			case 'config':
				$val = $this->px->conf();
				print $this->data_convert( $val );
				break;
			case 'sitemap':
				$val = ($this->px->site() ? $this->px->site()->get_sitemap() : false);
				print $this->data_convert( $val );
				break;
			case 'page_info':
				$path = $this->px->req()->get_param('path');
				if( is_null($path) ){
					$path = $this->px->req()->get_request_file_path();
				}
				$val = ($this->px->site() ? $this->px->site()->get_page_info($path) : false);
				print $this->data_convert( $val );
				break;
			case 'page_originated_csv':
				$path = $this->px->req()->get_param('path');
				if( is_null($path) ){
					$path = $this->px->req()->get_request_file_path();
				}
				$val = ($this->px->site() ? $this->px->site()->get_page_originated_csv($path) : false);
				print $this->data_convert( $val );
				break;
			case 'parent':
				$val = ($this->px->site() ? $this->px->site()->get_parent() : false);
				print $this->data_convert( $val );
				break;
			case 'actors':
				$val = ($this->px->site() ? $this->px->site()->get_actors() : false);
				print $this->data_convert( $val );
				break;
			case 'role':
				$val = ($this->px->site() ? $this->px->site()->get_role() : false);
				print $this->data_convert( $val );
				break;
			case 'children':
				$val = ($this->px->site() ? $this->px->site()->get_children(null, $sitemap_filter_options($this->px, $this->command[2])) : false);
				print $this->data_convert( $val );
				break;
			case 'bros':
				$val = ($this->px->site() ? $this->px->site()->get_bros(null, $sitemap_filter_options($this->px, $this->command[2])) : false);
				print $this->data_convert( $val );
				break;
			case 'bros_next':
				$val = ($this->px->site() ? $this->px->site()->get_bros_next(null, $sitemap_filter_options($this->px, $this->command[2])) : false);
				print $this->data_convert( $val );
				break;
			case 'bros_prev':
				$val = ($this->px->site() ? $this->px->site()->get_bros_prev(null, $sitemap_filter_options($this->px, $this->command[2])) : false);
				print $this->data_convert( $val );
				break;
			case 'next':
				$val = ($this->px->site() ? $this->px->site()->get_next(null, $sitemap_filter_options($this->px, $this->command[2])) : false);
				print $this->data_convert( $val );
				break;
			case 'prev':
				$val = ($this->px->site() ? $this->px->site()->get_prev(null, $sitemap_filter_options($this->px, $this->command[2])) : false);
				print $this->data_convert( $val );
				break;
			case 'breadcrumb_array':
				$val = ($this->px->site() ? $this->px->site()->get_breadcrumb_array() : false);
				print $this->data_convert( $val );
				break;
			case 'dynamic_path_info':
				$val = ($this->px->site() ? $this->px->site()->get_dynamic_path_info($this->px->req()->get_param('path')) : false);
				print $this->data_convert( $val );
				break;
			case 'bind_dynamic_path_param':
				$param = $this->px->req()->get_param('param');
				$param = @json_decode( $param, true );
				$val = ($this->px->site() ? $this->px->site()->bind_dynamic_path_param($this->px->req()->get_param('path'), $param) : false);
				print $this->data_convert( $val );
				unset($param);
				break;
			case 'path_homedir': // deprecated
				$val = $this->px->get_realpath_homedir();
				print $this->data_convert( $val );
				break;
			case 'realpath_homedir':
				$val = $this->px->get_realpath_homedir();
				print $this->data_convert( $val );
				break;
			case 'path_controot':
				$val = $this->px->get_path_controot();
				print $this->data_convert( $val );
				break;
			case 'path_docroot': // deprecated
				$val = $this->px->get_realpath_docroot();
				print $this->data_convert( $val );
				break;
			case 'realpath_docroot':
				$val = $this->px->get_realpath_docroot();
				print $this->data_convert( $val );
				break;
			case 'path_content':
				$val = $this->px->get_path_content();
				print $this->data_convert( $val );
				break;
			case 'path_files':
				$val = ($this->px->site() ? $this->px->path_files($this->px->req()->get_param('path_resource')) : false);
				print $this->data_convert( $val );
				break;
			case 'realpath_files':
				$val = ($this->px->site() ? $this->px->realpath_files($this->px->req()->get_param('path_resource')) : false);
				print $this->data_convert( $val );
				break;
			case 'path_files_cache':
				$val = ($this->px->site() ? $this->px->path_files_cache($this->px->req()->get_param('path_resource')) : false);
				print $this->data_convert( $val );
				break;
			case 'realpath_files_cache':
				$val = ($this->px->site() ? $this->px->realpath_files_cache($this->px->req()->get_param('path_resource')) : false);
				print $this->data_convert( $val );
				break;
			case 'realpath_files_private_cache':
				$val = ($this->px->site() ? $this->px->realpath_files_private_cache($this->px->req()->get_param('path_resource')) : false);
				print $this->data_convert( $val );
				break;
			case 'domain':
				$val = $this->px->get_domain();
				print $this->data_convert( $val );
				break;
			case 'directory_index':
				$val = $this->px->get_directory_index();
				print $this->data_convert( $val );
				break;
			case 'directory_index_primary':
				$val = $this->px->get_directory_index_primary();
				print $this->data_convert( $val );
				break;
			case 'path_proc_type':
				$val = $this->px->get_path_proc_type();
				print $this->data_convert( $val );
				break;
			case 'href':
				$val = ($this->px->site() ? $this->px->href($this->px->req()->get_param('linkto')) : false);
				print $this->data_convert( $val );
				break;
			case 'canonical':
				$val = ($this->px->site() ? $this->px->canonical($this->px->req()->get_param('linkto')) : false);
				print $this->data_convert( $val );
				break;
			default:
				print $this->data_convert( array('result'=>0) );
				break;
		}
		exit;
	}

	/**
	 * [API] api.is.*
	 *
	 * 結果を標準出力した後、`exit()` を発行してスクリプトを終了します。
	 *
	 * @return void
	 */
	private function api_is(){
		switch( $this->command[2] ){
			case 'match_dynamic_path':
				$val = ($this->px->site() ? $this->px->site()->is_match_dynamic_path($this->px->req()->get_param('path')) : false);
				print $this->data_convert( $val );
				break;
			case 'page_in_breadcrumb':
				$val = ($this->px->site() ? $this->px->site()->is_page_in_breadcrumb($this->px->req()->get_param('path')) : false);
				print $this->data_convert( $val );
				break;
			case 'ignore_path':
				$val = $this->px->is_ignore_path($this->px->req()->get_param('path'));
				print $this->data_convert( $val );
				break;
			default:
				print $this->data_convert( array('result'=>0) );
				break;
		}
		exit;
	}

	/**
	 * データを自動的に加工して返す。
	 *
	 * @param mixed $val 加工するデータ
	 * @return string 加工されたテキストデータ
	 */
	private function data_convert($val){
		$data_type = $this->px->req()->get_param('type');
		if( !is_string($data_type) || !strlen($data_type) ){
			$data_type = 'json';
		}
		header('Content-type: application/xml; charset=UTF-8');
		if( $data_type == 'json' ){
			header('Content-type: application/json; charset=UTF-8');
		}elseif( $data_type == 'jsonp' ){
			header('Content-type: application/javascript; charset=UTF-8');
		}
		switch( $data_type ){
			case 'jsonp':
				return $this->data2jsonp($val);
				break;
			case 'json':
				return $this->data2json($val);
				break;
			case 'xml':
				return $this->data2xml($val);
				break;
		}
		// return self::data2jssrc($val);
		return json_encode($val);
	}

	/**
	 * データをXMLに加工して返す。
	 *
	 * @param mixed $val 加工するデータ
	 * @return string 加工されたテキストデータ
	 */
	private function data2xml($val){
		return '<api>'.self::xml_encode($val).'</api>';
	}

	/**
	 * データをJSONに加工して返す。
	 *
	 * @param mixed $val 加工するデータ
	 * @return string 加工されたテキストデータ
	 */
	private function data2json($val){
		// return self::data2jssrc($val);
		return json_encode($val);
	}

	/**
	 * データをJSONPに加工して返す。
	 *
	 * @param mixed $val 加工するデータ
	 * @return string 加工されたテキストデータ
	 */
	private function data2jsonp($val){
		//JSONPのコールバック関数名は、パラメータ callback に受け取る。
		$cb = trim( $this->px->req()->get_param('callback') );
		if( !strlen($cb) ){
			$cb = 'callback';
		}
		// return $cb.'('.self::data2jssrc($val).');';
		return $cb.'('.json_encode($val).');';
	}

	/**
	 * 変数をXML構造に変換する
	 *
	 * @param mixed $value 値
	 * @param array $options オプション
	 *

	 *
delete_arrayelm_if_null

	 *
配列の要素が `null` だった場合に削除。

	 *
array_break

	 *
配列に適当なところで改行を入れる。

	 *

	 * @return string XMLシンタックスに変換された値
	 */
	private static function xml_encode( $value = null , $options = array() ){

		if( is_array( $value ) ){
			#	配列
			$is_hash = false;
			$i = 0;
			foreach( $value as $key=>$val ){
				#	ArrayかHashか見極める
				if( !is_int( $key ) ){
					$is_hash = true;
					break;
				}
				if( $key != $i ){
					#	順番通りに並んでなかったらHash とする。
					$is_hash = true;
					break;
				}
				$i ++;
			}

			if( $is_hash ){
				$RTN .= '<object>';
			}else{
				$RTN .= '<array>';
			}
			if( $options['array_break'] ){ $RTN .= "\n"; }
			foreach( $value as $key=>$val ){
				if( $options['delete_arrayelm_if_null'] && is_null( $value[$key] ) ){
					#	配列のnull要素を削除するオプションが有効だった場合
					continue;
				}
				$RTN .= '<element';
				if( $is_hash ){
					$RTN .= ' name="'.htmlspecialchars( $key ).'"';
				}
				$RTN .= '>';
				$RTN .= self::xml_encode( $value[$key] , $options );
				$RTN .= '</element>';
				if( $options['array_break'] ){ $RTN .= "\n"; }
			}
			if( $is_hash ){
				$RTN .= '</object>';
			}else{
				$RTN .= '</array>';
			}
			if( $options['array_break'] ){ $RTN .= "\n"; }
			return	$RTN;
		}

		if( is_object( $value ) ){
			#	オブジェクト型
			$RTN = '';
			$RTN .= '<object>';
			$proparray = get_object_vars( $value );
			$methodarray = get_class_methods( get_class( $value ) );
			foreach( $proparray as $key=>$val ){
				$RTN .= '<element name="'.htmlspecialchars( $key ).'">';

				$RTN .= self::xml_encode( $val , $options );
				$RTN .= '</element>';
			}
			$RTN .= '</object>';
			return	$RTN;
		}

		if( is_int( $value ) ){
			#	数値
			$RTN = '<value type="int">'.htmlspecialchars( $value ).'</value>';
			return	$RTN;
		}

		if( is_float( $value ) ){
			#	浮動小数点
			$RTN = '<value type="float">'.htmlspecialchars( $value ).'</value>';
			return	$RTN;
		}

		if( is_string( $value ) ){
			#	文字列型
			$RTN = '<value type="string">'.htmlspecialchars( $value ).'</value>';
			return	$RTN;
		}

		if( is_null( $value ) ){
			#	ヌル
			return	'<value type="null"></value>';
		}

		if( is_resource( $value ) ){
			#	リソース型
			return	'<value type="undefined"></value>';
		}

		if( is_bool( $value ) ){
			#	ブール型
			if( $value ){
				return	'<value type="bool">true</value>';
			}else{
				return	'<value type="bool">false</value>';
			}
		}

		return	'<value type="undefined"></value>';

	}

	/**
	 * ダブルクオートで囲えるようにエスケープ処理する。
	 *
	 * @param string $text テキスト
	 * @return string エスケープされたテキスト
	 */
	private static function escape_doublequote( $text ){
		$text = preg_replace( '/\\\\/' , '\\\\\\\\' , $text);
		$text = preg_replace( '/"/' , '\\"' , $text);
		return	$text;
	}

}


<?php

namespace DDDominio\EventSourcing\Common;

abstract class EventSourcedAggregateRoot implements EventSourcedAggregateRootInterface
{
    /**
     * @var EventStream
     */
    private $changes;

    /**
     * @var int
     */
    private $version = 0;

    /**
     * @param mixed $domainEvent
     * @throws DomainEventNotUnderstandableException
     */
    public function applyAndRecord($domainEvent)
    {
        $domainEvent = $this->ensureDomainEvent($domainEvent);
        $this->apply($domainEvent);
        $this->record($domainEvent);
    }

    /**
     * Record a Domain Event
     *
     * @param mixed $domainEvent
     */
    private function record($domainEvent)
    {
        $this->ensureChangesEventStream();
        $this->changes = $this->changes->append($domainEvent);
    }

    private function ensureChangesEventStream()
    {
        if (is_null($this->changes)) {
            $this->clearChanges();
        }
    }

    /**
     * Apply a Domain Event to the aggregate
     *
     * @param mixed $domainEvent
     */
    public function apply($domainEvent)
    {
        $domainEvent = $this->ensureDomainEvent($domainEvent);
        $eventHandlerName = $this->getEventHandlerName($domainEvent);
        if (method_exists($this, $eventHandlerName)) {
            $this->executeEventHandler($this, $eventHandlerName, $domainEvent);
        } else {
            $this->applyRecursively($eventHandlerName, $domainEvent);
        }
    }

    /**
     * @param $domainEvent
     * @return DomainEvent
     */
    private function ensureDomainEvent($domainEvent)
    {
        if (!$domainEvent instanceof DomainEvent) {
            $domainEvent = DomainEvent::produceNow($domainEvent);
        }
        return $domainEvent;
    }

    /**
     * @param string $eventHandlerName
     * @param mixed $domainEventData
     * @throws DomainEventNotUnderstandableException
     */
    private function applyRecursively($eventHandlerName, $domainEventData)
    {
        $applied = false;
        $reflectedClass = new \ReflectionClass(get_class($this));
        foreach ($reflectedClass->getProperties() as $property) {
            $propertyValue = $this->{$property->getName()};
            if (is_object($propertyValue)) {
                if (method_exists($propertyValue, $eventHandlerName)) {
                    $this->executeEventHandler($propertyValue, $eventHandlerName, $domainEventData);
                    $applied = true;
                }
            }
            if (is_array($propertyValue)) {
                foreach ($propertyValue as $item) {
                    if (method_exists($item, $eventHandlerName)) {
                        $this->executeEventHandler($item, $eventHandlerName, $domainEventData);
                        $applied = true;
                    }
                }
            }
        }
        if (!$applied) {
            throw DomainEventNotUnderstandableException::fromAggreagteAndEventTypes(
                get_class($this),
                get_class($domainEventData)
            );
        }
    }

    /**
     * @param DomainEvent $domainEvent
     * @return string
     */
    private function getEventHandlerName($domainEvent)
    {
        return $this->eventHandlerPrefix() . (new \ReflectionClass($domainEvent->data()))->getShortName();
    }

    /**
     * @return string
     */
    protected function eventHandlerPrefix()
    {
        return 'when';
    }

    /**
     * @param object $entity
     * @param string $eventHandlerName
     * @param DomainEvent $domainEvent
     */
    private function executeEventHandler($entity, $eventHandlerName, $domainEvent)
    {
        $entity->{$eventHandlerName}($domainEvent->data(), $domainEvent->occurredOn());
        $this->increaseAggregateVersion();
    }

    private function increaseAggregateVersion()
    {
        $this->version++;
    }

    /**
     * Recorded stream of Domain Events
     *
     * @return EventStream
     */
    public function changes()
    {
        $this->ensureChangesEventStream();
        return $this->changes;
    }

    /**
     * Current version of the aggregate
     *
     * @return int
     */
    public function version()
    {
        return $this->version;
    }

    /**
     * The version of the aggregate before applying changes
     *
     * @return int
     */
    public function originalVersion()
    {
        return $this->version - count($this->changes());
    }

    /**
     * Removes recorded domain events
     */
    public function clearChanges()
    {
        $this->changes = EventStream::buildEmpty();
    }
}


<?php
/**
 * Project seo.
 * Created by PhpStorm.
 * User: 713uk13m <dev@nguyenanhung.com>
 * Date: 11/6/18
 * Time: 16:03
 */

namespace nguyenanhung\SEO\Social;

use nguyenanhung\SEO\ProjectInterface;
use nguyenanhung\SEO\Version;

/**
 * Class Twitter
 *
 * @package   nguyenanhung\SEO\Social
 * @author    713uk13m <dev@nguyenanhung.com>
 * @copyright 713uk13m <dev@nguyenanhung.com>
 */
class Twitter implements ProjectInterface, TwitterInterface
{
    use Version, SocialTrait;
    const SHARE_URI = 'https://twitter.com/intent/tweet';
    /** @var string Link dùng để nhúng share trên twitter */
    private $link;

    /**
     * Twitter constructor.
     */
    public function __construct()
    {
    }

    /**
     * Function createShareLink
     *
     * @author: 713uk13m <dev@nguyenanhung.com>
     * @time  : 11/6/18 16:09
     *
     * @param string $url
     * @param string $text
     * @param string $referer
     *
     * @return $this
     */
    public function createShareLink($url = '', $text = '', $referer = '')
    {
        if (empty($referer)) {
            $referer = $url;
        }
        $params     = array(
            'url'              => $url . '?utm_source=twitter&utm_medium=link_share&utm_campaign=twitter_share',
            'text'             => $text,
            'original_referer' => $referer
        );
        $this->link = self::SHARE_URI . '?' . http_build_query($params);

        return $this;
    }
}


<?php
/**
 * Project seo.
 * Created by PhpStorm.
 * User: 713uk13m <dev@nguyenanhung.com>
 * Date: 11/6/18
 * Time: 15:16
 */

namespace nguyenanhung\SEO;

/**
 * Class Utils
 *
 * @package   nguyenanhung\SEO
 * @author    713uk13m <dev@nguyenanhung.com>
 * @copyright 713uk13m <dev@nguyenanhung.com>
 */
class Utils
{
    /**
     * Function sendRequest
     *
     * @author: 713uk13m <dev@nguyenanhung.com>
     * @time  : 2018-12-31 01:48
     *
     * @param string $url
     * @param null   $params
     * @param string $method
     *
     * @return bool|null|string
     */
    public static function sendRequest($url = '', $params = NULL, $method = 'GET')
    {
        try {
            $method   = strtoupper($method);
            $endpoint = ((is_array($params) || is_object($params)) && !empty($params)) ? $url . '?' . http_build_query($params) : $url;
            $curl     = curl_init();
            curl_setopt_array($curl, array(
                CURLOPT_URL            => $endpoint,
                CURLOPT_RETURNTRANSFER => TRUE,
                CURLOPT_ENCODING       => "",
                CURLOPT_MAXREDIRS      => 10,
                CURLOPT_TIMEOUT        => 30,
                CURLOPT_HTTP_VERSION   => CURL_HTTP_VERSION_1_1,
                CURLOPT_CUSTOMREQUEST  => $method,
                CURLOPT_POSTFIELDS     => "",
                CURLOPT_HTTPHEADER     => array(),
            ));
            $response = curl_exec($curl);
            $err      = curl_error($curl);
            curl_close($curl);
            if ($err) {
                $message = "cURL Error #:" . $err;
                if (function_exists('log_message')) {
                    log_message('error', $message);
                }

                return NULL;
            } else {
                return $response;
            }
        }
        catch (\Exception $e) {
            $message = 'Error Code: ' . $e->getCode() . ' - File: ' . $e->getFile() . ' - Line: ' . $e->getLine() . ' - Message: ' . $e->getMessage();
            if (function_exists('log_message')) {
                log_message('error', $message);
            }

            return NULL;
        }
    }
}