Completed
Push — master ( 175e11...08c540 )
by
unknown
15:46
created

IntegrityService::check()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 2
nc 2
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * This file is part of the TYPO3 CMS project.
5
 *
6
 * It is free software; you can redistribute it and/or modify it under
7
 * the terms of the GNU General Public License, either version 2
8
 * of the License, or any later version.
9
 *
10
 * For the full copyright and license information, please read the
11
 * LICENSE.txt file that was distributed with this source code.
12
 *
13
 * The TYPO3 project - inspiring people to share!
14
 */
15
16
namespace TYPO3\CMS\Workspaces\Service;
17
18
use TYPO3\CMS\Backend\Utility\BackendUtility;
19
use TYPO3\CMS\Core\Localization\LanguageService;
20
use TYPO3\CMS\Core\Versioning\VersionState;
21
use TYPO3\CMS\Workspaces\Domain\Model\CombinedRecord;
22
23
/**
24
 * Service for integrity
25
 */
26
class IntegrityService
27
{
28
    /**
29
     * Success status - everything is fine
30
     *
31
     * @var int
32
     */
33
    const STATUS_Succes = 100;
0 ignored issues
show
Coding Style introduced by
This class constant is not uppercase (expected STATUS_SUCCES).
Loading history...
34
    /**
35
     * Info status - nothing is wrong, but a notice is shown
36
     *
37
     * @var int
38
     */
39
    const STATUS_Info = 101;
0 ignored issues
show
Coding Style introduced by
This class constant is not uppercase (expected STATUS_INFO).
Loading history...
40
    /**
41
     * Warning status - user interaction might be required
42
     *
43
     * @var int
44
     */
45
    const STATUS_Warning = 102;
0 ignored issues
show
Coding Style introduced by
This class constant is not uppercase (expected STATUS_WARNING).
Loading history...
46
    /**
47
     * Error status - user interaction is required
48
     *
49
     * @var int
50
     */
51
    const STATUS_Error = 103;
0 ignored issues
show
Coding Style introduced by
This class constant is not uppercase (expected STATUS_ERROR).
Loading history...
52
    /**
53
     * @var array
54
     */
55
    protected $statusRepresentation = [
56
        self::STATUS_Succes => 'success',
57
        self::STATUS_Info => 'info',
58
        self::STATUS_Warning => 'warning',
59
        self::STATUS_Error => 'error'
60
    ];
61
62
    /**
63
     * @var CombinedRecord[]
64
     */
65
    protected $affectedElements;
66
67
    /**
68
     * Array storing all issues that have been checked and
69
     * found during runtime in this object. The array keys
70
     * are identifiers of table and the version-id.
71
     *
72
     * 'tx_table:123' => array(
73
     * array(
74
     * 'status' => 'warning',
75
     * 'message' => 'Element cannot be...',
76
     * )
77
     * )
78
     *
79
     * @var array
80
     */
81
    protected $issues = [];
82
83
    /**
84
     * Sets the affected elements.
85
     *
86
     * @param CombinedRecord[] $affectedElements
87
     */
88
    public function setAffectedElements(array $affectedElements)
89
    {
90
        $this->affectedElements = $affectedElements;
91
    }
92
93
    /**
94
     * Checks integrity of affected records.
95
     */
96
    public function check()
97
    {
98
        foreach ($this->affectedElements as $affectedElement) {
99
            $this->checkElement($affectedElement);
100
        }
101
    }
102
103
    /**
104
     * Checks a single element.
105
     *
106
     * @param CombinedRecord $element
107
     */
108
    public function checkElement(CombinedRecord $element)
109
    {
110
        $this->checkLocalization($element);
111
    }
112
113
    /**
114
     * Checks workspace localization integrity of a single elements.
115
     * If current record is a localization and its localization parent
116
     * is new in this workspace (has only a placeholder record in live),
117
     * then both (localization and localization parent) should be published.
118
     *
119
     * @param CombinedRecord $element
120
     */
121
    protected function checkLocalization(CombinedRecord $element)
122
    {
123
        $table = $element->getTable();
124
        if (BackendUtility::isTableLocalizable($table)) {
125
            $languageField = $GLOBALS['TCA'][$table]['ctrl']['languageField'];
126
            $languageParentField = $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField'];
127
            $versionRow = $element->getVersionRecord()->getRow();
128
            // If element is a localization:
129
            if ($versionRow[$languageField] > 0) {
130
                // Get localization parent from live workspace:
131
                $languageParentRecord = BackendUtility::getRecord($table, $versionRow[$languageParentField], 'uid,t3ver_state');
132
                // If localization parent is a "new placeholder" record:
133
                if (VersionState::cast($languageParentRecord['t3ver_state'])->equals(VersionState::NEW_PLACEHOLDER)) {
134
                    $title = BackendUtility::getRecordTitle($table, $versionRow);
135
                    $languageService = $this->getLanguageService();
136
                    // Add warning for current versionized record:
137
                    $this->addIssue(
138
                        $element->getLiveRecord()->getIdentifier(),
139
                        self::STATUS_Warning,
140
                        sprintf($languageService->sL('LLL:EXT:workspaces/Resources/Private/Language/locallang.xlf:integrity.dependsOnDefaultLanguageRecord'), $title)
141
                    );
142
                    // Add info for related localization parent record:
143
                    $this->addIssue(
144
                        $table . ':' . $languageParentRecord['uid'],
145
                        self::STATUS_Info,
146
                        sprintf($languageService->sL('LLL:EXT:workspaces/Resources/Private/Language/locallang.xlf:integrity.isDefaultLanguageRecord'), $title)
147
                    );
148
                }
149
            }
150
        }
151
    }
152
153
    /**
154
     * Gets the status of the most important severity.
155
     * (low << success, info, warning, error >> high)
156
     *
157
     * @param string $identifier Record identifier (table:id) for look-ups
158
     * @return string
159
     */
160
    public function getStatus($identifier = null)
161
    {
162
        $status = self::STATUS_Succes;
163
        if ($identifier === null) {
164
            foreach ($this->issues as $idenfieriferIssues) {
165
                foreach ($idenfieriferIssues as $issue) {
166
                    if ($status < $issue['status']) {
167
                        $status = $issue['status'];
168
                    }
169
                }
170
            }
171
        } else {
172
            foreach ($this->getIssues($identifier) as $issue) {
173
                if ($status < $issue['status']) {
174
                    $status = $issue['status'];
175
                }
176
            }
177
        }
178
        return $status;
179
    }
180
181
    /**
182
     * Gets the (human readable) representation of the status with the most
183
     * important severity (wraps $this->getStatus() and translates the result).
184
     *
185
     * @param string $identifier Record identifier (table:id) for look-ups
186
     * @return string One out of success, info, warning, error
187
     */
188
    public function getStatusRepresentation($identifier = null)
189
    {
190
        return $this->statusRepresentation[$this->getStatus($identifier)];
191
    }
192
193
    /**
194
     * Gets issues, all or specific for one identifier.
195
     *
196
     * @param string $identifier Record identifier (table:id) for look-ups
197
     * @return array
198
     */
199
    public function getIssues($identifier = null)
200
    {
201
        if ($identifier === null) {
202
            return $this->issues;
203
        }
204
        if (isset($this->issues[$identifier])) {
205
            return $this->issues[$identifier];
206
        }
207
        return [];
208
    }
209
210
    /**
211
     * Gets the message of all issues.
212
     *
213
     * @param string $identifier Record identifier (table:id) for look-ups
214
     * @param bool $asString Return results as string instead of array
215
     * @return array|string
216
     */
217
    public function getIssueMessages($identifier = null, $asString = false)
218
    {
219
        $messages = [];
220
        if ($identifier === null) {
221
            foreach ($this->issues as $idenfieriferIssues) {
222
                foreach ($idenfieriferIssues as $issue) {
223
                    $messages[] = $issue['message'];
224
                }
225
            }
226
        } else {
227
            foreach ($this->getIssues($identifier) as $issue) {
228
                $messages[] = $issue['message'];
229
            }
230
        }
231
        if ($asString) {
232
            $messages = implode('<br/>', $messages);
233
        }
234
        return $messages;
235
    }
236
237
    /**
238
     * Adds an issue.
239
     *
240
     * @param string $identifier Record identifier (table:id)
241
     * @param int $status Status code (see constants)
242
     * @param string $message Message/description of the issue
243
     */
244
    protected function addIssue($identifier, $status, $message)
245
    {
246
        if (!isset($this->issues[$identifier])) {
247
            $this->issues[$identifier] = [];
248
        }
249
        $this->issues[$identifier][] = [
250
            'status' => $status,
251
            'message' => $message
252
        ];
253
    }
254
255
    protected function getLanguageService(): LanguageService
256
    {
257
        return $GLOBALS['LANG'];
258
    }
259
}
260