From 29055d34d6f0ceee253a4122bb6c9dae6cb53b2b Mon Sep 17 00:00:00 2001
From: Dries Buytaert <dries@buytaert.net>
Date: Fri, 27 Apr 2007 07:42:54 +0000
Subject: [PATCH] - Patch #137236 by merlinofchaos: provide a way to secure the
 theme variables system.

---
 includes/common.inc                           |   4 +
 includes/theme.inc                            | 387 +++++++++++-------
 modules/comment/comment.module                |  27 +-
 modules/comment/comment.tpl.php               |  25 ++
 modules/node/node.tpl.php                     |  29 ++
 modules/system/block.tpl.php                  |   8 +
 modules/system/box.tpl.php                    |   8 +
 modules/system/page.tpl.php                   |  60 +++
 themes/engines/phptemplate/phptemplate.engine | 221 +---------
 themes/garland/template.php                   |   2 +-
 10 files changed, 387 insertions(+), 384 deletions(-)
 create mode 100644 modules/comment/comment.tpl.php
 create mode 100644 modules/node/node.tpl.php
 create mode 100644 modules/system/block.tpl.php
 create mode 100644 modules/system/box.tpl.php
 create mode 100644 modules/system/page.tpl.php

diff --git a/includes/common.inc b/includes/common.inc
index a6e4ef381137..ea1a21a17793 100644
--- a/includes/common.inc
+++ b/includes/common.inc
@@ -2314,6 +2314,7 @@ function drupal_common_themes() {
     ),
     'page' => array(
       'arguments' => array('content' => NULL, 'show_blocks' => TRUE),
+      'file' => 'page',
     ),
     'maintenance_page' => array(
       'arguments' => array('content' => NULL, 'messages' => TRUE),
@@ -2341,6 +2342,7 @@ function drupal_common_themes() {
     ),
     'node' => array(
       'arguments' => array('node' => NULL, 'teaser' => FALSE, 'page' => FALSE),
+      'file' => 'node',
     ),
     'submenu' => array(
       'arguments' => array('links' => NULL),
@@ -2356,9 +2358,11 @@ function drupal_common_themes() {
     ),
     'box' => array(
       'arguments' => array('title' => NULL, 'content' => NULL, 'region' => 'main'),
+      'file' => 'box',
     ),
     'block' => array(
       'arguments' => array('block' => NULL),
+      'file' => 'block',
     ),
     'mark' => array(
       'arguments' => array('type' => MARK_NEW),
diff --git a/includes/theme.inc b/includes/theme.inc
index 230bb20da276..c3e8253cdf9b 100644
--- a/includes/theme.inc
+++ b/includes/theme.inc
@@ -166,6 +166,32 @@ function _theme_process_registry(&$cache, $name, $type) {
       if (!isset($info['arguments']) && isset($cache[$hook])) {
         $result[$hook]['arguments'] = $cache[$hook]['arguments'];
       }
+      // Check for default _preprocess_ functions. Ensure arrayness.
+      if (!isset($info['preprocess functions']) || !is_array($info['preprocess functions'])) {
+        $info['preprocess functions'] = array();
+        $prefix = ($type == 'module' ? 'template' : $name);
+        // It would be too much of a performance hit to let every module have
+        // a generic preprocess function; themes and theme engines can do that.
+        if ($type != 'module' && function_exists($prefix .'_preprocess')) {
+          $info['preprocess functions'][] = $prefix .'_preprocess';
+        }
+        if (function_exists($prefix .'_preprocess_'. $hook)) {
+          $info['preprocess functions'][] = $prefix .'_preprocess_'. $hook;
+        }
+        // theme engines get an extra set.
+        if ($type == 'theme_engine') {
+          if (function_exists($prefix .'_engine_preprocess')) {
+            $info['preprocess functions'][] = $prefix .'_engine_preprocess';
+          }
+          if (function_exists($prefix .'_engine_preprocess_'. $hook)) {
+            $info['preprocess functions'][] = $prefix .'_engine_preprocess_'. $hook;
+          }
+        }
+      }
+      if (isset($cache[$hook]['preprocess functions']) && is_array($cache[$hook]['preprocess functions']) && empty($cache[$hook]['override preprocess functions'])) {
+        $info['preprocess functions'] = array_merge($cache[$hook]['preprocess functions'], $info['preprocess functions']);
+      }
+      $result[$hook]['preprocess functions'] = $info['preprocess functions'];
     }
 
     $cache = array_merge($cache, $result);
@@ -264,24 +290,30 @@ function list_theme_engines($refresh = FALSE) {
  * applicable) and the theme. The following functions may be used to modify
  * the $variables array:
  *
- * ENGINE_engine_variables(&$variables)
+ * ENGINE_engine_preprocess(&$variables)
  *   This function should only be implemented by theme engines and is exists
  *   so that the theme engine can set necessary variables. It is commonly
  *   used to set global variables such as $directory and $is_front_page.
- * ENGINE_engine_variables_HOOK(&$variables)
+ * ENGINE_engine_preprocess_HOOK(&$variables)
  *   This is the same as the previous function, but is called only per hook.
- * ENGINE_variables_HOOK(&$variables)
- * ENGINE_variables(&$variables)
+ * ENGINE_preprocess_HOOK(&$variables)
+ * ENGINE_preprocess(&$variables)
  *   This is meant to be used by themes that utilize a theme engine; as it is
  *   good practice for these themes to use the theme engine's name for
  *   their functions so that they may share code. In PHPTemplate, these
  *   functions will appear in template.php
- * THEME_variables_HOOK(&$variables)
- * THEME_variables(&$variables)
+ * THEME_preprocess_HOOK(&$variables)
+ * THEME_preprocess(&$variables)
  *   These functions are based upon the raw theme; they should primarily be
  *   used by themes that do not use an engine or by themes that need small
  *   changes to what has already been established in the theme engine version
  *   of the function.
+ * template_preprocess(&$variables)
+ *   This function will only be called for theme functions registered by
+ *   the named module. In general it is preferred to use the following
+ *   function if possible, but it may not always be the case.
+ * template_preprocess_HOOK(&$variables)
+ *   This is the same as the previous function, but is called only per hook.
  *
  * There are two special variables that these hooks can set:
  *   'template_file' and 'template_files'. These will be merged together
@@ -337,18 +369,10 @@ function theme() {
     // default render function and extension.
     $render_function = 'theme_render_template';
     $extension = '.tpl.php';
-    $variables_list = array();
 
     // Run through the theme engine variables, if necessary
     global $theme_engine;
     if (isset($theme_engine)) {
-      // Call each of our variable override functions. We allow
-      // several to create cleaner code.
-      $variables_list[] = $theme_engine .'_engine_variables';
-      $variables_list[] = $theme_engine .'_engine_variables_'. $hook;
-      $variables_list[] = $theme_engine .'_variables';
-      $variables_list[] = $theme_engine .'_variables_'. $hook;
-
       // If theme or theme engine is implementing this, it may have
       // a different extension and a different renderer.
       if ($hooks[$hook]['type'] != 'module') {
@@ -362,17 +386,14 @@ function theme() {
       }
     }
 
-    // Add theme specific variable substitution:
-    global $theme;
-    $variables_list[] = $theme .'_variables';
-    $variables_list[] = $theme .'_variables_'. $hook;
-
-    // This construct ensures that we can keep a reference through
-    // call_user_func_array.
-    $args = array(&$variables, $hook);
-    foreach ($variables_list as $variables_function) {
-      if (function_exists($variables_function)) {
-        call_user_func_array($variables_function, $args);
+    if (isset($info['preprocess functions']) && is_array($info['preprocess functions'])) {
+      // This construct ensures that we can keep a reference through
+      // call_user_func_array.
+      $args = array(&$variables, $hook);
+      foreach ($info['preprocess functions'] as $preprocess_function) {
+        if (function_exists($preprocess_function)) {
+          call_user_func_array($preprocess_function, $args);
+        }
       }
     }
 
@@ -654,56 +675,6 @@ function theme_placeholder($text) {
   return '<em>'. check_plain($text) .'</em>';
 }
 
-/**
- * Return an entire Drupal page displaying the supplied content.
- *
- * @param $content
- *   A string to display in the main content area of the page.
- * @return
- *   A string containing the entire HTML page.
- */
-function theme_page($content) {
-  // Get blocks before so that they can alter the header (JavaScript, Stylesheets etc.)
-  $blocks = theme('blocks', 'all');
-
-  $output = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n";
-  $output .= '<html xmlns="http://www.w3.org/1999/xhtml">';
-  $output .= '<head>';
-  $output .= ' <title>'. (drupal_get_title() ? strip_tags(drupal_get_title()) : variable_get('site_name', 'Drupal')) .'</title>';
-  $output .= drupal_get_html_head();
-  $output .= drupal_get_css();
-  $output .= drupal_get_js();
-
-  $output .= ' </head>';
-  $output .= ' <body style="background-color: #fff; color: #000;">';
-  $output .= '<table border="0" cellspacing="4" cellpadding="4"><tr><td style="vertical-align: top; width: 170px;">';
-
-  $output .= $blocks;
-  $output .= '</td><td style="vertical-align: top;">';
-
-  $output .= theme('breadcrumb', drupal_get_breadcrumb());
-  $output .= '<h1>'. drupal_get_title() .'</h1>';
-
-  if ($tabs = theme('menu_local_tasks')) {
-   $output .= $tabs;
-  }
-
-  $output .= theme('help');
-
-  $output .= theme('status_messages');
-
-  $output .= "\n<!-- begin content -->\n";
-  $output .= $content;
-  $output .= drupal_get_feeds();
-  $output .= "\n<!-- end content -->\n";
-
-  $output .= '</td></tr></table>';
-  $output .= theme('closure');
-  $output .= '</body></html>';
-
-  return $output;
-}
-
 /**
  * Generate a themed maintenance page.
  *
@@ -954,66 +925,6 @@ function theme_help() {
   }
 }
 
-/**
- * Return a themed node.
- *
- * @param $node
- *   An object providing all relevant information for displaying a node:
- *   - $node->nid: The ID of the node.
- *   - $node->type: The content type (story, blog, forum...).
- *   - $node->title: The title of the node.
- *   - $node->created: The creation date, as a UNIX timestamp.
- *   - $node->teaser: A shortened version of the node body.
- *   - $node->body: The entire node contents.
- *   - $node->changed: The last modification date, as a UNIX timestamp.
- *   - $node->uid: The ID of the author.
- *   - $node->username: The username of the author.
- * @param $teaser
- *   Whether to display the teaser only, as on the main page.
- * @param $page
- *   Whether to display the node as a standalone page. If TRUE, do not display
- *   the title because it will be provided by the menu system.
- * @return
- *   A string containing the node output.
- */
-function theme_node($node, $teaser = FALSE, $page = FALSE) {
-  if (!$node->status) {
-    $output  = '<div class="node-unpublished">';
-  }
-
-  if (module_exists('taxonomy')) {
-    $terms = taxonomy_link('taxonomy terms', $node);
-  }
-
-  if ($page == 0) {
-    $output .= t('!title by !name', array('!title' => '<h2 class="title">'. check_plain($node->title) .'</h2>', '!name' => theme('username', $node)));
-  }
-  else {
-    $output .= t('by !name', array('!name' => theme('username', $node)));
-  }
-
-  if (count($terms)) {
-    $output .= ' <small>('. theme('links', $terms) .')</small><br />';
-  }
-
-  if ($teaser && $node->teaser) {
-    $output .= $node->teaser;
-  }
-  else {
-    $output .= $node->body;
-  }
-
-  if ($node->links) {
-    $output .= '<div class="links">'. theme('links', $node->links) .'</div>';
-  }
-
-  if (!$node->status) {
-    $output .= '</div>';
-  }
-
-  return $output;
-}
-
 /**
  * Return a themed submenu, typically displayed under the tabs.
  *
@@ -1182,29 +1093,6 @@ function theme_box($title, $content, $region = 'main') {
   return $output;
 }
 
-/**
- * Return a themed block.
- *
- * You can style your blocks by defining .block (all blocks),
- * .block-<i>module</i> (all blocks of module <i>module</i>), and
- * \#block-<i>module</i>-<i>delta</i> (specific block of module <i>module</i>
- * with delta <i>delta</i>) in your theme's CSS.
- *
- * @param $block
- *   An object populated with fields from the "blocks" database table
- *   ($block->module, $block->delta ...) and fields returned by
- *   <i>module</i>_block('view') ($block->subject, $block->content, ...).
- * @return
- *   A string containing the block output.
- */
-function theme_block($block) {
-  $output  = "<div class=\"block block-$block->module\" id=\"block-$block->module-$block->delta\">\n";
-  $output .= " <h2 class=\"title\">$block->subject</h2>\n";
-  $output .= " <div class=\"content\">$block->content</div>\n";
-  $output .= "</div>\n";
-  return $output;
-}
-
 /**
  * Return a themed marker, useful for marking new or updated
  * content.
@@ -1432,3 +1320,186 @@ function _theme_table_cell($cell, $header = FALSE) {
   return $output;
 }
 
+/**
+ * Prepare the variables passed to the page.tpl.php template. Uses the arg()
+ * function to generate a series of page template files suggestions based on
+ * the current path.
+ */
+function template_preprocess_page(&$variables) {
+  /* Set title and breadcrumb to declared values */
+  if (drupal_is_front_page()) {
+    $variables['mission'] = filter_xss_admin(theme_get_setting('mission'));
+  }
+
+  /* Add favicon */
+  if (theme_get_setting('toggle_favicon')) {
+    drupal_set_html_head('<link rel="shortcut icon" href="'. check_url(theme_get_setting('favicon')) .'" type="image/x-icon" />');
+  }
+
+  /**
+  * Populate sidebars.
+  */
+  $variables['sidebar_left'] = NULL;
+  $variables['sidebar_right'] = NULL;
+  $layout = 'none';
+  if ($variables['show_blocks']) {
+    global $sidebar_indicator;
+    /**
+     * Sidebar_indicator tells the block counting code to count sidebars separately.
+     */
+    $sidebar_indicator = 'left';
+    $variables['sidebar_left'] = theme('blocks', 'left');
+    if ($variables['sidebar_left'] != '') {
+      $layout = 'left';
+    }
+
+    $sidebar_indicator = 'right';
+    $variables['sidebar_right'] = theme('blocks', 'right');
+    if ($variables['sidebar_right'] != '') {
+      $variables['layout'] = ($layout == 'left') ? 'both' : 'right';
+    }
+    $sidebar_indicator = NULL;
+  }
+  $variables['layout'] = $layout;
+
+  global $theme;
+  // Populate the rest of the regions.
+  $regions = system_region_list($theme);
+  // Load all region content assigned via blocks.
+  foreach (array_keys($regions) as $region) {
+    // Skip blocks in this region that have already been loaded.
+    // This pre-loading is necessary because phptemplate uses variable names different from
+    // the region names, e.g., 'sidebar_left' instead of 'left'.
+    if (!in_array($region, array('left', 'right', 'footer'))) {
+      isset($variables[$region]) ? $variables[$region] .= theme('blocks', $region) : $variables[$region] = theme('blocks', $region);
+    }
+  }
+
+  // Construct page title
+  if (drupal_get_title()) {
+    $head_title = array(strip_tags(drupal_get_title()), variable_get('site_name', 'Drupal'));
+  }
+  else {
+    $head_title = array(variable_get('site_name', 'Drupal'));
+    if (variable_get('site_slogan', '')) {
+      $head_title[] = variable_get('site_slogan', '');
+    }
+  }
+  $variables['head_title']        = implode(' | ', $head_title);
+  $variables['base_path']         = base_path();
+  $variables['breadcrumb']        = theme('breadcrumb', drupal_get_breadcrumb());
+  $variables['closure']           = theme('closure');
+  $variables['feed_icons']        = drupal_get_feeds();
+  $variables['footer_message']    = filter_xss_admin(variable_get('site_footer', FALSE)) . "\n" . theme('blocks', 'footer');
+  $variables['head']              = drupal_get_html_head();
+  $variables['help']              = theme('help');
+  $variables['language']          = $GLOBALS['language'];
+  $variables['logo']              = theme_get_setting('logo');
+  $variables['messages']          = theme('status_messages');
+  $variables['mission']           = isset($mission) ? $mission : '';
+  $variables['primary_links']     = menu_primary_links();
+  $variables['search_box']        = (theme_get_setting('toggle_search') ? drupal_get_form('search_theme_form') : '');
+  $variables['secondary_links']   = menu_secondary_links();
+  $variables['site_name']         = (theme_get_setting('toggle_name') ? variable_get('site_name', 'Drupal') : '');
+  $variables['site_slogan']       = (theme_get_setting('toggle_slogan') ? variable_get('site_slogan', '') : '');
+  $variables['css']               = drupal_add_css();
+  $variables['styles']            = drupal_get_css();
+  $variables['scripts']           = drupal_get_js();
+  $variables['tabs']              = theme('menu_local_tasks');
+  $variables['title']             = drupal_get_title();
+
+  if ((arg(0) == 'node') && is_numeric(arg(1))) {
+    $variables['node'] = node_load(arg(1));
+  }
+
+  // Build a list of suggested template files in order of specificity. One
+  // suggestion is made for every element of the current path, though
+  // numeric elements are not carried to subsequent suggestions. For example,
+  // http://www.example.com/node/1/edit would result in the following
+  // suggestions:
+  //
+  // page-node-edit.tpl.php
+  // page-node-1.tpl.php
+  // page-node.tpl.php
+  // page.tpl.php
+  $i = 0;
+  $suggestion = 'page';
+  $suggestions = array();
+  while ($arg = arg($i++)) {
+    $suggestions[] = $suggestion . '-' . $arg;
+    if (!is_numeric($arg)) {
+      $suggestion .= '-' . $arg;
+    }
+  }
+  if (drupal_is_front_page()) {
+    $suggestions[] = 'page-front';
+  }
+
+  if ($suggestions) {
+    $variables['template_files'] = $suggestions;
+  }
+}
+
+/*
+ * Prepare the values passed to the theme_node function to be passed
+ * into standard template files.
+ */
+function template_preprocess_node(&$variables) {
+  $node = $variables['node'];
+  if (module_exists('taxonomy')) {
+    $variables['taxonomy'] = taxonomy_link('taxonomy terms', $node);
+  }
+  else {
+    $variables['taxonomy'] = array();
+  }
+
+  if ($variables['teaser'] && $node->teaser) {
+    $variables['content'] = $node->teaser;
+  }
+  elseif (isset($node->body)) {
+    $variables['content'] = $node->body;
+  }
+  else {
+    $variables['content'] = '';
+  }
+
+  $variables['date']      = format_date($node->created);
+  $variables['links']     = !empty($node->links) ? theme('links', $node->links, array('class' => 'links inline')) : '';
+  $variables['name']      = theme('username', $node);
+  $variables['node_url']  = url('node/'. $node->nid);
+  $variables['terms']     = theme('links', $variables['taxonomy'], array('class' => 'links inline'));
+  $variables['title']     = check_plain($node->title);
+
+  // Flatten the node object's member fields.
+  $variables = array_merge((array)$node, $variables);
+
+  // Display info only on certain node types.
+  if (theme_get_setting('toggle_node_info_' . $node->type)) {
+    $variables['submitted'] = t('Submitted by !a on @b.', array('!a' => theme('username', $node), '@b' => format_date($node->created)));
+    $variables['picture'] = theme_get_setting('toggle_node_user_picture') ? theme('user_picture', $node) : '';
+  }
+  else {
+    $variables['submitted'] = '';
+    $variables['picture'] = '';
+  }
+
+  $variables['template_files'][] = 'node-'. $node->type;
+}
+
+/**
+ * Prepare the values passed to the theme_block function to be passed
+ * into a pluggable template engine. Uses block properties to generate a
+ * series of template file suggestions. If none are found, the default
+ * block.tpl.php is used.
+ */
+function template_preprocess_block(&$variables) {
+  global $sidebar_indicator;
+  $count['block_counter'][$sidebar_indicator] = isset($count['block_counter'][$sidebar_indicator]) && is_int($count['block_counter'][$sidebar_indicator]) ? $count['block_counter'][$sidebar_indicator] : 1;
+
+  $variables['block_zebra'] = ($count['block_counter'][$sidebar_indicator] % 2) ? 'odd' : 'even';
+
+  $variables['block_id'] = $count['block_counter'][$sidebar_indicator]++;
+  $variables['template_files'][] = 'block-' . $variables['block']->region;
+  $variables['template_files'][] = 'block-' . $variables['block']->module;
+  $variables['template_files'][] = 'block-' . $variables['block']->module .'-'. $variables['block']->delta;
+}
diff --git a/modules/comment/comment.module b/modules/comment/comment.module
index 8cf30b3dc8bf..1357a3462637 100644
--- a/modules/comment/comment.module
+++ b/modules/comment/comment.module
@@ -162,6 +162,7 @@ function comment_theme() {
     ),
     'comment' => array(
       'arguments' => array('comment' => NULL, 'links' => array()),
+      'file' => 'comment.tpl.php',
     ),
     'comment_folded' => array(
       'arguments' => array('comment' => NULL),
@@ -1811,15 +1812,23 @@ function comment_controls_submit($form_id, $form_values) {
   }
 }
 
-function theme_comment($comment, $links = array()) {
-  $output  = '<div class="comment'. ($comment->status == COMMENT_NOT_PUBLISHED ? ' comment-unpublished' : '') .'">';
-  $output .= '<div class="subject">'. l($comment->subject, $_GET['q'], array('fragment' => "comment-$comment->cid")) .' '. theme('mark', $comment->new) ."</div>\n";
-  $output .= '<div class="credit">'. t('by %a on %b', array('%a' => theme('username', $comment), '%b' => format_date($comment->timestamp))) ."</div>\n";
-  $output .= '<div class="body">'. $comment->comment .'</div>';
-  $output .= theme('user_signature', $comment->signature);
-  $output .= '<div class="links">'. theme('links', $links) .'</div>';
-  $output .= '</div>';
-  return $output;
+/**
+ * Prepare values for comment.tpl.php
+ */
+function template_preprocess_comment(&$variables) {
+  $comment = $variables['comment'];
+  $variables['author']    = theme('username', $comment);
+  $variables['comment']   = $comment;
+  $variables['content']   = $comment->comment;
+  $variables['date']      = format_date($comment->timestamp);
+  $variables['links']     = isset($variables['links']) ? theme('links', $variables['links']) : '';
+  $variables['new']       = $comment->new ? t('new') : '';
+  $variables['picture']   = theme_get_setting('toggle_comment_user_picture') ? theme('user_picture', $comment) : '';
+  $variables['signature'] = $comment->signature;
+  $variables['submitted'] = t('Submitted by !a on @b.',
+                      array('!a' => theme('username', $comment),
+                            '@b' => format_date($comment->timestamp)));
+  $variables['title']     = l($comment->subject, $_GET['q'], array('fragment' => "comment-$comment->cid"));
 }
 
 function theme_comment_folded($comment) {
diff --git a/modules/comment/comment.tpl.php b/modules/comment/comment.tpl.php
new file mode 100644
index 000000000000..ac4eeb88a739
--- /dev/null
+++ b/modules/comment/comment.tpl.php
@@ -0,0 +1,25 @@
+<div class="comment<?php print ($comment->new) ? ' comment-new' : ''; print ($comment->status == COMMENT_NOT_PUBLISHED) ? ' comment-unpublished' : ''; ?> clear-block">
+  <?php print $picture ?>
+
+<?php if ($comment->new) : ?>
+  <a id="new"></a>
+  <span class="new"><?php print $new ?></span>
+<?php endif; ?>
+
+  <h3><?php print $title ?></h3>
+
+  <div class="submitted">
+    <?php print $submitted ?>
+  </div>
+
+  <div class="content">
+    <?php print $content ?>
+    <?php if ($signature): ?>
+    <div class="user-signature clear-block">
+      <?php print $signature ?>
+    </div>
+    <?php endif; ?>
+  </div>
+
+  <?php print $links ?>
+</div>
diff --git a/modules/node/node.tpl.php b/modules/node/node.tpl.php
new file mode 100644
index 000000000000..872ea0c292c1
--- /dev/null
+++ b/modules/node/node.tpl.php
@@ -0,0 +1,29 @@
+<div id="node-<?php print $node->nid; ?>" class="node<?php if ($sticky) { print ' sticky'; } ?><?php if (!$status) { print ' node-unpublished'; } ?> clear-block">
+
+<?php print $picture ?>
+
+<?php if ($page == 0): ?>
+  <h2><a href="<?php print $node_url ?>" title="<?php print $title ?>"><?php print $title ?></a></h2>
+<?php endif; ?>
+
+  <div class="meta">
+  <?php if ($submitted): ?>
+    <span class="submitted"><?php print $submitted ?></span>
+  <?php endif; ?>
+
+  <?php if ($terms): ?>
+    <span class="terms"><?php print $terms ?></span>
+  <?php endif;?>
+  </div>
+
+  <div class="content">
+    <?php print $content ?>
+  </div>
+
+<?php
+  if ($links) {
+    print $links;
+  }
+?>
+
+</div>
\ No newline at end of file
diff --git a/modules/system/block.tpl.php b/modules/system/block.tpl.php
new file mode 100644
index 000000000000..8ba204d40ea5
--- /dev/null
+++ b/modules/system/block.tpl.php
@@ -0,0 +1,8 @@
+<div id="block-<?php print $block->module .'-'. $block->delta; ?>" class="block block-<?php print $block->module ?>">
+
+<?php if ($block->subject): ?>
+  <h2><?php print $block->subject ?></h2>
+<?php endif;?>
+
+  <div class="content"><?php print $block->content ?></div>
+</div>
diff --git a/modules/system/box.tpl.php b/modules/system/box.tpl.php
new file mode 100644
index 000000000000..84d810cf0a7c
--- /dev/null
+++ b/modules/system/box.tpl.php
@@ -0,0 +1,8 @@
+<div class="box">
+
+<?php if ($title): ?>
+  <h2><?php print $title ?></h2>
+<?php endif; ?>
+
+  <div class="content"><?php print $content ?></div>
+</div>
diff --git a/modules/system/page.tpl.php b/modules/system/page.tpl.php
new file mode 100644
index 000000000000..fce977e5fb36
--- /dev/null
+++ b/modules/system/page.tpl.php
@@ -0,0 +1,60 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="<?php print $language->language ?>" xml:lang="<?php print $language->language ?>">
+
+<head>
+  <title><?php print $head_title ?></title>
+  <?php print $head ?>
+  <?php print $styles ?>
+  <?php print $scripts ?>
+  <script type="text/javascript"><?php /* Needed to avoid Flash of Unstyle Content in IE */ ?> </script>
+</head>
+
+<body>
+
+<table border="0" cellpadding="0" cellspacing="0" id="header">
+  <tr>
+    <td id="logo">
+      <?php if ($logo) { ?><a href="<?php print $base_path ?>" title="<?php print t('Home') ?>"><img src="<?php print $logo ?>" alt="<?php print t('Home') ?>" /></a><?php } ?>
+      <?php if ($site_name) { ?><h1 class='site-name'><a href="<?php print $base_path ?>" title="<?php print t('Home') ?>"><?php print $site_name ?></a></h1><?php } ?>
+      <?php if ($site_slogan) { ?><div class='site-slogan'><?php print $site_slogan ?></div><?php } ?>
+    </td>
+    <td id="menu">
+      <?php if (isset($secondary_links)) { ?><?php print theme('links', $secondary_links, array('class' =>'links', 'id' => 'subnavlist')) ?><?php } ?>
+      <?php if (isset($primary_links)) { ?><?php print theme('links', $primary_links, array('class' =>'links', 'id' => 'navlist')) ?><?php } ?>
+      <?php print $search_box ?>
+    </td>
+  </tr>
+  <tr>
+    <td colspan="2"><div><?php print $header ?></div></td>
+  </tr>
+</table>
+
+<table border="0" cellpadding="0" cellspacing="0" id="content">
+  <tr>
+    <?php if ($sidebar_left) { ?><td id="sidebar-left">
+      <?php print $sidebar_left ?>
+    </td><?php } ?>
+    <td valign="top">
+      <?php if ($mission) { ?><div id="mission"><?php print $mission ?></div><?php } ?>
+      <div id="main">
+        <?php print $breadcrumb ?>
+        <h1 class="title"><?php print $title ?></h1>
+        <div class="tabs"><?php print $tabs ?></div>
+        <?php print $help ?>
+        <?php print $messages ?>
+        <?php print $content; ?>
+        <?php print $feed_icons; ?>
+      </div>
+    </td>
+    <?php if ($sidebar_right) { ?><td id="sidebar-right">
+      <?php print $sidebar_right ?>
+    </td><?php } ?>
+  </tr>
+</table>
+
+<div id="footer">
+  <?php print $footer_message ?>
+</div>
+<?php print $closure ?>
+</body>
+</html>
diff --git a/themes/engines/phptemplate/phptemplate.engine b/themes/engines/phptemplate/phptemplate.engine
index 331615967cb2..86f1a002f6bf 100644
--- a/themes/engines/phptemplate/phptemplate.engine
+++ b/themes/engines/phptemplate/phptemplate.engine
@@ -14,18 +14,13 @@ function phptemplate_init($template) {
 }
 
 /**
- * Implementation of hook_themes to tell Drupal what templates the engine
+ * Implementation of hook_theme to tell Drupal what templates the engine
  * and the current theme use. The $existing argument will contain hooks
  * pre-defined by Drupal so that we can use that information if
  * we need to.
  */
 function phptemplate_theme($existing) {
-  $templates = array(
-    'box' => array('file' => 'box'),
-    'node' => array('file' => 'node'),
-    'comment' => array('file' => 'comment'),
-    'block' => array('file' => 'block'),
-  );
+  $templates = array();
 
   // Check for template overrides.
   $files = drupal_system_listing('\.tpl\.php$', path_to_theme(), 'name', 0);
@@ -68,13 +63,12 @@ function phptemplate_templates($directory = 'themes') {
  *
  * Counts how many times certain hooks have been called. Sidebar left / right are special cases.
  *
+ * @param $variables
+ *   A series of key-value value pairs.
  * @param $hook
  *   The name of the theme function being executed.
- * @param $variables
- *   A sequential array of variables passed to the theme function.
  */
-function phptemplate_engine_variables(&$variables, $hook) {
-  global $theme, $sidebar_indicator;
+function phptemplate_engine_preprocess(&$variables, $hook) {
   static $count = array();
 
   // Create variables so anything which is themed can be zebra striped automatically.
@@ -86,208 +80,3 @@ function phptemplate_engine_variables(&$variables, $hook) {
   $variables['directory'] = path_to_theme();
   $variables['is_front'] = drupal_is_front_page();
 }
-
-/**
- * Prepare the variables passed to the page.tpl.php template Uses the arg()
- * function to generate a series of page template files suggestions based on
- * the current path.
- */
-function phptemplate_engine_variables_page(&$variables) {
-  /* Set title and breadcrumb to declared values */
-  if (drupal_is_front_page()) {
-    $variables['mission'] = filter_xss_admin(theme_get_setting('mission'));
-  }
-
-  /* Add favicon */
-  if (theme_get_setting('toggle_favicon')) {
-    drupal_set_html_head('<link rel="shortcut icon" href="'. check_url(theme_get_setting('favicon')) .'" type="image/x-icon" />');
-  }
-
-  /**
-  * Populate sidebars.
-  */
-  $variables['sidebar_left'] = NULL;
-  $variables['sidebar_right'] = NULL;
-  $layout = 'none';
-  if ($variables['show_blocks']) {
-    global $sidebar_indicator;
-    /**
-     * Sidebar_indicator tells the block counting code to count sidebars separately.
-     */
-    $sidebar_indicator = 'left';
-    $variables['sidebar_left'] = theme('blocks', 'left');
-    if ($variables['sidebar_left'] != '') {
-      $layout = 'left';
-    }
-
-    $sidebar_indicator = 'right';
-    $variables['sidebar_right'] = theme('blocks', 'right');
-    if ($variables['sidebar_right'] != '') {
-      $variables['layout'] = ($layout == 'left') ? 'both' : 'right';
-    }
-    $sidebar_indicator = NULL;
-  }
-  $variables['layout'] = $layout;
-
-  global $theme;
-  // Populate the rest of the regions.
-  $regions = system_region_list($theme);
-  // Load all region content assigned via blocks.
-  foreach (array_keys($regions) as $region) {
-    // Skip blocks in this region that have already been loaded.
-    // This pre-loading is necessary because phptemplate uses variable names different from
-    // the region names, e.g., 'sidebar_left' instead of 'left'.
-    if (!in_array($region, array('left', 'right', 'footer'))) {
-      isset($variables[$region]) ? $variables[$region] .= theme('blocks', $region) : $variables[$region] = theme('blocks', $region);
-    }
-  }
-
-  // Construct page title
-  if (drupal_get_title()) {
-    $head_title = array(strip_tags(drupal_get_title()), variable_get('site_name', 'Drupal'));
-  }
-  else {
-    $head_title = array(variable_get('site_name', 'Drupal'));
-    if (variable_get('site_slogan', '')) {
-      $head_title[] = variable_get('site_slogan', '');
-    }
-  }
-  $variables['head_title']        = implode(' | ', $head_title);
-  $variables['base_path']         = base_path();
-  $variables['breadcrumb']        = theme('breadcrumb', drupal_get_breadcrumb());
-  $variables['closure']           = theme('closure');
-  $variables['feed_icons']        = drupal_get_feeds();
-  $variables['footer_message']    = filter_xss_admin(variable_get('site_footer', FALSE)) . "\n" . theme('blocks', 'footer');
-  $variables['head']              = drupal_get_html_head();
-  $variables['help']              = theme('help');
-  $variables['language']          = $GLOBALS['language'];
-  $variables['logo']              = theme_get_setting('logo');
-  $variables['messages']          = theme('status_messages');
-  $variables['mission']           = isset($mission) ? $mission : '';
-  $variables['primary_links']     = menu_primary_links();
-  $variables['search_box']        = (theme_get_setting('toggle_search') ? drupal_get_form('search_theme_form') : '');
-  $variables['secondary_links']   = menu_secondary_links();
-  $variables['site_name']         = (theme_get_setting('toggle_name') ? variable_get('site_name', 'Drupal') : '');
-  $variables['site_slogan']       = (theme_get_setting('toggle_slogan') ? variable_get('site_slogan', '') : '');
-  $variables['css']               = drupal_add_css();
-  $variables['styles']            = drupal_get_css();
-  $variables['scripts']           = drupal_get_js();
-  $variables['tabs']              = theme('menu_local_tasks');
-  $variables['title']             = drupal_get_title();
-
-  if ((arg(0) == 'node') && is_numeric(arg(1))) {
-    $variables['node'] = node_load(arg(1));
-  }
-
-  // Build a list of suggested template files in order of specificity. One
-  // suggestion is made for every element of the current path, though
-  // numeric elements are not carried to subsequent suggestions. For example,
-  // http://www.example.com/node/1/edit would result in the following
-  // suggestions:
-  //
-  // page-node-edit.tpl.php
-  // page-node-1.tpl.php
-  // page-node.tpl.php
-  // page.tpl.php
-  $i = 0;
-  $suggestion = 'page';
-  $suggestions = array();
-  while ($arg = arg($i++)) {
-    $suggestions[] = $suggestion . '-' . $arg;
-    if (!is_numeric($arg)) {
-      $suggestion .= '-' . $arg;
-    }
-  }
-  if (drupal_is_front_page()) {
-    $suggestions[] = 'page-front';
-  }
-
-  if ($suggestions) {
-    $variables['template_files'] = $suggestions;
-  }
-}
-
-/*
- * Prepare the values passed to the theme_node function to be passed
- * into standard template files.
- */
-function phptemplate_engine_variables_node(&$variables) {
-  $node = $variables['node'];
-  if (module_exists('taxonomy')) {
-    $variables['taxonomy'] = taxonomy_link('taxonomy terms', $node);
-  }
-  else {
-    $variables['taxonomy'] = array();
-  }
-
-  if ($variables['teaser'] && $node->teaser) {
-    $variables['content'] = $node->teaser;
-  }
-  elseif (isset($node->body)) {
-    $variables['content'] = $node->body;
-  }
-  else {
-    $variables['content'] = '';
-  }
-
-  $variables['date']      = format_date($node->created);
-  $variables['links']     = !empty($node->links) ? theme('links', $node->links, array('class' => 'links inline')) : '';
-  $variables['name']      = theme('username', $node);
-  $variables['node_url']  = url('node/'. $node->nid);
-  $variables['terms']     = theme('links', $variables['taxonomy'], array('class' => 'links inline'));
-  $variables['title']     = check_plain($node->title);
-
-  // Flatten the node object's member fields.
-  $variables = array_merge((array)$node, $variables);
-
-  // Display info only on certain node types.
-  if (theme_get_setting('toggle_node_info_' . $node->type)) {
-    $variables['submitted'] = t('Submitted by !a on @b.', array('!a' => theme('username', $node), '@b' => format_date($node->created)));
-    $variables['picture'] = theme_get_setting('toggle_node_user_picture') ? theme('user_picture', $node) : '';
-  }
-  else {
-    $variables['submitted'] = '';
-    $variables['picture'] = '';
-  }
-
-  $variables['template_files'][] = 'node-'. $node->type;
-}
-
-/**
- * Prepare the values passed to the theme_comment function to be passed
- * into a pluggable template engine.
- */
-// function phptemplate_comment($comment, $links = 0) {
-function phptemplate_engine_variables_comment(&$variables) {
-  $comment = $variables['comment'];
-  $variables['author']    = theme('username', $comment);
-  $variables['comment']   = $comment;
-  $variables['content']   = $comment->comment;
-  $variables['date']      = format_date($comment->timestamp);
-  $variables['links']     = isset($variables['links']) ? theme('links', $variables['links']) : '';
-  $variables['new']       = $comment->new ? t('new') : '';
-  $variables['picture']   = theme_get_setting('toggle_comment_user_picture') ? theme('user_picture', $comment) : '';
-  $variables['signature'] = $comment->signature;
-  $variables['submitted'] = t('Submitted by !a on @b.',
-                      array('!a' => theme('username', $comment),
-                            '@b' => format_date($comment->timestamp)));
-  $variables['title']     = l($comment->subject, $_GET['q'], array('fragment' => "comment-$comment->cid"));
-}
-
-/**
- * Prepare the values passed to the theme_block function to be passed
- * into a pluggable template engine. Uses block properties to generate a
- * series of template file suggestions. If none are found, the default
- * block.tpl.php is used.
- */
-function phptemplate_engine_variables_block(&$variables) {
-  global $sidebar_indicator;
-  $count['block_counter'][$sidebar_indicator] = isset($count['block_counter'][$sidebar_indicator]) && is_int($count['block_counter'][$sidebar_indicator]) ? $count['block_counter'][$sidebar_indicator] : 1;
-
-  $variables['block_zebra'] = ($count['block_counter'][$sidebar_indicator] % 2) ? 'odd' : 'even';
-
-  $variables['block_id'] = $count['block_counter'][$sidebar_indicator]++;
-  $variables['template_files'][] = 'block-' . $variables['block']->region;
-  $variables['template_files'][] = 'block-' . $variables['block']->module;
-  $variables['template_files'][] = 'block-' . $variables['block']->module .'-'. $variables['block']->delta;
-}
diff --git a/themes/garland/template.php b/themes/garland/template.php
index 9caf7dfd6951..3efbff7b913d 100644
--- a/themes/garland/template.php
+++ b/themes/garland/template.php
@@ -55,7 +55,7 @@ function phptemplate_comment_wrapper($content, $type = null) {
 /**
  * Override or insert PHPTemplate variables into the templates.
  */
-function phptemplate_variables_page(&$vars) {
+function phptemplate_preprocess_page(&$vars) {
   if ($secondary = menu_secondary_local_tasks()) {
     $output = '<span class="clear"></span>';
     $output .= "<ul class=\"tabs secondary\">\n". $secondary ."</ul>\n";
-- 
GitLab