Completed
Push — master ( 022281...f9cc19 )
by Elan
20s
created

src/Xhgui/Controller/Run.php (3 issues)

Severity

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
use Slim\Slim;
4
5
class Xhgui_Controller_Run extends Xhgui_Controller
6
{
7
    /**
8
     * HTTP GET attribute name for comma separated filters
9
     */
10
    const FILTER_ARGUMENT_NAME = 'filter';
11
    
12
    /**
13
     * @var Xhgui_Profiles
14
     */
15
    private $profiles;
16
17
    /**
18
     * @var Xhgui_WatchFunctions
19
     */
20
    private $watches;
21
22
    public function __construct(Slim $app, Xhgui_Profiles $profiles, Xhgui_WatchFunctions $watches)
23
    {
24
        $this->app = $app;
25
        $this->profiles = $profiles;
26
        $this->watches = $watches;
27
    }
28
29
    public function index()
30
    {
31
        $request = $this->app->request();
32
33
        $search = array();
34
        $keys = array('date_start', 'date_end', 'url');
35
        foreach ($keys as $key) {
36
            if ($request->get($key)) {
37
                $search[$key] = $request->get($key);
38
            }
39
        }
40
        $sort = $request->get('sort');
41
42
        $result = $this->profiles->getAll(array(
43
            'sort' => $sort,
44
            'page' => $request->get('page'),
45
            'direction' => $request->get('direction'),
46
            'perPage' => $this->app->config('page.limit'),
47
            'conditions' => $search,
48
            'projection' => true,
49
        ));
50
51
        $title = 'Recent runs';
52
        $titleMap = array(
53
            'wt' => 'Longest wall time',
54
            'cpu' => 'Most CPU time',
55
            'mu' => 'Highest memory use',
56
        );
57
        if (isset($titleMap[$sort])) {
58
            $title = $titleMap[$sort];
59
        }
60
61
        $paging = array(
62
            'total_pages' => $result['totalPages'],
63
            'page' => $result['page'],
64
            'sort' => $sort,
65
            'direction' => $result['direction']
66
        );
67
68
        $this->_template = 'runs/list.twig';
69
        $this->set(array(
70
            'paging' => $paging,
71
            'base_url' => 'home',
72
            'runs' => $result['results'],
73
            'date_format' => $this->app->config('date.format'),
74
            'search' => $search,
75
            'has_search' => strlen(implode('', $search)) > 0,
76
            'title' => $title
77
        ));
78
    }
79
80
    public function view()
81
    {
82
        $request = $this->app->request();
83
        $detailCount = $this->app->config('detail.count');
84
        $result = $this->profiles->get($request->get('id'));
85
86
        $result->calculateSelf();
87
88
        // Self wall time graph
89
        $timeChart = $result->extractDimension('ewt', $detailCount);
90
91
        // Memory Block
92
        $memoryChart = $result->extractDimension('emu', $detailCount);
93
94
        // Watched Functions Block
95
        $watchedFunctions = array();
96
        foreach ($this->watches->getAll() as $watch) {
97
            $matches = $result->getWatched($watch['name']);
98
            if ($matches) {
99
                $watchedFunctions = array_merge($watchedFunctions, $matches);
100
            }
101
        }
102
103
        if (false !== $request->get(self::FILTER_ARGUMENT_NAME, false)) {
104
            $profile = $result->sort('ewt', $result->filter($result->getProfile(), $this->getFilters()));
105
        } else {
106
            $profile = $result->sort('ewt', $result->getProfile());
107
        }
108
109
        $this->_template = 'runs/view.twig';
110
        $this->set(array(
111
            'profile' => $profile,
112
            'result' => $result,
113
            'wall_time' => $timeChart,
114
            'memory' => $memoryChart,
115
            'watches' => $watchedFunctions,
116
            'date_format' => $this->app->config('date.format'),
117
        ));
118
    }
119
    
120
    /**
121
     * @return array
122
     */
123
    protected function getFilters()
124
    {
125
        $request = $this->app->request();
126
        $filterString = $request->get(self::FILTER_ARGUMENT_NAME);
127
        if (strlen($filterString) > 1 && $filterString !== 'true') {
128
            $filters = array_map('trim', explode(',', $filterString));
129
        } else {
130
            $filters = $this->app->config('run.view.filter.names');
131
        }
132
        
133
        return $filters;
134
    }
135
136
    public function deleteForm()
137
    {
138
        $request = $this->app->request();
139
        $id = $request->get('id');
140
        if (!is_string($id) || !strlen($id)) {
141
            throw new Exception('The "id" parameter is required.');
142
        }
143
144
        // Get details
145
        $result = $this->profiles->get($id);
146
147
        $this->_template = 'runs/delete-form.twig';
148
        $this->set(array(
149
            'run_id' => $id,
150
            'result' => $result,
151
        ));
152
    }
153
154
    public function deleteSubmit()
155
    {
156
        $request = $this->app->request();
157
        $id = $request->post('id');
158
        // Don't call profilers->delete() unless $id is set,
159
        // otherwise it will turn the null into a MongoId and return "Sucessful".
160
        if (!is_string($id) || !strlen($id)) {
161
            // Form checks this already,
162
            // only reachable by handcrafted or malformed requests.
163
            throw new Exception('The "id" parameter is required.');
164
        }
165
166
        // Delete the profile run.
167
        $delete = $this->profiles->delete($id);
0 ignored issues
show
$delete 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...
168
169
        $this->app->flash('success', 'Deleted profile ' . $id);
170
171
        $this->app->redirect($this->app->urlFor('home'));
172
    }
173
174
    public function deleteAllForm()
175
    {
176
        $this->_template = 'runs/delete-all-form.twig';
177
    }
178
179
    public function deleteAllSubmit()
180
    {
181
        $request = $this->app->request();
0 ignored issues
show
$request 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...
182
183
        // Delete all profile runs.
184
        $delete = $this->profiles->truncate();
0 ignored issues
show
$delete 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...
185
186
        $this->app->flash('success', 'Deleted all profiles');
187
188
        $this->app->redirect($this->app->urlFor('home'));
189
    }
190
191
    public function url()
192
    {
193
        $request = $this->app->request();
194
        $pagination = array(
195
            'sort' => $request->get('sort'),
196
            'direction' => $request->get('direction'),
197
            'page' => $request->get('page'),
198
            'perPage' => $this->app->config('page.limit'),
199
        );
200
201
        $search = array();
202
        $keys = array('date_start', 'date_end', 'limit', 'limit_custom');
203
        foreach ($keys as $key) {
204
            $search[$key] = $request->get($key);
205
        }
206
207
        $runs = $this->profiles->getForUrl(
208
            $request->get('url'),
209
            $pagination,
210
            $search
211
        );
212
213
        if (isset($search['limit_custom']) && strlen($search['limit_custom']) > 0 && $search['limit_custom'][0] == 'P') {
214
            $search['limit'] = $search['limit_custom'];
215
        }
216
217
        $chartData = $this->profiles->getPercentileForUrl(
218
            90,
219
            $request->get('url'),
220
            $search
221
        );
222
223
        $paging = array(
224
            'total_pages' => $runs['totalPages'],
225
            'sort' => $pagination['sort'],
226
            'page' => $runs['page'],
227
            'direction' => $runs['direction']
228
        );
229
230
        $this->_template = 'runs/url.twig';
231
        $this->set(array(
232
            'paging' => $paging,
233
            'base_url' => 'url.view',
234
            'runs' => $runs['results'],
235
            'url' => $request->get('url'),
236
            'chart_data' => $chartData,
237
            'date_format' => $this->app->config('date.format'),
238
            'search' => array_merge($search, array('url' => $request->get('url'))),
239
        ));
240
    }
241
242
    public function compare()
243
    {
244
        $request = $this->app->request();
245
246
        $baseRun = $headRun = $candidates = $comparison = null;
247
        $paging = array();
248
249
        if ($request->get('base')) {
250
            $baseRun = $this->profiles->get($request->get('base'));
251
        }
252
253
        if ($baseRun && !$request->get('head')) {
254
            $pagination = array(
255
                'direction' => $request->get('direction'),
256
                'sort' => $request->get('sort'),
257
                'page' => $request->get('page'),
258
                'perPage' => $this->app->config('page.limit'),
259
            );
260
            $candidates = $this->profiles->getForUrl(
261
                $baseRun->getMeta('simple_url'),
262
                $pagination
263
            );
264
265
            $paging = array(
266
                'total_pages' => $candidates['totalPages'],
267
                'sort' => $pagination['sort'],
268
                'page' => $candidates['page'],
269
                'direction' => $candidates['direction']
270
            );
271
        }
272
273
        if ($request->get('head')) {
274
            $headRun = $this->profiles->get($request->get('head'));
275
        }
276
277
        if ($baseRun && $headRun) {
278
            $comparison = $baseRun->compare($headRun);
279
        }
280
281
        $this->_template = 'runs/compare.twig';
282
        $this->set(array(
283
            'base_url' => 'run.compare',
284
            'base_run' => $baseRun,
285
            'head_run' => $headRun,
286
            'candidates' => $candidates,
287
            'url_params' => $request->get(),
288
            'date_format' => $this->app->config('date.format'),
289
            'comparison' => $comparison,
290
            'paging' => $paging,
291
            'search' => array(
292
                'base' => $request->get('base'),
293
                'head' => $request->get('head'),
294
            )
295
        ));
296
    }
297
298
    public function symbol()
299
    {
300
        $request = $this->app->request();
301
        $id = $request->get('id');
302
        $symbol = $request->get('symbol');
303
304
        $profile = $this->profiles->get($id);
305
        $profile->calculateSelf();
306
        list($parents, $current, $children) = $profile->getRelatives($symbol);
307
308
        $this->_template = 'runs/symbol.twig';
309
        $this->set(array(
310
            'symbol' => $symbol,
311
            'id' => $id,
312
            'main' => $profile->get('main()'),
313
            'parents' => $parents,
314
            'current' => $current,
315
            'children' => $children,
316
        ));
317
    }
318
319
    public function symbolShort()
320
    {
321
        $request = $this->app->request();
322
        $id = $request->get('id');
323
        $threshold = $request->get('threshold');
324
        $symbol = $request->get('symbol');
325
        $metric = $request->get('metric');
326
327
        $profile = $this->profiles->get($id);
328
        $profile->calculateSelf();
329
        list($parents, $current, $children) = $profile->getRelatives($symbol, $metric, $threshold);
330
331
        $this->_template = 'runs/symbol-short.twig';
332
        $this->set(array(
333
            'symbol' => $symbol,
334
            'id' => $id,
335
            'main' => $profile->get('main()'),
336
            'parents' => $parents,
337
            'current' => $current,
338
            'children' => $children,
339
        ));
340
    }
341
342
    public function callgraph()
343
    {
344
        $request = $this->app->request();
345
        $profile = $this->profiles->get($request->get('id'));
346
347
        $this->_template = 'runs/callgraph.twig';
348
        $this->set(array(
349
            'profile' => $profile,
350
            'date_format' => $this->app->config('date.format'),
351
        ));
352
    }
353
354 View Code Duplication
    public function callgraphData()
355
    {
356
        $request = $this->app->request();
357
        $response = $this->app->response();
358
        $profile = $this->profiles->get($request->get('id'));
359
        $metric = $request->get('metric') ?: 'wt';
360
        $threshold = (float)$request->get('threshold') ?: 0.01;
361
        $callgraph = $profile->getCallgraph($metric, $threshold);
362
363
        $response['Content-Type'] = 'application/json';
364
        return $response->body(json_encode($callgraph));
365
    }
366
367 View Code Duplication
    public function callgraphDataDot()
368
    {
369
        $request = $this->app->request();
370
        $response = $this->app->response();
371
        $profile = $this->profiles->get($request->get('id'));
372
        $metric = $request->get('metric') ?: 'wt';
373
        $threshold = (float)$request->get('threshold') ?: 0.01;
374
        $callgraph = $profile->getCallgraphNodes($metric, $threshold);
375
376
        $response['Content-Type'] = 'application/json';
377
        return $response->body(json_encode($callgraph));
378
    }
379
}
380