public function fetchRelatedObjectRefsOfEntity(MySQLi $mySQLi, ObjectEntity $otherEntity, QueryContext $queryContext, Scope $scope, array &$fetchedObjectRefs)
 {
     // Find the corresponding relationship, ignoring link-relationships.
     $hasTerminatedObjects = FALSE;
     foreach ($this->objectEntity->getRelationships() as $relationship) {
         if ($relationship->getOppositeEntity($this->objectEntity) != $otherEntity) {
             continue;
         }
         // Select the id of the related object.
         $objectIdColumnName = $otherEntity->getObjectIdColumnName();
         $query = new QueryRelatedEntity($this->objectEntity, $this->id, $relationship, $queryContext, $scope);
         $query->setPropertyNames(array($objectIdColumnName));
         $queryString = $query->getQueryString();
         $queryResult = $mySQLi->query($queryString);
         if (!$queryResult) {
             throw new Exception("Error fetching ObjectRefs of entity '" . $otherEntity->getName() . "', associated to '" . $this->objectEntity->getName() . "[{$this->id}]' - " . $mySQLi->error . "\n<!--\n{$queryString}\n-->");
         }
         while ($dbObject = $queryResult->fetch_assoc()) {
             $objectRef = new ObjectRef($otherEntity, $dbObject[$objectIdColumnName]);
             if (!$queryContext->getParameterPublished() and isset($dbObject[QueryEntity::ID_TERMINATED])) {
                 $hasTerminatedObjects = TRUE;
             } else {
                 // Always use the objectRef if we're fetching published data or if it's not terminated.
                 $fetchedObjectRefs[] = $objectRef;
             }
         }
         $queryResult->close();
     }
     return $hasTerminatedObjects;
 }
 private function terminateObject(Schema $schema, ObjectEntity $entity, $id, Audit $audit)
 {
     if ($entity->getStateIdColumnName() == NULL) {
         return 0;
     }
     $mySQLi = $schema->getMySQLi();
     $queryString = "UPDATE " . DbConstants::TABLE_STATE . " s, " . $entity->getName() . " e SET" . " s.id_terminated = " . $audit->getId() . " WHERE s.id = e." . $entity->getStateIdColumnName() . " AND s.id_terminated IS NULL" . " AND e." . $entity->getObjectIdColumnName() . " = {$id}";
     $queryResult = $mySQLi->query($queryString);
     if (!$queryResult) {
         throw new Exception("Error terminating object " . $entity->getName() . "[{$id}] - {$mySQLi->error}\n<!--\n{$queryString}\n-->");
     }
     return $mySQLi->affected_rows;
 }
 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();
 }