[BUGFIX] Resolve strict type assertion in RecordStateFactory
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Classes / DataHandling / Model / RecordStateFactory.php
1 <?php
2 declare(strict_types = 1);
3
4 namespace TYPO3\CMS\Core\DataHandling\Model;
5
6 /*
7 * This file is part of the TYPO3 CMS project.
8 *
9 * It is free software; you can redistribute it and/or modify it under
10 * the terms of the GNU General Public License, either version 2
11 * of the License, or any later version.
12 *
13 * For the full copyright and license information, please read the
14 * LICENSE.txt file that was distributed with this source code.
15 *
16 * The TYPO3 project - inspiring people to share!
17 */
18
19 use TYPO3\CMS\Core\Utility\GeneralUtility;
20
21 /**
22 * Factory class that creates a record state
23 */
24 class RecordStateFactory
25 {
26 /**
27 * @var string
28 */
29 protected $name;
30
31 /**
32 * @param string $name
33 * @return static
34 */
35 public static function forName(string $name): self
36 {
37 return GeneralUtility::makeInstance(
38 static::class,
39 $name
40 );
41 }
42
43 /**
44 * @param string $name
45 */
46 public function __construct(string $name)
47 {
48 $this->name = $name;
49 }
50
51 /**
52 * @param array $data
53 * @param int|string|null $pageId
54 * @param int|string|null $recordId
55 * @return object|RecordState
56 */
57 public function fromArray(array $data, $pageId = null, $recordId = null): RecordState
58 {
59 $pageId = $pageId ?? $data['pid'] ?? null;
60 $recordId = $recordId ?? $data['uid'] ?? null;
61
62 $aspectFieldValues = $this->resolveAspectFieldValues($data);
63
64 $context = GeneralUtility::makeInstance(EntityContext::class)
65 ->withWorkspaceId($aspectFieldValues['workspace'])
66 ->withLanguageId($aspectFieldValues['language']);
67 $node = $this->createEntityPointer($pageId, 'pages');
68 $subject = $this->createEntityPointer($recordId);
69
70 /** @var RecordState $target */
71 $target = GeneralUtility::makeInstance(
72 RecordState::class,
73 $context,
74 $node,
75 $subject
76 );
77 return $target
78 ->withLanguageLink($this->resolveLanguageLink($aspectFieldValues))
79 ->withVersionLink($this->resolveLanguageLink($aspectFieldValues));
80 }
81
82 /**
83 * @return array
84 */
85 protected function resolveAspectFieldNames(): array
86 {
87 return [
88 'workspace' => 't3ver_wsid',
89 'versionParent' => 't3ver_oid',
90 'language' => $GLOBALS['TCA'][$this->name]['ctrl']['languageField'] ?? null,
91 'languageParent' => $GLOBALS['TCA'][$this->name]['ctrl']['transOrigPointerField'] ?? null,
92 'languageSource' => $GLOBALS['TCA'][$this->name]['ctrl']['translationSource'] ?? null,
93 ];
94 }
95
96 /**
97 * @param array $data
98 * @return array
99 */
100 protected function resolveAspectFieldValues(array $data): array
101 {
102 return array_map(
103 function ($aspectFieldName) use ($data) {
104 return (int)($data[$aspectFieldName] ?? 0);
105 },
106 $this->resolveAspectFieldNames()
107 );
108 }
109
110 /**
111 * @param array $aspectFieldNames
112 * @return EntityPointerLink|null
113 */
114 protected function resolveLanguageLink(array $aspectFieldNames): ?EntityPointerLink
115 {
116 if (!empty($aspectFieldNames['languageSource'])) {
117 $languageSourceLink = GeneralUtility::makeInstance(
118 EntityPointerLink::class,
119 $this->createEntityPointer($aspectFieldNames['languageSource'])
120 );
121 }
122
123 if (!empty($aspectFieldNames['languageParent'])) {
124 $languageParentLink = GeneralUtility::makeInstance(
125 EntityPointerLink::class,
126 $this->createEntityPointer($aspectFieldNames['languageParent'])
127 );
128 }
129
130 if (empty($languageSourceLink) || empty($languageParentLink)
131 || $languageSourceLink->getSubject()->isEqualTo(
132 $languageParentLink->getSubject()
133 )
134 ) {
135 return $languageSourceLink ?? $languageParentLink ?? null;
136 }
137 return $languageSourceLink->withAncestor($languageParentLink);
138 }
139
140 /**
141 * @param string|int $identifier
142 * @param string|null $name
143 * @return EntityPointer
144 * @throws \LogicException
145 */
146 protected function createEntityPointer($identifier, string $name = null): EntityPointer
147 {
148 if ($identifier === null) {
149 throw new \LogicException(
150 'Cannot create null pointer',
151 1536407967
152 );
153 }
154
155 $identifier = (string)$identifier;
156
157 return GeneralUtility::makeInstance(
158 EntityUidPointer::class,
159 $name ?? $this->name,
160 $identifier
161 );
162 }
163 }