示例#1
0
 /**
  * Generate a new atom identifier for this concept
  * @return string
  */
 public function createNewAtomId()
 {
     static $prevTime = null;
     if (strpos($this->name, '_AI') !== false && $this->isInteger()) {
         $firstCol = current($this->mysqlConceptTable->getCols());
         $query = "SELECT MAX(`{$firstCol->name}`) as `MAX` FROM `{$this->mysqlConceptTable->name}`";
         $result = array_column((array) $this->database->Exe($query), 'MAX');
         if (empty($result)) {
             $atomId = 1;
         } else {
             $atomId = $result[0] + 1;
         }
     } else {
         $now = explode(' ', microTime());
         // yields ["microseconds", "seconds"] both in seconds, e.g. ["0.85629400", "1322761879"]
         $time = $now[1] . substr($now[0], 2, 6);
         // we drop the leading "0." and trailing "00"  from the microseconds
         // Guarantee that time is increased
         if ($time <= $prevTime) {
             $time = ++$prevTime;
         } else {
             $prevTime = $time;
         }
         $atomId = $this->name . '_' . $time;
     }
     return $atomId;
 }
示例#2
0
 /**
  *
  * @throws Exception when segment type is unknown
  * @throws Exception when segment expression return more that 1 tgt atom
  * @return string
  */
 public function getViolationMessage()
 {
     $database = Database::singleton();
     $strArr = array();
     foreach ($this->rule->violationSegments as $segment) {
         // text segment
         if ($segment['segmentType'] == 'Text') {
             $strArr[] = $segment['Text'];
             // expressie segment
         } elseif ($segment['segmentType'] == 'Exp') {
             // select starting atom depending on whether the segment uses the src of tgt atom.
             $atom = $segment['srcOrTgt'] == 'Src' ? $this->src : $this->tgt;
             // quering the expression
             $query = "SELECT DISTINCT `tgt` FROM ({$segment['expSQL']}) AS `results` WHERE `src` = '{$atom->idEsc}'";
             // SRC of TGT kunnen door een expressie gevolgd worden
             $rows = $database->Exe($query);
             // returning the result
             if (count($rows) > 1) {
                 throw new Exception("Expression of pairview results in more than one tgt atom", 501);
             }
             // 501: Not implemented
             $strArr[] = $rows[0]['tgt'];
             // unknown segment
         } else {
             $errorMessage = "Unknown segmentType '{$segment['segmentType']}' in violationSegments of rule '{$this->rule->id}'";
             throw new Exception($errorMessage, 501);
             // 501: Not implemented
         }
     }
     // If empty array of strings (i.e. no violation segments defined), use default violation representation: '<srcAtom>,<tgtAtom>'
     $this->message = empty($strArr) ? "{$this->src->getLabel()},{$this->tgt->getLabel()}" : implode($strArr);
     return $this->message;
 }
示例#3
0
 /**
  * Function to delete an atom from Concept collection
  * @param array $options
  * @throws Exception when delete is not allowed/possible
  * @return void
  */
 public function delete($options = array())
 {
     $this->logger->debug("delete() called on {$this->path}");
     // CRUD check
     if (!$this->parentIfc->crudD) {
         throw new Exception("Delete not allowed for '{$this->path}'", 405);
     }
     if (!$this->parentIfc->tgtConcept->isObject) {
         throw new Exception("Cannot delete non-object '{$this->__toString()}' in '{$this->path}'. Use PATCH remove operation instead", 405);
     }
     if ($this->parentIfc->isRef()) {
         throw new Exception("Cannot delete on reference interface in '{$this->path}'. See #498", 501);
     }
     // Handle options
     if (isset($options['requestType'])) {
         $this->database->setRequestType($options['requestType']);
     }
     // Perform delete
     $this->deleteAtom();
     // Close transaction
     $this->database->closeTransaction($this->concept . ' deleted');
     return;
 }
示例#4
0
 /**
  * Return array with all links (pair of Atoms) in this relation
  * @return array[]
  */
 public function getAllLinks()
 {
     // Query all atoms in table
     $query = "SELECT `{$this->mysqlTable->srcCol()->name}` as `src`, `{$this->mysqlTable->tgtCol()->name}` as `tgt` FROM `{$this->mysqlTable->name}`";
     return (array) $this->db->Exe($query);
 }
示例#5
0
    $allLinks = array();
    foreach (Relation::getAllRelations() as $rel) {
        $allLinks[$rel->signature] = $rel->getAllLinks();
    }
    $strFileContent = '<?php' . PHP_EOL . '$allAtoms = ' . var_export($allAtoms, true) . ';' . PHP_EOL . '$allLinks = ' . var_export($allLinks, true) . ';' . PHP_EOL . '?>';
    file_put_contents(Config::get('absolutePath') . Config::get('logPath') . "export-" . date('Y-m-d_H-i-s') . ".php", $strFileContent);
});
$app->get('/admin/import', function () use($app) {
    if (Config::get('productionEnv')) {
        throw new Exception("Import not allowed in production environment", 403);
    }
    $file = $app->request->params('file');
    if (is_null($file)) {
        throw new Exception("Import file not specified", 500);
    }
    $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) {
 /**
  * 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();
 }
示例#7
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);
 }
示例#8
0
global $app;
// Path to API is 'api/v1/excelimport/import'
$app->post('/excelimport/import', function () use($app) {
    $session = Session::singleton();
    $roleIds = $app->request->params('roleIds');
    $session->activateRoles($roleIds);
    // Check sessionRoles if allowedRolesForExcelImport is specified
    $allowedRoles = Config::get('allowedRolesForExcelImport', 'excelImport');
    if (!is_null($allowedRoles)) {
        $ok = false;
        foreach ($session->getSessionRoles() as $role) {
            if (in_array($role->label, $allowedRoles)) {
                $ok = true;
            }
        }
        if (!$ok) {
            throw new Exception("You do not have access to import excel files", 401);
        }
    }
    if (is_uploaded_file($_FILES['file']['tmp_name'])) {
        // Parse:
        $parser = new ExcelImport();
        $parser->ParseFile($_FILES['file']['tmp_name']);
        Database::singleton()->closeTransaction("File {$_FILES['file']['tmp_name']} imported successfully", true);
        unlink($_FILES['file']['tmp_name']);
    } else {
        Logger::getUserLogger()->error("No file uploaded");
    }
    $result = array('notifications' => Notifications::getAll(), 'files' => $_FILES);
    print json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
});
示例#9
0
 /**
  * Overwrites getViolationMessage() method from Violation class
  * @throws Exception when segment type is unknown
  * @throws Exception when segment expression return more that 1 tgt atom
  * @return string
  */
 public function getViolationMessage()
 {
     $database = Database::singleton();
     $strArr = array();
     foreach ($this->rule->violationSegments as $segment) {
         // text segment
         if ($segment['segmentType'] == 'Text') {
             $strArr[] = $segment['Text'];
             // expressie segment
         } elseif ($segment['segmentType'] == 'Exp') {
             // select starting atom depending on whether the segment uses the src of tgt atom.
             $atom = $segment['srcOrTgt'] == 'Src' ? $this->src : $this->tgt;
             $rows = array();
             if ($segment['expIsIdent']) {
                 // when segment expression isIdent (i.e. SRC I or TGT I), we don't have to query the database.
                 $rows[] = array('tgt' => $atom->id);
             } else {
                 // quering the expression
                 $query = "SELECT DISTINCT `tgt` FROM ({$segment['expSQL']}) AS `results` WHERE `src` = '{$atom->idEsc}'";
                 // SRC of TGT kunnen door een expressie gevolgd worden
                 $rows = $database->Exe($query);
             }
             // returning the result
             if (count($rows) == 0) {
                 $strArr[] = '_NULL';
             } else {
                 $str = '';
                 foreach ($rows as $row) {
                     $str .= $row['tgt'] . '_AND';
                 }
                 $str = substr($str, 0, -4);
                 // strip the last _AND
                 $strArr[] = str_replace(array('{EX}', '{php}'), '', $str);
                 // prevent php interpreter by user input. Only allowed as Text segments specified in &-script
             }
             // unknown segment
         } else {
             $errorMessage = "Unknown segmentType '{$segment['segmentType']}' in violationSegments of rule '{$this->rule->id}'";
             throw new Exception($errorMessage, 501);
             // 501: Not implemented
         }
     }
     return $this->message = implode($strArr);
 }
示例#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 to evaluate conjunct
  * @param boolean $cacheConjuncts
  * @return array[] array(array('src' => '<srcAtomId>', 'tgt' => '<tgtAtomId>'))
  */
 public function evaluateConjunct($cacheConjuncts = true)
 {
     $this->logger->debug("Checking conjunct '{$this->id}' cache:" . var_export($cacheConjuncts, true));
     try {
         // If conjunct is already evaluated and conjunctCach may be used -> return violations
         if (isset($this->conjunctViolations) && $cacheConjuncts) {
             $this->logger->debug("Conjunct is already evaluated, getting violations from cache");
             return $this->conjunctViolations;
             // Otherwise evaluate conjunct, cache and return violations
         } else {
             $db = Database::singleton();
             $dbsignalTableName = Config::get('dbsignalTableName', 'mysqlDatabase');
             $violations = array();
             // Execute conjunct query
             $violations = (array) $db->Exe($this->query);
             // Cache violations in php Conjunct object
             if ($cacheConjuncts) {
                 $this->conjunctViolations = $violations;
             }
             if (count($violations) == 0) {
                 $this->logger->debug("Conjunct '{$this->id}' holds");
                 // Remove "old" conjunct violations from database
                 $query = "DELETE FROM `{$dbsignalTableName}` WHERE `conjId` = '{$this->id}'";
                 $db->Exe($query);
             } else {
                 $this->logger->debug("Conjunct '{$this->id}' broken, updating violations in database");
                 // Remove "old" conjunct violations from database
                 $query = "DELETE FROM `{$dbsignalTableName}` WHERE `conjId` = '{$this->id}'";
                 $db->Exe($query);
                 // Add new conjunct violation to database
                 $query = "INSERT IGNORE INTO `{$dbsignalTableName}` (`conjId`, `src`, `tgt`) VALUES ";
                 $values = array();
                 foreach ($violations as $violation) {
                     $values[] = "('{$this->id}', '" . $db->escape($violation['src']) . "', '" . $db->escape($violation['tgt']) . "')";
                 }
                 $query .= implode(',', $values);
                 $db->Exe($query);
             }
             return $violations;
         }
     } catch (Exception $e) {
         Logger::getUserLogger()->error("While checking conjunct '{$this->id}': " . $e->getMessage());
         return array();
     }
 }
示例#12
0
 /**
  * Function to return the database instance
  * @return Database
  */
 public static function singleton()
 {
     try {
         if (!is_object(self::$_instance)) {
             self::$_instance = new Database();
         }
     } catch (Exception $e) {
         // Convert mysqli_sql_exceptions into 500 errors
         if (!Config::get('productionEnv')) {
             switch ($e->getCode()) {
                 case 1049:
                     // Error: 1049 SQLSTATE: 42000 (ER_BAD_DB_ERROR)
                     // throw new Exception("Please <a href=\"#/admin/installer\" class=\"alert-link\">install database</a>",500);
                     self::createDB();
                     self::$_instance = new Database();
                     self::$_instance->logger->info("Automatically installing database for the first time");
                     self::$_instance->reinstallDB();
                     break;
                 default:
                     throw new Exception("{$e->getCode()}: {$e->getMessage()}", 500);
             }
         } else {
             throw new Exception("Cannot connect to database", 500);
         }
     }
     return self::$_instance;
 }
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());
    }
}
示例#14
0
 /**
  * Returns if session refresh is adviced in frontend
  * True when
  * - session variable is affected (otherwise nothing to update)
  * - AND transaction request is 'promise' (otherwise rollback)
  * - AND invariant rules hold (otherwise rollback)
  * False otherwise
  * @return boolean
  */
 public function getSessionRefreshAdvice()
 {
     return $this->getSessionVarAffected() && $this->database->getRequestType() == 'promise' && $this->database->getInvariantRulesHold();
 }