public function __construct(Entity $givenEntity, $givenObjectId, Relationship $relationship, QueryContext $queryContext, Scope $scope) { parent::__construct($relationship->getOppositeEntity($givenEntity), $queryContext, $scope); // Check input consistency. if ($givenObjectId == null) { throw new Exception("The reference-id is not specified for relationship '" . $givenEntity->getName() . "' to '" . $this->getSearchEntity()->getName() . "'."); } if ($relationship->getOneEntity() != $givenEntity && $relationship->getOtherEntity() != $givenEntity) { throw new Exception("Given entity '" . $givenEntity->getName() . "' is not part of the given relationship between '" . $relationship->getOneEntity()->getName() . "' and '" . $relationship->getOtherEntity()->getName() . "'."); } $this->givenEntity = $givenEntity; $this->givenObjectId = $givenObjectId; $this->relationship = $relationship; }
public function establishLinks(Schema $schema, LinkEntity $linkEntity, $oneFkColumnName, $oneId, $otherFkColumnName, array $otherIds, Audit $audit) { // Get the id's of all existing links. $scope = Scope::parseValue(Scope::VALUE_P_ALL); $query = new QueryEntity($linkEntity, $this->defaultQueryContext, $scope); $query->addWhereClause($oneFkColumnName, $oneId); $mySQLi = $schema->getMySQLi(); $queryString = $query->getQueryString(); $queryResult = $mySQLi->query($queryString); if (!$queryResult) { throw new Exception("Error fetching '{$otherFkColumnName}' properties of link entity " . $linkEntity->getName() . "[{$oneId}] - {$mySQLi->error}\n<!--\n{$queryString}\n-->"); } // Compose a list of otherIds that must be deleted and adjust $otherIds, so it will only contain links that // must be created. $surplusOtherIds = array(); while ($dbObject = $queryResult->fetch_assoc()) { $existingOtherId = $dbObject[$otherFkColumnName]; $key = array_search($existingOtherId, $otherIds); if ($key !== FALSE) { // The link is already there. unset($otherIds[$key]); } else { $surplusOtherIds[] = $existingOtherId; } } $queryResult->close(); // Delete surplus links. if (count($surplusOtherIds) > 0) { $propertyValues = array(); $propertyValues[$oneFkColumnName] = $oneId; $propertyValues[$otherFkColumnName] = $surplusOtherIds; $this->terminateLinks($schema, $linkEntity, $propertyValues, $audit); } // Create missing links. if (count($otherIds) > 0) { $propertyValues = array(); $propertyValues[$oneFkColumnName] = $oneId; foreach ($otherIds as $otherId) { // Pass a NULL to indicate that a new link object must be inserted. $propertyValues[$otherFkColumnName] = $otherId; $this->insertOrUpdate($schema, $linkEntity, NULL, $propertyValues, $audit); } } }
private function fetchObjects(ObjectEntity $entity, $queryId, QueryContext $queryContext, Scope $defaultScope, $skipBinaries, DOMDocument $domDoc, DOMNode $xmlParent, array &$xmlElementsWithState, array &$allFetchedObjects = array()) { // Compose and execute the query. $mySQLi = $this->schema->getMySQLi(); $query = new QueryEntity($entity, $queryContext, $defaultScope, $queryId, $skipBinaries); $queryString = $query->getQueryString(); $queryResult = $mySQLi->query($queryString); if (!$queryResult) { throw new Exception("Error fetching objects of entity '" . $entity->getName() . "' - " . $mySQLi->error . "\n<!--\n{$queryString}\n-->"); } // Convert the query result into XML. while ($dbObject = $queryResult->fetch_assoc()) { $id = $dbObject[$entity->getObjectIdColumnName()]; $objectRef = new ObjectRef($entity, $id); // Beware of endless recursion! $scope = $this->detectEndlessRecursion($objectRef, $query->getScope(), $allFetchedObjects); // Create an XML node with the object id as an attribute and insert the node sorted by entity and id. $xmlElement = $domDoc->createElementNS($this->namespaceUri, $entity->getName()); $xmlElement->setAttribute(XmlConstants::ID, $id); $this->sortedInsertNode($xmlParent, $xmlElement); // Now determine what else to fetch, depending on the given scope. $hasTerminatedObjects = $this->fetchRelatedObjects($objectRef, $queryContext, $scope, $skipBinaries, $domDoc, $xmlElement, $xmlElementsWithState, $allFetchedObjects); // Add any object properties to the XML. $skipBinaryProperties = $skipBinaries || $scope->includes(Scope::TAG_PROPERTIES) == Scope::INCLUDES_REFS_ONLY; $publishedState = $this->addPropertiesToXML($dbObject, $entity, $skipBinaryProperties, $domDoc, $xmlElement, $xmlElementsWithState); if ($hasTerminatedObjects) { $publishedState = FALSE; } // Add a scope-attribute if it is not a reference, if the value is not empty and if it is not updatable. if ($xmlElement->childNodes->length > 0 and strlen($scope->getScopeValue()) > 0 and !$scope->isUpdatable()) { $xmlElement->setAttribute(XmlConstants::SCOPE, $scope->getScopeValue()); } // Notify the published-state to the parent node and its ancestors. $this->setPublishedStateAndPropagateToAncestors($xmlElement, $publishedState); } $queryResult->close(); }