summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorFrédéric Guillot <fred@kanboard.net>2014-10-04 23:31:03 -0400
committerFrédéric Guillot <fred@kanboard.net>2014-10-04 23:31:03 -0400
commit8e5673e3d289e4d28b4fc9f20721bda9f1c858c7 (patch)
treea5dc3eff7408e8709d20ea92b926c5424d70c5f9 /app
parentf531d57dc27b9d1568de0a10b19f69e8c2b2f156 (diff)
Improve settings page and move some config parameters to the database
Diffstat (limited to 'app')
-rw-r--r--app/Controller/Base.php9
-rw-r--r--app/Controller/Board.php8
-rw-r--r--app/Controller/Config.php124
-rw-r--r--app/Controller/User.php2
-rw-r--r--app/Controller/Webhook.php4
-rw-r--r--app/Locales/de_DE/translations.php20
-rw-r--r--app/Locales/es_ES/translations.php20
-rw-r--r--app/Locales/fi_FI/translations.php20
-rw-r--r--app/Locales/fr_FR/translations.php20
-rw-r--r--app/Locales/it_IT/translations.php20
-rw-r--r--app/Locales/pl_PL/translations.php20
-rw-r--r--app/Locales/pt_BR/translations.php20
-rw-r--r--app/Locales/ru_RU/translations.php20
-rw-r--r--app/Locales/sv_SE/translations.php20
-rw-r--r--app/Locales/zh_CN/translations.php20
-rw-r--r--app/Model/Config.php70
-rw-r--r--app/Model/Notification.php2
-rw-r--r--app/Model/Project.php2
-rw-r--r--app/Model/Webhook.php6
-rw-r--r--app/Schema/Mysql.php33
-rw-r--r--app/Schema/Postgres.php33
-rw-r--r--app/Schema/Sqlite.php33
-rw-r--r--app/Templates/board_index.php8
-rw-r--r--app/Templates/board_show.php4
-rw-r--r--app/Templates/config_about.php41
-rw-r--r--app/Templates/config_api.php18
-rw-r--r--app/Templates/config_application.php23
-rw-r--r--app/Templates/config_board.php29
-rw-r--r--app/Templates/config_index.php71
-rw-r--r--app/Templates/config_layout.php13
-rw-r--r--app/Templates/config_sidebar.php22
-rw-r--r--app/Templates/config_webhook.php38
-rw-r--r--app/Templates/layout.php4
-rw-r--r--app/Templates/notification_comment_creation.php2
-rw-r--r--app/Templates/notification_comment_update.php2
-rw-r--r--app/Templates/notification_file_creation.php2
-rw-r--r--app/Templates/notification_footer.php4
-rw-r--r--app/Templates/notification_subtask_creation.php2
-rw-r--r--app/Templates/notification_subtask_update.php2
-rw-r--r--app/Templates/notification_task_assignee_change.php2
-rw-r--r--app/Templates/notification_task_close.php2
-rw-r--r--app/Templates/notification_task_creation.php2
-rw-r--r--app/Templates/notification_task_due.php2
-rw-r--r--app/Templates/notification_task_move_column.php2
-rw-r--r--app/Templates/notification_task_move_position.php2
-rw-r--r--app/Templates/notification_task_open.php2
-rw-r--r--app/Templates/notification_task_update.php2
-rw-r--r--app/Templates/project_share.php2
-rw-r--r--app/Templates/project_show.php2
-rw-r--r--app/Templates/user_external.php4
-rw-r--r--app/Templates/user_show.php2
-rw-r--r--app/constants.php9
-rw-r--r--app/helpers.php29
53 files changed, 677 insertions, 198 deletions
diff --git a/app/Controller/Base.php b/app/Controller/Base.php
index e07aabf7..9c1416fc 100644
--- a/app/Controller/Base.php
+++ b/app/Controller/Base.php
@@ -5,7 +5,6 @@ namespace Controller;
use Core\Tool;
use Core\Registry;
use Core\Security;
-use Core\Translator;
use Model\LastLogin;
/**
@@ -123,12 +122,8 @@ abstract class Base
$this->response->hsts();
}
- // Load translations
- $language = $this->config->get('language', 'en_US');
- if ($language !== 'en_US') Translator::load($language);
-
- // Set timezone
- date_default_timezone_set($this->config->get('timezone', 'UTC'));
+ $this->config->setupTranslations();
+ $this->config->setupTimezone();
// Authentication
if (! $this->authentication->isAuthenticated($controller, $action)) {
diff --git a/app/Controller/Board.php b/app/Controller/Board.php
index b56adca0..0e1dd3e1 100644
--- a/app/Controller/Board.php
+++ b/app/Controller/Board.php
@@ -177,8 +177,8 @@ class Board extends Base
'categories' => $this->category->getList($project['id'], false),
'title' => $project['name'],
'no_layout' => true,
- 'auto_refresh' => true,
'not_editable' => true,
+ 'board_public_refresh_interval' => $this->config->get('board_public_refresh_interval'),
)));
}
@@ -238,6 +238,8 @@ class Board extends Base
'menu' => 'boards',
'title' => $projects[$project['id']],
'board_selector' => $board_selector,
+ 'board_private_refresh_interval' => $this->config->get('board_private_refresh_interval'),
+ 'board_highlight_period' => $this->config->get('board_highlight_period'),
)));
}
@@ -407,6 +409,8 @@ class Board extends Base
'current_project_id' => $project_id,
'board' => $this->board->get($project_id),
'categories' => $this->category->getList($project_id, false),
+ 'board_private_refresh_interval' => $this->config->get('board_private_refresh_interval'),
+ 'board_highlight_period' => $this->config->get('board_highlight_period'),
)),
201
);
@@ -443,6 +447,8 @@ class Board extends Base
'current_project_id' => $project_id,
'board' => $this->board->get($project_id),
'categories' => $this->category->getList($project_id, false),
+ 'board_private_refresh_interval' => $this->config->get('board_private_refresh_interval'),
+ 'board_highlight_period' => $this->config->get('board_highlight_period'),
))
);
}
diff --git a/app/Controller/Config.php b/app/Controller/Config.php
index 4c3018c1..869d4331 100644
--- a/app/Controller/Config.php
+++ b/app/Controller/Config.php
@@ -11,59 +11,118 @@ namespace Controller;
class Config extends Base
{
/**
- * Display the settings page
+ * Common layout for config views
*
- * @access public
+ * @access private
+ * @param string $template Template name
+ * @param array $params Template parameters
+ * @return string
*/
- public function index()
+ private function layout($template, array $params)
{
- $this->response->html($this->template->layout('config_index', array(
- 'db_size' => $this->config->getDatabaseSize(),
- 'languages' => $this->config->getLanguages(),
- 'values' => $this->config->getAll(),
- 'errors' => array(),
- 'menu' => 'config',
- 'title' => t('Settings'),
- 'timezones' => $this->config->getTimezones(),
- 'default_columns' => implode(', ', $this->board->getDefaultColumns()),
- )));
+ $params['values'] = $this->config->getAll();
+ $params['errors'] = array();
+ $params['menu'] = 'config';
+ $params['config_content_for_layout'] = $this->template->load($template, $params);
+
+ return $this->template->layout('config_layout', $params);
}
/**
- * Validate and save settings
+ * Common method between pages
*
- * @access public
+ * @access private
+ * @param string $redirect Action to redirect after saving the form
*/
- public function save()
+ private function common($redirect)
{
- $values = $this->request->getValues();
- list($valid, $errors) = $this->config->validateModification($values);
+ if ($this->request->isPost()) {
- if ($valid) {
+ $values = $this->request->getValues();
if ($this->config->save($values)) {
$this->config->reload();
$this->session->flash(t('Settings saved successfully.'));
- } else {
+ }
+ else {
$this->session->flashError(t('Unable to save your settings.'));
}
- $this->response->redirect('?controller=config');
+ $this->response->redirect('?controller=config&action='.$redirect);
}
+ }
- $this->response->html($this->template->layout('config_index', array(
+ /**
+ * Display the about page
+ *
+ * @access public
+ */
+ public function index()
+ {
+ $this->response->html($this->layout('config_about', array(
'db_size' => $this->config->getDatabaseSize(),
+ 'title' => t('About'),
+ )));
+ }
+
+ /**
+ * Display the application settings page
+ *
+ * @access public
+ */
+ public function application()
+ {
+ $this->common('application');
+
+ $this->response->html($this->layout('config_application', array(
+ 'title' => t('Application settings'),
'languages' => $this->config->getLanguages(),
- 'values' => $values,
- 'errors' => $errors,
- 'menu' => 'config',
- 'title' => t('Settings'),
'timezones' => $this->config->getTimezones(),
+ )));
+ }
+
+ /**
+ * Display the board settings page
+ *
+ * @access public
+ */
+ public function board()
+ {
+ $this->common('board');
+
+ $this->response->html($this->layout('config_board', array(
+ 'title' => t('Board settings'),
'default_columns' => implode(', ', $this->board->getDefaultColumns()),
)));
}
/**
+ * Display the webhook settings page
+ *
+ * @access public
+ */
+ public function webhook()
+ {
+ $this->common('webhook');
+
+ $this->response->html($this->layout('config_webhook', array(
+ 'title' => t('Webhook settings'),
+ )));
+ }
+
+ /**
+ * Display the api settings page
+ *
+ * @access public
+ */
+ public function api()
+ {
+ $this->response->html($this->layout('config_api', array(
+ 'title' => t('API'),
+ )));
+ }
+
+ /**
* Download the Sqlite database
*
* @access public
@@ -89,15 +148,18 @@ class Config extends Base
}
/**
- * Regenerate all application tokens
+ * Regenerate webhook token
*
* @access public
*/
- public function tokens()
+ public function token()
{
+ $type = $this->request->getStringParam('type');
+
$this->checkCSRFParam();
- $this->config->regenerateTokens();
- $this->session->flash(t('All tokens have been regenerated.'));
- $this->response->redirect('?controller=config');
+ $this->config->regenerateToken($type.'_token');
+
+ $this->session->flash(t('Token regenerated.'));
+ $this->response->redirect('?controller=config&action='.$type);
}
}
diff --git a/app/Controller/User.php b/app/Controller/User.php
index cc7464e6..bbed9f6f 100644
--- a/app/Controller/User.php
+++ b/app/Controller/User.php
@@ -73,7 +73,7 @@ class User extends Base
}
/**
- * Common layout for project views
+ * Common layout for user views
*
* @access private
* @param string $template Template name
diff --git a/app/Controller/Webhook.php b/app/Controller/Webhook.php
index c72dc983..71acab08 100644
--- a/app/Controller/Webhook.php
+++ b/app/Controller/Webhook.php
@@ -17,7 +17,7 @@ class Webhook extends Base
*/
public function task()
{
- if ($this->config->get('webhooks_token') !== $this->request->getStringParam('token')) {
+ if ($this->config->get('webhook_token') !== $this->request->getStringParam('token')) {
$this->response->text('Not Authorized', 401);
}
@@ -49,7 +49,7 @@ class Webhook extends Base
*/
public function github()
{
- if ($this->config->get('webhooks_token') !== $this->request->getStringParam('token')) {
+ if ($this->config->get('webhook_token') !== $this->request->getStringParam('token')) {
$this->response->text('Not Authorized', 401);
}
diff --git a/app/Locales/de_DE/translations.php b/app/Locales/de_DE/translations.php
index ec570691..93721f65 100644
--- a/app/Locales/de_DE/translations.php
+++ b/app/Locales/de_DE/translations.php
@@ -83,7 +83,7 @@ return array(
'Settings' => 'Einstellungen',
'Application settings' => 'Anwendungskonfiguration',
'Language' => 'Sprache',
- 'Webhooks token:' => 'Webhooks Token:',
+ // 'Webhook token:' => '',
'API token:' => 'API Token:',
'More information' => 'Mehr Informationen',
'Database size:' => 'Datenbankgröße:',
@@ -516,4 +516,22 @@ return array(
// 'Reference' => '',
// 'Reference: %s' => '',
// 'Label' => '',
+ // 'Database' => '',
+ // 'About' => '',
+ // 'Database driver:' => '',
+ // 'Board settings' => '',
+ // 'URL and token' => '',
+ // 'Webhook settings' => '',
+ // 'URL for task creation:' => '',
+ // 'Reset token' => '',
+ // 'API endpoint:' => '',
+ // 'Refresh interval for private board' => '',
+ // 'Refresh interval for public board' => '',
+ // 'Task highlight period' => '',
+ // 'Period (in second) to consider a task was modified recently (0 to disable, 2 days by default)' => '',
+ // 'Frequency in second (60 seconds by default)' => '',
+ // 'Frequency in second (0 to disable this feature, 10 seconds by default)' => '',
+ // 'Application URL' => '',
+ // 'Example: http://example.kanboard.net/ (used by email notifications)' => '',
+ // 'Token regenerated.' => '',
);
diff --git a/app/Locales/es_ES/translations.php b/app/Locales/es_ES/translations.php
index 05646a74..8b92b9a5 100644
--- a/app/Locales/es_ES/translations.php
+++ b/app/Locales/es_ES/translations.php
@@ -83,7 +83,7 @@ return array(
'Settings' => 'Preferencias',
'Application settings' => 'Parámetros de la aplicación',
'Language' => 'Idioma',
- 'Webhooks token:' => 'Ficha de seguridad (token) para los webhooks :',
+ 'Webhook token:' => 'Ficha de seguridad (token) para los webhooks :',
'API token:' => 'Ficha de seguridad (token) para API:',
'More information' => 'Más informaciones',
'Database size:' => 'Tamaño de la base de datos:',
@@ -516,4 +516,22 @@ return array(
// 'Reference' => '',
// 'Reference: %s' => '',
// 'Label' => '',
+ // 'Database' => '',
+ // 'About' => '',
+ // 'Database driver:' => '',
+ // 'Board settings' => '',
+ // 'URL and token' => '',
+ // 'Webhook settings' => '',
+ // 'URL for task creation:' => '',
+ // 'Reset token' => '',
+ // 'API endpoint:' => '',
+ // 'Refresh interval for private board' => '',
+ // 'Refresh interval for public board' => '',
+ // 'Task highlight period' => '',
+ // 'Period (in second) to consider a task was modified recently (0 to disable, 2 days by default)' => '',
+ // 'Frequency in second (60 seconds by default)' => '',
+ // 'Frequency in second (0 to disable this feature, 10 seconds by default)' => '',
+ // 'Application URL' => '',
+ // 'Example: http://example.kanboard.net/ (used by email notifications)' => '',
+ // 'Token regenerated.' => '',
);
diff --git a/app/Locales/fi_FI/translations.php b/app/Locales/fi_FI/translations.php
index 3bb2185e..923ba970 100644
--- a/app/Locales/fi_FI/translations.php
+++ b/app/Locales/fi_FI/translations.php
@@ -83,7 +83,7 @@ return array(
'Settings' => 'Asetukset',
'Application settings' => 'Ohjelman asetukset',
'Language' => 'Kieli',
- 'Webhooks token:' => 'Webhooks avain:',
+ 'Webhook token:' => 'Webhooks avain:',
// 'API token:' => '',
'More information' => 'Lisätietoja',
'Database size:' => 'Tietokannan koko:',
@@ -516,4 +516,22 @@ return array(
// 'Reference' => '',
// 'Reference: %s' => '',
// 'Label' => '',
+ // 'Database' => '',
+ // 'About' => '',
+ // 'Database driver:' => '',
+ // 'Board settings' => '',
+ // 'URL and token' => '',
+ // 'Webhook settings' => '',
+ // 'URL for task creation:' => '',
+ // 'Reset token' => '',
+ // 'API endpoint:' => '',
+ // 'Refresh interval for private board' => '',
+ // 'Refresh interval for public board' => '',
+ // 'Task highlight period' => '',
+ // 'Period (in second) to consider a task was modified recently (0 to disable, 2 days by default)' => '',
+ // 'Frequency in second (60 seconds by default)' => '',
+ // 'Frequency in second (0 to disable this feature, 10 seconds by default)' => '',
+ // 'Application URL' => '',
+ // 'Example: http://example.kanboard.net/ (used by email notifications)' => '',
+ // 'Token regenerated.' => '',
);
diff --git a/app/Locales/fr_FR/translations.php b/app/Locales/fr_FR/translations.php
index c1723875..19c15f86 100644
--- a/app/Locales/fr_FR/translations.php
+++ b/app/Locales/fr_FR/translations.php
@@ -83,7 +83,7 @@ return array(
'Settings' => 'Préférences',
'Application settings' => 'Paramètres de l\'application',
'Language' => 'Langue',
- 'Webhooks token:' => 'Jeton de securité pour les webhooks :',
+ 'Webhook token:' => 'Jeton de securité pour les webhooks :',
'API token:' => 'Jeton de securité pour l\'API :',
'More information' => 'Plus d\'informations',
'Database size:' => 'Taille de la base de données :',
@@ -516,4 +516,22 @@ return array(
'Reference' => 'Référence',
'Reference: %s' => 'Référence : %s',
'Label' => 'Libellé',
+ 'Database' => 'Base de données',
+ 'About' => 'A propos',
+ 'Database driver:' => 'Type de base de données :',
+ 'Board settings' => 'Paramètres du tableau',
+ 'URL and token' => 'URL et jeton de sécurité',
+ 'Webhook settings' => 'Paramètres pour les webhooks',
+ 'URL for task creation:' => 'URL pour la création de tâche :',
+ 'Reset token' => 'Regénérer le jeton de sécurité',
+ 'API endpoint:' => 'URL de l\'API :',
+ 'Refresh interval for private board' => 'Intervalle pour rafraîchir un tableau privé',
+ 'Refresh interval for public board' => 'Intervalle pour rafraîchir un tableau public',
+ 'Task highlight period' => 'Durée pour mettre une tâche en évidence',
+ 'Period (in second) to consider a task was modified recently (0 to disable, 2 days by default)' => 'Durée en seconde pour considérer une tâche comme récemment modifiée (0 pour désactiver, 2 jours par défaut)',
+ 'Frequency in second (60 seconds by default)' => 'Fréquence en seconde (60 secondes par défaut)',
+ 'Frequency in second (0 to disable this feature, 10 seconds by default)' => 'Fréquence en seconde (0 pour désactiver, 10 secondes par défaut)',
+ 'Application URL' => 'URL de l\'application',
+ 'Example: http://example.kanboard.net/ (used by email notifications)' => 'Exemple : http://exemple.kanboard.net/ (utilisé pour les notifications)',
+ 'Token regenerated.' => 'Jeton de sécurité regénéré.',
);
diff --git a/app/Locales/it_IT/translations.php b/app/Locales/it_IT/translations.php
index 6acac109..e5b5eb57 100644
--- a/app/Locales/it_IT/translations.php
+++ b/app/Locales/it_IT/translations.php
@@ -83,7 +83,7 @@ return array(
'Settings' => 'Impostazioni',
'Application settings' => 'Impostazioni dell\'applicazione',
'Language' => 'Lingua',
- 'Webhooks token:' => 'Identificatore (token) per i webhooks :',
+ 'Webhook token:' => 'Identificatore (token) per i webhooks :',
// 'API token:' => '',
'More information' => 'Più informazioni',
'Database size:' => 'Dimensioni della base dati:',
@@ -516,4 +516,22 @@ return array(
// 'Reference' => '',
// 'Reference: %s' => '',
// 'Label' => '',
+ // 'Database' => '',
+ // 'About' => '',
+ // 'Database driver:' => '',
+ // 'Board settings' => '',
+ // 'URL and token' => '',
+ // 'Webhook settings' => '',
+ // 'URL for task creation:' => '',
+ // 'Reset token' => '',
+ // 'API endpoint:' => '',
+ // 'Refresh interval for private board' => '',
+ // 'Refresh interval for public board' => '',
+ // 'Task highlight period' => '',
+ // 'Period (in second) to consider a task was modified recently (0 to disable, 2 days by default)' => '',
+ // 'Frequency in second (60 seconds by default)' => '',
+ // 'Frequency in second (0 to disable this feature, 10 seconds by default)' => '',
+ // 'Application URL' => '',
+ // 'Example: http://example.kanboard.net/ (used by email notifications)' => '',
+ // 'Token regenerated.' => '',
);
diff --git a/app/Locales/pl_PL/translations.php b/app/Locales/pl_PL/translations.php
index 3e33ce8b..cdf200b9 100644
--- a/app/Locales/pl_PL/translations.php
+++ b/app/Locales/pl_PL/translations.php
@@ -83,7 +83,7 @@ return array(
'Settings' => 'Ustawienia',
'Application settings' => 'Ustawienia aplikacji',
'Language' => 'Język',
- 'Webhooks token:' => 'Token :',
+ 'Webhook token:' => 'Token :',
// 'API token:' => '',
'More information' => 'Więcej informacji',
'Database size:' => 'Rozmiar bazy danych :',
@@ -516,4 +516,22 @@ return array(
// 'Reference' => '',
// 'Reference: %s' => '',
// 'Label' => '',
+ // 'Database' => '',
+ // 'About' => '',
+ // 'Database driver:' => '',
+ // 'Board settings' => '',
+ // 'URL and token' => '',
+ // 'Webhook settings' => '',
+ // 'URL for task creation:' => '',
+ // 'Reset token' => '',
+ // 'API endpoint:' => '',
+ // 'Refresh interval for private board' => '',
+ // 'Refresh interval for public board' => '',
+ // 'Task highlight period' => '',
+ // 'Period (in second) to consider a task was modified recently (0 to disable, 2 days by default)' => '',
+ // 'Frequency in second (60 seconds by default)' => '',
+ // 'Frequency in second (0 to disable this feature, 10 seconds by default)' => '',
+ // 'Application URL' => '',
+ // 'Example: http://example.kanboard.net/ (used by email notifications)' => '',
+ // 'Token regenerated.' => '',
);
diff --git a/app/Locales/pt_BR/translations.php b/app/Locales/pt_BR/translations.php
index 68946936..1524355d 100644
--- a/app/Locales/pt_BR/translations.php
+++ b/app/Locales/pt_BR/translations.php
@@ -83,7 +83,7 @@ return array(
'Settings' => 'Preferências',
'Application settings' => 'Preferências da aplicação',
'Language' => 'Idioma',
- 'Webhooks token:' => 'Token de webhooks:',
+ 'Webhook token:' => 'Token de webhooks:',
'API token:' => 'API Token:',
'More information' => 'Mais informação',
'Database size:' => 'Tamanho do banco de dados:',
@@ -516,4 +516,22 @@ return array(
// 'Reference' => '',
// 'Reference: %s' => '',
// 'Label' => '',
+ // 'Database' => '',
+ // 'About' => '',
+ // 'Database driver:' => '',
+ // 'Board settings' => '',
+ // 'URL and token' => '',
+ // 'Webhook settings' => '',
+ // 'URL for task creation:' => '',
+ // 'Reset token' => '',
+ // 'API endpoint:' => '',
+ // 'Refresh interval for private board' => '',
+ // 'Refresh interval for public board' => '',
+ // 'Task highlight period' => '',
+ // 'Period (in second) to consider a task was modified recently (0 to disable, 2 days by default)' => '',
+ // 'Frequency in second (60 seconds by default)' => '',
+ // 'Frequency in second (0 to disable this feature, 10 seconds by default)' => '',
+ // 'Application URL' => '',
+ // 'Example: http://example.kanboard.net/ (used by email notifications)' => '',
+ // 'Token regenerated.' => '',
);
diff --git a/app/Locales/ru_RU/translations.php b/app/Locales/ru_RU/translations.php
index a949dbd0..e5e3e8bc 100644
--- a/app/Locales/ru_RU/translations.php
+++ b/app/Locales/ru_RU/translations.php
@@ -83,7 +83,7 @@ return array(
'Settings' => 'Настройки',
'Application settings' => 'Настройки приложения',
'Language' => 'Язык',
- 'Webhooks token:' => 'Webhooks токен :',
+ 'Webhook token:' => 'Webhooks токен :',
'API token:' => 'API токен :',
'More information' => 'Подробнее',
'Database size:' => 'Размер базы данных :',
@@ -516,4 +516,22 @@ return array(
// 'Reference' => '',
// 'Reference: %s' => '',
// 'Label' => '',
+ // 'Database' => '',
+ // 'About' => '',
+ // 'Database driver:' => '',
+ // 'Board settings' => '',
+ // 'URL and token' => '',
+ // 'Webhook settings' => '',
+ // 'URL for task creation:' => '',
+ // 'Reset token' => '',
+ // 'API endpoint:' => '',
+ // 'Refresh interval for private board' => '',
+ // 'Refresh interval for public board' => '',
+ // 'Task highlight period' => '',
+ // 'Period (in second) to consider a task was modified recently (0 to disable, 2 days by default)' => '',
+ // 'Frequency in second (60 seconds by default)' => '',
+ // 'Frequency in second (0 to disable this feature, 10 seconds by default)' => '',
+ // 'Application URL' => '',
+ // 'Example: http://example.kanboard.net/ (used by email notifications)' => '',
+ // 'Token regenerated.' => '',
);
diff --git a/app/Locales/sv_SE/translations.php b/app/Locales/sv_SE/translations.php
index 68c0597f..4c8aef81 100644
--- a/app/Locales/sv_SE/translations.php
+++ b/app/Locales/sv_SE/translations.php
@@ -83,7 +83,7 @@ return array(
'Settings' => 'Inställningar',
'Application settings' => 'Applikationsinställningar',
'Language' => 'Språk',
- 'Webhooks token:' => 'Token för webhooks:',
+ 'Webhook token:' => 'Token för webhooks:',
'API token:' => 'API token:',
'More information' => 'Mer information',
'Database size:' => 'Databasstorlek:',
@@ -516,4 +516,22 @@ return array(
// 'Reference' => '',
// 'Reference: %s' => '',
// 'Label' => '',
+ // 'Database' => '',
+ // 'About' => '',
+ // 'Database driver:' => '',
+ // 'Board settings' => '',
+ // 'URL and token' => '',
+ // 'Webhook settings' => '',
+ // 'URL for task creation:' => '',
+ // 'Reset token' => '',
+ // 'API endpoint:' => '',
+ // 'Refresh interval for private board' => '',
+ // 'Refresh interval for public board' => '',
+ // 'Task highlight period' => '',
+ // 'Period (in second) to consider a task was modified recently (0 to disable, 2 days by default)' => '',
+ // 'Frequency in second (60 seconds by default)' => '',
+ // 'Frequency in second (0 to disable this feature, 10 seconds by default)' => '',
+ // 'Application URL' => '',
+ // 'Example: http://example.kanboard.net/ (used by email notifications)' => '',
+ // 'Token regenerated.' => '',
);
diff --git a/app/Locales/zh_CN/translations.php b/app/Locales/zh_CN/translations.php
index ef33881e..3285e9a6 100644
--- a/app/Locales/zh_CN/translations.php
+++ b/app/Locales/zh_CN/translations.php
@@ -83,7 +83,7 @@ return array(
'Settings' => '设置',
'Application settings' => '应用设置',
'Language' => '语言',
- 'Webhooks token:' => '页面钩子令牌:',
+ 'Webhook token:' => '页面钩子令牌:',
// 'API token:' => '',
'More information' => '更多信息',
'Database size:' => '数据库大小:',
@@ -516,4 +516,22 @@ return array(
// 'Reference' => '',
// 'Reference: %s' => '',
// 'Label' => '',
+ // 'Database' => '',
+ // 'About' => '',
+ // 'Database driver:' => '',
+ // 'Board settings' => '',
+ // 'URL and token' => '',
+ // 'Webhook settings' => '',
+ // 'URL for task creation:' => '',
+ // 'Reset token' => '',
+ // 'API endpoint:' => '',
+ // 'Refresh interval for private board' => '',
+ // 'Refresh interval for public board' => '',
+ // 'Task highlight period' => '',
+ // 'Period (in second) to consider a task was modified recently (0 to disable, 2 days by default)' => '',
+ // 'Frequency in second (60 seconds by default)' => '',
+ // 'Frequency in second (0 to disable this feature, 10 seconds by default)' => '',
+ // 'Application URL' => '',
+ // 'Example: http://example.kanboard.net/ (used by email notifications)' => '',
+ // 'Token regenerated.' => '',
);
diff --git a/app/Model/Config.php b/app/Model/Config.php
index f411e3e2..da261de6 100644
--- a/app/Model/Config.php
+++ b/app/Model/Config.php
@@ -6,6 +6,7 @@ use SimpleValidator\Validator;
use SimpleValidator\Validators;
use Core\Translator;
use Core\Security;
+use Core\Session;
/**
* Config model
@@ -20,7 +21,7 @@ class Config extends Base
*
* @var string
*/
- const TABLE = 'config';
+ const TABLE = 'settings';
/**
* Get available timezones
@@ -68,6 +69,11 @@ class Config extends Base
*/
public function get($name, $default_value = '')
{
+ if (! Session::isOpen()) {
+ $value = $this->db->table(self::TABLE)->eq('option', $name)->findOneColumn('value');
+ return $value ?: $default_value;
+ }
+
if (! isset($_SESSION['config'][$name])) {
$_SESSION['config'] = $this->getAll();
}
@@ -87,7 +93,7 @@ class Config extends Base
*/
public function getAll()
{
- return $this->db->table(self::TABLE)->findOne();
+ return $this->db->table(self::TABLE)->listing('option', 'value');
}
/**
@@ -99,8 +105,16 @@ class Config extends Base
*/
public function save(array $values)
{
- $_SESSION['config'] = $values;
- return $this->db->table(self::TABLE)->update($values);
+ foreach ($values as $option => $value) {
+
+ $result = $this->db->table(self::TABLE)->eq('option', $option)->update(array('value' => $value));
+
+ if (! $result) {
+ return false;
+ }
+ }
+
+ return true;
}
/**
@@ -111,27 +125,31 @@ class Config extends Base
public function reload()
{
$_SESSION['config'] = $this->getAll();
- Translator::load($this->get('language', 'en_US'));
+ $this->setupTranslations();
}
/**
- * Validate settings modification
+ * Load translations
*
* @access public
- * @param array $values Form values
- * @return array $valid, $errors [0] = Success or not, [1] = List of errors
*/
- public function validateModification(array $values)
+ public function setupTranslations()
{
- $v = new Validator($values, array(
- new Validators\Required('language', t('The language is required')),
- new Validators\Required('timezone', t('The timezone is required')),
- ));
+ $language = $this->get('application_language', 'en_US');
- return array(
- $v->execute(),
- $v->getErrors()
- );
+ if ($language !== 'en_US') {
+ Translator::load($language);
+ }
+ }
+
+ /**
+ * Set timezone
+ *
+ * @access public
+ */
+ public function setupTimezone()
+ {
+ date_default_timezone_set($this->get('application_timezone', 'UTC'));
}
/**
@@ -168,21 +186,15 @@ class Config extends Base
}
/**
- * Regenerate all tokens (projects and webhooks)
+ * Regenerate a token
*
* @access public
+ * @param string $option Parameter name
*/
- public function regenerateTokens()
+ public function regenerateToken($option)
{
- $this->db->table(self::TABLE)->update(array(
- 'webhooks_token' => Security::generateToken(),
- 'api_token' => Security::generateToken(),
- ));
-
- $projects = $this->db->table(Project::TABLE)->findAllByColumn('id');
-
- foreach ($projects as $project_id) {
- $this->db->table(Project::TABLE)->eq('id', $project_id)->update(array('token' => Security::generateToken()));
- }
+ return $this->db->table(self::TABLE)
+ ->eq('option', $option)
+ ->update(array('value' => Security::generateToken()));
}
}
diff --git a/app/Model/Notification.php b/app/Model/Notification.php
index a7dd7fc0..3c14caf0 100644
--- a/app/Model/Notification.php
+++ b/app/Model/Notification.php
@@ -182,7 +182,7 @@ class Notification extends Base
public function getMailContent($template, array $data)
{
$tpl = new Template;
- return $tpl->load($template, $data);
+ return $tpl->load($template, $data + array('application_url' => $this->config->get('application_url')));
}
/**
diff --git a/app/Model/Project.php b/app/Model/Project.php
index c3e8cc55..d2b769ed 100644
--- a/app/Model/Project.php
+++ b/app/Model/Project.php
@@ -287,7 +287,7 @@ class Project extends Base
}
$project_id = $this->db->getConnection()->getLastId();
- $column_names = explode(',', $this->config->get('default_columns', implode(',', $this->board->getDefaultColumns())));
+ $column_names = explode(',', $this->config->get('board_columns', implode(',', $this->board->getDefaultColumns())));
$columns = array();
foreach ($column_names as $column_name) {
diff --git a/app/Model/Webhook.php b/app/Model/Webhook.php
index e03bdcb4..241806ba 100644
--- a/app/Model/Webhook.php
+++ b/app/Model/Webhook.php
@@ -64,9 +64,9 @@ class Webhook extends Base
*/
public function attachEvents()
{
- $this->url_task_creation = $this->config->get('webhooks_url_task_creation');
- $this->url_task_modification = $this->config->get('webhooks_url_task_modification');
- $this->token = $this->config->get('webhooks_token');
+ $this->url_task_creation = $this->config->get('webhook_url_task_creation');
+ $this->url_task_modification = $this->config->get('webhook_url_task_modification');
+ $this->token = $this->config->get('webhook_token');
if ($this->url_task_creation) {
$this->attachCreateEvents();
diff --git a/app/Schema/Mysql.php b/app/Schema/Mysql.php
index 577fac80..e6a33ee5 100644
--- a/app/Schema/Mysql.php
+++ b/app/Schema/Mysql.php
@@ -2,9 +2,40 @@
namespace Schema;
+use PDO;
use Core\Security;
-const VERSION = 28;
+const VERSION = 29;
+
+function version_29($pdo)
+{
+ $pdo->exec("
+ CREATE TABLE settings (
+ option VARCHAR(100) PRIMARY KEY,
+ value VARCHAR(255) DEFAULT ''
+ )
+ ");
+
+ // Migrate old config parameters
+ $rq = $pdo->prepare('SELECT * FROM config');
+ $rq->execute();
+ $parameters = $rq->fetch(PDO::FETCH_ASSOC);
+
+ $rq = $pdo->prepare('INSERT INTO settings VALUES (?, ?)');
+ $rq->execute(array('board_highlight_period', defined('RECENT_TASK_PERIOD') ? RECENT_TASK_PERIOD : 48*60*60));
+ $rq->execute(array('board_public_refresh_interval', defined('BOARD_PUBLIC_CHECK_INTERVAL') ? BOARD_PUBLIC_CHECK_INTERVAL : 60));
+ $rq->execute(array('board_private_refresh_interval', defined('BOARD_CHECK_INTERVAL') ? BOARD_CHECK_INTERVAL : 10));
+ $rq->execute(array('board_columns', $parameters['default_columns']));
+ $rq->execute(array('webhook_url_task_creation', $parameters['webhooks_url_task_creation']));
+ $rq->execute(array('webhook_url_task_modification', $parameters['webhooks_url_task_modification']));
+ $rq->execute(array('webhook_token', $parameters['webhooks_token']));
+ $rq->execute(array('api_token', $parameters['api_token']));
+ $rq->execute(array('application_language', $parameters['language']));
+ $rq->execute(array('application_timezone', $parameters['timezone']));
+ $rq->execute(array('application_url', defined('KANBOARD_URL') ? KANBOARD_URL : ''));
+
+ $pdo->exec('DROP TABLE config');
+}
function version_28($pdo)
{
diff --git a/app/Schema/Postgres.php b/app/Schema/Postgres.php
index 33859513..0eeb2a72 100644
--- a/app/Schema/Postgres.php
+++ b/app/Schema/Postgres.php
@@ -2,9 +2,40 @@
namespace Schema;
+use PDO;
use Core\Security;
-const VERSION = 9;
+const VERSION = 10;
+
+function version_10($pdo)
+{
+ $pdo->exec("
+ CREATE TABLE settings (
+ option VARCHAR(100) PRIMARY KEY,
+ value VARCHAR(255) DEFAULT ''
+ )
+ ");
+
+ // Migrate old config parameters
+ $rq = $pdo->prepare('SELECT * FROM config');
+ $rq->execute();
+ $parameters = $rq->fetch(PDO::FETCH_ASSOC);
+
+ $rq = $pdo->prepare('INSERT INTO settings VALUES (?, ?)');
+ $rq->execute(array('board_highlight_period', defined('RECENT_TASK_PERIOD') ? RECENT_TASK_PERIOD : 48*60*60));
+ $rq->execute(array('board_public_refresh_interval', defined('BOARD_PUBLIC_CHECK_INTERVAL') ? BOARD_PUBLIC_CHECK_INTERVAL : 60));
+ $rq->execute(array('board_private_refresh_interval', defined('BOARD_CHECK_INTERVAL') ? BOARD_CHECK_INTERVAL : 10));
+ $rq->execute(array('board_columns', $parameters['default_columns']));
+ $rq->execute(array('webhook_url_task_creation', $parameters['webhooks_url_task_creation']));
+ $rq->execute(array('webhook_url_task_modification', $parameters['webhooks_url_task_modification']));
+ $rq->execute(array('webhook_token', $parameters['webhooks_token']));
+ $rq->execute(array('api_token', $parameters['api_token']));
+ $rq->execute(array('application_language', $parameters['language']));
+ $rq->execute(array('application_timezone', $parameters['timezone']));
+ $rq->execute(array('application_url', defined('KANBOARD_URL') ? KANBOARD_URL : ''));
+
+ $pdo->exec('DROP TABLE config');
+}
function version_9($pdo)
{
diff --git a/app/Schema/Sqlite.php b/app/Schema/Sqlite.php
index d9b3787d..5986d327 100644
--- a/app/Schema/Sqlite.php
+++ b/app/Schema/Sqlite.php
@@ -3,8 +3,39 @@
namespace Schema;
use Core\Security;
+use PDO;
-const VERSION = 28;
+const VERSION = 29;
+
+function version_29($pdo)
+{
+ $pdo->exec("
+ CREATE TABLE settings (
+ option TEXT PRIMARY KEY,
+ value TEXT DEFAULT ''
+ )
+ ");
+
+ // Migrate old config parameters
+ $rq = $pdo->prepare('SELECT * FROM config');
+ $rq->execute();
+ $parameters = $rq->fetch(PDO::FETCH_ASSOC);
+
+ $rq = $pdo->prepare('INSERT INTO settings VALUES (?, ?)');
+ $rq->execute(array('board_highlight_period', defined('RECENT_TASK_PERIOD') ? RECENT_TASK_PERIOD : 48*60*60));
+ $rq->execute(array('board_public_refresh_interval', defined('BOARD_PUBLIC_CHECK_INTERVAL') ? BOARD_PUBLIC_CHECK_INTERVAL : 60));
+ $rq->execute(array('board_private_refresh_interval', defined('BOARD_CHECK_INTERVAL') ? BOARD_CHECK_INTERVAL : 10));
+ $rq->execute(array('board_columns', $parameters['default_columns']));
+ $rq->execute(array('webhook_url_task_creation', $parameters['webhooks_url_task_creation']));
+ $rq->execute(array('webhook_url_task_modification', $parameters['webhooks_url_task_modification']));
+ $rq->execute(array('webhook_token', $parameters['webhooks_token']));
+ $rq->execute(array('api_token', $parameters['api_token']));
+ $rq->execute(array('application_language', $parameters['language']));
+ $rq->execute(array('application_timezone', $parameters['timezone']));
+ $rq->execute(array('application_url', defined('KANBOARD_URL') ? KANBOARD_URL : ''));
+
+ $pdo->exec('DROP TABLE config');
+}
function version_28($pdo)
{
diff --git a/app/Templates/board_index.php b/app/Templates/board_index.php
index da40468d..bff7dcc9 100644
--- a/app/Templates/board_index.php
+++ b/app/Templates/board_index.php
@@ -26,7 +26,13 @@
<?php if (empty($board)): ?>
<p class="alert alert-error"><?= t('There is no column in your project!') ?></p>
<?php else: ?>
- <?= Helper\template('board_show', array('current_project_id' => $current_project_id, 'board' => $board, 'categories' => $categories)) ?>
+ <?= Helper\template('board_show', array(
+ 'current_project_id' => $current_project_id,
+ 'board' => $board,
+ 'categories' => $categories,
+ 'board_private_refresh_interval' => $board_private_refresh_interval,
+ 'board_highlight_period' => $board_highlight_period,
+ )) ?>
<?php endif ?>
</section>
diff --git a/app/Templates/board_show.php b/app/Templates/board_show.php
index e91ab4cf..e8c3c1ba 100644
--- a/app/Templates/board_show.php
+++ b/app/Templates/board_show.php
@@ -1,4 +1,4 @@
-<table id="board" data-project-id="<?= $current_project_id ?>" data-time="<?= time() ?>" data-check-interval="<?= BOARD_CHECK_INTERVAL ?>" data-csrf-token=<?= \Core\Security::getCSRFToken() ?>>
+<table id="board" data-project-id="<?= $current_project_id ?>" data-time="<?= time() ?>" data-check-interval="<?= $board_private_refresh_interval ?>" data-csrf-token=<?= \Core\Security::getCSRFToken() ?>>
<tr>
<?php $column_with = round(100 / count($board), 2); ?>
<?php foreach ($board as $column): ?>
@@ -32,7 +32,7 @@
data-task-limit="<?= $column['task_limit'] ?>"
>
<?php foreach ($column['tasks'] as $task): ?>
- <div class="task-board draggable-item task-<?= $task['color_id'] ?> <?= $task['date_modification'] > time() - RECENT_TASK_PERIOD ? 'task-board-recent' : '' ?>"
+ <div class="task-board draggable-item task-<?= $task['color_id'] ?> <?= $task['date_modification'] > time() - $board_highlight_period ? 'task-board-recent' : '' ?>"
data-task-id="<?= $task['id'] ?>"
data-owner-id="<?= $task['owner_id'] ?>"
data-category-id="<?= $task['category_id'] ?>"
diff --git a/app/Templates/config_about.php b/app/Templates/config_about.php
new file mode 100644
index 00000000..3f34f802
--- /dev/null
+++ b/app/Templates/config_about.php
@@ -0,0 +1,41 @@
+<div class="page-header">
+ <h2><?= t('About') ?></h2>
+</div>
+<section class="listing">
+ <ul>
+ <li>
+ <?= t('Official website:') ?>
+ <a href="http://kanboard.net/" target="_blank" rel="noreferer">http://kanboard.net/</a>
+ </li>
+ <li>
+ <?= t('Application version:') ?>
+ <strong><?= APP_VERSION ?></strong>
+ </li>
+ </ul>
+</section>
+
+<div class="page-header">
+ <h2><?= t('Database') ?></h2>
+</div>
+<section class="listing">
+ <ul>
+ <li>
+ <?= t('Database driver:') ?>
+ <strong><?= Helper\escape(DB_DRIVER) ?></strong>
+ </li>
+ <?php if (DB_DRIVER === 'sqlite'): ?>
+ <li>
+ <?= t('Database size:') ?>
+ <strong><?= Helper\format_bytes($db_size) ?></strong>
+ </li>
+ <li>
+ <?= Helper\a(t('Download the database'), 'config', 'downloadDb', array(), true) ?>&nbsp;
+ <?= t('(Gzip compressed Sqlite file)') ?>
+ </li>
+ <li>
+ <?= Helper\a(t('Optimize the database'), 'config', 'optimizeDb', array(), true) ?>&nbsp;
+ <?= t('(VACUUM command)') ?>
+ </li>
+ <?php endif ?>
+ </ul>
+</section> \ No newline at end of file
diff --git a/app/Templates/config_api.php b/app/Templates/config_api.php
new file mode 100644
index 00000000..037ea08d
--- /dev/null
+++ b/app/Templates/config_api.php
@@ -0,0 +1,18 @@
+<div class="page-header">
+ <h2><?= t('API') ?></h2>
+</div>
+<section class="listing">
+ <ul>
+ <li>
+ <?= t('API token:') ?>
+ <strong><?= Helper\escape($values['api_token']) ?></strong>
+ </li>
+ <li>
+ <?= t('API endpoint:') ?>
+ <input type="text" readonly="readonly" value="<?= Helper\get_current_base_url().'jsonrpc.php' ?>">
+ </li>
+ <li>
+ <?= Helper\a(t('Reset token'), 'config', 'token', array('type' => 'api'), true) ?>
+ </li>
+ </ul>
+</section> \ No newline at end of file
diff --git a/app/Templates/config_application.php b/app/Templates/config_application.php
new file mode 100644
index 00000000..251a45dc
--- /dev/null
+++ b/app/Templates/config_application.php
@@ -0,0 +1,23 @@
+<div class="page-header">
+ <h2><?= t('Application settings') ?></h2>
+</div>
+<section>
+<form method="post" action="<?= Helper\u('config', 'application') ?>" autocomplete="off">
+
+ <?= Helper\form_csrf() ?>
+
+ <?= Helper\form_label(t('Application URL'), 'application_url') ?>
+ <?= Helper\form_text('application_url', $values, $errors, array('placeholder="http://example.kanboar.net/"')) ?><br/>
+ <p class="form-help"><?= t('Example: http://example.kanboard.net/ (used by email notifications)') ?></p>
+
+ <?= Helper\form_label(t('Language'), 'application_language') ?>
+ <?= Helper\form_select('application_language', $languages, $values, $errors) ?><br/>
+
+ <?= Helper\form_label(t('Timezone'), 'application_timezone') ?>
+ <?= Helper\form_select('application_timezone', $timezones, $values, $errors) ?><br/>
+
+ <div class="form-actions">
+ <input type="submit" value="<?= t('Save') ?>" class="btn btn-blue"/>
+ </div>
+</form>
+</section> \ No newline at end of file
diff --git a/app/Templates/config_board.php b/app/Templates/config_board.php
new file mode 100644
index 00000000..f260d084
--- /dev/null
+++ b/app/Templates/config_board.php
@@ -0,0 +1,29 @@
+<div class="page-header">
+ <h2><?= t('Board settings') ?></h2>
+</div>
+<section>
+<form method="post" action="<?= Helper\u('config', 'board') ?>" autocomplete="off">
+
+ <?= Helper\form_csrf() ?>
+
+ <?= Helper\form_label(t('Task highlight period'), 'board_highlight_period') ?>
+ <?= Helper\form_number('board_highlight_period', $values, $errors) ?><br/>
+ <p class="form-help"><?= t('Period (in second) to consider a task was modified recently (0 to disable, 2 days by default)') ?></p>
+
+ <?= Helper\form_label(t('Refresh interval for public board'), 'board_public_refresh_interval') ?>
+ <?= Helper\form_number('board_public_refresh_interval', $values, $errors) ?><br/>
+ <p class="form-help"><?= t('Frequency in second (60 seconds by default)') ?></p>
+
+ <?= Helper\form_label(t('Refresh interval for private board'), 'board_private_refresh_interval') ?>
+ <?= Helper\form_number('board_private_refresh_interval', $values, $errors) ?><br/>
+ <p class="form-help"><?= t('Frequency in second (0 to disable this feature, 10 seconds by default)') ?></p>
+
+ <?= Helper\form_label(t('Default columns for new projects (Comma-separated)'), 'board_columns') ?>
+ <?= Helper\form_text('board_columns', $values, $errors) ?><br/>
+ <p class="form-help"><?= t('Default values are "%s"', $default_columns) ?></p>
+
+ <div class="form-actions">
+ <input type="submit" value="<?= t('Save') ?>" class="btn btn-blue"/>
+ </div>
+</form>
+</section> \ No newline at end of file
diff --git a/app/Templates/config_index.php b/app/Templates/config_index.php
deleted file mode 100644
index 2d9ce116..00000000
--- a/app/Templates/config_index.php
+++ /dev/null
@@ -1,71 +0,0 @@
-<section id="main">
-
- <div class="page-header">
- <h2><?= t('Application settings') ?></h2>
- </div>
- <section>
- <form method="post" action="?controller=config&amp;action=save" autocomplete="off">
-
- <?= Helper\form_csrf() ?>
-
- <?= Helper\form_label(t('Language'), 'language') ?>
- <?= Helper\form_select('language', $languages, $values, $errors) ?><br/>
-
- <?= Helper\form_label(t('Timezone'), 'timezone') ?>
- <?= Helper\form_select('timezone', $timezones, $values, $errors) ?><br/>
-
- <?= Helper\form_label(t('Webhook URL for task creation'), 'webhooks_url_task_creation') ?>
- <?= Helper\form_text('webhooks_url_task_creation', $values, $errors) ?><br/>
-
- <?= Helper\form_label(t('Webhook URL for task modification'), 'webhooks_url_task_modification') ?>
- <?= Helper\form_text('webhooks_url_task_modification', $values, $errors) ?><br/>
-
- <?= Helper\form_label(t('Default columns for new projects (Comma-separated)'), 'default_columns') ?>
- <?= Helper\form_text('default_columns', $values, $errors) ?><br/>
- <p class="form-help"><?= t('Default values are "%s"', $default_columns) ?></p>
-
- <div class="form-actions">
- <input type="submit" value="<?= t('Save') ?>" class="btn btn-blue"/>
- </div>
- </form>
- </section>
-
- <div class="page-header">
- <h2><?= t('More information') ?></h2>
- </div>
- <section class="settings">
- <ul>
- <li><a href="?controller=config&amp;action=tokens<?= Helper\param_csrf() ?>"><?= t('Reset all tokens') ?></a></li>
- <li>
- <?= t('Webhooks token:') ?>
- <strong><?= Helper\escape($values['webhooks_token']) ?></strong>
- </li>
- <li>
- <?= t('API token:') ?>
- <strong><?= Helper\escape($values['api_token']) ?></strong>
- </li>
- <?php if (DB_DRIVER === 'sqlite'): ?>
- <li>
- <?= t('Database size:') ?>
- <strong><?= Helper\format_bytes($db_size) ?></strong>
- </li>
- <li>
- <a href="?controller=config&amp;action=downloadDb<?= Helper\param_csrf() ?>"><?= t('Download the database') ?></a>
- <?= t('(Gzip compressed Sqlite file)') ?>
- </li>
- <li>
- <a href="?controller=config&amp;action=optimizeDb <?= Helper\param_csrf() ?>"><?= t('Optimize the database') ?></a>
- <?= t('(VACUUM command)') ?>
- </li>
- <?php endif ?>
- <li>
- <?= t('Official website:') ?>
- <a href="http://kanboard.net/" target="_blank" rel="noreferer">http://kanboard.net/</a>
- </li>
- <li>
- <?= t('Application version:') ?>
- <?= APP_VERSION ?>
- </li>
- </ul>
- </section>
-</section>
diff --git a/app/Templates/config_layout.php b/app/Templates/config_layout.php
new file mode 100644
index 00000000..3aacb9b7
--- /dev/null
+++ b/app/Templates/config_layout.php
@@ -0,0 +1,13 @@
+<section id="main">
+ <div class="page-header">
+ <h2><?= t('Settings') ?></h2>
+ </div>
+ <section class="config-show" id="config-section">
+
+ <?= Helper\template('config_sidebar') ?>
+
+ <div class="config-show-main">
+ <?= $config_content_for_layout ?>
+ </div>
+ </section>
+</section> \ No newline at end of file
diff --git a/app/Templates/config_sidebar.php b/app/Templates/config_sidebar.php
new file mode 100644
index 00000000..d96159b8
--- /dev/null
+++ b/app/Templates/config_sidebar.php
@@ -0,0 +1,22 @@
+<div class="config-show-sidebar">
+ <h2><?= t('Actions') ?></h2>
+ <div class="config-show-actions">
+ <ul>
+ <li>
+ <?= Helper\a(t('About'), 'config', 'index') ?>
+ </li>
+ <li>
+ <?= Helper\a(t('Application settings'), 'config', 'application') ?>
+ </li>
+ <li>
+ <?= Helper\a(t('Board settings'), 'config', 'board') ?>
+ </li>
+ <li>
+ <?= Helper\a(t('Webhooks'), 'config', 'webhook') ?>
+ </li>
+ <li>
+ <?= Helper\a(t('API'), 'config', 'api') ?>
+ </li>
+ </ul>
+ </div>
+</div> \ No newline at end of file
diff --git a/app/Templates/config_webhook.php b/app/Templates/config_webhook.php
new file mode 100644
index 00000000..052a2a99
--- /dev/null
+++ b/app/Templates/config_webhook.php
@@ -0,0 +1,38 @@
+<div class="page-header">
+ <h2><?= t('Webhook settings') ?></h2>
+</div>
+<section>
+<form method="post" action="<?= Helper\u('config', 'webhook') ?>" autocomplete="off">
+
+ <?= Helper\form_csrf() ?>
+
+ <?= Helper\form_label(t('Webhook URL for task creation'), 'webhook_url_task_creation') ?>
+ <?= Helper\form_text('webhook_url_task_creation', $values, $errors) ?><br/>
+
+ <?= Helper\form_label(t('Webhook URL for task modification'), 'webhook_url_task_modification') ?>
+ <?= Helper\form_text('webhook_url_task_modification', $values, $errors) ?><br/>
+
+ <div class="form-actions">
+ <input type="submit" value="<?= t('Save') ?>" class="btn btn-blue"/>
+ </div>
+</form>
+</section>
+
+<div class="page-header">
+ <h2><?= t('URL and token') ?></h2>
+</div>
+<section class="listing">
+ <ul>
+ <li>
+ <?= t('Webhook token:') ?>
+ <strong><?= Helper\escape($values['webhook_token']) ?></strong>
+ </li>
+ <li>
+ <?= t('URL for task creation:') ?>
+ <input type="text" readonly="readonly" value="<?= Helper\get_current_base_url().Helper\u('webhook', 'task', array('token' => $values['webhook_token'])) ?>">
+ </li>
+ <li>
+ <?= Helper\a(t('Reset token'), 'config', 'token', array('type' => 'webhook'), true) ?>
+ </li>
+ </ul>
+</section> \ No newline at end of file
diff --git a/app/Templates/layout.php b/app/Templates/layout.php
index e0158dfb..434c5aca 100644
--- a/app/Templates/layout.php
+++ b/app/Templates/layout.php
@@ -6,8 +6,8 @@
<meta name="mobile-web-app-capable" content="yes">
<meta name="robots" content="noindex,nofollow">
- <?php if (isset($auto_refresh)): ?>
- <meta http-equiv="refresh" content="<?= BOARD_PUBLIC_CHECK_INTERVAL ?>" >
+ <?php if (isset($board_public_refresh_interval)): ?>
+ <meta http-equiv="refresh" content="<?= $board_public_refresh_interval ?>" >
<?php endif ?>
<?php if (! isset($not_editable)): ?>
diff --git a/app/Templates/notification_comment_creation.php b/app/Templates/notification_comment_creation.php
index fac6ea25..5b334d76 100644
--- a/app/Templates/notification_comment_creation.php
+++ b/app/Templates/notification_comment_creation.php
@@ -4,4 +4,4 @@
<?= Helper\markdown($comment['comment']) ?>
-<?= Helper\template('notification_footer', array('task' => $task)) ?> \ No newline at end of file
+<?= Helper\template('notification_footer', array('task' => $task, 'application_url' => $application_url)) ?> \ No newline at end of file
diff --git a/app/Templates/notification_comment_update.php b/app/Templates/notification_comment_update.php
index 92c06ffb..04aafb85 100644
--- a/app/Templates/notification_comment_update.php
+++ b/app/Templates/notification_comment_update.php
@@ -4,4 +4,4 @@
<?= Helper\markdown($comment['comment']) ?>
-<?= Helper\template('notification_footer', array('task' => $task)) ?> \ No newline at end of file
+<?= Helper\template('notification_footer', array('task' => $task, 'application_url' => $application_url)) ?> \ No newline at end of file
diff --git a/app/Templates/notification_file_creation.php b/app/Templates/notification_file_creation.php
index 50f4a2d5..d8636820 100644
--- a/app/Templates/notification_file_creation.php
+++ b/app/Templates/notification_file_creation.php
@@ -2,4 +2,4 @@
<h3><?= t('New attachment added "%s"', $file['name']) ?></h3>
-<?= Helper\template('notification_footer', array('task' => $task)) ?> \ No newline at end of file
+<?= Helper\template('notification_footer', array('task' => $task, 'application_url' => $application_url)) ?> \ No newline at end of file
diff --git a/app/Templates/notification_footer.php b/app/Templates/notification_footer.php
index f0c9c0d4..533621f4 100644
--- a/app/Templates/notification_footer.php
+++ b/app/Templates/notification_footer.php
@@ -1,6 +1,6 @@
<hr/>
Kanboard
-<?php if (defined('KANBOARD_URL')): ?>
- - <a href="<?= KANBOARD_URL.'?controller=task&action=show&task_id='.$task['id'] ?>"><?= t('view the task on Kanboard') ?></a>.
+<?php if ($application_url): ?>
+ - <a href="<?= $application_url.'?controller=task&action=show&task_id='.$task['id'] ?>"><?= t('view the task on Kanboard') ?></a>.
<?php endif ?>
diff --git a/app/Templates/notification_subtask_creation.php b/app/Templates/notification_subtask_creation.php
index c382355c..2ddfc649 100644
--- a/app/Templates/notification_subtask_creation.php
+++ b/app/Templates/notification_subtask_creation.php
@@ -14,4 +14,4 @@
</li>
</ul>
-<?= Helper\template('notification_footer', array('task' => $task)) ?> \ No newline at end of file
+<?= Helper\template('notification_footer', array('task' => $task, 'application_url' => $application_url)) ?> \ No newline at end of file
diff --git a/app/Templates/notification_subtask_update.php b/app/Templates/notification_subtask_update.php
index ad6dfdc9..999edbf9 100644
--- a/app/Templates/notification_subtask_update.php
+++ b/app/Templates/notification_subtask_update.php
@@ -18,4 +18,4 @@
</li>
</ul>
-<?= Helper\template('notification_footer', array('task' => $task)) ?> \ No newline at end of file
+<?= Helper\template('notification_footer', array('task' => $task, 'application_url' => $application_url)) ?> \ No newline at end of file
diff --git a/app/Templates/notification_task_assignee_change.php b/app/Templates/notification_task_assignee_change.php
index 65194f1e..d23f769e 100644
--- a/app/Templates/notification_task_assignee_change.php
+++ b/app/Templates/notification_task_assignee_change.php
@@ -17,4 +17,4 @@
<?= Helper\markdown($task['description']) ?: t('There is no description.') ?>
<?php endif ?>
-<?= Helper\template('notification_footer', array('task' => $task)) ?> \ No newline at end of file
+<?= Helper\template('notification_footer', array('task' => $task, 'application_url' => $application_url)) ?> \ No newline at end of file
diff --git a/app/Templates/notification_task_close.php b/app/Templates/notification_task_close.php
index d9b2dce6..d56e71bb 100644
--- a/app/Templates/notification_task_close.php
+++ b/app/Templates/notification_task_close.php
@@ -2,4 +2,4 @@
<p><?= t('The task #%d have been closed.', $task['id']) ?></p>
-<?= Helper\template('notification_footer', array('task' => $task)) ?> \ No newline at end of file
+<?= Helper\template('notification_footer', array('task' => $task, 'application_url' => $application_url)) ?> \ No newline at end of file
diff --git a/app/Templates/notification_task_creation.php b/app/Templates/notification_task_creation.php
index 43b3b291..1b555096 100644
--- a/app/Templates/notification_task_creation.php
+++ b/app/Templates/notification_task_creation.php
@@ -40,4 +40,4 @@
<?= Helper\markdown($task['description']) ?>
<?php endif ?>
-<?= Helper\template('notification_footer', array('task' => $task)) ?> \ No newline at end of file
+<?= Helper\template('notification_footer', array('task' => $task, 'application_url' => $application_url)) ?> \ No newline at end of file
diff --git a/app/Templates/notification_task_due.php b/app/Templates/notification_task_due.php
index 25ecc9f1..ae02f64e 100644
--- a/app/Templates/notification_task_due.php
+++ b/app/Templates/notification_task_due.php
@@ -12,4 +12,4 @@
<?php endforeach ?>
</ul>
-<?= Helper\template('notification_footer', array('task' => $task)) ?> \ No newline at end of file
+<?= Helper\template('notification_footer', array('task' => $task, 'application_url' => $application_url)) ?> \ No newline at end of file
diff --git a/app/Templates/notification_task_move_column.php b/app/Templates/notification_task_move_column.php
index 026db776..c3f94df7 100644
--- a/app/Templates/notification_task_move_column.php
+++ b/app/Templates/notification_task_move_column.php
@@ -8,4 +8,4 @@
<li><?= t('Task position:').' '.Helper\escape($task['position']) ?></li>
</ul>
-<?= Helper\template('notification_footer', array('task' => $task)) ?> \ No newline at end of file
+<?= Helper\template('notification_footer', array('task' => $task, 'application_url' => $application_url)) ?> \ No newline at end of file
diff --git a/app/Templates/notification_task_move_position.php b/app/Templates/notification_task_move_position.php
index 026db776..c3f94df7 100644
--- a/app/Templates/notification_task_move_position.php
+++ b/app/Templates/notification_task_move_position.php
@@ -8,4 +8,4 @@
<li><?= t('Task position:').' '.Helper\escape($task['position']) ?></li>
</ul>
-<?= Helper\template('notification_footer', array('task' => $task)) ?> \ No newline at end of file
+<?= Helper\template('notification_footer', array('task' => $task, 'application_url' => $application_url)) ?> \ No newline at end of file
diff --git a/app/Templates/notification_task_open.php b/app/Templates/notification_task_open.php
index 7bf674cc..5d9f7d5b 100644
--- a/app/Templates/notification_task_open.php
+++ b/app/Templates/notification_task_open.php
@@ -2,4 +2,4 @@
<p><?= t('The task #%d have been opened.', $task['id']) ?></p>
-<?= Helper\template('notification_footer', array('task' => $task)) ?> \ No newline at end of file
+<?= Helper\template('notification_footer', array('task' => $task, 'application_url' => $application_url)) ?> \ No newline at end of file
diff --git a/app/Templates/notification_task_update.php b/app/Templates/notification_task_update.php
index 9fd61b57..b3c07911 100644
--- a/app/Templates/notification_task_update.php
+++ b/app/Templates/notification_task_update.php
@@ -40,4 +40,4 @@
<?= Helper\markdown($task['description']) ?: t('There is no description.') ?>
<?php endif ?>
-<?= Helper\template('notification_footer', array('task' => $task)) ?> \ No newline at end of file
+<?= Helper\template('notification_footer', array('task' => $task, 'application_url' => $application_url)) ?> \ No newline at end of file
diff --git a/app/Templates/project_share.php b/app/Templates/project_share.php
index 6cfd85f6..f06d7671 100644
--- a/app/Templates/project_share.php
+++ b/app/Templates/project_share.php
@@ -4,7 +4,7 @@
<?php if ($project['is_public']): ?>
- <div class="settings">
+ <div class="listing">
<ul class="no-bullet">
<li><strong><i class="fa fa-share-alt"></i> <a href="?controller=board&amp;action=readonly&amp;token=<?= $project['token'] ?>" target="_blank"><?= t('Public link') ?></a></strong></li>
<li><strong><i class="fa fa-rss-square"></i> <a href="?controller=project&amp;action=feed&amp;token=<?= $project['token'] ?>" target="_blank"><?= t('RSS feed') ?></a></strong></li>
diff --git a/app/Templates/project_show.php b/app/Templates/project_show.php
index 98ffb581..96b9e404 100644
--- a/app/Templates/project_show.php
+++ b/app/Templates/project_show.php
@@ -1,7 +1,7 @@
<div class="page-header">
<h2><?= t('Summary') ?></h2>
</div>
-<ul class="settings">
+<ul class="listing">
<li><strong><?= $project['is_active'] ? t('Active') : t('Inactive') ?></strong></li>
<?php if ($project['is_public']): ?>
diff --git a/app/Templates/user_external.php b/app/Templates/user_external.php
index a67d886e..676b2c73 100644
--- a/app/Templates/user_external.php
+++ b/app/Templates/user_external.php
@@ -5,7 +5,7 @@
<?php if (GOOGLE_AUTH): ?>
<h3><i class="fa fa-google"></i> <?= t('Google Account') ?></h3>
- <p class="settings">
+ <p class="listing">
<?php if (Helper\is_current_user($user['id'])): ?>
<?php if (empty($user['google_id'])): ?>
<a href="?controller=user&amp;action=google<?= Helper\param_csrf() ?>"><?= t('Link my Google Account') ?></a>
@@ -21,7 +21,7 @@
<?php if (GITHUB_AUTH): ?>
<h3><i class="fa fa-github"></i> <?= t('Github Account') ?></h3>
- <p class="settings">
+ <p class="listing">
<?php if (Helper\is_current_user($user['id'])): ?>
<?php if (empty($user['github_id'])): ?>
<a href="?controller=user&amp;action=gitHub<?= Helper\param_csrf() ?>"><?= t('Link my GitHub Account') ?></a>
diff --git a/app/Templates/user_show.php b/app/Templates/user_show.php
index 5d42d3cf..1c843751 100644
--- a/app/Templates/user_show.php
+++ b/app/Templates/user_show.php
@@ -1,7 +1,7 @@
<div class="page-header">
<h2><?= t('Summary') ?></h2>
</div>
-<ul class="settings">
+<ul class="listing">
<li><?= t('Username:') ?> <strong><?= Helper\escape($user['username']) ?></strong></li>
<li><?= t('Name:') ?> <strong><?= Helper\escape($user['name']) ?></strong></li>
<li><?= t('Email:') ?> <strong><?= Helper\escape($user['email']) ?></strong></li>
diff --git a/app/constants.php b/app/constants.php
index 777e6f0e..93075892 100644
--- a/app/constants.php
+++ b/app/constants.php
@@ -1,14 +1,5 @@
<?php
-// Board refresh frequency in seconds for the public board view
-defined('BOARD_PUBLIC_CHECK_INTERVAL') or define('BOARD_PUBLIC_CHECK_INTERVAL', 60);
-
-// Board refresh frequency in seconds (the value 0 disable this feature)
-defined('BOARD_CHECK_INTERVAL') or define('BOARD_CHECK_INTERVAL', 10);
-
-// Period (in second) to consider a task was modified recently
-defined('RECENT_TASK_PERIOD') or define('RECENT_TASK_PERIOD', 48*60*60);
-
// Custom session save path
defined('SESSION_SAVE_PATH') or define('SESSION_SAVE_PATH', '');
diff --git a/app/helpers.php b/app/helpers.php
index 5cb7b82e..1ab8586a 100644
--- a/app/helpers.php
+++ b/app/helpers.php
@@ -556,16 +556,37 @@ function form_numeric($name, $values = array(), array $errors = array(), array $
* @param string $controller Controller name
* @param string $action Action name
* @param array $params Url parameters
+ * @param boolean $csrf Add a CSRF token
* @param string $class CSS class attribute
* @return string
*/
-function a($label, $controller, $action, array $params = array(), $css = '')
+function a($label, $controller, $action, array $params = array(), $csrf = false, $class = '')
{
- $html = '<a href="?controller='.$controller.'&amp;action='.$action;
+ return '<a href="'.u($controller, $action, $params, $csrf).'" class="'.$class.'"/>'.$label.'</a>';
+}
+
+/**
+ * URL
+ *
+ * a('link', 'task', 'show', array('task_id' => $task_id))
+ *
+ * @param string $controller Controller name
+ * @param string $action Action name
+ * @param array $params Url parameters
+ * @param boolean $csrf Add a CSRF token
+ * @return string
+ */
+function u($controller, $action, array $params = array(), $csrf = false)
+{
+ $html = '?controller='.$controller.'&amp;action='.$action;
+
+ if ($csrf) {
+ $params['csrf_token'] = Security::getCSRFToken();
+ }
foreach ($params as $key => $value) {
$html .= '&amp;'.$key.'='.$value;
}
- return '" class="'.$class.'"/>'.$label.'</a>';
-}
+ return $html;
+} \ No newline at end of file