diff --git a/rector.php b/rector.php new file mode 100644 index 0000000..632ef48 --- /dev/null +++ b/rector.php @@ -0,0 +1,58 @@ +withPaths([ + __DIR__ . '/src', + ]) + ->withPhpVersion(PhpVersion::PHP_82) + ->withCache( + cacheDirectory: __DIR__ . '/var/rector', + cacheClass: FileCacheStorage::class, + ) + ->withRootFiles() + ->withParallel(timeoutSeconds: 300) + ->withImportNames(removeUnusedImports: true) + ->withPreparedSets( + deadCode: true, + codeQuality: true, + codingStyle: true, + ) + ->withPhpSets(php82: true) // apply PHP sets up to PHP 8.2 +; diff --git a/src/Controller/GetAuthLdapFilterController.php b/src/Controller/GetAuthLdapFilterController.php index b9c5ade..e5e2a58 100644 --- a/src/Controller/GetAuthLdapFilterController.php +++ b/src/Controller/GetAuthLdapFilterController.php @@ -70,7 +70,7 @@ public function __invoke(Request $request): Response : '' ; return new JsonResponse([ - 'filter' => "(& $filter $ldap_condition)", + 'filter' => sprintf('(& %s %s)', $filter, $ldap_condition), ]); } } diff --git a/src/Controller/LdapDropdownController.php b/src/Controller/LdapDropdownController.php index 756804b..4583fca 100644 --- a/src/Controller/LdapDropdownController.php +++ b/src/Controller/LdapDropdownController.php @@ -65,6 +65,7 @@ public function __invoke(Request $request): Response if ($condition_uuid === "") { throw new BadRequestHttpException(); } + // We don't control this array // @phpstan-ignore offsetAccess.nonOffsetAccessible $condition = $_SESSION['glpicondition'][$condition_uuid] ?? null; @@ -78,6 +79,7 @@ public function __invoke(Request $request): Response if (!isset($condition[$fkey])) { throw new BadRequestHttpException(); } + $question_id = $condition[$fkey]; $question = Question::getById($question_id); if (!$question) { diff --git a/src/Model/Dropdown/LdapDropdown.php b/src/Model/Dropdown/LdapDropdown.php index 0d7b820..f37d4f6 100644 --- a/src/Model/Dropdown/LdapDropdown.php +++ b/src/Model/Dropdown/LdapDropdown.php @@ -130,6 +130,7 @@ public function getDropdownValues(LdapDropdownQuery $query): array if (!$attribute) { throw new RuntimeException(); } + $attribute = $attribute->fields['value']; if (!is_string($attribute)) { throw new LogicException(); @@ -142,7 +143,7 @@ public function getDropdownValues(LdapDropdownQuery $query): array } // Insert search text into filter if specified - if ($search_text != '') { + if ($search_text !== '') { $ldap_filter = sprintf( "(& %s (%s))", $config->getLdapFilter(), @@ -154,7 +155,7 @@ public function getDropdownValues(LdapDropdownQuery $query): array try { // Transform LDAP warnings into errors - set_error_handler([self::class, 'ldapErrorHandler'], E_WARNING); + set_error_handler(self::ldapErrorHandler(...), E_WARNING); // Execute search $ldap_values = $this->executeLdapSearch( @@ -164,16 +165,14 @@ public function getDropdownValues(LdapDropdownQuery $query): array $page_size, $ldap_filter, ); - } catch (Throwable $e) { - throw new RuntimeException("Failed LDAP query", previous: $e); + } catch (Throwable $throwable) { + throw new RuntimeException("Failed LDAP query", $throwable->getCode(), previous: $throwable); } finally { restore_error_handler(); } // Sort results - usort($ldap_values, function ($a, $b) { - return strnatcmp($a['text'], $b['text']); - }); + usort($ldap_values, fn($a, $b) => strnatcmp($a['text'], $b['text'])); // Set expected select2 format return [ @@ -226,6 +225,7 @@ private function executeLdapSearch( if (!$result instanceof Result) { throw new RuntimeException(); } + ldap_parse_result($ds, $result, $errcode, $matcheddn, $errmsg, $referrals, $controls); // PHPstan doens't know that this is safe @@ -260,11 +260,12 @@ private function executeLdapSearch( } $found_count++; - if ($found_count < ((int) $page - 1) * (int) $page_size + 1) { + if ($found_count < ($page - 1) * $page_size + 1) { // before the requested page continue; } - if ($found_count > ((int) $page) * (int) $page_size) { + + if ($found_count > ($page) * $page_size) { // after the requested page break; } @@ -280,6 +281,7 @@ private function executeLdapSearch( break; } } + // @phpstan-ignore notIdentical.alwaysTrue } while ($cookie !== null && $cookie != '' && $count < $page_size); diff --git a/src/Model/Dropdown/LdapDropdownQuery.php b/src/Model/Dropdown/LdapDropdownQuery.php index 6949eaf..83bafc0 100644 --- a/src/Model/Dropdown/LdapDropdownQuery.php +++ b/src/Model/Dropdown/LdapDropdownQuery.php @@ -35,7 +35,7 @@ use Glpi\Form\Question; -final class LdapDropdownQuery +final readonly class LdapDropdownQuery { public function __construct( private Question $question, diff --git a/src/Model/QuestionType/LdapQuestion.php b/src/Model/QuestionType/LdapQuestion.php index 6f7fed0..1c04799 100644 --- a/src/Model/QuestionType/LdapQuestion.php +++ b/src/Model/QuestionType/LdapQuestion.php @@ -35,6 +35,7 @@ use AuthLDAP; use Glpi\Application\View\TemplateRenderer; +use Glpi\DBAL\JsonFieldInterface; use Glpi\Form\Migration\FormQuestionDataConverterInterface; use Glpi\Form\Question; use Glpi\Form\QuestionType\AbstractQuestionType; @@ -83,7 +84,7 @@ public function renderAdministrationTemplate(Question|null $question): string { // Read extra config specific to this question type $decoded_extra_data = []; - if ($question !== null && is_string($question->fields['extra_data'])) { + if ($question instanceof Question && is_string($question->fields['extra_data'])) { $decoded_extra_data = json_decode( $question->fields['extra_data'], associative: true, @@ -94,8 +95,9 @@ public function renderAdministrationTemplate(Question|null $question): string $decoded_extra_data = []; } } + $config = $this->getExtraDataConfig($decoded_extra_data); - if ($config === null) { + if (!$config instanceof JsonFieldInterface) { $config = new LdapQuestionConfig(); } @@ -119,15 +121,7 @@ public function renderAdministrationTemplate(Question|null $question): string public function validateExtraDataInput(array $input): bool { // Check if the itemtype is set - if ( - !isset($input[LdapQuestionConfig::AUTHLDAP_ID]) - && !isset($input[LdapQuestionConfig::LDAP_FILTER]) - && !isset($input[LdapQuestionConfig::LDAP_ATTRIBUTE_ID]) - ) { - return false; - } - - return true; + return !(!isset($input[LdapQuestionConfig::AUTHLDAP_ID]) && !isset($input[LdapQuestionConfig::LDAP_FILTER]) && !isset($input[LdapQuestionConfig::LDAP_ATTRIBUTE_ID])); } #[Override] @@ -139,7 +133,7 @@ public function getExtraDataConfigClass(): string #[Override] public function renderEndUserTemplate(Question|null $question): string { - if ($question === null) { + if (!$question instanceof Question) { throw new LogicException(); } diff --git a/src/Model/QuestionType/LdapQuestionConfig.php b/src/Model/QuestionType/LdapQuestionConfig.php index fa5679e..ae3b0b7 100644 --- a/src/Model/QuestionType/LdapQuestionConfig.php +++ b/src/Model/QuestionType/LdapQuestionConfig.php @@ -36,11 +36,13 @@ use Glpi\DBAL\JsonFieldInterface; use Override; -final class LdapQuestionConfig implements JsonFieldInterface +final readonly class LdapQuestionConfig implements JsonFieldInterface { // Unique reference to hardcoded name used for serialization public const AUTHLDAP_ID = "authldap_id"; + public const LDAP_FILTER = "ldap_filter"; + public const LDAP_ATTRIBUTE_ID = "ldap_attribute_id"; public function __construct( diff --git a/src/Service/ConfigManager.php b/src/Service/ConfigManager.php index d60a7fb..7ce6be8 100644 --- a/src/Service/ConfigManager.php +++ b/src/Service/ConfigManager.php @@ -93,6 +93,6 @@ public function getEnabledQuestionsTypes(): array public function hasAtLeastOneQuestionTypeEnabled(): bool { - return count($this->getEnabledQuestionsTypes()) > 0; + return $this->getEnabledQuestionsTypes() !== []; } } diff --git a/src/Utils/SafeCommonDBTM.php b/src/Utils/SafeCommonDBTM.php index 888a716..532b8f0 100644 --- a/src/Utils/SafeCommonDBTM.php +++ b/src/Utils/SafeCommonDBTM.php @@ -70,6 +70,7 @@ public static function getForeignKeyField(string $class): string if (!is_string($field)) { throw new RuntimeException(); } + return $field; } }