Completed
Push — master ( c28fba...9b84d0 )
by Tim
15s queued 11s
created

SlugService::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 13
rs 9.8333
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace HDNET\Calendarize\Service\Url;
6
7
use HDNET\Calendarize\Event\BaseSlugGenerationEvent;
8
use HDNET\Calendarize\Event\SlugSuffixGenerationEvent;
9
use HDNET\Calendarize\Features\SpeakingUrlInterface;
10
use HDNET\Calendarize\Utility\ConfigurationUtility;
11
use HDNET\Calendarize\Utility\EventUtility;
12
use HDNET\Calendarize\Utility\ExtensionConfigurationUtility;
13
use Psr\EventDispatcher\EventDispatcherInterface;
14
use TYPO3\CMS\Core\DataHandling\Model\RecordStateFactory;
15
use TYPO3\CMS\Core\DataHandling\SlugHelper;
16
use TYPO3\CMS\Core\Utility\GeneralUtility;
17
use TYPO3\CMS\Extbase\DomainObject\DomainObjectInterface;
18
19
class SlugService extends \HDNET\Calendarize\Service\AbstractService
20
{
21
    protected const TABLE_NAME = 'tx_calendarize_domain_model_index';
22
    protected const SLUG_NAME = 'slug';
23
24
    /**
25
     * @var SlugHelper
26
     */
27
    protected $slugHelper;
28
29
    /**
30
     * @var RecordStateFactory
31
     */
32
    protected $stateFactory;
33
34
    /**
35
     * @var EventDispatcherInterface
36
     */
37
    protected $eventDispatcher;
38
39
    /**
40
     * @var bool
41
     */
42
    protected $useDate;
43
44
    public function __construct(EventDispatcherInterface $eventDispatcher)
45
    {
46
        $this->eventDispatcher = $eventDispatcher;
47
        $this->slugHelper = GeneralUtility::makeInstance(
48
            SlugHelper::class,
49
            self::TABLE_NAME,
50
            self::SLUG_NAME,
51
            $GLOBALS['TCA'][self::TABLE_NAME]['columns'][self::SLUG_NAME]['config']
52
        );
53
        $this->stateFactory = RecordStateFactory::forName(self::TABLE_NAME);
0 ignored issues
show
Documentation Bug introduced by
It seems like \TYPO3\CMS\Core\DataHand...rName(self::TABLE_NAME) of type object<self> is incompatible with the declared type object<TYPO3\CMS\Core\Da...del\RecordStateFactory> of property $stateFactory.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
54
55
        $this->useDate = !(bool)ConfigurationUtility::get('disableDateInSpeakingUrl');
56
    }
57
58
    /**
59
     * Generate a slug for the record and add specific suffixes to each index,
60
     * e.g. spacex-falcon-9-crew-2-20210422.
61
     *
62
     * @param string $uniqueRegisterKey
63
     * @param array  $record
64
     * @param array  $neededItems
65
     *
66
     * @return array
67
     */
68
    public function generateSlugForItems(string $uniqueRegisterKey, array $record, array $neededItems): array
69
    {
70
        if (empty($neededItems)) {
71
            return [];
72
        }
73
74
        // Get domain model
75
        $configuration = ExtensionConfigurationUtility::get($uniqueRegisterKey);
76
        /** @var DomainObjectInterface $model */
77
        $model = EventUtility::getOriginalRecordByConfiguration($configuration, $record['uid']);
78
79
        $baseSlug = $this->generateBaseSlug($uniqueRegisterKey, $record, $model);
80
81
        return $this->generateSlugSuffix($uniqueRegisterKey, $baseSlug, $neededItems);
82
    }
83
84
    /**
85
     * Generate a base slug for the record.
86
     *
87
     * @param string                $uniqueRegisterKey
88
     * @param array                 $record
89
     * @param DomainObjectInterface $model
90
     *
91
     * @return string
92
     */
93
    protected function generateBaseSlug(string $uniqueRegisterKey, array $record, DomainObjectInterface $model): string
94
    {
95
        // If the model has a speaking url use it
96
        if ($model instanceof SpeakingUrlInterface) {
97
            $baseSlug = $model->getRealUrlAliasBase();
98
        }
99
100
        // Multiple fallbacks
101
        if (empty($baseSlug)) {
102
            $baseSlug = $record['slug']
103
                ?? $record['path_segment']
104
                ?? "$uniqueRegisterKey-{$record['uid']}";
105
        }
106
107
        $baseSlug = $this->slugHelper->sanitize($baseSlug);
108
109
        return $this->eventDispatcher->dispatch(new BaseSlugGenerationEvent(
0 ignored issues
show
Documentation introduced by
new \HDNET\Calendarize\E...el, $record, $baseSlug) is of type object<HDNET\Calendarize...aseSlugGenerationEvent>, but the function expects a object<Psr\EventDispatcher\object>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
110
            $uniqueRegisterKey,
111
            $model,
112
            $record,
113
            $baseSlug
114
        ))->getBaseSlug();
115
    }
116
117
    /**
118
     * Generate a suffix for all items, e.g. test-20201103.
119
     *
120
     * @param string $uniqueRegisterKey
121
     * @param string $base
122
     * @param array  $items
123
     *
124
     * @return array
125
     */
126
    protected function generateSlugSuffix(string $uniqueRegisterKey, string $base, array $items): array
127
    {
128
        $addFields = [];
129
        foreach ($items as $key => $item) {
130
            $indexSlug = $base;
131
132
            // Skip date on single event
133
            if ($this->useDate && 1 !== \count($items)) {
134
                $indexSlug .= '-' . str_replace('-', '', $item['start_date']);
135
            }
136
137
            $indexSlug = $this->slugHelper->sanitize($indexSlug);
138
            $addFields[$key]['slug'] = $this->eventDispatcher->dispatch(new SlugSuffixGenerationEvent(
0 ignored issues
show
Documentation introduced by
new \HDNET\Calendarize\E...Key, $item, $indexSlug) is of type object<HDNET\Calendarize...gSuffixGenerationEvent>, but the function expects a object<Psr\EventDispatcher\object>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
139
                $uniqueRegisterKey,
140
                $item,
141
                $indexSlug
142
            ))->getSlug();
143
        }
144
145
        return $addFields;
146
    }
147
148
    /**
149
     * Process the record and make the slug unique in the table, e.g. adds a suffix on duplicate.
150
     *
151
     * @param array $recordData
152
     *
153
     * @return string
154
     */
155
    public function makeSlugUnique(array $recordData): string
156
    {
157
        // Create RecordState and generate slug
158
        $state = $this->stateFactory->fromArray(
159
            $recordData,
160
            $recordData['pid'],
161
            $recordData['uid'] ?? ''
162
        );
163
        /* @noinspection PhpUnhandledExceptionInspection */
164
        return $this->slugHelper->buildSlugForUniqueInTable($recordData['slug'], $state);
165
    }
166
}
167