PageRenderTime 54ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/details/index.php

https://github.com/rakshithkr/showslow
PHP | 870 lines | 729 code | 127 blank | 14 comment | 167 complexity | 20f18c49738f0bbecf92dd027f07e789 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. <?php
  2. require_once(dirname(dirname(__FILE__)).'/global.php');
  3. require_once(dirname(dirname(__FILE__)).'/users/users.php');
  4. $urlid = array_key_exists('urlid', $_GET) ? filter_var($_GET['urlid'], FILTER_VALIDATE_INT) : null;
  5. $url_passed = $_GET['url'];
  6. # fixing up a URL if it is missing a double slash in domain name
  7. $url_passed = preg_replace('#^http://?#', 'http://', $url_passed);
  8. $url_passed = preg_replace('#^https://?#', 'https://', $url_passed);
  9. $url = array_key_exists('url', $_GET) ? filter_var($url_passed, FILTER_VALIDATE_URL) : null;
  10. function not_found() {
  11. header("HTTP/1.0 404 Not Found");
  12. ?><html>
  13. <head>
  14. <title>Error - no such URL</title>
  15. </head>
  16. <body>
  17. <h1>Error - no such URL</h1>
  18. <p><a href="../">Go back</a> and pick the URL</p>
  19. </body></html>
  20. <?php
  21. exit;
  22. }
  23. if (!$urlid && !$url) {
  24. not_found();
  25. }
  26. if (!$urlid && $url) {
  27. $query = "SELECT id FROM urls WHERE urls.url_md5 = UNHEX(MD5('".mysql_real_escape_string($url)."'))";
  28. $result = mysql_query($query);
  29. if (!$result) {
  30. error_log(mysql_error());
  31. }
  32. $row = mysql_fetch_assoc($result);
  33. if (is_null($row)) {
  34. not_found();
  35. } else {
  36. $urlid = $row['id'];
  37. if (is_null($urlid)) {
  38. not_found();
  39. }
  40. header("Location: ".detailsUrl($urlid, $url));
  41. exit;
  42. }
  43. }
  44. if ($urlid && !$url) {
  45. $query = "SELECT url FROM urls WHERE urls.id = ".mysql_real_escape_string($urlid);
  46. $result = mysql_query($query);
  47. if (!$result) {
  48. error_log(mysql_error());
  49. }
  50. $row = mysql_fetch_assoc($result);
  51. if (is_null($row)) {
  52. not_found();
  53. } else {
  54. $url = $row['url'];
  55. if (is_null($url)) {
  56. not_found();
  57. }
  58. header("Location: ".detailsUrl($urlid, $url));
  59. exit;
  60. }
  61. }
  62. # building a query to select all beacon data in one swoop
  63. $query = "SELECT urls.id AS url_id, urls.url as url, UNIX_TIMESTAMP(last_update) AS t, last_event_update, yslow2.details AS yslow_details";
  64. foreach ($all_metrics as $provider_name => $provider) {
  65. $query .= ",\n\t".$provider['table'].'_last_id, UNIX_TIMESTAMP('.$provider['table'].'.timestamp) AS '.$provider_name.'_timestamp';
  66. foreach ($provider['metrics'] as $section_name => $section) {
  67. foreach ($section as $metric) {
  68. $query .= ",\n\t\t".$provider['table'].'.'.$metric[1].' AS '.$provider_name.'_'.$metric[1];
  69. }
  70. }
  71. }
  72. $query .= "\nFROM urls";
  73. foreach ($all_metrics as $provider_name => $provider) {
  74. $query .= "\n\tLEFT JOIN ".$provider['table'].' ON urls.'.$provider['table'].'_last_id = '.$provider['table'].'.id';
  75. }
  76. $query .= "\nWHERE urls.id = ".mysql_real_escape_string($urlid);
  77. #echo $query; exit;
  78. $result = mysql_query($query);
  79. if (!$result) {
  80. error_log(mysql_error());
  81. }
  82. $row = mysql_fetch_assoc($result);
  83. $lastupdate = $row['t'];
  84. $eventupdate = $row['last_event_update'];
  85. $url = $row['url'];
  86. $yslow2_last_id = $row['yslow2_last_id'];
  87. $pagespeed_last_id = $row['pagespeed_last_id'];
  88. $dynatrace_last_id = $row['dynatrace_last_id'];
  89. mysql_free_result($result);
  90. $custom_metrics = array();
  91. $custom_metrics_version = 0;
  92. foreach ($metrics as $id => $metric) {
  93. $query = sprintf("SELECT value, UNIX_TIMESTAMP(timestamp) as t
  94. FROM metric WHERE url_id = %d AND metric_id = %d AND timestamp > DATE_SUB(now(), INTERVAL 3 MONTH)
  95. ORDER BY timestamp DESC LIMIT 1",
  96. mysql_real_escape_string($urlid),
  97. mysql_real_escape_string($metric['id'])
  98. );
  99. $result = mysql_query($query);
  100. if (!$result) {
  101. error_log(mysql_error());
  102. }
  103. if ($row_metrics = mysql_fetch_assoc($result)) {
  104. $custom_metrics[$metric['id']]['metric_slug'] = $id;
  105. $custom_metrics[$metric['id']]['metric'] = $metric;
  106. $custom_metrics[$metric['id']]['value'] = $row_metrics['value'];
  107. if ($row_metrics['t'] > $custom_metrics_version) {
  108. $custom_metrics_version = $row_metrics['t'];
  109. }
  110. }
  111. }
  112. // fetching locations only when needed
  113. getPageTestLocations();
  114. header('Last-modified: '.date(DATE_RFC2822, $lastupdate));
  115. if (array_key_exists('HTTP_IF_MODIFIED_SINCE', $_SERVER) &&
  116. ($lastupdate <= strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']))
  117. ) {
  118. header('HTTP/1.0 304 Not Modified');
  119. exit;
  120. }
  121. $TITLE = 'Details for '.htmlentities($url);
  122. $SCRIPTS[] = 'http://yui.yahooapis.com/combo?2.8.1/build/yahoo/yahoo-min.js&2.8.1/build/event/event-min.js&2.8.1/build/yuiloader/yuiloader-min.js';
  123. $current_user = User::get();
  124. if (!$enableFlot && !is_null($current_user)) {
  125. $enableFlot = $current_user->hasFeature(SHOWSLOW_FLOT_SUPPORT);
  126. }
  127. if (!$enableFlot) {
  128. $SCRIPTS = array_merge($SCRIPTS, array(
  129. $showslow_base.'ajax/simile-ajax-api.js?bundle=true',
  130. $showslow_base.'timeline/timeline-api.js?bundle=true',
  131. $showslow_base.'timeplot/timeplot-api.js?bundle=true',
  132. assetURL('details/timeplot.js')
  133. ));
  134. } else {
  135. $SCRIPTS = array_merge($SCRIPTS, array(
  136. array('condition' => 'if lte IE 8', 'url' => assetURL('flot/excanvas.js')),
  137. 'http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js',
  138. assetURL('flot/jquery.flot.js'),
  139. assetURL('flot/jquery.flot.crosshair.js'),
  140. assetURL('flot/jquery.flot.selection.js'),
  141. assetURL('flot/jquery.flot.resize.js'),
  142. ));
  143. }
  144. $SCRIPTS[] = assetURL('details/details.js');
  145. $SECTION = 'all';
  146. require_once(dirname(dirname(__FILE__)).'/header.php');
  147. if ($enableFlot) {
  148. $flot_metrics = array();
  149. $flot_versions = array();
  150. $color = 49;
  151. if (count($custom_metrics) > 0) {
  152. $flot_versions['custom'] = $custom_metrics_version;
  153. }
  154. $custom_metric_colors = array();
  155. foreach ($metrics as $slug => $custom_metric) {
  156. // assume the default value is NUBER
  157. if (!array_key_exists('type', $custom_metric)) {
  158. $custom_metric['type'] = NUMBER;
  159. }
  160. $flot_metrics['custom'][$slug] = array(
  161. 'color' => $color++,
  162. 'label' => $custom_metric['title'].' (custom)',
  163. 'data' => array(),
  164. 'yaxis' => $custom_metric['type'] + 1
  165. );
  166. $custom_metric_colors[] = $custom_metric['color'];
  167. }
  168. foreach ($all_metrics as $provider_name => $provider) {
  169. if ($enabledMetrics[$provider_name] && !is_null($row[$provider_name.'_timestamp']))
  170. {
  171. $flot_versions[$provider_name] = $row[$provider_name.'_timestamp'];
  172. foreach ($provider['metrics'] as $section_name => $section) {
  173. foreach ($section as $metric) {
  174. $flot_metrics[$provider_name][$metric[1]] = array(
  175. 'label' => $metric[0].' ('.$provider['title'].')',
  176. 'data' => array(),
  177. 'yaxis' => $metric[2] + 1
  178. );
  179. }
  180. }
  181. }
  182. }
  183. $default_metrics = array();
  184. foreach (array_keys($defaultGraphMetrics) as $provider_name) {
  185. if ($provider_name == 'custom') {
  186. foreach ($defaultGraphMetrics['custom'] as $metric_name) {
  187. foreach ($custom_metrics as $id => $metric) {
  188. if ($metric['metric_slug'] == $metric_name) {
  189. $default_metrics[$provider_name][] = $metric_name;
  190. break;
  191. }
  192. }
  193. }
  194. } else if ($enabledMetrics[$provider_name] && !is_null($row[$provider_name.'_timestamp'])) {
  195. $default_metrics[$provider_name] = $defaultGraphMetrics[$provider_name];
  196. }
  197. }
  198. ?>
  199. <script>
  200. var flot_metrics = <?php echo json_encode($flot_metrics); ?>;
  201. var flot_versions = <?php echo json_encode($flot_versions); ?>;
  202. var default_metrics = <?php echo json_encode($default_metrics); ?>;
  203. var custom_metric_colors = <?php echo json_encode($custom_metric_colors); ?>;
  204. <?php } else { ?>
  205. <script>
  206. <?php } ?>
  207. var url = <?php echo json_encode($url); ?>;
  208. var urlid = <?php echo json_encode($urlid); ?>;
  209. var metrics = <?php echo json_encode($metrics); ?>;
  210. </script>
  211. <h2>Details for <?php if ($linkToURLs) {?><a target="_blank" href="<?php echo htmlentities($url)?>" rel="nofollow"><?php } else { ?><span class="sitelink"><?php } ?><span title="<?php echo htmlentities($url) ?>"><?php echo htmlentities(ellipsis($url, 61)) ?></span><?php if ($linkToURLs) {?></a><?php } else { ?></span><?php } ?></h2>
  212. <?php if (!is_null($addThisProfile)) {?>
  213. <!-- AddThis Button BEGIN -->
  214. <div class="addthis_toolbox addthis_default_style" style="margin-right: 10px;">
  215. <a href="http://www.addthis.com/bookmark.php?v=250&amp;username=<?php echo urlencode($addThisProfile)?>" class="addthis_button_compact">Share</a>
  216. <span class="addthis_separator">|</span>
  217. <a class="addthis_button_twitter"></a>
  218. <a class="addthis_button_facebook"></a>
  219. <a class="addthis_button_google"></a>
  220. <a class="addthis_button_delicious"></a>
  221. <a class="addthis_button_stumbleupon"></a>
  222. <a class="addthis_button_reddit"></a>
  223. <span class="addthis_separator">|</span>
  224. <a class="addthis_button_favorites"></a>
  225. <a class="addthis_button_print"></a>
  226. <a class="addthis_button_email"></a>
  227. </div>
  228. <script type="text/javascript" src="http://s7.addthis.com/js/250/addthis_widget.js#username=<?php echo urlencode($addThisProfile)?>"></script>
  229. <!-- AddThis Button END -->
  230. <?php
  231. }
  232. // checking if there is har data
  233. $query = sprintf("SELECT har.timestamp as t, har.id as id, har.link as link FROM har WHERE har.url_id = '%d' ORDER BY timestamp DESC",
  234. mysql_real_escape_string($urlid)
  235. );
  236. $result = mysql_query($query);
  237. if (!$result) {
  238. error_log(mysql_error());
  239. }
  240. $har = array();
  241. while ($har_row = mysql_fetch_assoc($result)) {
  242. $har[] = $har_row;
  243. }
  244. // checking if there were PageTest tests ran
  245. $query = sprintf("SELECT pagetest.timestamp as t, test_id, location FROM pagetest WHERE pagetest.url_id = '%d' ORDER BY timestamp DESC",
  246. mysql_real_escape_string($urlid)
  247. );
  248. $result = mysql_query($query);
  249. if (!$result) {
  250. error_log(mysql_error());
  251. }
  252. $pagetest = array();
  253. while ($pagetest_row = mysql_fetch_assoc($result)) {
  254. $pagetest[] = $pagetest_row;
  255. }
  256. mysql_free_result($result);
  257. $data = array();
  258. $havemetrics = false;
  259. if (count($custom_metrics) > 0) {
  260. $havemetrics = true;
  261. }
  262. if (!$havemetrics && $row) {
  263. foreach (array_keys($all_metrics) as $provider_name) {
  264. if ($enabledMetrics[$provider_name]
  265. && !is_null($row[$provider_name.'_timestamp']))
  266. {
  267. $havemetrics = true;
  268. break;
  269. }
  270. }
  271. }
  272. if ($havemetrics)
  273. {
  274. ?>
  275. <table cellpadding="0" cellspacing="5"><tr>
  276. <?php
  277. foreach ($all_metrics as $provider_name => $provider) {
  278. if (!$enabledMetrics[$provider_name] || !array_key_exists('score_column', $provider)) {
  279. continue;
  280. }
  281. $score = $row[$provider_name.'_'.$provider['score_column']];
  282. if (!is_null($score)) {
  283. $pretty_score = prettyScore($score);
  284. ?>
  285. <td valign="top" align="center" class="<?php echo $provider_name ?>">
  286. <a href="#<?php echo $provider_name ?>"><img src="http://chart.apis.google.com/chart?chs=225x108&cht=gom&chd=t:<?php echo urlencode($score)?>&chl=<?php echo urlencode($pretty_score.' ('.$score.')') ?>" width="225" height="108" alt="<?php echo $pretty_score ?> (<?php echo htmlentities($score)?>)" title="Current <?php echo $provider['title'] ?> <?php echo $provider['score_name'] ?>: <?php echo $pretty_score ?> (<?php echo htmlentities($score)?>)" border="0"/></a>
  287. <div>Current <a href="#<?php echo $provider_name ?>"><?php echo $provider['title'] ?></a> <?php echo $provider['score_name'] ?>: <b><?php echo $pretty_score ?> (<i><?php echo htmlentities($score)?></i>)</b></div>
  288. </td>
  289. <?php
  290. }
  291. }
  292. ?>
  293. </tr></table>
  294. <?php
  295. }
  296. if ((!is_null($webPageTestBase) && !is_null($webPageTestKey))
  297. || !is_null($redBotBase)
  298. || $enablePageSpeedInsightsTool
  299. || is_array($customTools)
  300. ) {
  301. ?>
  302. <a name="tools"></a><fieldset id="tools"><legend>Tools</legend>
  303. <?php
  304. if (!is_null($webPageTestBase) && !is_null($webPageTestKey)) { ?>
  305. <div class="well pull-left" style="margin: 0.5%; width: 27%">
  306. <a name="pagetest"></a><h4>Run a test using <a href="<?php echo htmlentities($webPageTestBase)?>" target="_blank">WebPageTest</a></h4>
  307. <form class="form form-inline" style="margin-bottom: 0" action="<?php echo htmlentities($showslow_base)?>pagetest.php" method="POST" target="_blank">
  308. <input type="hidden" name="url" size="40" value="<?php echo htmlentities($url)?>"/>
  309. <img src="<?php echo assetURL('img/webpagetest-20h.png')?>" height="20" width="28" style="float: left; margin-right: 0.5em"/>
  310. Location: <select name="location" width="150">
  311. <?php foreach ($webPageTestLocations as $location) {
  312. if ($location['tests'] > 50) {
  313. continue;
  314. }
  315. ?>
  316. <option <?php echo htmlentities($location['default']) ? 'selected ' : ''?>value="<?php echo htmlentities($location['id'])?>"><?php echo htmlentities($location['title'])?></option>
  317. <?php } ?></select>
  318. <div>
  319. <label class="checkbox"><input type="checkbox" name="private" id="wpt_private" value="1"<?php if ($webPageTestPrivateByDefault) {?> checked="true"<?php } ?>/> Private</label>
  320. <label class="checkbox"><input type="checkbox" name="fvonly" id="wpt_fvonly" value="1"<?php if ($webPageTestFirstRunOnlyByDefault) {?> checked="true"<?php } ?>/> First View Only</label>
  321. </div>
  322. <input class="btn btn-mini btn-success pull-right" type="submit" value="Start Test"/>
  323. <?php if (count($pagetest) > 0) {?><a href="#pagetest-table">See test history below</a><?php } ?>
  324. </form>
  325. </div>
  326. <?php
  327. }
  328. if (!is_null($redBotBase)) { ?>
  329. <div class="well pull-left" style="margin: 0.5%; width: 27%">
  330. <a name="redbot"></a><h4>Run a test using <a href="<?php echo htmlentities($redBotBase)?>" target="_blank"><span style="color: #D33">RED</span>bot</a></h4>
  331. <form class="form form-inline" style="margin-bottom: 0" action="<?php echo htmlentities($redBotBase)?>" method="GET" target="_blank">
  332. <input type="hidden" name="uri" size="40" value="<?php echo htmlentities($url)?>"/>
  333. <label class="checkbox" for="checkallassets"><input type="checkbox" id="checkallassets" name="descend" value="True"<?php if ($redBotCheckAllByDefault) {?> checked<?php } ?>/> Check all components:</label>
  334. <input class="btn btn-mini btn-success pull-right" type="submit" value="Start Test"/>
  335. </form>
  336. </div>
  337. <?php
  338. }
  339. if ($enablePageSpeedInsightsTool) {
  340. ?>
  341. <div class="well pull-left" style="margin: 0.5%; width: 27%">
  342. <a name="pagespeedinsights"></a><h4>Run <a href="http://developers.google.com/speed/pagespeed/insights/" target="_blank">Google PageSpeed</a> Insights</h4>
  343. <img src="<?php echo assetURL('img/pagespeed-20h.png')?>" height="20" width="27" style="float: left; margin-right: 0.5em"/>
  344. Start Google PageSpeed Insights test
  345. <a class="btn btn-mini btn-success pull-right" href="https://developers.google.com/speed/pagespeed/insights/?url=<?php echo urlencode($url) ?>" target="_blank">Start Test</a>
  346. </div>
  347. <?php
  348. }
  349. if (is_array($customTools)) {
  350. foreach ($customTools as $name => $title) {
  351. ?>
  352. <div class="well pull-left" style="margin: 0 1em 1em 0">
  353. <a name="<?php echo $name ?>"></a><h3><?php echo $title ?></h3>
  354. <?php
  355. call_user_func('customTool_'.$name, $url);
  356. ?>
  357. </div>
  358. <?php
  359. }
  360. }
  361. ?>
  362. </fieldset>
  363. <?php
  364. }
  365. if (!$havemetrics)
  366. {
  367. ?>
  368. <h2 style="clear: both">Measurements over time</h2>
  369. <table width="100%" height="250px" style="border: 1px solid silver"><tr>
  370. <td align="center" valign="middle">
  371. <table cellpadding="3px">
  372. <tr>
  373. <td><img src="<?php echo assetURL('clock.png')?>"/></td>
  374. <td style="font-size: larger">Data is being collected</td>
  375. </tr>
  376. <tr><td colspan="2" align="center"><div class="gbox"><div class="bar ccol"></div></td></tr>
  377. </table>
  378. </td>
  379. </tr></table>
  380. <?php
  381. } else if (!$row) {
  382. ?><div style="padding: 2em">No data is collected for this URL</div><?php
  383. }
  384. if ($havemetrics)
  385. {
  386. ?>
  387. <a name="graph"></a>
  388. <h2 style="clear: both">Measurements over time</h2>
  389. <script>
  390. ydataversion = <?php if ($enabledMetrics['yslow']) {
  391. echo json_encode($row['yslow_timestamp']);
  392. } else {
  393. ?>null<?php
  394. } ?>;
  395. psdataversion = <?php if ($enabledMetrics['pagespeed']) {
  396. echo json_encode($row['pagespeed_timestamp']);
  397. } else {
  398. ?>null<?php
  399. } ?>;
  400. dtdataversion = <?php if ($enabledMetrics['dynatrace']) {
  401. echo json_encode($row['dynatrace_timestamp']);
  402. } else {
  403. ?>null<?php
  404. } ?>;
  405. eventversion = <?php echo json_encode($eventupdate)?>;
  406. </script>
  407. <?php
  408. // Graph
  409. if ($enableFlot) { ?>
  410. <style>
  411. #flot {
  412. width: 100%;
  413. height: 320px;
  414. margin: 0 auto;
  415. }
  416. #overview {
  417. width: 480px;
  418. height: 60px;
  419. margin: 1em auto;
  420. }
  421. #graphbuttons{
  422. text-align: center;
  423. margin: 1em;
  424. }
  425. </style>
  426. <div id="flot"></div>
  427. <div id="graphcontrols">
  428. <div id="graphbuttons">
  429. <button class="btn" id="default">Default Metrics</button>
  430. <button class="btn" id="clear">Clear Metrics</button>
  431. <button class="btn" id="reset" disabled="disabled">Reset Zoom</button>
  432. </div>
  433. <div id="overview"></div>
  434. </div>
  435. <?php
  436. } else {
  437. ?>
  438. <div id="my-timeplot" style="height: 250px;"></div>
  439. <div style="font-size: 0.9em">
  440. <?php
  441. if ($enabledMetrics['yslow'] && !is_null($row['yslow_timestamp']))
  442. {
  443. ?>
  444. <span style="color: #D0A825">Page Size</span> (in bytes);
  445. <span style="color: purple">Page Load time (YSlow)</span> (in ms);
  446. <span style="color: #75CF74">Total Requests</span>;
  447. <span class="yslow2">YSlow Grade</span> (0-100);
  448. <?php
  449. }
  450. if ($enabledMetrics['pagespeed'] && !is_null($row['pagespeed_timestamp']))
  451. {
  452. ?>
  453. <span style="color: #6F4428">Page Speed Grade</span> (0-100);
  454. <span style="color: #EE4F00">Page Load time (Page Speed)</span> (in ms);
  455. <?php
  456. }
  457. if ($enabledMetrics['dynatrace'] && !is_null($row['dynatrace_timestamp']))
  458. {
  459. ?>
  460. <span style="color: #AB0617">dynaTrace rank</span> (0-100);
  461. <?php
  462. }
  463. foreach ($metrics as $name => $metric)
  464. {
  465. ?><span title="<?php echo htmlentities($metric['description'])?>" style="color: <?php echo array_key_exists('color', $metric) ? $metric['color'] : 'black' ?>"><?php echo htmlentities($metric['title'])?></span> (<a href="<?php echo $showslow_base ?>/details/data_metric.php?metric=<?php echo urlencode($name);?>&urlid=<?php echo urlencode($urlid);?>">csv</a>);
  466. <?php
  467. }
  468. ?>
  469. </div>
  470. <?php
  471. $details = json_decode($row['yslow_details'], true);
  472. ?>
  473. <script>
  474. <?php
  475. $comps = array();
  476. if (is_array($details) && array_key_exists('g', $details)) {
  477. foreach ($details['g'] as $n => $y) {
  478. if (is_array($y) && array_key_exists('components', $y)) {
  479. $comps['yslow_'.$n] = $y['components'];
  480. }
  481. }
  482. }
  483. ?>
  484. var details = <?php echo json_encode($comps)?>;
  485. </script>
  486. <?php
  487. }
  488. // Custom metrics
  489. if (count($custom_metrics) > 0) {
  490. ?><a name="custom"></a><fieldset id="custom"><legend>Custom metrics</legend>
  491. <div class="col">
  492. Metrics defined for this instance
  493. <table>
  494. <?php
  495. $odd = true;
  496. foreach ($custom_metrics as $id => $data) {
  497. $metric = $data['metric'];
  498. // assume the default value is NUBER
  499. if (!array_key_exists('type', $metric)) {
  500. $metric['type'] = NUMBER;
  501. }
  502. if ($odd) { ?><tr><?php }
  503. ?><td class="titlecol">
  504. <label class="checkbox"><?php
  505. if ($enableFlot) { ?>
  506. <input type="checkbox" class="metric-toggle" id="custom-<?php echo $data['metric_slug']?>"/><?php
  507. }
  508. echo $metric['title'];
  509. if ($metric['type'] == NUMBER) {
  510. if (array_key_exists('min', $metric) && array_key_exists('max', $metric)) {
  511. echo ' ('.$metric['min'].' - '.$metric['max'].')';
  512. } else if (array_key_exists('min', $metric)) {
  513. echo ' ('.$metric['min'].' and up)';
  514. } else if (array_key_exists('max', $metric)) {
  515. echo ' (Under '.$metric['max'].')';
  516. }
  517. }
  518. ?></label>
  519. </td>
  520. <?php
  521. $value = $data['value'];
  522. if (is_null($value)) {
  523. ?><td colspan="3" class="na">n/a</td><?php
  524. } else {
  525. if ($metric['type'] == PERCENT_GRADE){
  526. $pretty_score = prettyScore($value);
  527. ?>
  528. <td class="value"><?php echo $pretty_score?> (<i><?php echo htmlentities($value)?></i>%)</td>
  529. <td><div class="gbox" title="Current <?php echo $metric['title']?>: <?php echo $pretty_score?> (<?php echo $value?>%)"><div class="bar c<?php echo scoreColorStep($value)?>" style="width: <?php echo $value+1?>px"/></div></td><?php
  530. } else {
  531. ?><td colspan="3" class="value"><?php
  532. if (array_key_exists('levels', $metric)) {
  533. ?><div class="levelbox-<?php
  534. if ($value < $metric['levels'][0]) {
  535. echo 'low';
  536. } else if ($value < $metric['levels'][1]) {
  537. echo 'mid';
  538. } else {
  539. echo 'high';
  540. }
  541. ?>"></div><?php
  542. } else if (array_key_exists('reverselevels', $metric)) {
  543. ?><div class="levelbox-<?php
  544. if ($value < $metric['reverselevels'][0]) {
  545. echo 'high';
  546. } else if ($value < $metric['reverselevels'][1]) {
  547. echo 'mid';
  548. } else {
  549. echo 'low';
  550. }
  551. ?>"></div><?php
  552. }
  553. if ($metric['type'] == BYTES) {
  554. ?><span title="<?php echo $value ?> bytes"><?php echo floor($value/1000) ?>KB</span><?php
  555. } else {
  556. echo $value.$metric_types[$metric['type']]['units'];
  557. }
  558. ?></td><?php
  559. }
  560. }
  561. if (!$odd) { ?></tr><?php }
  562. $odd = !$odd;
  563. ?>
  564. </tr>
  565. <?php
  566. }
  567. ?>
  568. </table>
  569. </div>
  570. </fieldset>
  571. <?php
  572. }
  573. // Breakdowns for each provider
  574. foreach ($all_metrics as $provider_name => $provider) {
  575. if (!is_null($row[$provider_name.'_timestamp']))
  576. {
  577. if (!$enabledMetrics[$provider_name]) {
  578. continue;
  579. }
  580. ?>
  581. <a name="<?php echo $provider_name ?>"></a><fieldset id="<?php echo $provider_name ?>"><legend><a href="<?php echo $provider['url']; ?>" target="_blank"><?php echo $provider['title']?></a> metrics</legend>
  582. <div class="col">
  583. <?php if (array_key_exists('description', $provider)) {
  584. ?><p><?php echo $provider['description'] ?></p><?php
  585. }?>
  586. <table>
  587. <?php
  588. foreach ($provider['metrics'] as $section_name => $metrics)
  589. {
  590. ?><tr><td colspan="8" class="sectionname"><b><?php echo $section_name ?></b></td></tr><?php
  591. $odd = true;
  592. foreach ($metrics as $metric) {
  593. if ($odd) { ?><tr><?php }
  594. ?><td class="titlecol"><?php
  595. ?><label class="checkbox" for="<?php echo $provider_name.'-'.$metric[1] ?>"><?php
  596. if ($enableFlot) { ?>
  597. <input type="checkbox" class="metric-toggle" id="<?php echo $provider_name.'-'.$metric[1] ?>"><?php
  598. }
  599. if (isset($metric[3])) {
  600. ?><a target="_blank" href="<?php echo $metric[3]?>"><?php echo $metric[0]?></a><?php
  601. }else{
  602. echo $metric[0];
  603. }
  604. ?></label><?php
  605. $value = $row[$provider_name.'_'.$metric[1]];
  606. if (is_null($value)) {
  607. ?><td colspan="3" class="na">n/a</td><?php
  608. } else {
  609. if ($metric[2] == PERCENT_GRADE){
  610. $pretty_score = prettyScore($value);
  611. ?>
  612. <td class="value"><?php echo $pretty_score?> (<i><?php echo htmlentities($value)?></i>%)</td>
  613. <td><span id="details_<?php echo $provider_name.'_'.$metric[1] ?>" class="details"></span></td>
  614. <td><div class="gbox" title="Current <?php echo $provider['score_name']?>: <?php echo $pretty_score?> (<?php echo $value?>%)"><div class="bar c<?php echo scoreColorStep($value)?>" style="width: <?php echo $value+1?>px"/></div></td><?php
  615. } else {
  616. ?><td colspan="3" class="value"><?php
  617. if (!array_key_exists(4, $metric)) {
  618. } else if ($metric[4] == 'levels') {
  619. ?><div class="levelbox-<?php
  620. if ($value < $metric[5][0]) {
  621. echo 'low';
  622. } else if ($value < $metric[5][1]) {
  623. echo 'mid';
  624. } else {
  625. echo 'high';
  626. }
  627. ?>"></div><?php
  628. } else if ($metric[4] == 'reverselevels') {
  629. ?><div class="levelbox-<?php
  630. if ($value < $metric[5][0]) {
  631. echo 'high';
  632. } else if ($value < $metric[5][1]) {
  633. echo 'mid';
  634. } else {
  635. echo 'low';
  636. }
  637. ?>"></div><?php
  638. }
  639. if ($metric[2] == BYTES) {
  640. ?><span title="<?php echo $value ?> bytes"><?php echo floor($value/1000) ?>KB</span><?php
  641. } else {
  642. echo $value.$metric_types[$metric[2]]['units'];
  643. }
  644. ?></td><?php
  645. }
  646. }
  647. if (!$odd) { ?></tr><?php }
  648. $odd = !$odd;
  649. }
  650. ?>
  651. </tr>
  652. <?php
  653. }
  654. ?>
  655. </table>
  656. </div>
  657. </fieldset>
  658. <?php
  659. }
  660. }
  661. }
  662. if ($enabledMetrics['yslow'] && !is_null($row['yslow_timestamp'])) {
  663. ?>
  664. <a name="yslow-table"></a><h2>YSlow measurements history (<a href="<?php echo $showslow_base ?>/details/data.php?ver=<?php echo urlencode($row['yslow_timestamp'])?>&urlid=<?php echo urlencode($urlid)?>">csv</a>)</h2>
  665. <div id="measurementstable" class="measurementstable"></div>
  666. <?php
  667. }
  668. if ($enabledMetrics['pagespeed'] && !is_null($row['pagespeed_timestamp'])) {
  669. ?>
  670. <a name="pagespeed-table"></a><h2>Page Speed measurements history (<a href="<?php echo $showslow_base ?>/details/data_pagespeed.php?ver=<?php echo urlencode($row['pagespeed_timestamp'])?>&urlid=<?php echo urlencode($urlid)?>">csv</a>)</h2>
  671. <div id="ps_measurementstable" class="measurementstable"></div>
  672. <?php
  673. }
  674. if ($enabledMetrics['dynatrace'] && !is_null($row['dynatrace_timestamp'])) {
  675. ?>
  676. <a name="dynatrace-table"></a><h2>dynaTrace measurements history (<a href="<?php echo $showslow_base ?>/details/data_dynatrace.php?ver=<?php echo urlencode($row['dynatrace_timestamp'])?>&urlid=<?php echo urlencode($urlid)?>">csv</a>)</h2>
  677. <div id="dt_measurementstable" class="measurementstable"></div>
  678. <?php
  679. }
  680. if (count($pagetest) > 0) {
  681. ?>
  682. <a name="pagetest-table"></a><h2>WebPageTest data collected</h2>
  683. <p>You can see latest <a href="<?php echo $webPageTestBase.'results.php?test='.htmlentities($pagetest[0]['test_id']) ?>" target="_blank">PageTest report for <?php echo htmlentities($url)?></a> or check the archive:</p>
  684. <table id="wpttable">
  685. <form class="form" action="<?php echo $showslow_base ?>/pagetestcompare.php" method="POST">
  686. <tr class="yui-dt-hd">
  687. <th>
  688. <div style="font-size: xx-small; text-align: left">
  689. <input type="submit" name="go" value="Compare"/>
  690. <input type="checkbox" name="repeat" value="true" id="wptrepeat"/>
  691. <label for="wptrepeat">repeat view</label>
  692. </div>
  693. </th>
  694. <th>Location</th>
  695. <th>PageTest</th>
  696. </tr>
  697. <?php
  698. foreach ($pagetest as $pagetestentry) {
  699. $location = array_key_exists($pagetestentry['location'], $webPageTestLocationsById) ?
  700. $webPageTestLocationsById[$pagetestentry['location']]['title'] :
  701. $pagetestentry['location'];
  702. ?>
  703. <tr>
  704. <td>
  705. <input id="wpttest<?php echo htmlentities($pagetestentry['test_id']) ?>" type="checkbox" name="compare[]" value="<?php echo htmlentities($pagetestentry['test_id']) ?>" />
  706. <input type="hidden" name="label[]" value="<?php echo htmlentities($pagetestentry['t']) ?>" />
  707. <label for="wpttest<?php echo htmlentities($pagetestentry['test_id']) ?>" type="checkbox" name="compare[]"><?php echo htmlentities($pagetestentry['t'])?></label></td>
  708. <td><?php echo htmlentities($location)?></td>
  709. <td><a href="<?php echo $webPageTestBase.'results.php?test='.htmlentities($pagetestentry['test_id']) ?>" target="_blank">view PageTest report</a></td>
  710. </tr>
  711. <?php
  712. }
  713. ?>
  714. </form>
  715. </table>
  716. <?php
  717. }
  718. if (count($har) > 0) {
  719. $har_url = is_null($har[0]['link']) ?
  720. $showslow_base.'details/har.php?id='.urlencode($har[0]['id']).'callback=onInputData'
  721. : $har[0]['link'];
  722. ?>
  723. <a name="har-table"></a><h2>HAR data collected</h2>
  724. <p>You can see latest HAR data in the viewer here: <a href="<?php echo htmlentities($HARViewerBase)?>?inputUrl=<?php echo urlencode($har_url) ?>" target="_blank">HAR for <?php echo htmlentities($url)?></a>.</p>
  725. <table id="hartable">
  726. <tr><th>Time</th><th>HAR</th></tr>
  727. <?php
  728. foreach ($har as $harentry) {
  729. $har_url = is_null($harentry['link']) ?
  730. $showslow_base.'details/har.php?id='.urlencode($harentry['id']).'callback=onInputData'
  731. : $harentry['link'];
  732. ?>
  733. <tr><td><?php echo htmlentities($harentry['t'])?></td><td><a href="<?php echo htmlentities($HARViewerBase)?>?inputUrl=<?php echo urlencode($har_url) ?>" target="_blank">view in HAR viewer</a></td></tr>
  734. <?php
  735. }
  736. ?>
  737. </table>
  738. <?php
  739. }
  740. if ($enableFlot) {
  741. ?><script src="<?php echo assetURL('details/showslow.flot.js') ?>"></script><?php
  742. }
  743. require_once(dirname(dirname(__FILE__)).'/footer.php');