diff --git a/.changelog/current/2628-fix-php-issues.md b/.changelog/current/2628-fix-php-issues.md new file mode 100644 index 000000000..89631e193 --- /dev/null +++ b/.changelog/current/2628-fix-php-issues.md @@ -0,0 +1,4 @@ +# Maintenance + +- Clean PHP code by removing code smells and redundant code + diff --git a/composer.json b/composer.json index 8db009ef1..138a80860 100644 --- a/composer.json +++ b/composer.json @@ -9,13 +9,14 @@ } ], "require": { - "ext-libxml": "*" + "ext-libxml": "*", + "ext-dom": "*" }, "require-dev": { "nextcloud/coding-standard": "^1.0.0", "christophwurst/nextcloud_testing": "^1.0.0", "psalm/phar": "^5.12", - "nextcloud/ocp": "^27.0" + "nextcloud/ocp": "dev-stable28" }, "scripts": { "cs:check": "./vendor/bin/php-cs-fixer fix --dry-run --diff", @@ -31,7 +32,7 @@ }, "config": { "platform": { - "php": "7.4" + "php": "8.0" } } } diff --git a/composer.lock b/composer.lock index a04b30b11..31114d08c 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "418ab4ba5a5387a733911562eb0e66a6", + "content-hash": "e5146684b199d0f423995ee72c758d0c", "packages": [], "packages-dev": [ { @@ -268,20 +268,20 @@ }, { "name": "nextcloud/ocp", - "version": "v27.1.9", + "version": "dev-stable28", "source": { "type": "git", "url": "https://github.com/nextcloud-deps/ocp.git", - "reference": "f451f80f29eda90c3283e9ad90c83e0a09a03010" + "reference": "d1399b589aa6c0393b4f62bd7022315a711d8c09" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nextcloud-deps/ocp/zipball/f451f80f29eda90c3283e9ad90c83e0a09a03010", - "reference": "f451f80f29eda90c3283e9ad90c83e0a09a03010", + "url": "https://api.github.com/repos/nextcloud-deps/ocp/zipball/d1399b589aa6c0393b4f62bd7022315a711d8c09", + "reference": "d1399b589aa6c0393b4f62bd7022315a711d8c09", "shasum": "" }, "require": { - "php": "^7.4 || ~8.0 || ~8.1", + "php": "~8.0 || ~8.1 || ~8.2 || ~8.3", "psr/clock": "^1.0", "psr/container": "^2.0.2", "psr/event-dispatcher": "^1.0", @@ -290,7 +290,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-stable27": "27.0.0-dev" + "dev-stable28": "28.0.0-dev" } }, "notification-url": "https://packagist.org/downloads/", @@ -306,9 +306,9 @@ "description": "Composer package containing Nextcloud's public API (classes, interfaces)", "support": { "issues": "https://github.com/nextcloud-deps/ocp/issues", - "source": "https://github.com/nextcloud-deps/ocp/tree/v27.1.9" + "source": "https://github.com/nextcloud-deps/ocp/tree/stable28" }, - "time": "2024-04-11T00:33:20+00:00" + "time": "2025-01-08T00:43:56+00:00" }, { "name": "nikic/php-parser", @@ -2492,15 +2492,18 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": { + "nextcloud/ocp": 20 + }, "prefer-stable": false, "prefer-lowest": false, "platform": { - "ext-libxml": "*" + "ext-libxml": "*", + "ext-dom": "*" }, - "platform-dev": [], + "platform-dev": {}, "platform-overrides": { - "php": "7.4" + "php": "8.0" }, "plugin-api-version": "2.3.0" } diff --git a/lib/Db/RecipeDb.php b/lib/Db/RecipeDb.php index daefcc747..e951ea690 100755 --- a/lib/Db/RecipeDb.php +++ b/lib/Db/RecipeDb.php @@ -349,7 +349,7 @@ public function getRecipesByKeywords(string $keywords, string $user_id) { * @throws \OCP\AppFramework\Db\DoesNotExistException if not found */ public function findRecipes(array $keywords, string $user_id) { - $has_keywords = $keywords && is_array($keywords) && $keywords[0]; + $has_keywords = $keywords && $keywords[0]; if (!$has_keywords) { return $this->findAllRecipes($user_id); diff --git a/lib/Helper/Filter/JSON/FixInstructionsFilter.php b/lib/Helper/Filter/JSON/FixInstructionsFilter.php index 191f0c93e..2658e159f 100644 --- a/lib/Helper/Filter/JSON/FixInstructionsFilter.php +++ b/lib/Helper/Filter/JSON/FixInstructionsFilter.php @@ -107,7 +107,7 @@ public function apply(array &$json): bool { } ksort($instructions); - $instructions = array_merge(...$instructions); + $instructions = array_merge([], ...$instructions); } $instructions = array_map(function ($x) { @@ -160,7 +160,7 @@ private function flattenItemList(array $list): array { } ksort($newElements); - $elements = array_merge(...$newElements); + $elements = array_merge([], ...$newElements); return $elements; } diff --git a/lib/Helper/Filter/JSON/SchemaConformityFilter.php b/lib/Helper/Filter/JSON/SchemaConformityFilter.php index 920869665..f4e5b55eb 100644 --- a/lib/Helper/Filter/JSON/SchemaConformityFilter.php +++ b/lib/Helper/Filter/JSON/SchemaConformityFilter.php @@ -8,10 +8,12 @@ class SchemaConformityFilter extends AbstractJSONFilter { public function apply(array &$json): bool { $changed = false; - - $changed |= $this->setJSONValue($json, '@context', 'http://schema.org'); - $changed |= $this->setJSONValue($json, '@type', 'Recipe'); - - return (bool)$changed; + if ($this->setJSONValue($json, '@context', 'http://schema.org')) { + $changed = true; + } + if ($this->setJSONValue($json, '@type', 'Recipe')) { + $changed = true; + } + return $changed; } } diff --git a/lib/Helper/HTMLParser/HttpMicrodataParser.php b/lib/Helper/HTMLParser/HttpMicrodataParser.php index 259963d41..1ce27daab 100644 --- a/lib/Helper/HTMLParser/HttpMicrodataParser.php +++ b/lib/Helper/HTMLParser/HttpMicrodataParser.php @@ -3,6 +3,7 @@ namespace OCA\Cookbook\Helper\HTMLParser; use DOMDocument; +use DOMElement; use DOMNode; use DOMNodeList; use DOMXPath; @@ -58,9 +59,9 @@ public function parse(DOMDocument $document, ?string $url): array { /** * Parse a DOM node that represents a recipe * - * @param DOMNode $recipeNode The DOM node to parse + * @param DOMElement $recipeNode The DOM node to parse */ - private function parseRecipe(DOMNode $recipeNode): void { + private function parseRecipe(DOMElement $recipeNode): void { $this->searchSimpleProperties($recipeNode, 'name'); $this->searchSimpleProperties($recipeNode, 'keywords'); $this->searchSimpleProperties($recipeNode, 'category'); @@ -75,9 +76,9 @@ private function parseRecipe(DOMNode $recipeNode): void { /** * Make one final desperate attempt at getting the instructions - * @param DOMNode $recipeNode The recipe node to use + * @param DOMElement $recipeNode The recipe node to use */ - private function fixupInstructions(DOMNode $recipeNode): void { + private function fixupInstructions(DOMElement $recipeNode): void { if ( !isset($this->recipe['recipeInstructions']) || !$this->recipe['recipeInstructions'] || sizeof($this->recipe['recipeInstructions']) < 1 @@ -254,12 +255,12 @@ private function extractAttribute(DOMNodeList $nodes, array $attributes): array * This can be used to extract a single attribute from the DOM tree. * The attributes are evaluated first to last and the first found attribute is returned. * - * @param DOMNode $node The node to evaluate + * @param DOMElement $node The node to evaluate * @param array $attributes The possible attributes to check * @throws AttributeNotFoundException If none of the named attributes is found * @return string The value of the attribute */ - private function extractSingeAttribute(DOMNode $node, array $attributes): string { + private function extractSingeAttribute(DOMElement $node, array $attributes): string { foreach ($attributes as $attr) { if ($node->hasAttribute($attr) && !empty($node->getAttribute($attr))) { return $node->getAttribute($attr); diff --git a/lib/Helper/ImageService/ThumbnailFileHelper.php b/lib/Helper/ImageService/ThumbnailFileHelper.php index ae16f8810..3a23af29c 100644 --- a/lib/Helper/ImageService/ThumbnailFileHelper.php +++ b/lib/Helper/ImageService/ThumbnailFileHelper.php @@ -2,12 +2,16 @@ namespace OCA\Cookbook\Helper\ImageService; +use OCA\Cookbook\Exception\InvalidThumbnailTypeException; use OCA\Cookbook\Exception\NoRecipeImageFoundException; use OCP\Files\File; use OCP\Files\Folder; +use OCP\Files\GenericFileException; +use OCP\Files\InvalidPathException; use OCP\Files\NotFoundException; use OCP\Files\NotPermittedException; use OCP\IL10N; +use OCP\Lock\LockedException; /** * This class allows to handle the files of the thumbnails diff --git a/lib/Helper/RestParameterParser.php b/lib/Helper/RestParameterParser.php index 6e6bac3f5..deb5e30eb 100644 --- a/lib/Helper/RestParameterParser.php +++ b/lib/Helper/RestParameterParser.php @@ -55,6 +55,8 @@ public function getParameters(): array { } break; + default: + throw new \Exception($this->l->t('Unsupported type of transmitted data. This is a bug, please report it.')); } } else { throw new \Exception($this->l->t('Cannot detect type of transmitted data. This is a bug, please report it.')); diff --git a/lib/Helper/UserConfigHelper.php b/lib/Helper/UserConfigHelper.php index f78cc5f62..a4b2efe51 100644 --- a/lib/Helper/UserConfigHelper.php +++ b/lib/Helper/UserConfigHelper.php @@ -124,7 +124,7 @@ public function getUpdateInterval(): int { * @throws UserNotLoggedInException if no user is logged in */ public function setUpdateInterval(int $value): void { - $this->setRawValue(self::KEY_UPDATE_INTERVAL, $value); + $this->setRawValue(self::KEY_UPDATE_INTERVAL, (string)$value); } /** diff --git a/lib/Service/ImageService.php b/lib/Service/ImageService.php index ba769c20a..14316aa4b 100644 --- a/lib/Service/ImageService.php +++ b/lib/Service/ImageService.php @@ -2,10 +2,15 @@ namespace OCA\Cookbook\Service; +use OCA\Cookbook\Exception\InvalidThumbnailTypeException; +use OCA\Cookbook\Exception\NoRecipeImageFoundException; +use OCA\Cookbook\Exception\RecipeImageExistsException; use OCA\Cookbook\Helper\ImageService\ImageFileHelper; use OCA\Cookbook\Helper\ImageService\ThumbnailFileHelper; use OCP\Files\File; use OCP\Files\Folder; +use OCP\Files\GenericFileException; +use OCP\Files\InvalidPathException; use OCP\Files\NotFoundException; use OCP\Files\NotPermittedException; use OCP\Lock\LockedException; diff --git a/lib/Service/RecipeService.php b/lib/Service/RecipeService.php index b7c0cf7cc..c26ed514a 100755 --- a/lib/Service/RecipeService.php +++ b/lib/Service/RecipeService.php @@ -224,6 +224,9 @@ public function addRecipe($json, $importedHtml = null) { if (isset($json['id']) && $json['id']) { // Recipe already has an id, update it $recipe_folder = $user_folder->getById($json['id'])[0]; + if (!($recipe_folder instanceof Folder)) { + throw new \RuntimeException($this->il10n->t('Unexpected node received for recipe folder.')); + } $old_path = $recipe_folder->getPath(); $new_path = dirname($old_path) . '/' . $recipeFolderName; @@ -566,14 +569,8 @@ public function getVisibleInfoBlocks(): array { /** * Get recipe file contents as an array - * - * @param File $file */ - public function parseRecipeFile($file): ?array { - if (!$file) { - return null; - } - + public function parseRecipeFile(File $file): ?array { $json = json_decode($file->getContent(), true); if (!$json) { @@ -583,7 +580,7 @@ public function parseRecipeFile($file): ?array { $json['id'] = $file->getParent()->getId(); - if (!array_key_exists('dateCreated', $json) && method_exists($file, 'getCreationTime')) { + if (!array_key_exists('dateCreated', $json)) { $json['dateCreated'] = $file->getCreationTime(); } diff --git a/psalm.xml b/psalm.xml index b86e8799c..6e49d1155 100644 --- a/psalm.xml +++ b/psalm.xml @@ -6,6 +6,8 @@ xmlns="https://getpsalm.org/schema/config" xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd" errorBaseline="tests/psalm-baseline.xml" + findUnusedBaselineEntry="true" + phpVersion="8.0" >