diff options
author | Frédéric Guillot <fred@kanboard.net> | 2014-05-22 20:58:21 -0400 |
---|---|---|
committer | Frédéric Guillot <fred@kanboard.net> | 2014-05-22 20:58:21 -0400 |
commit | 40917992e775bd21a280eb267241c452e04e5ade (patch) | |
tree | c1bf82ab83564bc9ca749f026f54342cbd35374f /app/Model | |
parent | 2230dd4e6b148346c0ec596b9e3e12996a762ed8 (diff) |
Add files upload
Diffstat (limited to 'app/Model')
-rw-r--r-- | app/Model/Acl.php | 23 | ||||
-rw-r--r-- | app/Model/File.php | 176 | ||||
-rw-r--r-- | app/Model/Task.php | 1 |
3 files changed, 199 insertions, 1 deletions
diff --git a/app/Model/Acl.php b/app/Model/Acl.php index ad2118f4..be32196a 100644 --- a/app/Model/Acl.php +++ b/app/Model/Acl.php @@ -32,10 +32,31 @@ class Acl extends Base 'app' => array('index'), 'board' => array('index', 'show', 'assign', 'assigntask', 'save', 'check'), 'project' => array('tasks', 'index', 'forbidden', 'search'), - 'task' => array('show', 'create', 'save', 'edit', 'update', 'close', 'confirmclose', 'open', 'confirmopen', 'description', 'duplicate', 'remove', 'confirmremove'), 'comment' => array('save', 'confirm', 'remove', 'update', 'edit'), 'user' => array('index', 'edit', 'update', 'forbidden', 'logout', 'index', 'unlinkgoogle'), 'config' => array('index', 'removeremembermetoken'), + 'task' => array( + 'show', + 'create', + 'save', + 'edit', + 'update', + 'close', + 'confirmclose', + 'open', + 'confirmopen', + 'description', + 'duplicate', + 'remove', + 'confirmremove', + 'file', + 'upload', + 'download', + 'openfile', + 'image', + 'removefile', + 'confirmremovefile', + ), ); /** diff --git a/app/Model/File.php b/app/Model/File.php new file mode 100644 index 00000000..1e2e1432 --- /dev/null +++ b/app/Model/File.php @@ -0,0 +1,176 @@ +<?php + +namespace Model; + +use SimpleValidator\Validator; +use SimpleValidator\Validators; + +/** + * File model + * + * @package model + * @author Frederic Guillot + */ +class File extends Base +{ + /** + * SQL table name + * + * @var string + */ + const TABLE = 'task_has_files'; + + /** + * Directory where are stored files + * + * @var string + */ + const BASE_PATH = 'data/files/'; + + /** + * Get a file by the id + * + * @access public + * @param integer $file_id File id + * @return array + */ + public function getById($file_id) + { + return $this->db->table(self::TABLE)->eq('id', $file_id)->findOne(); + } + + /** + * Remove a file + * + * @access public + * @param integer $file_id File id + * @return bool + */ + public function remove($file_id) + { + $file = $this->getbyId($file_id); + + if (! empty($file) && @unlink(self::BASE_PATH.$file['path'])) { + return $this->db->table(self::TABLE)->eq('id', $file_id)->remove(); + } + + return false; + } + + /** + * 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 bool $is_image Image or not + * @return bool + */ + public function create($task_id, $name, $path, $is_image) + { + return $this->db->table(self::TABLE)->save(array( + 'task_id' => $task_id, + 'name' => $name, + 'path' => $path, + 'is_image' => $is_image ? '1' : '0', + )); + } + + /** + * Get all files for a given task + * + * @access public + * @param integer $task_id Task id + * @return array + */ + public function getAll($task_id) + { + return $listing = $this->db->table(self::TABLE) + ->eq('task_id', $task_id) + ->asc('name') + ->findAll(); + } + + /** + * Check if a filename is an image + * + * @access public + * @param string $filename Filename + * @return bool + */ + public function isImage($filename) + { + return getimagesize($filename) !== false; + } + + /** + * 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 bool + */ + public function generatePath($project_id, $task_id, $filename) + { + return $project_id.DIRECTORY_SEPARATOR.$task_id.DIRECTORY_SEPARATOR.hash('sha1', $filename.time()); + } + + /** + * Check if the base directory is created correctly + * + * @access public + */ + public function setup() + { + if (! is_dir(self::BASE_PATH)) { + if (! mkdir(self::BASE_PATH, 0755, true)) { + die('Unable to create the upload directory: "'.self::BASE_PATH.'"'); + } + } + + if (! is_writable(self::BASE_PATH)) { + die('The directory "'.self::BASE_PATH.'" must be writeable by your webserver user'); + } + } + + /** + * Handle file upload + * + * @access public + * @param integer $project_id Project id + * @param integer $task_id Task id + * @param string $form_name File form name + */ + public function upload($project_id, $task_id, $form_name) + { + $this->setup(); + + if (! empty($_FILES[$form_name])) { + + foreach ($_FILES[$form_name]['error'] as $key => $error) { + + if ($error == UPLOAD_ERR_OK && $_FILES[$form_name]['size'][$key] > 0) { + + $original_filename = basename($_FILES[$form_name]['name'][$key]); + $uploaded_filename = $_FILES[$form_name]['tmp_name'][$key]; + $destination_filename = $this->generatePath($project_id, $task_id, $original_filename); + + @mkdir(self::BASE_PATH.dirname($destination_filename), 0755, true); + + if (@move_uploaded_file($uploaded_filename, self::BASE_PATH.$destination_filename)) { + + $this->create( + $task_id, + $original_filename, + $destination_filename, + $this->isImage(self::BASE_PATH.$destination_filename) + ); + } + } + } + } + } +} diff --git a/app/Model/Task.php b/app/Model/Task.php index bd67d272..f31594c9 100644 --- a/app/Model/Task.php +++ b/app/Model/Task.php @@ -139,6 +139,7 @@ class Task extends Base ->table(self::TABLE) ->columns( '(SELECT count(*) FROM comments WHERE task_id=tasks.id) AS nb_comments', + '(SELECT count(*) FROM task_has_files WHERE task_id=tasks.id) AS nb_files', 'tasks.id', 'tasks.title', 'tasks.description', |