diff --git a/.github/workflows/psalm.yml b/.github/workflows/psalm.yml
new file mode 100644
index 00000000..9934b3e6
--- /dev/null
+++ b/.github/workflows/psalm.yml
@@ -0,0 +1,56 @@
+# This workflow is provided via the organization template repository
+#
+# https://github.com/nextcloud/.github
+# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
+
+name: Psalm static analysis
+
+on:
+ pull_request:
+ paths:
+ - .github/workflows/psalm.yml
+ - appinfo/**
+ - composer.*
+ - lib/**
+ - templates/**
+ - tests/**
+ push:
+ branches:
+ - main
+ - stable*
+ - test
+ paths:
+ - .github/workflows/psalm.yml
+ - appinfo/**
+ - composer.*
+ - lib/**
+ - templates/**
+ - tests/**
+
+concurrency:
+ group: psalm-${{ github.head_ref || github.run_id }}
+ cancel-in-progress: true
+
+jobs:
+ static-analysis:
+ runs-on: ubuntu-latest
+
+ name: Psalm check
+ steps:
+ - name: Checkout
+ uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
+
+ - name: Set up php
+ uses: shivammathur/setup-php@c5fc0d8281aba02c7fda07d3a70cc5371548067d # v2
+ with:
+ php-version: 8.2
+ coverage: none
+ ini-file: development
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Install dependencies
+ run: composer i
+
+ - name: Run coding standards check
+ run: composer run psalm
diff --git a/appinfo/info.xml b/appinfo/info.xml
index bdff9d0c..f56b39d0 100644
--- a/appinfo/info.xml
+++ b/appinfo/info.xml
@@ -37,7 +37,7 @@ include text processing providers to:
1.0.3
agpl
Julien Veyssier
- TPAssistant
+ TpAssistant
https://github.com/nextcloud/assistant
@@ -48,17 +48,17 @@ include text processing providers to:
https://github.com/nextcloud/assistant/raw/main/img/screenshot2.jpg
https://github.com/nextcloud/assistant/raw/main/img/screenshot3.jpg
- OCA\TPAssistant\Cron\CleanupImageGenerations
+ OCA\TpAssistant\Cron\CleanupImageGenerations
- OCA\TPAssistant\Command\CleanupImageGenerations
+ OCA\TpAssistant\Command\CleanupImageGenerations
- OCA\TPAssistant\Settings\Admin
- OCA\TPAssistant\Settings\Personal
- OCA\TPAssistant\Settings\PersonalSection
+ OCA\TpAssistant\Settings\Admin
+ OCA\TpAssistant\Settings\Personal
+ OCA\TpAssistant\Settings\PersonalSection
diff --git a/composer.json b/composer.json
index cb19da3d..d602b616 100644
--- a/composer.json
+++ b/composer.json
@@ -17,7 +17,7 @@
"lint": "find . -name \\*.php -not -path './vendor/*' -print0 | xargs -0 -n1 php -l",
"cs:check": "php-cs-fixer fix --dry-run --diff",
"cs:fix": "php-cs-fixer fix",
- "psalm": "psalm.phar",
+ "psalm": "psalm.phar --no-cache",
"test:unit": "phpunit --config tests/phpunit.xml"
},
"require-dev": {
diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php
index 65a9c075..c641d857 100644
--- a/lib/AppInfo/Application.php
+++ b/lib/AppInfo/Application.php
@@ -1,16 +1,16 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
-namespace OCA\TPAssistant\Command;
+namespace OCA\TpAssistant\Command;
use Exception;
-use OCA\TPAssistant\AppInfo\Application;
-use OCA\TPAssistant\Service\Text2Image\CleanUpService;
+use OC\Core\Command\Base;
+use OCA\TpAssistant\AppInfo\Application;
+use OCA\TpAssistant\Service\Text2Image\CleanUpService;
use OCP\IConfig;
-use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
-class CleanupImageGenerations extends Command {
+class CleanupImageGenerations extends Base {
public function __construct(
private CleanUpService $cleanUpService,
private IConfig $config
diff --git a/lib/Controller/AssistantController.php b/lib/Controller/AssistantController.php
index 31553667..4162667d 100644
--- a/lib/Controller/AssistantController.php
+++ b/lib/Controller/AssistantController.php
@@ -1,9 +1,9 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
-namespace OCA\TPAssistant\Controller;
+namespace OCA\TpAssistant\Controller;
use Exception;
-use OCA\TPAssistant\Service\FreePrompt\FreePromptService;
+use OCA\TpAssistant\Service\FreePrompt\FreePromptService;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\Attribute\NoAdminRequired;
diff --git a/lib/Controller/Text2ImageController.php b/lib/Controller/Text2ImageController.php
index f1954c46..1f49f626 100644
--- a/lib/Controller/Text2ImageController.php
+++ b/lib/Controller/Text2ImageController.php
@@ -3,11 +3,11 @@
// SPDX-FileCopyrightText: Sami Finnilä
// SPDX-License-Identifier: AGPL-3.0-or-later
-namespace OCA\TPAssistant\Controller;
+namespace OCA\TpAssistant\Controller;
use Exception;
-use OCA\TPAssistant\AppInfo\Application;
-use OCA\TPAssistant\Service\Text2Image\Text2ImageHelperService;
+use OCA\TpAssistant\AppInfo\Application;
+use OCA\TpAssistant\Service\Text2Image\Text2ImageHelperService;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\Attribute\AnonRateLimit;
@@ -83,8 +83,8 @@ public function getImage(string $imageGenId, int $fileNameId): DataDisplayRespon
try {
$result = $this->text2ImageHelperService->getImage($imageGenId, $fileNameId);
} catch (Exception $e) {
- $response = new DataResponse(['error' => $e->getMessage()], $e->getCode());
- if ($e->getCode() === Http::STATUS_BAD_REQUEST | Http::STATUS_UNAUTHORIZED) {
+ $response = new DataResponse(['error' => $e->getMessage()], (int) $e->getCode());
+ if ($e->getCode() === Http::STATUS_BAD_REQUEST || $e->getCode() === Http::STATUS_UNAUTHORIZED) {
// Throttle brute force attempts
$response->throttle(['action' => 'imageGenId']);
}
@@ -114,8 +114,8 @@ public function getGenerationInfo(string $imageGenId): DataResponse {
try {
$result = $this->text2ImageHelperService->getGenerationInfo($imageGenId, true);
} catch (Exception $e) {
- $response = new DataResponse(['error' => $e->getMessage()], $e->getCode());
- if ($e->getCode() === Http::STATUS_BAD_REQUEST | Http::STATUS_UNAUTHORIZED) {
+ $response = new DataResponse(['error' => $e->getMessage()], (int) $e->getCode());
+ if ($e->getCode() === Http::STATUS_BAD_REQUEST || $e->getCode() === Http::STATUS_UNAUTHORIZED) {
// Throttle brute force attempts
$response->throttle(['action' => 'imageGenId']);
}
@@ -140,8 +140,8 @@ public function setVisibilityOfImageFiles(string $imageGenId, array $fileVisStat
try {
$this->text2ImageHelperService->setVisibilityOfImageFiles($imageGenId, $fileVisStatusArray);
} catch (Exception $e) {
- $response = new DataResponse(['error' => $e->getMessage()], $e->getCode());
- if($e->getCode() === Http::STATUS_BAD_REQUEST | Http::STATUS_UNAUTHORIZED) {
+ $response = new DataResponse(['error' => $e->getMessage()], (int) $e->getCode());
+ if($e->getCode() === Http::STATUS_BAD_REQUEST || $e->getCode() === Http::STATUS_UNAUTHORIZED) {
// Throttle brute force attempts
$response->throttle(['action' => 'imageGenId']);
}
diff --git a/lib/Cron/CleanupImageGenerations.php b/lib/Cron/CleanupImageGenerations.php
index ec15d76d..600b2465 100644
--- a/lib/Cron/CleanupImageGenerations.php
+++ b/lib/Cron/CleanupImageGenerations.php
@@ -4,11 +4,11 @@
// SPDX-FileCopyrightText: Sami Finnilä
// SPDX-License-Identifier: AGPL-3.0-or-later
-namespace OCA\TPAssistant\Cron;
+namespace OCA\TpAssistant\Cron;
use Exception;
-use OCA\TPAssistant\Db\Text2Image\ImageGenerationMapper;
-use OCA\TPAssistant\Service\Text2Image\CleanUpService;
+use OCA\TpAssistant\Db\Text2Image\ImageGenerationMapper;
+use OCA\TpAssistant\Service\Text2Image\CleanUpService;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\BackgroundJob\TimedJob;
use Psr\Log\LoggerInterface;
diff --git a/lib/Db/FreePrompt/Prompt.php b/lib/Db/FreePrompt/Prompt.php
index 360b5733..af2a6cdb 100644
--- a/lib/Db/FreePrompt/Prompt.php
+++ b/lib/Db/FreePrompt/Prompt.php
@@ -4,7 +4,7 @@
// SPDX-FileCopyrightText: Sami Finnilä
// SPDX-License-Identifier: AGPL-3.0-or-later
-namespace OCA\TPAssistant\Db\FreePrompt;
+namespace OCA\TpAssistant\Db\FreePrompt;
use OCP\AppFramework\Db\Entity;
diff --git a/lib/Db/FreePrompt/PromptMapper.php b/lib/Db/FreePrompt/PromptMapper.php
index 73aae1d6..c9a02fd3 100644
--- a/lib/Db/FreePrompt/PromptMapper.php
+++ b/lib/Db/FreePrompt/PromptMapper.php
@@ -5,10 +5,10 @@
declare(strict_types=1);
-namespace OCA\TPAssistant\Db\FreePrompt;
+namespace OCA\TpAssistant\Db\FreePrompt;
use DateTime;
-use OCA\TPAssistant\AppInfo\Application;
+use OCA\TpAssistant\AppInfo\Application;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\AppFramework\Db\MultipleObjectsReturnedException;
use OCP\AppFramework\Db\QBMapper;
@@ -17,7 +17,7 @@
use OCP\IDBConnection;
/**
- * @implements QBMapper
+ * @extends QBMapper
*/
class PromptMapper extends QBMapper {
public function __construct(IDBConnection $db) {
@@ -124,7 +124,7 @@ public function createPrompt(string $userId, string $value, ?int $timestamp = nu
if ($timestamp === null) {
$timestamp = (new DateTime())->getTimestamp();
}
-
+
try {
$prompt = $this->getPromptOfUserByValue($userId, $value);
$prompt->setTimestamp($timestamp);
diff --git a/lib/Db/Text2Image/ImageFileName.php b/lib/Db/Text2Image/ImageFileName.php
index 8ad10c11..e581524d 100644
--- a/lib/Db/Text2Image/ImageFileName.php
+++ b/lib/Db/Text2Image/ImageFileName.php
@@ -4,7 +4,7 @@
// SPDX-FileCopyrightText: Sami Finnilä
// SPDX-License-Identifier: AGPL-3.0-or-later
-namespace OCA\TPAssistant\Db\Text2Image;
+namespace OCA\TpAssistant\Db\Text2Image;
use OCP\AppFramework\Db\Entity;
diff --git a/lib/Db/Text2Image/ImageFileNameMapper.php b/lib/Db/Text2Image/ImageFileNameMapper.php
index acf670a0..89ab1bd6 100644
--- a/lib/Db/Text2Image/ImageFileNameMapper.php
+++ b/lib/Db/Text2Image/ImageFileNameMapper.php
@@ -4,9 +4,10 @@
// SPDX-FileCopyrightText: Sami Finnilä
// SPDX-License-Identifier: AGPL-3.0-or-later
-namespace OCA\TPAssistant\Db\Text2Image;
+namespace OCA\TpAssistant\Db\Text2Image;
use OCP\AppFramework\Db\DoesNotExistException;
+use OCP\AppFramework\Db\Entity;
use OCP\AppFramework\Db\MultipleObjectsReturnedException;
use OCP\AppFramework\Db\QBMapper;
use OCP\DB\Exception;
@@ -14,7 +15,7 @@
use OCP\IDBConnection;
/**
- * @implements QBMapper
+ * @extends QBMapper
*/
class ImageFileNameMapper extends QBMapper {
public function __construct(IDBConnection $db) {
@@ -81,11 +82,9 @@ public function setFileNameHidden(int $fileNameId, bool $hidden = true): int {
/**
* @param int $generationId
* @param int $fileNameId
- * @return ImageFileName|null
- *
+ * @return ImageFileName|Entity|null
*/
-
- public function getImageFileNameOfGenerationId(int $generationId, int $fileNameId): ImageFileName | null {
+ public function getImageFileNameOfGenerationId(int $generationId, int $fileNameId): ImageFileName|Entity|null {
$qb = $this->db->getQueryBuilder();
$qb->select('file_name')
@@ -106,21 +105,16 @@ public function getImageFileNameOfGenerationId(int $generationId, int $fileNameI
/**
* @param int $generationId
* @param string $fileName
- * @param string $prompt
- * @return ImageFileName
+ * @return ImageFileName|Entity
* @throws Exception
*/
- public function createImageFileName(int $generationId, string $fileName): ImageFileName {
+ public function createImageFileName(int $generationId, string $fileName): ImageFileName|Entity {
$imageFile = new ImageFileName();
$imageFile->setGenerationId($generationId);
$imageFile->setFileName($fileName);
return $this->insert($imageFile);
}
- /**
- *
- */
-
/**
* @param int $generationId
* @return void
diff --git a/lib/Db/Text2Image/ImageGeneration.php b/lib/Db/Text2Image/ImageGeneration.php
index b3b824b7..59e06707 100644
--- a/lib/Db/Text2Image/ImageGeneration.php
+++ b/lib/Db/Text2Image/ImageGeneration.php
@@ -4,7 +4,7 @@
// SPDX-FileCopyrightText: Sami Finnilä
// SPDX-License-Identifier: AGPL-3.0-or-later
-namespace OCA\TPAssistant\Db\Text2Image;
+namespace OCA\TpAssistant\Db\Text2Image;
use OCP\AppFramework\Db\Entity;
diff --git a/lib/Db/Text2Image/ImageGenerationMapper.php b/lib/Db/Text2Image/ImageGenerationMapper.php
index 5f030b8d..477a508a 100644
--- a/lib/Db/Text2Image/ImageGenerationMapper.php
+++ b/lib/Db/Text2Image/ImageGenerationMapper.php
@@ -4,11 +4,12 @@
// SPDX-FileCopyrightText: Sami Finnilä
// SPDX-License-Identifier: AGPL-3.0-or-later
-namespace OCA\TPAssistant\Db\Text2Image;
+namespace OCA\TpAssistant\Db\Text2Image;
use DateTime;
-use OCA\TPAssistant\AppInfo\Application;
+use OCA\TpAssistant\AppInfo\Application;
use OCP\AppFramework\Db\DoesNotExistException;
+use OCP\AppFramework\Db\Entity;
use OCP\AppFramework\Db\MultipleObjectsReturnedException;
use OCP\AppFramework\Db\QBMapper;
use OCP\DB\Exception;
@@ -16,7 +17,7 @@
use OCP\IDBConnection;
/**
- * @implements QBMapper
+ * @extends QBMapper
*/
class ImageGenerationMapper extends QBMapper {
public function __construct(
@@ -29,13 +30,12 @@ public function __construct(
/**
* @param string $imageGenId
- * @param int $fileNameId
- * @return ImageGeneration
- * @throws Exception
+ * @return ImageGeneration|Entity
* @throws DoesNotExistException
+ * @throws Exception
* @throws MultipleObjectsReturnedException
*/
- public function getImageGenerationOfImageGenId(string $imageGenId): ImageGeneration {
+ public function getImageGenerationOfImageGenId(string $imageGenId): ImageGeneration|Entity {
$qb = $this->db->getQueryBuilder();
$qb->select('*')
@@ -52,10 +52,10 @@ public function getImageGenerationOfImageGenId(string $imageGenId): ImageGenerat
* @param string $prompt
* @param string $userId
* @param int|null $expCompletionTime
- * @return ImageGeneration
+ * @return ImageGeneration|Entity
* @throws Exception
*/
- public function createImageGeneration(string $imageGenId, string $prompt = '', string $userId = '', ?int $expCompletionTime = null): ImageGeneration {
+ public function createImageGeneration(string $imageGenId, string $prompt = '', string $userId = '', ?int $expCompletionTime = null): ImageGeneration|Entity {
$imageGeneration = new ImageGeneration();
$imageGeneration->setImageGenId($imageGenId);
$imageGeneration->setTimestamp((new DateTime())->getTimestamp());
@@ -171,7 +171,7 @@ public function setNotifyReady(string $imageGenId, bool $notifyReady): int {
/**
* @param int $maxAge
- * @return array('deleted_generations' => int, 'file_names' => string[])
+ * @return array ('deleted_generations' => int, 'file_names' => string[])
* @throws Exception
* @throws \RuntimeException
*/
diff --git a/lib/Db/Text2Image/Prompt.php b/lib/Db/Text2Image/Prompt.php
index 0b6b2275..b1f780ec 100644
--- a/lib/Db/Text2Image/Prompt.php
+++ b/lib/Db/Text2Image/Prompt.php
@@ -4,7 +4,7 @@
// SPDX-FileCopyrightText: Sami Finnilä
// SPDX-License-Identifier: AGPL-3.0-or-later
-namespace OCA\TPAssistant\Db\Text2Image;
+namespace OCA\TpAssistant\Db\Text2Image;
use OCP\AppFramework\Db\Entity;
diff --git a/lib/Db/Text2Image/PromptMapper.php b/lib/Db/Text2Image/PromptMapper.php
index abb3afa9..141bee99 100644
--- a/lib/Db/Text2Image/PromptMapper.php
+++ b/lib/Db/Text2Image/PromptMapper.php
@@ -6,10 +6,10 @@
declare(strict_types=1);
-namespace OCA\TPAssistant\Db\Text2Image;
+namespace OCA\TpAssistant\Db\Text2Image;
use DateTime;
-use OCA\TPAssistant\AppInfo\Application;
+use OCA\TpAssistant\AppInfo\Application;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\AppFramework\Db\Entity;
use OCP\AppFramework\Db\MultipleObjectsReturnedException;
@@ -19,7 +19,7 @@
use OCP\IDBConnection;
/**
- * @implements QBMapper
+ * @extends QBMapper
*/
class PromptMapper extends QBMapper {
public function __construct(IDBConnection $db) {
@@ -28,12 +28,12 @@ public function __construct(IDBConnection $db) {
/**
* @param int $id
- * @return Prompt | Entity
+ * @return Prompt|Entity
* @throws DoesNotExistException
* @throws Exception
* @throws MultipleObjectsReturnedException
*/
- public function getPrompt(int $id): Prompt | Entity {
+ public function getPrompt(int $id): Prompt|Entity {
$qb = $this->db->getQueryBuilder();
$qb->select('*')
@@ -48,12 +48,12 @@ public function getPrompt(int $id): Prompt | Entity {
/**
* @param int $id
* @param string $userId
- * @return Prompt
+ * @return Prompt|Entity
* @throws DoesNotExistException
* @throws Exception
* @throws MultipleObjectsReturnedException
*/
- public function getPromptOfUser(int $id, string $userId): Prompt {
+ public function getPromptOfUser(int $id, string $userId): Prompt|Entity {
$qb = $this->db->getQueryBuilder();
$qb->select('*')
@@ -71,12 +71,12 @@ public function getPromptOfUser(int $id, string $userId): Prompt {
/**
* @param string $userId
* @param string $value
- * @return Prompt
+ * @return Prompt|Entity
* @throws DoesNotExistException
* @throws Exception
* @throws MultipleObjectsReturnedException
*/
- public function getPromptOfUserByValue(string $userId, string $value): Prompt {
+ public function getPromptOfUserByValue(string $userId, string $value): Prompt|Entity {
$qb = $this->db->getQueryBuilder();
$qb->select('*')
@@ -115,11 +115,12 @@ public function getPromptsOfUser(string $userId): array {
* @param string $userId
* @param string $value
* @param int|null $timestamp
- * @return Prompt
+ * @return Prompt|Entity
* @throws Exception
*/
- public function createPrompt(string $userId, string $value, ?int $timestamp = null): Prompt {
+ public function createPrompt(string $userId, string $value, ?int $timestamp = null): Prompt|Entity {
try {
+ /** @var Prompt $prompt */
$prompt = $this->getPromptOfUserByValue($userId, $value);
$ts = (new DateTime())->getTimestamp();
$prompt->setTimestamp($ts);
diff --git a/lib/Db/Text2Image/StaleGeneration.php b/lib/Db/Text2Image/StaleGeneration.php
index 09e3c6b9..1f0a835d 100644
--- a/lib/Db/Text2Image/StaleGeneration.php
+++ b/lib/Db/Text2Image/StaleGeneration.php
@@ -4,7 +4,7 @@
// SPDX-FileCopyrightText: Sami Finnilä
// SPDX-License-Identifier: AGPL-3.0-or-later
-namespace OCA\TPAssistant\Db\Text2Image;
+namespace OCA\TpAssistant\Db\Text2Image;
use OCP\AppFramework\Db\Entity;
diff --git a/lib/Db/Text2Image/StaleGenerationMapper.php b/lib/Db/Text2Image/StaleGenerationMapper.php
index 40d426c0..fece0816 100644
--- a/lib/Db/Text2Image/StaleGenerationMapper.php
+++ b/lib/Db/Text2Image/StaleGenerationMapper.php
@@ -5,9 +5,10 @@
declare(strict_types=1);
-namespace OCA\TPAssistant\Db\Text2Image;
+namespace OCA\TpAssistant\Db\Text2Image;
use OCP\AppFramework\Db\DoesNotExistException;
+use OCP\AppFramework\Db\Entity;
use OCP\AppFramework\Db\MultipleObjectsReturnedException;
use OCP\AppFramework\Db\QBMapper;
use OCP\DB\Exception;
@@ -16,7 +17,7 @@
use RuntimeException;
/**
- * @implements QBMapper
+ * @extends QBMapper
*/
class StaleGenerationMapper extends QBMapper {
public function __construct(IDBConnection $db) {
@@ -25,12 +26,12 @@ public function __construct(IDBConnection $db) {
/**
* @param int $id
- * @return StaleGeneration
+ * @return StaleGeneration|Entity
* @throws DoesNotExistException
* @throws Exception
* @throws MultipleObjectsReturnedException
*/
- public function getStaleGeneration(int $id): StaleGeneration {
+ public function getStaleGeneration(int $id): StaleGeneration|Entity {
$qb = $this->db->getQueryBuilder();
$qb->select('*')
@@ -84,15 +85,13 @@ public function genIdExists(string $imageGenId): bool {
/**
* @param string $imageGenId
- * @return StaleGeneration
+ * @return StaleGeneration|Entity inserted StaleGeneration
* @throws Exception
*/
- public function createStaleGeneration(string $imageGenId): StaleGeneration {
+ public function createStaleGeneration(string $imageGenId): StaleGeneration|Entity {
$staleGen = new StaleGeneration();
$staleGen->setImageGenId($imageGenId);
- $insertedStaleGeneration = $this->insert($staleGen);
-
- return $insertedStaleGeneration;
+ return $this->insert($staleGen);
}
}
diff --git a/lib/Event/BeforeAssistantNotificationEvent.php b/lib/Event/BeforeAssistantNotificationEvent.php
index 30d91d4b..afa8aed6 100644
--- a/lib/Event/BeforeAssistantNotificationEvent.php
+++ b/lib/Event/BeforeAssistantNotificationEvent.php
@@ -2,7 +2,7 @@
declare(strict_types=1);
-namespace OCA\TPAssistant\Event;
+namespace OCA\TpAssistant\Event;
use OCP\EventDispatcher\Event;
use OCP\TextProcessing\Task;
diff --git a/lib/Listener/BeforeTemplateRenderedListener.php b/lib/Listener/BeforeTemplateRenderedListener.php
index 8f430c6c..c2da303d 100644
--- a/lib/Listener/BeforeTemplateRenderedListener.php
+++ b/lib/Listener/BeforeTemplateRenderedListener.php
@@ -2,9 +2,9 @@
declare(strict_types=1);
-namespace OCA\TPAssistant\Listener;
+namespace OCA\TpAssistant\Listener;
-use OCA\TPAssistant\AppInfo\Application;
+use OCA\TpAssistant\AppInfo\Application;
use OCP\AppFramework\Http\Events\BeforeTemplateRenderedEvent;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\AppFramework\Services\IInitialState;
@@ -16,6 +16,9 @@
use OCP\TextProcessing\IManager as ITextProcessingManager;
use OCP\Util;
+/**
+ * @template-implements IEventListener
+ */
class BeforeTemplateRenderedListener implements IEventListener {
public function __construct(
diff --git a/lib/Listener/FreePrompt/FreePromptReferenceListener.php b/lib/Listener/FreePrompt/FreePromptReferenceListener.php
index 1ff9be33..3c80572e 100644
--- a/lib/Listener/FreePrompt/FreePromptReferenceListener.php
+++ b/lib/Listener/FreePrompt/FreePromptReferenceListener.php
@@ -3,30 +3,23 @@
// SPDX-FileCopyrightText: Sami Finnilä
// SPDX-License-Identifier: AGPL-3.0-or-later
-namespace OCA\TPAssistant\Listener\FreePrompt;
+namespace OCA\TpAssistant\Listener\FreePrompt;
-use OCA\TPAssistant\AppInfo\Application;
-use OCP\AppFramework\Services\IInitialState;
+use OCA\TpAssistant\AppInfo\Application;
use OCP\Collaboration\Reference\RenderReferenceEvent;
use OCP\EventDispatcher\Event;
use OCP\EventDispatcher\IEventListener;
use OCP\IConfig;
-use OCP\IGroupManager;
use OCP\TextProcessing\IManager;
use OCP\Util;
-use Psr\Log\LoggerInterface;
-
/**
* @implements IEventListener
*/
class FreePromptReferenceListener implements IEventListener {
public function __construct(
private IConfig $config,
- private IInitialState $initialState,
private ?string $userId,
- private LoggerInterface $logger,
- private IGroupManager $iGroupManager,
private IManager $textProcessingManager,
) {
@@ -40,8 +33,8 @@ public function handle(Event $event): void {
if ($this->config->getAppValue(Application::APP_ID, 'free_prompt_picker_enabled', '1') === '1' &&
$this->config->getUserValue($this->userId, Application::APP_ID, 'free_prompt_picker_enabled', '1') === '1') {
-
- // Double check that atleast one provider is registered
+
+ // Double check that at least one provider is registered
if ($this->textProcessingManager->hasProviders()) {
Util::addScript(Application::APP_ID, Application::APP_ID . '-textGenerationReference');
}
diff --git a/lib/Listener/TaskFailedListener.php b/lib/Listener/TaskFailedListener.php
index 657302be..5eb10980 100644
--- a/lib/Listener/TaskFailedListener.php
+++ b/lib/Listener/TaskFailedListener.php
@@ -1,15 +1,18 @@
+ */
class TaskFailedListener implements IEventListener {
public function __construct(
diff --git a/lib/Listener/TaskSuccessfulListener.php b/lib/Listener/TaskSuccessfulListener.php
index ce2a9a7f..ecbe1203 100644
--- a/lib/Listener/TaskSuccessfulListener.php
+++ b/lib/Listener/TaskSuccessfulListener.php
@@ -1,15 +1,18 @@
+ */
class TaskSuccessfulListener implements IEventListener {
public function __construct(
diff --git a/lib/Listener/Text2Image/Text2ImageReferenceListener.php b/lib/Listener/Text2Image/Text2ImageReferenceListener.php
index b99d99d8..acc03807 100644
--- a/lib/Listener/Text2Image/Text2ImageReferenceListener.php
+++ b/lib/Listener/Text2Image/Text2ImageReferenceListener.php
@@ -3,10 +3,9 @@
// SPDX-FileCopyrightText: Sami Finnilä
// SPDX-License-Identifier: AGPL-3.0-or-later
-namespace OCA\TPAssistant\Listener\Text2Image;
+namespace OCA\TpAssistant\Listener\Text2Image;
-use OCA\TPAssistant\AppInfo\Application;
-use OCP\AppFramework\Services\IInitialState;
+use OCA\TpAssistant\AppInfo\Application;
use OCP\Collaboration\Reference\RenderReferenceEvent;
use OCP\EventDispatcher\Event;
use OCP\EventDispatcher\IEventListener;
@@ -14,10 +13,12 @@
use OCP\TextToImage\IManager;
use OCP\Util;
+/**
+ * @template-implements IEventListener
+ */
class Text2ImageReferenceListener implements IEventListener {
public function __construct(
private IConfig $config,
- private IInitialState $initialState,
private ?string $userId,
private IManager $manager
) {
diff --git a/lib/Listener/Text2Image/Text2ImageResultListener.php b/lib/Listener/Text2Image/Text2ImageResultListener.php
index 16cc07ae..b831a433 100644
--- a/lib/Listener/Text2Image/Text2ImageResultListener.php
+++ b/lib/Listener/Text2Image/Text2ImageResultListener.php
@@ -1,11 +1,12 @@
+ */
class Text2ImageResultListener implements IEventListener {
- /**
- * Constructor
- * @param Text2ImageHelperService $text2ImageService
- * @param ImageGenerationMapper $imageGenerationMapper
- * @param LoggerInterface $logger
- * @param AssistantService $assistantService
- * @param IURLGenerator $urlGenerator
- */
+
public function __construct(
private Text2ImageHelperService $text2ImageService,
private ImageGenerationMapper $imageGenerationMapper,
@@ -74,13 +71,15 @@ public function handle(Event $event): void {
if ($event instanceof TaskFailedEvent) {
$this->logger->warning('Image generation task failed: ' . $imageGenId);
$this->imageGenerationMapper->setFailed($imageGenId, true);
-
+
$this->assistantService->sendNotification($event->getTask());
}
// Only send the notification if the user enabled them for this task:
try {
- if($this->imageGenerationMapper->getImageGenerationOfImageGenId($imageGenId)->getNotifyReady()) {
+ /** @var ImageGeneration $imageGeneration */
+ $imageGeneration = $this->imageGenerationMapper->getImageGenerationOfImageGenId($imageGenId);
+ if ($imageGeneration->getNotifyReady()) {
$this->assistantService->sendNotification($event->getTask(), $link);
}
} catch (\OCP\Db\Exception | DoesNotExistException | MultipleObjectsReturnedException $e) {
diff --git a/lib/Migration/Version010003Date20231208083112.php b/lib/Migration/Version010003Date20231208083112.php
index 10e5a2e8..d5607525 100644
--- a/lib/Migration/Version010003Date20231208083112.php
+++ b/lib/Migration/Version010003Date20231208083112.php
@@ -5,7 +5,7 @@
declare(strict_types=1);
-namespace OCA\TPAssistant\Migration;
+namespace OCA\TpAssistant\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
diff --git a/lib/Notification/Notifier.php b/lib/Notification/Notifier.php
index 1582c523..66f5928f 100644
--- a/lib/Notification/Notifier.php
+++ b/lib/Notification/Notifier.php
@@ -1,9 +1,9 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
-namespace OCA\TPAssistant\Reference;
+namespace OCA\TpAssistant\Reference;
-use OC\Collaboration\Reference\ReferenceManager;
-use OCA\TPAssistant\AppInfo\Application;
-use OCA\TPAssistant\Service\FreePrompt\FreePromptService;
+use OCA\TpAssistant\AppInfo\Application;
use OCP\Collaboration\Reference\ADiscoverableReferenceProvider;
use OCP\Collaboration\Reference\IReference;
+use OCP\Collaboration\Reference\IReferenceManager;
use OCP\IL10N;
use OCP\IURLGenerator;
@@ -17,8 +16,7 @@ class FreePromptReferenceProvider extends ADiscoverableReferenceProvider {
public function __construct(
private IL10N $l10n,
private IURLGenerator $urlGenerator,
- private ReferenceManager $referenceManager,
- private FreePromptService $freePromptService,
+ private IReferenceManager $referenceManager,
private ?string $userId
) {
}
diff --git a/lib/Reference/Text2ImageReferenceProvider.php b/lib/Reference/Text2ImageReferenceProvider.php
index 5be32355..12353be5 100644
--- a/lib/Reference/Text2ImageReferenceProvider.php
+++ b/lib/Reference/Text2ImageReferenceProvider.php
@@ -3,15 +3,15 @@
// SPDX-FileCopyrightText: Sami Finnilä
// SPDX-License-Identifier: AGPL-3.0-or-later
-namespace OCA\TPAssistant\Reference;
+namespace OCA\TpAssistant\Reference;
use Exception;
-use OC\Collaboration\Reference\ReferenceManager;
-use OCA\TPAssistant\AppInfo\Application;
-use OCA\TPAssistant\Db\Text2Image\ImageGenerationMapper;
-use OCA\TPAssistant\Service\Text2Image\Text2ImageHelperService;
+use OCA\TpAssistant\AppInfo\Application;
+use OCA\TpAssistant\Db\Text2Image\ImageGeneration;
+use OCA\TpAssistant\Db\Text2Image\ImageGenerationMapper;
use OCP\Collaboration\Reference\ADiscoverableReferenceProvider;
use OCP\Collaboration\Reference\IReference;
+use OCP\Collaboration\Reference\IReferenceManager;
use OCP\Collaboration\Reference\Reference;
use OCP\IL10N;
use OCP\IURLGenerator;
@@ -22,8 +22,7 @@ class Text2ImageReferenceProvider extends ADiscoverableReferenceProvider {
public function __construct(
private IL10N $l10n,
private IURLGenerator $urlGenerator,
- private ReferenceManager $referenceManager,
- private Text2ImageHelperService $text2ImageHelperService,
+ private IReferenceManager $referenceManager,
private ImageGenerationMapper $imageGenerationMapper,
private ?string $userId
) {
@@ -75,6 +74,7 @@ public function resolveReference(string $referenceText): ?IReference {
}
try {
+ /** @var ImageGeneration $imageGeneration */
$imageGeneration = $this->imageGenerationMapper->getImageGenerationOfImageGenId($imageGenId);
} catch (Exception $e) {
$imageGeneration = null;
diff --git a/lib/Service/AssistantService.php b/lib/Service/AssistantService.php
index 3ef5aae3..dc84d523 100644
--- a/lib/Service/AssistantService.php
+++ b/lib/Service/AssistantService.php
@@ -1,9 +1,9 @@
setApp(Application::APP_ID)
->setUser($task->getUserId())
->setDateTime(new DateTime())
- ->setObject($objectType, $task->getId())
+ ->setObject($objectType, (string) ($task->getId() ?? 0))
->setSubject($subject, $params);
$manager->notify($notification);
diff --git a/lib/Service/FreePrompt/FreePromptService.php b/lib/Service/FreePrompt/FreePromptService.php
index dce67d3a..fec5bdae 100644
--- a/lib/Service/FreePrompt/FreePromptService.php
+++ b/lib/Service/FreePrompt/FreePromptService.php
@@ -3,11 +3,11 @@
// SPDX-FileCopyrightText: Sami Finnilä
// SPDX-License-Identifier: AGPL-3.0-or-later
-namespace OCA\TPAssistant\Service\FreePrompt;
+namespace OCA\TpAssistant\Service\FreePrompt;
use Exception;
-use OCA\TPAssistant\AppInfo\Application;
-use OCA\TPAssistant\Db\FreePrompt\PromptMapper;
+use OCA\TpAssistant\AppInfo\Application;
+use OCA\TpAssistant\Db\FreePrompt\PromptMapper;
use OCP\AppFramework\Http;
use OCP\DB\Exception as DBException;
use OCP\IConfig;
diff --git a/lib/Service/Text2Image/CleanUpService.php b/lib/Service/Text2Image/CleanUpService.php
index 6c47c887..c54b1d63 100644
--- a/lib/Service/Text2Image/CleanUpService.php
+++ b/lib/Service/Text2Image/CleanUpService.php
@@ -3,11 +3,11 @@
// SPDX-FileCopyrightText: Sami Finnilä
// SPDX-License-Identifier: AGPL-3.0-or-later
-namespace OCA\TPAssistant\Service\Text2Image;
+namespace OCA\TpAssistant\Service\Text2Image;
use Exception;
-use OCA\TPAssistant\AppInfo\Application;
-use OCA\TPAssistant\Db\Text2Image\ImageGenerationMapper;
+use OCA\TpAssistant\AppInfo\Application;
+use OCA\TpAssistant\Db\Text2Image\ImageGenerationMapper;
use OCP\Files\IAppData;
use OCP\Files\NotFoundException;
use OCP\Files\NotPermittedException;
@@ -31,7 +31,7 @@ public function __construct(
/**
* @param int|null $maxAge
- * @return array('deleted_files' => int, 'file_deletion_errors' => int, 'deleted_generations' => int)
+ * @return array ('deleted_files' => int, 'file_deletion_errors' => int, 'deleted_generations' => int)
* @throws Exception
*/
public function cleanupGenerationsAndFiles(?int $maxAge = null): array {
diff --git a/lib/Service/Text2Image/Text2ImageHelperService.php b/lib/Service/Text2Image/Text2ImageHelperService.php
index f1370241..17118227 100644
--- a/lib/Service/Text2Image/Text2ImageHelperService.php
+++ b/lib/Service/Text2Image/Text2ImageHelperService.php
@@ -3,18 +3,20 @@
// SPDX-FileCopyrightText: Sami Finnilä
// SPDX-License-Identifier: AGPL-3.0-or-later
-namespace OCA\TPAssistant\Service\Text2Image;
+namespace OCA\TpAssistant\Service\Text2Image;
use DateTime;
use Exception as BaseException;
use GdImage;
-use OCA\TPAssistant\AppInfo\Application;
-use OCA\TPAssistant\Db\Text2Image\ImageFileNameMapper;
-use OCA\TPAssistant\Db\Text2Image\ImageGenerationMapper;
-use OCA\TPAssistant\Db\Text2Image\PromptMapper;
-use OCA\TPAssistant\Db\Text2Image\StaleGenerationMapper;
-use OCA\TPAssistant\Service\AssistantService;
+use OCA\TpAssistant\AppInfo\Application;
+use OCA\TpAssistant\Db\Text2Image\ImageFileName;
+use OCA\TpAssistant\Db\Text2Image\ImageFileNameMapper;
+use OCA\TpAssistant\Db\Text2Image\ImageGeneration;
+use OCA\TpAssistant\Db\Text2Image\ImageGenerationMapper;
+use OCA\TpAssistant\Db\Text2Image\PromptMapper;
+use OCA\TpAssistant\Db\Text2Image\StaleGenerationMapper;
+use OCA\TpAssistant\Service\AssistantService;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\AppFramework\Db\MultipleObjectsReturnedException;
@@ -24,37 +26,22 @@
use OCP\Files\NotFoundException;
use OCP\Files\NotPermittedException;
use OCP\Files\SimpleFS\ISimpleFolder;
-use OCP\IConfig;
use OCP\IImage;
use OCP\IL10N;
use OCP\IURLGenerator;
+use OCP\PreConditionNotMetException;
+use OCP\TextToImage\Exception\TaskFailureException;
use OCP\TextToImage\IManager;
use OCP\TextToImage\Task;
use Psr\Log\LoggerInterface;
+use Random\RandomException;
use RuntimeException;
class Text2ImageHelperService {
- /**
- * @var ISimpleFolder|null
- */
+
private ?ISimpleFolder $imageDataFolder = null;
- /**
- * @param IConfig $config
- * @param LoggerInterface $logger
- * @param IManager $textToImageManager
- * @param string|null $userId
- * @param PromptMapper $promptMapper
- * @param ImageGenerationMapper $imageGenerationMapper
- * @param ImageFileNameMapper $imageFileNameMapper
- * @param StaleGenerationMapper $staleGenerationMapper
- * @param IAppData $appData
- * @param IURLGenerator $urlGenerator
- * @param IL10N $l10n
- * @param AssistantService $assistantService
- */
public function __construct(
- private IConfig $config,
private LoggerInterface $logger,
private IManager $textToImageManager,
private ?string $userId,
@@ -74,10 +61,12 @@ public function __construct(
*
* @param string $prompt
* @param int $nResults
- * @param bool $storePrompt
+ * @param bool $displayPrompt
* @return array
- * @throws \Exception
- * @throws \OCP\TextToImage\Exception\TaskFailureException;
+ * @throws Exception
+ * @throws PreConditionNotMetException
+ * @throws TaskFailureException ;
+ * @throws RandomException
*/
public function processPrompt(string $prompt, int $nResults, bool $displayPrompt): array {
if (!$this->textToImageManager->hasProviders()) {
@@ -95,7 +84,7 @@ public function processPrompt(string $prompt, int $nResults, bool $displayPrompt
$promptTask = new Task($prompt, Application::APP_ID, $nResults, $this->userId, $imageGenId);
$this->textToImageManager->runOrScheduleTask($promptTask);
-
+
$taskExecuted = false;
/** @var IImage[]|null $images */
@@ -260,7 +249,7 @@ public function notifyUser(string $imageGenId): void {
$this->logger->debug('Task for the given generation id does not exist or could not be retrieved: ' . $e->getMessage(), ['app' => Application::APP_ID]);
return;
}
-
+
// Generate the link:
$link = $this->urlGenerator->linkToRouteAbsolute(
Application::APP_ID . '.Text2Image.showGenerationPage',
@@ -295,7 +284,7 @@ public function getImageDataFolder(): ISimpleFolder {
} catch (NotPermittedException | RuntimeException $e) {
$this->logger->debug('Image data folder could not be created: '
. $e->getMessage(), ['app' => Application::APP_ID]);
- throw new Exception('Image data folder could not be created: ' . $e->getMessage());
+ throw new \Exception('Image data folder could not be created: ' . $e->getMessage());
}
}
}
@@ -313,6 +302,7 @@ public function getImageDataFolder(): ISimpleFolder {
public function getGenerationInfo(string $imageGenId, bool $updateTimestamp = true): array {
// Check whether the task has completed:
try {
+ /** @var ImageGeneration $imageGeneration */
$imageGeneration = $this->imageGenerationMapper->getImageGenerationOfImageGenId($imageGenId);
} catch (DoesNotExistException $e) {
try {
@@ -380,12 +370,13 @@ public function getGenerationInfo(string $imageGenId, bool $updateTimestamp = tr
* Get image based on imageFileNameId (imageGenId is used to prevent guessing image ids)
* @param string $imageGenId
* @param int $imageFileNameId
- * @return array('image' => string, 'content-type' => string)
+ * @return array ('image' => string, 'content-type' => string)
* @throws BaseException
*/
public function getImage(string $imageGenId, int $imageFileNameId): ?array {
try {
$generationId = $this->imageGenerationMapper->getImageGenerationOfImageGenId($imageGenId)->getId();
+ /** @var ImageFileName $imageFileName */
$imageFileName = $this->imageFileNameMapper->getImageFileNameOfGenerationId($generationId, $imageFileNameId);
} catch (Exception | DoesNotExistException | MultipleObjectsReturnedException $e) {
$this->logger->debug('Image request error : ' . $e->getMessage(), ['app' => Application::APP_ID]);
@@ -425,6 +416,7 @@ public function getImage(string $imageGenId, int $imageFileNameId): ?array {
*/
public function cancelGeneration(string $imageGenId): void {
try {
+ /** @var ImageGeneration $imageGeneration */
$imageGeneration = $this->imageGenerationMapper->getImageGenerationOfImageGenId($imageGenId);
} catch (Exception | DoesNotExistException | MultipleObjectsReturnedException $e) {
$this->logger->warning('Image generation being deleted not in db: ' . $e->getMessage(), ['app' => Application::APP_ID]);
@@ -502,6 +494,7 @@ public function cancelGeneration(string $imageGenId): void {
*/
public function setVisibilityOfImageFiles(string $imageGenId, array $fileVisSatusArray): void {
try {
+ /** @var ImageGeneration $imageGeneration */
$imageGeneration = $this->imageGenerationMapper->getImageGenerationOfImageGenId($imageGenId);
} catch (DoesNotExistException $e) {
$this->logger->debug('Image request error : ' . $e->getMessage());
@@ -532,6 +525,7 @@ public function setVisibilityOfImageFiles(string $imageGenId, array $fileVisSatu
*/
public function notifyWhenReady(string $imageGenId): void {
try {
+ /** @var ImageGeneration $imageGeneration */
$imageGeneration = $this->imageGenerationMapper->getImageGenerationOfImageGenId($imageGenId);
} catch (DoesNotExistException $e) {
$this->logger->debug('Image request error : ' . $e->getMessage());
diff --git a/lib/Settings/Admin.php b/lib/Settings/Admin.php
index 5925c63a..0279d50d 100644
--- a/lib/Settings/Admin.php
+++ b/lib/Settings/Admin.php
@@ -1,8 +1,8 @@
config->getAppValue(Application::APP_ID, 'assistant_enabled', '1') === '1';
$textToImagePickerAvailable = $this->textToImageManager->hasProviders();
$textToImagePickerEnabled = $this->config->getAppValue(Application::APP_ID, 'text_to_image_picker_enabled', '1') === '1';
- $maxImageGenerationIdleTime = $this->config->getAppValue(Application::APP_ID, 'max_image_generation_idle_time', Application::DEFAULT_MAX_IMAGE_GENERATION_IDLE_TIME);
+ $maxImageGenerationIdleTime = (int) $this->config->getAppValue(Application::APP_ID, 'max_image_generation_idle_time', (string) Application::DEFAULT_MAX_IMAGE_GENERATION_IDLE_TIME);
$freePromptPickerEnabled = $this->config->getAppValue(Application::APP_ID, 'free_prompt_picker_enabled', '1') === '1';
$adminConfig = [
diff --git a/lib/Settings/Personal.php b/lib/Settings/Personal.php
index 2207bf04..1e8cf27f 100644
--- a/lib/Settings/Personal.php
+++ b/lib/Settings/Personal.php
@@ -1,8 +1,8 @@
urlGenerator->imagePath('settings', 'ai.svg');
}
diff --git a/psalm.xml b/psalm.xml
new file mode 100644
index 00000000..ad581540
--- /dev/null
+++ b/psalm.xml
@@ -0,0 +1,93 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assistant.js b/src/assistant.js
index ba68bcf3..7b4b0b21 100644
--- a/src/assistant.js
+++ b/src/assistant.js
@@ -7,7 +7,7 @@ __webpack_public_path__ = linkTo('assistant', 'js/') // eslint-disable-line
/**
* Creates an assistant modal and return a promise which provides the result
*
- * OCA.TPAssistant.openAssistantForm({
+ * OCA.TpAssistant.openAssistantForm({
* appId: 'my_app_id',
* identifier: 'my task identifier',
* taskType: 'OCP\\TextProcessing\\FreePromptTaskType',
diff --git a/src/main.js b/src/main.js
index ccc03ddf..44f8b551 100644
--- a/src/main.js
+++ b/src/main.js
@@ -3,16 +3,16 @@ import { subscribe } from '@nextcloud/event-bus'
import { loadState } from '@nextcloud/initial-state'
/**
- * - Expose OCA.TPAssistant.openTextProcessingModal to let apps use the assistant
+ * - Expose OCA.TpAssistant.openTextProcessingModal to let apps use the assistant
* - Add a header right menu entry
* - Listen to notification event
*/
function init() {
- if (!OCA.TPAssistant) {
+ if (!OCA.TpAssistant) {
/**
* @namespace
*/
- OCA.TPAssistant = {
+ OCA.TpAssistant = {
openAssistantForm,
openAssistantResult,
}
diff --git a/templates/adminSettings.php b/templates/adminSettings.php
index bc61638d..7bd7b0d9 100644
--- a/templates/adminSettings.php
+++ b/templates/adminSettings.php
@@ -1,5 +1,5 @@
diff --git a/templates/imageGenerationPage.php b/templates/imageGenerationPage.php
index 70f5340c..70392b4b 100644
--- a/templates/imageGenerationPage.php
+++ b/templates/imageGenerationPage.php
@@ -1,9 +1,9 @@
-
\ No newline at end of file
+
diff --git a/templates/personalSettings.php b/templates/personalSettings.php
index 11a15da1..900212d2 100644
--- a/templates/personalSettings.php
+++ b/templates/personalSettings.php
@@ -1,5 +1,5 @@
diff --git a/templates/taskResultPage.php b/templates/taskResultPage.php
index e64b076a..c155548f 100644
--- a/templates/taskResultPage.php
+++ b/templates/taskResultPage.php
@@ -1,4 +1,4 @@
get(IAppManager::class)->loadApp(Application::APP_ID);
diff --git a/tests/psalm-baseline.xml b/tests/psalm-baseline.xml
new file mode 100644
index 00000000..5a9a7d82
--- /dev/null
+++ b/tests/psalm-baseline.xml
@@ -0,0 +1,3 @@
+
+
+
diff --git a/tests/stubs/oc_core_command_base.php b/tests/stubs/oc_core_command_base.php
new file mode 100644
index 00000000..bbae1a65
--- /dev/null
+++ b/tests/stubs/oc_core_command_base.php
@@ -0,0 +1,63 @@
+