/**
  * Index action.
  *
  * @param folders = 12-13 (will download a zip of the folder 12 and 13, recursively)
  * @param folders = 12, 1-13, 1 (will download a zip of the folder 12 and 13, recursively) // Need testing
  * @param items = 12-13 (will download a zip containing the last revisions of the items 12 and 13)
  * @param items = 12, 1-13 (will download a zip containing the revision 1 of item 12 and last revision of item 13)
  * @param items = 12, 1 (will download the revision 1 of the item 12, a zip if there are multiple bitstream or simply the file)
  * @param bitstream = 1 (will download related bitstream)
  * @param offset The offset in bytes if downloading a bitstream (defaults to 0)
  * @param name Alternate filename when downloading a bitstream (defaults to bitstream name)
  * @throws Zend_Exception
  */
 public function indexAction()
 {
     $this->disableLayout();
     $itemIds = $this->getParam('items');
     $folderIds = $this->getParam('folders');
     $bitsreamid = $this->getParam('bitstream');
     $sessionUser = $this->userSession->Dao;
     $testingMode = Zend_Registry::get('configGlobal')->environment == 'testing';
     if ($sessionUser != null) {
         // Make sure this is a copy and not a reference
         $sessionUser = $this->User->load($sessionUser->getKey());
     } else {
         // see if module can authenticate with a special parameter
         $authToken = $this->getParam('authToken');
         if (isset($authToken)) {
             $responses = Zend_Registry::get('notifier')->callback('CALLBACK_CORE_PARAMETER_AUTHENTICATION', array('authToken' => $authToken));
             foreach ($responses as $user) {
                 $sessionUser = $user;
                 break;
             }
         }
     }
     $offset = $this->getParam('offset');
     if (!isset($offset)) {
         $offset = 0;
     }
     if (isset($bitsreamid) && is_numeric($bitsreamid)) {
         $name = $this->getParam('name');
         $bitstream = $this->Bitstream->load($bitsreamid);
         if (!$bitstream) {
             throw new Zend_Exception('Invalid bitstream id', 404);
         }
         if (isset($name)) {
             $bitstream->setName($name);
             // don't save name, just set it on this dao
         }
         $revision = $bitstream->getItemrevision();
         $item = $revision->getItem();
         if ($item == false || !$this->Item->policyCheck($item, $sessionUser)) {
             throw new Zend_Exception('Permission denied');
         }
         $this->Component->DownloadBitstream->download($bitstream, $offset, true);
         return;
     }
     if (!isset($itemIds) && !isset($folderIds)) {
         throw new Zend_Exception('No parameters, expecting itemIds or folderIds.');
     }
     $folderIds = explode('-', $folderIds);
     $folders = $this->Folder->load($folderIds);
     $item = null;
     $itemIds = explode('-', $itemIds);
     $revisions = array();
     if (!empty($itemIds)) {
         foreach ($itemIds as $itemId) {
             // check revision
             $tmp = explode(',', $itemId);
             if (empty($tmp[0])) {
                 continue;
             }
             $item = $this->Item->load($tmp[0]);
             if (!$item) {
                 throw new Zend_Exception('Item does not exist: ' . $tmp[0], 404);
             }
             if (!$this->Item->policyCheck($item, $sessionUser)) {
                 throw new Zend_Exception('Read permission required on item ' . $tmp[0], 403);
             }
             if (isset($tmp[1])) {
                 $tmp = $this->Item->getRevision($item, $tmp[1]);
                 if ($tmp !== false) {
                     $revisions[] = $tmp;
                 }
             } else {
                 $tmp = $this->Item->getLastRevision($item);
                 if ($tmp !== false) {
                     $revisions[] = $tmp;
                 }
             }
         }
     }
     if (empty($folders) && empty($revisions)) {
         // download an empty zip with the name of item (if it exists), then exit
         $this->_downloadEmptyItem($item);
     } elseif (empty($folders) && count($revisions) == 1) {
         $revision = $revisions[0];
         $bitstreams = $revision->getBitstreams();
         if ($testingMode) {
             $bitstreams = array($bitstreams[0]);
         }
         if (count($bitstreams) == 0) {
             // download an empty zip with the name of item (if it exists), then exit
             $this->Item->incrementDownloadCount($revision->getItem());
             $this->_downloadEmptyItem($revision->getItem());
         } elseif (count($bitstreams) == 1) {
             if (preg_match('/^https?:\\/\\//', $bitstreams[0]->getPath())) {
                 $this->redirect($bitstreams[0]->getPath());
                 return;
             }
             $this->disableView();
             $this->Component->DownloadBitstream->testingmode = $testingMode;
             $this->Component->DownloadBitstream->download($bitstreams[0], $offset, true);
         } else {
             ob_start();
             $this->_helper->viewRenderer->setNoRender();
             $name = $revision->getItem()->getName();
             $name = substr($name, 0, 50);
             session_write_close();
             // unlock session writing for concurrent access
             $zip = new \ZipStream\ZipStream($name . '.zip');
             foreach ($bitstreams as $bitstream) {
                 $filename = $bitstream->getName();
                 $path = $bitstream->getAssetstore()->getPath() . '/' . $bitstream->getPath();
                 Zend_Registry::get('dbAdapter')->closeConnection();
                 $zip->addFileFromPath($filename, $path);
             }
             $zip->finish();
             $this->Item->incrementDownloadCount($revision->getItem());
             exit;
         }
     } else {
         $this->_helper->viewRenderer->setNoRender();
         if (count($folders) == 1 && empty($revisions)) {
             $name = $folders[0]->getName();
             $name = substr($name, 0, 50);
             $rootFolder = $this->Folder->getRoot($folders[0]);
             if ($rootFolder) {
                 // Find the Community or the User which have the folder
                 $rootCom = $this->Community->getByFolder($rootFolder);
                 if (!$rootCom) {
                     $user = $this->User->getByFolder($rootFolder);
                     $name = $user->getFirstname() . $user->getLastname() . '-' . $name;
                 } else {
                     $name = $rootCom->getName() . '-' . $name;
                 }
             }
         } else {
             $name = 'Custom';
         }
         session_write_close();
         // unlock session writing for concurrent access
         ob_start();
         $zip = new \ZipStream\ZipStream($name . '.zip');
         UtilityComponent::disableMemoryLimit();
         foreach ($revisions as $revision) {
             $item = $revision->getItem();
             $bitstreams = $revision->getBitstreams();
             $count = count($bitstreams);
             foreach ($bitstreams as $bitstream) {
                 if ($count > 1 || $bitstream->getName() != $item->getName()) {
                     $path = $item->getName() . '/';
                 } else {
                     $path = '';
                 }
                 $filename = $path . $bitstream->getName();
                 $fullpath = $bitstream->getAssetstore()->getPath() . '/' . $bitstream->getPath();
                 Zend_Registry::get('dbAdapter')->closeConnection();
                 $zip->addFileFromPath($filename, $fullpath);
             }
             $this->Item->incrementDownloadCount($item);
             unset($item);
             unset($bitstreams);
         }
         foreach ($folders as $folder) {
             if (!$this->Folder->policyCheck($folder, $sessionUser)) {
                 continue;
             }
             $this->Folder->zipStream($zip, $folder->getName(), $folder, $sessionUser);
         }
         $zip->finish();
         exit;
     }
 }
 /**
  * Delete a set of folders and items. Called by ajax from common.browser.js.
  *
  * @param folders A list of folder ids separated by '-'
  * @param items A list of item ids separated by '-'
  * @return Replies with a json object of the form:
  *                 {success: {folders: [<id>, <id>, ...], items: [<id>, <id>, ...]},
  *                 failure: {folders: [<id>, <id>, ...], items: [<id>, <id>, ...]}}
  *                 Denoting which deletes succeeded and which failed.  Invalid ids will be considered
  *                 already deleted and are thus returned as successful.
  */
 public function deleteAction()
 {
     if (!$this->logged) {
         throw new Zend_Exception('You must be logged in to delete resources.');
     }
     UtilityComponent::disableMemoryLimit();
     $this->disableLayout();
     $this->_helper->viewRenderer->setNoRender();
     $folderIds = $this->getParam('folders');
     $itemIds = $this->getParam('items');
     $resp = array('success' => array('folders' => array(), 'items' => array()), 'failure' => array('folders' => array(), 'items' => array()));
     $folderIds = explode('-', $folderIds);
     $itemIds = explode('-', $itemIds);
     foreach ($folderIds as $folderId) {
         if ($folderId == '') {
             continue;
         }
         $folder = $this->Folder->load($folderId);
         if (!$folder) {
             $resp['success']['folders'][] = $folderId;
             // probably deleted by a parent delete
             continue;
         }
         if ($this->Folder->policyCheck($folder, $this->userSession->Dao, MIDAS_POLICY_ADMIN) && $this->Folder->isDeleteable($folder)) {
             $this->Folder->delete($folder);
             $resp['success']['folders'][] = $folderId;
         } else {
             $resp['failure']['folders'][] = $folderId;
             // permission failure
         }
     }
     foreach ($itemIds as $itemId) {
         if ($itemId == '') {
             continue;
         }
         $item = $this->Item->load($itemId);
         if (!$item) {
             $resp['success']['items'][] = $itemId;
             // probably deleted by a parent delete
             continue;
         }
         if ($this->Item->policyCheck($item, $this->userSession->Dao, MIDAS_POLICY_ADMIN)) {
             $this->Item->delete($item);
             $resp['success']['items'][] = $itemId;
         } else {
             $resp['failure']['items'][] = $itemId;
             // permission failure
         }
     }
     echo JsonComponent::encode($resp);
 }
 /** delete a folder (ajax action)*/
 public function deleteAction()
 {
     $this->disableLayout();
     $this->disableView();
     $folder_id = $this->getParam('folderId');
     $folder = $this->Folder->load($folder_id);
     if (!isset($folder_id)) {
         throw new Zend_Exception('Please set the folderId.');
     } elseif ($folder === false) {
         throw new Zend_Exception("The folder doesn't exist.");
     } elseif (!$this->Folder->policyCheck($folder, $this->userSession->Dao, MIDAS_POLICY_ADMIN)) {
         throw new Zend_Exception('Permissions error.');
     }
     // User cannot delete community's root folder, the default 'Public' folder and the default 'Private' folder
     if ($this->Folder->getCommunity($folder) != false) {
         throw new Zend_Exception('Community Root Folder. You cannot delete it.');
     }
     // User cannot delete its root folder, the default 'Public' folder and the default 'Private' folder
     if ($this->Folder->getUser($folder) != false) {
         throw new Zend_Exception('User Root Folder. You cannot delete it.');
     }
     if ($this->progressDao) {
         $this->progressDao->setMaximum($this->Folder->getRecursiveChildCount($folder) + 1);
         $this->progressDao->setMessage('Preparing to delete folder...');
         $this->Progress->save($this->progressDao);
     }
     UtilityComponent::disableMemoryLimit();
     $this->Folder->delete($folder, $this->progressDao);
     $folderInfo = $folder->toArray();
     echo JsonComponent::encode(array(true, $this->t('Changes saved'), $folderInfo));
 }
 /**
  * Download key files for a selected group of folders and/or items.
  * @param items List of item id's separated by -
  * @param folders List of folder id's separated by -
  */
 public function batchAction()
 {
     UtilityComponent::disableMemoryLimit();
     $itemIds = $this->getParam('items');
     $folderIds = $this->getParam('folders');
     if (!isset($itemIds) && !isset($folderIds)) {
         throw new Zend_Exception('No parameters');
     }
     $this->disableLayout();
     $this->disableView();
     $folderIds = explode('-', $folderIds);
     $folders = $this->Folder->load($folderIds);
     $itemIds = explode('-', $itemIds);
     $items = $this->Item->load($itemIds);
     if (headers_sent()) {
         return;
         // can't do anything if headers sent already
     }
     $this->_emptyOutputBuffer();
     ob_start();
     //must start a new output buffer for ZipStream to work
     $zip = new \ZipStream\ZipStream('Keyfiles.zip');
     // Iterate over top level items
     foreach ($items as $item) {
         if (!$this->Item->policyCheck($item, $this->userSession->Dao)) {
             $this->getLogger()->warn('Keyfiles: Permission failure, skipping item ' . $item->getKey());
             continue;
         }
         $revision = $this->Item->getLastRevision($item);
         if (!$revision) {
             continue;
         }
         $bitstreams = $revision->getBitstreams();
         $count = count($bitstreams);
         foreach ($bitstreams as $bitstream) {
             if ($count > 1 || $bitstream->getName() != $item->getName()) {
                 $path = $item->getName() . '/';
             } else {
                 $path = '';
             }
             $filename = $path . $bitstream->getName() . '.md5';
             Zend_Registry::get('dbAdapter')->closeConnection();
             $zip->addFile($filename, $bitstream->getChecksum());
         }
         $this->Item->incrementDownloadCount($item);
         unset($item);
         unset($revision);
         unset($bitstreams);
     }
     // Iterate over top level folders, stream them out recursively using FolderModel::zipStream()
     foreach ($folders as $folder) {
         if (!$this->Folder->policyCheck($folder, $this->userSession->Dao)) {
             $this->getLogger()->warn('Keyfiles: Permission failure, skipping folder ' . $folder->getKey());
             continue;
         }
         $callable = array($this, 'outputCallback');
         $this->Folder->zipStream($zip, $folder->getName(), $folder, $this->userSession->Dao, $callable);
     }
     $zip->finish();
     exit;
 }