parent = $parent; $definitions = $parent->Definitions(); $classLeft = "\\Resources\\".$definitions["left"]["resourceClass"]; $this->left = $classLeft::; foreach ($definitions["ids"] as $id => $className) { $class = "\\Resources\\".$className; $this->ids[$id] = isset($data[$id]) ? $class::Get()->RefByData($data[$id]) : null; } $this->fields = array_combine(array_keys($definitions["fields"]), array_column($definitions["fields"], "value")); $this->keys = array_combine(array_keys($definitions["keys"]), array_column($definitions["keys"], "reference")); $this->Patch($data); } public function ID($key) {return $this->ids[$key];} public function Patch($data) { // Overwrite field values if data exists foreach ($this->fields as $field => &$value) { if (isset($data[$field])) { $value = $data[$field]; } } unset($value); // If removed, $value would still point to last element of fields $definitions = $this->parent->Definitions(); foreach ($this->keys as $key => &$reference) { if (isset($data[$key])) { $class = "\\Resources\\".$definitions["keys"][$key]["resourceClass"]; $reference = is_array($data[$key]) ? $class::Get()->RefByData($data[$key]) : $class::Get()->RefById($data[$key]); } } unset($reference); // If removed, $reference would still point to last element of keys } public function Store() { $ids = []; $fields = []; $values = []; $types = ""; $definitions = $this->parent->Definitions(); if (!empty($definitions["fields"]) || !empty($definitions["keys"])) { foreach ($definitions["fields"] as $field => $def) { $fields[] = $field." = ?"; $values[] = $this->fields[$field]; $types.= $def["type"]; } foreach ($definitions["keys"] as $key => $def) { $fields[] = $key; $values[] = is_null($this->keys[$key]) ? null : $this->keys[$key]->ID(); $types.= $def["type"]; } foreach ($this->ids as $id => $reference) { $ids[] = $id." = ?"; $values[] = $reference->ID(); $types.= "s"; } $qry = "UPDATE ".$this->parent->Table()." SET ".implode(", ", $fields)." WHERE ".implode(" AND ", $ids); if ($stmt = \DB::Get()->prepare($qry)) { $stmt->bind_param($types, ...$values); if ($stmt->execute()) { $this->parent->UpdateChecksum(); return true; } } \Response::Get()->DbError(); return false; } return true; } public function Json($depth = null) { if (is_null($depth)) { $depth = \Request::DetailDepth(); } $ret = []; foreach ($this->ids as $id => $reference) { $ret[$key] = is_null($reference) ? null : ($depth>0 ? $reference->Json($depth-1) : $reference->ID()); } foreach ($this->fields as $field => $value) { $ret[$field] = $value; } foreach ($this->keys as $key => $reference) { $ret[$key] = is_null($reference) ? null : ($depth>0 ? $reference->Json($depth-1) : $reference->ID()); } return $ret; } }*/ abstract class Link { protected static $instances = []; protected $leftIndex = []; protected $rightIndex = []; public static function Get() { $class = get_called_class(); if (!isset($instances[$class])) { self::$instances[$class] = new $class(); } return self::$instances[$class]; } private function __construct() {} public function Table() {return $this->names["table"];} public function Short() {return $this->names["short"];} public function TableWithShort() {return $this->names["table"]." ".$this->names["short"];} public function RefList($id, $target, $dataOrIds = null) { if ($target==$this->definitions["left"]["ident"]) { // We come from right if (!isset($this->rightIndex[$id])) { $this->rightIndex[$id] = is_array($dataOrIds) ? $this->connect("left", $dataOrIds) : $this->load("left", $id); } return $this->rightIndex[$id]; } else { // We come from left if (!isset($this->leftIndex[$id])) { $this->rightIndex[$id] = is_array($dataOrIds) ? $this->connect("right", $dataOrIds) : $this->load("right", $id); } return $this->leftIndex[$id]; } } public function Unset($id, $target, $targetId) { $idIsRight = $target==$this->definitions["left"]["ident"]; $qry = "DELETE FROM ".$this->Table()." WHERE ".$this->definitions["left"]["ident"]." = ? AND ".$this->definitions["right"]["ident"]." = ?"; if ($stmt = \DB::Get()->prepare($qry)) { if ($idIsRight) { $stmt->bind_param("ss", $targetId, $id); } else { $stmt->bind_param("ss", $id, $targetId); } if ($stmt->execute()) { if (1==$stmt->affected_rows) { if ($idIsRight) { $this->indexRight[$id] = $this->load("left", $id); } else { $this->indexLeft[$id] = $this->load("right", $id); } return true; } else if (0==$stmt->affected_rows) { \Response::Get()->Message("Fehler: Es wurde nichts entfernt!"); } else { \Response::Get()->Message("Fehler: Es wurden mehrere Einträge entfernt!"); } } } \Response::Get()->DbError(); return false; } public function Set($id, $target, $targetId) { $idIsRight = $target==$this->definitions["left"]["ident"]; $qry = "INSERT INTO ".$this->Table()." (".$this->definitions["left"]["ident"].",".$this->definitions["right"]["ident"].") VALUES (?, ?)"; if ($stmt = \DB::Get()->prepare($qry)) { if ($idIsRight) { $stmt->bind_param("ss", $targetId, $id); } else { $stmt->bind_param("ss", $id, $targetId); } if ($stmt->execute()) { if ($idIsRight) { $this->indexRight[$id] = $this->load("left", $id); } else { $this->indexLeft[$id] = $this->load("right", $id); } return true; } } \Response::Get()->DbError(); return false; } protected function connect($target, $dataOrIds) { $targetClass = "\\Resources\\".$this->definitions[$target]["resourceClass"]; $ret = []; foreach ($dataOrIds as $dataOrId) { if (is_array($dataOrId)) { $ret[] = $targetClass::Get()->RefByData($dataOrId); } else { $ret[] = $targetClass::Get()->RefById($dataOrId); } } return $ret; } protected function load($target, $id) { $source = "left" == $target ? "right" : "left"; $sourceField = $this->definitions[$source]["ident"]; $targetField = $this->definitions[$target]["ident"]; $targetClass = "\\Resources\\".$this->definitions[$target]["resourceClass"]; $qry = "SELECT ".$targetField." FROM ".$this->Table()." WHERE ".$sourceField." = ?"; if ($stmt = \DB::Get()->prepare($qry)) { if (!is_null($id)) { $stmt->bind_param("s", $id); } if ($stmt->execute()) { $res = $stmt->get_result(); $ret = []; while ($row = $res->fetch_assoc()) { $ret[] = $targetClass::Get()->RefById($row[$targetField]); } return $ret; } } \Response::Get()->DbError(); return []; } }