.
* ---------------------------------------------------------------------
*/
namespace Glpi\Dashboard;
use Ramsey\Uuid\Uuid;
use Config;
use CommonGLPI;
use Dropdown;
use DBConnection;
use Entity;
use Group;
use Html;
use Plugin;
use Profile;
use Session;
use Telemetry;
use Toolbox;
use User;
if (!defined('GLPI_ROOT')) {
die("Sorry. You can't access this file directly");
}
class Grid extends CommonGLPI {
protected $cell_margin = 6;
protected $grid_cols = 26;
protected $grid_rows = 24;
protected $current = "";
protected $dashboard = null;
protected $items = [];
static $embed = false;
static $context = '';
static $all_dashboards = [];
public function __construct(
string $dashboard_key = "central",
int $grid_cols = 26,
int $grid_rows = 24,
string $context = "core"
) {
$this->current = $dashboard_key;
$this->grid_cols = $grid_cols;
$this->grid_rows = $grid_rows;
$this->dashboard = new Dashboard($dashboard_key);
self::$context = $context;
}
/**
* Return the instance of current dasbhoard
*
* @return Dashboard
*/
public function getDashboard() {
return $this->dashboard;
}
/**
* load all existing dashboards from DB into a static property for caching data
*
* @param bool $force, if false, don't use cache
*
* @return bool
*/
static function loadAllDashboards(bool $force = true): bool {
if (!is_array(self::$all_dashboards)
|| count(self::$all_dashboards) === 0
|| $force) {
self::$all_dashboards = Dashboard::getAll($force, !self::$embed, self::$context);
}
return is_array(self::$all_dashboards);
}
/**
* Init dashboards cards
* A define.php constant (GLPI_AJAX_DASHBOARD) exists to control how the cards should be loaded
* - if true: only the parent block will be initialized and the content will be load by ajax
* pros: if a widget fails, only this one will crash
* - else: load all html
* pros: better perfs
*
* @return void
*/
public function getCards() {
self::loadAllDashboards();
if (!isset(self::$all_dashboards[$this->current])
|| !isset(self::$all_dashboards[$this->current]['items'])) {
self::$all_dashboards[$this->current] = [
'items' => []
];
}
foreach (self::$all_dashboards[$this->current]['items'] as $specs) {
$card_id = $specs['card_id'] ?? $specs['gridstack_id'] ?? $specs['id'];
$gridstack_id = $specs['gridstack_id'] ?? $specs['id'];
$card_options = ($specs['card_options'] ?? []) + [
'card_id' => $card_id
];
if (GLPI_AJAX_DASHBOARD) {
$card_html = <<
HTML;
} else {
$card_html = $this->getCardHtml($card_id, ['args' => $card_options]);
}
$this->addGridItem(
$card_html,
$gridstack_id,
$specs['x'] ?? -1,
$specs['y'] ?? -1,
$specs['width'] ?? 2,
$specs['height'] ?? 2,
$card_options
);
}
}
/**
* Do we have the right to view at least one dashboard int the current collection
*
* @return bool
*/
public function canViewCurrent(): bool {
// check global (admin) right
if (Dashboard::canView()) {
return true;
}
return $this->dashboard->canViewCurrent();
}
/**
* Do we have the right to view at least one dashboard in the current collection
*
* @return bool
*/
static function canViewOneDashboard(): bool {
// check global (admin) right
if (Dashboard::canView()) {
return true;
}
self::loadAllDashboards();
return (count(self::$all_dashboards) > 0);
}
/**
* Do we have the right to view the specified dashboard int the current collection
*
* @param string $key the dashboard to check
*
* @return bool
*/
static function canViewSpecificicDashboard($key): bool {
// check global (admin) right
if (Dashboard::canView()) {
return true;
}
self::loadAllDashboards();
return isset(self::$all_dashboards[$key]);
}
/**
* Display grid for the current dashboard
*
* @return void display html of the grid
*/
public function show(bool $mini = false) {
$rand = mt_rand();
if (!self::$embed && !$this->dashboard->canViewCurrent()) {
return;
}
self::loadAllDashboards();
$this->restoreLastDashboard();
if ($mini) {
$this->cell_margin = 3;
}
$embed_str = self::$embed ? "true" : "false";
$embed_class = self::$embed ? "embed" : "";
$mini_class = $mini ? "mini" : "";
$nb_dashboards = count(self::$all_dashboards);
$can_view_all = Session::haveRight('dashboard', READ) || self::$embed;
$can_create = Session::haveRight('dashboard', CREATE);
$can_edit = Session::haveRight('dashboard', UPDATE) && $nb_dashboards;
$can_purge = Session::haveRight('dashboard', PURGE) && $nb_dashboards;
$can_clone = $can_create && $nb_dashboards;
// prepare html for add controls
$add_controls = "";
for ($y = 0; $y < $this->grid_rows; $y++) {
for ($x = 0; $x < $this->grid_cols; $x++) {
$add_controls.= "
";
}
}
// prepare all available cards
$cards = $this->getAllDasboardCards();
$cards_json = json_encode($cards);
// prepare all available widgets
$all_widgets = Widget::getAllTypes();
$all_widgets_json = json_encode($all_widgets);
// prepare labels
$embed_label = __("Share or embed this dashboard");
$delete_label = __("Delete this dashboard");
$history_label = __("Toggle auto-refresh");
$night_label = __("Toggle night mode");
$fs_label = __("Toggle fullscreen");
$clone_label = __("Clone this dashboard");
$edit_label = __("Toggle edit mode");
$add_filter_lbl = __("Add filter");
$add_dash_label = __("Add a new dashboard");
$save_label = _x('button', "Save");
$gridstack_items = $this->getGridItemsHtml();
$dropdown_dashboards = "";
if ($nb_dashboards) {
$dropdown_dashboards = self::dropdownDashboard("", [
'value' => $this->current,
'display' => false,
'class' => 'dashboard_select',
'can_view_all' => $can_view_all,
'noselect2' => true,
]);
}
$dashboard_title = $this->dashboard->getTitle();
$l_tb_icons = "";
$r_tb_icons = "";
$rename = "";
$left_toolbar = "";
$grid_guide = "";
if (!self::$embed) {
if (!$mini && $can_create) {
$l_tb_icons.= "";
}
if (!$mini && $can_clone) {
$r_tb_icons.= "";
}
if (!$mini && $can_edit) {
$r_tb_icons.= "";
$rename = "
";
}
if (!$mini && $can_purge) {
$r_tb_icons.= "";
}
if ($can_edit) {
$r_tb_icons.= "";
}
if (!$mini) {
$r_tb_icons.= "";
}
if (!$mini) {
$left_toolbar = <<