CVE-2023-29006 (PHP, published 2023-04-05T18:15Z)
Description: value: The Order GLPI plugin allows users to manage order management within GLPI. Starting with version 1.8.0 and prior to versions 2.7.7 and 2.10.1, an authenticated user that has access to standard interface can craft an URL that can be used to execute a system command. Versions 2.7.7 and 2.10.1 contain a patch for this issue. As a workaround, delete the `ajax/dropdownContact.php` file from the plugin.
Severity: nan (CVSS v3 base score: 8.8)
Weakness: CWE-502 \u2014 Deserialization of Untrusted Data
The product deserializes untrusted data without sufficiently verifying that the resulting data will be valid.
Repository: https://github.com/pluginsGLPI/order
Files changed:
ajax/referencespecifications.php
front/bill.form.php
front/menu.php
front/order.form.php
front/order.php
front/reference.php
front/reference_supplier.form.php
front/surveysupplier.form.php
hook.php
inc/bill.class.php
inc/config.class.php
inc/link.class.php
inc/order.class.php
inc/order_item.class.php
inc/order_supplier.class.php
inc/orderinjection.class.php
inc/preference.class.php
inc/reception.class.php
inc/reference.class.php
inc/reference_supplier.class.php
inc/referencefree.class.php
inc/referenceinjection.class.php
setup.php
Commit message: Clean-up code


Vulnerable code:
<?php

/**
 * -------------------------------------------------------------------------
 * Order plugin for GLPI
 * -------------------------------------------------------------------------
 *
 * LICENSE
 *
 * This file is part of Order.
 *
 * Order 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.
 *
 * Order 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 Order. If not, see <http://www.gnu.org/licenses/>.
 * -------------------------------------------------------------------------
 * @copyright Copyright (C) 2009-2022 by Order plugin team.
 * @license   GPLv3 https://www.gnu.org/licenses/gpl-3.0.html
 * @link      https://github.com/pluginsGLPI/order
 * -------------------------------------------------------------------------
 */

include ("../../../inc/includes.php");

header("Content-Type: text/html; charset=UTF-8");

Html::header_nocache();

if (!defined('GLPI_ROOT')) {
   die("Can not acces directly to this file");
}

Session::checkCentralAccess();

$rand         = $_POST["rand"];
$paramsaction = [
   'plugin_order_references_id' => '__VALUE__',
   'entity_restrict'            => $_POST["entity_restrict"],
   'suppliers_id'               => $_POST["suppliers_id"],
   'itemtype'                   => $_POST['itemtype'],
];
$fields = [
   "quantity",
   "priceht",
   "pricediscounted",
   "taxe",
   "validate",
];

$order_url = Plugin::getWebDir('order');

foreach ($fields as $field) {
   $paramsaction['update'] = $field;
   Ajax::updateItem("show_$field",
                    "$order_url/ajax/referencedetail.php",
                    $paramsaction, "dropdown_reference$rand");
   Ajax::updateItemOnSelectEvent("dropdown_reference$rand",
                                 "show_$field",
                                 "$order_url/ajax/referencedetail.php",
                                 $paramsaction);
}
<?php

/**
 * -------------------------------------------------------------------------
 * Order plugin for GLPI
 * -------------------------------------------------------------------------
 *
 * LICENSE
 *
 * This file is part of Order.
 *
 * Order 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.
 *
 * Order 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 Order. If not, see <http://www.gnu.org/licenses/>.
 * -------------------------------------------------------------------------
 * @copyright Copyright (C) 2009-2022 by Order plugin team.
 * @license   GPLv3 https://www.gnu.org/licenses/gpl-3.0.html
 * @link      https://github.com/pluginsGLPI/order
 * -------------------------------------------------------------------------
 */

if (strpos($_SERVER['PHP_SELF'], "dropdownContact.php")) {
   include ("../../../inc/includes.php");
   header("Content-Type: text/html; charset=UTF-8");
   Html::header_nocache();
}

if (!defined('GLPI_ROOT')) {
   die("Can not acces directly to this file");
}

Session::checkCentralAccess();

// Make a select box with all glpi users
$where = " WHERE `glpi_contacts_suppliers`.`contacts_id` = `glpi_contacts`.`id`
           AND (`glpi_contacts_suppliers`.`suppliers_id` = '".$_POST['suppliers_id']."'
           AND `glpi_contacts`.`is_deleted` = '0' ) ";


if (isset($_POST["entity_restrict"])) {
   if (!is_numeric($_POST["entity_restrict"]) && !is_array($_POST["entity_restrict"])) {
      $_POST["entity_restrict"] = unserialize(Toolbox::stripslashes_deep($_POST["entity_restrict"]));
   }
   $where .= getEntitiesRestrictRequest("AND", "glpi_contacts", '', $_POST["entity_restrict"], true);
} else {
   $where .= getEntitiesRestrictRequest("AND", "glpi_contacts", '', '', true);
}

if ($_POST['searchText'] != $CFG_GLPI["ajax_wildcard"]) {
   $where .= " AND `glpi_contacts`.`name` ".makeTextSearch($_POST['searchText']);
}

$LIMIT = "LIMIT 0, ".$CFG_GLPI["dropdown_max"];
if ($_POST['searchText'] == $CFG_GLPI["ajax_wildcard"]) {
   $LIMIT = "";
}


$query = "SELECT `glpi_contacts`.*
          FROM `glpi_contacts`,`glpi_contacts_suppliers`
          $where
          ORDER BY `entities_id`, `name` $LIMIT";
//error_log($query);
$result = $DB->query($query);

echo "<select name='contacts_id'>";

echo "<option value='0'>".Dropdown::EMPTY_VALUE."</option>";

if ($DB->numrows($result)) {
   $prev = -1;
   while ($data = $DB->fetchArray($result)) {
      if ($data["entities_id"] != $prev) {
         if ($prev > 0) {
            echo "</optgroup>";
         }
         $prev = $data["entities_id"];
         echo "<optgroup label=\"".Dropdown::getDropdownName("glpi_entities", $prev)."\">";
      }
      $output = formatUserName($data["id"], "", $data["name"], $data["firstname"]);
      if ($_SESSION["glpiis_ids_visible"] || empty($output)) {
         $output .= " (".$data["id"].")";
      }
      echo "<option value=\"".$data["id"]."\" title=\"$output\">"
        .substr($output, 0, $CFG_GLPI["dropdown_chars_limit"])."</option>";
   }
   if ($prev >= 0) {
      echo "</optgroup>";
   }
}

echo "</select>";
<?php

/**
 * -------------------------------------------------------------------------
 * Order plugin for GLPI
 * -------------------------------------------------------------------------
 *
 * LICENSE
 *
 * This file is part of Order.
 *
 * Order 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.
 *
 * Order 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 Order. If not, see <http://www.gnu.org/licenses/>.
 * -------------------------------------------------------------------------
 * @copyright Copyright (C) 2009-2022 by Order plugin team.
 * @license   GPLv3 https://www.gnu.org/licenses/gpl-3.0.html
 * @link      https://github.com/pluginsGLPI/order
 * -------------------------------------------------------------------------
 */

include ("../../../inc/includes.php");

header("Content-Type: text/html; charset=UTF-8");

Html::header_nocache();

if (!defined('GLPI_ROOT')) {
   die("Can not acces directly to this file");
}

Session::checkCentralAccess();

if ($_POST["plugin_order_references_id"] > 0) {
   $reference_supplier = new PluginOrderReference_Supplier();
   $price = $reference_supplier->getPriceByReferenceAndSupplier($_POST["plugin_order_references_id"],
                                                                $_POST["suppliers_id"]);
   switch ($_POST["update"]) {
      case 'quantity':
         echo "<input type='number' class='form-control' min='0' name='quantity' class='quantity'>";
         break;
      case 'priceht':
         echo "<input type='number' class='form-control' min='0' step='".PLUGIN_ORDER_NUMBER_STEP."'
                      name='price' value='".Html::formatNumber($price, true)."' class='decimal'>";
         break;
      case 'pricediscounted':
         echo "<input type='number' class='form-control' min='0' step='".PLUGIN_ORDER_NUMBER_STEP."'
                      name='discount' class='smalldecimal' value='0'>";
         break;
      case 'taxe':
         $config = PluginOrderConfig::getConfig();
         PluginOrderOrderTax::Dropdown([
            'name'                => "plugin_order_ordertaxes_id",
            'value'               => $config->getDefaultTaxes(),
            'display_emptychoice' => true,
            'emptylabel'          => __("No VAT", "order"),
         ]);
         break;
      case 'validate':
         echo Html::hidden('itemtype', ['value' => $_POST["itemtype"]]);
         echo Html::hidden('plugin_order_references_id',
                           ['value' => $_POST["plugin_order_references_id"]]);
         echo "<input type='submit' name='add_item' value=\"". __("Add")."\" class='submit' >";
         break;
   }
} else {
   return "";
}
         if ($_POST["itemtype"] == 'PluginOrderOther') {
            $file = 'other';
         } else {
            $file = $_POST["itemtype"];
         }
<?php

/**
 * -------------------------------------------------------------------------
 * Order plugin for GLPI
 * -------------------------------------------------------------------------
 *
 * LICENSE
 *
 * This file is part of Order.
 *
 * Order 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.
 *
 * Order 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 Order. If not, see <http://www.gnu.org/licenses/>.
 * -------------------------------------------------------------------------
 * @copyright Copyright (C) 2009-2022 by Order plugin team.
 * @license   GPLv3 https://www.gnu.org/licenses/gpl-3.0.html
 * @link      https://github.com/pluginsGLPI/order
 * -------------------------------------------------------------------------
 */

$AJAX_INCLUDE = 1;

include ("../../../inc/includes.php");

header("Content-Type: text/html; charset=UTF-8");

Html::header_nocache();

Session::checkLoginUser();

if (!isset($_GET['target'])) {
   $_GET['target'] = Plugin::getWebDir('order')."/front/reference.php";
}

PluginOrderReference::showSelector($_GET['target']);

Html::ajaxFooter();
<?php

/**
 * -------------------------------------------------------------------------
 * Order plugin for GLPI
 * -------------------------------------------------------------------------
 *
 * LICENSE
 *
 * This file is part of Order.
 *
 * Order 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.
 *
 * Order 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 Order. If not, see <http://www.gnu.org/licenses/>.
 * -------------------------------------------------------------------------
 * @copyright Copyright (C) 2009-2022 by Order plugin team.
 * @license   GPLv3 https://www.gnu.org/licenses/gpl-3.0.html
 * @link      https://github.com/pluginsGLPI/order
 * -------------------------------------------------------------------------
 */

$AJAX_INCLUDE = 1;

include ("../../../inc/includes.php");

header("Content-Type: text/html; charset=UTF-8");

Html::header_nocache();

Session::checkLoginUser();

if (isset($_REQUEST['node'])) {
   $target = "reference.php";
   $nodes  = [];

   // Root node
   if ($_REQUEST['node'] == -1) {
      $pos      = 0;
      $entity   = $_SESSION['glpiactive_entity'];
      $entities = getEntitiesRestrictRequest("AND", "glpi_plugin_order_references");

      $query = "SELECT DISTINCT `itemtype`
                FROM `glpi_plugin_order_references`
                WHERE `glpi_plugin_order_references`.`is_deleted` = '0'
                $entities
                GROUP BY `itemtype`
                ORDER BY `itemtype`";

      if ($result = $DB->query($query)) {
         if ($DB->numrows($result)) {
            $pos = 0;

            while ($row = $DB->fetchArray($result)) {
               $class             = $row['itemtype'];
               $item              = new $class();
               $path['text']      = $item->getTypeName();
               $path['position']  = $pos;
               $pos++;
               $path['draggable'] = false;

               if ($entity == 0) {
                  $link = "&link[1]=AND&searchtype[1]=contains&contains[1]=NULL&field[1]=80";
               } else {
                  $link = "&link[1]=AND&searchtype[1]=contains&contains[1]=".
                          Dropdown::getDropdownName("glpi_entities", $entity)."&field[1]=80";
               }

               $path['href'] = Plugin::getWebDir('order').
                  "/front/$target?is_deleted=0&field[0]=3&searchtype[0]=equals&contains[0]=".
                  rawurlencode($class)."&$link&itemtype=PluginOrderReference&start=0";

               // Check if node is a leaf or a folder.
               $path['leaf'] = true;
               $path['cls']  = 'file';
               $nodes[]      = $path;
            }
         }
      }
   }

   print json_encode($nodes);
}
$dropdown = new PluginOrderBill();
$PluginOrderOrder     = new PluginOrderOrder();
$PluginOrderReference = new PluginOrderReference();
$PluginOrderBill      = new PluginOrderBill();

$pluginOrderOrder_Supplier = new PluginOrderOrder_Supplier();
$order = new PluginOrderOrder();

$reference = new PluginOrderReference();

         $newID = $PluginOrderReference_Supplier->add($_POST);
         $newID = $PluginOrderSurveySupplier->add($_POST);
   global $CFG_GLPI;

         $old_itemtype = '';
         $num          = 0;

            if ($data['itemtype']::canView()) {
               $ID = "";
               if ($_SESSION["glpiis_ids_visible"]
                   || empty($data["name"])) {
                    $ID = " (".$data["id"].")";
               }
               $name = NOT_AVAILABLE;
               if ($item->getFromDB($data["id"])) {
                  $name = $item->getLink();
               }

      global $CFG_GLPI;

   
               $serial       = $item->fields["serial"] ?? "";
               $serial       = false;
			
      $isadmin = static::canUpdate();
   public function getLinkedItemDetails($itemtype, $items_id) {
      $comments = "";

      switch ($itemtype) {
         case 'ConsumableItem' :
            $ci = new Consumable();
            if ($ci->getFromDB($items_id)) {
               $ct = new ConsumableItem();
               $ct->getFromDB($ci->fields['consumableitems_id']);

               $comments .= "<strong>".__("Entity").":</strong> ";
               $comments .= Dropdown::getDropdownName("glpi_entities", $ct->fields["entities_id"]);
               $comments .= '<br><strong>'.__("Consumable").' : </strong> #'.$items_id;
               $comments .= '<br><strong>'.__("Consumable type").' : </strong>';
               $comments .= $ct->fields['name'];
               $comments .= '<br><strong>'.__("Manufacturer").' : </strong>';
               $comments .= Dropdown::getDropdownName('glpi_manufacturers', $ct->fields['manufacturers_id']);
               $comments .= '<br><strong>'.__("State").' : </strong>';
               $comments .= (!$ci->fields['users_id'] ? __("In stock") : __("Used"));
               if ($ci->fields['users_id']) {
                  $comments .= '<br><strong>'.__("User").' : </strong>';
                  $comments .= Dropdown::getDropdownName('glpi_users', $ci->fields['users_id']);
               }
            }
            break;
         case 'CartridgeItem' :
            $ci = new Cartridge();
            if ($ci->getFromDB($items_id)) {
               $ct = new CartridgeItem();
               $ct->getFromDB($ci->fields['cartridgeitems_id']);

               $comments .= "<strong>".__("Entity").":</strong> ";
               $comments .= Dropdown::getDropdownName("glpi_entities", $ct->fields["entities_id"]);
               $comments .= '<br><strong>'.__("Cartridge").' : </strong> #'.$items_id;
               $comments .= '<br><strong>'._n("New", "New", 2).' : </strong>';
               $comments .= $ct->fields['name'];
               $comments .= '<br><strong>'.__("Manufacturer").' : </strong>';
               $comments .= Dropdown::getDropdownName('glpi_manufacturers', $ct->fields['manufacturers_id']);
            }
            break;
         // case 'Computer' :
         // case 'Monitor' :
         // case 'NetworkEquipment' :
         // case 'Peripheral' :
         // case 'Phone' :
         // case 'Printer' :
         default :
            $item = new $itemtype();
            $item->getFromDB($items_id);

            if ($item->getField("name")) {
               $comments .= "<strong>".__("Name").":</strong> ";
               $comments .= $item->getField("name");
            }

            if ($item->getField("entities_id")) {
               $comments .= "<strong>".__("Entity").":</strong> ";
               $comments .= Dropdown::getDropdownName("glpi_entities", $item->getField("entities_id"));
            }

            if ($item->getField("serial") != '') {
               $comments .= "<br><strong>".__("Serial number").":</strong> ";
               $comments .= $item->getField("serial");
            }

            if ($item->getField("otherserial") != '') {
               $comments .= "<br><strong>".__("Inventory number").":</strong> ";
               $comments .= $item->getField("otherserial");
            }
            if ($item->getField("locations_id")) {
               $comments .= "<br><strong>".__("Location").":</strong> ";
               $comments .= Dropdown::getDropdownName('glpi_locations', $item->getField("locations_id"));
            }

            if ($item->getField("users_id")) {
               $comments .= "<br><strong>".__("User").":</strong> ";
               $comments .= Dropdown::getDropdownName('glpi_users', $item->getField("users_id"));
            }
            break;
      }

      return ($comments);
   }



   /*public function dropdownLinkActions($itemtype, $plugin_order_references_id,
                                       $plugin_order_orders_id, $entities_id) {
      global $CFG_GLPI;

      $rand       = mt_rand();
      $reception  = new PluginOrderReception();
      $actions[0] = Dropdown::EMPTY_VALUE;
      if ($reception->checkItemStatus($plugin_order_orders_id, $plugin_order_references_id,
                                      PluginOrderOrder::ORDER_DEVICE_DELIVRED)) {
         if (!in_array($itemtype, self::getTypesThanCannotBeGenerared())) {
            $actions['generation'] = __("Generate item", "order");
         }
         if ($itemtype::canView()) {
            $actions['createLink'] = __("Link to an existing item", "order");
            $actions['deleteLink'] = __("Delete item link", "order");
         }
      }
      $rand   = Dropdown::showFromArray('generationActions', $actions);
      Ajax::updateItemOnSelectEvent("dropdown_generationActions$rand", "show_generationActions$rand",
                                  Plugin::getWebDir('order')."/ajax/linkactions.php",
                                  ['action'                     => '__VALUE__',
                                   'itemtype'                   => $itemtype,
                                   'plugin_order_references_id' => $plugin_order_references_id,
                                   'plugin_order_orders_id'     => $plugin_order_orders_id,
                                   'entities_id'                => $entities_id]);
      echo "<span id='show_generationActions$rand'>&nbsp;</span>";
   }*/

         $result = $PluginOrderOrder_Item->queryRef($detail->fields["plugin_order_orders_id"],
   
   
               $ticketID = $ticket->add($input);
         $result = $this->createLinkWithItem($values["id"], $newID, $add_item["itemtype"],
    * @param unknown_type $itemtype
    * @param unknown_type $items_id
    * @param unknown_type $orders_id
    * @param unknown_type $entity
   public function dropdownSuppliers($myname, $value = 0, $entity_restrict = '') {
      global $DB, $CFG_GLPI;

      $rand     = mt_rand();
      $entities = getEntitiesRestrictRequest("AND", "glpi_suppliers", '', $entity_restrict, true);

      $query = "SELECT `glpi_suppliers`.*
                FROM `glpi_suppliers`
                LEFT JOIN `glpi_contacts_suppliers`
                   ON (`glpi_contacts_suppliers`.`suppliers_id` = `glpi_suppliers`.`id`)
                WHERE `glpi_suppliers`.`is_deleted` = '0'
                $entities
                GROUP BY `glpi_suppliers`.`id`
                ORDER BY `entities_id`, `name`";
      $result = $DB->query($query);

      echo "<select name='suppliers_id' id='suppliers_id'>\n";
      echo "<option value='0'>".Dropdown::EMPTY_VALUE."</option>\n";

      $prev = -1;
      while ($data = $DB->fetchArray($result)) {
         if ($data["entities_id"] != $prev) {
            if ($prev >= 0) {
               echo "</optgroup>";
            }
            $prev = $data["entities_id"];
            echo "<optgroup label=\"".Dropdown::getDropdownName("glpi_entities", $prev)."\">";
         }
         $output = $data["name"];
         if ($_SESSION["glpiis_ids_visible"] || empty($output)) {
            $output .= " (".$data["id"].")";
         }
         echo "<option value='".$data["id"]."' ".($value == $data["id"] ? " selected " : "").
               " title=\"".Html::cleanInputText($output)."\">".
               substr($output, 0, $CFG_GLPI["dropdown_chars_limit"])."</option>";
      }
      if ($prev >= 0) {
         echo "</optgroup>";
      }
      echo "</select>";
      Ajax::updateItemOnSelectEvent("suppliers_id", "show_contacts_id",
                                    Plugin::getWebDir('order')."/ajax/dropdownSupplier.php",
                                    [
                                       'suppliers_id'    => '__VALUE__',
                                       'entity_restrict' => $entity_restrict,
                                       'rand'            => $rand,
                                       'myname'          => $myname,
                                    ]);

      return $rand;
   }


   public function dropdownContacts($suppliers_id, $value = 0, $entity_restrict = '') {
      global $DB, $CFG_GLPI;

      $rand     = mt_rand();
      $entities = getEntitiesRestrictRequest("AND", "glpi_contacts", '', $entity_restrict, true);

      $query = "SELECT `glpi_contacts`.*
                FROM `glpi_contacts`,`glpi_contacts_suppliers`
                WHERE `glpi_contacts_suppliers`.`contacts_id` = `glpi_contacts`.`id`
                AND `glpi_contacts_suppliers`.`suppliers_id` = '$suppliers_id'
                AND `glpi_contacts`.`is_deleted` = '0'
                $entities
                ORDER BY `entities_id`, `name`";
      $result = $DB->query($query);

      echo "<select name='contacts_id'>";
      echo "<option value='0'>".Dropdown::EMPTY_VALUE."</option>";

      if ($DB->numrows($result)) {
         $prev = -1;
         while ($data = $DB->fetchArray($result)) {
            if ($data["entities_id"] != $prev) {
               if ($prev >= 0) {
                  echo "</optgroup>";
               }
               $prev = $data["entities_id"];
               echo "<optgroup label=\"".Dropdown::getDropdownName("glpi_entities", $prev)."\">";
            }
            $output = formatUserName($data["id"], "", $data["name"], $data["firstname"]);
            if ($_SESSION["glpiis_ids_visible"] || empty($output)) {
               $output .= " (".$data["id"].")";
            }
            echo "<option value='".$data["id"]."' ".($value == $data["id"] ? " selected " : "")
              ." title=\"".Html::cleanInputText($output)."\">"
              .substr($output, 0, $CFG_GLPI["dropdown_chars_limit"])."</option>";
         }
         if ($prev >= 0) {
            echo "</optgroup>";
         }
      }
      echo "</select>";
   }


   public function needValidation($ID) {
      if ($ID > 0 && $this->getFromDB($ID)) {
         return $this->isDraft() || $this->isWaitingForApproval();
      } else {
         return false;
      }
   }


         $detail = new PluginOrderOrder_Item();
            $num    = $DB->numrows($result);
            $num    = $DB->numrows($result);
            $ref = $reference->transfer($detail["plugin_order_references_id"], $entity);
      $cron_status = 1;
   /**
    * Get the standard massive actions which are forbidden
    *
    * @since version 0.84
    *
    * @return an array of massive actions
    **/
      global $UNINSTALL_TYPES;

      global $CFG_GLPI;

               $id     = false;
                  $id = $tmp['id'];
                  $id = $budget->add($tmp);
   public function checkIFReferenceExistsInOrder($orders_id, $ref_id) {
      return (countElementsInTable(
         $this->getTable(),
         [
            'plugin_order_orders_id' => $orders_id,
            'plugin_order_references_id' => $ref_id,
         ]
      ));
   }


         $num    = $DB->numrows($result);
   public function getTotalQuantityByRef($orders_id, $references_id) {
      global $DB;

      $query = "SELECT COUNT(*) AS quantity
                FROM `".self::getTable()."`
                WHERE `plugin_order_orders_id` = '$orders_id'
                   AND `plugin_order_references_id` = '$references_id' ";
      $result = $DB->query($query);
      return ($DB->result($result, 0, 'quantity'));
   }


      global $DB;

      global $DB;

            $result = $DB->query($query) or die($DB->error());
   public function checkIfSupplierInfosExists($plugin_order_orders_id) {

      if ($plugin_order_orders_id) {
         $devices = getAllDataFromTable(self::getTable(),
                                         ['plugin_order_orders_id' => $plugin_order_orders_id]);
         if (!empty($devices)) {
            return true;
         } else {
            return false;
         }
      }
   }



   /**
    * Standard method to add an object into glpi
    *
    * @param values fields to add into glpi
    * @param options options used during creation
    * @return an array of IDs of newly created objects : for example array(Computer=>1, Networkport=>10)
    *
   **/
    * @param $value default value
    * @param $value default value
    * @param $extension list files of this extension only
    * @param $value default value
      $array_dir  = [];

                  } else if ($filetype == "dir") {
                     $array_dir[] = $filename;
         $result = $PluginOrderOrder_Item->queryRef($_POST["plugin_order_orders_id"],
      $isadmin = static::canUpdate();

   public function dropdownReceptionActions($itemtype, $plugin_order_references_id, $plugin_order_orders_id) {
      global $CFG_GLPI;

      $rand = mt_rand();

      echo "<select name='receptionActions$rand' id='receptionActions$rand'>";
      echo "<option value='0' selected>".Dropdown::EMPTY_VALUE."</option>";
      echo "<option value='reception'>".__("Take item delivery", "order")."</option>";
      echo "</select>";
      $params = [
         'action'                     => '__VALUE__',
         'itemtype'                   => $itemtype,
         'plugin_order_references_id' => $plugin_order_references_id,
         'plugin_order_orders_id'     => $plugin_order_orders_id,
      ];
      Ajax::updateItemOnSelectEvent("receptionActions$rand", "show_receptionActions$rand",
                                    Plugin::getWebDir('order')."/ajax/receptionactions.php",
                                    $params);
      echo "<span id='show_receptionActions$rand'>&nbsp;</span>";
   }


   * return nothing
            foreach ($types as $key => $type) {

   /**
    * Display entities of the loaded profile
    *
   * @param $myname select name
    * @param $target target for entity change action
    */
   public static function showSelector($target) {
      $rand = mt_rand();
      Plugin::loadLang('order');
      echo "<div class='center' ><span class='b'>".__("Select the wanted item type", "order")
        ."</span><br>";
      echo "<a style='font-size:14px;' href='".$target."?reset=reset' title=\""
        .__("Show all")."\">".str_replace(" ", "&nbsp;", __("Show all"))."</a></div>";

      echo "<div class='left' style='width:100%'>";

      echo "<script type='javascript'>";
      echo "var Tree_Category_Loader$rand = new Ext.tree.TreeLoader({
         dataUrl:'".Plugin::getWebDir('order')."/ajax/referencetreetypes.php'
      });";

      echo "var Tree_Category$rand = new Ext.tree.TreePanel({
         collapsible      : false,
         animCollapse     : false,
         border           : false,
         id               : 'tree_projectcategory$rand',
         el               : 'tree_projectcategory$rand',
         autoScroll       : true,
         animate          : false,
         enableDD         : true,
         containerScroll  : true,
         height           : 320,
         width            : 770,
         loader           : Tree_Category_Loader$rand,
         rootVisible     : false
      });";

      // SET the root node.
      echo "var Tree_Category_Root$rand = new Ext.tree.AsyncTreeNode({
         text     : '',
         draggable   : false,
         id    : '-1'                  // this IS the id of the startnode
      });
      Tree_Category$rand.setRootNode(Tree_Category_Root$rand);";

      // Render the tree.
      echo "Tree_Category$rand.render();
            Tree_Category_Root$rand.expand();";

      echo "</script>";

      echo "<div id='tree_projectcategory$rand' ></div>";
      echo "</div>";
   }


   public function title() {
      echo "<div align='center'>";
      echo self::getPerTypeJavascriptCode();
      echo "<a onclick='order_window.show();' href='#modal_reference_content' title='"
           .__("View by item type", "order")."'>"
           .__("View by item type", "order")."</a>";
      echo "</div>";

   }


   public static function getPerTypeJavascriptCode() {
      global $CFG_GLPI;

      $out  = "<script type='text/javascript'>";
      $out .= "cleanhide('modal_reference_content');";
      $out .= "var order_window=new Ext.Window({
         layout:'fit',
         width:800,
         height:400,
         closeAction:'hide',
         modal: true,
         autoScroll: true,
         title: \"".__("View by item type", "order")."\",
         autoLoad: '".Plugin::getWebDir('order')."/ajax/referencetree.php'
      });";
      $out .= "</script>";
      return $out;
   }


   /**
    * Get the standard massive actions which are forbidden
    *
    * @since version 0.84
    *
    * @return an array of massive actions
    **/

   /*   function getValueToSelect($field_id_or_search_options, $name = '', $values = '', $options = []) {
      if (isset($field_id_or_search_options['displaytype'])
         && $field_id_or_search_options['displaytype'] == 'reference_type') {
            Toolbox::logDebug($field_id_or_search_options['displaytype'],
                              $field_id_or_search_options, $name, $values, $options);

      }
      return false;
   }*/

      global $DB, $CFG_GLPI;
   public function getPriceByReferenceAndSupplier($plugin_order_references_id, $suppliers_id) {
      global $DB;

      $table = self::getTable();
      $query = "SELECT `price_taxfree`
                FROM `$table`
                WHERE `plugin_order_references_id` = '$plugin_order_references_id'
                AND `suppliers_id` = '$suppliers_id' ";
      $result = $DB->query($query);

      if ($DB->numrows($result) > 0) {
         return $DB->result($result, 0, "price_taxfree");
      } else {
         return 0;
      }
   }


   public function addDetails($ref_id, $itemtype, $orders_id, $quantity, $price, $discounted_price, $taxes_id) {
      $order = new PluginOrderOrder();
      if ($quantity > 0 && $order->getFromDB($orders_id)) {
         for ($i = 0; $i < $quantity; $i++) {
            $input["plugin_order_orders_id"]     = $orders_id;
            $input["plugin_order_ordertaxes_id"] = $taxes_id;
            $input["itemtype"]                   = $itemtype;
            $input["entities_id"]                = $order->getEntityID();
            $input["is_recursive"]               = $order->isRecursive();
            $input["price_taxfree"]              = $price;
            $input["price_discounted"]           = $price - ($price * ($discounted_price / 100));
            $input["states_id"]                  = PluginOrderOrder::ORDER_DEVICE_NOT_DELIVRED;

            $input["price_ati"] = $this->getPricesATI($input["price_discounted"], Dropdown::getDropdownName("glpi_plugin_order_ordertaxes", $taxes_id));
            $input["discount"]  = $discounted_price;

            $this->add($input);
         }
      }
   }

   /**
    * Standard method to add an object into glpi
    *
    * @param values fields to add into glpi
    * @param options options used during creation
    * @return an array of IDs of newly created objects : for example [Computer => 1, Networkport => 10]
    *
   **/
            'dev' => true, //Required to allow 9.2-dev

Fixed code:
         $PluginOrderReference_Supplier->add($_POST);
         $PluginOrderSurveySupplier->add($_POST);
            if ($data['itemtype']::canView() && $item->getFromDB($data["id"])) {


         $result = $detail->queryRef($detail->fields["plugin_order_orders_id"],


               $ticket->add($input);
         $this->createLinkWithItem($values["id"], $newID, $add_item["itemtype"],
    * @param $itemtype
    * @param $items_id
    * @param $orders_id
    * @param $entity
            $reference->transfer($detail["plugin_order_references_id"], $entity);
                  $budget->add($tmp);
            $DB->query($query) or die($DB->error());
    * @param $value
    * @param $value
    * @param array $extension list files of this extension only
    * @param $value
         $result = $detail->queryRef($_POST["plugin_order_orders_id"],
   * @return void
            foreach ($types as $type) {
      global $DB;