/** * Get session variables (from 'SessionVars' interface) * @return mixed|false session variables (if interface 'SessionVars' is defined in &-script) or false otherwise */ public function getSessionVars() { if (InterfaceObject::interfaceExists('SessionVars')) { try { $this->logger->debug("Getting interface 'SessionVars' for {$this->sessionAtom->__toString()}"); return $this->sessionAtom->ifc('SessionVars')->read(['metaData' => false, 'navIfc' => false]); } catch (Exception $e) { $this->logger->warning("Error while getting SessionVars interface: " . $e->getMessage()); return false; } } else { return false; } }
/** * How to use Relation::deleteLink() to delete link (a1,b1) from r: * r :: A * B * deleteLink(a1[A], b1[B], false); * deleteLink(b1[B], a1[A], true); * * @param Atom $leftAtom * @param Atom $rightAtom * @param boolean $isFlipped * @param string $source specifies who calls this function (e.g. 'User' or 'ExecEngine') * @return void */ public function deleteLink($leftAtom, $rightAtom, $isFlipped = false, $source = 'User') { $this->logger->debug("Delete link ({$leftAtom->__toString()},{$rightAtom->__toString()}) from relation '{$this->__toString()}{({$isFlipped} ? '~' : '')}'"); // Determine src and tgt atom based on $isFlipped $srcAtom = $isFlipped ? $rightAtom : $leftAtom; $tgtAtom = $isFlipped ? $leftAtom : $rightAtom; // Checks if (!in_array($srcAtom->concept, $this->srcConcept->getSpecializationsIncl())) { throw new Exception("Cannot delete link ({$srcAtom->__toString()},{$tgtAtom->__toString()}) from relation '{$this->__toString()}', because source concept does not match relation source or its specializations", 500); } if (!in_array($tgtAtom->concept, $this->tgtConcept->getSpecializationsIncl())) { throw new Exception("Cannot delete link ({$srcAtom->__toString()},{$tgtAtom->__toString()}) from relation '{$this->__toString()}', because target concept does not match relation target or its specializations", 500); } // Delete link from relation table $this->db->deleteLink($this, $srcAtom, $tgtAtom); // Flag session var as affected when src or tgt concept of this relation is SESSION if ($srcAtom->concept->isSession() || $tgtAtom->concept->isSession()) { Session::singleton()->setSessionVarAffected(); } }
// Get list of all atoms for $resourceType (i.e. concept) $content = $concept->getAllAtomObjects(); print json_encode($content, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); }); $app->get('/resources/:resourceType/:resourceId', function ($resourceType, $resourceId) use($app) { $session = Session::singleton(); $roleIds = $app->request->params('roleIds'); $session->activateRoles($roleIds); $resource = new Atom($resourceId, Concept::getConcept($resourceType)); // Checks if (!$session->isEditableConcept($resource->concept)) { throw new Exception("You do not have access for this call", 403); } // Get specific resource (i.e. atom) if (!$resource->atomExists()) { throw new Exception("Resource '{$resource->__toString()}' not found", 404); } $content = $resource->getAtom(); print json_encode($content, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); }); /************************************************************************************************** * * resource calls WITH interfaces * *************************************************************************************************/ $app->get('/resources/:resourceType/:resourceId/:ifcPath+', function ($resourceType, $resourceId, $ifcPath) use($app) { $session = Session::singleton(); $roleIds = $app->request->params('roleIds'); $session->activateRoles($roleIds); $options = $app->request->params(); $ifcPath = implode('/', $ifcPath);
/** * Add (src,tgt) tuple in relation provided in this interface * @var array $patch * @throws Exception * @return void */ public function doPatchAdd($patch) { // CRUD check if (!$this->crudU) { throw new Exception("Update is not allowed for path '{$this->path}'", 403); } if ($this->isRef()) { throw new Exception("Cannot update on reference interface in '{$this->path}'. See #498", 501); } // Check if patch value is provided if (!array_key_exists('value', $patch)) { throw new Exception("Cannot patch add. No 'value' specfied in '{$this->path}'", 400); } $tgtAtom = new Atom($patch['value'], $this->tgtConcept); // Interface is property if ($this->isProp()) { // Properties must be treated as a 'replace', so not handled here throw new Exception("Cannot patch add for property '{$this->path}'. Use patch replace instead", 500); // Interface is a relation to an object } elseif ($this->tgtConcept->isObject) { // Check if atom exists and may be created (crudC) if (!$tgtAtom->atomExists()) { if ($this->crudC) { $tgtAtom->addAtom(); } else { throw new Exception("Resource '{$tgtAtom->__toString()}' does not exist and may not be created in {$this->path}", 403); } } // Add link when possible (relation is specified) if (is_null($this->relation)) { $this->logger->debug("addLink skipped because '{$this->path}' is not an editable expression"); } else { $this->relation()->addLink($this->srcAtom, $tgtAtom, $this->relationIsFlipped); } // Interface is a relation to a scalar (i.e. not an object) } elseif (!$this->tgtConcept->isObject) { // Check: If interface is univalent, throw exception if ($this->isUni) { throw new Exception("Cannot patch add for univalent interface {$this->path}. Use patch replace instead", 500); } $this->relation()->addLink($this->srcAtom, $tgtAtom, $this->relationIsFlipped); } else { throw new Exception("Unknown patch add. Please contact the application administrator", 500); } }
/** * Remove all occurrences of $atom in the database (all concept tables and all relation tables) * In tables where the atom may not be null, the entire row is removed. * TODO: If all relation fields in a wide table are null, the entire row could be deleted, but this doesn't happen now. As a result, relation queries may return some nulls, but these are filtered out anyway. * @param \Ampersand\Core\Atom $atom * @return void */ function deleteAtom($atom) { $this->logger->debug("deleteAtom({$atom->__toString()})"); // This function is under control of transaction check! if (!isset($this->transaction)) { $this->startTransaction(); } $concept = $atom->concept; // Delete atom from concept table $conceptTable = $concept->getConceptTableInfo(); $query = "DELETE FROM `{$conceptTable->name}` WHERE `{$conceptTable->getFirstCol()->name}` = '{$atom->idEsc}' LIMIT 1"; $this->Exe($query); // Check if query resulted in an affected row $this->checkForAffectedRows(); $this->addAffectedConcept($concept); // add concept to affected concepts. Needed for conjunct evaluation. // Delete atom from relation tables where atom is mentioned as src or tgt atom foreach (Relation::getAllRelations() as $relation) { $tableName = $relation->getMysqlTable()->name; $cols = array(); if ($relation->srcConcept->inSameClassificationTree($concept)) { $cols[] = $relation->getMysqlTable()->srcCol(); } if ($relation->tgtConcept->inSameClassificationTree($concept)) { $cols[] = $relation->getMysqlTable()->tgtCol(); } foreach ($cols as $col) { // If n-n table, remove row if (is_null($relation->getMysqlTable()->tableOf)) { $query = "DELETE FROM `{$tableName}` WHERE `{$col->name}` = '{$atom->idEsc}'"; } elseif ($col->null) { $query = "UPDATE `{$tableName}` SET `{$col->name}` = NULL WHERE `{$col->name}` = '{$atom->idEsc}'"; } else { $query = "DELETE FROM `{$tableName}` WHERE `{$col->name}` = '{$atom->idEsc}'"; } $this->Exe($query); $this->addAffectedRelations($relation); } } $this->logger->debug("Atom '{$atom->__toString()}' (and all related links) deleted in database"); Hooks::callHooks('postDatabaseDeleteAtom', get_defined_vars()); }