summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrederic Guillot <fred@kanboard.net>2015-05-24 20:28:54 -0400
committerFrederic Guillot <fred@kanboard.net>2015-05-24 20:28:54 -0400
commit00c2e5c80ee4b6c5e5234e5b6a333bb19edd9b76 (patch)
treed6ad2135d614de68adf2fb6a8e8d702785e9ce0a
parent3eb5501ca0cfc11e774514a4169c718d1e54854d (diff)
Add file procedures to the API
-rw-r--r--app/Api/File.php48
-rw-r--r--app/Model/File.php35
-rw-r--r--docs/api-json-rpc.markdown186
-rw-r--r--jsonrpc.php1
-rw-r--r--tests/functionals/ApiTest.php30
-rw-r--r--tests/units/TimetableTest.php2
6 files changed, 299 insertions, 3 deletions
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 @@
+<?php
+
+namespace Api;
+
+/**
+ * File API controller
+ *
+ * @package api
+ * @author Frederic Guillot
+ */
+class File extends Base
+{
+ public function getFile($file_id)
+ {
+ return $this->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(),
));
}
@@ -320,6 +320,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)
*
* @access public
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);