aboutsummaryrefslogtreecommitdiff
path: root/lib/models/SimpleORMapCollection.class.php
diff options
context:
space:
mode:
Diffstat (limited to 'lib/models/SimpleORMapCollection.class.php')
-rw-r--r--lib/models/SimpleORMapCollection.class.php261
1 files changed, 0 insertions, 261 deletions
diff --git a/lib/models/SimpleORMapCollection.class.php b/lib/models/SimpleORMapCollection.class.php
deleted file mode 100644
index f06ee17..0000000
--- a/lib/models/SimpleORMapCollection.class.php
+++ /dev/null
@@ -1,261 +0,0 @@
-<?php
-/**
- * SimpleORMapCollection.class.php
- * simple object-relational mapping
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * @author André Noack <noack@data-quest.de>
- * @copyright 2012 Stud.IP Core-Group
- * @license http://www.gnu.org/licenses/gpl-2.0.html GPL version 2
- * @category Stud.IP
- *
- * @extends SimpleCollection<SimpleORMap>
- *
- * @template T of SimpleORMap
- */
-class SimpleORMapCollection extends SimpleCollection
-{
- /**
- * @var int Exception error code denoting a wrong type of objects.
- */
- const WRONG_OBJECT_TYPE = 1;
-
- /**
- * @var int Exception error code denoting that an object of this `id` already exists.
- */
- const OBJECT_EXISTS = 2;
-
- /**
- * the record object this collection belongs to
- *
- * @var ?SimpleORMap
- */
- protected $related_record;
-
- /**
- * relation options
- * @var array
- */
- protected $relation_options = [];
-
- /**
- * creates a collection from an array of objects
- * all objects should be of the same type
- *
- * @throws InvalidArgumentException if first entry is not SimpleOrMap
- * @param T[] $data array with SimpleORMap objects
- * @param bool $strict check every element for correct type and unique pk
- * @return SimpleORMapCollection<T>
- */
- public static function createFromArray(array $data, $strict = true)
- {
- $ret = new SimpleORMapCollection();
- if (count($data)) {
- $first = current($data);
- if ($first instanceof SimpleORMap) {
- $ret->setClassName(get_class($first));
- if ($strict) {
- foreach ($data as $one) {
- $ret[] = $one;
- }
- } else {
- $ret->exchangeArray($data);
- }
- } else {
- throw new InvalidArgumentException('This collection only accepts objects derived from SimpleORMap', self::WRONG_OBJECT_TYPE);
- }
- }
- return $ret;
- }
-
- /**
- * Constructor
- *
- * @param ?Closure $finder callable to fill collection
- * @param ?array $options relationship options
- * @param SimpleORMap|null $record related record
- */
- public function __construct(Closure $finder = null, array $options = null, SimpleORMap $record = null)
- {
- $this->relation_options = $options;
- $this->related_record = $record;
- parent::__construct($finder === null ? [] : $finder);
- }
-
- /**
- * Sets the value at the specified index
- * checks if the value is an object of specified class
- *
- * @see ArrayObject::offsetSet()
- * @throws InvalidArgumentException if the given model does not fit (wrong type or id)
- *
- * @todo Add void return type when Stud.IP requires PHP8 minimal
- */
- #[ReturnTypeWillChange]
- public function offsetSet($index, $newval)
- {
- if (!is_null($index)) {
- $index = (int)$index;
- }
- if (!is_a($newval, $this->getClassName())) {
- throw new InvalidArgumentException('This collection only accepts objects of type: ' . $this->getClassName(), self::WRONG_OBJECT_TYPE);
- }
- if ($this->related_record && $this->relation_options['type'] === 'has_many') {
- $foreign_key_value = call_user_func($this->relation_options['assoc_func_params_func'], $this->related_record);
- call_user_func($this->relation_options['assoc_foreign_key_setter'], $newval, $foreign_key_value);
- }
- if ($newval->id !== null) {
- $exists = $this->find($newval->id);
- if ($exists) {
- throw new InvalidArgumentException('Element could not be appended, element with id: ' . $exists->id . ' is in the way', self::OBJECT_EXISTS);
- }
- }
- parent::offsetSet($index, $newval);
- }
-
- /**
- * sets the allowed class name
- * @param class-string $class_name
- * @return void
- */
- public function setClassName($class_name)
- {
- $this->relation_options['class_name'] = strtolower($class_name);
- $this->deleted->relation_options['class_name'] = strtolower($class_name);
- }
-
- /**
- * sets the related record
- *
- * @param SimpleORMap $record
- * @return void
- */
- public function setRelatedRecord(SimpleORMap $record)
- {
- $this->related_record = $record;
- }
-
- /**
- * gets the allowed classname
- *
- * @return string
- */
- public function getClassName()
- {
- return strtolower($this->relation_options['class_name']);
- }
-
- /**
- * reloads the elements of the collection
- * by calling the finder function
- *
- * @throws InvalidArgumentException
- * @return ?int number of records after refresh
- */
- public function refresh()
- {
- if (is_callable($this->finder)) {
- $data = call_user_func($this->finder, $this->related_record);
- foreach ($data as $one) {
- if (!is_a($one, $this->getClassName())) {
- throw new InvalidArgumentException('This collection only accepts objects of type: ' . $this->getClassName(), self::WRONG_OBJECT_TYPE);
- }
- }
- $this->exchangeArray($data);
- $this->deleted->exchangeArray([]);
- return $this->last_count = $this->count();
- }
-
- return null;
- }
-
- /**
- * returns element with given primary key value
- *
- * @param string $value primary key value to search for
- * @return ?T
- */
- public function find($value)
- {
- return $this->findOneBy('id', $value);
- }
-
- /**
- * returns the collection as grouped array
- * first param is the column to group by, it becomes the key in
- * the resulting array, default is pk. Limit returned fields with second param
- * The grouped entries can optoionally go through the given
- * callback. If no callback is provided, only the first grouped
- * entry is returned, suitable for grouping by unique column
- *
- * @param string $group_by the column to group by, pk if ommitted
- * @param mixed $only_these_fields limit returned fields
- * @param ?callable $group_func closure to aggregate grouped entries
- * @return array assoc array
- */
- public function toGroupedArray($group_by = 'id', $only_these_fields = null, callable $group_func = null)
- {
- $result = [];
- foreach ($this as $record) {
- $key = $record->getValue($group_by);
- if (is_array($key)) {
- $key = join('_', $key);
- }
- $result[$key][] = $record->toArray($only_these_fields);
- }
- if ($group_func === null) {
- $group_func = 'current';
- }
- return array_map($group_func, $result);
- }
-
- /**
- * mark element(s) for deletion
- * element(s) with given primary key are moved to
- * internal deleted collection
- *
- * @param string $id primary key of element
- * @return int number of unsetted elements
- */
- public function unsetByPk($id)
- {
- return $this->unsetBy('id', $id);
- }
-
- /**
- * merge in another collection, elements must be of
- * the same type, if an element already exists it is
- * replaced or ignored depending on second param
- *
- * @param SimpleORMapCollection $a_collection
- * @param string $mode 'replace' or 'ignore'
- * @return void
- */
- public function merge(SimpleCollection $a_collection, string $mode = 'ignore')
- {
- $mode = func_get_arg(1);
- foreach ($a_collection as $element) {
- try {
- /**
- * @throws InvalidArgumentException
- * @see SimpleORMapCollection::offsetSet()
- */
- $this[] = $element;
- } catch (InvalidArgumentException $e) {
- if ($e->getCode() === self::OBJECT_EXISTS) {
- if ($mode === 'replace') {
- $this->unsetByPk($element->id);
- $this[] = $element;
- } // else $mode means 'ignore'
- } else {
- throw $e;
- }
- }
- }
- $this->storage = array_values($this->storage);
- }
-}