From 503c02aaacc8ee414ff548ed2fd0d6fbec1407e3 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Fri, 27 May 2022 13:16:48 +0000 Subject: [PATCH] added a primitive global search view --- codepot/src/codepot/controllers/site.php | 95 ++++++++++++++++++++ codepot/src/codepot/models/filemodel.php | 77 ++++++++++++++++ codepot/src/codepot/models/issuemodel.php | 103 ++++++++++++++++++++++ codepot/src/codepot/models/wikimodel.php | 69 +++++++++++++++ codepot/src/codepot/views/Makefile.am | 1 + codepot/src/codepot/views/Makefile.in | 1 + 6 files changed, 346 insertions(+) diff --git a/codepot/src/codepot/controllers/site.php b/codepot/src/codepot/controllers/site.php index d9a1317d..939a028d 100644 --- a/codepot/src/codepot/controllers/site.php +++ b/codepot/src/codepot/controllers/site.php @@ -9,6 +9,7 @@ class Site extends CI_Controller var $VIEW_DELETE = 'site_delete'; var $VIEW_CATALOG = 'site_catalog'; var $VIEW_LOG = 'log'; + var $VIEW_SEARCH = 'site_search'; function __construct () { @@ -609,6 +610,100 @@ class Site extends CI_Controller redirect ("wiki/attachment/{$part[0]}/{$hexwikiname}/{$hexattname}"); } } + + function search ($scope = '', $needle = '') + { + $login = $this->login->getUser (); + if (CODEPOT_SIGNIN_COMPULSORY && $login['id'] == '') + redirect (CODEPOT_SIGNIN_REDIR_PATH . $this->converter->AsciiTohex(current_url())); + + $search = new stdClass(); + $search->scope = $scope; + $search->needle = $this->converter->HexToAscii($needle); + + $data['login'] = $login; + $data['search'] = $search; + + $this->load->view ($this->VIEW_SEARCH, $data); + } + + function enjson_search ($filter = '', $offset = '') + { + $this->load->model ('WikiModel', 'wikis'); + $this->load->model ('IssueModel', 'issues'); + $this->load->model ('FileModel', 'files'); + + $login = $this->login->getUser (); + if (CODEPOT_SIGNIN_COMPULSORY && $login['id'] == '') + { + $status = 'signin'; + $results = array(); + } + else + { + $scope = ''; + $needle = ''; + if ($filter != '') + { + parse_str ($this->converter->HexToAscii($filter), $search); + if (array_key_exists ('scope', $search)) $scope = $search['scope']; + if (array_key_exists ('needle', $search)) $needle = $search['needle']; + } + + if ($filter == '' && $offset == '') + { + $offset = 0; + } + else if ($filter != '' && $offset == '') + { + if (is_numeric($filter)) + { + $offset = (integer)$filter; + } + else + { + $offset = 0; + } + } + else + { + $offset = (integer)$offset; + } + + $status = 'ok'; + $results = array(); + + if ($scope == 'wikis' || $scope == 'all') + { + $x = $this->wikis->search($needle); + if ($x === FALSE) $status = 'dberr'; + else $results = array_merge($results, $x); + } + + if ($scope == 'issues' || $scope == 'all') + { + $x = $this->issues->search($needle); + if ($x === FALSE) $status = 'dberr'; + else $results = array_merge($results, $x); + } + + if ($scope == 'files' || $scope == 'all') + { + $x = $this->files->search($needle); + if ($x === FALSE) $status = 'dberr'; + else $results = array_merge($results, $x); + } + + if ($status != 'ok') $results = array(); + } + + $data = array ( + 'status' => $status, + 'results' => $results + ); + + print codepot_json_encode($data); + } } ?> diff --git a/codepot/src/codepot/models/filemodel.php b/codepot/src/codepot/models/filemodel.php index adfd2263..d5599adf 100644 --- a/codepot/src/codepot/models/filemodel.php +++ b/codepot/src/codepot/models/filemodel.php @@ -560,6 +560,83 @@ class FileModel extends CI_Model restore_error_handler (); return $x; } + + function search ($needle = '') + { + $items = array(); + if ($needle == '') return $items; + + $this->db->trans_start (); + + $this->db->select ('projectid,name,tag,description'); + $this->db->like ('name', $needle); + $this->db->or_like ('tag', $needle); + $this->db->or_like ('description', $needle); + $query = $this->db->get('file'); + if ($this->db->trans_status() === FALSE) + { + $this->db->trans_complete (); + return FALSE; + } + + $result = $query->result(); + if (!empty($result)) + { + foreach ($result as $r) + { + $posa = stripos($r->name, $needle); + $posb = stripos($r->tag, $needle); + $posc = stripos($r->description, $needle); + if ($posa !== false || $posb !== false || $posc !== false) + { + $text = ""; + if ($posc !== false) + { + $start_pos = $posc - 30; + if ($start_pos < 0) $start_pos = 0; + $text = substr($r->description, $start_pos, strlen($needle) + 100); + } + array_push ($items, array( 'type' => 'file_holder', 'projectid' => $r->projectid, 'name' => $r->name, 'tag' => $r->tag, 'partial_text' => $text)); + } + } + } + + $this->db->select ('projectid,name,filename,description'); + $this->db->like ('filename', $needle); + $this->db->or_like ('description', $needle); + $query = $this->db->get ('file_list'); + + if ($this->db->trans_status() === FALSE) + { + $this->db->trans_complete (); + return FALSE; + } + + $result = $query->result(); + if (!empty($result)) + { + foreach ($result as $r) + { + $posa = stripos($r->filename, $needle); + $posb = stripos($r->description, $needle); + if ($posa !== false || $posb !== false) + { + $text = ""; + if ($posb !== false) + { + $start_pos = $posb - 30; + if ($start_pos < 0) $start_pos = 0; + $text = substr($r->description, $start_pos, strlen($needle) + 30); + } + array_push ($items, array( 'type' => 'file', 'projectid' => $r->projectid, 'name' => $r->name, 'filename' => $r->filename, 'partial_text' => $text)); + } + } + } + + $this->db->trans_complete (); + + return $items; + } } ?> diff --git a/codepot/src/codepot/models/issuemodel.php b/codepot/src/codepot/models/issuemodel.php index 0de8b8de..9acf7575 100644 --- a/codepot/src/codepot/models/issuemodel.php +++ b/codepot/src/codepot/models/issuemodel.php @@ -1076,6 +1076,109 @@ class IssueModel extends CI_Model $issue = &$result[0]; return ($issue->createdby == $userid || $issue->updatedby == $userid); } + + function search ($needle = '') + { + $items = array(); + if ($needle == '') return $items; + + $this->db->trans_start (); + + $this->db->select ('projectid,id,summary,description'); + $this->db->like ('summary', $needle); + $this->db->or_like ('description', $needle); + $query = $this->db->get('issue'); + if ($this->db->trans_status() === FALSE) + { + $this->db->trans_complete (); + return FALSE; + } + + $result = $query->result(); + if (!empty($result)) + { + foreach ($result as $r) + { + $posa = stripos($r->summary, $needle); + $posb = stripos($r->description, $needle); + if ($posa !== false || $posb !== false) + { + $text = ""; + if ($posb !== false) + { + $start_pos = $posb - 30; + if ($start_pos < 0) $start_pos = 0; + $text = substr($r->description, $start_pos, strlen($needle) + 100); + } + array_push ($items, array( 'type' => 'issue', 'projectid' => $r->projectid, 'issueid' => $r->id, 'summary' => $r->summary, 'partial_text' => $text)); + } + } + } + + $this->db->select ('projectid,id,sno,comment'); + $this->db->like ('comment', $needle); + $query = $this->db->get ('issue_change'); + + if ($this->db->trans_status() === FALSE) + { + $this->db->trans_complete (); + return FALSE; + } + + $result = $query->result(); + if (!empty($result)) + { + // TODO: create a link to each chnage log comment in the main issue view. + // Use the link to jump to the comment. + foreach ($result as $r) + { + $posa = false; + if (($posa = stripos($r->comment, $needle)) !== false) + { + $start_pos = $posa - 30; + if ($start_pos < 0) $start_pos = 0; + $text = substr($r->comment, $start_pos, strlen($needle) + 100); + array_push ($items, array( 'type' => 'issue', 'projectid' => $r->projectid, 'issueid' => $r->id, 'summary' => $r->sno, 'partial_text' => $text)); + } + } + } + + $this->db->select ('projectid,issueid,filename,description'); + $this->db->like ('filename', $needle); + $this->db->or_like ('description', $needle); + $query = $this->db->get ('issue_file_list'); + + if ($this->db->trans_status() === FALSE) + { + $this->db->trans_complete (); + return FALSE; + } + + $result = $query->result(); + if (!empty($result)) + { + foreach ($result as $r) + { + $posa = stripos($r->filename, $needle); + $posb = stripos($r->description, $needle); + if ($posa !== false || $posb !== false) + { + $text = ""; + if ($posb !== false) + { + $start_pos = $posb - 30; + if ($start_pos < 0) $start_pos = 0; + $text = substr($r->description, $start_pos, strlen($needle) + 30); + } + array_push ($items, array( 'type' => 'issue_file', 'projectid' => $r->projectid, 'issueid' => $r->issueid, 'filename' => $r->filename, 'partial_text' => $text)); + } + } + } + + $this->db->trans_complete (); + + return $items; + } } ?> diff --git a/codepot/src/codepot/models/wikimodel.php b/codepot/src/codepot/models/wikimodel.php index e2479e35..cf1005ec 100644 --- a/codepot/src/codepot/models/wikimodel.php +++ b/codepot/src/codepot/models/wikimodel.php @@ -518,6 +518,75 @@ class WikiModel extends CI_Model restore_error_handler (); return $x; } + + function search ($needle = '') + { + $items = array(); + if ($needle == '') return $items; + + $this->db->trans_start (); + + $this->db->select ('projectid,name,text,doctype'); + $this->db->like ('name', $needle); + $this->db->or_like ('text', $needle); + $query = $this->db->get('wiki'); + if ($this->db->trans_status() === FALSE) + { + $this->db->trans_complete (); + return FALSE; + } + + $result = $query->result(); + if (!empty($result)) + { + foreach ($result as $r) + { + $posa = stripos($r->name, $needle); + $posb = stripos($r->text, $needle); + /* TODO: consider the wiki type and strip special tags, and let matching happen against the normal text only */ + if ($posa !== false || $posb !== false) + { + $text = ""; + if ($posb !== false) + { + $start_pos = $posb - 30; + if ($start_pos < 0) $start_pos = 0; + $text = substr($r->text, $start_pos, strlen($needle) + 100); + } + array_push ($items, array( 'type' => 'wiki', 'projectid' => $r->projectid, 'name' => $r->name, 'partial_text' => $text)); + } + } + } + + $this->db->select ('projectid,wikiname,name'); + + $this->db->like ('name', $needle); + $query = $this->db->get ('wiki_attachment'); + + if ($this->db->trans_status() === FALSE) + { + $this->db->trans_complete (); + return FALSE; + } + + $result = $query->result(); + if (!empty($result)) + { + foreach ($result as $r) + { + /* TODO: consider the wiki type and strip special tags, and let matching happen against the normal text only */ + if (($posa = stripos($r->name, $needle)) !== false) + { + array_push ($items, array( 'type' => 'wiki_attachment', 'projectid' => $r->projectid, 'name' => $r->name, 'wikiname' => $r->wikiname)); + } + } + } + + $this->db->trans_complete (); + + return $items; + } + } ?> diff --git a/codepot/src/codepot/views/Makefile.am b/codepot/src/codepot/views/Makefile.am index f1af8f21..5f1bb911 100644 --- a/codepot/src/codepot/views/Makefile.am +++ b/codepot/src/codepot/views/Makefile.am @@ -28,6 +28,7 @@ www_DATA = \ site_edit.php \ site_delete.php \ site_home.php \ + site_search.php \ site_show.php \ taskbar.php \ user_home.php \ diff --git a/codepot/src/codepot/views/Makefile.in b/codepot/src/codepot/views/Makefile.in index 884414e3..05903f5d 100644 --- a/codepot/src/codepot/views/Makefile.in +++ b/codepot/src/codepot/views/Makefile.in @@ -280,6 +280,7 @@ www_DATA = \ site_edit.php \ site_delete.php \ site_home.php \ + site_search.php \ site_show.php \ taskbar.php \ user_home.php \