grthtrhthjhtyjytjytkergtrhtrjytjerhrfh4:24 29/09/2026.
--------------------------------------------------------------------------
*/
/** @file
* @brief
*/
if (!defined('GLPI_ROOT')) {
die("Sorry. You can't access this file directly");
}
/**
* KnowbaseItem Class
**/
class KnowbaseItem extends CommonDBTM {
// From CommonDBTM
public $dohistory = true;
// For visibility checks
protected $users = array();
protected $groups = array();
protected $profiles = array();
protected $entities = array();
const KNOWBASEADMIN = 1024;
const READFAQ = 2048;
const PUBLISHFAQ = 4096;
static $rightname = 'knowbase';
static function getTypeName($nb=0) {
return __('Knowledge base');
}
/**
* @see CommonGLPI::getMenuShorcut()
*
* @since version 0.85
**/
static function getMenuShorcut() {
return 'b';
}
/**
* @see CommonGLPI::getMenuName()
*
* @since version 0.85
**/
static function getMenuName() {
if (!Session::haveRight('knowbase', READ)) {
return __('FAQ');
} else {
return static::getTypeName(Session::getPluralNumber());
}
}
static function canCreate() {
return Session::haveRightsOr(self::$rightname, array(CREATE, self::PUBLISHFAQ));
}
/**
* @since version 0.85
**/
static function canUpdate() {
return Session::haveRightsOr(self::$rightname, array(UPDATE, self::KNOWBASEADMIN));
}
static function canView() {
global $CFG_GLPI;
return (Session::haveRightsOr(self::$rightname, array(READ, self::READFAQ))
|| ((Session::getLoginUserID() === false) && $CFG_GLPI["use_public_faq"]));
}
function canViewItem() {
global $CFG_GLPI;
if ($this->fields['users_id'] == Session::getLoginUserID()) {
return true;
}
if (Session::haveRight(self::$rightname, self::KNOWBASEADMIN)) {
return true;
}
if ($this->fields["is_faq"]) {
return ((Session::haveRightsOr(self::$rightname, array(READ, self::READFAQ))
&& $this->haveVisibilityAccess())
|| ((Session::getLoginUserID() === false) && $this->isPubliclyVisible()));
}
return (Session::haveRight(self::$rightname, READ) && $this->haveVisibilityAccess());
}
function canUpdateItem() {
// Personal knowbase or visibility and write access
return (Session::haveRight(self::$rightname, self::KNOWBASEADMIN)
|| (($_SESSION["glpiactiveprofile"]["interface"] == "central")
&& ($this->fields['users_id'] == Session::getLoginUserID()))
|| ((($this->fields["is_faq"] && Session::haveRight(self::$rightname, self::PUBLISHFAQ))
|| (!$this->fields["is_faq"]
&& Session::haveRight(self::$rightname, UPDATE)))
&& $this->haveVisibilityAccess()));
}
/**
* Get the search page URL for the current classe
*
* @since version 0.84
*
* @param $full path or relative one (true by default)
**/
static function getSearchURL($full=true) {
global $CFG_GLPI;
$dir = ($full ? $CFG_GLPI['root_doc'] : '');
if (isset($_SESSION['glpiactiveprofile'])
&& ($_SESSION['glpiactiveprofile']['interface'] == "central")) {
return "$dir/front/knowbaseitem.php";
}
return "$dir/front/helpdesk.faq.php";
}
function defineTabs($options=array()) {
$ong = array();
$this->addStandardTab(__CLASS__, $ong, $options);
$this->addStandardTab('Document_Item', $ong, $options);
$this->addStandardTab('KnowbaseItemTranslation',$ong, $options);
$this->addStandardTab('Log',$ong, $options);
return $ong;
}
function getTabNameForItem(CommonGLPI $item, $withtemplate=0) {
if (!$withtemplate) {
$nb = 0;
switch ($item->getType()) {
case __CLASS__ :
$ong[1] = $this->getTypeName(1);
if ($item->canUpdateItem()) {
if ($_SESSION['glpishow_count_on_tabs']) {
$nb = $item->countVisibilities();
}
$ong[2] = self::createTabEntry(_n('Target','Targets', Session::getPluralNumber()),
$nb);
$ong[3] = __('Edit');
}
return $ong;
}
}
return '';
}
static function displayTabContentForItem(CommonGLPI $item, $tabnum=1, $withtemplate=0) {
if ($item->getType() == __CLASS__) {
switch($tabnum) {
case 1 :
$item->showFull();
break;
case 2 :
$item->showVisibility();
break;
case 3 :
$item->showForm($item->getID());
break;
}
}
return true;
}
/**
* Actions done at the end of the getEmpty function
*
*@return nothing
**/
function post_getEmpty() {
if (Session::haveRight(self::$rightname, self::PUBLISHFAQ)
&& !Session::haveRight("knowbase", UPDATE)) {
$this->fields["is_faq"] = 1;
}
}
/**
* @since version 0.85
* @see CommonDBTM::post_addItem()
**/
function post_addItem() {
if (isset($this->input["_visibility"])
&& isset($this->input["_visibility"]['_type'])
&& !empty($this->input["_visibility"]["_type"])) {
$this->input["_visibility"]['knowbaseitems_id'] = $this->getID();
$item = NULL;
switch ($this->input["_visibility"]['_type']) {
case 'User' :
if (isset($this->input["_visibility"]['users_id'])
&& $this->input["_visibility"]['users_id']) {
$item = new KnowbaseItem_User();
}
break;
case 'Group' :
if (isset($this->input["_visibility"]['groups_id'])
&& $this->input["_visibility"]['groups_id']) {
$item = new Group_KnowbaseItem();
}
break;
case 'Profile' :
if (isset($this->input["_visibility"]['profiles_id'])
&& $this->input["_visibility"]['profiles_id']) {
$item = new KnowbaseItem_Profile();
}
break;
case 'Entity' :
$item = new Entity_KnowbaseItem();
break;
}
if (!is_null($item)) {
$item->add($this->input["_visibility"]);
Event::log($this->getID(), "knowbaseitem", 4, "tools",
//TRANS: %s is the user login
sprintf(__('%s adds a target'), $_SESSION["glpiname"]));
}
}
}
/**
* @since version 0.83
**/
function post_getFromDB() {
// Users
$this->users = KnowbaseItem_User::getUsers($this->fields['id']);
// Entities
$this->entities = Entity_KnowbaseItem::getEntities($this->fields['id']);
// Group / entities
$this->groups = Group_KnowbaseItem::getGroups($this->fields['id']);
// Profile / entities
$this->profiles = KnowbaseItem_Profile::getProfiles($this->fields['id']);
}
/**
* @see CommonDBTM::cleanDBonPurge()
*
* @since version 0.83.1
**/
function cleanDBonPurge() {
$class = new KnowbaseItem_User();
$class->cleanDBonItemDelete($this->getType(), $this->fields['id']);
$class = new Entity_KnowbaseItem();
$class->cleanDBonItemDelete($this->getType(), $this->fields['id']);
$class = new Group_KnowbaseItem();
$class->cleanDBonItemDelete($this->getType(), $this->fields['id']);
$class = new KnowbaseItem_Profile();
$class->cleanDBonItemDelete($this->getType(), $this->fields['id']);
}
/**
* @since version 0.83
**/
function countVisibilities() {
return (count($this->entities)
+ count($this->users)
+ count($this->groups)
+ count($this->profiles));
}
/**
* Check is this item if visible to everybody (anonymous users)
*
* @since version 0.83
*
* @return Boolean
**/
function isPubliclyVisible() {
global $CFG_GLPI;
if (!$CFG_GLPI['use_public_faq']) {
return false;
}
if (isset($this->entities[0])) { // Browse root entity rights
foreach ($this->entities[0] as $entity) {
if ($entity['is_recursive']) {
return true;
}
}
}
return false;
}
/**
* Is the login user have access to KnowbaseItem based on visibility configuration
*
* @since version 0.83
*
* @return boolean
**/
function haveVisibilityAccess() {
// No public knowbaseitem right : no visibility check
if (!Session::haveRightsOr(self::$rightname, array(self::READFAQ, READ))) {
return false;
}
// Author
if ($this->fields['users_id'] == Session::getLoginUserID()) {
return true;
}
// Admin
if (Session::haveRight(self::$rightname, self::KNOWBASEADMIN)) {
return true;
}
// Users
if (isset($this->users[Session::getLoginUserID()])) {
return true;
}
// Groups
if (count($this->groups)
&& isset($_SESSION["glpigroups"]) && count($_SESSION["glpigroups"])) {
foreach ($this->groups as $key => $data) {
foreach ($data as $group) {
if (in_array($group['groups_id'], $_SESSION["glpigroups"])) {
// All the group
if ($group['entities_id'] < 0) {
return true;
}
// Restrict to entities
if (Session::haveAccessToEntity($group['entities_id'], $group['is_recursive'])) {
return true;
}
}
}
}
}
// Entities
if (count($this->entities)
&& isset($_SESSION["glpiactiveentities"]) && count($_SESSION["glpiactiveentities"])) {
foreach ($this->entities as $key => $data) {
foreach ($data as $entity) {
if (Session::haveAccessToEntity($entity['entities_id'], $entity['is_recursive'])) {
return true;
}
}
}
}
// Profiles
if (count($this->profiles)
&& isset($_SESSION["glpiactiveprofile"]) && isset($_SESSION["glpiactiveprofile"]['id'])) {
if (isset($this->profiles[$_SESSION["glpiactiveprofile"]['id']])) {
foreach ($this->profiles[$_SESSION["glpiactiveprofile"]['id']] as $profile) {
// All the profile
if ($profile['entities_id'] < 0) {
return true;
}
// Restrict to entities
if (Session::haveAccessToEntity($profile['entities_id'], $profile['is_recursive'])) {
return true;
}
}
}
}
return false;
}
/**
* Return visibility joins to add to SQL
*
* @since version 0.83
*
* @param $forceall force all joins (false by default)
*
* @return string joins to add
**/
static function addVisibilityJoins($forceall=false) {
$join = '';
// Users
$join .= " LEFT JOIN `glpi_knowbaseitems_users`
ON (`glpi_knowbaseitems_users`.`knowbaseitems_id` = `glpi_knowbaseitems`.`id`) ";
// Groups
if ($forceall
|| (isset($_SESSION["glpigroups"]) && count($_SESSION["glpigroups"]))) {
$join .= " LEFT JOIN `glpi_groups_knowbaseitems`
ON (`glpi_groups_knowbaseitems`.`knowbaseitems_id`
= `glpi_knowbaseitems`.`id`) ";
}
// Profiles
if ($forceall
|| (isset($_SESSION["glpiactiveprofile"])
&& isset($_SESSION["glpiactiveprofile"]['id']))) {
$join .= " LEFT JOIN `glpi_knowbaseitems_profiles`
ON (`glpi_knowbaseitems_profiles`.`knowbaseitems_id`
= `glpi_knowbaseitems`.`id`) ";
}
// Entities
if ($forceall
|| !Session::getLoginUserID()
|| (isset($_SESSION["glpiactiveentities"]) && count($_SESSION["glpiactiveentities"]))) {
$join .= " LEFT JOIN `glpi_entities_knowbaseitems`
ON (`glpi_entities_knowbaseitems`.`knowbaseitems_id`
= `glpi_knowbaseitems`.`id`) ";
}
return $join;
}
/**
* Return visibility SQL restriction to add
*
* @since version 0.83
*
* @return string restrict to add
**/
static function addVisibilityRestrict() {
$restrict = '';
if (Session::getLoginUserID()) {
$restrict = "(`glpi_knowbaseitems_users`.`users_id` = '".Session::getLoginUserID()."' ";
// Users
$restrict .= " OR `glpi_knowbaseitems_users`.`users_id` = '".Session::getLoginUserID()."' ";
// Groups
if (isset($_SESSION["glpigroups"]) && count($_SESSION["glpigroups"])) {
$restrict .= " OR (`glpi_groups_knowbaseitems`.`groups_id`
IN ('".implode("','",$_SESSION["glpigroups"])."')
AND (`glpi_groups_knowbaseitems`.`entities_id` < 0
".getEntitiesRestrictRequest("OR", "glpi_groups_knowbaseitems",
'', '', true).")) ";
}
// Profiles
if (isset($_SESSION["glpiactiveprofile"])
&& isset($_SESSION["glpiactiveprofile"]['id'])) {
$restrict .= " OR (`glpi_knowbaseitems_profiles`.`profiles_id`
= '".$_SESSION["glpiactiveprofile"]['id']."'
AND (`glpi_knowbaseitems_profiles`.`entities_id` < 0
".getEntitiesRestrictRequest("OR", "glpi_knowbaseitems_profiles",
'', '', true).")) ";
}
// Entities
if (isset($_SESSION["glpiactiveentities"]) && count($_SESSION["glpiactiveentities"])) {
// Force complete SQL not summary when access to all entities
$restrict .= getEntitiesRestrictRequest("OR", "glpi_entities_knowbaseitems", '', '',
true, true);
}
$restrict .= ") ";
} else {
$restrict = '1';
}
return $restrict;
}
/**
* @see CommonDBTM::prepareInputForAdd()
**/
function prepareInputForAdd($input) {
// set new date if not exists
if (!isset($input["date"]) || empty($input["date"])) {
$input["date"] = $_SESSION["glpi_currenttime"];
}
// set users_id
// set title for question if empty
if (isset($input["name"]) && empty($input["name"])) {
$input["name"] = __('New item');
}
if (Session::haveRight(self::$rightname, self::PUBLISHFAQ)
&& !Session::haveRight(self::$rightname, UPDATE)) {
$input["is_faq"] = 1;
}
if (!Session::haveRight(self::$rightname, self::PUBLISHFAQ)
&& Session::haveRight(self::$rightname, UPDATE)) {
$input["is_faq"] = 0;
}
return $input;
}
/**
* @see CommonDBTM::prepareInputForUpdate()
**/
function prepareInputForUpdate($input) {
// set title for question if empty
if (isset($input["name"]) && empty($input["name"])) {
$input["name"] = __('New item');
}
return $input;
}
/**
* Print out an HTML "
" for Search knowbase item
*
* @since version 0.84
*
* @param $options $_GET
*
* @return nothing (display the form)
**/
function showBrowseForm($options) {
global $CFG_GLPI;
if (!$CFG_GLPI["use_public_faq"]
&& !Session::haveRightsOr(self::$rightname, array(READ, self::READFAQ))) {
return false;
}
// Default values of parameters
$params["knowbaseitemcategories_id"] = "";
if (is_array($options) && count($options)) {
foreach ($options as $key => $val) {
$params[$key] = $val;
}
}
$faq = !Session::haveRight(self::$rightname, READ);
// Category select not for anonymous FAQ
if (Session::getLoginUserID()
&& !$faq) {
echo "";
echo "
";
echo "";
if (isset($options['item_itemtype'])
&& isset($options['item_items_id'])) {
echo " ";
echo " ";
}
Html::closeForm();
echo " ";
}
}
/**
* Print out an HTML form for Search knowbase item
*
* @since version 0.84
*
* @param $options $_GET
*
* @return nothing (display the form)
**/
function showManageForm($options) {
global $CFG_GLPI;
if (!Session::haveRightsOr(self::$rightname,
array(UPDATE, self::PUBLISHFAQ, self::KNOWBASEADMIN))) {
return false;
}
$params['unpublished'] = 'my';
if (is_array($options) && count($options)) {
foreach ($options as $key => $val) {
$params[$key] = $val;
}
}
$faq = !Session::haveRight(self::$rightname, UPDATE);
echo "";
echo "
";
echo "";
Html::closeForm();
echo " ";
}
/**
* Build request for showList
*
* @since version 0.83
*
* @param $params array (contains, knowbaseitemcategories_id, faq)
* @param $type string search type : browse / search (default search)
*
* @return String : SQL request
**/
static function getListRequest(array $params, $type='search') {
global $DB;
// Lists kb Items
$where = "";
$order = "";
$score = "";
$addselect = "";
$join = self::addVisibilityJoins(true);
switch ($type) {
case 'myunpublished' :
break;
case 'allmy' :
break;
case 'allunpublished' :
break;
default :
// Build query
if (Session::getLoginUserID() && $type != 'myunpublished') {
$where = self::addVisibilityRestrict();
} else {
// Anonymous access
if (Session::isMultiEntitiesMode()) {
$where = " (`glpi_entities_knowbaseitems`.`entities_id` = '0'
AND `glpi_entities_knowbaseitems`.`is_recursive` = '1')";
}
}
break;
}
if (empty($where)) {
$where = '1 = 1';
}
if ($params['faq']) { // helpdesk
$where .= " AND (`glpi_knowbaseitems`.`is_faq` = '1')";
}
if (KnowbaseItemTranslation::isKbTranslationActive()
&& (countElementsInTable('glpi_knowbaseitemtranslations') > 0)) {
$join .= "LEFT JOIN `glpi_knowbaseitemtranslations`
ON (`glpi_knowbaseitems`.`id` = `glpi_knowbaseitemtranslations`.`knowbaseitems_id`
AND `glpi_knowbaseitemtranslations`.`language` = '".$_SESSION['glpilanguage']."')";
$addselect .= ", `glpi_knowbaseitemtranslations`.`name` AS transname,
`glpi_knowbaseitemtranslations`.`answer` AS transanswer ";
}
// a search with $contains
switch ($type) {
case 'allmy' :
$where .= " AND `glpi_knowbaseitems`.`users_id` = '".Session::getLoginUserID()."'";
break;
case 'myunpublished' :
$where .= " AND `glpi_knowbaseitems`.`users_id` = '".Session::getLoginUserID()."'
AND (`glpi_entities_knowbaseitems`.`entities_id` IS NULL
AND `glpi_knowbaseitems_profiles`.`profiles_id` IS NULL
AND `glpi_groups_knowbaseitems`.`groups_id` IS NULL
AND `glpi_knowbaseitems_users`.`users_id` IS NULL)";
break;
case 'allunpublished' :
// Only published
$where .= " AND (`glpi_entities_knowbaseitems`.`entities_id` IS NULL
AND `glpi_knowbaseitems_profiles`.`profiles_id` IS NULL
AND `glpi_groups_knowbaseitems`.`groups_id` IS NULL
AND `glpi_knowbaseitems_users`.`users_id` IS NULL)";
break;
case 'search' :
if (strlen($params["contains"]) > 0) {
$search = Toolbox::unclean_cross_side_scripting_deep($params["contains"]);
$search_wilcard = explode(' ', $search);
$search_wilcard = implode('* ', $search_wilcard).'*';
$addscore = array();
if (KnowbaseItemTranslation::isKbTranslationActive()
&& (countElementsInTable('glpi_knowbaseitemtranslations') > 0)) {
$addscore = array('`glpi_knowbaseitemtranslations`.`name`',
'`glpi_knowbaseitemtranslations`.`answer`');
}
$score = " ,(MATCH(`glpi_knowbaseitems`.`name`, `glpi_knowbaseitems`.`answer`)
AGAINST('$search_wilcard' IN BOOLEAN MODE)";
if (!empty($addscore)) {
foreach($addscore as $addscore_field) {
$score.= " + MATCH($addscore_field)
AGAINST('$search_wilcard' IN BOOLEAN MODE)";
}
}
$score .=" ) AS SCORE ";
$where_1 = $where." AND (MATCH(`glpi_knowbaseitems`.`name`,
`glpi_knowbaseitems`.`answer`)
AGAINST('$search_wilcard' IN BOOLEAN MODE) ";
if (!empty($addscore)) {
foreach($addscore as $addscore_field) {
$where_1.= "OR $addscore_field IS NOT NULL
AND MATCH($addscore_field)
AGAINST('$search_wilcard' IN BOOLEAN MODE)";
}
}
$where_1.= ")";
// Add visibility date
$where_1 .= " AND (`glpi_knowbaseitems`.`begin_date` IS NULL
OR `glpi_knowbaseitems`.`begin_date` < NOW())
AND (`glpi_knowbaseitems`.`end_date` IS NULL
OR `glpi_knowbaseitems`.`end_date` > NOW()) ";
$order = "ORDER BY `SCORE` DESC";
// preliminar query to allow alternate search if no result with fulltext
$query_1 = "SELECT COUNT(`glpi_knowbaseitems`.`id`)
FROM `glpi_knowbaseitems`
$join
WHERE $where_1";
$result_1 = $DB->query($query_1);
$numrows_1 = $DB->result($result_1,0,0);
if ($numrows_1 <= 0) {// not result this fulltext try with alternate search
$search1 = array(/* 1 */ '/\\\"/',
/* 2 */ "/\+/",
/* 3 */ "/\*/",
/* 4 */ "/~/",
/* 5 */ "/",
/* 6 */ "/>/",
/* 7 */ "/\(/",
/* 8 */ "/\)/",
/* 9 */ "/\-/");
$contains = preg_replace($search1,"", $params["contains"]);
$addwhere = '';
if (KnowbaseItemTranslation::isKbTranslationActive()
&& (countElementsInTable('glpi_knowbaseitemtranslations') > 0)) {
$addwhere = " OR `glpi_knowbaseitemtranslations`.`name` ".Search::makeTextSearch($contains)."
OR `glpi_knowbaseitemtranslations`.`answer` ".Search::makeTextSearch($contains);
}
$where .= " AND (`glpi_knowbaseitems`.`name` ".Search::makeTextSearch($contains)."
OR `glpi_knowbaseitems`.`answer` ".Search::makeTextSearch($contains)."
$addwhere)";
} else {
$where = $where_1;
}
}
break;
case 'browse' :
$where .= " AND (`glpi_knowbaseitems`.`knowbaseitemcategories_id`
= '".$params["knowbaseitemcategories_id"]."')";
// Add visibility date
$where .= " AND (`glpi_knowbaseitems`.`begin_date` IS NULL
OR `glpi_knowbaseitems`.`begin_date` < NOW())
AND (`glpi_knowbaseitems`.`end_date` IS NULL
OR `glpi_knowbaseitems`.`end_date` > NOW()) ";
$order = " ORDER BY `glpi_knowbaseitems`.`name` ASC";
break;
}
$query = "SELECT DISTINCT `glpi_knowbaseitems`.*,
`glpi_knowbaseitemcategories`.`completename` AS category
$addselect
$score
FROM `glpi_knowbaseitems`
$join
LEFT JOIN `glpi_knowbaseitemcategories`
ON (`glpi_knowbaseitemcategories`.`id`
= `glpi_knowbaseitems`.`knowbaseitemcategories_id`)
WHERE $where
$order";
return $query;
}
/**
* Print out list kb item
*
* @param $options $_GET
* @param $type string search type : browse / search (default search)
**/
static function showList($options, $type='search') {
global $DB, $CFG_GLPI;
// Default values of parameters
$params['faq'] = !Session::haveRight(self::$rightname, READ);
$params["start"] = "0";
$params["knowbaseitemcategories_id"] = "0";
$params["contains"] = "";
$params["target"] = $_SERVER['PHP_SELF'];
if (is_array($options) && count($options)) {
foreach ($options as $key => $val) {
$params[$key] = $val;
}
}
$ki = new self();
switch ($type) {
case 'myunpublished' :
if (!Session::haveRightsOr(self::$rightname, array(UPDATE, self::PUBLISHFAQ))) {
return false;
}
break;
case 'allunpublished' :
if (!Session::haveRight(self::$rightname, self::KNOWBASEADMIN)) {
return false;
}
break;
default :
break;
}
if (!$params["start"]) {
$params["start"] = 0;
}
$query = self::getListRequest($params, $type);
// Get it from database
if ($result = $DB->query($query)) {
$KbCategory = new KnowbaseItemCategory();
$title = "";
if ($KbCategory->getFromDB($params["knowbaseitemcategories_id"])) {
$title = (empty($KbCategory->fields['name']) ?"(".$params['knowbaseitemcategories_id'].")"
: $KbCategory->fields['name']);
$title = sprintf(__('%1$s: %2$s'), __('Category'), $title);
}
Session::initNavigateListItems('KnowbaseItem', $title);
$numrows = $DB->numrows($result);
$list_limit = $_SESSION['glpilist_limit'];
$showwriter = in_array($type, array('myunpublished', 'allunpublished', 'allmy'));
// Limit the result, if no limit applies, use prior result
if (($numrows > $list_limit)
&& !isset($_GET['export_all'])) {
$query_limit = $query ." LIMIT ".intval($params["start"]).", ".intval($list_limit)." ";
$result_limit = $DB->query($query_limit);
$numrows_limit = $DB->numrows($result_limit);
} else {
$numrows_limit = $numrows;
$result_limit = $result;
}
if ($numrows_limit > 0) {
// Set display type for export if define
$output_type = Search::HTML_OUTPUT;
if (isset($_GET["display_type"])) {
$output_type = $_GET["display_type"];
}
// Pager
$parameters = "start=".$params["start"]."&knowbaseitemcategories_id=".
$params['knowbaseitemcategories_id']."&contains=".
$params["contains"]."&is_faq=".$params['faq'];
if (isset($options['item_itemtype'])
&& isset($options['item_items_id'])) {
$parameters .= "&item_items_id=".$options['item_items_id']."&item_itemtype=".
$options['item_itemtype'];
}
if ($output_type == Search::HTML_OUTPUT) {
Html::printPager($params['start'], $numrows,
Toolbox::getItemTypeSearchURL('KnowbaseItem'), $parameters,
'KnowbaseItem');
}
$nbcols = 1;
// Display List Header
echo Search::showHeader($output_type, $numrows_limit+1, $nbcols);
echo Search::showNewLine($output_type);
$header_num = 1;
echo Search::showHeaderItem($output_type, __('Subject'), $header_num);
if ($output_type != Search::HTML_OUTPUT) {
echo Search::showHeaderItem($output_type, __('Content'), $header_num);
}
if ($showwriter) {
echo Search::showHeaderItem($output_type, __('Writer'), $header_num);
}
echo Search::showHeaderItem($output_type, __('Category'), $header_num);
if (isset($options['item_itemtype'])
&& isset($options['item_items_id'])
&& ($output_type == Search::HTML_OUTPUT)) {
echo Search::showHeaderItem($output_type, ' ', $header_num);
}
// Num of the row (1=header_line)
$row_num = 1;
for ($i=0 ; $i<$numrows_limit ; $i++) {
$data = $DB->fetch_assoc($result_limit);
Session::addToNavigateListItems('KnowbaseItem', $data["id"]);
// Column num
$item_num = 1;
$row_num++;
echo Search::showNewLine($output_type, $i%2);
$item = new self;
$item->getFromDB($data["id"]);
$name = $data["name"];
$answer = $data["answer"];
// Manage translations
if (isset($data['transname']) && !empty($data['transname'])) {
$name = $data["transname"];
}
if (isset($data['transanswer']) && !empty($data['transanswer'])) {
$answer = $data["transanswer"];
}
if ($output_type == Search::HTML_OUTPUT) {
$toadd = '';
if (isset($options['item_itemtype'])
&& isset($options['item_items_id'])) {
$href = " href='#' onClick=\"".Html::jsGetElementbyID('kbshow'.$data["id"]).".dialog('open');\"" ;
$toadd = Ajax::createIframeModalWindow('kbshow'.$data["id"],
$CFG_GLPI["root_doc"].
"/front/knowbaseitem.form.php?id=".$data["id"],
array('display' => false));
} else {
$href = " href=\"".$CFG_GLPI['root_doc']."/front/knowbaseitem.form.php?id=".
$data["id"]."\" ";
}
echo Search::showItem($output_type,
"
".
Html::resume_text(Html::clean(Toolbox::unclean_cross_side_scripting_deep($answer)),
600)."
",
$item_num, $row_num);
} else {
echo Search::showItem($output_type, $name, $item_num, $row_num);
echo Search::showItem($output_type,
Html::clean(Toolbox::unclean_cross_side_scripting_deep(html_entity_decode($answer,
ENT_QUOTES,
"UTF-8"))),
$item_num, $row_num);
}
$showuserlink = 0;
if (Session::haveRight('user', READ)) {
$showuserlink = 1;
}
if ($showwriter) {
echo Search::showItem($output_type, getUserName($data["users_id"], $showuserlink),
$item_num, $row_num);
}
$categ = $data["category"];
if ($output_type == Search::HTML_OUTPUT) {
$cathref = $ki->getSearchURL()."?knowbaseitemcategories_id=".
$data["knowbaseitemcategories_id"].'&forcetab=Knowbase$2';
$categ = "".$categ.' ';
}
echo Search::showItem($output_type, $categ, $item_num, $row_num);
if (isset($options['item_itemtype'])
&& isset($options['item_items_id'])
&& ($output_type == Search::HTML_OUTPUT)) {
$forcetab = $options['item_itemtype'];
if (!$_SESSION['glpiticket_timeline'] || $_SESSION['glpiticket_timeline_keep_replaced_tabs']) {
$forcetab .= '$2'; //Solution tab
} else {
$forcetab .= '$1'; //Timeline tab
}
$content = "".
__('Use as a solution')." ";
echo Search::showItem($output_type, $content, $item_num, $row_num);
}
// End Line
echo Search::showEndLine($output_type);
}
// Display footer
if (($output_type == Search::PDF_OUTPUT_LANDSCAPE)
|| ($output_type == Search::PDF_OUTPUT_PORTRAIT)) {
echo Search::showFooter($output_type,
Dropdown::getDropdownName("glpi_knowbaseitemcategories",
$params['knowbaseitemcategories_id']),
$numrows_limit);
} else {
echo Search::showFooter($output_type, '', $numrows_limit);
}
echo " ";
if ($output_type == Search::HTML_OUTPUT) {
Html::printPager($params['start'], $numrows,
Toolbox::getItemTypeSearchURL('KnowbaseItem'), $parameters,
'KnowbaseItem');
}
} else {
echo "".__('No item found')."
";
}
}
}
/**
* Print out list recent or popular kb/faq
*
* @param $type type : recent / popular / not published
*
* @return nothing (display table)
**/
static function showRecentPopular($type) {
global $DB, $CFG_GLPI;
$faq = !Session::haveRight(self::$rightname, READ);
if ($type == "recent") {
$orderby = "ORDER BY `date` DESC";
$title = __('Recent entries');
} else if ($type == 'lastupdate') {
$orderby = "ORDER BY `date_mod` DESC";
$title = __('Last updated entries');
} else {
$orderby = "ORDER BY `view` DESC";
$title = __('Most popular questions');
}
$faq_limit = "";
$addselect = "";
// Force all joins for not published to verify no visibility set
$join = self::addVisibilityJoins(true);
if (Session::getLoginUserID()) {
$faq_limit .= "WHERE ".self::addVisibilityRestrict();
} else {
// Anonymous access
if (Session::isMultiEntitiesMode()) {
$faq_limit .= " WHERE (`glpi_entities_knowbaseitems`.`entities_id` = '0'
AND `glpi_entities_knowbaseitems`.`is_recursive` = '1')";
} else {
$faq_limit .= " WHERE 1";
}
}
// Only published
$faq_limit .= " AND (`glpi_entities_knowbaseitems`.`entities_id` IS NOT NULL
OR `glpi_knowbaseitems_profiles`.`profiles_id` IS NOT NULL
OR `glpi_groups_knowbaseitems`.`groups_id` IS NOT NULL
OR `glpi_knowbaseitems_users`.`users_id` IS NOT NULL)";
// Add visibility date
$faq_limit .= " AND (`glpi_knowbaseitems`.`begin_date` IS NULL
OR `glpi_knowbaseitems`.`begin_date` < NOW())
AND (`glpi_knowbaseitems`.`end_date` IS NULL
OR `glpi_knowbaseitems`.`end_date` > NOW()) ";
if ($faq) { // FAQ
$faq_limit .= " AND (`glpi_knowbaseitems`.`is_faq` = '1')";
}
if (KnowbaseItemTranslation::isKbTranslationActive()
&& (countElementsInTable('glpi_knowbaseitemtranslations') > 0)) {
$join .= "LEFT JOIN `glpi_knowbaseitemtranslations`
ON (`glpi_knowbaseitems`.`id` = `glpi_knowbaseitemtranslations`.`knowbaseitems_id`
AND `glpi_knowbaseitemtranslations`.`language` = '".$_SESSION['glpilanguage']."')";
$addselect .= ", `glpi_knowbaseitemtranslations`.`name` AS transname,
`glpi_knowbaseitemtranslations`.`answer` AS transanswer ";
}
$query = "SELECT DISTINCT `glpi_knowbaseitems`.* $addselect
FROM `glpi_knowbaseitems`
$join
$faq_limit
$orderby
LIMIT 10";
$result = $DB->query($query);
$number = $DB->numrows($result);
if ($number > 0) {
echo "";
echo "".$title." ";
while ($data = $DB->fetch_assoc($result)) {
$name = $data['name'];
if (isset($data['transname']) && !empty($data['transname'])) {
$name = $data['transname'];
}
echo "";
echo "".
Html::resume_text($name,80)." ";
}
echo "
";
}
}
function getSearchOptions() {
$tab = array();
$tab['common'] = __('Characteristics');
$tab[2]['table'] = $this->getTable();
$tab[2]['field'] = 'id';
$tab[2]['name'] = __('ID');
$tab[2]['massiveaction'] = false;
$tab[2]['datatype'] = 'number';
$tab[4]['table'] = 'glpi_knowbaseitemcategories';
$tab[4]['field'] = 'name';
$tab[4]['name'] = __('Category');
$tab[4]['datatype'] = 'dropdown';
$tab[5]['table'] = $this->getTable();
$tab[5]['field'] = 'date';
$tab[5]['name'] = __('Date');
$tab[5]['datatype'] = 'datetime';
$tab[5]['massiveaction'] = false;
$tab[6]['table'] = $this->getTable();
$tab[6]['field'] = 'name';
$tab[6]['name'] = __('Subject');
$tab[6]['datatype'] = 'text';
$tab[7]['table'] = $this->getTable();
$tab[7]['field'] = 'answer';
$tab[7]['name'] = __('Content');
$tab[7]['datatype'] = 'text';
$tab[7]['htmltext'] = true;
$tab[8]['table'] = $this->getTable();
$tab[8]['field'] = 'is_faq';
$tab[8]['name'] = __('FAQ item');
$tab[8]['datatype'] = 'bool';
$tab[9]['table'] = $this->getTable();
$tab[9]['field'] = 'view';
$tab[9]['name'] = _n('View', 'Views', Session::getPluralNumber());
$tab[9]['datatype'] = 'integer';
$tab[9]['massiveaction'] = false;
$tab[10]['table'] = $this->getTable();
$tab[10]['field'] = 'begin_date';
$tab[10]['name'] = __('Visibility start date');
$tab[10]['datatype'] = 'datetime';
$tab[11]['table'] = $this->getTable();
$tab[11]['field'] = 'end_date';
$tab[11]['name'] = __('Visibility end date');
$tab[11]['datatype'] = 'datetime';
$tab[19]['table'] = $this->getTable();
$tab[19]['field'] = 'date_mod';
$tab[19]['name'] = __('Last update');
$tab[19]['datatype'] = 'datetime';
$tab[19]['massiveaction'] = false;
$tab[70]['table'] = 'glpi_users';
$tab[70]['field'] = 'name';
$tab[70]['name'] = __('User');
$tab[70]['massiveaction'] = false;
$tab[70]['datatype'] = 'dropdown';
$tab[70]['right'] = 'all';
$tab[80]['table'] = 'glpi_entities';
$tab[80]['field'] = 'completename';
$tab[80]['name'] = __('Entity');
$tab[80]['massiveaction'] = false;
$tab[80]['datatype'] = 'dropdown';
$tab[86]['table'] = $this->getTable();
$tab[86]['field'] = 'is_recursive';
$tab[86]['name'] = __('Child entities');
$tab[86]['datatype'] = 'bool';
// add objectlock search options
$tab += ObjectLock::getSearchOptionsToAdd( get_class($this) ) ;
return $tab;
}
/**
* Show visibility config for a knowbaseitem
*
* @since version 0.83
**/
function showVisibility() {
global $DB, $CFG_GLPI;
$ID = $this->fields['id'];
$canedit = $this->can($ID, UPDATE);
echo "";
$rand = mt_rand();
$nb = count($this->users) + count($this->groups) + count($this->profiles)
+ count($this->entities);
if ($canedit) {
echo "
";
echo "
";
echo " ";
echo "";
echo "".__('Add a target')." ";
echo "";
$types = array('Entity', 'Group', 'Profile', 'User');
$addrand = Dropdown::showItemTypes('_type', $types);
$params = array('type' => '__VALUE__',
'right' => ($this->getField('is_faq') ? 'faq' : 'knowbase'));
Ajax::updateItemOnSelectEvent("dropdown__type".$addrand,"visibility$rand",
$CFG_GLPI["root_doc"]."/ajax/visibility.php",
$params);
echo " ";
echo " ";
echo " ";
echo "
";
Html::closeForm();
echo " ";
}
echo "
";
if ($canedit && $nb) {
Html::openMassiveActionsForm('mass'.__CLASS__.$rand);
$massiveactionparams
= array('num_displayed'
=> min($_SESSION['glpilist_limit'], $nb),
'container'
=> 'mass'.__CLASS__.$rand,
'specific_actions'
=> array('delete' => _x('button', 'Delete permanently')) );
if ($this->fields['users_id'] != Session::getLoginUserID()) {
$massiveactionparams['confirm']
= __('Caution! You are not the author of this element. Delete targets can result in loss of access to that element.');
}
Html::showMassiveActions($massiveactionparams);
}
echo "
";
$header_begin = "";
$header_top = '';
$header_bottom = '';
$header_end = '';
if ($canedit && $nb) {
$header_begin .= "";
$header_top .= Html::getCheckAllAsCheckbox('mass'.__CLASS__.$rand);
$header_bottom .= Html::getCheckAllAsCheckbox('mass'.__CLASS__.$rand);
$header_end .= " ";
}
$header_end .= "".__('Type')." ";
$header_end .= ""._n('Recipient', 'Recipients', Session::getPluralNumber())." ";
$header_end .= " ";
echo $header_begin.$header_top.$header_end;
// Users
if (count($this->users)) {
foreach ($this->users as $key => $val) {
foreach ($val as $data) {
echo "";
if ($canedit) {
echo "";
Html::showMassiveActionCheckBox('KnowbaseItem_User',$data["id"]);
echo " ";
}
echo "".__('User')." ";
echo "".getUserName($data['users_id'])." ";
echo " ";
}
}
}
// Groups
if (count($this->groups)) {
foreach ($this->groups as $key => $val) {
foreach ($val as $data) {
echo "";
if ($canedit) {
echo "";
Html::showMassiveActionCheckBox('Group_KnowbaseItem',$data["id"]);
echo " ";
}
echo "".__('Group')." ";
echo "";
$names = Dropdown::getDropdownName('glpi_groups', $data['groups_id'],1);
$groupname = sprintf(__('%1$s %2$s'), $names["name"],
Html::showToolTip($names["comment"], array('display' => false)));
if ($data['entities_id'] >= 0) {
$groupname = sprintf(__('%1$s / %2$s'), $groupname,
Dropdown::getDropdownName('glpi_entities',
$data['entities_id']));
if ($data['is_recursive']) {
$groupname = sprintf(__('%1$s %2$s'), $groupname,
"(".__('R').") ");
}
}
echo $groupname;
echo " ";
echo " ";
}
}
}
// Entity
if (count($this->entities)) {
foreach ($this->entities as $key => $val) {
foreach ($val as $data) {
echo "";
if ($canedit) {
echo "";
Html::showMassiveActionCheckBox('Entity_KnowbaseItem',$data["id"]);
echo " ";
}
echo "".__('Entity')." ";
echo "";
$names = Dropdown::getDropdownName('glpi_entities', $data['entities_id'],1);
$entityname = sprintf(__('%1$s %2$s'), $names["name"],
Html::showToolTip($names["comment"], array('display' => false)));
if ($data['is_recursive']) {
$entityname = sprintf(__('%1$s %2$s'), $entityname,
"(".__('R').") ");
}
echo $entityname;
echo " ";
echo " ";
}
}
}
// Profiles
if (count($this->profiles)) {
foreach ($this->profiles as $key => $val) {
foreach ($val as $data) {
echo "";
if ($canedit) {
echo "";
Html::showMassiveActionCheckBox('KnowbaseItem_Profile',$data["id"]);
echo " ";
}
echo ""._n('Profile', 'Profiles', 1)." ";
echo "";
$names = Dropdown::getDropdownName('glpi_profiles', $data['profiles_id'], 1);
$profilename = sprintf(__('%1$s %2$s'), $names["name"],
Html::showToolTip($names["comment"], array('display' => false)));
if ($data['entities_id'] >= 0) {
$profilename = sprintf(__('%1$s / %2$s'), $profilename,
Dropdown::getDropdownName('glpi_entities',
$data['entities_id']));
if ($data['is_recursive']) {
$profilename = sprintf(__('%1$s %2$s'), $profilename,
"(".__('R').") ");
}
}
echo $profilename;
echo " ";
echo " ";
}
}
}
if ($nb) {
echo $header_begin.$header_bottom.$header_end;
}
echo "
";
if ($canedit && $nb) {
$massiveactionparams['ontop'] =false;
Html::showMassiveActions($massiveactionparams);
Html::closeForm();
}
echo "
";
// Add items
return true;
}
/**
* @since version 0.85
*
* @see commonDBTM::getRights()
**/
function getRights($interface='central') {
if ($interface == 'central') {
$values = parent::getRights();
$values[self::KNOWBASEADMIN] = __('Knowledge base administration');
$values[self::PUBLISHFAQ] = __('Publish in the FAQ');
}
$values[self::READFAQ] = __('Read the FAQ');
return $values;
}
}
?>