Skip to content

Commit 7c30793

Browse files
committed
Merge branch '4.6'
2 parents 382f9a6 + b435700 commit 7c30793

File tree

14 files changed

+388
-38
lines changed

14 files changed

+388
-38
lines changed

src/lib/MVC/Symfony/Templating/Twig/Extension/ContentExtension.php

Lines changed: 91 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
use Ibexa\Contracts\Core\Repository\Repository;
1111
use Ibexa\Contracts\Core\Repository\Values\Content\Content;
12+
use Ibexa\Contracts\Core\Repository\Values\Content\ContentAwareInterface;
1213
use Ibexa\Contracts\Core\Repository\Values\Content\ContentInfo;
1314
use Ibexa\Contracts\Core\Repository\Values\Content\Field;
1415
use Ibexa\Contracts\Core\Repository\Values\ValueObject;
@@ -101,69 +102,70 @@ public function getFunctions(): array
101102
}
102103

103104
/**
104-
* @param \Ibexa\Contracts\Core\Repository\Values\ValueObject $content Must be a valid Content or ContentInfo object.
105+
* @param \Ibexa\Contracts\Core\Repository\Values\Content\Content|\Ibexa\Contracts\Core\Repository\Values\Content\ContentInfo|\Ibexa\Contracts\Core\Repository\Values\Content\ContentAwareInterface $data Must be a valid Content, ContentInfo, or ContentAwareInterface object.
105106
* @param string $forcedLanguage Locale we want the content name translation in (e.g. "fre-FR"). Null by default (takes current locale)
106107
*
107-
* @throws \Ibexa\Core\Base\Exceptions\InvalidArgumentType When $content is not a valid Content or ContentInfo object.
108+
* @throws \Ibexa\Core\Base\Exceptions\InvalidArgumentType When $content is not a valid Content, ContentInfo, or ContentAwareInterface object.
108109
*
109110
* @return string
110111
*/
111-
public function getTranslatedContentName(ValueObject $content, $forcedLanguage = null)
112+
public function getTranslatedContentName(object $data, $forcedLanguage = null)
112113
{
114+
$content = $this->resolveData($data);
113115
if ($content instanceof Content) {
114116
return $this->translationHelper->getTranslatedContentName($content, $forcedLanguage);
115117
} elseif ($content instanceof ContentInfo) {
116118
return $this->translationHelper->getTranslatedContentNameByContentInfo($content, $forcedLanguage);
117119
}
118120

119121
throw new InvalidArgumentType(
120-
'$content',
121-
sprintf('%s or %s', Content::class, ContentInfo::class),
122-
$content
122+
'$data',
123+
sprintf('%s or %s or %s', Content::class, ContentInfo::class, ContentAwareInterface::class),
124+
$data
123125
);
124126
}
125127

126128
/**
127129
* Returns the translated field, very similar to getTranslatedFieldValue but this returns the whole field.
128130
* To be used with ibexa_image_alias for example, which requires the whole field.
129131
*
130-
* @param \Ibexa\Contracts\Core\Repository\Values\Content\Content $content
132+
* @param \Ibexa\Contracts\Core\Repository\Values\Content\Content|\Ibexa\Contracts\Core\Repository\Values\Content\ContentAwareInterface $data
131133
* @param string $fieldDefIdentifier Identifier for the field we want to get.
132134
* @param string $forcedLanguage Locale we want the field in (e.g. "cro-HR"). Null by default (takes current locale).
133135
*
134136
* @return \Ibexa\Contracts\Core\Repository\Values\Content\Field
135137
*/
136-
public function getTranslatedField(Content $content, $fieldDefIdentifier, $forcedLanguage = null)
138+
public function getTranslatedField(object $data, $fieldDefIdentifier, $forcedLanguage = null)
137139
{
138-
return $this->translationHelper->getTranslatedField($content, $fieldDefIdentifier, $forcedLanguage);
140+
return $this->translationHelper->getTranslatedField($this->getContent($data), $fieldDefIdentifier, $forcedLanguage);
139141
}
140142

141143
/**
142-
* @param \Ibexa\Contracts\Core\Repository\Values\Content\Content $content
144+
* @param \Ibexa\Contracts\Core\Repository\Values\Content\Content|\Ibexa\Contracts\Core\Repository\Values\Content\ContentAwareInterface $data
143145
* @param string $fieldDefIdentifier Identifier for the field we want to get the value from.
144146
* @param string $forcedLanguage Locale we want the content name translation in (e.g. "fre-FR"). Null by default (takes current locale).
145147
*
146148
* @return mixed A primitive type or a field type Value object depending on the field type.
147149
*/
148-
public function getTranslatedFieldValue(Content $content, $fieldDefIdentifier, $forcedLanguage = null)
150+
public function getTranslatedFieldValue(object $data, $fieldDefIdentifier, $forcedLanguage = null)
149151
{
150-
return $this->translationHelper->getTranslatedField($content, $fieldDefIdentifier, $forcedLanguage)->value;
152+
return $this->translationHelper->getTranslatedField($this->getContent($data), $fieldDefIdentifier, $forcedLanguage)->value;
151153
}
152154

153155
/**
154-
* Gets name of a FieldDefinition name by loading ContentType based on Content/ContentInfo object.
156+
* Gets name of a FieldDefinition name by loading ContentType based on Content/ContentInfo/ContentAwareInterface object.
155157
*
156-
* @param \Ibexa\Contracts\Core\Repository\Values\ValueObject $content Must be Content or ContentInfo object
158+
* @param \Ibexa\Contracts\Core\Repository\Values\Content\Content|\Ibexa\Contracts\Core\Repository\Values\Content\ContentInfo|\Ibexa\Contracts\Core\Repository\Values\Content\ContentAwareInterface $data Must be Content, ContentInfo, or ContentAwareInterface object
157159
* @param string $fieldDefIdentifier Identifier for the field we want to get the name from
158160
* @param string $forcedLanguage Locale we want the content name translation in (e.g. "fre-FR"). Null by default (takes current locale)
159161
*
160-
* @throws \Ibexa\Core\Base\Exceptions\InvalidArgumentType When $content is not a valid Content object.
162+
* @throws \Ibexa\Core\Base\Exceptions\InvalidArgumentType When $content is not a valid Content, ContentInfo, or ContentAwareInterface object.
161163
*
162164
* @return string|null
163165
*/
164-
public function getTranslatedFieldDefinitionName(ValueObject $content, $fieldDefIdentifier, $forcedLanguage = null)
166+
public function getTranslatedFieldDefinitionName(object $data, $fieldDefIdentifier, $forcedLanguage = null)
165167
{
166-
if ($contentType = $this->getContentType($content)) {
168+
if ($contentType = $this->getContentType($this->resolveData($data))) {
167169
return $this->translationHelper->getTranslatedFieldDefinitionProperty(
168170
$contentType,
169171
$fieldDefIdentifier,
@@ -172,23 +174,25 @@ public function getTranslatedFieldDefinitionName(ValueObject $content, $fieldDef
172174
);
173175
}
174176

175-
throw new InvalidArgumentType('$content', 'Content|ContentInfo', $content);
177+
throw new InvalidArgumentType(
178+
'$data',
179+
sprintf('%s or %s or %s', Content::class, ContentInfo::class, ContentAwareInterface::class),
180+
$data
181+
);
176182
}
177183

178184
/**
179-
* Gets name of a FieldDefinition description by loading ContentType based on Content/ContentInfo object.
185+
* Gets name of a FieldDefinition description by loading ContentType based on Content/ContentInfo/ContentAwareInterface object.
180186
*
181-
* @param \Ibexa\Contracts\Core\Repository\Values\ValueObject $content Must be Content or ContentInfo object
187+
* @param \Ibexa\Contracts\Core\Repository\Values\Content\Content|\Ibexa\Contracts\Core\Repository\Values\Content\ContentInfo|\Ibexa\Contracts\Core\Repository\Values\Content\ContentAwareInterface $data Must be Content, ContentInfo, or ContentAwareInterface object
182188
* @param string $fieldDefIdentifier Identifier for the field we want to get the name from
183189
* @param string $forcedLanguage Locale we want the content name translation in (e.g. "fre-FR"). Null by default (takes current locale)
184190
*
185-
* @throws \Ibexa\Core\Base\Exceptions\InvalidArgumentType When $content is not a valid Content object.
186-
*
187191
* @return string|null
188192
*/
189-
public function getTranslatedFieldDefinitionDescription(ValueObject $content, $fieldDefIdentifier, $forcedLanguage = null)
193+
public function getTranslatedFieldDefinitionDescription(object $data, $fieldDefIdentifier, $forcedLanguage = null)
190194
{
191-
if ($contentType = $this->getContentType($content)) {
195+
if ($contentType = $this->getContentType($this->resolveData($data))) {
192196
return $this->translationHelper->getTranslatedFieldDefinitionProperty(
193197
$contentType,
194198
$fieldDefIdentifier,
@@ -197,11 +201,20 @@ public function getTranslatedFieldDefinitionDescription(ValueObject $content, $f
197201
);
198202
}
199203

200-
throw new InvalidArgumentType('$content', 'Content|ContentInfo', $content);
204+
throw new InvalidArgumentType(
205+
'$data',
206+
sprintf('%s or %s or %s', Content::class, ContentInfo::class, ContentAwareInterface::class),
207+
$data
208+
);
201209
}
202210

203-
public function hasField(Content $content, string $fieldDefIdentifier): bool
211+
/**
212+
* @param \Ibexa\Contracts\Core\Repository\Values\Content\Content|\Ibexa\Contracts\Core\Repository\Values\Content\ContentAwareInterface $data
213+
*/
214+
public function hasField(object $data, string $fieldDefIdentifier): bool
204215
{
216+
$content = $this->getContent($data);
217+
205218
return $content->getContentType()->hasFieldDefinition($fieldDefIdentifier);
206219
}
207220

@@ -214,21 +227,21 @@ public function getFieldGroupName(string $identifier): ?string
214227
* Checks if a given field is considered empty.
215228
* This method accepts field as Objects or by identifiers.
216229
*
217-
* @param \Ibexa\Contracts\Core\Repository\Values\Content\Content $content
230+
* @param \Ibexa\Contracts\Core\Repository\Values\Content\Content|\Ibexa\Contracts\Core\Repository\Values\Content\ContentAwareInterface $data
218231
* @param \Ibexa\Contracts\Core\Repository\Values\Content\Field|string $fieldDefIdentifier Field or Field Identifier to
219232
* get the value from.
220233
* @param string $forcedLanguage Locale we want the content name translation in (e.g. "fre-FR").
221234
* Null by default (takes current locale).
222235
*
223236
* @return bool
224237
*/
225-
public function isFieldEmpty(Content $content, $fieldDefIdentifier, $forcedLanguage = null)
238+
public function isFieldEmpty(object $data, $fieldDefIdentifier, $forcedLanguage = null)
226239
{
227240
if ($fieldDefIdentifier instanceof Field) {
228241
$fieldDefIdentifier = $fieldDefIdentifier->fieldDefIdentifier;
229242
}
230243

231-
return $this->fieldHelper->isFieldEmpty($content, $fieldDefIdentifier, $forcedLanguage);
244+
return $this->fieldHelper->isFieldEmpty($this->getContent($data), $fieldDefIdentifier, $forcedLanguage);
232245
}
233246

234247
/**
@@ -249,8 +262,12 @@ private function getContentType(ValueObject $content)
249262
}
250263
}
251264

252-
public function getFirstFilledImageFieldIdentifier(Content $content)
265+
/**
266+
* @param \Ibexa\Contracts\Core\Repository\Values\Content\Content|\Ibexa\Contracts\Core\Repository\Values\Content\ContentAwareInterface $data
267+
*/
268+
public function getFirstFilledImageFieldIdentifier(object $data)
253269
{
270+
$content = $this->getContent($data);
254271
foreach ($content->getFieldsByLanguage() as $field) {
255272
$fieldTypeIdentifier = $content->getContentType()
256273
->getFieldDefinition($field->fieldDefIdentifier)
@@ -269,4 +286,48 @@ public function getFirstFilledImageFieldIdentifier(Content $content)
269286

270287
return null;
271288
}
289+
290+
/**
291+
* @param \Ibexa\Contracts\Core\Repository\Values\Content\Content|\Ibexa\Contracts\Core\Repository\Values\Content\ContentInfo|\Ibexa\Contracts\Core\Repository\Values\Content\ContentAwareInterface $data
292+
*
293+
* @throws \Ibexa\Core\Base\Exceptions\InvalidArgumentType
294+
*/
295+
private function resolveData(object $data): ValueObject
296+
{
297+
if ($data instanceof Content || $data instanceof ContentInfo) {
298+
return $data;
299+
}
300+
301+
if ($data instanceof ContentAwareInterface) {
302+
return $data->getContent();
303+
}
304+
305+
throw new InvalidArgumentType(
306+
'$content',
307+
sprintf('%s or %s or %s', Content::class, ContentInfo::class, ContentAwareInterface::class),
308+
$data,
309+
);
310+
}
311+
312+
/**
313+
* @param \Ibexa\Contracts\Core\Repository\Values\Content\Content|\Ibexa\Contracts\Core\Repository\Values\Content\ContentAwareInterface $data
314+
*
315+
* @throws \Ibexa\Core\Base\Exceptions\InvalidArgumentType
316+
*/
317+
private function getContent(object $data): Content
318+
{
319+
if ($data instanceof Content) {
320+
return $data;
321+
}
322+
323+
if ($data instanceof ContentAwareInterface) {
324+
return $data->getContent();
325+
}
326+
327+
throw new InvalidArgumentType(
328+
'$content',
329+
sprintf('%s or %s', Content::class, ContentAwareInterface::class),
330+
$data,
331+
);
332+
}
272333
}

src/lib/MVC/Symfony/Templating/Twig/Extension/FieldRenderingExtension.php

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@
88
namespace Ibexa\Core\MVC\Symfony\Templating\Twig\Extension;
99

1010
use Ibexa\Contracts\Core\Repository\Values\Content\Content;
11+
use Ibexa\Contracts\Core\Repository\Values\Content\ContentAwareInterface;
1112
use Ibexa\Contracts\Core\Repository\Values\Content\Field;
1213
use Ibexa\Contracts\Core\Repository\Values\ContentType\FieldDefinition;
1314
use Ibexa\Core\Base\Exceptions\InvalidArgumentException;
15+
use Ibexa\Core\Base\Exceptions\InvalidArgumentType;
1416
use Ibexa\Core\Helper\TranslationHelper;
1517
use Ibexa\Core\MVC\Symfony\FieldType\View\ParameterProviderRegistryInterface;
1618
use Ibexa\Core\MVC\Symfony\Templating\FieldBlockRendererInterface;
@@ -51,17 +53,22 @@ public function __construct(
5153

5254
public function getFunctions()
5355
{
54-
$renderFieldCallable = function (Environment $environment, Content $content, $fieldIdentifier, array $params = []) {
56+
$renderFieldCallable = function (Environment $environment, $data, $fieldIdentifier, array $params = []) {
5557
$this->fieldBlockRenderer->setTwig($environment);
5658

57-
return $this->renderField($content, $fieldIdentifier, $params);
59+
return $this->renderField($this->getContent($data), $fieldIdentifier, $params);
5860
};
5961

60-
$renderFieldDefinitionSettingsCallable = function (Environment $environment, FieldDefinition $fieldDefinition, array $params = []) {
61-
$this->fieldBlockRenderer->setTwig($environment);
62+
$renderFieldDefinitionSettingsCallable =
63+
function (
64+
Environment $environment,
65+
FieldDefinition $fieldDefinition,
66+
array $params = []
67+
) {
68+
$this->fieldBlockRenderer->setTwig($environment);
6269

63-
return $this->renderFieldDefinitionSettings($fieldDefinition, $params);
64-
};
70+
return $this->renderFieldDefinitionSettings($fieldDefinition, $params);
71+
};
6572

6673
return [
6774
new TwigFunction(
@@ -187,4 +194,25 @@ private function getFieldTypeIdentifier(Content $content, Field $field)
187194

188195
return $this->fieldTypeIdentifiers[$key];
189196
}
197+
198+
/**
199+
* @param \Ibexa\Contracts\Core\Repository\Values\Content\Content|\Ibexa\Contracts\Core\Repository\Values\Content\ContentAwareInterface $content
200+
*
201+
* @throws \Ibexa\Core\Base\Exceptions\InvalidArgumentType
202+
*/
203+
private function getContent(object $content): Content
204+
{
205+
if ($content instanceof Content) {
206+
return $content;
207+
}
208+
if ($content instanceof ContentAwareInterface) {
209+
return $content->getContent();
210+
}
211+
212+
throw new InvalidArgumentType(
213+
'$content',
214+
sprintf('%s or %s', Content::class, ContentAwareInterface::class),
215+
$content,
216+
);
217+
}
190218
}

src/lib/MVC/Symfony/Templating/Twig/Extension/RenderContentExtension.php

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
namespace Ibexa\Core\MVC\Symfony\Templating\Twig\Extension;
1010

1111
use Ibexa\Contracts\Core\Repository\Values\Content\Content;
12+
use Ibexa\Contracts\Core\Repository\Values\Content\ContentAwareInterface;
13+
use Ibexa\Core\Base\Exceptions\InvalidArgumentType;
1214
use Ibexa\Core\MVC\Symfony\Event\ResolveRenderOptionsEvent;
1315
use Ibexa\Core\MVC\Symfony\Templating\RenderContentStrategy;
1416
use Ibexa\Core\MVC\Symfony\Templating\RenderOptions;
@@ -46,13 +48,38 @@ public function getFunctions(): array
4648
];
4749
}
4850

49-
public function renderContent(Content $content, array $options = []): string
51+
/**
52+
* @param \Ibexa\Contracts\Core\Repository\Values\Content\Content|\Ibexa\Contracts\Core\Repository\Values\Content\ContentAwareInterface $data
53+
*/
54+
public function renderContent(object $data, array $options = []): string
5055
{
5156
$renderOptions = new RenderOptions($options);
5257
$event = $this->eventDispatcher->dispatch(
5358
new ResolveRenderOptionsEvent($renderOptions)
5459
);
5560

56-
return $this->renderContentStrategy->render($content, $event->getRenderOptions());
61+
return $this->renderContentStrategy->render($this->getContent($data), $event->getRenderOptions());
62+
}
63+
64+
/**
65+
* @param \Ibexa\Contracts\Core\Repository\Values\Content\Content|\Ibexa\Contracts\Core\Repository\Values\Content\ContentAwareInterface $data
66+
*
67+
* @throws \Ibexa\Core\Base\Exceptions\InvalidArgumentType
68+
*/
69+
private function getContent(object $data): Content
70+
{
71+
if ($data instanceof Content) {
72+
return $data;
73+
}
74+
75+
if ($data instanceof ContentAwareInterface) {
76+
return $data->getContent();
77+
}
78+
79+
throw new InvalidArgumentType(
80+
'$content',
81+
sprintf('%s or %s', Content::class, ContentAwareInterface::class),
82+
$data,
83+
);
5784
}
5885
}

tests/lib/MVC/Symfony/Templating/Twig/Extension/ContentExtensionTest.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use Ibexa\Contracts\Core\Repository\ContentService;
1111
use Ibexa\Contracts\Core\Repository\ContentTypeService;
1212
use Ibexa\Contracts\Core\Repository\Repository;
13+
use Ibexa\Contracts\Core\Repository\Values\Content\ContentAwareInterface;
1314
use Ibexa\Contracts\Core\Repository\Values\Content\ContentInfo;
1415
use Ibexa\Contracts\Core\Repository\Values\Content\Field;
1516
use Ibexa\Contracts\Core\SiteAccess\ConfigResolverInterface;
@@ -127,6 +128,20 @@ protected function getContent(string $contentTypeIdentifier, array $fieldsData,
127128
return $content;
128129
}
129130

131+
/**
132+
* @param array<string, mixed> $fieldsData
133+
* @param array<mixed> $namesData
134+
*/
135+
protected function getContentAwareObject(string $contentTypeIdentifier, array $fieldsData, array $namesData = []): ContentAwareInterface
136+
{
137+
$content = $this->getContent($contentTypeIdentifier, $fieldsData, $namesData);
138+
139+
$mock = $this->createMock(ContentAwareInterface::class);
140+
$mock->method('getContent')->willReturn($content);
141+
142+
return $mock;
143+
}
144+
130145
private function getConfigResolverMock()
131146
{
132147
$mock = $this->createMock(ConfigResolverInterface::class);

0 commit comments

Comments
 (0)