Subversion Repositories web.creative

Rev

Blame | Last modification | View Log | Download

<?php namespace ProcessWire; 

/** @var Config $config */
/** @var Pages $pages */
/** @var Sanitizer $sanitizer */
/** @var Session $session */
/** @var WireInput $input */
/** @var Fuel $fuel */
/** @var Modules $modules */
/** @var WireDatabasePDO $database */
/** @var DatabaseMysqli $db */
/** @var User $user */
/** @var Page $page */
/** @var WireCache $cache */
/** @var WireClassLoader $classLoader */

if(!defined("PROCESSWIRE")) die(); 
$debugToolsLabel = __('Debug Mode Tools', __FILE__);

echo 
  "<p><a class='pw-panel' data-panel-id='debug' data-panel-width='75%' " . 
  "data-tab-text='$debugToolsLabel' data-tab-icon='bug' data-tab-offset='200' " . 
  "id='debug_toggle' href='#debug'><i class='fa fa-bug'></i> $debugToolsLabel</a></p>";

?>

<div id="debug">
  
<?php foreach($config->debugTools as $tool): ?>

  <?php if($tool == 'pages'): ?>
    <?php
    $o = '';
    $oc = 0;
    $oct = $pages->loader()->getTotalPagesLoaded();
    foreach($pages->getCache() as $p) {
      $oc++;
      $parts = explode('/', trim($p->path, '/'));
      $name = array_pop($parts);
      $path = implode('/', $parts) . "/$name/";
      $path = '/' . ltrim($path, '/');
      $path = str_replace("/$name/", "/<b>$name</b>/", $path);
      $o .= "\n<tr>" .
        "<td>$p->id</td>" .
        "<td>$path</td>" .
        "<td>" . wireClassName($p) . "</td>" .
        ($config->debug === Config::debugVerbose ? "<td>" . $sanitizer->entities($p->_debug_loader) . "</td>" : "") .
        "</tr>";
    }
    $occ = $oct > $oc ? "$oc/$oct" : $oc;
    ?>
    <div class="container">
      <h3><a href='#'><?php echo __('Pages Loaded', __FILE__) . " <span class='ui-priority-secondary'>($occ)</span>"; ?></a></h3>
      <div>
      <table>
      <thead>
      <tr>
      <th>ID</th>
      <th>Path</th>
      <th>Type</th>
      <?php if($config->debug === Config::debugVerbose) echo "<th>Loader</th>"; ?>
      </tr>
      </thead>
      <tbody>
      <?php 
      echo $o; 
      if($oct > $oc) echo "<p>A total of <strong>$oct</strong> pages were loaded, <strong>$oc</strong> of which are in memory:</p>";
      unset($o, $oc, $oct, $occ); 
      ?> 
      </tbody>
      </table>
      </div>
    </div>
  <?php endif; ?>

  <?php if($tool == 'api'): ?>
    <?php
    $o = '';
    $oc = 0;
    $apiVars = array();
    foreach($fuel as $key => $value) {
      if(!is_object($value)) continue;
      $apiVars[$key] = $value; 
    }
    ksort($apiVars);
    foreach($apiVars as $key => $value) {
      $oc++;
      $o .= "\n" . 
        "<tr>" . 
        "<td><a target='_blank' href='https://processwire.com/api/ref/$key/'>\$$key</a></td>" .
        "<td>" . get_class($value) . "</td>" . 
        "</tr>";
    }
    unset($apiVars);
    ?>
    <div class="container">
      <h3><a href='#'><?php echo __('API Variables', __FILE__) . " <span class='ui-priority-secondary'>($oc)</span>"; ?></a></h3>
      <div>
      <table>
      <thead>
      <tr>
      <th>Name</th>
      <th>Class</th>
      </tr>
      </thead>
      <tbody>
      <?php echo $o; unset($o, $oc); ?>
      </tbody>
      </table>
      </div>
    </div>
  <?php endif; ?>

  <?php if($tool == 'session'): ?>
    <?php
    $o = ''; $oc = 0;
    foreach($session as $key => $value) {
      if(is_object($value)) $value = (string) $value;
      if(is_array($value)) $value = print_r($value, true);
      $oc++;
      $o .= "<tr><td>$key</td><td><pre>" . $sanitizer->entities($value) . "</pre></td></tr>";
    } 
    ?>
    <div class="container">
      <h3><a href='#'><?php echo __('Session', __FILE__) . " <span class='ui-priority-secondary'>($oc)</span>"; ?></a></h3>
      <div>
      <table>
      <thead>
      <tr>
      <th>Key</th>
      <th>Value</th>
      </tr>
      </thead>
      <tbody>
      <?php echo $o; unset($o, $oc); ?>
      </tbody>
      </table>
      </div>
    </div>
  <?php endif; ?>

  <?php if($tool == 'modules'): ?>
    <?php
    $o = '';
    $numLoaded = 0;
    $numSkipped = 0;
    foreach($modules as $module) {
      if($module instanceof ModulePlaceholder) {
        $numSkipped++;
        continue;
      }
      $numLoaded++;
      $info = $modules->getModuleInfo($module, array('verbose' => false));
      $o .= 
        "<tr>" . 
        "<td>$info[name]</td>" . 
        "<td>$info[version]</td>" . 
        "<td>$info[title]</td>" . 
        "</tr>";
    }
    
    ?>
    <div class="container">
      <h3><a href='#'><?php echo __('Modules Loaded', __FILE__) . " <span class='ui-priority-secondary'>($numLoaded/$numSkipped)</span>"; ?></a></h3>
      <div>
      <table>
      <thead>
      <tr>
      <th>Class</th>
      <th>Version</th>
      <th>Title</th>
      </tr>
      </thead>
      <tbody>
      <?php echo $o; unset($o); ?>
      </tbody>
      </table>
      <p class='description'><?php echo 
        sprintf(__('%d modules loaded', __FILE__), $numLoaded) . ' / ' . 
        sprintf(__('%d not loaded', __FILE__), $numSkipped); 
        unset($numLoaded, $numSkipped);
      ?></p>
      </div>
    </div>
  <?php endif; ?>

  <?php if($tool == 'hooks'): ?>
    <?php
    $o = '';
    $oc = 0;
    $hooks = array_merge($this->wire()->getHooks('*'), $this->wire('hooks')->getAllLocalHooks());
    $hooksSorted = array();
    foreach($hooks as $hook) {
      $whenKey = $hook['options']['before'] ? '0' : '1';
      $sortKey = $hook['options']['fromClass'] . ":$hook[method]:$whenKey:" . $hook['options']['priority'];
      $hooksSorted[$sortKey] = $hook;
      $oc++;
    }
    ksort($hooksSorted);
    foreach($hooksSorted as $key => $hook) {
      $suffix = $hook['options']['type'] == 'method' ? '()' : '';
      $toObject = !empty($hook['toObject']) ? $hook['toObject'] : '';
      $toMethod = $hook['toMethod'];
      if(is_callable($toMethod)) $toMethod = 'anonymous function';
      $o .= 
        "<tr>" . 
        "<td>" . ($hook['options']['before'] ? 'before ' : '') . ($hook['options']['after'] ? 'after' : '') . "</td>" . 
        "<td>" . ($hook['options']['fromClass'] ? $hook['options']['fromClass'] . '::' : '') . "$hook[method]$suffix</td>" . 
        "<td>" . ($toObject ? "$toObject::$toMethod" : $toMethod) . "()</td>" . 
        "<td>" . ($hook['options']['allInstances'] || $hook['options']['fromClass'] ? "class " : "instance ") . $hook['options']['type'] . "</td>" . 
        "<td>" . $hook['options']['priority'] . "</td>" . 
        "</tr>";
    }
    
    ?>
    <div class="container">
      <h3><a href='#'><?php echo __('Hooks', __FILE__) . " <span class='ui-priority-secondary'>($oc)</span>"; ?></a></h3>
      <div>
      <table>
      <thead>
      <tr>
      <th>When</th>
      <th>Method::object</th>
      <th>Visited by</th>
      <th>Type</th>
      <th>Priority</th>
      </tr>
      </thead>
      <tbody>
      <?php echo $o; unset($o, $oc); ?>
      </tbody>
      </table>
      </div>
    </div>
  <?php endif; ?>

  <?php if($tool == 'database'): ?>
    <?php
    $o = '';
    $oc = 0;
    foreach($database->queryLog() as $n => $sql) {
      $oc++;
      $sql = $sanitizer->entities1($sql);
      $o .= "\n<tr><th>$n</th><td>$sql</td></tr>";
    }
    ?>
    <div class="container">
      <h3><a href='#'><?php echo __('PDO Queries ($database)', __FILE__) . " <span class='ui-priority-secondary'>($oc)</span>"; ?></a></h3>
      <div>
      <table>
      <tbody>
      <?php echo $o; unset($o, $oc); ?>
      </tbody>
      </table>
      </div>
    </div>
  <?php endif; ?>

  <?php if($tool == 'timers'): ?>
    <?php
    $o = ''; $oc = 0;
    $timers = Debug::getSavedTimers();
    foreach($timers as $name => $timer) {
      $o .= "<tr><th>$name</th><td>$timer</td></tr>";
      $oc++;
    }
    ?>
    <div class="container">
      <h3><a href='#'><?php echo __('Timers', __FILE__) . " <span class='ui-priority-secondary'>($oc)</span>"; ?></a></h3>
      <div>
        <table>
          <tbody>
          <?php echo $o; unset($o, $oc); ?>
          </tbody>
        </table>
        <p class='description'>To add more timers here&hellip;</p>
        <pre>
Debug::timer('timer-name'); // start timer, you make up the name
execute_some_code(); // any amount of code you want to time
Debug::saveTimer('timer-name', 'optional notes'); // stop and save timer
        </pre>
      </div>
    </div>
  <?php endif; ?>

  <?php if($tool == 'db' && $db->isInstantiated()): ?>
    <?php
    $queries = Database::getQueryLog();
    $oc = count($queries);
    ?>
    <div class="container">
      <h3><a href='#'><?php echo __('MySQLi Queries ($db) - Deprecated', __FILE__) . " <span class='ui-priority-secondary'>($oc)</span>"; ?></a></h3>
      <div>
      <?php
      if(count($queries)): ?>
      <p>Mysqli was instantiated and queries were made. These should ideally be converted to PDO ($database). Here are the queries:</p>
      <table>
      <tbody>
      <?php 
      foreach($queries as $n => $sql) {
        $sql = $sanitizer->entities1($sql);
        echo "\n<tr><th>$n</th><td>$sql</td></tr>";
      }
      ?>
      </tbody>
      </table>
      <?php else: ?>
      <p>Mysqli was instantiated but no queries executed. Here are the callers that should be converted to PDO:</p>
      <ul><?php foreach($db->getCallers() as $n => $caller) echo "<li>" . ($n+1) . ". $caller</li>"; ?></ul>
      <?php
      endif; 
      unset($queries, $oc, $sql);
      ?>
      </div>
    </div>
  <?php endif; ?>

  <?php if($tool == 'user'): ?>
    <div class="container">
      <h3><a href='#'><?php echo __('User', __FILE__); ?> <span class='ui-priority-secondary'>(<?php echo $user->name;?>)</span></a></h3>
      <div>
      <h4><?php echo __('Current User Roles', __FILE__); ?></h4>
      <ol>
      <?php foreach($user->roles as $role) echo "\n<li>{$role->name}</li>"; ?>
      </ol>
      <h4><?php echo __('Current User Permissions', __FILE__); ?></h4>
      <ol>
      <?php foreach($user->getPermissions() as $permission) echo "\n<li>{$permission->name}</li>"; ?>
      </ol>
      <h4><?php echo __('Current User Permissions on this page', __FILE__); ?></h4>
      <ol>
      <?php foreach($user->getPermissions($page) as $permission) echo "\n<li>{$permission->name}</li>"; ?>
      </ol>
      </div>
    </div>
  <?php endif; ?>

  <?php if($tool == 'input'):
    foreach(array('get', 'post', 'cookie') as $type): 
      $i = $input->$type; 
      $oc = count($i);
      if(!$oc) continue; 
      ?>
      <div class="container">
        <h3><a href='#'>$input-><?php echo $type . " <span class='ui-priority-secondary'>($oc)</span>"; ?></a></h3>
        <div>
        <table>
        <thead>
        <tr>
        <th>Key</th>
        <th>Value</th>
        </tr>
        </thead>
        <tbody>
        <?php 
        foreach($i as $key => $value) {
          if(is_array($value)) $value = print_r($value, true); 
          echo "<tr><td>" . $sanitizer->entities($key) . "</td><td><pre>" . $sanitizer->entities($value) . "</pre></td></tr>";
        } 
        unset($oc, $i);
        ?>
        </tbody>
        </table>
        </div>
      </div>
    <?php endforeach; ?>
  <?php endif; ?>
  
  <?php if($tool == 'cache'): ?>
    <?php
    $o = '';  
    $oc = 0;
    foreach($cache->getInfo(true, array(), array('FileCompiler', 'Modules', 'Permissions.')) as $info) {
      $oc++;
      $o .= "<table class=''><thead><tr><th colspan='2'>";
      $o .= $sanitizer->entities($info['name']) . "</th></tr></thead><tbody>";
      foreach($info as $key => $value) {
        if($key == 'name') continue;
        if($key == 'size') $value = wireBytesStr($value);
        $key = $sanitizer->entities($key);
        $value = $sanitizer->entities($value);
        $o .= "<tr><th width='30%'>$key</th><td>$value</td></tr>";
      }
      $o .= "</tbody></table><br />";
    }
    ?>
    <div class="container">
      <h3><a href='#'><?php echo __('Cache') . " <span class='ui-priority-secondary'>($oc)</span>"; ?></a></h3>
      <div>
        <?php echo $o; unset($o, $oc); ?>
      </div>
    </div>
  <?php endif; ?>
  
  <?php if($tool == 'autoload'): ?>
    <?php
    $oc = 0;
    $o = "<table class=''><thead><th>Class</th><th>File/Details</th><tbody>";
    foreach($classLoader->getDebugLog() as $className => $classFile) {
      $oc++;
      $className = $sanitizer->entities($className);
      $classFile = $sanitizer->entities($classFile);
      $o .= "<tr><th width='40%'>$className</th><td>$classFile</td></tr>";
    }
    $o .= "</tbody></table><br />";
    ?>
    <div class="container">
      <h3><a href='#'><?php echo __('Autoload') . " <span class='ui-priority-secondary'>($oc)</span>"; ?></a></h3>
      <div>
        <?php echo $o; unset($o, $oc); ?>
      </div>
    </div>
  <?php endif; ?> 
  
<?php endforeach; ?>
  
<p class='detail' style='margin: 0; padding: 0.25em 1em;'>
  <?php echo __('Do not leave debug mode enabled in live/production environments (see $config->debug in file /site/config.php).'); ?>
</p>
  
</div><!--/#debug-->

<script type="text/javascript">
  $(document).ready(function() {
    var $debug = $("#debug");
    function initDebugAccordion() {
      $debug.accordion({
        active: false,
        header: 'h3',
        collapsible: true,
        heightStyle: 'content'
      });
    }
    if(typeof pwPanels == "undefined" || $('body').hasClass('touch')) {
      initDebugAccordion();
      $debug.hide();
      $("#debug_toggle").click(function() {
        if($debug.is(":hidden")) {
          $debug.slideDown();
        } else {
          $debug.slideUp();
        }
        $('html, body').animate({ scrollTop: $(document).height() },'50');
        return false;
      }); 
    } else {
      $debug.on('pw-panel-init', function() {
        console.log('pw-panel-init');
        initDebugAccordion();
      });
    }
  }); 
</script>