From 40917992e775bd21a280eb267241c452e04e5ade Mon Sep 17 00:00:00 2001 From: Frédéric Guillot Date: Thu, 22 May 2014 20:58:21 -0400 Subject: Add files upload --- app/Model/Acl.php | 23 ++++++- app/Model/File.php | 176 +++++++++++++++++++++++++++++++++++++++++++++++++++++ app/Model/Task.php | 1 + 3 files changed, 199 insertions(+), 1 deletion(-) create mode 100644 app/Model/File.php (limited to 'app/Model') 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 @@ +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', -- cgit v1.2.3