diff options
-rw-r--r-- | app/Controller/Board.php | 3 | ||||
-rw-r--r-- | app/Controller/File.php | 75 | ||||
-rw-r--r-- | app/Controller/Task.php | 3 | ||||
-rw-r--r-- | app/Model/File.php | 103 | ||||
-rw-r--r-- | app/Template/board/files.php | 43 | ||||
-rw-r--r-- | app/Template/file/show.php | 73 | ||||
-rw-r--r-- | app/Template/task/show.php | 2 | ||||
-rw-r--r-- | assets/css/app.css | 35 | ||||
-rw-r--r-- | assets/css/src/task.css | 35 |
9 files changed, 329 insertions, 43 deletions
diff --git a/app/Controller/Board.php b/app/Controller/Board.php index a6e002f2..17170317 100644 --- a/app/Controller/Board.php +++ b/app/Controller/Board.php @@ -441,7 +441,8 @@ class Board extends Base $task = $this->getTask(); $this->response->html($this->template->render('board/files', array( - 'files' => $this->file->getAll($task['id']), + 'files' => $this->file->getAllDocuments($task['id']), + 'images' => $this->file->getAllImages($task['id']), 'task' => $task, ))); } diff --git a/app/Controller/File.php b/app/Controller/File.php index 3255fe84..1e719d2f 100644 --- a/app/Controller/File.php +++ b/app/Controller/File.php @@ -20,8 +20,8 @@ class File extends Base $task = $this->getTask(); $this->response->html($this->taskLayout('file/new', array( - 'task' => $task, - 'max_size' => ini_get('upload_max_filesize'), + 'task' => $task, + 'max_size' => ini_get('upload_max_filesize'), ))); } @@ -74,8 +74,8 @@ class File extends Base if ($file['task_id'] == $task['id']) { $this->response->html($this->template->render('file/open', array( - 'file' => $file, - 'task' => $task, + 'file' => $file, + 'task' => $task, ))); } } @@ -102,6 +102,69 @@ class File extends Base } /** + * Return the file content (work only for images) resized + * + * @access public + */ + public function imageThumbnail() { + $task = $this->getTask(); + $file = $this->file->getById($this->request->getIntegerParam('file_id')); + $width_param = $this->request->getIntegerParam('width'); + $height_param = $this->request->getIntegerParam('height'); + $filename = FILES_DIR . $file['path']; + + if ($file['task_id'] == $task['id'] && file_exists($filename)) { + + // Get new sizes + list($width, $height) = getimagesize($filename); + if ($width_param == 0 && $height_param == 0) { + $newwidth = 100; + $newheight = 100; + } elseif ($width_param > 0 && $height_param == 0) { + $newwidth = $width_param; + $newheight = floor($height * ( $width_param / $width )); + } elseif ($width_param == 0 && $height_param > 0) { + $newwidth = floor($width * ( $height_param / $height )); + $newheight = $height_param; + } else { + $newwidth = $width_param; + $newheight = $height_param; + } + + // Load + $thumb = imagecreatetruecolor($newwidth, $newheight); + + $info = pathinfo($file['name']); + $extension = strtolower($info['extension']); + + switch ($extension) { + case 'jpeg': + case 'jpg': + $source = imagecreatefromjpeg($filename); + break; + case 'png': + $source = imagecreatefrompng($filename); + break; + case 'gif': + $source = imagecreatefromgif($filename); + break; + default: + die('File "' . $filename . '" is not valid jpg, png or gif image.'); + break; + } + + // Resize + imagecopyresampled($thumb, $source, 0, 0, 0, 0, $newwidth, $newheight, $width, $height); + + $metadata = getimagesize($filename); + if (isset($metadata['mime'])) { + $this->response->contentType($metadata['mime']); + imagejpeg($thumb); + } + } + } + + /** * Remove a file * * @access public @@ -132,8 +195,8 @@ class File extends Base $file = $this->file->getById($this->request->getIntegerParam('file_id')); $this->response->html($this->taskLayout('file/remove', array( - 'task' => $task, - 'file' => $file, + 'task' => $task, + 'file' => $file, ))); } } diff --git a/app/Controller/Task.php b/app/Controller/Task.php index 741db61e..d94c5908 100644 --- a/app/Controller/Task.php +++ b/app/Controller/Task.php @@ -68,7 +68,8 @@ class Task extends Base $this->response->html($this->taskLayout('task/show', array( 'project' => $this->project->getById($task['project_id']), - 'files' => $this->file->getAll($task['id']), + 'files' => $this->file->getAllDocuments($task['id']), + 'images' => $this->file->getAllImages($task['id']), 'comments' => $this->comment->getAll($task['id']), 'subtasks' => $subtasks, 'links' => $this->taskLink->getLinks($task['id']), diff --git a/app/Model/File.php b/app/Model/File.php index f069c8cf..3c2f2b68 100644 --- a/app/Model/File.php +++ b/app/Model/File.php @@ -111,6 +111,38 @@ class File extends Base ->asc('name') ->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->db->table(self::TABLE) + ->eq('task_id', $task_id) + ->eq('is_image', 1) + ->asc('name') + ->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->db->table(self::TABLE) + ->eq('task_id', $task_id) + ->eq('is_image', 0) + ->asc('name') + ->findAll(); + } /** * Check if a filename is an image @@ -121,10 +153,77 @@ class File extends Base */ public function isImage($filename) { - return getimagesize($filename) !== false; + $info = pathinfo($filename); + $extension = strtolower($info['extension']); + + switch ($extension) { + case 'jpeg': + case 'jpg': + case 'png': + case 'gif': + return true; + break; + default: + return false; + break; + } } /** + * get Font-Awesome Icon for file extension + * + * @access public + * @param string $filename Filename + * @return string Font-Awesome-Icon-Name + */ + public function get_icon($filename){ + $info = pathinfo($filename); + $extension = strtolower($info['extension']); + switch ($extension) { + case 'jpeg': + case 'jpg': + case 'png': + case 'gif': + $icon = 'fa-file-image-o'; + break; + case 'xls': + case 'xlsx': + $icon = 'fa-file-excel-o'; + break; + case 'doc': + case 'docx': + $icon = 'fa-file-word-o'; + break; + case 'ppt': + case 'pptx': + $icon = 'fa-file-powerpoint-o'; + break; + case 'zip': + case 'rar': + $icon = 'fa-archive-o'; + break; + case 'mp3': + $icon = 'fa-audio-o'; + break; + case 'avi': + $icon = 'fa-video-o'; + break; + case 'php': + case 'html': + case 'css': + $icon = 'fa-code-o'; + break; + case 'pdf': + $icon = 'fa-file-pdf-o'; + break; + default: + $icon = 'fa-file-o'; + break; + } + return $icon; + } + + /** * Generate the path for a new filename * * @access public @@ -188,7 +287,7 @@ class File extends Base $task_id, $original_filename, $destination_filename, - $this->isImage(FILES_DIR.$destination_filename) + $this->isImage($original_filename) ); } } diff --git a/app/Template/board/files.php b/app/Template/board/files.php index 278b906b..61529434 100644 --- a/app/Template/board/files.php +++ b/app/Template/board/files.php @@ -1,14 +1,33 @@ <section> - <?php foreach ($files as $file): ?> - <i class="fa fa-file-o fa-fw"></i> - - <?= $this->a( - $this->e($file['name']), - 'file', - 'download', - array('file_id' => $file['id'], 'task_id' => $file['task_id'], 'project_id' => $task['project_id']) - ) ?> - - <br/> - <?php endforeach ?> + <table> + <?php if (!empty($images)): ?> + <?php foreach ($images as $file): ?> + <tr> + <td><i class="fa fa-file-image-o fa-fw"></i> + <?= + $this->e($file['name']) + ?> + </td> + <td> + <i class="fa fa-download"></i> <?= $this->a(t('download'), 'file', 'download', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'file_id' => $file['id'])) ?> + <i class="fa fa-eye"></i> <?= $this->a(t('open'), 'file', 'open', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'file_id' => $file['id']), false, 'popover') ?> + </td> + </tr> + <?php endforeach ?> + <?php endif ?> + <?php if (!empty($files)): ?> + <?php foreach ($files as $file): ?> + <tr> + <td><i class="fa <?= $this->file->get_icon($file['name']) ?> fa-fw"></i> + <?= + $this->e($file['name']) + ?> + </td> + <td> + <i class="fa fa-download"></i> <?= $this->a(t('download'), 'file', 'download', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'file_id' => $file['id'])) ?> + </td> + </tr> + <?php endforeach ?> + <?php endif ?> + </table> </section> diff --git a/app/Template/file/show.php b/app/Template/file/show.php index 298976f6..0f5bd4ee 100644 --- a/app/Template/file/show.php +++ b/app/Template/file/show.php @@ -1,23 +1,56 @@ -<?php if (! empty($files)): ?> -<div id="attachments" class="task-show-section"> +<?php if (!empty($files) || !empty($images)): ?> + <div id="attachments" class="task-show-section"> - <div class="page-header"> - <h2><?= t('Attachments') ?></h2> - </div> + <div class="page-header"> + <h2><?= t('Attachments') ?></h2> + </div> + <?php if (!empty($images)): ?> + <h3> + <?= t('Images') ?> + </h3> + <ul class="task-show-images"> + <?php foreach ($images as $file): ?> + <li> + <div class="img_container"> + <img src="<?= $this->u('file', 'imageThumbnail', array('width' => 250, 'file_id' => $file['id'], 'project_id' => $task['project_id'], 'task_id' => $file['task_id'])) ?>" alt="<?= $this->e($file['name']) ?>"/> + </div> + <p> + <?= $this->e($file['name']) ?> + </p> + <span class="task-show-file-actions task-show-image-actions"> + <i class="fa fa-eye"></i> <?= $this->a(t('open'), 'file', 'open', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'file_id' => $file['id']), false, 'popover') ?> + <i class="fa fa-trash"></i> <?= $this->a(t('remove'), 'file', 'confirm', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'file_id' => $file['id'])) ?> + <i class="fa fa-download"></i> <?= $this->a(t('download'), 'file', 'download', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'file_id' => $file['id'])) ?> + </span> + </li> + <?php endforeach ?> + </ul> + <?php endif + ?> + <?php if (!empty($files)): ?> + <h3> + <?= t('Files') ?> + </h3> + <table class="task-show-file-table"> + <?php foreach ($files as $file): ?> + <tr> + <td><i class="fa <?= $this->file->get_icon($file['name']) ?> fa-fw"></i></td> + <td> + <?= $this->e($file['name']) ?> + </td><td> + <span class="task-show-file-actions"> + <i class="fa fa-trash"></i> <?= $this->a(t('remove'), 'file', 'confirm', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'file_id' => $file['id'])) ?> + <i class="fa fa-download"></i> <?= $this->a(t('download'), 'file', 'download', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'file_id' => $file['id'])) ?> + </span> + </td></tr> + <?php endforeach ?> + </table> + </div> + <?php endif + ?> + <?php - <ul class="task-show-files"> - <?php foreach ($files as $file): ?> - <li> - <?= $this->a($this->e($file['name']), 'file', 'download', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'file_id' => $file['id'])) ?> - <span class="task-show-file-actions"> - <?php if ($file['is_image']): ?> - <?= $this->a(t('open'), 'file', 'open', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'file_id' => $file['id']), false, 'popover') ?>, - <?php endif ?> - <?= $this->a(t('remove'), 'file', 'confirm', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'file_id' => $file['id'])) ?> - </span> - </li> - <?php endforeach ?> - </ul> -</div> -<?php endif ?>
\ No newline at end of file + + + endif ?>
\ No newline at end of file diff --git a/app/Template/task/show.php b/app/Template/task/show.php index d51b5542..ec930715 100644 --- a/app/Template/task/show.php +++ b/app/Template/task/show.php @@ -4,5 +4,5 @@ <?= $this->render('tasklink/show', array('task' => $task, 'links' => $links)) ?> <?= $this->render('subtask/show', array('task' => $task, 'subtasks' => $subtasks, 'project' => $project)) ?> <?= $this->render('task/timesheet', array('task' => $task)) ?> -<?= $this->render('file/show', array('task' => $task, 'files' => $files)) ?> +<?= $this->render('file/show', array('task' => $task, 'files' => $files, 'images' => $images)) ?> <?= $this->render('task/comments', array('task' => $task, 'comments' => $comments, 'project' => $project)) ?> diff --git a/assets/css/app.css b/assets/css/app.css index 5b1ab97f..4d2f4075 100644 --- a/assets/css/app.css +++ b/assets/css/app.css @@ -1555,3 +1555,38 @@ td li.dropit-trigger { .task-board .dropit-submenu a:hover { text-decoration: none; } +.task-show-images { + list-style-type: none; +} +.task-show-images li img { + width: 100%; +} +.task-show-images li .img_container { + width: 250px; + height: 100px; + overflow: hidden; +} +.task-show-images li { + padding: 10px; + overflow: auto; + width: 250px; + min-height: 120px; + display: inline-block; + vertical-align: top; +} +.task-show-images li p{ + padding: 5px; + font-weight: bold; +} +.task-show-images li:hover { + background: #eee; +} +.task-show-image-actions { + margin-left: 5px; +} +.task-show-images li .img_container:hover { + height: 100%; +} +.task-show-file-table { + width: auto; +}
\ No newline at end of file diff --git a/assets/css/src/task.css b/assets/css/src/task.css index b7a5cb9c..39cda76a 100644 --- a/assets/css/src/task.css +++ b/assets/css/src/task.css @@ -245,3 +245,38 @@ span.task-board-date-overdue { .task-link-closed { text-decoration: line-through; } +.task-show-images { + list-style-type: none; +} +.task-show-images li img { + width: 100%; +} +.task-show-images li .img_container { + width: 250px; + height: 100px; + overflow: hidden; +} +.task-show-images li { + padding: 10px; + overflow: auto; + width: 250px; + min-height: 120px; + display: inline-block; + vertical-align: top; +} +.task-show-images li p{ + padding: 5px; + font-weight: bold; +} +.task-show-images li:hover { + background: #eee; +} +.task-show-image-actions { + margin-left: 5px; +} +.task-show-images li .img_container:hover { + height: 100%; +} +.task-show-file-table { + width: auto; +} |