/** * Generate a unique upload token. Either <b>itemid</b> or <b>folderid</b> is required, * but both are not allowed. * * @path /system/uploadtoken * @http GET * @param useSession (Optional) Authenticate using the current Midas session * @param token (Optional) Authentication token * @param itemid (Optional) * The id of the item to upload into. * @param folderid (Optional) * The id of the folder to create a new item in and then upload to. * The new item will have the same name as <b>filename</b> unless <b>itemname</b> * is supplied. * @param filename The filename of the file you will upload, will be used as the * bitstream's name and the item's name (unless <b>itemname</b> is supplied). * @param itemdescription (Optional) * When passing the <b>folderid</b> param, the description of the item, * if not supplied the item's description will be blank. * @param itemname (Optional) * When passing the <b>folderid</b> param, the name of the newly created item, * if not supplied, the item will have the same name as <b>filename</b>. * @param checksum (Optional) The md5 checksum of the file to be uploaded. * @return An upload token that can be used to upload a file. * If <b>folderid</b> is passed instead of <b>itemid</b>, a new item will be created * in that folder, but the id of the newly created item will not be * returned. If the id of the newly created item is needed, * then call the <b>/item (POST)</b> api instead. * If <b>checksum</b> is passed and the token returned is blank, the * server already has this file and there is no need to follow this * call with a call to <b>/system/upload</b>, as the passed in * file will have been added as a bitstream to the item's latest * revision, creating a new revision if one doesn't exist. * * @param array $args parameters * @throws Exception */ public function uploadGeneratetoken($args) { /** @var ApihelperComponent $apihelperComponent */ $apihelperComponent = MidasLoader::loadComponent('Apihelper'); $apihelperComponent->validateParams($args, array('filename')); if (!array_key_exists('itemid', $args) && !array_key_exists('folderid', $args)) { throw new Exception('Parameter itemid or folderid must be defined', MIDAS_INVALID_PARAMETER); } if (array_key_exists('itemid', $args) && array_key_exists('folderid', $args)) { throw new Exception('Parameter itemid or folderid must be defined, but not both', MIDAS_INVALID_PARAMETER); } $apihelperComponent->requirePolicyScopes(array(MIDAS_API_PERMISSION_SCOPE_WRITE_DATA)); $userDao = $apihelperComponent->getUser($args); if (!$userDao) { throw new Exception('Anonymous users may not upload', MIDAS_INVALID_POLICY); } /** @var ItemModel $itemModel */ $itemModel = MidasLoader::loadModel('Item'); if (array_key_exists('itemid', $args)) { $item = $itemModel->load($args['itemid']); if (!$itemModel->policyCheck($item, $userDao, MIDAS_POLICY_WRITE)) { throw new Exception('Invalid policy or itemid', MIDAS_INVALID_POLICY); } } elseif (array_key_exists('folderid', $args)) { /** @var FolderModel $folderModel */ $folderModel = MidasLoader::loadModel('Folder'); $folder = $folderModel->load($args['folderid']); if ($folder == false) { throw new Exception('Parent folder corresponding to folderid doesn\'t exist', MIDAS_INVALID_PARAMETER); } if (!$folderModel->policyCheck($folder, $userDao, MIDAS_POLICY_WRITE)) { throw new Exception('Invalid policy or folderid', MIDAS_INVALID_POLICY); } // create a new item in this folder $itemname = isset($args['itemname']) ? $args['itemname'] : $args['filename']; $description = isset($args['itemdescription']) ? $args['itemdescription'] : ''; $item = $itemModel->createItem($itemname, $description, $folder); if ($item === false) { throw new Exception('Create new item failed', MIDAS_INTERNAL_ERROR); } $itemModel->copyParentPolicies($item, $folder); /** @var ItempolicyuserModel $itempolicyuserModel */ $itempolicyuserModel = MidasLoader::loadModel('Itempolicyuser'); $itempolicyuserModel->createPolicy($userDao, $item, MIDAS_POLICY_ADMIN); } if (array_key_exists('checksum', $args)) { // If we already have a bitstream with this checksum, create a reference and return blank token /** @var BitstreamModel $bitstreamModel */ $bitstreamModel = MidasLoader::loadModel('Bitstream'); $existingBitstream = $bitstreamModel->getByChecksum($args['checksum']); if ($existingBitstream) { // User must have read access to the existing bitstream if they are circumventing the upload. // Otherwise an attacker could spoof the checksum and read a private bitstream with a known checksum. if ($itemModel->policyCheck($existingBitstream->getItemrevision()->getItem(), $userDao, MIDAS_POLICY_READ)) { $revision = $itemModel->getLastRevision($item); if ($revision === false) { // Create new revision if none exists yet Zend_Loader::loadClass('ItemRevisionDao', BASE_PATH . '/core/models/dao'); $revision = new ItemRevisionDao(); $revision->setChanges('Initial revision'); $revision->setUser_id($userDao->getKey()); $revision->setDate(date('Y-m-d H:i:s')); $revision->setLicenseId(null); $itemModel->addRevision($item, $revision); } $siblings = $revision->getBitstreams(); foreach ($siblings as $sibling) { if ($sibling->getName() == $args['filename']) { // already have a file with this name. don't add new record. return array('token' => ''); } } Zend_Loader::loadClass('BitstreamDao', BASE_PATH . '/core/models/dao'); $bitstream = new BitstreamDao(); $bitstream->setChecksum($args['checksum']); $bitstream->setName($args['filename']); $bitstream->setSizebytes($existingBitstream->getSizebytes()); $bitstream->setPath($existingBitstream->getPath()); $bitstream->setAssetstoreId($existingBitstream->getAssetstoreId()); $bitstream->setMimetype($existingBitstream->getMimetype()); /** @var ItemRevisionModel $revisionModel */ $revisionModel = MidasLoader::loadModel('ItemRevision'); $revisionModel->addBitstream($revision, $bitstream); return array('token' => ''); } } } // we don't already have this content, so create the token /** @var HttpuploadComponent $uploadComponent */ $uploadComponent = MidasLoader::loadComponent('Httpupload'); $apiSetup = $apihelperComponent->getApiSetup(); $uploadComponent->setTestingMode(Zend_Registry::get('configGlobal')->environment === 'testing'); return $uploadComponent->generateToken($args, $userDao->getKey() . '/' . $item->getKey()); }
/** Import a directory recursively */ private function _recursiveParseDirectory($path, $currentdir) { $it = new DirectoryIterator($path); foreach ($it as $fileInfo) { if ($fileInfo->isDot()) { continue; } // If the file/dir is not readable (permission issue) if (!$fileInfo->isReadable()) { $this->getLogger()->crit($fileInfo->getPathName() . ' cannot be imported. Not readable.'); continue; } // If this is too slow we'll figure something out if ($this->_checkStopImport()) { return false; } if ($fileInfo->isDir()) { // we have a directory // If the the directory actually doesn't exist at this point, // skip it. if (!file_exists($fileInfo->getPathName())) { continue; } // Get the files in the directory and skip the folder if it does not // contain any files and we aren't set to import empty directories. The // count($files) <= 2 is there to account for our our friends . and .. $files = scandir($fileInfo->getPathName()); if (!$this->importemptydirectories && $files && count($files) <= 2) { continue; } // Find if the child exists $child = $this->Folder->getFolderByName($currentdir, $fileInfo->getFilename()); // If the folder does not exist, create one. if (!$child) { $child = new FolderDao(); $child->setName($fileInfo->getFilename()); $child->setParentId($currentdir->getFolderId()); $child->setDateCreation(date('Y-m-d H:i:s')); $child->setDescription(''); $this->Folder->save($child); $this->Folderpolicyuser->createPolicy($this->userSession->Dao, $child, MIDAS_POLICY_ADMIN); } // Keep descending $this->_recursiveParseDirectory($fileInfo->getPathName(), $child); } else { // We have a file $this->_incrementFileProcessed(); $newrevision = true; $item = $this->Folder->getItemByName($currentdir, $fileInfo->getFilename()); if (!$item) { // Create an item $item = new ItemDao(); $item->setName($fileInfo->getFilename()); $item->setDescription(''); $item->setPrivacyStatus(MIDAS_PRIVACY_PRIVATE); // Must set this flag private initially $this->Item->save($item, true); // Set the policy of the item $this->Itempolicyuser->createPolicy($this->userSession->Dao, $item, MIDAS_POLICY_ADMIN); // Add the item to the current directory $this->Folder->addItem($currentdir, $item); } // Check if the bistream has been updated based on the local date $revision = $this->ItemRevision->getLatestRevision($item); if ($revision) { $newrevision = false; $bitstream = $this->ItemRevision->getBitstreamByName($revision, $fileInfo->getFilename()); $curMD5 = UtilityComponent::md5file($fileInfo->getPathName()); $diskFileIsNewer = strtotime($bitstream->getDate()) < filemtime($fileInfo->getPathName()); $md5IsDifferent = $bitstream->getChecksum() != $curMD5; if (!$bitstream || $diskFileIsNewer && $md5IsDifferent) { $newrevision = true; } } if ($newrevision) { // Create a revision for the item $itemRevisionDao = new ItemRevisionDao(); $itemRevisionDao->setChanges('Initial revision'); $itemRevisionDao->setUser_id($this->userSession->Dao->getUserId()); $this->Item->addRevision($item, $itemRevisionDao); // Add bitstreams to the revision $this->getLogger()->debug('create New Bitstream'); $bitstreamDao = new BitstreamDao(); $bitstreamDao->setName($fileInfo->getFilename()); $bitstreamDao->setPath($fileInfo->getPathName()); $bitstreamDao->fillPropertiesFromPath(); // Set the Assetstore $bitstreamDao->setAssetstoreId($this->assetstoreid); // Upload the bitstream $assetstoreDao = $this->Assetstore->load($this->assetstoreid); $this->Component->Upload->uploadBitstream($bitstreamDao, $assetstoreDao, true); $this->ItemRevision->addBitstream($itemRevisionDao, $bitstreamDao); } } } unset($it); return true; }
/** testRemoveRevision */ public function testRemoveRevision() { Zend_Registry::set('modulesEnable', array()); Zend_Registry::set('notifier', new MIDAS_Notifier(false, null)); $itemsFile = $this->loadData('Item', 'default'); $usersFile = $this->loadData('User', 'default'); $item = $itemsFile[1]; // remove any revisions that may exist while ($this->Item->getLastRevision($itemsFile[1])) { $revision = $this->Item->getLastRevision($itemsFile[1]); $this->Item->removeRevision($item, $revision); } // add on 3 revisions $revision = new ItemRevisionDao(); $revision->setUserId($usersFile[0]->getKey()); $revision->setDate(date('Y-m-d H:i:s')); $revision->setChanges('r1'); $revision->setItemId(0); $revision->setRevision(1); $this->ItemRevision->save($revision); $this->Item->addRevision($itemsFile[1], $revision); $lastRev = $this->Item->getLastRevision($item); $this->assertEquals($revision->getKey(), $lastRev->getKey()); $this->assertEquals($revision->getChanges(), $lastRev->getChanges()); $revision = new ItemRevisionDao(); $revision->setUserId($usersFile[0]->getKey()); $revision->setDate(date('Y-m-d H:i:s')); $revision->setChanges('r2'); $revision->setItemId(0); $revision->setRevision(2); $this->ItemRevision->save($revision); $this->Item->addRevision($item, $revision); $lastRev = $this->Item->getLastRevision($item); $this->assertEquals($revision->getKey(), $lastRev->getKey()); $this->assertEquals($revision->getChanges(), $lastRev->getChanges()); $revision = new ItemRevisionDao(); $revision->setUserId($usersFile[0]->getKey()); $revision->setDate(date('Y-m-d H:i:s')); $revision->setChanges('r3'); $revision->setItemId(0); $revision->setRevision(3); $this->ItemRevision->save($revision); $this->Item->addRevision($item, $revision); $lastRev = $this->Item->getLastRevision($item); $this->assertEquals($revision->getKey(), $lastRev->getKey()); $this->assertEquals($revision->getChanges(), $lastRev->getChanges()); // we now have revision:changes 1:r1, 2:r2, 3:r3 // remove r3, check that last revision changes = r2 $this->Item->removeRevision($item, $lastRev); $lastRev = $this->Item->getLastRevision($item); $this->assertEquals($lastRev->getRevision(), '2'); $this->assertEquals($lastRev->getChanges(), 'r2'); // now we have 1:r1, 2:r2 // remove r1, check that last revision changes = r2 and revision = 1 $rev1 = $this->Item->getRevision($item, 1); $this->Item->removeRevision($item, $rev1); $lastRev = $this->Item->getLastRevision($item); $this->assertEquals($lastRev->getRevision(), '1'); $this->assertEquals($lastRev->getChanges(), 'r2'); // now we have 1:r2 // remove r2, check that there are no revisions $this->Item->removeRevision($item, $lastRev); $lastRev = $this->Item->getLastRevision($item); $this->assertFalse($lastRev); }
/** * Return the latest bitstream from the given item revision. * * @param ItemRevisionDao $itemRevisionDao item revision DAO * @return BitstreamDao * @throws Zend_Exception */ public function getLatestBitstream($itemRevisionDao) { $bitstreamDaos = $itemRevisionDao->getBitstreams(); if (count($bitstreamDaos) === 0) { throw new Zend_Exception('Item revision does not contain any bitstreams'); } return $bitstreamDaos[0]; }
/** * Save upload item in the database. * * @param UserDao $userDao * @param string $name * @param string $url * @param null|int $parent * @param int $sizebytes * @param string $checksum * @return ItemDao * @throws Zend_Exception */ public function createLinkItem($userDao, $name, $url, $parent = null, $sizebytes = 0, $checksum = ' ') { /** @var ItemModel $itemModel */ $itemModel = MidasLoader::loadModel('Item'); /** @var FolderModel $folderModel */ $folderModel = MidasLoader::loadModel('Folder'); /** @var AssetstoreModel $assetstoreModel */ $assetstoreModel = MidasLoader::loadModel('Assetstore'); /** @var ItemRevisionModel $itemRevisionModel */ $itemRevisionModel = MidasLoader::loadModel('ItemRevision'); if ($userDao == null) { throw new Zend_Exception('Please log in'); } if (is_numeric($parent)) { $parent = $folderModel->load($parent); } if ($parent == false || !$folderModel->policyCheck($parent, $userDao, MIDAS_POLICY_WRITE)) { throw new Zend_Exception('Parent permissions errors'); } Zend_Loader::loadClass('ItemDao', BASE_PATH . '/core/models/dao'); $item = new ItemDao(); $item->setName($name); $item->setDescription(''); $item->setSizebytes($sizebytes); $item->setType(0); $item->setPrivacyStatus(MIDAS_PRIVACY_PRIVATE); // Must set this flag private initially $itemModel->save($item, false); $folderModel->addItem($parent, $item); $itemModel->copyParentPolicies($item, $parent); Zend_Loader::loadClass('ItemRevisionDao', BASE_PATH . '/core/models/dao'); $itemRevisionDao = new ItemRevisionDao(); $itemRevisionDao->setChanges('Initial revision'); $itemRevisionDao->setUser_id($userDao->getKey()); $itemRevisionDao->setDate(date('Y-m-d H:i:s')); $itemRevisionDao->setLicenseId(null); $itemModel->addRevision($item, $itemRevisionDao); // Add bitstreams to the revision Zend_Loader::loadClass('BitstreamDao', BASE_PATH . '/core/models/dao'); $bitstreamDao = new BitstreamDao(); $bitstreamDao->setName($url); $bitstreamDao->setPath($url); $bitstreamDao->setMimetype('url'); $bitstreamDao->setSizebytes($sizebytes); $bitstreamDao->setChecksum($checksum); $assetstoreDao = $assetstoreModel->getDefault(); $bitstreamDao->setAssetstoreId($assetstoreDao->getKey()); $itemRevisionModel->addBitstream($itemRevisionDao, $bitstreamDao); $this->getLogger()->debug('Link item created (' . $item->getName() . ', id=' . $item->getKey() . ')'); return $item; }
/** Test file upload */ public function testBitstreamUpload() { $this->resetAll(); $itemsFile = $this->loadData('Item', 'default'); // This method is quite complex, so here is a listing of all // the tests performed. Also, the upload.generatetoken and // upload.perform have been reworked for 3.2.8, but the previous // versions of the API are tested here for backwards compatibility // (the previous versions of the APIs should still work). // Each request gets a new count, related requests are grouped. /* * 1 generate upload token for an item lacking permissions, ERROR * * 2 generate an upload token for an item with permissions * 3 upload using 2's token to the head revision * 4 upload again using 2's token, tokens should be 1 time use, ERROR * * 5 generate an upload token with a checksum of an existing bitstream * * 6 create a new item in the user root folder * 23 create a duplicate name item in user root folder with item.create * 24 create a duplicate name item in user root folder with generatetoken * 7 generate an upload token for 6's item, using a checksum of an existing bitstream * * 8 create a new item in the user root folder * 9 generate an upload token for 8's item, without a checksum *10 upload to 8's item revision 1, which doesn't exist, ERROR *11 upload to 8's item head revision, this will create a revision 1 *12 upload to 8's item head revision again, tests using head revision when one exists * *13 generatetoken without folderid or itemid, ERROR * *14 generatetoken with folderid and itemid, ERROR * *15 generatetoken passing in folderid, default of Public * *16 generatetoken passing in folderid and setting optional values with Private itemprivacy *17 upload without passing a revision to 16's item, this should create a revision 1 *18 generate a token for 16's item *19 upload to an item with an existing revision, without the revision parameter, which should create a new revision 2 *20 generate a token for 16's item, after creating 2 new revisions, 3 and 4 *21 upload to an item with 4 revisions, with revision parameter of 3, check that revision 3 has the bitstream and revision 4 has 0 bitstreams * *22 generatetoken passing in folderid and a checksum of an existing bitstream, * and passing Public explicitly *25 generatetoken passing in folderid and checksum of an existing bitstream, but the user * has no read access to the already existing item, so exception is thrown * */ // 1 // generate an upload token $this->params['token'] = $this->_loginAsNormalUser(); $this->params['method'] = 'midas.upload.generatetoken'; $this->params['filename'] = 'test.txt'; $this->params['checksum'] = 'foo'; // call should fail for the first item since we don't have write permission $this->params['itemid'] = $itemsFile[0]->getKey(); $resp = $this->_callJsonApi(); $this->_assertStatusFail($resp, MIDAS_INVALID_POLICY, 'Invalid policy or itemid'); // now upload using our token $this->resetAll(); $usersFile = $this->loadData('User', 'default'); $itemsFile = $this->loadData('Item', 'default'); // generate the test file $string = ''; $length = 100; for ($i = 0; $i < $length; ++$i) { $string .= 'a'; } $fh = fopen($this->getTempDirectory() . '/test.txt', 'w'); fwrite($fh, $string); fclose($fh); $md5 = md5($string); $assetstores = $this->Assetstore->getAll(); $this->assertTrue(count($assetstores) > 0, 'There are no assetstores defined in the database'); $assetstoreFile = $assetstores[0]->getPath() . '/' . substr($md5, 0, 2) . '/' . substr($md5, 2, 2) . '/' . $md5; if (file_exists($assetstoreFile)) { unlink($assetstoreFile); } // 2 // generate another upload token $this->params['token'] = $this->_loginAsNormalUser(); $this->params['method'] = 'midas.upload.generatetoken'; $this->params['filename'] = 'test.txt'; $this->params['checksum'] = $md5; // use the second item since it has write permission set for our user $this->params['itemid'] = $itemsFile[1]->getKey(); $resp = $this->_callJsonApi(); $this->_assertStatusOk($resp); // verify the upload token $token = $resp->data->token; $this->assertTrue(preg_match('/^' . $usersFile[0]->getKey() . '\\/' . $itemsFile[1]->getKey() . '\\/.+/', $token) > 0, 'Upload token (' . $token . ') is not of the form <userid>/<itemid>/*'); $this->assertTrue(file_exists($this->getTempDirectory() . '/' . $token), 'Token placeholder file ' . $token . ' was not created in the temp dir'); // 3 // attempt the upload $this->resetAll(); $this->params['method'] = 'midas.upload.perform'; $this->params['uploadtoken'] = $token; $this->params['filename'] = 'test.txt'; $this->params['length'] = $length; $this->params['revision'] = 'head'; // upload into head revision $this->params['testingmode'] = 'true'; $changes = 'revision message'; $this->params['changes'] = $changes; $resp = $this->_callJsonApi(); $this->_assertStatusOk($resp); $this->assertTrue(file_exists($assetstoreFile), 'File was not written to the assetstore'); $this->assertEquals(filesize($assetstoreFile), $length, 'Assetstore file is the wrong length'); $this->assertEquals(md5_file($assetstoreFile), $md5, 'Assetstore file had incorrect checksum'); // make sure it was uploaded to the head revision of the item $itemDao = $this->Item->load($itemsFile[1]->getKey()); $revisions = $itemDao->getRevisions(); $this->assertEquals(count($revisions), 1, 'Wrong number of revisions in the item'); $bitstreams = $revisions[0]->getBitstreams(); $this->assertEquals($revisions[0]->getChanges(), $changes, 'Wrong number of bitstreams in the revision'); $this->assertEquals(count($bitstreams), 1, 'Wrong number of bitstreams in the revision'); $this->assertEquals($bitstreams[0]->name, 'test.txt'); $this->assertEquals($bitstreams[0]->sizebytes, $length); $this->assertEquals($bitstreams[0]->checksum, $md5); // 4 // when calling midas.upload.perform 2x in a row with the same params // (same upload token, same file that had just been uploaded), // the response should be an invalid token. // // This is because the token is good for a single upload, and it no longer // exists once the original upload is finished. $this->resetAll(); $this->params['method'] = 'midas.upload.perform'; $this->params['uploadtoken'] = $token; $this->params['filename'] = 'test.txt'; $this->params['length'] = $length; $this->params['revision'] = 'head'; // upload into head revision $this->params['testingmode'] = 'true'; $resp = $this->_callJsonApi(); $this->_assertStatusFail($resp, MIDAS_INVALID_UPLOAD_TOKEN); // 5 // Check that a redundant upload yields a blank upload token and a new reference // redundant upload meaning uploading a checksum that already exists $this->resetAll(); $this->params['token'] = $this->_loginAsNormalUser(); $this->params['method'] = 'midas.upload.generatetoken'; $this->params['filename'] = 'test2.txt'; $this->params['checksum'] = $md5; $this->params['itemid'] = $itemsFile[1]->getKey(); $resp = $this->_callJsonApi(); $this->_assertStatusOk($resp); $token = $resp->data->token; $this->assertEquals($token, '', 'Redundant content upload did not return a blank token'); // check that the new bitstream has been created // in the generatetoken step $itemDao = $this->Item->load($itemsFile[1]->getKey()); $revisions = $itemDao->getRevisions(); $this->assertEquals(count($revisions), 1, 'Wrong number of revisions in the item'); $bitstreams = $revisions[0]->getBitstreams(); $this->assertEquals(count($bitstreams), 2, 'Wrong number of bitstreams in the revision'); $this->assertEquals($bitstreams[0]->name, 'test.txt'); $this->assertEquals($bitstreams[0]->sizebytes, $length); $this->assertEquals($bitstreams[0]->checksum, $md5); $this->assertEquals($bitstreams[1]->name, 'test2.txt'); $this->assertEquals($bitstreams[1]->sizebytes, $length); $this->assertEquals($bitstreams[1]->checksum, $md5); // separate testing for item create and delete // 6 // create a new item in the user root folder // use folderid 1000 $this->resetAll(); $this->params['token'] = $this->_loginAsNormalUser(); $this->params['method'] = 'midas.item.create'; $this->params['name'] = 'created_item'; $this->params['parentid'] = '1000'; $resp = $this->_callJsonApi(); $this->_assertStatusOk($resp); $generatedItemId = $resp->data->item_id; $itemDao = $this->Item->load($generatedItemId); $revisions = $itemDao->getRevisions(); $this->assertEquals(count($revisions), 0, 'Wrong number of revisions in the new item'); // 23 // create a new item in the user root folder with a duplicate name, which // will result in an item with an amended name from the request // use folderid 1000 $this->resetAll(); $this->params['token'] = $this->_loginAsNormalUser(); $this->params['method'] = 'midas.item.create'; $this->params['name'] = 'created_item'; $this->params['parentid'] = '1000'; $resp = $this->_callJsonApi(); $this->_assertStatusOk($resp); $generatedDuplicateItemId = $resp->data->item_id; $itemDao = $this->Item->load($generatedDuplicateItemId); $revisions = $itemDao->getRevisions(); $this->assertEquals(count($revisions), 0, 'Wrong number of revisions in the new item'); $this->assertEquals($itemDao->getName(), 'created_item (1)', 'Duplicate Item has wrong name'); // delete the newly created item $this->Item->delete($itemDao); // 24 // create a new item in the user root folder with a duplicate name, which // will result in an item with an amended name from the request, using // upload.generatetoken, use folderid 1000 $this->resetAll(); $this->params['token'] = $this->_loginAsNormalUser(); $this->params['method'] = 'midas.upload.generatetoken'; $this->params['name'] = 'created_item'; $this->params['filename'] = 'created_item'; $this->params['folderid'] = '1000'; $resp = $this->_callJsonApi(); $this->_assertStatusOk($resp); $token = $resp->data->token; $tokenParts = explode('/', $token); $generatedDuplicateItemId = $tokenParts[1]; $itemDao = $this->Item->load($generatedDuplicateItemId); $revisions = $itemDao->getRevisions(); $this->assertEquals(count($revisions), 0, 'Wrong number of revisions in the new item'); $this->assertEquals($itemDao->getName(), 'created_item (1)', 'Duplicate Item has wrong name'); // delete the newly created item $this->Item->delete($itemDao); // 25 // Just like #22, but we want to make sure the clone existing bitstream behavior // doesn't happen when the user doesn't have read access to the item with the given checksum. // Otherwise for an attacker, having the checksum of a bitstream would allow them to exploit // upload.generatetoken to gain read access to that bitstream, even if they didn't have // read access on it. $existingItem = $this->Item->load(1001); // this should be the item with the existing bitstream in it $policy = $this->Itempolicyuser->getPolicy($usersFile[0], $existingItem); $this->Itempolicyuser->delete($policy); // delete permission for the user on the item $this->resetAll(); $this->params['token'] = $this->_loginAsNormalUser(); $this->params['method'] = 'midas.upload.generatetoken'; $this->params['filename'] = 'some_new_file.txt'; $this->params['checksum'] = $md5; $this->params['folderid'] = '1000'; $this->params['itemprivacy'] = 'Public'; $resp = $this->_callJsonApi(); $this->_assertStatusOk($resp); $token = $resp->data->token; $this->assertNotEquals($token, '', 'User needs read access to existing bitstream to clone it'); $this->Itempolicyuser->createPolicy($usersFile[0], $existingItem, $policy->getPolicy()); // restore policy state // 7 // generate upload token // when we generate an upload token for a newly created item with a // previously uploaded bitstream, and we are passing the checksum, // we expect that the item will create a new revision for the bitstream, // but pass back an empty upload token, since we have the bitstream content // already and do not need to actually upload it $this->resetAll(); $this->params['token'] = $this->_loginAsNormalUser(); $this->params['method'] = 'midas.upload.generatetoken'; $this->params['filename'] = 'test3.txt'; $this->params['checksum'] = $md5; $this->params['itemid'] = $generatedItemId; $resp = $this->_callJsonApi(); $this->_assertStatusOk($resp); $token = $resp->data->token; $this->assertEquals($token, '', 'Redundant content upload did not return a blank token'); $itemDao = $this->Item->load($generatedItemId); $revisions = $itemDao->getRevisions(); $this->assertEquals(count($revisions), 1, 'Wrong number of revisions in the item'); $bitstreams = $revisions[0]->getBitstreams(); $this->assertEquals(count($bitstreams), 1, 'Wrong number of bitstreams in the revision'); $this->assertEquals($bitstreams[0]->name, 'test3.txt'); $this->assertEquals($bitstreams[0]->sizebytes, $length); $this->assertEquals($bitstreams[0]->checksum, $md5); // delete the newly created item $this->Item->delete($itemDao); // 8 // create a new item in the user root folder // use folderid 1000 // need a new item because we are testing functionality involved with // a new item $this->resetAll(); $this->params['token'] = $this->_loginAsNormalUser(); $this->params['method'] = 'midas.item.create'; $this->params['name'] = 'created_item2'; $this->params['parentid'] = '1000'; $resp = $this->_callJsonApi(); $this->_assertStatusOk($resp); $generatedItemId = $resp->data->item_id; $itemDao = $this->Item->load($generatedItemId); $revisions = $itemDao->getRevisions(); $this->assertEquals(count($revisions), 0, 'Wrong number of revisions in the new item'); // 9 // generate upload token // when we generate an upload token for a newly created item without any // previously uploaded bitstream (and we don't pass a checksum), // we expect that the item will not create any new revision for the bitstream, // and that a non-blank upload token will be returned. $this->resetAll(); $this->params['token'] = $this->_loginAsNormalUser(); $this->params['method'] = 'midas.upload.generatetoken'; $this->params['filename'] = 'test.txt'; $this->params['itemid'] = $generatedItemId; $resp = $this->_callJsonApi(); $token = $resp->data->token; // verify the token $this->assertTrue(preg_match('/^' . $usersFile[0]->getKey() . '\\/' . $generatedItemId . '\\/.+/', $token) > 0, 'Upload token (' . $token . ') is not of the form <userid>/<itemid>/*.*'); $this->assertTrue(file_exists($this->getTempDirectory() . '/' . $token), 'Token placeholder file ' . $token . ' was not created in the temp dir'); $itemDao = $this->Item->load($generatedItemId); $revisions = $itemDao->getRevisions(); $this->assertEquals(count($revisions), 0, 'Wrong number of revisions in the new item'); // 10 // upload to revision 1, this should be an error since there is no such rev $this->resetAll(); $this->params['method'] = 'midas.upload.perform'; $this->params['uploadtoken'] = $token; $this->params['filename'] = 'test.txt'; $this->params['length'] = $length; $this->params['revision'] = '1'; // upload into revision 1 $this->params['testingmode'] = 'true'; $resp = $this->_callJsonApi(); $this->_assertStatusFail($resp, MIDAS_INVALID_PARAMETER); // 11 // upload to head revision, this should create a revision 1 and // put the bitstream there $this->resetAll(); $this->params['method'] = 'midas.upload.perform'; $this->params['uploadtoken'] = $token; $this->params['filename'] = 'test.txt'; $this->params['length'] = $length; $this->params['revision'] = 'head'; // upload into head revision $this->params['testingmode'] = 'true'; $this->params['DBG'] = 'true'; $this->_callJsonApi(); // ensure that there is 1 revision with 1 bitstream $revisions = $itemDao->getRevisions(); $this->assertEquals(count($revisions), 1, 'Wrong number of revisions in the new item'); $bitstreams = $revisions[0]->getBitstreams(); $this->assertEquals(count($bitstreams), 1, 'Wrong number of bitstreams in the revision'); $this->assertEquals($bitstreams[0]->name, 'test.txt'); $this->assertEquals($bitstreams[0]->sizebytes, $length); $this->assertEquals($bitstreams[0]->checksum, $md5); // 12 // upload to head revision again, to test using the head revision when one exists $this->resetAll(); $this->params['method'] = 'midas.upload.perform'; $this->params['uploadtoken'] = $token; $this->params['filename'] = 'test.txt'; $this->params['length'] = $length; $this->params['revision'] = 'head'; // upload into head revision $this->params['testingmode'] = 'true'; $this->params['DBG'] = 'true'; $this->_callJsonApi(); // ensure that there is 1 revision with 1 bitstream, will be only one bitstream // since we are uploading the same file $revisions = $itemDao->getRevisions(); $this->assertEquals(count($revisions), 1, 'Wrong number of revisions in the new item'); $bitstreams = $revisions[0]->getBitstreams(); $this->assertEquals(count($bitstreams), 1, 'Wrong number of bitstreams in the revision'); $this->assertEquals($bitstreams[0]->name, 'test.txt'); $this->assertEquals($bitstreams[0]->sizebytes, $length); $this->assertEquals($bitstreams[0]->checksum, $md5); // 13 // test upload.generatetoken without folderid or itemid $this->resetAll(); $this->params['token'] = $this->_loginAsNormalUser(); $this->params['method'] = 'midas.upload.generatetoken'; $this->params['filename'] = 'test.txt'; $resp = $this->_callJsonApi(); // should be an error $this->_assertStatusFail($resp, MIDAS_INVALID_PARAMETER); // 14 // test upload.generatetoken with folderid and itemid $this->resetAll(); $this->params['token'] = $this->_loginAsNormalUser(); $this->params['method'] = 'midas.upload.generatetoken'; $this->params['filename'] = 'test.txt'; $this->params['itemid'] = '0'; $this->params['folderid'] = '0'; $resp = $this->_callJsonApi(); // should be an error $this->_assertStatusFail($resp, MIDAS_INVALID_PARAMETER); // 15 // test upload.generatetoken passing in folderid $this->resetAll(); $this->params['token'] = $this->_loginAsNormalUser(); $this->params['method'] = 'midas.upload.generatetoken'; $filename = 'test.txt'; $this->params['filename'] = $filename; $this->params['folderid'] = '1000'; $resp = $this->_callJsonApi(); $this->_assertStatusOk($resp); $token = $resp->data->token; // don't know the itemid as it is generated, but can get it from the token $this->assertTrue(preg_match('/^' . $usersFile[0]->getKey() . '\\/(\\d+)\\/.+/', $token, $matches) > 0, 'Upload token (' . $token . ') is not of the form <userid>/<itemid>/*.*'); $generatedItemId = $matches[1]; $this->assertTrue(file_exists($this->getTempDirectory() . '/' . $token), 'Token placeholder file ' . $token . ' was not created in the temp dir'); // test that the item was created without any revisions $itemDao = $this->Item->load($generatedItemId); $revisions = $itemDao->getRevisions(); $this->assertEquals(count($revisions), 0, 'Wrong number of revisions in the new item'); // test that the properties of the item are as expected with defaults $this->assertEquals($itemDao->getName(), $filename, 'Expected a different name for generated item'); $this->assertEquals($itemDao->getDescription(), '', 'Expected a different description for generated item'); $this->assertEquals($itemDao->getPrivacyStatus(), MIDAS_PRIVACY_PRIVATE, 'Expected a different privacy_status for generated item'); // delete the newly created item $this->Item->delete($itemDao); // 16 // test upload.generatetoken passing in folderid and setting optional values $filename = 'test.txt'; $description = 'generated item description'; $itemname = 'generated item name'; $this->resetAll(); $this->params['token'] = $this->_loginAsNormalUser(); $this->params['method'] = 'midas.upload.generatetoken'; $this->params['filename'] = $filename; $this->params['folderid'] = '1000'; $this->params['itemprivacy'] = 'Public'; $this->params['itemdescription'] = $description; $this->params['itemname'] = $itemname; $resp = $this->_callJsonApi(); $this->_assertStatusOk($resp); $token = $resp->data->token; // don't know the itemid as it is generated, but can get it from the token $this->assertTrue(preg_match('/^' . $usersFile[0]->getKey() . '\\/(\\d+)\\/.+/', $token, $matches) > 0, 'Upload token (' . $token . ') is not of the form <userid>/<itemid>/*.*'); $generatedItemId = $matches[1]; $this->assertTrue(file_exists($this->getTempDirectory() . '/' . $token), 'Token placeholder file ' . $token . ' was not created in the temp dir'); // test that the item was created without any revisions $itemDao = $this->Item->load($generatedItemId); $revisions = $itemDao->getRevisions(); $this->assertEquals(count($revisions), 0, 'Wrong number of revisions in the new item'); // test that the properties of the item are as expected with parameters $this->assertEquals($itemDao->getName(), $itemname, 'Expected a different name for generated item'); $this->assertEquals($itemDao->getDescription(), $description, 'Expected a different description for generated item'); $this->assertEquals($itemDao->getPrivacyStatus(), MIDAS_PRIVACY_PRIVATE, 'Expected a different privacy_status for generated item'); // 17 // upload without passing a revision, this should create a revision 1 and // put the bitstream there $this->resetAll(); $this->params['method'] = 'midas.upload.perform'; $this->params['uploadtoken'] = $token; $this->params['filename'] = $filename; $this->params['length'] = $length; $this->params['testingmode'] = 'true'; $this->params['DBG'] = 'true'; $this->_callJsonApi(); // ensure that there is 1 revision with 1 bitstream $revisions = $itemDao->getRevisions(); $this->assertEquals(count($revisions), 1, 'Wrong number of revisions in the new item'); $bitstreams = $revisions[0]->getBitstreams(); $this->assertEquals(count($bitstreams), 1, 'Wrong number of bitstreams in the revision'); $this->assertEquals($bitstreams[0]->name, $filename); $this->assertEquals($bitstreams[0]->sizebytes, $length); $this->assertEquals($bitstreams[0]->checksum, $md5); // 18 // test uploading a file into an existing item with an existing revision, // but without passing the revision parameter, which should create a new // revision. $this->resetAll(); $this->params['token'] = $this->_loginAsNormalUser(); $this->params['method'] = 'midas.upload.generatetoken'; $this->params['filename'] = $filename; $this->params['itemid'] = $generatedItemId; $resp = $this->_callJsonApi(); $this->_assertStatusOk($resp); $token = $resp->data->token; // 19 $this->resetAll(); $this->params['method'] = 'midas.upload.perform'; $this->params['uploadtoken'] = $token; $this->params['filename'] = $filename; $this->params['length'] = $length; $this->params['testingmode'] = 'true'; $this->params['DBG'] = 'true'; $this->_callJsonApi(); // ensure that there are now 2 revisions with 1 bitstream each $revisions = $itemDao->getRevisions(); $this->assertEquals(count($revisions), 2, 'Wrong number of revisions in the new item'); $bitstreams = $revisions[0]->getBitstreams(); $this->assertEquals(count($bitstreams), 1, 'Wrong number of bitstreams in revision 1'); $this->assertEquals($bitstreams[0]->name, $filename); $this->assertEquals($bitstreams[0]->sizebytes, $length); $this->assertEquals($bitstreams[0]->checksum, $md5); $bitstreams = $revisions[1]->getBitstreams(); $this->assertEquals(count($bitstreams), 1, 'Wrong number of bitstreams in revision 2'); $this->assertEquals($bitstreams[0]->name, $filename); $this->assertEquals($bitstreams[0]->sizebytes, $length); $this->assertEquals($bitstreams[0]->checksum, $md5); // now to test upload a bitstream to a specific revision // create 2 new revisions on this item, 3 and 4, then add to the 3rd Zend_Loader::loadClass('ItemRevisionDao', BASE_PATH . '/core/models/dao'); $revision = new ItemRevisionDao(); $revision->setUser_id($usersFile[0]->getKey()); $revision->setChanges('revision 3'); $this->Item->addRevision($itemDao, $revision); $revision = new ItemRevisionDao(); $revision->setUser_id($usersFile[0]->getKey()); $revision->setChanges('revision 4'); $this->Item->addRevision($itemDao, $revision); $revisions = $itemDao->getRevisions(); $this->assertEquals(count($revisions), 4, 'Wrong number of revisions in the new item'); // 20 // test uploading a file into an existing item with an existing revision, // passing the revision parameter of 3, which should add to revision 3 // first generate the token $this->resetAll(); $this->params['token'] = $this->_loginAsNormalUser(); $this->params['method'] = 'midas.upload.generatetoken'; $this->params['filename'] = $filename; $this->params['itemid'] = $generatedItemId; $resp = $this->_callJsonApi(); $this->_assertStatusOk($resp); $token = $resp->data->token; // 21 // now upload to revision 3 $this->resetAll(); $this->params['method'] = 'midas.upload.perform'; $this->params['uploadtoken'] = $token; $this->params['filename'] = $filename; $this->params['length'] = $length; $this->params['revision'] = '3'; $this->params['testingmode'] = 'true'; $this->params['DBG'] = 'true'; $this->_callJsonApi(); // ensure that there are now 4 revisions, the first 3 having 1 bitstream and the last having 0 $revisions = $itemDao->getRevisions(); $this->assertEquals(count($revisions), 4, 'Wrong number of revisions in the new item'); $rev1 = $this->Item->getRevision($itemDao, '1'); $bitstreams = $rev1->getBitstreams(); $this->assertEquals(count($bitstreams), 1, 'Wrong number of bitstreams in revision 1'); $this->assertEquals($bitstreams[0]->name, $filename); $this->assertEquals($bitstreams[0]->sizebytes, $length); $this->assertEquals($bitstreams[0]->checksum, $md5); $rev2 = $this->Item->getRevision($itemDao, '2'); $bitstreams = $rev2->getBitstreams(); $this->assertEquals(count($bitstreams), 1, 'Wrong number of bitstreams in revision 2'); $this->assertEquals($bitstreams[0]->name, $filename); $this->assertEquals($bitstreams[0]->sizebytes, $length); $this->assertEquals($bitstreams[0]->checksum, $md5); $rev3 = $this->Item->getRevision($itemDao, '3'); $bitstreams = $rev3->getBitstreams(); $this->assertEquals(count($bitstreams), 1, 'Wrong number of bitstreams in revision 3'); $this->assertEquals($bitstreams[0]->name, $filename); $this->assertEquals($bitstreams[0]->sizebytes, $length); $this->assertEquals($bitstreams[0]->checksum, $md5); $rev4 = $this->Item->getRevision($itemDao, '4'); $bitstreams = $rev4->getBitstreams(); $this->assertEquals(count($bitstreams), 0, 'Wrong number of bitstreams in revision 4'); // delete the newly created item $this->Item->delete($itemDao); // 22 // test upload.generatetoken passing in folderid // when we generate an upload token for an item that will be created by // the upload.generatetoken method, // with a previously uploaded bitstream, and we are passing the checksum, // we expect that the item will create a new revision for the bitstream, // but pass back an empty upload token, since we have the bitstream content // already and do not need to actually upload it; also test passing in Public // explicitly $this->resetAll(); $this->params['token'] = $this->_loginAsNormalUser(); $this->params['method'] = 'midas.upload.generatetoken'; $this->params['filename'] = $filename; $this->params['checksum'] = $md5; $this->params['folderid'] = '1000'; $resp = $this->_callJsonApi(); $this->_assertStatusOk($resp); $token = $resp->data->token; $this->assertEquals($token, '', 'Redundant content upload did not return a blank token'); // this is hackish, since we aren't getting back the itemid for the // newly generated item, we know it will be the next id in the sequence // this at least allows us to test it $generatedItemId = $generatedItemId + 1; $itemDao = $this->Item->load($generatedItemId); $this->assertEquals($itemDao->getPrivacyStatus(), MIDAS_PRIVACY_PRIVATE, 'Expected a different privacy_status for generated item'); $revisions = $itemDao->getRevisions(); $this->assertEquals(count($revisions), 1, 'Wrong number of revisions in the item'); $bitstreams = $revisions[0]->getBitstreams(); $this->assertEquals(count($bitstreams), 1, 'Wrong number of bitstreams in the revision'); $this->assertEquals($bitstreams[0]->name, $filename); $this->assertEquals($bitstreams[0]->sizebytes, $length); $this->assertEquals($bitstreams[0]->checksum, $md5); // delete the newly created item $this->Item->delete($itemDao); unlink($this->getTempDirectory() . '/test.txt'); }
/** * Function to create the items. * * @param int $collectionId * @param int $parentFolderid */ private function _createFolderForItem($collectionId, $parentFolderid) { /** @var FolderModel $Folder */ $Folder = MidasLoader::loadModel('Folder'); /** @var ItemModel $Item */ $Item = MidasLoader::loadModel('Item'); /** @var ItemRevisionModel $ItemRevision */ $ItemRevision = MidasLoader::loadModel('ItemRevision'); /** @var GroupModel $Group */ $Group = MidasLoader::loadModel('Group'); /** @var AssetstoreModel $Assetstore */ $Assetstore = MidasLoader::loadModel('Assetstore'); /** @var FolderpolicygroupModel $Folderpolicygroup */ $Folderpolicygroup = MidasLoader::loadModel('Folderpolicygroup'); /** @var FolderpolicyuserModel $Folderpolicyuser */ $Folderpolicyuser = MidasLoader::loadModel('Folderpolicyuser'); /** @var ItempolicygroupModel $Itempolicygroup */ $Itempolicygroup = MidasLoader::loadModel('Itempolicygroup'); /** @var ItempolicyuserModel $Itempolicyuser */ $Itempolicyuser = MidasLoader::loadModel('Itempolicyuser'); /** @var UserModel $User */ $User = MidasLoader::loadModel('User'); $colquery = pg_query('SELECT i.item_id, mtitle.text_value AS title, mabstract.text_value AS abstract ' . 'FROM item AS i ' . 'LEFT JOIN metadatavalue AS mtitle ON (i.item_id = mtitle.item_id AND mtitle.metadata_field_id = 64) ' . 'LEFT JOIN metadatavalue AS mabstract ON (i.item_id = mabstract.item_id AND mabstract.metadata_field_id = 27) ' . 'WHERE i.owning_collection=' . $collectionId); while ($colquery_array = pg_fetch_array($colquery)) { $item_id = $colquery_array['item_id']; $title = $colquery_array['title']; // If title is empty we skip this item if (empty($title)) { continue; } $abstract = $colquery_array['abstract']; $folderDao = false; try { // Create the folder for the item $folderDao = $Folder->createFolder($title, $abstract, $parentFolderid); // Assign the policies to the folder as the same as the parent folder $folder = $Folder->load($parentFolderid); $policyGroup = $folder->getFolderpolicygroup(); $policyUser = $folder->getFolderpolicyuser(); foreach ($policyGroup as $policy) { $group = $policy->getGroup(); $policyValue = $policy->getPolicy(); $Folderpolicygroup->createPolicy($group, $folderDao, $policyValue); } foreach ($policyUser as $policy) { $user = $policy->getUser(); $policyValue = $policy->getPolicy(); $Folderpolicyuser->createPolicy($user, $folderDao, $policyValue); } // Add specific policies for users (not dealing with groups) $policyquery = pg_query('SELECT max(action_id) AS actionid, eperson.eperson_id, eperson.email FROM resourcepolicy LEFT JOIN eperson ON (eperson.eperson_id=resourcepolicy.eperson_id) WHERE epersongroup_id IS NULL AND resource_type_id=' . MIDAS2_RESOURCE_ITEM . ' AND resource_id=' . $item_id . ' GROUP BY eperson.eperson_id, email'); while ($policyquery_array = pg_fetch_array($policyquery)) { $actionid = $policyquery_array['actionid']; $email = $policyquery_array['email']; if ($actionid > 1) { $policyValue = MIDAS_POLICY_ADMIN; } elseif ($actionid == 1) { $policyValue = MIDAS_POLICY_WRITE; } else { $policyValue = MIDAS_POLICY_READ; } $userDao = $User->getByEmail($email); $Folderpolicyuser->createPolicy($userDao, $folderDao, $policyValue); } } catch (Zend_Exception $e) { $this->getLogger()->info($e->getMessage()); Zend_Debug::dump($e); // we continue } if ($folderDao) { // Create the item from the bitstreams $bitquery = pg_query('SELECT b.bitstream_id, b.name, b.description, b.internal_id FROM bitstream AS b, item2bitstream AS i2b ' . 'WHERE i2b.bitstream_id = b.bitstream_id AND i2b.item_id=' . $item_id); while ($bitquery_array = pg_fetch_array($bitquery)) { $filename = $bitquery_array['name']; $itemdao = new ItemDao(); $itemdao->setName($filename); // Get the number of downloads and set it $itemstatsquery = pg_query('SELECT downloads from midas_resourcelog WHERE resource_id_type=' . MIDAS2_RESOURCE_ITEM . ' AND resource_id=' . $item_id); $itemstats_array = pg_fetch_array($itemstatsquery); if ($itemstats_array) { $itemdao->setView($itemstats_array['downloads']); $itemdao->setDownload($itemstats_array['downloads']); } $Item->save($itemdao); // Just check if the group anonymous can access the item $policyquery = pg_query('SELECT policy_id FROM resourcepolicy WHERE resource_type_id=' . MIDAS2_RESOURCE_ITEM . ' AND resource_id=' . $item_id . ' AND epersongroup_id=0'); if (pg_num_rows($policyquery) > 0) { $anonymousGroup = $Group->load(MIDAS_GROUP_ANONYMOUS_KEY); $Itempolicygroup->createPolicy($anonymousGroup, $itemdao, MIDAS_POLICY_READ); } // Add specific policies for users $policyquery = pg_query('SELECT max(action_id) AS actionid, eperson.eperson_id, eperson.email FROM resourcepolicy LEFT JOIN eperson ON (eperson.eperson_id=resourcepolicy.eperson_id) WHERE epersongroup_id IS NULL AND resource_type_id=' . MIDAS2_RESOURCE_ITEM . ' AND resource_id=' . $item_id . ' GROUP BY eperson.eperson_id, email'); while ($policyquery_array = pg_fetch_array($policyquery)) { $actionid = $policyquery_array['actionid']; $email = $policyquery_array['email']; if ($actionid > 1) { $policyValue = MIDAS_POLICY_ADMIN; } elseif ($actionid == 1) { $policyValue = MIDAS_POLICY_WRITE; } else { $policyValue = MIDAS_POLICY_READ; } $userDao = $User->getByEmail($email); // Set the policy of the item $Itempolicyuser->createPolicy($userDao, $itemdao, $policyValue); } // Add the item to the current directory $Folder->addItem($folderDao, $itemdao); // Create a revision for the item $itemRevisionDao = new ItemRevisionDao(); $itemRevisionDao->setChanges('Initial revision'); $itemRevisionDao->setUser_id($this->userId); $Item->addRevision($itemdao, $itemRevisionDao); // Add the metadata /** @var MetadataModel $MetadataModel */ $MetadataModel = MidasLoader::loadModel('Metadata'); // $metadataquery = pg_query('SELECT metadata_field_id, text_value FROM metadatavalue WHERE item_id=' . $item_id); while ($metadata_array = pg_fetch_array($metadataquery)) { $text_value = $metadata_array['text_value']; $metadata_field_id = $metadata_array['metadata_field_id']; // Do not check 64 and 27 because they are stored as field and not metadata // in MIDAS3 switch ($metadata_field_id) { case 3: $element = 'contributor'; $qualifier = 'author'; break; case 11: $element = 'date'; $qualifier = 'uploaded'; break; case 14: $element = 'date'; $qualifier = 'created'; break; case 15: $element = 'date'; $qualifier = 'issued'; break; case 18: $element = 'identifier'; $qualifier = 'citation'; break; case 25: $element = 'identifier'; $qualifier = 'uri'; break; case 26: $element = 'description'; $qualifier = 'general'; break; case 28: $element = 'description'; $qualifier = 'provenance'; break; case 29: $element = 'description'; $qualifier = 'sponsorship'; break; case 39: $element = 'description'; $qualifier = 'publisher'; break; case 57: $element = 'subject'; $qualifier = 'keyword'; break; case 68: $element = 'subject'; $qualifier = 'ocis'; break; case 75: $element = 'identifier'; $qualifier = 'pubmed'; break; case 74: $element = 'identifier'; $qualifier = 'doi'; break; default: $element = ''; $qualifier = ''; } if ($element != '') { $MetadataModel->addMetadataValue($itemRevisionDao, MIDAS_METADATA_TEXT, $element, $qualifier, $text_value); } } // Add bitstreams to the revision $bitstreamDao = new BitstreamDao(); $bitstreamDao->setName($filename); // Compute the path from the internalid // We are assuming only one assetstore $internal_id = $bitquery_array['internal_id']; $filepath = $this->midas2Assetstore . '/'; $filepath .= substr($internal_id, 0, 2) . '/'; $filepath .= substr($internal_id, 2, 2) . '/'; $filepath .= substr($internal_id, 4, 2) . '/'; $filepath .= $internal_id; // Check that the file exists if (file_exists($filepath)) { // Upload the bitstream $assetstoreDao = $Assetstore->load($this->assetstoreId); $bitstreamDao->setPath($filepath); $bitstreamDao->fillPropertiesFromPath(); $bitstreamDao->setAssetstoreId($this->assetstoreId); $UploadComponent = new UploadComponent(); $UploadComponent->uploadBitstream($bitstreamDao, $assetstoreDao); // Upload the bitstream if necessary (based on the assetstore type) $ItemRevision->addBitstream($itemRevisionDao, $bitstreamDao); unset($UploadComponent); } } } else { echo 'Cannot create Folder for item: ' . $title . '<br>'; } } }
/** * Delete an itemrevision from an item, will reduce all other * itemrevision revision numbers appropriately. * * @param ItemDao $itemdao * @param ItemRevisionDao $revisiondao * @throws Zend_Exception */ public function removeRevision($itemdao, $revisiondao) { if (!$itemdao instanceof ItemDao) { throw new Zend_Exception('First argument should be an item'); } if (!$revisiondao instanceof ItemRevisionDao) { throw new Zend_Exception('Second argument should be an item revision'); } if ($revisiondao->getItemId() != $itemdao->getItemId()) { throw new Zend_Exception('Revision needs to be associated with Item'); } /** @var ItemRevisionModel $itemRevisionModel */ $itemRevisionModel = MidasLoader::loadModel('ItemRevision'); $lastRevisionDao = $this->getLastRevision($itemdao); $numRevisions = $lastRevisionDao->getRevision(); $deletedRevisionNum = $revisiondao->getRevision(); $itemRevisionModel->delete($revisiondao); // compact the revision numbers if necessary if ($deletedRevisionNum < $numRevisions) { // reach past the deleted revision, reduce each revision number by 1 $revisions = range($deletedRevisionNum + 1, $numRevisions); foreach ($revisions as $revision) { $itemRevisionDao = $this->getRevision($itemdao, $revision); $itemRevisionDao->setRevision($itemRevisionDao->getRevision() - 1); $itemRevisionModel->save($itemRevisionDao); } } // reload the item and last revision now that we have updated revisions $itemId = $itemdao->getItemId(); $itemdao = $this->load($itemId); $lastRevisionDao = $this->getLastRevision($itemdao); // now that we have deleted a revision, recalculate size of item if (empty($lastRevisionDao)) { $itemdao->setSizebytes(0); } else { $itemdao->setSizebytes($itemRevisionModel->getSize($lastRevisionDao)); } $this->save($itemdao, true); }
/** * Return a bitstream by name. * * @param ItemRevisionDao $revision * @param string $name * @return false|BitstreamDao */ public function getBitstreamByName($revision, $name) { $row = $this->database->fetchRow($this->database->select()->setIntegrityCheck(false)->from('bitstream')->where('itemrevision_id=?', $revision->getItemrevisionId())->where('name=?', $name)); return $this->initDao('Bitstream', $row); }
/** define an executable */ public function defineAction() { $itemId = $this->getParam('itemId'); if (!isset($itemId) || !is_numeric($itemId)) { throw new Zend_Exception('itemId should be a number'); } $isAjax = $this->getRequest()->isXmlHttpRequest(); $this->view->isAjax = $isAjax; if ($isAjax) { $this->disableLayout(); } $itemDao = $this->Item->load($itemId); if ($itemDao === false) { throw new Zend_Exception("This item doesn't exist."); } if (!$this->Item->policyCheck($itemDao, $this->userSession->Dao, MIDAS_POLICY_WRITE)) { throw new Zend_Exception('Problem policies.'); } $this->view->header = $this->t('Manage Configuration: ' . $itemDao->getName()); $metaFile = $this->ModuleComponent->Executable->getMetaIoFile($itemDao); if (isset($_GET['init'])) { $this->showNotificationMessage('Please set the option of the executable first.'); } $jsonContents = JsonComponent::encode(array()); if ($metaFile !== false) { $jsonContents = Zend_Json::fromXml(file_get_contents($metaFile->getFullPath()), true); } $this->view->itemDao = $itemDao; $this->view->jsonMetadata = $jsonContents; $this->view->json['item'] = $itemDao->toArray(); if ($this->_request->isPost()) { $this->disableLayout(); $this->disableView(); $results = $_POST['results']; $xmlContent = $this->ModuleComponent->Executable->createDefinitionFile($results); /** @var RandomComponent $randomComponent */ $randomComponent = MidasLoader::loadComponent('Random'); $pathFile = $this->getTempDirectory() . '/' . $randomComponent->generateString(32); file_put_contents($pathFile, $xmlContent); $revision = $this->Item->getLastRevision($itemDao); if ($revision === false) { throw new Zend_Exception('The item has no revisions', MIDAS_INVALID_POLICY); } $bitstreams = $revision->getBitstreams(); $itemRevisionDao = new ItemRevisionDao(); $itemRevisionDao->setChanges('Modification Definition File'); $itemRevisionDao->setUser_id($this->userSession->Dao->getKey()); $itemRevisionDao->setDate(date('Y-m-d H:i:s')); $itemRevisionDao->setLicenseId(null); $this->Item->addRevision($itemDao, $itemRevisionDao); foreach ($bitstreams as $b) { if ($b->getName() != 'MetaIO.vxml') { $b->saved = false; $b->setBitstreamId(null); $this->Bitstream->save($b); $this->ItemRevision->addBitstream($itemRevisionDao, $b); } } $bitstreamDao = new BitstreamDao(); $bitstreamDao->setName('MetaIO.vxml'); $bitstreamDao->setPath($pathFile); $bitstreamDao->fillPropertiesFromPath(); $assetstoreDao = $this->Assetstore->getDefault(); $bitstreamDao->setAssetstoreId($assetstoreDao->getKey()); // Upload the bitstream if necessary (based on the assetstore type) $this->Component->Upload->uploadBitstream($bitstreamDao, $assetstoreDao); $this->ItemRevision->addBitstream($itemRevisionDao, $bitstreamDao); if (file_exists($pathFile)) { unlink($pathFile); } } }