From 00c2e5c80ee4b6c5e5234e5b6a333bb19edd9b76 Mon Sep 17 00:00:00 2001 From: Frederic Guillot Date: Sun, 24 May 2015 20:28:54 -0400 Subject: Add file procedures to the API --- app/Api/File.php | 48 +++++++++++ app/Model/File.php | 35 +++++++- docs/api-json-rpc.markdown | 186 ++++++++++++++++++++++++++++++++++++++++++ jsonrpc.php | 1 + tests/functionals/ApiTest.php | 30 ++++++- tests/units/TimetableTest.php | 2 +- 6 files changed, 299 insertions(+), 3 deletions(-) create mode 100644 app/Api/File.php diff --git a/app/Api/File.php b/app/Api/File.php new file mode 100644 index 00000000..11c48404 --- /dev/null +++ b/app/Api/File.php @@ -0,0 +1,48 @@ +file->getById($file_id); + } + + public function getAllFiles($task_id) + { + return $this->file->getAll($task_id); + } + + public function downloadFile($file_id) + { + $file = $this->file->getById($file_id); + + if (! empty($file)) { + + $filename = FILES_DIR.$file['path']; + + if (file_exists($filename)) { + return base64_encode(file_get_contents($filename)); + } + } + + return ''; + } + + public function createFile($project_id, $task_id, $filename, $is_image, &$blob) + { + return $this->file->uploadContent($project_id, $task_id, $filename, $is_image, $blob); + } + + public function removeFile($file_id) + { + return $this->file->remove($file_id); + } +} diff --git a/app/Model/File.php b/app/Model/File.php index cb1e4792..16bf079e 100644 --- a/app/Model/File.php +++ b/app/Model/File.php @@ -96,7 +96,7 @@ class File extends Base 'path' => $path, 'is_image' => $is_image ? '1' : '0', 'size' => $size, - 'user_id' => $this->userSession->getId(), + 'user_id' => $this->userSession->getId() ?: 0, 'date' => time(), )); } @@ -319,6 +319,39 @@ class File extends Base ); } + /** + * Handle file upload (base64 encoded content) + * + * @access public + * @param integer $project_id Project id + * @param integer $task_id Task id + * @param string $filename Filename + * @param bool $is_image Is image file? + * @param string $blob Base64 encoded image + * @return bool + */ + public function uploadContent($project_id, $task_id, $filename, $is_image, &$blob) + { + $data = base64_decode($blob); + + if (empty($data)) { + return false; + } + + $destination_filename = $this->generatePath($project_id, $task_id, $filename); + + @mkdir(FILES_DIR.dirname($destination_filename), 0755, true); + @file_put_contents(FILES_DIR.$destination_filename, $data); + + return $this->create( + $task_id, + $filename, + $destination_filename, + $is_image, + strlen($data) + ); + } + /** * Generate a jpeg thumbnail from an image (output directly the image) * diff --git a/docs/api-json-rpc.markdown b/docs/api-json-rpc.markdown index 89010cef..98ce48d7 100644 --- a/docs/api-json-rpc.markdown +++ b/docs/api-json-rpc.markdown @@ -3489,3 +3489,189 @@ Response example: "result": true } ``` + +### createFile + +- Purpose: **Create and upload a new task attachment** +- Parameters: + - **project_id** (integer, required) + - **task_id** (integer, required) + - **filename** (integer, required) + - **is_image** (boolean, required) + - **blob** File content encoded in base64 (string, required) +- Result on success: **true** +- Result on failure: **false** +- Note: **The maximum file size depends of your PHP configuration, this method should not be used to upload large files** + +Request example: + +```json +{ + "jsonrpc": "2.0", + "method": "createFile", + "id": 1035045925, + "params": [ + 1, + 1, + "My file", + false, + "cGxhaW4gdGV4dCBmaWxl" + ] +} +``` + +Response example: + +```json +{ + "jsonrpc": "2.0", + "id": 1035045925, + "result": true +} +``` + +### getAllFiles + +- Purpose: **Get all files attached to task** +- Parameters: + - **task_id** (integer, required) +- Result on success: **list of files** +- Result on failure: **false** + +Request example: + +```json +{ + "jsonrpc": "2.0", + "method": "getAllFiles", + "id": 1880662820, + "params": { + "task_id": 1 + } +} +``` + +Response example: + +```json +{ + "jsonrpc": "2.0", + "id": 1880662820, + "result": [ + { + "id": "1", + "name": "My file", + "path": "1\/1\/0db4d0a897a4c852f6e12f0239d4805f7b4ab596", + "is_image": "0", + "task_id": "1", + "date": "1432509941", + "user_id": "0", + "size": "15", + "username": null, + "user_name": null + } + ] +} +``` + +### getFile + +- Purpose: **Get file information** +- Parameters: + - **file_id** (integer, required) +- Result on success: **file properties** +- Result on failure: **false** + +Request example: + +```json +{ + "jsonrpc": "2.0", + "method": "getFile", + "id": 318676852, + "params": [ + "1" + ] +} +``` + +Response example: + +```json +{ + "jsonrpc": "2.0", + "id": 318676852, + "result": { + "id": "1", + "name": "My file", + "path": "1\/1\/0db4d0a897a4c852f6e12f0239d4805f7b4ab596", + "is_image": "0", + "task_id": "1", + "date": "1432509941", + "user_id": "0", + "size": "15" + } +} +``` + +### downloadFile + +- Purpose: **Download file contents (encoded in base64)** +- Parameters: + - **file_id** (integer, required) +- Result on success: **base64 encoded string** +- Result on failure: **empty string** + +Request example: + +```json +{ + "jsonrpc": "2.0", + "method": "downloadFile", + "id": 235943344, + "params": [ + "1" + ] +} +``` + +Response example: + +```json +{ + "jsonrpc": "2.0", + "id": 235943344, + "result": "cGxhaW4gdGV4dCBmaWxl" +} +``` + +### removeFile + +- Purpose: **Remove file** +- Parameters: + - **file_id** (integer, required) +- Result on success: **true** +- Result on failure: **false** + +Request example: + +```json +{ + "jsonrpc": "2.0", + "method": "removeFile", + "id": 447036524, + "params": [ + "1" + ] +} +``` + +Response example: + +```json +{ + "jsonrpc": "2.0", + "id": 447036524, + "result": true +} +``` diff --git a/jsonrpc.php b/jsonrpc.php index b6ec8291..c3de1fc5 100644 --- a/jsonrpc.php +++ b/jsonrpc.php @@ -9,6 +9,7 @@ $server->attach(new Api\App($container)); $server->attach(new Api\Board($container)); $server->attach(new Api\Category($container)); $server->attach(new Api\Comment($container)); +$server->attach(new Api\File($container)); $server->attach(new Api\Link($container)); $server->attach(new Api\Project($container)); $server->attach(new Api\ProjectPermission($container)); diff --git a/tests/functionals/ApiTest.php b/tests/functionals/ApiTest.php index 4ab2db99..b5039759 100644 --- a/tests/functionals/ApiTest.php +++ b/tests/functionals/ApiTest.php @@ -36,7 +36,7 @@ class Api extends PHPUnit_Framework_TestCase { $this->client = new JsonRPC\Client(API_URL); $this->client->authentication('jsonrpc', API_KEY); - $this->client->debug = true; + // $this->client->debug = true; } private function getTaskId() @@ -934,4 +934,32 @@ class Api extends PHPUnit_Framework_TestCase $this->assertTrue($this->client->removeTaskLink($task_link_id)); $this->assertEmpty($this->client->getAllTaskLinks($task_id1)); } + + public function testCreateFile() + { + $this->assertTrue($this->client->createFile(1, 1, 'My file', false, base64_encode('plain text file'))); + } + + public function testGetAllFiles() + { + $files = $this->client->getAllFiles(array('task_id' => 1)); + + $this->assertNotEmpty($files); + $this->assertCount(1, $files); + $this->assertEquals('My file', $files[0]['name']); + + $file = $this->client->getFile($files[0]['id']); + $this->assertNotEmpty($file); + $this->assertEquals('My file', $file['name']); + + $content = $this->client->downloadFile($file['id']); + $this->assertNotEmpty($content); + $this->assertEquals('plain text file', base64_decode($content)); + + $content = $this->client->downloadFile(1234567); + $this->assertEmpty($content); + + $this->assertTrue($this->client->removeFile($file['id'])); + $this->assertEmpty($this->client->getAllFiles(1)); + } } \ No newline at end of file diff --git a/tests/units/TimetableTest.php b/tests/units/TimetableTest.php index 5f698941..9c40dce1 100644 --- a/tests/units/TimetableTest.php +++ b/tests/units/TimetableTest.php @@ -141,7 +141,7 @@ class TimetableTest extends Base $monday = new DateTime('next Monday'); $tuesday = new DateTime('next Monday + 1 day'); - $timetable = $t->calculate(1, new DateTime('Monday'), new DateTime('Monday + 6 days')); + $timetable = $t->calculate(1, new DateTime('next Monday'), new DateTime('next Monday + 6 days')); $this->assertNotEmpty($timetable); $this->assertCount(4, $timetable); -- cgit v1.2.3