TemplateOrmLoader::__invoke()   B
last analyzed

Complexity

Conditions 3
Paths 2

Size

Total Lines 29
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 29
rs 8.8571
c 0
b 0
f 0
cc 3
eloc 16
nc 2
nop 1
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)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
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)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
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