ACC SHELL

Path : /srv/www/vhosts/centrumlb/3rdparty/Nette/Database/Table/
File Upload :
Current File : /srv/www/vhosts/centrumlb/3rdparty/Nette/Database/Table/GroupedSelection.php

<?php

/**
 * This file is part of the Nette Framework (http://nette.org)
 * Copyright (c) 2004 David Grudl (http://davidgrudl.com)
 * @package Nette\Database\Table
 */



/**
 * Representation of filtered table grouped by some column.
 * GroupedSelection is based on the great library NotORM http://www.notorm.com written by Jakub Vrana.
 *
 * @author     Jakub Vrana
 * @author     Jan Skrasek
 * @package Nette\Database\Table
 */
class NGroupedTableSelection extends NTableSelection
{
	/** @var NTableSelection referenced table */
	protected $refTable;

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

	/** @var int primary key */
	protected $active;


	/**
	 * Creates filtered and grouped table representation.
	 * @param  NTableSelection  $refTable
	 * @param  string  database table name
	 * @param  string  joining column
	 */
	public function __construct(NTableSelection $refTable, $table, $column)
	{
		parent::__construct($table, $refTable->connection);
		$this->refTable = $refTable;
		$this->column = $column;
	}


	/**
	 * Sets active group.
	 * @internal
	 * @param  int  primary key of grouped rows
	 * @return NGroupedTableSelection
	 */
	public function setActive($active)
	{
		$this->active = $active;
		return $this;
	}


	/** @deprecated */
	public function through($column)
	{
		trigger_error(__METHOD__ . '() is deprecated; use ' . __CLASS__ . '::related("' . $this->name . '", "' . $column . '") instead.', E_USER_WARNING);
		$this->column = $column;
		$this->delimitedColumn = $this->refTable->connection->getSupplementalDriver()->delimite($this->column);
		return $this;
	}


	public function select($columns)
	{
		if (!$this->sqlBuilder->getSelect()) {
			$this->sqlBuilder->addSelect("$this->name.$this->column");
		}

		return parent::select($columns);
	}


	public function order($columns)
	{
		if (!$this->sqlBuilder->getOrder()) {
			// improve index utilization
			$this->sqlBuilder->addOrder("$this->name.$this->column" . (preg_match('~\bDESC\z~i', $columns) ? ' DESC' : ''));
		}

		return parent::order($columns);
	}


	/********************* aggregations ****************d*g**/


	public function aggregation($function)
	{
		$aggregation = & $this->getRefTable($refPath)->aggregation[$refPath . $function . $this->getSql() . json_encode($this->sqlBuilder->getParameters())];

		if ($aggregation === NULL) {
			$aggregation = array();

			$selection = $this->createSelectionInstance();
			$selection->getSqlBuilder()->importConditions($this->getSqlBuilder());
			$selection->select($function);
			$selection->select("$this->name.$this->column");
			$selection->group("$this->name.$this->column");

			foreach ($selection as $row) {
				$aggregation[$row[$this->column]] = $row;
			}
		}

		if (isset($aggregation[$this->active])) {
			foreach ($aggregation[$this->active] as $val) {
				return $val;
			}
		}
	}


	public function count($column = NULL)
	{
		$return = parent::count($column);
		return isset($return) ? $return : 0;
	}


	/********************* internal ****************d*g**/


	protected function execute()
	{
		if ($this->rows !== NULL) {
			$this->observeCache = $this;
			return;
		}

		$hash = md5($this->getSql() . json_encode($this->sqlBuilder->getParameters()));
		$accessedColumns = $this->accessedColumns;

		$referencingBase = & $this->getRefTable($refPath)->referencing[$this->getCacheKey()];
		$referencing = & $referencingBase[$refPath . $hash];
		$this->rows = & $referencing['rows'];
		$this->referenced = & $referencing['refs'];
		$this->accessedColumns = & $referencing['accessed'];
		$this->observeCache = & $referencingBase['observeCache'];
		$refData = & $referencing['data'];

		if ($refData === NULL) {
			// we have not fetched any data => init accessedColumns by cached accessedColumns
			$this->accessedColumns = $accessedColumns;

			$limit = $this->sqlBuilder->getLimit();
			$rows = count($this->refTable->rows);
			if ($limit && $rows > 1) {
				$this->sqlBuilder->setLimit(NULL, NULL);
			}
			parent::execute();
			$this->sqlBuilder->setLimit($limit, NULL);
			$refData = array();
			$offset = array();
			$this->accessColumn($this->column);
			foreach ((array) $this->rows as $key => $row) {
				$ref = & $refData[$row[$this->column]];
				$skip = & $offset[$row[$this->column]];
				if ($limit === NULL || $rows <= 1 || (count($ref) < $limit && $skip >= $this->sqlBuilder->getOffset())) {
					$ref[$key] = $row;
				} else {
					unset($this->rows[$key]);
				}
				$skip++;
				unset($ref, $skip);
			}
		}

		$this->observeCache = $this;
		$this->data = & $refData[$this->active];
		if ($this->data === NULL) {
			$this->data = array();
		} else {
			foreach ($this->data as $row) {
				$row->setTable($this); // injects correct parent GroupedSelection
			}
			reset($this->data);
			$this->checkReferenced = TRUE;
		}
	}


	protected function getRefTable(& $refPath)
	{
		$refObj = $this->refTable;
		$refPath = $this->name . '.';
		while ($refObj instanceof NGroupedTableSelection) {
			$refPath .= $refObj->name . '.';
			$refObj = $refObj->refTable;
		}

		return $refObj;
	}


	/********************* manipulation ****************d*g**/


	public function insert($data)
	{
		if ($data instanceof Traversable && !$data instanceof NTableSelection) {
			$data = iterator_to_array($data);
		}

		if (NValidators::isList($data)) {
			foreach (array_keys($data) as $key) {
				$data[$key][$this->column] = $this->active;
			}
		} else {
			$data[$this->column] = $this->active;
		}

		return parent::insert($data);
	}


	public function update($data)
	{
		$builder = $this->sqlBuilder;

		$this->sqlBuilder = clone $this->sqlBuilder;
		$this->where($this->column, $this->active);
		$return = parent::update($data);

		$this->sqlBuilder = $builder;
		return $return;
	}


	public function delete()
	{
		$builder = $this->sqlBuilder;

		$this->sqlBuilder = clone $this->sqlBuilder;
		$this->where($this->column, $this->active);
		$return = parent::delete();

		$this->sqlBuilder = $builder;
		return $return;
	}

}

ACC SHELL 2018