diff options
Diffstat (limited to 'plugins/KanboardSearchPlugin')
10 files changed, 428 insertions, 0 deletions
diff --git a/plugins/KanboardSearchPlugin/Controller/AdvancedSearchController.php b/plugins/KanboardSearchPlugin/Controller/AdvancedSearchController.php new file mode 100644 index 00000000..73930fec --- /dev/null +++ b/plugins/KanboardSearchPlugin/Controller/AdvancedSearchController.php @@ -0,0 +1,54 @@ +<?php + +namespace Kanboard\Plugin\KanboardSearchPlugin\Controller; + + +use Kanboard\Controller\BaseController; + + +class AdvancedSearchController extends BaseController +{ + /** + * Display the ASF settings page + * + * @access public + */ + public function index() + { + $this->response->html($this->helper->layout->config('KanboardSearchPlugin:config/advanced-search-filter', array( + 'db_size' => $this->configModel->getDatabaseSize(), + 'db_version' => $this->db->getDriver()->getDatabaseVersion(), + 'user_agent' => $this->request->getServerVariable('HTTP_USER_AGENT'), + 'title' => t('Settings').' > '.t('Advanced Search Filter'), + ))); + } + + /** + * Save settings + * + */ + public function save() + { + $values = $this->request->getValues(); + $redirect = $this->request->getStringParam('redirect', 'index'); + switch ($redirect) { + case 'index': + $values += array( + 'comment_search' => 0, + 'title_search' => 0, + 'description_search' => 0, + 'subtask_search' => 0, + 'attachment_search' => 0 + ); + break; + } + + if ($this->configModel->save($values)) { + $this->languageModel->loadCurrentLanguage(); + $this->flash->success(t('Settings saved successfully.')); + } else { + $this->flash->failure(t('Unable to save your settings.')); + } + $this->response->redirect($this->helper->url->to('AdvancedSearchController', 'index', array('plugin' => 'KanboardSearchPlugin'))); + } +} diff --git a/plugins/KanboardSearchPlugin/Filter/AdvancedSearchFilter.php b/plugins/KanboardSearchPlugin/Filter/AdvancedSearchFilter.php new file mode 100644 index 00000000..5809d37f --- /dev/null +++ b/plugins/KanboardSearchPlugin/Filter/AdvancedSearchFilter.php @@ -0,0 +1,198 @@ +<?php + +namespace Kanboard\Plugin\KanboardSearchPlugin\Filter; + +use Kanboard\Core\Filter\FilterInterface; +use Kanboard\Filter\BaseFilter; +use Kanboard\Model\CommentModel; +use Kanboard\Model\TaskFileModel; +use Kanboard\Model\SubtaskModel; +use Kanboard\Model\TaskModel; +use Kanboard\Model\ConfigModel; +use PicoDb\Database; + + +class AdvancedSearchFilter extends BaseFilter implements FilterInterface +{ + + /** + * Database object + * + * @access private + * @var Database + */ + private $db; + + /** + * @var ConfigModel + */ + private $config; + + /** + * @var TaskFileModel + */ + private $file; + + /** + * Set database object + * + * @access public + * @param Database $db + * @return AdvancedSearchFilter + */ + public function setDatabase(Database $db) + { + $this->db = $db; + return $this; + } + + /** + * Set configModel object + * + * @access public + * @param ConfigModel $config + * @return AdvancedSearchFilter + */ + public function setConfigModel(ConfigModel $config) + { + $this->config = $config; + return $this; + } + + /** + * Set TaskFileModel object + * + * @access public + * @param TaskFileModel $file + * @return AdvancedSearchFilter + */ + public function setFileModel(TaskFileModel $file) + { + $this->file = $file; + return $this; + } + + /** + * Get search attribute + * + * @access public + * @return string[] + */ + public function getAttributes() + { + return array('title', 'comment', 'description', 'desc'); + } + + /** + * Apply filter + * + * @access public + * @return string + */ + public function apply() + { + $commentTaskIds = $this->getTaskIdsWithGivenComment(); + $titlesTaskIds = $this->getTaskIdsWithGivenTitles(); + $descriptionTaskIds = $this->getTaskIdsWithGivenDescription(); + $subtaskTitlesIds = $this->getTaskIdsWithGivenSubtaskTitles(); + $attachmentIds = $this->getTaskIdsWithGivenAttachmentName(); + + $task_ids = array_merge($commentTaskIds, $titlesTaskIds, $descriptionTaskIds, $subtaskTitlesIds, $attachmentIds); + + if (empty($task_ids)) { + $task_ids = array(-1); + } + $this->query->in(TaskModel::TABLE . '.id', $task_ids); + + return $this; + } + + /** + * Get task ids having this comment + * + * @access public + * @return array + */ + protected function getTaskIdsWithGivenComment() + { + if($this->config->get('comment_search') == 1) { + return $this->db + ->table(CommentModel::TABLE) + ->ilike(CommentModel::TABLE . '.comment', '%' . $this->value . '%') + ->findAllByColumn(CommentModel::TABLE . '.task_id'); + } + return array(); + } + + + /** + * Get task ids having this description + * + * @access public + * @return array + */ + protected function getTaskIdsWithGivenDescription() + { + if($this->config->get('description_search') == 1) { + return $this->db + ->table(TaskModel::TABLE) + ->ilike(TaskModel::TABLE . '.description', '%' . $this->value . '%') + ->findAllByColumn(TaskModel::TABLE . '.id'); + } + return array(); + } + + + /** + * Get task ids having this title + * + * @access public + * @return array + */ + private function getTaskIdsWithGivenTitles() + { + if($this->config->get('title_search') == 1) { + return $this->db + ->table(TaskModel::TABLE) + ->ilike(TaskModel::TABLE . '.title', '%' . $this->value . '%') + ->findAllByColumn(TaskModel::TABLE . '.id'); + } + return array(); + } + + + /** + * Get task ids having this Subtask title + * + * @access public + * @return array + */ + private function getTaskIdsWithGivenSubtaskTitles() + { + if($this->config->get('subtask_search') == 1) { + return $this->db + ->table(SubtaskModel::TABLE) + ->ilike(SubtaskModel::TABLE . '.title', '%' . $this->value . '%') + ->findAllByColumn(SubtaskModel::TABLE . '.task_id'); + } + return array(); + } + + + /** + * Get task ids having this Attachment Name + * + * @access public + * @return array + */ + private function getTaskIdsWithGivenAttachmentName() + { + if($this->config->get('attachment_search') == 1) { + return $this->db + ->table(TaskFileModel::TABLE) + ->ilike(TaskFileModel::TABLE . '.name', '%' . $this->value . '%') + ->findAllByColumn(TaskFileModel::TABLE . '.task_id'); + } + return array(); + } +}
\ No newline at end of file diff --git a/plugins/KanboardSearchPlugin/LICENSE b/plugins/KanboardSearchPlugin/LICENSE new file mode 100644 index 00000000..d943a883 --- /dev/null +++ b/plugins/KanboardSearchPlugin/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 ipunkt Business Solutions + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/plugins/KanboardSearchPlugin/Locale/de_DE/translations.php b/plugins/KanboardSearchPlugin/Locale/de_DE/translations.php new file mode 100644 index 00000000..23eecae2 --- /dev/null +++ b/plugins/KanboardSearchPlugin/Locale/de_DE/translations.php @@ -0,0 +1,13 @@ +<?php +return array( + 'Advanced Search Filter' => 'Erweiterter Suchfilter', + 'Advanced Search Filter settings' => 'Erweiterte Suchfilterkonfiguration', + 'This plugin is used for advanced fulltext search within all Projects' => 'Dieses Plugin wird für die erweiterte Volltextsuche in allen Projekten verwendet', + 'Enable "Search in Comment"' => '"Suche in Kommentaren" aktivieren', + 'Enable "Search in Title"' => '"Suche im Titel" aktivieren', + 'Enable "Search in Description"' => '"Suche in Beschreibung" aktivieren', + 'Enable "Search in Subtask Title"' => '"Suche in Teilaufgaben" aktivieren', + 'Enable "Search in Attachments"' => '"Suche in Anhänge" aktivieren', + 'Save' => 'Speichern', + 'Settings' => 'Einstellungen', +);
\ No newline at end of file diff --git a/plugins/KanboardSearchPlugin/Locale/ru_RU/translations.php b/plugins/KanboardSearchPlugin/Locale/ru_RU/translations.php new file mode 100644 index 00000000..411955a9 --- /dev/null +++ b/plugins/KanboardSearchPlugin/Locale/ru_RU/translations.php @@ -0,0 +1,13 @@ +<?php +return array( + 'Advanced Search Filter' => 'Улучшенный поисковой фильтр', + 'Advanced Search Filter settings' => 'Настройки улучшеного поискового фильтра', + 'This plugin is used for advanced fulltext search within all Projects' => 'Этот плагин позволяет выполнять более детальный поиск во всех проэктах', + 'Enable "Search in Comment"' => 'активировать "Поиск в комментариях" ', + 'Enable "Search in Title"' => 'активировать "Поиск в заглавии" ', + 'Enable "Search in Description"' => 'активировать "Поиск по описанию" ', + 'Enable "Search in Subtask Title"' => 'активировать "Поиск в подзадачах" ', + 'Enable "Search in Attachments"' => 'активировать "Поиск во вложениях" ', + 'Save' => 'Сохранить', + 'Settings' => 'Настройки', +);
\ No newline at end of file diff --git a/plugins/KanboardSearchPlugin/Plugin.php b/plugins/KanboardSearchPlugin/Plugin.php new file mode 100644 index 00000000..4b041d1a --- /dev/null +++ b/plugins/KanboardSearchPlugin/Plugin.php @@ -0,0 +1,62 @@ +<?php + +namespace Kanboard\Plugin\KanboardSearchPlugin; + +use Kanboard\Core\Filter\LexerBuilder; +use Kanboard\Core\Plugin\Base; +use Kanboard\Core\Translator; +use Kanboard\Plugin\KanboardSearchPlugin\Filter\AdvancedSearchFilter; + +class Plugin extends Base +{ + public function initialize() + { + $this->template->hook->attach("template:config:sidebar", + "KanboardSearchPlugin:config/sidebar"); + + $this->route->addRoute('settings/advancedsearch', 'AdvancedSearchController', 'index', + 'KanboardSearchPlugin'); + + $this->container->extend('taskLexer', function ($taskLexer, $c) { + /** + * @var LexerBuilder $taskLexer + */ + $taskLexer->withFilter(AdvancedSearchFilter::getInstance() + ->setDatabase($c['db']) + ->setConfigModel($this->configModel) + ->setFileModel($this->taskFileModel), true); + + return $taskLexer; + }); + } + + public function onStartup() + { + Translator::load($this->languageModel->getCurrentLanguage(), __DIR__.'/Locale'); + } + + public function getPluginName() + { + return 'KanboardSearchPlugin'; + } + + public function getPluginDescription() + { + return t('This plugin is used for advanced fulltext search within all Projects'); + } + + public function getPluginAuthor() + { + return 'ipunkt Business Solutions'; + } + + public function getPluginVersion() + { + return '1.0.0'; + } + + public function getPluginHomepage() + { + return 'https://www.ipunkt.biz/unternehmen/opensource'; + } +}
\ No newline at end of file diff --git a/plugins/KanboardSearchPlugin/README.md b/plugins/KanboardSearchPlugin/README.md new file mode 100644 index 00000000..0a964e0b --- /dev/null +++ b/plugins/KanboardSearchPlugin/README.md @@ -0,0 +1,6 @@ +# Kanboard Search Plugin + + +This Plugin is created for advanced fulltext search within all Projects. +The search will be performed in Task title, Task description, Task comments, Subtask title and in Attachments. +All 5 filters can be turned on/off in Kanboard Settings page.
\ No newline at end of file diff --git a/plugins/KanboardSearchPlugin/Template/config/advanced-search-filter.php b/plugins/KanboardSearchPlugin/Template/config/advanced-search-filter.php new file mode 100644 index 00000000..c8dddb8b --- /dev/null +++ b/plugins/KanboardSearchPlugin/Template/config/advanced-search-filter.php @@ -0,0 +1,30 @@ +<div class="page-header"> + <h2><?= t('Advanced Search Filter') ?></h2> +</div> +<form method="post" action="<?= $this->url->href('AdvancedSearchController', 'save', ['plugin' => 'KanboardSearchPlugin']) ?>" autocomplete="off"> + <?= $this->form->csrf() ?> + + <fieldset> + <?= $this->form->checkbox('comment_search', t('Enable "Search in Comment"'), 1, $values['comment_search'] == 1) ?> + </fieldset> + <fieldset> + <?= $this->form->checkbox('title_search', t('Enable "Search in Title"'), 1, $values['title_search'] == 1) ?> + </fieldset> + + <fieldset> + <?= $this->form->checkbox('description_search', t('Enable "Search in Description"'), 1, $values['description_search'] == 1) ?> + </fieldset> + + <fieldset> + <?= $this->form->checkbox('subtask_search', t('Enable "Search in Subtask Title"'), 1, $values['subtask_search'] == 1) ?> + </fieldset> + <fieldset> + <?= $this->form->checkbox('attachment_search', t('Enable "Search in Attachments"'), 1, $values['attachment_search'] == 1) ?> + </fieldset> + + <?= $this->hook->render('template:config:advanced-search-filter', array('values' => $values, 'errors' => $errors)) ?> + + <div class="form-actions"> + <button type="submit" class="btn btn-blue"><?= t('Save') ?></button> + </div> +</form>
\ No newline at end of file diff --git a/plugins/KanboardSearchPlugin/Template/config/sidebar.php b/plugins/KanboardSearchPlugin/Template/config/sidebar.php new file mode 100644 index 00000000..6c2c9b5e --- /dev/null +++ b/plugins/KanboardSearchPlugin/Template/config/sidebar.php @@ -0,0 +1,4 @@ +<li <?= $this->app->checkMenuSelection('AdvancedSearchController', 'index') ?>> + <?= $this->url->link(t('Advanced Search Filter settings'), 'AdvancedSearchController', 'index', + ['plugin' => 'KanboardSearchPlugin']) ?> +</li> diff --git a/plugins/KanboardSearchPlugin/docker-compose.yml b/plugins/KanboardSearchPlugin/docker-compose.yml new file mode 100644 index 00000000..dd5fd508 --- /dev/null +++ b/plugins/KanboardSearchPlugin/docker-compose.yml @@ -0,0 +1,27 @@ +version: '2' +services: + kanboard: + image: kanboard/kanboard:latest + ports: + - "80:80" + volumes: + - .:/var/www/app/plugins/KanboardSearchPlugin + - .:/usr/share/php7 + environment: + DATABASE_URL: mysql://kb:kb-secret@db/kanboard + pma: + image: phpmyadmin/phpmyadmin + ports: + - "8000:80" + environment: + PMA_HOST: db + PMA_USER: kb + PMA_PASSWORD: kb-secret + db: + image: mariadb:latest + command: --default-authentication-plugin=mysql_native_password + environment: + MYSQL_ROOT_PASSWORD: secret + MYSQL_DATABASE: kanboard + MYSQL_USER: kb + MYSQL_PASSWORD: kb-secret
\ No newline at end of file |