Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/continuous-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
name: "Generate CI matrix"
uses: "glpi-project/plugin-ci-workflows/.github/workflows/generate-ci-matrix.yml@v1"
with:
glpi-version: "11.0.x"
glpi-version: "12.0.x"
ci:
name: "GLPI ${{ matrix.glpi-version }} - php:${{ matrix.php-version }} - ${{ matrix.db-image }}"
needs: "generate-ci-matrix"
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,16 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]

### Added

- GLPI 12 compatibility

### Fixed

- Fix flaky escalation test on solve/reject-solution data sets
- CI: fix Psalm cache directory, drop the stray `glpi-project/tools` composer dependency, declare a unique composer autoloader suffix
- Simplify group reassignment to a single actor diff, relying on GLPI core's status preservation on simultaneous actor removal/addition


## [2.10.8] 2026-09-11

Expand Down
10 changes: 4 additions & 6 deletions front/config.form.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,7 @@

Session::checkLoginUser();

if (! isset($_GET["id"])) {
$_GET["id"] = 0;
}
$_GET["id"] ??= 0;

if (!Plugin::isPluginActive('escalade')) {
echo "Plugin not installed or activated";
Expand All @@ -42,15 +40,15 @@
$config = new PluginEscaladeConfig();

if (isset($_POST["add"])) {
Session::checkRight("config", CREATE);
Session::checkRight(Config::$rightname, CREATE);
$newID = $config->add($_POST);
Html::back();
} elseif (isset($_POST["update"])) {
Session::checkRight("config", UPDATE);
Session::checkRight(Config::$rightname, UPDATE);
$config->update($_POST);
Html::back();
} elseif (isset($_POST["delete"])) {
Session::checkRight("config", DELETE);
Session::checkRight(Config::$rightname, DELETE);
$config->delete($_POST, true);
Html::redirect("./config.form.php");
} else {
Expand Down
2 changes: 1 addition & 1 deletion front/group_group.form.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@

Html::header("escalade", $_SERVER["PHP_SELF"], "plugins", "escalade", "group_group");

if (Session::haveRight('group', UPDATE)) {
if (Session::haveRight(Group::$rightname, UPDATE)) {
if (isset($_POST['addgroup'])) {
$group_source = new Group();
$group_destination = new Group();
Expand Down
8 changes: 2 additions & 6 deletions hook.php
Original file line number Diff line number Diff line change
Expand Up @@ -329,9 +329,7 @@ function plugin_escalade_install()
$tickets_id = $data['tickets_id'];
unset($data['tickets_id']);

if (!isset($histories[$tickets_id])) {
$histories[$tickets_id] = [];
}
$histories[$tickets_id] ??= [];

$histories[$tickets_id][] = $data;
}
Expand Down Expand Up @@ -525,9 +523,7 @@ function plugin_escalade_pre_item_add_group_ticket($item)
&& $item->input['type'] == CommonITILActor::ASSIGN
&& empty($item->input['_plugin_escalade_rules_only'])
) {
if (!isset($_SESSION['plugin_escalade']['current_group_assignment'])) {
$_SESSION['plugin_escalade']['current_group_assignment'] = [];
}
$_SESSION['plugin_escalade']['current_group_assignment'] ??= [];

$_SESSION['plugin_escalade']['current_group_assignment'][$item->input['tickets_id']] = [
'group_id' => $item->input['groups_id'],
Expand Down
2 changes: 1 addition & 1 deletion inc/config.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@

class PluginEscaladeConfig extends CommonDBTM
{
public static $rightname = 'config';
public static string $rightname = 'config';

public static function getMenuName()
{
Expand Down
12 changes: 6 additions & 6 deletions inc/group_group.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,13 @@
class PluginEscaladeGroup_Group extends CommonDBRelation
{
// From CommonDBRelation
public static $itemtype_1 = 'Group';
public static ?string $itemtype_1 = 'Group';

public static $items_id_1 = 'groups_id_source';
public static ?string $items_id_1 = 'groups_id_source';

public static $itemtype_2 = 'Group';
public static ?string $itemtype_2 = 'Group';

public static $items_id_2 = 'groups_id_destination';
public static ?string $items_id_2 = 'groups_id_destination';

public function getForbiddenStandardMassiveAction()
{
Expand Down Expand Up @@ -96,7 +96,7 @@ public function manageGroup($groups_id)
$gg_found = $this->find(['groups_id_source' => $groups_id]);
$nb = count($gg_found);

if (Session::haveRight('group', UPDATE)) {
if (Session::haveRight(Group::$rightname, UPDATE)) {
$groups_id_used = [];
foreach ($gg_found as $gg) {
$groups_id_used[] = $gg['groups_id_destination'];
Expand All @@ -123,7 +123,7 @@ public function manageGroup($groups_id)
}

TemplateRenderer::getInstance()->display('@escalade/group_group.html.twig', [
'canedit' => Session::haveRight('group', UPDATE),
'canedit' => Session::haveRight(Group::$rightname, UPDATE),
'group_id' => $groups_id,
'groups' => $groups,
'massiveactionparams' => $massiveactionparams ?? [],
Expand Down
18 changes: 9 additions & 9 deletions inc/history.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,19 +41,19 @@ public static function getFirstLineForTicket($tickets_id)
$found = self::getFullHistory($tickets_id);
if (count($found) === 0) {
return false;
} else {
return array_pop($found);
}

return array_pop($found);
}

public static function getlastLineForTicket($tickets_id)
{
$found = self::getFullHistory($tickets_id);
if (count($found) === 0) {
return false;
} else {
return array_shift($found);
}

return array_shift($found);
}

public static function getLastHistoryForTicketAndGroup($tickets_id, $groups_id, $previous_groups_id)
Expand Down Expand Up @@ -272,7 +272,7 @@ public static function getHistory($tickets_id, $full_history = false)
public static function showGroupLink($group, $full_history = false)
{

if (!$group->can($group->fields['id'], READ)) {
if (!Session::haveRight(Group::$rightname, READ)) {
return '';
}

Expand All @@ -287,7 +287,7 @@ public static function showGroupLink($group, $full_history = false)
echo sprintf(" onclick='self.opener.location.href=\"%s\"; self.close();'", $link);
}

echo ">" . $group->getNameID(true) . "</a>";
echo ">" . $group->getNameID() . "</a>";
return null;
}

Expand All @@ -304,9 +304,9 @@ public static function showCentralSpecificList($type)
global $CFG_GLPI, $DB;

if (
! Session::haveRight("ticket", Ticket::READALL)
&& ! Session::haveRight("ticket", Ticket::READASSIGN)
&& ! Session::haveRight("ticket", CREATE)
! Session::haveRight(Ticket::$rightname, Ticket::READALL)
&& ! Session::haveRight(Ticket::$rightname, Ticket::READASSIGN)
&& ! Session::haveRight(Ticket::$rightname, CREATE)
&& ! Session::haveRight("ticketvalidation", TicketValidation::VALIDATEREQUEST
& TicketValidation::VALIDATEINCIDENT)
) {
Expand Down
40 changes: 9 additions & 31 deletions inc/notification.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -169,34 +169,21 @@ public static function getActionTargets(NotificationTarget $target)
case self::NTRGT_TICKET_REQUESTER_GROUP: // phpcs:ignore
$group_type = CommonITILActor::REQUESTER;
// no break
case self::NTRGT_TICKET_WATCH_GROUP: // phpcs:ignore
if (!isset($group_type)) {
$group_type = CommonITILActor::OBSERVER;
}
case self::NTRGT_TICKET_WATCH_GROUP: $group_type ??= CommonITILActor::OBSERVER;
// no break
case self::NTRGT_TICKET_TECH_GROUP:
$manager = 0;

// manager of group's users
// no break
case self::NTRGT_TICKET_REQUESTER_GROUP_MANAGER: // phpcs:ignore
if (!isset($group_type)) {
$group_type = CommonITILActor::REQUESTER;
}
case self::NTRGT_TICKET_REQUESTER_GROUP_MANAGER: $group_type ??= CommonITILActor::REQUESTER;
// no break
case self::NTRGT_TICKET_WATCH_GROUP_MANAGER: // phpcs:ignore
if (!isset($group_type)) {
$group_type = CommonITILActor::OBSERVER;
}
case self::NTRGT_TICKET_WATCH_GROUP_MANAGER: $group_type ??= CommonITILActor::OBSERVER;
// no break
case self::NTRGT_TICKET_TECH_GROUP_MANAGER:
if (!isset($manager)) {
$manager = 1;
}
$manager ??= 1;

if (!isset($group_type)) {
$group_type = CommonITILActor::ASSIGN;
}
$group_type ??= CommonITILActor::ASSIGN;

self::addGroupsOfTicket($target, $ticket->getID(), $manager, $group_type);
break;
Expand All @@ -205,15 +192,10 @@ public static function getActionTargets(NotificationTarget $target)
case self::NTRGT_TICKET_REQUESTER_USER: // phpcs:ignore
$user_type = CommonITILActor::REQUESTER;
// no break
case self::NTRGT_TICKET_WATCH_USER: // phpcs:ignore
if (!isset($user_type)) {
$user_type = CommonITILActor::OBSERVER;
}
case self::NTRGT_TICKET_WATCH_USER: $user_type ??= CommonITILActor::OBSERVER;
// no break
case self::NTRGT_TICKET_TECH_USER:
if (!isset($user_type)) {
$user_type = CommonITILActor::ASSIGN;
}
$user_type ??= CommonITILActor::ASSIGN;

self::addUsersOfTicket($target, $ticket->getID(), $user_type);
break;
Expand All @@ -228,9 +210,7 @@ public static function getActionTargets(NotificationTarget $target)
$manager = 0;
// no break
case self::NTRGT_TICKET_ESCALADE_GROUP_MANAGER:
if (!isset($manager)) {
$manager = 1;
}
$manager ??= 1;

$history = new PluginEscaladeHistory();
foreach ($history->find(['tickets_id' => $ticket->getID()]) as $found_history) {
Expand All @@ -249,9 +229,7 @@ public static function getActionTargets(NotificationTarget $target)
$manager = 0;
// no break
case self::NTRGT_TICKET_LAST_ESCALADE_GROUP_MANAGER:
if (!isset($manager)) {
$manager = 1;
}
$manager ??= 1;

$group_to_notify = null;

Expand Down
2 changes: 1 addition & 1 deletion inc/taskmanager.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public static function setTicketTask(array $input): void
return;
}

if (!empty(self::$ticket_task->input)) {
if (self::$ticket_task->input !== [] && self::$ticket_task->input !== false) {
return;
}

Expand Down
25 changes: 6 additions & 19 deletions inc/ticket.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,7 @@ public static function addHistoryOnAddGroup(CommonDBTM $item)
$previous_groups_id = 0;
$counter = 0;

if (count($group_ticket->fields) > 0) {
if ($group_ticket->fields !== []) {
$previous_groups_id = $group_ticket->fields['groups_id'];

$last_history_groups = PluginEscaladeHistory::getLastHistoryForTicketAndGroup($tickets_id, $groups_id, $previous_groups_id);
Expand Down Expand Up @@ -551,24 +551,6 @@ public static function processAfterAddGroup(Group_Ticket $item)
if ($_SESSION['glpi_plugins']['escalade']['config']['remove_group'] == true) {
$all_actors = self::getTicketFieldsWithActors($tickets_id, $groups_id);

// Keep only the new group in the assign list (drop old ones).
$seen_new_group = false;
$all_actors['assign'] = array_values(array_filter(
$all_actors['assign'],
function (array $actor) use ($groups_id, &$seen_new_group): bool {
if ($actor['itemtype'] !== 'Group') {
return true;
}

if ($actor['items_id'] == $groups_id && !$seen_new_group) {
$seen_new_group = true;
return true;
}

return false;
},
));

$ticket_for_rules = new Ticket();
$ticket_for_rules->getFromDB($tickets_id);
$ticket_for_rules->update([
Expand Down Expand Up @@ -1279,6 +1261,11 @@ public static function getTicketFieldsWithActors($tickets_id, $group_id)
}
}

// Diff-only when remove_group: lets core delete the old group(s) and add the new one in a single call.
if ($_SESSION['glpi_plugins']['escalade']['config']['remove_group'] == true) {
$ticket_actors['Group']['assign'] = [];
}

$ticket_actors['Group']['assign'][] = [
'itemtype' => 'Group',
'items_id' => $group_id,
Expand Down
4 changes: 2 additions & 2 deletions inc/user.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,9 @@ public static function processMassiveActionsForOneItemtype(MassiveAction $ma, Co
if ($escalade_user->getFromDBByCrit(['users_id' => $id])) {
$escalade_user->fields['bypass_filter_assign_group'] = $input['bypass_filter_assign_group'];
if ($escalade_user->update($escalade_user->fields)) {
$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);
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions public/js/central.js.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@
//not executed in self-service interface & right verification
if (
$_SESSION['glpiactiveprofile']['interface'] == "central"
&& (Session::haveRight("ticket", CREATE)
|| Session::haveRight("ticket", UPDATE))
&& (Session::haveRight(Ticket::$rightname, CREATE)
|| Session::haveRight(Ticket::$rightname, UPDATE))
) {
$locale_group_view = __s('Group View');

Expand Down
4 changes: 2 additions & 2 deletions public/js/cloneandlink_ticket.js.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@
//not executed in self-service interface & right verification
if (
$_SESSION['glpiactiveprofile']['interface'] == "central"
&& Session::haveRight("ticket", CREATE)
&& Session::haveRight("ticket", UPDATE)
&& Session::haveRight(Ticket::$rightname, CREATE)
&& Session::haveRight(Ticket::$rightname, UPDATE)
) {
$locale_cloneandlink = __s("Clone and link", "escalade");
$locale_clone = __s("Clone");
Expand Down
4 changes: 2 additions & 2 deletions public/js/escalade.js.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@
//not executed in self-service interface & right verification
if (
$_SESSION['glpiactiveprofile']['interface'] == "central"
&& (Session::haveRight("ticket", CREATE)
|| Session::haveRight("ticket", UPDATE))
&& (Session::haveRight(Ticket::$rightname, CREATE)
|| Session::haveRight(Ticket::$rightname, UPDATE))
) {
$locale_actor = __s('Actor');

Expand Down
8 changes: 4 additions & 4 deletions setup.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@

define('PLUGIN_ESCALADE_VERSION', '2.10.8');
// Minimal GLPI version, inclusive
define("PLUGIN_ESCALADE_MIN_GLPI", "11.0.0");
define("PLUGIN_ESCALADE_MIN_GLPI", "12.0.0");
// Maximum GLPI version, exclusive
define("PLUGIN_ESCALADE_MAX_GLPI", "11.0.99");
define("PLUGIN_ESCALADE_MAX_GLPI", "12.0.99");

if (!defined("PLUGIN_ESCALADE_DIR")) {
define("PLUGIN_ESCALADE_DIR", Plugin::getPhpDir("escalade"));
Expand Down Expand Up @@ -134,7 +134,7 @@ function plugin_init_escalade()
}

// == Interface links ==
if (Session::haveRight('config', UPDATE)) {
if (Session::haveRight(Config::$rightname, UPDATE)) {
$PLUGIN_HOOKS['config_page']['escalade'] = 'front/config.form.php';

$PLUGIN_HOOKS['menu_toadd']['escalade'] = [
Expand Down Expand Up @@ -172,7 +172,7 @@ function plugin_init_escalade()
function plugin_version_escalade()
{
return [
'name' => __s("Escalation", "escalade"),
'name' => "Escalation",
'version' => PLUGIN_ESCALADE_VERSION,
'author' => "<a href='http://www.teclib.com'>Teclib'</a>",
'homepage' => "https://github.com/pluginsGLPI/escalade",
Expand Down
Loading
Loading