/** * Regression Test for OPUSVIER-3051 */ public function testDocumentServerDateModifiedNotUpdatedWhenCollectionSortOrderChanged() { // check for expected test data $collectionRole1 = new Opus_CollectionRole(1); $this->assertEquals(1, $collectionRole1->getPosition(), 'Test setup changed'); $collectionRole2 = new Opus_CollectionRole(2); $this->assertEquals(2, $collectionRole2->getPosition(), 'Test setup changed'); $docfinder = new Opus_DocumentFinder(); $docfinder->setCollectionRoleId(2); $collectionRoleDocs = $docfinder->ids(); $this->assertTrue(in_array(146, $collectionRoleDocs), 'Test setup changed'); // test if server_date_modified is altered $docBefore = new Opus_Document(146); $this->dispatch('/admin/collectionroles/move/roleid/1/pos/2'); $docAfter = new Opus_Document(146); // revert change in test data $this->resetRequest(); $this->resetResponse(); $this->dispatch('/admin/collectionroles/move/roleid/1/pos/1'); $this->assertEquals((string) $docBefore->getServerDateModified(), (string) $docAfter->getServerDateModified()); }
/** * Im Rahmen der Zuweisung von Dokumenten, die Collections der Collection Role * series zugeordnet sind, müssen verschiedene Konflikte behandelt werden. * * Im Folgenden werden nur Dokumente betrachtet, die mindestens einer Collection * der Collection Role series (kurz: series-Collection) zugeordnet sind. * * Fall 1 (Dokumente ohne IdentifierSerial): * Da die Bandnummer einer Schriftenreihe Opus_Series obligatorisch ist, können * Dokumente ohne IdentifierSerial nicht migriert werden. Sie verbleiben * unangetastet. Die Zuweisung(en) zu series-Collection(s) wird (werden) nicht * verändert. * * Fall 2 (Dokumente mit mehr als einem IdentifierSerial): * Da ein Dokument pro Schriftenreihe nur eine Bandnummer besitzen kann, können * Dokumente mit mehr als einem Wert für das Feld IdentifierSerial nicht * migriert werden. Sie verbleiben unangetastet. Die Zuweisung(en) zu * series-Collection(s) wird (werden) nicht verändert. * * Fall 3 (Dokumente mit einem IdentifierSerial): * Da in einer Schriftenreihe nicht zwei Dokumente mit der gleichen Bandnummer * existieren können, muss beim Zuweisen von Dokumenten darauf geachtet werden, * dass eine Bandnummer nicht mehrfach vergeben wird. * Wird versucht ein Dokument zu einer Schriftenreihe mit einer bereits * in Benutzung befindlichen Bandnummer zuzuweisen, so wird die Zuweisung * nicht durchgeführt. Die Zuweisung des Dokuments zur series-Collection wird * in diesem Fall unverändert beibehalten. * * Im Falle der erfolgreichen Zuweisung des Dokuments zu einer Schriftenreihe * wird die Verknüpfung mit der korrespondierenden series-Collection * entfernt. Außerdem wird das Feld IdentifierSerial entfernt. * * * @return array an array that contains both the number of conflicts found and * the number of documents that were successfully migrated */ private function migrateDocuments() { $numOfConflicts = 0; $numOfDocsMigrated = 0; $finder = new Opus_DocumentFinder(); $finder->setCollectionRoleId($this->seriesRole->getId()); $serialIdsInUse = array(); foreach ($finder->ids() as $docId) { $doc = new Opus_Document($docId); $serialIds = $doc->getIdentifierSerial(); $numOfSerialIds = count($serialIds); if ($numOfSerialIds == 0) { $this->logger->warn("doc #{$docId} : does not have a field IdentifierSerial -- leave it untouched"); $numOfConflicts++; continue; } if ($numOfSerialIds > 1) { $this->logger->warn("doc #{$docId} : has {$numOfSerialIds} values for field IdentifierSerial -- leave it untouched"); $numOfConflicts++; continue; } $serialId = $serialIds[0]->getValue(); $remainingCollections = array(); foreach ($doc->getCollection() as $collection) { // only consider collection in collection role series if ($collection->getRoleId() != $this->seriesRole->getId()) { array_push($remainingCollections, $collection); } else { $collectionId = $collection->getId(); if (!$collection->isRoot()) { // check for conflict if (array_key_exists($collectionId, $serialIdsInUse) && in_array($serialId, $serialIdsInUse[$collectionId])) { // conflict was found: serialId for series $collectionId already in use $this->logger->warn("doc #{$docId} : could not assign to series #{$collectionId}: value {$serialId} already in use"); $this->logger->warn("doc #{$docId} : leave assignment to collection #{$collectionId} untouched"); array_push($remainingCollections, $collection); $numOfConflicts++; } else { // no conflict $series = new Opus_Series($collectionId); $doc->addSeries($series)->setNumber($serialId); $doc->setIdentifierSerial(array()); // mark usage of serialId for collection $collectionId if (array_key_exists($collectionId, $serialIdsInUse)) { array_push($serialIdsInUse[$collectionId], $serialId); } else { $serialIdsInUse[$collectionId] = array($serialId); } $this->logger->info("doc #{$docId} : assign document to series #{$collectionId} with value {$serialId}"); $this->logger->info("doc #{$docId} : removed assignment from collection #{$collectionId}"); $this->logger->info("doc #{$docId} : removed field IdentifierSerial with value " . $serialId); $numOfDocsMigrated++; } } else { // series root collection assignment will not be migrated $this->logger->warn("doc #{$docId} : is assigned to root collection #{$collectionId} of collection role series: leave assignment untouched"); array_push($remainingCollections, $collection); $numOfConflicts++; } } } $doc->setCollection($remainingCollections); $doc->unregisterPlugin('Opus_Document_Plugin_Index'); $doc->store(); } return array('numOfConflicts' => $numOfConflicts, 'numOfDocsMigrated' => $numOfDocsMigrated); }
/** * Retrieve all document ids for a valid oai request. * * @param array &$oaiRequest * @return array */ public function query(array $oaiRequest) { $finder = new Opus_DocumentFinder(); // add server state restrictions $finder->setServerStateInList($this->deliveringDocumentStates); $metadataPrefix = $oaiRequest['metadataPrefix']; if ('xMetaDissPlus' === $metadataPrefix || 'xMetaDiss' === $metadataPrefix) { $finder->setFilesVisibleInOai(); } if ('xMetaDiss' === $metadataPrefix) { $finder->setTypeInList($this->xMetaDissRestriction); } if ('epicur' === $metadataPrefix) { $finder->setIdentifierTypeExists('urn'); } if (array_key_exists('set', $oaiRequest)) { $setarray = explode(':', $oaiRequest['set']); if (!isset($setarray[0])) { return array(); } if ($setarray[0] == 'doc-type') { if (count($setarray) === 2 and !empty($setarray[1])) { $finder->setType($setarray[1]); } else { return array(); } } else { if ($setarray[0] == 'bibliography') { if (count($setarray) !== 2 or empty($setarray[1])) { return array(); } $setValue = $setarray[1]; $bibliographyMap = array("true" => 1, "false" => 0); if (false === isset($setValue, $bibliographyMap[$setValue])) { return array(); } $finder->setBelongsToBibliography($bibliographyMap[$setValue]); } else { if (count($setarray) < 1 or count($setarray) > 2) { $msg = "Invalid SetSpec: Must be in format 'set:subset'."; throw new Oai_Model_Exception($msg); } // Trying to locate collection role and filter documents. $role = Opus_CollectionRole::fetchByOaiName($setarray[0]); if (is_null($role)) { $msg = "Invalid SetSpec: Top level set does not exist."; throw new Oai_Model_Exception($msg); } $finder->setCollectionRoleId($role->getId()); // Trying to locate given collection and filter documents. if (count($setarray) == 2) { $subsetName = $setarray[1]; $foundSubsets = array_filter($role->getOaiSetNames(), function ($s) use($subsetName) { return $s['oai_subset'] === $subsetName; }); if (count($foundSubsets) < 1) { $msg = "Invalid SetSpec: Subset does not exist."; throw new Oai_Model_Exception($msg); } foreach ($foundSubsets as $subset) { if ($subset['oai_subset'] !== $subsetName) { $msg = "Invalid SetSpec: Internal error."; throw new Oai_Model_Exception($msg); } $finder->setCollectionId($subset['id']); } } } } } if (array_key_exists('from', $oaiRequest) and !empty($oaiRequest['from'])) { $from = DateTime::createFromFormat('Y-m-d', $oaiRequest['from']); $finder->setServerDateModifiedAfter($from->format('Y-m-d')); } if (array_key_exists('until', $oaiRequest)) { $until = DateTime::createFromFormat('Y-m-d', $oaiRequest['until']); $until->add(new DateInterval('P1D')); $finder->setServerDateModifiedBefore($until->format('Y-m-d')); } return $finder->ids(); }