/**
  * InterfaceObject constructor
  * @param array $ifcDef Interface object definition as provided by Ampersand generator
  * @param string $pathEntry
  * @param boolean $rootIfc Specifies if this interface object is a toplevel interface (true) or subinterface (false)
  */
 public function __construct($ifcDef, $pathEntry = null, $rootIfc = false)
 {
     $this->database = Database::singleton();
     $this->logger = Logger::getLogger('FW');
     $this->isRoot = $rootIfc;
     // Set attributes from $ifcDef
     $this->id = $ifcDef['id'];
     $this->label = $ifcDef['label'];
     $this->view = is_null($ifcDef['viewId']) ? null : View::getView($ifcDef['viewId']);
     $this->path = is_null($pathEntry) ? $this->id : "{$pathEntry}/{$this->id}";
     // Information about the (editable) relation if applicable
     $this->relation = is_null($ifcDef['relation']) ? null : Relation::getRelation($ifcDef['relation']);
     $this->relationIsFlipped = $ifcDef['relationIsFlipped'];
     // Interface expression information
     $this->srcConcept = Concept::getConcept($ifcDef['expr']['srcConceptId']);
     $this->tgtConcept = Concept::getConcept($ifcDef['expr']['tgtConceptId']);
     $this->isUni = $ifcDef['expr']['isUni'];
     $this->isTot = $ifcDef['expr']['isTot'];
     $this->isIdent = $ifcDef['expr']['isIdent'];
     $this->query = $ifcDef['expr']['query'];
     // CRUD rights
     $this->crudC = $ifcDef['crud']['create'];
     $this->crudR = $ifcDef['crud']['read'];
     $this->crudU = $ifcDef['crud']['update'];
     $this->crudD = $ifcDef['crud']['delete'];
     if ($this->crudU && $this->tgtConcept->isObject) {
         $this->editableConcepts[] = $this->tgtConcept;
     }
     // Interface expression must equal (editable) relation when crudU is specified
     if ($this->crudU && is_null($this->relation)) {
         $this->logger->warning("Update rights (crUd) specified while interface expression is not an editable relation for (sub)interface: {$this->path}");
     }
     // Check for unsupported patchReplace functionality due to missing 'old value'. Related with issue #318
     if (!is_null($this->relation) && $this->crudU && !$this->tgtConcept->isObject && $this->isUni) {
         // Only applies to editable relations
         // Only applies to crudU, because issue is with patchReplace, not with add/remove
         // Only applies to scalar, because objects don't use patchReplace, but Remove and Add
         // Only if interface expression (not! the relation) is univalent, because else a add/remove option is used in the UI
         if (!$this->relationIsFlipped && $this->relation->getMysqlTable()->tableOf == 'tgt' || $this->relationIsFlipped && $this->relation->getMysqlTable()->tableOf == 'src') {
             $this->logger->warning("Unsupported edit functionality due to combination of factors for (sub)interface: '{$this->path}' - {$this->relation->__toString()}" . ($this->relationIsFlipped ? '~' : '') . " administrated in table of '{$this->relation->getMysqlTable()->tableOf}'");
         }
     }
     // Subinterfacing
     if (!is_null($ifcDef['subinterfaces'])) {
         // Subinterfacing is not supported/possible for tgt concepts with a scalar representation type (i.e. non-objects)
         if (!$this->tgtConcept->isObject) {
             throw new Exception("Subinterfacing is not supported for concepts with a scalar representation type (i.e. non-objects). (Sub)Interface '{$this->path}' with target {$this->tgtConcept->__toString()} (type:{$this->tgtConcept->type}) has subinterfaces specified", 501);
         }
         // Reference to top level interface
         $this->refInterfaceId = $ifcDef['subinterfaces']['refSubInterfaceId'];
         $this->isLinkTo = $ifcDef['subinterfaces']['refIsLinTo'];
         // Inline subinterface definitions
         foreach ((array) $ifcDef['subinterfaces']['ifcObjects'] as $subIfcDef) {
             $ifc = new InterfaceObject($subIfcDef, $this->path);
             $this->subInterfaces[$ifc->id] = $ifc;
             $this->editableConcepts = array_merge($this->editableConcepts, $ifc->editableConcepts);
         }
     }
 }
Beispiel #2
0
 /**
  * Delete link (srcAtom,tgtAtom) into database table for relation r
  * @param Relation $relation
  * @param Atom $srcAtom
  * @param Atom $tgtAtom
  */
 public function deleteLink($relation, $srcAtom, $tgtAtom)
 {
     // This function is under control of transaction check!
     if (!isset($this->transaction)) {
         $this->startTransaction();
     }
     $relTable = $relation->getMysqlTable();
     switch ($relTable->tableOf) {
         case null:
             // Relation is administrated in n-n table
             if (is_null($srcAtom->id) || is_null($tgtAtom->id)) {
                 throw new Exception("Cannot delete from relation table '{$relTable->name}', because srcAtom or tgtAtom is null", 500);
             }
             $this->Exe("DELETE FROM `{$relTable->name}` WHERE `{$relTable->srcCol()->name}` = '{$srcAtom->idEsc}' AND `{$relTable->tgtCol()->name}` = '{$tgtAtom->idEsc}'");
             break;
         case 'src':
             // Relation is administrated in concept table (wide) of source of relation
             if (!$relTable->tgtCol()->null) {
                 throw new Exception("Cannot delete link ({$srcAtom->__toString()},{$tgtAtom->__toString()}) from relation '{$relation->__toString()}' because target column '{$relTable->tgtCol()->name}' in table '{$relTable->name}' may not be set to null", 500);
             }
             // Source atom can be used in WHERE statement
             if (!is_null($srcAtom->id)) {
                 $this->Exe("UPDATE `{$relTable->name}` SET `{$relTable->tgtCol()->name}` = NULL WHERE `{$relTable->srcCol()->name}` = '{$srcAtom->idEsc}'");
             } elseif ($relTable->tgtCol()->unique) {
                 $this->Exe("UPDATE `{$relTable->name}` SET `{$relTable->tgtCol()->name}` = NULL WHERE `{$relTable->tgtCol()->name}` = '{$tgtAtom->idEsc}'");
             } else {
                 throw new Exception("Cannot set '{$relTable->tgtCol()->name}' to NULL in concept table '{$relTable->name}', because srcAtom is null", 500);
             }
             break;
         case 'tgt':
             //  Relation is administrated in concept table (wide) of target of relation
             if (!$relTable->srcCol()->null) {
                 throw new Exception("Cannot delete link ({$srcAtom->__toString()},{$tgtAtom->__toString()}) from relation '{$relation->__toString()}' because source column '{$relTable->srcCol()->name}' in table '{$relTable->name}' may not be set to null", 500);
             }
             // Target atom can be used in WHERE statement
             if (!is_null($tgtAtom->id)) {
                 $this->Exe("UPDATE `{$relTable->name}` SET `{$relTable->srcCol()->name}` = NULL WHERE `{$relTable->tgtCol()->name}` = '{$tgtAtom->idEsc}'");
             } elseif ($relTable->srcCol()->unique) {
                 $this->Exe("UPDATE `{$relTable->name}` SET `{$relTable->srcCol()->name}` = NULL WHERE `{$relTable->srcCol()->name}` = '{$srcAtom->idEsc}'");
             } else {
                 throw new Exception("Cannot set '{$relTable->srcCol()->name}' to NULL in concept table '{$relTable->name}', because tgtAtom is null", 500);
             }
             break;
         default:
             throw new Exception("Unknown 'tableOf' option for relation '{$relation}'", 500);
     }
     // Check if query resulted in an affected row
     $this->checkForAffectedRows();
     $this->addAffectedRelations($relation);
     // Add relation to affected relations. Needed for conjunct evaluation.
 }