Skip to content
Browse files

Refactored Zend/File/Transfer/Adapter/Http upload progress methods in…

…to Zend/Progressbar/Upload/UploadHandlers
  • Loading branch information...
1 parent a68d5b2 commit 81d634b0970fe21c3253a8cbbc4dd4e29fb60525 @cgmartin committed Oct 4, 2012
View
18 library/Zend/ProgressBar/Exception/PhpEnvironmentException.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @package Zend_ProgressBar
+ */
+
+namespace Zend\ProgressBar\Exception;
+
+/**
+ * @category Zend
+ * @package Zend_ProgressBar
+ */
+class PhpEnvironmentException extends RuntimeException
+{}
View
185 library/Zend/ProgressBar/Upload/AbstractUploadHandler.php
@@ -0,0 +1,185 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @package Zend_ProgressBar
+ */
+
+namespace Zend\ProgressBar\Upload;
+
+use Traversable;
+use Zend\ProgressBar\Adapter\AbstractAdapter as AbstractProgressAdapter;
+use Zend\ProgressBar\Exception;
+use Zend\ProgressBar\ProgressBar;
+use Zend\Stdlib\ArrayUtils;
+
+/**
+ * Abstract class for Upload Progress Handlers
+ *
+ * @category Zend
+ * @package Zend_ProgressBar
+ */
+abstract class AbstractUploadHandler implements UploadHandlerInterface
+{
+ /**
+ * @var string
+ */
+ protected $sessionNamespace = 'Zend\ProgressBar\Upload\AbstractUploadHandler';
+
+ /**
+ * @var AbstractProgressAdapter|ProgressBar
+ */
+ protected $progressAdapter;
+
+ /**
+ * @param array|\Traversable $options Optional options
+ * @throws Exception\InvalidArgumentException
+ */
+ public function __construct($options = array())
+ {
+ if (!empty($options)) {
+ $this->setOptions($options);
+ }
+ }
+
+ /**
+ * Set options for a upload handler. Accepted options are:
+ * - session_namespace: session namespace for upload progress
+ * - progress_adapter: progressbar adapter to use for updating progress
+ *
+ * @param array|\Traversable $options
+ * @return AbstractUploadHandler
+ * @throws Exception\InvalidArgumentException
+ */
+ public function setOptions($options)
+ {
+ if ($options instanceof Traversable) {
+ $options = ArrayUtils::iteratorToArray($options);
+ } elseif (!is_array($options)) {
+ throw new Exception\InvalidArgumentException(
+ 'The options parameter must be an array or a Traversable'
+ );
+ }
+
+ if (isset($options['session_namespace'])) {
+ $this->setSessionNamespace($options['session_namespace']);
+ }
+ if (isset($options['progress_adapter'])) {
+ $this->setProgressAdapter($options['progress_adapter']);
+ }
+
+ return $this;
+ }
+
+ /**
+ * @param string $sessionNamespace
+ * @return AbstractUploadHandler|UploadHandlerInterface
+ */
+ public function setSessionNamespace($sessionNamespace)
+ {
+ $this->sessionNamespace = $sessionNamespace;
+ return $this;
+ }
+
+ /**
+ * @return string
+ */
+ public function getSessionNamespace()
+ {
+ return $this->sessionNamespace;
+ }
+
+ /**
+ * @param AbstractProgressAdapter|ProgressBar $progressAdapter
+ * @return AbstractUploadHandler|UploadHandlerInterface
+ */
+ public function setProgressAdapter($progressAdapter)
+ {
+ $this->progressAdapter = $progressAdapter;
+ return $this;
+ }
+
+ /**
+ * @return AbstractProgressAdapter|ProgressBar
+ */
+ public function getProgressAdapter()
+ {
+ return $this->progressAdapter;
+ }
+
+ /**
+ * @param string $id
+ * @return array
+ */
+ public function getProgress($id)
+ {
+ $status = array(
+ 'total' => 0,
+ 'current' => 0,
+ 'rate' => 0,
+ 'message' => 'No upload in progress',
+ 'done' => true
+ );
+ if (empty($id)) {
+ return $status;
+ }
+
+ $newStatus = $this->getUploadProgress($id);
+ if (false === $newStatus) {
+ return $status;
+ }
+ $status = $newStatus;
+ if (!empty($status['done'])) {
+ $status['message'] = $this->toByteString($status['current']) .
+ " - " . $this->toByteString($status['total']);
+ }
+ $status['id'] = $id;
+
+ $adapter = $this->getProgressAdapter();
+ if (isset($adapter)) {
+ if ($adapter instanceof AbstractProgressAdapter) {
+ $adapter = new ProgressBar(
+ $adapter, 0, $status['total'], $this->getSessionNamespace()
+ );
+ $this->setProgressAdapter($adapter);
+ }
+
+ if (!$adapter instanceof ProgressBar) {
+ throw new Exception\RuntimeException('Unknown Adapter type given');
+ }
+
+ if ($status['done']) {
+ $adapter->finish();
+ } else {
+ $adapter->update($status['current'], $status['message']);
+ }
+ }
+
+ return $status;
+ }
+
+ /**
+ * @param string $id
+ * @return array|boolean
+ */
+ abstract protected function getUploadProgress($id);
+
+ /**
+ * Returns the formatted size
+ *
+ * @param integer $size
+ * @return string
+ */
+ protected function toByteString($size)
+ {
+ $sizes = array('B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
+ for ($i=0; $size >= 1024 && $i < 9; $i++) {
+ $size /= 1024;
+ }
+
+ return round($size, 2) . $sizes[$i];
+ }
+}
View
68 library/Zend/ProgressBar/Upload/ApcProgress.php
@@ -0,0 +1,68 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @package Zend_ProgressBar
+ */
+
+namespace Zend\ProgressBar\Upload;
+
+use Traversable;
+use Zend\ProgressBar\Exception;
+use Zend\Stdlib\ArrayUtils;
+
+/**
+ * Progress Bar Upload Handler for the APC extension
+ *
+ * @category Zend
+ * @package Zend_ProgressBar
+ */
+class ApcProgress extends AbstractUploadHandler
+{
+ /**
+ * @param string $id
+ * @return array|boolean
+ * @throws Exception\PhpEnvironmentException
+ */
+ protected function getUploadProgress($id)
+ {
+ if (!$this->isApcAvailable()) {
+ throw new Exception\PhpEnvironmentException('APC extension is not installed');
+ }
+
+ $uploadInfo = apc_fetch(ini_get('apc.rfc1867_prefix') . $id);
+ if (!is_array($uploadInfo)) {
+ return false;
+ }
+
+ $status = array(
+ 'total' => 0,
+ 'current' => 0,
+ 'rate' => 0,
+ 'message' => '',
+ 'done' => false
+ );
+ $status = $uploadInfo + $status;
+ if (!empty($status['cancel_upload'])) {
+ $status['done'] = true;
+ $status['message'] = 'The upload has been canceled';
+ }
+
+ return $status;
+ }
+
+ /**
+ * Checks for the APC extension
+ *
+ * @return boolean
+ */
+ public function isApcAvailable()
+ {
+ return (bool) ini_get('apc.enabled')
+ && (bool) ini_get('apc.rfc1867')
+ && is_callable('apc_fetch');
+ }
+}
View
72 library/Zend/ProgressBar/Upload/SessionProgress.php
@@ -0,0 +1,72 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @package Zend_ProgressBar
+ */
+
+namespace Zend\ProgressBar\Upload;
+
+use Traversable;
+use Zend\ProgressBar\Exception;
+use Zend\Stdlib\ArrayUtils;
+
+/**
+ * Progress Bar Upload Handler for PHP 5.4+ Session Upload Progress handling
+ *
+ * @category Zend
+ * @package Zend_ProgressBar
+ */
+class SessionProgress extends AbstractUploadHandler
+{
+ /**
+ * @param string $id
+ * @return array|boolean
+ * @throws Exception\PhpEnvironmentException
+ */
+ protected function getUploadProgress($id)
+ {
+ if (!$this->isSessionUploadProgressAvailable()) {
+ throw new Exception\PhpEnvironmentException(
+ 'Session Upload Progress is not available'
+ );
+ }
+
+ $uploadInfo = $_SESSION[ini_get('session.upload_progress.prefix') . $id];
+ if (!is_array($uploadInfo)) {
+ return false;
+ }
+
+ $status = array(
+ 'total' => 0,
+ 'current' => 0,
+ 'rate' => 0,
+ 'message' => '',
+ 'done' => false
+ );
+ $status = $uploadInfo + $status;
+ $status['total'] = $status['content_length'];
+ $status['current'] = $status['bytes_processed'];
+ $status['rate'] = $status['bytes_processed'] / (time() - $status['start_time']);
+ if (!empty($status['cancel_upload'])) {
+ $status['done'] = true;
+ $status['message'] = 'The upload has been canceled';
+ }
+
+ return $status;
+ }
+
+ /**
+ * Checks if Session Upload Progress is available
+ *
+ * @return boolean
+ */
+ public function isSessionUploadProgressAvailable()
+ {
+ return (bool) version_compare(PHP_VERSION, '5.4.0rc1', '>=')
+ && (bool) ini_get('session.upload_progress.enabled');
+ }
+}
View
29 library/Zend/ProgressBar/Upload/UploadHandlerInterface.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @package Zend_ProgressBar
+ */
+
+namespace Zend\ProgressBar\Upload;
+
+use Traversable;
+use Zend\Stdlib\ArrayUtils;
+
+/**
+ * Interface for Upload Progress Handlers
+ *
+ * @category Zend
+ * @package Zend_ProgressBar
+ */
+interface UploadHandlerInterface
+{
+ /**
+ * @param string $id
+ * @return array
+ */
+ public function getProgress($id);
+}
View
70 library/Zend/ProgressBar/Upload/UploadProgress.php
@@ -0,0 +1,70 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @package Zend_ProgressBar
+ */
+
+namespace Zend\ProgressBar\Upload;
+
+use Traversable;
+use Zend\ProgressBar\Exception;
+use Zend\Stdlib\ArrayUtils;
+
+/**
+ * Progress Bar Upload Handler for the UploadProgress extension
+ *
+ * @category Zend
+ * @package Zend_ProgressBar
+ */
+class UploadProgress extends AbstractUploadHandler
+{
+ /**
+ * @param string $id
+ * @return array|boolean
+ * @throws Exception\PhpEnvironmentException
+ */
+ protected function getUploadProgress($id)
+ {
+ if (!$this->isUploadProgressAvailable()) {
+ throw new Exception\PhpEnvironmentException(
+ 'UploadProgress extension is not installed'
+ );
+ }
+
+ $uploadInfo = uploadprogress_get_info($id);
+ if (!is_array($uploadInfo)) {
+ return false;
+ }
+
+ $status = array(
+ 'total' => 0,
+ 'current' => 0,
+ 'rate' => 0,
+ 'message' => '',
+ 'done' => false
+ );
+ $status = $uploadInfo + $status;
+ $status['total'] = $status['bytes_total'];
+ $status['current'] = $status['bytes_uploaded'];
+ $status['rate'] = $status['speed_average'];
+ if ($status['total'] == $status['current']) {
+ $status['done'] = true;
+ }
+
+ return $status;
+ }
+
+ /**
+ * Checks for the UploadProgress extension
+ *
+ * @return boolean
+ */
+ public function isUploadProgressAvailable()
+ {
+ return is_callable('uploadprogress_get_info');
+ }
+}
View
2 tests/ZendTest/Filter/File/RenameUploadTest.php
@@ -18,7 +18,7 @@
* @subpackage UnitTests
* @group Zend_Filter
*/
-class RenameTest extends \PHPUnit_Framework_TestCase
+class RenameUploadTest extends \PHPUnit_Framework_TestCase
{
/**
* Path to test files

0 comments on commit 81d634b

Please sign in to comment.
Something went wrong with that request. Please try again.