Completed
Push — master ( d23e95...bd2a27 )
by Laurent
04:21
created

AbstractController::getOrder()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 6
rs 9.4285
cc 2
eloc 3
nc 2
nop 1
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
/**
23
 * Abstract controller.
24
 *
25
 * @category Controller
26
 */
27
abstract class AbstractController extends Controller
28
{
29
    /**
30
     * Lists all items entity.
31
     *
32
     * @param string $entityName Name of Entity
33
     * @param \Symfony\Component\HttpFoundation\Request $request Sort request
34
     * @return array
35
     */
36
    public function abstractIndexAction($entityName, Request $request = null)
37
    {
38
        $etm = $this->getDoctrine()->getManager();
39
        $paginator = '';
40
        switch ($entityName) {
41
            case 'Article': 
42
                $entities = $etm->getRepository('AppBundle:'.$entityName)->getArticles();
43
                break;
44
            case 'Supplier':
45
                $entities = $etm->getRepository('AppBundle:'.$entityName)->getSuppliers();
46
                break;
47
            case 'User':
48
                $entities = $etm->getRepository('AppBundle:'.$entityName)->getUsers();
49
                break;
50
            case 'FamilyLog':
51
                $entities = $etm->getRepository('AppBundle:'.$entityName)->childrenHierarchy();
52
                break;
53
            case 'UnitStorage':
54
                $entities = $etm->getRepository('AppBundle:'.$entityName)->createQueryBuilder('u');
55
                break;
56
            default:
57
                $entities = $etm->getRepository('AppBundle:'.$entityName)->findAll();
58
        }
59
        if ($request !== null) {
60
            $item = $this->container->getParameter('knp_paginator.page_range');
61
            $this->addQueryBuilderSort($entities, strtolower($entityName));
62
            $paginator = $this->get('knp_paginator')->paginate($entities, $request->query->get('page', 1), $item);
63
        }
64
65
        return array('entities'  => $entities, 'ctEntity' => count($entities), 'paginator' => $paginator,);
66
    }
67
68
    /**
69
     * Finds and displays an item entity.
70
     *
71
     * @param Object $entity     Entity
72
     * @param string $entityName Name of Entity
73
     * @return array
74
     */
75
    public function abstractShowAction($entity, $entityName)
76
    {
77
        $deleteForm = $this->createDeleteForm($entity->getId(), $entityName.'_delete');
78
79
        return array(
80
            $entityName => $entity,
81
            'delete_form' => $deleteForm->createView(),
82
        );
83
    }
84
85
    /**
86
     * Displays a form to create a new item entity.
87
     *
88
     * @param string $entity     Entity
89
     * @param string $entityPath Path of Entity
90
     * @param string $typePath   Path of FormType
91
     * @return array
92
     */
93
    public function abstractNewAction($entity, $entityPath, $typePath)
94
    {
95
        $etm = $this->getDoctrine()->getManager();
96
        $ctEntity = count($etm->getRepository('AppBundle:'.$entity)->findAll());
97
        
98
        if ($entity === 'Company' || $entity === 'Settings' && $ctEntity >= 1) {
99
            $return = $this->redirectToRoute('_home');
100
            $this->addFlash('danger', 'gestock.settings.'.strtolower($entity).'.add2');
101
        }
102
103
        $entityNew = $etm->getClassMetadata($entityPath)->newInstance();
104
        $form = $this->createForm(new $typePath(), $entityNew, array(
105
            'action' => $this->generateUrl(strtolower($entity).'_create'),
106
        ));
107
108
        $return = array(strtolower($entity) => $entityNew, 'form'   => $form->createView(),);
109
110
        return $return;
111
    }
112
113
    /**
114
     * Creates a new item entity.
115
     *
116
     * @param Request $request   Request in progress
117
     * @param string $entity     Entity <i>First letter Upper</i>
118
     * @param string $entityPath Path of Entity
119
     * @param string $typePath   Path of FormType
120
     * @return array
121
     */
122
    public function abstractCreateAction(Request $request, $entity, $entityPath, $typePath)
123
    {
124
        $param = array();
125
        $etm = $this->getDoctrine()->getManager();
126
        $entityNew = $etm->getClassMetadata($entityPath)->newInstance();
127
        $form = $this->createForm(new $typePath(), $entityNew, array(
128
            'action' => $this->generateUrl(strtolower($entity).'_create'),
129
        ));
130
131
        if ($form->handleRequest($request)->isValid()) {
132
            $etm = $this->getDoctrine()->getManager();
133
            $etm->persist($entityNew);
134
            $etm->flush();
135
            $this->addFlash('info', 'gestock.create.ok');
136
137
            $param = $this->testReturnParam($entityNew, strtolower($entity));
138
            $return = $form->get('addmore')->isClicked() ? $entity.'_new' : $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...
139
140
            return $this->redirectToRoute($return, $param);
141
        }
142
143
        return array($entity => $entityNew, 'form' => $form->createView(),);
144
    }
145
146
    /**
147
     * Displays a form to edit an existing item entity.
148
     *
149
     * @param Object $entity     Entity
150
     * @param string $entityName Name of Entity
151
     * @param string $typePath   Path of FormType
152
     * @return array
153
     */
154
    public function abstractEditAction($entity, $entityName, $typePath)
155
    {
156
        $param = $this->testReturnParam($entity, $entityName);
157
        $editForm = $this->createForm(new $typePath(), $entity, array(
158
            'action' => $this->generateUrl($entityName.'_update', $param),
159
            'method' => 'PUT',
160
        ));
161
        $deleteForm = $this->createDeleteForm($entity->getId(), $entityName.'_delete');
162
163
        return array(
164
            $entityName => $entity,
165
            'edit_form'   => $editForm->createView(),
166
            'delete_form' => $deleteForm->createView(),
167
        );
168
    }
169
170
    /**
171
     * Edits an existing item entity.
172
     *
173
     * @param Object $entity     Entity
174
     * @param Request $request   Request in progress
175
     * @param string $entityName Name of Entity
176
     * @param string $typePath   Path of FormType
177
     * @return array
178
     */
179
    public function abstractUpdateAction($entity, Request $request, $entityName, $typePath)
180
    {
181
        $param = $this->testReturnParam($entity, $entityName);
182
        $editForm = $this->createForm(new $typePath(), $entity, array(
183
            'action' => $this->generateUrl($entityName.'_update', $param),
184
            'method' => 'PUT',
185
        ));
186
        if ($editForm->handleRequest($request)->isValid()) {
187
            $this->getDoctrine()->getManager()->flush();
188
            $this->addFlash('info', 'gestock.edit.ok');
189
190
            return $this->redirectToRoute($entityName.'_edit', $param);
191
        }
192
        $deleteForm = $this->createDeleteForm($entity->getId(), $entityName.'_delete');
193
194
        return array(
195
            $entityName => $entity,
196
            'edit_form'   => $editForm->createView(),
197
            'delete_form' => $deleteForm->createView(),
198
        );
199
    }
200
201
    /**
202
     * Deletes an item entity.
203
     *
204
     * @param Object $entity     Entity
205
     * @param Request $request   Request in progress
206
     * @param string $entityName Name of Entity
207
     * @return array
208
     */
209
    public function abstractDeleteAction($entity, Request $request, $entityName)
210
    {
211
        $form = $this->createDeleteForm($entity->getId(), $entityName.'_delete');
212
        if ($form->handleRequest($request)->isValid()) {
213
            $etm = $this->getDoctrine()->getManager();
214
            $etm->remove($entity);
215
            $etm->flush();
216
        }
217
    }
218
219
    private function testReturnParam($entity, $entityName)
220
    {
221
        if ($entityName === 'company' || $entityName === 'settings' || $entityName === 'tva') {
222
            $param = array('id' => $entity->getId());
223
        } else {
224
            $param = array('slug' => $entity->getSlug());
225
        }
226
227
        return $param;
228
    }
229
    /**
230
     * SetOrder for the SortAction in views.
231
     *
232
     * @param string $name   session name
233
     * @param string $entity entity name
234
     * @param string $field  field name
235
     * @param string $type   sort type ("ASC"/"DESC")
236
     */
237
    protected function setOrder($name, $entity, $field, $type = 'ASC')
238
    {
239
        $session = new Session();
240
241
        $session->set('sort.'.$name, array('entity' => $entity, 'field' => $field, 'type' => $type));
242
    }
243
244
    /**
245
     * GetOrder for the SortAction in views.
246
     *
247
     * @param string $name session name
248
     *
249
     * @return array
250
     */
251
    protected function getOrder($name)
252
    {
253
        $session = new Session();
254
255
        return $session->has('sort.' . $name) ? $session->get('sort.' . $name) : null;
256
    }
257
258
    /**
259
     * AddQueryBuilderSort for the SortAction in views.
260
     *
261
     * @param QueryBuilder $qbd
262
     * @param string       $name
263
     */
264
    protected function addQueryBuilderSort(QueryBuilder $qbd, $name)
265
    {
266
        $alias = '';
267
        if (is_array($order = $this->getOrder($name))) {
268
            if ($name !== $order['entity']) {
269
                $rootAlias = current($qbd->getDQLPart('from'))->getAlias();
270
                $join = current($qbd->getDQLPart('join'));
271
                foreach ($join as $item) {
272
                    if ($item->getJoin() === $rootAlias.'.'.$order['entity']) {
273
                        $alias = $item->getAlias();
274
                    }
275
                }
276
            } else {
277
                $alias = current($qbd->getDQLPart('from'))->getAlias();
278
            }
279
            $qbd->orderBy($alias . '.' . $order['field'], $order['type']);
280
        }
281
    }
282
283
    /**
284
     * Create Delete form.
285
     *
286
     * @param int    $id
287
     * @param string $route
288
     *
289
     * @return \Symfony\Component\Form\Form
290
     */
291
    protected function createDeleteForm($id, $route)
292
    {
293
        return $this->createFormBuilder(null, array('attr' => array('id' => 'delete')))
294
            ->setAction($this->generateUrl($route, array('id' => $id)))
295
            ->setMethod('DELETE')
296
            ->getForm()
297
        ;
298
    }
299
300
    /**
301
     * Testing the installation inventory.
302
     *
303
     * @return string|null
304
     */
305
    protected function testInventory()
306
    {
307
        $url = null;
308
        $etm = $this->getDoctrine()->getManager();
309
        $inventories = $etm->getRepository('AppBundle:Inventory')->getInventory();
310
311
        if (empty($inventories)) {
312
            $url = 'gs_install_st7';
313
        } else {
314
            foreach ($inventories as $inventory) {
315
                if ($inventory->getstatus() === 1 || $inventory->getStatus() === 2) {
316
                    $message = $this->get('translator')
317
                        ->trans('yet', array(), 'gs_inventories');
318
                    $this->addFlash('danger', $message);
319
                    $url = 'inventory';
320
                    break;
321
                }
322
            }
323
        }
324
325
        return $url;
326
    }
327
328
    /**
329
     * Array of file (`pdf`) layout.
330
     *
331
     * @param string $date File date
332
     * @param string $title Tile title
333
     * @return array<string,integer|string|boolean>
334
     */
335
    protected function getArray($date, $title)
336
    {
337
        $array = array(
338
            'margin-top' => 15,
339
            'header-spacing' => 5,
340
            'header-font-size' => 8,
341
            'header-left' => 'G.L.S.R.',
342
            'header-center' => $title,
343
            'header-right' => $date,
344
            'header-line' => true,
345
            'margin-bottom' => 15,
346
            'footer-spacing' => 5,
347
            'footer-font-size' => 8,
348
            'footer-left' => 'GLSR &copy 2014 and beyond.',
349
            'footer-right' => 'Page [page]/[toPage]',
350
            'footer-line' => true,
351
        );
352
        return $array;
353
    }
354
}
355