Add ProjecFile and TaskFile models

This commit is contained in:
Frederic Guillot
2016-02-14 15:25:16 -05:00
parent fbb58e08d3
commit 8e25c875f2
30 changed files with 1223 additions and 563 deletions

View File

@@ -2,6 +2,7 @@
namespace Kanboard\Api; namespace Kanboard\Api;
use Kanboard\Core\Base;
use Kanboard\Core\ObjectStorage\ObjectStorageException; use Kanboard\Core\ObjectStorage\ObjectStorageException;
/** /**
@@ -10,22 +11,22 @@ use Kanboard\Core\ObjectStorage\ObjectStorageException;
* @package api * @package api
* @author Frederic Guillot * @author Frederic Guillot
*/ */
class File extends \Kanboard\Core\Base class File extends Base
{ {
public function getFile($file_id) public function getTaskFile($file_id)
{ {
return $this->file->getById($file_id); return $this->taskFile->getById($file_id);
} }
public function getAllFiles($task_id) public function getAllTaskFiles($task_id)
{ {
return $this->file->getAll($task_id); return $this->taskFile->getAll($task_id);
} }
public function downloadFile($file_id) public function downloadTaskFile($file_id)
{ {
try { try {
$file = $this->file->getById($file_id); $file = $this->taskFile->getById($file_id);
if (! empty($file)) { if (! empty($file)) {
return base64_encode($this->objectStorage->get($file['path'])); return base64_encode($this->objectStorage->get($file['path']));
@@ -36,23 +37,55 @@ class File extends \Kanboard\Core\Base
} }
} }
public function createFile($project_id, $task_id, $filename, $blob) public function createTaskFile($project_id, $task_id, $filename, $blob)
{ {
try { try {
return $this->file->uploadContent($project_id, $task_id, $filename, $blob); return $this->taskFile->uploadContent($task_id, $filename, $blob);
} catch (ObjectStorageException $e) { } catch (ObjectStorageException $e) {
$this->logger->error($e->getMessage()); $this->logger->error($e->getMessage());
return false; return false;
} }
} }
public function removeTaskFile($file_id)
{
return $this->taskFile->remove($file_id);
}
public function removeAllTaskFiles($task_id)
{
return $this->taskFile->removeAll($task_id);
}
// Deprecated procedures
public function getFile($file_id)
{
return $this->getTaskFile($file_id);
}
public function getAllFiles($task_id)
{
return $this->getAllTaskFiles($task_id);
}
public function downloadFile($file_id)
{
return $this->downloadTaskFile($file_id);
}
public function createFile($project_id, $task_id, $filename, $blob)
{
return $this->createTaskFile($project_id, $task_id, $filename, $blob);
}
public function removeFile($file_id) public function removeFile($file_id)
{ {
return $this->file->remove($file_id); return $this->removeTaskFile($file_id);
} }
public function removeAllFiles($task_id) public function removeAllFiles($task_id)
{ {
return $this->file->removeAll($task_id); return $this->removeAllTaskFiles($task_id);
} }
} }

View File

@@ -62,7 +62,7 @@ class BoardTooltip extends Base
$task = $this->getTask(); $task = $this->getTask();
$this->response->html($this->template->render('board/tooltip_files', array( $this->response->html($this->template->render('board/tooltip_files', array(
'files' => $this->file->getAll($task['id']), 'files' => $this->taskFile->getAll($task['id']),
'task' => $task, 'task' => $task,
))); )));
} }

View File

@@ -21,7 +21,7 @@ class File extends Base
{ {
$task = $this->getTask(); $task = $this->getTask();
if ($this->request->isPost() && $this->file->uploadScreenshot($task['project_id'], $task['id'], $this->request->getValue('screenshot')) !== false) { if ($this->request->isPost() && $this->taskFile->uploadScreenshot($task['id'], $this->request->getValue('screenshot')) !== false) {
$this->flash->success(t('Screenshot uploaded successfully.')); $this->flash->success(t('Screenshot uploaded successfully.'));
return $this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])), true); return $this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])), true);
} }
@@ -55,7 +55,7 @@ class File extends Base
{ {
$task = $this->getTask(); $task = $this->getTask();
if (! $this->file->uploadFiles($task['project_id'], $task['id'], 'files')) { if (! $this->taskFile->uploadFiles($task['id'], $this->request->getFileInfo('files'))) {
$this->flash->failure(t('Unable to upload the file.')); $this->flash->failure(t('Unable to upload the file.'));
} }
@@ -71,7 +71,7 @@ class File extends Base
{ {
try { try {
$task = $this->getTask(); $task = $this->getTask();
$file = $this->file->getById($this->request->getIntegerParam('file_id')); $file = $this->taskFile->getById($this->request->getIntegerParam('file_id'));
if ($file['task_id'] != $task['id']) { if ($file['task_id'] != $task['id']) {
$this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']))); $this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])));
@@ -92,7 +92,7 @@ class File extends Base
public function open() public function open()
{ {
$task = $this->getTask(); $task = $this->getTask();
$file = $this->file->getById($this->request->getIntegerParam('file_id')); $file = $this->taskFile->getById($this->request->getIntegerParam('file_id'));
if ($file['task_id'] == $task['id']) { if ($file['task_id'] == $task['id']) {
$this->response->html($this->template->render('file/open', array( $this->response->html($this->template->render('file/open', array(
@@ -111,10 +111,10 @@ class File extends Base
{ {
try { try {
$task = $this->getTask(); $task = $this->getTask();
$file = $this->file->getById($this->request->getIntegerParam('file_id')); $file = $this->taskFile->getById($this->request->getIntegerParam('file_id'));
if ($file['task_id'] == $task['id']) { if ($file['task_id'] == $task['id']) {
$this->response->contentType($this->file->getImageMimeType($file['name'])); $this->response->contentType($this->taskFile->getImageMimeType($file['name']));
$this->objectStorage->output($file['path']); $this->objectStorage->output($file['path']);
} }
} catch (ObjectStorageException $e) { } catch (ObjectStorageException $e) {
@@ -133,18 +133,18 @@ class File extends Base
try { try {
$task = $this->getTask(); $task = $this->getTask();
$file = $this->file->getById($this->request->getIntegerParam('file_id')); $file = $this->taskFile->getById($this->request->getIntegerParam('file_id'));
if ($file['task_id'] == $task['id']) { if ($file['task_id'] == $task['id']) {
$this->objectStorage->output($this->file->getThumbnailPath($file['path'])); $this->objectStorage->output($this->taskFile->getThumbnailPath($file['path']));
} }
} catch (ObjectStorageException $e) { } catch (ObjectStorageException $e) {
$this->logger->error($e->getMessage()); $this->logger->error($e->getMessage());
// Try to generate thumbnail on the fly for images uploaded before Kanboard < 1.0.19 // Try to generate thumbnail on the fly for images uploaded before Kanboard < 1.0.19
$data = $this->objectStorage->get($file['path']); $data = $this->objectStorage->get($file['path']);
$this->file->generateThumbnailFromData($file['path'], $data); $this->taskFile->generateThumbnailFromData($file['path'], $data);
$this->objectStorage->output($this->file->getThumbnailPath($file['path'])); $this->objectStorage->output($this->taskFile->getThumbnailPath($file['path']));
} }
} }
@@ -157,9 +157,9 @@ class File extends Base
{ {
$this->checkCSRFParam(); $this->checkCSRFParam();
$task = $this->getTask(); $task = $this->getTask();
$file = $this->file->getById($this->request->getIntegerParam('file_id')); $file = $this->taskFile->getById($this->request->getIntegerParam('file_id'));
if ($file['task_id'] == $task['id'] && $this->file->remove($file['id'])) { if ($file['task_id'] == $task['id'] && $this->taskFile->remove($file['id'])) {
$this->flash->success(t('File removed successfully.')); $this->flash->success(t('File removed successfully.'));
} else { } else {
$this->flash->failure(t('Unable to remove this file.')); $this->flash->failure(t('Unable to remove this file.'));
@@ -176,7 +176,7 @@ class File extends Base
public function confirm() public function confirm()
{ {
$task = $this->getTask(); $task = $this->getTask();
$file = $this->file->getById($this->request->getIntegerParam('file_id')); $file = $this->taskFile->getById($this->request->getIntegerParam('file_id'));
$this->response->html($this->helper->layout->task('file/remove', array( $this->response->html($this->helper->layout->task('file/remove', array(
'task' => $task, 'task' => $task,

View File

@@ -66,8 +66,8 @@ class Task extends Base
$this->response->html($this->helper->layout->task('task/show', array( $this->response->html($this->helper->layout->task('task/show', array(
'project' => $this->project->getById($task['project_id']), 'project' => $this->project->getById($task['project_id']),
'files' => $this->file->getAllDocuments($task['id']), 'files' => $this->taskFile->getAllDocuments($task['id']),
'images' => $this->file->getAllImages($task['id']), 'images' => $this->taskFile->getAllImages($task['id']),
'comments' => $this->comment->getAll($task['id'], $this->userSession->getCommentSorting()), 'comments' => $this->comment->getAll($task['id'], $this->userSession->getCommentSorting()),
'subtasks' => $subtasks, 'subtasks' => $subtasks,
'links' => $this->taskLink->getAllGroupedByLabel($task['id']), 'links' => $this->taskLink->getAllGroupedByLabel($task['id']),

View File

@@ -67,7 +67,8 @@ use Pimple\Container;
* @property \Kanboard\Model\Config $config * @property \Kanboard\Model\Config $config
* @property \Kanboard\Model\Currency $currency * @property \Kanboard\Model\Currency $currency
* @property \Kanboard\Model\CustomFilter $customFilter * @property \Kanboard\Model\CustomFilter $customFilter
* @property \Kanboard\Model\File $file * @property \Kanboard\Model\TaskFile $taskFile
* @property \Kanboard\Model\ProjectFile $projectFile
* @property \Kanboard\Model\Group $group * @property \Kanboard\Model\Group $group
* @property \Kanboard\Model\GroupMember $groupMember * @property \Kanboard\Model\GroupMember $groupMember
* @property \Kanboard\Model\LastLogin $lastLogin * @property \Kanboard\Model\LastLogin $lastLogin

View File

@@ -2,31 +2,44 @@
namespace Kanboard\Model; namespace Kanboard\Model;
use Exception;
use Kanboard\Event\FileEvent; use Kanboard\Event\FileEvent;
use Kanboard\Core\Tool; use Kanboard\Core\Tool;
use Kanboard\Core\ObjectStorage\ObjectStorageException; use Kanboard\Core\ObjectStorage\ObjectStorageException;
/** /**
* File model * Base File Model
* *
* @package model * @package model
* @author Frederic Guillot * @author Frederic Guillot
*/ */
class File extends Base abstract class File extends Base
{ {
/** /**
* SQL table name * Get PicoDb query to get all files
* *
* @var string * @access protected
* @return \PicoDb\Table
*/ */
const TABLE = 'files'; protected function getQuery()
{
/** return $this->db
* Events ->table(static::TABLE)
* ->columns(
* @var string static::TABLE.'.id',
*/ static::TABLE.'.name',
const EVENT_CREATE = 'file.create'; static::TABLE.'.path',
static::TABLE.'.is_image',
static::TABLE.'.'.static::FOREIGN_KEY,
static::TABLE.'.date',
static::TABLE.'.user_id',
static::TABLE.'.size',
User::TABLE.'.username',
User::TABLE.'.name as user_name'
)
->join(User::TABLE, 'id', 'user_id')
->asc(static::TABLE.'.name');
}
/** /**
* Get a file by the id * Get a file by the id
@@ -37,7 +50,96 @@ class File extends Base
*/ */
public function getById($file_id) public function getById($file_id)
{ {
return $this->db->table(self::TABLE)->eq('id', $file_id)->findOne(); return $this->db->table(static::TABLE)->eq('id', $file_id)->findOne();
}
/**
* Get all files
*
* @access public
* @param integer $id
* @return array
*/
public function getAll($id)
{
return $this->getQuery()->eq(static::FOREIGN_KEY, $id)->findAll();
}
/**
* Get all images
*
* @access public
* @param integer $id
* @return array
*/
public function getAllImages($id)
{
return $this->getQuery()->eq(static::FOREIGN_KEY, $id)->eq('is_image', 1)->findAll();
}
/**
* Get all files without images
*
* @access public
* @param integer $id
* @return array
*/
public function getAllDocuments($id)
{
return $this->getQuery()->eq(static::FOREIGN_KEY, $id)->eq('is_image', 0)->findAll();
}
/**
* Create a file entry in the database
*
* @access public
* @param integer $id Foreign key
* @param string $name Filename
* @param string $path Path on the disk
* @param integer $size File size
* @return bool|integer
*/
public function create($id, $name, $path, $size)
{
$values = array(
static::FOREIGN_KEY => $id,
'name' => substr($name, 0, 255),
'path' => $path,
'is_image' => $this->isImage($name) ? 1 : 0,
'size' => $size,
'user_id' => $this->userSession->getId() ?: 0,
'date' => time(),
);
$result = $this->db->table(static::TABLE)->insert($values);
if ($result) {
$file_id = (int) $this->db->getLastId();
$event = new FileEvent($values + array('file_id' => $file_id));
$this->dispatcher->dispatch(static::EVENT_CREATE, $event);
return $file_id;
}
return false;
}
/**
* Remove all files
*
* @access public
* @param integer $id
* @return bool
*/
public function removeAll($id)
{
$file_ids = $this->db->table(static::TABLE)->eq(static::FOREIGN_KEY, $id)->asc('id')->findAllByColumn('id');
$results = array();
foreach ($file_ids as $file_id) {
$results[] = $this->remove($file_id);
}
return ! in_array(false, $results, true);
} }
/** /**
@@ -50,135 +152,20 @@ class File extends Base
public function remove($file_id) public function remove($file_id)
{ {
try { try {
$file = $this->getbyId($file_id); $file = $this->getById($file_id);
$this->objectStorage->remove($file['path']); $this->objectStorage->remove($file['path']);
if ($file['is_image'] == 1) { if ($file['is_image'] == 1) {
$this->objectStorage->remove($this->getThumbnailPath($file['path'])); $this->objectStorage->remove($this->getThumbnailPath($file['path']));
} }
return $this->db->table(self::TABLE)->eq('id', $file['id'])->remove(); return $this->db->table(static::TABLE)->eq('id', $file['id'])->remove();
} catch (ObjectStorageException $e) { } catch (ObjectStorageException $e) {
$this->logger->error($e->getMessage()); $this->logger->error($e->getMessage());
return false; return false;
} }
} }
/**
* Remove all files for a given task
*
* @access public
* @param integer $task_id Task id
* @return bool
*/
public function removeAll($task_id)
{
$file_ids = $this->db->table(self::TABLE)->eq('task_id', $task_id)->asc('id')->findAllByColumn('id');
$results = array();
foreach ($file_ids as $file_id) {
$results[] = $this->remove($file_id);
}
return ! in_array(false, $results, true);
}
/**
* Create a file entry in the database
*
* @access public
* @param integer $task_id Task id
* @param string $name Filename
* @param string $path Path on the disk
* @param integer $size File size
* @return bool|integer
*/
public function create($task_id, $name, $path, $size)
{
$result = $this->db->table(self::TABLE)->save(array(
'task_id' => $task_id,
'name' => substr($name, 0, 255),
'path' => $path,
'is_image' => $this->isImage($name) ? 1 : 0,
'size' => $size,
'user_id' => $this->userSession->getId() ?: 0,
'date' => time(),
));
if ($result) {
$this->container['dispatcher']->dispatch(
self::EVENT_CREATE,
new FileEvent(array('task_id' => $task_id, 'name' => $name))
);
return (int) $this->db->getLastId();
}
return false;
}
/**
* Get PicoDb query to get all files
*
* @access public
* @return \PicoDb\Table
*/
public function getQuery()
{
return $this->db
->table(self::TABLE)
->columns(
self::TABLE.'.id',
self::TABLE.'.name',
self::TABLE.'.path',
self::TABLE.'.is_image',
self::TABLE.'.task_id',
self::TABLE.'.date',
self::TABLE.'.user_id',
self::TABLE.'.size',
User::TABLE.'.username',
User::TABLE.'.name as user_name'
)
->join(User::TABLE, 'id', 'user_id')
->asc(self::TABLE.'.name');
}
/**
* Get all files for a given task
*
* @access public
* @param integer $task_id Task id
* @return array
*/
public function getAll($task_id)
{
return $this->getQuery()->eq('task_id', $task_id)->findAll();
}
/**
* Get all images for a given task
*
* @access public
* @param integer $task_id Task id
* @return array
*/
public function getAllImages($task_id)
{
return $this->getQuery()->eq('task_id', $task_id)->eq('is_image', 1)->findAll();
}
/**
* Get all files without images for a given task
*
* @access public
* @param integer $task_id Task id
* @return array
*/
public function getAllDocuments($task_id)
{
return $this->getQuery()->eq('task_id', $task_id)->eq('is_image', 0)->findAll();
}
/** /**
* Check if a filename is an image (file types that can be shown as thumbnail) * Check if a filename is an image (file types that can be shown as thumbnail)
* *
@@ -225,20 +212,6 @@ class File extends Base
} }
} }
/**
* Generate the path for a new filename
*
* @access public
* @param integer $project_id Project id
* @param integer $task_id Task id
* @param string $filename Filename
* @return string
*/
public function generatePath($project_id, $task_id, $filename)
{
return $project_id.DIRECTORY_SEPARATOR.$task_id.DIRECTORY_SEPARATOR.hash('sha1', $filename.time());
}
/** /**
* Generate the path for a thumbnails * Generate the path for a thumbnails
* *
@@ -252,77 +225,84 @@ class File extends Base
} }
/** /**
* Handle file upload * Generate the path for a new filename
* *
* @access public * @access public
* @param integer $project_id Project id * @param integer $id Foreign key
* @param integer $task_id Task id * @param string $filename Filename
* @param string $form_name File form name * @return string
*/
public function generatePath($id, $filename)
{
return static::PATH_PREFIX.DIRECTORY_SEPARATOR.$id.DIRECTORY_SEPARATOR.hash('sha1', $filename.time());
}
/**
* Upload multiple files
*
* @access public
* @param integer $id
* @param array $files
* @return bool * @return bool
*/ */
public function uploadFiles($project_id, $task_id, $form_name) public function uploadFiles($id, array $files)
{ {
try { try {
$file = $this->request->getFileInfo($form_name); if (empty($files)) {
if (empty($file)) {
return false; return false;
} }
foreach ($file['error'] as $key => $error) { foreach (array_keys($files['error']) as $key) {
if ($error == UPLOAD_ERR_OK && $file['size'][$key] > 0) { $file = array(
$original_filename = $file['name'][$key]; 'name' => $files['name'][$key],
$uploaded_filename = $file['tmp_name'][$key]; 'tmp_name' => $files['tmp_name'][$key],
$destination_filename = $this->generatePath($project_id, $task_id, $original_filename); 'size' => $files['size'][$key],
'error' => $files['error'][$key],
);
if ($this->isImage($original_filename)) { $this->uploadFile($id, $file);
$this->generateThumbnailFromFile($uploaded_filename, $destination_filename);
}
$this->objectStorage->moveUploadedFile($uploaded_filename, $destination_filename);
$this->create(
$task_id,
$original_filename,
$destination_filename,
$file['size'][$key]
);
}
} }
return true; return true;
} catch (ObjectStorageException $e) { } catch (Exception $e) {
$this->logger->error($e->getMessage()); $this->logger->error($e->getMessage());
return false; return false;
} }
} }
/** /**
* Handle screenshot upload * Upload a file
* *
* @access public * @access public
* @param integer $project_id Project id * @param integer $id
* @param integer $task_id Task id * @param array $file
* @param string $blob Base64 encoded image
* @return bool|integer
*/ */
public function uploadScreenshot($project_id, $task_id, $blob) public function uploadFile($id, array $file)
{ {
$original_filename = e('Screenshot taken %s', $this->helper->dt->datetime(time())).'.png'; if ($file['error'] == UPLOAD_ERR_OK && $file['size'] > 0) {
return $this->uploadContent($project_id, $task_id, $original_filename, $blob); $destination_filename = $this->generatePath($id, $file['name']);
if ($this->isImage($file['name'])) {
$this->generateThumbnailFromFile($file['tmp_name'], $destination_filename);
}
$this->objectStorage->moveUploadedFile($file['tmp_name'], $destination_filename);
$this->create($id, $file['name'], $destination_filename, $file['size']);
} else {
throw new Exception('File not uploaded: '.var_export($file['error'], true));
}
} }
/** /**
* Handle file upload (base64 encoded content) * Handle file upload (base64 encoded content)
* *
* @access public * @access public
* @param integer $project_id Project id * @param integer $id
* @param integer $task_id Task id * @param string $original_filename
* @param string $original_filename Filename * @param string $blob
* @param string $blob Base64 encoded file
* @return bool|integer * @return bool|integer
*/ */
public function uploadContent($project_id, $task_id, $original_filename, $blob) public function uploadContent($id, $original_filename, $blob)
{ {
try { try {
$data = base64_decode($blob); $data = base64_decode($blob);
@@ -331,7 +311,7 @@ class File extends Base
return false; return false;
} }
$destination_filename = $this->generatePath($project_id, $task_id, $original_filename); $destination_filename = $this->generatePath($id, $original_filename);
$this->objectStorage->put($destination_filename, $data); $this->objectStorage->put($destination_filename, $data);
if ($this->isImage($original_filename)) { if ($this->isImage($original_filename)) {
@@ -339,7 +319,7 @@ class File extends Base
} }
return $this->create( return $this->create(
$task_id, $id,
$original_filename, $original_filename,
$destination_filename, $destination_filename,
strlen($data) strlen($data)

View File

@@ -72,7 +72,7 @@ class Notification extends Base
return e('%s updated a comment on the task #%d', $event_author, $event_data['task']['id']); return e('%s updated a comment on the task #%d', $event_author, $event_data['task']['id']);
case Comment::EVENT_CREATE: case Comment::EVENT_CREATE:
return e('%s commented on the task #%d', $event_author, $event_data['task']['id']); return e('%s commented on the task #%d', $event_author, $event_data['task']['id']);
case File::EVENT_CREATE: case TaskFile::EVENT_CREATE:
return e('%s attached a file to the task #%d', $event_author, $event_data['task']['id']); return e('%s attached a file to the task #%d', $event_author, $event_data['task']['id']);
case Task::EVENT_USER_MENTION: case Task::EVENT_USER_MENTION:
return e('%s mentioned you in the task #%d', $event_author, $event_data['task']['id']); return e('%s mentioned you in the task #%d', $event_author, $event_data['task']['id']);
@@ -94,7 +94,7 @@ class Notification extends Base
public function getTitleWithoutAuthor($event_name, array $event_data) public function getTitleWithoutAuthor($event_name, array $event_data)
{ {
switch ($event_name) { switch ($event_name) {
case File::EVENT_CREATE: case TaskFile::EVENT_CREATE:
return e('New attachment on task #%d: %s', $event_data['file']['task_id'], $event_data['file']['name']); return e('New attachment on task #%d: %s', $event_data['file']['task_id'], $event_data['file']['name']);
case Comment::EVENT_CREATE: case Comment::EVENT_CREATE:
return e('New comment on task #%d', $event_data['comment']['task_id']); return e('New comment on task #%d', $event_data['comment']['task_id']);

40
app/Model/ProjectFile.php Normal file
View File

@@ -0,0 +1,40 @@
<?php
namespace Kanboard\Model;
/**
* Project File Model
*
* @package model
* @author Frederic Guillot
*/
class ProjectFile extends File
{
/**
* SQL table name
*
* @var string
*/
const TABLE = 'project_has_files';
/**
* SQL foreign key
*
* @var string
*/
const FOREIGN_KEY = 'project_id';
/**
* Path prefix
*
* @var string
*/
const PATH_PREFIX = 'projects';
/**
* Events
*
* @var string
*/
const EVENT_CREATE = 'project.file.create';
}

View File

@@ -92,7 +92,7 @@ class Task extends Base
return false; return false;
} }
$this->file->removeAll($task_id); $this->taskFile->removeAll($task_id);
return $this->db->table(self::TABLE)->eq('id', $task_id)->remove(); return $this->db->table(self::TABLE)->eq('id', $task_id)->remove();
} }

54
app/Model/TaskFile.php Normal file
View File

@@ -0,0 +1,54 @@
<?php
namespace Kanboard\Model;
/**
* Task File Model
*
* @package model
* @author Frederic Guillot
*/
class TaskFile extends File
{
/**
* SQL table name
*
* @var string
*/
const TABLE = 'task_has_files';
/**
* SQL foreign key
*
* @var string
*/
const FOREIGN_KEY = 'task_id';
/**
* Path prefix
*
* @var string
*/
const PATH_PREFIX = 'tasks';
/**
* Events
*
* @var string
*/
const EVENT_CREATE = 'task.file.create';
/**
* Handle screenshot upload
*
* @access public
* @param integer $task_id Task id
* @param string $blob Base64 encoded image
* @return bool|integer
*/
public function uploadScreenshot($task_id, $blob)
{
$original_filename = e('Screenshot taken %s', $this->helper->dt->datetime(time())).'.png';
return $this->uploadContent($task_id, $original_filename, $blob);
}
}

View File

@@ -89,7 +89,7 @@ class TaskFinder extends Base
->table(Task::TABLE) ->table(Task::TABLE)
->columns( ->columns(
'(SELECT COUNT(*) FROM '.Comment::TABLE.' WHERE task_id=tasks.id) AS nb_comments', '(SELECT COUNT(*) FROM '.Comment::TABLE.' WHERE task_id=tasks.id) AS nb_comments',
'(SELECT COUNT(*) FROM '.File::TABLE.' WHERE task_id=tasks.id) AS nb_files', '(SELECT COUNT(*) FROM '.TaskFile::TABLE.' WHERE task_id=tasks.id) AS nb_files',
'(SELECT COUNT(*) FROM '.Subtask::TABLE.' WHERE '.Subtask::TABLE.'.task_id=tasks.id) AS nb_subtasks', '(SELECT COUNT(*) FROM '.Subtask::TABLE.' WHERE '.Subtask::TABLE.'.task_id=tasks.id) AS nb_subtasks',
'(SELECT COUNT(*) FROM '.Subtask::TABLE.' WHERE '.Subtask::TABLE.'.task_id=tasks.id AND status=2) AS nb_completed_subtasks', '(SELECT COUNT(*) FROM '.Subtask::TABLE.' WHERE '.Subtask::TABLE.'.task_id=tasks.id AND status=2) AS nb_completed_subtasks',
'(SELECT COUNT(*) FROM '.TaskLink::TABLE.' WHERE '.TaskLink::TABLE.'.task_id = tasks.id) AS nb_links', '(SELECT COUNT(*) FROM '.TaskLink::TABLE.' WHERE '.TaskLink::TABLE.'.task_id = tasks.id) AS nb_links',

View File

@@ -4,7 +4,7 @@ namespace Kanboard\Notification;
use Kanboard\Core\Base; use Kanboard\Core\Base;
use Kanboard\Model\Task; use Kanboard\Model\Task;
use Kanboard\Model\File; use Kanboard\Model\TaskFile;
use Kanboard\Model\Comment; use Kanboard\Model\Comment;
use Kanboard\Model\Subtask; use Kanboard\Model\Subtask;
@@ -82,7 +82,7 @@ class Mail extends Base implements NotificationInterface
public function getMailSubject($event_name, array $event_data) public function getMailSubject($event_name, array $event_data)
{ {
switch ($event_name) { switch ($event_name) {
case File::EVENT_CREATE: case TaskFile::EVENT_CREATE:
$subject = $this->getStandardMailSubject(e('New attachment'), $event_data); $subject = $this->getStandardMailSubject(e('New attachment'), $event_data);
break; break;
case Comment::EVENT_CREATE: case Comment::EVENT_CREATE:

View File

@@ -6,7 +6,27 @@ use PDO;
use Kanboard\Core\Security\Token; use Kanboard\Core\Security\Token;
use Kanboard\Core\Security\Role; use Kanboard\Core\Security\Role;
const VERSION = 105; const VERSION = 106;
function version_106(PDO $pdo)
{
$pdo->exec('RENAME TABLE files TO task_has_files');
$pdo->exec("
CREATE TABLE project_has_files (
`id` INT NOT NULL AUTO_INCREMENT,
`project_id` INT NOT NULL,
`name` VARCHAR(255) NOT NULL,
`path` VARCHAR(255) NOT NULL,
`is_image` TINYINT(1) DEFAULT 0,
`size` INT DEFAULT 0 NOT NULL,
`user_id` INT DEFAULT 0 NOT NULL,
`date` INT DEFAULT 0 NOT NULL,
FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE,
PRIMARY KEY(id)
) ENGINE=InnoDB CHARSET=utf8"
);
}
function version_105(PDO $pdo) function version_105(PDO $pdo)
{ {

View File

@@ -6,7 +6,26 @@ use PDO;
use Kanboard\Core\Security\Token; use Kanboard\Core\Security\Token;
use Kanboard\Core\Security\Role; use Kanboard\Core\Security\Role;
const VERSION = 85; const VERSION = 86;
function version_86(PDO $pdo)
{
$pdo->exec('ALTER TABLE files RENAME TO task_has_files');
$pdo->exec("
CREATE TABLE project_has_files (
id SERIAL PRIMARY KEY,
project_id INTEGER NOT NULL,
name VARCHAR(255) NOT NULL,
path VARCHAR(255) NOT NULL,
is_image BOOLEAN DEFAULT '0',
size INTEGER DEFAULT 0 NOT NULL,
user_id INTEGER DEFAULT 0 NOT NULL,
date INTEGER DEFAULT 0 NOT NULL,
FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE
)"
);
}
function version_85(PDO $pdo) function version_85(PDO $pdo)
{ {
@@ -17,7 +36,7 @@ function version_84(PDO $pdo)
{ {
$pdo->exec(" $pdo->exec("
CREATE TABLE task_has_external_links ( CREATE TABLE task_has_external_links (
id SERIAL, id SERIAL PRIMARY KEY,
link_type VARCHAR(100) NOT NULL, link_type VARCHAR(100) NOT NULL,
dependency VARCHAR(100) NOT NULL, dependency VARCHAR(100) NOT NULL,
title VARCHAR(255) NOT NULL, title VARCHAR(255) NOT NULL,

View File

@@ -6,7 +6,26 @@ use Kanboard\Core\Security\Token;
use Kanboard\Core\Security\Role; use Kanboard\Core\Security\Role;
use PDO; use PDO;
const VERSION = 97; const VERSION = 98;
function version_98(PDO $pdo)
{
$pdo->exec('ALTER TABLE files RENAME TO task_has_files');
$pdo->exec("
CREATE TABLE project_has_files (
id INTEGER PRIMARY KEY,
project_id INTEGER NOT NULL,
name TEXT COLLATE NOCASE NOT NULL,
path TEXT NOT NULL,
is_image INTEGER DEFAULT 0,
size INTEGER DEFAULT 0 NOT NULL,
user_id INTEGER DEFAULT 0 NOT NULL,
date INTEGER DEFAULT 0 NOT NULL,
FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE
)"
);
}
function version_97(PDO $pdo) function version_97(PDO $pdo)
{ {

View File

@@ -31,7 +31,6 @@ class ClassProvider implements ServiceProviderInterface
'Config', 'Config',
'Currency', 'Currency',
'CustomFilter', 'CustomFilter',
'File',
'Group', 'Group',
'GroupMember', 'GroupMember',
'LastLogin', 'LastLogin',
@@ -40,6 +39,7 @@ class ClassProvider implements ServiceProviderInterface
'OverdueNotification', 'OverdueNotification',
'PasswordReset', 'PasswordReset',
'Project', 'Project',
'ProjectFile',
'ProjectActivity', 'ProjectActivity',
'ProjectDuplication', 'ProjectDuplication',
'ProjectDailyColumnStats', 'ProjectDailyColumnStats',
@@ -63,6 +63,7 @@ class ClassProvider implements ServiceProviderInterface
'TaskExport', 'TaskExport',
'TaskExternalLink', 'TaskExternalLink',
'TaskFinder', 'TaskFinder',
'TaskFile',
'TaskFilter', 'TaskFilter',
'TaskLink', 'TaskLink',
'TaskModification', 'TaskModification',

View File

@@ -6,7 +6,7 @@ use Kanboard\Event\GenericEvent;
use Kanboard\Model\Task; use Kanboard\Model\Task;
use Kanboard\Model\Comment; use Kanboard\Model\Comment;
use Kanboard\Model\Subtask; use Kanboard\Model\Subtask;
use Kanboard\Model\File; use Kanboard\Model\TaskFile;
use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class NotificationSubscriber extends BaseSubscriber implements EventSubscriberInterface class NotificationSubscriber extends BaseSubscriber implements EventSubscriberInterface
@@ -28,7 +28,7 @@ class NotificationSubscriber extends BaseSubscriber implements EventSubscriberIn
Comment::EVENT_CREATE => 'handleEvent', Comment::EVENT_CREATE => 'handleEvent',
Comment::EVENT_UPDATE => 'handleEvent', Comment::EVENT_UPDATE => 'handleEvent',
Comment::EVENT_USER_MENTION => 'handleEvent', Comment::EVENT_USER_MENTION => 'handleEvent',
File::EVENT_CREATE => 'handleEvent', TaskFile::EVENT_CREATE => 'handleEvent',
); );
} }

View File

@@ -1,7 +1,7 @@
API File Procedures API File Procedures
=================== ===================
## createFile ## createTaskFile
- Purpose: **Create and upload a new task attachment** - Purpose: **Create and upload a new task attachment**
- Parameters: - Parameters:
@@ -18,7 +18,7 @@ Request example:
```json ```json
{ {
"jsonrpc": "2.0", "jsonrpc": "2.0",
"method": "createFile", "method": "createTaskFile",
"id": 94500810, "id": 94500810,
"params": [ "params": [
1, 1,
@@ -39,7 +39,7 @@ Response example:
} }
``` ```
## getAllFiles ## getAllTaskFiles
- Purpose: **Get all files attached to task** - Purpose: **Get all files attached to task**
- Parameters: - Parameters:
@@ -52,7 +52,7 @@ Request example:
```json ```json
{ {
"jsonrpc": "2.0", "jsonrpc": "2.0",
"method": "getAllFiles", "method": "getAllTaskFiles",
"id": 1880662820, "id": 1880662820,
"params": { "params": {
"task_id": 1 "task_id": 1
@@ -83,7 +83,7 @@ Response example:
} }
``` ```
## getFile ## getTaskFile
- Purpose: **Get file information** - Purpose: **Get file information**
- Parameters: - Parameters:
@@ -96,7 +96,7 @@ Request example:
```json ```json
{ {
"jsonrpc": "2.0", "jsonrpc": "2.0",
"method": "getFile", "method": "getTaskFile",
"id": 318676852, "id": 318676852,
"params": [ "params": [
"1" "1"
@@ -123,7 +123,7 @@ Response example:
} }
``` ```
## downloadFile ## downloadTaskFile
- Purpose: **Download file contents (encoded in base64)** - Purpose: **Download file contents (encoded in base64)**
- Parameters: - Parameters:
@@ -136,7 +136,7 @@ Request example:
```json ```json
{ {
"jsonrpc": "2.0", "jsonrpc": "2.0",
"method": "downloadFile", "method": "downloadTaskFile",
"id": 235943344, "id": 235943344,
"params": [ "params": [
"1" "1"
@@ -154,7 +154,7 @@ Response example:
} }
``` ```
## removeFile ## removeTaskFile
- Purpose: **Remove file** - Purpose: **Remove file**
- Parameters: - Parameters:
@@ -167,7 +167,7 @@ Request example:
```json ```json
{ {
"jsonrpc": "2.0", "jsonrpc": "2.0",
"method": "removeFile", "method": "removeTaskFile",
"id": 447036524, "id": 447036524,
"params": [ "params": [
"1" "1"
@@ -185,7 +185,7 @@ Response example:
} }
``` ```
## removeAllFiles ## removeAllTaskFiles
- Purpose: **Remove all files associated to a task** - Purpose: **Remove all files associated to a task**
- Parameters: - Parameters:
@@ -198,7 +198,7 @@ Request example:
```json ```json
{ {
"jsonrpc": "2.0", "jsonrpc": "2.0",
"method": "removeAllFiles", "method": "removeAllTaskFiles",
"id": 593312993, "id": 593312993,
"params": { "params": {
"task_id": 1 "task_id": 1

View File

@@ -28,34 +28,26 @@ class AverageTimeSpentColumnAnalyticTest extends Base
$this->container['db']->table(Task::TABLE)->eq('id', 2)->update(array('date_completed' => $now + 1800)); $this->container['db']->table(Task::TABLE)->eq('id', 2)->update(array('date_completed' => $now + 1800));
$stats = $averageLeadCycleTimeAnalytic->build(1); $stats = $averageLeadCycleTimeAnalytic->build(1);
$expected = array(
1 => array(
'count' => 2,
'time_spent' => 3600+1800,
'average' => (int) ((3600+1800)/2),
'title' => 'Backlog',
),
2 => array(
'count' => 0,
'time_spent' => 0,
'average' => 0,
'title' => 'Ready',
),
3 => array(
'count' => 0,
'time_spent' => 0,
'average' => 0,
'title' => 'Work in progress',
),
4 => array(
'count' => 0,
'time_spent' => 0,
'average' => 0,
'title' => 'Done',
)
);
$this->assertEquals($expected, $stats); $this->assertEquals(2, $stats[1]['count']);
$this->assertEquals(3600+1800, $stats[1]['time_spent'], '', 3);
$this->assertEquals((int) ((3600+1800)/2), $stats[1]['average'], '', 3);
$this->assertEquals('Backlog', $stats[1]['title']);
$this->assertEquals(0, $stats[2]['count']);
$this->assertEquals(0, $stats[2]['time_spent'], '', 3);
$this->assertEquals(0, $stats[2]['average'], '', 3);
$this->assertEquals('Ready', $stats[2]['title']);
$this->assertEquals(0, $stats[3]['count']);
$this->assertEquals(0, $stats[3]['time_spent'], '', 3);
$this->assertEquals(0, $stats[3]['average'], '', 3);
$this->assertEquals('Work in progress', $stats[3]['title']);
$this->assertEquals(0, $stats[4]['count']);
$this->assertEquals(0, $stats[4]['time_spent'], '', 3);
$this->assertEquals(0, $stats[4]['average'], '', 3);
$this->assertEquals('Done', $stats[4]['title']);
} }
public function testAverageWithTransitions() public function testAverageWithTransitions()
@@ -85,33 +77,25 @@ class AverageTimeSpentColumnAnalyticTest extends Base
} }
$stats = $averageLeadCycleTimeAnalytic->build(1); $stats = $averageLeadCycleTimeAnalytic->build(1);
$expected = array(
1 => array(
'count' => 2,
'time_spent' => 3600+1800,
'average' => (int) ((3600+1800)/2),
'title' => 'Backlog',
),
2 => array(
'count' => 0,
'time_spent' => 0,
'average' => 0,
'title' => 'Ready',
),
3 => array(
'count' => 2,
'time_spent' => 1800,
'average' => 900,
'title' => 'Work in progress',
),
4 => array(
'count' => 0,
'time_spent' => 0,
'average' => 0,
'title' => 'Done',
)
);
$this->assertEquals($expected, $stats); $this->assertEquals(2, $stats[1]['count']);
$this->assertEquals(3600+1800, $stats[1]['time_spent'], '', 3);
$this->assertEquals((int) ((3600+1800)/2), $stats[1]['average'], '', 3);
$this->assertEquals('Backlog', $stats[1]['title']);
$this->assertEquals(0, $stats[2]['count']);
$this->assertEquals(0, $stats[2]['time_spent'], '', 3);
$this->assertEquals(0, $stats[2]['average'], '', 3);
$this->assertEquals('Ready', $stats[2]['title']);
$this->assertEquals(2, $stats[3]['count']);
$this->assertEquals(1800, $stats[3]['time_spent'], '', 3);
$this->assertEquals(900, $stats[3]['average'], '', 3);
$this->assertEquals('Work in progress', $stats[3]['title']);
$this->assertEquals(0, $stats[4]['count']);
$this->assertEquals(0, $stats[4]['time_spent'], '', 3);
$this->assertEquals(0, $stats[4]['average'], '', 3);
$this->assertEquals('Done', $stats[4]['title']);
} }
} }

View File

@@ -67,6 +67,12 @@ abstract class Base extends PHPUnit_Framework_TestCase
->setMethods(array('getType', 'getSelectedTypes')) ->setMethods(array('getType', 'getSelectedTypes'))
->getMock(); ->getMock();
$this->container['objectStorage'] = $this
->getMockBuilder('\Kanboard\Core\ObjectStorage\FileStorage')
->setConstructorArgs(array($this->container))
->setMethods(array('put', 'moveFile', 'remove', 'moveUploadedFile'))
->getMock();
$this->container['sessionStorage'] = new SessionStorage; $this->container['sessionStorage'] = new SessionStorage;
$this->container->register(new ActionProvider); $this->container->register(new ActionProvider);

View File

@@ -1,263 +0,0 @@
<?php
require_once __DIR__.'/../Base.php';
use Kanboard\Model\Task;
use Kanboard\Model\File;
use Kanboard\Model\TaskCreation;
use Kanboard\Model\Project;
class FileTest extends Base
{
public function setUp()
{
parent::setUp();
$this->container['objectStorage'] = $this
->getMockBuilder('\Kanboard\Core\ObjectStorage\FileStorage')
->setConstructorArgs(array($this->container))
->setMethods(array('put', 'moveFile', 'remove'))
->getMock();
}
public function testCreation()
{
$p = new Project($this->container);
$f = new File($this->container);
$tc = new TaskCreation($this->container);
$this->assertEquals(1, $p->create(array('name' => 'test')));
$this->assertEquals(1, $tc->create(array('project_id' => 1, 'title' => 'test')));
$this->assertEquals(1, $f->create(1, 'test', '/tmp/foo', 10));
$file = $f->getById(1);
$this->assertNotEmpty($file);
$this->assertEquals('test', $file['name']);
$this->assertEquals('/tmp/foo', $file['path']);
$this->assertEquals(0, $file['is_image']);
$this->assertEquals(1, $file['task_id']);
$this->assertEquals(time(), $file['date'], '', 2);
$this->assertEquals(0, $file['user_id']);
$this->assertEquals(10, $file['size']);
$this->assertEquals(2, $f->create(1, 'test2.png', '/tmp/foobar', 10));
$file = $f->getById(2);
$this->assertNotEmpty($file);
$this->assertEquals('test2.png', $file['name']);
$this->assertEquals('/tmp/foobar', $file['path']);
$this->assertEquals(1, $file['is_image']);
}
public function testCreationFileNameTooLong()
{
$p = new Project($this->container);
$f = new File($this->container);
$tc = new TaskCreation($this->container);
$this->assertEquals(1, $p->create(array('name' => 'test')));
$this->assertEquals(1, $tc->create(array('project_id' => 1, 'title' => 'test')));
$this->assertNotFalse($f->create(1, 'test', '/tmp/foo', 10));
$this->assertNotFalse($f->create(1, str_repeat('a', 1000), '/tmp/foo', 10));
$files = $f->getAll(1);
$this->assertNotEmpty($files);
$this->assertCount(2, $files);
$this->assertEquals(str_repeat('a', 255), $files[0]['name']);
$this->assertEquals('test', $files[1]['name']);
}
public function testIsImage()
{
$f = new File($this->container);
$this->assertTrue($f->isImage('test.png'));
$this->assertTrue($f->isImage('test.jpeg'));
$this->assertTrue($f->isImage('test.gif'));
$this->assertTrue($f->isImage('test.jpg'));
$this->assertTrue($f->isImage('test.JPG'));
$this->assertFalse($f->isImage('test.bmp'));
$this->assertFalse($f->isImage('test'));
$this->assertFalse($f->isImage('test.pdf'));
}
public function testGeneratePath()
{
$f = new File($this->container);
$this->assertStringStartsWith('12'.DIRECTORY_SEPARATOR.'34'.DIRECTORY_SEPARATOR, $f->generatePath(12, 34, 'test.png'));
$this->assertNotEquals($f->generatePath(12, 34, 'test1.png'), $f->generatePath(12, 34, 'test2.png'));
}
public function testUploadScreenshot()
{
$p = new Project($this->container);
$tc = new TaskCreation($this->container);
$this->assertEquals(1, $p->create(array('name' => 'test')));
$this->assertEquals(1, $tc->create(array('project_id' => 1, 'title' => 'test')));
$data = base64_encode('image data');
$f = $this
->getMockBuilder('\Kanboard\Model\File')
->setConstructorArgs(array($this->container))
->setMethods(array('generateThumbnailFromData'))
->getMock();
$this->container['objectStorage']
->expects($this->once())
->method('put')
->with(
$this->stringContains('1'.DIRECTORY_SEPARATOR.'1'.DIRECTORY_SEPARATOR),
$this->equalTo(base64_decode($data))
)
->will($this->returnValue(true));
$f->expects($this->once())
->method('generateThumbnailFromData');
$this->assertEquals(1, $f->uploadScreenshot(1, 1, $data));
$file = $f->getById(1);
$this->assertNotEmpty($file);
$this->assertStringStartsWith('Screenshot taken ', $file['name']);
$this->assertStringStartsWith('1'.DIRECTORY_SEPARATOR.'1'.DIRECTORY_SEPARATOR, $file['path']);
$this->assertEquals(1, $file['is_image']);
$this->assertEquals(1, $file['task_id']);
$this->assertEquals(time(), $file['date'], '', 2);
$this->assertEquals(0, $file['user_id']);
$this->assertEquals(10, $file['size']);
}
public function testUploadFileContent()
{
$p = new Project($this->container);
$f = new File($this->container);
$tc = new TaskCreation($this->container);
$this->assertEquals(1, $p->create(array('name' => 'test')));
$this->assertEquals(1, $tc->create(array('project_id' => 1, 'title' => 'test')));
$data = base64_encode('file data');
$this->container['objectStorage']
->expects($this->once())
->method('put')
->with(
$this->stringContains('1'.DIRECTORY_SEPARATOR.'1'.DIRECTORY_SEPARATOR),
$this->equalTo(base64_decode($data))
)
->will($this->returnValue(true));
$this->assertEquals(1, $f->uploadContent(1, 1, 'my file.pdf', $data));
$file = $f->getById(1);
$this->assertNotEmpty($file);
$this->assertEquals('my file.pdf', $file['name']);
$this->assertStringStartsWith('1'.DIRECTORY_SEPARATOR.'1'.DIRECTORY_SEPARATOR, $file['path']);
$this->assertEquals(0, $file['is_image']);
$this->assertEquals(1, $file['task_id']);
$this->assertEquals(time(), $file['date'], '', 2);
$this->assertEquals(0, $file['user_id']);
$this->assertEquals(9, $file['size']);
}
public function testGetAll()
{
$p = new Project($this->container);
$f = new File($this->container);
$tc = new TaskCreation($this->container);
$this->assertEquals(1, $p->create(array('name' => 'test')));
$this->assertEquals(1, $tc->create(array('project_id' => 1, 'title' => 'test')));
$this->assertEquals(1, $f->create(1, 'B.pdf', '/tmp/foo', 10));
$this->assertEquals(2, $f->create(1, 'A.png', '/tmp/foo', 10));
$this->assertEquals(3, $f->create(1, 'D.doc', '/tmp/foo', 10));
$this->assertEquals(4, $f->create(1, 'C.JPG', '/tmp/foo', 10));
$files = $f->getAll(1);
$this->assertNotEmpty($files);
$this->assertCount(4, $files);
$this->assertEquals('A.png', $files[0]['name']);
$this->assertEquals('B.pdf', $files[1]['name']);
$this->assertEquals('C.JPG', $files[2]['name']);
$this->assertEquals('D.doc', $files[3]['name']);
$files = $f->getAllImages(1);
$this->assertNotEmpty($files);
$this->assertCount(2, $files);
$this->assertEquals('A.png', $files[0]['name']);
$this->assertEquals('C.JPG', $files[1]['name']);
$files = $f->getAllDocuments(1);
$this->assertNotEmpty($files);
$this->assertCount(2, $files);
$this->assertEquals('B.pdf', $files[0]['name']);
$this->assertEquals('D.doc', $files[1]['name']);
}
public function testRemove()
{
$p = new Project($this->container);
$f = new File($this->container);
$tc = new TaskCreation($this->container);
$this->assertEquals(1, $p->create(array('name' => 'test')));
$this->assertEquals(1, $tc->create(array('project_id' => 1, 'title' => 'test')));
$this->assertEquals(1, $f->create(1, 'B.pdf', DIRECTORY_SEPARATOR.'tmp'.DIRECTORY_SEPARATOR.'foo1', 10));
$this->assertEquals(2, $f->create(1, 'A.png', DIRECTORY_SEPARATOR.'tmp'.DIRECTORY_SEPARATOR.'foo2', 10));
$this->assertEquals(3, $f->create(1, 'D.doc', DIRECTORY_SEPARATOR.'tmp'.DIRECTORY_SEPARATOR.'foo3', 10));
$this->container['objectStorage']
->expects($this->at(0))
->method('remove')
->with(
$this->equalTo(DIRECTORY_SEPARATOR.'tmp'.DIRECTORY_SEPARATOR.'foo2')
)
->will($this->returnValue(true));
$this->container['objectStorage']
->expects($this->at(1))
->method('remove')
->with(
$this->equalTo('thumbnails'.DIRECTORY_SEPARATOR.DIRECTORY_SEPARATOR.'tmp'.DIRECTORY_SEPARATOR.'foo2')
)
->will($this->returnValue(true));
$this->container['objectStorage']
->expects($this->at(2))
->method('remove')
->with(
$this->equalTo(DIRECTORY_SEPARATOR.'tmp'.DIRECTORY_SEPARATOR.'foo1')
)
->will($this->returnValue(true));
$this->container['objectStorage']
->expects($this->at(3))
->method('remove')
->with(
$this->equalTo(DIRECTORY_SEPARATOR.'tmp'.DIRECTORY_SEPARATOR.'foo3')
)
->will($this->returnValue(true));
$this->assertTrue($f->remove(2));
$files = $f->getAll(1);
$this->assertNotEmpty($files);
$this->assertCount(2, $files);
$this->assertEquals('B.pdf', $files[0]['name']);
$this->assertEquals('D.doc', $files[1]['name']);
$this->assertTrue($f->removeAll(1));
$files = $f->getAll(1);
$this->assertEmpty($files);
}
}

View File

@@ -7,7 +7,7 @@ use Kanboard\Model\TaskCreation;
use Kanboard\Model\Subtask; use Kanboard\Model\Subtask;
use Kanboard\Model\Comment; use Kanboard\Model\Comment;
use Kanboard\Model\User; use Kanboard\Model\User;
use Kanboard\Model\File; use Kanboard\Model\TaskFile;
use Kanboard\Model\Task; use Kanboard\Model\Task;
use Kanboard\Model\Project; use Kanboard\Model\Project;
use Kanboard\Model\Notification; use Kanboard\Model\Notification;
@@ -23,7 +23,7 @@ class NotificationTest extends Base
$tc = new TaskCreation($this->container); $tc = new TaskCreation($this->container);
$s = new Subtask($this->container); $s = new Subtask($this->container);
$c = new Comment($this->container); $c = new Comment($this->container);
$f = new File($this->container); $f = new TaskFile($this->container);
$this->assertEquals(1, $p->create(array('name' => 'test'))); $this->assertEquals(1, $p->create(array('name' => 'test')));
$this->assertEquals(1, $tc->create(array('title' => 'test', 'project_id' => 1))); $this->assertEquals(1, $tc->create(array('title' => 'test', 'project_id' => 1)));

View File

@@ -9,7 +9,6 @@ use Kanboard\Model\ProjectActivity;
use Kanboard\Model\Project; use Kanboard\Model\Project;
use Kanboard\Model\Subtask; use Kanboard\Model\Subtask;
use Kanboard\Model\Comment; use Kanboard\Model\Comment;
use Kanboard\Model\File;
class ProjectActivityTest extends Base class ProjectActivityTest extends Base
{ {

View File

@@ -0,0 +1,311 @@
<?php
require_once __DIR__.'/../Base.php';
use Kanboard\Model\ProjectFile;
use Kanboard\Model\Project;
class ProjectFileTest extends Base
{
public function testCreation()
{
$projectModel = new Project($this->container);
$fileModel = new ProjectFile($this->container);
$this->assertEquals(1, $projectModel->create(array('name' => 'test')));
$this->assertEquals(1, $fileModel->create(1, 'test', '/tmp/foo', 10));
$file = $fileModel->getById(1);
$this->assertEquals('test', $file['name']);
$this->assertEquals('/tmp/foo', $file['path']);
$this->assertEquals(0, $file['is_image']);
$this->assertEquals(1, $file['project_id']);
$this->assertEquals(time(), $file['date'], '', 2);
$this->assertEquals(0, $file['user_id']);
$this->assertEquals(10, $file['size']);
$this->assertEquals(2, $fileModel->create(1, 'test2.png', '/tmp/foobar', 10));
$file = $fileModel->getById(2);
$this->assertEquals('test2.png', $file['name']);
$this->assertEquals('/tmp/foobar', $file['path']);
$this->assertEquals(1, $file['is_image']);
}
public function testCreationWithFileNameTooLong()
{
$projectModel = new Project($this->container);
$fileModel = new ProjectFile($this->container);
$this->assertEquals(1, $projectModel->create(array('name' => 'test')));
$this->assertNotFalse($fileModel->create(1, 'test', '/tmp/foo', 10));
$this->assertNotFalse($fileModel->create(1, str_repeat('a', 1000), '/tmp/foo', 10));
$files = $fileModel->getAll(1);
$this->assertNotEmpty($files);
$this->assertCount(2, $files);
$this->assertEquals(str_repeat('a', 255), $files[0]['name']);
$this->assertEquals('test', $files[1]['name']);
}
public function testCreationWithSessionOpen()
{
$this->container['sessionStorage']->user = array('id' => 1);
$projectModel = new Project($this->container);
$fileModel = new ProjectFile($this->container);
$this->assertEquals(1, $projectModel->create(array('name' => 'test')));
$this->assertEquals(1, $fileModel->create(1, 'test', '/tmp/foo', 10));
$file = $fileModel->getById(1);
$this->assertEquals('test', $file['name']);
$this->assertEquals(1, $file['user_id']);
}
public function testGetAll()
{
$projectModel = new Project($this->container);
$fileModel = new ProjectFile($this->container);
$this->assertEquals(1, $projectModel->create(array('name' => 'test')));
$this->assertEquals(1, $fileModel->create(1, 'B.pdf', '/tmp/foo', 10));
$this->assertEquals(2, $fileModel->create(1, 'A.png', '/tmp/foo', 10));
$this->assertEquals(3, $fileModel->create(1, 'D.doc', '/tmp/foo', 10));
$this->assertEquals(4, $fileModel->create(1, 'C.JPG', '/tmp/foo', 10));
$fileModeliles = $fileModel->getAll(1);
$this->assertNotEmpty($fileModeliles);
$this->assertCount(4, $fileModeliles);
$this->assertEquals('A.png', $fileModeliles[0]['name']);
$this->assertEquals('B.pdf', $fileModeliles[1]['name']);
$this->assertEquals('C.JPG', $fileModeliles[2]['name']);
$this->assertEquals('D.doc', $fileModeliles[3]['name']);
$fileModeliles = $fileModel->getAllImages(1);
$this->assertNotEmpty($fileModeliles);
$this->assertCount(2, $fileModeliles);
$this->assertEquals('A.png', $fileModeliles[0]['name']);
$this->assertEquals('C.JPG', $fileModeliles[1]['name']);
$fileModeliles = $fileModel->getAllDocuments(1);
$this->assertNotEmpty($fileModeliles);
$this->assertCount(2, $fileModeliles);
$this->assertEquals('B.pdf', $fileModeliles[0]['name']);
$this->assertEquals('D.doc', $fileModeliles[1]['name']);
}
public function testGetThumbnailPath()
{
$fileModel = new ProjectFile($this->container);
$this->assertEquals('thumbnails'.DIRECTORY_SEPARATOR.'test', $fileModel->getThumbnailPath('test'));
}
public function testGeneratePath()
{
$fileModel = new ProjectFile($this->container);
$this->assertStringStartsWith('projects'.DIRECTORY_SEPARATOR.'34'.DIRECTORY_SEPARATOR, $fileModel->generatePath(34, 'test.png'));
$this->assertNotEquals($fileModel->generatePath(34, 'test1.png'), $fileModel->generatePath(34, 'test2.png'));
}
public function testUploadFiles()
{
$fileModel = $this
->getMockBuilder('\Kanboard\Model\ProjectFile')
->setConstructorArgs(array($this->container))
->setMethods(array('generateThumbnailFromFile'))
->getMock();
$projectModel = new Project($this->container);
$this->assertEquals(1, $projectModel->create(array('name' => 'test')));
$files = array(
'name' => array(
'file1.png',
'file2.doc',
),
'tmp_name' => array(
'/tmp/phpYzdqkD',
'/tmp/phpeEwEWG',
),
'error' => array(
UPLOAD_ERR_OK,
UPLOAD_ERR_OK,
),
'size' => array(
123,
456,
),
);
$fileModel
->expects($this->once())
->method('generateThumbnailFromFile');
$this->container['objectStorage']
->expects($this->at(0))
->method('moveUploadedFile')
->with($this->equalTo('/tmp/phpYzdqkD'), $this->anything());
$this->container['objectStorage']
->expects($this->at(1))
->method('moveUploadedFile')
->with($this->equalTo('/tmp/phpeEwEWG'), $this->anything());
$this->assertTrue($fileModel->uploadFiles(1, $files));
$files = $fileModel->getAll(1);
$this->assertCount(2, $files);
$this->assertEquals(1, $files[0]['id']);
$this->assertEquals('file1.png', $files[0]['name']);
$this->assertEquals(1, $files[0]['is_image']);
$this->assertEquals(1, $files[0]['project_id']);
$this->assertEquals(0, $files[0]['user_id']);
$this->assertEquals(123, $files[0]['size']);
$this->assertEquals(time(), $files[0]['date'], '', 2);
$this->assertEquals(2, $files[1]['id']);
$this->assertEquals('file2.doc', $files[1]['name']);
$this->assertEquals(0, $files[1]['is_image']);
$this->assertEquals(1, $files[1]['project_id']);
$this->assertEquals(0, $files[1]['user_id']);
$this->assertEquals(456, $files[1]['size']);
$this->assertEquals(time(), $files[1]['date'], '', 2);
}
public function testUploadFilesWithEmptyFiles()
{
$fileModel = new ProjectFile($this->container);
$this->assertFalse($fileModel->uploadFiles(1, array()));
}
public function testUploadFilesWithUploadError()
{
$files = array(
'name' => array(
'file1.png',
'file2.doc',
),
'tmp_name' => array(
'',
'/tmp/phpeEwEWG',
),
'error' => array(
UPLOAD_ERR_CANT_WRITE,
UPLOAD_ERR_OK,
),
'size' => array(
123,
456,
),
);
$fileModel = new ProjectFile($this->container);
$this->assertFalse($fileModel->uploadFiles(1, $files));
}
public function testUploadFilesWithObjectStorageError()
{
$files = array(
'name' => array(
'file1.csv',
'file2.doc',
),
'tmp_name' => array(
'/tmp/phpYzdqkD',
'/tmp/phpeEwEWG',
),
'error' => array(
UPLOAD_ERR_OK,
UPLOAD_ERR_OK,
),
'size' => array(
123,
456,
),
);
$this->container['objectStorage']
->expects($this->at(0))
->method('moveUploadedFile')
->with($this->equalTo('/tmp/phpYzdqkD'), $this->anything())
->will($this->throwException(new \Kanboard\Core\ObjectStorage\ObjectStorageException('test')));
$fileModel = new ProjectFile($this->container);
$this->assertFalse($fileModel->uploadFiles(1, $files));
}
public function testUploadFileContent()
{
$fileModel = $this
->getMockBuilder('\Kanboard\Model\ProjectFile')
->setConstructorArgs(array($this->container))
->setMethods(array('generateThumbnailFromFile'))
->getMock();
$projectModel = new Project($this->container);
$data = 'test';
$this->assertEquals(1, $projectModel->create(array('name' => 'test')));
$this->container['objectStorage']
->expects($this->once())
->method('put')
->with($this->anything(), $this->equalTo($data));
$this->assertEquals(1, $fileModel->uploadContent(1, 'test.doc', base64_encode($data)));
$files = $fileModel->getAll(1);
$this->assertCount(1, $files);
$this->assertEquals(1, $files[0]['id']);
$this->assertEquals('test.doc', $files[0]['name']);
$this->assertEquals(0, $files[0]['is_image']);
$this->assertEquals(1, $files[0]['project_id']);
$this->assertEquals(0, $files[0]['user_id']);
$this->assertEquals(4, $files[0]['size']);
$this->assertEquals(time(), $files[0]['date'], '', 2);
}
public function testUploadImageContent()
{
$fileModel = $this
->getMockBuilder('\Kanboard\Model\ProjectFile')
->setConstructorArgs(array($this->container))
->setMethods(array('generateThumbnailFromFile'))
->getMock();
$projectModel = new Project($this->container);
$data = 'test';
$this->assertEquals(1, $projectModel->create(array('name' => 'test')));
$fileModel
->expects($this->once())
->method('generateThumbnailFromFile');
$this->container['objectStorage']
->expects($this->once())
->method('put')
->with($this->anything(), $this->equalTo($data));
$this->assertEquals(1, $fileModel->uploadContent(1, 'test.png', base64_encode($data)));
$files = $fileModel->getAll(1);
$this->assertCount(1, $files);
$this->assertEquals(1, $files[0]['id']);
$this->assertEquals('test.png', $files[0]['name']);
$this->assertEquals(1, $files[0]['is_image']);
$this->assertEquals(1, $files[0]['project_id']);
$this->assertEquals(0, $files[0]['user_id']);
$this->assertEquals(4, $files[0]['size']);
$this->assertEquals(time(), $files[0]['date'], '', 2);
}
}

View File

@@ -0,0 +1,458 @@
<?php
require_once __DIR__.'/../Base.php';
use Kanboard\Model\Task;
use Kanboard\Model\TaskFile;
use Kanboard\Model\TaskCreation;
use Kanboard\Model\Project;
class TaskFileTest extends Base
{
public function testCreation()
{
$projectModel = new Project($this->container);
$fileModel = new TaskFile($this->container);
$taskCreationModel = new TaskCreation($this->container);
$this->assertEquals(1, $projectModel->create(array('name' => 'test')));
$this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test')));
$this->assertEquals(1, $fileModel->create(1, 'test', '/tmp/foo', 10));
$file = $fileModel->getById(1);
$this->assertEquals('test', $file['name']);
$this->assertEquals('/tmp/foo', $file['path']);
$this->assertEquals(0, $file['is_image']);
$this->assertEquals(1, $file['task_id']);
$this->assertEquals(time(), $file['date'], '', 2);
$this->assertEquals(0, $file['user_id']);
$this->assertEquals(10, $file['size']);
$this->assertEquals(2, $fileModel->create(1, 'test2.png', '/tmp/foobar', 10));
$file = $fileModel->getById(2);
$this->assertEquals('test2.png', $file['name']);
$this->assertEquals('/tmp/foobar', $file['path']);
$this->assertEquals(1, $file['is_image']);
}
public function testCreationWithFileNameTooLong()
{
$projectModel = new Project($this->container);
$fileModel = new TaskFile($this->container);
$taskCreationModel = new TaskCreation($this->container);
$this->assertEquals(1, $projectModel->create(array('name' => 'test')));
$this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test')));
$this->assertNotFalse($fileModel->create(1, 'test', '/tmp/foo', 10));
$this->assertNotFalse($fileModel->create(1, str_repeat('a', 1000), '/tmp/foo', 10));
$files = $fileModel->getAll(1);
$this->assertNotEmpty($files);
$this->assertCount(2, $files);
$this->assertEquals(str_repeat('a', 255), $files[0]['name']);
$this->assertEquals('test', $files[1]['name']);
}
public function testCreationWithSessionOpen()
{
$this->container['sessionStorage']->user = array('id' => 1);
$projectModel = new Project($this->container);
$fileModel = new TaskFile($this->container);
$taskCreationModel = new TaskCreation($this->container);
$this->assertEquals(1, $projectModel->create(array('name' => 'test')));
$this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test')));
$this->assertEquals(1, $fileModel->create(1, 'test', '/tmp/foo', 10));
$file = $fileModel->getById(1);
$this->assertEquals('test', $file['name']);
$this->assertEquals(1, $file['user_id']);
}
public function testGetAll()
{
$projectModel = new Project($this->container);
$fileModel = new TaskFile($this->container);
$taskCreationModel = new TaskCreation($this->container);
$this->assertEquals(1, $projectModel->create(array('name' => 'test')));
$this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test')));
$this->assertEquals(1, $fileModel->create(1, 'B.pdf', '/tmp/foo', 10));
$this->assertEquals(2, $fileModel->create(1, 'A.png', '/tmp/foo', 10));
$this->assertEquals(3, $fileModel->create(1, 'D.doc', '/tmp/foo', 10));
$this->assertEquals(4, $fileModel->create(1, 'C.JPG', '/tmp/foo', 10));
$fileModeliles = $fileModel->getAll(1);
$this->assertNotEmpty($fileModeliles);
$this->assertCount(4, $fileModeliles);
$this->assertEquals('A.png', $fileModeliles[0]['name']);
$this->assertEquals('B.pdf', $fileModeliles[1]['name']);
$this->assertEquals('C.JPG', $fileModeliles[2]['name']);
$this->assertEquals('D.doc', $fileModeliles[3]['name']);
$fileModeliles = $fileModel->getAllImages(1);
$this->assertNotEmpty($fileModeliles);
$this->assertCount(2, $fileModeliles);
$this->assertEquals('A.png', $fileModeliles[0]['name']);
$this->assertEquals('C.JPG', $fileModeliles[1]['name']);
$fileModeliles = $fileModel->getAllDocuments(1);
$this->assertNotEmpty($fileModeliles);
$this->assertCount(2, $fileModeliles);
$this->assertEquals('B.pdf', $fileModeliles[0]['name']);
$this->assertEquals('D.doc', $fileModeliles[1]['name']);
}
public function testIsImage()
{
$fileModel = new TaskFile($this->container);
$this->assertTrue($fileModel->isImage('test.png'));
$this->assertTrue($fileModel->isImage('test.jpeg'));
$this->assertTrue($fileModel->isImage('test.gif'));
$this->assertTrue($fileModel->isImage('test.jpg'));
$this->assertTrue($fileModel->isImage('test.JPG'));
$this->assertFalse($fileModel->isImage('test.bmp'));
$this->assertFalse($fileModel->isImage('test'));
$this->assertFalse($fileModel->isImage('test.pdf'));
}
public function testGetMimeType()
{
$fileModel = new TaskFile($this->container);
$this->assertEquals('image/jpeg', $fileModel->getImageMimeType('My File.JPG'));
$this->assertEquals('image/jpeg', $fileModel->getImageMimeType('My File.jpeg'));
$this->assertEquals('image/png', $fileModel->getImageMimeType('My File.PNG'));
$this->assertEquals('image/gif', $fileModel->getImageMimeType('My File.gif'));
$this->assertEquals('image/jpeg', $fileModel->getImageMimeType('My File.bmp'));
$this->assertEquals('image/jpeg', $fileModel->getImageMimeType('My File'));
}
public function testGetThumbnailPath()
{
$fileModel = new TaskFile($this->container);
$this->assertEquals('thumbnails'.DIRECTORY_SEPARATOR.'test', $fileModel->getThumbnailPath('test'));
}
public function testGeneratePath()
{
$fileModel = new TaskFile($this->container);
$this->assertStringStartsWith('tasks'.DIRECTORY_SEPARATOR.'34'.DIRECTORY_SEPARATOR, $fileModel->generatePath(34, 'test.png'));
$this->assertNotEquals($fileModel->generatePath(34, 'test1.png'), $fileModel->generatePath(34, 'test2.png'));
}
public function testUploadFiles()
{
$fileModel = $this
->getMockBuilder('\Kanboard\Model\TaskFile')
->setConstructorArgs(array($this->container))
->setMethods(array('generateThumbnailFromFile'))
->getMock();
$projectModel = new Project($this->container);
$taskCreationModel = new TaskCreation($this->container);
$this->assertEquals(1, $projectModel->create(array('name' => 'test')));
$this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test')));
$files = array(
'name' => array(
'file1.png',
'file2.doc',
),
'tmp_name' => array(
'/tmp/phpYzdqkD',
'/tmp/phpeEwEWG',
),
'error' => array(
UPLOAD_ERR_OK,
UPLOAD_ERR_OK,
),
'size' => array(
123,
456,
),
);
$fileModel
->expects($this->once())
->method('generateThumbnailFromFile');
$this->container['objectStorage']
->expects($this->at(0))
->method('moveUploadedFile')
->with($this->equalTo('/tmp/phpYzdqkD'), $this->anything());
$this->container['objectStorage']
->expects($this->at(1))
->method('moveUploadedFile')
->with($this->equalTo('/tmp/phpeEwEWG'), $this->anything());
$this->assertTrue($fileModel->uploadFiles(1, $files));
$files = $fileModel->getAll(1);
$this->assertCount(2, $files);
$this->assertEquals(1, $files[0]['id']);
$this->assertEquals('file1.png', $files[0]['name']);
$this->assertEquals(1, $files[0]['is_image']);
$this->assertEquals(1, $files[0]['task_id']);
$this->assertEquals(0, $files[0]['user_id']);
$this->assertEquals(123, $files[0]['size']);
$this->assertEquals(time(), $files[0]['date'], '', 2);
$this->assertEquals(2, $files[1]['id']);
$this->assertEquals('file2.doc', $files[1]['name']);
$this->assertEquals(0, $files[1]['is_image']);
$this->assertEquals(1, $files[1]['task_id']);
$this->assertEquals(0, $files[1]['user_id']);
$this->assertEquals(456, $files[1]['size']);
$this->assertEquals(time(), $files[1]['date'], '', 2);
}
public function testUploadFilesWithEmptyFiles()
{
$fileModel = new TaskFile($this->container);
$this->assertFalse($fileModel->uploadFiles(1, array()));
}
public function testUploadFilesWithUploadError()
{
$files = array(
'name' => array(
'file1.png',
'file2.doc',
),
'tmp_name' => array(
'',
'/tmp/phpeEwEWG',
),
'error' => array(
UPLOAD_ERR_CANT_WRITE,
UPLOAD_ERR_OK,
),
'size' => array(
123,
456,
),
);
$fileModel = new TaskFile($this->container);
$this->assertFalse($fileModel->uploadFiles(1, $files));
}
public function testUploadFilesWithObjectStorageError()
{
$files = array(
'name' => array(
'file1.csv',
'file2.doc',
),
'tmp_name' => array(
'/tmp/phpYzdqkD',
'/tmp/phpeEwEWG',
),
'error' => array(
UPLOAD_ERR_OK,
UPLOAD_ERR_OK,
),
'size' => array(
123,
456,
),
);
$this->container['objectStorage']
->expects($this->at(0))
->method('moveUploadedFile')
->with($this->equalTo('/tmp/phpYzdqkD'), $this->anything())
->will($this->throwException(new \Kanboard\Core\ObjectStorage\ObjectStorageException('test')));
$fileModel = new TaskFile($this->container);
$this->assertFalse($fileModel->uploadFiles(1, $files));
}
public function testUploadFileContent()
{
$fileModel = $this
->getMockBuilder('\Kanboard\Model\TaskFile')
->setConstructorArgs(array($this->container))
->setMethods(array('generateThumbnailFromFile'))
->getMock();
$projectModel = new Project($this->container);
$taskCreationModel = new TaskCreation($this->container);
$data = 'test';
$this->assertEquals(1, $projectModel->create(array('name' => 'test')));
$this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test')));
$this->container['objectStorage']
->expects($this->once())
->method('put')
->with($this->anything(), $this->equalTo($data));
$this->assertEquals(1, $fileModel->uploadContent(1, 'test.doc', base64_encode($data)));
$files = $fileModel->getAll(1);
$this->assertCount(1, $files);
$this->assertEquals(1, $files[0]['id']);
$this->assertEquals('test.doc', $files[0]['name']);
$this->assertEquals(0, $files[0]['is_image']);
$this->assertEquals(1, $files[0]['task_id']);
$this->assertEquals(0, $files[0]['user_id']);
$this->assertEquals(4, $files[0]['size']);
$this->assertEquals(time(), $files[0]['date'], '', 2);
}
public function testUploadFileContentWithObjectStorageError()
{
$fileModel = $this
->getMockBuilder('\Kanboard\Model\TaskFile')
->setConstructorArgs(array($this->container))
->setMethods(array('generateThumbnailFromFile'))
->getMock();
$projectModel = new Project($this->container);
$taskCreationModel = new TaskCreation($this->container);
$data = 'test';
$this->assertEquals(1, $projectModel->create(array('name' => 'test')));
$this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test')));
$this->container['objectStorage']
->expects($this->once())
->method('put')
->with($this->anything(), $this->equalTo($data))
->will($this->throwException(new \Kanboard\Core\ObjectStorage\ObjectStorageException('test')));
$this->assertFalse($fileModel->uploadContent(1, 'test.doc', base64_encode($data)));
}
public function testUploadScreenshot()
{
$fileModel = $this
->getMockBuilder('\Kanboard\Model\TaskFile')
->setConstructorArgs(array($this->container))
->setMethods(array('generateThumbnailFromFile'))
->getMock();
$projectModel = new Project($this->container);
$taskCreationModel = new TaskCreation($this->container);
$data = 'test';
$this->assertEquals(1, $projectModel->create(array('name' => 'test')));
$this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test')));
$fileModel
->expects($this->once())
->method('generateThumbnailFromFile');
$this->container['objectStorage']
->expects($this->once())
->method('put')
->with($this->anything(), $this->equalTo($data));
$this->assertEquals(1, $fileModel->uploadScreenshot(1, base64_encode($data)));
$files = $fileModel->getAll(1);
$this->assertCount(1, $files);
$this->assertEquals(1, $files[0]['id']);
$this->assertStringStartsWith('Screenshot taken ', $files[0]['name']);
$this->assertEquals(1, $files[0]['is_image']);
$this->assertEquals(1, $files[0]['task_id']);
$this->assertEquals(0, $files[0]['user_id']);
$this->assertEquals(4, $files[0]['size']);
$this->assertEquals(time(), $files[0]['date'], '', 2);
}
public function testRemove()
{
$fileModel = new TaskFile($this->container);
$projectModel = new Project($this->container);
$taskCreationModel = new TaskCreation($this->container);
$this->assertEquals(1, $projectModel->create(array('name' => 'test')));
$this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test')));
$this->assertEquals(1, $fileModel->create(1, 'test', 'tmp/foo', 10));
$this->container['objectStorage']
->expects($this->once())
->method('remove')
->with('tmp/foo');
$this->assertTrue($fileModel->remove(1));
}
public function testRemoveWithObjectStorageError()
{
$fileModel = new TaskFile($this->container);
$projectModel = new Project($this->container);
$taskCreationModel = new TaskCreation($this->container);
$this->assertEquals(1, $projectModel->create(array('name' => 'test')));
$this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test')));
$this->assertEquals(1, $fileModel->create(1, 'test', 'tmp/foo', 10));
$this->container['objectStorage']
->expects($this->once())
->method('remove')
->with('tmp/foo')
->will($this->throwException(new \Kanboard\Core\ObjectStorage\ObjectStorageException('test')));
$this->assertFalse($fileModel->remove(1));
}
public function testRemoveImage()
{
$fileModel = new TaskFile($this->container);
$projectModel = new Project($this->container);
$taskCreationModel = new TaskCreation($this->container);
$this->assertEquals(1, $projectModel->create(array('name' => 'test')));
$this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test')));
$this->assertEquals(1, $fileModel->create(1, 'image.gif', 'tmp/image.gif', 10));
$this->container['objectStorage']
->expects($this->at(0))
->method('remove')
->with('tmp/image.gif');
$this->container['objectStorage']
->expects($this->at(1))
->method('remove')
->with('thumbnails'.DIRECTORY_SEPARATOR.'tmp/image.gif');
$this->assertTrue($fileModel->remove(1));
}
public function testRemoveAll()
{
$fileModel = new TaskFile($this->container);
$projectModel = new Project($this->container);
$taskCreationModel = new TaskCreation($this->container);
$this->assertEquals(1, $projectModel->create(array('name' => 'test')));
$this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test')));
$this->assertEquals(1, $fileModel->create(1, 'test', 'tmp/foo', 10));
$this->assertEquals(2, $fileModel->create(1, 'test', 'tmp/foo', 10));
$this->container['objectStorage']
->expects($this->exactly(2))
->method('remove')
->with('tmp/foo');
$this->assertTrue($fileModel->removeAll(1));
}
}

View File

@@ -9,7 +9,6 @@ use Kanboard\Model\Comment;
use Kanboard\Model\User; use Kanboard\Model\User;
use Kanboard\Model\Group; use Kanboard\Model\Group;
use Kanboard\Model\GroupMember; use Kanboard\Model\GroupMember;
use Kanboard\Model\File;
use Kanboard\Model\Project; use Kanboard\Model\Project;
use Kanboard\Model\ProjectPermission; use Kanboard\Model\ProjectPermission;
use Kanboard\Model\Task; use Kanboard\Model\Task;

View File

@@ -7,7 +7,6 @@ use Kanboard\Model\TaskCreation;
use Kanboard\Model\Subtask; use Kanboard\Model\Subtask;
use Kanboard\Model\Comment; use Kanboard\Model\Comment;
use Kanboard\Model\User; use Kanboard\Model\User;
use Kanboard\Model\File;
use Kanboard\Model\Task; use Kanboard\Model\Task;
use Kanboard\Model\Project; use Kanboard\Model\Project;
use Kanboard\Model\UserUnreadNotification; use Kanboard\Model\UserUnreadNotification;

View File

@@ -7,7 +7,7 @@ use Kanboard\Model\TaskCreation;
use Kanboard\Model\Subtask; use Kanboard\Model\Subtask;
use Kanboard\Model\Comment; use Kanboard\Model\Comment;
use Kanboard\Model\User; use Kanboard\Model\User;
use Kanboard\Model\File; use Kanboard\Model\TaskFile;
use Kanboard\Model\Project; use Kanboard\Model\Project;
use Kanboard\Model\Task; use Kanboard\Model\Task;
use Kanboard\Notification\Mail; use Kanboard\Notification\Mail;
@@ -23,7 +23,7 @@ class MailTest extends Base
$tc = new TaskCreation($this->container); $tc = new TaskCreation($this->container);
$s = new Subtask($this->container); $s = new Subtask($this->container);
$c = new Comment($this->container); $c = new Comment($this->container);
$f = new File($this->container); $f = new TaskFile($this->container);
$this->assertEquals(1, $p->create(array('name' => 'test'))); $this->assertEquals(1, $p->create(array('name' => 'test')));
$this->assertEquals(1, $tc->create(array('title' => 'test', 'project_id' => 1))); $this->assertEquals(1, $tc->create(array('title' => 'test', 'project_id' => 1)));