diff --git a/app/controllers/KBController.php b/app/controllers/KBController.php index 7c8a600..7bf70f0 100644 --- a/app/controllers/KBController.php +++ b/app/controllers/KBController.php @@ -30,11 +30,11 @@ class KBController { $args[] = $tag_param; if($search_term){ - $sql .= ' AND a.title LIKE ?'; + $sql .= ' AND LOWER(a.title) LIKE LOWER(?)'; $args[] = '%' . $search_term . '%'; } } else if ($search_term){ - $sql .= ' WHERE a.title LIKE ?'; + $sql .= ' WHERE LOWER(a.title) LIKE LOWER(?)'; $args[] = '%' . $search_term . '%'; } @@ -82,7 +82,7 @@ class KBController { $db->exec( 'INSERT INTO kb (title, content, created_by, updated_by, created_at, updated_at) VALUES (?,?,?,?, NOW(), NOW())', - [$title, $content, $created_by] + [$title, $content, $created_by, $created_by] ); $article_id = $db->lastInsertId(); @@ -92,24 +92,26 @@ class KBController { $f3->reroute('/kb'); } + // + + protected function check_kb_exists($article_id, $db, $f3){ + $articles = $db->exec( + 'SELECT * FROM kb WHERE id = ? LIMIT 1', [$article_id] + ); + if(!$articles){ + $f3->set('SESSION.error', 'Article not found'); + $f3->reroute('/kb'); + } + return $articles; + } + // view a single public function view($f3){ $this->check_access($f3); $article_id = $f3->get('PARAMS.id'); $db = $f3->get('DB'); - $articles = $db->exec( - 'SELECT a.*, u.username AS created_by_name - FROM kb AS a - LEFT JOIN users AS u ON a.created_by = u.id - WHERE a.id = ? LIMIT 1', - [$article_id] - ); - - if(!$articles){ - $f3->set('SESSION.error', 'Article not found'); - $f3->reroute('/kb'); - } + $articles = $this->check_kb_exists($article_id, $db, $f3); $article = $articles[0]; $f3->set('article', $article); @@ -118,7 +120,7 @@ class KBController { $tags = $db->exec( 'SELECT t.* FROM tags AS t JOIN kb_tags AS at ON t.id = at.tag_id - WHERE at.article_id = ?', + WHERE at.kb_id = ?', [$article_id] ); @@ -128,4 +130,76 @@ class KBController { $f3->clear('SESSION.error'); } + /** + * Form to edit existing kb article + */ + public function editForm($f3){ + + $this->check_access($f3); + + $article_id = $f3->get('PARAMS.id'); + $db = $f3->get('DB'); + + $articles = $this->check_kb_exists($article_id, $db, $f3); + + $article = $articles[0]; + $f3->set('article', $article); + + // fetch current tags + $current_tag_ids = $db->exec( + 'SELECT tag_id FROM kb_tags WHERE kb_id = ?', [$article_id] + ); + + $article_tag_ids = array_column($current_tag_ids, 'tag_id'); + $f3->set('article_tag_ids', $article_tag_ids); + + // render + $f3->set('content', '../ui/views/kb/edit.html'); + echo \Template::instance()->render('../ui/templates/layout.html'); + $f3->clear('SESSION.error'); + + } + + /** + * Handle POST to edit existing article + */ + public function update($f3){ + $this->check_access($f3); + $article_id = $f3->get('PARAMS.id'); + $db = $f3->get('DB'); + + $articles = $this->check_kb_exists($article_id, $db, $f3); + $article = $articles[0]; + + $title = $f3->get('POST.title'); + $content = $f3->get('POST.content'); + $updated_by = $f3->get('SESSION.user.id'); + + $db->exec( + 'UPDATE kb + SET title=?, content=?, updated_by =?, updated_at = NOW() + WHERE id = ?', + [$title, $content, $updated_by, $article_id] + ); + + // update tags - first delete + $db->exec('DELETE FROM kb_tags WHERE kb_id = ?', [$article_id]); + + $tags_id = $f3->get('POST.tags'); + if(!empty($tags_id) && is_array($tags_id)){ + foreach($tags_id as $tag_id){ + $db->exec( + 'INSERT IGNORE INTO kb_tags (article_id, tag_id) VALUES (?,?)', + [$article_id, $tag_id] + ); + } + } + + $f3->reroute('/kb/'.$article_id); + + } + + + + } \ No newline at end of file diff --git a/app/controllers/TagController.php b/app/controllers/TagController.php new file mode 100644 index 0000000..3a774cb --- /dev/null +++ b/app/controllers/TagController.php @@ -0,0 +1,44 @@ +exists('SESSION.user')){ + $f3->reroute('/login'); + } + } + + /** + * List all tags + */ + public function index($f3){ + $this->check_access($f3); + + $db = $f3->get('DB'); + $tags = $db->exec('SELECT * FROM tags ORDER BY name ASC'); + $f3->set('tags', $tags); + + $f3->set('content', '../ui/views/tag/index.html'); + echo \Template::instance()->render('../ui/templates/layout.html'); + } + + public function createForm($f3){ + $this->check_access($f3); + + $f3->set('content', '../ui/views/tag/create.html'); + echo \Template::instance()->render('../ui/templates/layout.html'); + } + + public function create($f3){ + $this->check_access($f3); + + $name = $f3->get('POST.name'); + $color = $f3->get('POST.color'); + $db = $f3->get('DB'); + + // insert new tag + $db->exec('INSERT IGNORE INTO tags (name, color) VALUES (?, ?)', [$name, $color]); + $f3->reroute('/tags'); + } + +} \ No newline at end of file diff --git a/ui/views/kb/create.html b/ui/views/kb/create.html index ea2cb16..d43eb70 100644 --- a/ui/views/kb/create.html +++ b/ui/views/kb/create.html @@ -1,16 +1,34 @@

Create Knowledge Base Article

-
+
+ - {{ BulmaForm::horizontal_field_input('Title:', 'title') }} + {{ BulmaForm::horizontal_field_input('Title:', 'title') }} - {{ BulmaForm::horizontal_field_textarea('Description:', 'description') }} +
+
+ +
- {{ BulmaForm::horizontal_field_select('Priority:', 'priority', ['Low', 'Medium', 'High'])}} +
+ {{ BulmaForm::horizontal_field_textarea('Content:', 'content') }} +
+
- {{ BulmaForm::horizontal_field_select('Status:', 'status', ['New', 'In Progress', 'On Hold', 'Completed'])}} + - -
-
\ No newline at end of file + +
+
+ Cancel +
+
+ +
+
+ + \ No newline at end of file diff --git a/ui/views/kb/edit.html b/ui/views/kb/edit.html new file mode 100644 index 0000000..3bc6a79 --- /dev/null +++ b/ui/views/kb/edit.html @@ -0,0 +1,25 @@ +

Edit Knowledge Base Article

+ + +
+ + {{ BulmaForm::horizontal_field_input('Title:', 'title', @article.title)}} + +
+
+ +
+ +
+ {{ BulmaForm::horizontal_field_textarea('Content:', 'content', @article.content) }} +
+
+ + + + + +
\ No newline at end of file diff --git a/ui/views/kb/index.html b/ui/views/kb/index.html index 2875984..48f870a 100644 --- a/ui/views/kb/index.html +++ b/ui/views/kb/index.html @@ -6,32 +6,56 @@ -

create kb article

+

create new kb article


- - - - - - - - +
+
+
+
+ +
+
+
+ +
+
+
+ +
+
+ +
- - + +
idtitledescriptionstatusprioritycreated_at
+ - - - - - - - + + - - -
{{@ticket.id}}{{@ticket.title}}{{@ticket.description}}{{@ticket.status}}{{@ticket.priority}}{{@ticket.created_at}} - - - idtitlecreated_at
\ No newline at end of file + + + + + + {{@article.id}} + {{@article.title}} + {{@article.created_at}} + + + + + + + + + + +
+

No articles found.

+
+
\ No newline at end of file diff --git a/ui/views/kb/view.html b/ui/views/kb/view.html index f1c36cb..d4348ea 100644 --- a/ui/views/kb/view.html +++ b/ui/views/kb/view.html @@ -1,18 +1,22 @@ -

Knowledge Article

+

{{@article.title}}

-
+
+ {{ Parsedown::instance()->text(@article.content) }} +
-

{{@article.title}}

- - - - - - - - - -
PropertyValue
{{@key}} {{@value}}
-
+ +
+ + + + + + + + + +
PropertyValue
{{@key}} {{@value}}
+
+
diff --git a/ui/views/tag/create.html b/ui/views/tag/create.html new file mode 100644 index 0000000..0737c17 --- /dev/null +++ b/ui/views/tag/create.html @@ -0,0 +1,29 @@ +

Create Tag

+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+
+ Cancel +
+
+ +
+
+
+
\ No newline at end of file diff --git a/ui/views/tag/index.html b/ui/views/tag/index.html new file mode 100644 index 0000000..e4bfcb1 --- /dev/null +++ b/ui/views/tag/index.html @@ -0,0 +1,45 @@ +

Tags

+ + +
+ {{ @SESSION.error }} +
+
+ +

create new tag

+
+ + + +
+ + {{ @tag.name }} + +
+
+ +
+ No tags found +
+
+
+ + +
+
+

Color Examples

+

The following color names can be used for tags

+
+
+ Black + Dark + Light + White + Primary + Link + Info + Success + Warning + Danger +
+
\ No newline at end of file