From ab160495edcf6247fc5efff142f2cc2c178649e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joris=20Dugu=C3=A9?= Date: Mon, 29 Jan 2024 18:34:27 +0100 Subject: [PATCH 1/4] feat(chore): implement usage without user --- Core/H5PSymfony.php | 23 ++++++++++++++--------- composer.json | 2 +- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/Core/H5PSymfony.php b/Core/H5PSymfony.php index 8c63c9a..b99d42d 100644 --- a/Core/H5PSymfony.php +++ b/Core/H5PSymfony.php @@ -2,6 +2,7 @@ namespace Studit\H5PBundle\Core; +use DateTime; use DateTimeInterface; use Doctrine\DBAL\Exception; use Doctrine\ORM\EntityManagerInterface; @@ -35,7 +36,6 @@ use Doctrine\DBAL\Exception\ConnectionException; use Doctrine\DBAL\Exception\TableNotFoundException; use Doctrine\DBAL\Exception\UniqueConstraintViolationException; -use Symfony\Component\Serializer\Normalizer\JsonSerializableNormalizer; class H5PSymfony implements \H5PFrameworkInterface { @@ -1088,8 +1088,8 @@ public function replaceContentTypeCache($contentTypeCache): void { $this->truncateTable(LibrariesHubCache::class); foreach ($contentTypeCache->contentTypes as $ct) { - $created_at = new \DateTime($ct->createdAt); - $updated_at = new \DateTime($ct->updatedAt); + $created_at = new DateTime($ct->createdAt); + $updated_at = new DateTime($ct->updatedAt); $cache = new LibrariesHubCache(); $cache->setMachineName($ct->id); $cache->setMajorVersion($ct->version->major); @@ -1118,18 +1118,23 @@ public function replaceContentTypeCache($contentTypeCache): void } /** - * @param string $tableClassName - * @throws Exception + * Truncate the specified database table. + * + * This method truncates the given database table by executing SQL queries to temporarily + * disable foreign key checks, truncate the table, and then re-enable foreign key checks. + * Truncating a table removes all rows but keeps the table structure intact. + * + * @param string $tableClassName The fully qualified class name of the entity representing the table. * @return void - */ + * @throws Exception + * */ private function truncateTable(string $tableClassName): void { $cmd = $this->manager->getClassMetadata($tableClassName); $connection = $this->manager->getConnection(); $dbPlatform = $connection->getDatabasePlatform(); $connection->executeQuery('SET FOREIGN_KEY_CHECKS=0'); - $q = $dbPlatform->getTruncateTableSql($cmd->getTableName()); - $connection->executeStatement($q); + $connection->executeStatement($dbPlatform->getTruncateTableSql($cmd->getTableName())); $connection->executeQuery('SET FOREIGN_KEY_CHECKS=1'); } @@ -1164,7 +1169,7 @@ public function getContentHubMetadataChecked($lang = 'en'): ?string { // Todo fetch the timestamp of current language here // dd(Languages::getName($lang)); - $date = new \DateTime('now'); + $date = new DateTime('now'); return $date->format(DateTimeInterface::RFC7231); } diff --git a/composer.json b/composer.json index c52a290..2db84bd 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { "name": "jorisdugue/h5p-bundle", - "version": "2.1.0", + "version": "2.0.2", "type": "symfony-bundle", "description": "H5P Bundle for Symfony 5, 6 and Symfony 7", "keywords": [ From cb27f715c0b1ee2c8585cfb3c2d681ee9dfa882d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joris=20Dugu=C3=A9?= Date: Mon, 29 Jan 2024 19:56:09 +0100 Subject: [PATCH 2/4] fix(chore): resolve problem about postgresql #50 prevent deduplicate code with getUserId method --- Controller/H5PInteractionController.php | 34 ++++++++++++--------- Core/H5PSymfony.php | 39 ++++++++++++++++--------- Core/H5PUtils.php | 17 ++++++++--- DependencyInjection/Configuration.php | 8 +++-- 4 files changed, 65 insertions(+), 33 deletions(-) diff --git a/Controller/H5PInteractionController.php b/Controller/H5PInteractionController.php index d063513..64f427d 100644 --- a/Controller/H5PInteractionController.php +++ b/Controller/H5PInteractionController.php @@ -67,7 +67,10 @@ public function setFinished(Request $request, $token): JsonResponse if (!\H5PCore::validToken('result', $token)) { \H5PCore::ajaxError('Invalid security token'); } - $result = $this->resultService->handleRequestFinished($request, $this->getUserId($this->getUser())); + $result = $this->resultService->handleRequestFinished( + $request, + $this->h5PIntegration->getUserId($this->getUser()) + ); $this->entityManager->persist($result); $this->entityManager->flush(); return new JsonResponse(['success' => true]); @@ -116,7 +119,7 @@ public function contentUserData(Request $request, $contentId, $dataType, $subCon 'subContentId' => $subContentId, 'mainContent' => $contentId, 'dataId' => $dataType, - 'user' => $this->getUserId($user), + 'user' => $this->h5PIntegration->getUserId($user), ] ); if (!$update) { @@ -125,7 +128,7 @@ public function contentUserData(Request $request, $contentId, $dataType, $subCon * @var ContentUserData $contentUserData */ $contentUserData = new ContentUserData(); - $contentUserData->setUser($this->getUserId($user)); + $contentUserData->setUser($this->h5PIntegration->getUserId($user)); $contentUserData->setData($data); $contentUserData->setDataId($dataType); $contentUserData->setSubContentId($subContentId); @@ -153,7 +156,7 @@ public function contentUserData(Request $request, $contentId, $dataType, $subCon 'subContentId' => $subContentId, 'mainContent' => $contentId, 'dataId' => $dataType, - 'user' => $this->getUserId($user), + 'user' => $this->h5PIntegration->getUserId($user), ]); //decode for read the information @@ -185,7 +188,9 @@ public function embedAction(Request $request, Content $content): Response $integration = $this->h5PIntegration->getGenericH5PIntegrationSettings(); $content_id_string = 'cid-' . $content->getId(); // Add content specific settings - $integration['contents'][$content_id_string] = $this->h5PIntegration->getH5PContentIntegrationSettings($content); + $integration['contents'][$content_id_string] = $this->h5PIntegration->getH5PContentIntegrationSettings( + $content + ); $preloaded_dependencies = $this->h5PCore->loadContentDependencies($content->getId(), 'preloaded'); $files = $this->h5PCore->getDependenciesFiles($preloaded_dependencies, $this->options->getRelativeH5PPath()); // Load public files @@ -206,7 +211,7 @@ public function embedAction(Request $request, Content $content): Response $lang = $request->getLocale(); $content = [ 'id' => $id, - 'title' => "H5P Content {$id}", + 'title' => "H5P Content $id", ]; //include the embed file (provide in h5p-core) include $this->kernel->getProjectDir() . '/vendor/h5p/h5p-core/embed.php'; @@ -215,16 +220,17 @@ public function embedAction(Request $request, Content $content): Response return new Response($response['#markup']); } + /** + * Retrieves the URL for the H5P asset based on the configured asset path. + * + * This method generates and returns the URL for the H5P asset by using the + * configured asset path provided through the options service. The URL is + * constructed using the asset path and the Symfony Asset component. + * + * @return string The URL for the H5P asset. + */ private function getH5PAssetUrl(): string { return $this->assetsPaths->getUrl($this->options->getH5PAssetPath()); } - - private function getUserId(UserInterface $user) - { - if (method_exists($user, 'getId')) { - return $user->getId(); - } - return $user->getUserIdentifier(); - } } diff --git a/Core/H5PSymfony.php b/Core/H5PSymfony.php index b99d42d..8abbf11 100644 --- a/Core/H5PSymfony.php +++ b/Core/H5PSymfony.php @@ -5,6 +5,7 @@ use DateTime; use DateTimeInterface; use Doctrine\DBAL\Exception; +use Doctrine\DBAL\Platforms\PostgreSQLPlatform; use Doctrine\ORM\EntityManagerInterface; use GuzzleHttp\Exception\GuzzleException; use JsonSerializable; @@ -85,16 +86,17 @@ class H5PSymfony implements \H5PFrameworkInterface * @param RouterInterface $router */ public function __construct( - H5POptions $options, - EditorStorage $editorStorage, - TokenStorageInterface $tokenStorage, - EntityManagerInterface $manager, - ?Session $session, - ?RequestStack $requestStack, + H5POptions $options, + EditorStorage $editorStorage, + TokenStorageInterface $tokenStorage, + EntityManagerInterface $manager, + ?Session $session, + ?RequestStack $requestStack, AuthorizationCheckerInterface $authorizationChecker, - EventDispatcherInterface $eventDispatcher, - RouterInterface $router - ) { + EventDispatcherInterface $eventDispatcher, + RouterInterface $router + ) + { $this->options = $options; $this->editorStorage = $editorStorage; $this->tokenStorage = $tokenStorage; @@ -156,7 +158,8 @@ public function fetchExternalData( $headers = [], $files = [], $method = 'POST' - ) { + ) + { $options = []; if (!empty($data)) { $options['headers'] = ['Content-Type' => 'application/x-www-form-urlencoded']; @@ -890,7 +893,7 @@ public function getOption($name, $default = null) try { // return default if db/table still not created return $this->options->getOption($name, $default); - } catch (ConnectionException | TableNotFoundException $e) { + } catch (ConnectionException|TableNotFoundException $e) { return $default; } } @@ -1133,9 +1136,19 @@ private function truncateTable(string $tableClassName): void $cmd = $this->manager->getClassMetadata($tableClassName); $connection = $this->manager->getConnection(); $dbPlatform = $connection->getDatabasePlatform(); - $connection->executeQuery('SET FOREIGN_KEY_CHECKS=0'); + // disable foreign key check or equivalent to pgsql + if ($dbPlatform instanceof PostgreSQLPlatform) { + $connection->executeQuery('SET session_replication_role = replica;'); + } else { + $connection->executeQuery('SET FOREIGN_KEY_CHECKS=0'); + } $connection->executeStatement($dbPlatform->getTruncateTableSql($cmd->getTableName())); - $connection->executeQuery('SET FOREIGN_KEY_CHECKS=1'); + // Enable foreign key check + if ($dbPlatform instanceof PostgreSQLPlatform) { + $connection->executeQuery('SET session_replication_role = DEFAULT;'); + } else { + $connection->executeQuery('SET FOREIGN_KEY_CHECKS=1'); + } } /** diff --git a/Core/H5PUtils.php b/Core/H5PUtils.php index 12088e5..2a8b35a 100644 --- a/Core/H5PUtils.php +++ b/Core/H5PUtils.php @@ -31,11 +31,20 @@ public function getCurrentOrAnonymousUser() return 'anon.'; } - public function getUserId(UserInterface $user) + /** + * Fetch current User ID + * @param UserInterface|null $user + * @return string|null|integer + */ + public function getUserId(?UserInterface $user) { - if (method_exists($user, 'getId')) { - return $user->getId(); + if ($user !== null) { + if (method_exists($user, 'getId')) { + return $user->getId(); + } + return $user->getUserIdentifier(); + } else { + return null; } - return $user->getUserIdentifier(); } } diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index cd77915..83dfbcf 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -9,14 +9,18 @@ class Configuration implements ConfigurationInterface { - const H5P_VERSION = '2.1.0'; // version of Symfony H5P bundle + /** + * version of Symfony H5P bundle + * @return {string} + */ + const H5P_VERSION = '2.1.0'; /** * Generates the configuration tree. * * @return TreeBuilder|NodeInterface */ - public function getConfigTreeBuilder() + public function getConfigTreeBuilder(): TreeBuilder { $treeBuilder = new TreeBuilder('studit_h5_p'); From caa919e1652212b8790ea40a97e1cadc0aceee5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joris=20Dugu=C3=A9?= Date: Mon, 29 Jan 2024 20:13:53 +0100 Subject: [PATCH 3/4] fix(chore): prevent crash with qcm bump to 2.1.0 --- Entity/Content.php | 7 ++++--- composer.json | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Entity/Content.php b/Entity/Content.php index 508fd88..0a61838 100644 --- a/Entity/Content.php +++ b/Entity/Content.php @@ -32,7 +32,7 @@ class Content */ private $parameters; /** - * @var string + * @var string|null * * @ORM\Column(name="filtered_parameters", type="text", nullable=true) */ @@ -96,10 +96,11 @@ public function getFilteredParameters(): string { return $this->filteredParameters; } + /** - * @param string $filteredParameters + * @param string|null $filteredParameters */ - public function setFilteredParameters(string $filteredParameters) + public function setFilteredParameters(?string $filteredParameters) { $this->filteredParameters = $filteredParameters; } diff --git a/composer.json b/composer.json index 2db84bd..c52a290 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { "name": "jorisdugue/h5p-bundle", - "version": "2.0.2", + "version": "2.1.0", "type": "symfony-bundle", "description": "H5P Bundle for Symfony 5, 6 and Symfony 7", "keywords": [ From 51e094990d86ec9adab88a752b548a94341ed7fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joris=20Dugu=C3=A9?= Date: Mon, 29 Jan 2024 20:16:08 +0100 Subject: [PATCH 4/4] fix(chore): resolve problem with phpstan --- DependencyInjection/Configuration.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index 83dfbcf..0388f9a 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -11,14 +11,13 @@ class Configuration implements ConfigurationInterface { /** * version of Symfony H5P bundle - * @return {string} + * @return string */ const H5P_VERSION = '2.1.0'; /** * Generates the configuration tree. - * - * @return TreeBuilder|NodeInterface + * @return TreeBuilder */ public function getConfigTreeBuilder(): TreeBuilder {