ACC SHELL

Path : /srv/www/vhosts/stakk/libs/Nette/Database/Table/
File Upload :
Current File : /srv/www/vhosts/stakk/libs/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)
 *
 * For the full copyright and license information, please view
 * the file license.txt that was distributed with this source code.
 */

namespace Nette\Database\Table;

use Nette;



/**
 * 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
 */
class GroupedSelection extends Selection
{
	/** @var Selection referenced table */
	protected $refTable;

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

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

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

	/** @var array of referencing cached results */
	protected $referencing;

	/** @var array of [conditions => [key => ActiveRow]] */
	protected $aggregation = array();



	public function __construct($name, Selection $refTable, $column)
	{
		parent::__construct($name, $refTable->connection);
		$this->refTable = $refTable;
		$this->column = $column;
		$this->delimitedColumn = $this->connection->getSupplementalDriver()->delimite($this->column);
	}



	/**
	 * @internal
	 * @param  int  $active
	 * @return GroupedSelection
	 */
	public function setActive($active)
	{
		$this->rows = NULL;
		$this->active = $active;
		$this->select = $this->where = $this->conditions = $this->parameters = $this->order = array();
		$this->limit = $this->offset = NULL;
		$this->group = $this->having = '';
		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->select) {
			$this->select[] = "$this->delimitedName.$this->delimitedColumn";
		}
		return parent::select($columns);
	}



	public function order($columns)
	{
		if (!$this->order) { // improve index utilization
			$this->order[] = "$this->delimitedName.$this->delimitedColumn"
				. (preg_match('~\\bDESC$~i', $columns) ? ' DESC' : '');
		}
		return parent::order($columns);
	}



	public function aggregation($function)
	{
		$aggregation = & $this->aggregation[$function . implode('', $this->where) . implode('', $this->conditions)];
		if ($aggregation === NULL) {
			$aggregation = array();

			$selection = new Selection($this->name, $this->connection);
			$selection->where = $this->where;
			$selection->parameters = $this->parameters;
			$selection->conditions = $this->conditions;

			$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 = '')
	{
		$return = parent::count($column);
		return isset($return) ? $return : 0;
	}



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

		if (Nette\Utils\Validators::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)
	{
		$condition = array($this->where, $this->parameters);

		$this->where[0] = "$this->delimitedColumn = ?";
		$this->parameters[0] = $this->active;
		$return = parent::update($data);

		list($this->where, $this->parameters) = $condition;
		return $return;
	}



	public function delete()
	{
		$condition = array($this->where, $this->parameters);

		$this->where[0] = "$this->delimitedColumn = ?";
		$this->parameters[0] = $this->active;
		$return = parent::delete();

		list($this->where, $this->parameters) = $condition;
		return $return;
	}



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

		$hash = md5($this->getSql() . json_encode($this->parameters));
		$referencing = & $this->referencing[$hash];
		if ($referencing === NULL) {
			$limit = $this->limit;
			$rows = count($this->refTable->rows);
			if ($this->limit && $rows > 1) {
				$this->limit = NULL;
			}
			parent::execute();
			$this->limit = $limit;
			$referencing = array();
			$offset = array();
			foreach ($this->rows as $key => $row) {
				$ref = & $referencing[$row[$this->column]];
				$skip = & $offset[$row[$this->column]];
				if ($limit === NULL || $rows <= 1 || (count($ref) < $limit && $skip >= $this->offset)) {
					$ref[$key] = $row;
				} else {
					unset($this->rows[$key]);
				}
				$skip++;
				unset($ref, $skip);
			}
		}

		$this->data = & $referencing[$this->active];
		if ($this->data === NULL) {
			$this->data = array();
		} else {
			reset($this->data);
		}
	}

}

ACC SHELL 2018