[BUGFIX] Always use default language for uniqueInSite
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Classes / DataHandling / Model / RecordState.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\MathUtility;
20
21 /**
22 * A RecordState is an abstract description of a record that consists of
23 *
24 * - an EntityContext describing the "variant" of a record
25 * - an EntityPointer that describes the node where the record is stored
26 * - an EntityUidPointer of the record the RecordState instance represents
27 *
28 * Instances of this class are created by the RecordStateFactory.
29 */
30 class RecordState
31 {
32 /**
33 * @var EntityContext
34 */
35 protected $context;
36
37 /**
38 * @var EntityPointer
39 */
40 protected $node;
41
42 /**
43 * @var EntityUidPointer
44 */
45 protected $subject;
46
47 /**
48 * @var EntityPointerLink
49 */
50 protected $languageLink;
51
52 /**
53 * @var EntityPointerLink
54 */
55 protected $versionLink;
56
57 /**
58 * @param EntityContext $context
59 * @param EntityPointer $node
60 * @param EntityUidPointer $subject
61 */
62 public function __construct(EntityContext $context, EntityPointer $node, EntityUidPointer $subject)
63 {
64 $this->context = $context;
65 $this->node = $node;
66 $this->subject = $subject;
67 }
68
69 /**
70 * @return EntityContext
71 */
72 public function getContext(): EntityContext
73 {
74 return $this->context;
75 }
76
77 /**
78 * @return EntityPointer
79 */
80 public function getNode(): EntityPointer
81 {
82 return $this->node;
83 }
84
85 /**
86 * @return EntityUidPointer
87 */
88 public function getSubject(): EntityUidPointer
89 {
90 return $this->subject;
91 }
92
93 /**
94 * @return EntityPointerLink
95 */
96 public function getLanguageLink(): ?EntityPointerLink
97 {
98 return $this->languageLink;
99 }
100
101 /**
102 * @param EntityPointerLink|null $languageLink
103 * @return static
104 */
105 public function withLanguageLink(?EntityPointerLink $languageLink): self
106 {
107 if ($this->languageLink === $languageLink) {
108 return $this;
109 }
110 $target = clone $this;
111 $target->languageLink = $languageLink;
112 return $target;
113 }
114
115 /**
116 * @return EntityPointerLink
117 */
118 public function getVersionLink(): ?EntityPointerLink
119 {
120 return $this->versionLink;
121 }
122
123 /**
124 * @param EntityPointerLink|null $versionLink
125 * @return static
126 */
127 public function withVersionLink(?EntityPointerLink $versionLink): self
128 {
129 if ($this->versionLink === $versionLink) {
130 return $this;
131 }
132 $target = clone $this;
133 $target->versionLink = $versionLink;
134 return $target;
135 }
136
137 /**
138 * @return bool
139 */
140 public function isNew(): bool
141 {
142 return !MathUtility::canBeInterpretedAsInteger(
143 $this->subject->getIdentifier()
144 );
145 }
146
147 /**
148 * Resolves node identifier (`pid`) of current subject. For translated pages
149 * that would result in the `uid` of the outer-most language parent page
150 * otherwise it's the `pid` of the current subject.
151 *
152 * Example:
153 * + pages: uid: 10, pid: 5, sys_language_uid: 0, l10n_parent: 0 -> returns 5
154 * + pages: uid: 11, pid: 5, sys_language_uid: 1, l10n_parent: 10 -> returns 10
155 * + other: uid: 12, pid: 10 -> returns 10
156 *
157 * @return string
158 */
159 public function resolveNodeIdentifier(): string
160 {
161 if ($this->subject->isNode()
162 && $this->context->getLanguageId() > 0
163 && $this->languageLink !== null
164 ) {
165 return $this->languageLink->getHead()->getSubject()->getIdentifier();
166 }
167 return $this->node->getIdentifier();
168 }
169
170 /**
171 * Resolves node identifier used as aggregate for current subject. For translated
172 * pages that would result in the `uid` of the outer-most language parent page,
173 * for pages it's the identifier of the current subject, otherwise it's
174 * the `pid` of the current subject.
175 *
176 * Example:
177 * + pages: uid: 10, pid: 5, sys_language_uid: 0, l10n_parent: 0 -> returns 10
178 * + pages: uid: 11, pid: 5, sys_language_uid: 1, l10n_parent: 10 -> returns 10
179 * + other: uid: 12, pid: 10 -> returns 10
180 *
181 * @return string
182 */
183 public function resolveNodeAggregateIdentifier(): string
184 {
185 if ($this->subject->isNode()
186 && $this->context->getLanguageId() > 0
187 && $this->languageLink !== null
188 ) {
189 return $this->languageLink->getHead()->getSubject()->getIdentifier();
190 }
191 if ($this->subject->isNode()) {
192 return $this->subject->getIdentifier();
193 }
194 return $this->node->getIdentifier();
195 }
196 }