Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like DoctrineDatabase often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use DoctrineDatabase, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
40 | class DoctrineDatabase extends Gateway |
||
41 | { |
||
42 | /** |
||
43 | * eZ Doctrine database handler. |
||
44 | * |
||
45 | * @var \eZ\Publish\Core\Persistence\Database\DatabaseHandler |
||
46 | */ |
||
47 | protected $dbHandler; |
||
48 | |||
49 | /** |
||
50 | * The native Doctrine connection. |
||
51 | * |
||
52 | * Meant to be used to transition from eZ/Zeta interface to Doctrine. |
||
53 | * |
||
54 | * @var \Doctrine\DBAL\Connection |
||
55 | */ |
||
56 | protected $connection; |
||
57 | |||
58 | /** |
||
59 | * Query builder. |
||
60 | * |
||
61 | * @var \eZ\Publish\Core\Persistence\Legacy\Content\Gateway\DoctrineDatabase\QueryBuilder |
||
62 | */ |
||
63 | protected $queryBuilder; |
||
64 | |||
65 | /** |
||
66 | * Caching language handler. |
||
67 | * |
||
68 | * @var \eZ\Publish\Core\Persistence\Legacy\Content\Language\CachingHandler |
||
69 | */ |
||
70 | protected $languageHandler; |
||
71 | |||
72 | /** |
||
73 | * Language mask generator. |
||
74 | * |
||
75 | * @var \eZ\Publish\Core\Persistence\Legacy\Content\Language\MaskGenerator |
||
76 | */ |
||
77 | protected $languageMaskGenerator; |
||
78 | |||
79 | /** |
||
80 | * Creates a new gateway based on $db. |
||
81 | * |
||
82 | * @param \eZ\Publish\Core\Persistence\Database\DatabaseHandler $db |
||
83 | * @param \Doctrine\DBAL\Connection $connection |
||
84 | * @param \eZ\Publish\Core\Persistence\Legacy\Content\Gateway\DoctrineDatabase\QueryBuilder $queryBuilder |
||
85 | * @param \eZ\Publish\SPI\Persistence\Content\Language\Handler $languageHandler |
||
86 | * @param \eZ\Publish\Core\Persistence\Legacy\Content\Language\MaskGenerator $languageMaskGenerator |
||
87 | */ |
||
88 | public function __construct( |
||
89 | DatabaseHandler $db, |
||
90 | Connection $connection, |
||
91 | QueryBuilder $queryBuilder, |
||
92 | LanguageHandler $languageHandler, |
||
93 | LanguageMaskGenerator $languageMaskGenerator |
||
94 | ) { |
||
95 | $this->dbHandler = $db; |
||
96 | $this->connection = $connection; |
||
97 | $this->queryBuilder = $queryBuilder; |
||
98 | $this->languageHandler = $languageHandler; |
||
|
|||
99 | $this->languageMaskGenerator = $languageMaskGenerator; |
||
100 | } |
||
101 | |||
102 | /** |
||
103 | * Get context definition for external storage layers. |
||
104 | * |
||
105 | * @return array |
||
106 | */ |
||
107 | public function getContext() |
||
114 | |||
115 | /** |
||
116 | * Inserts a new content object. |
||
117 | * |
||
118 | * @param \eZ\Publish\SPI\Persistence\Content\CreateStruct $struct |
||
119 | * @param mixed $currentVersionNo |
||
120 | * |
||
121 | * @return int ID |
||
122 | */ |
||
123 | public function insertContentObject(CreateStruct $struct, $currentVersionNo = 1) |
||
124 | { |
||
125 | $initialLanguageId = !empty($struct->mainLanguageId) ? $struct->mainLanguageId : $struct->initialLanguageId; |
||
126 | $initialLanguageCode = $this->languageHandler->load($initialLanguageId)->languageCode; |
||
127 | |||
128 | if (isset($struct->name[$initialLanguageCode])) { |
||
129 | $name = $struct->name[$initialLanguageCode]; |
||
130 | } else { |
||
131 | $name = ''; |
||
132 | } |
||
133 | |||
134 | $q = $this->dbHandler->createInsertQuery(); |
||
135 | $q->insertInto( |
||
136 | $this->dbHandler->quoteTable('ezcontentobject') |
||
137 | )->set( |
||
138 | $this->dbHandler->quoteColumn('id'), |
||
139 | $this->dbHandler->getAutoIncrementValue('ezcontentobject', 'id') |
||
140 | )->set( |
||
141 | $this->dbHandler->quoteColumn('current_version'), |
||
142 | $q->bindValue($currentVersionNo, null, \PDO::PARAM_INT) |
||
143 | )->set( |
||
144 | $this->dbHandler->quoteColumn('name'), |
||
145 | $q->bindValue($name, null, \PDO::PARAM_STR) |
||
146 | )->set( |
||
147 | $this->dbHandler->quoteColumn('contentclass_id'), |
||
148 | $q->bindValue($struct->typeId, null, \PDO::PARAM_INT) |
||
149 | )->set( |
||
150 | $this->dbHandler->quoteColumn('section_id'), |
||
151 | $q->bindValue($struct->sectionId, null, \PDO::PARAM_INT) |
||
152 | )->set( |
||
153 | $this->dbHandler->quoteColumn('owner_id'), |
||
154 | $q->bindValue($struct->ownerId, null, \PDO::PARAM_INT) |
||
155 | )->set( |
||
156 | $this->dbHandler->quoteColumn('initial_language_id'), |
||
157 | $q->bindValue($initialLanguageId, null, \PDO::PARAM_INT) |
||
158 | )->set( |
||
159 | $this->dbHandler->quoteColumn('remote_id'), |
||
160 | $q->bindValue($struct->remoteId, null, \PDO::PARAM_STR) |
||
161 | )->set( |
||
162 | $this->dbHandler->quoteColumn('modified'), |
||
163 | $q->bindValue(0, null, \PDO::PARAM_INT) |
||
164 | )->set( |
||
165 | $this->dbHandler->quoteColumn('published'), |
||
166 | $q->bindValue(0, null, \PDO::PARAM_INT) |
||
167 | )->set( |
||
168 | $this->dbHandler->quoteColumn('status'), |
||
169 | $q->bindValue(ContentInfo::STATUS_DRAFT, null, \PDO::PARAM_INT) |
||
170 | )->set( |
||
171 | $this->dbHandler->quoteColumn('language_mask'), |
||
172 | $q->bindValue( |
||
173 | $this->generateLanguageMask( |
||
174 | $struct->fields, |
||
175 | $initialLanguageCode, |
||
176 | $struct->alwaysAvailable |
||
177 | ), |
||
178 | null, |
||
179 | \PDO::PARAM_INT |
||
180 | ) |
||
181 | ); |
||
182 | |||
183 | $q->prepare()->execute(); |
||
184 | |||
185 | return $this->dbHandler->lastInsertId( |
||
186 | $this->dbHandler->getSequenceName('ezcontentobject', 'id') |
||
187 | ); |
||
188 | } |
||
189 | |||
190 | /** |
||
191 | * Generates a language mask for $version. |
||
192 | * |
||
193 | * @param \eZ\Publish\SPI\Persistence\Content\Field[] $fields |
||
194 | * @param string $initialLanguageCode |
||
195 | * @param bool $alwaysAvailable |
||
196 | * |
||
197 | * @return int |
||
198 | */ |
||
199 | protected function generateLanguageMask(array $fields, $initialLanguageCode, $alwaysAvailable) |
||
200 | { |
||
201 | $languages = array($initialLanguageCode => true); |
||
202 | View Code Duplication | foreach ($fields as $field) { |
|
203 | if (isset($languages[$field->languageCode])) { |
||
204 | continue; |
||
205 | } |
||
206 | |||
207 | $languages[$field->languageCode] = true; |
||
208 | } |
||
209 | |||
210 | if ($alwaysAvailable) { |
||
211 | $languages['always-available'] = true; |
||
212 | } |
||
213 | |||
214 | return $this->languageMaskGenerator->generateLanguageMask($languages); |
||
215 | } |
||
216 | |||
217 | /** |
||
218 | * Inserts a new version. |
||
219 | * |
||
220 | * @param \eZ\Publish\SPI\Persistence\Content\VersionInfo $versionInfo |
||
221 | * @param \eZ\Publish\SPI\Persistence\Content\Field[] $fields |
||
222 | * |
||
223 | * @return int ID |
||
224 | */ |
||
225 | public function insertVersion(VersionInfo $versionInfo, array $fields) |
||
226 | { |
||
227 | /** @var $q \eZ\Publish\Core\Persistence\Database\InsertQuery */ |
||
228 | $q = $this->dbHandler->createInsertQuery(); |
||
229 | $q->insertInto( |
||
230 | $this->dbHandler->quoteTable('ezcontentobject_version') |
||
231 | )->set( |
||
232 | $this->dbHandler->quoteColumn('id'), |
||
233 | $this->dbHandler->getAutoIncrementValue('ezcontentobject_version', 'id') |
||
234 | )->set( |
||
235 | $this->dbHandler->quoteColumn('version'), |
||
236 | $q->bindValue($versionInfo->versionNo, null, \PDO::PARAM_INT) |
||
237 | )->set( |
||
238 | $this->dbHandler->quoteColumn('modified'), |
||
239 | $q->bindValue($versionInfo->modificationDate, null, \PDO::PARAM_INT) |
||
240 | )->set( |
||
241 | $this->dbHandler->quoteColumn('creator_id'), |
||
242 | $q->bindValue($versionInfo->creatorId, null, \PDO::PARAM_INT) |
||
243 | )->set( |
||
244 | $this->dbHandler->quoteColumn('created'), |
||
245 | $q->bindValue($versionInfo->creationDate, null, \PDO::PARAM_INT) |
||
246 | )->set( |
||
247 | $this->dbHandler->quoteColumn('status'), |
||
248 | $q->bindValue($versionInfo->status, null, \PDO::PARAM_INT) |
||
249 | )->set( |
||
250 | $this->dbHandler->quoteColumn('initial_language_id'), |
||
251 | $q->bindValue( |
||
252 | $this->languageHandler->loadByLanguageCode($versionInfo->initialLanguageCode)->id, |
||
253 | null, |
||
254 | \PDO::PARAM_INT |
||
255 | ) |
||
256 | )->set( |
||
257 | $this->dbHandler->quoteColumn('contentobject_id'), |
||
258 | $q->bindValue($versionInfo->contentInfo->id, null, \PDO::PARAM_INT) |
||
259 | )->set( |
||
260 | // As described in field mapping document |
||
261 | $this->dbHandler->quoteColumn('workflow_event_pos'), |
||
262 | $q->bindValue(0, null, \PDO::PARAM_INT) |
||
263 | )->set( |
||
264 | $this->dbHandler->quoteColumn('language_mask'), |
||
265 | $q->bindValue( |
||
266 | $this->generateLanguageMask( |
||
267 | $fields, |
||
268 | $versionInfo->initialLanguageCode, |
||
269 | $versionInfo->contentInfo->alwaysAvailable |
||
270 | ), |
||
271 | null, |
||
272 | \PDO::PARAM_INT |
||
273 | ) |
||
274 | ); |
||
275 | |||
276 | $q->prepare()->execute(); |
||
277 | |||
278 | return $this->dbHandler->lastInsertId( |
||
279 | $this->dbHandler->getSequenceName('ezcontentobject_version', 'id') |
||
280 | ); |
||
281 | } |
||
282 | |||
283 | /** |
||
284 | * Updates an existing content identified by $contentId in respect to $struct. |
||
285 | * |
||
286 | * @param int $contentId |
||
287 | * @param \eZ\Publish\SPI\Persistence\Content\MetadataUpdateStruct $struct |
||
288 | * @param \eZ\Publish\SPI\Persistence\Content\VersionInfo $prePublishVersionInfo Provided on publish |
||
289 | */ |
||
290 | public function updateContent($contentId, MetadataUpdateStruct $struct, VersionInfo $prePublishVersionInfo = null) |
||
291 | { |
||
292 | $q = $this->dbHandler->createUpdateQuery(); |
||
293 | $q->update($this->dbHandler->quoteTable('ezcontentobject')); |
||
294 | |||
295 | if (isset($struct->name)) { |
||
296 | $q->set( |
||
297 | $this->dbHandler->quoteColumn('name'), |
||
298 | $q->bindValue($struct->name, null, \PDO::PARAM_STR) |
||
299 | ); |
||
300 | } |
||
301 | if (isset($struct->mainLanguageId)) { |
||
302 | $q->set( |
||
303 | $this->dbHandler->quoteColumn('initial_language_id'), |
||
304 | $q->bindValue($struct->mainLanguageId, null, \PDO::PARAM_INT) |
||
305 | ); |
||
306 | } |
||
307 | if (isset($struct->modificationDate)) { |
||
308 | $q->set( |
||
309 | $this->dbHandler->quoteColumn('modified'), |
||
310 | $q->bindValue($struct->modificationDate, null, \PDO::PARAM_INT) |
||
311 | ); |
||
312 | } |
||
313 | if (isset($struct->ownerId)) { |
||
314 | $q->set( |
||
315 | $this->dbHandler->quoteColumn('owner_id'), |
||
316 | $q->bindValue($struct->ownerId, null, \PDO::PARAM_INT) |
||
317 | ); |
||
318 | } |
||
319 | if (isset($struct->publicationDate)) { |
||
320 | $q->set( |
||
321 | $this->dbHandler->quoteColumn('published'), |
||
322 | $q->bindValue($struct->publicationDate, null, \PDO::PARAM_INT) |
||
323 | ); |
||
324 | } |
||
325 | if (isset($struct->remoteId)) { |
||
326 | $q->set( |
||
327 | $this->dbHandler->quoteColumn('remote_id'), |
||
328 | $q->bindValue($struct->remoteId, null, \PDO::PARAM_STR) |
||
329 | ); |
||
330 | } |
||
331 | if ($prePublishVersionInfo !== null) { |
||
332 | $languages = []; |
||
333 | foreach ($prePublishVersionInfo->languageCodes as $languageCodes) { |
||
334 | if (!isset($languages[$languageCodes])) { |
||
335 | $languages[$languageCodes] = true; |
||
336 | } |
||
337 | } |
||
338 | |||
339 | $languages['always-available'] = isset($struct->alwaysAvailable) ? $struct->alwaysAvailable : |
||
340 | $prePublishVersionInfo->contentInfo->alwaysAvailable; |
||
341 | |||
342 | $mask = $this->languageMaskGenerator->generateLanguageMask($languages); |
||
343 | |||
344 | $q->set( |
||
345 | $this->dbHandler->quoteColumn('language_mask'), |
||
346 | $q->bindValue($mask, null, \PDO::PARAM_INT) |
||
347 | ); |
||
348 | } |
||
349 | $q->where( |
||
350 | $q->expr->eq( |
||
351 | $this->dbHandler->quoteColumn('id'), |
||
352 | $q->bindValue($contentId, null, \PDO::PARAM_INT) |
||
353 | ) |
||
354 | ); |
||
355 | $q->prepare()->execute(); |
||
356 | |||
357 | // Handle alwaysAvailable flag update separately as it's a more complex task and has impact on several tables |
||
358 | if (isset($struct->alwaysAvailable) || isset($struct->mainLanguageId)) { |
||
359 | $this->updateAlwaysAvailableFlag($contentId, $struct->alwaysAvailable); |
||
360 | } |
||
361 | } |
||
362 | |||
363 | /** |
||
364 | * Updates version $versionNo for content identified by $contentId, in respect to $struct. |
||
365 | * |
||
366 | * @param int $contentId |
||
367 | * @param int $versionNo |
||
368 | * @param \eZ\Publish\SPI\Persistence\Content\UpdateStruct $struct |
||
369 | */ |
||
370 | public function updateVersion($contentId, $versionNo, UpdateStruct $struct) |
||
371 | { |
||
372 | $q = $this->dbHandler->createUpdateQuery(); |
||
373 | $q->update( |
||
374 | $this->dbHandler->quoteTable('ezcontentobject_version') |
||
375 | )->set( |
||
376 | $this->dbHandler->quoteColumn('creator_id'), |
||
377 | $q->bindValue($struct->creatorId, null, \PDO::PARAM_INT) |
||
378 | )->set( |
||
379 | $this->dbHandler->quoteColumn('modified'), |
||
380 | $q->bindValue($struct->modificationDate, null, \PDO::PARAM_INT) |
||
381 | )->set( |
||
382 | $this->dbHandler->quoteColumn('initial_language_id'), |
||
383 | $q->bindValue($struct->initialLanguageId, null, \PDO::PARAM_INT) |
||
384 | )->set( |
||
385 | $this->dbHandler->quoteColumn('language_mask'), |
||
386 | $q->expr->bitOr( |
||
387 | $this->dbHandler->quoteColumn('language_mask'), |
||
388 | $q->bindValue( |
||
389 | $this->generateLanguageMask( |
||
390 | $struct->fields, |
||
391 | $this->languageHandler->load($struct->initialLanguageId)->languageCode, |
||
392 | false |
||
393 | ), |
||
394 | null, |
||
395 | \PDO::PARAM_INT |
||
396 | ) |
||
397 | ) |
||
398 | )->where( |
||
399 | $q->expr->lAnd( |
||
400 | $q->expr->eq( |
||
401 | $this->dbHandler->quoteColumn('contentobject_id'), |
||
402 | $q->bindValue($contentId, null, \PDO::PARAM_INT) |
||
403 | ), |
||
404 | $q->expr->eq( |
||
405 | $this->dbHandler->quoteColumn('version'), |
||
406 | $q->bindValue($versionNo, null, \PDO::PARAM_INT) |
||
407 | ) |
||
408 | ) |
||
409 | ); |
||
410 | $q->prepare()->execute(); |
||
411 | } |
||
412 | |||
413 | /** |
||
414 | * Updates "always available" flag for Content identified by $contentId, in respect to |
||
415 | * Content's current main language and optionally new $alwaysAvailable state. |
||
416 | * |
||
417 | * @param int $contentId |
||
418 | * @param bool|null $alwaysAvailable New "always available" value or null if not defined |
||
419 | */ |
||
420 | public function updateAlwaysAvailableFlag($contentId, $alwaysAvailable = null) |
||
421 | { |
||
422 | // We will need to know some info on the current language mask to update the flag |
||
423 | // everywhere needed |
||
424 | $contentInfoRow = $this->loadContentInfo($contentId); |
||
425 | if (!isset($alwaysAvailable)) { |
||
426 | $alwaysAvailable = (bool)$contentInfoRow['language_mask'] & 1; |
||
427 | } |
||
428 | |||
429 | /** @var $q \eZ\Publish\Core\Persistence\Database\UpdateQuery */ |
||
430 | $q = $this->dbHandler->createUpdateQuery(); |
||
431 | $q |
||
432 | ->update($this->dbHandler->quoteTable('ezcontentobject')) |
||
433 | ->set( |
||
434 | $this->dbHandler->quoteColumn('language_mask'), |
||
435 | $alwaysAvailable ? |
||
436 | $q->expr->bitOr($this->dbHandler->quoteColumn('language_mask'), 1) : |
||
437 | $q->expr->bitAnd($this->dbHandler->quoteColumn('language_mask'), -2) |
||
438 | ) |
||
439 | ->where( |
||
440 | $q->expr->eq( |
||
441 | $this->dbHandler->quoteColumn('id'), |
||
442 | $q->bindValue($contentId, null, \PDO::PARAM_INT) |
||
443 | ) |
||
444 | ); |
||
445 | $q->prepare()->execute(); |
||
446 | |||
447 | // Now we need to update ezcontentobject_name |
||
448 | /** @var $qName \eZ\Publish\Core\Persistence\Database\UpdateQuery */ |
||
449 | $qName = $this->dbHandler->createUpdateQuery(); |
||
450 | $qName |
||
451 | ->update($this->dbHandler->quoteTable('ezcontentobject_name')) |
||
452 | ->set( |
||
453 | $this->dbHandler->quoteColumn('language_id'), |
||
454 | $alwaysAvailable ? |
||
455 | $qName->expr->bitOr($this->dbHandler->quoteColumn('language_id'), 1) : |
||
456 | $qName->expr->bitAnd($this->dbHandler->quoteColumn('language_id'), -2) |
||
457 | ) |
||
458 | ->where( |
||
459 | $qName->expr->lAnd( |
||
460 | $qName->expr->eq( |
||
461 | $this->dbHandler->quoteColumn('contentobject_id'), |
||
462 | $qName->bindValue($contentId, null, \PDO::PARAM_INT) |
||
463 | ), |
||
464 | $qName->expr->eq( |
||
465 | $this->dbHandler->quoteColumn('content_version'), |
||
466 | $qName->bindValue( |
||
467 | $contentInfoRow['current_version'], |
||
468 | null, |
||
469 | \PDO::PARAM_INT |
||
470 | ) |
||
471 | ) |
||
472 | ) |
||
473 | ); |
||
474 | $qName->prepare()->execute(); |
||
475 | |||
476 | // Now update ezcontentobject_attribute for current version |
||
477 | // Create update query that will be reused |
||
478 | /** @var $qAttr \eZ\Publish\Core\Persistence\Database\UpdateQuery */ |
||
479 | $qAttr = $this->dbHandler->createUpdateQuery(); |
||
480 | $qAttr |
||
481 | ->update($this->dbHandler->quoteTable('ezcontentobject_attribute')) |
||
482 | ->where( |
||
483 | $qAttr->expr->lAnd( |
||
484 | $qAttr->expr->eq( |
||
485 | $this->dbHandler->quoteColumn('contentobject_id'), |
||
486 | $qAttr->bindValue($contentId, null, \PDO::PARAM_INT) |
||
487 | ), |
||
488 | $qAttr->expr->eq( |
||
489 | $this->dbHandler->quoteColumn('version'), |
||
490 | $qAttr->bindValue( |
||
491 | $contentInfoRow['current_version'], |
||
492 | null, |
||
493 | \PDO::PARAM_INT |
||
494 | ) |
||
495 | ) |
||
496 | ) |
||
497 | ); |
||
498 | |||
499 | // If there is only a single language, update all fields and return |
||
500 | if (!$this->languageMaskGenerator->isLanguageMaskComposite($contentInfoRow['language_mask'])) { |
||
501 | $qAttr->set( |
||
502 | $this->dbHandler->quoteColumn('language_id'), |
||
503 | $alwaysAvailable ? |
||
504 | $qAttr->expr->bitOr($this->dbHandler->quoteColumn('language_id'), 1) : |
||
505 | $qAttr->expr->bitAnd($this->dbHandler->quoteColumn('language_id'), -2) |
||
506 | ); |
||
507 | $qAttr->prepare()->execute(); |
||
508 | |||
509 | return; |
||
510 | } |
||
511 | |||
512 | // Otherwise: |
||
513 | // 1. Remove always available flag on all fields |
||
514 | $qAttr->set( |
||
515 | $this->dbHandler->quoteColumn('language_id'), |
||
516 | $qAttr->expr->bitAnd($this->dbHandler->quoteColumn('language_id'), -2) |
||
517 | ); |
||
518 | $qAttr->prepare()->execute(); |
||
519 | |||
520 | // 2. If Content is always available set the flag only on fields in main language |
||
521 | if ($alwaysAvailable) { |
||
522 | $qAttr->set( |
||
523 | $this->dbHandler->quoteColumn('language_id'), |
||
524 | $qAttr->expr->bitOr($this->dbHandler->quoteColumn('language_id'), 1) |
||
525 | ); |
||
526 | $qAttr->where( |
||
527 | $qAttr->expr->gt( |
||
528 | $qAttr->expr->bitAnd( |
||
529 | $this->dbHandler->quoteColumn('language_id'), |
||
530 | $qAttr->bindValue($contentInfoRow['initial_language_id'], null, PDO::PARAM_INT) |
||
531 | ), |
||
532 | $qAttr->bindValue(0, null, PDO::PARAM_INT) |
||
533 | ) |
||
534 | ); |
||
535 | $qAttr->prepare()->execute(); |
||
536 | } |
||
537 | } |
||
538 | |||
539 | /** |
||
540 | * Sets the status of the version identified by $contentId and $version to $status. |
||
541 | * |
||
542 | * The $status can be one of STATUS_DRAFT, STATUS_PUBLISHED, STATUS_ARCHIVED |
||
543 | * |
||
544 | * @param int $contentId |
||
545 | * @param int $version |
||
546 | * @param int $status |
||
547 | * |
||
548 | * @return bool |
||
549 | */ |
||
550 | public function setStatus($contentId, $version, $status) |
||
551 | { |
||
552 | $q = $this->dbHandler->createUpdateQuery(); |
||
553 | $q->update( |
||
554 | $this->dbHandler->quoteTable('ezcontentobject_version') |
||
555 | )->set( |
||
556 | $this->dbHandler->quoteColumn('status'), |
||
557 | $q->bindValue($status, null, \PDO::PARAM_INT) |
||
558 | )->set( |
||
559 | $this->dbHandler->quoteColumn('modified'), |
||
560 | $q->bindValue(time(), null, \PDO::PARAM_INT) |
||
561 | )->where( |
||
562 | $q->expr->lAnd( |
||
563 | $q->expr->eq( |
||
564 | $this->dbHandler->quoteColumn('contentobject_id'), |
||
565 | $q->bindValue($contentId, null, \PDO::PARAM_INT) |
||
566 | ), |
||
567 | $q->expr->eq( |
||
568 | $this->dbHandler->quoteColumn('version'), |
||
569 | $q->bindValue($version, null, \PDO::PARAM_INT) |
||
570 | ) |
||
571 | ) |
||
572 | ); |
||
573 | $statement = $q->prepare(); |
||
574 | $statement->execute(); |
||
575 | |||
576 | if ((bool)$statement->rowCount() === false) { |
||
577 | return false; |
||
578 | } |
||
579 | |||
580 | if ($status !== APIVersionInfo::STATUS_PUBLISHED) { |
||
581 | return true; |
||
582 | } |
||
583 | |||
584 | // If the version's status is PUBLISHED, we set the content to published status as well |
||
585 | $q = $this->dbHandler->createUpdateQuery(); |
||
586 | $q->update( |
||
587 | $this->dbHandler->quoteTable('ezcontentobject') |
||
588 | )->set( |
||
589 | $this->dbHandler->quoteColumn('status'), |
||
590 | $q->bindValue(ContentInfo::STATUS_PUBLISHED, null, \PDO::PARAM_INT) |
||
591 | )->set( |
||
592 | $this->dbHandler->quoteColumn('current_version'), |
||
593 | $q->bindValue($version, null, \PDO::PARAM_INT) |
||
594 | )->where( |
||
595 | $q->expr->eq( |
||
596 | $this->dbHandler->quoteColumn('id'), |
||
597 | $q->bindValue($contentId, null, \PDO::PARAM_INT) |
||
598 | ) |
||
599 | ); |
||
600 | $statement = $q->prepare(); |
||
601 | $statement->execute(); |
||
602 | |||
603 | return (bool)$statement->rowCount(); |
||
604 | } |
||
605 | |||
606 | /** |
||
607 | * Inserts a new field. |
||
608 | * |
||
609 | * Only used when a new field is created (i.e. a new object or a field in a |
||
610 | * new language!). After that, field IDs need to stay the same, only the |
||
611 | * version number changes. |
||
612 | * |
||
613 | * @param \eZ\Publish\SPI\Persistence\Content $content |
||
614 | * @param \eZ\Publish\SPI\Persistence\Content\Field $field |
||
615 | * @param \eZ\Publish\Core\Persistence\Legacy\Content\StorageFieldValue $value |
||
616 | * |
||
617 | * @return int ID |
||
618 | */ |
||
619 | public function insertNewField(Content $content, Field $field, StorageFieldValue $value) |
||
620 | { |
||
621 | $q = $this->dbHandler->createInsertQuery(); |
||
622 | |||
623 | $this->setInsertFieldValues($q, $content, $field, $value); |
||
624 | |||
625 | // Insert with auto increment ID |
||
626 | $q->set( |
||
627 | $this->dbHandler->quoteColumn('id'), |
||
628 | $this->dbHandler->getAutoIncrementValue('ezcontentobject_attribute', 'id') |
||
629 | ); |
||
630 | |||
631 | $q->prepare()->execute(); |
||
632 | |||
633 | return $this->dbHandler->lastInsertId( |
||
634 | $this->dbHandler->getSequenceName('ezcontentobject_attribute', 'id') |
||
635 | ); |
||
636 | } |
||
637 | |||
638 | /** |
||
639 | * Inserts an existing field. |
||
640 | * |
||
641 | * Used to insert a field with an exsting ID but a new version number. |
||
642 | * |
||
643 | * @param Content $content |
||
644 | * @param Field $field |
||
645 | * @param StorageFieldValue $value |
||
646 | */ |
||
647 | public function insertExistingField(Content $content, Field $field, StorageFieldValue $value) |
||
648 | { |
||
649 | $q = $this->dbHandler->createInsertQuery(); |
||
650 | |||
651 | $this->setInsertFieldValues($q, $content, $field, $value); |
||
652 | |||
653 | $q->set( |
||
654 | $this->dbHandler->quoteColumn('id'), |
||
655 | $q->bindValue($field->id, null, \PDO::PARAM_INT) |
||
656 | ); |
||
657 | |||
658 | $q->prepare()->execute(); |
||
659 | } |
||
660 | |||
661 | /** |
||
662 | * Sets field (ezcontentobject_attribute) values to the given query. |
||
663 | * |
||
664 | * @param \eZ\Publish\Core\Persistence\Database\InsertQuery $q |
||
665 | * @param Content $content |
||
666 | * @param Field $field |
||
667 | * @param StorageFieldValue $value |
||
668 | */ |
||
669 | protected function setInsertFieldValues(InsertQuery $q, Content $content, Field $field, StorageFieldValue $value) |
||
670 | { |
||
671 | $q->insertInto( |
||
672 | $this->dbHandler->quoteTable('ezcontentobject_attribute') |
||
673 | )->set( |
||
674 | $this->dbHandler->quoteColumn('contentobject_id'), |
||
675 | $q->bindValue($content->versionInfo->contentInfo->id, null, \PDO::PARAM_INT) |
||
676 | )->set( |
||
677 | $this->dbHandler->quoteColumn('contentclassattribute_id'), |
||
678 | $q->bindValue($field->fieldDefinitionId, null, \PDO::PARAM_INT) |
||
679 | )->set( |
||
680 | $this->dbHandler->quoteColumn('data_type_string'), |
||
681 | $q->bindValue($field->type) |
||
682 | )->set( |
||
683 | $this->dbHandler->quoteColumn('language_code'), |
||
684 | $q->bindValue($field->languageCode) |
||
685 | )->set( |
||
686 | $this->dbHandler->quoteColumn('version'), |
||
687 | $q->bindValue($field->versionNo, null, \PDO::PARAM_INT) |
||
688 | )->set( |
||
689 | $this->dbHandler->quoteColumn('data_float'), |
||
690 | $q->bindValue($value->dataFloat) |
||
691 | )->set( |
||
692 | $this->dbHandler->quoteColumn('data_int'), |
||
693 | $q->bindValue($value->dataInt, null, \PDO::PARAM_INT) |
||
694 | )->set( |
||
695 | $this->dbHandler->quoteColumn('data_text'), |
||
696 | $q->bindValue($value->dataText) |
||
697 | )->set( |
||
698 | $this->dbHandler->quoteColumn('sort_key_int'), |
||
699 | $q->bindValue($value->sortKeyInt, null, \PDO::PARAM_INT) |
||
700 | )->set( |
||
701 | $this->dbHandler->quoteColumn('sort_key_string'), |
||
702 | $q->bindValue(mb_substr($value->sortKeyString, 0, 255)) |
||
703 | )->set( |
||
704 | $this->dbHandler->quoteColumn('language_id'), |
||
705 | $q->bindValue( |
||
706 | $this->languageMaskGenerator->generateLanguageIndicator( |
||
707 | $field->languageCode, |
||
708 | $this->isLanguageAlwaysAvailable($content, $field->languageCode) |
||
709 | ), |
||
710 | null, |
||
711 | \PDO::PARAM_INT |
||
712 | ) |
||
713 | ); |
||
714 | } |
||
715 | |||
716 | /** |
||
717 | * Checks if $languageCode is always available in $content. |
||
718 | * |
||
719 | * @param \eZ\Publish\SPI\Persistence\Content $content |
||
720 | * @param string $languageCode |
||
721 | * |
||
722 | * @return bool |
||
723 | */ |
||
724 | protected function isLanguageAlwaysAvailable(Content $content, $languageCode) |
||
725 | { |
||
726 | return |
||
727 | $content->versionInfo->contentInfo->alwaysAvailable && |
||
728 | $content->versionInfo->contentInfo->mainLanguageCode === $languageCode |
||
729 | ; |
||
730 | } |
||
731 | |||
732 | /** |
||
733 | * Updates an existing field. |
||
734 | * |
||
735 | * @param Field $field |
||
736 | * @param StorageFieldValue $value |
||
737 | */ |
||
738 | public function updateField(Field $field, StorageFieldValue $value) |
||
739 | { |
||
740 | // Note, no need to care for language_id here, since Content->$alwaysAvailable |
||
741 | // cannot change on update |
||
742 | $q = $this->dbHandler->createUpdateQuery(); |
||
743 | $this->setFieldUpdateValues($q, $value); |
||
744 | $q->where( |
||
745 | $q->expr->lAnd( |
||
746 | $q->expr->eq( |
||
747 | $this->dbHandler->quoteColumn('id'), |
||
748 | $q->bindValue($field->id, null, \PDO::PARAM_INT) |
||
749 | ), |
||
750 | $q->expr->eq( |
||
751 | $this->dbHandler->quoteColumn('version'), |
||
752 | $q->bindValue($field->versionNo, null, \PDO::PARAM_INT) |
||
753 | ) |
||
754 | ) |
||
755 | ); |
||
756 | $q->prepare()->execute(); |
||
757 | } |
||
758 | |||
759 | /** |
||
760 | * Sets update fields for $value on $q. |
||
761 | * |
||
762 | * @param \eZ\Publish\Core\Persistence\Database\UpdateQuery $q |
||
763 | * @param StorageFieldValue $value |
||
764 | */ |
||
765 | protected function setFieldUpdateValues(UpdateQuery $q, StorageFieldValue $value) |
||
766 | { |
||
767 | $q->update( |
||
768 | $this->dbHandler->quoteTable('ezcontentobject_attribute') |
||
769 | )->set( |
||
770 | $this->dbHandler->quoteColumn('data_float'), |
||
771 | $q->bindValue($value->dataFloat) |
||
772 | )->set( |
||
773 | $this->dbHandler->quoteColumn('data_int'), |
||
774 | $q->bindValue($value->dataInt, null, \PDO::PARAM_INT) |
||
775 | )->set( |
||
776 | $this->dbHandler->quoteColumn('data_text'), |
||
777 | $q->bindValue($value->dataText) |
||
778 | )->set( |
||
779 | $this->dbHandler->quoteColumn('sort_key_int'), |
||
780 | $q->bindValue($value->sortKeyInt, null, \PDO::PARAM_INT) |
||
781 | )->set( |
||
782 | $this->dbHandler->quoteColumn('sort_key_string'), |
||
783 | $q->bindValue(mb_substr($value->sortKeyString, 0, 255)) |
||
784 | ); |
||
785 | } |
||
786 | |||
787 | /** |
||
788 | * Updates an existing, non-translatable field. |
||
789 | * |
||
790 | * @param \eZ\Publish\SPI\Persistence\Content\Field $field |
||
791 | * @param \eZ\Publish\Core\Persistence\Legacy\Content\StorageFieldValue $value |
||
792 | * @param int $contentId |
||
793 | */ |
||
794 | public function updateNonTranslatableField( |
||
795 | Field $field, |
||
796 | StorageFieldValue $value, |
||
797 | $contentId |
||
798 | ) { |
||
799 | // Note, no need to care for language_id here, since Content->$alwaysAvailable |
||
800 | // cannot change on update |
||
801 | $q = $this->dbHandler->createUpdateQuery(); |
||
802 | $this->setFieldUpdateValues($q, $value); |
||
803 | $q->where( |
||
804 | $q->expr->lAnd( |
||
805 | $q->expr->eq( |
||
806 | $this->dbHandler->quoteColumn('contentclassattribute_id'), |
||
807 | $q->bindValue($field->fieldDefinitionId, null, \PDO::PARAM_INT) |
||
808 | ), |
||
809 | $q->expr->eq( |
||
810 | $this->dbHandler->quoteColumn('contentobject_id'), |
||
811 | $q->bindValue($contentId, null, \PDO::PARAM_INT) |
||
812 | ), |
||
813 | $q->expr->eq( |
||
814 | $this->dbHandler->quoteColumn('version'), |
||
815 | $q->bindValue($field->versionNo, null, \PDO::PARAM_INT) |
||
816 | ) |
||
817 | ) |
||
818 | ); |
||
819 | $q->prepare()->execute(); |
||
820 | } |
||
821 | |||
822 | /** |
||
823 | * Loads data for a content object. |
||
824 | * |
||
825 | * Returns an array with the relevant data. |
||
826 | * |
||
827 | * @param mixed $contentId |
||
828 | * @param mixed $version |
||
829 | * @param string[] $translations |
||
830 | * |
||
831 | * @return array |
||
832 | */ |
||
833 | public function load($contentId, $version, array $translations = null) |
||
834 | { |
||
835 | $query = $this->queryBuilder->createFindQuery($translations); |
||
836 | $query->where( |
||
837 | $query->expr->lAnd( |
||
838 | $query->expr->eq( |
||
839 | $this->dbHandler->quoteColumn('id', 'ezcontentobject'), |
||
840 | $query->bindValue($contentId) |
||
841 | ), |
||
842 | $query->expr->eq( |
||
843 | $this->dbHandler->quoteColumn('version', 'ezcontentobject_version'), |
||
844 | $query->bindValue($version) |
||
845 | ) |
||
846 | ) |
||
847 | ); |
||
848 | $statement = $query->prepare(); |
||
849 | $statement->execute(); |
||
850 | |||
851 | return $statement->fetchAll(\PDO::FETCH_ASSOC); |
||
852 | } |
||
853 | |||
854 | /** |
||
855 | * @see loadContentInfo(), loadContentInfoByRemoteId() |
||
856 | * |
||
857 | * @param string $column |
||
858 | * @param mixed $id |
||
859 | * |
||
860 | * @throws \eZ\Publish\Core\Base\Exceptions\NotFoundException |
||
861 | * |
||
862 | * @return array |
||
863 | */ |
||
864 | private function internalLoadContentInfo($column, $id) |
||
865 | { |
||
866 | /** @var $query \eZ\Publish\Core\Persistence\Database\SelectQuery */ |
||
867 | $query = $this->dbHandler->createSelectQuery(); |
||
868 | $query->select( |
||
869 | 'ezcontentobject.*', |
||
870 | $this->dbHandler->aliasedColumn($query, 'main_node_id', 'ezcontentobject_tree') |
||
871 | )->from( |
||
872 | $this->dbHandler->quoteTable('ezcontentobject') |
||
873 | )->leftJoin( |
||
874 | $this->dbHandler->quoteTable('ezcontentobject_tree'), |
||
875 | $query->expr->lAnd( |
||
876 | $query->expr->eq( |
||
877 | $this->dbHandler->quoteColumn('contentobject_id', 'ezcontentobject_tree'), |
||
878 | $this->dbHandler->quoteColumn('id', 'ezcontentobject') |
||
879 | ), |
||
880 | $query->expr->eq( |
||
881 | $this->dbHandler->quoteColumn('main_node_id', 'ezcontentobject_tree'), |
||
882 | $this->dbHandler->quoteColumn('node_id', 'ezcontentobject_tree') |
||
883 | ) |
||
884 | ) |
||
885 | )->where( |
||
886 | $query->expr->eq( |
||
887 | $this->dbHandler->quoteColumn($column, 'ezcontentobject'), |
||
888 | $query->bindValue($id, null, $column === 'id' ? PDO::PARAM_INT : PDO::PARAM_STR) |
||
889 | ) |
||
890 | ); |
||
891 | $statement = $query->prepare(); |
||
892 | $statement->execute(); |
||
893 | $row = $statement->fetch(PDO::FETCH_ASSOC); |
||
894 | |||
895 | if (empty($row)) { |
||
896 | throw new NotFound('content', "$column: $id"); |
||
897 | } |
||
898 | |||
899 | return $row; |
||
900 | } |
||
901 | |||
902 | /** |
||
903 | * Loads info for content identified by $contentId. |
||
904 | * Will basically return a hash containing all field values for ezcontentobject table plus some additional keys: |
||
905 | * - always_available => Boolean indicating if content's language mask contains alwaysAvailable bit field |
||
906 | * - main_language_code => Language code for main (initial) language. E.g. "eng-GB". |
||
907 | * |
||
908 | * @param int $contentId |
||
909 | * |
||
910 | * @throws \eZ\Publish\Core\Base\Exceptions\NotFoundException |
||
911 | * |
||
912 | * @return array |
||
913 | */ |
||
914 | public function loadContentInfo($contentId) |
||
918 | |||
919 | /** |
||
920 | * Loads info for a content object identified by its remote ID. |
||
921 | * |
||
922 | * Returns an array with the relevant data. |
||
923 | * |
||
924 | * @param mixed $remoteId |
||
925 | * |
||
926 | * @throws \eZ\Publish\Core\Base\Exceptions\NotFoundException |
||
927 | * |
||
928 | * @return array |
||
929 | */ |
||
930 | public function loadContentInfoByRemoteId($remoteId) |
||
931 | { |
||
932 | return $this->internalLoadContentInfo('remote_id', $remoteId); |
||
933 | } |
||
934 | |||
935 | /** |
||
936 | * Loads version info for content identified by $contentId and $versionNo. |
||
937 | * Will basically return a hash containing all field values from ezcontentobject_version table plus following keys: |
||
938 | * - names => Hash of content object names. Key is the language code, value is the name. |
||
939 | * - languages => Hash of language ids. Key is the language code (e.g. "eng-GB"), value is the language numeric id without the always available bit. |
||
940 | * - initial_language_code => Language code for initial language in this version. |
||
941 | * |
||
942 | * @param int $contentId |
||
943 | * @param int $versionNo |
||
944 | * |
||
945 | * @return array |
||
946 | */ |
||
947 | View Code Duplication | public function loadVersionInfo($contentId, $versionNo) |
|
967 | |||
968 | /** |
||
969 | * Returns data for all versions with given status created by the given $userId. |
||
970 | * |
||
971 | * @param int $userId |
||
972 | * @param int $status |
||
973 | * |
||
974 | * @return string[][] |
||
975 | */ |
||
976 | public function listVersionsForUser($userId, $status = VersionInfo::STATUS_DRAFT) |
||
994 | |||
995 | /** |
||
996 | * Returns all version data for the given $contentId, optionally filtered by status. |
||
997 | * |
||
998 | * Result is returned with oldest version first (using version id as it has index and is auto increment). |
||
999 | * |
||
1000 | * @param mixed $contentId |
||
1001 | * @param mixed|null $status Optional argument to filter versions by status, like {@see VersionInfo::STATUS_ARCHIVED}. |
||
1002 | * @param int $limit Limit for items returned, -1 means none. |
||
1003 | * |
||
1004 | * @return string[][] |
||
1005 | */ |
||
1006 | public function listVersions($contentId, $status = null, $limit = -1) |
||
1033 | |||
1034 | /** |
||
1035 | * Helper for {@see listVersions()} and {@see listVersionsForUser()} that filters duplicates |
||
1036 | * that are the result of the cartesian product performed by createVersionInfoFindQuery(). |
||
1037 | * |
||
1038 | * @param \eZ\Publish\Core\Persistence\Database\SelectQuery $query |
||
1039 | * |
||
1040 | * @return string[][] |
||
1041 | */ |
||
1042 | private function listVersionsHelper(SelectQuery $query) |
||
1064 | |||
1065 | /** |
||
1066 | * Returns all version numbers for the given $contentId. |
||
1067 | * |
||
1068 | * @param mixed $contentId |
||
1069 | * |
||
1070 | * @return int[] |
||
1071 | */ |
||
1072 | public function listVersionNumbers($contentId) |
||
1091 | |||
1092 | /** |
||
1093 | * Returns last version number for content identified by $contentId. |
||
1094 | * |
||
1095 | * @param int $contentId |
||
1096 | * |
||
1097 | * @return int |
||
1098 | */ |
||
1099 | public function getLastVersionNumber($contentId) |
||
1118 | |||
1119 | /** |
||
1120 | * Returns all IDs for locations that refer to $contentId. |
||
1121 | * |
||
1122 | * @param int $contentId |
||
1123 | * |
||
1124 | * @return int[] |
||
1125 | */ |
||
1126 | public function getAllLocationIds($contentId) |
||
1145 | |||
1146 | /** |
||
1147 | * Returns all field IDs of $contentId grouped by their type. |
||
1148 | * If $versionNo is set only field IDs for that version are returned. |
||
1149 | * If $languageCode is set, only field IDs for that language are returned. |
||
1150 | * |
||
1151 | * @param int $contentId |
||
1152 | * @param int|null $versionNo |
||
1153 | * @param string|null $languageCode |
||
1154 | * |
||
1155 | * @return int[][] |
||
1156 | */ |
||
1157 | public function getFieldIdsByType($contentId, $versionNo = null, $languageCode = null) |
||
1203 | |||
1204 | /** |
||
1205 | * Deletes relations to and from $contentId. |
||
1206 | * If $versionNo is set only relations for that version are deleted. |
||
1207 | * |
||
1208 | * @param int $contentId |
||
1209 | * @param int|null $versionNo |
||
1210 | */ |
||
1211 | public function deleteRelations($contentId, $versionNo = null) |
||
1248 | |||
1249 | /** |
||
1250 | * Removes relations to Content with $contentId from Relation and RelationList field type fields. |
||
1251 | * |
||
1252 | * @param int $contentId |
||
1253 | */ |
||
1254 | public function removeReverseFieldRelations($contentId) |
||
1304 | |||
1305 | /** |
||
1306 | * Updates field value of RelationList field type identified by given $row data, |
||
1307 | * removing relations toward given $contentId. |
||
1308 | * |
||
1309 | * @param int $contentId |
||
1310 | * @param array $row |
||
1311 | */ |
||
1312 | protected function removeRelationFromRelationListField($contentId, array $row) |
||
1347 | |||
1348 | /** |
||
1349 | * Updates field value of Relation field type identified by given $row data, |
||
1350 | * removing relation data. |
||
1351 | * |
||
1352 | * @param array $row |
||
1353 | */ |
||
1354 | protected function removeRelationFromRelationField(array $row) |
||
1376 | |||
1377 | /** |
||
1378 | * Deletes the field with the given $fieldId. |
||
1379 | * |
||
1380 | * @param int $fieldId |
||
1381 | */ |
||
1382 | public function deleteField($fieldId) |
||
1396 | |||
1397 | /** |
||
1398 | * Deletes all fields of $contentId in all versions. |
||
1399 | * If $versionNo is set only fields for that version are deleted. |
||
1400 | * |
||
1401 | * @param int $contentId |
||
1402 | * @param int|null $versionNo |
||
1403 | */ |
||
1404 | public function deleteFields($contentId, $versionNo = null) |
||
1426 | |||
1427 | /** |
||
1428 | * Deletes all versions of $contentId. |
||
1429 | * If $versionNo is set only that version is deleted. |
||
1430 | * |
||
1431 | * @param int $contentId |
||
1432 | * @param int|null $versionNo |
||
1433 | */ |
||
1434 | public function deleteVersions($contentId, $versionNo = null) |
||
1456 | |||
1457 | /** |
||
1458 | * Deletes all names of $contentId. |
||
1459 | * If $versionNo is set only names for that version are deleted. |
||
1460 | * |
||
1461 | * @param int $contentId |
||
1462 | * @param int|null $versionNo |
||
1463 | */ |
||
1464 | public function deleteNames($contentId, $versionNo = null) |
||
1486 | |||
1487 | /** |
||
1488 | * Sets the name for Content $contentId in version $version to $name in $language. |
||
1489 | * |
||
1490 | * @param int $contentId |
||
1491 | * @param int $version |
||
1492 | * @param string $name |
||
1493 | * @param string $language |
||
1494 | */ |
||
1495 | public function setName($contentId, $version, $name, $language) |
||
1556 | |||
1557 | /** |
||
1558 | * Returns a language sub select query for setName. |
||
1559 | * |
||
1560 | * Return sub select query which gets proper language mask for alwaysAvailable Content. |
||
1561 | * |
||
1562 | * @return \eZ\Publish\Core\Persistence\Database\SelectQuery |
||
1563 | */ |
||
1564 | private function getLanguageQuery() |
||
1603 | |||
1604 | /** |
||
1605 | * Deletes the actual content object referred to by $contentId. |
||
1606 | * |
||
1607 | * @param int $contentId |
||
1608 | */ |
||
1609 | public function deleteContent($contentId) |
||
1622 | |||
1623 | /** |
||
1624 | * Loads relations from $contentId to published content, optionally only from $contentVersionNo. |
||
1625 | * |
||
1626 | * $relationType can also be filtered. |
||
1627 | * |
||
1628 | * @param int $contentId |
||
1629 | * @param int $contentVersionNo |
||
1630 | * @param int $relationType |
||
1631 | * |
||
1632 | * @return string[][] array of relation data |
||
1633 | */ |
||
1634 | public function loadRelations($contentId, $contentVersionNo = null, $relationType = null) |
||
1702 | |||
1703 | /** |
||
1704 | * Loads data that related to $toContentId. |
||
1705 | * |
||
1706 | * @param int $toContentId |
||
1707 | * @param int $relationType |
||
1708 | * |
||
1709 | * @return mixed[][] Content data, array structured like {@see \eZ\Publish\Core\Persistence\Legacy\Content\Gateway::load()} |
||
1710 | */ |
||
1711 | public function loadReverseRelations($toContentId, $relationType = null) |
||
1760 | |||
1761 | /** |
||
1762 | * Inserts a new relation database record. |
||
1763 | * |
||
1764 | * @param \eZ\Publish\SPI\Persistence\Content\Relation\CreateStruct $createStruct |
||
1765 | * |
||
1766 | * @return int ID the inserted ID |
||
1767 | */ |
||
1768 | View Code Duplication | public function insertRelation(RelationCreateStruct $createStruct) |
|
1799 | |||
1800 | /** |
||
1801 | * Deletes the relation with the given $relationId. |
||
1802 | * |
||
1803 | * @param int $relationId |
||
1804 | * @param int $type {@see \eZ\Publish\API\Repository\Values\Content\Relation::COMMON, |
||
1805 | * \eZ\Publish\API\Repository\Values\Content\Relation::EMBED, |
||
1806 | * \eZ\Publish\API\Repository\Values\Content\Relation::LINK, |
||
1807 | * \eZ\Publish\API\Repository\Values\Content\Relation::FIELD} |
||
1808 | */ |
||
1809 | public function deleteRelation($relationId, $type) |
||
1871 | |||
1872 | /** |
||
1873 | * Returns all Content IDs for a given $contentTypeId. |
||
1874 | * |
||
1875 | * @param int $contentTypeId |
||
1876 | * |
||
1877 | * @return int[] |
||
1878 | */ |
||
1879 | public function getContentIdsByContentTypeId($contentTypeId) |
||
1897 | |||
1898 | /** |
||
1899 | * Load name data for set of content id's and corresponding version number. |
||
1900 | * |
||
1901 | * @param array[] $rows array of hashes with 'id' and 'version' to load names for |
||
1902 | * |
||
1903 | * @return array |
||
1904 | */ |
||
1905 | public function loadVersionedNameData($rows) |
||
1928 | |||
1929 | /** |
||
1930 | * Batch method for copying all relation meta data for copied Content object. |
||
1931 | * |
||
1932 | * {@inheritdoc} |
||
1933 | * |
||
1934 | * @param int $originalContentId |
||
1935 | * @param int $copiedContentId |
||
1936 | * @param int|null $versionNo If specified only copy for a given version number, otherwise all. |
||
1937 | */ |
||
1938 | public function copyRelations($originalContentId, $copiedContentId, $versionNo = null) |
||
1958 | |||
1959 | /** |
||
1960 | * Remove the specified translation from the Content Object Version. |
||
1961 | * |
||
1962 | * @param int $contentId |
||
1963 | * @param string $languageCode language code of the translation |
||
1964 | * @throws \Doctrine\DBAL\DBALException |
||
1965 | */ |
||
1966 | public function removeTranslationFromContent($contentId, $languageCode) |
||
1985 | |||
1986 | /** |
||
1987 | * Delete Content fields (attributes) for the given Translation. |
||
1988 | * If $versionNo is given, fields for that Version only will be deleted. |
||
1989 | * |
||
1990 | * @param string $languageCode |
||
1991 | * @param int $contentId |
||
1992 | * @param int $versionNo (optional) filter by versionNo |
||
1993 | */ |
||
1994 | View Code Duplication | public function deleteTranslatedFields($languageCode, $contentId, $versionNo = null) |
|
1995 | { |
||
1996 | $query = $this->connection->createQueryBuilder(); |
||
1997 | $query |
||
1998 | ->delete('ezcontentobject_attribute') |
||
1999 | ->where('contentobject_id = :contentId') |
||
2000 | ->andWhere('language_code = :languageCode') |
||
2001 | ->setParameters( |
||
2002 | [ |
||
2003 | ':contentId' => $contentId, |
||
2004 | ':languageCode' => $languageCode, |
||
2005 | ] |
||
2006 | ) |
||
2007 | ; |
||
2008 | |||
2009 | if (null !== $versionNo) { |
||
2010 | $query |
||
2011 | ->andWhere('version = :versionNo') |
||
2012 | ->setParameter(':versionNo', $versionNo) |
||
2013 | ; |
||
2014 | } |
||
2015 | |||
2016 | $query->execute(); |
||
2017 | } |
||
2018 | |||
2019 | /** |
||
2020 | * Delete the specified Translation from the given Version. |
||
2021 | * |
||
2022 | * @param int $contentId |
||
2023 | * @param int $versionNo |
||
2024 | * @param string $languageCode |
||
2025 | * @throws \Doctrine\DBAL\DBALException |
||
2026 | */ |
||
2027 | public function deleteTranslationFromVersion($contentId, $versionNo, $languageCode) |
||
2028 | { |
||
2029 | $language = $this->languageHandler->loadByLanguageCode($languageCode); |
||
2030 | |||
2031 | $this->connection->beginTransaction(); |
||
2032 | try { |
||
2033 | $this->deleteTranslationFromContentVersions($contentId, $language->id, $versionNo); |
||
2034 | $this->deleteTranslationFromContentNames($contentId, $languageCode, $versionNo); |
||
2035 | |||
2036 | $this->connection->commit(); |
||
2037 | } catch (DBALException $e) { |
||
2038 | $this->connection->rollBack(); |
||
2039 | throw $e; |
||
2040 | } |
||
2041 | } |
||
2042 | |||
2043 | /** |
||
2044 | * Delete translation from the ezcontentobject_name table. |
||
2045 | * |
||
2046 | * @param int $contentId |
||
2047 | * @param string $languageCode |
||
2048 | * @param int $versionNo optional, if specified, apply to this Version only. |
||
2049 | */ |
||
2050 | View Code Duplication | private function deleteTranslationFromContentNames($contentId, $languageCode, $versionNo = null) |
|
2074 | |||
2075 | /** |
||
2076 | * Remove language from language_mask of ezcontentobject. |
||
2077 | * |
||
2078 | * @param int $contentId |
||
2079 | * @param int $languageId |
||
2080 | * @throws \eZ\Publish\Core\Base\Exceptions\BadStateException |
||
2081 | */ |
||
2082 | private function deleteTranslationFromContentObject($contentId, $languageId) |
||
2111 | |||
2112 | /** |
||
2113 | * Remove language from language_mask of ezcontentobject_version and update initialLanguageId |
||
2114 | * if it matches the removed one. |
||
2115 | * |
||
2116 | * @param int $contentId |
||
2117 | * @param int $languageId |
||
2118 | * @param int $versionNo optional, if specified, apply to this Version only. |
||
2119 | * @throws \eZ\Publish\Core\Base\Exceptions\BadStateException |
||
2120 | */ |
||
2121 | private function deleteTranslationFromContentVersions($contentId, $languageId, $versionNo = null) |
||
2165 | } |
||
2166 |
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.
Either this assignment is in error or an instanceof check should be added for that assignment.