-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' of git://github.com/esvit/bazalt-rest
- Loading branch information
Showing
5 changed files
with
268 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
<?php | ||
|
||
namespace Bazalt\Rest; | ||
|
||
define('DEFAULT_MAX_SIZE', 10485760); | ||
|
||
class Uploader | ||
{ | ||
private $allowedExtensions = array(); | ||
|
||
private $sizeLimit = DEFAULT_MAX_SIZE; | ||
|
||
public function __construct(array $allowedExtensions = array(), $sizeLimit = DEFAULT_MAX_SIZE) | ||
{ | ||
$allowedExtensions = array_map("strtolower", $allowedExtensions); | ||
|
||
$this->allowedExtensions = $allowedExtensions; | ||
$this->sizeLimit = $sizeLimit; | ||
} | ||
|
||
/** | ||
* Returns array('success'=>true) or array('error'=>'error message') | ||
*/ | ||
public function handleUpload($uploadDirectory, $pathParams = array()) | ||
{ | ||
if (!is_writable($uploadDirectory)) { | ||
throw new \Exception("Server error. Upload directory isn't writable."); | ||
} | ||
|
||
$size = $this->getFileSize(); | ||
if ($size == 0) { | ||
throw new \Exception('File is empty.'); | ||
} | ||
if ($size > $this->sizeLimit) { | ||
throw new \Exception('File is too large.'); | ||
} | ||
|
||
$ext = $this->getExt(); | ||
if ($this->allowedExtensions && !in_array(strtolower($ext), $this->allowedExtensions)) { | ||
$these = implode(', ', $this->allowedExtensions); | ||
throw new \Exception(sprintf('File has an invalid extension, it should be one of "%s"', $these)); | ||
} | ||
|
||
|
||
if ($_FILES['file']['error'] !== UPLOAD_ERR_OK) { | ||
throw new UploaderException($_FILES['file']['error']); | ||
} | ||
|
||
$fileName = md5(uniqid()) . '.' . $ext; | ||
$filePath = $this->getSavePath($fileName, $pathParams); | ||
$fullName = $uploadDirectory . $filePath . $fileName; | ||
mkdir(dirname($uploadDirectory . $filePath), 0777, true); | ||
|
||
$this->moveUploadedFile($_FILES['file']['tmp_name'], $fullName); | ||
|
||
return $filePath . $fileName; | ||
} | ||
|
||
public function moveUploadedFile($src, $dst) | ||
{ | ||
if (!move_uploaded_file($src, $dst)) { | ||
throw new \Exception('Cannot move file'); | ||
} | ||
} | ||
|
||
protected function getSavePath($filename, $pathParams) | ||
{ | ||
$name = '/'; | ||
if (count($pathParams) > 0) { | ||
$name .= implode('/', $pathParams); | ||
} | ||
$name = rtrim($name, '/') . '/'; | ||
$name .= $filename[0] . $filename[1] . '/' . $filename[2] . $filename[3]; | ||
return $name; | ||
} | ||
|
||
protected function getFileSize() | ||
{ | ||
return $_FILES['file']['size']; | ||
} | ||
|
||
protected function getExt() | ||
{ | ||
$pathinfo = pathinfo($this->getFileName()); | ||
return $pathinfo['extension']; | ||
} | ||
|
||
protected function getFileName() | ||
{ | ||
return $_FILES['file']['name']; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
<?php | ||
|
||
namespace Bazalt\Rest; | ||
|
||
/** | ||
* UploaderException | ||
* | ||
* @category Uploader | ||
* @package BAZALT/Uploader | ||
* @author Alex Slubsky <aslubsky@gmail.com> | ||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL | ||
* @version Release: $Rev: 20 $ | ||
* @link http://www.php-solves.com/ | ||
*/ | ||
class UploaderException extends \Exception | ||
{ | ||
/** | ||
* __construct | ||
* | ||
* @param int $code | ||
*/ | ||
public function __construct($code) | ||
{ | ||
$message = $this->codeToMessage($code); | ||
parent::__construct($message, $code); | ||
} | ||
|
||
/** | ||
* | ||
* | ||
* | ||
* @param int $code | ||
* | ||
* @return string | ||
*/ | ||
private function codeToMessage($code) | ||
{ | ||
switch ($code) { | ||
case UPLOAD_ERR_INI_SIZE: | ||
$message = 'The uploaded file exceeds the upload_max_filesize directive in php.ini'; | ||
break; | ||
case UPLOAD_ERR_FORM_SIZE: | ||
$message = 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form'; | ||
break; | ||
case UPLOAD_ERR_PARTIAL: | ||
$message = 'The uploaded file was only partially uploaded'; | ||
break; | ||
case UPLOAD_ERR_NO_FILE: | ||
$message = 'No file was uploaded'; | ||
break; | ||
case UPLOAD_ERR_NO_TMP_DIR: | ||
$message = 'Missing a temporary folder'; | ||
break; | ||
case UPLOAD_ERR_CANT_WRITE: | ||
$message = 'Failed to write file to disk'; | ||
break; | ||
case UPLOAD_ERR_EXTENSION: | ||
$message = 'File upload stopped by extension'; | ||
break; | ||
|
||
default: | ||
$message = 'Could not save uploaded file. The upload was cancelled, or server error encountered'; | ||
break; | ||
} | ||
return $message; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
<?php | ||
|
||
namespace tests; | ||
|
||
use Bazalt\Rest; | ||
use Tonic; | ||
|
||
class UploaderTest extends \Bazalt\Rest\Test\BaseCase | ||
{ | ||
protected $uploader; | ||
|
||
protected function setUp() | ||
{ | ||
$this->uploader = new \Bazalt\Rest\Uploader(array('jpg'), 1024); | ||
|
||
if(file_exists('/tmp/uploads_test')) { | ||
$this->rrmdir('/tmp/uploads_test'); | ||
} | ||
mkdir('/tmp/uploads_test'); | ||
file_put_contents('/tmp/test.jpg', 'test'); | ||
} | ||
|
||
protected function tearDown() | ||
{ | ||
$this->uploader = null; | ||
unlink('/tmp/test.jpg'); | ||
$this->rrmdir('/tmp/uploads_test'); | ||
} | ||
|
||
protected function rrmdir($dir) | ||
{ | ||
if (is_dir($dir)) { | ||
$objects = scandir($dir); | ||
foreach ($objects as $object) { | ||
if ($object != "." && $object != "..") { | ||
if (filetype($dir . "/" . $object) == "dir") { | ||
$this->rrmdir($dir . "/" . $object); | ||
} else { | ||
unlink($dir . "/" . $object); | ||
} | ||
} | ||
} | ||
reset($objects); | ||
rmdir($dir); | ||
} | ||
} | ||
|
||
/** | ||
* @expectedException Exception | ||
*/ | ||
public function testHandleUploadInvalidDir() | ||
{ | ||
$this->uploader->handleUpload('/'); | ||
} | ||
|
||
/** | ||
* @expectedException Exception | ||
*/ | ||
public function testHandleUploadInvalidFile() | ||
{ | ||
$_FILES['file'] = array( | ||
'size' => 0 | ||
); | ||
$res = $this->uploader->handleUpload('/tmp'); | ||
$this->assertEquals(array('error' => 'File is empty.'), $res); | ||
} | ||
|
||
/** | ||
* @expectedException Exception | ||
*/ | ||
public function testHandleUploadInvalidFile2() | ||
{ | ||
$_FILES['file'] = array( | ||
'size' => 10, | ||
'name' => '/tmp/test.jpg' | ||
); | ||
$this->uploader = new \Bazalt\Rest\Uploader(array('png'), 1024); | ||
$res = $this->uploader->handleUpload('/tmp'); | ||
} | ||
|
||
/** | ||
* @expectedException Exception | ||
*/ | ||
public function testHandleUploadError() | ||
{ | ||
$_FILES['file'] = array( | ||
'size' => 10, | ||
'error' => 1, | ||
'name' => '/tmp/test.jpg' | ||
); | ||
$res = $this->uploader->handleUpload('/tmp'); | ||
} | ||
|
||
public function testHandleUpload() | ||
{ | ||
$this->uploader = $this->getMock('\Bazalt\Rest\Uploader', array('moveUploadedFile'), array(array('jpg'), 1024)); | ||
$_FILES['file'] = array( | ||
'size' => 10, | ||
'error' => 0, | ||
'tmp_name' => '/tmp/test.jpg', | ||
'name' => '/tmp/test.jpg' | ||
); | ||
$this->uploader->expects($this->once()) | ||
->method('moveUploadedFile'); | ||
$res = $this->uploader->handleUpload('/tmp/uploads_test', array(21, 'photos')); | ||
$this->assertTrue(strstr($res, '/21/photos/') !== false); | ||
} | ||
} |