/** * 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); } } }
/** * Concept constructor * Private function to prevent outside instantiation of concepts. Use Concept::getConcept($conceptName) * * @param array $conceptDef */ private function __construct($conceptDef) { $this->database = Database::singleton(); $this->logger = Logger::getLogger('FW'); $this->def = $conceptDef; $this->name = $conceptDef['id']; $this->label = $conceptDef['label']; $this->type = $conceptDef['type']; $this->isObject = $this->type == "OBJECT" ? true : false; $this->affectedConjunctIds = (array) $conceptDef['affectedConjuncts']; foreach ($this->affectedConjunctIds as $conjId) { $conj = Conjunct::getConjunct($conjId); if ($conj->isSigConj()) { $this->affectedSigConjuncts[] = $conj; } if ($conj->isInvConj()) { $this->affectedInvConjuncts[] = $conj; } // if (!$conj->isSigConj() && !$conj->isInvConj()) $this->logger->warning("Affected conjunct '{$conj->id}' (specified for concept '[{$this->name}]') is not part of an invariant or signal rule"); } $this->specializations = (array) $conceptDef['specializations']; $this->generalizations = (array) $conceptDef['generalizations']; $this->interfaceIds = (array) $conceptDef['interfaces']; $this->largestConceptId = $conceptDef['largestConcept']; if (!is_null($conceptDef['defaultViewId'])) { $this->defaultView = View::getView($conceptDef['defaultViewId']); } $this->mysqlConceptTable = new DatabaseTable($conceptDef['conceptTable']['name']); foreach ($conceptDef['conceptTable']['cols'] as $colName) { $this->mysqlConceptTable->addCol(new DatabaseTableCol($colName)); } }