• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

FluidTYPO3 / flux / 14774311267

01 May 2025 11:00AM UTC coverage: 93.246% (+0.3%) from 92.9%
14774311267

push

github

NamelessCoder
[TER] 11.0.0

7083 of 7596 relevant lines covered (93.25%)

66.31 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.55
/Classes/Provider/ProviderResolver.php
1
<?php
2
declare(strict_types=1);
3
namespace FluidTYPO3\Flux\Provider;
4

5
/*
6
 * This file is part of the FluidTYPO3/Flux project under GPLv2 or later.
7
 *
8
 * For the full copyright and license information, please read the
9
 * LICENSE.md file that was distributed with this source code.
10
 */
11

12
use FluidTYPO3\Flux\Core;
13
use FluidTYPO3\Flux\Hooks\HookHandler;
14
use FluidTYPO3\Flux\Provider\Interfaces\RecordProviderInterface;
15
use TYPO3\CMS\Core\SingletonInterface;
16
use TYPO3\CMS\Core\Utility\GeneralUtility;
17

18
/**
19
 * Provider Resolver
20
 *
21
 * Returns one or more Provider instances based on parameters.
22
 */
23
class ProviderResolver implements SingletonInterface
24
{
25
    protected array $providers = [];
26

27
    /**
28
     * Resolve fluidpages specific configuration provider. Always
29
     * returns the main PageProvider type which needs to be used
30
     * as primary PageProvider when processing a complete page
31
     * rather than just the "sub configuration" field value.
32
     */
33
    public function resolvePageProvider(array $row): ?ProviderInterface
34
    {
35
        $provider = $this->resolvePrimaryConfigurationProvider('pages', PageProvider::FIELD_NAME_MAIN, $row);
×
36
        return $provider;
×
37
    }
38

39
    /**
40
     * ResolveUtility the top-priority ConfigurationPrivider which can provide
41
     * a working FlexForm configuration baed on the given parameters.
42
     *
43
     * @template T
44
     * @param class-string<T>[] $interfaces
45
     * @return T|null
46
     */
47
    public function resolvePrimaryConfigurationProvider(
48
        ?string $table,
49
        ?string $fieldName,
50
        array $row = null,
51
        ?string $extensionKey = null,
52
        array $interfaces = [ProviderInterface::class]
53
    ) {
54
        $providers = $this->resolveConfigurationProviders($table, $fieldName, $row, $extensionKey, $interfaces);
7✔
55
        return reset($providers) ?: null;
7✔
56
    }
57

58
    /**
59
     * Resolves a ConfigurationProvider which can provide a working FlexForm
60
     * configuration based on the given parameters.
61
     *
62
     * @template T
63
     * @param class-string<T>[] $interfaces
64
     * @return T[]
65
     */
66
    public function resolveConfigurationProviders(
67
        ?string $table,
68
        ?string $fieldName,
69
        array $row = null,
70
        ?string $extensionKey = null,
71
        array $interfaces = [ProviderInterface::class]
72
    ) {
73
        $row = false === is_array($row) ? [] : $row;
21✔
74
        $providers = $this->getAllRegisteredProviderInstances();
21✔
75
        if ($interfaces) {
21✔
76
            $providers = array_filter(
21✔
77
                $providers,
21✔
78
                function ($provider) use ($interfaces) {
21✔
79
                    foreach ((array) $interfaces as $interface) {
21✔
80
                        if (!is_a($provider, $interface, true)) {
21✔
81
                            return false;
7✔
82
                        }
83
                    }
84
                    return true;
21✔
85
                }
21✔
86
            );
21✔
87
        }
88
        usort(
21✔
89
            $providers,
21✔
90
            function (ProviderInterface $a, ProviderInterface $b) use ($row) {
21✔
91
                return $b->getPriority($row) <=> $a->getPriority($row);
21✔
92
            }
21✔
93
        );
21✔
94
        // RecordProviderInterface being missing will automatically include the Provider. Those that do
95
        // implement the interface will be asked if they should trigger on the table/field/row/ext combo.
96
        $providers = array_filter(
21✔
97
            $providers,
21✔
98
            function (ProviderInterface $provider) use ($row, $table, $fieldName, $extensionKey) {
21✔
99
                return !$provider instanceof RecordProviderInterface
21✔
100
                    || $provider->trigger($row, $table, $fieldName, $extensionKey);
21✔
101
            }
21✔
102
        );
21✔
103
        return HookHandler::trigger(
21✔
104
            HookHandler::PROVIDERS_RESOLVED,
21✔
105
            [
21✔
106
                'table' => $table,
21✔
107
                'field' => $fieldName,
21✔
108
                'record' => $row,
21✔
109
                'extensionKey' => $extensionKey,
21✔
110
                'interfaces' => $interfaces,
21✔
111
                'providers' => $providers
21✔
112
            ]
21✔
113
        )['providers'];
21✔
114
    }
115

116
    /**
117
     * @return ProviderInterface[]
118
     */
119
    protected function getAllRegisteredProviderInstances(): array
120
    {
121
        if (empty($this->providers)) {
7✔
122
            $providers = $this->loadCoreRegisteredProviders();
7✔
123
            $this->providers = $this->validateAndInstantiateProviders($providers);
7✔
124
        }
125
        return $this->providers;
7✔
126
    }
127

128
    /**
129
     * @return ProviderInterface[]
130
     */
131
    protected function validateAndInstantiateProviders(array $providers): array
132
    {
133
        $instances = [];
35✔
134
        foreach ($providers as $classNameOrInstance) {
35✔
135
            if (!is_a($classNameOrInstance, ProviderInterface::class, true)) {
28✔
136
                $className = is_object($classNameOrInstance) ? get_class($classNameOrInstance) : $classNameOrInstance;
14✔
137
                throw new \RuntimeException(
14✔
138
                    $className . ' must implement ProviderInterfaces from Flux/Provider',
14✔
139
                    1327173536
14✔
140
                );
14✔
141
            }
142
            if (true === is_object($classNameOrInstance)) {
14✔
143
                /** @var ProviderInterface $provider */
144
                $provider = $classNameOrInstance;
7✔
145
            } else {
146
                /** @var ProviderInterface $provider */
147
                $provider = GeneralUtility::makeInstance($classNameOrInstance);
7✔
148
            }
149
            $instances[] = $provider;
14✔
150
        }
151
        return $instances;
21✔
152
    }
153

154
    protected function loadCoreRegisteredProviders(): array
155
    {
156
        return Core::getRegisteredFlexFormProviders();
7✔
157
    }
158
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc