Example #1
0
 /**
  * Merge all chunks to single file
  *
  * @param string $destination final file location
  *
  *
  * @throws FileLockException
  * @throws FileOpenException
  * @throws \Exception
  *
  * @return bool indicates if file was saved
  */
 public function save($destination)
 {
     $fh = fopen($destination, 'wb');
     if (!$fh) {
         throw new FileOpenException('failed to open destination file: ' . $destination);
     }
     if (!flock($fh, LOCK_EX | LOCK_NB, $blocked)) {
         // @codeCoverageIgnoreStart
         if ($blocked) {
             // Concurrent request has requested a lock.
             // File is being processed at the moment.
             // Warning: lock is not checked in windows.
             return false;
         }
         // @codeCoverageIgnoreEnd
         throw new FileLockException('failed to lock file: ' . $destination);
     }
     $totalChunks = $this->request->getTotalChunks();
     try {
         $preProcessChunk = $this->config->getPreprocessCallback();
         for ($i = 1; $i <= $totalChunks; $i++) {
             $file = $this->getChunkPath($i);
             $chunk = fopen($file, "rb");
             if (!$chunk) {
                 throw new FileOpenException('failed to open chunk: ' . $file);
             }
             if ($preProcessChunk !== null) {
                 call_user_func($preProcessChunk, $chunk);
             }
             stream_copy_to_stream($chunk, $fh);
             fclose($chunk);
         }
     } catch (\Exception $e) {
         flock($fh, LOCK_UN);
         fclose($fh);
         throw $e;
     }
     if ($this->config->getDeleteChunksOnSave()) {
         $this->deleteChunks();
     }
     flock($fh, LOCK_UN);
     fclose($fh);
     return true;
 }