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

Controller/GoogleAnalyticsAJAXController.php (7 issues)

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\DashboardBundle\Controller;
4
5
use Kunstmaan\AdminBundle\FlashMessages\FlashTypes;
6
use Kunstmaan\DashboardBundle\Command\GoogleAnalyticsDataCollectCommand;
7
use Kunstmaan\DashboardBundle\Entity\AnalyticsConfig;
8
use Kunstmaan\DashboardBundle\Entity\AnalyticsGoal;
9
use Kunstmaan\DashboardBundle\Entity\AnalyticsOverview;
10
use Kunstmaan\DashboardBundle\Entity\AnalyticsSegment;
11
use Kunstmaan\DashboardBundle\Repository\AnalyticsOverviewRepository;
12
use Symfony\Component\Routing\Annotation\Route;
13
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
14
use Symfony\Component\Console\Input\ArrayInput;
15
use Symfony\Component\Console\Output\NullOutput;
16
use Symfony\Component\HttpFoundation\JsonResponse;
17
use Symfony\Component\HttpFoundation\Request;
18
19
class GoogleAnalyticsAJAXController extends Controller
20
{
21
    /**
22
     * @Route("/updateData", name="KunstmaanDashboardBundle_analytics_update")
23
     */
24
    public function runUpdateAction(Request $request)
25
    {
26
        $configId = $request->query->get('configId');
27
        $segmentId = $request->query->get('segmentId');
28
29
        $command = new GoogleAnalyticsDataCollectCommand();
30
        $command->setContainer($this->container);
31
        $input = new ArrayInput(array('--config' => $configId, '--segment' => $segmentId));
32
        $output = new NullOutput();
33
        $command->run($input, $output);
34
35
        return new JsonResponse(array(), 200, array('Content-Type' => 'application/json'));
36
    }
37
38
    /**
39
     * Return an ajax response with all data for an overview
40
     *
41
     * @Route("/getOverview/{id}", requirements={"id" = "\d+"}, name="KunstmaanDashboardBundle_analytics_overview_ajax")
42
     */
43
    public function getOverviewAction($id)
44
    {
45
        $em = $this->getDoctrine()->getManager();
46
        /** @var AnalyticsOverviewRepository $analyticsOverviewRepository */
47
        $analyticsOverviewRepository = $em->getRepository(AnalyticsOverview::class);
48
        $overview = $analyticsOverviewRepository->find($id);
49
50
        // goals data
51
        $goals = array();
52
        foreach ($overview->getActiveGoals() as $key => $goal) {
53
            /* @var AnalyticsGoal $goal */
54
            $goals[$key]['name'] = $goal->getName();
55
            $goals[$key]['visits'] = $goal->getVisits();
56
            $goals[$key]['id'] = $goal->getId();
57
            $goals[$key]['chartData'] = json_decode($goal->getChartData());
58
        }
59
60
        // overview data
61
        $overviewData = array(
62
            'id' => $overview->getId(),
63
            'chartData' => json_decode($overview->getChartData(), true),
64
            'chartDataMaxValue' => $overview->getChartDataMaxValue(),
65
            'title' => $overview->getTitle(),
66
            'timespan' => $overview->getTimespan(),
67
            'startOffset' => $overview->getStartOffset(),
68
            'sessions' => number_format($overview->getSessions()),
69
            'users' => number_format($overview->getUsers()),
70
            'pagesPerSession' => round($overview->getPagesPerSession(), 2),
71
            'avgSessionDuration' => $overview->getAvgSessionDuration(),
72
            'returningUsers' => number_format($overview->getReturningUsers()),
73
            'newUsers' => round($overview->getNewUsers(), 2),
74
            'pageViews' => number_format($overview->getPageViews()),
75
            'returningUsersPercentage' => $overview->getReturningUsersPercentage(),
76
            'newUsersPercentage' => $overview->getNewUsersPercentage(),
77
        );
78
79
        // put all data in the return array
80
        $return = array(
81
            'responseCode' => 200,
82
            'overview' => $overviewData,
83
            'goals' => $goals,
84
        );
85
86
        // return json response
87
        return new JsonResponse($return, 200, array('Content-Type' => 'application/json'));
88
    }
89
90
    /* =============================== ACCOUNT =============================== */
91
92
    /**
93
     * @Route("/accounts/", name="kunstmaan_dashboard_ajax_accounts")
94
     */
95
    public function getAccountsAction(Request $request)
96
    {
97
        $configHelper = $this->container->get('kunstmaan_dashboard.helper.google.analytics.config');
98
        $configId = $request->query->get('configId');
99
        if ($configId) {
100
            $configHelper->init($configId);
101
        }
102
103
        $accounts = $configHelper->getAccounts();
104
105
        return new JsonResponse($accounts, 200, array('Content-Type' => 'application/json'));
106
    }
107
108
    /**
109
     * @Route("/account/save", name="kunstmaan_dashboard_ajax_account_save")
110
     */
111 View Code Duplication
    public function saveAccountAction(Request $request)
112
    {
113
        $accountId = $request->query->get('id');
114
        $configHelper = $this->container->get('kunstmaan_dashboard.helper.google.analytics.config');
115
        $configHelper->saveAccountId($accountId);
116
117
        return new JsonResponse();
118
    }
119
120
    /* =============================== PROPERTY =============================== */
121
122
    /**
123
     * @Route("/properties/", name="kunstmaan_dashboard_ajax_properties")
124
     */
125
    public function getPropertiesAction(Request $request)
126
    {
127
        $accountId = $request->query->get('accountId');
128
        $configHelper = $this->container->get('kunstmaan_dashboard.helper.google.analytics.config');
129
        $configId = $request->query->get('configId');
130
        if ($configId) {
131
            $configHelper->init($configId);
132
        }
133
134
        $properties = $configHelper->getProperties($accountId);
135
136
        return new JsonResponse($properties, 200, array('Content-Type' => 'application/json'));
137
    }
138
139
    /**
140
     * @Route("/property/save", name="kunstmaan_dashboard_ajax_property_save")
141
     */
142 View Code Duplication
    public function savePropertyAction(Request $request)
143
    {
144
        $propertyId = $request->query->get('id');
145
        $configHelper = $this->container->get('kunstmaan_dashboard.helper.google.analytics.config');
146
        $configHelper->savePropertyId($propertyId);
147
148
        return new JsonResponse();
149
    }
150
151
    /* =============================== PROFILE =============================== */
152
153
    /**
154
     * @Route("/profiles/", name="kunstmaan_dashboard_ajax_profiles")
155
     */
156
    public function getProfilesAction(Request $request)
157
    {
158
        $accountId = $request->query->get('accountId');
159
        $propertyId = $request->query->get('propertyId');
160
        $configHelper = $this->container->get('kunstmaan_dashboard.helper.google.analytics.config');
161
        $configId = $request->query->get('configId');
162
        if ($configId) {
163
            $configHelper->init($configId);
164
        }
165
166
        $profiles = $configHelper->getProfiles($accountId, $propertyId);
167
168
        return new JsonResponse($profiles, 200, array('Content-Type' => 'application/json'));
169
    }
170
171
    /**
172
     * @Route("/profile/save", name="kunstmaan_dashboard_ajax_profile_save")
173
     */
174 View Code Duplication
    public function saveProfileAction(Request $request)
175
    {
176
        $propertyId = $request->query->get('id');
177
        $configHelper = $this->container->get('kunstmaan_dashboard.helper.google.analytics.config');
178
        $configHelper->saveProfileId($propertyId);
179
180
        return new JsonResponse();
181
    }
182
183
    /* =============================== CONFIG =============================== */
184
185
    /**
186
     * @Route("/config/save", name="kunstmaan_dashboard_ajax_config_save")
187
     */
188
    public function saveConfigAction(Request $request)
189
    {
190
        // get params
191
        $configId = $request->query->get('configId');
192
        $accountId = $request->query->get('accountId');
193
        $propertyId = $request->query->get('propertyId');
194
        $profileId = $request->query->get('profileId');
195
        $disableGoals = $request->query->get('disableGoals');
196
197
        // edit the config
198
        $em = $this->getDoctrine()->getManager();
199
        $config = $em->getRepository(AnalyticsConfig::class)->find($configId);
200
        if ($accountId && $propertyId && $profileId) {
201
            $config->setAccountId($accountId);
202
            $config->setPropertyId($propertyId);
203
            $config->setProfileId($profileId);
204
        }
205
206
        $em->persist($config);
0 ignored issues
show
It seems like $config defined by $em->getRepository(\Kuns...class)->find($configId) on line 199 can also be of type null; however, Doctrine\Persistence\ObjectManager::persist() does only seem to accept object, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
207
        $em->flush();
208
209
        // set the config name
210
        $configHelper = $this->container->get('kunstmaan_dashboard.helper.google.analytics.config');
211
        $configHelper->init($configId);
212
        $profile = $configHelper->getActiveProfile();
213
        $config->setName($profile['profileName']);
214
        $config->setDisableGoals($disableGoals);
215
216
        $em->persist($config);
0 ignored issues
show
It seems like $config defined by $em->getRepository(\Kuns...class)->find($configId) on line 199 can also be of type null; however, Doctrine\Persistence\ObjectManager::persist() does only seem to accept object, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
217
        $em->flush();
218
219
        $this->addFlash(
220
            FlashTypes::SUCCESS,
221
            $this->get('translator')->trans('kuma_admin.ga_ajax_controller.flash.success')
222
        );
223
224
        return new JsonResponse();
225
    }
226
227
    /**
228
     * @Route("/config/remove", name="kunstmaan_dashboard_ajax_config_remove")
229
     */
230
    public function removeConfigAction(Request $request)
231
    {
232
        // get params
233
        $configId = $request->query->get('configId');
234
235
        // edit the config
236
        $em = $this->getDoctrine()->getManager();
237
        $config = $em->getRepository(AnalyticsConfig::class)->find($configId);
238
        $em->remove($config);
0 ignored issues
show
It seems like $config defined by $em->getRepository(\Kuns...class)->find($configId) on line 237 can also be of type null; however, Doctrine\Persistence\ObjectManager::remove() does only seem to accept object, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
239
        $em->flush();
240
241
        return new JsonResponse();
242
    }
243
244
    /**
245
     * @Route("/config/get", name="kunstmaan_dashboard_ajax_config_get")
246
     */
247
    public function getConfigAction(Request $request)
248
    {
249
        $em = $this->getDoctrine()->getManager();
250
        $config = $em->getRepository(AnalyticsConfig::class)->findFirst();
0 ignored issues
show
It seems like you code against a concrete implementation and not the interface Doctrine\Persistence\ObjectRepository as the method findFirst() does only exist in the following implementations of said interface: Kunstmaan\DashboardBundl...alyticsConfigRepository.

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...
251
        $accountId = $config->getAccountId();
252
253
        if (!$accountId) {
254
            return new JsonResponse();
255
        }
256
257
        $configHelper = $this->container->get('kunstmaan_dashboard.helper.google.analytics.config');
258
        $configHelper->getAccounts();
259
        $configHelper->getProperties();
260
        $configHelper->getProfiles();
261
    }
262
263
    /* =============================== SEGMENT =============================== */
264
265
    /**
266
     * @Route("/segment/add/", name="kunstmaan_dashboard_ajax_segment_add")
267
     */
268
    public function addSegmentAction(Request $request)
269
    {
270
        $configId = $request->query->get('configId');
271
        $em = $this->getDoctrine()->getManager();
272
273
        // create a new segment
274
        $segment = new AnalyticsSegment();
275
        $query = $request->query->get('query');
276
        $name = $request->query->get('name');
277
        $segment->setQuery($query);
278
        $segment->setName($name);
279
280
        // add the segment to the config
281
        $config = $em->getRepository(AnalyticsConfig::class)->find($configId);
282
        $segment->setConfig($config);
283
        $segments = $config->getSegments();
284
        $segments[] = $segment;
285
        $config->setSegments($segments);
286
287
        $em->persist($config);
0 ignored issues
show
It seems like $config defined by $em->getRepository(\Kuns...class)->find($configId) on line 281 can also be of type null; however, Doctrine\Persistence\ObjectManager::persist() does only seem to accept object, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
288
        $em->flush();
289
290
        return new JsonResponse();
291
    }
292
293
    /**
294
     * @Route("/segment/delete", name="kunstmaan_dashboard_ajax_segment_delete")
295
     */
296
    public function deleteSegmentAction(Request $request)
297
    {
298
        $em = $this->getDoctrine()->getManager();
299
300
        $id = $request->query->get('id');
301
        $em->getRepository(AnalyticsSegment::class)->deleteSegment($id);
0 ignored issues
show
It seems like you code against a concrete implementation and not the interface Doctrine\Persistence\ObjectRepository as the method deleteSegment() does only exist in the following implementations of said interface: Kunstmaan\DashboardBundl...lyticsSegmentRepository.

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...
302
303
        return new JsonResponse();
304
    }
305
306
    /**
307
     * @Route("/segment/edit", name="kunstmaan_dashboard_ajax_segment_edit")
308
     */
309
    public function editSegmentAction(Request $request)
310
    {
311
        $em = $this->getDoctrine()->getManager();
312
313
        $id = $request->query->get('id');
314
        $query = $request->query->get('query');
315
        $name = $request->query->get('name');
316
        $segment = $em->getRepository(AnalyticsSegment::class)->find($id);
317
        $segment->setName($name);
318
        $segment->setQuery($query);
319
        $em->persist($segment);
0 ignored issues
show
It seems like $segment defined by $em->getRepository(\Kuns...ment::class)->find($id) on line 316 can also be of type null; however, Doctrine\Persistence\ObjectManager::persist() does only seem to accept object, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
320
        $em->flush();
321
322
        return new JsonResponse();
323
    }
324
}
325