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 |
||
43 | class DoctrineDatabase extends Gateway |
||
44 | { |
||
45 | /** |
||
46 | * eZ Doctrine database handler. |
||
47 | * |
||
48 | * @var \eZ\Publish\Core\Persistence\Database\DatabaseHandler |
||
49 | * @deprecated Start to use DBAL $connection instead. |
||
50 | */ |
||
51 | protected $dbHandler; |
||
52 | |||
53 | /** |
||
54 | * The native Doctrine connection. |
||
55 | * |
||
56 | * Meant to be used to transition from eZ/Zeta interface to Doctrine. |
||
57 | * |
||
58 | * @var \Doctrine\DBAL\Connection |
||
59 | */ |
||
60 | protected $connection; |
||
61 | |||
62 | /** |
||
63 | * Query builder. |
||
64 | * |
||
65 | * @var \eZ\Publish\Core\Persistence\Legacy\Content\Gateway\DoctrineDatabase\QueryBuilder |
||
66 | */ |
||
67 | protected $queryBuilder; |
||
68 | |||
69 | /** |
||
70 | * Caching language handler. |
||
71 | * |
||
72 | * @var \eZ\Publish\Core\Persistence\Legacy\Content\Language\CachingHandler |
||
73 | */ |
||
74 | protected $languageHandler; |
||
75 | |||
76 | /** |
||
77 | * Language mask generator. |
||
78 | * |
||
79 | * @var \eZ\Publish\Core\Persistence\Legacy\Content\Language\MaskGenerator |
||
80 | */ |
||
81 | protected $languageMaskGenerator; |
||
82 | |||
83 | /** |
||
84 | * Creates a new gateway based on $db. |
||
85 | * |
||
86 | * @param \eZ\Publish\Core\Persistence\Database\DatabaseHandler $db |
||
87 | * @param \Doctrine\DBAL\Connection $connection |
||
88 | * @param \eZ\Publish\Core\Persistence\Legacy\Content\Gateway\DoctrineDatabase\QueryBuilder $queryBuilder |
||
89 | * @param \eZ\Publish\SPI\Persistence\Content\Language\Handler $languageHandler |
||
90 | * @param \eZ\Publish\Core\Persistence\Legacy\Content\Language\MaskGenerator $languageMaskGenerator |
||
91 | */ |
||
92 | public function __construct( |
||
93 | DatabaseHandler $db, |
||
94 | Connection $connection, |
||
95 | QueryBuilder $queryBuilder, |
||
96 | LanguageHandler $languageHandler, |
||
97 | LanguageMaskGenerator $languageMaskGenerator |
||
98 | ) { |
||
99 | $this->dbHandler = $db; |
||
100 | $this->connection = $connection; |
||
101 | $this->queryBuilder = $queryBuilder; |
||
102 | $this->languageHandler = $languageHandler; |
||
|
|||
103 | $this->languageMaskGenerator = $languageMaskGenerator; |
||
104 | } |
||
105 | |||
106 | /** |
||
107 | * Get context definition for external storage layers. |
||
108 | * |
||
109 | * @return array |
||
110 | */ |
||
111 | public function getContext() |
||
112 | { |
||
113 | return [ |
||
114 | 'identifier' => 'LegacyStorage', |
||
115 | 'connection' => $this->dbHandler, |
||
116 | ]; |
||
117 | } |
||
118 | |||
119 | /** |
||
120 | * Inserts a new content object. |
||
121 | * |
||
122 | * @param \eZ\Publish\SPI\Persistence\Content\CreateStruct $struct |
||
123 | * @param mixed $currentVersionNo |
||
124 | * |
||
125 | * @return int ID |
||
126 | */ |
||
127 | public function insertContentObject(CreateStruct $struct, $currentVersionNo = 1) |
||
128 | { |
||
129 | $initialLanguageId = !empty($struct->mainLanguageId) ? $struct->mainLanguageId : $struct->initialLanguageId; |
||
130 | $initialLanguageCode = $this->languageHandler->load($initialLanguageId)->languageCode; |
||
131 | |||
132 | if (isset($struct->name[$initialLanguageCode])) { |
||
133 | $name = $struct->name[$initialLanguageCode]; |
||
134 | } else { |
||
135 | $name = ''; |
||
136 | } |
||
137 | |||
138 | $q = $this->dbHandler->createInsertQuery(); |
||
139 | $q->insertInto( |
||
140 | $this->dbHandler->quoteTable('ezcontentobject') |
||
141 | )->set( |
||
142 | $this->dbHandler->quoteColumn('id'), |
||
143 | $this->dbHandler->getAutoIncrementValue('ezcontentobject', 'id') |
||
144 | )->set( |
||
145 | $this->dbHandler->quoteColumn('current_version'), |
||
146 | $q->bindValue($currentVersionNo, null, \PDO::PARAM_INT) |
||
147 | )->set( |
||
148 | $this->dbHandler->quoteColumn('name'), |
||
149 | $q->bindValue($name, null, \PDO::PARAM_STR) |
||
150 | )->set( |
||
151 | $this->dbHandler->quoteColumn('contentclass_id'), |
||
152 | $q->bindValue($struct->typeId, null, \PDO::PARAM_INT) |
||
153 | )->set( |
||
154 | $this->dbHandler->quoteColumn('section_id'), |
||
155 | $q->bindValue($struct->sectionId, null, \PDO::PARAM_INT) |
||
156 | )->set( |
||
157 | $this->dbHandler->quoteColumn('owner_id'), |
||
158 | $q->bindValue($struct->ownerId, null, \PDO::PARAM_INT) |
||
159 | )->set( |
||
160 | $this->dbHandler->quoteColumn('initial_language_id'), |
||
161 | $q->bindValue($initialLanguageId, null, \PDO::PARAM_INT) |
||
162 | )->set( |
||
163 | $this->dbHandler->quoteColumn('remote_id'), |
||
164 | $q->bindValue($struct->remoteId, null, \PDO::PARAM_STR) |
||
165 | )->set( |
||
166 | $this->dbHandler->quoteColumn('modified'), |
||
167 | $q->bindValue(0, null, \PDO::PARAM_INT) |
||
168 | )->set( |
||
169 | $this->dbHandler->quoteColumn('published'), |
||
170 | $q->bindValue(0, null, \PDO::PARAM_INT) |
||
171 | )->set( |
||
172 | $this->dbHandler->quoteColumn('status'), |
||
173 | $q->bindValue(ContentInfo::STATUS_DRAFT, null, \PDO::PARAM_INT) |
||
174 | )->set( |
||
175 | $this->dbHandler->quoteColumn('language_mask'), |
||
176 | $q->bindValue( |
||
177 | $this->generateLanguageMask( |
||
178 | $struct->fields, |
||
179 | $initialLanguageCode, |
||
180 | $struct->alwaysAvailable |
||
181 | ), |
||
182 | null, |
||
183 | \PDO::PARAM_INT |
||
184 | ) |
||
185 | ); |
||
186 | |||
187 | $q->prepare()->execute(); |
||
188 | |||
189 | return $this->dbHandler->lastInsertId( |
||
190 | $this->dbHandler->getSequenceName('ezcontentobject', 'id') |
||
191 | ); |
||
192 | } |
||
193 | |||
194 | /** |
||
195 | * Generates a language mask for $fields. |
||
196 | * |
||
197 | * @param \eZ\Publish\SPI\Persistence\Content\Field[] $fields |
||
198 | * @param string $initialLanguageCode |
||
199 | * @param bool $isAlwaysAvailable |
||
200 | * |
||
201 | * @return int |
||
202 | */ |
||
203 | protected function generateLanguageMask(array $fields, string $initialLanguageCode, bool $isAlwaysAvailable): int |
||
204 | { |
||
205 | $languages = [$initialLanguageCode => true]; |
||
206 | foreach ($fields as $field) { |
||
207 | if (isset($languages[$field->languageCode])) { |
||
208 | continue; |
||
209 | } |
||
210 | |||
211 | $languages[$field->languageCode] = true; |
||
212 | } |
||
213 | |||
214 | return $this->languageMaskGenerator->generateLanguageMaskFromLanguageCodes(array_keys($languages), $isAlwaysAvailable); |
||
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) |
||
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 | $mask = $this->languageMaskGenerator->generateLanguageMaskFromLanguageCodes( |
||
333 | $prePublishVersionInfo->languageCodes, |
||
334 | $struct->alwaysAvailable ?? $prePublishVersionInfo->contentInfo->alwaysAvailable |
||
335 | ); |
||
336 | |||
337 | $q->set( |
||
338 | $this->dbHandler->quoteColumn('language_mask'), |
||
339 | $q->bindValue($mask, null, \PDO::PARAM_INT) |
||
340 | ); |
||
341 | } |
||
342 | if (isset($struct->isHidden)) { |
||
343 | $q->set( |
||
344 | $this->dbHandler->quoteColumn('is_hidden'), |
||
345 | $q->bindValue($struct->isHidden, null, \PDO::PARAM_BOOL) |
||
346 | ); |
||
347 | } |
||
348 | $q->where( |
||
349 | $q->expr->eq( |
||
350 | $this->dbHandler->quoteColumn('id'), |
||
351 | $q->bindValue($contentId, null, \PDO::PARAM_INT) |
||
352 | ) |
||
353 | ); |
||
354 | $q->prepare()->execute(); |
||
355 | |||
356 | // Handle alwaysAvailable flag update separately as it's a more complex task and has impact on several tables |
||
357 | if (isset($struct->alwaysAvailable) || isset($struct->mainLanguageId)) { |
||
358 | $this->updateAlwaysAvailableFlag($contentId, $struct->alwaysAvailable); |
||
359 | } |
||
360 | } |
||
361 | |||
362 | /** |
||
363 | * Updates version $versionNo for content identified by $contentId, in respect to $struct. |
||
364 | * |
||
365 | * @param int $contentId |
||
366 | * @param int $versionNo |
||
367 | * @param \eZ\Publish\SPI\Persistence\Content\UpdateStruct $struct |
||
368 | */ |
||
369 | public function updateVersion($contentId, $versionNo, UpdateStruct $struct) |
||
411 | |||
412 | /** |
||
413 | * Updates "always available" flag for Content identified by $contentId, in respect to |
||
414 | * Content's current main language and optionally new $alwaysAvailable state. |
||
415 | * |
||
416 | * @param int $contentId |
||
417 | * @param bool|null $alwaysAvailable New "always available" value or null if not defined |
||
418 | */ |
||
419 | public function updateAlwaysAvailableFlag($contentId, $alwaysAvailable = null) |
||
537 | |||
538 | /** |
||
539 | * Sets the status of the version identified by $contentId and $version to $status. |
||
540 | * |
||
541 | * The $status can be one of STATUS_DRAFT, STATUS_PUBLISHED, STATUS_ARCHIVED |
||
542 | * |
||
543 | * @param int $contentId |
||
544 | * @param int $version |
||
545 | * @param int $status |
||
546 | * |
||
547 | * @return bool |
||
548 | */ |
||
549 | public function setStatus($contentId, $version, $status) |
||
604 | |||
605 | /** |
||
606 | * Inserts a new field. |
||
607 | * |
||
608 | * Only used when a new field is created (i.e. a new object or a field in a |
||
609 | * new language!). After that, field IDs need to stay the same, only the |
||
610 | * version number changes. |
||
611 | * |
||
612 | * @param \eZ\Publish\SPI\Persistence\Content $content |
||
613 | * @param \eZ\Publish\SPI\Persistence\Content\Field $field |
||
614 | * @param \eZ\Publish\Core\Persistence\Legacy\Content\StorageFieldValue $value |
||
615 | * |
||
616 | * @return int ID |
||
617 | */ |
||
618 | public function insertNewField(Content $content, Field $field, StorageFieldValue $value) |
||
636 | |||
637 | /** |
||
638 | * Inserts an existing field. |
||
639 | * |
||
640 | * Used to insert a field with an exsting ID but a new version number. |
||
641 | * |
||
642 | * @param Content $content |
||
643 | * @param Field $field |
||
644 | * @param StorageFieldValue $value |
||
645 | */ |
||
646 | public function insertExistingField(Content $content, Field $field, StorageFieldValue $value) |
||
659 | |||
660 | /** |
||
661 | * Sets field (ezcontentobject_attribute) values to the given query. |
||
662 | * |
||
663 | * @param \eZ\Publish\Core\Persistence\Database\InsertQuery $q |
||
664 | * @param Content $content |
||
665 | * @param Field $field |
||
666 | * @param StorageFieldValue $value |
||
667 | */ |
||
668 | protected function setInsertFieldValues(InsertQuery $q, Content $content, Field $field, StorageFieldValue $value) |
||
714 | |||
715 | /** |
||
716 | * Checks if $languageCode is always available in $content. |
||
717 | * |
||
718 | * @param \eZ\Publish\SPI\Persistence\Content $content |
||
719 | * @param string $languageCode |
||
720 | * |
||
721 | * @return bool |
||
722 | */ |
||
723 | protected function isLanguageAlwaysAvailable(Content $content, $languageCode) |
||
730 | |||
731 | /** |
||
732 | * Updates an existing field. |
||
733 | * |
||
734 | * @param Field $field |
||
735 | * @param StorageFieldValue $value |
||
736 | */ |
||
737 | public function updateField(Field $field, StorageFieldValue $value) |
||
757 | |||
758 | /** |
||
759 | * Sets update fields for $value on $q. |
||
760 | * |
||
761 | * @param \eZ\Publish\Core\Persistence\Database\UpdateQuery $q |
||
762 | * @param StorageFieldValue $value |
||
763 | */ |
||
764 | protected function setFieldUpdateValues(UpdateQuery $q, StorageFieldValue $value) |
||
785 | |||
786 | /** |
||
787 | * Updates an existing, non-translatable field. |
||
788 | * |
||
789 | * @param \eZ\Publish\SPI\Persistence\Content\Field $field |
||
790 | * @param \eZ\Publish\Core\Persistence\Legacy\Content\StorageFieldValue $value |
||
791 | * @param int $contentId |
||
792 | */ |
||
793 | public function updateNonTranslatableField( |
||
820 | |||
821 | /** |
||
822 | * {@inheritdoc} |
||
823 | */ |
||
824 | public function load($contentId, $version = null, array $translations = null) |
||
825 | { |
||
826 | return $this->internalLoadContent([$contentId], $version, $translations); |
||
827 | } |
||
828 | |||
829 | /** |
||
830 | * {@inheritdoc} |
||
831 | */ |
||
832 | public function loadContentList(array $contentIds, array $translations = null): array |
||
833 | { |
||
834 | return $this->internalLoadContent($contentIds, null, $translations); |
||
835 | } |
||
836 | |||
837 | /** |
||
838 | * @see load(), loadContentList() |
||
839 | * |
||
840 | * @param array $contentIds |
||
841 | * @param int|null $version |
||
842 | * @param string[]|null $translations |
||
843 | * |
||
844 | * @return array |
||
845 | */ |
||
846 | private function internalLoadContent(array $contentIds, int $version = null, array $translations = null): array |
||
847 | { |
||
848 | $queryBuilder = $this->connection->createQueryBuilder(); |
||
849 | $expr = $queryBuilder->expr(); |
||
850 | $queryBuilder |
||
851 | ->select( |
||
852 | 'c.id AS ezcontentobject_id', |
||
853 | 'c.contentclass_id AS ezcontentobject_contentclass_id', |
||
854 | 'c.section_id AS ezcontentobject_section_id', |
||
855 | 'c.owner_id AS ezcontentobject_owner_id', |
||
856 | 'c.remote_id AS ezcontentobject_remote_id', |
||
857 | 'c.current_version AS ezcontentobject_current_version', |
||
858 | 'c.initial_language_id AS ezcontentobject_initial_language_id', |
||
859 | 'c.modified AS ezcontentobject_modified', |
||
860 | 'c.published AS ezcontentobject_published', |
||
861 | 'c.status AS ezcontentobject_status', |
||
862 | 'c.name AS ezcontentobject_name', |
||
863 | 'c.language_mask AS ezcontentobject_language_mask', |
||
864 | 'c.is_hidden AS ezcontentobject_is_hidden', |
||
865 | 'v.id AS ezcontentobject_version_id', |
||
866 | 'v.version AS ezcontentobject_version_version', |
||
867 | 'v.modified AS ezcontentobject_version_modified', |
||
868 | 'v.creator_id AS ezcontentobject_version_creator_id', |
||
869 | 'v.created AS ezcontentobject_version_created', |
||
870 | 'v.status AS ezcontentobject_version_status', |
||
871 | 'v.language_mask AS ezcontentobject_version_language_mask', |
||
872 | 'v.initial_language_id AS ezcontentobject_version_initial_language_id', |
||
873 | 'a.id AS ezcontentobject_attribute_id', |
||
874 | 'a.contentclassattribute_id AS ezcontentobject_attribute_contentclassattribute_id', |
||
875 | 'a.data_type_string AS ezcontentobject_attribute_data_type_string', |
||
876 | 'a.language_code AS ezcontentobject_attribute_language_code', |
||
877 | 'a.language_id AS ezcontentobject_attribute_language_id', |
||
878 | 'a.data_float AS ezcontentobject_attribute_data_float', |
||
879 | 'a.data_int AS ezcontentobject_attribute_data_int', |
||
880 | 'a.data_text AS ezcontentobject_attribute_data_text', |
||
881 | 'a.sort_key_int AS ezcontentobject_attribute_sort_key_int', |
||
882 | 'a.sort_key_string AS ezcontentobject_attribute_sort_key_string', |
||
883 | 't.main_node_id AS ezcontentobject_tree_main_node_id' |
||
884 | ) |
||
885 | ->from('ezcontentobject', 'c') |
||
886 | ->innerJoin( |
||
887 | 'c', |
||
888 | 'ezcontentobject_version', |
||
889 | 'v', |
||
890 | $expr->andX( |
||
891 | $expr->eq('c.id', 'v.contentobject_id'), |
||
892 | $expr->eq('v.version', $version ?? 'c.current_version') |
||
893 | ) |
||
894 | ) |
||
895 | ->innerJoin( |
||
896 | 'v', |
||
897 | 'ezcontentobject_attribute', |
||
898 | 'a', |
||
899 | $expr->andX( |
||
900 | $expr->eq('v.contentobject_id', 'a.contentobject_id'), |
||
901 | $expr->eq('v.version', 'a.version') |
||
902 | ) |
||
903 | ) |
||
904 | ->leftJoin( |
||
905 | 'c', |
||
906 | 'ezcontentobject_tree', |
||
907 | 't', |
||
908 | $expr->andX( |
||
909 | $expr->eq('c.id', 't.contentobject_id'), |
||
910 | $expr->eq('t.node_id', 't.main_node_id') |
||
911 | ) |
||
912 | ); |
||
913 | |||
914 | $queryBuilder->where( |
||
915 | $expr->in( |
||
916 | 'c.id', |
||
917 | $queryBuilder->createNamedParameter($contentIds, Connection::PARAM_INT_ARRAY) |
||
918 | ) |
||
919 | ); |
||
920 | |||
921 | if (!empty($translations)) { |
||
922 | $queryBuilder->andWhere( |
||
923 | $expr->in( |
||
924 | 'a.language_code', |
||
925 | $queryBuilder->createNamedParameter($translations, Connection::PARAM_STR_ARRAY) |
||
926 | ) |
||
927 | ); |
||
928 | } |
||
929 | |||
930 | return $queryBuilder->execute()->fetchAll(FetchMode::ASSOCIATIVE); |
||
931 | } |
||
932 | |||
933 | /** |
||
934 | * Get query builder to load Content Info data. |
||
935 | * |
||
936 | * @see loadContentInfo(), loadContentInfoByRemoteId(), loadContentInfoList(), loadContentInfoByLocationId() |
||
937 | * |
||
938 | * @param bool $joinMainLocation |
||
939 | * |
||
940 | * @return \Doctrine\DBAL\Query\QueryBuilder |
||
941 | */ |
||
942 | private function createLoadContentInfoQueryBuilder(bool $joinMainLocation = true): DoctrineQueryBuilder |
||
943 | { |
||
944 | $queryBuilder = $this->connection->createQueryBuilder(); |
||
945 | $expr = $queryBuilder->expr(); |
||
946 | |||
947 | $joinCondition = $expr->eq('c.id', 't.contentobject_id'); |
||
948 | if ($joinMainLocation) { |
||
949 | // wrap join condition with AND operator and join by a Main Location |
||
950 | $joinCondition = $expr->andX( |
||
951 | $joinCondition, |
||
952 | $expr->eq('t.node_id', 't.main_node_id') |
||
953 | ); |
||
954 | } |
||
955 | |||
956 | $queryBuilder |
||
957 | ->select('c.*', 't.main_node_id AS ezcontentobject_tree_main_node_id') |
||
958 | ->from('ezcontentobject', 'c') |
||
959 | ->leftJoin( |
||
960 | 'c', |
||
961 | 'ezcontentobject_tree', |
||
962 | 't', |
||
963 | $joinCondition |
||
964 | ); |
||
965 | |||
966 | return $queryBuilder; |
||
967 | } |
||
968 | |||
969 | /** |
||
970 | * Loads info for content identified by $contentId. |
||
971 | * Will basically return a hash containing all field values for ezcontentobject table plus some additional keys: |
||
972 | * - always_available => Boolean indicating if content's language mask contains alwaysAvailable bit field |
||
973 | * - main_language_code => Language code for main (initial) language. E.g. "eng-GB". |
||
974 | * |
||
975 | * @param int $contentId |
||
976 | * |
||
977 | * @throws \eZ\Publish\Core\Base\Exceptions\NotFoundException |
||
978 | * |
||
979 | * @return array |
||
980 | */ |
||
981 | public function loadContentInfo($contentId) |
||
982 | { |
||
983 | $queryBuilder = $this->createLoadContentInfoQueryBuilder(); |
||
984 | $queryBuilder |
||
985 | ->where('c.id = :id') |
||
986 | ->setParameter('id', $contentId, ParameterType::INTEGER); |
||
987 | |||
988 | $results = $queryBuilder->execute()->fetchAll(FetchMode::ASSOCIATIVE); |
||
989 | if (empty($results)) { |
||
990 | throw new NotFound('content', "id: $contentId"); |
||
991 | } |
||
992 | |||
993 | return $results[0]; |
||
994 | } |
||
995 | |||
996 | public function loadContentInfoList(array $contentIds) |
||
997 | { |
||
998 | $queryBuilder = $this->createLoadContentInfoQueryBuilder(); |
||
999 | $queryBuilder |
||
1000 | ->where('c.id IN (:ids)') |
||
1001 | ->setParameter('ids', $contentIds, Connection::PARAM_INT_ARRAY); |
||
1002 | |||
1003 | return $queryBuilder->execute()->fetchAll(FetchMode::ASSOCIATIVE); |
||
1004 | } |
||
1005 | |||
1006 | /** |
||
1007 | * Loads info for a content object identified by its remote ID. |
||
1008 | * |
||
1009 | * Returns an array with the relevant data. |
||
1010 | * |
||
1011 | * @param mixed $remoteId |
||
1012 | * |
||
1013 | * @throws \eZ\Publish\Core\Base\Exceptions\NotFoundException |
||
1014 | * |
||
1015 | * @return array |
||
1016 | */ |
||
1017 | public function loadContentInfoByRemoteId($remoteId) |
||
1018 | { |
||
1019 | $queryBuilder = $this->createLoadContentInfoQueryBuilder(); |
||
1020 | $queryBuilder |
||
1021 | ->where('c.remote_id = :id') |
||
1022 | ->setParameter('id', $remoteId, ParameterType::STRING); |
||
1023 | |||
1024 | $results = $queryBuilder->execute()->fetchAll(FetchMode::ASSOCIATIVE); |
||
1025 | if (empty($results)) { |
||
1026 | throw new NotFound('content', "remote_id: $remoteId"); |
||
1027 | } |
||
1028 | |||
1029 | return $results[0]; |
||
1030 | } |
||
1031 | |||
1032 | /** |
||
1033 | * Loads info for a content object identified by its location ID (node ID). |
||
1034 | * |
||
1035 | * Returns an array with the relevant data. |
||
1036 | * |
||
1037 | * @param int $locationId |
||
1038 | * |
||
1039 | * @throws \eZ\Publish\Core\Base\Exceptions\NotFoundException |
||
1040 | * |
||
1041 | * @return array |
||
1042 | */ |
||
1043 | public function loadContentInfoByLocationId($locationId) |
||
1044 | { |
||
1045 | $queryBuilder = $this->createLoadContentInfoQueryBuilder(false); |
||
1046 | $queryBuilder |
||
1047 | ->where('t.node_id = :id') |
||
1048 | ->setParameter('id', $locationId, ParameterType::INTEGER); |
||
1049 | |||
1050 | $results = $queryBuilder->execute()->fetchAll(FetchMode::ASSOCIATIVE); |
||
1051 | if (empty($results)) { |
||
1052 | throw new NotFound('content', "node_id: $locationId"); |
||
1053 | } |
||
1054 | |||
1055 | return $results[0]; |
||
1056 | } |
||
1057 | |||
1058 | /** |
||
1059 | * Loads version info for content identified by $contentId and $versionNo. |
||
1060 | * Will basically return a hash containing all field values from ezcontentobject_version table plus following keys: |
||
1061 | * - names => Hash of content object names. Key is the language code, value is the name. |
||
1062 | * - 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. |
||
1063 | * - initial_language_code => Language code for initial language in this version. |
||
1064 | * |
||
1065 | * @param int $contentId |
||
1066 | * @param int|null $versionNo |
||
1067 | * |
||
1068 | * @return array |
||
1069 | */ |
||
1070 | public function loadVersionInfo($contentId, $versionNo = null) |
||
1071 | { |
||
1072 | $queryBuilder = $this->queryBuilder->createVersionInfoQueryBuilder($versionNo); |
||
1073 | $queryBuilder->where( |
||
1074 | $queryBuilder->expr()->eq( |
||
1075 | 'c.id', |
||
1076 | $queryBuilder->createNamedParameter($contentId, PDO::PARAM_INT) |
||
1077 | ) |
||
1078 | ); |
||
1079 | |||
1080 | return $queryBuilder->execute()->fetchAll(PDO::FETCH_ASSOC); |
||
1081 | } |
||
1082 | |||
1083 | /** |
||
1084 | * Returns data for all versions with given status created by the given $userId. |
||
1085 | * |
||
1086 | * @param int $userId |
||
1087 | * @param int $status |
||
1088 | * |
||
1089 | * @return string[][] |
||
1090 | */ |
||
1091 | public function listVersionsForUser($userId, $status = VersionInfo::STATUS_DRAFT) |
||
1109 | |||
1110 | /** |
||
1111 | * Returns all version data for the given $contentId, optionally filtered by status. |
||
1112 | * |
||
1113 | * Result is returned with oldest version first (using version id as it has index and is auto increment). |
||
1114 | * |
||
1115 | * @param mixed $contentId |
||
1116 | * @param mixed|null $status Optional argument to filter versions by status, like {@see VersionInfo::STATUS_ARCHIVED}. |
||
1117 | * @param int $limit Limit for items returned, -1 means none. |
||
1118 | * |
||
1119 | * @return string[][] |
||
1120 | */ |
||
1121 | public function listVersions($contentId, $status = null, $limit = -1) |
||
1148 | |||
1149 | /** |
||
1150 | * Helper for {@see listVersions()} and {@see listVersionsForUser()} that filters duplicates |
||
1151 | * that are the result of the cartesian product performed by createVersionInfoFindQuery(). |
||
1152 | * |
||
1153 | * @param \eZ\Publish\Core\Persistence\Database\SelectQuery $query |
||
1154 | * |
||
1155 | * @return string[][] |
||
1156 | */ |
||
1157 | private function listVersionsHelper(SelectQuery $query) |
||
1179 | |||
1180 | /** |
||
1181 | * Returns all version numbers for the given $contentId. |
||
1182 | * |
||
1183 | * @param mixed $contentId |
||
1184 | * |
||
1185 | * @return int[] |
||
1186 | */ |
||
1187 | public function listVersionNumbers($contentId) |
||
1206 | |||
1207 | /** |
||
1208 | * Returns last version number for content identified by $contentId. |
||
1209 | * |
||
1210 | * @param int $contentId |
||
1211 | * |
||
1212 | * @return int |
||
1213 | */ |
||
1214 | public function getLastVersionNumber($contentId) |
||
1233 | |||
1234 | /** |
||
1235 | * Returns all IDs for locations that refer to $contentId. |
||
1236 | * |
||
1237 | * @param int $contentId |
||
1238 | * |
||
1239 | * @return int[] |
||
1240 | */ |
||
1241 | public function getAllLocationIds($contentId) |
||
1260 | |||
1261 | /** |
||
1262 | * Returns all field IDs of $contentId grouped by their type. |
||
1263 | * If $versionNo is set only field IDs for that version are returned. |
||
1264 | * If $languageCode is set, only field IDs for that language are returned. |
||
1265 | * |
||
1266 | * @param int $contentId |
||
1267 | * @param int|null $versionNo |
||
1268 | * @param string|null $languageCode |
||
1269 | * |
||
1270 | * @return int[][] |
||
1271 | */ |
||
1272 | public function getFieldIdsByType($contentId, $versionNo = null, $languageCode = null) |
||
1318 | |||
1319 | /** |
||
1320 | * Deletes relations to and from $contentId. |
||
1321 | * If $versionNo is set only relations for that version are deleted. |
||
1322 | * |
||
1323 | * @param int $contentId |
||
1324 | * @param int|null $versionNo |
||
1325 | */ |
||
1326 | public function deleteRelations($contentId, $versionNo = null) |
||
1363 | |||
1364 | /** |
||
1365 | * Removes relations to Content with $contentId from Relation and RelationList field type fields. |
||
1366 | * |
||
1367 | * @param int $contentId |
||
1368 | */ |
||
1369 | public function removeReverseFieldRelations($contentId) |
||
1419 | |||
1420 | /** |
||
1421 | * Updates field value of RelationList field type identified by given $row data, |
||
1422 | * removing relations toward given $contentId. |
||
1423 | * |
||
1424 | * @param int $contentId |
||
1425 | * @param array $row |
||
1426 | */ |
||
1427 | protected function removeRelationFromRelationListField($contentId, array $row) |
||
1462 | |||
1463 | /** |
||
1464 | * Updates field value of Relation field type identified by given $row data, |
||
1465 | * removing relation data. |
||
1466 | * |
||
1467 | * @param array $row |
||
1468 | */ |
||
1469 | protected function removeRelationFromRelationField(array $row) |
||
1491 | |||
1492 | /** |
||
1493 | * Deletes the field with the given $fieldId. |
||
1494 | * |
||
1495 | * @param int $fieldId |
||
1496 | */ |
||
1497 | public function deleteField($fieldId) |
||
1511 | |||
1512 | /** |
||
1513 | * Deletes all fields of $contentId in all versions. |
||
1514 | * If $versionNo is set only fields for that version are deleted. |
||
1515 | * |
||
1516 | * @param int $contentId |
||
1517 | * @param int|null $versionNo |
||
1518 | */ |
||
1519 | public function deleteFields($contentId, $versionNo = null) |
||
1541 | |||
1542 | /** |
||
1543 | * Deletes all versions of $contentId. |
||
1544 | * If $versionNo is set only that version is deleted. |
||
1545 | * |
||
1546 | * @param int $contentId |
||
1547 | * @param int|null $versionNo |
||
1548 | */ |
||
1549 | public function deleteVersions($contentId, $versionNo = null) |
||
1571 | |||
1572 | /** |
||
1573 | * Deletes all names of $contentId. |
||
1574 | * If $versionNo is set only names for that version are deleted. |
||
1575 | * |
||
1576 | * @param int $contentId |
||
1577 | * @param int|null $versionNo |
||
1578 | */ |
||
1579 | public function deleteNames($contentId, $versionNo = null) |
||
1601 | |||
1602 | /** |
||
1603 | * Sets the name for Content $contentId in version $version to $name in $language. |
||
1604 | * |
||
1605 | * @param int $contentId |
||
1606 | * @param int $version |
||
1607 | * @param string $name |
||
1608 | * @param string $language |
||
1609 | */ |
||
1610 | public function setName($contentId, $version, $name, $language) |
||
1671 | |||
1672 | /** |
||
1673 | * Returns a language sub select query for setName. |
||
1674 | * |
||
1675 | * Return sub select query which gets proper language mask for alwaysAvailable Content. |
||
1676 | * |
||
1677 | * @return \eZ\Publish\Core\Persistence\Database\SelectQuery |
||
1678 | */ |
||
1679 | private function getLanguageQuery() |
||
1718 | |||
1719 | /** |
||
1720 | * Deletes the actual content object referred to by $contentId. |
||
1721 | * |
||
1722 | * @param int $contentId |
||
1723 | */ |
||
1724 | public function deleteContent($contentId) |
||
1737 | |||
1738 | /** |
||
1739 | * Loads relations from $contentId to published content, optionally only from $contentVersionNo. |
||
1740 | * |
||
1741 | * $relationType can also be filtered. |
||
1742 | * |
||
1743 | * @param int $contentId |
||
1744 | * @param int $contentVersionNo |
||
1745 | * @param int $relationType |
||
1746 | * |
||
1747 | * @return string[][] array of relation data |
||
1748 | */ |
||
1749 | public function loadRelations($contentId, $contentVersionNo = null, $relationType = null) |
||
1817 | |||
1818 | /** |
||
1819 | * {@inheritdoc} |
||
1820 | */ |
||
1821 | public function countReverseRelations(int $toContentId, ?int $relationType = null): int |
||
1856 | |||
1857 | /** |
||
1858 | * Loads data that related to $toContentId. |
||
1859 | * |
||
1860 | * @param int $toContentId |
||
1861 | * @param int $relationType |
||
1862 | * |
||
1863 | * @return mixed[][] Content data, array structured like {@see \eZ\Publish\Core\Persistence\Legacy\Content\Gateway::load()} |
||
1864 | */ |
||
1865 | public function loadReverseRelations($toContentId, $relationType = null) |
||
1914 | |||
1915 | /** |
||
1916 | * Inserts a new relation database record. |
||
1917 | * |
||
1918 | * @param \eZ\Publish\SPI\Persistence\Content\Relation\CreateStruct $createStruct |
||
1919 | * |
||
1920 | * @return int ID the inserted ID |
||
1921 | */ |
||
1922 | public function insertRelation(RelationCreateStruct $createStruct) |
||
1953 | |||
1954 | /** |
||
1955 | * Deletes the relation with the given $relationId. |
||
1956 | * |
||
1957 | * @param int $relationId |
||
1958 | * @param int $type {@see \eZ\Publish\API\Repository\Values\Content\Relation::COMMON, |
||
1959 | * \eZ\Publish\API\Repository\Values\Content\Relation::EMBED, |
||
1960 | * \eZ\Publish\API\Repository\Values\Content\Relation::LINK, |
||
1961 | * \eZ\Publish\API\Repository\Values\Content\Relation::FIELD} |
||
1962 | */ |
||
1963 | public function deleteRelation($relationId, $type) |
||
2025 | |||
2026 | /** |
||
2027 | * Returns all Content IDs for a given $contentTypeId. |
||
2028 | * |
||
2029 | * @param int $contentTypeId |
||
2030 | * |
||
2031 | * @return int[] |
||
2032 | */ |
||
2033 | public function getContentIdsByContentTypeId($contentTypeId) |
||
2051 | |||
2052 | /** |
||
2053 | * Load name data for set of content id's and corresponding version number. |
||
2054 | * |
||
2055 | * @param array[] $rows array of hashes with 'id' and 'version' to load names for |
||
2056 | * |
||
2057 | * @return array |
||
2058 | */ |
||
2059 | public function loadVersionedNameData($rows) |
||
2082 | |||
2083 | /** |
||
2084 | * Batch method for copying all relation meta data for copied Content object. |
||
2085 | * |
||
2086 | * {@inheritdoc} |
||
2087 | * |
||
2088 | * @param int $originalContentId |
||
2089 | * @param int $copiedContentId |
||
2090 | * @param int|null $versionNo If specified only copy for a given version number, otherwise all. |
||
2091 | */ |
||
2092 | public function copyRelations($originalContentId, $copiedContentId, $versionNo = null) |
||
2112 | |||
2113 | /** |
||
2114 | * Remove the specified translation from the Content Object Version. |
||
2115 | * |
||
2116 | * @param int $contentId |
||
2117 | * @param string $languageCode language code of the translation |
||
2118 | * @throws \Doctrine\DBAL\DBALException |
||
2119 | */ |
||
2120 | public function deleteTranslationFromContent($contentId, $languageCode) |
||
2136 | |||
2137 | /** |
||
2138 | * Delete Content fields (attributes) for the given Translation. |
||
2139 | * If $versionNo is given, fields for that Version only will be deleted. |
||
2140 | * |
||
2141 | * @param string $languageCode |
||
2142 | * @param int $contentId |
||
2143 | * @param int $versionNo (optional) filter by versionNo |
||
2144 | */ |
||
2145 | public function deleteTranslatedFields($languageCode, $contentId, $versionNo = null) |
||
2169 | |||
2170 | /** |
||
2171 | * Delete the specified Translation from the given Version. |
||
2172 | * |
||
2173 | * @param int $contentId |
||
2174 | * @param int $versionNo |
||
2175 | * @param string $languageCode |
||
2176 | * @throws \Doctrine\DBAL\DBALException |
||
2177 | */ |
||
2178 | public function deleteTranslationFromVersion($contentId, $versionNo, $languageCode) |
||
2193 | |||
2194 | /** |
||
2195 | * Delete translation from the ezcontentobject_name table. |
||
2196 | * |
||
2197 | * @param int $contentId |
||
2198 | * @param string $languageCode |
||
2199 | * @param int $versionNo optional, if specified, apply to this Version only. |
||
2200 | */ |
||
2201 | private function deleteTranslationFromContentNames($contentId, $languageCode, $versionNo = null) |
||
2225 | |||
2226 | /** |
||
2227 | * Remove language from language_mask of ezcontentobject. |
||
2228 | * |
||
2229 | * @param int $contentId |
||
2230 | * @param int $languageId |
||
2231 | * @throws \eZ\Publish\Core\Base\Exceptions\BadStateException |
||
2232 | */ |
||
2233 | private function deleteTranslationFromContentObject($contentId, $languageId) |
||
2262 | |||
2263 | /** |
||
2264 | * Remove language from language_mask of ezcontentobject_version and update initialLanguageId |
||
2265 | * if it matches the removed one. |
||
2266 | * |
||
2267 | * @param int $contentId |
||
2268 | * @param int $languageId |
||
2269 | * @param int $versionNo optional, if specified, apply to this Version only. |
||
2270 | * @throws \eZ\Publish\Core\Base\Exceptions\BadStateException |
||
2271 | */ |
||
2272 | private function deleteTranslationFromContentVersions($contentId, $languageId, $versionNo = null) |
||
2316 | } |
||
2317 |
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.