diff --git a/ajax/dropdownZone.php b/ajax/dropdownZone.php new file mode 100644 index 00000000..f801150b --- /dev/null +++ b/ajax/dropdownZone.php @@ -0,0 +1,54 @@ +. + * + * ------------------------------------------------------------------------- + */ + +use GlpiPlugin\Carbon\Source_Zone; +use GlpiPlugin\Carbon\Zone; + +include(__DIR__ . '/../../../inc/includes.php'); + +// Check if plugin is activated... +if (!Plugin::isPluginActive('carbon')) { + http_response_code(404); + die(); +} + +// throw new RuntimeException('Required argument missing or incorrect!'); + +$source_zone_table = Source_Zone::getTable(); +$zone_table = Zone::getTable(); +$source_id = (int) $_POST['plugin_carbon_sources_id']; +Zone::dropdown([ + 'rand' => (int) $_POST['dom_id'], + 'condition' => Zone::getRestrictBySourceCondition($source_id), + // 'disabled' => ($source_id === 0), + 'specific_tags' => ($source_id === 0 ? ['disabled' => 'disabled'] : []), +]); diff --git a/ajax/toggleZoneDownload.php b/ajax/toggleZoneDownload.php index 581a2a8c..feba5601 100644 --- a/ajax/toggleZoneDownload.php +++ b/ajax/toggleZoneDownload.php @@ -30,8 +30,8 @@ * ------------------------------------------------------------------------- */ -use GlpiPlugin\Carbon\CarbonIntensitySource; -use GlpiPlugin\Carbon\CarbonIntensitySource_Zone; +use GlpiPlugin\Carbon\Source; +use GlpiPlugin\Carbon\Source_Zone; include(__DIR__ . '/../../../inc/includes.php'); @@ -41,7 +41,7 @@ die(); } -if (!CarbonIntensitySource::canView()) { +if (!Source::canView()) { // Will die http_response_code(403); die(); @@ -52,7 +52,7 @@ die(); } -$source_zone = new CarbonIntensitySource_Zone(); +$source_zone = new Source_Zone(); if (!$source_zone->getFromDB($_GET['id'])) { http_response_code(403); die(); diff --git a/front/computertype.form.php b/front/computertype.form.php index b7b90a71..d2503e62 100644 --- a/front/computertype.form.php +++ b/front/computertype.form.php @@ -32,6 +32,7 @@ use Glpi\Exception\Http\NotFoundHttpException; use GlpiPlugin\Carbon\ComputerType; +use ComputerType as GlpiComputerType; include(__DIR__ . '/../../../inc/includes.php'); @@ -39,13 +40,12 @@ throw new NotFoundHttpException(); } -Session::checkRight('config', UPDATE); +Session::checkRight(GlpiComputerType::$rightname, UPDATE); $item = new ComputerType(); if (isset($_POST['update'])) { - // Add a new Form - Session::checkRight('entity', UPDATE); + Session::checkRight(GlpiComputerType::$rightname, UPDATE); $item->update($_POST); Html::back(); } diff --git a/front/location.form.php b/front/location.form.php new file mode 100644 index 00000000..2ebed113 --- /dev/null +++ b/front/location.form.php @@ -0,0 +1,53 @@ +. + * + * ------------------------------------------------------------------------- + */ + +use Glpi\Exception\Http\NotFoundHttpException; +use GlpiPlugin\Carbon\Location; +use Location as GlpiLocation; + +include(__DIR__ . "/../../../inc/includes.php"); + +if (!Plugin::isPluginActive('carbon')) { + throw new NotFoundHttpException(); +} + +Session::checkRight(GlpiLocation::$rightname, UPDATE); + +$item = new Location(); + +if (isset($_POST['update'])) { + Session::checkRight(GlpiLocation::$rightname, UPDATE); + $item->update($_POST); + Html::back(); +} + +Html::back(); diff --git a/front/monitortype.form.php b/front/monitortype.form.php index 585a3dd6..02dc412a 100644 --- a/front/monitortype.form.php +++ b/front/monitortype.form.php @@ -34,18 +34,18 @@ use GlpiPlugin\Carbon\MonitorType; use Glpi\Exception\Http\NotFoundHttpException; +use MonitorType as GlpiMonitorType; if (!Plugin::isPluginActive('carbon')) { throw new NotFoundHttpException(); } -Session::checkRight('config', UPDATE); +Session::checkRight(GlpiMonitorType::$rightname, UPDATE); $item = new MonitorType(); if (isset($_POST['update'])) { - // Add a new Form - Session::checkRight('entity', UPDATE); + Session::checkRight(GlpiMonitorType::$rightname, UPDATE); $item->update($_POST); Html::back(); } diff --git a/front/networkequipmenttype.form.php b/front/networkequipmenttype.form.php index 093c1f8e..397f092e 100644 --- a/front/networkequipmenttype.form.php +++ b/front/networkequipmenttype.form.php @@ -32,6 +32,7 @@ use Glpi\Exception\Http\NotFoundHttpException; use GlpiPlugin\Carbon\NetworkEquipmentType; +use NetworkEquipmentType as GlpiNetworkEquipmentType; include(__DIR__ . '/../../../inc/includes.php'); @@ -39,13 +40,12 @@ throw new NotFoundHttpException(); } -Session::checkRight('config', UPDATE); +Session::checkRight(GlpiNetworkEquipmentType::$rightname, UPDATE); $item = new NetworkEquipmentType(); if (isset($_POST['update'])) { - // Add a new Form - Session::checkRight('entity', UPDATE); + Session::checkRight(GlpiNetworkEquipmentType::$rightname, UPDATE); $item->update($_POST); Html::back(); } diff --git a/hook.php b/hook.php index 7f91f6ef..1fd8aeda 100644 --- a/hook.php +++ b/hook.php @@ -36,14 +36,14 @@ use GlpiPlugin\Carbon\Install; use GlpiPlugin\Carbon\Uninstall; use GlpiPlugin\Carbon\UsageInfo; -use GlpiPlugin\Carbon\CarbonIntensitySource; +use GlpiPlugin\Carbon\Source; use GlpiPlugin\Carbon\Zone; use ComputerType as GlpiComputerType; use GlpiPlugin\Carbon\CarbonEmission; use GlpiPlugin\Carbon\CarbonIntensity; use MonitorType as GlpiMonitorType; use NetworkEquipmentType as GlpiNetworkEquipmentType; -use GlpiPlugin\Carbon\CarbonIntensitySource_Zone; +use GlpiPlugin\Carbon\Source_Zone; use GlpiPlugin\Carbon\Config; use GlpiPlugin\Carbon\EmbodiedImpact; use GlpiPlugin\Carbon\Location; @@ -120,7 +120,7 @@ function plugin_carbon_getDropdown() { return [ ComputerUsageProfile::class => ComputerUsageProfile::getTypeName(), - CarbonIntensitySource::class => CarbonIntensitySource::getTypeName(), + Source::class => Source::getTypeName(), Zone::class => Zone::getTypeName(), CarbonIntensity::class => CarbonIntensity::getTypeName(), ]; @@ -153,25 +153,11 @@ function plugin_carbon_getAddSearchOptionsNew($itemtype): array } /** - * Callback before showing save / update button on an item form + * Callback when an object is added into the database * - * @param array $params 'item' => CommonDBTM - * 'options => array + * @param CommonDBTM $item item being added * @return void */ -function plugin_carbon_postItemForm(array $params) -{ - switch ($params['item']->getType()) { - case GlpiLocation::class: - $location = new Location(); - $location->getFromDBByCrit([ - GlpiLocation::getForeignKeyField() => $params['item']->getID(), - ]); - $location->showForm($location->getID()); - break; - } -} - function plugin_carbon_hook_add_asset(CommonDBTM $item) { if (!in_array($item::getType(), PLUGIN_CARBON_TYPES)) { @@ -184,21 +170,20 @@ function plugin_carbon_hook_add_asset(CommonDBTM $item) if (GlpiLocation::isNewID($item->fields[$location_fk])) { return; } - $zone = Zone::getByAsset($item); - if ($zone === null) { - return; - } - $source_zone = new CarbonIntensitySource_Zone(); - $source_zone->getFromDBByCrit([ - $zone->getForeignKeyField() => $zone->fields['id'], - CarbonIntensitySource::getForeignKeyField() => $zone->fields['plugin_carbon_carbonintensitysources_id_historical'], - ]); - if ($source_zone->isNewItem()) { + + $source_zone = new Source_Zone(); + if ($source_zone->getFromDbByItem($item) === false) { return; } $source_zone->toggleZone(true); } +/** + * Callback when an item is being updated in the database + * + * @param CommonDBTM $item item being updated + * @return void + */ function plugin_carbon_hook_update_asset(CommonDBTM $item) { if (!in_array($item::getType(), PLUGIN_CARBON_TYPES)) { @@ -211,14 +196,14 @@ function plugin_carbon_hook_update_asset(CommonDBTM $item) if (GlpiLocation::isNewID($item->fields[$location_fk])) { return; } - $zone = Zone::getByAsset($item); - if ($zone === null) { + $zone = new Zone(); + if ($zone->getByAsset($item) === false) { return; } - $source_zone = new CarbonIntensitySource_Zone(); + $source_zone = new Source_Zone(); $source_zone->getFromDBByCrit([ $zone->getForeignKeyField() => $zone->fields['id'], - CarbonIntensitySource::getForeignKeyField() => $zone->fields['plugin_carbon_carbonintensitysources_id_historical'], + Source::getForeignKeyField() => $zone->fields['plugin_carbon_sources_id_historical'], ]); if ($source_zone->isNewItem()) { return; diff --git a/install/Install.php b/install/Install.php index 10b885f3..832882bf 100644 --- a/install/Install.php +++ b/install/Install.php @@ -35,8 +35,6 @@ use Config; use DBmysql; use DirectoryIterator; -use Glpi\Message\MessageType; -use Glpi\Toolbox\Sanitizer; use Migration; use Plugin; @@ -247,16 +245,18 @@ private function getMigrationsToDo(string $current_version): array * * @param string $name Name of the zone * @param int $is_fallback Is the zone a fallback zone (1) or not (0) + * @param int $is_carbon_intensity_source Does the source provide carbon intensity (1) or not (0) * @return int ID of the zone */ - public static function getOrCreateSource(string $name, int $is_fallback = 1): int + public static function getOrCreateSource(string $name, int $is_fallback = 1, int $is_carbon_intensity_source = 1): int { - $source = new CarbonIntensitySource(); + $source = new Source(); $source->getFromDBByCrit(['name' => $name]); if ($source->isNewItem()) { $source->add([ 'name' => $name, 'is_fallback' => $is_fallback, + 'is_carbon_intensity_source' => $is_carbon_intensity_source, ]); /** @phpstan-ignore if.alwaysTrue */ if ($source->isNewItem()) { @@ -280,7 +280,7 @@ public static function getOrCreateZone(string $name, int $source_id): int if ($zone->isNewItem()) { $zone->add([ 'name' => $name, - 'plugin_carbon_carbonintensitysources_id_historical' => $source_id, + 'plugin_carbon_sources_id_historical' => $source_id, ]); /** @phpstan-ignore if.alwaysTrue */ if ($zone->isNewItem()) { @@ -294,22 +294,31 @@ public static function getOrCreateZone(string $name, int $source_id): int /** * Link a carbon intensity source to a zone * - * @param int $source_id ID of the carbon intensity source - * @param int $zone_id ID of the zone - * @return int ID of the link + * @param int $source_id ID of the carbon intensity source + * @param int $zone_id ID of the zone + * @param string $code Identifier of the zone used by the source + * @return int ID of the link */ - public static function linkSourceZone(int $source_id, int $zone_id): int + public static function linkSourceZone(int $source_id, int $zone_id, string $code = ''): int { - $source_zone = new CarbonIntensitySource_Zone(); + $source_zone = new Source_Zone(); $source_zone->getFromDBByCrit([ - 'plugin_carbon_carbonintensitysources_id' => $source_id, - 'plugin_carbon_zones_id' => $zone_id, + 'plugin_carbon_sources_id' => $source_id, + 'plugin_carbon_zones_id' => $zone_id, ]); if ($source_zone->isNewItem()) { $source_zone->add([ - 'plugin_carbon_carbonintensitysources_id' => $source_id, - 'plugin_carbon_zones_id' => $zone_id, + 'plugin_carbon_sources_id' => $source_id, + 'plugin_carbon_zones_id' => $zone_id, + 'code' => $code ]); + } else { + if ($source_zone->fields['code'] !== $code) { + $source_zone->update([ + 'id' => $source_zone->getID(), + 'code' => $code, + ]); + } } return $source_zone->getID(); diff --git a/install/install/init_datasources.php b/install/install/init_datasources.php index 2614450b..645e04eb 100644 --- a/install/install/init_datasources.php +++ b/install/install/init_datasources.php @@ -33,19 +33,30 @@ use GlpiPlugin\Carbon\Install; use Symfony\Component\Console\Helper\ProgressBar; use Symfony\Component\Console\Output\ConsoleOutput; +use GlpiPlugin\Carbon\Source; +use GlpiPlugin\Carbon\Source_Zone; +use GlpiPlugin\Carbon\Zone; /** @var DBmysql $DB */ global $DB; +// This file is executed at the end of an upgrade. +// Upgrade to 1.2.0 changed the tables modified by this code +// then we need to reset DB columns cache +$DB->listFields(getTableForItemType(Source::class), false); +$DB->listFields(getTableForItemType(Source_Zone::class), false); +$DB->listFields(getTableForItemType(Zone::class), false); + $source_id = Install::getOrCreateSource('RTE', 0); $zone_id = Install::getOrCreateZone('France', $source_id); +Install::linkSourceZone($source_id, $zone_id); $source_id = Install::getOrCreateSource('ElectricityMap', 0); $dbUtil = new DbUtils(); $table = $dbUtil->getTableForItemType(GlpiPlugin\Carbon\CarbonIntensity::class); -// Expected columns are Entity;Code; Year; Carbon intensity of electricity - gCO2/kWh +// Expected columns are Entity; Code; Year; Carbon intensity of electricity - gCO2/kWh $data_source = dirname(__DIR__) . '/data/carbon_intensity/carbon-intensity-electricity.csv'; // Create data source in DB @@ -89,7 +100,7 @@ } $zone_id = Install::getOrCreateZone($entity, $source_id); - Install::linkSourceZone($source_id, $zone_id); + Install::linkSourceZone($source_id, $zone_id, $code); // Insert into the database $success = $DB->updateOrInsert($table, [ @@ -97,8 +108,8 @@ 'data_quality' => 2 // constant GlpiPlugin\Carbon\DataTracking::DATA_QUALITY_ESTIMATED ], [ 'date' => "$year-01-01 00:00:00", - 'plugin_carbon_carbonintensitysources_id' => $source_id, - 'plugin_carbon_zones_id' => $zone_id + 'plugin_carbon_sources_id' => $source_id, + 'plugin_carbon_zones_id' => $zone_id, ]); if ($success === false) { @@ -111,7 +122,7 @@ } $file = null; // close the file -$source_id = Install::getOrCreateSource('Hydro Quebec'); +$source_id = Install::getOrCreateSource('Hydro Quebec', 1, 0); $zone_id_quebec = Install::getOrCreateZone('Quebec', $source_id); Install::linkSourceZone($source_id, $zone_id_quebec); @@ -122,7 +133,7 @@ 'data_quality' => 2 // constant GlpiPlugin\Carbon\DataTracking::DATA_QUALITY_ESTIMATED ], [ 'date' => "$year-01-01 00:00:00", - 'plugin_carbon_carbonintensitysources_id' => $source_id, + 'plugin_carbon_sources_id' => $source_id, 'plugin_carbon_zones_id' => $zone_id_quebec, ]); diff --git a/install/migration/update_1.0.0_to_1.0.1/01_fix_source_zone_quebec.php b/install/migration/update_1.0.0_to_1.0.1/01_fix_source_zone_quebec.php index b07b8b0f..12b617b7 100644 --- a/install/migration/update_1.0.0_to_1.0.1/01_fix_source_zone_quebec.php +++ b/install/migration/update_1.0.0_to_1.0.1/01_fix_source_zone_quebec.php @@ -32,9 +32,6 @@ use Glpi\DBAL\QuerySubQuery; use GlpiPlugin\Carbon\CarbonEmission; -use GlpiPlugin\Carbon\CarbonIntensitySource; -use GlpiPlugin\Carbon\CarbonIntensitySource_Zone; -use GlpiPlugin\Carbon\Zone; /** @var DBmysql $DB */ global $DB; @@ -42,9 +39,9 @@ $db_utils = new DbUtils(); // Update and fix the bad relation -$source_table = $db_utils->getTableForItemType(CarbonIntensitySource::class); -$zone_table = $db_utils->getTableForItemType(Zone::class); -$source_zone_table = $db_utils->getTableForItemType(CarbonIntensitySource_Zone::class); +$source_table = 'glpi_plugin_carbon_carbonintensitysources'; +$zone_table = 'glpi_plugin_carbon_zones'; +$source_zone_table = 'glpi_plugin_carbon_carbonintensitysources_zones'; $source_iterator = $DB->request([ 'SELECT' => 'id', 'FROM' => $source_table, @@ -70,7 +67,7 @@ NetworkEquipment::class ]; -$carbon_emission_table = $db_utils->getTableForItemType(CarbonEmission::class); +$carbon_emission_table = 'glpi_plugin_carbon_carbonemissions'; $location_table = $db_utils->getTableForItemType(Location::class); foreach ($itemtypes as $itemtype) { $item_table = $db_utils->getTableForItemType($itemtype); diff --git a/install/migration/update_1.1.0_to_1.2.0.php b/install/migration/update_1.1.0_to_1.2.0.php new file mode 100644 index 00000000..e92d090e --- /dev/null +++ b/install/migration/update_1.1.0_to_1.2.0.php @@ -0,0 +1,69 @@ +. + * + * ------------------------------------------------------------------------- + */ + +function update110to120(Migration $migration) +{ + /** @var DBmysql $DB */ + global $DB; + + $updateresult = true; + $from_version = '1.1.0'; + $to_version = '1.2.0'; + $update_dir = __DIR__ . "/update_{$from_version}_to_{$to_version}/"; + + //TRANS: %s is the number of new version + $migration->addInfoMessage(sprintf(__('Update to %s'), $to_version)); + $migration->setVersion($to_version); + + // New tables from enpty.sql file after the migration + // If a script requires a new table, it may create it by itself + + $update_scripts = scandir($update_dir); + natcasesort($update_scripts); + foreach ($update_scripts as $update_script) { + if (preg_match('/\.php$/', $update_script) !== 1) { + continue; + } + require $update_dir . $update_script; + } + + $dbFile = plugin_carbon_getSchemaPath($to_version); + if ($dbFile === null || !$DB->runFile($dbFile)) { + $migration->addWarningMessage("Error creating tables : " . $DB->error()); + $updateresult = false; + } + + // ************ Keep it at the end ************** + $migration->executeMigration(); + + return $updateresult; +} diff --git a/install/migration/update_1.1.0_to_1.2.0/01_rename_carbonintensitysource.php b/install/migration/update_1.1.0_to_1.2.0/01_rename_carbonintensitysource.php new file mode 100644 index 00000000..795e235b --- /dev/null +++ b/install/migration/update_1.1.0_to_1.2.0/01_rename_carbonintensitysource.php @@ -0,0 +1,64 @@ +. + * + * ------------------------------------------------------------------------- + */ + +/** @var DBmysql $DB */ +/** @var Migration $migration */ + +// Rename CarbonIntensitySource +// Move data to new table +$old_table = 'glpi_plugin_carbon_carbonintensitysources'; +$new_table = 'glpi_plugin_carbon_sources'; +$migration->renameTable($old_table, $new_table); + +// Rename CarbonIntensitySource_Zone +$old_table = 'glpi_plugin_carbon_carbonintensitysources_zones'; +$new_table = 'glpi_plugin_carbon_sources_zones'; +$migration->renameTable($old_table, $new_table); + +$table = 'glpi_plugin_carbon_carbonintensities'; +$migration->changeField($table, 'plugin_carbon_carbonintensitysources_id', 'plugin_carbon_sources_id', 'fkey'); + +$table = 'glpi_plugin_carbon_zones'; +$migration->changeField($table, 'plugin_carbon_carbonintensitysources_id_historical', 'plugin_carbon_sources_id_historical', 'fkey'); +$migration->dropKey($table, 'plugin_carbon_carbonintensitysources_id_historical'); +$migration->addKey($table, 'plugin_carbon_sources_id_historical', 'plugin_carbon_sources_id_historical'); + +$table = 'glpi_plugin_carbon_sources_zones'; +$migration->changeField($table, 'plugin_carbon_carbonintensitysources_id', 'plugin_carbon_sources_id', 'fkey'); + +// Migrate tables now and clear cache to avoid issues in subsequent upgrade tasks +$migration->migrationOneTable('glpi_plugin_carbon_carbonintensities'); +$DB->listFields('glpi_plugin_carbon_carbonintensities', false); +$migration->migrationOneTable('glpi_plugin_carbon_sources_zones'); +$DB->listFields('glpi_plugin_carbon_sources_zones', false); +$migration->migrationOneTable('glpi_plugin_carbon_zones'); +$DB->listFields('glpi_plugin_carbon_zones', false); diff --git a/install/migration/update_1.1.0_to_1.2.0/02_update_tables_schema.php b/install/migration/update_1.1.0_to_1.2.0/02_update_tables_schema.php new file mode 100644 index 00000000..401135f8 --- /dev/null +++ b/install/migration/update_1.1.0_to_1.2.0/02_update_tables_schema.php @@ -0,0 +1,56 @@ +. + * + * ------------------------------------------------------------------------- + */ + +/** @var DBmysql $DB */ +/** @var Migration $migration */ + +$table = 'glpi_plugin_carbon_sources'; +$migration->addField( + $table, + 'is_carbon_intensity_source', + 'bool', + [ + 'after' => 'is_fallback', + 'update' => 1, + 'condition' => "WHERE `name` IN ('RTE', 'ElectricityMap', 'Ember - Energy Institute', 'Hydro Quebec')" + ] +); + +$table = 'glpi_plugin_carbon_locations'; +$migration->addField( + $table, + 'plugin_carbon_sources_zones_id', + 'fkey', + [ + 'after' => 'boavizta_zone' + ] +); diff --git a/install/migration/update_1.1.0_to_1.2.0/03_RTE_zone.php b/install/migration/update_1.1.0_to_1.2.0/03_RTE_zone.php new file mode 100644 index 00000000..45d9b451 --- /dev/null +++ b/install/migration/update_1.1.0_to_1.2.0/03_RTE_zone.php @@ -0,0 +1,42 @@ +. + * + * ------------------------------------------------------------------------- + */ + +use GlpiPlugin\Carbon\Install; + +/** @var Migration $migration */ +/** @var DBmysql $DB */ + +// Force immediate migration of this table to let the subsequent code work +// with the up to date schema +$rte_source = Install::getOrCreateSource('RTE', 0, 1); +$france_zone = Install::getOrCreateZone('France', $rte_source); +Install::linkSourceZone($rte_source, $france_zone); diff --git a/install/migration/update_1.1.0_to_1.2.0/04_update_location_zone_relation.php b/install/migration/update_1.1.0_to_1.2.0/04_update_location_zone_relation.php new file mode 100644 index 00000000..b3ac2a81 --- /dev/null +++ b/install/migration/update_1.1.0_to_1.2.0/04_update_location_zone_relation.php @@ -0,0 +1,124 @@ +. + * + * ------------------------------------------------------------------------- + */ + +use Glpi\DBAL\QueryExpression; + +/** @var DBmysql $DB */ +global $DB; + +// Migrate relations based on a country +$glpi_location_table = 'glpi_locations'; +$zone_table = 'glpi_plugin_carbon_zones'; +$source_zone_table = 'glpi_plugin_carbon_sources_zones'; +$iterator = $DB->request([ + 'SELECT' => [ + $glpi_location_table . '.id as locations_id', + $zone_table . '.plugin_carbon_sources_id_historical', + $zone_table . '.id as plugin_carbon_zones_id', + $source_zone_table . '.id as plugin_carbon_sources_zones_id', + ], + 'FROM' => $glpi_location_table, + 'INNER JOIN' => [ + $zone_table => [ + 'FKEY' => [ + $zone_table => 'name', + $glpi_location_table => 'country', + ] + ], + $source_zone_table => [ + 'FKEY' => [ + $source_zone_table => 'plugin_carbon_zones_id', + $zone_table => 'id', + [ + 'AND' => [ + new QueryExpression('`' . $source_zone_table . '`.`plugin_carbon_sources_id` = `' . $zone_table . '`.`plugin_carbon_sources_id_historical`'), + ] + ] + ] + ] + ] +]); + +$location_table = 'glpi_plugin_carbon_locations'; +foreach ($iterator as $row) { + $where = [ + 'locations_id' => $row['locations_id'], + ]; + $params = [ + 'plugin_carbon_sources_zones_id' => $row['plugin_carbon_sources_zones_id'], + ]; + $DB->updateOrInsert($location_table, $params, $where); +} + +// Migrate relations based on a state +$glpi_location_table = 'glpi_locations'; +$zone_table = 'glpi_plugin_carbon_zones'; +$source_zone_table = 'glpi_plugin_carbon_sources_zones'; +$iterator = $DB->request([ + 'SELECT' => [ + $glpi_location_table . '.id as locations_id', + $zone_table . '.plugin_carbon_sources_id_historical', + $zone_table . '.id as plugin_carbon_zones_id', + $source_zone_table . '.id as plugin_carbon_sources_zones_id', + ], + 'FROM' => $glpi_location_table, + 'INNER JOIN' => [ + $zone_table => [ + 'FKEY' => [ + $zone_table => 'name', + $glpi_location_table => 'state', + ] + ], + $source_zone_table => [ + 'FKEY' => [ + $source_zone_table => 'plugin_carbon_zones_id', + $zone_table => 'id', + [ + 'AND' => [ + new QueryExpression('`' . $source_zone_table . '`.`plugin_carbon_sources_id` = `' . $zone_table . '`.`plugin_carbon_sources_id_historical`'), + ] + ] + ] + ] + ] +]); + +$location_table = 'glpi_plugin_carbon_locations'; +foreach ($iterator as $row) { + $where = [ + 'locations_id' => $row['locations_id'], + ]; + $params = [ + 'plugin_carbon_sources_zones_id' => $row['plugin_carbon_sources_zones_id'], + ]; + $DB->updateOrInsert($location_table, $params, $where); +} diff --git a/install/mysql/plugin_carbon_1.1.0_empty.sql b/install/mysql/plugin_carbon_1.1.0_empty.sql new file mode 100644 index 00000000..2758eee4 --- /dev/null +++ b/install/mysql/plugin_carbon_1.1.0_empty.sql @@ -0,0 +1,191 @@ +-- +-- ------------------------------------------------------------------------- +-- Carbon plugin for GLPI +-- +-- @copyright Copyright (C) 2024-2025 Teclib' and contributors. +-- @license https://www.gnu.org/licenses/gpl-3.0.txt GPLv3+ +-- @license MIT https://opensource.org/licenses/mit-license.php +-- @link https://github.com/pluginsGLPI/carbon +-- +-- ------------------------------------------------------------------------- +-- +-- LICENSE +-- +-- This file is part of Carbon plugin for 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 . +-- +-- ------------------------------------------------------------------------- +-- + +CREATE TABLE IF NOT EXISTS `glpi_plugin_carbon_carbonemissions` ( + `id` int unsigned NOT NULL AUTO_INCREMENT, + `itemtype` varchar(255) DEFAULT NULL, + `items_id` int unsigned NOT NULL DEFAULT '0', + `engine` varchar(255) DEFAULT NULL, + `engine_version` varchar(255) DEFAULT NULL, + `date_mod` timestamp NULL DEFAULT NULL, + `entities_id` int unsigned NOT NULL DEFAULT '0', + `types_id` int unsigned NOT NULL DEFAULT '0', + `models_id` int unsigned NOT NULL DEFAULT '0', + `locations_id` int unsigned NOT NULL DEFAULT '0', + `energy_per_day` float DEFAULT '0' COMMENT 'KWh', + `emission_per_day` float DEFAULT '0' COMMENT 'gCO2eq', + `date` timestamp NULL DEFAULT NULL, + `energy_quality` int unsigned NOT NULL DEFAULT '0' COMMENT 'DataTtacking\\AbstractTracked::DATA_QUALITY_* constants', + `emission_quality` int unsigned NOT NULL DEFAULT '0' COMMENT 'DataTtacking\\AbstractTracked::DATA_QUALITY_* constants', + PRIMARY KEY (`id`), + UNIQUE KEY `unicity` (`itemtype`, `items_id`, `date`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS `glpi_plugin_carbon_carbonintensities` ( + `id` int unsigned NOT NULL AUTO_INCREMENT, + `date` timestamp NULL DEFAULT NULL, + `plugin_carbon_carbonintensitysources_id` int unsigned NOT NULL DEFAULT '0', + `plugin_carbon_zones_id` int unsigned NOT NULL DEFAULT '0', + `intensity` float DEFAULT '0' COMMENT 'gCO2eq/KWh', + `data_quality` int unsigned NOT NULL DEFAULT '0' COMMENT 'DataTtacking\\AbstractTracked::DATA_QUALITY_* constants', + PRIMARY KEY (`id`), + UNIQUE KEY `unicity` (`date`, `plugin_carbon_carbonintensitysources_id`, `plugin_carbon_zones_id`), + INDEX `date` (`date`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS `glpi_plugin_carbon_zones` ( + `id` int unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(255) DEFAULT NULL, + `entities_id` int unsigned NOT NULL DEFAULT '0', + `plugin_carbon_carbonintensitysources_id_historical` int unsigned NOT NULL DEFAULT '0' COMMENT 'Source to be used for historical calculation', + PRIMARY KEY (`id`), + UNIQUE KEY `unicity` (`name`), + INDEX `entities_id` (`entities_id`), + INDEX `plugin_carbon_carbonintensitysources_id_historical` (`plugin_carbon_carbonintensitysources_id_historical`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS `glpi_plugin_carbon_carbonintensitysources` ( + `id` int unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(255) DEFAULT NULL, + `is_fallback` tinyint NOT NULL DEFAULT '0' COMMENT 'Fallback source for carbon intensity', + PRIMARY KEY (`id`), + UNIQUE KEY `unicity` (`name`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS `glpi_plugin_carbon_carbonintensitysources_zones` ( + `id` int unsigned NOT NULL AUTO_INCREMENT, + `plugin_carbon_carbonintensitysources_id` int unsigned NOT NULL DEFAULT '0', + `plugin_carbon_zones_id` int unsigned NOT NULL DEFAULT '0', + `code` varchar(255) DEFAULT NULL COMMENT 'Zone identifier in the API of the source', + `is_download_enabled` tinyint NOT NULL DEFAULT '0' COMMENT 'Download enabled from the source for this zone', + PRIMARY KEY (`id`), + UNIQUE KEY `unicity` (`plugin_carbon_carbonintensitysources_id`, `plugin_carbon_zones_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS `glpi_plugin_carbon_computertypes` ( + `id` int unsigned NOT NULL AUTO_INCREMENT, + `computertypes_id` int unsigned NOT NULL DEFAULT '0', + `power_consumption` int DEFAULT '0', + `category` int NOT NULL DEFAULT '0' COMMENT 'ComputerType::CATEGORY_* constants', + PRIMARY KEY (`id`), + UNIQUE KEY `unicity` (`computertypes_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS `glpi_plugin_carbon_computerusageprofiles` ( + `id` int unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(255) DEFAULT NULL, + `time_start` varchar(255) DEFAULT NULL, + `time_stop` varchar(255) DEFAULT NULL, + `day_1` tinyint NOT NULL DEFAULT '0', + `day_2` tinyint NOT NULL DEFAULT '0', + `day_3` tinyint NOT NULL DEFAULT '0', + `day_4` tinyint NOT NULL DEFAULT '0', + `day_5` tinyint NOT NULL DEFAULT '0', + `day_6` tinyint NOT NULL DEFAULT '0', + `day_7` tinyint NOT NULL DEFAULT '0', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS `glpi_plugin_carbon_embodiedimpacts` ( + `id` int unsigned NOT NULL AUTO_INCREMENT, + `itemtype` varchar(255) DEFAULT NULL, + `items_id` int unsigned NOT NULL DEFAULT '0', + `engine` varchar(255) DEFAULT NULL, + `engine_version` varchar(255) DEFAULT NULL, + `date_mod` timestamp NULL DEFAULT NULL, + `gwp` float unsigned DEFAULT '0' COMMENT '(unit gCO2eq) Global warming potential', + `gwp_quality` int unsigned NOT NULL DEFAULT '0' COMMENT 'DataTtacking\\AbstractTracked::DATA_QUALITY_* constants', + `adp` float unsigned DEFAULT '0' COMMENT '(unit gSbeq) Abiotic depletion potential', + `adp_quality` int unsigned NOT NULL DEFAULT '0' COMMENT 'DataTtacking\\AbstractTracked::DATA_QUALITY_* constants', + `pe` float unsigned DEFAULT '0' COMMENT '(unit J) Primary energy', + `pe_quality` int unsigned NOT NULL DEFAULT '0' COMMENT 'DataTtacking\\AbstractTracked::DATA_QUALITY_* constants', + PRIMARY KEY (`id`), + UNIQUE KEY `unicity` (`itemtype`, `items_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS `glpi_plugin_carbon_environmentalimpacts` ( + `id` int unsigned NOT NULL AUTO_INCREMENT, + `computers_id` int unsigned NOT NULL DEFAULT '0', + `plugin_carbon_computerusageprofiles_id` int unsigned NOT NULL DEFAULT '0', + PRIMARY KEY (`id`), + UNIQUE KEY `unicity` (`computers_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS `glpi_plugin_carbon_monitortypes` ( + `id` int unsigned NOT NULL AUTO_INCREMENT, + `monitortypes_id` int unsigned NOT NULL DEFAULT '0', + `power_consumption` int DEFAULT '0', + PRIMARY KEY (`id`), + UNIQUE KEY `unicity` (`monitortypes_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS `glpi_plugin_carbon_networkequipmenttypes` ( + `id` int unsigned NOT NULL AUTO_INCREMENT, + `networkequipmenttypes_id` int unsigned NOT NULL DEFAULT '0', + `power_consumption` int DEFAULT '0', + PRIMARY KEY (`id`), + UNIQUE KEY `unicity` (`networkequipmenttypes_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS `glpi_plugin_carbon_locations` ( + `id` int unsigned NOT NULL AUTO_INCREMENT, + `locations_id` int unsigned NOT NULL DEFAULT '0', + `boavizta_zone` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `unicity` (`locations_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS `glpi_plugin_carbon_usageinfos` ( + `id` int unsigned NOT NULL AUTO_INCREMENT, + `itemtype` varchar(255) DEFAULT NULL, + `items_id` int unsigned NOT NULL DEFAULT '0', + `plugin_carbon_computerusageprofiles_id` int unsigned NOT NULL DEFAULT '0', + `planned_lifespan` int unsigned NOT NULL DEFAULT '0' COMMENT '(unit months)', + PRIMARY KEY (`id`), + UNIQUE KEY `unicity` (`itemtype`, `items_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS `glpi_plugin_carbon_usageimpacts` ( + `id` int unsigned NOT NULL AUTO_INCREMENT, + `itemtype` varchar(255) DEFAULT NULL, + `items_id` int unsigned NOT NULL DEFAULT '0', + `engine` varchar(255) DEFAULT NULL, + `engine_version` varchar(255) DEFAULT NULL, + `date_mod` timestamp NULL DEFAULT NULL, + `gwp` float unsigned DEFAULT '0' COMMENT '(unit gCO2eq) Global warming potential', + `gwp_quality` int unsigned NOT NULL DEFAULT '0' COMMENT 'DataTtacking\\AbstractTracked::DATA_QUALITY_* constants', + `adp` float unsigned DEFAULT '0' COMMENT '(unit gSbeq) Abiotic depletion potential', + `adp_quality` int unsigned NOT NULL DEFAULT '0' COMMENT 'DataTtacking\\AbstractTracked::DATA_QUALITY_* constants', + `pe` float unsigned DEFAULT '0' COMMENT '(unit J) Primary energy', + `pe_quality` int unsigned NOT NULL DEFAULT '0' COMMENT 'DataTtacking\\AbstractTracked::DATA_QUALITY_* constants', + PRIMARY KEY (`id`), + UNIQUE KEY `unicity` (`itemtype`, `items_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; diff --git a/install/mysql/plugin_carbon_empty.sql b/install/mysql/plugin_carbon_empty.sql index 2758eee4..a7fcc0fa 100644 --- a/install/mysql/plugin_carbon_empty.sql +++ b/install/mysql/plugin_carbon_empty.sql @@ -50,44 +50,45 @@ CREATE TABLE IF NOT EXISTS `glpi_plugin_carbon_carbonemissions` ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; CREATE TABLE IF NOT EXISTS `glpi_plugin_carbon_carbonintensities` ( - `id` int unsigned NOT NULL AUTO_INCREMENT, - `date` timestamp NULL DEFAULT NULL, - `plugin_carbon_carbonintensitysources_id` int unsigned NOT NULL DEFAULT '0', - `plugin_carbon_zones_id` int unsigned NOT NULL DEFAULT '0', - `intensity` float DEFAULT '0' COMMENT 'gCO2eq/KWh', - `data_quality` int unsigned NOT NULL DEFAULT '0' COMMENT 'DataTtacking\\AbstractTracked::DATA_QUALITY_* constants', + `id` int unsigned NOT NULL AUTO_INCREMENT, + `date` timestamp NULL DEFAULT NULL, + `plugin_carbon_sources_id` int unsigned NOT NULL DEFAULT '0', + `plugin_carbon_zones_id` int unsigned NOT NULL DEFAULT '0', + `intensity` float DEFAULT '0' COMMENT 'gCO2eq/KWh', + `data_quality` int unsigned NOT NULL DEFAULT '0' COMMENT 'DataTtacking\\AbstractTracked::DATA_QUALITY_* constants', PRIMARY KEY (`id`), - UNIQUE KEY `unicity` (`date`, `plugin_carbon_carbonintensitysources_id`, `plugin_carbon_zones_id`), + UNIQUE KEY `unicity` (`date`, `plugin_carbon_sources_id`, `plugin_carbon_zones_id`), INDEX `date` (`date`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; CREATE TABLE IF NOT EXISTS `glpi_plugin_carbon_zones` ( - `id` int unsigned NOT NULL AUTO_INCREMENT, - `name` varchar(255) DEFAULT NULL, - `entities_id` int unsigned NOT NULL DEFAULT '0', - `plugin_carbon_carbonintensitysources_id_historical` int unsigned NOT NULL DEFAULT '0' COMMENT 'Source to be used for historical calculation', + `id` int unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(255) DEFAULT NULL, + `entities_id` int unsigned NOT NULL DEFAULT '0', + `plugin_carbon_sources_id_historical` int unsigned NOT NULL DEFAULT '0' COMMENT 'Source to be used for historical calculation', PRIMARY KEY (`id`), UNIQUE KEY `unicity` (`name`), INDEX `entities_id` (`entities_id`), - INDEX `plugin_carbon_carbonintensitysources_id_historical` (`plugin_carbon_carbonintensitysources_id_historical`) + INDEX `plugin_carbon_sources_id_historical` (`plugin_carbon_sources_id_historical`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -CREATE TABLE IF NOT EXISTS `glpi_plugin_carbon_carbonintensitysources` ( - `id` int unsigned NOT NULL AUTO_INCREMENT, - `name` varchar(255) DEFAULT NULL, - `is_fallback` tinyint NOT NULL DEFAULT '0' COMMENT 'Fallback source for carbon intensity', +CREATE TABLE IF NOT EXISTS `glpi_plugin_carbon_sources` ( + `id` int unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(255) DEFAULT NULL, + `is_fallback` tinyint NOT NULL DEFAULT '0' COMMENT 'Fallback source for carbon intensity', + `is_carbon_intensity_source` tinyint NOT NULL DEFAULT '0' COMMENT 'provides carbon intensity', PRIMARY KEY (`id`), UNIQUE KEY `unicity` (`name`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -CREATE TABLE IF NOT EXISTS `glpi_plugin_carbon_carbonintensitysources_zones` ( +CREATE TABLE IF NOT EXISTS `glpi_plugin_carbon_sources_zones` ( `id` int unsigned NOT NULL AUTO_INCREMENT, - `plugin_carbon_carbonintensitysources_id` int unsigned NOT NULL DEFAULT '0', + `plugin_carbon_sources_id` int unsigned NOT NULL DEFAULT '0', `plugin_carbon_zones_id` int unsigned NOT NULL DEFAULT '0', `code` varchar(255) DEFAULT NULL COMMENT 'Zone identifier in the API of the source', `is_download_enabled` tinyint NOT NULL DEFAULT '0' COMMENT 'Download enabled from the source for this zone', PRIMARY KEY (`id`), - UNIQUE KEY `unicity` (`plugin_carbon_carbonintensitysources_id`, `plugin_carbon_zones_id`) + UNIQUE KEY `unicity` (`plugin_carbon_sources_id`, `plugin_carbon_zones_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; CREATE TABLE IF NOT EXISTS `glpi_plugin_carbon_computertypes` ( @@ -156,9 +157,10 @@ CREATE TABLE IF NOT EXISTS `glpi_plugin_carbon_networkequipmenttypes` ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; CREATE TABLE IF NOT EXISTS `glpi_plugin_carbon_locations` ( - `id` int unsigned NOT NULL AUTO_INCREMENT, - `locations_id` int unsigned NOT NULL DEFAULT '0', - `boavizta_zone` varchar(255) DEFAULT NULL, + `id` int unsigned NOT NULL AUTO_INCREMENT, + `locations_id` int unsigned NOT NULL DEFAULT '0', + `boavizta_zone` varchar(255) DEFAULT NULL, + `plugin_carbon_sources_zones_id` int unsigned NOT NULL DEFAULT '0', PRIMARY KEY (`id`), UNIQUE KEY `unicity` (`locations_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; diff --git a/js/carbon.js b/js/carbon.js index 530bea44..ea8ad782 100644 --- a/js/carbon.js +++ b/js/carbon.js @@ -27,3 +27,17 @@ * * ------------------------------------------------------------------------- */ + +window.GLPIPlugin = window.GLPIPlugin || {}; + +window.GLPIPlugin.Carbon = { + onSourceChange: function() { + var value = document.querySelector("select[name='plugin_carbon_sources_id']").value; + var zoneDropdown = document.querySelector("select[name='plugin_carbon_zones_id']").closest('div.form-field'); + if (value == 0 && !zoneDropdown.classList.contains('d-none')) { + zoneDropdown.classList.add('d-none'); + } else if (value != 0 && zoneDropdown.classList.contains('d-none')) { + zoneDropdown.classList.remove('d-none'); + } + } +}; diff --git a/phpunit.xml b/phpunit.xml index 6de88c45..34ac3cc1 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -42,5 +42,8 @@ ./tests/upgrade/ + + ./tests/migration/ + diff --git a/setup.php b/setup.php index e9cfdd45..8bc52c66 100644 --- a/setup.php +++ b/setup.php @@ -40,8 +40,9 @@ use Location as GlpiLocation; use Profile as GlpiProfile; use GlpiPlugin\Carbon\Dashboard\Grid; +use GlpiPlugin\Carbon\Location; -define('PLUGIN_CARBON_VERSION', '1.1.0-dev'); +define('PLUGIN_CARBON_VERSION', '1.2.0-dev'); define('PLUGIN_CARBON_SCHEMA_VERSION', '1.1.0'); // Minimal GLPI version, inclusive @@ -113,7 +114,7 @@ function plugin_carbon_setupHooks() // asset's type $PLUGIN_HOOKS[Hooks::PRE_ITEM_PURGE]['carbon'][$itemtype . 'Type'] = 'plugin_carbon_hook_pre_purge_assettype'; } - $PLUGIN_HOOKS[Hooks::POST_ITEM_FORM]['carbon'] = 'plugin_carbon_postItemForm'; + // $PLUGIN_HOOKS[Hooks::POST_ITEM_FORM]['carbon'] = 'plugin_carbon_postItemForm'; // Actions taken on locations events $PLUGIN_HOOKS[Hooks::ITEM_ADD]['carbon'][GlpiLocation::class] = 'plugin_carbon_locationAdd'; @@ -125,6 +126,7 @@ function plugin_carbon_setupHooks() $PLUGIN_HOOKS[Hooks::PRE_ITEM_ADD]['carbon'][GlpiProfile::class] = 'plugin_carbon_profileAdd'; $PLUGIN_HOOKS[Hooks::ADD_JAVASCRIPT]['carbon'][] = 'lib/apexcharts.js'; + $PLUGIN_HOOKS[Hooks::ADD_JAVASCRIPT]['carbon'][] = 'lib/carbon.js'; // Import CSS $PLUGIN_HOOKS[Hooks::ADD_CSS]['carbon'][] = 'lib/carbon.css'; @@ -138,6 +140,7 @@ function plugin_carbon_registerClasses() { Plugin::registerClass(Config::class, ['addtabon' => GlpiConfig::class]); Plugin::registerClass(Profile::class, ['addtabon' => GlpiProfile::class]); + Plugin::registerClass(Location::class, ['addtabon' => GlpiLocation::class]); foreach (PLUGIN_CARBON_TYPES as $itemtype) { $item_type_class = 'GlpiPlugin\\Carbon\\' . $itemtype . 'Type'; diff --git a/src/CarbonIntensity.php b/src/CarbonIntensity.php index e6b067a6..a319562e 100644 --- a/src/CarbonIntensity.php +++ b/src/CarbonIntensity.php @@ -38,7 +38,7 @@ use DateTimeImmutable; use DateTimeInterface; use DBmysql; -use GlpiPlugin\Carbon\CarbonIntensitySource; +use GlpiPlugin\Carbon\Source; use GlpiPlugin\Carbon\Zone; use Glpi\DBAL\QueryParam; use GlpiPlugin\Carbon\DataSource\CarbonIntensity\ClientInterface; @@ -92,9 +92,9 @@ public function rawSearchOptions() $tab[] = [ 'id' => SearchOptions::CARBON_INTENSITY_SOURCE, - 'table' => CarbonIntensitySource::getTable(), + 'table' => Source::getTable(), 'field' => 'name', - 'name' => CarbonIntensitySource::getTypeName(1), + 'name' => Source::getTypeName(1), 'massiveaction' => false, // implicit field is id 'datatype' => 'dropdown', ]; @@ -131,7 +131,7 @@ public function rawSearchOptions() private function getKnownDatesQuery(string $zone_name, string $source_name) { $intensity_table = CarbonIntensity::getTable(); - $source_table = CarbonIntensitySource::getTable(); + $source_table = Source::getTable(); $zone_table = Zone::getTable(); return [ 'SELECT' => [$intensity_table => ['id', 'date']], @@ -139,7 +139,7 @@ private function getKnownDatesQuery(string $zone_name, string $source_name) 'INNER JOIN' => [ $source_table => [ 'FKEY' => [ - $intensity_table => CarbonIntensitySource::getForeignKeyField(), + $intensity_table => Source::getForeignKeyField(), $source_table => 'id', ] ], @@ -151,7 +151,7 @@ private function getKnownDatesQuery(string $zone_name, string $source_name) ] ], 'WHERE' => [ - CarbonIntensitySource::getTableField('name') => $source_name, + Source::getTableField('name') => $source_name, Zone::getTableField('name') => $zone_name ], ]; @@ -218,7 +218,7 @@ public function downloadOneZone(ClientInterface $data_source, string $zone_name, $total_count = 0; // Check if there are gaps to fill - $source = new CarbonIntensitySource(); + $source = new Source(); $source->getFromDBByCrit(['name' => $data_source->getSourceName()]); $zone = new Zone(); $zone->getFromDBByCrit(['name' => $zone_name]); @@ -334,7 +334,7 @@ public function save(string $zone_name, string $source_name, array $data): int global $DB; $count = 0; - $source = new CarbonIntensitySource(); + $source = new Source(); $source->getFromDBByCrit([ 'name' => $source_name, ]); @@ -357,7 +357,7 @@ public function save(string $zone_name, string $source_name, array $data): int CarbonIntensity::getTable(), [ 'date' => new QueryParam(), - CarbonIntensitySource::getForeignKeyField() => new QueryParam(), + Source::getForeignKeyField() => new QueryParam(), Zone::getForeignKeyField() => new QueryParam(), 'intensity' => new QueryParam(), 'data_quality' => new QueryParam(), @@ -399,7 +399,7 @@ public function save(string $zone_name, string $source_name, array $data): int public function findGaps(int $source_id, int $zone_id, DateTimeInterface $start, ?DateTimeInterface $stop = null): array { $criteria = [ - CarbonIntensitySource::getForeignKeyField() => $source_id, + Source::getForeignKeyField() => $source_id, Zone::getForeignKeyField() => $zone_id, ]; $interval = new DateInterval('PT1H'); diff --git a/src/Command/CollectCarbonIntensityCommand.php b/src/Command/CollectCarbonIntensityCommand.php index 370f160f..9f26b90b 100644 --- a/src/Command/CollectCarbonIntensityCommand.php +++ b/src/Command/CollectCarbonIntensityCommand.php @@ -36,10 +36,10 @@ use DateTimeImmutable; use Glpi\Console\AbstractCommand; use GlpiPlugin\Carbon\CarbonIntensity; -use GlpiPlugin\Carbon\CarbonIntensitySource; -use GlpiPlugin\Carbon\CarbonIntensitySource_Zone; +use GlpiPlugin\Carbon\Source_Zone; use GlpiPlugin\Carbon\DataSource\CarbonIntensity\ClientFactory; use GlpiPlugin\Carbon\DataSource\CarbonIntensity\ClientInterface; +use GlpiPlugin\Carbon\Source; use GlpiPlugin\Carbon\Zone; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Helper\ProgressBar; @@ -76,7 +76,7 @@ protected function interact(InputInterface $input, OutputInterface $output) // Set data source argument if not provided if (is_null($input->getArgument('source'))) { $question_helper = new QuestionHelper(); - $choices = (new CarbonIntensitySource())->getDownloadableSources(); + $choices = (new Source())->getDownloadableSources(); $choices = ClientFactory::getClientNames(); $question = new ChoiceQuestion(__('Source:', 'carbon'), array_values($choices)); $value = $question_helper->ask($input, $output, $question); @@ -118,7 +118,7 @@ protected function execute(InputInterface $input, OutputInterface $output) $output->writeln("$message"); // Create the source if it does not exist - $data_source = new CarbonIntensitySource(); + $data_source = new Source(); $source_name = $input->getArgument('source'); if (!$data_source->getFromDBByCrit(['name' => $source_name])) { $data_source->add([ @@ -139,7 +139,7 @@ protected function execute(InputInterface $input, OutputInterface $output) if (!$zone->getID()) { $zone->add([ 'name' => $this->zones[$zone_code], - 'plugin_carbon_carbonintensitysources_id_historical' => $data_source->getID(), + 'plugin_carbon_sources_id_historical' => $data_source->getID(), ]); if ($zone->isNewItem()) { $message = __("Zone not found", 'carbon'); @@ -150,7 +150,7 @@ protected function execute(InputInterface $input, OutputInterface $output) $carbon_intensity = new CarbonIntensity(); // Create relation between source and zone if t does not exist - $source_zone = new CarbonIntensitySource_Zone(); + $source_zone = new Source_Zone(); $input = [ 'code' => $zone_code, $data_source::getForeignKeyField() => $data_source->getID(), diff --git a/src/Command/CreateFakeCarbonIntensityCommand.php b/src/Command/CreateFakeCarbonIntensityCommand.php index 8090b8f9..b65ef0b3 100644 --- a/src/Command/CreateFakeCarbonIntensityCommand.php +++ b/src/Command/CreateFakeCarbonIntensityCommand.php @@ -37,7 +37,7 @@ use DateTimeZone; use GlpiPlugin\Carbon\CarbonIntensity; use GlpiPlugin\Carbon\Zone; -use GlpiPlugin\Carbon\CarbonIntensitySource; +use GlpiPlugin\Carbon\Source; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Helper\ProgressBar; use Symfony\Component\Console\Input\InputInterface; @@ -66,7 +66,7 @@ protected function execute(InputInterface $input, OutputInterface $output) $message = __("Creating data source name", 'carbon'); $output->writeln("$message"); - $dataSource = new CarbonIntensitySource(); + $dataSource = new Source(); $source_name = 'Fake data'; if (!$dataSource->getFromDBByCrit(['name' => $source_name])) { $dataSource->add([ @@ -117,7 +117,7 @@ protected function generateFakeData(DateTime $start_date, DateTime $end_date) $carbon_intensity = new CarbonIntensity(); foreach ($intensities as $date => $intensity) { $carbon_intensity->add([ - 'plugin_carbon_carbonintensitysources_id' => $this->source_id, + 'plugin_carbon_sources_id' => $this->source_id, 'plugin_carbon_zones_id' => $this->zone_id, 'date' => $date, // Eco2mix seems to provide datetime in 'intensity' => $intensity, diff --git a/src/CronTask.php b/src/CronTask.php index 9038dbc8..1ec0cfb3 100644 --- a/src/CronTask.php +++ b/src/CronTask.php @@ -171,7 +171,7 @@ public static function cronEmbodiedImpact(GlpiCronTask $task): int */ public static function cronDownloadRte(GlpiCronTask $task): int { - $client = ClientFactory::create('rte'); + $client = ClientFactory::create('Rte'); return self::downloadCarbonIntensityFromSource($task, $client, new CarbonIntensity()); } @@ -182,7 +182,7 @@ public static function cronDownloadRte(GlpiCronTask $task): int */ public static function cronDownloadElectricityMap(GlpiCronTask $task): int { - $client = ClientFactory::create('electricitymap'); + $client = ClientFactory::create('ElectricityMap'); return self::downloadCarbonIntensityFromSource($task, $client, new CarbonIntensity()); } @@ -193,7 +193,7 @@ public static function cronDownloadElectricityMap(GlpiCronTask $task): int */ public static function cronDownloadWatttime(GlpiCronTask $task): int { - $client = ClientFactory::create('watttime'); + $client = ClientFactory::create('Watttime'); return self::downloadCarbonIntensityFromSource($task, $client, new CarbonIntensity()); } diff --git a/src/Dashboard/Provider.php b/src/Dashboard/Provider.php index b30c10d0..dbb15e5f 100644 --- a/src/Dashboard/Provider.php +++ b/src/Dashboard/Provider.php @@ -46,7 +46,7 @@ use GlpiPlugin\Carbon\Toolbox; use GlpiPlugin\Carbon\CarbonEmission; use GlpiPlugin\Carbon\CarbonIntensity; -use GlpiPlugin\Carbon\CarbonIntensitySource; +use GlpiPlugin\Carbon\Source; use GlpiPlugin\Carbon\Zone; use GlpiPlugin\Carbon\SearchOptions; use GlpiPlugin\Carbon\UsageImpact; @@ -590,7 +590,7 @@ public static function getCarbonIntensity(array $params): array /** @var DBmysql $DB */ global $DB; - $source = new CarbonIntensitySource(); + $source = new Source(); $zone = new Zone(); $source->getFromDBByCrit([ 'name' => 'RTE' @@ -606,7 +606,7 @@ public static function getCarbonIntensity(array $params): array // ], 'FROM' => CarbonIntensity::getTable(), 'WHERE' => [ - CarbonIntensitySource::getForeignKeyField() => $source->getID(), + Source::getForeignKeyField() => $source->getID(), Zone::getForeignKeyField() => $zone->getID(), ], ]; diff --git a/src/Dashboard/Widget.php b/src/Dashboard/Widget.php index 6dc080b7..dd639208 100644 --- a/src/Dashboard/Widget.php +++ b/src/Dashboard/Widget.php @@ -574,7 +574,11 @@ public static function displayGraphUsageCarbonEmissionPerMonth(array $params = [ $apex_data['labels'] = $data['labels']; $apex_data['xaxis']['categories'] = $data['labels']; - $apex_data['yaxis'][1]['min'] = 0.8 * min(array_column($apex_data['series'][1]['data'], 'y')); + $apex_data['yaxis'][1]['min'] = 0; + $energy = array_column($apex_data['series'][1]['data'], 'y'); + if (count($energy) > 0) { + $apex_data['yaxis'][1]['min'] = 0.8 * min($energy); + } return TemplateRenderer::getInstance()->render('@carbon/dashboard/graph-carbon-emission-per-month.html.twig', [ 'id' => $p['id'], diff --git a/src/DataSource/Boaviztapi.php b/src/DataSource/Boaviztapi.php index 4db15b7d..8fe9f351 100644 --- a/src/DataSource/Boaviztapi.php +++ b/src/DataSource/Boaviztapi.php @@ -35,8 +35,8 @@ use Config; use DBmysql; use Dropdown; -use GlpiPlugin\Carbon\CarbonIntensitySource; -use GlpiPlugin\Carbon\CarbonIntensitySource_Zone; +use GlpiPlugin\Carbon\Source; +use GlpiPlugin\Carbon\Source_Zone; use GlpiPlugin\Carbon\Zone; class Boaviztapi @@ -99,8 +99,8 @@ public function get(string $endpoint, array $options = []): array public function createSource(): bool { $source_name = $this->getSourceName(); - // create a source in CarbonIntensitySource - $source = new CarbonIntensitySource(); + // create a source in Source + $source = new Source(); $source->getFromDBByCrit([ 'name' => $source_name, ]); @@ -136,7 +136,7 @@ public function queryZones(): array */ public function saveZones(array $zones): void { - $source = new CarbonIntensitySource(); + $source = new Source(); $source->getFromDBByCrit([ 'name' => $this->getSourceName(), ]); @@ -161,14 +161,14 @@ public function saveZones(array $zones): void } else { $zone_id = $zone->getID(); } - $source_zone = new CarbonIntensitySource_Zone(); + $source_zone = new Source_Zone(); $source_zone_id = $source_zone->getFromDBByCrit([ - 'plugin_carbon_carbonintensitysources_id' => $source_id, + 'plugin_carbon_sources_id' => $source_id, 'plugin_carbon_zones_id' => $zone_id, ]); if ($source_zone_id === false) { $source_zone_id = $source_zone->add([ - 'plugin_carbon_carbonintensitysources_id' => $source_id, + 'plugin_carbon_sources_id' => $source_id, 'plugin_carbon_zones_id' => $zone_id, ]); if ($source_zone_id === false) { @@ -190,12 +190,12 @@ public static function getZones() global $DB; $zone_table = Zone::getTable(); - $source_table = CarbonIntensitySource::getTable(); - $source_zone_table = CarbonIntensitySource_Zone::getTable(); + $source_table = Source::getTable(); + $source_zone_table = Source_Zone::getTable(); $result = $DB->request([ 'SELECT' => [ Zone::getTableField('name'), - CarbonIntensitySource_Zone::getTableField('code'), + Source_Zone::getTableField('code'), ], 'FROM' => Zone::getTable(), 'INNER JOIN' => [ @@ -207,13 +207,13 @@ public static function getZones() ], $source_table => [ 'FKEY' => [ - $source_zone_table => 'plugin_carbon_carbonintensitysources_id', - CarbonIntensitySource::getTable() => 'id', + $source_zone_table => 'plugin_carbon_sources_id', + Source::getTable() => 'id', ], ], ], 'WHERE' => [ - CarbonIntensitySource::getTableField('name') => self::$source_name, + Source::getTableField('name') => self::$source_name, ], 'ORDER' => Zone::getTableField('name'), ]); @@ -234,7 +234,6 @@ public static function getZones() */ public static function dropdownBoaviztaZone(string $name, array $options = []) { - return Dropdown::showFromArray($name, self::getZones(), $options); } } diff --git a/src/DataSource/CarbonIntensity/AbstractClient.php b/src/DataSource/CarbonIntensity/AbstractClient.php index 415a460b..619f862f 100644 --- a/src/DataSource/CarbonIntensity/AbstractClient.php +++ b/src/DataSource/CarbonIntensity/AbstractClient.php @@ -39,8 +39,8 @@ use DateTimeImmutable; use Toolbox as GlpiToolbox; use GlpiPlugin\Carbon\CarbonIntensity; -use GlpiPlugin\Carbon\CarbonIntensitySource; -use GlpiPlugin\Carbon\CarbonIntensitySource_Zone; +use GlpiPlugin\Carbon\Source; +use GlpiPlugin\Carbon\Source_Zone; use GlpiPlugin\Carbon\Zone; use Symfony\Component\Console\Helper\ProgressBar; @@ -58,11 +58,11 @@ abstract protected function formatOutput(array $response, int $step): array; * Create the source in the database * Should not be called as it shall be created at plugin installation * - * @return CarbonIntensitySource + * @return Source */ - protected function getOrCreateSource(): ?CarbonIntensitySource + protected function getOrCreateSource(): ?Source { - $source = new CarbonIntensitySource(); + $source = new Source(); if (!$source->getFromDBByCrit(['name' => $this->getSourceName()])) { $source->add([ 'name' => $this->getSourceName(), @@ -146,11 +146,11 @@ public function getZones(array $crit = []): array /** @var DBmysql $DB */ global $DB; - $source_table = CarbonIntensitySource::getTable(); - $source_fk = CarbonIntensitySource::getForeignKeyField(); + $source_table = Source::getTable(); + $source_fk = Source::getForeignKeyField(); $zone_table = Zone::getTable(); $zone_fk = Zone::getForeignKeyField(); - $source_zone_table = CarbonIntensitySource_Zone::getTable(); + $source_zone_table = Source_Zone::getTable(); $iterator = $DB->request([ 'SELECT' => Zone::getTableField('name'), 'FROM' => $zone_table, @@ -169,7 +169,7 @@ public function getZones(array $crit = []): array ], ], 'WHERE' => [ - CarbonIntensitySource::getTableField('name') => $this->getSourceName(), + Source::getTableField('name') => $this->getSourceName(), ] + $crit, ]); @@ -310,9 +310,9 @@ protected function sliceDateRangeByDay(DateTimeImmutable $start, DateTimeImmutab } } - protected function toggleZoneDownload(Zone $zone, CarbonIntensitySource $source, ?bool $state): bool + protected function toggleZoneDownload(Zone $zone, Source $source, ?bool $state): bool { - $source_zone = new CarbonIntensitySource_Zone(); + $source_zone = new Source_Zone(); $source_zone->getFromDBByCrit([ $zone->getForeignKeyField() => $zone->getID(), $source->getForeignKeyField() => $source->getID(), diff --git a/src/DataSource/CarbonIntensity/ElectricityMapClient.php b/src/DataSource/CarbonIntensity/ElectricityMapClient.php index b9c05570..becb6ee9 100644 --- a/src/DataSource/CarbonIntensity/ElectricityMapClient.php +++ b/src/DataSource/CarbonIntensity/ElectricityMapClient.php @@ -38,9 +38,9 @@ use DateTimeZone; use DateTimeImmutable; use GlpiPlugin\Carbon\CarbonIntensity; -use GlpiPlugin\Carbon\CarbonIntensitySource; +use GlpiPlugin\Carbon\Source; use GlpiPlugin\Carbon\Zone; -use GlpiPlugin\Carbon\CarbonIntensitySource_Zone; +use GlpiPlugin\Carbon\Source_Zone; use Config as GlpiConfig; use GLPIKey; use GlpiPlugin\Carbon\DataSource\RestApiClientInterface; @@ -120,16 +120,16 @@ public function createZones(): int $zone = new Zone(); if ($zone->getFromDbByCrit($zone_input) === false) { if ($this->enableHistorical($zone_spec['zoneName'])) { - $zone_input['plugin_carbon_carbonintensitysources_id_historical'] = $source_id; + $zone_input['plugin_carbon_sources_id_historical'] = $source_id; } if ($zone->add($zone_input) === false) { $failed = true; continue; } } - $source_zone = new CarbonIntensitySource_Zone(); + $source_zone = new Source_Zone(); $source_zone->add([ - CarbonIntensitySource::getForeignKeyField() => $source_id, + Source::getForeignKeyField() => $source_id, Zone::getForeignKeyField() => $zone->getID(), 'code' => $zone_key, 'is_download_enabled' => Toolbox::isLocationExistForZone($zone->fields['name']), @@ -212,7 +212,7 @@ public function getSupportedZones(): array */ public function fetchDay(DateTimeImmutable $day, string $zone): array { - $source_zone = new CarbonIntensitySource_Zone(); + $source_zone = new Source_Zone(); $zone_code = $source_zone->getFromDbBySourceAndZone($this->getSourceName(), $zone); if ($zone_code === null) { diff --git a/src/DataSource/CarbonIntensity/RteClient.php b/src/DataSource/CarbonIntensity/RteClient.php index 773a9137..72d65edc 100644 --- a/src/DataSource/CarbonIntensity/RteClient.php +++ b/src/DataSource/CarbonIntensity/RteClient.php @@ -38,9 +38,9 @@ use DateTimeInterface; use DateTimeZone; use DBmysql; -use GlpiPlugin\Carbon\CarbonIntensitySource; -use GlpiPlugin\Carbon\CarbonIntensitySource_Zone; use GlpiPlugin\Carbon\DataSource\RestApiClientInterface; +use GlpiPlugin\Carbon\Source; +use GlpiPlugin\Carbon\Source_Zone; use GlpiPlugin\Carbon\Zone; use GlpiPlugin\Carbon\DataTracking\AbstractTracked; use GlpiPlugin\Carbon\Toolbox; @@ -118,21 +118,21 @@ public function createZones(): int 'name' => 'France', ]; if ($zone->getFromDBByCrit($input) === false) { - $input['plugin_carbon_carbonintensitysources_id_historical'] = $source_id; + $input['plugin_carbon_sources_id_historical'] = $source_id; if (!$zone->add($input)) { return -1; } } else { - if ($zone->fields['plugin_carbon_carbonintensitysources_id_historical'] == 0) { - $input['plugin_carbon_carbonintensitysources_id_historical'] = $source_id; + if ($zone->fields['plugin_carbon_sources_id_historical'] == 0) { + $input['plugin_carbon_sources_id_historical'] = $source_id; $input['id'] = $zone->getID(); } $zone->update($input); } - $source_zone = new CarbonIntensitySource_Zone(); + $source_zone = new Source_Zone(); $source_zone->add([ - CarbonIntensitySource::getForeignKeyField() => $source_id, + Source::getForeignKeyField() => $source_id, Zone::getForeignKeyField() => $zone->getID(), 'is_download_enabled' => Toolbox::isLocationExistForZone($zone->fields['name']), ]); diff --git a/src/Engine/V1/AbstractAsset.php b/src/Engine/V1/AbstractAsset.php index 1c13efa9..fc064cc0 100644 --- a/src/Engine/V1/AbstractAsset.php +++ b/src/Engine/V1/AbstractAsset.php @@ -41,8 +41,8 @@ use DbUtils; use DBmysql; use GlpiPlugin\Carbon\CarbonIntensity; -use GlpiPlugin\Carbon\CarbonIntensitySource; -use GlpiPlugin\Carbon\CarbonIntensitySource_Zone; +use GlpiPlugin\Carbon\Source; +use GlpiPlugin\Carbon\Source_Zone; use GlpiPlugin\Carbon\DataTracking\TrackedInt; use GlpiPlugin\Carbon\Zone; use Glpi\DBAL\QueryExpression; @@ -112,7 +112,7 @@ protected function requestCarbonIntensitiesPerDay(DateTimeImmutable $start_time, 'WHERE' => [ 'AND' => [ CarbonIntensity::getTableField('plugin_carbon_zones_id') => $zone->getID(), - CarbonIntensity::getTableField('plugin_carbon_carbonintensitysources_id') => $zone->fields['plugin_carbon_carbonintensitysources_id_historical'], + CarbonIntensity::getTableField('plugin_carbon_sources_id') => $zone->fields['plugin_carbon_sources_id_historical'], [CarbonIntensity::getTableField('date') => ['>=', $start_date_s]], [CarbonIntensity::getTableField('date') => ['<', $stop_date_s]], ], @@ -192,8 +192,8 @@ protected function getFallbackCarbonIntensity(DateTimeInterface $day, Zone $zone global $DB; $carbon_intensity_table = CarbonIntensity::getTable(); - $carbon_intensity_source_zone_table = CarbonIntensitySource_Zone::getTable(); - $carbon_intensity_source_table = CarbonIntensitySource::getTable(); + $carbon_intensity_source_zone_table = Source_Zone::getTable(); + $carbon_intensity_source_table = Source::getTable(); $request = [ 'SELECT' => "$carbon_intensity_table.*", 'FROM' => $carbon_intensity_table, @@ -206,15 +206,15 @@ protected function getFallbackCarbonIntensity(DateTimeInterface $day, Zone $zone ], $carbon_intensity_source_table => [ 'FKEY' => [ - $carbon_intensity_source_zone_table => 'plugin_carbon_carbonintensitysources_id', + $carbon_intensity_source_zone_table => 'plugin_carbon_sources_id', $carbon_intensity_source_table => 'id', ] ] ], 'WHERE' => [ - CarbonIntensitySource::getTableField('is_fallback') => 1, - 'NOT' => [CarbonIntensitySource::getTableField('name') => 'Ember - Energy Institute'], - CarbonIntensitySource_Zone::getTableField('plugin_carbon_zones_id') => $zone->getID(), + Source::getTableField('is_fallback') => 1, + 'NOT' => [Source::getTableField('name') => 'Ember - Energy Institute'], + Source_Zone::getTableField('plugin_carbon_zones_id') => $zone->getID(), CarbonIntensity::getTableField('date') => ['<=', $day->format('Y-m-d H:i:s')], ], 'ORDER' => CarbonIntensity::getTableField('date') . ' DESC', @@ -237,8 +237,8 @@ protected function getFallbackCarbonIntensityFromEmber(DateTimeInterface $day, Z global $DB; $carbon_intensity_table = CarbonIntensity::getTable(); - $carbon_intensity_source_zone_table = CarbonIntensitySource_Zone::getTable(); - $carbon_intensity_source_table = CarbonIntensitySource::getTable(); + $carbon_intensity_source_zone_table = Source_Zone::getTable(); + $carbon_intensity_source_table = Source::getTable(); $request = [ 'SELECT' => "$carbon_intensity_table.*", 'FROM' => $carbon_intensity_table, @@ -251,15 +251,15 @@ protected function getFallbackCarbonIntensityFromEmber(DateTimeInterface $day, Z ], $carbon_intensity_source_table => [ 'FKEY' => [ - $carbon_intensity_source_zone_table => 'plugin_carbon_carbonintensitysources_id', + $carbon_intensity_source_zone_table => 'plugin_carbon_sources_id', $carbon_intensity_source_table => 'id', ] ] ], 'WHERE' => [ - CarbonIntensitySource::getTableField('is_fallback') => 1, - CarbonIntensitySource::getTableField('name') => 'Ember - Energy Institute', - CarbonIntensitySource_Zone::getTableField('plugin_carbon_zones_id') => $zone->getID(), + Source::getTableField('is_fallback') => 1, + Source::getTableField('name') => 'Ember - Energy Institute', + Source_Zone::getTableField('plugin_carbon_zones_id') => $zone->getID(), CarbonIntensity::getTableField('date') => ['<=', $day->format('Y-m-d H:i:s')], ], 'ORDER' => CarbonIntensity::getTableField('date') . ' DESC', @@ -271,14 +271,14 @@ protected function getFallbackCarbonIntensityFromEmber(DateTimeInterface $day, Z } // No result, try to find a zone by country - $zone = new Zone(); - $zone->getByItem($this->item, null, true); $result = $DB->request($request); if ($result->count() === 1) { return $result->current(); } // Still no result, fallback to the world carbon intensity + $zone = new Zone(); + $zone->getByAsset($this->item); return $this->getFallbackCarbonIntensityForEmberWorldwide($day, $zone); } @@ -288,8 +288,8 @@ public function getFallbackCarbonIntensityForEmberWorldwide(DateTimeInterface $d global $DB; $carbon_intensity_table = CarbonIntensity::getTable(); - $carbon_intensity_source_zone_table = CarbonIntensitySource_Zone::getTable(); - $carbon_intensity_source_table = CarbonIntensitySource::getTable(); + $carbon_intensity_source_zone_table = Source_Zone::getTable(); + $carbon_intensity_source_table = Source::getTable(); $carbon_intensity_zone_table = Zone::getTable(); $request = [ 'SELECT' => "$carbon_intensity_table.*", @@ -303,7 +303,7 @@ public function getFallbackCarbonIntensityForEmberWorldwide(DateTimeInterface $d ], $carbon_intensity_source_table => [ 'FKEY' => [ - $carbon_intensity_source_zone_table => 'plugin_carbon_carbonintensitysources_id', + $carbon_intensity_source_zone_table => 'plugin_carbon_sources_id', $carbon_intensity_source_table => 'id', ] ], @@ -315,14 +315,14 @@ public function getFallbackCarbonIntensityForEmberWorldwide(DateTimeInterface $d ], $carbon_intensity_source_table => [ 'FKEY' => [ - $carbon_intensity_table => 'plugin_carbon_carbonintensitysources_id', + $carbon_intensity_table => 'plugin_carbon_sources_id', $carbon_intensity_source_table => 'id', ] ], ], 'WHERE' => [ - CarbonIntensitySource::getTableField('is_fallback') => 1, - CarbonIntensitySource::getTableField('name') => 'Ember - Energy Institute', + Source::getTableField('is_fallback') => 1, + Source::getTableField('name') => 'Ember - Energy Institute', Zone::getTableField('name') => 'World', CarbonIntensity::getTableField('date') => ['<=', $day->format('Y-m-d H:i:s')], ], diff --git a/src/Impact/History/AbstractAsset.php b/src/Impact/History/AbstractAsset.php index 5ecc706e..95bb18bd 100644 --- a/src/Impact/History/AbstractAsset.php +++ b/src/Impact/History/AbstractAsset.php @@ -38,15 +38,12 @@ use DateTime; use DateTimeImmutable; use DateTimeInterface; -use DateTimeZone; use DBmysql; -use DbUtils; use GlpiPlugin\Carbon\Zone; use GlpiPlugin\Carbon\CarbonEmission; use GlpiPlugin\Carbon\DataTracking\TrackedFloat; use GlpiPlugin\Carbon\Engine\V1\EngineInterface; use GlpiPlugin\Carbon\Toolbox; -use Location as GlpiLocation; use LogicException; use Session; use Toolbox as GlpiToolbox; @@ -157,9 +154,6 @@ public function evaluateItems(): int */ public function evaluateItem(int $id, ?DateTime $start_date = null, ?DateTime $end_date = null): int { - /** @var DBmysql $DB */ - global $DB; - $itemtype = static::$itemtype; $item = $itemtype::getById($id); if ($item === false) { @@ -188,11 +182,9 @@ public function evaluateItem(int $id, ?DateTime $start_date = null, ?DateTime $e * We NEED to check memory usage to avoid running out of memory * @see DbMysql::doQuery() */ - $memory_limit = GlpiToolbox::getMemoryLimit() - 8 * 1024 * 1024; - if ($memory_limit < 0) { - // May happen in test seems that ini_get("memory_limits") returns - // enpty string in PHPUnit environment - $memory_limit = null; + $memory_limit = GlpiToolbox::getMemoryLimit(); + if ($memory_limit) { + $memory_limit -= 8 * 1024 * 1024; } foreach ($gaps as $gap) { // $date_cursor = DateTime::createFromFormat('U', $gap['start']); @@ -203,6 +195,11 @@ public function evaluateItem(int $id, ?DateTime $start_date = null, ?DateTime $e $date_cursor = DateTime::createFromFormat('Y-m-d H:i:s', $gap['start'])->setTime(0, 0, 0, 0); $end_date = DateTime::createFromFormat('Y-m-d H:i:s', $gap['end'])->setTime(0, 0, 0, 0); while ($date_cursor < $end_date) { + if ($memory_limit && $memory_limit < memory_get_usage()) { + // 8 MB memory left, emergency exit + $this->limit_reached = true; + break 2; + } $success = $this->evaluateItemPerDay($item, $engine, $date_cursor); if ($success) { $count++; @@ -211,11 +208,6 @@ public function evaluateItem(int $id, ?DateTime $start_date = null, ?DateTime $e break 2; } } - if ($memory_limit && $memory_limit < memory_get_usage()) { - // 8 MB memory left, emergency exit - $this->limit_reached = true; - break 2; - } $date_cursor = $date_cursor->add(new DateInterval(static::$date_increment)); } } @@ -235,8 +227,8 @@ protected function evaluateItemPerDay(CommonDBTM $item, EngineInterface $engine, { $energy = $engine->getEnergyPerDay($day); $zone = new Zone(); - $zone->getByItem($item /* ,$date_cursor */); - if ($zone->isNewItem()) { + + if ($zone->getByAsset($item) === false) { return false; } diff --git a/src/Impact/History/Computer.php b/src/Impact/History/Computer.php index c0daf074..971c7339 100644 --- a/src/Impact/History/Computer.php +++ b/src/Impact/History/Computer.php @@ -45,10 +45,10 @@ use Glpi\Application\View\TemplateRenderer; use GlpiPlugin\Carbon\UsageInfo; use GlpiPlugin\Carbon\ComputerUsageProfile; -use GlpiPlugin\Carbon\Location as CarbonLocation; +use GlpiPlugin\Carbon\Location; use GlpiPlugin\Carbon\UsageImpact; use Infocom; -use Location; +use Location as GlpiLocation; class Computer extends AbstractAsset { @@ -67,6 +67,7 @@ public function getEvaluableQuery(array $crit = [], bool $entity_restrict = true $item_model_table = self::$model_itemtype::getTable(); $glpi_computertypes_table = GlpiComputerType::getTable(); $computertypes_table = ComputerType::getTable(); + $glpi_location_table = GlpiLocation::getTable(); $location_table = Location::getTable(); $usage_table = UsageInfo::getTable(); $computerUsageProfile_table = ComputerUsageProfile::getTable(); @@ -78,10 +79,16 @@ public function getEvaluableQuery(array $crit = [], bool $entity_restrict = true ], 'FROM' => $item_table, 'INNER JOIN' => [ - $location_table => [ + $glpi_location_table => [ 'FKEY' => [ $item_table => 'locations_id', - $location_table => 'id', + $glpi_location_table => 'id', + ] + ], + $location_table => [ + 'FKEY' => [ + $location_table => 'locations_id', + $glpi_location_table => 'id', ] ], $usage_table => [ @@ -138,18 +145,7 @@ public function getEvaluableQuery(array $crit = [], bool $entity_restrict = true 'AND' => [ self::$itemtype::getTableField('is_deleted') => 0, self::$itemtype::getTableField('is_template') => 0, - [ - 'OR' => [ - [ - ['NOT' => [Location::getTableField('country') => '']], - ['NOT' => [Location::getTableField('country') => null]], - ], - [ - ['NOT' => [Location::getTableField('state') => '']], - ['NOT' => [Location::getTableField('state') => null]], - ] - ] - ], + Location::getTableField('plugin_carbon_sources_zones_id') => ['>', 0], [ 'OR' => [ ComputerType::getTableField('power_consumption') => ['>', 0], @@ -187,9 +183,8 @@ public static function getHistorizableDiagnosis(CommonDBTM $item): ?array $request['SELECT'] = [ self::$itemtype::getTableField('is_deleted'), self::$itemtype::getTableField('is_template'), - Location::getTableField('id as location_id'), - Location::getTableField('state'), - Location::getTableField('country'), + GlpiLocation::getTableField('id as location_id'), + Location::getTableField('plugin_carbon_sources_zones_id'), GlpiComputerModel::getTableField('id as model_id'), GlpiComputerModel::getTableField('power_consumption as model_power_consumption'), GlpiComputerType::getTableField('id as type_id'), @@ -217,18 +212,20 @@ public static function getHistorizableDiagnosis(CommonDBTM $item): ?array return null; } - $glpi_location = new Location(); + $glpi_location = new GlpiLocation(); $glpi_location->getFromDB($item->fields['locations_id']); - $location = new CarbonLocation(); + $location = new Location(); $is_carbon_intensity_download_enabled = $location->isCarbonIntensityDownloadEnabled($glpi_location); $is_carbon_intensity_fallback_available = $location->hasFallbackCarbonIntensityData($glpi_location); // Each state is analyzed, with bool results // false means that data is missing or invalid for historization + // TODO : rename is_deleted, is_template into is_not_deleted is_not_template $status['is_deleted'] = ($data['is_deleted'] === 0); $status['is_template'] = ($data['is_template'] === 0); - $status['has_location'] = !Location::isNewID($data['location_id']); - $status['has_state_or_country'] = (strlen($data['state'] ?? '') > 0) || (strlen($data['country'] ?? '') > 0); + $status['has_location'] = !GlpiLocation::isNewID($data['location_id']); + // $status['has_state_or_country'] = (strlen($data['state'] ?? '') > 0) || (strlen($data['country'] ?? '') > 0); + $status['has_carbon_intensity_zone'] = (($data['plugin_carbon_sources_zones_id'] ?? 0) !== 0); $status['has_model'] = !GlpiComputerModel::isNewID($data['model_id']); $status['has_model_power_consumption'] = (($data['model_power_consumption'] ?? 0) !== 0); $status['has_type'] = !GlpiComputerType::isNewID($data['type_id']); diff --git a/src/Impact/History/Monitor.php b/src/Impact/History/Monitor.php index d42f886e..acea534b 100644 --- a/src/Impact/History/Monitor.php +++ b/src/Impact/History/Monitor.php @@ -45,12 +45,12 @@ use GlpiPlugin\Carbon\ComputerUsageProfile; use GlpiPlugin\Carbon\Engine\V1\EngineInterface; use GlpiPlugin\Carbon\Engine\V1\Monitor as EngineMonitor; -use GlpiPlugin\Carbon\Location as CarbonLocation; +use GlpiPlugin\Carbon\Location; use GlpiPlugin\Carbon\MonitorType; use GlpiPlugin\Carbon\UsageImpact; use GlpiPlugin\Carbon\UsageInfo; use Infocom; -use Location; +use Location as GlpiLocation; use Monitor as GlpiMonitor; use MonitorType as GlpiMonitorType; use MonitorModel as GlpiMonitorModel; @@ -153,18 +153,7 @@ public function getEvaluableQuery(array $crit = [], bool $entity_restrict = true self::$itemtype::getTableField('is_template') => 0, // Check the monitor is located the same place as the attached computer // self::$itemtype::getTableField('locations_id') => new QueryExpression(DBmysql::quoteName(GlpiComputer::getTableField('locations_id'))), - [ - 'OR' => [ - [ - ['NOT' => [Location::getTableField('country') => '']], - ['NOT' => [Location::getTableField('country') => null]], - ], - [ - ['NOT' => [Location::getTableField('state') => '']], - ['NOT' => [Location::getTableField('state') => null]], - ] - ] - ], + Location::getTableField('plugin_carbon_sources_zones_id') => ['>', 0], [ 'OR' => [ MonitorType::getTableField('power_consumption') => ['>', 0], @@ -195,9 +184,8 @@ public static function getHistorizableDiagnosis(CommonDBTM $item): ?array self::$itemtype::getTableField('is_template'), Asset_PeripheralAsset::getTableField('items_id_asset'), UsageInfo::getTableField('plugin_carbon_computerusageprofiles_id'), - Location::getTableField('id as location_id'), - Location::getTableField('state'), - Location::getTableField('country'), + GlpiLocation::getTableField('id as location_id'), + Location::getTableField('plugin_carbon_sources_zones_id'), GlpiMonitorModel::getTableField('id as model_id'), GlpiMonitorModel::getTableField('power_consumption as model_power_consumption'), GlpiMonitorType::getTableField('id as type_id'), @@ -222,9 +210,9 @@ public static function getHistorizableDiagnosis(CommonDBTM $item): ?array return null; } - $glpi_location = new Location(); + $glpi_location = new GlpiLocation(); $glpi_location->getFromDB($item->fields['locations_id']); - $location = new CarbonLocation(); + $location = new Location(); $is_carbon_intensity_download_enabled = $location->isCarbonIntensityDownloadEnabled($glpi_location); $is_carbon_intensity_fallback_available = $location->hasFallbackCarbonIntensityData($glpi_location); @@ -234,8 +222,9 @@ public static function getHistorizableDiagnosis(CommonDBTM $item): ?array $status['is_template'] = ($data['is_template'] === 0); // Actually the result is whether it is "not template" $status['has_computer'] = !GlpiComputer::isNewID($data['items_id_asset']); $status['has_usage_profile'] = !ComputerUsageProfile::isNewID($data['plugin_carbon_computerusageprofiles_id']); - $status['has_location'] = !Location::isNewID($data['location_id']); - $status['has_state_or_country'] = (strlen($data['state'] ?? '') > 0) || (strlen($data['country'] ?? '') > 0); + $status['has_location'] = !GlpiLocation::isNewID($data['location_id']); + // $status['has_state_or_country'] = (strlen($data['state'] ?? '') > 0) || (strlen($data['country'] ?? '') > 0); + $status['has_carbon_intensity_zone'] = (($data['plugin_carbon_sources_zones_id'] ?? 0) !== 0); $status['has_model'] = !GlpiMonitorModel::isNewID($data['model_id']); $status['has_model_power_consumption'] = !GlpiMonitorType::isNewID($data['model_power_consumption']); $status['has_type'] = !GlpiMonitorType::isNewID($data['type_id']); diff --git a/src/Impact/History/NetworkEquipment.php b/src/Impact/History/NetworkEquipment.php index ddf5f7ae..dea087d6 100644 --- a/src/Impact/History/NetworkEquipment.php +++ b/src/Impact/History/NetworkEquipment.php @@ -38,13 +38,13 @@ use DbUtils; use Glpi\Application\View\TemplateRenderer; use Infocom; -use Location; +use Location as GlpiLocation; use NetworkEquipment as GlpiNetworkEquipment; use NetworkEquipmentType as GlpiNetworkEquipmentType; use NetworkEquipmentModel as GlpiNetworkEquipmentModel; use GlpiPlugin\Carbon\Engine\V1\EngineInterface; use GlpiPlugin\Carbon\Engine\V1\NetworkEquipment as EngineNetworkEquipment; -use GlpiPlugin\Carbon\Location as CarbonLocation; +use GlpiPlugin\Carbon\Location; use GlpiPlugin\Carbon\NetworkEquipmentType; use GlpiPlugin\Carbon\UsageImpact; @@ -65,6 +65,7 @@ public function getEvaluableQuery(array $crit = [], bool $entity_restrict = true $item_model_table = self::$model_itemtype::getTable(); $item_glpitype_table = self::$type_itemtype::getTable(); $item_type_table = NetworkEquipmentType::getTable(); + $glpi_location_table = GlpiLocation::getTable(); $location_table = Location::getTable(); $infocom_table = Infocom::getTable(); @@ -78,10 +79,16 @@ public function getEvaluableQuery(array $crit = [], bool $entity_restrict = true $item_model_table => 'id', ] ], - $location_table => [ + $glpi_location_table => [ 'FKEY' => [ $item_table => 'locations_id', - $location_table => 'id', + $glpi_location_table => 'id', + ] + ], + $location_table => [ + 'FKEY' => [ + $location_table => 'locations_id', + $glpi_location_table => 'id', ] ], $item_glpitype_table => [ @@ -114,18 +121,7 @@ public function getEvaluableQuery(array $crit = [], bool $entity_restrict = true 'WHERE' => [ self::$itemtype::getTableField('is_deleted') => 0, self::$itemtype::getTableField('is_template') => 0, - [ - 'OR' => [ - [ - ['NOT' => [Location::getTableField('country') => '']], - ['NOT' => [Location::getTableField('country') => null]], - ], - [ - ['NOT' => [Location::getTableField('state') => '']], - ['NOT' => [Location::getTableField('state') => null]], - ] - ] - ], + Location::getTableField('plugin_carbon_sources_zones_id') => ['>', 0], [ 'OR' => [ NetworkEquipmentType::getTableField('power_consumption') => ['>', 0], @@ -164,9 +160,8 @@ public static function getHistorizableDiagnosis(CommonDBTM $item): ?array $request['SELECT'] = [ self::$itemtype::getTableField('is_deleted'), self::$itemtype::getTableField('is_template'), - Location::getTableField('id as location_id'), - Location::getTableField('state'), - Location::getTableField('country'), + GlpiLocation::getTableField('id as location_id'), + Location::getTableField('plugin_carbon_sources_zones_id'), GlpiNetworkEquipmentModel::getTableField('id as model_id'), GlpiNetworkEquipmentModel::getTableField('power_consumption as model_power_consumption'), GlpiNetworkEquipmentType::getTableField('id as type_id'), @@ -201,9 +196,9 @@ public static function getHistorizableDiagnosis(CommonDBTM $item): ?array return null; } - $glpi_location = new Location(); + $glpi_location = new GlpiLocation(); $glpi_location->getFromDB($item->fields['locations_id']); - $location = new CarbonLocation(); + $location = new Location(); $is_carbon_intensity_download_enabled = $location->isCarbonIntensityDownloadEnabled($glpi_location); $is_carbon_intensity_fallback_available = $location->hasFallbackCarbonIntensityData($glpi_location); @@ -211,8 +206,9 @@ public static function getHistorizableDiagnosis(CommonDBTM $item): ?array // false means that data is missing or invalid for historization $status['is_deleted'] = ($data['is_deleted'] === 0); $status['is_template'] = ($data['is_template'] === 0); - $status['has_location'] = !Location::isNewId($data['location_id']); - $status['has_state_or_country'] = (strlen($data['state'] ?? '') > 0) || (strlen($data['country'] ?? '') > 0); + $status['has_location'] = !GlpiLocation::isNewId($data['location_id']); + // $status['has_state_or_country'] = (strlen($data['state'] ?? '') > 0) || (strlen($data['country'] ?? '') > 0); + $status['has_carbon_intensity_zone'] = (($data['plugin_carbon_sources_zones_id'] ?? 0) !== 0); $status['has_model'] = !GlpiNetworkEquipmentModel::isNewId($data['model_id']); $status['has_model_power_consumption'] = (($data['model_power_consumption'] ?? 0) !== 0); $status['has_type'] = !GlpiNetworkEquipmentType::isNewId($data['type_id']); diff --git a/src/Location.php b/src/Location.php index c8e039d1..fa636247 100644 --- a/src/Location.php +++ b/src/Location.php @@ -34,25 +34,22 @@ use CommonDBChild; use CommonDBTM; +use CommonGLPI; use Config as GlpiConfig; use DBmysql; use DBmysqlIterator; +use DbUtils; use Geocoder\Geocoder; -use Geocoder\Provider\Nominatim\Nominatim; use Geocoder\Query\GeocodeQuery; -use Geocoder\StatefulGeocoder; -use GuzzleHttp\Client; use Html; use Location as GlpiLocation; use MassiveAction; use Glpi\Application\View\TemplateRenderer; -use GLPINetwork; use GlpiPlugin\Carbon\DataSource\Boaviztapi; use League\ISO3166\ISO3166; -use Session; /** - * Additional data for a location + * Additional data for a location. Extends the Location object from GLPI with aditional fields */ class Location extends CommonDBChild { @@ -60,11 +57,110 @@ class Location extends CommonDBChild public static $itemtype = GlpiLocation::class; public static $items_id = 'locations_id'; - public function showForm($ID, array $options = []) + public static function getIcon() { - $this->getFromDB($ID); + return 'ti ti-map-2'; + } + + public function getTabNameForItem(CommonGLPI $item, $withtemplate = 0) + { + if (is_a($item, GlpiLocation::class)) { + return self::createTabEntry(__('Environmental impact', 'carbon'), 0); + } + return ''; + } + + public static function displayTabContentForItem(CommonGLPI $item, $tabnum = 1, $withtemplate = 0) + { + if (is_a($item, GlpiLocation::class)) { + /** @var GlpiLocation $item */ + $location = new self(); + $location->showForLocation($item); + } + return true; + } + + public function prepareInputForAdd($input) + { + if (isset($input['plugin_carbon_sources_id']) && isset($input['plugin_carbon_zones_id'])) { + $source_zone = new Source_Zone(); + $source_zone->getFromDBByCrit([ + 'plugin_carbon_sources_id' => $input['plugin_carbon_sources_id'], + 'plugin_carbon_zones_id' => $input['plugin_carbon_zones_id'], + ]); + if (!$source_zone->isNewItem()) { + $input['plugin_carbon_sources_zones_id'] = $source_zone->getID(); + } + } + + return $input; + } + + public function prepareInputForUpdate($input) + { + if (isset($input['plugin_carbon_sources_id']) && isset($input['plugin_carbon_zones_id'])) { + $source_zone = new Source_Zone(); + $source_zone->getFromDBByCrit([ + 'plugin_carbon_sources_id' => $input['plugin_carbon_sources_id'], + 'plugin_carbon_zones_id' => $input['plugin_carbon_zones_id'], + ]); + if (!$source_zone->isNewItem()) { + $input['plugin_carbon_sources_zones_id'] = $source_zone->getID(); + } else { + $input['plugin_carbon_sources_zones_id'] = 0; + } + } + + return $input; + } + + public function showForLocation(GlpiLocation $item, array $options = []) + { + /** @var DBmysql $DB */ + global $DB; + + $this->getFromDBByCrit(['locations_id' => $item->getID()]); + if ($this->isNewItem()) { + $this->add(['locations_id' => $item->getID()]); + } + + $source_zone_table = Source_Zone::getTable(); + $source_table = Source::getTable(); + $iterator = $DB->request([ + 'SELECT' => [ + Source_Zone::getTableField('plugin_carbon_sources_id') . ' AS sources_id', + Source_Zone::getTableField('plugin_carbon_zones_id') . ' AS zones_id', + ], + 'FROM' => $source_table, + 'LEFT JOIN' => [ + $source_zone_table => [ + 'FKEY' => [ + $source_zone_table => 'plugin_carbon_sources_id', + $source_table => 'id', + ] + ] + ], + 'WHERE' => [ + 'is_fallback' => 0, + 'is_carbon_intensity_source' => 1, + Source_Zone::getTableField('id') => $this->fields['plugin_carbon_sources_zones_id'], + ] + ]); + $row = $iterator->current(); + $source_id = $row['sources_id'] ?? 0; + $zone_id = $row['zones_id'] ?? 0; + if ($source_id === 0) { + $zone_id = 0; + } + TemplateRenderer::getInstance()->display('@carbon/location.html.twig', [ 'item' => $this, + 'params' => [ + 'candel' => false, + ], + 'source_id' => $source_id, + 'zone_id' => $zone_id, + 'zone_condition' => Zone::getRestrictBySourceCondition($source_id), ]); return true; @@ -209,18 +305,9 @@ public function onGlpiLocationPreUpdate(CommonDBTM $item, Geocoder $geocoder) */ protected function enableCarbonIntensityDownload(CommonDBTM $item): bool { - if (!in_array('country', array_keys($item->fields))) { - return false; - } - $zone = Zone::getByLocation($item); - if ($zone === null) { - return false; - } - $source_zone = new CarbonIntensitySource_Zone(); - $source_zone->getFromDBByCrit([ - Zone::getForeignKeyField() => $zone->fields['id'], - CarbonIntensitySource::getForeignKeyField() => $zone->fields['plugin_carbon_carbonintensitysources_id_historical'], - ]); + $source_zone = new Source_Zone(); + /** @var GlpiLocation $item */ + $source_zone->getFromDbByItem($item); if ($source_zone->isNewItem()) { return false; } @@ -235,65 +322,61 @@ protected function enableCarbonIntensityDownload(CommonDBTM $item): bool */ public function isCarbonIntensityDownloadEnabled(CommonDBTM $item): bool { - $zone = Zone::getByLocation($item); - if ($zone === null) { - return false; - } - $source_zone = new CarbonIntensitySource_Zone(); - $source_zone->getFromDBByCrit([ - Zone::getForeignKeyField() => $zone->fields['id'], - CarbonIntensitySource::getForeignKeyField() => $zone->fields['plugin_carbon_carbonintensitysources_id_historical'], - ]); - if ($source_zone->isNewItem()) { + $source_zone = new Source_Zone(); + /** @var GlpiLocation $item */ + if (!$source_zone->getFromDbByItem($item)) { return false; } return $source_zone->fields['is_download_enabled'] === 1; } /** - * Tells id a location has fallback carbon intensity data + * Tells if a location has fallback carbon intensity data * - * @param CommonDBTM $item + * @param GlpiLocation $item * @return boolean */ - public function hasFallbackCarbonIntensityData(CommonDBTM $item): bool + public function hasFallbackCarbonIntensityData(GlpiLocation $item): bool { /** @var DBmysql $DB */ global $DB; - $zone = Zone::getByLocation($item); - if ($zone === null) { - return false; - } $carbon_intensity_table = CarbonIntensity::getTable(); - $carbon_intensity_source_zone_table = CarbonIntensitySource_Zone::getTable(); - $carbon_intensity_source_table = CarbonIntensitySource::getTable(); + $source_zone_table = Source_Zone::getTable(); + $source_table = Source::getTable(); + $location_table = Location::getTable(); $request = [ 'COUNT' => 'count', 'FROM' => $carbon_intensity_table, 'INNER JOIN' => [ - $carbon_intensity_source_zone_table => [ + $source_zone_table => [ 'FKEY' => [ $carbon_intensity_table => 'plugin_carbon_zones_id', - $carbon_intensity_source_zone_table => 'plugin_carbon_zones_id', + $source_zone_table => 'plugin_carbon_zones_id', ] ], - $carbon_intensity_source_table => [ + $location_table => [ + 'FKEY' => [ + $location_table => 'plugin_carbon_sources_zones_id', + $source_zone_table => 'id' + ] + ], + $source_table => [ 'FKEY' => [ - $carbon_intensity_source_zone_table => 'plugin_carbon_carbonintensitysources_id', - $carbon_intensity_source_table => 'id', + $source_zone_table => 'plugin_carbon_sources_id', + $source_table => 'id', ] - ] + ], ], 'WHERE' => [ - CarbonIntensitySource::getTableField('is_fallback') => 1, - CarbonIntensitySource_Zone::getTableField('plugin_carbon_zones_id') => $zone->getID(), + Source::getTableField('is_fallback') => 1, + Location::getTableField('locations_id') => $item->getID(), ], 'ORDER' => CarbonIntensity::getTableField('date') . ' DESC', 'LIMIT' => 1, ]; $result = $DB->request($request); - return ($result->count() > 0); + return ($result->current()['count'] > 0); } /** @@ -387,7 +470,7 @@ public function getCountryCode(CommonDBTM $item, Geocoder $geocoder): string */ public static function getIncompleteLocations(array $where = []): DBmysqlIterator { - /** @var DBmysql $DB */ + /** @var DBmysql $DB */ global $DB; $where = array_diff_key($where, [ @@ -428,4 +511,51 @@ public static function getIncompleteLocations(array $where = []): DBmysqlIterato return $result; } + + public function getSourceZoneId(): int + { + /** @var DBmysql $DB */ + global $DB; + + if ($this->isNewItem()) { + return 0; + } + + if (!Source_Zone::isNewID($this->fields['plugin_carbon_sources_zones_id'])) { + return $this->fields['plugin_carbon_sources_zones_id']; + } + + $location_table = self::getTable(); + $glpi_location_table = GlpiLocation::getTable(); + $ancestors = (new DbUtils())->getAncestorsOf($glpi_location_table, $this->fields['locations_id']); + if (count($ancestors) === 0) { + return 0; + } + + $ancestors = array_values($ancestors); // Drop keys + $request = [ + 'SELECT' => self::getTableField('plugin_carbon_sources_zones_id'), + 'FROM' => $glpi_location_table, + 'INNER JOIN' => [ + $location_table => [ + 'FKEY' => [ + $glpi_location_table => 'id', + $location_table => 'locations_id', + ] + ] + ], + 'WHERE' => [ + GlpiLocation::getTableField('id') => $ancestors, + self::getTableField('plugin_carbon_sources_zones_id') => ['>', 0] + ], + 'ORDER' => 'level DESC', + 'LIMIT' => '1' + ]; + $iterator = $DB->request($request); + if ($iterator->count() === 0) { + return 0; + } + + return $iterator->current()['plugin_carbon_sources_zones_id']; + } } diff --git a/src/SearchOptions.php b/src/SearchOptions.php index 4f278ed9..077c08e4 100644 --- a/src/SearchOptions.php +++ b/src/SearchOptions.php @@ -179,10 +179,9 @@ public static function getCoreSearchOptions(string $itemtype): array ] ]; - $computation = "IF(`glpi_computers_id_e1f6cdb2d63e8a0252da5d4cb339a927`.`is_deleted` = 0 - AND `glpi_computers_id_e1f6cdb2d63e8a0252da5d4cb339a927`.`is_template` = 0 - AND NOT `glpi_locations`.`country` = '' - AND NOT `glpi_locations`.`country` IS NULL + $computation = "IF(`glpi_computers_id_963cd5e903dddc7ab00a3b70933369df`.`is_deleted` = 0 + AND `glpi_computers_id_963cd5e903dddc7ab00a3b70933369df`.`is_template` = 0 + AND `glpi_plugin_carbon_locations_3d6da7fccf9233a3f1a4e41183391a41`.`plugin_carbon_sources_zones_id` > 0 AND `glpi_plugin_carbon_computerusageprofiles_09f8403aa14af64cd70f350288a0331b`.`id` > 0 AND ( `glpi_plugin_carbon_computertypes_a643ab3ffd70abf99533ed214da87d60`.`power_consumption` > 0 @@ -200,10 +199,16 @@ public static function getCoreSearchOptions(string $itemtype): array 'jointype' => 'empty', 'beforejoin' => [ [ - 'table' => GlpiLocation::getTable(), + 'table' => Location::getTable(), 'joinparams' => [ - 'jointype' => 'empty', + 'jointype' => 'child', 'nolink' => true, + 'beforejoin' => [ + 'table' => GlpiLocation::getTable(), + 'joinparams' => [ + 'jointype' => 'empty', + ] + ] ] ], [ @@ -257,10 +262,9 @@ public static function getCoreSearchOptions(string $itemtype): array ] ]; } else if ($itemtype === Monitor::class && in_array($itemtype, PLUGIN_CARBON_TYPES)) { - $computation = "IF(`glpi_monitors_id_fd9c1a8262e8f3b6e96bc8948f2a6226`.`is_deleted` = 0 - AND `glpi_monitors_id_fd9c1a8262e8f3b6e96bc8948f2a6226`.`is_template` = 0 - AND NOT `glpi_locations_fad8b1764dcda16e3822068239df73f2`.`country` = '' - AND NOT `glpi_locations_fad8b1764dcda16e3822068239df73f2`.`country` IS NULL + $computation = "IF(`glpi_monitors_id_b24d2115745b49f0b5cdaf2ebb5e9ffe`.`is_deleted` = 0 + AND `glpi_monitors_id_b24d2115745b49f0b5cdaf2ebb5e9ffe`.`is_template` = 0 + AND `glpi_plugin_carbon_locations_3d6da7fccf9233a3f1a4e41183391a41`.`plugin_carbon_sources_zones_id` > 0 AND ( `glpi_plugin_carbon_monitortypes_54b036337d1b9bbf4f13db0e1ae93bc9`.`power_consumption` > 0 OR `glpi_monitormodels`.`power_consumption` > 0 @@ -277,28 +281,33 @@ public static function getCoreSearchOptions(string $itemtype): array 'jointype' => 'empty', 'beforejoin' => [ [ - 'table' => GlpiLocation::getTable(), + 'table' => Location::getTable(), 'joinparams' => [ - 'jointype' => 'empty', - 'nolink' => true, + 'jointype' => 'child', 'beforejoin' => [ - 'table' => Computer::getTable(), - 'linkfield' => 'items_id_peripheral', + 'table' => GlpiLocation::getTable(), 'joinparams' => [ 'jointype' => 'empty', 'beforejoin' => [ - 'table' => Asset_PeripheralAsset::getTable(), + 'table' => Computer::getTable(), + 'linkfield' => 'items_id_peripheral', 'joinparams' => [ - 'jointype' => 'custom_condition_only', - 'condition' => [ - 'ON' => [ - 'NEWTABLE' => 'items_id_peripheral', - 'REFTABLE' => 'id', - ], - 'AND' => [ - 'itemtype_peripheral' => Monitor::getType(), + 'jointype' => 'empty', + 'beforejoin' => [ + 'table' => Asset_PeripheralAsset::getTable(), + 'joinparams' => [ + 'jointype' => 'custom_condition_only', + 'condition' => [ + 'ON' => [ + 'NEWTABLE' => 'items_id_peripheral', + 'REFTABLE' => 'id', + ], + 'AND' => [ + 'itemtype_peripheral' => Monitor::getType(), + ] + ], ] - ], + ] ] ] ] @@ -309,7 +318,6 @@ public static function getCoreSearchOptions(string $itemtype): array 'table' => MonitorType::getTable(), 'joinparams' => [ 'jointype' => 'child', - 'nolink' => true, 'beforejoin' => [ 'table' => GlpiMonitorType::getTable(), 'joinparams' => [ @@ -322,7 +330,6 @@ public static function getCoreSearchOptions(string $itemtype): array 'table' => MonitorModel::getTable(), 'joinparams' => [ 'jointype' => 'empty', - 'nolink' => true, ] ], ], @@ -330,10 +337,9 @@ public static function getCoreSearchOptions(string $itemtype): array 'computation' => $computation, ]; } else if ($itemtype === NetworkEquipment::class && in_array($itemtype, PLUGIN_CARBON_TYPES)) { - $computation = "IF(`glpi_networkequipments_id_aef00423a27f97ae31ca50f63fb1a6fb`.`is_deleted` = 0 - AND `glpi_networkequipments_id_aef00423a27f97ae31ca50f63fb1a6fb`.`is_template` = 0 - AND NOT `glpi_locations`.`country` = '' - AND NOT `glpi_locations`.`country` IS NULL + $computation = "IF(`glpi_networkequipments_id_401e18dd2eaa15834dcd21d0f6fc677c`.`is_deleted` = 0 + AND `glpi_networkequipments_id_401e18dd2eaa15834dcd21d0f6fc677c`.`is_template` = 0 + AND `glpi_plugin_carbon_locations_3d6da7fccf9233a3f1a4e41183391a41`.`plugin_carbon_sources_zones_id` > 0 AND ( `glpi_plugin_carbon_networkequipmenttypes_640a9703b62363e5d254356fb4df69ef`.`power_consumption` > 0 OR `glpi_networkequipmentmodels`.`power_consumption` > 0 @@ -350,10 +356,16 @@ public static function getCoreSearchOptions(string $itemtype): array 'jointype' => 'empty', 'beforejoin' => [ [ - 'table' => GlpiLocation::getTable(), + 'table' => Location::getTable(), 'joinparams' => [ - 'jointype' => 'empty', + 'jointype' => 'child', 'nolink' => true, + 'beforejoin' => [ + 'table' => GlpiLocation::getTable(), + 'joinparams' => [ + 'jointype' => 'empty', + ] + ] ] ], [ diff --git a/src/CarbonIntensitySource.php b/src/Source.php similarity index 86% rename from src/CarbonIntensitySource.php rename to src/Source.php index e4d319d0..6ba1c7e3 100644 --- a/src/CarbonIntensitySource.php +++ b/src/Source.php @@ -39,7 +39,7 @@ use DBmysql; use Session; -class CarbonIntensitySource extends CommonDropdown +class Source extends CommonDropdown { public static function getTypeName($nb = 0) { @@ -82,7 +82,7 @@ public function getTabNameForItem(CommonGLPI $item, $withtemplate = 0) case Zone::class: if ($_SESSION['glpishow_count_on_tabs']) { $nb = (new DbUtils())->countElementsInTable( - CarbonIntensitySource_Zone::getTable(), + Source_Zone::getTable(), [self::getForeignKeyField() => $item->getID()] ); } @@ -98,7 +98,7 @@ public static function displayTabContentForItem(CommonGLPI $item, $tabnum = 1, $ /** @var CommonDBTM $item */ switch ($item->getType()) { case Zone::class: - CarbonIntensitySource_Zone::showForZone($item); + Source_Zone::showForZone($item); } return true; @@ -108,15 +108,26 @@ public function rawSearchOptions() { $tab = parent::rawSearchOptions(); + $table = self::getTable(); + $tab[] = [ 'id' => '3', - 'table' => $this->getTable(), + 'table' => $table, 'field' => 'is_fallback', 'name' => __('Is a fallback source'), 'massiveaction' => false, 'datatype' => 'boolean', ]; + $tab[] = [ + 'id' => '4', + 'table' => $table, + 'field' => 'is_carbon_intensity_source', + 'name' => __('Is a carbon intensity source'), + 'massiveaction' => false, + 'datatype' => 'boolean', + ]; + return $tab; } diff --git a/src/CarbonIntensitySource_Zone.php b/src/Source_Zone.php similarity index 80% rename from src/CarbonIntensitySource_Zone.php rename to src/Source_Zone.php index 10081e5f..8df21509 100644 --- a/src/CarbonIntensitySource_Zone.php +++ b/src/Source_Zone.php @@ -37,14 +37,16 @@ use CommonDBTM; use CronTask; use DBmysql; -use GlpiPlugin\Carbon\Application\View\Extension\DataHelpersExtension; +use Location as GlpiLocation; use Glpi\Application\View\TemplateRenderer; use Html; +use InvalidArgumentException; +use RuntimeException; -class CarbonIntensitySource_Zone extends CommonDBRelation +class Source_Zone extends CommonDBRelation { - public static $itemtype_1 = CarbonIntensitySource::class; // Type ref or field name (must start with itemtype) - public static $items_id_1 = 'plugin_carbon_carbonintensitysources_id'; // Field name + public static $itemtype_1 = Source::class; // Type ref or field name (must start with itemtype) + public static $items_id_1 = 'plugin_carbon_sources_id'; // Field name public static $checkItem_1_Rights = self::HAVE_SAME_RIGHT_ON_ITEM; public static $itemtype_2 = Zone::class; // Type ref or field name (must start with itemtype) @@ -53,10 +55,10 @@ class CarbonIntensitySource_Zone extends CommonDBRelation public function getTabNameForItem(CommonGLPI $item, $withtemplate = 0) { - if ($item->getType() === CarbonIntensitySource::class) { + if ($item->getType() === Source::class) { return self::createTabEntry(Zone::getTypeName(), 0); } - return self::createTabEntry(CarbonIntensitySource::getTypeName(), 0); + return self::createTabEntry(Source::getTypeName(), 0); } public function rawSearchOptions() @@ -65,7 +67,7 @@ public function rawSearchOptions() $tab[] = [ 'id' => '5', - 'table' => CarbonIntensitySource::getTable(), + 'table' => Source::getTable(), 'field' => 'name', 'name' => __('Source name', 'carbon'), 'datatype' => 'dropdown', @@ -81,7 +83,7 @@ public function rawSearchOptions() $tab[] = [ 'id' => '7', - 'table' => CarbonIntensitySource::getTable(), + 'table' => Source::getTable(), 'field' => 'is_download_enabled', 'name' => __('Download enabled', 'carbon'), 'datatype' => 'bool', @@ -110,21 +112,21 @@ public static function showForSource(CommonDBTM $item) } $canedit = $item->canEdit($item_id); - $source_table = CarbonIntensitySource::getTable(); + $source_table = Source::getTable(); $zone_table = Zone::getTable(); $source_zone_table = self::getTable(); $iterator = $DB->request([ 'SELECT' => [ $zone_table => 'name', $source_zone_table => ['id', 'is_download_enabled'], - CarbonIntensitySource::getTableField('name') . ' AS historical_source_name', + Source::getTableField('name') . ' AS historical_source_name', $source_table => 'is_fallback' ], 'FROM' => $source_zone_table, 'INNER JOIN' => [ $source_table => [ 'FKEY' => [ - $source_zone_table => 'plugin_carbon_carbonintensitysources_id', + $source_zone_table => 'plugin_carbon_sources_id', $source_table => 'id', ], ], @@ -136,7 +138,7 @@ public static function showForSource(CommonDBTM $item) ], ], 'WHERE' => [ - CarbonIntensitySource::getTableField('id') => $item_id, + Source::getTableField('id') => $item_id, ], 'ORDER' => ['name ASC'], ]); @@ -150,7 +152,7 @@ public static function showForSource(CommonDBTM $item) $is_download_enabled = self::getToggleLink($data['id'], $data['is_download_enabled']); } $entries[] = [ - 'itemtype' => CarbonIntensitySource::class, + 'itemtype' => Source::class, 'id' => $item->getID(), 'name' => $data['name'], 'historical_source_name' => $data['historical_source_name'], @@ -213,8 +215,10 @@ public static function showForZone(CommonDBTM $item) } $canedit = $item->canEdit($item_id); - $source_table = CarbonIntensitySource::getTable(); + $source_table = Source::getTable(); + $source_fk = Source::getForeignKeyField(); $zone_table = Zone::getTable(); + $zone_fk = Zone::getForeignKeyField(); $source_zone_table = self::getTable(); $iterator = $DB->request([ 'SELECT' => [ @@ -225,13 +229,13 @@ public static function showForZone(CommonDBTM $item) 'INNER JOIN' => [ $source_table => [ 'FKEY' => [ - $source_zone_table => 'plugin_carbon_carbonintensitysources_id', + $source_zone_table => $source_fk, $source_table => 'id', ], ], $zone_table => [ 'FKEY' => [ - $source_zone_table => 'plugin_carbon_zones_id', + $source_zone_table => $zone_fk, $zone_table => 'id', ], ], @@ -246,7 +250,7 @@ public static function showForZone(CommonDBTM $item) $entries = []; foreach ($iterator as $data) { $entries[] = [ - 'itemtype' => CarbonIntensitySource::class, + 'itemtype' => Source::class, 'id' => $item->getID(), 'name' => $data['name'], 'is_download_enabled' => self::getToggleLink($data['id'], $data['is_download_enabled']), @@ -307,16 +311,16 @@ public function getFromDbBySourceAndZone(string $source_name, string $zone_name) global $DB; $zone_table = Zone::getTable(); - $source_table = CarbonIntensitySource::getTable(); + $source_table = Source::getTable(); $source_zone_table = self::getTable(); $request = [ - 'SELECT' => CarbonIntensitySource_Zone::getTableField('code'), + 'SELECT' => Source_Zone::getTableField('code'), 'FROM' => $source_zone_table, 'INNER JOIN' => [ $source_table => [ 'ON' => [ $source_table => 'id', - $source_zone_table => CarbonIntensitySource::getForeignKeyField(), + $source_zone_table => Source::getForeignKeyField(), ] ], $zone_table => [ @@ -327,7 +331,7 @@ public function getFromDbBySourceAndZone(string $source_name, string $zone_name) ] ], 'WHERE' => [ - CarbonIntensitySource::getTableField('name') => $source_name, + Source::getTableField('name') => $source_name, Zone::getTableField('name') => $zone_name, ], 'LIMIT' => '1' @@ -361,8 +365,8 @@ protected static function getToggleLink(int $zone_id, ?string $state): string public function toggleZone(?bool $state = null): bool { // Check if the source is a fallback source - $source = new CarbonIntensitySource(); - $source->getFromDB($this->fields['plugin_carbon_carbonintensitysources_id']); + $source = new Source(); + $source->getFromDB($this->fields['plugin_carbon_sources_id']); if ($source->fields['is_fallback'] === 1) { // Fallback sources cannot be toggled return false; @@ -378,4 +382,49 @@ public function toggleZone(?bool $state = null): bool ]; return $this->update($input) !== false; } + + /** + * Get a source_zone by a item criteria. + * If the item is a location, get the source_zone by location relation + * If the item is something else, get the source_zone by its associated location + * + * @param CommonDBTM $item + * @return bool + */ + public function getFromDbByItem(CommonDBTM $item): bool + { + if ($item->isNewItem()) { + return false; + } + + // Prepare WHERE clause dependingof the type of the item + $where = []; + if ($item->getType() === GlpiLocation::class) { + $where = [ + Location::getTableField('locations_id') => $item->getID(), + ]; + } elseif (isset($item->fields['locations_id'])) { + $where = [ + Location::getTableField('locations_id') => $item->fields['locations_id'], + ]; + } else { + throw new InvalidArgumentException('Invalid item'); + } + + $location_table = Location::getTable(); + $source_zone_table = Source_Zone::getTable(); + $request = [ + 'INNER JOIN' => [ + $location_table => [ + 'FKEY' => [ + $location_table => 'plugin_carbon_sources_zones_id', + $source_zone_table => 'id' + ] + ], + ], + 'WHERE' => $where, + ]; + + return $this->getFromDBByRequest($request); + } } diff --git a/src/Zone.php b/src/Zone.php index 542fa47d..2bbbf1ed 100644 --- a/src/Zone.php +++ b/src/Zone.php @@ -38,8 +38,7 @@ use DateTime; use DBmysql; use DbUtils; -use Glpi\Toolbox\Sanitizer; -use Location; +use Location as GlpiLocation; use LogicException; use Session; @@ -76,7 +75,7 @@ public static function canPurge(): bool public function defineTabs($options = []) { $tabs = parent::defineTabs($options); - $this->addStandardTab(CarbonIntensitySource::class, $tabs, $options); + $this->addStandardTab(Source::class, $tabs, $options); return $tabs; } @@ -86,11 +85,11 @@ public function getTabNameForItem(CommonGLPI $item, $withtemplate = 0) $nb = 0; /** @var CommonDBTM $item */ switch ($item->getType()) { - case CarbonIntensitySource::class: + case Source::class: if ($_SESSION['glpishow_count_on_tabs']) { $nb = (new DbUtils())->countElementsInTable( - CarbonIntensitySource_Zone::getTable(), - [CarbonIntensitySource::getForeignKeyField() => $item->getID()] + Source_Zone::getTable(), + [Source::getForeignKeyField() => $item->getID()] ); } return self::createTabEntry(self::getTypeName(Session::getPluralNumber()), $nb); @@ -111,8 +110,8 @@ public static function displayTabContentForItem(CommonGLPI $item, $tabnum = 1, $ { /** @var CommonDBTM $item */ switch ($item->getType()) { - case CarbonIntensitySource::class: - CarbonIntensitySource_Zone::showForSource($item); + case Source::class: + Source_Zone::showForSource($item); } return true; @@ -122,7 +121,7 @@ public function getAdditionalFields() { return [ [ - 'name' => 'plugin_carbon_carbonintensitysources_id_historical', + 'name' => 'plugin_carbon_sources_id_historical', 'label' => __('Data source for historical calculation', 'carbon'), 'type' => 'dropdownValue', 'list' => true @@ -136,13 +135,13 @@ public function rawSearchOptions() $tab[] = [ 'id' => SearchOptions::HISTORICAL_DATA_SOURCE, - 'table' => CarbonIntensitySource::getTable(), + 'table' => Source::getTable(), 'field' => 'name', 'name' => __('Data source for historical calculation', 'carbon'), 'datatype' => 'dropdown', 'joinparams' => [ 'beforejoin' => [ - 'table' => CarbonIntensitySource_Zone::getTable(), + 'table' => Source_Zone::getTable(), 'joinparams' => [ 'jointype' => 'child', ], @@ -152,7 +151,7 @@ public function rawSearchOptions() $tab[] = [ 'id' => SearchOptions::HISTORICAL_DATA_DL_ENABLED, - 'table' => CarbonIntensitySource_Zone::getTable(), + 'table' => Source_Zone::getTable(), 'field' => 'is_download_enabled', 'name' => __('Download enabled', 'carbon'), 'datatype' => 'bool', @@ -161,131 +160,120 @@ public function rawSearchOptions() return $tab; } + // /** + // * Get a zone by a location criteria + // * + // * @param CommonDBTM $item + // * @return Zone|null + // * @todo : de-staticify the method + // */ + // public static function getByLocation(CommonDBTM $item): ?Zone + // { + // if ($item->isNewItem()) { + // return null; + // } + + // $request = self::getByLocationRequest(); + // $request['WHERE'] = [ + // Location::getTableField('locations_id') => $item->getID(), + // ]; + // $zone = new self(); + // if (!$zone->getFromDBByRequest($request)) { + // return null; + // } + + // return $zone; + // } + + // /** + // * Get the request fragment to find a zone by location + // * + // * @return array Request fragment + // */ + // private static function getByLocationRequest(): array + // { + // $location_table = Location::getTable(); + // $source_zone_table = Source_Zone::getTable(); + // $zone_table = Zone::getTable(); + // return [ + // 'INNER JOIN' => [ + // $source_zone_table => [ + // 'FKEY' => [ + // $zone_table => 'id', + // $source_zone_table => 'plugin_carbon_zones_id', + // ] + // ], + // $location_table => [ + // 'FKEY' => [ + // $location_table => 'plugin_carbon_sources_zones_id', + // $source_zone_table => 'id' + // ] + // ], + // ], + // ]; + // } + /** - * Get a zone by a location criteria + * Get the request fragment to find a zone by asset * - * @param CommonDBTM $item - * @return Zone|null + * @param class-string $itemtype asset type + * @return array Request fragment */ - public static function getByLocation(CommonDBTM $item): ?Zone + private static function getByAssetRequest(string $itemtype): array { - /** @var DBmysql $DB */ - global $DB; - - if ($item->isNewItem()) { - return null; - } - - if (($item->fields['country'] ?? '') == '' && ($item->fields['state'] ?? '') == '') { - return null; - } - - // TODO: support translations - $location_table = Location::getTable(); - $zone_table = Zone::getTable(); + $dbUtil = new DbUtils(); + $location_table = $dbUtil->getTableForItemType(Location::class); + $source_zone_table = $dbUtil->getTableForItemType(Source_Zone::class); + $zone_table = $dbUtil->getTableForItemType(Zone::class); + $itemtype_table = $dbUtil->getTableForItemType($itemtype); $request = [ - 'SELECT' => Zone::getTableField('id'), - 'FROM' => $zone_table, 'INNER JOIN' => [ + $source_zone_table => [ + 'FKEY' => [ + $zone_table => 'id', + $source_zone_table => 'plugin_carbon_zones_id', + ] + ], $location_table => [ 'FKEY' => [ - $location_table => 'state', - $zone_table => 'name', - ], + $location_table => 'plugin_carbon_sources_zones_id', + $source_zone_table => 'id' + ] ], + $itemtype_table => [ + 'FKEY' => [ + $itemtype_table => 'locations_id', + $location_table => 'locations_id', + ] + ] ], - 'WHERE' => [ - Location::getTableField('id') => $item->getID(), - ] ]; - $iterator = $DB->request($request); - - if ($iterator->count() !== 1) { - // no state found, fallback to country - $request['INNER JOIN'][$location_table]['FKEY'][$location_table] = 'country'; - $iterator = $DB->request($request); - if ($iterator->count() !== 1) { - // Give up - return null; - } - } - - $zone_id = $iterator->current()['id']; - $zone = Zone::getById($zone_id); - if ($zone === false) { - return null; - } - return $zone; + return $request; } /** * Get a zone by an asset criteria * * @param CommonDBTM $item - * @return Zone|null + * @return bool */ - public static function getByAsset(CommonDBTM $item): ?Zone + public function getByAsset(CommonDBTM $item): bool { - /** @var DBmysql $DB */ - global $DB; - - if (!isset($item->fields[Location::getForeignKeyField()])) { - return null; + if (!isset($item->fields[GlpiLocation::getForeignKeyField()])) { + return false; } if ($item->isNewItem()) { - return null; + return false; } - // TODO: support translations - $location_table = Location::getTable(); - $zone_table = Zone::getTable(); - $item_table = $item::getTable(); - $state_field = Location::getTableField('state'); - $request = [ - 'SELECT' => Zone::getTableField('id'), - 'FROM' => $zone_table, - 'INNER JOIN' => [ - $location_table => [ - 'FKEY' => [ - $location_table => 'state', - $zone_table => 'name', - ], - ], - $item_table => [ - 'FKEY' => [ - $item_table => 'locations_id', - $location_table => 'id', - ], - ], - ], - 'WHERE' => [ - $state_field => ['<>', ''], - $item::getTableField('id') => $item->getID(), - ] + $request = self::getByAssetRequest($item->getType()); + $request['WHERE'] = [ + $item::getTableField('id') => $item->getID(), ]; - $iterator = $DB->request($request); - - if ($iterator->count() !== 1) { - // no state found, fallback to country - $request['INNER JOIN'][$location_table]['FKEY'][$location_table] = 'country'; - unset($request['WHERE'][$state_field]); - $request['WHERE'][Location::getTableField('country')] = ['<>', '']; - $iterator = $DB->request($request); - if ($iterator->count() !== 1) { - // Give up - return null; - } - } - - $zone_id = $iterator->current()['id']; - $zone = Zone::getById($zone_id); - if ($zone === false) { - return null; - } - return $zone; + return $this->getFromDBByRequest($request); } /** @@ -298,11 +286,11 @@ public function hasHistoricalData(): bool if ($this->isNewItem()) { return false; } - if (!isset($this->fields['plugin_carbon_carbonintensitysources_id_historical'])) { + if (!isset($this->fields['plugin_carbon_sources_id_historical'])) { return false; } - $source = new CarbonIntensitySource(); - if (!$source->getFromDB($this->fields['plugin_carbon_carbonintensitysources_id_historical'])) { + $source = new Source(); + if (!$source->getFromDB($this->fields['plugin_carbon_sources_id_historical'])) { // source does not exists return false; } @@ -317,7 +305,7 @@ public function hasHistoricalData(): bool * @param CommonDBTM $item * @param null|DateTime $date Date for which the zone must be found * @param bool $use_country Do not search by state first - * @return bool + * @return bool true if found in DB, false otherwise */ public function getByItem(CommonDBTM $item, ?DateTime $date = null, bool $use_country = false): bool { @@ -328,21 +316,21 @@ public function getByItem(CommonDBTM $item, ?DateTime $date = null, bool $use_co // TODO: use date to find where was the asset at the given date if ($date === null) { $item_table = $item->getTable(); - $location_table = Location::getTable(); + $glpi_location_table = GlpiLocation::getTable(); $zone_table = Zone::getTable(); $request = [ 'INNER JOIN' => [ - $location_table => [ + $glpi_location_table => [ 'FKEY' => [ $zone_table => 'name', - $location_table => 'state', + $glpi_location_table => 'state', ], ], $item_table => [ 'FKEY' => [ - $item_table => Location::getForeignKeyField(), - $location_table => 'id', + $item_table => GlpiLocation::getForeignKeyField(), + $glpi_location_table => 'id', ], ] ], @@ -360,10 +348,35 @@ public function getByItem(CommonDBTM $item, ?DateTime $date = null, bool $use_co } // no state found, fallback to country - $request['INNER JOIN'][$location_table]['FKEY'][$location_table] = 'country'; + $request['INNER JOIN'][$glpi_location_table]['FKEY'][$glpi_location_table] = 'country'; return $this->getFromDBByRequest($request); } throw new LogicException('Not implemented yet'); } + + /** + * Undocumented function + * + * @param integer $source_id + * @return array a request fragment + */ + public static function getRestrictBySourceCondition(int $source_id): array + { + $source_zone_table = Source_Zone::getTable(); + $zone_table = Zone::getTable(); + return [ + 'LEFT JOIN' => [ + $source_zone_table => [ + 'FKEY' => [ + $source_zone_table => 'plugin_carbon_zones_id', + $zone_table => 'id', + ] + ] + ], + 'WHERE' => [ + Source_Zone::getTableField('plugin_carbon_sources_id') => $source_id, + ] + ]; + } } diff --git a/templates/history/status-item.html.twig b/templates/history/status-item.html.twig index e68db9eb..735eb793 100644 --- a/templates/history/status-item.html.twig +++ b/templates/history/status-item.html.twig @@ -91,12 +91,12 @@ {{ fields.field('', field, __('Has a location', 'carbon')) }} {% endif %} - {% if status.has_state_or_country is defined %} + {% if status.has_carbon_intensity_zone is defined %} {% set field = nok_field %} - {% if status.has_state_or_country %} + {% if status.has_carbon_intensity_zone %} {% set field = ok_field %} {% endif %} - {{ fields.field('', field, __('The location has a state or a country', 'carbon')) }} + {{ fields.field('', field, __('The location has carbon intensity data', 'carbon')) }} {% endif %} {% if status.ci_download_enabled is defined %} diff --git a/templates/location.html.twig b/templates/location.html.twig index 101d8a64..4db4480f 100644 --- a/templates/location.html.twig +++ b/templates/location.html.twig @@ -29,14 +29,66 @@ # ------------------------------------------------------------------------- #} +{% extends "generic_show_form.html.twig" %} + {% import 'components/form/fields_macros.html.twig' as fields %} {% import '@carbon/components/form/fields_macros.html.twig' as carbonFields %} -{{ fields.smallTitle(__('Environmental impact', 'carbon')) }} -{{ carbonFields.dropdownBoaviztaZone('_boavizta_zone', - item.fields['boavizta_zone'] ?? '', - __('Boavizta zone', 'carbon'), - { - 'display_emptychoice': true, - }) -}} +{% block form_fields %} +
+ + {{ __('Boavizta', 'carbon') }} +
+ + {{ carbonFields.dropdownBoaviztaZone('boavizta_zone', + item.fields['boavizta_zone'] ?? '', + __('Boavizta zone', 'carbon'), + { + 'display_emptychoice': true, + }) }} + +
+ + {{ __('Carbon intensity', 'carbon') }} +
+ + {% set plugin_carbon_zones_rand = random() %} + {{ fields.dropdownField('GlpiPlugin\\Carbon\\Source', + 'plugin_carbon_sources_id', + source_id, + __('Source', 'carbon'), + { + display_emptychoice: true, + multiple: false, + disabled: false, + condition: { + is_fallback: 0, + is_carbon_intensity_source: 1 + }, + }) }} + + + + {{ fields.dropdownField('GlpiPlugin\\Carbon\\Zone', + 'plugin_carbon_zones_id', + zone_id, + __('Carbon intensity zone', 'carbon'), + { + rand: plugin_carbon_zones_rand, + display_emptychoice: true, + condition: zone_condition, + disabled: (source_id == 0) + }) }} +{% endblock %} diff --git a/tests/install/PluginInstallTest.php b/tests/install/PluginInstallTest.php index 5720f222..27e164f5 100644 --- a/tests/install/PluginInstallTest.php +++ b/tests/install/PluginInstallTest.php @@ -48,7 +48,6 @@ use Glpi\DBAL\QueryExpression as QueryExpression; use Glpi\Plugin\Hooks; use Glpi\System\Diagnostic\DatabaseSchemaIntegrityChecker; -use Glpi\Toolbox\Sanitizer; use GlpiPlugin\Carbon\CarbonIntensity; use GlpiPlugin\Carbon\CarbonIntensitySource; use GlpiPlugin\Carbon\CarbonIntensitySource_Zone; @@ -347,7 +346,7 @@ private function checkInitialDataSources() { $sources = ['RTE', 'ElectricityMap']; foreach ($sources as $source_name) { - $source = new CarbonIntensitySource(); + $source = new Source(); $source->getFromDBByCrit([ 'name' => $source_name, 'is_fallback' => 0 @@ -357,7 +356,7 @@ private function checkInitialDataSources() $sources = ['Ember - Energy Institute', 'Hydro Quebec']; foreach ($sources as $source_name) { - $source = new CarbonIntensitySource(); + $source = new Source(); $source->getFromDBByCrit([ 'name' => $source_name, 'is_fallback' => 1 @@ -388,7 +387,7 @@ private function checkInitialZones() $zone->getFromDBByCrit([ 'name' => $zone_name, ]); - $this->assertFalse($zone->isNewItem()); + $this->assertFalse($zone->isNewItem(), "Zone '$zone_name' not found"); } } @@ -399,7 +398,7 @@ private function checkInitialCarbonIntensities() // Find the source for Ember - Energy Institute $source_name = 'Ember - Energy Institute'; - $source = new CarbonIntensitySource(); + $source = new Source(); $source->getFromDBByCrit([ 'name' => $source_name, ]); @@ -426,7 +425,7 @@ private function checkInitialCarbonIntensities() // Find the source for Hydro Quebec $source_name = 'Hydro Quebec'; - $source = new CarbonIntensitySource(); + $source = new Source(); $source->getFromDBByCrit([ 'name' => $source_name ]); @@ -443,10 +442,10 @@ private function checkInitialCarbonIntensities() $this->assertEquals(1, $count); // Check all sources and zones are linked together via source_zone table - $source_zone_table = getTableForItemType(CarbonIntensitySource_Zone::class); + $source_zone_table = getTableForItemType(Source_Zone::class); $zone_table = $dbUtils->getTableForItemType(Zone::class); - $source_table = $dbUtils->getTableForItemType(CarbonIntensitySource::class); - $source_fk = getForeignKeyFieldForItemType(CarbonIntensitySource::class); + $source_table = $dbUtils->getTableForItemType(Source::class); + $source_fk = getForeignKeyFieldForItemType(Source::class); $zone_fk = getForeignKeyFieldForItemType(Zone::class); $iterator = $DB->request([ 'SELECT' => '*', @@ -779,17 +778,43 @@ public function checkSourceZoneRelation() /** @var DBmysql */ global $DB; - $source_table = CarbonIntensitySource::getTable(); + $source_table = Source::getTable(); $zone_table = Zone::getTable(); - $source_zone_table = CarbonIntensitySource_Zone::getTable(); + $source_zone_table = Source_Zone::getTable(); + + // Test that France and RTE are associated + $iterator = $DB->request([ + 'SELECT' => $source_zone_table . '.id', + 'FROM' => $source_zone_table, + 'INNER JOIN' => [ + $source_table => [ + 'FKEY' => [ + $source_zone_table => 'plugin_carbon_sources_id', + $source_table => 'id' + ] + ], + $zone_table => [ + 'FKEY' => [ + $source_zone_table => 'plugin_carbon_zones_id', + $zone_table => 'id' + ] + ] + ], + 'WHERE' => [ + $source_table . '.name' => 'RTE', + $zone_table . '.name' => 'France', + ], + ]); + $this->assertEquals(1, $iterator->count()); + // Test that Quebec and Hydroquebec are associated $iterator = $DB->request([ 'SELECT' => $source_zone_table . '.id', 'FROM' => $source_zone_table, 'INNER JOIN' => [ $source_table => [ 'FKEY' => [ - $source_zone_table => 'plugin_carbon_carbonintensitysources_id', + $source_zone_table => 'plugin_carbon_sources_id', $source_table => 'id' ] ], diff --git a/tests/integration/SearchOptionTest.php b/tests/integration/SearchOptionTest.php index d00f0ef7..d8bca027 100644 --- a/tests/integration/SearchOptionTest.php +++ b/tests/integration/SearchOptionTest.php @@ -45,14 +45,15 @@ use RecursiveDirectoryIterator; use CommonDBTM; use CommonGLPI; +use DBmysql; use DbUtils; use Plugin; use PHPUnit\Framework\Attributes\CoversMethod; #[CoversMethod('GlpiPlugin\Carbon\CarbonEmission', 'rawSearchOptions')] #[CoversMethod('GlpiPlugin\Carbon\CarbonIntensity', 'rawSearchOptions')] -#[CoversMethod('GlpiPlugin\Carbon\CarbonIntensitySource', 'rawSearchOptions')] -#[CoversMethod('GlpiPlugin\Carbon\CarbonIntensitySource_Zone', 'rawSearchOptions')] +#[CoversMethod('GlpiPlugin\Carbon\Source', 'rawSearchOptions')] +#[CoversMethod('GlpiPlugin\Carbon\Source_Zone', 'rawSearchOptions')] #[CoversMethod('GlpiPlugin\Carbon\ComputerUsageProfile', 'rawSearchOptions')] #[CoversMethod('GlpiPlugin\Carbon\EmbodiedImpact', 'rawSearchOptions')] #[CoversMethod('GlpiPlugin\Carbon\UsageImpact', 'rawSearchOptions')] @@ -85,16 +86,17 @@ class SearchOptionTest extends CommonTestCase private array $mapping = [ CarbonIntensity::class => [ - 'plugin_carbon_carbonintensitysources_id' => 'name', + 'plugin_carbon_sources_id' => 'name', 'plugin_carbon_zones_id' => 'name', ], Zone::class => [ - 'plugin_carbon_carbonintensitysources_id_historical' => 'name', + 'plugin_carbon_sources_id_historical' => 'name', ] ]; public function testSearchOption() { + /** @var DBmysql $DB */ global $DB; // Find each .php file in /src directory and subdirectories diff --git a/tests/migration/migration_to_1_2_0_Test.php b/tests/migration/migration_to_1_2_0_Test.php new file mode 100644 index 00000000..194e899e --- /dev/null +++ b/tests/migration/migration_to_1_2_0_Test.php @@ -0,0 +1,157 @@ +. + * + * ------------------------------------------------------------------------- + */ + +use DBmysql; +use Location as GlpiLocation; +use GlpiPlugin\Carbon\Tests\CommonTestCase; +use GlpiPlugin\Carbon\Tests\DbTestCase; +use GlpiPlugin\Carbon\Uninstall; + +class migration_to_1_2_0_Test extends DbTestCase +{ + public static function setUpBeforeClass(): void + { + global $DB; + + parent::setUpBeforeClass(); + $plugin = new Plugin(); + $plugin->getFromDBbyDir('carbon'); + if ($plugin->fields['state'] !== Plugin::ANEW && $plugin->fields['state'] !== Plugin::NOTINSTALLED) { + require_once(__DIR__ . '/../../install/Uninstall.php'); + $uninstall = new Uninstall(); + $uninstall->uninstall(); + } + + require_once(__DIR__ . '/../../setup.php'); + $sql_file = plugin_carbon_getSchemaPath('1.2.0'); + $success = $DB->runFile(realpath($sql_file)); + } + + public static function tearDownAfterClass(): void + { + parent::tearDownAfterClass(); + require_once(__DIR__ . '/../../install/Uninstall.php'); + $uninstall = new Uninstall(); + $uninstall->uninstall(); + } + + public function testUpdateCountryLocationZoneRelation() + { + /** @var DBMysql $DB */ + global $DB; + return; + + $glpi_location = $this->createItem(GlpiLocation::class, [ + 'country' => 'France', + ]); + $DB->insert('glpi_plugin_carbon_zones', [ + 'name' => 'France', + 'plugin_carbon_sources_id_historical' => 1, + ]); + $zone_id = $DB->insertId(); + $DB->insert('glpi_plugin_carbon_sources', [ + 'name' => 'RTE', + 'is_fallback' => 0, + 'is_carbon_intensity_source' => 1, + ]); + $source_id = $DB->insertId(); + $DB->insert('glpi_plugin_carbon_sources_zones', [ + 'plugin_carbon_sources_id' => $source_id, + 'plugin_carbon_zones_id' => $zone_id, + ]); + $source_zone_id = $DB->insertId(); + $migration_file = __DIR__ . '/../../install/migration/update_1.1.0_to_1.2.0/04_update_location_zone_relation.php'; + $migration_file = realpath($migration_file); + require($migration_file); + + $result = $DB->request([ + 'SELECT' => '*', + 'FROM' => 'glpi_plugin_carbon_locations', + 'WHERE' => [ + 'locations_id' => $glpi_location->getID(), + ], + ]); + $this->assertEquals(1, $result->count()); + $expected = [ + 'id' => $result->current()['id'], + 'locations_id' => $glpi_location->getID(), + 'boavizta_zone' => null, + 'plugin_carbon_sources_zones_id' => $source_zone_id, + ]; + $this->assertEquals($expected, $result->current()); + } + + public function testUpdateStateLocationZoneRelation() + { + /** @var DBMysql $DB */ + global $DB; + + $glpi_location = $this->createItem(GlpiLocation::class, [ + 'state' => 'foo state', + ]); + $DB->insert('glpi_plugin_carbon_zones', [ + 'name' => 'foo state', + 'plugin_carbon_sources_id_historical' => 1, + ]); + $zone_id = $DB->insertId(); + $DB->insert('glpi_plugin_carbon_sources', [ + 'name' => 'foo electricity distributor', + 'is_fallback' => 1, + 'is_carbon_intensity_source' => 1, + ]); + $source_id = $DB->insertId(); + $DB->insert('glpi_plugin_carbon_sources_zones', [ + 'plugin_carbon_sources_id' => $source_id, + 'plugin_carbon_zones_id' => $zone_id, + ]); + $source_zone_id = $DB->insertId(); + $migration_file = __DIR__ . '/../../install/migration/update_1.1.0_to_1.2.0/04_update_location_zone_relation.php'; + $migration_file = realpath($migration_file); + require($migration_file); + + $result = $DB->request([ + 'SELECT' => '*', + 'FROM' => 'glpi_plugin_carbon_locations', + 'WHERE' => [ + 'locations_id' => $glpi_location->getID(), + ], + ]); + $this->assertEquals(1, $result->count()); + $expected = [ + 'id' => $result->current()['id'], + 'locations_id' => $glpi_location->getID(), + 'boavizta_zone' => null, + 'plugin_carbon_sources_zones_id' => $source_zone_id, + ]; + $this->assertEquals($expected, $result->current()); + } +} diff --git a/tests/src/CommonTestCase.php b/tests/src/CommonTestCase.php index bc9c5666..32a16eea 100644 --- a/tests/src/CommonTestCase.php +++ b/tests/src/CommonTestCase.php @@ -46,7 +46,7 @@ use GlpiPlugin\Carbon\UsageInfo; use GlpiPlugin\Carbon\ComputerUsageProfile; use GlpiPlugin\Carbon\ComputerType; -use GlpiPlugin\Carbon\CarbonIntensitySource; +use GlpiPlugin\Carbon\Source; use GlpiPlugin\Carbon\Zone; use GlpiPlugin\Carbon\CarbonIntensity; use Entity; @@ -146,6 +146,10 @@ protected function getUniqueString() /** * @deprecated use createItem instead + * + * @param class-string $itemtype itemtype to create + * @param array $input + * @return T */ protected function getItem(string $itemtype, array $input = []): CommonDBTM { @@ -155,9 +159,10 @@ protected function getItem(string $itemtype, array $input = []): CommonDBTM /** * Create an item of the given itemtype * - * @param string $itemtype itemtype to create + * @template T of CommonDBTM + * @param class-string $itemtype itemtype to create * @param array $input - * @return CommonDBTM + * @return T */ protected function createItem(string $itemtype, array $input = []): CommonDBTM { @@ -286,10 +291,10 @@ protected function createComputerUsageProfilePowerLocation(array $usage_profile_ protected function createCarbonIntensityData(string $country, string $source_name, DateTimeInterface $begin_date, float $intensity, string $length = 'P2D') { - $source = new CarbonIntensitySource(); + $source = new Source(); $source->getFromDBByCrit(['name' => $source_name]); if ($source->isNewItem()) { - $source = $this->createItem(CarbonIntensitySource::class, [ + $source = $this->createItem(Source::class, [ 'name' => $source_name ]); } @@ -299,7 +304,7 @@ protected function createCarbonIntensityData(string $country, string $source_nam if ($zone->isNewItem()) { $zone = $this->createItem(Zone::class, [ 'name' => $country, - 'plugin_carbon_carbonintensitysources_id_historical' => $source->getID() + 'plugin_carbon_sources_id_historical' => $source->getID() ]); } @@ -310,7 +315,7 @@ protected function createCarbonIntensityData(string $country, string $source_nam $one_hour = new DateInterval('PT1H'); while ($current_date < $end_date) { $crit = [ - CarbonIntensitySource::getForeignKeyField() => $source->getID(), + Source::getForeignKeyField() => $source->getID(), Zone::getForeignKeyField() => $zone->getID(), 'date' => $current_date->format('Y-m-d H:00:00'), 'intensity' => $intensity, diff --git a/tests/src/GlobalFixture.php b/tests/src/GlobalFixture.php index cd6abbe1..531fa4c8 100644 --- a/tests/src/GlobalFixture.php +++ b/tests/src/GlobalFixture.php @@ -71,7 +71,7 @@ public static function loadDataset() Config::setConfigurationValues('core', ['timezone' => 'Europe/Paris']); $DB->beginTransaction(); - $source_table = 'glpi_plugin_carbon_carbonintensitysources'; + $source_table = 'glpi_plugin_carbon_sources'; $fake_source_name = 'Fake source'; $iterator = $DB->request([ 'SELECT' => ['id'], @@ -101,24 +101,24 @@ public static function loadDataset() if ($iterator->count() === 0) { $result = $DB->insert($zone_table, [ 'name' => $fake_zone_name, - 'plugin_carbon_carbonintensitysources_id_historical' => $source_id, + 'plugin_carbon_sources_id_historical' => $source_id, ]); $zone_id = $DB->insertId(); } else { $zone_id = $iterator->current()['id']; } - $source_zone_table = 'glpi_plugin_carbon_carbonintensitysources_zones'; + $source_zone_table = 'glpi_plugin_carbon_sources_zones'; $iterator = $DB->request([ 'SELECT' => ['id'], 'FROM' => $source_zone_table, 'WHERE' => [ - 'plugin_carbon_carbonintensitysources_id' => $source_id, + 'plugin_carbon_sources_id' => $source_id, 'plugin_carbon_zones_id' => $zone_id, ], ]); if ($iterator->count() === 0) { $result = $DB->insert($source_zone_table, [ - 'plugin_carbon_carbonintensitysources_id' => $source_id, + 'plugin_carbon_sources_id' => $source_id, 'plugin_carbon_zones_id' => $zone_id, 'code' => 'FZ', ]); @@ -135,7 +135,7 @@ public static function loadDataset() } while (($row = fgetcsv($handle, 256, ',', '"', '\\')) !== false) { $DB->insert($intensity_table, [ - 'plugin_carbon_carbonintensitysources_id' => $source_id, + 'plugin_carbon_sources_id' => $source_id, 'plugin_carbon_zones_id' => $zone_id, 'date' => $row[0], 'intensity' => $row[1], @@ -143,7 +143,7 @@ public static function loadDataset() } // ini_set('auto_detect_line_endings', $line_ending_mode); $condition = [ - 'plugin_carbon_carbonintensitysources_id' => $source_id, + 'plugin_carbon_sources_id' => $source_id, 'plugin_carbon_zones_id' => $zone_id, ]; $count = (new DbUtils())->countElementsInTable($intensity_table, $condition); diff --git a/tests/units/CarbonIntensitySource_ZoneTest.php b/tests/units/CarbonIntensitySource_ZoneTest.php deleted file mode 100644 index 3e4749be..00000000 --- a/tests/units/CarbonIntensitySource_ZoneTest.php +++ /dev/null @@ -1,104 +0,0 @@ -. - * - * ------------------------------------------------------------------------- - */ - -namespace GlpiPlugin\Carbon\Tests; - -use GlpiPlugin\Carbon\CarbonIntensitySource; -use GlpiPlugin\Carbon\CarbonIntensitySource_Zone; -use GlpiPlugin\Carbon\Tests\DbTestCase; -use GlpiPlugin\Carbon\Zone; -use PHPUnit\Framework\Attributes\CoversMethod; - -class CarbonIntensitySource_ZoneTest extends DbTestCase -{ - /** - * #CoversMethod GlpiPlugin\Carbon\CarbonIntensitySource_Zone::showForSource - */ - public function testShowForSource() - { - $source = $this->createItem(CarbonIntensitySource::class, [ - 'name' => 'foo' - ]); - - $zone = $this->createItem(Zone::class, [ - 'name' => 'bar' - ]); - - $instance = $this->createItem(CarbonIntensitySource_Zone::class, [ - $source::getForeignKeyField() => $source->getID(), - $zone::getForeignKeyField() => $zone->getID(), - ]); - - $this->logout(); - ob_start(); - $result = $instance->showForSource($source); - $output = ob_get_clean(); - $this->assertEquals('', $output); - - $this->login('glpi', 'glpi'); - ob_start(); - $result = $instance->showForSource($source); - $output = ob_get_clean(); - $this->assertNotEmpty($output); - } - - /** - * #CoversMethod GlpiPlugin\Carbon\CarbonIntensitySource_Zone::showForZone - */ - public function testShowForZone() - { - $source = $this->createItem(CarbonIntensitySource::class, [ - 'name' => 'foo' - ]); - - $zone = $this->createItem(Zone::class, [ - 'name' => 'bar' - ]); - - $instance = $this->createItem(CarbonIntensitySource_Zone::class, [ - $source::getForeignKeyField() => $source->getID(), - $zone::getForeignKeyField() => $zone->getID(), - ]); - - $this->logout(); - ob_start(); - $result = $instance->showForZone($zone); - $output = ob_get_clean(); - $this->assertEquals('', $output); - - $this->login('glpi', 'glpi'); - ob_start(); - $result = $instance->showForZone($zone); - $output = ob_get_clean(); - $this->assertNotEmpty($output); - } -} diff --git a/tests/units/CarbonIntensityTest.php b/tests/units/CarbonIntensityTest.php index 2c6a3793..23ff95f2 100644 --- a/tests/units/CarbonIntensityTest.php +++ b/tests/units/CarbonIntensityTest.php @@ -39,8 +39,8 @@ use GlpiPlugin\Carbon\CarbonIntensity; use GlpiPlugin\Carbon\Tests\DbTestCase; use GlpiPlugin\Carbon\Zone; -use GlpiPlugin\Carbon\CarbonIntensitySource; -use GlpiPlugin\Carbon\CarbonIntensitySource_Zone; +use GlpiPlugin\Carbon\Source; +use GlpiPlugin\Carbon\Source_Zone; use GlpiPlugin\Carbon\DataSource\AbstractCarbonIntensity; use GlpiPlugin\Carbon\DataSource\CarbonIntensity\AbstractClient; use Infocom; @@ -60,10 +60,10 @@ public function testGetLastKnownDate() $zone = $this->createItem(Zone::class, [ 'name' => 'foo', ]); - $source = $this->createItem(CarbonIntensitySource::class, [ + $source = $this->createItem(Source::class, [ 'name' => 'bar' ]); - $source_zone = $this->createItem(CarbonIntensitySource_Zone::class, [ + $source_zone = $this->createItem(Source_Zone::class, [ $source::getForeignKeyField() => $source->getID(), $zone::getForeignKeyField() => $zone->getID() ]); @@ -98,10 +98,10 @@ public function testGetFirstKnownDate() $zone = $this->createItem(Zone::class, [ 'name' => 'foo', ]); - $source = $this->createItem(CarbonIntensitySource::class, [ + $source = $this->createItem(Source::class, [ 'name' => 'bar' ]); - $source_zone = $this->createItem(CarbonIntensitySource_Zone::class, [ + $source_zone = $this->createItem(Source_Zone::class, [ $source::getForeignKeyField() => $source->getID(), $zone::getForeignKeyField() => $zone->getID() ]); @@ -147,15 +147,15 @@ public function testFindGaps() $this->login('glpi', 'glpi'); - $source = $this->createItem(CarbonIntensitySource::class, [ + $source = $this->createItem(Source::class, [ 'name' => 'test_source', ]); $zone = $this->createItem(Zone::class, [ 'name' => 'test_zone', - 'plugin_carbon_carbonintensitysources_id_historical' => $source->getID(), + 'plugin_carbon_sources_id_historical' => $source->getID(), ]); - $source_zone = $this->createItem(CarbonIntensitySource_Zone::class, [ - 'plugin_carbon_carbonintensitysources_id' => $source->getID(), + $source_zone = $this->createItem(Source_Zone::class, [ + 'plugin_carbon_sources_id' => $source->getID(), 'plugin_carbon_zones_id' => $zone->getID(), ]); @@ -167,7 +167,7 @@ public function testFindGaps() while ($cursor_date < $end_date) { $DB->insert($table, [ 'date' => $cursor_date->format('Y-m-d H:i:s'), - 'plugin_carbon_carbonintensitysources_id' => $source->getID(), + 'plugin_carbon_sources_id' => $source->getID(), 'plugin_carbon_zones_id' => $zone->getID(), 'intensity' => 1, ]); @@ -181,7 +181,7 @@ public function testFindGaps() // delete some samples at the beginning $delete_before_date = new DateTime('2024-01-03 12:00:00'); $DB->delete($table, [ - 'plugin_carbon_carbonintensitysources_id' => $source->getID(), + 'plugin_carbon_sources_id' => $source->getID(), 'plugin_carbon_zones_id' => $zone->getID(), 'date' => ['<', $delete_before_date->format('Y-m-d H:i:s')], ]); @@ -197,7 +197,7 @@ public function testFindGaps() // delete some samples at the end $delete_after_date = new DateTime('2024-02-17 09:00:00'); $DB->delete($table, [ - 'plugin_carbon_carbonintensitysources_id' => $source->getID(), + 'plugin_carbon_sources_id' => $source->getID(), 'plugin_carbon_zones_id' => $zone->getID(), 'date' => ['>=', $delete_after_date->format('Y-m-d H:i:s')], ]); @@ -217,7 +217,7 @@ public function testFindGaps() $delete_middle_start_date = new DateTime('2024-01-29 06:00:00'); $delete_middle_end_date = new DateTime('2024-02-05 18:00:00'); $DB->delete($table, [ - 'plugin_carbon_carbonintensitysources_id' => $source->getID(), + 'plugin_carbon_sources_id' => $source->getID(), 'plugin_carbon_zones_id' => $zone->getID(), 'AND' => [ ['date' => ['>=', $delete_middle_start_date->format('Y-m-d H:i:s')]], @@ -245,7 +245,7 @@ public function testFindGaps() while ($cursor_date < $delete_before_date) { $DB->insert($table, [ 'date' => $cursor_date->format('Y-m-d H:i:s'), - 'plugin_carbon_carbonintensitysources_id' => $source->getID(), + 'plugin_carbon_sources_id' => $source->getID(), 'plugin_carbon_zones_id' => $zone->getID(), 'intensity' => 1, ]); @@ -269,7 +269,7 @@ public function testFindGaps() while ($cursor_date < $delete_middle_end_date) { $DB->insert($table, [ 'date' => $cursor_date->format('Y-m-d H:i:s'), - 'plugin_carbon_carbonintensitysources_id' => $source->getID(), + 'plugin_carbon_sources_id' => $source->getID(), 'plugin_carbon_zones_id' => $zone->getID(), 'intensity' => 1, ]); @@ -324,11 +324,11 @@ public function testGetDownloadStopDate() $zone = $this->createItem(Zone::class, [ 'name' => 'foo', ]); - $source = $this->createItem(CarbonIntensitySource::class, [ + $source = $this->createItem(Source::class, [ 'name' => 'bar' ]); $expected = new DateTimeImmutable('2019-01-31 23:00:00'); - $source_zone = $this->createItem(CarbonIntensitySource_Zone::class, [ + $source_zone = $this->createItem(Source_Zone::class, [ $source::getForeignKeyField() => $source->getID(), $zone::getForeignKeyField() => $zone->getID(), ]); @@ -352,10 +352,10 @@ public function testDownloadOneZone() $zone = $this->createItem(Zone::class, [ 'name' => 'foo', ]); - $source = $this->createItem(CarbonIntensitySource::class, [ + $source = $this->createItem(Source::class, [ 'name' => 'bar' ]); - $source_zone = $this->createItem(CarbonIntensitySource_Zone::class, [ + $source_zone = $this->createItem(Source_Zone::class, [ $source::getForeignKeyField() => $source->getID(), $zone::getForeignKeyField() => $zone->getID() ]); diff --git a/tests/units/CronTaskTest.php b/tests/units/CronTaskTest.php index 417e04e7..f0371078 100644 --- a/tests/units/CronTaskTest.php +++ b/tests/units/CronTaskTest.php @@ -137,7 +137,7 @@ public function testFillIncompleteLocations() ]); // Test a single - $glpi_locations = $this->getItems([ + $glpi_locations = $this->createItems([ GlpiLocation::class => [ [ 'name' => 'Valid Location', diff --git a/tests/units/Dashboard/ProviderTest.php b/tests/units/Dashboard/ProviderTest.php index fda3baa6..b574e395 100644 --- a/tests/units/Dashboard/ProviderTest.php +++ b/tests/units/Dashboard/ProviderTest.php @@ -41,11 +41,14 @@ use GlpiPlugin\Carbon\ComputerType; use GlpiPlugin\Carbon\ComputerUsageProfile; use GlpiPlugin\Carbon\Dashboard\Provider; +use GlpiPlugin\Carbon\Location; +use GlpiPlugin\Carbon\Source; +use GlpiPlugin\Carbon\Source_Zone; use GlpiPlugin\Carbon\UsageInfo; -use GlpiPlugin\Carbon\Impact\History\Computer as HistoryComputer; use GlpiPlugin\Carbon\Tests\DbTestCase; +use GlpiPlugin\Carbon\Zone; use Infocom; -use Location; +use Location as GlpiLocation; use PHPUnit\Framework\Attributes\CoversClass; use Session; @@ -88,15 +91,17 @@ protected function handledComputersCountFixture(): int 'power_consumption' => 150, ]); - $location_empty = $this->createItem(Location::class); - // $location_empty_2 = $this->createItem(Location::class, [ - // 'latitude' => 1, - // ]); - // $location_empty_3 = $this->createItem(Location::class, [ - // 'longitude' => 1, - // ]); + $glpi_location_empty = $this->createItem(GlpiLocation::class); + $glpi_location = $this->createItem(GlpiLocation::class); + $source = $this->createItem(Source::class); + $zone = $this->createItem(Zone::class); + $source_zone = $this->createItem(Source_Zone::class, [ + 'plugin_carbon_sources_id' => $source->getID(), + 'plugin_carbo_zones_id' => $zone->getID(), + ]); $location = $this->createItem(Location::class, [ - 'country' => 'France', + 'locations_id' => $glpi_location->getID(), + $source_zone::getForeignKeyField() => $source_zone->getID(), ]); $usage_profile = $this->createItem(ComputerUsageProfile::class); @@ -107,51 +112,51 @@ protected function handledComputersCountFixture(): int [ 'computermodels_id' => $computer_model_empty->getID(), 'computertypes_id' => $glpi_computer_type_empty->getID(), - 'locations_id' => $location_empty->getID(), + 'locations_id' => $glpi_location_empty->getID(), ], [ 'computermodels_id' => $computer_model->getID(), 'computertypes_id' => $glpi_computer_type_empty->getID(), - 'locations_id' => $location_empty->getID(), + 'locations_id' => $glpi_location_empty->getID(), ], [ 'computermodels_id' => $computer_model_empty->getID(), 'computertypes_id' => $glpi_computer_type->getID(), - 'locations_id' => $location_empty->getID(), + 'locations_id' => $glpi_location_empty->getID(), ], [ 'computermodels_id' => $computer_model->getID(), 'computertypes_id' => $glpi_computer_type->getID(), - 'locations_id' => $location_empty->getID(), + 'locations_id' => $glpi_location_empty->getID(), ], [ 'computermodels_id' => $computer_model_empty->getID(), 'computertypes_id' => $glpi_computer_type_empty->getID(), - 'locations_id' => $location->getID(), + 'locations_id' => $glpi_location->getID(), ], [ 'computermodels_id' => $computer_model->getID(), 'computertypes_id' => $glpi_computer_type_empty->getID(), - 'locations_id' => $location->getID(), + 'locations_id' => $glpi_location->getID(), ], [ 'computermodels_id' => $computer_model_empty->getID(), 'computertypes_id' => $glpi_computer_type->getID(), - 'locations_id' => $location->getID(), + 'locations_id' => $glpi_location->getID(), ], [ 'computermodels_id' => $computer_model->getID(), 'computertypes_id' => $glpi_computer_type->getID(), - 'locations_id' => $location->getID(), + 'locations_id' => $glpi_location->getID(), ], ] ]; - $computers = $this->getItems($computers_definition); + $computers = $this->createItems($computers_definition); $total_count += count($computers[Computer::class]); // computers with a usage profile; 3 of them are complete - $computers = $this->getItems($computers_definition); + $computers = $this->createItems($computers_definition); $total_count += count($computers[Computer::class]); foreach ($computers[Computer::class] as $computers_id => $computer) { $impact = $this->createItem(UsageInfo::class, [ @@ -199,10 +204,16 @@ public function testGetSumUsageEmissionsPerModel() $computer_type = $this->createItem(GlpiComputerType::class); $computer_model_1 = $this->createItem(ComputerModel::class); $computer_model_2 = $this->createItem(ComputerModel::class); + $source = $this->createItem(Source::class); + $zone = $this->createItem(Zone::class); + $source_zone = $this->createItem(Source_Zone::class, [ + 'plugin_carbon_sources_id' => $source->getID(), + 'plugin_carbo_zones_id' => $zone->getID(), + ]); + $glpi_location = $this->createItem(GlpiLocation::class); $location = $this->createItem(Location::class, [ - 'latitude' => '48.864716', - 'longitude' => '2.349014', - 'country' => 'France' + 'locations_id' => $glpi_location->getID(), + $source_zone::getForeignKeyField() => $source_zone->getID(), ]); $computer_1 = $this->createItem(Computer::class); $computer_2 = $this->createItem(Computer::class); @@ -221,7 +232,7 @@ public function testGetSumUsageEmissionsPerModel() 'entities_id' => $entities_id, 'types_id' => $computer_type->getID(), 'models_id' => $computer_model_1->getID(), - 'locations_id' => $location->getID(), + 'locations_id' => $glpi_location->getID(), 'energy_per_day' => 0.5, 'emission_per_day' => 1, 'date' => $date->format('Y-m-d'), @@ -231,7 +242,7 @@ public function testGetSumUsageEmissionsPerModel() 'entities_id' => $entities_id, 'types_id' => $computer_type->getID(), 'models_id' => $computer_model_2->getID(), - 'locations_id' => $location->getID(), + 'locations_id' => $glpi_location->getID(), 'energy_per_day' => 1, 'emission_per_day' => 2, 'date' => $date->format('Y-m-d'), @@ -239,7 +250,7 @@ public function testGetSumUsageEmissionsPerModel() ] ]; - $items = $this->getItems($rows); + $items = $this->createItems($rows); } $output = Provider::getSumUsageEmissionsPerModel(); diff --git a/tests/units/DataSource/CarbonIntensity/ElectricityMapClientTest.php b/tests/units/DataSource/CarbonIntensity/ElectricityMapClientTest.php index 358c0c40..7be47381 100644 --- a/tests/units/DataSource/CarbonIntensity/ElectricityMapClientTest.php +++ b/tests/units/DataSource/CarbonIntensity/ElectricityMapClientTest.php @@ -34,11 +34,11 @@ use GlpiPlugin\Carbon\DataSource\CarbonIntensity\ElectricityMapClient; use GlpiPlugin\Carbon\DataSource\RestApiClientInterface; -use GlpiPlugin\Carbon\CarbonIntensitySource; +use GlpiPlugin\Carbon\Source; use GlpiPlugin\Carbon\Zone; use GlpiPlugin\Carbon\Tests\DbTestCase; use DateTimeImmutable; -use GlpiPlugin\Carbon\CarbonIntensitySource_Zone; +use GlpiPlugin\Carbon\Source_Zone; class ElectricityMapClientTest extends DbTestCase { @@ -75,14 +75,14 @@ public function testFetchDay() /** @var RestApiClientInterface $client */ $data_source = new ElectricityMapClient($client); - $source = new CarbonIntensitySource(); + $source = new Source(); $source->getFromDBByCrit(['name' => $data_source->getSourceName()]); $this->assertFalse($source->isNewItem()); $zone = new Zone(); $zone->getFromDbByCrit(['name' => 'France']); $this->assertFalse($zone->isNewItem()); - $source_zone = $this->createItem(CarbonIntensitySource_Zone::class, [ - CarbonIntensitySource::getForeignKeyField() => $source->getID(), + $source_zone = $this->createItem(Source_Zone::class, [ + Source::getForeignKeyField() => $source->getID(), Zone::getForeignKeyField() => $zone->getID(), 'code' => 'FR' ]); diff --git a/tests/units/Engine/V1/InventoryTest.php b/tests/units/Engine/V1/InventoryTest.php index 665ac340..66c9f4b3 100644 --- a/tests/units/Engine/V1/InventoryTest.php +++ b/tests/units/Engine/V1/InventoryTest.php @@ -57,7 +57,7 @@ public function testAddItemByCrit() $this->login('glpi', 'glpi'); $entities_id = $this->isolateInEntity('glpi', 'glpi'); - $computers = $this->getItems([ + $computers = $this->createItems([ Computer::class => [ [], [], diff --git a/tests/units/Impact/History/ComputerTest.php b/tests/units/Impact/History/ComputerTest.php index b1050bf4..3e795aca 100644 --- a/tests/units/Impact/History/ComputerTest.php +++ b/tests/units/Impact/History/ComputerTest.php @@ -32,12 +32,10 @@ namespace GlpiPlugin\Carbon\Impact\History\Tests; -use CommonDBTM; use Computer as GlpiComputer; -use DateInterval; use GlpiPlugin\Carbon\Impact\History\Computer; use GlpiPlugin\Carbon\Tests\Impact\History\CommonAsset; -use Location; +use Location as GlpiLocation; use ComputerModel as GlpiComputerModel; use ComputerType as GlpiComputerType; use DateTime; @@ -45,6 +43,9 @@ use GlpiPlugin\Carbon\CarbonEmission; use GlpiPlugin\Carbon\ComputerType; use GlpiPlugin\Carbon\ComputerUsageProfile; +use GlpiPlugin\Carbon\Location; +use GlpiPlugin\Carbon\Source; +use GlpiPlugin\Carbon\Source_Zone; use GlpiPlugin\Carbon\UsageInfo; use GlpiPlugin\Carbon\Zone; @@ -85,9 +86,26 @@ public function testEvaluateItem() $entities_id = $this->isolateInEntity('glpi', 'glpi'); $model_power = 55; - $location = $this->createItem(Location::class, [ + $glpi_location = $this->createItem(GlpiLocation::class, [ 'state' => 'Quebec', ]); + $source = new Source(); // This source exists after a fresh install + $source->getFromDBByCrit([ + 'name' => 'Hydro Quebec' + ]); + $zone = new Zone(); // This zone exists after a fresh install + $zone->getFromDBByCrit([ + 'name' => 'Quebec' + ]); + $source_zone = new Source_Zone(); // the relation source / zone also exists after a fresh install + $source_zone->getFromDBByCrit([ + $source::getForeignKeyField() => $source->getID(), + $zone::getForeignKeyField() => $zone->getID() + ]); + $location = $this->createItem(Location::class, [ + 'locations_id' => $glpi_location->getID(), + 'plugin_carbon_sources_zones_id' => $source_zone->getID() + ]); $model = $this->createItem(GlpiComputerModel::class, ['power_consumption' => $model_power]); $glpi_type = $this->createItem(GlpiComputerType::class); $type = $this->createItem(ComputerType::class, [ @@ -96,7 +114,7 @@ public function testEvaluateItem() $asset = $this->createItem(GlpiComputer::class, [ 'computertypes_id' => $glpi_type->getID(), 'computermodels_id' => $model->getID(), - 'locations_id' => $location->getID(), + 'locations_id' => $glpi_location->getID(), 'date_creation' => '2024-01-01', 'date_mod' => null, ]); @@ -203,17 +221,30 @@ public function testCanHistorize() $this->assertFalse($history->canHistorize($id)); // Add an empty location - $location = $this->createItem(Location::class); + $glpi_location = $this->createItem(GlpiLocation::class); $computer->update([ 'id' => $id, - 'locations_id' => $location->getID(), + 'locations_id' => $glpi_location->getID(), ]); $this->assertFalse($history->canHistorize($id)); - // Add a country to the location - $location->update([ - 'id' => $location->getID(), - 'country' => 'France', + // Add a zone to the location + $source = new Source(); // This source exists after a fresh install + $source->getFromDBByCrit([ + 'name' => 'RTE' + ]); + $zone = new Zone(); // This zone exists after a fresh install + $zone->getFromDBByCrit([ + 'name' => 'France' + ]); + $source_zone = new Source_Zone(); // the relation source / zone also exists after a fresh install + $source_zone->getFromDBByCrit([ + $source::getForeignKeyField() => $source->getID(), + $zone::getForeignKeyField() => $zone->getID() + ]); + $location = $this->createItem(Location::class, [ + 'locations_id' => $glpi_location->getID(), + 'plugin_carbon_sources_zones_id' => $source_zone->getID(), ]); $this->assertFalse($history->canHistorize($id)); @@ -316,7 +347,7 @@ public function testEmptyComputerIsNotHistorizable() 'is_deleted' => true, 'is_template' => true, 'has_location' => false, - 'has_state_or_country' => false, + 'has_carbon_intensity_zone' => false, 'has_model' => false, 'has_model_power_consumption' => false, 'has_type' => false, @@ -347,7 +378,7 @@ public function testComputerWithEmptyInfocomIsNotHistorizable() 'is_deleted' => true, 'is_template' => true, 'has_location' => false, - 'has_state_or_country' => false, + 'has_carbon_intensity_zone' => false, 'has_model' => false, 'has_model_power_consumption' => false, 'has_type' => false, @@ -379,7 +410,7 @@ public function testComputerWithEntryDateIsNotHistorizable() 'is_deleted' => true, 'is_template' => true, 'has_location' => false, - 'has_state_or_country' => false, + 'has_carbon_intensity_zone' => false, 'has_model' => false, 'has_model_power_consumption' => false, 'has_type' => false, @@ -400,15 +431,15 @@ public function testComputerWithEmptyLocationIsNotHistorizable() { $history = new Computer(); - $location = $this->createItem(Location::class); + $glpi_location = $this->createItem(GlpiLocation::class); $computer = $this->createItem(GlpiComputer::class, [ - 'locations_id' => $location->getID(), + 'locations_id' => $glpi_location->getID(), ]); $expected = [ 'is_deleted' => true, 'is_template' => true, 'has_location' => true, - 'has_state_or_country' => false, + 'has_carbon_intensity_zone' => false, 'has_model' => false, 'has_model_power_consumption' => false, 'has_type' => false, @@ -425,52 +456,36 @@ public function testComputerWithEmptyLocationIsNotHistorizable() $this->assertFalse($result); } - public function testComputerWithLocationAndCountryIsNotHistorizable() + public function testComputerWithLocationAndZoneIsNotHistorizable() { $history = new Computer(); - $location = $this->createItem(Location::class, [ - 'country' => 'France' + $glpi_location = $this->createItem(GlpiLocation::class); + $source = new Source(); // This source exists after a fresh install + $source->getFromDBByCrit([ + 'name' => 'RTE' ]); - $computer = $this->createItem(GlpiComputer::class, [ - 'locations_id' => $location->getID(), + $zone = new Zone(); // This zone exists after a fresh install + $zone->getFromDBByCrit([ + 'name' => 'France' + ]); + $source_zone = new Source_Zone(); // the relation source / zone also exists after a fresh install + $source_zone->getFromDBByCrit([ + $source::getForeignKeyField() => $source->getID(), + $zone::getForeignKeyField() => $zone->getID() ]); - $expected = [ - 'is_deleted' => true, - 'is_template' => true, - 'has_location' => true, - 'has_state_or_country' => true, - 'has_model' => false, - 'has_model_power_consumption' => false, - 'has_type' => false, - 'has_type_power_consumption' => false, - 'has_usage_profile' => false, - 'has_category' => false, - 'has_inventory_entry_date' => false, - 'ci_download_enabled' => false, - 'ci_fallback_available' => true, - ]; - $result = $history->getHistorizableDiagnosis($computer); - $this->assertEquals($expected, $result); - $result = $history->canHistorize($computer->getID()); - $this->assertFalse($result); - } - - public function testComputerWithLocationAndStateIsNotHistorizable() - { - $history = new Computer(); - $location = $this->createItem(Location::class, [ - 'state' => 'Quebec' + 'locations_id' => $glpi_location->getID(), + 'plugin_carbon_sources_zones_id' => $source_zone->getID(), ]); $computer = $this->createItem(GlpiComputer::class, [ - 'locations_id' => $location->getID(), + 'locations_id' => $glpi_location->getID(), ]); $expected = [ 'is_deleted' => true, 'is_template' => true, 'has_location' => true, - 'has_state_or_country' => true, + 'has_carbon_intensity_zone' => true, 'has_model' => false, 'has_model_power_consumption' => false, 'has_type' => false, @@ -478,8 +493,8 @@ public function testComputerWithLocationAndStateIsNotHistorizable() 'has_usage_profile' => false, 'has_category' => false, 'has_inventory_entry_date' => false, - 'ci_download_enabled' => false, - 'ci_fallback_available' => true, + 'ci_download_enabled' => true, + 'ci_fallback_available' => false, ]; $result = $history->getHistorizableDiagnosis($computer); $this->assertEquals($expected, $result); @@ -502,7 +517,7 @@ public function testComputerWithUsageProfileIsNotHistorizable() 'is_deleted' => true, 'is_template' => true, 'has_location' => false, - 'has_state_or_country' => false, + 'has_carbon_intensity_zone' => false, 'has_model' => false, 'has_model_power_consumption' => false, 'has_type' => false, @@ -523,15 +538,15 @@ public function testComputerWithEmptyModelIsNotHistorizable() { $history = new Computer(); - $model = $this->createItem(GlpiComputerModel::class); + $glpi_model = $this->createItem(GlpiComputerModel::class); $computer = $this->createItem(GlpiComputer::class, [ - 'computermodels_id' => $model->getID(), + 'computermodels_id' => $glpi_model->getID(), ]); $expected = [ 'is_deleted' => true, 'is_template' => true, 'has_location' => false, - 'has_state_or_country' => false, + 'has_carbon_intensity_zone' => false, 'has_model' => true, 'has_model_power_consumption' => false, 'has_type' => false, @@ -562,7 +577,7 @@ public function testComputerWithModelIsNotHistorizable() 'is_deleted' => true, 'is_template' => true, 'has_location' => false, - 'has_state_or_country' => false, + 'has_carbon_intensity_zone' => false, 'has_model' => true, 'has_model_power_consumption' => true, 'has_type' => false, @@ -591,7 +606,7 @@ public function testComputerWithEmptyTypeIsNotHistorizable() 'is_deleted' => true, 'is_template' => true, 'has_location' => false, - 'has_state_or_country' => false, + 'has_carbon_intensity_zone' => false, 'has_model' => false, 'has_model_power_consumption' => false, 'has_type' => true, @@ -624,7 +639,7 @@ public function testComputerWithTypeIsNotHistorizable() 'is_deleted' => true, 'is_template' => true, 'has_location' => false, - 'has_state_or_country' => false, + 'has_carbon_intensity_zone' => false, 'has_model' => false, 'has_model_power_consumption' => false, 'has_type' => true, @@ -657,7 +672,7 @@ public function testComputerWithCategoryIsNotHistorizable() 'is_deleted' => true, 'is_template' => true, 'has_location' => false, - 'has_state_or_country' => false, + 'has_carbon_intensity_zone' => false, 'has_model' => false, 'has_model_power_consumption' => false, 'has_type' => true, @@ -678,8 +693,23 @@ public function testComputerWithEverythingIsHistorizable() { $history = new Computer(); + $glpi_location = $this->createItem(GlpiLocation::class); + $source = new Source(); // This source exists after a fresh install + $source->getFromDBByCrit([ + 'name' => 'RTE' + ]); + $zone = new Zone(); // This zone exists after a fresh install + $zone->getFromDBByCrit([ + 'name' => 'France' + ]); + $source_zone = new Source_Zone(); // the relation source / zone also exists after a fresh install + $source_zone->getFromDBByCrit([ + $source::getForeignKeyField() => $source->getID(), + $zone::getForeignKeyField() => $zone->getID() + ]); $location = $this->createItem(Location::class, [ - 'country' => 'France' + 'locations_id' => $glpi_location->getID(), + 'plugin_carbon_sources_zones_id' => $source_zone->getID() ]); $glpi_computer_type = $this->createItem(GlpiComputerType::class); $computer_type = $this->createItem(ComputerType::class, [ @@ -687,7 +717,7 @@ public function testComputerWithEverythingIsHistorizable() 'computertypes_id' => $glpi_computer_type->getID(), ]); $computer = $this->createItem(GlpiComputer::class, [ - 'locations_id' => $location->getID(), + 'locations_id' => $glpi_location->getID(), 'computertypes_id' => $glpi_computer_type->getID(), ]); $management = $this->createItem(Infocom::class, [ @@ -705,7 +735,7 @@ public function testComputerWithEverythingIsHistorizable() 'is_deleted' => true, 'is_template' => true, 'has_location' => true, - 'has_state_or_country' => true, + 'has_carbon_intensity_zone' => true, 'has_model' => false, 'has_model_power_consumption' => false, 'has_type' => true, @@ -713,8 +743,8 @@ public function testComputerWithEverythingIsHistorizable() 'has_usage_profile' => true, 'has_category' => false, 'has_inventory_entry_date' => true, - 'ci_download_enabled' => false, - 'ci_fallback_available' => true, + 'ci_download_enabled' => true, + 'ci_fallback_available' => false, ]; $result = $history->getHistorizableDiagnosis($computer); $this->assertEquals($expected, $result); diff --git a/tests/units/Impact/History/MonitorTest.php b/tests/units/Impact/History/MonitorTest.php index 4d931898..a2daf7cd 100644 --- a/tests/units/Impact/History/MonitorTest.php +++ b/tests/units/Impact/History/MonitorTest.php @@ -35,22 +35,27 @@ use CommonDBTM; use Computer as GlpiComputer; use ComputerModel; -use Computer_Item; use Monitor as GlpiMonitor; use GlpiPlugin\Carbon\Impact\History\Monitor; use GlpiPlugin\Carbon\Tests\Impact\History\CommonAsset; use Infocom; -use Location; +use Location as GlpiLocation; use DateTime; use MonitorModel as GlpiMonitorModel; use MonitorType as GlpiMonitorType; use ComputerType as GlpiComputerType; use DBmysql; +use Glpi\Asset\Asset_PeripheralAsset; +use Computer_Item; use GlpiPlugin\Carbon\CarbonEmission; use GlpiPlugin\Carbon\ComputerType; use GlpiPlugin\Carbon\ComputerUsageProfile; +use GlpiPlugin\Carbon\Location; use GlpiPlugin\Carbon\MonitorType; +use GlpiPlugin\Carbon\Source; +use GlpiPlugin\Carbon\Source_Zone; use GlpiPlugin\Carbon\UsageInfo; +use GlpiPlugin\Carbon\Zone; /** * #CoversMethod \GlpiPlugin\Carbon\Impact\History\Monitor @@ -90,9 +95,26 @@ public function testEvaluateItem() $entities_id = $this->isolateInEntity('glpi', 'glpi'); $model_power = 55; - $location = $this->createItem(Location::class, [ + $glpi_location = $this->createItem(GlpiLocation::class, [ 'state' => 'Quebec', ]); + $source = new Source(); // This source exists after a fresh install + $source->getFromDBByCrit([ + 'name' => 'Hydro Quebec' + ]); + $zone = new Zone(); // This zone exists after a fresh install + $zone->getFromDBByCrit([ + 'name' => 'Quebec' + ]); + $source_zone = new Source_Zone(); // the relation source / zone also exists after a fresh install + $source_zone->getFromDBByCrit([ + $source::getForeignKeyField() => $source->getID(), + $zone::getForeignKeyField() => $zone->getID() + ]); + $location = $this->createItem(Location::class, [ + 'locations_id' => $glpi_location->getID(), + 'plugin_carbon_sources_zones_id' => $source_zone->getID() + ]); $computer_model_power = 80; $computer_model = $this->createItem(ComputerModel::class, ['power_consumption' => $computer_model_power]); @@ -103,7 +125,7 @@ public function testEvaluateItem() $computer = $this->createItem(GlpiComputer::class, [ 'computertypes_id' => $glpi_computer_type->getID(), 'computermodels_id' => $computer_model->getID(), - 'locations_id' => $location->getID(), + 'locations_id' => $glpi_location->getID(), ]); $usage_profile = $this->createItem(ComputerUsageProfile::class, [ 'time_start' => '09:00:00', @@ -130,7 +152,7 @@ public function testEvaluateItem() $asset = $this->createItem(GlpiMonitor::class, [ 'monitortypes_id' => $glpi_type->getID(), 'monitormodels_id' => $model->getID(), - 'locations_id' => $location->getID(), + 'locations_id' => $glpi_location->getID(), 'date_creation' => '2024-01-01', 'date_mod' => null, ]); @@ -206,12 +228,12 @@ private static function getMonitorLinkedToComputer(?GlpiComputer $computer = nul { $self = new self(); if ($computer === null) { - $computer = $self->getItem(GlpiComputer::class); + $computer = $self->createItem(GlpiComputer::class); } - $item = $self->getItem(GlpiMonitor::class); + $item = $self->createItem(GlpiMonitor::class); - $computer_item = $self->getItem(Computer_Item::class, [ + $computer_item = $self->createItem(Computer_Item::class, [ 'computers_id' => $computer->getID(), 'itemtype' => $item->getType(), 'items_id' => $item->getID(), @@ -223,7 +245,7 @@ private static function getMonitorLinkedToComputer(?GlpiComputer $computer = nul private static function addManagementToMonitor(CommonDBTM $item) { $self = new self(); - $management = $self->getItem(Infocom::class, [ + $management = $self->createItem(Infocom::class, [ 'itemtype' => $item->getType(), 'items_id' => $item->getID(), ]); @@ -259,7 +281,7 @@ public function testEmptyMonitorIsNotHistorizable() 'has_computer' => false, 'has_usage_profile' => false, 'has_location' => false, - 'has_state_or_country' => false, + 'has_carbon_intensity_zone' => false, 'has_model' => false, 'has_model_power_consumption' => false, 'has_type' => false, @@ -292,7 +314,7 @@ public function testMonitorLinkedToComputerIsNotHistorizable() 'has_computer' => true, 'has_usage_profile' => false, 'has_location' => false, - 'has_state_or_country' => false, + 'has_carbon_intensity_zone' => false, 'has_model' => false, 'has_model_power_consumption' => false, 'has_type' => false, @@ -323,7 +345,7 @@ public function testMonitorWithEmptyInfocomIsNotHistorizable() 'has_computer' => false, 'has_usage_profile' => false, 'has_location' => false, - 'has_state_or_country' => false, + 'has_carbon_intensity_zone' => false, 'has_model' => false, 'has_model_power_consumption' => false, 'has_type' => false, @@ -355,7 +377,7 @@ public function testMonitorWithInfocomIsNotHistorizable() 'has_computer' => false, 'has_usage_profile' => false, 'has_location' => false, - 'has_state_or_country' => false, + 'has_carbon_intensity_zone' => false, 'has_model' => false, 'has_model_power_consumption' => false, 'has_type' => false, @@ -375,9 +397,9 @@ public function testMonitorWithEmptyLocationIsNotHistorizable() $history = new Monitor(); $monitor = $this->createItem(GlpiMonitor::class); - $location = $this->createItem(Location::class); + $glpi_location = $this->createItem(GlpiLocation::class); $computer = $this->createItem(GlpiComputer::class, [ - 'locations_id' => $location->getID(), + 'locations_id' => $glpi_location->getID(), ]); $computer_item = $this->createItem(Computer_Item::class, [ 'computers_id' => $computer->getID(), @@ -391,7 +413,7 @@ public function testMonitorWithEmptyLocationIsNotHistorizable() 'has_computer' => true, 'has_usage_profile' => false, 'has_location' => true, - 'has_state_or_country' => false, + 'has_carbon_intensity_zone' => false, 'has_model' => false, 'has_model_power_consumption' => false, 'has_type' => false, @@ -406,61 +428,38 @@ public function testMonitorWithEmptyLocationIsNotHistorizable() $this->assertFalse($result); } - public function testMonitorWithLocationWithCountryIsNotHistorizable() + public function testMonitorWithLocationWithZoneIsNotHistorizable() { $history = new Monitor(); $monitor = $this->createItem(GlpiMonitor::class); - $location = $this->createItem(Location::class, [ - 'country' => 'France', + $glpi_location = $this->createItem(GlpiLocation::class); + $source = new Source(); // This source exists after a fresh install + $source->getFromDBByCrit([ + 'name' => 'RTE' ]); - $computer = $this->createItem(GlpiComputer::class, [ - 'locations_id' => $location->getID(), + $zone = new Zone(); // This zone exists after a fresh install + $zone->getFromDBByCrit([ + 'name' => 'France' ]); - $computer_item = $this->createItem(Computer_Item::class, [ - 'computers_id' => $computer->getID(), - 'itemtype' => $monitor->getType(), - 'items_id' => $monitor->getID(), + $source_zone = new Source_Zone(); // the relation source / zone also exists after a fresh install + $source_zone->getFromDBByCrit([ + $source::getForeignKeyField() => $source->getID(), + $zone::getForeignKeyField() => $zone->getID() ]); - - $result = $history->getHistorizableDiagnosis($monitor); - $expected = [ - 'is_deleted' => true, - 'is_template' => true, - 'has_computer' => true, - 'has_usage_profile' => false, - 'has_location' => true, - 'has_state_or_country' => true, - 'has_model' => false, - 'has_model_power_consumption' => false, - 'has_type' => false, - 'has_type_power_consumption' => false, - 'has_inventory_entry_date' => false, - 'ci_download_enabled' => false, - 'ci_fallback_available' => false, - ]; - $this->assertEquals($expected, $result); - $expected = !in_array(false, $result, true); - $result = $history->canHistorize($monitor->getID()); - $this->assertFalse($result); - } - - public function testMonitorWithLocationWithStateIsNotHistorizable() - { - $history = new Monitor(); - $location = $this->createItem(Location::class, [ - 'state' => 'Quebec', + 'locations_id' => $glpi_location->getID(), + 'plugin_carbon_sources_zones_id' => $source_zone->getID() ]); - $monitor = $this->createItem(GlpiMonitor::class); $computer = $this->createItem(GlpiComputer::class, [ - 'locations_id' => $location->getID(), + 'locations_id' => $glpi_location->getID(), ]); $computer_item = $this->createItem(Computer_Item::class, [ 'computers_id' => $computer->getID(), 'itemtype' => $monitor->getType(), 'items_id' => $monitor->getID(), ]); + $result = $history->getHistorizableDiagnosis($monitor); $expected = [ 'is_deleted' => true, @@ -468,7 +467,7 @@ public function testMonitorWithLocationWithStateIsNotHistorizable() 'has_computer' => true, 'has_usage_profile' => false, 'has_location' => true, - 'has_state_or_country' => true, + 'has_carbon_intensity_zone' => true, 'has_model' => false, 'has_model_power_consumption' => false, 'has_type' => false, @@ -507,7 +506,7 @@ public function testMonitorWithUsageProfileIsNotHistorizable() 'has_computer' => true, 'has_usage_profile' => true, 'has_location' => false, - 'has_state_or_country' => false, + 'has_carbon_intensity_zone' => false, 'has_model' => false, 'has_model_power_consumption' => false, 'has_type' => false, @@ -537,7 +536,7 @@ public function testMonitorWithEmptyModelIsNotHistorizable() 'has_computer' => false, 'has_usage_profile' => false, 'has_location' => false, - 'has_state_or_country' => false, + 'has_carbon_intensity_zone' => false, 'has_model' => true, 'has_model_power_consumption' => false, 'has_type' => false, @@ -569,7 +568,7 @@ public function testMonitorWithModelIsNotHistorizable() 'has_computer' => false, 'has_usage_profile' => false, 'has_location' => false, - 'has_state_or_country' => false, + 'has_carbon_intensity_zone' => false, 'has_model' => true, 'has_model_power_consumption' => true, 'has_type' => false, @@ -603,7 +602,7 @@ public function testMonitorWithEmptyTypeIsNotHistorizable() 'has_computer' => false, 'has_usage_profile' => false, 'has_location' => false, - 'has_state_or_country' => false, + 'has_carbon_intensity_zone' => false, 'has_model' => false, 'has_model_power_consumption' => false, 'has_type' => true, @@ -637,7 +636,7 @@ public function testMonitorWithTypeIsNotHistorizable() 'has_computer' => false, 'has_usage_profile' => false, 'has_location' => false, - 'has_state_or_country' => false, + 'has_carbon_intensity_zone' => false, 'has_model' => false, 'has_model_power_consumption' => false, 'has_type' => true, @@ -657,8 +656,23 @@ public function testMonitorIsHistorizable() { $history = new Monitor(); + $glpi_location = $this->createItem(GlpiLocation::class); + $source = new Source(); // This source exists after a fresh install + $source->getFromDBByCrit([ + 'name' => 'RTE' + ]); + $zone = new Zone(); // This zone exists after a fresh install + $zone->getFromDBByCrit([ + 'name' => 'France' + ]); + $source_zone = new Source_Zone(); // the relation source / zone also exists after a fresh install + $source_zone->getFromDBByCrit([ + $source::getForeignKeyField() => $source->getID(), + $zone::getForeignKeyField() => $zone->getID() + ]); $location = $this->createItem(Location::class, [ - 'country' => 'France', + 'locations_id' => $glpi_location->getID(), + 'plugin_carbon_sources_zones_id' => $source_zone->getID() ]); $glpi_monitor_model = $this->createItem(GlpiMonitorModel::class, [ 'power_consumption' => 35, @@ -667,7 +681,7 @@ public function testMonitorIsHistorizable() 'monitormodels_id' => $glpi_monitor_model->getID(), ]); $computer = $this->createItem(GlpiComputer::class, [ - 'locations_id' => $location->getID(), + 'locations_id' => $glpi_location->getID(), ]); $computer_item = $this->createItem(Computer_Item::class, [ 'computers_id' => $computer->getID(), @@ -696,14 +710,13 @@ public function testMonitorIsHistorizable() 'items_id' => $computer->getID(), ]); - $result = $history->getHistorizableDiagnosis($monitor); $expected = [ 'is_deleted' => true, 'is_template' => true, 'has_computer' => true, 'has_usage_profile' => true, 'has_location' => true, - 'has_state_or_country' => true, + 'has_carbon_intensity_zone' => true, 'has_model' => true, 'has_model_power_consumption' => true, 'has_type' => false, @@ -712,6 +725,7 @@ public function testMonitorIsHistorizable() 'ci_download_enabled' => false, 'ci_fallback_available' => false, ]; + $result = $history->getHistorizableDiagnosis($monitor); $this->assertEquals($expected, $result); $expected = !in_array(false, $result, true); $result = $history->canHistorize($monitor->getID()); diff --git a/tests/units/Impact/History/NetworkEquipmentTest.php b/tests/units/Impact/History/NetworkEquipmentTest.php index 1f50dcb8..c1addb07 100644 --- a/tests/units/Impact/History/NetworkEquipmentTest.php +++ b/tests/units/Impact/History/NetworkEquipmentTest.php @@ -36,11 +36,15 @@ use GlpiPlugin\Carbon\CarbonEmission; use GlpiPlugin\Carbon\Tests\Impact\History\CommonAsset; use GlpiPlugin\Carbon\Impact\History\NetworkEquipment; +use GlpiPlugin\Carbon\Location; use GlpiPlugin\Carbon\NetworkEquipmentType; +use GlpiPlugin\Carbon\Source; +use GlpiPlugin\Carbon\Source_Zone; +use GlpiPlugin\Carbon\Zone; use Infocom; use NetworkEquipmentType as GlpiNetworkEquipmentType; use NetworkEquipment as GlpiNetworkEquipment; -use Location; +use Location as GlpiLocation; use NetworkEquipmentModel as GlpiNetworkEquipmentModel; /** @@ -80,9 +84,26 @@ public function testEvaluateItem() $entities_id = $this->isolateInEntity('glpi', 'glpi'); $model_power = 100; - $location = $this->createItem(Location::class, [ + $glpi_location = $this->createItem(GlpiLocation::class, [ 'state' => 'Quebec', ]); + $source = new Source(); // This source exists after a fresh install + $source->getFromDBByCrit([ + 'name' => 'Hydro Quebec' + ]); + $zone = new Zone(); // This zone exists after a fresh install + $zone->getFromDBByCrit([ + 'name' => 'Quebec' + ]); + $source_zone = new Source_Zone(); // the relation source / zone also exists after a fresh install + $source_zone->getFromDBByCrit([ + $source::getForeignKeyField() => $source->getID(), + $zone::getForeignKeyField() => $zone->getID() + ]); + $location = $this->createItem(Location::class, [ + 'locations_id' => $glpi_location->getID(), + 'plugin_carbon_sources_zones_id' => $source_zone->getID() + ]); $model = $this->createItem(GlpiNetworkEquipmentModel::class, ['power_consumption' => $model_power]); $glpi_type = $this->createItem(GlpiNetworkEquipmentType::class); $type = $this->createItem(NetworkEquipmentType::class, [ @@ -91,7 +112,7 @@ public function testEvaluateItem() $asset = $this->createItem(GlpiNetworkEquipment::class, [ 'networkequipmenttypes_id' => $glpi_type->getID(), 'networkequipmentmodels_id' => $model->getID(), - 'locations_id' => $location->getID(), + 'locations_id' => $glpi_location->getID(), 'date_creation' => '2024-01-01', 'date_mod' => null, ]); @@ -180,7 +201,7 @@ public function testEmptyItemIsNotHistorizable() 'is_deleted' => true, 'is_template' => true, 'has_location' => false, - 'has_state_or_country' => false, + 'has_carbon_intensity_zone' => false, 'has_model' => false, 'has_model_power_consumption' => false, 'has_type' => false, @@ -209,7 +230,7 @@ public function testNetDeviceWithEmptyInfocomIsNotHistorizable() 'is_deleted' => true, 'is_template' => true, 'has_location' => false, - 'has_state_or_country' => false, + 'has_carbon_intensity_zone' => false, 'has_model' => false, 'has_model_power_consumption' => false, 'has_type' => false, @@ -239,7 +260,7 @@ public function testNetDeviceWithInfocomIsNotHistorizable() 'is_deleted' => true, 'is_template' => true, 'has_location' => false, - 'has_state_or_country' => false, + 'has_carbon_intensity_zone' => false, 'has_model' => false, 'has_model_power_consumption' => false, 'has_type' => false, @@ -258,16 +279,16 @@ public function testNetDeviceWithEmptyLocationIsNotHistorizable() { $history = new NetworkEquipment(); - $location = $this->createItem(Location::class); + $glpi_location = $this->createItem(GlpiLocation::class); $network_equipment = $this->createItem(GlpiNetworkEquipment::class, [ - 'locations_id' => $location->getID(), + 'locations_id' => $glpi_location->getID(), ]); $result = $history->getHistorizableDiagnosis($network_equipment); $expected = [ 'is_deleted' => true, 'is_template' => true, 'has_location' => true, - 'has_state_or_country' => false, + 'has_carbon_intensity_zone' => false, 'has_model' => false, 'has_model_power_consumption' => false, 'has_type' => false, @@ -282,59 +303,44 @@ public function testNetDeviceWithEmptyLocationIsNotHistorizable() $this->assertFalse($result); } - public function testNetDeviceWithLocationWithCountryIsNotHistorizable() + public function testNetDeviceWithLocationWithZoneIsNotHistorizable() { $history = new NetworkEquipment(); - $location = $this->createItem(Location::class, [ - 'country' => 'France', + $source = new Source(); // This source exists after a fresh install + $source->getFromDBByCrit([ + 'name' => 'RTE' ]); - $network_equipment = $this->createItem(GlpiNetworkEquipment::class, [ - 'locations_id' => $location->getID(), + $zone = new Zone(); // This zone exists after a fresh install + $zone->getFromDBByCrit([ + 'name' => 'France' ]); - $result = $history->getHistorizableDiagnosis($network_equipment); - $expected = [ - 'is_deleted' => true, - 'is_template' => true, - 'has_location' => true, - 'has_state_or_country' => true, - 'has_model' => false, - 'has_model_power_consumption' => false, - 'has_type' => false, - 'has_type_power_consumption' => false, - 'has_inventory_entry_date' => false, - 'ci_download_enabled' => false, - 'ci_fallback_available' => true, - ]; - $this->assertEquals($expected, $result); - $expected = !in_array(false, $result, true); - $result = $history->canHistorize($network_equipment->getID()); - $this->assertFalse($result); - } - - public function testNetDeviceWithLocationWithStateIsNotHistorizable() - { - $history = new NetworkEquipment(); - + $source_zone = new Source_Zone(); // the relation source / zone also exists after a fresh install + $source_zone->getFromDBByCrit([ + $source::getForeignKeyField() => $source->getID(), + $zone::getForeignKeyField() => $zone->getID() + ]); + $glpi_location = $this->createItem(GlpiLocation::class); $location = $this->createItem(Location::class, [ - 'state' => 'Quebec', + 'locations_id' => $glpi_location->getID(), + 'plugin_carbon_sources_zones_id' => $source_zone->getID() ]); $network_equipment = $this->createItem(GlpiNetworkEquipment::class, [ - 'locations_id' => $location->getID(), + 'locations_id' => $glpi_location->getID(), ]); $result = $history->getHistorizableDiagnosis($network_equipment); $expected = [ 'is_deleted' => true, 'is_template' => true, 'has_location' => true, - 'has_state_or_country' => true, + 'has_carbon_intensity_zone' => true, 'has_model' => false, 'has_model_power_consumption' => false, 'has_type' => false, 'has_type_power_consumption' => false, 'has_inventory_entry_date' => false, - 'ci_download_enabled' => false, - 'ci_fallback_available' => true, + 'ci_download_enabled' => true, + 'ci_fallback_available' => false, ]; $this->assertEquals($expected, $result); $expected = !in_array(false, $result, true); @@ -350,12 +356,11 @@ public function testNetDeviceWithEmptyModelIsNotHistorizable() $network_equipment = $this->createItem(GlpiNetworkEquipment::class, [ 'networkequipmentmodels_id' => $glpi_model->getID(), ]); - $result = $history->getHistorizableDiagnosis($network_equipment); $expected = [ 'is_deleted' => true, 'is_template' => true, 'has_location' => false, - 'has_state_or_country' => false, + 'has_carbon_intensity_zone' => false, 'has_model' => true, 'has_model_power_consumption' => false, 'has_type' => false, @@ -364,6 +369,7 @@ public function testNetDeviceWithEmptyModelIsNotHistorizable() 'ci_download_enabled' => false, 'ci_fallback_available' => false, ]; + $result = $history->getHistorizableDiagnosis($network_equipment); $this->assertEquals($expected, $result); $expected = !in_array(false, $result, true); $result = $history->canHistorize($network_equipment->getID()); @@ -385,7 +391,7 @@ public function testNetDeviceWithModelIsNotHistorizable() 'is_deleted' => true, 'is_template' => true, 'has_location' => false, - 'has_state_or_country' => false, + 'has_carbon_intensity_zone' => false, 'has_model' => true, 'has_model_power_consumption' => true, 'has_type' => false, @@ -413,7 +419,7 @@ public function testNetDeviceWithEmptyTypeIsNotHistorizable() 'is_deleted' => true, 'is_template' => true, 'has_location' => false, - 'has_state_or_country' => false, + 'has_carbon_intensity_zone' => false, 'has_model' => false, 'has_model_power_consumption' => false, 'has_type' => true, @@ -445,7 +451,7 @@ public function testNetDeviceWithTypeIsNotHistorizable() 'is_deleted' => true, 'is_template' => true, 'has_location' => false, - 'has_state_or_country' => false, + 'has_carbon_intensity_zone' => false, 'has_model' => false, 'has_model_power_consumption' => false, 'has_type' => true, diff --git a/tests/units/LocationTest.php b/tests/units/LocationTest.php index fcd283ba..8c96205b 100644 --- a/tests/units/LocationTest.php +++ b/tests/units/LocationTest.php @@ -40,11 +40,12 @@ use Geocoder\Model\AdminLevelCollection; use Geocoder\Model\Country; use Geocoder\Provider\Nominatim\Model\NominatimAddress; -use GlpiPlugin\Carbon\CarbonIntensitySource; -use GlpiPlugin\Carbon\CarbonIntensitySource_Zone; +use GlpiPlugin\Carbon\Source; +use GlpiPlugin\Carbon\Source_Zone; use GlpiPlugin\Carbon\Zone; use Location as GlpiLocation; use GlpiPlugin\Carbon\Location; +use Locale; class LocationTest extends DbTestCase { @@ -194,7 +195,7 @@ public function testOnGlpiLocationPrePurge() * * @return void */ - public function testgetIncompleteLocations() + public function testGetIncompleteLocations() { $iterator = Location::getIncompleteLocations(); $output = $iterator->count(); @@ -277,14 +278,14 @@ public function testEnableCarbonIntensityDownload() $this->assertFalse($result); // Test when the zone does not matchs a source - $source = $this->createItem(CarbonIntensitySource::class, [ + $source = $this->createItem(Source::class, [ 'name' => 'bar', ]); $zone = $this->createItem(Zone::class, [ 'name' => 'foo', - 'plugin_carbon_carbonintensitysources_id_historical' => 0, + 'plugin_carbon_sources_id_historical' => 0, ]); - $source_zone = $this->createItem(CarbonIntensitySource_Zone::class, [ + $source_zone = $this->createItem(Source_Zone::class, [ $zone::getForeignKeyField() => $zone->getID(), $source::getForeignKeyField() => $source->getID(), 'is_download_enabled' => 0, @@ -296,20 +297,19 @@ public function testEnableCarbonIntensityDownload() $this->assertFalse($result); // Test when the zone matches a source and download switches to enabled - $source = $this->createItem(CarbonIntensitySource::class, [ - 'name' => 'baz', - ]); + $source = $this->createItem(Source::class); $zone = $this->createItem(Zone::class, [ - 'name' => 'baz', - 'plugin_carbon_carbonintensitysources_id_historical' => $source->getID(), + 'plugin_carbon_sources_id_historical' => $source->getID(), ]); - $source_zone = $this->createItem(CarbonIntensitySource_Zone::class, [ + $source_zone = $this->createItem(Source_Zone::class, [ $zone::getForeignKeyField() => $zone->getID(), $source::getForeignKeyField() => $source->getID(), 'is_download_enabled' => 0, ]); - $glpi_location = $this->createItem(GlpiLocation::class, [ - 'country' => 'baz' + $glpi_location = $this->createItem(GlpiLocation::class); + $location = $this->createItem(Location::class, [ + $glpi_location::getForeignKeyField() => $glpi_location->getID(), + $source_zone::getForeignKeyField() => $source_zone->getID(), ]); $result = $this->callPrivateMethod($instance, 'enableCarbonIntensityDownload', $glpi_location); $this->assertTrue($result); @@ -317,99 +317,168 @@ public function testEnableCarbonIntensityDownload() public function testIsCarbonIntensityDownloadEnabled() { - // Test with an enmpty core location + // Test with an enmpty core location object $glpi_location = new GlpiLocation(); $location = new Location(); $result = $location->isCarbonIntensityDownloadEnabled($glpi_location); $this->assertFalse($result); - // Test with a core location without a country + // Test with a core location without additional data with the plugin object $glpi_location = $this->createItem(GlpiLocation::class); $location = new Location(); $result = $location->isCarbonIntensityDownloadEnabled($glpi_location); $this->assertFalse($result); // Test with a core location with a country - $glpi_location = $this->createItem(GlpiLocation::class, [ - 'country' => 'France' - ]); + $glpi_location = $this->createItem(GlpiLocation::class); $location = new Location(); $result = $location->isCarbonIntensityDownloadEnabled($glpi_location); $this->assertFalse($result); // Test with a core location with a country and the relation zource / zone exists, download disabled - $source_zone = new CarbonIntensitySource_Zone(); - $source = new CarbonIntensitySource(); - $source->getFromDBByCrit(['name' => 'RTE']); - $zone = new Zone(); - $zone->getFromDBByCrit(['name' => 'France']); - $source_zone = $this->createItem(CarbonIntensitySource_Zone::class, [ - 'plugin_carbon_carbonintensitysources_id' => $source->getID(), + $source = $this->createItem(Source::class); + $zone = $this->createItem(Zone::class); + $source_zone = $this->createItem(Source_Zone::class, [ + 'plugin_carbon_sources_id' => $source->getID(), 'plugin_carbon_zones_id' => $zone->getID(), 'is_download_enabled' => 0, ]); - $source_zone->update([ - 'id' => $source_zone->getID(), - 'is_download_enabled' => 0, - ]); $location = new Location(); $result = $location->isCarbonIntensityDownloadEnabled($glpi_location); $this->assertFalse($result); - // Test with a core location with a country and the relation zource / zone exists, download enabled - $source_zone->update([ - 'id' => $source_zone->getID(), + // Test with a core location with a relation zource / zone, download enabled + $source = $this->createItem(Source::class); + $zone = $this->createItem(Zone::class); + $source_zone = $this->createItem(Source_Zone::class, [ + 'plugin_carbon_sources_id' => $source->getID(), + 'plugin_carbon_zones_id' => $zone->getID(), 'is_download_enabled' => 1, ]); - $location = new Location(); + $glpi_location = $this->createItem(GlpiLocation::class); + $location = $this->createItem(Location::class, [ + 'locations_id' => $glpi_location->getID(), + $source_zone::getForeignKeyField() => $source_zone->getID(), + ]); $result = $location->isCarbonIntensityDownloadEnabled($glpi_location); $this->assertTrue($result); } public function testHasFallbackCarbonIntensityData() { - // Test with an enmpty core location + // Test with an empty core location $glpi_location = new GlpiLocation(); $location = new Location(); $result = $location->hasFallbackCarbonIntensityData($glpi_location); $this->assertFalse($result); - // Test with a core location without a country + // Test with a core location $glpi_location = $this->createItem(GlpiLocation::class); $location = new Location(); $result = $location->hasFallbackCarbonIntensityData($glpi_location); $this->assertFalse($result); - // Test with a core location with a non-existing country - $glpi_location = $this->createItem(GlpiLocation::class, [ - 'country' => 'Azeroth' + // Test with a core location with a relation to a non-fallback source + $source = new Source(); // This source exists after a fresh install + $source->getFromDBByCrit([ + 'name' => 'RTE' + ]); + $zone = new Zone(); // This zone exists after a fresh install + $zone->getFromDBByCrit([ + 'name' => 'France' + ]); + $source_zone = new Source_Zone(); // the relation source / zone also exists after a fresh install + $source_zone->getFromDBByCrit([ + $source::getForeignKeyField() => $source->getID(), + $zone::getForeignKeyField() => $zone->getID() + ]); + $glpi_location = $this->createItem(GlpiLocation::class); + $location = $this->createItem(Location::class, [ + 'locations_id' => $glpi_location->getID(), + $source_zone::getForeignKeyField() => $source_zone->getID(), ]); - $location = new Location(); $result = $location->hasFallbackCarbonIntensityData($glpi_location); $this->assertFalse($result); - // Test with a core location with a non-existing state - $glpi_location = $this->createItem(GlpiLocation::class, [ - 'state' => 'Durotar' + // Test with a core location with a relation to a fallback source + $source = new Source(); // This source exists after a fresh install + $source->getFromDBByCrit([ + 'name' => 'Ember - Energy Institute' + ]); + $zone = new Zone(); // This zone exists after a fresh install + $zone->getFromDBByCrit([ + 'name' => 'France' + ]); + $source_zone = new Source_Zone(); // the relation source / zone also exists after a fresh install + $source_zone->getFromDBByCrit([ + $source::getForeignKeyField() => $source->getID(), + $zone::getForeignKeyField() => $zone->getID() + ]); + $glpi_location = $this->createItem(GlpiLocation::class); + $location = $this->createItem(Location::class, [ + 'locations_id' => $glpi_location->getID(), + $source_zone::getForeignKeyField() => $source_zone->getID(), ]); - $location = new Location(); $result = $location->hasFallbackCarbonIntensityData($glpi_location); - $this->assertFalse($result); + $this->assertTrue($result); + } - // Test with a core location with a country + public function testGetSourceZoneId() + { + // Test an unitialized location + $location = new Location(); + $result = $location->getSourceZoneId(); + $this->assertEquals(0, $result); + + // Test a location without a relation to a source and a zone + $glpi_location = $this->createItem(GlpiLocation::class); + $location = $this->createItem(Location::class, ['locations_id' => $glpi_location->getID()]); + $result = $location->getSourceZoneId(); + $this->assertEquals(0, $result); + + // Test a location associated to a source_zone + $source = $this->createItem(Source::class); + $zone = $this->createItem(Zone::class); + $source_zone = $this->createItem(Source_Zone::class, [ + Source::getForeignKeyField() => $source->getID(), + Zone::getForeignKeyField() => $zone->getID(), + ]); + $glpi_location = $this->createItem(GlpiLocation::class); + $location = $this->createItem(Location::class, [ + 'locations_id' => $glpi_location->getID(), + 'plugin_carbon_sources_zones_id' => $source_zone->getID(), + ]); + $result = $location->getSourceZoneId(); + $this->assertEquals($source_zone->getID(), $result); + + // Test a source_zone associated to the parent of the location + $glpi_location_ancestor = $this->createItem(GlpiLocation::class); $glpi_location = $this->createItem(GlpiLocation::class, [ - 'country' => 'France' + 'locations_id' => $glpi_location_ancestor->getID(), ]); - $location = new Location(); - $result = $location->hasFallbackCarbonIntensityData($glpi_location); - $this->assertTrue($result); + $location = $this->createItem(Location::class, [ + 'locations_id' => $glpi_location_ancestor->getID(), + 'plugin_carbon_sources_zones_id' => $source_zone->getID(), + ]); + $result = $location->getSourceZoneId(); + $this->assertEquals($source_zone->getID(), $result); - // Test with a core location with a state + // Test a source_zone associated to the gand-parent of the location + $glpi_location_grand_ancestor = $this->createItem(GlpiLocation::class); + $glpi_location_ancestor = $this->createItem(GlpiLocation::class, [ + 'locations_id' => $glpi_location_grand_ancestor->getID() + ]); $glpi_location = $this->createItem(GlpiLocation::class, [ - 'state' => 'Quebec' + 'locations_id' => $glpi_location_ancestor->getID(), ]); - $location = new Location(); - $result = $location->hasFallbackCarbonIntensityData($glpi_location); - $this->assertTrue($result); + $location_grand_ancestor = $this->createItem(Location::class, [ + 'locations_id' => $glpi_location_grand_ancestor->getID(), + 'plugin_carbon_sources_zones_id' => $source_zone->getID(), + ]); + $location = $this->createItem(Location::class, [ + 'locations_id' => $glpi_location->getID(), + ]); + $result = $location->getSourceZoneId(); + $this->assertEquals($source_zone->getID(), $result); } } diff --git a/tests/units/CarbonIntensitySourceTest.php b/tests/units/SourceTest.php similarity index 72% rename from tests/units/CarbonIntensitySourceTest.php rename to tests/units/SourceTest.php index f7589969..75826323 100644 --- a/tests/units/CarbonIntensitySourceTest.php +++ b/tests/units/SourceTest.php @@ -33,75 +33,75 @@ namespace GlpiPlugin\Carbon\Tests; use Computer; -use GlpiPlugin\Carbon\CarbonIntensitySource; -use GlpiPlugin\Carbon\CarbonIntensitySource_Zone; +use GlpiPlugin\Carbon\Source; +use GlpiPlugin\Carbon\Source_Zone; use GlpiPlugin\Carbon\Zone; use Log; use Session; -class CarbonIntensitySourceTest extends DbTestCase +class SourceTest extends DbTestCase { /** - * #CoversMethod \GlpiPlugin\Carbon\CarbonIntensitySource::getTypeName + * #CoversMethod \GlpiPlugin\Carbon\Source::getTypeName */ public function testGetTypeName() { - $result = CarbonIntensitySource::getTypeName(1); + $result = Source::getTypeName(1); $this->assertEquals('Carbon intensity source', $result); - $result = CarbonIntensitySource::getTypeName(Session::getPluralNumber()); + $result = Source::getTypeName(Session::getPluralNumber()); $this->assertEquals('Carbon intensity sources', $result); } /** - * #CoversMethod \GlpiPlugin\Carbon\CarbonIntensitySource::canCreate + * #CoversMethod \GlpiPlugin\Carbon\Source::canCreate */ public function testCanCreate() { $this->login('glpi', 'glpi'); - $result = CarbonIntensitySource::canCreate(); + $result = Source::canCreate(); $this->assertFalse($result); } /** - * #CoversMethod \GlpiPlugin\Carbon\CarbonIntensitySource::canUpdate + * #CoversMethod \GlpiPlugin\Carbon\Source::canUpdate */ public function testCanUpdate() { $this->login('glpi', 'glpi'); - $result = CarbonIntensitySource::canUpdate(); + $result = Source::canUpdate(); $this->assertFalse($result); } /** - * #CoversMethod \GlpiPlugin\Carbon\CarbonIntensitySource::canDelete + * #CoversMethod \GlpiPlugin\Carbon\Source::canDelete */ public function testCanDelete() { $this->login('glpi', 'glpi'); - $result = CarbonIntensitySource::canDelete(); + $result = Source::canDelete(); $this->assertFalse($result); } /** - * #CoversMethod \GlpiPlugin\Carbon\CarbonIntensitySource::canPurge + * #CoversMethod \GlpiPlugin\Carbon\Source::canPurge */ public function testCanPurge() { $this->login('glpi', 'glpi'); - $result = CarbonIntensitySource::canPurge(); + $result = Source::canPurge(); $this->assertFalse($result); } /** - * #CoversMethod \GlpiPlugin\Carbon\CarbonIntensitySource::defineTabs + * #CoversMethod \GlpiPlugin\Carbon\Source::defineTabs */ public function testDefineTabs() { $this->login('glpi', 'glpi'); - $instance = new CarbonIntensitySource(); + $instance = new Source(); $result = $instance->defineTabs(); - $this->assertStringContainsString('Carbon intensity source', $result[CarbonIntensitySource::class . '$main']); + $this->assertStringContainsString('Carbon intensity source', $result[Source::class . '$main']); $this->assertStringContainsString('Carbon intensity zones', $result[Zone::class . '$1']); $this->assertStringContainsString('Historical', $result[Log::class . '$1']); } @@ -110,7 +110,7 @@ public function testGetTabNameForItem() { $this->login('glpi', 'glpi'); $item = $this->createItem(Zone::class); - $instance = new CarbonIntensitySource(); + $instance = new Source(); $result = $instance->getTabNameForItem($item); $expected = 'Carbon intensity sources'; $this->assertStringContainsString($expected, $result); @@ -126,7 +126,7 @@ public function testGetTabNameForItem() } /** - * #CoversMethod \GlpiPlugin\Carbon\CarbonIntensitySource::displayTabContentForItem + * #CoversMethod \GlpiPlugin\Carbon\Source::displayTabContentForItem */ public function testDisplayTabContentForItem() { @@ -135,21 +135,21 @@ public function testDisplayTabContentForItem() ob_start(function ($buffer) { return $buffer; }); - $result = CarbonIntensitySource::displayTabContentForItem($item); + $result = Source::displayTabContentForItem($item); $output = ob_get_clean(); $this->assertEquals('', $output); $this->assertTrue($result); $item = $this->createItem(Zone::class); - $source = $this->createItem(CarbonIntensitySource::class); - $source_zone = $this->createItem(CarbonIntensitySource_Zone::class, [ + $source = $this->createItem(Source::class); + $source_zone = $this->createItem(Source_Zone::class, [ $item::getForeignKeyField() => $item->getID(), $source::getForeignKeyField() => $source->getID() ]); ob_start(function ($buffer) { return $buffer; }); - $result = CarbonIntensitySource::displayTabContentForItem($item); + $result = Source::displayTabContentForItem($item); $output = ob_get_clean(); $this->assertNotEquals('', $output); $this->assertTrue($result); diff --git a/tests/units/Source_ZoneTest.php b/tests/units/Source_ZoneTest.php new file mode 100644 index 00000000..46c79d73 --- /dev/null +++ b/tests/units/Source_ZoneTest.php @@ -0,0 +1,193 @@ +. + * + * ------------------------------------------------------------------------- + */ + +namespace GlpiPlugin\Carbon\Tests; + +use Computer; +use GlpiPlugin\Carbon\CarbonIntensity; +use GlpiPlugin\Carbon\Location; +use GlpiPlugin\Carbon\Source; +use GlpiPlugin\Carbon\Source_Zone; +use GlpiPlugin\Carbon\Tests\DbTestCase; +use GlpiPlugin\Carbon\Zone; +use Location as GlpiLocation; + +class Source_ZoneTest extends DbTestCase +{ + /** + * #CoversMethod GlpiPlugin\Carbon\Source_Zone::showForSource + */ + public function testShowForSource() + { + $source = $this->createItem(Source::class, [ + 'name' => 'foo' + ]); + + $zone = $this->createItem(Zone::class, [ + 'name' => 'bar' + ]); + + $instance = $this->createItem(Source_Zone::class, [ + $source::getForeignKeyField() => $source->getID(), + $zone::getForeignKeyField() => $zone->getID(), + ]); + + $this->logout(); + ob_start(); + $result = $instance->showForSource($source); + $output = ob_get_clean(); + $this->assertEquals('', $output); + + $this->login('glpi', 'glpi'); + ob_start(); + $result = $instance->showForSource($source); + $output = ob_get_clean(); + $this->assertNotEmpty($output); + } + + /** + * #CoversMethod GlpiPlugin\Carbon\Source_Zone::showForZone + */ + public function testShowForZone() + { + $source = $this->createItem(Source::class, [ + 'name' => 'foo' + ]); + + $zone = $this->createItem(Zone::class, [ + 'name' => 'bar' + ]); + + $instance = $this->createItem(Source_Zone::class, [ + $source::getForeignKeyField() => $source->getID(), + $zone::getForeignKeyField() => $zone->getID(), + ]); + + $this->logout(); + ob_start(); + $result = $instance->showForZone($zone); + $output = ob_get_clean(); + $this->assertEquals('', $output); + + $this->login('glpi', 'glpi'); + ob_start(); + $result = $instance->showForZone($zone); + $output = ob_get_clean(); + $this->assertNotEmpty($output); + } + + public function testFromDbByItem() + { + // Test a location having a source_zone relation + $zone = $this->createItem(Zone::class); + $source = $this->createItem(Source::class); + $source_zone = $this->createItem(Source_Zone::class, [ + $zone::getForeignKeyField() => $zone->getID(), + $source::getForeignKeyField() => $source->getID(), + ]); + $glpi_location = $this->createItem(GlpiLocation::class); + $this->createItem(Location::class, [ + 'locations_id' => $glpi_location->getID(), + 'plugin_carbon_sources_zones_id' => $source_zone->getID(), + ]); + $source_zone = new Source_Zone(); + $output = $source_zone->getFromDbByItem($glpi_location); + $this->assertTrue($output); + + // Test a location without source_zone + $glpi_location = $this->createItem(GlpiLocation::class); + $this->createItem(Location::class, [ + 'locations_id' => $glpi_location->getID(), + ]); + $source_zone = new Source_Zone(); + $output = $source_zone->getFromDbByItem($glpi_location); + $this->assertFalse($output); + + // Test a location without additional plugin data + $glpi_location = $this->createItem(GlpiLocation::class); + $source_zone = new Source_Zone(); + $output = $source_zone->getFromDbByItem($glpi_location); + $this->assertFalse($output); + + // Test an unitialized asset + $computer = new Computer(); + $source_zone = new Source_Zone(); + $output = $source_zone->getFromDbByItem($glpi_location); + $this->assertFalse($output); + + // Test an asset + $computer = $this->createItem(Computer::class); + $source_zone = new Source_Zone(); + $output = $source_zone->getFromDbByItem($glpi_location); + $this->assertFalse($output); + + // Test an asset with a location + $glpi_location = $this->createItem(GlpiLocation::class); + $computer = $this->createItem(Computer::class, [ + 'locations_id' => $glpi_location->getID(), + ]); + $source_zone = new Source_Zone(); + $output = $source_zone->getFromDbByItem($glpi_location); + $this->assertFalse($output); + + // Test an asset with plugin location data + $glpi_location = $this->createItem(GlpiLocation::class); + $location = $this->createItem(Location::class, [ + 'locations_id' => $glpi_location->getID(), + ]); + $computer = $this->createItem(Computer::class, [ + 'locations_id' => $glpi_location->getID(), + ]); + $source_zone = new Source_Zone(); + $output = $source_zone->getFromDbByItem($glpi_location); + $this->assertFalse($output); + + // Test an asset with plugin location data linked to a source_zone + $zone = $this->createItem(Zone::class); + $source = $this->createItem(Source::class); + $source_zone = $this->createItem(Source_Zone::class, [ + $zone::getForeignKeyField() => $zone->getID(), + $source::getForeignKeyField() => $source->getID(), + ]); + $glpi_location = $this->createItem(GlpiLocation::class); + $location = $this->createItem(Location::class, [ + 'locations_id' => $glpi_location->getID(), + 'plugin_carbon_sources_zones_id' => $source_zone->getID(), + ]); + $computer = $this->createItem(Computer::class, [ + 'locations_id' => $glpi_location->getID(), + ]); + $source_zone = new Source_Zone(); + $output = $source_zone->getFromDbByItem($glpi_location); + $this->assertTrue($output); + } +} diff --git a/tests/units/ZoneTest.php b/tests/units/ZoneTest.php index 6b1e19a5..21ff7b0a 100644 --- a/tests/units/ZoneTest.php +++ b/tests/units/ZoneTest.php @@ -33,123 +33,66 @@ namespace GlpiPlugin\Carbon\Tests; use Computer; -use GlpiPlugin\Carbon\CarbonIntensitySource; +use GlpiPlugin\Carbon\Location; +use GlpiPlugin\Carbon\Source; +use GlpiPlugin\Carbon\Source_Zone; use GlpiPlugin\Carbon\Zone; -use Location; +use Location as GlpiLocation; class ZoneTest extends DbTestCase { - public function testGetByLocation() - { - // Test with a new Location object - $output = Zone::getByLocation(new Location()); - $this->assertNull($output); - - // Test with a Location object that has no country or state - $location = $this->createItem(Location::class); - $output = Zone::getByLocation($location); - $this->assertNull($output); - - // Test with a Location object that has a country - $location = $this->createItem(Location::class, [ - 'country' => 'foo' - ]); - $output = Zone::getByLocation($location); - $this->assertNull($output); - - // Test with a Location object that has a country and a zoone exists for this location - $zone = $this->createItem(Zone::class, [ - 'name' => 'foo' - ]); - $output = Zone::getByLocation($location); - $this->assertEquals($output->getID(), $zone->getID()); - - // Test with a Location object that has a state - $location = $this->createItem(Location::class, [ - 'state' => 'bar' - ]); - $output = Zone::getByLocation($location); - $this->assertNull($output); - - // Test with a Location object that has a state and a zone exists for this location - $zone = $this->createItem(Zone::class, [ - 'name' => 'bar' - ]); - $output = Zone::getByLocation($location); - $this->assertEquals($output->getID(), $zone->getID()); - - // Test with a Location object that has both country and state - $location = $this->createItem(Location::class, [ - 'country' => 'fooo', - 'state' => 'baz' - ]); - $output = Zone::getByLocation($location); - $this->assertNull($output); - // Test with a Location object that has both country and state and a zone exists for this location - $zone = $this->createItem(Zone::class, [ - 'name' => 'baz' - ]); - $output = Zone::getByLocation($location); - $this->assertEquals($output->getID(), $zone->getID()); - } - public function testGetByAsset() { // Test with a new Computer object - $output = Zone::getByAsset(new Computer()); - $this->assertNull($output); + $zone = new Zone(); + $output = $zone->getByAsset(new Computer()); + $this->assertFalse($output); - // Test with a Computer object that has a location with country and no matching zone - $location = $this->createItem(Location::class, [ - 'country' => 'foo' - ]); + // Test with a Computer object that has a location without child location data + $glpi_location = $this->createItem(GlpiLocation::class); $computer = $this->createItem(Computer::class, [ - 'locations_id' => $location->getID(), + 'locations_id' => $glpi_location->getID(), ]); - $output = Zone::getByAsset($computer); - $this->assertNull($output); + $zone = new Zone(); + $output = $zone->getByAsset($computer); + $this->assertFalse($output); - // Test with a Computer object that has a location with country and a matching zone - $zone = $this->createItem(Zone::class, [ - 'name' => 'foo' + // Test with a Computer object that has a location with child location data + $zone = $this->createItem(Zone::class); + $source = $this->createItem(Source::class); + $source_zone = $this->createItem(Source_Zone::class, [ + $zone::getForeignKeyField() => $zone->getID(), + $source::getForeignKeyField() => $source->getID(), ]); - $output = Zone::getByAsset($computer); - $this->assertEquals($output->getID(), $zone->getID()); - - // Test with a Computer object that has a location with state and no matching zone + $glpi_location = $this->createItem(GlpiLocation::class); $location = $this->createItem(Location::class, [ - 'state' => 'bar' + 'locations_id' => $glpi_location->getID(), ]); $computer = $this->createItem(Computer::class, [ - 'locations_id' => $location->getID(), + 'locations_id' => $glpi_location->getID(), ]); - $output = Zone::getByAsset($computer); - $this->assertNull($output); + $zone = new Zone(); + $output = $zone->getByAsset($computer); + $this->assertFalse($output); - // Test with a Computer object that has a location with state and a matching zone - $zone = $this->createItem(Zone::class, [ - 'name' => 'bar' + // Test with a Computer object that has a location matching a source_zone + $zone = $this->createItem(Zone::class); + $source = $this->createItem(Source::class); + $source_zone = $this->createItem(Source_Zone::class, [ + $zone::getForeignKeyField() => $zone->getID(), + $source::getForeignKeyField() => $source->getID(), ]); - $output = Zone::getByAsset($computer); - $this->assertEquals($output->getID(), $zone->getID()); - - // Test with a Computer object that has a location with both country and state and no matching zone + $glpi_location = $this->createItem(GlpiLocation::class); $location = $this->createItem(Location::class, [ - 'country' => 'fooo', - 'state' => 'baz' + 'locations_id' => $glpi_location->getID(), + 'plugin_carbon_sources_zones_id' => $source_zone->getID(), ]); $computer = $this->createItem(Computer::class, [ - 'locations_id' => $location->getID(), + 'locations_id' => $glpi_location->getID(), ]); - $output = Zone::getByAsset($computer); - $this->assertNull($output); - - // Test with a Computer object that has a location with both country and state and a matching zone - $zone = $this->createItem(Zone::class, [ - 'name' => 'baz' - ]); - $output = Zone::getByAsset($computer); - $this->assertEquals($output->getID(), $zone->getID()); + $zone = new Zone(); + $output = $zone->getByAsset($computer); + $this->assertTrue($output); } public function testHasHistoricalData() @@ -160,7 +103,7 @@ public function testHasHistoricalData() // Test with a Zone object without the field $zone = $this->createItem(Zone::class); - unset($zone->fields['plugin_carbon_carbonintensitysources_id_historical']); + unset($zone->fields['plugin_carbon_sources_id_historical']); $this->assertFalse($zone->hasHistoricalData()); // Test with a Zone object that has no historical data @@ -168,11 +111,11 @@ public function testHasHistoricalData() $zone = $this->createItem(Zone::class); $this->assertFalse($zone->hasHistoricalData()); - $source = $this->createItem(CarbonIntensitySource::class, [ + $source = $this->createItem(Source::class, [ 'name' => 'foo' ]); $zone->update(array_merge($zone->fields, [ - 'plugin_carbon_carbonintensitysources_id_historical' => $source->getID(), + 'plugin_carbon_sources_id_historical' => $source->getID(), ])); $this->assertTrue($zone->hasHistoricalData()); } @@ -190,10 +133,10 @@ public function testGetByItem() $this->assertFalse($zone->getByItem($item)); // Test with a Computer object that has a location with country and no matching zone - $location = $this->createItem(Location::class, [ + $glpi_location = $this->createItem(GlpiLocation::class, [ 'country' => 'foo' ]); - $item->update(['id' => $item->getID(), 'locations_id' => $location->getID()]); + $item->update(['id' => $item->getID(), 'locations_id' => $glpi_location->getID()]); $zone = new Zone(); $this->assertFalse($zone->getByItem($item)); @@ -206,10 +149,10 @@ public function testGetByItem() $this->assertEquals($zone->getID(), $expected_zone->getID()); // Test with a Computer object that has a location with state and no matching zone - $location = $this->createItem(Location::class, [ + $glpi_location = $this->createItem(GlpiLocation::class, [ 'state' => 'bar' ]); - $item->update(['id' => $item->getID(), 'locations_id' => $location->getID()]); + $item->update(['id' => $item->getID(), 'locations_id' => $glpi_location->getID()]); $zone = new Zone(); $this->assertFalse($zone->getByItem($item)); @@ -222,11 +165,11 @@ public function testGetByItem() $this->assertEquals($zone->getID(), $expected_zone->getID()); // Test with a Computer object that has a location with both country and state and no matching zone - $location = $this->createItem(Location::class, [ + $glpi_location = $this->createItem(GlpiLocation::class, [ 'country' => 'fooo', 'state' => 'baz' ]); - $item->update(['id' => $item->getID(), 'locations_id' => $location->getID()]); + $item->update(['id' => $item->getID(), 'locations_id' => $glpi_location->getID()]); $zone = new Zone(); $this->assertFalse($zone->getByItem($item)); @@ -239,11 +182,11 @@ public function testGetByItem() $this->assertEquals($zone->getID(), $expected_zone->getID()); // Test with a Computer object that has a location with both country and state and a matching zone for state and country - $location = $this->createItem(Location::class, [ + $glpi_location = $this->createItem(GlpiLocation::class, [ 'country' => 'foo', 'state' => 'baz' ]); - $item->update(['id' => $item->getID(), 'locations_id' => $location->getID()]); + $item->update(['id' => $item->getID(), 'locations_id' => $glpi_location->getID()]); $zone = new Zone(); $this->assertTrue($zone->getByItem($item)); $this->assertEquals($zone->getID(), $expected_zone->getID());