Completed
Push — master ( eba3fc...7f8ec6 )
by Tim
16s queued 11s
created

PopulateEventSlugs::checkEmptySlug()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 20
rs 9.6
c 0
b 0
f 0
cc 1
nc 1
nop 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace HDNET\Calendarize\Updates;
6
7
use HDNET\Calendarize\Service\IndexerService;
8
use TYPO3\CMS\Core\Database\ConnectionPool;
9
use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
10
use TYPO3\CMS\Core\DataHandling\Model\RecordStateFactory;
11
use TYPO3\CMS\Core\DataHandling\SlugHelper;
12
use TYPO3\CMS\Core\Utility\GeneralUtility;
13
use TYPO3\CMS\Install\Updates\DatabaseUpdatedPrerequisite;
14
15
class PopulateEventSlugs extends AbstractUpdate
16
{
17
    protected $title = 'Introduce URL parts ("slugs") to calendarize event model';
18
19
    protected $description = 'Updates slug field of EXT:calendarize event records and runs a reindex';
20
21
    /**
22
     * @var string
23
     */
24
    protected $table = 'tx_calendarize_domain_model_event';
25
26
    /**
27
     * @var string
28
     */
29
    protected $fieldName = 'slug';
30
31
    /**
32
     * @var IndexerService
33
     */
34
    protected $indexerService;
35
36
    /**
37
     * PupulateEventSlugs constructor.
38
     */
39
    public function __construct()
40
    {
41
        $this->indexerService = GeneralUtility::makeInstance(IndexerService::class);
42
    }
43
44
    public function getIdentifier(): string
45
    {
46
        return 'calendarize_populateEventSlugs';
47
    }
48
49
    public function executeUpdate(): bool
50
    {
51
        $this->populateSlugs($this->table, $this->fieldName);
52
        $this->indexerService->reindexAll();
53
54
        return true;
55
    }
56
57
    /**
58
     * Populate the slug fields in the table using SlugHelper.
59
     *
60
     * @param string $table
61
     * @param string $field
62
     */
63
    public function populateSlugs(string $table, string $field): void
64
    {
65
        $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($table);
66
        $queryBuilder = $connection->createQueryBuilder();
67
        $queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
68
        $statement = $queryBuilder
69
            ->select('*')
70
            ->from($table)
71
            ->where(
72
                $queryBuilder->expr()->orX(
73
                    $queryBuilder->expr()->eq($field, $queryBuilder->createNamedParameter('')),
74
                    $queryBuilder->expr()->isNull($field)
75
                )
76
            )
77
            ->execute();
78
79
        $fieldConfig = $GLOBALS['TCA'][$table]['columns'][$field]['config'];
80
        $evalInfo = !empty($fieldConfig['eval']) ? GeneralUtility::trimExplode(',', $fieldConfig['eval'], true) : [];
81
        $hasToBeUnique = \in_array('unique', $evalInfo, true);
82
        $hasToBeUniqueInSite = \in_array('uniqueInSite', $evalInfo, true);
83
        $hasToBeUniqueInPid = \in_array('uniqueInPid', $evalInfo, true);
84
        /** @var SlugHelper $slugHelper */
85
        $slugHelper = GeneralUtility::makeInstance(SlugHelper::class, $table, $field, $fieldConfig);
86
        while ($record = $statement->fetch()) {
87
            $recordId = (int)$record['uid'];
88
            $pid = (int)$record['pid'];
89
            $slug = $slugHelper->generate($record, $pid);
90
91
            $state = RecordStateFactory::forName($table)
92
                ->fromArray($record, $pid, $recordId);
93
            if ($hasToBeUnique && !$slugHelper->isUniqueInTable($slug, $state)) {
94
                $slug = $slugHelper->buildSlugForUniqueInTable($slug, $state);
95
            }
96
            if ($hasToBeUniqueInSite && !$slugHelper->isUniqueInSite($slug, $state)) {
97
                $slug = $slugHelper->buildSlugForUniqueInSite($slug, $state);
98
            }
99
            if ($hasToBeUniqueInPid && !$slugHelper->isUniqueInPid($slug, $state)) {
100
                $slug = $slugHelper->buildSlugForUniqueInPid($slug, $state);
101
            }
102
103
            $connection->update(
104
                $table,
105
                [$field => $slug],
106
                ['uid' => $recordId]
107
            );
108
        }
109
    }
110
111
    /**
112
     * Check if any slug field in the table has an empty value.
113
     *
114
     * @param string $table
115
     * @param string $field
116
     *
117
     * @return bool
118
     */
119
    protected function checkEmptySlug(string $table, string $field): bool
120
    {
121
        $connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
122
        $queryBuilder = $connectionPool->getQueryBuilderForTable($table);
123
        $queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
124
125
        $numberOfEntries = $queryBuilder
126
            ->count('uid')
127
            ->from($table)
128
            ->where(
129
                $queryBuilder->expr()->orX(
130
                    $queryBuilder->expr()->eq($field, $queryBuilder->createNamedParameter('')),
131
                    $queryBuilder->expr()->isNull($field)
132
                )
133
            )
134
            ->execute()
135
            ->fetchColumn();
136
137
        return $numberOfEntries > 0;
138
    }
139
140
    public function updateNecessary(): bool
141
    {
142
        return $this->checkEmptySlug($this->table, $this->fieldName);
143
    }
144
145
    /**
146
     * @return string[] All new fields and tables must exist
147
     */
148
    public function getPrerequisites(): array
149
    {
150
        return [
151
            DatabaseUpdatedPrerequisite::class,
152
        ];
153
    }
154
}
155