Git Product home page Git Product logo

sourcebroker / t3api Goto Github PK

View Code? Open in Web Editor NEW
31.0 11.0 17.0 4.34 MB

TYPO3 extension t3api. REST API for your TYPO3 project. Config with annotations, built in filtering, pagination, typolinks, image processing, uploads (FAL), serialization contexts, responses in Hydra/JSON-LD format.

License: Other

PHP 94.57% HTML 0.06% Shell 5.19% CSS 0.05% JavaScript 0.13%
typo3-extension typo3-cms-extension rest-api rest hydra json-ld

t3api's Introduction

TYPO3 Extension t3api

https://poser.pugx.org/sourcebroker/t3api/v/stable https://scrutinizer-ci.com/g/sourcebroker/t3api/badges/quality-score.png?b=master

Features

  • Support for Extbase models with GET, POST, PATCH, PUT, DELETE operations.
  • Configuration with classes, properties and methods annotations.
  • Build-in filters: boolean, numeric, order, range and text (partial, match against and exact strategies).
  • Build-in pagination.
  • Support for typolinks.
  • Support for image processing.
  • Support for file uploads (FAL).
  • Configurable routing.
  • Responses in Hydra /JSON-LD format.
  • Serialization contexts - customizable output depending on routing.
  • Easy customizable serialization handlers and subscribers.
  • Backend module with Swagger for documentation and real testing.

Documentation

Read the docs at https://docs.typo3.org/p/sourcebroker/t3api/master/en-us/

Take a look and test

After cloning repo you can run ddev restart && ddev composer install and then ddev ci 12 to install local integration test instance. Local instance is available at https://12.t3api.ddev.site/ (login to backend with admin / Password1! credentials).

At frontend part you can at once test REST API responses for ext news:

You can also run Postman test with ddev ci:tests:postman command or full test suite with ddev composer ci. Postman is doing full CRUD test with category and news (with image).

Development

If you want to help with development take a look at https://docs.typo3.org/p/sourcebroker/t3api/main/en-us/Miscellaneous/Development/Index.html

t3api's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

t3api's Issues

Table mapping doesn't work on Typo3 9.5.19

Table mapping doesn't seem to work with T3api on Typo3 9.5.19

I've tried with my own extension and t3apinews. In both cases I get the response: "Table XYZ doesn't exist" when I'm using the api.
Typo3 backend-records works as expected.

{
  "hydra:title": "Table 'kas_imh.tx_t3apinews_domain_model_news' doesn't exist",`
  "hydra:code": 1472074485,
  "hydra:description": "Table 'kas_imh.tx_t3apinews_domain_model_news' doesn't exist"
}

Right now I'm trying my luck with Typo3 10.4 wich seems to work.

Additional ApiResource Type for Lists

I really appreciate your library as it provides an easy way to define an API with Swagger definition for paged return types (Hydra) and individual entries. Nevertheless, it would be very helpful to have also a simple list as return type. It is already possible to achieve this by simply returning an array in the OperationHandler, but it is not possible to define the corresponding ApiResource to get the correct Swagger definition (without paging attributes and the correct return type). For example, such an ApiResource could be called "listOperations".

My question now is, would it be in your interest to add this function to your library? If it is possible I would be willing to help as well.

Migrate from TYPO3's signal slots to PSR-14 events

TYPO3's Signal slots are deprecated since TYPO3 v10 and will be completely removed on TYPO3 v12. It means that some features of t3api won't work anymore. We are using signal slots in following places:

  • \SourceBroker\T3api\Security\OperationAccessChecker::isGranted
  • \SourceBroker\T3api\Security\OperationAccessChecker::isGrantedPostDenormalize
  • \SourceBroker\T3api\Dispatcher\AbstractDispatcher::processOperation
  • \SourceBroker\T3api\OperationHandler\AbstractOperationHandler::deserializeOperation
  • \SourceBroker\T3api\Security\FilterAccessChecker::isGranted
  • \SourceBroker\T3api\Serializer\ContextBuilder\AbstractContextBuilder

We are also utilizing one of the signal slot inside following classes:

  • SourceBroker\T3api\Slot\AddHydraCollectionResponseSerializationGroup
  • SourceBroker\T3api\Slot\EnrichSerializationContext

Within this task we need to:

  • Replace signal slots with PSR-14 events
  • Change t3api's internal signal slot connections to event listeners (AddHydraCollectionResponseSerializationGroup and EnrichSerializationContext)
  • Remove all constants with signal slot names
  • Replace documentation about signal slots with events

Support for Typo3 12 and PHP 8.2

Typo3 12 (LTS) and PHP 8.2 should be supported, too. Otherwise it would be strange that t3api is mentioned in the official Typo3 documentation and without any hints about T3 v12.

Security for Ressources

Hello,
i want to secure my API. Unfortunately the documentation for Security is missing.
Can someone show me some Examples or help me here?

Thanks!

Improve and refactor loader for API Resource classes

Currently path of API Resource classes is not configurable. There is hardcoded path Classes/Domain/Model/*.php of loaded extensions (see \SourceBroker\T3api\Domain\Repository\ApiResourceRepository::getAllDomainModels). Although it's probably enough for most of use cases, hardcoded part makes it impossible to write tests. This task is about refactoring this part of code to make it possible to write tests.
Moreover within this task t3api should start to include also subfolders of Classes/Domain/Model when looking for API Resources.

  • Make API Resource path configurable.
  • Include subfolders of Classes/Domain/Model when searching for API Resource.
  • Write unit/functional tests.
  • Write documentation how to customise API Resource path.

Remove keys from slots argument - afterProcessOperation, afterDeserializeOperation

Some slots has been fixed in t3api 2.0.0. but some (afterProcessOperation, afterDeserializeOperation) have still assoc array in passed argument and this is not possible now for TYPO3 11. This throws fatal error.

If someone upgraded to t3api 2.0.0 and used that not yet fixed slots he would see the problem at once.
Therefore this issue is treated as bugfix and not as breaking change.

Question: how to add custom filter unrelated to a query parameter

I have the following scenario: I'm using t3api in a project where some API consumers have more right than others. Each record has a kind of visibility flag, which may indicate either that the record is public or that is has restricted access. Access to the API requires a valid FE user, identified using an API key passed in the HTTP headers.

A FE user may be allowed to access restricted records of any table. So what I'm trying to do is to add a filter that would set a condition on the records depending on the FE user rights: namely, if the user is not allowed to access restricted records, then such records should not be fetched from the repository and returned.

I have tried various strategies without success so far, in part due to the documentation being missing on topics like security. My latest try is to use a custom filter, which I add to the operation by adding a custom operation for collections, extending and overriding \SourceBroker\T3api\OperationHandler\CollectionGetOperationHandler. This nearly works, but my custom filter gets removed by this call (in \SourceBroker\T3api\Domain\Repository\CommonRepository::findFiltered()):

$apiFilters = $this->filterAndSortApiFiltersByQueryParams($apiFilters, $queryParams);

because the flag that I want to check is not a query parameter. I understand the logic of dropping filters that are related to a query parameter when said parameter is not defined, but is there a way to preserve a filter, without relating it to a query parameter?

Or is there another way to achieve what I'm trying to do?

Thanks in advance for any help.

API site-config entry other than "/" resulting in "RuntimeException: Route enhancer `T3apiResourceEnhancer` is not defined"

If we have 2 root-pages (e.g. one for the website, another one for the API), with the "website" site-config entry defined as "/" (base URL) and the "api" site-config entry defined as "/v1", the following exception is thrown (backend and frontend):

Route enhancer T3apiResourceEnhancer is not defined. You need to add it to your site configuration first. See example configuration in PHP doc of SourceBroker\T3api\Routing\Enhancer\ResourceEnhancer.

Typo3 10.4 site identifier "main"

t3api\Classes\Dispatcher\Bootstrap.php

->getSiteByIdentifier('main')

May be this could be added to the documentation, that the site identifier has to be called "main". I have been struggling with that in Typo3 10.4 ... but somehow not in 9.5.x?

PHP Warning: Undefined array key "cacheCmd" in SerializerService.php

The following exception is thrown in the backend after editing a custom domain record (on save):

#1476107295 TYPO3\CMS\Core\Error\Exception

PHP Warning: Undefined array key "cacheCmd" in /var/www/html/public/typo3conf/ext/t3api/Classes/Service/SerializerService.php line 93

The $params variable looks like this (array key cacheCmd does not exist):

array (
  'table' => 'my_domain_table',
  'uid' => 540,
  'uid_page' => 58,
  'TSConfig' => 
  array (
    // ...
  ),
  'tags' => 
  array (
    'pageId_58' => true,
    'my_domain_table' => true,
    'my_domain_table_540' => true,
  ),
  'clearCacheEnabled' => true,
)

Fix in line 93

if (in_array(($params['cacheCmd'] ?? ''), ['all', 'system'])) {

System:
TYPO3: v11.5.17
PHP: v8.0
T3API: v2.0.1

Feature: adding @type attribute by core

Similar to @id property which is shown by default in each response, I'm asking if it make sense to have a @type property as well filled with the entity class name. Sure, its easy to implement on a project level, but as it seems to be a quite common property for JSON-LD+Hydra, I'd suggest to implement this into core. Example response:

{
   "@id": "/api/v1/blog/post", // optional, not really needed
   "@type": "HydraCollectionResponse", // optional, added from class-name to always have the same format
   "hydra:member": [
      {
         "name": "Blog post 1",
         "@id": "/api/v1/blog/post/1",
         "@type": "Post" // this would be useful for front-end devs (using model class-name as type)
      }, {
         "name": "Blog post 2",
         "@id": "/api/v1/blog/post/2",
         "@type": "Post"
      }
   ],
   "hydra:totalItems": 2,
   "hydra:view": {
      "hydra:first": "/api/v1/blog/post?page=1",
      "hydra:last": "/api/v1/blog/post?page=1",
      "hydra:pages": ["/api/v1/blog/post?page=1"],
      "hydra:page": 1
   },
   "hydra:search": {
      "hydra:template": "/api/v1/blog/post{?}",
      "hydra:mapping": []
   }
}

Edit: Maybe the full FQDN is better, as an entity with the same name might exist in different namespaces/contexts.

Add support for `cacheHash.enforceValidation` set to `true`

In TYPO3 releases 10.4.35 and 11.5.23 an important change has been made into cHash validation within commit 5e1585ea790209d7967c562735e8003c608347bb. More details about it can be found on TYPO3 Forge's issue #95297. The most important thing from t3api extension point of view is that new setting was introduced ($GLOBALS['TYPO3_CONF_VARS']['FE']['cacheHash']['enforceValidation']) and when it's set to true for all API requests following error is thrown:

Request parameters could not be validated (&cHash empty)

Although default value for cacheHash.enforceValidation is false (see Configuration/DefaultConfiguration.php in TYPO3 core) it's done only for a backward compatibility. Whenever new project is started (e.g. with typo3cms install:setup) value of this setting is set to true inside typo3conf/LocalConfiguration.php which makes API requests are failing.

References:
https://docs.typo3.org/m/typo3/reference-coreapi/main/en-us/ApiOverview/CachingFramework/Index.html#confval-enforceValidation
https://forge.typo3.org/issues/95297
TYPO3/typo3@5e1585e

Feature: using an alias column as identifier for endpoints

Don't know how difficult this is, but creating an alias for certain endpoints could be a useful core feature. As example:

Lets say we have endpoints for pages or custom products-records. Instead of requesting /pages/123 or /products/987, it would be useful if e.g. the slug attribute of the records could be used as alias for ID.

Reason: currently, if a front-end wants to use SEO friendly URLs like /show/demo-item, it has to query for all products, loop through the result array, find the record matching demo-item, get the corresponding ID and request the API again to get the product details (the mapping happens on front-end side).

Maybe a TypeConverter can be used (see here and here) or the ID field can be selected with a condition:

IF {alias} is not empty THAN query by {alias} == {id}
ELSE query by uid == {id} (current implementation)
     itemOperations={
          "get"={
              "method"="GET",
              "path"="/pages/{id}",
              "alias"="slug",
          },
     },

Not sure if a REST API should be made for such things in general, please see it only as suggestion, discussion welcomed :)

The child-references of a record are not marked as deleted if enableCascadingDelete is TRUE

Lets say we have the following record relation: a book (parent) has multiple chapters (children), defined like this:

TCA configuration:

//book.php
      'ctrl' => [
        'delete' => 'deleted',
      ],
      'columns' => [
        'chapters' => [
            'config' => [
                'type' => 'inline',
                'foreign_table' => 'chapter',
                'foreign_field' => 'book_uid',
                'maxitems' => 9999,
                'behaviour' => [
                    'enableCascadingDelete' => TRUE,
                ],
            ],
        ],
      ],

//chapter.php
      'ctrl' => [
        'delete' => 'deleted',
      ],

Model: Book.php

/**
 * @T3api\ApiResource(
 *     itemOperations={
 *          "delete"={
 *              "method"="DELETE",
 *              "path"="/book/{id}",
 *          },
 *     },
 * )
 */
class Book extends AbstractEntity {
    /**
     * @var ObjectStorage<Chapter>
     * @T3api\Serializer\Groups({
     *     "api_book_post_collection",
     * })
     * @T3api\ORM\Cascade("persist")
     */
    protected $chapters;
}

The request DELETE /api/book/123 will set deleted=1 for parent record 123, but not for the child-records.
Instead, if the record 123 is deleted in the TYPO3 backend list view, also the child-records are marked as deleted.

I tried it also with the replaced annotation @T3api\ORM\Cascade("delete") but with the same result.

Drop support for TYPO3 <= 9.4.99

Here is the quick list of usages version_compare function to check if TYPO3 version is <= 9.4.99. All of these places has to be cleaned up.

  • \SourceBroker\T3api\Annotation\Serializer\Type\PasswordHash::__construct
  • \SourceBroker\T3api\Security\AbstractAccessChecker::shouldUseLegacyCheckMethod and all usages
  • \SourceBroker\T3api\Service\RouteService::getApiBasePath
  • \SourceBroker\T3api\Service\RouteService::getDefaultLanguageBasePath
  • \SourceBroker\T3api\Service\SerializerService::getSerializerCacheDirectory
  • \SourceBroker\T3api\Service\SerializerService::getAutogeneratedMetadataDirectory
  • ext_localconf.php

FileReference with broken link breaks API

If you have a model which has a list of FileReferences, then a missing file will cause the parent object to fail being loaded.

A fileReference with a missing/broken link will throw an Exception, not just report a broken link. This might be good behavier some places, but it does block the API from ever fixing the missing/broken link.

Tested with 1.2.3 and branch:issue-22 for TYPO3 10.4

Order of extension installation matters for adding custom "serializerMetadataDirs" config

The order of extension installation matters for adding custom serializerMetadataDirs config in ext_localconf.php. The generated PackageStates.php loads the extension in the order how they was installed, e.g.:

        'my_extension' => [
            'packagePath' => 'typo3conf/ext/my_extension/',
        ],
        't3api' => [
            'packagePath' => 'typo3conf/ext/t3api/',
        ],
        't3apinews' => [
            'packagePath' => 'typo3conf/ext/t3apinews/',
        ],

If we define serializerMetadataDirs in my_extension/ext_localconf.php, the value is overwritten as soon as t3api loads. You can see/test this behavior if you manually move up t3apinews before t3api in the PackageStates array.

Solution / Fix:
The configuration in t3api/ext_localconf.php should also use array_merge() to merge values from prior loaded extensions:

	$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['t3api']['serializerMetadataDirs'] = array_merge(
		$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['t3api']['serializerMetadataDirs'] ?? [], [
			't3api' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath('t3api') . 'Resources/Private/Serializer/Metadata',
		]
	);

This applies also to all other config values like serializerHandlers or serializerSubscribers which might be extended in own extensions!

System:
TYPO3 v10.4.6
T3api v1.0.6
PHP 7.4

Add domain validators support for TYPO3 10+

Since TYPO3 10.0 domain validators are not automatically registered anymore (ref). Now every domain validator needs to be registered manually in controller annotations.

t3api validation was relaying on this automatically registered validators. It means it is needed to implement possibility to register validators. To keep consistency with TYPO3 core domain validators, which are registered per controller's action, validators in t3api should be registered per operations.

Method `getPublicUrl` can return `null` within `\SourceBroker\T3api\Serializer\Handler\FileReferenceHandler::serialize`

At line 112 within class \SourceBroker\T3api\Serializer\Handler\FileReferenceHandler the PHP method parse_url can be called with null value.

These lead to an TypeError.

parse_url() expects parameter 1 to be string, null given

TypeError thrown in file
/var/www/vagrant/releases/20200923061840/typo3conf/ext/t3api/Classes/Serializer/Handler/FileReferenceHandler.php in line 113.

The public url is null, if file is missing in the system.

Wrong URL generation when using subpath in base URL

Hey, great extension, love it!

I encountered a problem in the API route generation (getFullApiBaseUrl) and TypoLinkHandler when using a subpath in the base of site configuration:

base: 'https://my-site.ddev.site/suffix/'
languages:
  -
    title: English
    languageId: 0
    base: /

The generated API url becomes: https://my-site.ddev.site/suffix/suffix/_api/something, accessing it leads to a 404.

I guess the problem for the API route is in getDefaultLanguageBasePath, which returns /suffix/ however it should be /. I don't know why the base of the default SiteLanguage equals the base of the Site, maybe the configuration should be used instead?

The TypolinkHandler has a quite similar problem: Both parameters used in UrlService::forceAbsoluteUrl contain the suffix.

Can you reproduce and confirm the issue?

Bug: 500 response is missing CORS header

If an exception occurs, for example a custom operation-handler returns a wrong object type, the resulting 500 response is missing CORS headers. If the requesting front-end is running under another domain (e.g. during development http://localhost:8080/), the whole response incl. a possible error message is hided by the browser, which makes it very difficult to debug.

Possible solution: Also responses from the exception catch() blocks in SourceBroker\T3api\Dispatcher\Bootstrap::process() should call the processors $this->callProcessors(). Maybe this applies only for exceptions from the catch (Throwable $throwable) block.

Implement support for CORS

  • Make CORS configurable
  • Add support for preflight request

This feature should be started with changes already done on issue-7 branch. It contains a huge refactor of AbstractDispatcher which will be soon merged to master branch.

Improvement: Serializer CurrentFeUser() and Exclude() can not be combined

The following is not really an issue in the sense of malfunction, but more about logic or "cleanness".

Lets say we have the endpoints /api/notes and /api/notes/{id} which acting on all CRUD operations. The records created by this endpoints always belonging to the current user, so the CurrentFeUser() serializer is used on a $user attribute. In this way, the user property is always shown in the response data-structure, which is "useless" as it is always the user itself.

Adding Exclude() to the property does not work, as it disables all serialization and will return NULL for getUser() than (which is expected, sure!). Also using serialization-groups doesn't work, as the $user attribute could be omitted in collection and item GET responses, but has to be set for POST and PUT (other wise user is NULL again). The latter case would make trouble in the front-end code as well, as the object structure varies (user attribute is sometimes there, sometimes not)

For now we keep the user attribute in all responses and ignore it in the front-end. Like I said, its not an issue, but maybe an improvement for a later versions. Maybe it is even possible, that the property where CurrentFeUser() is used on excludes itself in the response (but will be there for the internal database handling). If someone really wants to include the user, an explicit Include() needs to be set or so...

Write spec to file

It would be nice to have the option to save the generated spec to file. This would enable further processing, e.g. generating types.

Default sorting for ApiResource

At the moment it's possible to apply sorting for collection response using the OrderFilter but it requires query parameter to have effect. Within this task we need to implement possibility to configure default sorting for ApiResource. It should be possible to define general sorting (for all collection operations) and override it for specific operations (it the same way as we do with other settings like pagination or persistence).

Related discussion: #59

Localization improvement

I use the branch "typo3-115-support" in a TYPO3 v11 installation.
This works fine, but I have some problems with the "x-locale" header.

Not all content is translated correctly. For example urls are not translated and always point to the default language.
Also, in the API URL the prefix of the default language is always visible e.g. "example.com/en/_api/...". However, this is just an inconvenience.

Suggested solution:
There are two ways how to set the language correctly:

  • Using "x-locale" header, then there is no need for language prefix in API url. e.g. "example.com/_api/..."
  • With language prefix in API url. e.g. "example.com/en/_api/..." , "example.com/it/_api/..."

I think it would be better to set the language not in the "Language Processor" but in a separate middleware before the TSFE initialization.
This will fix the translation problem and set the language correctly in the TSFE and in the request.
I made some changes in a fork of the typo3-115 branch, so that by default the LanguagePrefix is removed from the API url.
The language can be set using "x-locale" header.
It also still works for backwards compatibility API Urls with LanguagePrefix.
The x-locale header only responds to the default language.

For me this solution works fine, but I am not sure if this is the best solution.

It would be helpful if this functionality could be added to the extension.

Uncaught TYPO3 Exception: Return value of SourceBroker\T3api\Service\RouteService::getSite()

My setup is: Typo3 9.5.22 with solr 11.0.3 and t3api 1.1.0
When I do a solr indexing job in the scheduler I get this error - but only if the t3api is installed and running:
Core: Exception handler (CLI): Uncaught TYPO3 Exception: Return value of SourceBroker\T3api\Service\RouteService::getSite() must be an instance of TYPO3\CMS\Core\Site\Entity\Site, null returned

I simply cant find what the problem is - can you help here?

solr-indexing-fejl

TYPO3 11 Compatibility

Do you have plans to make this extension compatible with TYPO3 11? If so, when do you plan a release?

TCA configuration "sortby" has no effect for tt_content related items

There is a strange issue if we create custom content-elements (based on tt_content) where child-items having an own relation table. Also the TCA config for these child-items has 'sortby' => 'sorting' set, the given sort-by column is ignored and the output is sorted by UID (default behavior). Custom entities with child-items are not effected, which is really strange.

I created a demonstration to show the issue (it's a fork of t3apicontent, the code is on branch issue/content-sorting).

Install / Preparation

  1. Start the t3apidemo (with clean default database)
  2. Add the t3apicontent extension of my fork-repository to the composer.json of t3apidemo and checkout the branch issue/content-sorting:
{
  "config": {
    "preferred-install": {
      "moongazer/t3apicontent": "source"
    },
  },
  "repositories": [
    {
      "type": "vcs",
      "url": "https://github.com/Moongazer/t3apicontent.git"
    }
  ],
  "require": {
    "moongazer/t3apicontent": "dev-master"
  },
}
  1. Import the SQL which you will find inside the README

Issue

Browse to https://t3apidemo.ddev.site:444/_api/content/pages/8 which will respond the following structure (see the items array where the elements are sorted by their UID 1, 2 and 3):
t3apicontent1

In the backend the elements are sorted into a certain order:
t3apicontent2

Bug: Serializer TypolinkHandler can not handle absolute URLs

If an absolute URL is set for a link-attribute like an external URL or mail-link, the Classes/Serializer/Handler/TypolinkHandler.php concatenates the current TYPO3_SITE_URL with the given (absolute) $typolinkParameter.

To fix it, I'd suggest to test the $typolinkParameter if it's a TYPO3 URN t3://, if not it is considered as absolute URL which does not need further processing:

    public function serialize(
        SerializationVisitorInterface $visitor,
        $typolinkParameter,
        array $type,
        SerializationContext $context
    ) {
        if (!empty($typolinkParameter) && !preg_match('/^t3:\/\/.*$/', $typolinkParameter)) {
            return $typolinkParameter;
        } else {
            return rtrim($context->getAttribute('TYPO3_SITE_URL'), '/') . $this->getContentObjectRenderer()->getTypoLink_URL(...(array)$typolinkParameter);
        }
    }

t3api is downgrading symfony/cache v6

t3api has dependency to

"symfony/cache": "^4.4 || ^5.0",

TYPO3 11 in default config resolve dependency to symfony/cache to v6.

When installing t3api symfony/cache version in TYPO3 11 is downgraded to v5

Solution. Add dependency to v6 with.

"symfony/cache": "^4.4 || ^5.0 || ^ 6.0",

Drop FileReferenceHandler and FileReferenceSubscriber by default - use JMS to handle FileReference

Currently t3api uses FileReferenceHandler and FileReferenceSubscriber for the serialisation of FileReference. However, it might be more efficient and straightforward to let the JMS serialiser handle the serialisation of FileReference directly.

Benefits of this approach is simplicity. By allowing the JMS serialiser to handle FileReference directly, we can reduce the complexity of our codebase by removing the FileReferenceHandler and FileReferenceSubscriber.

This is breaking change as structure of FileReference will change however a simple backward compatibility fix is easy.
Just register old handler and subscriber in some of your local extension like this:

$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['t3api']['serializerSubscribers'][] = \SourceBroker\T3api\Serializer\Subscriber\FileReferenceSubscriber::class;
$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['t3api']['serializerHandlers'][] = \SourceBroker\T3api\Serializer\Handler\FileReferenceSubscriber::class;

Steps:

  • Remove declaration of FileReferenceSubscriber and FileReferenceSubscriber from $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['t3api']['serializerSubscribers'], $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['t3api']['serializerHandlers']
  • Test FileReference read / add / remove.
  • Write backward compatibility note.
  • Write documentation about YAML level configuration for FileReference and File.

Implement possibility to customize operation handlers

At the moment operation handling is hardcoded inside \SourceBroker\T3api\Dispatcher\AbstractDispatcher. It causes two issues:

  • It is not possible to customize operation handlers.
  • It increases complexity of \SourceBroker\T3api\Dispatcher\AbstractDispatcher while this class should only dispatch appropriate handler instead of execute it.

Customization of operation handler may be really useful. One of basic examples of its usage could be response with logged user data available via route without ID (e.g. /users/current). At the moment such route is not supported because it is needed to pass ID as route param to execute the item operation.

Here is the list of the points which should be achieved when this issue is resolved:

  • Interface for Operation should be created and it should be used in type hinting instead of \SourceBroker\T3api\Domain\Model\AbstractOperation class.
  • \SourceBroker\T3api\Dispatcher\AbstractDispatcher should be refactored
    • Operations handling should be moved to separate classes.
    • Signals \SourceBroker\T3api\Dispatcher\AbstractDispatcher::SIGNAL_AFTER_DESERIALIZE_OPERATION and \SourceBroker\T3api\Dispatcher\AbstractDispatcher::SIGNAL_AFTER_PROCESS_OPERATION should be marked as deprecated and moved to more appropriate place.
  • Operation handlers should be prioritizable.
  • It should be possible to add custom operation handlers (also capable of prioritization).
  • Documentation should be updated and new features should be described.
  • Tests for the operation handling should be added (at the moment there are no tests for operations at all).

Allow to define exceptions per serialised object that do not throw error on serialisation

In current serialization process, any exceptions that occur during the serialization of an object result in an error being thrown. This will interrupt the serialization process and return JSON with error. To improve this, we propose to allow the definition of specific exceptions for each serialized object that will not result in an error being thrown during serialization. Instead, when these specific exceptions occur, they will be gracefully handled and the serialization process will continue.

This is especially important for file operation as TYPO3 throws errors on files problem.

Setting responsible for that will be:

$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['t3api']['serializer']['exclusionForExceptionsInAccessorStrategyGetValue']

Example value:

        $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['t3api']['serializer']['exclusionForExceptionsInAccessorStrategyGetValue'] = [
            \SourceBroker\T3apinews\Domain\Model\FileReference::class => [
                \TYPO3\CMS\Core\Resource\Exception\FileDoesNotExistException::class,
            ],
        ];

Asterix as "all exceptions" is also supported:
Example:

        $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['t3api']['serializer']['exclusionForExceptionsInAccessorStrategyGetValue'] = [
            \SourceBroker\T3apinews\Domain\Model\FileReference::class => ['*'],
        ];

CurrentFeUserSubscriber throws access array offset in PHP 8

If no user-session is available, the $GLOBALS['TSFE']->fe_user->user attribute is null, so the array access does not work:

PHP Warning: Trying to access array offset on value of type null in /var/www/html/public/typo3conf/ext/t3api/Classes/Serializer/Subscriber/CurrentFeUserSubscriber.php line 59

Fix in line 59

$data[$propertyName] = $GLOBALS['TSFE']->fe_user->user['uid'] ?? null;

Patch-File:

--- Classes/Serializer/Subscriber/CurrentFeUserSubscriber.php
+++ Classes/Serializer/Subscriber/CurrentFeUserSubscriber.php
@@ -56,7 +56,7 @@
                 continue;
             }
 
-            $data[$propertyName] = $GLOBALS['TSFE']->fe_user->user['uid'];
+            $data[$propertyName] = $GLOBALS['TSFE']->fe_user->user['uid'] ?? null;
         }
 
         $event->setData($data);

System:
TYPO3: v11.5.25
PHP: v8.0
T3API: v2.0.1

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.