From 2145886bd87dba9e97ddc76abaa6e194a2edca81 Mon Sep 17 00:00:00 2001 From: Johan Cwiklinski Date: Thu, 16 Nov 2023 14:14:19 +0100 Subject: [PATCH] Improve code quality, prevent issues MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * checks for phpstan at level 8 * Add missing types * Missing extensions in composer file * Use statements * Simplify code * Check depreciations from phpstan Co-authored-by: Cédric Anne --- .github/workflows/ci-linux.yml | 4 + composer.json | 9 +- lib/php/Converter.php | 216 +++++++++--------- lib/php/FilesToJSON.php | 64 ++++-- phpstan.neon | 4 + .../Glpi/Inventory/tests/units/Converter.php | 2 +- 6 files changed, 169 insertions(+), 130 deletions(-) create mode 100644 phpstan.neon diff --git a/.github/workflows/ci-linux.yml b/.github/workflows/ci-linux.yml index bd60cd4..3f80fad 100644 --- a/.github/workflows/ci-linux.yml +++ b/.github/workflows/ci-linux.yml @@ -53,6 +53,10 @@ jobs: run: | vendor/bin/phpcs --standard=PSR12 lib/php/* + - name: Run code static analysis + run: | + vendor/bin/phpstan analyze --ansi --no-interaction --no-progress + - name: Conversions tests run: for i in `ls tests/data/*.xml`; do ./bin/convert $i || exit 1; done diff --git a/composer.json b/composer.json index cbec9d3..4a2da6f 100644 --- a/composer.json +++ b/composer.json @@ -18,13 +18,20 @@ "php": ">=7.4", "seld/jsonlint": "^1.10", "swaggest/json-schema": "^0.12.42", - "symfony/polyfill-php81": "^1.28" + "symfony/polyfill-php81": "^1.28", + "ext-json": "*", + "ext-libxml": "*", + "ext-simplexml": "*", + "ext-ctype": "*", + "ext-curl": "*" }, "autoload": { "files": ["lib/php/Converter.php", "lib/php/FilesToJSON.php"] }, "bin": ["bin/convert", "bin/build_hw_jsons", "bin/refresh_hw_sources","bin/validate"], "require-dev": { + "phpstan/phpstan": "^1.10", + "phpstan/phpstan-deprecation-rules": "^1.1", "phpunit/phpunit": "^9.6", "squizlabs/php_codesniffer": "^3.7" }, diff --git a/lib/php/Converter.php b/lib/php/Converter.php index f3dc799..e70b570 100644 --- a/lib/php/Converter.php +++ b/lib/php/Converter.php @@ -41,8 +41,12 @@ namespace Glpi\Inventory; +use DateTime; +use Exception; +use RuntimeException; use Swaggest\JsonSchema\Context; use Swaggest\JsonSchema\Schema; +use UnexpectedValueException; /** * Converts old FusionInventory XML format to new JSON schema @@ -59,31 +63,31 @@ class Converter { public const LAST_VERSION = 0.1; - /** @var ?double */ - private $target_version; + /** @var ?float */ + private ?float $target_version; /** @var bool */ - private $debug = false; + private bool $debug = false; /** * XML a different steps. Used for debug only - * @var array + * @var array */ - private $steps; + private array $steps; - /** @var array */ - private $mapping = [ + /** @var array */ + private array $mapping = [ '01' => 0.1 ]; - /** @var array */ - private $schema_patterns; - /** @var array */ - private $extra_properties; - /** @var array */ - private $extra_sub_properties; + /** @var array> */ + private array $schema_patterns; + /** @var array> */ + private array $extra_properties = []; + /** @var array>> */ + private array $extra_sub_properties = []; /** - * @var array + * @var array> * * A two dimensions array with types as key, * and nodes names as values. @@ -103,12 +107,12 @@ class Converter * @see Converter::getCastedValue() for supported types * @see Converter::convertTypes() for usage */ - private $convert_types; + private array $convert_types; /** * Instantiate converter * - * @param double|null $target_version JSON schema based version to target. Use last version if null. + * @param ?float $target_version JSON schema based version to target. Use last version if null. */ public function __construct($target_version = null) { @@ -117,7 +121,7 @@ public function __construct($target_version = null) } if (!is_double($target_version)) { - throw new \UnexpectedValueException('Version must be a double!'); + throw new UnexpectedValueException('Version must be a double!'); } $this->target_version = $target_version; @@ -126,11 +130,11 @@ public function __construct($target_version = null) /** * Get target version * - * @return double + * @return float */ - public function getTargetVersion() + public function getTargetVersion(): float { - return $this->target_version; + return $this->target_version ?? self::LAST_VERSION; } /** @@ -140,9 +144,9 @@ public function getTargetVersion() * * @return Converter */ - public function setDebug($debug) + public function setDebug(bool $debug): self { - $this->debug = (bool)$debug; + $this->debug = $debug; return $this; } @@ -151,7 +155,7 @@ public function setDebug($debug) * * @return boolean */ - public function isDebug() + public function isDebug(): bool { return $this->debug; } @@ -161,26 +165,30 @@ public function isDebug() * * @return string */ - public function getSchemaPath() + public function getSchemaPath(): string { - return realpath(__DIR__ . '/../../inventory.schema.json'); + $schema_path = realpath(__DIR__ . '/../../inventory.schema.json'); + if ($schema_path === false) { + throw new RuntimeException('Schema file not found!'); + } + return $schema_path; } /** - * @param array $properties + * @param array> $properties * @return $this */ - public function setExtraProperties(array $properties) + public function setExtraProperties(array $properties): self { $this->extra_properties = $properties; return $this; } /** - * @param array $properties + * @param array>> $properties * @return $this */ - public function setExtraSubProperties(array $properties) + public function setExtraSubProperties(array $properties): self { $this->extra_sub_properties = $properties; return $this; @@ -192,14 +200,18 @@ public function setExtraSubProperties(array $properties) */ public function buildSchema() { - $schema = json_decode(file_get_contents($this->getSchemaPath())); + $string = file_get_contents($this->getSchemaPath()); + if ($string === false) { + throw new RuntimeException('Unable to read schema file'); + } + $schema = json_decode($string); $properties = $schema->properties->content->properties; if ($this->extra_properties != null) { foreach ($this->extra_properties as $extra_property => $extra_config) { if (!property_exists($properties, $extra_property)) { - $properties->$extra_property = json_decode(json_encode($extra_config)); + $properties->$extra_property = json_decode((string)json_encode($extra_config)); } else { trigger_error( sprintf('Property %1$s already exists in schema.', $extra_property), @@ -218,7 +230,7 @@ public function buildSchema() case 'array': if (!property_exists($properties->$extra_sub_property->items->properties, $subprop)) { $properties->$extra_sub_property->items->properties->$subprop = - json_decode(json_encode($subconfig)); + json_decode((string)json_encode($subconfig)); } else { trigger_error( sprintf('Property %1$s already exists in schema.', $subprop), @@ -229,7 +241,7 @@ public function buildSchema() case 'object': if (!property_exists($properties->$extra_sub_property->properties, $subprop)) { $properties->$extra_sub_property->properties->$subprop = - json_decode(json_encode($subconfig)); + json_decode((string)json_encode($subconfig)); } else { trigger_error( sprintf( @@ -260,11 +272,11 @@ public function buildSchema() /** * Do validation (against last schema only!) * - * @param array $json Converted data to validate + * @param mixed $json Converted data to validate * * @return boolean */ - public function validate($json) + public function validate($json): bool { try { $schema = Schema::import($this->buildSchema()); @@ -273,11 +285,11 @@ public function validate($json) $context->tolerateStrings = (!defined('TU_USER')); $schema->in($json, $context); return true; - } catch (\Exception $e) { + } catch (Exception $e) { $errmsg = "JSON does not validate. Violations:\n"; $errmsg .= $e->getMessage(); $errmsg .= "\n"; - throw new \RuntimeException($errmsg); + throw new RuntimeException($errmsg); } } @@ -288,7 +300,7 @@ public function validate($json) * * @return string|false */ - public function convert($xml) + public function convert(string $xml) { libxml_use_internal_errors(true); $sxml = simplexml_load_string($xml); @@ -297,7 +309,7 @@ public function convert($xml) foreach (libxml_get_errors() as $error) { $errmsg .= "\n" . $error->message; } - throw new \RuntimeException($errmsg); + throw new RuntimeException($errmsg); } //remove empty nodes @@ -308,7 +320,7 @@ public function convert($xml) } //convert SimpleXML object to array, recursively. $data = json_decode( - json_encode((array)$sxml), + (string)json_encode((array)$sxml), true ); $this->loadSchemaPatterns(); @@ -321,7 +333,7 @@ public function convert($xml) } if (!$data = $this->$method($data)) { - throw new \RuntimeException('Conversion has failed at ' . $method); + throw new RuntimeException('Conversion has failed at ' . $method); } } @@ -331,9 +343,9 @@ public function convert($xml) /** * Get methods names we'll have to call in order to convert * - * @return string[] + * @return array */ - public function getMethods() + public function getMethods(): array { $methods = []; @@ -349,11 +361,11 @@ public function getMethods() /** * Converts to inventory format 0.1 * - * @param array $data Contents + * @param array $data Contents * - * @return array + * @return array */ - private function convertTo01(array $data) + private function convertTo01(array $data): array { //all keys are now lowercase $data = $this->arrayChangeKeyCaseRecursive($data); @@ -580,9 +592,9 @@ private function convertTo01(array $data) if (isset($process['started'])) { if (preg_match($ns_pattern, $process['started'])) { try { - $started = new \DateTime($process['started']); + $started = new DateTime($process['started']); $process['started'] = $started->format('Y-m-d H:i:s'); - } catch (\Exception $e) { + } catch (Exception $e) { //not valid, drop. unset($process['started']); } @@ -635,7 +647,7 @@ private function convertTo01(array $data) if (isset($data['content']['operatingsystem']['boot_time'])) { //convert to 'Y-m-d H:i:s' if format = 'Y-d-m H:i:s' $boot_time = $data['content']['operatingsystem']['boot_time']; - $boot_datetime = \DateTime::createFromFormat('Y-d-m H:i:s', $boot_time); + $boot_datetime = DateTime::createFromFormat('Y-d-m H:i:s', $boot_time); //check if create from 'Y-d-m H:i:s' format is OK (ie: 2022-21-09 05:21:23) //but he can return a new DateTime instead of false for '2022-10-04 05:21:23' //so check return value from strtotime because he only knows / handle 'English textual datetime' @@ -804,7 +816,7 @@ private function convertTo01(array $data) } //missing hour in timezone offset - if (isset($data['content']['operatingsystem']) && isset($data['content']['operatingsystem']['timezone'])) { + if (isset($data['content']['operatingsystem']['timezone'])) { $timezone = &$data['content']['operatingsystem']['timezone']; if (preg_match('/^[+-][0-9]{2}$/', $timezone['offset'])) { @@ -845,7 +857,7 @@ private function convertTo01(array $data) foreach ($powers as $power) { if (isset($battery[$power])) { $value = $this->convertBatteryPower($battery[$power]); - if ($value == false) { + if (!$value) { unset($battery[$power]); } else { $battery[$power] = $value; @@ -855,7 +867,7 @@ private function convertTo01(array $data) if (isset($battery['voltage'])) { $voltage = $this->convertBatteryVoltage($battery['voltage']); - if ($voltage == false) { + if (!$voltage) { unset($battery['voltage']); } else { $battery['voltage'] = $voltage; @@ -869,7 +881,7 @@ private function convertTo01(array $data) foreach ($data['content']['powersupplies'] as &$psupply) { if (isset($psupply['power_max'])) { $value = $this->convertBatteryPower($psupply['power_max']); - if ($value == false) { + if (!$value) { unset($psupply['power_max']); } else { $psupply['power_max'] = $value; @@ -1068,11 +1080,11 @@ private function convertTo01(array $data) /** * Set convert types * - * @param array $convert_types Convert types configuration + * @param array> $convert_types Convert types configuration * * @return Converter */ - public function setConvertTypes(array $convert_types) + public function setConvertTypes(array $convert_types): self { $this->convert_types = $convert_types; return $this; @@ -1084,18 +1096,18 @@ public function setConvertTypes(array $convert_types) * Method must populate $convert_types array. * @see Converter::convert_types parameter * - * @param array $data Input data, will be modified + * @param array $data Input data, will be modified * * @return void */ - public function convertTypes(&$data) + public function convertTypes(array &$data): void { $types = $this->convert_types; foreach ($types as $type => $names) { foreach ($names as $name) { $keys = explode('/', $name); if (count($keys) != 2) { - throw new \RuntimeException($name . ' not supported!'); + throw new RuntimeException($name . ' not supported!'); } if (isset($data['content'][$keys[0]])) { if (is_array($data['content'][$keys[0]])) { @@ -1118,7 +1130,7 @@ public function convertTypes(&$data) } } } - if (isset($data['content'][$keys[0]]) && isset($data['content'][$keys[0]][$keys[1]])) { + if (isset($data['content'][$keys[0]][$keys[1]])) { $data['content'][$keys[0]][$keys[1]] = $this->getCastedValue( $data['content'][$keys[0]][$keys[1]], $type @@ -1137,31 +1149,31 @@ public function convertTypes(&$data) * * @return mixed */ - public function getCastedValue($value, $type) + public function getCastedValue(string $value, string $type) { switch ($type) { case 'boolean': return (bool)$value; case 'integer': $casted = (int)$value; - if ($value == $casted && is_numeric($value)) { + if (is_numeric($value) && $value == $casted) { return $casted; } else { return null; } default: - throw new \UnexpectedValueException('Type ' . $type . ' not known.'); + throw new UnexpectedValueException('Type ' . $type . ' not known.'); } } /** * Change array keys case recursively * - * @param array $array Input array + * @param array $array Input array * - * @return array + * @return array */ - public function arrayChangeKeyCaseRecursive(array $array) + public function arrayChangeKeyCaseRecursive(array $array): array { return array_map( function ($item) { @@ -1182,7 +1194,7 @@ function ($item) { * * @return string|null */ - public function convertDate($value, $format = 'Y-m-d'): ?string + public function convertDate(string $value, string $format = 'Y-m-d'): ?string { $nullables = ['n/a', 'boot_time']; if (empty($value) || isset(array_flip($nullables)[strtolower($value)])) { @@ -1202,21 +1214,18 @@ public function convertDate($value, $format = 'Y-m-d'): ?string 'd.m.Y', 'Ymd' ]; - try { - while ($current = array_shift($formats)) { - $d = \DateTime::createFromFormat($current, $value); - if ($d !== false) { - break; - } - } + while ($current = array_shift($formats)) { + $d = DateTime::createFromFormat($current, $value); if ($d !== false) { - return $d->format($format); + break; } - return $value; - } catch (\Exception $e) { - throw $e; } + + if ($d !== false) { + return $d->format($format); + } + return $value; } /** @@ -1224,9 +1233,12 @@ public function convertDate($value, $format = 'Y-m-d'): ?string * * @return void */ - public function loadSchemaPatterns() + public function loadSchemaPatterns(): void { $string = file_get_contents($this->getSchemaPath()); + if ($string === false) { + throw new RuntimeException('Unable to read schema file'); + } $json = json_decode($string, true); $this->schema_patterns['networks_types'] = explode( @@ -1242,7 +1254,7 @@ public function loadSchemaPatterns() /** * Convert battery capacity * - * @param string $capacity Inventoried capacity + * @param integer|string $capacity Inventoried capacity * * @return integer|false */ @@ -1284,7 +1296,7 @@ public function convertBatteryPower($capacity) * * @return integer|false */ - public function convertBatteryVoltage($voltage) + public function convertBatteryVoltage(string $voltage) { $volt_pattern = "/^([0-9]+(\.[0-9]+)?) ?V$/i"; $matches = []; @@ -1308,9 +1320,9 @@ public function convertBatteryVoltage($voltage) /** * Handle network inventory XML format * - * @param array $data Contents + * @param array $data Contents * - * @return array + * @return array */ public function convertNetworkInventory(array $data): array { @@ -1403,7 +1415,7 @@ public function convertNetworkInventory(array $data): array $itemtype = 'NetworkEquipment'; break; default: - throw new \RuntimeException('Unhandled device type: ' . $device_info['type']); + throw new RuntimeException('Unhandled device type: ' . $device_info['type']); } } $data['itemtype'] = $itemtype; @@ -1479,7 +1491,7 @@ public function convertNetworkInventory(array $data): array case 'modems': case 'simcards': //first, retrieve data from device - $elements = $device[$key]; + $elements = $device_data; if (!array_is_list($elements)) { $elements = [$elements]; } @@ -1523,14 +1535,12 @@ public function convertNetworkInventory(array $data): array break; case "cartridges": case "pagecounters": - case "error": - $data['content'][$key] = $device[$key]; - break; case "drives": - $data['content'][$key] = $device[$key]; + case "error": + $data['content'][$key] = $device_data; break; default: - throw new \RuntimeException('Key ' . $key . ' is not handled in network devices conversion'); + throw new RuntimeException('Key ' . $key . ' is not handled in network devices conversion'); } } @@ -1545,9 +1555,9 @@ public function convertNetworkInventory(array $data): array /** * Pre-handle network inventory XML format * - * @param array $data Contents + * @param array $data Contents * - * @return array + * @return array */ public function convertNetworkDiscovery(array $data): array { @@ -1562,7 +1572,7 @@ public function convertNetworkDiscovery(array $data): array } $device_info = &$data['content']['device']['info']; - if (isset($device['snmphostname']) && !empty($device['snmphostname'])) { + if (!empty($device['snmphostname'])) { //SNMP hostname has precedence if (isset($device['dnshostname'])) { unset($device['dnshostname']); @@ -1572,7 +1582,7 @@ public function convertNetworkDiscovery(array $data): array } } - if (isset($device['netbiosname']) && !empty($device['netbiosname']) && isset($device['dnshostname'])) { + if (!empty($device['netbiosname']) && isset($device['dnshostname'])) { //NETBIOS name has precedence unset($device['dnshostname']); } @@ -1592,7 +1602,7 @@ public function convertNetworkDiscovery(array $data): array case 'dnshostname': case 'snmphostname': case 'netbiosname': - $device_info['name'] = $device[$key]; + $device_info['name'] = $device_data; unset($device[$key]); break; case 'entity': @@ -1601,7 +1611,7 @@ public function convertNetworkDiscovery(array $data): array //not used break; case 'ips': - $device_info['ips'] = $device[$key]; + $device_info['ips'] = $device_data; unset($device[$key]); break; case 'mac': @@ -1615,26 +1625,26 @@ public function convertNetworkDiscovery(array $data): array case 'description': case 'serial': case 'assettag': - $device_info[$key] = $device[$key]; + $device_info[$key] = $device_data; unset($device[$key]); break; case 'netportvendor': //translate as manufacturer - if not present if (!isset($device['manufacturer'])) { - $device_info['manufacturer'] = $device[$key]; + $device_info['manufacturer'] = $device_data; } unset($device[$key]); break; case 'workgroup': - $data['content']['hardware']['workgroup'] = $device[$key]; + $data['content']['hardware']['workgroup'] = $device_data; unset($device[$key]); break; case 'authsnmp': - $device_info['credentials'] = $device[$key]; + $device_info['credentials'] = $device_data; unset($device[$key]); break; default: - throw new \RuntimeException('Key ' . $key . ' is not handled in network discovery conversion'); + throw new RuntimeException('Key ' . $key . ' is not handled in network discovery conversion'); } } @@ -1644,7 +1654,7 @@ public function convertNetworkDiscovery(array $data): array /** * Explode old pciid to vendorid:productid * - * @param array $data Node data + * @param array $data Node data * * @return void */ @@ -1667,7 +1677,7 @@ private function checkPciid(array &$data): void /** * Is a network inventory? * - * @param array $data Data + * @param array $data Data * * @return boolean */ @@ -1679,7 +1689,7 @@ private function isNetworkInventory(array $data): bool /** * Is a network discovery? * - * @param array $data Data + * @param array $data Data * * @return boolean */ diff --git a/lib/php/FilesToJSON.php b/lib/php/FilesToJSON.php index 0466a00..e99ffc9 100644 --- a/lib/php/FilesToJSON.php +++ b/lib/php/FilesToJSON.php @@ -41,6 +41,8 @@ namespace Glpi\Inventory; +use RuntimeException; + /** * Converts old FusionInventory XML format to new JSON schema * for automatic inventory. @@ -69,7 +71,7 @@ final class FilesToJSON /** * @var string */ - private $path = __DIR__ . '/../../data'; + private string $path = __DIR__ . '/../../data'; /** * Get JSON file path @@ -86,7 +88,7 @@ public function getJsonFilePath(string $type): string /** * Download new sources * - * @throws \RuntimeException + * @throws RuntimeException * @return void */ public function refreshSources() @@ -96,7 +98,7 @@ public function refreshSources() $contents = $this->callCurl($uri); if (file_put_contents($path, $contents) !== strlen($contents)) { - throw new \RuntimeException(sprintf('Unable to write content in %s.', $path)); + throw new RuntimeException(sprintf('Unable to write content in %s.', $path)); } } } @@ -104,7 +106,7 @@ public function refreshSources() /** * Runs all conversions * - * @throws \RuntimeException + * @throws RuntimeException * @return void */ public function run(): void @@ -139,7 +141,7 @@ private function getSourceFilename(string $type): string $basename = 'iftype.csv'; break; default: - throw new \RuntimeException('Unknown type ' . $type); + throw new RuntimeException('Unknown type ' . $type); } return $basename; @@ -161,7 +163,7 @@ private function getSourceFilePath(string $type): string * Get file for type * * @param string $type Type - * @throws \RuntimeException + * @throws RuntimeException * @return resource */ private function getSourceFile(string $type) @@ -173,14 +175,14 @@ private function getSourceFile(string $type) $path = __DIR__ . '/../../source_files/' . $this->getSourceFilename($type); if (!file_exists($path)) { - throw new \RuntimeException(sprintf('Source file %s not found.', $this->getSourceFilename($type))); + throw new RuntimeException(sprintf('Source file %s not found.', $this->getSourceFilename($type))); } } $file = fopen($path, 'r'); if ($file === false) { - throw new \RuntimeException(sprintf('Unable to open source file %s.', $path)); + throw new RuntimeException(sprintf('Unable to open source file %s.', $path)); } return $file; @@ -189,7 +191,7 @@ private function getSourceFile(string $type) /** * Convert PCI file from IDS to JSON * - * @throws \RuntimeException + * @throws RuntimeException * @return void */ private function convertPciFile(): void @@ -197,6 +199,7 @@ private function convertPciFile(): void $pciFile = $this->getSourceFile(self::TYPE_PCI); $pci_ids = []; + $vendorId = null; while ($buffer = fgets($pciFile)) { $stack = []; if (preg_match("/^(\w+)\s*(.+)/i", $buffer, $stack)) { @@ -213,7 +216,7 @@ private function convertPciFile(): void if (!feof($pciFile)) { // Ensure source file reading reach end of file. - throw new \RuntimeException('Error while reading PCI source file.'); + throw new RuntimeException('Error while reading PCI source file.'); } $this->writeJsonFile(self::TYPE_PCI, $pci_ids); @@ -222,7 +225,7 @@ private function convertPciFile(): void /** * Convert USB file from IDS to JSON * - * @throws \RuntimeException + * @throws RuntimeException * @return void */ private function convertUsbFile(): void @@ -230,6 +233,7 @@ private function convertUsbFile(): void $usbFile = $this->getSourceFile(self::TYPE_USB); $usb_ids = []; + $vendorId = null; while ($buffer = fgets($usbFile)) { $stack = []; if (preg_match("/^(\w+)\s*(.+)/i", $buffer, $stack)) { @@ -246,7 +250,7 @@ private function convertUsbFile(): void if (!feof($usbFile)) { // Ensure source file reading reach end of file. - throw new \RuntimeException('Error while reading USB source file.'); + throw new RuntimeException('Error while reading USB source file.'); } $this->writeJsonFile(self::TYPE_USB, $usb_ids); @@ -256,7 +260,7 @@ private function convertUsbFile(): void /** * Convert OUI file from TXT to JSON * - * @throws \RuntimeException + * @throws RuntimeException * @return void */ private function convertOUIFile(): void @@ -274,7 +278,7 @@ private function convertOUIFile(): void if (!feof($ouiFile)) { // Ensure source file reading reach end of file. - throw new \RuntimeException('Error while reading OUI source file.'); + throw new RuntimeException('Error while reading OUI source file.'); } $this->writeJsonFile(self::TYPE_OUI, $ouis); @@ -283,7 +287,7 @@ private function convertOUIFile(): void /** * Convert iftype file from CSV to JSON * - * @throws \RuntimeException + * @throws RuntimeException * @return void */ private function convertIftypeFile(): void @@ -302,7 +306,7 @@ private function convertIftypeFile(): void if (!feof($iftypeFile)) { // Ensure source file reading reach end of file. - throw new \RuntimeException('Error while reading IFtype source file.'); + throw new RuntimeException('Error while reading IFtype source file.'); } $this->writeJsonFile(self::TYPE_IFTYPE, $iftypes); @@ -312,8 +316,8 @@ private function convertIftypeFile(): void * Write converted source into corresponding file. * * @param string $type - * @param array $data - * @throws \RuntimeException + * @param array $data + * @throws RuntimeException * @return void */ private function writeJsonFile(string $type, array $data): void @@ -322,11 +326,11 @@ private function writeJsonFile(string $type, array $data): void $contents = json_encode($data, JSON_PRETTY_PRINT); if ($contents === false) { - throw new \RuntimeException(sprintf('Error while encoding "%s" data to JSON.', $type)); + throw new RuntimeException(sprintf('Error while encoding "%s" data to JSON.', $type)); } - if (!file_put_contents($path, $contents) === strlen($contents)) { - throw new \RuntimeException(sprintf('Unable to write "%s" JSON into "%s".', $type, $path)); + if (file_put_contents($path, $contents) !== strlen($contents)) { + throw new RuntimeException(sprintf('Unable to write "%s" JSON into "%s".', $type, $path)); } } @@ -334,13 +338,22 @@ private function writeJsonFile(string $type, array $data): void * Executes a curl call * * @param string $url URL to retrieve - * @throws \RuntimeException + * @throws RuntimeException * @return string */ - private function callCurl($url): string + private function callCurl(string $url): string { $ch = curl_init($url); + if ($ch === false) { + throw new RuntimeException( + sprintf( + 'Unable to initialize curl for %s', + $url + ) + ); + } + $opts = [ CURLOPT_URL => $url, CURLOPT_USERAGENT => "GLPI/Inventory format 1.0", @@ -371,9 +384,10 @@ private function callCurl($url): string } if ($msgerr !== null) { - throw new \RuntimeException($msgerr); + throw new RuntimeException($msgerr); } - return $content; + //force cast to made phpstan happy, but return is always string here + return (string)$content; } } diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..7ea5679 --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,4 @@ +parameters: + level: 8 + paths: + - lib/php/ diff --git a/tests/Glpi/Inventory/tests/units/Converter.php b/tests/Glpi/Inventory/tests/units/Converter.php index b8e7d57..1f78eb1 100644 --- a/tests/Glpi/Inventory/tests/units/Converter.php +++ b/tests/Glpi/Inventory/tests/units/Converter.php @@ -98,7 +98,7 @@ public function testGetMethods() * * @return array */ - public static function valuesToCastProvider() + public static function valuesToCastProvider(): array { return [ //true real values