Пример #1
0
 /**
  * Returns view array of key-value pairs for this atom
  * @return array
  */
 private function getView()
 {
     // If view is not already set
     if (!isset($this->view)) {
         $this->logger->debug("Get view for atom '{$this->__toString()}'");
         $this->view = array();
         // If parentIfc is set, use view as defined by interface (can be null)
         if (isset($this->parentIfc)) {
             $viewDef = $this->parentIfc->view;
         } else {
             $viewDef = $this->concept->getDefaultView();
         }
         // If there is a view definition
         if (!is_null($viewDef)) {
             foreach ($viewDef->segments as $viewSegment) {
                 $key = is_null($viewSegment->label) ? $viewSegment->seqNr : $viewSegment->label;
                 switch ($viewSegment->segType) {
                     case "Text":
                         $this->view[$key] = $viewSegment->text;
                         break;
                     case "Exp":
                         try {
                             // Try to get view segment from atom query data
                             $this->view[$key] = $this->getQueryData('view_' . $key);
                             // column is prefixed with view_
                             // $this->logger->debug("VIEW <{$viewDef->label}:{$key}> #217 Query saved due to reusing data from source atom");
                         } catch (Exception $e) {
                             // Column not defined, perform query
                             if ($e->getCode() == 1001) {
                                 // TODO: fix this 1001 exception code handling by proper construct
                                 $query = "/* VIEW <{$viewDef->label}:{$key}> */ SELECT DISTINCT `tgt` FROM ({$viewSegment->expSQL}) AS `results` WHERE `src` = '{$this->idEsc}' AND `tgt` IS NOT NULL";
                                 $tgtAtoms = array_column((array) $this->database->Exe($query), 'tgt');
                                 $this->view[$key] = count($tgtAtoms) ? $tgtAtoms[0] : null;
                             } else {
                                 throw $e;
                             }
                         }
                         break;
                     default:
                         throw new Exception("Unsupported segmentType '{$viewSegment->segType}' in VIEW <{$viewDef->label}:{$key}>", 501);
                         // 501: Not implemented
                         break;
                 }
             }
         }
     }
     return $this->view;
 }
Пример #2
0
 /**
  * Return Relation object
  * @param string $relationSignature
  * @param Concept $srcConcept
  * @param Concept $tgtConcept
  * @throws Exception if Relation is not defined
  * @return Relation
  */
 public static function getRelation($relationSignature, Concept $srcConcept = null, Concept $tgtConcept = null)
 {
     $relations = self::getAllRelations();
     if (is_string($srcConcept)) {
         $srcConcept = Concept::getConceptByLabel($srcConcept);
     }
     if (is_string($tgtConcept)) {
         $tgtConcept = Concept::getConceptByLabel($tgtConcept);
     }
     // If relation can be found by its fullRelationSignature return the relation
     if (array_key_exists($relationSignature, $relations)) {
         $relation = $relations[$relationSignature];
         // If srcConceptName and tgtConceptName are provided, check that they match the found relation
         if (!is_null($srcConcept) && !in_array($srcConcept, $relation->srcConcept->getSpecializationsIncl())) {
             throw new Exception("Provided src concept '{$srcConcept}' does not match the relation '{$relation->__toString()}'", 500);
         }
         if (!is_null($tgtConcept) && !in_array($tgtConcept, $relation->tgtConcept->getSpecializationsIncl())) {
             throw new Exception("Provided tgt concept '{$tgtConcept}' does not match the relation '{$relation->__toString()}'", 500);
         }
         return $relation;
     }
     // Else try to find the relation by its name, srcConcept and tgtConcept
     if (!is_null($srcConcept) && !is_null($tgtConcept)) {
         foreach ($relations as $relation) {
             if ($relation->name == $relationSignature && in_array($srcConcept, $relation->srcConcept->getSpecializationsIncl()) && in_array($tgtConcept, $relation->tgtConcept->getSpecializationsIncl())) {
                 return $relation;
             }
         }
     }
     // Else
     throw new Exception("Relation '{$relationSignature}' is not defined", 500);
 }
Пример #3
0
 }
 $database = Database::singleton();
 include_once Config::get('absolutePath') . Config::get('logPath') . "{$file}";
 // 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));
Пример #4
0
    $result = array('patches' => $app->request->getBody(), 'content' => $content, 'notifications' => Notifications::getAll(), 'invariantRulesHold' => $session->database->getInvariantRulesHold(), 'requestType' => $session->database->getRequestType(), 'sessionRefreshAdvice' => $session->getSessionRefreshAdvice());
    print json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
});
$app->post('/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);
    $atom = new Atom($resourceId, Concept::getConcept($resourceType));
    $atomOrIfc = $atom->walkIfcPath($ifcPath);
    // Perform create
    $content = $atomOrIfc->create($app->request->getBody(), $options);
    // Return result
    $result = array('content' => $content, 'notifications' => Notifications::getAll(), 'invariantRulesHold' => $session->database->getInvariantRulesHold(), 'requestType' => $session->database->getRequestType(), 'sessionRefreshAdvice' => $session->getSessionRefreshAdvice());
    print json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
});
$app->delete('/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);
    $atom = new Atom($resourceId, Concept::getConcept($resourceType));
    $atomOrIfc = $atom->walkIfcPath($ifcPath);
    // Perform delete
    $atomOrIfc->delete($options);
    // Return result
    $result = array('notifications' => Notifications::getAll(), 'invariantRulesHold' => $session->database->getInvariantRulesHold(), 'requestType' => $session->database->getRequestType(), 'sessionRefreshAdvice' => $session->getSessionRefreshAdvice());
    print json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
});
Пример #5
0
 /**
  * Rule constructor
  * Private function to prevent outside instantiation. Use Rule::getRule($ruleName)
  *
  * @param array $ruleDef
  * @param boolean $type
  */
 private function __construct($ruleDef, $type = null)
 {
     $this->logger = Logger::getLogger('FW');
     $this->id = $ruleDef['name'];
     $this->origin = $ruleDef['origin'];
     $this->ruleAdl = $ruleDef['ruleAdl'];
     $this->srcConcept = Concept::getConcept($ruleDef['srcConceptId']);
     $this->tgtConcept = Concept::getConcept($ruleDef['tgtConceptId']);
     $this->meaning = $ruleDef['meaning'];
     $this->message = $ruleDef['message'];
     // Conjuncts
     foreach ($ruleDef['conjunctIds'] as $conjId) {
         $this->conjuncts[] = Conjunct::getConjunct($conjId);
     }
     $this->violationSegments = (array) $ruleDef['pairView'];
     switch ($type) {
         case 'sig':
             $this->isSignal = true;
             break;
         case 'inv':
             $this->isInvariant = true;
             break;
         case null:
             break;
         default:
             throw new Exception("Unknown/unsupported rule type. Allowed types are signal or invariant", 500);
     }
 }
Пример #6
0
 /**
  * 
  * @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');
                 }
             }
         }
     }
 }
Пример #7
0
 /**
  * Function to create a new Atom at the given interface.
  * @param array $data
  * @param array $options
  * @throws Exception
  * @return mixed
  */
 public function create($data, $options = array())
 {
     $this->logger->debug("create() called on {$this->path}");
     // CRUD check
     if (!$this->crudC) {
         throw new Exception("Create not allowed for '{$this->path}'", 405);
     }
     if (!$this->tgtConcept->isObject) {
         throw new Exception("Cannot create non-object '{$this->tgtConcept}' in '{$this->path}'. Use PATCH add operation instead", 405);
     }
     if ($this->isRef()) {
         throw new Exception("Cannot create on reference interface in '{$this->path}'. See #498", 501);
     }
     // Handle options
     if (isset($options['requestType'])) {
         $this->database->setRequestType($options['requestType']);
     }
     // Perform create
     $newAtom = $this->tgtConcept->createNewAtom();
     // Special case for CREATE in I[Concept] interfaces
     if ($this->srcAtom->id === '_NEW') {
         $this->srcAtom->setId($newAtom->id);
         $this->path = str_replace('_NEW', $newAtom->getJsonRepresentation(), $this->path);
     }
     // If interface expression is a relation, also add tuple(this, newAtom) in this relation
     if ($this->relation) {
         $this->relation()->addLink($this->srcAtom, $newAtom, $this->relationIsFlipped);
     } else {
         $newAtom->addAtom();
     }
     // Walk to new atom
     $newAtom = $this->atom($newAtom->id);
     // Set requested state (using patches)
     $patches = is_array($data) ? $data['patches'] : array();
     $newAtom->doPatches($patches);
     // Special case for file upload. TODO: make extension with hooks
     if ($this->tgtConcept->isFileObject()) {
         $conceptFilePath = Concept::getConceptByLabel('FilePath');
         $conceptFileName = Concept::getConceptByLabel('FileName');
         if (is_uploaded_file($_FILES['file']['tmp_name'])) {
             $tmp_name = $_FILES['file']['tmp_name'];
             $new_name = time() . '_' . $_FILES['file']['name'];
             $absolutePath = Config::get('absolutePath') . Config::get('uploadPath') . $new_name;
             $relativePath = Config::get('uploadPath') . $new_name;
             $result = move_uploaded_file($tmp_name, $absolutePath);
             if ($result) {
                 Logger::getUserLogger()->notice("File '{$new_name}' uploaded");
             } else {
                 throw new Exception("Error in file upload", 500);
             }
             // Populate filePath and originalFileName relations in database
             $relFilePath = Relation::getRelation('filePath', $newAtom->concept, $conceptFilePath);
             $relOriginalFileName = Relation::getRelation('originalFileName', $newAtom->concept, $conceptFileName);
             $relFilePath->addLink($newAtom, new Atom($relativePath, $conceptFilePath));
             $relOriginalFileName->addLink($newAtom, new Atom($_FILES['file']['name'], $conceptFileName));
         } else {
             throw new Exception("No file uploaded", 500);
         }
     }
     // Close transaction
     $this->database->closeTransaction($newAtom->concept . ' created', null, $newAtom);
     // temp store content of $newAtom (also when not crudR)
     // Return atom content (can be null)
     return $newAtom->getStoredContent();
 }
Пример #8
0
 private function login($email)
 {
     if (empty($email)) {
         throw new Exception("No emailaddress provided to login", 500);
     }
     $session = Session::singleton();
     $db = Database::singleton();
     $conceptUserID = Concept::getConceptByLabel('UserID');
     $conceptDomain = Concept::getConceptByLabel('Domain');
     $conceptDateTime = Concept::getConceptByLabel('DateTime');
     $conceptOrg = Concept::getConceptByLabel('Organization');
     $conceptAccount = Concept::getConceptByLabel('Account');
     $conceptSession = Concept::getConceptByLabel('SESSION');
     // Set sessionUser
     $atom = new Atom($email, $conceptUserID);
     $accounts = $atom->ifc('AccountForUserid')->getTgtAtoms();
     // create new user
     if (empty($accounts)) {
         $newAccount = Concept::getConceptByLabel('Account')->createNewAtom();
         // Save email as accUserid
         $relAccUserid = Relation::getRelation('accUserid', $newAccount->concept, $conceptUserID);
         $relAccUserid->addLink($newAccount, new Atom($email, $conceptUserID), false, 'OAuthLoginExtension');
         // If possible, add account to organization(s) based on domain name
         $domain = explode('@', $email)[1];
         $atom = new Atom($domain, $conceptDomain);
         $orgs = $atom->ifc('DomainOrgs')->getTgtAtoms();
         $relAccOrg = Relation::getRelation('accOrg', $newAccount->concept, $conceptOrg);
         foreach ($orgs as $org) {
             $relAccOrg->addLink($newAccount, $org, false, 'OAuthLoginExtension');
         }
         // Account created, add to $accounts list (used lateron)
         $accounts[] = $newAccount;
     }
     if (count($accounts) > 1) {
         throw new Exception("Multiple users registered with email {$email}", 401);
     }
     $relSessionAccount = Relation::getRelation('sessionAccount', $conceptSession, $conceptAccount);
     $relAccMostRecentLogin = Relation::getRelation('accMostRecentLogin', $conceptAccount, $conceptDateTime);
     $relAccLoginTimestamps = Relation::getRelation('accLoginTimestamps', $conceptAccount, $conceptDateTime);
     foreach ($accounts as $account) {
         // Set sessionAccount
         $relSessionAccount->addLink($session->sessionAtom, $account, false, 'OAuthLoginExtension');
         // Timestamps
         $ts = new Atom(date(DATE_ISO8601), $conceptDateTime);
         $relAccMostRecentLogin->addLink($account, $ts, false, 'OAuthLoginExtension');
         $relAccLoginTimestamps->addLink($account, $ts, false, 'OAuthLoginExtension');
     }
     $db->closeTransaction('Login successfull', true);
 }
Пример #9
0
 /**
  * Returns largest generalization concept (can be itself)
  * @return Concept
  */
 public function getLargestConcept()
 {
     return Concept::getConcept($this->largestConceptId);
 }
Пример #10
0
function OverwritePopulation($rArray, $relationName, $conceptName)
{
    try {
        $database = Database::singleton();
        $concept = Concept::getConceptByLabel($conceptName);
        $relation = Relation::getRelation($relationName, $concept, $concept);
        $relationTable = $relation->getMysqlTable();
        $srcCol = $relationTable->srcCol();
        $tgtCol = $relationTable->tgtCol();
        $query = "DELETE FROM `{$relationTable->name}`";
        // Do not use TRUNCATE statement, this causes an implicit commit
        $database->Exe($query);
        foreach ($rArray as $src => $tgtArray) {
            foreach ($tgtArray as $tgt => $bool) {
                if ($bool) {
                    $query = "INSERT INTO `{$relationTable->name}` (`{$srcCol->name}`, `{$tgtCol->name}`) VALUES ('{$src}','{$tgt}')";
                    $database->Exe($query);
                }
            }
        }
    } catch (Exception $e) {
        throw new Exception('OverwritePopulation: ' . $e->getMessage(), 500);
    }
}
Пример #11
0
function ClearConcept($concept, $atom)
{
    Logger::getLogger('EXECENGINE')->info("ClearConcept({$concept},{$atom})");
    if (func_num_args() != 2) {
        throw new Exception("Wrong number of arguments supplied for function ClearConcept(): " . func_num_args() . " arguments", 500);
    }
    try {
        $database = Database::singleton();
        $atom = new Atom($atom, Concept::getConceptByLabel($concept));
        $database->atomClearConcept($atom);
        Logger::getLogger('EXECENGINE')->debug("Atom '{$atom->__toString()}' removed as member from concept '{$concept}'");
    } catch (Exception $e) {
        Logger::getUserLogger()->error('ClearConcept: ' . $e->getMessage());
    }
}
Пример #12
0
 /**
  * Delete provided Ampersand session atom from database
  * @param string $sessionAtomId ampersand session atom id
  * @return void
  */
 private function destroyAmpersandSession($sessionAtomId)
 {
     $this->database->Exe("DELETE FROM `__SessionTimeout__` WHERE SESSION = '{$sessionAtomId}'");
     $atom = new Atom($sessionAtomId, Concept::getConceptByLabel('SESSION'));
     $atom->deleteAtom();
     $this->database->commitTransaction();
 }