1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Victoire\Bundle\BusinessPageBundle\Helper; |
4
|
|
|
|
5
|
|
|
use Doctrine\DBAL\Schema\View; |
6
|
|
|
use Doctrine\ORM\EntityManager; |
7
|
|
|
use Doctrine\ORM\QueryBuilder; |
8
|
|
|
use Victoire\Bundle\BusinessEntityBundle\Converter\ParameterConverter; |
9
|
|
|
use Victoire\Bundle\BusinessEntityBundle\Entity\BusinessEntity; |
10
|
|
|
use Victoire\Bundle\BusinessEntityBundle\Entity\BusinessProperty; |
11
|
|
|
use Victoire\Bundle\BusinessEntityBundle\Helper\BusinessEntityHelper; |
12
|
|
|
use Victoire\Bundle\BusinessPageBundle\Entity\BusinessTemplate; |
13
|
|
|
use Victoire\Bundle\CoreBundle\Helper\UrlBuilder; |
14
|
|
|
use Victoire\Bundle\QueryBundle\Helper\QueryHelper; |
15
|
|
|
use Victoire\Bundle\ViewReferenceBundle\Connector\ViewReferenceRepository; |
16
|
|
|
use Victoire\Bundle\ViewReferenceBundle\ViewReference\BusinessPageReference; |
17
|
|
|
|
18
|
|
|
/** |
19
|
|
|
* The business entity page pattern helper |
20
|
|
|
* ref: victoire_business_page.business_page_helper. |
21
|
|
|
*/ |
22
|
|
|
class BusinessPageHelper |
23
|
|
|
{ |
24
|
|
|
protected $queryHelper = null; |
25
|
|
|
protected $viewReferenceRepository = null; |
26
|
|
|
protected $businessEntityHelper = null; |
27
|
|
|
protected $parameterConverter = null; |
28
|
|
|
protected $urlBuilder = null; |
29
|
|
|
|
30
|
|
|
/** |
31
|
|
|
* @param QueryHelper $queryHelper |
32
|
|
|
* @param ViewReferenceRepository $viewReferenceRepository |
33
|
|
|
* @param BusinessEntityHelper $businessEntityHelper |
34
|
|
|
* @param ParameterConverter $parameterConverter |
35
|
|
|
* @param UrlBuilder $urlBuilder |
36
|
|
|
*/ |
37
|
|
View Code Duplication |
public function __construct(QueryHelper $queryHelper, ViewReferenceRepository $viewReferenceRepository, BusinessEntityHelper $businessEntityHelper, ParameterConverter $parameterConverter, UrlBuilder $urlBuilder) |
|
|
|
|
38
|
|
|
{ |
39
|
|
|
$this->queryHelper = $queryHelper; |
40
|
|
|
$this->viewReferenceRepository = $viewReferenceRepository; |
41
|
|
|
$this->businessEntityHelper = $businessEntityHelper; |
42
|
|
|
$this->parameterConverter = $parameterConverter; |
43
|
|
|
$this->urlBuilder = $urlBuilder; |
44
|
|
|
} |
45
|
|
|
|
46
|
|
|
/** |
47
|
|
|
* Is the entity allowed for the business entity page. |
48
|
|
|
* |
49
|
|
|
* @param BusinessTemplate $businessTemplate |
50
|
|
|
* @param object|null $entity |
51
|
|
|
* @param EntityManager $em |
52
|
|
|
* |
53
|
|
|
* @throws \Exception |
54
|
|
|
* |
55
|
|
|
* @return bool |
56
|
|
|
*/ |
57
|
|
|
public function isEntityAllowed(BusinessTemplate $businessTemplate, $entity, EntityManager $em = null) |
58
|
|
|
{ |
59
|
|
|
$allowed = true; |
60
|
|
|
|
61
|
|
|
//test that an entity is given |
62
|
|
|
if ($entity === null) { |
63
|
|
|
throw new \Exception('The entity is required.'); |
64
|
|
|
} |
65
|
|
|
|
66
|
|
|
$queryHelper = $this->queryHelper; |
67
|
|
|
|
68
|
|
|
//the page id |
69
|
|
|
$entityId = $entity->getId(); |
70
|
|
|
|
71
|
|
|
//the base of the query |
72
|
|
|
$baseQuery = $queryHelper->getQueryBuilder($businessTemplate, $em); |
|
|
|
|
73
|
|
|
|
74
|
|
|
$baseQuery->andWhere('main_item.id = '.$entityId); |
75
|
|
|
|
76
|
|
|
//filter with the query of the page |
77
|
|
|
$items = $queryHelper->buildWithSubQuery($businessTemplate, $baseQuery, $em) |
|
|
|
|
78
|
|
|
->getQuery()->getResult(); |
79
|
|
|
|
80
|
|
|
//only one page can be found because we filter on the |
81
|
|
|
if (count($items) > 1) { |
82
|
|
|
throw new \Exception('More than 1 item was found, there should not be more than 1 item with this query.'); |
83
|
|
|
} |
84
|
|
|
|
85
|
|
|
if (count($items) === 0) { |
86
|
|
|
$allowed = false; |
87
|
|
|
} |
88
|
|
|
|
89
|
|
|
return $allowed; |
90
|
|
|
} |
91
|
|
|
|
92
|
|
|
/** |
93
|
|
|
* Get the list of entities allowed for the BusinessTemplate page. |
94
|
|
|
* |
95
|
|
|
* @param BusinessTemplate $businessTemplate |
96
|
|
|
* @param EntityManager $em |
97
|
|
|
* |
98
|
|
|
* @return array |
99
|
|
|
*/ |
100
|
|
|
public function getEntitiesAllowed(BusinessTemplate $businessTemplate, EntityManager $em) |
101
|
|
|
{ |
102
|
|
|
return $this->getEntitiesAllowedQueryBuilder($businessTemplate, $em) |
103
|
|
|
->getQuery() |
104
|
|
|
->getResult(); |
105
|
|
|
} |
106
|
|
|
|
107
|
|
|
/** |
108
|
|
|
* Get the list of entities allowed for the BusinessTemplate page. |
109
|
|
|
* |
110
|
|
|
* @param BusinessTemplate $businessTemplate |
111
|
|
|
* @param EntityManager $em |
112
|
|
|
* |
113
|
|
|
* @throws \Exception |
114
|
|
|
* |
115
|
|
|
* @return QueryBuilder |
116
|
|
|
*/ |
117
|
|
|
public function getEntitiesAllowedQueryBuilder(BusinessTemplate $businessTemplate, EntityManager $em) |
118
|
|
|
{ |
119
|
|
|
//the base of the query |
120
|
|
|
$baseQuery = $this->queryHelper->getQueryBuilder($businessTemplate, $em); |
121
|
|
|
|
122
|
|
|
// add this fake condition to ensure that there is always a "where" clause. |
123
|
|
|
// In query mode, usage of "AND" will be always valid instead of "WHERE" |
124
|
|
|
$baseQuery->andWhere('1 = 1'); |
125
|
|
|
|
126
|
|
|
//filter with the query of the page |
127
|
|
|
return $this->queryHelper->buildWithSubQuery($businessTemplate, $baseQuery, $em); |
128
|
|
|
} |
129
|
|
|
|
130
|
|
|
/** |
131
|
|
|
* Get the list of business properties usable for the url. |
132
|
|
|
* |
133
|
|
|
* @param BusinessEntity $businessEntity |
134
|
|
|
* |
135
|
|
|
* @return BusinessProperty[] The list of business properties |
136
|
|
|
*/ |
137
|
|
View Code Duplication |
public function getBusinessProperties(BusinessEntity $businessEntity) |
|
|
|
|
138
|
|
|
{ |
139
|
|
|
//the business properties usable in a url |
140
|
|
|
$businessProperties = $businessEntity->getBusinessPropertiesByType('businessParameter'); |
141
|
|
|
|
142
|
|
|
//the business properties usable in a url |
143
|
|
|
$seoBusinessProps = $businessEntity->getBusinessPropertiesByType('seoable'); |
144
|
|
|
|
145
|
|
|
//the business properties are the identifier and the seoables properties |
146
|
|
|
$businessProperties = array_merge($businessProperties, $seoBusinessProps); |
147
|
|
|
|
148
|
|
|
return $businessProperties; |
149
|
|
|
} |
150
|
|
|
|
151
|
|
|
/** |
152
|
|
|
* Get the position of the identifier in the url of a business entity page pattern. |
153
|
|
|
* |
154
|
|
|
* @param BusinessTemplate $businessTemplate |
155
|
|
|
* |
156
|
|
|
* @return int The position |
157
|
|
|
*/ |
158
|
|
|
public function getIdentifierPositionInUrl(BusinessTemplate $businessTemplate) |
159
|
|
|
{ |
160
|
|
|
$position = null; |
161
|
|
|
|
162
|
|
|
$url = $businessTemplate->getUrl(); |
|
|
|
|
163
|
|
|
|
164
|
|
|
// split on the / character |
165
|
|
|
$keywords = preg_split("/\//", $url); |
166
|
|
|
// preg_match_all('/\{\%\s*([^\%\}]*)\s*\%\}|\{\{\s*([^\}\}]*)\s*\}\}/i', $url, $matches); |
|
|
|
|
167
|
|
|
|
168
|
|
|
//the business property link to the page |
169
|
|
|
$businessEntityId = $businessTemplate->getBusinessEntityId(); |
170
|
|
|
|
171
|
|
|
$businessEntity = $this->businessEntityHelper->findById($businessEntityId); |
172
|
|
|
|
173
|
|
|
//the business properties usable in a url |
174
|
|
|
$businessProperties = $businessEntity->getBusinessPropertiesByType('businessParameter'); |
175
|
|
|
|
176
|
|
|
//we parse the words of the url |
177
|
|
|
foreach ($keywords as $index => $keyword) { |
178
|
|
|
foreach ($businessProperties as $businessProperty) { |
179
|
|
|
$entityProperty = $businessProperty->getEntityProperty(); |
180
|
|
|
$searchWord = '{{item.'.$entityProperty.'}}'; |
181
|
|
|
|
182
|
|
|
if ($searchWord === $keyword) { |
183
|
|
|
//the array start at index 0 but we want the position to start at 1 |
184
|
|
|
$position = [ |
185
|
|
|
'position' => $index + 1, |
186
|
|
|
'businessProperty' => $businessProperty, |
187
|
|
|
]; |
188
|
|
|
} |
189
|
|
|
} |
190
|
|
|
} |
191
|
|
|
|
192
|
|
|
return $position; |
193
|
|
|
} |
194
|
|
|
|
195
|
|
|
/** |
196
|
|
|
* Guess the best pattern to represent given reflectionClass. |
197
|
|
|
* |
198
|
|
|
* @param \ReflectionClass $refClass |
199
|
|
|
* @param int $entityId |
200
|
|
|
* @param EntityManager $em |
201
|
|
|
* @param string $originalRefClassName When digging into parentClass, we do not have to forget originalClass to be able to get reference after all |
202
|
|
|
* |
203
|
|
|
* @throws \Exception |
204
|
|
|
* |
205
|
|
|
* @return View |
206
|
|
|
*/ |
207
|
|
|
public function guessBestPatternIdForEntity($refClass, $entityId, $em, $originalRefClassName = null) |
208
|
|
|
{ |
209
|
|
|
$templateId = null; |
210
|
|
|
$refClassName = $em->getClassMetadata($refClass->name)->name; |
211
|
|
|
|
212
|
|
|
$viewReference = null; |
213
|
|
|
if (!$originalRefClassName) { |
|
|
|
|
214
|
|
|
$originalRefClassName = $refClassName; |
215
|
|
|
} |
216
|
|
|
|
217
|
|
|
$businessEntity = $this->businessEntityHelper->findByEntityClassname($refClassName); |
218
|
|
|
|
219
|
|
|
if ($businessEntity) { |
220
|
|
|
$parameters = [ |
221
|
|
|
'entityId' => $entityId, |
222
|
|
|
'entityNamespace' => $originalRefClassName, |
223
|
|
|
]; |
224
|
|
|
$viewReference = $this->viewReferenceRepository->getOneReferenceByParameters($parameters); |
225
|
|
|
} |
226
|
|
|
|
227
|
|
|
if (!$viewReference) { |
228
|
|
|
$parentRefClass = $refClass->getParentClass(); |
229
|
|
|
if ($parentRefClass) { |
230
|
|
|
$templateId = $this->guessBestPatternIdForEntity($parentRefClass, $entityId, $em, $originalRefClassName); |
231
|
|
|
} else { |
232
|
|
|
throw new \Exception(sprintf('Cannot find a BusinessTemplate that can display the requested BusinessEntity ("%s", "%s".)', $refClassName, $entityId)); |
233
|
|
|
} |
234
|
|
|
} elseif ($viewReference instanceof BusinessPageReference) { |
235
|
|
|
$templateId = $viewReference->getTemplateId(); |
236
|
|
|
} |
237
|
|
|
|
238
|
|
|
return $templateId; |
239
|
|
|
} |
240
|
|
|
} |
241
|
|
|
|
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.