/**
  * Update a progress record. Touches its update timestamp and sets its value.
  *
  * @param ProgressDao $progressDao progress record to update
  * @param int $currentValue current value of the progress
  * @param string $message progress message
  */
 public function updateProgress($progressDao, $currentValue, $message = '')
 {
     $progressDao->setCurrent((int) $currentValue);
     $progressDao->setMessage($message);
     $progressDao->setLastUpdate(date('Y-m-d H:i:s'));
     $this->save($progressDao);
 }
 /**
  * Remove all orphaned item revision records.
  *
  * @param null|ProgressDao $progressDao
  */
 public function removeOrphans($progressDao = null)
 {
     if ($progressDao) {
         $max = $this->countOrphans();
         $progressDao->setMaximum($max);
         $progressDao->setMessage('Removing orphaned bitstreams (0/' . $max . ')');
         $this->Progress = MidasLoader::loadModel('Progress');
         $this->Progress->save($progressDao);
     }
     $sql = $this->database->select()->setIntegrityCheck(false)->from(array('b' => 'bitstream'), array('bitstream_id'))->where('b.itemrevision_id > ?', 0)->where('(NOT b.itemrevision_id IN (' . new Zend_Db_Expr($this->database->select()->setIntegrityCheck(false)->from(array('subr' => 'itemrevision'), array('itemrevision_id')) . '))'));
     $rowset = $this->database->fetchAll($sql);
     $ids = array();
     foreach ($rowset as $row) {
         $ids[] = $row['bitstream_id'];
     }
     $itr = 0;
     foreach ($ids as $id) {
         if ($progressDao) {
             ++$itr;
             $message = 'Removing orphaned bitstreams (' . $itr . '/' . $max . ')';
             $this->Progress->updateProgress($progressDao, $itr, $message);
         }
         $bitstream = $this->load($id);
         if (!$bitstream) {
             continue;
         }
         $this->getLogger()->info('Deleting orphaned bitstream ' . $bitstream->getName() . ' [revision id=' . $bitstream->getItemrevisionId() . ']');
         $this->delete($bitstream);
     }
 }
 /**
  * Copy the permissions from the given folder to all child folders and items. Do not pass a results
  * parameter, that is for the recursive counting.
  *
  * @param FolderDao $folder folder DAO
  * @param UserDao $user user DAO
  * @param null|ProgressDao $progress progress DAO
  * @param array $results
  * @return array array('success' => number of resources whose policies were successfully changed,
  *                     'failure' => number of resources failed to change due to invalid permissions
  */
 public function applyPoliciesRecursive($folder, $user, $progress = null, $results = array('success' => 0, 'failure' => 0))
 {
     foreach ($folder->getFolders() as $subfolder) {
         if ($progress) {
             $current = $progress->getCurrent() + 1;
             $message = 'Set policies on ' . $current . ' of ' . $progress->getMaximum() . ' resources';
             $this->Progress->updateProgress($progress, $current, $message);
         }
         if (!$this->Folder->policyCheck($subfolder, $user, MIDAS_POLICY_ADMIN)) {
             ++$results['failure'];
             continue;
         }
         // delete all existing policies on the subfolder
         foreach ($subfolder->getFolderpolicygroup() as $folderPolicyGroup) {
             $this->Folderpolicygroup->delete($folderPolicyGroup);
         }
         foreach ($subfolder->getFolderpolicyuser() as $folderPolicyUser) {
             $this->Folderpolicyuser->delete($folderPolicyUser);
         }
         // copy down policies from parent folder
         foreach ($folder->getFolderpolicygroup() as $folderPolicyGroup) {
             $this->Folderpolicygroup->createPolicy($folderPolicyGroup->getGroup(), $subfolder, $folderPolicyGroup->getPolicy());
         }
         foreach ($folder->getFolderpolicyuser() as $folderPolicyUser) {
             $this->Folderpolicyuser->createPolicy($folderPolicyUser->getUser(), $subfolder, $folderPolicyUser->getPolicy());
         }
         ++$results['success'];
         $results = $this->applyPoliciesRecursive($subfolder, $user, $progress, $results);
     }
     foreach ($folder->getItems() as $item) {
         if ($progress) {
             $current = $progress->getCurrent() + 1;
             $message = 'Set policies on ' . $current . ' of ' . $progress->getMaximum() . ' resources';
             $this->Progress->updateProgress($progress, $current, $message);
         }
         if (!$this->Item->policyCheck($item, $user, MIDAS_POLICY_ADMIN)) {
             ++$results['failure'];
             continue;
         }
         // delete all existing policies on the item
         foreach ($item->getItempolicygroup() as $itemPolicyGroup) {
             $this->Itempolicygroup->delete($itemPolicyGroup);
         }
         foreach ($item->getItempolicyuser() as $itemPolicyUser) {
             $this->Itempolicyuser->delete($itemPolicyUser);
         }
         // copy down policies from parent folder
         foreach ($folder->getFolderpolicygroup() as $folderPolicyGroup) {
             $this->Itempolicygroup->createPolicy($folderPolicyGroup->getGroup(), $item, $folderPolicyGroup->getPolicy());
         }
         foreach ($folder->getFolderpolicyuser() as $folderPolicyUser) {
             $this->Itempolicyuser->createPolicy($folderPolicyUser->getUser(), $item, $folderPolicyUser->getPolicy());
         }
         ++$results['success'];
     }
     return $results;
 }
 /**
  * Move all bitstreams from one asset store to another.
  *
  * @param AssetstoreDao $srcAssetstore The source asset store
  * @param AssetstoreDao $dstAssetstore The destination asset store
  * @param null|ProgressDao $progressDao Progress dao for asynchronous updating
  * @throws Zend_Exception
  */
 public function moveBitstreams($srcAssetstore, $dstAssetstore, $progressDao = null)
 {
     $current = 0;
     /** @var ProgressModel $progressModel */
     $progressModel = MidasLoader::loadModel('Progress');
     /** @var BitstreamModel $bitstreamModel */
     $bitstreamModel = MidasLoader::loadModel('Bitstream');
     $sql = $this->database->select()->setIntegrityCheck(false)->from('bitstream')->where('assetstore_id = ?', $srcAssetstore->getKey());
     $rows = $this->database->fetchAll($sql);
     $srcPath = $srcAssetstore->getPath();
     $dstPath = $dstAssetstore->getPath();
     foreach ($rows as $row) {
         $bitstream = $this->initDao('Bitstream', $row);
         if ($progressDao) {
             ++$current;
             $message = $current . ' / ' . $progressDao->getMaximum() . ': Moving ' . $bitstream->getName() . ' (' . UtilityComponent::formatSize($bitstream->getSizebytes()) . ')';
             $progressModel->updateProgress($progressDao, $current, $message);
         }
         // Move the file on disk to its new location
         $dir1 = substr($bitstream->getChecksum(), 0, 2);
         $dir2 = substr($bitstream->getChecksum(), 2, 2);
         if (!is_dir($dstPath . '/' . $dir1)) {
             if (!mkdir($dstPath . '/' . $dir1)) {
                 throw new Zend_Exception('Failed to mkdir ' . $dstPath . '/' . $dir1);
             }
         }
         if (!is_dir($dstPath . '/' . $dir1 . '/' . $dir2)) {
             if (!mkdir($dstPath . '/' . $dir1 . '/' . $dir2)) {
                 throw new Zend_Exception('Failed to mkdir ' . $dstPath . '/' . $dir1 . '/' . $dir2);
             }
         }
         if (is_file($dstPath . '/' . $bitstream->getPath())) {
             if (is_file($srcPath . '/' . $bitstream->getPath())) {
                 unlink($srcPath . '/' . $bitstream->getPath());
             }
         } else {
             if (!rename($srcPath . '/' . $bitstream->getPath(), $dstPath . '/' . $bitstream->getPath())) {
                 throw new Zend_Exception('Error moving ' . $bitstream->getPath());
             }
         }
         // Update the asset store id on the bitstream record once it has been moved
         $bitstream->setAssetstoreId($dstAssetstore->getKey());
         $bitstreamModel->save($bitstream);
     }
 }