Completed
Push — master ( 7c7b22...3f9c93 )
by Laurent
04:22
created

AbstractController::abstractCreateAction()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 23
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 7
Bugs 1 Features 0
Metric Value
c 7
b 1
f 0
dl 0
loc 23
rs 9.0856
cc 3
eloc 15
nc 3
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
/**
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
     * @return array
34
     */
35
    public function abstractIndexAction($entityName)
36
    {
37
        $etm = $this->getDoctrine()->getManager();
38
        $entities = $etm->getRepository('AppBundle:'.$entityName)->findAll();
39
40
        return array(
41
            'entities'  => $entities,
42
            'ctEntity' => count($entities),
43
        );
44
    }
45
46
    /**
47
     * Finds and displays an item entity.
48
     *
49
     * @param Object $entity     Entity
50
     * @param string $entityName Name of Entity
51
     * @return array
52
     */
53
    public function abstractShowAction($entity, $entityName)
54
    {
55
        $deleteForm = $this->createDeleteForm($entity->getId(), $entityName.'_delete');
56
57
        return array(
58
            $entityName => $entity,
59
            'delete_form' => $deleteForm->createView(),
60
        );
61
    }
62
63
    /**
64
     * Displays a form to create a new item entity.
65
     *
66
     * @param string $entity     Entity
67
     * @param string $entityPath Path of Entity
68
     * @param string $typePath   Path of FormType
69
     * @return array
70
     */
71
    public function abstractNewAction($entity, $entityPath, $typePath)
72
    {
73
        $etm = $this->getDoctrine()->getManager();
74
        $ctEntity = count($etm->getRepository('AppBundle:'.$entity)->findAll());
75
        
76
        if ($entity === 'Company' || $entity === 'Settings' && $ctEntity >= 1) {
77
            $return = $this->redirectToRoute('_home');
1 ignored issue
show
Unused Code introduced by
$return is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
78
            $this->addFlash('danger', 'gestock.settings.'.strtolower($entity).'.add2');
79
        }
80
81
        $entityNew = $etm->getClassMetadata($entityPath)->newInstance();
82
        $form = $this->createForm(new $typePath(), $entityNew, array(
83
            'action' => $this->generateUrl(strtolower($entity).'_create'),
84
        ));
85
86
        $return = array(strtolower($entity) => $entityNew, 'form'   => $form->createView(),);
87
88
        return $return;
89
    }
90
91
    /**
92
     * Creates a new item entity.
93
     *
94
     * @param Request $request   Request in progress
95
     * @param string $entity     Entity <i>First letter Upper</i>
96
     * @param string $entityPath Path of Entity
97
     * @param string $typePath   Path of FormType
98
     * @return array
99
     */
100
    public function abstractCreateAction(Request $request, $entity, $entityPath, $typePath)
101
    {
102
        $param = array();
1 ignored issue
show
Unused Code introduced by
$param is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
103
        $etm = $this->getDoctrine()->getManager();
104
        $entityNew = $etm->getClassMetadata($entityPath)->newInstance();
105
        $form = $this->createForm(new $typePath(), $entityNew, array(
106
            'action' => $this->generateUrl(strtolower($entity).'_create'),
107
        ));
108
109
        if ($form->handleRequest($request)->isValid()) {
110
            $etm = $this->getDoctrine()->getManager();
111
            $etm->persist($entityNew);
112
            $etm->flush();
113
            $this->addFlash('info', 'gestock.create.ok');
114
115
            $param = $this->testReturnParam($entityNew, strtolower($entity));
116
            $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...
117
118
            return $this->redirectToRoute($return, $param);
119
        }
120
121
        return array($entity => $entityNew, 'form' => $form->createView(),);
122
    }
123
124
    /**
125
     * Displays a form to edit an existing item entity.
126
     *
127
     * @param Object $entity     Entity
128
     * @param string $entityName Name of Entity
129
     * @param string $typePath   Path of FormType
130
     * @return array
131
     */
132
    public function abstractEditAction($entity, $entityName, $typePath)
133
    {
134
        $param = $this->testReturnParam($entity, $entityName);
135
        $editForm = $this->createForm(new $typePath(), $entity, array(
136
            'action' => $this->generateUrl($entityName.'_update', $param),
137
            'method' => 'PUT',
138
        ));
139
        $deleteForm = $this->createDeleteForm($entity->getId(), $entityName.'_delete');
140
141
        return array(
142
            $entityName => $entity,
143
            'edit_form'   => $editForm->createView(),
144
            'delete_form' => $deleteForm->createView(),
145
        );
146
    }
147
148
    /**
149
     * Edits an existing item entity.
150
     *
151
     * @param Object $entity     Entity
152
     * @param Request $request   Request in progress
153
     * @param string $entityName Name of Entity
154
     * @param string $typePath   Path of FormType
155
     * @return array
156
     */
157
    public function abstractUpdateAction($entity, Request $request, $entityName, $typePath)
158
    {
159
        $param = $this->testReturnParam($entity, $entityName);
160
        $editForm = $this->createForm(new $typePath(), $entity, array(
161
            'action' => $this->generateUrl($entityName.'_update', $param),
162
            'method' => 'PUT',
163
        ));
164
        if ($editForm->handleRequest($request)->isValid()) {
165
            $this->getDoctrine()->getManager()->flush();
166
            $this->addFlash('info', 'gestock.edit.ok');
167
168
            return $this->redirectToRoute($entityName.'_edit', $param);
169
        }
170
        $deleteForm = $this->createDeleteForm($entity->getId(), $entityName.'_delete');
171
172
        return array(
173
            $entityName => $entity,
174
            'edit_form'   => $editForm->createView(),
175
            'delete_form' => $deleteForm->createView(),
176
        );
177
    }
178
179
    /**
180
     * Deletes an item entity.
181
     *
182
     * @param Object $entity     Entity
183
     * @param Request $request   Request in progress
184
     * @param string $entityName Name of Entity
185
     * @return array
186
     */
187
    public function abstractDeleteAction($entity, Request $request, $entityName)
188
    {
189
        $form = $this->createDeleteForm($entity->getId(), $entityName.'_delete');
190
        if ($form->handleRequest($request)->isValid()) {
191
            $etm = $this->getDoctrine()->getManager();
192
            $etm->remove($entity);
193
            $etm->flush();
194
        }
195
    }
196
197
    private function testReturnParam($entity, $entityName)
198
    {
199
        if ($entityName === 'company' || $entityName === 'settings' || $entityName === 'tva') {
200
            $param = array('id' => $entity->getId());
201
        } else {
202
            $param = array('slug' => $entity->getSlug());
203
        }
204
205
        return $param;
206
    }
207
    /**
208
     * SetOrder for the SortAction in views.
209
     *
210
     * @param string $name   session name
211
     * @param string $entity entity name
212
     * @param string $field  field name
213
     * @param string $type   sort type ("ASC"/"DESC")
214
     */
215
    protected function setOrder($name, $entity, $field, $type = 'ASC')
216
    {
217
        $session = new Session();
218
219
        $session->set('sort.'.$name, array(
220
            'entity' => $entity,
221
            'field' => $field,
222
            'type' => $type
223
        ));
224
    }
225
226
    /**
227
     * GetOrder for the SortAction in views.
228
     *
229
     * @param string $name session name
230
     *
231
     * @return array
232
     */
233
    protected function getOrder($name)
234
    {
235
        $session = new Session();
236
237
        return $session->has('sort.' . $name) ? $session->get('sort.' . $name) : null;
238
    }
239
240
    /**
241
     * AddQueryBuilderSort for the SortAction in views.
242
     *
243
     * @param QueryBuilder $qbd
244
     * @param string       $name
245
     */
246
    protected function addQueryBuilderSort(QueryBuilder $qbd, $name)
247
    {
248
        $alias = '';
249
        if (is_array($order = $this->getOrder($name))) {
250
            if ($name !== $order['entity']) {
251
                $rootAlias = current($qbd->getDQLPart('from'))->getAlias();
252
                $join = current($qbd->getDQLPart('join'));
253
                foreach ($join as $item) {
254
                    if ($item->getJoin() === $rootAlias.'.'.$order['entity']) {
255
                        $alias = $item->getAlias();
256
                    }
257
                }
258
            } else {
259
                $alias = current($qbd->getDQLPart('from'))->getAlias();
260
            }
261
            $qbd->orderBy($alias . '.' . $order['field'], $order['type']);
262
        }
263
    }
264
265
    /**
266
     * Create Delete form.
267
     *
268
     * @param int    $id
269
     * @param string $route
270
     *
271
     * @return \Symfony\Component\Form\Form
272
     */
273
    protected function createDeleteForm($id, $route)
274
    {
275
        return $this->createFormBuilder(null, array('attr' => array('id' => 'delete')))
276
            ->setAction($this->generateUrl($route, array('id' => $id)))
277
            ->setMethod('DELETE')
278
            ->getForm()
279
        ;
280
    }
281
282
    /**
283
     * Test Inventory.
284
     *
285
     * @return string|null
286
     */
287
    protected function testInventory()
288
    {
289
        $url = null;
290
        $etm = $this->getDoctrine()->getManager();
291
        $inventories = $etm->getRepository('AppBundle:Inventory')->getInventory();
292
293
        if (empty($inventories)) {
294
            $url = 'gs_install_st7';
295
        } else {
296
            foreach ($inventories as $inventory) {
297
                if ($inventory->getstatus() === 1 || $inventory->getStatus() === 2) {
298
                    $message = $this->get('translator')
299
                        ->trans('yet', array(), 'gs_inventories');
300
                    $this->addFlash('danger', $message);
301
                    $url = 'inventory';
302
                    break;
303
                }
304
            }
305
        }
306
307
        return $url;
308
    }
309
}
310