Completed
Push — master ( 80f2c6...3ec183 )
by Laurent
03:15
created

AbstractController::setOrder()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 6
rs 9.4285
cc 1
eloc 3
nc 1
nop 4
1
<?php
2
/**
3
 * AbstractController controller des méthodes communes.
4
 *
5
 * PHP Version 5
6
 *
7
 * @author    Quétier Laurent <[email protected]>
8
 * @copyright 2014 Dev-Int GLSR
9
 * @license   http://opensource.org/licenses/gpl-license.php GNU Public License
10
 *
11
 * @version since 1.0.0
12
 *
13
 * @link      https://github.com/Dev-Int/glsr
14
 */
15
namespace AppBundle\Controller;
16
17
use Symfony\Component\HttpFoundation\Request;
18
use Symfony\Component\HttpFoundation\Session\Session;
19
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
20
use Doctrine\ORM\QueryBuilder;
21
22
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
23
24
/**
25
 * Abstract controller.
26
 *
27
 * @category Controller
28
 */
29
abstract class AbstractController extends Controller
30
{
31
    /**
32
     * Lists all items entity.
33
     *
34
     * @param string $entityName Name of Entity
35
     * @param \Symfony\Component\HttpFoundation\Request $request Sort request
36
     * @return array
37
     */
38
    public function abstractIndexAction($entityName, Request $request = null)
39
    {
40
        $etm = $this->getDoctrine()->getManager();
41
        $paginator = '';
42
        $entities = $this->getEntity($entityName, $etm);
43
        
44
        if ($request !== null) {
45
            $item = $this->container->getParameter('knp_paginator.page_range');
46
            $this->addQueryBuilderSort($entities, strtolower($entityName));
47
            $paginator = $this->get('knp_paginator')->paginate($entities, $request->query->get('page', 1), $item);
48
        }
49
50
        return array('entities'  => $entities, 'ctEntity' => count($entities), 'paginator' => $paginator,);
51
    }
52
53
    /**
54
     * Get the entity
55
     *
56
     * @param string $entityName Name of Entity
57
     * @param \Doctrine\Common\Persistence\ObjectManager $etm ObjectManager instances
58
     * @return type
59
     */
60
    protected function getEntity($entityName, $etm)
61
    {
62
        $roles = ['ROLE_ADMIN', 'ROLE_SUPER_ADMIN'];
63
        switch ($entityName) {
64
            case 'Article':
65
                if($this->getUser() !== null && in_array($this->getUser()->getRoles()[0], $roles)) {
66
                    $entities = $etm->getRepository('AppBundle:'.$entityName)->getAllArticles();
67
                } else {
68
                    $entities = $etm->getRepository('AppBundle:'.$entityName)->getArticles();
69
                }
70
                break;
71
            case 'Supplier':
72
                $entities = $etm->getRepository('AppBundle:'.$entityName)->getSuppliers();
73
                break;
74
            case 'User':
75
                $entities = $etm->getRepository('AppBundle:'.$entityName)->getUsers();
76
                break;
77
            case 'FamilyLog':
78
                $entities = $etm->getRepository('AppBundle:'.$entityName)->childrenHierarchy();
79
                break;
80
            case 'UnitStorage':
81
                $entities = $etm->getRepository('AppBundle:'.$entityName)->createQueryBuilder('u');
82
                break;
83
            default:
84
                $entities = $etm->getRepository('AppBundle:'.$entityName)->findAll();
85
        }
86
        return $entities;
87
    }
88
89
    /**
90
     * Finds and displays an item entity.
91
     *
92
     * @param Object $entity     Entity
93
     * @param string $entityName Name of Entity
94
     * @return array
95
     */
96
    public function abstractShowAction($entity, $entityName)
97
    {
98
        $deleteForm = $this->createDeleteForm($entity->getId(), $entityName.'_delete');
99
100
        return array(
101
            $entityName => $entity,
102
            'delete_form' => $deleteForm->createView(),
103
        );
104
    }
105
106
    /**
107
     * Displays a form to create a new item entity.
108
     *
109
     * @param string      $entity     Entity
110
     * @param string      $entityPath Path of Entity
111
     * @param string      $typePath   Path of FormType
112
     * @param string|null $options    Options of Form
113
     * @return array
114
     */
115
    public function abstractNewAction($entity, $entityPath, $typePath, $options = null)
116
    {
117
        $etm = $this->getDoctrine()->getManager();
118
        $ctEntity = count($etm->getRepository('AppBundle:'.$entity)->findAll());
119
        
120
        if ($entity === 'Company' || $entity === 'Settings' && $ctEntity >= 1) {
121
            $return = $this->redirectToRoute('_home');
122
            $this->addFlash('danger', 'gestock.settings.'.strtolower($entity).'.add2');
123
        }
124
125
        $entityNew = $etm->getClassMetadata($entityPath)->newInstance();
126
        if ($entity === 'User') {
127
            $form = $this->createForm($typePath, $entityNew, array(
128
                'action' => $this->generateUrl(strtolower($entity).'_create'),
129
                'roles' => $options['roles'],
130
            ));
131
        } else {
132
            $form = $this->createForm($typePath, $entityNew, array(
133
                'action' => $this->generateUrl(strtolower($entity).'_create'),
134
            ));
135
        }
136
        $return = array(strtolower($entity) => $entityNew, 'form'   => $form->createView(),);
137
138
        return $return;
139
    }
140
141
    /**
142
     * Creates a new item entity.
143
     *
144
     * @param Request $request   Request in progress
145
     * @param string $entity     Entity <i>First letter Upper</i>
146
     * @param string $entityPath Path of Entity
147
     * @param string $typePath   Path of FormType
148
     * @return array
149
     */
150
    public function abstractCreateAction(Request $request, $entity, $entityPath, $typePath)
151
    {
152
        $param = array();
153
        $etm = $this->getDoctrine()->getManager();
154
        $entityNew = $etm->getClassMetadata($entityPath)->newInstance();
155
        $form = $this->createForm($typePath, $entityNew, array(
156
            'action' => $this->generateUrl(strtolower($entity).'_create'),
157
        ));
158
        $form->handleRequest($request);
159
        $return = [$entity => $entityNew, 'form' => $form->createView(),];
160
161
        if ($form->isValid()) {
162
            $etm = $this->getDoctrine()->getManager();
163
            $etm->persist($entityNew);
164
            $etm->flush();
165
            $this->addFlash('info', 'gestock.create.ok');
166
167
            $param = $this->testReturnParam($entityNew, strtolower($entity));
168
            $route = $form->get('addmore')->isClicked() ? strtolower($entity).'_new' : strtolower($entity).'_show';
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Symfony\Component\Form\FormInterface as the method isClicked() does only exist in the following implementations of said interface: Symfony\Component\Form\SubmitButton.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
169
170
            $return = $this->redirectToRoute($route, $param);
171
        }
172
173
        return $return;
174
    }
175
176
    /**
177
     * Displays a form to edit an existing item entity.
178
     *
179
     * @param Object $entity     Entity
180
     * @param string $entityName Name of Entity
181
     * @param string $typePath   Path of FormType
182
     * @return array
183
     */
184
    public function abstractEditAction($entity, $entityName, $typePath)
185
    {
186
        $param = $this->testReturnParam($entity, $entityName);
187
        $editForm = $this->createForm($typePath, $entity, array(
188
            'action' => $this->generateUrl($entityName.'_update', $param),
189
            'method' => 'PUT',
190
        ));
191
        if ($entityName === 'group') {
192
            $this->addRoles($editForm, $entity);
193
        }
194
        $deleteForm = $this->createDeleteForm($entity->getId(), $entityName.'_delete');
195
196
        return array(
197
            $entityName => $entity,
198
            'edit_form'   => $editForm->createView(),
199
            'delete_form' => $deleteForm->createView(),
200
        );
201
    }
202
203
    /**
204
     * Edits an existing item entity.
205
     *
206
     * @param Object $entity     Entity
207
     * @param Request $request   Request in progress
208
     * @param string $entityName Name of Entity
209
     * @param string $typePath   Path of FormType
210
     * @return array
211
     */
212
    public function abstractUpdateAction($entity, Request $request, $entityName, $typePath)
213
    {
214
        $param = $this->testReturnParam($entity, $entityName);
215
        $editForm = $this->createForm($typePath, $entity, array(
216
            'action' => $this->generateUrl($entityName.'_update', $param),
217
            'method' => 'PUT',
218
        ));
219
        if ($entityName === 'group') {
220
            $this->addRoles($editForm, $entity);
221
        }
222
223
        $deleteForm = $this->createDeleteForm($entity->getId(), $entityName.'_delete');
224
225
        $return = array(
226
            $entityName => $entity,
227
            'edit_form'   => $editForm->createView(),
228
            'delete_form' => $deleteForm->createView(),
229
        );
230
231
        if ($editForm->handleRequest($request)->isValid()) {
232
            $this->getDoctrine()->getManager()->flush();
233
            $this->addFlash('info', 'gestock.edit.ok');
234
235
            $return = $this->redirectToRoute($entityName.'_edit', $param);
236
        }
237
238
        return $return;
239
    }
240
241
    /**
242
     * Deletes an item entity.
243
     *
244
     * @param Object $entity     Entity
245
     * @param Request $request   Request in progress
246
     * @param string $entityName Name of Entity
247
     * @return array
248
     */
249
    public function abstractDeleteAction($entity, Request $request, $entityName)
250
    {
251
        $form = $this->createDeleteForm($entity->getId(), $entityName.'_delete');
252
        if ($form->handleRequest($request)->isValid()) {
253
            $etm = $this->getDoctrine()->getManager();
254
            $etm->remove($entity);
255
            $etm->flush();
256
        }
257
    }
258
259
    private function testReturnParam($entity, $entityName)
260
    {
261
        $entityArray = ['company', 'settings', 'group', 'tva'];
262
        if (in_array($entityName, $entityArray, true)) {
263
            $param = array('id' => $entity->getId());
264
        } else {
265
            $param = array('slug' => $entity->getSlug());
266
        }
267
268
        return $param;
269
    }
270
271
    /**
272
     * SetOrder for the SortAction in views.
273
     *
274
     * @param string $name   session name
275
     * @param string $entity entity name
276
     * @param string $field  field name
277
     * @param string $type   sort type ("ASC"/"DESC")
278
     */
279
    protected function setOrder($name, $entity, $field, $type = 'ASC')
280
    {
281
        $session = new Session();
282
283
        $session->set('sort.'.$name, array('entity' => $entity, 'field' => $field, 'type' => $type));
284
    }
285
286
    /**
287
     * GetOrder for the SortAction in views.
288
     *
289
     * @param string $name session name
290
     *
291
     * @return array
292
     */
293
    protected function getOrder($name)
294
    {
295
        $session = new Session();
296
297
        return $session->has('sort.' . $name) ? $session->get('sort.' . $name) : null;
298
    }
299
300
    /**
301
     * AddQueryBuilderSort for the SortAction in views.
302
     *
303
     * @param QueryBuilder $qbd
304
     * @param string       $name
305
     */
306
    protected function addQueryBuilderSort(QueryBuilder $qbd, $name)
307
    {
308
        $alias = '';
309
        if (is_array($order = $this->getOrder($name))) {
310
            if ($name !== $order['entity']) {
311
                $rootAlias = current($qbd->getDQLPart('from'))->getAlias();
312
                $join = current($qbd->getDQLPart('join'));
313
                foreach ($join as $item) {
314
                    if ($item->getJoin() === $rootAlias.'.'.$order['entity']) {
315
                        $alias = $item->getAlias();
316
                    }
317
                }
318
            } else {
319
                $alias = current($qbd->getDQLPart('from'))->getAlias();
320
            }
321
            $qbd->orderBy($alias . '.' . $order['field'], $order['type']);
322
        }
323
    }
324
325
    /**
326
     * Create Delete form.
327
     *
328
     * @param int    $id
329
     * @param string $route
330
     *
331
     * @return \Symfony\Component\Form\Form
332
     */
333
    protected function createDeleteForm($id, $route)
334
    {
335
        return $this->createFormBuilder(null, array('attr' => array('id' => 'delete')))
336
            ->setAction($this->generateUrl($route, array('id' => $id)))
337
            ->setMethod('DELETE')
338
            ->getForm()
339
        ;
340
    }
341
342
    /**
343
     * Array of file (`pdf`) layout.
344
     *
345
     * @param string $date File date
346
     * @param string $title File title
347
     * @return array<string,integer|string|boolean>
348
     */
349
    protected function getArray($date, $title)
350
    {
351
        $array = array(
352
            'margin-top' => 15,
353
            'header-spacing' => 5,
354
            'header-font-size' => 8,
355
            'header-left' => 'G.L.S.R.',
356
            'header-center' => $title,
357
            'header-right' => $date,
358
            'header-line' => true,
359
            'margin-bottom' => 15,
360
            'footer-spacing' => 5,
361
            'footer-font-size' => 8,
362
            'footer-left' => 'GLSR &copy 2014 and beyond.',
363
            'footer-right' => 'Page [page]/[toPage]',
364
            'footer-line' => true,
365
        );
366
        return $array;
367
    }
368
369
    /**
370
     * Get the existing roles
371
     *
372
     * @return array Array of roles
373
     */
374
    private function getExistingRoles()
375
    {
376
        $roleHierarchy = $this->container->getParameter('security.role_hierarchy.roles');
377
        $roles = array_keys($roleHierarchy);
378
        $theRoles = array();
379
380
        foreach ($roles as $role) {
381
            $theRoles[$role] = $role;
382
        }
383
        return $theRoles;
384
    }
385
386
    /**
387
     * Add roles to form
388
     *
389
     * @param \Symfony\Component\Form\Form  $form  The form in which to insert the roles
390
     * @param \AppBundle\Entity\Group       $group The entity to deal
391
     * @return \Symfony\Component\Form\Form The form
392
     */
393
    private function addRoles($form, $group)
394
    {
395
        $form->add('roles', ChoiceType::class, array(
396
            'choices' => $this->getExistingRoles(),
397
            'choices_as_values' => true,
398
            'data' => $group->getRoles(),
399
            'label' => 'Roles',
400
            'expanded' => true,
401
            'multiple' => true,
402
            'mapped' => true,
403
        ));
404
405
        return $form;
406
    }
407
}
408