From ae5d77953ab62906c0b5197c6ad803c063be457a Mon Sep 17 00:00:00 2001 From: Andreas Pfeiffer <88720542+epx-anpf@users.noreply.github.com> Date: Fri, 11 Mar 2022 10:01:12 +0100 Subject: [PATCH 1/9] Add composer file --- composer.json | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 composer.json diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..f36ac2f --- /dev/null +++ b/composer.json @@ -0,0 +1,29 @@ +{ + "name": "slub/slub-profile-bookmarks", + "type": "typo3-cms-extension", + "description": "SLUB profile service bookmark extension for TYPO3", + "authors": [ + { + "name": "Andreas Pfeiffer", + "role": "Developer" + } + ], + "version": "0.1.0", + "license": "GPL-2.0-or-later", + "require": { + "typo3/cms-core": "^11" + }, + "replace": { + "typo3-ter/slub-profile-bookmarks": "self.version" + }, + "autoload": { + "psr-4": { + "Slub\\SlubProfileBookmarks\\": "Classes/" + } + }, + "extra": { + "typo3/cms": { + "extension-key": "slub_profile_bookmarks" + } + } +} From 42b787af485fcf94deb0db58ff6a1146955ce442 Mon Sep 17 00:00:00 2001 From: Andreas Pfeiffer Date: Fri, 11 Mar 2022 10:05:56 +0100 Subject: [PATCH 2/9] Add initial code --- .editorconfig | 56 +++++++++ Classes/Controller/BookmarkController.php | 47 ++++++++ .../Dto/ApiBookmarkListConfiguration.php | 53 +++++++++ .../RequestArgumentIdentifierInterface.php | 25 ++++ .../RequestArgumentIdentifierTrait.php | 33 ++++++ .../Model/Dto/Request/RequestUriInterface.php | 25 ++++ .../Model/Dto/Request/RequestUriTrait.php | 33 ++++++ Classes/Http/Request.php | 108 ++++++++++++++++++ Classes/Mvc/View/JsonView.php | 56 +++++++++ Classes/Routing/UriGenerator.php | 74 ++++++++++++ .../BookmarkArgumentSanitization.php | 41 +++++++ Classes/Service/BookmarkService.php | 52 +++++++++ Classes/Utility/ConstantsUtility.php | 18 +++ Classes/Utility/LanguageUtility.php | 68 +++++++++++ Configuration/Icons.php | 14 +++ Configuration/Routes/BookmarkList.yaml | 10 ++ Configuration/Routes/Default.yaml | 5 + Configuration/Services.yaml | 17 +++ Configuration/TCA/Overrides/sys_template.php | 10 ++ Configuration/TCA/Overrides/tt_content.php | 63 ++++++++++ Configuration/TsConfig/Page.tsconfig | 18 +++ Configuration/TypoScript/constants.typoscript | 4 + Configuration/TypoScript/setup.typoscript | 10 ++ README.md | 52 ++++++++- .../Private/Language/de.locallang_backend.xlf | 30 +++++ .../Private/Language/locallang_backend.xlf | 25 ++++ Resources/Public/Icons/Extension.svg | 1 + Resources/Public/Icons/Overlay/extension.svg | 6 + .../Public/Icons/Wizard/bookmark-list.svg | 14 +++ ext_conf_template.txt | 5 + ext_emconf.php | 28 +++++ ext_localconf.php | 25 ++++ 32 files changed, 1025 insertions(+), 1 deletion(-) create mode 100644 .editorconfig create mode 100644 Classes/Controller/BookmarkController.php create mode 100644 Classes/Domain/Model/Dto/ApiBookmarkListConfiguration.php create mode 100644 Classes/Domain/Model/Dto/Request/RequestArgumentIdentifierInterface.php create mode 100644 Classes/Domain/Model/Dto/Request/RequestArgumentIdentifierTrait.php create mode 100644 Classes/Domain/Model/Dto/Request/RequestUriInterface.php create mode 100644 Classes/Domain/Model/Dto/Request/RequestUriTrait.php create mode 100644 Classes/Http/Request.php create mode 100644 Classes/Mvc/View/JsonView.php create mode 100644 Classes/Routing/UriGenerator.php create mode 100644 Classes/Sanitization/BookmarkArgumentSanitization.php create mode 100644 Classes/Service/BookmarkService.php create mode 100644 Classes/Utility/ConstantsUtility.php create mode 100644 Classes/Utility/LanguageUtility.php create mode 100644 Configuration/Icons.php create mode 100644 Configuration/Routes/BookmarkList.yaml create mode 100644 Configuration/Routes/Default.yaml create mode 100644 Configuration/Services.yaml create mode 100644 Configuration/TCA/Overrides/sys_template.php create mode 100644 Configuration/TCA/Overrides/tt_content.php create mode 100644 Configuration/TsConfig/Page.tsconfig create mode 100644 Configuration/TypoScript/constants.typoscript create mode 100644 Configuration/TypoScript/setup.typoscript create mode 100644 Resources/Private/Language/de.locallang_backend.xlf create mode 100644 Resources/Private/Language/locallang_backend.xlf create mode 100644 Resources/Public/Icons/Extension.svg create mode 100644 Resources/Public/Icons/Overlay/extension.svg create mode 100644 Resources/Public/Icons/Wizard/bookmark-list.svg create mode 100644 ext_conf_template.txt create mode 100644 ext_emconf.php create mode 100644 ext_localconf.php diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..b0b42d7 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,56 @@ +# EditorConfig is awesome: http://EditorConfig.org + +# top-most EditorConfig file +root = true + +# Unix-style newlines with a newline ending every file +[*] +charset = utf-8 +end_of_line = lf +indent_style = space +indent_size = 4 +insert_final_newline = true +trim_trailing_whitespace = true + +# TS/JS-Files +[*.{ts,js}] +indent_size = 2 + +# JSON-Files +[*.json] +indent_style = tab + +# ReST-Files +[*.rst] +indent_size = 4 +max_line_length = 80 + +# YAML-Files +[*.{yaml,yml}] +indent_size = 2 + +# NEON-Files +[*.neon] +indent_size = 2 +indent_style = tab + +# package.json +[package.json] +indent_size = 2 + +# TypoScript +[*.{typoscript,tsconfig}] +indent_size = 2 + +# XLF-Files +[*.xlf] +indent_style = tab + +# SQL-Files +[*.sql] +indent_style = tab +indent_size = 2 + +# .htaccess +[{_.htaccess,.htaccess}] +indent_style = tab \ No newline at end of file diff --git a/Classes/Controller/BookmarkController.php b/Classes/Controller/BookmarkController.php new file mode 100644 index 0000000..6b0c734 --- /dev/null +++ b/Classes/Controller/BookmarkController.php @@ -0,0 +1,47 @@ +bookmarkService = $bookmarkService; + } + + /** + * @return ResponseInterface + * @throws AspectNotFoundException + */ + public function listAction(): ResponseInterface + { + $bookmarks = $this->bookmarkService->getBookmarks($this->request->getArguments()); + + $this->view->setVariablesToRender(['bookmarkList']); + $this->view->assign('bookmarkList', $bookmarks); + + return $this->jsonResponse(); + } +} diff --git a/Classes/Domain/Model/Dto/ApiBookmarkListConfiguration.php b/Classes/Domain/Model/Dto/ApiBookmarkListConfiguration.php new file mode 100644 index 0000000..eb58eea --- /dev/null +++ b/Classes/Domain/Model/Dto/ApiBookmarkListConfiguration.php @@ -0,0 +1,53 @@ +getConfiguration(ConstantsUtility::EXTENSION_KEY)[self::KEY]; + + empty($configuration['requestArgumentIdentifier']) ?: $this->setRequestArgumentIdentifier($configuration['requestArgumentIdentifier']); + empty($configuration['requestUri']) ?: $this->setRequestUri($configuration['requestUri']); + } + + /** + * @param string $extensionKey + * @return array + */ + protected function getConfiguration(string $extensionKey = ''): array + { + /** @var ExtensionConfiguration $extensionConfiguration */ + $extensionConfiguration = GeneralUtility::makeInstance(ExtensionConfiguration::class); + + try { + return $extensionConfiguration->get($extensionKey); + } catch (Exception $e) { + return []; + } + } +} diff --git a/Classes/Domain/Model/Dto/Request/RequestArgumentIdentifierInterface.php b/Classes/Domain/Model/Dto/Request/RequestArgumentIdentifierInterface.php new file mode 100644 index 0000000..f90be1c --- /dev/null +++ b/Classes/Domain/Model/Dto/Request/RequestArgumentIdentifierInterface.php @@ -0,0 +1,25 @@ +requestArgumentIdentifier; + } + + /** + * @param string $requestArgumentIdentifier + */ + public function setRequestArgumentIdentifier(string $requestArgumentIdentifier = ''): void + { + $this->requestArgumentIdentifier = $requestArgumentIdentifier; + } +} diff --git a/Classes/Domain/Model/Dto/Request/RequestUriInterface.php b/Classes/Domain/Model/Dto/Request/RequestUriInterface.php new file mode 100644 index 0000000..b6a3cdd --- /dev/null +++ b/Classes/Domain/Model/Dto/Request/RequestUriInterface.php @@ -0,0 +1,25 @@ +requestUri; + } + + /** + * @param string $requestUri + */ + public function setRequestUri(string $requestUri = ''): void + { + $this->requestUri = $requestUri; + } +} diff --git a/Classes/Http/Request.php b/Classes/Http/Request.php new file mode 100644 index 0000000..64658c3 --- /dev/null +++ b/Classes/Http/Request.php @@ -0,0 +1,108 @@ + [ + 'Cache-Control' => 'no-cache' + ], + 'allow_redirects' => false + ]; + protected LoggerInterface $logger; + protected RequestFactoryInterface $requestFactory; + + /** + * @param LoggerInterface $logger + * @param RequestFactoryInterface $requestFactory + */ + public function __construct( + LoggerInterface $logger, + RequestFactoryInterface $requestFactory + ) { + $this->logger = $logger; + $this->requestFactory = $requestFactory; + } + + /** + * @param string $uri + * @param string $method + * @param array $options + * @return array|null + */ + public function process(string $uri = '', string $method = 'GET', array $options = []): ?array + { + try { + $options = $this->mergeOptions($this->options, $options); + $response = $this->requestFactory->request($uri, $method, $options); + + return $this->getContent($response, $uri); + } catch (RequestException $e) { + /** @extensionScannerIgnoreLine */ + $this->logger->error($e->getMessage()); + + return null; + } + } + + /** + * @param array $default + * @param array $new + * @return array + */ + protected function mergeOptions(array $default, array $new): array + { + if (count($new) > 0) { + ArrayUtility::mergeRecursiveWithOverrule($default, $new); + } + + return $default; + } + + /** + * @param ResponseInterface $response + * @param string $uri + * @return array|null + */ + protected function getContent(ResponseInterface $response, string $uri = ''): ?array + { + $content = ''; + + if ($response->getStatusCode() === 200 && + strpos($response->getHeaderLine('Content-Type'), 'application/json') === 0 + ) { + $content = (array)json_decode($response->getBody()->getContents(), true); + } + + if (empty($content)) { + $this->logger->warning( + 'Requesting {request} was not successful, got status code {status} ({reason})', + [ + 'request' => $uri, + 'status' => $response->getStatusCode(), + 'reason' => $response->getReasonPhrase(), + ] + ); + + return null; + } + + return $content; + } +} diff --git a/Classes/Mvc/View/JsonView.php b/Classes/Mvc/View/JsonView.php new file mode 100644 index 0000000..9e0a63b --- /dev/null +++ b/Classes/Mvc/View/JsonView.php @@ -0,0 +1,56 @@ + [ + * '_descendAll' => [ + * '_exclude' => [ + * 'categories', + * 'contact', + * 'discipline' + * ] + * ] + * ] + */ + protected array $bookmarkConfiguration = [ + 'bookmarkList' => [ + '_only' => [ + 'bookmarks' + ], + 'bookmarks' => [ + '_descendAll' => [ + '_only' => [ + 'crdate', + 'title', + 'recordid' + ], + ] + ] + ] + ]; + + public function __construct() + { + $this->setConfiguration($this->bookmarkConfiguration); + } +} diff --git a/Classes/Routing/UriGenerator.php b/Classes/Routing/UriGenerator.php new file mode 100644 index 0000000..474f42e --- /dev/null +++ b/Classes/Routing/UriGenerator.php @@ -0,0 +1,74 @@ +configurationManager = $configurationManager; + } + + /** + * @param array $additionalParameters + * @return string + * @throws AspectNotFoundException + */ + public function buildBookmarkList(array $additionalParameters): string + { + /** @var ApiBookmarkListConfiguration $apiConfiguration */ + $apiConfiguration = GeneralUtility::makeInstance(ApiBookmarkListConfiguration::class); + + /** @extensionScannerIgnoreLine */ + $requestUri = $apiConfiguration->getRequestUri(); + $requestArgumentIdentifier = $apiConfiguration->getRequestArgumentIdentifier(); + + return $this->build($requestUri, $requestArgumentIdentifier, $additionalParameters); + } + + /** + * @param string $requestUri + * @param string $requestArgumentIdentifier + * @param array $additionalParameters + * @return string + * @throws AspectNotFoundException + */ + protected function build( + string $requestUri, + string $requestArgumentIdentifier, + array $additionalParameters + ): string { + $parameters = [ + 'L' => LanguageUtility::getUid() ?? 0 + ]; + + empty($requestArgumentIdentifier) ?: $parameters[$requestArgumentIdentifier] = $additionalParameters; + + if (count($parameters) > 0) { + $requestUri .= strpos($requestUri, '?') ? '&' : '?'; + $requestUri .= http_build_query($parameters); + } + + return $requestUri; + } +} diff --git a/Classes/Sanitization/BookmarkArgumentSanitization.php b/Classes/Sanitization/BookmarkArgumentSanitization.php new file mode 100644 index 0000000..617c8d8 --- /dev/null +++ b/Classes/Sanitization/BookmarkArgumentSanitization.php @@ -0,0 +1,41 @@ + 0]; + } + + $this->sanitizeInteger('user', $arguments['user']); + + return $this->sanitizedArguments; + } + + /** + * @param string $key + * @param string $value + */ + protected function sanitizeInteger(string $key = '', string $value = ''): void + { + empty($value) ?: $this->sanitizedArguments[$key] = (int)$value; + } +} diff --git a/Classes/Service/BookmarkService.php b/Classes/Service/BookmarkService.php new file mode 100644 index 0000000..0189836 --- /dev/null +++ b/Classes/Service/BookmarkService.php @@ -0,0 +1,52 @@ +bookmarkArgumentSanitization = $bookmarkArgumentSanitization; + $this->request = $request; + $this->uriGenerator = $uriGenerator; + } + + /** + * @param array $arguments + * @return array + * @throws AspectNotFoundException + */ + public function getBookmarks(array $arguments): array + { + $sanitizedArguments = $this->bookmarkArgumentSanitization->sanitizeArguments($arguments); + $uri = $this->uriGenerator->buildBookmarkList($sanitizedArguments); + + return $this->request->process($uri) ?? []; + } +} diff --git a/Classes/Utility/ConstantsUtility.php b/Classes/Utility/ConstantsUtility.php new file mode 100644 index 0000000..cf99cf1 --- /dev/null +++ b/Classes/Utility/ConstantsUtility.php @@ -0,0 +1,18 @@ +getLanguageById($languageUid); + } + + /** + * @return int + * @throws AspectNotFoundException + */ + public static function getUid(): int + { + /** @var Context $context */ + $context = GeneralUtility::makeInstance(Context::class); + + return (int)$context->getPropertyFromAspect('language', 'id'); + } + + /** + * @param int $pageUid + * @return Site + */ + protected static function getSite(int $pageUid): Site + { + /** @var SiteFinder $siteFinder */ + $siteFinder = GeneralUtility::makeInstance(SiteFinder::class); + + try { + return $siteFinder->getSiteByPageId($pageUid); + } catch (SiteNotFoundException $e) { + throw new UnexpectedValueException( + 'A site not found by "' . $pageUid . '".', + 1490360742 + ); + } + } +} diff --git a/Configuration/Icons.php b/Configuration/Icons.php new file mode 100644 index 0000000..f0a9c61 --- /dev/null +++ b/Configuration/Icons.php @@ -0,0 +1,14 @@ + [ + 'provider' => \TYPO3\CMS\Core\Imaging\IconProvider\SvgIconProvider::class, + 'source' => 'EXT:slub_profile_bookmarks/Resources/Public/Icons/Wizard/bookmark-list.svg' + ], + 'slubprofilebookmarks-overlay-extension' => [ + 'provider' => \TYPO3\CMS\Core\Imaging\IconProvider\SvgIconProvider::class, + 'source' => 'EXT:slub_profile_bookmarks/Resources/Public/Icons/Overlay/extension.svg' + ] +]; diff --git a/Configuration/Routes/BookmarkList.yaml b/Configuration/Routes/BookmarkList.yaml new file mode 100644 index 0000000..39f9cf1 --- /dev/null +++ b/Configuration/Routes/BookmarkList.yaml @@ -0,0 +1,10 @@ +routeEnhancers: + SlubBookmarksBookmarkList: + type: Simple + limitToPages: [22] + routePath: '/{user}' + requirements: + user: '[0-9]{1,10}' + _arguments: + user: 'tx_slubprofilebookmarks_bookmarklist/user' + diff --git a/Configuration/Routes/Default.yaml b/Configuration/Routes/Default.yaml new file mode 100644 index 0000000..2fbe382 --- /dev/null +++ b/Configuration/Routes/Default.yaml @@ -0,0 +1,5 @@ +# This route enhancer config is not final +# But you can simply include it in your site configuration: +imports: + - resource: 'EXT:slub_profile_bookmarks/Configuration/Routes/BookmarkList.yaml' + diff --git a/Configuration/Services.yaml b/Configuration/Services.yaml new file mode 100644 index 0000000..a004789 --- /dev/null +++ b/Configuration/Services.yaml @@ -0,0 +1,17 @@ +services: + _defaults: + autowire: true + autoconfigure: true + public: false + + Slub\SlubProfileBookmarks\: + resource: '../Classes/*' + + Slub\SlubProfileBookmarks\Http\Request: + public: true + + Slub\SlubProfileBookmarks\Routing\UriGenerator: + public: true + + Slub\SlubProfileBookmarks\Service\BookmarkService: + public: true diff --git a/Configuration/TCA/Overrides/sys_template.php b/Configuration/TCA/Overrides/sys_template.php new file mode 100644 index 0000000..3d2af30 --- /dev/null +++ b/Configuration/TCA/Overrides/sys_template.php @@ -0,0 +1,10 @@ + 'LLL:EXT:' . $extensionKey . '/Resources/Private/Language/locallang_backend.xlf', + 'core' => 'LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf', + 'frontend' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf', + ]; + + // Add new group to ctype selector + TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTcaSelectItemGroup( + 'tt_content', + 'CType', + $extensionName, + $ll['backend'] . ':plugin.title', + 'after:default' // Should be the same like "common" in page tsconfig + ); + + foreach ($pluginNames as $pluginName) { + // Merge content element definition + TYPO3\CMS\Core\Utility\ArrayUtility::mergeRecursiveWithOverrule($GLOBALS['TCA']['tt_content'], [ + 'ctrl' => [ + 'typeicon_classes' => [ + $extensionName . '_' . $pluginName => $extensionName . '-wizard-' . $pluginName, + ], + ], + 'types' => [ + $extensionName . '_' . $pluginName => [ + 'showitem' => ' + --div--;' . $ll['core'] . ':general, + --palette--;;general, + --palette--;;headers, + --div--;' . $ll['core'] . ':language, + --palette--;;language, + --div--;' . $ll['core'] . ':access, + --palette--;;hidden, + --palette--;;access, + --div--;' . $ll['core'] . ':notes, + rowDescription, + --div--;' . $ll['core'] . ':extended', + ], + ], + ]); + + // Add item to select field list (ctype) + TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTcaSelectItem( + 'tt_content', + 'CType', + [ + $ll['backend'] . ':plugin.' . $pluginName . '.title', // Title + $extensionName . '_' . $pluginName, // CType + $extensionName . '-wizard-' . $pluginName, // Icon identifier + $extensionName // Item group id + ] + ); + } +})( + 'slub_profile_bookmarks', + ['bookmarklist'] +); diff --git a/Configuration/TsConfig/Page.tsconfig b/Configuration/TsConfig/Page.tsconfig new file mode 100644 index 0000000..ff5b305 --- /dev/null +++ b/Configuration/TsConfig/Page.tsconfig @@ -0,0 +1,18 @@ +mod { + wizards.newContentElement.wizardItems.slubprofilebookmarks { + after = common + header = LLL:EXT:slub_profile_bookmarks/Resources/Private/Language/locallang_backend.xlf:plugin.title + + elements { + slubprofilebookmarks_bookmarklist { + iconIdentifier = slubprofilebookmarks-wizard-bookmarklist + iconOverlay = slubprofilebookmarks-overlay-extension + title = LLL:EXT:slub_profile_bookmarks/Resources/Private/Language/locallang_backend.xlf:plugin.bookmarklist.title + description = LLL:EXT:slub_profile_bookmarks/Resources/Private/Language/locallang_backend.xlf:plugin.bookmarklist.description + tt_content_defValues.CType = slubprofilebookmarks_bookmarklist + } + } + + show := addToList(slubprofilebookmarks_bookmarklist) + } +} diff --git a/Configuration/TypoScript/constants.typoscript b/Configuration/TypoScript/constants.typoscript new file mode 100644 index 0000000..c1cee79 --- /dev/null +++ b/Configuration/TypoScript/constants.typoscript @@ -0,0 +1,4 @@ +plugin.tx_slubprofilebookmarks { + # cat=plugin.tx_slubprofilebookmarks//a; type=string; label=Default storage PID + settings.storagePid = 0 +} diff --git a/Configuration/TypoScript/setup.typoscript b/Configuration/TypoScript/setup.typoscript new file mode 100644 index 0000000..5fec4d1 --- /dev/null +++ b/Configuration/TypoScript/setup.typoscript @@ -0,0 +1,10 @@ +plugin.tx_slubprofilebookmarks { + mvc { + callDefaultActionIfActionCantBeResolved = 1 + throwPageNotFoundExceptionIfActionCantBeResolved = 1 + } + + features { + skipDefaultArguments = 1 + } +} diff --git a/README.md b/README.md index e7e048a..2a7df1d 100644 --- a/README.md +++ b/README.md @@ -1 +1,51 @@ -# slub-profile-bookmarks \ No newline at end of file +# TYPO3 Extension `slub_profile_bookmarks` + +[![TYPO3](https://img.shields.io/badge/TYPO3-11-orange.svg)](https://typo3.org/) + +SLUB profile service bookmark extension for TYPO3. + +## 1 Usage + +### 1.1 Installation using Composer + +The recommended way to install the extension is using [Composer][1]. + +Run the following command within your Composer based TYPO3 project: + +``` +composer require slub/slub-profile-bookmarks +``` + +## 2 Administration corner + +### 2.1 Release Management + +News uses [semantic versioning][2], which means, that +* **bugfix updates** (e.g. 1.0.0 => 1.0.1) just includes small bugfixes or security relevant stuff without breaking changes, +* **minor updates** (e.g. 1.0.0 => 1.1.0) includes new features and smaller tasks without breaking changes, +* **major updates** (e.g. 1.0.0 => 2.0.0) breaking changes wich can be refactorings, features or bugfixes. + +## 3 API + +This extension communicates with another system to provide bookmarks. + +### 3.1 Routes + +Please check the routes' configuration. You have to set the matching page (limitToPages). If not the routes will not work properly. + +### 3.2 Bookmarks + +A list of bookmarks from a given user. + +- **Uri DDEV local:** https://ddev-slub-profile-service.ddev.site/merkliste/###USER_ID### +- **Uri general:** https://###YOUR-DOMAIN###/merkliste/###USER_ID### + +#### 3.2.1 Extension configuration + +- **Uri:** Address or domain to request the data. The uri has to begin with "https://". If you connect to another ddev container, please use "https://ddev-###YOUR-CONTAINER###-web". +- **Argument identifier:** When you request data from this extension to the bookmark api (external extension), you use additional parameters too. These parameters are wrapped with the "argument identifier". The default value is "tx_slubfindbookmarks_bookmarklist". Change only if you know what you do. + +[1]: https://getcomposer.org/ +[2]: https://semver.org/ + + diff --git a/Resources/Private/Language/de.locallang_backend.xlf b/Resources/Private/Language/de.locallang_backend.xlf new file mode 100644 index 0000000..96058ff --- /dev/null +++ b/Resources/Private/Language/de.locallang_backend.xlf @@ -0,0 +1,30 @@ + + + +
+ + + Bookmarks + Merkliste + + + + Bookmark list + Merkliste + + + List of bookmarks. + Auflistung von gemerkten Seiten. + + + + URI: The uri has to begin with "https://". Another DDEV container can be addressed directly via the container with "https: // ddev - ### YOUR-CONTAINER ### - web" or the domain, if configured "external_links". + URI: Die URI muss mit "https://" anfangen. Ein anderer DDEV-Container kann direkt über den Container mit "https://ddev-###YOUR-CONTAINER###-web" angesprochen werden oder die Domain, wenn "external_links" konfiguriert. + + + Argument identifier: The parameter needs to be written in a specific identifier. Default value "tx_slubfindbookmarks_bookmarklist". Change only if you know what you do. + Parameter ID: Die Parameter benötigen einen spezifischen Container. Default-Wert "tx_slubfindbookmarks_bookmarklist". Nur ändern, wenn wirklich notwendig. + + + + diff --git a/Resources/Private/Language/locallang_backend.xlf b/Resources/Private/Language/locallang_backend.xlf new file mode 100644 index 0000000..11b3047 --- /dev/null +++ b/Resources/Private/Language/locallang_backend.xlf @@ -0,0 +1,25 @@ + + + +
+ + + Bookmarks + + + + Bookmark list + + + List of bookmarks. + + + + URI: The uri has to begin with "https://". Another DDEV container can be addressed directly via the container with "https: // ddev - ### YOUR-CONTAINER ### - web" or the domain, if configured "external_links". + + + Argument identifier: The parameter needs to be written in a specific identifier. Default value "tx_slubfindbookmarks_bookmarklist". Change only if you know what you do. + + + + diff --git a/Resources/Public/Icons/Extension.svg b/Resources/Public/Icons/Extension.svg new file mode 100644 index 0000000..528d7f0 --- /dev/null +++ b/Resources/Public/Icons/Extension.svg @@ -0,0 +1 @@ + diff --git a/Resources/Public/Icons/Overlay/extension.svg b/Resources/Public/Icons/Overlay/extension.svg new file mode 100644 index 0000000..5fa6dd3 --- /dev/null +++ b/Resources/Public/Icons/Overlay/extension.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/Resources/Public/Icons/Wizard/bookmark-list.svg b/Resources/Public/Icons/Wizard/bookmark-list.svg new file mode 100644 index 0000000..e59fb07 --- /dev/null +++ b/Resources/Public/Icons/Wizard/bookmark-list.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/ext_conf_template.txt b/ext_conf_template.txt new file mode 100644 index 0000000..7b2b372 --- /dev/null +++ b/ext_conf_template.txt @@ -0,0 +1,5 @@ +# cat=API bookmark list; type=string; label=LLL:EXT:slub_profile_bookmarks/Resources/Private/Language/locallang_backend.xlf:extensionConfiguration.bookmarkList.requestUri +bookmarkList.requestUri = + +# cat=API bookmark list; type=string; label=LLL:EXT:slub_profile_bookmarks/Resources/Private/Language/locallang_backend.xlf:extensionConfiguration.bookmarkList.requestArgumentIdentifier +bookmarkList.requestArgumentIdentifier = tx_slubfindbookmarks_bookmarklist diff --git a/ext_emconf.php b/ext_emconf.php new file mode 100644 index 0000000..842519a --- /dev/null +++ b/ext_emconf.php @@ -0,0 +1,28 @@ + 'SLUB profile bookmarks', + 'description' => 'SLUB profile service bookmark extension for TYPO3', + 'category' => 'fe', + 'author' => 'Andreas Pfeiffer', + 'author_email' => 'andreas.pfeiffer@e-pixler.com', + 'author_company' => 'e-pixler', + 'shy' => '', + 'priority' => '', + 'module' => '', + 'state' => 'stable', + 'internal' => '', + 'uploadfolder' => 1, + 'createDirs' => '', + 'modify_tables' => '', + 'clearCacheOnLoad' => 1, + 'lockType' => '', + 'version' => '0.1.0', + 'constraints' => [ + 'depends' => [ + 'typo3' => '11.0.0-11.5.99' + ], + 'conflicts' => [], + 'suggests' => [], + ], +]; diff --git a/ext_localconf.php b/ext_localconf.php new file mode 100644 index 0000000..7f6849d --- /dev/null +++ b/ext_localconf.php @@ -0,0 +1,25 @@ + 'list' + ], + [ + BookmarkController::class => 'list' + ], + ExtensionUtility::PLUGIN_TYPE_CONTENT_ELEMENT +); From aca18ee29e81b922c20f28b306b73e33ade6b11c Mon Sep 17 00:00:00 2001 From: Andreas Pfeiffer Date: Wed, 30 Mar 2022 15:52:47 +0200 Subject: [PATCH 3/9] [TASK] Remove unused class ConfigurationManager --- Classes/Routing/UriGenerator.php | 11 ----------- Configuration/Services.yaml | 3 --- 2 files changed, 14 deletions(-) diff --git a/Classes/Routing/UriGenerator.php b/Classes/Routing/UriGenerator.php index 474f42e..8980993 100644 --- a/Classes/Routing/UriGenerator.php +++ b/Classes/Routing/UriGenerator.php @@ -15,20 +15,9 @@ use Slub\SlubProfileBookmarks\Utility\LanguageUtility; use TYPO3\CMS\Core\Context\Exception\AspectNotFoundException; use TYPO3\CMS\Core\Utility\GeneralUtility; -use TYPO3\CMS\Extbase\Configuration\ConfigurationManager; class UriGenerator { - protected ConfigurationManager $configurationManager; - - /** - * @param ConfigurationManager $configurationManager - */ - public function __construct(ConfigurationManager $configurationManager) - { - $this->configurationManager = $configurationManager; - } - /** * @param array $additionalParameters * @return string diff --git a/Configuration/Services.yaml b/Configuration/Services.yaml index a004789..b345d4f 100644 --- a/Configuration/Services.yaml +++ b/Configuration/Services.yaml @@ -10,8 +10,5 @@ services: Slub\SlubProfileBookmarks\Http\Request: public: true - Slub\SlubProfileBookmarks\Routing\UriGenerator: - public: true - Slub\SlubProfileBookmarks\Service\BookmarkService: public: true From af414ff2e49c1034f1863c21448e6dfeb7c6c916 Mon Sep 17 00:00:00 2001 From: Andreas Pfeiffer Date: Tue, 23 Apr 2024 15:19:56 +0200 Subject: [PATCH 4/9] [TASK] Change api for bookmark list; Add app key authentication --- Classes/Controller/BookmarkController.php | 11 ++- .../Model/Dto/ApiAppKeyConfiguration.php | 81 +++++++++++++++++++ .../Dto/ApiBookmarkListConfiguration.php | 44 ++++++++-- .../RequestArgumentIdentifierInterface.php | 25 ------ .../RequestArgumentIdentifierTrait.php | 33 -------- .../Model/Dto/Request/RequestUriInterface.php | 25 ------ .../Model/Dto/Request/RequestUriTrait.php | 33 -------- Classes/Routing/UriGenerator.php | 17 ++++ Classes/Service/AppKeyService.php | 58 +++++++++++++ Classes/Service/BookmarkService.php | 13 ++- .../Private/Language/de.locallang_backend.xlf | 9 +++ .../Private/Language/locallang_backend.xlf | 9 +++ ext_conf_template.txt | 6 ++ 13 files changed, 238 insertions(+), 126 deletions(-) create mode 100644 Classes/Domain/Model/Dto/ApiAppKeyConfiguration.php delete mode 100644 Classes/Domain/Model/Dto/Request/RequestArgumentIdentifierInterface.php delete mode 100644 Classes/Domain/Model/Dto/Request/RequestArgumentIdentifierTrait.php delete mode 100644 Classes/Domain/Model/Dto/Request/RequestUriInterface.php delete mode 100644 Classes/Domain/Model/Dto/Request/RequestUriTrait.php create mode 100644 Classes/Service/AppKeyService.php diff --git a/Classes/Controller/BookmarkController.php b/Classes/Controller/BookmarkController.php index 6b0c734..2ce2028 100644 --- a/Classes/Controller/BookmarkController.php +++ b/Classes/Controller/BookmarkController.php @@ -37,7 +37,16 @@ public function __construct(BookmarkService $bookmarkService) */ public function listAction(): ResponseInterface { - $bookmarks = $this->bookmarkService->getBookmarks($this->request->getArguments()); + $arguments = $this->request->getArguments(); + /** + * IMPORTANT + * --------- + * The api to get the api key requires a password from the user we do not have. + * Well, fake the password and disable credential check at katalog service + * account extension via "plugin.tx_slubaccount.settings.debugapi". + */ + $arguments['password'] = 'password'; + $bookmarks = $this->bookmarkService->getBookmarks($arguments); $this->view->setVariablesToRender(['bookmarkList']); $this->view->assign('bookmarkList', $bookmarks); diff --git a/Classes/Domain/Model/Dto/ApiAppKeyConfiguration.php b/Classes/Domain/Model/Dto/ApiAppKeyConfiguration.php new file mode 100644 index 0000000..eb48eb3 --- /dev/null +++ b/Classes/Domain/Model/Dto/ApiAppKeyConfiguration.php @@ -0,0 +1,81 @@ +getConfiguration(ConstantsUtility::EXTENSION_KEY)[self::KEY]; + + empty($configuration['requestArgumentIdentifier']) ?: $this->setRequestArgumentIdentifier($configuration['requestArgumentIdentifier']); + empty($configuration['requestUri']) ?: $this->setRequestUri($configuration['requestUri']); + } + + /** + * @return string + */ + public function getRequestUri(): string + { + return $this->requestUri; + } + + /** + * @param string $requestUri + */ + public function setRequestUri(string $requestUri = ''): void + { + $this->requestUri = $requestUri; + } + + /** + * @return string + */ + public function getRequestArgumentIdentifier(): string + { + return $this->requestArgumentIdentifier; + } + + /** + * @param string $requestArgumentIdentifier + */ + public function setRequestArgumentIdentifier(string $requestArgumentIdentifier = ''): void + { + $this->requestArgumentIdentifier = $requestArgumentIdentifier; + } + + /** + * @param string $extensionKey + * @return array + */ + protected function getConfiguration(string $extensionKey = ''): array + { + /** @var ExtensionConfiguration $extensionConfiguration */ + $extensionConfiguration = GeneralUtility::makeInstance(ExtensionConfiguration::class); + + try { + return $extensionConfiguration->get($extensionKey); + } catch (Exception $e) { + return []; + } + } +} diff --git a/Classes/Domain/Model/Dto/ApiBookmarkListConfiguration.php b/Classes/Domain/Model/Dto/ApiBookmarkListConfiguration.php index eb58eea..2d36959 100644 --- a/Classes/Domain/Model/Dto/ApiBookmarkListConfiguration.php +++ b/Classes/Domain/Model/Dto/ApiBookmarkListConfiguration.php @@ -12,21 +12,17 @@ namespace Slub\SlubProfileBookmarks\Domain\Model\Dto; use Exception; -use Slub\SlubProfileBookmarks\Domain\Model\Dto\Request\RequestArgumentIdentifierInterface; -use Slub\SlubProfileBookmarks\Domain\Model\Dto\Request\RequestArgumentIdentifierTrait; -use Slub\SlubProfileBookmarks\Domain\Model\Dto\Request\RequestUriInterface; -use Slub\SlubProfileBookmarks\Domain\Model\Dto\Request\RequestUriTrait; use Slub\SlubProfileBookmarks\Utility\ConstantsUtility; use TYPO3\CMS\Core\Configuration\ExtensionConfiguration; use TYPO3\CMS\Core\Utility\GeneralUtility; -class ApiBookmarkListConfiguration implements RequestArgumentIdentifierInterface, RequestUriInterface +class ApiBookmarkListConfiguration { - use RequestArgumentIdentifierTrait; - use RequestUriTrait; - public const KEY = 'bookmarkList'; + protected string $requestUri = ''; + protected string $requestArgumentIdentifier = ''; + public function __construct() { $configuration = $this->getConfiguration(ConstantsUtility::EXTENSION_KEY)[self::KEY]; @@ -35,6 +31,38 @@ public function __construct() empty($configuration['requestUri']) ?: $this->setRequestUri($configuration['requestUri']); } + /** + * @return string + */ + public function getRequestUri(): string + { + return $this->requestUri; + } + + /** + * @param string $requestUri + */ + public function setRequestUri(string $requestUri = ''): void + { + $this->requestUri = $requestUri; + } + + /** + * @return string + */ + public function getRequestArgumentIdentifier(): string + { + return $this->requestArgumentIdentifier; + } + + /** + * @param string $requestArgumentIdentifier + */ + public function setRequestArgumentIdentifier(string $requestArgumentIdentifier = ''): void + { + $this->requestArgumentIdentifier = $requestArgumentIdentifier; + } + /** * @param string $extensionKey * @return array diff --git a/Classes/Domain/Model/Dto/Request/RequestArgumentIdentifierInterface.php b/Classes/Domain/Model/Dto/Request/RequestArgumentIdentifierInterface.php deleted file mode 100644 index f90be1c..0000000 --- a/Classes/Domain/Model/Dto/Request/RequestArgumentIdentifierInterface.php +++ /dev/null @@ -1,25 +0,0 @@ -requestArgumentIdentifier; - } - - /** - * @param string $requestArgumentIdentifier - */ - public function setRequestArgumentIdentifier(string $requestArgumentIdentifier = ''): void - { - $this->requestArgumentIdentifier = $requestArgumentIdentifier; - } -} diff --git a/Classes/Domain/Model/Dto/Request/RequestUriInterface.php b/Classes/Domain/Model/Dto/Request/RequestUriInterface.php deleted file mode 100644 index b6a3cdd..0000000 --- a/Classes/Domain/Model/Dto/Request/RequestUriInterface.php +++ /dev/null @@ -1,25 +0,0 @@ -requestUri; - } - - /** - * @param string $requestUri - */ - public function setRequestUri(string $requestUri = ''): void - { - $this->requestUri = $requestUri; - } -} diff --git a/Classes/Routing/UriGenerator.php b/Classes/Routing/UriGenerator.php index 8980993..d9795c3 100644 --- a/Classes/Routing/UriGenerator.php +++ b/Classes/Routing/UriGenerator.php @@ -11,6 +11,7 @@ namespace Slub\SlubProfileBookmarks\Routing; +use Slub\SlubProfileBookmarks\Domain\Model\Dto\ApiAppKeyConfiguration; use Slub\SlubProfileBookmarks\Domain\Model\Dto\ApiBookmarkListConfiguration; use Slub\SlubProfileBookmarks\Utility\LanguageUtility; use TYPO3\CMS\Core\Context\Exception\AspectNotFoundException; @@ -34,6 +35,22 @@ public function buildBookmarkList(array $additionalParameters): string return $this->build($requestUri, $requestArgumentIdentifier, $additionalParameters); } + /** + * @param array $additionalParameters + * @return string + * @throws AspectNotFoundException + */ + public function buildAppKey(array $additionalParameters): string + { + /** @var ApiAppKeyConfiguration $apiConfiguration */ + $apiConfiguration = GeneralUtility::makeInstance(ApiAppKeyConfiguration::class); + + /** @extensionScannerIgnoreLine */ + $requestUri = $apiConfiguration->getRequestUri(); + $requestArgumentIdentifier = $apiConfiguration->getRequestArgumentIdentifier(); + + return $this->build($requestUri, $requestArgumentIdentifier, $additionalParameters); + } /** * @param string $requestUri diff --git a/Classes/Service/AppKeyService.php b/Classes/Service/AppKeyService.php new file mode 100644 index 0000000..abd75be --- /dev/null +++ b/Classes/Service/AppKeyService.php @@ -0,0 +1,58 @@ +request = $request; + $this->uriGenerator = $uriGenerator; + } + + /** + * @param int $username + * @param string $password + * @return string|null + * @throws AspectNotFoundException + */ + public function getAppKey(int $username, string $password): ?string + { + $uri = $this->uriGenerator->buildAppKey([ + 'username' => $username, + 'password' => $password, + ]); + $data = $this->request->process($uri); + + if ( + is_array($data) && + array_key_exists('appkey', $data) + ) { + return $data['appkey']; + } + + return null; + } +} diff --git a/Classes/Service/BookmarkService.php b/Classes/Service/BookmarkService.php index 0189836..a211637 100644 --- a/Classes/Service/BookmarkService.php +++ b/Classes/Service/BookmarkService.php @@ -21,20 +21,24 @@ class BookmarkService protected BookmarkArgumentSanitization $bookmarkArgumentSanitization; protected Request $request; protected UriGenerator $uriGenerator; + protected AppKeyService $appKeyService; /** * @param BookmarkArgumentSanitization $bookmarkArgumentSanitization * @param Request $request * @param UriGenerator $uriGenerator + * @param AppKeyService $appKeyService */ public function __construct( BookmarkArgumentSanitization $bookmarkArgumentSanitization, Request $request, - UriGenerator $uriGenerator + UriGenerator $uriGenerator, + AppKeyService $appKeyService ) { $this->bookmarkArgumentSanitization = $bookmarkArgumentSanitization; $this->request = $request; $this->uriGenerator = $uriGenerator; + $this->appKeyService = $appKeyService; } /** @@ -45,6 +49,13 @@ public function __construct( public function getBookmarks(array $arguments): array { $sanitizedArguments = $this->bookmarkArgumentSanitization->sanitizeArguments($arguments); + $appKey = $this->appKeyService->getAppKey($sanitizedArguments['user'], $arguments['password']); + + if ($appKey === null) { + return []; + } + + $sanitizedArguments['appkey'] = $appKey; $uri = $this->uriGenerator->buildBookmarkList($sanitizedArguments); return $this->request->process($uri) ?? []; diff --git a/Resources/Private/Language/de.locallang_backend.xlf b/Resources/Private/Language/de.locallang_backend.xlf index 96058ff..e925791 100644 --- a/Resources/Private/Language/de.locallang_backend.xlf +++ b/Resources/Private/Language/de.locallang_backend.xlf @@ -25,6 +25,15 @@ Argument identifier: The parameter needs to be written in a specific identifier. Default value "tx_slubfindbookmarks_bookmarklist". Change only if you know what you do. Parameter ID: Die Parameter benötigen einen spezifischen Container. Default-Wert "tx_slubfindbookmarks_bookmarklist". Nur ändern, wenn wirklich notwendig. + + + URI: The uri has to begin with "https://". Another DDEV container can be addressed directly via the container with "https: // ddev - ### YOUR-CONTAINER ### - web" or the domain, if configured "external_links". + URI: Die URI muss mit "https://" anfangen. Ein anderer DDEV-Container kann direkt über den Container mit "https://ddev-###YOUR-CONTAINER###-web" angesprochen werden oder die Domain, wenn "external_links" konfiguriert. + + + Argument identifier: The parameter needs to be written in a specific identifier. Default value "tx_slubaccount_account". Change only if you know what you do. + Parameter ID: Die Parameter benötigen einen spezifischen Container. Default-Wert "tx_slubaccount_account". Nur ändern, wenn wirklich notwendig. + diff --git a/Resources/Private/Language/locallang_backend.xlf b/Resources/Private/Language/locallang_backend.xlf index 11b3047..5f781f9 100644 --- a/Resources/Private/Language/locallang_backend.xlf +++ b/Resources/Private/Language/locallang_backend.xlf @@ -20,6 +20,15 @@ Argument identifier: The parameter needs to be written in a specific identifier. Default value "tx_slubfindbookmarks_bookmarklist". Change only if you know what you do. + + + URI: The uri has to begin with "https://". Another DDEV container can be addressed directly via the container with "https: // ddev - ### YOUR-CONTAINER ### - web" or the domain, if configured "external_links". + URI: Die URI muss mit "https://" anfangen. Ein anderer DDEV-Container kann direkt über den Container mit "https://ddev-###YOUR-CONTAINER###-web" angesprochen werden oder die Domain, wenn "external_links" konfiguriert. + + + Argument identifier: The parameter needs to be written in a specific identifier. Default value "tx_slubaccount_account". Change only if you know what you do. + Parameter ID: Die Parameter benötigen einen spezifischen Container. Default-Wert "tx_slubaccount_account". Nur ändern, wenn wirklich notwendig. + diff --git a/ext_conf_template.txt b/ext_conf_template.txt index 7b2b372..1e7c6de 100644 --- a/ext_conf_template.txt +++ b/ext_conf_template.txt @@ -3,3 +3,9 @@ bookmarkList.requestUri = # cat=API bookmark list; type=string; label=LLL:EXT:slub_profile_bookmarks/Resources/Private/Language/locallang_backend.xlf:extensionConfiguration.bookmarkList.requestArgumentIdentifier bookmarkList.requestArgumentIdentifier = tx_slubfindbookmarks_bookmarklist + +# cat=API app key; type=string; label=LLL:EXT:slub_profile_bookmarks/Resources/Private/Language/locallang_backend.xlf:extensionConfiguration.appKey.requestUri +appKey.requestUri = + +# cat=API app key; type=string; label=LLL:EXT:slub_profile_bookmarks/Resources/Private/Language/locallang_backend.xlf:extensionConfiguration.appKey.requestArgumentIdentifier +appKey.requestArgumentIdentifier = tx_slubaccount_account From 7e070756c10fe9af817917d8e8e0259555e18c26 Mon Sep 17 00:00:00 2001 From: Andreas Pfeiffer Date: Tue, 23 Apr 2024 15:35:37 +0200 Subject: [PATCH 5/9] [TASK] Refresh api collection --- Classes/Mvc/View/JsonView.php | 7 +- postman_collection.json | 136 ++++++++++++++++++++++++++++++++++ 2 files changed, 139 insertions(+), 4 deletions(-) create mode 100644 postman_collection.json diff --git a/Classes/Mvc/View/JsonView.php b/Classes/Mvc/View/JsonView.php index 9e0a63b..565d5ea 100644 --- a/Classes/Mvc/View/JsonView.php +++ b/Classes/Mvc/View/JsonView.php @@ -39,10 +39,9 @@ class JsonView extends ExtbaseJsonView ], 'bookmarks' => [ '_descendAll' => [ - '_only' => [ - 'crdate', - 'title', - 'recordid' + '_exclude' => [ + 'uid', + 'pid', ], ] ] diff --git a/postman_collection.json b/postman_collection.json new file mode 100644 index 0000000..374fb85 --- /dev/null +++ b/postman_collection.json @@ -0,0 +1,136 @@ +{ + "info": { + "_postman_id": "6b24390e-c459-4be4-b38d-a531a8c64240", + "name": "SLUB - Profile Service - Bookmark (slub_profile_bookmark)", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", + "_exporter_id": "32157282" + }, + "item": [ + { + "name": "AppKey", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{domainCatalogue}}mein-konto/?type=1&tx_slubaccount_account[controller]=API&tx_slubaccount_account[action]=getBookmarksAppkey&L=0&tx_slubaccount_account[username]={{user}}&tx_slubaccount_account[password]=password", + "host": [ + "{{domainCatalogue}}mein-konto" + ], + "path": [ + "" + ], + "query": [ + { + "key": "type", + "value": "1" + }, + { + "key": "tx_slubaccount_account[controller]", + "value": "API" + }, + { + "key": "tx_slubaccount_account[action]", + "value": "getBookmarksAppkey" + }, + { + "key": "L", + "value": "0" + }, + { + "key": "tx_slubaccount_account[username]", + "value": "{{user}}" + }, + { + "key": "tx_slubaccount_account[password]", + "value": "password" + } + ] + } + }, + "response": [] + }, + { + "name": "List", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{domainCatalogue}}/merkliste/api/?type=1469315139&tx_slubfindbookmarks_bookmarklist[controller]=BookmarkList&tx_slubfindbookmarks_bookmarklist[action]=getBookmarks&tx_slubfindbookmarks_bookmarklist[user]={{user}}&tx_slubfindbookmarks_bookmarklist[appkey]={{appKey}}", + "host": [ + "{{domainCatalogue}}" + ], + "path": [ + "merkliste", + "api", + "" + ], + "query": [ + { + "key": "type", + "value": "1469315139" + }, + { + "key": "tx_slubfindbookmarks_bookmarklist[controller]", + "value": "BookmarkList" + }, + { + "key": "tx_slubfindbookmarks_bookmarklist[action]", + "value": "getBookmarks" + }, + { + "key": "tx_slubfindbookmarks_bookmarklist[user]", + "value": "{{user}}" + }, + { + "key": "tx_slubfindbookmarks_bookmarklist[appkey]", + "value": "{{appKey}}" + } + ] + } + }, + "response": [] + } + ], + "event": [ + { + "listen": "prerequest", + "script": { + "type": "text/javascript", + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ], + "variable": [ + { + "key": "user", + "value": "4998866", + "type": "default" + }, + { + "key": "domain", + "value": "https://ddev-slub-profile-service.ddev.site/", + "type": "default" + }, + { + "key": "domainCatalogue", + "value": "https://katalog.ddev.site/", + "type": "string" + }, + { + "key": "appKey", + "value": "6627b6fab58c1", + "type": "string" + } + ] +} \ No newline at end of file From d91efe58ec87f0f8dce2813178b370c965a490cf Mon Sep 17 00:00:00 2001 From: Andreas Pfeiffer Date: Thu, 25 Apr 2024 16:21:59 +0200 Subject: [PATCH 6/9] [BUGFIX] Empty result --- Classes/Service/BookmarkService.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/Service/BookmarkService.php b/Classes/Service/BookmarkService.php index a211637..3c5ddb1 100644 --- a/Classes/Service/BookmarkService.php +++ b/Classes/Service/BookmarkService.php @@ -58,6 +58,6 @@ public function getBookmarks(array $arguments): array $sanitizedArguments['appkey'] = $appKey; $uri = $this->uriGenerator->buildBookmarkList($sanitizedArguments); - return $this->request->process($uri) ?? []; + return $this->request->process($uri) ?? ['bookmarks' => []]; } } From 15265e1dbfdff184bb39f2af7b11c270d0e1e28e Mon Sep 17 00:00:00 2001 From: Andreas Pfeiffer Date: Fri, 3 May 2024 10:48:41 +0200 Subject: [PATCH 7/9] [TASK] Update api documentation --- postman_collection.json | 5 ----- 1 file changed, 5 deletions(-) diff --git a/postman_collection.json b/postman_collection.json index 374fb85..dd02741 100644 --- a/postman_collection.json +++ b/postman_collection.json @@ -117,11 +117,6 @@ "value": "4998866", "type": "default" }, - { - "key": "domain", - "value": "https://ddev-slub-profile-service.ddev.site/", - "type": "default" - }, { "key": "domainCatalogue", "value": "https://katalog.ddev.site/", From de5fb78e3317131166af10bad330d618e48374ad Mon Sep 17 00:00:00 2001 From: Andreas Pfeiffer Date: Wed, 12 Jun 2024 14:07:49 +0200 Subject: [PATCH 8/9] [TASK] Change to api authorization --- Classes/Controller/BookmarkController.php | 8 -- .../Model/Dto/ApiAppKeyConfiguration.php | 81 ------------------- .../Dto/ApiBookmarkListConfiguration.php | 18 +++++ Classes/Http/Request.php | 3 +- Classes/Routing/UriGenerator.php | 19 +---- Classes/Service/AppKeyService.php | 58 ------------- Classes/Service/BookmarkService.php | 12 +-- .../Private/Language/de.locallang_backend.xlf | 11 +-- .../Private/Language/locallang_backend.xlf | 10 +-- ext_conf_template.txt | 6 +- postman_collection.json | 81 ++----------------- 11 files changed, 36 insertions(+), 271 deletions(-) delete mode 100644 Classes/Domain/Model/Dto/ApiAppKeyConfiguration.php delete mode 100644 Classes/Service/AppKeyService.php diff --git a/Classes/Controller/BookmarkController.php b/Classes/Controller/BookmarkController.php index 2ce2028..f1832e4 100644 --- a/Classes/Controller/BookmarkController.php +++ b/Classes/Controller/BookmarkController.php @@ -38,14 +38,6 @@ public function __construct(BookmarkService $bookmarkService) public function listAction(): ResponseInterface { $arguments = $this->request->getArguments(); - /** - * IMPORTANT - * --------- - * The api to get the api key requires a password from the user we do not have. - * Well, fake the password and disable credential check at katalog service - * account extension via "plugin.tx_slubaccount.settings.debugapi". - */ - $arguments['password'] = 'password'; $bookmarks = $this->bookmarkService->getBookmarks($arguments); $this->view->setVariablesToRender(['bookmarkList']); diff --git a/Classes/Domain/Model/Dto/ApiAppKeyConfiguration.php b/Classes/Domain/Model/Dto/ApiAppKeyConfiguration.php deleted file mode 100644 index eb48eb3..0000000 --- a/Classes/Domain/Model/Dto/ApiAppKeyConfiguration.php +++ /dev/null @@ -1,81 +0,0 @@ -getConfiguration(ConstantsUtility::EXTENSION_KEY)[self::KEY]; - - empty($configuration['requestArgumentIdentifier']) ?: $this->setRequestArgumentIdentifier($configuration['requestArgumentIdentifier']); - empty($configuration['requestUri']) ?: $this->setRequestUri($configuration['requestUri']); - } - - /** - * @return string - */ - public function getRequestUri(): string - { - return $this->requestUri; - } - - /** - * @param string $requestUri - */ - public function setRequestUri(string $requestUri = ''): void - { - $this->requestUri = $requestUri; - } - - /** - * @return string - */ - public function getRequestArgumentIdentifier(): string - { - return $this->requestArgumentIdentifier; - } - - /** - * @param string $requestArgumentIdentifier - */ - public function setRequestArgumentIdentifier(string $requestArgumentIdentifier = ''): void - { - $this->requestArgumentIdentifier = $requestArgumentIdentifier; - } - - /** - * @param string $extensionKey - * @return array - */ - protected function getConfiguration(string $extensionKey = ''): array - { - /** @var ExtensionConfiguration $extensionConfiguration */ - $extensionConfiguration = GeneralUtility::makeInstance(ExtensionConfiguration::class); - - try { - return $extensionConfiguration->get($extensionKey); - } catch (Exception $e) { - return []; - } - } -} diff --git a/Classes/Domain/Model/Dto/ApiBookmarkListConfiguration.php b/Classes/Domain/Model/Dto/ApiBookmarkListConfiguration.php index 2d36959..d9651f3 100644 --- a/Classes/Domain/Model/Dto/ApiBookmarkListConfiguration.php +++ b/Classes/Domain/Model/Dto/ApiBookmarkListConfiguration.php @@ -20,6 +20,7 @@ class ApiBookmarkListConfiguration { public const KEY = 'bookmarkList'; + protected string $apiKey = ''; protected string $requestUri = ''; protected string $requestArgumentIdentifier = ''; @@ -27,10 +28,27 @@ public function __construct() { $configuration = $this->getConfiguration(ConstantsUtility::EXTENSION_KEY)[self::KEY]; + empty($configuration['apiKey']) ?: $this->setApiKey($configuration['apiKey']); empty($configuration['requestArgumentIdentifier']) ?: $this->setRequestArgumentIdentifier($configuration['requestArgumentIdentifier']); empty($configuration['requestUri']) ?: $this->setRequestUri($configuration['requestUri']); } + /** + * @return string + */ + public function getApiKey(): string + { + return $this->apiKey; + } + + /** + * @param string $apiKey + */ + public function setApiKey(string $apiKey = ''): void + { + $this->apiKey = $apiKey; + } + /** * @return string */ diff --git a/Classes/Http/Request.php b/Classes/Http/Request.php index 64658c3..ba357d2 100644 --- a/Classes/Http/Request.php +++ b/Classes/Http/Request.php @@ -84,7 +84,8 @@ protected function getContent(ResponseInterface $response, string $uri = ''): ?a { $content = ''; - if ($response->getStatusCode() === 200 && + if ( + $response->getStatusCode() === 200 && strpos($response->getHeaderLine('Content-Type'), 'application/json') === 0 ) { $content = (array)json_decode($response->getBody()->getContents(), true); diff --git a/Classes/Routing/UriGenerator.php b/Classes/Routing/UriGenerator.php index d9795c3..d7632b4 100644 --- a/Classes/Routing/UriGenerator.php +++ b/Classes/Routing/UriGenerator.php @@ -11,7 +11,6 @@ namespace Slub\SlubProfileBookmarks\Routing; -use Slub\SlubProfileBookmarks\Domain\Model\Dto\ApiAppKeyConfiguration; use Slub\SlubProfileBookmarks\Domain\Model\Dto\ApiBookmarkListConfiguration; use Slub\SlubProfileBookmarks\Utility\LanguageUtility; use TYPO3\CMS\Core\Context\Exception\AspectNotFoundException; @@ -33,21 +32,9 @@ public function buildBookmarkList(array $additionalParameters): string $requestUri = $apiConfiguration->getRequestUri(); $requestArgumentIdentifier = $apiConfiguration->getRequestArgumentIdentifier(); - return $this->build($requestUri, $requestArgumentIdentifier, $additionalParameters); - } - /** - * @param array $additionalParameters - * @return string - * @throws AspectNotFoundException - */ - public function buildAppKey(array $additionalParameters): string - { - /** @var ApiAppKeyConfiguration $apiConfiguration */ - $apiConfiguration = GeneralUtility::makeInstance(ApiAppKeyConfiguration::class); - - /** @extensionScannerIgnoreLine */ - $requestUri = $apiConfiguration->getRequestUri(); - $requestArgumentIdentifier = $apiConfiguration->getRequestArgumentIdentifier(); + if (!array_key_exists('apikey', $additionalParameters)) { + $additionalParameters['apikey'] = $apiConfiguration->getApiKey(); + } return $this->build($requestUri, $requestArgumentIdentifier, $additionalParameters); } diff --git a/Classes/Service/AppKeyService.php b/Classes/Service/AppKeyService.php deleted file mode 100644 index abd75be..0000000 --- a/Classes/Service/AppKeyService.php +++ /dev/null @@ -1,58 +0,0 @@ -request = $request; - $this->uriGenerator = $uriGenerator; - } - - /** - * @param int $username - * @param string $password - * @return string|null - * @throws AspectNotFoundException - */ - public function getAppKey(int $username, string $password): ?string - { - $uri = $this->uriGenerator->buildAppKey([ - 'username' => $username, - 'password' => $password, - ]); - $data = $this->request->process($uri); - - if ( - is_array($data) && - array_key_exists('appkey', $data) - ) { - return $data['appkey']; - } - - return null; - } -} diff --git a/Classes/Service/BookmarkService.php b/Classes/Service/BookmarkService.php index 3c5ddb1..b15dbbb 100644 --- a/Classes/Service/BookmarkService.php +++ b/Classes/Service/BookmarkService.php @@ -21,24 +21,20 @@ class BookmarkService protected BookmarkArgumentSanitization $bookmarkArgumentSanitization; protected Request $request; protected UriGenerator $uriGenerator; - protected AppKeyService $appKeyService; /** * @param BookmarkArgumentSanitization $bookmarkArgumentSanitization * @param Request $request * @param UriGenerator $uriGenerator - * @param AppKeyService $appKeyService */ public function __construct( BookmarkArgumentSanitization $bookmarkArgumentSanitization, Request $request, - UriGenerator $uriGenerator, - AppKeyService $appKeyService + UriGenerator $uriGenerator ) { $this->bookmarkArgumentSanitization = $bookmarkArgumentSanitization; $this->request = $request; $this->uriGenerator = $uriGenerator; - $this->appKeyService = $appKeyService; } /** @@ -49,13 +45,7 @@ public function __construct( public function getBookmarks(array $arguments): array { $sanitizedArguments = $this->bookmarkArgumentSanitization->sanitizeArguments($arguments); - $appKey = $this->appKeyService->getAppKey($sanitizedArguments['user'], $arguments['password']); - if ($appKey === null) { - return []; - } - - $sanitizedArguments['appkey'] = $appKey; $uri = $this->uriGenerator->buildBookmarkList($sanitizedArguments); return $this->request->process($uri) ?? ['bookmarks' => []]; diff --git a/Resources/Private/Language/de.locallang_backend.xlf b/Resources/Private/Language/de.locallang_backend.xlf index e925791..a46d62f 100644 --- a/Resources/Private/Language/de.locallang_backend.xlf +++ b/Resources/Private/Language/de.locallang_backend.xlf @@ -25,14 +25,9 @@ Argument identifier: The parameter needs to be written in a specific identifier. Default value "tx_slubfindbookmarks_bookmarklist". Change only if you know what you do. Parameter ID: Die Parameter benötigen einen spezifischen Container. Default-Wert "tx_slubfindbookmarks_bookmarklist". Nur ändern, wenn wirklich notwendig. - - - URI: The uri has to begin with "https://". Another DDEV container can be addressed directly via the container with "https: // ddev - ### YOUR-CONTAINER ### - web" or the domain, if configured "external_links". - URI: Die URI muss mit "https://" anfangen. Ein anderer DDEV-Container kann direkt über den Container mit "https://ddev-###YOUR-CONTAINER###-web" angesprochen werden oder die Domain, wenn "external_links" konfiguriert. - - - Argument identifier: The parameter needs to be written in a specific identifier. Default value "tx_slubaccount_account". Change only if you know what you do. - Parameter ID: Die Parameter benötigen einen spezifischen Container. Default-Wert "tx_slubaccount_account". Nur ändern, wenn wirklich notwendig. + + API key + API Schlüssel diff --git a/Resources/Private/Language/locallang_backend.xlf b/Resources/Private/Language/locallang_backend.xlf index 5f781f9..8592afc 100644 --- a/Resources/Private/Language/locallang_backend.xlf +++ b/Resources/Private/Language/locallang_backend.xlf @@ -20,14 +20,8 @@ Argument identifier: The parameter needs to be written in a specific identifier. Default value "tx_slubfindbookmarks_bookmarklist". Change only if you know what you do. - - - URI: The uri has to begin with "https://". Another DDEV container can be addressed directly via the container with "https: // ddev - ### YOUR-CONTAINER ### - web" or the domain, if configured "external_links". - URI: Die URI muss mit "https://" anfangen. Ein anderer DDEV-Container kann direkt über den Container mit "https://ddev-###YOUR-CONTAINER###-web" angesprochen werden oder die Domain, wenn "external_links" konfiguriert. - - - Argument identifier: The parameter needs to be written in a specific identifier. Default value "tx_slubaccount_account". Change only if you know what you do. - Parameter ID: Die Parameter benötigen einen spezifischen Container. Default-Wert "tx_slubaccount_account". Nur ändern, wenn wirklich notwendig. + + API key diff --git a/ext_conf_template.txt b/ext_conf_template.txt index 1e7c6de..a3085ee 100644 --- a/ext_conf_template.txt +++ b/ext_conf_template.txt @@ -4,8 +4,6 @@ bookmarkList.requestUri = # cat=API bookmark list; type=string; label=LLL:EXT:slub_profile_bookmarks/Resources/Private/Language/locallang_backend.xlf:extensionConfiguration.bookmarkList.requestArgumentIdentifier bookmarkList.requestArgumentIdentifier = tx_slubfindbookmarks_bookmarklist -# cat=API app key; type=string; label=LLL:EXT:slub_profile_bookmarks/Resources/Private/Language/locallang_backend.xlf:extensionConfiguration.appKey.requestUri -appKey.requestUri = +# cat=API bookmark list; type=string; label=LLL:EXT:slub_profile_bookmarks/Resources/Private/Language/locallang_backend.xlf:extensionConfiguration.bookmarkList.apiKey +bookmarkList.apiKey = -# cat=API app key; type=string; label=LLL:EXT:slub_profile_bookmarks/Resources/Private/Language/locallang_backend.xlf:extensionConfiguration.appKey.requestArgumentIdentifier -appKey.requestArgumentIdentifier = tx_slubaccount_account diff --git a/postman_collection.json b/postman_collection.json index dd02741..626a2d5 100644 --- a/postman_collection.json +++ b/postman_collection.json @@ -6,85 +6,19 @@ "_exporter_id": "32157282" }, "item": [ - { - "name": "AppKey", - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "{{domainCatalogue}}mein-konto/?type=1&tx_slubaccount_account[controller]=API&tx_slubaccount_account[action]=getBookmarksAppkey&L=0&tx_slubaccount_account[username]={{user}}&tx_slubaccount_account[password]=password", - "host": [ - "{{domainCatalogue}}mein-konto" - ], - "path": [ - "" - ], - "query": [ - { - "key": "type", - "value": "1" - }, - { - "key": "tx_slubaccount_account[controller]", - "value": "API" - }, - { - "key": "tx_slubaccount_account[action]", - "value": "getBookmarksAppkey" - }, - { - "key": "L", - "value": "0" - }, - { - "key": "tx_slubaccount_account[username]", - "value": "{{user}}" - }, - { - "key": "tx_slubaccount_account[password]", - "value": "password" - } - ] - } - }, - "response": [] - }, { "name": "List", "request": { "method": "GET", "header": [], "url": { - "raw": "{{domainCatalogue}}/merkliste/api/?type=1469315139&tx_slubfindbookmarks_bookmarklist[controller]=BookmarkList&tx_slubfindbookmarks_bookmarklist[action]=getBookmarks&tx_slubfindbookmarks_bookmarklist[user]={{user}}&tx_slubfindbookmarks_bookmarklist[appkey]={{appKey}}", + "raw": "{{domain}}/merkliste/{{user}}", "host": [ - "{{domainCatalogue}}" + "{{domain}}" ], "path": [ "merkliste", - "api", - "" - ], - "query": [ - { - "key": "type", - "value": "1469315139" - }, - { - "key": "tx_slubfindbookmarks_bookmarklist[controller]", - "value": "BookmarkList" - }, - { - "key": "tx_slubfindbookmarks_bookmarklist[action]", - "value": "getBookmarks" - }, - { - "key": "tx_slubfindbookmarks_bookmarklist[user]", - "value": "{{user}}" - }, - { - "key": "tx_slubfindbookmarks_bookmarklist[appkey]", - "value": "{{appKey}}" - } + "{{user}}" ] } }, @@ -118,13 +52,8 @@ "type": "default" }, { - "key": "domainCatalogue", - "value": "https://katalog.ddev.site/", - "type": "string" - }, - { - "key": "appKey", - "value": "6627b6fab58c1", + "key": "domain", + "value": "https://ddev-slub-profile-service.ddev.site/", "type": "string" } ] From 35801321da8cbfb3c0cf4a7b9269f5f0d5fbcdb6 Mon Sep 17 00:00:00 2001 From: Andreas Pfeiffer Date: Wed, 18 Dec 2024 10:32:00 +0100 Subject: [PATCH 9/9] [TASK] Remove versioning from documentation --- README.md | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 2a7df1d..4f772f6 100644 --- a/README.md +++ b/README.md @@ -16,36 +16,26 @@ Run the following command within your Composer based TYPO3 project: composer require slub/slub-profile-bookmarks ``` -## 2 Administration corner - -### 2.1 Release Management - -News uses [semantic versioning][2], which means, that -* **bugfix updates** (e.g. 1.0.0 => 1.0.1) just includes small bugfixes or security relevant stuff without breaking changes, -* **minor updates** (e.g. 1.0.0 => 1.1.0) includes new features and smaller tasks without breaking changes, -* **major updates** (e.g. 1.0.0 => 2.0.0) breaking changes wich can be refactorings, features or bugfixes. - -## 3 API +## 2 API This extension communicates with another system to provide bookmarks. -### 3.1 Routes +### 2.1 Routes Please check the routes' configuration. You have to set the matching page (limitToPages). If not the routes will not work properly. -### 3.2 Bookmarks +### 2.2 Bookmarks A list of bookmarks from a given user. - **Uri DDEV local:** https://ddev-slub-profile-service.ddev.site/merkliste/###USER_ID### - **Uri general:** https://###YOUR-DOMAIN###/merkliste/###USER_ID### -#### 3.2.1 Extension configuration +#### 2.2.1 Extension configuration - **Uri:** Address or domain to request the data. The uri has to begin with "https://". If you connect to another ddev container, please use "https://ddev-###YOUR-CONTAINER###-web". - **Argument identifier:** When you request data from this extension to the bookmark api (external extension), you use additional parameters too. These parameters are wrapped with the "argument identifier". The default value is "tx_slubfindbookmarks_bookmarklist". Change only if you know what you do. [1]: https://getcomposer.org/ -[2]: https://semver.org/