Guest User

Mantis templates patch

a guest
Dec 29th, 2011
195
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 <cesar@caih.org>
  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. + * smarty-discussion-subscribe@googlegroups.com
  780. + *
  781. + * @link http://www.smarty.net/
  782. + * @version 2.6.26
  783. + * @copyright Copyright: 2001-2005 New Digital Group, Inc.
  784. + * @author Andrei Zmievski <andrei@php.net>
  785. + * @access public
  786. + * @package Smarty
  787. + */
  788. +
  789. +/* $Id: Config_File.class.php 3149 2009-05-23 20:59:25Z monte.ohrt $ */
  790. +
  791. +/**
  792. + * Config file reading class
  793. + * @package Smarty
  794. + */
  795. +class Config_File {
  796. +    /**#@+
  797. +     * Options
  798. +     * @var boolean
  799. +     */
  800. +    /**
  801. +     * Controls whether variables with the same name overwrite each other.
  802. +     */
  803. +    var $overwrite        =    true;
  804. +
  805. +    /**
  806. +     * Controls whether config values of on/true/yes and off/false/no get
  807. +     * converted to boolean values automatically.
  808. +     */
  809. +    var $booleanize        =    true;
  810. +
  811. +    /**
  812. +     * Controls whether hidden config sections/vars are read from the file.
  813. +     */
  814. +    var $read_hidden     =    true;
  815. +
  816. +    /**
  817. +     * Controls whether or not to fix mac or dos formatted newlines.
  818. +     * If set to true, \r or \r\n will be changed to \n.
  819. +     */
  820. +    var $fix_newlines =    true;
  821. +    /**#@-*/
  822. +
  823. +    /** @access private */
  824. +    var $_config_path    = "";
  825. +    var $_config_data    = array();
  826. +    /**#@-*/
  827. +
  828. +    /**
  829. +     * Constructs a new config file class.
  830. +     *
  831. +     * @param string $config_path (optional) path to the config files
  832. +     */
  833. +    function Config_File($config_path = NULL)
  834. +    {
  835. +        if (isset($config_path))
  836. +            $this->set_path($config_path);
  837. +    }
  838. +
  839. +
  840. +    /**
  841. +     * Set the path where configuration files can be found.
  842. +     *
  843. +     * @param string $config_path path to the config files
  844. +     */
  845. +    function set_path($config_path)
  846. +    {
  847. +        if (!empty($config_path)) {
  848. +            if (!is_string($config_path) || !file_exists($config_path) || !is_dir($config_path)) {
  849. +                $this->_trigger_error_msg("Bad config file path '$config_path'");
  850. +                return;
  851. +            }
  852. +            if(substr($config_path, -1) != DIRECTORY_SEPARATOR) {
  853. +                $config_path .= DIRECTORY_SEPARATOR;
  854. +            }
  855. +
  856. +            $this->_config_path = $config_path;
  857. +        }
  858. +    }
  859. +
  860. +
  861. +    /**
  862. +     * Retrieves config info based on the file, section, and variable name.
  863. +     *
  864. +     * @param string $file_name config file to get info for
  865. +     * @param string $section_name (optional) section to get info for
  866. +     * @param string $var_name (optional) variable to get info for
  867. +     * @return string|array a value or array of values
  868. +     */
  869. +    function get($file_name, $section_name = NULL, $var_name = NULL)
  870. +    {
  871. +        if (empty($file_name)) {
  872. +            $this->_trigger_error_msg('Empty config file name');
  873. +            return;
  874. +        } else {
  875. +            $file_name = $this->_config_path . $file_name;
  876. +            if (!isset($this->_config_data[$file_name]))
  877. +                $this->load_file($file_name, false);
  878. +        }
  879. +
  880. +        if (!empty($var_name)) {
  881. +            if (empty($section_name)) {
  882. +                return $this->_config_data[$file_name]["vars"][$var_name];
  883. +            } else {
  884. +                if(isset($this->_config_data[$file_name]["sections"][$section_name]["vars"][$var_name]))
  885. +                    return $this->_config_data[$file_name]["sections"][$section_name]["vars"][$var_name];
  886. +                else
  887. +                    return array();
  888. +            }
  889. +        } else {
  890. +            if (empty($section_name)) {
  891. +                return (array)$this->_config_data[$file_name]["vars"];
  892. +            } else {
  893. +                if(isset($this->_config_data[$file_name]["sections"][$section_name]["vars"]))
  894. +                    return (array)$this->_config_data[$file_name]["sections"][$section_name]["vars"];
  895. +                else
  896. +                    return array();
  897. +            }
  898. +        }
  899. +    }
  900. +
  901. +
  902. +    /**
  903. +     * Retrieves config info based on the key.
  904. +     *
  905. +     * @param $file_name string config key (filename/section/var)
  906. +     * @return string|array same as get()
  907. +     * @uses get() retrieves information from config file and returns it
  908. +     */
  909. +    function &get_key($config_key)
  910. +    {
  911. +        list($file_name, $section_name, $var_name) = explode('/', $config_key, 3);
  912. +        $result = &$this->get($file_name, $section_name, $var_name);
  913. +        return $result;
  914. +    }
  915. +
  916. +    /**
  917. +     * Get all loaded config file names.
  918. +     *
  919. +     * @return array an array of loaded config file names
  920. +     */
  921. +    function get_file_names()
  922. +    {
  923. +        return array_keys($this->_config_data);
  924. +    }
  925. +
  926. +
  927. +    /**
  928. +     * Get all section names from a loaded file.
  929. +     *
  930. +     * @param string $file_name config file to get section names from
  931. +     * @return array an array of section names from the specified file
  932. +     */
  933. +    function get_section_names($file_name)
  934. +    {
  935. +        $file_name = $this->_config_path . $file_name;
  936. +        if (!isset($this->_config_data[$file_name])) {
  937. +            $this->_trigger_error_msg("Unknown config file '$file_name'");
  938. +            return;
  939. +        }
  940. +
  941. +        return array_keys($this->_config_data[$file_name]["sections"]);
  942. +    }
  943. +
  944. +
  945. +    /**
  946. +     * Get all global or section variable names.
  947. +     *
  948. +     * @param string $file_name config file to get info for
  949. +     * @param string $section_name (optional) section to get info for
  950. +     * @return array an array of variables names from the specified file/section
  951. +     */
  952. +    function get_var_names($file_name, $section = NULL)
  953. +    {
  954. +        if (empty($file_name)) {
  955. +            $this->_trigger_error_msg('Empty config file name');
  956. +            return;
  957. +        } else if (!isset($this->_config_data[$file_name])) {
  958. +            $this->_trigger_error_msg("Unknown config file '$file_name'");
  959. +            return;
  960. +        }
  961. +
  962. +        if (empty($section))
  963. +            return array_keys($this->_config_data[$file_name]["vars"]);
  964. +        else
  965. +            return array_keys($this->_config_data[$file_name]["sections"][$section]["vars"]);
  966. +    }
  967. +
  968. +
  969. +    /**
  970. +     * Clear loaded config data for a certain file or all files.
  971. +     *
  972. +     * @param string $file_name file to clear config data for
  973. +     */
  974. +    function clear($file_name = NULL)
  975. +    {
  976. +        if ($file_name === NULL)
  977. +            $this->_config_data = array();
  978. +        else if (isset($this->_config_data[$file_name]))
  979. +            $this->_config_data[$file_name] = array();
  980. +    }
  981. +
  982. +
  983. +    /**
  984. +     * Load a configuration file manually.
  985. +     *
  986. +     * @param string $file_name file name to load
  987. +     * @param boolean $prepend_path whether current config path should be
  988. +     *                              prepended to the filename
  989. +     */
  990. +    function load_file($file_name, $prepend_path = true)
  991. +    {
  992. +        if ($prepend_path && $this->_config_path != "")
  993. +            $config_file = $this->_config_path . $file_name;
  994. +        else
  995. +            $config_file = $file_name;
  996. +
  997. +        ini_set('track_errors', true);
  998. +        $fp = @fopen($config_file, "r");
  999. +        if (!is_resource($fp)) {
  1000. +            $this->_trigger_error_msg("Could not open config file '$config_file'");
  1001. +            return false;
  1002. +        }
  1003. +
  1004. +        $contents = ($size = filesize($config_file)) ? fread($fp, $size) : '';
  1005. +        fclose($fp);
  1006. +
  1007. +        $this->_config_data[$config_file] = $this->parse_contents($contents);
  1008. +        return true;
  1009. +    }
  1010. +
  1011. +    /**
  1012. +     * Store the contents of a file manually.
  1013. +     *
  1014. +     * @param string $config_file file name of the related contents
  1015. +     * @param string $contents the file-contents to parse
  1016. +     */
  1017. +    function set_file_contents($config_file, $contents)
  1018. +    {
  1019. +        $this->_config_data[$config_file] = $this->parse_contents($contents);
  1020. +        return true;
  1021. +    }
  1022. +
  1023. +    /**
  1024. +     * parse the source of a configuration file manually.
  1025. +     *
  1026. +     * @param string $contents the file-contents to parse
  1027. +     */
  1028. +    function parse_contents($contents)
  1029. +    {
  1030. +        if($this->fix_newlines) {
  1031. +            // fix mac/dos formatted newlines
  1032. +            $contents = preg_replace('!\r\n?!', "\n", $contents);
  1033. +        }
  1034. +
  1035. +        $config_data = array();
  1036. +        $config_data['sections'] = array();
  1037. +        $config_data['vars'] = array();
  1038. +
  1039. +        /* reference to fill with data */
  1040. +        $vars =& $config_data['vars'];
  1041. +
  1042. +        /* parse file line by line */
  1043. +        preg_match_all('!^.*\r?\n?!m', $contents, $match);
  1044. +        $lines = $match[0];
  1045. +        for ($i=0, $count=count($lines); $i<$count; $i++) {
  1046. +            $line = $lines[$i];
  1047. +            if (empty($line)) continue;
  1048. +
  1049. +            if ( substr($line, 0, 1) == '[' && preg_match('!^\[(.*?)\]!', $line, $match) ) {
  1050. +                /* section found */
  1051. +                if (substr($match[1], 0, 1) == '.') {
  1052. +                    /* hidden section */
  1053. +                    if ($this->read_hidden) {
  1054. +                        $section_name = substr($match[1], 1);
  1055. +                    } else {
  1056. +                        /* break reference to $vars to ignore hidden section */
  1057. +                        unset($vars);
  1058. +                        $vars = array();
  1059. +                        continue;
  1060. +                    }
  1061. +                } else {                    
  1062. +                    $section_name = $match[1];
  1063. +                }
  1064. +                if (!isset($config_data['sections'][$section_name]))
  1065. +                    $config_data['sections'][$section_name] = array('vars' => array());
  1066. +                $vars =& $config_data['sections'][$section_name]['vars'];
  1067. +                continue;
  1068. +            }
  1069. +
  1070. +            if (preg_match('/^\s*(\.?\w+)\s*=\s*(.*)/s', $line, $match)) {
  1071. +                /* variable found */
  1072. +                $var_name = rtrim($match[1]);
  1073. +                if (strpos($match[2], '"""') === 0) {
  1074. +                    /* handle multiline-value */
  1075. +                    $lines[$i] = substr($match[2], 3);
  1076. +                    $var_value = '';
  1077. +                    while ($i<$count) {
  1078. +                        if (($pos = strpos($lines[$i], '"""')) === false) {
  1079. +                            $var_value .= $lines[$i++];
  1080. +                        } else {
  1081. +                            /* end of multiline-value */
  1082. +                            $var_value .= substr($lines[$i], 0, $pos);
  1083. +                            break;
  1084. +                        }
  1085. +                    }
  1086. +                    $booleanize = false;
  1087. +
  1088. +                } else {
  1089. +                    /* handle simple value */
  1090. +                    $var_value = preg_replace('/^([\'"])(.*)$/', '\2', rtrim($match[2]));
  1091. +                    $booleanize = $this->booleanize;
  1092. +
  1093. +                }
  1094. +                $this->_set_config_var($vars, $var_name, $var_value, $booleanize);
  1095. +            }
  1096. +            /* else unparsable line / means it is a comment / means ignore it */
  1097. +        }
  1098. +        return $config_data;
  1099. +    }
  1100. +
  1101. +    /**#@+ @access private */
  1102. +    /**
  1103. +     * @param array &$container
  1104. +     * @param string $var_name
  1105. +     * @param mixed $var_value
  1106. +     * @param boolean $booleanize determines whether $var_value is converted to
  1107. +     *                            to true/false
  1108. +     */
  1109. +    function _set_config_var(&$container, $var_name, $var_value, $booleanize)
  1110. +    {
  1111. +        if (substr($var_name, 0, 1) == '.') {
  1112. +            if (!$this->read_hidden)
  1113. +                return;
  1114. +            else
  1115. +                $var_name = substr($var_name, 1);
  1116. +        }
  1117. +
  1118. +        if (!preg_match("/^[a-zA-Z_]\w*$/", $var_name)) {
  1119. +            $this->_trigger_error_msg("Bad variable name '$var_name'");
  1120. +            return;
  1121. +        }
  1122. +
  1123. +        if ($booleanize) {
  1124. +            if (preg_match("/^(on|true|yes)$/i", $var_value))
  1125. +                $var_value = true;
  1126. +            else if (preg_match("/^(off|false|no)$/i", $var_value))
  1127. +                $var_value = false;
  1128. +        }
  1129. +
  1130. +        if (!isset($container[$var_name]) || $this->overwrite)
  1131. +            $container[$var_name] = $var_value;
  1132. +        else {
  1133. +            settype($container[$var_name], 'array');
  1134. +            $container[$var_name][] = $var_value;
  1135. +        }
  1136. +    }
  1137. +
  1138. +    /**
  1139. +     * @uses trigger_error() creates a PHP warning/error
  1140. +     * @param string $error_msg
  1141. +     * @param integer $error_type one of
  1142. +     */
  1143. +    function _trigger_error_msg($error_msg, $error_type = E_USER_WARNING)
  1144. +    {
  1145. +        trigger_error("Config_File error: $error_msg", $error_type);
  1146. +    }
  1147. +    /**#@-*/
  1148. +}
  1149. +
  1150. +?>
  1151. diff --git a/library/smarty/Smarty.class.php b/library/smarty/Smarty.class.php
  1152. new file mode 100644
  1153. --- /dev/null
  1154. +++ b/library/smarty/Smarty.class.php
  1155. @@ -0,0 +1,1961 @@
  1156. +<?php
  1157. +
  1158. +/**
  1159. + * Project:     Smarty: the PHP compiling template engine
  1160. + * File:        Smarty.class.php
  1161. + *
  1162. + * This library is free software; you can redistribute it and/or
  1163. + * modify it under the terms of the GNU Lesser General Public
  1164. + * License as published by the Free Software Foundation; either
  1165. + * version 2.1 of the License, or (at your option) any later version.
  1166. + *
  1167. + * This library is distributed in the hope that it will be useful,
  1168. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  1169. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  1170. + * Lesser General Public License for more details.
  1171. + *
  1172. + * You should have received a copy of the GNU Lesser General Public
  1173. + * License along with this library; if not, write to the Free Software
  1174. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  1175. + *
  1176. + * For questions, help, comments, discussion, etc., please join the
  1177. + * Smarty mailing list. Send a blank e-mail to
  1178. + * smarty-discussion-subscribe@googlegroups.com
  1179. + *
  1180. + * @link http://www.smarty.net/
  1181. + * @copyright 2001-2005 New Digital Group, Inc.
  1182. + * @author Monte Ohrt <monte at ohrt dot com>
  1183. + * @author Andrei Zmievski <andrei@php.net>
  1184. + * @package Smarty
  1185. + * @version 2.6.26
  1186. + */
  1187. +
  1188. +/* $Id: Smarty.class.php 3163 2009-06-17 14:39:24Z monte.ohrt $ */
  1189. +
  1190. +/**
  1191. + * DIR_SEP isn't used anymore, but third party apps might
  1192. + */
  1193. +if(!defined('DIR_SEP')) {
  1194. +    define('DIR_SEP', DIRECTORY_SEPARATOR);
  1195. +}
  1196. +
  1197. +/**
  1198. + * set SMARTY_DIR to absolute path to Smarty library files.
  1199. + * if not defined, include_path will be used. Sets SMARTY_DIR only if user
  1200. + * application has not already defined it.
  1201. + */
  1202. +
  1203. +if (!defined('SMARTY_DIR')) {
  1204. +    define('SMARTY_DIR', dirname(__FILE__) . DIRECTORY_SEPARATOR);
  1205. +}
  1206. +
  1207. +if (!defined('SMARTY_CORE_DIR')) {
  1208. +    define('SMARTY_CORE_DIR', SMARTY_DIR . 'internals' . DIRECTORY_SEPARATOR);
  1209. +}
  1210. +
  1211. +define('SMARTY_PHP_PASSTHRU',   0);
  1212. +define('SMARTY_PHP_QUOTE',      1);
  1213. +define('SMARTY_PHP_REMOVE',     2);
  1214. +define('SMARTY_PHP_ALLOW',      3);
  1215. +
  1216. +/**
  1217. + * @package Smarty
  1218. + */
  1219. +class Smarty
  1220. +{
  1221. +    /**#@+
  1222. +     * Smarty Configuration Section
  1223. +     */
  1224. +
  1225. +    /**
  1226. +     * The name of the directory where templates are located.
  1227. +     *
  1228. +     * @var string
  1229. +     */
  1230. +    var $template_dir    =  'templates';
  1231. +
  1232. +    /**
  1233. +     * The directory where compiled templates are located.
  1234. +     *
  1235. +     * @var string
  1236. +     */
  1237. +    var $compile_dir     =  'templates_c';
  1238. +
  1239. +    /**
  1240. +     * The directory where config files are located.
  1241. +     *
  1242. +     * @var string
  1243. +     */
  1244. +    var $config_dir      =  'configs';
  1245. +
  1246. +    /**
  1247. +     * An array of directories searched for plugins.
  1248. +     *
  1249. +     * @var array
  1250. +     */
  1251. +    var $plugins_dir     =  array('plugins');
  1252. +
  1253. +    /**
  1254. +     * If debugging is enabled, a debug console window will display
  1255. +     * when the page loads (make sure your browser allows unrequested
  1256. +     * popup windows)
  1257. +     *
  1258. +     * @var boolean
  1259. +     */
  1260. +    var $debugging       =  false;
  1261. +
  1262. +    /**
  1263. +     * When set, smarty does uses this value as error_reporting-level.
  1264. +     *
  1265. +     * @var integer
  1266. +     */
  1267. +    var $error_reporting  =  null;
  1268. +
  1269. +    /**
  1270. +     * This is the path to the debug console template. If not set,
  1271. +     * the default one will be used.
  1272. +     *
  1273. +     * @var string
  1274. +     */
  1275. +    var $debug_tpl       =  '';
  1276. +
  1277. +    /**
  1278. +     * This determines if debugging is enable-able from the browser.
  1279. +     * <ul>
  1280. +     *  <li>NONE => no debugging control allowed</li>
  1281. +     *  <li>URL => enable debugging when SMARTY_DEBUG is found in the URL.</li>
  1282. +     * </ul>
  1283. +     * @link http://www.foo.dom/index.php?SMARTY_DEBUG
  1284. +     * @var string
  1285. +     */
  1286. +    var $debugging_ctrl  =  'NONE';
  1287. +
  1288. +    /**
  1289. +     * This tells Smarty whether to check for recompiling or not. Recompiling
  1290. +     * does not need to happen unless a template or config file is changed.
  1291. +     * Typically you enable this during development, and disable for
  1292. +     * production.
  1293. +     *
  1294. +     * @var boolean
  1295. +     */
  1296. +    var $compile_check   =  true;
  1297. +
  1298. +    /**
  1299. +     * This forces templates to compile every time. Useful for development
  1300. +     * or debugging.
  1301. +     *
  1302. +     * @var boolean
  1303. +     */
  1304. +    var $force_compile   =  false;
  1305. +
  1306. +    /**
  1307. +     * This enables template caching.
  1308. +     * <ul>
  1309. +     *  <li>0 = no caching</li>
  1310. +     *  <li>1 = use class cache_lifetime value</li>
  1311. +     *  <li>2 = use cache_lifetime in cache file</li>
  1312. +     * </ul>
  1313. +     * @var integer
  1314. +     */
  1315. +    var $caching         =  0;
  1316. +
  1317. +    /**
  1318. +     * The name of the directory for cache files.
  1319. +     *
  1320. +     * @var string
  1321. +     */
  1322. +    var $cache_dir       =  'cache';
  1323. +
  1324. +    /**
  1325. +     * This is the number of seconds cached content will persist.
  1326. +     * <ul>
  1327. +     *  <li>0 = always regenerate cache</li>
  1328. +     *  <li>-1 = never expires</li>
  1329. +     * </ul>
  1330. +     *
  1331. +     * @var integer
  1332. +     */
  1333. +    var $cache_lifetime  =  3600;
  1334. +
  1335. +    /**
  1336. +     * Only used when $caching is enabled. If true, then If-Modified-Since headers
  1337. +     * are respected with cached content, and appropriate HTTP headers are sent.
  1338. +     * This way repeated hits to a cached page do not send the entire page to the
  1339. +     * client every time.
  1340. +     *
  1341. +     * @var boolean
  1342. +     */
  1343. +    var $cache_modified_check = false;
  1344. +
  1345. +    /**
  1346. +     * This determines how Smarty handles "<?php ... ?>" tags in templates.
  1347. +     * possible values:
  1348. +     * <ul>
  1349. +     *  <li>SMARTY_PHP_PASSTHRU -> print tags as plain text</li>
  1350. +     *  <li>SMARTY_PHP_QUOTE    -> escape tags as entities</li>
  1351. +     *  <li>SMARTY_PHP_REMOVE   -> remove php tags</li>
  1352. +     *  <li>SMARTY_PHP_ALLOW    -> execute php tags</li>
  1353. +     * </ul>
  1354. +     *
  1355. +     * @var integer
  1356. +     */
  1357. +    var $php_handling    =  SMARTY_PHP_PASSTHRU;
  1358. +
  1359. +    /**
  1360. +     * This enables template security. When enabled, many things are restricted
  1361. +     * in the templates that normally would go unchecked. This is useful when
  1362. +     * untrusted parties are editing templates and you want a reasonable level
  1363. +     * of security. (no direct execution of PHP in templates for example)
  1364. +     *
  1365. +     * @var boolean
  1366. +     */
  1367. +    var $security       =   false;
  1368. +
  1369. +    /**
  1370. +     * This is the list of template directories that are considered secure. This
  1371. +     * is used only if {@link $security} is enabled. One directory per array
  1372. +     * element.  {@link $template_dir} is in this list implicitly.
  1373. +     *
  1374. +     * @var array
  1375. +     */
  1376. +    var $secure_dir     =   array();
  1377. +
  1378. +    /**
  1379. +     * These are the security settings for Smarty. They are used only when
  1380. +     * {@link $security} is enabled.
  1381. +     *
  1382. +     * @var array
  1383. +     */
  1384. +    var $security_settings  = array(
  1385. +                                    'PHP_HANDLING'    => false,
  1386. +                                    'IF_FUNCS'        => array('array', 'list',
  1387. +                                                               'isset', 'empty',
  1388. +                                                               'count', 'sizeof',
  1389. +                                                               'in_array', 'is_array',
  1390. +                                                               'true', 'false', 'null'),
  1391. +                                    'INCLUDE_ANY'     => false,
  1392. +                                    'PHP_TAGS'        => false,
  1393. +                                    'MODIFIER_FUNCS'  => array('count'),
  1394. +                                    'ALLOW_CONSTANTS'  => false,
  1395. +                                    'ALLOW_SUPER_GLOBALS' => true
  1396. +                                   );
  1397. +
  1398. +    /**
  1399. +     * This is an array of directories where trusted php scripts reside.
  1400. +     * {@link $security} is disabled during their inclusion/execution.
  1401. +     *
  1402. +     * @var array
  1403. +     */
  1404. +    var $trusted_dir        = array();
  1405. +
  1406. +    /**
  1407. +     * The left delimiter used for the template tags.
  1408. +     *
  1409. +     * @var string
  1410. +     */
  1411. +    var $left_delimiter  =  '{';
  1412. +
  1413. +    /**
  1414. +     * The right delimiter used for the template tags.
  1415. +     *
  1416. +     * @var string
  1417. +     */
  1418. +    var $right_delimiter =  '}';
  1419. +
  1420. +    /**
  1421. +     * The order in which request variables are registered, similar to
  1422. +     * variables_order in php.ini E = Environment, G = GET, P = POST,
  1423. +     * C = Cookies, S = Server
  1424. +     *
  1425. +     * @var string
  1426. +     */
  1427. +    var $request_vars_order    = 'EGPCS';
  1428. +
  1429. +    /**
  1430. +     * Indicates wether $HTTP_*_VARS[] (request_use_auto_globals=false)
  1431. +     * are uses as request-vars or $_*[]-vars. note: if
  1432. +     * request_use_auto_globals is true, then $request_vars_order has
  1433. +     * no effect, but the php-ini-value "gpc_order"
  1434. +     *
  1435. +     * @var boolean
  1436. +     */
  1437. +    var $request_use_auto_globals      = true;
  1438. +
  1439. +    /**
  1440. +     * Set this if you want different sets of compiled files for the same
  1441. +     * templates. This is useful for things like different languages.
  1442. +     * Instead of creating separate sets of templates per language, you
  1443. +     * set different compile_ids like 'en' and 'de'.
  1444. +     *
  1445. +     * @var string
  1446. +     */
  1447. +    var $compile_id            = null;
  1448. +
  1449. +    /**
  1450. +     * This tells Smarty whether or not to use sub dirs in the cache/ and
  1451. +     * templates_c/ directories. sub directories better organized, but
  1452. +     * may not work well with PHP safe mode enabled.
  1453. +     *
  1454. +     * @var boolean
  1455. +     *
  1456. +     */
  1457. +    var $use_sub_dirs          = false;
  1458. +
  1459. +    /**
  1460. +     * This is a list of the modifiers to apply to all template variables.
  1461. +     * Put each modifier in a separate array element in the order you want
  1462. +     * them applied. example: <code>array('escape:"htmlall"');</code>
  1463. +     *
  1464. +     * @var array
  1465. +     */
  1466. +    var $default_modifiers        = array();
  1467. +
  1468. +    /**
  1469. +     * This is the resource type to be used when not specified
  1470. +     * at the beginning of the resource path. examples:
  1471. +     * $smarty->display('file:index.tpl');
  1472. +     * $smarty->display('db:index.tpl');
  1473. +     * $smarty->display('index.tpl'); // will use default resource type
  1474. +     * {include file="file:index.tpl"}
  1475. +     * {include file="db:index.tpl"}
  1476. +     * {include file="index.tpl"} {* will use default resource type *}
  1477. +     *
  1478. +     * @var array
  1479. +     */
  1480. +    var $default_resource_type    = 'file';
  1481. +
  1482. +    /**
  1483. +     * The function used for cache file handling. If not set, built-in caching is used.
  1484. +     *
  1485. +     * @var null|string function name
  1486. +     */
  1487. +    var $cache_handler_func   = null;
  1488. +
  1489. +    /**
  1490. +     * This indicates which filters are automatically loaded into Smarty.
  1491. +     *
  1492. +     * @var array array of filter names
  1493. +     */
  1494. +    var $autoload_filters = array();
  1495. +
  1496. +    /**#@+
  1497. +     * @var boolean
  1498. +     */
  1499. +    /**
  1500. +     * This tells if config file vars of the same name overwrite each other or not.
  1501. +     * if disabled, same name variables are accumulated in an array.
  1502. +     */
  1503. +    var $config_overwrite = true;
  1504. +
  1505. +    /**
  1506. +     * This tells whether or not to automatically booleanize config file variables.
  1507. +     * If enabled, then the strings "on", "true", and "yes" are treated as boolean
  1508. +     * true, and "off", "false" and "no" are treated as boolean false.
  1509. +     */
  1510. +    var $config_booleanize = true;
  1511. +
  1512. +    /**
  1513. +     * This tells whether hidden sections [.foobar] are readable from the
  1514. +     * tempalates or not. Normally you would never allow this since that is
  1515. +     * the point behind hidden sections: the application can access them, but
  1516. +     * the templates cannot.
  1517. +     */
  1518. +    var $config_read_hidden = false;
  1519. +
  1520. +    /**
  1521. +     * This tells whether or not automatically fix newlines in config files.
  1522. +     * It basically converts \r (mac) or \r\n (dos) to \n
  1523. +     */
  1524. +    var $config_fix_newlines = true;
  1525. +    /**#@-*/
  1526. +
  1527. +    /**
  1528. +     * If a template cannot be found, this PHP function will be executed.
  1529. +     * Useful for creating templates on-the-fly or other special action.
  1530. +     *
  1531. +     * @var string function name
  1532. +     */
  1533. +    var $default_template_handler_func = '';
  1534. +
  1535. +    /**
  1536. +     * The file that contains the compiler class. This can a full
  1537. +     * pathname, or relative to the php_include path.
  1538. +     *
  1539. +     * @var string
  1540. +     */
  1541. +    var $compiler_file        =    'Smarty_Compiler.class.php';
  1542. +
  1543. +    /**
  1544. +     * The class used for compiling templates.
  1545. +     *
  1546. +     * @var string
  1547. +     */
  1548. +    var $compiler_class        =   'Smarty_Compiler';
  1549. +
  1550. +    /**
  1551. +     * The class used to load config vars.
  1552. +     *
  1553. +     * @var string
  1554. +     */
  1555. +    var $config_class          =   'Config_File';
  1556. +
  1557. +/**#@+
  1558. + * END Smarty Configuration Section
  1559. + * There should be no need to touch anything below this line.
  1560. + * @access private
  1561. + */
  1562. +    /**
  1563. +     * where assigned template vars are kept
  1564. +     *
  1565. +     * @var array
  1566. +     */
  1567. +    var $_tpl_vars             = array();
  1568. +
  1569. +    /**
  1570. +     * stores run-time $smarty.* vars
  1571. +     *
  1572. +     * @var null|array
  1573. +     */
  1574. +    var $_smarty_vars          = null;
  1575. +
  1576. +    /**
  1577. +     * keeps track of sections
  1578. +     *
  1579. +     * @var array
  1580. +     */
  1581. +    var $_sections             = array();
  1582. +
  1583. +    /**
  1584. +     * keeps track of foreach blocks
  1585. +     *
  1586. +     * @var array
  1587. +     */
  1588. +    var $_foreach              = array();
  1589. +
  1590. +    /**
  1591. +     * keeps track of tag hierarchy
  1592. +     *
  1593. +     * @var array
  1594. +     */
  1595. +    var $_tag_stack            = array();
  1596. +
  1597. +    /**
  1598. +     * configuration object
  1599. +     *
  1600. +     * @var Config_file
  1601. +     */
  1602. +    var $_conf_obj             = null;
  1603. +
  1604. +    /**
  1605. +     * loaded configuration settings
  1606. +     *
  1607. +     * @var array
  1608. +     */
  1609. +    var $_config               = array(array('vars'  => array(), 'files' => array()));
  1610. +
  1611. +    /**
  1612. +     * md5 checksum of the string 'Smarty'
  1613. +     *
  1614. +     * @var string
  1615. +     */
  1616. +    var $_smarty_md5           = 'f8d698aea36fcbead2b9d5359ffca76f';
  1617. +
  1618. +    /**
  1619. +     * Smarty version number
  1620. +     *
  1621. +     * @var string
  1622. +     */
  1623. +    var $_version              = '2.6.26';
  1624. +
  1625. +    /**
  1626. +     * current template inclusion depth
  1627. +     *
  1628. +     * @var integer
  1629. +     */
  1630. +    var $_inclusion_depth      = 0;
  1631. +
  1632. +    /**
  1633. +     * for different compiled templates
  1634. +     *
  1635. +     * @var string
  1636. +     */
  1637. +    var $_compile_id           = null;
  1638. +
  1639. +    /**
  1640. +     * text in URL to enable debug mode
  1641. +     *
  1642. +     * @var string
  1643. +     */
  1644. +    var $_smarty_debug_id      = 'SMARTY_DEBUG';
  1645. +
  1646. +    /**
  1647. +     * debugging information for debug console
  1648. +     *
  1649. +     * @var array
  1650. +     */
  1651. +    var $_smarty_debug_info    = array();
  1652. +
  1653. +    /**
  1654. +     * info that makes up a cache file
  1655. +     *
  1656. +     * @var array
  1657. +     */
  1658. +    var $_cache_info           = array();
  1659. +
  1660. +    /**
  1661. +     * default file permissions
  1662. +     *
  1663. +     * @var integer
  1664. +     */
  1665. +    var $_file_perms           = 0644;
  1666. +
  1667. +    /**
  1668. +     * default dir permissions
  1669. +     *
  1670. +     * @var integer
  1671. +     */
  1672. +    var $_dir_perms               = 0771;
  1673. +
  1674. +    /**
  1675. +     * registered objects
  1676. +     *
  1677. +     * @var array
  1678. +     */
  1679. +    var $_reg_objects           = array();
  1680. +
  1681. +    /**
  1682. +     * table keeping track of plugins
  1683. +     *
  1684. +     * @var array
  1685. +     */
  1686. +    var $_plugins              = array(
  1687. +                                       'modifier'      => array(),
  1688. +                                       'function'      => array(),
  1689. +                                       'block'         => array(),
  1690. +                                       'compiler'      => array(),
  1691. +                                       'prefilter'     => array(),
  1692. +                                       'postfilter'    => array(),
  1693. +                                       'outputfilter'  => array(),
  1694. +                                       'resource'      => array(),
  1695. +                                       'insert'        => array());
  1696. +
  1697. +
  1698. +    /**
  1699. +     * cache serials
  1700. +     *
  1701. +     * @var array
  1702. +     */
  1703. +    var $_cache_serials = array();
  1704. +
  1705. +    /**
  1706. +     * name of optional cache include file
  1707. +     *
  1708. +     * @var string
  1709. +     */
  1710. +    var $_cache_include = null;
  1711. +
  1712. +    /**
  1713. +     * indicate if the current code is used in a compiled
  1714. +     * include
  1715. +     *
  1716. +     * @var string
  1717. +     */
  1718. +    var $_cache_including = false;
  1719. +
  1720. +    /**#@-*/
  1721. +    /**
  1722. +     * The class constructor.
  1723. +     */
  1724. +    function Smarty()
  1725. +    {
  1726. +      $this->assign('SCRIPT_NAME', isset($_SERVER['SCRIPT_NAME']) ? $_SERVER['SCRIPT_NAME']
  1727. +                    : @$GLOBALS['HTTP_SERVER_VARS']['SCRIPT_NAME']);
  1728. +    }
  1729. +
  1730. +    /**
  1731. +     * assigns values to template variables
  1732. +     *
  1733. +     * @param array|string $tpl_var the template variable name(s)
  1734. +     * @param mixed $value the value to assign
  1735. +     */
  1736. +    function assign($tpl_var, $value = null)
  1737. +    {
  1738. +        if (is_array($tpl_var)){
  1739. +            foreach ($tpl_var as $key => $val) {
  1740. +                if ($key != '') {
  1741. +                    $this->_tpl_vars[$key] = $val;
  1742. +                }
  1743. +            }
  1744. +        } else {
  1745. +            if ($tpl_var != '')
  1746. +                $this->_tpl_vars[$tpl_var] = $value;
  1747. +        }
  1748. +    }
  1749. +
  1750. +    /**
  1751. +     * assigns values to template variables by reference
  1752. +     *
  1753. +     * @param string $tpl_var the template variable name
  1754. +     * @param mixed $value the referenced value to assign
  1755. +     */
  1756. +    function assign_by_ref($tpl_var, &$value)
  1757. +    {
  1758. +        if ($tpl_var != '')
  1759. +            $this->_tpl_vars[$tpl_var] = &$value;
  1760. +    }
  1761. +
  1762. +    /**
  1763. +     * appends values to template variables
  1764. +     *
  1765. +     * @param array|string $tpl_var the template variable name(s)
  1766. +     * @param mixed $value the value to append
  1767. +     */
  1768. +    function append($tpl_var, $value=null, $merge=false)
  1769. +    {
  1770. +        if (is_array($tpl_var)) {
  1771. +            // $tpl_var is an array, ignore $value
  1772. +            foreach ($tpl_var as $_key => $_val) {
  1773. +                if ($_key != '') {
  1774. +                    if(!@is_array($this->_tpl_vars[$_key])) {
  1775. +                        settype($this->_tpl_vars[$_key],'array');
  1776. +                    }
  1777. +                    if($merge && is_array($_val)) {
  1778. +                        foreach($_val as $_mkey => $_mval) {
  1779. +                            $this->_tpl_vars[$_key][$_mkey] = $_mval;
  1780. +                        }
  1781. +                    } else {
  1782. +                        $this->_tpl_vars[$_key][] = $_val;
  1783. +                    }
  1784. +                }
  1785. +            }
  1786. +        } else {
  1787. +            if ($tpl_var != '' && isset($value)) {
  1788. +                if(!@is_array($this->_tpl_vars[$tpl_var])) {
  1789. +                    settype($this->_tpl_vars[$tpl_var],'array');
  1790. +                }
  1791. +                if($merge && is_array($value)) {
  1792. +                    foreach($value as $_mkey => $_mval) {
  1793. +                        $this->_tpl_vars[$tpl_var][$_mkey] = $_mval;
  1794. +                    }
  1795. +                } else {
  1796. +                    $this->_tpl_vars[$tpl_var][] = $value;
  1797. +                }
  1798. +            }
  1799. +        }
  1800. +    }
  1801. +
  1802. +    /**
  1803. +     * appends values to template variables by reference
  1804. +     *
  1805. +     * @param string $tpl_var the template variable name
  1806. +     * @param mixed $value the referenced value to append
  1807. +     */
  1808. +    function append_by_ref($tpl_var, &$value, $merge=false)
  1809. +    {
  1810. +        if ($tpl_var != '' && isset($value)) {
  1811. +            if(!@is_array($this->_tpl_vars[$tpl_var])) {
  1812. +             settype($this->_tpl_vars[$tpl_var],'array');
  1813. +            }
  1814. +            if ($merge && is_array($value)) {
  1815. +                foreach($value as $_key => $_val) {
  1816. +                    $this->_tpl_vars[$tpl_var][$_key] = &$value[$_key];
  1817. +                }
  1818. +            } else {
  1819. +                $this->_tpl_vars[$tpl_var][] = &$value;
  1820. +            }
  1821. +        }
  1822. +    }
  1823. +
  1824. +
  1825. +    /**
  1826. +     * clear the given assigned template variable.
  1827. +     *
  1828. +     * @param string $tpl_var the template variable to clear
  1829. +     */
  1830. +    function clear_assign($tpl_var)
  1831. +    {
  1832. +        if (is_array($tpl_var))
  1833. +            foreach ($tpl_var as $curr_var)
  1834. +                unset($this->_tpl_vars[$curr_var]);
  1835. +        else
  1836. +            unset($this->_tpl_vars[$tpl_var]);
  1837. +    }
  1838. +
  1839. +
  1840. +    /**
  1841. +     * Registers custom function to be used in templates
  1842. +     *
  1843. +     * @param string $function the name of the template function
  1844. +     * @param string $function_impl the name of the PHP function to register
  1845. +     */
  1846. +    function register_function($function, $function_impl, $cacheable=true, $cache_attrs=null)
  1847. +    {
  1848. +        $this->_plugins['function'][$function] =
  1849. +            array($function_impl, null, null, false, $cacheable, $cache_attrs);
  1850. +
  1851. +    }
  1852. +
  1853. +    /**
  1854. +     * Unregisters custom function
  1855. +     *
  1856. +     * @param string $function name of template function
  1857. +     */
  1858. +    function unregister_function($function)
  1859. +    {
  1860. +        unset($this->_plugins['function'][$function]);
  1861. +    }
  1862. +
  1863. +    /**
  1864. +     * Registers object to be used in templates
  1865. +     *
  1866. +     * @param string $object name of template object
  1867. +     * @param object &$object_impl the referenced PHP object to register
  1868. +     * @param null|array $allowed list of allowed methods (empty = all)
  1869. +     * @param boolean $smarty_args smarty argument format, else traditional
  1870. +     * @param null|array $block_functs list of methods that are block format
  1871. +     */
  1872. +    function register_object($object, &$object_impl, $allowed = array(), $smarty_args = true, $block_methods = array())
  1873. +    {
  1874. +        settype($allowed, 'array');
  1875. +        settype($smarty_args, 'boolean');
  1876. +        $this->_reg_objects[$object] =
  1877. +            array(&$object_impl, $allowed, $smarty_args, $block_methods);
  1878. +    }
  1879. +
  1880. +    /**
  1881. +     * Unregisters object
  1882. +     *
  1883. +     * @param string $object name of template object
  1884. +     */
  1885. +    function unregister_object($object)
  1886. +    {
  1887. +        unset($this->_reg_objects[$object]);
  1888. +    }
  1889. +
  1890. +
  1891. +    /**
  1892. +     * Registers block function to be used in templates
  1893. +     *
  1894. +     * @param string $block name of template block
  1895. +     * @param string $block_impl PHP function to register
  1896. +     */
  1897. +    function register_block($block, $block_impl, $cacheable=true, $cache_attrs=null)
  1898. +    {
  1899. +        $this->_plugins['block'][$block] =
  1900. +            array($block_impl, null, null, false, $cacheable, $cache_attrs);
  1901. +    }
  1902. +
  1903. +    /**
  1904. +     * Unregisters block function
  1905. +     *
  1906. +     * @param string $block name of template function
  1907. +     */
  1908. +    function unregister_block($block)
  1909. +    {
  1910. +        unset($this->_plugins['block'][$block]);
  1911. +    }
  1912. +
  1913. +    /**
  1914. +     * Registers compiler function
  1915. +     *
  1916. +     * @param string $function name of template function
  1917. +     * @param string $function_impl name of PHP function to register
  1918. +     */
  1919. +    function register_compiler_function($function, $function_impl, $cacheable=true)
  1920. +    {
  1921. +        $this->_plugins['compiler'][$function] =
  1922. +            array($function_impl, null, null, false, $cacheable);
  1923. +    }
  1924. +
  1925. +    /**
  1926. +     * Unregisters compiler function
  1927. +     *
  1928. +     * @param string $function name of template function
  1929. +     */
  1930. +    function unregister_compiler_function($function)
  1931. +    {
  1932. +        unset($this->_plugins['compiler'][$function]);
  1933. +    }
  1934. +
  1935. +    /**
  1936. +     * Registers modifier to be used in templates
  1937. +     *
  1938. +     * @param string $modifier name of template modifier
  1939. +     * @param string $modifier_impl name of PHP function to register
  1940. +     */
  1941. +    function register_modifier($modifier, $modifier_impl)
  1942. +    {
  1943. +        $this->_plugins['modifier'][$modifier] =
  1944. +            array($modifier_impl, null, null, false);
  1945. +    }
  1946. +
  1947. +    /**
  1948. +     * Unregisters modifier
  1949. +     *
  1950. +     * @param string $modifier name of template modifier
  1951. +     */
  1952. +    function unregister_modifier($modifier)
  1953. +    {
  1954. +        unset($this->_plugins['modifier'][$modifier]);
  1955. +    }
  1956. +
  1957. +    /**
  1958. +     * Registers a resource to fetch a template
  1959. +     *
  1960. +     * @param string $type name of resource
  1961. +     * @param array $functions array of functions to handle resource
  1962. +     */
  1963. +    function register_resource($type, $functions)
  1964. +    {
  1965. +        if (count($functions)==4) {
  1966. +            $this->_plugins['resource'][$type] =
  1967. +                array($functions, false);
  1968. +
  1969. +        } elseif (count($functions)==5) {
  1970. +            $this->_plugins['resource'][$type] =
  1971. +                array(array(array(&$functions[0], $functions[1])
  1972. +                            ,array(&$functions[0], $functions[2])
  1973. +                            ,array(&$functions[0], $functions[3])
  1974. +                            ,array(&$functions[0], $functions[4]))
  1975. +                      ,false);
  1976. +
  1977. +        } else {
  1978. +            $this->trigger_error("malformed function-list for '$type' in register_resource");
  1979. +
  1980. +        }
  1981. +    }
  1982. +
  1983. +    /**
  1984. +     * Unregisters a resource
  1985. +     *
  1986. +     * @param string $type name of resource
  1987. +     */
  1988. +    function unregister_resource($type)
  1989. +    {
  1990. +        unset($this->_plugins['resource'][$type]);
  1991. +    }
  1992. +
  1993. +    /**
  1994. +     * Registers a prefilter function to apply
  1995. +     * to a template before compiling
  1996. +     *
  1997. +     * @param callback $function
  1998. +     */
  1999. +    function register_prefilter($function)
  2000. +    {
  2001. +        $this->_plugins['prefilter'][$this->_get_filter_name($function)]
  2002. +            = array($function, null, null, false);
  2003. +    }
  2004. +
  2005. +    /**
  2006. +     * Unregisters a prefilter function
  2007. +     *
  2008. +     * @param callback $function
  2009. +     */
  2010. +    function unregister_prefilter($function)
  2011. +    {
  2012. +        unset($this->_plugins['prefilter'][$this->_get_filter_name($function)]);
  2013. +    }
  2014. +
  2015. +    /**
  2016. +     * Registers a postfilter function to apply
  2017. +     * to a compiled template after compilation
  2018. +     *
  2019. +     * @param callback $function
  2020. +     */
  2021. +    function register_postfilter($function)
  2022. +    {
  2023. +        $this->_plugins['postfilter'][$this->_get_filter_name($function)]
  2024. +            = array($function, null, null, false);
  2025. +    }
  2026. +
  2027. +    /**
  2028. +     * Unregisters a postfilter function
  2029. +     *
  2030. +     * @param callback $function
  2031. +     */
  2032. +    function unregister_postfilter($function)
  2033. +    {
  2034. +        unset($this->_plugins['postfilter'][$this->_get_filter_name($function)]);
  2035. +    }
  2036. +
  2037. +    /**
  2038. +     * Registers an output filter function to apply
  2039. +     * to a template output
  2040. +     *
  2041. +     * @param callback $function
  2042. +     */
  2043. +    function register_outputfilter($function)
  2044. +    {
  2045. +        $this->_plugins['outputfilter'][$this->_get_filter_name($function)]
  2046. +            = array($function, null, null, false);
  2047. +    }
  2048. +
  2049. +    /**
  2050. +     * Unregisters an outputfilter function
  2051. +     *
  2052. +     * @param callback $function
  2053. +     */
  2054. +    function unregister_outputfilter($function)
  2055. +    {
  2056. +        unset($this->_plugins['outputfilter'][$this->_get_filter_name($function)]);
  2057. +    }
  2058. +
  2059. +    /**
  2060. +     * load a filter of specified type and name
  2061. +     *
  2062. +     * @param string $type filter type
  2063. +     * @param string $name filter name
  2064. +     */
  2065. +    function load_filter($type, $name)
  2066. +    {
  2067. +        switch ($type) {
  2068. +            case 'output':
  2069. +                $_params = array('plugins' => array(array($type . 'filter', $name, null, null, false)));
  2070. +                require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');
  2071. +                smarty_core_load_plugins($_params, $this);
  2072. +                break;
  2073. +
  2074. +            case 'pre':
  2075. +            case 'post':
  2076. +                if (!isset($this->_plugins[$type . 'filter'][$name]))
  2077. +                    $this->_plugins[$type . 'filter'][$name] = false;
  2078. +                break;
  2079. +        }
  2080. +    }
  2081. +
  2082. +    /**
  2083. +     * clear cached content for the given template and cache id
  2084. +     *
  2085. +     * @param string $tpl_file name of template file
  2086. +     * @param string $cache_id name of cache_id
  2087. +     * @param string $compile_id name of compile_id
  2088. +     * @param string $exp_time expiration time
  2089. +     * @return boolean
  2090. +     */
  2091. +    function clear_cache($tpl_file = null, $cache_id = null, $compile_id = null, $exp_time = null)
  2092. +    {
  2093. +
  2094. +        if (!isset($compile_id))
  2095. +            $compile_id = $this->compile_id;
  2096. +
  2097. +        if (!isset($tpl_file))
  2098. +            $compile_id = null;
  2099. +
  2100. +        $_auto_id = $this->_get_auto_id($cache_id, $compile_id);
  2101. +
  2102. +        if (!empty($this->cache_handler_func)) {
  2103. +            return call_user_func_array($this->cache_handler_func,
  2104. +                                  array('clear', &$this, &$dummy, $tpl_file, $cache_id, $compile_id, $exp_time));
  2105. +        } else {
  2106. +            $_params = array('auto_base' => $this->cache_dir,
  2107. +                            'auto_source' => $tpl_file,
  2108. +                            'auto_id' => $_auto_id,
  2109. +                            'exp_time' => $exp_time);
  2110. +            require_once(SMARTY_CORE_DIR . 'core.rm_auto.php');
  2111. +            return smarty_core_rm_auto($_params, $this);
  2112. +        }
  2113. +
  2114. +    }
  2115. +
  2116. +
  2117. +    /**
  2118. +     * clear the entire contents of cache (all templates)
  2119. +     *
  2120. +     * @param string $exp_time expire time
  2121. +     * @return boolean results of {@link smarty_core_rm_auto()}
  2122. +     */
  2123. +    function clear_all_cache($exp_time = null)
  2124. +    {
  2125. +        return $this->clear_cache(null, null, null, $exp_time);
  2126. +    }
  2127. +
  2128. +
  2129. +    /**
  2130. +     * test to see if valid cache exists for this template
  2131. +     *
  2132. +     * @param string $tpl_file name of template file
  2133. +     * @param string $cache_id
  2134. +     * @param string $compile_id
  2135. +     * @return string|false results of {@link _read_cache_file()}
  2136. +     */
  2137. +    function is_cached($tpl_file, $cache_id = null, $compile_id = null)
  2138. +    {
  2139. +        if (!$this->caching)
  2140. +            return false;
  2141. +
  2142. +        if (!isset($compile_id))
  2143. +            $compile_id = $this->compile_id;
  2144. +
  2145. +        $_params = array(
  2146. +            'tpl_file' => $tpl_file,
  2147. +            'cache_id' => $cache_id,
  2148. +            'compile_id' => $compile_id
  2149. +        );
  2150. +        require_once(SMARTY_CORE_DIR . 'core.read_cache_file.php');
  2151. +        return smarty_core_read_cache_file($_params, $this);
  2152. +    }
  2153. +
  2154. +
  2155. +    /**
  2156. +     * clear all the assigned template variables.
  2157. +     *
  2158. +     */
  2159. +    function clear_all_assign()
  2160. +    {
  2161. +        $this->_tpl_vars = array();
  2162. +    }
  2163. +
  2164. +    /**
  2165. +     * clears compiled version of specified template resource,
  2166. +     * or all compiled template files if one is not specified.
  2167. +     * This function is for advanced use only, not normally needed.
  2168. +     *
  2169. +     * @param string $tpl_file
  2170. +     * @param string $compile_id
  2171. +     * @param string $exp_time
  2172. +     * @return boolean results of {@link smarty_core_rm_auto()}
  2173. +     */
  2174. +    function clear_compiled_tpl($tpl_file = null, $compile_id = null, $exp_time = null)
  2175. +    {
  2176. +        if (!isset($compile_id)) {
  2177. +            $compile_id = $this->compile_id;
  2178. +        }
  2179. +        $_params = array('auto_base' => $this->compile_dir,
  2180. +                        'auto_source' => $tpl_file,
  2181. +                        'auto_id' => $compile_id,
  2182. +                        'exp_time' => $exp_time,
  2183. +                        'extensions' => array('.inc', '.php'));
  2184. +        require_once(SMARTY_CORE_DIR . 'core.rm_auto.php');
  2185. +        return smarty_core_rm_auto($_params, $this);
  2186. +    }
  2187. +
  2188. +    /**
  2189. +     * Checks whether requested template exists.
  2190. +     *
  2191. +     * @param string $tpl_file
  2192. +     * @return boolean
  2193. +     */
  2194. +    function template_exists($tpl_file)
  2195. +    {
  2196. +        $_params = array('resource_name' => $tpl_file, 'quiet'=>true, 'get_source'=>false);
  2197. +        return $this->_fetch_resource_info($_params);
  2198. +    }
  2199. +
  2200. +    /**
  2201. +     * Returns an array containing template variables
  2202. +     *
  2203. +     * @param string $name
  2204. +     * @param string $type
  2205. +     * @return array
  2206. +     */
  2207. +    function &get_template_vars($name=null)
  2208. +    {
  2209. +        if(!isset($name)) {
  2210. +            return $this->_tpl_vars;
  2211. +        } elseif(isset($this->_tpl_vars[$name])) {
  2212. +            return $this->_tpl_vars[$name];
  2213. +        } else {
  2214. +            // var non-existant, return valid reference
  2215. +            $_tmp = null;
  2216. +            return $_tmp;  
  2217. +        }
  2218. +    }
  2219. +
  2220. +    /**
  2221. +     * Returns an array containing config variables
  2222. +     *
  2223. +     * @param string $name
  2224. +     * @param string $type
  2225. +     * @return array
  2226. +     */
  2227. +    function &get_config_vars($name=null)
  2228. +    {
  2229. +        if(!isset($name) && is_array($this->_config[0])) {
  2230. +            return $this->_config[0]['vars'];
  2231. +        } else if(isset($this->_config[0]['vars'][$name])) {
  2232. +            return $this->_config[0]['vars'][$name];
  2233. +        } else {
  2234. +            // var non-existant, return valid reference
  2235. +            $_tmp = null;
  2236. +            return $_tmp;
  2237. +        }
  2238. +    }
  2239. +
  2240. +    /**
  2241. +     * trigger Smarty error
  2242. +     *
  2243. +     * @param string $error_msg
  2244. +     * @param integer $error_type
  2245. +     */
  2246. +    function trigger_error($error_msg, $error_type = E_USER_WARNING)
  2247. +    {
  2248. +        trigger_error("Smarty error: $error_msg", $error_type);
  2249. +    }
  2250. +
  2251. +
  2252. +    /**
  2253. +     * executes & displays the template results
  2254. +     *
  2255. +     * @param string $resource_name
  2256. +     * @param string $cache_id
  2257. +     * @param string $compile_id
  2258. +     */
  2259. +    function display($resource_name, $cache_id = null, $compile_id = null)
  2260. +    {
  2261. +        $this->fetch($resource_name, $cache_id, $compile_id, true);
  2262. +    }
  2263. +
  2264. +    /**
  2265. +     * executes & returns or displays the template results
  2266. +     *
  2267. +     * @param string $resource_name
  2268. +     * @param string $cache_id
  2269. +     * @param string $compile_id
  2270. +     * @param boolean $display
  2271. +     */
  2272. +    function fetch($resource_name, $cache_id = null, $compile_id = null, $display = false)
  2273. +    {
  2274. +        static $_cache_info = array();
  2275. +        
  2276. +        $_smarty_old_error_level = $this->debugging ? error_reporting() : error_reporting(isset($this->error_reporting)
  2277. +               ? $this->error_reporting : error_reporting() & ~E_NOTICE);
  2278. +
  2279. +        if (!$this->debugging && $this->debugging_ctrl == 'URL') {
  2280. +            $_query_string = $this->request_use_auto_globals ? $_SERVER['QUERY_STRING'] : $GLOBALS['HTTP_SERVER_VARS']['QUERY_STRING'];
  2281. +            if (@strstr($_query_string, $this->_smarty_debug_id)) {
  2282. +                if (@strstr($_query_string, $this->_smarty_debug_id . '=on')) {
  2283. +                    // enable debugging for this browser session
  2284. +                    @setcookie('SMARTY_DEBUG', true);
  2285. +                    $this->debugging = true;
  2286. +                } elseif (@strstr($_query_string, $this->_smarty_debug_id . '=off')) {
  2287. +                    // disable debugging for this browser session
  2288. +                    @setcookie('SMARTY_DEBUG', false);
  2289. +                    $this->debugging = false;
  2290. +                } else {
  2291. +                    // enable debugging for this page
  2292. +                    $this->debugging = true;
  2293. +                }
  2294. +            } else {
  2295. +                $this->debugging = (bool)($this->request_use_auto_globals ? @$_COOKIE['SMARTY_DEBUG'] : @$GLOBALS['HTTP_COOKIE_VARS']['SMARTY_DEBUG']);
  2296. +            }
  2297. +        }
  2298. +
  2299. +        if ($this->debugging) {
  2300. +            // capture time for debugging info
  2301. +            $_params = array();
  2302. +            require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
  2303. +            $_debug_start_time = smarty_core_get_microtime($_params, $this);
  2304. +            $this->_smarty_debug_info[] = array('type'      => 'template',
  2305. +                                                'filename'  => $resource_name,
  2306. +                                                'depth'     => 0);
  2307. +            $_included_tpls_idx = count($this->_smarty_debug_info) - 1;
  2308. +        }
  2309. +
  2310. +        if (!isset($compile_id)) {
  2311. +            $compile_id = $this->compile_id;
  2312. +        }
  2313. +
  2314. +        $this->_compile_id = $compile_id;
  2315. +        $this->_inclusion_depth = 0;
  2316. +
  2317. +        if ($this->caching) {
  2318. +            // save old cache_info, initialize cache_info
  2319. +            array_push($_cache_info, $this->_cache_info);
  2320. +            $this->_cache_info = array();
  2321. +            $_params = array(
  2322. +                'tpl_file' => $resource_name,
  2323. +                'cache_id' => $cache_id,
  2324. +                'compile_id' => $compile_id,
  2325. +                'results' => null
  2326. +            );
  2327. +            require_once(SMARTY_CORE_DIR . 'core.read_cache_file.php');
  2328. +            if (smarty_core_read_cache_file($_params, $this)) {
  2329. +                $_smarty_results = $_params['results'];
  2330. +                if (!empty($this->_cache_info['insert_tags'])) {
  2331. +                    $_params = array('plugins' => $this->_cache_info['insert_tags']);
  2332. +                    require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');
  2333. +                    smarty_core_load_plugins($_params, $this);
  2334. +                    $_params = array('results' => $_smarty_results);
  2335. +                    require_once(SMARTY_CORE_DIR . 'core.process_cached_inserts.php');
  2336. +                    $_smarty_results = smarty_core_process_cached_inserts($_params, $this);
  2337. +                }
  2338. +                if (!empty($this->_cache_info['cache_serials'])) {
  2339. +                    $_params = array('results' => $_smarty_results);
  2340. +                    require_once(SMARTY_CORE_DIR . 'core.process_compiled_include.php');
  2341. +                    $_smarty_results = smarty_core_process_compiled_include($_params, $this);
  2342. +                }
  2343. +
  2344. +
  2345. +                if ($display) {
  2346. +                    if ($this->debugging)
  2347. +                    {
  2348. +                        // capture time for debugging info
  2349. +                        $_params = array();
  2350. +                        require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
  2351. +                        $this->_smarty_debug_info[$_included_tpls_idx]['exec_time'] = smarty_core_get_microtime($_params, $this) - $_debug_start_time;
  2352. +                        require_once(SMARTY_CORE_DIR . 'core.display_debug_console.php');
  2353. +                        $_smarty_results .= smarty_core_display_debug_console($_params, $this);
  2354. +                    }
  2355. +                    if ($this->cache_modified_check) {
  2356. +                        $_server_vars = ($this->request_use_auto_globals) ? $_SERVER : $GLOBALS['HTTP_SERVER_VARS'];
  2357. +                        $_last_modified_date = @substr($_server_vars['HTTP_IF_MODIFIED_SINCE'], 0, strpos($_server_vars['HTTP_IF_MODIFIED_SINCE'], 'GMT') + 3);
  2358. +                        $_gmt_mtime = gmdate('D, d M Y H:i:s', $this->_cache_info['timestamp']).' GMT';
  2359. +                        if (@count($this->_cache_info['insert_tags']) == 0
  2360. +                            && !$this->_cache_serials
  2361. +                            && $_gmt_mtime == $_last_modified_date) {
  2362. +                            if (php_sapi_name()=='cgi')
  2363. +                                header('Status: 304 Not Modified');
  2364. +                            else
  2365. +                                header('HTTP/1.1 304 Not Modified');
  2366. +
  2367. +                        } else {
  2368. +                            header('Last-Modified: '.$_gmt_mtime);
  2369. +                            echo $_smarty_results;
  2370. +                        }
  2371. +                    } else {
  2372. +                            echo $_smarty_results;
  2373. +                    }
  2374. +                    error_reporting($_smarty_old_error_level);
  2375. +                    // restore initial cache_info
  2376. +                    $this->_cache_info = array_pop($_cache_info);
  2377. +                    return true;
  2378. +                } else {
  2379. +                    error_reporting($_smarty_old_error_level);
  2380. +                    // restore initial cache_info
  2381. +                    $this->_cache_info = array_pop($_cache_info);
  2382. +                    return $_smarty_results;
  2383. +                }
  2384. +            } else {
  2385. +                $this->_cache_info['template'][$resource_name] = true;
  2386. +                if ($this->cache_modified_check && $display) {
  2387. +                    header('Last-Modified: '.gmdate('D, d M Y H:i:s', time()).' GMT');
  2388. +                }
  2389. +            }
  2390. +        }
  2391. +
  2392. +        // load filters that are marked as autoload
  2393. +        if (count($this->autoload_filters)) {
  2394. +            foreach ($this->autoload_filters as $_filter_type => $_filters) {
  2395. +                foreach ($_filters as $_filter) {
  2396. +                    $this->load_filter($_filter_type, $_filter);
  2397. +                }
  2398. +            }
  2399. +        }
  2400. +
  2401. +        $_smarty_compile_path = $this->_get_compile_path($resource_name);
  2402. +
  2403. +        // if we just need to display the results, don't perform output
  2404. +        // buffering - for speed
  2405. +        $_cache_including = $this->_cache_including;
  2406. +        $this->_cache_including = false;
  2407. +        if ($display && !$this->caching && count($this->_plugins['outputfilter']) == 0) {
  2408. +            if ($this->_is_compiled($resource_name, $_smarty_compile_path)
  2409. +                    || $this->_compile_resource($resource_name, $_smarty_compile_path))
  2410. +            {
  2411. +                include($_smarty_compile_path);
  2412. +            }
  2413. +        } else {
  2414. +            ob_start();
  2415. +            if ($this->_is_compiled($resource_name, $_smarty_compile_path)
  2416. +                    || $this->_compile_resource($resource_name, $_smarty_compile_path))
  2417. +            {
  2418. +                include($_smarty_compile_path);
  2419. +            }
  2420. +            $_smarty_results = ob_get_contents();
  2421. +            ob_end_clean();
  2422. +
  2423. +            foreach ((array)$this->_plugins['outputfilter'] as $_output_filter) {
  2424. +                $_smarty_results = call_user_func_array($_output_filter[0], array($_smarty_results, &$this));
  2425. +            }
  2426. +        }
  2427. +
  2428. +        if ($this->caching) {
  2429. +            $_params = array('tpl_file' => $resource_name,
  2430. +                        'cache_id' => $cache_id,
  2431. +                        'compile_id' => $compile_id,
  2432. +                        'results' => $_smarty_results);
  2433. +            require_once(SMARTY_CORE_DIR . 'core.write_cache_file.php');
  2434. +            smarty_core_write_cache_file($_params, $this);
  2435. +            require_once(SMARTY_CORE_DIR . 'core.process_cached_inserts.php');
  2436. +            $_smarty_results = smarty_core_process_cached_inserts($_params, $this);
  2437. +
  2438. +            if ($this->_cache_serials) {
  2439. +                // strip nocache-tags from output
  2440. +                $_smarty_results = preg_replace('!(\{/?nocache\:[0-9a-f]{32}#\d+\})!s'
  2441. +                                                ,''
  2442. +                                                ,$_smarty_results);
  2443. +            }
  2444. +            // restore initial cache_info
  2445. +            $this->_cache_info = array_pop($_cache_info);
  2446. +        }
  2447. +        $this->_cache_including = $_cache_including;
  2448. +
  2449. +        if ($display) {
  2450. +            if (isset($_smarty_results)) { echo $_smarty_results; }
  2451. +            if ($this->debugging) {
  2452. +                // capture time for debugging info
  2453. +                $_params = array();
  2454. +                require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
  2455. +                $this->_smarty_debug_info[$_included_tpls_idx]['exec_time'] = (smarty_core_get_microtime($_params, $this) - $_debug_start_time);
  2456. +                require_once(SMARTY_CORE_DIR . 'core.display_debug_console.php');
  2457. +                echo smarty_core_display_debug_console($_params, $this);
  2458. +            }
  2459. +            error_reporting($_smarty_old_error_level);
  2460. +            return;
  2461. +        } else {
  2462. +            error_reporting($_smarty_old_error_level);
  2463. +            if (isset($_smarty_results)) { return $_smarty_results; }
  2464. +        }
  2465. +    }
  2466. +
  2467. +    /**
  2468. +     * load configuration values
  2469. +     *
  2470. +     * @param string $file
  2471. +     * @param string $section
  2472. +     * @param string $scope
  2473. +     */
  2474. +    function config_load($file, $section = null, $scope = 'global')
  2475. +    {
  2476. +        require_once($this->_get_plugin_filepath('function', 'config_load'));
  2477. +        smarty_function_config_load(array('file' => $file, 'section' => $section, 'scope' => $scope), $this);
  2478. +    }
  2479. +
  2480. +    /**
  2481. +     * return a reference to a registered object
  2482. +     *
  2483. +     * @param string $name
  2484. +     * @return object
  2485. +     */
  2486. +    function &get_registered_object($name) {
  2487. +        if (!isset($this->_reg_objects[$name]))
  2488. +        $this->_trigger_fatal_error("'$name' is not a registered object");
  2489. +
  2490. +        if (!is_object($this->_reg_objects[$name][0]))
  2491. +        $this->_trigger_fatal_error("registered '$name' is not an object");
  2492. +
  2493. +        return $this->_reg_objects[$name][0];
  2494. +    }
  2495. +
  2496. +    /**
  2497. +     * clear configuration values
  2498. +     *
  2499. +     * @param string $var
  2500. +     */
  2501. +    function clear_config($var = null)
  2502. +    {
  2503. +        if(!isset($var)) {
  2504. +            // clear all values
  2505. +            $this->_config = array(array('vars'  => array(),
  2506. +                                         'files' => array()));
  2507. +        } else {
  2508. +            unset($this->_config[0]['vars'][$var]);
  2509. +        }
  2510. +    }
  2511. +
  2512. +    /**
  2513. +     * get filepath of requested plugin
  2514. +     *
  2515. +     * @param string $type
  2516. +     * @param string $name
  2517. +     * @return string|false
  2518. +     */
  2519. +    function _get_plugin_filepath($type, $name)
  2520. +    {
  2521. +        $_params = array('type' => $type, 'name' => $name);
  2522. +        require_once(SMARTY_CORE_DIR . 'core.assemble_plugin_filepath.php');
  2523. +        return smarty_core_assemble_plugin_filepath($_params, $this);
  2524. +    }
  2525. +
  2526. +   /**
  2527. +     * test if resource needs compiling
  2528. +     *
  2529. +     * @param string $resource_name
  2530. +     * @param string $compile_path
  2531. +     * @return boolean
  2532. +     */
  2533. +    function _is_compiled($resource_name, $compile_path)
  2534. +    {
  2535. +        if (!$this->force_compile && file_exists($compile_path)) {
  2536. +            if (!$this->compile_check) {
  2537. +                // no need to check compiled file
  2538. +                return true;
  2539. +            } else {
  2540. +                // get file source and timestamp
  2541. +                $_params = array('resource_name' => $resource_name, 'get_source'=>false);
  2542. +                if (!$this->_fetch_resource_info($_params)) {
  2543. +                    return false;
  2544. +                }
  2545. +                if ($_params['resource_timestamp'] <= filemtime($compile_path)) {
  2546. +                    // template not expired, no recompile
  2547. +                    return true;
  2548. +                } else {
  2549. +                    // compile template
  2550. +                    return false;
  2551. +                }
  2552. +            }
  2553. +        } else {
  2554. +            // compiled template does not exist, or forced compile
  2555. +            return false;
  2556. +        }
  2557. +    }
  2558. +
  2559. +   /**
  2560. +     * compile the template
  2561. +     *
  2562. +     * @param string $resource_name
  2563. +     * @param string $compile_path
  2564. +     * @return boolean
  2565. +     */
  2566. +    function _compile_resource($resource_name, $compile_path)
  2567. +    {
  2568. +
  2569. +        $_params = array('resource_name' => $resource_name);
  2570. +        if (!$this->_fetch_resource_info($_params)) {
  2571. +            return false;
  2572. +        }
  2573. +
  2574. +        $_source_content = $_params['source_content'];
  2575. +        $_cache_include    = substr($compile_path, 0, -4).'.inc';
  2576. +
  2577. +        if ($this->_compile_source($resource_name, $_source_content, $_compiled_content, $_cache_include)) {
  2578. +            // if a _cache_serial was set, we also have to write an include-file:
  2579. +            if ($this->_cache_include_info) {
  2580. +                require_once(SMARTY_CORE_DIR . 'core.write_compiled_include.php');
  2581. +                smarty_core_write_compiled_include(array_merge($this->_cache_include_info, array('compiled_content'=>$_compiled_content, 'resource_name'=>$resource_name)),  $this);
  2582. +            }
  2583. +
  2584. +            $_params = array('compile_path'=>$compile_path, 'compiled_content' => $_compiled_content);
  2585. +            require_once(SMARTY_CORE_DIR . 'core.write_compiled_resource.php');
  2586. +            smarty_core_write_compiled_resource($_params, $this);
  2587. +
  2588. +            return true;
  2589. +        } else {
  2590. +            return false;
  2591. +        }
  2592. +
  2593. +    }
  2594. +
  2595. +   /**
  2596. +     * compile the given source
  2597. +     *
  2598. +     * @param string $resource_name
  2599. +     * @param string $source_content
  2600. +     * @param string $compiled_content
  2601. +     * @return boolean
  2602. +     */
  2603. +    function _compile_source($resource_name, &$source_content, &$compiled_content, $cache_include_path=null)
  2604. +    {
  2605. +        if (file_exists(SMARTY_DIR . $this->compiler_file)) {
  2606. +            require_once(SMARTY_DIR . $this->compiler_file);
  2607. +        } else {
  2608. +            // use include_path
  2609. +            require_once($this->compiler_file);
  2610. +        }
  2611. +
  2612. +
  2613. +        $smarty_compiler = new $this->compiler_class;
  2614. +
  2615. +        $smarty_compiler->template_dir      = $this->template_dir;
  2616. +        $smarty_compiler->compile_dir       = $this->compile_dir;
  2617. +        $smarty_compiler->plugins_dir       = $this->plugins_dir;
  2618. +        $smarty_compiler->config_dir        = $this->config_dir;
  2619. +        $smarty_compiler->force_compile     = $this->force_compile;
  2620. +        $smarty_compiler->caching           = $this->caching;
  2621. +        $smarty_compiler->php_handling      = $this->php_handling;
  2622. +        $smarty_compiler->left_delimiter    = $this->left_delimiter;
  2623. +        $smarty_compiler->right_delimiter   = $this->right_delimiter;
  2624. +        $smarty_compiler->_version          = $this->_version;
  2625. +        $smarty_compiler->security          = $this->security;
  2626. +        $smarty_compiler->secure_dir        = $this->secure_dir;
  2627. +        $smarty_compiler->security_settings = $this->security_settings;
  2628. +        $smarty_compiler->trusted_dir       = $this->trusted_dir;
  2629. +        $smarty_compiler->use_sub_dirs      = $this->use_sub_dirs;
  2630. +        $smarty_compiler->_reg_objects      = &$this->_reg_objects;
  2631. +        $smarty_compiler->_plugins          = &$this->_plugins;
  2632. +        $smarty_compiler->_tpl_vars         = &$this->_tpl_vars;
  2633. +        $smarty_compiler->default_modifiers = $this->default_modifiers;
  2634. +        $smarty_compiler->compile_id        = $this->_compile_id;
  2635. +        $smarty_compiler->_config            = $this->_config;
  2636. +        $smarty_compiler->request_use_auto_globals  = $this->request_use_auto_globals;
  2637. +
  2638. +        if (isset($cache_include_path) && isset($this->_cache_serials[$cache_include_path])) {
  2639. +            $smarty_compiler->_cache_serial = $this->_cache_serials[$cache_include_path];
  2640. +        }
  2641. +        $smarty_compiler->_cache_include = $cache_include_path;
  2642. +
  2643. +
  2644. +        $_results = $smarty_compiler->_compile_file($resource_name, $source_content, $compiled_content);
  2645. +
  2646. +        if ($smarty_compiler->_cache_serial) {
  2647. +            $this->_cache_include_info = array(
  2648. +                'cache_serial'=>$smarty_compiler->_cache_serial
  2649. +                ,'plugins_code'=>$smarty_compiler->_plugins_code
  2650. +                ,'include_file_path' => $cache_include_path);
  2651. +
  2652. +        } else {
  2653. +            $this->_cache_include_info = null;
  2654. +
  2655. +        }
  2656. +
  2657. +        return $_results;
  2658. +    }
  2659. +
  2660. +    /**
  2661. +     * Get the compile path for this resource
  2662. +     *
  2663. +     * @param string $resource_name
  2664. +     * @return string results of {@link _get_auto_filename()}
  2665. +     */
  2666. +    function _get_compile_path($resource_name)
  2667. +    {
  2668. +        return $this->_get_auto_filename($this->compile_dir, $resource_name,
  2669. +                                         $this->_compile_id) . '.php';
  2670. +    }
  2671. +
  2672. +    /**
  2673. +     * fetch the template info. Gets timestamp, and source
  2674. +     * if get_source is true
  2675. +     *
  2676. +     * sets $source_content to the source of the template, and
  2677. +     * $resource_timestamp to its time stamp
  2678. +     * @param string $resource_name
  2679. +     * @param string $source_content
  2680. +     * @param integer $resource_timestamp
  2681. +     * @param boolean $get_source
  2682. +     * @param boolean $quiet
  2683. +     * @return boolean
  2684. +     */
  2685. +
  2686. +    function _fetch_resource_info(&$params)
  2687. +    {
  2688. +        if(!isset($params['get_source'])) { $params['get_source'] = true; }
  2689. +        if(!isset($params['quiet'])) { $params['quiet'] = false; }
  2690. +
  2691. +        $_return = false;
  2692. +        $_params = array('resource_name' => $params['resource_name']) ;
  2693. +        if (isset($params['resource_base_path']))
  2694. +            $_params['resource_base_path'] = $params['resource_base_path'];
  2695. +        else
  2696. +            $_params['resource_base_path'] = $this->template_dir;
  2697. +
  2698. +        if ($this->_parse_resource_name($_params)) {
  2699. +            $_resource_type = $_params['resource_type'];
  2700. +            $_resource_name = $_params['resource_name'];
  2701. +            switch ($_resource_type) {
  2702. +                case 'file':
  2703. +                    if ($params['get_source']) {
  2704. +                        $params['source_content'] = $this->_read_file($_resource_name);
  2705. +                    }
  2706. +                    $params['resource_timestamp'] = filemtime($_resource_name);
  2707. +                    $_return = is_file($_resource_name) && is_readable($_resource_name);
  2708. +                    break;
  2709. +
  2710. +                default:
  2711. +                    // call resource functions to fetch the template source and timestamp
  2712. +                    if ($params['get_source']) {
  2713. +                        $_source_return = isset($this->_plugins['resource'][$_resource_type]) &&
  2714. +                            call_user_func_array($this->_plugins['resource'][$_resource_type][0][0],
  2715. +                                                 array($_resource_name, &$params['source_content'], &$this));
  2716. +                    } else {
  2717. +                        $_source_return = true;
  2718. +                    }
  2719. +
  2720. +                    $_timestamp_return = isset($this->_plugins['resource'][$_resource_type]) &&
  2721. +                        call_user_func_array($this->_plugins['resource'][$_resource_type][0][1],
  2722. +                                             array($_resource_name, &$params['resource_timestamp'], &$this));
  2723. +
  2724. +                    $_return = $_source_return && $_timestamp_return;
  2725. +                    break;
  2726. +            }
  2727. +        }
  2728. +
  2729. +        if (!$_return) {
  2730. +            // see if we can get a template with the default template handler
  2731. +            if (!empty($this->default_template_handler_func)) {
  2732. +                if (!is_callable($this->default_template_handler_func)) {
  2733. +                    $this->trigger_error("default template handler function \"$this->default_template_handler_func\" doesn't exist.");
  2734. +                } else {
  2735. +                    $_return = call_user_func_array(
  2736. +                        $this->default_template_handler_func,
  2737. +                        array($_params['resource_type'], $_params['resource_name'], &$params['source_content'], &$params['resource_timestamp'], &$this));
  2738. +                }
  2739. +            }
  2740. +        }
  2741. +
  2742. +        if (!$_return) {
  2743. +            if (!$params['quiet']) {
  2744. +                $this->trigger_error('unable to read resource: "' . $params['resource_name'] . '"');
  2745. +            }
  2746. +        } else if ($_return && $this->security) {
  2747. +            require_once(SMARTY_CORE_DIR . 'core.is_secure.php');
  2748. +            if (!smarty_core_is_secure($_params, $this)) {
  2749. +                if (!$params['quiet'])
  2750. +                    $this->trigger_error('(secure mode) accessing "' . $params['resource_name'] . '" is not allowed');
  2751. +                $params['source_content'] = null;
  2752. +                $params['resource_timestamp'] = null;
  2753. +                return false;
  2754. +            }
  2755. +        }
  2756. +        return $_return;
  2757. +    }
  2758. +
  2759. +
  2760. +    /**
  2761. +     * parse out the type and name from the resource
  2762. +     *
  2763. +     * @param string $resource_base_path
  2764. +     * @param string $resource_name
  2765. +     * @param string $resource_type
  2766. +     * @param string $resource_name
  2767. +     * @return boolean
  2768. +     */
  2769. +
  2770. +    function _parse_resource_name(&$params)
  2771. +    {
  2772. +
  2773. +        // split tpl_path by the first colon
  2774. +        $_resource_name_parts = explode(':', $params['resource_name'], 2);
  2775. +
  2776. +        if (count($_resource_name_parts) == 1) {
  2777. +            // no resource type given
  2778. +            $params['resource_type'] = $this->default_resource_type;
  2779. +            $params['resource_name'] = $_resource_name_parts[0];
  2780. +        } else {
  2781. +            if(strlen($_resource_name_parts[0]) == 1) {
  2782. +                // 1 char is not resource type, but part of filepath
  2783. +                $params['resource_type'] = $this->default_resource_type;
  2784. +                $params['resource_name'] = $params['resource_name'];
  2785. +            } else {
  2786. +                $params['resource_type'] = $_resource_name_parts[0];
  2787. +                $params['resource_name'] = $_resource_name_parts[1];
  2788. +            }
  2789. +        }
  2790. +
  2791. +        if ($params['resource_type'] == 'file') {
  2792. +            if (!preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $params['resource_name'])) {
  2793. +                // relative pathname to $params['resource_base_path']
  2794. +                // use the first directory where the file is found
  2795. +                foreach ((array)$params['resource_base_path'] as $_curr_path) {
  2796. +                    $_fullpath = $_curr_path . DIRECTORY_SEPARATOR . $params['resource_name'];
  2797. +                    if (file_exists($_fullpath) && is_file($_fullpath)) {
  2798. +                        $params['resource_name'] = $_fullpath;
  2799. +                        return true;
  2800. +                    }
  2801. +                    // didn't find the file, try include_path
  2802. +                    $_params = array('file_path' => $_fullpath);
  2803. +                    require_once(SMARTY_CORE_DIR . 'core.get_include_path.php');
  2804. +                    if(smarty_core_get_include_path($_params, $this)) {
  2805. +                        $params['resource_name'] = $_params['new_file_path'];
  2806. +                        return true;
  2807. +                    }
  2808. +                }
  2809. +                return false;
  2810. +            } else {
  2811. +                /* absolute path */
  2812. +                return file_exists($params['resource_name']);
  2813. +            }
  2814. +        } elseif (empty($this->_plugins['resource'][$params['resource_type']])) {
  2815. +            $_params = array('type' => $params['resource_type']);
  2816. +            require_once(SMARTY_CORE_DIR . 'core.load_resource_plugin.php');
  2817. +            smarty_core_load_resource_plugin($_params, $this);
  2818. +        }
  2819. +
  2820. +        return true;
  2821. +    }
  2822. +
  2823. +
  2824. +    /**
  2825. +     * Handle modifiers
  2826. +     *
  2827. +     * @param string|null $modifier_name
  2828. +     * @param array|null $map_array
  2829. +     * @return string result of modifiers
  2830. +     */
  2831. +    function _run_mod_handler()
  2832. +    {
  2833. +        $_args = func_get_args();
  2834. +        list($_modifier_name, $_map_array) = array_splice($_args, 0, 2);
  2835. +        list($_func_name, $_tpl_file, $_tpl_line) =
  2836. +            $this->_plugins['modifier'][$_modifier_name];
  2837. +
  2838. +        $_var = $_args[0];
  2839. +        foreach ($_var as $_key => $_val) {
  2840. +            $_args[0] = $_val;
  2841. +            $_var[$_key] = call_user_func_array($_func_name, $_args);
  2842. +        }
  2843. +        return $_var;
  2844. +    }
  2845. +
  2846. +    /**
  2847. +     * Remove starting and ending quotes from the string
  2848. +     *
  2849. +     * @param string $string
  2850. +     * @return string
  2851. +     */
  2852. +    function _dequote($string)
  2853. +    {
  2854. +        if ((substr($string, 0, 1) == "'" || substr($string, 0, 1) == '"') &&
  2855. +            substr($string, -1) == substr($string, 0, 1))
  2856. +            return substr($string, 1, -1);
  2857. +        else
  2858. +            return $string;
  2859. +    }
  2860. +
  2861. +
  2862. +    /**
  2863. +     * read in a file
  2864. +     *
  2865. +     * @param string $filename
  2866. +     * @return string
  2867. +     */
  2868. +    function _read_file($filename)
  2869. +    {
  2870. +        if ( file_exists($filename) && is_readable($filename) && ($fd = @fopen($filename, 'rb')) ) {
  2871. +            $contents = '';
  2872. +            while (!feof($fd)) {
  2873. +                $contents .= fread($fd, 8192);
  2874. +            }
  2875. +            fclose($fd);
  2876. +            return $contents;
  2877. +        } else {
  2878. +            return false;
  2879. +        }
  2880. +    }
  2881. +
  2882. +    /**
  2883. +     * get a concrete filename for automagically created content
  2884. +     *
  2885. +     * @param string $auto_base
  2886. +     * @param string $auto_source
  2887. +     * @param string $auto_id
  2888. +     * @return string
  2889. +     * @staticvar string|null
  2890. +     * @staticvar string|null
  2891. +     */
  2892. +    function _get_auto_filename($auto_base, $auto_source = null, $auto_id = null)
  2893. +    {
  2894. +        $_compile_dir_sep =  $this->use_sub_dirs ? DIRECTORY_SEPARATOR : '^';
  2895. +        $_return = $auto_base . DIRECTORY_SEPARATOR;
  2896. +
  2897. +        if(isset($auto_id)) {
  2898. +            // make auto_id safe for directory names
  2899. +            $auto_id = str_replace('%7C',$_compile_dir_sep,(urlencode($auto_id)));
  2900. +            // split into separate directories
  2901. +            $_return .= $auto_id . $_compile_dir_sep;
  2902. +        }
  2903. +
  2904. +        if(isset($auto_source)) {
  2905. +            // make source name safe for filename
  2906. +            $_filename = urlencode(basename($auto_source));
  2907. +            $_crc32 = sprintf('%08X', crc32($auto_source));
  2908. +            // prepend %% to avoid name conflicts with
  2909. +            // with $params['auto_id'] names
  2910. +            $_crc32 = substr($_crc32, 0, 2) . $_compile_dir_sep .
  2911. +                      substr($_crc32, 0, 3) . $_compile_dir_sep . $_crc32;
  2912. +            $_return .= '%%' . $_crc32 . '%%' . $_filename;
  2913. +        }
  2914. +
  2915. +        return $_return;
  2916. +    }
  2917. +
  2918. +    /**
  2919. +     * unlink a file, possibly using expiration time
  2920. +     *
  2921. +     * @param string $resource
  2922. +     * @param integer $exp_time
  2923. +     */
  2924. +    function _unlink($resource, $exp_time = null)
  2925. +    {
  2926. +        if(isset($exp_time)) {
  2927. +            if(time() - @filemtime($resource) >= $exp_time) {
  2928. +                return @unlink($resource);
  2929. +            }
  2930. +        } else {
  2931. +            return @unlink($resource);
  2932. +        }
  2933. +    }
  2934. +
  2935. +    /**
  2936. +     * returns an auto_id for auto-file-functions
  2937. +     *
  2938. +     * @param string $cache_id
  2939. +     * @param string $compile_id
  2940. +     * @return string|null
  2941. +     */
  2942. +    function _get_auto_id($cache_id=null, $compile_id=null) {
  2943. +    if (isset($cache_id))
  2944. +        return (isset($compile_id)) ? $cache_id . '|' . $compile_id  : $cache_id;
  2945. +    elseif(isset($compile_id))
  2946. +        return $compile_id;
  2947. +    else
  2948. +        return null;
  2949. +    }
  2950. +
  2951. +    /**
  2952. +     * trigger Smarty plugin error
  2953. +     *
  2954. +     * @param string $error_msg
  2955. +     * @param string $tpl_file
  2956. +     * @param integer $tpl_line
  2957. +     * @param string $file
  2958. +     * @param integer $line
  2959. +     * @param integer $error_type
  2960. +     */
  2961. +    function _trigger_fatal_error($error_msg, $tpl_file = null, $tpl_line = null,
  2962. +            $file = null, $line = null, $error_type = E_USER_ERROR)
  2963. +    {
  2964. +        if(isset($file) && isset($line)) {
  2965. +            $info = ' ('.basename($file).", line $line)";
  2966. +        } else {
  2967. +            $info = '';
  2968. +        }
  2969. +        if (isset($tpl_line) && isset($tpl_file)) {
  2970. +            $this->trigger_error('[in ' . $tpl_file . ' line ' . $tpl_line . "]: $error_msg$info", $error_type);
  2971. +        } else {
  2972. +            $this->trigger_error($error_msg . $info, $error_type);
  2973. +        }
  2974. +    }
  2975. +
  2976. +
  2977. +    /**
  2978. +     * callback function for preg_replace, to call a non-cacheable block
  2979. +     * @return string
  2980. +     */
  2981. +    function _process_compiled_include_callback($match) {
  2982. +        $_func = '_smarty_tplfunc_'.$match[2].'_'.$match[3];
  2983. +        ob_start();
  2984. +        $_func($this);
  2985. +        $_ret = ob_get_contents();
  2986. +        ob_end_clean();
  2987. +        return $_ret;
  2988. +    }
  2989. +
  2990. +
  2991. +    /**
  2992. +     * called for included templates
  2993. +     *
  2994. +     * @param string $_smarty_include_tpl_file
  2995. +     * @param string $_smarty_include_vars
  2996. +     */
  2997. +
  2998. +    // $_smarty_include_tpl_file, $_smarty_include_vars
  2999. +
  3000. +    function _smarty_include($params)
  3001. +    {
  3002. +        if ($this->debugging) {
  3003. +            $_params = array();
  3004. +            require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
  3005. +            $debug_start_time = smarty_core_get_microtime($_params, $this);
  3006. +            $this->_smarty_debug_info[] = array('type'      => 'template',
  3007. +                                                  'filename'  => $params['smarty_include_tpl_file'],
  3008. +                                                  'depth'     => ++$this->_inclusion_depth);
  3009. +            $included_tpls_idx = count($this->_smarty_debug_info) - 1;
  3010. +        }
  3011. +
  3012. +        $this->_tpl_vars = array_merge($this->_tpl_vars, $params['smarty_include_vars']);
  3013. +
  3014. +        // config vars are treated as local, so push a copy of the
  3015. +        // current ones onto the front of the stack
  3016. +        array_unshift($this->_config, $this->_config[0]);
  3017. +
  3018. +        $_smarty_compile_path = $this->_get_compile_path($params['smarty_include_tpl_file']);
  3019. +
  3020. +
  3021. +        if ($this->_is_compiled($params['smarty_include_tpl_file'], $_smarty_compile_path)
  3022. +            || $this->_compile_resource($params['smarty_include_tpl_file'], $_smarty_compile_path))
  3023. +        {
  3024. +            include($_smarty_compile_path);
  3025. +        }
  3026. +
  3027. +        // pop the local vars off the front of the stack
  3028. +        array_shift($this->_config);
  3029. +
  3030. +        $this->_inclusion_depth--;
  3031. +
  3032. +        if ($this->debugging) {
  3033. +            // capture time for debugging info
  3034. +            $_params = array();
  3035. +            require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
  3036. +            $this->_smarty_debug_info[$included_tpls_idx]['exec_time'] = smarty_core_get_microtime($_params, $this) - $debug_start_time;
  3037. +        }
  3038. +
  3039. +        if ($this->caching) {
  3040. +            $this->_cache_info['template'][$params['smarty_include_tpl_file']] = true;
  3041. +        }
  3042. +    }
  3043. +
  3044. +
  3045. +    /**
  3046. +     * get or set an array of cached attributes for function that is
  3047. +     * not cacheable
  3048. +     * @return array
  3049. +     */
  3050. +    function &_smarty_cache_attrs($cache_serial, $count) {
  3051. +        $_cache_attrs =& $this->_cache_info['cache_attrs'][$cache_serial][$count];
  3052. +
  3053. +        if ($this->_cache_including) {
  3054. +            /* return next set of cache_attrs */
  3055. +            $_return = current($_cache_attrs);
  3056. +            next($_cache_attrs);
  3057. +            return $_return;
  3058. +
  3059. +        } else {
  3060. +            /* add a reference to a new set of cache_attrs */
  3061. +            $_cache_attrs[] = array();
  3062. +            return $_cache_attrs[count($_cache_attrs)-1];
  3063. +
  3064. +        }
  3065. +
  3066. +    }
  3067. +
  3068. +
  3069. +    /**
  3070. +     * wrapper for include() retaining $this
  3071. +     * @return mixed
  3072. +     */
  3073. +    function _include($filename, $once=false, $params=null)
  3074. +    {
  3075. +        if ($once) {
  3076. +            return include_once($filename);
  3077. +        } else {
  3078. +            return include($filename);
  3079. +        }
  3080. +    }
  3081. +
  3082. +
  3083. +    /**
  3084. +     * wrapper for eval() retaining $this
  3085. +     * @return mixed
  3086. +     */
  3087. +    function _eval($code, $params=null)
  3088. +    {
  3089. +        return eval($code);
  3090. +    }
  3091. +    
  3092. +    /**
  3093. +     * Extracts the filter name from the given callback
  3094. +     *
  3095. +     * @param callback $function
  3096. +     * @return string
  3097. +     */
  3098. +   function _get_filter_name($function)
  3099. +   {
  3100. +       if (is_array($function)) {
  3101. +           $_class_name = (is_object($function[0]) ?
  3102. +               get_class($function[0]) : $function[0]);
  3103. +           return $_class_name . '_' . $function[1];
  3104. +       }
  3105. +       else {
  3106. +           return $function;
  3107. +       }
  3108. +   }
  3109. +  
  3110. +    /**#@-*/
  3111. +
  3112. +}
  3113. +
  3114. +/* vim: set expandtab: */
  3115. +
  3116. +?>
  3117. diff --git a/library/smarty/Smarty_Compiler.class.php b/library/smarty/Smarty_Compiler.class.php
  3118. new file mode 100644
  3119. --- /dev/null
  3120. +++ b/library/smarty/Smarty_Compiler.class.php
  3121. @@ -0,0 +1,2365 @@
  3122. +<?php
  3123. +
  3124. +/**
  3125. + * Project:     Smarty: the PHP compiling template engine
  3126. + * File:        Smarty_Compiler.class.php
  3127. + *
  3128. + * This library is free software; you can redistribute it and/or
  3129. + * modify it under the terms of the GNU Lesser General Public
  3130. + * License as published by the Free Software Foundation; either
  3131. + * version 2.1 of the License, or (at your option) any later version.
  3132. + *
  3133. + * This library is distributed in the hope that it will be useful,
  3134. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  3135. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  3136. + * Lesser General Public License for more details.
  3137. + *
  3138. + * You should have received a copy of the GNU Lesser General Public
  3139. + * License along with this library; if not, write to the Free Software
  3140. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  3141. + *
  3142. + * @link http://smarty.php.net/
  3143. + * @author Monte Ohrt <monte at ohrt dot com>
  3144. + * @author Andrei Zmievski <andrei@php.net>
  3145. + * @version 2.6.26
  3146. + * @copyright 2001-2005 New Digital Group, Inc.
  3147. + * @package Smarty
  3148. + */
  3149. +
  3150. +/* $Id: Smarty_Compiler.class.php 3163 2009-06-17 14:39:24Z monte.ohrt $ */
  3151. +
  3152. +/**
  3153. + * Template compiling class
  3154. + * @package Smarty
  3155. + */
  3156. +class Smarty_Compiler extends Smarty {
  3157. +
  3158. +    // internal vars
  3159. +    /**#@+
  3160. +     * @access private
  3161. +     */
  3162. +    var $_folded_blocks         =   array();    // keeps folded template blocks
  3163. +    var $_current_file          =   null;       // the current template being compiled
  3164. +    var $_current_line_no       =   1;          // line number for error messages
  3165. +    var $_capture_stack         =   array();    // keeps track of nested capture buffers
  3166. +    var $_plugin_info           =   array();    // keeps track of plugins to load
  3167. +    var $_init_smarty_vars      =   false;
  3168. +    var $_permitted_tokens      =   array('true','false','yes','no','on','off','null');
  3169. +    var $_db_qstr_regexp        =   null;        // regexps are setup in the constructor
  3170. +    var $_si_qstr_regexp        =   null;
  3171. +    var $_qstr_regexp           =   null;
  3172. +    var $_func_regexp           =   null;
  3173. +    var $_reg_obj_regexp        =   null;
  3174. +    var $_var_bracket_regexp    =   null;
  3175. +    var $_num_const_regexp      =   null;
  3176. +    var $_dvar_guts_regexp      =   null;
  3177. +    var $_dvar_regexp           =   null;
  3178. +    var $_cvar_regexp           =   null;
  3179. +    var $_svar_regexp           =   null;
  3180. +    var $_avar_regexp           =   null;
  3181. +    var $_mod_regexp            =   null;
  3182. +    var $_var_regexp            =   null;
  3183. +    var $_parenth_param_regexp  =   null;
  3184. +    var $_func_call_regexp      =   null;
  3185. +    var $_obj_ext_regexp        =   null;
  3186. +    var $_obj_start_regexp      =   null;
  3187. +    var $_obj_params_regexp     =   null;
  3188. +    var $_obj_call_regexp       =   null;
  3189. +    var $_cacheable_state       =   0;
  3190. +    var $_cache_attrs_count     =   0;
  3191. +    var $_nocache_count         =   0;
  3192. +    var $_cache_serial          =   null;
  3193. +    var $_cache_include         =   null;
  3194. +
  3195. +    var $_strip_depth           =   0;
  3196. +    var $_additional_newline    =   "\n";
  3197. +
  3198. +    /**#@-*/
  3199. +    /**
  3200. +     * The class constructor.
  3201. +     */
  3202. +    function Smarty_Compiler()
  3203. +    {
  3204. +        // matches double quoted strings:
  3205. +        // "foobar"
  3206. +        // "foo\"bar"
  3207. +        $this->_db_qstr_regexp = '"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"';
  3208. +
  3209. +        // matches single quoted strings:
  3210. +        // 'foobar'
  3211. +        // 'foo\'bar'
  3212. +        $this->_si_qstr_regexp = '\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\'';
  3213. +
  3214. +        // matches single or double quoted strings
  3215. +        $this->_qstr_regexp = '(?:' . $this->_db_qstr_regexp . '|' . $this->_si_qstr_regexp . ')';
  3216. +
  3217. +        // matches bracket portion of vars
  3218. +        // [0]
  3219. +        // [foo]
  3220. +        // [$bar]
  3221. +        $this->_var_bracket_regexp = '\[\$?[\w\.]+\]';
  3222. +
  3223. +        // matches numerical constants
  3224. +        // 30
  3225. +        // -12
  3226. +        // 13.22
  3227. +        $this->_num_const_regexp = '(?:\-?\d+(?:\.\d+)?)';
  3228. +
  3229. +        // matches $ vars (not objects):
  3230. +        // $foo
  3231. +        // $foo.bar
  3232. +        // $foo.bar.foobar
  3233. +        // $foo[0]
  3234. +        // $foo[$bar]
  3235. +        // $foo[5][blah]
  3236. +        // $foo[5].bar[$foobar][4]
  3237. +        $this->_dvar_math_regexp = '(?:[\+\*\/\%]|(?:-(?!>)))';
  3238. +        $this->_dvar_math_var_regexp = '[\$\w\.\+\-\*\/\%\d\>\[\]]';
  3239. +        $this->_dvar_guts_regexp = '\w+(?:' . $this->_var_bracket_regexp
  3240. +                . ')*(?:\.\$?\w+(?:' . $this->_var_bracket_regexp . ')*)*(?:' . $this->_dvar_math_regexp . '(?:' . $this->_num_const_regexp . '|' . $this->_dvar_math_var_regexp . ')*)?';
  3241. +        $this->_dvar_regexp = '\$' . $this->_dvar_guts_regexp;
  3242. +
  3243. +        // matches config vars:
  3244. +        // #foo#
  3245. +        // #foobar123_foo#
  3246. +        $this->_cvar_regexp = '\#\w+\#';
  3247. +
  3248. +        // matches section vars:
  3249. +        // %foo.bar%
  3250. +        $this->_svar_regexp = '\%\w+\.\w+\%';
  3251. +
  3252. +        // matches all valid variables (no quotes, no modifiers)
  3253. +        $this->_avar_regexp = '(?:' . $this->_dvar_regexp . '|'
  3254. +           . $this->_cvar_regexp . '|' . $this->_svar_regexp . ')';
  3255. +
  3256. +        // matches valid variable syntax:
  3257. +        // $foo
  3258. +        // $foo
  3259. +        // #foo#
  3260. +        // #foo#
  3261. +        // "text"
  3262. +        // "text"
  3263. +        $this->_var_regexp = '(?:' . $this->_avar_regexp . '|' . $this->_qstr_regexp . ')';
  3264. +
  3265. +        // matches valid object call (one level of object nesting allowed in parameters):
  3266. +        // $foo->bar
  3267. +        // $foo->bar()
  3268. +        // $foo->bar("text")
  3269. +        // $foo->bar($foo, $bar, "text")
  3270. +        // $foo->bar($foo, "foo")
  3271. +        // $foo->bar->foo()
  3272. +        // $foo->bar->foo->bar()
  3273. +        // $foo->bar($foo->bar)
  3274. +        // $foo->bar($foo->bar())
  3275. +        // $foo->bar($foo->bar($blah,$foo,44,"foo",$foo[0].bar))
  3276. +        $this->_obj_ext_regexp = '\->(?:\$?' . $this->_dvar_guts_regexp . ')';
  3277. +        $this->_obj_restricted_param_regexp = '(?:'
  3278. +                . '(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . ')(?:' . $this->_obj_ext_regexp . '(?:\((?:(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . ')'
  3279. +                . '(?:\s*,\s*(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . '))*)?\))?)*)';
  3280. +        $this->_obj_single_param_regexp = '(?:\w+|' . $this->_obj_restricted_param_regexp . '(?:\s*,\s*(?:(?:\w+|'
  3281. +                . $this->_var_regexp . $this->_obj_restricted_param_regexp . ')))*)';
  3282. +        $this->_obj_params_regexp = '\((?:' . $this->_obj_single_param_regexp
  3283. +                . '(?:\s*,\s*' . $this->_obj_single_param_regexp . ')*)?\)';
  3284. +        $this->_obj_start_regexp = '(?:' . $this->_dvar_regexp . '(?:' . $this->_obj_ext_regexp . ')+)';
  3285. +        $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 . ')*)?)';
  3286. +        
  3287. +        // matches valid modifier syntax:
  3288. +        // |foo
  3289. +        // |@foo
  3290. +        // |foo:"bar"
  3291. +        // |foo:$bar
  3292. +        // |foo:"bar":$foobar
  3293. +        // |foo|bar
  3294. +        // |foo:$foo->bar
  3295. +        $this->_mod_regexp = '(?:\|@?\w+(?::(?:\w+|' . $this->_num_const_regexp . '|'
  3296. +           . $this->_obj_call_regexp . '|' . $this->_avar_regexp . '|' . $this->_qstr_regexp .'))*)';
  3297. +
  3298. +        // matches valid function name:
  3299. +        // foo123
  3300. +        // _foo_bar
  3301. +        $this->_func_regexp = '[a-zA-Z_]\w*';
  3302. +
  3303. +        // matches valid registered object:
  3304. +        // foo->bar
  3305. +        $this->_reg_obj_regexp = '[a-zA-Z_]\w*->[a-zA-Z_]\w*';
  3306. +
  3307. +        // matches valid parameter values:
  3308. +        // true
  3309. +        // $foo
  3310. +        // $foo|bar
  3311. +        // #foo#
  3312. +        // #foo#|bar
  3313. +        // "text"
  3314. +        // "text"|bar
  3315. +        // $foo->bar
  3316. +        $this->_param_regexp = '(?:\s*(?:' . $this->_obj_call_regexp . '|'
  3317. +           . $this->_var_regexp . '|' . $this->_num_const_regexp  . '|\w+)(?>' . $this->_mod_regexp . '*)\s*)';
  3318. +
  3319. +        // matches valid parenthesised function parameters:
  3320. +        //
  3321. +        // "text"
  3322. +        //    $foo, $bar, "text"
  3323. +        // $foo|bar, "foo"|bar, $foo->bar($foo)|bar
  3324. +        $this->_parenth_param_regexp = '(?:\((?:\w+|'
  3325. +                . $this->_param_regexp . '(?:\s*,\s*(?:(?:\w+|'
  3326. +                . $this->_param_regexp . ')))*)?\))';
  3327. +
  3328. +        // matches valid function call:
  3329. +        // foo()
  3330. +        // foo_bar($foo)
  3331. +        // _foo_bar($foo,"bar")
  3332. +        // foo123($foo,$foo->bar(),"foo")
  3333. +        $this->_func_call_regexp = '(?:' . $this->_func_regexp . '\s*(?:'
  3334. +           . $this->_parenth_param_regexp . '))';
  3335. +    }
  3336. +
  3337. +    /**
  3338. +     * compile a resource
  3339. +     *
  3340. +     * sets $compiled_content to the compiled source
  3341. +     * @param string $resource_name
  3342. +     * @param string $source_content
  3343. +     * @param string $compiled_content
  3344. +     * @return true
  3345. +     */
  3346. +    function _compile_file($resource_name, $source_content, &$compiled_content)
  3347. +    {
  3348. +
  3349. +        if ($this->security) {
  3350. +            // do not allow php syntax to be executed unless specified
  3351. +            if ($this->php_handling == SMARTY_PHP_ALLOW &&
  3352. +                !$this->security_settings['PHP_HANDLING']) {
  3353. +                $this->php_handling = SMARTY_PHP_PASSTHRU;
  3354. +            }
  3355. +        }
  3356. +
  3357. +        $this->_load_filters();
  3358. +
  3359. +        $this->_current_file = $resource_name;
  3360. +        $this->_current_line_no = 1;
  3361. +        $ldq = preg_quote($this->left_delimiter, '~');
  3362. +        $rdq = preg_quote($this->right_delimiter, '~');
  3363. +
  3364. +        // run template source through prefilter functions
  3365. +        if (count($this->_plugins['prefilter']) > 0) {
  3366. +            foreach ($this->_plugins['prefilter'] as $filter_name => $prefilter) {
  3367. +                if ($prefilter === false) continue;
  3368. +                if ($prefilter[3] || is_callable($prefilter[0])) {
  3369. +                    $source_content = call_user_func_array($prefilter[0],
  3370. +                                                            array($source_content, &$this));
  3371. +                    $this->_plugins['prefilter'][$filter_name][3] = true;
  3372. +                } else {
  3373. +                    $this->_trigger_fatal_error("[plugin] prefilter '$filter_name' is not implemented");
  3374. +                }
  3375. +            }
  3376. +        }
  3377. +
  3378. +        /* fetch all special blocks */
  3379. +        $search = "~{$ldq}\*(.*?)\*{$rdq}|{$ldq}\s*literal\s*{$rdq}(.*?){$ldq}\s*/literal\s*{$rdq}|{$ldq}\s*php\s*{$rdq}(.*?){$ldq}\s*/php\s*{$rdq}~s";
  3380. +
  3381. +        preg_match_all($search, $source_content, $match,  PREG_SET_ORDER);
  3382. +        $this->_folded_blocks = $match;
  3383. +        reset($this->_folded_blocks);
  3384. +
  3385. +        /* replace special blocks by "{php}" */
  3386. +        $source_content = preg_replace($search.'e', "'"
  3387. +                                       . $this->_quote_replace($this->left_delimiter) . 'php'
  3388. +                                       . "' . str_repeat(\"\n\", substr_count('\\0', \"\n\")) .'"
  3389. +                                       . $this->_quote_replace($this->right_delimiter)
  3390. +                                       . "'"
  3391. +                                       , $source_content);
  3392. +
  3393. +        /* Gather all template tags. */
  3394. +        preg_match_all("~{$ldq}\s*(.*?)\s*{$rdq}~s", $source_content, $_match);
  3395. +        $template_tags = $_match[1];
  3396. +        /* Split content by template tags to obtain non-template content. */
  3397. +        $text_blocks = preg_split("~{$ldq}.*?{$rdq}~s", $source_content);
  3398. +
  3399. +        /* loop through text blocks */
  3400. +        for ($curr_tb = 0, $for_max = count($text_blocks); $curr_tb < $for_max; $curr_tb++) {
  3401. +            /* match anything resembling php tags */
  3402. +            if (preg_match_all('~(<\?(?:\w+|=)?|\?>|language\s*=\s*[\"\']?\s*php\s*[\"\']?)~is', $text_blocks[$curr_tb], $sp_match)) {
  3403. +                /* replace tags with placeholders to prevent recursive replacements */
  3404. +                $sp_match[1] = array_unique($sp_match[1]);
  3405. +                usort($sp_match[1], '_smarty_sort_length');
  3406. +                for ($curr_sp = 0, $for_max2 = count($sp_match[1]); $curr_sp < $for_max2; $curr_sp++) {
  3407. +                    $text_blocks[$curr_tb] = str_replace($sp_match[1][$curr_sp],'%%%SMARTYSP'.$curr_sp.'%%%',$text_blocks[$curr_tb]);
  3408. +                }
  3409. +                /* process each one */
  3410. +                for ($curr_sp = 0, $for_max2 = count($sp_match[1]); $curr_sp < $for_max2; $curr_sp++) {
  3411. +                    if ($this->php_handling == SMARTY_PHP_PASSTHRU) {
  3412. +                        /* echo php contents */
  3413. +                        $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', '<?php echo \''.str_replace("'", "\'", $sp_match[1][$curr_sp]).'\'; ?>'."\n", $text_blocks[$curr_tb]);
  3414. +                    } else if ($this->php_handling == SMARTY_PHP_QUOTE) {
  3415. +                        /* quote php tags */
  3416. +                        $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', htmlspecialchars($sp_match[1][$curr_sp]), $text_blocks[$curr_tb]);
  3417. +                    } else if ($this->php_handling == SMARTY_PHP_REMOVE) {
  3418. +                        /* remove php tags */
  3419. +                        $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', '', $text_blocks[$curr_tb]);
  3420. +                    } else {
  3421. +                        /* SMARTY_PHP_ALLOW, but echo non php starting tags */
  3422. +                        $sp_match[1][$curr_sp] = preg_replace('~(<\?(?!php|=|$))~i', '<?php echo \'\\'?>'."\n", $sp_match[1][$curr_sp]);
  3423. +                        $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', $sp_match[1][$curr_sp], $text_blocks[$curr_tb]);
  3424. +                    }
  3425. +                }
  3426. +            }
  3427. +        }
  3428. +        
  3429. +        /* Compile the template tags into PHP code. */
  3430. +        $compiled_tags = array();
  3431. +        for ($i = 0, $for_max = count($template_tags); $i < $for_max; $i++) {
  3432. +            $this->_current_line_no += substr_count($text_blocks[$i], "\n");
  3433. +            $compiled_tags[] = $this->_compile_tag($template_tags[$i]);
  3434. +            $this->_current_line_no += substr_count($template_tags[$i], "\n");
  3435. +        }
  3436. +        if (count($this->_tag_stack)>0) {
  3437. +            list($_open_tag, $_line_no) = end($this->_tag_stack);
  3438. +            $this->_syntax_error("unclosed tag \{$_open_tag} (opened line $_line_no).", E_USER_ERROR, __FILE__, __LINE__);
  3439. +            return;
  3440. +        }
  3441. +
  3442. +        /* Reformat $text_blocks between 'strip' and '/strip' tags,
  3443. +           removing spaces, tabs and newlines. */
  3444. +        $strip = false;
  3445. +        for ($i = 0, $for_max = count($compiled_tags); $i < $for_max; $i++) {
  3446. +            if ($compiled_tags[$i] == '{strip}') {
  3447. +                $compiled_tags[$i] = '';
  3448. +                $strip = true;
  3449. +                /* remove leading whitespaces */
  3450. +                $text_blocks[$i + 1] = ltrim($text_blocks[$i + 1]);
  3451. +            }
  3452. +            if ($strip) {
  3453. +                /* strip all $text_blocks before the next '/strip' */
  3454. +                for ($j = $i + 1; $j < $for_max; $j++) {
  3455. +                    /* remove leading and trailing whitespaces of each line */
  3456. +                    $text_blocks[$j] = preg_replace('![\t ]*[\r\n]+[\t ]*!', '', $text_blocks[$j]);
  3457. +                    if ($compiled_tags[$j] == '{/strip}') {                      
  3458. +                        /* remove trailing whitespaces from the last text_block */
  3459. +                        $text_blocks[$j] = rtrim($text_blocks[$j]);
  3460. +                    }
  3461. +                    $text_blocks[$j] = "<?php echo '" . strtr($text_blocks[$j], array("'"=>"\'", "\\"=>"\\\\")) . "'; ?>";
  3462. +                    if ($compiled_tags[$j] == '{/strip}') {
  3463. +                        $compiled_tags[$j] = "\n"; /* slurped by php, but necessary
  3464. +                                    if a newline is following the closing strip-tag */
  3465. +                        $strip = false;
  3466. +                        $i = $j;
  3467. +                        break;
  3468. +                    }
  3469. +                }
  3470. +            }
  3471. +        }
  3472. +        $compiled_content = '';
  3473. +        
  3474. +        $tag_guard = '%%%SMARTYOTG' . md5(uniqid(rand(), true)) . '%%%';
  3475. +        
  3476. +        /* Interleave the compiled contents and text blocks to get the final result. */
  3477. +        for ($i = 0, $for_max = count($compiled_tags); $i < $for_max; $i++) {
  3478. +            if ($compiled_tags[$i] == '') {
  3479. +                // tag result empty, remove first newline from following text block
  3480. +                $text_blocks[$i+1] = preg_replace('~^(\r\n|\r|\n)~', '', $text_blocks[$i+1]);
  3481. +            }
  3482. +            // replace legit PHP tags with placeholder
  3483. +            $text_blocks[$i] = str_replace('<?', $tag_guard, $text_blocks[$i]);
  3484. +            $compiled_tags[$i] = str_replace('<?', $tag_guard, $compiled_tags[$i]);
  3485. +            
  3486. +            $compiled_content .= $text_blocks[$i] . $compiled_tags[$i];
  3487. +        }
  3488. +        $compiled_content .= str_replace('<?', $tag_guard, $text_blocks[$i]);
  3489. +
  3490. +        // escape php tags created by interleaving
  3491. +        $compiled_content = str_replace('<?', "<?php echo '<?' ?>\n", $compiled_content);
  3492. +        $compiled_content = preg_replace("~(?<!')language\s*=\s*[\"\']?\s*php\s*[\"\']?~", "<?php echo 'language=php' ?>\n", $compiled_content);
  3493. +
  3494. +        // recover legit tags
  3495. +        $compiled_content = str_replace($tag_guard, '<?', $compiled_content);
  3496. +        
  3497. +        // remove \n from the end of the file, if any
  3498. +        if (strlen($compiled_content) && (substr($compiled_content, -1) == "\n") ) {
  3499. +            $compiled_content = substr($compiled_content, 0, -1);
  3500. +        }
  3501. +
  3502. +        if (!empty($this->_cache_serial)) {
  3503. +            $compiled_content = "<?php \$this->_cache_serials['".$this->_cache_include."'] = '".$this->_cache_serial."'; ?>" . $compiled_content;
  3504. +        }
  3505. +
  3506. +        // run compiled template through postfilter functions
  3507. +        if (count($this->_plugins['postfilter']) > 0) {
  3508. +            foreach ($this->_plugins['postfilter'] as $filter_name => $postfilter) {
  3509. +                if ($postfilter === false) continue;
  3510. +                if ($postfilter[3] || is_callable($postfilter[0])) {
  3511. +                    $compiled_content = call_user_func_array($postfilter[0],
  3512. +                                                              array($compiled_content, &$this));
  3513. +                    $this->_plugins['postfilter'][$filter_name][3] = true;
  3514. +                } else {
  3515. +                    $this->_trigger_fatal_error("Smarty plugin error: postfilter '$filter_name' is not implemented");
  3516. +                }
  3517. +            }
  3518. +        }
  3519. +
  3520. +        // put header at the top of the compiled template
  3521. +        $template_header = "<?php /* Smarty version ".$this->_version.", created on ".strftime("%Y-%m-%d %H:%M:%S")."\n";
  3522. +        $template_header .= "         compiled from ".strtr(urlencode($resource_name), array('%2F'=>'/', '%3A'=>':'))." */ ?>\n";
  3523. +
  3524. +        /* Emit code to load needed plugins. */
  3525. +        $this->_plugins_code = '';
  3526. +        if (count($this->_plugin_info)) {
  3527. +            $_plugins_params = "array('plugins' => array(";
  3528. +            foreach ($this->_plugin_info as $plugin_type => $plugins) {
  3529. +                foreach ($plugins as $plugin_name => $plugin_info) {
  3530. +                    $_plugins_params .= "array('$plugin_type', '$plugin_name', '" . strtr($plugin_info[0], array("'" => "\\'", "\\" => "\\\\")) . "', $plugin_info[1], ";
  3531. +                    $_plugins_params .= $plugin_info[2] ? 'true),' : 'false),';
  3532. +                }
  3533. +            }
  3534. +            $_plugins_params .= '))';
  3535. +            $plugins_code = "<?php require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');\nsmarty_core_load_plugins($_plugins_params, \$this); ?>\n";
  3536. +            $template_header .= $plugins_code;
  3537. +            $this->_plugin_info = array();
  3538. +            $this->_plugins_code = $plugins_code;
  3539. +        }
  3540. +
  3541. +        if ($this->_init_smarty_vars) {
  3542. +            $template_header .= "<?php require_once(SMARTY_CORE_DIR . 'core.assign_smarty_interface.php');\nsmarty_core_assign_smarty_interface(null, \$this); ?>\n";
  3543. +            $this->_init_smarty_vars = false;
  3544. +        }
  3545. +
  3546. +        $compiled_content = $template_header . $compiled_content;
  3547. +        return true;
  3548. +    }
  3549. +
  3550. +    /**
  3551. +     * Compile a template tag
  3552. +     *
  3553. +     * @param string $template_tag
  3554. +     * @return string
  3555. +     */
  3556. +    function _compile_tag($template_tag)
  3557. +    {
  3558. +        /* Matched comment. */
  3559. +        if (substr($template_tag, 0, 1) == '*' && substr($template_tag, -1) == '*')
  3560. +            return '';
  3561. +        
  3562. +        /* Split tag into two three parts: command, command modifiers and the arguments. */
  3563. +        if(! preg_match('~^(?:(' . $this->_num_const_regexp . '|' . $this->_obj_call_regexp . '|' . $this->_var_regexp
  3564. +                . '|\/?' . $this->_reg_obj_regexp . '|\/?' . $this->_func_regexp . ')(' . $this->_mod_regexp . '*))
  3565. +                      (?:\s+(.*))?$
  3566. +                    ~xs', $template_tag, $match)) {
  3567. +            $this->_syntax_error("unrecognized tag: $template_tag", E_USER_ERROR, __FILE__, __LINE__);
  3568. +        }
  3569. +        
  3570. +        $tag_command = $match[1];
  3571. +        $tag_modifier = isset($match[2]) ? $match[2] : null;
  3572. +        $tag_args = isset($match[3]) ? $match[3] : null;
  3573. +
  3574. +        if (preg_match('~^' . $this->_num_const_regexp . '|' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '$~', $tag_command)) {
  3575. +            /* tag name is a variable or object */
  3576. +            $_return = $this->_parse_var_props($tag_command . $tag_modifier);
  3577. +            return "<?php echo $_return; ?>" . $this->_additional_newline;
  3578. +        }
  3579. +
  3580. +        /* If the tag name is a registered object, we process it. */
  3581. +        if (preg_match('~^\/?' . $this->_reg_obj_regexp . '$~', $tag_command)) {
  3582. +            return $this->_compile_registered_object_tag($tag_command, $this->_parse_attrs($tag_args), $tag_modifier);
  3583. +        }
  3584. +
  3585. +        switch ($tag_command) {
  3586. +            case 'include':
  3587. +                return $this->_compile_include_tag($tag_args);
  3588. +
  3589. +            case 'include_php':
  3590. +                return $this->_compile_include_php_tag($tag_args);
  3591. +
  3592. +            case 'if':
  3593. +                $this->_push_tag('if');
  3594. +                return $this->_compile_if_tag($tag_args);
  3595. +
  3596. +            case 'else':
  3597. +                list($_open_tag) = end($this->_tag_stack);
  3598. +                if ($_open_tag != 'if' && $_open_tag != 'elseif')
  3599. +                    $this->_syntax_error('unexpected {else}', E_USER_ERROR, __FILE__, __LINE__);
  3600. +                else
  3601. +                    $this->_push_tag('else');
  3602. +                return '<?php else: ?>';
  3603. +
  3604. +            case 'elseif':
  3605. +                list($_open_tag) = end($this->_tag_stack);
  3606. +                if ($_open_tag != 'if' && $_open_tag != 'elseif')
  3607. +                    $this->_syntax_error('unexpected {elseif}', E_USER_ERROR, __FILE__, __LINE__);
  3608. +                if ($_open_tag == 'if')
  3609. +                    $this->_push_tag('elseif');
  3610. +                return $this->_compile_if_tag($tag_args, true);
  3611. +
  3612. +            case '/if':
  3613. +                $this->_pop_tag('if');
  3614. +                return '<?php endif; ?>';
  3615. +
  3616. +            case 'capture':
  3617. +                return $this->_compile_capture_tag(true, $tag_args);
  3618. +
  3619. +            case '/capture':
  3620. +                return $this->_compile_capture_tag(false);
  3621. +
  3622. +            case 'ldelim':
  3623. +                return $this->left_delimiter;
  3624. +
  3625. +            case 'rdelim':
  3626. +                return $this->right_delimiter;
  3627. +
  3628. +            case 'section':
  3629. +                $this->_push_tag('section');
  3630. +                return $this->_compile_section_start($tag_args);
  3631. +
  3632. +            case 'sectionelse':
  3633. +                $this->_push_tag('sectionelse');
  3634. +                return "<?php endfor; else: ?>";
  3635. +                break;
  3636. +
  3637. +            case '/section':
  3638. +                $_open_tag = $this->_pop_tag('section');
  3639. +                if ($_open_tag == 'sectionelse')
  3640. +                    return "<?php endif; ?>";
  3641. +                else
  3642. +                    return "<?php endfor; endif; ?>";
  3643. +
  3644. +            case 'foreach':
  3645. +                $this->_push_tag('foreach');
  3646. +                return $this->_compile_foreach_start($tag_args);
  3647. +                break;
  3648. +
  3649. +            case 'foreachelse':
  3650. +                $this->_push_tag('foreachelse');
  3651. +                return "<?php endforeach; else: ?>";
  3652. +
  3653. +            case '/foreach':
  3654. +                $_open_tag = $this->_pop_tag('foreach');
  3655. +                if ($_open_tag == 'foreachelse')
  3656. +                    return "<?php endif; unset(\$_from); ?>";
  3657. +                else
  3658. +                    return "<?php endforeach; endif; unset(\$_from); ?>";
  3659. +                break;
  3660. +
  3661. +            case 'strip':
  3662. +            case '/strip':
  3663. +                if (substr($tag_command, 0, 1)=='/') {
  3664. +                    $this->_pop_tag('strip');
  3665. +                    if (--$this->_strip_depth==0) { /* outermost closing {/strip} */
  3666. +                        $this->_additional_newline = "\n";
  3667. +                        return '{' . $tag_command . '}';
  3668. +                    }
  3669. +                } else {
  3670. +                    $this->_push_tag('strip');
  3671. +                    if ($this->_strip_depth++==0) { /* outermost opening {strip} */
  3672. +                        $this->_additional_newline = "";
  3673. +                        return '{' . $tag_command . '}';
  3674. +                    }
  3675. +                }
  3676. +                return '';
  3677. +
  3678. +            case 'php':
  3679. +                /* handle folded tags replaced by {php} */
  3680. +                list(, $block) = each($this->_folded_blocks);
  3681. +                $this->_current_line_no += substr_count($block[0], "\n");
  3682. +                /* the number of matched elements in the regexp in _compile_file()
  3683. +                   determins the type of folded tag that was found */
  3684. +                switch (count($block)) {
  3685. +                    case 2: /* comment */
  3686. +                        return '';
  3687. +
  3688. +                    case 3: /* literal */
  3689. +                        return "<?php echo '" . strtr($block[2], array("'"=>"\'", "\\"=>"\\\\")) . "'; ?>" . $this->_additional_newline;
  3690. +
  3691. +                    case 4: /* php */
  3692. +                        if ($this->security && !$this->security_settings['PHP_TAGS']) {
  3693. +                            $this->_syntax_error("(secure mode) php tags not permitted", E_USER_WARNING, __FILE__, __LINE__);
  3694. +                            return;
  3695. +                        }
  3696. +                        return '<?php ' . $block[3] .' ?>';
  3697. +                }
  3698. +                break;
  3699. +
  3700. +            case 'insert':
  3701. +                return $this->_compile_insert_tag($tag_args);
  3702. +
  3703. +            default:
  3704. +                if ($this->_compile_compiler_tag($tag_command, $tag_args, $output)) {
  3705. +                    return $output;
  3706. +                } else if ($this->_compile_block_tag($tag_command, $tag_args, $tag_modifier, $output)) {
  3707. +                    return $output;
  3708. +                } else if ($this->_compile_custom_tag($tag_command, $tag_args, $tag_modifier, $output)) {
  3709. +                    return $output;                    
  3710. +                } else {
  3711. +                    $this->_syntax_error("unrecognized tag '$tag_command'", E_USER_ERROR, __FILE__, __LINE__);
  3712. +                }
  3713. +
  3714. +        }
  3715. +    }
  3716. +
  3717. +
  3718. +    /**
  3719. +     * compile the custom compiler tag
  3720. +     *
  3721. +     * sets $output to the compiled custom compiler tag
  3722. +     * @param string $tag_command
  3723. +     * @param string $tag_args
  3724. +     * @param string $output
  3725. +     * @return boolean
  3726. +     */
  3727. +    function _compile_compiler_tag($tag_command, $tag_args, &$output)
  3728. +    {
  3729. +        $found = false;
  3730. +        $have_function = true;
  3731. +
  3732. +        /*
  3733. +         * First we check if the compiler function has already been registered
  3734. +         * or loaded from a plugin file.
  3735. +         */
  3736. +        if (isset($this->_plugins['compiler'][$tag_command])) {
  3737. +            $found = true;
  3738. +            $plugin_func = $this->_plugins['compiler'][$tag_command][0];
  3739. +            if (!is_callable($plugin_func)) {
  3740. +                $message = "compiler function '$tag_command' is not implemented";
  3741. +                $have_function = false;
  3742. +            }
  3743. +        }
  3744. +        /*
  3745. +         * Otherwise we need to load plugin file and look for the function
  3746. +         * inside it.
  3747. +         */
  3748. +        else if ($plugin_file = $this->_get_plugin_filepath('compiler', $tag_command)) {
  3749. +            $found = true;
  3750. +
  3751. +            include_once $plugin_file;
  3752. +
  3753. +            $plugin_func = 'smarty_compiler_' . $tag_command;
  3754. +            if (!is_callable($plugin_func)) {
  3755. +                $message = "plugin function $plugin_func() not found in $plugin_file\n";
  3756. +                $have_function = false;
  3757. +            } else {
  3758. +                $this->_plugins['compiler'][$tag_command] = array($plugin_func, null, null, null, true);
  3759. +            }
  3760. +        }
  3761. +
  3762. +        /*
  3763. +         * True return value means that we either found a plugin or a
  3764. +         * dynamically registered function. False means that we didn't and the
  3765. +         * compiler should now emit code to load custom function plugin for this
  3766. +         * tag.
  3767. +         */
  3768. +        if ($found) {
  3769. +            if ($have_function) {
  3770. +                $output = call_user_func_array($plugin_func, array($tag_args, &$this));
  3771. +                if($output != '') {
  3772. +                $output = '<?php ' . $this->_push_cacheable_state('compiler', $tag_command)
  3773. +                                   . $output
  3774. +                                   . $this->_pop_cacheable_state('compiler', $tag_command) . ' ?>';
  3775. +                }
  3776. +            } else {
  3777. +                $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__);
  3778. +            }
  3779. +            return true;
  3780. +        } else {
  3781. +            return false;
  3782. +        }
  3783. +    }
  3784. +
  3785. +
  3786. +    /**
  3787. +     * compile block function tag
  3788. +     *
  3789. +     * sets $output to compiled block function tag
  3790. +     * @param string $tag_command
  3791. +     * @param string $tag_args
  3792. +     * @param string $tag_modifier
  3793. +     * @param string $output
  3794. +     * @return boolean
  3795. +     */
  3796. +    function _compile_block_tag($tag_command, $tag_args, $tag_modifier, &$output)
  3797. +    {
  3798. +        if (substr($tag_command, 0, 1) == '/') {
  3799. +            $start_tag = false;
  3800. +            $tag_command = substr($tag_command, 1);
  3801. +        } else
  3802. +            $start_tag = true;
  3803. +
  3804. +        $found = false;
  3805. +        $have_function = true;
  3806. +
  3807. +        /*
  3808. +         * First we check if the block function has already been registered
  3809. +         * or loaded from a plugin file.
  3810. +         */
  3811. +        if (isset($this->_plugins['block'][$tag_command])) {
  3812. +            $found = true;
  3813. +            $plugin_func = $this->_plugins['block'][$tag_command][0];
  3814. +            if (!is_callable($plugin_func)) {
  3815. +                $message = "block function '$tag_command' is not implemented";
  3816. +                $have_function = false;
  3817. +            }
  3818. +        }
  3819. +        /*
  3820. +         * Otherwise we need to load plugin file and look for the function
  3821. +         * inside it.
  3822. +         */
  3823. +        else if ($plugin_file = $this->_get_plugin_filepath('block', $tag_command)) {
  3824. +            $found = true;
  3825. +
  3826. +            include_once $plugin_file;
  3827. +
  3828. +            $plugin_func = 'smarty_block_' . $tag_command;
  3829. +            if (!function_exists($plugin_func)) {
  3830. +                $message = "plugin function $plugin_func() not found in $plugin_file\n";
  3831. +                $have_function = false;
  3832. +            } else {
  3833. +                $this->_plugins['block'][$tag_command] = array($plugin_func, null, null, null, true);
  3834. +
  3835. +            }
  3836. +        }
  3837. +
  3838. +        if (!$found) {
  3839. +            return false;
  3840. +        } else if (!$have_function) {
  3841. +            $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__);
  3842. +            return true;
  3843. +        }
  3844. +
  3845. +        /*
  3846. +         * Even though we've located the plugin function, compilation
  3847. +         * happens only once, so the plugin will still need to be loaded
  3848. +         * at runtime for future requests.
  3849. +         */
  3850. +        $this->_add_plugin('block', $tag_command);
  3851. +
  3852. +        if ($start_tag)
  3853. +            $this->_push_tag($tag_command);
  3854. +        else
  3855. +            $this->_pop_tag($tag_command);
  3856. +
  3857. +        if ($start_tag) {
  3858. +            $output = '<?php ' . $this->_push_cacheable_state('block', $tag_command);
  3859. +            $attrs = $this->_parse_attrs($tag_args);
  3860. +            $_cache_attrs='';
  3861. +            $arg_list = $this->_compile_arg_list('block', $tag_command, $attrs, $_cache_attrs);
  3862. +            $output .= "$_cache_attrs\$this->_tag_stack[] = array('$tag_command', array(".implode(',', $arg_list).')); ';
  3863. +            $output .= '$_block_repeat=true;' . $this->_compile_plugin_call('block', $tag_command).'($this->_tag_stack[count($this->_tag_stack)-1][1], null, $this, $_block_repeat);';
  3864. +            $output .= 'while ($_block_repeat) { ob_start(); ?>';
  3865. +        } else {
  3866. +            $output = '<?php $_block_content = ob_get_contents(); ob_end_clean(); ';
  3867. +            $_out_tag_text = $this->_compile_plugin_call('block', $tag_command).'($this->_tag_stack[count($this->_tag_stack)-1][1], $_block_content, $this, $_block_repeat)';
  3868. +            if ($tag_modifier != '') {
  3869. +                $this->_parse_modifiers($_out_tag_text, $tag_modifier);
  3870. +            }
  3871. +            $output .= '$_block_repeat=false;echo ' . $_out_tag_text . '; } ';
  3872. +            $output .= " array_pop(\$this->_tag_stack); " . $this->_pop_cacheable_state('block', $tag_command) . '?>';
  3873. +        }
  3874. +
  3875. +        return true;
  3876. +    }
  3877. +
  3878. +
  3879. +    /**
  3880. +     * compile custom function tag
  3881. +     *
  3882. +     * @param string $tag_command
  3883. +     * @param string $tag_args
  3884. +     * @param string $tag_modifier
  3885. +     * @return string
  3886. +     */
  3887. +    function _compile_custom_tag($tag_command, $tag_args, $tag_modifier, &$output)
  3888. +    {
  3889. +        $found = false;
  3890. +        $have_function = true;
  3891. +
  3892. +        /*
  3893. +         * First we check if the custom function has already been registered
  3894. +         * or loaded from a plugin file.
  3895. +         */
  3896. +        if (isset($this->_plugins['function'][$tag_command])) {
  3897. +            $found = true;
  3898. +            $plugin_func = $this->_plugins['function'][$tag_command][0];
  3899. +            if (!is_callable($plugin_func)) {
  3900. +                $message = "custom function '$tag_command' is not implemented";
  3901. +                $have_function = false;
  3902. +            }
  3903. +        }
  3904. +        /*
  3905. +         * Otherwise we need to load plugin file and look for the function
  3906. +         * inside it.
  3907. +         */
  3908. +        else if ($plugin_file = $this->_get_plugin_filepath('function', $tag_command)) {
  3909. +            $found = true;
  3910. +
  3911. +            include_once $plugin_file;
  3912. +
  3913. +            $plugin_func = 'smarty_function_' . $tag_command;
  3914. +            if (!function_exists($plugin_func)) {
  3915. +                $message = "plugin function $plugin_func() not found in $plugin_file\n";
  3916. +                $have_function = false;
  3917. +            } else {
  3918. +                $this->_plugins['function'][$tag_command] = array($plugin_func, null, null, null, true);
  3919. +
  3920. +            }
  3921. +        }
  3922. +
  3923. +        if (!$found) {
  3924. +            return false;
  3925. +        } else if (!$have_function) {
  3926. +            $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__);
  3927. +            return true;
  3928. +        }
  3929. +
  3930. +        /* declare plugin to be loaded on display of the template that
  3931. +           we compile right now */
  3932. +        $this->_add_plugin('function', $tag_command);
  3933. +
  3934. +        $_cacheable_state = $this->_push_cacheable_state('function', $tag_command);
  3935. +        $attrs = $this->_parse_attrs($tag_args);
  3936. +        $_cache_attrs = '';
  3937. +        $arg_list = $this->_compile_arg_list('function', $tag_command, $attrs, $_cache_attrs);
  3938. +
  3939. +        $output = $this->_compile_plugin_call('function', $tag_command).'(array('.implode(',', $arg_list)."), \$this)";
  3940. +        if($tag_modifier != '') {
  3941. +            $this->_parse_modifiers($output, $tag_modifier);
  3942. +        }
  3943. +
  3944. +        if($output != '') {
  3945. +            $output =  '<?php ' . $_cacheable_state . $_cache_attrs . 'echo ' . $output . ';'
  3946. +                . $this->_pop_cacheable_state('function', $tag_command) . "?>" . $this->_additional_newline;
  3947. +        }
  3948. +
  3949. +        return true;
  3950. +    }
  3951. +
  3952. +    /**
  3953. +     * compile a registered object tag
  3954. +     *
  3955. +     * @param string $tag_command
  3956. +     * @param array $attrs
  3957. +     * @param string $tag_modifier
  3958. +     * @return string
  3959. +     */
  3960. +    function _compile_registered_object_tag($tag_command, $attrs, $tag_modifier)
  3961. +    {
  3962. +        if (substr($tag_command, 0, 1) == '/') {
  3963. +            $start_tag = false;
  3964. +            $tag_command = substr($tag_command, 1);
  3965. +        } else {
  3966. +            $start_tag = true;
  3967. +        }
  3968. +
  3969. +        list($object, $obj_comp) = explode('->', $tag_command);
  3970. +
  3971. +        $arg_list = array();
  3972. +        if(count($attrs)) {
  3973. +            $_assign_var = false;
  3974. +            foreach ($attrs as $arg_name => $arg_value) {
  3975. +                if($arg_name == 'assign') {
  3976. +                    $_assign_var = $arg_value;
  3977. +                    unset($attrs['assign']);
  3978. +                    continue;
  3979. +                }
  3980. +                if (is_bool($arg_value))
  3981. +                    $arg_value = $arg_value ? 'true' : 'false';
  3982. +                $arg_list[] = "'$arg_name' => $arg_value";
  3983. +            }
  3984. +        }
  3985. +
  3986. +        if($this->_reg_objects[$object][2]) {
  3987. +            // smarty object argument format
  3988. +            $args = "array(".implode(',', (array)$arg_list)."), \$this";
  3989. +        } else {
  3990. +            // traditional argument format
  3991. +            $args = implode(',', array_values($attrs));
  3992. +            if (empty($args)) {
  3993. +                $args = '';
  3994. +            }
  3995. +        }
  3996. +
  3997. +        $prefix = '';
  3998. +        $postfix = '';
  3999. +        $newline = '';
  4000. +        if(!is_object($this->_reg_objects[$object][0])) {
  4001. +            $this->_trigger_fatal_error("registered '$object' is not an object" , $this->_current_file, $this->_current_line_no, __FILE__, __LINE__);
  4002. +        } elseif(!empty($this->_reg_objects[$object][1]) && !in_array($obj_comp, $this->_reg_objects[$object][1])) {
  4003. +            $this->_trigger_fatal_error("'$obj_comp' is not a registered component of object '$object'", $this->_current_file, $this->_current_line_no, __FILE__, __LINE__);
  4004. +        } elseif(method_exists($this->_reg_objects[$object][0], $obj_comp)) {
  4005. +            // method
  4006. +            if(in_array($obj_comp, $this->_reg_objects[$object][3])) {
  4007. +                // block method
  4008. +                if ($start_tag) {
  4009. +                    $prefix = "\$this->_tag_stack[] = array('$obj_comp', $args); ";
  4010. +                    $prefix .= "\$_block_repeat=true; \$this->_reg_objects['$object'][0]->$obj_comp(\$this->_tag_stack[count(\$this->_tag_stack)-1][1], null, \$this, \$_block_repeat); ";
  4011. +                    $prefix .= "while (\$_block_repeat) { ob_start();";
  4012. +                    $return = null;
  4013. +                    $postfix = '';
  4014. +                } else {
  4015. +                    $prefix = "\$_obj_block_content = ob_get_contents(); ob_end_clean(); \$_block_repeat=false;";
  4016. +                    $return = "\$this->_reg_objects['$object'][0]->$obj_comp(\$this->_tag_stack[count(\$this->_tag_stack)-1][1], \$_obj_block_content, \$this, \$_block_repeat)";
  4017. +                    $postfix = "} array_pop(\$this->_tag_stack);";
  4018. +                }
  4019. +            } else {
  4020. +                // non-block method
  4021. +                $return = "\$this->_reg_objects['$object'][0]->$obj_comp($args)";
  4022. +            }
  4023. +        } else {
  4024. +            // property
  4025. +            $return = "\$this->_reg_objects['$object'][0]->$obj_comp";
  4026. +        }
  4027. +
  4028. +        if($return != null) {
  4029. +            if($tag_modifier != '') {
  4030. +                $this->_parse_modifiers($return, $tag_modifier);
  4031. +            }
  4032. +
  4033. +            if(!empty($_assign_var)) {
  4034. +                $output = "\$this->assign('" . $this->_dequote($_assign_var) ."',  $return);";
  4035. +            } else {
  4036. +                $output = 'echo ' . $return . ';';
  4037. +                $newline = $this->_additional_newline;
  4038. +            }
  4039. +        } else {
  4040. +            $output = '';
  4041. +        }
  4042. +
  4043. +        return '<?php ' . $prefix . $output . $postfix . "?>" . $newline;
  4044. +    }
  4045. +
  4046. +    /**
  4047. +     * Compile {insert ...} tag
  4048. +     *
  4049. +     * @param string $tag_args
  4050. +     * @return string
  4051. +     */
  4052. +    function _compile_insert_tag($tag_args)
  4053. +    {
  4054. +        $attrs = $this->_parse_attrs($tag_args);
  4055. +        $name = $this->_dequote($attrs['name']);
  4056. +
  4057. +        if (empty($name)) {
  4058. +            return $this->_syntax_error("missing insert name", E_USER_ERROR, __FILE__, __LINE__);
  4059. +        }
  4060. +        
  4061. +        if (!preg_match('~^\w+$~', $name)) {
  4062. +            return $this->_syntax_error("'insert: 'name' must be an insert function name", E_USER_ERROR, __FILE__, __LINE__);
  4063. +        }
  4064. +
  4065. +        if (!empty($attrs['script'])) {
  4066. +            $delayed_loading = true;
  4067. +        } else {
  4068. +            $delayed_loading = false;
  4069. +        }
  4070. +
  4071. +        foreach ($attrs as $arg_name => $arg_value) {
  4072. +            if (is_bool($arg_value))
  4073. +                $arg_value = $arg_value ? 'true' : 'false';
  4074. +            $arg_list[] = "'$arg_name' => $arg_value";
  4075. +        }
  4076. +
  4077. +        $this->_add_plugin('insert', $name, $delayed_loading);
  4078. +
  4079. +        $_params = "array('args' => array(".implode(', ', (array)$arg_list)."))";
  4080. +
  4081. +        return "<?php require_once(SMARTY_CORE_DIR . 'core.run_insert_handler.php');\necho smarty_core_run_insert_handler($_params, \$this); ?>" . $this->_additional_newline;
  4082. +    }
  4083. +
  4084. +    /**
  4085. +     * Compile {include ...} tag
  4086. +     *
  4087. +     * @param string $tag_args
  4088. +     * @return string
  4089. +     */
  4090. +    function _compile_include_tag($tag_args)
  4091. +    {
  4092. +        $attrs = $this->_parse_attrs($tag_args);
  4093. +        $arg_list = array();
  4094. +
  4095. +        if (empty($attrs['file'])) {
  4096. +            $this->_syntax_error("missing 'file' attribute in include tag", E_USER_ERROR, __FILE__, __LINE__);
  4097. +        }
  4098. +
  4099. +        foreach ($attrs as $arg_name => $arg_value) {
  4100. +            if ($arg_name == 'file') {
  4101. +                $include_file = $arg_value;
  4102. +                continue;
  4103. +            } else if ($arg_name == 'assign') {
  4104. +                $assign_var = $arg_value;
  4105. +                continue;
  4106. +            }
  4107. +            if (is_bool($arg_value))
  4108. +                $arg_value = $arg_value ? 'true' : 'false';
  4109. +            $arg_list[] = "'$arg_name' => $arg_value";
  4110. +        }
  4111. +
  4112. +        $output = '<?php ';
  4113. +
  4114. +        if (isset($assign_var)) {
  4115. +            $output .= "ob_start();\n";
  4116. +        }
  4117. +
  4118. +        $output .=
  4119. +            "\$_smarty_tpl_vars = \$this->_tpl_vars;\n";
  4120. +
  4121. +
  4122. +        $_params = "array('smarty_include_tpl_file' => " . $include_file . ", 'smarty_include_vars' => array(".implode(',', (array)$arg_list)."))";
  4123. +        $output .= "\$this->_smarty_include($_params);\n" .
  4124. +        "\$this->_tpl_vars = \$_smarty_tpl_vars;\n" .
  4125. +        "unset(\$_smarty_tpl_vars);\n";
  4126. +
  4127. +        if (isset($assign_var)) {
  4128. +            $output .= "\$this->assign(" . $assign_var . ", ob_get_contents()); ob_end_clean();\n";
  4129. +        }
  4130. +
  4131. +        $output .= ' ?>';
  4132. +
  4133. +        return $output;
  4134. +
  4135. +    }
  4136. +
  4137. +    /**
  4138. +     * Compile {include ...} tag
  4139. +     *
  4140. +     * @param string $tag_args
  4141. +     * @return string
  4142. +     */
  4143. +    function _compile_include_php_tag($tag_args)
  4144. +    {
  4145. +        $attrs = $this->_parse_attrs($tag_args);
  4146. +
  4147. +        if (empty($attrs['file'])) {
  4148. +            $this->_syntax_error("missing 'file' attribute in include_php tag", E_USER_ERROR, __FILE__, __LINE__);
  4149. +        }
  4150. +
  4151. +        $assign_var = (empty($attrs['assign'])) ? '' : $this->_dequote($attrs['assign']);
  4152. +        $once_var = (empty($attrs['once']) || $attrs['once']=='false') ? 'false' : 'true';
  4153. +
  4154. +        $arg_list = array();
  4155. +        foreach($attrs as $arg_name => $arg_value) {
  4156. +            if($arg_name != 'file' AND $arg_name != 'once' AND $arg_name != 'assign') {
  4157. +                if(is_bool($arg_value))
  4158. +                    $arg_value = $arg_value ? 'true' : 'false';
  4159. +                $arg_list[] = "'$arg_name' => $arg_value";
  4160. +            }
  4161. +        }
  4162. +
  4163. +        $_params = "array('smarty_file' => " . $attrs['file'] . ", 'smarty_assign' => '$assign_var', 'smarty_once' => $once_var, 'smarty_include_vars' => array(".implode(',', $arg_list)."))";
  4164. +
  4165. +        return "<?php require_once(SMARTY_CORE_DIR . 'core.smarty_include_php.php');\nsmarty_core_smarty_include_php($_params, \$this); ?>" . $this->_additional_newline;
  4166. +    }
  4167. +
  4168. +
  4169. +    /**
  4170. +     * Compile {section ...} tag
  4171. +     *
  4172. +     * @param string $tag_args
  4173. +     * @return string
  4174. +     */
  4175. +    function _compile_section_start($tag_args)
  4176. +    {
  4177. +        $attrs = $this->_parse_attrs($tag_args);
  4178. +        $arg_list = array();
  4179. +
  4180. +        $output = '<?php ';
  4181. +        $section_name = $attrs['name'];
  4182. +        if (empty($section_name)) {
  4183. +            $this->_syntax_error("missing section name", E_USER_ERROR, __FILE__, __LINE__);
  4184. +        }
  4185. +
  4186. +        $output .= "unset(\$this->_sections[$section_name]);\n";
  4187. +        $section_props = "\$this->_sections[$section_name]";
  4188. +
  4189. +        foreach ($attrs as $attr_name => $attr_value) {
  4190. +            switch ($attr_name) {
  4191. +                case 'loop':
  4192. +                    $output .= "{$section_props}['loop'] = is_array(\$_loop=$attr_value) ? count(\$_loop) : max(0, (int)\$_loop); unset(\$_loop);\n";
  4193. +                    break;
  4194. +
  4195. +                case 'show':
  4196. +                    if (is_bool($attr_value))
  4197. +                        $show_attr_value = $attr_value ? 'true' : 'false';
  4198. +                    else
  4199. +                        $show_attr_value = "(bool)$attr_value";
  4200. +                    $output .= "{$section_props}['show'] = $show_attr_value;\n";
  4201. +                    break;
  4202. +
  4203. +                case 'name':
  4204. +                    $output .= "{$section_props}['$attr_name'] = $attr_value;\n";
  4205. +                    break;
  4206. +
  4207. +                case 'max':
  4208. +                case 'start':
  4209. +                    $output .= "{$section_props}['$attr_name'] = (int)$attr_value;\n";
  4210. +                    break;
  4211. +
  4212. +                case 'step':
  4213. +                    $output .= "{$section_props}['$attr_name'] = ((int)$attr_value) == 0 ? 1 : (int)$attr_value;\n";
  4214. +                    break;
  4215. +
  4216. +                default:
  4217. +                    $this->_syntax_error("unknown section attribute - '$attr_name'", E_USER_ERROR, __FILE__, __LINE__);
  4218. +                    break;
  4219. +            }
  4220. +        }
  4221. +
  4222. +        if (!isset($attrs['show']))
  4223. +            $output .= "{$section_props}['show'] = true;\n";
  4224. +
  4225. +        if (!isset($attrs['loop']))
  4226. +            $output .= "{$section_props}['loop'] = 1;\n";
  4227. +
  4228. +        if (!isset($attrs['max']))
  4229. +            $output .= "{$section_props}['max'] = {$section_props}['loop'];\n";
  4230. +        else
  4231. +            $output .= "if ({$section_props}['max'] < 0)\n" .
  4232. +                       "    {$section_props}['max'] = {$section_props}['loop'];\n";
  4233. +
  4234. +        if (!isset($attrs['step']))
  4235. +            $output .= "{$section_props}['step'] = 1;\n";
  4236. +
  4237. +        if (!isset($attrs['start']))
  4238. +            $output .= "{$section_props}['start'] = {$section_props}['step'] > 0 ? 0 : {$section_props}['loop']-1;\n";
  4239. +        else {
  4240. +            $output .= "if ({$section_props}['start'] < 0)\n" .
  4241. +                       "    {$section_props}['start'] = max({$section_props}['step'] > 0 ? 0 : -1, {$section_props}['loop'] + {$section_props}['start']);\n" .
  4242. +                       "else\n" .
  4243. +                       "    {$section_props}['start'] = min({$section_props}['start'], {$section_props}['step'] > 0 ? {$section_props}['loop'] : {$section_props}['loop']-1);\n";
  4244. +        }
  4245. +
  4246. +        $output .= "if ({$section_props}['show']) {\n";
  4247. +        if (!isset($attrs['start']) && !isset($attrs['step']) && !isset($attrs['max'])) {
  4248. +            $output .= "    {$section_props}['total'] = {$section_props}['loop'];\n";
  4249. +        } else {
  4250. +            $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";
  4251. +        }
  4252. +        $output .= "    if ({$section_props}['total'] == 0)\n" .
  4253. +                   "        {$section_props}['show'] = false;\n" .
  4254. +                   "} else\n" .
  4255. +                   "    {$section_props}['total'] = 0;\n";
  4256. +
  4257. +        $output .= "if ({$section_props}['show']):\n";
  4258. +        $output .= "
  4259. +            for ({$section_props}['index'] = {$section_props}['start'], {$section_props}['iteration'] = 1;
  4260. +                 {$section_props}['iteration'] <= {$section_props}['total'];
  4261. +                 {$section_props}['index'] += {$section_props}['step'], {$section_props}['iteration']++):\n";
  4262. +        $output .= "{$section_props}['rownum'] = {$section_props}['iteration'];\n";
  4263. +        $output .= "{$section_props}['index_prev'] = {$section_props}['index'] - {$section_props}['step'];\n";
  4264. +        $output .= "{$section_props}['index_next'] = {$section_props}['index'] + {$section_props}['step'];\n";
  4265. +        $output .= "{$section_props}['first']      = ({$section_props}['iteration'] == 1);\n";
  4266. +        $output .= "{$section_props}['last']       = ({$section_props}['iteration'] == {$section_props}['total']);\n";
  4267. +
  4268. +        $output .= "?>";
  4269. +
  4270. +        return $output;
  4271. +    }
  4272. +
  4273. +
  4274. +    /**
  4275. +     * Compile {foreach ...} tag.
  4276. +     *
  4277. +     * @param string $tag_args
  4278. +     * @return string
  4279. +     */
  4280. +    function _compile_foreach_start($tag_args)
  4281. +    {
  4282. +        $attrs = $this->_parse_attrs($tag_args);
  4283. +        $arg_list = array();
  4284. +
  4285. +        if (empty($attrs['from'])) {
  4286. +            return $this->_syntax_error("foreach: missing 'from' attribute", E_USER_ERROR, __FILE__, __LINE__);
  4287. +        }
  4288. +        $from = $attrs['from'];
  4289. +
  4290. +        if (empty($attrs['item'])) {
  4291. +            return $this->_syntax_error("foreach: missing 'item' attribute", E_USER_ERROR, __FILE__, __LINE__);
  4292. +        }
  4293. +        $item = $this->_dequote($attrs['item']);
  4294. +        if (!preg_match('~^\w+$~', $item)) {
  4295. +            return $this->_syntax_error("foreach: 'item' must be a variable name (literal string)", E_USER_ERROR, __FILE__, __LINE__);
  4296. +        }
  4297. +
  4298. +        if (isset($attrs['key'])) {
  4299. +            $key  = $this->_dequote($attrs['key']);
  4300. +            if (!preg_match('~^\w+$~', $key)) {
  4301. +                return $this->_syntax_error("foreach: 'key' must to be a variable name (literal string)", E_USER_ERROR, __FILE__, __LINE__);
  4302. +            }
  4303. +            $key_part = "\$this->_tpl_vars['$key'] => ";
  4304. +        } else {
  4305. +            $key = null;
  4306. +            $key_part = '';
  4307. +        }
  4308. +
  4309. +        if (isset($attrs['name'])) {
  4310. +            $name = $attrs['name'];
  4311. +        } else {
  4312. +            $name = null;
  4313. +        }
  4314. +
  4315. +        $output = '<?php ';
  4316. +        $output .= "\$_from = $from; if (!is_array(\$_from) && !is_object(\$_from)) { settype(\$_from, 'array'); }";
  4317. +        if (isset($name)) {
  4318. +            $foreach_props = "\$this->_foreach[$name]";
  4319. +            $output .= "{$foreach_props} = array('total' => count(\$_from), 'iteration' => 0);\n";
  4320. +            $output .= "if ({$foreach_props}['total'] > 0):\n";
  4321. +            $output .= "    foreach (\$_from as $key_part\$this->_tpl_vars['$item']):\n";
  4322. +            $output .= "        {$foreach_props}['iteration']++;\n";
  4323. +        } else {
  4324. +            $output .= "if (count(\$_from)):\n";
  4325. +            $output .= "    foreach (\$_from as $key_part\$this->_tpl_vars['$item']):\n";
  4326. +        }
  4327. +        $output .= '?>';
  4328. +
  4329. +        return $output;
  4330. +    }
  4331. +
  4332. +
  4333. +    /**
  4334. +     * Compile {capture} .. {/capture} tags
  4335. +     *
  4336. +     * @param boolean $start true if this is the {capture} tag
  4337. +     * @param string $tag_args
  4338. +     * @return string
  4339. +     */
  4340. +
  4341. +    function _compile_capture_tag($start, $tag_args = '')
  4342. +    {
  4343. +        $attrs = $this->_parse_attrs($tag_args);
  4344. +
  4345. +        if ($start) {
  4346. +            $buffer = isset($attrs['name']) ? $attrs['name'] : "'default'";
  4347. +            $assign = isset($attrs['assign']) ? $attrs['assign'] : null;
  4348. +            $append = isset($attrs['append']) ? $attrs['append'] : null;
  4349. +            
  4350. +            $output = "<?php ob_start(); ?>";
  4351. +            $this->_capture_stack[] = array($buffer, $assign, $append);
  4352. +        } else {
  4353. +            list($buffer, $assign, $append) = array_pop($this->_capture_stack);
  4354. +            $output = "<?php \$this->_smarty_vars['capture'][$buffer] = ob_get_contents(); ";
  4355. +            if (isset($assign)) {
  4356. +                $output .= " \$this->assign($assign, ob_get_contents());";
  4357. +            }
  4358. +            if (isset($append)) {
  4359. +                $output .= " \$this->append($append, ob_get_contents());";
  4360. +            }
  4361. +            $output .= "ob_end_clean(); ?>";
  4362. +        }
  4363. +
  4364. +        return $output;
  4365. +    }
  4366. +
  4367. +    /**
  4368. +     * Compile {if ...} tag
  4369. +     *
  4370. +     * @param string $tag_args
  4371. +     * @param boolean $elseif if true, uses elseif instead of if
  4372. +     * @return string
  4373. +     */
  4374. +    function _compile_if_tag($tag_args, $elseif = false)
  4375. +    {
  4376. +
  4377. +        /* Tokenize args for 'if' tag. */
  4378. +        preg_match_all('~(?>
  4379. +                ' . $this->_obj_call_regexp . '(?:' . $this->_mod_regexp . '*)? | # valid object call
  4380. +                ' . $this->_var_regexp . '(?:' . $this->_mod_regexp . '*)?    | # var or quoted string
  4381. +                \-?0[xX][0-9a-fA-F]+|\-?\d+(?:\.\d+)?|\.\d+|!==|===|==|!=|<>|<<|>>|<=|>=|\&\&|\|\||\(|\)|,|\!|\^|=|\&|\~|<|>|\||\%|\+|\-|\/|\*|\@    | # valid non-word token
  4382. +                \b\w+\b                                                        | # valid word token
  4383. +                \S+                                                           # anything else
  4384. +                )~x', $tag_args, $match);
  4385. +
  4386. +        $tokens = $match[0];
  4387. +
  4388. +        if(empty($tokens)) {
  4389. +            $_error_msg = $elseif ? "'elseif'" : "'if'";
  4390. +            $_error_msg .= ' statement requires arguments';
  4391. +            $this->_syntax_error($_error_msg, E_USER_ERROR, __FILE__, __LINE__);
  4392. +        }
  4393. +            
  4394. +                
  4395. +        // make sure we have balanced parenthesis
  4396. +        $token_count = array_count_values($tokens);
  4397. +        if(isset($token_count['(']) && $token_count['('] != $token_count[')']) {
  4398. +            $this->_syntax_error("unbalanced parenthesis in if statement", E_USER_ERROR, __FILE__, __LINE__);
  4399. +        }
  4400. +
  4401. +        $is_arg_stack = array();
  4402. +
  4403. +        for ($i = 0; $i < count($tokens); $i++) {
  4404. +
  4405. +            $token = &$tokens[$i];
  4406. +
  4407. +            switch (strtolower($token)) {
  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. +                case '/':
  4433. +                case '@':
  4434. +                    break;
  4435. +
  4436. +                case 'eq':
  4437. +                    $token = '==';
  4438. +                    break;
  4439. +
  4440. +                case 'ne':
  4441. +                case 'neq':
  4442. +                    $token = '!=';
  4443. +                    break;
  4444. +
  4445. +                case 'lt':
  4446. +                    $token = '<';
  4447. +                    break;
  4448. +
  4449. +                case 'le':
  4450. +                case 'lte':
  4451. +                    $token = '<=';
  4452. +                    break;
  4453. +
  4454. +                case 'gt':
  4455. +                    $token = '>';
  4456. +                    break;
  4457. +
  4458. +                case 'ge':
  4459. +                case 'gte':
  4460. +                    $token = '>=';
  4461. +                    break;
  4462. +
  4463. +                case 'and':
  4464. +                    $token = '&&';
  4465. +                    break;
  4466. +
  4467. +                case 'or':
  4468. +                    $token = '||';
  4469. +                    break;
  4470. +
  4471. +                case 'not':
  4472. +                    $token = '!';
  4473. +                    break;
  4474. +
  4475. +                case 'mod':
  4476. +                    $token = '%';
  4477. +                    break;
  4478. +
  4479. +                case '(':
  4480. +                    array_push($is_arg_stack, $i);
  4481. +                    break;
  4482. +
  4483. +                case 'is':
  4484. +                    /* If last token was a ')', we operate on the parenthesized
  4485. +                       expression. The start of the expression is on the stack.
  4486. +                       Otherwise, we operate on the last encountered token. */
  4487. +                    if ($tokens[$i-1] == ')') {
  4488. +                        $is_arg_start = array_pop($is_arg_stack);
  4489. +                        if ($is_arg_start != 0) {
  4490. +                            if (preg_match('~^' . $this->_func_regexp . '$~', $tokens[$is_arg_start-1])) {
  4491. +                                $is_arg_start--;
  4492. +                            }
  4493. +                        }
  4494. +                    } else
  4495. +                        $is_arg_start = $i-1;
  4496. +                    /* Construct the argument for 'is' expression, so it knows
  4497. +                       what to operate on. */
  4498. +                    $is_arg = implode(' ', array_slice($tokens, $is_arg_start, $i - $is_arg_start));
  4499. +
  4500. +                    /* Pass all tokens from next one until the end to the
  4501. +                       'is' expression parsing function. The function will
  4502. +                       return modified tokens, where the first one is the result
  4503. +                       of the 'is' expression and the rest are the tokens it
  4504. +                       didn't touch. */
  4505. +                    $new_tokens = $this->_parse_is_expr($is_arg, array_slice($tokens, $i+1));
  4506. +
  4507. +                    /* Replace the old tokens with the new ones. */
  4508. +                    array_splice($tokens, $is_arg_start, count($tokens), $new_tokens);
  4509. +
  4510. +                    /* Adjust argument start so that it won't change from the
  4511. +                       current position for the next iteration. */
  4512. +                    $i = $is_arg_start;
  4513. +                    break;
  4514. +
  4515. +                default:
  4516. +                    if(preg_match('~^' . $this->_func_regexp . '$~', $token) ) {
  4517. +                            // function call
  4518. +                            if($this->security &&
  4519. +                               !in_array($token, $this->security_settings['IF_FUNCS'])) {
  4520. +                                $this->_syntax_error("(secure mode) '$token' not allowed in if statement", E_USER_ERROR, __FILE__, __LINE__);
  4521. +                            }
  4522. +                    } elseif(preg_match('~^' . $this->_var_regexp . '$~', $token) && (strpos('+-*/^%&|', substr($token, -1)) === false) && isset($tokens[$i+1]) && $tokens[$i+1] == '(') {
  4523. +                        // variable function call
  4524. +                        $this->_syntax_error("variable function call '$token' not allowed in if statement", E_USER_ERROR, __FILE__, __LINE__);                      
  4525. +                    } elseif(preg_match('~^' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '(?:' . $this->_mod_regexp . '*)$~', $token)) {
  4526. +                        // object or variable
  4527. +                        $token = $this->_parse_var_props($token);
  4528. +                    } elseif(is_numeric($token)) {
  4529. +                        // number, skip it
  4530. +                    } else {
  4531. +                        $this->_syntax_error("unidentified token '$token'", E_USER_ERROR, __FILE__, __LINE__);
  4532. +                    }
  4533. +                    break;
  4534. +            }
  4535. +        }
  4536. +
  4537. +        if ($elseif)
  4538. +            return '<?php elseif ('.implode(' ', $tokens).'): ?>';
  4539. +        else
  4540. +            return '<?php if ('.implode(' ', $tokens).'): ?>';
  4541. +    }
  4542. +
  4543. +
  4544. +    function _compile_arg_list($type, $name, $attrs, &$cache_code) {
  4545. +        $arg_list = array();
  4546. +
  4547. +        if (isset($type) && isset($name)
  4548. +            && isset($this->_plugins[$type])
  4549. +            && isset($this->_plugins[$type][$name])
  4550. +            && empty($this->_plugins[$type][$name][4])
  4551. +            && is_array($this->_plugins[$type][$name][5])
  4552. +            ) {
  4553. +            /* we have a list of parameters that should be cached */
  4554. +            $_cache_attrs = $this->_plugins[$type][$name][5];
  4555. +            $_count = $this->_cache_attrs_count++;
  4556. +            $cache_code = "\$_cache_attrs =& \$this->_smarty_cache_attrs('$this->_cache_serial','$_count');";
  4557. +
  4558. +        } else {
  4559. +            /* no parameters are cached */
  4560. +            $_cache_attrs = null;
  4561. +        }
  4562. +
  4563. +        foreach ($attrs as $arg_name => $arg_value) {
  4564. +            if (is_bool($arg_value))
  4565. +                $arg_value = $arg_value ? 'true' : 'false';
  4566. +            if (is_null($arg_value))
  4567. +                $arg_value = 'null';
  4568. +            if ($_cache_attrs && in_array($arg_name, $_cache_attrs)) {
  4569. +                $arg_list[] = "'$arg_name' => (\$this->_cache_including) ? \$_cache_attrs['$arg_name'] : (\$_cache_attrs['$arg_name']=$arg_value)";
  4570. +            } else {
  4571. +                $arg_list[] = "'$arg_name' => $arg_value";
  4572. +            }
  4573. +        }
  4574. +        return $arg_list;
  4575. +    }
  4576. +
  4577. +    /**
  4578. +     * Parse is expression
  4579. +     *
  4580. +     * @param string $is_arg
  4581. +     * @param array $tokens
  4582. +     * @return array
  4583. +     */
  4584. +    function _parse_is_expr($is_arg, $tokens)
  4585. +    {
  4586. +        $expr_end = 0;
  4587. +        $negate_expr = false;
  4588. +
  4589. +        if (($first_token = array_shift($tokens)) == 'not') {
  4590. +            $negate_expr = true;
  4591. +            $expr_type = array_shift($tokens);
  4592. +        } else
  4593. +            $expr_type = $first_token;
  4594. +
  4595. +        switch ($expr_type) {
  4596. +            case 'even':
  4597. +                if (isset($tokens[$expr_end]) && $tokens[$expr_end] == 'by') {
  4598. +                    $expr_end++;
  4599. +                    $expr_arg = $tokens[$expr_end++];
  4600. +                    $expr = "!(1 & ($is_arg / " . $this->_parse_var_props($expr_arg) . "))";
  4601. +                } else
  4602. +                    $expr = "!(1 & $is_arg)";
  4603. +                break;
  4604. +
  4605. +            case 'odd':
  4606. +                if (isset($tokens[$expr_end]) && $tokens[$expr_end] == 'by') {
  4607. +                    $expr_end++;
  4608. +                    $expr_arg = $tokens[$expr_end++];
  4609. +                    $expr = "(1 & ($is_arg / " . $this->_parse_var_props($expr_arg) . "))";
  4610. +                } else
  4611. +                    $expr = "(1 & $is_arg)";
  4612. +                break;
  4613. +
  4614. +            case 'div':
  4615. +                if (@$tokens[$expr_end] == 'by') {
  4616. +                    $expr_end++;
  4617. +                    $expr_arg = $tokens[$expr_end++];
  4618. +                    $expr = "!($is_arg % " . $this->_parse_var_props($expr_arg) . ")";
  4619. +                } else {
  4620. +                    $this->_syntax_error("expecting 'by' after 'div'", E_USER_ERROR, __FILE__, __LINE__);
  4621. +                }
  4622. +                break;
  4623. +
  4624. +            default:
  4625. +                $this->_syntax_error("unknown 'is' expression - '$expr_type'", E_USER_ERROR, __FILE__, __LINE__);
  4626. +                break;
  4627. +        }
  4628. +
  4629. +        if ($negate_expr) {
  4630. +            $expr = "!($expr)";
  4631. +        }
  4632. +
  4633. +        array_splice($tokens, 0, $expr_end, $expr);
  4634. +
  4635. +        return $tokens;
  4636. +    }
  4637. +
  4638. +
  4639. +    /**
  4640. +     * Parse attribute string
  4641. +     *
  4642. +     * @param string $tag_args
  4643. +     * @return array
  4644. +     */
  4645. +    function _parse_attrs($tag_args)
  4646. +    {
  4647. +
  4648. +        /* Tokenize tag attributes. */
  4649. +        preg_match_all('~(?:' . $this->_obj_call_regexp . '|' . $this->_qstr_regexp . ' | (?>[^"\'=\s]+)
  4650. +                         )+ |
  4651. +                         [=]
  4652. +                        ~x', $tag_args, $match);
  4653. +        $tokens       = $match[0];
  4654. +
  4655. +        $attrs = array();
  4656. +        /* Parse state:
  4657. +            0 - expecting attribute name
  4658. +            1 - expecting '='
  4659. +            2 - expecting attribute value (not '=') */
  4660. +        $state = 0;
  4661. +
  4662. +        foreach ($tokens as $token) {
  4663. +            switch ($state) {
  4664. +                case 0:
  4665. +                    /* If the token is a valid identifier, we set attribute name
  4666. +                       and go to state 1. */
  4667. +                    if (preg_match('~^\w+$~', $token)) {
  4668. +                        $attr_name = $token;
  4669. +                        $state = 1;
  4670. +                    } else
  4671. +                        $this->_syntax_error("invalid attribute name: '$token'", E_USER_ERROR, __FILE__, __LINE__);
  4672. +                    break;
  4673. +
  4674. +                case 1:
  4675. +                    /* If the token is '=', then we go to state 2. */
  4676. +                    if ($token == '=') {
  4677. +                        $state = 2;
  4678. +                    } else
  4679. +                        $this->_syntax_error("expecting '=' after attribute name '$last_token'", E_USER_ERROR, __FILE__, __LINE__);
  4680. +                    break;
  4681. +
  4682. +                case 2:
  4683. +                    /* If token is not '=', we set the attribute value and go to
  4684. +                       state 0. */
  4685. +                    if ($token != '=') {
  4686. +                        /* We booleanize the token if it's a non-quoted possible
  4687. +                           boolean value. */
  4688. +                        if (preg_match('~^(on|yes|true)$~', $token)) {
  4689. +                            $token = 'true';
  4690. +                        } else if (preg_match('~^(off|no|false)$~', $token)) {
  4691. +                            $token = 'false';
  4692. +                        } else if ($token == 'null') {
  4693. +                            $token = 'null';
  4694. +                        } else if (preg_match('~^' . $this->_num_const_regexp . '|0[xX][0-9a-fA-F]+$~', $token)) {
  4695. +                            /* treat integer literally */
  4696. +                        } else if (!preg_match('~^' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '(?:' . $this->_mod_regexp . ')*$~', $token)) {
  4697. +                            /* treat as a string, double-quote it escaping quotes */
  4698. +                            $token = '"'.addslashes($token).'"';
  4699. +                        }
  4700. +
  4701. +                        $attrs[$attr_name] = $token;
  4702. +                        $state = 0;
  4703. +                    } else
  4704. +                        $this->_syntax_error("'=' cannot be an attribute value", E_USER_ERROR, __FILE__, __LINE__);
  4705. +                    break;
  4706. +            }
  4707. +            $last_token = $token;
  4708. +        }
  4709. +
  4710. +        if($state != 0) {
  4711. +            if($state == 1) {
  4712. +                $this->_syntax_error("expecting '=' after attribute name '$last_token'", E_USER_ERROR, __FILE__, __LINE__);
  4713. +            } else {
  4714. +                $this->_syntax_error("missing attribute value", E_USER_ERROR, __FILE__, __LINE__);
  4715. +            }
  4716. +        }
  4717. +
  4718. +        $this->_parse_vars_props($attrs);
  4719. +
  4720. +        return $attrs;
  4721. +    }
  4722. +
  4723. +    /**
  4724. +     * compile multiple variables and section properties tokens into
  4725. +     * PHP code
  4726. +     *
  4727. +     * @param array $tokens
  4728. +     */
  4729. +    function _parse_vars_props(&$tokens)
  4730. +    {
  4731. +        foreach($tokens as $key => $val) {
  4732. +            $tokens[$key] = $this->_parse_var_props($val);
  4733. +        }
  4734. +    }
  4735. +
  4736. +    /**
  4737. +     * compile single variable and section properties token into
  4738. +     * PHP code
  4739. +     *
  4740. +     * @param string $val
  4741. +     * @param string $tag_attrs
  4742. +     * @return string
  4743. +     */
  4744. +    function _parse_var_props($val)
  4745. +    {
  4746. +        $val = trim($val);
  4747. +
  4748. +        if(preg_match('~^(' . $this->_obj_call_regexp . '|' . $this->_dvar_regexp . ')(' . $this->_mod_regexp . '*)$~', $val, $match)) {
  4749. +            // $ variable or object
  4750. +            $return = $this->_parse_var($match[1]);
  4751. +            $modifiers = $match[2];
  4752. +            if (!empty($this->default_modifiers) && !preg_match('~(^|\|)smarty:nodefaults($|\|)~',$modifiers)) {
  4753. +                $_default_mod_string = implode('|',(array)$this->default_modifiers);
  4754. +                $modifiers = empty($modifiers) ? $_default_mod_string : $_default_mod_string . '|' . $modifiers;
  4755. +            }
  4756. +            $this->_parse_modifiers($return, $modifiers);
  4757. +            return $return;
  4758. +        } elseif (preg_match('~^' . $this->_db_qstr_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) {
  4759. +                // double quoted text
  4760. +                preg_match('~^(' . $this->_db_qstr_regexp . ')('. $this->_mod_regexp . '*)$~', $val, $match);
  4761. +                $return = $this->_expand_quoted_text($match[1]);
  4762. +                if($match[2] != '') {
  4763. +                    $this->_parse_modifiers($return, $match[2]);
  4764. +                }
  4765. +                return $return;
  4766. +            }
  4767. +        elseif(preg_match('~^' . $this->_num_const_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) {
  4768. +                // numerical constant
  4769. +                preg_match('~^(' . $this->_num_const_regexp . ')('. $this->_mod_regexp . '*)$~', $val, $match);
  4770. +                if($match[2] != '') {
  4771. +                    $this->_parse_modifiers($match[1], $match[2]);
  4772. +                    return $match[1];
  4773. +                }
  4774. +            }
  4775. +        elseif(preg_match('~^' . $this->_si_qstr_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) {
  4776. +                // single quoted text
  4777. +                preg_match('~^(' . $this->_si_qstr_regexp . ')('. $this->_mod_regexp . '*)$~', $val, $match);
  4778. +                if($match[2] != '') {
  4779. +                    $this->_parse_modifiers($match[1], $match[2]);
  4780. +                    return $match[1];
  4781. +                }
  4782. +            }
  4783. +        elseif(preg_match('~^' . $this->_cvar_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) {
  4784. +                // config var
  4785. +                return $this->_parse_conf_var($val);
  4786. +            }
  4787. +        elseif(preg_match('~^' . $this->_svar_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) {
  4788. +                // section var
  4789. +                return $this->_parse_section_prop($val);
  4790. +            }
  4791. +        elseif(!in_array($val, $this->_permitted_tokens) && !is_numeric($val)) {
  4792. +            // literal string
  4793. +            return $this->_expand_quoted_text('"' . strtr($val, array('\\' => '\\\\', '"' => '\\"')) .'"');
  4794. +        }
  4795. +        return $val;
  4796. +    }
  4797. +
  4798. +    /**
  4799. +     * expand quoted text with embedded variables
  4800. +     *
  4801. +     * @param string $var_expr
  4802. +     * @return string
  4803. +     */
  4804. +    function _expand_quoted_text($var_expr)
  4805. +    {
  4806. +        // if contains unescaped $, expand it
  4807. +        if(preg_match_all('~(?:\`(?<!\\\\)\$' . $this->_dvar_guts_regexp . '(?:' . $this->_obj_ext_regexp . ')*\`)|(?:(?<!\\\\)\$\w+(\[[a-zA-Z0-9]+\])*)~', $var_expr, $_match)) {
  4808. +            $_match = $_match[0];
  4809. +            $_replace = array();
  4810. +            foreach($_match as $_var) {
  4811. +                $_replace[$_var] = '".(' . $this->_parse_var(str_replace('`','',$_var)) . ')."';
  4812. +            }
  4813. +            $var_expr = strtr($var_expr, $_replace);
  4814. +            $_return = preg_replace('~\.""|(?<!\\\\)""\.~', '', $var_expr);
  4815. +        } else {
  4816. +            $_return = $var_expr;
  4817. +        }
  4818. +        // replace double quoted literal string with single quotes
  4819. +        $_return = preg_replace('~^"([\s\w]+)"$~',"'\'",$_return);
  4820. +        return $_return;
  4821. +    }
  4822. +
  4823. +    /**
  4824. +     * parse variable expression into PHP code
  4825. +     *
  4826. +     * @param string $var_expr
  4827. +     * @param string $output
  4828. +     * @return string
  4829. +     */
  4830. +    function _parse_var($var_expr)
  4831. +    {
  4832. +        $_has_math = false;
  4833. +        $_math_vars = preg_split('~('.$this->_dvar_math_regexp.'|'.$this->_qstr_regexp.')~', $var_expr, -1, PREG_SPLIT_DELIM_CAPTURE);
  4834. +
  4835. +        if(count($_math_vars) > 1) {
  4836. +            $_first_var = "";
  4837. +            $_complete_var = "";
  4838. +            $_output = "";
  4839. +            // simple check if there is any math, to stop recursion (due to modifiers with "xx % yy" as parameter)
  4840. +            foreach($_math_vars as $_k => $_math_var) {
  4841. +                $_math_var = $_math_vars[$_k];
  4842. +
  4843. +                if(!empty($_math_var) || is_numeric($_math_var)) {
  4844. +                    // hit a math operator, so process the stuff which came before it
  4845. +                    if(preg_match('~^' . $this->_dvar_math_regexp . '$~', $_math_var)) {
  4846. +                        $_has_math = true;
  4847. +                        if(!empty($_complete_var) || is_numeric($_complete_var)) {
  4848. +                            $_output .= $this->_parse_var($_complete_var);
  4849. +                        }
  4850. +
  4851. +                        // just output the math operator to php
  4852. +                        $_output .= $_math_var;
  4853. +
  4854. +                        if(empty($_first_var))
  4855. +                            $_first_var = $_complete_var;
  4856. +
  4857. +                        $_complete_var = "";
  4858. +                    } else {
  4859. +                        $_complete_var .= $_math_var;
  4860. +                    }
  4861. +                }
  4862. +            }
  4863. +            if($_has_math) {
  4864. +                if(!empty($_complete_var) || is_numeric($_complete_var))
  4865. +                    $_output .= $this->_parse_var($_complete_var);
  4866. +
  4867. +                // get the modifiers working (only the last var from math + modifier is left)
  4868. +                $var_expr = $_complete_var;
  4869. +            }
  4870. +        }
  4871. +
  4872. +        // prevent cutting of first digit in the number (we _definitly_ got a number if the first char is a digit)
  4873. +        if(is_numeric(substr($var_expr, 0, 1)))
  4874. +            $_var_ref = $var_expr;
  4875. +        else
  4876. +            $_var_ref = substr($var_expr, 1);
  4877. +        
  4878. +        if(!$_has_math) {
  4879. +            
  4880. +            // get [foo] and .foo and ->foo and (...) pieces
  4881. +            preg_match_all('~(?:^\w+)|' . $this->_obj_params_regexp . '|(?:' . $this->_var_bracket_regexp . ')|->\$?\w+|\.\$?\w+|\S+~', $_var_ref, $match);
  4882. +                        
  4883. +            $_indexes = $match[0];
  4884. +            $_var_name = array_shift($_indexes);
  4885. +
  4886. +            /* Handle $smarty.* variable references as a special case. */
  4887. +            if ($_var_name == 'smarty') {
  4888. +                /*
  4889. +                 * If the reference could be compiled, use the compiled output;
  4890. +                 * otherwise, fall back on the $smarty variable generated at
  4891. +                 * run-time.
  4892. +                 */
  4893. +                if (($smarty_ref = $this->_compile_smarty_ref($_indexes)) !== null) {
  4894. +                    $_output = $smarty_ref;
  4895. +                } else {
  4896. +                    $_var_name = substr(array_shift($_indexes), 1);
  4897. +                    $_output = "\$this->_smarty_vars['$_var_name']";
  4898. +                }
  4899. +            } elseif(is_numeric($_var_name) && is_numeric(substr($var_expr, 0, 1))) {
  4900. +                // because . is the operator for accessing arrays thru inidizes we need to put it together again for floating point numbers
  4901. +                if(count($_indexes) > 0)
  4902. +                {
  4903. +                    $_var_name .= implode("", $_indexes);
  4904. +                    $_indexes = array();
  4905. +                }
  4906. +                $_output = $_var_name;
  4907. +            } else {
  4908. +                $_output = "\$this->_tpl_vars['$_var_name']";
  4909. +            }
  4910. +
  4911. +            foreach ($_indexes as $_index) {
  4912. +                if (substr($_index, 0, 1) == '[') {
  4913. +                    $_index = substr($_index, 1, -1);
  4914. +                    if (is_numeric($_index)) {
  4915. +                        $_output .= "[$_index]";
  4916. +                    } elseif (substr($_index, 0, 1) == '$') {
  4917. +                        if (strpos($_index, '.') !== false) {
  4918. +                            $_output .= '[' . $this->_parse_var($_index) . ']';
  4919. +                        } else {
  4920. +                            $_output .= "[\$this->_tpl_vars['" . substr($_index, 1) . "']]";
  4921. +                        }
  4922. +                    } else {
  4923. +                        $_var_parts = explode('.', $_index);
  4924. +                        $_var_section = $_var_parts[0];
  4925. +                        $_var_section_prop = isset($_var_parts[1]) ? $_var_parts[1] : 'index';
  4926. +                        $_output .= "[\$this->_sections['$_var_section']['$_var_section_prop']]";
  4927. +                    }
  4928. +                } else if (substr($_index, 0, 1) == '.') {
  4929. +                    if (substr($_index, 1, 1) == '$')
  4930. +                        $_output .= "[\$this->_tpl_vars['" . substr($_index, 2) . "']]";
  4931. +                    else
  4932. +                        $_output .= "['" . substr($_index, 1) . "']";
  4933. +                } else if (substr($_index,0,2) == '->') {
  4934. +                    if(substr($_index,2,2) == '__') {
  4935. +                        $this->_syntax_error('call to internal object members is not allowed', E_USER_ERROR, __FILE__, __LINE__);
  4936. +                    } elseif($this->security && substr($_index, 2, 1) == '_') {
  4937. +                        $this->_syntax_error('(secure) call to private object member is not allowed', E_USER_ERROR, __FILE__, __LINE__);
  4938. +                    } elseif (substr($_index, 2, 1) == '$') {
  4939. +                        if ($this->security) {
  4940. +                            $this->_syntax_error('(secure) call to dynamic object member is not allowed', E_USER_ERROR, __FILE__, __LINE__);
  4941. +                        } else {
  4942. +                            $_output .= '->{(($_var=$this->_tpl_vars[\''.substr($_index,3).'\']) && substr($_var,0,2)!=\'__\') ? $_var : $this->trigger_error("cannot access property \\"$_var\\"")}';
  4943. +                        }
  4944. +                    } else {
  4945. +                        $_output .= $_index;
  4946. +                    }
  4947. +                } elseif (substr($_index, 0, 1) == '(') {
  4948. +                    $_index = $this->_parse_parenth_args($_index);
  4949. +                    $_output .= $_index;
  4950. +                } else {
  4951. +                    $_output .= $_index;
  4952. +                }
  4953. +            }
  4954. +        }
  4955. +
  4956. +        return $_output;
  4957. +    }
  4958. +
  4959. +    /**
  4960. +     * parse arguments in function call parenthesis
  4961. +     *
  4962. +     * @param string $parenth_args
  4963. +     * @return string
  4964. +     */
  4965. +    function _parse_parenth_args($parenth_args)
  4966. +    {
  4967. +        preg_match_all('~' . $this->_param_regexp . '~',$parenth_args, $match);
  4968. +        $orig_vals = $match = $match[0];
  4969. +        $this->_parse_vars_props($match);
  4970. +        $replace = array();
  4971. +        for ($i = 0, $count = count($match); $i < $count; $i++) {
  4972. +            $replace[$orig_vals[$i]] = $match[$i];
  4973. +        }
  4974. +        return strtr($parenth_args, $replace);
  4975. +    }
  4976. +
  4977. +    /**
  4978. +     * parse configuration variable expression into PHP code
  4979. +     *
  4980. +     * @param string $conf_var_expr
  4981. +     */
  4982. +    function _parse_conf_var($conf_var_expr)
  4983. +    {
  4984. +        $parts = explode('|', $conf_var_expr, 2);
  4985. +        $var_ref = $parts[0];
  4986. +        $modifiers = isset($parts[1]) ? $parts[1] : '';
  4987. +
  4988. +        $var_name = substr($var_ref, 1, -1);
  4989. +
  4990. +        $output = "\$this->_config[0]['vars']['$var_name']";
  4991. +
  4992. +        $this->_parse_modifiers($output, $modifiers);
  4993. +
  4994. +        return $output;
  4995. +    }
  4996. +
  4997. +    /**
  4998. +     * parse section property expression into PHP code
  4999. +     *
  5000. +     * @param string $section_prop_expr
  5001. +     * @return string
  5002. +     */
  5003. +    function _parse_section_prop($section_prop_expr)
  5004. +    {
  5005. +        $parts = explode('|', $section_prop_expr, 2);
  5006. +        $var_ref = $parts[0];
  5007. +        $modifiers = isset($parts[1]) ? $parts[1] : '';
  5008. +
  5009. +        preg_match('!%(\w+)\.(\w+)%!', $var_ref, $match);
  5010. +        $section_name = $match[1];
  5011. +        $prop_name = $match[2];
  5012. +
  5013. +        $output = "\$this->_sections['$section_name']['$prop_name']";
  5014. +
  5015. +        $this->_parse_modifiers($output, $modifiers);
  5016. +
  5017. +        return $output;
  5018. +    }
  5019. +
  5020. +
  5021. +    /**
  5022. +     * parse modifier chain into PHP code
  5023. +     *
  5024. +     * sets $output to parsed modified chain
  5025. +     * @param string $output
  5026. +     * @param string $modifier_string
  5027. +     */
  5028. +    function _parse_modifiers(&$output, $modifier_string)
  5029. +    {
  5030. +        preg_match_all('~\|(@?\w+)((?>:(?:'. $this->_qstr_regexp . '|[^|]+))*)~', '|' . $modifier_string, $_match);
  5031. +        list(, $_modifiers, $modifier_arg_strings) = $_match;
  5032. +
  5033. +        for ($_i = 0, $_for_max = count($_modifiers); $_i < $_for_max; $_i++) {
  5034. +            $_modifier_name = $_modifiers[$_i];
  5035. +
  5036. +            if($_modifier_name == 'smarty') {
  5037. +                // skip smarty modifier
  5038. +                continue;
  5039. +            }
  5040. +
  5041. +            preg_match_all('~:(' . $this->_qstr_regexp . '|[^:]+)~', $modifier_arg_strings[$_i], $_match);
  5042. +            $_modifier_args = $_match[1];
  5043. +
  5044. +            if (substr($_modifier_name, 0, 1) == '@') {
  5045. +                $_map_array = false;
  5046. +                $_modifier_name = substr($_modifier_name, 1);
  5047. +            } else {
  5048. +                $_map_array = true;
  5049. +            }
  5050. +
  5051. +            if (empty($this->_plugins['modifier'][$_modifier_name])
  5052. +                && !$this->_get_plugin_filepath('modifier', $_modifier_name)
  5053. +                && function_exists($_modifier_name)) {
  5054. +                if ($this->security && !in_array($_modifier_name, $this->security_settings['MODIFIER_FUNCS'])) {
  5055. +                    $this->_trigger_fatal_error("[plugin] (secure mode) modifier '$_modifier_name' is not allowed" , $this->_current_file, $this->_current_line_no, __FILE__, __LINE__);
  5056. +                } else {
  5057. +                    $this->_plugins['modifier'][$_modifier_name] = array($_modifier_name,  null, null, false);
  5058. +                }
  5059. +            }
  5060. +            $this->_add_plugin('modifier', $_modifier_name);
  5061. +
  5062. +            $this->_parse_vars_props($_modifier_args);
  5063. +
  5064. +            if($_modifier_name == 'default') {
  5065. +                // supress notifications of default modifier vars and args
  5066. +                if(substr($output, 0, 1) == '$') {
  5067. +                    $output = '@' . $output;
  5068. +                }
  5069. +                if(isset($_modifier_args[0]) && substr($_modifier_args[0], 0, 1) == '$') {
  5070. +                    $_modifier_args[0] = '@' . $_modifier_args[0];
  5071. +                }
  5072. +            }
  5073. +            if (count($_modifier_args) > 0)
  5074. +                $_modifier_args = ', '.implode(', ', $_modifier_args);
  5075. +            else
  5076. +                $_modifier_args = '';
  5077. +
  5078. +            if ($_map_array) {
  5079. +                $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))";
  5080. +
  5081. +            } else {
  5082. +
  5083. +                $output = $this->_compile_plugin_call('modifier', $_modifier_name)."($output$_modifier_args)";
  5084. +
  5085. +            }
  5086. +        }
  5087. +    }
  5088. +
  5089. +
  5090. +    /**
  5091. +     * add plugin
  5092. +     *
  5093. +     * @param string $type
  5094. +     * @param string $name
  5095. +     * @param boolean? $delayed_loading
  5096. +     */
  5097. +    function _add_plugin($type, $name, $delayed_loading = null)
  5098. +    {
  5099. +        if (!isset($this->_plugin_info[$type])) {
  5100. +            $this->_plugin_info[$type] = array();
  5101. +        }
  5102. +        if (!isset($this->_plugin_info[$type][$name])) {
  5103. +            $this->_plugin_info[$type][$name] = array($this->_current_file,
  5104. +                                                      $this->_current_line_no,
  5105. +                                                      $delayed_loading);
  5106. +        }
  5107. +    }
  5108. +
  5109. +
  5110. +    /**
  5111. +     * Compiles references of type $smarty.foo
  5112. +     *
  5113. +     * @param string $indexes
  5114. +     * @return string
  5115. +     */
  5116. +    function _compile_smarty_ref(&$indexes)
  5117. +    {
  5118. +        /* Extract the reference name. */
  5119. +        $_ref = substr($indexes[0], 1);
  5120. +        foreach($indexes as $_index_no=>$_index) {
  5121. +            if (substr($_index, 0, 1) != '.' && $_index_no<2 || !preg_match('~^(\.|\[|->)~', $_index)) {
  5122. +                $this->_syntax_error('$smarty' . implode('', array_slice($indexes, 0, 2)) . ' is an invalid reference', E_USER_ERROR, __FILE__, __LINE__);
  5123. +            }
  5124. +        }
  5125. +
  5126. +        switch ($_ref) {
  5127. +            case 'now':
  5128. +                $compiled_ref = 'time()';
  5129. +                $_max_index = 1;
  5130. +                break;
  5131. +
  5132. +            case 'foreach':
  5133. +                array_shift($indexes);
  5134. +                $_var = $this->_parse_var_props(substr($indexes[0], 1));
  5135. +                $_propname = substr($indexes[1], 1);
  5136. +                $_max_index = 1;
  5137. +                switch ($_propname) {
  5138. +                    case 'index':
  5139. +                        array_shift($indexes);
  5140. +                        $compiled_ref = "(\$this->_foreach[$_var]['iteration']-1)";
  5141. +                        break;
  5142. +                        
  5143. +                    case 'first':
  5144. +                        array_shift($indexes);
  5145. +                        $compiled_ref = "(\$this->_foreach[$_var]['iteration'] <= 1)";
  5146. +                        break;
  5147. +
  5148. +                    case 'last':
  5149. +                        array_shift($indexes);
  5150. +                        $compiled_ref = "(\$this->_foreach[$_var]['iteration'] == \$this->_foreach[$_var]['total'])";
  5151. +                        break;
  5152. +                        
  5153. +                    case 'show':
  5154. +                        array_shift($indexes);
  5155. +                        $compiled_ref = "(\$this->_foreach[$_var]['total'] > 0)";
  5156. +                        break;
  5157. +                        
  5158. +                    default:
  5159. +                        unset($_max_index);
  5160. +                        $compiled_ref = "\$this->_foreach[$_var]";
  5161. +                }
  5162. +                break;
  5163. +
  5164. +            case 'section':
  5165. +                array_shift($indexes);
  5166. +                $_var = $this->_parse_var_props(substr($indexes[0], 1));
  5167. +                $compiled_ref = "\$this->_sections[$_var]";
  5168. +                break;
  5169. +
  5170. +            case 'get':
  5171. +                if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) {
  5172. +                    $this->_syntax_error("(secure mode) super global access not permitted",
  5173. +                                         E_USER_WARNING, __FILE__, __LINE__);
  5174. +                    return;
  5175. +                }
  5176. +                $compiled_ref = "\$_GET";
  5177. +                break;
  5178. +
  5179. +            case 'post':
  5180. +                if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) {
  5181. +                    $this->_syntax_error("(secure mode) super global access not permitted",
  5182. +                                         E_USER_WARNING, __FILE__, __LINE__);
  5183. +                    return;
  5184. +                }
  5185. +                $compiled_ref = "\$_POST";
  5186. +                break;
  5187. +
  5188. +            case 'cookies':
  5189. +                if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) {
  5190. +                    $this->_syntax_error("(secure mode) super global access not permitted",
  5191. +                                         E_USER_WARNING, __FILE__, __LINE__);
  5192. +                    return;
  5193. +                }
  5194. +                $compiled_ref = "\$_COOKIE";
  5195. +                break;
  5196. +
  5197. +            case 'env':
  5198. +                if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) {
  5199. +                    $this->_syntax_error("(secure mode) super global access not permitted",
  5200. +                                         E_USER_WARNING, __FILE__, __LINE__);
  5201. +                    return;
  5202. +                }
  5203. +                $compiled_ref = "\$_ENV";
  5204. +                break;
  5205. +
  5206. +            case 'server':
  5207. +                if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) {
  5208. +                    $this->_syntax_error("(secure mode) super global access not permitted",
  5209. +                                         E_USER_WARNING, __FILE__, __LINE__);
  5210. +                    return;
  5211. +                }
  5212. +                $compiled_ref = "\$_SERVER";
  5213. +                break;
  5214. +
  5215. +            case 'session':
  5216. +                if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) {
  5217. +                    $this->_syntax_error("(secure mode) super global access not permitted",
  5218. +                                         E_USER_WARNING, __FILE__, __LINE__);
  5219. +                    return;
  5220. +                }
  5221. +                $compiled_ref = "\$_SESSION";
  5222. +                break;
  5223. +
  5224. +            /*
  5225. +             * These cases are handled either at run-time or elsewhere in the
  5226. +             * compiler.
  5227. +             */
  5228. +            case 'request':
  5229. +                if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) {
  5230. +                    $this->_syntax_error("(secure mode) super global access not permitted",
  5231. +                                         E_USER_WARNING, __FILE__, __LINE__);
  5232. +                    return;
  5233. +                }
  5234. +                if ($this->request_use_auto_globals) {
  5235. +                    $compiled_ref = "\$_REQUEST";
  5236. +                    break;
  5237. +                } else {
  5238. +                    $this->_init_smarty_vars = true;
  5239. +                }
  5240. +                return null;
  5241. +
  5242. +            case 'capture':
  5243. +                return null;
  5244. +
  5245. +            case 'template':
  5246. +                $compiled_ref = "'$this->_current_file'";
  5247. +                $_max_index = 1;
  5248. +                break;
  5249. +
  5250. +            case 'version':
  5251. +                $compiled_ref = "'$this->_version'";
  5252. +                $_max_index = 1;
  5253. +                break;
  5254. +
  5255. +            case 'const':
  5256. +                if ($this->security && !$this->security_settings['ALLOW_CONSTANTS']) {
  5257. +                    $this->_syntax_error("(secure mode) constants not permitted",
  5258. +                                         E_USER_WARNING, __FILE__, __LINE__);
  5259. +                    return;
  5260. +                }
  5261. +                array_shift($indexes);
  5262. +                if (preg_match('!^\.\w+$!', $indexes[0])) {
  5263. +                    $compiled_ref = '@' . substr($indexes[0], 1);
  5264. +                } else {
  5265. +                    $_val = $this->_parse_var_props(substr($indexes[0], 1));
  5266. +                    $compiled_ref = '@constant(' . $_val . ')';
  5267. +                }
  5268. +                $_max_index = 1;
  5269. +                break;
  5270. +
  5271. +            case 'config':
  5272. +                $compiled_ref = "\$this->_config[0]['vars']";
  5273. +                $_max_index = 3;
  5274. +                break;
  5275. +
  5276. +            case 'ldelim':
  5277. +                $compiled_ref = "'$this->left_delimiter'";
  5278. +                break;
  5279. +
  5280. +            case 'rdelim':
  5281. +                $compiled_ref = "'$this->right_delimiter'";
  5282. +                break;
  5283. +                
  5284. +            default:
  5285. +                $this->_syntax_error('$smarty.' . $_ref . ' is an unknown reference', E_USER_ERROR, __FILE__, __LINE__);
  5286. +                break;
  5287. +        }
  5288. +
  5289. +        if (isset($_max_index) && count($indexes) > $_max_index) {
  5290. +            $this->_syntax_error('$smarty' . implode('', $indexes) .' is an invalid reference', E_USER_ERROR, __FILE__, __LINE__);
  5291. +        }
  5292. +
  5293. +        array_shift($indexes);
  5294. +        return $compiled_ref;
  5295. +    }
  5296. +
  5297. +    /**
  5298. +     * compiles call to plugin of type $type with name $name
  5299. +     * returns a string containing the function-name or method call
  5300. +     * without the paramter-list that would have follow to make the
  5301. +     * call valid php-syntax
  5302. +     *
  5303. +     * @param string $type
  5304. +     * @param string $name
  5305. +     * @return string
  5306. +     */
  5307. +    function _compile_plugin_call($type, $name) {
  5308. +        if (isset($this->_plugins[$type][$name])) {
  5309. +            /* plugin loaded */
  5310. +            if (is_array($this->_plugins[$type][$name][0])) {
  5311. +                return ((is_object($this->_plugins[$type][$name][0][0])) ?
  5312. +                        "\$this->_plugins['$type']['$name'][0][0]->"    /* method callback */
  5313. +                        : (string)($this->_plugins[$type][$name][0][0]).'::'    /* class callback */
  5314. +                       ). $this->_plugins[$type][$name][0][1];
  5315. +
  5316. +            } else {
  5317. +                /* function callback */
  5318. +                return $this->_plugins[$type][$name][0];
  5319. +
  5320. +            }
  5321. +        } else {
  5322. +            /* plugin not loaded -> auto-loadable-plugin */
  5323. +            return 'smarty_'.$type.'_'.$name;
  5324. +
  5325. +        }
  5326. +    }
  5327. +
  5328. +    /**
  5329. +     * load pre- and post-filters
  5330. +     */
  5331. +    function _load_filters()
  5332. +    {
  5333. +        if (count($this->_plugins['prefilter']) > 0) {
  5334. +            foreach ($this->_plugins['prefilter'] as $filter_name => $prefilter) {
  5335. +                if ($prefilter === false) {
  5336. +                    unset($this->_plugins['prefilter'][$filter_name]);
  5337. +                    $_params = array('plugins' => array(array('prefilter', $filter_name, null, null, false)));
  5338. +                    require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');
  5339. +                    smarty_core_load_plugins($_params, $this);
  5340. +                }
  5341. +            }
  5342. +        }
  5343. +        if (count($this->_plugins['postfilter']) > 0) {
  5344. +            foreach ($this->_plugins['postfilter'] as $filter_name => $postfilter) {
  5345. +                if ($postfilter === false) {
  5346. +                    unset($this->_plugins['postfilter'][$filter_name]);
  5347. +                    $_params = array('plugins' => array(array('postfilter', $filter_name, null, null, false)));
  5348. +                    require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');
  5349. +                    smarty_core_load_plugins($_params, $this);
  5350. +                }
  5351. +            }
  5352. +        }
  5353. +    }
  5354. +
  5355. +
  5356. +    /**
  5357. +     * Quote subpattern references
  5358. +     *
  5359. +     * @param string $string
  5360. +     * @return string
  5361. +     */
  5362. +    function _quote_replace($string)
  5363. +    {
  5364. +        return strtr($string, array('\\' => '\\\\', '$' => '\\$'));
  5365. +    }
  5366. +
  5367. +    /**
  5368. +     * display Smarty syntax error
  5369. +     *
  5370. +     * @param string $error_msg
  5371. +     * @param integer $error_type
  5372. +     * @param string $file
  5373. +     * @param integer $line
  5374. +     */
  5375. +    function _syntax_error($error_msg, $error_type = E_USER_ERROR, $file=null, $line=null)
  5376. +    {
  5377. +        $this->_trigger_fatal_error("syntax error: $error_msg", $this->_current_file, $this->_current_line_no, $file, $line, $error_type);
  5378. +    }
  5379. +
  5380. +
  5381. +    /**
  5382. +     * check if the compilation changes from cacheable to
  5383. +     * non-cacheable state with the beginning of the current
  5384. +     * plugin. return php-code to reflect the transition.
  5385. +     * @return string
  5386. +     */
  5387. +    function _push_cacheable_state($type, $name) {
  5388. +        $_cacheable = !isset($this->_plugins[$type][$name]) || $this->_plugins[$type][$name][4];
  5389. +        if ($_cacheable
  5390. +            || 0<$this->_cacheable_state++) return '';
  5391. +        if (!isset($this->_cache_serial)) $this->_cache_serial = md5(uniqid('Smarty'));
  5392. +        $_ret = 'if ($this->caching && !$this->_cache_including): echo \'{nocache:'
  5393. +            . $this->_cache_serial . '#' . $this->_nocache_count
  5394. +            . '}\'; endif;';
  5395. +        return $_ret;
  5396. +    }
  5397. +
  5398. +
  5399. +    /**
  5400. +     * check if the compilation changes from non-cacheable to
  5401. +     * cacheable state with the end of the current plugin return
  5402. +     * php-code to reflect the transition.
  5403. +     * @return string
  5404. +     */
  5405. +    function _pop_cacheable_state($type, $name) {
  5406. +        $_cacheable = !isset($this->_plugins[$type][$name]) || $this->_plugins[$type][$name][4];
  5407. +        if ($_cacheable
  5408. +            || --$this->_cacheable_state>0) return '';
  5409. +        return 'if ($this->caching && !$this->_cache_including): echo \'{/nocache:'
  5410. +            . $this->_cache_serial . '#' . ($this->_nocache_count++)
  5411. +            . '}\'; endif;';
  5412. +    }
  5413. +
  5414. +
  5415. +    /**
  5416. +     * push opening tag-name, file-name and line-number on the tag-stack
  5417. +     * @param string the opening tag's name
  5418. +     */
  5419. +    function _push_tag($open_tag)
  5420. +    {
  5421. +        array_push($this->_tag_stack, array($open_tag, $this->_current_line_no));
  5422. +    }
  5423. +
  5424. +    /**
  5425. +     * pop closing tag-name
  5426. +     * raise an error if this stack-top doesn't match with the closing tag
  5427. +     * @param string the closing tag's name
  5428. +     * @return string the opening tag's name
  5429. +     */
  5430. +    function _pop_tag($close_tag)
  5431. +    {
  5432. +        $message = '';
  5433. +        if (count($this->_tag_stack)>0) {
  5434. +            list($_open_tag, $_line_no) = array_pop($this->_tag_stack);
  5435. +            if ($close_tag == $_open_tag) {
  5436. +                return $_open_tag;
  5437. +            }
  5438. +            if ($close_tag == 'if' && ($_open_tag == 'else' || $_open_tag == 'elseif' )) {
  5439. +                return $this->_pop_tag($close_tag);
  5440. +            }
  5441. +            if ($close_tag == 'section' && $_open_tag == 'sectionelse') {
  5442. +                $this->_pop_tag($close_tag);
  5443. +                return $_open_tag;
  5444. +            }
  5445. +            if ($close_tag == 'foreach' && $_open_tag == 'foreachelse') {
  5446. +                $this->_pop_tag($close_tag);
  5447. +                return $_open_tag;
  5448. +            }
  5449. +            if ($_open_tag == 'else' || $_open_tag == 'elseif') {
  5450. +                $_open_tag = 'if';
  5451. +            } elseif ($_open_tag == 'sectionelse') {
  5452. +                $_open_tag = 'section';
  5453. +            } elseif ($_open_tag == 'foreachelse') {
  5454. +                $_open_tag = 'foreach';
  5455. +            }
  5456. +            $message = " expected {/$_open_tag} (opened line $_line_no).";
  5457. +        }
  5458. +        $this->_syntax_error("mismatched tag {/$close_tag}.$message",
  5459. +                             E_USER_ERROR, __FILE__, __LINE__);
  5460. +    }
  5461. +
  5462. +}
  5463. +
  5464. +/**
  5465. + * compare to values by their string length
  5466. + *
  5467. + * @access private
  5468. + * @param string $a
  5469. + * @param string $b
  5470. + * @return 0|-1|1
  5471. + */
  5472. +function _smarty_sort_length($a, $b)
  5473. +{
  5474. +    if($a == $b)
  5475. +        return 0;
  5476. +
  5477. +    if(strlen($a) == strlen($b))
  5478. +        return ($a > $b) ? -1 : 1;
  5479. +
  5480. +    return (strlen($a) > strlen($b)) ? -1 : 1;
  5481. +}
  5482. +
  5483. +
  5484. +/* vim: set et: */
  5485. +
  5486. +?>
  5487. diff --git a/library/smarty/debug.tpl b/library/smarty/debug.tpl
  5488. new file mode 100644
  5489. --- /dev/null
  5490. +++ b/library/smarty/debug.tpl
  5491. @@ -0,0 +1,157 @@
  5492. +{* Smarty *}
  5493. +{* debug.tpl, last updated version 2.1.0 *}
  5494. +{assign_debug_info}
  5495. +{capture assign=debug_output}
  5496. +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
  5497. +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
  5498. +<head>
  5499. +    <title>Smarty Debug Console</title>
  5500. +{literal}
  5501. +<style type="text/css">
  5502. +/* <![CDATA[ */
  5503. +body, h1, h2, td, th, p {
  5504. +    font-family: sans-serif;
  5505. +    font-weight: normal;
  5506. +    font-size: 0.9em;
  5507. +    margin: 1px;
  5508. +    padding: 0;
  5509. +}
  5510. +
  5511. +h1 {
  5512. +    margin: 0;
  5513. +    text-align: left;
  5514. +    padding: 2px;
  5515. +    background-color: #f0c040;
  5516. +    color:  black;
  5517. +    font-weight: bold;
  5518. +    font-size: 1.2em;
  5519. + }
  5520. +
  5521. +h2 {
  5522. +    background-color: #9B410E;
  5523. +    color: white;
  5524. +    text-align: left;
  5525. +    font-weight: bold;
  5526. +    padding: 2px;
  5527. +    border-top: 1px solid black;
  5528. +}
  5529. +
  5530. +body {
  5531. +    background: black;
  5532. +}
  5533. +
  5534. +p, table, div {
  5535. +    background: #f0ead8;
  5536. +}
  5537. +
  5538. +p {
  5539. +    margin: 0;
  5540. +    font-style: italic;
  5541. +    text-align: center;
  5542. +}
  5543. +
  5544. +table {
  5545. +    width: 100%;
  5546. +}
  5547. +
  5548. +th, td {
  5549. +    font-family: monospace;
  5550. +    vertical-align: top;
  5551. +    text-align: left;
  5552. +    width: 50%;
  5553. +}
  5554. +
  5555. +td {
  5556. +    color: green;
  5557. +}
  5558. +
  5559. +.odd {
  5560. +    background-color: #eeeeee;
  5561. +}
  5562. +
  5563. +.even {
  5564. +    background-color: #fafafa;
  5565. +}
  5566. +
  5567. +.exectime {
  5568. +    font-size: 0.8em;
  5569. +    font-style: italic;
  5570. +}
  5571. +
  5572. +#table_assigned_vars th {
  5573. +    color: blue;
  5574. +}
  5575. +
  5576. +#table_config_vars th {
  5577. +    color: maroon;
  5578. +}
  5579. +/* ]]> */
  5580. +</style>
  5581. +{/literal}
  5582. +</head>
  5583. +<body>
  5584. +
  5585. +<h1>Smarty Debug Console</h1>
  5586. +
  5587. +<h2>included templates &amp; config files (load time in seconds)</h2>
  5588. +
  5589. +<div>
  5590. +{section name=templates loop=$_debug_tpls}
  5591. +    {section name=indent loop=$_debug_tpls[templates].depth}&nbsp;&nbsp;&nbsp;{/section}
  5592. +    <font color={if $_debug_tpls[templates].type eq "template"}brown{elseif $_debug_tpls[templates].type eq "insert"}black{else}green{/if}>
  5593. +        {$_debug_tpls[templates].filename|escape:html}</font>
  5594. +    {if isset($_debug_tpls[templates].exec_time)}
  5595. +        <span class="exectime">
  5596. +        ({$_debug_tpls[templates].exec_time|string_format:"%.5f"})
  5597. +        {if %templates.index% eq 0}(total){/if}
  5598. +        </span>
  5599. +    {/if}
  5600. +    <br />
  5601. +{sectionelse}
  5602. +    <p>no templates included</p>
  5603. +{/section}
  5604. +</div>
  5605. +
  5606. +<h2>assigned template variables</h2>
  5607. +
  5608. +<table id="table_assigned_vars">
  5609. +    {section name=vars loop=$_debug_keys}
  5610. +        <tr class="{cycle values="odd,even"}">
  5611. +            <th>{ldelim}${$_debug_keys[vars]|escape:'html'}{rdelim}</th>
  5612. +            <td>{$_debug_vals[vars]|@debug_print_var}</td></tr>
  5613. +    {sectionelse}
  5614. +        <tr><td><p>no template variables assigned</p></td></tr>
  5615. +    {/section}
  5616. +</table>
  5617. +
  5618. +<h2>assigned config file variables (outer template scope)</h2>
  5619. +
  5620. +<table id="table_config_vars">
  5621. +    {section name=config_vars loop=$_debug_config_keys}
  5622. +        <tr class="{cycle values="odd,even"}">
  5623. +            <th>{ldelim}#{$_debug_config_keys[config_vars]|escape:'html'}#{rdelim}</th>
  5624. +            <td>{$_debug_config_vals[config_vars]|@debug_print_var}</td></tr>
  5625. +    {sectionelse}
  5626. +        <tr><td><p>no config vars assigned</p></td></tr>
  5627. +    {/section}
  5628. +</table>
  5629. +</body>
  5630. +</html>
  5631. +{/capture}
  5632. +{if isset($_smarty_debug_output) and $_smarty_debug_output eq "html"}
  5633. +    {$debug_output}
  5634. +{else}
  5635. +<script type="text/javascript">
  5636. +// <![CDATA[
  5637. +    if ( self.name == '' ) {ldelim}
  5638. +       var title = 'Console';
  5639. +    {rdelim}
  5640. +    else {ldelim}
  5641. +       var title = 'Console_' + self.name;
  5642. +    {rdelim}
  5643. +    _smarty_console = window.open("",title.value,"width=680,height=600,resizable,scrollbars=yes");
  5644. +    _smarty_console.document.write('{$debug_output|escape:'javascript'}');
  5645. +    _smarty_console.document.close();
  5646. +// ]]>
  5647. +</script>
  5648. +{/if}
  5649. \ No newline at end of file
  5650. diff --git a/library/smarty/internals/core.assemble_plugin_filepath.php b/library/smarty/internals/core.assemble_plugin_filepath.php
  5651. new file mode 100644
  5652. --- /dev/null
  5653. +++ b/library/smarty/internals/core.assemble_plugin_filepath.php
  5654. @@ -0,0 +1,67 @@
  5655. +<?php
  5656. +/**
  5657. + * Smarty plugin
  5658. + * @package Smarty
  5659. + * @subpackage plugins
  5660. + */
  5661. +
  5662. +/**
  5663. + * assemble filepath of requested plugin
  5664. + *
  5665. + * @param string $type
  5666. + * @param string $name
  5667. + * @return string|false
  5668. + */
  5669. +function smarty_core_assemble_plugin_filepath($params, &$smarty)
  5670. +{
  5671. +    static $_filepaths_cache = array();
  5672. +
  5673. +    $_plugin_filename = $params['type'] . '.' . $params['name'] . '.php';
  5674. +    if (isset($_filepaths_cache[$_plugin_filename])) {
  5675. +        return $_filepaths_cache[$_plugin_filename];
  5676. +    }
  5677. +    $_return = false;
  5678. +
  5679. +    foreach ((array)$smarty->plugins_dir as $_plugin_dir) {
  5680. +
  5681. +        $_plugin_filepath = $_plugin_dir . DIRECTORY_SEPARATOR . $_plugin_filename;
  5682. +
  5683. +        // see if path is relative
  5684. +        if (!preg_match("/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/", $_plugin_dir)) {
  5685. +            $_relative_paths[] = $_plugin_dir;
  5686. +            // relative path, see if it is in the SMARTY_DIR
  5687. +            if (@is_readable(SMARTY_DIR . $_plugin_filepath)) {
  5688. +                $_return = SMARTY_DIR . $_plugin_filepath;
  5689. +                break;
  5690. +            }
  5691. +        }
  5692. +        // try relative to cwd (or absolute)
  5693. +        if (@is_readable($_plugin_filepath)) {
  5694. +            $_return = $_plugin_filepath;
  5695. +            break;
  5696. +        }
  5697. +    }
  5698. +
  5699. +    if($_return === false) {
  5700. +        // still not found, try PHP include_path
  5701. +        if(isset($_relative_paths)) {
  5702. +            foreach ((array)$_relative_paths as $_plugin_dir) {
  5703. +
  5704. +                $_plugin_filepath = $_plugin_dir . DIRECTORY_SEPARATOR . $_plugin_filename;
  5705. +
  5706. +                $_params = array('file_path' => $_plugin_filepath);
  5707. +                require_once(SMARTY_CORE_DIR . 'core.get_include_path.php');
  5708. +                if(smarty_core_get_include_path($_params, $smarty)) {
  5709. +                    $_return = $_params['new_file_path'];
  5710. +                    break;
  5711. +                }
  5712. +            }
  5713. +        }
  5714. +    }
  5715. +    $_filepaths_cache[$_plugin_filename] = $_return;
  5716. +    return $_return;
  5717. +}
  5718. +
  5719. +/* vim: set expandtab: */
  5720. +
  5721. +?>
  5722. diff --git a/library/smarty/internals/core.assign_smarty_interface.php b/library/smarty/internals/core.assign_smarty_interface.php
  5723. new file mode 100644
  5724. --- /dev/null
  5725. +++ b/library/smarty/internals/core.assign_smarty_interface.php
  5726. @@ -0,0 +1,43 @@
  5727. +<?php
  5728. +/**
  5729. + * Smarty plugin
  5730. + * @package Smarty
  5731. + * @subpackage plugins
  5732. + */
  5733. +
  5734. +/**
  5735. + * Smarty assign_smarty_interface core plugin
  5736. + *
  5737. + * Type:     core<br>
  5738. + * Name:     assign_smarty_interface<br>
  5739. + * Purpose:  assign the $smarty interface variable
  5740. + * @param array Format: null
  5741. + * @param Smarty
  5742. + */
  5743. +function smarty_core_assign_smarty_interface($params, &$smarty)
  5744. +{
  5745. +        if (isset($smarty->_smarty_vars) && isset($smarty->_smarty_vars['request'])) {
  5746. +            return;
  5747. +        }
  5748. +
  5749. +        $_globals_map = array('g'  => 'HTTP_GET_VARS',
  5750. +                             'p'  => 'HTTP_POST_VARS',
  5751. +                             'c'  => 'HTTP_COOKIE_VARS',
  5752. +                             's'  => 'HTTP_SERVER_VARS',
  5753. +                             'e'  => 'HTTP_ENV_VARS');
  5754. +
  5755. +        $_smarty_vars_request  = array();
  5756. +
  5757. +        foreach (preg_split('!!', strtolower($smarty->request_vars_order)) as $_c) {
  5758. +            if (isset($_globals_map[$_c])) {
  5759. +                $_smarty_vars_request = array_merge($_smarty_vars_request, $GLOBALS[$_globals_map[$_c]]);
  5760. +            }
  5761. +        }
  5762. +        $_smarty_vars_request = @array_merge($_smarty_vars_request, $GLOBALS['HTTP_SESSION_VARS']);
  5763. +
  5764. +        $smarty->_smarty_vars['request'] = $_smarty_vars_request;
  5765. +}
  5766. +
  5767. +/* vim: set expandtab: */
  5768. +
  5769. +?>
  5770. diff --git a/library/smarty/internals/core.create_dir_structure.php b/library/smarty/internals/core.create_dir_structure.php
  5771. new file mode 100644
  5772. --- /dev/null
  5773. +++ b/library/smarty/internals/core.create_dir_structure.php
  5774. @@ -0,0 +1,79 @@
  5775. +<?php
  5776. +/**
  5777. + * Smarty plugin
  5778. + * @package Smarty
  5779. + * @subpackage plugins
  5780. + */
  5781. +
  5782. +/**
  5783. + * create full directory structure
  5784. + *
  5785. + * @param string $dir
  5786. + */
  5787. +
  5788. +// $dir
  5789. +
  5790. +function smarty_core_create_dir_structure($params, &$smarty)
  5791. +{
  5792. +    if (!file_exists($params['dir'])) {
  5793. +        $_open_basedir_ini = ini_get('open_basedir');
  5794. +
  5795. +        if (DIRECTORY_SEPARATOR=='/') {
  5796. +            /* unix-style paths */
  5797. +            $_dir = $params['dir'];
  5798. +            $_dir_parts = preg_split('!/+!', $_dir, -1, PREG_SPLIT_NO_EMPTY);
  5799. +            $_new_dir = (substr($_dir, 0, 1)=='/') ? '/' : getcwd().'/';
  5800. +            if($_use_open_basedir = !empty($_open_basedir_ini)) {
  5801. +                $_open_basedirs = explode(':', $_open_basedir_ini);
  5802. +            }
  5803. +
  5804. +        } else {
  5805. +            /* other-style paths */
  5806. +            $_dir = str_replace('\\','/', $params['dir']);
  5807. +            $_dir_parts = preg_split('!/+!', $_dir, -1, PREG_SPLIT_NO_EMPTY);
  5808. +            if (preg_match('!^((//)|([a-zA-Z]:/))!', $_dir, $_root_dir)) {
  5809. +                /* leading "//" for network volume, or "[letter]:/" for full path */
  5810. +                $_new_dir = $_root_dir[1];
  5811. +                /* remove drive-letter from _dir_parts */
  5812. +                if (isset($_root_dir[3])) array_shift($_dir_parts);
  5813. +
  5814. +            } else {
  5815. +                $_new_dir = str_replace('\\', '/', getcwd()).'/';
  5816. +
  5817. +            }
  5818. +
  5819. +            if($_use_open_basedir = !empty($_open_basedir_ini)) {
  5820. +                $_open_basedirs = explode(';', str_replace('\\', '/', $_open_basedir_ini));
  5821. +            }
  5822. +
  5823. +        }
  5824. +
  5825. +        /* all paths use "/" only from here */
  5826. +        foreach ($_dir_parts as $_dir_part) {
  5827. +            $_new_dir .= $_dir_part;
  5828. +
  5829. +            if ($_use_open_basedir) {
  5830. +                // do not attempt to test or make directories outside of open_basedir
  5831. +                $_make_new_dir = false;
  5832. +                foreach ($_open_basedirs as $_open_basedir) {
  5833. +                    if (substr($_new_dir, 0, strlen($_open_basedir)) == $_open_basedir) {
  5834. +                        $_make_new_dir = true;
  5835. +                        break;
  5836. +                    }
  5837. +                }
  5838. +            } else {
  5839. +                $_make_new_dir = true;
  5840. +            }
  5841. +
  5842. +            if ($_make_new_dir && !file_exists($_new_dir) && !@mkdir($_new_dir, $smarty->_dir_perms) && !is_dir($_new_dir)) {
  5843. +                $smarty->trigger_error("problem creating directory '" . $_new_dir . "'");
  5844. +                return false;
  5845. +            }
  5846. +            $_new_dir .= '/';
  5847. +        }
  5848. +    }
  5849. +}
  5850. +
  5851. +/* vim: set expandtab: */
  5852. +
  5853. +?>
  5854. diff --git a/library/smarty/internals/core.display_debug_console.php b/library/smarty/internals/core.display_debug_console.php
  5855. new file mode 100644
  5856. --- /dev/null
  5857. +++ b/library/smarty/internals/core.display_debug_console.php
  5858. @@ -0,0 +1,61 @@
  5859. +<?php
  5860. +/**
  5861. + * Smarty plugin
  5862. + * @package Smarty
  5863. + * @subpackage plugins
  5864. + */
  5865. +
  5866. +/**
  5867. + * Smarty debug_console function plugin
  5868. + *
  5869. + * Type:     core<br>
  5870. + * Name:     display_debug_console<br>
  5871. + * Purpose:  display the javascript debug console window
  5872. + * @param array Format: null
  5873. + * @param Smarty
  5874. + */
  5875. +function smarty_core_display_debug_console($params, &$smarty)
  5876. +{
  5877. +    // we must force compile the debug template in case the environment
  5878. +    // changed between separate applications.
  5879. +
  5880. +    if(empty($smarty->debug_tpl)) {
  5881. +        // set path to debug template from SMARTY_DIR
  5882. +        $smarty->debug_tpl = SMARTY_DIR . 'debug.tpl';
  5883. +        if($smarty->security && is_file($smarty->debug_tpl)) {
  5884. +            $smarty->secure_dir[] = realpath($smarty->debug_tpl);
  5885. +        }
  5886. +        $smarty->debug_tpl = 'file:' . SMARTY_DIR . 'debug.tpl';
  5887. +    }
  5888. +
  5889. +    $_ldelim_orig = $smarty->left_delimiter;
  5890. +    $_rdelim_orig = $smarty->right_delimiter;
  5891. +
  5892. +    $smarty->left_delimiter = '{';
  5893. +    $smarty->right_delimiter = '}';
  5894. +
  5895. +    $_compile_id_orig = $smarty->_compile_id;
  5896. +    $smarty->_compile_id = null;
  5897. +
  5898. +    $_compile_path = $smarty->_get_compile_path($smarty->debug_tpl);
  5899. +    if ($smarty->_compile_resource($smarty->debug_tpl, $_compile_path))
  5900. +    {
  5901. +        ob_start();
  5902. +        $smarty->_include($_compile_path);
  5903. +        $_results = ob_get_contents();
  5904. +        ob_end_clean();
  5905. +    } else {
  5906. +        $_results = '';
  5907. +    }
  5908. +
  5909. +    $smarty->_compile_id = $_compile_id_orig;
  5910. +
  5911. +    $smarty->left_delimiter = $_ldelim_orig;
  5912. +    $smarty->right_delimiter = $_rdelim_orig;
  5913. +
  5914. +    return $_results;
  5915. +}
  5916. +
  5917. +/* vim: set expandtab: */
  5918. +
  5919. +?>
  5920. diff --git a/library/smarty/internals/core.get_include_path.php b/library/smarty/internals/core.get_include_path.php
  5921. new file mode 100644
  5922. --- /dev/null
  5923. +++ b/library/smarty/internals/core.get_include_path.php
  5924. @@ -0,0 +1,44 @@
  5925. +<?php
  5926. +/**
  5927. + * Smarty plugin
  5928. + * @package Smarty
  5929. + * @subpackage plugins
  5930. + */
  5931. +
  5932. +/**
  5933. + * Get path to file from include_path
  5934. + *
  5935. + * @param string $file_path
  5936. + * @param string $new_file_path
  5937. + * @return boolean
  5938. + * @staticvar array|null
  5939. + */
  5940. +
  5941. +//  $file_path, &$new_file_path
  5942. +
  5943. +function smarty_core_get_include_path(&$params, &$smarty)
  5944. +{
  5945. +    static $_path_array = null;
  5946. +
  5947. +    if(!isset($_path_array)) {
  5948. +        $_ini_include_path = ini_get('include_path');
  5949. +
  5950. +        if(strstr($_ini_include_path,';')) {
  5951. +            // windows pathnames
  5952. +            $_path_array = explode(';',$_ini_include_path);
  5953. +        } else {
  5954. +            $_path_array = explode(':',$_ini_include_path);
  5955. +        }
  5956. +    }
  5957. +    foreach ($_path_array as $_include_path) {
  5958. +        if (@is_readable($_include_path . DIRECTORY_SEPARATOR . $params['file_path'])) {
  5959. +               $params['new_file_path'] = $_include_path . DIRECTORY_SEPARATOR . $params['file_path'];
  5960. +            return true;
  5961. +        }
  5962. +    }
  5963. +    return false;
  5964. +}
  5965. +
  5966. +/* vim: set expandtab: */
  5967. +
  5968. +?>
  5969. diff --git a/library/smarty/internals/core.get_microtime.php b/library/smarty/internals/core.get_microtime.php
  5970. new file mode 100644
  5971. --- /dev/null
  5972. +++ b/library/smarty/internals/core.get_microtime.php
  5973. @@ -0,0 +1,23 @@
  5974. +<?php
  5975. +/**
  5976. + * Smarty plugin
  5977. + * @package Smarty
  5978. + * @subpackage plugins
  5979. + */
  5980. +
  5981. +/**
  5982. + * Get seconds and microseconds
  5983. + * @return double
  5984. + */
  5985. +function smarty_core_get_microtime($params, &$smarty)
  5986. +{
  5987. +    $mtime = microtime();
  5988. +    $mtime = explode(" ", $mtime);
  5989. +    $mtime = (double)($mtime[1]) + (double)($mtime[0]);
  5990. +    return ($mtime);
  5991. +}
  5992. +
  5993. +
  5994. +/* vim: set expandtab: */
  5995. +
  5996. +?>
  5997. diff --git a/library/smarty/internals/core.get_php_resource.php b/library/smarty/internals/core.get_php_resource.php
  5998. new file mode 100644
  5999. --- /dev/null
  6000. +++ b/library/smarty/internals/core.get_php_resource.php
  6001. @@ -0,0 +1,80 @@
  6002. +<?php
  6003. +/**
  6004. + * Smarty plugin
  6005. + * @package Smarty
  6006. + * @subpackage plugins
  6007. + */
  6008. +
  6009. +/**
  6010. + * Retrieves PHP script resource
  6011. + *
  6012. + * sets $php_resource to the returned resource
  6013. + * @param string $resource
  6014. + * @param string $resource_type
  6015. + * @param  $php_resource
  6016. + * @return boolean
  6017. + */
  6018. +
  6019. +function smarty_core_get_php_resource(&$params, &$smarty)
  6020. +{
  6021. +
  6022. +    $params['resource_base_path'] = $smarty->trusted_dir;
  6023. +    $smarty->_parse_resource_name($params, $smarty);
  6024. +
  6025. +    /*
  6026. +     * Find out if the resource exists.
  6027. +     */
  6028. +
  6029. +    if ($params['resource_type'] == 'file') {
  6030. +        $_readable = false;
  6031. +        if(file_exists($params['resource_name']) && is_readable($params['resource_name'])) {
  6032. +            $_readable = true;
  6033. +        } else {
  6034. +            // test for file in include_path
  6035. +            $_params = array('file_path' => $params['resource_name']);
  6036. +            require_once(SMARTY_CORE_DIR . 'core.get_include_path.php');
  6037. +            if(smarty_core_get_include_path($_params, $smarty)) {
  6038. +                $_include_path = $_params['new_file_path'];
  6039. +                $_readable = true;
  6040. +            }
  6041. +        }
  6042. +    } else if ($params['resource_type'] != 'file') {
  6043. +        $_template_source = null;
  6044. +        $_readable = is_callable($smarty->_plugins['resource'][$params['resource_type']][0][0])
  6045. +            && call_user_func_array($smarty->_plugins['resource'][$params['resource_type']][0][0],
  6046. +                                    array($params['resource_name'], &$_template_source, &$smarty));
  6047. +    }
  6048. +
  6049. +    /*
  6050. +     * Set the error function, depending on which class calls us.
  6051. +     */
  6052. +    if (method_exists($smarty, '_syntax_error')) {
  6053. +        $_error_funcc = '_syntax_error';
  6054. +    } else {
  6055. +        $_error_funcc = 'trigger_error';
  6056. +    }
  6057. +
  6058. +    if ($_readable) {
  6059. +        if ($smarty->security) {
  6060. +            require_once(SMARTY_CORE_DIR . 'core.is_trusted.php');
  6061. +            if (!smarty_core_is_trusted($params, $smarty)) {
  6062. +                $smarty->$_error_funcc('(secure mode) ' . $params['resource_type'] . ':' . $params['resource_name'] . ' is not trusted');
  6063. +                return false;
  6064. +            }
  6065. +        }
  6066. +    } else {
  6067. +        $smarty->$_error_funcc($params['resource_type'] . ':' . $params['resource_name'] . ' is not readable');
  6068. +        return false;
  6069. +    }
  6070. +
  6071. +    if ($params['resource_type'] == 'file') {
  6072. +        $params['php_resource'] = $params['resource_name'];
  6073. +    } else {
  6074. +        $params['php_resource'] = $_template_source;
  6075. +    }
  6076. +    return true;
  6077. +}
  6078. +
  6079. +/* vim: set expandtab: */
  6080. +
  6081. +?>
  6082. diff --git a/library/smarty/internals/core.is_secure.php b/library/smarty/internals/core.is_secure.php
  6083. new file mode 100644
  6084. --- /dev/null
  6085. +++ b/library/smarty/internals/core.is_secure.php
  6086. @@ -0,0 +1,59 @@
  6087. +<?php
  6088. +/**
  6089. + * Smarty plugin
  6090. + * @package Smarty
  6091. + * @subpackage plugins
  6092. + */
  6093. +
  6094. +/**
  6095. + * determines if a resource is secure or not.
  6096. + *
  6097. + * @param string $resource_type
  6098. + * @param string $resource_name
  6099. + * @return boolean
  6100. + */
  6101. +
  6102. +//  $resource_type, $resource_name
  6103. +
  6104. +function smarty_core_is_secure($params, &$smarty)
  6105. +{
  6106. +    if (!$smarty->security || $smarty->security_settings['INCLUDE_ANY']) {
  6107. +        return true;
  6108. +    }
  6109. +
  6110. +    if ($params['resource_type'] == 'file') {
  6111. +        $_rp = realpath($params['resource_name']);
  6112. +        if (isset($params['resource_base_path'])) {
  6113. +            foreach ((array)$params['resource_base_path'] as $curr_dir) {
  6114. +                if ( ($_cd = realpath($curr_dir)) !== false &&
  6115. +                     strncmp($_rp, $_cd, strlen($_cd)) == 0 &&
  6116. +                     substr($_rp, strlen($_cd), 1) == DIRECTORY_SEPARATOR ) {
  6117. +                    return true;
  6118. +                }
  6119. +            }
  6120. +        }
  6121. +        if (!empty($smarty->secure_dir)) {
  6122. +            foreach ((array)$smarty->secure_dir as $curr_dir) {
  6123. +                if ( ($_cd = realpath($curr_dir)) !== false) {
  6124. +                    if($_cd == $_rp) {
  6125. +                        return true;
  6126. +                    } elseif (strncmp($_rp, $_cd, strlen($_cd)) == 0 &&
  6127. +                        substr($_rp, strlen($_cd), 1) == DIRECTORY_SEPARATOR) {
  6128. +                        return true;
  6129. +                    }
  6130. +                }
  6131. +            }
  6132. +        }
  6133. +    } else {
  6134. +        // resource is not on local file system
  6135. +        return call_user_func_array(
  6136. +            $smarty->_plugins['resource'][$params['resource_type']][0][2],
  6137. +            array($params['resource_name'], &$smarty));
  6138. +    }
  6139. +
  6140. +    return false;
  6141. +}
  6142. +
  6143. +/* vim: set expandtab: */
  6144. +
  6145. +?>
  6146. diff --git a/library/smarty/internals/core.is_trusted.php b/library/smarty/internals/core.is_trusted.php
  6147. new file mode 100644
  6148. --- /dev/null
  6149. +++ b/library/smarty/internals/core.is_trusted.php
  6150. @@ -0,0 +1,47 @@
  6151. +<?php
  6152. +/**
  6153. + * Smarty plugin
  6154. + * @package Smarty
  6155. + * @subpackage plugins
  6156. + */
  6157. +
  6158. +/**
  6159. + * determines if a resource is trusted or not
  6160. + *
  6161. + * @param string $resource_type
  6162. + * @param string $resource_name
  6163. + * @return boolean
  6164. + */
  6165. +
  6166. + // $resource_type, $resource_name
  6167. +
  6168. +function smarty_core_is_trusted($params, &$smarty)
  6169. +{
  6170. +    $_smarty_trusted = false;
  6171. +    if ($params['resource_type'] == 'file') {
  6172. +        if (!empty($smarty->trusted_dir)) {
  6173. +            $_rp = realpath($params['resource_name']);
  6174. +            foreach ((array)$smarty->trusted_dir as $curr_dir) {
  6175. +                if (!empty($curr_dir) && is_readable ($curr_dir)) {
  6176. +                    $_cd = realpath($curr_dir);
  6177. +                    if (strncmp($_rp, $_cd, strlen($_cd)) == 0
  6178. +                        && substr($_rp, strlen($_cd), 1) == DIRECTORY_SEPARATOR ) {
  6179. +                        $_smarty_trusted = true;
  6180. +                        break;
  6181. +                    }
  6182. +                }
  6183. +            }
  6184. +        }
  6185. +
  6186. +    } else {
  6187. +        // resource is not on local file system
  6188. +        $_smarty_trusted = call_user_func_array($smarty->_plugins['resource'][$params['resource_type']][0][3],
  6189. +                                                array($params['resource_name'], $smarty));
  6190. +    }
  6191. +
  6192. +    return $_smarty_trusted;
  6193. +}
  6194. +
  6195. +/* vim: set expandtab: */
  6196. +
  6197. +?>
  6198. diff --git a/library/smarty/internals/core.load_plugins.php b/library/smarty/internals/core.load_plugins.php
  6199. new file mode 100644
  6200. --- /dev/null
  6201. +++ b/library/smarty/internals/core.load_plugins.php
  6202. @@ -0,0 +1,125 @@
  6203. +<?php
  6204. +/**
  6205. + * Smarty plugin
  6206. + * @package Smarty
  6207. + * @subpackage plugins
  6208. + */
  6209. +
  6210. +/**
  6211. + * Load requested plugins
  6212. + *
  6213. + * @param array $plugins
  6214. + */
  6215. +
  6216. +// $plugins
  6217. +
  6218. +function smarty_core_load_plugins($params, &$smarty)
  6219. +{
  6220. +
  6221. +    foreach ($params['plugins'] as $_plugin_info) {
  6222. +        list($_type, $_name, $_tpl_file, $_tpl_line, $_delayed_loading) = $_plugin_info;
  6223. +        $_plugin = &$smarty->_plugins[$_type][$_name];
  6224. +
  6225. +        /*
  6226. +         * We do not load plugin more than once for each instance of Smarty.
  6227. +         * The following code checks for that. The plugin can also be
  6228. +         * registered dynamically at runtime, in which case template file
  6229. +         * and line number will be unknown, so we fill them in.
  6230. +         *
  6231. +         * The final element of the info array is a flag that indicates
  6232. +         * whether the dynamically registered plugin function has been
  6233. +         * checked for existence yet or not.
  6234. +         */
  6235. +        if (isset($_plugin)) {
  6236. +            if (empty($_plugin[3])) {
  6237. +                if (!is_callable($_plugin[0])) {
  6238. +                    $smarty->_trigger_fatal_error("[plugin] $_type '$_name' is not implemented", $_tpl_file, $_tpl_line, __FILE__, __LINE__);
  6239. +                } else {
  6240. +                    $_plugin[1] = $_tpl_file;
  6241. +                    $_plugin[2] = $_tpl_line;
  6242. +                    $_plugin[3] = true;
  6243. +                    if (!isset($_plugin[4])) $_plugin[4] = true; /* cacheable */
  6244. +                }
  6245. +            }
  6246. +            continue;
  6247. +        } else if ($_type == 'insert') {
  6248. +            /*
  6249. +             * For backwards compatibility, we check for insert functions in
  6250. +             * the symbol table before trying to load them as a plugin.
  6251. +             */
  6252. +            $_plugin_func = 'insert_' . $_name;
  6253. +            if (function_exists($_plugin_func)) {
  6254. +                $_plugin = array($_plugin_func, $_tpl_file, $_tpl_line, true, false);
  6255. +                continue;
  6256. +            }
  6257. +        }
  6258. +
  6259. +        $_plugin_file = $smarty->_get_plugin_filepath($_type, $_name);
  6260. +
  6261. +        if (! $_found = ($_plugin_file != false)) {
  6262. +            $_message = "could not load plugin file '$_type.$_name.php'\n";
  6263. +        }
  6264. +
  6265. +        /*
  6266. +         * If plugin file is found, it -must- provide the properly named
  6267. +         * plugin function. In case it doesn't, simply output the error and
  6268. +         * do not fall back on any other method.
  6269. +         */
  6270. +        if ($_found) {
  6271. +            include_once $_plugin_file;
  6272. +
  6273. +            $_plugin_func = 'smarty_' . $_type . '_' . $_name;
  6274. +            if (!function_exists($_plugin_func)) {
  6275. +                $smarty->_trigger_fatal_error("[plugin] function $_plugin_func() not found in $_plugin_file", $_tpl_file, $_tpl_line, __FILE__, __LINE__);
  6276. +                continue;
  6277. +            }
  6278. +        }
  6279. +        /*
  6280. +         * In case of insert plugins, their code may be loaded later via
  6281. +         * 'script' attribute.
  6282. +         */
  6283. +        else if ($_type == 'insert' && $_delayed_loading) {
  6284. +            $_plugin_func = 'smarty_' . $_type . '_' . $_name;
  6285. +            $_found = true;
  6286. +        }
  6287. +
  6288. +        /*
  6289. +         * Plugin specific processing and error checking.
  6290. +         */
  6291. +        if (!$_found) {
  6292. +            if ($_type == 'modifier') {
  6293. +                /*
  6294. +                 * In case modifier falls back on using PHP functions
  6295. +                 * directly, we only allow those specified in the security
  6296. +                 * context.
  6297. +                 */
  6298. +                if ($smarty->security && !in_array($_name, $smarty->security_settings['MODIFIER_FUNCS'])) {
  6299. +                    $_message = "(secure mode) modifier '$_name' is not allowed";
  6300. +                } else {
  6301. +                    if (!function_exists($_name)) {
  6302. +                        $_message = "modifier '$_name' is not implemented";
  6303. +                    } else {
  6304. +                        $_plugin_func = $_name;
  6305. +                        $_found = true;
  6306. +                    }
  6307. +                }
  6308. +            } else if ($_type == 'function') {
  6309. +                /*
  6310. +                 * This is a catch-all situation.
  6311. +                 */
  6312. +                $_message = "unknown tag - '$_name'";
  6313. +            }
  6314. +        }
  6315. +
  6316. +        if ($_found) {
  6317. +            $smarty->_plugins[$_type][$_name] = array($_plugin_func, $_tpl_file, $_tpl_line, true, true);
  6318. +        } else {
  6319. +            // output error
  6320. +            $smarty->_trigger_fatal_error('[plugin] ' . $_message, $_tpl_file, $_tpl_line, __FILE__, __LINE__);
  6321. +        }
  6322. +    }
  6323. +}
  6324. +
  6325. +/* vim: set expandtab: */
  6326. +
  6327. +?>
  6328. diff --git a/library/smarty/internals/core.load_resource_plugin.php b/library/smarty/internals/core.load_resource_plugin.php
  6329. new file mode 100644
  6330. --- /dev/null
  6331. +++ b/library/smarty/internals/core.load_resource_plugin.php
  6332. @@ -0,0 +1,74 @@
  6333. +<?php
  6334. +/**
  6335. + * Smarty plugin
  6336. + * @package Smarty
  6337. + * @subpackage plugins
  6338. + */
  6339. +
  6340. +/**
  6341. + * load a resource plugin
  6342. + *
  6343. + * @param string $type
  6344. + */
  6345. +
  6346. +// $type
  6347. +
  6348. +function smarty_core_load_resource_plugin($params, &$smarty)
  6349. +{
  6350. +    /*
  6351. +     * Resource plugins are not quite like the other ones, so they are
  6352. +     * handled differently. The first element of plugin info is the array of
  6353. +     * functions provided by the plugin, the second one indicates whether
  6354. +     * all of them exist or not.
  6355. +     */
  6356. +
  6357. +    $_plugin = &$smarty->_plugins['resource'][$params['type']];
  6358. +    if (isset($_plugin)) {
  6359. +        if (!$_plugin[1] && count($_plugin[0])) {
  6360. +            $_plugin[1] = true;
  6361. +            foreach ($_plugin[0] as $_plugin_func) {
  6362. +                if (!is_callable($_plugin_func)) {
  6363. +                    $_plugin[1] = false;
  6364. +                    break;
  6365. +                }
  6366. +            }
  6367. +        }
  6368. +
  6369. +        if (!$_plugin[1]) {
  6370. +            $smarty->_trigger_fatal_error("[plugin] resource '" . $params['type'] . "' is not implemented", null, null, __FILE__, __LINE__);
  6371. +        }
  6372. +
  6373. +        return;
  6374. +    }
  6375. +
  6376. +    $_plugin_file = $smarty->_get_plugin_filepath('resource', $params['type']);
  6377. +    $_found = ($_plugin_file != false);
  6378. +
  6379. +    if ($_found) {            /*
  6380. +         * If the plugin file is found, it -must- provide the properly named
  6381. +         * plugin functions.
  6382. +         */
  6383. +        include_once($_plugin_file);
  6384. +
  6385. +        /*
  6386. +         * Locate functions that we require the plugin to provide.
  6387. +         */
  6388. +        $_resource_ops = array('source', 'timestamp', 'secure', 'trusted');
  6389. +        $_resource_funcs = array();
  6390. +        foreach ($_resource_ops as $_op) {
  6391. +            $_plugin_func = 'smarty_resource_' . $params['type'] . '_' . $_op;
  6392. +            if (!function_exists($_plugin_func)) {
  6393. +                $smarty->_trigger_fatal_error("[plugin] function $_plugin_func() not found in $_plugin_file", null, null, __FILE__, __LINE__);
  6394. +                return;
  6395. +            } else {
  6396. +                $_resource_funcs[] = $_plugin_func;
  6397. +            }
  6398. +        }
  6399. +
  6400. +        $smarty->_plugins['resource'][$params['type']] = array($_resource_funcs, true);
  6401. +    }
  6402. +}
  6403. +
  6404. +/* vim: set expandtab: */
  6405. +
  6406. +?>
  6407. diff --git a/library/smarty/internals/core.process_cached_inserts.php b/library/smarty/internals/core.process_cached_inserts.php
  6408. new file mode 100644
  6409. --- /dev/null
  6410. +++ b/library/smarty/internals/core.process_cached_inserts.php
  6411. @@ -0,0 +1,71 @@
  6412. +<?php
  6413. +/**
  6414. + * Smarty plugin
  6415. + * @package Smarty
  6416. + * @subpackage plugins
  6417. + */
  6418. +
  6419. +/**
  6420. + * Replace cached inserts with the actual results
  6421. + *
  6422. + * @param string $results
  6423. + * @return string
  6424. + */
  6425. +function smarty_core_process_cached_inserts($params, &$smarty)
  6426. +{
  6427. +    preg_match_all('!'.$smarty->_smarty_md5.'{insert_cache (.*)}'.$smarty->_smarty_md5.'!Uis',
  6428. +                   $params['results'], $match);
  6429. +    list($cached_inserts, $insert_args) = $match;
  6430. +
  6431. +    for ($i = 0, $for_max = count($cached_inserts); $i < $for_max; $i++) {
  6432. +        if ($smarty->debugging) {
  6433. +            $_params = array();
  6434. +            require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
  6435. +            $debug_start_time = smarty_core_get_microtime($_params, $smarty);
  6436. +        }
  6437. +
  6438. +        $args = unserialize($insert_args[$i]);
  6439. +        $name = $args['name'];
  6440. +
  6441. +        if (isset($args['script'])) {
  6442. +            $_params = array('resource_name' => $smarty->_dequote($args['script']));
  6443. +            require_once(SMARTY_CORE_DIR . 'core.get_php_resource.php');
  6444. +            if(!smarty_core_get_php_resource($_params, $smarty)) {
  6445. +                return false;
  6446. +            }
  6447. +            $resource_type = $_params['resource_type'];
  6448. +            $php_resource = $_params['php_resource'];
  6449. +
  6450. +
  6451. +            if ($resource_type == 'file') {
  6452. +                $smarty->_include($php_resource, true);
  6453. +            } else {
  6454. +                $smarty->_eval($php_resource);
  6455. +            }
  6456. +        }
  6457. +
  6458. +        $function_name = $smarty->_plugins['insert'][$name][0];
  6459. +        if (empty($args['assign'])) {
  6460. +            $replace = $function_name($args, $smarty);
  6461. +        } else {
  6462. +            $smarty->assign($args['assign'], $function_name($args, $smarty));
  6463. +            $replace = '';
  6464. +        }
  6465. +
  6466. +        $params['results'] = substr_replace($params['results'], $replace, strpos($params['results'], $cached_inserts[$i]), strlen($cached_inserts[$i]));
  6467. +        if ($smarty->debugging) {
  6468. +            $_params = array();
  6469. +            require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
  6470. +            $smarty->_smarty_debug_info[] = array('type'      => 'insert',
  6471. +                                                'filename'  => 'insert_'.$name,
  6472. +                                                'depth'     => $smarty->_inclusion_depth,
  6473. +                                                'exec_time' => smarty_core_get_microtime($_params, $smarty) - $debug_start_time);
  6474. +        }
  6475. +    }
  6476. +
  6477. +    return $params['results'];
  6478. +}
  6479. +
  6480. +/* vim: set expandtab: */
  6481. +
  6482. +?>
  6483. diff --git a/library/smarty/internals/core.process_compiled_include.php b/library/smarty/internals/core.process_compiled_include.php
  6484. new file mode 100644
  6485. --- /dev/null
  6486. +++ b/library/smarty/internals/core.process_compiled_include.php
  6487. @@ -0,0 +1,37 @@
  6488. +<?php
  6489. +/**
  6490. + * Smarty plugin
  6491. + * @package Smarty
  6492. + * @subpackage plugins
  6493. + */
  6494. +
  6495. +/**
  6496. + * Replace nocache-tags by results of the corresponding non-cacheable
  6497. + * functions and return it
  6498. + *
  6499. + * @param string $compiled_tpl
  6500. + * @param string $cached_source
  6501. + * @return string
  6502. + */
  6503. +
  6504. +function smarty_core_process_compiled_include($params, &$smarty)
  6505. +{
  6506. +    $_cache_including = $smarty->_cache_including;
  6507. +    $smarty->_cache_including = true;
  6508. +
  6509. +    $_return = $params['results'];
  6510. +
  6511. +    foreach ($smarty->_cache_info['cache_serials'] as $_include_file_path=>$_cache_serial) {
  6512. +        $smarty->_include($_include_file_path, true);
  6513. +    }
  6514. +
  6515. +    foreach ($smarty->_cache_info['cache_serials'] as $_include_file_path=>$_cache_serial) {
  6516. +        $_return = preg_replace_callback('!(\{nocache\:('.$_cache_serial.')#(\d+)\})!s',
  6517. +                                         array(&$smarty, '_process_compiled_include_callback'),
  6518. +                                         $_return);
  6519. +    }
  6520. +    $smarty->_cache_including = $_cache_including;
  6521. +    return $_return;
  6522. +}
  6523. +
  6524. +?>
  6525. diff --git a/library/smarty/internals/core.read_cache_file.php b/library/smarty/internals/core.read_cache_file.php
  6526. new file mode 100644
  6527. --- /dev/null
  6528. +++ b/library/smarty/internals/core.read_cache_file.php
  6529. @@ -0,0 +1,101 @@
  6530. +<?php
  6531. +/**
  6532. + * Smarty plugin
  6533. + * @package Smarty
  6534. + * @subpackage plugins
  6535. + */
  6536. +
  6537. +/**
  6538. + * read a cache file, determine if it needs to be
  6539. + * regenerated or not
  6540. + *
  6541. + * @param string $tpl_file
  6542. + * @param string $cache_id
  6543. + * @param string $compile_id
  6544. + * @param string $results
  6545. + * @return boolean
  6546. + */
  6547. +
  6548. +//  $tpl_file, $cache_id, $compile_id, &$results
  6549. +
  6550. +function smarty_core_read_cache_file(&$params, &$smarty)
  6551. +{
  6552. +    static  $content_cache = array();
  6553. +
  6554. +    if ($smarty->force_compile) {
  6555. +        // force compile enabled, always regenerate
  6556. +        return false;
  6557. +    }
  6558. +
  6559. +    if (isset($content_cache[$params['tpl_file'].','.$params['cache_id'].','.$params['compile_id']])) {
  6560. +        list($params['results'], $smarty->_cache_info) = $content_cache[$params['tpl_file'].','.$params['cache_id'].','.$params['compile_id']];
  6561. +        return true;
  6562. +    }
  6563. +
  6564. +    if (!empty($smarty->cache_handler_func)) {
  6565. +        // use cache_handler function
  6566. +        call_user_func_array($smarty->cache_handler_func,
  6567. +                             array('read', &$smarty, &$params['results'], $params['tpl_file'], $params['cache_id'], $params['compile_id'], null));
  6568. +    } else {
  6569. +        // use local cache file
  6570. +        $_auto_id = $smarty->_get_auto_id($params['cache_id'], $params['compile_id']);
  6571. +        $_cache_file = $smarty->_get_auto_filename($smarty->cache_dir, $params['tpl_file'], $_auto_id);
  6572. +        $params['results'] = $smarty->_read_file($_cache_file);
  6573. +    }
  6574. +
  6575. +    if (empty($params['results'])) {
  6576. +        // nothing to parse (error?), regenerate cache
  6577. +        return false;
  6578. +    }
  6579. +
  6580. +    $_contents = $params['results'];
  6581. +    $_info_start = strpos($_contents, "\n") + 1;
  6582. +    $_info_len = (int)substr($_contents, 0, $_info_start - 1);
  6583. +    $_cache_info = unserialize(substr($_contents, $_info_start, $_info_len));
  6584. +    $params['results'] = substr($_contents, $_info_start + $_info_len);
  6585. +
  6586. +    if ($smarty->caching == 2 && isset ($_cache_info['expires'])){
  6587. +        // caching by expiration time
  6588. +        if ($_cache_info['expires'] > -1 && (time() > $_cache_info['expires'])) {
  6589. +            // cache expired, regenerate
  6590. +            return false;
  6591. +        }
  6592. +    } else {
  6593. +        // caching by lifetime
  6594. +        if ($smarty->cache_lifetime > -1 && (time() - $_cache_info['timestamp'] > $smarty->cache_lifetime)) {
  6595. +            // cache expired, regenerate
  6596. +            return false;
  6597. +        }
  6598. +    }
  6599. +
  6600. +    if ($smarty->compile_check) {
  6601. +        $_params = array('get_source' => false, 'quiet'=>true);
  6602. +        foreach (array_keys($_cache_info['template']) as $_template_dep) {
  6603. +            $_params['resource_name'] = $_template_dep;
  6604. +            if (!$smarty->_fetch_resource_info($_params) || $_cache_info['timestamp'] < $_params['resource_timestamp']) {
  6605. +                // template file has changed, regenerate cache
  6606. +                return false;
  6607. +            }
  6608. +        }
  6609. +
  6610. +        if (isset($_cache_info['config'])) {
  6611. +            $_params = array('resource_base_path' => $smarty->config_dir, 'get_source' => false, 'quiet'=>true);
  6612. +            foreach (array_keys($_cache_info['config']) as $_config_dep) {
  6613. +                $_params['resource_name'] = $_config_dep;
  6614. +                if (!$smarty->_fetch_resource_info($_params) || $_cache_info['timestamp'] < $_params['resource_timestamp']) {
  6615. +                    // config file has changed, regenerate cache
  6616. +                    return false;
  6617. +                }
  6618. +            }
  6619. +        }
  6620. +    }
  6621. +
  6622. +    $content_cache[$params['tpl_file'].','.$params['cache_id'].','.$params['compile_id']] = array($params['results'], $_cache_info);
  6623. +
  6624. +    $smarty->_cache_info = $_cache_info;
  6625. +    return true;
  6626. +}
  6627. +
  6628. +/* vim: set expandtab: */
  6629. +
  6630. +?>
  6631. diff --git a/library/smarty/internals/core.rm_auto.php b/library/smarty/internals/core.rm_auto.php
  6632. new file mode 100644
  6633. --- /dev/null
  6634. +++ b/library/smarty/internals/core.rm_auto.php
  6635. @@ -0,0 +1,71 @@
  6636. +<?php
  6637. +/**
  6638. + * Smarty plugin
  6639. + * @package Smarty
  6640. + * @subpackage plugins
  6641. + */
  6642. +
  6643. +/**
  6644. + * delete an automagically created file by name and id
  6645. + *
  6646. + * @param string $auto_base
  6647. + * @param string $auto_source
  6648. + * @param string $auto_id
  6649. + * @param integer $exp_time
  6650. + * @return boolean
  6651. + */
  6652. +
  6653. +// $auto_base, $auto_source = null, $auto_id = null, $exp_time = null
  6654. +
  6655. +function smarty_core_rm_auto($params, &$smarty)
  6656. +{
  6657. +    if (!@is_dir($params['auto_base']))
  6658. +      return false;
  6659. +
  6660. +    if(!isset($params['auto_id']) && !isset($params['auto_source'])) {
  6661. +        $_params = array(
  6662. +            'dirname' => $params['auto_base'],
  6663. +            'level' => 0,
  6664. +            'exp_time' => $params['exp_time']
  6665. +        );
  6666. +        require_once(SMARTY_CORE_DIR . 'core.rmdir.php');
  6667. +        $_res = smarty_core_rmdir($_params, $smarty);
  6668. +    } else {
  6669. +        $_tname = $smarty->_get_auto_filename($params['auto_base'], $params['auto_source'], $params['auto_id']);
  6670. +
  6671. +        if(isset($params['auto_source'])) {
  6672. +            if (isset($params['extensions'])) {
  6673. +                $_res = false;
  6674. +                foreach ((array)$params['extensions'] as $_extension)
  6675. +                    $_res |= $smarty->_unlink($_tname.$_extension, $params['exp_time']);
  6676. +            } else {
  6677. +                $_res = $smarty->_unlink($_tname, $params['exp_time']);
  6678. +            }
  6679. +        } elseif ($smarty->use_sub_dirs) {
  6680. +            $_params = array(
  6681. +                'dirname' => $_tname,
  6682. +                'level' => 1,
  6683. +                'exp_time' => $params['exp_time']
  6684. +            );
  6685. +            require_once(SMARTY_CORE_DIR . 'core.rmdir.php');
  6686. +            $_res = smarty_core_rmdir($_params, $smarty);
  6687. +        } else {
  6688. +            // remove matching file names
  6689. +            $_handle = opendir($params['auto_base']);
  6690. +            $_res = true;
  6691. +            while (false !== ($_filename = readdir($_handle))) {
  6692. +                if($_filename == '.' || $_filename == '..') {
  6693. +                    continue;
  6694. +                } elseif (substr($params['auto_base'] . DIRECTORY_SEPARATOR . $_filename, 0, strlen($_tname)) == $_tname) {
  6695. +                    $_res &= (bool)$smarty->_unlink($params['auto_base'] . DIRECTORY_SEPARATOR . $_filename, $params['exp_time']);
  6696. +                }
  6697. +            }
  6698. +        }
  6699. +    }
  6700. +
  6701. +    return $_res;
  6702. +}
  6703. +
  6704. +/* vim: set expandtab: */
  6705. +
  6706. +?>
  6707. diff --git a/library/smarty/internals/core.rmdir.php b/library/smarty/internals/core.rmdir.php
  6708. new file mode 100644
  6709. --- /dev/null
  6710. +++ b/library/smarty/internals/core.rmdir.php
  6711. @@ -0,0 +1,54 @@
  6712. +<?php
  6713. +/**
  6714. + * Smarty plugin
  6715. + * @package Smarty
  6716. + * @subpackage plugins
  6717. + */
  6718. +
  6719. +/**
  6720. + * delete a dir recursively (level=0 -> keep root)
  6721. + * WARNING: no tests, it will try to remove what you tell it!
  6722. + *
  6723. + * @param string $dirname
  6724. + * @param integer $level
  6725. + * @param integer $exp_time
  6726. + * @return boolean
  6727. + */
  6728. +
  6729. +//  $dirname, $level = 1, $exp_time = null
  6730. +
  6731. +function smarty_core_rmdir($params, &$smarty)
  6732. +{
  6733. +   if(!isset($params['level'])) { $params['level'] = 1; }
  6734. +   if(!isset($params['exp_time'])) { $params['exp_time'] = null; }
  6735. +
  6736. +   if($_handle = @opendir($params['dirname'])) {
  6737. +
  6738. +        while (false !== ($_entry = readdir($_handle))) {
  6739. +            if ($_entry != '.' && $_entry != '..') {
  6740. +                if (@is_dir($params['dirname'] . DIRECTORY_SEPARATOR . $_entry)) {
  6741. +                    $_params = array(
  6742. +                        'dirname' => $params['dirname'] . DIRECTORY_SEPARATOR . $_entry,
  6743. +                        'level' => $params['level'] + 1,
  6744. +                        'exp_time' => $params['exp_time']
  6745. +                    );
  6746. +                    smarty_core_rmdir($_params, $smarty);
  6747. +                }
  6748. +                else {
  6749. +                    $smarty->_unlink($params['dirname'] . DIRECTORY_SEPARATOR . $_entry, $params['exp_time']);
  6750. +                }
  6751. +            }
  6752. +        }
  6753. +        closedir($_handle);
  6754. +   }
  6755. +
  6756. +   if ($params['level']) {
  6757. +       return @rmdir($params['dirname']);
  6758. +   }
  6759. +   return (bool)$_handle;
  6760. +
  6761. +}
  6762. +
  6763. +/* vim: set expandtab: */
  6764. +
  6765. +?>
  6766. diff --git a/library/smarty/internals/core.run_insert_handler.php b/library/smarty/internals/core.run_insert_handler.php
  6767. new file mode 100644
  6768. --- /dev/null
  6769. +++ b/library/smarty/internals/core.run_insert_handler.php
  6770. @@ -0,0 +1,71 @@
  6771. +<?php
  6772. +/**
  6773. + * Smarty plugin
  6774. + * @package Smarty
  6775. + * @subpackage plugins
  6776. + */
  6777. +
  6778. +/**
  6779. + * Handle insert tags
  6780. + *
  6781. + * @param array $args
  6782. + * @return string
  6783. + */
  6784. +function smarty_core_run_insert_handler($params, &$smarty)
  6785. +{
  6786. +
  6787. +    require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
  6788. +    if ($smarty->debugging) {
  6789. +        $_params = array();
  6790. +        $_debug_start_time = smarty_core_get_microtime($_params, $smarty);
  6791. +    }
  6792. +
  6793. +    if ($smarty->caching) {
  6794. +        $_arg_string = serialize($params['args']);
  6795. +        $_name = $params['args']['name'];
  6796. +        if (!isset($smarty->_cache_info['insert_tags'][$_name])) {
  6797. +            $smarty->_cache_info['insert_tags'][$_name] = array('insert',
  6798. +                                                             $_name,
  6799. +                                                             $smarty->_plugins['insert'][$_name][1],
  6800. +                                                             $smarty->_plugins['insert'][$_name][2],
  6801. +                                                             !empty($params['args']['script']) ? true : false);
  6802. +        }
  6803. +        return $smarty->_smarty_md5."{insert_cache $_arg_string}".$smarty->_smarty_md5;
  6804. +    } else {
  6805. +        if (isset($params['args']['script'])) {
  6806. +            $_params = array('resource_name' => $smarty->_dequote($params['args']['script']));
  6807. +            require_once(SMARTY_CORE_DIR . 'core.get_php_resource.php');
  6808. +            if(!smarty_core_get_php_resource($_params, $smarty)) {
  6809. +                return false;
  6810. +            }
  6811. +
  6812. +            if ($_params['resource_type'] == 'file') {
  6813. +                $smarty->_include($_params['php_resource'], true);
  6814. +            } else {
  6815. +                $smarty->_eval($_params['php_resource']);
  6816. +            }
  6817. +            unset($params['args']['script']);
  6818. +        }
  6819. +
  6820. +        $_funcname = $smarty->_plugins['insert'][$params['args']['name']][0];
  6821. +        $_content = $_funcname($params['args'], $smarty);
  6822. +        if ($smarty->debugging) {
  6823. +            $_params = array();
  6824. +            require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
  6825. +            $smarty->_smarty_debug_info[] = array('type'      => 'insert',
  6826. +                                                'filename'  => 'insert_'.$params['args']['name'],
  6827. +                                                'depth'     => $smarty->_inclusion_depth,
  6828. +                                                'exec_time' => smarty_core_get_microtime($_params, $smarty) - $_debug_start_time);
  6829. +        }
  6830. +
  6831. +        if (!empty($params['args']["assign"])) {
  6832. +            $smarty->assign($params['args']["assign"], $_content);
  6833. +        } else {
  6834. +            return $_content;
  6835. +        }
  6836. +    }
  6837. +}
  6838. +
  6839. +/* vim: set expandtab: */
  6840. +
  6841. +?>
  6842. diff --git a/library/smarty/internals/core.smarty_include_php.php b/library/smarty/internals/core.smarty_include_php.php
  6843. new file mode 100644
  6844. --- /dev/null
  6845. +++ b/library/smarty/internals/core.smarty_include_php.php
  6846. @@ -0,0 +1,50 @@
  6847. +<?php
  6848. +/**
  6849. + * Smarty plugin
  6850. + * @package Smarty
  6851. + * @subpackage plugins
  6852. + */
  6853. +
  6854. +/**
  6855. + * called for included php files within templates
  6856. + *
  6857. + * @param string $smarty_file
  6858. + * @param string $smarty_assign variable to assign the included template's
  6859. + *               output into
  6860. + * @param boolean $smarty_once uses include_once if this is true
  6861. + * @param array $smarty_include_vars associative array of vars from
  6862. + *              {include file="blah" var=$var}
  6863. + */
  6864. +
  6865. +//  $file, $assign, $once, $_smarty_include_vars
  6866. +
  6867. +function smarty_core_smarty_include_php($params, &$smarty)
  6868. +{
  6869. +    $_params = array('resource_name' => $params['smarty_file']);
  6870. +    require_once(SMARTY_CORE_DIR . 'core.get_php_resource.php');
  6871. +    smarty_core_get_php_resource($_params, $smarty);
  6872. +    $_smarty_resource_type = $_params['resource_type'];
  6873. +    $_smarty_php_resource = $_params['php_resource'];
  6874. +
  6875. +    if (!empty($params['smarty_assign'])) {
  6876. +        ob_start();
  6877. +        if ($_smarty_resource_type == 'file') {
  6878. +            $smarty->_include($_smarty_php_resource, $params['smarty_once'], $params['smarty_include_vars']);
  6879. +        } else {
  6880. +            $smarty->_eval($_smarty_php_resource, $params['smarty_include_vars']);
  6881. +        }
  6882. +        $smarty->assign($params['smarty_assign'], ob_get_contents());
  6883. +        ob_end_clean();
  6884. +    } else {
  6885. +        if ($_smarty_resource_type == 'file') {
  6886. +            $smarty->_include($_smarty_php_resource, $params['smarty_once'], $params['smarty_include_vars']);
  6887. +        } else {
  6888. +            $smarty->_eval($_smarty_php_resource, $params['smarty_include_vars']);
  6889. +        }
  6890. +    }
  6891. +}
  6892. +
  6893. +
  6894. +/* vim: set expandtab: */
  6895. +
  6896. +?>
  6897. diff --git a/library/smarty/internals/core.write_cache_file.php b/library/smarty/internals/core.write_cache_file.php
  6898. new file mode 100644
  6899. --- /dev/null
  6900. +++ b/library/smarty/internals/core.write_cache_file.php
  6901. @@ -0,0 +1,96 @@
  6902. +<?php
  6903. +/**
  6904. + * Smarty plugin
  6905. + * @package Smarty
  6906. + * @subpackage plugins
  6907. + */
  6908. +
  6909. +/**
  6910. + * Prepend the cache information to the cache file
  6911. + * and write it
  6912. + *
  6913. + * @param string $tpl_file
  6914. + * @param string $cache_id
  6915. + * @param string $compile_id
  6916. + * @param string $results
  6917. + * @return true|null
  6918. + */
  6919. +
  6920. + // $tpl_file, $cache_id, $compile_id, $results
  6921. +
  6922. +function smarty_core_write_cache_file($params, &$smarty)
  6923. +{
  6924. +
  6925. +    // put timestamp in cache header
  6926. +    $smarty->_cache_info['timestamp'] = time();
  6927. +    if ($smarty->cache_lifetime > -1){
  6928. +        // expiration set
  6929. +        $smarty->_cache_info['expires'] = $smarty->_cache_info['timestamp'] + $smarty->cache_lifetime;
  6930. +    } else {
  6931. +        // cache will never expire
  6932. +        $smarty->_cache_info['expires'] = -1;
  6933. +    }
  6934. +
  6935. +    // collapse nocache.../nocache-tags
  6936. +    if (preg_match_all('!\{(/?)nocache\:[0-9a-f]{32}#\d+\}!', $params['results'], $match, PREG_PATTERN_ORDER)) {
  6937. +        // remove everything between every pair of outermost noache.../nocache-tags
  6938. +        // and replace it by a single nocache-tag
  6939. +        // this new nocache-tag will be replaced by dynamic contents in
  6940. +        // smarty_core_process_compiled_includes() on a cache-read
  6941. +        
  6942. +        $match_count = count($match[0]);
  6943. +        $results = preg_split('!(\{/?nocache\:[0-9a-f]{32}#\d+\})!', $params['results'], -1, PREG_SPLIT_DELIM_CAPTURE);
  6944. +        
  6945. +        $level = 0;
  6946. +        $j = 0;
  6947. +        for ($i=0, $results_count = count($results); $i < $results_count && $j < $match_count; $i++) {
  6948. +            if ($results[$i] == $match[0][$j]) {
  6949. +                // nocache tag
  6950. +                if ($match[1][$j]) { // closing tag
  6951. +                    $level--;
  6952. +                    unset($results[$i]);
  6953. +                } else { // opening tag
  6954. +                    if ($level++ > 0) unset($results[$i]);
  6955. +                }
  6956. +                $j++;
  6957. +            } elseif ($level > 0) {
  6958. +                unset($results[$i]);
  6959. +            }
  6960. +        }
  6961. +        $params['results'] = implode('', $results);
  6962. +    }
  6963. +    $smarty->_cache_info['cache_serials'] = $smarty->_cache_serials;
  6964. +
  6965. +    // prepend the cache header info into cache file
  6966. +    $_cache_info = serialize($smarty->_cache_info);
  6967. +    $params['results'] = strlen($_cache_info) . "\n" . $_cache_info . $params['results'];
  6968. +
  6969. +    if (!empty($smarty->cache_handler_func)) {
  6970. +        // use cache_handler function
  6971. +        call_user_func_array($smarty->cache_handler_func,
  6972. +                             array('write', &$smarty, &$params['results'], $params['tpl_file'], $params['cache_id'], $params['compile_id'], $smarty->_cache_info['expires']));
  6973. +    } else {
  6974. +        // use local cache file
  6975. +
  6976. +        if(!@is_writable($smarty->cache_dir)) {
  6977. +            // cache_dir not writable, see if it exists
  6978. +            if(!@is_dir($smarty->cache_dir)) {
  6979. +                $smarty->trigger_error('the $cache_dir \'' . $smarty->cache_dir . '\' does not exist, or is not a directory.', E_USER_ERROR);
  6980. +                return false;
  6981. +            }
  6982. +            $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);
  6983. +            return false;
  6984. +        }
  6985. +
  6986. +        $_auto_id = $smarty->_get_auto_id($params['cache_id'], $params['compile_id']);
  6987. +        $_cache_file = $smarty->_get_auto_filename($smarty->cache_dir, $params['tpl_file'], $_auto_id);
  6988. +        $_params = array('filename' => $_cache_file, 'contents' => $params['results'], 'create_dirs' => true);
  6989. +        require_once(SMARTY_CORE_DIR . 'core.write_file.php');
  6990. +        smarty_core_write_file($_params, $smarty);
  6991. +        return true;
  6992. +    }
  6993. +}
  6994. +
  6995. +/* vim: set expandtab: */
  6996. +
  6997. +?>
  6998. diff --git a/library/smarty/internals/core.write_compiled_include.php b/library/smarty/internals/core.write_compiled_include.php
  6999. new file mode 100644
  7000. --- /dev/null
  7001. +++ b/library/smarty/internals/core.write_compiled_include.php
  7002. @@ -0,0 +1,91 @@
  7003. +<?php
  7004. +/**
  7005. + * Smarty plugin
  7006. + * @package Smarty
  7007. + * @subpackage plugins
  7008. + */
  7009. +
  7010. +/**
  7011. + * Extract non-cacheable parts out of compiled template and write it
  7012. + *
  7013. + * @param string $compile_path
  7014. + * @param string $template_compiled
  7015. + * @return boolean
  7016. + */
  7017. +
  7018. +function smarty_core_write_compiled_include($params, &$smarty)
  7019. +{
  7020. +    $_tag_start = 'if \(\$this->caching && \!\$this->_cache_including\)\: echo \'\{nocache\:('.$params['cache_serial'].')#(\d+)\}\'; endif;';
  7021. +    $_tag_end   = 'if \(\$this->caching && \!\$this->_cache_including\)\: echo \'\{/nocache\:(\\2)#(\\3)\}\'; endif;';
  7022. +
  7023. +    preg_match_all('!('.$_tag_start.'(.*)'.$_tag_end.')!Us',
  7024. +                   $params['compiled_content'], $_match_source, PREG_SET_ORDER);
  7025. +    
  7026. +    // no nocache-parts found: done
  7027. +    if (count($_match_source)==0) return;
  7028. +
  7029. +    // convert the matched php-code to functions
  7030. +    $_include_compiled =  "<?php /* Smarty version ".$smarty->_version.", created on ".strftime("%Y-%m-%d %H:%M:%S")."\n";
  7031. +    $_include_compiled .= "         compiled from " . strtr(urlencode($params['resource_name']), array('%2F'=>'/', '%3A'=>':')) . " */\n\n";
  7032. +
  7033. +    $_compile_path = $params['include_file_path'];
  7034. +
  7035. +    $smarty->_cache_serials[$_compile_path] = $params['cache_serial'];
  7036. +    $_include_compiled .= "\$this->_cache_serials['".$_compile_path."'] = '".$params['cache_serial']."';\n\n?>";
  7037. +
  7038. +    $_include_compiled .= $params['plugins_code'];
  7039. +    $_include_compiled .= "<?php";
  7040. +
  7041. +    $this_varname = ((double)phpversion() >= 5.0) ? '_smarty' : 'this';
  7042. +    for ($_i = 0, $_for_max = count($_match_source); $_i < $_for_max; $_i++) {
  7043. +        $_match =& $_match_source[$_i];
  7044. +        $source = $_match[4];
  7045. +        if ($this_varname == '_smarty') {
  7046. +            /* rename $this to $_smarty in the sourcecode */
  7047. +            $tokens = token_get_all('<?php ' . $_match[4]);
  7048. +
  7049. +            /* remove trailing <?php */
  7050. +            $open_tag = '';
  7051. +            while ($tokens) {
  7052. +                $token = array_shift($tokens);
  7053. +                if (is_array($token)) {
  7054. +                    $open_tag .= $token[1];
  7055. +                } else {
  7056. +                    $open_tag .= $token;
  7057. +                }
  7058. +                if ($open_tag == '<?php ') break;
  7059. +            }
  7060. +
  7061. +            for ($i=0, $count = count($tokens); $i < $count; $i++) {
  7062. +                if (is_array($tokens[$i])) {
  7063. +                    if ($tokens[$i][0] == T_VARIABLE && $tokens[$i][1] == '$this') {
  7064. +                        $tokens[$i] = '$' . $this_varname;
  7065. +                    } else {
  7066. +                        $tokens[$i] = $tokens[$i][1];
  7067. +                    }                  
  7068. +                }
  7069. +            }
  7070. +            $source = implode('', $tokens);
  7071. +        }
  7072. +
  7073. +        /* add function to compiled include */
  7074. +        $_include_compiled .= "
  7075. +function _smarty_tplfunc_$_match[2]_$_match[3](&\$$this_varname)
  7076. +{
  7077. +$source
  7078. +}
  7079. +
  7080. +";
  7081. +    }
  7082. +    $_include_compiled .= "\n\n?>\n";
  7083. +
  7084. +    $_params = array('filename' => $_compile_path,
  7085. +                     'contents' => $_include_compiled, 'create_dirs' => true);
  7086. +
  7087. +    require_once(SMARTY_CORE_DIR . 'core.write_file.php');
  7088. +    smarty_core_write_file($_params, $smarty);
  7089. +    return true;
  7090. +}
  7091. +
  7092. +
  7093. +?>
  7094. diff --git a/library/smarty/internals/core.write_compiled_resource.php b/library/smarty/internals/core.write_compiled_resource.php
  7095. new file mode 100644
  7096. --- /dev/null
  7097. +++ b/library/smarty/internals/core.write_compiled_resource.php
  7098. @@ -0,0 +1,35 @@
  7099. +<?php
  7100. +/**
  7101. + * Smarty plugin
  7102. + * @package Smarty
  7103. + * @subpackage plugins
  7104. + */
  7105. +
  7106. +/**
  7107. + * write the compiled resource
  7108. + *
  7109. + * @param string $compile_path
  7110. + * @param string $compiled_content
  7111. + * @return true
  7112. + */
  7113. +function smarty_core_write_compiled_resource($params, &$smarty)
  7114. +{
  7115. +    if(!@is_writable($smarty->compile_dir)) {
  7116. +        // compile_dir not writable, see if it exists
  7117. +        if(!@is_dir($smarty->compile_dir)) {
  7118. +            $smarty->trigger_error('the $compile_dir \'' . $smarty->compile_dir . '\' does not exist, or is not a directory.', E_USER_ERROR);
  7119. +            return false;
  7120. +        }
  7121. +        $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);
  7122. +        return false;
  7123. +    }
  7124. +
  7125. +    $_params = array('filename' => $params['compile_path'], 'contents' => $params['compiled_content'], 'create_dirs' => true);
  7126. +    require_once(SMARTY_CORE_DIR . 'core.write_file.php');
  7127. +    smarty_core_write_file($_params, $smarty);
  7128. +    return true;
  7129. +}
  7130. +
  7131. +/* vim: set expandtab: */
  7132. +
  7133. +?>
  7134. diff --git a/library/smarty/internals/core.write_file.php b/library/smarty/internals/core.write_file.php
  7135. new file mode 100644
  7136. --- /dev/null
  7137. +++ b/library/smarty/internals/core.write_file.php
  7138. @@ -0,0 +1,54 @@
  7139. +<?php
  7140. +/**
  7141. + * Smarty plugin
  7142. + * @package Smarty
  7143. + * @subpackage plugins
  7144. + */
  7145. +
  7146. +/**
  7147. + * write out a file to disk
  7148. + *
  7149. + * @param string $filename
  7150. + * @param string $contents
  7151. + * @param boolean $create_dirs
  7152. + * @return boolean
  7153. + */
  7154. +function smarty_core_write_file($params, &$smarty)
  7155. +{
  7156. +    $_dirname = dirname($params['filename']);
  7157. +
  7158. +    if ($params['create_dirs']) {
  7159. +        $_params = array('dir' => $_dirname);
  7160. +        require_once(SMARTY_CORE_DIR . 'core.create_dir_structure.php');
  7161. +        smarty_core_create_dir_structure($_params, $smarty);
  7162. +    }
  7163. +
  7164. +    // write to tmp file, then rename it to avoid file locking race condition
  7165. +    $_tmp_file = tempnam($_dirname, 'wrt');
  7166. +
  7167. +    if (!($fd = @fopen($_tmp_file, 'wb'))) {
  7168. +        $_tmp_file = $_dirname . DIRECTORY_SEPARATOR . uniqid('wrt');
  7169. +        if (!($fd = @fopen($_tmp_file, 'wb'))) {
  7170. +            $smarty->trigger_error("problem writing temporary file '$_tmp_file'");
  7171. +            return false;
  7172. +        }
  7173. +    }
  7174. +
  7175. +    fwrite($fd, $params['contents']);
  7176. +    fclose($fd);
  7177. +
  7178. +    if (DIRECTORY_SEPARATOR == '\\' || !@rename($_tmp_file, $params['filename'])) {
  7179. +        // On platforms and filesystems that cannot overwrite with rename()
  7180. +        // delete the file before renaming it -- because windows always suffers
  7181. +        // this, it is short-circuited to avoid the initial rename() attempt
  7182. +        @unlink($params['filename']);
  7183. +        @rename($_tmp_file, $params['filename']);
  7184. +    }
  7185. +    @chmod($params['filename'], $smarty->_file_perms);
  7186. +
  7187. +    return true;
  7188. +}
  7189. +
  7190. +/* vim: set expandtab: */
  7191. +
  7192. +?>
  7193. \ No newline at end of file
  7194. diff --git a/library/smarty/plugins/block.textformat.php b/library/smarty/plugins/block.textformat.php
  7195. new file mode 100644
  7196. --- /dev/null
  7197. +++ b/library/smarty/plugins/block.textformat.php
  7198. @@ -0,0 +1,103 @@
  7199. +<?php
  7200. +/**
  7201. + * Smarty plugin
  7202. + * @package Smarty
  7203. + * @subpackage plugins
  7204. + */
  7205. +
  7206. +/**
  7207. + * Smarty {textformat}{/textformat} block plugin
  7208. + *
  7209. + * Type:     block function<br>
  7210. + * Name:     textformat<br>
  7211. + * Purpose:  format text a certain way with preset styles
  7212. + *           or custom wrap/indent settings<br>
  7213. + * @link http://smarty.php.net/manual/en/language.function.textformat.php {textformat}
  7214. + *       (Smarty online manual)
  7215. + * @param array
  7216. + * <pre>
  7217. + * Params:   style: string (email)
  7218. + *           indent: integer (0)
  7219. + *           wrap: integer (80)
  7220. + *           wrap_char string ("\n")
  7221. + *           indent_char: string (" ")
  7222. + *           wrap_boundary: boolean (true)
  7223. + * </pre>
  7224. + * @author Monte Ohrt <monte at ohrt dot com>
  7225. + * @param string contents of the block
  7226. + * @param Smarty clever simulation of a method
  7227. + * @return string string $content re-formatted
  7228. + */
  7229. +function smarty_block_textformat($params, $content, &$smarty)
  7230. +{
  7231. +    if (is_null($content)) {
  7232. +        return;
  7233. +    }
  7234. +
  7235. +    $style = null;
  7236. +    $indent = 0;
  7237. +    $indent_first = 0;
  7238. +    $indent_char = ' ';
  7239. +    $wrap = 80;
  7240. +    $wrap_char = "\n";
  7241. +    $wrap_cut = false;
  7242. +    $assign = null;
  7243. +    
  7244. +    foreach ($params as $_key => $_val) {
  7245. +        switch ($_key) {
  7246. +            case 'style':
  7247. +            case 'indent_char':
  7248. +            case 'wrap_char':
  7249. +            case 'assign':
  7250. +                $$_key = (string)$_val;
  7251. +                break;
  7252. +
  7253. +            case 'indent':
  7254. +            case 'indent_first':
  7255. +            case 'wrap':
  7256. +                $$_key = (int)$_val;
  7257. +                break;
  7258. +
  7259. +            case 'wrap_cut':
  7260. +                $$_key = (bool)$_val;
  7261. +                break;
  7262. +
  7263. +            default:
  7264. +                $smarty->trigger_error("textformat: unknown attribute '$_key'");
  7265. +        }
  7266. +    }
  7267. +
  7268. +    if ($style == 'email') {
  7269. +        $wrap = 72;
  7270. +    }
  7271. +
  7272. +    // split into paragraphs
  7273. +    $_paragraphs = preg_split('![\r\n][\r\n]!',$content);
  7274. +    $_output = '';
  7275. +
  7276. +    for($_x = 0, $_y = count($_paragraphs); $_x < $_y; $_x++) {
  7277. +        if ($_paragraphs[$_x] == '') {
  7278. +            continue;
  7279. +        }
  7280. +        // convert mult. spaces & special chars to single space
  7281. +        $_paragraphs[$_x] = preg_replace(array('!\s+!','!(^\s+)|(\s+$)!'), array(' ',''), $_paragraphs[$_x]);
  7282. +        // indent first line
  7283. +        if($indent_first > 0) {
  7284. +            $_paragraphs[$_x] = str_repeat($indent_char, $indent_first) . $_paragraphs[$_x];
  7285. +        }
  7286. +        // wordwrap sentences
  7287. +        $_paragraphs[$_x] = wordwrap($_paragraphs[$_x], $wrap - $indent, $wrap_char, $wrap_cut);
  7288. +        // indent lines
  7289. +        if($indent > 0) {
  7290. +            $_paragraphs[$_x] = preg_replace('!^!m', str_repeat($indent_char, $indent), $_paragraphs[$_x]);
  7291. +        }
  7292. +    }
  7293. +    $_output = implode($wrap_char . $wrap_char, $_paragraphs);
  7294. +
  7295. +    return $assign ? $smarty->assign($assign, $_output) : $_output;
  7296. +
  7297. +}
  7298. +
  7299. +/* vim: set expandtab: */
  7300. +
  7301. +?>
  7302. diff --git a/library/smarty/plugins/compiler.assign.php b/library/smarty/plugins/compiler.assign.php
  7303. new file mode 100644
  7304. --- /dev/null
  7305. +++ b/library/smarty/plugins/compiler.assign.php
  7306. @@ -0,0 +1,40 @@
  7307. +<?php
  7308. +/**
  7309. + * Smarty plugin
  7310. + * @package Smarty
  7311. + * @subpackage plugins
  7312. + */
  7313. +
  7314. +/**
  7315. + * Smarty {assign} compiler function plugin
  7316. + *
  7317. + * Type:     compiler function<br>
  7318. + * Name:     assign<br>
  7319. + * Purpose:  assign a value to a template variable
  7320. + * @link http://smarty.php.net/manual/en/language.custom.functions.php#LANGUAGE.FUNCTION.ASSIGN {assign}
  7321. + *       (Smarty online manual)
  7322. + * @author Monte Ohrt <monte at ohrt dot com> (initial author)
  7323. + * @author messju mohr <messju at lammfellpuschen dot de> (conversion to compiler function)
  7324. + * @param string containing var-attribute and value-attribute
  7325. + * @param Smarty_Compiler
  7326. + */
  7327. +function smarty_compiler_assign($tag_attrs, &$compiler)
  7328. +{
  7329. +    $_params = $compiler->_parse_attrs($tag_attrs);
  7330. +
  7331. +    if (!isset($_params['var'])) {
  7332. +        $compiler->_syntax_error("assign: missing 'var' parameter", E_USER_WARNING);
  7333. +        return;
  7334. +    }
  7335. +
  7336. +    if (!isset($_params['value'])) {
  7337. +        $compiler->_syntax_error("assign: missing 'value' parameter", E_USER_WARNING);
  7338. +        return;
  7339. +    }
  7340. +
  7341. +    return "\$this->assign({$_params['var']}, {$_params['value']});";
  7342. +}
  7343. +
  7344. +/* vim: set expandtab: */
  7345. +
  7346. +?>
  7347. diff --git a/library/smarty/plugins/function.assign_debug_info.php b/library/smarty/plugins/function.assign_debug_info.php
  7348. new file mode 100644
  7349. --- /dev/null
  7350. +++ b/library/smarty/plugins/function.assign_debug_info.php
  7351. @@ -0,0 +1,40 @@
  7352. +<?php
  7353. +/**
  7354. + * Smarty plugin
  7355. + * @package Smarty
  7356. + * @subpackage plugins
  7357. + */
  7358. +
  7359. +/**
  7360. + * Smarty {assign_debug_info} function plugin
  7361. + *
  7362. + * Type:     function<br>
  7363. + * Name:     assign_debug_info<br>
  7364. + * Purpose:  assign debug info to the template<br>
  7365. + * @author Monte Ohrt <monte at ohrt dot com>
  7366. + * @param array unused in this plugin, this plugin uses {@link Smarty::$_config},
  7367. + *              {@link Smarty::$_tpl_vars} and {@link Smarty::$_smarty_debug_info}
  7368. + * @param Smarty
  7369. + */
  7370. +function smarty_function_assign_debug_info($params, &$smarty)
  7371. +{
  7372. +    $assigned_vars = $smarty->_tpl_vars;
  7373. +    ksort($assigned_vars);
  7374. +    if (@is_array($smarty->_config[0])) {
  7375. +        $config_vars = $smarty->_config[0];
  7376. +        ksort($config_vars);
  7377. +        $smarty->assign("_debug_config_keys", array_keys($config_vars));
  7378. +        $smarty->assign("_debug_config_vals", array_values($config_vars));
  7379. +    }
  7380. +    
  7381. +    $included_templates = $smarty->_smarty_debug_info;
  7382. +    
  7383. +    $smarty->assign("_debug_keys", array_keys($assigned_vars));
  7384. +    $smarty->assign("_debug_vals", array_values($assigned_vars));
  7385. +    
  7386. +    $smarty->assign("_debug_tpls", $included_templates);
  7387. +}
  7388. +
  7389. +/* vim: set expandtab: */
  7390. +
  7391. +?>
  7392. diff --git a/library/smarty/plugins/function.config_load.php b/library/smarty/plugins/function.config_load.php
  7393. new file mode 100644
  7394. --- /dev/null
  7395. +++ b/library/smarty/plugins/function.config_load.php
  7396. @@ -0,0 +1,142 @@
  7397. +<?php
  7398. +/**
  7399. + * Smarty plugin
  7400. + * @package Smarty
  7401. + * @subpackage plugins
  7402. + */
  7403. +
  7404. +/**
  7405. + * Smarty {config_load} function plugin
  7406. + *
  7407. + * Type:     function<br>
  7408. + * Name:     config_load<br>
  7409. + * Purpose:  load config file vars
  7410. + * @link http://smarty.php.net/manual/en/language.function.config.load.php {config_load}
  7411. + *       (Smarty online manual)
  7412. + * @author Monte Ohrt <monte at ohrt dot com>
  7413. + * @author messju mohr <messju at lammfellpuschen dot de> (added use of resources)
  7414. + * @param array Format:
  7415. + * <pre>
  7416. + * array('file' => required config file name,
  7417. + *       'section' => optional config file section to load
  7418. + *       'scope' => local/parent/global
  7419. + *       'global' => overrides scope, setting to parent if true)
  7420. + * </pre>
  7421. + * @param Smarty
  7422. + */
  7423. +function smarty_function_config_load($params, &$smarty)
  7424. +{
  7425. +        if ($smarty->debugging) {
  7426. +            $_params = array();
  7427. +            require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
  7428. +            $_debug_start_time = smarty_core_get_microtime($_params, $smarty);
  7429. +        }
  7430. +
  7431. +        $_file = isset($params['file']) ? $smarty->_dequote($params['file']) : null;
  7432. +        $_section = isset($params['section']) ? $smarty->_dequote($params['section']) : null;
  7433. +        $_scope = isset($params['scope']) ? $smarty->_dequote($params['scope']) : 'global';
  7434. +        $_global = isset($params['global']) ? $smarty->_dequote($params['global']) : false;
  7435. +
  7436. +        if (!isset($_file) || strlen($_file) == 0) {
  7437. +            $smarty->trigger_error("missing 'file' attribute in config_load tag", E_USER_ERROR, __FILE__, __LINE__);
  7438. +        }
  7439. +
  7440. +        if (isset($_scope)) {
  7441. +            if ($_scope != 'local' &&
  7442. +                $_scope != 'parent' &&
  7443. +                $_scope != 'global') {
  7444. +                $smarty->trigger_error("invalid 'scope' attribute value", E_USER_ERROR, __FILE__, __LINE__);
  7445. +            }
  7446. +        } else {
  7447. +            if ($_global) {
  7448. +                $_scope = 'parent';
  7449. +            } else {
  7450. +                $_scope = 'local';
  7451. +            }
  7452. +        }
  7453. +
  7454. +        $_params = array('resource_name' => $_file,
  7455. +                         'resource_base_path' => $smarty->config_dir,
  7456. +                         'get_source' => false);
  7457. +        $smarty->_parse_resource_name($_params);
  7458. +        $_file_path = $_params['resource_type'] . ':' . $_params['resource_name'];
  7459. +        if (isset($_section))
  7460. +            $_compile_file = $smarty->_get_compile_path($_file_path.'|'.$_section);
  7461. +        else
  7462. +            $_compile_file = $smarty->_get_compile_path($_file_path);
  7463. +
  7464. +        if($smarty->force_compile || !file_exists($_compile_file)) {
  7465. +            $_compile = true;
  7466. +        } elseif ($smarty->compile_check) {
  7467. +            $_params = array('resource_name' => $_file,
  7468. +                             'resource_base_path' => $smarty->config_dir,
  7469. +                             'get_source' => false);
  7470. +            $_compile = $smarty->_fetch_resource_info($_params) &&
  7471. +                $_params['resource_timestamp'] > filemtime($_compile_file);
  7472. +        } else {
  7473. +            $_compile = false;
  7474. +        }
  7475. +
  7476. +        if($_compile) {
  7477. +            // compile config file
  7478. +            if(!is_object($smarty->_conf_obj)) {
  7479. +                require_once SMARTY_DIR . $smarty->config_class . '.class.php';
  7480. +                $smarty->_conf_obj = new $smarty->config_class();
  7481. +                $smarty->_conf_obj->overwrite = $smarty->config_overwrite;
  7482. +                $smarty->_conf_obj->booleanize = $smarty->config_booleanize;
  7483. +                $smarty->_conf_obj->read_hidden = $smarty->config_read_hidden;
  7484. +                $smarty->_conf_obj->fix_newlines = $smarty->config_fix_newlines;
  7485. +            }
  7486. +
  7487. +            $_params = array('resource_name' => $_file,
  7488. +                             'resource_base_path' => $smarty->config_dir,
  7489. +                             $_params['get_source'] = true);
  7490. +            if (!$smarty->_fetch_resource_info($_params)) {
  7491. +                return;
  7492. +            }
  7493. +            $smarty->_conf_obj->set_file_contents($_file, $_params['source_content']);
  7494. +            $_config_vars = array_merge($smarty->_conf_obj->get($_file),
  7495. +                    $smarty->_conf_obj->get($_file, $_section));
  7496. +            if(function_exists('var_export')) {
  7497. +                $_output = '<?php $_config_vars = ' . var_export($_config_vars, true) . '; ?>';
  7498. +            } else {
  7499. +                $_output = '<?php $_config_vars = unserialize(\'' . strtr(serialize($_config_vars),array('\''=>'\\\'', '\\'=>'\\\\')) . '\'); ?>';
  7500. +            }
  7501. +            $_params = (array('compile_path' => $_compile_file, 'compiled_content' => $_output, 'resource_timestamp' => $_params['resource_timestamp']));
  7502. +            require_once(SMARTY_CORE_DIR . 'core.write_compiled_resource.php');
  7503. +            smarty_core_write_compiled_resource($_params, $smarty);
  7504. +        } else {
  7505. +            include($_compile_file);
  7506. +        }
  7507. +
  7508. +        if ($smarty->caching) {
  7509. +            $smarty->_cache_info['config'][$_file] = true;
  7510. +        }
  7511. +
  7512. +        $smarty->_config[0]['vars'] = @array_merge($smarty->_config[0]['vars'], $_config_vars);
  7513. +        $smarty->_config[0]['files'][$_file] = true;
  7514. +
  7515. +        if ($_scope == 'parent') {
  7516. +                $smarty->_config[1]['vars'] = @array_merge($smarty->_config[1]['vars'], $_config_vars);
  7517. +                $smarty->_config[1]['files'][$_file] = true;
  7518. +        } else if ($_scope == 'global') {
  7519. +            for ($i = 1, $for_max = count($smarty->_config); $i < $for_max; $i++) {
  7520. +                $smarty->_config[$i]['vars'] = @array_merge($smarty->_config[$i]['vars'], $_config_vars);
  7521. +                $smarty->_config[$i]['files'][$_file] = true;
  7522. +            }
  7523. +        }
  7524. +
  7525. +        if ($smarty->debugging) {
  7526. +            $_params = array();
  7527. +            require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
  7528. +            $smarty->_smarty_debug_info[] = array('type'      => 'config',
  7529. +                                                'filename'  => $_file.' ['.$_section.'] '.$_scope,
  7530. +                                                'depth'     => $smarty->_inclusion_depth,
  7531. +                                                'exec_time' => smarty_core_get_microtime($_params, $smarty) - $_debug_start_time);
  7532. +        }
  7533. +
  7534. +}
  7535. +
  7536. +/* vim: set expandtab: */
  7537. +
  7538. +?>
  7539. diff --git a/library/smarty/plugins/function.counter.php b/library/smarty/plugins/function.counter.php
  7540. new file mode 100644
  7541. --- /dev/null
  7542. +++ b/library/smarty/plugins/function.counter.php
  7543. @@ -0,0 +1,80 @@
  7544. +<?php
  7545. +/**
  7546. + * Smarty plugin
  7547. + * @package Smarty
  7548. + * @subpackage plugins
  7549. + */
  7550. +
  7551. +
  7552. +/**
  7553. + * Smarty {counter} function plugin
  7554. + *
  7555. + * Type:     function<br>
  7556. + * Name:     counter<br>
  7557. + * Purpose:  print out a counter value
  7558. + * @author Monte Ohrt <monte at ohrt dot com>
  7559. + * @link http://smarty.php.net/manual/en/language.function.counter.php {counter}
  7560. + *       (Smarty online manual)
  7561. + * @param array parameters
  7562. + * @param Smarty
  7563. + * @return string|null
  7564. + */
  7565. +function smarty_function_counter($params, &$smarty)
  7566. +{
  7567. +    static $counters = array();
  7568. +
  7569. +    $name = (isset($params['name'])) ? $params['name'] : 'default';
  7570. +    if (!isset($counters[$name])) {
  7571. +        $counters[$name] = array(
  7572. +            'start'=>1,
  7573. +            'skip'=>1,
  7574. +            'direction'=>'up',
  7575. +            'count'=>1
  7576. +            );
  7577. +    }
  7578. +    $counter =& $counters[$name];
  7579. +
  7580. +    if (isset($params['start'])) {
  7581. +        $counter['start'] = $counter['count'] = (int)$params['start'];
  7582. +    }
  7583. +
  7584. +    if (!empty($params['assign'])) {
  7585. +        $counter['assign'] = $params['assign'];
  7586. +    }
  7587. +
  7588. +    if (isset($counter['assign'])) {
  7589. +        $smarty->assign($counter['assign'], $counter['count']);
  7590. +    }
  7591. +    
  7592. +    if (isset($params['print'])) {
  7593. +        $print = (bool)$params['print'];
  7594. +    } else {
  7595. +        $print = empty($counter['assign']);
  7596. +    }
  7597. +
  7598. +    if ($print) {
  7599. +        $retval = $counter['count'];
  7600. +    } else {
  7601. +        $retval = null;
  7602. +    }
  7603. +
  7604. +    if (isset($params['skip'])) {
  7605. +        $counter['skip'] = $params['skip'];
  7606. +    }
  7607. +    
  7608. +    if (isset($params['direction'])) {
  7609. +        $counter['direction'] = $params['direction'];
  7610. +    }
  7611. +
  7612. +    if ($counter['direction'] == "down")
  7613. +        $counter['count'] -= $counter['skip'];
  7614. +    else
  7615. +        $counter['count'] += $counter['skip'];
  7616. +    
  7617. +    return $retval;
  7618. +    
  7619. +}
  7620. +
  7621. +/* vim: set expandtab: */
  7622. +
  7623. +?>
  7624. diff --git a/library/smarty/plugins/function.cycle.php b/library/smarty/plugins/function.cycle.php
  7625. new file mode 100644
  7626. --- /dev/null
  7627. +++ b/library/smarty/plugins/function.cycle.php
  7628. @@ -0,0 +1,102 @@
  7629. +<?php
  7630. +/**
  7631. + * Smarty plugin
  7632. + * @package Smarty
  7633. + * @subpackage plugins
  7634. + */
  7635. +
  7636. +/**
  7637. + * Smarty {cycle} function plugin
  7638. + *
  7639. + * Type:     function<br>
  7640. + * Name:     cycle<br>
  7641. + * Date:     May 3, 2002<br>
  7642. + * Purpose:  cycle through given values<br>
  7643. + * Input:
  7644. + *         - name = name of cycle (optional)
  7645. + *         - values = comma separated list of values to cycle,
  7646. + *                    or an array of values to cycle
  7647. + *                    (this can be left out for subsequent calls)
  7648. + *         - reset = boolean - resets given var to true
  7649. + *         - print = boolean - print var or not. default is true
  7650. + *         - advance = boolean - whether or not to advance the cycle
  7651. + *         - delimiter = the value delimiter, default is ","
  7652. + *         - assign = boolean, assigns to template var instead of
  7653. + *                    printed.
  7654. + *
  7655. + * Examples:<br>
  7656. + * <pre>
  7657. + * {cycle values="#eeeeee,#d0d0d0d"}
  7658. + * {cycle name=row values="one,two,three" reset=true}
  7659. + * {cycle name=row}
  7660. + * </pre>
  7661. + * @link http://smarty.php.net/manual/en/language.function.cycle.php {cycle}
  7662. + *       (Smarty online manual)
  7663. + * @author Monte Ohrt <monte at ohrt dot com>
  7664. + * @author credit to Mark Priatel <mpriatel@rogers.com>
  7665. + * @author credit to Gerard <gerard@interfold.com>
  7666. + * @author credit to Jason Sweat <jsweat_php@yahoo.com>
  7667. + * @version  1.3
  7668. + * @param array
  7669. + * @param Smarty
  7670. + * @return string|null
  7671. + */
  7672. +function smarty_function_cycle($params, &$smarty)
  7673. +{
  7674. +    static $cycle_vars;
  7675. +    
  7676. +    $name = (empty($params['name'])) ? 'default' : $params['name'];
  7677. +    $print = (isset($params['print'])) ? (bool)$params['print'] : true;
  7678. +    $advance = (isset($params['advance'])) ? (bool)$params['advance'] : true;
  7679. +    $reset = (isset($params['reset'])) ? (bool)$params['reset'] : false;
  7680. +            
  7681. +    if (!in_array('values', array_keys($params))) {
  7682. +        if(!isset($cycle_vars[$name]['values'])) {
  7683. +            $smarty->trigger_error("cycle: missing 'values' parameter");
  7684. +            return;
  7685. +        }
  7686. +    } else {
  7687. +        if(isset($cycle_vars[$name]['values'])
  7688. +            && $cycle_vars[$name]['values'] != $params['values'] ) {
  7689. +            $cycle_vars[$name]['index'] = 0;
  7690. +        }
  7691. +        $cycle_vars[$name]['values'] = $params['values'];
  7692. +    }
  7693. +
  7694. +    $cycle_vars[$name]['delimiter'] = (isset($params['delimiter'])) ? $params['delimiter'] : ',';
  7695. +    
  7696. +    if(is_array($cycle_vars[$name]['values'])) {
  7697. +        $cycle_array = $cycle_vars[$name]['values'];
  7698. +    } else {
  7699. +        $cycle_array = explode($cycle_vars[$name]['delimiter'],$cycle_vars[$name]['values']);
  7700. +    }
  7701. +    
  7702. +    if(!isset($cycle_vars[$name]['index']) || $reset ) {
  7703. +        $cycle_vars[$name]['index'] = 0;
  7704. +    }
  7705. +    
  7706. +    if (isset($params['assign'])) {
  7707. +        $print = false;
  7708. +        $smarty->assign($params['assign'], $cycle_array[$cycle_vars[$name]['index']]);
  7709. +    }
  7710. +        
  7711. +    if($print) {
  7712. +        $retval = $cycle_array[$cycle_vars[$name]['index']];
  7713. +    } else {
  7714. +        $retval = null;
  7715. +    }
  7716. +
  7717. +    if($advance) {
  7718. +        if ( $cycle_vars[$name]['index'] >= count($cycle_array) -1 ) {
  7719. +            $cycle_vars[$name]['index'] = 0;
  7720. +        } else {
  7721. +            $cycle_vars[$name]['index']++;
  7722. +        }
  7723. +    }
  7724. +    
  7725. +    return $retval;
  7726. +}
  7727. +
  7728. +/* vim: set expandtab: */
  7729. +
  7730. +?>
  7731. diff --git a/library/smarty/plugins/function.debug.php b/library/smarty/plugins/function.debug.php
  7732. new file mode 100644
  7733. --- /dev/null
  7734. +++ b/library/smarty/plugins/function.debug.php
  7735. @@ -0,0 +1,35 @@
  7736. +<?php
  7737. +/**
  7738. + * Smarty plugin
  7739. + * @package Smarty
  7740. + * @subpackage plugins
  7741. + */
  7742. +
  7743. +
  7744. +/**
  7745. + * Smarty {debug} function plugin
  7746. + *
  7747. + * Type:     function<br>
  7748. + * Name:     debug<br>
  7749. + * Date:     July 1, 2002<br>
  7750. + * Purpose:  popup debug window
  7751. + * @link http://smarty.php.net/manual/en/language.function.debug.php {debug}
  7752. + *       (Smarty online manual)
  7753. + * @author   Monte Ohrt <monte at ohrt dot com>
  7754. + * @version  1.0
  7755. + * @param array
  7756. + * @param Smarty
  7757. + * @return string output from {@link Smarty::_generate_debug_output()}
  7758. + */
  7759. +function smarty_function_debug($params, &$smarty)
  7760. +{
  7761. +    if (isset($params['output'])) {
  7762. +        $smarty->assign('_smarty_debug_output', $params['output']);
  7763. +    }
  7764. +    require_once(SMARTY_CORE_DIR . 'core.display_debug_console.php');
  7765. +    return smarty_core_display_debug_console(null, $smarty);
  7766. +}
  7767. +
  7768. +/* vim: set expandtab: */
  7769. +
  7770. +?>
  7771. diff --git a/library/smarty/plugins/function.eval.php b/library/smarty/plugins/function.eval.php
  7772. new file mode 100644
  7773. --- /dev/null
  7774. +++ b/library/smarty/plugins/function.eval.php
  7775. @@ -0,0 +1,49 @@
  7776. +<?php
  7777. +/**
  7778. + * Smarty plugin
  7779. + * @package Smarty
  7780. + * @subpackage plugins
  7781. + */
  7782. +
  7783. +
  7784. +/**
  7785. + * Smarty {eval} function plugin
  7786. + *
  7787. + * Type:     function<br>
  7788. + * Name:     eval<br>
  7789. + * Purpose:  evaluate a template variable as a template<br>
  7790. + * @link http://smarty.php.net/manual/en/language.function.eval.php {eval}
  7791. + *       (Smarty online manual)
  7792. + * @author Monte Ohrt <monte at ohrt dot com>
  7793. + * @param array
  7794. + * @param Smarty
  7795. + */
  7796. +function smarty_function_eval($params, &$smarty)
  7797. +{
  7798. +
  7799. +    if (!isset($params['var'])) {
  7800. +        $smarty->trigger_error("eval: missing 'var' parameter");
  7801. +        return;
  7802. +    }
  7803. +
  7804. +    if($params['var'] == '') {
  7805. +        return;
  7806. +    }
  7807. +
  7808. +    $smarty->_compile_source('evaluated template', $params['var'], $_var_compiled);
  7809. +
  7810. +    ob_start();
  7811. +    $smarty->_eval('?>' . $_var_compiled);
  7812. +    $_contents = ob_get_contents();
  7813. +    ob_end_clean();
  7814. +
  7815. +    if (!empty($params['assign'])) {
  7816. +        $smarty->assign($params['assign'], $_contents);
  7817. +    } else {
  7818. +        return $_contents;
  7819. +    }
  7820. +}
  7821. +
  7822. +/* vim: set expandtab: */
  7823. +
  7824. +?>
  7825. diff --git a/library/smarty/plugins/function.fetch.php b/library/smarty/plugins/function.fetch.php
  7826. new file mode 100644
  7827. --- /dev/null
  7828. +++ b/library/smarty/plugins/function.fetch.php
  7829. @@ -0,0 +1,221 @@
  7830. +<?php
  7831. +/**
  7832. + * Smarty plugin
  7833. + * @package Smarty
  7834. + * @subpackage plugins
  7835. + */
  7836. +
  7837. +
  7838. +/**
  7839. + * Smarty {fetch} plugin
  7840. + *
  7841. + * Type:     function<br>
  7842. + * Name:     fetch<br>
  7843. + * Purpose:  fetch file, web or ftp data and display results
  7844. + * @link http://smarty.php.net/manual/en/language.function.fetch.php {fetch}
  7845. + *       (Smarty online manual)
  7846. + * @author Monte Ohrt <monte at ohrt dot com>
  7847. + * @param array
  7848. + * @param Smarty
  7849. + * @return string|null if the assign parameter is passed, Smarty assigns the
  7850. + *                     result to a template variable
  7851. + */
  7852. +function smarty_function_fetch($params, &$smarty)
  7853. +{
  7854. +    if (empty($params['file'])) {
  7855. +        $smarty->_trigger_fatal_error("[plugin] parameter 'file' cannot be empty");
  7856. +        return;
  7857. +    }
  7858. +
  7859. +    $content = '';
  7860. +    if ($smarty->security && !preg_match('!^(http|ftp)://!i', $params['file'])) {
  7861. +        $_params = array('resource_type' => 'file', 'resource_name' => $params['file']);
  7862. +        require_once(SMARTY_CORE_DIR . 'core.is_secure.php');
  7863. +        if(!smarty_core_is_secure($_params, $smarty)) {
  7864. +            $smarty->_trigger_fatal_error('[plugin] (secure mode) fetch \'' . $params['file'] . '\' is not allowed');
  7865. +            return;
  7866. +        }
  7867. +        
  7868. +        // fetch the file
  7869. +        if($fp = @fopen($params['file'],'r')) {
  7870. +            while(!feof($fp)) {
  7871. +                $content .= fgets ($fp,4096);
  7872. +            }
  7873. +            fclose($fp);
  7874. +        } else {
  7875. +            $smarty->_trigger_fatal_error('[plugin] fetch cannot read file \'' . $params['file'] . '\'');
  7876. +            return;
  7877. +        }
  7878. +    } else {
  7879. +        // not a local file
  7880. +        if(preg_match('!^http://!i',$params['file'])) {
  7881. +            // http fetch
  7882. +            if($uri_parts = parse_url($params['file'])) {
  7883. +                // set defaults
  7884. +                $host = $server_name = $uri_parts['host'];
  7885. +                $timeout = 30;
  7886. +                $accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*";
  7887. +                $agent = "Smarty Template Engine ".$smarty->_version;
  7888. +                $referer = "";
  7889. +                $uri = !empty($uri_parts['path']) ? $uri_parts['path'] : '/';
  7890. +                $uri .= !empty($uri_parts['query']) ? '?' . $uri_parts['query'] : '';
  7891. +                $_is_proxy = false;
  7892. +                if(empty($uri_parts['port'])) {
  7893. +                    $port = 80;
  7894. +                } else {
  7895. +                    $port = $uri_parts['port'];
  7896. +                }
  7897. +                if(!empty($uri_parts['user'])) {
  7898. +                    $user = $uri_parts['user'];
  7899. +                }
  7900. +                if(!empty($uri_parts['pass'])) {
  7901. +                    $pass = $uri_parts['pass'];
  7902. +                }
  7903. +                // loop through parameters, setup headers
  7904. +                foreach($params as $param_key => $param_value) {
  7905. +                    switch($param_key) {
  7906. +                        case "file":
  7907. +                        case "assign":
  7908. +                        case "assign_headers":
  7909. +                            break;
  7910. +                        case "user":
  7911. +                            if(!empty($param_value)) {
  7912. +                                $user = $param_value;
  7913. +                            }
  7914. +                            break;
  7915. +                        case "pass":
  7916. +                            if(!empty($param_value)) {
  7917. +                                $pass = $param_value;
  7918. +                            }
  7919. +                            break;
  7920. +                        case "accept":
  7921. +                            if(!empty($param_value)) {
  7922. +                                $accept = $param_value;
  7923. +                            }
  7924. +                            break;
  7925. +                        case "header":
  7926. +                            if(!empty($param_value)) {
  7927. +                                if(!preg_match('![\w\d-]+: .+!',$param_value)) {
  7928. +                                    $smarty->_trigger_fatal_error("[plugin] invalid header format '".$param_value."'");
  7929. +                                    return;
  7930. +                                } else {
  7931. +                                    $extra_headers[] = $param_value;
  7932. +                                }
  7933. +                            }
  7934. +                            break;
  7935. +                        case "proxy_host":
  7936. +                            if(!empty($param_value)) {
  7937. +                                $proxy_host = $param_value;
  7938. +                            }
  7939. +                            break;
  7940. +                        case "proxy_port":
  7941. +                            if(!preg_match('!\D!', $param_value)) {
  7942. +                                $proxy_port = (int) $param_value;
  7943. +                            } else {
  7944. +                                $smarty->_trigger_fatal_error("[plugin] invalid value for attribute '".$param_key."'");
  7945. +                                return;
  7946. +                            }
  7947. +                            break;
  7948. +                        case "agent":
  7949. +                            if(!empty($param_value)) {
  7950. +                                $agent = $param_value;
  7951. +                            }
  7952. +                            break;
  7953. +                        case "referer":
  7954. +                            if(!empty($param_value)) {
  7955. +                                $referer = $param_value;
  7956. +                            }
  7957. +                            break;
  7958. +                        case "timeout":
  7959. +                            if(!preg_match('!\D!', $param_value)) {
  7960. +                                $timeout = (int) $param_value;
  7961. +                            } else {
  7962. +                                $smarty->_trigger_fatal_error("[plugin] invalid value for attribute '".$param_key."'");
  7963. +                                return;
  7964. +                            }
  7965. +                            break;
  7966. +                        default:
  7967. +                            $smarty->_trigger_fatal_error("[plugin] unrecognized attribute '".$param_key."'");
  7968. +                            return;
  7969. +                    }
  7970. +                }
  7971. +                if(!empty($proxy_host) && !empty($proxy_port)) {
  7972. +                    $_is_proxy = true;
  7973. +                    $fp = fsockopen($proxy_host,$proxy_port,$errno,$errstr,$timeout);
  7974. +                } else {
  7975. +                    $fp = fsockopen($server_name,$port,$errno,$errstr,$timeout);
  7976. +                }
  7977. +
  7978. +                if(!$fp) {
  7979. +                    $smarty->_trigger_fatal_error("[plugin] unable to fetch: $errstr ($errno)");
  7980. +                    return;
  7981. +                } else {
  7982. +                    if($_is_proxy) {
  7983. +                        fputs($fp, 'GET ' . $params['file'] . " HTTP/1.0\r\n");
  7984. +                    } else {
  7985. +                        fputs($fp, "GET $uri HTTP/1.0\r\n");
  7986. +                    }
  7987. +                    if(!empty($host)) {
  7988. +                        fputs($fp, "Host: $host\r\n");
  7989. +                    }
  7990. +                    if(!empty($accept)) {
  7991. +                        fputs($fp, "Accept: $accept\r\n");
  7992. +                    }
  7993. +                    if(!empty($agent)) {
  7994. +                        fputs($fp, "User-Agent: $agent\r\n");
  7995. +                    }
  7996. +                    if(!empty($referer)) {
  7997. +                        fputs($fp, "Referer: $referer\r\n");
  7998. +                    }
  7999. +                    if(isset($extra_headers) && is_array($extra_headers)) {
  8000. +                        foreach($extra_headers as $curr_header) {
  8001. +                            fputs($fp, $curr_header."\r\n");
  8002. +                        }
  8003. +                    }
  8004. +                    if(!empty($user) && !empty($pass)) {
  8005. +                        fputs($fp, "Authorization: BASIC ".base64_encode("$user:$pass")."\r\n");
  8006. +                    }
  8007. +
  8008. +                    fputs($fp, "\r\n");
  8009. +                    while(!feof($fp)) {
  8010. +                        $content .= fgets($fp,4096);
  8011. +                    }
  8012. +                    fclose($fp);
  8013. +                    $csplit = split("\r\n\r\n",$content,2);
  8014. +
  8015. +                    $content = $csplit[1];
  8016. +
  8017. +                    if(!empty($params['assign_headers'])) {
  8018. +                        $smarty->assign($params['assign_headers'],split("\r\n",$csplit[0]));
  8019. +                    }
  8020. +                }
  8021. +            } else {
  8022. +                $smarty->_trigger_fatal_error("[plugin] unable to parse URL, check syntax");
  8023. +                return;
  8024. +            }
  8025. +        } else {
  8026. +            // ftp fetch
  8027. +            if($fp = @fopen($params['file'],'r')) {
  8028. +                while(!feof($fp)) {
  8029. +                    $content .= fgets ($fp,4096);
  8030. +                }
  8031. +                fclose($fp);
  8032. +            } else {
  8033. +                $smarty->_trigger_fatal_error('[plugin] fetch cannot read file \'' . $params['file'] .'\'');
  8034. +                return;
  8035. +            }
  8036. +        }
  8037. +
  8038. +    }
  8039. +
  8040. +
  8041. +    if (!empty($params['assign'])) {
  8042. +        $smarty->assign($params['assign'],$content);
  8043. +    } else {
  8044. +        return $content;
  8045. +    }
  8046. +}
  8047. +
  8048. +/* vim: set expandtab: */
  8049. +
  8050. +?>
  8051. diff --git a/library/smarty/plugins/function.html_checkboxes.php b/library/smarty/plugins/function.html_checkboxes.php
  8052. new file mode 100644
  8053. --- /dev/null
  8054. +++ b/library/smarty/plugins/function.html_checkboxes.php
  8055. @@ -0,0 +1,143 @@
  8056. +<?php
  8057. +/**
  8058. + * Smarty plugin
  8059. + * @package Smarty
  8060. + * @subpackage plugins
  8061. + */
  8062. +
  8063. +
  8064. +/**
  8065. + * Smarty {html_checkboxes} function plugin
  8066. + *
  8067. + * File:       function.html_checkboxes.php<br>
  8068. + * Type:       function<br>
  8069. + * Name:       html_checkboxes<br>
  8070. + * Date:       24.Feb.2003<br>
  8071. + * Purpose:    Prints out a list of checkbox input types<br>
  8072. + * Input:<br>
  8073. + *           - name       (optional) - string default "checkbox"
  8074. + *           - values     (required) - array
  8075. + *           - options    (optional) - associative array
  8076. + *           - checked    (optional) - array default not set
  8077. + *           - separator  (optional) - ie <br> or &nbsp;
  8078. + *           - output     (optional) - the output next to each checkbox
  8079. + *           - assign     (optional) - assign the output as an array to this variable
  8080. + * Examples:
  8081. + * <pre>
  8082. + * {html_checkboxes values=$ids output=$names}
  8083. + * {html_checkboxes values=$ids name='box' separator='<br>' output=$names}
  8084. + * {html_checkboxes values=$ids checked=$checked separator='<br>' output=$names}
  8085. + * </pre>
  8086. + * @link http://smarty.php.net/manual/en/language.function.html.checkboxes.php {html_checkboxes}
  8087. + *      (Smarty online manual)
  8088. + * @author     Christopher Kvarme <christopher.kvarme@flashjab.com>
  8089. + * @author credits to Monte Ohrt <monte at ohrt dot com>
  8090. + * @version    1.0
  8091. + * @param array
  8092. + * @param Smarty
  8093. + * @return string
  8094. + * @uses smarty_function_escape_special_chars()
  8095. + */
  8096. +function smarty_function_html_checkboxes($params, &$smarty)
  8097. +{
  8098. +    require_once $smarty->_get_plugin_filepath('shared','escape_special_chars');
  8099. +
  8100. +    $name = 'checkbox';
  8101. +    $values = null;
  8102. +    $options = null;
  8103. +    $selected = null;
  8104. +    $separator = '';
  8105. +    $labels = true;
  8106. +    $output = null;
  8107. +
  8108. +    $extra = '';
  8109. +
  8110. +    foreach($params as $_key => $_val) {
  8111. +        switch($_key) {
  8112. +            case 'name':
  8113. +            case 'separator':
  8114. +                $$_key = $_val;
  8115. +                break;
  8116. +
  8117. +            case 'labels':
  8118. +                $$_key = (bool)$_val;
  8119. +                break;
  8120. +
  8121. +            case 'options':
  8122. +                $$_key = (array)$_val;
  8123. +                break;
  8124. +
  8125. +            case 'values':
  8126. +            case 'output':
  8127. +                $$_key = array_values((array)$_val);
  8128. +                break;
  8129. +
  8130. +            case 'checked':
  8131. +            case 'selected':
  8132. +                $selected = array_map('strval', array_values((array)$_val));
  8133. +                break;
  8134. +
  8135. +            case 'checkboxes':
  8136. +                $smarty->trigger_error('html_checkboxes: the use of the "checkboxes" attribute is deprecated, use "options" instead', E_USER_WARNING);
  8137. +                $options = (array)$_val;
  8138. +                break;
  8139. +
  8140. +            case 'assign':
  8141. +                break;
  8142. +
  8143. +            default:
  8144. +                if(!is_array($_val)) {
  8145. +                    $extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"';
  8146. +                } else {
  8147. +                    $smarty->trigger_error("html_checkboxes: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
  8148. +                }
  8149. +                break;
  8150. +        }
  8151. +    }
  8152. +
  8153. +    if (!isset($options) && !isset($values))
  8154. +        return ''; /* raise error here? */
  8155. +
  8156. +    settype($selected, 'array');
  8157. +    $_html_result = array();
  8158. +
  8159. +    if (isset($options)) {
  8160. +
  8161. +        foreach ($options as $_key=>$_val)
  8162. +            $_html_result[] = smarty_function_html_checkboxes_output($name, $_key, $_val, $selected, $extra, $separator, $labels);
  8163. +
  8164. +
  8165. +    } else {
  8166. +        foreach ($values as $_i=>$_key) {
  8167. +            $_val = isset($output[$_i]) ? $output[$_i] : '';
  8168. +            $_html_result[] = smarty_function_html_checkboxes_output($name, $_key, $_val, $selected, $extra, $separator, $labels);
  8169. +        }
  8170. +
  8171. +    }
  8172. +
  8173. +    if(!empty($params['assign'])) {
  8174. +        $smarty->assign($params['assign'], $_html_result);
  8175. +    } else {
  8176. +        return implode("\n",$_html_result);
  8177. +    }
  8178. +
  8179. +}
  8180. +
  8181. +function smarty_function_html_checkboxes_output($name, $value, $output, $selected, $extra, $separator, $labels) {
  8182. +    $_output = '';
  8183. +    if ($labels) $_output .= '<label>';
  8184. +    $_output .= '<input type="checkbox" name="'
  8185. +        . smarty_function_escape_special_chars($name) . '[]" value="'
  8186. +        . smarty_function_escape_special_chars($value) . '"';
  8187. +
  8188. +    if (in_array((string)$value, $selected)) {
  8189. +        $_output .= ' checked="checked"';
  8190. +    }
  8191. +    $_output .= $extra . ' />' . $output;
  8192. +    if ($labels) $_output .= '</label>';
  8193. +    $_output .=  $separator;
  8194. +
  8195. +    return $_output;
  8196. +}
  8197. +
  8198. +?>
  8199. diff --git a/library/smarty/plugins/function.html_image.php b/library/smarty/plugins/function.html_image.php
  8200. new file mode 100644
  8201. --- /dev/null
  8202. +++ b/library/smarty/plugins/function.html_image.php
  8203. @@ -0,0 +1,142 @@
  8204. +<?php
  8205. +/**
  8206. + * Smarty plugin
  8207. + * @package Smarty
  8208. + * @subpackage plugins
  8209. + */
  8210. +
  8211. +
  8212. +/**
  8213. + * Smarty {html_image} function plugin
  8214. + *
  8215. + * Type:     function<br>
  8216. + * Name:     html_image<br>
  8217. + * Date:     Feb 24, 2003<br>
  8218. + * Purpose:  format HTML tags for the image<br>
  8219. + * Input:<br>
  8220. + *         - file = file (and path) of image (required)
  8221. + *         - height = image height (optional, default actual height)
  8222. + *         - width = image width (optional, default actual width)
  8223. + *         - basedir = base directory for absolute paths, default
  8224. + *                     is environment variable DOCUMENT_ROOT
  8225. + *         - path_prefix = prefix for path output (optional, default empty)
  8226. + *
  8227. + * Examples: {html_image file="/images/masthead.gif"}
  8228. + * Output:   <img src="/images/masthead.gif" width=400 height=23>
  8229. + * @link http://smarty.php.net/manual/en/language.function.html.image.php {html_image}
  8230. + *      (Smarty online manual)
  8231. + * @author   Monte Ohrt <monte at ohrt dot com>
  8232. + * @author credits to Duda <duda@big.hu> - wrote first image function
  8233. + *           in repository, helped with lots of functionality
  8234. + * @version  1.0
  8235. + * @param array
  8236. + * @param Smarty
  8237. + * @return string
  8238. + * @uses smarty_function_escape_special_chars()
  8239. + */
  8240. +function smarty_function_html_image($params, &$smarty)
  8241. +{
  8242. +    require_once $smarty->_get_plugin_filepath('shared','escape_special_chars');
  8243. +    
  8244. +    $alt = '';
  8245. +    $file = '';
  8246. +    $height = '';
  8247. +    $width = '';
  8248. +    $extra = '';
  8249. +    $prefix = '';
  8250. +    $suffix = '';
  8251. +    $path_prefix = '';
  8252. +    $server_vars = ($smarty->request_use_auto_globals) ? $_SERVER : $GLOBALS['HTTP_SERVER_VARS'];
  8253. +    $basedir = isset($server_vars['DOCUMENT_ROOT']) ? $server_vars['DOCUMENT_ROOT'] : '';
  8254. +    foreach($params as $_key => $_val) {
  8255. +        switch($_key) {
  8256. +            case 'file':
  8257. +            case 'height':
  8258. +            case 'width':
  8259. +            case 'dpi':
  8260. +            case 'path_prefix':
  8261. +            case 'basedir':
  8262. +                $$_key = $_val;
  8263. +                break;
  8264. +
  8265. +            case 'alt':
  8266. +                if(!is_array($_val)) {
  8267. +                    $$_key = smarty_function_escape_special_chars($_val);
  8268. +                } else {
  8269. +                    $smarty->trigger_error("html_image: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
  8270. +                }
  8271. +                break;
  8272. +
  8273. +            case 'link':
  8274. +            case 'href':
  8275. +                $prefix = '<a href="' . $_val . '">';
  8276. +                $suffix = '</a>';
  8277. +                break;
  8278. +
  8279. +            default:
  8280. +                if(!is_array($_val)) {
  8281. +                    $extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"';
  8282. +                } else {
  8283. +                    $smarty->trigger_error("html_image: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
  8284. +                }
  8285. +                break;
  8286. +        }
  8287. +    }
  8288. +
  8289. +    if (empty($file)) {
  8290. +        $smarty->trigger_error("html_image: missing 'file' parameter", E_USER_NOTICE);
  8291. +        return;
  8292. +    }
  8293. +
  8294. +    if (substr($file,0,1) == '/') {
  8295. +        $_image_path = $basedir . $file;
  8296. +    } else {
  8297. +        $_image_path = $file;
  8298. +    }
  8299. +    
  8300. +    if(!isset($params['width']) || !isset($params['height'])) {
  8301. +        if(!$_image_data = @getimagesize($_image_path)) {
  8302. +            if(!file_exists($_image_path)) {
  8303. +                $smarty->trigger_error("html_image: unable to find '$_image_path'", E_USER_NOTICE);
  8304. +                return;
  8305. +            } else if(!is_readable($_image_path)) {
  8306. +                $smarty->trigger_error("html_image: unable to read '$_image_path'", E_USER_NOTICE);
  8307. +                return;
  8308. +            } else {
  8309. +                $smarty->trigger_error("html_image: '$_image_path' is not a valid image file", E_USER_NOTICE);
  8310. +                return;
  8311. +            }
  8312. +        }
  8313. +        if ($smarty->security &&
  8314. +            ($_params = array('resource_type' => 'file', 'resource_name' => $_image_path)) &&
  8315. +            (require_once(SMARTY_CORE_DIR . 'core.is_secure.php')) &&
  8316. +            (!smarty_core_is_secure($_params, $smarty)) ) {
  8317. +            $smarty->trigger_error("html_image: (secure) '$_image_path' not in secure directory", E_USER_NOTICE);
  8318. +        }        
  8319. +        
  8320. +        if(!isset($params['width'])) {
  8321. +            $width = $_image_data[0];
  8322. +        }
  8323. +        if(!isset($params['height'])) {
  8324. +            $height = $_image_data[1];
  8325. +        }
  8326. +
  8327. +    }
  8328. +
  8329. +    if(isset($params['dpi'])) {
  8330. +        if(strstr($server_vars['HTTP_USER_AGENT'], 'Mac')) {
  8331. +            $dpi_default = 72;
  8332. +        } else {
  8333. +            $dpi_default = 96;
  8334. +        }
  8335. +        $_resize = $dpi_default/$params['dpi'];
  8336. +        $width = round($width * $_resize);
  8337. +        $height = round($height * $_resize);
  8338. +    }
  8339. +
  8340. +    return $prefix . '<img src="'.$path_prefix.$file.'" alt="'.$alt.'" width="'.$width.'" height="'.$height.'"'.$extra.' />' . $suffix;
  8341. +}
  8342. +
  8343. +/* vim: set expandtab: */
  8344. +
  8345. +?>
  8346. diff --git a/library/smarty/plugins/function.html_options.php b/library/smarty/plugins/function.html_options.php
  8347. new file mode 100644
  8348. --- /dev/null
  8349. +++ b/library/smarty/plugins/function.html_options.php
  8350. @@ -0,0 +1,122 @@
  8351. +<?php
  8352. +/**
  8353. + * Smarty plugin
  8354. + * @package Smarty
  8355. + * @subpackage plugins
  8356. + */
  8357. +
  8358. +
  8359. +/**
  8360. + * Smarty {html_options} function plugin
  8361. + *
  8362. + * Type:     function<br>
  8363. + * Name:     html_options<br>
  8364. + * Input:<br>
  8365. + *           - name       (optional) - string default "select"
  8366. + *           - values     (required if no options supplied) - array
  8367. + *           - options    (required if no values supplied) - associative array
  8368. + *           - selected   (optional) - string default not set
  8369. + *           - output     (required if not options supplied) - array
  8370. + * Purpose:  Prints the list of <option> tags generated from
  8371. + *           the passed parameters
  8372. + * @link http://smarty.php.net/manual/en/language.function.html.options.php {html_image}
  8373. + *      (Smarty online manual)
  8374. + * @author Monte Ohrt <monte at ohrt dot com>
  8375. + * @param array
  8376. + * @param Smarty
  8377. + * @return string
  8378. + * @uses smarty_function_escape_special_chars()
  8379. + */
  8380. +function smarty_function_html_options($params, &$smarty)
  8381. +{
  8382. +    require_once $smarty->_get_plugin_filepath('shared','escape_special_chars');
  8383. +    
  8384. +    $name = null;
  8385. +    $values = null;
  8386. +    $options = null;
  8387. +    $selected = array();
  8388. +    $output = null;
  8389. +    
  8390. +    $extra = '';
  8391. +    
  8392. +    foreach($params as $_key => $_val) {
  8393. +        switch($_key) {
  8394. +            case 'name':
  8395. +                $$_key = (string)$_val;
  8396. +                break;
  8397. +            
  8398. +            case 'options':
  8399. +                $$_key = (array)$_val;
  8400. +                break;
  8401. +                
  8402. +            case 'values':
  8403. +            case 'output':
  8404. +                $$_key = array_values((array)$_val);
  8405. +                break;
  8406. +
  8407. +            case 'selected':
  8408. +                $$_key = array_map('strval', array_values((array)$_val));
  8409. +                break;
  8410. +                
  8411. +            default:
  8412. +                if(!is_array($_val)) {
  8413. +                    $extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"';
  8414. +                } else {
  8415. +                    $smarty->trigger_error("html_options: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
  8416. +                }
  8417. +                break;
  8418. +        }
  8419. +    }
  8420. +
  8421. +    if (!isset($options) && !isset($values))
  8422. +        return ''; /* raise error here? */
  8423. +
  8424. +    $_html_result = '';
  8425. +
  8426. +    if (isset($options)) {
  8427. +        
  8428. +        foreach ($options as $_key=>$_val)
  8429. +            $_html_result .= smarty_function_html_options_optoutput($_key, $_val, $selected);
  8430. +
  8431. +    } else {
  8432. +        
  8433. +        foreach ($values as $_i=>$_key) {
  8434. +            $_val = isset($output[$_i]) ? $output[$_i] : '';
  8435. +            $_html_result .= smarty_function_html_options_optoutput($_key, $_val, $selected);
  8436. +        }
  8437. +
  8438. +    }
  8439. +
  8440. +    if(!empty($name)) {
  8441. +        $_html_result = '<select name="' . $name . '"' . $extra . '>' . "\n" . $_html_result . '</select>' . "\n";
  8442. +    }
  8443. +
  8444. +    return $_html_result;
  8445. +
  8446. +}
  8447. +
  8448. +function smarty_function_html_options_optoutput($key, $value, $selected) {
  8449. +    if(!is_array($value)) {
  8450. +        $_html_result = '<option label="' . smarty_function_escape_special_chars($value) . '" value="' .
  8451. +            smarty_function_escape_special_chars($key) . '"';
  8452. +        if (in_array((string)$key, $selected))
  8453. +            $_html_result .= ' selected="selected"';
  8454. +        $_html_result .= '>' . smarty_function_escape_special_chars($value) . '</option>' . "\n";
  8455. +    } else {
  8456. +        $_html_result = smarty_function_html_options_optgroup($key, $value, $selected);
  8457. +    }
  8458. +    return $_html_result;
  8459. +}
  8460. +
  8461. +function smarty_function_html_options_optgroup($key, $values, $selected) {
  8462. +    $optgroup_html = '<optgroup label="' . smarty_function_escape_special_chars($key) . '">' . "\n";
  8463. +    foreach ($values as $key => $value) {
  8464. +        $optgroup_html .= smarty_function_html_options_optoutput($key, $value, $selected);
  8465. +    }
  8466. +    $optgroup_html .= "</optgroup>\n";
  8467. +    return $optgroup_html;
  8468. +}
  8469. +
  8470. +/* vim: set expandtab: */
  8471. +
  8472. +?>
  8473. diff --git a/library/smarty/plugins/function.html_radios.php b/library/smarty/plugins/function.html_radios.php
  8474. new file mode 100644
  8475. --- /dev/null
  8476. +++ b/library/smarty/plugins/function.html_radios.php
  8477. @@ -0,0 +1,156 @@
  8478. +<?php
  8479. +/**
  8480. + * Smarty plugin
  8481. + * @package Smarty
  8482. + * @subpackage plugins
  8483. + */
  8484. +
  8485. +
  8486. +/**
  8487. + * Smarty {html_radios} function plugin
  8488. + *
  8489. + * File:       function.html_radios.php<br>
  8490. + * Type:       function<br>
  8491. + * Name:       html_radios<br>
  8492. + * Date:       24.Feb.2003<br>
  8493. + * Purpose:    Prints out a list of radio input types<br>
  8494. + * Input:<br>
  8495. + *           - name       (optional) - string default "radio"
  8496. + *           - values     (required) - array
  8497. + *           - options    (optional) - associative array
  8498. + *           - checked    (optional) - array default not set
  8499. + *           - separator  (optional) - ie <br> or &nbsp;
  8500. + *           - output     (optional) - the output next to each radio button
  8501. + *           - assign     (optional) - assign the output as an array to this variable
  8502. + * Examples:
  8503. + * <pre>
  8504. + * {html_radios values=$ids output=$names}
  8505. + * {html_radios values=$ids name='box' separator='<br>' output=$names}
  8506. + * {html_radios values=$ids checked=$checked separator='<br>' output=$names}
  8507. + * </pre>
  8508. + * @link http://smarty.php.net/manual/en/language.function.html.radios.php {html_radios}
  8509. + *      (Smarty online manual)
  8510. + * @author     Christopher Kvarme <christopher.kvarme@flashjab.com>
  8511. + * @author credits to Monte Ohrt <monte at ohrt dot com>
  8512. + * @version    1.0
  8513. + * @param array
  8514. + * @param Smarty
  8515. + * @return string
  8516. + * @uses smarty_function_escape_special_chars()
  8517. + */
  8518. +function smarty_function_html_radios($params, &$smarty)
  8519. +{
  8520. +    require_once $smarty->_get_plugin_filepath('shared','escape_special_chars');
  8521. +  
  8522. +    $name = 'radio';
  8523. +    $values = null;
  8524. +    $options = null;
  8525. +    $selected = null;
  8526. +    $separator = '';
  8527. +    $labels = true;
  8528. +    $label_ids = false;
  8529. +    $output = null;
  8530. +    $extra = '';
  8531. +
  8532. +    foreach($params as $_key => $_val) {
  8533. +        switch($_key) {
  8534. +            case 'name':
  8535. +            case 'separator':
  8536. +                $$_key = (string)$_val;
  8537. +                break;
  8538. +
  8539. +            case 'checked':
  8540. +            case 'selected':
  8541. +                if(is_array($_val)) {
  8542. +                    $smarty->trigger_error('html_radios: the "' . $_key . '" attribute cannot be an array', E_USER_WARNING);
  8543. +                } else {
  8544. +                    $selected = (string)$_val;
  8545. +                }
  8546. +                break;
  8547. +
  8548. +            case 'labels':
  8549. +            case 'label_ids':
  8550. +                $$_key = (bool)$_val;
  8551. +                break;
  8552. +
  8553. +            case 'options':
  8554. +                $$_key = (array)$_val;
  8555. +                break;
  8556. +
  8557. +            case 'values':
  8558. +            case 'output':
  8559. +                $$_key = array_values((array)$_val);
  8560. +                break;
  8561. +
  8562. +            case 'radios':
  8563. +                $smarty->trigger_error('html_radios: the use of the "radios" attribute is deprecated, use "options" instead', E_USER_WARNING);
  8564. +                $options = (array)$_val;
  8565. +                break;
  8566. +
  8567. +            case 'assign':
  8568. +                break;
  8569. +
  8570. +            default:
  8571. +                if(!is_array($_val)) {
  8572. +                    $extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"';
  8573. +                } else {
  8574. +                    $smarty->trigger_error("html_radios: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
  8575. +                }
  8576. +                break;
  8577. +        }
  8578. +    }
  8579. +
  8580. +    if (!isset($options) && !isset($values))
  8581. +        return ''; /* raise error here? */
  8582. +
  8583. +    $_html_result = array();
  8584. +
  8585. +    if (isset($options)) {
  8586. +
  8587. +        foreach ($options as $_key=>$_val)
  8588. +            $_html_result[] = smarty_function_html_radios_output($name, $_key, $_val, $selected, $extra, $separator, $labels, $label_ids);
  8589. +
  8590. +    } else {
  8591. +
  8592. +        foreach ($values as $_i=>$_key) {
  8593. +            $_val = isset($output[$_i]) ? $output[$_i] : '';
  8594. +            $_html_result[] = smarty_function_html_radios_output($name, $_key, $_val, $selected, $extra, $separator, $labels, $label_ids);
  8595. +        }
  8596. +
  8597. +    }
  8598. +
  8599. +    if(!empty($params['assign'])) {
  8600. +        $smarty->assign($params['assign'], $_html_result);
  8601. +    } else {
  8602. +        return implode("\n",$_html_result);
  8603. +    }
  8604. +
  8605. +}
  8606. +
  8607. +function smarty_function_html_radios_output($name, $value, $output, $selected, $extra, $separator, $labels, $label_ids) {
  8608. +    $_output = '';
  8609. +    if ($labels) {
  8610. +      if($label_ids) {
  8611. +          $_id = smarty_function_escape_special_chars(preg_replace('![^\w\-\.]!', '_', $name . '_' . $value));
  8612. +          $_output .= '<label for="' . $_id . '">';
  8613. +      } else {
  8614. +          $_output .= '<label>';          
  8615. +      }
  8616. +   }
  8617. +   $_output .= '<input type="radio" name="'
  8618. +        . smarty_function_escape_special_chars($name) . '" value="'
  8619. +        . smarty_function_escape_special_chars($value) . '"';
  8620. +
  8621. +   if ($labels && $label_ids) $_output .= ' id="' . $_id . '"';
  8622. +
  8623. +    if ((string)$value==$selected) {
  8624. +        $_output .= ' checked="checked"';
  8625. +    }
  8626. +    $_output .= $extra . ' />' . $output;
  8627. +    if ($labels) $_output .= '</label>';
  8628. +    $_output .=  $separator;
  8629. +
  8630. +    return $_output;
  8631. +}
  8632. +
  8633. +?>
  8634. diff --git a/library/smarty/plugins/function.html_select_date.php b/library/smarty/plugins/function.html_select_date.php
  8635. new file mode 100644
  8636. --- /dev/null
  8637. +++ b/library/smarty/plugins/function.html_select_date.php
  8638. @@ -0,0 +1,331 @@
  8639. +<?php
  8640. +/**
  8641. + * Smarty plugin
  8642. + * @package Smarty
  8643. + * @subpackage plugins
  8644. + */
  8645. +
  8646. +/**
  8647. + * Smarty {html_select_date} plugin
  8648. + *
  8649. + * Type:     function<br>
  8650. + * Name:     html_select_date<br>
  8651. + * Purpose:  Prints the dropdowns for date selection.
  8652. + *
  8653. + * ChangeLog:<br>
  8654. + *           - 1.0 initial release
  8655. + *           - 1.1 added support for +/- N syntax for begin
  8656. + *                and end year values. (Monte)
  8657. + *           - 1.2 added support for yyyy-mm-dd syntax for
  8658. + *                time value. (Jan Rosier)
  8659. + *           - 1.3 added support for choosing format for
  8660. + *                month values (Gary Loescher)
  8661. + *           - 1.3.1 added support for choosing format for
  8662. + *                day values (Marcus Bointon)
  8663. + *           - 1.3.2 support negative timestamps, force year
  8664. + *             dropdown to include given date unless explicitly set (Monte)
  8665. + *           - 1.3.4 fix behaviour of 0000-00-00 00:00:00 dates to match that
  8666. + *             of 0000-00-00 dates (cybot, boots)
  8667. + * @link http://smarty.php.net/manual/en/language.function.html.select.date.php {html_select_date}
  8668. + *      (Smarty online manual)
  8669. + * @version 1.3.4
  8670. + * @author Andrei Zmievski
  8671. + * @author Monte Ohrt <monte at ohrt dot com>
  8672. + * @param array
  8673. + * @param Smarty
  8674. + * @return string
  8675. + */
  8676. +function smarty_function_html_select_date($params, &$smarty)
  8677. +{
  8678. +    require_once $smarty->_get_plugin_filepath('shared','escape_special_chars');
  8679. +    require_once $smarty->_get_plugin_filepath('shared','make_timestamp');
  8680. +    require_once $smarty->_get_plugin_filepath('function','html_options');
  8681. +    /* Default values. */
  8682. +    $prefix          = "Date_";
  8683. +    $start_year      = strftime("%Y");
  8684. +    $end_year        = $start_year;
  8685. +    $display_days    = true;
  8686. +    $display_months  = true;
  8687. +    $display_years   = true;
  8688. +    $month_format    = "%B";
  8689. +    /* Write months as numbers by default  GL */
  8690. +    $month_value_format = "%m";
  8691. +    $day_format      = "%02d";
  8692. +    /* Write day values using this format MB */
  8693. +    $day_value_format = "%d";
  8694. +    $year_as_text    = false;
  8695. +    /* Display years in reverse order? Ie. 2000,1999,.... */
  8696. +    $reverse_years   = false;
  8697. +    /* Should the select boxes be part of an array when returned from PHP?
  8698. +       e.g. setting it to "birthday", would create "birthday[Day]",
  8699. +       "birthday[Month]" & "birthday[Year]". Can be combined with prefix */
  8700. +    $field_array     = null;
  8701. +    /* <select size>'s of the different <select> tags.
  8702. +       If not set, uses default dropdown. */
  8703. +    $day_size        = null;
  8704. +    $month_size      = null;
  8705. +    $year_size       = null;
  8706. +    /* Unparsed attributes common to *ALL* the <select>/<input> tags.
  8707. +       An example might be in the template: all_extra ='class ="foo"'. */
  8708. +    $all_extra       = null;
  8709. +    /* Separate attributes for the tags. */
  8710. +    $day_extra       = null;
  8711. +    $month_extra     = null;
  8712. +    $year_extra      = null;
  8713. +    /* Order in which to display the fields.
  8714. +       "D" -> day, "M" -> month, "Y" -> year. */
  8715. +    $field_order     = 'MDY';
  8716. +    /* String printed between the different fields. */
  8717. +    $field_separator = "\n";
  8718. +    $time = time();
  8719. +    $all_empty       = null;
  8720. +    $day_empty       = null;
  8721. +    $month_empty     = null;
  8722. +    $year_empty      = null;
  8723. +    $extra_attrs     = '';
  8724. +
  8725. +    foreach ($params as $_key=>$_value) {
  8726. +        switch ($_key) {
  8727. +            case 'prefix':
  8728. +            case 'time':
  8729. +            case 'start_year':
  8730. +            case 'end_year':
  8731. +            case 'month_format':
  8732. +            case 'day_format':
  8733. +            case 'day_value_format':
  8734. +            case 'field_array':
  8735. +            case 'day_size':
  8736. +            case 'month_size':
  8737. +            case 'year_size':
  8738. +            case 'all_extra':
  8739. +            case 'day_extra':
  8740. +            case 'month_extra':
  8741. +            case 'year_extra':
  8742. +            case 'field_order':
  8743. +            case 'field_separator':
  8744. +            case 'month_value_format':
  8745. +            case 'month_empty':
  8746. +            case 'day_empty':
  8747. +            case 'year_empty':
  8748. +                $$_key = (string)$_value;
  8749. +                break;
  8750. +
  8751. +            case 'all_empty':
  8752. +                $$_key = (string)$_value;
  8753. +                $day_empty = $month_empty = $year_empty = $all_empty;
  8754. +                break;
  8755. +
  8756. +            case 'display_days':
  8757. +            case 'display_months':
  8758. +            case 'display_years':
  8759. +            case 'year_as_text':
  8760. +            case 'reverse_years':
  8761. +                $$_key = (bool)$_value;
  8762. +                break;
  8763. +
  8764. +            default:
  8765. +                if(!is_array($_value)) {
  8766. +                    $extra_attrs .= ' '.$_key.'="'.smarty_function_escape_special_chars($_value).'"';
  8767. +                } else {
  8768. +                    $smarty->trigger_error("html_select_date: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
  8769. +                }
  8770. +                break;
  8771. +        }
  8772. +    }
  8773. +
  8774. +    if (preg_match('!^-\d+$!', $time)) {
  8775. +        // negative timestamp, use date()
  8776. +        $time = date('Y-m-d', $time);
  8777. +    }
  8778. +    // If $time is not in format yyyy-mm-dd
  8779. +    if (preg_match('/^(\d{0,4}-\d{0,2}-\d{0,2})/', $time, $found)) {
  8780. +        $time = $found[1];
  8781. +    } else {
  8782. +        // use smarty_make_timestamp to get an unix timestamp and
  8783. +        // strftime to make yyyy-mm-dd
  8784. +        $time = strftime('%Y-%m-%d', smarty_make_timestamp($time));
  8785. +    }
  8786. +    // Now split this in pieces, which later can be used to set the select
  8787. +    $time = explode("-", $time);
  8788. +
  8789. +    // make syntax "+N" or "-N" work with start_year and end_year
  8790. +    if (preg_match('!^(\+|\-)\s*(\d+)$!', $end_year, $match)) {
  8791. +        if ($match[1] == '+') {
  8792. +            $end_year = strftime('%Y') + $match[2];
  8793. +        } else {
  8794. +            $end_year = strftime('%Y') - $match[2];
  8795. +        }
  8796. +    }
  8797. +    if (preg_match('!^(\+|\-)\s*(\d+)$!', $start_year, $match)) {
  8798. +        if ($match[1] == '+') {
  8799. +            $start_year = strftime('%Y') + $match[2];
  8800. +        } else {
  8801. +            $start_year = strftime('%Y') - $match[2];
  8802. +        }
  8803. +    }
  8804. +    if (strlen($time[0]) > 0) {
  8805. +        if ($start_year > $time[0] && !isset($params['start_year'])) {
  8806. +            // force start year to include given date if not explicitly set
  8807. +            $start_year = $time[0];
  8808. +        }
  8809. +        if($end_year < $time[0] && !isset($params['end_year'])) {
  8810. +            // force end year to include given date if not explicitly set
  8811. +            $end_year = $time[0];
  8812. +        }
  8813. +    }
  8814. +
  8815. +    $field_order = strtoupper($field_order);
  8816. +
  8817. +    $html_result = $month_result = $day_result = $year_result = "";
  8818. +
  8819. +    $field_separator_count = -1;
  8820. +    if ($display_months) {
  8821. +       $field_separator_count++;
  8822. +        $month_names = array();
  8823. +        $month_values = array();
  8824. +        if(isset($month_empty)) {
  8825. +            $month_names[''] = $month_empty;
  8826. +            $month_values[''] = '';
  8827. +        }
  8828. +        for ($i = 1; $i <= 12; $i++) {
  8829. +            $month_names[$i] = strftime($month_format, mktime(0, 0, 0, $i, 1, 2000));
  8830. +            $month_values[$i] = strftime($month_value_format, mktime(0, 0, 0, $i, 1, 2000));
  8831. +        }
  8832. +
  8833. +        $month_result .= '<select name=';
  8834. +        if (null !== $field_array){
  8835. +            $month_result .= '"' . $field_array . '[' . $prefix . 'Month]"';
  8836. +        } else {
  8837. +            $month_result .= '"' . $prefix . 'Month"';
  8838. +        }
  8839. +        if (null !== $month_size){
  8840. +            $month_result .= ' size="' . $month_size . '"';
  8841. +        }
  8842. +        if (null !== $month_extra){
  8843. +            $month_result .= ' ' . $month_extra;
  8844. +        }
  8845. +        if (null !== $all_extra){
  8846. +            $month_result .= ' ' . $all_extra;
  8847. +        }
  8848. +        $month_result .= $extra_attrs . '>'."\n";
  8849. +
  8850. +        $month_result .= smarty_function_html_options(array('output'     => $month_names,
  8851. +                                                            'values'     => $month_values,
  8852. +                                                            'selected'   => (int)$time[1] ? strftime($month_value_format, mktime(0, 0, 0, (int)$time[1], 1, 2000)) : '',
  8853. +                                                            'print_result' => false),
  8854. +                                                      $smarty);
  8855. +        $month_result .= '</select>';
  8856. +    }
  8857. +
  8858. +    if ($display_days) {
  8859. +       $field_separator_count++;
  8860. +        $days = array();
  8861. +        if (isset($day_empty)) {
  8862. +            $days[''] = $day_empty;
  8863. +            $day_values[''] = '';
  8864. +        }
  8865. +        for ($i = 1; $i <= 31; $i++) {
  8866. +            $days[] = sprintf($day_format, $i);
  8867. +            $day_values[] = sprintf($day_value_format, $i);
  8868. +        }
  8869. +
  8870. +        $day_result .= '<select name=';
  8871. +        if (null !== $field_array){
  8872. +            $day_result .= '"' . $field_array . '[' . $prefix . 'Day]"';
  8873. +        } else {
  8874. +            $day_result .= '"' . $prefix . 'Day"';
  8875. +        }
  8876. +        if (null !== $day_size){
  8877. +            $day_result .= ' size="' . $day_size . '"';
  8878. +        }
  8879. +        if (null !== $all_extra){
  8880. +            $day_result .= ' ' . $all_extra;
  8881. +        }
  8882. +        if (null !== $day_extra){
  8883. +            $day_result .= ' ' . $day_extra;
  8884. +        }
  8885. +        $day_result .= $extra_attrs . '>'."\n";
  8886. +        $day_result .= smarty_function_html_options(array('output'     => $days,
  8887. +                                                          'values'     => $day_values,
  8888. +                                                          'selected'   => $time[2],
  8889. +                                                          'print_result' => false),
  8890. +                                                    $smarty);
  8891. +        $day_result .= '</select>';
  8892. +    }
  8893. +
  8894. +    if ($display_years) {
  8895. +       $field_separator_count++;
  8896. +        if (null !== $field_array){
  8897. +            $year_name = $field_array . '[' . $prefix . 'Year]';
  8898. +        } else {
  8899. +            $year_name = $prefix . 'Year';
  8900. +        }
  8901. +        if ($year_as_text) {
  8902. +            $year_result .= '<input type="text" name="' . $year_name . '" value="' . $time[0] . '" size="4" maxlength="4"';
  8903. +            if (null !== $all_extra){
  8904. +                $year_result .= ' ' . $all_extra;
  8905. +            }
  8906. +            if (null !== $year_extra){
  8907. +                $year_result .= ' ' . $year_extra;
  8908. +            }
  8909. +            $year_result .= ' />';
  8910. +        } else {
  8911. +            $years = range((int)$start_year, (int)$end_year);
  8912. +            if ($reverse_years) {
  8913. +                rsort($years, SORT_NUMERIC);
  8914. +            } else {
  8915. +                sort($years, SORT_NUMERIC);
  8916. +            }
  8917. +            $yearvals = $years;
  8918. +            if(isset($year_empty)) {
  8919. +                array_unshift($years, $year_empty);
  8920. +                array_unshift($yearvals, '');
  8921. +            }
  8922. +            $year_result .= '<select name="' . $year_name . '"';
  8923. +            if (null !== $year_size){
  8924. +                $year_result .= ' size="' . $year_size . '"';
  8925. +            }
  8926. +            if (null !== $all_extra){
  8927. +                $year_result .= ' ' . $all_extra;
  8928. +            }
  8929. +            if (null !== $year_extra){
  8930. +                $year_result .= ' ' . $year_extra;
  8931. +            }
  8932. +            $year_result .= $extra_attrs . '>'."\n";
  8933. +            $year_result .= smarty_function_html_options(array('output' => $years,
  8934. +                                                               'values' => $yearvals,
  8935. +                                                               'selected'   => $time[0],
  8936. +                                                               'print_result' => false),
  8937. +                                                         $smarty);
  8938. +            $year_result .= '</select>';
  8939. +        }
  8940. +    }
  8941. +
  8942. +    // Loop thru the field_order field
  8943. +    for ($i = 0; $i <= 2; $i++){
  8944. +        $c = substr($field_order, $i, 1);
  8945. +        switch ($c){
  8946. +            case 'D':
  8947. +                $html_result .= $day_result;
  8948. +                break;
  8949. +
  8950. +            case 'M':
  8951. +                $html_result .= $month_result;
  8952. +                break;
  8953. +
  8954. +            case 'Y':
  8955. +                $html_result .= $year_result;
  8956. +                break;
  8957. +        }
  8958. +        // Add the field seperator
  8959. +        if($i < $field_separator_count) {
  8960. +            $html_result .= $field_separator;
  8961. +        }
  8962. +    }
  8963. +
  8964. +    return $html_result;
  8965. +}
  8966. +
  8967. +/* vim: set expandtab: */
  8968. +
  8969. +?>
  8970. diff --git a/library/smarty/plugins/function.html_select_time.php b/library/smarty/plugins/function.html_select_time.php
  8971. new file mode 100644
  8972. --- /dev/null
  8973. +++ b/library/smarty/plugins/function.html_select_time.php
  8974. @@ -0,0 +1,194 @@
  8975. +<?php
  8976. +/**
  8977. + * Smarty plugin
  8978. + * @package Smarty
  8979. + * @subpackage plugins
  8980. + */
  8981. +
  8982. +
  8983. +/**
  8984. + * Smarty {html_select_time} function plugin
  8985. + *
  8986. + * Type:     function<br>
  8987. + * Name:     html_select_time<br>
  8988. + * Purpose:  Prints the dropdowns for time selection
  8989. + * @link http://smarty.php.net/manual/en/language.function.html.select.time.php {html_select_time}
  8990. + *          (Smarty online manual)
  8991. + * @author Roberto Berto <roberto@berto.net>
  8992. + * @credits Monte Ohrt <monte AT ohrt DOT com>
  8993. + * @param array
  8994. + * @param Smarty
  8995. + * @return string
  8996. + * @uses smarty_make_timestamp()
  8997. + */
  8998. +function smarty_function_html_select_time($params, &$smarty)
  8999. +{
  9000. +    require_once $smarty->_get_plugin_filepath('shared','make_timestamp');
  9001. +    require_once $smarty->_get_plugin_filepath('function','html_options');
  9002. +    /* Default values. */
  9003. +    $prefix             = "Time_";
  9004. +    $time               = time();
  9005. +    $display_hours      = true;
  9006. +    $display_minutes    = true;
  9007. +    $display_seconds    = true;
  9008. +    $display_meridian   = true;
  9009. +    $use_24_hours       = true;
  9010. +    $minute_interval    = 1;
  9011. +    $second_interval    = 1;
  9012. +    /* Should the select boxes be part of an array when returned from PHP?
  9013. +       e.g. setting it to "birthday", would create "birthday[Hour]",
  9014. +       "birthday[Minute]", "birthday[Seconds]" & "birthday[Meridian]".
  9015. +       Can be combined with prefix. */
  9016. +    $field_array        = null;
  9017. +    $all_extra          = null;
  9018. +    $hour_extra         = null;
  9019. +    $minute_extra       = null;
  9020. +    $second_extra       = null;
  9021. +    $meridian_extra     = null;
  9022. +
  9023. +    foreach ($params as $_key=>$_value) {
  9024. +        switch ($_key) {
  9025. +            case 'prefix':
  9026. +            case 'time':
  9027. +            case 'field_array':
  9028. +            case 'all_extra':
  9029. +            case 'hour_extra':
  9030. +            case 'minute_extra':
  9031. +            case 'second_extra':
  9032. +            case 'meridian_extra':
  9033. +                $$_key = (string)$_value;
  9034. +                break;
  9035. +
  9036. +            case 'display_hours':
  9037. +            case 'display_minutes':
  9038. +            case 'display_seconds':
  9039. +            case 'display_meridian':
  9040. +            case 'use_24_hours':
  9041. +                $$_key = (bool)$_value;
  9042. +                break;
  9043. +
  9044. +            case 'minute_interval':
  9045. +            case 'second_interval':
  9046. +                $$_key = (int)$_value;
  9047. +                break;
  9048. +
  9049. +            default:
  9050. +                $smarty->trigger_error("[html_select_time] unknown parameter $_key", E_USER_WARNING);
  9051. +        }
  9052. +    }
  9053. +
  9054. +    $time = smarty_make_timestamp($time);
  9055. +
  9056. +    $html_result = '';
  9057. +
  9058. +    if ($display_hours) {
  9059. +        $hours       = $use_24_hours ? range(0, 23) : range(1, 12);
  9060. +        $hour_fmt = $use_24_hours ? '%H' : '%I';
  9061. +        for ($i = 0, $for_max = count($hours); $i < $for_max; $i++)
  9062. +            $hours[$i] = sprintf('%02d', $hours[$i]);
  9063. +        $html_result .= '<select name=';
  9064. +        if (null !== $field_array) {
  9065. +            $html_result .= '"' . $field_array . '[' . $prefix . 'Hour]"';
  9066. +        } else {
  9067. +            $html_result .= '"' . $prefix . 'Hour"';
  9068. +        }
  9069. +        if (null !== $hour_extra){
  9070. +            $html_result .= ' ' . $hour_extra;
  9071. +        }
  9072. +        if (null !== $all_extra){
  9073. +            $html_result .= ' ' . $all_extra;
  9074. +        }
  9075. +        $html_result .= '>'."\n";
  9076. +        $html_result .= smarty_function_html_options(array('output'          => $hours,
  9077. +                                                           'values'          => $hours,
  9078. +                                                           'selected'      => strftime($hour_fmt, $time),
  9079. +                                                           'print_result' => false),
  9080. +                                                     $smarty);
  9081. +        $html_result .= "</select>\n";
  9082. +    }
  9083. +
  9084. +    if ($display_minutes) {
  9085. +        $all_minutes = range(0, 59);
  9086. +        for ($i = 0, $for_max = count($all_minutes); $i < $for_max; $i+= $minute_interval)
  9087. +            $minutes[] = sprintf('%02d', $all_minutes[$i]);
  9088. +        $selected = intval(floor(strftime('%M', $time) / $minute_interval) * $minute_interval);
  9089. +        $html_result .= '<select name=';
  9090. +        if (null !== $field_array) {
  9091. +            $html_result .= '"' . $field_array . '[' . $prefix . 'Minute]"';
  9092. +        } else {
  9093. +            $html_result .= '"' . $prefix . 'Minute"';
  9094. +        }
  9095. +        if (null !== $minute_extra){
  9096. +            $html_result .= ' ' . $minute_extra;
  9097. +        }
  9098. +        if (null !== $all_extra){
  9099. +            $html_result .= ' ' . $all_extra;
  9100. +        }
  9101. +        $html_result .= '>'."\n";
  9102. +        
  9103. +        $html_result .= smarty_function_html_options(array('output'          => $minutes,
  9104. +                                                           'values'          => $minutes,
  9105. +                                                           'selected'      => $selected,
  9106. +                                                           'print_result' => false),
  9107. +                                                     $smarty);
  9108. +        $html_result .= "</select>\n";
  9109. +    }
  9110. +
  9111. +    if ($display_seconds) {
  9112. +        $all_seconds = range(0, 59);
  9113. +        for ($i = 0, $for_max = count($all_seconds); $i < $for_max; $i+= $second_interval)
  9114. +            $seconds[] = sprintf('%02d', $all_seconds[$i]);
  9115. +        $selected = intval(floor(strftime('%S', $time) / $second_interval) * $second_interval);
  9116. +        $html_result .= '<select name=';
  9117. +        if (null !== $field_array) {
  9118. +            $html_result .= '"' . $field_array . '[' . $prefix . 'Second]"';
  9119. +        } else {
  9120. +            $html_result .= '"' . $prefix . 'Second"';
  9121. +        }
  9122. +        
  9123. +        if (null !== $second_extra){
  9124. +            $html_result .= ' ' . $second_extra;
  9125. +        }
  9126. +        if (null !== $all_extra){
  9127. +            $html_result .= ' ' . $all_extra;
  9128. +        }
  9129. +        $html_result .= '>'."\n";
  9130. +        
  9131. +        $html_result .= smarty_function_html_options(array('output'          => $seconds,
  9132. +                                                           'values'          => $seconds,
  9133. +                                                           'selected'      => $selected,
  9134. +                                                           'print_result' => false),
  9135. +                                                     $smarty);
  9136. +        $html_result .= "</select>\n";
  9137. +    }
  9138. +
  9139. +    if ($display_meridian && !$use_24_hours) {
  9140. +        $html_result .= '<select name=';
  9141. +        if (null !== $field_array) {
  9142. +            $html_result .= '"' . $field_array . '[' . $prefix . 'Meridian]"';
  9143. +        } else {
  9144. +            $html_result .= '"' . $prefix . 'Meridian"';
  9145. +        }
  9146. +        
  9147. +        if (null !== $meridian_extra){
  9148. +            $html_result .= ' ' . $meridian_extra;
  9149. +        }
  9150. +        if (null !== $all_extra){
  9151. +            $html_result .= ' ' . $all_extra;
  9152. +        }
  9153. +        $html_result .= '>'."\n";
  9154. +        
  9155. +        $html_result .= smarty_function_html_options(array('output'          => array('AM', 'PM'),
  9156. +                                                           'values'          => array('am', 'pm'),
  9157. +                                                           'selected'      => strtolower(strftime('%p', $time)),
  9158. +                                                           'print_result' => false),
  9159. +                                                     $smarty);
  9160. +        $html_result .= "</select>\n";
  9161. +    }
  9162. +
  9163. +    return $html_result;
  9164. +}
  9165. +
  9166. +/* vim: set expandtab: */
  9167. +
  9168. +?>
  9169. diff --git a/library/smarty/plugins/function.html_table.php b/library/smarty/plugins/function.html_table.php
  9170. new file mode 100644
  9171. --- /dev/null
  9172. +++ b/library/smarty/plugins/function.html_table.php
  9173. @@ -0,0 +1,177 @@
  9174. +<?php
  9175. +/**
  9176. + * Smarty plugin
  9177. + * @package Smarty
  9178. + * @subpackage plugins
  9179. + */
  9180. +
  9181. +
  9182. +/**
  9183. + * Smarty {html_table} function plugin
  9184. + *
  9185. + * Type:     function<br>
  9186. + * Name:     html_table<br>
  9187. + * Date:     Feb 17, 2003<br>
  9188. + * Purpose:  make an html table from an array of data<br>
  9189. + * Input:<br>
  9190. + *         - loop = array to loop through
  9191. + *         - cols = number of columns, comma separated list of column names
  9192. + *                  or array of column names
  9193. + *         - rows = number of rows
  9194. + *         - table_attr = table attributes
  9195. + *         - th_attr = table heading attributes (arrays are cycled)
  9196. + *         - tr_attr = table row attributes (arrays are cycled)
  9197. + *         - td_attr = table cell attributes (arrays are cycled)
  9198. + *         - trailpad = value to pad trailing cells with
  9199. + *         - caption = text for caption element
  9200. + *         - vdir = vertical direction (default: "down", means top-to-bottom)
  9201. + *         - hdir = horizontal direction (default: "right", means left-to-right)
  9202. + *         - inner = inner loop (default "cols": print $loop line by line,
  9203. + *                   $loop will be printed column by column otherwise)
  9204. + *
  9205. + *
  9206. + * Examples:
  9207. + * <pre>
  9208. + * {table loop=$data}
  9209. + * {table loop=$data cols=4 tr_attr='"bgcolor=red"'}
  9210. + * {table loop=$data cols="first,second,third" tr_attr=$colors}
  9211. + * </pre>
  9212. + * @author   Monte Ohrt <monte at ohrt dot com>
  9213. + * @author credit to Messju Mohr <messju at lammfellpuschen dot de>
  9214. + * @author credit to boots <boots dot smarty at yahoo dot com>
  9215. + * @version  1.1
  9216. + * @link http://smarty.php.net/manual/en/language.function.html.table.php {html_table}
  9217. + *          (Smarty online manual)
  9218. + * @param array
  9219. + * @param Smarty
  9220. + * @return string
  9221. + */
  9222. +function smarty_function_html_table($params, &$smarty)
  9223. +{
  9224. +    $table_attr = 'border="1"';
  9225. +    $tr_attr = '';
  9226. +    $th_attr = '';
  9227. +    $td_attr = '';
  9228. +    $cols = $cols_count = 3;
  9229. +    $rows = 3;
  9230. +    $trailpad = '&nbsp;';
  9231. +    $vdir = 'down';
  9232. +    $hdir = 'right';
  9233. +    $inner = 'cols';
  9234. +    $caption = '';
  9235. +
  9236. +    if (!isset($params['loop'])) {
  9237. +        $smarty->trigger_error("html_table: missing 'loop' parameter");
  9238. +        return;
  9239. +    }
  9240. +
  9241. +    foreach ($params as $_key=>$_value) {
  9242. +        switch ($_key) {
  9243. +            case 'loop':
  9244. +                $$_key = (array)$_value;
  9245. +                break;
  9246. +
  9247. +            case 'cols':
  9248. +                if (is_array($_value) && !empty($_value)) {
  9249. +                    $cols = $_value;
  9250. +                    $cols_count = count($_value);
  9251. +                } elseif (!is_numeric($_value) && is_string($_value) && !empty($_value)) {
  9252. +                    $cols = explode(',', $_value);
  9253. +                    $cols_count = count($cols);
  9254. +                } elseif (!empty($_value)) {
  9255. +                    $cols_count = (int)$_value;
  9256. +                } else {
  9257. +                    $cols_count = $cols;
  9258. +                }
  9259. +                break;
  9260. +
  9261. +            case 'rows':
  9262. +                $$_key = (int)$_value;
  9263. +                break;
  9264. +
  9265. +            case 'table_attr':
  9266. +            case 'trailpad':
  9267. +            case 'hdir':
  9268. +            case 'vdir':
  9269. +            case 'inner':
  9270. +            case 'caption':
  9271. +                $$_key = (string)$_value;
  9272. +                break;
  9273. +
  9274. +            case 'tr_attr':
  9275. +            case 'td_attr':
  9276. +            case 'th_attr':
  9277. +                $$_key = $_value;
  9278. +                break;
  9279. +        }
  9280. +    }
  9281. +
  9282. +    $loop_count = count($loop);
  9283. +    if (empty($params['rows'])) {
  9284. +        /* no rows specified */
  9285. +        $rows = ceil($loop_count/$cols_count);
  9286. +    } elseif (empty($params['cols'])) {
  9287. +        if (!empty($params['rows'])) {
  9288. +            /* no cols specified, but rows */
  9289. +            $cols_count = ceil($loop_count/$rows);
  9290. +        }
  9291. +    }
  9292. +
  9293. +    $output = "<table $table_attr>\n";
  9294. +
  9295. +    if (!empty($caption)) {
  9296. +        $output .= '<caption>' . $caption . "</caption>\n";
  9297. +    }
  9298. +
  9299. +    if (is_array($cols)) {
  9300. +        $cols = ($hdir == 'right') ? $cols : array_reverse($cols);
  9301. +        $output .= "<thead><tr>\n";
  9302. +
  9303. +        for ($r=0; $r<$cols_count; $r++) {
  9304. +            $output .= '<th' . smarty_function_html_table_cycle('th', $th_attr, $r) . '>';
  9305. +            $output .= $cols[$r];
  9306. +            $output .= "</th>\n";
  9307. +        }
  9308. +        $output .= "</tr></thead>\n";
  9309. +    }
  9310. +
  9311. +    $output .= "<tbody>\n";
  9312. +    for ($r=0; $r<$rows; $r++) {
  9313. +        $output .= "<tr" . smarty_function_html_table_cycle('tr', $tr_attr, $r) . ">\n";
  9314. +        $rx =  ($vdir == 'down') ? $r*$cols_count : ($rows-1-$r)*$cols_count;
  9315. +
  9316. +        for ($c=0; $c<$cols_count; $c++) {
  9317. +            $x =  ($hdir == 'right') ? $rx+$c : $rx+$cols_count-1-$c;
  9318. +            if ($inner!='cols') {
  9319. +                /* shuffle x to loop over rows*/
  9320. +                $x = floor($x/$cols_count) + ($x%$cols_count)*$rows;
  9321. +            }
  9322. +
  9323. +            if ($x<$loop_count) {
  9324. +                $output .= "<td" . smarty_function_html_table_cycle('td', $td_attr, $c) . ">" . $loop[$x] . "</td>\n";
  9325. +            } else {
  9326. +                $output .= "<td" . smarty_function_html_table_cycle('td', $td_attr, $c) . ">$trailpad</td>\n";
  9327. +            }
  9328. +        }
  9329. +        $output .= "</tr>\n";
  9330. +    }
  9331. +    $output .= "</tbody>\n";
  9332. +    $output .= "</table>\n";
  9333. +    
  9334. +    return $output;
  9335. +}
  9336. +
  9337. +function smarty_function_html_table_cycle($name, $var, $no) {
  9338. +    if(!is_array($var)) {
  9339. +        $ret = $var;
  9340. +    } else {
  9341. +        $ret = $var[$no % count($var)];
  9342. +    }
  9343. +    
  9344. +    return ($ret) ? ' '.$ret : '';
  9345. +}
  9346. +
  9347. +
  9348. +/* vim: set expandtab: */
  9349. +
  9350. +?>
  9351. diff --git a/library/smarty/plugins/function.mailto.php b/library/smarty/plugins/function.mailto.php
  9352. new file mode 100644
  9353. --- /dev/null
  9354. +++ b/library/smarty/plugins/function.mailto.php
  9355. @@ -0,0 +1,165 @@
  9356. +<?php
  9357. +/**
  9358. + * Smarty plugin
  9359. + * @package Smarty
  9360. + * @subpackage plugins
  9361. + */
  9362. +
  9363. +
  9364. +/**
  9365. + * Smarty {mailto} function plugin
  9366. + *
  9367. + * Type:     function<br>
  9368. + * Name:     mailto<br>
  9369. + * Date:     May 21, 2002
  9370. + * Purpose:  automate mailto address link creation, and optionally
  9371. + *           encode them.<br>
  9372. + * Input:<br>
  9373. + *         - address = e-mail address
  9374. + *         - text = (optional) text to display, default is address
  9375. + *         - encode = (optional) can be one of:
  9376. + *                * none : no encoding (default)
  9377. + *                * javascript : encode with javascript
  9378. + *                * javascript_charcode : encode with javascript charcode
  9379. + *                * hex : encode with hexidecimal (no javascript)
  9380. + *         - cc = (optional) address(es) to carbon copy
  9381. + *         - bcc = (optional) address(es) to blind carbon copy
  9382. + *         - subject = (optional) e-mail subject
  9383. + *         - newsgroups = (optional) newsgroup(s) to post to
  9384. + *         - followupto = (optional) address(es) to follow up to
  9385. + *         - extra = (optional) extra tags for the href link
  9386. + *
  9387. + * Examples:
  9388. + * <pre>
  9389. + * {mailto address="me@domain.com"}
  9390. + * {mailto address="me@domain.com" encode="javascript"}
  9391. + * {mailto address="me@domain.com" encode="hex"}
  9392. + * {mailto address="me@domain.com" subject="Hello to you!"}
  9393. + * {mailto address="me@domain.com" cc="you@domain.com,they@domain.com"}
  9394. + * {mailto address="me@domain.com" extra='class="mailto"'}
  9395. + * </pre>
  9396. + * @link http://smarty.php.net/manual/en/language.function.mailto.php {mailto}
  9397. + *          (Smarty online manual)
  9398. + * @version  1.2
  9399. + * @author   Monte Ohrt <monte at ohrt dot com>
  9400. + * @author   credits to Jason Sweat (added cc, bcc and subject functionality)
  9401. + * @param    array
  9402. + * @param    Smarty
  9403. + * @return   string
  9404. + */
  9405. +function smarty_function_mailto($params, &$smarty)
  9406. +{
  9407. +    $extra = '';
  9408. +
  9409. +    if (empty($params['address'])) {
  9410. +        $smarty->trigger_error("mailto: missing 'address' parameter");
  9411. +        return;
  9412. +    } else {
  9413. +        $address = $params['address'];
  9414. +    }
  9415. +
  9416. +    $text = $address;
  9417. +
  9418. +    // netscape and mozilla do not decode %40 (@) in BCC field (bug?)
  9419. +    // so, don't encode it.
  9420. +    $search = array('%40', '%2C');
  9421. +    $replace  = array('@', ',');
  9422. +    $mail_parms = array();
  9423. +    foreach ($params as $var=>$value) {
  9424. +        switch ($var) {
  9425. +            case 'cc':
  9426. +            case 'bcc':
  9427. +            case 'followupto':
  9428. +                if (!empty($value))
  9429. +                    $mail_parms[] = $var.'='.str_replace($search,$replace,rawurlencode($value));
  9430. +                break;
  9431. +                
  9432. +            case 'subject':
  9433. +            case 'newsgroups':
  9434. +                $mail_parms[] = $var.'='.rawurlencode($value);
  9435. +                break;
  9436. +
  9437. +            case 'extra':
  9438. +            case 'text':
  9439. +                $$var = $value;
  9440. +
  9441. +            default:
  9442. +        }
  9443. +    }
  9444. +
  9445. +    $mail_parm_vals = '';
  9446. +    for ($i=0; $i<count($mail_parms); $i++) {
  9447. +        $mail_parm_vals .= (0==$i) ? '?' : '&';
  9448. +        $mail_parm_vals .= $mail_parms[$i];
  9449. +    }
  9450. +    $address .= $mail_parm_vals;
  9451. +
  9452. +    $encode = (empty($params['encode'])) ? 'none' : $params['encode'];
  9453. +    if (!in_array($encode,array('javascript','javascript_charcode','hex','none')) ) {
  9454. +        $smarty->trigger_error("mailto: 'encode' parameter must be none, javascript or hex");
  9455. +        return;
  9456. +    }
  9457. +
  9458. +    if ($encode == 'javascript' ) {
  9459. +        $string = 'document.write(\'<a href="mailto:'.$address.'" '.$extra.'>'.$text.'</a>\');';
  9460. +
  9461. +        $js_encode = '';
  9462. +        for ($x=0; $x < strlen($string); $x++) {
  9463. +            $js_encode .= '%' . bin2hex($string[$x]);
  9464. +        }
  9465. +
  9466. +        return '<script type="text/javascript">eval(unescape(\''.$js_encode.'\'))</script>';
  9467. +
  9468. +    } elseif ($encode == 'javascript_charcode' ) {
  9469. +        $string = '<a href="mailto:'.$address.'" '.$extra.'>'.$text.'</a>';
  9470. +
  9471. +        for($x = 0, $y = strlen($string); $x < $y; $x++ ) {
  9472. +            $ord[] = ord($string[$x]);  
  9473. +        }
  9474. +
  9475. +        $_ret = "<script type=\"text/javascript\" language=\"javascript\">\n";
  9476. +        $_ret .= "<!--\n";
  9477. +        $_ret .= "{document.write(String.fromCharCode(";
  9478. +        $_ret .= implode(',',$ord);
  9479. +        $_ret .= "))";
  9480. +        $_ret .= "}\n";
  9481. +        $_ret .= "//-->\n";
  9482. +        $_ret .= "</script>\n";
  9483. +        
  9484. +        return $_ret;
  9485. +        
  9486. +        
  9487. +    } elseif ($encode == 'hex') {
  9488. +
  9489. +        preg_match('!^(.*)(\?.*)$!',$address,$match);
  9490. +        if(!empty($match[2])) {
  9491. +            $smarty->trigger_error("mailto: hex encoding does not work with extra attributes. Try javascript.");
  9492. +            return;
  9493. +        }
  9494. +        $address_encode = '';
  9495. +        for ($x=0; $x < strlen($address); $x++) {
  9496. +            if(preg_match('!\w!',$address[$x])) {
  9497. +                $address_encode .= '%' . bin2hex($address[$x]);
  9498. +            } else {
  9499. +                $address_encode .= $address[$x];
  9500. +            }
  9501. +        }
  9502. +        $text_encode = '';
  9503. +        for ($x=0; $x < strlen($text); $x++) {
  9504. +            $text_encode .= '&#x' . bin2hex($text[$x]).';';
  9505. +        }
  9506. +
  9507. +        $mailto = "&#109;&#97;&#105;&#108;&#116;&#111;&#58;";
  9508. +        return '<a href="'.$mailto.$address_encode.'" '.$extra.'>'.$text_encode.'</a>';
  9509. +
  9510. +    } else {
  9511. +        // no encoding
  9512. +        return '<a href="mailto:'.$address.'" '.$extra.'>'.$text.'</a>';
  9513. +
  9514. +    }
  9515. +
  9516. +}
  9517. +
  9518. +/* vim: set expandtab: */
  9519. +
  9520. +?>
  9521. diff --git a/library/smarty/plugins/function.math.php b/library/smarty/plugins/function.math.php
  9522. new file mode 100644
  9523. --- /dev/null
  9524. +++ b/library/smarty/plugins/function.math.php
  9525. @@ -0,0 +1,85 @@
  9526. +<?php
  9527. +/**
  9528. + * Smarty plugin
  9529. + * @package Smarty
  9530. + * @subpackage plugins
  9531. + */
  9532. +
  9533. +
  9534. +/**
  9535. + * Smarty {math} function plugin
  9536. + *
  9537. + * Type:     function<br>
  9538. + * Name:     math<br>
  9539. + * Purpose:  handle math computations in template<br>
  9540. + * @link http://smarty.php.net/manual/en/language.function.math.php {math}
  9541. + *          (Smarty online manual)
  9542. + * @author   Monte Ohrt <monte at ohrt dot com>
  9543. + * @param array
  9544. + * @param Smarty
  9545. + * @return string
  9546. + */
  9547. +function smarty_function_math($params, &$smarty)
  9548. +{
  9549. +    // be sure equation parameter is present
  9550. +    if (empty($params['equation'])) {
  9551. +        $smarty->trigger_error("math: missing equation parameter");
  9552. +        return;
  9553. +    }
  9554. +
  9555. +    // strip out backticks, not necessary for math
  9556. +    $equation = str_replace('`','',$params['equation']);
  9557. +
  9558. +    // make sure parenthesis are balanced
  9559. +    if (substr_count($equation,"(") != substr_count($equation,")")) {
  9560. +        $smarty->trigger_error("math: unbalanced parenthesis");
  9561. +        return;
  9562. +    }
  9563. +
  9564. +    // match all vars in equation, make sure all are passed
  9565. +    preg_match_all("!(?:0x[a-fA-F0-9]+)|([a-zA-Z][a-zA-Z0-9_]+)!",$equation, $match);
  9566. +    $allowed_funcs = array('int','abs','ceil','cos','exp','floor','log','log10',
  9567. +                           'max','min','pi','pow','rand','round','sin','sqrt','srand','tan');
  9568. +    
  9569. +    foreach($match[1] as $curr_var) {
  9570. +        if ($curr_var && !in_array($curr_var, array_keys($params)) && !in_array($curr_var, $allowed_funcs)) {
  9571. +            $smarty->trigger_error("math: function call $curr_var not allowed");
  9572. +            return;
  9573. +        }
  9574. +    }
  9575. +
  9576. +    foreach($params as $key => $val) {
  9577. +        if ($key != "equation" && $key != "format" && $key != "assign") {
  9578. +            // make sure value is not empty
  9579. +            if (strlen($val)==0) {
  9580. +                $smarty->trigger_error("math: parameter $key is empty");
  9581. +                return;
  9582. +            }
  9583. +            if (!is_numeric($val)) {
  9584. +                $smarty->trigger_error("math: parameter $key: is not numeric");
  9585. +                return;
  9586. +            }
  9587. +            $equation = preg_replace("/\b$key\b/", " \$params['$key'] ", $equation);
  9588. +        }
  9589. +    }
  9590. +
  9591. +    eval("\$smarty_math_result = ".$equation.";");
  9592. +
  9593. +    if (empty($params['format'])) {
  9594. +        if (empty($params['assign'])) {
  9595. +            return $smarty_math_result;
  9596. +        } else {
  9597. +            $smarty->assign($params['assign'],$smarty_math_result);
  9598. +        }
  9599. +    } else {
  9600. +        if (empty($params['assign'])){
  9601. +            printf($params['format'],$smarty_math_result);
  9602. +        } else {
  9603. +            $smarty->assign($params['assign'],sprintf($params['format'],$smarty_math_result));
  9604. +        }
  9605. +    }
  9606. +}
  9607. +
  9608. +/* vim: set expandtab: */
  9609. +
  9610. +?>
  9611. diff --git a/library/smarty/plugins/function.popup.php b/library/smarty/plugins/function.popup.php
  9612. new file mode 100644
  9613. --- /dev/null
  9614. +++ b/library/smarty/plugins/function.popup.php
  9615. @@ -0,0 +1,119 @@
  9616. +<?php
  9617. +/**
  9618. + * Smarty plugin
  9619. + * @package Smarty
  9620. + * @subpackage plugins
  9621. + */
  9622. +
  9623. +
  9624. +/**
  9625. + * Smarty {popup} function plugin
  9626. + *
  9627. + * Type:     function<br>
  9628. + * Name:     popup<br>
  9629. + * Purpose:  make text pop up in windows via overlib
  9630. + * @link http://smarty.php.net/manual/en/language.function.popup.php {popup}
  9631. + *          (Smarty online manual)
  9632. + * @author   Monte Ohrt <monte at ohrt dot com>
  9633. + * @param array
  9634. + * @param Smarty
  9635. + * @return string
  9636. + */
  9637. +function smarty_function_popup($params, &$smarty)
  9638. +{
  9639. +    $append = '';
  9640. +    foreach ($params as $_key=>$_value) {
  9641. +        switch ($_key) {
  9642. +            case 'text':
  9643. +            case 'trigger':
  9644. +            case 'function':
  9645. +            case 'inarray':
  9646. +                $$_key = (string)$_value;
  9647. +                if ($_key == 'function' || $_key == 'inarray')
  9648. +                    $append .= ',' . strtoupper($_key) . ",'$_value'";
  9649. +                break;
  9650. +
  9651. +            case 'caption':
  9652. +            case 'closetext':
  9653. +            case 'status':
  9654. +                $append .= ',' . strtoupper($_key) . ",'" . str_replace("'","\'",$_value) . "'";
  9655. +                break;
  9656. +
  9657. +            case 'fgcolor':
  9658. +            case 'bgcolor':
  9659. +            case 'textcolor':
  9660. +            case 'capcolor':
  9661. +            case 'closecolor':
  9662. +            case 'textfont':
  9663. +            case 'captionfont':
  9664. +            case 'closefont':
  9665. +            case 'fgbackground':
  9666. +            case 'bgbackground':
  9667. +            case 'caparray':
  9668. +            case 'capicon':
  9669. +            case 'background':
  9670. +            case 'frame':
  9671. +                $append .= ',' . strtoupper($_key) . ",'$_value'";
  9672. +                break;
  9673. +
  9674. +            case 'textsize':
  9675. +            case 'captionsize':
  9676. +            case 'closesize':
  9677. +            case 'width':
  9678. +            case 'height':
  9679. +            case 'border':
  9680. +            case 'offsetx':
  9681. +            case 'offsety':
  9682. +            case 'snapx':
  9683. +            case 'snapy':
  9684. +            case 'fixx':
  9685. +            case 'fixy':
  9686. +            case 'padx':
  9687. +            case 'pady':
  9688. +            case 'timeout':
  9689. +            case 'delay':
  9690. +                $append .= ',' . strtoupper($_key) . ",$_value";
  9691. +                break;
  9692. +
  9693. +            case 'sticky':
  9694. +            case 'left':
  9695. +            case 'right':
  9696. +            case 'center':
  9697. +            case 'above':
  9698. +            case 'below':
  9699. +            case 'noclose':
  9700. +            case 'autostatus':
  9701. +            case 'autostatuscap':
  9702. +            case 'fullhtml':
  9703. +            case 'hauto':
  9704. +            case 'vauto':
  9705. +            case 'mouseoff':
  9706. +            case 'followmouse':
  9707. +            case 'closeclick':
  9708. +                if ($_value) $append .= ',' . strtoupper($_key);
  9709. +                break;
  9710. +
  9711. +            default:
  9712. +                $smarty->trigger_error("[popup] unknown parameter $_key", E_USER_WARNING);
  9713. +        }
  9714. +    }
  9715. +
  9716. +    if (empty($text) && !isset($inarray) && empty($function)) {
  9717. +        $smarty->trigger_error("overlib: attribute 'text' or 'inarray' or 'function' required");
  9718. +        return false;
  9719. +    }
  9720. +
  9721. +    if (empty($trigger)) { $trigger = "onmouseover"; }
  9722. +
  9723. +    $retval = $trigger . '="return overlib(\''.preg_replace(array("!'!","![\r\n]!"),array("\'",'\r'),$text).'\'';
  9724. +    $retval .= $append . ');"';
  9725. +    if ($trigger == 'onmouseover')
  9726. +       $retval .= ' onmouseout="nd();"';
  9727. +
  9728. +
  9729. +    return $retval;
  9730. +}
  9731. +
  9732. +/* vim: set expandtab: */
  9733. +
  9734. +?>
  9735. diff --git a/library/smarty/plugins/function.popup_init.php b/library/smarty/plugins/function.popup_init.php
  9736. new file mode 100644
  9737. --- /dev/null
  9738. +++ b/library/smarty/plugins/function.popup_init.php
  9739. @@ -0,0 +1,40 @@
  9740. +<?php
  9741. +/**
  9742. + * Smarty plugin
  9743. + * @package Smarty
  9744. + * @subpackage plugins
  9745. + */
  9746. +
  9747. +
  9748. +/**
  9749. + * Smarty {popup_init} function plugin
  9750. + *
  9751. + * Type:     function<br>
  9752. + * Name:     popup_init<br>
  9753. + * Purpose:  initialize overlib
  9754. + * @link http://smarty.php.net/manual/en/language.function.popup.init.php {popup_init}
  9755. + *          (Smarty online manual)
  9756. + * @author   Monte Ohrt <monte at ohrt dot com>
  9757. + * @param array
  9758. + * @param Smarty
  9759. + * @return string
  9760. + */
  9761. +function smarty_function_popup_init($params, &$smarty)
  9762. +{
  9763. +    $zindex = 1000;
  9764. +    
  9765. +    if (!empty($params['zindex'])) {
  9766. +        $zindex = $params['zindex'];
  9767. +    }
  9768. +    
  9769. +    if (!empty($params['src'])) {
  9770. +        return '<div id="overDiv" style="position:absolute; visibility:hidden; z-index:'.$zindex.';"></div>' . "\n"
  9771. +         . '<script type="text/javascript" language="JavaScript" src="'.$params['src'].'"></script>' . "\n";
  9772. +    } else {
  9773. +        $smarty->trigger_error("popup_init: missing src parameter");
  9774. +    }
  9775. +}
  9776. +
  9777. +/* vim: set expandtab: */
  9778. +
  9779. +?>
  9780. diff --git a/library/smarty/plugins/modifier.capitalize.php b/library/smarty/plugins/modifier.capitalize.php
  9781. new file mode 100644
  9782. --- /dev/null
  9783. +++ b/library/smarty/plugins/modifier.capitalize.php
  9784. @@ -0,0 +1,43 @@
  9785. +<?php
  9786. +/**
  9787. + * Smarty plugin
  9788. + * @package Smarty
  9789. + * @subpackage plugins
  9790. + */
  9791. +
  9792. +
  9793. +/**
  9794. + * Smarty capitalize modifier plugin
  9795. + *
  9796. + * Type:     modifier<br>
  9797. + * Name:     capitalize<br>
  9798. + * Purpose:  capitalize words in the string
  9799. + * @link http://smarty.php.net/manual/en/language.modifiers.php#LANGUAGE.MODIFIER.CAPITALIZE
  9800. + *      capitalize (Smarty online manual)
  9801. + * @author   Monte Ohrt <monte at ohrt dot com>
  9802. + * @param string
  9803. + * @return string
  9804. + */
  9805. +function smarty_modifier_capitalize($string, $uc_digits = false)
  9806. +{
  9807. +    smarty_modifier_capitalize_ucfirst(null, $uc_digits);
  9808. +    return preg_replace_callback('!\'?\b\w(\w|\')*\b!', 'smarty_modifier_capitalize_ucfirst', $string);
  9809. +}
  9810. +
  9811. +function smarty_modifier_capitalize_ucfirst($string, $uc_digits = null)
  9812. +{
  9813. +    static $_uc_digits = false;
  9814. +    
  9815. +    if(isset($uc_digits)) {
  9816. +        $_uc_digits = $uc_digits;
  9817. +        return;
  9818. +    }
  9819. +    
  9820. +    if(substr($string[0],0,1) != "'" && !preg_match("!\d!",$string[0]) || $_uc_digits)
  9821. +        return ucfirst($string[0]);
  9822. +    else
  9823. +        return $string[0];
  9824. +}
  9825. +
  9826. +
  9827. +?>
  9828. diff --git a/library/smarty/plugins/modifier.cat.php b/library/smarty/plugins/modifier.cat.php
  9829. new file mode 100644
  9830. --- /dev/null
  9831. +++ b/library/smarty/plugins/modifier.cat.php
  9832. @@ -0,0 +1,33 @@
  9833. +<?php
  9834. +/**
  9835. + * Smarty plugin
  9836. + * @package Smarty
  9837. + * @subpackage plugins
  9838. + */
  9839. +
  9840. +
  9841. +/**
  9842. + * Smarty cat modifier plugin
  9843. + *
  9844. + * Type:     modifier<br>
  9845. + * Name:     cat<br>
  9846. + * Date:     Feb 24, 2003
  9847. + * Purpose:  catenate a value to a variable
  9848. + * Input:    string to catenate
  9849. + * Example:  {$var|cat:"foo"}
  9850. + * @link http://smarty.php.net/manual/en/language.modifier.cat.php cat
  9851. + *          (Smarty online manual)
  9852. + * @author   Monte Ohrt <monte at ohrt dot com>
  9853. + * @version 1.0
  9854. + * @param string
  9855. + * @param string
  9856. + * @return string
  9857. + */
  9858. +function smarty_modifier_cat($string, $cat)
  9859. +{
  9860. +    return $string . $cat;
  9861. +}
  9862. +
  9863. +/* vim: set expandtab: */
  9864. +
  9865. +?>
  9866. diff --git a/library/smarty/plugins/modifier.count_characters.php b/library/smarty/plugins/modifier.count_characters.php
  9867. new file mode 100644
  9868. --- /dev/null
  9869. +++ b/library/smarty/plugins/modifier.count_characters.php
  9870. @@ -0,0 +1,32 @@
  9871. +<?php
  9872. +/**
  9873. + * Smarty plugin
  9874. + * @package Smarty
  9875. + * @subpackage plugins
  9876. + */
  9877. +
  9878. +
  9879. +/**
  9880. + * Smarty count_characters modifier plugin
  9881. + *
  9882. + * Type:     modifier<br>
  9883. + * Name:     count_characteres<br>
  9884. + * Purpose:  count the number of characters in a text
  9885. + * @link http://smarty.php.net/manual/en/language.modifier.count.characters.php
  9886. + *          count_characters (Smarty online manual)
  9887. + * @author   Monte Ohrt <monte at ohrt dot com>
  9888. + * @param string
  9889. + * @param boolean include whitespace in the character count
  9890. + * @return integer
  9891. + */
  9892. +function smarty_modifier_count_characters($string, $include_spaces = false)
  9893. +{
  9894. +    if ($include_spaces)
  9895. +       return(strlen($string));
  9896. +
  9897. +    return preg_match_all("/[^\s]/",$string, $match);
  9898. +}
  9899. +
  9900. +/* vim: set expandtab: */
  9901. +
  9902. +?>
  9903. diff --git a/library/smarty/plugins/modifier.count_paragraphs.php b/library/smarty/plugins/modifier.count_paragraphs.php
  9904. new file mode 100644
  9905. --- /dev/null
  9906. +++ b/library/smarty/plugins/modifier.count_paragraphs.php
  9907. @@ -0,0 +1,29 @@
  9908. +<?php
  9909. +/**
  9910. + * Smarty plugin
  9911. + * @package Smarty
  9912. + * @subpackage plugins
  9913. + */
  9914. +
  9915. +
  9916. +/**
  9917. + * Smarty count_paragraphs modifier plugin
  9918. + *
  9919. + * Type:     modifier<br>
  9920. + * Name:     count_paragraphs<br>
  9921. + * Purpose:  count the number of paragraphs in a text
  9922. + * @link http://smarty.php.net/manual/en/language.modifier.count.paragraphs.php
  9923. + *          count_paragraphs (Smarty online manual)
  9924. + * @author   Monte Ohrt <monte at ohrt dot com>
  9925. + * @param string
  9926. + * @return integer
  9927. + */
  9928. +function smarty_modifier_count_paragraphs($string)
  9929. +{
  9930. +    // count \r or \n characters
  9931. +    return count(preg_split('/[\r\n]+/', $string));
  9932. +}
  9933. +
  9934. +/* vim: set expandtab: */
  9935. +
  9936. +?>
  9937. diff --git a/library/smarty/plugins/modifier.count_sentences.php b/library/smarty/plugins/modifier.count_sentences.php
  9938. new file mode 100644
  9939. --- /dev/null
  9940. +++ b/library/smarty/plugins/modifier.count_sentences.php
  9941. @@ -0,0 +1,29 @@
  9942. +<?php
  9943. +/**
  9944. + * Smarty plugin
  9945. + * @package Smarty
  9946. + * @subpackage plugins
  9947. + */
  9948. +
  9949. +
  9950. +/**
  9951. + * Smarty count_sentences modifier plugin
  9952. + *
  9953. + * Type:     modifier<br>
  9954. + * Name:     count_sentences
  9955. + * Purpose:  count the number of sentences in a text
  9956. + * @link http://smarty.php.net/manual/en/language.modifier.count.paragraphs.php
  9957. + *          count_sentences (Smarty online manual)
  9958. + * @author   Monte Ohrt <monte at ohrt dot com>
  9959. + * @param string
  9960. + * @return integer
  9961. + */
  9962. +function smarty_modifier_count_sentences($string)
  9963. +{
  9964. +    // find periods with a word before but not after.
  9965. +    return preg_match_all('/[^\s]\.(?!\w)/', $string, $match);
  9966. +}
  9967. +
  9968. +/* vim: set expandtab: */
  9969. +
  9970. +?>
  9971. diff --git a/library/smarty/plugins/modifier.count_words.php b/library/smarty/plugins/modifier.count_words.php
  9972. new file mode 100644
  9973. --- /dev/null
  9974. +++ b/library/smarty/plugins/modifier.count_words.php
  9975. @@ -0,0 +1,33 @@
  9976. +<?php
  9977. +/**
  9978. + * Smarty plugin
  9979. + * @package Smarty
  9980. + * @subpackage plugins
  9981. + */
  9982. +
  9983. +
  9984. +/**
  9985. + * Smarty count_words modifier plugin
  9986. + *
  9987. + * Type:     modifier<br>
  9988. + * Name:     count_words<br>
  9989. + * Purpose:  count the number of words in a text
  9990. + * @link http://smarty.php.net/manual/en/language.modifier.count.words.php
  9991. + *          count_words (Smarty online manual)
  9992. + * @author   Monte Ohrt <monte at ohrt dot com>
  9993. + * @param string
  9994. + * @return integer
  9995. + */
  9996. +function smarty_modifier_count_words($string)
  9997. +{
  9998. +    // split text by ' ',\r,\n,\f,\t
  9999. +    $split_array = preg_split('/\s+/',$string);
  10000. +    // count matches that contain alphanumerics
  10001. +    $word_count = preg_grep('/[a-zA-Z0-9\\x80-\\xff]/', $split_array);
  10002. +
  10003. +    return count($word_count);
  10004. +}
  10005. +
  10006. +/* vim: set expandtab: */
  10007. +
  10008. +?>
  10009. diff --git a/library/smarty/plugins/modifier.date_format.php b/library/smarty/plugins/modifier.date_format.php
  10010. new file mode 100644
  10011. --- /dev/null
  10012. +++ b/library/smarty/plugins/modifier.date_format.php
  10013. @@ -0,0 +1,58 @@
  10014. +<?php
  10015. +/**
  10016. + * Smarty plugin
  10017. + * @package Smarty
  10018. + * @subpackage plugins
  10019. + */
  10020. +
  10021. +/**
  10022. + * Include the {@link shared.make_timestamp.php} plugin
  10023. + */
  10024. +require_once $smarty->_get_plugin_filepath('shared', 'make_timestamp');
  10025. +/**
  10026. + * Smarty date_format modifier plugin
  10027. + *
  10028. + * Type:     modifier<br>
  10029. + * Name:     date_format<br>
  10030. + * Purpose:  format datestamps via strftime<br>
  10031. + * Input:<br>
  10032. + *         - string: input date string
  10033. + *         - format: strftime format for output
  10034. + *         - default_date: default date if $string is empty
  10035. + * @link http://smarty.php.net/manual/en/language.modifier.date.format.php
  10036. + *          date_format (Smarty online manual)
  10037. + * @author   Monte Ohrt <monte at ohrt dot com>
  10038. + * @param string
  10039. + * @param string
  10040. + * @param string
  10041. + * @return string|void
  10042. + * @uses smarty_make_timestamp()
  10043. + */
  10044. +function smarty_modifier_date_format($string, $format = '%b %e, %Y', $default_date = '')
  10045. +{
  10046. +    if ($string != '') {
  10047. +        $timestamp = smarty_make_timestamp($string);
  10048. +    } elseif ($default_date != '') {
  10049. +        $timestamp = smarty_make_timestamp($default_date);
  10050. +    } else {
  10051. +        return;
  10052. +    }
  10053. +    if (DIRECTORY_SEPARATOR == '\\') {
  10054. +        $_win_from = array('%D',       '%h', '%n', '%r',          '%R',    '%t', '%T');
  10055. +        $_win_to   = array('%m/%d/%y', '%b', "\n", '%I:%M:%S %p', '%H:%M', "\t", '%H:%M:%S');
  10056. +        if (strpos($format, '%e') !== false) {
  10057. +            $_win_from[] = '%e';
  10058. +            $_win_to[]   = sprintf('%\' 2d', date('j', $timestamp));
  10059. +        }
  10060. +        if (strpos($format, '%l') !== false) {
  10061. +            $_win_from[] = '%l';
  10062. +            $_win_to[]   = sprintf('%\' 2d', date('h', $timestamp));
  10063. +        }
  10064. +        $format = str_replace($_win_from, $_win_to, $format);
  10065. +    }
  10066. +    return strftime($format, $timestamp);
  10067. +}
  10068. +
  10069. +/* vim: set expandtab: */
  10070. +
  10071. +?>
  10072. diff --git a/library/smarty/plugins/modifier.debug_print_var.php b/library/smarty/plugins/modifier.debug_print_var.php
  10073. new file mode 100644
  10074. --- /dev/null
  10075. +++ b/library/smarty/plugins/modifier.debug_print_var.php
  10076. @@ -0,0 +1,90 @@
  10077. +<?php
  10078. +/**
  10079. + * Smarty plugin
  10080. + * @package Smarty
  10081. + * @subpackage plugins
  10082. + */
  10083. +
  10084. +
  10085. +/**
  10086. + * Smarty debug_print_var modifier plugin
  10087. + *
  10088. + * Type:     modifier<br>
  10089. + * Name:     debug_print_var<br>
  10090. + * Purpose:  formats variable contents for display in the console
  10091. + * @link http://smarty.php.net/manual/en/language.modifier.debug.print.var.php
  10092. + *          debug_print_var (Smarty online manual)
  10093. + * @author   Monte Ohrt <monte at ohrt dot com>
  10094. + * @param array|object
  10095. + * @param integer
  10096. + * @param integer
  10097. + * @return string
  10098. + */
  10099. +function smarty_modifier_debug_print_var($var, $depth = 0, $length = 40)
  10100. +{
  10101. +    $_replace = array(
  10102. +        "\n" => '<i>\n</i>',
  10103. +        "\r" => '<i>\r</i>',
  10104. +        "\t" => '<i>\t</i>'
  10105. +    );
  10106. +
  10107. +    switch (gettype($var)) {
  10108. +        case 'array' :
  10109. +            $results = '<b>Array (' . count($var) . ')</b>';
  10110. +            foreach ($var as $curr_key => $curr_val) {
  10111. +                $results .= '<br>' . str_repeat('&nbsp;', $depth * 2)
  10112. +                    . '<b>' . strtr($curr_key, $_replace) . '</b> =&gt; '
  10113. +                    . smarty_modifier_debug_print_var($curr_val, ++$depth, $length);
  10114. +                    $depth--;
  10115. +            }
  10116. +            break;
  10117. +        case 'object' :
  10118. +            $object_vars = get_object_vars($var);
  10119. +            $results = '<b>' . get_class($var) . ' Object (' . count($object_vars) . ')</b>';
  10120. +            foreach ($object_vars as $curr_key => $curr_val) {
  10121. +                $results .= '<br>' . str_repeat('&nbsp;', $depth * 2)
  10122. +                    . '<b> -&gt;' . strtr($curr_key, $_replace) . '</b> = '
  10123. +                    . smarty_modifier_debug_print_var($curr_val, ++$depth, $length);
  10124. +                    $depth--;
  10125. +            }
  10126. +            break;
  10127. +        case 'boolean' :
  10128. +        case 'NULL' :
  10129. +        case 'resource' :
  10130. +            if (true === $var) {
  10131. +                $results = 'true';
  10132. +            } elseif (false === $var) {
  10133. +                $results = 'false';
  10134. +            } elseif (null === $var) {
  10135. +                $results = 'null';
  10136. +            } else {
  10137. +                $results = htmlspecialchars((string) $var);
  10138. +            }
  10139. +            $results = '<i>' . $results . '</i>';
  10140. +            break;
  10141. +        case 'integer' :
  10142. +        case 'float' :
  10143. +            $results = htmlspecialchars((string) $var);
  10144. +            break;
  10145. +        case 'string' :
  10146. +            $results = strtr($var, $_replace);
  10147. +            if (strlen($var) > $length ) {
  10148. +                $results = substr($var, 0, $length - 3) . '...';
  10149. +            }
  10150. +            $results = htmlspecialchars('"' . $results . '"');
  10151. +            break;
  10152. +        case 'unknown type' :
  10153. +        default :
  10154. +            $results = strtr((string) $var, $_replace);
  10155. +            if (strlen($results) > $length ) {
  10156. +                $results = substr($results, 0, $length - 3) . '...';
  10157. +            }
  10158. +            $results = htmlspecialchars($results);
  10159. +    }
  10160. +
  10161. +    return $results;
  10162. +}
  10163. +
  10164. +/* vim: set expandtab: */
  10165. +
  10166. +?>
  10167. diff --git a/library/smarty/plugins/modifier.default.php b/library/smarty/plugins/modifier.default.php
  10168. new file mode 100644
  10169. --- /dev/null
  10170. +++ b/library/smarty/plugins/modifier.default.php
  10171. @@ -0,0 +1,32 @@
  10172. +<?php
  10173. +/**
  10174. + * Smarty plugin
  10175. + * @package Smarty
  10176. + * @subpackage plugins
  10177. + */
  10178. +
  10179. +
  10180. +/**
  10181. + * Smarty default modifier plugin
  10182. + *
  10183. + * Type:     modifier<br>
  10184. + * Name:     default<br>
  10185. + * Purpose:  designate default value for empty variables
  10186. + * @link http://smarty.php.net/manual/en/language.modifier.default.php
  10187. + *          default (Smarty online manual)
  10188. + * @author   Monte Ohrt <monte at ohrt dot com>
  10189. + * @param string
  10190. + * @param string
  10191. + * @return string
  10192. + */
  10193. +function smarty_modifier_default($string, $default = '')
  10194. +{
  10195. +    if (!isset($string) || $string === '')
  10196. +        return $default;
  10197. +    else
  10198. +        return $string;
  10199. +}
  10200. +
  10201. +/* vim: set expandtab: */
  10202. +
  10203. +?>
  10204. diff --git a/library/smarty/plugins/modifier.escape.php b/library/smarty/plugins/modifier.escape.php
  10205. new file mode 100644
  10206. --- /dev/null
  10207. +++ b/library/smarty/plugins/modifier.escape.php
  10208. @@ -0,0 +1,93 @@
  10209. +<?php
  10210. +/**
  10211. + * Smarty plugin
  10212. + * @package Smarty
  10213. + * @subpackage plugins
  10214. + */
  10215. +
  10216. +
  10217. +/**
  10218. + * Smarty escape modifier plugin
  10219. + *
  10220. + * Type:     modifier<br>
  10221. + * Name:     escape<br>
  10222. + * Purpose:  Escape the string according to escapement type
  10223. + * @link http://smarty.php.net/manual/en/language.modifier.escape.php
  10224. + *          escape (Smarty online manual)
  10225. + * @author   Monte Ohrt <monte at ohrt dot com>
  10226. + * @param string
  10227. + * @param html|htmlall|url|quotes|hex|hexentity|javascript
  10228. + * @return string
  10229. + */
  10230. +function smarty_modifier_escape($string, $esc_type = 'html', $char_set = 'ISO-8859-1')
  10231. +{
  10232. +    switch ($esc_type) {
  10233. +        case 'html':
  10234. +            return htmlspecialchars($string, ENT_QUOTES, $char_set);
  10235. +
  10236. +        case 'htmlall':
  10237. +            return htmlentities($string, ENT_QUOTES, $char_set);
  10238. +
  10239. +        case 'url':
  10240. +            return rawurlencode($string);
  10241. +
  10242. +        case 'urlpathinfo':
  10243. +            return str_replace('%2F','/',rawurlencode($string));
  10244. +            
  10245. +        case 'quotes':
  10246. +            // escape unescaped single quotes
  10247. +            return preg_replace("%(?<!\\\\)'%", "\\'", $string);
  10248. +
  10249. +        case 'hex':
  10250. +            // escape every character into hex
  10251. +            $return = '';
  10252. +            for ($x=0; $x < strlen($string); $x++) {
  10253. +                $return .= '%' . bin2hex($string[$x]);
  10254. +            }
  10255. +            return $return;
  10256. +            
  10257. +        case 'hexentity':
  10258. +            $return = '';
  10259. +            for ($x=0; $x < strlen($string); $x++) {
  10260. +                $return .= '&#x' . bin2hex($string[$x]) . ';';
  10261. +            }
  10262. +            return $return;
  10263. +
  10264. +        case 'decentity':
  10265. +            $return = '';
  10266. +            for ($x=0; $x < strlen($string); $x++) {
  10267. +                $return .= '&#' . ord($string[$x]) . ';';
  10268. +            }
  10269. +            return $return;
  10270. +
  10271. +        case 'javascript':
  10272. +            // escape quotes and backslashes, newlines, etc.
  10273. +            return strtr($string, array('\\'=>'\\\\',"'"=>"\\'",'"'=>'\\"',"\r"=>'\\r',"\n"=>'\\n','</'=>'<\/'));
  10274. +            
  10275. +        case 'mail':
  10276. +            // safe way to display e-mail address on a web page
  10277. +            return str_replace(array('@', '.'),array(' [AT] ', ' [DOT] '), $string);
  10278. +            
  10279. +        case 'nonstd':
  10280. +           // escape non-standard chars, such as ms document quotes
  10281. +           $_res = '';
  10282. +           for($_i = 0, $_len = strlen($string); $_i < $_len; $_i++) {
  10283. +               $_ord = ord(substr($string, $_i, 1));
  10284. +               // non-standard char, escape it
  10285. +               if($_ord >= 126){
  10286. +                   $_res .= '&#' . $_ord . ';';
  10287. +               }
  10288. +               else {
  10289. +                   $_res .= substr($string, $_i, 1);
  10290. +               }
  10291. +           }
  10292. +           return $_res;
  10293. +
  10294. +        default:
  10295. +            return $string;
  10296. +    }
  10297. +}
  10298. +
  10299. +/* vim: set expandtab: */
  10300. +
  10301. +?>
  10302. diff --git a/library/smarty/plugins/modifier.indent.php b/library/smarty/plugins/modifier.indent.php
  10303. new file mode 100644
  10304. --- /dev/null
  10305. +++ b/library/smarty/plugins/modifier.indent.php
  10306. @@ -0,0 +1,28 @@
  10307. +<?php
  10308. +/**
  10309. + * Smarty plugin
  10310. + * @package Smarty
  10311. + * @subpackage plugins
  10312. + */
  10313. +
  10314. +
  10315. +/**
  10316. + * Smarty indent modifier plugin
  10317. + *
  10318. + * Type:     modifier<br>
  10319. + * Name:     indent<br>
  10320. + * Purpose:  indent lines of text
  10321. + * @link http://smarty.php.net/manual/en/language.modifier.indent.php
  10322. + *          indent (Smarty online manual)
  10323. + * @author   Monte Ohrt <monte at ohrt dot com>
  10324. + * @param string
  10325. + * @param integer
  10326. + * @param string
  10327. + * @return string
  10328. + */
  10329. +function smarty_modifier_indent($string,$chars=4,$char=" ")
  10330. +{
  10331. +    return preg_replace('!^!m',str_repeat($char,$chars),$string);
  10332. +}
  10333. +
  10334. +?>
  10335. diff --git a/library/smarty/plugins/modifier.lower.php b/library/smarty/plugins/modifier.lower.php
  10336. new file mode 100644
  10337. --- /dev/null
  10338. +++ b/library/smarty/plugins/modifier.lower.php
  10339. @@ -0,0 +1,26 @@
  10340. +<?php
  10341. +/**
  10342. + * Smarty plugin
  10343. + * @package Smarty
  10344. + * @subpackage plugins
  10345. + */
  10346. +
  10347. +
  10348. +/**
  10349. + * Smarty lower modifier plugin
  10350. + *
  10351. + * Type:     modifier<br>
  10352. + * Name:     lower<br>
  10353. + * Purpose:  convert string to lowercase
  10354. + * @link http://smarty.php.net/manual/en/language.modifier.lower.php
  10355. + *          lower (Smarty online manual)
  10356. + * @author   Monte Ohrt <monte at ohrt dot com>
  10357. + * @param string
  10358. + * @return string
  10359. + */
  10360. +function smarty_modifier_lower($string)
  10361. +{
  10362. +    return strtolower($string);
  10363. +}
  10364. +
  10365. +?>
  10366. diff --git a/library/smarty/plugins/modifier.nl2br.php b/library/smarty/plugins/modifier.nl2br.php
  10367. new file mode 100644
  10368. --- /dev/null
  10369. +++ b/library/smarty/plugins/modifier.nl2br.php
  10370. @@ -0,0 +1,35 @@
  10371. +<?php
  10372. +/**
  10373. + * Smarty plugin
  10374. + * @package Smarty
  10375. + * @subpackage plugins
  10376. + */
  10377. +
  10378. +
  10379. +/**
  10380. + * Smarty plugin
  10381. + *
  10382. + * Type:     modifier<br>
  10383. + * Name:     nl2br<br>
  10384. + * Date:     Feb 26, 2003
  10385. + * Purpose:  convert \r\n, \r or \n to <<br>>
  10386. + * Input:<br>
  10387. + *         - contents = contents to replace
  10388. + *         - preceed_test = if true, includes preceeding break tags
  10389. + *           in replacement
  10390. + * Example:  {$text|nl2br}
  10391. + * @link http://smarty.php.net/manual/en/language.modifier.nl2br.php
  10392. + *          nl2br (Smarty online manual)
  10393. + * @version  1.0
  10394. + * @author   Monte Ohrt <monte at ohrt dot com>
  10395. + * @param string
  10396. + * @return string
  10397. + */
  10398. +function smarty_modifier_nl2br($string)
  10399. +{
  10400. +    return nl2br($string);
  10401. +}
  10402. +
  10403. +/* vim: set expandtab: */
  10404. +
  10405. +?>
  10406. diff --git a/library/smarty/plugins/modifier.regex_replace.php b/library/smarty/plugins/modifier.regex_replace.php
  10407. new file mode 100644
  10408. --- /dev/null
  10409. +++ b/library/smarty/plugins/modifier.regex_replace.php
  10410. @@ -0,0 +1,48 @@
  10411. +<?php
  10412. +/**
  10413. + * Smarty plugin
  10414. + * @package Smarty
  10415. + * @subpackage plugins
  10416. + */
  10417. +
  10418. +
  10419. +/**
  10420. + * Smarty regex_replace modifier plugin
  10421. + *
  10422. + * Type:     modifier<br>
  10423. + * Name:     regex_replace<br>
  10424. + * Purpose:  regular expression search/replace
  10425. + * @link http://smarty.php.net/manual/en/language.modifier.regex.replace.php
  10426. + *          regex_replace (Smarty online manual)
  10427. + * @author   Monte Ohrt <monte at ohrt dot com>
  10428. + * @param string
  10429. + * @param string|array
  10430. + * @param string|array
  10431. + * @return string
  10432. + */
  10433. +function smarty_modifier_regex_replace($string, $search, $replace)
  10434. +{
  10435. +    if(is_array($search)) {
  10436. +      foreach($search as $idx => $s)
  10437. +        $search[$idx] = _smarty_regex_replace_check($s);
  10438. +    } else {
  10439. +      $search = _smarty_regex_replace_check($search);
  10440. +    }      
  10441. +
  10442. +    return preg_replace($search, $replace, $string);
  10443. +}
  10444. +
  10445. +function _smarty_regex_replace_check($search)
  10446. +{
  10447. +    if (($pos = strpos($search,"\0")) !== false)
  10448. +      $search = substr($search,0,$pos);
  10449. +    if (preg_match('!([a-zA-Z\s]+)$!s', $search, $match) && (strpos($match[1], 'e') !== false)) {
  10450. +        /* remove eval-modifier from $search */
  10451. +        $search = substr($search, 0, -strlen($match[1])) . preg_replace('![e\s]+!', '', $match[1]);
  10452. +    }
  10453. +    return $search;
  10454. +}
  10455. +
  10456. +/* vim: set expandtab: */
  10457. +
  10458. +?>
  10459. diff --git a/library/smarty/plugins/modifier.replace.php b/library/smarty/plugins/modifier.replace.php
  10460. new file mode 100644
  10461. --- /dev/null
  10462. +++ b/library/smarty/plugins/modifier.replace.php
  10463. @@ -0,0 +1,30 @@
  10464. +<?php
  10465. +/**
  10466. + * Smarty plugin
  10467. + * @package Smarty
  10468. + * @subpackage plugins
  10469. + */
  10470. +
  10471. +
  10472. +/**
  10473. + * Smarty replace modifier plugin
  10474. + *
  10475. + * Type:     modifier<br>
  10476. + * Name:     replace<br>
  10477. + * Purpose:  simple search/replace
  10478. + * @link http://smarty.php.net/manual/en/language.modifier.replace.php
  10479. + *          replace (Smarty online manual)
  10480. + * @author   Monte Ohrt <monte at ohrt dot com>
  10481. + * @param string
  10482. + * @param string
  10483. + * @param string
  10484. + * @return string
  10485. + */
  10486. +function smarty_modifier_replace($string, $search, $replace)
  10487. +{
  10488. +    return str_replace($search, $replace, $string);
  10489. +}
  10490. +
  10491. +/* vim: set expandtab: */
  10492. +
  10493. +?>
  10494. diff --git a/library/smarty/plugins/modifier.spacify.php b/library/smarty/plugins/modifier.spacify.php
  10495. new file mode 100644
  10496. --- /dev/null
  10497. +++ b/library/smarty/plugins/modifier.spacify.php
  10498. @@ -0,0 +1,30 @@
  10499. +<?php
  10500. +/**
  10501. + * Smarty plugin
  10502. + * @package Smarty
  10503. + * @subpackage plugins
  10504. + */
  10505. +
  10506. +
  10507. +/**
  10508. + * Smarty spacify modifier plugin
  10509. + *
  10510. + * Type:     modifier<br>
  10511. + * Name:     spacify<br>
  10512. + * Purpose:  add spaces between characters in a string
  10513. + * @link http://smarty.php.net/manual/en/language.modifier.spacify.php
  10514. + *          spacify (Smarty online manual)
  10515. + * @author   Monte Ohrt <monte at ohrt dot com>
  10516. + * @param string
  10517. + * @param string
  10518. + * @return string
  10519. + */
  10520. +function smarty_modifier_spacify($string, $spacify_char = ' ')
  10521. +{
  10522. +    return implode($spacify_char,
  10523. +                   preg_split('//', $string, -1, PREG_SPLIT_NO_EMPTY));
  10524. +}
  10525. +
  10526. +/* vim: set expandtab: */
  10527. +
  10528. +?>
  10529. diff --git a/library/smarty/plugins/modifier.string_format.php b/library/smarty/plugins/modifier.string_format.php
  10530. new file mode 100644
  10531. --- /dev/null
  10532. +++ b/library/smarty/plugins/modifier.string_format.php
  10533. @@ -0,0 +1,29 @@
  10534. +<?php
  10535. +/**
  10536. + * Smarty plugin
  10537. + * @package Smarty
  10538. + * @subpackage plugins
  10539. + */
  10540. +
  10541. +
  10542. +/**
  10543. + * Smarty string_format modifier plugin
  10544. + *
  10545. + * Type:     modifier<br>
  10546. + * Name:     string_format<br>
  10547. + * Purpose:  format strings via sprintf
  10548. + * @link http://smarty.php.net/manual/en/language.modifier.string.format.php
  10549. + *          string_format (Smarty online manual)
  10550. + * @author   Monte Ohrt <monte at ohrt dot com>
  10551. + * @param string
  10552. + * @param string
  10553. + * @return string
  10554. + */
  10555. +function smarty_modifier_string_format($string, $format)
  10556. +{
  10557. +    return sprintf($format, $string);
  10558. +}
  10559. +
  10560. +/* vim: set expandtab: */
  10561. +
  10562. +?>
  10563. diff --git a/library/smarty/plugins/modifier.strip.php b/library/smarty/plugins/modifier.strip.php
  10564. new file mode 100644
  10565. --- /dev/null
  10566. +++ b/library/smarty/plugins/modifier.strip.php
  10567. @@ -0,0 +1,33 @@
  10568. +<?php
  10569. +/**
  10570. + * Smarty plugin
  10571. + * @package Smarty
  10572. + * @subpackage plugins
  10573. + */
  10574. +
  10575. +
  10576. +/**
  10577. + * Smarty strip modifier plugin
  10578. + *
  10579. + * Type:     modifier<br>
  10580. + * Name:     strip<br>
  10581. + * Purpose:  Replace all repeated spaces, newlines, tabs
  10582. + *           with a single space or supplied replacement string.<br>
  10583. + * Example:  {$var|strip} {$var|strip:"&nbsp;"}
  10584. + * Date:     September 25th, 2002
  10585. + * @link http://smarty.php.net/manual/en/language.modifier.strip.php
  10586. + *          strip (Smarty online manual)
  10587. + * @author   Monte Ohrt <monte at ohrt dot com>
  10588. + * @version  1.0
  10589. + * @param string
  10590. + * @param string
  10591. + * @return string
  10592. + */
  10593. +function smarty_modifier_strip($text, $replace = ' ')
  10594. +{
  10595. +    return preg_replace('!\s+!', $replace, $text);
  10596. +}
  10597. +
  10598. +/* vim: set expandtab: */
  10599. +
  10600. +?>
  10601. diff --git a/library/smarty/plugins/modifier.strip_tags.php b/library/smarty/plugins/modifier.strip_tags.php
  10602. new file mode 100644
  10603. --- /dev/null
  10604. +++ b/library/smarty/plugins/modifier.strip_tags.php
  10605. @@ -0,0 +1,32 @@
  10606. +<?php
  10607. +/**
  10608. + * Smarty plugin
  10609. + * @package Smarty
  10610. + * @subpackage plugins
  10611. + */
  10612. +
  10613. +
  10614. +/**
  10615. + * Smarty strip_tags modifier plugin
  10616. + *
  10617. + * Type:     modifier<br>
  10618. + * Name:     strip_tags<br>
  10619. + * Purpose:  strip html tags from text
  10620. + * @link http://smarty.php.net/manual/en/language.modifier.strip.tags.php
  10621. + *          strip_tags (Smarty online manual)
  10622. + * @author   Monte Ohrt <monte at ohrt dot com>
  10623. + * @param string
  10624. + * @param boolean
  10625. + * @return string
  10626. + */
  10627. +function smarty_modifier_strip_tags($string, $replace_with_space = true)
  10628. +{
  10629. +    if ($replace_with_space)
  10630. +        return preg_replace('!<[^>]*?>!', ' ', $string);
  10631. +    else
  10632. +        return strip_tags($string);
  10633. +}
  10634. +
  10635. +/* vim: set expandtab: */
  10636. +
  10637. +?>
  10638. diff --git a/library/smarty/plugins/modifier.truncate.php b/library/smarty/plugins/modifier.truncate.php
  10639. new file mode 100644
  10640. --- /dev/null
  10641. +++ b/library/smarty/plugins/modifier.truncate.php
  10642. @@ -0,0 +1,50 @@
  10643. +<?php
  10644. +/**
  10645. + * Smarty plugin
  10646. + * @package Smarty
  10647. + * @subpackage plugins
  10648. + */
  10649. +
  10650. +
  10651. +/**
  10652. + * Smarty truncate modifier plugin
  10653. + *
  10654. + * Type:     modifier<br>
  10655. + * Name:     truncate<br>
  10656. + * Purpose:  Truncate a string to a certain length if necessary,
  10657. + *           optionally splitting in the middle of a word, and
  10658. + *           appending the $etc string or inserting $etc into the middle.
  10659. + * @link http://smarty.php.net/manual/en/language.modifier.truncate.php
  10660. + *          truncate (Smarty online manual)
  10661. + * @author   Monte Ohrt <monte at ohrt dot com>
  10662. + * @param string
  10663. + * @param integer
  10664. + * @param string
  10665. + * @param boolean
  10666. + * @param boolean
  10667. + * @return string
  10668. + */
  10669. +function smarty_modifier_truncate($string, $length = 80, $etc = '...',
  10670. +                                  $break_words = false, $middle = false)
  10671. +{
  10672. +    if ($length == 0)
  10673. +        return '';
  10674. +
  10675. +    if (strlen($string) > $length) {
  10676. +        $length -= min($length, strlen($etc));
  10677. +        if (!$break_words && !$middle) {
  10678. +            $string = preg_replace('/\s+?(\S+)?$/', '', substr($string, 0, $length+1));
  10679. +        }
  10680. +        if(!$middle) {
  10681. +            return substr($string, 0, $length) . $etc;
  10682. +        } else {
  10683. +            return substr($string, 0, $length/2) . $etc . substr($string, -$length/2);
  10684. +        }
  10685. +    } else {
  10686. +        return $string;
  10687. +    }
  10688. +}
  10689. +
  10690. +/* vim: set expandtab: */
  10691. +
  10692. +?>
  10693. diff --git a/library/smarty/plugins/modifier.upper.php b/library/smarty/plugins/modifier.upper.php
  10694. new file mode 100644
  10695. --- /dev/null
  10696. +++ b/library/smarty/plugins/modifier.upper.php
  10697. @@ -0,0 +1,26 @@
  10698. +<?php
  10699. +/**
  10700. + * Smarty plugin
  10701. + * @package Smarty
  10702. + * @subpackage plugins
  10703. + */
  10704. +
  10705. +
  10706. +/**
  10707. + * Smarty upper modifier plugin
  10708. + *
  10709. + * Type:     modifier<br>
  10710. + * Name:     upper<br>
  10711. + * Purpose:  convert string to uppercase
  10712. + * @link http://smarty.php.net/manual/en/language.modifier.upper.php
  10713. + *          upper (Smarty online manual)
  10714. + * @author   Monte Ohrt <monte at ohrt dot com>
  10715. + * @param string
  10716. + * @return string
  10717. + */
  10718. +function smarty_modifier_upper($string)
  10719. +{
  10720. +    return strtoupper($string);
  10721. +}
  10722. +
  10723. +?>
  10724. diff --git a/library/smarty/plugins/modifier.wordwrap.php b/library/smarty/plugins/modifier.wordwrap.php
  10725. new file mode 100644
  10726. --- /dev/null
  10727. +++ b/library/smarty/plugins/modifier.wordwrap.php
  10728. @@ -0,0 +1,29 @@
  10729. +<?php
  10730. +/**
  10731. + * Smarty plugin
  10732. + * @package Smarty
  10733. + * @subpackage plugins
  10734. + */
  10735. +
  10736. +
  10737. +/**
  10738. + * Smarty wordwrap modifier plugin
  10739. + *
  10740. + * Type:     modifier<br>
  10741. + * Name:     wordwrap<br>
  10742. + * Purpose:  wrap a string of text at a given length
  10743. + * @link http://smarty.php.net/manual/en/language.modifier.wordwrap.php
  10744. + *          wordwrap (Smarty online manual)
  10745. + * @author   Monte Ohrt <monte at ohrt dot com>
  10746. + * @param string
  10747. + * @param integer
  10748. + * @param string
  10749. + * @param boolean
  10750. + * @return string
  10751. + */
  10752. +function smarty_modifier_wordwrap($string,$length=80,$break="\n",$cut=false)
  10753. +{
  10754. +    return wordwrap($string,$length,$break,$cut);
  10755. +}
  10756. +
  10757. +?>
  10758. diff --git a/library/smarty/plugins/outputfilter.trimwhitespace.php b/library/smarty/plugins/outputfilter.trimwhitespace.php
  10759. new file mode 100644
  10760. --- /dev/null
  10761. +++ b/library/smarty/plugins/outputfilter.trimwhitespace.php
  10762. @@ -0,0 +1,75 @@
  10763. +<?php
  10764. +/**
  10765. + * Smarty plugin
  10766. + * @package Smarty
  10767. + * @subpackage plugins
  10768. + */
  10769. +
  10770. +/**
  10771. + * Smarty trimwhitespace outputfilter plugin
  10772. + *
  10773. + * File:     outputfilter.trimwhitespace.php<br>
  10774. + * Type:     outputfilter<br>
  10775. + * Name:     trimwhitespace<br>
  10776. + * Date:     Jan 25, 2003<br>
  10777. + * Purpose:  trim leading white space and blank lines from
  10778. + *           template source after it gets interpreted, cleaning
  10779. + *           up code and saving bandwidth. Does not affect
  10780. + *           <<PRE>></PRE> and <SCRIPT></SCRIPT> blocks.<br>
  10781. + * Install:  Drop into the plugin directory, call
  10782. + *           <code>$smarty->load_filter('output','trimwhitespace');</code>
  10783. + *           from application.
  10784. + * @author   Monte Ohrt <monte at ohrt dot com>
  10785. + * @author Contributions from Lars Noschinski <lars@usenet.noschinski.de>
  10786. + * @version  1.3
  10787. + * @param string
  10788. + * @param Smarty
  10789. + */
  10790. +function smarty_outputfilter_trimwhitespace($source, &$smarty)
  10791. +{
  10792. +    // Pull out the script blocks
  10793. +    preg_match_all("!<script[^>]*?>.*?</script>!is", $source, $match);
  10794. +    $_script_blocks = $match[0];
  10795. +    $source = preg_replace("!<script[^>]*?>.*?</script>!is",
  10796. +                           '@@@SMARTY:TRIM:SCRIPT@@@', $source);
  10797. +
  10798. +    // Pull out the pre blocks
  10799. +    preg_match_all("!<pre[^>]*?>.*?</pre>!is", $source, $match);
  10800. +    $_pre_blocks = $match[0];
  10801. +    $source = preg_replace("!<pre[^>]*?>.*?</pre>!is",
  10802. +                           '@@@SMARTY:TRIM:PRE@@@', $source);
  10803. +    
  10804. +    // Pull out the textarea blocks
  10805. +    preg_match_all("!<textarea[^>]*?>.*?</textarea>!is", $source, $match);
  10806. +    $_textarea_blocks = $match[0];
  10807. +    $source = preg_replace("!<textarea[^>]*?>.*?</textarea>!is",
  10808. +                           '@@@SMARTY:TRIM:TEXTAREA@@@', $source);
  10809. +
  10810. +    // remove all leading spaces, tabs and carriage returns NOT
  10811. +    // preceeded by a php close tag.
  10812. +    $source = trim(preg_replace('/((?<!\?>)\n)[\s]+/m', '', $source));
  10813. +
  10814. +    // replace textarea blocks
  10815. +    smarty_outputfilter_trimwhitespace_replace("@@@SMARTY:TRIM:TEXTAREA@@@",$_textarea_blocks, $source);
  10816. +
  10817. +    // replace pre blocks
  10818. +    smarty_outputfilter_trimwhitespace_replace("@@@SMARTY:TRIM:PRE@@@",$_pre_blocks, $source);
  10819. +
  10820. +    // replace script blocks
  10821. +    smarty_outputfilter_trimwhitespace_replace("@@@SMARTY:TRIM:SCRIPT@@@",$_script_blocks, $source);
  10822. +
  10823. +    return $source;
  10824. +}
  10825. +
  10826. +function smarty_outputfilter_trimwhitespace_replace($search_str, $replace, &$subject) {
  10827. +    $_len = strlen($search_str);
  10828. +    $_pos = 0;
  10829. +    for ($_i=0, $_count=count($replace); $_i<$_count; $_i++)
  10830. +        if (($_pos=strpos($subject, $search_str, $_pos))!==false)
  10831. +            $subject = substr_replace($subject, $replace[$_i], $_pos, $_len);
  10832. +        else
  10833. +            break;
  10834. +
  10835. +}
  10836. +
  10837. +?>
  10838. diff --git a/library/smarty/plugins/shared.escape_special_chars.php b/library/smarty/plugins/shared.escape_special_chars.php
  10839. new file mode 100644
  10840. --- /dev/null
  10841. +++ b/library/smarty/plugins/shared.escape_special_chars.php
  10842. @@ -0,0 +1,31 @@
  10843. +<?php
  10844. +/**
  10845. + * Smarty shared plugin
  10846. + * @package Smarty
  10847. + * @subpackage plugins
  10848. + */
  10849. +
  10850. +
  10851. +/**
  10852. + * escape_special_chars common function
  10853. + *
  10854. + * Function: smarty_function_escape_special_chars<br>
  10855. + * Purpose:  used by other smarty functions to escape
  10856. + *           special chars except for already escaped ones
  10857. + * @author   Monte Ohrt <monte at ohrt dot com>
  10858. + * @param string
  10859. + * @return string
  10860. + */
  10861. +function smarty_function_escape_special_chars($string)
  10862. +{
  10863. +    if(!is_array($string)) {
  10864. +        $string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\%%%SMARTY_END%%%', $string);
  10865. +        $string = htmlspecialchars($string);
  10866. +        $string = str_replace(array('%%%SMARTY_START%%%','%%%SMARTY_END%%%'), array('&',';'), $string);
  10867. +    }
  10868. +    return $string;
  10869. +}
  10870. +
  10871. +/* vim: set expandtab: */
  10872. +
  10873. +?>
  10874. diff --git a/library/smarty/plugins/shared.make_timestamp.php b/library/smarty/plugins/shared.make_timestamp.php
  10875. new file mode 100644
  10876. --- /dev/null
  10877. +++ b/library/smarty/plugins/shared.make_timestamp.php
  10878. @@ -0,0 +1,46 @@
  10879. +<?php
  10880. +/**
  10881. + * Smarty shared plugin
  10882. + * @package Smarty
  10883. + * @subpackage plugins
  10884. + */
  10885. +
  10886. +
  10887. +/**
  10888. + * Function: smarty_make_timestamp<br>
  10889. + * Purpose:  used by other smarty functions to make a timestamp
  10890. + *           from a string.
  10891. + * @author   Monte Ohrt <monte at ohrt dot com>
  10892. + * @param string
  10893. + * @return string
  10894. + */
  10895. +function smarty_make_timestamp($string)
  10896. +{
  10897. +    if(empty($string)) {
  10898. +        // use "now":
  10899. +        $time = time();
  10900. +
  10901. +    } elseif (preg_match('/^\d{14}$/', $string)) {
  10902. +        // it is mysql timestamp format of YYYYMMDDHHMMSS?            
  10903. +        $time = mktime(substr($string, 8, 2),substr($string, 10, 2),substr($string, 12, 2),
  10904. +                       substr($string, 4, 2),substr($string, 6, 2),substr($string, 0, 4));
  10905. +        
  10906. +    } elseif (is_numeric($string)) {
  10907. +        // it is a numeric string, we handle it as timestamp
  10908. +        $time = (int)$string;
  10909. +        
  10910. +    } else {
  10911. +        // strtotime should handle it
  10912. +        $time = strtotime($string);
  10913. +        if ($time == -1 || $time === false) {
  10914. +            // strtotime() was not able to parse $string, use "now":
  10915. +            $time = time();
  10916. +        }
  10917. +    }
  10918. +    return $time;
  10919. +
  10920. +}
  10921. +
  10922. +/* vim: set expandtab: */
  10923. +
  10924. +?>
  10925. diff --git a/templates/default/html_css.tpl b/templates/default/html_css.tpl
  10926. new file mode 100644
  10927. --- /dev/null
  10928. +++ b/templates/default/html_css.tpl
  10929. @@ -0,0 +1,8 @@
  10930. +
  10931. +   <link rel="stylesheet" type="text/css" href="{$path}css/{config_get option='css_include_file'}" />
  10932. +   <link rel="stylesheet" type="text/css" href="{$path}css/jquery-ui.css" />
  10933. +   <link rel="stylesheet" type="text/css" href="{$path}css/common_config.php" />
  10934. +   {* Add right-to-left css if needed *}
  10935. +   {if $directionality == 'rtl'}<link rel="stylesheet" type="text/css" href="{$path}css/{config_get option='css_rtl_include_file'|escape:'html'}" />{/if}
  10936. +   {foreach from=$g_stylesheets_included item=t_stylesheet_path }<link rel="stylesheet" type="text/css" href="{$path}css/{$t_stylesheet_path|escape:'html'}" />{/foreach}
  10937. +
  10938. diff --git a/templates/default/html_footer.tpl b/templates/default/html_footer.tpl
  10939. new file mode 100644
  10940. --- /dev/null
  10941. +++ b/templates/default/html_footer.tpl
  10942. @@ -0,0 +1,27 @@
  10943. +   <div id="footer">
  10944. +       <hr />
  10945. +       <div id="powered-by-mantisbt-logo">
  10946. +           <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>
  10947. +       </div>
  10948. +
  10949. +       {* Show optional user-specificed custom copyright statement *}
  10950. +       {if $copyright_statement}
  10951. +       <address id="user-copyright">$t_copyright_statement</address>
  10952. +       {/if}
  10953. +
  10954. +       {* Show MantisBT version and copyright statement *}
  10955. +       <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>
  10956. +
  10957. +       {* Show contact information *}
  10958. +       <address id="webmaster-contact-information">{lang_get string='webmaster_contact_information'}{config_get option='webmaster_email'}</address>
  10959. +
  10960. +       { if $horizontal }<hr />{/if}
  10961. +
  10962. +       {if $t_page_execution_time}<p id="page-execution-time">$t_page_execution_time</p>{/if}
  10963. +       {if $t_page_memory_usage}<p id="page-memory-usage">$t_page_memory_usage</p>{/if}
  10964. +       {if $t_total_queries_executed}<p id="total-queries-count">$t_total_queries_executed</p>{/if}
  10965. +       {if $t_unique_queries_executed}<p id="unique-queries-count">$t_unique_queries_executed</p>{/if}
  10966. +       {if $t_total_query_time}<p id="total-query-execution-time">$t_total_query_time</p>{/if}
  10967. +
  10968. +       {$log_events}
  10969. +   </div>
  10970. diff --git a/templates/default/html_head_javascript.tpl b/templates/default/html_head_javascript.tpl
  10971. new file mode 100644
  10972. --- /dev/null
  10973. +++ b/templates/default/html_head_javascript.tpl
  10974. @@ -0,0 +1,10 @@
  10975. +
  10976. +   <script type="text/javascript" src="{$short_path}/javascript_config.php"></script>
  10977. +   <script type="text/javascript" src="{$short_path}/javascript_translations.php"></script>
  10978. +   <script type="text/javascript" src="{$short_path}/javascript/jquery.js"></script>
  10979. +   <script type="text/javascript" src="{$short_path}/javascript/jquery-ui.js"></script>
  10980. +   <script type="text/javascript" src="{$short_path}/javascript/common.js"></script>
  10981. +   {foreach from=$g_scripts_included item=p_filename}
  10982. +   <script type="text/javascript" src="{$short_path}/javascript/{$p_filename|escape:'html'}"></script>
  10983. +   {/foreach}
  10984. +
  10985. diff --git a/templates/default/html_login_info.tpl b/templates/default/html_login_info.tpl
  10986. new file mode 100644
  10987. --- /dev/null
  10988. +++ b/templates/default/html_login_info.tpl
  10989. @@ -0,0 +1,43 @@
  10990. +
  10991. +   <div id="login-info">
  10992. +       {if current_user_is_anonymous() }
  10993. +       <span id="logged-anon-label">{ lang_get string='anonymous'}</span>
  10994. +       <span id="login-link"><a href="{$path}login_page.php?return={$t_return_page}">{lang_get string='login_link'}</a></span>
  10995. +       {if $allow_signup}
  10996. +       <span id="signup-link"><a href="{$path}signup_page.php">{lang_get string='signup_link'}</a></span>
  10997. +       {/if}
  10998. +       {else}
  10999. +       <span id="logged-in-label">{lang_get string='logged_in_as'}</span>
  11000. +       <span id="logged-in-user">{$t_username}</span>
  11001. +       <span id="logged-in">
  11002. +           {if $t_realname}<span id="logged-in-realname">{$t_realname}</span>{/if}
  11003. +           <span id="logged-in-accesslevel" class="{$t_access_level}">{$t_access_level}</span>
  11004. +       </span>
  11005. +       {/if}
  11006. +   </div>
  11007. +
  11008. +   {if $rss_enabled}
  11009. +   <div id="rss-feed">
  11010. +       {* Link to RSS issues feed for the selected project, including authentication details. *}
  11011. +       <a href="{$rss_get_issues_feed_url|escape:'html'}">
  11012. +           <img src="{$short_path}images/rss.png" alt="{lang_get string='rss'}" title="{lang_get string='rss'}" />
  11013. +       </a>
  11014. +   </div>
  11015. +   {/if}
  11016. +
  11017. +   {if $t_show_project_selector }
  11018. +   <form method="post" id="form-set-project" action="{$short_path}set_project.php">
  11019. +       <fieldset id="project-selector">
  11020. +           {* CSRF protection not required here - form does not result in modifications *}
  11021. +           <label for="form-set-project-id">{lang_get string='email_project'}</label>
  11022. +           <select id="form-set-project-id" name="project_id">
  11023. +               {$project_option_list}
  11024. +           </select>
  11025. +           <input type="submit" class="button" value="{lang_get string='switch'}" />
  11026. +       </fieldset>
  11027. +   </form>
  11028. +   <div id="current-time">{$smarty.now|date_format:"%Y-%m-%d %H:%M:%S"}</div>
  11029. +   {else}
  11030. +   <div id="current-time-centered">{$smarty.now|date_format:"%Y-%m-%d %H:%M:%S"}</div>
  11031. +   {/if}
  11032. +
  11033. diff --git a/templates/default/html_menu.tpl b/templates/default/html_menu.tpl
  11034. new file mode 100644
  11035. --- /dev/null
  11036. +++ b/templates/default/html_menu.tpl
  11037. @@ -0,0 +1,46 @@
  11038. +   {if auth_is_user_authenticated()}
  11039. +   <form method="post" action="{$short_path}jump_to_bug.php" class="bug-jump-form">
  11040. +       <fieldset class="bug-jump">
  11041. +           {* CSRF protection not required here - form does not result in modifications *}
  11042. +           <input type="hidden" name="bug_label" value="{lang_get string='issue_id'}" />
  11043. +           <input type="text" name="bug_id" size="10" class="small" />
  11044. +           <input type="submit" class="button-small" value="{lang_get string='jump'}" />
  11045. +       </fieldset>
  11046. +   </form>
  11047. +
  11048. +   <div class="main-menu">
  11049. +       <div>
  11050. +           <ul class="menu">
  11051. +               {* Main Page *}
  11052. +               <li><a href="{$short_path}main_page.php">{lang_get string='main_link'}</a></li>
  11053. +
  11054. +               {foreach from=$t_menu_plugin_pre_options item=t_menu_option}
  11055. +               <li>{$t_menu_option}</li>
  11056. +               {/foreach}
  11057. +
  11058. +               {foreach from=$t_menu_options item=t_menu_option}
  11059. +               <li>{$t_menu_option}</li>
  11060. +               {/foreach}
  11061. +
  11062. +               {foreach from=$menu_plugin_post_options item=t_menu_option}
  11063. +               <li>{$t_menu_option}</li>
  11064. +               {/foreach}
  11065. +
  11066. +               {foreach from=$t_menu_extra_options item=t_menu_option}
  11067. +               <li>{$t_menu_option}</li>
  11068. +               {/foreach}
  11069. +
  11070. +               {* Time Tracking / Billing *}
  11071. +               {if $t_time_tracking_enabled}
  11072. +               <li><a href="{$short_path}billing_page.php">{lang_get string='time_tracking_billing_link'}</a></li>
  11073. +               {/if}
  11074. +
  11075. +               {* Logout (no if anonymously logged in) *}
  11076. +               {if !current_user_is_anonymous()}
  11077. +               <li><a id="logout-link" href="{$short_path}logout_page.php">{lang_get string='logout_link'}</a></li>
  11078. +               {/if}
  11079. +           </ul>
  11080. +       </div>
  11081. +   </div>
  11082. +   {/if}
  11083. +
  11084. diff --git a/templates/default/html_top_banner.tpl b/templates/default/html_top_banner.tpl
  11085. new file mode 100644
  11086. --- /dev/null
  11087. +++ b/templates/default/html_top_banner.tpl
  11088. @@ -0,0 +1,15 @@
  11089. +
  11090. +   {if $t_page }
  11091. +       {include_php file=$t_page};
  11092. +   {elseif $t_show_logo }
  11093. +   <div id="banner">
  11094. +       {if $t_show_url }
  11095. +       <a id="logo-link" href="{config_get option='logo_url'|escape:'html'}">
  11096. +       {/if}
  11097. +       <img id="logo-image" alt="Mantis Bug Tracker" src="{$path}{config_get option='logo_image'|escape:'html'}" />
  11098. +       {if $t_show_url}
  11099. +       </a>
  11100. +       {/if}
  11101. +   </div>
  11102. +   {/if}
  11103. +
  11104. diff --git a/templates/default/main.tpl b/templates/default/main.tpl
  11105. new file mode 100644
  11106. --- /dev/null
  11107. +++ b/templates/default/main.tpl
  11108. @@ -0,0 +1,49 @@
  11109. +<?xml version="1.0" encoding="utf-8"?>
  11110. +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  11111. +<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en" >
  11112. +
  11113. +<head>
  11114. +   {include file='html_css.tpl'}
  11115. +
  11116. +   <meta http-equiv="Content-type" content="application/xhtml+xml; charset=UTF-8" />
  11117. +   {include_php file=$meta_include_file}
  11118. +
  11119. +   {if $g_robots_meta}<meta name="robots" content="{$g_robots_meta}" />{/if}
  11120. +
  11121. +   {if $g_rss_feed_url}<link rel="alternate" type="application/rss+xml" title="RSS" href="{$g_rss_feed_url}" />{/if}
  11122. +
  11123. +   {if $t_favicon_image}<link rel="shortcut icon" href="{$short_path}{$t_favicon_image}" type="image/x-icon" />{/if}
  11124. +
  11125. +   <link rel="search" type="application/opensearchdescription+xml" title="MantisBT: Text Search" href="{$path}browser_search_plugin.php?type=text" />
  11126. +   <link rel="search" type="application/opensearchdescription+xml" title="MantisBT: Issue Id" href="{$path}browser_search_plugin.php?type=id" />
  11127. +
  11128. +   <title>{$t_title}</title>
  11129. +
  11130. +   {include file='html_head_javascript.tpl'}
  11131. +
  11132. +   {if $t_url}
  11133. +   <meta http-equiv="Refresh" content="{$p_time};URL={$t_url}" />
  11134. +   {/if}
  11135. +
  11136. +</head>
  11137. +
  11138. +<body>
  11139. +
  11140. +  <div id="mantis">
  11141. +
  11142. +   {include file='html_top_banner.tpl'}
  11143. +   {* include file='html_login_info.tpl' *}
  11144. +   {include file='html_menu.tpl'}
  11145. +
  11146. +   <div id="content">
  11147. +       {$content}
  11148. +   </div>
  11149. +
  11150. +   {include file='html_footer.tpl'}
  11151. +
  11152. +  </div>
  11153. +
  11154. +</body>
  11155. +
  11156. +</html>
  11157. +
Add Comment
Please, Sign In to add comment