<?php
/*
 * Copyright (c) 2012-2016, Hofmänner New Media.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This file is part of the N2N FRAMEWORK.
 *
 * The N2N FRAMEWORK is free software: you can redistribute it and/or modify it under the terms of
 * the GNU Lesser General Public License as published by the Free Software Foundation, either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * N2N is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details: http://www.gnu.org/licenses/
 *
 * The following people participated in this project:
 *
 * Andreas von Burg.....: Architect, Lead Developer
 * Bert Hofmänner.......: Idea, Frontend UI, Community Leader, Marketing
 * Thomas Günther.......: Developer, Hangar
 */
namespace n2n\impl\persistence\orm\property\relation\util;

use n2n\persistence\orm\property\BasicEntityProperty;
use n2n\persistence\orm\model\EntityModel;
use n2n\impl\persistence\orm\property\relation\selection\ArrayObjectProxy;
use n2n\util\type\ArgUtils;
use n2n\util\col\ArrayUtils;
use n2n\persistence\orm\store\ValueHash;
use n2n\util\ex\IllegalStateException;

class ToManyValueHasher {
	const PROXY_KEYWORD = 'proxy';
	private $targetIdProperty;

	public function __construct(BasicEntityProperty $targetIdProperty) {
		$this->targetIdProperty = $targetIdProperty;
	}

	public static function createFromEntityModel(EntityModel $entityModel) {
		return new ToManyValueHasher($entityModel->getIdDef()->getEntityProperty());
	}

// 	public static function extractIdReps(ValueHash $hash) {
// 		$hash = $hash->getHash();
// 		if (!is_array($hash)) {
// 			throw new \InvalidArgumentException('Ids not extractable from AccessProxy hash.');
// 			return array();
// 		}

// 		$idReps = array();
// 		foreach ($hash as $idRep) {
// 			if ($idRep !== null) {
// 				$idReps[$idRep] = $idRep;
// 			}
// 		}
// 		return $idReps;
// 	}

	public function reportId($key, $id, ToManyValueHash $valueHash) {
		$valueHash->reportIdRep($key, $this->targetIdProperty->valueToRep($id));
	}

	public function createValueHash($value) {
// 		if ($value === null) return new CommonValueHash(array());

		if ($value instanceof ArrayObjectProxy) {
			return ToManyValueHash::createFromArrayObjectProxy($value, $this);
		}

		return ToManyValueHash::createFromValue($value, $this);
// 		if ($value instanceof ArrayObjectProxy && $value->getLoadedValueHash() === $valueHash) {
// 			return $value->getId();
// 		}

// 		return $valueHash;
	}

	public function extractIdRepsMapFromValue($entities) {
		if ($entities === null) return array();

		ArgUtils::assertTrue(ArrayUtils::isArrayLike($entities));
		$entityIdReps = array();
		foreach ($entities as $key => $entity) {
			$id = $this->targetIdProperty->readValue($entity);
			if ($id === null) {
				$entityIdReps[$key] = null;
			} else {
				$entityIdReps[$key] = $this->targetIdProperty->valueToRep($id);
			}
		}
		return $entityIdReps;
	}

// 	public function createValueHashFromEntities($entities) {
// 		ArgUtils::assertTrue(ArrayUtils::isArrayLike($entities));
// 		$entityIdReps = array();
// 		foreach ($entities as $key => $entity) {
// 			$id = $this->targetIdProperty->readValue($entity);
// 			if ($id === null) {
// 				$entityIdReps[$key] = null;
// 			} else {
// 				$entityIdReps[$key] = $this->targetIdProperty->valueToRep($id);
// 			}
// 		}
// 		return new CommonValueHash($entityIdReps);
// 	}

// 	public static function isUntouchedProxy($value, $valueHash) {
// 		return $value instanceof ArrayObjectProxy && !$value->isInitialized()
// 				&& $valueHash === $value->getId();
// 	}

	public function matches(array $entityIds, ToManyValueHash $valueHash) {
		// this means that other array object has been asigned
		if (!$valueHash->isInitialized()) return false;

		$vhIdReps = $valueHash->getIdReps(true);

		foreach ($entityIds as $entityId) {
			$entityIdRep = $this->targetIdProperty->valueToRep($entityId);
			if (!isset($vhIdReps[$entityIdRep])) return false;
			unset($vhIdReps[$entityIdRep]);
		}

		return empty($vhIdReps);
	}

// 	public function findOrphanIdReps(array $entityIds, $valueHash) {
// 		$vhIdReps = self::extractIdReps($valueHash);

// 		foreach ($entityIds as $entityId) {
// 			$entityIdRep = $this->targetIdProperty->valueToRep($entityId);
// 			if (isset($vhIdReps[$entityIdRep])) {
// 				unset($vhIdReps[$entityIdRep]);
// 			}
// 		}

// 		return $vhIdReps;
// 	}
}

class ToManyValueHash implements ValueHash {
	protected $arrayObjectProxy;
	protected $idRepsMap;

	protected function __construct() {
	}

	public function isInitialized() {
		return $this->idRepsMap !== null;
	}

	public function initialize() {
		if ($this->arrayObjectProxy !== null) {
			$this->arrayObjectProxy->initialize();
			return;
		}

		throw new IllegalStateException('No uninitialized ArrayObjectProxy found.');
	}

	public function getIdRepsMap(bool $initialize = false) {
		if ($this->isInitialized()) {
			return $this->idRepsMap;
		} else if ($initialize) {
			$this->initialize();
			return $this->idRepsMap;
		}

		throw new IllegalStateException('ArrayObjectProxy not initialized.');
	}

	public function reportIdRep($key, $idRep) {
		IllegalStateException::assertTrue($this->idRepsMap !== null
				&& array_key_exists($key, $this->idRepsMap) && $this->idRepsMap[$key] === null);
		$this->idRepsMap[$key] = $idRep;
	}

	public function getIdReps(bool $initialize = false) {
		$idReps = array();
		foreach ($this->getIdRepsMap($initialize) as $key => $idRep) {
			if ($idRep === null) continue;
			$idReps[$key] = $idRep;
		}
		return $idReps;
	}

	/**
	 * {@inheritDoc}
	 * @see \n2n\persistence\orm\store\ValueHash::matches()
	 */
	public function matches(ValueHash $valueHash): bool {
		ArgUtils::assertTrue($valueHash instanceof ToManyValueHash);

		return $this->idRepsMap === $valueHash->idRepsMap
				&& $this->arrayObjectProxy === $valueHash->arrayObjectProxy;
	}

	public static function createFromArrayObjectProxy(ArrayObjectProxy $arrayObjectProxy, ToManyValueHasher $toManyValueHasher) {
		if ($arrayObjectProxy->isInitialized()) {
			return self::createFromValue($arrayObjectProxy, $toManyValueHasher);
		}

		$toManyValueHash = new ToManyValueHash();
		$toManyValueHash->arrayObjectProxy = $arrayObjectProxy;
		$arrayObjectProxy->whenInitialized(function () use ($arrayObjectProxy, $toManyValueHash, $toManyValueHasher) {
			$toManyValueHash->idRepsMap = $toManyValueHasher->extractIdRepsMapFromValue($arrayObjectProxy);
			$toManyValueHash->arrayObjectProxy = null;
		});
		return $toManyValueHash;
	}

	public static function createFromValue($value, ToManyValueHasher $toManyValueHasher) {
		$toManyValueHash = new ToManyValueHash();
		$toManyValueHash->idRepsMap = $toManyValueHasher->extractIdRepsMapFromValue($value);
		return $toManyValueHash;
	}

	public function checkForUntouchedProxy($value) {
		return $this->arrayObjectProxy !== null && $this->arrayObjectProxy === $value;
	}
}


<?php
/*
 * Copyright (c) 2012-2016, Hofmänner New Media.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This file is part of the N2N FRAMEWORK.
 *
 * The N2N FRAMEWORK is free software: you can redistribute it and/or modify it under the terms of
 * the GNU Lesser General Public License as published by the Free Software Foundation, either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * N2N is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details: http://www.gnu.org/licenses/
 *
 * The following people participated in this project:
 *
 * Andreas von Burg.....: Architect, Lead Developer
 * Bert Hofmänner.......: Idea, Frontend UI, Community Leader, Marketing
 * Thomas Günther.......: Developer, Hangar
 */
namespace n2n\impl\persistence\orm\property\relation;

use n2n\persistence\orm\query\from\MetaTreePoint;
use n2n\persistence\orm\query\QueryState;
use n2n\persistence\orm\FetchType;
use n2n\impl\persistence\orm\property\relation\selection\ToManyRelationSelection;
use n2n\persistence\orm\query\from\TreePath;
use n2n\impl\persistence\orm\property\relation\util\ToManyValueHasher;
use n2n\impl\persistence\orm\property\relation\compare\ToManyCustomComparable;
use n2n\persistence\orm\store\action\supply\SupplyJob;
use n2n\impl\persistence\orm\property\relation\util\ToManyUtils;
use n2n\persistence\orm\property\EntityProperty;
use n2n\persistence\orm\EntityManager;
use n2n\persistence\orm\model\EntityModel;
use n2n\persistence\orm\store\ValueHash;

class PropertyMappedToManyRelation extends MappedRelation implements ToManyRelation {
	private $toManyUtils;
	private $orderDirectives = array();

	public function __construct(EntityProperty $entityProperty, EntityModel $targetEntityModel,
			EntityProperty $targetEntityProperty) {
		parent::__construct($entityProperty, $targetEntityModel, $targetEntityProperty);
		$this->toManyUtils = new ToManyUtils($this, false);
	}

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

	public function setOrderDirectives(array $orderDirectives) {
		$this->orderDirectives = $orderDirectives;
	}

	public function createCustomComparable(MetaTreePoint $metaTreePoint, QueryState $queryState) {
		$toManyQueryItemFactory = $this->getMasterRelation()->createInverseJoinTableToManyQueryItemFactory(
				$this->getTargetEntityModel());

		return new ToManyCustomComparable($metaTreePoint, $this->targetEntityModel,
				$this->createTargetIdTreePath(), $toManyQueryItemFactory, $queryState);
	}
	/* (non-PHPdoc)
	 * @see \n2n\impl\persistence\orm\property\relation\Relation::createSelection()
	 */
	public function createSelection(MetaTreePoint $metaTreePoint, QueryState $queryState) {
		$idSelection = $metaTreePoint->requestPropertySelection(new TreePath(
				array($this->entityModel->getIdDef()->getPropertyName())));
		$toManyLoader = $this->getMasterRelation()->createInverseToManyLoader($this->targetEntityModel, $queryState);
		$toManyLoader->setOrderDirectives($this->orderDirectives);

		$toManySelection = new ToManyRelationSelection($idSelection, $toManyLoader,
				$this->getTargetIdEntityProperty());
		$toManySelection->setLazy($this->fetchType == FetchType::LAZY);
		return $toManySelection;
	}

	public function createValueHash($value, EntityManager $em): ValueHash {
		return ToManyValueHasher::createFromEntityModel($this->targetEntityModel)
				->createValueHash($value);
	}

	public function prepareSupplyJob(SupplyJob $supplyJob, $value, ?ValueHash $oldValueHash) {
		$this->toManyUtils->prepareSupplyJob($supplyJob, $value, $oldValueHash);
// 		if (!$this->orphanRemoval || $supplyJob->isInsert()) return;

// 		if (ToManyValueHasher::checkForUntouchedProxy($value, $oldValueHash)) {
// 			if (!$supplyJob->isRemove()) return;

// 			ArgUtils::assertTrue($value instanceof ArrayObjectProxy);
// 			$value->initialize();
// 			$oldValueHash = $value->getLoadedValueHash();
// 		}

// // 		if (ToManyValueHasher::checkForProxy($oldValueHash)) {
// // 			throw new NotYetImplementedException('PersistenceContext must be able to store ArrayObjectProxy by valueHash');
// // 		}

// 		$orphanRemover = new OrphanRemover($supplyJob, $this->targetEntityModel, $this->actionMarker);

// 		if (!$supplyJob->isRemove()) {
// 			ArgUtils::assertTrue(ArrayUtils::isArrayLike($value));
// 			foreach ($value as $entity) {
// 				$orphanRemover->releaseCandiate($entity);
// 			}
// 		}

// 		$orphanRemover->removeByIdReps(ToManyValueHasher::extractIdReps($oldValueHash));
	}
}


<?php
/*
 * Copyright (c) 2012-2016, Hofmänner New Media.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This file is part of the N2N FRAMEWORK.
 *
 * The N2N FRAMEWORK is free software: you can redistribute it and/or modify it under the terms of
 * the GNU Lesser General Public License as published by the Free Software Foundation, either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * N2N is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details: http://www.gnu.org/licenses/
 *
 * The following people participated in this project:
 *
 * Andreas von Burg.....: Architect, Lead Developer
 * Bert Hofmänner.......: Idea, Frontend UI, Community Leader, Marketing
 * Thomas Günther.......: Developer, Hangar
 */
namespace n2n\impl\persistence\orm\property\hangar\relation;

use hangar\api\HangarPropDef;
use hangar\api\PropSourceDef;
use n2n\util\type\attrs\Attributes;
use hangar\api\DbInfo;
use n2n\persistence\orm\property\EntityProperty;
use n2n\reflection\annotation\AnnotationSet;
use n2n\util\type\ArgUtils;
use n2n\persistence\orm\annotation\AnnoManyToOne;
use n2n\impl\persistence\orm\property\ToOneEntityProperty;
use hangar\api\ColumnDefaults;
use n2n\impl\persistence\orm\property\relation\JoinColumnToOneRelation;
use n2n\persistence\meta\structure\IndexType;
use n2n\persistence\meta\structure\Table;
use hangar\api\CompatibilityLevel;
use phpbob\representation\PhpTypeDef;
use phpbob\PhpbobUtils;
use hangar\api\HuoContext;
use n2n\web\dispatch\mag\MagCollection;
use n2n\persistence\meta\structure\Column;
use n2n\impl\persistence\orm\property\IntEntityProperty;

class ManyToOnePropDef implements HangarPropDef {
	protected $columnDefaults;
	private $huoContext;

	/**
	 * {@inheritDoc}
	 * @see \hangar\api\HangarPropDef::setup()
	 */
	public function setup(HuoContext $huoContext, ColumnDefaults $columnDefaults) {
		$this->columnDefaults = $columnDefaults;
		$this->huoContext = $huoContext;
	}

	/**
	 * {@inheritDoc}
	 * @see \hangar\api\HangarPropDef::getName()
	 */
	public function getName(): string {
		return 'ManyToOne';
	}

	/**
	 * {@inheritDoc}
	 * @see \hangar\api\HangarPropDef::createMagCollection()
	 * @return MagCollection
	 */
	public function createMagCollection(PropSourceDef $propSourceDef = null): MagCollection {
		$magCollection = new OrmRelationMagCollection($this->huoContext->getEntityModelManager(), false);

		if (null !== $propSourceDef) {
			if ($propSourceDef->hasPhpPropertyAnno(AnnoManyToOne::class)) {
				$phpAnnotation = $propSourceDef->getPhpPropertyAnno(AnnoManyToOne::class);

				$localName = OrmRelationMagCollection::determineLocalName($phpAnnotation->getPhpAnnoParam(1));
				$magCollection->setTargetEntityClasName($propSourceDef->determineTypeName($localName));

				if ($phpAnnotation->hasPhpAnnoParam(2)) {
					$magCollection->setCascadeTypes(
							OrmRelationMagCollection::determineCascadeTypes($phpAnnotation->getPhpAnnoParam(2)));
				}

				if ($phpAnnotation->hasPhpAnnoParam(3)) {
					$magCollection->setFetchType(
							OrmRelationMagCollection::determineFetchType($phpAnnotation->getPhpAnnoParam(3)));
				}
			}
		}

		return $magCollection;
	}

	/**
	 * {@inheritDoc}
	 * @see \hangar\api\HangarPropDef::resetPropSourceDef()
	 */
	public function resetPropSourceDef(PropSourceDef $propSourceDef) {
		if ($propSourceDef->hasPhpPropertyAnno(AnnoManyToOne::class)) {
			$phpAnno = $propSourceDef->getPhpPropertyAnno(AnnoManyToOne::class);
			$localName = OrmRelationMagCollection::determineLocalName($phpAnno->getPhpAnnoParam(1));
			$typeName = $propSourceDef->determineTypeName($localName);
			if (null === $typeName && null !== ($phpTypeDef = $propSourceDef->getPhpTypeDef())) {
				$typeName = $phpTypeDef->getTypeName();
			}

			$propSourceDef->removePhpUse($typeName);
			$propSourceDef->removePhpPropertyAnno(AnnoManyToOne::class);
			$propSourceDef->removePhpUse(AnnoManyToOne::class);
		}
	}

	/**
	 * {@inheritDoc}
	 * @see \hangar\api\HangarPropDef::updatePropSourceDef()
	 */
	public function updatePropSourceDef(Attributes $attributes, PropSourceDef $propSourceDef) {
		$propSourceDef->getHangarData()->setAll($attributes->toArray());

		$targetEntityTypeName = $attributes->get(OrmRelationMagCollection::PROP_NAME_TARGET_ENTITY_CLASS);

		$propSourceDef->setPhpTypeDef(PhpTypeDef::fromTypeName($targetEntityTypeName));

		$anno = $propSourceDef->getOrCreatePhpPropertyAnno(AnnoManyToOne::class);
		$anno->resetPhpAnnoParams();
		$anno->createPhpAnnoParam(PhpbobUtils::extractClassName($targetEntityTypeName) . '::getClass()');
		$propSourceDef->createPhpUse($targetEntityTypeName);

		$cascadeTypeValue = OrmRelationMagCollection::buildCascadeTypeAnnoParam(
				$attributes->get(OrmRelationMagCollection::PROP_NAME_CASCADE_TYPE));

		$fetchType = OrmRelationMagCollection::buildFetchTypeAnnoParam(
				$attributes->getString(OrmRelationMagCollection::PROP_NAME_FETCH_TYPE));

		// Pseudo mapped by
		if (null !== $cascadeTypeValue) {
			$anno->createPhpAnnoParam($cascadeTypeValue);
		} elseif (null !== $fetchType) {
			$anno->createPhpAnnoParam('null');
		}

		if (null !== $fetchType) {
			$anno->createPhpAnnoParam($fetchType);
		}
	}

	/**
	 * {@inheritDoc}
	 * @see \hangar\api\HangarPropDef::applyDbMeta()
	 */
	public function applyDbMeta(DbInfo $dbInfo, PropSourceDef $propSourceDef, EntityProperty $entityProperty,
			AnnotationSet $annotationSet) {
		ArgUtils::assertTrue($entityProperty instanceof ToOneEntityProperty);

		$relation = $entityProperty->getRelation();
		ArgUtils::assertTrue($relation instanceof JoinColumnToOneRelation);

		$joinColumnName = $relation->getJoinColumnName();
		$table = $dbInfo->getTable();
		if (!$table->containsColumnName($joinColumnName)) {
			$relation->getTargetEntityModel()->getTableName();
			$targetEntityProperty = $relation->getTargetEntityModel()->getIdDef()->getEntityProperty();

			//@todo @andi: das sollte einfach sein eine lösung zu finden, sobald das die EntityProperties selbst können
			if ($targetEntityProperty instanceof IntEntityProperty || $targetEntityProperty->getName() === 'id') {
				$dbInfo->getTable()->createColumnFactory()->createIntegerColumn($joinColumnName,
						$this->columnDefaults->getDefaultIntegerSize(), $this->columnDefaults->getDefaultInterSigned());
			} else {
				$dbInfo->getTable()->createColumnFactory()->createStringColumn($joinColumnName,
						$this->columnDefaults->getDefaultStringLength(), $this->columnDefaults->getDefaultStringCharset());
			}
		}

		if (!$this->hasIndexForColumn($dbInfo->getTable(), $joinColumnName)) {
			$dbInfo->getTable()->createIndex(IndexType::INDEX, array($joinColumnName));
		}
	}

	private function hasIndexForColumn(Table $table, $columnName) {
		foreach ($table->getIndexes() as $index) {
			if ($index->containsColumnName($columnName) && count($index->getColumns()) === 1) return true;
		}

		return false;
	}

	/**
	 * @param PropSourceDef $propSourceDef
	 * @return Column
	 */
	public function createMetaColumn(EntityProperty $entityProperty, PropSourceDef $propSourceDef): ?Column {
		return null;
	}

	/**
	 * {@inheritDoc}
	 * @see \hangar\api\HangarPropDef::testSourceCompatibility()
	 */
	public function testCompatibility(PropSourceDef $propSourceDef): int {
		if ($propSourceDef->hasPhpPropertyAnno(AnnoManyToOne::class)) {
			return CompatibilityLevel::COMMON;
		}

		return CompatibilityLevel::NOT_COMPATIBLE;
	}
}


<?php

namespace Igorwanbarros\Php2Html\Form;

use Igorwanbarros\Php2Html\ViewAbstract;

/**
 * Class Form
 * @package Igorwanbarros\Php2Html\Form
 */
class FormView extends ViewAbstract
{

    /**
     * @var string
     */
    protected $template = 'templates/%s/form.php';

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

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

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

    /**
     * @param string $action
     * @param string $method
     * @param array  $attributes
     */
    public function __construct($action = '', $method = 'GET', array $attributes = [])
    {
        parent::__construct();
        $this->action       = $action;
        $this->method       = $method;
        $this->attributes   = $attributes;

        $this->toStart();
    }

    public function toStart() {}

    /**
     * @return array
     */
    public function getVars()
    {
        return ['form' => $this];
    }

    /**
     * @param $data
     *
     * @return $this
     */
    public function fill($data)
    {
        if (is_array($data))
            $this->_fillArray($data);

        if (is_object($data))
            $this->_fillObject($data);

        return $this;
    }

    /**
     * @param $data
     */
    protected function _fillArray($data)
    {
        foreach ($data as $key => $value) {
            if (!array_key_exists($key, $this->fields)) {
                continue;
            }

            $this->fields[$key]->setValue($value);
        }
    }

    /**
     * @param $data
     */
    protected function _fillObject($data)
    {
        foreach ($this->fields as $name => $field) {
            if (isset($data->{$name})) {
                $field->setValue($data->{$name});
            }
        }
    }

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

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

        return $this;
    }

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

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

        return $this;
    }

    /**
     * @return array
     */
    public function getFields()
    {
        return $this->fields;
    }

    /**
     * @param $name
     *
     * @return null|Field
     */
    public function getField($name)
    {
        return array_key_exists($name, $this->fields) ? $this->fields[$name] : null;
    }

    /**
     * @param Field         $fields
     * @param null|string   $name
     *
     * @return $this
     */
    public function addField(Field $fields, $name = null)
    {
        $name = $name ?: $fields->getName();
        $this->fields[$name] = $fields;

        return $this;
    }
}


<?php

namespace Igorwanbarros\Php2Html\Table;

use Igorwanbarros\Php2Html\ViewAbstract;

/**
 * Class TableView
 * @package Igorwanbarros\Php2Html\Table
 */
class TableView extends ViewAbstract
{

    /**
     * @var string
     */
    protected $template         = 'templates/%s/table.php';

    /**
     * @var array
     */
    protected $headers          = [];

    /**
     * @var array
     */
    protected $callback         = [];

    /**
     * @var string
     */
    protected $emptyList        = 'Esta listagem está vazia';

    /**
     * @var bool|string
     */
    protected $lineLink         = false;

    /**
     * @var string
     */
    protected $classTable       = ViewAbstract::TABLE_BOOTSTRAP;

    /**
     * @var mixed
     */
    protected $collection;

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

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

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

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

    /**
     * @var mixed
     */
    protected $paginator;

    /**
     * @param array         $headers
     * @param null|mixed    $collection
     */
    public function __construct(array $headers, $collection = null)
    {
        parent::__construct();
        $this->headers = $headers;
        $this->setCollection($collection);
    }

    public function checkHeader($header = 'id', $begin = true)
    {
        $check = '<input type="checkbox" class="check-all" />';

        unset($this->headers[$header]);
        return $this->addHeader($header, $check, $begin);
    }

    /**
     * @param $row
     *
     * @return RowTableView
     */
    public function getRow($row)
    {
        $row = new RowTableView($this->headers, $row);
        $row->setLineLink($this->lineLink);

        foreach ($this->callback as $callback) {
            $callback($row);
        }

        return $row;
    }

    /**
     * @param callable $callback
     *
     * @return $this
     */
    public function callback(callable $callback)
    {
        $this->callback[] = $callback;

        return $this;
    }

    /**
     * @return array
     */
    public function getVars()
    {
        return ['table' => $this];
    }

    /**
     * @return array
     */
    public function getCollection()
    {
        return $this->collection ?: [];
    }

    /**
     * @param mixed $collection
     *
     * @return $this
     */
    public function setCollection($collection)
    {
        $this->collection = $collection;

        return $this;
    }

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

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

        return $this;
    }

    /**
     * @return array
     */
    public function getHeaders()
    {
        return $this->headers;
    }

    /**
     * @param string    $key
     * @param string    $value
     * @param bool      $begin
     *
     * @return $this
     */
    public function addHeader($key, $value, $begin = false)
    {
        if ($begin) {
            $headers[$key] = $value;
            $this->headers = array_merge($headers, $this->headers);
        } else {
            $this->headers[$key] = $value;
        }

        return $this;
    }

    /**
     * @param array $headers
     *
     * @return $this
     */
    public function setHeaders(array $headers)
    {
        $this->headers = $headers;

        return $this;
    }

    /**
     * @return array
     */
    public function getCallback()
    {
        return $this->callback;
    }

    /**
     * @param array $callback
     *
     * @return $this
     */
    public function setCallback(array $callback)
    {
        $this->callback = $callback;

        return $this;
    }

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

    /**
     * @param string $emptyList
     *
     * @return $this
     */
    public function setEmptyList($emptyList)
    {
        $this->emptyList = $emptyList;

        return $this;
    }

    /**
     * @return bool|string
     */
    public function getLineLink()
    {
        return $this->lineLink;
    }

    /**
     * @param string $lineLink
     *
     * @return $this
     */
    public function setLineLink($lineLink)
    {
        $this->lineLink = $lineLink;

        return $this;
    }

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

    /**
     * @param string $classTable
     *
     * @return $this
     */
    public function setClassTable($classTable)
    {
        $this->classTable = $classTable;

        return $this;
    }

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

    /**
     * @param string $classThead
     *
     * @return $this
     */
    public function setClassThead($classThead)
    {
        $this->classThead = $classThead;

        return $this;
    }

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

    /**
     * @param string $classTfooter
     *
     * @return $this
     */
    public function setClassTfooter($classTfooter)
    {
        $this->classTfooter = $classTfooter;

        return $this;
    }

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

    /**
     * @param string $classTd
     *
     * @return $this
     */
    public function setClassTd($classTd)
    {
        $this->classTd = $classTd;

        return $this;
    }

    /**
     * @return mixed
     */
    public function getPaginator()
    {
        return $this->paginator;
    }

    /**
     * @param mixed $paginator
     *
     * @return $this
     */
    public function setPaginator($paginator)
    {
        $this->paginator = $paginator;

        return $this;
    }
}


<?php
/*
 * Copyright (c) 2012-2016, Hofmänner New Media.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This file is part of the N2N FRAMEWORK.
 *
 * The N2N FRAMEWORK is free software: you can redistribute it and/or modify it under the terms of
 * the GNU Lesser General Public License as published by the Free Software Foundation, either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * N2N is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details: http://www.gnu.org/licenses/
 *
 * The following people participated in this project:
 *
 * Andreas von Burg.....: Architect, Lead Developer
 * Bert Hofmänner.......: Idea, Frontend UI, Community Leader, Marketing
 * Thomas Günther.......: Developer, Hangar
 */
namespace n2n\impl\persistence\orm\property;

use n2n\persistence\orm\criteria\compare\UrlColumnComparable;
use n2n\persistence\orm\query\select\UrlSelection;
use n2n\util\type\TypeConstraint;
use n2n\persistence\orm\store\action\PersistAction;
use n2n\reflection\property\AccessProxy;
use n2n\persistence\orm\store\action\RemoveAction;
use n2n\persistence\orm\property\BasicEntityProperty;
use n2n\persistence\Pdo;
use n2n\util\type\ArgUtils;
use n2n\persistence\meta\data\QueryItem;
use n2n\persistence\orm\query\QueryState;
use n2n\persistence\orm\query\from\MetaTreePoint;
use n2n\persistence\orm\store\operation\MergeOperation;
use n2n\persistence\orm\EntityManager;
use n2n\persistence\orm\store\ValueHash;
use n2n\persistence\orm\store\CommonValueHash;
use n2n\util\uri\Url;

class UrlEntityProperty extends ColumnPropertyAdapter implements BasicEntityProperty {
	public function __construct(AccessProxy $accessProxy, $columnName) {
		$accessProxy->setConstraint(TypeConstraint::createSimple(Url::class, true));

		parent::__construct($accessProxy, $columnName);
	}

	public function supplyPersistAction(PersistAction $persistingJob, $value, ValueHash $valueHash, ?ValueHash $oldValueHash) {
		$rawValue = null;

		if ($value instanceof Url) {
			$rawValue = (string) $value;
		}

		$persistingJob->getMeta()->setRawValue($this->getEntityModel(), $this->getColumnName(), $rawValue);
	}
	/* (non-PHPdoc)
	 * @see \n2n\persistence\orm\property\EntityProperty::supplyRemoveAction()
	 */
	public function supplyRemoveAction(RemoveAction $removeAction, $value, ValueHash $oldValueHash) {
	}

	public static function areConstraintsTypical(TypeConstraint $constraints = null) {
		return isset($constraints) && !is_null($constraints->getParamClass())
				&& $constraints->getParamClass()->getName() == Url::class && !$constraints->isArray();
	}
	/* (non-PHPdoc)
	 * @see \n2n\persistence\orm\property\BasicEntityProperty::valueToRep()
	 */
	public function valueToRep($value): string {
		ArgUtils::assertTrue($value instanceof Url);
		return (string) $value;
	}
	/* (non-PHPdoc)
	 * @see \n2n\persistence\orm\property\BasicEntityProperty::repToValue()
	 */
	public function repToValue(string $rep) {
		try {
			return Url::create($rep);
		} catch (\InvalidArgumentException $e) {
			throw new \InvalidArgumentException('tbd', 0, $e);
		}
	}
	/* (non-PHPdoc)
	 * @see \n2n\persistence\orm\property\BasicEntityProperty::parseValue()
	 */
	public function parseValue($raw, Pdo $pdo) {
		return $this->repToValue($raw);
	}
	/* (non-PHPdoc)
	 * @see \n2n\persistence\orm\property\BasicEntityProperty::buildRaw()
	 */
	public function buildRaw($value, Pdo $pdo) {
		return $this->valueToRep($value);
	}
	/* (non-PHPdoc)
	 * @see \n2n\persistence\orm\property\BasicEntityProperty::createSelectionFromQueryItem()
	 */
	public function createSelectionFromQueryItem(QueryItem $queryItem, QueryState $queryState) {
		return new UrlSelection($queryItem);
	}
	/* (non-PHPdoc)
	 * @see \n2n\persistence\orm\property\BasicEntityProperty::createColumnComparableFromQueryItem()
	 */
	public function createColumnComparableFromQueryItem(QueryItem $queryItem, QueryState $queryState) {
		return new UrlColumnComparable($queryItem, $queryState);
	}
	/* (non-PHPdoc)
	 * @see \n2n\persistence\orm\property\ColumnComparableEntityProperty::createColumnComparable()
	 */
	public function createColumnComparable(MetaTreePoint $metaTreePoint, QueryState $queryState) {
		return new UrlColumnComparable($this->createQueryColumn($metaTreePoint->getMeta()), $queryState);
	}
	/* (non-PHPdoc)
	 * @see \n2n\persistence\orm\property\EntityProperty::createSelection()
	 */
	public function createSelection(MetaTreePoint $metaTreePoint, QueryState $queryState) {
		return new UrlSelection($this->createQueryColumn($metaTreePoint->getMeta()));
	}
	/* (non-PHPdoc)
	 * @see \n2n\persistence\orm\property\EntityProperty::mergeValue()
	 */
	public function mergeValue($value, $sameEntity, MergeOperation $mergeOperation) {
		return $value;
	}
	/* (non-PHPdoc)
	 * @see \n2n\persistence\orm\property\EntityProperty::createValueHash()
	 */
	public function createValueHash($value, EntityManager $em): ValueHash {
		if ($value === null) return new CommonValueHash(null);
		return new CommonValueHash((string) $value);
	}
}


<?php
/*
 * Copyright (c) 2012-2016, Hofmänner New Media.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This file is part of the N2N FRAMEWORK.
 *
 * The N2N FRAMEWORK is free software: you can redistribute it and/or modify it under the terms of
 * the GNU Lesser General Public License as published by the Free Software Foundation, either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * N2N is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details: http://www.gnu.org/licenses/
 *
 * The following people participated in this project:
 *
 * Andreas von Burg.....: Architect, Lead Developer
 * Bert Hofmänner.......: Idea, Frontend UI, Community Leader, Marketing
 * Thomas Günther.......: Developer, Hangar
 */
namespace n2n\impl\persistence\orm\property\relation;

use n2n\persistence\orm\query\QueryState;
use n2n\impl\persistence\orm\property\relation\tree\JoinTableTreePoint;
use n2n\impl\persistence\orm\property\relation\selection\JoinTableToManyLoader;
use n2n\persistence\orm\store\SimpleLoaderUtils;
use n2n\persistence\orm\store\action\RemoveAction;
use n2n\persistence\Pdo;
use n2n\persistence\orm\store\action\PersistAction;
use n2n\persistence\orm\query\from\meta\TreePointMeta;
use n2n\impl\persistence\orm\property\relation\util\JoinTableAction;
use n2n\impl\persistence\orm\property\relation\compare\JoinTableToManyQueryItemFactory;
use n2n\persistence\orm\model\EntityModel;
use n2n\persistence\orm\store\ValueHash;

abstract class JoinTableRelation extends MasterRelation {
	protected $joinTableName;
	protected $joinColumnName;
	protected $inverseJoinColumnName;
	protected $orphanRemoval = false;

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

	public function setJoinTableName($joinTableName) {
		$this->joinTableName = $joinTableName;
	}

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

	public function setJoinColumnName($joinColumnName) {
		$this->joinColumnName = $joinColumnName;
	}

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

	public function setInverseJoinColumnName($inverseJoinColumnName) {
		$this->inverseJoinColumnName = $inverseJoinColumnName;
	}

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

	public function setOrphanRemoval($orphanRemoval) {
		return $this->orphanRemoval = $orphanRemoval;
	}

	public function createJoinTreePoint(TreePointMeta $treePointMeta, QueryState $queryState) {
		$idColumn = $this->entityModel->getIdDef()->getEntityProperty()
				->createQueryColumn($treePointMeta);

		$joinTableAlias = $queryState->createTableAlias($this->joinTableName);

		$targetEntityModel = $this->getTargetEntityModel();
		$targetTreePointMeta = $targetEntityModel->createTreePointMeta($queryState);
		$targetIdColumn = $targetEntityModel->getIdDef()->getEntityProperty()->createQueryColumn($targetTreePointMeta);

		$treePoint = new JoinTableTreePoint($queryState, $targetTreePointMeta);
		$treePoint->setIdColumn($idColumn);
		$treePoint->setJoinTableName($this->joinTableName);
		$treePoint->setJoinTableAlias($joinTableAlias);
		$treePoint->setJoinColumnName($this->joinColumnName);
		$treePoint->setInverseJoinColumnName($this->inverseJoinColumnName);
		$treePoint->setTargetIdColumn($targetIdColumn);
		return $treePoint;
	}

	public function createInverseJoinTreePoint(EntityModel $entityModel, TreePointMeta $targetTreePointMeta, QueryState $queryState) {
		$targetIdColumn = $this->getTargetEntityModel()->getIdDef()->getEntityProperty()
				->createQueryColumn($targetTreePointMeta);

		$joinTableAlias = $queryState->createTableAlias($this->joinTableName);

		$treePointMeta = $entityModel->createTreePointMeta($queryState);
		$idColumn = $this->entityModel->getIdDef()->getEntityProperty()->createQueryColumn($treePointMeta);

		$treePoint = new JoinTableTreePoint($queryState, $treePointMeta);
		$treePoint->setIdColumn($targetIdColumn);
		$treePoint->setJoinTableName($this->joinTableName);
		$treePoint->setJoinTableAlias($joinTableAlias);
		$treePoint->setJoinColumnName($this->inverseJoinColumnName);
		$treePoint->setInverseJoinColumnName($this->joinColumnName);
		$treePoint->setTargetIdColumn($idColumn);

		return $treePoint;
	}

	public function createInverseToManyLoader(EntityModel $entityModel, QueryState $queryState) {
		return new JoinTableToManyLoader(
				new SimpleLoaderUtils($queryState->getEntityManager(), $entityModel),
				$this->targetEntityModel->getIdDef()->getEntityProperty(),
				$this->joinTableName, $this->joinColumnName, $this->inverseJoinColumnName);
	}

	protected function createJoinTableAction(Pdo $pdo) {
		return new JoinTableAction($pdo, $this->joinTableName, $this->joinColumnName,
				$this->inverseJoinColumnName);
	}
	/**
	 * @param PersistAction $persistAction
	 * @return JoinTableAction
	 */
	protected function createJoinTableActionFromPersistAction(PersistAction $persistAction) {
		$actionQueue = $persistAction->getActionQueue();
		$idProperty = $this->entityModel->getIdDef()->getEntityProperty();

		$pdo = $actionQueue->getEntityManager()->getPdo();
		$joinTableAction = $this->createJoinTableAction($pdo);
		$actionQueue->add($joinTableAction);

		if ($persistAction->hasId()) {
			$joinTableAction->setJoinIdRaw($idProperty->buildRaw($persistAction->getId(), $pdo));
			return $joinTableAction;
		}

		$joinTableAction->addDependent($persistAction);
		$persistAction->executeAtEnd(function () use ($joinTableAction, $idProperty, $persistAction, $pdo) {
			$joinTableAction->setJoinIdRaw($idProperty->buildRaw($persistAction->getId(), $pdo));
		});

		return $joinTableAction;
	}

	public function supplyRemoveAction(RemoveAction $removeAction, $value, ValueHash $oldValueHash) {
		$actionQueue = $removeAction->getActionQueue();

		$pdo = $actionQueue->getEntityManager()->getPdo();
		$joinTableAction = $this->createJoinTableAction($pdo);
		$joinTableAction->setJoinIdRaw($this->entityModel->getIdDef()->getEntityProperty()
				->buildRaw($removeAction->getId(), $pdo));

		$actionQueue->add($joinTableAction);
	}

// 	public function supplyInverseToOneRemoveAction($targetValue, $targetValueHash, RemoveAction $targetRemoveAction) {
// 		if ($targetValueHash === null) return;

// 		$persistenceContext = $targetRemoveAction->getActionQueue()->getEntityManager()->getPersistenceContext();

// 		$entity = $persistenceContext->getEntityByIdRep($this->entityModel, $targetValueHash);
// 		if ($persistenceContext->containsRemovedEntity($entity)) continue;

// 		$this->createJoinTableActionFromTargetRemoveAction($targetRemoveAction);

// 	}

// 	public function supplyInverseToManyRemoveAction($targetValue, $targetValueHash, RemoveAction $targetRemoveAction) {
// 		$this->createJoinTableActionFromTargetRemoveAction($targetRemoveAction);
// 	}

	public function createInverseJoinTableToManyQueryItemFactory(EntityModel $entityModel) {
		return new JoinTableToManyQueryItemFactory($this->joinTableName,
				$this->inverseJoinColumnName, $this->joinColumnName);
	}
	/* (non-PHPdoc)
	 * @see \n2n\persistence\orm\model\ActionDependency::removeActionSupplied()
	 */
	public function removeActionSupplied(RemoveAction $targetRemoveAction) {
		if ($this->actionMarker->isConstraintReleased($targetRemoveAction)) return;

		$actionQueue = $targetRemoveAction->getActionQueue();
		$pdo = $actionQueue->getEntityManager()->getPdo();
		$targetIdProperty = $this->targetEntityModel->getIdDef()->getEntityProperty();

		$joinTableAction = new JoinTableAction($pdo, $this->joinTableName,
				$this->inverseJoinColumnName, $this->joinColumnName);
		$joinTableAction->setJoinIdRaw($targetIdProperty->buildRaw($targetRemoveAction->getId(), $pdo));

		$actionQueue->add($joinTableAction);

		$targetRemoveAction->executeAtEnd(function ($actionQueue, $resetAction) {
			$actionQueue->add($joinTableAction);
		});
	}
}

// public function createSelectionQueryColumn(QueryState $queryState, TreePointMeta $queryPoint) {
// 	return $queryPoint->registerColumn($this->entityModel, $this->getReferencedColumnName());
// }

// public function createInverseToManyLoader(EntityManager $em, $id, ToMany $toMany) {
// 	return new JoinTableToManyLoader($em, $id, $this->entityModel, $this->getJoinTableName(),
// 			$this->getInverseJoinColumnName(), $this->getJoinColumnName(), $toMany);
// }

// public function lookupInverseOneToOneEntity(EntityManager $em, $id) {
// 	$toOneLoader = new JoinTableToOneLoader($em, $id, $this->entityModel, $this->getJoinTableName(),
// 			$this->getInverseJoinColumnName(), $this->getJoinColumnName());
// 	return $toOneLoader->load();
// }

// public function supplyNonCascadeInverseRemoveAction($mappedValue, RemoveAction $deletingJob) {
// 	if (!$deletingJob->getRemoveMeta()->hasObjectId()) return;

// 	$relationAction = new JoinTableRelationAction($deletingJob->getActionQueue(), $this->getJoinTableName(),
// 			$this->getInverseJoinColumnName(), $this->getJoinColumnName());
// 	$relationAction->setId($deletingJob->getRemoveMeta()->getObjectId());
// 	$relationAction->addDependent($deletingJob);

// 	$deletingJob->getActionQueue()->add($relationAction);
// }


<?php
/*
 * Copyright (c) 2012-2016, Hofmänner New Media.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This file is part of the N2N FRAMEWORK.
 *
 * The N2N FRAMEWORK is free software: you can redistribute it and/or modify it under the terms of
 * the GNU Lesser General Public License as published by the Free Software Foundation, either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * N2N is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details: http://www.gnu.org/licenses/
 *
 * The following people participated in this project:
 *
 * Andreas von Burg.....: Architect, Lead Developer
 * Bert Hofmänner.......: Idea, Frontend UI, Community Leader, Marketing
 * Thomas Günther.......: Developer, Hangar
 */
namespace n2n\impl\persistence\orm\property;

use n2n\impl\persistence\orm\property\relation\Relation;
use n2n\util\type\TypeConstraint;
use n2n\persistence\orm\store\operation\CascadeOperation;
use n2n\util\col\ArrayUtils;
use n2n\util\type\ArgUtils;
use n2n\impl\persistence\orm\property\relation\selection\ArrayObjectProxy;
use n2n\persistence\orm\store\operation\MergeOperation;
use n2n\persistence\orm\CascadeType;
use n2n\impl\persistence\orm\property\relation\ToManyRelation;
use n2n\persistence\orm\query\from\MetaTreePoint;
use n2n\persistence\orm\query\QueryState;
use n2n\persistence\orm\property\CustomComparableEntityProperty;

class ToManyEntityProperty extends RelationEntityPropertyAdapter implements CustomComparableEntityProperty {
	public function setRelation(Relation $relation) {
		parent::assignRelation($relation);
		ArgUtils::assertTrue($this->relation instanceof ToManyRelation);
		$this->accessProxy->setConstraint(TypeConstraint::createArrayLike(null, true,
				TypeConstraint::createSimple($relation->getTargetEntityModel()->getClass()->getName()),
				array('n2n\impl\persistence\orm\property\relation\selection\ArrayObjectProxy')));
	}

	public function cascade($value, $cascadeType, CascadeOperation $cascadeOperation) {
		if ($value === null || !($this->getRelation()->getCascadeType() & $cascadeType)) return;

		if ($cascadeType !== CascadeType::REMOVE && $value instanceof ArrayObjectProxy && !$value->isInitialized()) {
			return;
		}

		ArgUtils::assertTrue(ArrayUtils::isArrayLike($value));
		foreach ($value as $entity) {
			$cascadeOperation->cascade($entity);
		}
	}

	/* (non-PHPdoc)
	 * @see \n2n\persistence\orm\property\EntityProperty::mergeValue()
	 */
	public function mergeValue($value, $sameEntity, MergeOperation $mergeOperation) {
		if ($value === null) return null;

		if ($value instanceof ArrayObjectProxy && !$value->isInitialized()) return $value;

		$mergedEntities = new \ArrayObject();
		if ($this->relation->getCascadeType() & CascadeType::MERGE) {
			foreach ($value as $key => $targetEntity) {
				$mergedEntities[$key] = $mergeOperation->mergeEntity($targetEntity);
			}
		}
		return $mergedEntities;
	}

	public function createCustomComparable(MetaTreePoint $metaTreePoint, QueryState $queryState) {
		return $this->relation->createCustomComparable($metaTreePoint, $queryState);
	}

// 	public function readValue($object) {
// 		$value = parent::readValue($object);
// 		if ($value === null && $this->isToMany()) {
// 			return new \ArrayObject();
// 		}
// 		return $value;
// 	}
}


<?php
/*
 * Copyright (c) 2012-2016, Hofmänner New Media.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This file is part of the N2N FRAMEWORK.
 *
 * The N2N FRAMEWORK is free software: you can redistribute it and/or modify it under the terms of
 * the GNU Lesser General Public License as published by the Free Software Foundation, either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * N2N is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details: http://www.gnu.org/licenses/
 *
 * The following people participated in this project:
 *
 * Andreas von Burg.....: Architect, Lead Developer
 * Bert Hofmänner.......: Idea, Frontend UI, Community Leader, Marketing
 * Thomas Günther.......: Developer, Hangar
 */
namespace n2n\impl\persistence\orm\property;

use n2n\util\type\TypeConstraint;
use n2n\persistence\orm\store\action\PersistAction;
use n2n\l10n\N2nLocale;
use n2n\reflection\property\AccessProxy;
use n2n\persistence\orm\store\action\RemoveAction;
use n2n\persistence\orm\property\BasicEntityProperty;
use n2n\l10n\IllegalN2nLocaleFormatException;
use n2n\persistence\Pdo;
use n2n\util\type\ArgUtils;
use n2n\persistence\orm\query\select\N2nLocaleSelection;
use n2n\persistence\meta\data\QueryItem;
use n2n\persistence\orm\query\QueryState;
use n2n\persistence\orm\criteria\compare\N2nLocaleColumnComparable;
use n2n\persistence\orm\query\from\MetaTreePoint;
use n2n\persistence\orm\store\operation\MergeOperation;
use n2n\persistence\orm\EntityManager;
use n2n\persistence\orm\store\ValueHash;
use n2n\persistence\orm\store\CommonValueHash;

class N2nLocaleEntityProperty extends ColumnPropertyAdapter implements BasicEntityProperty {
	public function __construct(AccessProxy $accessProxy, $columnName) {
		$accessProxy->setConstraint(TypeConstraint::createSimple('n2n\l10n\N2nLocale', true));

		parent::__construct($accessProxy, $columnName);
	}

	public function supplyPersistAction(PersistAction $persistingJob, $value, ValueHash $valueHash, ?ValueHash $oldValueHash) {
		$rawValue = null;

		if ($value instanceof N2nLocale) {
			$rawValue = $value->getId();
		}

		$persistingJob->getMeta()->setRawValue($this->getEntityModel(), $this->getColumnName(), $rawValue);
	}
	/* (non-PHPdoc)
	 * @see \n2n\persistence\orm\property\EntityProperty::supplyRemoveAction()
	 */
	public function supplyRemoveAction(RemoveAction $removeAction, $value, ValueHash $oldValueHash) {
	}

	public static function areConstraintsTypical(TypeConstraint $constraints = null) {
		return isset($constraints) && !is_null($constraints->getParamClass())
				&& $constraints->getParamClass()->getName() == 'n2n\l10n\N2nLocale' && !$constraints->isArray();
	}
	/* (non-PHPdoc)
	 * @see \n2n\persistence\orm\property\BasicEntityProperty::valueToRep()
	 */
	public function valueToRep($value): string {
		if ($value === null) return null;

		ArgUtils::assertTrue($value instanceof N2nLocale);
		return $value->getId();
	}
	/* (non-PHPdoc)
	 * @see \n2n\persistence\orm\property\BasicEntityProperty::repToValue()
	 */
	public function repToValue(string $rep) {
		try {
			return N2nLocale::create($rep);
		} catch (IllegalN2nLocaleFormatException $e) {
			// @todo
			throw new \InvalidArgumentException('tbd', 0, $e);
		}
	}
	/* (non-PHPdoc)
	 * @see \n2n\persistence\orm\property\BasicEntityProperty::parseValue()
	 */
	public function parseValue($raw, Pdo $pdo) {
		return $this->repToValue($raw);
	}
	/* (non-PHPdoc)
	 * @see \n2n\persistence\orm\property\BasicEntityProperty::buildRaw()
	 */
	public function buildRaw($value, Pdo $pdo) {
		return $this->valueToRep($value);
	}
	/* (non-PHPdoc)
	 * @see \n2n\persistence\orm\property\BasicEntityProperty::createSelectionFromQueryItem()
	 */
	public function createSelectionFromQueryItem(QueryItem $queryItem, QueryState $queryState) {
		return new N2nLocaleSelection($queryItem);
	}
	/* (non-PHPdoc)
	 * @see \n2n\persistence\orm\property\BasicEntityProperty::createColumnComparableFromQueryItem()
	 */
	public function createColumnComparableFromQueryItem(QueryItem $queryItem, QueryState $queryState) {
		return new N2nLocaleColumnComparable($queryItem, $queryState);
	}
	/* (non-PHPdoc)
	 * @see \n2n\persistence\orm\property\ColumnComparableEntityProperty::createColumnComparable()
	 */
	public function createColumnComparable(MetaTreePoint $metaTreePoint, QueryState $queryState) {
		return new N2nLocaleColumnComparable($this->createQueryColumn($metaTreePoint->getMeta()), $queryState);
	}
	/* (non-PHPdoc)
	 * @see \n2n\persistence\orm\property\EntityProperty::createSelection()
	 */
	public function createSelection(MetaTreePoint $metaTreePoint, QueryState $queryState) {
		return new N2nLocaleSelection($this->createQueryColumn($metaTreePoint->getMeta()));
	}
	/* (non-PHPdoc)
	 * @see \n2n\persistence\orm\property\EntityProperty::mergeValue()
	 */
	public function mergeValue($value, $sameEntity, MergeOperation $mergeOperation) {
		return $value;
	}
	/* (non-PHPdoc)
	 * @see \n2n\persistence\orm\property\EntityProperty::createValueHash()
	 */
	public function createValueHash($value, EntityManager $em): ValueHash {
		if ($value === null) return new CommonValueHash(null);
		return new CommonValueHash($value->getId());
	}
}


<?php

namespace Igorwanbarros\Php2Html\Accordion;

use Igorwanbarros\Php2Html\Helpers;
use Igorwanbarros\Php2Html\ViewAbstract;

/**
 * Class AccordionView
 * @package Igorwanbarros\Php2Html\Accordion
 */
class AccordionView extends ViewAbstract
{

    /**
     * @var string
     */
    protected $template = 'templates/%s/accordion.php';

    /**
     * @type array
     */
    protected $titles = [];

    /**
     * @type array
     */
    protected $contents = [];

    /**
     * @type bool
     */
    protected $active;

    /**
     * @param array $titles
     * @param array $contents
     */
    public function __construct(array $titles = [], array $contents = [])
    {
        parent::__construct();
        $this->setTitles($titles);
        $this->setContents($contents);

        $this->addAttribute('class', 'panel-group')
            ->addAttribute('role', 'tablist')
            ->addAttribute('aria-multiselectable', 'true');
    }

    /**
     * @return array
     */
    public function getVars()
    {
        return ['accordion' => $this];
    }

    /**
     * @return array
     */
    public function getTitles()
    {
        return $this->titles;
    }

    /**
     * @param $titles
     *
     * @return $this
     */
    public function setTitles(array $titles)
    {
        $this->titles = [];

        foreach ($titles as $titleKey => $title) {
            $this->addTitle($titleKey, $title);
        }

        return $this;
    }

    /**
     * @param $titleKey
     * @param $title
     *
     * @return AccordionView
     */
    public function addTitle($titleKey, $title)
    {
        if (is_array($titleKey)) {
            return $this->setTitles($titleKey);
        }

        return $this->_preparedTitle($titleKey, $title);
    }

    /**
     * @return array
     */
    public function getContents()
    {
        return $this->contents;
    }

    /**
     * @param $contents
     *
     * @return $this
     */
    public function setContents(array $contents)
    {
        $this->titles = [];

        foreach ($contents as $titleContent => $content) {
            $this->addTitle($titleContent, $content);
        }

        return $this;
    }

    /**
     * @param $titleContent
     * @param $content
     *
     * @return AccordionView
     */
    public function addContent($titleContent, $content)
    {
        if (is_array($titleContent)) {
            return $this->setContents($titleContent);
        }

        return $this->_preparedContent($titleContent, $content);
    }

    /**
     * @param string|int    $name
     * @param string        $title
     *
     * @return $this
     */
    protected function _preparedTitle($name, $title)
    {
        $name = is_int($name) ? $title : $name;
        $name = Helpers::normalize($name);
        $name = strtolower(str_replace(' ', '-', $name));

        if (!$this->active) {
            $this->active = $name;
        }

        $this->titles[$name] = $title;

        return $this;
    }

    /**
     * @param string|int $titleName
     * @param string     $content
     *
     * @return $this
     */
    protected function _preparedContent($titleName, $content)
    {
        $titleName = is_int($titleName) ? $content : $titleName;
        $titleName = Helpers::normalize($titleName);
        $titleName = strtolower(str_replace(' ', '-', $titleName));

        $this->contents[$titleName] = $content;

        return $this;
    }

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

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

        return $this;
    }
}


<?php
/*
 * Copyright (c) 2012-2016, Hofmänner New Media.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This file is part of the N2N FRAMEWORK.
 *
 * The N2N FRAMEWORK is free software: you can redistribute it and/or modify it under the terms of
 * the GNU Lesser General Public License as published by the Free Software Foundation, either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * N2N is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details: http://www.gnu.org/licenses/
 *
 * The following people participated in this project:
 *
 * Andreas von Burg.....: Architect, Lead Developer
 * Bert Hofmänner.......: Idea, Frontend UI, Community Leader, Marketing
 * Thomas Günther.......: Developer, Hangar
 */
namespace n2n\impl\persistence\orm\property\hangar\scalar;

use hangar\api\PropSourceDef;
use n2n\util\type\attrs\Attributes;
use hangar\api\DbInfo;
use n2n\impl\web\dispatch\mag\model\NumericMag;
use n2n\impl\web\dispatch\mag\model\StringMag;
use n2n\persistence\meta\structure\ColumnFactory;
use n2n\persistence\orm\property\EntityProperty;
use n2n\util\type\ArgUtils;
use n2n\persistence\meta\structure\common\CommonTextColumn;
use n2n\impl\persistence\orm\property\ScalarEntityProperty;
use hangar\api\CompatibilityLevel;
use n2n\util\StringUtils;
use phpbob\representation\PhpTypeDef;
use n2n\web\dispatch\mag\MagCollection;
use n2n\persistence\meta\structure\Column;

class TextPropDef extends ScalarPropDefAdapter {
	const PROP_NAME_SIZE = 'size';
	const PROP_NAME_CHARSET = 'charset';

	/**
	 * {@inheritDoc}
	 * @see \hangar\api\HangarPropDef::getName()
	 */
	public function getName(): string {
		return 'Text';
	}

	/**
	 * {@inheritDoc}
	 * @see \hangar\api\HangarPropDef::createMagCollection()
	 */
	public function createMagCollection(PropSourceDef $propSourceDef = null): MagCollection {
		$magCollection = new MagCollection();

		$size = $this->columnDefaults->getDefaultTextSize();
		$charset = $this->columnDefaults->getDefaultTextCharset();

		if (null !== $propSourceDef) {
			$size = $propSourceDef->getHangarData()->get(self::PROP_NAME_SIZE, false, $size);
			$charset = $propSourceDef->getHangarData()->get(self::PROP_NAME_CHARSET, false, $charset);
		}
		$magCollection->addMag(self::PROP_NAME_SIZE, new NumericMag('Size', $size, true));
		$magCollection->addMag(self::PROP_NAME_CHARSET, new StringMag('Charset', $charset));

		return $magCollection;
	}

	public function updatePropSourceDef(Attributes $attributes, PropSourceDef $propSourceDef) {
		$propSourceDef->getHangarData()->setAll(array(self::PROP_NAME_SIZE => $attributes->get(self::PROP_NAME_SIZE),
				self::PROP_NAME_CHARSET => $attributes->get(self::PROP_NAME_CHARSET, false)));
		$propSourceDef->setPhpTypeDef(new PhpTypeDef('string'));
	}

	/**
	 * @param PropSourceDef $propSourceDef
	 * @return Column
	 */
	public function createMetaColumn(EntityProperty $entityProperty, PropSourceDef $propSourceDef): Column {
		ArgUtils::assertTrue($entityProperty instanceof ScalarEntityProperty);

		return new CommonTextColumn($entityProperty->getColumnName(),
				$this->determineSize($propSourceDef->getHangarData()),
				$this->determineCharset($propSourceDef->getHangarData()));
	}

	/**
	 * @param EntityProperty $entityProperty
	 * @return int
	 */
	public function testCompatibility(PropSourceDef $propSourceDef): int {
		if ($propSourceDef->getPhpTypeDef() === null || $propSourceDef->getPhpTypeDef()->isString()) {
			switch ($propSourceDef->getPropertyName()) {
				case 'description':
				case 'lead':
					return CompatibilityLevel::COMMON;
			}

			if (StringUtils::endsWith('Html', $propSourceDef->getPropertyName())) {
				return CompatibilityLevel::COMMON;
			}

			if (null !== $propSourceDef) {
				return CompatibilityLevel::COMPATIBLE;
			}

			return parent::testCompatibility($propSourceDef);
		}

		return CompatibilityLevel::NOT_COMPATIBLE;
	}

	protected function createColumn(EntityProperty $entityProperty, DbInfo $dbInfo, ColumnFactory $columnFactory, $columnName, Attributes $attributes) {
		$columnFactory->createTextColumn($columnName, $this->determineSize($attributes),
				$this->determineCharset($attributes));
	}

	private function determineSize(Attributes $attributes) {
		return $attributes->get(self::PROP_NAME_SIZE, false, $this->columnDefaults->getDefaultTextSize());
	}

	private function determineCharset(Attributes $attributes) {
		return $attributes->get(self::PROP_NAME_CHARSET,
				false, $this->columnDefaults->getDefaultTextCharset());
	}
}


<?php
declare(strict_types = 1);

namespace Innmind\Http\Factory\ServerRequest;

use Innmind\Http\{
    Factory\ServerRequestFactory as ServerRequestFactoryInterface,
    Message\ServerRequest,
    Message\Method\Method,
    ProtocolVersion\ProtocolVersion,
    Factory\HeadersFactory,
    Factory\Header\Factories,
    Factory\EnvironmentFactory,
    Factory\CookiesFactory,
    Factory\QueryFactory,
    Factory\FormFactory,
    Factory\FilesFactory,
    Factory
};
use Innmind\Url\Url;
use Innmind\Filesystem\Stream\LazyStream;
use Innmind\Immutable\{
    Str,
    Map
};

final class ServerRequestFactory implements ServerRequestFactoryInterface
{
    private $headersFactory;
    private $environmentFactory;
    private $cookiesFactory;
    private $queryFactory;
    private $formFactory;
    private $filesFactory;

    public function __construct(
        HeadersFactory $headersFactory,
        EnvironmentFactory $environmentFactory,
        CookiesFactory $cookiesFactory,
        QueryFactory $queryFactory,
        FormFactory $formFactory,
        FilesFactory $filesFactory
    ) {
        $this->headersFactory = $headersFactory;
        $this->environmentFactory = $environmentFactory;
        $this->cookiesFactory = $cookiesFactory;
        $this->queryFactory = $queryFactory;
        $this->formFactory = $formFactory;
        $this->filesFactory = $filesFactory;
    }

    public function make(): ServerRequest
    {
        $protocol = (new Str($_SERVER['SERVER_PROTOCOL']))->capture(
            '~HTTP/(?<major>\d)\.(?<minor>\d)~'
        );
        $https = (string) Str::of($_SERVER['HTTPS'] ?? 'off')->toLower();
        $user = '';

        if (isset($_SERVER['PHP_AUTH_USER'])) {
            $user = $_SERVER['PHP_AUTH_USER'];

            if (isset($_SERVER['PHP_AUTH_PW'])) {
                $user .= ':'.$_SERVER['PHP_AUTH_PW'];
            }

            $user .= '@';
        }

        return new ServerRequest\ServerRequest(
            Url::fromString(sprintf(
                '%s://%s%s%s',
                $https === 'on' ? 'https' : 'http',
                $user,
                $_SERVER['HTTP_HOST'],
                $_SERVER['REQUEST_URI']
            )),
            new Method($_SERVER['REQUEST_METHOD']),
            new ProtocolVersion(
                (int) (string) $protocol['major'],
                (int) (string) $protocol['minor']
            ),
            $this->headersFactory->make(),
            new LazyStream('php://input'),
            $this->environmentFactory->make(),
            $this->cookiesFactory->make(),
            $this->queryFactory->make(),
            $this->formFactory->make(),
            $this->filesFactory->make()
        );
    }

    /**
     * Return a fully configured factory
     *
     * @return self
     */
    public static function default(): self
    {
        return new self(
            new Factory\Header\HeadersFactory(
                Factories::default()
            ),
            new Factory\Environment\EnvironmentFactory,
            new Factory\Cookies\CookiesFactory,
            new Factory\Query\QueryFactory,
            new Factory\Form\FormFactory,
            new Factory\Files\FilesFactory
        );
    }
}


<?php

namespace Igorwanbarros\Php2Html\Form;

use Igorwanbarros\Php2Html\AbstractHtml;
use Igorwanbarros\Php2Html\TagHtml;
use Igorwanbarros\Php2Html\ViewAbstract;

/**
 * Class Field
 * @package Igorwanbarros\Php2Html\Form
 */
abstract class Field extends ViewAbstract
{

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

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

    /**
     * @var null|string
     */
    protected $value;

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

    /**
     * @var null|string
     */
    protected $id;

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

    /**
     * @var string
     */
    protected $tagName  = 'input';

    /**
     * @var int|string
     */
    protected $size     = 4;

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

    /**
     * @param string        $name
     * @param string        $label
     * @param null|string   $value
     */
    public function __construct($name, $label = '', $value = null)
    {
        parent::__construct();
        $this->name     = $name;
        $this->value    = $value;
        $this->label    = $label;
    }

    /**
     * @param string        $name
     * @param string        $label
     * @param null|string   $value
     *
     * @return $this
     */
    public static function create($name, $label = '', $value = null)
    {
        return new static($name, $label, $value);
    }

    /**
     * @return string
     */
    public function render($template = null)
    {
        if ($template) {
            return parent::render($template);
        }

        $field = $this->_createFieldHtml();

        $this->_addAttributesFieldHtml($field);

        return $field->render();
    }

    /**
     * @return $this|AbstractHtml
     */
    protected function _createFieldHtml()
    {
        $field = TagHtml::source($this->tagName)
            ->addAttributeRaw('type', $this->type)
            ->addAttributeRaw('name', $this->name)
            ->addAttributeRaw('id', $this->getId())
            ->addAttributeRaw('value', $this->value);

        return $field;
    }

    /**
     * @param AbstractHtml $field
     */
    protected function _addAttributesFieldHtml(AbstractHtml $field)
    {
        if (count($this->attributes) > 0) {
            foreach ($this->attributes as $key => $value) {
                $field->addAttributeRaw($key, $value);
            }
        }
    }

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

    /**
     * @return null|string
     */
    public function getId()
    {
        if ($this->id == null) {
            $this->id = $this->name;
        }

        return $this->id;
    }

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

        return $this;
    }

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

    /**
     * @param string $label
     *
     * @return $this
     */
    public function setLabel($label)
    {
        $this->label = $label;

        return $this;
    }

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

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

        return $this;
    }

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

    /**
     * @param string $type
     *
     * @return $this
     */
    public function setType($type)
    {
        $this->type = $type;

        return $this;
    }

    /**
     * @return null|string
     */
    public function getValue()
    {
        return $this->value;
    }

    /**
     * @param string $value
     *
     * @return $this
     */
    public function setValue($value)
    {
        $this->value = $value;

        return $this;
    }

    /**
     * @return int|string
     */
    public function getSize()
    {
        return $this->size;
    }

    /**
     * @param int|string $size
     *
     * @return $this
     */
    public function setSize($size)
    {
        $this->size = $size;

        return $this;
    }

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

    /**
     * @param string $rule
     *
     * @return $this
     */
    public function addRule($rule)
    {
        $this->rules .= $rule;

        return $this;
    }

    public function setRule($rules)
    {
        $this->rules = $rules;

        return $this;
    }

    public function setLabelRequired($required = true)
    {
        if ($required) {
            $requiredXs = '*';
            $required = '*obrigatório';
            return $this->setLabel($this->getLabel() . $requiredXs . $required);
        }

        $label = $this->getLabel();

        if (($pos = strpos($label, '<')) !== false) {
            $label = substr($label, 0, $pos);
            return $this->setLabel($label);
        }

        return $this;
    }

    /**
     * @param TagHtml $field
     *
     * @return TagHtml
     */
    protected function _setPersonalizationAttribute(TagHtml $field)
    {
        if (array_key_exists($class = get_called_class(), static::$personalizations)) {
            foreach (static::$personalizations[$class] as $key => $value) {
                $field->addAttributeRaw($key, $value);
            }
        }

        return $field;
    }
}


<?php

namespace Igorwanbarros\Php2Html\Tabs;

use Igorwanbarros\Php2Html\Helpers;
use Igorwanbarros\Php2Html\ViewAbstract;

/**
 * Class TabsView
 * @package Igorwanbarros\Php2Html\Tabs
 */
class TabsView extends ViewAbstract
{
    const BOOTSTRAP_TABS = 'nav-tabs';
    const BOOTSTRAP_PILLS = 'nav-pills';
    const BOOTSTRAP_JUSTIFIED = 'nav-justified';

    /**
     * @var string
     */
    protected $template = 'templates/%s/tabs.php';

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

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

    /**
     * @var string
     */
    protected $class = self::BOOTSTRAP_TABS;

    /**
     * @var bool|string
     */
    protected $active = false;

    /**
     * @var array
     */
    protected $keyContents = [];

    /**
     * @param array $titles
     * @param array $contents
     */
    public function __construct(array $titles = [], array $contents = [])
    {
        parent::__construct();
        $this->setTitles($titles);
        $this->setContents($contents);
    }

    /**
     * @return array
     */
    public function getVars()
    {
        return ['tabs' => $this];
    }

    /**
     * @return array
     */
    public function getContents()
    {
        return $this->contents;
    }

    /**
     * @param array $contents
     *
     * @return $this
     */
    public function setContents(array $contents)
    {
        foreach ($contents as $name => $content) {
            $this->_preparedContent($name, $content);
        }

        return $this;
    }

    /**
     * @param string|array $name
     * @param string|null  $content
     *
     * @return $this
     */
    public function addContent($name, $content = null)
    {
        if (is_array($name)) {
            return $this->setContents($name);
        }

        return $this->_preparedContent($name, $content);
    }

    /**
     * @return array
     */
    public function getTitles()
    {
        return $this->titles;
    }

    /**
     * @param array $titles
     *
     * @return $this
     */
    public function setTitles(array $titles)
    {
        foreach ($titles as $name => $title) {
            $this->_preparedTitle($name, $title);
        }

        return $this;
    }

    /**
     * @param string|array  $name
     * @param string|null   $title
     *
     * @return $this
     */
    public function addTitle($name, $title = null)
    {
        if (is_array($name)) {
            return $this->setTitles($name);
        }

        return $this->_preparedTitle($name, $title);
    }

    /**
     * @param string|int    $name
     * @param string        $title
     *
     * @return $this
     */
    protected function _preparedTitle($name, $title)
    {
        $name = is_int($name) ? $title : $name;
        $name = Helpers::normalize($name);
        $name = strtolower(str_replace(' ', '-', $name));

        if (!$this->active) {
            $this->active = $name;
        }

        $this->titles[$name] = $title;

        return $this;
    }

    /**
     * @param string|int $titleName
     * @param string     $content
     *
     * @return $this
     */
    protected function _preparedContent($titleName, $content)
    {
        $titleName = is_int($titleName) ? $content : $titleName;
        $titleName = Helpers::normalize($titleName);
        $titleName = strtolower(str_replace(' ', '-', $titleName));

        $this->contents[$titleName] = $content;

        return $this;
    }

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

    /**
     * @param $class
     *
     * @return $this
     */
    public function setClass($class)
    {
        $this->class = $class;
        return $this;
    }

    /**
     * @return bool|string
     */
    public function getActive()
    {
        return $this->active;
    }

    /**
     * @param string $active
     *
     * @return $this
     */
    public function setActive($active)
    {
        $this->active = $active;
        return $this;
    }
}


<?php
/*
 * Copyright (c) 2012-2016, Hofmänner New Media.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This file is part of the N2N FRAMEWORK.
 *
 * The N2N FRAMEWORK is free software: you can redistribute it and/or modify it under the terms of
 * the GNU Lesser General Public License as published by the Free Software Foundation, either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * N2N is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details: http://www.gnu.org/licenses/
 *
 * The following people participated in this project:
 *
 * Andreas von Burg.....: Architect, Lead Developer
 * Bert Hofmänner.......: Idea, Frontend UI, Community Leader, Marketing
 * Thomas Günther.......: Developer, Hangar
 */
namespace n2n\impl\persistence\orm\property;

use n2n\persistence\orm\model\EntityModel;
use n2n\persistence\orm\property\EntityProperty;
use n2n\reflection\property\AccessProxy;
use n2n\util\ex\IllegalStateException;
use n2n\persistence\orm\model\EntityPropertyCollection;
use n2n\persistence\orm\EntityDataException;
use n2n\reflection\ReflectionException;
use n2n\util\type\TypeUtils;

abstract class EntityPropertyAdapter implements EntityProperty {
	private $entityModel;
	private $parent;
	protected $accessProxy;

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

	/**
	 * {@inheritDoc}
	 * @see \n2n\persistence\orm\property\EntityProperty::setEntityModel()
	 */
	public function setEntityModel(EntityModel $entityModel) {
		$this->entityModel = $entityModel;
	}

	/**
	 * {@inheritDoc}
	 * @see \n2n\persistence\orm\property\EntityProperty::getEntityModel()
	 */
	public function getEntityModel() {
		if ($this->entityModel === null) {
			throw new IllegalStateException('No EntityModel assigned.');
		}

		return $this->entityModel;
	}

	/**
	 * {@inheritDoc}
	 * @see \n2n\persistence\orm\property\EntityProperty::setParent()
	 */
	public function setParent(EntityProperty $parent) {
		$this->parent = $parent;
	}

	/**
	 * {@inheritDoc}
	 * @see \n2n\persistence\orm\property\EntityProperty::getParent()
	 */
	public function getParent() {
		return $this->parent;
	}

	/**
	 * {@inheritDoc}
	 * @see \n2n\persistence\orm\property\EntityProperty::getName()
	 */
	public function getName() {
		return $this->accessProxy->getPropertyName();
	}

	/**
	 * {@inheritDoc}
	 * @see \n2n\persistence\orm\property\EntityProperty::writeValue()
	 */
	public function writeValue($object, $value) {
		$this->accessProxy->setValue($object, $value);
	}

	/* (non-PHPdoc)
	 * @see \n2n\persistence\orm\property\EntityProperty::readValue()
	 */
	public function readValue($object) {
		try {
			return $this->accessProxy->getValue($object);
		} catch (ReflectionException $e) {
			throw new EntityDataException('Failed to read value of ' . $this, 0, $e);
		}
	}

	public function toPropertyString() {
		return TypeUtils::prettyReflPropName($this->accessProxy->getProperty());
	}

	public function copy($value) {
		return $value;
	}

	public function equals($obj) {
		return $obj instanceof EntityProperty
				&& $obj->getEntityModel()->equals($this->entityModel)
				&& $obj->getName() == $this->getName();
	}

	public function hasTargetEntityModel(): bool {
		return false;
	}

	public function getTargetEntityModel(): EntityModel {
		throw new IllegalStateException('EntityProperty contains no target EntityModel: ' . $this);
	}

	public function hasEmbeddedEntityPropertyCollection(): bool {
		return false;
	}

	public function getEmbeddedEntityPropertyCollection(): EntityPropertyCollection {
		throw new IllegalStateException('EntityProperty contains no target EntityPropertyCollection: ' . $this);
	}

	public function __toString(): string {
		return (new \ReflectionClass($this))->getShortName() . ' [' . $this->accessProxy . ']';
	}
}


<?php
declare(strict_types = 1);

namespace Innmind\Http\Message\Environment;

use Innmind\Http\{
    Message\Environment as EnvironmentInterface,
    Exception\EnvironmentVariableNotFound
};
use Innmind\Immutable\{
    MapInterface,
    Map
};

final class Environment implements EnvironmentInterface
{
    private $variables;

    public function __construct(MapInterface $variables = null)
    {
        $variables = $variables ?? new Map('string', 'scalar');

        if (
            (string) $variables->keyType() !== 'string' ||
            (string) $variables->valueType() !== 'scalar'
        ) {
            throw new \TypeError(
                'Argument 1 must be of type MapInterface<string, scalar>'
            );
        }

        $this->variables = $variables;
    }

    /**
     * {@inheritdoc}
     */
    public function get(string $name)
    {
        if (!$this->has($name)) {
            throw new EnvironmentVariableNotFound;
        }

        return $this->variables->get($name);
    }

    /**
     * {@inheritdoc}
     */
    public function has(string $name): bool
    {
        return $this->variables->contains($name);
    }

    /**
     * {@inheritdoc}
     */
    public function current()
    {
        return $this->variables->current();
    }

    /**
     * {@inheritdoc}
     */
    public function key()
    {
        return $this->variables->key();
    }

    /**
     * {@inheritdoc}
     */
    public function next()
    {
        $this->variables->next();
    }

    /**
     * {@inheritdoc}
     */
    public function rewind()
    {
        $this->variables->rewind();
    }

    /**
     * {@inheritdoc}
     */
    public function valid()
    {
        return $this->variables->valid();
    }

    /**
     * {@inheritdoc}
     */
    public function count()
    {
        return $this->variables->size();
    }
}


<?php
/*
 * Copyright (c) 2012-2016, Hofmänner New Media.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This file is part of the N2N FRAMEWORK.
 *
 * The N2N FRAMEWORK is free software: you can redistribute it and/or modify it under the terms of
 * the GNU Lesser General Public License as published by the Free Software Foundation, either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * N2N is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details: http://www.gnu.org/licenses/
 *
 * The following people participated in this project:
 *
 * Andreas von Burg.....: Architect, Lead Developer
 * Bert Hofmänner.......: Idea, Frontend UI, Community Leader, Marketing
 * Thomas Günther.......: Developer, Hangar
 */
namespace n2n\impl\persistence\orm\property;

use n2n\util\type\TypeConstraint;
use n2n\reflection\property\AccessProxy;
use n2n\persistence\orm\property\BasicEntityProperty;
use n2n\persistence\orm\query\from\MetaTreePoint;
use n2n\persistence\orm\query\QueryState;
use n2n\persistence\meta\data\QueryItem;
use n2n\util\type\ArgUtils;
use n2n\persistence\orm\query\select\DateTimeSelection;
use n2n\persistence\orm\criteria\compare\DateTimeColumnComparable;
use n2n\persistence\orm\store\action\PersistAction;
use n2n\persistence\orm\store\operation\MergeOperation;
use n2n\persistence\Pdo;
use n2n\persistence\orm\store\action\RemoveAction;
use n2n\persistence\orm\EntityManager;
use n2n\persistence\orm\store\ValueHash;
use n2n\persistence\orm\store\CommonValueHash;

class DateTimeEntityProperty extends ColumnPropertyAdapter implements BasicEntityProperty {
	public function __construct(AccessProxy $accessProxy, $columnName) {
		$accessProxy->setConstraint(TypeConstraint::createSimple('DateTime', true));

		parent::__construct($accessProxy, $columnName);
	}
	/* (non-PHPdoc)
	 * @see \n2n\persistence\orm\property\ColumnComparableEntityProperty::createComparisonStrategy()
	 */
	public function createColumnComparable(MetaTreePoint $metaTreePoint, QueryState $queryState) {
		return new DateTimeColumnComparable($this->createQueryColumn($metaTreePoint->getMeta()), $queryState);
	}
	/* (non-PHPdoc)
	 * @see \n2n\persistence\orm\property\BasicEntityProperty::createColumnComparableFromQueryItem()
	 */
	public function createColumnComparableFromQueryItem(QueryItem $queryItem, QueryState $queryState) {
		return new DateTimeColumnComparable($queryItem, $queryState);
	}

	public function createSelection(MetaTreePoint $metaTreePoint, QueryState $queryState) {
		return new DateTimeSelection($this->createQueryColumn($metaTreePoint->getMeta()),
				$queryState->getEntityManager()->getPdo()->getMetaData()
						->getDialect()->getOrmDialectConfig());
	}
	/* (non-PHPdoc)
	 * @see \n2n\persistence\orm\property\BasicEntityProperty::valueToRep()
	 */
	public function valueToRep($value): string {
		ArgUtils::assertTrue($value instanceof \DateTime);

		return $value->getTimestamp();
	}
	/* (non-PHPdoc)
	 * @see \n2n\persistence\orm\property\BasicEntityProperty::repToValue()
	 */
	public function repToValue(string $rep) {
		ArgUtils::assertTrue(is_numeric($rep));
		$value = new \DateTime();
		$value->setTimestamp($rep);
		return $value;
	}

	public function supplyPersistAction(PersistAction $persistAction, $value, ValueHash $valueHash, ?ValueHash $oldValueHash) {
		$rawValue = $this->buildRaw($value, $persistAction->getActionQueue()->getEntityManager()->getPdo());

		$persistAction->getMeta()->setRawValue($this->getEntityModel(), $this->getColumnName(), $rawValue);
	}
	/* (non-PHPdoc)
	 * @see \n2n\persistence\orm\property\EntityProperty::createValueHash()
	 */
	public function createValueHash($value, EntityManager $em): ValueHash {
		if ($value === null) return new CommonValueHash(null);
		return new CommonValueHash($this->valueToRep($value));
	}
	/* (non-PHPdoc)
	 * @see \n2n\persistence\orm\property\EntityProperty::mergeValue()
	 */
	public function mergeValue($value, $sameEntity, MergeOperation $mergeOperation) {
		if ($sameEntity || $value === null) {
			return $value;
		}

		ArgUtils::assertTrue($value instanceof \DateTime);
		return clone $value;
	}
	/* (non-PHPdoc)
	 * @see \n2n\persistence\orm\property\EntityProperty::supplyRemoveAction()
	 */
	public function supplyRemoveAction(RemoveAction $removeAction, $value, ValueHash $valueHash = null) {
	}
	/* (non-PHPdoc)
	 * @see \n2n\persistence\orm\property\BasicEntityProperty::parseValue()
	 */
	public function parseValue($raw, Pdo $pdo) {
		return $pdo->getMetaData()->getDialect()->getOrmDialectConfig()->parseDateTime($raw);
	}
	/* (non-PHPdoc)
	 * @see \n2n\persistence\orm\property\BasicEntityProperty::buildRaw()
	 */
	public function buildRaw($value, Pdo $pdo) {
		return $pdo->getMetaData()->getDialect()->getOrmDialectConfig()->buildDateTimeRawValue($value);
	}
	/* (non-PHPdoc)
	 * @see \n2n\persistence\orm\property\BasicEntityProperty::createSelectionFromQueryItem()
	 */
	public function createSelectionFromQueryItem(QueryItem $queryItem, QueryState $queryState) {
		return new DateTimeSelection($queryItem, $queryState->getEntityManager()->getPdo()->getMetaData()
				->getDialect()->getOrmDialectConfig());
	}
}


<?php
/*
 * Copyright (c) 2012-2016, Hofmänner New Media.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This file is part of the N2N FRAMEWORK.
 *
 * The N2N FRAMEWORK is free software: you can redistribute it and/or modify it under the terms of
 * the GNU Lesser General Public License as published by the Free Software Foundation, either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * N2N is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details: http://www.gnu.org/licenses/
 *
 * The following people participated in this project:
 *
 * Andreas von Burg.....: Architect, Lead Developer
 * Bert Hofmänner.......: Idea, Frontend UI, Community Leader, Marketing
 * Thomas Günther.......: Developer, Hangar
 */
namespace n2n\impl\persistence\orm\property;

use n2n\persistence\orm\property\ColumnComparableEntityProperty;
use n2n\persistence\orm\property\QueryItemRepresentableEntityProperty;
use n2n\impl\persistence\orm\property\relation\ToOneRelation;
use n2n\util\type\TypeConstraint;
use n2n\persistence\orm\query\from\MetaTreePoint;
use n2n\persistence\orm\query\QueryState;
use n2n\persistence\orm\store\operation\MergeOperation;
use n2n\persistence\orm\CascadeType;
use n2n\persistence\orm\store\operation\CascadeOperation;
use n2n\persistence\orm\model\EntityPropertyCollection;

class ToOneEntityProperty extends RelationEntityPropertyAdapter implements ColumnComparableEntityProperty,
		QueryItemRepresentableEntityProperty {

	public function setRelation(ToOneRelation $relation) {
		parent::assignRelation($relation);

		$this->accessProxy->setConstraint(TypeConstraint::createSimple($relation->getTargetEntityModel()->getClass()
				->getName()));
	}

	public function createRepresentingQueryItem(MetaTreePoint $metaTreePoint, QueryState $queryState) {
		return $this->getRelation()->createRepresentingQueryItem($metaTreePoint, $queryState);
	}
	/* (non-PHPdoc)
	 * @see \n2n\persistence\orm\property\ColumnComparableEntityProperty::createColumnComparable()
	*/
	public function createColumnComparable(MetaTreePoint $metaTreePoint, QueryState $queryState) {
		return $this->getRelation()->createColumnComparable($metaTreePoint, $queryState);
	}

	public function cascade($value, $cascadeType, CascadeOperation $cascadeOperation) {
		if ($value === null) return null;

		if ($this->getRelation()->getCascadeType() & $cascadeType) {
			$cascadeOperation->cascade($value);
		}
	}
	/* (non-PHPdoc)
	 * @see \n2n\persistence\orm\property\EntityProperty::mergeValue()
	*/
	public function mergeValue($value, $sameEntity, MergeOperation $mergeOperation) {
		if ($value === null) return null;

		if ($this->relation->getCascadeType() & CascadeType::MERGE) {
			return $mergeOperation->mergeEntity($value);
		}

		return $value;
	}

	public function hasEmbeddedEntityPropertyCollection(): bool {
		return true;
	}

	public function getEmbeddedEntityPropertyCollection(): EntityPropertyCollection {
		return $this->getRelation()->getTargetEntityModel();
	}
}


<?php
namespace Igorwanbarros\Php2Html;

/**
 * Class ViewAbstract
 * @package Igorwanbarros\Php2Html
 */
abstract class ViewAbstract
{
    const PANEL_BOOTSTRAP_DEFAULT = 'panel-default';
    const PANEL_BOOTSTRAP_SUCCESS = 'panel-success';
    const PANEL_BOOTSTRAP_PRIMARY = 'panel-primary';
    const PANEL_BOOTSTRAP_WARNING = 'panel-warning';
    const PANEL_BOOTSTRAP_DANGER = 'panel-danger';
    const PANEL_SEMANTIC_DEFAULT = '';
    const PANEL_SEMANTIC_SUCCESS = 'green';
    const PANEL_SEMANTIC_PRIMARY = 'blue';
    const PANEL_SEMANTIC_WARNING = 'yellow';
    const PANEL_SEMANTIC_DANGER = 'red';
    const FRONT_BOOTSTRAP = 'bootstrap';
    const FRONT_SEMANTIC = 'semantic';
    const TABLE_SEMANTIC = 'ui striped selectable table';
    const TABLE_BOOTSTRAP = 'table table-striped table-hover';

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

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

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

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

    /**
     * @var string
     */
    protected $front = self::FRONT_BOOTSTRAP;

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

    /**
     * @var array
     */
    protected static $personalizations = [];

    public function __construct()
    {
        $this->_initPersonalizationByClass();
    }

    protected function _initPersonalizationByClass()
    {
        if (array_key_exists($class = get_called_class(), self::$personalizations)) {
            return;
        }

        self::$personalizations[$class] = [];
    }

    /**
     * @return array
     */
    public static function getPersonalizations()
    {
        return array_key_exists($class = get_called_class(), self::$personalizations)
            ? self::$personalizations[$class]
            : [];
    }

    /**
     * @param array $personalizations
     */
    public static function setPersonalizations(array $personalizations)
    {
        self::$personalizations = array_merge(self::$personalizations, $personalizations);
    }

    /**
     * @param $propertie
     * @param $value
     */
    public static function addPersonalization($propertie, $value)
    {
        self::$personalizations[get_called_class()][$propertie] = $value;
    }

    protected function _personalizeView()
    {
        $class = get_called_class();

        if (!array_key_exists($class, self::$personalizations)) {
            return;
        }

        $attributes = self::$personalizations[$class];

        foreach ($attributes as $key => $value) {
            $key = ucwords(str_replace(['_', '-'], ' ', $key));
            $key = lcfirst(str_replace(' ', '', $key));

            if (!property_exists($class, $key)) {
                continue;
            }

            $this->{$key} = $value;
        }
    }

    /**
     * @return $this
     */
    public static function source()
    {
        $args   = func_get_args();
        $class  = new \ReflectionClass(get_called_class());

        return $class->newInstanceArgs($args);
    }

    /**
     * @param string $method
     * @param array $arguments
     *
     * @return $this|mixed
     */
    public function __call($method, $arguments)
    {
        if ($this->_callSetAttributes($method, $arguments)) {
            return $this;
        }

        if ($getAttributes = $this->_callGetAttributes($method)) {
            return $getAttributes;
        }
    }

    /**
     * @return string
     */
    public function getBasePath()
    {
        return $this->basePath ? $this->basePath : __DIR__ . '/';
    }

    /**
     * @param string $basePath
     *
     * @return $this
     */
    public function setBasePath($basePath)
    {
        $this->basePath = $basePath;
        return $this;
    }

    /**
     * @return array
     */
    public function getVars()
    {
        return is_array($this->vars) ? $this->vars : ['this' => $this];
    }

    /**
     * @param array $vars
     *
     * @return $this
     */
    public function setVars(array $vars)
    {
        $this->vars = $vars;
        return $this;
    }

    /**
     * @param null|string $template
     *
     * @return string
     * @throws \Exception
     */
    public function render($template = null)
    {
        $this->_personalizeView();
        try {
            ob_start();

            $template = $template ? $template : $this->getBasePath() . $this->getTemplate();

            if (!file_exists($template)) {
                throw new \Exception("O caminho do template '{$template}' informado não foi encontrado :(");
            }

            extract($this->getVars(), EXTR_OVERWRITE);

            include $template;

            $this->output = ob_get_contents();

            ob_end_clean();
        } catch (\Exception $e) {
            $this->output = "
" .
                    "Não foi possível exibir a view solicitada.
" .
                    "{$e->getMessage()}" .
                "
";
        }

        return $this->output;
    }

    /**
     * @return string
     * @throws \Exception
     */
    public function __toString()
    {
        return $this->render();
    }

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

    /**
     * @param string $output
     *
     * @return $this
     */
    public function setOutput($output)
    {
        $this->output = $output;
        return $this;
    }

    /**
     * @return string
     */
    public function getTemplate()
    {
        if (strpos($this->template, '%s') !== false)
            $this->template = sprintf($this->template, $this->front);

        return $this->template;
    }

    /**
     * @param string $template
     *
     * @return $this
     */
    public function setTemplate($template)
    {
        $this->template = $template;
        return $this;
    }

    /**
     * Retorna qual front o elemento esta utilizando
     *
     * @return string
     */
    public function getFront()
    {
        return $this->front;
    }

    /**
     * Definir qual front o elemento vai utilizar
     *
     * @param string $front
     *
     * @return $this
     */
    public function setFront($front)
    {
        $this->front = $front;

        return $this;
    }

    /**
     * @return array|string
     */
    public function getAttributes()
    {
        return $this->attributes;
    }

    /**
     * @param $key
     *
     * @return null
     */
    public function getAttribute($key)
    {
        return array_key_exists($key, $this->attributes) ? $this->attributes[$key] : null;
    }

    /**
     * @return string
     */
    public function renderAttributes()
    {
        $string = '';

        if (is_array($this->attributes)) {
            foreach ($this->attributes as $key => $value) {
                $string .= " $key=\"$value\"";
            }
        }

        return $string;
    }

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

        return $this;
    }

    /**
     * @param string|array  $key
     * @param string|null   $value
     *
     * @return $this
     */
    public function addAttribute($key, $value = null)
    {
        if (is_array($key)) {
            return $this->setAttributes($key);
        }

        $key = Helpers::camelCase($key);

        if (is_array($this->attributes) && array_key_exists($key, $this->attributes)) {
            $this->attributes[$key] .= " $value";

            return $this;
        }

        $this->attributes[$key] = $value;

        return $this;
    }

    private function _callGetAttributes($method)
    {
        $key = Helpers::camelCase(str_replace(['get', 'attribute', 'Attribute'], '', $method));
        $method = strtolower($method);

        if (strpos($method, 'attribute') === false &&
            strpos($method, 'get') === false) {
            return false;
        }

        if (!array_key_exists($key, $this->attributes)) {
            return false;
        }

        return $this->attributes[$key];
    }

    private function _callSetAttributes($method, $arguments)
    {
        $key = str_replace(['set', 'attribute', 'Attribute'], '', $method);
        $method = strtolower($method);

        if (strpos($method, 'attribute') === false &&
            strpos($method, 'set') === false
        ) {
            return false;
        }

        if (!isset($arguments[0])) {
            return false;
        }

        return $this->addAttribute($key, $arguments[0]);
    }
}


<?php

/*
 * This file is part of the Wid'op package.
 *
 * (c) Wid'op <contact@widop.com>
 *
 * For the full copyright and license information, please read the LICENSE
 * file that was distributed with this source code.
 */

namespace Widop\Twitter\Options;

/**
 * Abstract boolean option.
 *
 * @author Geoffrey Brier <geoffrey.brier@gmail.com>
 */
abstract class AbstractBooleanOption extends AbstractOption
{
    /**
     * {@inheritdoc}
     */
    public function setValue($value)
    {
        if (!is_bool($value) && ($value !== null)) {
            throw new \InvalidArgumentException(sprintf(
                'The option "%s" only accepts boolean value.',
                $this->getName()
            ));
        }

        parent::setValue($value);
    }

    /**
     * {@inheritdoc}
     */
    public function getNormalizedValue()
    {
        return json_encode($this->getValue());
    }
}


<?php
declare(strict_types = 1);

namespace Innmind\Http\Message\Query;

use Innmind\Http\{
    Message\Query as QueryInterface,
    Exception\QueryParameterNotFound
};
use Innmind\Immutable\{
    MapInterface,
    Map,
    Sequence
};

final class Query implements QueryInterface
{
    private $parameters;

    public function __construct(MapInterface $parameters = null)
    {
        $parameters = $parameters ?? new Map('string', Parameter::class);

        if (
            (string) $parameters->keyType() !== 'string' ||
            (string) $parameters->valueType() !== Parameter::class
        ) {
            throw new \TypeError(sprintf(
                'Argument 1 must be of type MapInterface<string, %s>',
                Parameter::class
            ));
        }

        $this->parameters = $parameters;
    }

    public static function of(Parameter ...$parameters): self
    {
        return new self(
            Sequence::of(...$parameters)->reduce(
                new Map('string', Parameter::class),
                static function(MapInterface $parameters, Parameter $parameter): MapInterface {
                    return $parameters->put(
                        $parameter->name(),
                        $parameter
                    );
                }
            )
        );
    }

    /**
     * {@inheritdoc}
     */
    public function get(string $name): Parameter
    {
        if (!$this->has($name)) {
            throw new QueryParameterNotFound;
        }

        return $this->parameters->get($name);
    }

    /**
     * {@inheritdoc}
     */
    public function has(string $name): bool
    {
        return $this->parameters->contains($name);
    }

    /**
     * {@inheritdoc}
     */
    public function current()
    {
        return $this->parameters->current();
    }

    /**
     * {@inheritdoc}
     */
    public function key()
    {
        return $this->parameters->key();
    }

    /**
     * {@inheritdoc}
     */
    public function next()
    {
        $this->parameters->next();
    }

    /**
     * {@inheritdoc}
     */
    public function rewind()
    {
        $this->parameters->rewind();
    }

    /**
     * {@inheritdoc}
     */
    public function valid()
    {
        return $this->parameters->valid();
    }

    /**
     * {@inheritdoc}
     */
    public function count()
    {
        return $this->parameters->size();
    }
}