Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.

Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401]

   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  /**
  18   * Profiling tool.
  19   *
  20   * @package    tool_profiling
  21   * @copyright  2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
  22   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  
  25  // TODO: Move all the DB stuff to profiling_db_xxxx() function in xhprof_moodle.php
  26  
  27  // TODO: it is wrong when core lib references ANY plugin lang strings, maybe more login could be moved here (skodak)
  28  
  29  require_once(__DIR__ . '/../../../config.php');
  30  require_once($CFG->libdir.'/adminlib.php');
  31  require_once($CFG->libdir . '/xhprof/xhprof_moodle.php');
  32  
  33  define('PROFILING_RUNSPERPAGE', 50);
  34  
  35  // page parameters
  36  $script   = optional_param('script', null, PARAM_PATH);
  37  $runid    = optional_param('runid', null, PARAM_ALPHANUM);
  38  $runid2   = optional_param('runid2', null, PARAM_ALPHANUM);
  39  $listurl  = optional_param('listurl', null, PARAM_PATH);
  40  $runreference= optional_param('runreference', 0, PARAM_INT);
  41  $runcomment  = optional_param('runcomment', null, PARAM_TEXT);
  42  
  43  $dbfields = 'runid, url, totalexecutiontime, totalcputime, ' .
  44              'totalcalls, totalmemory, runreference, runcomment, timecreated';
  45  
  46  admin_externalpage_setup('toolprofiling');
  47  
  48  // Always add listurl if available
  49  if ($listurl) {
  50      $listurlnav = new moodle_url('/admin/tool/profiling/index.php', array('listurl' => $listurl));
  51      $PAGE->navbar->add($listurl, $listurlnav);
  52  }
  53  
  54  // Add a new nav item to make $listurl clickable for the Boost theme.
  55  if (isset($script)) {
  56      $lastrunnav = get_string('lastrun', 'tool_profiling');
  57      $PAGE->navbar->add($lastrunnav);
  58  }
  59  
  60  // Header
  61  echo $OUTPUT->header();
  62  
  63  // We have requested the last available run for one script
  64  if (isset($script)) {
  65      // Get the last available run for the given script
  66      $run = $DB->get_record_sql("SELECT $dbfields
  67                                   FROM {profiling}
  68                                  WHERE url = ?
  69                                    AND id = (SELECT MAX(id)
  70                                                FROM {profiling}
  71                                               WHERE url = ?)",
  72                                array($script, $script), IGNORE_MISSING);
  73  
  74      // No run found for script, warn and exit
  75      if (!$run) {
  76          notice(get_string('cannotfindanyrunforurl', 'tool_profiling', $script), 'index.php');
  77      }
  78  
  79      // Check if there is any previous run marked as reference one
  80      $prevreferences = $DB->get_records_select('profiling',
  81                                                'url = ? AND runreference = 1 AND timecreated < ?',
  82                                                array($run->url, $run->timecreated),
  83                                                'timecreated DESC', 'runid, runcomment, timecreated', 0, 10);
  84      echo $OUTPUT->box_start('generalbox boxwidthwide boxaligncenter');
  85      $header = get_string('lastrunof', 'tool_profiling', $script);
  86      echo $OUTPUT->heading($header);
  87      $table = profiling_print_run($run, $prevreferences);
  88      echo $table;
  89      echo $OUTPUT->box_end();
  90  
  91  
  92  // We have requested the diff between 2 runs
  93  } else if (isset($runid) && isset($runid2)) {
  94      $run1 = $DB->get_record('profiling', array('runid'=>$runid), $dbfields, MUST_EXIST);
  95      $run2 = $DB->get_record('profiling', array('runid'=>$runid2), $dbfields, MUST_EXIST);
  96      if ($run1->url == $run2->url && $run1->runid != $run2->runid) {
  97          if ($run2->timecreated < $run1->timecreated) {
  98              $runtemp = $run1;
  99              $run1 = $run2;
 100              $run2 = $runtemp;
 101          }
 102          echo $OUTPUT->box_start('generalbox boxwidthwide boxaligncenter');
 103          $header = get_string('differencesbetween2runsof', 'tool_profiling', $run1->url);
 104          echo $OUTPUT->heading($header);
 105          $table = profiling_print_rundiff($run1, $run2);
 106          echo $table;
 107          echo $OUTPUT->box_end();
 108      }
 109  
 110  
 111  // We have requested one run, invoke it
 112  } else if (isset($runid)) {
 113      // Check if we are trying to update the runreference/runcomment for the run
 114      if (isset($runcomment) && confirm_sesskey()) {
 115          $id = $DB->get_field('profiling', 'id', array('runid' => $runid), MUST_EXIST);
 116          $rec = new stdClass();
 117          $rec->id = $id;
 118          $rec->runreference = (bool)$runreference;
 119          $rec->runcomment   = $runcomment;
 120          $DB->update_record('profiling', $rec);
 121      }
 122      // Get the requested runid
 123      $run = $DB->get_record('profiling', array('runid'=>$runid), $dbfields, IGNORE_MISSING);
 124  
 125      // No run found for runid, warn and exit
 126      if (!$run) {
 127          notice(get_string('cannotfindanyrunforrunid', 'tool_profiling', $runid), 'index.php');
 128      }
 129  
 130      // Check if there is any previous run marked as reference one
 131      $prevreferences = $DB->get_records_select('profiling',
 132                                                'url = ? AND runreference = 1 AND timecreated < ?',
 133                                                array($run->url, $run->timecreated),
 134                                                'timecreated DESC', 'runid, runcomment, timecreated', 0, 10);
 135      echo $OUTPUT->box_start('generalbox boxwidthwide boxaligncenter');
 136      $header = get_string('summaryof', 'tool_profiling', $run->url);
 137      echo $OUTPUT->heading($header);
 138      $table = profiling_print_run($run, $prevreferences);
 139      echo $table;
 140      echo $OUTPUT->box_end();
 141  
 142  
 143  // Default: List one page of runs
 144  } else {
 145  
 146      // The flexitable that will root listings
 147      $table = new xhprof_table_sql('profiling-list-table');
 148      $baseurl = $CFG->wwwroot . '/'.$CFG->admin.'/tool/profiling/index.php';
 149  
 150      // Check if we are listing all or some URL ones
 151      $sqlconditions = '';
 152      $sqlparams = array();
 153      if (!isset($listurl)) {
 154          $header = get_string('pluginname', 'tool_profiling');
 155          $sqlconditions = '1 = 1';
 156          $table->set_listurlmode(false);
 157      } else {
 158          $header =  get_string('profilingrunsfor', 'tool_profiling', $listurl);
 159          $sqlconditions = 'url = :url';
 160          $sqlparams['url'] = $listurl;
 161          $table->set_listurlmode(true);
 162          $baseurl .= '?listurl=' . urlencode($listurl);
 163      }
 164  
 165      echo $OUTPUT->heading($header);
 166  
 167      // Print the controller block with different options.
 168      echo profiling_list_controls($listurl);
 169  
 170      // TODO: Fix flexitable to validate tsort/thide/tshow/tifirs/tilast/page
 171      // TODO: Fix table_sql to allow it to work without WHERE clause
 172      // add silly condition (1 = 1) because of table_sql bug
 173      $table->set_sql($dbfields, '{profiling}', $sqlconditions, $sqlparams);
 174      $table->set_count_sql("SELECT COUNT(*) FROM {profiling} WHERE $sqlconditions", $sqlparams);
 175      $columns = array(
 176          'url', 'timecreated', 'totalexecutiontime', 'totalcputime',
 177          'totalcalls', 'totalmemory', 'runcomment');
 178      $headers = array(
 179          get_string('url'), get_string('date'), get_string('executiontime', 'tool_profiling'),
 180          get_string('cputime', 'tool_profiling'), get_string('calls', 'tool_profiling'),
 181          get_string('memory', 'tool_profiling'), get_string('comment', 'tool_profiling'));
 182      $table->define_columns($columns);
 183      $table->define_headers($headers);
 184      $table->sortable(true, 'timecreated', SORT_DESC);
 185      $table->define_baseurl($baseurl);
 186      $table->column_suppress('url');
 187      $table->out(PROFILING_RUNSPERPAGE, true);
 188  }
 189  
 190  // Footer.
 191  echo $OUTPUT->footer();
 192