Completed
Push — master ( 6d6774...64f3ed )
by Jeroen
11:23 queued 05:13
created

NodeBundle/Controller/WidgetsController.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace Kunstmaan\NodeBundle\Controller;
4
5
use Doctrine\Common\Collections\ArrayCollection;
6
use Doctrine\ORM\EntityManagerInterface;
7
use Kunstmaan\AdminBundle\Helper\DomainConfigurationInterface;
8
use Kunstmaan\NodeBundle\Entity\Node;
9
use Kunstmaan\NodeBundle\Entity\NodeTranslation;
10
use Kunstmaan\NodeBundle\Entity\StructureNode;
11
use Symfony\Component\Routing\Annotation\Route;
12
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
13
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
14
use Symfony\Component\HttpFoundation\JsonResponse;
15
use Symfony\Component\HttpFoundation\Request;
16
17
/**
18
 * WidgetsController
19
 */
20
class WidgetsController extends Controller
21
{
22
    /**
23
     * @Route("/ckselecturl", name="KunstmaanNodeBundle_ckselecturl")
24
     * @Template("@KunstmaanNode/Widgets/selectLink.html.twig")
25
     *
26
     * @param \Symfony\Component\HttpFoundation\Request $request
27
     *
28
     * @return array
29
     */
30 View Code Duplication
    public function ckSelectLinkAction(Request $request)
31
    {
32
        $params = $this->getTemplateParameters($request);
33
        $params['cke'] = true;
34
        $params['multilanguage'] = $this->getParameter('kunstmaan_admin.multi_language');
35
36
        return $params;
37
    }
38
39
    /**
40
     * Select a link
41
     *
42
     * @Route("/selecturl", name="KunstmaanNodeBundle_selecturl")
43
     * @Template("@KunstmaanNode/Widgets/selectLink.html.twig")
44
     *
45
     * @param \Symfony\Component\HttpFoundation\Request $request
46
     *
47
     * @return array
48
     */
49 View Code Duplication
    public function selectLinkAction(Request $request)
50
    {
51
        $params = $this->getTemplateParameters($request);
52
        $params['cke'] = false;
53
        $params['multilanguage'] = $this->getParameter('kunstmaan_admin.multi_language');
54
55
        return $params;
56
    }
57
58
    /**
59
     * Select a link
60
     *
61
     * @Route("/select-nodes-lazy_search", name="KunstmaanNodeBundle_nodes_lazy_search")
62
     *
63
     * @param \Symfony\Component\HttpFoundation\Request $request
64
     *
65
     * @return JsonResponse
66
     */
67
    public function selectNodesLazySearch(Request $request)
68
    {
69
        @trigger_error(sprintf('The "%s" controller action is deprecated in KunstmaanNodeBundle 5.1 and will be removed in KunstmaanNodeBundle 6.0.', __METHOD__), E_USER_DEPRECATED);
70
71
        /* @var EntityManagerInterface $em */
72
        $em = $this->getDoctrine()->getManager();
73
        $locale = $request->getLocale();
74
        $search = $request->query->get('str');
75
76
        $results = [];
77
        if ($search) {
78
            $nts = $em->getRepository('KunstmaanNodeBundle:NodeTranslation')->getNodeTranslationsLikeTitle($search, $locale);
79
            /** @var NodeTranslation $nt */
80
            foreach ($nts as $nt) {
81
                $node = $nt->getNode();
82
                $results[] = $node->getId();
83
                while ($node->getParent()) {
84
                    $node = $node->getParent();
85
                    $results[] = $node->getId();
86
                }
87
            }
88
            $results = array_unique($results);
89
            sort($results);
90
        }
91
92
        return new JsonResponse($results);
93
    }
94
95
    /**
96
     * Select a link
97
     *
98
     * @Route("/select-nodes-lazy", name="KunstmaanNodeBundle_nodes_lazy")
99
     *
100
     * @param \Symfony\Component\HttpFoundation\Request $request
101
     *
102
     * @return JsonResponse
103
     */
104
    public function selectNodesLazy(Request $request)
105
    {
106
        /* @var EntityManagerInterface $em */
107
        $em = $this->getDoctrine()->getManager();
108
        $locale = $request->getLocale();
109
        $id = $request->query->get('id');
110
        $depth = $this->getParameter('kunstmaan_node.url_chooser.lazy_increment');
111
112
        if (!$id || $id == '#') {
113
            $domainConfig = $this->get('kunstmaan_admin.domain_configuration');
114
115
            if ($domainConfig->isMultiDomainHost()) {
116
                $switchedHost = $domainConfig->getHostSwitched();
117
                $rootItems = [$domainConfig->getRootNode($switchedHost['host'])];
118
            } else {
119
                $rootItems = $em->getRepository('KunstmaanNodeBundle:Node')->getAllTopNodes();
0 ignored issues
show
It seems like you code against a concrete implementation and not the interface Doctrine\Persistence\ObjectRepository as the method getAllTopNodes() does only exist in the following implementations of said interface: Kunstmaan\NodeBundle\Repository\NodeRepository.

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...
120
            }
121
        } else {
122
            $rootItems = $em->getRepository('KunstmaanNodeBundle:Node')->find($id)->getChildren();
123
        }
124
125
        $results = $this->nodesToArray($locale, $rootItems, $depth);
126
127
        return new JsonResponse($results);
128
    }
129
130
    /**
131
     * Get the parameters needed in the template. This is common for the
132
     * default link chooser and the cke link chooser.
133
     *
134
     * @param \Symfony\Component\HttpFoundation\Request $request
135
     *
136
     * @return array
137
     */
138
    private function getTemplateParameters(Request $request)
139
    {
140
        // When the media bundle is available, we show a link in the header to the media chooser
141
        $allBundles = $this->getParameter('kernel.bundles');
142
        $mediaChooserLink = null;
143
144
        if (\array_key_exists('KunstmaanMediaBundle', $allBundles)) {
145
            $params = ['linkChooser' => 1];
146
            $cKEditorFuncNum = $request->get('CKEditorFuncNum');
147
            if (!empty($cKEditorFuncNum)) {
148
                $params['CKEditorFuncNum'] = $cKEditorFuncNum;
149
            }
150
            $mediaChooserLink = $this->generateUrl(
151
                'KunstmaanMediaBundle_chooser',
152
                $params
153
            );
154
        }
155
156
        return [
157
            'mediaChooserLink' => $mediaChooserLink,
158
        ];
159
    }
160
161
    /**
162
     * Determine if current node is a structure node.
163
     *
164
     * @param string $refEntityName
165
     *
166
     * @return bool
167
     */
168
    protected function isStructureNode($refEntityName)
169
    {
170
        $structureNode = false;
171
        if (class_exists($refEntityName)) {
172
            $page = new $refEntityName();
173
            $structureNode = ($page instanceof StructureNode);
174
            unset($page);
175
        }
176
177
        return $structureNode;
178
    }
179
180
    /**
181
     * Determine if current node is a structure node.
182
     *
183
     * @param string                 $locale
184
     * @param Node[]|ArrayCollection $rootNodes
185
     * @param int                    $depth
186
     *
187
     * @return array
188
     */
189
    protected function nodesToArray($locale, $rootNodes, $depth = 2)
190
    {
191
        /** @var DomainConfigurationInterface $domainconfig */
192
        $domainconfig = $this->get('kunstmaan_admin.domain_configuration');
193
        $isMultiDomain = $domainconfig->isMultiDomainHost();
194
        $switchedHost = $domainconfig->getHostSwitched();
195
        $switched = null !== $switchedHost && array_key_exists('host', $switchedHost) && $domainconfig->getHost() === $switchedHost['host'];
196
197
        $results = [];
198
199
        /** @var Node $rootNode */
200
        foreach ($rootNodes as $rootNode) {
201
            if ($nodeTranslation = $rootNode->getNodeTranslation($locale, true)) {
202
                if ($isMultiDomain && !$switched) {
203
                    $slug = sprintf('[%s:%s]', $switchedHost['id'], 'NT'.$nodeTranslation->getId());
204
                } else {
205
                    $slug = sprintf('[%s]', 'NT'.$nodeTranslation->getId());
206
                }
207
208
                switch (true) {
209
                    case !$nodeTranslation->isOnline():
210
                        $type = 'offline';
211
212
                        break;
213
                    case $rootNode->isHiddenFromNav():
214
                        $type = 'hidden-from-nav';
215
216
                        break;
217
                    default:
218
                        $type = 'default';
219
                }
220
221
                $root = [
222
                    'id' => $rootNode->getId(),
223
                    'type' => $type,
224
                    'text' => $nodeTranslation->getTitle(),
225
                    'li_attr' => ['class' => 'js-url-chooser-link-select', 'data-slug' => $slug, 'data-id' => $rootNode->getId()],
226
                ];
227
228
                if ($rootNode->getChildren()->count()) {
229
                    if ($depth - 1) {
230
                        $root['children'] = $this->nodesToArray($locale, $rootNode->getChildren(), --$depth);
231
                    } else {
232
                        $root['children'] = true;
233
                    }
234
                }
235
                $results[] = $root;
236
            }
237
        }
238
239
        return $results;
240
    }
241
}
242