|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
/* |
|
4
|
|
|
* This file is part of EC-CUBE |
|
5
|
|
|
* |
|
6
|
|
|
* Copyright(c) LOCKON CO.,LTD. All Rights Reserved. |
|
7
|
|
|
* |
|
8
|
|
|
* http://www.lockon.co.jp/ |
|
9
|
|
|
* |
|
10
|
|
|
* For the full copyright and license information, please view the LICENSE |
|
11
|
|
|
* file that was distributed with this source code. |
|
12
|
|
|
*/ |
|
13
|
|
|
|
|
14
|
|
|
namespace Eccube\Controller\Admin\Content; |
|
15
|
|
|
|
|
16
|
|
|
use Doctrine\ORM\NoResultException; |
|
17
|
|
|
use Eccube\Controller\AbstractController; |
|
18
|
|
|
use Eccube\Entity\BlockPosition; |
|
19
|
|
|
use Eccube\Entity\Layout; |
|
20
|
|
|
use Eccube\Form\Type\Master\DeviceTypeType; |
|
21
|
|
|
use Eccube\Repository\BlockRepository; |
|
22
|
|
|
use Eccube\Repository\LayoutRepository; |
|
23
|
|
|
use Eccube\Repository\PageLayoutRepository; |
|
24
|
|
|
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method; |
|
25
|
|
|
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; |
|
26
|
|
|
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; |
|
27
|
|
|
use Symfony\Component\Form\Extension\Core\Type\FormType; |
|
28
|
|
|
use Symfony\Component\Form\Extension\Core\Type\TextType; |
|
29
|
|
|
use Symfony\Component\HttpFoundation\JsonResponse; |
|
30
|
|
|
use Symfony\Component\HttpFoundation\RedirectResponse; |
|
31
|
|
|
use Symfony\Component\HttpFoundation\Request; |
|
32
|
|
|
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; |
|
33
|
|
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; |
|
34
|
|
|
use Symfony\Component\Validator\Constraints\NotBlank; |
|
35
|
|
|
use Twig\Environment as Twig; |
|
36
|
|
|
|
|
37
|
|
|
// todo プレビュー実装 |
|
38
|
|
|
class LayoutController extends AbstractController |
|
39
|
|
|
{ |
|
40
|
|
|
const DUMMY_BLOCK_ID = 9999999999; |
|
41
|
|
|
|
|
42
|
|
|
/** |
|
43
|
|
|
* @var BlockRepository |
|
44
|
|
|
*/ |
|
45
|
|
|
protected $blockRepository; |
|
46
|
|
|
|
|
47
|
|
|
/** |
|
48
|
|
|
* @var LayoutRepository |
|
49
|
|
|
*/ |
|
50
|
|
|
protected $layoutRepository; |
|
51
|
|
|
|
|
52
|
|
|
/** |
|
53
|
|
|
* @var PageLayoutRepository |
|
54
|
|
|
*/ |
|
55
|
|
|
protected $pageLayoutRepository; |
|
56
|
|
|
|
|
57
|
|
|
/** |
|
58
|
|
|
* LayoutController constructor. |
|
59
|
|
|
* |
|
60
|
|
|
* @param BlockRepository $blockRepository |
|
61
|
|
|
* @param LayoutRepository $layoutRepository |
|
62
|
|
|
* @param PageLayoutRepository $pageLayoutRepository |
|
63
|
|
|
*/ |
|
64
|
6 |
|
public function __construct(BlockRepository $blockRepository, LayoutRepository $layoutRepository, PageLayoutRepository $pageLayoutRepository) |
|
65
|
|
|
{ |
|
66
|
6 |
|
$this->blockRepository = $blockRepository; |
|
67
|
6 |
|
$this->layoutRepository = $layoutRepository; |
|
68
|
6 |
|
$this->pageLayoutRepository = $pageLayoutRepository; |
|
69
|
|
|
} |
|
70
|
|
|
|
|
71
|
|
|
/** |
|
72
|
|
|
* @Route("/%eccube_admin_route%/content/layout", name="admin_content_layout") |
|
73
|
|
|
* @Template("@admin/Content/layout_list.twig") |
|
74
|
|
|
*/ |
|
75
|
3 |
|
public function index() |
|
76
|
|
|
{ |
|
77
|
3 |
|
$Layouts = $this->layoutRepository->findBy([], ['DeviceType' => 'DESC', 'id' => 'ASC']); |
|
78
|
|
|
|
|
79
|
|
|
return [ |
|
80
|
3 |
|
'Layouts' => $Layouts, |
|
81
|
|
|
]; |
|
82
|
|
|
} |
|
83
|
|
|
|
|
84
|
|
|
/** |
|
85
|
|
|
* @Method("DELETE") |
|
86
|
|
|
* @Route("/%eccube_admin_route%/content/layout/{id}/delete", requirements={"id" = "\d+"}, name="admin_content_layout_delete") |
|
87
|
|
|
* |
|
88
|
|
|
* @param Layout $Layout |
|
89
|
|
|
* |
|
90
|
|
|
* @return RedirectResponse |
|
91
|
|
|
*/ |
|
92
|
2 |
|
public function delete(Layout $Layout) |
|
93
|
|
|
{ |
|
94
|
2 |
|
$this->isTokenValid(); |
|
95
|
|
|
|
|
96
|
|
|
/** @var Layout $Layout */ |
|
97
|
2 |
|
if (!$Layout->isDeletable()) { |
|
98
|
1 |
|
$this->deleteMessage(); |
|
99
|
|
|
|
|
100
|
1 |
|
return $this->redirectToRoute('admin_content_layout'); |
|
101
|
|
|
} |
|
102
|
|
|
|
|
103
|
1 |
|
$this->entityManager->remove($Layout); |
|
104
|
1 |
|
$this->entityManager->flush($Layout); |
|
|
|
|
|
|
105
|
|
|
|
|
106
|
1 |
|
$this->addSuccess('admin.delete.complete', 'admin'); |
|
107
|
|
|
|
|
108
|
1 |
|
return $this->redirectToRoute('admin_content_layout'); |
|
109
|
|
|
} |
|
110
|
|
|
|
|
111
|
|
|
/** |
|
112
|
|
|
* @Route("/%eccube_admin_route%/content/layout/new", name="admin_content_layout_new") |
|
113
|
|
|
* @Route("/%eccube_admin_route%/content/layout/{id}/edit", requirements={"id" = "\d+"}, name="admin_content_layout_edit") |
|
114
|
|
|
* @Template("@admin/Content/layout.twig") |
|
115
|
|
|
*/ |
|
116
|
2 |
|
public function edit(Request $request, $id = null) |
|
117
|
|
|
{ |
|
118
|
2 |
|
if (is_null($id)) { |
|
119
|
1 |
|
$Layout = new Layout(); |
|
120
|
|
|
} else { |
|
121
|
|
|
// todo レポジトリへ移動 |
|
122
|
|
|
try { |
|
123
|
1 |
|
$Layout = $this->layoutRepository->createQueryBuilder('l') |
|
124
|
1 |
|
->select('l, bp, b') |
|
125
|
1 |
|
->leftJoin('l.BlockPositions', 'bp') |
|
126
|
1 |
|
->leftJoin('bp.Block', 'b') |
|
127
|
1 |
|
->where('l.id = :layout_id') |
|
128
|
1 |
|
->orderBy('bp.block_row', 'ASC') |
|
129
|
1 |
|
->setParameter('layout_id', $id) |
|
130
|
1 |
|
->getQuery() |
|
131
|
1 |
|
->getSingleResult(); |
|
132
|
|
|
} catch (NoResultException $e) { |
|
133
|
|
|
throw new NotFoundHttpException(); |
|
134
|
|
|
} |
|
135
|
|
|
} |
|
136
|
|
|
|
|
137
|
|
|
// todo レポジトリへ移動 |
|
138
|
|
|
// 未使用ブロックの取得 |
|
139
|
2 |
|
$Blocks = $Layout->getBlocks(); |
|
140
|
2 |
|
if (empty($Blocks)) { |
|
141
|
1 |
|
$UnusedBlocks = $this->blockRepository->findAll(); |
|
142
|
|
|
} else { |
|
143
|
1 |
|
$UnusedBlocks = $this->blockRepository |
|
144
|
1 |
|
->createQueryBuilder('b') |
|
145
|
1 |
|
->select('b') |
|
146
|
1 |
|
->where('b not in (:blocks)') |
|
147
|
1 |
|
->setParameter('blocks', $Blocks) |
|
148
|
1 |
|
->getQuery() |
|
149
|
1 |
|
->getResult(); |
|
150
|
|
|
} |
|
151
|
|
|
|
|
152
|
2 |
|
$builder = $this->formFactory->createBuilder(FormType::class, $Layout); |
|
153
|
|
|
$builder |
|
154
|
2 |
|
->add( |
|
155
|
2 |
|
'name', |
|
156
|
2 |
|
TextType::class, |
|
157
|
|
|
[ |
|
158
|
2 |
|
'constraints' => [ |
|
159
|
2 |
|
new NotBlank(), |
|
160
|
|
|
], |
|
161
|
|
|
'required' => false, |
|
162
|
2 |
|
'label' => trans('layout.label'), |
|
163
|
|
|
] |
|
164
|
2 |
|
)->add( |
|
165
|
2 |
|
'DeviceType', |
|
166
|
2 |
|
DeviceTypeType::class, |
|
167
|
|
|
[ |
|
168
|
2 |
|
'constraints' => [ |
|
169
|
2 |
|
new NotBlank(), |
|
170
|
|
|
], |
|
171
|
|
|
'required' => false, |
|
172
|
|
|
] |
|
173
|
|
|
); |
|
174
|
|
|
|
|
175
|
2 |
|
$form = $builder->getForm(); |
|
176
|
2 |
|
$form->handleRequest($request); |
|
177
|
|
|
|
|
178
|
2 |
|
if ($form->isSubmitted() && $form->isValid()) { |
|
179
|
|
|
// Layoutの更新 |
|
180
|
1 |
|
$Layout = $form->getData(); |
|
181
|
1 |
|
$this->entityManager->persist($Layout); |
|
182
|
1 |
|
$this->entityManager->flush($Layout); |
|
|
|
|
|
|
183
|
|
|
|
|
184
|
|
|
// BlockPositionの更新 |
|
185
|
|
|
// delete/insertのため、一度削除する. |
|
186
|
1 |
|
$BlockPositions = $Layout->getBlockPositions(); |
|
187
|
1 |
|
foreach ($BlockPositions as $BlockPosition) { |
|
188
|
1 |
|
$Layout->removeBlockPosition($BlockPosition); |
|
189
|
1 |
|
$this->entityManager->remove($BlockPosition); |
|
190
|
1 |
|
$this->entityManager->flush($BlockPosition); |
|
|
|
|
|
|
191
|
|
|
} |
|
192
|
|
|
|
|
193
|
|
|
// ブロックの個数分登録を行う. |
|
194
|
1 |
|
$max = count($Blocks) + count($UnusedBlocks); |
|
195
|
1 |
|
$data = $request->request->all(); |
|
196
|
1 |
|
for ($i = 0; $i < $max; $i++) { |
|
197
|
|
|
// block_idが取得できない場合はinsertしない |
|
198
|
1 |
|
if (!isset($data['block_id_'.$i])) { |
|
199
|
1 |
|
continue; |
|
200
|
|
|
} |
|
201
|
|
|
// 未使用ブロックはinsertしない |
|
202
|
1 |
|
if ($data['section_'.$i] == \Eccube\Entity\Page::TARGET_ID_UNUSED) { |
|
203
|
|
|
continue; |
|
204
|
|
|
} |
|
205
|
1 |
|
$Block = $this->blockRepository->find($data['block_id_'.$i]); |
|
206
|
1 |
|
$BlockPosition = new BlockPosition(); |
|
207
|
|
|
$BlockPosition |
|
208
|
1 |
|
->setBlockId($data['block_id_'.$i]) |
|
209
|
1 |
|
->setLayoutId($Layout->getId()) |
|
210
|
1 |
|
->setBlockRow($data['block_row_'.$i]) |
|
211
|
1 |
|
->setSection($data['section_'.$i]) |
|
212
|
1 |
|
->setBlock($Block) |
|
|
|
|
|
|
213
|
1 |
|
->setLayout($Layout); |
|
214
|
1 |
|
$Layout->addBlockPosition($BlockPosition); |
|
215
|
1 |
|
$this->entityManager->persist($BlockPosition); |
|
216
|
1 |
|
$this->entityManager->flush($BlockPosition); |
|
|
|
|
|
|
217
|
|
|
} |
|
218
|
|
|
|
|
219
|
1 |
|
$this->addSuccess('admin.register.complete', 'admin'); |
|
220
|
|
|
|
|
221
|
1 |
|
return $this->redirectToRoute('admin_content_layout_edit', ['id' => $Layout->getId()]); |
|
222
|
|
|
} |
|
223
|
|
|
|
|
224
|
|
|
return [ |
|
225
|
1 |
|
'form' => $form->createView(), |
|
226
|
1 |
|
'Layout' => $Layout, |
|
227
|
1 |
|
'UnusedBlocks' => $UnusedBlocks, |
|
228
|
|
|
]; |
|
229
|
|
|
} |
|
230
|
|
|
|
|
231
|
|
|
/** |
|
232
|
|
|
* @Method("GET") |
|
233
|
|
|
* @Route("/%eccube_admin_route%/content/layout/view_block", name="admin_content_layout_view_block") |
|
234
|
|
|
* |
|
235
|
|
|
* @param Request $request |
|
236
|
|
|
* @param Twig $twig |
|
237
|
|
|
* |
|
238
|
|
|
* @return JsonResponse |
|
239
|
|
|
*/ |
|
240
|
|
|
public function viewBlock(Request $request, Twig $twig) |
|
241
|
|
|
{ |
|
242
|
|
|
if (!$request->isXmlHttpRequest()) { |
|
243
|
|
|
throw new BadRequestHttpException(); |
|
244
|
|
|
} |
|
245
|
|
|
|
|
246
|
|
|
$id = $request->get('id'); |
|
247
|
|
|
|
|
248
|
|
|
if (is_null($id)) { |
|
249
|
|
|
throw new BadRequestHttpException(); |
|
250
|
|
|
} |
|
251
|
|
|
|
|
252
|
|
|
$Block = $this->blockRepository->find($id); |
|
253
|
|
|
|
|
254
|
|
|
if (null === $Block) { |
|
255
|
|
|
throw new NotFoundHttpException(); |
|
256
|
|
|
} |
|
257
|
|
|
|
|
258
|
|
|
$source = $twig->getLoader() |
|
259
|
|
|
->getSourceContext('Block/'.$Block->getFileName().'.twig') |
|
260
|
|
|
->getCode(); |
|
261
|
|
|
|
|
262
|
|
|
return $this->json([ |
|
263
|
|
|
'id' => $Block->getId(), |
|
264
|
|
|
'source' => $source, |
|
265
|
|
|
]); |
|
266
|
|
|
} |
|
267
|
|
|
} |
|
268
|
|
|
|
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.
If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.
In this case you can add the
@ignorePhpDoc annotation to the duplicate definition and it will be ignored.