1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* File containing the ContentExtension class. |
5
|
|
|
* |
6
|
|
|
* @copyright Copyright (C) eZ Systems AS. All rights reserved. |
7
|
|
|
* @license For full copyright and license information view LICENSE file distributed with this source code. |
8
|
|
|
*/ |
9
|
|
|
namespace eZ\Publish\Core\MVC\Symfony\Templating\Twig\Extension; |
10
|
|
|
|
11
|
|
|
use eZ\Publish\API\Repository\Repository; |
12
|
|
|
use eZ\Publish\API\Repository\Values\Content\ContentInfo; |
13
|
|
|
use eZ\Publish\API\Repository\Values\ValueObject; |
14
|
|
|
use eZ\Publish\Core\Base\Exceptions\InvalidArgumentType; |
15
|
|
|
use eZ\Publish\Core\Base\Exceptions\InvalidArgumentValue; |
16
|
|
|
use eZ\Publish\Core\Helper\FieldHelper; |
17
|
|
|
use eZ\Publish\Core\Helper\TranslationHelper; |
18
|
|
|
use eZ\Publish\API\Repository\Values\Content\Content; |
19
|
|
|
use eZ\Publish\API\Repository\Values\Content\Field; |
20
|
|
|
use Psr\Log\LoggerInterface; |
21
|
|
|
use Twig\Extension\AbstractExtension; |
22
|
|
|
use Twig\TwigFunction; |
23
|
|
|
|
24
|
|
|
/** |
25
|
|
|
* Twig content extension for eZ Publish specific usage. |
26
|
|
|
* Exposes helpers to play with public API objects. |
27
|
|
|
*/ |
28
|
|
|
class ContentExtension extends AbstractExtension |
29
|
|
|
{ |
30
|
|
|
/** |
31
|
|
|
* @var \eZ\Publish\API\Repository\Repository |
32
|
|
|
*/ |
33
|
|
|
protected $repository; |
34
|
|
|
|
35
|
|
|
/** |
36
|
|
|
* @var \eZ\Publish\Core\Helper\TranslationHelper |
37
|
|
|
*/ |
38
|
|
|
protected $translationHelper; |
39
|
|
|
|
40
|
|
|
/** |
41
|
|
|
* @var \eZ\Publish\Core\Helper\FieldHelper |
42
|
|
|
*/ |
43
|
|
|
protected $fieldHelper; |
44
|
|
|
|
45
|
|
|
/** |
46
|
|
|
* @var LoggerInterface |
47
|
|
|
*/ |
48
|
|
|
protected $logger; |
49
|
|
|
|
50
|
|
|
public function __construct( |
51
|
|
|
Repository $repository, |
52
|
|
|
TranslationHelper $translationHelper, |
53
|
|
|
FieldHelper $fieldHelper, |
54
|
|
|
LoggerInterface $logger = null |
55
|
|
|
) { |
56
|
|
|
$this->repository = $repository; |
57
|
|
|
$this->translationHelper = $translationHelper; |
58
|
|
|
$this->fieldHelper = $fieldHelper; |
59
|
|
|
$this->logger = $logger; |
60
|
|
|
} |
61
|
|
|
|
62
|
|
|
/** |
63
|
|
|
* Returns a list of functions to add to the existing list. |
64
|
|
|
* |
65
|
|
|
* @return array |
66
|
|
|
*/ |
67
|
|
|
public function getFunctions() |
68
|
|
|
{ |
69
|
|
|
return [ |
70
|
|
|
new TwigFunction( |
71
|
|
|
'ez_content_name', |
72
|
|
|
[$this, 'getTranslatedContentName'] |
73
|
|
|
), |
74
|
|
|
new TwigFunction( |
75
|
|
|
'ez_field_value', |
76
|
|
|
[$this, 'getTranslatedFieldValue'] |
77
|
|
|
), |
78
|
|
|
new TwigFunction( |
79
|
|
|
'ez_field', |
80
|
|
|
[$this, 'getTranslatedField'] |
81
|
|
|
), |
82
|
|
|
new TwigFunction( |
83
|
|
|
'ez_field_is_empty', |
84
|
|
|
[$this, 'isFieldEmpty'] |
85
|
|
|
), |
86
|
|
|
new TwigFunction( |
87
|
|
|
'ez_field_name', |
88
|
|
|
[$this, 'getTranslatedFieldDefinitionName'] |
89
|
|
|
), |
90
|
|
|
new TwigFunction( |
91
|
|
|
'ez_field_description', |
92
|
|
|
[$this, 'getTranslatedFieldDefinitionDescription'] |
93
|
|
|
), |
94
|
|
|
new TwigFunction( |
95
|
|
|
'ez_content_field_identifier_first_filled_image', |
96
|
|
|
[$this, 'getFirstFilledImageFieldIdentifier'] |
97
|
|
|
), |
98
|
|
|
]; |
99
|
|
|
} |
100
|
|
|
|
101
|
|
|
/** |
102
|
|
|
* Returns the name of the extension. |
103
|
|
|
* |
104
|
|
|
* @return string The extension name |
105
|
|
|
*/ |
106
|
|
|
public function getName() |
107
|
|
|
{ |
108
|
|
|
return 'ezpublish.content'; |
109
|
|
|
} |
110
|
|
|
|
111
|
|
|
/** |
112
|
|
|
* @param \eZ\Publish\API\Repository\Values\ValueObject $content Must be a valid Content or ContentInfo object. |
113
|
|
|
* @param string $forcedLanguage Locale we want the content name translation in (e.g. "fre-FR"). Null by default (takes current locale) |
114
|
|
|
* |
115
|
|
|
* @throws \eZ\Publish\Core\Base\Exceptions\InvalidArgumentType When $content is not a valid Content or ContentInfo object. |
116
|
|
|
* |
117
|
|
|
* @return string |
118
|
|
|
*/ |
119
|
|
|
public function getTranslatedContentName(ValueObject $content, $forcedLanguage = null) |
120
|
|
|
{ |
121
|
|
|
if ($content instanceof Content) { |
122
|
|
|
return $this->translationHelper->getTranslatedContentName($content, $forcedLanguage); |
123
|
|
|
} elseif ($content instanceof ContentInfo) { |
124
|
|
|
return $this->translationHelper->getTranslatedContentNameByContentInfo($content, $forcedLanguage); |
125
|
|
|
} |
126
|
|
|
|
127
|
|
|
throw new InvalidArgumentType('$content', 'eZ\Publish\API\Repository\Values\Content\Content or eZ\Publish\API\Repository\Values\Content\ContentInfo', $content); |
128
|
|
|
} |
129
|
|
|
|
130
|
|
|
/** |
131
|
|
|
* Returns the translated field, very similar to getTranslatedFieldValue but this returns the whole field. |
132
|
|
|
* To be used with ez_image_alias for example, which requires the whole field. |
133
|
|
|
* |
134
|
|
|
* @param \eZ\Publish\API\Repository\Values\Content\Content $content |
135
|
|
|
* @param string $fieldDefIdentifier Identifier for the field we want to get. |
136
|
|
|
* @param string $forcedLanguage Locale we want the field in (e.g. "cro-HR"). Null by default (takes current locale). |
137
|
|
|
* |
138
|
|
|
* @return \eZ\Publish\API\Repository\Values\Content\Field |
139
|
|
|
*/ |
140
|
|
|
public function getTranslatedField(Content $content, $fieldDefIdentifier, $forcedLanguage = null) |
141
|
|
|
{ |
142
|
|
|
return $this->translationHelper->getTranslatedField($content, $fieldDefIdentifier, $forcedLanguage); |
143
|
|
|
} |
144
|
|
|
|
145
|
|
|
/** |
146
|
|
|
* @param \eZ\Publish\API\Repository\Values\Content\Content $content |
147
|
|
|
* @param string $fieldDefIdentifier Identifier for the field we want to get the value from. |
148
|
|
|
* @param string $forcedLanguage Locale we want the content name translation in (e.g. "fre-FR"). Null by default (takes current locale). |
149
|
|
|
* |
150
|
|
|
* @return mixed A primitive type or a field type Value object depending on the field type. |
151
|
|
|
*/ |
152
|
|
|
public function getTranslatedFieldValue(Content $content, $fieldDefIdentifier, $forcedLanguage = null) |
153
|
|
|
{ |
154
|
|
|
return $this->translationHelper->getTranslatedField($content, $fieldDefIdentifier, $forcedLanguage)->value; |
155
|
|
|
} |
156
|
|
|
|
157
|
|
|
/** |
158
|
|
|
* Gets name of a FieldDefinition name by loading ContentType based on Content/ContentInfo object. |
159
|
|
|
* |
160
|
|
|
* @param \eZ\Publish\API\Repository\Values\ValueObject $content Must be Content or ContentInfo object |
161
|
|
|
* @param string $fieldDefIdentifier Identifier for the field we want to get the name from |
162
|
|
|
* @param string $forcedLanguage Locale we want the content name translation in (e.g. "fre-FR"). Null by default (takes current locale) |
163
|
|
|
* |
164
|
|
|
* @throws \eZ\Publish\Core\Base\Exceptions\InvalidArgumentType When $content is not a valid Content object. |
165
|
|
|
* |
166
|
|
|
* @return string|null |
167
|
|
|
*/ |
168
|
|
View Code Duplication |
public function getTranslatedFieldDefinitionName(ValueObject $content, $fieldDefIdentifier, $forcedLanguage = null) |
169
|
|
|
{ |
170
|
|
|
if ($contentType = $this->getContentType($content)) { |
171
|
|
|
return $this->translationHelper->getTranslatedFieldDefinitionProperty( |
172
|
|
|
$contentType, |
173
|
|
|
$fieldDefIdentifier, |
174
|
|
|
'name', |
175
|
|
|
$forcedLanguage |
176
|
|
|
); |
177
|
|
|
} |
178
|
|
|
|
179
|
|
|
throw new InvalidArgumentType('$content', 'Content|ContentInfo', $content); |
180
|
|
|
} |
181
|
|
|
|
182
|
|
|
/** |
183
|
|
|
* Gets name of a FieldDefinition description by loading ContentType based on Content/ContentInfo object. |
184
|
|
|
* |
185
|
|
|
* @param \eZ\Publish\API\Repository\Values\ValueObject $content Must be Content or ContentInfo object |
186
|
|
|
* @param string $fieldDefIdentifier Identifier for the field we want to get the name from |
187
|
|
|
* @param string $forcedLanguage Locale we want the content name translation in (e.g. "fre-FR"). Null by default (takes current locale) |
188
|
|
|
* |
189
|
|
|
* @throws \eZ\Publish\Core\Base\Exceptions\InvalidArgumentType When $content is not a valid Content object. |
190
|
|
|
* |
191
|
|
|
* @return string|null |
192
|
|
|
*/ |
193
|
|
View Code Duplication |
public function getTranslatedFieldDefinitionDescription(ValueObject $content, $fieldDefIdentifier, $forcedLanguage = null) |
194
|
|
|
{ |
195
|
|
|
if ($contentType = $this->getContentType($content)) { |
196
|
|
|
return $this->translationHelper->getTranslatedFieldDefinitionProperty( |
197
|
|
|
$contentType, |
198
|
|
|
$fieldDefIdentifier, |
199
|
|
|
'description', |
200
|
|
|
$forcedLanguage |
201
|
|
|
); |
202
|
|
|
} |
203
|
|
|
|
204
|
|
|
throw new InvalidArgumentType('$content', 'Content|ContentInfo', $content); |
205
|
|
|
} |
206
|
|
|
|
207
|
|
|
/** |
208
|
|
|
* Checks if a given field is considered empty. |
209
|
|
|
* This method accepts field as Objects or by identifiers. |
210
|
|
|
* |
211
|
|
|
* @param \eZ\Publish\API\Repository\Values\Content\Content $content |
212
|
|
|
* @param \eZ\Publish\API\Repository\Values\Content\Field|string $fieldDefIdentifier Field or Field Identifier to |
213
|
|
|
* get the value from. |
214
|
|
|
* @param string $forcedLanguage Locale we want the content name translation in (e.g. "fre-FR"). |
215
|
|
|
* Null by default (takes current locale). |
216
|
|
|
* |
217
|
|
|
* @return bool |
218
|
|
|
*/ |
219
|
|
|
public function isFieldEmpty(Content $content, $fieldDefIdentifier, $forcedLanguage = null) |
220
|
|
|
{ |
221
|
|
|
if ($fieldDefIdentifier instanceof Field) { |
222
|
|
|
$fieldDefIdentifier = $fieldDefIdentifier->fieldDefIdentifier; |
223
|
|
|
} |
224
|
|
|
|
225
|
|
|
return $this->fieldHelper->isFieldEmpty($content, $fieldDefIdentifier, $forcedLanguage); |
|
|
|
|
226
|
|
|
} |
227
|
|
|
|
228
|
|
|
/** |
229
|
|
|
* Get ContentType by Content/ContentInfo. |
230
|
|
|
* |
231
|
|
|
* @param \eZ\Publish\API\Repository\Values\Content\Content|\eZ\Publish\API\Repository\Values\Content\ContentInfo $content |
232
|
|
|
* |
233
|
|
|
* @return \eZ\Publish\API\Repository\Values\ContentType\ContentType|null |
234
|
|
|
*/ |
235
|
|
|
private function getContentType(ValueObject $content) |
236
|
|
|
{ |
237
|
|
|
if ($content instanceof Content) { |
238
|
|
|
return $this->repository->getContentTypeService()->loadContentType( |
239
|
|
|
$content->getVersionInfo()->getContentInfo()->contentTypeId |
240
|
|
|
); |
241
|
|
|
} elseif ($content instanceof ContentInfo) { |
242
|
|
|
return $this->repository->getContentTypeService()->loadContentType($content->contentTypeId); |
243
|
|
|
} |
244
|
|
|
} |
245
|
|
|
|
246
|
|
|
public function getFirstFilledImageFieldIdentifier(Content $content) |
247
|
|
|
{ |
248
|
|
|
foreach ($content->getFieldsByLanguage() as $field) { |
249
|
|
|
$fieldTypeIdentifier = $content->getContentType() |
250
|
|
|
->getFieldDefinition($field->fieldDefIdentifier) |
251
|
|
|
->fieldTypeIdentifier; |
252
|
|
|
|
253
|
|
|
if ($fieldTypeIdentifier !== 'ezimage') { |
254
|
|
|
continue; |
255
|
|
|
} |
256
|
|
|
|
257
|
|
|
if ($this->fieldHelper->isFieldEmpty($content, $field->fieldDefIdentifier)) { |
258
|
|
|
continue; |
259
|
|
|
} |
260
|
|
|
|
261
|
|
|
return $field->fieldDefIdentifier; |
262
|
|
|
} |
263
|
|
|
|
264
|
|
|
return null; |
265
|
|
|
} |
266
|
|
|
} |
267
|
|
|
|
This check looks at variables that have been passed in as parameters and are passed out again to other methods.
If the outgoing method call has stricter type requirements than the method itself, an issue is raised.
An additional type check may prevent trouble.