// check if all concepts and relations are defined foreach ((array) $allAtoms as $cpt => $atoms) { if (!empty($atoms)) { Concept::getConcept($cpt); } } foreach ((array) $allLinks as $rel => $links) { if (!empty($links)) { Relation::getRelation($rel); } } foreach ((array) $allAtoms as $cpt => $atoms) { $concept = Concept::getConcept($cpt); foreach ($atoms as $atomId) { $atom = new Atom($atomId, $concept); $atom->addAtom(); } } foreach ((array) $allLinks as $rel => $links) { if (!empty($links)) { $relation = Relation::getRelation($rel); } foreach ($links as $link) { if (is_null($link['src']) || is_null($link['tgt'])) { continue; } // skip $relation->addLink(new Atom($link['src'], $relation->srcConcept), new Atom($link['tgt'], $relation->tgtConcept)); } } $database->closeTransaction("Imported successfully", true);
/** * * @param array $lines */ private function ParseLines($lines) { $relations = $concept = $separator = $flipped = array(); foreach ($lines as $linenr => $line) { $totalcolumns = count($line); // First line specifies relation names if ($linenr == 0) { for ($col = 0; $col < $totalcolumns; $col++) { $relations[$col] = trim($line[$col]); // No leading/trailing spaces around relation names. } // Second line specifies concepts (and optionally: separators) } elseif ($linenr == 1) { // In the Haskell importer, separators are the last character before the ']' if the concept is surrounded by such block quotes. Alternatively, you could specify a separator following such block-quotes, allowing for multiple-character separators. for ($col = 0; $col < $totalcolumns; $col++) { $cellvalue = trim($line[$col]); // No leading/trailing spaces around cell values in second line if ($cellvalue == '') { $concept[$col] = null; // The cell contains either 'Concept' or '[Conceptx]' where x is a separator character (e.g. ';', ',', ...) } elseif (substr($cellvalue, 0, 1) == '[' && substr($cellvalue, -1) == ']') { if ($col == 0) { throw new Exception("Seperator character not allowed for first column of excel import. Specified '{$line[$col]}'", 500); } $concept[$col] = Concept::getConceptByLabel(substr($cellvalue, 1, -2)); $separator[$col] = substr($cellvalue, -2, 1); } else { $concept[$col] = Concept::getConceptByLabel($cellvalue); $separator[$col] = false; } // Determine relations for all cols except col 0 if ($col > 0) { if ($relations[$col] == '' || $concept[$col] == '') { $relations[$col] = null; } elseif (substr($relations[$col], -1) == '~') { // Relation is flipped is last character is a tilde (~) $relations[$col] = Relation::getRelation(substr($relations[$col], 0, -1), $concept[$col], $concept[0]); $flipped[$col] = true; } else { $relations[$col] = Relation::getRelation($relations[$col], $concept[0], $concept[$col]); $flipped[$col] = false; } } } // All other lines specify atoms } else { $line[0] = trim($line[0]); // Trim cell content (= dirty identifier) // Determine left atom (column 0) of line if ($line[0] == '') { continue; } elseif ($line[0] == '_NEW') { $leftAtom = $concept[0]->createNewAtom(); } else { $leftAtom = new Atom($line[0], $concept[0]); } // Insert $leftAtom into the DB if it does not yet exist $leftAtom->addAtom(); // Process other columns of line for ($col = 1; $col < $totalcolumns; $col++) { if (is_null($concept[$col])) { continue; } // If no concept is specified, the cell is skipped if (is_null($relations[$col])) { continue; } // If no relation is specified, the cell is skipped // Determine right atom(s) $rightAtoms = array(); $cell = trim($line[$col]); // Start of check for multiple atoms in single cell if ($cell == '') { continue; } elseif ($cell == '_NEW') { $rightAtoms[] = $leftAtom; } elseif ($separator[$col]) { $atomsIds = explode($separator[$col], $cell); // atomnames may have surrounding whitespace foreach ($atomsIds as $atomId) { $rightAtoms[] = new Atom(trim($atomId), $concept[$col]); } } else { $rightAtoms[] = new Atom($line[$col], $concept[$col]); // DO NOT TRIM THIS CELL CONTENTS as it contains an atom that may need leading/trailing spaces } foreach ($rightAtoms as $rightAtom) { $relations[$col]->addLink($leftAtom, $rightAtom, $flipped[$col], 'ExcelImport'); } } } } }
function NewStruct() { // arglist: ($ConceptC[,$newAtom][,$relation,$srcConcept,$srcAtom,$tgtConcept,$tgtAtom]+) try { // We start with parsing the first one or two arguments $c = Concept::getConceptByLabel(func_get_arg(0)); // Concept for which atom is to be created $atom = $c->createNewAtom(); // Default marker for atom-to-be-created. Logger::getLogger('EXECENGINE')->info("Newstruct for concept '{$c}'"); // Check if name of new atom is explicitly specified if (func_num_args() % 5 == 2) { $atom = new Atom(func_get_arg(1), $c); } elseif (func_num_args() % 5 != 1) { throw new Exception("Wrong number of arguments supplied for function Newstruct(): " . func_num_args() . " arguments", 500); } // Add atom to concept $atom->addAtom(); // Next, for every relation that follows in the argument list, we create a link for ($i = func_num_args() % 5; $i < func_num_args(); $i = $i + 5) { $relation = func_get_arg($i); $srcConcept = Concept::getConceptByLabel(func_get_arg($i + 1)); $srcAtomId = func_get_arg($i + 2); $tgtConcept = Concept::getConceptByLabel(func_get_arg($i + 3)); $tgtAtomId = func_get_arg($i + 4); if ($srcAtomId == "NULL" or $tgtAtomId == "NULL") { throw new Exception("NewStruct: use of keyword NULL is deprecated, use '_NEW'", 500); } // NewStruct requires that atom $srcAtomId or $tgtAtomId must be _NEW // Note: when populating a [PROP] relation, both atoms can be new if (!($srcAtomId == '_NEW' or $tgtAtomId == '_NEW')) { throw new Exception("NewStruct: relation '{$relation}' requires that atom '{$srcAtomId}' or '{$tgtAtomId}' must be '_NEW'", 500); } // NewStruct requires that concept $srcConcept or $tgtConcept must be concept $c if (!in_array($srcConcept, $c->getGeneralizationsIncl()) && !in_array($tgtConcept, $c->getGeneralizationsIncl())) { throw new Exception("NewStruct: relation '{$relation}' requires that src or tgt concept must be '{$c}' (or any of its generalizations)", 500); } // Replace atom by the newstruct atom if _NEW is used if (in_array($srcConcept, $c->getGeneralizationsIncl()) && $srcAtomId == '_NEW') { $srcAtomId = $atom->id; } if (in_array($tgtConcept, $c->getGeneralizationsIncl()) && $tgtAtomId == '_NEW') { $tgtAtomId = $atom->id; } // Any logging is done by InsPair InsPair($relation, $srcConcept->name, $srcAtomId, $tgtConcept->name, $tgtAtomId); } Logger::getLogger('EXECENGINE')->debug("Newstruct: atom '{$atom}' created"); } catch (Exception $e) { Logger::getUserLogger()->error("NewStruct: {$e->getMessage()}"); } }
/** * 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); } }
/** * Constructor of Session class * private to prevent any outside instantiation of this object */ private function __construct() { $this->logger = Logger::getLogger('FW'); $this->database = Database::singleton(); $conceptSession = Concept::getConceptByLabel('SESSION'); // Also checks if 'SESSION' is defined as concept in Ampersand script $this->id = session_id(); $this->sessionAtom = new Atom($this->id, $conceptSession); $this->logger->debug("Session id: {$this->id}"); // Remove expired Ampersand sessions from __SessionTimeout__ and all concept tables and relations where it appears. $expiredSessionsAtoms = array_column((array) $this->database->Exe("SELECT SESSION FROM `__SessionTimeout__` WHERE `lastAccess` < " . (time() - Config::get('sessionExpirationTime'))), 'SESSION'); foreach ($expiredSessionsAtoms as $expiredSessionAtom) { if ($expiredSessionAtom == $this->id) { // Notify user that session is expired when login functionality is enabled if (Config::get('loginEnabled')) { Logger::getUserLogger()->warning("Your session has expired, please login again"); } // 440 Login Timeout -> is redirected by frontend to login page } $this->destroyAmpersandSession($expiredSessionAtom); } // Create a new Ampersand session atom if not yet in SESSION table (browser started a new session or Ampersand session was expired) $sessionAtom = new Atom($this->id, $conceptSession); if (!$sessionAtom->atomExists()) { $sessionAtom->addAtom(); $this->database->commitTransaction(); //TODO: ook door Database->closeTransaction() laten doen, maar die verwijst terug naar Session class voor de checkrules. Oneindige loop } $this->database->Exe("INSERT INTO `__SessionTimeout__` (`SESSION`,`lastAccess`) VALUES ('" . $this->id . "', '" . time() . "') ON DUPLICATE KEY UPDATE `lastAccess` = '" . time() . "'"); // Add public interfaces $this->accessibleInterfaces = InterfaceObject::getPublicInterfaces(); }