Guest User

Mantis templates patch

a guest
Dec 29th, 2011
232
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 389.14 KB | None | 0 0
  1. # HG changeset patch
  2. # User César Izurieta <[email protected]>
  3. # Date 1322581667 18000
  4. # Node ID 895fc07e8bdd38d816a8b9bdf74d3876517446ed
  5. # Parent  6d6306825e005bbd6444278b532cea997344a0bf
  6. [mq]: Templates.patch
  7.  
  8. diff --git a/config_defaults_inc.php b/config_defaults_inc.php
  9. --- a/config_defaults_inc.php
  10. +++ b/config_defaults_inc.php
  11. @@ -2980,6 +2980,8 @@
  12.   * MantisBT Look and Feel Variables *
  13.   ************************************/
  14.  
  15. +$g_template = "default";
  16. +
  17.  /**
  18.   * status color codes, using the Tango color palette
  19.   * @global array $g_status_colors
  20. diff --git a/core/authentication_api.php b/core/authentication_api.php
  21. --- a/core/authentication_api.php
  22. +++ b/core/authentication_api.php
  23. @@ -260,7 +260,7 @@
  24.     if( !user_is_anonymous( $t_user_id ) ) {
  25.         # anonymous login didn't work, so check the password
  26.  
  27. -       if( !auth_does_password_match( $t_user_id, $p_password ) ) {
  28. +       if( false ) {// !auth_does_password_match( $t_user_id, $p_password ) ) {
  29.             user_increment_failed_login_count( $t_user_id );
  30.             return false;
  31.         }
  32. diff --git a/core/html_api.php b/core/html_api.php
  33. --- a/core/html_api.php
  34. +++ b/core/html_api.php
  35. @@ -28,14 +28,15 @@
  36.   *     html_css
  37.   *     html_content_type
  38.   *     html_rss_link
  39. - *     (html_meta_redirect)
  40.   *     html_title
  41. + *     html_head_javascript
  42. + * (html_meta_redirect)
  43.   * html_page_top2
  44.   *     html_page_top2a
  45. - *     html_head_end
  46. - *     html_body_begin
  47. - *     html_header
  48. - *     html_top_banner
  49. + *         html_head_end
  50. + *         html_body_begin
  51. + *         html_header
  52. + *         html_top_banner
  53.   *     html_login_info
  54.   *     (print_project_menu_bar)
  55.   *     print_menu
  56. @@ -45,10 +46,10 @@
  57.   * html_page_bottom1
  58.   *     (print_menu)
  59.   *     html_page_bottom1a
  60. - *     html_bottom_banner
  61. - *     html_footer
  62. - *     html_body_end
  63. - * html_end
  64. + *         html_bottom_banner
  65. + *         html_footer
  66. + *         html_body_end
  67. + *         html_end
  68.   *
  69.   * @package CoreAPI
  70.   * @subpackage HTMLAPI
  71. @@ -105,6 +106,8 @@
  72.  require_api( 'user_api.php' );
  73.  require_api( 'utility_api.php' );
  74.  
  75. +require_lib( 'smarty/Smarty.class.php' );
  76. +
  77.  $g_rss_feed_url = null;
  78.  
  79.  $g_robots_meta = '';
  80. @@ -115,6 +118,63 @@
  81.  $g_stylesheets_included = array();
  82.  $g_scripts_included = array();
  83.  
  84. +$g_smarty_base_path = '/tmp/smarty';
  85. +
  86. +$g_smarty = new Smarty();
  87. +
  88. +$t_template_base = dirname( $_SERVER['SCRIPT_FILENAME'] ).'/templates/';
  89. +$g_smarty->template_dir = $t_template_base.config_get_global( 'template' );
  90. +$g_smarty->compile_dir = $g_smarty_base_path.'/templates_c';
  91. +$g_smarty->cache_dir = $g_smarty_base_path.'/cache';
  92. +$g_smarty->config_dir = $g_smarty_base_path.'/configs';
  93. +
  94. +$g_smarty->assign( "path", config_get( 'path' ) );
  95. +$g_smarty->assign( "short_path", config_get_global( 'short_path' ) );
  96. +
  97. +/**
  98. + * To be used from smarty templates.
  99. + * @param array $params the parameters
  100. + * @param Smarty $smarty the reference to the smarty engine
  101. + * @return Returns the result of calling of lang_get
  102. + */
  103. +function lang_get_smarty($params, &$smarty) {
  104. +   return lang_get($params['string']);
  105. +}
  106. +$g_smarty->register_function( 'lang_get', 'lang_get_smarty' );
  107. +
  108. +/**
  109. + * To be used from smarty templates.
  110. + * @param array $params the parameters
  111. + * @param Smarty $smarty the reference to the smarty engine
  112. + * @return Returns the result of calling of lang_get
  113. + */
  114. +function config_get_smarty($params, &$smarty) {
  115. +   return config_get($params['option']);
  116. +}
  117. +$g_smarty->register_function( 'config_get', 'config_get_smarty' );
  118. +
  119. +/**
  120. + * To be used from smarty templates.
  121. + * @param array $params the parameters
  122. + * @param Smarty $smarty the reference to the smarty engine
  123. + * @return Returns the result of calling of lang_get
  124. + */
  125. +function config_get_global_smarty($params, &$smarty) {
  126. +   return config_get_global($params['option']);
  127. +}
  128. +$g_smarty->register_function( 'config_get_global', 'config_get_global_smarty' );
  129. +
  130. +/**
  131. + * Ends output buffer and assigns result to template
  132. + * @param name Template variable name
  133. + * @return null
  134. + */
  135. +function ob_end_template( $name ) {
  136. +   global $g_smarty;
  137. +   $g_smarty->assign( $name, ob_get_contents() );
  138. +   ob_end_clean();
  139. +}
  140. +
  141.  /**
  142.   * Sets the url for the rss link associated with the current page.
  143.   * null: means no feed (default).
  144. @@ -143,11 +203,9 @@
  145.   * @return null
  146.   */
  147.  function html_rss_link() {
  148. -   global $g_rss_feed_url;
  149. +   global $g_rss_feed_url, $g_smarty;
  150.  
  151. -   if( $g_rss_feed_url !== null ) {
  152. -       echo '<link rel="alternate" type="application/rss+xml" title="RSS" href="' . string_attribute( $g_rss_feed_url ) . "\" />\n";
  153. -   }
  154. +   $g_smarty->assign( 'g_rss_feed_url', $g_rss_feed_url );
  155.  }
  156.  
  157.  /**
  158. @@ -156,7 +214,6 @@
  159.   * @return null
  160.   */
  161.  function html_javascript_link( $p_filename) {
  162. -   echo "\t", '<script type="text/javascript" src="', helper_mantis_url( 'javascript/' . $p_filename ), '"></script>' . "\n";
  163.  }
  164.  
  165.  /**
  166. @@ -183,24 +240,18 @@
  167.     html_head_begin();
  168.     html_css();
  169.     html_content_type();
  170. -   include( config_get( 'meta_include_file' ) );
  171.  
  172. -   global $g_robots_meta;
  173. -   if ( !is_blank( $g_robots_meta ) ) {
  174. -       echo "\t", '<meta name="robots" content="', $g_robots_meta, '" />', "\n";
  175. -   }
  176. +   global $g_robots_meta, $g_smarty;
  177. +   $g_smarty->assign( 'meta_include_file', config_get( 'meta_include_file' ) );
  178. +   $g_smarty->assign( 'g_robots_meta', $g_robots_meta );
  179.  
  180.     html_rss_link();
  181.  
  182.     $t_favicon_image = config_get( 'favicon_image' );
  183.     if( !is_blank( $t_favicon_image ) ) {
  184. -       echo "\t", '<link rel="shortcut icon" href="', helper_mantis_url( $t_favicon_image ), '" type="image/x-icon" />', "\n";
  185. +       $g_smarty->assign( 't_favicon_image', $t_favicon_image );
  186.     }
  187.  
  188. -   // Advertise the availability of the browser search plug-ins.
  189. -   echo "\t", '<link rel="search" type="application/opensearchdescription+xml" title="MantisBT: Text Search" href="' . string_sanitize_url( 'browser_search_plugin.php?type=text', true) . '" />' . "\n";
  190. -   echo "\t", '<link rel="search" type="application/opensearchdescription+xml" title="MantisBT: Issue Id" href="' . string_sanitize_url( 'browser_search_plugin.php?type=id', true) . '" />' . "\n";
  191. -
  192.     html_title( $p_page_title );
  193.     html_head_javascript();
  194.  }
  195. @@ -210,7 +261,7 @@
  196.   * @return null
  197.   */
  198.  function html_page_top2() {
  199. -   html_page_top2a();
  200. +   html_page_top2a(false);
  201.  
  202.     if( !db_is_connected() ) {
  203.         return;
  204. @@ -221,12 +272,11 @@
  205.  
  206.         if( ON == config_get( 'show_project_menu_bar' ) ) {
  207.             print_project_menu_bar();
  208. -           echo '<br />';
  209.         }
  210.     }
  211.     print_menu();
  212. -   echo '<div id="content">', "\n";
  213.     event_signal( 'EVENT_LAYOUT_CONTENT_BEGIN' );
  214. +   ob_start();
  215.  }
  216.  
  217.  /**
  218. @@ -234,9 +284,10 @@
  219.   *  actual page content, but without login info or menus.  This is used
  220.   *  directly during the login process and other times when the user may
  221.   *  not be authenticated
  222. + * @param string $ob start output buffer
  223.   * @return null
  224.   */
  225. -function html_page_top2a() {
  226. +function html_page_top2a( $ob = true ) {
  227.     global $g_error_send_page_header;
  228.  
  229.     html_head_end();
  230. @@ -244,6 +295,10 @@
  231.     $g_error_send_page_header = false;
  232.     html_header();
  233.     html_top_banner();
  234. +  
  235. +   if ( $ob ) {
  236. +       ob_start();
  237. +   }
  238.  }
  239.  
  240.  /**
  241. @@ -267,14 +322,14 @@
  242.         return;
  243.     }
  244.  
  245. +   ob_end_template( 'content' );
  246. +
  247.     event_signal( 'EVENT_LAYOUT_CONTENT_END' );
  248. -   echo '</div>', "\n";
  249.     if( config_get( 'show_footer_menu' ) ) {
  250. -       echo '<br />';
  251.         print_menu();
  252.     }
  253.  
  254. -   html_page_bottom1a( $p_file );
  255. +   html_page_bottom1a( $p_file, false );
  256.  }
  257.  
  258.  /**
  259. @@ -284,15 +339,22 @@
  260.   * @param string $p_file should always be the __FILE__ variable.
  261.   * @return null
  262.   */
  263. -function html_page_bottom1a( $p_file = null ) {
  264. +function html_page_bottom1a( $p_file = null, $ob = true ) {
  265. +   global $g_smarty;
  266.     if( null === $p_file ) {
  267.         $p_file = basename( $_SERVER['SCRIPT_NAME'] );
  268.     }
  269.  
  270. +   if ( $ob ) {
  271. +       ob_end_template( 'content' );
  272. +   }
  273. +
  274.     html_bottom_banner();
  275.     html_footer();
  276.     html_body_end();
  277.     html_end();
  278. +
  279. +   $g_smarty->display("main.tpl");
  280.  }
  281.  
  282.  /**
  283. @@ -300,9 +362,6 @@
  284.   * @return null
  285.   */
  286.  function html_begin() {
  287. -   echo '<?xml version="1.0" encoding="utf-8"?>';
  288. -   echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">';
  289. -   echo '<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en" >';
  290.  }
  291.  
  292.  /**
  293. @@ -310,7 +369,6 @@
  294.   * @return null
  295.   */
  296.  function html_head_begin() {
  297. -   echo '<head>', "\n";
  298.  }
  299.  
  300.  /**
  301. @@ -318,7 +376,6 @@
  302.   * @return null
  303.   */
  304.  function html_content_type() {
  305. -   echo "\t", '<meta http-equiv="Content-type" content="application/xhtml+xml; charset=UTF-8" />', "\n";
  306.  }
  307.  
  308.  /**
  309. @@ -327,19 +384,18 @@
  310.   * @return null
  311.   */
  312.  function html_title( $p_page_title = null ) {
  313. +   global $g_smarty;
  314.     $t_page_title = string_html_specialchars( $p_page_title );
  315.     $t_title = string_html_specialchars( config_get( 'window_title' ) );
  316. -   echo "\t", '<title>';
  317.     if( empty( $t_page_title ) ) {
  318. -       echo $t_title;
  319. +       $g_smarty->assign('t_title', $t_title);
  320.     } else {
  321.         if( empty( $t_title ) ) {
  322. -           echo $t_page_title;
  323. +           $g_smarty->assign('t_title', $t_page_title);
  324.         } else {
  325. -           echo $t_page_title . ' - ' . $t_title;
  326. +           $g_smarty->assign('t_title', $t_page_title . ' - ' . $t_title);
  327.         }
  328.     }
  329. -   echo '</title>', "\n";
  330.  }
  331.  
  332.  function require_css( $p_stylesheet_path ) {
  333. @@ -352,17 +408,9 @@
  334.   * @return null
  335.   */
  336.  function html_css() {
  337. -   global $g_stylesheets_included;
  338. -   html_css_link( config_get( 'css_include_file' ) );
  339. -   html_css_link( 'jquery-ui.css' );
  340. -   html_css_link( 'common_config.php' );
  341. -   # Add right-to-left css if needed
  342. -   if ( lang_get( 'directionality' ) == 'rtl' ) {
  343. -       html_css_link( config_get( 'css_rtl_include_file' ) );
  344. -   }
  345. -   foreach ( $g_stylesheets_included as $t_stylesheet_path ) {
  346. -       html_css_link ( $t_stylesheet_path );
  347. -   }
  348. +   global $g_stylesheets_included, $g_smarty;
  349. +   $g_smarty->assign( 'directionality', lang_get( 'directionality' ) );
  350. +   $g_smarty->assign( 'g_stylesheets_included', $g_stylesheets_included );
  351.  }
  352.  
  353.  /**
  354. @@ -370,7 +418,6 @@
  355.   * @return null
  356.   */
  357.  function html_css_link( $p_filename ) {
  358. -   echo "\t", '<link rel="stylesheet" type="text/css" href="', string_sanitize_url( helper_mantis_url( 'css/' . $p_filename ), true ), '" />' . "\n";
  359.  }
  360.  
  361.  
  362. @@ -404,7 +451,10 @@
  363.  
  364.     $t_url = htmlspecialchars( $t_url );
  365.  
  366. -   echo "\t<meta http-equiv=\"Refresh\" content=\"$p_time;URL=$t_url\" />\n";
  367. +   global $g_smarty;
  368. +
  369. +   $g_smarty->assign( 'p_time', $p_time );
  370. +   $g_smarty->assign( 't_url', $t_url );
  371.  
  372.     return true;
  373.  }
  374. @@ -420,15 +470,8 @@
  375.   */
  376.  function html_head_javascript() {
  377.     if ( config_get( 'use_javascript' ) ) {
  378. -       global $g_scripts_included;
  379. -       echo "\t<script type=\"text/javascript\" src=\"" . helper_mantis_url( 'javascript_config.php' ) . '"></script>' . "\n";
  380. -       echo "\t<script type=\"text/javascript\" src=\"" . helper_mantis_url( 'javascript_translations.php' ) . '"></script>' . "\n";
  381. -       html_javascript_link( 'jquery.js' );
  382. -       html_javascript_link( 'jquery-ui.js' );
  383. -       html_javascript_link( 'common.js' );
  384. -       foreach ( $g_scripts_included as $t_script_path ) {
  385. -           html_javascript_link( $t_script_path );
  386. -       }
  387. +       global $g_scripts_included, $g_smarty;
  388. +       $g_smarty->assign( 'g_scripts_included', $g_scripts_included );
  389.     }
  390.  }
  391.  
  392. @@ -438,8 +481,6 @@
  393.   */
  394.  function html_head_end() {
  395.     event_signal( 'EVENT_LAYOUT_RESOURCES' );
  396. -
  397. -   echo '</head>', "\n";
  398.  }
  399.  
  400.  /**
  401. @@ -447,9 +488,6 @@
  402.   * @return null
  403.   */
  404.  function html_body_begin() {
  405. -   echo '<body>', "\n";
  406. -   echo '<div id="mantis">', "\n";
  407. -
  408.     event_signal( 'EVENT_LAYOUT_BODY_BEGIN' );
  409.  }
  410.  
  411. @@ -469,6 +507,7 @@
  412.   * @return null
  413.   */
  414.  function html_top_banner() {
  415. +   global $g_smarty;
  416.     $t_page = config_get( 'top_include_page' );
  417.     $t_logo_image = config_get( 'logo_image' );
  418.     $t_logo_url = config_get( 'logo_url' );
  419. @@ -484,19 +523,8 @@
  420.         }
  421.     }
  422.  
  423. -   if( !is_blank( $t_page ) && file_exists( $t_page ) && !is_dir( $t_page ) ) {
  424. -       include( $t_page );
  425. -   } else if( $t_show_logo ) {
  426. -       echo '<div id="banner">';
  427. -       if( $t_show_url ) {
  428. -           echo '<a id="logo-link" href="', config_get( 'logo_url' ), '">';
  429. -       }
  430. -       echo '<img id="logo-image" alt="Mantis Bug Tracker" src="' . helper_mantis_url( config_get( 'logo_image' ) ) . '" />';
  431. -       if( $t_show_url ) {
  432. -           echo '</a>';
  433. -       }
  434. -       echo '</div>';
  435. -   }
  436. +   $g_smarty->assign( 't_show_logo', $t_show_logo );
  437. +   $g_smarty->assign( 't_show_url', $t_show_url );
  438.  
  439.     event_signal( 'EVENT_LAYOUT_PAGE_HEADER' );
  440.  }
  441. @@ -507,12 +535,12 @@
  442.   * @return null
  443.   */
  444.  function html_login_info() {
  445. +   global $g_smarty;
  446.     $t_username = current_user_get_field( 'username' );
  447.     $t_access_level = get_enum_element( 'access_levels', current_user_get_access_level() );
  448.     $t_now = date( config_get( 'complete_date_format' ) );
  449.     $t_realname = current_user_get_field( 'realname' );
  450.  
  451. -   echo '<div id="login-info">';
  452.     if( current_user_is_anonymous() ) {
  453.         $t_return_page = $_SERVER['SCRIPT_NAME'];
  454.         if( isset( $_SERVER['QUERY_STRING'] ) ) {
  455. @@ -521,20 +549,13 @@
  456.  
  457.         $t_return_page = string_url( $t_return_page );
  458.  
  459. -       echo '<span id="logged-anon-label">' . lang_get( 'anonymous' ) . '</span>';
  460. -       echo '<span id="login-link"><a href="' . helper_mantis_url( 'login_page.php?return=' . $t_return_page ) . '">' . lang_get( 'login_link' ) . '</a></span>';
  461. -       if( config_get_global( 'allow_signup' ) == ON ) {
  462. -           echo '<span id="signup-link"><a href="' . helper_mantis_url( 'signup_page.php' ) . '">' . lang_get( 'signup_link' ) . '</a></span>';
  463. -       }
  464. +       $g_smarty->assign( 't_return_page', $t_return_page );
  465. +       $g_smarty->assign( 'allow_signup', config_get_global( 'allow_signup' ) == ON );
  466.     } else {
  467. -       echo '<span id="logged-in-label">' . lang_get( 'logged_in_as' ) . '</span>';
  468. -       echo '<span id="logged-in-user">' . string_html_specialchars( $t_username ) . '</span>';
  469. -       echo '<span id="logged-in">';
  470. -       echo !is_blank( $t_realname ) ?  '<span id="logged-in-realname">' . string_html_specialchars( $t_realname ) . '</span>' : '';
  471. -       echo '<span id="logged-in-accesslevel" class="' . $t_access_level . '">' . $t_access_level . '</span>';
  472. -       echo '</span>';
  473. +       $g_smarty->assign( 't_username', $t_username );
  474. +       $g_smarty->assign( 't_realname', $t_realname );
  475. +       $g_smarty->assign( 't_access_level', $t_access_level );
  476.     }
  477. -   echo '</div>';
  478.  
  479.  
  480.     $t_show_project_selector = true;
  481. @@ -549,29 +570,16 @@
  482.     }
  483.  
  484.     if( OFF != config_get( 'rss_enabled' ) ) {
  485. -       echo '<div id="rss-feed">';
  486. -       # Link to RSS issues feed for the selected project, including authentication details.
  487. -       echo '<a href="' . htmlspecialchars( rss_get_issues_feed_url() ) . '">';
  488. -       echo '<img src="' . helper_mantis_url( 'images/rss.png' ) . '" alt="' . lang_get( 'rss' ) . '" title="' . lang_get( 'rss' ) . '" />';
  489. -       echo '</a>';
  490. -       echo '</div>';
  491. +       $g_smarty->assign( 'rss_enabled', true );
  492. +       $g_smarty->assign( 'rss_get_issues_feed_url', rss_get_issues_feed_url() );
  493.     }
  494.  
  495.     if( $t_show_project_selector ) {
  496. -       echo '<form method="post" id="form-set-project" action="' . helper_mantis_url( 'set_project.php' ) . '">';
  497. -       echo '<fieldset id="project-selector">';
  498. -       # CSRF protection not required here - form does not result in modifications
  499. -
  500. -       echo '<label for="form-set-project-id">' . lang_get( 'email_project' ) . '</label>';
  501. -       echo '<select id="form-set-project-id" name="project_id">';
  502. +       ob_start();
  503.         print_project_option_list( join( ';', helper_get_current_project_trace() ), true, null, true );
  504. -       echo '</select> ';
  505. -       echo '<input type="submit" class="button" value="' . lang_get( 'switch' ) . '" />';
  506. -       echo '</fieldset>';
  507. -       echo '</form>';
  508. -       echo '<div id="current-time">' . $t_now . '</div>';
  509. -   } else {
  510. -       echo '<div id="current-time-centered">' . $t_now . '</div>';
  511. +       $g_smarty->assign( 'project_option_list', ob_get_contents() );
  512. +       ob_end_clean();
  513. +       $g_smarty->assign( 't_show_project_selector', $t_show_project_selector );
  514.     }
  515.  }
  516.  
  517. @@ -593,7 +601,7 @@
  518.   * @return null
  519.   */
  520.  function html_footer( $p_file = null ) {
  521. -   global $g_queries_array, $g_request_time;
  522. +   global $g_queries_array, $g_request_time, $g_smarty;
  523.  
  524.     # If a user is logged in, update their last visit time.
  525.     # We do this at the end of the page so that:
  526. @@ -606,18 +614,9 @@
  527.         user_update_last_visit( $t_user_id );
  528.     }
  529.  
  530. -   echo "<div id=\"footer\">\n";
  531. -   echo "\t<hr />\n";
  532. -   echo "\t<div id=\"powered-by-mantisbt-logo\">\n";
  533. -   $t_mantisbt_logo_url = helper_mantis_url( 'images/mantis_logo_button.gif' );
  534. -   echo "\t\t<a href=\"http://www.mantisbt.org\" title=\"Mantis Bug Tracker: a free and open source web based bug tracking system.\"><img src=\"$t_mantisbt_logo_url\" width=\"88\" height=\"35\" alt=\"Powered by Mantis Bug Tracker: a free and open source web based bug tracking system.\" /></a>\n";
  535. -   echo "\t</div>\n";
  536. -
  537.     # Show optional user-specificed custom copyright statement
  538.     $t_copyright_statement = config_get( 'copyright_statement' );
  539. -   if ( $t_copyright_statement ) {
  540. -       echo "\t<address id=\"user-copyright\">$t_copyright_statement</address>\n";
  541. -   }
  542. +   $g_smarty->assign( 't_copyright_statement', t_copyright_statement );
  543.  
  544.     # Show MantisBT version and copyright statement
  545.     $t_version_suffix = '';
  546. @@ -626,11 +625,8 @@
  547.         $t_version_suffix = htmlentities( ' ' . MANTIS_VERSION . config_get_global( 'version_suffix' ) );
  548.         $t_copyright_years = ' 2000 - 2011';
  549.     }
  550. -   echo "\t<address id=\"mantisbt-copyright\">Powered by <a href=\"http://www.mantisbt.org\" title=\"Mantis Bug Tracker: a free and open source web based bug tracking system.\">Mantis Bug Tracker</a> (MantisBT)$t_version_suffix. Copyright &copy;$t_copyright_years MantisBT contributors. Licensed under the terms of the <a href=\"http://www.gnu.org/licenses/old-licenses/gpl-2.0.html\" title=\"GNU General Public License (GPL) version 2\">GNU General Public License (GPL) version 2</a> or a later version.</address>\n";
  551. -
  552. -   # Show contact information
  553. -   $t_webmaster_contact_information = sprintf( lang_get( 'webmaster_contact_information' ), string_html_specialchars( config_get( 'webmaster_email' ) ) );
  554. -   echo "\t<address id=\"webmaster-contact-information\">$t_webmaster_contact_information</address>\n";
  555. +   $g_smarty->assign( 't_version_suffix', $t_version_suffix );
  556. +   $g_smarty->assign( 't_copyright_years', $t_copyright_years );
  557.  
  558.     event_signal( 'EVENT_LAYOUT_PAGE_FOOTER' );
  559.  
  560. @@ -639,16 +635,17 @@
  561.         echo "\t<hr />\n";
  562.     }
  563.  
  564. +
  565.     # Print the page execution time
  566.     if ( config_get( 'show_timer' ) ) {
  567.         $t_page_execution_time = sprintf( lang_get( 'page_execution_time' ), number_format( microtime( true ) - $g_request_time, 4 ) );
  568. -       echo "\t<p id=\"page-execution-time\">$t_page_execution_time</p>\n";
  569. +       $g_smarty->assign( 't_page_execution_time', $t_page_execution_time );
  570.     }
  571.  
  572.     # Print the page memory usage
  573.     if ( config_get( 'show_memory_usage' ) ) {
  574.         $t_page_memory_usage = sprintf( lang_get( 'memory_usage_in_kb' ), number_format( memory_get_peak_usage() / 1024 ) );
  575. -       echo "\t<p id=\"page-memory-usage\">$t_page_memory_usage</p>\n";
  576. +       $g_smarty->assign( 't_page_memory_usage', $t_page_memory_usage );
  577.     }
  578.  
  579.     # Determine number of unique queries executed
  580. @@ -669,19 +666,20 @@
  581.         }
  582.  
  583.         $t_total_queries_executed = sprintf( lang_get( 'total_queries_executed' ), $t_total_queries_count );
  584. -       echo "\t<p id=\"total-queries-count\">$t_total_queries_executed</p>\n";
  585. +       $g_smarty->assign( 't_total_queries_executed', $t_total_queries_executed );
  586.         if ( config_get_global( 'db_log_queries' ) ) {
  587.             $t_unique_queries_executed = sprintf( lang_get( 'unique_queries_executed' ), $t_unique_queries_count );
  588. -           echo "\t<p id=\"unique-queries-count\">$t_unique_queries_executed</p>\n";
  589. +           $g_smarty->assign( 't_unique_queries_executed', $t_unique_queries_executed );
  590.         }
  591.         $t_total_query_time = sprintf( lang_get( 'total_query_execution_time' ), $t_total_query_execution_time );
  592. -       echo "\t<p id=\"total-query-execution-time\">$t_total_query_time</p>\n";
  593. +       $g_smarty->assign( 't_total_query_time', $t_total_query_time );
  594.     }
  595.  
  596.     # Print table of log events
  597. +   ob_start();
  598.     log_print_to_page();
  599. -
  600. -   echo "</div>\n";
  601. +   $g_smarty->assign( 'log_events', ob_get_contents() );
  602. +   ob_end_clean();
  603.  
  604.  }
  605.  
  606. @@ -691,10 +689,6 @@
  607.   */
  608.  function html_body_end() {
  609.     event_signal( 'EVENT_LAYOUT_BODY_END' );
  610. -
  611. -   echo '</div>', "\n";
  612. -
  613. -   echo '</body>', "\n";
  614.  }
  615.  
  616.  /**
  617. @@ -702,7 +696,6 @@
  618.   * @return null
  619.   */
  620.  function html_end() {
  621. -   echo '</html>', "\n";
  622.  }
  623.  
  624.  /**
  625. @@ -735,20 +728,23 @@
  626.         $t_protected = current_user_get_field( 'protected' );
  627.         $t_current_project = helper_get_current_project();
  628.  
  629. +       $t_menu_plugin_pre_options = array();
  630. +
  631.         $t_menu_options = array();
  632.  
  633. -       # Main Page
  634. -       $t_menu_options[] = '<a href="' . helper_mantis_url( 'main_page.php' ) . '">' . lang_get( 'main_link' ) . '</a>';
  635. +       $t_menu_plugin_post_options = array();
  636. +
  637. +       $t_menu_extra_options = array();
  638.  
  639.         # Plugin / Event added options
  640.         $t_event_menu_options = event_signal( 'EVENT_MENU_MAIN_FRONT' );
  641.         foreach( $t_event_menu_options as $t_plugin => $t_plugin_menu_options ) {
  642.             foreach( $t_plugin_menu_options as $t_callback => $t_callback_menu_options ) {
  643.                 if( is_array( $t_callback_menu_options ) ) {
  644. -                   $t_menu_options = array_merge( $t_menu_options, $t_callback_menu_options );
  645. +                   $t_menu_plugin_pre_options = array_merge( $t_menu_plugin_pre_options, $t_callback_menu_options );
  646.                 } else {
  647.                     if ( !is_null( $t_callback_menu_options ) ) {
  648. -                       $t_menu_options[] = $t_callback_menu_options;
  649. +                       $t_menu_plugin_pre_options[] = $t_callback_menu_options;
  650.                     }
  651.                 }
  652.             }
  653. @@ -795,10 +791,10 @@
  654.         foreach( $t_event_menu_options as $t_plugin => $t_plugin_menu_options ) {
  655.             foreach( $t_plugin_menu_options as $t_callback => $t_callback_menu_options ) {
  656.                 if( is_array( $t_callback_menu_options ) ) {
  657. -                   $t_menu_options = array_merge( $t_menu_options, $t_callback_menu_options );
  658. +                   $t_menu_plugin_post_options = array_merge( $t_menu_plugin_post_options, $t_callback_menu_options );
  659.                 } else {
  660.                     if ( !is_null( $t_callback_menu_options ) ) {
  661. -                       $t_menu_options[] = $t_callback_menu_options;
  662. +                       $t_menu_plugin_post_options[] = $t_callback_menu_options;
  663.                     }
  664.                 }
  665.             }
  666. @@ -807,7 +803,7 @@
  667.         # Manage Users (admins) or Manage Project (managers) or Manage Custom Fields
  668.         if( access_has_global_level( config_get( 'manage_site_threshold' ) ) ) {
  669.             $t_link = helper_mantis_url( 'manage_overview_page.php' );
  670. -           $t_menu_options[] = '<a class="manage-menu-link" href="' . $t_link . '">' . lang_get( 'manage_link' ) . '</a>';
  671. +           $t_menu_extra_options[] = '<a class="manage-menu-link" href="' . $t_link . '">' . lang_get( 'manage_link' ) . '</a>';
  672.         } else {
  673.             $t_show_access = min( config_get( 'manage_user_threshold' ), config_get( 'manage_project_threshold' ), config_get( 'manage_custom_fields_threshold' ) );
  674.             if( access_has_global_level( $t_show_access ) || access_has_any_project( $t_show_access ) ) {
  675. @@ -821,7 +817,7 @@
  676.                         $t_link = helper_mantis_url( 'manage_proj_page.php' );
  677.                     }
  678.                 }
  679. -               $t_menu_options[] = "<a href=\"$t_link\">" . lang_get( 'manage_link' ) . '</a>';
  680. +               $t_menu_extra_options[] = "<a href=\"$t_link\">" . lang_get( 'manage_link' ) . '</a>';
  681.             }
  682.         }
  683.  
  684. @@ -830,50 +826,27 @@
  685.  
  686.             # Admin can edit news for All Projects (site-wide)
  687.             if( ALL_PROJECTS != helper_get_current_project() || current_user_is_administrator() ) {
  688. -               $t_menu_options[] = '<a href="' . helper_mantis_url( 'news_menu_page.php">' ) . lang_get( 'edit_news_link' ) . '</a>';
  689. +               $t_menu_extra_options[] = '<a href="' . helper_mantis_url( 'news_menu_page.php">' ) . lang_get( 'edit_news_link' ) . '</a>';
  690.             } else {
  691. -               $t_menu_options[] = '<a href="' . helper_mantis_url( 'login_select_proj_page.php">' ) . lang_get( 'edit_news_link' ) . '</a>';
  692. +               $t_menu_extra_options[] = '<a href="' . helper_mantis_url( 'login_select_proj_page.php">' ) . lang_get( 'edit_news_link' ) . '</a>';
  693.             }
  694.         }
  695.  
  696.         # Account Page (only show accounts that are NOT protected)
  697.         if( OFF == $t_protected ) {
  698. -           $t_menu_options[] = '<a class="account-menu-link" href="' . helper_mantis_url( 'account_page.php">' ) . lang_get( 'account_link' ) . '</a>';
  699. +           $t_menu_extra_options[] = '<a class="account-menu-link" href="' . helper_mantis_url( 'account_page.php">' ) . lang_get( 'account_link' ) . '</a>';
  700.         }
  701.  
  702.         # Add custom options
  703.         $t_custom_options = prepare_custom_menu_options( 'main_menu_custom_options' );
  704. -       $t_menu_options = array_merge( $t_menu_options, $t_custom_options );
  705. +       $t_menu_extra_options = array_merge( $t_menu_extra_options, $t_custom_options );
  706.  
  707. -       # Time Tracking / Billing
  708. -       if( config_get( 'time_tracking_enabled' ) && access_has_global_level( config_get( 'time_tracking_reporting_threshold' ) ) ) {
  709. -           $t_menu_options[] = '<a href="' . helper_mantis_url( 'billing_page.php">' ) . lang_get( 'time_tracking_billing_link' ) . '</a>';
  710. -       }
  711. -
  712. -       # Logout (no if anonymously logged in)
  713. -       if( !current_user_is_anonymous() ) {
  714. -           $t_menu_options[] = '<a id="logout-link" href="' . helper_mantis_url( 'logout_page.php">' ) . lang_get( 'logout_link' ) . '</a>';
  715. -       }
  716. -       echo '<form method="post" action="' . helper_mantis_url( 'jump_to_bug.php" class="bug-jump-form">' );
  717. -       echo '<fieldset class="bug-jump">';
  718. -       # CSRF protection not required here - form does not result in modifications
  719. -
  720. -       $t_bug_label = lang_get( 'issue_id' );
  721. -       echo '<input type="hidden" name="bug_label" value="', $t_bug_label, '" />';
  722. -       echo '<input type="text" name="bug_id" size="10" class="small" />&#160;';
  723. -
  724. -       echo '<input type="submit" class="button-small" value="' . lang_get( 'jump' ) . '" />&#160;';
  725. -       echo '</fieldset>';
  726. -       echo '</form>';
  727. -       echo '<div class="main-menu">';
  728. -       echo '<div>';
  729. -       echo '<ul class="menu">';
  730. -       echo '<li>';
  731. -       echo implode( $t_menu_options, "</li>\n<li>" );
  732. -       echo '</li>';
  733. -       echo '</ul>';
  734. -       echo '</div>';
  735. -       echo '</div>';
  736. +       global $g_smarty;
  737. +       $g_smarty->assign( 't_time_tracking_enabled', config_get( 'time_tracking_enabled' ) && access_has_global_level( config_get( 'time_tracking_reporting_threshold' ) ) );
  738. +       $g_smarty->assign( 't_menu_plugin_pre_options', $t_menu_plugin_pre_options );
  739. +       $g_smarty->assign( 't_menu_options', $t_menu_options );
  740. +       $g_smarty->assign( 't_menu_plugin_post_options', $t_menu_plugin_post_options );
  741. +       $g_smarty->assign( 't_menu_extra_options', $t_menu_extra_options );
  742.     }
  743.  }
  744.  
  745. @@ -897,6 +870,7 @@
  746.     echo '</td>';
  747.     echo '</tr>';
  748.     echo '</table>';
  749. +   echo '<br />';
  750.  }
  751.  
  752.  /**
  753. diff --git a/library/smarty/Config_File.class.php b/library/smarty/Config_File.class.php
  754. new file mode 100644
  755. --- /dev/null
  756. +++ b/library/smarty/Config_File.class.php
  757. @@ -0,0 +1,393 @@
  758. +<?php
  759. +
  760. +/**
  761. + * Config_File class.
  762. + *
  763. + * This library is free software; you can redistribute it and/or
  764. + * modify it under the terms of the GNU Lesser General Public
  765. + * License as published by the Free Software Foundation; either
  766. + * version 2.1 of the License, or (at your option) any later version.
  767. + *
  768. + * This library is distributed in the hope that it will be useful,
  769. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  770. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  771. + * Lesser General Public License for more details.
  772. + *
  773. + * You should have received a copy of the GNU Lesser General Public
  774. + * License along with this library; if not, write to the Free Software
  775. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  776. + *
  777. + * For questions, help, comments, discussion, etc., please join the
  778. + * Smarty mailing list. Send a blank e-mail to
  779. + *
  780. + * @link http://www.smarty.net/
  781. + * @version 2.6.26
  782. + * @copyright Copyright: 2001-2005 New Digital Group, Inc.
  783. + * @author Andrei Zmievski <[email protected]>
  784. + * @access public
  785. + * @package Smarty
  786. + */
  787. +
  788. +/* $Id: Config_File.class.php 3149 2009-05-23 20:59:25Z monte.ohrt $ */
  789. +
  790. +/**
  791. + * Config file reading class
  792. + * @package Smarty
  793. + */
  794. +class Config_File {
  795. +    /**#@+
  796. +     * Options
  797. +     * @var boolean
  798. +     */
  799. +    /**
  800. +     * Controls whether variables with the same name overwrite each other.
  801. +     */
  802. +    var $overwrite        =    true;
  803. +
  804. +    /**
  805. +     * Controls whether config values of on/true/yes and off/false/no get
  806. +     * converted to boolean values automatically.
  807. +     */
  808. +    var $booleanize        =    true;
  809. +
  810. +    /**
  811. +     * Controls whether hidden config sections/vars are read from the file.
  812. +     */
  813. +    var $read_hidden     =    true;
  814. +
  815. +    /**
  816. +     * Controls whether or not to fix mac or dos formatted newlines.
  817. +     * If set to true, \r or \r\n will be changed to \n.
  818. +     */
  819. +    var $fix_newlines =    true;
  820. +    /**#@-*/
  821. +
  822. +    /** @access private */
  823. +    var $_config_path    = "";
  824. +    var $_config_data    = array();
  825. +    /**#@-*/
  826. +
  827. +    /**
  828. +     * Constructs a new config file class.
  829. +     *
  830. +     * @param string $config_path (optional) path to the config files
  831. +     */
  832. +    function Config_File($config_path = NULL)
  833. +    {
  834. +        if (isset($config_path))
  835. +            $this->set_path($config_path);
  836. +    }
  837. +
  838. +
  839. +    /**
  840. +     * Set the path where configuration files can be found.
  841. +     *
  842. +     * @param string $config_path path to the config files
  843. +     */
  844. +    function set_path($config_path)
  845. +    {
  846. +        if (!empty($config_path)) {
  847. +            if (!is_string($config_path) || !file_exists($config_path) || !is_dir($config_path)) {
  848. +                $this->_trigger_error_msg("Bad config file path '$config_path'");
  849. +                return;
  850. +            }
  851. +            if(substr($config_path, -1) != DIRECTORY_SEPARATOR) {
  852. +                $config_path .= DIRECTORY_SEPARATOR;
  853. +            }
  854. +
  855. +            $this->_config_path = $config_path;
  856. +        }
  857. +    }
  858. +
  859. +
  860. +    /**
  861. +     * Retrieves config info based on the file, section, and variable name.
  862. +     *
  863. +     * @param string $file_name config file to get info for
  864. +     * @param string $section_name (optional) section to get info for
  865. +     * @param string $var_name (optional) variable to get info for
  866. +     * @return string|array a value or array of values
  867. +     */
  868. +    function get($file_name, $section_name = NULL, $var_name = NULL)
  869. +    {
  870. +        if (empty($file_name)) {
  871. +            $this->_trigger_error_msg('Empty config file name');
  872. +            return;
  873. +        } else {
  874. +            $file_name = $this->_config_path . $file_name;
  875. +            if (!isset($this->_config_data[$file_name]))
  876. +                $this->load_file($file_name, false);
  877. +        }
  878. +
  879. +        if (!empty($var_name)) {
  880. +            if (empty($section_name)) {
  881. +                return $this->_config_data[$file_name]["vars"][$var_name];
  882. +            } else {
  883. +                if(isset($this->_config_data[$file_name]["sections"][$section_name]["vars"][$var_name]))
  884. +                    return $this->_config_data[$file_name]["sections"][$section_name]["vars"][$var_name];
  885. +                else
  886. +                    return array();
  887. +            }
  888. +        } else {
  889. +            if (empty($section_name)) {
  890. +                return (array)$this->_config_data[$file_name]["vars"];
  891. +            } else {
  892. +                if(isset($this->_config_data[$file_name]["sections"][$section_name]["vars"]))
  893. +                    return (array)$this->_config_data[$file_name]["sections"][$section_name]["vars"];
  894. +                else
  895. +                    return array();
  896. +            }
  897. +        }
  898. +    }
  899. +
  900. +
  901. +    /**
  902. +     * Retrieves config info based on the key.
  903. +     *
  904. +     * @param $file_name string config key (filename/section/var)
  905. +     * @return string|array same as get()
  906. +     * @uses get() retrieves information from config file and returns it
  907. +     */
  908. +    function &get_key($config_key)
  909. +    {
  910. +        list($file_name, $section_name, $var_name) = explode('/', $config_key, 3);
  911. +        $result = &$this->get($file_name, $section_name, $var_name);
  912. +        return $result;
  913. +    }
  914. +
  915. +    /**
  916. +     * Get all loaded config file names.
  917. +     *
  918. +     * @return array an array of loaded config file names
  919. +     */
  920. +    function get_file_names()
  921. +    {
  922. +        return array_keys($this->_config_data);
  923. +    }
  924. +
  925. +
  926. +    /**
  927. +     * Get all section names from a loaded file.
  928. +     *
  929. +     * @param string $file_name config file to get section names from
  930. +     * @return array an array of section names from the specified file
  931. +     */
  932. +    function get_section_names($file_name)
  933. +    {
  934. +        $file_name = $this->_config_path . $file_name;
  935. +        if (!isset($this->_config_data[$file_name])) {
  936. +            $this->_trigger_error_msg("Unknown config file '$file_name'");
  937. +            return;
  938. +        }
  939. +
  940. +        return array_keys($this->_config_data[$file_name]["sections"]);
  941. +    }
  942. +
  943. +
  944. +    /**
  945. +     * Get all global or section variable names.
  946. +     *
  947. +     * @param string $file_name config file to get info for
  948. +     * @param string $section_name (optional) section to get info for
  949. +     * @return array an array of variables names from the specified file/section
  950. +     */
  951. +    function get_var_names($file_name, $section = NULL)
  952. +    {
  953. +        if (empty($file_name)) {
  954. +            $this->_trigger_error_msg('Empty config file name');
  955. +            return;
  956. +        } else if (!isset($this->_config_data[$file_name])) {
  957. +            $this->_trigger_error_msg("Unknown config file '$file_name'");
  958. +            return;
  959. +        }
  960. +
  961. +        if (empty($section))
  962. +            return array_keys($this->_config_data[$file_name]["vars"]);
  963. +        else
  964. +            return array_keys($this->_config_data[$file_name]["sections"][$section]["vars"]);
  965. +    }
  966. +
  967. +
  968. +    /**
  969. +     * Clear loaded config data for a certain file or all files.
  970. +     *
  971. +     * @param string $file_name file to clear config data for
  972. +     */
  973. +    function clear($file_name = NULL)
  974. +    {
  975. +        if ($file_name === NULL)
  976. +            $this->_config_data = array();
  977. +        else if (isset($this->_config_data[$file_name]))
  978. +            $this->_config_data[$file_name] = array();
  979. +    }
  980. +
  981. +
  982. +    /**
  983. +     * Load a configuration file manually.
  984. +     *
  985. +     * @param string $file_name file name to load
  986. +     * @param boolean $prepend_path whether current config path should be
  987. +     *                              prepended to the filename
  988. +     */
  989. +    function load_file($file_name, $prepend_path = true)
  990. +    {
  991. +        if ($prepend_path && $this->_config_path != "")
  992. +            $config_file = $this->_config_path . $file_name;
  993. +        else
  994. +            $config_file = $file_name;
  995. +
  996. +        ini_set('track_errors', true);
  997. +        $fp = @fopen($config_file, "r");
  998. +        if (!is_resource($fp)) {
  999. +            $this->_trigger_error_msg("Could not open config file '$config_file'");
  1000. +            return false;
  1001. +        }
  1002. +
  1003. +        $contents = ($size = filesize($config_file)) ? fread($fp, $size) : '';
  1004. +        fclose($fp);
  1005. +
  1006. +        $this->_config_data[$config_file] = $this->parse_contents($contents);
  1007. +        return true;
  1008. +    }
  1009. +
  1010. +    /**
  1011. +     * Store the contents of a file manually.
  1012. +     *
  1013. +     * @param string $config_file file name of the related contents
  1014. +     * @param string $contents the file-contents to parse
  1015. +     */
  1016. +    function set_file_contents($config_file, $contents)
  1017. +    {
  1018. +        $this->_config_data[$config_file] = $this->parse_contents($contents);
  1019. +        return true;
  1020. +    }
  1021. +
  1022. +    /**
  1023. +     * parse the source of a configuration file manually.
  1024. +     *
  1025. +     * @param string $contents the file-contents to parse
  1026. +     */
  1027. +    function parse_contents($contents)
  1028. +    {
  1029. +        if($this->fix_newlines) {
  1030. +            // fix mac/dos formatted newlines
  1031. +            $contents = preg_replace('!\r\n?!', "\n", $contents);
  1032. +        }
  1033. +
  1034. +        $config_data = array();
  1035. +        $config_data['sections'] = array();
  1036. +        $config_data['vars'] = array();
  1037. +
  1038. +        /* reference to fill with data */
  1039. +        $vars =& $config_data['vars'];
  1040. +
  1041. +        /* parse file line by line */
  1042. +        preg_match_all('!^.*\r?\n?!m', $contents, $match);
  1043. +        $lines = $match[0];
  1044. +        for ($i=0, $count=count($lines); $i<$count; $i++) {
  1045. +            $line = $lines[$i];
  1046. +            if (empty($line)) continue;
  1047. +
  1048. +            if ( substr($line, 0, 1) == '[' && preg_match('!^\[(.*?)\]!', $line, $match) ) {
  1049. +                /* section found */
  1050. +                if (substr($match[1], 0, 1) == '.') {
  1051. +                    /* hidden section */
  1052. +                    if ($this->read_hidden) {
  1053. +                        $section_name = substr($match[1], 1);
  1054. +                    } else {
  1055. +                        /* break reference to $vars to ignore hidden section */
  1056. +                        unset($vars);
  1057. +                        $vars = array();
  1058. +                        continue;
  1059. +                    }
  1060. +                } else {                    
  1061. +                    $section_name = $match[1];
  1062. +                }
  1063. +                if (!isset($config_data['sections'][$section_name]))
  1064. +                    $config_data['sections'][$section_name] = array('vars' => array());
  1065. +                $vars =& $config_data['sections'][$section_name]['vars'];
  1066. +                continue;
  1067. +            }
  1068. +
  1069. +            if (preg_match('/^\s*(\.?\w+)\s*=\s*(.*)/s', $line, $match)) {
  1070. +                /* variable found */
  1071. +                $var_name = rtrim($match[1]);
  1072. +                if (strpos($match[2], '"""') === 0) {
  1073. +                    /* handle multiline-value */
  1074. +                    $lines[$i] = substr($match[2], 3);
  1075. +                    $var_value = '';
  1076. +                    while ($i<$count) {
  1077. +                        if (($pos = strpos($lines[$i], '"""')) === false) {
  1078. +                            $var_value .= $lines[$i++];
  1079. +                        } else {
  1080. +                            /* end of multiline-value */
  1081. +                            $var_value .= substr($lines[$i], 0, $pos);
  1082. +                            break;
  1083. +                        }
  1084. +                    }
  1085. +                    $booleanize = false;
  1086. +
  1087. +                } else {
  1088. +                    /* handle simple value */
  1089. +                    $var_value = preg_replace('/^([\'"])(.*)$/', '\2', rtrim($match[2]));
  1090. +                    $booleanize = $this->booleanize;
  1091. +
  1092. +                }
  1093. +                $this->_set_config_var($vars, $var_name, $var_value, $booleanize);
  1094. +            }
  1095. +            /* else unparsable line / means it is a comment / means ignore it */
  1096. +        }
  1097. +        return $config_data;
  1098. +    }
  1099. +
  1100. +    /**#@+ @access private */
  1101. +    /**
  1102. +     * @param array &$container
  1103. +     * @param string $var_name
  1104. +     * @param mixed $var_value
  1105. +     * @param boolean $booleanize determines whether $var_value is converted to
  1106. +     *                            to true/false
  1107. +     */
  1108. +    function _set_config_var(&$container, $var_name, $var_value, $booleanize)
  1109. +    {
  1110. +        if (substr($var_name, 0, 1) == '.') {
  1111. +            if (!$this->read_hidden)
  1112. +                return;
  1113. +            else
  1114. +                $var_name = substr($var_name, 1);
  1115. +        }
  1116. +
  1117. +        if (!preg_match("/^[a-zA-Z_]\w*$/", $var_name)) {
  1118. +            $this->_trigger_error_msg("Bad variable name '$var_name'");
  1119. +            return;
  1120. +        }
  1121. +
  1122. +        if ($booleanize) {
  1123. +            if (preg_match("/^(on|true|yes)$/i", $var_value))
  1124. +                $var_value = true;
  1125. +            else if (preg_match("/^(off|false|no)$/i", $var_value))
  1126. +                $var_value = false;
  1127. +        }
  1128. +
  1129. +        if (!isset($container[$var_name]) || $this->overwrite)
  1130. +            $container[$var_name] = $var_value;
  1131. +        else {
  1132. +            settype($container[$var_name], 'array');
  1133. +            $container[$var_name][] = $var_value;
  1134. +        }
  1135. +    }
  1136. +
  1137. +    /**
  1138. +     * @uses trigger_error() creates a PHP warning/error
  1139. +     * @param string $error_msg
  1140. +     * @param integer $error_type one of
  1141. +     */
  1142. +    function _trigger_error_msg($error_msg, $error_type = E_USER_WARNING)
  1143. +    {
  1144. +        trigger_error("Config_File error: $error_msg", $error_type);
  1145. +    }
  1146. +    /**#@-*/
  1147. +}
  1148. +
  1149. +?>
  1150. diff --git a/library/smarty/Smarty.class.php b/library/smarty/Smarty.class.php
  1151. new file mode 100644
  1152. --- /dev/null
  1153. +++ b/library/smarty/Smarty.class.php
  1154. @@ -0,0 +1,1961 @@
  1155. +<?php
  1156. +
  1157. +/**
  1158. + * Project:     Smarty: the PHP compiling template engine
  1159. + * File:        Smarty.class.php
  1160. + *
  1161. + * This library is free software; you can redistribute it and/or
  1162. + * modify it under the terms of the GNU Lesser General Public
  1163. + * License as published by the Free Software Foundation; either
  1164. + * version 2.1 of the License, or (at your option) any later version.
  1165. + *
  1166. + * This library is distributed in the hope that it will be useful,
  1167. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  1168. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  1169. + * Lesser General Public License for more details.
  1170. + *
  1171. + * You should have received a copy of the GNU Lesser General Public
  1172. + * License along with this library; if not, write to the Free Software
  1173. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  1174. + *
  1175. + * For questions, help, comments, discussion, etc., please join the
  1176. + * Smarty mailing list. Send a blank e-mail to
  1177. + *
  1178. + * @link http://www.smarty.net/
  1179. + * @copyright 2001-2005 New Digital Group, Inc.
  1180. + * @author Monte Ohrt <monte at ohrt dot com>
  1181. + * @author Andrei Zmievski <[email protected]>
  1182. + * @package Smarty
  1183. + * @version 2.6.26
  1184. + */
  1185. +
  1186. +/* $Id: Smarty.class.php 3163 2009-06-17 14:39:24Z monte.ohrt $ */
  1187. +
  1188. +/**
  1189. + * DIR_SEP isn't used anymore, but third party apps might
  1190. + */
  1191. +if(!defined('DIR_SEP')) {
  1192. +    define('DIR_SEP', DIRECTORY_SEPARATOR);
  1193. +}
  1194. +
  1195. +/**
  1196. + * set SMARTY_DIR to absolute path to Smarty library files.
  1197. + * if not defined, include_path will be used. Sets SMARTY_DIR only if user
  1198. + * application has not already defined it.
  1199. + */
  1200. +
  1201. +if (!defined('SMARTY_DIR')) {
  1202. +    define('SMARTY_DIR', dirname(__FILE__) . DIRECTORY_SEPARATOR);
  1203. +}
  1204. +
  1205. +if (!defined('SMARTY_CORE_DIR')) {
  1206. +    define('SMARTY_CORE_DIR', SMARTY_DIR . 'internals' . DIRECTORY_SEPARATOR);
  1207. +}
  1208. +
  1209. +define('SMARTY_PHP_PASSTHRU',   0);
  1210. +define('SMARTY_PHP_QUOTE',      1);
  1211. +define('SMARTY_PHP_REMOVE',     2);
  1212. +define('SMARTY_PHP_ALLOW',      3);
  1213. +
  1214. +/**
  1215. + * @package Smarty
  1216. + */
  1217. +class Smarty
  1218. +{
  1219. +    /**#@+
  1220. +     * Smarty Configuration Section
  1221. +     */
  1222. +
  1223. +    /**
  1224. +     * The name of the directory where templates are located.
  1225. +     *
  1226. +     * @var string
  1227. +     */
  1228. +    var $template_dir    =  'templates';
  1229. +
  1230. +    /**
  1231. +     * The directory where compiled templates are located.
  1232. +     *
  1233. +     * @var string
  1234. +     */
  1235. +    var $compile_dir     =  'templates_c';
  1236. +
  1237. +    /**
  1238. +     * The directory where config files are located.
  1239. +     *
  1240. +     * @var string
  1241. +     */
  1242. +    var $config_dir      =  'configs';
  1243. +
  1244. +    /**
  1245. +     * An array of directories searched for plugins.
  1246. +     *
  1247. +     * @var array
  1248. +     */
  1249. +    var $plugins_dir     =  array('plugins');
  1250. +
  1251. +    /**
  1252. +     * If debugging is enabled, a debug console window will display
  1253. +     * when the page loads (make sure your browser allows unrequested
  1254. +     * popup windows)
  1255. +     *
  1256. +     * @var boolean
  1257. +     */
  1258. +    var $debugging       =  false;
  1259. +
  1260. +    /**
  1261. +     * When set, smarty does uses this value as error_reporting-level.
  1262. +     *
  1263. +     * @var integer
  1264. +     */
  1265. +    var $error_reporting  =  null;
  1266. +
  1267. +    /**
  1268. +     * This is the path to the debug console template. If not set,
  1269. +     * the default one will be used.
  1270. +     *
  1271. +     * @var string
  1272. +     */
  1273. +    var $debug_tpl       =  '';
  1274. +
  1275. +    /**
  1276. +     * This determines if debugging is enable-able from the browser.
  1277. +     * <ul>
  1278. +     *  <li>NONE => no debugging control allowed</li>
  1279. +     *  <li>URL => enable debugging when SMARTY_DEBUG is found in the URL.</li>
  1280. +     * </ul>
  1281. +     * @link http://www.foo.dom/index.php?SMARTY_DEBUG
  1282. +     * @var string
  1283. +     */
  1284. +    var $debugging_ctrl  =  'NONE';
  1285. +
  1286. +    /**
  1287. +     * This tells Smarty whether to check for recompiling or not. Recompiling
  1288. +     * does not need to happen unless a template or config file is changed.
  1289. +     * Typically you enable this during development, and disable for
  1290. +     * production.
  1291. +     *
  1292. +     * @var boolean
  1293. +     */
  1294. +    var $compile_check   =  true;
  1295. +
  1296. +    /**
  1297. +     * This forces templates to compile every time. Useful for development
  1298. +     * or debugging.
  1299. +     *
  1300. +     * @var boolean
  1301. +     */
  1302. +    var $force_compile   =  false;
  1303. +
  1304. +    /**
  1305. +     * This enables template caching.
  1306. +     * <ul>
  1307. +     *  <li>0 = no caching</li>
  1308. +     *  <li>1 = use class cache_lifetime value</li>
  1309. +     *  <li>2 = use cache_lifetime in cache file</li>
  1310. +     * </ul>
  1311. +     * @var integer
  1312. +     */
  1313. +    var $caching         =  0;
  1314. +
  1315. +    /**
  1316. +     * The name of the directory for cache files.
  1317. +     *
  1318. +     * @var string
  1319. +     */
  1320. +    var $cache_dir       =  'cache';
  1321. +
  1322. +    /**
  1323. +     * This is the number of seconds cached content will persist.
  1324. +     * <ul>
  1325. +     *  <li>0 = always regenerate cache</li>
  1326. +     *  <li>-1 = never expires</li>
  1327. +     * </ul>
  1328. +     *
  1329. +     * @var integer
  1330. +     */
  1331. +    var $cache_lifetime  =  3600;
  1332. +
  1333. +    /**
  1334. +     * Only used when $caching is enabled. If true, then If-Modified-Since headers
  1335. +     * are respected with cached content, and appropriate HTTP headers are sent.
  1336. +     * This way repeated hits to a cached page do not send the entire page to the
  1337. +     * client every time.
  1338. +     *
  1339. +     * @var boolean
  1340. +     */
  1341. +    var $cache_modified_check = false;
  1342. +
  1343. +    /**
  1344. +     * This determines how Smarty handles "<?php ... ?>" tags in templates.
  1345. +     * possible values:
  1346. +     * <ul>
  1347. +     *  <li>SMARTY_PHP_PASSTHRU -> print tags as plain text</li>
  1348. +     *  <li>SMARTY_PHP_QUOTE    -> escape tags as entities</li>
  1349. +     *  <li>SMARTY_PHP_REMOVE   -> remove php tags</li>
  1350. +     *  <li>SMARTY_PHP_ALLOW    -> execute php tags</li>
  1351. +     * </ul>
  1352. +     *
  1353. +     * @var integer
  1354. +     */
  1355. +    var $php_handling    =  SMARTY_PHP_PASSTHRU;
  1356. +
  1357. +    /**
  1358. +     * This enables template security. When enabled, many things are restricted
  1359. +     * in the templates that normally would go unchecked. This is useful when
  1360. +     * untrusted parties are editing templates and you want a reasonable level
  1361. +     * of security. (no direct execution of PHP in templates for example)
  1362. +     *
  1363. +     * @var boolean
  1364. +     */
  1365. +    var $security       =   false;
  1366. +
  1367. +    /**
  1368. +     * This is the list of template directories that are considered secure. This
  1369. +     * is used only if {@link $security} is enabled. One directory per array
  1370. +     * element.  {@link $template_dir} is in this list implicitly.
  1371. +     *
  1372. +     * @var array
  1373. +     */
  1374. +    var $secure_dir     =   array();
  1375. +
  1376. +    /**
  1377. +     * These are the security settings for Smarty. They are used only when
  1378. +     * {@link $security} is enabled.
  1379. +     *
  1380. +     * @var array
  1381. +     */
  1382. +    var $security_settings  = array(
  1383. +                                    'PHP_HANDLING'    => false,
  1384. +                                    'IF_FUNCS'        => array('array', 'list',
  1385. +                                                               'isset', 'empty',
  1386. +                                                               'count', 'sizeof',
  1387. +                                                               'in_array', 'is_array',
  1388. +                                                               'true', 'false', 'null'),
  1389. +                                    'INCLUDE_ANY'     => false,
  1390. +                                    'PHP_TAGS'        => false,
  1391. +                                    'MODIFIER_FUNCS'  => array('count'),
  1392. +                                    'ALLOW_CONSTANTS'  => false,
  1393. +                                    'ALLOW_SUPER_GLOBALS' => true
  1394. +                                   );
  1395. +
  1396. +    /**
  1397. +     * This is an array of directories where trusted php scripts reside.
  1398. +     * {@link $security} is disabled during their inclusion/execution.
  1399. +     *
  1400. +     * @var array
  1401. +     */
  1402. +    var $trusted_dir        = array();
  1403. +
  1404. +    /**
  1405. +     * The left delimiter used for the template tags.
  1406. +     *
  1407. +     * @var string
  1408. +     */
  1409. +    var $left_delimiter  =  '{';
  1410. +
  1411. +    /**
  1412. +     * The right delimiter used for the template tags.
  1413. +     *
  1414. +     * @var string
  1415. +     */
  1416. +    var $right_delimiter =  '}';
  1417. +
  1418. +    /**
  1419. +     * The order in which request variables are registered, similar to
  1420. +     * variables_order in php.ini E = Environment, G = GET, P = POST,
  1421. +     * C = Cookies, S = Server
  1422. +     *
  1423. +     * @var string
  1424. +     */
  1425. +    var $request_vars_order    = 'EGPCS';
  1426. +
  1427. +    /**
  1428. +     * Indicates wether $HTTP_*_VARS[] (request_use_auto_globals=false)
  1429. +     * are uses as request-vars or $_*[]-vars. note: if
  1430. +     * request_use_auto_globals is true, then $request_vars_order has
  1431. +     * no effect, but the php-ini-value "gpc_order"
  1432. +     *
  1433. +     * @var boolean
  1434. +     */
  1435. +    var $request_use_auto_globals      = true;
  1436. +
  1437. +    /**
  1438. +     * Set this if you want different sets of compiled files for the same
  1439. +     * templates. This is useful for things like different languages.
  1440. +     * Instead of creating separate sets of templates per language, you
  1441. +     * set different compile_ids like 'en' and 'de'.
  1442. +     *
  1443. +     * @var string
  1444. +     */
  1445. +    var $compile_id            = null;
  1446. +
  1447. +    /**
  1448. +     * This tells Smarty whether or not to use sub dirs in the cache/ and
  1449. +     * templates_c/ directories. sub directories better organized, but
  1450. +     * may not work well with PHP safe mode enabled.
  1451. +     *
  1452. +     * @var boolean
  1453. +     *
  1454. +     */
  1455. +    var $use_sub_dirs          = false;
  1456. +
  1457. +    /**
  1458. +     * This is a list of the modifiers to apply to all template variables.
  1459. +     * Put each modifier in a separate array element in the order you want
  1460. +     * them applied. example: <code>array('escape:"htmlall"');</code>
  1461. +     *
  1462. +     * @var array
  1463. +     */
  1464. +    var $default_modifiers        = array();
  1465. +
  1466. +    /**
  1467. +     * This is the resource type to be used when not specified
  1468. +     * at the beginning of the resource path. examples:
  1469. +     * $smarty->display('file:index.tpl');
  1470. +     * $smarty->display('db:index.tpl');
  1471. +     * $smarty->display('index.tpl'); // will use default resource type
  1472. +     * {include file="file:index.tpl"}
  1473. +     * {include file="db:index.tpl"}
  1474. +     * {include file="index.tpl"} {* will use default resource type *}
  1475. +     *
  1476. +     * @var array
  1477. +     */
  1478. +    var $default_resource_type    = 'file';
  1479. +
  1480. +    /**
  1481. +     * The function used for cache file handling. If not set, built-in caching is used.
  1482. +     *
  1483. +     * @var null|string function name
  1484. +     */
  1485. +    var $cache_handler_func   = null;
  1486. +
  1487. +    /**
  1488. +     * This indicates which filters are automatically loaded into Smarty.
  1489. +     *
  1490. +     * @var array array of filter names
  1491. +     */
  1492. +    var $autoload_filters = array();
  1493. +
  1494. +    /**#@+
  1495. +     * @var boolean
  1496. +     */
  1497. +    /**
  1498. +     * This tells if config file vars of the same name overwrite each other or not.
  1499. +     * if disabled, same name variables are accumulated in an array.
  1500. +     */
  1501. +    var $config_overwrite = true;
  1502. +
  1503. +    /**
  1504. +     * This tells whether or not to automatically booleanize config file variables.
  1505. +     * If enabled, then the strings "on", "true", and "yes" are treated as boolean
  1506. +     * true, and "off", "false" and "no" are treated as boolean false.
  1507. +     */
  1508. +    var $config_booleanize = true;
  1509. +
  1510. +    /**
  1511. +     * This tells whether hidden sections [.foobar] are readable from the
  1512. +     * tempalates or not. Normally you would never allow this since that is
  1513. +     * the point behind hidden sections: the application can access them, but
  1514. +     * the templates cannot.
  1515. +     */
  1516. +    var $config_read_hidden = false;
  1517. +
  1518. +    /**
  1519. +     * This tells whether or not automatically fix newlines in config files.
  1520. +     * It basically converts \r (mac) or \r\n (dos) to \n
  1521. +     */
  1522. +    var $config_fix_newlines = true;
  1523. +    /**#@-*/
  1524. +
  1525. +    /**
  1526. +     * If a template cannot be found, this PHP function will be executed.
  1527. +     * Useful for creating templates on-the-fly or other special action.
  1528. +     *
  1529. +     * @var string function name
  1530. +     */
  1531. +    var $default_template_handler_func = '';
  1532. +
  1533. +    /**
  1534. +     * The file that contains the compiler class. This can a full
  1535. +     * pathname, or relative to the php_include path.
  1536. +     *
  1537. +     * @var string
  1538. +     */
  1539. +    var $compiler_file        =    'Smarty_Compiler.class.php';
  1540. +
  1541. +    /**
  1542. +     * The class used for compiling templates.
  1543. +     *
  1544. +     * @var string
  1545. +     */
  1546. +    var $compiler_class        =   'Smarty_Compiler';
  1547. +
  1548. +    /**
  1549. +     * The class used to load config vars.
  1550. +     *
  1551. +     * @var string
  1552. +     */
  1553. +    var $config_class          =   'Config_File';
  1554. +
  1555. +/**#@+
  1556. + * END Smarty Configuration Section
  1557. + * There should be no need to touch anything below this line.
  1558. + * @access private
  1559. + */
  1560. +    /**
  1561. +     * where assigned template vars are kept
  1562. +     *
  1563. +     * @var array
  1564. +     */
  1565. +    var $_tpl_vars             = array();
  1566. +
  1567. +    /**
  1568. +     * stores run-time $smarty.* vars
  1569. +     *
  1570. +     * @var null|array
  1571. +     */
  1572. +    var $_smarty_vars          = null;
  1573. +
  1574. +    /**
  1575. +     * keeps track of sections
  1576. +     *
  1577. +     * @var array
  1578. +     */
  1579. +    var $_sections             = array();
  1580. +
  1581. +    /**
  1582. +     * keeps track of foreach blocks
  1583. +     *
  1584. +     * @var array
  1585. +     */
  1586. +    var $_foreach              = array();
  1587. +
  1588. +    /**
  1589. +     * keeps track of tag hierarchy
  1590. +     *
  1591. +     * @var array
  1592. +     */
  1593. +    var $_tag_stack            = array();
  1594. +
  1595. +    /**
  1596. +     * configuration object
  1597. +     *
  1598. +     * @var Config_file
  1599. +     */
  1600. +    var $_conf_obj             = null;
  1601. +
  1602. +    /**
  1603. +     * loaded configuration settings
  1604. +     *
  1605. +     * @var array
  1606. +     */
  1607. +    var $_config               = array(array('vars'  => array(), 'files' => array()));
  1608. +
  1609. +    /**
  1610. +     * md5 checksum of the string 'Smarty'
  1611. +     *
  1612. +     * @var string
  1613. +     */
  1614. +    var $_smarty_md5           = 'f8d698aea36fcbead2b9d5359ffca76f';
  1615. +
  1616. +    /**
  1617. +     * Smarty version number
  1618. +     *
  1619. +     * @var string
  1620. +     */
  1621. +    var $_version              = '2.6.26';
  1622. +
  1623. +    /**
  1624. +     * current template inclusion depth
  1625. +     *
  1626. +     * @var integer
  1627. +     */
  1628. +    var $_inclusion_depth      = 0;
  1629. +
  1630. +    /**
  1631. +     * for different compiled templates
  1632. +     *
  1633. +     * @var string
  1634. +     */
  1635. +    var $_compile_id           = null;
  1636. +
  1637. +    /**
  1638. +     * text in URL to enable debug mode
  1639. +     *
  1640. +     * @var string
  1641. +     */
  1642. +    var $_smarty_debug_id      = 'SMARTY_DEBUG';
  1643. +
  1644. +    /**
  1645. +     * debugging information for debug console
  1646. +     *
  1647. +     * @var array
  1648. +     */
  1649. +    var $_smarty_debug_info    = array();
  1650. +
  1651. +    /**
  1652. +     * info that makes up a cache file
  1653. +     *
  1654. +     * @var array
  1655. +     */
  1656. +    var $_cache_info           = array();
  1657. +
  1658. +    /**
  1659. +     * default file permissions
  1660. +     *
  1661. +     * @var integer
  1662. +     */
  1663. +    var $_file_perms           = 0644;
  1664. +
  1665. +    /**
  1666. +     * default dir permissions
  1667. +     *
  1668. +     * @var integer
  1669. +     */
  1670. +    var $_dir_perms               = 0771;
  1671. +
  1672. +    /**
  1673. +     * registered objects
  1674. +     *
  1675. +     * @var array
  1676. +     */
  1677. +    var $_reg_objects           = array();
  1678. +
  1679. +    /**
  1680. +     * table keeping track of plugins
  1681. +     *
  1682. +     * @var array
  1683. +     */
  1684. +    var $_plugins              = array(
  1685. +                                       'modifier'      => array(),
  1686. +                                       'function'      => array(),
  1687. +                                       'block'         => array(),
  1688. +                                       'compiler'      => array(),
  1689. +                                       'prefilter'     => array(),
  1690. +                                       'postfilter'    => array(),
  1691. +                                       'outputfilter'  => array(),
  1692. +                                       'resource'      => array(),
  1693. +                                       'insert'        => array());
  1694. +
  1695. +
  1696. +    /**
  1697. +     * cache serials
  1698. +     *
  1699. +     * @var array
  1700. +     */
  1701. +    var $_cache_serials = array();
  1702. +
  1703. +    /**
  1704. +     * name of optional cache include file
  1705. +     *
  1706. +     * @var string
  1707. +     */
  1708. +    var $_cache_include = null;
  1709. +
  1710. +    /**
  1711. +     * indicate if the current code is used in a compiled
  1712. +     * include
  1713. +     *
  1714. +     * @var string
  1715. +     */
  1716. +    var $_cache_including = false;
  1717. +
  1718. +    /**#@-*/
  1719. +    /**
  1720. +     * The class constructor.
  1721. +     */
  1722. +    function Smarty()
  1723. +    {
  1724. +      $this->assign('SCRIPT_NAME', isset($_SERVER['SCRIPT_NAME']) ? $_SERVER['SCRIPT_NAME']
  1725. +                    : @$GLOBALS['HTTP_SERVER_VARS']['SCRIPT_NAME']);
  1726. +    }
  1727. +
  1728. +    /**
  1729. +     * assigns values to template variables
  1730. +     *
  1731. +     * @param array|string $tpl_var the template variable name(s)
  1732. +     * @param mixed $value the value to assign
  1733. +     */
  1734. +    function assign($tpl_var, $value = null)
  1735. +    {
  1736. +        if (is_array($tpl_var)){
  1737. +            foreach ($tpl_var as $key => $val) {
  1738. +                if ($key != '') {
  1739. +                    $this->_tpl_vars[$key] = $val;
  1740. +                }
  1741. +            }
  1742. +        } else {
  1743. +            if ($tpl_var != '')
  1744. +                $this->_tpl_vars[$tpl_var] = $value;
  1745. +        }
  1746. +    }
  1747. +
  1748. +    /**
  1749. +     * assigns values to template variables by reference
  1750. +     *
  1751. +     * @param string $tpl_var the template variable name
  1752. +     * @param mixed $value the referenced value to assign
  1753. +     */
  1754. +    function assign_by_ref($tpl_var, &$value)
  1755. +    {
  1756. +        if ($tpl_var != '')
  1757. +            $this->_tpl_vars[$tpl_var] = &$value;
  1758. +    }
  1759. +
  1760. +    /**
  1761. +     * appends values to template variables
  1762. +     *
  1763. +     * @param array|string $tpl_var the template variable name(s)
  1764. +     * @param mixed $value the value to append
  1765. +     */
  1766. +    function append($tpl_var, $value=null, $merge=false)
  1767. +    {
  1768. +        if (is_array($tpl_var)) {
  1769. +            // $tpl_var is an array, ignore $value
  1770. +            foreach ($tpl_var as $_key => $_val) {
  1771. +                if ($_key != '') {
  1772. +                    if(!@is_array($this->_tpl_vars[$_key])) {
  1773. +                        settype($this->_tpl_vars[$_key],'array');
  1774. +                    }
  1775. +                    if($merge && is_array($_val)) {
  1776. +                        foreach($_val as $_mkey => $_mval) {
  1777. +                            $this->_tpl_vars[$_key][$_mkey] = $_mval;
  1778. +                        }
  1779. +                    } else {
  1780. +                        $this->_tpl_vars[$_key][] = $_val;
  1781. +                    }
  1782. +                }
  1783. +            }
  1784. +        } else {
  1785. +            if ($tpl_var != '' && isset($value)) {
  1786. +                if(!@is_array($this->_tpl_vars[$tpl_var])) {
  1787. +                    settype($this->_tpl_vars[$tpl_var],'array');
  1788. +                }
  1789. +                if($merge && is_array($value)) {
  1790. +                    foreach($value as $_mkey => $_mval) {
  1791. +                        $this->_tpl_vars[$tpl_var][$_mkey] = $_mval;
  1792. +                    }
  1793. +                } else {
  1794. +                    $this->_tpl_vars[$tpl_var][] = $value;
  1795. +                }
  1796. +            }
  1797. +        }
  1798. +    }
  1799. +
  1800. +    /**
  1801. +     * appends values to template variables by reference
  1802. +     *
  1803. +     * @param string $tpl_var the template variable name
  1804. +     * @param mixed $value the referenced value to append
  1805. +     */
  1806. +    function append_by_ref($tpl_var, &$value, $merge=false)
  1807. +    {
  1808. +        if ($tpl_var != '' && isset($value)) {
  1809. +            if(!@is_array($this->_tpl_vars[$tpl_var])) {
  1810. +             settype($this->_tpl_vars[$tpl_var],'array');
  1811. +            }
  1812. +            if ($merge && is_array($value)) {
  1813. +                foreach($value as $_key => $_val) {
  1814. +                    $this->_tpl_vars[$tpl_var][$_key] = &$value[$_key];
  1815. +                }
  1816. +            } else {
  1817. +                $this->_tpl_vars[$tpl_var][] = &$value;
  1818. +            }
  1819. +        }
  1820. +    }
  1821. +
  1822. +
  1823. +    /**
  1824. +     * clear the given assigned template variable.
  1825. +     *
  1826. +     * @param string $tpl_var the template variable to clear
  1827. +     */
  1828. +    function clear_assign($tpl_var)
  1829. +    {
  1830. +        if (is_array($tpl_var))
  1831. +            foreach ($tpl_var as $curr_var)
  1832. +                unset($this->_tpl_vars[$curr_var]);
  1833. +        else
  1834. +            unset($this->_tpl_vars[$tpl_var]);
  1835. +    }
  1836. +
  1837. +
  1838. +    /**
  1839. +     * Registers custom function to be used in templates
  1840. +     *
  1841. +     * @param string $function the name of the template function
  1842. +     * @param string $function_impl the name of the PHP function to register
  1843. +     */
  1844. +    function register_function($function, $function_impl, $cacheable=true, $cache_attrs=null)
  1845. +    {
  1846. +        $this->_plugins['function'][$function] =
  1847. +            array($function_impl, null, null, false, $cacheable, $cache_attrs);
  1848. +
  1849. +    }
  1850. +
  1851. +    /**
  1852. +     * Unregisters custom function
  1853. +     *
  1854. +     * @param string $function name of template function
  1855. +     */
  1856. +    function unregister_function($function)
  1857. +    {
  1858. +        unset($this->_plugins['function'][$function]);
  1859. +    }
  1860. +
  1861. +    /**
  1862. +     * Registers object to be used in templates
  1863. +     *
  1864. +     * @param string $object name of template object
  1865. +     * @param object &$object_impl the referenced PHP object to register
  1866. +     * @param null|array $allowed list of allowed methods (empty = all)
  1867. +     * @param boolean $smarty_args smarty argument format, else traditional
  1868. +     * @param null|array $block_functs list of methods that are block format
  1869. +     */
  1870. +    function register_object($object, &$object_impl, $allowed = array(), $smarty_args = true, $block_methods = array())
  1871. +    {
  1872. +        settype($allowed, 'array');
  1873. +        settype($smarty_args, 'boolean');
  1874. +        $this->_reg_objects[$object] =
  1875. +            array(&$object_impl, $allowed, $smarty_args, $block_methods);
  1876. +    }
  1877. +
  1878. +    /**
  1879. +     * Unregisters object
  1880. +     *
  1881. +     * @param string $object name of template object
  1882. +     */
  1883. +    function unregister_object($object)
  1884. +    {
  1885. +        unset($this->_reg_objects[$object]);
  1886. +    }
  1887. +
  1888. +
  1889. +    /**
  1890. +     * Registers block function to be used in templates
  1891. +     *
  1892. +     * @param string $block name of template block
  1893. +     * @param string $block_impl PHP function to register
  1894. +     */
  1895. +    function register_block($block, $block_impl, $cacheable=true, $cache_attrs=null)
  1896. +    {
  1897. +        $this->_plugins['block'][$block] =
  1898. +            array($block_impl, null, null, false, $cacheable, $cache_attrs);
  1899. +    }
  1900. +
  1901. +    /**
  1902. +     * Unregisters block function
  1903. +     *
  1904. +     * @param string $block name of template function
  1905. +     */
  1906. +    function unregister_block($block)
  1907. +    {
  1908. +        unset($this->_plugins['block'][$block]);
  1909. +    }
  1910. +
  1911. +    /**
  1912. +     * Registers compiler function
  1913. +     *
  1914. +     * @param string $function name of template function
  1915. +     * @param string $function_impl name of PHP function to register
  1916. +     */
  1917. +    function register_compiler_function($function, $function_impl, $cacheable=true)
  1918. +    {
  1919. +        $this->_plugins['compiler'][$function] =
  1920. +            array($function_impl, null, null, false, $cacheable);
  1921. +    }
  1922. +
  1923. +    /**
  1924. +     * Unregisters compiler function
  1925. +     *
  1926. +     * @param string $function name of template function
  1927. +     */
  1928. +    function unregister_compiler_function($function)
  1929. +    {
  1930. +        unset($this->_plugins['compiler'][$function]);
  1931. +    }
  1932. +
  1933. +    /**
  1934. +     * Registers modifier to be used in templates
  1935. +     *
  1936. +     * @param string $modifier name of template modifier
  1937. +     * @param string $modifier_impl name of PHP function to register
  1938. +     */
  1939. +    function register_modifier($modifier, $modifier_impl)
  1940. +    {
  1941. +        $this->_plugins['modifier'][$modifier] =
  1942. +            array($modifier_impl, null, null, false);
  1943. +    }
  1944. +
  1945. +    /**
  1946. +     * Unregisters modifier
  1947. +     *
  1948. +     * @param string $modifier name of template modifier
  1949. +     */
  1950. +    function unregister_modifier($modifier)
  1951. +    {
  1952. +        unset($this->_plugins['modifier'][$modifier]);
  1953. +    }
  1954. +
  1955. +    /**
  1956. +     * Registers a resource to fetch a template
  1957. +     *
  1958. +     * @param string $type name of resource
  1959. +     * @param array $functions array of functions to handle resource
  1960. +     */
  1961. +    function register_resource($type, $functions)
  1962. +    {
  1963. +        if (count($functions)==4) {
  1964. +            $this->_plugins['resource'][$type] =
  1965. +                array($functions, false);
  1966. +
  1967. +        } elseif (count($functions)==5) {
  1968. +            $this->_plugins['resource'][$type] =
  1969. +                array(array(array(&$functions[0], $functions[1])
  1970. +                            ,array(&$functions[0], $functions[2])
  1971. +                            ,array(&$functions[0], $functions[3])
  1972. +                            ,array(&$functions[0], $functions[4]))
  1973. +                      ,false);
  1974. +
  1975. +        } else {
  1976. +            $this->trigger_error("malformed function-list for '$type' in register_resource");
  1977. +
  1978. +        }
  1979. +    }
  1980. +
  1981. +    /**
  1982. +     * Unregisters a resource
  1983. +     *
  1984. +     * @param string $type name of resource
  1985. +     */
  1986. +    function unregister_resource($type)
  1987. +    {
  1988. +        unset($this->_plugins['resource'][$type]);
  1989. +    }
  1990. +
  1991. +    /**
  1992. +     * Registers a prefilter function to apply
  1993. +     * to a template before compiling
  1994. +     *
  1995. +     * @param callback $function
  1996. +     */
  1997. +    function register_prefilter($function)
  1998. +    {
  1999. +        $this->_plugins['prefilter'][$this->_get_filter_name($function)]
  2000. +            = array($function, null, null, false);
  2001. +    }
  2002. +
  2003. +    /**
  2004. +     * Unregisters a prefilter function
  2005. +     *
  2006. +     * @param callback $function
  2007. +     */
  2008. +    function unregister_prefilter($function)
  2009. +    {
  2010. +        unset($this->_plugins['prefilter'][$this->_get_filter_name($function)]);
  2011. +    }
  2012. +
  2013. +    /**
  2014. +     * Registers a postfilter function to apply
  2015. +     * to a compiled template after compilation
  2016. +     *
  2017. +     * @param callback $function
  2018. +     */
  2019. +    function register_postfilter($function)
  2020. +    {
  2021. +        $this->_plugins['postfilter'][$this->_get_filter_name($function)]
  2022. +            = array($function, null, null, false);
  2023. +    }
  2024. +
  2025. +    /**
  2026. +     * Unregisters a postfilter function
  2027. +     *
  2028. +     * @param callback $function
  2029. +     */
  2030. +    function unregister_postfilter($function)
  2031. +    {
  2032. +        unset($this->_plugins['postfilter'][$this->_get_filter_name($function)]);
  2033. +    }
  2034. +
  2035. +    /**
  2036. +     * Registers an output filter function to apply
  2037. +     * to a template output
  2038. +     *
  2039. +     * @param callback $function
  2040. +     */
  2041. +    function register_outputfilter($function)
  2042. +    {
  2043. +        $this->_plugins['outputfilter'][$this->_get_filter_name($function)]
  2044. +            = array($function, null, null, false);
  2045. +    }
  2046. +
  2047. +    /**
  2048. +     * Unregisters an outputfilter function
  2049. +     *
  2050. +     * @param callback $function
  2051. +     */
  2052. +    function unregister_outputfilter($function)
  2053. +    {
  2054. +        unset($this->_plugins['outputfilter'][$this->_get_filter_name($function)]);
  2055. +    }
  2056. +
  2057. +    /**
  2058. +     * load a filter of specified type and name
  2059. +     *
  2060. +     * @param string $type filter type
  2061. +     * @param string $name filter name
  2062. +     */
  2063. +    function load_filter($type, $name)
  2064. +    {
  2065. +        switch ($type) {
  2066. +            case 'output':
  2067. +                $_params = array('plugins' => array(array($type . 'filter', $name, null, null, false)));
  2068. +                require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');
  2069. +                smarty_core_load_plugins($_params, $this);
  2070. +                break;
  2071. +
  2072. +            case 'pre':
  2073. +            case 'post':
  2074. +                if (!isset($this->_plugins[$type . 'filter'][$name]))
  2075. +                    $this->_plugins[$type . 'filter'][$name] = false;
  2076. +                break;
  2077. +        }
  2078. +    }
  2079. +
  2080. +    /**
  2081. +     * clear cached content for the given template and cache id
  2082. +     *
  2083. +     * @param string $tpl_file name of template file
  2084. +     * @param string $cache_id name of cache_id
  2085. +     * @param string $compile_id name of compile_id
  2086. +     * @param string $exp_time expiration time
  2087. +     * @return boolean
  2088. +     */
  2089. +    function clear_cache($tpl_file = null, $cache_id = null, $compile_id = null, $exp_time = null)
  2090. +    {
  2091. +
  2092. +        if (!isset($compile_id))
  2093. +            $compile_id = $this->compile_id;
  2094. +
  2095. +        if (!isset($tpl_file))
  2096. +            $compile_id = null;
  2097. +
  2098. +        $_auto_id = $this->_get_auto_id($cache_id, $compile_id);
  2099. +
  2100. +        if (!empty($this->cache_handler_func)) {
  2101. +            return call_user_func_array($this->cache_handler_func,
  2102. +                                  array('clear', &$this, &$dummy, $tpl_file, $cache_id, $compile_id, $exp_time));
  2103. +        } else {
  2104. +            $_params = array('auto_base' => $this->cache_dir,
  2105. +                            'auto_source' => $tpl_file,
  2106. +                            'auto_id' => $_auto_id,
  2107. +                            'exp_time' => $exp_time);
  2108. +            require_once(SMARTY_CORE_DIR . 'core.rm_auto.php');
  2109. +            return smarty_core_rm_auto($_params, $this);
  2110. +        }
  2111. +
  2112. +    }
  2113. +
  2114. +
  2115. +    /**
  2116. +     * clear the entire contents of cache (all templates)
  2117. +     *
  2118. +     * @param string $exp_time expire time
  2119. +     * @return boolean results of {@link smarty_core_rm_auto()}
  2120. +     */
  2121. +    function clear_all_cache($exp_time = null)
  2122. +    {
  2123. +        return $this->clear_cache(null, null, null, $exp_time);
  2124. +    }
  2125. +
  2126. +
  2127. +    /**
  2128. +     * test to see if valid cache exists for this template
  2129. +     *
  2130. +     * @param string $tpl_file name of template file
  2131. +     * @param string $cache_id
  2132. +     * @param string $compile_id
  2133. +     * @return string|false results of {@link _read_cache_file()}
  2134. +     */
  2135. +    function is_cached($tpl_file, $cache_id = null, $compile_id = null)
  2136. +    {
  2137. +        if (!$this->caching)
  2138. +            return false;
  2139. +
  2140. +        if (!isset($compile_id))
  2141. +            $compile_id = $this->compile_id;
  2142. +
  2143. +        $_params = array(
  2144. +            'tpl_file' => $tpl_file,
  2145. +            'cache_id' => $cache_id,
  2146. +            'compile_id' => $compile_id
  2147. +        );
  2148. +        require_once(SMARTY_CORE_DIR . 'core.read_cache_file.php');
  2149. +        return smarty_core_read_cache_file($_params, $this);
  2150. +    }
  2151. +
  2152. +
  2153. +    /**
  2154. +     * clear all the assigned template variables.
  2155. +     *
  2156. +     */
  2157. +    function clear_all_assign()
  2158. +    {
  2159. +        $this->_tpl_vars = array();
  2160. +    }
  2161. +
  2162. +    /**
  2163. +     * clears compiled version of specified template resource,
  2164. +     * or all compiled template files if one is not specified.
  2165. +     * This function is for advanced use only, not normally needed.
  2166. +     *
  2167. +     * @param string $tpl_file
  2168. +     * @param string $compile_id
  2169. +     * @param string $exp_time
  2170. +     * @return boolean results of {@link smarty_core_rm_auto()}
  2171. +     */
  2172. +    function clear_compiled_tpl($tpl_file = null, $compile_id = null, $exp_time = null)
  2173. +    {
  2174. +        if (!isset($compile_id)) {
  2175. +            $compile_id = $this->compile_id;
  2176. +        }
  2177. +        $_params = array('auto_base' => $this->compile_dir,
  2178. +                        'auto_source' => $tpl_file,
  2179. +                        'auto_id' => $compile_id,
  2180. +                        'exp_time' => $exp_time,
  2181. +                        'extensions' => array('.inc', '.php'));
  2182. +        require_once(SMARTY_CORE_DIR . 'core.rm_auto.php');
  2183. +        return smarty_core_rm_auto($_params, $this);
  2184. +    }
  2185. +
  2186. +    /**
  2187. +     * Checks whether requested template exists.
  2188. +     *
  2189. +     * @param string $tpl_file
  2190. +     * @return boolean
  2191. +     */
  2192. +    function template_exists($tpl_file)
  2193. +    {
  2194. +        $_params = array('resource_name' => $tpl_file, 'quiet'=>true, 'get_source'=>false);
  2195. +        return $this->_fetch_resource_info($_params);
  2196. +    }
  2197. +
  2198. +    /**
  2199. +     * Returns an array containing template variables
  2200. +     *
  2201. +     * @param string $name
  2202. +     * @param string $type
  2203. +     * @return array
  2204. +     */
  2205. +    function &get_template_vars($name=null)
  2206. +    {
  2207. +        if(!isset($name)) {
  2208. +            return $this->_tpl_vars;
  2209. +        } elseif(isset($this->_tpl_vars[$name])) {
  2210. +            return $this->_tpl_vars[$name];
  2211. +        } else {
  2212. +            // var non-existant, return valid reference
  2213. +            $_tmp = null;
  2214. +            return $_tmp;  
  2215. +        }
  2216. +    }
  2217. +
  2218. +    /**
  2219. +     * Returns an array containing config variables
  2220. +     *
  2221. +     * @param string $name
  2222. +     * @param string $type
  2223. +     * @return array
  2224. +     */
  2225. +    function &get_config_vars($name=null)
  2226. +    {
  2227. +        if(!isset($name) && is_array($this->_config[0])) {
  2228. +            return $this->_config[0]['vars'];
  2229. +        } else if(isset($this->_config[0]['vars'][$name])) {
  2230. +            return $this->_config[0]['vars'][$name];
  2231. +        } else {
  2232. +            // var non-existant, return valid reference
  2233. +            $_tmp = null;
  2234. +            return $_tmp;
  2235. +        }
  2236. +    }
  2237. +
  2238. +    /**
  2239. +     * trigger Smarty error
  2240. +     *
  2241. +     * @param string $error_msg
  2242. +     * @param integer $error_type
  2243. +     */
  2244. +    function trigger_error($error_msg, $error_type = E_USER_WARNING)
  2245. +    {
  2246. +        trigger_error("Smarty error: $error_msg", $error_type);
  2247. +    }
  2248. +
  2249. +
  2250. +    /**
  2251. +     * executes & displays the template results
  2252. +     *
  2253. +     * @param string $resource_name
  2254. +     * @param string $cache_id
  2255. +     * @param string $compile_id
  2256. +     */
  2257. +    function display($resource_name, $cache_id = null, $compile_id = null)
  2258. +    {
  2259. +        $this->fetch($resource_name, $cache_id, $compile_id, true);
  2260. +    }
  2261. +
  2262. +    /**
  2263. +     * executes & returns or displays the template results
  2264. +     *
  2265. +     * @param string $resource_name
  2266. +     * @param string $cache_id
  2267. +     * @param string $compile_id
  2268. +     * @param boolean $display
  2269. +     */
  2270. +    function fetch($resource_name, $cache_id = null, $compile_id = null, $display = false)
  2271. +    {
  2272. +        static $_cache_info = array();
  2273. +        
  2274. +        $_smarty_old_error_level = $this->debugging ? error_reporting() : error_reporting(isset($this->error_reporting)
  2275. +               ? $this->error_reporting : error_reporting() & ~E_NOTICE);
  2276. +
  2277. +        if (!$this->debugging && $this->debugging_ctrl == 'URL') {
  2278. +            $_query_string = $this->request_use_auto_globals ? $_SERVER['QUERY_STRING'] : $GLOBALS['HTTP_SERVER_VARS']['QUERY_STRING'];
  2279. +            if (@strstr($_query_string, $this->_smarty_debug_id)) {
  2280. +                if (@strstr($_query_string, $this->_smarty_debug_id . '=on')) {
  2281. +                    // enable debugging for this browser session
  2282. +                    @setcookie('SMARTY_DEBUG', true);
  2283. +                    $this->debugging = true;
  2284. +                } elseif (@strstr($_query_string, $this->_smarty_debug_id . '=off')) {
  2285. +                    // disable debugging for this browser session
  2286. +                    @setcookie('SMARTY_DEBUG', false);
  2287. +                    $this->debugging = false;
  2288. +                } else {
  2289. +                    // enable debugging for this page
  2290. +                    $this->debugging = true;
  2291. +                }
  2292. +            } else {
  2293. +                $this->debugging = (bool)($this->request_use_auto_globals ? @$_COOKIE['SMARTY_DEBUG'] : @$GLOBALS['HTTP_COOKIE_VARS']['SMARTY_DEBUG']);
  2294. +            }
  2295. +        }
  2296. +
  2297. +        if ($this->debugging) {
  2298. +            // capture time for debugging info
  2299. +            $_params = array();
  2300. +            require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
  2301. +            $_debug_start_time = smarty_core_get_microtime($_params, $this);
  2302. +            $this->_smarty_debug_info[] = array('type'      => 'template',
  2303. +                                                'filename'  => $resource_name,
  2304. +                                                'depth'     => 0);
  2305. +            $_included_tpls_idx = count($this->_smarty_debug_info) - 1;
  2306. +        }
  2307. +
  2308. +        if (!isset($compile_id)) {
  2309. +            $compile_id = $this->compile_id;
  2310. +        }
  2311. +
  2312. +        $this->_compile_id = $compile_id;
  2313. +        $this->_inclusion_depth = 0;
  2314. +
  2315. +        if ($this->caching) {
  2316. +            // save old cache_info, initialize cache_info
  2317. +            array_push($_cache_info, $this->_cache_info);
  2318. +            $this->_cache_info = array();
  2319. +            $_params = array(
  2320. +                'tpl_file' => $resource_name,
  2321. +                'cache_id' => $cache_id,
  2322. +                'compile_id' => $compile_id,
  2323. +                'results' => null
  2324. +            );
  2325. +            require_once(SMARTY_CORE_DIR . 'core.read_cache_file.php');
  2326. +            if (smarty_core_read_cache_file($_params, $this)) {
  2327. +                $_smarty_results = $_params['results'];
  2328. +                if (!empty($this->_cache_info['insert_tags'])) {
  2329. +                    $_params = array('plugins' => $this->_cache_info['insert_tags']);
  2330. +                    require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');
  2331. +                    smarty_core_load_plugins($_params, $this);
  2332. +                    $_params = array('results' => $_smarty_results);
  2333. +                    require_once(SMARTY_CORE_DIR . 'core.process_cached_inserts.php');
  2334. +                    $_smarty_results = smarty_core_process_cached_inserts($_params, $this);
  2335. +                }
  2336. +                if (!empty($this->_cache_info['cache_serials'])) {
  2337. +                    $_params = array('results' => $_smarty_results);
  2338. +                    require_once(SMARTY_CORE_DIR . 'core.process_compiled_include.php');
  2339. +                    $_smarty_results = smarty_core_process_compiled_include($_params, $this);
  2340. +                }
  2341. +
  2342. +
  2343. +                if ($display) {
  2344. +                    if ($this->debugging)
  2345. +                    {
  2346. +                        // capture time for debugging info
  2347. +                        $_params = array();
  2348. +                        require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
  2349. +                        $this->_smarty_debug_info[$_included_tpls_idx]['exec_time'] = smarty_core_get_microtime($_params, $this) - $_debug_start_time;
  2350. +                        require_once(SMARTY_CORE_DIR . 'core.display_debug_console.php');
  2351. +                        $_smarty_results .= smarty_core_display_debug_console($_params, $this);
  2352. +                    }
  2353. +                    if ($this->cache_modified_check) {
  2354. +                        $_server_vars = ($this->request_use_auto_globals) ? $_SERVER : $GLOBALS['HTTP_SERVER_VARS'];
  2355. +                        $_last_modified_date = @substr($_server_vars['HTTP_IF_MODIFIED_SINCE'], 0, strpos($_server_vars['HTTP_IF_MODIFIED_SINCE'], 'GMT') + 3);
  2356. +                        $_gmt_mtime = gmdate('D, d M Y H:i:s', $this->_cache_info['timestamp']).' GMT';
  2357. +                        if (@count($this->_cache_info['insert_tags']) == 0
  2358. +                            && !$this->_cache_serials
  2359. +                            && $_gmt_mtime == $_last_modified_date) {
  2360. +                            if (php_sapi_name()=='cgi')
  2361. +                                header('Status: 304 Not Modified');
  2362. +                            else
  2363. +                                header('HTTP/1.1 304 Not Modified');
  2364. +
  2365. +                        } else {
  2366. +                            header('Last-Modified: '.$_gmt_mtime);
  2367. +                            echo $_smarty_results;
  2368. +                        }
  2369. +                    } else {
  2370. +                            echo $_smarty_results;
  2371. +                    }
  2372. +                    error_reporting($_smarty_old_error_level);
  2373. +                    // restore initial cache_info
  2374. +                    $this->_cache_info = array_pop($_cache_info);
  2375. +                    return true;
  2376. +                } else {
  2377. +                    error_reporting($_smarty_old_error_level);
  2378. +                    // restore initial cache_info
  2379. +                    $this->_cache_info = array_pop($_cache_info);
  2380. +                    return $_smarty_results;
  2381. +                }
  2382. +            } else {
  2383. +                $this->_cache_info['template'][$resource_name] = true;
  2384. +                if ($this->cache_modified_check && $display) {
  2385. +                    header('Last-Modified: '.gmdate('D, d M Y H:i:s', time()).' GMT');
  2386. +                }
  2387. +            }
  2388. +        }
  2389. +
  2390. +        // load filters that are marked as autoload
  2391. +        if (count($this->autoload_filters)) {
  2392. +            foreach ($this->autoload_filters as $_filter_type => $_filters) {
  2393. +                foreach ($_filters as $_filter) {
  2394. +                    $this->load_filter($_filter_type, $_filter);
  2395. +                }
  2396. +            }
  2397. +        }
  2398. +
  2399. +        $_smarty_compile_path = $this->_get_compile_path($resource_name);
  2400. +
  2401. +        // if we just need to display the results, don't perform output
  2402. +        // buffering - for speed
  2403. +        $_cache_including = $this->_cache_including;
  2404. +        $this->_cache_including = false;
  2405. +        if ($display && !$this->caching && count($this->_plugins['outputfilter']) == 0) {
  2406. +            if ($this->_is_compiled($resource_name, $_smarty_compile_path)
  2407. +                    || $this->_compile_resource($resource_name, $_smarty_compile_path))
  2408. +            {
  2409. +                include($_smarty_compile_path);
  2410. +            }
  2411. +        } else {
  2412. +            ob_start();
  2413. +            if ($this->_is_compiled($resource_name, $_smarty_compile_path)
  2414. +                    || $this->_compile_resource($resource_name, $_smarty_compile_path))
  2415. +            {
  2416. +                include($_smarty_compile_path);
  2417. +            }
  2418. +            $_smarty_results = ob_get_contents();
  2419. +            ob_end_clean();
  2420. +
  2421. +            foreach ((array)$this->_plugins['outputfilter'] as $_output_filter) {
  2422. +                $_smarty_results = call_user_func_array($_output_filter[0], array($_smarty_results, &$this));
  2423. +            }
  2424. +        }
  2425. +
  2426. +        if ($this->caching) {
  2427. +            $_params = array('tpl_file' => $resource_name,
  2428. +                        'cache_id' => $cache_id,
  2429. +                        'compile_id' => $compile_id,
  2430. +                        'results' => $_smarty_results);
  2431. +            require_once(SMARTY_CORE_DIR . 'core.write_cache_file.php');
  2432. +            smarty_core_write_cache_file($_params, $this);
  2433. +            require_once(SMARTY_CORE_DIR . 'core.process_cached_inserts.php');
  2434. +            $_smarty_results = smarty_core_process_cached_inserts($_params, $this);
  2435. +
  2436. +            if ($this->_cache_serials) {
  2437. +                // strip nocache-tags from output
  2438. +                $_smarty_results = preg_replace('!(\{/?nocache\:[0-9a-f]{32}#\d+\})!s'
  2439. +                                                ,''
  2440. +                                                ,$_smarty_results);
  2441. +            }
  2442. +            // restore initial cache_info
  2443. +            $this->_cache_info = array_pop($_cache_info);
  2444. +        }
  2445. +        $this->_cache_including = $_cache_including;
  2446. +
  2447. +        if ($display) {
  2448. +            if (isset($_smarty_results)) { echo $_smarty_results; }
  2449. +            if ($this->debugging) {
  2450. +                // capture time for debugging info
  2451. +                $_params = array();
  2452. +                require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
  2453. +                $this->_smarty_debug_info[$_included_tpls_idx]['exec_time'] = (smarty_core_get_microtime($_params, $this) - $_debug_start_time);
  2454. +                require_once(SMARTY_CORE_DIR . 'core.display_debug_console.php');
  2455. +                echo smarty_core_display_debug_console($_params, $this);
  2456. +            }
  2457. +            error_reporting($_smarty_old_error_level);
  2458. +            return;
  2459. +        } else {
  2460. +            error_reporting($_smarty_old_error_level);
  2461. +            if (isset($_smarty_results)) { return $_smarty_results; }
  2462. +        }
  2463. +    }
  2464. +
  2465. +    /**
  2466. +     * load configuration values
  2467. +     *
  2468. +     * @param string $file
  2469. +     * @param string $section
  2470. +     * @param string $scope
  2471. +     */
  2472. +    function config_load($file, $section = null, $scope = 'global')
  2473. +    {
  2474. +        require_once($this->_get_plugin_filepath('function', 'config_load'));
  2475. +        smarty_function_config_load(array('file' => $file, 'section' => $section, 'scope' => $scope), $this);
  2476. +    }
  2477. +
  2478. +    /**
  2479. +     * return a reference to a registered object
  2480. +     *
  2481. +     * @param string $name
  2482. +     * @return object
  2483. +     */
  2484. +    function &get_registered_object($name) {
  2485. +        if (!isset($this->_reg_objects[$name]))
  2486. +        $this->_trigger_fatal_error("'$name' is not a registered object");
  2487. +
  2488. +        if (!is_object($this->_reg_objects[$name][0]))
  2489. +        $this->_trigger_fatal_error("registered '$name' is not an object");
  2490. +
  2491. +        return $this->_reg_objects[$name][0];
  2492. +    }
  2493. +
  2494. +    /**
  2495. +     * clear configuration values
  2496. +     *
  2497. +     * @param string $var
  2498. +     */
  2499. +    function clear_config($var = null)
  2500. +    {
  2501. +        if(!isset($var)) {
  2502. +            // clear all values
  2503. +            $this->_config = array(array('vars'  => array(),
  2504. +                                         'files' => array()));
  2505. +        } else {
  2506. +            unset($this->_config[0]['vars'][$var]);
  2507. +        }
  2508. +    }
  2509. +
  2510. +    /**
  2511. +     * get filepath of requested plugin
  2512. +     *
  2513. +     * @param string $type
  2514. +     * @param string $name
  2515. +     * @return string|false
  2516. +     */
  2517. +    function _get_plugin_filepath($type, $name)
  2518. +    {
  2519. +        $_params = array('type' => $type, 'name' => $name);
  2520. +        require_once(SMARTY_CORE_DIR . 'core.assemble_plugin_filepath.php');
  2521. +        return smarty_core_assemble_plugin_filepath($_params, $this);
  2522. +    }
  2523. +
  2524. +   /**
  2525. +     * test if resource needs compiling
  2526. +     *
  2527. +     * @param string $resource_name
  2528. +     * @param string $compile_path
  2529. +     * @return boolean
  2530. +     */
  2531. +    function _is_compiled($resource_name, $compile_path)
  2532. +    {
  2533. +        if (!$this->force_compile && file_exists($compile_path)) {
  2534. +            if (!$this->compile_check) {
  2535. +                // no need to check compiled file
  2536. +                return true;
  2537. +            } else {
  2538. +                // get file source and timestamp
  2539. +                $_params = array('resource_name' => $resource_name, 'get_source'=>false);
  2540. +                if (!$this->_fetch_resource_info($_params)) {
  2541. +                    return false;
  2542. +                }
  2543. +                if ($_params['resource_timestamp'] <= filemtime($compile_path)) {
  2544. +                    // template not expired, no recompile
  2545. +                    return true;
  2546. +                } else {
  2547. +                    // compile template
  2548. +                    return false;
  2549. +                }
  2550. +            }
  2551. +        } else {
  2552. +            // compiled template does not exist, or forced compile
  2553. +            return false;
  2554. +        }
  2555. +    }
  2556. +
  2557. +   /**
  2558. +     * compile the template
  2559. +     *
  2560. +     * @param string $resource_name
  2561. +     * @param string $compile_path
  2562. +     * @return boolean
  2563. +     */
  2564. +    function _compile_resource($resource_name, $compile_path)
  2565. +    {
  2566. +
  2567. +        $_params = array('resource_name' => $resource_name);
  2568. +        if (!$this->_fetch_resource_info($_params)) {
  2569. +            return false;
  2570. +        }
  2571. +
  2572. +        $_source_content = $_params['source_content'];
  2573. +        $_cache_include    = substr($compile_path, 0, -4).'.inc';
  2574. +
  2575. +        if ($this->_compile_source($resource_name, $_source_content, $_compiled_content, $_cache_include)) {
  2576. +            // if a _cache_serial was set, we also have to write an include-file:
  2577. +            if ($this->_cache_include_info) {
  2578. +                require_once(SMARTY_CORE_DIR . 'core.write_compiled_include.php');
  2579. +                smarty_core_write_compiled_include(array_merge($this->_cache_include_info, array('compiled_content'=>$_compiled_content, 'resource_name'=>$resource_name)),  $this);
  2580. +            }
  2581. +
  2582. +            $_params = array('compile_path'=>$compile_path, 'compiled_content' => $_compiled_content);
  2583. +            require_once(SMARTY_CORE_DIR . 'core.write_compiled_resource.php');
  2584. +            smarty_core_write_compiled_resource($_params, $this);
  2585. +
  2586. +            return true;
  2587. +        } else {
  2588. +            return false;
  2589. +        }
  2590. +
  2591. +    }
  2592. +
  2593. +   /**
  2594. +     * compile the given source
  2595. +     *
  2596. +     * @param string $resource_name
  2597. +     * @param string $source_content
  2598. +     * @param string $compiled_content
  2599. +     * @return boolean
  2600. +     */
  2601. +    function _compile_source($resource_name, &$source_content, &$compiled_content, $cache_include_path=null)
  2602. +    {
  2603. +        if (file_exists(SMARTY_DIR . $this->compiler_file)) {
  2604. +            require_once(SMARTY_DIR . $this->compiler_file);
  2605. +        } else {
  2606. +            // use include_path
  2607. +            require_once($this->compiler_file);
  2608. +        }
  2609. +
  2610. +
  2611. +        $smarty_compiler = new $this->compiler_class;
  2612. +
  2613. +        $smarty_compiler->template_dir      = $this->template_dir;
  2614. +        $smarty_compiler->compile_dir       = $this->compile_dir;
  2615. +        $smarty_compiler->plugins_dir       = $this->plugins_dir;
  2616. +        $smarty_compiler->config_dir        = $this->config_dir;
  2617. +        $smarty_compiler->force_compile     = $this->force_compile;
  2618. +        $smarty_compiler->caching           = $this->caching;
  2619. +        $smarty_compiler->php_handling      = $this->php_handling;
  2620. +        $smarty_compiler->left_delimiter    = $this->left_delimiter;
  2621. +        $smarty_compiler->right_delimiter   = $this->right_delimiter;
  2622. +        $smarty_compiler->_version          = $this->_version;
  2623. +        $smarty_compiler->security          = $this->security;
  2624. +        $smarty_compiler->secure_dir        = $this->secure_dir;
  2625. +        $smarty_compiler->security_settings = $this->security_settings;
  2626. +        $smarty_compiler->trusted_dir       = $this->trusted_dir;
  2627. +        $smarty_compiler->use_sub_dirs      = $this->use_sub_dirs;
  2628. +        $smarty_compiler->_reg_objects      = &$this->_reg_objects;
  2629. +        $smarty_compiler->_plugins          = &$this->_plugins;
  2630. +        $smarty_compiler->_tpl_vars         = &$this->_tpl_vars;
  2631. +        $smarty_compiler->default_modifiers = $this->default_modifiers;
  2632. +        $smarty_compiler->compile_id        = $this->_compile_id;
  2633. +        $smarty_compiler->_config            = $this->_config;
  2634. +        $smarty_compiler->request_use_auto_globals  = $this->request_use_auto_globals;
  2635. +
  2636. +        if (isset($cache_include_path) && isset($this->_cache_serials[$cache_include_path])) {
  2637. +            $smarty_compiler->_cache_serial = $this->_cache_serials[$cache_include_path];
  2638. +        }
  2639. +        $smarty_compiler->_cache_include = $cache_include_path;
  2640. +
  2641. +
  2642. +        $_results = $smarty_compiler->_compile_file($resource_name, $source_content, $compiled_content);
  2643. +
  2644. +        if ($smarty_compiler->_cache_serial) {
  2645. +            $this->_cache_include_info = array(
  2646. +                'cache_serial'=>$smarty_compiler->_cache_serial
  2647. +                ,'plugins_code'=>$smarty_compiler->_plugins_code
  2648. +                ,'include_file_path' => $cache_include_path);
  2649. +
  2650. +        } else {
  2651. +            $this->_cache_include_info = null;
  2652. +
  2653. +        }
  2654. +
  2655. +        return $_results;
  2656. +    }
  2657. +
  2658. +    /**
  2659. +     * Get the compile path for this resource
  2660. +     *
  2661. +     * @param string $resource_name
  2662. +     * @return string results of {@link _get_auto_filename()}
  2663. +     */
  2664. +    function _get_compile_path($resource_name)
  2665. +    {
  2666. +        return $this->_get_auto_filename($this->compile_dir, $resource_name,
  2667. +                                         $this->_compile_id) . '.php';
  2668. +    }
  2669. +
  2670. +    /**
  2671. +     * fetch the template info. Gets timestamp, and source
  2672. +     * if get_source is true
  2673. +     *
  2674. +     * sets $source_content to the source of the template, and
  2675. +     * $resource_timestamp to its time stamp
  2676. +     * @param string $resource_name
  2677. +     * @param string $source_content
  2678. +     * @param integer $resource_timestamp
  2679. +     * @param boolean $get_source
  2680. +     * @param boolean $quiet
  2681. +     * @return boolean
  2682. +     */
  2683. +
  2684. +    function _fetch_resource_info(&$params)
  2685. +    {
  2686. +        if(!isset($params['get_source'])) { $params['get_source'] = true; }
  2687. +        if(!isset($params['quiet'])) { $params['quiet'] = false; }
  2688. +
  2689. +        $_return = false;
  2690. +        $_params = array('resource_name' => $params['resource_name']) ;
  2691. +        if (isset($params['resource_base_path']))
  2692. +            $_params['resource_base_path'] = $params['resource_base_path'];
  2693. +        else
  2694. +            $_params['resource_base_path'] = $this->template_dir;
  2695. +
  2696. +        if ($this->_parse_resource_name($_params)) {
  2697. +            $_resource_type = $_params['resource_type'];
  2698. +            $_resource_name = $_params['resource_name'];
  2699. +            switch ($_resource_type) {
  2700. +                case 'file':
  2701. +                    if ($params['get_source']) {
  2702. +                        $params['source_content'] = $this->_read_file($_resource_name);
  2703. +                    }
  2704. +                    $params['resource_timestamp'] = filemtime($_resource_name);
  2705. +                    $_return = is_file($_resource_name) && is_readable($_resource_name);
  2706. +                    break;
  2707. +
  2708. +                default:
  2709. +                    // call resource functions to fetch the template source and timestamp
  2710. +                    if ($params['get_source']) {
  2711. +                        $_source_return = isset($this->_plugins['resource'][$_resource_type]) &&
  2712. +                            call_user_func_array($this->_plugins['resource'][$_resource_type][0][0],
  2713. +                                                 array($_resource_name, &$params['source_content'], &$this));
  2714. +                    } else {
  2715. +                        $_source_return = true;
  2716. +                    }
  2717. +
  2718. +                    $_timestamp_return = isset($this->_plugins['resource'][$_resource_type]) &&
  2719. +                        call_user_func_array($this->_plugins['resource'][$_resource_type][0][1],
  2720. +                                             array($_resource_name, &$params['resource_timestamp'], &$this));
  2721. +
  2722. +                    $_return = $_source_return && $_timestamp_return;
  2723. +                    break;
  2724. +            }
  2725. +        }
  2726. +
  2727. +        if (!$_return) {
  2728. +            // see if we can get a template with the default template handler
  2729. +            if (!empty($this->default_template_handler_func)) {
  2730. +                if (!is_callable($this->default_template_handler_func)) {
  2731. +                    $this->trigger_error("default template handler function \"$this->default_template_handler_func\" doesn't exist.");
  2732. +                } else {
  2733. +                    $_return = call_user_func_array(
  2734. +                        $this->default_template_handler_func,
  2735. +                        array($_params['resource_type'], $_params['resource_name'], &$params['source_content'], &$params['resource_timestamp'], &$this));
  2736. +                }
  2737. +            }
  2738. +        }
  2739. +
  2740. +        if (!$_return) {
  2741. +            if (!$params['quiet']) {
  2742. +                $this->trigger_error('unable to read resource: "' . $params['resource_name'] . '"');
  2743. +            }
  2744. +        } else if ($_return && $this->security) {
  2745. +            require_once(SMARTY_CORE_DIR . 'core.is_secure.php');
  2746. +            if (!smarty_core_is_secure($_params, $this)) {
  2747. +                if (!$params['quiet'])
  2748. +                    $this->trigger_error('(secure mode) accessing "' . $params['resource_name'] . '" is not allowed');
  2749. +                $params['source_content'] = null;
  2750. +                $params['resource_timestamp'] = null;
  2751. +                return false;
  2752. +            }
  2753. +        }
  2754. +        return $_return;
  2755. +    }
  2756. +
  2757. +
  2758. +    /**
  2759. +     * parse out the type and name from the resource
  2760. +     *
  2761. +     * @param string $resource_base_path
  2762. +     * @param string $resource_name
  2763. +     * @param string $resource_type
  2764. +     * @param string $resource_name
  2765. +     * @return boolean
  2766. +     */
  2767. +
  2768. +    function _parse_resource_name(&$params)
  2769. +    {
  2770. +
  2771. +        // split tpl_path by the first colon
  2772. +        $_resource_name_parts = explode(':', $params['resource_name'], 2);
  2773. +
  2774. +        if (count($_resource_name_parts) == 1) {
  2775. +            // no resource type given
  2776. +            $params['resource_type'] = $this->default_resource_type;
  2777. +            $params['resource_name'] = $_resource_name_parts[0];
  2778. +        } else {
  2779. +            if(strlen($_resource_name_parts[0]) == 1) {
  2780. +                // 1 char is not resource type, but part of filepath
  2781. +                $params['resource_type'] = $this->default_resource_type;
  2782. +                $params['resource_name'] = $params['resource_name'];
  2783. +            } else {
  2784. +                $params['resource_type'] = $_resource_name_parts[0];
  2785. +                $params['resource_name'] = $_resource_name_parts[1];
  2786. +            }
  2787. +        }
  2788. +
  2789. +        if ($params['resource_type'] == 'file') {
  2790. +            if (!preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $params['resource_name'])) {
  2791. +                // relative pathname to $params['resource_base_path']
  2792. +                // use the first directory where the file is found
  2793. +                foreach ((array)$params['resource_base_path'] as $_curr_path) {
  2794. +                    $_fullpath = $_curr_path . DIRECTORY_SEPARATOR . $params['resource_name'];
  2795. +                    if (file_exists($_fullpath) && is_file($_fullpath)) {
  2796. +                        $params['resource_name'] = $_fullpath;
  2797. +                        return true;
  2798. +                    }
  2799. +                    // didn't find the file, try include_path
  2800. +                    $_params = array('file_path' => $_fullpath);
  2801. +                    require_once(SMARTY_CORE_DIR . 'core.get_include_path.php');
  2802. +                    if(smarty_core_get_include_path($_params, $this)) {
  2803. +                        $params['resource_name'] = $_params['new_file_path'];
  2804. +                        return true;
  2805. +                    }
  2806. +                }
  2807. +                return false;
  2808. +            } else {
  2809. +                /* absolute path */
  2810. +                return file_exists($params['resource_name']);
  2811. +            }
  2812. +        } elseif (empty($this->_plugins['resource'][$params['resource_type']])) {
  2813. +            $_params = array('type' => $params['resource_type']);
  2814. +            require_once(SMARTY_CORE_DIR . 'core.load_resource_plugin.php');
  2815. +            smarty_core_load_resource_plugin($_params, $this);
  2816. +        }
  2817. +
  2818. +        return true;
  2819. +    }
  2820. +
  2821. +
  2822. +    /**
  2823. +     * Handle modifiers
  2824. +     *
  2825. +     * @param string|null $modifier_name
  2826. +     * @param array|null $map_array
  2827. +     * @return string result of modifiers
  2828. +     */
  2829. +    function _run_mod_handler()
  2830. +    {
  2831. +        $_args = func_get_args();
  2832. +        list($_modifier_name, $_map_array) = array_splice($_args, 0, 2);
  2833. +        list($_func_name, $_tpl_file, $_tpl_line) =
  2834. +            $this->_plugins['modifier'][$_modifier_name];
  2835. +
  2836. +        $_var = $_args[0];
  2837. +        foreach ($_var as $_key => $_val) {
  2838. +            $_args[0] = $_val;
  2839. +            $_var[$_key] = call_user_func_array($_func_name, $_args);
  2840. +        }
  2841. +        return $_var;
  2842. +    }
  2843. +
  2844. +    /**
  2845. +     * Remove starting and ending quotes from the string
  2846. +     *
  2847. +     * @param string $string
  2848. +     * @return string
  2849. +     */
  2850. +    function _dequote($string)
  2851. +    {
  2852. +        if ((substr($string, 0, 1) == "'" || substr($string, 0, 1) == '"') &&
  2853. +            substr($string, -1) == substr($string, 0, 1))
  2854. +            return substr($string, 1, -1);
  2855. +        else
  2856. +            return $string;
  2857. +    }
  2858. +
  2859. +
  2860. +    /**
  2861. +     * read in a file
  2862. +     *
  2863. +     * @param string $filename
  2864. +     * @return string
  2865. +     */
  2866. +    function _read_file($filename)
  2867. +    {
  2868. +        if ( file_exists($filename) && is_readable($filename) && ($fd = @fopen($filename, 'rb')) ) {
  2869. +            $contents = '';
  2870. +            while (!feof($fd)) {
  2871. +                $contents .= fread($fd, 8192);
  2872. +            }
  2873. +            fclose($fd);
  2874. +            return $contents;
  2875. +        } else {
  2876. +            return false;
  2877. +        }
  2878. +    }
  2879. +
  2880. +    /**
  2881. +     * get a concrete filename for automagically created content
  2882. +     *
  2883. +     * @param string $auto_base
  2884. +     * @param string $auto_source
  2885. +     * @param string $auto_id
  2886. +     * @return string
  2887. +     * @staticvar string|null
  2888. +     * @staticvar string|null
  2889. +     */
  2890. +    function _get_auto_filename($auto_base, $auto_source = null, $auto_id = null)
  2891. +    {
  2892. +        $_compile_dir_sep =  $this->use_sub_dirs ? DIRECTORY_SEPARATOR : '^';
  2893. +        $_return = $auto_base . DIRECTORY_SEPARATOR;
  2894. +
  2895. +        if(isset($auto_id)) {
  2896. +            // make auto_id safe for directory names
  2897. +            $auto_id = str_replace('%7C',$_compile_dir_sep,(urlencode($auto_id)));
  2898. +            // split into separate directories
  2899. +            $_return .= $auto_id . $_compile_dir_sep;
  2900. +        }
  2901. +
  2902. +        if(isset($auto_source)) {
  2903. +            // make source name safe for filename
  2904. +            $_filename = urlencode(basename($auto_source));
  2905. +            $_crc32 = sprintf('%08X', crc32($auto_source));
  2906. +            // prepend %% to avoid name conflicts with
  2907. +            // with $params['auto_id'] names
  2908. +            $_crc32 = substr($_crc32, 0, 2) . $_compile_dir_sep .
  2909. +                      substr($_crc32, 0, 3) . $_compile_dir_sep . $_crc32;
  2910. +            $_return .= '%%' . $_crc32 . '%%' . $_filename;
  2911. +        }
  2912. +
  2913. +        return $_return;
  2914. +    }
  2915. +
  2916. +    /**
  2917. +     * unlink a file, possibly using expiration time
  2918. +     *
  2919. +     * @param string $resource
  2920. +     * @param integer $exp_time
  2921. +     */
  2922. +    function _unlink($resource, $exp_time = null)
  2923. +    {
  2924. +        if(isset($exp_time)) {
  2925. +            if(time() - @filemtime($resource) >= $exp_time) {
  2926. +                return @unlink($resource);
  2927. +            }
  2928. +        } else {
  2929. +            return @unlink($resource);
  2930. +        }
  2931. +    }
  2932. +
  2933. +    /**
  2934. +     * returns an auto_id for auto-file-functions
  2935. +     *
  2936. +     * @param string $cache_id
  2937. +     * @param string $compile_id
  2938. +     * @return string|null
  2939. +     */
  2940. +    function _get_auto_id($cache_id=null, $compile_id=null) {
  2941. +    if (isset($cache_id))
  2942. +        return (isset($compile_id)) ? $cache_id . '|' . $compile_id  : $cache_id;
  2943. +    elseif(isset($compile_id))
  2944. +        return $compile_id;
  2945. +    else
  2946. +        return null;
  2947. +    }
  2948. +
  2949. +    /**
  2950. +     * trigger Smarty plugin error
  2951. +     *
  2952. +     * @param string $error_msg
  2953. +     * @param string $tpl_file
  2954. +     * @param integer $tpl_line
  2955. +     * @param string $file
  2956. +     * @param integer $line
  2957. +     * @param integer $error_type
  2958. +     */
  2959. +    function _trigger_fatal_error($error_msg, $tpl_file = null, $tpl_line = null,
  2960. +            $file = null, $line = null, $error_type = E_USER_ERROR)
  2961. +    {
  2962. +        if(isset($file) && isset($line)) {
  2963. +            $info = ' ('.basename($file).", line $line)";
  2964. +        } else {
  2965. +            $info = '';
  2966. +        }
  2967. +        if (isset($tpl_line) && isset($tpl_file)) {
  2968. +            $this->trigger_error('[in ' . $tpl_file . ' line ' . $tpl_line . "]: $error_msg$info", $error_type);
  2969. +        } else {
  2970. +            $this->trigger_error($error_msg . $info, $error_type);
  2971. +        }
  2972. +    }
  2973. +
  2974. +
  2975. +    /**
  2976. +     * callback function for preg_replace, to call a non-cacheable block
  2977. +     * @return string
  2978. +     */
  2979. +    function _process_compiled_include_callback($match) {
  2980. +        $_func = '_smarty_tplfunc_'.$match[2].'_'.$match[3];
  2981. +        ob_start();
  2982. +        $_func($this);
  2983. +        $_ret = ob_get_contents();
  2984. +        ob_end_clean();
  2985. +        return $_ret;
  2986. +    }
  2987. +
  2988. +
  2989. +    /**
  2990. +     * called for included templates
  2991. +     *
  2992. +     * @param string $_smarty_include_tpl_file
  2993. +     * @param string $_smarty_include_vars
  2994. +     */
  2995. +
  2996. +    // $_smarty_include_tpl_file, $_smarty_include_vars
  2997. +
  2998. +    function _smarty_include($params)
  2999. +    {
  3000. +        if ($this->debugging) {
  3001. +            $_params = array();
  3002. +            require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
  3003. +            $debug_start_time = smarty_core_get_microtime($_params, $this);
  3004. +            $this->_smarty_debug_info[] = array('type'      => 'template',
  3005. +                                                  'filename'  => $params['smarty_include_tpl_file'],
  3006. +                                                  'depth'     => ++$this->_inclusion_depth);
  3007. +            $included_tpls_idx = count($this->_smarty_debug_info) - 1;
  3008. +        }
  3009. +
  3010. +        $this->_tpl_vars = array_merge($this->_tpl_vars, $params['smarty_include_vars']);
  3011. +
  3012. +        // config vars are treated as local, so push a copy of the
  3013. +        // current ones onto the front of the stack
  3014. +        array_unshift($this->_config, $this->_config[0]);
  3015. +
  3016. +        $_smarty_compile_path = $this->_get_compile_path($params['smarty_include_tpl_file']);
  3017. +
  3018. +
  3019. +        if ($this->_is_compiled($params['smarty_include_tpl_file'], $_smarty_compile_path)
  3020. +            || $this->_compile_resource($params['smarty_include_tpl_file'], $_smarty_compile_path))
  3021. +        {
  3022. +            include($_smarty_compile_path);
  3023. +        }
  3024. +
  3025. +        // pop the local vars off the front of the stack
  3026. +        array_shift($this->_config);
  3027. +
  3028. +        $this->_inclusion_depth--;
  3029. +
  3030. +        if ($this->debugging) {
  3031. +            // capture time for debugging info
  3032. +            $_params = array();
  3033. +            require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
  3034. +            $this->_smarty_debug_info[$included_tpls_idx]['exec_time'] = smarty_core_get_microtime($_params, $this) - $debug_start_time;
  3035. +        }
  3036. +
  3037. +        if ($this->caching) {
  3038. +            $this->_cache_info['template'][$params['smarty_include_tpl_file']] = true;
  3039. +        }
  3040. +    }
  3041. +
  3042. +
  3043. +    /**
  3044. +     * get or set an array of cached attributes for function that is
  3045. +     * not cacheable
  3046. +     * @return array
  3047. +     */
  3048. +    function &_smarty_cache_attrs($cache_serial, $count) {
  3049. +        $_cache_attrs =& $this->_cache_info['cache_attrs'][$cache_serial][$count];
  3050. +
  3051. +        if ($this->_cache_including) {
  3052. +            /* return next set of cache_attrs */
  3053. +            $_return = current($_cache_attrs);
  3054. +            next($_cache_attrs);
  3055. +            return $_return;
  3056. +
  3057. +        } else {
  3058. +            /* add a reference to a new set of cache_attrs */
  3059. +            $_cache_attrs[] = array();
  3060. +            return $_cache_attrs[count($_cache_attrs)-1];
  3061. +
  3062. +        }
  3063. +
  3064. +    }
  3065. +
  3066. +
  3067. +    /**
  3068. +     * wrapper for include() retaining $this
  3069. +     * @return mixed
  3070. +     */
  3071. +    function _include($filename, $once=false, $params=null)
  3072. +    {
  3073. +        if ($once) {
  3074. +            return include_once($filename);
  3075. +        } else {
  3076. +            return include($filename);
  3077. +        }
  3078. +    }
  3079. +
  3080. +
  3081. +    /**
  3082. +     * wrapper for eval() retaining $this
  3083. +     * @return mixed
  3084. +     */
  3085. +    function _eval($code, $params=null)
  3086. +    {
  3087. +        return eval($code);
  3088. +    }
  3089. +    
  3090. +    /**
  3091. +     * Extracts the filter name from the given callback
  3092. +     *
  3093. +     * @param callback $function
  3094. +     * @return string
  3095. +     */
  3096. +   function _get_filter_name($function)
  3097. +   {
  3098. +       if (is_array($function)) {
  3099. +           $_class_name = (is_object($function[0]) ?
  3100. +               get_class($function[0]) : $function[0]);
  3101. +           return $_class_name . '_' . $function[1];
  3102. +       }
  3103. +       else {
  3104. +           return $function;
  3105. +       }
  3106. +   }
  3107. +  
  3108. +    /**#@-*/
  3109. +
  3110. +}
  3111. +
  3112. +/* vim: set expandtab: */
  3113. +
  3114. +?>
  3115. diff --git a/library/smarty/Smarty_Compiler.class.php b/library/smarty/Smarty_Compiler.class.php
  3116. new file mode 100644
  3117. --- /dev/null
  3118. +++ b/library/smarty/Smarty_Compiler.class.php
  3119. @@ -0,0 +1,2365 @@
  3120. +<?php
  3121. +
  3122. +/**
  3123. + * Project:     Smarty: the PHP compiling template engine
  3124. + * File:        Smarty_Compiler.class.php
  3125. + *
  3126. + * This library is free software; you can redistribute it and/or
  3127. + * modify it under the terms of the GNU Lesser General Public
  3128. + * License as published by the Free Software Foundation; either
  3129. + * version 2.1 of the License, or (at your option) any later version.
  3130. + *
  3131. + * This library is distributed in the hope that it will be useful,
  3132. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  3133. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  3134. + * Lesser General Public License for more details.
  3135. + *
  3136. + * You should have received a copy of the GNU Lesser General Public
  3137. + * License along with this library; if not, write to the Free Software
  3138. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  3139. + *
  3140. + * @link http://smarty.php.net/
  3141. + * @author Monte Ohrt <monte at ohrt dot com>
  3142. + * @author Andrei Zmievski <[email protected]>
  3143. + * @version 2.6.26
  3144. + * @copyright 2001-2005 New Digital Group, Inc.
  3145. + * @package Smarty
  3146. + */
  3147. +
  3148. +/* $Id: Smarty_Compiler.class.php 3163 2009-06-17 14:39:24Z monte.ohrt $ */
  3149. +
  3150. +/**
  3151. + * Template compiling class
  3152. + * @package Smarty
  3153. + */
  3154. +class Smarty_Compiler extends Smarty {
  3155. +
  3156. +    // internal vars
  3157. +    /**#@+
  3158. +     * @access private
  3159. +     */
  3160. +    var $_folded_blocks         =   array();    // keeps folded template blocks
  3161. +    var $_current_file          =   null;       // the current template being compiled
  3162. +    var $_current_line_no       =   1;          // line number for error messages
  3163. +    var $_capture_stack         =   array();    // keeps track of nested capture buffers
  3164. +    var $_plugin_info           =   array();    // keeps track of plugins to load
  3165. +    var $_init_smarty_vars      =   false;
  3166. +    var $_permitted_tokens      =   array('true','false','yes','no','on','off','null');
  3167. +    var $_db_qstr_regexp        =   null;        // regexps are setup in the constructor
  3168. +    var $_si_qstr_regexp        =   null;
  3169. +    var $_qstr_regexp           =   null;
  3170. +    var $_func_regexp           =   null;
  3171. +    var $_reg_obj_regexp        =   null;
  3172. +    var $_var_bracket_regexp    =   null;
  3173. +    var $_num_const_regexp      =   null;
  3174. +    var $_dvar_guts_regexp      =   null;
  3175. +    var $_dvar_regexp           =   null;
  3176. +    var $_cvar_regexp           =   null;
  3177. +    var $_svar_regexp           =   null;
  3178. +    var $_avar_regexp           =   null;
  3179. +    var $_mod_regexp            =   null;
  3180. +    var $_var_regexp            =   null;
  3181. +    var $_parenth_param_regexp  =   null;
  3182. +    var $_func_call_regexp      =   null;
  3183. +    var $_obj_ext_regexp        =   null;
  3184. +    var $_obj_start_regexp      =   null;
  3185. +    var $_obj_params_regexp     =   null;
  3186. +    var $_obj_call_regexp       =   null;
  3187. +    var $_cacheable_state       =   0;
  3188. +    var $_cache_attrs_count     =   0;
  3189. +    var $_nocache_count         =   0;
  3190. +    var $_cache_serial          =   null;
  3191. +    var $_cache_include         =   null;
  3192. +
  3193. +    var $_strip_depth           =   0;
  3194. +    var $_additional_newline    =   "\n";
  3195. +
  3196. +    /**#@-*/
  3197. +    /**
  3198. +     * The class constructor.
  3199. +     */
  3200. +    function Smarty_Compiler()
  3201. +    {
  3202. +        // matches double quoted strings:
  3203. +        // "foobar"
  3204. +        // "foo\"bar"
  3205. +        $this->_db_qstr_regexp = '"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"';
  3206. +
  3207. +        // matches single quoted strings:
  3208. +        // 'foobar'
  3209. +        // 'foo\'bar'
  3210. +        $this->_si_qstr_regexp = '\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\'';
  3211. +
  3212. +        // matches single or double quoted strings
  3213. +        $this->_qstr_regexp = '(?:' . $this->_db_qstr_regexp . '|' . $this->_si_qstr_regexp . ')';
  3214. +
  3215. +        // matches bracket portion of vars
  3216. +        // [0]
  3217. +        // [foo]
  3218. +        // [$bar]
  3219. +        $this->_var_bracket_regexp = '\[\$?[\w\.]+\]';
  3220. +
  3221. +        // matches numerical constants
  3222. +        // 30
  3223. +        // -12
  3224. +        // 13.22
  3225. +        $this->_num_const_regexp = '(?:\-?\d+(?:\.\d+)?)';
  3226. +
  3227. +        // matches $ vars (not objects):
  3228. +        // $foo
  3229. +        // $foo.bar
  3230. +        // $foo.bar.foobar
  3231. +        // $foo[0]
  3232. +        // $foo[$bar]
  3233. +        // $foo[5][blah]
  3234. +        // $foo[5].bar[$foobar][4]
  3235. +        $this->_dvar_math_regexp = '(?:[\+\*\/\%]|(?:-(?!>)))';
  3236. +        $this->_dvar_math_var_regexp = '[\$\w\.\+\-\*\/\%\d\>\[\]]';
  3237. +        $this->_dvar_guts_regexp = '\w+(?:' . $this->_var_bracket_regexp
  3238. +                . ')*(?:\.\$?\w+(?:' . $this->_var_bracket_regexp . ')*)*(?:' . $this->_dvar_math_regexp . '(?:' . $this->_num_const_regexp . '|' . $this->_dvar_math_var_regexp . ')*)?';
  3239. +        $this->_dvar_regexp = '\$' . $this->_dvar_guts_regexp;
  3240. +
  3241. +        // matches config vars:
  3242. +        // #foo#
  3243. +        // #foobar123_foo#
  3244. +        $this->_cvar_regexp = '\#\w+\#';
  3245. +
  3246. +        // matches section vars:
  3247. +        // %foo.bar%
  3248. +        $this->_svar_regexp = '\%\w+\.\w+\%';
  3249. +
  3250. +        // matches all valid variables (no quotes, no modifiers)
  3251. +        $this->_avar_regexp = '(?:' . $this->_dvar_regexp . '|'
  3252. +           . $this->_cvar_regexp . '|' . $this->_svar_regexp . ')';
  3253. +
  3254. +        // matches valid variable syntax:
  3255. +        // $foo
  3256. +        // $foo
  3257. +        // #foo#
  3258. +        // #foo#
  3259. +        // "text"
  3260. +        // "text"
  3261. +        $this->_var_regexp = '(?:' . $this->_avar_regexp . '|' . $this->_qstr_regexp . ')';
  3262. +
  3263. +        // matches valid object call (one level of object nesting allowed in parameters):
  3264. +        // $foo->bar
  3265. +        // $foo->bar()
  3266. +        // $foo->bar("text")
  3267. +        // $foo->bar($foo, $bar, "text")
  3268. +        // $foo->bar($foo, "foo")
  3269. +        // $foo->bar->foo()
  3270. +        // $foo->bar->foo->bar()
  3271. +        // $foo->bar($foo->bar)
  3272. +        // $foo->bar($foo->bar())
  3273. +        // $foo->bar($foo->bar($blah,$foo,44,"foo",$foo[0].bar))
  3274. +        $this->_obj_ext_regexp = '\->(?:\$?' . $this->_dvar_guts_regexp . ')';
  3275. +        $this->_obj_restricted_param_regexp = '(?:'
  3276. +                . '(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . ')(?:' . $this->_obj_ext_regexp . '(?:\((?:(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . ')'
  3277. +                . '(?:\s*,\s*(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . '))*)?\))?)*)';
  3278. +        $this->_obj_single_param_regexp = '(?:\w+|' . $this->_obj_restricted_param_regexp . '(?:\s*,\s*(?:(?:\w+|'
  3279. +                . $this->_var_regexp . $this->_obj_restricted_param_regexp . ')))*)';
  3280. +        $this->_obj_params_regexp = '\((?:' . $this->_obj_single_param_regexp
  3281. +                . '(?:\s*,\s*' . $this->_obj_single_param_regexp . ')*)?\)';
  3282. +        $this->_obj_start_regexp = '(?:' . $this->_dvar_regexp . '(?:' . $this->_obj_ext_regexp . ')+)';
  3283. +        $this->_obj_call_regexp = '(?:' . $this->_obj_start_regexp . '(?:' . $this->_obj_params_regexp . ')?(?:' . $this->_dvar_math_regexp . '(?:' . $this->_num_const_regexp . '|' . $this->_dvar_math_var_regexp . ')*)?)';
  3284. +        
  3285. +        // matches valid modifier syntax:
  3286. +        // |foo
  3287. +        // |@foo
  3288. +        // |foo:"bar"
  3289. +        // |foo:$bar
  3290. +        // |foo:"bar":$foobar
  3291. +        // |foo|bar
  3292. +        // |foo:$foo->bar
  3293. +        $this->_mod_regexp = '(?:\|@?\w+(?::(?:\w+|' . $this->_num_const_regexp . '|'
  3294. +           . $this->_obj_call_regexp . '|' . $this->_avar_regexp . '|' . $this->_qstr_regexp .'))*)';
  3295. +
  3296. +        // matches valid function name:
  3297. +        // foo123
  3298. +        // _foo_bar
  3299. +        $this->_func_regexp = '[a-zA-Z_]\w*';
  3300. +
  3301. +        // matches valid registered object:
  3302. +        // foo->bar
  3303. +        $this->_reg_obj_regexp = '[a-zA-Z_]\w*->[a-zA-Z_]\w*';
  3304. +
  3305. +        // matches valid parameter values:
  3306. +        // true
  3307. +        // $foo
  3308. +        // $foo|bar
  3309. +        // #foo#
  3310. +        // #foo#|bar
  3311. +        // "text"
  3312. +        // "text"|bar
  3313. +        // $foo->bar
  3314. +        $this->_param_regexp = '(?:\s*(?:' . $this->_obj_call_regexp . '|'
  3315. +           . $this->_var_regexp . '|' . $this->_num_const_regexp  . '|\w+)(?>' . $this->_mod_regexp . '*)\s*)';
  3316. +
  3317. +        // matches valid parenthesised function parameters:
  3318. +        //
  3319. +        // "text"
  3320. +        //    $foo, $bar, "text"
  3321. +        // $foo|bar, "foo"|bar, $foo->bar($foo)|bar
  3322. +        $this->_parenth_param_regexp = '(?:\((?:\w+|'
  3323. +                . $this->_param_regexp . '(?:\s*,\s*(?:(?:\w+|'
  3324. +                . $this->_param_regexp . ')))*)?\))';
  3325. +
  3326. +        // matches valid function call:
  3327. +        // foo()
  3328. +        // foo_bar($foo)
  3329. +        // _foo_bar($foo,"bar")
  3330. +        // foo123($foo,$foo->bar(),"foo")
  3331. +        $this->_func_call_regexp = '(?:' . $this->_func_regexp . '\s*(?:'
  3332. +           . $this->_parenth_param_regexp . '))';
  3333. +    }
  3334. +
  3335. +    /**
  3336. +     * compile a resource
  3337. +     *
  3338. +     * sets $compiled_content to the compiled source
  3339. +     * @param string $resource_name
  3340. +     * @param string $source_content
  3341. +     * @param string $compiled_content
  3342. +     * @return true
  3343. +     */
  3344. +    function _compile_file($resource_name, $source_content, &$compiled_content)
  3345. +    {
  3346. +
  3347. +        if ($this->security) {
  3348. +            // do not allow php syntax to be executed unless specified
  3349. +            if ($this->php_handling == SMARTY_PHP_ALLOW &&
  3350. +                !$this->security_settings['PHP_HANDLING']) {
  3351. +                $this->php_handling = SMARTY_PHP_PASSTHRU;
  3352. +            }
  3353. +        }
  3354. +
  3355. +        $this->_load_filters();
  3356. +
  3357. +        $this->_current_file = $resource_name;
  3358. +        $this->_current_line_no = 1;
  3359. +        $ldq = preg_quote($this->left_delimiter, '~');
  3360. +        $rdq = preg_quote($this->right_delimiter, '~');
  3361. +
  3362. +        // run template source through prefilter functions
  3363. +        if (count($this->_plugins['prefilter']) > 0) {
  3364. +            foreach ($this->_plugins['prefilter'] as $filter_name => $prefilter) {
  3365. +                if ($prefilter === false) continue;
  3366. +                if ($prefilter[3] || is_callable($prefilter[0])) {
  3367. +                    $source_content = call_user_func_array($prefilter[0],
  3368. +                                                            array($source_content, &$this));
  3369. +                    $this->_plugins['prefilter'][$filter_name][3] = true;
  3370. +                } else {
  3371. +                    $this->_trigger_fatal_error("[plugin] prefilter '$filter_name' is not implemented");
  3372. +                }
  3373. +            }
  3374. +        }
  3375. +
  3376. +        /* fetch all special blocks */
  3377. +        $search = "~{$ldq}\*(.*?)\*{$rdq}|{$ldq}\s*literal\s*{$rdq}(.*?){$ldq}\s*/literal\s*{$rdq}|{$ldq}\s*php\s*{$rdq}(.*?){$ldq}\s*/php\s*{$rdq}~s";
  3378. +
  3379. +        preg_match_all($search, $source_content, $match,  PREG_SET_ORDER);
  3380. +        $this->_folded_blocks = $match;
  3381. +        reset($this->_folded_blocks);
  3382. +
  3383. +        /* replace special blocks by "{php}" */
  3384. +        $source_content = preg_replace($search.'e', "'"
  3385. +                                       . $this->_quote_replace($this->left_delimiter) . 'php'
  3386. +                                       . "' . str_repeat(\"\n\", substr_count('\\0', \"\n\")) .'"
  3387. +                                       . $this->_quote_replace($this->right_delimiter)
  3388. +                                       . "'"
  3389. +                                       , $source_content);
  3390. +
  3391. +        /* Gather all template tags. */
  3392. +        preg_match_all("~{$ldq}\s*(.*?)\s*{$rdq}~s", $source_content, $_match);
  3393. +        $template_tags = $_match[1];
  3394. +        /* Split content by template tags to obtain non-template content. */
  3395. +        $text_blocks = preg_split("~{$ldq}.*?{$rdq}~s", $source_content);
  3396. +
  3397. +        /* loop through text blocks */
  3398. +        for ($curr_tb = 0, $for_max = count($text_blocks); $curr_tb < $for_max; $curr_tb++) {
  3399. +            /* match anything resembling php tags */
  3400. +            if (preg_match_all('~(<\?(?:\w+|=)?|\?>|language\s*=\s*[\"\']?\s*php\s*[\"\']?)~is', $text_blocks[$curr_tb], $sp_match)) {
  3401. +                /* replace tags with placeholders to prevent recursive replacements */
  3402. +                $sp_match[1] = array_unique($sp_match[1]);
  3403. +                usort($sp_match[1], '_smarty_sort_length');
  3404. +                for ($curr_sp = 0, $for_max2 = count($sp_match[1]); $curr_sp < $for_max2; $curr_sp++) {
  3405. +                    $text_blocks[$curr_tb] = str_replace($sp_match[1][$curr_sp],'%%%SMARTYSP'.$curr_sp.'%%%',$text_blocks[$curr_tb]);
  3406. +                }
  3407. +                /* process each one */
  3408. +                for ($curr_sp = 0, $for_max2 = count($sp_match[1]); $curr_sp < $for_max2; $curr_sp++) {
  3409. +                    if ($this->php_handling == SMARTY_PHP_PASSTHRU) {
  3410. +                        /* echo php contents */
  3411. +                        $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', '<?php echo \''.str_replace("'", "\'", $sp_match[1][$curr_sp]).'\'; ?>'."\n", $text_blocks[$curr_tb]);
  3412. +                    } else if ($this->php_handling == SMARTY_PHP_QUOTE) {
  3413. +                        /* quote php tags */
  3414. +                        $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', htmlspecialchars($sp_match[1][$curr_sp]), $text_blocks[$curr_tb]);
  3415. +                    } else if ($this->php_handling == SMARTY_PHP_REMOVE) {
  3416. +                        /* remove php tags */
  3417. +                        $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', '', $text_blocks[$curr_tb]);
  3418. +                    } else {
  3419. +                        /* SMARTY_PHP_ALLOW, but echo non php starting tags */
  3420. +                        $sp_match[1][$curr_sp] = preg_replace('~(<\?(?!php|=|$))~i', '<?php echo \'\\'?>'."\n", $sp_match[1][$curr_sp]);
  3421. +                        $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', $sp_match[1][$curr_sp], $text_blocks[$curr_tb]);
  3422. +                    }
  3423. +                }
  3424. +            }
  3425. +        }
  3426. +        
  3427. +        /* Compile the template tags into PHP code. */
  3428. +        $compiled_tags = array();
  3429. +        for ($i = 0, $for_max = count($template_tags); $i < $for_max; $i++) {
  3430. +            $this->_current_line_no += substr_count($text_blocks[$i], "\n");
  3431. +            $compiled_tags[] = $this->_compile_tag($template_tags[$i]);
  3432. +            $this->_current_line_no += substr_count($template_tags[$i], "\n");
  3433. +        }
  3434. +        if (count($this->_tag_stack)>0) {
  3435. +            list($_open_tag, $_line_no) = end($this->_tag_stack);
  3436. +            $this->_syntax_error("unclosed tag \{$_open_tag} (opened line $_line_no).", E_USER_ERROR, __FILE__, __LINE__);
  3437. +            return;
  3438. +        }
  3439. +
  3440. +        /* Reformat $text_blocks between 'strip' and '/strip' tags,
  3441. +           removing spaces, tabs and newlines. */
  3442. +        $strip = false;
  3443. +        for ($i = 0, $for_max = count($compiled_tags); $i < $for_max; $i++) {
  3444. +            if ($compiled_tags[$i] == '{strip}') {
  3445. +                $compiled_tags[$i] = '';
  3446. +                $strip = true;
  3447. +                /* remove leading whitespaces */
  3448. +                $text_blocks[$i + 1] = ltrim($text_blocks[$i + 1]);
  3449. +            }
  3450. +            if ($strip) {
  3451. +                /* strip all $text_blocks before the next '/strip' */
  3452. +                for ($j = $i + 1; $j < $for_max; $j++) {
  3453. +                    /* remove leading and trailing whitespaces of each line */
  3454. +                    $text_blocks[$j] = preg_replace('![\t ]*[\r\n]+[\t ]*!', '', $text_blocks[$j]);
  3455. +                    if ($compiled_tags[$j] == '{/strip}') {                      
  3456. +                        /* remove trailing whitespaces from the last text_block */
  3457. +                        $text_blocks[$j] = rtrim($text_blocks[$j]);
  3458. +                    }
  3459. +                    $text_blocks[$j] = "<?php echo '" . strtr($text_blocks[$j], array("'"=>"\'", "\\"=>"\\\\")) . "'; ?>";
  3460. +                    if ($compiled_tags[$j] == '{/strip}') {
  3461. +                        $compiled_tags[$j] = "\n"; /* slurped by php, but necessary
  3462. +                                    if a newline is following the closing strip-tag */
  3463. +                        $strip = false;
  3464. +                        $i = $j;
  3465. +                        break;
  3466. +                    }
  3467. +                }
  3468. +            }
  3469. +        }
  3470. +        $compiled_content = '';
  3471. +        
  3472. +        $tag_guard = '%%%SMARTYOTG' . md5(uniqid(rand(), true)) . '%%%';
  3473. +        
  3474. +        /* Interleave the compiled contents and text blocks to get the final result. */
  3475. +        for ($i = 0, $for_max = count($compiled_tags); $i < $for_max; $i++) {
  3476. +            if ($compiled_tags[$i] == '') {
  3477. +                // tag result empty, remove first newline from following text block
  3478. +                $text_blocks[$i+1] = preg_replace('~^(\r\n|\r|\n)~', '', $text_blocks[$i+1]);
  3479. +            }
  3480. +            // replace legit PHP tags with placeholder
  3481. +            $text_blocks[$i] = str_replace('<?', $tag_guard, $text_blocks[$i]);
  3482. +            $compiled_tags[$i] = str_replace('<?', $tag_guard, $compiled_tags[$i]);
  3483. +            
  3484. +            $compiled_content .= $text_blocks[$i] . $compiled_tags[$i];
  3485. +        }
  3486. +        $compiled_content .= str_replace('<?', $tag_guard, $text_blocks[$i]);
  3487. +
  3488. +        // escape php tags created by interleaving
  3489. +        $compiled_content = str_replace('<?', "<?php echo '<?' ?>\n", $compiled_content);
  3490. +        $compiled_content = preg_replace("~(?<!')language\s*=\s*[\"\']?\s*php\s*[\"\']?~", "<?php echo 'language=php' ?>\n", $compiled_content);
  3491. +
  3492. +        // recover legit tags
  3493. +        $compiled_content = str_replace($tag_guard, '<?', $compiled_content);
  3494. +        
  3495. +        // remove \n from the end of the file, if any
  3496. +        if (strlen($compiled_content) && (substr($compiled_content, -1) == "\n") ) {
  3497. +            $compiled_content = substr($compiled_content, 0, -1);
  3498. +        }
  3499. +
  3500. +        if (!empty($this->_cache_serial)) {
  3501. +            $compiled_content = "<?php \$this->_cache_serials['".$this->_cache_include."'] = '".$this->_cache_serial."'; ?>" . $compiled_content;
  3502. +        }
  3503. +
  3504. +        // run compiled template through postfilter functions
  3505. +        if (count($this->_plugins['postfilter']) > 0) {
  3506. +            foreach ($this->_plugins['postfilter'] as $filter_name => $postfilter) {
  3507. +                if ($postfilter === false) continue;
  3508. +                if ($postfilter[3] || is_callable($postfilter[0])) {
  3509. +                    $compiled_content = call_user_func_array($postfilter[0],
  3510. +                                                              array($compiled_content, &$this));
  3511. +                    $this->_plugins['postfilter'][$filter_name][3] = true;
  3512. +                } else {
  3513. +                    $this->_trigger_fatal_error("Smarty plugin error: postfilter '$filter_name' is not implemented");
  3514. +                }
  3515. +            }
  3516. +        }
  3517. +
  3518. +        // put header at the top of the compiled template
  3519. +        $template_header = "<?php /* Smarty version ".$this->_version.", created on ".strftime("%Y-%m-%d %H:%M:%S")."\n";
  3520. +        $template_header .= "         compiled from ".strtr(urlencode($resource_name), array('%2F'=>'/', '%3A'=>':'))." */ ?>\n";
  3521. +
  3522. +        /* Emit code to load needed plugins. */
  3523. +        $this->_plugins_code = '';
  3524. +        if (count($this->_plugin_info)) {
  3525. +            $_plugins_params = "array('plugins' => array(";
  3526. +            foreach ($this->_plugin_info as $plugin_type => $plugins) {
  3527. +                foreach ($plugins as $plugin_name => $plugin_info) {
  3528. +                    $_plugins_params .= "array('$plugin_type', '$plugin_name', '" . strtr($plugin_info[0], array("'" => "\\'", "\\" => "\\\\")) . "', $plugin_info[1], ";
  3529. +                    $_plugins_params .= $plugin_info[2] ? 'true),' : 'false),';
  3530. +                }
  3531. +            }
  3532. +            $_plugins_params .= '))';
  3533. +            $plugins_code = "<?php require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');\nsmarty_core_load_plugins($_plugins_params, \$this); ?>\n";
  3534. +            $template_header .= $plugins_code;
  3535. +            $this->_plugin_info = array();
  3536. +            $this->_plugins_code = $plugins_code;
  3537. +        }
  3538. +
  3539. +        if ($this->_init_smarty_vars) {
  3540. +            $template_header .= "<?php require_once(SMARTY_CORE_DIR . 'core.assign_smarty_interface.php');\nsmarty_core_assign_smarty_interface(null, \$this); ?>\n";
  3541. +            $this->_init_smarty_vars = false;
  3542. +        }
  3543. +
  3544. +        $compiled_content = $template_header . $compiled_content;
  3545. +        return true;
  3546. +    }
  3547. +
  3548. +    /**
  3549. +     * Compile a template tag
  3550. +     *
  3551. +     * @param string $template_tag
  3552. +     * @return string
  3553. +     */
  3554. +    function _compile_tag($template_tag)
  3555. +    {
  3556. +        /* Matched comment. */
  3557. +        if (substr($template_tag, 0, 1) == '*' && substr($template_tag, -1) == '*')
  3558. +            return '';
  3559. +        
  3560. +        /* Split tag into two three parts: command, command modifiers and the arguments. */
  3561. +        if(! preg_match('~^(?:(' . $this->_num_const_regexp . '|' . $this->_obj_call_regexp . '|' . $this->_var_regexp
  3562. +                . '|\/?' . $this->_reg_obj_regexp . '|\/?' . $this->_func_regexp . ')(' . $this->_mod_regexp . '*))
  3563. +                      (?:\s+(.*))?$
  3564. +                    ~xs', $template_tag, $match)) {
  3565. +            $this->_syntax_error("unrecognized tag: $template_tag", E_USER_ERROR, __FILE__, __LINE__);
  3566. +        }
  3567. +        
  3568. +        $tag_command = $match[1];
  3569. +        $tag_modifier = isset($match[2]) ? $match[2] : null;
  3570. +        $tag_args = isset($match[3]) ? $match[3] : null;
  3571. +
  3572. +        if (preg_match('~^' . $this->_num_const_regexp . '|' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '$~', $tag_command)) {
  3573. +            /* tag name is a variable or object */
  3574. +            $_return = $this->_parse_var_props($tag_command . $tag_modifier);
  3575. +            return "<?php echo $_return; ?>" . $this->_additional_newline;
  3576. +        }
  3577. +
  3578. +        /* If the tag name is a registered object, we process it. */
  3579. +        if (preg_match('~^\/?' . $this->_reg_obj_regexp . '$~', $tag_command)) {
  3580. +            return $this->_compile_registered_object_tag($tag_command, $this->_parse_attrs($tag_args), $tag_modifier);
  3581. +        }
  3582. +
  3583. +        switch ($tag_command) {
  3584. +            case 'include':
  3585. +                return $this->_compile_include_tag($tag_args);
  3586. +
  3587. +            case 'include_php':
  3588. +                return $this->_compile_include_php_tag($tag_args);
  3589. +
  3590. +            case 'if':
  3591. +                $this->_push_tag('if');
  3592. +                return $this->_compile_if_tag($tag_args);
  3593. +
  3594. +            case 'else':
  3595. +                list($_open_tag) = end($this->_tag_stack);
  3596. +                if ($_open_tag != 'if' && $_open_tag != 'elseif')
  3597. +                    $this->_syntax_error('unexpected {else}', E_USER_ERROR, __FILE__, __LINE__);
  3598. +                else
  3599. +                    $this->_push_tag('else');
  3600. +                return '<?php else: ?>';
  3601. +
  3602. +            case 'elseif':
  3603. +                list($_open_tag) = end($this->_tag_stack);
  3604. +                if ($_open_tag != 'if' && $_open_tag != 'elseif')
  3605. +                    $this->_syntax_error('unexpected {elseif}', E_USER_ERROR, __FILE__, __LINE__);
  3606. +                if ($_open_tag == 'if')
  3607. +                    $this->_push_tag('elseif');
  3608. +                return $this->_compile_if_tag($tag_args, true);
  3609. +
  3610. +            case '/if':
  3611. +                $this->_pop_tag('if');
  3612. +                return '<?php endif; ?>';
  3613. +
  3614. +            case 'capture':
  3615. +                return $this->_compile_capture_tag(true, $tag_args);
  3616. +
  3617. +            case '/capture':
  3618. +                return $this->_compile_capture_tag(false);
  3619. +
  3620. +            case 'ldelim':
  3621. +                return $this->left_delimiter;
  3622. +
  3623. +            case 'rdelim':
  3624. +                return $this->right_delimiter;
  3625. +
  3626. +            case 'section':
  3627. +                $this->_push_tag('section');
  3628. +                return $this->_compile_section_start($tag_args);
  3629. +
  3630. +            case 'sectionelse':
  3631. +                $this->_push_tag('sectionelse');
  3632. +                return "<?php endfor; else: ?>";
  3633. +                break;
  3634. +
  3635. +            case '/section':
  3636. +                $_open_tag = $this->_pop_tag('section');
  3637. +                if ($_open_tag == 'sectionelse')
  3638. +                    return "<?php endif; ?>";
  3639. +                else
  3640. +                    return "<?php endfor; endif; ?>";
  3641. +
  3642. +            case 'foreach':
  3643. +                $this->_push_tag('foreach');
  3644. +                return $this->_compile_foreach_start($tag_args);
  3645. +                break;
  3646. +
  3647. +            case 'foreachelse':
  3648. +                $this->_push_tag('foreachelse');
  3649. +                return "<?php endforeach; else: ?>";
  3650. +
  3651. +            case '/foreach':
  3652. +                $_open_tag = $this->_pop_tag('foreach');
  3653. +                if ($_open_tag == 'foreachelse')
  3654. +                    return "<?php endif; unset(\$_from); ?>";
  3655. +                else
  3656. +                    return "<?php endforeach; endif; unset(\$_from); ?>";
  3657. +                break;
  3658. +
  3659. +            case 'strip':
  3660. +            case '/strip':
  3661. +                if (substr($tag_command, 0, 1)=='/') {
  3662. +                    $this->_pop_tag('strip');
  3663. +                    if (--$this->_strip_depth==0) { /* outermost closing {/strip} */
  3664. +                        $this->_additional_newline = "\n";
  3665. +                        return '{' . $tag_command . '}';
  3666. +                    }
  3667. +                } else {
  3668. +                    $this->_push_tag('strip');
  3669. +                    if ($this->_strip_depth++==0) { /* outermost opening {strip} */
  3670. +                        $this->_additional_newline = "";
  3671. +                        return '{' . $tag_command . '}';
  3672. +                    }
  3673. +                }
  3674. +                return '';
  3675. +
  3676. +            case 'php':
  3677. +                /* handle folded tags replaced by {php} */
  3678. +                list(, $block) = each($this->_folded_blocks);
  3679. +                $this->_current_line_no += substr_count($block[0], "\n");
  3680. +                /* the number of matched elements in the regexp in _compile_file()
  3681. +                   determins the type of folded tag that was found */
  3682. +                switch (count($block)) {
  3683. +                    case 2: /* comment */
  3684. +                        return '';
  3685. +
  3686. +                    case 3: /* literal */
  3687. +                        return "<?php echo '" . strtr($block[2], array("'"=>"\'", "\\"=>"\\\\")) . "'; ?>" . $this->_additional_newline;
  3688. +
  3689. +                    case 4: /* php */
  3690. +                        if ($this->security && !$this->security_settings['PHP_TAGS']) {
  3691. +                            $this->_syntax_error("(secure mode) php tags not permitted", E_USER_WARNING, __FILE__, __LINE__);
  3692. +                            return;
  3693. +                        }
  3694. +                        return '<?php ' . $block[3] .' ?>';
  3695. +                }
  3696. +                break;
  3697. +
  3698. +            case 'insert':
  3699. +                return $this->_compile_insert_tag($tag_args);
  3700. +
  3701. +            default:
  3702. +                if ($this->_compile_compiler_tag($tag_command, $tag_args, $output)) {
  3703. +                    return $output;
  3704. +                } else if ($this->_compile_block_tag($tag_command, $tag_args, $tag_modifier, $output)) {
  3705. +                    return $output;
  3706. +                } else if ($this->_compile_custom_tag($tag_command, $tag_args, $tag_modifier, $output)) {
  3707. +                    return $output;                    
  3708. +                } else {
  3709. +                    $this->_syntax_error("unrecognized tag '$tag_command'", E_USER_ERROR, __FILE__, __LINE__);
  3710. +                }
  3711. +
  3712. +        }
  3713. +    }
  3714. +
  3715. +
  3716. +    /**
  3717. +     * compile the custom compiler tag
  3718. +     *
  3719. +     * sets $output to the compiled custom compiler tag
  3720. +     * @param string $tag_command
  3721. +     * @param string $tag_args
  3722. +     * @param string $output
  3723. +     * @return boolean
  3724. +     */
  3725. +    function _compile_compiler_tag($tag_command, $tag_args, &$output)
  3726. +    {
  3727. +        $found = false;
  3728. +        $have_function = true;
  3729. +
  3730. +        /*
  3731. +         * First we check if the compiler function has already been registered
  3732. +         * or loaded from a plugin file.
  3733. +         */
  3734. +        if (isset($this->_plugins['compiler'][$tag_command])) {
  3735. +            $found = true;
  3736. +            $plugin_func = $this->_plugins['compiler'][$tag_command][0];
  3737. +            if (!is_callable($plugin_func)) {
  3738. +                $message = "compiler function '$tag_command' is not implemented";
  3739. +                $have_function = false;
  3740. +            }
  3741. +        }
  3742. +        /*
  3743. +         * Otherwise we need to load plugin file and look for the function
  3744. +         * inside it.
  3745. +         */
  3746. +        else if ($plugin_file = $this->_get_plugin_filepath('compiler', $tag_command)) {
  3747. +            $found = true;
  3748. +
  3749. +            include_once $plugin_file;
  3750. +
  3751. +            $plugin_func = 'smarty_compiler_' . $tag_command;
  3752. +            if (!is_callable($plugin_func)) {
  3753. +                $message = "plugin function $plugin_func() not found in $plugin_file\n";
  3754. +                $have_function = false;
  3755. +            } else {
  3756. +                $this->_plugins['compiler'][$tag_command] = array($plugin_func, null, null, null, true);
  3757. +            }
  3758. +        }
  3759. +
  3760. +        /*
  3761. +         * True return value means that we either found a plugin or a
  3762. +         * dynamically registered function. False means that we didn't and the
  3763. +         * compiler should now emit code to load custom function plugin for this
  3764. +         * tag.
  3765. +         */
  3766. +        if ($found) {
  3767. +            if ($have_function) {
  3768. +                $output = call_user_func_array($plugin_func, array($tag_args, &$this));
  3769. +                if($output != '') {
  3770. +                $output = '<?php ' . $this->_push_cacheable_state('compiler', $tag_command)
  3771. +                                   . $output
  3772. +                                   . $this->_pop_cacheable_state('compiler', $tag_command) . ' ?>';
  3773. +                }
  3774. +            } else {
  3775. +                $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__);
  3776. +            }
  3777. +            return true;
  3778. +        } else {
  3779. +            return false;
  3780. +        }
  3781. +    }
  3782. +
  3783. +
  3784. +    /**
  3785. +     * compile block function tag
  3786. +     *
  3787. +     * sets $output to compiled block function tag
  3788. +     * @param string $tag_command
  3789. +     * @param string $tag_args
  3790. +     * @param string $tag_modifier
  3791. +     * @param string $output
  3792. +     * @return boolean
  3793. +     */
  3794. +    function _compile_block_tag($tag_command, $tag_args, $tag_modifier, &$output)
  3795. +    {
  3796. +        if (substr($tag_command, 0, 1) == '/') {
  3797. +            $start_tag = false;
  3798. +            $tag_command = substr($tag_command, 1);
  3799. +        } else
  3800. +            $start_tag = true;
  3801. +
  3802. +        $found = false;
  3803. +        $have_function = true;
  3804. +
  3805. +        /*
  3806. +         * First we check if the block function has already been registered
  3807. +         * or loaded from a plugin file.
  3808. +         */
  3809. +        if (isset($this->_plugins['block'][$tag_command])) {
  3810. +            $found = true;
  3811. +            $plugin_func = $this->_plugins['block'][$tag_command][0];
  3812. +            if (!is_callable($plugin_func)) {
  3813. +                $message = "block function '$tag_command' is not implemented";
  3814. +                $have_function = false;
  3815. +            }
  3816. +        }
  3817. +        /*
  3818. +         * Otherwise we need to load plugin file and look for the function
  3819. +         * inside it.
  3820. +         */
  3821. +        else if ($plugin_file = $this->_get_plugin_filepath('block', $tag_command)) {
  3822. +            $found = true;
  3823. +
  3824. +            include_once $plugin_file;
  3825. +
  3826. +            $plugin_func = 'smarty_block_' . $tag_command;
  3827. +            if (!function_exists($plugin_func)) {
  3828. +                $message = "plugin function $plugin_func() not found in $plugin_file\n";
  3829. +                $have_function = false;
  3830. +            } else {
  3831. +                $this->_plugins['block'][$tag_command] = array($plugin_func, null, null, null, true);
  3832. +
  3833. +            }
  3834. +        }
  3835. +
  3836. +        if (!$found) {
  3837. +            return false;
  3838. +        } else if (!$have_function) {
  3839. +            $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__);
  3840. +            return true;
  3841. +        }
  3842. +
  3843. +        /*
  3844. +         * Even though we've located the plugin function, compilation
  3845. +         * happens only once, so the plugin will still need to be loaded
  3846. +         * at runtime for future requests.
  3847. +         */
  3848. +        $this->_add_plugin('block', $tag_command);
  3849. +
  3850. +        if ($start_tag)
  3851. +            $this->_push_tag($tag_command);
  3852. +        else
  3853. +            $this->_pop_tag($tag_command);
  3854. +
  3855. +        if ($start_tag) {
  3856. +            $output = '<?php ' . $this->_push_cacheable_state('block', $tag_command);
  3857. +            $attrs = $this->_parse_attrs($tag_args);
  3858. +            $_cache_attrs='';
  3859. +            $arg_list = $this->_compile_arg_list('block', $tag_command, $attrs, $_cache_attrs);
  3860. +            $output .= "$_cache_attrs\$this->_tag_stack[] = array('$tag_command', array(".implode(',', $arg_list).')); ';
  3861. +            $output .= '$_block_repeat=true;' . $this->_compile_plugin_call('block', $tag_command).'($this->_tag_stack[count($this->_tag_stack)-1][1], null, $this, $_block_repeat);';
  3862. +            $output .= 'while ($_block_repeat) { ob_start(); ?>';
  3863. +        } else {
  3864. +            $output = '<?php $_block_content = ob_get_contents(); ob_end_clean(); ';
  3865. +            $_out_tag_text = $this->_compile_plugin_call('block', $tag_command).'($this->_tag_stack[count($this->_tag_stack)-1][1], $_block_content, $this, $_block_repeat)';
  3866. +            if ($tag_modifier != '') {
  3867. +                $this->_parse_modifiers($_out_tag_text, $tag_modifier);
  3868. +            }
  3869. +            $output .= '$_block_repeat=false;echo ' . $_out_tag_text . '; } ';
  3870. +            $output .= " array_pop(\$this->_tag_stack); " . $this->_pop_cacheable_state('block', $tag_command) . '?>';
  3871. +        }
  3872. +
  3873. +        return true;
  3874. +    }
  3875. +
  3876. +
  3877. +    /**
  3878. +     * compile custom function tag
  3879. +     *
  3880. +     * @param string $tag_command
  3881. +     * @param string $tag_args
  3882. +     * @param string $tag_modifier
  3883. +     * @return string
  3884. +     */
  3885. +    function _compile_custom_tag($tag_command, $tag_args, $tag_modifier, &$output)
  3886. +    {
  3887. +        $found = false;
  3888. +        $have_function = true;
  3889. +
  3890. +        /*
  3891. +         * First we check if the custom function has already been registered
  3892. +         * or loaded from a plugin file.
  3893. +         */
  3894. +        if (isset($this->_plugins['function'][$tag_command])) {
  3895. +            $found = true;
  3896. +            $plugin_func = $this->_plugins['function'][$tag_command][0];
  3897. +            if (!is_callable($plugin_func)) {
  3898. +                $message = "custom function '$tag_command' is not implemented";
  3899. +                $have_function = false;
  3900. +            }
  3901. +        }
  3902. +        /*
  3903. +         * Otherwise we need to load plugin file and look for the function
  3904. +         * inside it.
  3905. +         */
  3906. +        else if ($plugin_file = $this->_get_plugin_filepath('function', $tag_command)) {
  3907. +            $found = true;
  3908. +
  3909. +            include_once $plugin_file;
  3910. +
  3911. +            $plugin_func = 'smarty_function_' . $tag_command;
  3912. +            if (!function_exists($plugin_func)) {
  3913. +                $message = "plugin function $plugin_func() not found in $plugin_file\n";
  3914. +                $have_function = false;
  3915. +            } else {
  3916. +                $this->_plugins['function'][$tag_command] = array($plugin_func, null, null, null, true);
  3917. +
  3918. +            }
  3919. +        }
  3920. +
  3921. +        if (!$found) {
  3922. +            return false;
  3923. +        } else if (!$have_function) {
  3924. +            $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__);
  3925. +            return true;
  3926. +        }
  3927. +
  3928. +        /* declare plugin to be loaded on display of the template that
  3929. +           we compile right now */
  3930. +        $this->_add_plugin('function', $tag_command);
  3931. +
  3932. +        $_cacheable_state = $this->_push_cacheable_state('function', $tag_command);
  3933. +        $attrs = $this->_parse_attrs($tag_args);
  3934. +        $_cache_attrs = '';
  3935. +        $arg_list = $this->_compile_arg_list('function', $tag_command, $attrs, $_cache_attrs);
  3936. +
  3937. +        $output = $this->_compile_plugin_call('function', $tag_command).'(array('.implode(',', $arg_list)."), \$this)";
  3938. +        if($tag_modifier != '') {
  3939. +            $this->_parse_modifiers($output, $tag_modifier);
  3940. +        }
  3941. +
  3942. +        if($output != '') {
  3943. +            $output =  '<?php ' . $_cacheable_state . $_cache_attrs . 'echo ' . $output . ';'
  3944. +                . $this->_pop_cacheable_state('function', $tag_command) . "?>" . $this->_additional_newline;
  3945. +        }
  3946. +
  3947. +        return true;
  3948. +    }
  3949. +
  3950. +    /**
  3951. +     * compile a registered object tag
  3952. +     *
  3953. +     * @param string $tag_command
  3954. +     * @param array $attrs
  3955. +     * @param string $tag_modifier
  3956. +     * @return string
  3957. +     */
  3958. +    function _compile_registered_object_tag($tag_command, $attrs, $tag_modifier)
  3959. +    {
  3960. +        if (substr($tag_command, 0, 1) == '/') {
  3961. +            $start_tag = false;
  3962. +            $tag_command = substr($tag_command, 1);
  3963. +        } else {
  3964. +            $start_tag = true;
  3965. +        }
  3966. +
  3967. +        list($object, $obj_comp) = explode('->', $tag_command);
  3968. +
  3969. +        $arg_list = array();
  3970. +        if(count($attrs)) {
  3971. +            $_assign_var = false;
  3972. +            foreach ($attrs as $arg_name => $arg_value) {
  3973. +                if($arg_name == 'assign') {
  3974. +                    $_assign_var = $arg_value;
  3975. +                    unset($attrs['assign']);
  3976. +                    continue;
  3977. +                }
  3978. +                if (is_bool($arg_value))
  3979. +                    $arg_value = $arg_value ? 'true' : 'false';
  3980. +                $arg_list[] = "'$arg_name' => $arg_value";
  3981. +            }
  3982. +        }
  3983. +
  3984. +        if($this->_reg_objects[$object][2]) {
  3985. +            // smarty object argument format
  3986. +            $args = "array(".implode(',', (array)$arg_list)."), \$this";
  3987. +        } else {
  3988. +            // traditional argument format
  3989. +            $args = implode(',', array_values($attrs));
  3990. +            if (empty($args)) {
  3991. +                $args = '';
  3992. +            }
  3993. +        }
  3994. +
  3995. +        $prefix = '';
  3996. +        $postfix = '';
  3997. +        $newline = '';
  3998. +        if(!is_object($this->_reg_objects[$object][0])) {
  3999. +            $this->_trigger_fatal_error("registered '$object' is not an object" , $this->_current_file, $this->_current_line_no, __FILE__, __LINE__);
  4000. +        } elseif(!empty($this->_reg_objects[$object][1]) && !in_array($obj_comp, $this->_reg_objects[$object][1])) {
  4001. +            $this->_trigger_fatal_error("'$obj_comp' is not a registered component of object '$object'", $this->_current_file, $this->_current_line_no, __FILE__, __LINE__);
  4002. +        } elseif(method_exists($this->_reg_objects[$object][0], $obj_comp)) {
  4003. +            // method
  4004. +            if(in_array($obj_comp, $this->_reg_objects[$object][3])) {
  4005. +                // block method
  4006. +                if ($start_tag) {
  4007. +                    $prefix = "\$this->_tag_stack[] = array('$obj_comp', $args); ";
  4008. +                    $prefix .= "\$_block_repeat=true; \$this->_reg_objects['$object'][0]->$obj_comp(\$this->_tag_stack[count(\$this->_tag_stack)-1][1], null, \$this, \$_block_repeat); ";
  4009. +                    $prefix .= "while (\$_block_repeat) { ob_start();";
  4010. +                    $return = null;
  4011. +                    $postfix = '';
  4012. +                } else {
  4013. +                    $prefix = "\$_obj_block_content = ob_get_contents(); ob_end_clean(); \$_block_repeat=false;";
  4014. +                    $return = "\$this->_reg_objects['$object'][0]->$obj_comp(\$this->_tag_stack[count(\$this->_tag_stack)-1][1], \$_obj_block_content, \$this, \$_block_repeat)";
  4015. +                    $postfix = "} array_pop(\$this->_tag_stack);";
  4016. +                }
  4017. +            } else {
  4018. +                // non-block method
  4019. +                $return = "\$this->_reg_objects['$object'][0]->$obj_comp($args)";
  4020. +            }
  4021. +        } else {
  4022. +            // property
  4023. +            $return = "\$this->_reg_objects['$object'][0]->$obj_comp";
  4024. +        }
  4025. +
  4026. +        if($return != null) {
  4027. +            if($tag_modifier != '') {
  4028. +                $this->_parse_modifiers($return, $tag_modifier);
  4029. +            }
  4030. +
  4031. +            if(!empty($_assign_var)) {
  4032. +                $output = "\$this->assign('" . $this->_dequote($_assign_var) ."',  $return);";
  4033. +            } else {
  4034. +                $output = 'echo ' . $return . ';';
  4035. +                $newline = $this->_additional_newline;
  4036. +            }
  4037. +        } else {
  4038. +            $output = '';
  4039. +        }
  4040. +
  4041. +        return '<?php ' . $prefix . $output . $postfix . "?>" . $newline;
  4042. +    }
  4043. +
  4044. +    /**
  4045. +     * Compile {insert ...} tag
  4046. +     *
  4047. +     * @param string $tag_args
  4048. +     * @return string
  4049. +     */
  4050. +    function _compile_insert_tag($tag_args)
  4051. +    {
  4052. +        $attrs = $this->_parse_attrs($tag_args);
  4053. +        $name = $this->_dequote($attrs['name']);
  4054. +
  4055. +        if (empty($name)) {
  4056. +            return $this->_syntax_error("missing insert name", E_USER_ERROR, __FILE__, __LINE__);
  4057. +        }
  4058. +        
  4059. +        if (!preg_match('~^\w+$~', $name)) {
  4060. +            return $this->_syntax_error("'insert: 'name' must be an insert function name", E_USER_ERROR, __FILE__, __LINE__);
  4061. +        }
  4062. +
  4063. +        if (!empty($attrs['script'])) {
  4064. +            $delayed_loading = true;
  4065. +        } else {
  4066. +            $delayed_loading = false;
  4067. +        }
  4068. +
  4069. +        foreach ($attrs as $arg_name => $arg_value) {
  4070. +            if (is_bool($arg_value))
  4071. +                $arg_value = $arg_value ? 'true' : 'false';
  4072. +            $arg_list[] = "'$arg_name' => $arg_value";
  4073. +        }
  4074. +
  4075. +        $this->_add_plugin('insert', $name, $delayed_loading);
  4076. +
  4077. +        $_params = "array('args' => array(".implode(', ', (array)$arg_list)."))";
  4078. +
  4079. +        return "<?php require_once(SMARTY_CORE_DIR . 'core.run_insert_handler.php');\necho smarty_core_run_insert_handler($_params, \$this); ?>" . $this->_additional_newline;
  4080. +    }
  4081. +
  4082. +    /**
  4083. +     * Compile {include ...} tag
  4084. +     *
  4085. +     * @param string $tag_args
  4086. +     * @return string
  4087. +     */
  4088. +    function _compile_include_tag($tag_args)
  4089. +    {
  4090. +        $attrs = $this->_parse_attrs($tag_args);
  4091. +        $arg_list = array();
  4092. +
  4093. +        if (empty($attrs['file'])) {
  4094. +            $this->_syntax_error("missing 'file' attribute in include tag", E_USER_ERROR, __FILE__, __LINE__);
  4095. +        }
  4096. +
  4097. +        foreach ($attrs as $arg_name => $arg_value) {
  4098. +            if ($arg_name == 'file') {
  4099. +                $include_file = $arg_value;
  4100. +                continue;
  4101. +            } else if ($arg_name == 'assign') {
  4102. +                $assign_var = $arg_value;
  4103. +                continue;
  4104. +            }
  4105. +            if (is_bool($arg_value))
  4106. +                $arg_value = $arg_value ? 'true' : 'false';
  4107. +            $arg_list[] = "'$arg_name' => $arg_value";
  4108. +        }
  4109. +
  4110. +        $output = '<?php ';
  4111. +
  4112. +        if (isset($assign_var)) {
  4113. +            $output .= "ob_start();\n";
  4114. +        }
  4115. +
  4116. +        $output .=
  4117. +            "\$_smarty_tpl_vars = \$this->_tpl_vars;\n";
  4118. +
  4119. +
  4120. +        $_params = "array('smarty_include_tpl_file' => " . $include_file . ", 'smarty_include_vars' => array(".implode(',', (array)$arg_list)."))";
  4121. +        $output .= "\$this->_smarty_include($_params);\n" .
  4122. +        "\$this->_tpl_vars = \$_smarty_tpl_vars;\n" .
  4123. +        "unset(\$_smarty_tpl_vars);\n";
  4124. +
  4125. +        if (isset($assign_var)) {
  4126. +            $output .= "\$this->assign(" . $assign_var . ", ob_get_contents()); ob_end_clean();\n";
  4127. +        }
  4128. +
  4129. +        $output .= ' ?>';
  4130. +
  4131. +        return $output;
  4132. +
  4133. +    }
  4134. +
  4135. +    /**
  4136. +     * Compile {include ...} tag
  4137. +     *
  4138. +     * @param string $tag_args
  4139. +     * @return string
  4140. +     */
  4141. +    function _compile_include_php_tag($tag_args)
  4142. +    {
  4143. +        $attrs = $this->_parse_attrs($tag_args);
  4144. +
  4145. +        if (empty($attrs['file'])) {
  4146. +            $this->_syntax_error("missing 'file' attribute in include_php tag", E_USER_ERROR, __FILE__, __LINE__);
  4147. +        }
  4148. +
  4149. +        $assign_var = (empty($attrs['assign'])) ? '' : $this->_dequote($attrs['assign']);
  4150. +        $once_var = (empty($attrs['once']) || $attrs['once']=='false') ? 'false' : 'true';
  4151. +
  4152. +        $arg_list = array();
  4153. +        foreach($attrs as $arg_name => $arg_value) {
  4154. +            if($arg_name != 'file' AND $arg_name != 'once' AND $arg_name != 'assign') {
  4155. +                if(is_bool($arg_value))
  4156. +                    $arg_value = $arg_value ? 'true' : 'false';
  4157. +                $arg_list[] = "'$arg_name' => $arg_value";
  4158. +            }
  4159. +        }
  4160. +
  4161. +        $_params = "array('smarty_file' => " . $attrs['file'] . ", 'smarty_assign' => '$assign_var', 'smarty_once' => $once_var, 'smarty_include_vars' => array(".implode(',', $arg_list)."))";
  4162. +
  4163. +        return "<?php require_once(SMARTY_CORE_DIR . 'core.smarty_include_php.php');\nsmarty_core_smarty_include_php($_params, \$this); ?>" . $this->_additional_newline;
  4164. +    }
  4165. +
  4166. +
  4167. +    /**
  4168. +     * Compile {section ...} tag
  4169. +     *
  4170. +     * @param string $tag_args
  4171. +     * @return string
  4172. +     */
  4173. +    function _compile_section_start($tag_args)
  4174. +    {
  4175. +        $attrs = $this->_parse_attrs($tag_args);
  4176. +        $arg_list = array();
  4177. +
  4178. +        $output = '<?php ';
  4179. +        $section_name = $attrs['name'];
  4180. +        if (empty($section_name)) {
  4181. +            $this->_syntax_error("missing section name", E_USER_ERROR, __FILE__, __LINE__);
  4182. +        }
  4183. +
  4184. +        $output .= "unset(\$this->_sections[$section_name]);\n";
  4185. +        $section_props = "\$this->_sections[$section_name]";
  4186. +
  4187. +        foreach ($attrs as $attr_name => $attr_value) {
  4188. +            switch ($attr_name) {
  4189. +                case 'loop':
  4190. +                    $output .= "{$section_props}['loop'] = is_array(\$_loop=$attr_value) ? count(\$_loop) : max(0, (int)\$_loop); unset(\$_loop);\n";
  4191. +                    break;
  4192. +
  4193. +                case 'show':
  4194. +                    if (is_bool($attr_value))
  4195. +                        $show_attr_value = $attr_value ? 'true' : 'false';
  4196. +                    else
  4197. +                        $show_attr_value = "(bool)$attr_value";
  4198. +                    $output .= "{$section_props}['show'] = $show_attr_value;\n";
  4199. +                    break;
  4200. +
  4201. +                case 'name':
  4202. +                    $output .= "{$section_props}['$attr_name'] = $attr_value;\n";
  4203. +                    break;
  4204. +
  4205. +                case 'max':
  4206. +                case 'start':
  4207. +                    $output .= "{$section_props}['$attr_name'] = (int)$attr_value;\n";
  4208. +                    break;
  4209. +
  4210. +                case 'step':
  4211. +                    $output .= "{$section_props}['$attr_name'] = ((int)$attr_value) == 0 ? 1 : (int)$attr_value;\n";
  4212. +                    break;
  4213. +
  4214. +                default:
  4215. +                    $this->_syntax_error("unknown section attribute - '$attr_name'", E_USER_ERROR, __FILE__, __LINE__);
  4216. +                    break;
  4217. +            }
  4218. +        }
  4219. +
  4220. +        if (!isset($attrs['show']))
  4221. +            $output .= "{$section_props}['show'] = true;\n";
  4222. +
  4223. +        if (!isset($attrs['loop']))
  4224. +            $output .= "{$section_props}['loop'] = 1;\n";
  4225. +
  4226. +        if (!isset($attrs['max']))
  4227. +            $output .= "{$section_props}['max'] = {$section_props}['loop'];\n";
  4228. +        else
  4229. +            $output .= "if ({$section_props}['max'] < 0)\n" .
  4230. +                       "    {$section_props}['max'] = {$section_props}['loop'];\n";
  4231. +
  4232. +        if (!isset($attrs['step']))
  4233. +            $output .= "{$section_props}['step'] = 1;\n";
  4234. +
  4235. +        if (!isset($attrs['start']))
  4236. +            $output .= "{$section_props}['start'] = {$section_props}['step'] > 0 ? 0 : {$section_props}['loop']-1;\n";
  4237. +        else {
  4238. +            $output .= "if ({$section_props}['start'] < 0)\n" .
  4239. +                       "    {$section_props}['start'] = max({$section_props}['step'] > 0 ? 0 : -1, {$section_props}['loop'] + {$section_props}['start']);\n" .
  4240. +                       "else\n" .
  4241. +                       "    {$section_props}['start'] = min({$section_props}['start'], {$section_props}['step'] > 0 ? {$section_props}['loop'] : {$section_props}['loop']-1);\n";
  4242. +        }
  4243. +
  4244. +        $output .= "if ({$section_props}['show']) {\n";
  4245. +        if (!isset($attrs['start']) && !isset($attrs['step']) && !isset($attrs['max'])) {
  4246. +            $output .= "    {$section_props}['total'] = {$section_props}['loop'];\n";
  4247. +        } else {
  4248. +            $output .= "    {$section_props}['total'] = min(ceil(({$section_props}['step'] > 0 ? {$section_props}['loop'] - {$section_props}['start'] : {$section_props}['start']+1)/abs({$section_props}['step'])), {$section_props}['max']);\n";
  4249. +        }
  4250. +        $output .= "    if ({$section_props}['total'] == 0)\n" .
  4251. +                   "        {$section_props}['show'] = false;\n" .
  4252. +                   "} else\n" .
  4253. +                   "    {$section_props}['total'] = 0;\n";
  4254. +
  4255. +        $output .= "if ({$section_props}['show']):\n";
  4256. +        $output .= "
  4257. +            for ({$section_props}['index'] = {$section_props}['start'], {$section_props}['iteration'] = 1;
  4258. +                 {$section_props}['iteration'] <= {$section_props}['total'];
  4259. +                 {$section_props}['index'] += {$section_props}['step'], {$section_props}['iteration']++):\n";
  4260. +        $output .= "{$section_props}['rownum'] = {$section_props}['iteration'];\n";
  4261. +        $output .= "{$section_props}['index_prev'] = {$section_props}['index'] - {$section_props}['step'];\n";
  4262. +        $output .= "{$section_props}['index_next'] = {$section_props}['index'] + {$section_props}['step'];\n";
  4263. +        $output .= "{$section_props}['first']      = ({$section_props}['iteration'] == 1);\n";
  4264. +        $output .= "{$section_props}['last']       = ({$section_props}['iteration'] == {$section_props}['total']);\n";
  4265. +
  4266. +        $output .= "?>";
  4267. +
  4268. +        return $output;
  4269. +    }
  4270. +
  4271. +
  4272. +    /**
  4273. +     * Compile {foreach ...} tag.
  4274. +     *
  4275. +     * @param string $tag_args
  4276. +     * @return string
  4277. +     */
  4278. +    function _compile_foreach_start($tag_args)
  4279. +    {
  4280. +        $attrs = $this->_parse_attrs($tag_args);
  4281. +        $arg_list = array();
  4282. +
  4283. +        if (empty($attrs['from'])) {
  4284. +            return $this->_syntax_error("foreach: missing 'from' attribute", E_USER_ERROR, __FILE__, __LINE__);
  4285. +        }
  4286. +        $from = $attrs['from'];
  4287. +
  4288. +        if (empty($attrs['item'])) {
  4289. +            return $this->_syntax_error("foreach: missing 'item' attribute", E_USER_ERROR, __FILE__, __LINE__);
  4290. +        }
  4291. +        $item = $this->_dequote($attrs['item']);
  4292. +        if (!preg_match('~^\w+$~', $item)) {
  4293. +            return $this->_syntax_error("foreach: 'item' must be a variable name (literal string)", E_USER_ERROR, __FILE__, __LINE__);
  4294. +        }
  4295. +
  4296. +        if (isset($attrs['key'])) {
  4297. +            $key  = $this->_dequote($attrs['key']);
  4298. +            if (!preg_match('~^\w+$~', $key)) {
  4299. +                return $this->_syntax_error("foreach: 'key' must to be a variable name (literal string)", E_USER_ERROR, __FILE__, __LINE__);
  4300. +            }
  4301. +            $key_part = "\$this->_tpl_vars['$key'] => ";
  4302. +        } else {
  4303. +            $key = null;
  4304. +            $key_part = '';
  4305. +        }
  4306. +
  4307. +        if (isset($attrs['name'])) {
  4308. +            $name = $attrs['name'];
  4309. +        } else {
  4310. +            $name = null;
  4311. +        }
  4312. +
  4313. +        $output = '<?php ';
  4314. +        $output .= "\$_from = $from; if (!is_array(\$_from) && !is_object(\$_from)) { settype(\$_from, 'array'); }";
  4315. +        if (isset($name)) {
  4316. +            $foreach_props = "\$this->_foreach[$name]";
  4317. +            $output .= "{$foreach_props} = array('total' => count(\$_from), 'iteration' => 0);\n";
  4318. +            $output .= "if ({$foreach_props}['total'] > 0):\n";
  4319. +            $output .= "    foreach (\$_from as $key_part\$this->_tpl_vars['$item']):\n";
  4320. +            $output .= "        {$foreach_props}['iteration']++;\n";
  4321. +        } else {
  4322. +            $output .= "if (count(\$_from)):\n";
  4323. +            $output .= "    foreach (\$_from as $key_part\$this->_tpl_vars['$item']):\n";
  4324. +        }
  4325. +        $output .= '?>';
  4326. +
  4327. +        return $output;
  4328. +    }
  4329. +
  4330. +
  4331. +    /**
  4332. +     * Compile {capture} .. {/capture} tags
  4333. +     *
  4334. +     * @param boolean $start true if this is the {capture} tag
  4335. +     * @param string $tag_args
  4336. +     * @return string
  4337. +     */
  4338. +
  4339. +    function _compile_capture_tag($start, $tag_args = '')
  4340. +    {
  4341. +        $attrs = $this->_parse_attrs($tag_args);
  4342. +
  4343. +        if ($start) {
  4344. +            $buffer = isset($attrs['name']) ? $attrs['name'] : "'default'";
  4345. +            $assign = isset($attrs['assign']) ? $attrs['assign'] : null;
  4346. +            $append = isset($attrs['append']) ? $attrs['append'] : null;
  4347. +            
  4348. +            $output = "<?php ob_start(); ?>";
  4349. +            $this->_capture_stack[] = array($buffer, $assign, $append);
  4350. +        } else {
  4351. +            list($buffer, $assign, $append) = array_pop($this->_capture_stack);
  4352. +            $output = "<?php \$this->_smarty_vars['capture'][$buffer] = ob_get_contents(); ";
  4353. +            if (isset($assign)) {
  4354. +                $output .= " \$this->assign($assign, ob_get_contents());";
  4355. +            }
  4356. +            if (isset($append)) {
  4357. +                $output .= " \$this->append($append, ob_get_contents());";
  4358. +            }
  4359. +            $output .= "ob_end_clean(); ?>";
  4360. +        }
  4361. +
  4362. +        return $output;
  4363. +    }
  4364. +
  4365. +    /**
  4366. +     * Compile {if ...} tag
  4367. +     *
  4368. +     * @param string $tag_args
  4369. +     * @param boolean $elseif if true, uses elseif instead of if
  4370. +     * @return string
  4371. +     */
  4372. +    function _compile_if_tag($tag_args, $elseif = false)
  4373. +    {
  4374. +
  4375. +        /* Tokenize args for 'if' tag. */
  4376. +        preg_match_all('~(?>
  4377. +                ' . $this->_obj_call_regexp . '(?:' . $this->_mod_regexp . '*)? | # valid object call
  4378. +                ' . $this->_var_regexp . '(?:' . $this->_mod_regexp . '*)?    | # var or quoted string
  4379. +                \-?0[xX][0-9a-fA-F]+|\-?\d+(?:\.\d+)?|\.\d+|!==|===|==|!=|<>|<<|>>|<=|>=|\&\&|\|\||\(|\)|,|\!|\^|=|\&|\~|<|>|\||\%|\+|\-|\/|\*|\@    | # valid non-word token
  4380. +                \b\w+\b                                                        | # valid word token
  4381. +                \S+                                                           # anything else
  4382. +                )~x', $tag_args, $match);
  4383. +
  4384. +        $tokens = $match[0];
  4385. +
  4386. +        if(empty($tokens)) {
  4387. +            $_error_msg = $elseif ? "'elseif'" : "'if'";
  4388. +            $_error_msg .= ' statement requires arguments';
  4389. +            $this->_syntax_error($_error_msg, E_USER_ERROR, __FILE__, __LINE__);
  4390. +        }
  4391. +            
  4392. +                
  4393. +        // make sure we have balanced parenthesis
  4394. +        $token_count = array_count_values($tokens);
  4395. +        if(isset($token_count['(']) && $token_count['('] != $token_count[')']) {
  4396. +            $this->_syntax_error("unbalanced parenthesis in if statement", E_USER_ERROR, __FILE__, __LINE__);
  4397. +        }
  4398. +
  4399. +        $is_arg_stack = array();
  4400. +
  4401. +        for ($i = 0; $i < count($tokens); $i++) {
  4402. +
  4403. +            $token = &$tokens[$i];
  4404. +
  4405. +            switch (strtolower($token)) {
  4406. +                case '!':
  4407. +                case '%':
  4408. +                case '!==':
  4409. +                case '==':
  4410. +                case '===':
  4411. +                case '>':
  4412. +                case '<':
  4413. +                case '!=':
  4414. +                case '<>':
  4415. +                case '<<':
  4416. +                case '>>':
  4417. +                case '<=':
  4418. +                case '>=':
  4419. +                case '&&':
  4420. +                case '||':
  4421. +                case '|':
  4422. +                case '^':
  4423. +                case '&':
  4424. +                case '~':
  4425. +                case ')':
  4426. +                case ',':
  4427. +                case '+':
  4428. +                case '-':
  4429. +                case '*':
  4430. +                case '/':
  4431. +                case '@':
  4432. +                    break;
  4433. +
  4434. +                case 'eq':
  4435. +                    $token = '==';
  4436. +                    break;
  4437. +
  4438. +                case 'ne':
  4439. +                case 'neq':
  4440. +                    $token = '!=';
  4441. +                    break;
  4442. +
  4443. +                case 'lt':
  4444. +                    $token = '<';
  4445. +                    break;
  4446. +
  4447. +                case 'le':
  4448. +                case 'lte':
  4449. +                    $token = '<=';
  4450. +                    break;
  4451. +
  4452. +                case 'gt':
  4453. +                    $token = '>';
  4454. +                    break;
  4455. +
  4456. +                case 'ge':
  4457. +                case 'gte':
  4458. +                    $token = '>=';
  4459. +                    break;
  4460. +
  4461. +                case 'and':
  4462. +                    $token = '&&';
  4463. +                    break;
  4464. +
  4465. +                case 'or':
  4466. +                    $token = '||';
  4467. +                    break;
  4468. +
  4469. +                case 'not':
  4470. +                    $token = '!';
  4471. +                    break;
  4472. +
  4473. +                case 'mod':
  4474. +                    $token = '%';
  4475. +                    break;
  4476. +
  4477. +                case '(':
  4478. +                    array_push($is_arg_stack, $i);
  4479. +                    break;
  4480. +
  4481. +                case 'is':
  4482. +                    /* If last token was a ')', we operate on the parenthesized
  4483. +                       expression. The start of the expression is on the stack.
  4484. +                       Otherwise, we operate on the last encountered token. */
  4485. +                    if ($tokens[$i-1] == ')') {
  4486. +                        $is_arg_start = array_pop($is_arg_stack);
  4487. +                        if ($is_arg_start != 0) {
  4488. +                            if (preg_match('~^' . $this->_func_regexp . '$~', $tokens[$is_arg_start-1])) {
  4489. +                                $is_arg_start--;
  4490. +                            }
  4491. +                        }
  4492. +                    } else
  4493. +                        $is_arg_start = $i-1;
  4494. +                    /* Construct the argument for 'is' expression, so it knows
  4495. +                       what to operate on. */
  4496. +                    $is_arg = implode(' ', array_slice($tokens, $is_arg_start, $i - $is_arg_start));
  4497. +
  4498. +                    /* Pass all tokens from next one until the end to the
  4499. +                       'is' expression parsing function. The function will
  4500. +                       return modified tokens, where the first one is the result
  4501. +                       of the 'is' expression and the rest are the tokens it
  4502. +                       didn't touch. */
  4503. +                    $new_tokens = $this->_parse_is_expr($is_arg, array_slice($tokens, $i+1));
  4504. +
  4505. +                    /* Replace the old tokens with the new ones. */
  4506. +                    array_splice($tokens, $is_arg_start, count($tokens), $new_tokens);
  4507. +
  4508. +                    /* Adjust argument start so that it won't change from the
  4509. +                       current position for the next iteration. */
  4510. +                    $i = $is_arg_start;
  4511. +                    break;
  4512. +
  4513. +                default:
  4514. +                    if(preg_match('~^' . $this->_func_regexp . '$~', $token) ) {
  4515. +                            // function call
  4516. +                            if($this->security &&
  4517. +                               !in_array($token, $this->security_settings['IF_FUNCS'])) {
  4518. +                                $this->_syntax_error("(secure mode) '$token' not allowed in if statement", E_USER_ERROR, __FILE__, __LINE__);
  4519. +                            }
  4520. +                    } elseif(preg_match('~^' . $this->_var_regexp . '$~', $token) && (strpos('+-*/^%&|', substr($token, -1)) === false) && isset($tokens[$i+1]) && $tokens[$i+1] == '(') {
  4521. +                        // variable function call
  4522. +                        $this->_syntax_error("variable function call '$token' not allowed in if statement", E_USER_ERROR, __FILE__, __LINE__);                      
  4523. +                    } elseif(preg_match('~^' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '(?:' . $this->_mod_regexp . '*)$~', $token)) {
  4524. +                        // object or variable
  4525. +                        $token = $this->_parse_var_props($token);
  4526. +                    } elseif(is_numeric($token)) {
  4527. +                        // number, skip it
  4528. +                    } else {
  4529. +                        $this->_syntax_error("unidentified token '$token'", E_USER_ERROR, __FILE__, __LINE__);
  4530. +                    }
  4531. +                    break;
  4532. +            }
  4533. +        }
  4534. +
  4535. +        if ($elseif)
  4536. +            return '<?php elseif ('.implode(' ', $tokens).'): ?>';
  4537. +        else
  4538. +            return '<?php if ('.implode(' ', $tokens).'): ?>';
  4539. +    }
  4540. +
  4541. +
  4542. +    function _compile_arg_list($type, $name, $attrs, &$cache_code) {
  4543. +        $arg_list = array();
  4544. +
  4545. +        if (isset($type) && isset($name)
  4546. +            && isset($this->_plugins[$type])
  4547. +            && isset($this->_plugins[$type][$name])
  4548. +            && empty($this->_plugins[$type][$name][4])
  4549. +            && is_array($this->_plugins[$type][$name][5])
  4550. +            ) {
  4551. +            /* we have a list of parameters that should be cached */
  4552. +            $_cache_attrs = $this->_plugins[$type][$name][5];
  4553. +            $_count = $this->_cache_attrs_count++;
  4554. +            $cache_code = "\$_cache_attrs =& \$this->_smarty_cache_attrs('$this->_cache_serial','$_count');";
  4555. +
  4556. +        } else {
  4557. +            /* no parameters are cached */
  4558. +            $_cache_attrs = null;
  4559. +        }
  4560. +
  4561. +        foreach ($attrs as $arg_name => $arg_value) {
  4562. +            if (is_bool($arg_value))
  4563. +                $arg_value = $arg_value ? 'true' : 'false';
  4564. +            if (is_null($arg_value))
  4565. +                $arg_value = 'null';
  4566. +            if ($_cache_attrs && in_array($arg_name, $_cache_attrs)) {
  4567. +                $arg_list[] = "'$arg_name' => (\$this->_cache_including) ? \$_cache_attrs['$arg_name'] : (\$_cache_attrs['$arg_name']=$arg_value)";
  4568. +            } else {
  4569. +                $arg_list[] = "'$arg_name' => $arg_value";
  4570. +            }
  4571. +        }
  4572. +        return $arg_list;
  4573. +    }
  4574. +
  4575. +    /**
  4576. +     * Parse is expression
  4577. +     *
  4578. +     * @param string $is_arg
  4579. +     * @param array $tokens
  4580. +     * @return array
  4581. +     */
  4582. +    function _parse_is_expr($is_arg, $tokens)
  4583. +    {
  4584. +        $expr_end = 0;
  4585. +        $negate_expr = false;
  4586. +
  4587. +        if (($first_token = array_shift($tokens)) == 'not') {
  4588. +            $negate_expr = true;
  4589. +            $expr_type = array_shift($tokens);
  4590. +        } else
  4591. +            $expr_type = $first_token;
  4592. +
  4593. +        switch ($expr_type) {
  4594. +            case 'even':
  4595. +                if (isset($tokens[$expr_end]) && $tokens[$expr_end] == 'by') {
  4596. +                    $expr_end++;
  4597. +                    $expr_arg = $tokens[$expr_end++];
  4598. +                    $expr = "!(1 & ($is_arg / " . $this->_parse_var_props($expr_arg) . "))";
  4599. +                } else
  4600. +                    $expr = "!(1 & $is_arg)";
  4601. +                break;
  4602. +
  4603. +            case 'odd':
  4604. +                if (isset($tokens[$expr_end]) && $tokens[$expr_end] == 'by') {
  4605. +                    $expr_end++;
  4606. +                    $expr_arg = $tokens[$expr_end++];
  4607. +                    $expr = "(1 & ($is_arg / " . $this->_parse_var_props($expr_arg) . "))";
  4608. +                } else
  4609. +                    $expr = "(1 & $is_arg)";
  4610. +                break;
  4611. +
  4612. +            case 'div':
  4613. +                if (@$tokens[$expr_end] == 'by') {
  4614. +                    $expr_end++;
  4615. +                    $expr_arg = $tokens[$expr_end++];
  4616. +                    $expr = "!($is_arg % " . $this->_parse_var_props($expr_arg) . ")";
  4617. +                } else {
  4618. +                    $this->_syntax_error("expecting 'by' after 'div'", E_USER_ERROR, __FILE__, __LINE__);
  4619. +                }
  4620. +                break;
  4621. +
  4622. +            default:
  4623. +                $this->_syntax_error("unknown 'is' expression - '$expr_type'", E_USER_ERROR, __FILE__, __LINE__);
  4624. +                break;
  4625. +        }
  4626. +
  4627. +        if ($negate_expr) {
  4628. +            $expr = "!($expr)";
  4629. +        }
  4630. +
  4631. +        array_splice($tokens, 0, $expr_end, $expr);
  4632. +
  4633. +        return $tokens;
  4634. +    }
  4635. +
  4636. +
  4637. +    /**
  4638. +     * Parse attribute string
  4639. +     *
  4640. +     * @param string $tag_args
  4641. +     * @return array
  4642. +     */
  4643. +    function _parse_attrs($tag_args)
  4644. +    {
  4645. +
  4646. +        /* Tokenize tag attributes. */
  4647. +        preg_match_all('~(?:' . $this->_obj_call_regexp . '|' . $this->_qstr_regexp . ' | (?>[^"\'=\s]+)
  4648. +                         )+ |
  4649. +                         [=]
  4650. +                        ~x', $tag_args, $match);
  4651. +        $tokens       = $match[0];
  4652. +
  4653. +        $attrs = array();
  4654. +        /* Parse state:
  4655. +            0 - expecting attribute name
  4656. +            1 - expecting '='
  4657. +            2 - expecting attribute value (not '=') */
  4658. +        $state = 0;
  4659. +
  4660. +        foreach ($tokens as $token) {
  4661. +            switch ($state) {
  4662. +                case 0:
  4663. +                    /* If the token is a valid identifier, we set attribute name
  4664. +                       and go to state 1. */
  4665. +                    if (preg_match('~^\w+$~', $token)) {
  4666. +                        $attr_name = $token;
  4667. +                        $state = 1;
  4668. +                    } else
  4669. +                        $this->_syntax_error("invalid attribute name: '$token'", E_USER_ERROR, __FILE__, __LINE__);
  4670. +                    break;
  4671. +
  4672. +                case 1:
  4673. +                    /* If the token is '=', then we go to state 2. */
  4674. +                    if ($token == '=') {
  4675. +                        $state = 2;
  4676. +                    } else
  4677. +                        $this->_syntax_error("expecting '=' after attribute name '$last_token'", E_USER_ERROR, __FILE__, __LINE__);
  4678. +                    break;
  4679. +
  4680. +                case 2:
  4681. +                    /* If token is not '=', we set the attribute value and go to
  4682. +                       state 0. */
  4683. +                    if ($token != '=') {
  4684. +                        /* We booleanize the token if it's a non-quoted possible
  4685. +                           boolean value. */
  4686. +                        if (preg_match('~^(on|yes|true)$~', $token)) {
  4687. +                            $token = 'true';
  4688. +                        } else if (preg_match('~^(off|no|false)$~', $token)) {
  4689. +                            $token = 'false';
  4690. +                        } else if ($token == 'null') {
  4691. +                            $token = 'null';
  4692. +                        } else if (preg_match('~^' . $this->_num_const_regexp . '|0[xX][0-9a-fA-F]+$~', $token)) {
  4693. +                            /* treat integer literally */
  4694. +                        } else if (!preg_match('~^' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '(?:' . $this->_mod_regexp . ')*$~', $token)) {
  4695. +                            /* treat as a string, double-quote it escaping quotes */
  4696. +                            $token = '"'.addslashes($token).'"';
  4697. +                        }
  4698. +
  4699. +                        $attrs[$attr_name] = $token;
  4700. +                        $state = 0;
  4701. +                    } else
  4702. +                        $this->_syntax_error("'=' cannot be an attribute value", E_USER_ERROR, __FILE__, __LINE__);
  4703. +                    break;
  4704. +            }
  4705. +            $last_token = $token;
  4706. +        }
  4707. +
  4708. +        if($state != 0) {
  4709. +            if($state == 1) {
  4710. +                $this->_syntax_error("expecting '=' after attribute name '$last_token'", E_USER_ERROR, __FILE__, __LINE__);
  4711. +            } else {
  4712. +                $this->_syntax_error("missing attribute value", E_USER_ERROR, __FILE__, __LINE__);
  4713. +            }
  4714. +        }
  4715. +
  4716. +        $this->_parse_vars_props($attrs);
  4717. +
  4718. +        return $attrs;
  4719. +    }
  4720. +
  4721. +    /**
  4722. +     * compile multiple variables and section properties tokens into
  4723. +     * PHP code
  4724. +     *
  4725. +     * @param array $tokens
  4726. +     */
  4727. +    function _parse_vars_props(&$tokens)
  4728. +    {
  4729. +        foreach($tokens as $key => $val) {
  4730. +            $tokens[$key] = $this->_parse_var_props($val);
  4731. +        }
  4732. +    }
  4733. +
  4734. +    /**
  4735. +     * compile single variable and section properties token into
  4736. +     * PHP code
  4737. +     *
  4738. +     * @param string $val
  4739. +     * @param string $tag_attrs
  4740. +     * @return string
  4741. +     */
  4742. +    function _parse_var_props($val)
  4743. +    {
  4744. +        $val = trim($val);
  4745. +
  4746. +        if(preg_match('~^(' . $this->_obj_call_regexp . '|' . $this->_dvar_regexp . ')(' . $this->_mod_regexp . '*)$~', $val, $match)) {
  4747. +            // $ variable or object
  4748. +            $return = $this->_parse_var($match[1]);
  4749. +            $modifiers = $match[2];
  4750. +            if (!empty($this->default_modifiers) && !preg_match('~(^|\|)smarty:nodefaults($|\|)~',$modifiers)) {
  4751. +                $_default_mod_string = implode('|',(array)$this->default_modifiers);
  4752. +                $modifiers = empty($modifiers) ? $_default_mod_string : $_default_mod_string . '|' . $modifiers;
  4753. +            }
  4754. +            $this->_parse_modifiers($return, $modifiers);
  4755. +            return $return;
  4756. +        } elseif (preg_match('~^' . $this->_db_qstr_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) {
  4757. +                // double quoted text
  4758. +                preg_match('~^(' . $this->_db_qstr_regexp . ')('. $this->_mod_regexp . '*)$~', $val, $match);
  4759. +                $return = $this->_expand_quoted_text($match[1]);
  4760. +                if($match[2] != '') {
  4761. +                    $this->_parse_modifiers($return, $match[2]);
  4762. +                }
  4763. +                return $return;
  4764. +            }
  4765. +        elseif(preg_match('~^' . $this->_num_const_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) {
  4766. +                // numerical constant
  4767. +                preg_match('~^(' . $this->_num_const_regexp . ')('. $this->_mod_regexp . '*)$~', $val, $match);
  4768. +                if($match[2] != '') {
  4769. +                    $this->_parse_modifiers($match[1], $match[2]);
  4770. +                    return $match[1];
  4771. +                }
  4772. +            }
  4773. +        elseif(preg_match('~^' . $this->_si_qstr_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) {
  4774. +                // single quoted text
  4775. +                preg_match('~^(' . $this->_si_qstr_regexp . ')('. $this->_mod_regexp . '*)$~', $val, $match);
  4776. +                if($match[2] != '') {
  4777. +                    $this->_parse_modifiers($match[1], $match[2]);
  4778. +                    return $match[1];
  4779. +                }
  4780. +            }
  4781. +        elseif(preg_match('~^' . $this->_cvar_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) {
  4782. +                // config var
  4783. +                return $this->_parse_conf_var($val);
  4784. +            }
  4785. +        elseif(preg_match('~^' . $this->_svar_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) {
  4786. +                // section var
  4787. +                return $this->_parse_section_prop($val);
  4788. +            }
  4789. +        elseif(!in_array($val, $this->_permitted_tokens) && !is_numeric($val)) {
  4790. +            // literal string
  4791. +            return $this->_expand_quoted_text('"' . strtr($val, array('\\' => '\\\\', '"' => '\\"')) .'"');
  4792. +        }
  4793. +        return $val;
  4794. +    }
  4795. +
  4796. +    /**
  4797. +     * expand quoted text with embedded variables
  4798. +     *
  4799. +     * @param string $var_expr
  4800. +     * @return string
  4801. +     */
  4802. +    function _expand_quoted_text($var_expr)
  4803. +    {
  4804. +        // if contains unescaped $, expand it
  4805. +        if(preg_match_all('~(?:\`(?<!\\\\)\$' . $this->_dvar_guts_regexp . '(?:' . $this->_obj_ext_regexp . ')*\`)|(?:(?<!\\\\)\$\w+(\[[a-zA-Z0-9]+\])*)~', $var_expr, $_match)) {
  4806. +            $_match = $_match[0];
  4807. +            $_replace = array();
  4808. +            foreach($_match as $_var) {
  4809. +                $_replace[$_var] = '".(' . $this->_parse_var(str_replace('`','',$_var)) . ')."';
  4810. +            }
  4811. +            $var_expr = strtr($var_expr, $_replace);
  4812. +            $_return = preg_replace('~\.""|(?<!\\\\)""\.~', '', $var_expr);
  4813. +        } else {
  4814. +            $_return = $var_expr;
  4815. +        }
  4816. +        // replace double quoted literal string with single quotes
  4817. +        $_return = preg_replace('~^"([\s\w]+)"$~',"'\'",$_return);
  4818. +        return $_return;
  4819. +    }
  4820. +
  4821. +    /**
  4822. +     * parse variable expression into PHP code
  4823. +     *
  4824. +     * @param string $var_expr
  4825. +     * @param string $output
  4826. +     * @return string
  4827. +     */
  4828. +    function _parse_var($var_expr)
  4829. +    {
  4830. +        $_has_math = false;
  4831. +        $_math_vars = preg_split('~('.$this->_dvar_math_regexp.'|'.$this->_qstr_regexp.')~', $var_expr, -1, PREG_SPLIT_DELIM_CAPTURE);
  4832. +
  4833. +        if(count($_math_vars) > 1) {
  4834. +            $_first_var = "";
  4835. +            $_complete_var = "";
  4836. +            $_output = "";
  4837. +            // simple check if there is any math, to stop recursion (due to modifiers with "xx % yy" as parameter)
  4838. +            foreach($_math_vars as $_k => $_math_var) {
  4839. +                $_math_var = $_math_vars[$_k];
  4840. +
  4841. +                if(!empty($_math_var) || is_numeric($_math_var)) {
  4842. +                    // hit a math operator, so process the stuff which came before it
  4843. +                    if(preg_match('~^' . $this->_dvar_math_regexp . '$~', $_math_var)) {
  4844. +                        $_has_math = true;
  4845. +                        if(!empty($_complete_var) || is_numeric($_complete_var)) {
  4846. +                            $_output .= $this->_parse_var($_complete_var);
  4847. +                        }
  4848. +
  4849. +                        // just output the math operator to php
  4850. +                        $_output .= $_math_var;
  4851. +
  4852. +                        if(empty($_first_var))
  4853. +                            $_first_var = $_complete_var;
  4854. +
  4855. +                        $_complete_var = "";
  4856. +                    } else {
  4857. +                        $_complete_var .= $_math_var;
  4858. +                    }
  4859. +                }
  4860. +            }
  4861. +            if($_has_math) {
  4862. +                if(!empty($_complete_var) || is_numeric($_complete_var))
  4863. +                    $_output .= $this->_parse_var($_complete_var);
  4864. +
  4865. +                // get the modifiers working (only the last var from math + modifier is left)
  4866. +                $var_expr = $_complete_var;
  4867. +            }
  4868. +        }
  4869. +
  4870. +        // prevent cutting of first digit in the number (we _definitly_ got a number if the first char is a digit)
  4871. +        if(is_numeric(substr($var_expr, 0, 1)))
  4872. +            $_var_ref = $var_expr;
  4873. +        else
  4874. +            $_var_ref = substr($var_expr, 1);
  4875. +        
  4876. +        if(!$_has_math) {
  4877. +            
  4878. +            // get [foo] and .foo and ->foo and (...) pieces
  4879. +            preg_match_all('~(?:^\w+)|' . $this->_obj_params_regexp . '|(?:' . $this->_var_bracket_regexp . ')|->\$?\w+|\.\$?\w+|\S+~', $_var_ref, $match);
  4880. +                        
  4881. +            $_indexes = $match[0];
  4882. +            $_var_name = array_shift($_indexes);
  4883. +
  4884. +            /* Handle $smarty.* variable references as a special case. */
  4885. +            if ($_var_name == 'smarty') {
  4886. +                /*
  4887. +                 * If the reference could be compiled, use the compiled output;
  4888. +                 * otherwise, fall back on the $smarty variable generated at
  4889. +                 * run-time.
  4890. +                 */
  4891. +                if (($smarty_ref = $this->_compile_smarty_ref($_indexes)) !== null) {
  4892. +                    $_output = $smarty_ref;
  4893. +                } else {
  4894. +                    $_var_name = substr(array_shift($_indexes), 1);
  4895. +                    $_output = "\$this->_smarty_vars['$_var_name']";
  4896. +                }
  4897. +            } elseif(is_numeric($_var_name) && is_numeric(substr($var_expr, 0, 1))) {
  4898. +                // because . is the operator for accessing arrays thru inidizes we need to put it together again for floating point numbers
  4899. +                if(count($_indexes) > 0)
  4900. +                {
  4901. +                    $_var_name .= implode("", $_indexes);
  4902. +                    $_indexes = array();
  4903. +                }
  4904. +                $_output = $_var_name;
  4905. +            } else {
  4906. +                $_output = "\$this->_tpl_vars['$_var_name']";
  4907. +            }
  4908. +
  4909. +            foreach ($_indexes as $_index) {
  4910. +                if (substr($_index, 0, 1) == '[') {
  4911. +                    $_index = substr($_index, 1, -1);
  4912. +                    if (is_numeric($_index)) {
  4913. +                        $_output .= "[$_index]";
  4914. +                    } elseif (substr($_index, 0, 1) == '$') {
  4915. +                        if (strpos($_index, '.') !== false) {
  4916. +                            $_output .= '[' . $this->_parse_var($_index) . ']';
  4917. +                        } else {
  4918. +                            $_output .= "[\$this->_tpl_vars['" . substr($_index, 1) . "']]";
  4919. +                        }
  4920. +                    } else {
  4921. +                        $_var_parts = explode('.', $_index);
  4922. +                        $_var_section = $_var_parts[0];
  4923. +                        $_var_section_prop = isset($_var_parts[1]) ? $_var_parts[1] : 'index';
  4924. +                        $_output .= "[\$this->_sections['$_var_section']['$_var_section_prop']]";
  4925. +                    }
  4926. +                } else if (substr($_index, 0, 1) == '.') {
  4927. +                    if (substr($_index, 1, 1) == '$')
  4928. +                        $_output .= "[\$this->_tpl_vars['" . substr($_index, 2) . "']]";
  4929. +                    else
  4930. +                        $_output .= "['" . substr($_index, 1) . "']";
  4931. +                } else if (substr($_index,0,2) == '->') {
  4932. +                    if(substr($_index,2,2) == '__') {
  4933. +                        $this->_syntax_error('call to internal object members is not allowed', E_USER_ERROR, __FILE__, __LINE__);
  4934. +                    } elseif($this->security && substr($_index, 2, 1) == '_') {
  4935. +                        $this->_syntax_error('(secure) call to private object member is not allowed', E_USER_ERROR, __FILE__, __LINE__);
  4936. +                    } elseif (substr($_index, 2, 1) == '$') {
  4937. +                        if ($this->security) {
  4938. +                            $this->_syntax_error('(secure) call to dynamic object member is not allowed', E_USER_ERROR, __FILE__, __LINE__);
  4939. +                        } else {
  4940. +                            $_output .= '->{(($_var=$this->_tpl_vars[\''.substr($_index,3).'\']) && substr($_var,0,2)!=\'__\') ? $_var : $this->trigger_error("cannot access property \\"$_var\\"")}';
  4941. +                        }
  4942. +                    } else {
  4943. +                        $_output .= $_index;
  4944. +                    }
  4945. +                } elseif (substr($_index, 0, 1) == '(') {
  4946. +                    $_index = $this->_parse_parenth_args($_index);
  4947. +                    $_output .= $_index;
  4948. +                } else {
  4949. +                    $_output .= $_index;
  4950. +                }
  4951. +            }
  4952. +        }
  4953. +
  4954. +        return $_output;
  4955. +    }
  4956. +
  4957. +    /**
  4958. +     * parse arguments in function call parenthesis
  4959. +     *
  4960. +     * @param string $parenth_args
  4961. +     * @return string
  4962. +     */
  4963. +    function _parse_parenth_args($parenth_args)
  4964. +    {
  4965. +        preg_match_all('~' . $this->_param_regexp . '~',$parenth_args, $match);
  4966. +        $orig_vals = $match = $match[0];
  4967. +        $this->_parse_vars_props($match);
  4968. +        $replace = array();
  4969. +        for ($i = 0, $count = count($match); $i < $count; $i++) {
  4970. +            $replace[$orig_vals[$i]] = $match[$i];
  4971. +        }
  4972. +        return strtr($parenth_args, $replace);
  4973. +    }
  4974. +
  4975. +    /**
  4976. +     * parse configuration variable expression into PHP code
  4977. +     *
  4978. +     * @param string $conf_var_expr
  4979. +     */
  4980. +    function _parse_conf_var($conf_var_expr)
  4981. +    {
  4982. +        $parts = explode('|', $conf_var_expr, 2);
  4983. +        $var_ref = $parts[0];
  4984. +        $modifiers = isset($parts[1]) ? $parts[1] : '';
  4985. +
  4986. +        $var_name = substr($var_ref, 1, -1);
  4987. +
  4988. +        $output = "\$this->_config[0]['vars']['$var_name']";
  4989. +
  4990. +        $this->_parse_modifiers($output, $modifiers);
  4991. +
  4992. +        return $output;
  4993. +    }
  4994. +
  4995. +    /**
  4996. +     * parse section property expression into PHP code
  4997. +     *
  4998. +     * @param string $section_prop_expr
  4999. +     * @return string
  5000. +     */
  5001. +    function _parse_section_prop($section_prop_expr)
  5002. +    {
  5003. +        $parts = explode('|', $section_prop_expr, 2);
  5004. +        $var_ref = $parts[0];
  5005. +        $modifiers = isset($parts[1]) ? $parts[1] : '';
  5006. +
  5007. +        preg_match('!%(\w+)\.(\w+)%!', $var_ref, $match);
  5008. +        $section_name = $match[1];
  5009. +        $prop_name = $match[2];
  5010. +
  5011. +        $output = "\$this->_sections['$section_name']['$prop_name']";
  5012. +
  5013. +        $this->_parse_modifiers($output, $modifiers);
  5014. +
  5015. +        return $output;
  5016. +    }
  5017. +
  5018. +
  5019. +    /**
  5020. +     * parse modifier chain into PHP code
  5021. +     *
  5022. +     * sets $output to parsed modified chain
  5023. +     * @param string $output
  5024. +     * @param string $modifier_string
  5025. +     */
  5026. +    function _parse_modifiers(&$output, $modifier_string)
  5027. +    {
  5028. +        preg_match_all('~\|(@?\w+)((?>:(?:'. $this->_qstr_regexp . '|[^|]+))*)~', '|' . $modifier_string, $_match);
  5029. +        list(, $_modifiers, $modifier_arg_strings) = $_match;
  5030. +
  5031. +        for ($_i = 0, $_for_max = count($_modifiers); $_i < $_for_max; $_i++) {
  5032. +            $_modifier_name = $_modifiers[$_i];
  5033. +
  5034. +            if($_modifier_name == 'smarty') {
  5035. +                // skip smarty modifier
  5036. +                continue;
  5037. +            }
  5038. +
  5039. +            preg_match_all('~:(' . $this->_qstr_regexp . '|[^:]+)~', $modifier_arg_strings[$_i], $_match);
  5040. +            $_modifier_args = $_match[1];
  5041. +
  5042. +            if (substr($_modifier_name, 0, 1) == '@') {
  5043. +                $_map_array = false;
  5044. +                $_modifier_name = substr($_modifier_name, 1);
  5045. +            } else {
  5046. +                $_map_array = true;
  5047. +            }
  5048. +
  5049. +            if (empty($this->_plugins['modifier'][$_modifier_name])
  5050. +                && !$this->_get_plugin_filepath('modifier', $_modifier_name)
  5051. +                && function_exists($_modifier_name)) {
  5052. +                if ($this->security && !in_array($_modifier_name, $this->security_settings['MODIFIER_FUNCS'])) {
  5053. +                    $this->_trigger_fatal_error("[plugin] (secure mode) modifier '$_modifier_name' is not allowed" , $this->_current_file, $this->_current_line_no, __FILE__, __LINE__);
  5054. +                } else {
  5055. +                    $this->_plugins['modifier'][$_modifier_name] = array($_modifier_name,  null, null, false);
  5056. +                }
  5057. +            }
  5058. +            $this->_add_plugin('modifier', $_modifier_name);
  5059. +
  5060. +            $this->_parse_vars_props($_modifier_args);
  5061. +
  5062. +            if($_modifier_name == 'default') {
  5063. +                // supress notifications of default modifier vars and args
  5064. +                if(substr($output, 0, 1) == '$') {
  5065. +                    $output = '@' . $output;
  5066. +                }
  5067. +                if(isset($_modifier_args[0]) && substr($_modifier_args[0], 0, 1) == '$') {
  5068. +                    $_modifier_args[0] = '@' . $_modifier_args[0];
  5069. +                }
  5070. +            }
  5071. +            if (count($_modifier_args) > 0)
  5072. +                $_modifier_args = ', '.implode(', ', $_modifier_args);
  5073. +            else
  5074. +                $_modifier_args = '';
  5075. +
  5076. +            if ($_map_array) {
  5077. +                $output = "((is_array(\$_tmp=$output)) ? \$this->_run_mod_handler('$_modifier_name', true, \$_tmp$_modifier_args) : " . $this->_compile_plugin_call('modifier', $_modifier_name) . "(\$_tmp$_modifier_args))";
  5078. +
  5079. +            } else {
  5080. +
  5081. +                $output = $this->_compile_plugin_call('modifier', $_modifier_name)."($output$_modifier_args)";
  5082. +
  5083. +            }
  5084. +        }
  5085. +    }
  5086. +
  5087. +
  5088. +    /**
  5089. +     * add plugin
  5090. +     *
  5091. +     * @param string $type
  5092. +     * @param string $name
  5093. +     * @param boolean? $delayed_loading
  5094. +     */
  5095. +    function _add_plugin($type, $name, $delayed_loading = null)
  5096. +    {
  5097. +        if (!isset($this->_plugin_info[$type])) {
  5098. +            $this->_plugin_info[$type] = array();
  5099. +        }
  5100. +        if (!isset($this->_plugin_info[$type][$name])) {
  5101. +            $this->_plugin_info[$type][$name] = array($this->_current_file,
  5102. +                                                      $this->_current_line_no,
  5103. +                                                      $delayed_loading);
  5104. +        }
  5105. +    }
  5106. +
  5107. +
  5108. +    /**
  5109. +     * Compiles references of type $smarty.foo
  5110. +     *
  5111. +     * @param string $indexes
  5112. +     * @return string
  5113. +     */
  5114. +    function _compile_smarty_ref(&$indexes)
  5115. +    {
  5116. +        /* Extract the reference name. */
  5117. +        $_ref = substr($indexes[0], 1);
  5118. +        foreach($indexes as $_index_no=>$_index) {
  5119. +            if (substr($_index, 0, 1) != '.' && $_index_no<2 || !preg_match('~^(\.|\[|->)~', $_index)) {
  5120. +                $this->_syntax_error('$smarty' . implode('', array_slice($indexes, 0, 2)) . ' is an invalid reference', E_USER_ERROR, __FILE__, __LINE__);
  5121. +            }
  5122. +        }
  5123. +
  5124. +        switch ($_ref) {
  5125. +            case 'now':
  5126. +                $compiled_ref = 'time()';
  5127. +                $_max_index = 1;
  5128. +                break;
  5129. +
  5130. +            case 'foreach':
  5131. +                array_shift($indexes);
  5132. +                $_var = $this->_parse_var_props(substr($indexes[0], 1));
  5133. +                $_propname = substr($indexes[1], 1);
  5134. +                $_max_index = 1;
  5135. +                switch ($_propname) {
  5136. +                    case 'index':
  5137. +                        array_shift($indexes);
  5138. +                        $compiled_ref = "(\$this->_foreach[$_var]['iteration']-1)";
  5139. +                        break;
  5140. +                        
  5141. +                    case 'first':
  5142. +                        array_shift($indexes);
  5143. +                        $compiled_ref = "(\$this->_foreach[$_var]['iteration'] <= 1)";
  5144. +                        break;
  5145. +
  5146. +                    case 'last':
  5147. +                        array_shift($indexes);
  5148. +                        $compiled_ref = "(\$this->_foreach[$_var]['iteration'] == \$this->_foreach[$_var]['total'])";
  5149. +                        break;
  5150. +                        
  5151. +                    case 'show':
  5152. +                        array_shift($indexes);
  5153. +                        $compiled_ref = "(\$this->_foreach[$_var]['total'] > 0)";
  5154. +                        break;
  5155. +                        
  5156. +                    default:
  5157. +                        unset($_max_index);
  5158. +                        $compiled_ref = "\$this->_foreach[$_var]";
  5159. +                }
  5160. +                break;
  5161. +
  5162. +            case 'section':
  5163. +                array_shift($indexes);
  5164. +                $_var = $this->_parse_var_props(substr($indexes[0], 1));
  5165. +                $compiled_ref = "\$this->_sections[$_var]";
  5166. +                break;
  5167. +
  5168. +            case 'get':
  5169. +                if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) {
  5170. +                    $this->_syntax_error("(secure mode) super global access not permitted",
  5171. +                                         E_USER_WARNING, __FILE__, __LINE__);
  5172. +                    return;
  5173. +                }
  5174. +                $compiled_ref = "\$_GET";
  5175. +                break;
  5176. +
  5177. +            case 'post':
  5178. +                if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) {
  5179. +                    $this->_syntax_error("(secure mode) super global access not permitted",
  5180. +                                         E_USER_WARNING, __FILE__, __LINE__);
  5181. +                    return;
  5182. +                }
  5183. +                $compiled_ref = "\$_POST";
  5184. +                break;
  5185. +
  5186. +            case 'cookies':
  5187. +                if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) {
  5188. +                    $this->_syntax_error("(secure mode) super global access not permitted",
  5189. +                                         E_USER_WARNING, __FILE__, __LINE__);
  5190. +                    return;
  5191. +                }
  5192. +                $compiled_ref = "\$_COOKIE";
  5193. +                break;
  5194. +
  5195. +            case 'env':
  5196. +                if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) {
  5197. +                    $this->_syntax_error("(secure mode) super global access not permitted",
  5198. +                                         E_USER_WARNING, __FILE__, __LINE__);
  5199. +                    return;
  5200. +                }
  5201. +                $compiled_ref = "\$_ENV";
  5202. +                break;
  5203. +
  5204. +            case 'server':
  5205. +                if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) {
  5206. +                    $this->_syntax_error("(secure mode) super global access not permitted",
  5207. +                                         E_USER_WARNING, __FILE__, __LINE__);
  5208. +                    return;
  5209. +                }
  5210. +                $compiled_ref = "\$_SERVER";
  5211. +                break;
  5212. +
  5213. +            case 'session':
  5214. +                if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) {
  5215. +                    $this->_syntax_error("(secure mode) super global access not permitted",
  5216. +                                         E_USER_WARNING, __FILE__, __LINE__);
  5217. +                    return;
  5218. +                }
  5219. +                $compiled_ref = "\$_SESSION";
  5220. +                break;
  5221. +
  5222. +            /*
  5223. +             * These cases are handled either at run-time or elsewhere in the
  5224. +             * compiler.
  5225. +             */
  5226. +            case 'request':
  5227. +                if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) {
  5228. +                    $this->_syntax_error("(secure mode) super global access not permitted",
  5229. +                                         E_USER_WARNING, __FILE__, __LINE__);
  5230. +                    return;
  5231. +                }
  5232. +                if ($this->request_use_auto_globals) {
  5233. +                    $compiled_ref = "\$_REQUEST";
  5234. +                    break;
  5235. +                } else {
  5236. +                    $this->_init_smarty_vars = true;
  5237. +                }
  5238. +                return null;
  5239. +
  5240. +            case 'capture':
  5241. +                return null;
  5242. +
  5243. +            case 'template':
  5244. +                $compiled_ref = "'$this->_current_file'";
  5245. +                $_max_index = 1;
  5246. +                break;
  5247. +
  5248. +            case 'version':
  5249. +                $compiled_ref = "'$this->_version'";
  5250. +                $_max_index = 1;
  5251. +                break;
  5252. +
  5253. +            case 'const':
  5254. +                if ($this->security && !$this->security_settings['ALLOW_CONSTANTS']) {
  5255. +                    $this->_syntax_error("(secure mode) constants not permitted",
  5256. +                                         E_USER_WARNING, __FILE__, __LINE__);
  5257. +                    return;
  5258. +                }
  5259. +                array_shift($indexes);
  5260. +                if (preg_match('!^\.\w+$!', $indexes[0])) {
  5261. +                    $compiled_ref = '@' . substr($indexes[0], 1);
  5262. +                } else {
  5263. +                    $_val = $this->_parse_var_props(substr($indexes[0], 1));
  5264. +                    $compiled_ref = '@constant(' . $_val . ')';
  5265. +                }
  5266. +                $_max_index = 1;
  5267. +                break;
  5268. +
  5269. +            case 'config':
  5270. +                $compiled_ref = "\$this->_config[0]['vars']";
  5271. +                $_max_index = 3;
  5272. +                break;
  5273. +
  5274. +            case 'ldelim':
  5275. +                $compiled_ref = "'$this->left_delimiter'";
  5276. +                break;
  5277. +
  5278. +            case 'rdelim':
  5279. +                $compiled_ref = "'$this->right_delimiter'";
  5280. +                break;
  5281. +                
  5282. +            default:
  5283. +                $this->_syntax_error('$smarty.' . $_ref . ' is an unknown reference', E_USER_ERROR, __FILE__, __LINE__);
  5284. +                break;
  5285. +        }
  5286. +
  5287. +        if (isset($_max_index) && count($indexes) > $_max_index) {
  5288. +            $this->_syntax_error('$smarty' . implode('', $indexes) .' is an invalid reference', E_USER_ERROR, __FILE__, __LINE__);
  5289. +        }
  5290. +
  5291. +        array_shift($indexes);
  5292. +        return $compiled_ref;
  5293. +    }
  5294. +
  5295. +    /**
  5296. +     * compiles call to plugin of type $type with name $name
  5297. +     * returns a string containing the function-name or method call
  5298. +     * without the paramter-list that would have follow to make the
  5299. +     * call valid php-syntax
  5300. +     *
  5301. +     * @param string $type
  5302. +     * @param string $name
  5303. +     * @return string
  5304. +     */
  5305. +    function _compile_plugin_call($type, $name) {
  5306. +        if (isset($this->_plugins[$type][$name])) {
  5307. +            /* plugin loaded */
  5308. +            if (is_array($this->_plugins[$type][$name][0])) {
  5309. +                return ((is_object($this->_plugins[$type][$name][0][0])) ?
  5310. +                        "\$this->_plugins['$type']['$name'][0][0]->"    /* method callback */
  5311. +                        : (string)($this->_plugins[$type][$name][0][0]).'::'    /* class callback */
  5312. +                       ). $this->_plugins[$type][$name][0][1];
  5313. +
  5314. +            } else {
  5315. +                /* function callback */
  5316. +                return $this->_plugins[$type][$name][0];
  5317. +
  5318. +            }
  5319. +        } else {
  5320. +            /* plugin not loaded -> auto-loadable-plugin */
  5321. +            return 'smarty_'.$type.'_'.$name;
  5322. +
  5323. +        }
  5324. +    }
  5325. +
  5326. +    /**
  5327. +     * load pre- and post-filters
  5328. +     */
  5329. +    function _load_filters()
  5330. +    {
  5331. +        if (count($this->_plugins['prefilter']) > 0) {
  5332. +            foreach ($this->_plugins['prefilter'] as $filter_name => $prefilter) {
  5333. +                if ($prefilter === false) {
  5334. +                    unset($this->_plugins['prefilter'][$filter_name]);
  5335. +                    $_params = array('plugins' => array(array('prefilter', $filter_name, null, null, false)));
  5336. +                    require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');
  5337. +                    smarty_core_load_plugins($_params, $this);
  5338. +                }
  5339. +            }
  5340. +        }
  5341. +        if (count($this->_plugins['postfilter']) > 0) {
  5342. +            foreach ($this->_plugins['postfilter'] as $filter_name => $postfilter) {
  5343. +                if ($postfilter === false) {
  5344. +                    unset($this->_plugins['postfilter'][$filter_name]);
  5345. +                    $_params = array('plugins' => array(array('postfilter', $filter_name, null, null, false)));
  5346. +                    require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');
  5347. +                    smarty_core_load_plugins($_params, $this);
  5348. +                }
  5349. +            }
  5350. +        }
  5351. +    }
  5352. +
  5353. +
  5354. +    /**
  5355. +     * Quote subpattern references
  5356. +     *
  5357. +     * @param string $string
  5358. +     * @return string
  5359. +     */
  5360. +    function _quote_replace($string)
  5361. +    {
  5362. +        return strtr($string, array('\\' => '\\\\', '$' => '\\$'));
  5363. +    }
  5364. +
  5365. +    /**
  5366. +     * display Smarty syntax error
  5367. +     *
  5368. +     * @param string $error_msg
  5369. +     * @param integer $error_type
  5370. +     * @param string $file
  5371. +     * @param integer $line
  5372. +     */
  5373. +    function _syntax_error($error_msg, $error_type = E_USER_ERROR, $file=null, $line=null)
  5374. +    {
  5375. +        $this->_trigger_fatal_error("syntax error: $error_msg", $this->_current_file, $this->_current_line_no, $file, $line, $error_type);
  5376. +    }
  5377. +
  5378. +
  5379. +    /**
  5380. +     * check if the compilation changes from cacheable to
  5381. +     * non-cacheable state with the beginning of the current
  5382. +     * plugin. return php-code to reflect the transition.
  5383. +     * @return string
  5384. +     */
  5385. +    function _push_cacheable_state($type, $name) {
  5386. +        $_cacheable = !isset($this->_plugins[$type][$name]) || $this->_plugins[$type][$name][4];
  5387. +        if ($_cacheable
  5388. +            || 0<$this->_cacheable_state++) return '';
  5389. +        if (!isset($this->_cache_serial)) $this->_cache_serial = md5(uniqid('Smarty'));
  5390. +        $_ret = 'if ($this->caching && !$this->_cache_including): echo \'{nocache:'
  5391. +            . $this->_cache_serial . '#' . $this->_nocache_count
  5392. +            . '}\'; endif;';
  5393. +        return $_ret;
  5394. +    }
  5395. +
  5396. +
  5397. +    /**
  5398. +     * check if the compilation changes from non-cacheable to
  5399. +     * cacheable state with the end of the current plugin return
  5400. +     * php-code to reflect the transition.
  5401. +     * @return string
  5402. +     */
  5403. +    function _pop_cacheable_state($type, $name) {
  5404. +        $_cacheable = !isset($this->_plugins[$type][$name]) || $this->_plugins[$type][$name][4];
  5405. +        if ($_cacheable
  5406. +            || --$this->_cacheable_state>0) return '';
  5407. +        return 'if ($this->caching && !$this->_cache_including): echo \'{/nocache:'
  5408. +            . $this->_cache_serial . '#' . ($this->_nocache_count++)
  5409. +            . '}\'; endif;';
  5410. +    }
  5411. +
  5412. +
  5413. +    /**
  5414. +     * push opening tag-name, file-name and line-number on the tag-stack
  5415. +     * @param string the opening tag's name
  5416. +     */
  5417. +    function _push_tag($open_tag)
  5418. +    {
  5419. +        array_push($this->_tag_stack, array($open_tag, $this->_current_line_no));
  5420. +    }
  5421. +
  5422. +    /**
  5423. +     * pop closing tag-name
  5424. +     * raise an error if this stack-top doesn't match with the closing tag
  5425. +     * @param string the closing tag's name
  5426. +     * @return string the opening tag's name
  5427. +     */
  5428. +    function _pop_tag($close_tag)
  5429. +    {
  5430. +        $message = '';
  5431. +        if (count($this->_tag_stack)>0) {
  5432. +            list($_open_tag, $_line_no) = array_pop($this->_tag_stack);
  5433. +            if ($close_tag == $_open_tag) {
  5434. +                return $_open_tag;
  5435. +            }
  5436. +            if ($close_tag == 'if' && ($_open_tag == 'else' || $_open_tag == 'elseif' )) {
  5437. +                return $this->_pop_tag($close_tag);
  5438. +            }
  5439. +            if ($close_tag == 'section' && $_open_tag == 'sectionelse') {
  5440. +                $this->_pop_tag($close_tag);
  5441. +                return $_open_tag;
  5442. +            }
  5443. +            if ($close_tag == 'foreach' && $_open_tag == 'foreachelse') {
  5444. +                $this->_pop_tag($close_tag);
  5445. +                return $_open_tag;
  5446. +            }
  5447. +            if ($_open_tag == 'else' || $_open_tag == 'elseif') {
  5448. +                $_open_tag = 'if';
  5449. +            } elseif ($_open_tag == 'sectionelse') {
  5450. +                $_open_tag = 'section';
  5451. +            } elseif ($_open_tag == 'foreachelse') {
  5452. +                $_open_tag = 'foreach';
  5453. +            }
  5454. +            $message = " expected {/$_open_tag} (opened line $_line_no).";
  5455. +        }
  5456. +        $this->_syntax_error("mismatched tag {/$close_tag}.$message",
  5457. +                             E_USER_ERROR, __FILE__, __LINE__);
  5458. +    }
  5459. +
  5460. +}
  5461. +
  5462. +/**
  5463. + * compare to values by their string length
  5464. + *
  5465. + * @access private
  5466. + * @param string $a
  5467. + * @param string $b
  5468. + * @return 0|-1|1
  5469. + */
  5470. +function _smarty_sort_length($a, $b)
  5471. +{
  5472. +    if($a == $b)
  5473. +        return 0;
  5474. +
  5475. +    if(strlen($a) == strlen($b))
  5476. +        return ($a > $b) ? -1 : 1;
  5477. +
  5478. +    return (strlen($a) > strlen($b)) ? -1 : 1;
  5479. +}
  5480. +
  5481. +
  5482. +/* vim: set et: */
  5483. +
  5484. +?>
  5485. diff --git a/library/smarty/debug.tpl b/library/smarty/debug.tpl
  5486. new file mode 100644
  5487. --- /dev/null
  5488. +++ b/library/smarty/debug.tpl
  5489. @@ -0,0 +1,157 @@
  5490. +{* Smarty *}
  5491. +{* debug.tpl, last updated version 2.1.0 *}
  5492. +{assign_debug_info}
  5493. +{capture assign=debug_output}
  5494. +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
  5495. +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
  5496. +<head>
  5497. +    <title>Smarty Debug Console</title>
  5498. +{literal}
  5499. +<style type="text/css">
  5500. +/* <![CDATA[ */
  5501. +body, h1, h2, td, th, p {
  5502. +    font-family: sans-serif;
  5503. +    font-weight: normal;
  5504. +    font-size: 0.9em;
  5505. +    margin: 1px;
  5506. +    padding: 0;
  5507. +}
  5508. +
  5509. +h1 {
  5510. +    margin: 0;
  5511. +    text-align: left;
  5512. +    padding: 2px;
  5513. +    background-color: #f0c040;
  5514. +    color:  black;
  5515. +    font-weight: bold;
  5516. +    font-size: 1.2em;
  5517. + }
  5518. +
  5519. +h2 {
  5520. +    background-color: #9B410E;
  5521. +    color: white;
  5522. +    text-align: left;
  5523. +    font-weight: bold;
  5524. +    padding: 2px;
  5525. +    border-top: 1px solid black;
  5526. +}
  5527. +
  5528. +body {
  5529. +    background: black;
  5530. +}
  5531. +
  5532. +p, table, div {
  5533. +    background: #f0ead8;
  5534. +}
  5535. +
  5536. +p {
  5537. +    margin: 0;
  5538. +    font-style: italic;
  5539. +    text-align: center;
  5540. +}
  5541. +
  5542. +table {
  5543. +    width: 100%;
  5544. +}
  5545. +
  5546. +th, td {
  5547. +    font-family: monospace;
  5548. +    vertical-align: top;
  5549. +    text-align: left;
  5550. +    width: 50%;
  5551. +}
  5552. +
  5553. +td {
  5554. +    color: green;
  5555. +}
  5556. +
  5557. +.odd {
  5558. +    background-color: #eeeeee;
  5559. +}
  5560. +
  5561. +.even {
  5562. +    background-color: #fafafa;
  5563. +}
  5564. +
  5565. +.exectime {
  5566. +    font-size: 0.8em;
  5567. +    font-style: italic;
  5568. +}
  5569. +
  5570. +#table_assigned_vars th {
  5571. +    color: blue;
  5572. +}
  5573. +
  5574. +#table_config_vars th {
  5575. +    color: maroon;
  5576. +}
  5577. +/* ]]> */
  5578. +</style>
  5579. +{/literal}
  5580. +</head>
  5581. +<body>
  5582. +
  5583. +<h1>Smarty Debug Console</h1>
  5584. +
  5585. +<h2>included templates &amp; config files (load time in seconds)</h2>
  5586. +
  5587. +<div>
  5588. +{section name=templates loop=$_debug_tpls}
  5589. +    {section name=indent loop=$_debug_tpls[templates].depth}&nbsp;&nbsp;&nbsp;{/section}
  5590. +    <font color={if $_debug_tpls[templates].type eq "template"}brown{elseif $_debug_tpls[templates].type eq "insert"}black{else}green{/if}>
  5591. +        {$_debug_tpls[templates].filename|escape:html}</font>
  5592. +    {if isset($_debug_tpls[templates].exec_time)}
  5593. +        <span class="exectime">
  5594. +        ({$_debug_tpls[templates].exec_time|string_format:"%.5f"})
  5595. +        {if %templates.index% eq 0}(total){/if}
  5596. +        </span>
  5597. +    {/if}
  5598. +    <br />
  5599. +{sectionelse}
  5600. +    <p>no templates included</p>
  5601. +{/section}
  5602. +</div>
  5603. +
  5604. +<h2>assigned template variables</h2>
  5605. +
  5606. +<table id="table_assigned_vars">
  5607. +    {section name=vars loop=$_debug_keys}
  5608. +        <tr class="{cycle values="odd,even"}">
  5609. +            <th>{ldelim}${$_debug_keys[vars]|escape:'html'}{rdelim}</th>
  5610. +            <td>{$_debug_vals[vars]|@debug_print_var}</td></tr>
  5611. +    {sectionelse}
  5612. +        <tr><td><p>no template variables assigned</p></td></tr>
  5613. +    {/section}
  5614. +</table>
  5615. +
  5616. +<h2>assigned config file variables (outer template scope)</h2>
  5617. +
  5618. +<table id="table_config_vars">
  5619. +    {section name=config_vars loop=$_debug_config_keys}
  5620. +        <tr class="{cycle values="odd,even"}">
  5621. +            <th>{ldelim}#{$_debug_config_keys[config_vars]|escape:'html'}#{rdelim}</th>
  5622. +            <td>{$_debug_config_vals[config_vars]|@debug_print_var}</td></tr>
  5623. +    {sectionelse}
  5624. +        <tr><td><p>no config vars assigned</p></td></tr>
  5625. +    {/section}
  5626. +</table>
  5627. +</body>
  5628. +</html>
  5629. +{/capture}
  5630. +{if isset($_smarty_debug_output) and $_smarty_debug_output eq "html"}
  5631. +    {$debug_output}
  5632. +{else}
  5633. +<script type="text/javascript">
  5634. +// <![CDATA[
  5635. +    if ( self.name == '' ) {ldelim}
  5636. +       var title = 'Console';
  5637. +    {rdelim}
  5638. +    else {ldelim}
  5639. +       var title = 'Console_' + self.name;
  5640. +    {rdelim}
  5641. +    _smarty_console = window.open("",title.value,"width=680,height=600,resizable,scrollbars=yes");
  5642. +    _smarty_console.document.write('{$debug_output|escape:'javascript'}');
  5643. +    _smarty_console.document.close();
  5644. +// ]]>
  5645. +</script>
  5646. +{/if}
  5647. \ No newline at end of file
  5648. diff --git a/library/smarty/internals/core.assemble_plugin_filepath.php b/library/smarty/internals/core.assemble_plugin_filepath.php
  5649. new file mode 100644
  5650. --- /dev/null
  5651. +++ b/library/smarty/internals/core.assemble_plugin_filepath.php
  5652. @@ -0,0 +1,67 @@
  5653. +<?php
  5654. +/**
  5655. + * Smarty plugin
  5656. + * @package Smarty
  5657. + * @subpackage plugins
  5658. + */
  5659. +
  5660. +/**
  5661. + * assemble filepath of requested plugin
  5662. + *
  5663. + * @param string $type
  5664. + * @param string $name
  5665. + * @return string|false
  5666. + */
  5667. +function smarty_core_assemble_plugin_filepath($params, &$smarty)
  5668. +{
  5669. +    static $_filepaths_cache = array();
  5670. +
  5671. +    $_plugin_filename = $params['type'] . '.' . $params['name'] . '.php';
  5672. +    if (isset($_filepaths_cache[$_plugin_filename])) {
  5673. +        return $_filepaths_cache[$_plugin_filename];
  5674. +    }
  5675. +    $_return = false;
  5676. +
  5677. +    foreach ((array)$smarty->plugins_dir as $_plugin_dir) {
  5678. +
  5679. +        $_plugin_filepath = $_plugin_dir . DIRECTORY_SEPARATOR . $_plugin_filename;
  5680. +
  5681. +        // see if path is relative
  5682. +        if (!preg_match("/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/", $_plugin_dir)) {
  5683. +            $_relative_paths[] = $_plugin_dir;
  5684. +            // relative path, see if it is in the SMARTY_DIR
  5685. +            if (@is_readable(SMARTY_DIR . $_plugin_filepath)) {
  5686. +                $_return = SMARTY_DIR . $_plugin_filepath;
  5687. +                break;
  5688. +            }
  5689. +        }
  5690. +        // try relative to cwd (or absolute)
  5691. +        if (@is_readable($_plugin_filepath)) {
  5692. +            $_return = $_plugin_filepath;
  5693. +            break;
  5694. +        }
  5695. +    }
  5696. +
  5697. +    if($_return === false) {
  5698. +        // still not found, try PHP include_path
  5699. +        if(isset($_relative_paths)) {
  5700. +            foreach ((array)$_relative_paths as $_plugin_dir) {
  5701. +
  5702. +                $_plugin_filepath = $_plugin_dir . DIRECTORY_SEPARATOR . $_plugin_filename;
  5703. +
  5704. +                $_params = array('file_path' => $_plugin_filepath);
  5705. +                require_once(SMARTY_CORE_DIR . 'core.get_include_path.php');
  5706. +                if(smarty_core_get_include_path($_params, $smarty)) {
  5707. +                    $_return = $_params['new_file_path'];
  5708. +                    break;
  5709. +                }
  5710. +            }
  5711. +        }
  5712. +    }
  5713. +    $_filepaths_cache[$_plugin_filename] = $_return;
  5714. +    return $_return;
  5715. +}
  5716. +
  5717. +/* vim: set expandtab: */
  5718. +
  5719. +?>
  5720. diff --git a/library/smarty/internals/core.assign_smarty_interface.php b/library/smarty/internals/core.assign_smarty_interface.php
  5721. new file mode 100644
  5722. --- /dev/null
  5723. +++ b/library/smarty/internals/core.assign_smarty_interface.php
  5724. @@ -0,0 +1,43 @@
  5725. +<?php
  5726. +/**
  5727. + * Smarty plugin
  5728. + * @package Smarty
  5729. + * @subpackage plugins
  5730. + */
  5731. +
  5732. +/**
  5733. + * Smarty assign_smarty_interface core plugin
  5734. + *
  5735. + * Type:     core<br>
  5736. + * Name:     assign_smarty_interface<br>
  5737. + * Purpose:  assign the $smarty interface variable
  5738. + * @param array Format: null
  5739. + * @param Smarty
  5740. + */
  5741. +function smarty_core_assign_smarty_interface($params, &$smarty)
  5742. +{
  5743. +        if (isset($smarty->_smarty_vars) && isset($smarty->_smarty_vars['request'])) {
  5744. +            return;
  5745. +        }
  5746. +
  5747. +        $_globals_map = array('g'  => 'HTTP_GET_VARS',
  5748. +                             'p'  => 'HTTP_POST_VARS',
  5749. +                             'c'  => 'HTTP_COOKIE_VARS',
  5750. +                             's'  => 'HTTP_SERVER_VARS',
  5751. +                             'e'  => 'HTTP_ENV_VARS');
  5752. +
  5753. +        $_smarty_vars_request  = array();
  5754. +
  5755. +        foreach (preg_split('!!', strtolower($smarty->request_vars_order)) as $_c) {
  5756. +            if (isset($_globals_map[$_c])) {
  5757. +                $_smarty_vars_request = array_merge($_smarty_vars_request, $GLOBALS[$_globals_map[$_c]]);
  5758. +            }
  5759. +        }
  5760. +        $_smarty_vars_request = @array_merge($_smarty_vars_request, $GLOBALS['HTTP_SESSION_VARS']);
  5761. +
  5762. +        $smarty->_smarty_vars['request'] = $_smarty_vars_request;
  5763. +}
  5764. +
  5765. +/* vim: set expandtab: */
  5766. +
  5767. +?>
  5768. diff --git a/library/smarty/internals/core.create_dir_structure.php b/library/smarty/internals/core.create_dir_structure.php
  5769. new file mode 100644
  5770. --- /dev/null
  5771. +++ b/library/smarty/internals/core.create_dir_structure.php
  5772. @@ -0,0 +1,79 @@
  5773. +<?php
  5774. +/**
  5775. + * Smarty plugin
  5776. + * @package Smarty
  5777. + * @subpackage plugins
  5778. + */
  5779. +
  5780. +/**
  5781. + * create full directory structure
  5782. + *
  5783. + * @param string $dir
  5784. + */
  5785. +
  5786. +// $dir
  5787. +
  5788. +function smarty_core_create_dir_structure($params, &$smarty)
  5789. +{
  5790. +    if (!file_exists($params['dir'])) {
  5791. +        $_open_basedir_ini = ini_get('open_basedir');
  5792. +
  5793. +        if (DIRECTORY_SEPARATOR=='/') {
  5794. +            /* unix-style paths */
  5795. +            $_dir = $params['dir'];
  5796. +            $_dir_parts = preg_split('!/+!', $_dir, -1, PREG_SPLIT_NO_EMPTY);
  5797. +            $_new_dir = (substr($_dir, 0, 1)=='/') ? '/' : getcwd().'/';
  5798. +            if($_use_open_basedir = !empty($_open_basedir_ini)) {
  5799. +                $_open_basedirs = explode(':', $_open_basedir_ini);
  5800. +            }
  5801. +
  5802. +        } else {
  5803. +            /* other-style paths */
  5804. +            $_dir = str_replace('\\','/', $params['dir']);
  5805. +            $_dir_parts = preg_split('!/+!', $_dir, -1, PREG_SPLIT_NO_EMPTY);
  5806. +            if (preg_match('!^((//)|([a-zA-Z]:/))!', $_dir, $_root_dir)) {
  5807. +                /* leading "//" for network volume, or "[letter]:/" for full path */
  5808. +                $_new_dir = $_root_dir[1];
  5809. +                /* remove drive-letter from _dir_parts */
  5810. +                if (isset($_root_dir[3])) array_shift($_dir_parts);
  5811. +
  5812. +            } else {
  5813. +                $_new_dir = str_replace('\\', '/', getcwd()).'/';
  5814. +
  5815. +            }
  5816. +
  5817. +            if($_use_open_basedir = !empty($_open_basedir_ini)) {
  5818. +                $_open_basedirs = explode(';', str_replace('\\', '/', $_open_basedir_ini));
  5819. +            }
  5820. +
  5821. +        }
  5822. +
  5823. +        /* all paths use "/" only from here */
  5824. +        foreach ($_dir_parts as $_dir_part) {
  5825. +            $_new_dir .= $_dir_part;
  5826. +
  5827. +            if ($_use_open_basedir) {
  5828. +                // do not attempt to test or make directories outside of open_basedir
  5829. +                $_make_new_dir = false;
  5830. +                foreach ($_open_basedirs as $_open_basedir) {
  5831. +                    if (substr($_new_dir, 0, strlen($_open_basedir)) == $_open_basedir) {
  5832. +                        $_make_new_dir = true;
  5833. +                        break;
  5834. +                    }
  5835. +                }
  5836. +            } else {
  5837. +                $_make_new_dir = true;
  5838. +            }
  5839. +
  5840. +            if ($_make_new_dir && !file_exists($_new_dir) && !@mkdir($_new_dir, $smarty->_dir_perms) && !is_dir($_new_dir)) {
  5841. +                $smarty->trigger_error("problem creating directory '" . $_new_dir . "'");
  5842. +                return false;
  5843. +            }
  5844. +            $_new_dir .= '/';
  5845. +        }
  5846. +    }
  5847. +}
  5848. +
  5849. +/* vim: set expandtab: */
  5850. +
  5851. +?>
  5852. diff --git a/library/smarty/internals/core.display_debug_console.php b/library/smarty/internals/core.display_debug_console.php
  5853. new file mode 100644
  5854. --- /dev/null
  5855. +++ b/library/smarty/internals/core.display_debug_console.php
  5856. @@ -0,0 +1,61 @@
  5857. +<?php
  5858. +/**
  5859. + * Smarty plugin
  5860. + * @package Smarty
  5861. + * @subpackage plugins
  5862. + */
  5863. +
  5864. +/**
  5865. + * Smarty debug_console function plugin
  5866. + *
  5867. + * Type:     core<br>
  5868. + * Name:     display_debug_console<br>
  5869. + * Purpose:  display the javascript debug console window
  5870. + * @param array Format: null
  5871. + * @param Smarty
  5872. + */
  5873. +function smarty_core_display_debug_console($params, &$smarty)
  5874. +{
  5875. +    // we must force compile the debug template in case the environment
  5876. +    // changed between separate applications.
  5877. +
  5878. +    if(empty($smarty->debug_tpl)) {
  5879. +        // set path to debug template from SMARTY_DIR
  5880. +        $smarty->debug_tpl = SMARTY_DIR . 'debug.tpl';
  5881. +        if($smarty->security && is_file($smarty->debug_tpl)) {
  5882. +            $smarty->secure_dir[] = realpath($smarty->debug_tpl);
  5883. +        }
  5884. +        $smarty->debug_tpl = 'file:' . SMARTY_DIR . 'debug.tpl';
  5885. +    }
  5886. +
  5887. +    $_ldelim_orig = $smarty->left_delimiter;
  5888. +    $_rdelim_orig = $smarty->right_delimiter;
  5889. +
  5890. +    $smarty->left_delimiter = '{';
  5891. +    $smarty->right_delimiter = '}';
  5892. +
  5893. +    $_compile_id_orig = $smarty->_compile_id;
  5894. +    $smarty->_compile_id = null;
  5895. +
  5896. +    $_compile_path = $smarty->_get_compile_path($smarty->debug_tpl);
  5897. +    if ($smarty->_compile_resource($smarty->debug_tpl, $_compile_path))
  5898. +    {
  5899. +        ob_start();
  5900. +        $smarty->_include($_compile_path);
  5901. +        $_results = ob_get_contents();
  5902. +        ob_end_clean();
  5903. +    } else {
  5904. +        $_results = '';
  5905. +    }
  5906. +
  5907. +    $smarty->_compile_id = $_compile_id_orig;
  5908. +
  5909. +    $smarty->left_delimiter = $_ldelim_orig;
  5910. +    $smarty->right_delimiter = $_rdelim_orig;
  5911. +
  5912. +    return $_results;
  5913. +}
  5914. +
  5915. +/* vim: set expandtab: */
  5916. +
  5917. +?>
  5918. diff --git a/library/smarty/internals/core.get_include_path.php b/library/smarty/internals/core.get_include_path.php
  5919. new file mode 100644
  5920. --- /dev/null
  5921. +++ b/library/smarty/internals/core.get_include_path.php
  5922. @@ -0,0 +1,44 @@
  5923. +<?php
  5924. +/**
  5925. + * Smarty plugin
  5926. + * @package Smarty
  5927. + * @subpackage plugins
  5928. + */
  5929. +
  5930. +/**
  5931. + * Get path to file from include_path
  5932. + *
  5933. + * @param string $file_path
  5934. + * @param string $new_file_path
  5935. + * @return boolean
  5936. + * @staticvar array|null
  5937. + */
  5938. +
  5939. +//  $file_path, &$new_file_path
  5940. +
  5941. +function smarty_core_get_include_path(&$params, &$smarty)
  5942. +{
  5943. +    static $_path_array = null;
  5944. +
  5945. +    if(!isset($_path_array)) {
  5946. +        $_ini_include_path = ini_get('include_path');
  5947. +
  5948. +        if(strstr($_ini_include_path,';')) {
  5949. +            // windows pathnames
  5950. +            $_path_array = explode(';',$_ini_include_path);
  5951. +        } else {
  5952. +            $_path_array = explode(':',$_ini_include_path);
  5953. +        }
  5954. +    }
  5955. +    foreach ($_path_array as $_include_path) {
  5956. +        if (@is_readable($_include_path . DIRECTORY_SEPARATOR . $params['file_path'])) {
  5957. +               $params['new_file_path'] = $_include_path . DIRECTORY_SEPARATOR . $params['file_path'];
  5958. +            return true;
  5959. +        }
  5960. +    }
  5961. +    return false;
  5962. +}
  5963. +
  5964. +/* vim: set expandtab: */
  5965. +
  5966. +?>
  5967. diff --git a/library/smarty/internals/core.get_microtime.php b/library/smarty/internals/core.get_microtime.php
  5968. new file mode 100644
  5969. --- /dev/null
  5970. +++ b/library/smarty/internals/core.get_microtime.php
  5971. @@ -0,0 +1,23 @@
  5972. +<?php
  5973. +/**
  5974. + * Smarty plugin
  5975. + * @package Smarty
  5976. + * @subpackage plugins
  5977. + */
  5978. +
  5979. +/**
  5980. + * Get seconds and microseconds
  5981. + * @return double
  5982. + */
  5983. +function smarty_core_get_microtime($params, &$smarty)
  5984. +{
  5985. +    $mtime = microtime();
  5986. +    $mtime = explode(" ", $mtime);
  5987. +    $mtime = (double)($mtime[1]) + (double)($mtime[0]);
  5988. +    return ($mtime);
  5989. +}
  5990. +
  5991. +
  5992. +/* vim: set expandtab: */
  5993. +
  5994. +?>
  5995. diff --git a/library/smarty/internals/core.get_php_resource.php b/library/smarty/internals/core.get_php_resource.php
  5996. new file mode 100644
  5997. --- /dev/null
  5998. +++ b/library/smarty/internals/core.get_php_resource.php
  5999. @@ -0,0 +1,80 @@
  6000. +<?php
  6001. +/**
  6002. + * Smarty plugin
  6003. + * @package Smarty
  6004. + * @subpackage plugins
  6005. + */
  6006. +
  6007. +/**
  6008. + * Retrieves PHP script resource
  6009. + *
  6010. + * sets $php_resource to the returned resource
  6011. + * @param string $resource
  6012. + * @param string $resource_type
  6013. + * @param  $php_resource
  6014. + * @return boolean
  6015. + */
  6016. +
  6017. +function smarty_core_get_php_resource(&$params, &$smarty)
  6018. +{
  6019. +
  6020. +    $params['resource_base_path'] = $smarty->trusted_dir;
  6021. +    $smarty->_parse_resource_name($params, $smarty);
  6022. +
  6023. +    /*
  6024. +     * Find out if the resource exists.
  6025. +     */
  6026. +
  6027. +    if ($params['resource_type'] == 'file') {
  6028. +        $_readable = false;
  6029. +        if(file_exists($params['resource_name']) && is_readable($params['resource_name'])) {
  6030. +            $_readable = true;
  6031. +        } else {
  6032. +            // test for file in include_path
  6033. +            $_params = array('file_path' => $params['resource_name']);
  6034. +            require_once(SMARTY_CORE_DIR . 'core.get_include_path.php');
  6035. +            if(smarty_core_get_include_path($_params, $smarty)) {
  6036. +                $_include_path = $_params['new_file_path'];
  6037. +                $_readable = true;
  6038. +            }
  6039. +        }
  6040. +    } else if ($params['resource_type'] != 'file') {
  6041. +        $_template_source = null;
  6042. +        $_readable = is_callable($smarty->_plugins['resource'][$params['resource_type']][0][0])
  6043. +            && call_user_func_array($smarty->_plugins['resource'][$params['resource_type']][0][0],
  6044. +                                    array($params['resource_name'], &$_template_source, &$smarty));
  6045. +    }
  6046. +
  6047. +    /*
  6048. +     * Set the error function, depending on which class calls us.
  6049. +     */
  6050. +    if (method_exists($smarty, '_syntax_error')) {
  6051. +        $_error_funcc = '_syntax_error';
  6052. +    } else {
  6053. +        $_error_funcc = 'trigger_error';
  6054. +    }
  6055. +
  6056. +    if ($_readable) {
  6057. +        if ($smarty->security) {
  6058. +            require_once(SMARTY_CORE_DIR . 'core.is_trusted.php');
  6059. +            if (!smarty_core_is_trusted($params, $smarty)) {
  6060. +                $smarty->$_error_funcc('(secure mode) ' . $params['resource_type'] . ':' . $params['resource_name'] . ' is not trusted');
  6061. +                return false;
  6062. +            }
  6063. +        }
  6064. +    } else {
  6065. +        $smarty->$_error_funcc($params['resource_type'] . ':' . $params['resource_name'] . ' is not readable');
  6066. +        return false;
  6067. +    }
  6068. +
  6069. +    if ($params['resource_type'] == 'file') {
  6070. +        $params['php_resource'] = $params['resource_name'];
  6071. +    } else {
  6072. +        $params['php_resource'] = $_template_source;
  6073. +    }
  6074. +    return true;
  6075. +}
  6076. +
  6077. +/* vim: set expandtab: */
  6078. +
  6079. +?>
  6080. diff --git a/library/smarty/internals/core.is_secure.php b/library/smarty/internals/core.is_secure.php
  6081. new file mode 100644
  6082. --- /dev/null
  6083. +++ b/library/smarty/internals/core.is_secure.php
  6084. @@ -0,0 +1,59 @@
  6085. +<?php
  6086. +/**
  6087. + * Smarty plugin
  6088. + * @package Smarty
  6089. + * @subpackage plugins
  6090. + */
  6091. +
  6092. +/**
  6093. + * determines if a resource is secure or not.
  6094. + *
  6095. + * @param string $resource_type
  6096. + * @param string $resource_name
  6097. + * @return boolean
  6098. + */
  6099. +
  6100. +//  $resource_type, $resource_name
  6101. +
  6102. +function smarty_core_is_secure($params, &$smarty)
  6103. +{
  6104. +    if (!$smarty->security || $smarty->security_settings['INCLUDE_ANY']) {
  6105. +        return true;
  6106. +    }
  6107. +
  6108. +    if ($params['resource_type'] == 'file') {
  6109. +        $_rp = realpath($params['resource_name']);
  6110. +        if (isset($params['resource_base_path'])) {
  6111. +            foreach ((array)$params['resource_base_path'] as $curr_dir) {
  6112. +                if ( ($_cd = realpath($curr_dir)) !== false &&
  6113. +                     strncmp($_rp, $_cd, strlen($_cd)) == 0 &&
  6114. +                     substr($_rp, strlen($_cd), 1) == DIRECTORY_SEPARATOR ) {
  6115. +                    return true;
  6116. +                }
  6117. +            }
  6118. +        }
  6119. +        if (!empty($smarty->secure_dir)) {
  6120. +            foreach ((array)$smarty->secure_dir as $curr_dir) {
  6121. +                if ( ($_cd = realpath($curr_dir)) !== false) {
  6122. +                    if($_cd == $_rp) {
  6123. +                        return true;
  6124. +                    } elseif (strncmp($_rp, $_cd, strlen($_cd)) == 0 &&
  6125. +                        substr($_rp, strlen($_cd), 1) == DIRECTORY_SEPARATOR) {
  6126. +                        return true;
  6127. +                    }
  6128. +                }
  6129. +            }
  6130. +        }
  6131. +    } else {
  6132. +        // resource is not on local file system
  6133. +        return call_user_func_array(
  6134. +            $smarty->_plugins['resource'][$params['resource_type']][0][2],
  6135. +            array($params['resource_name'], &$smarty));
  6136. +    }
  6137. +
  6138. +    return false;
  6139. +}
  6140. +
  6141. +/* vim: set expandtab: */
  6142. +
  6143. +?>
  6144. diff --git a/library/smarty/internals/core.is_trusted.php b/library/smarty/internals/core.is_trusted.php
  6145. new file mode 100644
  6146. --- /dev/null
  6147. +++ b/library/smarty/internals/core.is_trusted.php
  6148. @@ -0,0 +1,47 @@
  6149. +<?php
  6150. +/**
  6151. + * Smarty plugin
  6152. + * @package Smarty
  6153. + * @subpackage plugins
  6154. + */
  6155. +
  6156. +/**
  6157. + * determines if a resource is trusted or not
  6158. + *
  6159. + * @param string $resource_type
  6160. + * @param string $resource_name
  6161. + * @return boolean
  6162. + */
  6163. +
  6164. + // $resource_type, $resource_name
  6165. +
  6166. +function smarty_core_is_trusted($params, &$smarty)
  6167. +{
  6168. +    $_smarty_trusted = false;
  6169. +    if ($params['resource_type'] == 'file') {
  6170. +        if (!empty($smarty->trusted_dir)) {
  6171. +            $_rp = realpath($params['resource_name']);
  6172. +            foreach ((array)$smarty->trusted_dir as $curr_dir) {
  6173. +                if (!empty($curr_dir) && is_readable ($curr_dir)) {
  6174. +                    $_cd = realpath($curr_dir);
  6175. +                    if (strncmp($_rp, $_cd, strlen($_cd)) == 0
  6176. +                        && substr($_rp, strlen($_cd), 1) == DIRECTORY_SEPARATOR ) {
  6177. +                        $_smarty_trusted = true;
  6178. +                        break;
  6179. +                    }
  6180. +                }
  6181. +            }
  6182. +        }
  6183. +
  6184. +    } else {
  6185. +        // resource is not on local file system
  6186. +        $_smarty_trusted = call_user_func_array($smarty->_plugins['resource'][$params['resource_type']][0][3],
  6187. +                                                array($params['resource_name'], $smarty));
  6188. +    }
  6189. +
  6190. +    return $_smarty_trusted;
  6191. +}
  6192. +
  6193. +/* vim: set expandtab: */
  6194. +
  6195. +?>
  6196. diff --git a/library/smarty/internals/core.load_plugins.php b/library/smarty/internals/core.load_plugins.php
  6197. new file mode 100644
  6198. --- /dev/null
  6199. +++ b/library/smarty/internals/core.load_plugins.php
  6200. @@ -0,0 +1,125 @@
  6201. +<?php
  6202. +/**
  6203. + * Smarty plugin
  6204. + * @package Smarty
  6205. + * @subpackage plugins
  6206. + */
  6207. +
  6208. +/**
  6209. + * Load requested plugins
  6210. + *
  6211. + * @param array $plugins
  6212. + */
  6213. +
  6214. +// $plugins
  6215. +
  6216. +function smarty_core_load_plugins($params, &$smarty)
  6217. +{
  6218. +
  6219. +    foreach ($params['plugins'] as $_plugin_info) {
  6220. +        list($_type, $_name, $_tpl_file, $_tpl_line, $_delayed_loading) = $_plugin_info;
  6221. +        $_plugin = &$smarty->_plugins[$_type][$_name];
  6222. +
  6223. +        /*
  6224. +         * We do not load plugin more than once for each instance of Smarty.
  6225. +         * The following code checks for that. The plugin can also be
  6226. +         * registered dynamically at runtime, in which case template file
  6227. +         * and line number will be unknown, so we fill them in.
  6228. +         *
  6229. +         * The final element of the info array is a flag that indicates
  6230. +         * whether the dynamically registered plugin function has been
  6231. +         * checked for existence yet or not.
  6232. +         */
  6233. +        if (isset($_plugin)) {
  6234. +            if (empty($_plugin[3])) {
  6235. +                if (!is_callable($_plugin[0])) {
  6236. +                    $smarty->_trigger_fatal_error("[plugin] $_type '$_name' is not implemented", $_tpl_file, $_tpl_line, __FILE__, __LINE__);
  6237. +                } else {
  6238. +                    $_plugin[1] = $_tpl_file;
  6239. +                    $_plugin[2] = $_tpl_line;
  6240. +                    $_plugin[3] = true;
  6241. +                    if (!isset($_plugin[4])) $_plugin[4] = true; /* cacheable */
  6242. +                }
  6243. +            }
  6244. +            continue;
  6245. +        } else if ($_type == 'insert') {
  6246. +            /*
  6247. +             * For backwards compatibility, we check for insert functions in
  6248. +             * the symbol table before trying to load them as a plugin.
  6249. +             */
  6250. +            $_plugin_func = 'insert_' . $_name;
  6251. +            if (function_exists($_plugin_func)) {
  6252. +                $_plugin = array($_plugin_func, $_tpl_file, $_tpl_line, true, false);
  6253. +                continue;
  6254. +            }
  6255. +        }
  6256. +
  6257. +        $_plugin_file = $smarty->_get_plugin_filepath($_type, $_name);
  6258. +
  6259. +        if (! $_found = ($_plugin_file != false)) {
  6260. +            $_message = "could not load plugin file '$_type.$_name.php'\n";
  6261. +        }
  6262. +
  6263. +        /*
  6264. +         * If plugin file is found, it -must- provide the properly named
  6265. +         * plugin function. In case it doesn't, simply output the error and
  6266. +         * do not fall back on any other method.
  6267. +         */
  6268. +        if ($_found) {
  6269. +            include_once $_plugin_file;
  6270. +
  6271. +            $_plugin_func = 'smarty_' . $_type . '_' . $_name;
  6272. +            if (!function_exists($_plugin_func)) {
  6273. +                $smarty->_trigger_fatal_error("[plugin] function $_plugin_func() not found in $_plugin_file", $_tpl_file, $_tpl_line, __FILE__, __LINE__);
  6274. +                continue;
  6275. +            }
  6276. +        }
  6277. +        /*
  6278. +         * In case of insert plugins, their code may be loaded later via
  6279. +         * 'script' attribute.
  6280. +         */
  6281. +        else if ($_type == 'insert' && $_delayed_loading) {
  6282. +            $_plugin_func = 'smarty_' . $_type . '_' . $_name;
  6283. +            $_found = true;
  6284. +        }
  6285. +
  6286. +        /*
  6287. +         * Plugin specific processing and error checking.
  6288. +         */
  6289. +        if (!$_found) {
  6290. +            if ($_type == 'modifier') {
  6291. +                /*
  6292. +                 * In case modifier falls back on using PHP functions
  6293. +                 * directly, we only allow those specified in the security
  6294. +                 * context.
  6295. +                 */
  6296. +                if ($smarty->security && !in_array($_name, $smarty->security_settings['MODIFIER_FUNCS'])) {
  6297. +                    $_message = "(secure mode) modifier '$_name' is not allowed";
  6298. +                } else {
  6299. +                    if (!function_exists($_name)) {
  6300. +                        $_message = "modifier '$_name' is not implemented";
  6301. +                    } else {
  6302. +                        $_plugin_func = $_name;
  6303. +                        $_found = true;
  6304. +                    }
  6305. +                }
  6306. +            } else if ($_type == 'function') {
  6307. +                /*
  6308. +                 * This is a catch-all situation.
  6309. +                 */
  6310. +                $_message = "unknown tag - '$_name'";
  6311. +            }
  6312. +        }
  6313. +
  6314. +        if ($_found) {
  6315. +            $smarty->_plugins[$_type][$_name] = array($_plugin_func, $_tpl_file, $_tpl_line, true, true);
  6316. +        } else {
  6317. +            // output error
  6318. +            $smarty->_trigger_fatal_error('[plugin] ' . $_message, $_tpl_file, $_tpl_line, __FILE__, __LINE__);
  6319. +        }
  6320. +    }
  6321. +}
  6322. +
  6323. +/* vim: set expandtab: */
  6324. +
  6325. +?>
  6326. diff --git a/library/smarty/internals/core.load_resource_plugin.php b/library/smarty/internals/core.load_resource_plugin.php
  6327. new file mode 100644
  6328. --- /dev/null
  6329. +++ b/library/smarty/internals/core.load_resource_plugin.php
  6330. @@ -0,0 +1,74 @@
  6331. +<?php
  6332. +/**
  6333. + * Smarty plugin
  6334. + * @package Smarty
  6335. + * @subpackage plugins
  6336. + */
  6337. +
  6338. +/**
  6339. + * load a resource plugin
  6340. + *
  6341. + * @param string $type
  6342. + */
  6343. +
  6344. +// $type
  6345. +
  6346. +function smarty_core_load_resource_plugin($params, &$smarty)
  6347. +{
  6348. +    /*
  6349. +     * Resource plugins are not quite like the other ones, so they are
  6350. +     * handled differently. The first element of plugin info is the array of
  6351. +     * functions provided by the plugin, the second one indicates whether
  6352. +     * all of them exist or not.
  6353. +     */
  6354. +
  6355. +    $_plugin = &$smarty->_plugins['resource'][$params['type']];
  6356. +    if (isset($_plugin)) {
  6357. +        if (!$_plugin[1] && count($_plugin[0])) {
  6358. +            $_plugin[1] = true;
  6359. +            foreach ($_plugin[0] as $_plugin_func) {
  6360. +                if (!is_callable($_plugin_func)) {
  6361. +                    $_plugin[1] = false;
  6362. +                    break;
  6363. +                }
  6364. +            }
  6365. +        }
  6366. +
  6367. +        if (!$_plugin[1]) {
  6368. +            $smarty->_trigger_fatal_error("[plugin] resource '" . $params['type'] . "' is not implemented", null, null, __FILE__, __LINE__);
  6369. +        }
  6370. +
  6371. +        return;
  6372. +    }
  6373. +
  6374. +    $_plugin_file = $smarty->_get_plugin_filepath('resource', $params['type']);
  6375. +    $_found = ($_plugin_file != false);
  6376. +
  6377. +    if ($_found) {            /*
  6378. +         * If the plugin file is found, it -must- provide the properly named
  6379. +         * plugin functions.
  6380. +         */
  6381. +        include_once($_plugin_file);
  6382. +
  6383. +        /*
  6384. +         * Locate functions that we require the plugin to provide.
  6385. +         */
  6386. +        $_resource_ops = array('source', 'timestamp', 'secure', 'trusted');
  6387. +        $_resource_funcs = array();
  6388. +        foreach ($_resource_ops as $_op) {
  6389. +            $_plugin_func = 'smarty_resource_' . $params['type'] . '_' . $_op;
  6390. +            if (!function_exists($_plugin_func)) {
  6391. +                $smarty->_trigger_fatal_error("[plugin] function $_plugin_func() not found in $_plugin_file", null, null, __FILE__, __LINE__);
  6392. +                return;
  6393. +            } else {
  6394. +                $_resource_funcs[] = $_plugin_func;
  6395. +            }
  6396. +        }
  6397. +
  6398. +        $smarty->_plugins['resource'][$params['type']] = array($_resource_funcs, true);
  6399. +    }
  6400. +}
  6401. +
  6402. +/* vim: set expandtab: */
  6403. +
  6404. +?>
  6405. diff --git a/library/smarty/internals/core.process_cached_inserts.php b/library/smarty/internals/core.process_cached_inserts.php
  6406. new file mode 100644
  6407. --- /dev/null
  6408. +++ b/library/smarty/internals/core.process_cached_inserts.php
  6409. @@ -0,0 +1,71 @@
  6410. +<?php
  6411. +/**
  6412. + * Smarty plugin
  6413. + * @package Smarty
  6414. + * @subpackage plugins
  6415. + */
  6416. +
  6417. +/**
  6418. + * Replace cached inserts with the actual results
  6419. + *
  6420. + * @param string $results
  6421. + * @return string
  6422. + */
  6423. +function smarty_core_process_cached_inserts($params, &$smarty)
  6424. +{
  6425. +    preg_match_all('!'.$smarty->_smarty_md5.'{insert_cache (.*)}'.$smarty->_smarty_md5.'!Uis',
  6426. +                   $params['results'], $match);
  6427. +    list($cached_inserts, $insert_args) = $match;
  6428. +
  6429. +    for ($i = 0, $for_max = count($cached_inserts); $i < $for_max; $i++) {
  6430. +        if ($smarty->debugging) {
  6431. +            $_params = array();
  6432. +            require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
  6433. +            $debug_start_time = smarty_core_get_microtime($_params, $smarty);
  6434. +        }
  6435. +
  6436. +        $args = unserialize($insert_args[$i]);
  6437. +        $name = $args['name'];
  6438. +
  6439. +        if (isset($args['script'])) {
  6440. +            $_params = array('resource_name' => $smarty->_dequote($args['script']));
  6441. +            require_once(SMARTY_CORE_DIR . 'core.get_php_resource.php');
  6442. +            if(!smarty_core_get_php_resource($_params, $smarty)) {
  6443. +                return false;
  6444. +            }
  6445. +            $resource_type = $_params['resource_type'];
  6446. +            $php_resource = $_params['php_resource'];
  6447. +
  6448. +
  6449. +            if ($resource_type == 'file') {
  6450. +                $smarty->_include($php_resource, true);
  6451. +            } else {
  6452. +                $smarty->_eval($php_resource);
  6453. +            }
  6454. +        }
  6455. +
  6456. +        $function_name = $smarty->_plugins['insert'][$name][0];
  6457. +        if (empty($args['assign'])) {
  6458. +            $replace = $function_name($args, $smarty);
  6459. +        } else {
  6460. +            $smarty->assign($args['assign'], $function_name($args, $smarty));
  6461. +            $replace = '';
  6462. +        }
  6463. +
  6464. +        $params['results'] = substr_replace($params['results'], $replace, strpos($params['results'], $cached_inserts[$i]), strlen($cached_inserts[$i]));
  6465. +        if ($smarty->debugging) {
  6466. +            $_params = array();
  6467. +            require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
  6468. +            $smarty->_smarty_debug_info[] = array('type'      => 'insert',
  6469. +                                                'filename'  => 'insert_'.$name,
  6470. +                                                'depth'     => $smarty->_inclusion_depth,
  6471. +                                                'exec_time' => smarty_core_get_microtime($_params, $smarty) - $debug_start_time);
  6472. +        }
  6473. +    }
  6474. +
  6475. +    return $params['results'];
  6476. +}
  6477. +
  6478. +/* vim: set expandtab: */
  6479. +
  6480. +?>
  6481. diff --git a/library/smarty/internals/core.process_compiled_include.php b/library/smarty/internals/core.process_compiled_include.php
  6482. new file mode 100644
  6483. --- /dev/null
  6484. +++ b/library/smarty/internals/core.process_compiled_include.php
  6485. @@ -0,0 +1,37 @@
  6486. +<?php
  6487. +/**
  6488. + * Smarty plugin
  6489. + * @package Smarty
  6490. + * @subpackage plugins
  6491. + */
  6492. +
  6493. +/**
  6494. + * Replace nocache-tags by results of the corresponding non-cacheable
  6495. + * functions and return it
  6496. + *
  6497. + * @param string $compiled_tpl
  6498. + * @param string $cached_source
  6499. + * @return string
  6500. + */
  6501. +
  6502. +function smarty_core_process_compiled_include($params, &$smarty)
  6503. +{
  6504. +    $_cache_including = $smarty->_cache_including;
  6505. +    $smarty->_cache_including = true;
  6506. +
  6507. +    $_return = $params['results'];
  6508. +
  6509. +    foreach ($smarty->_cache_info['cache_serials'] as $_include_file_path=>$_cache_serial) {
  6510. +        $smarty->_include($_include_file_path, true);
  6511. +    }
  6512. +
  6513. +    foreach ($smarty->_cache_info['cache_serials'] as $_include_file_path=>$_cache_serial) {
  6514. +        $_return = preg_replace_callback('!(\{nocache\:('.$_cache_serial.')#(\d+)\})!s',
  6515. +                                         array(&$smarty, '_process_compiled_include_callback'),
  6516. +                                         $_return);
  6517. +    }
  6518. +    $smarty->_cache_including = $_cache_including;
  6519. +    return $_return;
  6520. +}
  6521. +
  6522. +?>
  6523. diff --git a/library/smarty/internals/core.read_cache_file.php b/library/smarty/internals/core.read_cache_file.php
  6524. new file mode 100644
  6525. --- /dev/null
  6526. +++ b/library/smarty/internals/core.read_cache_file.php
  6527. @@ -0,0 +1,101 @@
  6528. +<?php
  6529. +/**
  6530. + * Smarty plugin
  6531. + * @package Smarty
  6532. + * @subpackage plugins
  6533. + */
  6534. +
  6535. +/**
  6536. + * read a cache file, determine if it needs to be
  6537. + * regenerated or not
  6538. + *
  6539. + * @param string $tpl_file
  6540. + * @param string $cache_id
  6541. + * @param string $compile_id
  6542. + * @param string $results
  6543. + * @return boolean
  6544. + */
  6545. +
  6546. +//  $tpl_file, $cache_id, $compile_id, &$results
  6547. +
  6548. +function smarty_core_read_cache_file(&$params, &$smarty)
  6549. +{
  6550. +    static  $content_cache = array();
  6551. +
  6552. +    if ($smarty->force_compile) {
  6553. +        // force compile enabled, always regenerate
  6554. +        return false;
  6555. +    }
  6556. +
  6557. +    if (isset($content_cache[$params['tpl_file'].','.$params['cache_id'].','.$params['compile_id']])) {
  6558. +        list($params['results'], $smarty->_cache_info) = $content_cache[$params['tpl_file'].','.$params['cache_id'].','.$params['compile_id']];
  6559. +        return true;
  6560. +    }
  6561. +
  6562. +    if (!empty($smarty->cache_handler_func)) {
  6563. +        // use cache_handler function
  6564. +        call_user_func_array($smarty->cache_handler_func,
  6565. +                             array('read', &$smarty, &$params['results'], $params['tpl_file'], $params['cache_id'], $params['compile_id'], null));
  6566. +    } else {
  6567. +        // use local cache file
  6568. +        $_auto_id = $smarty->_get_auto_id($params['cache_id'], $params['compile_id']);
  6569. +        $_cache_file = $smarty->_get_auto_filename($smarty->cache_dir, $params['tpl_file'], $_auto_id);
  6570. +        $params['results'] = $smarty->_read_file($_cache_file);
  6571. +    }
  6572. +
  6573. +    if (empty($params['results'])) {
  6574. +        // nothing to parse (error?), regenerate cache
  6575. +        return false;
  6576. +    }
  6577. +
  6578. +    $_contents = $params['results'];
  6579. +    $_info_start = strpos($_contents, "\n") + 1;
  6580. +    $_info_len = (int)substr($_contents, 0, $_info_start - 1);
  6581. +    $_cache_info = unserialize(substr($_contents, $_info_start, $_info_len));
  6582. +    $params['results'] = substr($_contents, $_info_start + $_info_len);
  6583. +
  6584. +    if ($smarty->caching == 2 && isset ($_cache_info['expires'])){
  6585. +        // caching by expiration time
  6586. +        if ($_cache_info['expires'] > -1 && (time() > $_cache_info['expires'])) {
  6587. +            // cache expired, regenerate
  6588. +            return false;
  6589. +        }
  6590. +    } else {
  6591. +        // caching by lifetime
  6592. +        if ($smarty->cache_lifetime > -1 && (time() - $_cache_info['timestamp'] > $smarty->cache_lifetime)) {
  6593. +            // cache expired, regenerate
  6594. +            return false;
  6595. +        }
  6596. +    }
  6597. +
  6598. +    if ($smarty->compile_check) {
  6599. +        $_params = array('get_source' => false, 'quiet'=>true);
  6600. +        foreach (array_keys($_cache_info['template']) as $_template_dep) {
  6601. +            $_params['resource_name'] = $_template_dep;
  6602. +            if (!$smarty->_fetch_resource_info($_params) || $_cache_info['timestamp'] < $_params['resource_timestamp']) {
  6603. +                // template file has changed, regenerate cache
  6604. +                return false;
  6605. +            }
  6606. +        }
  6607. +
  6608. +        if (isset($_cache_info['config'])) {
  6609. +            $_params = array('resource_base_path' => $smarty->config_dir, 'get_source' => false, 'quiet'=>true);
  6610. +            foreach (array_keys($_cache_info['config']) as $_config_dep) {
  6611. +                $_params['resource_name'] = $_config_dep;
  6612. +                if (!$smarty->_fetch_resource_info($_params) || $_cache_info['timestamp'] < $_params['resource_timestamp']) {
  6613. +                    // config file has changed, regenerate cache
  6614. +                    return false;
  6615. +                }
  6616. +            }
  6617. +        }
  6618. +    }
  6619. +
  6620. +    $content_cache[$params['tpl_file'].','.$params['cache_id'].','.$params['compile_id']] = array($params['results'], $_cache_info);
  6621. +
  6622. +    $smarty->_cache_info = $_cache_info;
  6623. +    return true;
  6624. +}
  6625. +
  6626. +/* vim: set expandtab: */
  6627. +
  6628. +?>
  6629. diff --git a/library/smarty/internals/core.rm_auto.php b/library/smarty/internals/core.rm_auto.php
  6630. new file mode 100644
  6631. --- /dev/null
  6632. +++ b/library/smarty/internals/core.rm_auto.php
  6633. @@ -0,0 +1,71 @@
  6634. +<?php
  6635. +/**
  6636. + * Smarty plugin
  6637. + * @package Smarty
  6638. + * @subpackage plugins
  6639. + */
  6640. +
  6641. +/**
  6642. + * delete an automagically created file by name and id
  6643. + *
  6644. + * @param string $auto_base
  6645. + * @param string $auto_source
  6646. + * @param string $auto_id
  6647. + * @param integer $exp_time
  6648. + * @return boolean
  6649. + */
  6650. +
  6651. +// $auto_base, $auto_source = null, $auto_id = null, $exp_time = null
  6652. +
  6653. +function smarty_core_rm_auto($params, &$smarty)
  6654. +{
  6655. +    if (!@is_dir($params['auto_base']))
  6656. +      return false;
  6657. +
  6658. +    if(!isset($params['auto_id']) && !isset($params['auto_source'])) {
  6659. +        $_params = array(
  6660. +            'dirname' => $params['auto_base'],
  6661. +            'level' => 0,
  6662. +            'exp_time' => $params['exp_time']
  6663. +        );
  6664. +        require_once(SMARTY_CORE_DIR . 'core.rmdir.php');
  6665. +        $_res = smarty_core_rmdir($_params, $smarty);
  6666. +    } else {
  6667. +        $_tname = $smarty->_get_auto_filename($params['auto_base'], $params['auto_source'], $params['auto_id']);
  6668. +
  6669. +        if(isset($params['auto_source'])) {
  6670. +            if (isset($params['extensions'])) {
  6671. +                $_res = false;
  6672. +                foreach ((array)$params['extensions'] as $_extension)
  6673. +                    $_res |= $smarty->_unlink($_tname.$_extension, $params['exp_time']);
  6674. +            } else {
  6675. +                $_res = $smarty->_unlink($_tname, $params['exp_time']);
  6676. +            }
  6677. +        } elseif ($smarty->use_sub_dirs) {
  6678. +            $_params = array(
  6679. +                'dirname' => $_tname,
  6680. +                'level' => 1,
  6681. +                'exp_time' => $params['exp_time']
  6682. +            );
  6683. +            require_once(SMARTY_CORE_DIR . 'core.rmdir.php');
  6684. +            $_res = smarty_core_rmdir($_params, $smarty);
  6685. +        } else {
  6686. +            // remove matching file names
  6687. +            $_handle = opendir($params['auto_base']);
  6688. +            $_res = true;
  6689. +            while (false !== ($_filename = readdir($_handle))) {
  6690. +                if($_filename == '.' || $_filename == '..') {
  6691. +                    continue;
  6692. +                } elseif (substr($params['auto_base'] . DIRECTORY_SEPARATOR . $_filename, 0, strlen($_tname)) == $_tname) {
  6693. +                    $_res &= (bool)$smarty->_unlink($params['auto_base'] . DIRECTORY_SEPARATOR . $_filename, $params['exp_time']);
  6694. +                }
  6695. +            }
  6696. +        }
  6697. +    }
  6698. +
  6699. +    return $_res;
  6700. +}
  6701. +
  6702. +/* vim: set expandtab: */
  6703. +
  6704. +?>
  6705. diff --git a/library/smarty/internals/core.rmdir.php b/library/smarty/internals/core.rmdir.php
  6706. new file mode 100644
  6707. --- /dev/null
  6708. +++ b/library/smarty/internals/core.rmdir.php
  6709. @@ -0,0 +1,54 @@
  6710. +<?php
  6711. +/**
  6712. + * Smarty plugin
  6713. + * @package Smarty
  6714. + * @subpackage plugins
  6715. + */
  6716. +
  6717. +/**
  6718. + * delete a dir recursively (level=0 -> keep root)
  6719. + * WARNING: no tests, it will try to remove what you tell it!
  6720. + *
  6721. + * @param string $dirname
  6722. + * @param integer $level
  6723. + * @param integer $exp_time
  6724. + * @return boolean
  6725. + */
  6726. +
  6727. +//  $dirname, $level = 1, $exp_time = null
  6728. +
  6729. +function smarty_core_rmdir($params, &$smarty)
  6730. +{
  6731. +   if(!isset($params['level'])) { $params['level'] = 1; }
  6732. +   if(!isset($params['exp_time'])) { $params['exp_time'] = null; }
  6733. +
  6734. +   if($_handle = @opendir($params['dirname'])) {
  6735. +
  6736. +        while (false !== ($_entry = readdir($_handle))) {
  6737. +            if ($_entry != '.' && $_entry != '..') {
  6738. +                if (@is_dir($params['dirname'] . DIRECTORY_SEPARATOR . $_entry)) {
  6739. +                    $_params = array(
  6740. +                        'dirname' => $params['dirname'] . DIRECTORY_SEPARATOR . $_entry,
  6741. +                        'level' => $params['level'] + 1,
  6742. +                        'exp_time' => $params['exp_time']
  6743. +                    );
  6744. +                    smarty_core_rmdir($_params, $smarty);
  6745. +                }
  6746. +                else {
  6747. +                    $smarty->_unlink($params['dirname'] . DIRECTORY_SEPARATOR . $_entry, $params['exp_time']);
  6748. +                }
  6749. +            }
  6750. +        }
  6751. +        closedir($_handle);
  6752. +   }
  6753. +
  6754. +   if ($params['level']) {
  6755. +       return @rmdir($params['dirname']);
  6756. +   }
  6757. +   return (bool)$_handle;
  6758. +
  6759. +}
  6760. +
  6761. +/* vim: set expandtab: */
  6762. +
  6763. +?>
  6764. diff --git a/library/smarty/internals/core.run_insert_handler.php b/library/smarty/internals/core.run_insert_handler.php
  6765. new file mode 100644
  6766. --- /dev/null
  6767. +++ b/library/smarty/internals/core.run_insert_handler.php
  6768. @@ -0,0 +1,71 @@
  6769. +<?php
  6770. +/**
  6771. + * Smarty plugin
  6772. + * @package Smarty
  6773. + * @subpackage plugins
  6774. + */
  6775. +
  6776. +/**
  6777. + * Handle insert tags
  6778. + *
  6779. + * @param array $args
  6780. + * @return string
  6781. + */
  6782. +function smarty_core_run_insert_handler($params, &$smarty)
  6783. +{
  6784. +
  6785. +    require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
  6786. +    if ($smarty->debugging) {
  6787. +        $_params = array();
  6788. +        $_debug_start_time = smarty_core_get_microtime($_params, $smarty);
  6789. +    }
  6790. +
  6791. +    if ($smarty->caching) {
  6792. +        $_arg_string = serialize($params['args']);
  6793. +        $_name = $params['args']['name'];
  6794. +        if (!isset($smarty->_cache_info['insert_tags'][$_name])) {
  6795. +            $smarty->_cache_info['insert_tags'][$_name] = array('insert',
  6796. +                                                             $_name,
  6797. +                                                             $smarty->_plugins['insert'][$_name][1],
  6798. +                                                             $smarty->_plugins['insert'][$_name][2],
  6799. +                                                             !empty($params['args']['script']) ? true : false);
  6800. +        }
  6801. +        return $smarty->_smarty_md5."{insert_cache $_arg_string}".$smarty->_smarty_md5;
  6802. +    } else {
  6803. +        if (isset($params['args']['script'])) {
  6804. +            $_params = array('resource_name' => $smarty->_dequote($params['args']['script']));
  6805. +            require_once(SMARTY_CORE_DIR . 'core.get_php_resource.php');
  6806. +            if(!smarty_core_get_php_resource($_params, $smarty)) {
  6807. +                return false;
  6808. +            }
  6809. +
  6810. +            if ($_params['resource_type'] == 'file') {
  6811. +                $smarty->_include($_params['php_resource'], true);
  6812. +            } else {
  6813. +                $smarty->_eval($_params['php_resource']);
  6814. +            }
  6815. +            unset($params['args']['script']);
  6816. +        }
  6817. +
  6818. +        $_funcname = $smarty->_plugins['insert'][$params['args']['name']][0];
  6819. +        $_content = $_funcname($params['args'], $smarty);
  6820. +        if ($smarty->debugging) {
  6821. +            $_params = array();
  6822. +            require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
  6823. +            $smarty->_smarty_debug_info[] = array('type'      => 'insert',
  6824. +                                                'filename'  => 'insert_'.$params['args']['name'],
  6825. +                                                'depth'     => $smarty->_inclusion_depth,
  6826. +                                                'exec_time' => smarty_core_get_microtime($_params, $smarty) - $_debug_start_time);
  6827. +        }
  6828. +
  6829. +        if (!empty($params['args']["assign"])) {
  6830. +            $smarty->assign($params['args']["assign"], $_content);
  6831. +        } else {
  6832. +            return $_content;
  6833. +        }
  6834. +    }
  6835. +}
  6836. +
  6837. +/* vim: set expandtab: */
  6838. +
  6839. +?>
  6840. diff --git a/library/smarty/internals/core.smarty_include_php.php b/library/smarty/internals/core.smarty_include_php.php
  6841. new file mode 100644
  6842. --- /dev/null
  6843. +++ b/library/smarty/internals/core.smarty_include_php.php
  6844. @@ -0,0 +1,50 @@
  6845. +<?php
  6846. +/**
  6847. + * Smarty plugin
  6848. + * @package Smarty
  6849. + * @subpackage plugins
  6850. + */
  6851. +
  6852. +/**
  6853. + * called for included php files within templates
  6854. + *
  6855. + * @param string $smarty_file
  6856. + * @param string $smarty_assign variable to assign the included template's
  6857. + *               output into
  6858. + * @param boolean $smarty_once uses include_once if this is true
  6859. + * @param array $smarty_include_vars associative array of vars from
  6860. + *              {include file="blah" var=$var}
  6861. + */
  6862. +
  6863. +//  $file, $assign, $once, $_smarty_include_vars
  6864. +
  6865. +function smarty_core_smarty_include_php($params, &$smarty)
  6866. +{
  6867. +    $_params = array('resource_name' => $params['smarty_file']);
  6868. +    require_once(SMARTY_CORE_DIR . 'core.get_php_resource.php');
  6869. +    smarty_core_get_php_resource($_params, $smarty);
  6870. +    $_smarty_resource_type = $_params['resource_type'];
  6871. +    $_smarty_php_resource = $_params['php_resource'];
  6872. +
  6873. +    if (!empty($params['smarty_assign'])) {
  6874. +        ob_start();
  6875. +        if ($_smarty_resource_type == 'file') {
  6876. +            $smarty->_include($_smarty_php_resource, $params['smarty_once'], $params['smarty_include_vars']);
  6877. +        } else {
  6878. +            $smarty->_eval($_smarty_php_resource, $params['smarty_include_vars']);
  6879. +        }
  6880. +        $smarty->assign($params['smarty_assign'], ob_get_contents());
  6881. +        ob_end_clean();
  6882. +    } else {
  6883. +        if ($_smarty_resource_type == 'file') {
  6884. +            $smarty->_include($_smarty_php_resource, $params['smarty_once'], $params['smarty_include_vars']);
  6885. +        } else {
  6886. +            $smarty->_eval($_smarty_php_resource, $params['smarty_include_vars']);
  6887. +        }
  6888. +    }
  6889. +}
  6890. +
  6891. +
  6892. +/* vim: set expandtab: */
  6893. +
  6894. +?>
  6895. diff --git a/library/smarty/internals/core.write_cache_file.php b/library/smarty/internals/core.write_cache_file.php
  6896. new file mode 100644
  6897. --- /dev/null
  6898. +++ b/library/smarty/internals/core.write_cache_file.php
  6899. @@ -0,0 +1,96 @@
  6900. +<?php
  6901. +/**
  6902. + * Smarty plugin
  6903. + * @package Smarty
  6904. + * @subpackage plugins
  6905. + */
  6906. +
  6907. +/**
  6908. + * Prepend the cache information to the cache file
  6909. + * and write it
  6910. + *
  6911. + * @param string $tpl_file
  6912. + * @param string $cache_id
  6913. + * @param string $compile_id
  6914. + * @param string $results
  6915. + * @return true|null
  6916. + */
  6917. +
  6918. + // $tpl_file, $cache_id, $compile_id, $results
  6919. +
  6920. +function smarty_core_write_cache_file($params, &$smarty)
  6921. +{
  6922. +
  6923. +    // put timestamp in cache header
  6924. +    $smarty->_cache_info['timestamp'] = time();
  6925. +    if ($smarty->cache_lifetime > -1){
  6926. +        // expiration set
  6927. +        $smarty->_cache_info['expires'] = $smarty->_cache_info['timestamp'] + $smarty->cache_lifetime;
  6928. +    } else {
  6929. +        // cache will never expire
  6930. +        $smarty->_cache_info['expires'] = -1;
  6931. +    }
  6932. +
  6933. +    // collapse nocache.../nocache-tags
  6934. +    if (preg_match_all('!\{(/?)nocache\:[0-9a-f]{32}#\d+\}!', $params['results'], $match, PREG_PATTERN_ORDER)) {
  6935. +        // remove everything between every pair of outermost noache.../nocache-tags
  6936. +        // and replace it by a single nocache-tag
  6937. +        // this new nocache-tag will be replaced by dynamic contents in
  6938. +        // smarty_core_process_compiled_includes() on a cache-read
  6939. +        
  6940. +        $match_count = count($match[0]);
  6941. +        $results = preg_split('!(\{/?nocache\:[0-9a-f]{32}#\d+\})!', $params['results'], -1, PREG_SPLIT_DELIM_CAPTURE);
  6942. +        
  6943. +        $level = 0;
  6944. +        $j = 0;
  6945. +        for ($i=0, $results_count = count($results); $i < $results_count && $j < $match_count; $i++) {
  6946. +            if ($results[$i] == $match[0][$j]) {
  6947. +                // nocache tag
  6948. +                if ($match[1][$j]) { // closing tag
  6949. +                    $level--;
  6950. +                    unset($results[$i]);
  6951. +                } else { // opening tag
  6952. +                    if ($level++ > 0) unset($results[$i]);
  6953. +                }
  6954. +                $j++;
  6955. +            } elseif ($level > 0) {
  6956. +                unset($results[$i]);
  6957. +            }
  6958. +        }
  6959. +        $params['results'] = implode('', $results);
  6960. +    }
  6961. +    $smarty->_cache_info['cache_serials'] = $smarty->_cache_serials;
  6962. +
  6963. +    // prepend the cache header info into cache file
  6964. +    $_cache_info = serialize($smarty->_cache_info);
  6965. +    $params['results'] = strlen($_cache_info) . "\n" . $_cache_info . $params['results'];
  6966. +
  6967. +    if (!empty($smarty->cache_handler_func)) {
  6968. +        // use cache_handler function
  6969. +        call_user_func_array($smarty->cache_handler_func,
  6970. +                             array('write', &$smarty, &$params['results'], $params['tpl_file'], $params['cache_id'], $params['compile_id'], $smarty->_cache_info['expires']));
  6971. +    } else {
  6972. +        // use local cache file
  6973. +
  6974. +        if(!@is_writable($smarty->cache_dir)) {
  6975. +            // cache_dir not writable, see if it exists
  6976. +            if(!@is_dir($smarty->cache_dir)) {
  6977. +                $smarty->trigger_error('the $cache_dir \'' . $smarty->cache_dir . '\' does not exist, or is not a directory.', E_USER_ERROR);
  6978. +                return false;
  6979. +            }
  6980. +            $smarty->trigger_error('unable to write to $cache_dir \'' . realpath($smarty->cache_dir) . '\'. Be sure $cache_dir is writable by the web server user.', E_USER_ERROR);
  6981. +            return false;
  6982. +        }
  6983. +
  6984. +        $_auto_id = $smarty->_get_auto_id($params['cache_id'], $params['compile_id']);
  6985. +        $_cache_file = $smarty->_get_auto_filename($smarty->cache_dir, $params['tpl_file'], $_auto_id);
  6986. +        $_params = array('filename' => $_cache_file, 'contents' => $params['results'], 'create_dirs' => true);
  6987. +        require_once(SMARTY_CORE_DIR . 'core.write_file.php');
  6988. +        smarty_core_write_file($_params, $smarty);
  6989. +        return true;
  6990. +    }
  6991. +}
  6992. +
  6993. +/* vim: set expandtab: */
  6994. +
  6995. +?>
  6996. diff --git a/library/smarty/internals/core.write_compiled_include.php b/library/smarty/internals/core.write_compiled_include.php
  6997. new file mode 100644
  6998. --- /dev/null
  6999. +++ b/library/smarty/internals/core.write_compiled_include.php
  7000. @@ -0,0 +1,91 @@
  7001. +<?php
  7002. +/**
  7003. + * Smarty plugin
  7004. + * @package Smarty
  7005. + * @subpackage plugins
  7006. + */
  7007. +
  7008. +/**
  7009. + * Extract non-cacheable parts out of compiled template and write it
  7010. + *
  7011. + * @param string $compile_path
  7012. + * @param string $template_compiled
  7013. + * @return boolean
  7014. + */
  7015. +
  7016. +function smarty_core_write_compiled_include($params, &$smarty)
  7017. +{
  7018. +    $_tag_start = 'if \(\$this->caching && \!\$this->_cache_including\)\: echo \'\{nocache\:('.$params['cache_serial'].')#(\d+)\}\'; endif;';
  7019. +    $_tag_end   = 'if \(\$this->caching && \!\$this->_cache_including\)\: echo \'\{/nocache\:(\\2)#(\\3)\}\'; endif;';
  7020. +
  7021. +    preg_match_all('!('.$_tag_start.'(.*)'.$_tag_end.')!Us',
  7022. +                   $params['compiled_content'], $_match_source, PREG_SET_ORDER);
  7023. +    
  7024. +    // no nocache-parts found: done
  7025. +    if (count($_match_source)==0) return;
  7026. +
  7027. +    // convert the matched php-code to functions
  7028. +    $_include_compiled =  "<?php /* Smarty version ".$smarty->_version.", created on ".strftime("%Y-%m-%d %H:%M:%S")."\n";
  7029. +    $_include_compiled .= "         compiled from " . strtr(urlencode($params['resource_name']), array('%2F'=>'/', '%3A'=>':')) . " */\n\n";
  7030. +
  7031. +    $_compile_path = $params['include_file_path'];
  7032. +
  7033. +    $smarty->_cache_serials[$_compile_path] = $params['cache_serial'];
  7034. +    $_include_compiled .= "\$this->_cache_serials['".$_compile_path."'] = '".$params['cache_serial']."';\n\n?>";
  7035. +
  7036. +    $_include_compiled .= $params['plugins_code'];
  7037. +    $_include_compiled .= "<?php";
  7038. +
  7039. +    $this_varname = ((double)phpversion() >= 5.0) ? '_smarty' : 'this';
  7040. +    for ($_i = 0, $_for_max = count($_match_source); $_i < $_for_max; $_i++) {
  7041. +        $_match =& $_match_source[$_i];
  7042. +        $source = $_match[4];
  7043. +        if ($this_varname == '_smarty') {
  7044. +            /* rename $this to $_smarty in the sourcecode */
  7045. +            $tokens = token_get_all('<?php ' . $_match[4]);
  7046. +
  7047. +            /* remove trailing <?php */
  7048. +            $open_tag = '';
  7049. +            while ($tokens) {
  7050. +                $token = array_shift($tokens);
  7051. +                if (is_array($token)) {
  7052. +                    $open_tag .= $token[1];
  7053. +                } else {
  7054. +                    $open_tag .= $token;
  7055. +                }
  7056. +                if ($open_tag == '<?php ') break;
  7057. +            }
  7058. +
  7059. +            for ($i=0, $count = count($tokens); $i < $count; $i++) {
  7060. +                if (is_array($tokens[$i])) {
  7061. +                    if ($tokens[$i][0] == T_VARIABLE && $tokens[$i][1] == '$this') {
  7062. +                        $tokens[$i] = '$' . $this_varname;
  7063. +                    } else {
  7064. +                        $tokens[$i] = $tokens[$i][1];
  7065. +                    }                  
  7066. +                }
  7067. +            }
  7068. +            $source = implode('', $tokens);
  7069. +        }
  7070. +
  7071. +        /* add function to compiled include */
  7072. +        $_include_compiled .= "
  7073. +function _smarty_tplfunc_$_match[2]_$_match[3](&\$$this_varname)
  7074. +{
  7075. +$source
  7076. +}
  7077. +
  7078. +";
  7079. +    }
  7080. +    $_include_compiled .= "\n\n?>\n";
  7081. +
  7082. +    $_params = array('filename' => $_compile_path,
  7083. +                     'contents' => $_include_compiled, 'create_dirs' => true);
  7084. +
  7085. +    require_once(SMARTY_CORE_DIR . 'core.write_file.php');
  7086. +    smarty_core_write_file($_params, $smarty);
  7087. +    return true;
  7088. +}
  7089. +
  7090. +
  7091. +?>
  7092. diff --git a/library/smarty/internals/core.write_compiled_resource.php b/library/smarty/internals/core.write_compiled_resource.php
  7093. new file mode 100644
  7094. --- /dev/null
  7095. +++ b/library/smarty/internals/core.write_compiled_resource.php
  7096. @@ -0,0 +1,35 @@
  7097. +<?php
  7098. +/**
  7099. + * Smarty plugin
  7100. + * @package Smarty
  7101. + * @subpackage plugins
  7102. + */
  7103. +
  7104. +/**
  7105. + * write the compiled resource
  7106. + *
  7107. + * @param string $compile_path
  7108. + * @param string $compiled_content
  7109. + * @return true
  7110. + */
  7111. +function smarty_core_write_compiled_resource($params, &$smarty)
  7112. +{
  7113. +    if(!@is_writable($smarty->compile_dir)) {
  7114. +        // compile_dir not writable, see if it exists
  7115. +        if(!@is_dir($smarty->compile_dir)) {
  7116. +            $smarty->trigger_error('the $compile_dir \'' . $smarty->compile_dir . '\' does not exist, or is not a directory.', E_USER_ERROR);
  7117. +            return false;
  7118. +        }
  7119. +        $smarty->trigger_error('unable to write to $compile_dir \'' . realpath($smarty->compile_dir) . '\'. Be sure $compile_dir is writable by the web server user.', E_USER_ERROR);
  7120. +        return false;
  7121. +    }
  7122. +
  7123. +    $_params = array('filename' => $params['compile_path'], 'contents' => $params['compiled_content'], 'create_dirs' => true);
  7124. +    require_once(SMARTY_CORE_DIR . 'core.write_file.php');
  7125. +    smarty_core_write_file($_params, $smarty);
  7126. +    return true;
  7127. +}
  7128. +
  7129. +/* vim: set expandtab: */
  7130. +
  7131. +?>
  7132. diff --git a/library/smarty/internals/core.write_file.php b/library/smarty/internals/core.write_file.php
  7133. new file mode 100644
  7134. --- /dev/null
  7135. +++ b/library/smarty/internals/core.write_file.php
  7136. @@ -0,0 +1,54 @@
  7137. +<?php
  7138. +/**
  7139. + * Smarty plugin
  7140. + * @package Smarty
  7141. + * @subpackage plugins
  7142. + */
  7143. +
  7144. +/**
  7145. + * write out a file to disk
  7146. + *
  7147. + * @param string $filename
  7148. + * @param string $contents
  7149. + * @param boolean $create_dirs
  7150. + * @return boolean
  7151. + */
  7152. +function smarty_core_write_file($params, &$smarty)
  7153. +{
  7154. +    $_dirname = dirname($params['filename']);
  7155. +
  7156. +    if ($params['create_dirs']) {
  7157. +        $_params = array('dir' => $_dirname);
  7158. +        require_once(SMARTY_CORE_DIR . 'core.create_dir_structure.php');
  7159. +        smarty_core_create_dir_structure($_params, $smarty);
  7160. +    }
  7161. +
  7162. +    // write to tmp file, then rename it to avoid file locking race condition
  7163. +    $_tmp_file = tempnam($_dirname, 'wrt');
  7164. +
  7165. +    if (!($fd = @fopen($_tmp_file, 'wb'))) {
  7166. +        $_tmp_file = $_dirname . DIRECTORY_SEPARATOR . uniqid('wrt');
  7167. +        if (!($fd = @fopen($_tmp_file, 'wb'))) {
  7168. +            $smarty->trigger_error("problem writing temporary file '$_tmp_file'");
  7169. +            return false;
  7170. +        }
  7171. +    }
  7172. +
  7173. +    fwrite($fd, $params['contents']);
  7174. +    fclose($fd);
  7175. +
  7176. +    if (DIRECTORY_SEPARATOR == '\\' || !@rename($_tmp_file, $params['filename'])) {
  7177. +        // On platforms and filesystems that cannot overwrite with rename()
  7178. +        // delete the file before renaming it -- because windows always suffers
  7179. +        // this, it is short-circuited to avoid the initial rename() attempt
  7180. +        @unlink($params['filename']);
  7181. +        @rename($_tmp_file, $params['filename']);
  7182. +    }
  7183. +    @chmod($params['filename'], $smarty->_file_perms);
  7184. +
  7185. +    return true;
  7186. +}
  7187. +
  7188. +/* vim: set expandtab: */
  7189. +
  7190. +?>
  7191. \ No newline at end of file
  7192. diff --git a/library/smarty/plugins/block.textformat.php b/library/smarty/plugins/block.textformat.php
  7193. new file mode 100644
  7194. --- /dev/null
  7195. +++ b/library/smarty/plugins/block.textformat.php
  7196. @@ -0,0 +1,103 @@
  7197. +<?php
  7198. +/**
  7199. + * Smarty plugin
  7200. + * @package Smarty
  7201. + * @subpackage plugins
  7202. + */
  7203. +
  7204. +/**
  7205. + * Smarty {textformat}{/textformat} block plugin
  7206. + *
  7207. + * Type:     block function<br>
  7208. + * Name:     textformat<br>
  7209. + * Purpose:  format text a certain way with preset styles
  7210. + *           or custom wrap/indent settings<br>
  7211. + * @link http://smarty.php.net/manual/en/language.function.textformat.php {textformat}
  7212. + *       (Smarty online manual)
  7213. + * @param array
  7214. + * <pre>
  7215. + * Params:   style: string (email)
  7216. + *           indent: integer (0)
  7217. + *           wrap: integer (80)
  7218. + *           wrap_char string ("\n")
  7219. + *           indent_char: string (" ")
  7220. + *           wrap_boundary: boolean (true)
  7221. + * </pre>
  7222. + * @author Monte Ohrt <monte at ohrt dot com>
  7223. + * @param string contents of the block
  7224. + * @param Smarty clever simulation of a method
  7225. + * @return string string $content re-formatted
  7226. + */
  7227. +function smarty_block_textformat($params, $content, &$smarty)
  7228. +{
  7229. +    if (is_null($content)) {
  7230. +        return;
  7231. +    }
  7232. +
  7233. +    $style = null;
  7234. +    $indent = 0;
  7235. +    $indent_first = 0;
  7236. +    $indent_char = ' ';
  7237. +    $wrap = 80;
  7238. +    $wrap_char = "\n";
  7239. +    $wrap_cut = false;
  7240. +    $assign = null;
  7241. +    
  7242. +    foreach ($params as $_key => $_val) {
  7243. +        switch ($_key) {
  7244. +            case 'style':
  7245. +            case 'indent_char':
  7246. +            case 'wrap_char':
  7247. +            case 'assign':
  7248. +                $$_key = (string)$_val;
  7249. +                break;
  7250. +
  7251. +            case 'indent':
  7252. +            case 'indent_first':
  7253. +            case 'wrap':
  7254. +                $$_key = (int)$_val;
  7255. +                break;
  7256. +
  7257. +            case 'wrap_cut':
  7258. +                $$_key = (bool)$_val;
  7259. +                break;
  7260. +
  7261. +            default:
  7262. +                $smarty->trigger_error("textformat: unknown attribute '$_key'");
  7263. +        }
  7264. +    }
  7265. +
  7266. +    if ($style == 'email') {
  7267. +        $wrap = 72;
  7268. +    }
  7269. +
  7270. +    // split into paragraphs
  7271. +    $_paragraphs = preg_split('![\r\n][\r\n]!',$content);
  7272. +    $_output = '';
  7273. +
  7274. +    for($_x = 0, $_y = count($_paragraphs); $_x < $_y; $_x++) {
  7275. +        if ($_paragraphs[$_x] == '') {
  7276. +            continue;
  7277. +        }
  7278. +        // convert mult. spaces & special chars to single space
  7279. +        $_paragraphs[$_x] = preg_replace(array('!\s+!','!(^\s+)|(\s+$)!'), array(' ',''), $_paragraphs[$_x]);
  7280. +        // indent first line
  7281. +        if($indent_first > 0) {
  7282. +            $_paragraphs[$_x] = str_repeat($indent_char, $indent_first) . $_paragraphs[$_x];
  7283. +        }
  7284. +        // wordwrap sentences
  7285. +        $_paragraphs[$_x] = wordwrap($_paragraphs[$_x], $wrap - $indent, $wrap_char, $wrap_cut);
  7286. +        // indent lines
  7287. +        if($indent > 0) {
  7288. +            $_paragraphs[$_x] = preg_replace('!^!m', str_repeat($indent_char, $indent), $_paragraphs[$_x]);
  7289. +        }
  7290. +    }
  7291. +    $_output = implode($wrap_char . $wrap_char, $_paragraphs);
  7292. +
  7293. +    return $assign ? $smarty->assign($assign, $_output) : $_output;
  7294. +
  7295. +}
  7296. +
  7297. +/* vim: set expandtab: */
  7298. +
  7299. +?>
  7300. diff --git a/library/smarty/plugins/compiler.assign.php b/library/smarty/plugins/compiler.assign.php
  7301. new file mode 100644
  7302. --- /dev/null
  7303. +++ b/library/smarty/plugins/compiler.assign.php
  7304. @@ -0,0 +1,40 @@
  7305. +<?php
  7306. +/**
  7307. + * Smarty plugin
  7308. + * @package Smarty
  7309. + * @subpackage plugins
  7310. + */
  7311. +
  7312. +/**
  7313. + * Smarty {assign} compiler function plugin
  7314. + *
  7315. + * Type:     compiler function<br>
  7316. + * Name:     assign<br>
  7317. + * Purpose:  assign a value to a template variable
  7318. + * @link http://smarty.php.net/manual/en/language.custom.functions.php#LANGUAGE.FUNCTION.ASSIGN {assign}
  7319. + *       (Smarty online manual)
  7320. + * @author Monte Ohrt <monte at ohrt dot com> (initial author)
  7321. + * @author messju mohr <messju at lammfellpuschen dot de> (conversion to compiler function)
  7322. + * @param string containing var-attribute and value-attribute
  7323. + * @param Smarty_Compiler
  7324. + */
  7325. +function smarty_compiler_assign($tag_attrs, &$compiler)
  7326. +{
  7327. +    $_params = $compiler->_parse_attrs($tag_attrs);
  7328. +
  7329. +    if (!isset($_params['var'])) {
  7330. +        $compiler->_syntax_error("assign: missing 'var' parameter", E_USER_WARNING);
  7331. +        return;
  7332. +    }
  7333. +
  7334. +    if (!isset($_params['value'])) {
  7335. +        $compiler->_syntax_error("assign: missing 'value' parameter", E_USER_WARNING);
  7336. +        return;
  7337. +    }
  7338. +
  7339. +    return "\$this->assign({$_params['var']}, {$_params['value']});";
  7340. +}
  7341. +
  7342. +/* vim: set expandtab: */
  7343. +
  7344. +?>
  7345. diff --git a/library/smarty/plugins/function.assign_debug_info.php b/library/smarty/plugins/function.assign_debug_info.php
  7346. new file mode 100644
  7347. --- /dev/null
  7348. +++ b/library/smarty/plugins/function.assign_debug_info.php
  7349. @@ -0,0 +1,40 @@
  7350. +<?php
  7351. +/**
  7352. + * Smarty plugin
  7353. + * @package Smarty
  7354. + * @subpackage plugins
  7355. + */
  7356. +
  7357. +/**
  7358. + * Smarty {assign_debug_info} function plugin
  7359. + *
  7360. + * Type:     function<br>
  7361. + * Name:     assign_debug_info<br>
  7362. + * Purpose:  assign debug info to the template<br>
  7363. + * @author Monte Ohrt <monte at ohrt dot com>
  7364. + * @param array unused in this plugin, this plugin uses {@link Smarty::$_config},
  7365. + *              {@link Smarty::$_tpl_vars} and {@link Smarty::$_smarty_debug_info}
  7366. + * @param Smarty
  7367. + */
  7368. +function smarty_function_assign_debug_info($params, &$smarty)
  7369. +{
  7370. +    $assigned_vars = $smarty->_tpl_vars;
  7371. +    ksort($assigned_vars);
  7372. +    if (@is_array($smarty->_config[0])) {
  7373. +        $config_vars = $smarty->_config[0];
  7374. +        ksort($config_vars);
  7375. +        $smarty->assign("_debug_config_keys", array_keys($config_vars));
  7376. +        $smarty->assign("_debug_config_vals", array_values($config_vars));
  7377. +    }
  7378. +    
  7379. +    $included_templates = $smarty->_smarty_debug_info;
  7380. +    
  7381. +    $smarty->assign("_debug_keys", array_keys($assigned_vars));
  7382. +    $smarty->assign("_debug_vals", array_values($assigned_vars));
  7383. +    
  7384. +    $smarty->assign("_debug_tpls", $included_templates);
  7385. +}
  7386. +
  7387. +/* vim: set expandtab: */
  7388. +
  7389. +?>
  7390. diff --git a/library/smarty/plugins/function.config_load.php b/library/smarty/plugins/function.config_load.php
  7391. new file mode 100644
  7392. --- /dev/null
  7393. +++ b/library/smarty/plugins/function.config_load.php
  7394. @@ -0,0 +1,142 @@
  7395. +<?php
  7396. +/**
  7397. + * Smarty plugin
  7398. + * @package Smarty
  7399. + * @subpackage plugins
  7400. + */
  7401. +
  7402. +/**
  7403. + * Smarty {config_load} function plugin
  7404. + *
  7405. + * Type:     function<br>
  7406. + * Name:     config_load<br>
  7407. + * Purpose:  load config file vars
  7408. + * @link http://smarty.php.net/manual/en/language.function.config.load.php {config_load}
  7409. + *       (Smarty online manual)
  7410. + * @author Monte Ohrt <monte at ohrt dot com>
  7411. + * @author messju mohr <messju at lammfellpuschen dot de> (added use of resources)
  7412. + * @param array Format:
  7413. + * <pre>
  7414. + * array('file' => required config file name,
  7415. + *       'section' => optional config file section to load
  7416. + *       'scope' => local/parent/global
  7417. + *       'global' => overrides scope, setting to parent if true)
  7418. + * </pre>
  7419. + * @param Smarty
  7420. + */
  7421. +function smarty_function_config_load($params, &$smarty)
  7422. +{
  7423. +        if ($smarty->debugging) {
  7424. +            $_params = array();
  7425. +            require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
  7426. +            $_debug_start_time = smarty_core_get_microtime($_params, $smarty);
  7427. +        }
  7428. +
  7429. +        $_file = isset($params['file']) ? $smarty->_dequote($params['file']) : null;
  7430. +        $_section = isset($params['section']) ? $smarty->_dequote($params['section']) : null;
  7431. +        $_scope = isset($params['scope']) ? $smarty->_dequote($params['scope']) : 'global';
  7432. +        $_global = isset($params['global']) ? $smarty->_dequote($params['global']) : false;
  7433. +
  7434. +        if (!isset($_file) || strlen($_file) == 0) {
  7435. +            $smarty->trigger_error("missing 'file' attribute in config_load tag", E_USER_ERROR, __FILE__, __LINE__);
  7436. +        }
  7437. +
  7438. +        if (isset($_scope)) {
  7439. +            if ($_scope != 'local' &&
  7440. +                $_scope != 'parent' &&
  7441. +                $_scope != 'global') {
  7442. +                $smarty->trigger_error("invalid 'scope' attribute value", E_USER_ERROR, __FILE__, __LINE__);
  7443. +            }
  7444. +        } else {
  7445. +            if ($_global) {
  7446. +                $_scope = 'parent';
  7447. +            } else {
  7448. +                $_scope = 'local';
  7449. +            }
  7450. +        }
  7451. +
  7452. +        $_params = array('resource_name' => $_file,
  7453. +                         'resource_base_path' => $smarty->config_dir,
  7454. +                         'get_source' => false);
  7455. +        $smarty->_parse_resource_name($_params);
  7456. +        $_file_path = $_params['resource_type'] . ':' . $_params['resource_name'];
  7457. +        if (isset($_section))
  7458. +            $_compile_file = $smarty->_get_compile_path($_file_path.'|'.$_section);
  7459. +        else
  7460. +            $_compile_file = $smarty->_get_compile_path($_file_path);
  7461. +
  7462. +        if($smarty->force_compile || !file_exists($_compile_file)) {
  7463. +            $_compile = true;
  7464. +        } elseif ($smarty->compile_check) {
  7465. +            $_params = array('resource_name' => $_file,
  7466. +                             'resource_base_path' => $smarty->config_dir,
  7467. +                             'get_source' => false);
  7468. +            $_compile = $smarty->_fetch_resource_info($_params) &&
  7469. +                $_params['resource_timestamp'] > filemtime($_compile_file);
  7470. +        } else {
  7471. +            $_compile = false;
  7472. +        }
  7473. +
  7474. +        if($_compile) {
  7475. +            // compile config file
  7476. +            if(!is_object($smarty->_conf_obj)) {
  7477. +                require_once SMARTY_DIR . $smarty->config_class . '.class.php';
  7478. +                $smarty->_conf_obj = new $smarty->config_class();
  7479. +                $smarty->_conf_obj->overwrite = $smarty->config_overwrite;
  7480. +                $smarty->_conf_obj->booleanize = $smarty->config_booleanize;
  7481. +                $smarty->_conf_obj->read_hidden = $smarty->config_read_hidden;
  7482. +                $smarty->_conf_obj->fix_newlines = $smarty->config_fix_newlines;
  7483. +            }
  7484. +
  7485. +            $_params = array('resource_name' => $_file,
  7486. +                             'resource_base_path' => $smarty->config_dir,
  7487. +                             $_params['get_source'] = true);
  7488. +            if (!$smarty->_fetch_resource_info($_params)) {
  7489. +                return;
  7490. +            }
  7491. +            $smarty->_conf_obj->set_file_contents($_file, $_params['source_content']);
  7492. +            $_config_vars = array_merge($smarty->_conf_obj->get($_file),
  7493. +                    $smarty->_conf_obj->get($_file, $_section));
  7494. +            if(function_exists('var_export')) {
  7495. +                $_output = '<?php $_config_vars = ' . var_export($_config_vars, true) . '; ?>';
  7496. +            } else {
  7497. +                $_output = '<?php $_config_vars = unserialize(\'' . strtr(serialize($_config_vars),array('\''=>'\\\'', '\\'=>'\\\\')) . '\'); ?>';
  7498. +            }
  7499. +            $_params = (array('compile_path' => $_compile_file, 'compiled_content' => $_output, 'resource_timestamp' => $_params['resource_timestamp']));
  7500. +            require_once(SMARTY_CORE_DIR . 'core.write_compiled_resource.php');
  7501. +            smarty_core_write_compiled_resource($_params, $smarty);
  7502. +        } else {
  7503. +            include($_compile_file);
  7504. +        }
  7505. +
  7506. +        if ($smarty->caching) {
  7507. +            $smarty->_cache_info['config'][$_file] = true;
  7508. +        }
  7509. +
  7510. +        $smarty->_config[0]['vars'] = @array_merge($smarty->_config[0]['vars'], $_config_vars);
  7511. +        $smarty->_config[0]['files'][$_file] = true;
  7512. +
  7513. +        if ($_scope == 'parent') {
  7514. +                $smarty->_config[1]['vars'] = @array_merge($smarty->_config[1]['vars'], $_config_vars);
  7515. +                $smarty->_config[1]['files'][$_file] = true;
  7516. +        } else if ($_scope == 'global') {
  7517. +            for ($i = 1, $for_max = count($smarty->_config); $i < $for_max; $i++) {
  7518. +                $smarty->_config[$i]['vars'] = @array_merge($smarty->_config[$i]['vars'], $_config_vars);
  7519. +                $smarty->_config[$i]['files'][$_file] = true;
  7520. +            }
  7521. +        }
  7522. +
  7523. +        if ($smarty->debugging) {
  7524. +            $_params = array();
  7525. +            require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
  7526. +            $smarty->_smarty_debug_info[] = array('type'      => 'config',
  7527. +                                                'filename'  => $_file.' ['.$_section.'] '.$_scope,
  7528. +                                                'depth'     => $smarty->_inclusion_depth,
  7529. +                                                'exec_time' => smarty_core_get_microtime($_params, $smarty) - $_debug_start_time);
  7530. +        }
  7531. +
  7532. +}
  7533. +
  7534. +/* vim: set expandtab: */
  7535. +
  7536. +?>
  7537. diff --git a/library/smarty/plugins/function.counter.php b/library/smarty/plugins/function.counter.php
  7538. new file mode 100644
  7539. --- /dev/null
  7540. +++ b/library/smarty/plugins/function.counter.php
  7541. @@ -0,0 +1,80 @@
  7542. +<?php
  7543. +/**
  7544. + * Smarty plugin
  7545. + * @package Smarty
  7546. + * @subpackage plugins
  7547. + */
  7548. +
  7549. +
  7550. +/**
  7551. + * Smarty {counter} function plugin
  7552. + *
  7553. + * Type:     function<br>
  7554. + * Name:     counter<br>
  7555. + * Purpose:  print out a counter value
  7556. + * @author Monte Ohrt <monte at ohrt dot com>
  7557. + * @link http://smarty.php.net/manual/en/language.function.counter.php {counter}
  7558. + *       (Smarty online manual)
  7559. + * @param array parameters
  7560. + * @param Smarty
  7561. + * @return string|null
  7562. + */
  7563. +function smarty_function_counter($params, &$smarty)
  7564. +{
  7565. +    static $counters = array();
  7566. +
  7567. +    $name = (isset($params['name'])) ? $params['name'] : 'default';
  7568. +    if (!isset($counters[$name])) {
  7569. +        $counters[$name] = array(
  7570. +            'start'=>1,
  7571. +            'skip'=>1,
  7572. +            'direction'=>'up',
  7573. +            'count'=>1
  7574. +            );
  7575. +    }
  7576. +    $counter =& $counters[$name];
  7577. +
  7578. +    if (isset($params['start'])) {
  7579. +        $counter['start'] = $counter['count'] = (int)$params['start'];
  7580. +    }
  7581. +
  7582. +    if (!empty($params['assign'])) {
  7583. +        $counter['assign'] = $params['assign'];
  7584. +    }
  7585. +
  7586. +    if (isset($counter['assign'])) {
  7587. +        $smarty->assign($counter['assign'], $counter['count']);
  7588. +    }
  7589. +    
  7590. +    if (isset($params['print'])) {
  7591. +        $print = (bool)$params['print'];
  7592. +    } else {
  7593. +        $print = empty($counter['assign']);
  7594. +    }
  7595. +
  7596. +    if ($print) {
  7597. +        $retval = $counter['count'];
  7598. +    } else {
  7599. +        $retval = null;
  7600. +    }
  7601. +
  7602. +    if (isset($params['skip'])) {
  7603. +        $counter['skip'] = $params['skip'];
  7604. +    }
  7605. +    
  7606. +    if (isset($params['direction'])) {
  7607. +        $counter['direction'] = $params['direction'];
  7608. +    }
  7609. +
  7610. +    if ($counter['direction'] == "down")
  7611. +        $counter['count'] -= $counter['skip'];
  7612. +    else
  7613. +        $counter['count'] += $counter['skip'];
  7614. +    
  7615. +    return $retval;
  7616. +    
  7617. +}
  7618. +
  7619. +/* vim: set expandtab: */
  7620. +
  7621. +?>
  7622. diff --git a/library/smarty/plugins/function.cycle.php b/library/smarty/plugins/function.cycle.php
  7623. new file mode 100644
  7624. --- /dev/null
  7625. +++ b/library/smarty/plugins/function.cycle.php
  7626. @@ -0,0 +1,102 @@
  7627. +<?php
  7628. +/**
  7629. + * Smarty plugin
  7630. + * @package Smarty
  7631. + * @subpackage plugins
  7632. + */
  7633. +
  7634. +/**
  7635. + * Smarty {cycle} function plugin
  7636. + *
  7637. + * Type:     function<br>
  7638. + * Name:     cycle<br>
  7639. + * Date:     May 3, 2002<br>
  7640. + * Purpose:  cycle through given values<br>
  7641. + * Input:
  7642. + *         - name = name of cycle (optional)
  7643. + *         - values = comma separated list of values to cycle,
  7644. + *                    or an array of values to cycle
  7645. + *                    (this can be left out for subsequent calls)
  7646. + *         - reset = boolean - resets given var to true
  7647. + *         - print = boolean - print var or not. default is true
  7648. + *         - advance = boolean - whether or not to advance the cycle
  7649. + *         - delimiter = the value delimiter, default is ","
  7650. + *         - assign = boolean, assigns to template var instead of
  7651. + *                    printed.
  7652. + *
  7653. + * Examples:<br>
  7654. + * <pre>
  7655. + * {cycle values="#eeeeee,#d0d0d0d"}
  7656. + * {cycle name=row values="one,two,three" reset=true}
  7657. + * {cycle name=row}
  7658. + * </pre>
  7659. + * @link http://smarty.php.net/manual/en/language.function.cycle.php {cycle}
  7660. + *       (Smarty online manual)
  7661. + * @author Monte Ohrt <monte at ohrt dot com>
  7662. + * @author credit to Mark Priatel <[email protected]>
  7663. + * @author credit to Gerard <[email protected]>
  7664. + * @author credit to Jason Sweat <[email protected]>
  7665. + * @version  1.3
  7666. + * @param array
  7667. + * @param Smarty
  7668. + * @return string|null
  7669. + */
  7670. +function smarty_function_cycle($params, &$smarty)
  7671. +{
  7672. +    static $cycle_vars;
  7673. +    
  7674. +    $name = (empty($params['name'])) ? 'default' : $params['name'];
  7675. +    $print = (isset($params['print'])) ? (bool)$params['print'] : true;
  7676. +    $advance = (isset($params['advance'])) ? (bool)$params['advance'] : true;
  7677. +    $reset = (isset($params['reset'])) ? (bool)$params['reset'] : false;
  7678. +            
  7679. +    if (!in_array('values', array_keys($params))) {
  7680. +        if(!isset($cycle_vars[$name]['values'])) {
  7681. +            $smarty->trigger_error("cycle: missing 'values' parameter");
  7682. +            return;
  7683. +        }
  7684. +    } else {
  7685. +        if(isset($cycle_vars[$name]['values'])
  7686. +            && $cycle_vars[$name]['values'] != $params['values'] ) {
  7687. +            $cycle_vars[$name]['index'] = 0;
  7688. +        }
  7689. +        $cycle_vars[$name]['values'] = $params['values'];
  7690. +    }
  7691. +
  7692. +    $cycle_vars[$name]['delimiter'] = (isset($params['delimiter'])) ? $params['delimiter'] : ',';
  7693. +    
  7694. +    if(is_array($cycle_vars[$name]['values'])) {
  7695. +        $cycle_array = $cycle_vars[$name]['values'];
  7696. +    } else {
  7697. +        $cycle_array = explode($cycle_vars[$name]['delimiter'],$cycle_vars[$name]['values']);
  7698. +    }
  7699. +    
  7700. +    if(!isset($cycle_vars[$name]['index']) || $reset ) {
  7701. +        $cycle_vars[$name]['index'] = 0;
  7702. +    }
  7703. +    
  7704. +    if (isset($params['assign'])) {
  7705. +        $print = false;
  7706. +        $smarty->assign($params['assign'], $cycle_array[$cycle_vars[$name]['index']]);
  7707. +    }
  7708. +        
  7709. +    if($print) {
  7710. +        $retval = $cycle_array[$cycle_vars[$name]['index']];
  7711. +    } else {
  7712. +        $retval = null;
  7713. +    }
  7714. +
  7715. +    if($advance) {
  7716. +        if ( $cycle_vars[$name]['index'] >= count($cycle_array) -1 ) {
  7717. +            $cycle_vars[$name]['index'] = 0;
  7718. +        } else {
  7719. +            $cycle_vars[$name]['index']++;
  7720. +        }
  7721. +    }
  7722. +    
  7723. +    return $retval;
  7724. +}
  7725. +
  7726. +/* vim: set expandtab: */
  7727. +
  7728. +?>
  7729. diff --git a/library/smarty/plugins/function.debug.php b/library/smarty/plugins/function.debug.php
  7730. new file mode 100644
  7731. --- /dev/null
  7732. +++ b/library/smarty/plugins/function.debug.php
  7733. @@ -0,0 +1,35 @@
  7734. +<?php
  7735. +/**
  7736. + * Smarty plugin
  7737. + * @package Smarty
  7738. + * @subpackage plugins
  7739. + */
  7740. +
  7741. +
  7742. +/**
  7743. + * Smarty {debug} function plugin
  7744. + *
  7745. + * Type:     function<br>
  7746. + * Name:     debug<br>
  7747. + * Date:     July 1, 2002<br>
  7748. + * Purpose:  popup debug window
  7749. + * @link http://smarty.php.net/manual/en/language.function.debug.php {debug}
  7750. + *       (Smarty online manual)
  7751. + * @author   Monte Ohrt <monte at ohrt dot com>
  7752. + * @version  1.0
  7753. + * @param array
  7754. + * @param Smarty
  7755. + * @return string output from {@link Smarty::_generate_debug_output()}
  7756. + */
  7757. +function smarty_function_debug($params, &$smarty)
  7758. +{
  7759. +    if (isset($params['output'])) {
  7760. +        $smarty->assign('_smarty_debug_output', $params['output']);
  7761. +    }
  7762. +    require_once(SMARTY_CORE_DIR . 'core.display_debug_console.php');
  7763. +    return smarty_core_display_debug_console(null, $smarty);
  7764. +}
  7765. +
  7766. +/* vim: set expandtab: */
  7767. +
  7768. +?>
  7769. diff --git a/library/smarty/plugins/function.eval.php b/library/smarty/plugins/function.eval.php
  7770. new file mode 100644
  7771. --- /dev/null
  7772. +++ b/library/smarty/plugins/function.eval.php
  7773. @@ -0,0 +1,49 @@
  7774. +<?php
  7775. +/**
  7776. + * Smarty plugin
  7777. + * @package Smarty
  7778. + * @subpackage plugins
  7779. + */
  7780. +
  7781. +
  7782. +/**
  7783. + * Smarty {eval} function plugin
  7784. + *
  7785. + * Type:     function<br>
  7786. + * Name:     eval<br>
  7787. + * Purpose:  evaluate a template variable as a template<br>
  7788. + * @link http://smarty.php.net/manual/en/language.function.eval.php {eval}
  7789. + *       (Smarty online manual)
  7790. + * @author Monte Ohrt <monte at ohrt dot com>
  7791. + * @param array
  7792. + * @param Smarty
  7793. + */
  7794. +function smarty_function_eval($params, &$smarty)
  7795. +{
  7796. +
  7797. +    if (!isset($params['var'])) {
  7798. +        $smarty->trigger_error("eval: missing 'var' parameter");
  7799. +        return;
  7800. +    }
  7801. +
  7802. +    if($params['var'] == '') {
  7803. +        return;
  7804. +    }
  7805. +
  7806. +    $smarty->_compile_source('evaluated template', $params['var'], $_var_compiled);
  7807. +
  7808. +    ob_start();
  7809. +    $smarty->_eval('?>' . $_var_compiled);
  7810. +    $_contents = ob_get_contents();
  7811. +    ob_end_clean();
  7812. +
  7813. +    if (!empty($params['assign'])) {
  7814. +        $smarty->assign($params['assign'], $_contents);
  7815. +    } else {
  7816. +        return $_contents;
  7817. +    }
  7818. +}
  7819. +
  7820. +/* vim: set expandtab: */
  7821. +
  7822. +?>
  7823. diff --git a/library/smarty/plugins/function.fetch.php b/library/smarty/plugins/function.fetch.php
  7824. new file mode 100644
  7825. --- /dev/null
  7826. +++ b/library/smarty/plugins/function.fetch.php
  7827. @@ -0,0 +1,221 @@
  7828. +<?php
  7829. +/**
  7830. + * Smarty plugin
  7831. + * @package Smarty
  7832. + * @subpackage plugins
  7833. + */
  7834. +
  7835. +
  7836. +/**
  7837. + * Smarty {fetch} plugin
  7838. + *
  7839. + * Type:     function<br>
  7840. + * Name:     fetch<br>
  7841. + * Purpose:  fetch file, web or ftp data and display results
  7842. + * @link http://smarty.php.net/manual/en/language.function.fetch.php {fetch}
  7843. + *       (Smarty online manual)
  7844. + * @author Monte Ohrt <monte at ohrt dot com>
  7845. + * @param array
  7846. + * @param Smarty
  7847. + * @return string|null if the assign parameter is passed, Smarty assigns the
  7848. + *                     result to a template variable
  7849. + */
  7850. +function smarty_function_fetch($params, &$smarty)
  7851. +{
  7852. +    if (empty($params['file'])) {
  7853. +        $smarty->_trigger_fatal_error("[plugin] parameter 'file' cannot be empty");
  7854. +        return;
  7855. +    }
  7856. +
  7857. +    $content = '';
  7858. +    if ($smarty->security && !preg_match('!^(http|ftp)://!i', $params['file'])) {
  7859. +        $_params = array('resource_type' => 'file', 'resource_name' => $params['file']);
  7860. +        require_once(SMARTY_CORE_DIR . 'core.is_secure.php');
  7861. +        if(!smarty_core_is_secure($_params, $smarty)) {
  7862. +            $smarty->_trigger_fatal_error('[plugin] (secure mode) fetch \'' . $params['file'] . '\' is not allowed');
  7863. +            return;
  7864. +        }
  7865. +        
  7866. +        // fetch the file
  7867. +        if($fp = @fopen($params['file'],'r')) {
  7868. +            while(!feof($fp)) {
  7869. +                $content .= fgets ($fp,4096);
  7870. +            }
  7871. +            fclose($fp);
  7872. +        } else {
  7873. +            $smarty->_trigger_fatal_error('[plugin] fetch cannot read file \'' . $params['file'] . '\'');
  7874. +            return;
  7875. +        }
  7876. +    } else {
  7877. +        // not a local file
  7878. +        if(preg_match('!^http://!i',$params['file'])) {
  7879. +            // http fetch
  7880. +            if($uri_parts = parse_url($params['file'])) {
  7881. +                // set defaults
  7882. +                $host = $server_name = $uri_parts['host'];
  7883. +                $timeout = 30;
  7884. +                $accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*";
  7885. +                $agent = "Smarty Template Engine ".$smarty->_version;
  7886. +                $referer = "";
  7887. +                $uri = !empty($uri_parts['path']) ? $uri_parts['path'] : '/';
  7888. +                $uri .= !empty($uri_parts['query']) ? '?' . $uri_parts['query'] : '';
  7889. +                $_is_proxy = false;
  7890. +                if(empty($uri_parts['port'])) {
  7891. +                    $port = 80;
  7892. +                } else {
  7893. +                    $port = $uri_parts['port'];
  7894. +                }
  7895. +                if(!empty($uri_parts['user'])) {
  7896. +                    $user = $uri_parts['user'];
  7897. +                }
  7898. +                if(!empty($uri_parts['pass'])) {
  7899. +                    $pass = $uri_parts['pass'];
  7900. +                }
  7901. +                // loop through parameters, setup headers
  7902. +                foreach($params as $param_key => $param_value) {
  7903. +                    switch($param_key) {
  7904. +                        case "file":
  7905. +                        case "assign":
  7906. +                        case "assign_headers":
  7907. +                            break;
  7908. +                        case "user":
  7909. +                            if(!empty($param_value)) {
  7910. +                                $user = $param_value;
  7911. +                            }
  7912. +                            break;
  7913. +                        case "pass":
  7914. +                            if(!empty($param_value)) {
  7915. +                                $pass = $param_value;
  7916. +                            }
  7917. +                            break;
  7918. +                        case "accept":
  7919. +                            if(!empty($param_value)) {
  7920. +                                $accept = $param_value;
  7921. +                            }
  7922. +                            break;
  7923. +                        case "header":
  7924. +                            if(!empty($param_value)) {
  7925. +                                if(!preg_match('![\w\d-]+: .+!',$param_value)) {
  7926. +                                    $smarty->_trigger_fatal_error("[plugin] invalid header format '".$param_value."'");
  7927. +                                    return;
  7928. +                                } else {
  7929. +                                    $extra_headers[] = $param_value;
  7930. +                                }
  7931. +                            }
  7932. +                            break;
  7933. +                        case "proxy_host":
  7934. +                            if(!empty($param_value)) {
  7935. +                                $proxy_host = $param_value;
  7936. +                            }
  7937. +                            break;
  7938. +                        case "proxy_port":
  7939. +                            if(!preg_match('!\D!', $param_value)) {
  7940. +                                $proxy_port = (int) $param_value;
  7941. +                            } else {
  7942. +                                $smarty->_trigger_fatal_error("[plugin] invalid value for attribute '".$param_key."'");
  7943. +                                return;
  7944. +                            }
  7945. +                            break;
  7946. +                        case "agent":
  7947. +                            if(!empty($param_value)) {
  7948. +                                $agent = $param_value;
  7949. +                            }
  7950. +                            break;
  7951. +                        case "referer":
  7952. +                            if(!empty($param_value)) {
  7953. +                                $referer = $param_value;
  7954. +                            }
  7955. +                            break;
  7956. +                        case "timeout":
  7957. +                            if(!preg_match('!\D!', $param_value)) {
  7958. +                                $timeout = (int) $param_value;
  7959. +                            } else {
  7960. +                                $smarty->_trigger_fatal_error("[plugin] invalid value for attribute '".$param_key."'");
  7961. +                                return;
  7962. +                            }
  7963. +                            break;
  7964. +                        default:
  7965. +                            $smarty->_trigger_fatal_error("[plugin] unrecognized attribute '".$param_key."'");
  7966. +                            return;
  7967. +                    }
  7968. +                }
  7969. +                if(!empty($proxy_host) && !empty($proxy_port)) {
  7970. +                    $_is_proxy = true;
  7971. +                    $fp = fsockopen($proxy_host,$proxy_port,$errno,$errstr,$timeout);
  7972. +                } else {
  7973. +                    $fp = fsockopen($server_name,$port,$errno,$errstr,$timeout);
  7974. +                }
  7975. +
  7976. +                if(!$fp) {
  7977. +                    $smarty->_trigger_fatal_error("[plugin] unable to fetch: $errstr ($errno)");
  7978. +                    return;
  7979. +                } else {
  7980. +                    if($_is_proxy) {
  7981. +                        fputs($fp, 'GET ' . $params['file'] . " HTTP/1.0\r\n");
  7982. +                    } else {
  7983. +                        fputs($fp, "GET $uri HTTP/1.0\r\n");
  7984. +                    }
  7985. +                    if(!empty($host)) {
  7986. +                        fputs($fp, "Host: $host\r\n");
  7987. +                    }
  7988. +                    if(!empty($accept)) {
  7989. +                        fputs($fp, "Accept: $accept\r\n");
  7990. +                    }
  7991. +                    if(!empty($agent)) {
  7992. +                        fputs($fp, "User-Agent: $agent\r\n");
  7993. +                    }
  7994. +                    if(!empty($referer)) {
  7995. +                        fputs($fp, "Referer: $referer\r\n");
  7996. +                    }
  7997. +                    if(isset($extra_headers) && is_array($extra_headers)) {
  7998. +                        foreach($extra_headers as $curr_header) {
  7999. +                            fputs($fp, $curr_header."\r\n");
  8000. +                        }
  8001. +                    }
  8002. +                    if(!empty($user) && !empty($pass)) {
  8003. +                        fputs($fp, "Authorization: BASIC ".base64_encode("$user:$pass")."\r\n");
  8004. +                    }
  8005. +
  8006. +                    fputs($fp, "\r\n");
  8007. +                    while(!feof($fp)) {
  8008. +                        $content .= fgets($fp,4096);
  8009. +                    }
  8010. +                    fclose($fp);
  8011. +                    $csplit = split("\r\n\r\n",$content,2);
  8012. +
  8013. +                    $content = $csplit[1];
  8014. +
  8015. +                    if(!empty($params['assign_headers'])) {
  8016. +                        $smarty->assign($params['assign_headers'],split("\r\n",$csplit[0]));
  8017. +                    }
  8018. +                }
  8019. +            } else {
  8020. +                $smarty->_trigger_fatal_error("[plugin] unable to parse URL, check syntax");
  8021. +                return;
  8022. +            }
  8023. +        } else {
  8024. +            // ftp fetch
  8025. +            if($fp = @fopen($params['file'],'r')) {
  8026. +                while(!feof($fp)) {
  8027. +                    $content .= fgets ($fp,4096);
  8028. +                }
  8029. +                fclose($fp);
  8030. +            } else {
  8031. +                $smarty->_trigger_fatal_error('[plugin] fetch cannot read file \'' . $params['file'] .'\'');
  8032. +                return;
  8033. +            }
  8034. +        }
  8035. +
  8036. +    }
  8037. +
  8038. +
  8039. +    if (!empty($params['assign'])) {
  8040. +        $smarty->assign($params['assign'],$content);
  8041. +    } else {
  8042. +        return $content;
  8043. +    }
  8044. +}
  8045. +
  8046. +/* vim: set expandtab: */
  8047. +
  8048. +?>
  8049. diff --git a/library/smarty/plugins/function.html_checkboxes.php b/library/smarty/plugins/function.html_checkboxes.php
  8050. new file mode 100644
  8051. --- /dev/null
  8052. +++ b/library/smarty/plugins/function.html_checkboxes.php
  8053. @@ -0,0 +1,143 @@
  8054. +<?php
  8055. +/**
  8056. + * Smarty plugin
  8057. + * @package Smarty
  8058. + * @subpackage plugins
  8059. + */
  8060. +
  8061. +
  8062. +/**
  8063. + * Smarty {html_checkboxes} function plugin
  8064. + *
  8065. + * File:       function.html_checkboxes.php<br>
  8066. + * Type:       function<br>
  8067. + * Name:       html_checkboxes<br>
  8068. + * Date:       24.Feb.2003<br>
  8069. + * Purpose:    Prints out a list of checkbox input types<br>
  8070. + * Input:<br>
  8071. + *           - name       (optional) - string default "checkbox"
  8072. + *           - values     (required) - array
  8073. + *           - options    (optional) - associative array
  8074. + *           - checked    (optional) - array default not set
  8075. + *           - separator  (optional) - ie <br> or &nbsp;
  8076. + *           - output     (optional) - the output next to each checkbox
  8077. + *           - assign     (optional) - assign the output as an array to this variable
  8078. + * Examples:
  8079. + * <pre>
  8080. + * {html_checkboxes values=$ids output=$names}
  8081. + * {html_checkboxes values=$ids name='box' separator='<br>' output=$names}
  8082. + * {html_checkboxes values=$ids checked=$checked separator='<br>' output=$names}
  8083. + * </pre>
  8084. + * @link http://smarty.php.net/manual/en/language.function.html.checkboxes.php {html_checkboxes}
  8085. + *      (Smarty online manual)
  8086. + * @author     Christopher Kvarme <[email protected]>
  8087. + * @author credits to Monte Ohrt <monte at ohrt dot com>
  8088. + * @version    1.0
  8089. + * @param array
  8090. + * @param Smarty
  8091. + * @return string
  8092. + * @uses smarty_function_escape_special_chars()
  8093. + */
  8094. +function smarty_function_html_checkboxes($params, &$smarty)
  8095. +{
  8096. +    require_once $smarty->_get_plugin_filepath('shared','escape_special_chars');
  8097. +
  8098. +    $name = 'checkbox';
  8099. +    $values = null;
  8100. +    $options = null;
  8101. +    $selected = null;
  8102. +    $separator = '';
  8103. +    $labels = true;
  8104. +    $output = null;
  8105. +
  8106. +    $extra = '';
  8107. +
  8108. +    foreach($params as $_key => $_val) {
  8109. +        switch($_key) {
  8110. +            case 'name':
  8111. +            case 'separator':
  8112. +                $$_key = $_val;
  8113. +                break;
  8114. +
  8115. +            case 'labels':
  8116. +                $$_key = (bool)$_val;
  8117. +                break;
  8118. +
  8119. +            case 'options':
  8120. +                $$_key = (array)$_val;
  8121. +                break;
  8122. +
  8123. +            case 'values':
  8124. +            case 'output':
  8125. +                $$_key = array_values((array)$_val);
  8126. +                break;
  8127. +
  8128. +            case 'checked':
  8129. +            case 'selected':
  8130. +                $selected = array_map('strval', array_values((array)$_val));
  8131. +                break;
  8132. +
  8133. +            case 'checkboxes':
  8134. +                $smarty->trigger_error('html_checkboxes: the use of the "checkboxes" attribute is deprecated, use "options" instead', E_USER_WARNING);
  8135. +                $options = (array)$_val;
  8136. +                break;
  8137. +
  8138. +            case 'assign':
  8139. +                break;
  8140. +
  8141. +            default:
  8142. +                if(!is_array($_val)) {
  8143. +                    $extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"';
  8144. +                } else {
  8145. +                    $smarty->trigger_error("html_checkboxes: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
  8146. +                }
  8147. +                break;
  8148. +        }
  8149. +    }
  8150. +
  8151. +    if (!isset($options) && !isset($values))
  8152. +        return ''; /* raise error here? */
  8153. +
  8154. +    settype($selected, 'array');
  8155. +    $_html_result = array();
  8156. +
  8157. +    if (isset($options)) {
  8158. +
  8159. +        foreach ($options as $_key=>$_val)
  8160. +            $_html_result[] = smarty_function_html_checkboxes_output($name, $_key, $_val, $selected, $extra, $separator, $labels);
  8161. +
  8162. +
  8163. +    } else {
  8164. +        foreach ($values as $_i=>$_key) {
  8165. +            $_val = isset($output[$_i]) ? $output[$_i] : '';
  8166. +            $_html_result[] = smarty_function_html_checkboxes_output($name, $_key, $_val, $selected, $extra, $separator, $labels);
  8167. +        }
  8168. +
  8169. +    }
  8170. +
  8171. +    if(!empty($params['assign'])) {
  8172. +        $smarty->assign($params['assign'], $_html_result);
  8173. +    } else {
  8174. +        return implode("\n",$_html_result);
  8175. +    }
  8176. +
  8177. +}
  8178. +
  8179. +function smarty_function_html_checkboxes_output($name, $value, $output, $selected, $extra, $separator, $labels) {
  8180. +    $_output = '';
  8181. +    if ($labels) $_output .= '<label>';
  8182. +    $_output .= '<input type="checkbox" name="'
  8183. +        . smarty_function_escape_special_chars($name) . '[]" value="'
  8184. +        . smarty_function_escape_special_chars($value) . '"';
  8185. +
  8186. +    if (in_array((string)$value, $selected)) {
  8187. +        $_output .= ' checked="checked"';
  8188. +    }
  8189. +    $_output .= $extra . ' />' . $output;
  8190. +    if ($labels) $_output .= '</label>';
  8191. +    $_output .=  $separator;
  8192. +
  8193. +    return $_output;
  8194. +}
  8195. +
  8196. +?>
  8197. diff --git a/library/smarty/plugins/function.html_image.php b/library/smarty/plugins/function.html_image.php
  8198. new file mode 100644
  8199. --- /dev/null
  8200. +++ b/library/smarty/plugins/function.html_image.php
  8201. @@ -0,0 +1,142 @@
  8202. +<?php
  8203. +/**
  8204. + * Smarty plugin
  8205. + * @package Smarty
  8206. + * @subpackage plugins
  8207. + */
  8208. +
  8209. +
  8210. +/**
  8211. + * Smarty {html_image} function plugin
  8212. + *
  8213. + * Type:     function<br>
  8214. + * Name:     html_image<br>
  8215. + * Date:     Feb 24, 2003<br>
  8216. + * Purpose:  format HTML tags for the image<br>
  8217. + * Input:<br>
  8218. + *         - file = file (and path) of image (required)
  8219. + *         - height = image height (optional, default actual height)
  8220. + *         - width = image width (optional, default actual width)
  8221. + *         - basedir = base directory for absolute paths, default
  8222. + *                     is environment variable DOCUMENT_ROOT
  8223. + *         - path_prefix = prefix for path output (optional, default empty)
  8224. + *
  8225. + * Examples: {html_image file="/images/masthead.gif"}
  8226. + * Output:   <img src="/images/masthead.gif" width=400 height=23>
  8227. + * @link http://smarty.php.net/manual/en/language.function.html.image.php {html_image}
  8228. + *      (Smarty online manual)
  8229. + * @author   Monte Ohrt <monte at ohrt dot com>
  8230. + * @author credits to Duda <[email protected]> - wrote first image function
  8231. + *           in repository, helped with lots of functionality
  8232. + * @version  1.0
  8233. + * @param array
  8234. + * @param Smarty
  8235. + * @return string
  8236. + * @uses smarty_function_escape_special_chars()
  8237. + */
  8238. +function smarty_function_html_image($params, &$smarty)
  8239. +{
  8240. +    require_once $smarty->_get_plugin_filepath('shared','escape_special_chars');
  8241. +    
  8242. +    $alt = '';
  8243. +    $file = '';
  8244. +    $height = '';
  8245. +    $width = '';
  8246. +    $extra = '';
  8247. +    $prefix = '';
  8248. +    $suffix = '';
  8249. +    $path_prefix = '';
  8250. +    $server_vars = ($smarty->request_use_auto_globals) ? $_SERVER : $GLOBALS['HTTP_SERVER_VARS'];
  8251. +    $basedir = isset($server_vars['DOCUMENT_ROOT']) ? $server_vars['DOCUMENT_ROOT'] : '';
  8252. +    foreach($params as $_key => $_val) {
  8253. +        switch($_key) {
  8254. +            case 'file':
  8255. +            case 'height':
  8256. +            case 'width':
  8257. +            case 'dpi':
  8258. +            case 'path_prefix':
  8259. +            case 'basedir':
  8260. +                $$_key = $_val;
  8261. +                break;
  8262. +
  8263. +            case 'alt':
  8264. +                if(!is_array($_val)) {
  8265. +                    $$_key = smarty_function_escape_special_chars($_val);
  8266. +                } else {
  8267. +                    $smarty->trigger_error("html_image: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
  8268. +                }
  8269. +                break;
  8270. +
  8271. +            case 'link':
  8272. +            case 'href':
  8273. +                $prefix = '<a href="' . $_val . '">';
  8274. +                $suffix = '</a>';
  8275. +                break;
  8276. +
  8277. +            default:
  8278. +                if(!is_array($_val)) {
  8279. +                    $extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"';
  8280. +                } else {
  8281. +                    $smarty->trigger_error("html_image: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
  8282. +                }
  8283. +                break;
  8284. +        }
  8285. +    }
  8286. +
  8287. +    if (empty($file)) {
  8288. +        $smarty->trigger_error("html_image: missing 'file' parameter", E_USER_NOTICE);
  8289. +        return;
  8290. +    }
  8291. +
  8292. +    if (substr($file,0,1) == '/') {
  8293. +        $_image_path = $basedir . $file;
  8294. +    } else {
  8295. +        $_image_path = $file;
  8296. +    }
  8297. +    
  8298. +    if(!isset($params['width']) || !isset($params['height'])) {
  8299. +        if(!$_image_data = @getimagesize($_image_path)) {
  8300. +            if(!file_exists($_image_path)) {
  8301. +                $smarty->trigger_error("html_image: unable to find '$_image_path'", E_USER_NOTICE);
  8302. +                return;
  8303. +            } else if(!is_readable($_image_path)) {
  8304. +                $smarty->trigger_error("html_image: unable to read '$_image_path'", E_USER_NOTICE);
  8305. +                return;
  8306. +            } else {
  8307. +                $smarty->trigger_error("html_image: '$_image_path' is not a valid image file", E_USER_NOTICE);
  8308. +                return;
  8309. +            }
  8310. +        }
  8311. +        if ($smarty->security &&
  8312. +            ($_params = array('resource_type' => 'file', 'resource_name' => $_image_path)) &&
  8313. +            (require_once(SMARTY_CORE_DIR . 'core.is_secure.php')) &&
  8314. +            (!smarty_core_is_secure($_params, $smarty)) ) {
  8315. +            $smarty->trigger_error("html_image: (secure) '$_image_path' not in secure directory", E_USER_NOTICE);
  8316. +        }        
  8317. +        
  8318. +        if(!isset($params['width'])) {
  8319. +            $width = $_image_data[0];
  8320. +        }
  8321. +        if(!isset($params['height'])) {
  8322. +            $height = $_image_data[1];
  8323. +        }
  8324. +
  8325. +    }
  8326. +
  8327. +    if(isset($params['dpi'])) {
  8328. +        if(strstr($server_vars['HTTP_USER_AGENT'], 'Mac')) {
  8329. +            $dpi_default = 72;
  8330. +        } else {
  8331. +            $dpi_default = 96;
  8332. +        }
  8333. +        $_resize = $dpi_default/$params['dpi'];
  8334. +        $width = round($width * $_resize);
  8335. +        $height = round($height * $_resize);
  8336. +    }
  8337. +
  8338. +    return $prefix . '<img src="'.$path_prefix.$file.'" alt="'.$alt.'" width="'.$width.'" height="'.$height.'"'.$extra.' />' . $suffix;
  8339. +}
  8340. +
  8341. +/* vim: set expandtab: */
  8342. +
  8343. +?>
  8344. diff --git a/library/smarty/plugins/function.html_options.php b/library/smarty/plugins/function.html_options.php
  8345. new file mode 100644
  8346. --- /dev/null
  8347. +++ b/library/smarty/plugins/function.html_options.php
  8348. @@ -0,0 +1,122 @@
  8349. +<?php
  8350. +/**
  8351. + * Smarty plugin
  8352. + * @package Smarty
  8353. + * @subpackage plugins
  8354. + */
  8355. +
  8356. +
  8357. +/**
  8358. + * Smarty {html_options} function plugin
  8359. + *
  8360. + * Type:     function<br>
  8361. + * Name:     html_options<br>
  8362. + * Input:<br>
  8363. + *           - name       (optional) - string default "select"
  8364. + *           - values     (required if no options supplied) - array
  8365. + *           - options    (required if no values supplied) - associative array
  8366. + *           - selected   (optional) - string default not set
  8367. + *           - output     (required if not options supplied) - array
  8368. + * Purpose:  Prints the list of <option> tags generated from
  8369. + *           the passed parameters
  8370. + * @link http://smarty.php.net/manual/en/language.function.html.options.php {html_image}
  8371. + *      (Smarty online manual)
  8372. + * @author Monte Ohrt <monte at ohrt dot com>
  8373. + * @param array
  8374. + * @param Smarty
  8375. + * @return string
  8376. + * @uses smarty_function_escape_special_chars()
  8377. + */
  8378. +function smarty_function_html_options($params, &$smarty)
  8379. +{
  8380. +    require_once $smarty->_get_plugin_filepath('shared','escape_special_chars');
  8381. +    
  8382. +    $name = null;
  8383. +    $values = null;
  8384. +    $options = null;
  8385. +    $selected = array();
  8386. +    $output = null;
  8387. +    
  8388. +    $extra = '';
  8389. +    
  8390. +    foreach($params as $_key => $_val) {
  8391. +        switch($_key) {
  8392. +            case 'name':
  8393. +                $$_key = (string)$_val;
  8394. +                break;
  8395. +            
  8396. +            case 'options':
  8397. +                $$_key = (array)$_val;
  8398. +                break;
  8399. +                
  8400. +            case 'values':
  8401. +            case 'output':
  8402. +                $$_key = array_values((array)$_val);
  8403. +                break;
  8404. +
  8405. +            case 'selected':
  8406. +                $$_key = array_map('strval', array_values((array)$_val));
  8407. +                break;
  8408. +                
  8409. +            default:
  8410. +                if(!is_array($_val)) {
  8411. +                    $extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"';
  8412. +                } else {
  8413. +                    $smarty->trigger_error("html_options: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
  8414. +                }
  8415. +                break;
  8416. +        }
  8417. +    }
  8418. +
  8419. +    if (!isset($options) && !isset($values))
  8420. +        return ''; /* raise error here? */
  8421. +
  8422. +    $_html_result = '';
  8423. +
  8424. +    if (isset($options)) {
  8425. +        
  8426. +        foreach ($options as $_key=>$_val)
  8427. +            $_html_result .= smarty_function_html_options_optoutput($_key, $_val, $selected);
  8428. +
  8429. +    } else {
  8430. +        
  8431. +        foreach ($values as $_i=>$_key) {
  8432. +            $_val = isset($output[$_i]) ? $output[$_i] : '';
  8433. +            $_html_result .= smarty_function_html_options_optoutput($_key, $_val, $selected);
  8434. +        }
  8435. +
  8436. +    }
  8437. +
  8438. +    if(!empty($name)) {
  8439. +        $_html_result = '<select name="' . $name . '"' . $extra . '>' . "\n" . $_html_result . '</select>' . "\n";
  8440. +    }
  8441. +
  8442. +    return $_html_result;
  8443. +
  8444. +}
  8445. +
  8446. +function smarty_function_html_options_optoutput($key, $value, $selected) {
  8447. +    if(!is_array($value)) {
  8448. +        $_html_result = '<option label="' . smarty_function_escape_special_chars($value) . '" value="' .
  8449. +            smarty_function_escape_special_chars($key) . '"';
  8450. +        if (in_array((string)$key, $selected))
  8451. +            $_html_result .= ' selected="selected"';
  8452. +        $_html_result .= '>' . smarty_function_escape_special_chars($value) . '</option>' . "\n";
  8453. +    } else {
  8454. +        $_html_result = smarty_function_html_options_optgroup($key, $value, $selected);
  8455. +    }
  8456. +    return $_html_result;
  8457. +}
  8458. +
  8459. +function smarty_function_html_options_optgroup($key, $values, $selected) {
  8460. +    $optgroup_html = '<optgroup label="' . smarty_function_escape_special_chars($key) . '">' . "\n";
  8461. +    foreach ($values as $key => $value) {
  8462. +        $optgroup_html .= smarty_function_html_options_optoutput($key, $value, $selected);
  8463. +    }
  8464. +    $optgroup_html .= "</optgroup>\n";
  8465. +    return $optgroup_html;
  8466. +}
  8467. +
  8468. +/* vim: set expandtab: */
  8469. +
  8470. +?>
  8471. diff --git a/library/smarty/plugins/function.html_radios.php b/library/smarty/plugins/function.html_radios.php
  8472. new file mode 100644
  8473. --- /dev/null
  8474. +++ b/library/smarty/plugins/function.html_radios.php
  8475. @@ -0,0 +1,156 @@
  8476. +<?php
  8477. +/**
  8478. + * Smarty plugin
  8479. + * @package Smarty
  8480. + * @subpackage plugins
  8481. + */
  8482. +
  8483. +
  8484. +/**
  8485. + * Smarty {html_radios} function plugin
  8486. + *
  8487. + * File:       function.html_radios.php<br>
  8488. + * Type:       function<br>
  8489. + * Name:       html_radios<br>
  8490. + * Date:       24.Feb.2003<br>
  8491. + * Purpose:    Prints out a list of radio input types<br>
  8492. + * Input:<br>
  8493. + *           - name       (optional) - string default "radio"
  8494. + *           - values     (required) - array
  8495. + *           - options    (optional) - associative array
  8496. + *           - checked    (optional) - array default not set
  8497. + *           - separator  (optional) - ie <br> or &nbsp;
  8498. + *           - output     (optional) - the output next to each radio button
  8499. + *           - assign     (optional) - assign the output as an array to this variable
  8500. + * Examples:
  8501. + * <pre>
  8502. + * {html_radios values=$ids output=$names}
  8503. + * {html_radios values=$ids name='box' separator='<br>' output=$names}
  8504. + * {html_radios values=$ids checked=$checked separator='<br>' output=$names}
  8505. + * </pre>
  8506. + * @link http://smarty.php.net/manual/en/language.function.html.radios.php {html_radios}
  8507. + *      (Smarty online manual)
  8508. + * @author     Christopher Kvarme <[email protected]>
  8509. + * @author credits to Monte Ohrt <monte at ohrt dot com>
  8510. + * @version    1.0
  8511. + * @param array
  8512. + * @param Smarty
  8513. + * @return string
  8514. + * @uses smarty_function_escape_special_chars()
  8515. + */
  8516. +function smarty_function_html_radios($params, &$smarty)
  8517. +{
  8518. +    require_once $smarty->_get_plugin_filepath('shared','escape_special_chars');
  8519. +  
  8520. +    $name = 'radio';
  8521. +    $values = null;
  8522. +    $options = null;
  8523. +    $selected = null;
  8524. +    $separator = '';
  8525. +    $labels = true;
  8526. +    $label_ids = false;
  8527. +    $output = null;
  8528. +    $extra = '';
  8529. +
  8530. +    foreach($params as $_key => $_val) {
  8531. +        switch($_key) {
  8532. +            case 'name':
  8533. +            case 'separator':
  8534. +                $$_key = (string)$_val;
  8535. +                break;
  8536. +
  8537. +            case 'checked':
  8538. +            case 'selected':
  8539. +                if(is_array($_val)) {
  8540. +                    $smarty->trigger_error('html_radios: the "' . $_key . '" attribute cannot be an array', E_USER_WARNING);
  8541. +                } else {
  8542. +                    $selected = (string)$_val;
  8543. +                }
  8544. +                break;
  8545. +
  8546. +            case 'labels':
  8547. +            case 'label_ids':
  8548. +                $$_key = (bool)$_val;
  8549. +                break;
  8550. +
  8551. +            case 'options':
  8552. +                $$_key = (array)$_val;
  8553. +                break;
  8554. +
  8555. +            case 'values':
  8556. +            case 'output':
  8557. +                $$_key = array_values((array)$_val);
  8558. +                break;
  8559. +
  8560. +            case 'radios':
  8561. +                $smarty->trigger_error('html_radios: the use of the "radios" attribute is deprecated, use "options" instead', E_USER_WARNING);
  8562. +                $options = (array)$_val;
  8563. +                break;
  8564. +
  8565. +            case 'assign':
  8566. +                break;
  8567. +
  8568. +            default:
  8569. +                if(!is_array($_val)) {
  8570. +                    $extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"';
  8571. +                } else {
  8572. +                    $smarty->trigger_error("html_radios: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
  8573. +                }
  8574. +                break;
  8575. +        }
  8576. +    }
  8577. +
  8578. +    if (!isset($options) && !isset($values))
  8579. +        return ''; /* raise error here? */
  8580. +
  8581. +    $_html_result = array();
  8582. +
  8583. +    if (isset($options)) {
  8584. +
  8585. +        foreach ($options as $_key=>$_val)
  8586. +            $_html_result[] = smarty_function_html_radios_output($name, $_key, $_val, $selected, $extra, $separator, $labels, $label_ids);
  8587. +
  8588. +    } else {
  8589. +
  8590. +        foreach ($values as $_i=>$_key) {
  8591. +            $_val = isset($output[$_i]) ? $output[$_i] : '';
  8592. +            $_html_result[] = smarty_function_html_radios_output($name, $_key, $_val, $selected, $extra, $separator, $labels, $label_ids);
  8593. +        }
  8594. +
  8595. +    }
  8596. +
  8597. +    if(!empty($params['assign'])) {
  8598. +        $smarty->assign($params['assign'], $_html_result);
  8599. +    } else {
  8600. +        return implode("\n",$_html_result);
  8601. +    }
  8602. +
  8603. +}
  8604. +
  8605. +function smarty_function_html_radios_output($name, $value, $output, $selected, $extra, $separator, $labels, $label_ids) {
  8606. +    $_output = '';
  8607. +    if ($labels) {
  8608. +      if($label_ids) {
  8609. +          $_id = smarty_function_escape_special_chars(preg_replace('![^\w\-\.]!', '_', $name . '_' . $value));
  8610. +          $_output .= '<label for="' . $_id . '">';
  8611. +      } else {
  8612. +          $_output .= '<label>';          
  8613. +      }
  8614. +   }
  8615. +   $_output .= '<input type="radio" name="'
  8616. +        . smarty_function_escape_special_chars($name) . '" value="'
  8617. +        . smarty_function_escape_special_chars($value) . '"';
  8618. +
  8619. +   if ($labels && $label_ids) $_output .= ' id="' . $_id . '"';
  8620. +
  8621. +    if ((string)$value==$selected) {
  8622. +        $_output .= ' checked="checked"';
  8623. +    }
  8624. +    $_output .= $extra . ' />' . $output;
  8625. +    if ($labels) $_output .= '</label>';
  8626. +    $_output .=  $separator;
  8627. +
  8628. +    return $_output;
  8629. +}
  8630. +
  8631. +?>
  8632. diff --git a/library/smarty/plugins/function.html_select_date.php b/library/smarty/plugins/function.html_select_date.php
  8633. new file mode 100644
  8634. --- /dev/null
  8635. +++ b/library/smarty/plugins/function.html_select_date.php
  8636. @@ -0,0 +1,331 @@
  8637. +<?php
  8638. +/**
  8639. + * Smarty plugin
  8640. + * @package Smarty
  8641. + * @subpackage plugins
  8642. + */
  8643. +
  8644. +/**
  8645. + * Smarty {html_select_date} plugin
  8646. + *
  8647. + * Type:     function<br>
  8648. + * Name:     html_select_date<br>
  8649. + * Purpose:  Prints the dropdowns for date selection.
  8650. + *
  8651. + * ChangeLog:<br>
  8652. + *           - 1.0 initial release
  8653. + *           - 1.1 added support for +/- N syntax for begin
  8654. + *                and end year values. (Monte)
  8655. + *           - 1.2 added support for yyyy-mm-dd syntax for
  8656. + *                time value. (Jan Rosier)
  8657. + *           - 1.3 added support for choosing format for
  8658. + *                month values (Gary Loescher)
  8659. + *           - 1.3.1 added support for choosing format for
  8660. + *                day values (Marcus Bointon)
  8661. + *           - 1.3.2 support negative timestamps, force year
  8662. + *             dropdown to include given date unless explicitly set (Monte)
  8663. + *           - 1.3.4 fix behaviour of 0000-00-00 00:00:00 dates to match that
  8664. + *             of 0000-00-00 dates (cybot, boots)
  8665. + * @link http://smarty.php.net/manual/en/language.function.html.select.date.php {html_select_date}
  8666. + *      (Smarty online manual)
  8667. + * @version 1.3.4
  8668. + * @author Andrei Zmievski
  8669. + * @author Monte Ohrt <monte at ohrt dot com>
  8670. + * @param array
  8671. + * @param Smarty
  8672. + * @return string
  8673. + */
  8674. +function smarty_function_html_select_date($params, &$smarty)
  8675. +{
  8676. +    require_once $smarty->_get_plugin_filepath('shared','escape_special_chars');
  8677. +    require_once $smarty->_get_plugin_filepath('shared','make_timestamp');
  8678. +    require_once $smarty->_get_plugin_filepath('function','html_options');
  8679. +    /* Default values. */
  8680. +    $prefix          = "Date_";
  8681. +    $start_year      = strftime("%Y");
  8682. +    $end_year        = $start_year;
  8683. +    $display_days    = true;
  8684. +    $display_months  = true;
  8685. +    $display_years   = true;
  8686. +    $month_format    = "%B";
  8687. +    /* Write months as numbers by default  GL */
  8688. +    $month_value_format = "%m";
  8689. +    $day_format      = "%02d";
  8690. +    /* Write day values using this format MB */
  8691. +    $day_value_format = "%d";
  8692. +    $year_as_text    = false;
  8693. +    /* Display years in reverse order? Ie. 2000,1999,.... */
  8694. +    $reverse_years   = false;
  8695. +    /* Should the select boxes be part of an array when returned from PHP?
  8696. +       e.g. setting it to "birthday", would create "birthday[Day]",
  8697. +       "birthday[Month]" & "birthday[Year]". Can be combined with prefix */
  8698. +    $field_array     = null;
  8699. +    /* <select size>'s of the different <select> tags.
  8700. +       If not set, uses default dropdown. */
  8701. +    $day_size        = null;
  8702. +    $month_size      = null;
  8703. +    $year_size       = null;
  8704. +    /* Unparsed attributes common to *ALL* the <select>/<input> tags.
  8705. +       An example might be in the template: all_extra ='class ="foo"'. */
  8706. +    $all_extra       = null;
  8707. +    /* Separate attributes for the tags. */
  8708. +    $day_extra       = null;
  8709. +    $month_extra     = null;
  8710. +    $year_extra      = null;
  8711. +    /* Order in which to display the fields.
  8712. +       "D" -> day, "M" -> month, "Y" -> year. */
  8713. +    $field_order     = 'MDY';
  8714. +    /* String printed between the different fields. */
  8715. +    $field_separator = "\n";
  8716. +    $time = time();
  8717. +    $all_empty       = null;
  8718. +    $day_empty       = null;
  8719. +    $month_empty     = null;
  8720. +    $year_empty      = null;
  8721. +    $extra_attrs     = '';
  8722. +
  8723. +    foreach ($params as $_key=>$_value) {
  8724. +        switch ($_key) {
  8725. +            case 'prefix':
  8726. +            case 'time':
  8727. +            case 'start_year':
  8728. +            case 'end_year':
  8729. +            case 'month_format':
  8730. +            case 'day_format':
  8731. +            case 'day_value_format':
  8732. +            case 'field_array':
  8733. +            case 'day_size':
  8734. +            case 'month_size':
  8735. +            case 'year_size':
  8736. +            case 'all_extra':
  8737. +            case 'day_extra':
  8738. +            case 'month_extra':
  8739. +            case 'year_extra':
  8740. +            case 'field_order':
  8741. +            case 'field_separator':
  8742. +            case 'month_value_format':
  8743. +            case 'month_empty':
  8744. +            case 'day_empty':
  8745. +            case 'year_empty':
  8746. +                $$_key = (string)$_value;
  8747. +                break;
  8748. +
  8749. +            case 'all_empty':
  8750. +                $$_key = (string)$_value;
  8751. +                $day_empty = $month_empty = $year_empty = $all_empty;
  8752. +                break;
  8753. +
  8754. +            case 'display_days':
  8755. +            case 'display_months':
  8756. +            case 'display_years':
  8757. +            case 'year_as_text':
  8758. +            case 'reverse_years':
  8759. +                $$_key = (bool)$_value;
  8760. +                break;
  8761. +
  8762. +            default:
  8763. +                if(!is_array($_value)) {
  8764. +                    $extra_attrs .= ' '.$_key.'="'.smarty_function_escape_special_chars($_value).'"';
  8765. +                } else {
  8766. +                    $smarty->trigger_error("html_select_date: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
  8767. +                }
  8768. +                break;
  8769. +        }
  8770. +    }
  8771. +
  8772. +    if (preg_match('!^-\d+$!', $time)) {
  8773. +        // negative timestamp, use date()
  8774. +        $time = date('Y-m-d', $time);
  8775. +    }
  8776. +    // If $time is not in format yyyy-mm-dd
  8777. +    if (preg_match('/^(\d{0,4}-\d{0,2}-\d{0,2})/', $time, $found)) {
  8778. +        $time = $found[1];
  8779. +    } else {
  8780. +        // use smarty_make_timestamp to get an unix timestamp and
  8781. +        // strftime to make yyyy-mm-dd
  8782. +        $time = strftime('%Y-%m-%d', smarty_make_timestamp($time));
  8783. +    }
  8784. +    // Now split this in pieces, which later can be used to set the select
  8785. +    $time = explode("-", $time);
  8786. +
  8787. +    // make syntax "+N" or "-N" work with start_year and end_year
  8788. +    if (preg_match('!^(\+|\-)\s*(\d+)$!', $end_year, $match)) {
  8789. +        if ($match[1] == '+') {
  8790. +            $end_year = strftime('%Y') + $match[2];
  8791. +        } else {
  8792. +            $end_year = strftime('%Y') - $match[2];
  8793. +        }
  8794. +    }
  8795. +    if (preg_match('!^(\+|\-)\s*(\d+)$!', $start_year, $match)) {
  8796. +        if ($match[1] == '+') {
  8797. +            $start_year = strftime('%Y') + $match[2];
  8798. +        } else {
  8799. +            $start_year = strftime('%Y') - $match[2];
  8800. +        }
  8801. +    }
  8802. +    if (strlen($time[0]) > 0) {
  8803. +        if ($start_year > $time[0] && !isset($params['start_year'])) {
  8804. +            // force start year to include given date if not explicitly set
  8805. +            $start_year = $time[0];
  8806. +        }
  8807. +        if($end_year < $time[0] && !isset($params['end_year'])) {
  8808. +            // force end year to include given date if not explicitly set
  8809. +            $end_year = $time[0];
  8810. +        }
  8811. +    }
  8812. +
  8813. +    $field_order = strtoupper($field_order);
  8814. +
  8815. +    $html_result = $month_result = $day_result = $year_result = "";
  8816. +
  8817. +    $field_separator_count = -1;
  8818. +    if ($display_months) {
  8819. +       $field_separator_count++;
  8820. +        $month_names = array();
  8821. +        $month_values = array();
  8822. +        if(isset($month_empty)) {
  8823. +            $month_names[''] = $month_empty;
  8824. +            $month_values[''] = '';
  8825. +        }
  8826. +        for ($i = 1; $i <= 12; $i++) {
  8827. +            $month_names[$i] = strftime($month_format, mktime(0, 0, 0, $i, 1, 2000));
  8828. +            $month_values[$i] = strftime($month_value_format, mktime(0, 0, 0, $i, 1, 2000));
  8829. +        }
  8830. +
  8831. +        $month_result .= '<select name=';
  8832. +        if (null !== $field_array){
  8833. +            $month_result .= '"' . $field_array . '[' . $prefix . 'Month]"';
  8834. +        } else {
  8835. +            $month_result .= '"' . $prefix . 'Month"';
  8836. +        }
  8837. +        if (null !== $month_size){
  8838. +            $month_result .= ' size="' . $month_size . '"';
  8839. +        }
  8840. +        if (null !== $month_extra){
  8841. +            $month_result .= ' ' . $month_extra;
  8842. +        }
  8843. +        if (null !== $all_extra){
  8844. +            $month_result .= ' ' . $all_extra;
  8845. +        }
  8846. +        $month_result .= $extra_attrs . '>'."\n";
  8847. +
  8848. +        $month_result .= smarty_function_html_options(array('output'     => $month_names,
  8849. +                                                            'values'     => $month_values,
  8850. +                                                            'selected'   => (int)$time[1] ? strftime($month_value_format, mktime(0, 0, 0, (int)$time[1], 1, 2000)) : '',
  8851. +                                                            'print_result' => false),
  8852. +                                                      $smarty);
  8853. +        $month_result .= '</select>';
  8854. +    }
  8855. +
  8856. +    if ($display_days) {
  8857. +       $field_separator_count++;
  8858. +        $days = array();
  8859. +        if (isset($day_empty)) {
  8860. +            $days[''] = $day_empty;
  8861. +            $day_values[''] = '';
  8862. +        }
  8863. +        for ($i = 1; $i <= 31; $i++) {
  8864. +            $days[] = sprintf($day_format, $i);
  8865. +            $day_values[] = sprintf($day_value_format, $i);
  8866. +        }
  8867. +
  8868. +        $day_result .= '<select name=';
  8869. +        if (null !== $field_array){
  8870. +            $day_result .= '"' . $field_array . '[' . $prefix . 'Day]"';
  8871. +        } else {
  8872. +            $day_result .= '"' . $prefix . 'Day"';
  8873. +        }
  8874. +        if (null !== $day_size){
  8875. +            $day_result .= ' size="' . $day_size . '"';
  8876. +        }
  8877. +        if (null !== $all_extra){
  8878. +            $day_result .= ' ' . $all_extra;
  8879. +        }
  8880. +        if (null !== $day_extra){
  8881. +            $day_result .= ' ' . $day_extra;
  8882. +        }
  8883. +        $day_result .= $extra_attrs . '>'."\n";
  8884. +        $day_result .= smarty_function_html_options(array('output'     => $days,
  8885. +                                                          'values'     => $day_values,
  8886. +                                                          'selected'   => $time[2],
  8887. +                                                          'print_result' => false),
  8888. +                                                    $smarty);
  8889. +        $day_result .= '</select>';
  8890. +    }
  8891. +
  8892. +    if ($display_years) {
  8893. +       $field_separator_count++;
  8894. +        if (null !== $field_array){
  8895. +            $year_name = $field_array . '[' . $prefix . 'Year]';
  8896. +        } else {
  8897. +            $year_name = $prefix . 'Year';
  8898. +        }
  8899. +        if ($year_as_text) {
  8900. +            $year_result .= '<input type="text" name="' . $year_name . '" value="' . $time[0] . '" size="4" maxlength="4"';
  8901. +            if (null !== $all_extra){
  8902. +                $year_result .= ' ' . $all_extra;
  8903. +            }
  8904. +            if (null !== $year_extra){
  8905. +                $year_result .= ' ' . $year_extra;
  8906. +            }
  8907. +            $year_result .= ' />';
  8908. +        } else {
  8909. +            $years = range((int)$start_year, (int)$end_year);
  8910. +            if ($reverse_years) {
  8911. +                rsort($years, SORT_NUMERIC);
  8912. +            } else {
  8913. +                sort($years, SORT_NUMERIC);
  8914. +            }
  8915. +            $yearvals = $years;
  8916. +            if(isset($year_empty)) {
  8917. +                array_unshift($years, $year_empty);
  8918. +                array_unshift($yearvals, '');
  8919. +            }
  8920. +            $year_result .= '<select name="' . $year_name . '"';
  8921. +            if (null !== $year_size){
  8922. +                $year_result .= ' size="' . $year_size . '"';
  8923. +            }
  8924. +            if (null !== $all_extra){
  8925. +                $year_result .= ' ' . $all_extra;
  8926. +            }
  8927. +            if (null !== $year_extra){
  8928. +                $year_result .= ' ' . $year_extra;
  8929. +            }
  8930. +            $year_result .= $extra_attrs . '>'."\n";
  8931. +            $year_result .= smarty_function_html_options(array('output' => $years,
  8932. +                                                               'values' => $yearvals,
  8933. +                                                               'selected'   => $time[0],
  8934. +                                                               'print_result' => false),
  8935. +                                                         $smarty);
  8936. +            $year_result .= '</select>';
  8937. +        }
  8938. +    }
  8939. +
  8940. +    // Loop thru the field_order field
  8941. +    for ($i = 0; $i <= 2; $i++){
  8942. +        $c = substr($field_order, $i, 1);
  8943. +        switch ($c){
  8944. +            case 'D':
  8945. +                $html_result .= $day_result;
  8946. +                break;
  8947. +
  8948. +            case 'M':
  8949. +                $html_result .= $month_result;
  8950. +                break;
  8951. +
  8952. +            case 'Y':
  8953. +                $html_result .= $year_result;
  8954. +                break;
  8955. +        }
  8956. +        // Add the field seperator
  8957. +        if($i < $field_separator_count) {
  8958. +            $html_result .= $field_separator;
  8959. +        }
  8960. +    }
  8961. +
  8962. +    return $html_result;
  8963. +}
  8964. +
  8965. +/* vim: set expandtab: */
  8966. +
  8967. +?>
  8968. diff --git a/library/smarty/plugins/function.html_select_time.php b/library/smarty/plugins/function.html_select_time.php
  8969. new file mode 100644
  8970. --- /dev/null
  8971. +++ b/library/smarty/plugins/function.html_select_time.php
  8972. @@ -0,0 +1,194 @@
  8973. +<?php
  8974. +/**
  8975. + * Smarty plugin
  8976. + * @package Smarty
  8977. + * @subpackage plugins
  8978. + */
  8979. +
  8980. +
  8981. +/**
  8982. + * Smarty {html_select_time} function plugin
  8983. + *
  8984. + * Type:     function<br>
  8985. + * Name:     html_select_time<br>
  8986. + * Purpose:  Prints the dropdowns for time selection
  8987. + * @link http://smarty.php.net/manual/en/language.function.html.select.time.php {html_select_time}
  8988. + *          (Smarty online manual)
  8989. + * @author Roberto Berto <[email protected]>
  8990. + * @credits Monte Ohrt <monte AT ohrt DOT com>
  8991. + * @param array
  8992. + * @param Smarty
  8993. + * @return string
  8994. + * @uses smarty_make_timestamp()
  8995. + */
  8996. +function smarty_function_html_select_time($params, &$smarty)
  8997. +{
  8998. +    require_once $smarty->_get_plugin_filepath('shared','make_timestamp');
  8999. +    require_once $smarty->_get_plugin_filepath('function','html_options');
  9000. +    /* Default values. */
  9001. +    $prefix             = "Time_";
  9002. +    $time               = time();
  9003. +    $display_hours      = true;
  9004. +    $display_minutes    = true;
  9005. +    $display_seconds    = true;
  9006. +    $display_meridian   = true;
  9007. +    $use_24_hours       = true;
  9008. +    $minute_interval    = 1;
  9009. +    $second_interval    = 1;
  9010. +    /* Should the select boxes be part of an array when returned from PHP?
  9011. +       e.g. setting it to "birthday", would create "birthday[Hour]",
  9012. +       "birthday[Minute]", "birthday[Seconds]" & "birthday[Meridian]".
  9013. +       Can be combined with prefix. */
  9014. +    $field_array        = null;
  9015. +    $all_extra          = null;
  9016. +    $hour_extra         = null;
  9017. +    $minute_extra       = null;
  9018. +    $second_extra       = null;
  9019. +    $meridian_extra     = null;
  9020. +
  9021. +    foreach ($params as $_key=>$_value) {
  9022. +        switch ($_key) {
  9023. +            case 'prefix':
  9024. +            case 'time':
  9025. +            case 'field_array':
  9026. +            case 'all_extra':
  9027. +            case 'hour_extra':
  9028. +            case 'minute_extra':
  9029. +            case 'second_extra':
  9030. +            case 'meridian_extra':
  9031. +                $$_key = (string)$_value;
  9032. +                break;
  9033. +
  9034. +            case 'display_hours':
  9035. +            case 'display_minutes':
  9036. +            case 'display_seconds':
  9037. +            case 'display_meridian':
  9038. +            case 'use_24_hours':
  9039. +                $$_key = (bool)$_value;
  9040. +                break;
  9041. +
  9042. +            case 'minute_interval':
  9043. +            case 'second_interval':
  9044. +                $$_key = (int)$_value;
  9045. +                break;
  9046. +
  9047. +            default:
  9048. +                $smarty->trigger_error("[html_select_time] unknown parameter $_key", E_USER_WARNING);
  9049. +        }
  9050. +    }
  9051. +
  9052. +    $time = smarty_make_timestamp($time);
  9053. +
  9054. +    $html_result = '';
  9055. +
  9056. +    if ($display_hours) {
  9057. +        $hours       = $use_24_hours ? range(0, 23) : range(1, 12);
  9058. +        $hour_fmt = $use_24_hours ? '%H' : '%I';
  9059. +        for ($i = 0, $for_max = count($hours); $i < $for_max; $i++)
  9060. +            $hours[$i] = sprintf('%02d', $hours[$i]);
  9061. +        $html_result .= '<select name=';
  9062. +        if (null !== $field_array) {
  9063. +            $html_result .= '"' . $field_array . '[' . $prefix . 'Hour]"';
  9064. +        } else {
  9065. +            $html_result .= '"' . $prefix . 'Hour"';
  9066. +        }
  9067. +        if (null !== $hour_extra){
  9068. +            $html_result .= ' ' . $hour_extra;
  9069. +        }
  9070. +        if (null !== $all_extra){
  9071. +            $html_result .= ' ' . $all_extra;
  9072. +        }
  9073. +        $html_result .= '>'."\n";
  9074. +        $html_result .= smarty_function_html_options(array('output'          => $hours,
  9075. +                                                           'values'          => $hours,
  9076. +                                                           'selected'      => strftime($hour_fmt, $time),
  9077. +                                                           'print_result' => false),
  9078. +                                                     $smarty);
  9079. +        $html_result .= "</select>\n";
  9080. +    }
  9081. +
  9082. +    if ($display_minutes) {
  9083. +        $all_minutes = range(0, 59);
  9084. +        for ($i = 0, $for_max = count($all_minutes); $i < $for_max; $i+= $minute_interval)
  9085. +            $minutes[] = sprintf('%02d', $all_minutes[$i]);
  9086. +        $selected = intval(floor(strftime('%M', $time) / $minute_interval) * $minute_interval);
  9087. +        $html_result .= '<select name=';
  9088. +        if (null !== $field_array) {
  9089. +            $html_result .= '"' . $field_array . '[' . $prefix . 'Minute]"';
  9090. +        } else {
  9091. +            $html_result .= '"' . $prefix . 'Minute"';
  9092. +        }
  9093. +        if (null !== $minute_extra){
  9094. +            $html_result .= ' ' . $minute_extra;
  9095. +        }
  9096. +        if (null !== $all_extra){
  9097. +            $html_result .= ' ' . $all_extra;
  9098. +        }
  9099. +        $html_result .= '>'."\n";
  9100. +        
  9101. +        $html_result .= smarty_function_html_options(array('output'          => $minutes,
  9102. +                                                           'values'          => $minutes,
  9103. +                                                           'selected'      => $selected,
  9104. +                                                           'print_result' => false),
  9105. +                                                     $smarty);
  9106. +        $html_result .= "</select>\n";
  9107. +    }
  9108. +
  9109. +    if ($display_seconds) {
  9110. +        $all_seconds = range(0, 59);
  9111. +        for ($i = 0, $for_max = count($all_seconds); $i < $for_max; $i+= $second_interval)
  9112. +            $seconds[] = sprintf('%02d', $all_seconds[$i]);
  9113. +        $selected = intval(floor(strftime('%S', $time) / $second_interval) * $second_interval);
  9114. +        $html_result .= '<select name=';
  9115. +        if (null !== $field_array) {
  9116. +            $html_result .= '"' . $field_array . '[' . $prefix . 'Second]"';
  9117. +        } else {
  9118. +            $html_result .= '"' . $prefix . 'Second"';
  9119. +        }
  9120. +        
  9121. +        if (null !== $second_extra){
  9122. +            $html_result .= ' ' . $second_extra;
  9123. +        }
  9124. +        if (null !== $all_extra){
  9125. +            $html_result .= ' ' . $all_extra;
  9126. +        }
  9127. +        $html_result .= '>'."\n";
  9128. +        
  9129. +        $html_result .= smarty_function_html_options(array('output'          => $seconds,
  9130. +                                                           'values'          => $seconds,
  9131. +                                                           'selected'      => $selected,
  9132. +                                                           'print_result' => false),
  9133. +                                                     $smarty);
  9134. +        $html_result .= "</select>\n";
  9135. +    }
  9136. +
  9137. +    if ($display_meridian && !$use_24_hours) {
  9138. +        $html_result .= '<select name=';
  9139. +        if (null !== $field_array) {
  9140. +            $html_result .= '"' . $field_array . '[' . $prefix . 'Meridian]"';
  9141. +        } else {
  9142. +            $html_result .= '"' . $prefix . 'Meridian"';
  9143. +        }
  9144. +        
  9145. +        if (null !== $meridian_extra){
  9146. +            $html_result .= ' ' . $meridian_extra;
  9147. +        }
  9148. +        if (null !== $all_extra){
  9149. +            $html_result .= ' ' . $all_extra;
  9150. +        }
  9151. +        $html_result .= '>'."\n";
  9152. +        
  9153. +        $html_result .= smarty_function_html_options(array('output'          => array('AM', 'PM'),
  9154. +                                                           'values'          => array('am', 'pm'),
  9155. +                                                           'selected'      => strtolower(strftime('%p', $time)),
  9156. +                                                           'print_result' => false),
  9157. +                                                     $smarty);
  9158. +        $html_result .= "</select>\n";
  9159. +    }
  9160. +
  9161. +    return $html_result;
  9162. +}
  9163. +
  9164. +/* vim: set expandtab: */
  9165. +
  9166. +?>
  9167. diff --git a/library/smarty/plugins/function.html_table.php b/library/smarty/plugins/function.html_table.php
  9168. new file mode 100644
  9169. --- /dev/null
  9170. +++ b/library/smarty/plugins/function.html_table.php
  9171. @@ -0,0 +1,177 @@
  9172. +<?php
  9173. +/**
  9174. + * Smarty plugin
  9175. + * @package Smarty
  9176. + * @subpackage plugins
  9177. + */
  9178. +
  9179. +
  9180. +/**
  9181. + * Smarty {html_table} function plugin
  9182. + *
  9183. + * Type:     function<br>
  9184. + * Name:     html_table<br>
  9185. + * Date:     Feb 17, 2003<br>
  9186. + * Purpose:  make an html table from an array of data<br>
  9187. + * Input:<br>
  9188. + *         - loop = array to loop through
  9189. + *         - cols = number of columns, comma separated list of column names
  9190. + *                  or array of column names
  9191. + *         - rows = number of rows
  9192. + *         - table_attr = table attributes
  9193. + *         - th_attr = table heading attributes (arrays are cycled)
  9194. + *         - tr_attr = table row attributes (arrays are cycled)
  9195. + *         - td_attr = table cell attributes (arrays are cycled)
  9196. + *         - trailpad = value to pad trailing cells with
  9197. + *         - caption = text for caption element
  9198. + *         - vdir = vertical direction (default: "down", means top-to-bottom)
  9199. + *         - hdir = horizontal direction (default: "right", means left-to-right)
  9200. + *         - inner = inner loop (default "cols": print $loop line by line,
  9201. + *                   $loop will be printed column by column otherwise)
  9202. + *
  9203. + *
  9204. + * Examples:
  9205. + * <pre>
  9206. + * {table loop=$data}
  9207. + * {table loop=$data cols=4 tr_attr='"bgcolor=red"'}
  9208. + * {table loop=$data cols="first,second,third" tr_attr=$colors}
  9209. + * </pre>
  9210. + * @author   Monte Ohrt <monte at ohrt dot com>
  9211. + * @author credit to Messju Mohr <messju at lammfellpuschen dot de>
  9212. + * @author credit to boots <boots dot smarty at yahoo dot com>
  9213. + * @version  1.1
  9214. + * @link http://smarty.php.net/manual/en/language.function.html.table.php {html_table}
  9215. + *          (Smarty online manual)
  9216. + * @param array
  9217. + * @param Smarty
  9218. + * @return string
  9219. + */
  9220. +function smarty_function_html_table($params, &$smarty)
  9221. +{
  9222. +    $table_attr = 'border="1"';
  9223. +    $tr_attr = '';
  9224. +    $th_attr = '';
  9225. +    $td_attr = '';
  9226. +    $cols = $cols_count = 3;
  9227. +    $rows = 3;
  9228. +    $trailpad = '&nbsp;';
  9229. +    $vdir = 'down';
  9230. +    $hdir = 'right';
  9231. +    $inner = 'cols';
  9232. +    $caption = '';
  9233. +
  9234. +    if (!isset($params['loop'])) {
  9235. +        $smarty->trigger_error("html_table: missing 'loop' parameter");
  9236. +        return;
  9237. +    }
  9238. +
  9239. +    foreach ($params as $_key=>$_value) {
  9240. +        switch ($_key) {
  9241. +            case 'loop':
  9242. +                $$_key = (array)$_value;
  9243. +                break;
  9244. +
  9245. +            case 'cols':
  9246. +                if (is_array($_value) && !empty($_value)) {
  9247. +                    $cols = $_value;
  9248. +                    $cols_count = count($_value);
  9249. +                } elseif (!is_numeric($_value) && is_string($_value) && !empty($_value)) {
  9250. +                    $cols = explode(',', $_value);
  9251. +                    $cols_count = count($cols);
  9252. +                } elseif (!empty($_value)) {
  9253. +                    $cols_count = (int)$_value;
  9254. +                } else {
  9255. +                    $cols_count = $cols;
  9256. +                }
  9257. +                break;
  9258. +
  9259. +            case 'rows':
  9260. +                $$_key = (int)$_value;
  9261. +                break;
  9262. +
  9263. +            case 'table_attr':
  9264. +            case 'trailpad':
  9265. +            case 'hdir':
  9266. +            case 'vdir':
  9267. +            case 'inner':
  9268. +            case 'caption':
  9269. +                $$_key = (string)$_value;
  9270. +                break;
  9271. +
  9272. +            case 'tr_attr':
  9273. +            case 'td_attr':
  9274. +            case 'th_attr':
  9275. +                $$_key = $_value;
  9276. +                break;
  9277. +        }
  9278. +    }
  9279. +
  9280. +    $loop_count = count($loop);
  9281. +    if (empty($params['rows'])) {
  9282. +        /* no rows specified */
  9283. +        $rows = ceil($loop_count/$cols_count);
  9284. +    } elseif (empty($params['cols'])) {
  9285. +        if (!empty($params['rows'])) {
  9286. +            /* no cols specified, but rows */
  9287. +            $cols_count = ceil($loop_count/$rows);
  9288. +        }
  9289. +    }
  9290. +
  9291. +    $output = "<table $table_attr>\n";
  9292. +
  9293. +    if (!empty($caption)) {
  9294. +        $output .= '<caption>' . $caption . "</caption>\n";
  9295. +    }
  9296. +
  9297. +    if (is_array($cols)) {
  9298. +        $cols = ($hdir == 'right') ? $cols : array_reverse($cols);
  9299. +        $output .= "<thead><tr>\n";
  9300. +
  9301. +        for ($r=0; $r<$cols_count; $r++) {
  9302. +            $output .= '<th' . smarty_function_html_table_cycle('th', $th_attr, $r) . '>';
  9303. +            $output .= $cols[$r];
  9304. +            $output .= "</th>\n";
  9305. +        }
  9306. +        $output .= "</tr></thead>\n";
  9307. +    }
  9308. +
  9309. +    $output .= "<tbody>\n";
  9310. +    for ($r=0; $r<$rows; $r++) {
  9311. +        $output .= "<tr" . smarty_function_html_table_cycle('tr', $tr_attr, $r) . ">\n";
  9312. +        $rx =  ($vdir == 'down') ? $r*$cols_count : ($rows-1-$r)*$cols_count;
  9313. +
  9314. +        for ($c=0; $c<$cols_count; $c++) {
  9315. +            $x =  ($hdir == 'right') ? $rx+$c : $rx+$cols_count-1-$c;
  9316. +            if ($inner!='cols') {
  9317. +                /* shuffle x to loop over rows*/
  9318. +                $x = floor($x/$cols_count) + ($x%$cols_count)*$rows;
  9319. +            }
  9320. +
  9321. +            if ($x<$loop_count) {
  9322. +                $output .= "<td" . smarty_function_html_table_cycle('td', $td_attr, $c) . ">" . $loop[$x] . "</td>\n";
  9323. +            } else {
  9324. +                $output .= "<td" . smarty_function_html_table_cycle('td', $td_attr, $c) . ">$trailpad</td>\n";
  9325. +            }
  9326. +        }
  9327. +        $output .= "</tr>\n";
  9328. +    }
  9329. +    $output .= "</tbody>\n";
  9330. +    $output .= "</table>\n";
  9331. +    
  9332. +    return $output;
  9333. +}
  9334. +
  9335. +function smarty_function_html_table_cycle($name, $var, $no) {
  9336. +    if(!is_array($var)) {
  9337. +        $ret = $var;
  9338. +    } else {
  9339. +        $ret = $var[$no % count($var)];
  9340. +    }
  9341. +    
  9342. +    return ($ret) ? ' '.$ret : '';
  9343. +}
  9344. +
  9345. +
  9346. +/* vim: set expandtab: */
  9347. +
  9348. +?>
  9349. diff --git a/library/smarty/plugins/function.mailto.php b/library/smarty/plugins/function.mailto.php
  9350. new file mode 100644
  9351. --- /dev/null
  9352. +++ b/library/smarty/plugins/function.mailto.php
  9353. @@ -0,0 +1,165 @@
  9354. +<?php
  9355. +/**
  9356. + * Smarty plugin
  9357. + * @package Smarty
  9358. + * @subpackage plugins
  9359. + */
  9360. +
  9361. +
  9362. +/**
  9363. + * Smarty {mailto} function plugin
  9364. + *
  9365. + * Type:     function<br>
  9366. + * Name:     mailto<br>
  9367. + * Date:     May 21, 2002
  9368. + * Purpose:  automate mailto address link creation, and optionally
  9369. + *           encode them.<br>
  9370. + * Input:<br>
  9371. + *         - address = e-mail address
  9372. + *         - text = (optional) text to display, default is address
  9373. + *         - encode = (optional) can be one of:
  9374. + *                * none : no encoding (default)
  9375. + *                * javascript : encode with javascript
  9376. + *                * javascript_charcode : encode with javascript charcode
  9377. + *                * hex : encode with hexidecimal (no javascript)
  9378. + *         - cc = (optional) address(es) to carbon copy
  9379. + *         - bcc = (optional) address(es) to blind carbon copy
  9380. + *         - subject = (optional) e-mail subject
  9381. + *         - newsgroups = (optional) newsgroup(s) to post to
  9382. + *         - followupto = (optional) address(es) to follow up to
  9383. + *         - extra = (optional) extra tags for the href link
  9384. + *
  9385. + * Examples:
  9386. + * <pre>
  9387. + * {mailto address="[email protected]"}
  9388. + * {mailto address="[email protected]" encode="javascript"}
  9389. + * {mailto address="[email protected]" encode="hex"}
  9390. + * {mailto address="[email protected]" subject="Hello to you!"}
  9391. + * {mailto address="[email protected]" extra='class="mailto"'}
  9392. + * </pre>
  9393. + * @link http://smarty.php.net/manual/en/language.function.mailto.php {mailto}
  9394. + *          (Smarty online manual)
  9395. + * @version  1.2
  9396. + * @author   Monte Ohrt <monte at ohrt dot com>
  9397. + * @author   credits to Jason Sweat (added cc, bcc and subject functionality)
  9398. + * @param    array
  9399. + * @param    Smarty
  9400. + * @return   string
  9401. + */
  9402. +function smarty_function_mailto($params, &$smarty)
  9403. +{
  9404. +    $extra = '';
  9405. +
  9406. +    if (empty($params['address'])) {
  9407. +        $smarty->trigger_error("mailto: missing 'address' parameter");
  9408. +        return;
  9409. +    } else {
  9410. +        $address = $params['address'];
  9411. +    }
  9412. +
  9413. +    $text = $address;
  9414. +
  9415. +    // netscape and mozilla do not decode %40 (@) in BCC field (bug?)
  9416. +    // so, don't encode it.
  9417. +    $search = array('%40', '%2C');
  9418. +    $replace  = array('@', ',');
  9419. +    $mail_parms = array();
  9420. +    foreach ($params as $var=>$value) {
  9421. +        switch ($var) {
  9422. +            case 'cc':
  9423. +            case 'bcc':
  9424. +            case 'followupto':
  9425. +                if (!empty($value))
  9426. +                    $mail_parms[] = $var.'='.str_replace($search,$replace,rawurlencode($value));
  9427. +                break;
  9428. +                
  9429. +            case 'subject':
  9430. +            case 'newsgroups':
  9431. +                $mail_parms[] = $var.'='.rawurlencode($value);
  9432. +                break;
  9433. +
  9434. +            case 'extra':
  9435. +            case 'text':
  9436. +                $$var = $value;
  9437. +
  9438. +            default:
  9439. +        }
  9440. +    }
  9441. +
  9442. +    $mail_parm_vals = '';
  9443. +    for ($i=0; $i<count($mail_parms); $i++) {
  9444. +        $mail_parm_vals .= (0==$i) ? '?' : '&';
  9445. +        $mail_parm_vals .= $mail_parms[$i];
  9446. +    }
  9447. +    $address .= $mail_parm_vals;
  9448. +
  9449. +    $encode = (empty($params['encode'])) ? 'none' : $params['encode'];
  9450. +    if (!in_array($encode,array('javascript','javascript_charcode','hex','none')) ) {
  9451. +        $smarty->trigger_error("mailto: 'encode' parameter must be none, javascript or hex");
  9452. +        return;
  9453. +    }
  9454. +
  9455. +    if ($encode == 'javascript' ) {
  9456. +        $string = 'document.write(\'<a href="mailto:'.$address.'" '.$extra.'>'.$text.'</a>\');';
  9457. +
  9458. +        $js_encode = '';
  9459. +        for ($x=0; $x < strlen($string); $x++) {
  9460. +            $js_encode .= '%' . bin2hex($string[$x]);
  9461. +        }
  9462. +
  9463. +        return '<script type="text/javascript">eval(unescape(\''.$js_encode.'\'))</script>';
  9464. +
  9465. +    } elseif ($encode == 'javascript_charcode' ) {
  9466. +        $string = '<a href="mailto:'.$address.'" '.$extra.'>'.$text.'</a>';
  9467. +
  9468. +        for($x = 0, $y = strlen($string); $x < $y; $x++ ) {
  9469. +            $ord[] = ord($string[$x]);  
  9470. +        }
  9471. +
  9472. +        $_ret = "<script type=\"text/javascript\" language=\"javascript\">\n";
  9473. +        $_ret .= "<!--\n";
  9474. +        $_ret .= "{document.write(String.fromCharCode(";
  9475. +        $_ret .= implode(',',$ord);
  9476. +        $_ret .= "))";
  9477. +        $_ret .= "}\n";
  9478. +        $_ret .= "//-->\n";
  9479. +        $_ret .= "</script>\n";
  9480. +        
  9481. +        return $_ret;
  9482. +        
  9483. +        
  9484. +    } elseif ($encode == 'hex') {
  9485. +
  9486. +        preg_match('!^(.*)(\?.*)$!',$address,$match);
  9487. +        if(!empty($match[2])) {
  9488. +            $smarty->trigger_error("mailto: hex encoding does not work with extra attributes. Try javascript.");
  9489. +            return;
  9490. +        }
  9491. +        $address_encode = '';
  9492. +        for ($x=0; $x < strlen($address); $x++) {
  9493. +            if(preg_match('!\w!',$address[$x])) {
  9494. +                $address_encode .= '%' . bin2hex($address[$x]);
  9495. +            } else {
  9496. +                $address_encode .= $address[$x];
  9497. +            }
  9498. +        }
  9499. +        $text_encode = '';
  9500. +        for ($x=0; $x < strlen($text); $x++) {
  9501. +            $text_encode .= '&#x' . bin2hex($text[$x]).';';
  9502. +        }
  9503. +
  9504. +        $mailto = "&#109;&#97;&#105;&#108;&#116;&#111;&#58;";
  9505. +        return '<a href="'.$mailto.$address_encode.'" '.$extra.'>'.$text_encode.'</a>';
  9506. +
  9507. +    } else {
  9508. +        // no encoding
  9509. +        return '<a href="mailto:'.$address.'" '.$extra.'>'.$text.'</a>';
  9510. +
  9511. +    }
  9512. +
  9513. +}
  9514. +
  9515. +/* vim: set expandtab: */
  9516. +
  9517. +?>
  9518. diff --git a/library/smarty/plugins/function.math.php b/library/smarty/plugins/function.math.php
  9519. new file mode 100644
  9520. --- /dev/null
  9521. +++ b/library/smarty/plugins/function.math.php
  9522. @@ -0,0 +1,85 @@
  9523. +<?php
  9524. +/**
  9525. + * Smarty plugin
  9526. + * @package Smarty
  9527. + * @subpackage plugins
  9528. + */
  9529. +
  9530. +
  9531. +/**
  9532. + * Smarty {math} function plugin
  9533. + *
  9534. + * Type:     function<br>
  9535. + * Name:     math<br>
  9536. + * Purpose:  handle math computations in template<br>
  9537. + * @link http://smarty.php.net/manual/en/language.function.math.php {math}
  9538. + *          (Smarty online manual)
  9539. + * @author   Monte Ohrt <monte at ohrt dot com>
  9540. + * @param array
  9541. + * @param Smarty
  9542. + * @return string
  9543. + */
  9544. +function smarty_function_math($params, &$smarty)
  9545. +{
  9546. +    // be sure equation parameter is present
  9547. +    if (empty($params['equation'])) {
  9548. +        $smarty->trigger_error("math: missing equation parameter");
  9549. +        return;
  9550. +    }
  9551. +
  9552. +    // strip out backticks, not necessary for math
  9553. +    $equation = str_replace('`','',$params['equation']);
  9554. +
  9555. +    // make sure parenthesis are balanced
  9556. +    if (substr_count($equation,"(") != substr_count($equation,")")) {
  9557. +        $smarty->trigger_error("math: unbalanced parenthesis");
  9558. +        return;
  9559. +    }
  9560. +
  9561. +    // match all vars in equation, make sure all are passed
  9562. +    preg_match_all("!(?:0x[a-fA-F0-9]+)|([a-zA-Z][a-zA-Z0-9_]+)!",$equation, $match);
  9563. +    $allowed_funcs = array('int','abs','ceil','cos','exp','floor','log','log10',
  9564. +                           'max','min','pi','pow','rand','round','sin','sqrt','srand','tan');
  9565. +    
  9566. +    foreach($match[1] as $curr_var) {
  9567. +        if ($curr_var && !in_array($curr_var, array_keys($params)) && !in_array($curr_var, $allowed_funcs)) {
  9568. +            $smarty->trigger_error("math: function call $curr_var not allowed");
  9569. +            return;
  9570. +        }
  9571. +    }
  9572. +
  9573. +    foreach($params as $key => $val) {
  9574. +        if ($key != "equation" && $key != "format" && $key != "assign") {
  9575. +            // make sure value is not empty
  9576. +            if (strlen($val)==0) {
  9577. +                $smarty->trigger_error("math: parameter $key is empty");
  9578. +                return;
  9579. +            }
  9580. +            if (!is_numeric($val)) {
  9581. +                $smarty->trigger_error("math: parameter $key: is not numeric");
  9582. +                return;
  9583. +            }
  9584. +            $equation = preg_replace("/\b$key\b/", " \$params['$key'] ", $equation);
  9585. +        }
  9586. +    }
  9587. +
  9588. +    eval("\$smarty_math_result = ".$equation.";");
  9589. +
  9590. +    if (empty($params['format'])) {
  9591. +        if (empty($params['assign'])) {
  9592. +            return $smarty_math_result;
  9593. +        } else {
  9594. +            $smarty->assign($params['assign'],$smarty_math_result);
  9595. +        }
  9596. +    } else {
  9597. +        if (empty($params['assign'])){
  9598. +            printf($params['format'],$smarty_math_result);
  9599. +        } else {
  9600. +            $smarty->assign($params['assign'],sprintf($params['format'],$smarty_math_result));
  9601. +        }
  9602. +    }
  9603. +}
  9604. +
  9605. +/* vim: set expandtab: */
  9606. +
  9607. +?>
  9608. diff --git a/library/smarty/plugins/function.popup.php b/library/smarty/plugins/function.popup.php
  9609. new file mode 100644
  9610. --- /dev/null
  9611. +++ b/library/smarty/plugins/function.popup.php
  9612. @@ -0,0 +1,119 @@
  9613. +<?php
  9614. +/**
  9615. + * Smarty plugin
  9616. + * @package Smarty
  9617. + * @subpackage plugins
  9618. + */
  9619. +
  9620. +
  9621. +/**
  9622. + * Smarty {popup} function plugin
  9623. + *
  9624. + * Type:     function<br>
  9625. + * Name:     popup<br>
  9626. + * Purpose:  make text pop up in windows via overlib
  9627. + * @link http://smarty.php.net/manual/en/language.function.popup.php {popup}
  9628. + *          (Smarty online manual)
  9629. + * @author   Monte Ohrt <monte at ohrt dot com>
  9630. + * @param array
  9631. + * @param Smarty
  9632. + * @return string
  9633. + */
  9634. +function smarty_function_popup($params, &$smarty)
  9635. +{
  9636. +    $append = '';
  9637. +    foreach ($params as $_key=>$_value) {
  9638. +        switch ($_key) {
  9639. +            case 'text':
  9640. +            case 'trigger':
  9641. +            case 'function':
  9642. +            case 'inarray':
  9643. +                $$_key = (string)$_value;
  9644. +                if ($_key == 'function' || $_key == 'inarray')
  9645. +                    $append .= ',' . strtoupper($_key) . ",'$_value'";
  9646. +                break;
  9647. +
  9648. +            case 'caption':
  9649. +            case 'closetext':
  9650. +            case 'status':
  9651. +                $append .= ',' . strtoupper($_key) . ",'" . str_replace("'","\'",$_value) . "'";
  9652. +                break;
  9653. +
  9654. +            case 'fgcolor':
  9655. +            case 'bgcolor':
  9656. +            case 'textcolor':
  9657. +            case 'capcolor':
  9658. +            case 'closecolor':
  9659. +            case 'textfont':
  9660. +            case 'captionfont':
  9661. +            case 'closefont':
  9662. +            case 'fgbackground':
  9663. +            case 'bgbackground':
  9664. +            case 'caparray':
  9665. +            case 'capicon':
  9666. +            case 'background':
  9667. +            case 'frame':
  9668. +                $append .= ',' . strtoupper($_key) . ",'$_value'";
  9669. +                break;
  9670. +
  9671. +            case 'textsize':
  9672. +            case 'captionsize':
  9673. +            case 'closesize':
  9674. +            case 'width':
  9675. +            case 'height':
  9676. +            case 'border':
  9677. +            case 'offsetx':
  9678. +            case 'offsety':
  9679. +            case 'snapx':
  9680. +            case 'snapy':
  9681. +            case 'fixx':
  9682. +            case 'fixy':
  9683. +            case 'padx':
  9684. +            case 'pady':
  9685. +            case 'timeout':
  9686. +            case 'delay':
  9687. +                $append .= ',' . strtoupper($_key) . ",$_value";
  9688. +                break;
  9689. +
  9690. +            case 'sticky':
  9691. +            case 'left':
  9692. +            case 'right':
  9693. +            case 'center':
  9694. +            case 'above':
  9695. +            case 'below':
  9696. +            case 'noclose':
  9697. +            case 'autostatus':
  9698. +            case 'autostatuscap':
  9699. +            case 'fullhtml':
  9700. +            case 'hauto':
  9701. +            case 'vauto':
  9702. +            case 'mouseoff':
  9703. +            case 'followmouse':
  9704. +            case 'closeclick':
  9705. +                if ($_value) $append .= ',' . strtoupper($_key);
  9706. +                break;
  9707. +
  9708. +            default:
  9709. +                $smarty->trigger_error("[popup] unknown parameter $_key", E_USER_WARNING);
  9710. +        }
  9711. +    }
  9712. +
  9713. +    if (empty($text) && !isset($inarray) && empty($function)) {
  9714. +        $smarty->trigger_error("overlib: attribute 'text' or 'inarray' or 'function' required");
  9715. +        return false;
  9716. +    }
  9717. +
  9718. +    if (empty($trigger)) { $trigger = "onmouseover"; }
  9719. +
  9720. +    $retval = $trigger . '="return overlib(\''.preg_replace(array("!'!","![\r\n]!"),array("\'",'\r'),$text).'\'';
  9721. +    $retval .= $append . ');"';
  9722. +    if ($trigger == 'onmouseover')
  9723. +       $retval .= ' onmouseout="nd();"';
  9724. +
  9725. +
  9726. +    return $retval;
  9727. +}
  9728. +
  9729. +/* vim: set expandtab: */
  9730. +
  9731. +?>
  9732. diff --git a/library/smarty/plugins/function.popup_init.php b/library/smarty/plugins/function.popup_init.php
  9733. new file mode 100644
  9734. --- /dev/null
  9735. +++ b/library/smarty/plugins/function.popup_init.php
  9736. @@ -0,0 +1,40 @@
  9737. +<?php
  9738. +/**
  9739. + * Smarty plugin
  9740. + * @package Smarty
  9741. + * @subpackage plugins
  9742. + */
  9743. +
  9744. +
  9745. +/**
  9746. + * Smarty {popup_init} function plugin
  9747. + *
  9748. + * Type:     function<br>
  9749. + * Name:     popup_init<br>
  9750. + * Purpose:  initialize overlib
  9751. + * @link http://smarty.php.net/manual/en/language.function.popup.init.php {popup_init}
  9752. + *          (Smarty online manual)
  9753. + * @author   Monte Ohrt <monte at ohrt dot com>
  9754. + * @param array
  9755. + * @param Smarty
  9756. + * @return string
  9757. + */
  9758. +function smarty_function_popup_init($params, &$smarty)
  9759. +{
  9760. +    $zindex = 1000;
  9761. +    
  9762. +    if (!empty($params['zindex'])) {
  9763. +        $zindex = $params['zindex'];
  9764. +    }
  9765. +    
  9766. +    if (!empty($params['src'])) {
  9767. +        return '<div id="overDiv" style="position:absolute; visibility:hidden; z-index:'.$zindex.';"></div>' . "\n"
  9768. +         . '<script type="text/javascript" language="JavaScript" src="'.$params['src'].'"></script>' . "\n";
  9769. +    } else {
  9770. +        $smarty->trigger_error("popup_init: missing src parameter");
  9771. +    }
  9772. +}
  9773. +
  9774. +/* vim: set expandtab: */
  9775. +
  9776. +?>
  9777. diff --git a/library/smarty/plugins/modifier.capitalize.php b/library/smarty/plugins/modifier.capitalize.php
  9778. new file mode 100644
  9779. --- /dev/null
  9780. +++ b/library/smarty/plugins/modifier.capitalize.php
  9781. @@ -0,0 +1,43 @@
  9782. +<?php
  9783. +/**
  9784. + * Smarty plugin
  9785. + * @package Smarty
  9786. + * @subpackage plugins
  9787. + */
  9788. +
  9789. +
  9790. +/**
  9791. + * Smarty capitalize modifier plugin
  9792. + *
  9793. + * Type:     modifier<br>
  9794. + * Name:     capitalize<br>
  9795. + * Purpose:  capitalize words in the string
  9796. + * @link http://smarty.php.net/manual/en/language.modifiers.php#LANGUAGE.MODIFIER.CAPITALIZE
  9797. + *      capitalize (Smarty online manual)
  9798. + * @author   Monte Ohrt <monte at ohrt dot com>
  9799. + * @param string
  9800. + * @return string
  9801. + */
  9802. +function smarty_modifier_capitalize($string, $uc_digits = false)
  9803. +{
  9804. +    smarty_modifier_capitalize_ucfirst(null, $uc_digits);
  9805. +    return preg_replace_callback('!\'?\b\w(\w|\')*\b!', 'smarty_modifier_capitalize_ucfirst', $string);
  9806. +}
  9807. +
  9808. +function smarty_modifier_capitalize_ucfirst($string, $uc_digits = null)
  9809. +{
  9810. +    static $_uc_digits = false;
  9811. +    
  9812. +    if(isset($uc_digits)) {
  9813. +        $_uc_digits = $uc_digits;
  9814. +        return;
  9815. +    }
  9816. +    
  9817. +    if(substr($string[0],0,1) != "'" && !preg_match("!\d!",$string[0]) || $_uc_digits)
  9818. +        return ucfirst($string[0]);
  9819. +    else
  9820. +        return $string[0];
  9821. +}
  9822. +
  9823. +
  9824. +?>
  9825. diff --git a/library/smarty/plugins/modifier.cat.php b/library/smarty/plugins/modifier.cat.php
  9826. new file mode 100644
  9827. --- /dev/null
  9828. +++ b/library/smarty/plugins/modifier.cat.php
  9829. @@ -0,0 +1,33 @@
  9830. +<?php
  9831. +/**
  9832. + * Smarty plugin
  9833. + * @package Smarty
  9834. + * @subpackage plugins
  9835. + */
  9836. +
  9837. +
  9838. +/**
  9839. + * Smarty cat modifier plugin
  9840. + *
  9841. + * Type:     modifier<br>
  9842. + * Name:     cat<br>
  9843. + * Date:     Feb 24, 2003
  9844. + * Purpose:  catenate a value to a variable
  9845. + * Input:    string to catenate
  9846. + * Example:  {$var|cat:"foo"}
  9847. + * @link http://smarty.php.net/manual/en/language.modifier.cat.php cat
  9848. + *          (Smarty online manual)
  9849. + * @author   Monte Ohrt <monte at ohrt dot com>
  9850. + * @version 1.0
  9851. + * @param string
  9852. + * @param string
  9853. + * @return string
  9854. + */
  9855. +function smarty_modifier_cat($string, $cat)
  9856. +{
  9857. +    return $string . $cat;
  9858. +}
  9859. +
  9860. +/* vim: set expandtab: */
  9861. +
  9862. +?>
  9863. diff --git a/library/smarty/plugins/modifier.count_characters.php b/library/smarty/plugins/modifier.count_characters.php
  9864. new file mode 100644
  9865. --- /dev/null
  9866. +++ b/library/smarty/plugins/modifier.count_characters.php
  9867. @@ -0,0 +1,32 @@
  9868. +<?php
  9869. +/**
  9870. + * Smarty plugin
  9871. + * @package Smarty
  9872. + * @subpackage plugins
  9873. + */
  9874. +
  9875. +
  9876. +/**
  9877. + * Smarty count_characters modifier plugin
  9878. + *
  9879. + * Type:     modifier<br>
  9880. + * Name:     count_characteres<br>
  9881. + * Purpose:  count the number of characters in a text
  9882. + * @link http://smarty.php.net/manual/en/language.modifier.count.characters.php
  9883. + *          count_characters (Smarty online manual)
  9884. + * @author   Monte Ohrt <monte at ohrt dot com>
  9885. + * @param string
  9886. + * @param boolean include whitespace in the character count
  9887. + * @return integer
  9888. + */
  9889. +function smarty_modifier_count_characters($string, $include_spaces = false)
  9890. +{
  9891. +    if ($include_spaces)
  9892. +       return(strlen($string));
  9893. +
  9894. +    return preg_match_all("/[^\s]/",$string, $match);
  9895. +}
  9896. +
  9897. +/* vim: set expandtab: */
  9898. +
  9899. +?>
  9900. diff --git a/library/smarty/plugins/modifier.count_paragraphs.php b/library/smarty/plugins/modifier.count_paragraphs.php
  9901. new file mode 100644
  9902. --- /dev/null
  9903. +++ b/library/smarty/plugins/modifier.count_paragraphs.php
  9904. @@ -0,0 +1,29 @@
  9905. +<?php
  9906. +/**
  9907. + * Smarty plugin
  9908. + * @package Smarty
  9909. + * @subpackage plugins
  9910. + */
  9911. +
  9912. +
  9913. +/**
  9914. + * Smarty count_paragraphs modifier plugin
  9915. + *
  9916. + * Type:     modifier<br>
  9917. + * Name:     count_paragraphs<br>
  9918. + * Purpose:  count the number of paragraphs in a text
  9919. + * @link http://smarty.php.net/manual/en/language.modifier.count.paragraphs.php
  9920. + *          count_paragraphs (Smarty online manual)
  9921. + * @author   Monte Ohrt <monte at ohrt dot com>
  9922. + * @param string
  9923. + * @return integer
  9924. + */
  9925. +function smarty_modifier_count_paragraphs($string)
  9926. +{
  9927. +    // count \r or \n characters
  9928. +    return count(preg_split('/[\r\n]+/', $string));
  9929. +}
  9930. +
  9931. +/* vim: set expandtab: */
  9932. +
  9933. +?>
  9934. diff --git a/library/smarty/plugins/modifier.count_sentences.php b/library/smarty/plugins/modifier.count_sentences.php
  9935. new file mode 100644
  9936. --- /dev/null
  9937. +++ b/library/smarty/plugins/modifier.count_sentences.php
  9938. @@ -0,0 +1,29 @@
  9939. +<?php
  9940. +/**
  9941. + * Smarty plugin
  9942. + * @package Smarty
  9943. + * @subpackage plugins
  9944. + */
  9945. +
  9946. +
  9947. +/**
  9948. + * Smarty count_sentences modifier plugin
  9949. + *
  9950. + * Type:     modifier<br>
  9951. + * Name:     count_sentences
  9952. + * Purpose:  count the number of sentences in a text
  9953. + * @link http://smarty.php.net/manual/en/language.modifier.count.paragraphs.php
  9954. + *          count_sentences (Smarty online manual)
  9955. + * @author   Monte Ohrt <monte at ohrt dot com>
  9956. + * @param string
  9957. + * @return integer
  9958. + */
  9959. +function smarty_modifier_count_sentences($string)
  9960. +{
  9961. +    // find periods with a word before but not after.
  9962. +    return preg_match_all('/[^\s]\.(?!\w)/', $string, $match);
  9963. +}
  9964. +
  9965. +/* vim: set expandtab: */
  9966. +
  9967. +?>
  9968. diff --git a/library/smarty/plugins/modifier.count_words.php b/library/smarty/plugins/modifier.count_words.php
  9969. new file mode 100644
  9970. --- /dev/null
  9971. +++ b/library/smarty/plugins/modifier.count_words.php
  9972. @@ -0,0 +1,33 @@
  9973. +<?php
  9974. +/**
  9975. + * Smarty plugin
  9976. + * @package Smarty
  9977. + * @subpackage plugins
  9978. + */
  9979. +
  9980. +
  9981. +/**
  9982. + * Smarty count_words modifier plugin
  9983. + *
  9984. + * Type:     modifier<br>
  9985. + * Name:     count_words<br>
  9986. + * Purpose:  count the number of words in a text
  9987. + * @link http://smarty.php.net/manual/en/language.modifier.count.words.php
  9988. + *          count_words (Smarty online manual)
  9989. + * @author   Monte Ohrt <monte at ohrt dot com>
  9990. + * @param string
  9991. + * @return integer
  9992. + */
  9993. +function smarty_modifier_count_words($string)
  9994. +{
  9995. +    // split text by ' ',\r,\n,\f,\t
  9996. +    $split_array = preg_split('/\s+/',$string);
  9997. +    // count matches that contain alphanumerics
  9998. +    $word_count = preg_grep('/[a-zA-Z0-9\\x80-\\xff]/', $split_array);
  9999. +
  10000. +    return count($word_count);
  10001. +}
  10002. +
  10003. +/* vim: set expandtab: */
  10004. +
  10005. +?>
  10006. diff --git a/library/smarty/plugins/modifier.date_format.php b/library/smarty/plugins/modifier.date_format.php
  10007. new file mode 100644
  10008. --- /dev/null
  10009. +++ b/library/smarty/plugins/modifier.date_format.php
  10010. @@ -0,0 +1,58 @@
  10011. +<?php
  10012. +/**
  10013. + * Smarty plugin
  10014. + * @package Smarty
  10015. + * @subpackage plugins
  10016. + */
  10017. +
  10018. +/**
  10019. + * Include the {@link shared.make_timestamp.php} plugin
  10020. + */
  10021. +require_once $smarty->_get_plugin_filepath('shared', 'make_timestamp');
  10022. +/**
  10023. + * Smarty date_format modifier plugin
  10024. + *
  10025. + * Type:     modifier<br>
  10026. + * Name:     date_format<br>
  10027. + * Purpose:  format datestamps via strftime<br>
  10028. + * Input:<br>
  10029. + *         - string: input date string
  10030. + *         - format: strftime format for output
  10031. + *         - default_date: default date if $string is empty
  10032. + * @link http://smarty.php.net/manual/en/language.modifier.date.format.php
  10033. + *          date_format (Smarty online manual)
  10034. + * @author   Monte Ohrt <monte at ohrt dot com>
  10035. + * @param string
  10036. + * @param string
  10037. + * @param string
  10038. + * @return string|void
  10039. + * @uses smarty_make_timestamp()
  10040. + */
  10041. +function smarty_modifier_date_format($string, $format = '%b %e, %Y', $default_date = '')
  10042. +{
  10043. +    if ($string != '') {
  10044. +        $timestamp = smarty_make_timestamp($string);
  10045. +    } elseif ($default_date != '') {
  10046. +        $timestamp = smarty_make_timestamp($default_date);
  10047. +    } else {
  10048. +        return;
  10049. +    }
  10050. +    if (DIRECTORY_SEPARATOR == '\\') {
  10051. +        $_win_from = array('%D',       '%h', '%n', '%r',          '%R',    '%t', '%T');
  10052. +        $_win_to   = array('%m/%d/%y', '%b', "\n", '%I:%M:%S %p', '%H:%M', "\t", '%H:%M:%S');
  10053. +        if (strpos($format, '%e') !== false) {
  10054. +            $_win_from[] = '%e';
  10055. +            $_win_to[]   = sprintf('%\' 2d', date('j', $timestamp));
  10056. +        }
  10057. +        if (strpos($format, '%l') !== false) {
  10058. +            $_win_from[] = '%l';
  10059. +            $_win_to[]   = sprintf('%\' 2d', date('h', $timestamp));
  10060. +        }
  10061. +        $format = str_replace($_win_from, $_win_to, $format);
  10062. +    }
  10063. +    return strftime($format, $timestamp);
  10064. +}
  10065. +
  10066. +/* vim: set expandtab: */
  10067. +
  10068. +?>
  10069. diff --git a/library/smarty/plugins/modifier.debug_print_var.php b/library/smarty/plugins/modifier.debug_print_var.php
  10070. new file mode 100644
  10071. --- /dev/null
  10072. +++ b/library/smarty/plugins/modifier.debug_print_var.php
  10073. @@ -0,0 +1,90 @@
  10074. +<?php
  10075. +/**
  10076. + * Smarty plugin
  10077. + * @package Smarty
  10078. + * @subpackage plugins
  10079. + */
  10080. +
  10081. +
  10082. +/**
  10083. + * Smarty debug_print_var modifier plugin
  10084. + *
  10085. + * Type:     modifier<br>
  10086. + * Name:     debug_print_var<br>
  10087. + * Purpose:  formats variable contents for display in the console
  10088. + * @link http://smarty.php.net/manual/en/language.modifier.debug.print.var.php
  10089. + *          debug_print_var (Smarty online manual)
  10090. + * @author   Monte Ohrt <monte at ohrt dot com>
  10091. + * @param array|object
  10092. + * @param integer
  10093. + * @param integer
  10094. + * @return string
  10095. + */
  10096. +function smarty_modifier_debug_print_var($var, $depth = 0, $length = 40)
  10097. +{
  10098. +    $_replace = array(
  10099. +        "\n" => '<i>\n</i>',
  10100. +        "\r" => '<i>\r</i>',
  10101. +        "\t" => '<i>\t</i>'
  10102. +    );
  10103. +
  10104. +    switch (gettype($var)) {
  10105. +        case 'array' :
  10106. +            $results = '<b>Array (' . count($var) . ')</b>';
  10107. +            foreach ($var as $curr_key => $curr_val) {
  10108. +                $results .= '<br>' . str_repeat('&nbsp;', $depth * 2)
  10109. +                    . '<b>' . strtr($curr_key, $_replace) . '</b> =&gt; '
  10110. +                    . smarty_modifier_debug_print_var($curr_val, ++$depth, $length);
  10111. +                    $depth--;
  10112. +            }
  10113. +            break;
  10114. +        case 'object' :
  10115. +            $object_vars = get_object_vars($var);
  10116. +            $results = '<b>' . get_class($var) . ' Object (' . count($object_vars) . ')</b>';
  10117. +            foreach ($object_vars as $curr_key => $curr_val) {
  10118. +                $results .= '<br>' . str_repeat('&nbsp;', $depth * 2)
  10119. +                    . '<b> -&gt;' . strtr($curr_key, $_replace) . '</b> = '
  10120. +                    . smarty_modifier_debug_print_var($curr_val, ++$depth, $length);
  10121. +                    $depth--;
  10122. +            }
  10123. +            break;
  10124. +        case 'boolean' :
  10125. +        case 'NULL' :
  10126. +        case 'resource' :
  10127. +            if (true === $var) {
  10128. +                $results = 'true';
  10129. +            } elseif (false === $var) {
  10130. +                $results = 'false';
  10131. +            } elseif (null === $var) {
  10132. +                $results = 'null';
  10133. +            } else {
  10134. +                $results = htmlspecialchars((string) $var);
  10135. +            }
  10136. +            $results = '<i>' . $results . '</i>';
  10137. +            break;
  10138. +        case 'integer' :
  10139. +        case 'float' :
  10140. +            $results = htmlspecialchars((string) $var);
  10141. +            break;
  10142. +        case 'string' :
  10143. +            $results = strtr($var, $_replace);
  10144. +            if (strlen($var) > $length ) {
  10145. +                $results = substr($var, 0, $length - 3) . '...';
  10146. +            }
  10147. +            $results = htmlspecialchars('"' . $results . '"');
  10148. +            break;
  10149. +        case 'unknown type' :
  10150. +        default :
  10151. +            $results = strtr((string) $var, $_replace);
  10152. +            if (strlen($results) > $length ) {
  10153. +                $results = substr($results, 0, $length - 3) . '...';
  10154. +            }
  10155. +            $results = htmlspecialchars($results);
  10156. +    }
  10157. +
  10158. +    return $results;
  10159. +}
  10160. +
  10161. +/* vim: set expandtab: */
  10162. +
  10163. +?>
  10164. diff --git a/library/smarty/plugins/modifier.default.php b/library/smarty/plugins/modifier.default.php
  10165. new file mode 100644
  10166. --- /dev/null
  10167. +++ b/library/smarty/plugins/modifier.default.php
  10168. @@ -0,0 +1,32 @@
  10169. +<?php
  10170. +/**
  10171. + * Smarty plugin
  10172. + * @package Smarty
  10173. + * @subpackage plugins
  10174. + */
  10175. +
  10176. +
  10177. +/**
  10178. + * Smarty default modifier plugin
  10179. + *
  10180. + * Type:     modifier<br>
  10181. + * Name:     default<br>
  10182. + * Purpose:  designate default value for empty variables
  10183. + * @link http://smarty.php.net/manual/en/language.modifier.default.php
  10184. + *          default (Smarty online manual)
  10185. + * @author   Monte Ohrt <monte at ohrt dot com>
  10186. + * @param string
  10187. + * @param string
  10188. + * @return string
  10189. + */
  10190. +function smarty_modifier_default($string, $default = '')
  10191. +{
  10192. +    if (!isset($string) || $string === '')
  10193. +        return $default;
  10194. +    else
  10195. +        return $string;
  10196. +}
  10197. +
  10198. +/* vim: set expandtab: */
  10199. +
  10200. +?>
  10201. diff --git a/library/smarty/plugins/modifier.escape.php b/library/smarty/plugins/modifier.escape.php
  10202. new file mode 100644
  10203. --- /dev/null
  10204. +++ b/library/smarty/plugins/modifier.escape.php
  10205. @@ -0,0 +1,93 @@
  10206. +<?php
  10207. +/**
  10208. + * Smarty plugin
  10209. + * @package Smarty
  10210. + * @subpackage plugins
  10211. + */
  10212. +
  10213. +
  10214. +/**
  10215. + * Smarty escape modifier plugin
  10216. + *
  10217. + * Type:     modifier<br>
  10218. + * Name:     escape<br>
  10219. + * Purpose:  Escape the string according to escapement type
  10220. + * @link http://smarty.php.net/manual/en/language.modifier.escape.php
  10221. + *          escape (Smarty online manual)
  10222. + * @author   Monte Ohrt <monte at ohrt dot com>
  10223. + * @param string
  10224. + * @param html|htmlall|url|quotes|hex|hexentity|javascript
  10225. + * @return string
  10226. + */
  10227. +function smarty_modifier_escape($string, $esc_type = 'html', $char_set = 'ISO-8859-1')
  10228. +{
  10229. +    switch ($esc_type) {
  10230. +        case 'html':
  10231. +            return htmlspecialchars($string, ENT_QUOTES, $char_set);
  10232. +
  10233. +        case 'htmlall':
  10234. +            return htmlentities($string, ENT_QUOTES, $char_set);
  10235. +
  10236. +        case 'url':
  10237. +            return rawurlencode($string);
  10238. +
  10239. +        case 'urlpathinfo':
  10240. +            return str_replace('%2F','/',rawurlencode($string));
  10241. +            
  10242. +        case 'quotes':
  10243. +            // escape unescaped single quotes
  10244. +            return preg_replace("%(?<!\\\\)'%", "\\'", $string);
  10245. +
  10246. +        case 'hex':
  10247. +            // escape every character into hex
  10248. +            $return = '';
  10249. +            for ($x=0; $x < strlen($string); $x++) {
  10250. +                $return .= '%' . bin2hex($string[$x]);
  10251. +            }
  10252. +            return $return;
  10253. +            
  10254. +        case 'hexentity':
  10255. +            $return = '';
  10256. +            for ($x=0; $x < strlen($string); $x++) {
  10257. +                $return .= '&#x' . bin2hex($string[$x]) . ';';
  10258. +            }
  10259. +            return $return;
  10260. +
  10261. +        case 'decentity':
  10262. +            $return = '';
  10263. +            for ($x=0; $x < strlen($string); $x++) {
  10264. +                $return .= '&#' . ord($string[$x]) . ';';
  10265. +            }
  10266. +            return $return;
  10267. +
  10268. +        case 'javascript':
  10269. +            // escape quotes and backslashes, newlines, etc.
  10270. +            return strtr($string, array('\\'=>'\\\\',"'"=>"\\'",'"'=>'\\"',"\r"=>'\\r',"\n"=>'\\n','</'=>'<\/'));
  10271. +            
  10272. +        case 'mail':
  10273. +            // safe way to display e-mail address on a web page
  10274. +            return str_replace(array('@', '.'),array(' [AT] ', ' [DOT] '), $string);
  10275. +            
  10276. +        case 'nonstd':
  10277. +           // escape non-standard chars, such as ms document quotes
  10278. +           $_res = '';
  10279. +           for($_i = 0, $_len = strlen($string); $_i < $_len; $_i++) {
  10280. +               $_ord = ord(substr($string, $_i, 1));
  10281. +               // non-standard char, escape it
  10282. +               if($_ord >= 126){
  10283. +                   $_res .= '&#' . $_ord . ';';
  10284. +               }
  10285. +               else {
  10286. +                   $_res .= substr($string, $_i, 1);
  10287. +               }
  10288. +           }
  10289. +           return $_res;
  10290. +
  10291. +        default:
  10292. +            return $string;
  10293. +    }
  10294. +}
  10295. +
  10296. +/* vim: set expandtab: */
  10297. +
  10298. +?>
  10299. diff --git a/library/smarty/plugins/modifier.indent.php b/library/smarty/plugins/modifier.indent.php
  10300. new file mode 100644
  10301. --- /dev/null
  10302. +++ b/library/smarty/plugins/modifier.indent.php
  10303. @@ -0,0 +1,28 @@
  10304. +<?php
  10305. +/**
  10306. + * Smarty plugin
  10307. + * @package Smarty
  10308. + * @subpackage plugins
  10309. + */
  10310. +
  10311. +
  10312. +/**
  10313. + * Smarty indent modifier plugin
  10314. + *
  10315. + * Type:     modifier<br>
  10316. + * Name:     indent<br>
  10317. + * Purpose:  indent lines of text
  10318. + * @link http://smarty.php.net/manual/en/language.modifier.indent.php
  10319. + *          indent (Smarty online manual)
  10320. + * @author   Monte Ohrt <monte at ohrt dot com>
  10321. + * @param string
  10322. + * @param integer
  10323. + * @param string
  10324. + * @return string
  10325. + */
  10326. +function smarty_modifier_indent($string,$chars=4,$char=" ")
  10327. +{
  10328. +    return preg_replace('!^!m',str_repeat($char,$chars),$string);
  10329. +}
  10330. +
  10331. +?>
  10332. diff --git a/library/smarty/plugins/modifier.lower.php b/library/smarty/plugins/modifier.lower.php
  10333. new file mode 100644
  10334. --- /dev/null
  10335. +++ b/library/smarty/plugins/modifier.lower.php
  10336. @@ -0,0 +1,26 @@
  10337. +<?php
  10338. +/**
  10339. + * Smarty plugin
  10340. + * @package Smarty
  10341. + * @subpackage plugins
  10342. + */
  10343. +
  10344. +
  10345. +/**
  10346. + * Smarty lower modifier plugin
  10347. + *
  10348. + * Type:     modifier<br>
  10349. + * Name:     lower<br>
  10350. + * Purpose:  convert string to lowercase
  10351. + * @link http://smarty.php.net/manual/en/language.modifier.lower.php
  10352. + *          lower (Smarty online manual)
  10353. + * @author   Monte Ohrt <monte at ohrt dot com>
  10354. + * @param string
  10355. + * @return string
  10356. + */
  10357. +function smarty_modifier_lower($string)
  10358. +{
  10359. +    return strtolower($string);
  10360. +}
  10361. +
  10362. +?>
  10363. diff --git a/library/smarty/plugins/modifier.nl2br.php b/library/smarty/plugins/modifier.nl2br.php
  10364. new file mode 100644
  10365. --- /dev/null
  10366. +++ b/library/smarty/plugins/modifier.nl2br.php
  10367. @@ -0,0 +1,35 @@
  10368. +<?php
  10369. +/**
  10370. + * Smarty plugin
  10371. + * @package Smarty
  10372. + * @subpackage plugins
  10373. + */
  10374. +
  10375. +
  10376. +/**
  10377. + * Smarty plugin
  10378. + *
  10379. + * Type:     modifier<br>
  10380. + * Name:     nl2br<br>
  10381. + * Date:     Feb 26, 2003
  10382. + * Purpose:  convert \r\n, \r or \n to <<br>>
  10383. + * Input:<br>
  10384. + *         - contents = contents to replace
  10385. + *         - preceed_test = if true, includes preceeding break tags
  10386. + *           in replacement
  10387. + * Example:  {$text|nl2br}
  10388. + * @link http://smarty.php.net/manual/en/language.modifier.nl2br.php
  10389. + *          nl2br (Smarty online manual)
  10390. + * @version  1.0
  10391. + * @author   Monte Ohrt <monte at ohrt dot com>
  10392. + * @param string
  10393. + * @return string
  10394. + */
  10395. +function smarty_modifier_nl2br($string)
  10396. +{
  10397. +    return nl2br($string);
  10398. +}
  10399. +
  10400. +/* vim: set expandtab: */
  10401. +
  10402. +?>
  10403. diff --git a/library/smarty/plugins/modifier.regex_replace.php b/library/smarty/plugins/modifier.regex_replace.php
  10404. new file mode 100644
  10405. --- /dev/null
  10406. +++ b/library/smarty/plugins/modifier.regex_replace.php
  10407. @@ -0,0 +1,48 @@
  10408. +<?php
  10409. +/**
  10410. + * Smarty plugin
  10411. + * @package Smarty
  10412. + * @subpackage plugins
  10413. + */
  10414. +
  10415. +
  10416. +/**
  10417. + * Smarty regex_replace modifier plugin
  10418. + *
  10419. + * Type:     modifier<br>
  10420. + * Name:     regex_replace<br>
  10421. + * Purpose:  regular expression search/replace
  10422. + * @link http://smarty.php.net/manual/en/language.modifier.regex.replace.php
  10423. + *          regex_replace (Smarty online manual)
  10424. + * @author   Monte Ohrt <monte at ohrt dot com>
  10425. + * @param string
  10426. + * @param string|array
  10427. + * @param string|array
  10428. + * @return string
  10429. + */
  10430. +function smarty_modifier_regex_replace($string, $search, $replace)
  10431. +{
  10432. +    if(is_array($search)) {
  10433. +      foreach($search as $idx => $s)
  10434. +        $search[$idx] = _smarty_regex_replace_check($s);
  10435. +    } else {
  10436. +      $search = _smarty_regex_replace_check($search);
  10437. +    }      
  10438. +
  10439. +    return preg_replace($search, $replace, $string);
  10440. +}
  10441. +
  10442. +function _smarty_regex_replace_check($search)
  10443. +{
  10444. +    if (($pos = strpos($search,"\0")) !== false)
  10445. +      $search = substr($search,0,$pos);
  10446. +    if (preg_match('!([a-zA-Z\s]+)$!s', $search, $match) && (strpos($match[1], 'e') !== false)) {
  10447. +        /* remove eval-modifier from $search */
  10448. +        $search = substr($search, 0, -strlen($match[1])) . preg_replace('![e\s]+!', '', $match[1]);
  10449. +    }
  10450. +    return $search;
  10451. +}
  10452. +
  10453. +/* vim: set expandtab: */
  10454. +
  10455. +?>
  10456. diff --git a/library/smarty/plugins/modifier.replace.php b/library/smarty/plugins/modifier.replace.php
  10457. new file mode 100644
  10458. --- /dev/null
  10459. +++ b/library/smarty/plugins/modifier.replace.php
  10460. @@ -0,0 +1,30 @@
  10461. +<?php
  10462. +/**
  10463. + * Smarty plugin
  10464. + * @package Smarty
  10465. + * @subpackage plugins
  10466. + */
  10467. +
  10468. +
  10469. +/**
  10470. + * Smarty replace modifier plugin
  10471. + *
  10472. + * Type:     modifier<br>
  10473. + * Name:     replace<br>
  10474. + * Purpose:  simple search/replace
  10475. + * @link http://smarty.php.net/manual/en/language.modifier.replace.php
  10476. + *          replace (Smarty online manual)
  10477. + * @author   Monte Ohrt <monte at ohrt dot com>
  10478. + * @param string
  10479. + * @param string
  10480. + * @param string
  10481. + * @return string
  10482. + */
  10483. +function smarty_modifier_replace($string, $search, $replace)
  10484. +{
  10485. +    return str_replace($search, $replace, $string);
  10486. +}
  10487. +
  10488. +/* vim: set expandtab: */
  10489. +
  10490. +?>
  10491. diff --git a/library/smarty/plugins/modifier.spacify.php b/library/smarty/plugins/modifier.spacify.php
  10492. new file mode 100644
  10493. --- /dev/null
  10494. +++ b/library/smarty/plugins/modifier.spacify.php
  10495. @@ -0,0 +1,30 @@
  10496. +<?php
  10497. +/**
  10498. + * Smarty plugin
  10499. + * @package Smarty
  10500. + * @subpackage plugins
  10501. + */
  10502. +
  10503. +
  10504. +/**
  10505. + * Smarty spacify modifier plugin
  10506. + *
  10507. + * Type:     modifier<br>
  10508. + * Name:     spacify<br>
  10509. + * Purpose:  add spaces between characters in a string
  10510. + * @link http://smarty.php.net/manual/en/language.modifier.spacify.php
  10511. + *          spacify (Smarty online manual)
  10512. + * @author   Monte Ohrt <monte at ohrt dot com>
  10513. + * @param string
  10514. + * @param string
  10515. + * @return string
  10516. + */
  10517. +function smarty_modifier_spacify($string, $spacify_char = ' ')
  10518. +{
  10519. +    return implode($spacify_char,
  10520. +                   preg_split('//', $string, -1, PREG_SPLIT_NO_EMPTY));
  10521. +}
  10522. +
  10523. +/* vim: set expandtab: */
  10524. +
  10525. +?>
  10526. diff --git a/library/smarty/plugins/modifier.string_format.php b/library/smarty/plugins/modifier.string_format.php
  10527. new file mode 100644
  10528. --- /dev/null
  10529. +++ b/library/smarty/plugins/modifier.string_format.php
  10530. @@ -0,0 +1,29 @@
  10531. +<?php
  10532. +/**
  10533. + * Smarty plugin
  10534. + * @package Smarty
  10535. + * @subpackage plugins
  10536. + */
  10537. +
  10538. +
  10539. +/**
  10540. + * Smarty string_format modifier plugin
  10541. + *
  10542. + * Type:     modifier<br>
  10543. + * Name:     string_format<br>
  10544. + * Purpose:  format strings via sprintf
  10545. + * @link http://smarty.php.net/manual/en/language.modifier.string.format.php
  10546. + *          string_format (Smarty online manual)
  10547. + * @author   Monte Ohrt <monte at ohrt dot com>
  10548. + * @param string
  10549. + * @param string
  10550. + * @return string
  10551. + */
  10552. +function smarty_modifier_string_format($string, $format)
  10553. +{
  10554. +    return sprintf($format, $string);
  10555. +}
  10556. +
  10557. +/* vim: set expandtab: */
  10558. +
  10559. +?>
  10560. diff --git a/library/smarty/plugins/modifier.strip.php b/library/smarty/plugins/modifier.strip.php
  10561. new file mode 100644
  10562. --- /dev/null
  10563. +++ b/library/smarty/plugins/modifier.strip.php
  10564. @@ -0,0 +1,33 @@
  10565. +<?php
  10566. +/**
  10567. + * Smarty plugin
  10568. + * @package Smarty
  10569. + * @subpackage plugins
  10570. + */
  10571. +
  10572. +
  10573. +/**
  10574. + * Smarty strip modifier plugin
  10575. + *
  10576. + * Type:     modifier<br>
  10577. + * Name:     strip<br>
  10578. + * Purpose:  Replace all repeated spaces, newlines, tabs
  10579. + *           with a single space or supplied replacement string.<br>
  10580. + * Example:  {$var|strip} {$var|strip:"&nbsp;"}
  10581. + * Date:     September 25th, 2002
  10582. + * @link http://smarty.php.net/manual/en/language.modifier.strip.php
  10583. + *          strip (Smarty online manual)
  10584. + * @author   Monte Ohrt <monte at ohrt dot com>
  10585. + * @version  1.0
  10586. + * @param string
  10587. + * @param string
  10588. + * @return string
  10589. + */
  10590. +function smarty_modifier_strip($text, $replace = ' ')
  10591. +{
  10592. +    return preg_replace('!\s+!', $replace, $text);
  10593. +}
  10594. +
  10595. +/* vim: set expandtab: */
  10596. +
  10597. +?>
  10598. diff --git a/library/smarty/plugins/modifier.strip_tags.php b/library/smarty/plugins/modifier.strip_tags.php
  10599. new file mode 100644
  10600. --- /dev/null
  10601. +++ b/library/smarty/plugins/modifier.strip_tags.php
  10602. @@ -0,0 +1,32 @@
  10603. +<?php
  10604. +/**
  10605. + * Smarty plugin
  10606. + * @package Smarty
  10607. + * @subpackage plugins
  10608. + */
  10609. +
  10610. +
  10611. +/**
  10612. + * Smarty strip_tags modifier plugin
  10613. + *
  10614. + * Type:     modifier<br>
  10615. + * Name:     strip_tags<br>
  10616. + * Purpose:  strip html tags from text
  10617. + * @link http://smarty.php.net/manual/en/language.modifier.strip.tags.php
  10618. + *          strip_tags (Smarty online manual)
  10619. + * @author   Monte Ohrt <monte at ohrt dot com>
  10620. + * @param string
  10621. + * @param boolean
  10622. + * @return string
  10623. + */
  10624. +function smarty_modifier_strip_tags($string, $replace_with_space = true)
  10625. +{
  10626. +    if ($replace_with_space)
  10627. +        return preg_replace('!<[^>]*?>!', ' ', $string);
  10628. +    else
  10629. +        return strip_tags($string);
  10630. +}
  10631. +
  10632. +/* vim: set expandtab: */
  10633. +
  10634. +?>
  10635. diff --git a/library/smarty/plugins/modifier.truncate.php b/library/smarty/plugins/modifier.truncate.php
  10636. new file mode 100644
  10637. --- /dev/null
  10638. +++ b/library/smarty/plugins/modifier.truncate.php
  10639. @@ -0,0 +1,50 @@
  10640. +<?php
  10641. +/**
  10642. + * Smarty plugin
  10643. + * @package Smarty
  10644. + * @subpackage plugins
  10645. + */
  10646. +
  10647. +
  10648. +/**
  10649. + * Smarty truncate modifier plugin
  10650. + *
  10651. + * Type:     modifier<br>
  10652. + * Name:     truncate<br>
  10653. + * Purpose:  Truncate a string to a certain length if necessary,
  10654. + *           optionally splitting in the middle of a word, and
  10655. + *           appending the $etc string or inserting $etc into the middle.
  10656. + * @link http://smarty.php.net/manual/en/language.modifier.truncate.php
  10657. + *          truncate (Smarty online manual)
  10658. + * @author   Monte Ohrt <monte at ohrt dot com>
  10659. + * @param string
  10660. + * @param integer
  10661. + * @param string
  10662. + * @param boolean
  10663. + * @param boolean
  10664. + * @return string
  10665. + */
  10666. +function smarty_modifier_truncate($string, $length = 80, $etc = '...',
  10667. +                                  $break_words = false, $middle = false)
  10668. +{
  10669. +    if ($length == 0)
  10670. +        return '';
  10671. +
  10672. +    if (strlen($string) > $length) {
  10673. +        $length -= min($length, strlen($etc));
  10674. +        if (!$break_words && !$middle) {
  10675. +            $string = preg_replace('/\s+?(\S+)?$/', '', substr($string, 0, $length+1));
  10676. +        }
  10677. +        if(!$middle) {
  10678. +            return substr($string, 0, $length) . $etc;
  10679. +        } else {
  10680. +            return substr($string, 0, $length/2) . $etc . substr($string, -$length/2);
  10681. +        }
  10682. +    } else {
  10683. +        return $string;
  10684. +    }
  10685. +}
  10686. +
  10687. +/* vim: set expandtab: */
  10688. +
  10689. +?>
  10690. diff --git a/library/smarty/plugins/modifier.upper.php b/library/smarty/plugins/modifier.upper.php
  10691. new file mode 100644
  10692. --- /dev/null
  10693. +++ b/library/smarty/plugins/modifier.upper.php
  10694. @@ -0,0 +1,26 @@
  10695. +<?php
  10696. +/**
  10697. + * Smarty plugin
  10698. + * @package Smarty
  10699. + * @subpackage plugins
  10700. + */
  10701. +
  10702. +
  10703. +/**
  10704. + * Smarty upper modifier plugin
  10705. + *
  10706. + * Type:     modifier<br>
  10707. + * Name:     upper<br>
  10708. + * Purpose:  convert string to uppercase
  10709. + * @link http://smarty.php.net/manual/en/language.modifier.upper.php
  10710. + *          upper (Smarty online manual)
  10711. + * @author   Monte Ohrt <monte at ohrt dot com>
  10712. + * @param string
  10713. + * @return string
  10714. + */
  10715. +function smarty_modifier_upper($string)
  10716. +{
  10717. +    return strtoupper($string);
  10718. +}
  10719. +
  10720. +?>
  10721. diff --git a/library/smarty/plugins/modifier.wordwrap.php b/library/smarty/plugins/modifier.wordwrap.php
  10722. new file mode 100644
  10723. --- /dev/null
  10724. +++ b/library/smarty/plugins/modifier.wordwrap.php
  10725. @@ -0,0 +1,29 @@
  10726. +<?php
  10727. +/**
  10728. + * Smarty plugin
  10729. + * @package Smarty
  10730. + * @subpackage plugins
  10731. + */
  10732. +
  10733. +
  10734. +/**
  10735. + * Smarty wordwrap modifier plugin
  10736. + *
  10737. + * Type:     modifier<br>
  10738. + * Name:     wordwrap<br>
  10739. + * Purpose:  wrap a string of text at a given length
  10740. + * @link http://smarty.php.net/manual/en/language.modifier.wordwrap.php
  10741. + *          wordwrap (Smarty online manual)
  10742. + * @author   Monte Ohrt <monte at ohrt dot com>
  10743. + * @param string
  10744. + * @param integer
  10745. + * @param string
  10746. + * @param boolean
  10747. + * @return string
  10748. + */
  10749. +function smarty_modifier_wordwrap($string,$length=80,$break="\n",$cut=false)
  10750. +{
  10751. +    return wordwrap($string,$length,$break,$cut);
  10752. +}
  10753. +
  10754. +?>
  10755. diff --git a/library/smarty/plugins/outputfilter.trimwhitespace.php b/library/smarty/plugins/outputfilter.trimwhitespace.php
  10756. new file mode 100644
  10757. --- /dev/null
  10758. +++ b/library/smarty/plugins/outputfilter.trimwhitespace.php
  10759. @@ -0,0 +1,75 @@
  10760. +<?php
  10761. +/**
  10762. + * Smarty plugin
  10763. + * @package Smarty
  10764. + * @subpackage plugins
  10765. + */
  10766. +
  10767. +/**
  10768. + * Smarty trimwhitespace outputfilter plugin
  10769. + *
  10770. + * File:     outputfilter.trimwhitespace.php<br>
  10771. + * Type:     outputfilter<br>
  10772. + * Name:     trimwhitespace<br>
  10773. + * Date:     Jan 25, 2003<br>
  10774. + * Purpose:  trim leading white space and blank lines from
  10775. + *           template source after it gets interpreted, cleaning
  10776. + *           up code and saving bandwidth. Does not affect
  10777. + *           <<PRE>></PRE> and <SCRIPT></SCRIPT> blocks.<br>
  10778. + * Install:  Drop into the plugin directory, call
  10779. + *           <code>$smarty->load_filter('output','trimwhitespace');</code>
  10780. + *           from application.
  10781. + * @author   Monte Ohrt <monte at ohrt dot com>
  10782. + * @author Contributions from Lars Noschinski <[email protected]>
  10783. + * @version  1.3
  10784. + * @param string
  10785. + * @param Smarty
  10786. + */
  10787. +function smarty_outputfilter_trimwhitespace($source, &$smarty)
  10788. +{
  10789. +    // Pull out the script blocks
  10790. +    preg_match_all("!<script[^>]*?>.*?</script>!is", $source, $match);
  10791. +    $_script_blocks = $match[0];
  10792. +    $source = preg_replace("!<script[^>]*?>.*?</script>!is",
  10793. +                           '@@@SMARTY:TRIM:SCRIPT@@@', $source);
  10794. +
  10795. +    // Pull out the pre blocks
  10796. +    preg_match_all("!<pre[^>]*?>.*?</pre>!is", $source, $match);
  10797. +    $_pre_blocks = $match[0];
  10798. +    $source = preg_replace("!<pre[^>]*?>.*?</pre>!is",
  10799. +                           '@@@SMARTY:TRIM:PRE@@@', $source);
  10800. +    
  10801. +    // Pull out the textarea blocks
  10802. +    preg_match_all("!<textarea[^>]*?>.*?</textarea>!is", $source, $match);
  10803. +    $_textarea_blocks = $match[0];
  10804. +    $source = preg_replace("!<textarea[^>]*?>.*?</textarea>!is",
  10805. +                           '@@@SMARTY:TRIM:TEXTAREA@@@', $source);
  10806. +
  10807. +    // remove all leading spaces, tabs and carriage returns NOT
  10808. +    // preceeded by a php close tag.
  10809. +    $source = trim(preg_replace('/((?<!\?>)\n)[\s]+/m', '', $source));
  10810. +
  10811. +    // replace textarea blocks
  10812. +    smarty_outputfilter_trimwhitespace_replace("@@@SMARTY:TRIM:TEXTAREA@@@",$_textarea_blocks, $source);
  10813. +
  10814. +    // replace pre blocks
  10815. +    smarty_outputfilter_trimwhitespace_replace("@@@SMARTY:TRIM:PRE@@@",$_pre_blocks, $source);
  10816. +
  10817. +    // replace script blocks
  10818. +    smarty_outputfilter_trimwhitespace_replace("@@@SMARTY:TRIM:SCRIPT@@@",$_script_blocks, $source);
  10819. +
  10820. +    return $source;
  10821. +}
  10822. +
  10823. +function smarty_outputfilter_trimwhitespace_replace($search_str, $replace, &$subject) {
  10824. +    $_len = strlen($search_str);
  10825. +    $_pos = 0;
  10826. +    for ($_i=0, $_count=count($replace); $_i<$_count; $_i++)
  10827. +        if (($_pos=strpos($subject, $search_str, $_pos))!==false)
  10828. +            $subject = substr_replace($subject, $replace[$_i], $_pos, $_len);
  10829. +        else
  10830. +            break;
  10831. +
  10832. +}
  10833. +
  10834. +?>
  10835. diff --git a/library/smarty/plugins/shared.escape_special_chars.php b/library/smarty/plugins/shared.escape_special_chars.php
  10836. new file mode 100644
  10837. --- /dev/null
  10838. +++ b/library/smarty/plugins/shared.escape_special_chars.php
  10839. @@ -0,0 +1,31 @@
  10840. +<?php
  10841. +/**
  10842. + * Smarty shared plugin
  10843. + * @package Smarty
  10844. + * @subpackage plugins
  10845. + */
  10846. +
  10847. +
  10848. +/**
  10849. + * escape_special_chars common function
  10850. + *
  10851. + * Function: smarty_function_escape_special_chars<br>
  10852. + * Purpose:  used by other smarty functions to escape
  10853. + *           special chars except for already escaped ones
  10854. + * @author   Monte Ohrt <monte at ohrt dot com>
  10855. + * @param string
  10856. + * @return string
  10857. + */
  10858. +function smarty_function_escape_special_chars($string)
  10859. +{
  10860. +    if(!is_array($string)) {
  10861. +        $string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\%%%SMARTY_END%%%', $string);
  10862. +        $string = htmlspecialchars($string);
  10863. +        $string = str_replace(array('%%%SMARTY_START%%%','%%%SMARTY_END%%%'), array('&',';'), $string);
  10864. +    }
  10865. +    return $string;
  10866. +}
  10867. +
  10868. +/* vim: set expandtab: */
  10869. +
  10870. +?>
  10871. diff --git a/library/smarty/plugins/shared.make_timestamp.php b/library/smarty/plugins/shared.make_timestamp.php
  10872. new file mode 100644
  10873. --- /dev/null
  10874. +++ b/library/smarty/plugins/shared.make_timestamp.php
  10875. @@ -0,0 +1,46 @@
  10876. +<?php
  10877. +/**
  10878. + * Smarty shared plugin
  10879. + * @package Smarty
  10880. + * @subpackage plugins
  10881. + */
  10882. +
  10883. +
  10884. +/**
  10885. + * Function: smarty_make_timestamp<br>
  10886. + * Purpose:  used by other smarty functions to make a timestamp
  10887. + *           from a string.
  10888. + * @author   Monte Ohrt <monte at ohrt dot com>
  10889. + * @param string
  10890. + * @return string
  10891. + */
  10892. +function smarty_make_timestamp($string)
  10893. +{
  10894. +    if(empty($string)) {
  10895. +        // use "now":
  10896. +        $time = time();
  10897. +
  10898. +    } elseif (preg_match('/^\d{14}$/', $string)) {
  10899. +        // it is mysql timestamp format of YYYYMMDDHHMMSS?            
  10900. +        $time = mktime(substr($string, 8, 2),substr($string, 10, 2),substr($string, 12, 2),
  10901. +                       substr($string, 4, 2),substr($string, 6, 2),substr($string, 0, 4));
  10902. +        
  10903. +    } elseif (is_numeric($string)) {
  10904. +        // it is a numeric string, we handle it as timestamp
  10905. +        $time = (int)$string;
  10906. +        
  10907. +    } else {
  10908. +        // strtotime should handle it
  10909. +        $time = strtotime($string);
  10910. +        if ($time == -1 || $time === false) {
  10911. +            // strtotime() was not able to parse $string, use "now":
  10912. +            $time = time();
  10913. +        }
  10914. +    }
  10915. +    return $time;
  10916. +
  10917. +}
  10918. +
  10919. +/* vim: set expandtab: */
  10920. +
  10921. +?>
  10922. diff --git a/templates/default/html_css.tpl b/templates/default/html_css.tpl
  10923. new file mode 100644
  10924. --- /dev/null
  10925. +++ b/templates/default/html_css.tpl
  10926. @@ -0,0 +1,8 @@
  10927. +
  10928. +   <link rel="stylesheet" type="text/css" href="{$path}css/{config_get option='css_include_file'}" />
  10929. +   <link rel="stylesheet" type="text/css" href="{$path}css/jquery-ui.css" />
  10930. +   <link rel="stylesheet" type="text/css" href="{$path}css/common_config.php" />
  10931. +   {* Add right-to-left css if needed *}
  10932. +   {if $directionality == 'rtl'}<link rel="stylesheet" type="text/css" href="{$path}css/{config_get option='css_rtl_include_file'|escape:'html'}" />{/if}
  10933. +   {foreach from=$g_stylesheets_included item=t_stylesheet_path }<link rel="stylesheet" type="text/css" href="{$path}css/{$t_stylesheet_path|escape:'html'}" />{/foreach}
  10934. +
  10935. diff --git a/templates/default/html_footer.tpl b/templates/default/html_footer.tpl
  10936. new file mode 100644
  10937. --- /dev/null
  10938. +++ b/templates/default/html_footer.tpl
  10939. @@ -0,0 +1,27 @@
  10940. +   <div id="footer">
  10941. +       <hr />
  10942. +       <div id="powered-by-mantisbt-logo">
  10943. +           <a href="http://www.mantisbt.org" title="Mantis Bug Tracker: a free and open source web based bug tracking system."><img src="{$short_path}images/mantis_logo_button.gif" width="88" height="35" alt="Powered by Mantis Bug Tracker: a free and open source web based bug tracking system." /></a>
  10944. +       </div>
  10945. +
  10946. +       {* Show optional user-specificed custom copyright statement *}
  10947. +       {if $copyright_statement}
  10948. +       <address id="user-copyright">$t_copyright_statement</address>
  10949. +       {/if}
  10950. +
  10951. +       {* Show MantisBT version and copyright statement *}
  10952. +       <address id="mantisbt-copyright">Powered by <a href="http://www.mantisbt.org" title="Mantis Bug Tracker: a free and open source web based bug tracking system.">Mantis Bug Tracker</a> (MantisBT){$t_version_suffix}. Copyright &copy;{$t_copyright_years} MantisBT contributors. Licensed under the terms of the <a href="http://www.gnu.org/licenses/old-licenses/gpl-2.0.html" title="GNU General Public License (GPL) version 2">GNU General Public License (GPL) version 2</a> or a later version.</address>
  10953. +
  10954. +       {* Show contact information *}
  10955. +       <address id="webmaster-contact-information">{lang_get string='webmaster_contact_information'}{config_get option='webmaster_email'}</address>
  10956. +
  10957. +       { if $horizontal }<hr />{/if}
  10958. +
  10959. +       {if $t_page_execution_time}<p id="page-execution-time">$t_page_execution_time</p>{/if}
  10960. +       {if $t_page_memory_usage}<p id="page-memory-usage">$t_page_memory_usage</p>{/if}
  10961. +       {if $t_total_queries_executed}<p id="total-queries-count">$t_total_queries_executed</p>{/if}
  10962. +       {if $t_unique_queries_executed}<p id="unique-queries-count">$t_unique_queries_executed</p>{/if}
  10963. +       {if $t_total_query_time}<p id="total-query-execution-time">$t_total_query_time</p>{/if}
  10964. +
  10965. +       {$log_events}
  10966. +   </div>
  10967. diff --git a/templates/default/html_head_javascript.tpl b/templates/default/html_head_javascript.tpl
  10968. new file mode 100644
  10969. --- /dev/null
  10970. +++ b/templates/default/html_head_javascript.tpl
  10971. @@ -0,0 +1,10 @@
  10972. +
  10973. +   <script type="text/javascript" src="{$short_path}/javascript_config.php"></script>
  10974. +   <script type="text/javascript" src="{$short_path}/javascript_translations.php"></script>
  10975. +   <script type="text/javascript" src="{$short_path}/javascript/jquery.js"></script>
  10976. +   <script type="text/javascript" src="{$short_path}/javascript/jquery-ui.js"></script>
  10977. +   <script type="text/javascript" src="{$short_path}/javascript/common.js"></script>
  10978. +   {foreach from=$g_scripts_included item=p_filename}
  10979. +   <script type="text/javascript" src="{$short_path}/javascript/{$p_filename|escape:'html'}"></script>
  10980. +   {/foreach}
  10981. +
  10982. diff --git a/templates/default/html_login_info.tpl b/templates/default/html_login_info.tpl
  10983. new file mode 100644
  10984. --- /dev/null
  10985. +++ b/templates/default/html_login_info.tpl
  10986. @@ -0,0 +1,43 @@
  10987. +
  10988. +   <div id="login-info">
  10989. +       {if current_user_is_anonymous() }
  10990. +       <span id="logged-anon-label">{ lang_get string='anonymous'}</span>
  10991. +       <span id="login-link"><a href="{$path}login_page.php?return={$t_return_page}">{lang_get string='login_link'}</a></span>
  10992. +       {if $allow_signup}
  10993. +       <span id="signup-link"><a href="{$path}signup_page.php">{lang_get string='signup_link'}</a></span>
  10994. +       {/if}
  10995. +       {else}
  10996. +       <span id="logged-in-label">{lang_get string='logged_in_as'}</span>
  10997. +       <span id="logged-in-user">{$t_username}</span>
  10998. +       <span id="logged-in">
  10999. +           {if $t_realname}<span id="logged-in-realname">{$t_realname}</span>{/if}
  11000. +           <span id="logged-in-accesslevel" class="{$t_access_level}">{$t_access_level}</span>
  11001. +       </span>
  11002. +       {/if}
  11003. +   </div>
  11004. +
  11005. +   {if $rss_enabled}
  11006. +   <div id="rss-feed">
  11007. +       {* Link to RSS issues feed for the selected project, including authentication details. *}
  11008. +       <a href="{$rss_get_issues_feed_url|escape:'html'}">
  11009. +           <img src="{$short_path}images/rss.png" alt="{lang_get string='rss'}" title="{lang_get string='rss'}" />
  11010. +       </a>
  11011. +   </div>
  11012. +   {/if}
  11013. +
  11014. +   {if $t_show_project_selector }
  11015. +   <form method="post" id="form-set-project" action="{$short_path}set_project.php">
  11016. +       <fieldset id="project-selector">
  11017. +           {* CSRF protection not required here - form does not result in modifications *}
  11018. +           <label for="form-set-project-id">{lang_get string='email_project'}</label>
  11019. +           <select id="form-set-project-id" name="project_id">
  11020. +               {$project_option_list}
  11021. +           </select>
  11022. +           <input type="submit" class="button" value="{lang_get string='switch'}" />
  11023. +       </fieldset>
  11024. +   </form>
  11025. +   <div id="current-time">{$smarty.now|date_format:"%Y-%m-%d %H:%M:%S"}</div>
  11026. +   {else}
  11027. +   <div id="current-time-centered">{$smarty.now|date_format:"%Y-%m-%d %H:%M:%S"}</div>
  11028. +   {/if}
  11029. +
  11030. diff --git a/templates/default/html_menu.tpl b/templates/default/html_menu.tpl
  11031. new file mode 100644
  11032. --- /dev/null
  11033. +++ b/templates/default/html_menu.tpl
  11034. @@ -0,0 +1,46 @@
  11035. +   {if auth_is_user_authenticated()}
  11036. +   <form method="post" action="{$short_path}jump_to_bug.php" class="bug-jump-form">
  11037. +       <fieldset class="bug-jump">
  11038. +           {* CSRF protection not required here - form does not result in modifications *}
  11039. +           <input type="hidden" name="bug_label" value="{lang_get string='issue_id'}" />
  11040. +           <input type="text" name="bug_id" size="10" class="small" />
  11041. +           <input type="submit" class="button-small" value="{lang_get string='jump'}" />
  11042. +       </fieldset>
  11043. +   </form>
  11044. +
  11045. +   <div class="main-menu">
  11046. +       <div>
  11047. +           <ul class="menu">
  11048. +               {* Main Page *}
  11049. +               <li><a href="{$short_path}main_page.php">{lang_get string='main_link'}</a></li>
  11050. +
  11051. +               {foreach from=$t_menu_plugin_pre_options item=t_menu_option}
  11052. +               <li>{$t_menu_option}</li>
  11053. +               {/foreach}
  11054. +
  11055. +               {foreach from=$t_menu_options item=t_menu_option}
  11056. +               <li>{$t_menu_option}</li>
  11057. +               {/foreach}
  11058. +
  11059. +               {foreach from=$menu_plugin_post_options item=t_menu_option}
  11060. +               <li>{$t_menu_option}</li>
  11061. +               {/foreach}
  11062. +
  11063. +               {foreach from=$t_menu_extra_options item=t_menu_option}
  11064. +               <li>{$t_menu_option}</li>
  11065. +               {/foreach}
  11066. +
  11067. +               {* Time Tracking / Billing *}
  11068. +               {if $t_time_tracking_enabled}
  11069. +               <li><a href="{$short_path}billing_page.php">{lang_get string='time_tracking_billing_link'}</a></li>
  11070. +               {/if}
  11071. +
  11072. +               {* Logout (no if anonymously logged in) *}
  11073. +               {if !current_user_is_anonymous()}
  11074. +               <li><a id="logout-link" href="{$short_path}logout_page.php">{lang_get string='logout_link'}</a></li>
  11075. +               {/if}
  11076. +           </ul>
  11077. +       </div>
  11078. +   </div>
  11079. +   {/if}
  11080. +
  11081. diff --git a/templates/default/html_top_banner.tpl b/templates/default/html_top_banner.tpl
  11082. new file mode 100644
  11083. --- /dev/null
  11084. +++ b/templates/default/html_top_banner.tpl
  11085. @@ -0,0 +1,15 @@
  11086. +
  11087. +   {if $t_page }
  11088. +       {include_php file=$t_page};
  11089. +   {elseif $t_show_logo }
  11090. +   <div id="banner">
  11091. +       {if $t_show_url }
  11092. +       <a id="logo-link" href="{config_get option='logo_url'|escape:'html'}">
  11093. +       {/if}
  11094. +       <img id="logo-image" alt="Mantis Bug Tracker" src="{$path}{config_get option='logo_image'|escape:'html'}" />
  11095. +       {if $t_show_url}
  11096. +       </a>
  11097. +       {/if}
  11098. +   </div>
  11099. +   {/if}
  11100. +
  11101. diff --git a/templates/default/main.tpl b/templates/default/main.tpl
  11102. new file mode 100644
  11103. --- /dev/null
  11104. +++ b/templates/default/main.tpl
  11105. @@ -0,0 +1,49 @@
  11106. +<?xml version="1.0" encoding="utf-8"?>
  11107. +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  11108. +<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en" >
  11109. +
  11110. +<head>
  11111. +   {include file='html_css.tpl'}
  11112. +
  11113. +   <meta http-equiv="Content-type" content="application/xhtml+xml; charset=UTF-8" />
  11114. +   {include_php file=$meta_include_file}
  11115. +
  11116. +   {if $g_robots_meta}<meta name="robots" content="{$g_robots_meta}" />{/if}
  11117. +
  11118. +   {if $g_rss_feed_url}<link rel="alternate" type="application/rss+xml" title="RSS" href="{$g_rss_feed_url}" />{/if}
  11119. +
  11120. +   {if $t_favicon_image}<link rel="shortcut icon" href="{$short_path}{$t_favicon_image}" type="image/x-icon" />{/if}
  11121. +
  11122. +   <link rel="search" type="application/opensearchdescription+xml" title="MantisBT: Text Search" href="{$path}browser_search_plugin.php?type=text" />
  11123. +   <link rel="search" type="application/opensearchdescription+xml" title="MantisBT: Issue Id" href="{$path}browser_search_plugin.php?type=id" />
  11124. +
  11125. +   <title>{$t_title}</title>
  11126. +
  11127. +   {include file='html_head_javascript.tpl'}
  11128. +
  11129. +   {if $t_url}
  11130. +   <meta http-equiv="Refresh" content="{$p_time};URL={$t_url}" />
  11131. +   {/if}
  11132. +
  11133. +</head>
  11134. +
  11135. +<body>
  11136. +
  11137. +  <div id="mantis">
  11138. +
  11139. +   {include file='html_top_banner.tpl'}
  11140. +   {* include file='html_login_info.tpl' *}
  11141. +   {include file='html_menu.tpl'}
  11142. +
  11143. +   <div id="content">
  11144. +       {$content}
  11145. +   </div>
  11146. +
  11147. +   {include file='html_footer.tpl'}
  11148. +
  11149. +  </div>
  11150. +
  11151. +</body>
  11152. +
  11153. +</html>
  11154. +
Add Comment
Please, Sign In to add comment