diff --git a/CHANGELOG.md b/CHANGELOG.md index a1533eae9ef..d0424733670 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -221,6 +221,7 @@ The present file will list all changes made to the project; according to the - `X-GLPI-Sanitized-Content` REST API header support. - Handling of encoded/escaped value in `autoName()`. - `regenerateTreeCompleteName()` +- `Cartridge::getNotificationParameters()` - `Change_Item::showForChange()` - `CommonDBTM::$deduplicate_queued_notifications` property. - `CommonDropdown::displayHeader()` @@ -234,6 +235,8 @@ The present file will list all changes made to the project; according to the - `ComputerAntivirus::showForComputer()` - `ComputerVirtualMachine::showForComputer()` - `Config::getCurrentDBVersion()` +- `Consumable::showAddForm()` +- `Consumable::showForConsumableItem()` - `DbUtils::regenerateTreeCompleteName()` - `Document::uploadDocument()` - `Document::showUploadedFilesDropdown()` diff --git a/src/Cartridge.php b/src/Cartridge.php index 69bd7594658..686f5ec53f0 100644 --- a/src/Cartridge.php +++ b/src/Cartridge.php @@ -33,6 +33,8 @@ * --------------------------------------------------------------------- */ +use Glpi\Application\View\TemplateRenderer; + /** * Cartridge class. * This class is used to manage printer cartridges. @@ -66,22 +68,18 @@ public function getCloneRelations(): array public function getForbiddenStandardMassiveAction() { - $forbidden = parent::getForbiddenStandardMassiveAction(); $forbidden[] = 'update'; return $forbidden; } - public static function showMassiveActionsSubForm(MassiveAction $ma) { - switch ($ma->getAction()) { case 'updatepages': $input = $ma->getInput(); - if (!isset($input['maxpages'])) { - $input['maxpages'] = ''; - } + $input['maxpages'] = isset($input['maxpages']) ? (int) $input['maxpages'] : ''; + echo ""; echo "

" . Html::submit(_x('button', 'Update'), ['name' => 'massiveaction']); return true; @@ -89,28 +87,25 @@ public static function showMassiveActionsSubForm(MassiveAction $ma) return parent::showMassiveActionsSubForm($ma); } - public static function getNameField() { return 'id'; } - public static function getTypeName($nb = 0) { return _n('Cartridge', 'Cartridges', $nb); } - public function prepareInputForAdd($input) { - $item = static::getItemFromArray(CartridgeItem::class, CartridgeItem::getForeignKeyField(), $input); if ($item === false) { return false; } - return ["cartridgeitems_id" => $item->fields["id"], + return [ + "cartridgeitems_id" => $item->fields["id"], "entities_id" => $item->getEntityID(), "date_in" => date("Y-m-d") ]; @@ -118,13 +113,12 @@ public function prepareInputForAdd($input) public function post_addItem() { - - // inherit infocom - $infocoms = Infocom::getItemsAssociatedTo(CartridgeItem::getType(), $this->fields[CartridgeItem::getForeignKeyField()]); + // inherit infocom + $infocoms = Infocom::getItemsAssociatedTo(CartridgeItem::class, $this->fields[CartridgeItem::getForeignKeyField()]); if (count($infocoms)) { $infocom = reset($infocoms); $infocom->clone([ - 'itemtype' => self::getType(), + 'itemtype' => self::class, 'items_id' => $this->getID() ]); } @@ -132,18 +126,17 @@ public function post_addItem() parent::post_addItem(); } - public function post_updateItem($history = true) { - - if (in_array('pages', $this->updates)) { + if (in_array('pages', $this->updates, true)) { $printer = new Printer(); if ( $printer->getFromDB($this->fields['printers_id']) && (($this->fields['pages'] > $printer->getField('last_pages_counter')) - || ($this->oldvalues['pages'] == $printer->getField('last_pages_counter'))) + || ($this->oldvalues['pages'] == $printer->getField('last_pages_counter'))) ) { - $printer->update(['id' => $printer->getID(), + $printer->update([ + 'id' => $printer->getID(), 'last_pages_counter' => $this->fields['pages'] ]); } @@ -151,10 +144,8 @@ public function post_updateItem($history = true) parent::post_updateItem($history); } - public function getPreAdditionalInfosForName() { - $ci = new CartridgeItem(); if ($ci->getFromDB($this->fields['cartridgeitems_id'])) { return $ci->getName(); @@ -162,7 +153,6 @@ public function getPreAdditionalInfosForName() return ''; } - public static function processMassiveActionsForOneItemtype( MassiveAction $ma, CommonDBTM $item, @@ -174,13 +164,13 @@ public static function processMassiveActionsForOneItemtype( foreach ($ids as $key) { if ($item->can($key, UPDATE)) { if ($item->uninstall($key)) { - $ma->itemDone($item->getType(), $key, MassiveAction::ACTION_OK); + $ma->itemDone($item::class, $key, MassiveAction::ACTION_OK); } else { - $ma->itemDone($item->getType(), $key, MassiveAction::ACTION_KO); + $ma->itemDone($item::class, $key, MassiveAction::ACTION_KO); $ma->addMessage($item->getErrorMessage(ERROR_ON_ACTION)); } } else { - $ma->itemDone($item->getType(), $key, MassiveAction::ACTION_NORIGHT); + $ma->itemDone($item::class, $key, MassiveAction::ACTION_NORIGHT); $ma->addMessage($item->getErrorMessage(ERROR_RIGHT)); } } @@ -190,13 +180,13 @@ public static function processMassiveActionsForOneItemtype( foreach ($ids as $id) { if ($item->can($id, UPDATE)) { if ($item->backToStock(["id" => $id])) { - $ma->itemDone($item->getType(), $id, MassiveAction::ACTION_OK); + $ma->itemDone($item::class, $id, MassiveAction::ACTION_OK); } else { - $ma->itemDone($item->getType(), $id, MassiveAction::ACTION_KO); + $ma->itemDone($item::class, $id, MassiveAction::ACTION_KO); $ma->addMessage($item->getErrorMessage(ERROR_ON_ACTION)); } } else { - $ma->itemDone($item->getType(), $id, MassiveAction::ACTION_NORIGHT); + $ma->itemDone($item::class, $id, MassiveAction::ACTION_NORIGHT); $ma->addMessage($item->getErrorMessage(ERROR_RIGHT)); } } @@ -212,25 +202,24 @@ public static function processMassiveActionsForOneItemtype( 'pages' => $input['pages'] ]) ) { - $ma->itemDone($item->getType(), $key, MassiveAction::ACTION_OK); + $ma->itemDone($item::class, $key, MassiveAction::ACTION_OK); } else { - $ma->itemDone($item->getType(), $key, MassiveAction::ACTION_KO); + $ma->itemDone($item::class, $key, MassiveAction::ACTION_KO); $ma->addMessage($item->getErrorMessage(ERROR_ON_ACTION)); } } else { - $ma->itemDone($item->getType(), $key, MassiveAction::ACTION_NORIGHT); + $ma->itemDone($item::class, $key, MassiveAction::ACTION_NORIGHT); $ma->addMessage($item->getErrorMessage(ERROR_RIGHT)); } } } else { - $ma->itemDone($item->getType(), $ids, MassiveAction::ACTION_KO); + $ma->itemDone($item::class, $ids, MassiveAction::ACTION_KO); } return; } parent::processMassiveActionsForOneItemtype($ma, $item, $ids); } - /** * Send the cartridge back to stock. * @@ -245,7 +234,7 @@ public function backToStock(array $input, $history = true) global $DB; $result = $DB->update( - $this->getTable(), + static::getTable(), [ 'date_out' => 'NULL', 'date_use' => 'NULL', @@ -255,13 +244,9 @@ public function backToStock(array $input, $history = true) 'id' => $input['id'] ] ); - if ($result && ($DB->affectedRows() > 0)) { - return true; - } - return false; + return $result && ($DB->affectedRows() > 0); } - // SPECIFIC FUNCTIONS /** @@ -279,10 +264,10 @@ public function install($pID, $tID) /** @var \DBmysql $DB */ global $DB; - // Get first unused cartridge + // Get first unused cartridge $iterator = $DB->request([ 'SELECT' => ['id'], - 'FROM' => $this->getTable(), + 'FROM' => static::getTable(), 'WHERE' => [ 'cartridgeitems_id' => $tID, 'date_use' => null @@ -295,7 +280,7 @@ public function install($pID, $tID) $cID = $result['id']; // Update cartridge taking care of multiple insertion $result = $DB->update( - $this->getTable(), + static::getTable(), [ 'date_use' => date('Y-m-d'), 'printers_id' => $pID @@ -315,12 +300,11 @@ public function install($pID, $tID) return true; } } else { - Session::addMessageAfterRedirect(__('No free cartridge'), false, ERROR); + Session::addMessageAfterRedirect(__s('No free cartridge'), false, ERROR); } return false; } - /** * Unlink a cartridge from a printer by cartridge ID. * @@ -341,7 +325,7 @@ public function uninstall($ID) } $result = $DB->update( - $this->getTable(), + static::getTable(), [ 'date_out' => date('Y-m-d') ] + $toadd, @@ -373,7 +357,6 @@ public function uninstall($ID) return false; } - /** * Print the cartridge count HTML array for the cartridge item $tID * @@ -385,30 +368,52 @@ public function uninstall($ID) **/ public static function getCount($tID, $alarm_threshold, $nohtml = 0) { - - // Get total + // Get total $total = self::getTotalNumber($tID); $out = ""; - if ($total != 0) { + if ($total !== 0) { $unused = self::getUnusedNumber($tID); $used = self::getUsedNumber($tID); $old = self::getOldNumber($tID); - $highlight = ""; - if ($unused <= $alarm_threshold) { - $highlight = "tab_bg_1_2"; - } + $highlight = $unused <= $alarm_threshold; + + $counts = [ + 'new' => [ + 'label' => _nx('cartridge', 'New', 'New', $unused), + 'value' => $unused + ], + 'used' => [ + 'label' => _nx('cartridge', 'Used', 'Used', $used), + 'value' => $used + ], + 'worn' => [ + 'label' => _nx('cartridge', 'Worn', 'Worn', $old), + 'value' => $old + ], + 'total' => [ + 'label' => __('Total'), + 'value' => $total + ] + ]; if (!$nohtml) { - $out .= ""; - $out .= "
"; - $out .= __('Total') . "$total"; - $out .= ""; - $out .= _nx('cartridge', 'New', 'New', $unused); - $out .= "$unused
"; - $out .= _nx('cartridge', 'Used', 'Used', $used); - $out .= "$used"; - $out .= _nx('cartridge', 'Worn', 'Worn', $old); - $out .= "$old
"; + // language=Twig + $out .= TemplateRenderer::getInstance()->renderFromStringTemplate(<< + + {{ counts['total']['label'] }} + {{ counts['total']['value'] }} + {{ counts['new']['label'] }} + {{ counts['new']['value'] }} + + + {{ counts['used']['label'] }} + {{ counts['used']['value'] }} + {{ counts['worn']['label'] }} + {{ counts['worn']['value'] }} + + +TWIG, ['counts' => $counts, 'highlight' => $highlight]); } else { //TRANS : for display cartridges count : %1$d is the total number, // %2$d the new one, %3$d the used one, %4$d worn one @@ -422,7 +427,7 @@ public static function getCount($tID, $alarm_threshold, $nohtml = 0) } } else { if (!$nohtml) { - $out .= "
" . __('No cartridge') . "
"; + $out .= "
" . __s('No cartridge') . "
"; } else { $out .= __('No cartridge'); } @@ -430,7 +435,6 @@ public static function getCount($tID, $alarm_threshold, $nohtml = 0) return $out; } - /** * Print the cartridge count HTML array for the printer $pID * @@ -443,27 +447,46 @@ public static function getCount($tID, $alarm_threshold, $nohtml = 0) **/ public static function getCountForPrinter($pID, $nohtml = 0) { - - // Get total + // Get total $total = self::getTotalNumberForPrinter($pID); $out = ""; - if ($total != 0) { + if ($total !== 0) { $used = self::getUsedNumberForPrinter($pID); $old = self::getOldNumberForPrinter($pID); - $highlight = ""; - if ($used == 0) { - $highlight = "tab_bg_1_2"; - } + $highlight = $used === 0; + + $counts = [ + 'used' => [ + 'label' => _nx('cartridge', 'Used', 'Used', $used), + 'value' => $used + ], + 'worn' => [ + 'label' => _nx('cartridge', 'Worn', 'Worn', $old), + 'value' => $old + ], + 'total' => [ + 'label' => __('Total'), + 'value' => $total + ] + ]; if (!$nohtml) { - $out .= ""; - $out .= "
"; - $out .= __('Total') . "$total"; - $out .= "
"; - $out .= _nx('cartridge', 'Used', 'Used', $used); - $out .= "$used"; - $out .= _nx('cartridge', 'Worn', 'Worn', $old); - $out .= "$old
"; + // language=Twig + $out .= TemplateRenderer::getInstance()->renderFromStringTemplate(<< + + {{ counts['total']['label'] }} + {{ counts['total']['value'] }} + + + + {{ counts['used']['label'] }} + {{ counts['used']['value'] }} + {{ counts['worn']['label'] }} + {{ counts['worn']['value'] }} + + +TWIG, ['counts' => $counts, 'highlight' => $highlight]); } else { //TRANS : for display cartridges count : %1$d is the total number, // %2$d the used one, %3$d the worn one @@ -471,7 +494,7 @@ public static function getCountForPrinter($pID, $nohtml = 0) } } else { if (!$nohtml) { - $out .= "
" . __('No cartridge') . "
"; + $out .= "
" . __s('No cartridge') . "
"; } else { $out .= __('No cartridge'); } @@ -479,7 +502,6 @@ public static function getCountForPrinter($pID, $nohtml = 0) return $out; } - /** * Count the total number of cartridges for the cartridge item $tID. * @@ -500,7 +522,6 @@ public static function getTotalNumber($tID) return $row['cpt']; } - /** * Count the number of cartridges used for the printer $pID * @@ -523,7 +544,6 @@ public static function getTotalNumberForPrinter($pID) return (int)$row['cpt']; } - /** * Count the number of used cartridges for the cartridge item $tID. * @@ -551,7 +571,6 @@ public static function getUsedNumber($tID) return (int)$row['cpt']; } - /** * Count the number of used cartridges used for the printer $pID. * @@ -578,7 +597,6 @@ public static function getUsedNumberForPrinter($pID) return $result['cpt']; } - /** * Count the number of old cartridges for the cartridge item $tID. * @@ -602,13 +620,12 @@ public static function getOldNumber($tID) return $result['cpt']; } - /** * count how many old cartbridge for theprinter $pID * * @since 0.85 * - * @param $pID integer: printer identifier. + * @param integer $pID printer identifier. * * @return integer : number of old cartridge counted. **/ @@ -628,11 +645,10 @@ public static function getOldNumberForPrinter($pID) return $result['cpt']; } - /** * count how many cartbridge unused for the cartridge item $tID * - * @param $tID integer: cartridge item identifier. + * @param integer $tID cartridge item identifier. * * @return integer : number of cartridge unused counted. **/ @@ -695,10 +711,7 @@ public static function getAlarmThreshold(int $tID): int 'id' => $tID ] ]); - if ($it->count()) { - return $it->current()['alarm_threshold']; - } - return 0; + return $it->count() ? $it->current()['alarm_threshold'] : 0; } /** @@ -711,17 +724,15 @@ public static function getAlarmThreshold(int $tID): int **/ public static function getStatus($date_use, $date_out) { - - if (is_null($date_use) || empty($date_use)) { + if (empty($date_use)) { return _nx('cartridge', 'New', 'New', 1); } - if (is_null($date_out) || empty($date_out)) { + if (empty($date_out)) { return _nx('cartridge', 'Used', 'Used', 1); } return _nx('cartridge', 'Worn', 'Worn', 1); } - /** * Print out the cartridges of a defined type * @@ -739,11 +750,7 @@ public static function showForCartridgeItem(CartridgeItem $cartitem, $show_old = if (!$cartitem->can($tID, READ)) { return false; } - if (isset($_GET["start"])) { - $start = $_GET["start"]; - } else { - $start = 0; - } + $start = (int) ($_GET["start"] ?? 0); $canedit = $cartitem->can($tID, UPDATE); @@ -783,7 +790,7 @@ public static function showForCartridgeItem(CartridgeItem $cartitem, $show_old = 'glpi_printers.name AS printname', 'glpi_printers.init_pages_counter' ], - 'FROM' => self::gettable(), + 'FROM' => self::getTable(), 'LEFT JOIN' => [ 'glpi_printers' => [ 'FKEY' => [ @@ -801,165 +808,141 @@ public static function showForCartridgeItem(CartridgeItem $cartitem, $show_old = $number = count($iterator); $rand = mt_rand(); - echo "
"; + // Display the pager Html::printAjaxPager(Consumable::getTypeName(Session::getPluralNumber()), $start, $total_number); if ($canedit && $number) { - Html::openMassiveActionsForm('mass' . __CLASS__ . $rand); - $actions = ['purge' => _x('button', 'Delete permanently'), - 'Infocom' . MassiveAction::CLASS_ACTION_SEPARATOR . 'activate' - => __('Enable the financial and administrative information') + $actions = [ + 'purge' => _x('button', 'Delete permanently'), + 'Infocom' . MassiveAction::CLASS_ACTION_SEPARATOR . 'activate' => __('Enable the financial and administrative information') ]; if (!$show_old) { - $actions['Cartridge' . MassiveAction::CLASS_ACTION_SEPARATOR . 'backtostock'] - = __('Back to stock'); + $actions['Cartridge' . MassiveAction::CLASS_ACTION_SEPARATOR . 'backtostock'] = __('Back to stock'); } $massiveactionparams = ['num_displayed' => min($_SESSION['glpilist_limit'], $number), 'specific_actions' => $actions, 'container' => 'mass' . __CLASS__ . $rand, 'rand' => $rand ]; - Html::showMassiveActions($massiveactionparams); - } - echo ""; - if (!$show_old) { - echo ""; - echo ""; - } else { // Old - echo ""; } - $header_begin = ""; - $header_top = ''; - $header_bottom = ''; - $header_end = ''; - - if ($canedit && $number) { - $header_begin .= ""; - } - $header_end .= ""; - $header_end .= ""; - $header_end .= ""; - $header_end .= ""; - - if ($show_old) { - $header_end .= ""; - $header_end .= ""; - } - - $header_end .= ""; - $header_end .= ""; - echo $header_begin . $header_top . $header_end; - $pages = []; - if ($number) { - foreach ($iterator as $data) { - $date_in = Html::convDate($data["date_in"]); - $date_use = Html::convDate($data["date_use"]); - $date_out = Html::convDate($data["date_out"]); - $printer = $data["printers_id"]; - - echo ""; - if ($canedit) { - echo ""; - } - echo "'; - echo ""; - echo ""; - echo ""; - if ($show_old) { - // Get initial counter page - if (!isset($pages[$printer])) { - $pages[$printer] = $data['init_pages_counter']; - } - echo ""; + if ($show_old) { + // Get initial counter page + if (!isset($pages[$printer])) { + $pages[$printer] = $data['init_pages_counter']; } - echo ""; - echo ""; - } - if ( - $show_old - && ($number > 0) - ) { - if ($nb_pages_printed == 0) { - $nb_pages_printed = 1; + if ($pages[$printer] < $data['pages']) { + $pages_printed += $data['pages'] - $pages[$printer]; + $nb_pages_printed++; + $pp = $data['pages'] - $pages[$printer]; + $pages[$printer] = $data['pages']; } - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - } else { - echo $header_begin . $header_bottom . $header_end; } + $entries[] = [ + 'itemtype' => self::class, + 'id' => $data['id'], + 'state' => self::getStatus($data["date_use"], $data["date_out"]), + 'used_on' => $printer_link, + 'date_in' => $data['date_in'], + 'date_use' => $data['date_use'], + 'date_out' => $data['date_out'], + 'printer_counter' => $pp ?? 0, + 'infocom' => Infocom::showDisplayLink('Cartridge', $data["id"], false) + ]; } - echo "
" . - self::getCount($tID, -1) . "
" . __('Worn cartridges'); - echo "
"; - $header_top = Html::getCheckAllAsCheckbox('mass' . __CLASS__ . $rand); - $header_bottom = Html::getCheckAllAsCheckbox('mass' . __CLASS__ . $rand); - $header_end .= "" . __('ID') . "" . _x('item', 'State') . "" . __('Add date') . "" . __('Use date') . "" . __('Used on') . "" . __('End date') . "" . __('Printer counter') . "" . __('Financial and administrative information') . "
"; - Html::showMassiveActionCheckBox(__CLASS__, $data["id"]); - echo "" . $data['id'] . '" . self::getStatus($data["date_use"], $data["date_out"]); - echo "" . $date_in . "" . $date_use . ""; - if (!is_null($date_use)) { - if ($data["printID"] > 0) { - $printname = $data["printname"]; - if ($_SESSION['glpiis_ids_visible'] || empty($printname)) { - $printname = sprintf(__('%1$s (%2$s)'), $printname, $data["printID"]); - } - echo "" . $printname . ""; - } else { - echo NOT_AVAILABLE; + $entries = []; + foreach ($iterator as $data) { + $printer = $data["printers_id"]; + + $printer_link = ''; + if (!is_null($data["date_use"])) { + if ($data["printID"] > 0) { + $printname = $data["printname"]; + if ($_SESSION['glpiis_ids_visible'] || empty($printname)) { + $printname = sprintf(__('%1$s (%2$s)'), $printname, $data["printID"]); } - $tmp_dbeg = explode("-", $data["date_in"]); - $tmp_dend = explode("-", $data["date_use"]); - $stock_time_tmp = mktime(0, 0, 0, $tmp_dend[1], $tmp_dend[2], $tmp_dend[0]) - - mktime(0, 0, 0, $tmp_dbeg[1], $tmp_dbeg[2], $tmp_dbeg[0]); - $stock_time += $stock_time_tmp; - } - if ($show_old) { - echo ""; - echo $date_out; - $tmp_dbeg = explode("-", $data["date_use"]); - $tmp_dend = explode("-", $data["date_out"]); - $use_time_tmp = mktime(0, 0, 0, $tmp_dend[1], $tmp_dend[2], $tmp_dend[0]) - - mktime(0, 0, 0, $tmp_dbeg[1], $tmp_dbeg[2], $tmp_dbeg[0]); - $use_time += $use_time_tmp; + $printer_link = "" . htmlspecialchars($printname) . ""; + } else { + $printer_link = NOT_AVAILABLE; } + $tmp_dbeg = explode("-", $data["date_in"]); + $tmp_dend = explode("-", $data["date_use"]); + $stock_time_tmp = mktime(0, 0, 0, $tmp_dend[1], $tmp_dend[2], $tmp_dend[0]) + - mktime(0, 0, 0, $tmp_dbeg[1], $tmp_dbeg[2], $tmp_dbeg[0]); + $stock_time += $stock_time_tmp; + } + if ($show_old) { + $tmp_dbeg = explode("-", $data["date_use"]); + $tmp_dend = explode("-", $data["date_out"]); + $use_time_tmp = mktime(0, 0, 0, $tmp_dend[1], $tmp_dend[2], $tmp_dend[0]) + - mktime(0, 0, 0, $tmp_dbeg[1], $tmp_dbeg[2], $tmp_dbeg[0]); + $use_time += $use_time_tmp; + } - echo ""; - if ($pages[$printer] < $data['pages']) { - $pages_printed += $data['pages'] - $pages[$printer]; - $nb_pages_printed++; - $pp = $data['pages'] - $pages[$printer]; - printf(_n('%d printed page', '%d printed pages', $pp), $pp); - $pages[$printer] = $data['pages']; - } else if ($data['pages'] != 0) { - echo "" . __('Counter error') . ""; - } - echo ""; - Infocom::showDisplayLink('Cartridge', $data["id"]); - echo "
 " . __('Average time in stock') . "
"; - echo round($stock_time / $number / 60 / 60 / 24 / 30.5, 1) . " " . _n('month', 'months', 1) . "
 " . __('Average time in use') . "
"; - echo round($use_time / $number / 60 / 60 / 24 / 30.5, 1) . " " . _n('month', 'months', 1) . "
" . __('Average number of printed pages') . "
"; - echo round($pages_printed / $nb_pages_printed) . "
 
"; - if ($canedit && $number) { - $massiveactionparams['ontop'] = false; - Html::showMassiveActions($massiveactionparams); - Html::closeForm(); + $footers = []; + if ( + $show_old + && ($number > 0) + ) { + if ($nb_pages_printed === 0) { + $nb_pages_printed = 1; + } + $time_stock = round($stock_time / $number / 60 / 60 / 24 / 30.5, 1); + $avg_stock = __('Average time in stock') . "\n" . $time_stock . " " . _n('month', 'months', $time_stock); + $time_use = round($use_time / $number / 60 / 60 / 24 / 30.5, 1); + $avg_use = __('Average time in use') . "\n" . $time_use . " " . _n('month', 'months', $time_use); + $avg_pages = __('Average number of printed pages') . "\n" . round($pages_printed / max($nb_pages_printed, 1)); + $footers = [['', '', '', $avg_stock, '', $avg_use, $avg_pages]]; } - echo "
\n\n"; - } + $columns = [ + 'id' => __('ID'), + 'state' => _x('item', 'State'), + 'date_in' => __('Add date'), + 'date_use' => __('Use date'), + 'used_on' => __('Used on'), + ]; + if ($show_old) { + $columns['date_out'] = __('End date'); + $columns['printer_counter'] = __('Printer counter'); + } + $columns['infocom'] = __('Financial and administrative information'); + + TemplateRenderer::getInstance()->display('components/datatable.html.twig', [ + 'is_tab' => true, + 'nopager' => true, + 'nofilter' => true, + 'nosort' => true, + 'super_header' => $show_old ? __('Worn cartridges') : __('Used cartridges'), + 'columns' => $columns, + 'formatters' => [ + 'used_on' => 'raw_html', + 'date_add' => 'date', + 'date_use' => 'date', + 'date_out' => 'date', + 'printer_counter' => 'integer', + 'infocom' => 'raw_html' + ], + 'entries' => $entries, + 'footers' => $footers, + 'footer_class' => 'fw-bold', + 'total_number' => count($entries), + 'filtered_number' => count($entries), + 'showmassiveactions' => $canedit, + 'massiveactionparams' => [ + 'num_displayed' => count($entries), + 'container' => 'mass' . static::class . $rand, + ] + $massiveactionparams + ]); + } /** * Print out a link to add directly a new cartridge from a cartridge item. * - * @param $cartitem CartridgeItem object + * @param CartridgeItem $cartitem * * @return boolean|void **/ @@ -990,7 +973,6 @@ class='btn btn-primary'>"; } } - /** * Show installed cartridges * @@ -1003,11 +985,8 @@ class='btn btn-primary'>"; **/ public static function showForPrinter(Printer $printer, $old = 0) { - /** - * @var array $CFG_GLPI - * @var \DBmysql $DB - */ - global $CFG_GLPI, $DB; + /** @var \DBmysql $DB */ + global $DB; $instID = $printer->getField('id'); if (!self::canView()) { @@ -1061,132 +1040,95 @@ public static function showForPrinter(Printer $printer, $old = 0) $number = count($iterator); if ($canedit && !$old) { - echo "
"; - echo "
"; - echo ""; - echo ""; - echo "
"; - echo "\n"; - if (CartridgeItem::dropdownForPrinter($printer)) { - //TRANS : multiplier - echo "" . __('x') . " "; - Dropdown::showNumber("nbcart", ['value' => 1, - 'min' => 1, - 'max' => 5 - ]); - echo ""; - } else { - echo __('No cartridge available'); - } - - echo "
"; - Html::closeForm(); - echo "
"; + $twig_params = [ + 'printer' => $printer, + 'install_label' => _sx('button', 'Install'), + 'count_label' => __('Count'), + ]; + // language=Twig + echo TemplateRenderer::getInstance()->renderFromStringTemplate(<< + +
+ {% set has_cartridges = false %} + {% set dropdown %} + {% set has_cartridges = call('CartridgeItem::dropdownForPrinter', [printer]) %} + {% endset %} + {% if has_cartridges %} + {{ fields.htmlField('', dropdown, null, { + field_class: 'col-4', + }) }} + {{ fields.numberField('nbcart', 1, count_label, { + min: 1, + max: 5, + field_class: 'col-4', + }) }} + {% set btn_install %} + + + {% endset %} + {{ fields.htmlField('', btn_install, null, { + no_label: true, + field_class: 'col-4', + mb: 'mb-2' + }) }} + {% endif %} +
+ + +TWIG, $twig_params); } - echo "
"; + // language=Twig + echo TemplateRenderer::getInstance()->renderFromStringTemplate(<< + +TWIG, ['printer_id' => $printer->getID()]); $pages = $printer->fields['init_pages_counter']; - echo "
"; - if ($canedit && $number) { - Html::openMassiveActionsForm('mass' . __CLASS__ . $rand); - if (!$old) { - $actions = [__CLASS__ . MassiveAction::CLASS_ACTION_SEPARATOR . 'uninstall' - => __('End of life'), - __CLASS__ . MassiveAction::CLASS_ACTION_SEPARATOR . 'backtostock' - => __('Back to stock') - ]; - } else { - $actions = [__CLASS__ . MassiveAction::CLASS_ACTION_SEPARATOR . 'updatepages' - => __('Update printer counter'), - 'purge' => _x('button', 'Delete permanently') - ]; - } - $massiveactionparams = ['num_displayed' => min($_SESSION['glpilist_limit'], $number), - 'specific_actions' => $actions, - 'container' => 'mass' . __CLASS__ . $rand, - 'rand' => $rand, - 'extraparams' => ['maxpages' - => $printer->fields['last_pages_counter'] - ] + if (!$old) { + $actions = [ + __CLASS__ . MassiveAction::CLASS_ACTION_SEPARATOR . 'uninstall' => __('End of life'), + __CLASS__ . MassiveAction::CLASS_ACTION_SEPARATOR . 'backtostock' => __('Back to stock') ]; - Html::showMassiveActions($massiveactionparams); - } - echo ""; - echo ""; - if ($old == 0) { - echo ""; } else { - echo ""; - } - echo ""; - - $header_begin = ""; - $header_top = ''; - $header_end = ''; - - if ($canedit) { - $header_begin .= ""; - } - $header_end .= ""; - $header_end .= ""; - $header_end .= ""; - $header_end .= ""; - if ($old != 0) { - $header_end .= ""; - $header_end .= ""; - $header_end .= ""; + $actions = [ + __CLASS__ . MassiveAction::CLASS_ACTION_SEPARATOR . 'updatepages' => __('Update printer counter'), + 'purge' => _x('button', 'Delete permanently') + ]; } - $header_end .= ""; - echo $header_begin . $header_top . $header_end; + $massiveactionparams = [ + 'specific_actions' => $actions, + 'rand' => $rand, + 'extraparams' => [ + 'maxpages' => $printer->fields['last_pages_counter'] + ] + ]; $stock_time = 0; $use_time = 0; $pages_printed = 0; $nb_pages_printed = 0; + $entries = []; foreach ($iterator as $data) { - $cart_id = $data["id"]; - $typename = $data["typename"]; - $date_in = Html::convDate($data["date_in"]); - $date_use = Html::convDate($data["date_use"]); - $date_out = Html::convDate($data["date_out"]); - $viewitemjs = ($canedit ? "style='cursor:pointer' onClick=\"viewEditCartridge" . $cart_id . - "$rand();\"" : ''); - echo ""; - if ($canedit) { - echo ""; - } - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; + $model = '' . htmlspecialchars(sprintf(__('%1$s - %2$s'), $data["type"], $data["ref"])) . ''; $tmp_dbeg = explode("-", $data["date_in"]); $tmp_dend = explode("-", $data["date_use"]); @@ -1194,61 +1136,86 @@ class='btn btn-primary'>"; $stock_time_tmp = mktime(0, 0, 0, $tmp_dend[1], $tmp_dend[2], $tmp_dend[0]) - mktime(0, 0, 0, $tmp_dbeg[1], $tmp_dbeg[2], $tmp_dbeg[0]); $stock_time += $stock_time_tmp; - if ($old != 0) { - echo ""; - echo ""; } - echo ""; + $entries[] = [ + 'row_class' => $data["is_deleted"] ? 'table-danger cursor-pointer' : 'cursor-pointer', + 'itemtype' => self::class, + 'id' => $data['id'], + 'model' => $model, + 'type' => $data["typename"], + 'date_add' => $data['date_in'], + 'date_use' => $data['date_use'], + 'date_out' => $data['date_out'], + 'pages' => $data['pages'], + 'pages_printed' => $pp ?? 0, + ]; } - if ($old) { // Print average + $columns = [ + 'id' => __('ID'), + 'model' => _n('Cartridge model', 'Cartridge models', 1), + 'type' => _n('Cartridge type', 'Cartridge types', 1), + 'date_add' => __('Add date'), + 'date_use' => __('Use date'), + ]; + $footers = []; + + if ($old) { + $columns['date_out'] = __('End date'); + $columns['pages'] = __('Printer counter'); + $columns['pages_printed'] = __('Printed pages'); + if ($number > 0) { - if ($nb_pages_printed == 0) { - $nb_pages_printed = 1; - } - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; + $avg_use = __('Average time in use') . "\n" . $time_use . " " . _n('month', 'months', $time_use); + $avg_pages = __('Average number of printed pages') . "\n" . round($pages_printed / max($nb_pages_printed, 1)); + $footers = [['', '', '', $avg_stock, $avg_use, '', '', $avg_pages]]; } } - echo "
" . __('Used cartridges') . "" . __('Worn cartridges') . "
"; - $header_top .= Html::getCheckAllAsCheckbox('mass' . __CLASS__ . $rand); - $header_end .= "" . __('ID') . "" . _n('Cartridge model', 'Cartridge models', 1) . "" . _n('Cartridge type', 'Cartridge types', 1) . "" . __('Add date') . "" . __('Use date') . "" . __('End date') . "" . __('Printer counter') . "" . __('Printed pages') . "
"; - Html::showMassiveActionCheckBox(__CLASS__, $cart_id); - echo ""; - if ($canedit) { - echo "\n\n"; - } - echo $data["id"] . ""; - echo ""; - printf(__('%1$s - %2$s'), $data["type"], $data["ref"]); - echo "" . $typename . "" . $date_in . "" . $date_use . "" . $date_out; - + if ($old) { $tmp_dbeg = explode("-", $data["date_use"]); $tmp_dend = explode("-", $data["date_out"]); - $use_time_tmp = mktime(0, 0, 0, $tmp_dend[1], $tmp_dend[2], $tmp_dend[0]) - mktime(0, 0, 0, $tmp_dbeg[1], $tmp_dbeg[2], $tmp_dbeg[0]); $use_time += $use_time_tmp; - echo "" . $data['pages'] . ""; - if ($pages < $data['pages']) { $pages_printed += $data['pages'] - $pages; $nb_pages_printed++; $pp = $data['pages'] - $pages; - echo $pp; $pages = $data['pages']; - } else { - echo " "; } - echo "
 " . __('Average time in stock') . "
"; $time_stock = round($stock_time / $number / 60 / 60 / 24 / 30.5, 1); - echo sprintf(_n('%d month', '%d months', $time_stock), $time_stock) . "
" . __('Average time in use') . "
"; + $avg_stock = __('Average time in stock') . "\n" . $time_stock . " " . _n('month', 'months', $time_stock); $time_use = round($use_time / $number / 60 / 60 / 24 / 30.5, 1); - echo sprintf(_n('%d month', '%d months', $time_use), $time_use) . "
" . __('Average number of printed pages') . "
"; - echo round($pages_printed / $nb_pages_printed) . "
"; - if ($canedit && $number) { - $massiveactionparams['ontop'] = false; - Html::showMassiveActions($massiveactionparams); - Html::closeForm(); - } - echo "
\n\n"; + TemplateRenderer::getInstance()->display('components/datatable.html.twig', [ + 'is_tab' => true, + 'nopager' => true, + 'nofilter' => true, + 'nosort' => true, + 'super_header' => $old ? __('Worn cartridges') : __('Used cartridges'), + 'columns' => $columns, + 'formatters' => [ + 'model' => 'raw_html', + 'date_add' => 'date', + 'date_use' => 'date', + 'date_out' => 'date', + 'pages' => 'integer', + 'pages_printed' => 'integer', + ], + 'entries' => $entries, + 'footers' => $footers, + 'footer_class' => 'fw-bold', + 'total_number' => count($entries), + 'filtered_number' => count($entries), + 'showmassiveactions' => $canedit, + 'massiveactionparams' => [ + 'num_displayed' => count($entries), + 'container' => 'mass' . static::class . $rand, + ] + $massiveactionparams + ]); } - /** * Show form for Cartridge * @since 0.84 @@ -1261,121 +1228,44 @@ class='btn btn-primary'>"; */ public function showForm($ID, array $options = []) { - - if (isset($options['parent']) && !empty($options['parent'])) { + $printer = new Printer(); + if (!empty($options['parent'])) { $printer = $options['parent']; } if (!$this->getFromDB($ID)) { return false; } - $printer = new Printer(); + $printer->check($this->getField('printers_id'), UPDATE); $cartitem = new CartridgeItem(); $cartitem->getFromDB($this->getField('cartridgeitems_id')); - $is_old = !empty($this->fields['date_out']); - $is_used = !empty($this->fields['date_use']); - - $options['colspan'] = 2; - $options['candel'] = false; // Do not permit delete here - $options['canedit'] = $is_used; // Do not permit edit if cart is not used - $this->showFormHeader($options); - - echo ""; - echo "" . _n('Printer', 'Printers', 1) . ""; - echo $printer->getLink(); - echo "\n"; - echo "\n"; - echo "\n"; - echo "" . _n('Cartridge model', 'Cartridge models', 1) . ""; - echo "" . $cartitem->getLink() . "\n"; - - echo ""; - echo "" . __('Add date') . ""; - echo "" . Html::convDate($this->fields["date_in"]) . ""; - - echo "" . __('Use date') . ""; - if ($is_used && !$is_old) { - Html::showDateField("date_use", ['value' => $this->fields["date_use"], - 'maybeempty' => false, - 'canedit' => true, - 'min' => $this->fields["date_in"] - ]); - } else { - echo Html::convDate($this->fields["date_use"]); - } - echo "\n"; - - if ($is_old) { - echo ""; - echo "" . __('End date') . ""; - Html::showDateField("date_out", ['value' => $this->fields["date_out"], - 'maybeempty' => false, - 'canedit' => true, - 'min' => $this->fields["date_use"] - ]); - echo ""; - echo "" . __('Printer counter') . ""; - echo "fields['pages'] . "\">"; - echo "\n"; - } - $this->showFormButtons($options); - - return true; - } - - - /** - * Get notification parameters by entity - * - * @param integer $entity The entity (default 0) - * @return array Array of notification parameters - */ - public static function getNotificationParameters($entity = 0) - { - /** - * @var array $CFG_GLPI - * @var \DBmysql $DB - */ - global $CFG_GLPI, $DB; - - //Look for parameters for this entity - $iterator = $DB->request([ - 'SELECT' => ['cartridges_alert_repeat'], - 'FROM' => 'glpi_entities', - 'WHERE' => ['id' => $entity] + TemplateRenderer::getInstance()->display('pages/assets/cartridge.html.twig', [ + 'item' => $this, + 'printer' => $printer, + 'model' => $cartitem, + 'params' => [ + 'canedit' => !empty($this->fields['date_use']), + 'candel' => false, + 'formfooter' => false, + ] ]); - - if (!count($iterator)) { - //No specific parameters defined, taking global configuration params - return $CFG_GLPI['cartridges_alert_repeat']; - } else { - $data = $iterator->current(); - //This entity uses global parameters -> return global config - if ($data['cartridges_alert_repeat'] == -1) { - return $CFG_GLPI['cartridges_alert_repeat']; - } - // ELSE Special configuration for this entity - return $data['cartridges_alert_repeat']; - } + return true; } - public function getTabNameForItem(CommonGLPI $item, $withtemplate = 0) { - if (!$withtemplate && self::canView()) { $nb = 0; - switch ($item->getType()) { - case 'Printer': + switch ($item::class) { + case Printer::class: if ($_SESSION['glpishow_count_on_tabs']) { $nb = self::countForPrinter($item); } return self::createTabEntry(self::getTypeName(Session::getPluralNumber()), $nb); - case 'CartridgeItem': + case CartridgeItem::class: if ($_SESSION['glpishow_count_on_tabs']) { $nb = self::countForCartridgeItem($item); } @@ -1385,7 +1275,6 @@ public function getTabNameForItem(CommonGLPI $item, $withtemplate = 0) return ''; } - /** * Count the number of cartridges associated with the given cartridge item. * @param CartridgeItem $item CartridgeItem object @@ -1393,11 +1282,9 @@ public function getTabNameForItem(CommonGLPI $item, $withtemplate = 0) */ public static function countForCartridgeItem(CartridgeItem $item) { - return countElementsInTable(['glpi_cartridges'], ['glpi_cartridges.cartridgeitems_id' => $item->getField('id')]); } - /** * Count the number of cartridges associated with the given printer. * @param Printer $item Printer object @@ -1405,23 +1292,20 @@ public static function countForCartridgeItem(CartridgeItem $item) */ public static function countForPrinter(Printer $item) { - return countElementsInTable(['glpi_cartridges'], ['glpi_cartridges.printers_id' => $item->getField('id')]); } - public static function displayTabContentForItem(CommonGLPI $item, $tabnum = 1, $withtemplate = 0) { - - switch ($item->getType()) { - case 'Printer': + switch ($item::class) { + case Printer::class: $info = new Printer_CartridgeInfo(); $info->showForPrinter($item); self::showForPrinter($item); self::showForPrinter($item, 1); break; - case 'CartridgeItem': + case CartridgeItem::class: self::showAddForm($item); self::showForCartridgeItem($item); self::showForCartridgeItem($item, 1); diff --git a/src/CartridgeItem.php b/src/CartridgeItem.php index 1e0f536ba9e..f9dc38790f9 100644 --- a/src/CartridgeItem.php +++ b/src/CartridgeItem.php @@ -61,26 +61,13 @@ public static function getTypeName($nb = 0) return _n('Cartridge model', 'Cartridge models', $nb); } - - /** - * @see CommonGLPI::getMenuName() - * - * @since 0.85 - **/ public static function getMenuName() { return Cartridge::getTypeName(Session::getPluralNumber()); } - - /** - * @since 0.84 - * - * @see CommonDBTM::getPostAdditionalInfosForName - **/ public function getPostAdditionalInfosForName() { - if (isset($this->fields["ref"]) && !empty($this->fields["ref"])) { return $this->fields["ref"]; } @@ -101,7 +88,6 @@ public function prepareInputForUpdate($input) public function cleanDBonPurge() { - $this->deleteChildrenAndRelationsFromDb( [ Cartridge::class, @@ -110,13 +96,11 @@ public function cleanDBonPurge() ); $class = new Alert(); - $class->cleanDBonItemDelete($this->getType(), $this->fields['id']); + $class->cleanDBonItemDelete(static::class, $this->fields['id']); } - public function post_getEmpty() { - if (isset($_SESSION['glpiactive_entity'])) { $this->fields["alarm_threshold"] = Entity::getUsedConfig( "cartridges_alert_repeat", @@ -127,10 +111,8 @@ public function post_getEmpty() } } - public function defineTabs($options = []) { - $ong = []; $this->addDefaultFormTab($ong); $this->addImpactTab($ong, $options); @@ -145,7 +127,6 @@ public function defineTabs($options = []) return $ong; } - ///// SPECIFIC FUNCTIONS /** @@ -170,7 +151,6 @@ public static function getCount($id) return $result['cpt']; } - /** * Add a compatible printer type for a cartridge type * @@ -201,14 +181,13 @@ public function addCompatibleType($cartridgeitems_id, $printermodels_id) return false; } - public function rawSearchOptions() { $tab = parent::rawSearchOptions(); $tab[] = [ 'id' => '2', - 'table' => $this->getTable(), + 'table' => static::getTable(), 'field' => 'id', 'name' => __('ID'), 'massiveaction' => false, @@ -217,7 +196,7 @@ public function rawSearchOptions() $tab[] = [ 'id' => '34', - 'table' => $this->getTable(), + 'table' => static::getTable(), 'field' => 'ref', 'name' => __('Reference'), 'datatype' => 'string', @@ -241,7 +220,7 @@ public function rawSearchOptions() $tab[] = [ 'id' => '9', - 'table' => $this->getTable(), + 'table' => static::getTable(), 'field' => '_virtual', 'name' => _n('Cartridge', 'Cartridges', Session::getPluralNumber()), 'datatype' => 'specific', @@ -324,7 +303,7 @@ public function rawSearchOptions() $tab[] = [ 'id' => '8', - 'table' => $this->getTable(), + 'table' => static::getTable(), 'field' => 'alarm_threshold', 'name' => __('Alert threshold'), 'datatype' => 'number', @@ -335,7 +314,7 @@ public function rawSearchOptions() $tab[] = [ 'id' => '16', - 'table' => $this->getTable(), + 'table' => static::getTable(), 'field' => 'comment', 'name' => __('Comments'), 'datatype' => 'text' @@ -373,19 +352,18 @@ public function rawSearchOptions() return $tab; } - public static function cronInfo($name) { return ['description' => __('Send alarms on cartridges')]; } - /** * Cron action on cartridges : alert if a stock is behind the threshold * * @param CronTask $task CronTask for log, display information if NULL? (default NULL) * - * @return void + * @return int + * @used-by CronTask **/ public static function cronCartridge($task = null) { @@ -397,7 +375,6 @@ public static function cronCartridge($task = null) $cron_status = 1; if ($CFG_GLPI["use_notifications"]) { - $message = []; $alert = new Alert(); foreach (Entity::getEntitiesToNotify('cartridges_alert_repeat') as $entity => $repeat) { @@ -480,11 +457,11 @@ public static function cronCartridge($task = null) $task->log(sprintf(__('%1$s: %2$s') . "\n", $entityname, $message)); $task->addVolume(1); } else { - Session::addMessageAfterRedirect(sprintf( + Session::addMessageAfterRedirect(htmlspecialchars(sprintf( __('%1$s: %2$s'), $entityname, $message - )); + ))); } $input = [ @@ -505,7 +482,7 @@ public static function cronCartridge($task = null) $task->log($msg); } else { //TRANS: %s is the entity - Session::addMessageAfterRedirect($msg, false, ERROR); + Session::addMessageAfterRedirect(htmlspecialchars($msg), false, ERROR); } } } @@ -515,11 +492,10 @@ public static function cronCartridge($task = null) return $cron_status; } - /** * Print a select with compatible cartridge * - * @param $printer Printer object + * @param Printer $printer * * @return string|boolean **/ @@ -583,21 +559,19 @@ public static function dropdownForPrinter(Printer $printer) return false; } - public function getEvents() { return ['alert' => __('Send alarms on cartridges')]; } - /** * Display debug information for current object **/ public function showDebug() { - - // see query_alert in cronCartridge() - $item = ['cartID' => $this->fields['id'], + // see query_alert in cronCartridge() + $item = [ + 'cartID' => $this->fields['id'], 'entity' => $this->fields['entities_id'], 'ref' => $this->fields['ref'], 'name' => $this->fields['name'], diff --git a/src/Consumable.php b/src/Consumable.php index 48d592b4033..f1bac15d863 100644 --- a/src/Consumable.php +++ b/src/Consumable.php @@ -47,13 +47,13 @@ class Consumable extends CommonDBChild { use Glpi\Features\Clonable; - // From CommonDBTM + // From CommonDBTM protected static $forward_entity_to = ['Infocom']; public $no_form_page = true; public static $rightname = 'consumable'; - // From CommonDBChild + // From CommonDBChild public static $itemtype = 'ConsumableItem'; public static $items_id = 'consumableitems_id'; @@ -66,7 +66,6 @@ public function getCloneRelations(): array public function getForbiddenStandardMassiveAction() { - $forbidden = parent::getForbiddenStandardMassiveAction(); $forbidden[] = 'update'; $forbidden[] = 'ObjectLock:unlock'; @@ -82,22 +81,18 @@ public function getForbiddenStandardMassiveAction() return $forbidden; } - public static function getNameField() { return 'id'; } - public static function getTypeName($nb = 0) { return _n('Consumable', 'Consumables', $nb); } - public function prepareInputForAdd($input) { - $item = new ConsumableItem(); if ($item->getFromDB($input["consumableitems_id"])) { return ["consumableitems_id" => $item->fields["id"], @@ -110,8 +105,7 @@ public function prepareInputForAdd($input) public function post_addItem() { - - // inherit infocom + // inherit infocom $infocoms = Infocom::getItemsAssociatedTo(ConsumableItem::getType(), $this->fields[ConsumableItem::getForeignKeyField()]); if (count($infocoms)) { $infocom = reset($infocoms); @@ -124,7 +118,6 @@ public function post_addItem() parent::post_addItem(); } - /** * send back to stock * @@ -139,7 +132,7 @@ public function backToStock(array $input, $history = true) global $DB; $result = $DB->update( - $this->getTable(), + static::getTable(), [ 'date_out' => 'NULL' ], @@ -153,10 +146,8 @@ public function backToStock(array $input, $history = true) return false; } - public function getPreAdditionalInfosForName() { - $ci = new ConsumableItem(); if ($ci->getFromDB($this->fields['consumableitems_id'])) { return $ci->getName(); @@ -164,7 +155,6 @@ public function getPreAdditionalInfosForName() return ''; } - /** * UnLink a consumable linked to a printer * @@ -186,7 +176,7 @@ public function out($ID, $itemtype = '', $items_id = 0) && ($items_id > 0) ) { $result = $DB->update( - $this->getTable(), + static::getTable(), [ 'date_out' => date('Y-m-d'), 'itemtype' => $itemtype, @@ -210,7 +200,7 @@ public static function getMassiveActionsForItemtype( CommonDBTM $checkitem = null ) { // Special actions only for self - if ($itemtype != self::getType()) { + if ($itemtype !== static::class) { return; } @@ -257,7 +247,6 @@ public static function showMassiveActionsSubForm(MassiveAction $ma) return parent::showMassiveActionsSubForm($ma); } - public static function processMassiveActionsForOneItemtype( MassiveAction $ma, CommonDBTM $item, @@ -269,13 +258,13 @@ public static function processMassiveActionsForOneItemtype( foreach ($ids as $id) { if ($item->can($id, UPDATE)) { if ($item->backToStock(["id" => $id])) { - $ma->itemDone($item->getType(), $id, MassiveAction::ACTION_OK); + $ma->itemDone($item::class, $id, MassiveAction::ACTION_OK); } else { - $ma->itemDone($item->getType(), $id, MassiveAction::ACTION_KO); + $ma->itemDone($item::class, $id, MassiveAction::ACTION_KO); $ma->addMessage($item->getErrorMessage(ERROR_ON_ACTION)); } } else { - $ma->itemDone($item->getType(), $id, MassiveAction::ACTION_NORIGHT); + $ma->itemDone($item::class, $id, MassiveAction::ACTION_NORIGHT); $ma->addMessage($item->getErrorMessage(ERROR_RIGHT)); } } @@ -289,13 +278,13 @@ public static function processMassiveActionsForOneItemtype( foreach ($ids as $key) { if ($item->can($key, UPDATE)) { if ($item->out($key, $input['give_itemtype'], $input["give_items_id"])) { - $ma->itemDone($item->getType(), $key, MassiveAction::ACTION_OK); + $ma->itemDone($item::class, $key, MassiveAction::ACTION_OK); } else { - $ma->itemDone($item->getType(), $key, MassiveAction::ACTION_KO); + $ma->itemDone($item::class, $key, MassiveAction::ACTION_KO); $ma->addMessage($item->getErrorMessage(ERROR_ON_ACTION)); } } else { - $ma->itemDone($item->getType(), $key, MassiveAction::ACTION_NORIGHT); + $ma->itemDone($item::class, $key, MassiveAction::ACTION_NORIGHT); $ma->addMessage($item->getErrorMessage(ERROR_RIGHT)); } } @@ -308,14 +297,13 @@ public static function processMassiveActionsForOneItemtype( sprintf(__('%s gives a consumable'), $_SESSION["glpiname"]) ); } else { - $ma->itemDone($item->getType(), $ids, MassiveAction::ACTION_KO); + $ma->itemDone($item::class, $ids, MassiveAction::ACTION_KO); } return; } parent::processMassiveActionsForOneItemtype($ma, $item, $ids); } - /** * count how many consumable for the consumable item $tID * @@ -336,7 +324,6 @@ public static function getTotalNumber($tID) return (int)$result['cpt']; } - /** * count how many old consumable for the consumable item $tID * @@ -360,7 +347,6 @@ public static function getOldNumber($tID) return (int)$result['cpt']; } - /** * count how many consumable unused for the consumable item $tID * @@ -444,11 +430,10 @@ public static function getAlarmThreshold(int $tID): int **/ public static function getCount($tID, $alarm_threshold, $nohtml = false) { - - // Get total + // Get total $total = self::getTotalNumber($tID); - if ($total != 0) { + if ($total !== 0) { $unused = self::getUnusedNumber($tID); $old = self::getOldNumber($tID); @@ -461,19 +446,18 @@ public static function getCount($tID, $alarm_threshold, $nohtml = false) if ($nohtml) { $out = $tmptxt; } else { - $out = "
" . $tmptxt . "
"; + $out = "
" . htmlspecialchars($tmptxt) . "
"; } } else { if ($nohtml) { $out = __('No consumable'); } else { - $out = "
" . __('No consumable') . "
"; + $out = "
" . __s('No consumable') . "
"; } } return $out; } - /** * Check if a Consumable is New (not used, in stock) * @@ -494,10 +478,9 @@ public static function isNew($cID) 'date_out' => null ] ])->current(); - return $result['cpt'] == 1; + return $result['cpt'] === 1; } - /** * Check if a consumable is Old (used, not in stock) * @@ -518,10 +501,9 @@ public static function isOld($cID) 'NOT' => ['date_out' => null] ] ])->current(); - return $result['cpt'] == 1; + return $result['cpt'] === 1; } - /** * Get the localized string for the status of a consumable * @@ -531,7 +513,6 @@ public static function isOld($cID) **/ public static function getStatus($cID) { - if (self::isNew($cID)) { return _nx('consumable', 'New', 'New', 1); } else if (self::isOld($cID)) { @@ -540,195 +521,6 @@ public static function getStatus($cID) return ''; } - - /** - * Print out a link to add directly a new consumable from a consumable item. - * - * @param ConsumableItem $consitem - * - * @return void - **/ - public static function showAddForm(ConsumableItem $consitem) - { - Toolbox::deprecated('Replaced by Consumable::displayConsumableList()'); - - $ID = $consitem->getField('id'); - - if (!$consitem->can($ID, UPDATE)) { - return; - } - - if ($ID > 0) { - echo "
"; - echo "
"; - echo ""; - echo ""; - echo "
"; - echo "\n"; - Dropdown::showNumber('to_add', ['value' => 1, - 'min' => 1, - 'max' => 100 - ]); - echo " "; - echo "
"; - Html::closeForm(); - echo "
"; - } - } - - - /** - * Print out the consumables of a defined type - * - * @param ConsumableItem $consitem - * @param boolean $show_old show old consumables or not. (default 0) - * - * @return void - **/ - public static function showForConsumableItem(ConsumableItem $consitem, $show_old = false) - { - /** @var \DBmysql $DB */ - global $DB; - - Toolbox::deprecated("Replaced by Consumable::displayConsumableList()"); - - $tID = $consitem->getField('id'); - if (!$consitem->can($tID, READ)) { - return; - } - - if (isset($_GET["start"])) { - $start = $_GET["start"]; - } else { - $start = 0; - } - - $canedit = $consitem->can($tID, UPDATE); - $rand = mt_rand(); - $where = ['consumableitems_id' => $tID]; - $order = ['date_in', 'id']; - if (!$show_old) { // NEW - $where += ['date_out' => 'NULL']; - } else { //OLD - $where += ['NOT' => ['date_out' => 'NULL']]; - $order = ['date_out DESC'] + $order; - } - - $number = countElementsInTable("glpi_consumables", $where); - - $iterator = $DB->request([ - 'FROM' => self::getTable(), - 'WHERE' => $where, - 'ORDER' => $order, - 'START' => (int)$start, - 'LIMIT' => (int)$_SESSION['glpilist_limit'] - ]); - - echo "
"; - - // Display the pager - Html::printAjaxPager(Consumable::getTypeName(Session::getPluralNumber()), $start, $number); - - if ($canedit && $number) { - Html::openMassiveActionsForm('mass' . __CLASS__ . $rand); - $actions = []; - if ($consitem->can($tID, PURGE)) { - $actions['delete'] = _x('button', 'Delete permanently'); - } - $actions['Infocom' . MassiveAction::CLASS_ACTION_SEPARATOR . 'activate'] - = __('Enable the financial and administrative information'); - - if ($show_old) { - $actions['Consumable' . MassiveAction::CLASS_ACTION_SEPARATOR . 'backtostock'] - = __('Back to stock'); - } else { - $actions[__CLASS__ . MassiveAction::CLASS_ACTION_SEPARATOR . 'give'] = _x('button', 'Give'); - } - $entparam = ['entities_id' => $consitem->getEntityID()]; - if ($consitem->isRecursive()) { - $entparam = ['entities_id' => getSonsOf('glpi_entities', $consitem->getEntityID())]; - } - $massiveactionparams = ['num_displayed' => min($_SESSION['glpilist_limit'], $number), - 'specific_actions' => $actions, - 'container' => 'mass' . __CLASS__ . $rand, - 'extraparams' => $entparam - ]; - Html::showMassiveActions($massiveactionparams); - echo "\n"; - } - - echo ""; - if (!$show_old) { - echo ""; - } else { // Old - echo ""; - } - - if ($number) { - $header_begin = ""; - $header_top = ''; - $header_bottom = ''; - $header_end = ''; - if ($canedit) { - $header_begin .= ""; - } - $header_end .= ""; - $header_end .= ""; - $header_end .= ""; - if ($show_old) { - $header_end .= ""; - $header_end .= ""; - } - $header_end .= ""; - $header_end .= ""; - echo $header_begin . $header_top . $header_end; - - foreach ($iterator as $data) { - $date_in = Html::convDate($data["date_in"]); - $date_out = Html::convDate($data["date_out"]); - - echo ""; - if ($canedit) { - echo ""; - } - echo ""; - echo ""; - echo ""; - if ($show_old) { - echo ""; - echo ""; - } - echo ""; - echo ""; - } - echo $header_begin . $header_bottom . $header_end; - } - echo "
"; - echo self::getCount($tID, -1); - echo "
" . __('Used consumables') . "
"; - $header_top .= Html::getCheckAllAsCheckbox('mass' . __CLASS__ . $rand); - $header_bottom .= Html::getCheckAllAsCheckbox('mass' . __CLASS__ . $rand); - $header_end .= "" . __('ID') . "" . _x('item', 'State') . "" . __('Add date') . "" . __('Use date') . "" . __('Given to') . "" . __('Financial and administrative information') . "
"; - Html::showMassiveActionCheckBox(__CLASS__, $data["id"]); - echo "" . $data["id"] . "" . self::getStatus($data["id"]) . "" . $date_in . "" . $date_out . ""; - if ($item = getItemForItemtype($data['itemtype'])) { - if ($item->getFromDB($data['items_id'])) { - echo $item->getLink(); - } - } - echo ""; - Infocom::showDisplayLink('Consumable', $data["id"]); - echo "
"; - if ($canedit && $number) { - $massiveactionparams['ontop'] = false; - Html::showMassiveActions($massiveactionparams); - Html::closeForm(); - } - - echo "
"; - } - /** * Display a consumable list for a given consumable item * @@ -776,7 +568,7 @@ public static function displayConsumableList(ConsumableItem $parent): void $twig->display('pages/assets/consumable_list.html.twig', [ 'item' => new self(), 'parent' => $parent, - 'itemtype' => self::getType(), + 'itemtype' => self::class, 'can_edit' => $parent->canUpdate() && $parent->canUpdateItem(), 'criteria_unused' => $criteria_unused, 'criteria_used' => $criteria_used, @@ -784,15 +576,16 @@ public static function displayConsumableList(ConsumableItem $parent): void 'count_used' => $count_used, ]); } + public static function showForUser(User $user) { /** @var \DBmysql $DB */ global $DB; - $itemtype = $user->getType(); + $itemtype = $user::class; $items_id = $user->getField('id'); - $start = intval($_GET["start"] ?? 0); + $start = (int) ($_GET["start"] ?? 0); $sort = $_GET["sort"] ?? ""; $order = strtoupper($_GET["order"] ?? ""); $filters = $_GET['filters'] ?? []; @@ -884,7 +677,6 @@ public static function showForUser(User $user) ]); } - /** * Show the usage summary of consumables by user * @@ -895,7 +687,7 @@ public static function showSummary() /** @var \DBmysql $DB */ global $DB; - if (!Consumable::canView()) { + if (!self::canView()) { return; } @@ -920,8 +712,7 @@ public static function showSummary() $used = []; foreach ($iterator as $data) { - $used[$data['itemtype'] . '####' . $data['items_id']][$data["consumableitems_id"]] - = $data["count"]; + $used[$data['itemtype'] . '####' . $data['items_id']][$data["consumableitems_id"]] = $data["count"]; } $iterator = $DB->request([ @@ -950,6 +741,11 @@ public static function showSummary() 'FROM' => 'glpi_consumableitems', 'WHERE' => getEntitiesRestrictCriteria('glpi_consumableitems') ]); + $columns = [ + 'give_to' => __('Give to') + ]; + $formatters = []; + $entries = []; $types = []; foreach ($iterator as $data) { @@ -957,93 +753,91 @@ public static function showSummary() } asort($types); - $total = []; - if (count($types) > 0) { - // Produce headline - echo "
"; - - // Type - echo ""; + foreach ($types as $key => $type) { + $columns[$key] = $type; + $formatters[$key] = 'integer'; + } + $columns['total'] = __('Total'); + $formatters['total'] = 'integer'; - foreach ($types as $key => $type) { - echo ""; - $total[$key] = 0; + $new_entry = [ + 'give_to' => __('In stock'), + 'total' => 0 + ]; + foreach ($types as $id_type => $type) { + if (!isset($new[$id_type])) { + $new[$id_type] = 0; } - echo ""; - echo ""; + $new_entry[$id_type] = $new[$id_type]; + $new_entry['total'] += $new[$id_type]; + } + $entries[] = $new_entry; + + foreach ($used as $itemtype_items_id => $val) { + [$itemtype, $items_id] = explode('####', $itemtype_items_id); + $item = new $itemtype(); + $item_name = ''; + if ($item->getFromDB($items_id)) { + //TRANS: %1$s is a type name - %2$s is a name + $item_name = sprintf(__('%1$s - %2$s'), $item->getTypeName(1), $item->getNameID()); + } + $entry = [ + 'give_to' => $item_name, + 'total' => 0 + ]; - // new - echo ""; - $tot = 0; foreach ($types as $id_type => $type) { - if (!isset($new[$id_type])) { - $new[$id_type] = 0; - } - echo ""; - $total[$id_type] += $new[$id_type]; - $tot += $new[$id_type]; - } - echo ""; - echo ""; - - foreach ($used as $itemtype_items_id => $val) { - echo ""; - $tot = 0; - foreach ($types as $id_type => $type) { - if (!isset($val[$id_type])) { - $val[$id_type] = 0; - } - echo ""; - $total[$id_type] += $val[$id_type]; - $tot += $val[$id_type]; + if (!isset($val[$id_type])) { + $val[$id_type] = 0; } - echo ""; - echo ""; + $entry[$id_type] = $val[$id_type]; + $entry['total'] += $val[$id_type]; } - echo ""; - $tot = 0; - foreach ($types as $id_type => $type) { - $tot += $total[$id_type]; - echo ""; - } - echo ""; - echo ""; - echo "
" . __('Give to') . "$type" . __('Total') . "
" . __('In stock') . "" . $new[$id_type] . "" . $tot . "
"; - list($itemtype,$items_id) = explode('####', $itemtype_items_id); - $item = new $itemtype(); - if ($item->getFromDB($items_id)) { - //TRANS: %1$s is a type name - %2$s is a name - printf(__('%1$s - %2$s'), $item->getTypeName(1), $item->getNameID()); - } - echo "" . $val[$id_type] . "" . $tot . "
" . __('Total') . "" . $total[$id_type] . "" . $tot . "
"; - } else { - echo "
" . __('No consumable found') . "
"; + $entries[] = $entry; } - } + $footer = [__('Total')]; + foreach ($types as $id_type => $type) { + $footer[] = array_sum(array_column($entries, $id_type)); + } + $footer[] = array_sum(array_column($entries, 'total')); + + TemplateRenderer::getInstance()->display('components/datatable.html.twig', [ + 'is_tab' => true, + 'nopager' => true, + 'nofilter' => true, + 'nosort' => true, + 'columns' => $columns, + 'formatters' => $formatters, + 'entries' => $entries, + 'footers' => [$footer], + 'footer_class' => 'fw-bold', + 'total_number' => count($entries), + 'filtered_number' => count($entries), + 'showmassiveactions' => false + ]); + } public function getTabNameForItem(CommonGLPI $item, $withtemplate = 0) { - - if (!$withtemplate && Consumable::canView()) { + if (!$withtemplate && self::canView()) { $nb = 0; - switch ($item->getType()) { - case 'ConsumableItem': + switch ($item::class) { + case ConsumableItem::class: if ($_SESSION['glpishow_count_on_tabs']) { $nb = self::countForConsumableItem($item); } - return self::createTabEntry(self::getTypeName(Session::getPluralNumber()), $nb, $item::getType()); - case 'User': + return self::createTabEntry(self::getTypeName(Session::getPluralNumber()), $nb, $item::class); + case User::class: if ($_SESSION['glpishow_count_on_tabs']) { $nb = self::countForUser($item); } - return self::createTabEntry(self::getTypeName(Session::getPluralNumber()), $nb, $item::getType()); + return self::createTabEntry(self::getTypeName(Session::getPluralNumber()), $nb, $item::class); } } return ''; } - /** * @param ConsumableItem $item * @@ -1051,11 +845,9 @@ public function getTabNameForItem(CommonGLPI $item, $withtemplate = 0) **/ public static function countForConsumableItem(ConsumableItem $item) { - return countElementsInTable(['glpi_consumables'], ['glpi_consumables.consumableitems_id' => $item->getField('id')]); } - /** * @param User $item * @@ -1063,7 +855,6 @@ public static function countForConsumableItem(ConsumableItem $item) **/ public static function countForUser(User $item) { - return countElementsInTable(['glpi_consumables'], [ 'glpi_consumables.itemtype' => 'User', 'glpi_consumables.items_id' => $item->getField('id'), @@ -1071,15 +862,13 @@ public static function countForUser(User $item) ]); } - public static function displayTabContentForItem(CommonGLPI $item, $tabnum = 1, $withtemplate = 0) { - - switch ($item->getType()) { - case 'ConsumableItem': + switch ($item::class) { + case ConsumableItem::class: self::displayConsumableList($item); break; - case 'User': + case User::class: self::showForUser($item); break; } @@ -1091,7 +880,6 @@ public function getRights($interface = 'central') return (new ConsumableItem())->getRights($interface); } - public static function getIcon() { return "ti ti-package"; @@ -1109,7 +897,7 @@ public static function convertFiltersValuesToSqlCriteria(array $filters = []): a 'date_out' => 'glpi_consumables.date_out', ]; foreach ($like_filters as $filter_key => $filter_field) { - if (strlen(($filters[$filter_key] ?? ""))) { + if (($filters[$filter_key] ?? "") !== '') { $sql_filters[$filter_field] = ['LIKE', '%' . $filters[$filter_key] . '%']; } } @@ -1123,7 +911,7 @@ public function rawSearchOptions() $options[] = [ 'id' => '2', - 'table' => $this->getTable(), + 'table' => static::getTable(), 'field' => 'id', 'name' => __('ID'), 'massiveaction' => false, @@ -1132,7 +920,7 @@ public function rawSearchOptions() $options[] = [ 'id' => '3', - 'table' => $this->getTable(), + 'table' => static::getTable(), 'field' => 'date_out', 'name' => _n('State', 'States', 1), 'massiveaction' => false, @@ -1142,7 +930,7 @@ public function rawSearchOptions() $options[] = [ 'id' => '4', - 'table' => $this->getTable(), + 'table' => static::getTable(), 'field' => 'date_in', 'name' => __('Add date'), 'massiveaction' => false, @@ -1151,7 +939,7 @@ public function rawSearchOptions() $options[] = [ 'id' => '5', - 'table' => $this->getTable(), + 'table' => static::getTable(), 'field' => 'date_out', 'name' => __('Use date'), 'massiveaction' => false, @@ -1160,7 +948,7 @@ public function rawSearchOptions() $options[] = [ 'id' => '6', - 'table' => $this->getTable(), + 'table' => static::getTable(), 'field' => 'items_id', 'name' => __('Given to'), 'massiveaction' => false, @@ -1172,7 +960,7 @@ public function rawSearchOptions() $infocom_label = Infocom::getTypeName(); $options[] = [ 'id' => '7', - 'table' => $this->getTable(), + 'table' => static::getTable(), 'field' => 'id', 'name' => $infocom_label, 'massiveaction' => false, @@ -1220,7 +1008,7 @@ public static function getSpecificValueToDisplay( case '7': // Infocom shortcut $id = $values['id']; ob_start(); - Infocom::showDisplayLink(Consumable::getType(), $id); + Infocom::showDisplayLink(self::class, $id); return ob_get_clean(); } diff --git a/src/ConsumableItem.php b/src/ConsumableItem.php index d1e49d53c2b..95f610a1a97 100644 --- a/src/ConsumableItem.php +++ b/src/ConsumableItem.php @@ -69,26 +69,21 @@ public static function getTypeName($nb = 0) return _n('Consumable model', 'Consumable models', $nb); } - public static function getMenuName() { return Consumable::getTypeName(Session::getPluralNumber()); } - public static function getAdditionalMenuLinks() { - if (static::canView()) { return ['summary' => '/front/consumableitem.php?synthese=yes']; } return false; } - public function getPostAdditionalInfosForName() { - if (isset($this->fields["ref"]) && !empty($this->fields["ref"])) { return $this->fields["ref"]; } @@ -109,22 +104,19 @@ public function prepareInputForUpdate($input) public function cleanDBonPurge() { - $this->deleteChildrenAndRelationsFromDb( [ Consumable::class, ] ); - // Alert does not extends CommonDBConnexity + // Alert does not extends CommonDBConnexity $alert = new Alert(); - $alert->cleanDBonItemDelete($this->getType(), $this->fields['id']); + $alert->cleanDBonItemDelete(static::class, $this->fields['id']); } - public function post_getEmpty() { - if (isset($_SESSION['glpiactive_entity'])) { $this->fields["alarm_threshold"] = Entity::getUsedConfig( "consumables_alert_repeat", @@ -135,10 +127,8 @@ public function post_getEmpty() } } - public function defineTabs($options = []) { - $ong = []; $this->addDefaultFormTab($ong); $this->addStandardTab('Consumable', $ong, $options); @@ -151,14 +141,13 @@ public function defineTabs($options = []) return $ong; } - public function rawSearchOptions() { $tab = parent::rawSearchOptions(); $tab[] = [ 'id' => '2', - 'table' => $this->getTable(), + 'table' => static::getTable(), 'field' => 'id', 'name' => __('ID'), 'datatype' => 'number', @@ -167,7 +156,7 @@ public function rawSearchOptions() $tab[] = [ 'id' => '34', - 'table' => $this->getTable(), + 'table' => static::getTable(), 'field' => 'ref', 'name' => __('Reference'), 'datatype' => 'string', @@ -175,7 +164,7 @@ public function rawSearchOptions() $tab[] = [ 'id' => '6', - 'table' => $this->getTable(), + 'table' => static::getTable(), 'field' => 'otherserial', 'name' => __('Inventory number'), 'datatype' => 'string', @@ -199,7 +188,7 @@ public function rawSearchOptions() $tab[] = [ 'id' => '9', - 'table' => $this->getTable(), + 'table' => static::getTable(), 'field' => '_virtual', 'linkfield' => '_virtual', 'name' => _n('Consumable', 'Consumables', Session::getPluralNumber()), @@ -264,7 +253,7 @@ public function rawSearchOptions() $tab[] = [ 'id' => '8', - 'table' => $this->getTable(), + 'table' => static::getTable(), 'field' => 'alarm_threshold', 'name' => __('Alert threshold'), 'datatype' => 'number', @@ -275,7 +264,7 @@ public function rawSearchOptions() $tab[] = [ 'id' => '16', - 'table' => $this->getTable(), + 'table' => static::getTable(), 'field' => 'comment', 'name' => __('Comments'), 'datatype' => 'text' @@ -295,19 +284,18 @@ public function rawSearchOptions() return $tab; } - public static function cronInfo($name) { return ['description' => __('Send alarms on consumables')]; } - /** * Cron action on consumables : alert if a stock is behind the threshold * * @param CronTask|null $task to log, if NULL display (default NULL) * * @return integer 0 : nothing to do 1 : done with success + * @used-by CronTask **/ public static function cronConsumable(CronTask $task = null) { @@ -320,8 +308,6 @@ public static function cronConsumable(CronTask $task = null) $cron_status = 1; if ($CFG_GLPI["use_notifications"]) { - $message = []; - $items = []; $alert = new Alert(); foreach (Entity::getEntitiesToNotify('consumables_alert_repeat') as $entity => $repeat) { @@ -336,7 +322,7 @@ public static function cronConsumable(CronTask $task = null) 'glpi_alerts.id AS alertID', 'glpi_alerts.date', ], - 'FROM' => ConsumableItem::getTable(), + 'FROM' => self::getTable(), 'LEFT JOIN' => [ 'glpi_alerts' => [ 'FKEY' => [ @@ -376,8 +362,8 @@ public static function cronConsumable(CronTask $task = null) ($unused = Consumable::getUnusedNumber($consumable["consID"])) <= $consumable["threshold"] ) { - // define message alert - //TRANS: %1$s is the consumable name, %2$s its reference, %3$d the remaining number + // define message alert + //TRANS: %1$s is the consumable name, %2$s its reference, %3$d the remaining number $message .= sprintf( __('Threshold of alarm reached for the type of consumable: %1$s - Reference %2$s - Remaining %3$d'), $consumable['name'], @@ -409,11 +395,10 @@ public static function cronConsumable(CronTask $task = null) ) . " : $message\n"); $task->addVolume(1); } else { - Session::addMessageAfterRedirect(Dropdown::getDropdownName( + Session::addMessageAfterRedirect(htmlspecialchars(Dropdown::getDropdownName( "glpi_entities", $entity - ) . - " : $message"); + ) . " : $message")); } $input = [ @@ -421,7 +406,7 @@ public static function cronConsumable(CronTask $task = null) 'itemtype' => 'ConsumableItem', ]; - // add alerts + // add alerts foreach ($items as $ID => $consumable) { $input["items_id"] = $ID; $alert->add($input); @@ -429,12 +414,12 @@ public static function cronConsumable(CronTask $task = null) } } else { $entityname = Dropdown::getDropdownName('glpi_entities', $entity); - //TRANS: %s is entity name + //TRANS: %s is entity name $msg = sprintf(__('%s: send consumable alert failed'), $entityname); if ($task) { $task->log($msg); } else { - Session::addMessageAfterRedirect($msg, false, ERROR); + Session::addMessageAfterRedirect(htmlspecialchars($msg), false, ERROR); } } } @@ -443,20 +428,17 @@ public static function cronConsumable(CronTask $task = null) return $cron_status; } - public function getEvents() { return ['alert' => __('Send alarms on consumables')]; } - /** * Display debug information for current object **/ public function showDebug() { - - // see query_alert in cronConsumable() + // see query_alert in cronConsumable() $item = ['consID' => $this->fields['id'], 'entity' => $this->fields['entities_id'], 'ref' => $this->fields['ref'], diff --git a/src/Infocom.php b/src/Infocom.php index 6e8c9e9583e..06622bf8cca 100644 --- a/src/Infocom.php +++ b/src/Infocom.php @@ -766,12 +766,14 @@ public static function showTco($ticket_tco, $value, $date_achat = "") /** * Show infocom link to display modal * - * @param $itemtype integer item type - * @param $device_id integer item ID + * @param integer $itemtype item type + * @param integer $device_id item ID + * @param boolean $display display or not the link (default true) * - * @return void + * @return void|string + * @phpstan-return $display ? void : string **/ - public static function showDisplayLink($itemtype, $device_id) + public static function showDisplayLink($itemtype, $device_id, bool $display = true) { /** * @var array $CFG_GLPI @@ -804,8 +806,9 @@ public static function showDisplayLink($itemtype, $device_id) return; } + $out = ''; if ($item->canView()) { - echo " + $out .= " \"$text\" "; $form_url = Infocom::getFormURL(); @@ -842,7 +845,12 @@ public static function showDisplayLink($itemtype, $device_id) } }); JS; - echo Html::scriptBlock($js); + $out .= Html::scriptBlock($js); + } + if ($display) { + echo $out; + } else { + return $out; } } diff --git a/src/Printer_CartridgeInfo.php b/src/Printer_CartridgeInfo.php index a68240944f3..943b98977bc 100644 --- a/src/Printer_CartridgeInfo.php +++ b/src/Printer_CartridgeInfo.php @@ -52,7 +52,7 @@ public function getInfoForPrinter(Printer $printer) global $DB; $iterator = $DB->request([ - 'FROM' => $this->getTable(), + 'FROM' => static::getTable(), 'WHERE' => [ self::$items_id => $printer->fields['id'] ] @@ -70,13 +70,9 @@ public function showForPrinter(Printer $printer) { $info = $this->getInfoForPrinter($printer); - echo "

" . $this->getTypeName(Session::getPluralNumber()) . "

"; - - echo ""; - echo ""; - $asset = new Glpi\Inventory\Asset\Cartridge($printer); $tags = $asset->knownTags(); + $entries = []; foreach ($info as $row) { $property = $row['property']; @@ -84,18 +80,15 @@ public function showForPrinter(Printer $printer) preg_match("/^toner(\w+.*$)/", $property, $matches); $bar_color = $matches[1] ?? 'green'; - $text_color = ($bar_color == "black") ? 'white' : 'black'; + $text_color = ($bar_color === "black") ? 'white' : 'black'; - echo ""; - echo sprintf("", $tags[$property]['name'] ?? $property); - - if (strstr($value, 'pages')) { + if (str_contains($value, 'pages')) { $pages = str_replace('pages', '', $value); $value = sprintf( _x('%1$s remaining page', '%1$s remaining pages', $pages), $pages ); - } else if ($value == 'OK') { + } else if ($value === 'OK') { $value = __('OK'); } @@ -127,11 +120,32 @@ public function showForPrinter(Printer $printer) } else { $out = $value; } - echo sprintf("", $out); + $entries[] = [ + 'property' => $tags[$property]['name'] ?? $property, + 'value' => $out + ]; + } - echo ""; + if (count($entries)) { + TemplateRenderer::getInstance()->display('components/datatable.html.twig', [ + 'is_tab' => true, + 'nopager' => true, + 'nofilter' => true, + 'nosort' => true, + 'super_header' => self::getTypeName(Session::getPluralNumber()), + 'columns' => [ + 'property' => __('Property'), + 'value' => __('Value') + ], + 'formatters' => [ + 'value' => 'raw_html' + ], + 'entries' => $entries, + 'total_number' => count($entries), + 'filtered_number' => count($entries), + 'showmassiveactions' => false + ]); } - echo "
" . __('Property') . "" . __('Value') . "
%s%s
"; } public static function rawSearchOptionsToAdd() @@ -192,8 +206,9 @@ public static function getSpecificValueToSelect($field, $name = '', $values = '' * * @param array $data * @param string $type + * @return string|null */ - private static function createCartridgeInformationBadge($data, $type): ?string + private static function createCartridgeInformationBadge(array $data, string $type): ?string { $color_aliases = [ 'magenta' => 'purple', @@ -205,24 +220,19 @@ private static function createCartridgeInformationBadge($data, $type): ?string 'yellow' => __('Yellow'), ]; - if ( - is_array($data) - && isset($data['property']) - && isset($data['value']) - && str_starts_with($data['property'], $type) - ) { + if (isset($data['property'], $data['value']) && is_array($data) && str_starts_with($data['property'], $type)) { $color = str_replace($type, '', $data['property']); - $templateContent = << - {{ color_translated }} : {{ status }} -
-TWIG; - - return TemplateRenderer::getInstance()->renderFromStringTemplate($templateContent, [ + $twig_params = [ 'color_translated' => $color_translations[$color] ?? ucwords($color), 'color' => $color_aliases[$color] ?? $color, 'status' => is_numeric($data['value']) ? $data['value'] . '%' : $data['value'] - ]); + ]; + // language=Twig + return TemplateRenderer::getInstance()->renderFromStringTemplate(<< + {{ color_translated }} : {{ status }} + +TWIG, $twig_params); } return null; @@ -234,24 +244,21 @@ public static function getSpecificValueToDisplay($field, $values, array $options if (str_starts_with($field, '_virtual_')) { $type = preg_match('/_virtual_(.*)_percent/', $field, $matches) ? $matches[1] : ''; $badges = array_filter(array_map( - function ($data) use ($type) { + static function ($data) use ($type) { return self::createCartridgeInformationBadge($data, $type); }, $options['raw_data']['Printer_' . $printer->getSearchOptionIDByField('field', $field)] )); if ($badges) { - $templateContent = <<renderFromStringTemplate(<< {% for badge in badges %} {{ badge|raw }} {% endfor %} -TWIG; - - return TemplateRenderer::getInstance()->renderFromStringTemplate($templateContent, [ - 'badges' => $badges - ]); +TWIG, ['badges' => $badges]); } } diff --git a/templates/components/datatable.html.twig b/templates/components/datatable.html.twig index b0944009f1b..df28e98ae81 100644 --- a/templates/components/datatable.html.twig +++ b/templates/components/datatable.html.twig @@ -293,7 +293,7 @@ {% endif %} {% for footer_col, footerval in footer %} - {{ footerval }} + {{ footerval|nl2br }} {% endfor %} {% if nofilter is not defined %} diff --git a/templates/pages/assets/cartridge.html.twig b/templates/pages/assets/cartridge.html.twig new file mode 100644 index 00000000000..ebaab0988bb --- /dev/null +++ b/templates/pages/assets/cartridge.html.twig @@ -0,0 +1,62 @@ +{# + # --------------------------------------------------------------------- + # + # GLPI - Gestionnaire Libre de Parc Informatique + # + # http://glpi-project.org + # + # @copyright 2015-2024 Teclib' and contributors. + # @copyright 2003-2014 by the INDEPNET Development Team. + # @licence https://www.gnu.org/licenses/gpl-3.0.html + # + # --------------------------------------------------------------------- + # + # LICENSE + # + # This file is part of GLPI. + # + # This program is free software: you can redistribute it and/or modify + # it under the terms of the GNU General Public License as published by + # the Free Software Foundation, either version 3 of the License, or + # (at your option) any later version. + # + # This program is distributed in the hope that it will be useful, + # but WITHOUT ANY WARRANTY; without even the implied warranty of + # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + # GNU General Public License for more details. + # + # You should have received a copy of the GNU General Public License + # along with this program. If not, see . + # + # --------------------------------------------------------------------- + #} + +{% extends 'generic_show_form.html.twig' %} +{% import 'components/form/fields_macros.html.twig' as fields %} + +{% block form_fields %} + + + {{ fields.htmlField('', printer.getLink(), 'Printer'|itemtype_name) }} + {{ fields.htmlField('', model.getLink(), _n('Cartridge model', 'Cartridge models', 1)) }} + + {{ fields.htmlField('', item.fields['date_in']|formatted_date|e, __('Add date')) }} + {% if item.fields['date_use'] is not empty and item.fields['date_out'] is empty %} + {{ fields.dateField('date_use', item.fields['date_use'], __('Use date'), { + maybeempty: false, + canedit: true, + min: item.fields['date_in'], + }) }} + {% else %} + {{ fields.htmlField('', item.fields['date_use']|formatted_date|e, __('Use date')) }} + {% endif %} + + {% if item.fields['date_out'] is not empty %} + {{ fields.dateField('date_out', item.fields['date_out'], __('End date'), { + maybeempty: false, + canedit: true, + min: item.fields['date_use'], + }) }} + {{ fields.numberField('pages', item.fields['pages'], __('Printer counter')) }} + {% endif %} +{% endblock %} diff --git a/templates/pages/assets/consumable_list.html.twig b/templates/pages/assets/consumable_list.html.twig index 206ece250cc..51666e3f18d 100644 --- a/templates/pages/assets/consumable_list.html.twig +++ b/templates/pages/assets/consumable_list.html.twig @@ -64,40 +64,41 @@ } ) }} - {% if can_edit %} - - {{ fields.numberField( - 'to_add', - 1, - '', - { - min: 1, - step: 1, - field_class: 'col-12 col-sm-2', - label_class: 'col-xxl-5', - } - ) }} + {% if can_edit %} + + {{ fields.numberField( + 'to_add', + 1, + '', + { + min: 1, + step: 1, + field_class: 'col-12 col-sm-2', + label_class: 'col-xxl-5', + } + ) }} - {% set add_several %} - - {% endset %} + {% set add_several %} + + {% endset %} - {{ fields.htmlField( - '', - add_several, - '', - { - field_class: 'col-12 col-sm-1', - label_class: 'col-xxl-1', - } - ) }} - - {% endif %} + {{ fields.htmlField( + '', + add_several, + '', + { + field_class: 'col-12 col-sm-1', + label_class: 'col-xxl-1', + } + ) }} + + {% endif %} +