From 73dce1279760434e1d1b7a903a0a7500462d6f9c Mon Sep 17 00:00:00 2001 From: Frederic Guillot Date: Wed, 8 Feb 2017 18:36:13 -0500 Subject: Prevent people to remove columns that contains tasks --- ChangeLog | 1 + app/Api/Procedure/ColumnProcedure.php | 10 ++ app/Controller/ColumnController.php | 2 +- app/Locale/bs_BA/translations.php | 1 - app/Locale/cs_CZ/translations.php | 1 - app/Locale/da_DK/translations.php | 1 - app/Locale/de_DE/translations.php | 1 - app/Locale/el_GR/translations.php | 1 - app/Locale/es_ES/translations.php | 1 - app/Locale/fi_FI/translations.php | 1 - app/Locale/fr_FR/translations.php | 1 - app/Locale/hu_HU/translations.php | 1 - app/Locale/id_ID/translations.php | 1 - app/Locale/it_IT/translations.php | 1 - app/Locale/ja_JP/translations.php | 1 - app/Locale/ko_KR/translations.php | 1 - app/Locale/my_MY/translations.php | 1 - app/Locale/nb_NO/translations.php | 1 - app/Locale/nl_NL/translations.php | 1 - app/Locale/pl_PL/translations.php | 1 - app/Locale/pt_BR/translations.php | 1 - app/Locale/pt_PT/translations.php | 1 - app/Locale/ru_RU/translations.php | 1 - app/Locale/sr_Latn_RS/translations.php | 1 - app/Locale/sv_SE/translations.php | 1 - app/Locale/th_TH/translations.php | 1 - app/Locale/tr_TR/translations.php | 1 - app/Locale/zh_CN/translations.php | 1 - app/Model/ColumnModel.php | 18 +++ app/Model/TaskFinderModel.php | 11 +- app/Template/column/index.php | 14 +- app/Template/column/remove.php | 1 - tests/units/Model/ColumnModelTest.php | 267 +++++++++++++++++++++++++++++++++ tests/units/Model/ColumnTest.php | 236 ----------------------------- 34 files changed, 315 insertions(+), 270 deletions(-) create mode 100644 tests/units/Model/ColumnModelTest.php delete mode 100644 tests/units/Model/ColumnTest.php diff --git a/ChangeLog b/ChangeLog index aef3007c..37cd84c5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,7 @@ Version 1.0.39 (unreleased) Improvements: +* Prevent people to remove columns that contains tasks * Improve LDAP error reporting * Add configuration parameter to disable email configuration from user interface * Add email address field for projects diff --git a/app/Api/Procedure/ColumnProcedure.php b/app/Api/Procedure/ColumnProcedure.php index ab9d173b..3ffe12ba 100644 --- a/app/Api/Procedure/ColumnProcedure.php +++ b/app/Api/Procedure/ColumnProcedure.php @@ -4,6 +4,7 @@ namespace Kanboard\Api\Procedure; use Kanboard\Api\Authorization\ColumnAuthorization; use Kanboard\Api\Authorization\ProjectAuthorization; +use Kanboard\Model\TaskModel; /** * Column API controller @@ -40,6 +41,15 @@ class ColumnProcedure extends BaseProcedure public function removeColumn($column_id) { ColumnAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeColumn', $column_id); + + $projectId = $this->columnModel->getProjectId($column_id); + $nbTasks = $this->taskFinderModel->countByColumnId($projectId, $column_id, array(TaskModel::STATUS_OPEN, TaskModel::STATUS_CLOSED)); + + if ($nbTasks > 0) { + $this->logger->error(__METHOD__.': This column cannot be removed because it contains '.$nbTasks.' tasks'); + return false; + } + return $this->columnModel->remove($column_id); } diff --git a/app/Controller/ColumnController.php b/app/Controller/ColumnController.php index 69167976..3facbebc 100644 --- a/app/Controller/ColumnController.php +++ b/app/Controller/ColumnController.php @@ -20,7 +20,7 @@ class ColumnController extends BaseController public function index() { $project = $this->getProject(); - $columns = $this->columnModel->getAll($project['id']); + $columns = $this->columnModel->getAllWithTasksCount($project['id']); $this->response->html($this->helper->layout->project('column/index', array( 'columns' => $columns, diff --git a/app/Locale/bs_BA/translations.php b/app/Locale/bs_BA/translations.php index a168f6df..ec94d427 100644 --- a/app/Locale/bs_BA/translations.php +++ b/app/Locale/bs_BA/translations.php @@ -73,7 +73,6 @@ return array( 'Remove a column' => 'Ukloni kolonu', 'Unable to remove this column.' => 'Nemoguće uklanjanje kolone.', 'Do you really want to remove this column: "%s"?' => 'Da li zaista želiš da ukoniš ovu kolonu: "%s"?', - 'This action will REMOVE ALL TASKS associated to this column!' => 'Ova akcija BRIŠE SVE ZADATKE vezane za ovu kolonu!', 'Settings' => 'Podešavanja', 'Application settings' => 'Podešavanja aplikacije', 'Language' => 'Jezik', diff --git a/app/Locale/cs_CZ/translations.php b/app/Locale/cs_CZ/translations.php index 96b50af3..f7ebf88b 100644 --- a/app/Locale/cs_CZ/translations.php +++ b/app/Locale/cs_CZ/translations.php @@ -73,7 +73,6 @@ return array( 'Remove a column' => 'Vyjmout sloupec', 'Unable to remove this column.' => 'Tento sloupec nelze odstranit', 'Do you really want to remove this column: "%s"?' => 'Opravdu chcete vyjmout tento sloupec: "%s"?', - 'This action will REMOVE ALL TASKS associated to this column!' => 'Tato akce vyjme všechny úkoly přiřazený k tomuto sloupci!', 'Settings' => 'Nastavení', 'Application settings' => 'Nastavení aplikace', 'Language' => 'Čeština', diff --git a/app/Locale/da_DK/translations.php b/app/Locale/da_DK/translations.php index 5d61581c..d47505fd 100644 --- a/app/Locale/da_DK/translations.php +++ b/app/Locale/da_DK/translations.php @@ -73,7 +73,6 @@ return array( 'Remove a column' => 'Fjern en kolonne', 'Unable to remove this column.' => 'Ikke muligt at fjerne denne kolonne', 'Do you really want to remove this column: "%s"?' => 'Vil du virkelig fjerne denne kolonne: "%s"?', - 'This action will REMOVE ALL TASKS associated to this column!' => 'Denne handling vil SLETTE ALLE OPGAVER tilknyttet denne kolonne', 'Settings' => 'Indstillinger', 'Application settings' => 'Applikationsindstillinger', 'Language' => 'Sprog', diff --git a/app/Locale/de_DE/translations.php b/app/Locale/de_DE/translations.php index 61175e33..33691161 100644 --- a/app/Locale/de_DE/translations.php +++ b/app/Locale/de_DE/translations.php @@ -73,7 +73,6 @@ return array( 'Remove a column' => 'Spalte löschen', 'Unable to remove this column.' => 'Löschen dieser Spalte nicht möglich.', 'Do you really want to remove this column: "%s"?' => 'Soll diese Spalte wirklich gelöscht werden: "%s"?', - 'This action will REMOVE ALL TASKS associated to this column!' => 'ALLE AUFGABEN dieser Spalte werden GELÖSCHT!', 'Settings' => 'Einstellungen', 'Application settings' => 'Anwendungskonfiguration', 'Language' => 'Sprache', diff --git a/app/Locale/el_GR/translations.php b/app/Locale/el_GR/translations.php index 5e99a225..182f69b7 100644 --- a/app/Locale/el_GR/translations.php +++ b/app/Locale/el_GR/translations.php @@ -73,7 +73,6 @@ return array( 'Remove a column' => 'Αφαίρεση στήλης', 'Unable to remove this column.' => 'Αδύνατη η αφαίρεση της στήλης', 'Do you really want to remove this column: "%s"?' => 'Θέλετε να αφαιρέσετε τη στήλη: « %s » ?', - 'This action will REMOVE ALL TASKS associated to this column!' => 'Αυτή η ενέργεια θα ΑΦΑΙΡΕΣΕΙ ΟΛΕΣ ΤΙΣ ΕΡΓΑΣΙΕΣ που είναι σχετικές με τη στήλη!!', 'Settings' => 'Προτιμήσεις', 'Application settings' => 'Παραμετροποίηση εφαρμογής', 'Language' => 'Γλώσσα', diff --git a/app/Locale/es_ES/translations.php b/app/Locale/es_ES/translations.php index 2e3f4215..4a0e8f47 100644 --- a/app/Locale/es_ES/translations.php +++ b/app/Locale/es_ES/translations.php @@ -73,7 +73,6 @@ return array( 'Remove a column' => 'Eliminar esta columna', 'Unable to remove this column.' => 'No se puede eliminar esta columna.', 'Do you really want to remove this column: "%s"?' => '¿De vedad que desea eliminar esta columna: «%s»?', - 'This action will REMOVE ALL TASKS associated to this column!' => '¡Esta acción ELIMINARÁ TODAS LAS TAREAS asociadas a esta columna!', 'Settings' => 'Preferencias', 'Application settings' => 'Preferencias de la aplicación', 'Language' => 'Idioma', diff --git a/app/Locale/fi_FI/translations.php b/app/Locale/fi_FI/translations.php index 84ddf1ce..30f40cee 100644 --- a/app/Locale/fi_FI/translations.php +++ b/app/Locale/fi_FI/translations.php @@ -73,7 +73,6 @@ return array( 'Remove a column' => 'Poista sarake', 'Unable to remove this column.' => 'Sarakkeen poistaminen ei onnistunut.', 'Do you really want to remove this column: "%s"?' => 'Haluatko varmasti poistaa sarakkeen "%s"?', - 'This action will REMOVE ALL TASKS associated to this column!' => 'Tämä toiminto POISTAA KAIKKI TEHTÄVÄT tästä sarakkeesta!', 'Settings' => 'Asetukset', 'Application settings' => 'Ohjelman asetukset', 'Language' => 'Kieli', diff --git a/app/Locale/fr_FR/translations.php b/app/Locale/fr_FR/translations.php index 8e062c45..5c1187f9 100644 --- a/app/Locale/fr_FR/translations.php +++ b/app/Locale/fr_FR/translations.php @@ -73,7 +73,6 @@ return array( 'Remove a column' => 'Supprimer une colonne', 'Unable to remove this column.' => 'Impossible de supprimer cette colonne.', 'Do you really want to remove this column: "%s"?' => 'Voulez vraiment supprimer cette colonne : « %s » ?', - 'This action will REMOVE ALL TASKS associated to this column!' => 'Cette action va supprimer toutes les tâches associées à cette colonne !', 'Settings' => 'Préférences', 'Application settings' => 'Paramètres de l\'application', 'Language' => 'Langue', diff --git a/app/Locale/hu_HU/translations.php b/app/Locale/hu_HU/translations.php index 0d4beb00..2c7c59d4 100644 --- a/app/Locale/hu_HU/translations.php +++ b/app/Locale/hu_HU/translations.php @@ -73,7 +73,6 @@ return array( 'Remove a column' => 'Oszlop törlése', 'Unable to remove this column.' => 'Az oszlop törlése nem lehetséges.', 'Do you really want to remove this column: "%s"?' => 'Valóban törölni akarja ezt az oszlopot: "%s"?', - 'This action will REMOVE ALL TASKS associated to this column!' => 'Az oszlophoz rendelt ÖSSZES FELADAT TÖRLŐDNI FOG!', 'Settings' => 'Beállítások', 'Application settings' => 'Alkalmazás beállítások', 'Language' => 'Nyelv', diff --git a/app/Locale/id_ID/translations.php b/app/Locale/id_ID/translations.php index 78b15e98..b7a73e20 100644 --- a/app/Locale/id_ID/translations.php +++ b/app/Locale/id_ID/translations.php @@ -73,7 +73,6 @@ return array( 'Remove a column' => 'Hapus kolom', 'Unable to remove this column.' => 'Tidak dapat menghapus kolom ini.', 'Do you really want to remove this column: "%s"?' => 'Apakah Anda yakin mau menghapus kolom ini: "%s"?', - 'This action will REMOVE ALL TASKS associated to this column!' => 'Tindakan ini akan MENGHAPUS SEMUA TUGAS yang berkaitan dengan kolom ini!', 'Settings' => 'Pengaturan', 'Application settings' => 'Pengaturan aplikasi', 'Language' => 'Bahasa', diff --git a/app/Locale/it_IT/translations.php b/app/Locale/it_IT/translations.php index 93128cd2..85ad4a8a 100644 --- a/app/Locale/it_IT/translations.php +++ b/app/Locale/it_IT/translations.php @@ -73,7 +73,6 @@ return array( 'Remove a column' => 'Cancella questa colonna', 'Unable to remove this column.' => 'Impossibile cancellare questa colonna.', 'Do you really want to remove this column: "%s"?' => 'Desideri davvero cancellare questa colonna: "%s" ?', - 'This action will REMOVE ALL TASKS associated to this column!' => 'Questa azione cancellerà TUTTI I TASK legati a questa colonna!', 'Settings' => 'Impostazioni', 'Application settings' => 'Impostazioni dell\'applicazione', 'Language' => 'Lingua', diff --git a/app/Locale/ja_JP/translations.php b/app/Locale/ja_JP/translations.php index 820d1b86..867a7644 100644 --- a/app/Locale/ja_JP/translations.php +++ b/app/Locale/ja_JP/translations.php @@ -73,7 +73,6 @@ return array( 'Remove a column' => 'カラムの削除', 'Unable to remove this column.' => 'カラムを削除できませんでした。', 'Do you really want to remove this column: "%s"?' => 'カラム「%s」を削除しますか?', - 'This action will REMOVE ALL TASKS associated to this column!' => 'この操作はこのカラムに割当てられた『全てのタスクを削除』します!', 'Settings' => '設定', 'Application settings' => 'アプリケーションの設定', 'Language' => '言語', diff --git a/app/Locale/ko_KR/translations.php b/app/Locale/ko_KR/translations.php index 56bac068..8b2c421b 100644 --- a/app/Locale/ko_KR/translations.php +++ b/app/Locale/ko_KR/translations.php @@ -73,7 +73,6 @@ return array( 'Remove a column' => '컬럼 삭제', 'Unable to remove this column.' => '(※)컬럼을 삭제할 수 없었습니다.', 'Do you really want to remove this column: "%s"?' => '컬럼을 삭제하시겠습니까: "%s"?', - 'This action will REMOVE ALL TASKS associated to this column!' => '이 조작은 이 컬럼에 할당된 『 모든 할일을 삭제 』합니다!', 'Settings' => '설정', 'Application settings' => '애플리케이션의 설정', 'Language' => '언어', diff --git a/app/Locale/my_MY/translations.php b/app/Locale/my_MY/translations.php index 1121a880..417d9510 100644 --- a/app/Locale/my_MY/translations.php +++ b/app/Locale/my_MY/translations.php @@ -73,7 +73,6 @@ return array( 'Remove a column' => 'Hapus kolom', 'Unable to remove this column.' => 'Tidak dapat menghapus kolom ini.', 'Do you really want to remove this column: "%s"?' => 'Apakah anda yakin akan menghapus kolom ini : « %s » ?', - 'This action will REMOVE ALL TASKS associated to this column!' => 'tindakan ini akan MENGHAPUS SEMUA TUGAS yang terkait dengan kolom ini!', 'Settings' => 'Penetapan', 'Application settings' => 'Penetapan aplikasi', 'Language' => 'Bahasa', diff --git a/app/Locale/nb_NO/translations.php b/app/Locale/nb_NO/translations.php index 2743009c..8d0baaa7 100644 --- a/app/Locale/nb_NO/translations.php +++ b/app/Locale/nb_NO/translations.php @@ -73,7 +73,6 @@ return array( 'Remove a column' => 'Fjern en kolonne', 'Unable to remove this column.' => 'Ikke mulig ø fjerne denne kolonnen', 'Do you really want to remove this column: "%s"?' => 'Vil du fjerne denne kolonnen: "%s"?', - 'This action will REMOVE ALL TASKS associated to this column!' => 'Denne handlingen vil SLETTE ALLE OPPGAVER tilknyttet denne kolonnen', 'Settings' => 'Innstillinger', 'Application settings' => 'Applikasjonsinnstillinger', 'Language' => 'Språk', diff --git a/app/Locale/nl_NL/translations.php b/app/Locale/nl_NL/translations.php index 45a8c5bc..cfdb26d3 100644 --- a/app/Locale/nl_NL/translations.php +++ b/app/Locale/nl_NL/translations.php @@ -73,7 +73,6 @@ return array( 'Remove a column' => 'Kolom verwijderen', 'Unable to remove this column.' => 'Verwijderen van deze kolom niet mogelijk.', 'Do you really want to remove this column: "%s"?' => 'Weet u zeker dat u deze kolom wil verwijderen : « %s » ?', - 'This action will REMOVE ALL TASKS associated to this column!' => 'Deze actie zal ALLE TAKEN VERWIJDEREN die zijn geassocieerd met deze kolom!', 'Settings' => 'Instellingen', 'Application settings' => 'Applicatie instellingen', 'Language' => 'Taal', diff --git a/app/Locale/pl_PL/translations.php b/app/Locale/pl_PL/translations.php index b8c4a2c7..245c6df1 100644 --- a/app/Locale/pl_PL/translations.php +++ b/app/Locale/pl_PL/translations.php @@ -73,7 +73,6 @@ return array( 'Remove a column' => 'Usuń kolumnę', 'Unable to remove this column.' => 'Nie udało się usunąć kolumny.', 'Do you really want to remove this column: "%s"?' => 'Na pewno chcesz usunąć kolumnę: "%s"?', - 'This action will REMOVE ALL TASKS associated to this column!' => 'Wszystkie zadania w kolumnie zostaną usunięte!', 'Settings' => 'Ustawienia', 'Application settings' => 'Ustawienia aplikacji', 'Language' => 'Język', diff --git a/app/Locale/pt_BR/translations.php b/app/Locale/pt_BR/translations.php index a21e7cb8..14e19d44 100644 --- a/app/Locale/pt_BR/translations.php +++ b/app/Locale/pt_BR/translations.php @@ -73,7 +73,6 @@ return array( 'Remove a column' => 'Remover uma coluna', 'Unable to remove this column.' => 'Não foi possível remover esta coluna.', 'Do you really want to remove this column: "%s"?' => 'Você realmente deseja remover esta coluna: "%s"?', - 'This action will REMOVE ALL TASKS associated to this column!' => 'Esta ação irá REMOVER TODAS AS TAREFAS associadas a esta coluna!', 'Settings' => 'Configurações', 'Application settings' => 'Configurações da aplicação', 'Language' => 'Idioma', diff --git a/app/Locale/pt_PT/translations.php b/app/Locale/pt_PT/translations.php index 17f46ba5..760bafaa 100644 --- a/app/Locale/pt_PT/translations.php +++ b/app/Locale/pt_PT/translations.php @@ -73,7 +73,6 @@ return array( 'Remove a column' => 'Remover uma coluna', 'Unable to remove this column.' => 'Não foi possível remover esta coluna.', 'Do you really want to remove this column: "%s"?' => 'Tem a certeza que quer remover esta coluna: "%s"?', - 'This action will REMOVE ALL TASKS associated to this column!' => 'Esta acção irá REMOVER TODAS AS TAREFAS associadas a esta coluna!', 'Settings' => 'Configurações', 'Application settings' => 'Configurações da aplicação', 'Language' => 'Idioma', diff --git a/app/Locale/ru_RU/translations.php b/app/Locale/ru_RU/translations.php index 9cd16716..ca2b4f60 100644 --- a/app/Locale/ru_RU/translations.php +++ b/app/Locale/ru_RU/translations.php @@ -73,7 +73,6 @@ return array( 'Remove a column' => 'Удалить колонку', 'Unable to remove this column.' => 'Не удалось удалить эту колонку.', 'Do you really want to remove this column: "%s"?' => 'Вы точно хотите удалить эту колонку: "%s" ?', - 'This action will REMOVE ALL TASKS associated to this column!' => 'Вы УДАЛИТЕ ВСЕ ЗАДАЧИ находящиеся в этой колонке!', 'Settings' => 'Настройки', 'Application settings' => 'Настройки приложения', 'Language' => 'Язык', diff --git a/app/Locale/sr_Latn_RS/translations.php b/app/Locale/sr_Latn_RS/translations.php index 3ebd5f68..9438293f 100644 --- a/app/Locale/sr_Latn_RS/translations.php +++ b/app/Locale/sr_Latn_RS/translations.php @@ -73,7 +73,6 @@ return array( 'Remove a column' => 'Ukloni kolonu', 'Unable to remove this column.' => 'Nemoguće uklanjanje kolone.', 'Do you really want to remove this column: "%s"?' => 'Da li zaista želiš da ukoniš ovu kolonu: "%s"?', - 'This action will REMOVE ALL TASKS associated to this column!' => 'Ova akcija BRIŠE SVE ZADATKE vezane za ovu kolonu!', 'Settings' => 'Podešavanja', 'Application settings' => 'Podešavanja aplikacije', 'Language' => 'Jezik', diff --git a/app/Locale/sv_SE/translations.php b/app/Locale/sv_SE/translations.php index 278c0f3c..51979ff8 100644 --- a/app/Locale/sv_SE/translations.php +++ b/app/Locale/sv_SE/translations.php @@ -73,7 +73,6 @@ return array( 'Remove a column' => 'Ta bort en kolumn', 'Unable to remove this column.' => 'Kunde inte ta bort kolumnen.', 'Do you really want to remove this column: "%s"?' => 'Vill du verkligen ta bort kolumnen: "%s"?', - 'This action will REMOVE ALL TASKS associated to this column!' => 'Denna åtgärd kommer att TA BORT ALLA uppgifter kopplade till kolumnen!', 'Settings' => 'Inställningar', 'Application settings' => 'Applikationsinställningar', 'Language' => 'Språk', diff --git a/app/Locale/th_TH/translations.php b/app/Locale/th_TH/translations.php index 00a290da..d08c3b74 100644 --- a/app/Locale/th_TH/translations.php +++ b/app/Locale/th_TH/translations.php @@ -73,7 +73,6 @@ return array( 'Remove a column' => 'ลบคอลัมน์', 'Unable to remove this column.' => 'ไม่สามารถลบคอลัมน์นี้', 'Do you really want to remove this column: "%s"?' => 'คุณต้องการลบคอลัมน์ « %s » ออกใช่หรือไม่?', - 'This action will REMOVE ALL TASKS associated to this column!' => 'การกระทำนี้จะลบงานที่เกี่ยวข้องกับคอลัมน์นี้', 'Settings' => 'ตั้งค่า', 'Application settings' => 'ตั้งค่าการทำงาน', 'Language' => 'ภาษา', diff --git a/app/Locale/tr_TR/translations.php b/app/Locale/tr_TR/translations.php index dc25f861..e4589bea 100644 --- a/app/Locale/tr_TR/translations.php +++ b/app/Locale/tr_TR/translations.php @@ -73,7 +73,6 @@ return array( 'Remove a column' => 'Bir sütunu sil', 'Unable to remove this column.' => 'Bu sütun silinemiyor.', 'Do you really want to remove this column: "%s"?' => 'Bu sütunu gerçekten silmek istiyor musunuz: "%s"?', - 'This action will REMOVE ALL TASKS associated to this column!' => 'Bu komut sütun içindeki TÜM GÖREVLERİ silecek!', 'Settings' => 'Ayarlar', 'Application settings' => 'Uygulama ayarları', 'Language' => 'Dil', diff --git a/app/Locale/zh_CN/translations.php b/app/Locale/zh_CN/translations.php index e49386df..587ae27d 100644 --- a/app/Locale/zh_CN/translations.php +++ b/app/Locale/zh_CN/translations.php @@ -73,7 +73,6 @@ return array( 'Remove a column' => '移除一个栏目', 'Unable to remove this column.' => '无法移除该栏目。', 'Do you really want to remove this column: "%s"?' => '确定要移除栏目"%s"吗?', - 'This action will REMOVE ALL TASKS associated to this column!' => '该动作将移除与该栏目相关的所有项目!', 'Settings' => '设置', 'Application settings' => '应用设置', 'Language' => '语言', diff --git a/app/Model/ColumnModel.php b/app/Model/ColumnModel.php index 5498ef54..535a31e5 100644 --- a/app/Model/ColumnModel.php +++ b/app/Model/ColumnModel.php @@ -120,6 +120,24 @@ class ColumnModel extends Base return $this->db->table(self::TABLE)->eq('project_id', $project_id)->asc('position')->findAll(); } + /** + * Get all columns with tasks count + * + * @access public + * @param integer $project_id Project id + * @return array + */ + public function getAllWithTasksCount($project_id) + { + return $this->db->table(self::TABLE) + ->columns('id', 'title', 'position', 'task_limit', 'description', 'hide_in_dashboard', 'project_id') + ->subquery('SELECT COUNT(*) FROM '.TaskModel::TABLE.' WHERE column_id='.self::TABLE.'.id AND is_active=1', 'nb_open_tasks') + ->subquery('SELECT COUNT(*) FROM '.TaskModel::TABLE.' WHERE column_id='.self::TABLE.'.id AND is_active=0', 'nb_closed_tasks') + ->eq('project_id', $project_id) + ->asc('position') + ->findAll(); + } + /** * Get the list of columns sorted by position [ column_id => title ] * diff --git a/app/Model/TaskFinderModel.php b/app/Model/TaskFinderModel.php index 3185afb7..e54a613b 100644 --- a/app/Model/TaskFinderModel.php +++ b/app/Model/TaskFinderModel.php @@ -367,17 +367,18 @@ class TaskFinderModel extends Base * Count the number of tasks for a given column and status * * @access public - * @param integer $project_id Project id - * @param integer $column_id Column id - * @return integer + * @param integer $project_id Project id + * @param integer $column_id Column id + * @param array $status + * @return int */ - public function countByColumnId($project_id, $column_id) + public function countByColumnId($project_id, $column_id, array $status = array(TaskModel::STATUS_OPEN)) { return $this->db ->table(TaskModel::TABLE) ->eq('project_id', $project_id) ->eq('column_id', $column_id) - ->eq('is_active', 1) + ->in('is_active', $status) ->count(); } diff --git a/app/Template/column/index.php b/app/Template/column/index.php index eaaae332..0b14e341 100644 --- a/app/Template/column/index.php +++ b/app/Template/column/index.php @@ -15,10 +15,12 @@ data-save-position-url="url->href('ColumnController', 'move', array('project_id' => $project['id'])) ?>"> - + - + + + @@ -39,6 +41,12 @@ + + + + + + diff --git a/app/Template/column/remove.php b/app/Template/column/remove.php index 4134b175..b4e7942d 100644 --- a/app/Template/column/remove.php +++ b/app/Template/column/remove.php @@ -5,7 +5,6 @@

-

modal->confirmButtons( diff --git a/tests/units/Model/ColumnModelTest.php b/tests/units/Model/ColumnModelTest.php new file mode 100644 index 00000000..75d1da20 --- /dev/null +++ b/tests/units/Model/ColumnModelTest.php @@ -0,0 +1,267 @@ +container); + $columnModel = new ColumnModel($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'UnitTest'))); + + $column = $columnModel->getById(3); + $this->assertNotEmpty($column); + $this->assertEquals('Work in progress', $column['title']); + + $column = $columnModel->getById(33); + $this->assertEmpty($column); + } + + public function testGetFirstColumnId() + { + $projectModel = new ProjectModel($this->container); + $columnModel = new ColumnModel($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'UnitTest'))); + $this->assertEquals(1, $columnModel->getFirstColumnId(1)); + } + + public function testGetLastColumnId() + { + $projectModel = new ProjectModel($this->container); + $columnModel = new ColumnModel($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'UnitTest'))); + $this->assertEquals(4, $columnModel->getLastColumnId(1)); + } + + public function testGetLastColumnPosition() + { + $projectModel = new ProjectModel($this->container); + $columnModel = new ColumnModel($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'UnitTest'))); + $this->assertEquals(4, $columnModel->getLastColumnPosition(1)); + } + + public function testGetColumnIdByTitle() + { + $projectModel = new ProjectModel($this->container); + $columnModel = new ColumnModel($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'UnitTest'))); + $this->assertEquals(2, $columnModel->getColumnIdByTitle(1, 'Ready')); + } + + public function testGetTitleByColumnId() + { + $projectModel = new ProjectModel($this->container); + $columnModel = new ColumnModel($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'UnitTest'))); + $this->assertEquals('Work in progress', $columnModel->getColumnTitleById(3)); + } + + public function testGetAll() + { + $projectModel = new ProjectModel($this->container); + $columnModel = new ColumnModel($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'UnitTest'))); + + $columns = $columnModel->getAll(1); + $this->assertCount(4, $columns); + + $this->assertEquals(1, $columns[0]['id']); + $this->assertEquals(1, $columns[0]['position']); + $this->assertEquals('Backlog', $columns[0]['title']); + + $this->assertEquals(2, $columns[1]['id']); + $this->assertEquals(2, $columns[1]['position']); + $this->assertEquals('Ready', $columns[1]['title']); + + $this->assertEquals(3, $columns[2]['id']); + $this->assertEquals(3, $columns[2]['position']); + $this->assertEquals('Work in progress', $columns[2]['title']); + + $this->assertEquals(4, $columns[3]['id']); + $this->assertEquals(4, $columns[3]['position']); + $this->assertEquals('Done', $columns[3]['title']); + } + + public function testGetAllWithTasksCount() + { + $projectModel = new ProjectModel($this->container); + $columnModel = new ColumnModel($this->container); + $taskCreationModel = new TaskCreationModel($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'UnitTest'))); + $this->assertEquals(1, $taskCreationModel->create(array('title' => 'UnitTest', 'project_id' => 1, 'column_id' => 1))); + $this->assertEquals(2, $taskCreationModel->create(array('title' => 'UnitTest', 'project_id' => 1, 'column_id' => 2, 'is_active' => 0))); + + $columns = $columnModel->getAllWithTasksCount(1); + $this->assertCount(4, $columns); + + $this->assertEquals(1, $columns[0]['id']); + $this->assertEquals(1, $columns[0]['position']); + $this->assertEquals(1, $columns[0]['project_id']); + $this->assertEquals(0, $columns[0]['task_limit']); + $this->assertEquals(0, $columns[0]['hide_in_dashboard']); + $this->assertEquals('', $columns[0]['description']); + $this->assertEquals('Backlog', $columns[0]['title']); + $this->assertEquals(1, $columns[0]['nb_open_tasks']); + $this->assertEquals(0, $columns[0]['nb_closed_tasks']); + + $this->assertEquals(2, $columns[1]['id']); + $this->assertEquals(2, $columns[1]['position']); + $this->assertEquals('Ready', $columns[1]['title']); + $this->assertEquals(0, $columns[1]['nb_open_tasks']); + $this->assertEquals(1, $columns[1]['nb_closed_tasks']); + } + + public function testGetList() + { + $projectModel = new ProjectModel($this->container); + $columnModel = new ColumnModel($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'UnitTest'))); + + $columns = $columnModel->getList(1); + $this->assertCount(4, $columns); + $this->assertEquals('Backlog', $columns[1]); + $this->assertEquals('Ready', $columns[2]); + $this->assertEquals('Work in progress', $columns[3]); + $this->assertEquals('Done', $columns[4]); + + $columns = $columnModel->getList(1, true); + $this->assertCount(5, $columns); + $this->assertEquals('All columns', $columns[-1]); + $this->assertEquals('Backlog', $columns[1]); + $this->assertEquals('Ready', $columns[2]); + $this->assertEquals('Work in progress', $columns[3]); + $this->assertEquals('Done', $columns[4]); + } + + public function testAddColumn() + { + $projectModel = new ProjectModel($this->container); + $columnModel = new ColumnModel($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'UnitTest'))); + $this->assertNotFalse($columnModel->create(1, 'another column')); + $this->assertNotFalse($columnModel->create(1, 'one more', 3, 'one more description')); + + $columns = $columnModel->getAll(1); + $this->assertTrue(is_array($columns)); + $this->assertEquals(6, count($columns)); + + $this->assertEquals('another column', $columns[4]['title']); + $this->assertEquals(0, $columns[4]['task_limit']); + $this->assertEquals(5, $columns[4]['position']); + + $this->assertEquals('one more', $columns[5]['title']); + $this->assertEquals(3, $columns[5]['task_limit']); + $this->assertEquals(6, $columns[5]['position']); + $this->assertEquals('one more description', $columns[5]['description']); + } + + public function testUpdateColumn() + { + $projectModel = new ProjectModel($this->container); + $columnModel = new ColumnModel($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'UnitTest'))); + + $this->assertTrue($columnModel->update(3, 'blah', 5)); + $this->assertTrue($columnModel->update(2, 'boo')); + + $column = $columnModel->getById(3); + $this->assertNotEmpty($column); + $this->assertEquals('blah', $column['title']); + $this->assertEquals(5, $column['task_limit']); + + $column = $columnModel->getById(2); + $this->assertNotEmpty($column); + $this->assertEquals('boo', $column['title']); + $this->assertEquals(0, $column['task_limit']); + } + + public function testRemoveColumn() + { + $projectModel = new ProjectModel($this->container); + $columnModel = new ColumnModel($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'UnitTest'))); + $this->assertTrue($columnModel->remove(3)); + $this->assertFalse($columnModel->remove(322)); + + $columns = $columnModel->getAll(1); + $this->assertTrue(is_array($columns)); + $this->assertEquals(3, count($columns)); + } + + public function testChangePosition() + { + $projectModel = new ProjectModel($this->container); + $columnModel = new ColumnModel($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + + $columns = $columnModel->getAll(1); + $this->assertEquals(1, $columns[0]['position']); + $this->assertEquals(1, $columns[0]['id']); + $this->assertEquals(2, $columns[1]['position']); + $this->assertEquals(2, $columns[1]['id']); + $this->assertEquals(3, $columns[2]['position']); + $this->assertEquals(3, $columns[2]['id']); + + $this->assertTrue($columnModel->changePosition(1, 3, 2)); + + $columns = $columnModel->getAll(1); + $this->assertEquals(1, $columns[0]['position']); + $this->assertEquals(1, $columns[0]['id']); + $this->assertEquals(2, $columns[1]['position']); + $this->assertEquals(3, $columns[1]['id']); + $this->assertEquals(3, $columns[2]['position']); + $this->assertEquals(2, $columns[2]['id']); + + $this->assertTrue($columnModel->changePosition(1, 2, 1)); + + $columns = $columnModel->getAll(1); + $this->assertEquals(1, $columns[0]['position']); + $this->assertEquals(2, $columns[0]['id']); + $this->assertEquals(2, $columns[1]['position']); + $this->assertEquals(1, $columns[1]['id']); + $this->assertEquals(3, $columns[2]['position']); + $this->assertEquals(3, $columns[2]['id']); + + $this->assertTrue($columnModel->changePosition(1, 2, 2)); + + $columns = $columnModel->getAll(1); + $this->assertEquals(1, $columns[0]['position']); + $this->assertEquals(1, $columns[0]['id']); + $this->assertEquals(2, $columns[1]['position']); + $this->assertEquals(2, $columns[1]['id']); + $this->assertEquals(3, $columns[2]['position']); + $this->assertEquals(3, $columns[2]['id']); + + $this->assertTrue($columnModel->changePosition(1, 4, 1)); + + $columns = $columnModel->getAll(1); + $this->assertEquals(1, $columns[0]['position']); + $this->assertEquals(4, $columns[0]['id']); + $this->assertEquals(2, $columns[1]['position']); + $this->assertEquals(1, $columns[1]['id']); + $this->assertEquals(3, $columns[2]['position']); + $this->assertEquals(2, $columns[2]['id']); + + $this->assertFalse($columnModel->changePosition(1, 2, 0)); + $this->assertFalse($columnModel->changePosition(1, 2, 5)); + } +} diff --git a/tests/units/Model/ColumnTest.php b/tests/units/Model/ColumnTest.php deleted file mode 100644 index 7340a274..00000000 --- a/tests/units/Model/ColumnTest.php +++ /dev/null @@ -1,236 +0,0 @@ -container); - $columnModel = new ColumnModel($this->container); - - $this->assertEquals(1, $projectModel->create(array('name' => 'UnitTest'))); - - $column = $columnModel->getById(3); - $this->assertNotEmpty($column); - $this->assertEquals('Work in progress', $column['title']); - - $column = $columnModel->getById(33); - $this->assertEmpty($column); - } - - public function testGetFirstColumnId() - { - $projectModel = new ProjectModel($this->container); - $columnModel = new ColumnModel($this->container); - - $this->assertEquals(1, $projectModel->create(array('name' => 'UnitTest'))); - $this->assertEquals(1, $columnModel->getFirstColumnId(1)); - } - - public function testGetLastColumnId() - { - $projectModel = new ProjectModel($this->container); - $columnModel = new ColumnModel($this->container); - - $this->assertEquals(1, $projectModel->create(array('name' => 'UnitTest'))); - $this->assertEquals(4, $columnModel->getLastColumnId(1)); - } - - public function testGetLastColumnPosition() - { - $projectModel = new ProjectModel($this->container); - $columnModel = new ColumnModel($this->container); - - $this->assertEquals(1, $projectModel->create(array('name' => 'UnitTest'))); - $this->assertEquals(4, $columnModel->getLastColumnPosition(1)); - } - - public function testGetColumnIdByTitle() - { - $projectModel = new ProjectModel($this->container); - $columnModel = new ColumnModel($this->container); - - $this->assertEquals(1, $projectModel->create(array('name' => 'UnitTest'))); - $this->assertEquals(2, $columnModel->getColumnIdByTitle(1, 'Ready')); - } - - public function testGetTitleByColumnId() - { - $projectModel = new ProjectModel($this->container); - $columnModel = new ColumnModel($this->container); - - $this->assertEquals(1, $projectModel->create(array('name' => 'UnitTest'))); - $this->assertEquals('Work in progress', $columnModel->getColumnTitleById(3)); - } - - public function testGetAll() - { - $projectModel = new ProjectModel($this->container); - $columnModel = new ColumnModel($this->container); - - $this->assertEquals(1, $projectModel->create(array('name' => 'UnitTest'))); - - $columns = $columnModel->getAll(1); - $this->assertCount(4, $columns); - - $this->assertEquals(1, $columns[0]['id']); - $this->assertEquals(1, $columns[0]['position']); - $this->assertEquals('Backlog', $columns[0]['title']); - - $this->assertEquals(2, $columns[1]['id']); - $this->assertEquals(2, $columns[1]['position']); - $this->assertEquals('Ready', $columns[1]['title']); - - $this->assertEquals(3, $columns[2]['id']); - $this->assertEquals(3, $columns[2]['position']); - $this->assertEquals('Work in progress', $columns[2]['title']); - - $this->assertEquals(4, $columns[3]['id']); - $this->assertEquals(4, $columns[3]['position']); - $this->assertEquals('Done', $columns[3]['title']); - } - - public function testGetList() - { - $projectModel = new ProjectModel($this->container); - $columnModel = new ColumnModel($this->container); - - $this->assertEquals(1, $projectModel->create(array('name' => 'UnitTest'))); - - $columns = $columnModel->getList(1); - $this->assertCount(4, $columns); - $this->assertEquals('Backlog', $columns[1]); - $this->assertEquals('Ready', $columns[2]); - $this->assertEquals('Work in progress', $columns[3]); - $this->assertEquals('Done', $columns[4]); - - $columns = $columnModel->getList(1, true); - $this->assertCount(5, $columns); - $this->assertEquals('All columns', $columns[-1]); - $this->assertEquals('Backlog', $columns[1]); - $this->assertEquals('Ready', $columns[2]); - $this->assertEquals('Work in progress', $columns[3]); - $this->assertEquals('Done', $columns[4]); - } - - public function testAddColumn() - { - $projectModel = new ProjectModel($this->container); - $columnModel = new ColumnModel($this->container); - - $this->assertEquals(1, $projectModel->create(array('name' => 'UnitTest'))); - $this->assertNotFalse($columnModel->create(1, 'another column')); - $this->assertNotFalse($columnModel->create(1, 'one more', 3, 'one more description')); - - $columns = $columnModel->getAll(1); - $this->assertTrue(is_array($columns)); - $this->assertEquals(6, count($columns)); - - $this->assertEquals('another column', $columns[4]['title']); - $this->assertEquals(0, $columns[4]['task_limit']); - $this->assertEquals(5, $columns[4]['position']); - - $this->assertEquals('one more', $columns[5]['title']); - $this->assertEquals(3, $columns[5]['task_limit']); - $this->assertEquals(6, $columns[5]['position']); - $this->assertEquals('one more description', $columns[5]['description']); - } - - public function testUpdateColumn() - { - $projectModel = new ProjectModel($this->container); - $columnModel = new ColumnModel($this->container); - - $this->assertEquals(1, $projectModel->create(array('name' => 'UnitTest'))); - - $this->assertTrue($columnModel->update(3, 'blah', 5)); - $this->assertTrue($columnModel->update(2, 'boo')); - - $column = $columnModel->getById(3); - $this->assertNotEmpty($column); - $this->assertEquals('blah', $column['title']); - $this->assertEquals(5, $column['task_limit']); - - $column = $columnModel->getById(2); - $this->assertNotEmpty($column); - $this->assertEquals('boo', $column['title']); - $this->assertEquals(0, $column['task_limit']); - } - - public function testRemoveColumn() - { - $projectModel = new ProjectModel($this->container); - $columnModel = new ColumnModel($this->container); - - $this->assertEquals(1, $projectModel->create(array('name' => 'UnitTest'))); - $this->assertTrue($columnModel->remove(3)); - $this->assertFalse($columnModel->remove(322)); - - $columns = $columnModel->getAll(1); - $this->assertTrue(is_array($columns)); - $this->assertEquals(3, count($columns)); - } - - public function testChangePosition() - { - $projectModel = new ProjectModel($this->container); - $columnModel = new ColumnModel($this->container); - - $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); - - $columns = $columnModel->getAll(1); - $this->assertEquals(1, $columns[0]['position']); - $this->assertEquals(1, $columns[0]['id']); - $this->assertEquals(2, $columns[1]['position']); - $this->assertEquals(2, $columns[1]['id']); - $this->assertEquals(3, $columns[2]['position']); - $this->assertEquals(3, $columns[2]['id']); - - $this->assertTrue($columnModel->changePosition(1, 3, 2)); - - $columns = $columnModel->getAll(1); - $this->assertEquals(1, $columns[0]['position']); - $this->assertEquals(1, $columns[0]['id']); - $this->assertEquals(2, $columns[1]['position']); - $this->assertEquals(3, $columns[1]['id']); - $this->assertEquals(3, $columns[2]['position']); - $this->assertEquals(2, $columns[2]['id']); - - $this->assertTrue($columnModel->changePosition(1, 2, 1)); - - $columns = $columnModel->getAll(1); - $this->assertEquals(1, $columns[0]['position']); - $this->assertEquals(2, $columns[0]['id']); - $this->assertEquals(2, $columns[1]['position']); - $this->assertEquals(1, $columns[1]['id']); - $this->assertEquals(3, $columns[2]['position']); - $this->assertEquals(3, $columns[2]['id']); - - $this->assertTrue($columnModel->changePosition(1, 2, 2)); - - $columns = $columnModel->getAll(1); - $this->assertEquals(1, $columns[0]['position']); - $this->assertEquals(1, $columns[0]['id']); - $this->assertEquals(2, $columns[1]['position']); - $this->assertEquals(2, $columns[1]['id']); - $this->assertEquals(3, $columns[2]['position']); - $this->assertEquals(3, $columns[2]['id']); - - $this->assertTrue($columnModel->changePosition(1, 4, 1)); - - $columns = $columnModel->getAll(1); - $this->assertEquals(1, $columns[0]['position']); - $this->assertEquals(4, $columns[0]['id']); - $this->assertEquals(2, $columns[1]['position']); - $this->assertEquals(1, $columns[1]['id']); - $this->assertEquals(3, $columns[2]['position']); - $this->assertEquals(2, $columns[2]['id']); - - $this->assertFalse($columnModel->changePosition(1, 2, 0)); - $this->assertFalse($columnModel->changePosition(1, 2, 5)); - } -} -- cgit v1.2.3