1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Synapse\Cmf\Bundle\Loader\Orm; |
4
|
|
|
|
5
|
|
|
use Majora\Framework\Loader\Bridge\Doctrine\AbstractDoctrineLoader; |
6
|
|
|
use Majora\Framework\Loader\Bridge\Doctrine\DoctrineLoaderTrait; |
7
|
|
|
use Majora\Framework\Loader\LazyLoaderInterface; |
8
|
|
|
use Synapse\Cmf\Bundle\Entity\Orm\Template; |
9
|
|
|
use Synapse\Cmf\Bundle\Entity\Orm\Zone; |
10
|
|
|
use Synapse\Cmf\Bundle\Loader\Orm\ZoneOrmLoader as ZoneLoader; |
11
|
|
|
use Synapse\Cmf\Framework\Theme\ContentType\Loader\LoaderInterface as ContentTypeLoader; |
12
|
|
|
use Synapse\Cmf\Framework\Theme\ContentType\Model\ContentTypeInterface; |
13
|
|
|
use Synapse\Cmf\Framework\Theme\Content\Entity\Content; |
14
|
|
|
use Synapse\Cmf\Framework\Theme\TemplateType\Entity\TemplateType; |
15
|
|
|
use Synapse\Cmf\Framework\Theme\TemplateType\Loader\LoaderInterface as TemplateTypeLoader; |
16
|
|
|
use Synapse\Cmf\Framework\Theme\Template\Loader\LoaderInterface as TemplateLoaderInterface; |
17
|
|
|
use Synapse\Cmf\Framework\Theme\Template\Model\TemplateInterface; |
18
|
|
|
use Synapse\Cmf\Framework\Theme\ZoneType\Model\ZoneTypeInterface; |
19
|
|
|
use Synapse\Cmf\Framework\Theme\Zone\Domain\ZoneDomain; |
20
|
|
|
use Synapse\Cmf\Framework\Theme\Zone\Entity\ZoneCollection; |
21
|
|
|
|
22
|
|
|
/** |
23
|
|
|
* Template loader override to register lazy loaders. |
24
|
|
|
*/ |
25
|
|
|
class TemplateOrmLoader extends AbstractDoctrineLoader implements TemplateLoaderInterface, LazyLoaderInterface |
26
|
|
|
{ |
27
|
|
|
use DoctrineLoaderTrait; |
28
|
|
|
|
29
|
|
|
/** |
30
|
|
|
* @var TemplateTypeLoader |
31
|
|
|
*/ |
32
|
|
|
protected $templateTypeLoader; |
33
|
|
|
|
34
|
|
|
/** |
35
|
|
|
* @var ContentTypeLoader |
36
|
|
|
*/ |
37
|
|
|
protected $contentTypeLoader; |
38
|
|
|
|
39
|
|
|
/** |
40
|
|
|
* @var ZoneLoader |
41
|
|
|
*/ |
42
|
|
|
protected $zoneLoader; |
43
|
|
|
|
44
|
|
|
/** |
45
|
|
|
* @var ZoneDomain |
46
|
|
|
*/ |
47
|
|
|
protected $zoneDomain; |
48
|
|
|
|
49
|
|
|
/** |
50
|
|
|
* Construct. |
51
|
|
|
* |
52
|
|
|
* @param TemplateTypeLoader $templateTypeLoader |
53
|
|
|
* @param ContentTypeLoader $contentTypeLoader |
54
|
|
|
* @param ZoneLoader $zoneLoader |
55
|
|
|
* @param ZoneDomain $zoneDomain |
56
|
|
|
*/ |
57
|
|
|
public function __construct( |
58
|
|
|
TemplateTypeLoader $templateTypeLoader, |
59
|
|
|
ContentTypeLoader $contentTypeLoader, |
60
|
|
|
ZoneLoader $zoneLoader, |
61
|
|
|
ZoneDomain $zoneDomain |
62
|
|
|
) { |
63
|
|
|
$this->templateTypeLoader = $templateTypeLoader; |
64
|
|
|
$this->contentTypeLoader = $contentTypeLoader; |
65
|
|
|
$this->zoneLoader = $zoneLoader; |
66
|
|
|
$this->zoneDomain = $zoneDomain; |
67
|
|
|
} |
68
|
|
|
|
69
|
|
|
/** |
70
|
|
|
* @see LazyLoaderInterface::getLoadingDelegates() |
71
|
|
|
*/ |
72
|
|
|
public function getLoadingDelegates() |
73
|
|
|
{ |
74
|
|
|
return array( |
75
|
|
|
'contentType' => function (Template $template) { |
76
|
|
|
return $this->contentTypeLoader->retrieve($template->getContentTypeName()); |
77
|
|
|
}, |
78
|
|
|
); |
79
|
|
|
} |
80
|
|
|
|
81
|
|
|
/** |
82
|
|
|
* Loader invocable handler as proxy for template factory method |
83
|
|
|
* |
84
|
|
|
* @param Template $template |
85
|
|
|
* |
86
|
|
|
* @return Template |
87
|
|
|
*/ |
88
|
|
|
public function __invoke(Template $template) |
89
|
|
|
{ |
90
|
|
|
// fetch TemplateType |
91
|
|
|
if (!$templateType = $this->templateTypeLoader->retrieve($template->getTemplateTypeId())) { |
92
|
|
|
throw new \RuntimeException(sprintf( |
93
|
|
|
'Unavailable to load template type "%s", from template "%s". Maybe your data and configurations have diverged, available templates types are : %s. Please check your themes configurations.', |
94
|
|
|
$template->getTemplateTypeId(), |
95
|
|
|
$template->getId(), |
96
|
|
|
$this->templateTypeLoader->retrieveAll()->display('id') |
97
|
|
|
)); |
98
|
|
|
} |
99
|
|
|
|
100
|
|
|
// due to Doctrine joined hydration concurrency with events, |
101
|
|
|
// we have to direct call zone hydration from another request |
102
|
|
|
$templateZones = $this->zoneLoader->retrieveForTemplate($template); |
103
|
|
|
|
104
|
|
|
$template |
105
|
|
|
->setTemplateType($templateType) |
106
|
|
|
->setZones(new ZoneCollection( |
107
|
|
|
$templateType->getZoneTypes() |
108
|
|
|
->map(function (ZoneTypeInterface $zoneType) use ($template, $templateZones) { |
109
|
|
|
return $templateZones->search(array('zoneType' => $zoneType))->first() |
110
|
|
|
?: $this->zoneDomain->create($zoneType) |
111
|
|
|
; |
112
|
|
|
}) |
113
|
|
|
->toArray() |
114
|
|
|
)) |
115
|
|
|
; |
116
|
|
|
} |
117
|
|
|
|
118
|
|
|
/** |
119
|
|
|
* @see TemplateLoaderInterface::retrieveDisplayable() |
120
|
|
|
*/ |
121
|
|
|
public function retrieveDisplayable(TemplateType $templateType, Content $content) |
122
|
|
|
{ |
123
|
|
|
$queryBuilder = $this->getEntityRepository() |
124
|
|
|
->createQueryBuilder('template') |
125
|
|
|
; |
126
|
|
|
|
127
|
|
|
$displayableTemplates = $this->toEntityCollection( |
128
|
|
|
$queryBuilder |
129
|
|
|
->andWhere('template.templateTypeId = :templateTypeId') |
130
|
|
|
->andWhere('template.contentTypeName = :contentTypeName') |
131
|
|
|
->andWhere($queryBuilder->expr()->orX( |
132
|
|
|
$queryBuilder->expr()->eq('template.contentId', ':contentId'), |
133
|
|
|
$queryBuilder->expr()->isNull('template.contentId') |
134
|
|
|
)) |
135
|
|
|
->setParameters(array( |
136
|
|
|
'templateTypeId' => $templateType->getId(), |
137
|
|
|
'contentTypeName' => $content->getType()->getName(), |
138
|
|
|
'contentId' => $content->getContentId(), |
139
|
|
|
)) |
140
|
|
|
->getQuery() |
141
|
|
|
->getResult() |
142
|
|
|
); |
143
|
|
|
if ($displayableTemplates->isEmpty()) { |
144
|
|
|
return; |
145
|
|
|
} |
146
|
|
|
if ($displayableTemplates->count() == 1) { |
147
|
|
|
return $displayableTemplates->first(); |
148
|
|
|
} |
149
|
|
|
|
150
|
|
|
// local by default (with hydrated global) |
151
|
|
|
return $displayableTemplates |
152
|
|
|
->search(array('scope' => TemplateInterface::LOCAL_SCOPE))->first() |
153
|
|
|
->setGlobalTemplate( |
154
|
|
|
$displayableTemplates->search(array('scope' => TemplateInterface::GLOBAL_SCOPE))->first() |
155
|
|
|
) |
156
|
|
|
; |
157
|
|
|
} |
158
|
|
|
|
159
|
|
|
/** |
160
|
|
|
* @see TemplateLoaderInterface::retrieveLocal() |
161
|
|
|
*/ |
162
|
|
View Code Duplication |
public function retrieveLocal(TemplateType $templateType, Content $content) |
|
|
|
|
163
|
|
|
{ |
164
|
|
|
$queryBuilder = $this->createQuery('template'); |
165
|
|
|
|
166
|
|
|
return $queryBuilder |
167
|
|
|
->andWhere('template.templateTypeId = :templateTypeId') |
168
|
|
|
->andWhere('template.contentTypeName = :contentTypeName') |
169
|
|
|
->andWhere('template.contentId = :contentId') |
170
|
|
|
->setParameters(array( |
171
|
|
|
'templateTypeId' => $templateType->getId(), |
172
|
|
|
'contentTypeName' => $content->getType()->getName(), |
173
|
|
|
'contentId' => $content->getContentId(), |
174
|
|
|
)) |
175
|
|
|
->getQuery() |
176
|
|
|
->getOneOrNullResult() |
177
|
|
|
; |
178
|
|
|
} |
179
|
|
|
|
180
|
|
|
/** |
181
|
|
|
* @see TemplateLoaderInterface::retrieveGlobal() |
182
|
|
|
*/ |
183
|
|
View Code Duplication |
public function retrieveGlobal(TemplateType $templateType, ContentTypeInterface $contentType) |
|
|
|
|
184
|
|
|
{ |
185
|
|
|
$queryBuilder = $this->createQuery('template'); |
186
|
|
|
|
187
|
|
|
return $queryBuilder |
188
|
|
|
->andWhere('template.templateTypeId = :templateTypeId') |
189
|
|
|
->andWhere('template.contentTypeName = :contentTypeName') |
190
|
|
|
->andWhere('template.contentId is null') |
191
|
|
|
->setParameters(array( |
192
|
|
|
'templateTypeId' => $templateType->getId(), |
193
|
|
|
'contentTypeName' => $contentType->getName(), |
194
|
|
|
)) |
195
|
|
|
->getQuery() |
196
|
|
|
->getOneOrNullResult() |
197
|
|
|
; |
198
|
|
|
} |
199
|
|
|
} |
200
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.